.TITLE Force ; PROGRAM FRC Force input to another terminal ; written by: Frank Penner ; October 1983 ; for RSX-11M-PLUS I/D space systems only. ; this program will take the typed string and make it ; seem as if it were typed on the target terminal ; to use, type: ; FRC TT5:string ; where TT5: is the target terminal and string is the data .MCALL QIOW$,EXIT$S,DIR$,ALUN$ .MCALL TCBDF$,CALL,RETURN,GMCR$ .MCALL DCBDF$,F11DF$,HDRDF$,HWDDF$,PCBDF$,UCBDF$ .MCALL FHDOF$ DCBDF$ ;DEFINE DCB OFFSETS HDRDF$ ;DEFINE TASK HEADER OFFSETS HWDDF$ ;DEFINE HARDWARE OFFSETS PCBDF$ ;DEFINE PCB OFFSETS UCBDF$ ,,TTDEF ;DEFINE UCB OFFSETS GMCR: GMCR$ DEVNAM =GMCR+G.MCRB+4 ;START OF TYPED INPUT DEVICE NAME IOST: .BLKW 2 ;I/O STATUS BLOCK QIODPB: QIOW$ IO.WLB,TLUN,TEFL,,IOST,,<,,VFC> TLUN= 5 TEFL= 2 VFC= 40 LUN: ALUN$ FLUN,0,0 FLUN= 1 SAVEM0: .WORD 0 ERR: .WORD 0 NOPRIM: .ASCII /FRC -- no privilege for attempted operation/ NOPRIS=.-NOPRIM NODRVM: .ASCII /FRC -- can't find TT: driver or TTCOM/ NODRVS=.-NODRVM NOCMDM: .ASCII /FRC -- no command line/ NOCMDS=.-NOCMDM BADEVM: .ASCII /FRC -- bad device name/ BADEVS=.-BADEVM NOTTM: .ASCII /FRC -- device not a terminal/ NOTTS=.-NOTTM NOPOOM: .ASCII /FRC -- no ICB pool for code/ NOPOOS=.-NOPOOM .EVEN BEGIN: ;start of code for low core MOV @#KINAR5,-(SP) ;save aprs MOV @#KINAR6,-(SP) MOV @#KDSAR5,-(SP) MOV @#KDSAR6,-(SP) TTDRV5: MOV #0,@#KINAR5 ;remap to TTDRV TTDRV6: MOV #0,@#KINAR6 ;8K TTCOM: MOV #0,@#KDSAR6 ;and TTCOM CALL @#ICHAR1 ;call terminal driver routine TST @#$TTUQ ;;;ANYTHING IN UCB QUEUE? BEQ 20$ ;;;N - RETURN MOV #$TTFB+2,R4 ;;;POINT TO PC IN FORK BLOCK TST (R4)+ ;;;FORK BLOCK ALREADY IN QUEUE? BNE 20$ ;;;Y - RETURN MOV #20$-BEGIN,-(SP) ;;;push our return address ADD R0,(SP) ;;;relocate return address MOV #FP000,-(SP) ;;;push terminal driver fork PC address JMP @#$FORK0 ;;;QUEUE FORK BLOCK 20$: MOV (SP)+,@#KDSAR6 ;restore aprs MOV (SP)+,@#KDSAR5 MOV (SP)+,@#KINAR6 MOV (SP)+,@#KINAR5 RTS PC END: ;end of code for APR 0 START: MOV $TKTCB,R3 ;PUT OUR TCB ADDRESS IN R3 MOV T.UCB(R3),R3 ;PUT OUR TI: UCB ADD IN R3 BIT #U2.PRV,U.CW2(R3) ;is terminal privileged? BNE .+6 ;if not equal yes, so OK JMP NOPRIV ;if equal no, so exit with message ;SEARCH PARTITION LIST FOR DRVPAR MOV $PARHD,R0 ;POINT TO FIRST PCB IN LIST 10$: CMP P.NAM(R0),#^RDRV ;FIRST HALF OF NAME MATCH ? BNE 20$ ;IF NE NO CMP P.NAM+2(R0),#^RPAR ;SECOND HALF OF NAME MATCH ? BEQ 30$ ;IF EQUALS YES 20$: MOV P.LNK(R0),R0 ;GET LINK TO NEXT PCB TST R0 ;NULL LINK? BNE 10$ ;IF NOT EQUALS NO JMP NODRV ;CAN'T FIND DRVPAR SO GIVE UP 30$: ;FOUND IT MOV R0,R1 ;remember DRVPAR par PCB address MOV P.SUB(R0),R0 ;POINT TO NEXT SUBPARTITION TST R0 ;NULL LINK? BNE 40$ ;no, keep going JMP NODRV ;YES, GIVE UP 40$: CMP P.NAM(R0),#^RTTC ;FIRST HALF OF SUB PAR NAME MATCH BNE 30$ ;NO MATCH, GET NEXT SUB PARTITION CMP P.NAM+2(R0),#^ROM ;SECOND HALF OF SUB PAR NAME MATCH BNE 30$ ;NO MATCH, GET NEXT SUB PAR ; ; ITS A MATCH! MOV P.REL(R0),TTCOM+2 ;PUT PHYSICAL ADDRES OF TTCOM IN ;code to load into low core MOV R1,R0 ;put DRVPAR PCB address back into R0 31$: MOV P.SUB(R0),R0 ;POINT TO NEXT SUBPARTITION TST R0 ;NULL LINK? BNE 32$ ;no, keep looking JMP NODRV ;YES, GIVE UP 32$: BIT #PS.COM,P.STAT(R0) ;common PCB? BEQ 31$ ;NO MATCH, GET NEXT SUB PARTITION CMP P.ST2(R0),#P2.DRV ;driver? BNE 31$ ;NO MATCH, GET NEXT SUB PAR MOV P.OWN(R0),R3 ;put address of DCB in R3 CMP #"TT,D.NAM(R3) ;DCB for TT:? BNE 31$ ;no, next please ; ITS A MATCH! MOV P.REL(R0),R2 ;PUT PHYSICAL ADDRES OF TT: IN R2 MOV R2,TTDRV5+2 ;put in code for lowcr ADD #200,R2 ;next APR MOV R2,TTDRV6+2 ;put in code for lowcr DIR$ #GMCR ;PICK UP COMMAND LINE BCC .+6 ;C CLEAR IS SUCESS JMP NOCMD ;GET COMMAND LINE ERROR MOV #DEVNAM,R0 ;PUT ADDRESS OF TYPED INPUT IN R0 MOV (R0)+,LUN+A.LUNA ;PUT TYPE ASCII DEV NAME IN ATT LUN DPB CALL $COTB ;CONVERT ASCII NUM IN R0 BUF ADD TO BIN CMPB #':,R2 ;DEVICE SPEC TERMINATED BY : ? BEQ .+6 ;YES SO PROCEED JMP BADDEV ;NO, SO ERROR MOV R0,R4 ;save R0, pointer to next char MOV R1,LUN+A.LUNU ;PUT BINARY DEV UNIT IN ASSIGN LUN DPB DIR$ #LUN ;DO ASSIGN LUN DIRECTIVE BCC .+6 ;C CLEAR MEANS DEVICE IS IN SYSTEM JMP BADDEV ;C SET MEANS ERROR MOVB #1,$CXDBL ;DISABLE CONTEXT SWITCHING MOV @#UISAR6,SAVEM0 ;SAVE MEMORY MANAGEMENT REGISTERS MOV @#UISDR4,@#UISDR6 ;make 6 look like 4 MOV $SAHDB,@#UISAR6 ;map task header MOV $SAHPT,R0 ;GET OUR HEADER ADDRESS MOV H.LUN(R0),R5 ;SINCE ASS LUN, 1ST ADD IN LUT IS UCB MOV SAVEM0,@#UISAR6 ;RESTORE MEMORY MANAGEMENT REGISTERS CLRB $CXDBL ;RENABLE CONTEXT SWITCHING BIT #DV.TTY,U.CW1(R5) ;is UCB a terminal? BNE .+6 ;not equal, YES, SO CONTINUE JMP NOTERM ;NO, SO ERROR ADD #U.TSTA,R5 ;make R5 point in UCB CALL $SWSTK,100$ ;system state MOV #END-BEGIN,R1 ;;size of code to load in bytes MOV #$ICAVL-2,R0 ;;listhead for ICB pool CALL $ALOC1 ;;allocate BCS 6$ ;;c-set failure MOV R0,R3 ;;address of place to move it to MOV #BEGIN,R2 ;;address of stuff to move ASR R1 ;;divide by 2==> bytes to words 1$: MOV (R2)+,(R3)+ ;;move it word at a time SOB R1,1$ ;;all of it MOV R4,R1 ;;recall address of next char to proc 2$: MOVB (R1),R2 ;;next char BIC #177400,R2 ;;clear top bits CMPB #33,R2 ;;is next char an ESC?? BEQ 4$ ;;yes, so quit & don't force to target CMPB #'^,R2 ;;is next char an uparrow (^) ?? BNE 3$ ;;no so treat normally TSTB (R1)+ ;;skip to next guy MOVB (R1),R2 ;;get next character after uparrow BIC #177400,R2 ;;clear top bits CMPB #'^,R2 ;;is next char an uparrow (^) ?? BEQ 3$ ;;yes so treat normally (2 ^^ in row) BIC #177700,R2 ;;clear out 100 bit, so control char 3$: MTPS #240 ;;disable ints, prior 5 JSR PC,(R0) ;;call routine MTPS #0 ;;reenable CMPB #15,(R1) ;;check for end of command line (cr) BEQ 4$ ;;more to do? TSTB (R1)+ ;;check for end of command line (null) BEQ 4$ ;;more to do? BR 2$ ;;keep going 4$: MOV #END-BEGIN,R1 ;;size of code to dealloc in bytes MOV #$ICAVL-2,R3 ;;listhead for ICB pool CALL $DEAC1 ;;deallocate 5$: RETURN ;;end of SWSTK code, return to 100$ 6$: MOV #1,ERR ;;signal error BR 5$ ;;go back to user state 100$: ;come here after after SWSTK code TST ERR ;error in system state code? BNE NOPOOL ;if not equal error, no pool message EXIT: EXIT$S NOPRIV: MOV #NOPRIM,QIODPB+Q.IOPL ;address of message into DPB MOV #NOPRIS,QIODPB+Q.IOPL+2 ;size of message BR ERRCOM ;goto common code NODRV: MOV #NODRVM,QIODPB+Q.IOPL ;address of message into DPB MOV #NODRVS,QIODPB+Q.IOPL+2 ;size of message BR ERRCOM ;goto common code NOCMD: MOV #NOCMDM,QIODPB+Q.IOPL ;address of message into DPB MOV #NOCMDS,QIODPB+Q.IOPL+2 ;size of message BR ERRCOM ;goto common code BADDEV: MOV #BADEVM,QIODPB+Q.IOPL ;address of message into DPB MOV #BADEVS,QIODPB+Q.IOPL+2 ;size of message BR ERRCOM ;goto common code NOTERM: MOV #NOTTM,QIODPB+Q.IOPL ;address of message into DPB MOV #NOTTS,QIODPB+Q.IOPL+2 ;size of message BR ERRCOM ;goto common code NOPOOL: MOV #NOPOOM,QIODPB+Q.IOPL ;address of message into DPB MOV #NOPOOS,QIODPB+Q.IOPL+2 ;size of message ERRCOM: ;common code DIR$ #QIODPB ;put out err message on TI: BR EXIT ;quit .END START