.TITLE DCL .IDENT /V1.0/ .ENABL LC .NLIST BEX .if df $DCL ; Only if we really want it ;+ ; P. Sorenson 17-JUN-82 MAKE DCL ITS OWN MODULE; ADD .PSECT ; PRS03 DEFINITIONS FOR PURE/IMPURE CODE. ; ; 27-FEB-83 FIXUP PROBLEMS WITH .$$$$. PSECT DEFN'S ; PRS07 CHANGE DCL SO ONLY DISALLOW HEY AND DLY ; WHEN ACTING AS A CLI. ; ; DCL ; This subroutine implements the following commands as though they were ; part of MCR: ; ; The majority of these commands will never be assembled as they are better ; handled by the internal table. However, these commands and the code ; are left here, conditionalized so they can not assemble (without great ; effort) for tutorial purposes for those who might wish to implement a ; command dispatcher. (try it, its fun!). ; ; BEL[L] Ring terminal bell. ; PAG[E] Erase screen on VT100/TEK 4014 ; ERA[SE] Erase screen of VT52 ; HOL[D] SET /HOLD =TI: ; NOH[OLD] SET /NOHOLD =TI: ; SCR[OLL] Set VT100 to slow scroll. ; NOS[CROLL] Set VT100 to normal mode. ; LIS[T] FILESPEC,FILESPEC,.... List files at user's TI: ; TYP[E] FILESPEC,FILESPEC,.... Type files at user's TI: ; DEL[ETE] FILESPEC,FILESPEC,... Delete the specified files ; DIR[ECTORY] FILESPEC,FILESPEC,... Display a directory listing ; PUR[GE] FILESPEC, FILESPEC,.... Purge a directory of files ; SPO[OL] FILESPEC,FILESPEC,... Send files to line printer ; TRU[NCATE] FILESPEC,FILESPEC,.... Truncate list of files ; FRE[E] DDn: Display free blocks on DDn: ; SOR[T] filespec/switches SRD [filespec/switches]/LI ; CREATE FILENAME PIP filename=TI: ; POOL SET /POOL ; UIC ={ grp, mem} Set or display UIC ; CHD Set or display UIC ; ATS or ATS TI: List all active tasks or only ; those on TI: ; SHQ Show full spool queue ; SHW Show spool queue waiting list ; DLG Display logged in terminals ; SYS Show current System UIC ; DLY NNNU Delay 'NNN' U units of time ; HEY taskname Connect to task and notify ; it when exits ; ; ; The syntax of most of the commands is: ; ; COMMAND [FILES] ; ; The directory command may be modified by using the switches ; "/BR", or "/FU" ; .SBTTL DCL - Process DCL-like PIP commands .MACRO MVZ,RA,RB,?A,?B ; Move ASCIZ string without trailing zero A: TSTB (RA) BEQ B MOVB (RA)+,(RB)+ BR A B: .ENDM EFN1 = 1 EF1 = 1 EF2 = 2 LUN2 = 2 ; LUN for TI: BELL = 7 ; Chimes LF = 12 ;PRS03 CR = 15 ;PRS03 ESC = 33 ;PRS03 SPA = 40 ;PRS03 ;PRS03 .MCALL STSE$S,QIOW$,SPWN$S,MRKT$S,DIR$,SPWN$ .MCALL CNCT$ .MCALL EXST$S ;PRS03 ; ; *** MAIN .$$$$. PSECT DEFINITIONS ARE NO GLOBALLY DEFINED IN CCL.MAC ;PRS07 ; ;PRS03 .PSECT $IDATA,RW,D,LCL,CON,REL ;PRS03 CNNECT: CNCT$ ,EF1,,EXTBLK QIOW: QIOW$ IO.WVB,LUN2,31,,,,<0,0,40> QIO: QIOW$ IO.WVB,LUN2,EF2,,ISB,, SPWN: SPWN$ MCR...,,,,,1 ;PRS03 EXSTAT: .BLKW 8. ;SPAWN EXIT STATUS BLOCK ;PRS03 CMDNAM: .WORD 0 ;PRS03 NOBYTE: .WORD 0 ;PRS03 NOPRE: .BYTE 0 ; 1 if "NO" prefixes command ;PRS03 ;PRS03 .PSECT $PDATA,RO,D,LCL,CON,REL ;PRS03 .ENABL LC ;PRS03 ; ; Error messages ; EM2: .ASCIZ /CCL -- Command line too long/ ;PRS03 BELMSG: .ASCIZ <7> ;PRS03 EMM2: .ASCII /CCL -- Task not in system/ EMM2L=.-EMM2 EMM3: .ASCII /CCL -- Syntax error/ EMM3L=.-EMM3 .IFDF $PIP EMM4: .ASCII /CCL -- Command parsing error after PIP:/ EMM4L=.-EMM4 .ENDC .EVEN ;PRS03 ;**-6 ; ; List of valid DCL commands. Those entries that can also take ; a prefix of "NO" are indicated by "-1" in the table and must ; immediately follow the un-prefixed entry for the same command. ; ; Normally commands conditionalized with $PIP or $DCLX will not get ; assembled but will be handled by the internal table. ; CMDTBL:; .if df $PIP ; Do we want this subset? .RAD50 /DIR/ ; LIst directory on TI: .RAD50 /PUR/ ; Purge directory .RAD50 /SPO/ ; Spool files via PIP /SP .RAD50 /FRE/ ; Display number of free blocks .RAD50 /DEL/ ; Delete file(s) .RAD50 /TYP/ ; Type file(s) on ti: .RAD50 /LIS/ ; .RAD50 /CRE/ ; Create a file .RAD50 /TRU/ ; Truncate file(s) .RAD50 /SOR/ ; Sort/brief listing .endc; $PIP ; .RAD50 /CHD/ ; Change default directory .RAD50 /UIC/ ; " " " .IFDF $DCLX ; .RAD50 /ATS/ ; List active tasks .RAD50 /SHQ/ ; Show print and batch queues in full format .RAD50 /SHW/ ; Show print and batch queues in short format .RAD50 /DLG/ ; Display terminals on TI: .RAD50 /POO/ ; Display the current amount of pool .RAD50 /SYS/ ; Display current system UIC .ENDC ;$DCLX .RAD50 /DLY/ ; Delay .RAD50 /HEY/ ; Notify terminal of specified task exit .IFDF $DCLX ; .RAD50 /BEL/ ; Ring terminal bell .RAD50 /PAG/ ; Erase terminal screen of VT100/TEK 4014 .RAD50 /ERA/ ; Erase terminal screen of VT52 .RAD50 /SCR/ ; Set VT100 to scroll mode .WORD -1 ; Set VT100 to noscroll mode .RAD50 /HOL/ ; SET /HOLD=TI: .WORD -1 ; SET /NOHOLD=TI: .ENDC ;$DCLX ; ENDCMD: ; End of command table ; ; Co-table to CMDTBL that contains the address the the servicing routine ; for the decoded command. ; JMPTBL: ; .if df $PIP ; .WORD PIP ; Directory listing .WORD PIP ; Use also for PURGE .WORD PIP ; Use also for SPOOL .WORD PIP ; Use also for FREE .WORD PIP ; Use also for DELETE entry .WORD PIP ; Use for TYPE .WORD PIP ; Use for LIST .WORD PIP ; Use PIP for CREATE .WORD PIP ; Use PIP for TRUNCATE .WORD SRD ; Use code template for SRD /LI .endc; $PIP ; .WORD CHD ; .WORD CHD ; .IFDF $DCLX ; .WORD ATS ; .WORD SHQ ; .WORD SHW ; .WORD DLG ; Show actice terminals .WORD POO ; Show pool .WORD SYS ; Display SYSUIC .ENDC .WORD DLY ; Delay for just a moment .WORD HEY ; Connect to task .IFDF $DCLX ; .WORD BELEP ; Ring terminal bell .WORD PAGE ; Erase VT100 screen .WORD ERASE ; Erase VT52 screen .WORD SCROLL ; Set VT100 to scroll mode .WORD NSCROLL ; Set VT100 to normal mode .WORD HOLD ; SET /HOLD =TI: .WORD NOHOLD ; SET /NOHOLD=TI: .ENDC ; $DCLX ; PRS03 -- INCLUDE COMMAND DEFINITIONS FORMERLY AT START OF CCL CODE ;PRS03 .EVEN ;PRS03 .if df $DCL ; Only if we want it ;ALI .if df $PIP ; Only if we really want ;ALI ; ; PIP commands for DIR,LIST, DELETE, SPOOL, PURGE, TRUNCATE, UNLOCK ; TYPMSG: .ASCIZ /PIP TI:=/ PIPHD: .ASCIZ /PIP / DELMSG: .ASCIZ \/DE/LD\ DIRMSG: .ASCIZ \/LI\ PURMSG: .ASCIZ \/PU\ SPOMSG: .ASCIZ \/SP\ TRUMSG: .ASCIZ \/TR\ CREMSG: .ASCIZ \=TI:\ FREMSG: .ASCIZ \/FR\ SORMSG: .ASCIZ \SRD \ .EVEN .endc; $PIP ;ALI .endc; $DCL ;ALI .EVEN ;PRS03 ;**-3 .PAGE .SBTTL Compress Command Line .PSECT $CODE1,RO,I,LCL,CON,REL ;PRS03 ; ; Get the command line from MCR and peel off the command from it. ; The command is defined as the first N characters of the line up to ; but not including the first non-alphanumeric ; DCL:: ; REF label, MAKE IT GLOBAL ;PRS03 MOV #CMD,SPWN+S.PWCA ; Set buffer address in normal SPWN DPB MOV #EXSTAT,SPWN+S.PWES ; and EXIT status block address MOV #MCR,R0 ; Start of MCR command buffer CLRB NOPRE ; Assume regular command CMPB (R0),#'N ; "NO"? BNE 5$ ; Branch if not CMPB 1(R0),#'O ; BNE 5$ ; Branch if not ADD #2,R0 ; Skip prefix INCB NOPRE ; Signal "NO" seen 5$: CLR R1 ; Control for $CAT5(Do not decode dots) CALL $CAT5 ; Convert R50 to ASCII ; (R1 contains command name) MOV #MCR,R0 ; Get start of command buffer again MOV R0,R2 ; for compression MOV R0,R5 ; Points to rest of command line MOV #CMDTBL,R4 ; Search the command table for a match MOV R1,CMDNAM ; Save command name for later 10$: CMP R1,(R4)+ ; See if it's a match BEQ 20$ ; Go it CMP R4,#ENDCMD ; Are we at end of table? BLO 10$ ; If LO , no, try again 15$: RETURN ; Go and try the .CCL file for a match 20$: TSTB NOPRE ; Prefixed command? BEQ 25$ ; Branch if not CMP (R4),#-1 ; Command takes "NO" prefix? BNE 15$ ; Branch if not, invalid DCL command TST (R4)+ ; Use prefixed command entry 25$: MOV R2,R0 ; Restore R0 ; ; Find where command ends ; The typical command will look as follows: ; ; ; ; The CMDNAME may be more than three characters long, but only the first ; three were tested against the jump table(this is consistent with MCR). ; A space separated the cmd name from any command qualifier string. ; PARSE: CMPB (R0),#SPA ; Is it a space? BEQ REPACK ; If EQ, Yes, go repack buffer CMPB (R0),#ESC ; Is it an ? BEQ REPACK ; If EQ, Yes CMPB (R0),#CR ; Is it a BEQ REPACK ; If EQ, Yes INC R0 ; Else increment counter BR PARSE ; And check next character .PAGE REPACK: MOVB (R0),(R2)+ ; Move in first byte CMPB (R0),#ESC ; Is it BEQ OUT ; If EQ, Yes CMPB (R0),#CR ; Is it BEQ OUT ; If EQ, Yes INC R0 ; Increment counter BR REPACK ; Pack next character OUT: CLRB (R2) ; Leave a null byte to signify end of buffer ; ; At this point the command line appears as follows. ; The command name has been removed from the command buffer. ; Note however, that the first character of the compressed buffer ; may be a space. The line ends with either a or ; depending on which key terminated the read. A zero byte follows this ; in order to simplify checking for EOL ; ; R4 points to the address of command routine +2 ; R5 points to the start of the command buffer ; MOV R4,R0 ; Restore R0 MOV #CMD,R1 ; Get SPAWN buffer TSTB 1(R5) ; Any files follow command? BNE 25$ ; If NE, Yes INC NOBYTE ; Show no data for later 25$: JMP @JMPTBL-CMDTBL-2(R0) ; You can tell this line was BENN'S .enable LSB ERR2: MOV #EMM2,QIOW+Q.IOPL ; Address of error message MOV #EMM2L,QIOW+Q.IOPL+2 ; Length of command BR 10$ ERR3: MOV #EMM3,QIOW+Q.IOPL MOV #EMM3L,QIOW+Q.IOPL+2 BR 10$ .IFDF $PIP ERR4: MOV #EMM4,QIOW+Q.IOPL MOV #EMM4L,Q.IOPL+2 BR 10$ .ENDC 10$: DIR$ #QIOW ; Print error message EXST$S #EX$SEV ; Then comes the bad news .DSABLE LSB .PAGE .if df $PIP ; Only if defined .SBTTL PIP-like commands ; ; DIR,SPOOL,DELETE,TRUNCATE,FREE,PURGE,CREATE, ..etc. all processed here ; SRD: MOV #SORMSG,R0 ; Move in SRD MOV #^RDIR,CMDNAM ; Pretend this is directory command BR COMON ; Branch through common code PIP: CMP CMDNAM,#^RTYP ; Is it TYPE command BEQ 10$ ; If EQ Yes CMP CMDNAM,#^RLIS ; Perhaps LIST? BNE 20$ ; If NE, No 10$: TST NOBYTE ; Any files to list? BNE XIT ; If NE, no files present MOV #TYPMSG,R0 ; Else point to start of command BR COMON ; And skip over 20$: MOV #PIPHD,R0 ; First part of SPAWN command COMON: ; MVZ R0,R1 ; Mov ASCIZ string to SPAWN buffer MVZ R5,R1 ; Mov rest of command up to zero DEC R1 ; Bump off terminating CMP CMDNAM,#^RPUR ; Is it purge? BNE 5$ ; If NE no TST NOBYTE ; Are any files present? BNE XIT ; If NE, no, syntax error MOV #PURMSG,R0 ; Move in second half of line BR DOIT ; 5$: CMP CMDNAM,#^RDIR ; Is it directory? BNE 10$ ; If NE, NO MOV #DIRMSG,R0 ; Mov in second half of name BR DOIT ; 10$: CMP CMDNAM,#^RSPO ; Is it spool? BNE 15$ ; If NE, no TST NOBYTE ; Are any files present? BNE XIT ; If NE, no , syntax error MOV #SPOMSG,R0 ; Move in /SP BR DOIT ; Go do it 15$: CMP CMDNAM,#^RFRE ; Is it /FR command? BNE 20$ ; If NE, no MOV #FREMSG,R0 ; Move in second half of name BR DOIT ; Go issue command 20$: CMP CMDNAM,#^RDEL ; Is it delete? BNE 25$ ; If NE,no TST NOBYTE ; Any files present? BNE XIT ; If NE, no, syntax error MOV #DELMSG,R0 ; Move in second half of command BR DOIT ; Go issue command 25$: CMP CMDNAM,#^RCRE ; Is it create? BNE 30$ ; If NE, no MOV #CREMSG,R0 ; Move in second half of command BR DOIT ; Go issue command 30$: CMP CMDNAM,#^RTRU ; Is it truncate? BNE 35$ ; If NE,no MOV #TRUMSG,R0 ; If YES, move in switch BR DOIT ; And go do it. 35$: CMP CMDNAM,#^RTYP ; Is it type? BEQ DOIT ; If EQ, Yes go do it CMP CMDNAM,#^RLIS ; Perhaps it is LIST? BEQ DOIT ; If YES, do it 40$: JMP ERR4 ; Warn user code fell through here DOIT: MVZ R0,R1 ; Move it in SUB #CMD,R1 ; Length of line to SPAWN CMP R1,#78. ; Is composit line too long? BGT LNGERR ; If GT, Yes MOV R1,SPWN+S.PWCL ; And the length of the command JMP SPWNIT ; SPAWN command and exit XIT: JMP ERR3 ; Say syntax error LNGERR: MOV #EM2,R0 ; It isn't, so say it's too long CALL TYPEIT ; Print message and exit with error ;PRS03 EXST$S #EX$SEV ;PRS03 .endc; $PIP ; No PIP or SRD commands implemented .PAGE .SBTTL CHD ; ; CHD - Change (or show) current UIC ; CHDM1: .ASCIZ \SET /UIC=[\ CHDM2: .ASCIZ \SET /UIC\ .EVEN CHD: ; Ref label TSTB 1(R5) ; Is there a UIC specified? BEQ CHDSHW ; No - show current UIC MOV #CHDM1,R0 ; Get first part of command MVZ R0,R1 ; Move first part of string to spawn buffer MOV R5,R0 ; INC R0 ; 10$: TSTB (R0) ; Is it end of line BEQ 20$ ; If EQ 0, YES, close up command CMPB (R0),#'[ ; Is it "["? BNE 11$ ; If NE, NO, skip MOVB #SPA,(R0)+ ; Yes, make it a space BR 10$ ; And try again 11$: CMPB (R0),#'= ; Is it an "="? BNE 12$ ; If NE, NO MOVB #SPA,(R0)+ ; Yes, make it a space BR 10$ ; And check again 12$: CMPB #'],(R0) ; Is it a "]"? BNE 13$ ; If NE, NO MOVB #CR,(R0)+ ; Yes, so terminate command with CLRB (R0) ; and 0 byte BR 10$ ; And loop again to catch 0 byte 13$: ; If not [, ], = , either number or CMPB (R0)+,#SPA ; If a space seperates the GRM MEM BNE 10$ ; If NE, must be number-get another MOVB #',,-1(R0) ; Else move in a COMMA 20$: MVZ R5,R1 ; Move in UIC DEC R1 ; Bump MOVB #'],(R1)+ ; Close up command SUB #CMD,R1 ; Length of spawn command MOV R1,SPWN+S.PWCL ; Set length in spawn DPB JMP SPWNIT ; Spawn command and exit CHDSHW: ; Ref label MOV #CHDM2,SPWN+S.PWCA ; Set buffer address MOV #8.,SPWN+S.PWCL ; Set buffer length JMP SPWNIT ; Spawn command and exit .IFDF $DCLX .PAGE .SBTTL ATS ; ; ATS - LIST ALL ACTIVE TASKS ( OR ONLY THOSE FOR A TERMINAL) ; ATSM1: .ASCII \ACT /ALL\ ATSM2: .ASCIZ \ACT /TERM=\ .EVEN ATS: TSTB 1(R5) ; US THERE A TERMINAL SPECIFIED BNE ATSTTY ; YES, JUMP MOV #8.,SPWN+S.PWCL ; SET COMMAND LENGTH MOV #ATSM1,SPWN+S.PWCA ; SET BUFFER ADDRESS BR SPWNIT ; SPAWN COMMAND AND EXIT ATSTTY: MOV #ATSM2,R0 ; FIRST PART OF SPAWN COMMAND MVZ R0,R1 ; MOVE ASCIZ STRING INTO SPAWN BUFFER INC R5 ; MVZ R5,R1 ; MOVE IN TERMINAL NUMBER DEC R1 ; BUMP SUB #CMD,R1 ; LENGTH OF LINE TO SPAWN MOV R1,SPWN+S.PWCL ; SET COMMAND LENGTH BR SPWNIT ; SPAWN THE COMMAND .ENDC ; $DCLX .IFDF $DCLX .SBTTL Terminal setting routines .ENABL LC ERAMSG: .ASCII /H/ ; Cursor to (1,1) VT52 .ASCII /J/ ; Erase to end of screen VT52 .BYTE 0 ; Sentinal PAGMSG: .ASCII /[1;1H/ ; Go to (1,1) VT100 .ASCII /[2J/ ; Erase screen VT100 .ASCII <14> ; Erase 4014 screen ; .ASCII /{WOR 0/ ; Erase 4025 .BYTE 0 ; Sentinal .ENDC ;$DCLX ; .IFDF $DCLX ; SCRMSG: .ASCIZ /[?4h/ ; Set terminal to scroll mode NSCMSG: .ASCIZ /[?4l/ ; Set terminal to fast jump mode HOLMSG: .ASCII \SET /HOLD=TI:\ NOHMSG: .ASCII \SET /NOHOLD=TI:\ .EVEN ERASE: MOV #ERAMSG,R0 ; Erase VT52 BR TOTERM ; Branch PAGE: MOV #PAGMSG,R0 ; Get escape string BR TOTERM ; Go write out escape seq SCROLL: MOV #SCRMSG,R0 ; Set up output message BR TOTERM ; Send it out NSCROLL:MOV #NSCMSG,R0 ; Set up output message BR TOTERM ; Send it to terminal BELEP: MOV #BELMSG,R0 ; Write out message TOTERM: CALL TYPEIT ; EXST$S #EX$SUC ; What could possibly go wrong? HOLD: MOV #13.,SPWN+S.PWCL ; Set length MOV #HOLMSG,SPWN+S.PWCA ; And buffer address BR SPWNIT ; Spawn command and wait NOHOLD: MOV #15.,SPWN+S.PWCL ; Set length of command MOV #NOHMSG,SPWN+S.PWCA ; And buffer length BR SPWNIT ; SPawn command and wait .ENDC ;$DCLX ; SPWNIT: DIR$ #SPWN ; Try spawning to MCR... first BCC 10$ ; If CC we got it MOV #BADSPN,R0 ; Print error message CALL TYPEIT ; Out on TI: EXST$S #EX$SEV ; Very bad error 10$: JMP END ; End up .IFDF $DCLX .PAGE .SBTTL SHQ - SHW - DLG ; ; SHQ - Show full queue entries ; SHQM: .ASCII \QUE /FU:ALL\ .EVEN SHQ: MOV #11.,SPWN+S.PWCL ; Set length MOV #SHQM,SPWN+S.PWCA ; And buffer address BR SPWNIT ; Spawn command ; ; SHW - Show QUE waiting list ; SHWM: .ASCII \QUE /BR:ALL\ .EVEN SHW: MOV #11.,SPWN+S.PWCL; Set length MOV #SHWM,SPWN+S.PWCA ; And address BR SPWNIT ; Spawn command and exit ; ; DLG - Display logged in terminals ; DLGM: .ASCII \DEV /LOG\ .EVEN DLG: MOV #8.,SPWN+S.PWCL ; Set length MOV #DLGM,SPWN+S.PWCA ; And address BR SPWNIT ; Spawn the command and exit .PAGE ; ; POO - Show pool amount ; POOM: .ASCII \SET /POOL\ .EVEN POO: MOV #9.,SPWN+S.PWCL ; Set length MOV #POOM,SPWN+S.PWCA ; And buffer address BR SPWNIT ; Spawn the command and exit ; ; SYS - Show current system UIC ; SYSM: .ASCII \SET /SYSUIC\ .EVEN SYS: MOV #11.,SPWN+S.PWCL ; Set length MOV #SYSM,SPWN+S.PWCA; And buffer address BR SPWNIT ; Spawn command and exit .ENDC ;$DCLX .PAGE .SBTTL DLY ; ; DLY NNNU -- Delay 'NNNN' units of time ; DLY: TSTB CLIFLG ; Are we a CLI ;JGD09 BEQ 1$ ; If EQ, no, continue ;JGD09 RETURN ; If a CLI, HEY or DLY would hang CLI ;JGD09 ; So return and let catchall get them ;JGD09 1$: ;JGD09 MOV R5,R0 ; Copy buffer pointer CALL $CDTB ; Convert units value MOV R1,R5 ; Save units value BEQ 30$ ; Exit if null MOV #1,R4 ; Assume tics CMPB R2,#'T ; Tics? BEQ 20$ ; Yes INC R4 ; Try next time value CMPB R2,#'S ; Seconds? BEQ 20$ ; If EQ YES INC R4 ; No , assume minutes CMPB R2,#'M ; Minutes? BEQ 20$ ; If EQ, YES INC R4 ; If NE, NO assume hours CMPB R2,#'H ; Hours? BNE 30$ ; If NE, illegal value 20$: MRKT$S #EFN1,R5,R4 ; Issue marktime BCS 30$ ; If directive ERROR JMP END ; Go wait 30$: ; Ref label JMP ERR3 ; Syntax error .PAGE .SBTTL HEY ; ; HEY ; BUFFER: .BLKW 40. EXTBLK: .WORD -1 ; EXIT STATUS BLOCK .BLKW 7 ; ;JGD08 ISB: .WORD 0,0 ; I/O Status block CODES: .WORD E2 .WORD E3 .WORD E4 .WORD FUNNY ; Because exit status is 0,1,2,or 4 .WORD E5 ERRS: .WORD FUNNY ; 0 - Internal consistency error .WORD CMLINE ; 2 - Command line I/O error .WORD SYNTAX ; 4 - Syntax error .WORD TSKCLI ; 6 - Task a CLI .WORD NSTASK ; 8 - No such active task BADSPN: .ASCII /CCL -- Bad SPAWN to ...MCR,/ .ASCIZ / Save printout and get help / MESS1: .ASCIZ /HEY -- Task / MESS2: .ASCIZ / exited with status - / ERMES: .ASCIZ /HEY -- / E2: .ASCIZ /warning/ E3: .ASCIZ /success/ E4: .ASCIZ /error/ E5: .ASCIZ /severe error/ NSTASK: .ASCIZ /Task not active/ TSKCLI: .ASCIZ /Bad task/ SYNTAX: .ASCIZ /Invalid syntax/ CMLINE: .ASCIZ /Bad command line/ FUNNY: .ASCIZ /FUNNY -- Internal consistency error/ .EVEN HEY: TSTB CLIFLG ; Are we a CLI ;JGD09 BEQ 1$ ; If EQ, no, continue ;JGD09 RETURN ; If a CLI, HEY or DLY would hang CLI ;JGD09 ; So return and let catchall get them ;JGD09 1$: ;JGD09 MOV #CNNECT+C.NCTN,R3 ; Get address to put taskname MOV R5,R0 ; Copy buffer pointer CLR R5 ; Zero error indicator CMPB (R0),#SPA ; Space? BNE 20$ ; If NE, NO TSTB (R0)+ ; Yes, skip over it 20$: ; Ref label CALL $CAT5 ; Convert ASCII takname to RAD50 BCS 30$ ; If CS less than 3 characters in taskname MOV R1,(R3)+ ; 1st part of taskname in connect DPB CALL $CAT5 ; Convert more taskname into RAD50 BCS 40$ ; If CS terminating character in R2 30$: ; MOVB (R0),R2 ; Get terminating character 40$: ; MOV R1,(R3) ; Taskname in connect DPB CMPB R2,#ESC ; Escape? BEQ 50$ ; If EQ YES, OK CMPB R2,#CR ; Carriage return? BNE ERROR2 ; If NE invalid terminator .PAGE .SBTTL Connect and Wait DIR$ #CNNECT ; Connect to the specified task CMP $DSW,#IS.SUC ; Successful connection? BEQ 50$ ; If EQ, YES CMP $DSW,#IE.INS ; Was specified task A CLI? BEQ ERROR3 ; If EQ YES CMP $DSW,#IE.ACT ; Was task inactive? BEQ ERROR4 ; If EQ, YES BR ERROR0 ; No funny error 50$: ; STSE$S #EF1 ; Wait for connected task to EXIT MOV #BUFFER,R0 ; Get output buffer address MOVB #BELL,(R0)+ ; Put in a BELL MOV #MESS1,R1 ; Get address of 1st part of MESSAGE CALL MOVE ; Put it in output buffer MOV CNNECT+C.NCTN,R1 ; Get 1st part of taskname CALL $C5TA ; Convert taskname to RAD50 MOV CNNECT+C.NCTN+2,R1 ; Get 2nd part of taskname CALL $C5TA ; Convert second part of taskname MOV #MESS2,R1 ; Get address of 2nd part of message CALL MOVE ; Move it into output buffer MOV EXTBLK,R1 ; Get exit status CMP #5,R1 ; Known return code BHI 60$ ; If HI, YES CLR R2 ; Suppress leading zeroes CALL $CBOMG ; Convert to octal BR 70$ ; 60$: ; ASL R1 ; Get word index MOV CODES(R1),R1 ; Get address of exit code message CALL MOVE ; Move it into buffer 70$: SUB #BUFFER,R0 ; Get length of message MOV R0,QIO+Q.IOPL+2 ; Move length of buffer into QIO DIR$ #QIO ; Print message ENDHEY: EXST$S #EX$SUC ; Exit successfully .PAGE .SBTTL HEY error processing ERROR4: INC R5 ; Task not active ERROR3: INC R5 ; Task a CLI ERROR2: INC R5 ; Invalid syntax ERROR1: INC R5 ; No command line ERROR0: ; Funny internal error ASL R5 ; Get word index MOV #ERMES,R1 ; Get 1st part of error message ;ALI MOV #BUFFER,R0 ; Move to output buffer CALL MOVE ; Move into output buffer MOV ERRS(R5),R1 ; Get address of error message CALL MOVE ; Move message into output buffer SUB #BUFFER,R0 ; Get length of message MOV R0,QIO+Q.IOPL+2 ; Put it in DPB DIR$ #QIO ; Print the error message EXST$S #EX$SEV ; Exit the worst way .PAGE .SBTTL The End ; ; The End ; END: STSE$S #EF1 ; Stop for spawn TST EXSTAT ; If EQ 0, we have success BNE 5$ ; If NE, use what's sent MOV #EX$SUC,EXSTAT ; Show success 5$: EXST$S EXSTAT ; Exit successfully .PAGE .SBTTL Subroutines ;+ ; *** MOVE - Move an ASCIZ string ; ; INPUTS: ; R0 - ADDRESS OF OUTPUT BUFFER ; R1 - ADDRESS OF ASCIZ STRING ; ; OUTPUTS: ; R0 - UPDATED ;- MOVE: ; MOVB (R1)+,(R0)+ ; Move next character TSTB (R1) ; End? BNE MOVE ; If NE NO RETURN ; Return to caller .endc; .END ;DCL