.TITLE STF .MCALL GMCR$,EXIT$S,CMOV$2 .MCALL MRKT$S,WTSE$S .MCALL TINIT,PSTR,PCRLF,TTYOUT .MCALL QIOW$,ENTER,LEAVE,ALUN$ ; ;+ ; STF - PROGRAM TO ALLOW THE INITIATION OF AN MCR ; COMMAND LINE AT ANY TERMINAL, FROM THE ISSUING ; TERMINAL. THAT IS, TO STUFF AN MCR COMMAND TO ANY ; TERMINAL. THE ISSUING TERMINAL MUST BE ; PRIVILEGED. ; ;- ; ;WK001 ; MODIFIED: ;WK001 ; ;WK001 ; WK001 W. KORENDYK 01-JUL-78 ;WK001 ; MODIFIED TO CORRECT ERROR IN OUTPUT TO THE ;WK001 ; DEVICE OF THE LINE WHICH WAS STUFFED. ;WK001 ; ;WK001 SPAC=40 ESC=33 .SBTTL MAIN START: TINIT 5,23 ;INIT TTYOUT. ; MOV $TKTCB,R4 ;GET TCB POINTR. MOV T.UCB(R4),R5 ;AND THEN UCB POINTER. ; BIT #U2.PRV,U.CW2(R5) ;IS THIS TERM PRIV? BNE 1$ ;YES, WE'RE COOL BR ERR1 ;NO, ERROR ; ; 1$: DIR$ #GMCR,DIRERR ;GET OUR COMMAND. MOV #GMCR+G.MCRB,R0 MOV $DSW,R1 ;AND GET THE LENGTH. INC R1 ;INCLUDE TERMINATOR CLRB ECHO ;INDICATE ECHO CMPB #ESC,GMCR+G.MCRB-1(R1) ;TERMINATOR AN ESC? BNE 2$ ;NO, SO ECHO INCB ECHO ;JA, NO ECHO 2$: DEC R1 ; BEQ ERR2 ;NO COMMAND GIVEN CMPB #SPAC,(R0)+ ;FIND NEXT NON BLANK BNE 2$ ; ; NOW HAVE R0 POINTING TO THE STF COMMAND ; R1 HOLDS THE LENGTH. ; CALL DEVICE ;EXTRACT DEVICE TO STUFF TO. BCS ERR4 ;HAD TROUBLE.. CALL LINE ;EXTRACT THE COMMAND TO STUFF. BCS ERR3 ;HAD TROUBLE.. ; ; ;WITH THE COMMAND TO STUFF AT 'COM' AND THE DEVICE AT 'DEV', ;AND COUNT WITH THE NUMBER OF DEVICES TO DO... LET'S DO IT. ; 11$: MOV #5,WTTST ;INIT WAIT COUNT CALL STUFF ;STUFF 'COM'. DEC COUNT BEQ 12$ ;WE'RE DONE MOV PTR,R2 ;IF NOT, THEN SET UP MOV (R2)+,DEV+2 ; FOR THE NEXT DEVICE. MOV R2,PTR ;(REMEM THE POINTER) BR 11$ ; ; 12$: DIE:: EXIT$S ; .SBTTL ERROR PROCESSING (MAIN) ; ; THE ERROR PROCESSING PORTION OF THE ; MAIN PROGRAM... ; ERR4: INC ERR ERR3: INC ERR ERR2: INC ERR ERR1: MOV ERR,R0 ;PUT INTO BASE. ASL R0 ;MAKE INTO DISPLACEMENT ASL R0 CALL ERRPFX ;LET OUT THE ERROR PREFIX TTYOUT ERRTAB(R0),ERRTAB+2(R0) PCRLF JMP DIE ; ; ERRTAB: .WORD ER1,LER1 .WORD ER2,LER2 .WORD ER3,LER3 .WORD ER4,LER4 .NLIST BEX ; ER1: .ASCII /PRIVILEGED COMMAND/ LER1 =.-ER1 ER2: .ASCII /MISSING COMMAND/ LER2 =.-ER2 ER3: .ASCII /MISSING OR INVALID COMMAND/ LER3 =.-ER3 ER4: .ASCII /MISSING OR INVALID DEVICE/ LER4 =.-ER4 .LIST BEX .SBTTL DEVICE STRING EXTRACTION ; ; DEVICE - ROUTINE TO EXTRACT THE DEVICE NAME FROM ; THE STF COMMAND LINE. ; ; INPUTS: R0 = START OF COMMAND STRING. ; R1 = LENGTH OF COMMAND STRING. ; ; OUTPUTS: R0 = UPDATED PAST DEVICE SUBSTRING ; R1 = REMAINING LENGTH OF STRING. ; ; DEVICE: MOV #DEV,R3 ;WHERE TO PUT IT. MOV #5,R2 ;ITS ABSOLUTE MAX SIZE. 1$: DEC R2 BLT 100$ ;IT'S TOO LONG A DEV SPEC. DEC R1 BEQ 100$ ;NOT ENOUGH COMMAND STRING MOVB (R0)+,(R3) ;MOVE IN THE CHAR. CMPB #':,(R3)+ ;A COLON? BNE 1$ ;NO, GO FOR MORE. ; ; WITH DEVICE IN HAND, RUN A SIMPLE TEST: "ALL"? ; MOV #1,COUNT ;DEFAULT TO 1 TERMINAL MOV #DEV,R3 ;POINT TO SUBSTRING. CMPB #'A,(R3)+ ;A BNE 2$ ;NO... CMPB #'L,(R3)+ ;L BNE 2$ ;NO... CMPB #'L,(R3)+ ;L BNE 2$ ;NO... MOV #MAXTER,COUNT ;NUM OF TERMINALS. MOV PTR,R2 MOV (R2)+,DEV+2 MOV R2,PTR ; 2$: CLC BR 110$ 100$: SEC 110$: RETURN .SBTTL COMMAND LINE EXTRACTION ; ; LINE - ROUTINE TO EXTRACT THE COMMAND TO BE STUFFED ; FROM THE STF COMMAND LINE. ; ; INPUTS: R0 = START OF COMMAND LINE (LESS DEVICE) ; R1 = LENGTH ; LINE: MOV #COM,R2 ;WHERE TO PUT IT 1$: CMPB #SPAC,(R0) ;A LEADING SPACE? BNE 2$ ;NO, CONTINUE DEC R1 BEQ 100$ ;NO COMMAND!!?? INC R0 ;JUMP IT. BR 1$ ;AND TRY AGAIN 2$: MOVB (R0)+,(R2)+ ;TRAN STRING SOB R1,2$ 120$: CLC ;INDICATE SUCCESS BR 110$ 100$: SEC ;INDICATE TROUBLE. 110$: RETURN .SBTTL STUFF THE COMMAND ; ; STUFF - THE ROUTINE WHICH ACTUALLY STUFFS THE COMMAND. ; ; INPUTS ARE ARE IN STORE...COM=. ; ; COM = COMMAND TO STUFF (SHOULD BE TERMINATED WITH A NULL) ; DEV = DEVICE TO STUFF TO. ; ; STUFF: MOV #DEV,R0 ;INIT FOR FDUCB MOV #PAA,R3 ;PARAM BLOCK (USUALLY EMPTY). CALL $FDUCB ;FIND UCB BCC 1$ ;FIND IT? TST R3 ;NO, BNE STFER1 ;DEVICE NOT IN SYSTEM. BR STFER2 ;SYNTAX. 1$: MOV R1,HOLD ;FOUND IT, SAVE IT. BIT #DV.TTY,U.CW1(R1) ;WAS IT A TERMINAL? BEQ STFER4 ;NO... CMP R1,R5 ;OURUCB? (WE SAVED OURS IN R5, REMEM?) BEQ END ;WE NEVER WANT TO STF TO OURSELVES. OK$: CALL PRINT ;MAYBE WE SHOULD ECHO? ; ; THE REMAINDER OF THIS PAGE DOES THE ACTUAL STUFF. ; WE SWITCH TO THE SYSTEM STACK, ; THUS INHIBITING TASK SWITCHING, AND THEN QUEUE AN MCR ; LINE (USING A BIT OF POOL), WITH THE DESIRED TERMINAL UCB. ; ; THE RETURN AT 59$ CAUSES THE STACKS TO SWITCH BACK, AND CONTROL ; TO PROCEED AT 60$. ; ; MOV #60$,R5 ; CALL $SWSTK ;SWITCH TO SYSTEM STACK EMT 376 .WORD 60$ MOV #84.,R1 ;GET BUFFER OF SIZE 84. CALL $ALOCB ; OUT OF POOL BCC 6$ ;WE GOT IT. BIS #40,FLAGS ;WE DIDN'T, SIGNAL ERROR BR 59$ ; AND GET OUR TASK STACK BACK 6$: BIC #40,FLAGS ;MAKE SURE WE KNOW WE GOT IT. MOV R0,R1 ;AND COPY THE ADDRESS. MOV #COM,R2 ;GET THE COMMAND LINE CLR (R0)+ ;CLEAR THE LINK WORD. MOV HOLD,(R0)+ ;MOV IN THAT UCB POINTER. 5$: MOVB (R2)+,(R0)+ ;TRANSFER THE COMMAND BNE 5$ CALL $QMCRL ;AND Q TO MCR 59$: RETURN ;SWITCH BACK STACKS ; 60$: BITB #40,FLAGS ;DID WE GET THE BUFFER? BEQ END ;WE DID IT!! CALL WAIT ;AHH. WELL WAIT. BCC OK$ ;TRY AGAIN. BR STFER3 ;WAITED ONCE TO OFTEN. END: RETURN ;BACK TO MAIN. .SBTTL ERROR PROCESSING (STUFF) ; ; ERROR PROCESSING FOR LITTLE MISHAPS IN THE ; STUFFING OF THE COMMAND. ; STFER4: CMOV$2 DEV,SER4 ;INCLUDE THE DEVICE... INC ERR STFER3: INC ERR STFER2: INC ERR STFER1: MOV ERR,R0 ASL R0 ASL R0 CALL ERRPFX ;LET OUT THE ERROR PREFIX TTYOUT STFTAB(R0),STFTAB+2(R0) PCRLF JMP DIE ; ; .NLIST BEX STFTAB: .WORD LSER1,SER1 .WORD LSER2,SER2 .WORD LSER3,SER3 .WORD LSER4,SER4 ; ; SER1: .ASCII /DEVICE NOT IN SYSTEM/ LSER1 =.-SER1 SER2: .ASCII /SYNTAX ERROR/ LSER2 =.-SER2 SER3: .ASCII /INSUFFICIENT POOL/ LSER3 =.-SER3 SER4: .ASCII /TT17: NOT A TERMINAL DEVICE/ LSER4 =.-SER4 .EVEN .LIST BEX .SBTTL ECHO THE COMMAND ; ; PRINT - ROUTINE TO ECHO THE COMMAND ON THE TERMINAL. ; PRINT: TSTB ECHO BNE 1$ ;DON'T ECHO ENTER R0,R1,R2 ;SAVE SOME REGS MOV #DEV,R0 ;THE DEVICE NAME. MOV (R0)+,ABLK+A.LUNA ;INTO ALUN BLK. CLR R1 ;PREPARE TO GET NUMBER CLR SHIFT ;EMPTY THE PLACE SHIFTER ;WK001 CALL CNVRT ;GET IT. MOV R1,ABLK+A.LUNU ;MOVE IT IN DIR$ #ABLK,DIRERR ;ALUN TO DEVICE DIR$ #QIO,DIRERR ;WRITE TO TERMINAL LEAVE 1$: RETURN ; ; CNVRT DOES THE CONVERSION OF THE ASCII NUMBER STARTING ; AT R0 AND GOING UP TO THE FIRST COLON (:). ; CNVRT: MOVB (R0)+,R2 ;GET CHARACTER CMPB #':,R2 ;A COLON? (IE DONE?) BEQ 1$ ;YEP MOVB R2,-(SP) ;SAVE IT CALL CNVRT ;GET THE NEXT MOVB (SP)+,R2 ;GET IT BACK SUB #60,R2 ;MAKE IT BINARY ASH SHIFT,R2 ;SHIFT TO RIGHT OCTAL POSITION ;WK001 ADD R2,R1 ;ACCUMULATE TOTAL ;WK001 ADD #3,SHIFT ;NEXT TIME, NEXT POSITION ;WK001 1$: RETURN ;WK001 ; ;WK001 ; ;WK001 ; ;WK001 SHIFT: .WORD 0 ;OCTAL DIGIT POSITIONER. ;WK001 ; ;**-3 LUN=4 QIO: QIOW$ IO.WBT,LUN,5,,,, ABLK: ALUN$ LUN,TT,0 .SBTTL WAIT FOR POOL SPACE ; ; WAIT - ROUTINE WHICH WILL MARK SOME TIME IF THERE ; WAS NOT ENOUGH POOL SPACE LYING AROUND. RETURNS AN ; ERROR IF IT HAS TO WAIT TO MANY TIMES. ; WAIT: DEC WTTST ;ONE LESS WAIT. BEQ 100$ ;WE'VE BEEN HERE TOO OFTEN MRKT$S #5,#2,#2 ;WAIT A COUPLE SECONDS. WTSE$S #5 CLC ;SUCCESS?? BR 110$ 100$: SEC 110$: RETURN ; WTTST: .WORD 5. .NLIST BEX .SBTTL LEFT OVER STORE ; ; WHATEVER ELSE WE NEED GOES HERE. ; GMCR: GMCR$ ; ERRPFX::PSTR ^*/STF -- /* RETURN ; PAA: .BLKW 2 ; PTR: .WORD TERTAB ;ADDR. OF TERMINAL TABLE ; TERTAB: .ASCII /00/ .ASCII /01/ .ASCII /02/ .ASCII /03/ .ASCII /04/ .ASCII /05/ .ASCII /06/ .ASCII /07/ .ASCII /10/ .ASCII /11/ .ASCII /12/ .ASCII /13/ MAXTER=.-TERTAB/2-1 ;(-1 SINCE FIRST IS ALREADY DONE) ; COUNT: .WORD MAXTER ; ; DEV: .ASCII /TT00:/ COM: .BLKB 80. ; .EVEN ; ECHO: .BYTE 0 .EVEN HOLD: .WORD 0 ERR: .WORD 0 FLAGS: .WORD 0 .LIST BEX .END START