.TITLE CLISUB - SUPPORT SUBROUTINES FOR ALTERNATE CLI'S .IDENT /123183/ .ENABL GBL .ENABL LC .NLIST BEX ; ;+ ;***** ; ; CLISUB - Contains various support routines required to ; manipulate non-DEC alternate CLI tasks. The basic ; flow for setting up an alternate CLI is similar to ; that supported under M V4.0 and M+ V2.0: ; ; 1) The CLI task must be installed ; ; 2) The CLI is initialized by setting up a CLI control block ; in system pool which defines the CLI name, ; prompt strings, # attached terminals, pointer ; back to the task's TCB. This control block is ; ALWAYS the 1st packet in the task's receive queue ; and is identified from command packets by a null ; terminal UCB field. The T3.CLI bit is set to inform ; the system that this is now a CLI. The CLI ; must be inactive (TS.EXE set), and cannot receive ; send-data packets (T3.NSD set). ; ; 3) Each terminal may then be set to use this CLI ; which simply involves linking the U.CLI pointer ; in the terminal UCB to the CLI control block ; and incrementing the # attached terminals. ; ; 4) The CLI may be eliminated when there are no terminals ; attached to the CLI. The CLI is aborted, all ; packets in the task's receive queue are deallocated, ; and the T3.CLI bit is cleared. ; ; The format of the CLI control block (CCB) allocated for each ; alternate CLI is, ; ; ------------------------------------------------- ; ! C.LILK = Receive queue link word (2) ! ; ------------------------------------------------- ; ! C.LIUA = Always 0, distinguishes this ! ; ! packet from unsolicited input ! ; ! which would define TT:'s UCB (2)! ; ------------------------------------------------- ; ! C.LISZ = Size of CCB packet in bytes (2)! ; ------------------------------------------------- ; ! C.LIST = CLI status/control bits (2) ! ; ------------------------------------------------- ; ! C.LINM = RAD50 CLI name, not necessarily! ; ! identical to CLI's task name (4)! ; ------------------------------------------------- ; ! C.LINT = Number of terminals attached ! ; ! to CLI (2) ! ; ------------------------------------------------- ; ! C.LITA = TCB address of CLI (2) ! ; ------------------------------------------------- C.LIFX=size ; ------------------------------------------------- of fixed defn ; ! C.LIPR = Start of CLI prompts; ! ; ! Full (CTRL-C) prompt string ! ; ! in ASCIZ followed by... ! ; ! Default prompt string (ASCIZ) ! ; ! (variable length data block) ! ; ------------------------------------------------- ; ; NOTE: DEC supplied CLI's (MCR and/or DCL) will define C.LITA/C.LIPR ; fields in system common @$MCRPT (and $CLIPT for DCL) when alternate ; CLI support is selected @ SYSGEN. ; ; CLI status bits @ C.LIST are defined when the CLI is initialized ; according to the following bit settings: ; ; CL.ILO = 100000; Set if CLI allows input from un-logged in TT's ; CL.INL = 40000; Set if CLI should issue default prompt ; on null input command lines ; CL.IPR = 20000; Set if CLI allows only Privileged users ; to set terminals to this CLI ; ; Error status is returned using the task's directive status word ; (@#$DSW) using standard RSX coding, eg. +1 = success, -ve = error. ;***** ; ; GLOBAL ENTRY POINTS: ; .CILOC - Locates all CLI tasks in the system ; .CIUCB - Gets information on the terminal being set to a CLI ; .CIINI - Initializes a task as an alternate CLI ; .CISET - Sets a terminal's CLI to a specified task ; .CIELI - Eliminates a CLI task from the system ; ;***** ; ; Update 12/31/83 -- PRS; Original edit ; Update 3/12/84 -- PRS; final (??) debugging ; ;***** ;- ; .MCALL TCBDF$,UCBDF$,LCBDF$,ABODF$ TCBDF$ ; DEFINE TCB OFFSETS UCBDF$ ; AND UCB OFFSETS LCBDF$ ; AND LCB OFFSETS ABODF$ ; AND ABORT CODES .MCALL CCBDF$ CCBDF$ ; DEFINE CLI CONTROL BLOCK OFFSETS/BIT PATTERNS .PSECT $PDATA,RO,D,LCL,CON,REL MCRNM: ; DEFINE DEC CLI NAMES .RAD50 /MCR / .IFDF R$$MPL ; ONLY M+ HAS DCL SUPPORT DCLNM: .RAD50 /DCL / .ENDC ;R$$MPL .PAGE .PSECT $PCODE,RO,I,LCL,CON,REL ; ;+ ;***** ; ; .CILOC - Locates all initialized CLI tasks (T3.CLI bit set) ; in the system...including MCR/DCL. Information for each ; CLI is stored in a null terminated list @$CILST, and consists ; of: ; 1) Address of 2 word entry = CLI's name (not task name!!) ; e.g. address of C.LINM in CLI's CCB ; 2) Address of CLI's TCB address/prompt data block ; e.g. address of C.LITA in CLI's CCB ; ; ; Returns: ; Carry bit clear (no failure possible), R5 points ; to start of CLI name/TCB list. ; List starts at global location $CILST; $CINUM contains ; number of 2 word entries in list = # CLI's in system. ; ; ;***** ;- ; .CILOC:: ; GLOBAL ENTRY POINT CLR $CINUM ; SHOW NO CLI'S YET MOV #$CILST,R5 ; GET ADDRESS FOR TCB LIST CALL $SWSTK,30$ ; SWITCH TO SYSTEM STATE MOV $TSKHD,R0 ;; PICKUP START OF STD LIST 2$: BIT #T3.CLI,T.ST3(R0) ;; TASK A CLI ?? BEQ 25$ ;; BRANCH IF NO CMP R0,$MCRPT ;; MCR DISPATCHER ?? BNE 10$ ;; BRANCH IF NO MOV #MCRNM,(R5)+ ;; DEFINE MCR'S CLI NAME MOV #$MCRPT,(R5)+ ;; DEFINE ADDRESS OF MCR TCB/PROMPT DATA BR 25$ ;; AND KEEP LOOKING 10$: .IF DF R$$MPL ;; M+ ALSO HAS DCL CMP R0,$CLIPT ;; DCL DISPATCHER ?? BNE 15$ ;; BRANCH IF NO MOV #DCLNM,(R5)+ ;; DEFINE DCL'S CLI NAME MOV #$CLIPT,(R5)+ ;; DEFINE ADDRESS OF DCL TCB/PROMPT DATA BR 25$ ;; AND KEEP LOOKING .ENDC ;R$$MPL 15$: MOV T.RCVL(R0),R1 ;; NON-DEC CLI, PICKUP 1ST RCV PACKET BEQ 25$ ;; BRANCH IF NOTHING THERE...SHOULDN'T HAPPEN TST C.LIUA(R1) ;; IS PACKET THE CLI CONTROL BLOCK ?? BNE 25$ ;; BRANCH IF NO...ALSO SHOULDN'T HAPPEN MOV R1,(R5) ;; SETUP POINTER TO ADD #C.LINM,(R5)+ ;; CLI'S NAME MOV R1,(R5) ;; SETUP POINTER TO ADD #C.LITA,(R5)+ ;; CLI'S TCB ADDRESS/PROMPT DATA 25$: MOV T.TCBL(R0),R0 ;; FOLLOW STD LIST BNE 2$ ;; TIL HIT NULL TASK CLR (R5) ;; SET END-OF-CLI-LIST MARK SUB #$CILST,R5 ;; COMPUTE NUMBER OF CLI'S FOUND ASR R5 ASR R5 MOV R5,$CINUM ;; AND SAVE IT RETURN ;; BACK TO TASK STATE ; 30$: RETURN ; RETURN TO .CILOC CALLER .PAGE ; ;+ ;***** ; ; .CIUCB - Finds the Unit Control Block (UCB) address and other ; info for the device/unit defined @$CIDEV/$CIUNT. ; NOTE: have a special case defined when $CIDCB (pointer to ; device's DCB) has been defined, e.g. from previous call, ; scan of DCB's starts at $CIDCB. ; ; Return: ; Carry bit set on failure, clear on success. ; $CIUCB,$CIUC2,$CICLI,$CIDCB all defined on success. ; ;***** ;- ; .CIUCB:: ; GLOBAL ENTRY POINT CALL $SWSTK,50$ ; SWITCH TO SYSTEM STATE MOV $CIDEV,R4 ;; PICKUP DESIRED DEVICE CMP R4,#"TI ;; WAS IT TI: ?? BNE 3$ ;; BRANCH IF NO MOV $TKTCB,R0 ;; PICKUP OUR TCB ADDRESS MOV T.UCB(R0),R0 ;; THEN TI:'S UCB ADDRESS BR 25$ ;; ALMOST DONE 3$: MOV $CIUNT,R3 ;; PICKUP UNIT # MOV $CIDCB,R2 ;; DCB ADDRESS ALREADY DEFINED ?? BNE 13$ ;; BRANCH IF YES, CONTINUE FROM HERE MOV #$LOGHD,R2 ;; ELSE, START SEARCH WITH LOGICAL ASSIGNS 5$: MOV (R2),R2 ;; GET NEXT LCB BEQ 10$ ;; BRANCH ON END-OF-LIST TSTB L.TYPE(R2) ;; GLOBAL ENTRY ?? BEQ 8$ ;; BRANCH IF YES, CHECK IT CMP L.UCB(R2),R0 ;; BELONGS TO US ?? BNE 5$ ;; BRANCH IF NO 8$: CMP L.NAM(R2),R4 ;; NAMES MATCH ?? BNE 5$ ;; BRANCH IF NO CMPB L.UNIT(R2),R3 ;; UNIT #'S MATCH ?? BNE 5$ ;; BRANCH IF NO MOV L.ASG(R2),R0 ;; PICKUP ASSIGNED UCB BR 25$ ;; AND CONTINUE THROUGH REDIRECTS 10$: MOV #$DEVHD,R2 ;; PICKUP DCB LIST POINTER 11$: MOV (R2),R2 ;; GET NEXT DCB ADDRESS BEQ 40$ ;; BRANCH ON END-OF-LIST 13$: CMP D.NAM(R2),R4 ;; NAMES MATCH ?? BNE 11$ ;; BRANCH IF NO CMPB D.UNIT(R2),R3 ;; LO DCB UNIT # > DESIRED UNIT ??? BHI 11$ ;; BRANCH IF YES, SKIP IT CMPB D.UNIT+1(R2),R3 ;; HI DCB UNIT # < DESIRED UNIT ??? BLO 11$ ;; BRANCH IF YES, SKIP IT MOV R2,$CIDCB ;; SAVE DCB ADDRESS ; 20$: MOV D.UCB(R2),R0 ;; GET 1ST UCB ADDRESS CLR R1 ;; PICKUP LOWEST UNIT FOR DCB BISB D.UNIT(R2),R1 ;; INTO R1 TO COMPUTE SUB R1,R3 ;; INDEX INTO UCB LIST BEQ 25$ ;; BRANCH IF AT RIGHT UCB MUL D.UCBL(R2),R3 ;; COMPUTE OFFSET TO CORRECT UCB ADD R3,R0 ;; ADD OFFSET TO 1ST UCB 25$: MOV U.RED(R0),R0 ;; PICKUP REDIRECT UCB CMP U.RED(R0),R0 ;; END-OF-CHAIN ?? BNE 25$ ;; BRANCH IF NO 30$: BIT #DV.TTY,U.CW1(R0) ;; IS THIS REALLY A TERMINAL DEVICE ?? BEQ 40$ ;; BRANCH IF NO, FAILURE MOV R0,$CIUCB ;; SAVE UCB ADDRESS MOV U.CW2(R0),$CIUC2 ;; AND 2ND CHAR. WORD MOV U.CLI(R0),$CICLI ;; AND POINTER TO CLI'S TCB ADDR MOV #IS.SUC,R0 ;; SET SUCCESS CODE BR 48$ ;; AND GET OUT 40$: MOV #IE.IDU,R0 ;; INVALID DEVICE CODE 48$: ;; COMMON EXIT POINT MOV R0,@#$DSW ;; SAVE STATUS CODE RETURN ;; AND BACK TO TASK STATE 50$: TST @#$DSW ; CHECK COMPLETION CODE BPL 55$ ; BRANCH ON SUCCESS SEC ; ELSE, SHOW FAILURE 55$: RETURN ; RETURN TO CALLER ; .PAGE ; ;+ ;***** ; ; .CIINI - Initializes a task to be an alternate CLI. Task must ; be inactive, not allow send data, and not already flagged ; as a CLI. A CLI control block will be allocated and linked ; into the task's receive data queue. ; ; Returns: ; Carry set on failure, clear on success ; all registers assumed free to be used ; $CICCB,$CITCB defined on successful completion ; ;***** ;- .CIINI:: ; GLOBAL ENTRY POINT CALL .CILOC ; FIND ALL CLI'S MOV #IE.UNS,@#$DSW ; ASSUME FAILURE CMP $CINUM,#N$$CLI ; ALREADY HAVE PREDEFINED LIMIT ?? BGE 54$ ; BRANCH IF YES, FLAGGED AS "INSUFFICIENT ; POOL FOR SEND" MOV #C.LIFX+2,R4 ; PICKUP SIZE OF FIXED PART OF CCB + 2 ; BYTES FOR NULLS IN PROMPT STRINGS ADD $CICPR,R4 ; ADD IN LENGTH OF CTRL-C PROMPT ADD $CIDPR,R4 ; ADD IN LENGTH OF DEFAULT PROMPT INC R4 ; MAKE SURE CCB LENGTH IS BIC #1,R4 ; WORD ALIGNED MOV #$CITSK,R3 ; POINT TO NAME OF TASK TO INIT CALL $SWSTK,50$ ; SWITCH TO SYSTEM STATE CALL $SRSTD ;; SEARCH FOR TASK BCS 40$ ;; BRANCH IF NOT INSTALLED BIT #TS.EXE,T.STAT(R0) ;; TASK ACTIVE ?? BEQ 42$ ;; BRANCH IF YES BIT #T3.CLI,T.ST3(R0) ;; TASK ALREADY A CLI ?? BNE 44$ ;; BRANCH IF YES BIT #T3.NSD,T.ST3(R0) ;; TASK ALLOW SEND-DATA ?? BEQ 44$ ;; BRANCH IF YES MOV R0,$CITCB ;; TASK MADE ALL CHECKS, SAVE TCB ADDR MOV R0,R5 ;; COPY TCB ADDRESS MOV R4,R1 ;; RECOVER REQUIRED CCB SIZE CALL $ALOCB ;; TRY TO ALLOCATE IT BCS 46$ ;; BRANCH IF INSUFFICIENT POOL MOV R0,$CICCB ;; SAVE ADDRESS FOR TASK CLR (R0)+ ;; CLEAR LINK WORD CLR (R0)+ ;; CLEAR TT UCB ADDR MOV R1,(R0)+ ;; SAVE SIZE OF CCB PACKET MOV $CIFL2,(R0)+ ;; SAVE CLI STATUS/FLAGS WORD MOV $CINAM,(R0)+ ;; SAVE CLI'S NAME MOV $CINAM+2,(R0)+ CLR (R0)+ ;; SHOW NO ATTACHED TERMINALS MOV R5,(R0)+ ;; SAVE TCB ADDRESS MOV #$CICPR+2,R1 ;; GET POINTER TO CTRL-C PROMPT 30$: MOVB (R1)+,(R0)+ ;; COPY STRING BNE 30$ MOV #$CIDPR+2,R1 ;; GET POINTER TO DEFAULT PROMPT 33$: MOVB (R1)+,(R0)+ ;; COPY STRING BNE 33$ ADD #T.RCVL,R5 ;; OFFSET POINTER TO RECEIVE QUEUE MOV $CICCB,R0 ;; RECOVER PACKET START ADDRESS MOV R0,(R5)+ ;; LINK CCB INTO START OF QUEUE MOV R0,(R5) BIS #T3.CLI,T.ST3-(R5) ;; SET TASK'S CLI BIT MOV #IS.SUC,R0 ;; FLAG SUCCESS BR 48$ ;; AND EXIT 40$: ;; ERROR TRAP ENTRY POINTS MOV #IE.INS,R0 ;; SET "TASK NOT INSTALLED" CODE BR 48$ 42$: MOV #IE.ACT,R0 ;; SET "TASK ACTIVE" CODE BR 48$ 44$: MOV #IE.ITS,R0 ;; SET "INCONSISTANT TASK STATE" BR 48$ 46$: MOV #IE.UPN,R0 ;; SET "INSUFFICIENT POOL" 48$: MOV R0,@#$DSW ;; PUT ERROR STATUS INTO DSW RETURN ;; AND RETURN TO TASK STATE 50$: TST @#$DSW ; CHECK STATUS BPL 55$ ; BRANCH ON SUCCESS 54$: SEC ; FLAG PROBLEMS IN CARRY BIT 55$: RETURN ; RETURN TO CALLER .PAGE ; ;+ ;***** ; ; .CISET - Sets a specified terminal device/unit @$CIDEV/$CIUNT ; to a CLI task named @$CINAM. The CLI task must have been ; successfully initialized prior to being activated for a terminal. ; ; Returns: ; Carry bit set on failure, clear on success ; ;***** ;- .CISET:: ; GLOBAL ENTRY POINT CALL .CIUCB ; FIND NECESSARY INFO ON TERMINAL BCS 65$ ; BRANCH ON PROBLEMS CALL .CILOC ; FIND ALL CLI'S 5$: MOV (R5)+,R0 ; GET ADDRESS OF CLI'S NAME BEQ 50$ ; BRANCH ON END-OF-LIST CMP $CINAM,(R0)+ ; DESIRED CLI ?? BNE 9$ ; BRANCH IF NO CMP $CINAM+2,(R0) ; MAYBE, 2ND 1/2 OF NAME MATCH ?? BEQ 10$ ; BRANCH IF YES 9$: TST (R5)+ ; SKIP OVER POINTER TO TCB BR 5$ ; AND LOOK AGAIN 10$: MOV (R5),R5 ; PICKUP CCB ADDRESS CMP #$POOL,R5 ; BUFFERED IN POOL ?? BHI 20$ ; BRANCH IF NO, DEC'S CLI BIT #U2.LOG,$CIUC2 ; TERMINAL LOGGED IN ?? BEQ 20$ ; BRANCH IF YES (BIT CLEAR) BIT #CL.ILO,C.LIST-C.LITA(R5) ; CLI ALLOWED INPUT ; FROM UN-LOGGED IN TT'S BEQ 52$ ; BRANCH IF NO 20$: CALL $SWSTK,40$ ; GET TO SYSTEM STATE MOV $CIUCB,R4 ;; PICKUP TERMINAL'S UCB ADDRESS MOV U.CLI(R4),R0 ;; GET CURRENT CLI POINTER CMP #$POOL,R0 ;; POINTS INTO POOL ?? BHI 30$ ;; BRANCH IF NO, DEC'S CLI DEC C.LINT-C.LITA(R0) ;; ELSE, DECREMENT # ATTACHED TT'S 30$: MOV R5,U.CLI(R4) ;; SET TT'S UCB TO POINT TO NEW CLI CMP #$POOL,R5 ;; POINTS INTO POOL ?? BHI 35$ ;; BRANCH IF NO, DEC'S CLI INC C.LINT-C.LITA(R5) ;; SHOW 1 MORE ATTACHED TT 35$: MOV R5,$CICLI ;; RESET LOCAL CLI DEF'N ;; UNCOMMENT FOLLOWING LINES TO FORCE NEW CLI TO PROMPT TTN: ; MOV #4.,R1 ;; SET SIZE OF PROMPT PACKET ; CALL $ALOCB ;; ALLOCATE IT ; BCS 39$ ;; BRANCH IF FAILED, NO BIG DEAL (YET) ; MOV R0,R1 ;; COPY PACKET ADDRESS ; INC R4 ;; SET BIT 0 IN UCB ADDRESS ; MOV R4,2(R1) ;; AND SAVE IT IN PACKET ; MOV R5,R0 ;; COPY POINTER TO CLI TCB POINTER ; CALL $QCLIL ;; QUEUE COMMAND TO CLI 39$: RETURN ;; BACK TO TASK STATE 40$: MOV #IS.SUC,@#$DSW ; SETUP SUCCESS RETURN CLC ; FLAG IT IN CARRY TOO BR 65$ ; CONTINUE EXIT 50$: MOV #IE.INS,@#$DSW ; SET "TASK NOT INSTALLED" BR 64$ 52$: MOV #IE.ITP,@#$DSW ; FOR LACK OF ANYTHING BETTER, INVALID ; TI: => TERMINAL NOT LOGGED IN ; 64$: SEC ; SHOW PROBLEMS IN CARRY BIT 65$: RETURN ; RETURN TO CALLER .page ; ;+ ;***** ; ; .CIELM - Eliminates CLI task from system. CLI to eliminate ; must be a non-DEC alternate CLI, have no attached terminals, ; and be identified by name @$CINAM. If $CINAM is 0, all non-DEC ; CLI's will be eliminated. Eliminating a CLI does NOT remove ; it from the STD list. When performing a wild card eliminate, ; failure to eliminate ANY CLI will be flagged, but the operation ; will proceed through all CLIs. To determine which CLIs could not ; be eliminated, recall ".CILOC" and check for any non-DEC CLI ; pointers. ; ; Returns: ; Carry bit clear on success, set on failure ; ;***** ;- ; .CIELM:: ; GLOBAL ENTRY POINT MOV #IS.SUC,@#$DSW ; USE DSW FOR ERROR STATUS CALL .CILOC ; FIRST, FIND ALL CLI'S CALL $SWSTK,50$ ; SWITCH TO SYSTEM STATE 2$: MOV (R5)+,R0 ;; PICKUP POINTER TO CLI'S NAME BEQ 49$ ;; BRANCH ON END-OF-LIST MOV (R5)+,R4 ;; GET ADDRESS OF CLI CONTROL BLOCK CMP #$POOL,R4 ;; BUFFERED IN SYSTEM POOL ?? BHI 2$ ;; BRANCH IF NO, DEC'S CLI MOV $CINAM,R1 ;; PICKUP NAME OF CLI TO ELIMINATE BEQ 10$ ;; BRANCH IF 0, DO ALL MOV #IE.INS,@#$DSW ;; ANTICIPATE PROBLEM CMP (R0)+,R1 ;; 1ST 1/2 OF TASK NAME MATCH ?? BNE 2$ ;; BRANCH IF NO CMP (R0),$CINAM+2 ;; 2ND HALF MATCH ?? BNE 2$ ;; BRANCH IF NO MOV #IS.SUC,@#$DSW ;; SHOW SUCCESS ON MATCH...FOR NOW 10$: TST C.LINT-C.LITA(R4) ;; ANY TERMINALS USING CLI ?? BNE 46$ ;; BRANCH IF YES, CAN'T ELIMINATE IT MOV (R4),R4 ;; PICKUP CLI'S TCB ADDRESS BIC #T3.CLI,T.ST3(R4) ;; SHOW ITS NOT A CLI ANYMORE TST T.STAT(R4) ;; TASK ACTIVE ?? BEQ 15$ ;; BRANCH IF NO MOV #S.CEXT,R0 ;; SETUP ABORT CODE MOV R4,R1 ;; COPY TCB ADDRESS CALL $ABTSK ;; ABORT THE TASK 15$: ;; CLI'S HAVE T3.NSD SET, MANUALLY DEALLOCATE RCV QUEUE ADD #T.RCVL,R4 ;; POINT TO RECEIVE QUEUE LIST HEAD MOV (R4),R0 ;; PICKUP 1ST PACKET ADDRESS => CCB CLR (R4) ;; CLEAR LIST-HEAD MOV R4,2(R4) ;; CLOSE LIST MOV C.LISZ(R0),R1 ;; PICKUP SIZE OF CLI CONTROL BLOCK 20$: MOV (R0),R4 ;; PICKUP LINK TO NEXT PACKET CALL $DEACB ;; DEALLOCATE CURRENT PACKET MOV R4,R0 ;; COPY NEXT PACKET ADDRESS BEQ 47$ ;; BRANCH WHEN DONE ASR C.LIUA(R0) ;; UCB ADDRESS ODD ?? BCC 28$ ;; BRANCH IF NO MOV #4.,R1 ;; ELSE, HAVE SPECIAL COMMAND PACKET BR 20$ ;; LOOP TO DEALLOCATE IT 28$: MOV #M$$CRB,R1 ;; SET SIZE TO STANDARD MCR BUFFER BR 20$ ;; LOOP TO DEALLOCATE IT 30$: ;; REF LABEL ; ; *** ; 46$: ;; ERROR ENTRY POINTS MOV #IE.RSU,@#$DSW ;; CLI HAS ATTACHED TT'S, SAY ITS ;; "RESOURCE IN USE" 47$: TST $CINAM ;; ELIMINATING ALL CLI'S ?? BEQ 2$ ;; BRANCH IF YES 49$: RETURN ;; BACK TO TASK STATE 50$: TST @#$DSW ; CHECK STATUS BPL 55$ ; BRANCH ON SUCCESS SEC ; ELSE, SHOW IT IN CARRY BIT 55$: RETURN ; BACK TO CALLER .END