.TITLE KB ; ; VERSION V005A ;  001 ; ; KEYBOARD AND TELEPRINTER DRIVER - PART 1 ; ; THE KB DRIVER IS IN THREE PARTS TO FACILITATE ; PAPER TAPE HANDLING. ; ; COPYRIGHT 1973,1974 DIGITAL EQUIPMENT CORP. MAYNARD MASS. ; ; ; GLOBAL DEFINITIONS ; .GLOBL CMDST ;KB KEYBOARD TYPE-AHEAD BUFFER. .GLOBL KB ;KB DRIVER. .GLOBL KBDDB ;KB KEYBOARD DDB. .GLOBL K.ENFL ;KEYBOARD END-OF-FILE FLAG(BYTE). .GLOBL TPDDB ;KB TELEPRINTER DDB. ; ; GLOBAL REFERENCES ; .GLOBL DV.A2 ;CREATE A002 MESSAGE SUBROUTINE. .GLOBL HSASI ;HIGH SPEED ACTIVATE SUBROUTINE. .GLOBL KBBUF ;ADDRESS OF KB KEYBOARD EXEC BUFFER. .GLOBL OPERT ;OPERR TASK AND SLOT NUMBER. .GLOBL PAN$ ;PANIC DUMP ADDRESS. .GLOBL SRTI ;COMMON SYSTEM EXIT. .GLOBL STRG ;COMMON SYSTEM ENTRY SUBROUTINE. .GLOBL SY.DFL ;DDB-FLAG BYTE. .GLOBL SY.DPR ;DDB-PERMANENT DDB BIT. .GLOBL SY.DWN ;DDB-DEVICE IS DOWN FLAG (NOT READY). .GLOBL SY.MUD ;DRIVER MULTI-ACCESS BIT. .GLOBL SY.RES ;DDB-RESERVED FLAG. .GLOBL SY.RTN ;DDB-TASK DDB RESERVED FOR (BYTE) .GLOBL SY.TO ;DDB-TIME OUT COUNT (0=NOT ACTIVE) .GLOBL TKI.CS ;ADDRESS OF LIST OF KB&TT INPUT STATUS REGISTER .GLOBL TKO.CS ;ADDRESS OF LIST OF KB&TT OUTPUT STATUS REGISTE .GLOBL TPBUF ;ADDRESS OF KB OUTPUT EXEC BUFFER. .GLOBL TTOPT ;TT OPERATOR TASK SLOT NUMBER. .GLOBL UTILT ;UTILITY TASK SLOT. R0=%0 R1=%1 R2=%2 R3=%3 R4=%4 R5=%5 SP=%6 PC=%7 ; ; KEYBOARD PREAMBLE ; KB: .WORD 0  ;DDB PTR .BYTE KB.BP  ;FACILITIES .BYTE 1  ;TERMINAL DEVICE .BYTE 4  ;BUFF SIZE/16 .BYTE KB.INT-KB ;INTERRUPT ENTRY .BYTE 200  ;PRIORITY=4 .BYTE KB.OP-KB ;OPEN .BYTE KB.TF-KB ;TRANSFER .BYTE KB.CL-KB ;CLOSE .BYTE 0  ;SPECIAL FCN .BYTE KB.TB-KB ;MISCELLANEOUS ENTRY KB.NM: .RAD50 /KB/  ;NAME ; ; TELEPRINTER PREAMBLE ; KBO: .WORD 0  ;DDB PTR .BYTE KBO.BP+SY.MUD ;FACILITIES .BYTE 1  ;TERMINAL DEVICE .BYTE 4  ;BUFF SIZE/16 .BYTE KBO.IN-KBO ;INTERRUPT ENTRY .BYTE 200  ;PRIORITY=4 .BYTE KBO.OP-KBO ;OPEN .BYTE KBO.TF-KBO ;TRANSFER .BYTE KBO.CL-KBO ;CLOSE .BYTE 0  ;SPECIAL FCN .BYTE KBO.TB-KBO ;MISCELLANEOUS ENTRY KBO.NM: .RAD50 /KB/ ;MISCELLANEOUS ENTRY DISPATCH TABLE FOR KEYBOARD KB.TB: 0 0 0 KB.S ;CANCEL ;MISCELLANEOUS ENTRY DISPATCH TABLE FOR PRINTER KBO.TB: 0 KBO.TO ;TIME OUT 0 0 .IFNDF TK.NOU TK.NOU=0 .ENDC .IFNZ TK.NOU ; ; MULTI-KEYBOARD/TELEPRINTER DRIVER ; ; GLOBAL DEFINITIONS ; .GLOBL TODDB ;TT TELEPRINTER DDB. .GLOBL TT ;TT DRIVER. .GLOBL TTDDB ;TT KEYBOARD DDB. ; ; GLOBAL REFERENCES ; .GLOBL TKBUF ;ADDRESS OF TT KEYBOARD EXEC BUFFER. .GLOBL TOBUF ;ADDRESS OF TT OUTPUT EXEC BUFFER. ; ;PARAMETER TK.NOU DEFINES THE NUMBER OF UNITS ; ; ; KEYBOARD PREAMBLE TT:TK: .WORD 0  ;DDB POINTER ON ENTRY .BYTE TK.BP  ;FACILITIES .BYTE 1  ;TERMINAL DEVICE .BYTE 4  ;STD BUFF SIZE .BYTE TK.INT-TK ;INTERRUPT ENTRY .BYTE 200+TK.NOU-1 ;PRIORITY 4 PLUS MAX UNIT NUMBER. .BYTE TK.OP-TK ;OPEN .BYTE TK.TF-TK ;TRANSFER .BYTE TK.CL-TK ;CLOSE .BYTE 0  ;SPECIAL FCN .BYTE TK.TB-TK ;MISCELLANEOUS ENTRY TK.NM: .RAD50 /TT/  ;NAME ; TELEPRINTER PREAMBLE TKO.TF=TT.TF   ;TRANSFER TKO.INT=TT.INT   ;INTERRUPT TKO: .WORD 0  ;DDB PTR .BYTE TKO.BP+SY.MUD ;FACILITIES .BYTE 1  ;TERMINAL DEVICE .BYTE 4  ;STD BUFF SIZE .BYTE TKO.INT-TKO ;INTERRUPT ENTRY .BYTE 200+TK.NOU-1 ;PRIORITY 4 PLUS MAX UNIT # .BYTE TKO.OP-TKO ;OPEN .BYTE TKO.TF-TKO ;TRANSFER .BYTE TKO.CL-TKO ;CLOSE .BYTE 0  ;SPECIAL FCN .BYTE TKOTB-TKO ;MISCELLANEOUS ENTRY TKO.NM: .RAD50 /TT/  ;NAME ;MISCELLANEOUS ENTRY DISPATCH TABLE FOR TT KEYBOARD TK.TB: 0 0 0 TT.S ;CANCEL ;MISCELLANEOUS ENTRY DISPATCH TABLE FOR TT PRINTER TKOTB: 0 TKO.TO ;TIME OUT 0 0 .ENDC ; TRANSFERS TO KB KB.INT: JMP KB.INA  ;INTERRUPT KB.OP: JMP KB.OPA  ;OPEN KB.CL=KB.OP   ;CLOSE KB.TF: JMP KB.TFA  ;TRANSFER .IFNZ TK.NOU ; TRANSFERS TO TT KEYBOARD TK.INT: JMP TK.INA  ;INTERRUPT TK.OP: JMP TK.OPA  ;OPEN TK.CL: JMP TK.CLA  ;CLOSE TK.TF: JMP TK.TFA  ;TRANSFER .ENDC ; ; PARAMETERS ; .IFNDF KBSZ KBSZ=72.   ;KEYBOARD TYPE AHEAD BUFFER SIZE .ENDC .IFNDF EBSZ EBSZ=10.   ;ECHO BUFFER SIZE .ENDC S.STAT=-2   ;ADDRESS OF STATUS REGISTER KBO.BP=322   ;FACILITIES=OUTPUT, ASCII, OPEN, CLOSE TKO.BP=322 KB.BP=324   ;FACILITIES=INPUT, ASCII, OPEN, CLOSE TK.BP=324 ; ; CONSOLE OUTPUT OPEN ENTRY ; KBO.OP:    ;USE CLOSE ENTRY. ; ; CONSOLE OUTPUT CLOSE ENTRY KBO.CL: MOV #-2,R5  ;UNIT # .IFNZ TK.NOU BR TKO.CA ; ; NON-CONSOLE OUTPUT CLOSE AND OPEN. TKO.OP: TKO.CL: CLR TKO  ;NOT BUSY JSR PC,TT.GU ;GET UNIT # .ENDC TKO.CA: MOV #-2,R4  ;PREPARE TO OUTPUT CR,LF MOV #KBO.CR,TKO.BF(R5) ;SET DATA POINTER BR TKO.A  ;CONTINUE AS NORMAL TRANSFER. ; ; CONSOLE OUTPUT TRANSFER ENTRY ; KBO.TF: MOV #-2,R5  ;UNIT # .IFNZ TK.NOU BR TT.TFA  ;JOIN NON-CONSOLE ENTRY. ; NON-CONSOLE OUTPUT TRANSFER ENTRY ; TT.TF: CLR TKO  ;NOT BUSY JSR PC,TT.GU ;GET UNIT # .ENDC TT.TFA: MOV 6(R0),TKO.BF(R5) ;SET INTERNAL DATA POINTER. MOV 10(R0),R4 ;GET WORD COUNT. ASL R4  ;CHANGE TO BYTE COUNT TKO.A: MOV R4,TKO.CT(R5) ;SET INTERNAL COUNT. MOV R0,TKO.TS(R5) ;SAVE THE DDB POINTER. MOVB #-2,SY.TO(R0) ;ENABLE TIME OUT BIS #100,@TKO.CS(R5) ;ENABLE INTERRUPT RTS PC ; ;CONSOLE OUTPUT TIME OUT KBO.TO: MOV #-2,R5  ;UNIT # .IFNZ TK.NOU BR TT.INC ;NON CONSOLE TIME OUT TKO.TO: JSR PC,TT.GU ;GET UNIT # .ENDC BR TT.INC  ;TRY AGAIN ; ; CONSOLE OUTPUT INTERRUPT ENTRY ; KBO.IN: JSR R5,STRG  ;SAVE REGISTERS SUB PC,R5  ;SET CONSOLE UNIT NUMBER .IFNZ TK.NOU BR TT.INB  ;JOIN NON-CONSOLE ENTRY ; ; NON-CONSOLE OUTPUT INTERRUPT ENTRY ; TT.INT: MOV S.STAT,TT.TMP ;SAVE CURRENT STATUS TO GET UNIT #. JSR R5,STRG  ;SAVE REGISTERS. MOV (PC)+,R5 ;GET UNIT # TT.TMP: 0 JSR PC,TT.GUA ;GO SAVE UNIT # .ENDC TT.INB: MOV #SRTI,-(SP) ;DRIVER EXIT ADDRESS MOV TKO.TS(R5),R0 ;DDB ADDRESS CLR SY.TO(R0) ;NO TIME OUT TT.INC: MOVB #200,S.STAT ;DROP PRIORITY CLR @TKO.CS(R5) ;DISABLE INTS. MOV TKO.TS(R5),R0 ;GET PROPER DDB POINTER. TSTB TKO.TP(R5) ;REPEAT OUTPUT IN PROGRESS. BEQ .+6 JMP TKO.T  ;YES- MOVB @K.MPTR(R5),R2 ;SOMETHING IN SPECIAL OUTPUT STRING? BNE TKO.JI  ;IF NE, YES, GO PRINT IT MOVB CCTMP(R5),R2 ;CONTROL CHARACTER TO OUTPUT? BNE TKO.JJ  ;YES- TKO.JA: TSTB EF(R5)  ;ECHO IN PROGRESS? BMI TKO.JB  ;YES- TKO.JH: INC TKO.CT(R5) ;COUNT THIS CHARACTER BGT TKO.B  ;DONE- MOVB @TKO.BF(R5),R2 ;GET CHARACTER FOR OUTPUT. INC TKO.BF(R5) ;ADVANCE DATA POINTER. TKO.JG: MOV #KO.MA,R4 ;GET POINTER TO CHECK STRING CMPB R2,(R4)+ ;CR? BEQ TKO.DX  ; CMPB R2,(R4)+ ;LF? BEQ TKO.H  ; CMPB R2,(R4)+ ;NULL? BEQ TKO.JA  ;YES-IGNORE CMPB R2,#177  ;R/O? BEQ TKO.JA  ; YES-IGNORE. CMPB R2,(R4)+ ;OVER 40 (PRINTING?) BHIS TKO.F  ;YES-GO PRINT CMPB R2,(R4)+ ;TAB? BEQ TKO.ST CMPB R2,(R4)+ ;VT? BEQ TKO.FB  ;YES- CMPB R2,(R4)+ ;FF? BEQ TKO.KA  ;YES CMPB R2,(R4)+ ;BELL? BEQ TKO.F  ;YES- PRINT IT CMPB R2,(R4)+ ;BACKSPACE? BEQ TKO.F  ;YES-PRINT IT ;CONTROL CHARACTER FOUND-PRINT ^ CHAR. ;PUT ASSOCIATED CHARACTER INTO CCTMP FOR OUTPUT NEXT. ; ADD #100,R2  ;CONVERT CONTROL CHARACTER TO R MOVB R2,CCTMP(R5) ;AND SET IT FOR OUTPUT NEXT. MOVB #'^,R2  ;GET AN UP ARROW BR TKO.F  ;GO PRINT. ; ; DETECTED A FORM FEED - SET UP TO REPEAT 8 LF'S ; TKO.KA: MOV #5010,TKO.TB(R5) ;SET TABLE FOR LF IN HIGH ORDER    ;AND "8" IN LOW ORDER BR TKO.T  ;INITIATE EXECUTION ; ;OUTPUT NEXT ECHO CHARACTER ; TKO.JB: DECB EC(R5)  ;ANY CHARACTER TO OUTPUT? BMI TKO.JC  ;NO-DONE WITH ECHO MOV EPO(R5),R1 ;GET A CHARACTER FROM THE BUFFER MOVB (R1)+,R2 BMI TKO.JD  ;BRANCH TO OUTPUT A BACKSLASH JSR PC,K.CWR ;CHECK PTR FOR WRAP AROUND TO MOV R1,EPO(R5) ;AND PUT BACK. BR TKO.JG  ;CONTINUE AS NORMAL CHARACTER. ; ;ECHO DONE-SEE IF TRANSFER IN PROGRESS. TKO.JC: CLR EF(R5)  ;NO ECHO NOW. ALSO CLEAR ECHO COUNT TST TKO.CT(R5) ;ANY NORMAL OUTPUT TO DO? BLE TKO.JH  ;YES-GO DO IT. RTS PC  ;NO-EXIT ; ;OUTPUT A "\" FOR RUBOUT ECHO. PUT OUT CURRENT CHARACTER NEXT TIME. TKO.JD: BIC #-177-1,R2 ;SAVE LOW 7 BITS OF CHARACTER. MOVB R2,-(R1) ;PUT BACK INTO ECHO BUFFER. MOVB #'\,R2  ;GET A BACKSLASH. INCB EC(R5)  ;FUDGE COUNT BACK. BR TKO.JG  ;NORMAL FROM HERE. ; ; OUTPUT CHARACTERS FROM SPECIAL STRING FOR CNTRL-U AND ; CNTRL-C ; ; TKO.JI: INC K.MPTR(R5) ;ADVANCE THE POINTER BR TKO.JG  ;GO PROCESS FOR OUTPUT. ; OUTPUT SECOND CHAR OF CNTRL-CHAR. CLEAR CURRENT CHARACTER. ; ; TKO.JJ: CLRB CCTMP(R5) ;CLEAR THE CHARACTER STORAGE. TSTB EF(R5)  ;IS ECHO IN PROGRESS? BPL TKO.JG  ;NO - GO PRINT JUST THE CHARACTER. CMPB R2,#125  ;YES - CHECK FOR CNTRL-U. BEQ TKO.JK .IFNZ TK.NOU TST R5  ;MUST ALSO BE CONSOLE. BPL TKO.JM  ;NOT CONSOLE- .ENDC CMPB R2,#103  ;MAYBE A CNTRL-C? BNE TKO.JG  ;NO - GO PRINT MOV #KO.MB,K.MPTR(R5) ;SET PTR TO SPECIAL STRING. BR TKO.JG  ;FOR CNTRL-C ; TKO.JM: CMPB R2,#130  ;IS IT A CONTROL X? BNE TKO.JG  ;IF NE, NOT ^X - GO PRINT THE CHAR ; TKO.JK: MOV #KO.MA,K.MPTR(R5) ;SPECIAL STRING FOR CNTRL-U. BR TKO.JG ; TKO.DX: BR TKO.D  ;AUX. BRANCH ; TKO.F: MOV TKO.CS(R5),R1 ;GET ADR OF TELEPRINTER STATUS REGISTER MOVB #-2,SY.TO(R0) ;ENABLE TIME OUT BIS #100,(R1)+ ;ENABLE INTERRUPT MOVB R2,(R1)  ;OUTPUT CHARACTER. TKO.EX: RTS PC ; ; OPERATION DONE. ; TKO.B: CLR @TKO.CS(R5) ;DISABLE INTERRUPTS JMP @14(R0)  ;COMPLETION EXIT ; ; ROUTINE TO OUTPUT A CHAR "N" TIMES ; TKO.ST: MOV #20010,TKO.TB(R5) ;SET "SPACE" AND REPEAT COUNT IN LOW ORDER TKO.T: MOVB TKO.TP(R5),R2 ;GET REPEAT CHARACTER BIC #177600,R2 ;CLEAR EXTRA BITS DECB TKO.TB(R5) ;LAST REPEAT? BGT TKO.F  ;IF GT BRANCH TO PRINT CLR TKO.TB(R5) ;RESET COUNT AND FLAG. CMP #12,R2  ;IF REPEAT CHAR = LF... BNE TKO.F  ;IF NE, BRANCH TO DO LAST REPEAT TKO.H: NEGB EF(R5)  ;OTHERWISE, RE-ENABLE ECHO PROCESS BGT .-4 MOVB TKO.LF(R5),TKO.TB(R5) ;SET FILL COUNT TKO.H1: BEQ TKO.F  ;IF EQ, NO FILL -- GO OUTPUT TERMINATOR MOVB #200,TKO.TP(R5) ;SET "REPEAT" INDICATOR BR TKO.F  ;GO DO LAST BEFORE DOING REPEAT NULLS ; ; VT COMES HERE ; TKO.FB: NEGB EF(R5)  ;SET ECHO FLAG. BGT .-4 JMP TKO.JA  ;IGNORE VT ; ; SET UP TO FILL NULLS AFTER IS OUTPUT ; TKO.D: MOVB TKO.FC(R5),TKO.TB(R5) ;SET FILL COUNT BR TKO.H1  ;GO DO BEFORE STARTING REPEAT NULLS .IFNZ TK.NOU ; ; COME HERE ON CNTRL-X FROM NON CONSOLE KEYBOARD. ; ; HALT ANY TASK INITER TO THE KEYBOARD ;  AND CLEAR INPUT BUFFER. ; KB.CX: TST R0  ;ANY DDB POINTER? BEQ KB.CXA  ;NO-CAN'T BE INITED. BITB #SY.RES,SY.DFL(R0);ANYONE INITED? BEQ KB.CXA  ;NO-SKIP TASK HALTING. MOVB SY.RTN(R0),R2 ;GET TASK # SWAB R2  ;PUT IN HIGH BYTE CLRB R2 INCB R2  ;OFF REQUEST IN LOW BYTE. MOVB #UTILT,R0 ;TASK INSEX TO R0 JSR R5,HSASI ;ACTIVATE TASK BR KB.CXB  ;ERROR KB.CXA: JSR PC,KB.RES ;RESTORE INPUT POINTERS,FLAGS. MOVB #30,R2  ;PUT CNTRL/X IN R2 BR KB.INI  ;GO ECHO CNTRL-X KB.CXB: JSR PC,PAN$  ;SYSTEM ERROR .EOT