Google
 

Trailing-Edge - PDP-10 Archives - dec-10-omona-u-mc9 - lptser.mac
There are 16 other files named lptser.mac in the archive. Click here to see a list.
TITLE	LPTSER - LINE PRINTER SERVICE ROUTINE FOR MULTIPLE LINE PRINTERS - V460
SUBTTL	T. N. MCMANUS /TNM/CHW/RCC/LSS   TS 11 MAR 77
	SEARCH	F,S
	$RELOC
	$HIGH
;***COPYRIGHT 1973,1974,1975,1976,1977 DIGITAL EQUIPMENT CORP., MAYNARD, MASS.***
XP VLPTSR,460		;DEFINE GLOBAL VERSION NUMBER FOR LOADER MAP

	ENTRY	LPTSER
LPTSER:
SUBTTL	CONI/CONO DEFINITIONS

;LINE PRINTER CONI BITS AND MASKS FOR LP100 AND BA10

	CI.VFU==3B1			;VFU TYPE
	   VFUPT==0			;OPTICAL
	   VFUDA==1			;DIRECT ACCESS
	   VFUNO==2			;NONE
	CI.FEN==1B2			;FEATURES ENABLED
	CI.ENV==1B3			;EVEN PARITY
	CI.CTR==7777B17			;PAGE COUNTER
	CI.INT==1B18			;INTERRUPT IF CI.FEN
	CI.NRY==1B19			;LPT NOT READY
	CI.PZR==1B20			;PAGE COUNTER ZERO
	CI.PAR==1B21			;LPT PARITY ERROR
	CI.VFE==1B22			;VFU ERROR
	CI.NLD==1B23			;VFU LOAD INHIBIT
	CI.CHR==3B25			;CHARACTER SET (BA10 ALSO)
	   CHR64==0			;64 CHARACTERS
	   CHR96==1			;96 CHARACTERS
	   CHR128==2			;128 CHARACTERS
	   CHRVAR==3			;VARIABLE (NOT BA10)
	CI.LOV==1B26			;LINE OVERFLOW (646 ONLY)
	CI.OFL==1B27			;OFF-LINE (BA10 ALSO)
	CI.BSY==1B28			;BUSY (BA10 ALSO)
	CI.DON==1B29			;DONE (BA10 ALSO)
	CI.PIB==7B32			;ERROR INTERRUPT CHN (BA10 ALSO)
	CI.PIA==7B35			;DONE INTERRUPT CHN (BA10 ALSO)

;LINE PRINTER CONO BITS AND MASKS FOR LP100 AND BA10

	CO.CIN==1B18			;CLEAR INTERRUPT
	CO.FEN==1B20			;FEATURES ENABLED
	CO.CPE==1B21			;CLEAR PARITY ERROR
	CO.SEP==1B22			;SEND EVEN PARITY
	CO.NLD==1B23			;INHIBIT VFU LOAD
	CO.PRI==1B25			;PRINTER INIT (BA10 ALSO)
	CO.LSV==1B26			;LOAD STANDARD VFU
	CO.SPC==1B27			;NEXT DATAO SETS PAGE COUNTER
	CO.SBY==1B28			;SET BUSY (BA10 ALSO)
	CO.SDN==1B29			;SET DONE (BA10 ALSO)
	CO.PIB==7B32			;ERROR INTERRUPT CHN (BA10 ALSO)
	CO.PIA==7B35			;DONE INTERRUPT CHAN (BA10 ALSO)

;SPECIAL CONI/CONO COMBOS

	CI%SKP==CI.INT+CI.LOV+CI.OFL+CI.DON  ;CONSO SKIP CHAIN MASK
	CI%SKF==CI.INT			     ;CONSO MASK WHEN LPT IF OFF
	CI%SKE==:CI%SKP-CI.DON		;CONSO/Z SKIP IF ERROR
	CO%OFF==CO.CIN+CO.FEN+CO.CPE	     ;CONO TO TURN LPT OFF
	CO%ON==CO%OFF+CO.SDN		     ;CONO TO TURN LPT ON
SUBTTL	SYMBOL DEFINITIONS

;DEVICE DEPENDENT BITS IN LH OF DEVIOS
	LPTSYN==Z(1B11)			;CRFF AFTER CLOSE HAS BEEN SENT
	LPTEND==Z(1B10)			;CLOSE UUO HAS BEEN DONE
	LPTRBL==Z(1B9)			;LPT TROUBLE DETECTED AT INTERRUPT LEVEL
	LPTOPB==Z(1B8)			;PARTIAL BUFFER ALREADY OUTPUT

;DEVICE DEPENDENT BITS IN RH OF DEVIOS
	LPTNFF==100			;SUPPRESS FREE FORM FEEDS


;LINEPRINTER HARDWARE CHARACTERISTICS (DEVHCW)
	HC.LCP==1B0			;LOWER CASE PRINTER
	HC.PGC==1B1			;LPT HAS A PAGE COUNTER
	HC.VFT==7B5			;VFU TYPE
	  .HCVTO==0			;  OPTICAL (PAPER TAPE) VFU
	  .HCVTD==1			;  DIRECT ACCESS VFU (DAVFU)
	  .HCVTN==2			;  NO VFU (HDW HANDLES LF,FF,CR)
	HC.CST==7B8			;CHARACTER SET TYPE
	  .HCC64==0			;  64 CHARACTER SET
	  .HCC95==1			;  95 CHARACTER SET
	  .HCC28==2			;  128 CHARACTER SET
	  .HCCVR==3			;  VARIABLE CHARACTER SET
	HC.CSN==0,,-1			;CHARACTER SET NAME (3 SIXBIT CHRS)
;BITS RETURNED BY DEVOP. FUNCTION 5
	LP.VFE==1B35		;VFU ERROR
	LP.VLE==1B34		;VFU LOAD ENABLED
SUBTTL	LPT ERROR REPORTING

;FIVE WORDS ARE IN EACH LINEPRINTER DDB FOR DAEMON ERROR REPORTING.

;;         !=======================================================!
;; LPTDAP: !          AOBJN POINTER TO DAEMON ERROR BLOCK          !
;;         !=======================================================!
;;	
;;	
;;	
;;         !=======================================================!
;; LPTDAE: !                  SIXBIT DEVICE NAME                   !
;;         !-------------------------------------------------------!
;;         !                  CONI WORD AT ERROR                   !
;;         !-------------------------------------------------------!
;;         !              LAST DATA WORD SENT TO LPT               !
;;         !-------------------------------------------------------!
;;         !CTR TYPE!                   RESERVED                   !
;;         !=======================================================!


	.LENAM==0			;DEVICE NAME
	.LECNI==1			;CONI AT ERROR
	.LEDAT==2			;LAST DATA WORD
	.LEFLG==3			;FLAG WORD
	  LE.CTR==77B5			;CONTROLLER TYPE
	    .LECIL==0			;ILLEGAL
	    .LECBX==1			;BA-10
	    .LECLC==2			;LP-100

	.LESIZ==4			;SIZE OF THE BLOCK
;LINE PRINTER SERVICE DISPATCH TABLE

	JRST	LPTONL		;SEE IF LPT IS ON LINE NOW
	JRST	LPTDVP		;DEVOP. UUO
	JRST	REGSIZ##	;GET BUFFER SIZE FROM DDB
	JRST	LPTINI		;INITIALIZE
	JRST	LPTHNG		;HUNG DEVICE ERROR
LPTDSP::JRST	LPTREL		;RELEASE
	JRST	LPTCLS		;CLOSE
	JRST	LPTOUT		;OUTPUT
	JRST	ILLINP##	;INPUT
SUBTTL	MONITOR-LOAD DEVICE INITIALIZATION

;LPTINI IS CALLED AT SYSTEM INITIALIZATION TIME FROM
;	IOGO IN SYSINI WITH THE DDB ADDRESS IN F

	;	1.  CLEAR THE SPECIFIED LINE PRINTER
	;	2.  DEASSIGN BOTH THE ERROR AND DONE INTERRUPT
	;	     CHANNELS FOR THAT LINE PRINTER
	;	3.  CLEAR THE SKIP CHAIN INTERRUPT MASK FLAGS
	;	     FOR THAT LINE PRINTER

	;NOTE:  THE LPTINI CODE FORCES IOGO IN SYSINI TO INVOKE
	;       LPTINI FOR EACH LINE PRINTER ON THE SYSTEM RATHER
	;       THAN FOR THE NORMAL CASE WHERE IT INVOKES THE
	;       INITIALIZATION CODE ONCE FOR EACH DISPATCH TABLE.
	;
	;       THEREFORE, THE CORRECT OPERATION OF THE LPTINI CODE
	;       IS DEPENDANT UPON THE IOGO CODE WHICH SHOULD BE:
	;
	;		PUSHJ P,DINI(P3)
	;		HRRZM P3,SAVITM

LPTINI:	PUSHJ	P,LPTREL		;GO THRU RELEASE CODE
	MOVSI	T1,-.LESIZ		;LOAD LENGTH OF ERROR BLOCK
	HRRI	T1,LPTDAE##(F)		;MAKE AN AOBJN POINTER
	MOVEM	T1,LPTDAP##(F)		;AND STORE IT
	MOVE	T1,DEVNAM(F)		;GET DEVICE NAME
	MOVEM	T1,LPTDAE##+.LENAM(F)	;SAVE TIME AT INTERRUPT LEVEL
	PJRST	CPOPJ1##		;SKIP RETURN TO FORCE CALL FOR EACH LPT
SUBTTL	OUT/OUTPUT UUO

LPTOUT:	TLO	S,IO			;NO, INDICATE OUTPUT
	PUSHJ	P,LPTOFL		;IF TROUBLE, GET IT FIXED
	XCT	LPTCNI##(F)		;DO A CONI
	ANDI	U,CI.NLD		;GET STATE OF NO LOAD BIT
	IOR	U,LPTCH##(F)		;GET CHANNEL ASSIGNMENT FROM DDB
	TRO	U,CO%ON			;SET LPT "ON"
	TRNE	S,LPTNFF		;SUPPRESS FORM FEED?
	TLZA	S,IOBEG			;YES, CLEAR IOBEG AND OUTPUT FIRST BUFFER
	TLNN	S,IOBEG			;1ST OUTPUT?
	JRST	LPTGO			;NO, CONTINUE ON NORMALLY

;HERE IF THIS IS THE FIRST OUTPUT AFTER INIT
	PUSHJ	P,LPTSTI		;SETUP INITIAL BLKO POINTER
	CAIA

;HERE TO START THE PRINTER GOING
LPTGO:	PUSHJ	P,LPTSET		;SET UP BLKO POINTER
	PUSHJ	P,SETACT##		;SET IOACT, STORE S, SET HNG CNT
	HRLI	U,CI%SKP		;GET SKIP CHAIN MASK FLAGS
	CONO	PI,PIOFF##		;TURN OFF PI TO PREVENT IMM. INT.
	XCT	LPTCNO##(F)		;SEND CONDITIONS OUT TO LPT
	HLRM	U,LPTCON##(F)		;SAVE SKIP CHAIN MASK FLAGS
	XCT	LPTCSZ##(F)		;FIND OUT IF DEVICE EXISTS
	JRST	ONPOPJ##		;DEVICE RECEIVED CONO, OK
	CONO	PI,PION##		;REENABLE ALL INTERRUPTS
	PUSHJ	P,CLRACT##		;DEVICE NON-EXISTANT OR OFF, CLEAR IOACT
	PUSHJ	P,LPTOF1		;CLEAR HUNG COUNTER AND PRINT A MESSAGE
	JRST	LPTOUT			;TRY AGAIN WHEN WE GET BACK


;HERE DURING OUTPUT UUO TO SEE IF DEVICE EXISTS
LPTOFL:	PUSHJ	P,LPTONL		;SEE IF LPT IS ON-LINE
	  SKIPA				;IT'S NOT, TELL THE USER
	POPJ	P,			;IT IS, JUST RETURN
LPTOF1:	MOVEM	S,DEVIOS(F)		;YES, SAVE S (LPTRBL OFF)
	MOVSI	T4,DEPADV		;WANT BUFFER LEFT ALONE
	IORM	T4,DEVADV(F)		;
	MOVSI	T4,DVOFLN		;MARK LPT OFF LINE
	IORM	T4,DEVCHR(F)
	PUSHJ	P,HNGSTP##		;HALT JOB & PRINT REMINDER
	MOVSI	T4,DEPADV		;LOAD "DONT ADV BUFFERS"
	ANDCAM	T4,DEVADV(F)		;AND CLEAR IT IN THE DDB
	JRST	LPTOFL			;BACK HERE ON CONT, TRY AGAIN
SUBTTL	CLOSE UUO - RELEASE UUO

;CLOSE UUO  -  WHEN A CLOSE UUO IS EXECUTED (OR CLOSE COMMAND)
;	LPTCLS IS CALLED.  LPTCLS RESETS SOME STATUS FLAGS AND
;	LIGHTS LPTEND SO THE FINAL CRFF CAN BE SETUP NEXT TIME
;	LPTOUT IS CALLED.  LPTCLS RETURNS BY BRANCHING TO "OUT"
;	SO THE LAST PARTIAL BUFFER IS OUTPUT.

LPTCLS:	TLO	S,LPTEND		;SET "CLOSE DONE"
	TLZ	S,LPTOPB+LPTSYN		;CLEAR TROUBLE BITS
	MOVEM	S,DEVIOS(F)		;STORE S
	JRST	OUT##			;AND CALL OUT FOR LAST BUFFER



;RELEASE UUO  -  WHEN A "RESET" IS DONE ON THE LPT, LPTREL IS
;	CALLED.  THE LINEPRINTER IS "TURNED-OFF" (SEE LPTOFF)
;	THE PAGE COUNTER IS TURNED OFF AND THE DDB IS CLEANED UP.

LPTREL:	PUSHJ	P,LPTTYP		;SETUP LINEPRINTER TYPE
	MOVEI	U,CO.PRI		;SET FOR PRINTER INIT
	CAIN	T2,.LECLC		;A LP100?
	MOVEI	U,CO%OFF+CO.NLD		;CLEAR AND TURN OFF THE PRINTER
	XCT	LPTCNO##(F)		;DO IT
	HLLZS	LPTCON##(F)		;AND TAKE IT OFF CONSO CHAIN
	MOVSI	T1,DEPADV		;GET "DONT ADV BUFFER" BIT
	ANDCAM	T1,DEVADV(F)		;TURN IT OFF
	TLZ	S,LPTOPB		;CLEAR THE TROUBLE BITS
	SETOM	LPTPAG##(F)		;TURN OFF PAGE COUNTER
	PUSHJ	P,LPTOFF		;CLEAR ACTIVE I/O
	PJRST	STOIOS##		;SAVE S AND RETURN


	LPTHNG==LPTREL			;HUNG DEVICE IS SAME AS RELEASE
SUBTTL	INTERRUPT ENTRY & DATA INTERRUPT ROUTINE

;ENTER HERE ON ALL INTERRUPTS
LPTINT::
IFN	FT5UUO,<
	XCT	LPXSTS##(F)		;STORE CONI STATUS IN DDB
>  ;END IFN FT5UUO
	XCT	LPTDNZ##(F)		;SKIP IF DONE FLAG IS OFF
	SKIPL	LPTPTR##(F)		;BLKO COUNT TO 0 ON LAST INT?
	JRST	LPTSVE##(F)		;YES, SAVE AC'S, RETURNS AT LPTNXT
	XCT	LPTBKO##(F)		;NO, SEND NEXT WORD FOR PRINTING
	JRST	LPTEX1##(F)		;LAST WORD SENT BUT INT PENDING
	JRST	LPTEX1##(F)		;GO RESTORE F AND RETURN



;HERE ON RETURN FROM JRST TO LPTSVE(F) WITH ACS SAVED IN CHANNEL
;	SAVE AREA.  LAST BLKO POINTER RAN OUT.  NEED TO ADVANCE
;	BUFFER-RING AND SETUP NEXT BLKO POINTER.

LPTNXT::PUSHJ	P,IOSET##		;SETUP ACS R AND S
	XCT	LPTDNO##(F)		;SKIP IF DONE IS UP
	JRST	LPTERR			;ELSE HANDLE ERROR INTERRUPT
	TLZE	S,IOBEG			;NO BUFFER ADVANCE ON 1ST OUTPUT
	JRST	LPTNX1			;YES, SETUP NEXT BLKO AND RETURN
	TLZE	S,LPTEND		;CLOSE DONE?
	JRST	LPTNX2			;YES, OUTPUT CRFF
	TLZN	S,LPTSYN		;WAS CRFF JUST OUTPUT?
	PUSHJ	P,ADVBFE##		;NO, ADVANCE TO NEXT BUFFER
	  PJRST	LPTSTP			;CANT ADVANCE, BUFFER UNAVAIL
	PUSHJ	P,SETIOD##		;ARRANGE FOR JOB TO RUN AGAIN
LPTNX1:	PUSHJ	P,LPTSET		;SET UP NEW BLKO POINTER
	PJRST	STOIOS##		;SAVE S, SET HUNG COUNT, AND JEN
LPTNX2:	TLO	S,LPTSYN		;REMEMBER CRFF SENT SO DON'T ADVANCE BUFFERS
	PUSHJ	P,LPTSTI		;SET BLKO POINTER FOR CRFF
	JRST	STOIOS##		;STORE S AND JEN
SUBTTL	ERROR INTERRUPT ROUTINE

LPTERR:	XCT	LPTCNI##(F)		;DO A CONI TO READ LPT STATUS
	TRNE	U,CI.PZR		;PAGE-ZERO?
	JRST	LPTPZR			;YES, HANDLE ZERO PAGE COUNTER
	TRNE	U,CI.VFE		;VFU ERROR?
	JRST	LPTVFE			;YES HANDLE VFU ERROR
	TRNE	U,CI.PAR		;LINE-PRINTER PARITY?
	JRST	LPTPAR			;YES, HANDLE PARITY ERROR
	TRNE	U,CI.LOV		;LINE OVERFLOW (PDP6 PRINTER)
	JRST	LPTLOV			;YES, DO IT
	TRNE	U,CI.OFL+CI.NRY		;OFF-LINE?
	JRST	LPTNOL			;YES, HANDLE IT

;HERE IF ON-LINE OR VFU ERROR CLEARED
	MOVSI	T1,DVOFLN		;OFF-LINE BIT
	TDNN	T1,DEVCHR(F)		;IS THE LPT OFF-LINE?
	JRST	LPTRTI			;NO, MUST HAVE BEEN VFU ERROR CLEARING
	ANDCAM	T1,DEVCHR(F)		;CLEAR OFF-LINE BIT
IFN FTPI,<
	PUSHJ	P,PSIONL##		;TELL USER LPT IS NOW ON-LINE
>
	TDZ	U,[-1,,CO.PIA+CO.PIB]
	JRST	LPTST1			;CLEAR INTERRUPT AND DISMISS

;HERE ON PAGE-COUNTER ZERO INTERRUPT ON LP100
LPTPZR:	MOVE	T2,LPTPAG##(F)		;GET THE PAGE COUNTER
	MOVEI	T1,IOPLE%		;LOAD THE ERROR CODE
	PJUMPE	T2,LPTIOE		;EMPTY, GIVE I/O ERROR
	PUSHJ	P,LPTSPC		;ELSE, SET IT
	JRST	LPTRTI			;CLEAR CONDITION AND RETURN
;HERE ON LINE-PRINTER PARITY ERROR ON LP100
LPTPAR:	PUSHJ	P,LPTSYR		;DO SYSERR REPORTING
	MOVEI	T1,IOPAR%		;LOAD PARITY ERROR
	PJRST	LPTIOE			;GIVE USER ERROR AND RETURN

;HERE ON LINE-PRINTER VFU ERROR ON LP100
LPTVFE:	TRNN	U,CI.NLD		;NO LOAD ON?
	JRST	LPTRTI			;NO, IGNORE THE ERROR (RESULT OF LOADING VFU)
	PUSHJ	P,LPTSYR		;TELL SYSERR
	PUSHJ	P,LPTNOL
	MOVEI	T1,IOVFE%		;VFU ERROR
	JRST	LPTIOE			;TELL THE USER ABOUT IT

;HERE TO HANDLE LINE-OVERFLOW INTERRUPT ON PDP6 PRINTER
LPTLOV:	MOVN	U,[EXP 1000001]		;DECREMENT BLKO POINTER
	ADDM	U,LPTPTR##(F)		;BACKUP THE POINTER
	MOVEI	U,[EXP 15B6+12B13]	;LOAD A CRLF
	XCT	LPTDTO##(F)		;AND PRINT IT
	POPJ	P,			;RETURN

;HERE WHEN LINE PRINTER IS OFF-LINE
LPTNOL:	MOVSI	T1,DVOFLN		;MARK LPT OFF-LINE
	IORM	T1,DEVCHR(F)		;FOR ON-LINE INTERRUPT
	TLO	S,LPTOPB		;INDICATE TROUBLE NOTICED ON INTERRUPT
	PUSHJ	P,LPTSTP		;TURN OFF LPT, CLEAR IOACT
	JRST	DEVERR##		;CAUSE UUOCON TO RETRY ON UUO LEVEL
SUBTTL	SETUP NEXT BLKO POINTER

LPTSET:	MOVEI	T1,@DEVOAD(F)		;GET ABS. ADDR. OF CURRENT BUFFER
	MOVN	T2,1(T1)		;GET NEGATIVE WORD COUNT
	HRL	T1,T2			;COMBINE NEG. WORD COUNT AND ADDR.
	TLZE	S,LPTOPB		;TROUBLE ON LAST IO?
	SKIPL	T2,LPTPTR##(F)		;YES PARTIAL BUFFER LEFT?
	AOJA	T1,LPTS1		;NO
	HRRI	T2,-1			;YES.  SET RH(T2) FOR SUB
	SUB	T2,T1			;LH(T2)=NO OF WORDS ALREADY OUT
	HLRS	T2
	ADD	T1,T2			;UPDATE POINTER BY NO OF WORDS DONE
	ADDI	T1,1			;+1 FOR IOWD TO FORM
LPTS1:	MOVEM	T1,LPTPTR##(F)		; LPTPTR:= -(WORD COUNT),(BUFF. ADDR. +1)
	POPJ	P,			; AND RETURN


;HERE TO SETUP BLKO POINTER FOR CRFF ON OPEN AND CLOSE
;	SETS BLKO POINTER FOR CRFF UNLESS THE USER HAS REQUESTED
;	SUPPRESSION.  SETS LPTDAB SINCE NEXT BLKO WILL NOT PROCESS
;	"CURRENT" BUFFER.

LPTSTI:	SETZM	LPTPTR##(F)		;CLEAR THE POINTER
	HRROI	T1,LPCRFF-1		;MAKE BLKO POINTER TO CRFF
	TRNN	S,LPTNFF		;DOES HE WANT THEM?
	MOVEM	T1,LPTPTR##(F)		;YES, GIVE THEM TO HIM
	POPJ	P,			;AND RETURN

LPCRFF:	BYTE	(7)	15,14,0		;<CR><FF>
SUBTTL	DEVOP UUO INTERFACE

;HERE ON DISPATCH FROM UUOCON
;	F=DDB
;	T1=FUNCTION

LPTDVP:	MOVSI	T2,-LPTDVL		;GET TABLE LENGTH SETUP AOBJN PTR
LPTDV1:	HLRZ	T3,LPTDVT(T2)		;GET THE FUNCTION CODE
	HRRZ	T4,LPTDVT(T2)		;GET THE DISPATCH ADDRESS
	CAMN	T1,T3			;DO CODES MATCH?
	JRST	(T4)			;YES, DISPATCH
	AOBJN	T2,LPTDV1		;NO, LOOP
	PJRST	ECOD2##			;NO MATCH, GIVE AN ERROR

LPTDVT:	XWD	1,DVLLV			;LOAD HARDWARE VFU
	XWD	2,DVENV			;ENABLE PROGRAM VFU LOAD
	XWD	3,DVDEV			;DISABLE PROGRAM VFU LOAD
	XWD	1000,DVPC		;READ PAGE COUNTER
	XWD	2000,DVPC		;SET PAGE COUNTER
	XWD	1004,DVDCS		;READ DEVICE STATUS
	LPTDVL==.-LPTDVT		;DISPATCH TABLE LENGTH

;ROUTINE TO LOAD STANDARD HARDWARE VFU
DVLLV:	PUSHJ	P,LPTSCO		;SETUP FOR CONO
	TRO	U,CO.LSV		;SET
	JRST	DVLLV1			;ENTER COMMON CODE

;DISABLE PROGRAM LOADING OF VFU
DVDEV:	PUSHJ	P,LPTSCO
	TRO	U,CO.NLD
	JRST	DVLLV1

;ENABLE FOR PROGRAM LOADING OF VFU
DVENV:	PUSHJ	P,LPTSCO
	TRZ	U,CO.NLD		;SET
DVLLV1:	LDB	T2,[POINT 2,U,1]  	;GET VFU TYPE
	CAIE	T2,VFUDA
	PJRST	ECOD5##
	XCT	LPTCNO##(F)		;OK
	PJRST	CPOPJ1##		;SKIP RETURN
;HERE TO READ OR SET THE PAGE COUNTER
DVPC:	MOVE	T3,DEVHCW(F)		;GET CHARACTERISTICS
	TLNN	T3,(HC.PGC)		;DEVICE HAVE PAGE COUNTER?
	  PJRST	ECOD11##		;NO, ERROR
	TRNE	T1,1000			;READ?
	  JRST	DVPC1			;YES
	PUSHJ	P,GETWR1##		;NO, SET T1=PAGE ARG
	  PJRST	RTM1##			;ERROR
	SETOM	LPTPAG##(F)		;ASSUME -1
	JUMPE	T1,CPOPJ1##		;RETURN
	MOVEM	T1,LPTPAG##(F)		;STORE NEW PAGE COUNTER WORD
	PUSHJ	P,LPTSPC		;SET PAGE COUNTER
	JRST	CPOPJ1##

DVPC1:	SKIPGE	LPTPAG##(F)		;ATTEMPT TO READ WHEN
	PJRST	ECOD10##		; NOT SET
	XCT	LPTCNI##(F)		;GET STATUS
	LDB	T1,[POINT 12,U,17]	;ISOLATE PAGE COUNTER
	ADD	T1,LPTPAG##(F)		;ADD IN REMAINING AMOUNT
	PJRST	STOTC1##		;RETURN WITH PAGE COUNT IN T1


;HERE TO READ LPT STATUS
DVDCS:	MOVEI	T1,0			;INITIALIZE
	PUSHJ	P,LPTONL		;READ STATUS/CHECK OFFLINE
	  TLO	T1,(DV.OFL)		;OFF LINE
	TRNE	U,CI.VFE		;VFU ERROR?
	TRO	T1,LP.VFE		;YES
	TRNN	U,CI.NLD		;CAN PROGRAM LOAD THE VFU?
	TRO	T1,LP.VLE		;YES
	PJRST	STOTC1##		;STORE STATUS/GOOD RETURN
SUBTTL	VARIOUS UTILITY ROUTINES

;SUBROUTINE TO SET THE HARDWARE PAGE COUNTER
;	IF SOFTWARE PAGE COUNTER WORD (SPCW) IS .EQ. 0, JUST RETURN
;	ELSE SET HARDWARE PAGE COUNTER TO MAX(SPCW,7777) I IF THE
;	SPCW IS NOT-NEGATIVE, DECREMENT IT BY THE AMOUNT SET.

LPTSPC:	SKIPN	LPTPAG##(F)		;IS THERE ANYTHING TO SET?
	POPJ	P,			;NO, JUST RETURN
	PUSHJ	P,LPTSCO		;SETUP FOR CONO
	TRO	U,CO.SPC		;SET THE FLAG
	XCT	LPTCNO##(F)		;DO THE CONO
	SKIPL	U,LPTPAG##(F)		;GET THE SPCW
	CAILE	U,7777			;WITHIN RANGE OF HARDWARE?
	MOVEI	U,7777			;NO, PUT WITHIN RANGE
	XCT	LPTDTO##(F)		;SET THE PAGE COUNTER
	MOVNS	U			;NEGATE THE AC
	SKIPL	LPTPAG##(F)		;DONT DECREMENT IF NOT SET
	ADDM	U,LPTPAG##(F)		;DECREMENT THE SPCW
	POPJ	P,			;AND RETURN

;SUBROUTINE TO SETUP TO DO A CONO
;	DOES A CONI, PRESERVES BUSY, DONE, PIA, PIB, FEATURES ENABLE,
;	AND VFU-NOLOAD.  RETURNS WORD IN U.

LPTSCO:	XCT	LPTCNI##(F)		;DO THE CONI
	TRZ	U,-1-CI.BSY-CI.DON-CI.NLD-CI.PIA-CI.PIB
	IORI	U,CO.FEN		;PRESERVE FEA-EN AND NOLOAD
	POPJ	P,			;AND RETURN

;SUBROUTINE TO SEE IF THE LPT IS ON LINE
LPTONL:	XCT	LPTCNI##(F)		;GET THE CONI WORD
	TRNN	U,CI.OFL		;IS IT OFF-LINE?
	AOS	(P)			;SKIP IF NOT "OFF"
	POPJ	P,			;EITHER OFF-LINE OR OFF

;HERE TO STOP THE LPT AND START THE USER.
LPTSTP:	PUSHJ	P,LPTSCO		;SETUP TO DO CONO
	TLNN	U,(CI.FEN)		;DID FEATURES ENABLED SET?
	JRST	LPTOFF			;NO, OLD LPT
	HRLI	U,CI%SKF		;CONSO MASK FOR PRINT WHEN OFF
LPTST1:	TRO	U,CO%OFF		;SET TO TURN LPT OFF
	TRZA	U,CI.BSY+CI.DON+CI.NRY+CI.OFL+CI.CHR
LPTOFF:	MOVEI	U,0			;CONO LPT, 0, NO CONSO MASK
	XCT	LPTCNO##(F)		;TURN LPT OFF
	HLRM	U,LPTCON##(F)		;SET CONSO MASK
	TRZ	S,IOACT			;CLEAR IOACT
	PUSHJ	P,SETIOD##		;START UP THE USER
	PJRST	STOIOS##		;STORE S AND RETURN
;HERE TO GIVE THE USER AN I/O ERROR AND DISMISS THE INTERRUPT.
;	ERROR CODE IN T1.
LPTIOE:	DPB	T1,PDVESE##		;STORE THE ERROR CODE
	TRO	S,740000		;SET ALL ERROR FLAGS IN S
					;FALL INTO DISMISS ROUTINE

;HERE TO CLEAR ALL INTERRUPT CONDITIONS AND DISMISS THE INTERRUPT
LPTRTI:	PUSHJ	P,LPTSCO		;SETUP THE CONO WORD
	TRO	U,CO%OFF		;CLEAR THE CONDITIONS
	XCT	LPTCNO##(F)		;DO THE CONO
	PJRST	STOIOS##		;STORE S AND RETURN

;HERE TO DO DAEMON ERROR REPORTING FOR SYSERR
LPTSYR:	XCT	LPTCNI##(F)		;GET THE CONI
	MOVEM	U,LPTDAE##+.LECNI(F)	;SAVE IT
	HRRZ	T1,LPTPTR##(F)		;GET BLKO POINTER
	MOVE	T1,(T1)			;GET THE DATA WORD
	MOVEM	T1,LPTDAE##+.LEDAT(F)	;SAVE IT
	MOVEI	T1,.ERLPT		;LOAD SYSERR TYPE
	HRLI	T1,LPTDAP##(F)		;POINTER TO AOBJN POINTER
	PJRST	DAEERR##		;CALL DAEMON

;HERE TO SETUP HARDWARE CHARACTERISTICS WORD AND DETERMINE CONTROLLER TYPE
LPTTYP:	PUSHJ	P,LPTSCO		;SETUP UP CONO WORD
	XCT	LPTCNO##(F)		;DO THE CONO
	XCT	LPTCNI##(F)		;DO A CONI
	SKIPL	DEVCHR(F)		;A LOWER CASE PRINTER?
	TDZA	T1,T1			;NO, UPPER CASE
	MOVSI	T1,(HC.LCP)		;YES, NOTE THAT
	LDB	T2,[POINT 3,U,25]	;GET CHARACTER SET TYPE
	DPB	T2,[POINT 3,T1,8]	;STORE IN HARDWARE CHARACTERISTICS
	LDB	T2,[POINT 2,U,1]	;GET VFU TYPE
	DPB	T2,[POINT 3,T1,5]	;STORE THAT
	MOVEI	T2,.LECBX		;ASSUME A BA10
	TLNN	U,(CI.FEN)		;FEATURES ENABLED IS ON IF THIS IS AN LP100
	JRST	LPTTY1			;BA10
	TLO	T1,(HC.PGC)		;LP100 HAS A HARDWARE PAGE COUNTER
	MOVEI	T2,.LECLC		;INDICATE LP100
LPTTY1:	HLLM	T1,DEVHCW(F)		;STORE HARDWARE CHARACTERISTICS
	DPB	T2,[POINT 6,LPTDAE##+.LEFLG(F),5] ;AND CONTROLLER TYPE
	POPJ	P,			;RETURN
	$LIT
	END