Google
 

Trailing-Edge - PDP-10 Archives - BB-X140B-BB_1986 - 10,7/703mon/dlpser.mac
There are 10 other files named dlpser.mac in the archive. Click here to see a list.
TITLE	DLPSER - LINEPRINTER SERVICE FOR MULTIPLE RSX-20F LINEPRINTERS - V024
SUBTTL	A. WILSON	19 FEB 86

	SEARCH	F,S,DTEPRM

	PRMMIN==017		;DTEPRM MUST BE AT LEAST THIS RECENT

   IFL VDTPRM-PRMMIN,<PRINTX ?PLEASE USE LATEST VERSION OF DTEPRM
				PASS2
				END>


	$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<1977,1986>
;COPYRIGHT (C) 1977,1978,1979,1980,1982,1984,1986
;BY DIGITAL EQUIPMENT CORP., MAYNARD, MASS.
;ALL RIGHTS RESERVED.
;

XP VDLPSR,024			;DEFINE GLOBAL VERSION NUMBER FOR LOADER MAP


	ENTRY	DLPSER

DLPSER:
SUBTTL	SYMBOL DEFINITIONS

	MAXLPT==1			;MAX LINE NUMBER (LPTS/CFE)

;DEVICE DEPENDENT BITS IN LH OF DEVIOS

	DLPSYN==Z(1B11)			;CRFF AFTER CLOSE HAS BEEN SENT
	DLPEND==Z(1B10)			;CLOSE UUO HAS BEEN DONE
	DLPOPB==Z(1B9)			;PARTIAL BUFFER ALREADY OUTPUT
	DLPRDS==Z(1B8)			;REQUESTING DEVICE STATUS FROM FRONT-END

;DEVICE DEPENDENT BITS IN RH OF DEVIOS

	DLPNFF==100			;SUPPRESS FREE CRFF



;LPT SPECIFIC STATUS BITS FROM RSX-20F

	DL.PGZ==1B35			;PAGE COUNTER PASSED ZERO
	DL.RCI==1B34			;CHARACTER INTERRUPT (FROM RAM)
	DL.VFE==1B33			;VFU ERROR--PAPER REALIGNMENT REQUIRED
	DL.LER==1B32			;ERROR FINDING/READING VFU/RAM FILE
	DL.OVF==1B31			;PRINTER HAS OPTICAL (NOT DA) VFU
	DL.RPE==1B30			;RAM PARITY ERROR--RELOAD REQUIRED
SUBTTL	DISPATCH TABLES

;UUOCON DISPATCH TABLE FOR RSX-20F LINEPRINTER(S)

	JRST	DLPONL			;SEE IF LPT ON-LINE NOW
	JRST	DLPDVP			;DEVOP. UUO
	JRST	REGSIZ##		;GET BUFFER SIZE FROM DDB
	JRST	DLPINI			;INITIALIZATION
	JRST	DLPHNG			;HUNG DEVICE ERROR
RLPDSP::JRST	DLPREL			;RELEASE
	JRST	DLPCLS			;CLOSE
	JRST	DLPOUT			;OUT/OUTPUT
	JRST	ILLINP##		;IN/INPUT



;DTESER DISPATCH TABLE FOR LPT

	CPOPJ##				;(-1)INTERNAL FUNCTION FOR TO-10 MESSAGE RUINED
DLPDSP::EATMSG##			;(0)
	EATMSG##			;(1)
	EATMSG##			;(2)
	EATMSG##			;(3)
	EATMSG##			;(4)
	EATMSG##			;(5)
	EATMSG##			;(6)
	DLPTKS				;(7)TAKE DEVICE STATUS
	EATMSG##			;(10)
	EATMSG##			;(11)
	EATMSG##			;(12)
	EATMSG##			;(13)
	EATMSG##			;(14)
	EATMSG##			;(15)
	EATMSG##			;(16)
	DLPACK				;(17)ACK
	EATMSG##			;(20)
	EATMSG##			;(21)
	EATMSG##			;(22)
	DLPHLA				;(23)HERE ARE LINE ALLOCATIONS
	EATMSG##			;(24)
	DLPAAL				;(25)ACK ALL
	EATMSG##			;(26)
	EATMSG##			;(27)
	EATMSG##			;(30)
	EATMSG##			;(31)
	EATMSG##			;(32)
	EATMSG##			;(33)
	EATMSG##			;(34)
SUBTTL	MONITOR-LOAD DEVICE INITIALIZATION

;DLPINI IS CALLED AT SYSTEM INITIALIZATION TIME FROM IOGO IN SYSINI WITH
; THE DDB ADDRESS IN F.  DLPINI FORCES IOGO TO INVOKE DLPINI FOR EACH RSX-20F
; LINEPRINTER 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 DLPINI IS DEPENDENT ON THE IOGO CODE WHICH SHOULD BE:
;
;	PUSHJ	P,DINI(P3)
;	HRRZM	P3,SAVITM

DLPINI:	PUSHJ	P,DLPREL		;GO THROUGH RELEASE CODE
	PJRST	CPOPJ1##		;SKIP RETURN TO FORCE CALL FOR EACH LPT
SUBTTL	OUT/OUTPUT UUO

;HERE FROM UUOCON ON OUT OR OUTPUT UUO

DLPOUT:	TLO	S,IO			;INDICATE OUTPUT
	PUSHJ	P,DLPOFL		;IF TROUBLE, GET IT FIXED
	TLZE	S,IOBEG			;FIRST OUTPUT?
	PUSHJ	P,DLPSFF		;YES, SEE ABOUT SENDING FREE CRFF
	  JFCL
	TLZE	S,DLPOPB		;PARTIAL BUFFER ALREADY OUTPUT?
DLPOU0:	JRST	[SKIPLE DEVCTR(F)	;YES, BUT WERE WE DONE WITH IT
		 JRST DLPOU1		;NO, MORE TO PRINT
		 PUSHJ P,ADVBFE##	;GET NEXT BUFFER HERE
		 PJRST DLPSTP		;NO MORE, SHUT DOWN PRINTER
		 JRST .+1]		;RETURN INLINE FOR NEW BUFFER
	MOVE	T1,DEVOAD(F)		;PICK UP BUFFER ADDRESS
	HRRZ	T1,1(T1)		;PICK UP WORD COUNT
	MOVEM	T1,DEVCTR(F)		;SET DEVCTR UP WITH WORD COUNT
	SETZM	DLPSNT##(F)		;NO DATA FROM THIS BUFFER YET
	JUMPE	T1,DLPOU0		;GET NEXT IF NO DATA
DLPOU1:	PUSHJ	P,DLPSND		;START DATA TRANSFER
	PJRST	SETACT##		;SET IOACT, STORE S, SET HUNG COUNT, RETURN



;HERE DURING OUTPUT UUO TO SEE IF LPT ON-LINE
;ARGS:	F/DDB ADDRESS
;	S/DEVIOS WORD FROM DDB
;CALL:	PUSHJ	P,DLPOFL
;	RETURN HERE WHEN ON-LINE (BOTHERING USER IF NECESSARY TO GET IT ON-LINE)

DLPOFL:	PUSHJ	P,DLPONL		;SEE IF LPT ON-LINE
	  JRST	DLPOF1			;IT'S NOT--TELL THE USER
	POPJ	P,			;IT IS--RETURN

DLPOF1:	MOVEM	S,DEVIOS(F)		;SAVE S
	MOVSI	T1,DEPADV
	IORM	T1,DEVADV(F)		;LEAVE BUFFERS ALONE
	MOVSI	T1,DVOFLN
	IORM	T1,DEVCHR(F)		;MARK DDB OFF-LINE
	PUSHJ	P,HNGSTP##		;HALT JOB AND COMPLAIN
	MOVSI	T1,DEPADV
	ANDCAM	T1,DEVADV(F)		;CLEAR BIT ON RETRY
	JRST	DLPOFL			;TRY AGAIN
;ROUTINE TO SEE IF LPT ON-LINE
;ARGS:	F/DDB ADDRESS
;CALL:	PUSHJ	P,DLPONL
;	  RETURN HERE IF OFF-LINE
;	RETURN HERE IF ON-LINE

DLPONL:	MOVEI	T1,EM.OFL+EM.NXD	;GET RSX-20F OFF-LINE BITS
	TDNN	T1,DEVSTS(F)		;OFF-LINE?
	AOS	(P)			;NO--SKIP RETURN FOR ON-LINE
	POPJ	P,			;YES--NON-SKIP RETURN



;HERE TO SEND INITIAL/FINAL CRFF IF NECESSARY
;ARGS:	F/DDB ADDRESS
;	S/DEVIOS WORD FROM DDB
;CALL:	PUSHJ	P,DLPSFF
;	  RETURN HERE IF CRFF NOT SENT
;	RETURN HERE IF SENT

DLPSFF:	TRNE	S,DLPNFF		;NEED TO SEND CRFF?
	POPJ	P,			;NO--NON-SKIP RETURN
	PUSHJ	P,SAVE4##		;SAVE P1-P4
	MOVE	P4,[POINT 7,LPCRFF]	;POINT TO CRFF
	MOVEI	T1,1			;ONLY 1 WORD
	PUSHJ	P,DLPSOU		;SEND THIS STRING
	PJRST	CPOPJ1##		;SKIP RETURN

LPCRFF:	BYTE	(7)	15,14,0		;CR,FF,0
SUBTTL	CLOSE AND RELEASE UUO'S

;HERE FROM UUOCON ON CLOSE UUO

DLPCLS:	TLO	S,DLPEND		;SET "CLOSE DONE"
	TLZ	S,DLPOPB+DLPSYN		;CLEAR TROUBLE AND SYNC BITS
	MOVEM	S,DEVIOS(F)		;STORE S
	JRST	OUT##			;TAKE CARE OF LAST BUFFER



;HERE FROM UUOCON ON RELEASE UUO

DLPHNG:					;HUNG DEVICE IS SAME AS RELEASE
DLPREL:	MOVEI	T1,.HCULP		;LP05 CLASS PRINTER
	DPB	T1,[POINT 3,DEVHCW(F),14] ;SAVE IN DDB
	MOVSI	T1,DEPADV		;GET "DON'T ADVANCE BUFFER" BIT
	ANDCAM	T1,DEVADV(F)		;TURN IT OFF IN DDB
	TLZ	S,DLPOPB		;CLEAR PARTIAL BUFFER BIT
	PJRST	DLPSTP			;CLEAR ACTIVE I/O
SUBTTL	ACK MESSAGE ("OUTPUT DONE") PROCESSING

;HERE FROM DTESER ON ACK FOR LPT

DLPACK:	SUBI	P3,2			;ACCOUNT FOR TWO BYTES/ARGUMENT
	JUMPL	P3,CPOPJ##		;RETURN WHEN ARGUMENT COUNT EXHAUSTED
	ILDB	T1,P4			;GET UNIT NUMBER
	IBP	P4			;MOVE PAST UNUSED BYTE
	CAILE	T1,MAXLPT		;OUT OF RANGE?
	JRST	DLPACK			;YES, IGNORE IT
	HLRZ	F,P1			;GET CPU NUMBER
	MOVEI	F,@LPDTDV##(F)		;GET DDB ADDRESS
	JUMPE	F,DLPACK		;FAILED--LOOP FOR NEXT ARGUMENT
	PUSHJ	P,DLPDON		;TREAT THIS AS DONE INTERRUPT
	JRST	DLPACK			;LOOP FOR MORE ARGUMENTS



;HERE FROM DTESER ON ACK ALL FOR LPT

DLPAAL:	MOVEI	F,FL0DDB##		;GET ADDRESS OF FIRST DLPT DDB
	MOVEI	P4,DLPTN##		;GET NUMBER OF DLPT'S
DLPAA1:	HRRZ	T1,DLPDUX##(F)		;GET THE DTE INDEX
	CAMN	P1,LPCPDT##(T1)		;THIS LPT ON THIS DTE?
	PUSHJ	P,DLPDON		;YES--TREAT THIS AS DONE INTERRUPT
	HLRZ	F,DEVSER(F)		;ON TO THE NEXT DDB
	SOJG	P4,DLPAA1		;LOOP IF MORE UNITS TO DO
	POPJ	P,			;RETURN
SUBTTL	HERE ARE LINE ALLOCATIONS PROCESSING

;HERE FROM DTESER ON HERE ARE LINE ALLOCATIONS FOR LPT

DLPHLA:	SUBI	P3,2			;ACCOUNT FOR TWO BYTES/ARGUMENT
	JUMPL	P3,CPOPJ##		;RETURN WHEN ARGUMENT COUNT EXHAUSTED
	ILDB	T2,P4			;GET ALLOCATION
	ILDB	T1,P4			;GET LINE NUMBER
	CAILE	T1,MAXLPT		;OUR OF RANGE?
	JRST	DLPHLA			;YES, IGNORE THIS LINE
	HLRZ	F,P1			;GET CPU NUMBER
	MOVEI	F,@LPDTDV##(F)		;GET DDB ADDRESS
	JUMPE	F,DLPHLA		;FAILED -- LOOP FOR NEXT ARGUMENT
	MOVEM	T2,DLPMLA##(F)		;SAVE LINE ALLOCATION
	JRST	DLPHLA			;LOOP FOR MORE
SUBTTL	OUTPUT DONE PROCESSING

;HERE IF RSX-20F ACKNOWLEDGED AN ACTIVE LINEPRINTER
;ARGS:	F/DDB ADDRESS
;	S/LPT STATUS WORD (DDB DEVIOS)
;CALL:	PUSHJ	P,DLPDON
;	RETURN HERE

DLPDON:	PUSHJ	P,IOSET##		;SET UP THE REST OF THE REGS
	MOVE	T1,DLPMLA##(F)		;PICK UP MAX ALLOCATION
	MOVEM	T1,DLPRLA##(F)		;THIS IS CURRENT ALLOCATION
	TRNN	S,IOACT			;OUTPUT ACTIVE?
	  POPJ	P,			;NO, RETURN
	SKIPLE	DEVCTR(F)		;OUTPUT REMAINING FROM PREVIOUS BUFFER?
	JRST	DLPDN1			;YES--WORK ON THAT BUFFER SOME MORE
	TLZE	S,DLPEND		;CLOSE DONE?
	JRST	DLPDN2			;YES--SEE ABOUT FINAL CRFF
	TLZN	S,DLPSYN		;NO--CRFF JUST OUTPUT?
DLPDN0:	PUSHJ	P,ADVBFE##		;NO--ADVANCE TO NEXT BUFFER
	  PJRST	DLPSTP			;CAN'T--SHUT DOWN LPT
	PUSHJ	P,SETIOD##		;ARRANGE FOR JOB TO RUN AGAIN
	MOVE	T1,DEVOAD(F)		;PICK UP BUFFER ADDRESS
	HRRZ	T1,1(T1)		;PICK UP WORD COUNT
	MOVEM	T1,DEVCTR(F)		;SET DEVCTR UP WITH WORD COUNT
	SETZM	DLPSNT##(F)		;NO, THIS BUFFER IS DONE
	JUMPE	T1,DLPDN0		;IGNORE EMPTY BUFFERS
DLPDN1:	PUSHJ	P,DLPSND		;START UP NEXT OUTPUT
	PJRST	STOIOS##		;SAVE S, SET HUNG COUNT, RETURN

DLPDN2:	PUSHJ	P,DLPSFF		;SEE ABOUT SENDING CRFF
	  PJRST	DLPSTP			;NOT SENT--SHUT DOWN LPT
	TLO	S,DLPSYN		;REMEMBER CRFF SENT SO DON'T ADVANCE BUFFERS
	PJRST	STOIOS##		;SAVE S, SET HUNG COUNT, RETURN



;HERE TO STOP LPT AND START USER

DLPSTP:	TRZ	S,IOACT			;CLEAR IOACT
	MOVEM	S,DEVIOS(F)		;SAVE DEVIOS
	PUSHJ	P,SETIOD##		;START UP THE USER
	PJRST	RTEVMO##		;RETURN ANY EVM
SUBTTL	SEND LPT DATA TO FRONT-END

;HERE TO SEND OUTPUT DATA TO RSX-20F LPT FROM USER BUFFER
;ARGS:	F/DDB ADDRESS
;CALL:	PUSHJ	P,DLPSND
;	RETURN HERE

DLPSND:	PUSHJ	P,SAVE4##		;SAVE P1-P4
	MOVE	P4,DEVPTR(F)		;PICK UP DATA ADDRESS
	ADDI	P4,2			;POINT TO FIRST DATA WORD
	ADD	P4,DLPSNT##(F)		;OFFSET POINTER TO REMAINING DATA
	HRLI	P4,440700		;ASSUME 7 BIT BYTES
	LDB	T1,PIOMOD##		;PICK UP I/O MODE
	CAIN	T1,BYTMOD		;REALLY BYTE MODE?
	HRLI	P4,441000		;YES, 8 BIT BYTES
	HRRZ	T1,DEVCTR(F)		;PICK UP REMAINING WORD COUNT
	PUSHJ	P,DLPSOU		;SEND THIS STRING
	ADDM	T1,DLPSNT##(F)		;ACCUMULATE WORD COUNT
	MOVNS	T1			;NEED NEGATIVE OF COUNT
	ADDM	T1,DEVCTR(F)		;DECREMENT REMAINING COUNT
	POPJ	P,			;DONE

;HERE TO SEND STRING OUTPUT DATA TO RSX-20F LPT
;ARGS:	F/DDB ADDRESS
;	T1/WORD COUNT
;	P4/BYTE POINTER
;CALL:	PUSHJ	P,DLPSOU
;	RETURN HERE WITH WORDS SENT IN T1

DLPSOU:	LDB	T3,[POINT 6,P4,11]	;PICK UP BYTE SIZE
	MOVEI	T2,44			;36 BITS/WORD
	IDIVI	T2,(T3)			;NOW GOT BYTES/WORD
	MOVE	T3,DLPRLA##(F)		;PICK UP REMAINING ALLOCATION
	IDIVI	T3,(T2)			;CONVERT TO WORDS
	CAMLE	T1,T3			;SMALLER THAN STRING LENGTH?
	MOVE	T1,T3			;YES, USE ALLOCATION
	JUMPLE	T1,CPOPJ##		;RETURN IF NO ALLOCATION LEFT
	MOVE	P3,DLPDUX##(F)		;P3 IS UNIT #,,DLP DTE INDEX
	MOVE	P1,LPCPDT##(P3)		;P1 IS CPU #,,DTE #
	MOVE	P2,[.EMLPT,,EM.IND+.EMSTR] ;OUTPUT INDIRECT STRING TO LPT
	IMULI	T2,(T1)			;GET STRING LENGTH IN BYTES
	HRR	P3,T2			;PUT INTO ARG LIST
	MOVNS	T2			;NEGATE
	ADDM	T2,DLPRLA##(F)		;UPDATE REMAINING ALLOCATION
	PUSH	P,S			;SAVE S
	PUSH	P,T1			;SAVE WORD COUNT
	MOVEI	S,0			;NO POST ADDRESS
	PUSHJ	P,DTEQUE##		;QUEUE THE REQUEST
	  JFCL				;FAILED--WAIT FOR HUNG TIME-OUT OR ACK ALL
	POP	P,T1			;RESTORE WORD COUNT
	POP	P,S			;RESTORE S
	POPJ	P,			;DONE
SUBTTL	TAKE DEVICE STATUS FROM FRONT-END

;HERE FROM DTESER TO TAKE LPT STATUS FROM FRONT-END (DTESER ALREADY RECEIVED IT)

DLPTKS:	PUSHJ	P,SETALL		;SET UP NECESSARY ACS
	  PJRST	EATMSG##		;COULDN'T--IGNORE THIS MESSAGE
	ILDB	T1,P4			;GET FIRST STATUS (GENERAL) BYTE
	ILDB	T2,P4			;GET SECOND (LPT) BYTE
	HRL	T1,T2			;PUT THEM TOGETHER
	MOVEM	T1,DEVSTS(F)		;SAVE COMBINED STATUS BITS
	MOVEI	T2,.HCVTO		;CODE FOR OPTICAL VFU
	TLNE	T1,DL.OVF		;IS IT OPTICAL TYPE
	DPB	T2,[POINT 3,DEVHCW(F),5] ;YES, SAVE IN CHARACTERISTICS WORD
	MOVEI	T2,IOPAR%		;CODE FOR RAM ERROR
	TLNE	T1,DL.RCI+DL.RPE	;ANY RAM PROBLEMS?
	JRST	DLPIOE			;YES
	MOVEI	T2,IOVFE%		;NO, CODE FOR VFU PROBLEM
	TLNE	T1,DL.VFE		;VFU PROBLEM?
	JRST	DLPIOE			;YES
	MOVEI	T2,IODER%		;CODE FOR DEVICE ERROR
	TRNN	T1,EM.FER		;FATAL ERROR (ALL RETRIES FAILED)
	JRST	DLPTK2			;NO, GO CHECK FOR OFFLINE
DLPIOE:	DPB	T2,PDVESE##		;STORE THE CODE
	TRO	S,740000		;SET ALL ERROR FLAGS IN S
	TRO	T1,EM.OFL		;DECLARE PRINTER OFF-LINE
	PUSH	P,S			;SAVE STATUS
	PUSH	P,T1			;SAVE STATUS FOR A MOMENT
	PUSHJ	P,[PUSHJ P,SAVE4	;SAVE SOME REGS
		   HRRI P2,.EMFLO	;FLUSH ANY REMAINING OUTPUT
		   HRRI P3,0		;NO DATA
		   SETZB P4,S		;NO POST ROUTINE
		   PJRST DTEQUE##]	;SEND MESSAGE TO CFE
	JFCL				;IGNORE FAILURE
	POP	P,T1			;GET BACK STATUS
	POP	P,S			;RESTORE S
;HERE TO DEAL WITH OFF-LINE OR ON-LINE

DLPTK2:	MOVE	T2,DEVCHR(F)		;PICK UP OLD STATUS
	MOVSI	T3,DVOFLN		;OFF-LINE BIT
	TRNE	T1,EM.OFL!EM.NXD	;DEVICE THERE?
	  JRST	DLPTK3			;NO
	ANDCAM	T3,DEVCHR(F)		;ASSUME ON-LINE
IFN FTPI,<
	TLNE	T2,DVOFLN		;WAS IT OFF-LINE?
	PUSHJ	P,PSIONL##		;YES, TELL USER IT IS BACK AGAIN
>
	PJRST	EATMSG##		;DONE WITH THIS MESSAGE

DLPTK3:	MOVEM	S,DEVIOS(F)		;MAKE SURE ERROR BITS ARE SAVED
	TRNN	S,IOACT			;PRINTER ACTIVE NOW?
	PJRST	EATMSG##		;NO, DONE WITH THIS MESSAGE
	IORM	T3,DEVCHR(F)		;NOTE DEVICE OFF-LINE
	TLNN	T1,DL.RCI+DL.RPE+DL.VFE	;ANY ERRORS IN LPT?
	TLO	S,DLPOPB		;NO, INDICATE MINOR TROUBLE NOTICED
	PUSHJ	P,DLPSTP		;STOP LPT AND START USER
	PUSHJ	P,DEVERR##		;CAUSE UUOCON TO RETRY ON UUO LEVEL
	PJRST	EATMSG##		;DONE
SUBTTL	DEVOP. UUO INTERFACE

;HERE FROM UUOCON ON DEVOP. UUO
;ARGS:	F/DDB ADDRESS
;	T1/FUNCTION
;CALL:	PUSHJ	P,DLPDVP
;	  RETURN HERE ON ERROR OR INVALID FUNCTION
;	RETURN HERE ON SUCCESS, T1 CONTAINING ANY ARGUMENT RETURNED

DLPDVP:	MOVSI	T2,-DLPDVL		;MAKE AOBJN POINTER WITH TABLE LENGTH
DLPDV1:	HLRZ	T3,DLPDVT(T2)		;GET THE FUNCTION CODE
	HRRZ	T4,DLPDVT(T2)		;GET DISPATCH ADDRESS
	CAMN	T1,T3			;CODES MATCH?
	JRST	(T4)			;YES--DISPATCH
	AOBJN	T2,DLPDV1		;NO--TRY NEXT ONE
	PJRST	ECOD2##			;NO MATCH--ERROR

DLPDVT:	11,,DVPRAM			;LOAD LPT RAM
	12,,DVPVFU			;LOAD LPT VFU
	1004,,DVPSTS			;READ DEVICE STATUS
	DLPDVL==.-DLPDVT		;DISPATCH TABLE LENGTH

;HERE TO READ LPT STATUS

DVPSTS:	MOVEI	T1,0			;ZERO INITIAL STATUS
	MOVE	T2,DEVSTS(F)		;GET STATUS BITS SENT FROM FRONT-END
	TRNE	T2,EM.OFL+EM.NXD	;OFF-LINE?
	TLO	T1,(DV.OFL)		;YES
	TLNE	T2,DL.VFE		;VFU ERROR?
	TRO	T1,DV.VFE		;YES
	PJRST	STOTC1##		;STORE STATUS, SKIP RETURN
;ROUTINE TO LOAD LPT RAM/VFU
;ARGS:	F/DDB ADDRESS
;	M/USER ARGUMENT AREA ADDRESS
;CALL:	SAVE P1-P4
;	PUSHJ	P,DVPXXX		WHERE XXX IS RAM OR VFU
;	  RETURN HERE IF UNSUCCESSFUL
;	RETURN HERE IF SUCCESSFUL

DVPRAM:	TDZA	P2,P2			;REMEMBER LOADING RAM
DVPVFU:	MOVEI	P2,1			;REMEMBER LOADING VFU
	PUSHJ	P,DLPOFL		;MUST BE ON-LINE
	PUSHJ	P,GETWR1##		;GET RAM/VFU BYTE-COUNT ARG FROM USER
	  PJRST	ECOD3##			;ERROR
	JUMPLE	T1,ECOD3##		;ERROR IF BYTE COUNT NOT GREATER THAN ZERO
	MOVE	P3,T1			;REMEMBER BYTE COUNT
	ADDI	T1,3(P2)		;FUDGE REMAINDER
	IDIVI	T1,4(P2)		;MAKE T1 A WORD-COUNT
	CAILE	T1,^D128		;WITHIN REASON?
	PJRST	ECOD3##			;NO--OUT-OF-RANGE ERROR
	MOVN	P1,T1			;YES--GET -WC
	HRLZS	P1			;MAKE LH OF AOBJN POINTER
	PUSHJ	P,GETWR1##		;GET ADDRESS OF RAM/VFU DATA BLOCK
	  PJRST	RTM1##			;COULDN'T--GIVE ADDRESS-ERROR RETURN
	HRRI	M,-1(T1)		;PREPARE FOR CALL TO GETWR1
	MOVEI	T2,^D40			;GET 160 WORDS OF MONITOR FREE CORE
	PUSHJ	P,GET4WD##		; IN 4-WORD BLOCKS
	  PJRST	ECOD3##			;NOT REALLY OUT OF RANGE, BUT ...
	MOVE	P4,T1			;REMEMBER ADDRESS OF FREE CORE
	HRR	P1,T1			;FINISH BUILDING AOBJN POINTER
	JUMPN	P2,DVPVF1		;GO GET VFU DATA
DVPMOV:	PUSHJ	P,GETWR1##		;GET WORD FROM USER
	  PJRST	[PUSHJ	P,DVPGIV	;ERROR--GIVE BACK FREE CORE
		 PJRST	RTM1##]		;GIVE ADDRESS-ERROR RETURN
	MOVEM	T1,(P1)			;SAVE WORD IN OUR BUFFER AREA
	AOBJN	P1,DVPMOV		;LOOP IF MORE DATA TO MOVE
	HRLI	P4,(POINT 18,)		;P4 IS BYTE POINTER
	MOVE	P2,[.EMLPT,,EM.16B+EM.IND+.EMLDR] ;FUNCTION WORD
	PUSH	P,P3			;SET UP THE BYTE COUNT
	JRST	DVPCMN			;GO TO COMMON PART
DVPVF1:	HRLI	P1,(POINT 8,0)		;MAKE OUTPUT BYTE POINTER
	MOVE	P2,P3			;PICK UP BYTE COUNT
	PUSHJ	P,DVPVB1		;GET A VFU BYTE
	CAIN	T2,25			;STANDARD START CODE?
	  MOVEI	T2,356			;YES
	CAIN	T2,26			;6 LPT?
	  MOVEI	T2,354			;YES
	CAIN	T2,27			;8 LPT?
	  MOVEI	T2,355			;YES
	SKIPA				;ALREADY HAVE FIRST BYTE
DVPVF2:	PUSHJ	P,DVPVFB		;GET ANOTHER BYTE
	PUSH	P,T2			;BYTES NEED TO SWAP
	SOJG	P2,DVPVF3		;COUNT IT
	SETZ	T2,			;PUT A ZERO BYTE FOR LAST
	JRST	DVPVF4			;GO STORE IT
DVPVF3:	PUSHJ	P,DVPVFB		;GET NEXT BYTE
	CAIN	T2,126			;STOP CODE?
	  MOVEI	T2,357			;YES
DVPVF4:	IDPB	T2,P1			;PUT BYTE INTO OUTPUT
	POP	P,T2			;GET SWAPPED BYTE
	IDPB	T2,P1			;PUT IT INTO OUTPUT ALSO
	SOJG	P2,DVPVF2		;LOOP THRU WHOLE VFU
	HRLI	P4,(POINT 16,)		;SET UP BYTE POINTER FOR DTESER
	MOVE	P2,[.EMLPT,,EM.16B+EM.IND+.EMLDV] ;SET UP FUNCTION WORD
	PUSH	P,P3			;SAVE ON STACK NOW
DVPCMN:	MOVE	P3,DLPDUX##(F)		;P3 IS UNIT #,,DLP DTE INDEX
	MOVE	P1,LPCPDT##(P3)		;GET CPU #,,DTE #
	PUSH	P,S			;SAVE S
	HRRZ	S,P4			;SET S TO BUFFER ADDR
DVPPRT:	MOVEI	T1,300			;DO MAX OF 300 BYTE TRANSFERS
	CAML	T1,-1(P)		;FEWER BYTES REMAINING?
	MOVE	T1,-1(P)		;YEP, USE SMALLER NUMBER
	HRR	P3,T1			;PUT COUNT INTO MESSAGE
	MOVNS	T1			;CALCULATE REMAINING DATA
	ADDM	T1,-1(P)
	SKIPG	-1(P)			;LAST MESSAGE?
	HRLI	S,DVPGIV		;YES, GIVE BACK CORE ON THIS ONE
	PUSHJ	P,DTEQUE##		;YES--QUEUE THE REQUEST
	  PJRST	DLPERR			;ERROR--SAY DEVICE OFF-LINE
	ADDI	P4,300/4		;POINT TO NEXT PART OF STRING
	SKIPE	-1(P)			;DONE?
	JRST	DVPPRT			;NO, GO DO THE NEXT PART
	PUSHJ	P,DLPEOF		;SEND EOF TO TERMINATE LOAD FUNCTION
	  PJRST	DLPER1			;ERROR--SAY DEVICE OFF-LINE
	POP	P,S			;RESTORE S
	POP	P,(P)			;THROW AWAY COUNT
	PJRST	CPOPJ1##		;SKIP RETURN

DVPVFB:	TLNE	T3,760000		;MORE DATA STILL IN WORD?
	JRST	DVPVB2			;YES, GO GET IT
DVPVB1:	PUSHJ	P,GETWR1##		;NO, GET NEXT WORD
	  PJRST	[POP P,(P)		;POP OFF RETURN
		 PUSHJ	P,DVPGIV	;GIVE BACK CORE
		 PJRST	RTM1##]		;GIVE ADDRESS-ERROR RETURN
	MOVE	T3,[POINT 7,T1]		;RESET BYTE POINTER
DVPVB2:	ILDB	T2,T3			;GET A BYTE
	POPJ	P,			;RETURN

DLPERR:	PUSHJ	P,DVPGIV		;GIVE BACK FREE CORE
DLPER1:	POP	P,S			;RESTORE S
	POP	P,(P)			;THROW AWAY COUNT
	PJRST	ECOD7##			;SAY DEVICE OFF-LINE
;ROUTINE TO GIVE BACK MONITOR FREE CORE
;ARGS:	RH(S)/ADDRESS OF FREE CORE AREA
;CALL:	PUSHJ	P,DVPGIV
;	RETURN HERE

DVPGIV:	MOVEI	T1,^D40			;RETURN THE 160 WORDS WE USED
	HRRZ	T2,S			;GET ADDRESS OF CORE AREA
	PJRST	GIV4WD##		;GIVE IT BACK



;ROUTINE TO SET EOF STATUS FOR FRONT-END LPT
;ARGS:	F/DDB ADDRESS
;CALL:	SAVE P1-P4,S
;	PUSHJ	P,DLPEOF
;	  RETURN HERE IF UNSUCCESSFUL
;	RETURN HERE IF EOF SENT SUCCESSFULLY

DLPEOF:	MOVE	P3,DLPDUX##(F)		;P3 IS UNIT #,,DLP DTE INDEX
	MOVE	P1,LPCPDT##(P3)		;GET CPU #,,DTE #
	MOVE	P2,[.EMLPT,,EM.16B+EM.IND+.EMHDS] ;SET DEVICE STATUS FOR LPT
	HRRI	P3,2			;TWO 8-BIT BYTES OF STATUS
	MOVE	P4,[POINT 16,[BYTE (16) EM.EOF]]
	MOVEI	S,0			;NO POST ROUTINE OR VALUE TO SAVE
	PUSHJ	P,DTEQUE##		;QUEUE THE REQUEST
	  POPJ	P,			;ERROR--NON-SKIP RETURN
	PJRST	CPOPJ1##		;SUCCESS--SKIP RETURN
SUBTTL	GENERAL SUBROUTINES
;ROUTINE TO SET UP ALL ACS FOR DLP ROUTINES
;ARGS:	P1/CPU #,,DTE # (AS SUPPLIED BY DTESER)
;	LH(P3)/UNIT NUMBER
;CALL:	PUSHJ	P,SETALL
;	  RETURN HERE IF FAILED FOR SOME REASON
;	RETURN HERE IF SUCCESSFUL

SETALL:	HLRZ	F,P1			;GET CPU NUMBER
	HLRZ	T1,P3			;GET UNIT NUMBER
	MOVEI	F,@LPDTDV##(F)		;GET DDB ADDRESS
	JUMPE	F,CPOPJ##		;NON-SKIP IF NONE
	AOS	(P)			;SKIP IF GOOD
	PJRST	IOSET##			;GO SET UP THE REST OF THE REGS
	END