Google
 

Trailing-Edge - PDP-10 Archives - tops10_703_distr_bb-x140b-sb - 10,7/703mon/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 - V515
SUBTTL	T. N. MCMANUS /TNM/CHW/RCC/LSS   TS 10 SEP 85
	SEARCH	F,S
	$RELOC
	$HIGH



;THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY ONLY BE USED
;  OR COPIED IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE.
;
.CPYRT<1973,1986>
;COPYRIGHT (C) 1973,1974,1975,1976,1977,1978,1979,1980,1982,1984,1986
;BY DIGITAL EQUIPMENT CORP., MAYNARD, MASS.
;ALL RIGHTS RESERVED.
;
; DATE		LOAD	EDIT #
; ----		----	------
;
;5-JUNE-84	70221	513
;11268
;
;
XP VLPTSR,515		;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
SUBTTL	LPT ERROR REPORTING

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

;;         !=======================================================!
;; LPTDAP: !          AOBJN POINTER TO DAEMON ERROR BLOCK          !
;;         !=======================================================!
;;	
;;	
;;	
;;         !=======================================================!
;; LPTDAE: !                  SIXBIT DEVICE NAME                   !
;;         !-------------------------------------------------------!
;;         !CTR TYPE!DEV TYPE!      !N !        RETRY COUNT        !
;;         !-------------------------------------------------------!
;;         !                          PPN                          !
;;         !-------------------------------------------------------!
;;         !                     PROGRAM NAME                      !
;;         !-------------------------------------------------------!
;;         !   # WORDS IN SUB-BLOCK    !     SUB-BLOCK OFFSET      !
;;         !-------------------------------------------------------!
;;         !                  CONI WORD AT ERROR                   !
;;         !-------------------------------------------------------!
;;         !              LAST DATA WORD SENT TO LPT               !
;;         !=======================================================!


	.LENAM==0		;SIXBIT DEVICE NAME
	.LETYP==1		;CONTROLLER/DEVICE TYPE
	  LE.CTR==77B5		;CONTROLLER TYPE
	    .LECIL==.HCTUK	;ILLEGAL
	    .LECBX==.HCTBX	;BA-10
	    .LECLC==.HCTLC	;LP-100
	  LE.DTP==77B11		;DEVICE TYPE
	    .LEDLP==1		;LPT
	  LE.NRC==1B17		;NON-RECOVERABLE ERROR
	  LE.RTY==777777B35	;RETRY COUNT
	.LEPPN==2		;PPN
	.LEPGM==3		;PROGRAM NAME
	.LEPTR==4		;NUMBER WORDS FOLLOWING,,OFFSET TO FIRST
	.LECNI==5		;CONI AT ERROR
	.LEDAT==6		;LAST DATA WORD SENT TO LPT

	.LESIZ==7		;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
	MOVEI	T1,.LEDLP	;DEVICE TYPE IS LPT
	DPB	T1,[POINT 6,LPTDAE##+.LETYP(F),11] ;STORE IN TYPE WORD
	MOVE	T1,[.LESIZ-.LEPTR-1,,.LECNI] ;GET SUB-BLOCK POINTER
	MOVEM	T1,LPTDAE##+.LEPTR(F) ;SAVE IN POINTER WORD
	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
	HLL	U,LPTCH##(F)	;GET SKIP CHAIN MASK FLAGS
	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	ONPOPD##	;DEVICE RECEIVED CONO, OK
	PION			;REENABLE ALL INTERRUPTS
	PUSHJ	P,CLRACT##	;DEVICE NON-EXISTANT OR OFF, CLEAR IOACT
	PUSHJ	P,LPTSTP	;DON'T LEAVE THE CONSO MASK SETUP
	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
	CAIE	T2,.LECLC	;AN LP100?
	JRST	LPTRE1		;NO, BA10
	MOVEI	U,CO%OFF+CO.NLD	;TURN OFF THE LPT AND DISABLE LOADING THE VFU
	MOVEI	T1,CI%SKP-CI.OFL ;CONSO MASK
	HRLI	T1,CI%SKF	;SKIP ON ERRORS
	JRST	LPTRE2		;GO DO THE INITIALIZATION
LPTRE1:	MOVEI	U,CO.PRI	;ZAP THE PRINTER
	MOVEI	T1,CI%SKP	;CONSO MASK
	HRLI	T1,CI%SKE	;SKIP ON ERRORS
LPTRE2:	XCT	LPTCNO##(F)	;TURN THE LPT OFF
	HRLM	T1,LPTCH##(F)	;STORE THE CONSO MASK
	HLRM	T1,LPTDNZ##(F)	;SKIP ON ERRORS
	HLRM	T1,LPTDNO##(F)	;SKIP ON DONE
	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
	TRZ	S,IOACT		;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::
	XCT	LPXSTS##(F)	;STORE CONI STATUS IN DDB
	HRL	F,DEVIOS(F)	;GET RH FLAGS
	TLNN	F,IOACT		;JOB DOING I/O
	JRST	LPTSVE##(F)	;NO, RANDOM DONE INT
	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
	TRNN	S,IOACT		;RANDOM DONE INT?
	JRST	LPTSTP		;YES, STOP PRINTER
	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:	PUSHJ	P,RTNEVM##
	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
>
	JRST	LPTRTI		;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	;LOADING THE VFU?
	JRST	LPTRTI		;YES, IGNORE VFU ERROR
	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:	TRNN	S,IOACT		;OFF-LINE WHILE PRINTING
	JRST	LPTSTP		;NO, CATCH IT LATER
	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.
	TLZN	S,LPTOPB	;TROUBLE ON LAST IO?
	AOJA	T1,LPTS1	;NO
	SKIPL	T2,LPTPTR##(F)	;YES PARTIAL BUFFER LEFT?
	JRST	[TLNE S,IOBEG!LPTSYN ;NO, TROUBLE ON FREE FORM FEED
		 AOJA T1,LPTS1	;YES, PROCEED WITH USERS BUFFER
		 PUSHJ P,ADVBFE## ;GET NEXT SINCE WE REALLY FINSHED LAST ONE
		   JRST LPTSTP	;WAS THE LAST, SHUT DOWN THE PRINTER
		 JRST LPTSET]	;SET UP FOR NEW BUFFER
	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,DV.VFE	;YES
	TRNN	U,CI.NLD	;CAN PROGRAM LOAD THE VFU?
	TRO	T1,DV.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
	JUMPE	U,[PIOFF	;NO CONI BITS, TURN OFF PI
		   MOVEI U,1	;"FAKE" PI CHANNEL
		   XCT LPTCNO##(F) ;GIVE IT ONE (1)
		   XCT LPTCSZ##(F) ;SEE IF SOMETHING TOOK IT
		   AOS (P)	;ITS THERE AND ON-LINE
		   SETZ U,	;CLEAR PI ASSIGNMENT
		   XCT LPTCNO##(F) ;ZAP
		   JRST ONPOPD##] ;RESTORE PI SYS AND RETURN
	TRNE	U,CI.NRY!CI.OFL!CI.BSY	;IS IT OFF-LINE?
	POPJ	P,
	TLNE	U,(CI.FEN)
	TRNE	U,CI.NLD
	TRNN	U,CI.VFE
	AOS	(P)		;SKIP IF NOT "OFF"
	POPJ	P,		;EITHER OFF-LINE OR OFF

;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
	PUSHJ	P,RTNEVM##	;RETURN ANY EVM
	TRO	S,740000	;SET ALL ERROR FLAGS IN S
				;FALL INTO DISMISS ROUTINE

;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%SKP-CI.OFL	;CONSO MASK FOR PRINT WHEN OFF
	TRO	U,CO%OFF	;SET TO TURN LPT OFF
	TRZA	U,CI.DON+CI.NRY+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
	TRZE	S,IOACT		;CLEAR IOACT
	PUSHJ	P,SETIOD##	;START UP THE USER
	PJRST	STOIOS##	;STORE S AND RETURN
;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:	LDB	J,PJOBN##	;GET JOB NUMBER FROM DDB
	MOVE	T1,JBTPPN##(J)	;GET PPN OF USER
	MOVEM	T1,LPTDAE##+.LEPPN(F) ;SAVE IN ERROR REPORTING BLOCK
	MOVE	T1,JBTNAM##(J)	;GET NAME OF RUNNING JOB
	MOVEM	T1,LPTDAE##+.LEPGM(F) ;SAVE IN ERROR REPORTING BLOCK
	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,.ERHCC	;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 2,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,.HCTBX	;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,.HCTLC	;INDICATE LP100
LPTTY1:	TLO	T1,(<.HCULP>B14) ;LP05 CLASS PRINTER
	HLLM	T1,DEVHCW(F)	;STORE HARDWARE CHARACTERISTICS
	DPB	T2,[POINT 3,DEVHCW(F),11] ;STORE CONTROLLER TYPE IN DEVHCW
	DPB	T2,[POINT 6,LPTDAE##+.LETYP(F),5] ;AND CONTROLLER TYPE
	POPJ	P,		;RETURN
	$LIT
	END