	.title	CHAN80
	.ident	/002/
;+
; File CHAN80.MAC
;
; Entry points: CALL CHAN80(ITKASC,IBUF [,IDS])
;
; Chains to user-specified task (taskname in ASCII), with user-
; specified buffer, with exit on successful completion of the chain.
; All Parent connections (OCB's) are passed to the target task.
;
; NOTE: Because the pass-all-OCB option is chosen, CHAN80 cannot chain
; to MCR or any other Command Line Interpreter. Use SPWN80 instead.
;
; 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 return value:
;
;  IDS = directive status from chain (applies only if could not chain)
;    NOTE: also returns IDS value if illegal name was specified, in which
;    case returns IE.INS (task-not-installed - defined under 11M v4.0 as -2)
;
; If IDS parameter is omitted, CHAN80 will abort on error conditions;
; i.e., will assume the caller chooses not to handle them. Before aborting,
; prints 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,rpoi$s,stse$s
	.mcall	qiow$s,gtsk$s
	.enable	lsb
	.enable	lc

CHAN80::
	jsr	r5,$savrg	; save nonvolatile reg's (3-5)
savoff=10			; offset curr sp to caller's address
	mov	savoff(sp),-(sp) ; save rtrn addr in convenient place
				;  for possible error print

;	   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)
	mov	sp,r3		; save pointer to tkname
tkoff=-6			; offset of tk name from vgn stack
	mov	#0,-(sp)	; (don't use CLR) - set name-OK ind
	bcs	6$		; skip if cat5 terminated early
	call	$cat5		; else convert 3 more
	mov	r1,2(r3)

6$:	bcc	10$		; now J if got 6 good chars
	tst	r2		; see if NUL is terminator
	beq	10$		; yes - all is ok
	cmpb	r2,#040		; how about blank
	beq	10$		; yes - all ok
	mov	#IE.INS,-(r3)	; else error - just indicate task-not-installed
	br	17$		; and go process error


10$:

; 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

;
; Chain
;
	rpoi$s	r3,,,  ,  ,  ,4(r5),r0,#RP.OEX!RP.OAL

;               ^              ^     ^       ^
;               |              |     |       |
;              tkname         cmd   cmdlen  flags
;                                             Exit on compl
;					      Pass-all-connections

	mov	$dsw,-(r3)	; save dsw

17$:
;	   If we got here must have dsw error (or bad name)
;	   (Note that this error-handling is simpler than SPWN80's)

	mov	(r5),r2		; no. of params
	add	#6.,r5		; skip to 3rd param
	cmp	r2,#3.		; how many params?
	blt	idser		; abort if no IDS parameter

; IDS param present, so pass him the DSW value

	mov	(r3),@(r5)+


; Done. Cleanup and return

100$:
	add	-tkoff+2,sp	; pop off dsw value, and everything beyond tknam
	rts	pc		; bye

;
; Abort section. Print err info and abort via TRAP 127.
;
; sp=r3=pointer to error info on stack
; 0(sp)   ids value
; 2-4(sp) tkname(target) as converted by cat5 calls
; 6(sp)   saved return addr of caller
; pop  -tkoff+2  before issuing any return to caller
;
;

idser:
ieser:

	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	r3,r2		; arg block parm
	mov	2(r0),-(r2)	; caller tk's name wd 2
	mov	(r0),-(r2)	; caller tk's name wd 1

	mov	#ermez,r1 	; input area parm

	CALL	$EDMSG

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

	mov	r3,sp
	add	#-tkoff+2,sp	; restore sp in case want to return
;				; some day


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

ermez:	.ascii	<12><15>/%2R -- Error in CHAN80./
	.asciz	/  IDS: %D  DESTTK: %2R  CALL: %P/<15>
	.even
ermlen=<.-ermez+1>/2*2

	.end
