CCL.MAC/-BF=[344,60]CCL.VGN;1 -,,/;**V6.AC/ -2,2 .ident /V6.AC/ ; UPDATE AUDIT CONTROL-9 APR 1981 10:55:30 ; EDIT # 0102 3 Apr 1981 10:33:54 DR0:[344,60]CCL.MAC;162 ; PREVIOUS EDIT 3 Apr 1981 8:40:22 DR0:[344,60]CCL.MAC;161 -53,53 PARLNG = 60. ; 60 bytes per %n% -91,94 ; ; 6 Feb 1981 RAY VAN TASSLE CHANGES TO PROPERLY HANDLE EXIT ; STATUS OF SPAWNED COMMANDS ; HAVE CCL EXIT AFTER SPAWNING THE LAST ; COMMAND, WITHOUT PROMPT. THE SPAWNED ; PGM WILL PROMPT. ; ; CCL IS TASK-BUILT AS PRIVILEGED SO THAT IT CAN: ; 1) TURN OFF THE BIT TO GET MCR PROMPT ON EXIT. ; 2) USE THE ROUTINE USED BY AT. TO FIGURE OUT ; EXACTLY WHICH TASK TO WAIT ON. .MCALL GET$S,OPEN$R,FDBDF$,FDRC$A,CLOSE$,EXIT$S,QIOW$S .MCALL TCBDF$ TCBDF$ ; TCB DEFINITION .MCALL FDOP$A,FSRSZ$,DIR$,EXST$S,GTSK$S,GLUN$ .MCALL QIOW$C,SPWN$S,STSE$S,CLEF$S -137,137 .PSECT -148 MSG7: .ASCIZ /CCL -- Invalid CCL command line/ MSG8: .ASCIZ /CCL -- Remainder of CCL command bypassed/ -153 EM5: .ASCIZ /CCL -- Missing parameter prompts in ?.CCL file/ -160,168 ESCMSG: .BYTE ESC ; AN ESCAPE .EVEN MCRNAM: .RAD50 "MCR..." $LNGFL: .WORD -1 ; Cleared on command not too long NOBYTE: .WORD 0 ; Non-zero if a DCL command without ; parameters after the command. CMDNAM: .WORD 0 ; To keep track of command name IOSTS: .BLKW 2 ; For prompting TYPFLG: .WORD 0 ; IF INVOKED BY "RUN ...CA.", PRINT ; THE LINES BEFORE SPAWNING THEM ; ; FLAGS TO SAY IF THE LAST COMMAND LINE WAS "INS" OR "RUN" FOR ; SYNC INSFLG: .BYTE 0 RUNFLG: .BYTE 0 INSNAM: .ASCII /INS/ .IFNDF R$$MPL ; FOR M IT IS "MCR" SYSNAM: .ASCII /MCR/ .IFF ; FOR M-PLUS, IT IS "RUN" SYSNAM: .ASCII /RUN/ .ENDC PR: .ASCII /CCL>/ -176,178 DELMSG: .ASCIZ \.;0/DE/LD/NM,\ ; A KLUDGY WAY TO GET /NM & /LD FOR ALL SPECS PURMSG: .ASCIZ \.;0/PU/LD/NM,\ DIRMSG: .ASCIZ \/LI\ -213,219 .PAGE .SBTTL CCL - Root section CCL: MOV $TKTCB,R1 ; MAKE ME NON-PRIV BIC #T3.PRV,T.ST3(R1) -233,233 ; PROMPT THE TERMINAL FOR THE COMMAND LINE INC TYPFLG ; TYPE THE COMMAND LINES QIOW$S #IO.RPR,#2,#1,,#IOSTS,,<#MCR,#80.,,#PR,#4,#'$> MOV IOSTS+2,R0 ; TERMINATE INPUT WITH C/R MOVB #CR,MCR(R0) MOV IOSTS+2,MCRL BGT CCL1 -338,338 ADD #PARLNG,R0 ; Each field is 60 bytes long -419,419 2$: GET$S #FDB ; Get a line from the .CCL file -424,427 BNE 4$ ; No, file format is bad CALL PRMPT ; It's a question mark, get an answer BR 1$ ; Check for too many parameters ; 4$: MOV #EM5,R0 JMP ERROR -435,435 CLR NOSTOP ; Reset this in case needed next time MOV #EXSTAT,EXBLKP ; Set addr for SPAWNed pgm status MOV #1,SPEFN ; SET EVENT FLAG 1 FOR THE SPAWN GET$S #FDB ; Get next line from the .CCL file MOV FDB+F.NRBD,R0 ; NULL AFTER LAST BYTE CLRB INBF(R0) -439 MOVB #CR,INBF(R0) ; terminate it with a to make it happy -445,445 BEQ 30$ ; YES CMPB INBF,#'? ; TAKE QUESTION MARK AS COMMENT BEQ .NCMD MOV #MSG7,R0 ; TYPE INVALID CCL COMMAND MSG CALL TYPERR MOV #INBF,R0 CLRB INBF+79. JMP ERROR -451,452 40$: CLRB (R1)+ ; Do one CLRB (R2)+ ; Do the other -457,457 BNE 41$ JMP ENDNX ; NOTHING TO DO ON THIS LINE 41$: MOV #INBF+1,R1 ; Get them from here -469 TSTB MCR-1(R0) ; QUIT IF IT IS A NULL BEQ 3$ -488,492 3$: TSTB CMD+111 ; Should be NULL, else command too long BEQ 31$ JMP TOLONG ; Branch if too long ; THIS IS THE LAST LINE (WHICH IS NOT NULL). HAVE IT GIVE THE ; MCR PROMPT WHEN IT QUITS, INSTEAD OF CCL, WHICH WILL EXIT ; NOW. IF YOU REALLY WANT CCL TO STICK AROUND, MAKE THE LAST ; LINE AN EMPTY COMMAND (* ONLY) 31$: CMPB SAVTYP,#'* ; LAST LINE? BNE 4$ ; NO TST RING ; IF HE WANTS ME TO RING THE BELL WHEN DONE BNE 4$ ; DON'T GO AWAY NOW MOV J,R1 ; PUT AFTER IT, TO MAKE IT PROMPT MOVB #15,CMD-1(R1) INC NOSTOP ; SEE IF THE LAST LINE WAS INS OR RUN CMP #"IN,CMD BNE 91$ CMPB #'S,CMD+2 BNE 92$ INCB INSFLG BR 92$ 91$: CMP #"RU,CMD BNE 92$ CMPB #'N,CMD+2 BNE 92$ INCB RUNFLG 92$: MOV $TKTCB,R0 ; FORCE NO PROMPT UPON EXIT BIT #T3.MCR,T.ST3(R0) ; WILL CCL PROMPT ON EXIT? BNE 5$ ; YES MOVB #ESC,CMD-1(R1) ; NO--HAVE THIS NOT PROMPT EITHER 5$: BIC #T3.MCR,T.ST3(R0) 4$: MOV #PMCR,R5 ; Get parameter list TST TYPFLG ; PRINT THE COMMAND LINE??? BEQ 6$ QIOW$S #IO.WVB,#2,#1,,,,<#CMD,J,#040> 6$: CALL PUTMCR ; Spawn to MCR -497,507 ENDDUP: TST NOSTOP BNE ENDNX ; There is no status to look at CMP #EX$SUC,EXSTAT ; Is it success ;JGD03 BEQ ENDNX JMP EREXST ; If NE, Error - Bad status ;JGD03 ENDNX: CMPB SAVTYP,#'* ; Is this the final command? ;JGD03 BEQ FINISH ; Finish up and exit ;JGD03 JMP .NCMD ; More commands coming ;JGD03 FINISH: CALL CLOS ; Close file -512,526 ; if CCL was spawned (e.g., from AT.), pass the OCB along to the ; task that CCL just spawned (assuming that it has not yet exited). ; This will let CCl get out of the way, just like "RUN" does. THEEND: mov $tktcb,r0 TST T.OCBH(R0) BEQ 200$ ; CCL has no parent, skip over all this junk ; SPAWN A NULL COMMAND TO MCR, TO MAKE SURE IT IS DONE WITH THE ; ONE WE JUST GAVE IT. THIS PREVENTS A POSSIBLE RACE CONDITION ; where MCR has not yet started the task & passed ownership to it SPWN$S #MCRNAM,,,,,#17.,,,#ESCMSG,#1 STSE$S #17. ; FOR SYNCHRONIZATION WITH LAST COMMAND, MUST DO FUNNY THINGS ; A) IF IT WAS RUN OF NON-INSTALLED TASK, FLOW IS: ; MCR... --> ...MCR(RUN) --> MCR... --> ...INS --> TASK ; OTB IS PASSED ALONG TO THE FINAL TASK ; ; B) IF IT WAS INS/RUN=REM OF NON-INSTALLED TASK, FLOW IS: ; MCR... --> ...INS --> TASK ; OTB IS PASSED ALONG TO THE FINAL TASK ; TSTB INSFLG BNE 8$ ; IT WAS INS TSTB RUNFLG BEQ 9$ ; NEITHER MOV #SYSNAM,R5 ; RUN--WAIT FOR ...SYS CALL TSKWAIT SPWN$S #MCRNAM,,,,,#17.,,,#ESCMSG,#1 ; WAIT FOR MCR... STSE$S #17. 8$: MOV #INSNAM,R5 ; WAIT FOR ...INS CALL TSKWAIT ; There is no way to tell what task is the offspring without looking ; at all tasks OCB's, to find which task has an OCB pointing to ; us as the parent. ; Because I am lazy, I only look at the first OCB on each task. This should ; be okay, because the OCB's are FIFO. 9$: MOV $TKTCB,R0 ; GET MY TCB BACK CALL $SWSTK,200$ MOV $TSKHD,R4 10$: TST T.TCBL(R4) ;; QUIT IF THIS IS THE NULL-TASK TCB BEQ 199$ MOV T.OCBH(R4),R2 ;; POINT TO 1ST OCB OF THE TASK BEQ 15$ ;; BR IF NONE CMP O.PTCB(R2),R0 ;; IS THIS TASK MY CHILD?? BEQ 20$ ;; YES--MY SON, MY SON!!! 15$: MOV T.TCBL(R4),R4 ;; NO--KEEP LOOKING BR 10$ ; R0 IS TCB OF CCL ; R4 IS TCB OF CCL'S CHILD 20$: ADD #T.OCBH,R0 ;; GET OUR OCB CALL $QRMVF BCS 199$ ;; NONE MOV R4,R0 ;; PASS IT TO THE CHILD ADD #T.OCBH,R0 CALL $QINSF 199$: RETURN ;; BACK TO USER STATE 200$: EXST$S EXSTAT ; Exit and show success EXIT$S ; If exit with status fails, try just exit TOLONG: MOV #MSG5,R0 ; Warning message CALL TYPERR ; Type on TI: CLRB CMD+116 ; Write out command causing trouble MOV #CMD,R0 ; Write out the truncated command ERROR: CALL TYPERR ; Tell the user the bad news ERRORE: CALL CLOS ; Close .CCL file EREXIT: EXST$S #EX$SEV ; Exit with severe error ;ALI EXIT$S ; If exit with status fails, just exit ;;;;; THE COMMAND FINISHED WITH NON-SUCCESS STATUS ;; SEE WHAT THE PROBLEM IS AND IF WE SHOULD CONTINUE OR NOT EREXST: MOV #BUFFER,R0 ; Get output buffer address MOV #MESS1-1,R1 ; Get address of 1st part of MESSAGE CALL MOVE ; Put it in output buffer MOVB #BELL,-1(R0) MOV #MESS2,R1 ; Get address of 2nd part of message CALL MOVE ; Move it into output buffer MOV EXSTAT,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 STSE$S #EF2 ; TYPE OUT THE OFFENDING COMMAND MOV #CMD,R0 CALL TYPERR CMP EXSTAT,#2 ; CONTINUE IF SUCCESS OR WARNING BGE 80$ JMP ENDNX ; ERROR OR SEVERE ERROR-STOP 80$: MOV #MSG8,R0 CALL TYPERR ; TELL HIM WE ARE GIVING UP EARLY EXST$S EXSTAT EXIT$S -572,572 -593,593 QIOW: QIOW$ IO.WVB,LUN2,EF2,,,,<0,0,40> -779,779 MOV #EMM4L,QIOW+Q.IOPL+2 -809,810 CMP CMDNAM,#^RPUR BNE 1$ MOV #PURMSG,R0 ; PURGE AND DELETE ACT FUNNY TO MAKE BR 2$ ; /NM/LD ACT PROPERLY (LEFT TO RIGHT) 1$: CMP CMDNAM,#^RDEL BNE 3$ MOV #DELMSG,R0 2$: MVZ R0,R1 3$: MVZ R5,R1 ; Mov rest of command up to zero DEC R1 ; BUMP OFF TRAILING -815,815 -835,835 -854,854 CMPB -1(R1),#CR ; put in a trailing so it will prompt BEQ 45$ MOVB #CR,(R1)+ 45$: SUB #MCRBUF,R1 ; Length of line to SPAWN -872,872 CHDM2: .ASCIZ \SET /UIC\ UICCL: .ASCIZ \]\ -903,910 DEC R1 ; STRIP OFF TRAILING MOV #UICCL,R0 JMP DOIT CHDSHW: ; Ref label MOV #CHDM2,SPWN+S.PWCA ; Set buffer address MOV #9.,SPWN+S.PWCL ; Set buffer length -918,918 ATSM1: .ASCII \ACT /ALL\ -924,924 MOV #9.,SPWN+S.PWCL ; SET COMMAND LENGTH -932,932 -943,946 .BYTE 176,034 ; ERASE HAZELTINE 1500 .BYTE 0 ; Sentinal PAGMSG: .ASCII /[1;1H/ ; Go to (1,1) VT100 .ASCII /[2J/ ; Erase screen VT100 .BYTE 176,034 ; ERASE HAZELTINE 1500 ; .ASCII <14> ; Erase 4014 screen -952,953 HOLMSG: .ASCII \SET /HOLD=TI:\ NOHMSG: .ASCII \SET /NOHOLD=TI:\ -969,981 HOLD: MOV #14.,SPWN+S.PWCL ; Set length MOV #HOLMSG,SPWN+S.PWCA ; And buffer address BR SPWNIT ; Spawn command and wait NOHOLD: MOV #16.,SPWN+S.PWCL ; Set length of command MOV #NOHMSG,SPWN+S.PWCA ; And buffer length BR SPWNIT ; SPawn command and wait SPWNIT: MOV $TKTCB,R1 ; WILL CCL PROMPT ON EXIT? BIT #T3.MCR,T.ST3(R1) BNE 1$ ; YES MOV SPWN+S.PWCA,R1 ; NO-DON'T LET THIS PROMPT AFTER ALL ADD SPWN+S.PWCL,R1 CMPB #CR,-1(R1) BNE 1$ MOVB #ESC,-1(R1) 1$: TST TYPFLG ; PRINT THE COMMAND LINE??? BEQ 6$ MOV SPWN+S.PWCA,R0 MOV SPWN+S.PWCL,R1 DEC R1 QIOW$S #IO.WVB,#2,#1,,,, 6$: DIR$ #SPWN ; Try spawning to MCR... first BCC 10$ ; If CC we got it MOV #BADSPN,R0 ; Print error message CALL TYPERR ; Out on TI: EXST$S #EX$SEV ; Very bad error ; HAVE THE SPAWNED TASK PROMPT ON EXIT, INSTEAD OF CCL ; ADD LATER--PASS THE OTB FROM CCL'S PARENT TASK TO THE JUST-SPAWNED TASK. 10$: MOV $TKTCB,R1 ; HAVE CCL DO NOT PROMPT ON EXIT BIC #T3.MCR,T.ST3(R1) JMP THEEND -989,992 SHQM: .ASCII \QUE /FU:ALL\ .EVEN SHQ: MOV #12.,SPWN+S.PWCL ; Set length -1000,1003 SHWM: .ASCII \QUE /BR:ALL\ .EVEN SHW: MOV #12.,SPWN+S.PWCL; Set length -1011,1014 DLGM: .ASCII \DEV /LOG\ .EVEN DLG: MOV #9.,SPWN+S.PWCL ; Set length -1024,1027 POOM: .ASCII \SET /POOL\ .EVEN POO: MOV #10.,SPWN+S.PWCL ; Set length -1035,1038 SYSM: .ASCII \SET /SYSUIC\ .EVEN SYS: MOV #12.,SPWN+S.PWCL ; Set length -1094 .BYTE 15 -1102,1142 NSTASK: .ASCIZ /Task not active "/ TSKCLI: .ASCIZ /Bad task-a CLI "/ SYNTAX: .ASCIZ /Invalid syntax "/ CMLINE: .ASCIZ /Bad command line "/ FUNNY: .ASCIZ /FUNNY -- Internal consistency error "/ .EVEN ;;;; ; WAITCK -- PROCESS THE CCL COMMAND ; -TASKNAME WAITCK: MOV #INBF+1,R5 CALL TSKWAIT BCC RET1 JMP ERRORE RET1: RETURN HEY: CALL TSKWAIT BCC EXOK EXST$S #EX$SEV ; ERROR, EXIT WITH SEVERE CODE EXIT$S EXOK: MOV #BUFFER,R0 ; Get output buffer address -1165,1166 EXST$S #EX$SUC ; Exit successfully EXIT$S ; R5 POINTS TO TASK-NAME STRING. LEADING SPACES IGNORED TSKWAIT: ; WAIT FOR TASK TO EXIT, RETURN WITH CARRY SET/CLEAR MOV #CNNECT+C.NCTN,R3 ; Get address to put taskname CLR (R3) CLR 2(R3) MOV R5,R0 ; Copy buffer pointer CLR R5 ; Zero error indicator 10$: CMPB (R0),#SPA ; Space? BNE 20$ ; If NE, NO TSTB (R0)+ ; Yes, skip over it BR 10$ 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 43$ ; If EQ YES, OK CMPB R2,#CR ; Carriage return? BNE ERROR2 ; If NE invalid terminator ; USE THE MCR ROUTINE THAT FINDS A TASK NAME FOR THE ...XXX ; NAMES, SO THAT HEY WILL WORK JUST LIKE "ABO" DOES, AND ; WILL TRACK DOWN THE TASK NAME OKAY. 43$: MOV #CNNECT+C.NCTN,R3 ; POINT TO THE NAME CALL $GTTSK BCS ERROR4 ; CAN'T FIND IT ; MAKE SURE WE GOT THE RIGHT TASK IF ONLY 3 CHARS SPECIFIED TST 2(R3) BNE 45$ ; >3 CHARS GIVEN, TAKE WHAT WE GOT ; IF ONLY 3 CHARS GIVEN, AND THE TASK IT FOUND STARTS WITH "..." CMP T.NAM(R0),#^R... ; IT MUST BE FOR MY TERMINAL BNE 45$ MOV $TKTCB,R1 CMP T.UCB(R0),T.UCB(R1) BNE ERROR4 ; TASK IS ON ANOTHER TERMINAL 45$: MOV T.NAM(R0),(R3) ;; GET THE REAL NAME FROM THE TCB MOV T.NAM+2(R0),2(R3) TST (R3) BEQ ERROR4 ; NO TASK 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 CLC RETURN ; RETURN SUCCESS -1170 TST INSFLG ; FOR SYNC---NOT ACTIVE IS OKAY BNE RET -1181,1184 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 MOVB #'",(R0)+ SUB #BUFFER,R0 ; Get length of message MOV R0,QIO+Q.IOPL+2 ; Put it in DPB DIR$ #QIO ; Print the error message RET: SEC RETURN ; RETURN WITH ERROR STATUS -1191,1193 -1224 TYPERR: MOV #040,VFC ; MESSAGES GET STANDARD CONTROL -1231,1234 QIOW$S #IO.WLB!TF.WAL,#2,#1,,,, MOV (SP)+,R1 CLR VFC RETURN VFC: .WORD 0 -1257,1257 ; Type it and get result in correct 60 byte array chunk. -1278,1278 QIOW$S #IO.RPR,#2,#1,,#IOSTS,, -1284,1320 /