.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,,,, ; 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