	.title	SPWN80
	.ident	/002/
;+
; File SPWN80.MAC
;
; Entry points: CALL SPWN80(ITKASC,IBUF [, [IESTS] [,IDS] ])
;
; Spawns user-specified task (taskname in ASCII), with user-
; specified buffer, and waits (stopped) for spawned
; task to complete.
;
; Inputs (required):
;
;  ITKNAM = taskname, 1-6 ASCII characters (less than 6 characters of input
;            allowed if use quoted string or if zero byte used as a terminator)
;  IBUF = buffer, 0-79 ASCII characters. (If submitting less than 79 characters,
;            buffer must be a quoted string or be terminated by a zero
;            byte, as above.)  ** WARNING ** Executive searches for control
;            characters imbedded in buffer (CR/ESC/???), so cannot send binary.
;
; Optional returned values:
;
;  IDS = directive status from spawn
;  IESTS = return code from spawned task exit
;
; NOTE: May omit optional return parameters, as indicated;
; however, in that case SPWN80 will abort if the error condition
; occurs, assuming the caller chooses not to handle it. Before aborting,
; will print an error message giving details of the problem.
;
; Abort is via a TRAP instruction so that Fortran
; OTS will print out a traceback.
;-

ef2=2	; event flag to use
isz=79.	; max cmd line size to use

	.mcall	abrt$s,spwn$s,stse$s
	.mcall	qiow$s,gtsk$s
	.enable	lsb
	.enable	lc

SPWN80::
	jsr	r5,$savrg	; save nonvolatile reg's (3-5)

;	   now set up 2-word RAD50 taskname on stack

	clr	-(sp)
	mov	2(r5),r0	; get ascii's addr
	call	$cat5		; convert 3 chrs to R50
	mov	r1,-(sp)
	bcs	10$		; skip done
	call	$cat5		; convert 3 more
	mov	r1,2(sp)

;	   leave 8 wds for sts block, make call to spawn

10$:
	mov	sp,r3		; save pointer to tkname
	sub	#2.+16.,sp	; 1 wd for dsw save, 8 wds for iesb
	clr	(sp)		; iesb(1)=0
	mov	sp,r4		; save addr of iesb

; Find length of inbuf

	mov	4(r5),r1
	mov	#isz,r0
11$:
	tstb	(r1)+		; ck for zero byte
	beq	12$		; exit loop if found
	sob	r0,11$		; else continue
12$:
	neg	r0		; -(unused count)
	add	#isz,r0		; + (initial count) , giving total

	spwn$s	r3,,,  ,  ,#ef2, ,r4,4(r5),r0  

;               ^            ^     ^    ^   ^
;               tkname     evfg   esbk cmd len(cmd)
;
; omitted parameters: #2-3: N/A; #4-5: g,m; #7: ast; #11-12: nn,dd
;
;

	mov	$dsw,-(r3)	; save dsw
	bcs	20$
	stse$s	#ef2		; wait for ef
20$:

;	   handle result depending on which error parms are present

	mov	(r5),r2		; no. of params
	add	#6.,r5		; skip to 3rd param
	cmp	r2,#3.		; how many?
	blt	25$
	beq	22$

; all 4 are present - just return idsw,iesb(1) to caller

	mov	(r3),@(r5)+
	mov	(sp),@(r5)+
	br	100$

; only ests present - pass iesb(1) back but abort if dsw err

22$:
	tst	(r3)	; saved dsw
	bmi	idser	; skip ids err
	mov	(sp),@(r5)+ ; output iesb(1)
	br	100$

; no args present

25$:
	tst	(r3)	; saved dsw
	bmi	idser
	cmp	(sp),#EX$SUC	; iesb(1) OK ?
	beq	100$
	tst	(sp)
	bne	ieser

100$:
	add	#2.+16.+4.,sp	; pop off 8 iesb words,
				;  1 dsw-save wd, 2 tkname wds
	rts	pc		; bye

;
; Abort section. Print IESB(1), IDSW, and abort via TRAP 127.
;
;  entry: r4=sp=addr(8word sts block) r3=16.+r4=addr(saved dsw)
;  at r3+2,r3+4 is name of task to be spawned. At r3+6 is rtrn to
;  register save coroutine
;

idser:
ieser:

	mov	(r4),-(r3)	; copy iesb(1)
	sub	#ermlen+32.,sp	; space for output area
				; note: size>32. and size>ermlen+
				; {max expansion of input args}
	mov	sp,r0		; save its addr
				; for GTSK (and for EDMSG output area parm)
	gtsk$s	r0		; get task params
	mov	2(r0),-(r3)	; tkname wd 2
	mov	(r0),-(r3)	; tkname wd 1

	mov	#ermez,r1 	; input area parm
	mov	r3,r2		; arg block parm

	CALL	$EDMSG

	mov	sp,r2
	qiow$s	#io.wvb,.MOLUN,#ef2,,,,<r2,r1> ; output the error

	mov	r4,sp		; restore sp in case want to return
;				; some day


	TRAP	127.		; abort via TRAP
	abrt$s			; In case of return from trap

ermez:	.asciz	<12>/%2R -- Error in SPWN80. IESB(1): %D  DSW: %D/<15>
	.even
ermlen=<.-ermez+1>/2*2

	.end
