.TITLE SPAWN .IDENT /042184/ .ENABL LC .ENABL GBL .NLIST BEX ; .NLIST CND ;Produce a sane listing ; ;+ ;***** ; ; Formerly SPWNMCR 1.4XA...further revised for CCL V9.1 ; ; SPAWN supports normal task spawning/chaining as well as new options ; for "long command line" support and "run-pass-offspring-info" ; style directive for M V3.2/ M+ V1.0. The new options to SPAWN ; require CCL to be a privileged task. When CCL is privileged, ; and the system has RPOI$ support, command lines < 80. characters ; are dispatched normally; without RPOI$ support, OR command ; lines >/= 80. characters, the following special operations ; are performed: ; ; 1) Check if command is for "INS", if yes, pull ; the /CMD="..." switch out and see if ; command may be dispatched in pieces. ; 2) If command can be done in pieces, append ; the /RUN=REM switch to the INS command, ; set CCL's priority to top task, ; and spawn/chain to INS. (INS will pass ; it's first OCB to the target task and ; request it via "/RUN=REM") ; 3) Once INS has been requested, connect to INS ; so receive notification that the destination ; task is in and ready to execute. ; 4) For systems without RPOI$ support, the target ; task's OCB queued by CCL via INS will be ; relinked to CCL's parent task, if any. ; 5) Queue the /CMD="..." command line directly to ; the target task. NOTE: target must not ; be a CLI for this version...too many differences ; in alternate CLI suppport between M+V1. and ; MV4/M+V2 to worry about. ; ; -- P. Sorenson, 11/83 ; ;***** ; ; SPAWN.MAC supports 2 global entry points for CCL V9.1: ; ; PUTMCR attempts to spawn a command line to MCR... ; PUTCA attempts to spawn a command line to catchall ; task; task name defined @ $CANAM, default = MCR... ; for CCL as alternate CLI, defined at run-time ; for CCL as catchall ; ; WHEN CALLED: ; R0 = start address of command line to spawn ; R1 = length of command line, caller must ensure that ; R1 > 0 prior to call !!!! ; ; ON RETURN: ; Carry bit clear = success, R0-R5 indeterminate ; Carry bit set = error, address of ASCIZ message ; in R0. (R1-R5 indeterminate) ; ; ; ASSEMBLY OPTIONS: ; Define $ALCLI in pre-assembly file to include support ; for CCL as an alternate CLI....must have RPOI$ support. ; ; Define R$$POI if system includes request-pass-offspring-info ; directive (handled by RSXMC.MAC if CCL built privileged) ; ; Define $DSSPW if R$$POI support not available, but system ; supports D. Steinberg's special spawn directive (see ; Feb '81 MULTI-TASKER) ; ; Define $PRIV if CCL will be built as a privileged task. ; As a privileged task, SPAWN may queue command lines ; directly to the offspring task, bypassing some restrictions ; on command line length in the INS/RUN command. ; ONLY command lines to INStall will be handled in this ; manner !!!! (See description of "CCS" by R. Stammerjohn ; in April '83 (V16, #3) issue of the MULTI-TASKER). ; ; When CCL is to be privileged, SPAWN must be ; preassembled against RSXMC.MAC to define: ; R$$POI defined when RPOI$ support present ; R$$MPL defined for M+ systems ; ; ; ;***** ; ; Update 4/21/84 -- PRS; Minor fix, if alternate CLI and successfully ; chain to target, clear parent's name from ; INFOBF to flag that OCB has been re-linked ; to target task ; Update 6/2/84 -- PRS; Fix direct queue of command for task when ; ccl is priv and running under M+V2.x ; Update 7/31/84 -- PRS; Fix typos ;***** ;- ; .IIF DF $ALCLI .IIF NDF R$$POI R$$POI=0 ; Force R$$POI definition .IIF NDF M$$CRB M$$CRB=84. ; Define default size of MCR buffers .MCALL SPWN$,DIR$,STSE$S,EXST$S .IFDF R$$POI .MCALL RPOI$ .ENDC ;R$$POI .IFDF $PRIV .MCALL ALTP$,CNCT$,TCBDF$,PKTDF$,WTSE$S,WSIG$S TCBDF$ ;DEFINE TCB SYMBOLS PKTDF$ ; AND OCB SYMBOLS .ENDC ;$PRIV C.LGTH=M$$CRB-5. ; Define max command line length excluding ; the implied terminator HI$PRI=247. ; Highest priority to run at EFN1=1 ; EVENT FLAG FOR STOP EFN2=2 ; EVENT FLAG FOR CONNECT/WAIT ESC=33 ;MISC. ASCII CONSTANTS REQUIRED CR=15 QUOTE=42 SWTCH=57 ; ;***** ; .PSECT $PDATA,RO,D,LCL,CON,REL .IFDF $PRIV ; Only needed when privileged...for 2 step spawn/chain INSCMD: .ASCIZ /INS/ ;String to check for "INS"tall commands TSKSW: .ASCIZ /TASK=/ ;String to check for "/TASK=" switch CMDSW: .ASCIZ /CMD="/ ;String to check for "/CMD=" switch RUNSW: .ASCIZ /RUN=REM/ ;String to force remove-on-exit for task INSNAM: .RAD50 /...INS/ ;Task name of task INStaller .ENDC ;PRIV MCRNAM: .RAD50 /MCR.../ ; Spawned task name for PUTMCR entry point ; ; *** ERROR MESSAGES -- RETURNED TO CALLER IN R0 WITH CARRY SET ; EM1: .ASCIZ /CCL -- Command line too long/ EM2: .ASCIZ /CCL -- Error spawning command line/ .IFDF $PRIV ; Errors assoc. with 2 part spawn/chain EM3: .ASCIZ /CCL -- No task name specified/ EM4: .ASCIZ /CCL -- Error installing task/ EM5: .ASCII /CCL -- Failed to re-link OCB, parent-offspring / .ASCIZ /synchronization lost/ EM6: .ASCIZ /CCL -- Unable to queue command for task/ EM7: .ASCIZ /CCL -- Failed to connect to INStall/ .ENDC ;$PRIV .EVEN ; ;***** ; .PSECT $IDATA,RW,D,CON,LCL,REL ;PRS05 $CANAM:: CA2NAM: .RAD50 /MCR.../ ; Spawned task name for PUTCA entry ;PRS05 ; set at run-time for catchalls, used ;PRS05 ; as predefined for alternate CLI's ;PRS05 ; SPNOFS: SPWN$ ,,,,,EFN1,,EXSTAT ;DPB for synchronized spawns to ; offspring task CHNOFS: ; DPB for chaining to offspring task .IFDF R$$POI ;Support for CHAIN directive in system RPOI$ ,,,,,,,,,,,, .IFF ;Otherwise, do it the hard way SPWN$ ,,,,,,,,, R.POTK=S.PWTN ; Define RPOI$ symbolic offsets for equivalent R.POBL=S.PWCL ; fields in SPWN$ DPB R.POBF=S.PWCA R.POSC=.-CHNOFS ; No corresponding field in SPWN$ for R.POSC .BLKW 1 ; So reserve space for RPOI$ flags byte RP.OEX=200 ; Define RPOI$ flag byte bit patterns RP.ONX=2 RP.OAL=1 .ENDC ;R$$POI .IFDF $PRIV ;Must be privileged to do these functions ALTPRI: ALTP$ , ; Alter priority DPB CONECT: CNCT$ ,EFN2,,EXSTAT ; Connect to task DPB OFSNAM: .BLKW 2 ; Ultimate offspring's task name for ; "INS file/TASK=nnn/CMD="command" lines OFSCMD: .BLKW 2 ; 2 word defn block for command line to ; queue to offspring...length/start addrs OFSTCB: .WORD 0 ; Place to save offsprings TCB/OCB address RUNSAV: .BLKB 4 ; Place to save characters displaced by ; RUN=REM switch .ENDC ;$PRIV .PAGE ; ;***** ; .PSECT $CODE1,RO,I,CON,LCL,REL ;PRS05 PUTCA:: ; External entry point--chain to a catchall MOVB R1,NOSTOP ; Never wait for catchall task exit ; R1 guaranteed to be >0, 79 char. BGT ERR1 ; Process "command too long" .IFDF $PRIV ; If privileged... CLR OFSTCB ; Show don't know offspring's TCB address .IFDF R$$POI ; If have real RPOI$... TST OFSCMD ; Direct queue of command required ?? BEQ 9$ ; Branch if no, don't need top priority .ENDC ;R$$POI ; Without RPOI$, OR if must queue command line... MOV #HI$PRI,ALTPRI+A.LTPR ; Save top priority in DPB DIR$ #ALTPRI ; Make us top priority task 9$: ; Ref label .ENDC ;$PRIV ; ;***** ; ; Time for a little explanation... ; CLIFLG set non-zero if CCL is an alternate CLI. CLI's ; MUST NOT wait/stop for offspring whether RPOI$ or SPWN$ ; issued (in latter case, parent-offspring synch is lost ; unless CCL is privileged) ; NOSTOP is set non-zero when %$ seen in template, it is also an ; unconditional DON'T STOP flag whether RPOI$ or SPWN$ issued ; RING is set non-zero when %R seen in template to ring bell ; when CCL exits, this will ALWAYS stop for offspring via SPWN$ ; (unless explicitely told to exit by %$) ; SAVTYP is set to * or +. If "*" and have RPOI$ support or ; priv CCL without RPOI$ support, NOSTOP will be implied; ; otherwise a synchronized SPWN$ to offspring will be issued ; ;***** ; .IFDF $ALCLI ; If supporting CCL as alternate CLI TSTB CLIFLG ; Are we a CLI ?? BEQ 12$ ; Branch if no MOVB #RP.ONX,CHNOFS+R.POSC ; Else, redefine CHAIN control flags ; (pass only 1 OCB, DON'T EXIT) BR CHAIN ; MUST use RPOI$ directive 12$: ; Ref label .ENDC ;$ALCLI TSTB NOSTOP ; Requested to not stop for offspring ? ; ; *** If priv or have RPOI$ or special spawns, possible to chain .IFDF $PRIV ! R$$POI ! $DSSPW BNE CHAIN ; Branch if yes, chain to offspring TSTB RING ; Requested to ring bell on exit ? BNE SPAWN ; Branch if yes, spawn to offspring CMPB SAVTYP,#'* ; Is this the last action line? BNE SPAWN ; Branch if no, spawn to offspring ; else, implied NOSTOP ; ; *** If can't chain, %$ required to "chain" since lose parent-offspring sync .IFF BEQ SPAWN ; Branch if no, all conditions except ; NOSTOP will SPWN$ and STOP .ENDC ;$PRIV ! R$$POI ; ;***** ; ; CHAIN code will request task via SPWN$ or RPOI$. If privileged, ; a command line may be queued directly to the ultimate ; offspring task via QUECMD, followed by a manual re-linking ; of OCB's if RPOI$ support is unavailable. ; ; R0 - start address of command line ; R1 - length of command line ; R2 - address of target task name ; CHAIN: .IFNDF R$$POI ; If don't have RPOI$ support... .IFDF $DSSPW ; but do have special spawn support MOV #-1,CHNOFS+S.PWEF ; Signal special spawn in EFN .ENDC ;$DSSPW .ENDC ;R$$POI MOV R0,CHNOFS+R.POBF ; Set up command start address MOV R1,CHNOFS+R.POBL ; Set up command length MOV #CHNOFS+R.POTK,R3 ; Pickup place for task name MOV (R2)+,(R3) ; Set up offspring's task name MOV (R2),2(R3) 10$: DIR$ #CHNOFS ; Issue directive ; .IFDF R$$POI & $ALCLI ; with real RPOI$ AND alternate CLI support BCS 12$ ; Branch if RPOI$ failed CLR INFOBF+G.CCPT ; Show no more parent task ; .IFDF $PRIV ; If privileged BR 20$ ; See if queueing command directly .IFF ; If not... BR EXIT ; All done .ENDC ;$PRIV 12$: ; ref label ; .IFF ;R$$POI & $ALCLI ; no RPOI$ OR alternate CLI support ; .IFDF $PRIV ; If privileged BCC 20$ ; Branch on success .IFF ; If not... BCC EXIT ; Exit on success .ENDC ;$PRIV ; .ENDC ;R$$POI & $ALCLI ; .IFNDF R$$POI ; If don't have RPOI$ support... .IFDF $DSSPW ; but do have special spawn support CMP $DSW,#IE.ITS ; Error spawn to CLI with mult. parents ?? BEQ SPAWN ; Branch if yes, retry normal spawn .ENDC ;$DSSPW .ENDC ;R$$POI .IFDF R$$MPL ; For M+ BR ERR2 ; No recourse but error exit .IFF ;R$$MPL ; Under M though, if ...xxx active, try xxxTnn CMP $DSW,#IE.ACT ; Task already active ??? BNE ERR2 ; Branch if no, error CMP (R3),#^R... ; Trying prototype task ??? BNE ERR2 ; Branch if no, error MOV 2(R3),(R3) ; Reset name to xxxTnn MOV TINAM,2(R3) BR 10$ ; Branch to retry .ENDC ;R$$MPL 20$: .IFDF $PRIV ; Must be privileged CALL QUECMD ; Check for direct queue of command to task .IFNDF R$$POI ; If don't have RPOI$ support to re-link OCB's CALL RELINK ; Try to re-link OCB's by hand .ENDC ;R$$POI CLC ; Show success BR EXIT ; Exit asynchronously from offspring .ENDC ;$PRIV ; ;***** ; ; SPAWN performs synchronized spawns to offspring task. ; If privileged, also allowed to queue command lines directly ; to offspring; defined previously by "CHKCMD" which also ; forces spawn to ...INS rather then MCR... ; ; R0 - start address of command line ; R1 - length of command line ; R2 - address of target task name ; ; SPAWN: ; Synchronize to offspring's exit status MOV R0,SPNOFS+S.PWCA ; Define command start address MOV R1,SPNOFS+S.PWCL ; and length MOV #SPNOFS+S.PWTN,R3 ; Pickup place for offspring's name MOV (R2)+,(R3) ; Define offspring's name MOV (R2),2(R3) 10$: DIR$ #SPNOFS ; Spawn command to offspring task .IFDF R$$MPL ; Under M+, should've worked BCS ERR2 ; Branch on error .IFF ;R$$MPL ; Under M though, if ...xxx active, try xxxTnn BCC 20$ ; Branch on succees CMP $DSW,#IE.ACT ; Task already active ??? BNE ERR2 ; Branch if no, error CMP (R3),#^R... ; Trying prototype task ??? BNE ERR2 ; Branch if no, error MOV 2(R3),(R3) ; Reset name to xxxTnn MOV TINAM,2(R3) BR 10$ ; Branch to retry .ENDC ;R$$MPL 20$: .IFDF $PRIV ; Must be privileged CALL QUECMD ; Queue command to offspring .ENDC ;$PRIV ; Synchronize to offspring... STSE$S #EFN1 ; stop till it emits status CLC ; Show success BR EXIT ; ; *** Error traps/messages .ENABL LSB ERR1: MOV #EM1,R0 ; Pickup error message BR 10$ ; and continue ERR2: MOV #EM2,R0 ; Pickup error message .IFDF $PRIV ; Errors assoc. with privileged operations BR 10$ ; and continue ERR3: MOV #EM3,R0 ; Pickup error message BR 10$ ; and continue ERR4: MOV #EM4,R0 ; Pickup error message BR 10$ ; and continue ERR5: MOV #EM5,R0 ; Pickup error message BR 10$ ERR6: MOV #EM6,R0 BR 10$ ERR7: MOV #EM7,R0 .ENDC ;$PRIV 10$: SEC ; Show failure .DSABL LSB EXIT: .IFDF $PRIV ; Privileged task must return to installed priority ROR R1 ; Save carry bit state TST ALTPRI+A.LTPR ; Altered our priority ??? BEQ 5$ ; Branch if no CLR ALTPRI+A.LTPR ; Setup to drop to installed priority DIR$ #ALTPRI ; do it 5$: ROL R1 ; Restore carry bit from R1 .ENDC ;$PRIV RETURN ; Return to caller ; .PAGE .SBTTL LOCAL SUBROUTINES -- Privileged operations .IFDF $PRIV ; Only privileged task needs these routines ; ;+ ;***** ; ; MATCH - Checks for exact match of 2 strings. ; ; WHEN CALLED: ; R0 - points to 1st character in master string ; R2 - points to ASCIZ string to check for in master string ; ; ON RETURN: ; Carry clear = success ; R0 - points to character following matched string ; R1 - original contents of R0 ; R2 - points to null terminator in match string ; ; Carry bit set = failure ; R0 = R1 - not updated from call ; R2 - points to null terminator in match string ; ;***** ;- MATCH: MOV R0,R1 ;COPY START ADDRESS 2$: CMPB (R0)+,(R2)+ ;CHECK STRINGS BNE 8$ ;BRANCH IF DON'T MATCH TSTB (R2) ;END OF TEST STRING ?? BNE 2$ ;BRANCH IF NO, CHECK AGAIN BR 10$ ;ELSE, RETURN WITH C-BIT CLEAR 8$: MOV R1,R0 ;NO MATCH, RESTORE R0 SEC ;SHOW FAILURE 10$: RETURN ; AND RETURN TO CALLER .PAGE ; ;+ ;***** ; ; CHKCMD - Checks comand string for the special "INS xxx/CMD=".."" ; command type. If recognized, all pertinent variables will ; be defined for the direct queuing of the quoted string ; in /CMD switch to the designated offspring task. The target ; task MUST be given an explicit task name via /TASK= switch ; and it MUST NOT be a prototype, i.e. ...xxx, task name. ; ; Special consideration is given to M+ systems; MCR... will ; activate ...CA. as xxxTnn, where xxx = RAD50 of 1st 3 characters ; in original MCR line. This presents a name conflict when ; CCL attempts to activate the task using the same name. ; So, CCL will alter its task name to CA.Tnn is a conflict is ; identified. ; ; WHEN CALLED: ; R0 - start address of command line ; R1 - length of command line ; ; ON RETURN: ; R0 - start address of command line ; R1 - length of command line ; R2 - address of task name to spawn/chain command to ; either MCR..., or ...INS ; OFSCMD - defines command for offspring ; OFSNAM - defines name of ultimate offspring task ; ; NOTE: Error returns will be made directly to the error exit points ; ;***** ;- CHKCMD: CLR OFSCMD ; Show no command for offspring yet .IFDF R$$POI ; If have RPOI$ directive CMP R1,#C.LGTH ; With RPOI$, can directly chain to BLE 52$ ; offspring provided command < max length .ENDC ;R$$POI ; ; *** (NOTE: without R$$POI support we assume don't have /CMD ; support in INStall (MV3.2, M+V1.0), so all INS lines ; will be handled as a special spawn/chain) ; MOV R1,R5 ; Save command length MOV #INSCMD,R2 ; Setup "INS" string CALL MATCH ; Check if it's an install request .IFDF R$$POI ; With RPOI$ support BCS 58$ ; Branch if can't split command... ; know line too long .IFF ;R$$POI ; Without RPOI$ support BCS 51$ ; Not INS/RUN, try normal spawn/chain .ENDC ;R$$POI 10$: MOV R1,R4 ; Save start addr of command ADD R5,R1 ; Reset R1 to end-of-string pointer CLRB (R1) ; Make string ASCIZ MOV #OFSNAM+4,R3 ; Clear name of offspring task CLR -(R3) CLR -(R3) 15$: MOVB (R0)+,R2 ; Pickup character BEQ 50$ ; Branch on end-of-string CMPB R2,#SWTCH ; Hit "/" in command string BNE 15$ ; Branch if no, check again MOV #TSKSW,R2 ; Check if its a "/TASK=" switch CALL MATCH BCS 22$ ; Branch if not MOV PC,R1 ; Allow .'s in taskname CALL $CAT5 ; Convert ascii to rad50 MOV R1,(R3) ; Save 1st part of name BCS 20$ ; Branch if nothing else CALL $CAT5 ; Else, convert 2nd half of name MOV R1,2(R3) ; Save it BCC 15$ ; Branch on even 3 chars 20$: DEC R0 ; > 3 rad50 chars, adjust pointer BR 15$ ; Branch to continue 22$: MOV #CMDSW,R2 ; Check if at the "/CMD" switch CALL MATCH BCS 15$ ; Branch if not, check again ; ; *** Almost ready for spawn to install the requested task ; R0 - points to 1st character in command line for offspring ; R1 - points to "C" in /CMD="..." ; R4 - start address of INS command line ; R5 - length of original INS command line 25$: MOV (R3),R2 ; Pickup 1st 1/2 of name BEQ 56$ ; Branch if undefined, error CMP R2,#^R... ; Prototype task name ?? BEQ 56$ ; Branch if yes, don't allow it .IFDF R$$MPL ; Under M+ system CMP R2,CCLNAM ; Name conflicts with ourself ?? BNE 30$ ; Branch if no, legit name .IFDF $ALCLI ; CCL could be an alternate CLI TSTB CLIFLG ; CCL acting as CLI ?? BNE 56$ ; Branch if yes, can't fool with name .ENDC ;$ALCLI CALL $SWSTK,29$ ; Switch to system state MOV $TKTCB,R0 ;; Pickup our TCB address MOV #^RCA.,T.NAM(R0) ;; Change our name RETURN ;; Back to task state 29$: ; Ref label .ENDC ;R$$MPL 30$: MOV R5,R2 ; Recover length ADD R4,R2 ; offset to end of string 32$: CMPB -(R2),#QUOTE ; Look backward for closing quote BNE 32$ ; Loop til found SUB R0,R2 ; Compute length of /CMD= line BLT 58$ ; Branch if bad syntax BEQ 45$ ; Branch if null command CMP R2,#C.LGTH ; Check length of /CMD line BGT 58$ ; Branch if > 79., error 40$: MOV R2,OFSCMD ; Save length of offspring's command line MOV R0,OFSCMD+2 ; and start address MOV #RUNSAV,R2 ; Pickup area to save 1st 3 char of line MOVB (R0)+,(R2)+ ; Push 1st 3 characters into save buffer MOVB (R0)+,(R2)+ MOVB (R0),(R2) 45$: MOV #RUNSW,R0 ; Pickup "RUN=REM" string address 46$: MOVB (R0)+,(R1)+ ; Copy RUN=REM over CMD="xx BNE 46$ ; Loop til done DEC R1 ; Point to new terminator MOV R4,R0 ; Recover start address SUB R4,R1 ; Compute length of INS line TST R2 ; Just replaced /CMD="" for /RUN=REM ?? BEQ 52$ ; Branch if yes, no command to queue MOV #INSNAM,R2 ; Spawn/chain directly to ...INS MOVB #RP.ONX,CHNOFS+R.POSC ; Define chain control ; (pass 1 OCB, must NOT exit after chain) BR 59$ ; Branch to continue 50$: ; NOT VALID "INS" COMMAND FOR SPECIAL HANDLING MOV R4,R0 ; Recover start address of command 51$: MOV R5,R1 ; Recover length of command line 52$: MOV #MCRNAM,R2 ; Default spawn/chain to MCR... MOVB #RP.ONX!RP.OEX,CHNOFS+R.POSC ;Define CHAIN control ; (pass 1 OCB, exit on success) BR 59$ ; Branch to continue ; ; *** Error trap...return direct to error exit points ; 56$: MOV #ERR3,(SP) ; Bad task name BR 59$ 58$: MOV #ERR1,(SP) ; Bad command line 59$: RETURN ; Back to caller .PAGE ; ;+ ;***** ; ; QUECMD - Queues command line for non-CLI tasks via linked list ; @$MCRCB under 11M, or @$CLICQ under 11M+ V2.x. For this to ; work correctly, CCL must be the top ; (or nearly so) task in the system so it can field INStall's ; exit status and block offspring's execution until the ; command line is queued in pool. Also banking on fact ; that INStall must exit before the task INS is installing ; starts. This latter restriction is a little tenuous, so ; obscure errors/unreliable activity may be expected when ; using this code to install tasks that have higher priority ; then INS !!! ; ; WHEN CALLED: ; R3 - address of task name requested to activate offspring ; (will always be ...INS/INSTnn) ; All registers assumed free to use... ; ; ON RETURN: ; Success is only return to caller ; ; NOTE: Error returns will be made directly to the error exit points ; ;***** ;- QUECMD: MOV OFSCMD,R5 ; Pickup length of command for offspring BEQ 29$ ; Branch if 0, all done MOV OFSCMD+2,R4 ; Pickup start address MOV R4,R1 ; Copy start MOV #RUNSAV,R0 ; Pickup pointer to saved chars MOVB (R0)+,(R1)+ ; Restore 1st 3 bytes of command line MOVB (R0)+,(R1)+ MOVB (R0),(R1) .IFDF R$$MPL ; Special handling for M+ CMP (R3),#^R... ; Chained/spawned prototype task ?? BNE 5$ ; Branch if no MOV 2(R3),(R3) ; Yes, always scan for xxxTnn MOV TINAM,2(R3) ; due to exec level dispatching 5$: ; Ref label .ENDC ;R$$MPL MOV (R3)+,CONECT+C.NCTN ; Define task to connect to... MOV (R3),CONECT+C.NCTN+2 ; this will always be INStall 6$: DIR$ #CONECT ; Connect to INS BCS 24$ ; Branch if failed WTSE$S #EFN2 ; WAIT for the install CMP EXSTAT,#EX$SUC ; Check for success BGT 26$ ; Branch if not success OR warning 10$: MOV #OFSNAM,R3 ; Pickup offspring's name ; (know this can't be ...xxx task) CALL $SWSTK,20$ ; Switch to system state CALL $SRSTD ;; Search for task just installed BCS 19$ ;; Branch if not found...oh-oh BIT #T3.CLI,T.ST3(R0) ;; Offspring a CLI ?? BNE 19$ ;; Branch if yes, flying install ;; unsupported .IFDF R$$MPL & V$$RSN ;; M+ V1.x and V2.x use different command queue ;; M+ V2.X uses secondary pool command packets ;; currently unsupported.... .ERROR Privileged CCL task is currently unsupported for RSX-11M-Plus V2.x .IFF ;R$$MPL & V$$RSN ;; M+ V1.X and MV3.X,V4.X are the same MOV R0,-(SP) ;; Save offspring's TCB address MOV #M$$CRB,R1 ;; Pickup size of pool buffer needed CALL $ALOCB ;; Try to allocate it MOV (SP)+,R2 ;; Recover TCB address BCS 19$ ;; Branch if allocation failed MOV R0,R1 ;; Copy address of buffer TST (R0)+ ;; Skip link word MOV R2,(R0)+ ;; Identify TCB destined for 15$: MOVB (R4)+,(R0)+ ;; Copy command to buffer SOB R5,15$ ;; til done MOVB #ESC,(R0) ;; Insert normal SPWN$ terminator MOV #$MCRCB,R0 ;; Pickup list-head for command lines MOV (R0),(R1) ;; Setup link word in new buffer MOV R1,(R0) ;; and link buffer into list .ENDC ;R$$MPL & V$$RSN MOV R2,OFSTCB ;; Save offspring TCB for task state 19$: RETURN ;; Back to task state 20$: TST OFSTCB ; Found offspring ?? BNE 29$ ; Branch if yes, worked MOV #ERR6,(SP) ; Else, setup error return BR 29$ 24$: MOV #ERR7,(SP) ; Error connecting to install BR 29$ 26$: MOV #ERR4,(SP) ; Error installing task BR 29$ 29$: RETURN .page .IFNDF R$$POI ; ;+ ;***** ; ; RELINK - for systems that do not have RPOI$ support, ; this subroutine re-links ONE OCB from the current task ; (us) to our offspring task. Offspring task name ; must be pointed to by R3, and be a modifiable location. ; ; In current coding, the offspring will be one of: ; MCR... - normal case ; ...CAn/CAnTnn - when activating next catchall ; @OFSNAM - When re-linking OCB of offspring that has ; already had command line queued for it directly ; via QUECMD ; ; WHEN CALLED: ; R3 - points to offspring's task name ; CHNOFS+R.POSC - equivalent bit settings controlling real RPOI$ ; directive...only RP.OEX (exit on success) used ; ; ON RETURN: ; Success is only return to caller ; ; Errors ;***** ;- ; RELINK: .IFDF R$$MPL ; Special handling for M+ CMP (R3),#^R... ; Chained/spawned prototype task ?? BNE 5$ ; Branch if no MOV 2(R3),(R3) ; Yes, always scan for xxxTnn MOV TINAM,2(R3) ; due to exec level dispatching 5$: ; Ref label .ENDC ;R$$MPL CALL $SWSTK,60$ ; Switch to system state MOV OFSTCB,R0 ;; QUECMD already found offspring ?? BNE 12$ ;; Branch if yes 10$: CALL $SRSTD ;; Search installed tasks for target BCS 59$ ;; Branch if offspring not found 12$: MOV R0,R4 ;; Save our child's TCB address ADD #T.OCBH,R0 ;; Point to child's OCB list head CLR R2 ;; Show no OCB yet MOV $TKTCB,R5 ;; Pickup our TCB address 16$: MOV (R0),R1 ;; Pickup next OCB queued to child BEQ 20$ ;; Branch on last OCB CMP O.PTCB(R1),R5 ;; OCB point to us ?? BNE 18$ ;; Branch if no, check next MOV R0,R2 ;; Save address of preceeding OCB MOV R1,R3 ;; and OCB to re-link 18$: MOV R1,R0 ;; Step to next OCB BR 16$ ;; Loop til done 20$: MOV R2,OFSTCB ;; Save address of OCB for task state BEQ 59$ ;; If 0, no OCB queued in offspring... ;; very bad error ; ; *** Now have address of newest OCB in child queued by ourselves in R3, ; check if we have a parent task... ; MOV R5,R0 ;; Pickup our TCB address ADD #T.OCBH,R0 ;; Point to our OCB list head MOV (R0),R1 ;; Get 1st OCB in our queue BEQ 30$ ;; Branch if nothing ; ; *** Found our parent...pass it on to our child by replacing the ; OCB we queued via the SPAWN directive with our parent's ; OCB. NOTE: some undocumented information is passed in the ; OCB status words for CLI'S; see comment's below ; MOV (R1),(R0) ;; Un-link 1st OCB BNE 24$ ;; Branch if not last OCB MOV R0,2(R0) ;; Last OCB must close list 24$: MOV R1,(R2) ;; Re-link our OCB into offspring's list MOV (R3),(R1) ;; Update link forward BNE 26$ ;; Branch if not last MOV R1,T.OCBH+2(R4) ;; Last OCB must close child's list 26$: MOV O.MCRL(R3),O.MCRL(R1) ;; Update command line address MOV O.STAT+4(R3),O.STAT+4(R1) ;; Copy CLI specific MOV O.STAT+6(R3),O.STAT+6(R1) ;; information BR 40$ ;; Branch to propagate CLI prompt ; ; *** We have no parent...remove child's OCB queued by spawn ; 30$: MOV (R3),(R2) ;; Reset link forward BNE 33$ ;; Branch if not last OCB MOV R2,T.OCBH+2(R4) ;; Close OCB list in child's TCB 33$: ;; ref label ; ; *** Propagate our T3.MCR bit...if child's a CLI, must do it via ; command line terminator. ; 40$: BIT #T3.CLI,T.ST3(R4) ;; Child a CLI ?? BEQ 45$ ;; Branch if no BIT #T3.MCR,T.ST3(R5) ;; Do we prompt on exit ?? BEQ 50$ ;; Branch if no, almost done MOV O.MCRL(R3),R0 ;; Else, pickup command line address ADD #4,R0 ;; Skip link & TCB address ADD CHNOFS+R.POBL,R0 ;; Offset to end-of-command MOVB #CR,(R0) ;; Change terminator to carriage return BR 50$ ;; Branch to finish 45$: BIT #T3.MCR,T.ST3(R5) ;; Propagate our T3.MCR bit BEQ 49$ BIS #T3.MCR,T.ST3(R4) ;; Have child prompt BR 50$ ;; Branch to finish up 49$: BIC #T3.MCR,T.ST3(R4) ;; Have child exit silently ; ; *** Wayward packet sitting in pool @ R3, must now deallocate it ; 50$: MOV R3,R0 ;; Copy pointer MOV #O.LGTH,R1 ;; Define size of packet CALL $DEACB ;; Deallocate it to free pool DEC T.RDCT(R5) ;; Decrement our offspring count BIC #T3.MCR,T.ST3(R5) ;; we will exit quietly 59$: RETURN ;; Back to task state ; ; *** ALL DONE... ; 60$: TST OFSTCB ; Found offspring's OCB ??? BEQ 68$ ; Branch if no, bad error BITB #RP.OEX,CHNOFS+R.POSC ; Exit on completion ??? BEQ 69$ ; Branch if no EXST$S #EX$SUC ; Yes, exit with success 68$: MOV #ERR5,(SP) ; Setup error return 69$: RETURN .ENDC ;R$$POI .ENDC ;$PRIV ; .END