; KEYBOARD AND TELEPRINTER DRIVER - PART 2 ; ; VERSION V005A ;  001 ; ; COPYRIGHT 1973,1974 DIGITAL EQUIPMENT CORP. MAYNARD, MASS. ; ; NON-CONSOLE INPUT INTERRUPT ; TK.INA: MOV S.STAT,#0 ;SAVE CURRENT STATUS TK.INB=.-2 JSR R5,STRG  ;SAVE REGISTERS MOV TK.INB,R5 ;GET STATUS JSR PC,TT.GUA ;SAVE UNIT # BR TK.INC  ;JOIN CONSOLE .ENDC ; ; CONSOLE INPUT INTERRUPT ENTRY ; KB.INA: JSR R5,STRG  ;SAVE REGISTERS SUB PC,R5  ;#-2 TO R5 TK.INC: MOVB #200,S.STAT ;DROP PRIORITY MOV #SRTI,-(SP) ;DRIVE EXIT ADDRESS MOV TKI.TS(R5),R0 ;GET DDB POINTER MOV TKI.CS(R5),R2 ; GET ADDRESS OF STATUS REQ MOVB 2(R2),R2 ;GET CHARACTER FROM KEYBOARD CMPB EC(R5),#EBSZ ;ECHO BUFF FULL? BGE TKO.EX  ;YES-DROP THE CHARACTER BIC #-177-1,R2 ;SAVE LOW 7 BITS + IGNORE NULLS. BEQ TKO.EX  ;IGNORE NULLS. MOV #KO.MA-1,R1 ;SET ADR OF CHECK STRING .IFNZ TK.NOU TST R5  ;CONSOLE? BMI KB.INN  ; YES- CMPB R2,#30  ;CNTRL-X? BEQ KB.CX  ;YES-GO TURN OFF CURRENT TASK BR KB.INC  ;GO INPUT THE CHARACTER .ENDC KB.INN: CMPB R2,(R1) ;CNTRL-C? BNE .+6 JMP KB.INB ;YES- TSTB (PC)+  ;COMMAND MODE? K.CCF: .WORD 0 BEQ KB.INS  ;NO- ; COME HERE IF IN CNTRL-CMODE MOV #-4,R5  ;SWITCH TO UNIT -2 BR KB.INC KB.INS: BITB #SY.RES,SY.DFL(R0);INITED? BEQ KB.EX  ;NO-EXIT KB.INC: JSR PC,KB.CRP ;GET POINTERS TSTB K.TRM(R5) ;IS BUFFER TERMINATOR SET? BNE KB.EX  ;BRANCH IF YES TO IGNORE CHAR CMPB R2,-(R1) ;CNTRL-U? BEQ KB.INH CMPB R2,-(R1) ;RUBOUT? BEQ KB.ING CMPB #32,R2  ;IS THIS CONTROL Z BNE KB.XR2  ;IF NE, NOT CONTROL Z INCB K.ENFL(R5) ;SET EOD INDICATOR BR KB.INI  ;GO ECHO IT KB.XR2: MOV #KBSZ-2,-(SP) ;CREATE POINTER TO END OF BUFFER. ADD K.BUF(R5),(SP) CMP (R4),(SP)+ ;ROOM FOR ONE CHARACTER? BHI KB.EX  ;NO-DROP CURRENT CHARACTER. KB.XR1: MOVB R2,@(R4)+ ;PUT CHARACTER INTO BUFFER INC -(R4)  ;UPDATE POINTER. DEC K.CT(R5) ;DECR MAX USER BYTE COUNT ; ; ECHO THE CHARACTER ; KB.INI: TSTB K.ESF(R5) ;ECHO SUPPRESS? BNE KB.INM  ;YES- MOVB K.ROM(R5),R1 ;ADD RUBOUT MODE INTO CHARACTER FOR ADD R1,R2  ;PROPER ECHO. CLR R3  ;SET RUBOUT MODE PROPERLY ADD R2,R1  ;DEPENDING ON ORIGINAL MODE, TSTB R1  ;AND CURRENT CHARACTER. BPL .+6 MOV #200,R3 MOVB R3,K.ROM(R5) MOV R5,-(SP) ;SAVE CURRENT R5 BPL .+6  ;SKIP IF POSITIVE MOV #-2,R5  ;ELSE, CHANGE -4 TO -2. MOV EPI(R5),R1 ;PUT CHARACTER INTO ECHO BUFFER MOVB R2,(R1)+ ;-ADVANCE POINTER. JSR PC,K.CWR ;CHECK FOR WRAP AROUND. MOV R1,EPI(R5) INCB EC(R5)  ;COUNT THE CHARACTER. CMPB EC(R5),#EBSZ ;ECHO BUFFER FULL? BGE KB.INV  ;YES-FORCE ECHO OUT TSTB EF(R5)  ;ECHO FLAG SET? BNE .+6  ;YES- INCB EF(R5)  ;NO-SET IT TO +1. TSTB TKO.CT(R5) ;XFER INPROGRESS? BLE KB.INJ  ;YES-- KB.INV: MOVB #-1,EF(R5) ;NO-START ECHO OUT MOVB #100,@TKO.CS(R5) ;AND START PRINTER. KB.INJ: BIC #-177-1,R2 ;GET ORIGINAL CHARACTER. MOV (SP)+,R5 ;GET ORIGINAL R5 KB.INM: TSTB K.OPF(R5) ;OPEN CALL? BNE KB.INR  ;YES- TSTB K.ENFL(R5) ;IS EOD SET? BNE KB.IM4  ;IF NE EOD IS SET..GO START XFER TST K.BC(R5) ;IS THIS UNSOLICITED INPUT? BGT KB.IM1  ;IF GT, IT IS UNSOLICITED BITB #2,30(R0) ;UNFORMATTED TRANSFER? BEQ KB.IM1  ;BRANCH IF FORMATTED TRANSFER TST K.CT(R5) ;DECREMENT USER BYTE COUNT BLE KB.IM4  ;IF LT, BRANCH TO START TRANSFER KB.IM1: CMPB R2,#15  ;IF CHAR IS ... BNE KB.IM2 ; MOV #12,R2  ;...CHANGE IT TO BR KB.XR1  ;AND GO ECHO IT KB.IM2: CMPB R2,#15  ;NOW CHECK FOR LINE TERMINATORS BHI KB.EX  ;NO- CMPB R2,#12   BLO KB.EX  ;NO- INCB K.TRM(R5) ;SET TERMINATOR INDICATOR .IFNZ TK.NOU TST R5  ;CONSOLE? BPL KB.IM3  ;NO-SKIP CNTRL-C TEST. .ENDC TSTB K.CCF  ;COMMAND MODE? BNE KB.INK  ;YES-GO START OPERATOR TASK KB.IM3: TST K.BC(R5) ;IS THIS UNSOLICITED INPUT BGT KB.INW  ;IF GT, IT IS UNSOLICITED BITB #2,30(R0) ;UNFORMATTED TRANSFER? BEQ KB.INW  ;BRANCH IF FORMATTED TRANSFER CLRB K.TRM(R5) ;IF UNFORMATTED, CLEAR TERMINATOR BR KB.EX  ;AND EXIT KB.IM4: INCB K.TRM(R5) ;SET BUFFER TERMINATOR KB.INW: TST K.BC(R5) ;ELSE-CHECK IF A TRANSFER IS REQUESTED. BLE KB.TFB  ;GO DO TRANSFER ; IF A NON-CONSOLE UNIT,CHECK IF INITED. ; IF NOT,SCHEDULE A TASK(USER SUPPLIED) .IFNZ TK.NOU TST R5  ;CONSOLE? BPL KB.INU  ; NO-GO CHECK. .ENDC KB.EX: RTS PC ; KB.INH: MOV K.BUF(R5),(R4) ;CNTRL-U SEEN - RESET MOV @2(R0),K.CT(R5) ;RESTORE MAX USER BYTE COUNT BR KB.INI  ;INPUT PTR. ; KB.ING: DEC (R4)+  ;RUB OUT SEEN - BACK UP INPUT POINTER MOVB @-(R4),R2 ;AND GET CHARACTER FOR ECHO. BEQ KB.INL  ;IF NULL, THIS IS BEGINNING OF BUFF - I BIS #200,R2  ;ELSE, SET HIGH BIT FOR "\" ECH INC K.CT(R5) ;BUMP MAX USER BYTE COUNT BR KB.INI ; KB.INL: INC (R4)  ;RESTORE INPUT PTR. RTS PC ; KB.INK: CLRB K.CCF  ;EXIT FROM COMMAND MODE. SUB #2,(R4)+ ;BACK UP INPUT PTR CLRB @-(R4)  ;TERMINATE COMMAND LINE WITH NULL. JSR PC,KB.RES ;RESET INPUT POINTERS CLR R2  ;NO DATA TO PASS MOVB #OPERT,R0 ;TASK INDEX TO R0 KB.IND: JSR R5,HSASI ;ACTIVATE TASK. RTS PC RTS PC ; DATA FOR OPERATOR START CALL & NON CONSOLE OPERATOR TASK ; KB.INB: MOVB #-1,K.CCF ;CNTRL-C SEEN-SWITCH TO MOV #-4,R5  ;COMMAND MODE. JSR PC,KB.RES JMP KB.INI ; OPEN CALL KB.INR: CLRB K.OPF(R5) BR KB.TFI .IFNZ TK.NOU ; KB.INU: BITB #SY.RES,SY.DFL(R0);INITED? BNE KB.EX  ;YES-EXIT TO WAIT FOR A READ. ASR R5 MOV R5,R2  ;DATA TO R2 MOVB #TTOPT,R0 ;TASK INDEX TO R0 BR KB.IND  ;GO START THE TASK ; ; NON-CONSOLE INPUT TRANSFER ; TK.TFA: CLR TK  ;NOT BUSY JSR PC,TT.GU ;GET UNIT # BR TK.TFB  ;JOIN CONSOLE .ENDC ; ; CONSOLE INPUT TRANSFER ENTRY ; KB.TFA: MOV #-2,R5  ;UNIT # TK.TFB: MOV R0,TKI.TS(R5) ;SAVE DDB POINTER MOVB 12(R0),R4 ;GET ECHO SUPPRESS BIT BIC #-10-1,R4 MOVB R4,K.ESF(R5) ;PUT INTO FLAG. MOV 10(R0),R4 ;SET BYTE COUNT ASL R4 MOV R4,K.BC(R5) MOV 6(R0),K.DP(R5) ;SET DATA POINTER BITB #2,30(R0) ;IS UNFORMATTED ASCII? BEQ KBTR  ;BRANCH IF FORMATTED MOV @2(R0),K.CT(R5) ;GET USER MAX BYTE COUNT MOV K.IN(R5),-(SP) ;TYPE AHEAD INPUT POINTER SUB K.OUT(R5),(SP) ;CALCULATE BYTE COUNT OF CHARS    ;ALREADY TYPED SUB (SP)+,K.CT(R5) ;IF MAX BYTE COUNT OVERFLOWED ... BLE KB.TFB  ;...BRANCH TO START TRANSFER KBTR:    ;..OTHERWISE CONTINUE TO PROCESS TSTB K.TRM(R5) ;LINE AVAILABLE FOR TRANSFER? BNE KB.TFB  ;YES-GO TO IT. RTS PC KB.TFB: MOV #K.OUT,R4 ;YES-SET POINTERS MOV #K.BC,R3 ;INTERNAL BYTE COUNT POINTER MOV #K.DP,R1 ADD R5,R4  ;ADJUST FOR UNIT #. ADD R5,R3 ADD R5,R1 KB.TFH: MOVB @(R4)+,@(R1)+ ;GET A CHARACTER INC -(R4)  ;ADVANCE POINTER INC -(R1)  ;ADVANCE POINTER CMP (R4),K.IN(R5) ;ALL CHARS GONE? BHIS KB.TFE  ; YES- INC (R3)  ;NO - IS REQUEST DONE? BLT KB.TFH  ;NO - GO GET ANOTHER CHARACTER. BR KB.TFI  ;YES - TAKE COMPLETION EXIT. KB.TFF: CLRB @(R1)+  ;GIVE A NULL TO REQUESTOR INC -(R1)  ;ADVANCE POINTER TSTB K.ENFL(R5) ;IS EOD FLAG SET? BNE KB.TFG  ;IF NE, FLAG IS SET KB.TFE: INC (R3)  ;BUMP INTERNAL BYTE COUNT BLT KB.TFF  ;INSERT A NULL IF LT KB.TFG: BIT #1,(R3)  ;BYTE COUNT EVEN? BEQ KB.TFK  ;IF EQ,BYTE COUNT IS EVEN INC (R3)  ;MAKE BYTE COUNT EVEN KB.TFK: ASR (R3)  ;MAKE REMAINING BYTE COUNT A WORD COUNT MOV (R3),16(R0) ;SET REMAINING BYTE COUNT KB.TFJ: JSR PC,KB.RES ;RESET THE INDICATORS AND POINTERS KB.TFI: JMP @14(R0)  ;COMPLETION EXIT. .IFNZ TK.NOU ; ;NON CONSOLE INPUT OPEN ; TK.OPA: CLR TK  ;NOT BUSY JSR PC,TT.GU ;GET UNIT # BR TK.OPC  ;JOIN NORMAL OPEN/CLOSE ; ; NON-CONSOLE INPUT CLOSE ; TK.CLA: CLR TK  ;NOT BUSY JSR PC,TT.GU ;GET UNIT # BR TK.OPB  ;JOIN CONSOLE .ENDC ; ; CONSOLE INPUT OPEN/CLOSE ; KB.OPA: MOV #-2,R5  ;UNIT # TK.OPB: JSR PC,KB.RES TK.OPC: MOV #1,K.OPF(R5) ;SET OPEN FLAG AND CLEAR ECHO SUPPRESS MOV #15,R2  ;GET A CR TO PUT INTO ECHO BUFF. .IFNZ TK.NOU CMPB EC(R5),#EBSZ ;ECHO BUFF FULL? BLT TK.OPD  ;NO- JMP KB.INR  ;YES-SKIP OUTPUT OF CR,LF .ENDC TK.OPD: JMP KB.INI  ;GO ECHO CR,LF ; COME HERE IF END OF DATA SEEN. .IFNZ TK.NOU ;NON CONSOLE CANCEL TT.S: JSR PC,TT.GU ;GET UNIT # BR KB.SA .ENDC ;CONSOLE CANCEL KB.S: MOV #-2,R5  ;UNIT # KB.SA: MOV #-2,16(R0) ;FORCE NON-ZERO BYTE COUNT AND EXIT BR KB.TFJ  ;EXIT. ; PUT POINTERS TO IN AND OUT POINTERS INTO R4 AND R3 KB.CRP: MOV R5,R4  ;CREATE POINTERS TO BUFFER POINTERS MOV R5,R3 ADD #K.IN,R4 ADD #K.OUT,R3 KBO.SX: RTS PC ;SUBROUTINE TO GET PTRS TO BUFF PTRS ; AND TO RESET BUFF POINTERS, ; TERMINATOR FLAG AND ECHO SUPPRESS FLAG ; KB.RES: JSR PC,KB.CRP ;GET PTRS TO POINTERS. MOV K.BUF(R5),(R3);RESET BUFF POINTERS. MOV (R3),(R4) CLR K.TRM(R5) ;NO TERMINATOR AND RUBOUT CLRB K.ESF(R5) ;NO ECHO SUPPRESS CLRB K.ENFL(R5) ;RESET EOD FLAG MOV #1,K.BC(R5) ;RESET INTERNAL BYTE COUNT RTS PC ; ; CHECK FOR WRAP AROUND OF ECHO POINTER ; CALL WITH  ;R5=UNIT # ; JSR PC,K.CWR ;R1=PTR OF INTEREST ;    ;BLOWS R3 ; K.CWR: MOV R1,R3  ;FORM DIFFERENCE BETWEEN CURRENT SUB EBP(R5),R3 ;PTR AND BEGINNING OF BUFF. CMP R3,#EBSZ ;GONE TOO FAR? BLT .+4  ;NO - SUB R3,R1  ;YES - BACK UP THE POINTER RTS PC ; ; ROUTINE TO FETCH UNIT #*2 FROM DDB ; ; ALTERNATE ENTRY AT TT.GUA WILL FETCH ;  UNIT #*2 FROM R5 ; ; CALL JSR PC,TT.GU ;R0=DDB ADDR. ; ; OR CALL JSR PC,TT.GUA ;R5=UNIT # ; TT.GU: MOVB 13(R0),R5 ;GET UNIT # FROM DDB TT.GUA: BIC #-7-1,R5 ;SAVE LOW 3 BITS ASL R5  ;CONVERT TO UNIT #*2 RTS PC ; ; ; ; ; DATA AREAS FOR CONSOLE AND NON-CONSOLE TELEPRINTERS ; ; INTERNAL BYTE COUNT .WORD 1  ;CONSOLE COUNT TKO.CT: .WORD 1  ;OTHER UNITS. .WORD 1  ;OTHER UNITS. .WORD 1  ;OTHER UNITS. .WORD 1  ;OTHER UNITS. .WORD 1  ;OTHER UNITS. .WORD 1  ;OTHER UNITS. .WORD 1  ;OTHER UNITS. .WORD 1  ;OTHER UNITS. .=TKO.CT+TK.NOU+TK.NOU ; INTERNAL BUFFER POINTER .WORD 0  ;CONSOLE TKO.BF: .WORD 0  ;OTHER UNITS .WORD 0  ;OTHER UNITS .WORD 0  ;OTHER UNITS .WORD 0  ;OTHER UNITS .WORD 0  ;OTHER UNITS .WORD 0  ;OTHER UNITS .WORD 0  ;OTHER UNITS .WORD 0  ;OTHER UNITS .=TKO.BF+TK.NOU+TK.NOU ; TAB COUNTERS AND FLAGS .WORD 0  ;CONSOLE TKO.TB: TKO.TP=.+1 .WORD 0  ;OTHER UNITS .WORD 0  ;OTHER UNITS .WORD 0  ;OTHER UNITS .WORD 0  ;OTHER UNITS .WORD 0  ;OTHER UNITS .WORD 0  ;OTHER UNITS .WORD 0  ;OTHER UNITS .WORD 0  ;OTHER UNITS .=TKO.TB+TK.NOU+TK.NOU ; ;  FILL COUNT ; .IFNDF KBCR KBCR=0 .ENDC ; .IFNDF TT0CR TT0CR=0 .ENDC ; .IFNDF TT1CR TT1CR=0 .ENDC ; .IFNDF TT2CR TT2CR=0 .ENDC ; .IFNDF TT3CR TT3CR=0 .ENDC ; .IFNDF TT4CR TT4CR=0 .ENDC ; .IFNDF TT5CR TT5CR=0 .ENDC ; .IFNDF TT6CR TT6CR=0 .ENDC ; .IFNDF TT7CR TT7CR=0 .ENDC ; ; ;  FILL COUNT ; .IFNDF KBLF KBLF=0 .ENDC ; .IFNDF TT0LF TT0LF=0 .ENDC ; .IFNDF TT1LF TT1LF=0 .ENDC ; .IFNDF TT2LF TT2LF=0 .ENDC ; .IFNDF TT3LF TT3LF=0 .ENDC ; .IFNDF TT4LF TT4LF=0 .ENDC ; .IFNDF TT5LF TT5LF=0 .ENDC ; .IFNDF TT6LF TT6LF=0 .ENDC ; .IFNDF TT7LF TT7LF=0 .ENDC ; .BYTE KBCR,KBLF  ;CONSOLE TKO.FC: TKO.LF=TKO.FC+1 .BYTE TT0CR,TT0LF  ;REMAINING TERMINALS 0-7 .BYTE TT1CR,TT1LF .BYTE TT2CR,TT2LF .BYTE TT3CR,TT3LF .BYTE TT4CR,TT4LF .BYTE TT5CR,TT5LF .BYTE TT6CR,TT6LF .BYTE TT7CR,TT7LF ; .=TKO.FC+TK.NOU+TK.NOU ; ; STORE FOR DDB POINTERS ; .WORD 0  ;CONSOLE TKO.TS: .WORD 0  ;OTHER UNITS .WORD 0  ;OTHER UNITS .WORD 0  ;OTHER UNITS .WORD 0  ;OTHER UNITS .WORD 0  ;OTHER UNITS .WORD 0  ;OTHER UNITS .WORD 0  ;OTHER UNITS .WORD 0  ;OTHER UNITS .=TKO.TS+TK.NOU+TK.NOU ; ; KEYBOARD DATA AREAS ; ; ; STORE FOR DDB POINTERS .WORD 0 TKI.TS: .WORD 0 .WORD 0 .WORD 0 .WORD 0 .WORD 0 .WORD 0 .WORD 0 .WORD 0 .=TKI.TS+TK.NOU+TK.NOU ; ECHO FLAG/ECHO COUNT .WORD 0  ;CONSOLE EF: EC=.+1 .WORD 0  ;NON-CONSOLE .WORD 0  ;NON-CONSOLE .WORD 0  ;NON-CONSOLE .WORD 0  ;NON-CONSOLE .WORD 0  ;NON-CONSOLE .WORD 0  ;NON-CONSOLE .WORD 0  ;NON-CONSOLE .WORD 0  ;NON-CONSOLE .=EF+TK.NOU+TK.NOU ; ; STORAGE FOR USER MAX BYTE COUNT ; .WORD 0  ;CONSOLE COMMAND MODE .WORD 0  ;CONSOLE INPUT TRAN K.CT: .WORD 0  ;NON-CONSOLE .WORD 0  ;NON-CONSOLE .WORD 0  ;NON-CONSOLE .WORD 0  ;NON-CONSOLE .WORD 0  ;NON-CONSOLE .WORD 0  ;NON-CONSOLE .WORD 0  ;NON-CONSOLE .WORD 0  ;NON-CONSOLE .=K.CT+TK.NOU+TK.NOU .EOT