.TITLE KLDRV KL11 driver .IDENT /03.04/ ; ; This is the hardware driver for the KL11 and compatible asynchronous serial ; line interfaces of the PDP11. ; ; The first device is the Console KL11 at 177560/60, additional devices are ; supported at 176500/300 and the following addresses. The symbol NKL must be ; defined to the number of devices to support, including the Console. ; ; 11-AUG-2005 H. Rosenfeld changed interrupt handlers ; 09-AUG-2005 H. Rosenfeld renamed to KLDRV since there now is support for ; more devices than just the Console ; 22-MAY-2005 H. Rosenfeld use $BUSHND call to install bus error handler ; 11-MAY-2005 H. Rosenfeld ; .LIST ME .NLIST CND .ENABL REG .LIBRARY /TTYCTL.SML/ .LIBRARY /IOSYS.SML/ .LIBRARY /JOBCTL.SML/ .LIBRARY /SYSCLL.SML/ .LIBRARY /CALL.SML/ .MCALL .TTY,.TTYCTL,$TTYREG .MCALL .DEV,.DEVCTL,$ASSOC,$DISSOC .MCALL $BUSHND,$TERM .MCALL $SYS .MCALL .IMAGE,.ENTRY,.RETRN,.CALL .DEVCTL .TTYCTL .MACRO .KL11 CSR,VEC .WORD CSR .WORD CSR+2 .WORD CSR+4 .WORD CSR+6 .WORD VEC .WORD VEC+4 .ENDM .MACRO .CINFO SCSR,SVEC .ASCIZ /, CSR 'SCSR, VEC 'SVEC/ .ENDM .MACRO .KLDEF NUM .CSECT K$INT'NUM::MOV R0,-(SP) MOV DEVTAB+NUM,R0 BR K$INTR P$INT'NUM::MOV R0,-(SP) MOV DEVTAB+NUM,R0 BR P$INTR .PSECT DEVTAB .WORD KL11$'NUM .PSECT CONST .IF EQ NUM DEFCSR=177560 DEFVEC=060 INFO$'NUM::.ASCII /KL11 CONSOLE INTERFACE/ .IFF DEFCSR=176500!<*10> DEFVEC=300!<*10> INFO$'NUM::.ASCII /KL11 ASYNCHRONOUS LINE/ .ENDC .CINFO \DEFCSR,\DEFVEC .PSECT DATA KL11$'NUM::.DEV ,,,,INFO$'NUM, .TTY K$ON,K$OFF,P$ON,P$OFF .KL11 \DEFCSR,\DEFVEC .ENDM KL$TKS=SIZE$T+0 ; terminal keyboard status KL$TKB=SIZE$T+2 ; terminal keyboard buffer KL$TPS=SIZE$T+4 ; terminal printer status KL$TPB=SIZE$T+6 ; terminal printer buffer KL$KV=SIZE$T+10 ; keyboard interrupt vector KL$PV=SIZE$T+12 ; printer interrupt vector SIZE$K=SIZE$T+14 NKL=4 .IMAGE KL$DRV .CSECT ; driver initialization ; probes for device, aborts if inexistant ; resets device, registers interrupt handlers, registers device KL$DRV::MOV #NKL,R4 ; get device count MOV #K$INT0,R2 ; get first interrupt handler CLR -(SP) ; device number on stack, start with 0 1$: MOV (SP),R0 ; get device number ASL R0 ; make table index MOV DEVTAB(R0),R3 ; get device structure $BUSHND #2$ ; register bus error handler TST @KL$TKS(R3) ; test for existance of device $BUSHND #0 ; device exists, reset bus-error handler CLR @KL$TKS(R3) ; reset keyboard status CLR @KL$TPS(R3) ; reset printer status $TTYREG R3 ; register terminal device BCS 2$ ; skip registering interrupt handlers if error $ASSOC KL$KV(R3),R2,#340 ; register keyboard interrupt handler ADD #P$INT0-K$INT0,R2 ; switch to printer interrupt handler $ASSOC KL$PV(R3),R2,#340 ; register printer interrupt handler SUB #P$INT0-K$INT0,R2 ; switch back 2$: ADD #*2,R2 ; next device INC (SP) ; next device DEC R4 ; next device BNE 1$ $TERM ; terminate ; K$ON, enable keyboard interrupt K$ON: .ENTRY MOV 6(R5),R4 ; get device structure BIS #100,@KL$TKS(R4); set interrupt enable bit in TKS .RETRN ; K$OFF, disable keyboard interrupt K$OFF: .ENTRY MFPS -(SP) MTPS #340 ; block interrupts to avoid hard system hang MOV 6(R5),R4 ; get device structure BIC #100,@KL$TKS(R4); clear interrupt enable bit in TKS MTPS (SP)+ .RETRN ; P$ON, enable printer interrupt P$ON: .ENTRY MOV 6(R5),R4 ; get device structure BIS #100,@KL$TPS(R4); set interrupt enable bit in TPS .RETRN ; P$OFF, disable printer interrupt P$OFF: .ENTRY MFPS -(SP) MTPS #340 ; block interrupts to avoid hard system hang MOV 6(R5),R4 ; get device structure BIC #100,@KL$TPS(R4); clear interrupt enable bit in TPS MTPS (SP)+ .RETRN ;K$INTR, keyboard interrupt handler ; read character off device, give it to terminal driver K$INTR: MOV R1,-(SP) .CALL @T$PUTC(R0),R0,@KL$TKB(R0) ; input character MOV (SP)+,R1 ; restore R0 and R1 MOV (SP)+,R0 RTI ; P$INTR, printer interrupt handler ; fetch character from terminal driver, write it to device ; if no character available, disable interrupt P$INTR: MOV R1,-(SP) MOV R0,-(SP) ; store for later use .CALL @T$GETC(R0),R0 ; get character MOV (SP)+,R1 ; get device entry BCS 1$ ; do not output on error MOVB R0,@KL$TPB(R1) ; output character BR 2$ 1$: .CALL P$OFF,R1 ; disable printer interrupt 2$: MOV (SP)+,R1 ; restore R0 and R1 MOV (SP)+,R0 RTI .PSECT DEVTAB DEVTAB:: KLNUM=0 .REPT NKL .KLDEF \KLNUM KLNUM=KLNUM+1 .ENDR .END KL$DRV