; maile3/asm - kjw/bqsd - version 2.00 - 01/83
;
; revised 02/10/83 - kjw
;
	SUBTTL	'<maile3/asm - printer logic>'
;
	PAGE
;
LABEL	LD	A,(BUFFER)	;get first byte data rec
	INC	A		;dead file?
	RET	Z		;yes, don't print it!
	LD	A,(IY+1)	;get flags
	BIT	6,A		;listing?
	JP	NZ,DOLIST	;yes, send to printer
;
;	setup loop to execute repeat count
;
	LD	B,(IY+18)	;get repeat count
RPCTLP	PUSH	BC		;save count
	CALL	REPOINT		;write labels to buf/prt
	POP	BC		;restore count
	DJNZ	RPCTLP		;go for count
	XOR	A		;return Z
	RET			;done
;
;	check if enough records in memory
;
REPOINT	LD	DE,$		;get memory pointer
POINTER	EQU	$-2
	LD	HL,BUFFER	;record stored here
	LD	BC,128		;buffer length
	LDIR			;save record
	LD	(POINTER),DE	;update pointer
	LD	A,'$'		;get # records in memory
RECCNT	EQU	$-1
	INC	A		;+1
	LD	(RECCNT),A	;update counter
	CP	(IY+15)		;enough to begin printing
	RET	C		;nope! continue
	CALL	FLUSH		;flush printer buffer
	XOR	A		;return Z
	RET			;done with label!
;
;	write contents of memory buffer to printer
;
FLUSH	BIT	6,(IY+1)	;labels?
	RET	NZ		;nope, listing!
	LD	A,(RECCNT)	;get record counter
	OR	A		;any records to flush?
	RET	Z		;nope, go!
	LD	C,A		;pass to C
	XOR	A		;load zero
	LD	(RECCNT),A	;clear record counter
	LD	(LINEC),A	;clear line counter
	LD	HL,$		;get low memory start
NEWPNT	EQU	$-2
	LD	(POINTER),HL	;reset buff pointer
	LD	IX,LABTBL1	;label printing table
	LD	A,(IY+1)	;get format type
	AND	3		;low 2 bits only
	JR	Z,PRLABLP	;go if have table
	LD	IX,LABTBL2	;label format 2
;
;	loop to print each label
;
PRLABLP	LD	A,(IX+0)	;get table entry
	INC	A		;FF terminator?
	JR	Z,PRLABEN	;go if done!
	PUSH	BC		;save count
	LD	HL,PRTBUFF	;printer buffer
	LD	(PLACE),HL	;save position
	LD	(IY+19),0	;clear char counter
	CALL	LABPUT		;construct single line
	POP	BC		;restore C
	LD	HL,(PLACE)	;get printer position
	LD	(HL),CR		;carriage return
	INC	HL		;bump pointer
	LD	(HL),ETX	;end of text
	LD	HL,PRTBUFF	;start of stored data
	BIT	7,(IY+23)	;compress?
	JR	NZ,GOEPRT	;go on empty
	LD	A,(IY+19)	;get char counter
	OR	A		;any chars?
	JR	Z,PRLABLP	;go if nil!
	CALL	CMPPRT		;compress print buffer
	JR	Z,PRLABLP	;go if nil!
GOEPRT	CALL	LPRINT		;print no adjust
	LD	A,(LINEC)	;get line counter
	INC	A		;+1
	LD	(LINEC),A	;update
	JR	PRLABLP		;continue
;
;	label done, adjust line counter
;
PRLABEN	LD	A,'$'		;get line counter
LINEC	EQU	$-1
	OR	A		;anything?
	RET	Z		;nope, go next label!
	LD	B,A		;pass value
	LD	A,(IY+17)	;get label length
	SUB	B		;test to # printed
	JR	Z,RESLC		;go if just enough
	JR	C,RESLC		;go if too many
	LD	B,A		;pass count
LINCC	PUSH	BC		;save count
	CALL	LINE		;send linefeed
	POP	BC		;restore count
	DJNZ	LINCC		;go for B times
RESLC	XOR	A		;load zero
	LD	(LINEC),A	;reset line counter
	RET			;done! line count adjustd
;
;	check for empty line buffer
;
CMPPRT	PUSH	HL		;save start
	LD	B,-1		;init counter
CKEP1	INC	B		;bump counter
CKEP2	LD	A,(HL)		;get a char
	INC	HL		;bump pointer
	CP	ETX		;done?
	JR	Z,CKEP3		;go if done!
	CP	CR		;done?
	JR	Z,CKEP3		;go if yes
	CP	' '		;blank?
	JR	Z,CKEP2		;yes, don't count
	JR	CKEP1		;else count a char
CKEP3	LD	A,B		;get counter
	OR	A		;any chars in buffer?
	POP	HL		;restore start
	RET			;Z = no chars!
;
;	send current buffer to printer
;
LABPUT	LD	(IXSTRT),IX	;save pointer for loop
	XOR	A		;load zero
	LD	(PRTTAB),A	;clear printer tab
	LD	(MEMPTR),A	;clear mem pointer
;
LABLPO	LD	IX,$		;get start pointer
IXSTRT	EQU	$-2
	LD	B,(IX+0)	;get # entries
	INC	IX		;IX => descriptor list
;
LABPLP	PUSH	BC		;save
	CALL	SNDFLD		;send field to printer
	POP	BC		;restore count
	LD	A,' '		;space to end
	CALL	TOPBUF		;to buffer
	INC	IX		;bump table
	INC	IX		;2 byte descriptors
	DJNZ	LABPLP		;go for length
	LD	A,'$'		;get buff #
MEMPTR	EQU	$-1
	INC	A		;bump it
	LD	(MEMPTR),A	;update #
	LD	A,'$'		;get printer tab spot
PRTTAB	EQU	$-1
	ADD	A,(IY+16)	;label width
	LD	(PRTTAB),A	;update pointer
	CALL	PADPRT		;position buff pointer
	DEC	C		;less buff counter
	JR	NZ,LABLPO	;go outer loop if more
	RET			;buffer done!
;
;	pad buffer to next tab stop
;
PADPRT	CP	(IY+19)		;at tap stop now?
	RET	C		;past
	RET	Z		;at it
	PUSH	AF		;save
	LD	A,' '		;load blank
	CALL	TOPBUF		;to printer buffer
	POP	AF		;restore
	JR	PADPRT		;continue
;
;	place char into printer buffer
;
TOPBUF	PUSH	HL		;save
	LD	HL,$		;get memory buffer
PLACE	EQU	$-2
	LD	(HL),A		;char to buffer
	INC	HL		;bump pointer
	LD	(PLACE),HL	;update
	INC	(IY+19)		;bump char counter
	POP	HL		;restore HL
	RET			;done!
;
;	send field (IX+0), (IX+1)
;
SNDFLD	LD	A,(MEMPTR)	;get mem pointer
	SRL	A		;divide in half
	LD	H,A		;pass to MSB offset
	LD	A,0		;load zero
	RRA			;carry => bit 7
	LD	L,A		;HL = (MEMPTR) * 128!
	LD	DE,(NEWPNT)	;get start of saved data
	ADD	HL,DE		;HL => data
	LD	E,(IX+0)	;get data offset
	LD	D,0		;DE = offset
	ADD	HL,DE		;HL => data entry
	LD	B,(IX+1)	;B = data length
	BIT	7,(IY+23)	;compress blanks?
	JR	NZ,NOCOMP	;nope, go!
;
;	remove trailing spaces from entry
;
	PUSH	HL		;save text start
	PUSH	BC		;save
	LD	C,B		;pass length
	LD	B,0		;BC = offset
	ADD	HL,BC		;HL => last +1
	DEC	HL		;HL => last char
	POP	BC		;restore B length
;
REMSPC	LD	A,(HL)		;get a char
	CP	' '		;blank?
	JR	NZ,NOCOMP-1	;done, go if not!
	DEC	HL		;less pointer
	DJNZ	REMSPC		;continue for length
	POP	HL		;restore stack
	RET			;done, no chars!
;
	POP	HL		;restore start
NOCOMP	LD	A,(HL)		;get a char
	CALL	TOPBUF		;to printer buffer
	INC	HL		;bump pointer
	DJNZ	NOCOMP		;go for length
	RET			;done!
;
;	send current record to printer
;
DOLIST	AND	3		;get format type
	ADD	A,A		;2 byte table
	BIT	5,(IY+1)	;80 col?
	JR	Z,$+4		;go if yes
	ADD	A,8		;offset to 132 table
	LD	C,A		;pass to C
	LD	B,0		;BC = offset
	LD	IX,PRTTBL	;printer table
	ADD	IX,BC		;IX => vector
	LD	C,(IX+0)	;get vector
	LD	B,(IX+1)	;BC = table address
	PUSH	BC		;pass to IX
	POP	IX		;IX => table
;
;	check if # labels / form issued
;
	LD	A,(IY+39)	;get # records before
	OR	A		;at 00?
	JR	NZ,CNTLST	;nope, continue
	CALL	NEWPAGE		;new page header
	LD	A,(IX+0)	;get reset count
	LD	(IY+39),A	;reset count
;
;	setup loop to send label to printer
;
CNTLST	INC	IX		;bump table entry
	LD	A,(IX+0)	;get byte
	LD	HL,LSTTBL	;listing table
	CALL	GOTABLE		;control byte?
;
;	non-control, print information
;
	LD	HL,BUFFER	;start of information
	LD	C,(IX+0)	;get data offset
	LD	B,0		;BC = offset
	ADD	HL,BC		;HL => data to print
	LD	B,(IX+1)	;get data length
	CALL	TOBUFF		;send to printer buffer
	INC	IX		;bump table
	JR	CNTLST		;continue next entry
;
;	table terminator
;
LIM1	DEC	(IY+39)		;less this label
	XOR	A		;set no error
	RET			;record complete!
;
;	terminate line(CR)
;
LIM2	CALL	LINE		;flush buffer
	JR	CNTLST		;continue
;
;	print flag #'s of file
;
LIM3	LD	A,1		;start flag #
LIM3A	PUSH	AF		;save flag #
	CALL	IFFLAG		;flag set?
	JR	Z,LIM3B		;go if not set
	POP	AF		;get flag #
	PUSH	AF		;save again
	CALL	ASCII		;to ascii
	LD	A,C		;get MSB
	CALL	POUT		;to printer
	LD	A,B		;get LSB
	CALL	POUT		;to printer
	LD	A,' '		;blank
	CALL	POUT		;to printer
;
LIM3B	POP	AF		;get flag #
	INC	A		;+1
	CP	25		;1-24?
	JR	C,LIM3A		;yes, go next flag
	CALL	LINE		;send CR
	JR	CNTLST		;go next entry
;
;	print flag names
;
LIM4	LD	A,(IX+1)	;get # flags / line
	LD	(LIM4C),A	;reset counter
	XOR	A		;load zero
	LD	(LIM4CC),A	;save flag line counter
	INC	A		;start flag # (1)
;
LIM4A	PUSH	AF		;save flag #
	CALL	IFFLAG		;flag set?
	JR	Z,LIM4B		;go if not
	POP	AF		;get flag # back
	PUSH	AF		;save on stack
	PUSH	IX		;save table pointer
	PUSH	AF		;save flag #
	LD	A,(IY+14)	;get current drive #
	CALL	LOCFILE		;locate file block
	LD	L,(IX+10)	;get flag name address
	LD	H,(IX+11)	;HL => flag name start
	POP	AF		;get flag #
	DEC	A		;adjust zero relative
	ADD	A,A		;*2
	ADD	A,A		;*4
	ADD	A,A		;*8
	LD	C,A		;C = offset
	LD	B,0		;BC = offset
	ADD	HL,BC		;HL => flag name
	LD	A,(IY+19)	;get char counter
	OR	A		;anything?
	LD	A,'/'		;flag separator
	CALL	NZ,POUT		;yes, print separator
	LD	B,8		;8 chars to print
	CALL	TOBUFF		;send to printer
	POP	IX		;restore IX
;
LIM4B	LD	A,'$'		;get # / line
LIM4C	EQU	$-1
	DEC	A		;less 1
	LD	(LIM4C),A	;update count
	JR	NZ,LIM4D	;go if not at end
	CALL	LINE		;print!
	LD	A,(IX+1)	;get # flags / line
	LD	(LIM4C),A	;reset counter
	LD	A,(LIM4CC)	;get line counter
	INC	A		;bump it
	LD	(LIM4CC),A	;resave it
;
LIM4D	POP	AF		;restore flag #
	INC	A		;+1
	CP	25		;1-24?
	JR	C,LIM4A		;go next one if more
	LD	A,(IX+2)	;get line count
	SUB	'$'		;less # lines done
LIM4CC	EQU	$-1
	INC	IX		;bump table
	INC	IX		;3 bytes this entry
	JP	Z,CNTLST	;go if correct!
	LD	B,A		;pass # left
	CALL	LINE		;go blank line
	DJNZ	$-3		;finish
	JP	CNTLST		;go next entry
;
;	print blank line
;
LIM5	CALL	LINE		;print blank line
	JP	CNTLST		;continue
;
;	print line of '='
;
LIM6	CALL	DASHES		;line of dashes
	JP	CNTLST		;contine listing
;
DASHES	LD	B,80-1		;80 cols printer
	BIT	5,(IY+1)	;80 cols?
	JR	Z,$+4		;go if yes
	LD	B,132-1		;132 col printer
;
LIM6A	LD	A,'='		;send =
	CALL	POUT		;to printer
	DJNZ	LIM6A		;for printer length
	JP	LINE		;send CR
;
;	print 'NOTES' as header
;
LIM7	LD	HL,NOTMSG	;notes message
	CALL	LPRINT		;to printer
	JP	CNTLST		;continue
;
;	print single space
;
LIM8	LD	A,' '		;send space
	CALL	POUT		;to printer
	JP	CNTLST		;continue
;
;	send current line to printer
;
TOBUFF	LD	A,(HL)		;get a char
	CALL	POUT		;to printer
	INC	HL		;bump pointer
	DJNZ	TOBUFF		;go for length
	RET			;done!
;
;**
;
;	convert A to CB in ascii
;
ASCII	LD	C,'0'		;init msb
ASC1	SUB	10		;less 10's place
	JR	C,ASC2		;go if done!
	INC	C		;bump ascii
	JR	ASC1		;continue
ASC2	ADD	A,'0'+10	;ascii + last sub
	LD	B,A		;pass lsb to B
	RET			;done, CB = ascii
;
;	check if current flag is set
;
IFFLAG	LD	DE,BUFFER+125	;start of flags
;
IFFF0	LD	B,1		;init test bit
;
IFFF1	DEC	A		;have flag ?
	JR	Z,IFFF3		;go if found!
	SLA	B		;shift test bit
	JR	NC,IFFF1	;go if not done with byte
	INC	DE		;bump flag pointer
	JR	IFFF0		;go next byte
;
IFFF3	LD	A,(DE)		;get user flag
	AND	B		;is flag set?
	RET			;NZ = flag set!
;
;##
;
NOTMSG	DEFM	'Notes:'
	DEFB	ETX
;
;###
;
;	lookup table for listing type format
;
PRTTBL	DEFW	LIST0		;80 col / flag names
	DEFW	LIST1		;80 col / flag #'s
	DEFW	LIST2		;80 col / salesman notes
	DEFW	LIST3		;80 col / packed list
	DEFW	LIST4		;132 col / flag names
	DEFW	LIST5		;132 col / flag #'s
	DEFW	LIST6		;132 col / salesman notes
	DEFW	LIST7		;132 col / packed list
;
;	definition tables for listing formats
;
;	+0	- # records / page
;	+1	-1 = table terminator
;		-2 = terminate current line
;		-3 = print flag #'s on current line
;		-4 = print flag names, (+2 = # / line)
;		-5 = print single blank line
;		-6 = print line of '='
;		-7 = print 'Notes:'
;		-8 = print single space
;	+1,2	else data offset, data length
;
LIST0	DEFB	10
	DEFB	000,15,-8
	DEFB	015,10,-8
	DEFB	025,20,-8
	DEFB	045,20,-8
	DEFB	065,10,-2
	DEFB	075,15,-8
	DEFB	090,08,-8
	DEFB	098,10,-8
	DEFB	108,05,-8
	DEFB	113,12,-2
	DEFB	-4,8,3
	DEFB	-6
	DEFB	-1
;
LIST1	DEFB	15
	DEFB	000,15,-8
	DEFB	015,10,-8
	DEFB	025,20,-8
	DEFB	045,20,-8
	DEFB	065,10,-2
	DEFB	075,15,-8
	DEFB	090,08,-8
	DEFB	098,10,-8
	DEFB	108,05,-8
	DEFB	113,12,-2
	DEFB	-3
	DEFB	-6
	DEFB	-1
;
LIST2	DEFB	6
	DEFB	000,15,-8
	DEFB	015,10,-8
	DEFB	025,20,-8
	DEFB	045,20,-8
	DEFB	065,10,-2
	DEFB	075,15,-8
	DEFB	090,08,-8
	DEFB	098,10,-8
	DEFB	108,05,-8
	DEFB	113,12,-2
	DEFB	-4,8,3
	DEFB	-7
	DEFB	-5,-5,-5,-6
	DEFB	-1
;
LIST3	DEFB	60
	DEFB	000,15,-8
	DEFB	015,10,-8
	DEFB	025,20,-8
	DEFB	075,15,-8
	DEFB	090,08,-2
	DEFB	-1
;
LIST4	DEFB	15
	DEFB	000,15,-8
	DEFB	015,10,-8
	DEFB	025,20,-8
	DEFB	045,20,-8
	DEFB	065,10
	DEFB	075,15,-8
	DEFB	090,08
	DEFB	098,10
	DEFB	108,05,-8
	DEFB	113,12,-2
	DEFB	-4,12,2
	DEFB	-6
	DEFB	-1
;
LIST5	DEFB	20
	DEFB	000,15,-8
	DEFB	015,10,-8
	DEFB	025,20,-8
	DEFB	045,20,-8
	DEFB	065,10
	DEFB	075,15,-8
	DEFB	090,08
	DEFB	098,10
	DEFB	108,05,-8
	DEFB	113,12,-2
	DEFB	-3
	DEFB	-6
	DEFB	-1
;
LIST6	DEFB	10
	DEFB	000,15,-8
	DEFB	015,10,-8
	DEFB	025,20,-8
	DEFB	045,20,-8
	DEFB	065,10
	DEFB	075,15,-8
	DEFB	090,08
	DEFB	098,10
	DEFB	108,05,-8
	DEFB	113,12,-2
	DEFB	-4,12,2
	DEFB	-7
	DEFB	-5,-6
	DEFB	-1
;
LIST7	DEFB	60
	DEFB	000,15,-8
	DEFB	015,10,-8
	DEFB	025,20,-8
	DEFB	045,20,-8
	DEFB	065,10
	DEFB	075,15,-8
	DEFB	090,08
	DEFB	098,10
	DEFB	108,05,-8
	DEFB	113,12,-2
	DEFB	-1
;
;	lookup table for listing special table commands
;
LSTTBL	DEFB	-1
	DEFW	LIM1
	DEFB	-2
	DEFW	LIM2
	DEFB	-3
	DEFW	LIM3
	DEFB	-4
	DEFW	LIM4
	DEFB	-5
	DEFW	LIM5
	DEFB	-6
	DEFW	LIM6
	DEFB	-7
	DEFW	LIM7
	DEFB	-8
	DEFW	LIM8
	DEFB	ETBL
;
;	lookup table defining label formats
;
;	-1 = terminator
;	 X = count of fields
;		field = offset, length
;
LABTBL2	DEFB	2
	DEFB	108,05
	DEFB	113,12
;
LABTBL1	DEFB	2
	DEFB	015,10
	DEFB	000,15
	DEFB	1
	DEFB	025,20
	DEFB	2
	DEFB	045,20
	DEFB	065,10
	DEFB	3
	DEFB	075,15
	DEFB	090,08
	DEFB	098,10
	DEFB	-1
;
