.TITLE LSFORM.P11 ;LSFORM - PREFIX MODULE FOR LPFORM.P11 FOR LS11 ; CENTRONIX PRINTER ;DATE: EDIT: BY: MHB/JDM LPFORM = 1 ; FORMS CONTROL IN LS = 1 ; 1 OR MORE LS11'S LPMULT = 0 ; 0 IF ONLY 1 PRINTER, 1 IF TWO PRINTERS .TITLE LPFORM.P11 LINE-PRINTER DRIVER ;COPYRIGHT 1972,1973 BY DIGITAL EQUIPMENT CORPORATION, ; MAYNARD, MASS. ;DATE: EDIT: BY: MHB/JDM .ASECT VECTOR 200,LPTINT,PR4 ;SET UP INTERUPT VECTOR FOR LP0: .IFNZ LPMULT VECTOR 170,LPTINT,PR5+1 ;VECTOR FOR SECOND LINE PRINTER .ENDC ;LPMULT .CSECT LP .GLOBL LPTGO,LPTSER,LPTHNG,LPTS10 ;INTERNAL .GLOBL RTI3,SAVREG,RESRTI,IOFINI,TABBER,STORE ;(MONITOR) .GLOBL CLRBUF,FETCH,FREBUF,RESREG .GLOBL LPTDDB,LPTIMR,LPTUPC,LPTDEV,LPSTS ;(TABLES) .GLOBL TTYS20,TTYS30 ;(TTY) .IFNDF LPFORM LPFORM = 0 ;IF HE DOESN'T KNOW ABOUT IT .ENDC .IIF NDF LPMULT LPMULT=0 .IIF NDF LS LS=0 LPTIMO = 5 ;LS11 FORM FEED TAKES A WHILE LPTS22: MOV (SP)+,R2 ;GET BACK THE SAVED CHARACTER LPTS10: JSR R5,FREBUF ;IS THERE ENOUGH BUFFERS .BYTE DDOUT+BC,2 BCS LPTS11 ;IF NOT, THEN EXIT NOW .IFZ LPFORM BIC #-177-1,R2 ;CLEAR ANY EXCESS BITS .ENDC .IFNZ LPFORM TSTB R2 ;IS THIS A CONTROL CHARACTER? BPL LPTS21 ;IF NORMAL, THEN CONTINUE JSR R5,FREBUF ;IF CONTROL, ARE THERE EXTRA BUFFERS? .BYTE DDOUT+BC,4 BCS LPTS11 ;IF NOT, THEN QUIT NOW BIC #-177-1,R2 ;CLEAR THE SIGN (CONTROL CHARACTER) BITS CLR -(SP) ;MAKE A FULL WORD OF 0 ON STACK MOVB DDVERC(R1),(SP) ;NOW STACK HAS THE MAX POSITION SUB R2,(SP) ;NOW FIND THE ROW WE WANT TO GO TO BLE LPTS24 ;UNLESS IT IS ILLEGAL, THEN IGNORE LPTS23: JSR PC,LPTLF ;NOW SEND LINE FEEDS CMPB DDVERT(R1),(SP) ;UNTIL THE VALUES MATCH BNE LPTS23 ;CONTINUE LINE FEEDS UNTIL THERE LPTS24: TST (SP)+ ;DUMP THE STACK ITEM (AND CARRY=0) RTS PC ;AND EXIT .ENDC LPTS21: CMPB R2,#177 ;RUBOUT? BEQ LPTS14 ;IF SO, THEN IGNORE IT CMPB R2,#15 ;IS IT RETURN BEQ LPTCR ;YES CMPB R2,#12 ;IS IT LINE FEED BEQ LPTLF ;YES CMPB R2,#14 ;IS IT FORM FEED BEQ LPTFF ;YES CMPB R2,#11 ;IS IT TAB BEQ LPTAB ;YES .IFNZ LPFORM BIT #LPTCH0,(R1) ;TRANSFORM 0'S TO O'S? BEQ LPTS16 ;NOT THIS TIME CMPB R2,#'0 ;IF SO, IS THIS A 0? BNE LPTS16 ;NOPE MOV #'O,R2 ;YEP, SO CHANGE IT TO A O .ENDC LPTS16: .IFNZ LPMULT CMPB R2,#140 ;IS THIS A LOWER CASE CHARACTER? BLOS LPTS15 ;LEAVE IT ALONE IF NOT BIT #LPTUCO,(R1) ;CONVERSION REQUESTED? BEQ LPTS15 ;NO .ENDC ;LPMULT .IFZ LPMULT CMPB R2,#LPTUPC ;IS THIS A LOWER CASE CHARACTER BLOS LPTS15 ;IF NOT, THEN LEAVE IT ALONE .ENDC ;LPMULT BIC #40,R2 ;ELSE MAKE IT UPPER CASE LPTS15: BIT R2,#140 ;IS THIS A PRINTING CHARACTER BEQ LPTS30 ;IF NOT, THEN IGNORE IT LPTS20: DECB DDHORZ(R1) ;BUMP THE HORIZONTAL POSITION BNE LPTS12 ;IF O.K., THEN GO STORE THAT CHARACTER MOV R2,-(SP) ;ELSE SAVE THE CHARACTER MOV #LPTS22,-(SP) ;AND RETURN TO LPTS22 LATER LPTLF: .IFNZ LS JSR PC,LPTS40 ;SEE IF EXTRA CR NEEDED .ENDC ;LS MOV #12,R2 ;NOW WE SEND OUT A LINE FEED DECB DDVERT(R1) ;COUNT THIS AS A LINE BNE LPTCR ;NOT END OF FORM YET .IFZ LPFORM LPTFF: .ENDC LPTFF1: .IFNZ LS JSR PC,LPTS40 ;SEE IF EXTRA CR NEEDED .ENDC ;LS MOVB DDVERC(R1),DDVERT(R1);RESET THE VERTICAL POSITION LPTCR: MOVB DDHORC(R1),DDHORZ(R1);AND RESET THE HORIZ POSITION LPTS12: JSR R5,STORE ;NOW STORE THE CHARACTER + DDOUT+FP ;INTO LPT BUFFER .IFZ LS LPTS30: .ENDC ;LS LPTS14: CLC ;INDICATE GOODNESS LPTS11: RTS PC ;AND EXIT .IFNZ LPFORM LPTFF: .IFNZ LS BIT #LPTSFT,(R1) ;SIMULATE FORM CONTROL? BEQ LPTFF1 ;NO .ENDC ;LS CMPB DDVERC(R1),#66. ;REGULAR? BEQ LPTFF1 ;YES, DO HARDWARE FORM FEED BR LPTS14 ;NO, IGNORE CHARACTER .ENDC .IFNZ LS LPTS30: BIT #LPTLS,(R1) ;IS THIS LS11? BEQ LPTS14 ;NO CMPB R2,#13 ;VERT TAB? BNE LPTS12 ;JUST SEND IT JSR PC,LPTS40 ;CHECK FOR LINE DUMPED BR LPTS12 ;NOW SEND IT LPTS40: CMPB DDHORZ(R1),DDHORC(R1) ;BEGINNING OF LINE? BEQ LPTS11 ;YEP MOV R2,-(SP) ;SAVE CHAR MOV #15,R2 ;SEND CR JSR PC,LPTCR MOV (SP)+,R2 ;RESTORE CHAR RTS PC .ENDC ;LS LPTAB: .IFNZ LS MOV #40,R2 ;ILLEGAL CHARS DON'T SPACE ON LS .ENDC ;LS JSR R5,TABBER ;DO THE TABBING + LPTS20 ;TO THIS ROUTINE FOR OUTPUT BR LPTS14 ;AND EXIT ;LINE-PRINTER- USER INTERFACE ;MOVE CHARACTERS FROM USER BUFFER TO MONITOR BUFFER ;TRANSLATING ODD CHARACTERS AS NECESSARY ;WHEN BUFFER IS FILLED (OR USER BUFFER EMPTY), START PRINTER LPTSER: TST (R1) ;RETURN FROM HUNG LPT? BMI LPTS01 ;YES--GIVE HIM A NASTY PMESSAGE TST (R5)+ ;ANYTHING LEFT TO TRANSFER BEQ LPTS02 ;NO - FORCE AN INTERRUPT JSR PC,TTYS20 ;GET A CHARACTER FROM USER BUFFER JSR PC,LPTS10 ;AND MAKE SURE IT IS PROCESSED PROPERLY BCS LPTS02 ;IF IT DIDN'T FIT, START LPT LPTS03: JSR R3,TTYS30 ;RESTORE R3, ION, UPDATE COUNTS + JSLPT ;JBWAIT BIT TO SET IF BUFFER FULL BR LPTSER ;CHARACTER ACCEPTED; PROCEED. LPTS01: BIC #DDSTAT,(R1) ;CLEAR HUNG BIT FOR NEXT TIME MOV #HNGDEV,@IOSTS ;JOB IS RUNNING NOW BR LPTS04 ;GET BACK TO USER VIA RTI3 ;START THE LINE PRINTER BY ENABLING INTERRUPT ;AND START THE COUNT DOWN TIMER IN CASE LPT IS OFF-LINE ;IF ENTERED WITH C=0, WE'VE EXHAUSTED USER BYTE COUNT, SO EXIT ;IF C=1, THEN MONITOR BUFFER IS FULL, SO UPDATE USER PARAMETERS LPTGO: .IFNZ LPMULT MOV @#PS,R2 ;SAVE THE DAMN C BIT MOVB DDUNT(R1),R4 ;MAKE A UNIT INDEX ASL R4 ;TO WORD TABLE MOV #LPTIMO,LPTIMR(R4) ;START COUNTDOWN TIMER BISB #100,@LPSTS(R4) ;AND ENABLE LPT INTERRUPT MOV R2,@#PS ;RETRIEVE THE DAMN C BIT .ENDC ;LPMULT .IFZ LPMULT MOV #LPTIMO,LPTIMR ;START COUNTDOWN TIMER BISB (PC),@#LPS ;AND ENABLE LPT INTERRUPT .ENDC ;LPMULT RTS PC LPTS02: JSR PC,LPTGO ;START THE PRINTER BCS LPTS03 ;PROCEED WITH TRANSFERRING CHARS LPTS04: JMP RTI3 ;NO MORE CHARACTERS TO MOVE ;WHEN THE LINE-PRINTER TIMES OUT (IF IT'S OFF-LINE), ;WE ENTER THE FOLLOWING ROUTINE FROM THE TIMER SERVICE LPTHNG: .IFNZ LPMULT MOV R0,R1 ;MAKE UNIT INDEX SUB #LPTIMR,R1 ;FROM DEVICE CLOCK POINTER MOV LPTDEV(R1),R1 ;GET DDB .ENDC ;LPMULT .IFZ LPMULT MOV #LPTDDB,R1 ;AND GET LPT DDB ADDRESS .ENDC ;LPMULT LPTHN1: JSR R5,CLRBUF ;REMOVE ANY SMALL BUFFERS IN USE + DDOUT+EP ;DDB ADDRESS JSR R5,IOFINI ;FINISH HIM OFF + JSLPT ;GIVE HIM HUNG DEVICE ERROR BIS #DDSTAT,(R1) ;SET HUNG FLAG FOR LPT: RTS PC ;RETURN TO TIMER SERVICE ;LINE PRINTER INTERRUPT SERVICE ;WE FEED MORE CHARACTERS TO PRINTER IF WE HAVE THEM ;IF THERE IS AN ERROR, WE GIVE USER "DATERR" ;IF PRINTER IS OFF LINE, USER GETS "HNGDEV" LPTINT: .IFNZ LPMULT MOV @#PS,-(SP) ;SAVE THE NEW STATUS .ENDC ;LPMULT JSR R5,SAVREG ;ENTERRED FROM HARD INTERRUPT .IFNZ LPMULT ;THIS CODE APPEARS ALSO AT TTYPOL MOV 6*2(SP),R3 ;GET DEV NUMBER BIC #-37-1,R3 ;MASK FROM PRIORITY WORD ASL R3 ;WORD INDEX CLR LPTIMR(R3) ;RESET TIMER MOV LPTDEV(R3),R1 ;GET DDB ADDRESS MOV LPSTS(R3),R0 ;LP STATUS REG ADDRESS .ENDC ;LPMULT .IFZ LPMULT CLR LPTIMR ;CLEAR TIME-OUT CLOCK MOV #LPTDDB,R1 ;GET LPT DDB ADDRESS MOV #LPS,R0 ;AND POINTER TO STATUS .ENDC ;LPMULT TST (R0) ;HARDWARE ERROR? BMI LPTI06 ;YES - GIVE USER "DATERR" BIC #DDSTAT,(R1) ;NOT AN ERROR SO CLEAR ERROR BIT LPTI01: TSTB (R0) ;READY FOR CHARACTER? BPL LPTI03 ;NO - START TIMING OUT JSR R5,FETCH ;GET A CHARACTER + DDOUT+FP ;FROM PRINTER BUFFER BCS LPTI02 ;BUFFER IS EMPTY MOVB R2,2(R0) ;OUTPUT THE CHARACTER .IFNZ LS CMPB @(PC)+,@-(PC) ;DELAY CMPB @(PC)+,@-(PC) ;DELAY .ENDC ;LS BR LPTI01 ;AND ON TO NEXT CHARACTER LPTI03: .IFNZ LPMULT MOV #LPTIMO,LPTIMR(R3) ;RESTART THE TIME-OUT .ENDC ;LPMULT .IFZ LPMULT MOV #LPTIMO,LPTIMR ;RESTART THE TIME-OUT .ENDC ;LPMULT TST @DDOUT+EP(R1) ;SEE IF CHAINED BNE LPTI05 ;NO RUNNING IF NOT LPTI04: JSR R5,IOFINI ;YES- RESTART JOB + JSLPT ;BY SETTING JSLPT IN JBSTAT BR LPTI05 ;RESTORE REGS AND EXIT LPTI06: .IFNZ LPMULT JSR PC,LPTHN1 ;DDB ALREADY AVAILABLE .ENDC ;LPMULT .IFZ LPMULT JSR PC,LPTHNG ;INDICATE "HUNG" PRINTER .ENDC ;LPMULT CLR (R0) ;NO MORE LPT INTERRUPTS LPTI05: .IFNZ LPMULT JSR R5,RESREG ;RESTORE WORLD TST (SP)+ ;GET RID OF STATUS RTI .ENDC ;LPMULT .IFZ LPMULT JMP RESRTI ;EXIT FROM INTERRUPT .ENDC ;LPMULT LPTI02: CLR (R0) ;NO MORE LPT INTERRUPTS BR LPTI04 ;START HIM UP WITH NO ERROR .END