Google
 

Trailing-Edge - PDP-10 Archives - BB-X140B-BB_1986 - 10,7/703anf/dnlpt.p11
There are 3 other files named dnlpt.p11 in the archive. Click here to see a list.
.SBTTL	DNLPT - LINE PRINTER ROUTINES  18 DEC 84

;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ONLY BE USED
;  OR COPIED IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE.
;
;COPYRIGHT (C) 1976,1977,1978,1979,1980,1981,1984 BY DIGITAL EQUIPMENT CORP., MAYNARD, MASS.

VRLPT=011			;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>
	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
	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
	BNE	11$			;ONLY TYPE 0 (LOAD VFU) ALLOWED
	INCB	DB.HLD(J)		;FLAG THE CHANGE OF VFU TAPE
	JSR	PC,LPTHOM		;HOME THE VFU
	MOV	DB.VFU(J),R2

43$:	JSR	PC,DVGBYT		;GET NEXT BYTE FROM OUTPUT MESSAGE
	  BR	44$			;BRANCH IF WE WON A DATA CHAR
	 BR	10$			;BRANCH IF WE WON A MESSAGE TYPE
	BR	5$			;SHUT DOWN IF END OF MESSAGE

44$:	MOVB	R0,(R2)+		;COPY TO THE VFU
	MOVB	#-1,(R2)		;AND SET A NEW END MARKER
	BR	43$


;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