	.TITLE	VRSSMBMAN - VERSATEC PRINT SYMBIONT MAIN ROUTINE
	.SBTTL	DECLARATIONS
;
;
;	LANGUAGE:  VAX-11 MACRO
;
;	OPERATING SYSTEM:  VAX/VMS
;
;	ORDER NUMBER:  12X-9XV
;
;	PART NUMBER:  000-025809-XXX REV. G  MAY, 1985
;
;	PRODUCT: VAX-11 DIAGNOSTIC,
;	PRODUCT: VAX/VMS DRIVER, SYMBIONT, AND OUTPUT PACKAGE
;
;	VERSATEC, INC., SANTA CLARA, CALIFORNIA 95051
;	A XEROX COMPANY
;
;	Copyright (C) 1985 by Xerox Corporation.  All rights reserved.
;
;	"NOTICE. THIS PROGRAM IS THE EXCLUSIVE PROPERTY OF VERSATEC,
;	INC. AND IS ISSUED IN STRICT CONFIDENCE UNDER A PREARRANGED
;	LICENSE AGREEMENT AND IS NOT TO BE DISCLOSED IN ANY MANNER TO
;	PERSONS OUTSIDE THE LICENSED ORGANIZATION AND SHALL NOT BE
;	REPRODUCED OR DISSEMINATED, IN WHOLE OR PART, TO ANYONE OUTSIDE
;	THE LICENSED ORGANIZATION WITHOUT THE PRIOR WRITTEN APPROVAL OF
;	VERSATEC, INC. UNLESS OTHERWISE PROVIDED FOR BY SUCH LICENSE
;	AGREEMENT.  THIS WORK IS PROTECTED AS AN UNPUBLISHED WORK UNDER
;	THE COPYRIGHT ACT OF 1976."
;
;
;	THIS MODULE CONTAINS THE MAINLINE CODE FOR THE PRINT SYMBIONT.
;
;	B.L.	MAY, 1985	INITIAL RELEASE WITH REV. G DRIVER
;
;
; EQUATED SYMBOLS:
	$FABDEF
	$RABDEF
	$PRVDEF
	$QIODEF
	$SHRDEF				;SHARED MESSAGE DEFINTIONS
 
	.LIBRARY	\SYS$LIBRARY:LIB\
	$SMBDEF
 
LF=10					;LINE FEED
FF=12					;FORM FEED
 
IO$M_REMOTE = ^X80
 
	.PAGE
	.SBTTL	SYMBIONT INITIALIZATION ROUTINE
 
; FUNCTIONAL DESCRIPTION:
;
;	THIS ROUTINE PERFORMS ALL ONE TIME FUNCTIONS FOR THE
;	PRINT SYMBIONT AND IS THE MAIN ENTRY POINT OF SYMBIONT.
 
	.PSECT	VRSSMBMAN,EXE,RD,NOWRT,LONG
	.ENTRY	VRSSMB_START	^M<>	;SYMBIONT INITIAL ENTRY
;
; RUN-TIME INITIALIZATION OF DATA FIELDS
 
	MOVZBL	#QIO$_NARGS,SD_G_QIOBLK	 ;SET QIO BLOCK LENGTH
	MOVZWL	#IO$_WRITELBLK,SD_G_QIOBLK+QIO$_FUNC ;SET I/O FUNCTION
;
; REQUEST NEEDED PRIVILEGES
	BBSS	#PRV$V_ALLSPOOL,SD_Q_PRVADR,1$
1$:	BBSS	#PRV$V_LOG_IO,SD_Q_PRVADR,2$
2$:	BBSS	#PRV$V_READALL,SD_Q_PRVADR,3$
3$:	BBSS	#PRV$V_SHARE,SD_Q_PRVADR,4$
4$:	$SETPRV_S	#1,SD_Q_PRVADR
	BLBC	R0,5$			;ABORT IF ERROR
;
; ESTABLISH CONDITION HANDLER
	MOVAB	VRSSMB$HANDLER,(FP)	;LOAD CONDITION HANDLER ADDRESS
;
; INITIALIZE THE SYMBIONT
	PUSHAB	VRSSMB$AST		;AST ROUTINE ADDRESS
	PUSHAL	#SMBMSG$K_STRUCTURE_LEVEL ;ADDR. OF VERSION LEVEL
	CALLS	#2,G^SMB$INITIALIZE	;INITIALIZE SYMBIONT
	BLBS	R0,VRSSMB$MAIN		;BR IF SUCCESSFUL
5$:	BRW	FATAL			;INITIALIZE ERROR IS FATAL
 
	.PAGE
	.SBTTL	PRINT SYMBIONT MAIN ROUTINE
	.ENABL	LSB
VRSSMB$MAIN:
	$SETEF_S  #VRSSMB$K_TOFEFN	;START WITH TOP OF FORM DONE
	$PURGWS_S INADR=VRSSMB$L_ADDESC	;PURGE WORKING SET
10$:	$HIBER_S			;WAIT FOR SOMETHING TO DO
	BBCC	#SD_V_GOOD_WAKE,SD_B_GEN_FLAGS,10$ ;EXPECTING WAKE-UP?
	CLRL	SD_L_NUM_ERROR		;CLEAR ERROR DETECTED
	CLRL	SD_L_GETCNT		;INIT GET COUNT
	CLRL	SD_L_QIOCNT		;INIT QIO COUNT
;
; OPEN USERS DATA FILE
	$OPEN	SD_G_FAB		;OPEN THE FILE
	BLBC	R0,20$			;BR IF NOT OK
	$CONNECT	RAB=SD_G_RAB	;CONNECT THE RAB
	BLBS	R0,25$			;BR IF OK
	ASSUME	RAB$L_STV EQ RAB$L_STS+4
	MOVQ	SD_G_RAB+RAB$L_STS,SD_T_ERROR+12 ;RMS STATUS CODES
	BRB	22$
20$:	ASSUME	FAB$L_STV EQ FAB$L_STS+4
	MOVQ	SD_G_FAB+FAB$L_STS,SD_T_ERROR+12 ;RMS STATUS CODES
22$:	MOVL	#5,SD_L_NUM_ERROR	;LOAD NO. OF ERROR CODES
	MOVL	#<4@16>!SHR$_OPENIN!4,SD_T_ERROR ;CONDITION CODE
	MOVL	#1,SD_T_ERROR+4		;1 FAO ARGUMENT
	MOVAL	SD_Q_FILE_SPEC,SD_T_ERROR+8 ;ADDRESS OF FILE SPEC DESCRIPTOR
	BRB	27$			;GET OUT
 
25$:	MOVAB	SD_T_SQBUF,SD_G_RAB+RAB$L_RHB ;SET HEADER BUF ADDR
	CMPB	#2,SD_G_FAB+FAB$B_FSZ	;IS THE FSZ OK
	BGEQU	27$			;BR IF YES
	CLRL	SD_G_RAB+RAB$L_RHB	;DON'T GET THE RECORD HEADER
27$:	CMPB	#FAB$C_VFC,SD_G_FAB+FAB$B_RFM ;SEQUENCE NO. OR PRINT FORMAT?
	BNEQ	28$			;BR IF NOT
	BBS	#FAB$V_PRN,SD_G_FAB+FAB$B_RAT,28$ ;BR IF PRINT FILE FORMAT
	BICL	#RAB$M_LOC,SD_G_RAB+RAB$L_ROP ;USE MOVE MODE
;
; DO A REMOTE NULL TO CHECK PRINTER/PLOTTER IS ONLINE
28$:	BBS	#SMBMSG$V_TERMINAL,SD_L_DEV_STAT,29$ ;BR IF ASYNC. TERMINAL
	$QIOW_S	-			;QIO AND WAIT
	EFN = #VRSSMB$K_TOFEFN,-	;USE TOP-OF-FORM EVENT FLAG
	CHAN = SD_G_QIOBLK+QIO$_CHAN,-	;CHANNEL NUMBER
	FUNC = #IO$_WRITELBLK!IO$M_REMOTE,- ;REMOTE FUNCTION
	IOSB = SD_Q_TOFIOSB,-		;I/O STATUS BLOCK
	P1 = #0,-			;BUFFER LENGTH = 0
	P2 = #0,-			;NO BUFFER ADDRESS
	P3 = #0				;NULL REMOTE FUNCTION
	INCL	SD_L_QIOCNT		;COUNT ONE MORE QIO
;
; TELL JOB CONTROLLER WE STARTED THE TASK
29$:	PUSHAL	#SMBMSG$K_START_TASK	;PUSH ADDR. OF REQUEST
	PUSHAL	#0			;STREAM NO. = 0 FOR SINGLE THREADED
	CALLS	#2,G^SMB$SEND_TO_JOBCTL	;SMBMSG$K_START_TASK
	BLBS	R0,30$			;BRANCH IF OK
	BRW	FATAL			;ANY ERROR IS FATAL
;
; FIND OUT WHAT TIME PRINTING STARTS
30$:	$GETTIM_S	SD_Q_PTIME	;GET TIME, IGNORE ERROR
;
; PRINT THE FLAG PAGE
	BBC	#SMBMSG$V_FILE_FLAG,SD_L_SEP_CTL,33$ ;BR IF NO FLAG PAGE
	BISB	#SD_M_FLGPAG,SD_B_GEN_FLAGS ;SET FLAG PRINTING FLAG PAGE
	BSBW	VRSSMB$FLAGPAGE		;PRINT THE FLAG PAGE
	BLBC	R0,36$			;BR IF NOT OK
	BSBW	VRSSMB$TOPOFORM		;PRINT THE FORM FEED
 
33$:	TSTL	SD_L_NUM_ERROR		;ANY ERROR COUNT?
	BEQL	35$			;BR IF NONE
	BRW	390$			;GO PRINT ERROR MESSAGE
35$:	MOVL	#1,SD_L_PAGE		;INIT PAGE NUMBER
	BBC	#SMBMSG$V_PAGE_HEADER,SD_L_PRT_CTL,40$ ;BR IF NO HEADERS
	BSBW	VRSSMB$PAGEHDRNFF	;PRINT A HEADER / NO FORM FEED
	BLBS	R0,38$			;BRANCH IF OK
36$:	BRW	385$			;GO HANDLE OUTPUT ERROR
38$:	BISL	#SMBMSG$M_PAGINATE,SD_L_PRT_CTL ;FORCE PRINTING /FEED
40$:	BICB	#SD_M_FLGPAG,SD_B_GEN_FLAGS ;CLEAR FLAG PRINTING FLAG PAGE
	BISB	#SD_M_FLGPAGDONE,SD_B_GEN_FLAGS ;SET DONE WITH FLAG PAGE
	BICB	#SD_M_FFREQ,SD_B_GEN_FLAGS ;CLEAR FORM FEED REQUIRED
;
; CHECK IF INTERNAL CARRIAGE CONTROL
	BITB	#FAB$M_CR!FAB$M_FTN!FAB$M_PRN,-
			SD_G_FAB+FAB$B_RAT ;IS IT INTERNAL CAR CONT
	BNEQ	50$			;BR IF NO
	CLRL	SD_G_QIOBLK+QIO$_P4	;NO CARRIAGE CONTROL
	BISB	#SD_M_INTRNLCC,SD_B_GEN_FLAGS ;SHOW INTERNAL CARRIAGE CONTROL
;
; CHECK IF 'CR-LF' CARRIAGE CONTROL
50$:	BBC	#FAB$V_CR,SD_G_FAB+FAB$B_RAT,60$ ;BR IF NOT 'CR-LF'
	MOVZBL	#^A\ \,SD_G_QIOBLK+QIO$_P4 ;SET SINGLE SPACE CC
;
; INITIALIZE THE I/O STATUS
60$:	CLRQ	SD_Q_IOSB		;CLEAR I/O STATUS
;
; MAIN I/O LOOP, DO THE GET
220$:	MOVAL	SD_G_RAB,R3		;GET ADDR OF RAB
;	MOVAL	SD_T_LBUF,RAB$L_UBF(R3)
	$GET	RAB=SD_G_RAB		;GET A RECORD
	INCL	SD_L_GETCNT		;ADD 1 TO GET COUNT
	BLBS	R0,230$			;BR IF SUCCESS
;
; GET ERROR - CHECK IT
	CMPL	#RMS$_EOF,R0		;WAS IT EOF
	BNEQ	225$			;BR IF NOT
	BRW	400$			;EOF IMPLIES WE ARE DONE
225$:	ASSUME	RAB$L_STV EQ RAB$L_STS+4
	MOVL	#5,SD_L_NUM_ERROR	;LOAD NO. OF ERROR CODES
	MOVL	#<4@16>!SHR$_READERR!4,SD_T_ERROR ;CONDITION CODE
	MOVL	#1,SD_T_ERROR+4		;1 FAO ARGUMENT
	MOVAL	SD_Q_FILE_SPEC,SD_T_ERROR+8 ;ADDRESS OF FILE SPEC DESCRIPTOR
	MOVQ	SD_G_RAB+RAB$L_STS,SD_T_ERROR+12 ;RMS STATUS CODES
	BRW	390$			;GO HANDLE UNEXPECTED ERROR
;
; SET BUFFER ADDRESS AND LENGTH
230$:	MOVL	RAB$L_RBF(R3),R1	;GET ADDR OF RECORD
 
; *** NOTE *** MOVZWL SETS COND CODES. CHECKED AT FTN CC AND AT 100$
 
	MOVZWL	RAB$W_RSZ(R3),R0	;GET LENGTH OF RECORD
;
; CHECK FOR FORTRAN CARRIAGE CONTROL
	BBC	#FAB$V_FTN,SD_G_FAB+FAB$B_RAT,290$ ;BR IF NOT FTN CC
	BNEQ	240$			;BR IF NOT NULL (COND CODE SET ON MOVZWL)
	MOVB	#^A\ \,R3		;SET BLANK CC - LENGTH ALREADY ZERO
	BRB	280$			;BR TO SET CARRIAGE CONTROL
240$:	DECL	R0			;ADJUST COUNT FOR CARRAIGE CONTROL BYTE
	MOVB	(R1)+,R3		;GET CARRIAGE CONTROL BYTE
	CMPB	#^A\1\,R3		;WILL THIS BE A FORM FEED
	BNEQ	280$			;BR IF NO
	BISB	#SD_M_FFREQ,SD_B_GEN_FLAGS ;SET FORM FEED REQUIRED FLAG
	MOVB	#^A\ \,R3		;FORM FEED HANDLED BY FFREQ FLAG
280$:
	MOVB	R3,SD_G_QIOBLK+QIO$_P4 ;SET UP CARRIAGE CONTROL
	BRB	310$
;
; CHECK FOR PRINT FILE CARRIAGE CONTROL
290$:	BBC	#FAB$V_PRN,SD_G_FAB+FAB$B_RAT,295$ ; BR IF NOT PRINT FILE
	CMPB	SD_T_SQBUF,#FF!128	;IS PREFIX A FORM FEED?
	BNEQ	293$			;BR IF NOT
	BISB	#SD_M_FFREQ,SD_B_GEN_FLAGS ;SET FORM FEED REQUIRED FLAG
	CLRB	SD_T_SQBUF		;FORM FEED HANDLED BY FFREQ FLAG
293$:	ASHL	#16,SD_T_SQBUF,-	;SET CARRIAGE CONTROL
		SD_G_QIOBLK+QIO$_P4
	TSTL	R0			;SET Z BIT FOR BYTE COUNT
;
; CHECK FOR INTERNAL CARRIAGE CONTROL
295$:	BBS	#SD_V_INTRNLCC,SD_B_GEN_FLAGS,320$ ;BR IF INTERNAL C.C.
;
; CHECK FOR FORM FEED IN IMPLIED CARRIAGE CONTROL
300$:	BEQL	310$			;BR IF NULL (COND CODE SET ON MOVZWL)
	CMPB	#FF,(R1)		;IS IT A FF
	BNEQ	310$			;BR IF NO
	BISB	#SD_M_FFREQ,SD_B_GEN_FLAGS ;SET FORM FEED REQUIRED FLAG
	DECL	R0			;SUBTRACT 1 FOR FORM_FEED
	BNEQ	305$			;BR IF MORE TEXT IN LINE
	BRW	220$			;NUL LINE - GET ANOTHER
305$:	INCL	R1			;ADJUST PAST CARRAIGE CONTROL FIELD
310$:					;
	BBS	#FAB$V_PRN,SD_G_FAB+FAB$B_RAT,320$ ;BR IF PRINT FILE
;
; CHECK FOR SEQUENCE NUMBERS
	CMPB	#FAB$C_VFC,SD_G_FAB+FAB$B_RFM ;IS IT SEQUENCED
	BNEQ	320$			;BR IF NO
	SUBL	#6,R1			;MOVE ADDR BACK TO SEQ BUF
	ADDL	#6,R0			;ADD 6 FOR SEQ NO AND TAB
	PUSHR	#^M<R0,R1>		;SAVE REGS - MAKES STRING DESC FOR FAO
	MOVL	SP,R3			;GET ADDR OF STRING DESC
	$FAO_S	SEQNODESC,,(R3),-	;CONVERT SEQ NO TO ASCII
		SD_T_SQBUF
	POPR	#^M<R0,R1>		;RESTORE REGS
;
; PRINT THE LINE
320$:	BBC	#SMBMSG$V_DOUBLE_SPACE,SD_L_PRT_CTL,330$ ;BR IF NO DBL SPACE
	MOVB	#^A\0\,SD_G_QIOBLK+QIO$_P4 ;SET DOUBLE SPACE
330$:	BSBW	VRSSMB$WRITELINE	;PRINT THE LINE
	BLBC	R0,385$			;BR IF ERROR
	$WAITFR_S #VRSSMB$K_LPEFN	;WAIT FOR THE I/O TO COMPLETE
	MOVAQ	SD_Q_IOSB,R0		;GET THE IOSB ADDRESS
	BLBC	(R0),384$		;BR IF ERROR
	MOVZBL	4(R0),R1		;GET #LINES PRINTED
	BBS	#SD_V_FFREQ,SD_B_GEN_FLAGS,380$ ;BR IF LAST I/O WAS A FF
	DECL	R1			;ALREADY ASSUMED ONE LINE
	ADDB	R1,SD_B_LTPCNT		;ADD TO LINES THIS PAGE COUNT
370$:	CMPB	SD_B_LTPCNT,SD_B_PAGELEN ;# LINES GTR THAN PAGE SIZE?
	BLEQU	380$			;BR IF NO
	SUBB	SD_B_PAGELEN,SD_B_LTPCNT ;NORMALIZE
	INCL	SD_L_PAGE		;ASSUME WE ARE ON THE NEXT PAGE
	BRB	370$			;CHECK AGAIN
380$:	BICB	#SD_M_FFREQ,SD_B_GEN_FLAGS ;CLEAR FF REQUIRED
	BRW	220$			;GET AND PRINT NEXT LINE
 
384$:	MOVL	(R0),R0			;PUT STATUS IN R0
385$:	CMPL	#SS$_ABORT,R0		;ABORTING?
	BNEQ	388$			;BR IF NOT
	BBS	#SD_V_PAUS_TASK,SD_B_GEN_FLAGS,395$ ;BR IF PAUSING
	BBC	#SD_V_STOP_TASK,SD_B_GEN_FLAGS,388$ ;BR IF NOT STOPPING
	MOVL	SD_L_STOP_COND,R0	;GET STOP CONDITION
388$:	MOVL	#1,SD_L_NUM_ERROR	;1 ERROR CODE
	MOVL	R0,SD_T_ERROR		;STORE ERROR CODE
390$:	MOVL	SD_L_NUM_ERROR,R1	;GET NUMBER OF ERRORS
392$:	PUSHL	SD_T_ERROR-4[R1]	;PUSH ARGUMENT FROM ERROR BLOCK
	SOBGTR	R1,392$			;LOOP UNTIL PUSHED ALL ARGUMENTS
	CALLS	SD_L_NUM_ERROR,G^LIB$SIGNAL ;SIGNAL THE ERROR
	BRB	400$			;DONE WITH THIS JOB
;
; HANDLE PAUSE TASK FLAG
395$:	PUSHAL	#SMBMSG$K_PAUSE_TASK	;INDICATE PAUSING TASK
	PUSHAL	#0			;STREAM NO. = 0 FOR SINGLE THREADED
	CALLS	#2,G^SMB$SEND_TO_JOBCTL	;SMBMSG$K_PAUSE_TASK
	BLBC	R0,397$			;ANY ERROR IS FATAL
396$:	$PURGWS_S INADR=VRSSMB$L_ADDESC	;PURGE WORKING SET
	$HIBER_S			;HIBERNATE UNTIL TASK RESUMES
	BBCC	#SD_V_GOOD_WAKE,SD_B_GEN_FLAGS,396$ ;EXPECTING WAKE-UP?
	BICB	#SD_M_PAUS_TASK,SD_B_GEN_FLAGS ;CLEAR PAUSE TASK FLAG
	PUSHAL	#SMBMSG$K_RESUME_TASK	;INDICATE RESUMING TASK
	PUSHAL	#0			;STREAM NO. = 0 FOR SINGLE THREADED
	CALLS	#2,G^SMB$SEND_TO_JOBCTL	;SMBMSG$K_RESUME_TASK
	BLBC	R0,397$			;ANY ERROR IS FATAL
	BRW	220$			;BRANCH TO RESUME READING THE FILE
397$:	BRW	FATAL			;BR TO HANDLE FATAL ERROR
;
; FILE PRINTED, SET PAPER TO TOP OF PAGE
399$:	.LONG	<-1*100*1000*1000>,-1	;10 SECOND DELTA TIME
400$:	$SETIMR_S  #VRSSMB$K_TIMEFN,B^399$,- ;TIMER IN CASE PRINTER BROKEN
		VRSSMB$CANCELIO		;GO CANCEL I/O IF IT TIMES OUT
	BSBW	VRSSMB$TOPOFORM		;PUT PAPER AT TOP OF FORM
	$CANTIM_S			;CANCEL TOP OF FORM TIMER
;
; FILE PRINTING DONE
	TSTW	SD_G_FAB+FAB$W_IFI	;HAS OPEN BEEN DONE?
	BEQL	450$			;BR IF NO
	$CLOSE	SD_G_FAB		;CLOSE THE FILE
450$:	PUSHAL	SD_L_NUM_ERROR		;ADDRESS OF ERROR STATUS
	PUSHAL	SD_L_DEV_STAT		;DEVICE STATUS
	CLRL	-(SP)			;CHECKPOINT DATA
	PUSHAL	SD_Q_ACC_DATA		;ADDR. OF DESCR. OF ACCOUNTING DATA
	BBC	#SMBMSG$V_FILE_FLAG,SD_L_SEP_CTL,455$ ;BR IF NO FLAG PAGE
	INCL	SD_L_PAGE		;INCREMENT TO ACCOUNT FOR FLAG PAGE
	BBC	#SMBMSG$V_FILE_BURST,SD_L_SEP_CTL,455$ ;BR IF NO BURST PAGE
	INCL	SD_L_PAGE		;INCREMENT TO ACCOUNT FOR BURST PAGE
455$:	PUSHAL	#SMBMSG$K_TASK_COMPLETE	;ASSUME REQUEST COMPLETED
	BBC	#SD_V_STOP_TASK,SD_B_GEN_FLAGS,460$ ;BR IF NOT STOPPING
	BICB	#SD_M_PAUS_TASK!SD_M_STOP_TASK,SD_B_GEN_FLAGS ;CLEAR FLAGS
	MOVAL	#SMBMSG$K_STOP_TASK,(SP) ;INDICATE STOPPING TASK
460$:	PUSHAL	#0			;STREAM NO. = 0 FOR SINGLE THREADED
	CALLS	#6,G^SMB$SEND_TO_JOBCTL	;SMBMSG$K_TASK_COMPLETE
	BLBC	R0,FATAL		;ANY ERROR IS FATAL
	BRW	VRSSMB$MAIN		;GO AGAIN
;
; FATAL ERROR HANDLER
FATAL:	PUSHL	R0			;PUSH ERROR CODE
	CALLS	#1,G^LIB$SIGNAL		;SIGNAL ERROR CONDITION
	$EXIT_S	R0			;ERROR IS FATAL
 
	.END	VRSSMB_START
