; maile/asm - kjw/bqsd - version 2.00 - 01/83
;
; revised 02/23/83 - kjw
;
	TITLE	'<PowerMAIL - 2.00 source code>'
;
;	system data usage
;
;	+1	7 - 0 = print, 1 = count
;		6 - 0 = labels, 1 = listing
;		5 - 0 = 80 cols, 1 = 132 cols
;		4 - 0 = case OK, 1 = convert to up case
;		3 - 0 = no action on files, 1 = flag acts
;		2 - 0 = no condition, 1 = compare mask
;		1-0   = print format type
;	+7,8,9		- current logical record #
;	+10,11,12	- current physical record #
;	+13		- data offset in I/O buffer
;	+14		- current drive #
;	+15		- # labels across
;	+16		- label width
;	+17		- label length
;	+18		- repeat count
;	+19		- printer char counter
;	+20		- printer line counter
;	+21		- printer page counter
;	+22		- # active files being printed
;	+23	7 - 0 = compress blanks, 1 = NO compress
;		6 - 0 = data record
;	+24,25,26	- logical index record #
;	+27,28,29	- physical index record #
;	+30		- offset into index I/O buffer
;	+32,33,34	- # records printed/counted
;	+35,36,37	- # records passed
;
*GET	MAILEQU			;system equates
*GET	MAILDISK		;I/O drivers
;
	ORG	CODE
*GET	MAILDVRS		;I/O drivers
*GET	MAILMATH		;math subs
;
	SUBTTL	'<maile/asm - Print Utility>'
;
	PAGE
;
ENTRY	LD	IY,SYSTEM	;reset system pointer
	CALL	INTEG		;check sys integrety
	LD	A,(IY+31)	;get init flag
	CP	'*'		;inited?
	JP	NZ,CORRUPT	;go if bad!
;
MENU	LD	IY,SYSTEM	;reset data pointer
	LD	L,(IY+2)	;fetch stack pointer
	LD	H,(IY+3)	;HL = init stack
	LD	SP,HL		;reset it
	LD	(IY+1),0	;clear all flags
	LD	(IY+23),0	;alternate flags
	CALL	CLRDATA		;clear data buffer
	CALL	SHOW		;to video
	CALL	SHOWF		;flags to video
;
;	check for data all sorted similarly
;
	CALL	CKSORTO		;check sorted order
;
	LD	HL,MSG1		;menu selections
	CALL	DISPLAY		;display options
	LD	B,1		;one key input
	CALL	GETSTR		;from keyboard
	JP	C,EXIT		;go on BREAK
	JP	Z,PRINT		;print default
	LD	HL,JUMPT1	;jump table
	CALL	GOTABLE		;go vector if match
	JR	MENU		;invalid, ask again
;
;	count records
;
COUNT	SET	7,(IY+1)	;set COUNT flag
	LD	HL,MSG25	;'counting'
	CALL	DISPLAY		;display message
	JP	PRINT2		;go common
;
;	print records
;
PRINT	RES	7,(IY+1)	;set PRINT flag
	LD	HL,MSG2		;'label or listing?'
	CALL	DISPLAY		;display prompt
	LD	B,1		;single key input
	CALL	GETSTR		;from keyboard
	JP	C,MENU		;go on BREAK
	JR	Z,PRINTL	;print labels default
	LD	HL,JUMPT2	;lookup table
	CALL	GOTABLE		;go vector!
	JR	PRINT		;not found, try again
;
;	print label format
;
PRINTL	LD	HL,MSG23	;'printing labels'
	CALL	DISPLAY		;display header
	CALL	LPARAMS		;get label params
	JP	C,MENU		;go on BREAK
	RES	6,(IY+1)	;set LABELS flag
	JR	PRINT1		;go common
;
;	print listing format
;
PRINTI	LD	HL,MSG24	;'printing listing'
	CALL	DISPLAY		;display message
	CALL	IPARAMS		;get listing params
	JP	C,MENU		;go on BREAK
	SET	6,(IY+1)	;set LISTING flag
	SET	7,(IY+23)	;set NO compress!
;
;	get message header text for listing
;
PRINTI1	LD	HL,MSG10	;prompt
	CALL	DISPLAY		;to video
	LD	B,63		;63 chars + CR
	CALL	GETSTR		;get from keyboard
	JP	C,MENU		;go on BREAK
	LD	DE,MESSAGE	;message storage
	LD	BC,63		;63 chars
	LDIR			;save it here
;
;	check if chars to be converted to upper case
;
PRINT1	LD	HL,MSG27	;'convert to upper case?'
	CALL	DISPLAY		;display prompt
	LD	B,1		;single key input
	CALL	GETSTR		;from keyboard
	JP	C,MENU		;go on BREAK
	RES	4,(IY+1)	;set case OK
	JR	Z,PRINT2	;default NO
	CALL	UCASE		;make input upper case
	CP	'N'		;no?
	JR	Z,PRINT2	;go if no
	CP	'Y'		;yes?
	JR	NZ,PRINT1	;neither, ask again
	SET	4,(IY+1)	;set case UPPER
;
;	fetch drive #'s to print from
;
PRINT2	LD	HL,MSG15	;'drive # or ALL?'
	CALL	DISPLAY		;display prompt
	LD	B,20		;max input length
	CALL	GETSTR		;from keyboard
	JP	C,MENU		;go on BREAK
	RES	4,(IY+0)	;set NO drives issued
	LD	(IY+22),0	;clear # active drives
;
;	clear all active drives for parse
;
	PUSH	HL		;save input pointer
	LD	HL,PARCLR	;reset all drives
	CALL	COMMON		;do all drives
	POP	HL		;restore input pointer
;
;	interrogate input string
;
PARSE	LD	A,(HL)		;get string byte
	INC	HL		;bump pointer
	CP	SPACE		;separator?
	JR	Z,PARSE		;yes, ignore it
	CP	COMMA		;separator?
	JR	Z,PARSE		;yes, ignore
	CP	CR		;terminator?
	JR	Z,PARSEND	;yes, done!
	SUB	'0'		;remove ascii
	JR	C,PRINT2	;go if invalid input
	CP	DRIVES		;in range?
	JR	NC,PRINT2	;out of range, ask again
;
;	drive # issued, set drive block and flags
;
	CALL	LOCFCB		;locate FCB address
	SET	4,(IX+0)	;set USE flag
	SET	4,(IY+0)	;set command issued!
	INC	(IY+22)		;bump # active files
	JR	PARSE		;continue
;
PARSEND	BIT	4,(IY+0)	;any commands issued?
	JR	NZ,PRINT3	;yes, go!
;
;	no drives issued, set all drives active!
;
	LD	HL,PARSET	;subroutine address
	CALL	COMMON		;do all drives
;
;	fetch condition mask from user
;
PRINT3	CALL	ASKCOND		;get condition mask
	CALL	ASKACTN		;get file action
	CALL	PRINTER		;printer ready?
	LD	A,(IY+1)	;get flags
	AND	0C0H		;check bits 7/6
	JR	NZ,PRINT4	;continue
	CALL	SAMPLE		;sample label
	JP	C,MENU		;go on BREAK
;
;	setup loop to print all labels
;
PRINT4	LD	(IY+22),0	;clear active files
	LD	(IY+21),0	;clear error reporter
	CALL	GETHIGH		;get topmem
	LD	(HIGH),HL	;pass to subroutine
	XOR	A		;load zero
	LD	(SORTF),A	;clear sorted field
	LD	HL,OPENIT	;subroutine vector
	CALL	COMMON		;setup all drives
	LD	A,(IY+21)	;any errors?
	OR	A		;set flags
	JP	NZ,ERROR	;go on disk error
	CALL	SETUPS		;setup params
;
	LD	A,(IY+22)	;get resulting # files
	OR	A		;anything?
	JR	NZ,LOOP		;yes, go!
	LD	HL,MSG20	;'no files to print from'
	CALL	DISPLAY		;display prompt
	CALL	INKEY		;wait for a key
	JP	PRINT2		;ask again for drives!
;
QUIT	CALL	DISPLAY		;display prompt
	CALL	INKEY		;wait for a key
	JP	MENU		;back to menu
;
;	setup loop to print all records
;
LOOP	CALL	MANY		;display figures
;
;	check for operation ABORT with <BREAK>
;
	CALL	STROBE		;strobe keyboard
	CP	BREAK		;break key?
	JP	Z,ABORT		;yes, abort!
	CALL	UCASE		;make upper case
	CP	'H'		;hold?
	JR	NZ,$+6		;go if not
	RES	4,(IY+23)	;reset CONTINUOUS
;
	CALL	FETCH		;fetch a record
	JP	NZ,ERROR	;go on disk error
	LD	A,(IY+38)	;get # records available
	OR	A		;any?
	JR	Z,LOOPEND	;nope, done!
	CALL	PRINTIT		;print the record
	JP	NZ,ERROR	;go on error!
	JR	LOOP		;continue
;
;	all printing completed
;
LOOPEND	BIT	7,(IY+1)	;printing?
	CALL	Z,FLUSH		;yes, flush partial buff
	LD	HL,MSG21	;'printing done'
	JP	QUIT		;continue
;
PARSET	BIT	7,(IX+0)	;file available?
	RET	Z		;nope, done!
	SET	4,(IX+0)	;set as active drive
	INC	(IY+22)		;count active file
	RET			;to next drive!
;
;	clear all drives
;
PARCLR	RES	4,(IX+0)	;set NOT active
	RET			;done
;
*GET	MAILE2			;support module
*GET	MAILE3			;printing logic
;**
;
;	check that files are all sorted similarly
;
CKSORTO	LD	DE,00FFH	;D = count, E = field
	LD	(CKPASD),DE	;pass DE to sub
	LD	HL,CKSRO	;subroutine vector
	CALL	COMMON		;do all drives
	LD	DE,(CKPASD)	;fetch result
	LD	A,D		;get counter
	OR	A		;anything?
	JR	Z,CKDEAD	;nope, cannot print!
	INC	A		;FF?
	RET	NZ		;go if not
;
;	nothing available or incompatable files!
;
CKDEAD	POP	HL		;restore stack
	LD	HL,MSG28	;message
	CALL	DISPLAY		;display
	CALL	INKEY		;wait for a key
	JP	EXIT		;back to menu
;
CKSRET	LD	(CKPASD),DE	;update flags
	RET			;done
;
CKSRO	LD	DE,CKSRET	;return vector
	PUSH	DE		;leave on stack
	LD	DE,$		;fetch flags
CKPASD	EQU	$-2
	BIT	7,(IX+0)	;file open?
	RET	Z		;nope, skip
	BIT	6,(IX+0)	;sorted?
	RET	Z		;nope!
	INC	D		;D = FF?
	JR	Z,CKSRE		;yes, go!
	DEC	D		;put back
	INC	E		;E = FF?
	JR	Z,CKSRI		;go if yes!
	DEC	E		;put back
	LD	A,(IX+13)	;get sorted field
	INC	D		;bump count
	CP	E		;same sort field?
	RET	Z		;yes, go!
	LD	D,-1		;set INVALID if not
	RET			;done!
CKSRE	DEC	D		;D = FF
	RET			;back FF
CKSRI	LD	E,(IX+13)	;get sorted field
	INC	D		;bump counter
	RET			;done!
;
;	setup for printer activity
;
SETUPS	CALL	INITCNT		;clear counters
	LD	BC,0		;load zero
	LD	(IY+19),C	;char counter
	LD	(IY+20),C	;line counter
	LD	(IY+21),C	;page counter
	LD	(IY+39),C	;# records before header
	LD	(PAGE),BC	;save as page #
	XOR	A		;load zero
	LD	(RECCNT),A	;clear record counter
;
;	make sure there is sufficient memory
;	to load in multiple records for
;	multiple across labels
;
	LD	DE,FREEMEM	;start free memory
	LD	(POINTER),DE	;init buff pointer
	LD	(NEWPNT),DE	;reset address
	LD	BC,128		;128 byte records
	LD	HL,0		;init count
	LD	A,(IY+15)	;# labels across
CKMSZ	ADD	HL,BC		;add buffer length
	DEC	A		;less # across
	JR	NZ,CKMSZ	;go for count
	ADD	HL,DE		;add to low mem
	EX	DE,HL		;DE = highest needed
	LD	HL,(HIGH)	;get top back
	OR	A		;clear carry
	SBC	HL,DE		;compare
	JP	C,OUTMEM	;out of memory!
	RET			;else OK
;
;	send form feed to printer
;
SENDFF	LD	A,0CH		;top of form
	CALL	POUT		;to printer
	JP	MENU		;back to menu
;
;	display author
;
SHOWKIM	LD	HL,KIMMSG	;message
	CALL	DISPLAY		;display
	CALL	INKEY		;wait for a key
	JP	MENU		;back to menu
;
KIMMSG	DEFB	SETCUR
	DEFB	12,00
	DEFB	EOF
	DEFM	'Program by Kim Watt'
	DEFB	CR
	DEFM	'(c)(p) Copyright 1983'
	DEFB	CR
	DEFM	'Breeze/QSD, Inc.'
	DEFB	CR
	DEFM	'Dallas, Texas '
	DEFB	ETX
;
;	char to printer with count
;
POUT	PUSH	AF		;save char
	BIT	4,(IY+1)	;convert to ucase?
	CALL	NZ,UCASE	;make UC if yes
	CALL	POUTX		;send to printer
	POP	AF		;restore char
	INC	(IY+19)		;bump char counter
	CP	CR		;carriage return?
	RET	NZ		;go if not
	LD	(IY+19),0	;reset char count
	INC	(IY+20)		;bump line counter
	RET			;done!
;
;	send char in A to printer
;
POUTX	POUT$			;char to printer
	RET			;done!
;
;	display # records printed/passed/total
;
MANY	LD	B,(IY+32)	;get # printed
	LD	H,(IY+33)
	LD	L,(IY+34)	;BHL = # printed
	PUSH	BC		;save on stack
	PUSH	HL
	LD	DE,MSG12A	;text to place it
	CALL	BINASC		;binary => ascii
	LD	B,(IY+35)	;get # passed
	LD	H,(IY+36)
	LD	L,(IY+37)	;BHL = # passed
	PUSH	BC		;leave on stack
	PUSH	HL
	LD	DE,MSG12B	;text
	CALL	BINASC		;binary => ascii
	POP	HL		;unstack
	POP	BC		;BHL = # passed
	POP	DE		;unstack
	POP	AF
	LD	C,A		;CDE = # printed
	CALL	ADDIT		;total records
	LD	DE,MSG12C	;text
	CALL	BINASC		;to ascii
	LD	HL,MSG12	;start of message
	JP	DISPLAY		;display and return
;
;	see if current record to be printed
;
PRINTIT	BIT	2,(IY+1)	;any conditions?
	JR	Z,PRTREC	;nope, print record
	CALL	MATCH		;does record match?
	JR	Z,PRTREC	;yes, print it!
;
;	current record does not qualify to print
;
SKIPIT	CALL	ADDCNTB		;bump counter B
	XOR	A		;return Z
	RET			;done!
;
;	print current record
;
PRTREC	CALL	SHOW		;display record
	CALL	SHOWF		;display flags
	BIT	7,(IY+1)	;counting or printing?
	JR	NZ,CNTREC	;count, go!
	JR	ASKPRT		;continue
;
SETHOLD	RES	4,(IY+23)	;clear continuous bit
;
ASKPRT	LD	HL,MSG14	;'print,skip, etc'
	CALL	DISPLAY		;display prompt
	BIT	4,(IY+23)	;continuous on?
	JR	NZ,CONTPRT	;yes, check for halt
	CALL	INKEY		;wait for a key
	JP	C,MENU		;quit on BREAK
	JR	Z,GOPRT		;go if ENTER
;
	CALL	UCASE		;make upper case
	CP	'P'		;print?
	JR	Z,GOPRT		;yes, go!
	CP	'S'		;skip?
	JR	Z,SKIPIT	;skip record
	CP	'H'		;hold?
	JR	Z,ASKPRT	;already holding!
	CP	'Q'		;quit?
	JP	Z,ABORT		;yes, abort!
	CP	'C'		;continuous?
	JR	NZ,ASKPRT	;none, ask again
	SET	4,(IY+23)	;set continuous
	JR	GOPRT		;print the record
;
CONTPRT	CALL	STROBE		;strobe keyboard
	JR	Z,GOPRT		;go if no key
	CP	BREAK		;break key?
	JP	Z,ABORT		;abort operation!
	CALL	UCASE		;make upper case
	CP	'H'		;hold?
	JR	Z,SETHOLD	;yes, cancel hold
;
;	send record to printer
;
GOPRT	CALL	LABEL		;print the record
;
CNTREC	CALL	ADDCNTA		;bump counter A
;
;	check if file data to be affected
;
UPDREC	BIT	3,(IY+1)	;any action?
	RET	Z		;nope, done!
;
;	combine action mask with user data
;
	LD	A,(IY+14)	;get current drive #
	CALL	LOCFCB		;find the fcb block
	LD	L,(IX+17)	;get buffer pointer
	LD	H,(IX+18)
	LD	C,(IY+13)	;offset into buffer
	LD	B,0		;BC = offset
	ADD	HL,BC		;HL => record
	LD	DE,ACTBUFF	;action buffer
	LD	B,125		;125 chars to move in
ACTLP	LD	A,(DE)		;get action char
	CP	' '		;blank?
	JR	Z,ACTNX		;yes, go next
	LD	(HL),A		;combine with user data
ACTNX	INC	DE		;bump pointers
	INC	HL
	DJNZ	ACTLP		;finish file data
	LD	B,3		;3 flags to do
ACTFL	INC	DE		;bump by 3
	INC	DE
	INC	DE
	LD	A,(DE)		;get flag byte
	DEC	DE		;put back
	DEC	DE
	DEC	DE
	CPL			;reverse bits
	AND	(HL)		;combine
	LD	C,A		;save
	LD	A,(DE)		;get mask byte
	OR	C		;merge mask bits
	LD	(HL),A		;to user buffer
	INC	HL		;bump pointers
	INC	DE
	DJNZ	ACTFL		;finish flags
;
;	write back record to file
;
	JP	WRITREC		;write record & return
;
;	fetch flag conditions from user
;
ASKCOND	RES	2,(IY+1)	;set NO condition
	CALL	CLRDATA		;clear out data
	LD	HL,MSG11	;'enter condition'
	CALL	DISPLAY		;display prompt
	PUSH	IY		;save IY
	CALL	GETSTUF		;get data from user
	POP	IY		;restore IY
	LD	DE,CONDBUF	;condition buffer
	CALL	ASKCOMM		;move data and compare
	RET	Z		;go if nil input
	SET	2,(IY+1)	;set YES condition
	RET			;done!
;
;	fetch action data from user
;
ASKACTN	RES	3,(IY+1)	;set NO action
	CALL	CLRDATA		;clear out data
	LD	HL,MSG16	;'enter action mask'
	CALL	DISPLAY		;display prompt
	PUSH	IY		;save IY
	CALL	GETSTUF		;get data from user
	POP	IY		;restore IY
	LD	DE,ACTBUFF	;action buffer
	CALL	ASKCOMM		;move and compare
	RET	Z		;go if no mask
	SET	3,(IY+1)	;set YES action
	RET			;done!
;
ASKCOMM	LD	BC,131		;length of buffer
	LD	HL,BUFFER	;stored buffer
	PUSH	DE		;save buffer
	LDIR			;move it in
	CALL	CLRDATA		;clear out data buffer
	POP	DE		;restore buff start
	LD	HL,BUFFER	;start cleared buffer
	LD	B,131		;length
;
COMPARE	LD	A,(DE)		;get a byte
	CP	(HL)		;match?
	RET	NZ		;go if no
	INC	DE		;bump pointers
	INC	HL
	DJNZ	COMPARE		;go for length
	RET			;done
;
;	fetch printer status
;
PSTATUS	EQU	$
;
	IF	MOD1.OR.MOD3.OR.LDOSSVC
	XOR	A		;load zero
	CALL	POUTX		;read printer status
	ENDIF
;
	IF	MOD2
	LD	B,0		;get status
	LD	A,@PRCTRL	;printer control
	RST	SVC		;fetch status
	ENDIF
;
	RET			;Z = ready!
;
;	check if printer ready
;
PRINTER	BIT	7,(IY+1)	;counting?
	JR	Z,CKPRT		;nope, check printer!
	LD	HL,MSG17	;'counting'
	CALL	DISPLAY		;display message
	XOR	A		;return NC
	RET			;done
;
CKPRT	CALL	PSTATUS		;get printer status
	LD	HL,MSG17A	;printer READY
	JR	Z,$+5		;go if yes
	LD	HL,MSG17B	;printer NOT ready
	CALL	DISPLAY		;display prompt
	CALL	INKEY		;wait for a key
	RET	C		;go on BREAK
	CALL	PSTATUS		;get printer status
	RET	Z		;ready, go!
	JR	CKPRT		;wait more
;
;	fetch value from input string
;
VALUE	LD	BC,0		;init value
VALLP	LD	A,(HL)		;get a char
	CP	CR		;terminator?
	RET	Z		;yes, done!
	INC	HL		;bump pointer
	CP	SPACE		;separator?
	RET	Z		;yes, done!
	CP	COMMA		;separator?
	RET	Z		;yes, done!
;
	SUB	'0'		;remove ascii
	RET	C		;go if invalid
	CP	10		;0-9?
	CCF			;reverse carry flag
	RET	C		;go if invalid
;
	PUSH	HL		;save pointer
	LD	H,B		;pass subtotal
	LD	L,C
	ADD	HL,HL		;*2
	ADD	HL,HL		;*4
	ADD	HL,BC		;*5
	ADD	HL,HL		;*10
	LD	C,A		;pass new digit
	LD	B,0		;BC = new digit
	ADD	HL,BC		;HL = new subtotal
	LD	B,H		;pass back to BC
	LD	C,L
	POP	HL		;restore input pointer
	JR	VALLP		;go next char
;
;	fetch parameters for LABEL listing
;
LPARAMS	LD	HL,MSG3		;'# labels across?'
	CALL	DISPLAY		;display prompt
	LD	B,3		;3 char input
	CALL	GETSTR		;from keyboard
	RET	C		;go on BREAK
	LD	(IY+15),1	;labels across default
	JR	Z,LPAR1		;go if nil input
	CALL	VALUE		;get input value
	JR	C,LPARAMS	;go if invalid
	LD	(IY+15),C	;set table
;
LPAR1	LD	HL,MSG4		;'label width?'
	CALL	DISPLAY		;display prompt
	LD	B,3		;3 char input
	CALL	GETSTR		;from keyboard
	RET	C		;go on BREAK
	LD	(IY+16),40	;default width
	JR	Z,LPAR2		;go on ENTER
	CALL	VALUE		;get input value
	JR	C,LPAR1		;ask again if invalid
	LD	(IY+16),C	;save value
;
LPAR2	LD	HL,MSG5		;'label length?'
	CALL	DISPLAY		;display prompt
	LD	B,3		;3 chars
	CALL	GETSTR		;from keyboard
	RET	C		;go on BREAK
	LD	(IY+17),6	;set default
	JR	Z,LPAR3		;go on ENTER
	CALL	VALUE		;get input value
	JR	C,LPAR2		;go if invalid
	LD	(IY+17),C	;save new value
;
LPAR3	LD	HL,MSG6		;'repeat count?'
	CALL	DISPLAY		;display prompt
	LD	B,3		;3 char input
	CALL	GETSTR		;from keyboard
	RET	C		;go on BREAK
	LD	(IY+18),1	;set repeat counter
	JR	Z,LPAR4		;go on ENTER
	CALL	VALUE		;get input value
	JR	C,LPAR3		;go if invalid
	LD	(IY+18),C	;save new value
;
LPAR4	LD	HL,MSG18	;'format 1 or 2?'
	CALL	DISPLAY		;display prompt
	LD	B,1		;single key input
	CALL	GETSTR		;from keyboard
	RET	C		;go on BREAK
	LD	C,0		;format 1
	JR	Z,LPAR4P	;use for default
	CP	'1'		;one?
	JR	Z,LPAR4P	;go if yes
	CP	'2'		;two?
	JR	NZ,LPAR4	;invalid, ask again
	INC	C		;format 2
LPAR4P	LD	A,(IY+1)	;get flags
	AND	0FCH		;loose low 2 bits
	OR	C		;set new ones
	LD	(IY+1),A	;save format type
;
LPAR5	LD	HL,MSG19	;'compress blanks?'
	CALL	DISPLAY		;display prompt
	LD	B,1		;one key input
	CALL	GETSTR		;from keyboard
	RET	C		;go on BREAK
	RES	7,(IY+23)	;set compress YES
	JR	Z,LPAR6		;go as default
	CALL	UCASE		;make upper case
	CP	'Y'		;yes?
	JR	Z,LPAR6		;yes, go!
	CP	'N'		;no?
	JR	NZ,LPAR5	;neither, ask again
	SET	7,(IY+23)	;set compress NO
;
LPAR6	XOR	A		;return with Z
	RET
;
;	print sample label
;
SAMPLE	LD	HL,MSG7		;'begin or sample?'
	CALL	DISPLAY		;display prompt
	LD	B,1		;one key input
	CALL	GETSTR		;from keyboard
	RET	C		;go on BREAK
	RET	Z		;go as default!
	CALL	UCASE		;make input upper case
	CP	'B'		;begin?
	RET	Z		;go if yes!
	CP	'S'		;sample?
	JR	NZ,SAMPLE	;neither, ask again
;
;	print sample label to printer
;
	LD	A,'w'		;fill character
	LD	(FILCHR),A	;save for test
	CALL	GETHIGH		;get highmem
	LD	(HIGH),HL	;set dummy for label
	CALL	SETUPS		;setup for printer
	LD	C,(IY+18)	;get repeat counter
	PUSH	BC		;save on stack
	LD	(IY+18),1	;set for once only
	LD	B,(IY+15)	;# labels across
SMPLB	PUSH	BC		;save count
	LD	A,'$'		;get fill char
FILCHR	EQU	$-1
	INC	A		;+1
	CP	'z'+1		;past end?
	JR	C,$+4		;go if not
	LD	A,'a'		;re-init
	LD	(FILCHR),A	;update
	CALL	CLRDAT0		;clear data buffer
	CALL	LABEL		;print it!
	POP	BC		;restore count
	DJNZ	SMPLB		;go for count
	POP	BC		;restore repeat count
	LD	(IY+18),C	;reset it
	JR	SAMPLE		;go again!
;
;	fetch listing params from user
;
IPARAMS	LD	HL,MSG8		;'printer width?'
	CALL	DISPLAY		;display prompt
	LD	B,3		;3 char input
	CALL	GETSTR		;from keyboard
	RET	C		;go on BREAK
	RES	5,(IY+1)	;set 80 col
	JR	Z,IPAR1		;go on ENTER
	CALL	VALUE		;get input value
	JR	C,IPARAMS	;go if invalid
	LD	A,C		;get input
	CP	80		;80 col?
	JR	Z,IPAR1		;go if yes
	CP	8		;80 col?
	JR	Z,IPAR1		;go if yes
	SET	5,(IY+1)	;set 132 col
	CP	1		;132 col?
	JR	Z,IPAR1		;go if yes
	CP	132		;132 col?
	JR	NZ,IPARAMS	;neither, ask again
;
IPAR1	LD	HL,MSG9		;'format 1-4?'
	CALL	DISPLAY		;display prompt
	LD	B,1		;single key input
	CALL	GETSTR		;from keyboard
	RET	C		;go on BREAK
	LD	C,0		;init one
	JR	Z,IPAR2		;go default 1
	CALL	UCASE		;make upper case
	CP	'X'		;abort?
	SCF			;set C for BREAK
	RET	Z		;go as if BREAK
	SUB	'1'		;remove ascii
	JR	C,IPAR1		;invalid, ask again
	CP	4		;0-3?
	JR	NC,IPAR1	;go if out of range
	LD	C,A		;pass value
;
IPAR2	LD	A,(IY+1)	;get system
	AND	0FCH		;drop low 2 bits
	OR	C		;combine new setting
	LD	(IY+1),A	;save result
;
IPAR3	XOR	A		;load zero
	RET			;done, no errors
;
CORRUPT	EQU	$
;
	IF	MOD2
	CALL	@VIDON		;enable video memory
	ENDIF
;
	LD	HL,MSG99	;start of message
	LD	DE,@VIDEO	;start video memory
	LD	BC,MSG99L	;length of text
	LDIR			;move to video
DEAD	JP	DEAD		;hold here!
;
EXIT	LD	HL,PGM1		;PMAILM/CMD
	LD	BC,RUNERR	;error vector
	JP	RUNPGM		;execute program!
;
;	error on run attempt
;
RUNERR	CALL	$ERROR		;display error message
	LD	HL,MSG22	;'key to continue'
	JP	QUIT		;back to menu
;
;	error on printing
;
ERROR	PUSH	AF		;save error code
	LD	HL,MSG26	;'error - '
	CALL	DISPLAY		;display message
	POP	AF		;restore
	JR	RUNERR		;display error message
;
	SUBTTL	'<maild/asm - subroutine section>'
;
	PAGE
;
;	clear current counters
;
INITCNT	PUSH	HL		;save
	LD	HL,SYSTEM+32	;start counter
	LD	A,6		;6 bytes
INITCL	LD	(HL),0		;clear a byte
	INC	HL		;bump posit
	DEC	A		;less counter
	JR	NZ,INITCL	;go for count
	POP	HL		;restore
	RET			;done
;
ADDCNTA	PUSH	BC		;save BC / HL
	PUSH	HL
	LD	B,(IY+32)	;get counter A
	LD	H,(IY+33)
	LD	L,(IY+34)
	CALL	INCBHL		;bump it
	LD	(IY+32),B	;update
	LD	(IY+33),H
	LD	(IY+34),L
	POP	HL		;unstack
	POP	BC
	RET
;
ADDCNTB	PUSH	BC		;save
	PUSH	HL
	LD	B,(IY+35)	;get counter B
	LD	H,(IY+36)
	LD	L,(IY+37)
	CALL	INCBHL		;+1
	LD	(IY+35),B	;update
	LD	(IY+36),H
	LD	(IY+37),L
	POP	HL		;unstack
	POP	BC
	RET
;
;	display error message
;
$ERROR	ERROR$			;display error message
	RET			;done
;
;	out of memory!
;
OUTMEM	LD	HL,MEMMSG	;'memory' message
	JP	QUIT		;go!
;
;	abort operation with BREAK
;
ABORT	LD	HL,ABMSG	;abort message
	JP	QUIT		;back to menu
;
	SUBTTL	'<maile/asm - text section>'
;
ABMSG	DEFB	SETCUR
	DEFB	14,00
	DEFB	EOF
	DEFM	'Operation ABORTED, (KEY):'
	DEFB	ETX
;
MEMMSG	DEFB	SETCUR
	DEFB	14,00
	DEFB	EOF
	DEFM	'OUT of MEMORY, (KEY):'
	DEFB	ETX
;
MSG1	DEFB	SETCUR
	DEFB	12,00
	DEFB	EOF
;
	DEFM	')1( Print Records'
	DEFB	SETCUR
	DEFB	12,COLS/2
	DEFM	'(3) Form Feed to printer'
	DEFB	CR
;
	DEFM	'(2) Count Records'
	DEFB	SETCUR
	DEFB	13,COLS/2
	DEFM	'(4) Return to Menu'
	DEFB	CR
	DEFM	'Choice ? '
	DEFB	ETX
;
MSG2	DEFB	SETCUR
	DEFB	12,00
	DEFB	EOF
	DEFM	')1( Label Format'
	DEFB	SETCUR
	DEFB	12,COLS/2
	DEFM	'(2) Listing Format'
	DEFB	CR
	DEFM	'Choice ? '
	DEFB	ETX
;
MSG3	DEFB	SETCUR
	DEFB	14,00
	DEFB	EOF
	DEFM	'Labels Across )1( ? '
	DEFB	ETX
;
MSG4	DEFB	SETCUR
	DEFB	14,00
	DEFB	EOF
	DEFM	'Label Width )40( ? '
	DEFB	ETX
;
MSG5	DEFB	SETCUR
	DEFB	14,00
	DEFB	EOF
	DEFM	'Label Length )6( ? '
	DEFB	ETX
;
MSG6	DEFB	SETCUR
	DEFB	14,00
	DEFB	EOF
	DEFM	'Repeat Count )1( ? '
	DEFB	ETX
;
MSG7	DEFB	SETCUR
	DEFB	14,00
	DEFB	EOF
	DEFM	')B(egin Printing, (S)ample Label ? '
	DEFB	ETX
;
MSG8	DEFB	SETCUR
	DEFB	14,00
	DEFB	EOF
	DEFM	'Printer Width )80( or (132) ? '
	DEFB	ETX
;
MSG9	DEFB	SETCUR
	DEFB	14,00
	DEFB	EOF
	DEFM	'Format )1( (2) (3) (4) ? '
	DEFB	ETX
;
MSG10	DEFB	SETCUR
	DEFB	14,00
	DEFB	EOF
	DEFM	'Enter Header Message:'
	DEFB	CR
	DEFB	ETX
;
MSG11	DEFB	SETCUR
	DEFB	14,00
	DEFB	EOF
	DEFM	'Enter CONDITION Mask'
	DEFB	ETX
;
MSG12	DEFB	SETCUR
	DEFB	12,00
MSG12A	DEFM	'xxxxxxxx Printed/Counted - '
MSG12B	DEFM	'xxxxxxxx Passed - '
MSG12C	DEFM	'xxxxxxxx Total'
	DEFB	CR
	DEFB	ETX
;
MESSAGE	DEFM	'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx'
	DEFM	'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx '
	DEFB	ETX
;
MSG13	DEFM	'Page '
	DEFB	ETX
;
MSG14	DEFB	SETCUR
	DEFB	14,00
	DEFB	EOF
	DEFM	')P(rint, (S)kip, (C)ontinuous, '
	DEFM	'(H)old, (Q)uit ? '
	DEFB	ETX
;
MSG15	DEFB	SETCUR
	DEFB	14,00
	DEFB	EOF
	DEFM	'Drive Number(s) or <ENTER> for all ? '
	DEFB	ETX
;
MSG16	DEFB	SETCUR
	DEFB	14,00
	DEFB	EOF
	DEFM	'Enter ACTION Mask'
	DEFB	ETX
;
MSG17	DEFB	SETCUR
	DEFB	14,00
	DEFB	EOF
	DEFM	'Counting, <BREAK> to abort ...'
	DEFB	ETX
;
MSG17A	DEFB	SETCUR
	DEFB	14,00
	DEFB	EOF
	DEFM	'Printer READY, (KEY) to begin:'
	DEFB	ETX
;
MSG17B	DEFB	SETCUR
	DEFB	14,00
	DEFB	EOF
	DEFM	'Printer NOT READY, (KEY) to continue:'
	DEFB	ETX
;
MSG18	DEFB	SETCUR
	DEFB	14,00
	DEFB	EOF
	DEFM	'Format )1( (2) ? '
	DEFB	ETX
;
MSG19	DEFB	SETCUR
	DEFB	14,00
	DEFB	EOF
	DEFM	'Compress Blanks )Y( (N) ? '
	DEFB	ETX
;
MSG20	DEFB	SETCUR
	DEFB	14,00
	DEFB	EOF
	DEFM	'NO FILES AVAILABLE to print from, '
	DEFM	'(KEY):'
	DEFB	ETX
;
MSG21	DEFB	SETCUR
	DEFB	14,00
	DEFB	EOF
	DEFM	'All Printing Completed, (KEY):'
	DEFB	ETX
;
MSG22	DEFM	'(KEY) to continue:'
	DEFB	ETX
;
MSG23	DEFB	SETCUR
	DEFB	12,00
	DEFB	EOF
	DEFM	'Printing Labels'
	DEFB	ETX
;
MSG24	DEFB	SETCUR
	DEFB	12,00
	DEFB	EOF
	DEFM	'Printing Listing'
	DEFB	ETX
;
MSG25	DEFB	SETCUR
	DEFB	12,00
	DEFB	EOF
	DEFM	'Counting Records'
	DEFB	ETX
;
MSG26	DEFB	SETCUR
	DEFB	14,00
	DEFB	EOF
	DEFM	'File Error - '
	DEFB	ETX
;
MSG27	DEFB	SETCUR
	DEFB	14,00
	DEFB	EOF
	DEFM	'Convert Output to Upper Case Only '
	DEFM	')N( (Y) ? '
	DEFB	ETX
;
MSG28	DEFB	SETCUR
	DEFB	12,00
	DEFB	EOF
	DEFM	'Files either Not Available or '
	DEFM	'Not Sorted Similarly'
	DEFB	CR
	DEFM	'(KEY) to continue:'
	DEFB	ETX
;
MSG99	DEFM	'RUN PMAIL/CMD ONLY!'
MSG99L	EQU	$-MSG99
;
;	3 bytes of 00 for rewinds
;
REWIND	DEFB	00,00,00
;
;	jump table for menu selections
;
JUMPT1	DEFB	'1'
	DEFW	PRINT		;print records
	DEFB	'2'
	DEFW	COUNT		;count records
	DEFB	'3'
	DEFW	SENDFF
	DEFB	'4'
	DEFW	EXIT		;exit to menu
	DEFB	'W'		;who?
	DEFW	SHOWKIM		;display author
	DEFB	ETBL		;end of table
;
JUMPT2	DEFB	'1'
	DEFW	PRINTL		;print labels
	DEFB	'2'
	DEFW	PRINTI		;print listing
	DEFB	ETBL		;end of table
;
;	program name to link back to menu
;
PGM1	DEFM	'PMAILM/CMD'
	DEFB	SYSDRV
	DEFB	SYSDRVN
	DEFB	ETX
;
;	param list for OPEN mod II
;
	IF	MOD2
OLIST	DEFW	0
	DEFW	0
	DEFW	0
	DEFB	'W'
	DEFB	0
	DEFB	'E'
	DEFB	0
	DEFB	00
	ENDIF
;
LSTBUFF	EQU	$&0FF00H	;last even page
BUFFER	EQU	LSTBUFF+100H	;first free page
CONDBUF	EQU	BUFFER+100H	;condition mask buffer
ACTBUFF	EQU	CONDBUF+100H	;action mask buffer
PRTBUFF	EQU	ACTBUFF+100H	;printer string storage
FTABLE	EQU	PRTBUFF+100H	;file control table
RECBUFF	EQU	FTABLE+100H	;record holding buffer
SORTBUF	EQU	RECBUFF+100H	;sorting buffer
FLAGBUF	EQU	RECBUFF+100H	;start flag name storage
;
FREEMEM	EQU	FLAGBUF+600H	;start free memory
;
PGMEND	EQU	FREEMEM+200H	;max memory needed
;
	SUBTTL	'<maile/asm - symbol table>'
;
	END	ENTRY
