.TITLE TSMCR ; ; TSMCR (TIME-SHARED MCR) IS A PSEUDO-CLI TASK THAT ALLOWS SEVERAL ; SIMULTANEOUS TIME-SHARED TASKS (CURRENTLY UP TO 5) TO BE RUN AT AN ; IAS TERMINAL. TSMCR WILL TAKE CONTROL-C RESPONSE AWAY FROM THE CLI ; (NORMALLY PDS) AND FUNCTION SIMILIARLY TO THE RSX-11D MCR, EXCEPT ; THAT IT WILL ADHERE TO THE CONSTRAINTS OF THE IAS TIME-SHARING ; CONTROL PRIMITIVES (TCP), INCLUDING THE SET DEFAULT CHARACTERISTICS. ; HOWEVER, TSMCR ADHERES TO THE RSX-11D COMMAND SYNTAX RATHER THAN ; THE PDS SYNTAX. ; ; TSMCR IS INITIALLY ACTIVATED SIMPLY BY RUN TSMCR. AFTER EACH COMMAND ; TSMCR WILL GO INTO A WAIT STATE AND WILL REPROMPT THE TERMINAL FOR ; INPUT ONLY IN RESPONSE TO A CONTROL-C OR WHENEVER A REQUESTED TASK ; EXITS. A CONTROL-Z INPUT WILL RETURN TSMCR TO ITS WAIT STATE. ; ; NOTE: WHEN TSMCR EXITS, THE CONSTRAINTS OF IAS ARE SUCH THAT TCP WILL ; ABORT ANY TSMCR-INITIATED TASKS THAT ARE STILL ACTIVE. ; ; TSMCR ACCEPTS FOUR TYPES OF INPUTS: RUN COMMANDS, MCR/PDS TYPE COMMANDS, ; THE ABORT COMMAND AND THE EXIT COMMAND. ; ; 1. RUN COMMANDS: TSMCR>RUN TASKNAME ; AN ATTEMPT WILL BE MADE TO EXECUTE AN INSTALLED TASK TASKNAME. IF NO ; SUCH TASK IS INSTALLED, THEN TASKNAME WILL BE ASSUMED TO BE A FILENAME. ; ; 2. MCR/PDS TYPE COMMANDS: TSMCR>[C]XXX [COMMAND LINE] ; IF THE OPTIONAL CHARACTER C IS OMITTED, AN ATTEMPT WILL BE MADE TO ; EXECUTE THE MCR-TYPE TASK ...XXX. IF UNSUCCESSFUL, AN ATTEMPT WILL ; THEN BE MADE TO EXECUTE A PDS-TYPE TASK $$$XXX. IN BOTH CASES THE ; OPTIONAL COMMAND LINE, IF INPUT, WILL BE PASSED TO THE TASK IN SUCH ; A MANNER THAT IT CAN BE READ BY THE GMCR$ OR GMCL$ DIRECTIVES. THE ; OPTIONAL CHARACTER C, WHICH CAN BE A PERIOD (.) OR DOLLAR SIGN($), ; WILL CAUSE TSMCR TO EXECUTE ONLY A MCR-TYPE TASK OR PDS-TYPE TASK ; REPSECTIVELY. ; ; 3. ABORT COMMAND: TSMCR>ABO[RT] TASKNAME ; THE SPECIFIED TASK, IF INITIATED BY TSMCR, WILL BE ABORTED. ; ; 4. EXIT COMMAND: TSMCR>EX[IT][/ABO] ; TSMCR WILL EXIT AND RETURN CONTROL TO THE CLI, NORMALLY PDS. IF ANY ; TASKS ARE STILL ACTIVE, THE USER WILL BE ASKED TO CONFIRM THAT EXIT ; IS REALLY DESIRED, SINCE IAS WILL ABORT ANY TSMCR-INITIATED TASKS ; WHEN TSMCR EXITS. THE OPTIONAL /ABO SWITCH, IF INPUT, WILL SUPPRESS ; THE CONFIRMATION REQUEST. ; ; IN ORDER FOR TSMCR TO FUNCTION PROPERLY, THE USERS ACCOUNT SHOULD HAVE ; A MAXIMUM TASK LIMIT OF AT LEAST 7 (SEE THE SCI COMMAND 'USERS' IN THE ; SYSTEM MANAGERS GUIDE). IN ADDITION, THE TERMINAL CLI ALLOCATION SHOULD ; ALSO ALLOW AT LEAST 7 TASKS (SEE THE SCI COMMANDS 'DEALLOCATE' AND ; 'ALLOCATE' IN THE SYSTEM MANAGERS GUIDE). ; TSMCR WAS WRITTEN ON A SYSTEM WHERE ALL USERS ARE GRANTED ALL TIME-SHARING ; PRIVLEDGES AVAILABLE UNDER THE IAS USERS COMMAND. UNDER MORE RESTRICTIVE ; CONDITIONS, TSMCR MAY NOT FUNCTION AS DESCRIBED. ; ; NOTE: THE FOLLOWING BUG IN THE IAS 2.0 TIME-SHARING CONTROL PRIMITIVES ; AFFECTS TSMCR. IF TWO TASKS OF THE SAME NAME ARE INITIATED AND ; SUBSEQUENTLY AN ABORT REQUEST IS ISSUED FOR ONE OF THEM, THE ; TASK (TSMCR IN THIS CASE) WILL HANG UP IN THE TCP ROUTINE .ABRT ; WAITING FOR A TASK EVENT (EVENT FLAG 2). IT WILL STAY THERE ; UNTIL ONE OF THE ACTIVE TASK EXITS, ABORTS OR CAUSES A SIMILAR ; TASK EVENT. ; ; WRITTEN APRIL 1978 R. FRENCH THE BOEING COMPANY ; ; TASK-BUILD FILE ; ; TSMCR,TSMCR/MA=TSMCR ; / ; ASG=TI:1 ; UNITS=1 ; STACK=32 ; / ; .MCALL TCSMC$,DIR$,QIOW$,EXIT$S ; .MACRO DEFTDB N TDB'N: TDBDF$ EDB'N: ESBDF$ TDEB$A EDB'N TDPR$A JP.PI!JP.PD!JP.PT,PR.RST!PR.CTC!PR.TEV!PR.CHN,20 TDTA$A 1,FB.NC .ENDM ; TCSMC$ DEFTDB 1 DEFTDB 2 DEFTDB 3 DEFTDB 4 DEFTDB 5 TDBS: .WORD TDB5,TDB4,TDB3,TDB2,TDB1 NTDB=.-TDBS TNAMES: .BLKW NTDB NAME: .WORD 2 ; START: CTC$T CLAIM ;CLAIM CONTROL C NOTIFICATION READ: RSAS$T ;RESUME ANY AUTO-SUSPENDED TASKS DIR$ #RDCMD ;WRITE PROMPT AND READ COMMAND CMP #-10.,IOSTAT ;CONTROL-Z? BNE 5$ ;BRANCH IF NOT TST NTASK ;ANY TASKS ACTIVE? BEQ 1$ ;IF NOT, GO EXIT INC EXFLAG ;OTHERWISE, JUST SET FLAG JMP WAIT ;AND GO WAIT 1$: JMP DONE 5$: MOV #CMDCHR,R1 ;CHECK FOR TYPE OF COMMAND MOV #NCMD,R2 10$: CMPB BUF,(R1)+ ;COMPARE AGAINST 1ST CHARACTER BEQ 20$ SOB R2,10$ JMP MCR ;IF NO MATCH - ASSUME MCR TYPE COMMAND 20$: DEC R2 ;DECREMENT POINTER ASL R2 ;CONVERT TO BYTES CMP #2,R2 ;DOT OR DOLLAR? BLT 30$ ;BRANCH IF NOT JSR PC,GETTDB ;GET A TDB BCC 25$ ;CHECK FOR ERRORS JMP NOTDB 25$: MOV #BUF+1,R1 ;SET POINTER TO START OF COMMAND DEC IOSTAT+2 30$: JMP @TBL(R2) ;AND DISPATCH FROM TABLE ; TBL: .WORD DOL,DOT,RUN,ABORT,EXIT ; ABORT: CMP BUF,#"AB ;MAKE SURE IT'S ABORT BNE 5$ ;IF NOT - ASSUME MCR CMPB BUF+2,#'O BEQ 6$ 5$: JMP MCR 6$: MOV #BUF+3,R0 ;SET BUFFER POINTER MOVB IOSTAT+1,R1 ;GET NUMBER OF BYTES SUB #3,R1 10$: CMPB #' ,(R0)+ ;SCAN FOR BLANK BEQ 20$ SOB R1,10$ MOV #SYNERR,MSG ;SET UP SYNTAX ERROR MESSAGE MOV #NSYNER,NMSG DIR$ #QIOW ;AND PRINT IT JMP READ ;AND TRY AGAIN 20$: MOV #1,R1 ;SET PERIOD ACCEPT FLAG JSR PC,$CAT5 ;CONVERT TO RAD50 MOV R1,NAME ;SAVE 1ST WORD BCC 30$ ;ANY ERRORS? CLR NAME+2 ;IF SO, CLEAR 2ND WORD BR 40$ ;WE'RE DONE 30$: JSR PC,$CAT5 ;CONVERT 2ND WORD MOV R1,NAME+2 ;AND SAVE IT 40$: MOV #TNAMES,R0 ;TABLE OF TASKNAMES MOV #,R1 ;MAX NUMBER OF TDB'S 50$: CMP NAME,(R0)+ ;COMPARE AGAINST NAMES BEQ 60$ ;BR ON MATCH ADD #2,R0 ;INCREMENT R0 BR 70$ 60$: CMP NAME+2,(R0)+ ;CHECK 2ND WORD BEQ 80$ ;GOT IT! 70$: SOB R1,50$ MOV #NOTASK,MSG ;SET UP NO SUCH TASK MESSAGE MOV #NNOTSK,NMSG DIR$ #QIOW ;AND PRINT IT JMP READ ;AND TRY AGAIN 80$: DEC R1 ;CONVERT TO TABLE OFFSET ASL R1 ABRT$T TDBS(R1) ;ABORT THE TASK BCC 90$ ;NO ERRORS SHOULD OCCUR, BUT CHECK ANYWAYS MOV #ABMSG,MSG ;SET UP ABORT ERROR MESSAGE MOV #NABMSG,NMSG DIR$ #QIOW ;AND PRINT IT JMP READ ;AND TRY AGAIN 90$: TDBR$T TDBS(R1) ;RELEASE THE TDB MOV #NTDB,R2 ;POINT TO TASKNAME SUB R1,R2 SUB #2,R2 ASL R2 CLR TNAMES(R2) ;CLEAR THE TASKNAME CLR TNAMES+2(R2) DEC NTASK MOV #TSKABO,MSG ;SET UP TASK ABORTED MESSAGE MOV #NTSKAB,NMSG DIR$ #QIOW ;AND PRINT IT JMP READ ; RUN: CMP BUF,#"RU ;MAKE SURE IT'S RUN BNE MCR ;IF NOT - ASSUME MCR COMMAND CMP BUF+2,#"N BNE MCR JSR PC,GETTDB ;GET A TDB BCC 5$ JMP NOTDB 5$: SUB #3,IOSTAT+2 RUN$T ,#BUF+3,IOSTAT+2,#TS.INS ;ASSUME INSTALLED TASK BCS 16$ ;IF ERROR, GO TRY FILENAME INC NTASK MOV #BUF+4,R0 MOV #1,R1 JSR PC,$CAT5 MOV R1,(R5) BCC 10$ CLR 2(R5) JMP WAIT 10$: JSR PC,$CAT5 MOV R1,2(R5) JMP WAIT ; 16$: RUN$T ,#BUF+3,IOSTAT+2,#TS.USE ; ASSUME IT'S A FILENAME BCC 15$ JMP RUNERR 15$: INC NTASK MOV #BUF+4,R2 ;SCAN FOR DEVICE MOV #4,R3 20$: CMPB #':,(R2)+ BEQ 30$ SOB R3,20$ MOV IOSTAT+2,R3 ;SAVE ORIGIN POINTERS MOV #BUF+4,R2 30$: SUB #4,IOSTAT+2 ;SCAN FOR UIC DEC R3 ADD R3,IOSTAT+2 MOV IOSTAT+2,R3 40$: CMPB #'],(R2)+ BEQ 50$ SOB R3,40$ MOV #BUF+4,R0 BR 60$ 50$: MOV R2,R0 60$: CLR R1 JSR PC,$CAT5 MOV R1,(R5) ;SAVE TASK NAME BCC 70$ CLR 2(R5) JMP WAIT 70$: JSR PC,$CAT5 MOV R1,2(R5) BR WAIT ; MCR: JSR PC,GETTDB ;GET A TDB BCC 5$ JMP NOTDB 5$: MOV #BUF,R1 ;R1 POINTS TO COMMAND DOT: RUN$T ,R1,IOSTAT+2,#TS.DOT ;RUN ... TYPE MCR COMMAND BCC 5$ CMP #BUF,R1 ;... TYPE TASK SPECIFICALLY REQUESTED? BEQ DOL ;IF NOT, GO TRY $$$ TYPE JMP RUNERR 5$: INC NTASK MOV DOTS,(R5) ;SAVE TASK NAME MOV R1,R0 JSR PC,$CAT5 MOV R1,2(R5) BR WAIT ; DOL: RUN$T ,R1,IOSTAT+2,#TS.DOL ;RUN $$$ TYPE MCR COMMAND BCC 5$ JMP RUNERR 5$: INC NTASK MOV DOLS,(R5) ;SAVE TASK NAME MOV R1,R0 JSR PC,$CAT5 MOV R1,2(R5) BR WAIT ; RUNERR: MOV R0,R3 CLR R2 DIV #,R2 DEC R2 ;CONVERT TO BYTE OFFSET ASL R2 ASL R2 CLR TNAMES(R2) ;CLEAR THE TASKNAME CLR TNAMES+2(R2) MOV T.TESB(R0),R1 ;GET THE ERROR NUMBER MOV 2(R1),R1 BIS #177400,R1 ;EXTEND SIGN BIT TDBR$T ;RELEASE THE TDB MOV #RUNMSG+12,R0 ;POINT TO BUFFER CLR R2 ;SUPPRESS ZEROS JSR PC,$CBDSG ;CONVERT IT MOV #RUNMSG,MSG ;SET UP ERROR MESSAGE MOV #NRNMSG,NMSG DIR$ #QIOW ;AND PRINT IT JMP READ ;AND TRY AGAIN ; GETTDB: MOV #TNAMES,R5 ;USE R5 FOR NAMELIST POINTER MOV #,R1 ;AND SIZE OF LIST 10$: TST (R5) ;TASK ACTIVE FOR THIS TDB? BEQ 20$ ;NO, GO USE THIS ONE ADD #4,R5 ;STEP POINTER SOB R1,10$ ;AND GO TRY THE NEXT ONE SEC ;NO MORE TDB'S - SET CARRY BR 30$ 20$: DEC R1 ;CONVERT R1 TO OFFSET INTO ASL R1 ;TDB TABLE MOV TDBS(R1),R0 ;R0 POINTS TO TDB TDBD$T ;DECLARE IT 30$: RTS PC ; NOTDB: MOV #TDBMSG,MSG ;SET UP NO TDB MESSAGE MOV #NTDBMG,NMSG DIR$ #QIOW ;AND PRINT IT JMP READ ;AND TRY AGAIN ; WAIT: CKEV$T WAIT,<#TDB1,#TDB2,#TDB3,#TDB4,#TDB5>,WAIT TST R0 ;CONTROL-C? BNE 10$ ;NOPE CLR EXFLAG ;CLEAR EXIT FLAG JMP READ ;AND GO SEE WHAT HE WANTS 10$: RDEV$T BITB #IF.JS!IF.JA!IF.NL!IF.CH,T.EVNT(R0) BEQ WAIT BITB #IF.JA,T.EVNT(R0) BEQ 20$ MOV #TSKABO,MSG ;SET UP TASK ABORTED MESSAGE MOV #NTSKAB-2,NMSG DIR$ #QIOW ;AND PRINT IT BR 30$ 20$: BITB #IF.NL,T.EVNT(R0) BEQ 30$ MOV #LDERR,MSG ;SET UP LOAD ERROR MESSAGE MOV #NLDERR,NMSG DIR$ #QIOW ;AND PRINT IT 30$: MOV R0,R3 CLR R2 DIV #,R2 DEC R2 ;CONVERT TO BYTE OFFSET ASL R2 ASL R2 CLR TNAMES(R2) ;CLEAR THE TASKNAME CLR TNAMES+2(R2) TDBR$T ;RELEASE THE TDB DEC NTASK ;DECREMENT TASK COUNT BGT WAIT TST EXFLAG BNE DONE JMP READ ; EXIT: CMP #"EX,BUF ;MAKE SURE IT'S AN EXIT REQUEST BEQ 10$ JMP MCR ;IF NOT, ASSUME AN MCR-TYPE COMMAND 10$: TST NTASK ;ANY TASKS ACTIVE? BEQ DONE ;IF NOT, JUST EXIT MOV #BUF+2,R0 ;POINT TO BUFFER MOV IOSTAT+2,R1 ;GET NUMBER OF CHARACTERS SUB #2,R1 ;SKIP OVER 'EX' BEQ 30$ ;IF ZERO, THERE'S NO SWITCH 20$: CMPB #'/,(R0)+ ;SCAN FOR SWITCH BEQ 40$ SOB R1,20$ 30$: DIR$ #EXQIO ;MAKE SURE HE WANTS TO EXIT CMPB #'Y,BUF ;IS IT YES? BEQ DONE ;THEN EXIT JMP READ 40$: MOV #ABO,R1 ;MAKE SURE SWITCH IS 'ABO' MOV #3,R2 50$: CMPB (R0)+,(R1)+ BNE 30$ SOB R2,50$ DONE: CTC$T RELINQ ;RELINQUISH CONTROL-C EXIT$S EXQIO: QIOW$ IO.RPR,1,1,,,, EXMSG: .ASCII /EXIT WILL ABORT CURRENTLY ACTIVE TASKS/<12><15> .ASCII $DO YOU WISH TO EXIT (Y/N) ? $ .EVEN ABO: .ASCII /ABO/ .EVEN ; RDCMD: QIOW$ IO.RPR,1,1,,IOSTAT,, PRMT: .ASCII <12>/TSMCR>/ .EVEN BUF: .BLKW 40. IOSTAT: .BLKW 2 ; CMDCHR: .ASCII /EAR.$/ NCMD=.-CMDCHR .EVEN DOTS: .RAD50 /.../ DOLS: .RAD50 /$$$/ NTASK: .WORD 0 ;NUMBER OF ACTIVE TASKS EXFLAG: .WORD 0 QIOW: QIOW$ IO.WLB,1,1,,,,<0,0,40> MSG=QIOW+Q.IOPL NMSG=QIOW+Q.IOPL+2 NOTASK: .ASCII /NO SUCH TASK/ NNOTSK=.-NOTASK .EVEN ABMSG: .ASCII /ABORT ERROR/ NABMSG=.-ABMSG .EVEN TSKABO: .ASCII /TASK ABORTED/ NTSKAB=.-TSKABO .EVEN LDERR: .ASCII /LOAD ERROR/ NLDERR=.-LDERR .EVEN SYNERR: .ASCII /SYNTAX ERROR/ NSYNER=.-SYNERR .EVEN RUNMSG: .ASCII /RUN ERROR - / NRNMSG=.-RUNMSG .EVEN TDBMSG: .ASCII /NO MORE TDB'S/ NTDBMG=.-TDBMSG .EVEN ; .END START