Google
 

Trailing-Edge - PDP-10 Archives - BB-BT99U-BB_1990 - 10,7/galaxy/lptspl/lptd60.mac
There are 10 other files named lptd60.mac in the archive. Click here to see a list.
TITLE	LPTD60 - DN60 printer driver for LPTSPL-10
SUBTTL	D. Mastrovito/DPM	16-OCT-89

;
;
;		COPYRIGHT (c) DIGITAL EQUIPMENT CORPORATION
;		     1984,1985,1986,1987,1990.
;			ALL RIGHTS RESERVED.
;
;     THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY  BE  USED
;     AND COPIED ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENSE
;     AND WITH THE INCLUSION OF THE ABOVE COPYRIGHT NOTICE.   THIS
;     SOFTWARE  OR ANY OTHER COPIES THEREOF MAY NOT BE PROVIDED OR
;     OTHERWISE MADE AVAILABLE TO ANY OTHER PERSON.  NO  TITLE  TO
;     AND OWNERSHIP OF THE SOFTWARE IS HEREBY TRANSFERRED.
;
;     THE INFORMATION  IN  THIS  SOFTWARE  IS  SUBJECT  TO  CHANGE
;     WITHOUT  NOTICE  AND SHOULD NOT BE CONSTRUED AS A COMMITMENT
;     BY DIGITAL EQUIPMENT CORPORATION.
;
;     DIGITAL ASSUMES NO RESPONSIBILITY FOR THE USE OR RELIABILITY
;     OF  ITS  SOFTWARE  ON  EQUIPMENT  WHICH  IS  NOT SUPPLIED BY
;     DIGITAL.
;

	SEARCH	GLXMAC			;SEARCH GALAXY PARAMETERS
	SEARCH	QSRMAC			;SEARCH QUASAR PARAMETERS
	SEARCH	ORNMAC			;SEARCH ORION/OPR PARAMETERS
	SEARCH	LPTMAC			;SEARCH LPTSPL PARAMETERS
	SEARCH	D60UNV			;SEARCH DN60 PARAMETERS
	PROLOG	(LPTD60)

IF2,<PRINTX Assembling GALAXY-10 LPTD60>


	SALL				;FOR CLEAN LISTINGS
	.DIRECT	FLBLST			;FOR CLEANER LISTINGS

	ENTRY	LPTD60			;LOAD IF LIBRARY SEARCH

	%%.LPT==:%%.LPT			;VERSION

	.TEXT	",REL:D60JSY/LOCALS"
SUBTTL	LPTD60 - Dispatch table


LPTD60::DEVDSP	(D60,<DN60>)

D60STS==LPTSTS##			;DEVICE STATUS TEXT


EMSG:	BLOCK	1			;ADDRESS OF ERROR MESSAGE FOR D60ER
OPRERR:	BLOCK	1			;OPR ERROR FLAG USED TO INDICATE
					; SOURCE OF DN60 ERROR
					; -1 INDICATES OPR CONSOLE FAILURE

	 .ORG	J$DWDS
J$D6OB:! BLOCK	OP$SIZ			;PARAMETER BLOCK FOR D60OPN
J$CWKT:! BLOCK	1			;DN60 CONSOLE WAKE-UP TIME
J$ENBR:! BLOCK	1			;THRESHOLD FOR NBR RETURNS
J$EDOL:! BLOCK	1			;THRESHOLD FOR DOL RETURNS
J$D6ER:! BLOCK	1			;LAST DN60 ERROR
J$OMSG:! BLOCK	1			;OPERATOR MESSAGE AVAILABLE FLAG
					; ON(-1) IF HAVE A MESSAGE OR IF
					; MESSAGE NOT COMPLETED
J$DCND:! BLOCK	OP$SIZ			;DN60 LINE CONDITIONING BLOCK
J$DFLG:! BLOCK	1			;DN60 FLAG WORD
J$D6OP:! BLOCK	1			;DN60 OPERATOR CONSOLE ID
J$LST6:! BLOCK	1			;DN60 OPERATORS MSG LIST ID
J$OFLN:! BLOCK	1			;DN60 PRINTER IS OFFLINE FLAG
J$D6SZ:!				;LENGTH OF BLOCK
	 .ORG

IF2,<
	IFL <DRVWDS-<J$D6SZ-J$DWDS>>,<
	PRINTX ? DN60 driver definitions overflow storage
	>
> ;END IF2


	 .ORG	0
OPRPTR:! BLOCK	1			;OPR MESSAGE BYTE POINTER
OPRBCT:! BLOCK	1			;OPR MESSAGE BYTE COUNT
OPRLEN:!				;OPR MESSAGE HEADER LENGTH
OPRTXT:!				;OPR MESSAGE TEXT
	 .ORG
; GENERATE DN60 ERROR CODES AND TEXT

	.Z.==$ER1ST			;SET STARTING VALUE

	DEFINE	ERRS(CODE,TEXT),<XLIST
	CODE==.Z.			;;DEFINE THE ERROR CODE
	EXP	[ASCIZ\TEXT\]		;;DEFINE THE TEXT FOR IT
	.Z.==.Z.+1			;;BUMP ERROR CODE COUNTER
	LIST>

D60TXT:	D60ERR	TEXT			;DEFINE THE ERROR TEXT

	DEFINE	X(ERR,TXT),<XLIST
ER'ERR:	ASCIZ\TXT\
	LIST>

	X	(FCC,<Failed to Close DN60 Console>)
	X	(FCO,<Failed to Close DN60 Output>)
	X	(DOE,<DN60 Output Error>)
	X	(COP,<Can't Open DN60 Printer>)
	X	(COC,<Can't Open DN60 Console>)
	X	(CRP,<Can't Release DN60 Printer>)
	X	(CRC,<Can't Release DN60 Console>)
	X	(COE,<DN60 Console Output Error>)
SUBTTL	D60INX - INITIALIZE


D60INX:	JUMPN	M,INIT.1		;CHECK FOR LPTSPL INITIALIZATION
	MOVEI	S1,SERFLG		;GET SYSERR FLAG
	PUSHJ P,D60INI##		;INIT DN60 DATA BASE
	$RETT				;RETURN

INIT.1:	SKIPN	SUP.CN(M)		;DN60 LPT?
	JRST	INIT.2			;MUST TRY ANOTHER DRIVER
	HRLI	T1,SUP.CN(M)		;GET LINE CONDITIONING BLK ADDRESS
	HRRI	T1,J$DCND(J)		; AND WHERE TO PUT IT
	BLT	T1,J$DCND+CN$SIZ-1(J)	;COPY IT OVER
	MOVE	T1,SUP.ST(M)		;GET THE DN60 FLAG WORD
	MOVEM	T1,J$DFLG(J)		;SAVE IT FOR LATER
	SETOM	J$ENBR(J)		;WE INITALLY DON'T CARE ABOUT NBR ERRS
	SETZM	J$CWKT(J)		;INIT THIS IN ANY CASE
	MOVSI	T1,LPTD60		;BUILD A BLT POINTER
	HRRI	T1,J$$DEV(J)		; TO THE INITIALIZATION VECTOR
	BLT	T1,J$$DND(J)		;COPY OUR VECTOR
	SETOM	J$POSF(J)		;DN60 DOES POSITIONING
	SETOM	J$FFDF(J)		;DN60 DOES FORM FEEDS
	SETZM	J$DC3F(J)		;WE DON'T DO DC3 PROCESSING
	SETOM	J$MNTF(J)		;DN60 SUPPORTS MOUNTABLE FORMS
	MOVSI	S1,'LPT'		;NAME FOR OUR DEVICE
	PUSHJ	P,LPTDVN##		;GO MAKE A REMOTE STATION LPT NAME
	SETZ	S2,			;NO EXTENDED ATTRIBUTES
	$RETT				;RETURN

INIT.2:	MOVNI	S1,1			;-1 MEANS DEVICE NOT FOR US
	$RETF				;RETURN

INIT.3:	SKIPA	S1,[%RSUNA]		;UNIT NOT AVAILABLE
INIT.4:	MOVEI	S1,%RSUDE		;UNIT WILL NEVER BE AVAILABLE
	$RETF				;RETURN
SUBTTL	D60IPC - SPECIAL IPCF MESSAGE PROCESSING


D60IPC:	CAIN	S2,.OMDSP		;DN60 OPERATOR MESSAGE?
	JRST	OPRD60			;YES
	MOVNI	S1,1			;SAY NOT FOR THIS DRIVER
	$RETF				;RETURN

OPRD60:	SETOM	JOBITS##		;DONT SAVE THE STATUS BITS
	MOVX	T1,.OTLPT		;GET LINE PRINTER OBJECT TYPE
	SETZM	T2			;GET UNIT 0
	MOVE	T3,.MSCOD(M)		;GET NODE NAME
	MOVEI	S1,T1			;POINT TO THIS OBJECT BLOCK
	PUSHJ	P,FNDOBJ##		;FIND IT IN OUR DATA BASE
	JUMPT	OPRD.1			;ITS THERE,,CONTINUE ON
	$WTO(<No operator console for IBM remote '^N/.MSCOD(M)/'>,,,<$WTFLG(WT.SJI)>)
	$RETT				;NOT FOUND,,TELL LOCAL OPR AND EXIT

OPRD.1:	PUSHJ	P,.SAVE2		;SAVE P1 AND P2 FOR A MINUTE
	MOVE	S1,J$LST6(J)		;GET THE OPR MSG LIST ID
	PUSHJ	P,L%LAST		;POSITION TO LAST ENTRY
	LOAD	S2,.MSTYP(M),MS.CNT	;GET THE MESSAGE LENGTH
	SUBI	S2,.OHDRS		;SUBTRACT ALL HEADER LENGTHS
	ADDI	S2,OPRLEN+2		;ADD OUR HEADER+TIME STAMP LENGTH
	MOVE	S1,J$LST6(J)		;GET THE OPR MSG LIST ID
	PUSHJ	P,L%CENT		;CREATE AN ENTRY IN THE LIST
	JUMPF	OPRD.3			;SHOULDN'T HAPPEN
	MOVE	P1,S2			;SAVE THE ENTRY ADDRESS
	MOVEI	P2,.OHDRS(M)		;POINT TO THE FIRST MESSAGE BLOCK
	LOAD	T1,.OARGC(M)		;GET THE BLOCK COUNT
	MOVEI	S1,OPRTXT(P1)		;GET THE TEXT ADDRESS
	HRLI	S1,(POINT 7,0)		;MAKE IT A BYTE POINTER
	MOVEM	S1,TEXTBP##		;SAVE IT FOR $TEXT

OPRD.2:	LOAD	S1,ARG.HD(P2),AR.TYP	;GET THE BLOCK TYPE
	CAXN	S1,.ORDSP		;IS IT A DISPLAY BLOCK ???
	$TEXT	(DEPBP##,<^C/ARG.DA(P2)/ ^T/ARG.DA+1(P2)/>) ;GEN THE DISPLAY
	CAXN	S1,.CMTXT		;IS IT A TEXT BLOCK ???
	$TEXT	(DEPBP##,<^T/ARG.DA(P2)/>) ;GEN THE DISPLAY
	LOAD	S1,ARG.HD(P2),AR.LEN	;GET THIS BLOCK LENGTH
	ADD	P2,S1			;POINT TO THE NEXT BLOCK
	SOJG	T1,OPRD.2		;PROCESS ALL MESSAGE BLOCKS

	HRROI	S1,OPRTXT(P1)		;GEN BYTE PTR TO MSG TEXT
	MOVEM	S1,OPRPTR(P1)		;SAVE IT IN THE LIST
	HRRZ	S1,TEXTBP##		;GET THE LAST TEXT ADDRESS
	SUBI	S1,OPRTXT-1(P1)		;CALC THE TEXT LENGTH
	IMULI	S1,5			;CALC THE NUMBER OF BYTES
	MOVNM	S1,OPRBCT(P1)		;SAVE THE -BYTE COUNT
	SETOM	J$OMSG(J)		;FLAG THAT THE STATION HAS A MESSAGE
	$RETT				;AND RETURN

OPRD.3:	$WTO(<DN60 operator message lost>,<Linked list processor failure ^E/S1/>)
	$RETT				;COMPLAIN AND RETURN
SUBTTL D60SCD - SCHEDULER CALL

; Check for DN60 OPR msgs and send them
;  The purpose of this routine is to perform stream-related DN60 operator
;  functions that are separate from the normal print functions.
;  This function sends operator messages between normal
;	printouts. (on 2780/3780)

;    Parameters:  J / Address of job parameter area
;		  P1/ The stream being examined
;    Returns:  True always

D60SCD:	SKIPN	J$OMSG(J)		;IS THERE AN OPERATOR MESSAGE WAITING?
	$RETT				;NO -- JUST RETURN
	LOAD	S1,J$DFLG(J),NT.TYP	;GET THE MODE
	CAXN	S1,DF.HSP		;IS IT HASP ???
	JRST	SCHD.1			;YES,,OK TO OUTPUT...
	MOVX	S1,PSF%OO		;GET OPR MSG WAIT CODE
	SKIPE	JOBACT##(P1)		;IF THE STREAM IS ACTIVE
	TDNE	S1,JOBSTW##(P1)		;   BUT WE ALREADY STARTED OPR MSGS
	SKIPA				;     THEN LETERRIP !!!
	$RETT				;     ELSE RETURN !!!!!

;Check to see if time to wake up
SCHD.1:	SKIPN	J$CWKT(J)		;NEED TO CHECK TIME?
	JRST	SCHD.2			;NO, SKIP THIS
	$CALL	I%NOW			;GET THE CURRENT TIME
	SUB	S1,J$CWKT(J)		;SUBTRACT CONSOLE WAKEUP TIME
	SKIPGE	S1			;TIME TO WAKE UP?
	JRST	[$CALL CHKTIM##		;NO, UPDATE SLEEPT
		$RETT]			;QUIT
	SETZM	J$CWKT(J)		;TIME TO CONTINUE

SCHD.2:	$SAVE	<P1>			;Save P1
	HRRZM	P1,STREAM##		;HERE ALSO

;Loop on messages
SCHD.3:	MOVE	S1,J$LST6(J)		;GET THE OPR MSG LIST ID
	PUSHJ	P,L%FIRST		;GET THE FIRST MESSAGE ON THE CHAIN
	JUMPF	SCHD.6			;NONE THERE,,CLEAN UP AND RETURN
	MOVE	P1,S2			;SAVE THE MSG ADDRESS
	MOVE	S1,J$D6OP(J)		;GET THE OPR'S CONSOLE ID
	MOVE	S2,OPRPTR(P1)		;GET THE POINTER TO THE TEXT
	MOVE	T1,OPRBCT(P1)		;GET THE TEXT BYTE COUNT
	PUSHJ	P,D60SOUT##		;OUTPUT THE OPERATOR MESSAGE
	JUMPT	[$CALL	D60SU		;PROCESS GOOD RETURN
		MOVE	S1,J$LST6(J)	;GET OPR MESSAGE LIST ID
		$CALL	L%DENT		;DELETE CURRENT MESSAGE
		MOVEI	S1,%TCNO	;GET THE STATS CODE FOR CONSOLE MESSAGE
		PUSHJ	P,IBMSTS	;TELL QUASAR
		JRST	SCHD.3]		;GO TRY AGAIN
;Process error
	$D60OE	(ERCOE)			;PROCESS THE ERROR
	JUMPT	SCHD.5			;GOOD ERROR -- PROCESS IT

;Bad error -- Assume fatal for console

SCHD.4:	MOVX	S1,%RSUDE		;GET 'DOES NOT EXIST' SETUP CODE
	PUSHJ	P,RSETUP##		;TELL QUASAR WHATS GOING ON
	PUSHJ	P,SHUTND##		;SHUT EVERYTHING DOWN !!!
	$RETT				;AND RETURN

;Good error -- Update pointers and flags

SCHD.5:	MOVEM	S2,OPRPTR(P1)		;SAVE THE NEW TEXT POINTER
	MOVEM	T1,OPRBCT(P1)		;SAVE THE NEW TEXT BYTE COUNT
	$RETT				;And return OK

;Done with messages -- Try to clean up
SCHD.6:	MOVE	S1,J$D6OP(J)		;GET THE OPERATOR CONSOLE ID
	$CALL	D60EOF##		;Try to EOF
	JUMPT	[$CALL	D60SU		;Process good error
		SETZM	J$OMSG(J)	;Clear message waiting flag
		MOVX	S1,PSF%OO	;GET 'OPERATOR OUTPUT WAIT' BITS
		MOVE	S2,STREAM##	;GET OUR STREAM NUMBER
		ANDCAM	S1,JOBSTW##(S2)	;CLEAR 'OPERATOR OUTPUT WAIT' BITS
		$RETT]			;and return
	$D60OE	(ERFCC)			;Go process the error
	JUMPF	SCHD.4			;Bad error
	$RETT				;Good error, return
SUBTTL	D60WAK - WAKEUP TIME CHECK


D60WAK:	SKIPN	J$OMSG(J)		;ANY CONSOLE MESSAGES?
	$RETT				;NO
	SKIPE	S2			;ANY TIME SET?
	CAML	S2,J$CWKT(J)		;YES, CONSOLE TIME SOONER?
	SKIPN	J$CWKT(J)		;YES, ANY CONSOLE TIME SET?
	$RETT				;NO--DON'T USE CONSOLE TIME
	PUSHJ	P,.SAVE2		;SAVE P1 AND P2
	MOVE	P1,J$CWKT(J)		;GET CONSOLE TIME
	SUB	P1,S1			;CALCULATE THE NUMBER
	IDIVI	P1,3			;   OF SECONDS TO WAKE-UP.
	JUMPG	P1,.RETT		;USE SUPPLIED VALUE IF NOT TIMED OUT
	MOVE	P1,STREAM##		;GET STREAM NUMBER
	MOVX	S2,PSF%DO		;AND DEVICE OFF-LINE BIT
	ANDCAM	S2,JOBSTW##(P1)		;CLEAR IT
	MOVE	S2,J$CWKT(J)		;ELSE GET CONSOLE WAKEUP TIME
	SETZM	J$CWKT(J)		;CLEAR FOR NEXT TIME
	$RETF				;AND RETURN (DON'T ZERO JOBWKT)
SUBTTL	D60OPX - OPEN DEVICE


D60OPX:	PUSHJ	P,OPEN60		;YES,,GO OPEN IT UP
	JUMPF	OPEN.2			;NO GOOD,,TOO BAD !!!!!
	PUSHJ	P,LPTRES##		;SETUP THE OUTPUT BUFFERS
	MOVE	S1,['DN60  ']		;LPT TYPE
	MOVEM	S1,J$LTYP(J)		;SAVE
	MOVEI	S1,%RSUOK		;LOAD THE CODE
	$RETT				;RETURN

OPEN.1:	SKIPA	S1,[%RSUNA]		;UNIT NOT AVAILABLE
OPEN.2:	MOVEI	S1,%RSUDE		;UNIT WILL NEVER BE AVAILABLE
	$RETF				;RETURN
OPEN60:	MOVSI	S1,(POINT 8,0)		;GET 8 BIT BYTE POINTER
	MOVEM	S1,J$LBTZ(J)		;SAVE IT FOR LATER
	SETOM	J$LST6(J)		;INDICATE NO OPR MSG LIST YET
	SETZM	J$OMSG(J)		;INDICATE NO OPERATOR MESSAGES EITHER
	MOVE	S1,STREAM##		;GET OUR STREAM NUMBER
	MOVE	S1,JOBOBA##(S1)		;GET OUR OBJECT BLOCK ADDRESS
	MOVE	S1,OBJ.UN(S1)		;GET OUR UNIT NUMBER
	STORE	S1,J$D6OB(J),OP$UNT	;SAVE THE UNIT NUMBER IN OPEN BLOCK
	MOVX	S1,.OPLPT		;WANT 'LPT' DEVICE
	STORE	S1,J$D6OB(J),OP$TYP	;SAVE THE DEVICE TYPE IN THE OPEN BLOCK
	LOAD	S1,J$DCND(J),CN$PRT	;GET THE PORT NUMBER
	STORE	S1,J$D6OB(J),OP$PRT	;SAVE IT IN THE OPEN BLOCK
	LOAD	S1,J$DCND(J),CN$LIN	;GET THE LINE NUMBER
	STORE	S1,J$D6OB(J),OP$LIN	;SAVE IT IN THE OPEN BLOCK
	LOAD	S1,J$DCND(J),CN$SIG	;GET THE LINE SIGNATURE
	STORE	S1,J$D6OB(J),OP$SIG	;SAVE IT IN THE OPEN BLOCK

OPN6.1:	HRROI	S1,-OP$SIZ		;GET THE NEGATIVE BLOCK LENGTH
	MOVEI	S2,J$D6OB(J)		;GET THE PARM BLOCK ADDRESS
	PUSHJ	P,D60OPN##		;OPEN THE PRINTER
	JUMPF	[$D60ER	(ERCOP)		;PROCESS THE ERROR
		 $RETIF			;RETURN IF BAD ERROR
		 JRST	OPN6.1]		;TRY AGAIN
	PUSHJ	P,D60SU			;SUCCESSFUL COUNTERS
	MOVEM	S1,J$LCHN(J)		;SAVE THE LPT HANDLE
	HRLZI	S1,.OPCOU		;WANT OUTPUT CONSOLE FOR REMOTE
	MOVEM	S1,J$D6OB(J)		;SAVE THE DEV-TYP, UNIT NUMBER

OPN6.2:	HRROI	S1,-OP$SIZ		;GET THE NEGATIVE PARM BLOCK LENGTH
	MOVEI	S2,J$D6OB(J)		;GET THE PARM BLOCK ADDRESS
	PUSHJ	P,D60OPN##		;OPEN THE OUTPUT CONSOLE
	JUMPT	OPN6.4			;O.K.  PROCEED
	$D60ER	(ERCOC)			;PROCESS THE ERROR
	JUMPT	OPN6.2			;GOOD ERROR, TRY AGAIN

; Need to release LPT since can't get console
OPN6.3:	MOVE	S1,J$LCHN(J)		;GET LPT ID
	$CALL	D60RLS##		;TRY TO RELEASE IT
	JUMPT	.RETF			;RETURN
	$D60ER	(ERCRP)			;PROCESS THE ERROR
	JUMPT	OPN6.3			;TRY AGAIN
	$RETF				;RETURN

OPN6.4:	PUSHJ	P,D60SU			;SUCCESSFUL CHECK COUNTERS
	MOVEM	S1,J$D6OP(J)		;SAVE THE OPERATORS CONSOLE ID
	PUSHJ	P,L%CLST		;CREATE A LIST FOR OPERATOR MESSAGES
	MOVEM	S1,J$LST6(J)		;SAVE THE LIST ID
	$RETT				;AND RETURN
SUBTTL	D60CLS - CLOSE DEVICE


D60CLS:	SETZM	J$OMSG(J)		;No more operator msgs.
	MOVEI	S1,NENBR		;Want this to terminate
	MOVEM	S1,J$ENBR(J)		;Set a threshold

CLOS.1:	MOVE	S1,J$LCHN(J)		;MAKE SURE WE HAVE JUST THE HANDLE
	PUSHJ	P,D60RLS##		;CLOSE DOWN THE DN60
	JUMPF	[$D60ER	(ERCRP)		;PROCESS ERROR
		JUMPT	CLOS.1		;TRY AGAIN IF APPROP.
		JRST	.+1]		;TRY TO CONTINUE

CLOS.2:	MOVE	S1,J$D6OP(J)		;GET THE CONSOLE ID
	PUSHJ	P,D60RLS##		;CLOSE DOWN THE OPERATORS CONSOLE
	JUMPF	[$D60ER	(ERCRC)		;process error
		JUMPT	CLOS.2		;TRY AGAIN IF APPROP.
		JRST	CLOS.3]		;TRY TO CONTINUE
	PUSHJ	P,D60SU			;FIX COUNTS

CLOS.3:	SKIPL	S1,J$LST6(J)		;CHECK AND GET THE OPERATORS LIST ID
	PUSHJ	P,L%DLST		;DELETE THE LIST IF THERE IS ONE
	$RETT				;AND RETURN (NO JFN HERE)
SUBTTL	D60FLS - FLUSH BUFFERS


D60FLS:	PJRST	LPTRES##		;RESET BUFFERS AND RETURN
SUBTTL	D60VFU - LOAD VFU


D60VFU:	$RETT				;DO NOTHING
SUBTTL	D60RAM - LOAD RAM


D60RAM:	$RETT				;DO NOTHING
SUBTTL	D60LER - FILE LOOKUP ERROR PROCESSING


D60LER:	PJRST	LPTLER##		;CALL COMMON ERROR ROUTINE
SUBTTL	D60IER - INPUT FILE ERROR PROCESSING


D60IER:	PJRST	LPTIER##		;CALL COMMON ERROR ROUTINE
SUBTTL	D60CHO - OUTPUT A CHARACTER

D60CHO:	$RETT				;LET DEVOUT DO IT
SUBTTL	D60OUT - OUTPUT A BUFFER


D60OUT:	PUSHJ	P,.SAVET		;SAVE THE 'T' ACS

OUTP.1:	SKIPGE	T1,J$LBCT(J)		;GET BYTES REMAINING IN BUFFER
	SETZM	T1			;IF LESS,,MAKE IT ZERO
	SUB	T1,J$LIBC(J)		;CALC -BYTE COUNT IN BUFFER
	JUMPGE	T1,LPTRES		;NOTHING TO PUT OUT,,RESET BUFR PTRS
	MOVE	S1,J$LCHN(J)		;GET THE LPT JFN
	MOVE	S2,J$LIBP(J)		;GET THE STARTING BYTE POINTER
	SETZM	J$LIOA(J)		;ZAP I/O ACTIVE (NONE FOR DN60)
	PUSHJ	P,D60SOUT##		;OUTPUT THE DATA
	MOVEM	S2,J$LIBP(J)		;SAVE THE BUFFER POINTER AND
	MOVMM	T1,J$LIBC(J)		;   THE BYTE COUNT JUST IN CASE
	SETZM	J$LBCT(J)		;CLEAR BYTE COUNT FOR THE BUFFER
	JUMPT	OUTP.2			;CONTINUE IF NO ERRORS
	$D60ER	(ERDOE)			;PROCESS THE ERROR
	JUMPT	OUTP.3			;IF GOOD ERROR, LOOP
	SETZM	J$LERR(J)		;FORCE FAILURE
	PUSHJ	P,LPTDIE##		;1 BAD ERROR IS TOO MANY, DO NOT RETURN

OUTP.2:	PUSHJ	P,D60SU			;PROCESS SUCCESS
OUTP.3:	SKIPLE	J$LIBC(J)		;ANY BYTES LEFT IN THE BUFFER ???
	JRST	OUTP.1			;YES,,GO PUT THEM OUT
	PUSHJ	P,LPTRES##		;RESET THE OUTPUT BUFFERS
	$RETT				;AND RETURN
SUBTTL	D60OER - OUTPUT ERROR PROCESSING


D60OER:	$RETT				;NEVER CALLED
SUBTTL	D60EOX - OUTPUT EOF PROCESSING


D60EOX:	MOVE	S1,J$LCHN(J)		;GET HANDLE
	PUSHJ	P,D60EOF##		;TRY TO DO EOF
	$RETIT				;OK -- RETURN
	$D60ER	(ERFCO)			;PROCESS THE ERROR
	JUMPT	D60EOX			;TRY AGAIN
	$RETT				;RETURN BUT STILL IN TROUBLE
SUBTTL	D60BJB - BEGINING OF JOB


D60BJB:	$RETT				;DO NOTHING
SUBTTL	D60EJB - END OF JOB


D60EJB:	MOVEI	S1,%TOUT		;GET IBM STATISTICS CODE
	PJRST	IBMSTS			;SEND MESSAGE TO QUASAR AND RETURN
SUBTTL	D60BFL - BEGINING OF FILE


D60BFL:	$RETT				;RETURN
SUBTTL	D60EFL - END OF FILE


D60EFL:	$RETT				;RETURN
SUBTTL	D60BAN - BANNER INITIALIZATION


D60BAN:	$RETT				;DO NOTHING
SUBTTL	D60HDR - HEADER INITIALIZATION


D60HDR:	$RETT				;DO NOTHING
SUBTTL	D60CHR - CHARACTER TRANSLATION


D60CHR:	$RETT				;RETURN
SUBTTL	D60RUL - RULER PROCESSING


D60RUL:	PJRST	LPTRUL##		;PRINT STANDARD RULER
SUBTTL	D60WID - PAGE WIDTH COMPUTATION


D60WID:	$RETT				;DO NOTHING
SUBTTL	D60SHT - SHUTDOWN


D60SHT:	$RETT				;RETURN
SUBTTL	MISCELLANEOUS -- D60SU - DN60 SUCCESS ROUTINE TO FIX COUNTS


;purpose:	To maintain counters etc. relating to a successful
;		DN60 return

; Parameters:	J / Address of current jobpage

D60SU:	SKIPN	J$OFLN(J)		;WERE WE OFFLINE BEFORE THIS?
	$RETT				;NO -- JUST RETURN
	SETZM	J$OFLN(J)		;CLEAR OFF-LINE FLAG
	PUSH	P,T1			;SAVE T1
	MOVE	T1,STREAM##		;GET CURRENT STREAM NUMBER
	MOVX	TF,PSF%DO		;GET DEVICE OFF-LINE BIT
	ANDCAM	TF,JOBSTW##(T1)		;CLEAR IT
	CAMN	J,JOBPAG##(T1)		;ARE WE SETUP?
	SETOM	JOBUPD##(T1)		;REQUEST STATUS UPDATE
	POP	P,T1			;RESTORE T1
	$RETT				;RETURN
SUBTTL	MISCELLANEOUS -- D60ER/D60OE - PROCESS DN60 ERRORS


; The purpose of D60ER is to process DN60 errors that deal with
; LPT device (operator console are processed as part of the routine
; OPRCHK).  The following actions are taken:

; 1.  Determine if error is "good" i.e. D6DOL or D6NBR
; 2.  If good error has overflowed threshold, then it is a bad error
; 3.  If good, DSCHD and then return true

; -- Bad error --

; 4.  Output error message if requested
; 5.  Return false

; The purpose/use of D60OE is the same as D60ER except the DSCHD must
; not occur.

; Parameters:

;	S1 / Last DN60 error
;	(P) / Error message address

;	Called by $D60ER macro

;		$D60ER (msg)
;		    Where msg is either error message address or
;					0 for no error to be output

D60OE:	SETOM	OPRERR			;This is an operator error
	SKIPA
D60ER:	SETZM	OPRERR			;This is the normal stream error
	MOVEM	S1,J$D6ER(J)		;Save the last DN60 error

;NBR error?

	CAIE	S1,D6NBR		;Non-blocking return?
	JRST	D60E.1			;no, go process other
	SKIPGE	J$ENBR(J)		;Do we care about errors?
	JRST	D60E.6			;No, skip this
	SOSG	J$ENBR(J)		;Out of errors?
	JRST	D60E.3			;Yes - process bad error
	JRST	D60E.6			;No, go process good error

;OAB error?

D60E.1:	CAIE	S1,D6OAB		;Output abort error?
	JRST	D60E.2			;No, go try for other
	SKIPE	OPRERR			;Is this during operator output?
	$RETT				;Yes, ignore it

;  Here when abort occurs in printer stream.
;  Requeue current job and shutdown stream.

	MOVE	S1,STREAM##		;Get the stream number
	$WTO	(<Job terminated due to IBMCOM output abort>,,@JOBOBA(S1))
	MOVEI	S1,%RSUNA		;Set the unit unavailable
	PUSHJ	P,RSETUP##		;Cause the current job to be requeued
	PJRST	SHUTIN##		;Shut the stream down till restarted

;DOL error?

D60E.2:	PUSH	P,T1			;SAVE T1
	MOVE	T1,STREAM##		;Get the stream number
	MOVX	TF,PSF%DO		;GET DEVICE OFF-LINE BIT
	SKIPL	J$OFLN(J)		;Are we already off line?
	SETOM	JOBUPD##(T1)		;No, indicate need for status message
	SETOM	J$OFLN(J)		;Indicate we are offline at least
	IORM	TF,JOBSTW##(T1)		;HERE TOO
	POP	P,T1			;RESTORE T1
	CAIN	S1,D6DOL		;Device off-line error?
	JRST	D60E.6			;Yes, finish processing good error
					;Else continue and process bad error
;Bad error

D60E.3:	MOVEM	T1,EMSG			;Save T1 a second
	HRRZ	T1,@0(P)		;Get error message
	SKIPN	T1			;Want error message output?
	JRST	[MOVE	T1,EMSG		;No - Restore T1
		 JRST	D60E.5]		;and return
	EXCH	T1,EMSG			;Save error message
	$SAVE	<T1,T2>			;Get a couple of free registers
	MOVE	T2,STREAM##		;Get current stream
	SUBI	S1,$ER1ST		;Set DN60 error message
	MOVE	T1,EMSG			;Get error message again
	$WTO	(<^T/0(T1)/>,<^T/@D60TXT(S1)/>,@JOBOBA(T2)) ;Yes tell opr
D60E.5:	$RETF

;  Here on DOL or NBR error, set new sleeptime based on polling estimate

D60E.6:	$SAVE	<S1,S2,T1>		;Save some acs
	$CALL	I%NOW			;Get the current time
	ADD	S1,POLEST##		;Get wakeup time from D60JSY
	SKIPE	OPRERR			;Are we at a console error?
	JRST	[MOVEM	S1,J$CWKT(J)	;Yes, set that wakeup time
		 PUSHJ	P,CHKTIM##	;Adjust sleeptime
		 JRST	D60E.8]		;And rejoin common code
	MOVE	S2,STREAM##		;Get the stream number
	MOVEM	S1,JOBWKT##(S2)		;Save job wake time
	PUSHJ	P,CHKTIM##		;Adjust sleep time
	$DSCHD	(0)			;Sleep one way
D60E.8:	$RETT				;And quit good
SUBTTL	MISCELLANEOUS -- IBMSTS - SEND IBM STATISTICS TO QUASAR

; CALL:	MOVE	S1, statistics code
;	PUSHJ	P,IBMSTS

IBMSTS:
IFE FTIBMS,<POPJ	P,>
IFN FTIBMS,<
	PUSH	P,T1			;SAVE T1
	MOVEM	S1,IBMSTM+MSHSIZ	;SAVE STATISTICS CODE IN MESSAGE
	MOVEI	T1,IBMSTM		;GET THE ADDRESS OF MESSAGE
	PUSHJ	P,SNDQSR##		;SEND IT OFF TO QUASAR
	POP	P,T1			;RESTORE T1
	POPJ	P,			;PASS ANY ERRORS UP

IBMSTM:	$BUILD	(MSHSIZ+1)		;HEADER PLUS STATUS WORD
	  $SET	(.MSTYP,MS.CNT,MSHSIZ+1);LENGTH OF MESSAGE
	  $SET	(.MSTYP,MS.TYP,.QOIBM)	;IBMCOM STATISTICS MSG TYPE
	$EOB				;EVERYTHING ELSE IS ZERO

> ;END OF FTIBMS
SUBTTL	LITERAL POOL

D60LIT:	LIT

D60END::!END