	.TITLE	VRSSMBSUB - VERSATEC SYMBIONT SUBROUTINES
	.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."
;
;
;	VERSATEC SYMBIONT OUTPUT SUBROUTINES
;
;	B.L.	MAY, 1985	INITIAL RELEASE WITH REV. G DRIVER
;
;
	$IODEF
	$QIODEF
 
	DC1	=	^X11		;CODE FOR TRANSPARENT PRINT
	DC2	=	^X12		;CODE FOR PLOT
	DC1_S	=	^X91		;CODE FOR TRANSPARENT PRINT, SWAP
	DC2_S	=	^X92		;CODE FOR PLOT, SWAP
	DC3	=	^X13		;CODE FOR REMOTE FUNCTION
	IO$M_PLOT	=^X40		;FUNCTION MODIFIER FOR PLOT
	IO$M_REMOTE	=^X80		;FUNCTION MODIFIER FOR REMOTE
	IO$M_SWAPBYTES	=^X400		;FUNCTION MODIFIER FOR SWAP-BYTES
 
	.LIBRARY	\SYS$LIBRARY:LIB\
	$SMBDEF
 
;
; PAGE HEADER $FAO DESCRIPTOR
;
	.PSECT	VRSSMBSUB,EXE,RD,NOWRT,LONG
HEADER_DESC:
	.WORD		HEADER_DESC_END - HEADER_DESC_START,0
	.ADDRESS	HEADER_DESC_START
HEADER_DESC_START:
	.ASCII		\!AS        !17%D        Page !UL!/\
HEADER_DESC_END:
 
	.PAGE
	.SBTTL	TOP OF FORMS AND PAGE HEADER
;
; ROUTINE TO ISSUE A TOP OF FORMS OR A TOP OF FORMS AND A PAGE HEADER.
 
	.ENABL	LSB
VRSSMB$TOPOFORM::
	PUSHR	#^M<R2>			;SAVE REGISTER
	MOVAL	SD_T_TBUF,R0		;SET DUMMY BUFFER ADDRESS
	CLRL	R1			;NO BUFFER LENGTH
	MOVB	#^A\1\,R2		;FF CARRIAGE CONTROL
	CLRB	SD_B_LTPCNT		;INIT LINES THIS PAGE COUNT
	BRB	10$
 
VRSSMB$PAGEHDRNFF::
	PUSHR	#^M<R2>			;SAVE REGISTER
	MOVB	#^A\ \,R2		;NO FORM FEED
	BRB	5$			;
 
VRSSMB$PAGEHDR::
	PUSHR	#^M<R2>			;SAVE REGISTER
	MOVB	#^A\1\,R2		;FF CARRIAGE CONTROL
;
; CREATE THE PAGE HEADER
;
5$:	PUSHAW	#88			;MAX NAME IS 88 CHARS.
	PUSHAQ	SD_Q_FILE_TRIM		;ADDR. OF DESCR. OF TRIMMED FILESPEC
	PUSHAQ	SD_Q_FILE_SPEC		;ADDR. OF DESCR. OF FILESPEC
	CALLS	#3,G^LIB$TRIM_FILESPEC	;TRIM FILESPEC TO FIT HEADER
	BLBC	R0,30$			;BR IF ERROR
	PUSHL	SD_L_PAGE		;PAGE NUMBER
	PUSHAL	SD_Q_PTIME		;PRINT TIME
	PUSHAQ	SD_Q_FILE_TRIM		;TRIMMED FILE SPEC DESCRIPTOR ADDRESS
	PUSHAQ	SD_Q_HDBUF		;OUTPUT BUFFER DESC ADDRESS
	PUSHAW	SD_W_HEAD_L		;RESULTING LENGTH RETURNED HERE
	PUSHAQ	HEADER_DESC		;FORMAT DESCRIPTOR
	CALLS	#6,@#SYS$FAO		;CALL $FAO
	BLBC	R0,30$			;BR IF ERROR
	MOVAL	SD_T_HDBUF,R0		;SET HEADER BUFFER ADDRESS
	MOVZWL	SD_W_HEAD_L,R1		;GET HEADER LENGTH
	MOVB	#2,SD_B_LTPCNT		;INIT LINE COUNT TO 2
10$:
 
;
; ISSUE THE SPECIAL QIO
;
 
	$QIOW_S	-			;PRINT THE FORM FEED AND HEADER
	EFN=#VRSSMB$K_TOFEFN,-		;EFN
	CHAN=SD_G_QIOBLK+QIO$_CHAN,-	;CHANNEL
	FUNC=#IO$_WRITELBLK,-		;FUNCTION
	IOSB=SD_Q_TOFIOSB,-		;IOSB ADDRESS
	P1=(R0),-			;BUFFER ADDRESS
	P2=R1,-				;BUFFER LENGTH
	P4=R2				;CARRIAGE CONTROL
	INCL	SD_L_QIOCNT		;ADD 1 FOR FORM FEED QIO
	BLBC	R0,30$			;BR IF ERROR
	MOVZWL	SD_Q_TOFIOSB,R0		;GET I/O STATUS
30$:	POPR	#^M<R2>			;RESTORE REGISTERS
	RSB				;RETURN
 
	.DSABL	LSB
	.PAGE
	.SBTTL	SYMBIONT PRINT LINE ROUTINE
;
;	THIS ROUTINE IS CALLED TO PRINT A LINE ON THE
;	OUTPUT DEVICE.
;
; INPUT PARAMETERS:
;	R0 IS THE COUNT OF BYTES TO PRINT
;	R1 IS THE ADDRESS OF THE LINE BUFFER
;
; OUTPUT PARAMETERS:
;	THE LINE IS QUEUED FOR PRINTING
;	R0 IS SET AS PER THE RESULT
;
; COMPLETION CODES:
;	AS SET BY THE QIO SYSTEM SERVICE
 
VRSSMB$WRITELINN::			;WRITE LINE - NORMAL CARRIAGE CONTROL
	MOVZBL	#^A/ /,SD_G_QIOBLK+QIO$_P4 ;SET CARRAIGE CONTROL BYTE
VRSSMB$WRITELINS::
 
	.ENABL	LSB
 
	BSBB	VRSSMB$WRITELINE	;PRINT THE LINE
	BLBC	R0,20$			;IF ERROR GET OUT, ERROR ALREADY SET
	$WAITFR_S SD_G_QIOBLK+QIO$_EFN	;WAIT FOR THE I/O
	MOVL	SD_G_QIOBLK+QIO$_IOSB,R1 ;GET IOSB ADDRESS
	MOVZWL	(R1),R0			;GET I/O STATUS
20$:	RSB				;RETURN
 
	.DSABL	LSB
	.ENABL	LSB
 
VRSSMB$WRITELINE::			;WRITE A LINE TO THE PRINTER
;
; SET UP QIO PARAMETERS
	MOVAQ	SD_Q_IOSB,SD_G_QIOBLK+QIO$_IOSB ;SET IOSB ADDRESS
	MOVL	#VRSSMB$K_LPEFN,SD_G_QIOBLK+QIO$_EFN ;SET EFN
	MOVZWL	#IO$_WRITELBLK,SD_G_QIOBLK+QIO$_FUNC ;SET FUNCTION
	CMPL	#2,R0			;AT LEAST 2 BYTES IN RECORD?
	BLEQ	1$			;CONTINUE IF SO
	BRW	10$			;SKIP DCx CHECK IF NOT
1$:	CMPW	(R1),#DC1		;PRINT TRANSPARENT DATA?
	BNEQ	2$			;BRANCH IF NOT
	BISL	#IO$M_NOFORMAT,SD_G_QIOBLK+QIO$_FUNC ;SET NOFMT
	BBS	#SMBMSG$V_TERMINAL,SD_L_DEV_STAT,515$ ;BRANCH IF ASYNC.
	BISL	#IO$M_INHRETRY,SD_G_QIOBLK+QIO$_FUNC ;SET NOFMT
515$:	BRW	9$
2$:	CMPW	(R1),#DC1_S		;PRINT TRANSPARENT DATA, SWAPBYTES?
	BNEQ	3$			;BRANCH IF NOT
	BISL	#IO$M_NOFORMAT,SD_G_QIOBLK+QIO$_FUNC ;SET NOFMT
	BBS	#SMBMSG$V_TERMINAL,SD_L_DEV_STAT,7$ ;BRANCH IF ASYNC.
	BISL	#IO$M_SWAPBYTES!IO$M_INHRETRY,-
			SD_G_QIOBLK+QIO$_FUNC ;SET PRINT TRANSPARENT, SWAP
	BRB	6$
3$:	CMPW	(R1),#DC2		;PLOT DATA?
	BNEQ	4$			;BRANCH IF NOT
	BISL	#IO$M_NOFORMAT!IO$M_PLOT!IO$M_INHRETRY,-
			SD_G_QIOBLK+QIO$_FUNC ;SET PLOT
	BRB	6$
4$:	CMPW	(R1),#DC2_S		;PLOT DATA, SWAPPED?
	BNEQ	5$			;BRANCH IF NOT
	BISL	#IO$M_NOFORMAT!IO$M_PLOT!IO$M_SWAPBYTES!IO$M_INHRETRY,-
			SD_G_QIOBLK+QIO$_FUNC ;SET PLOT, SWAP
	BRB	6$
5$:	CMPB	(R1),#DC3		;REMOTE FUNCTION
	BNEQ	10$			;BRANCH IF NOT
	MOVZBL	1(R1),SD_G_QIOBLK+QIO$_P3 ;LOAD REMOTE FUNCTION CODE
	BISL	#IO$M_REMOTE!IO$M_PLOT!IO$M_INHRETRY,-
			SD_G_QIOBLK+QIO$_FUNC ;SET REMOTE
6$:	BBC	#SMBMSG$V_TERMINAL,SD_L_DEV_STAT,9$ ;BRANCH IF PRINTER
	BRW	70$			;IF TERMINAL, IGNORE
7$:	PUSHR	#^M<R2,R3,R4>		;SAVE REGISTERS R2, R3, AND R4
	SUBL3	#1,R0,R2		;PUT BYTE COUNT OF DATA + 1 IN R2
				;(SUBTRACT 1 INSTEAD OF 2 IN CASE COUNT IS ODD)
	DIVL	#2,R2			;CONVERT TO WORD COUNT
	ADDL3	#2,R1,R3		;PUT ADDRESS IS R3
8$:	MOVB	(R3),R4			;GET LOW BYTE INTO R4
	MOVB	1(R3),(R3)+		;PUT HIGH BYTE IN LOW BYTE
	MOVB	R4,(R3)+		;PUT LOW BYTE IN HIGH BYTE
	SOBGTR	R2,8$			;LOOP UNTIL SWAPPED WHOLE BUFFER
	POPR	#^M<R2,R3,R4>		;RESTORE REGISTERS R2, R3, AND R4
9$:	ADDL	#2,R1			;BUMP ADDRESS BY 2
	SUBL	#2,R0			;DECREMENT BYTE COUNT BY 2
10$:	MOVL	R0,SD_G_QIOBLK+QIO$_P2 	;SET BUFFER LENGTH
	MOVL	R1,SD_G_QIOBLK+QIO$_P1	;SET BUFFER ADDRESS
;
; CHECK IF FORM-FEED/HEADER SHOULD BE PRINTED
	BBS	#SD_V_FLGPAG,SD_B_GEN_FLAGS,50$ ;BR IF PRINTING FLAG PAGE
	BBS	#SD_V_INTRNLCC,SD_B_GEN_FLAGS,50$ ;BR IF INTERNAL CARRG CTRL
	BBSC	#SD_V_FLGPAGDONE,SD_B_GEN_FLAGS,50$ ;BR IF FLAG PAGE JUST DONE
	BBS	#SD_V_FFREQ,SD_B_GEN_FLAGS,20$ ;BR IF FF REQUIRED
	CMPB	SD_B_MAXLTP,SD_B_LTPCNT ;IS LINE COUNT TOO BIG
	BGEQU	50$			;BR IF NO - PRINT LINE
	BBC	#SMBMSG$V_PAGINATE,SD_L_PRT_CTL,50$ ;BR IF NO FORM FEED
20$:	INCL	SD_L_PAGE		;INCREMENT THE PAGE NUMBER
	BBC	#SMBMSG$V_PAGE_HEADER,SD_L_PRT_CTL,30$ ;BR IF NO PAGE HEADER
	BSBW	VRSSMB$PAGEHDR		;PRINT THE HEADER
	BLBC	R0,60$			;BR IF NOT OK
	BRB	50$
30$:	BSBW	VRSSMB$TOPOFORM		;DO THE FORM FEED
	BLBC	R0,60$			;BR IF NOT OK
;
; QUEUE THE LINE TO THE PRINTER
50$:	BBS	#SD_V_STOP_TASK,SD_B_GEN_FLAGS,55$ ;BRANCH IF STOPPING
	INCL	SD_L_QIOCNT		;ADD 1 FOR THE QIO COUNT
	INCB	SD_B_LTPCNT		;ASSUME ONE LINE WILL BE PRINTED
	$QIO_G	SD_G_QIOBLK		;ISSUE THE QIO
	BLBC	R0,60$			;BR IF NOT OK
	BBC	#SD_V_PAUS_TASK,SD_B_GEN_FLAGS,60$ ;BR IF NOT PAUSING
55$:	MOVL	#SS$_ABORT,R0		;SET ABORTING STATUS
60$:	RSB
 
70$:	MOVL	#1,R0			;SET SUCCESS STATUS
	RSB				;UNSUPPORTED DATA TYPE FOR TERMINAL
	.DSABL	LSB
 
	.PAGE
	.SBTTL	CANCEL I/O ROUTINE
	.ENTRY	VRSSMB$CANCELIO,^M<>
	$CANCEL_S	SD_G_QIOBLK+QIO$_CHAN	;CANCEL I/O ON CHANNEL
	RET
 
	.END
