Trailing-Edge
-
PDP-10 Archives
-
tops10_704_monitoranf_bb-x140c-sb
-
10,7/anf10/dnlpt.p11
There are 3 other files named dnlpt.p11 in the archive. Click here to see a list.
.SBTTL DNLPT - LINE PRINTER ROUTINES 23-OCT-87
;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED
; OR COPIED ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE.
;
;COPYRIGHT (c) DIGITAL EQUIPMENT CORPORATION
; 1976,1977,1978,1979,1980,1981,1984,1987,1988.
;ALL RIGHTS RESERVED.
VRLPT=012 ;FILE EDIT NUMBER
.IF NE LP11N
;DB.DCS STATUS BITS FOR LPT SERVICE
SLP.FE= B0 ;FATAL ERROR
SLP.FL= B1 ;OFF LINE
;OTHER LP20 STATUS BITS
SLP.8B= B14 ;8-BIT MODE (NO COMPRESSION)
SLP.SV= B15 ;SUPPRESS VFU ("IMAGE" DATA)
;DB.DVT ATTRIBUTES BITS FOR LPT SERVICE
DLP.LL= B2 ;LOWER CASE
DLP.FC= B14 ;FULL CHARACTER SET
DLP.8B= B15 ;EIGHT-BIT CHARACTER DATA (NO COMPRESSION)
;DATA FOR LINE PRINTER IS COMPRESSED AS FOLLOWS:
; 1CCCCCCC CCCCCCC IS CHARACTER
; 01XXXXXX XXXXXX IS NUMBER OF BLANKS
; 001XXXXX XXXXX IS REPETITION FOR FOLLOWING CHAR
;ATTRIBUTES FOR THE LP11-SERVICED PRINTERS
;
; LP-.LL LPT- IS LOWER CASE
; LP-FCS LPT- IS FULL CHARACTER SET (NO TAB SIMULATION,
; NO FREE CRLF [WARNING!!!], PASS ALL NON-VFE
; CHARACTERS - <ESC>, ETC.)
; LP-8BT LPT- IS AN 8-BIT-ASCII PRINTER (THEREFORE CAN'T
; SUPPORT DATA COMPRESSION)
; LP-DVU LPT- "DVU" (PRINTER TYPE - 1=LP05, 2=LN01, ETC)
;LOCATIONS IN DEVICE DEPENDENT PORTION OF LINE PRINTER DEVICE BLOCK
LP.DRG= DB.SIZ ;ADDRESS OF DATA REGISTER
LP.VFU= LP.DRG+2 ;START OF VFU FOR LPT
LP.SIZ= LP.VFU+LPTVFL ;END OF DDB FOR LPTS
;MACRO TO MAKE DEVICE DEPENDENT PORTION OF DEVICE BLOCK
.MACRO DDXGEN DEV,DV,DRQ,XBITS,XZZ
.WORD ZZZ+2 ;LP.DRG
ZZZ=ZZZ+10
.=DV'XZZ'DDB+LP.SIZ
.ENDM DDXGEN
ZZZ=LP.STS
DRESET=0
DDBGEN LPT,LP,LP11N,4,<DS.OUT> ;MAKE A DEVICE BLOCK FOR THE LPT
.MACRO DDXGEN DEV,DV,DRQ,XBITS,XZZ
.ENDM DDXGEN
;HERE TO SERVICE LPT QUEUE REQUEST
LPTSER:
.IF NE <2&LP11N>
.IF NE <1&LP11N>
MOV #LPVA2,174
MOV #LP.LVL*40,176
.ENDC;.IF NE <1&LP11N>
MOV #LPVA1,170
MOV #LP.LVL*40,172
.ENDC;.IF NE <2&LP11N>
JSR PC,LPTHOM ;HOME THE VFU TAPE
CMP #LPTMML,DB.MML(J) ;DID USER GIVE REASONABLE SIZE ?
BPL 10$ ;HE WAS SMALLER THAN WE WERE
MOV #LPTMML,DB.MML(J) ;SET OUR SIZE
10$: MOVB #DCM.AS!DCM.CF,DB.DCM(J);SET DATA CODE AND MODE
MOVB #4,DB.DVV(J) ;LP11 IS LPT CONTROLLER TYPE 4
MOV #LPTVFU,R0 ;POINT TO DEFAULT VFU TABLE
MOV DB.VFU(J),R1 ;NOW COPY THE DEFAULT VFU TAPE
MOV #LPTVFL,R2 ;NUMBER OF POSITIONS
12$: MOVB (R0)+,(R1)+ ;COPY NEXT ENTRY IN VFU
SOB R2,12$
JSR PC,DVCCFM ;SEND CONNECT CONFIRM
;NORMALLY HERE WHEN LPT DEVICE IS QUEUED
TRACE DV
JSR PC,DVXDCS ;SEND DEVICE CONTROL STATUS
JSR PC,DVXDRQ ;SEND DATA REQUESTS IF TIME TO
BIT #DS.ACT,@J ;IS DEVICE ACTIVE ?
BNE 50$ ;IF SO LEAVE IT ALONE
MOV DB.OBF(J),R0 ;IS THERE OUTPUT TO PRINT ?
BEQ 40$ ;IF NOT WAIT FOR IT
BIS #DS.ACT,@J ;SET ACTIVE FLAG
MOVB #-5,DB.TIM(J) ; FORCE THE TIMER TO RUN
BIS #LP.INE,@DB.HDW(J) ;SET INTERRUPT ENABLE
RTS PC ;RETURN
40$: BIT #DS.DIE!DS.DSC,@J ;ARE WE THROUGH WITH DEVICE ?
BEQ 50$
JSR PC,DVCCFM ;SEND DISCONNECT
50$: RTS PC
;HERE IN CASE OF DEVICE TIMEOUTS
; SHOULD ONLY HAPPEN IF LPT NOT READY
LPTTIM: BIT #DS.ACT,@J ;IS PRINTER RUNNING ?
BEQ 80$ ;NO SO JUST WAKE ROUTINE
MOVB #-3,DB.TIM(J) ;THREE SECONDS TO TRY AGAIN
TST @DB.HDW(J) ;IS PRINTER READY ?
BMI 20$ ;BRANCH IF NOT READY
BIS #LP.INE,@DB.HDW(J) ;REENABLE PRINTER INTERRUPTS
BIT #SLP.FL,DB.DCS(J) ;DID I SEND EVIL STATUS TO 10 ?
BEQ 90$ ;IF NOT WE ARE DONE
BIC #SLP.FL,DB.DCS(J) ;FLAG ONLINE
BR 70$ ;SEND ONLINE STATUS TO 10
20$: BIT #SLP.FL,DB.DCS(J) ;DID I ALREADY FLAG IT ?
BNE 90$ ;YES SO KEEP WAITING
.IF NE RPLPOL
CTYMSG LPT
.ENDC ; .IF NE RPLPOL
BIS #SLP.FL,DB.DCS(J) ;SET FLAG SAYING NOT READY
BIC #DS.ACT,@J ;CLEAR ACT SO CAN DISCONNECT
70$: BIS #DS.XDS,@J ;AND SEND STATUS
80$: JSR PC,QUEDEV ;WAKE ROUTINE
90$: RTS PC
;HERE TO HOME THE VFU TAPE
LPTHOM: MOV J,DB.VFU(J)
ADD #LP.VFU,DB.VFU(J)
RTS PC
;INTERRUPT SERVICE FOR LPT
DEVINT LP11,LP
LP11INT:TST @DB.HDW(J) ;CHECK FOR ERROR BIT
BPL 10$
BIC #LP.INE,@DB.HDW(J) ;CLEAR INTERRUPT ENABLES
JMP LPTDIS ;THEN DISMISS
10$: MOVB #-3,DB.TIM(J) ;TIMER FOR NEXT INTERRUPT
SAVE <R0,R1,R2,R3> ;SAVE THE REGISTERS
;LOOP HERE SENDING CHARACTERS TO THE LP11 CONTROLLER
LPINT0: MOVB DB.HLD(J),R0 ;IF NO CHARACTER BEING HELD,
BEQ 10$ ;THEN GO GET A NEW CHARACTER
CLRB DB.HLD(J) ;POP THE QUEUE
SWAB DB.HLD(J)
BR 11$ ;GO PRINT THE HELD CHARACTER
10$: JSR PC,LPINT1 ;ELSE GET THE NEXT CHAR
BCS LPIDIS ;DISMISS INTERRUPT IF NOTHING TO PRINT
11$: BIT #SLP.SV,DB.DCS(J) ;SUPPRESS VFU CONTROL?
BNE LPIN66 ;YES, OUTPUT CHARACTER DIRECTLY
BITB #CHRLPM,CHRTAB(R0) ;IF MOTION CHAR, DO THE MOTION
BEQ LPI.GO ;ELSE JUST SHOVE HIM THE CHAR
TSTB R0 ;CHECK FOR 8-BIT
BMI LPI.GO ;PUNT MOTION FOR NOW
MOVB LPTTBL-11(R0),R3 ;DECODE TYPE OF MOTION
BEQ LPI.HT ;BRANCH FOR HT
BPL LPI.VM ;BRANCH IF VERTICAL MOTION
DECB R3
BPL LPI.CR ;BRANCH FOR A CARRIAGE RETURN
;HERE FOR VERTICAL PAPER MOTION CHARACTER
LPI.VM: TSTB DB.COL(J) ;IF NOT AT LEFT MARGIN,
BNE LPQ.CR ;GO THERE FIRST
MOV DB.VFU(J),R1 ;GET OUR POINTER TO VFU TABLE
INC DB.VFU(J) ;ADVANCE POINTER TO VFU TABLE
TSTB @R1 ;IF NOT AT THE END OF THE TAPE,
BPL LPI.51 ;THEN "SKIP TO CHANNEL"
JSR PC,LPTHOM ;ELSE HOME THE TAPE,
BR LPI.LF ; AND PRINT A <LF>
LPI.51: BITB R3,(R1)+ ;IF ONLY ONE <LF> IS REQUIRED,
BNE LPI.LF ;PRINT IT
LPI.52: BITB R3,(R1)+ ;SEARCH THE TAPE FOR THIS CHANNEL
BEQ LPI.52 ;NOT HERE, KEEP SEARCHING
TSTB -(R1) ;IF AT END OF TAPE,
BMI LPI.FF ; PRINT A FORM FEED
; BR LPQ.LF ;ELSE "SKIP-TO-CHANNEL" VIA <LF>S
;CONTINUED ON NEXT PAGE
;CONTINUED FROM PREVIOUS PAGE
;HERE TO QUEUE THE CHAR FOR LATER AND PRINT A LINE FEED
LPQ.LF: MOVB R0,DB.HLD(J)
;HERE TO PRINT A LINE FEED
LPI.LF: MOVB #12,R0
BR LPIN66 ;GO PRINT IT
;HERE TO OUTPUT A <CR>,<LF>
LPI.CL: MOV #12,R0
;HERE TO QUEUE THE CHARACTER AND PRINT A <CR>
LPQ.CR: SWAB DB.HLD(J)
MOVB R0,DB.HLD(J)
;HERE TO PRINT A CARRIAGE RETURN
LPI.CR: MOV #15,R0
CLRB DB.COL(J) ;BACK TO COLUMN 0
BR LPIN66 ;GO PRINT IT
;HERE TO PRINT A FORM FEED
LPI.FF: MOVB #14,R0 ;MAKE CHAR A FORM FEED
MOVB #-5,DB.TIM(J) ;TIMER FOR NEXT CHAR INTERRUPT
JSR PC,LPTHOM ;HOME THE VFU TAPE
BR LPIN66
;HERE TO PRINT A HT
LPI.HT: BIT #DLP.FC,DB.DVT(J) ;IS THIS A "FULL CHAR SET" LPT?
BNE LPI.65 ;YUP, JUST PRINT THE TAB
MOVB DB.COL(J),R3 ;GET CURRENT COLUMN
INC R3
CMPB R3,DB.WID(J) ;IF THIS PUTS US AT END OF LINE
BHIS LPI.CL ;OUTPUT A <CR><<LF>
BIT #7,R3 ;IF ONE SPACE ONLY IS REQUIRED,
BEQ LPI.SP ;OUTPUT A SPACE
MOVB R0,DB.HLD(J) ;ELSE QUEUE <HT> FOR A SECOND GO AROUND
;HERE TO OUPUT A SPACE
LPI.SP: MOVB #40,R0 ;PRINT A SPACE
BR LPI.65
;HERE TO PRINT THE ORDINARY CHARS
LPI.GO: BIT #DLP.FC,DB.DVT(J) ;FULL CHARACTER SET?
BNE LPI.65 ;YES, OUTPUT CHARACTER, NO QUESTIONS
BITB #CHRLPF,CHRTAB(R0) ;IF LPT FLUSH CHAR
BNE LPINT0 ;THEN EAT IT, GO GET ANOTHER CHAR
LPI.62: BITB #CF..LC,CHRTAB(R0) ;IF UPPER CASE
BEQ LPI.64 ;THEN PRINT IT
BIT #DLP.LL,DB.DVT(J) ;IF PRINTER HAS LOWER CASE
BNE LPI.64 ;THEN NO CASE CONVERSION
BIC #40,R0 ;ELSE CONVERT CHAR TO UPPER CASE
LPI.64: CMPB DB.WID(J),DB.COL(J) ;IF NOT AT END OF LINE
BNE LPI.65 ;THEN ROOM TO PRINT CHARACTER
MOVB R0,DB.HLD(J) ;NO ROOM, QUEUE CHAR
BR LPI.CL ;THEN OUTPUT A <CR>,<LF>
LPI.65: INCB DB.COL(J) ;COUNT COLUMN
LPIN66: MOVB R0,@LP.DRG(J) ;PRINT CHARACTER
TSTB @DB.HDW(J) ;IF READY AGAIN
BMI LPINT0 ;LOOP
;ELSE DISMISS INTERRRPT
LPIDIS: RESTORE <R3,R2,R1,R0>
LPTDIS: RESTORE <J>
RTI ;DISMISS INTERRUPT
;HERE TO FETCH NEXT CHAR TO PRINT
LPINT1: BIT #SLP.8B,DB.DCS(J) ;IF CURRENLTY IN 8-BIT MODE,
BNE LPI.20 ;THEN NOTHING TO EXPAND
DECB DB.CCN(J) ;IF WE ARE EXPANDING A COMPRESSED CHAR
BMI LPI.20
MOVB DB.CHR(J),R0 ;GET CHAR
LPINT2: TSTB DB.HLD(J) ;IF NEW VFU TAPE MADE,
BEQ LPINT3
MOVB R0,DB.HLD(J) ;SAVE THE CHARACTER FOR LATER
MOV #14,R0 ;AND FORCE A FORM FEED TO ALIGN THE TAPE
LPINT3: CLC ;PRINT CHAR
RTS PC
LPI.20: CLRB DB.CCN(J) ;CLEAR THE COMPRESSED CHAR COUNT
LPI.21: JSR PC,DVGBYT ;GET NEXT BYTE FROM OUTPUT MESSAGE
BR 100$ ;BRANCH IF WE WON A DATA CHAR
BR 10$ ;BRANCH IF WE WON A MESSAGE TYPE
;END OF MSG, SO
5$: BIC #DS.ACT,@J ;NO LONGER ACTIVE
BIC #LP.INE,@DB.HDW(J) ;CLEAR INTERRUPT ENABLE
CLRB DB.TIM(J) ;CLEAR TICKER
JSR PC,QUEDEV
SEC
RTS PC
10$: DEC R0 ;BRANCH ON TYPE OF MSG
BEQ LPI.21 ;ONE IS DATA
DEC R0
BEQ LPI.21 ;TWO IS DATA
DEC R0
BEQ 30$ ;THREE IS STATUS
DEC R0
BEQ 40$ ;FOUR IS CONTROL
.IF NE DGUTS
11$:
CTYMSG NCL ;LOG THE ERROR
111$: JSR PC,DVGBYT ;EAT THE MSG
BR 111$
BR 10$ ;TRY THE NEXT MSG
BR 5$ ;SHUT THE PRINTER DOWN
.IFF
11$: TRAP
.ENDC ;.IF NE DGUTS
;HERE FOR LPT STATUS FROM THE -10 (E.G., SET/CLEAR DLP.SV)
30$: JSR PC,DVRSTS ;VANILLA STATUS PROCESSING
BR LPI.21 ;NEXT SUB/MESSAGE
;HERE FOR LPT CONTROL MESSAGE
40$: JSR PC,DVGDBY ;GET NEXT TYPE BYTE
TST R0
BEQ 50$ ;TYPE 0 IS LOAD VFU
DEC R0 ;TYPE 1 IS RESERVED TO RAM LOADING
DEC R0 ;TYPE 2 IS SET FORMS TYPE
BNE 11$ ;ANYTHING ELSE IS ILLEGAL
CMP #6,DB.OCN(J) ;RANGE-CHECK THE NAME LENGTH
BLO 11$ ;DISALLOW IF TOO LONG
MOV #DB.DFT,R2 ;OFFSET TO FORMS TYPE
ADD J,R2 ;FORM ADDRESS OF STRING STORAGE
CLR (R2) ;MAKE SURE IT STARTS CLEAR
43$: JSR PC,DVGBYT ;GET NEXT BYTE OF FORMS TYPE
BR 44$ ;STUFF IT IF STILL DATA
BR 10$ ;TRY NEXT MESSAGE TYPE
BR 5$ ;END OF MESSAGE
44$: MOVB R0,(R2)+ ;STORE THE CHARACTER
BPL 45$ ;CHECK END AT END
TST DB.OCN(J) ;REQUIRE MORE
BEQ 11$ ;ERROR IF NOT
BR 43$ ;YES, GET NEXT
45$: TST DB.OCN(J) ;REQUIRE END
BNE 11$ ;ERROR IF NOT
BR 43$ ;YES, GET NEXT
50$: CMP #LPTVFL,DB.OCN(J) ;MAKE SURE IT'LL FIT IN THE DDB
BLOS 11$ ;INCLUDING THE -1 AT THE END
INCB DB.HLD(J) ;FLAG THE CHANGE OF VFU TAPE
JSR PC,LPTHOM ;HOME THE VFU
MOV DB.VFU(J),R2
53$: JSR PC,DVGBYT ;GET NEXT BYTE FROM OUTPUT MESSAGE
BR 54$ ;BRANCH IF WE WON A DATA CHAR
BR 10$ ;BRANCH IF WE WON A MESSAGE TYPE
BR 5$ ;SHUT DOWN IF END OF MESSAGE
54$: MOVB R0,(R2)+ ;COPY TO THE VFU
MOVB #-1,(R2) ;AND SET A NEW END MARKER
BR 53$
;HERE FOR LPT DATA CHARACTER
100$: BIT #SLP.8B,DB.DCS(J) ;IF CURRENTLY IN EIGHT-BIT MODE
BNE LPINT2 ;THEN THIS BYTE IS VALID CHARACTER
TSTB R0 ;IF A COMPRESSED CHAR,
BPL 102$ ;THEN GO EXPAND IT
BIC #^C177,R0 ;OTHERWISE MASK TO 7-BIT CHARACTER
BR LPINT2 ;AND GO PRINT IT
102$: MOV R0,-(P)
BIC #^C77,(P) ;GET THE COUNT
BIT #100,R0 ;IF THIS IS COMPRESSED BLANKS,
BEQ LPT.26
MOV #40,R0 ;USE SPACE
BR LPT.27
LPT.26: JSR PC,DVGDBY ;GET THE CHAR
BIC #40,(P) ;LIMIT THE COUNT
BIC #^C177,R0 ;STRIP EXTRA BITS
LPT.27: MOVB R0,DB.CHR(J) ;SAVE CHAR WE ARE PRINTING
DEC (P) ;COUNT THIS INSTANCE
MOVB (P)+,DB.CCN(J) ;SET COMPRESSED COUNT
BR LPINT2 ;AND PRINT
LPTTBL: .BYTE 0 ;CHAR 11 = HORIZONTAL TAB
.BYTE 001 ;CHAR 12 = LF = CHANNEL 8
.BYTE 002 ;CHAR 13 = VT = CHANNEL 7
.BYTE 201 ;CHAR 14 = FORM FEED = CHANNEL 1
.BYTE 200 ;CHAR 15 = CARRIAGE RETURN
.BYTE 0 ;TABLE FILL FOR CHAR 16
.BYTE 0 ;TABLE FILL FOR CHAR 17
.BYTE 100 ;CHAR 20 = DC0 = CHANNEL 2
.BYTE 040 ;CHAR 21 = DC1 = CHANNEL 3
.BYTE 020 ;CHAR 22 = DC2 = CHANNEL 4
.BYTE 010 ;CHAR 23 = DC3 = CHANNEL 5
.BYTE 004 ;CHAR 24 = DC4 = CHANNEL 6
;SIMULATED CARRIAGE CONTROL TAPE FOR LPT
LPTVFU: .BYTE 011 ; 5-8
.BYTE 051 ; 3-5-8
.BYTE 031 ; 4-5-8
.BYTE 051 ; 3-5-8
.BYTE 011 ; 5-8
.BYTE 071 ; 3-4-5-8
.BYTE 011 ; 5-8
.BYTE 051 ; 3-5-8
.BYTE 031 ; 4-5-8
.BYTE 055 ; 3-5-6-8
.BYTE 011 ; 5-8
.BYTE 071 ; 3-4-5-8
.BYTE 011 ; 5-8
.BYTE 051 ; 3-5-8
.BYTE 031 ; 4-5-8
.BYTE 051 ; 3-5-8
.BYTE 011 ; 5-8
.BYTE 071 ; 3-4-5-8
.BYTE 011 ; 5-8
.BYTE 057 ; 3-5-6-7-8
.BYTE 031 ; 4-5-8
.BYTE 051 ; 3-5-8
.BYTE 011 ; 5-8
.BYTE 071 ; 3-4-5-8
.BYTE 011 ; 5-8
.BYTE 051 ; 3-5-8
.BYTE 031 ; 4-5-8
.BYTE 051 ; 3-5-8
.BYTE 011 ; 5-8
.BYTE 175 ; 2-3-4-5-6-8
.BYTE 011 ; 5-8
.BYTE 051 ; 3-5-8
.BYTE 031 ; 4-5-8
.BYTE 051 ; 3-5-8
.BYTE 011 ; 5-8
.BYTE 071 ; 3-4-5-8
.BYTE 011 ; 5-8
.BYTE 051 ; 3-5-8
.BYTE 031 ; 4-5-8
.BYTE 057 ; 3-5-6-7-8
.BYTE 011 ; 5-8
.BYTE 071 ; 3-4-5-8
.BYTE 011 ; 5-8
.BYTE 051 ; 3-5-8
.BYTE 031 ; 4-5-8
.BYTE 051 ; 3-5-8
.BYTE 011 ; 5-8
.BYTE 071 ; 3-4-5-8
.BYTE 011 ; 5-8
.BYTE 055 ; 3-5-6-8
.BYTE 031 ; 4-5-8
.BYTE 051 ; 3-5-8
.BYTE 011 ; 5-8
.BYTE 071 ; 3-4-5-8
.BYTE 011 ; 5-8
.BYTE 051 ; 3-5-8
.BYTE 031 ; 4-5-8
.BYTE 051 ; 3-5-8
.BYTE 011 ; 5-8
.BYTE 010 ; 5
.BYTE 010 ; 5
.BYTE 010 ; 5
.BYTE 010 ; 5
.BYTE 010 ; 5
.BYTE 010 ; 5
.BYTE -1 ;FLAG END OF TAPE
.EVEN
.ENDC;.IF NE LP11N