;VERSION NUMBER: V000B .GLOBL LPINT ;INTERRUPT ADDRESS ; LINE PRINTER DRIVER (LP) PRSIZE=132. ; NUMBER OF COLUMNS FOR THIS PRINTER .TITLE LP 27-MAR-74 ; BINARY MODE TRANSFERS DATA TO PLOTTER .GLOBL LP R0=%0 R1=%1 R2=%2 R3=%3 R4=%4 R5=%5 SP=%6 PC=%7 ; PREAMBLE (FIXED) LP: .WORD 0 ; CURRENT DCB OR 0 .BYTE LP.BP ; FACILITIES INDICATOR .BYTE 0 .BYTE 3 ; STD. BUF. / 16 ; 80 CHAR. MAX. .BYTE LP.IVC-LP ; INTERRUPT ADDRESS .BYTE 200 ; STATUS (PRIORITY 4) .BYTE LP.OPN-LP ; OPEN ENTRY .BYTE LP.TFR-LP ; TRANSFER (OUT) .BYTE LP.CLS-LP ; CLOSE .BYTE 0 ; SPECIAL .BYTE 0 ; SPARE LP.NAM: .RAD50 'LP' ; LP LINKBLOCK AND DDB .GLOBL LP0 LP0: .WORD LPDDB ;DDB POINTER .WORD 0 ;NO LOGICAL NAME .BYTE 1,0 ; .RAD50 /LP/ ;DEVICE NAME DEFAULT .REPT 25. .WORD 0 .ENDR .WORD 0,0,0,LP ;DRIVER ADDR LPDDB: .WORD 0 ;USER CALL ADDR .REPT 25. .WORD 0 ;DDB .ENDR LP.IVC: JMP LP.INT ; MISC. STORES: LP.FRM: .BYTE 14,0 ; USED FOR OPEN & CLOSE LP.LIN: .WORD 0 BTCT: .WORD 0 ; INTERNAL COUNT BUFAD: .WORD 0 ; BUFFER POINTER BUFAD2: .WORD 0 ; BUFFER PHYS BLK NO. ;N.B. OPEN AND CLOSE ASSUME LP HANDLER IN 1ST 32K OF MEMORY! LP.TAB: .WORD 0 ; TABULATION COUNT ; OPEN & CLOSE ROUTINES: LP.OPN: JSR R5,LP.STS ; SIMULATE INTERRUPT MOV #1,BTCT ; SET FOR FF PRINT MOV PC,-(SP) ;SET UP POINTER T_ FF ADD #LP.FRM-.,@SP MOV (SP)+,BUFAD MOV BUFAD,BUFAD2 ;SPLIT BUFAD INTO BLK, DISPLACEMENT BIC #^C77,BUFAD ;BUFAD IS DISPLACEMENT MOV R3,-(SP) MOV BUFAD2,R3 ASH #-6,R3 ;SHIFT OFF BLK # BIC #176000,R3 ;LEGALIZE EVEN IF SIGN EXTEND WAS DONE MOV R3,BUFAD2 MOV (SP)+,R3 ;RESTORE THE REG ; N.B. LP ASSUMED IN LOW 32K FOR THIS! BR LP.INT ; TRANSFER ROUTINE: LP.TFR: MOV LP,R0 ; PICK UP DDB JSR R5,LP.STS ; RUN AT LP STATUS MOV 6(R0),BUFAD ; SAVE BUFFER ADDRESS MOV BUFAD,BUFAD2 ;SETUP KNL MODE OFFSET FIRST BIC #^C77,BUFAD ;CLR ALL BUT DISPLACEMENT MOV R3,-(SP) MOV BUFAD2,R3 ;MAKE BLK # ASH #-6,R3 BIC #176000,R3 ;IN R3 MOV R3,BUFAD2 MOV (SP)+,R3 ;RESET R3 TST LPDDB+20 ;SEE IF ANY TSK OR IF KNL BEQ 1$ ;SKIP RELOC IF NO TSK JSR R5,S.RSAV ;SAVE USER REGS MOV 20(R0),R1 ;GET CALL TCB ADD #34,R1 ;POINTER CALL TSK'S APR SET MOV 6(R0),R2 ;GET ADDRESS IN USER VIRTUAL SPACE MOV R2,R3 ;COPY IT ASH #-12.,R2 ;GET APR # BIC #^C16,R2 ;MAKE WORD INDEX ADD R1,R2 ;POINT AT DESIRED APR START MOV @R2,R2 ;GET USER APR CONTENT ;USER BETTER NOT REMAP UNTIL I/O DONE!!! BAD NEWS IF HE DOES!!! MOV R3,R1 ;RECOPY BUFFER ADDR ASH #-6,R1 ;SHIFT OFF BLK # BIC #176000,R1 ;(NO SIGN EXTENSIONS PLEASE!) ADD R1,R2 ;MAKE PHYSICAL BLK # IN MEMORY MOV R2,BUFAD2 ;BUFAD2 BECOMES BLOCK NO. BIC #^C77,R3 ;ISOLATE ADDRESS DISPLACEMENT MOV R3,BUFAD ;BUFAD BECOMES D.I.B. JSR R5,S.RRES 1$: MOV 10(R0),R4 ; PRESERVE DDB W.C. .IIF DF,IO$WDS, ASL R4 ; CHARACTER COUNT NEG R4 ; MAKE POSITIVE MOV R4,BTCT LP.INT: BIC #100,@#LP.CSR ; DISABLE INTERRUPT TST @#LP.CSR ; CHECK FOR ERROR BMI LP.ERR ; YES MOV R1,-(SP) ;QUICK SAVE mOV R2,-(SP) ; REGS. MOV BTCT,R1 ; GET CURRENT BYTE COUNT BEQ LP.DNE ; NO MORE MOV BUFAD,R2 ; GET CURRENT BUF LOC. LP.LOP: TSTB @#LP.CSR ; IS PRINTER GOING BPL LP.STI ; YES MOV @#PS,-(SP) MOVB #340,@#PS ;LOCK OUT INTERRUPTS MOV @#KAPR6,-(SP) ;USE KNL APR6 FOR MAPPING MOV BUFAD2,KAPR6 ;FILL IN KNL APR6 WITH BLK BIS #140000,R2 ;SET KNL APR6 VIRTUAL OFFSET MOV @R2,R2 ;GET CHAR INTO R2 INC BUFAD ;BUMP DISPLACEMENT (OK IF OVER 64.) MOV (SP)+,@#KAPR6 ;RESTORE KNL APR6 MOV (SP)+,@#PS ;RESTORE PS TO OLD VALUE CMPB R2,#11 ; TAB ? BEQ LP.PTB CMPB R2,#15 ; CARRIAGE RETURN ... BEQ LP.RSC ; ... RESET COUNTS TSTB R2 ; IGNORE NULL ... BEQ LP.DNP CMPB R2,#13 ; VERTICAL TAB ... BEQ LP.DNP CMPB R2,#177 ; ... & RUBOUT BEQ LP.DNP CMPB R2,#12 ; IF LINE TERMINATOR ... BEQ LP.RSC CMPB R2,#14 BNE LP.CLO LP.RSC: MOV #9.,LP.TAB ; ... RESET COUNTS MOV #PRSIZE+1,LP.LIN BR LP.TBF ;... & OMIT NEXT LP.CLO: TST LP.LIN ; oTHERWISE CHECK LINE OFLO BEQ LP.DNP ; IGNORE CHAR IF FULL LP.TBF: MOVB R2,@#LP.BUF ; PRINT CHAR DEC LP.LIN ; COUNT CHARS. DISPATCHED DEC LP.TAB ; UPDATE TAB COUNT BNE LP.TRT MOV #8.,LP.TAB ; RESET TAB COUNT LP.TRT: DEC R1 ; UPDATE COUNT BNE LP.LOP ; MORE TSTB @#LP.CSR ; PRINTER GOING BMI LP.DUN ; NO, SO NO INTERRUPT LP.STI: MOV R1,BTCT ; SET UP FOR NEXT TIME ; MOV R2,BUFAD LP.TWC: BIS #100,@#LP.CSR ; ENABLE INTERRUPT MOV (SP)+,R2 ; RESTORE REGS MOV (SP)+,R1 RTI ; THROUGH INTERRUPT LP.DUN: MOV LP,R1 MOV #1,12(R1) ;????NEXT LINE WRONG PLACE??? MOV #1,16(R1) LP.DNE: MOV (SP)+,R2 ; RESTORE REGS MOV (SP)+,R1 .GLOBL S.RSAV,S.RRES JSR R5,S.RSAV CLR @#LP.CSR ; DISABLE INTERRUPT LP.IGN: MOV LP,R0 JMP @14(R0) ; COMPLETION RETURN LP.ERR: MOV R1,-(SP) ;SAVE A REG MOV LP,R1 ;(R1) DDB ADDR MOV #-7,12(R1) ;SET ERROR FLAG ; MOV #-7,16(R1) ;SET ERROR FLAG BR LP.DNE+2 ;AND RETURN TO HANDLER ; SUBROUTINE FOR INTERRUPT SIMULATION: LP.STS: MOV (SP),R4 ; SIMULATE INTERRUPT MOV 2(SP),R3 MOV @#S.STAT,2(SP) ; FROM JSR PC,XXXX MOV R3,(SP) MOV R4,-(SP) MOV @#LP.STV,@#S.STAT ; RUN UNDER LP STATUS RTS R5 LP.PTB: TST LP.TAB ; AT NEW TAB ALREADY? BEQ LP.EVN LP.MTB: MOVB #40,@#LP.BUF ; SPQCE FOR TABS TST LP.LIN ; LINE OVERFLOW BEQ LP.DNP ; YES, IGNORE REST DEC LP.LIN ; INCLUDE IN LINE COUNT DEC LP.TAB ; DONE ? BNE LP.LOP LP.EVN: MOV #8.,LP.TAB ; RESET LP.DNP:; INC R2 INC BUFAD BR LP.TRT LPINT: JSR R5,MX.PST ;POST THE INTERRUPT .WORD 240 ;RETURN AT PRI 5, NO REG SAVE JMP LP.INT LP.PLC=177500 LP.DBF=177506 LP.PLS=177510 LP.CSR=177514 LP.BUF=177516 LP.BP=332 LP.DMV=176 LP.SAV=44 S.STAT=177776 LP.STV=202 LP.CLS=LP.OPN .END