.TITLE MCRDIS - MULTI-USER MCR DISPATCHER OVERLAY .IDENT /01.03/ ; ; COPYRIGHT 1975, 1977, DIGITAL EQUIPMENT CORP., MAYNARD, MASS. ; ; THIS SOFTWARE IS FURNISHED TO PURCHASER UNDER A LICENSE FOR USE ; ON A SINGLE COMPUTER SYSTEM AND CAN BE COPIED (WITH INCLUSION ; OF DEC'S COPYRIGHT NOTICE) ONLY FOR USE IN SUCH SYSTEM, EXCEPT ; AS MAY OTHERWISE BE PROVIDED IN WRITING BY DEC. ; ; THE INFORMATION IN THIS DOCUMENT IS SUBJECT TO CHANGE WITHOUT ; NOTICE AND SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL ; EQUIPMENT CORPORATION. ; ; DEC ASUMES NO RESPONSIBILITY FOR THE USE OR RELIABILITY ; OF ITS SOFTWARE ON EQUIPMENT WHICH IS NOT SUPPLIED BY DEC. ; ; VERSION: 01 ; BY: H. LEV ; DATE: 11/2/75 ; MODIFIED: ; ; EB027 3/8/77 SAVE SOME WORDS (BE LIKE MCROV) ; ; HJL060 28-MAR-77 ADD SUPPORT FOR DCLS TYPE COMMANDS. ; STOP COMMAND SCAN AT SLASH ("/"). ; ; HJL070 23-JUN-77 ALLOW SEMI-COLON BETWEEN EXCLAMATION MARKS ; ; HJL072 7-JUL-77 DISABLE CHECKPOINTING BEFORE PRINTING PROMPT ; ; PW001 2-AUG-77 DON'T PROMPT AFTER STARTING AT. ; ; RJDK001 28-JUL-78 REMOVE CONTROLS & LEADING SPACES ; ALSO CALLS CCL ON NO TASK/ SYNTAX ERROR ; THIS IS THE DISPATCHER FOR THE MULTI-USER VERSION ; OF MCR. IT DISPATCHES ALL BUT A SMALL SUBSET OF MCR ; COMMANDS TO THE TASK ...SYS. IF A COMMAND IS RECEIVED ; AND IS IN THE TABLE SYSCMD, IT IS SENT TO ...SYS TO BE ; PROCESSED. ; .MCALL CALL,DIR$,MRKT$,RETURN,WTSE$S .MCALL WTLO$S,CMKT$S,RDAF$S,PCBDF$ .SBTTL EQUATED SYMBOLS CR = 15 ; CARRIAGE RETURN ESC = 033 ; ESCAPE (ALT MODE) HT = 011 ; HORIZONTAL TAB SPA = 040 ; SPACE EFN1 = 1 ; EVENT FLAG FOR TI IO EFN2 = 16. ; EVENT FLAG FOR MARKTIME EF1BIT = 1 ; BIT FOR EFN1 EF2BIT = 100000 ; BIT FOR EFN2 LUN1 = 1 ; "TI" LUN. PCBDF$ ; DEFINE PCB OFFSETS ; TRANSFER VECTOR INDICES ; ; AT THE BEGINNING OF EACH OVERLAY THERE IS A TABLE OF ; ENTRY POINTS FOR THE OVERLAY. THESE ENTRY POINTS ARE ; FOR COMMANDS, PARSERS OR THE DISPATCHER OR THE ERROR PROCESSER ; THEY ARE USED BY MCRDIS AND MCROOT TO PASS CONTROL TO THE ; CORRECT PROCESSOR. MCROOT EXECUTES AN INDIRECT JUMP ; THROUGH THE FIRST ADDRESS OF THE OVERLAY USING THESE INDICES ; TO INDEX INTO THE TRANSFER VECTOR TABLE. ; $ABOEP = 2 ; ABORT $CANEP = 4 ; CANCEL TASK $FIXEP = 6 ; FIX TASK $LN1EP = 10 ; LUNS FILE SET UP $LUNEP = 0 ; LOGICAL UNIT LIST $PR1EP = 0 ; PARSER 1 $REMEP = 12 ; REMOVE $RESEP = 14 ; RESUME $UNFEP = 16 ; UNFIX TASK .SBTTL MACRO DEFINITIONS ; DEFINE OVERLAY TABLE ENTRY ; NAME IS 3 CHAR COMMAND NAME ; PARSER IS OPTIONAL 3 CHAR PARSER NAME ; COMMON IS OPTIONAL 3 CHAR COMMON OVERLAY NAME FOR COMMAND PROCESSOR ; COMEP IS OPTIONAL COMMON OVERLAY ENTRY POINT IF DIFFERENT FROM $'NAME'EP ; .MACRO .OVLY,NAME,PARSER,COMMON,COMEP .RAD50 /NAME/ .WORD $'NAME'EP .IF B,PARSER .IFF .WORD PARSER'.. .IFT .WORD NUL.. .ENDC .IF B,COMMON .IFF .RAD50 /COMMON/ .IF B COMEP .IFT .WORD $'NAME'EP .IFF .WORD $'COMEP'EP .ENDC .IFT .WORD 0,0 .ENDC .ENDM .SBTTL LOCAL DATA ;******************************** ; ; TRANSFER VECTOR ; ; THIS WORD MUST BE LOCATED AT WORD ZERO OF THE ; OVERLAY SINCE THE ROOT SEGMENT PASSES CONTROL TO THE ; ENTRY POINT VIA AN INDEXED JUMP THROUGH THIS LOCATION ; ; THE LABEL "$OVEP" IS USED BY THE ROOT AS THE ADDRESS ; OF THE TRANSFER VECTOR TABLE FOR ALL OVERLAYS. ; $OVEP:: .WORD MCREP ; DISPATCHER ENTRY POINT ; ;********************************* ; C O M M A N D T A B L E ; ; FORMAT OF ENTRIES: ; ; WORD1 RAD50 COMMAND NAME (3 CHARACTERS) ; WORD2 ENTRY POINT TRANSFER VECTOR INDEX ; INTO COMMAND OVERLAY OR COMMON OVERLAY ; ; THE FOLLOWING WORDS MAY BE ZERO IF THERE ISN'T ; ANY PARSER OR COMMON OVERLAY ; WORD3 ADDRESS OF TWO WORD PARSER NAME AND ENTRY POINT TABLE ; WORD4 COMMON COMMAND OVERLAY NAME (3 CHARACTERS). ; WORD5 ENTRY POINT TRANSFER INDEX FOR COMMON OVERLAY ; ; ; UNPRIVILEDGED COMMANDS - ALL TERMINALS MAY ISSUE THESE. ; MCMDUP: .OVLY ABO,PR1,PR1 ; ABORT .OVLY CAN,PR1,PR1 ; CANCEL .OVLY LUN,PR1,PR1,LN1 ; LOGICAL UNITS .OVLY REM,PR1,PR1 ; REMOVE .OVLY RES,PR1,PR1 ; RESUME .WORD 0 ; END OF TABLE ; ; PRIVILEDGED COMMANDS - ONLY TERMINALS WITH U2.PRV SET IN ; U.CW2 OF THE UCB MAY ISSUE THESE. ; MCMDPR: .OVLY FIX,PR1,PR1 ; FIX .OVLY UNF,PR1,PR1 ; UNFIX .WORD 0 ; END OF PRIVILEDGED COMMANDS ; ; PARSER TABLE ; PR1..: .RAD50 /PR1/ .WORD $PR1EP ; ; LIST OF COMMANDS PROCESSED BY TASK ...SYS ; SYSCMD: .RAD50 /ACT/ .RAD50 /ALL/ .RAD50 /ALT/ .RAD50 /ASN/ .RAD50 /ATL/ .RAD50 /BRK/ .RAD50 /CLQ/ .RAD50 /DEA/ .RAD50 /DEV/ .RAD50 /OPE/ .RAD50 /PAR/ .RAD50 /REA/ .RAD50 /RED/ .RAD50 /RUN/ .RAD50 /SET/ .RAD50 /TAL/ .RAD50 /TAS/ .RAD50 /TIM/ .WORD 0 ; END OF TABLE ; ; DPB'S ; DISMKT: MRKT$ EFN2,2.,2. ; MARK TIME 2. SECONDS ; ; ERROR TABLE USED TO CONVERT FROM LOCAL ERROR CODES ; TO GLOBAL ERROR CODES USED BY THE ERROR OVERLAY ; DERRTB: .BYTE 1 ; 1 - ILLEGAL FUNCTION .BYTE 0 ; 2 - MARK TIME ERROR .BYTE 6 ; 3 - TASK NOT IN SYSTEM .BYTE 17. ; 4 - TASK ACTIVE .BYTE 44. ; 5 - LATER .BYTE 43. ; 6 - PRIVILEDGED COMMAND .BYTE 2. ; 7 - SYNTAX ERROR .BYTE 20. ; 8 - NO POOL SPACE .BYTE 52. ; 9 - NOT LOGGED IN ; ; PROMPT CHARACTER ; GTSGN: .ASCII <15><12>/>/ ; HLDPMT: .ASCII <33>/\/<15><12>/>/<33>/[/ ; EXIT, PROMPT, ENTER HOLD SCREEN .EVEN DISLEN: .BLKW 1 ; BYTE COUNT-1 COMFLG: .WORD 0 ; COMMENT FLIP FLOP ; ZERO NO COMMENT, NON-ZERO COMMENT IN PROGRWEESS RDEFBF: .BLKW 2 ; READ ALL FLAGS BUFFER (PLUS UNIT:) UNIT: .BLKW 3 ; UNIT NUMBER CONVERSION AREA .SBTTL DISPATCHER CODE ;+ ; ; *** - MCREP-MCR DISPATCHER ; ; THE MCR DISPATCHER OBTAINS COMMANDS FROM THE MCR UNSOLICITED ; MESSAGE QUEUE. IT EDITS THE INPUT MESSAGE TO REMOVE ; MULTIPLE SPACES, CONVERTS TABS TO SPACES, CONVERTS "ESC" ; TO "CR" AND IF NEEDED INSERTS A "CR" INTO BYTE 80 ON A FULL ; BUFFER. THE DISPACTHER EXTRACTS THE COMMAND CODE AND DETERMINES WHETHER ; OR NOT IT IS VALID. IT THEN REQUESTS THE PARSER OVERLAY ; IF THIS COMMAND IS PRE-PROCESSED BY A PARSER. ; OTHERWISE IT REQUESTS THE CORRECT COMMAND PROCESSING OVERLAY ; OR THE COMMAND PROCESSING TASK TO FINISH PROCESSING THE COMMAND. ; IF ERRORS ARE DETECTED, IT CALLS THE ERROR PROCESSING OVERLAY. ; ; SIDE EFFECTS-INPUT: ; ; T.RCVL-POINTS TO THE MCR UNSOLICITED MESSAGE QUEUE ; ; SIDE EFFECTS-OUTPUT: ; ; $MCMD - RAD50 COMMAND NAME ; $MCMD+2 - COMMAND PROCESSOR ENTRY POINT ; $MPSR - RAD50 PARSER NAME ; $MPSR+2 - PARSER ENTRY POINT ; $MBUF - ADDRESS OF MESSAGE BUFFER ; $MERRN - ERROR NUMBER IF ERROR DETECTED ; ; OUTPUTS: ; ; R5-POINTER TO NEXT CHARACTER IN COMMAND BUFFER AFTER LIST ; THREE CHARACTERS OF COMMAND VERB. ; ;- ; ; GET NEXT BUFFER TO PROCESS ; MCREP: CLR $MDPB+10 ; ZERO ADDRESS OF I/O STATUS BLOCK MOV $MBUF,R0 ; DO WE HAVE TO PROMPT? ; IF NON-ZERO, IT MEANS MCR JUST ; PROCESSED A COMMAND AND SHOULD ; ISSUE THE PROMPTING CHARACTER. BEQ MCR1 ; NO, WE WERE JUST CALLED BY EXEC. 10$: CMPB $MTERM,#ESC ; LINE TERMINATED BY ESCAPE? BEQ MCRP1 ; YES, SKIP PROMPT MCRPMT: CALL PROMPT ; NO, ISSUE PROMPT STRING MOV $MUCB,R0 ; GET TI UCB ADDRESS BIC #U2.AT.,U.CW2(R0) ; CLEAR INDIRECT FILE FLAG MCRP1: CLR $MBUF ; SHOW BUFFER IS FREE MCR1: MOV #5.,R0 ; SET COUNT MOV #$MCMD+2,R1 ; GET AREA TO CLEAR 3$: CLR (R1)+ ; ZERO WORD DEC R0 ; DONE ? BNE 3$ ; NO, LOOP CALL $SWSTK,5$ ; SWITCH TO SYSTEM STACK CLR $MERRN ; ZERO ERROR CODE MOV $TKTCB,R0 ; GET OUR TCB ADDRESS ADD #T.RCVL,R0 ; AND THEN ADDRESS OF RECEIVE LIST CALL $QRMVF ; REMOVE A MESSAGE BCC 4$ ; GOT ONE BIT #FE.MXT,$FMASK ; SHOULD MCR EXIT INSTEAD OF STOP? BEQ 301$ ; NO MOV $TKTCB,R5 ; YES, GET OUR TCB ADDRESS CALLR $DREXT ; AND EXIT DIRECTLY TO EXEC. 301$: CALLR $STPCT ; WAIT FOR MORE COMMANDS 4$: MOV R1,$MBUF ; SAVE BUFFER ADDRESS MOV 2(R1),R0 ; GET UCB ADDRESS BIC #1,R0 ; CLEAR PROMPT REQUEST BIT 41$: MOV U.RED(R0),R0 ; FOLLOW REDIRECT POINTER CMP R0,U.RED(R0) ; END OF LIST? BNE 41$ ; NO, CONTINUE DOWN IT MOV R0,$MUCB ; SET UCB ADDRESS MOV $TKTCB,R2 ; GET OUR TCB ADDRESS MOV R0,T.UCB(R2) ; ASSIGN TI TO CURRENT UCB RETURN ; SWITCH TO USER STACK 5$: MOV $MBUF,R0 ; GET BUFFER ADDRESS BEQ MCREP ; ZERO MEANS NOW COMMAND LINE TRY AGAIN BIT #1,2(R0) ; IS THIS A PROMPT REQUEST? BEQ 30$ ; NO ; ; BUFFER IS PROMPT REQUEST ; MOV #4.,R1 ; SET COUNT OF BYTES TO RELEASE CALL $SWSTK,MCRPMT ; SWITCH TO SYSTEM STATE CALLR $DEACB ; RELEASE BLOCK AND GO TO PROMPT ; ; BUFFER CONTAINS A COMMAND ; 30$: MOV #84./2,R2 ; SET COUNT OF WORDS IN BUFFER MOV #$MLINE,R1 ; SET DESTINATION ADDRESS 33$: MOV (R0)+,(R1)+ ; MOVE NEXT WORD DEC R2 ; DONE? BNE 33$ ; NO, LOOP MOV $MBUF,R0 ; GET BUFFER ADDRESS CALL $SWSTK,37$ ; SWITCH TO SYSTEM STATE MOV #84.,R1 ; SET BUFFER LENGTH CALLR $DEACB ; RELEASE DYNAMIC BUFFER 37$: MOV #$MLINE,R0 ; POINT TO MCR INTERNAL BUFFER MOV R0,$MBUF ; SAVE POINTER TO BUFFER CMP (R0)+,(R0)+ ; SKIP TO BEGINNING OF COMMAND MOV $MUCB,R2 ; GET TI UCB ADDRESS MOV U.CW4(R2),R2 ; GET MAX LENGTH OF COMMAND LINE CMP R2,#80. ; IS IT GREATER THAN 80.? BLE 38$ ; NO MOV #80.,R2 ; YES, DEFAULT TO 80. 38$: MOV R0,R3 ; GET BUFFER ADDRESS ; ; CONVERT TABS TO SPACES, ESC TO CR, REMOVE ALL MULTIPLE ; BLANKS AND INSERT A CR AT THE END OF THE BUFFER IF NONE IS ; THERE. WHEN THIS PROCESS IS DONE THE BUFFER WILL ; BE FORMATTED SO THAT THERE WILL BE FIELDS TERMINATED BY ; ONE SPACE, AND THE END OF BUFFER WILL BE MARKED BY A ; CARRIAGE RETURN. NO BUFFERS WILL BE LONGER THAN 80 CHARACTERS ; ; IF A SEMI COLON IS FOUND IN THE FIRST COLUMN OF TEXT THE LINE WILL ; BE TREATED AS A COMMENT. AN EXCLAMATION MARK INDICATES ; THE BEGINNING OF A COMMENT FIELD, THE NEXT EXCLAMATION MARK TERMINATES ; THE COMMENT FIELD. AN NUMBER OF PAIRS MAY BE INCLUDED ON A LINE ; IF NO TRAILING EXCLAMATION MARK IS FOUND, THE LINE TERMINATOR TERMINATES ; THE COMMENT ; MCR2: CLR DISLEN ; ZERO COMPACTED LINE LENGTH CLR $MTERM ; ZERO TERMINATOR CLR COMFLG ; SET NO COMMENT IN PROGRESS 6$: MOVB (R3)+,R1 ; GET NEXT CHAR CMPB R1,#CR ; IS IT CARRIAGE RETURN (EOB) ? BEQ 20$ ; YES CMPB R1,#ESC ; IS IT ESCAPE ( ALT MODE )? BEQ 20$ ; YES ; DELETE TESTS FOR HT & SPACE [RJDK001] ; INCLUDE IN MORE GENERAL LATER CMPB R1,#IE.EOF ; CTRL/Z? BNE 7$ ; NO MOVB #CR,R1 ; YES, SET IT TO CR BR 20$ ; 7$: TST DISLEN ; ANY TEXT YET? [RJDK001] BNE 71$ ; YES [RJDK001] CMPB R1,#SPA ; CONTROL OR SPACE [RJDK001] BLE 6$ ; YES JUST IGNORE IT [RJDK001] 71$: CMPB R1,#SPA ; GENERAL SPACES & CONTROLS [RJDK001] BLE 10$ ; YES - THEN MAKE JUST 1 SPACE [RJDK001] TST COMFLG ; COMMENT IN PROGRESS? ;HJL070 BNE 75$ ; YES, SKIP SEMI-COLON CHECK ;HJL070 CMPB R1,#'; ; SEMI-COLON? ;HJL070 BEQ 8$ ; YES ;**-1 75$: CMPB R1,#'! ; NO, EXCLAMATION MARK? ;HJL070 BNE 15$ ; NO ;**-1 COM COMFLG ; YES, COMPLEMENT COMMENT FLIP FLOP BR 6$ ; 8$: TST DISLEN ; SEMI-COLON IN COLUMN 1? BNE 15$ ; NO, NOT A COMMENT LINE INC COMFLG ; SET FLAG SO NEVER CAN GO TO ZERO BR 6$ ; 10$: CMPB #SPA,-1(R0) ; LAST CHARACTER A SPACE ? BEQ 6$ ; YES, SO SKIP THIS ONE MOV #SPA,R1 ; NO, SET SPACE 15$: TST COMFLG ; COMMENT IN PROGRESS BNE 6$ ; YES, SKIP THIS CHARACTER CMPB R1,#141 ; LOWER CASE? BLT 17$ ; NO CMPB R1,#172 ; MAYBE BGT 17$ ; NO SUB #40,R1 ; YES, CONVERT IT TO UPPER CASE 17$: MOVB R1,(R0)+ ; NO, STORE THE CHAR IN BUFFER INC DISLEN ; INCREMENT LENGTH OF COMPACTED LINE DEC R2 ; BUFFER FULL ? BNE 6$ ; NO MOVB #CR,R1 ; YES, FORCE CR AT END MOVB R1,-(R0) ; AND STORE IT IN LINE DEC DISLEN ; DECREMENT LENGTH OF COMPACTED LINE 20$: CMPB #SPA,-1(R0) ; LAST CHAR IN BUFFER A BLANK ? BNE 25$ ; NO TSTB -(R0) ; YES, DELETE IT DEC DISLEN ; DECREMENT LENGTH OF COMPACTED LINE 25$: MOVB #CR,(R0) ; NOW PUT IN CARRIAGE RETURN MOV R1,$MTERM ; SAVE TERMINATOR TST DISLEN ; IS LINE ALL COMMENT? BGT 30$ ; NO JMP MCREP ; YES, SKIP PROCESSING IT ; GET COMMAND NAME ; 30$: MOV $MBUF,R0 ; GET ADDRESS OF BUFFER CMP (R0)+,(R0)+ ; POINT TO DATA CLR R1 ; PERIOD IS TERMINATOR CMPB (R0),#'@ ; INDIRECT COMMAND BEQ LODAT ; YES CALL $CAT5 ; CONVERT 3 CHARS TO RAD50 BCC 40$ ; JMP LODCCL ; USE CCL TO DECODE IT [RJDK001] 40$: MOVB (R0)+,R2 ; GET NEXT CHARACTER CMPB R2,#SPA ; IS IT SPACE? BEQ 50$ ; YES, END OF COMMAND NAME CMPB R2,#CR ; NO, IS IT CARRIAGE RETURN? BEQ 45$ ; YES, END OF COMMAND CMPB R2,#'/ ; DCLS TYPE COMMAND? ;HJL060 BEQ 45$ ; YES, STOP SCAN ;HJL060 CMPB R2,#101 ; NO, IS IT AN ALPHA? BLO 42$ ; NO CMPB R2,#132 ; MAYBE BLOS 40$ ; YES 42$: CMPB R2,#60 ; NO, IS IT A NUMERIC? BLO 44$ ; NO, ERROR CMPB R2,#71 ; MAYBE BLOS 40$ ; YES 44$: JMP LODCCL ; SYNTAX ERROR [RJDK001] 45$: DEC R0 ; BACK UP OVER CARRIAGE RETURN ; ; SCAN THE COMMAND TABLES FOR THE COMMAND TYPED IN. ; ; R1=RAD50 COMMAND NAME ; 50$: MOV #MCMDUP,R2 ; GET UNPRIVILEDGED COMMAND TABLE CALL CMDSRC ; SEARCH THIS TABLE FOR COMMAND TST (R2) ; DID WE FIND IT BNE LDOVLY ; YES, LOAD OVERLAY ; ; SCAN PRIVILEDGED COMMAND TABLE ; MOV #MCMDPR,R2 ; GET PRIVILEDGED COMMAND TABLE CALL CMDSRC ; SEARCH TABLE FOR COMMAND TST (R2) ; DID WE FIND ONE? BEQ 60$ ; NO, MAYBE ITS PROCESSED BY ...SYS ; ; COMMAND IS PRIVILEDGED , SEE IF TERMINAL IS PRIVILEDGED ; MOV $MUCB,R1 ; GET UCB ADDRESS BIT #U2.PRV,U.CW2(R1) ; IS TERMINAL PRIVILEDGED? BNE LDOVLY ; YES JMP DISER8 ; NO, PRIVILEGED COMMAND ; ; SCAN TABLE SYSCMD FOR COMMANDS PROCESSED BY ...SYS ; 60$: MOV #SYSCMD,R2 ; POINT TO TABLE 70$: CMP R1,(R2)+ ; IS COMMAND IN TABLE? BEQ LODSYS ; YES, GET ...SYS TO PROCESS IT TST (R2) ; NO, END OF TABLE? BNE 70$ ; NO, LOOP BR LDTSK ; YES, MUST BE PROCESSED BY A TASK ; ; THE COMMAND IS VALID AND IS PROCESSED BY AN OVERLAY. SET UP TO CALL OVERLAY ; LDOVLY: CMP R1,(PC)+ ; IS THIS REMOVE? .RAD50 /REM/ ; BEQ 5$ ; YES, ALWAYS ALLOW IT MOV $MUCB,R1 ; GET TI UCB ADDRESS BIT #U2.LOG,U.CW2(R1) ; IS TERMINAL LOGGED ON? BEQ 5$ ; YES JMP DISE12 ; NO, ERROR 5$: MOV R0,R5 ; COPY NEXT CHAR POINTER MOV #$MCMD,R0 ; GET COMMAND STORAGE AREA MOV (R2)+,(R0)+ ; STORE COMMAND AND MOV (R2)+,(R0)+ ; ENTRY POINT TRANSFER INDEX MOV (R2)+,R1 ; GET PARSER TABLE ELEMENT ADDRESS MOV (R1)+,(R0)+ ; STORE PARSER MOV (R1)+,(R0)+ ; AND ENTRY POINT TRANSFER INDEX MOV (R2)+,(R0)+ ; STORE COMMON COMMAND OVERLAY MOV (R2)+,(R0) ; AND ENTRY POINT TRANSFER INDEX MOV #$MPRSR,R0 ; POINT TO PARSER TST (R0) ; IS THERE ONE ? BNE 10$ ; YES MOV #$MCOV,R0 ; POINT TO COMMON OVERLAY TST (R0) ; IS THERE ONE ? BNE 10$ ; YES MOV #$MCMD,R0 ; POINT TO COMMAND OVERLAY 10$: JMP $MLDOV ; LOAD OVERLAY ; ; REQUEST TASK LOAD ; LODCCL: MOV (PC)+,R1 ; GET CCL'S NAME [RJDK001] .RAD50 /CCL/ ; [RJDK001] BR LDTSK ; AND LOAD IT [RJDK001] LODSYS: MOV (PC)+,R1 ; GET NAME OF TASK .RAD50 /SYS/ ; BR LDTSK ; AND BRING IT UP LODAT: MOV (PC)+,R1 ; SET NAME FOR INDIRECT .RAD50 /AT./ ; COMMAND PROCESSOR TASK LDTSK: MOV #$MPARS+2,R3 ; GET ADDRESS FOR TASK NAME MOV R1,(R3) ; STORE COMMAND NAME MOV (PC)+,-(R3) ; STORE ... .RAD50 /.../ ; MOV $MUCB,R0 ; GET TI UCB ADDRESS BIT #U2.LOG,U.CW2(R0) ; IS TERMINAL LOGGED ON? BEQ 15$ ; YES CMP $MPARS+2,(PC)+ ; NO, TRYING TO LOG ON? .RAD50 /HEL/ ; BEQ 5$ ; YES JMP DISE12 ; NO, ERROR NOT LOGGED ON 5$: MOV #402,U.UIC(R0) ; SET UIC FOR HELLO TO [1,2] MOV #402,U.LUIC(R0) ; SET PROTECTION UIC TO [1,2] BR 15$ ; 12$: JMP DISER2 ; 13$: JMP DISER4 ; TASK NOT IN SYSTEM 14$: JMP DISER6 ; TASK ACTIVE ; ; SYSCOM POINTER IS FREE, FIND TASK ; 15$: CALL $LOCKL ; LOCK SYSTEM LISTS CALL $SWSTK,40$ ; SWITCH TO SYSTEM STATE CLR R5 ; ZERO PARENT TCB ADDRESS CALL $SRSTD ; SEARCH FOR TASK BCC 16$ ; FOUND IT [RJDK001] CLR R5 ; SET NO PARENT [RJDK001] MOV (PC)+,R1 ; GET CCL NAME [RJDK001] .RAD50 /CCL/ ; [RJDK001] MOV R1,$MPARS+2 ; AND SET FOR LATER [RJDK001] CALL $SRSTD ; SEARCH FOR CCL INSTEAD [RJDK001] BCS 17$ ; NOT IN SYSTEM 16$: ; REF LABEL [RJDK001] TST T.STAT(R0) ; IS TASK ACTIVE? .IF DF M$$MGE BMI 19$ ; NO, START IT UP .IFF BMI 30$ ; NO, START IT UP .ENDC CMP $MUCB,T.UCB(R0) ; YES, IS IT ACTIVE FOR THIS TERMINAL? BEQ 14$ ; YES, CAN'T SPAWN ANOTHER TASK MOV R0,R5 ; NO, COPY PARENT TCB ADDRESS ; ; TASK ...XXX IS ACTIVE OR NOT IN SYSTEM. ; LOOK FOR TASK XXXN ; 17$: CLRB UNIT+2 ; ZERO UNIT NUMBER MOV #UNIT+1,R3 ; GET ADDRESS OF UNIT AREA CALL $GTMNM ; CONVERT TERMINAL NUMBER TO ASCII MOV $MUCB,R0 ; GET TI UCB ADDRESS MOV U.DCB(R0),R0 ; GET DCB ADDRESS MOVB D.NAM(R0),UNIT ; GET FIRST CHARACTER OF DEVICE NAME MOV #UNIT,R0 ; POINT TO ASCII TERMINAL NUMBER CALL $CAT5 ; CONVERT TO RAD50 MOV #$MPARS,R3 ; POINT TO TASK NAME MOV 2(R3),(R3) ; SET NAME TO XXXYN MOV R1,2(R3) ; CALL $SRSTD ; SEARCH FOR TASK XXXYN .IF DF M$$MGE .IFF BCS 13$ ; TASK NOT IN SYSTEM .IFT BCS 20$ ; TASK NOT IN SYSTEM TST T.STAT(R0) ; TASK ACTIVE? BPL 14$ ; YES, ERROR CLR R5 ; NO, SET NO PARENT 19$: BR 30$ ; START IT UP FOR THIS TERMINAL 20$: TST R5 ; PARENT FOUND? BEQ 13$ ; NO, TASK NOT IN SYSTEM ; ; TASK ...XXX FOUND, XXXYN NOT FOUND. TRY TO SPAWN TASK XXXYN ; MOV T.PCB(R5),R1 ; GET TASK PCB ADDRESS MOV P.MAIN(R1),R4 ; GET MAIN PARTITION BIT #PS.SYS,P.STAT(R4) ; SYSTEM CONTROLLED PARTITION? BEQ 14$ ; NO, TASK ACTIVE BIT #T2.CHK,T.ST2(R5) ; IS PARENT CHECK POINTABLE? BNE 21$ ; NO BIT #FE.CAL,$FMASK ; YES, DYNAMIC CHECKPOINT SUPPORTED? BEQ 14$ ; NO, TASK ACTIVE 21$: MOV #T.LGTH,R1 ; YES, GET LENGTH OF A TCB CALL $ALOCB ; TRY TO GET A TCB BCS 26$ ; COULDN'T, NO POOL SPACE ; ; TCB ALLOCATED, FILL IN TCB FROM PARENT ; MOV R5,R3 ; COPY PARENT TCB ADDRESS MOV R0,R1 ; COPY OFFSPRING TCB ADDRESS CLR (R1)+ ; ZERO T.LNK TST (R3)+ ; MOVB (R3)+,(R1)+ ; COPY T.PRI CLRB (R1)+ ; ZERO T.IOC TSTB (R3)+ ; CLR (R1)+ ; ZERO CHECKPOINT PCB MOV $MPARS,(R1)+ ; SET TASK NAME MOV $MPARS+2,(R1)+ ; MOV R1,R2 ; GET ADDRESS OF T.RCVL CLR (R1)+ ; ZERO FORWARD POINTER MOV R2,(R1)+ ; SET BACK POINTER MOV R1,R2 ; GET ADDRESS OF T.ASTL CLR (R1)+ ; ZERO FORWARD ADDRESS MOV R2,(R1)+ ; SET BACK POINTER CLR (R1)+ ; ZERO T.EFLG CLR (R1)+ ; MOV $MUCB,(R1)+ ; SET TI UCB ;**-1 CLR (R1)+ ; ZERO T.TCBL MOV #TS.EXE!TS.OUT,(R1)+ ; SET NOT IN EXEC AND OUT OF MEMORY ; EB027 ADD #T.ST2-T.CPCB,R3 ; POINT TO PARENT'S T.ST2 ; EB027 MOV (R3)+,(R1) ; GET T.ST2 ;**-3 BIC #^C,(R1)+ ; CLEAR ALL BUT CHECKPOINTABLE FLAG MOV (R3)+,(R1) ; GET T.ST3 BIC #^C,(R1)+ ; COPY IMPORTANT FLAGS MOVB (R3)+,(R1)+ ; COPY DEFAULT PRIORITY T.DPRI MOVB (R3)+,(R1)+ ; COPY T.LBN MOV (R3)+,(R1)+ ; COPY T.LBN+1 MOV (R3)+,(R1)+ ; COPY T.LDV MOV R4,(R1)+ ; SET T.PCB TST (R3)+ ; MOV (R3)+,(R1)+ ; COPY T.MXSZ CLR (R1)+ ; ZERO T.ACTL BIT #FE.PLA,$FMASK ; PLAS SUPPORTED? BEQ 22$ ; NO MOV R1,R2 ; COPY ADDRESS CLR (R1)+ ; ZERO LIST HEAD MOV R2,(R1)+ ; SET LIST END POINTER T.ATT ADD #T.OFF-T.ACTL,R3 ; POINT TO T.OFF MOV (R3)+,(R1)+ ; SET T.OFF CLR (R1)+ ; ZERO T.SRCT MOV R1,R2 ; COPY ADDRESS OF T.RRFL CLR (R1)+ ; ZERO LIST HEAD MOV R2,(R1)+ ; SET BACK POINTER ; ; INSERT TCB INTO STD ; 22$: MOV T.TCBL(R5),R1 ; GET LINK TO NEXT TCB TST T.TCBL(R1) ; NULL TASK? BEQ 24$ ; YES CMPB T.DPRI(R0),T.DPRI(R1) ; NEW TASK HIGHER PRIORITY? BHI 24$ ; YES MOV R1,R5 ; NO, COPY TCB ADDRESS BR 22$ ; LOOP TO END OF STD 26$: BR DISE11 ; NO POOL SPACE 24$: MOV R1,T.TCBL(R0) ; LINK OFFSPRING TCB INTO STD MOV R0,T.TCBL(R5) ; .IFTF MOVB T.DPRI(R0),T.PRI(R0) ; SET CURRENT PRIORITY ; ; START TASK UP ; 30$: MOV R0,-(SP) ; SAVE TCB ADDRESS MOV $MUCB,R2 ; GET UCB ADDRESS MOV U.UIC(R2),R1 ; SET DEFAULT UIC MOV R1,R3 ; COPY DEFAULT UIC BIT #FE.MUP,$FMASK ; MULTI-USER PROTECTION? BEQ 31$ ; NO BIT #U2.PRV,U.CW2(R2) ; PRIVILEGED USER? BNE 31$ ; YES, USE R1 AS PROTECTION UIC MOV U.LUIC(R2),R1 ; NO, GET PROTECTION UIC 31$: CALL $TSKRP ; START TASK WITH PROTECTION MOV (SP)+,R0 ; RESTORE TCB ADDRESS BCC 32$ ; GOOD IT'S STARTED .IFT TST R5 ; IS THIS AN OFFSPRING TCB? BEQ DISER6 ; NO MOV T.TCBL(R0),T.TCBL(R5) ; YES, UNLINK IT FROM STD MOV #T.LGTH,R1 ; GET LENGTH OF TCB CALL $DEACB ; RELEASE IT .ENDC BR DISER6 ; ; ; SET UP MCR COMMAND BUFFER FOR GMCR$ ; 32$: TST R5 ; IS THIS AN OFFSPRING TASK? BEQ 34$ ; NO BIS #T3.REM,T.ST3(R0) ; YES, SET TO REMOVE ON EXIT 34$: CMPB $MTERM,#ESC ; TERMINATED BY ESCAPE? BEQ 35$ ; YES, DON'T PROMPT MOV #<^RCCL>,R1 ; OR IS IT CCL? [RJDK001] CMP R1,$MPARS+2 ; ...CCL? [RJDK001] BEQ 35$ ; YES DONT PROMPT [RJDK001] CMP R1,$MPARS ; OR CCLXN [RJDK001] BEQ 35$ ; YES NEITHER FOR THIS [RJDK001] BIS #T3.MCR,T.ST3(R0) ; NO, SET TO PROMPT ON TASK EXIT 35$: MOV $MBUF,R1 ; GET BUFFER ADDRESS MOV R0,2(R1) ; STORE TCB ADDRESS MOV #84.,R1 ; SET BUFFER SIZE TO GET CALL $ALOCB ; TRY TO GET IT BCS DISER9 ; COULDN'T GET ONE MOV DISLEN,R2 ; GET BYTE COUNT-1 ADD R0,R2 ; COMPUTE ADDRESS ADD #4,R2 ; OF TERMINATOR MOVB $MTERM,(R2) ; AND STORE IN BUFFER MOV R0,R1 ; COPY BUFFER ADDRESS MOV DISLEN,R2 ; GET LENGTH-1 AGAIN ADD #4.,R2 ; INCLUDE LINK WORDS MOV $MBUF,R3 ; GET ADDRESS OF COMMAND 37$: MOVB (R3)+,(R1)+ ; MOVE IN COMMAND DEC R2 ; DONE? BGT 37$ ; NO, LOOP UNTIL ALL CHARACTERS ARE COPIED MOV $MCRCB,(R0) ; LINK COMMAND IN MOV R0,$MCRCB ; TO GMCR LIST RETURN ; SWITCH BACK TO USER STACK ; ; TASK STARTED OR ERROR. DETERMINE WHICH AND PROCESS. ; 40$: CALL $UNLKL ; UNLOCK SYSTEM LISTS TST $MERRN ; IS THERE AN ERROR BNE DISERR ; YES, PROCESS ERROR CLR $MBUF ; ZERO BUFFER, SET NO PROMPT ;**-6 JMP MCR1 ; GO GET NEXT BUFFER ; ERROR MESSAGE CODES ARE BUILT HERE ; DISE11: ADD #3,$MERRN ; 8 - NO POOL SPACE DISER9: INC $MERRN ; 5 - LATER DISER6: INC $MERRN ; 4 - TASK ACTIVE DISER4: ADD #2,$MERRN ; 3 - TASK REQUEST ERROR DISER3: INC $MERRN ; 1 - INVALID COMMAND RETURN ; RETURN TO USER STACK DISE12: ADD #2.,$MERRN ; 9 - NOT LOGGED ON DISE10: INC $MERRN ; 7 - SYNTAX ERROR DISER8: INC $MERRN ; 6 - PRIV CMD DISER7: ADD #3,$MERRN ; 5 - LATER DISER2: INC $MERRN ; 2 - MARK TIME ERROR DISER1: INC $MERRN ; 1 - INVALID COMMAND DISERR: MOV $MERRN,R4 ; GET LOCAL ERROR CODE MOVB DERRTB-1(R4),R4 ; GET GLOBAL ERROR CODE MOV R4,$MERRN ; AND SAVE IT FOR ERROR OVERLAY CALL $UNLKL ; UNLOCK SYSTEM LISTS JMP $MERLD ; LOAD ERROR OVERLAY ;+ ; ; *** - CMDSRC-SEARCH COMMAND TABLE FOR MATCH ; INPUT: ; ; R1 - COMMAND IN RAD50 ; R2 - ADDRESS OF COMMAND TABLE ; ; OUTPUT: ; ; R1 - PRESERVED ; R2 - ADDRESS OF COMMAND ENTRY IF FOUND ; (R2)><0 IF FOUND ; (R2)=0 OF NOT FOUND ; ;- CMDSRC: CMP R1,(R2) ; IS THE COMMAND BEQ 10$ ; YES ADD #10.,R2 ; NO, INDEX TO NEXT ENTRY TST (R2) ; END OF TABLE BNE CMDSRC ; NO, TRY NEXT COMMAND 10$: RETURN ; RETURN ;+ ; *** - PROMPT - ISSUE PROMT TO "TI" ; ; INPUT: ; NONE ; ; OUTPUT: ; NONE ; ;- PROMPT: MOV #$MDPB+2,R0 ; POINT TO DPB FOR QIO MOV #IO.WVB,(R0)+ ; SET FUNCTION CODE MOV #LUN1,(R0)+ ; AND LOGICAL UNIT NUMBER FOR "TI" MOV #EFN1,(R0)+ ; SET EVENT FLAG MOV #$MPARS,(R0)+ ; SET I/O STATUS BLOCK ADDRESS CLR (R0)+ ; ZERO AST MOV $MUCB,R1 ; GET TI UCB ADDRESS BIT #U2.HLD,U.CW2(R1) ; IS IT IN HOLD SCREEN MODE? BNE 3$ ; YES MOV #GTSGN,(R0)+ ; SET BUFFER POINTER MOV #3,(R0)+ ; SET CHARACTER COUNT BR 5$ ; 3$: MOV #HLDPMT,(R0)+ ; SET HOLD SCREEN MODE PROMPT MOV #7.,(R0)+ ; SET BYTE COUNT 5$: CLR (R0)+ ; NO CARRIAGE CONTROL CALL $MCKD ; DISABLE CHECKPOINTING ;HJL072 DIR$ #$MDPB ; ISSUE QIO BCS 10$ ; DIR$ #DISMKT ; MARK TIME FOR 2 SECONDS BCS 10$ ; ERROR WTLO$S 0,#EF1BIT!EF2BIT ; WAIT FOR I/O OR TIME OUT CMKT$S ; CANCEL MARK TIME BCS 10$ ; ERROR RDAF$S #RDEFBF ; READ THE EVENT FLAGS BIT #EF1BIT!EF2BIT,RDEFBF ; WRITE COMPLETE? BPL 10$ ; YES MOV #IO.KIL,$MDPB+2 ; NO, SET TO ISSUE KILL I/O CLR $MDPB+6 ; ZERO EVENT FLAG DIR$ #$MDPB ; ISSUE KILL I/O MOV #IO.WVB,$MDPB+2 ; RESET FUNCTION CODE MOV #EFN1,$MDPB+6 ; AND EVENT FLAG BCS 10$ ; ERROR WTSE$S #EFN1 ; WAIT FOR COMPLETION 10$: CLR $MDPB+10 ; ZERO I/O STATUS BLOCK ADDRESS CALL $MCKE ; ENABLE CHECKPOINTING ;HJL072 RETURN ; .END