.ENABL LC .MCALL DIR$,QIOW$,ASTX$S,CLEF$S,STSE$S,SETF$S .MCALL STOP$S .PSECT LIBCUR LIBCUR:: TST (R5)+ MOV @(R5)+, R1 ADD #37, R1 MOVB R1, ROW MOV @(R5)+, R1 ADD #37, R1 MOVB R1, COL MOV #POS, TRMIO+Q.IOPL MOV #4, TRMIO+Q.IOPL+2 DIR$ #TRMIO RTS PC POS: .ASCII <33>/Y/ ROW: .BYTE 0 COL: .BYTE 0 .PSECT LIBPGE LIBPGE:: TST @R5 BEQ 1$ JSR PC, LIBCUR MOV #ESCR, TRMIO+Q.IOPL MOV #2, TRMIO+Q.IOPL+2 DIR$ #TRMIO RTS PC 1$: MOV #ERALL, TRMIO+Q.IOPL MOV #4, TRMIO+Q.IOPL+2 DIR$ #TRMIO RTS PC ERALL: .ASCII <33>/H/ ESCR: .ASCII <33>/J/ .PSECT LIBLIN LIBLIN:: TST @R5 BEQ 1$ JSR PC, LIBCUR 1$: MOV #ERRLIN, TRMIO+Q.IOPL MOV #2, TRMIO+Q.IOPL+2 DIR$ #TRMIO RTS PC ERRLIN: .ASCII <33>/K/ .PSECT STTRM STTRM:: JSR PC, STTRM1 JSR PC, MAPSET RTS PC STTRM1: DIR$ #ATT DIR$ #FIND 2$: CMPB BUFF+1, #T.V100 BNE 3$ MOV #VT52M, TRMIO+Q.IOPL MOV #5, TRMIO+Q.IOPL+2 DIR$ #TRMIO 3$: RTS PC VT52M: .ASCII <33>/[?2l/ .EVEN .PSECT TERMIO GETC:: CLRB GETTBL+1 DIR$ #TTYFLU GETC1: CMP KBSTPT, KBGTPT BNE 1$ CALL KBWAIT BR GETC1 1$: MOV @KBGTPT, R0 INC KBGTPT RTS PC ; ;01.09 ; Check for async input. ;01.09 ; ;01.09 KBDCHK:: ; Look for async CTRL/E.;01.09 MOV R0,-(SP) ; Save R0 ;01.09 MOV R4,-(SP) ; Save R4 ;01.09 MOV #KBBUF,R4 ; Point to buffer start ;01.09 MOV KBGTPT,R0 ; And to where we are ;01.09 MOV R4,KBGTPT ; Bottom is now at start;01.09 10$: CMP R0,KBSTPT ; At end yet? ;01.09 BEQ 20$ ; Yes, finish up. ;01.09 MOVB (R0)+,(R4)+ ; Copy the next byte ;01.09 BR 10$ ; Keep it going ;01.09 20$: MOV R4,KBSTPT ; New top-of-buffer ;01.09 DIR$ #TTYGET ; Get char count from KB;01.09 MOVB GETTBL+1,R0 ; Copy count into R0 ;01.09 BEQ 30$ ; No more input, exit. ;01.09 MOV R4,TTYKIN+Q.IOPL ; Point at free area ;01.10 MOV R0,TTYKIN+Q.IOPL+2 ; And how many to get ;01.09 ADD R4,R0 ; Add start to count ;01.09 CMP R0,#KBBUF+74. ; Will it all fit? ;01.09 BHI 30$ ; No, then don't do it. ;01.09 DIR$ #TTYKIN ; Get the input chars ;01.09 MOV R0,KBSTPT ; Store new end-of-buff ;01.09 30$: MOV (SP)+,R4 ; Restore (CHAR), ;01.09 MOV (SP)+,R0 ; Also TEMP ;01.09 RETURN ; And exit. ;01.09 ; ;01.09 ; Keyboard Input "wait" routine. Gets input if any,else waits for KNOTFY;01.09 ; to set Event Flag 10 and looks again for input. ;01.09 ; ;01.09 KBWAIT:: ;01.09 10$: CLEF$S #10. ; Clear the event flag ;01.09 CALL KBDCHK ; Do input if possible ;01.09 MOVB GETTBL+1,R0 ; See if we did any ;01.09 BNE 30$ ; Yes, exit now. ;01.09 STSE$S #10. ; Wait for a signal ;01.09 BR 10$ ; See if it was right ;01.09 30$: RETURN ; Success, return. ;01.09 ; ;01.09 ; Unsolicited-input notification AST. ;01.09 ; ;01.09 KNOTFY: ;01.09 SETF$S #10. ; Don't need to do much ;01.09 TST (SP)+ ; Clean up the stack, ;01.09 ASTX$S ; Exit the AST service ;01.09 ; ;01.09 ; Control-C AST handler ;01.09 ; ;01.09 KNTRLC:: ;01.09 TST (SP)+ ; Pop a word off stack ;01.09 MOV 2(SP), RETADD ; Save the old return. MOV #ERROR0,2(SP) ; Point at the Control-C code 40$: SETF$S #10. ; Set input event flag ;01.09 50$: ASTX$S ; Exit from KB AST ;01.09 ERROR0: DIR$ #DET ; Let go of our device STOP$S ; Stop the task for later. JSR PC, STTRM1 ; Reset the terminal MOV RETADD, -(SP) ; Get the re-start address. RTS PC ; And restart the process. RETADD: .WORD 0 ASTPC == 4 ; offset on AST stack to PC DET: QIOW$ IO.DET,7,1 ; Dump the terminal ATT: QIOW$ IO.ATA!TF.NOT,7,,,,, ; Specify KB AST;01.09 TTYGET: QIOW$ SF.GMC,7,1,,,, ; Get buff len ;01.09 TTYKIN: QIOW$ IO.RNE!TF.RAL,7,1,,,, ; Get KBD input ;01.09 TTYFLU: QIOW$ SF.SMC,7,1,,,, ; Flush KB buff ;01.09 GETTBL: .BYTE TC.TBF,0 ; GMC/SMC buffer;01.09 KBSTPT: .WORD 0 KBGTPT: .WORD 0 KBBUF: .BLKB 32. TRMIO:: QIOW$ IO.WVB,7,1,,,, FIND: QIOW$ SF.GMC,7,1,,,, BUFF: .BYTE TC.TTP,0 .END