.TITLE TSMCR ; ; TSMCR (Time-shared MCR) ; ; TSMCR is a pseudo-CLI task that allows several time-shared tasks (currently ; up to 5) to be run simultaneously at an IAS terminal. TSMCR will take con- ; trol-C response away from PDS and function similiarly to the RSX-11D MCR, ; except that it will be subject to the constraints of the IAS time-sharing ; control primitives (TCP). However, TSMCR adheres to the MCR commnad syntax ; rather than the PDS syntax. The primary difference between TSMCR and MCR ; mode of IAS 3.0 is that under MCR mode all tasks except the last are sus- ; pended, while under TSMCR all tasks are concurrently active. ; ; 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, unless ; no more tasks are active, in which case TSMCR will return control to PDS ; and exit. ; ; TSMCR accepts four types of inputs: MCR/PDS type commands (except MOUNT), ; RUN commands, the ABORT command and the EXIT command. All MOUNT requests ; must be issued from PDS. TSMCR will reject all MOUNT requests with a warn- ; ing message. ; ; 1. MCR/PDS type commands: TSMCR>[C]XXX [Command line] ; If the optional character C is omitted, an attempt will be made to exe- ; cute 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 such 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 on- ; ly a MCR-type task or PDS-type task respectively. ; ; 2. 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 filen- ; ame. ; ; 3. ABORT command: TSMCR>ABO[RT] 'Taskname' ; The specified task 'taskname', if initiated by TSMCR, will be aborted. ; ; 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 wait- ; ing for a task event. It will stay there until one of the active ; task exits, aborts or causes a similar task event. This bug has ; been fixed in IAS 3.0. ; ; 4. EXIT command: TSMCR>EX[IT][/ABO] ; TSMCR will exit and return control to PDS. If any tasks are still ac- ; tive, 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 al- ; low at least 7 tasks (see the SCI commands DEALLOCATE and ALLOCATE in the ; System Manager's 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. ; ; WRITTEN APRIL 1978 R. FRENCH THE BOEING COMPANY ; +001 JUNE 1978 R. FRENCH MODIFIED FOR IAS 3.0 ; ; LINK FILE ; ; LINK/OPT TSMCR ; ASG=TI:1 ; UNITS=1 ; STACK=32 ; / ; ; +001 DEFINE THE FOLLOWING SYMBOL FOR IAS VERSION 3.0. COMMENT IT OUT ; FOR EARLIER VERSIONS OF IAS. IASV3=1 ;+001 CONDITIONAL FLAG FOR IAS 3.0 ; .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$ CMP BUF,#"MO ;MOUNT COMMAND? BNE 15$ ;BRANCH IF NOT CMPB BUF+2,#'U ;ARE WE SURE? BNE 15$ MOV #MOUERR,MSG ;SET UP MOUNT WARNING MESSAGE MOV #NMOUER,NMSG DIR$ #QIOW ;AND PRINT IT BR READ ;AND TRY AGAIN ; 15$: MOV #BUF,R0 ;START OF BUFFER IN R0 MOVB IOSTAT+1,R1 ;NUMBER OF BYTES IN R1 16$: CMPB #'/,(R0) ;CHECK FOR NO TASK NAME BNE 17$ ;BRANCH IF OK (MAYBE) MOV #SYNERR,MSG ;SET UP SYNTAX ERROR MESSAGE MOV #NSYNER,NMSG DIR$ #QIOW ;AND PRINT IT BR READ ;AND TRY AGAIN 17$: CMPB #' ,(R0)+ ;HOW ABOUT A BLANK? BNE 18$ ;NOW WE'RE OK SOB R1,16$ ; 18$: JMP MCR ;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 ; .IF DF,IASV3 ;+001 WAIT: CKEV$T TERM,<#TDB1,#TDB2,#TDB3,#TDB4,#TDB5>,WAIT ;+001 .IFF ;+001 WAIT: CKEV$T WAIT,<#TDB1,#TDB2,#TDB3,#TDB4,#TDB5>,WAIT .ENDC ;+001 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 MOUERR: .ASCII /WARNING - MOUNT DEVICES ONLY FROM PDS/ NMOUER=.-MOUERR .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