; mailc/asm - kjw/bqsd - version 2.00 - 01/83
;
; revised 02/24/83 - kjw
;
	TITLE	'<PowerMAIL - 2.00 source code>'
;
;	system data usage
;
;	+1	7 - 1 = data record current in buffer
;		6 - 1 = index record current in buffer
;		5 - 1 = use index to search for record
;		4 - 0 = scan forward, 1 = scan backward
;		3 - 1 = current record out of file range
;		2-0   = current drive #
;	+7,8,9		- logical record # data
;	+10,11,12	- logical record # index
;	+13,14,15	- physical record #
;	+16		- data offset
;
*GET	MAILEQU			;equivalences
*GET	MAILDISK		;I/O drivers
;
	ORG	CODE
*GET	MAILDVRS		;I/O drivers
*GET	MAILMATH		;math subroutines
;
	SUBTTL	'<mailc/asm - find/edit flags/records>'
;
	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	;nope, go PMAIL!
;
MENU	LD	IY,SYSTEM	;reset pointer
	LD	L,(IY+2)	;fetch stack pointer
	LD	H,(IY+3)	;HL = init stack
	LD	SP,HL		;reset it
;
	CALL	CLRDATA		;clear out data field
	CALL	SHOW		;display data
	CALL	SHOWF		;display flags
;
MENU0	LD	HL,MSG1		;menu options
	CALL	DISPLAY		;display options
	LD	B,1		;one key input
	CALL	GETSTR		;from keyboard
	JP	C,EXIT		;go if BREAK
	JP	Z,EDITR		;go default on nil input
	LD	HL,TABLE1	;menu jump table
	CALL	GOTABLE		;go vector if valid entry
	JR	MENU0		;invalid, ask again
;
;	exit program back to main menu
;
CORRUPT	EQU	$
;
	IF	MOD2
	CALL	@VIDON		;enable video
	ENDIF
;
	LD	HL,MSG99	;error text
	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 exit
	JP	RUNPGM		;execute program
;
;	error on run attempt
;
RUNERR	CALL	ERROR		;display error message
	LD	HL,MSG2		;'key to continue'
	CALL	DISPLAY		;display message
	CALL	INKEY		;wait for a key
	JP	MENU		;back to menu
;
*GET	MAILCC			;EDITR / EDITF
;
	SUBTTL	'<mailc/asm - subroutine section>'
;
	PAGE
;
;	display author
;
SHOWWHO	LD	HL,WHOMSG	;text
	CALL	DISPLAY		;display it
	CALL	INKEY		;wait for a key
	JP	MENU		;back to menu
;
WHOMSG	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
;
;	edit flag mask with name display
;
FLAGMSP	LD	BC,NAMEF	;subroutine
	JR	FLAGMSK+3	;continue
;
;	specify search flags with + -
;
FLAGMSK	LD	BC,RETURN	;RET opcode
	LD	HL,TABLE4M	;edit table
	LD	DE,SHOWFM	;flag display
	JR	FLAGCM		;go common
;
;	get flags from user
;
GETFLAG	LD	HL,TABLE4	;command table
	LD	DE,SHOWF	;normal flags
	LD	BC,NAMEF	;display flag names
;
FLAGCM	LD	(FLAGTBL),HL	;save command table
	LD	(FLAGS1),DE	;save display vector
	LD	(FLAGS2),DE	;twice
	LD	(FLAGS3),BC	;save display driver
	LD	IX,TABLEB	;lower video table
	LD	IY,TABLEB2	;offset table
;
GETFLP	PUSH	IY		;save
	PUSH	IX		;save
	LD	A,(IX+2)	;get flag #
	CALL	$		;display flag name?
FLAGS3	EQU	$-2
	CALL	$		;display flags
FLAGS1	EQU	$-2
	POP	IX		;unstack
	POP	IY
;
	LD	L,(IX+0)	;lsb video address
	LD	H,(IX+1)	;msb video address
	LD	A,95		;cursor
	LD	(CURCHR),A	;save it
	CALL	KEY		;wait for a key
	RET	C		;return on BREAK
	JP	Z,GETFNX	;go next if ENTER
	CP	ESCAPE		;escape key?
	RET	Z		;yes, go!
;
	LD	HL,$		;command table
FLAGTBL	EQU	$-2
	LD	C,0		;init counter
	CALL	UCASE		;make upper case
	CALL	GOTABLE		;see if valid command
	JR	GETFLP		;nope, wait more
;
RFLAG	INC	C		;+3 = right
LFLAG	INC	C		;+2 = left
DFLAG	INC	C		;+1 = down
UFLAG	EQU	$		;+0 = up
	LD	A,C		;fetch offset
	LD	(FDISY),A	;save into code
	LD	C,(IY+0)	;fetch table entry
FDISY	EQU	$-1
	LD	B,0		;BC = offset
	LD	IX,TABLEB	;video table
	LD	IY,TABLEB2	;start offset table
FDISZ	ADD	IX,BC		;offset to next
	ADD	IY,BC		;add offset
;
;	check for terminator
;
	LD	A,(IX+0)	;fetch a byte
	OR	(IX+1)		;terminator?
	JR	NZ,GETFLP	;go next flag
	JP	$		;display results!
FLAGS2	EQU	$-2
;
;	set flag
;
SETF	INC	C		;C = 1
;
;	reset flag
;
RESETF	LD	A,(IX+2)	;get flag #
	LD	B,C		;pass flag byte
	LD	DE,BUFFER+125	;start of flags
GOTF0	LD	C,1		;test bit
GOTF1	DEC	A		;less flag #
	JR	Z,GOTF2		;go if found
	SLA	C		;shift test bit
	JR	NC,GOTF1	;go for byte
	INC	DE		;bump flag byte
	JR	GOTF0		;go next byte
GOTF2	LD	A,C		;fetch test bit
	CPL			;reverse bits
	LD	C,A		;re-save it
	LD	A,(DE)		;read current flag
	AND	C		;reset bit
	LD	(DE),A		;save result
	DEC	B		;reset?
	JR	NZ,GETFNX	;go next if yes
	LD	A,C		;fetch mask
	CPL			;reverse back
	LD	C,A		;save temp
	LD	A,(DE)		;fetch byte
	OR	C		;set bit
	LD	(DE),A		;save result
;
GETFNX	LD	BC,4		;offset to next entry
	JR	FDISZ		;go next entry
;
	PAGE
;
;	get information from user
;
GETINFO	LD	IX,TABLET	;top video table
	LD	IY,TABLET2	;editor vector table
;
;	special inkeyed editor
;
GETINLP	LD	E,(IX+3)	;data offset
	LD	D,BUFFER<-8	;page data
	LD	B,(IX+2)	;length of input
	LD	L,(IX+0)	;fetch lsb video
	LD	H,(IX+1)	;fetch msb video
	LD	A,EDITCUR	;editor cursor
	LD	(CURCHR),A	;save character
	CALL	KEY		;fetch key
	RET	C		;go if BREAK
	JR	Z,EDITMOD	;go if ENTER
	CP	ESCAPE		;escape key?
	RET	Z		;yes, go!
;
;	evaluate edit command
;
	LD	C,0		;init for vector
	LD	HL,TABLE2	;jump table for arrows
	CALL	GOTABLE		;go if arrow else right
;
;	not an edit key, go next entry
;
	PUSH	AF		;save key
	LD	A,CHARCUR	;character cursor
	LD	(CURCHR),A	;save it
	POP	AF		;restore key
	LD	C,0		;init count
	LD	L,(IX+0)	;fetch LSB video
	LD	H,(IX+1)	;fetch MSB video
	CALL	ONEKEY		;intercept keyboard drvr
	RET	C		;go on BREAK
	JR	ADVNX		;continue
;
EDITMOD	LD	L,(IX+0)	;lsb video
	LD	H,(IX+1)	;msb video
	CALL	SPGET		;special inkey
	RET	C		;go on BREAK
;
ADVNX	LD	BC,4		;offset to next entry
	JR	DISPZ		;continue
;
ADVR	INC	C		;+3 - right
ADVL	INC	C		;+2 - left
ADVD	INC	C		;+1 - down
ADVU	EQU	$		;+0 - up
;
	LD	A,C		;fetch offset
	LD	(DISPY),A	;save for load
	LD	C,(IY+0)	;fetch offset value
DISPY	EQU	$-1
	LD	B,0		;BC = table offset
	LD	IX,TABLET	;top table start
	LD	IY,TABLET2	;top arrow vectors
DISPZ	ADD	IX,BC		;IX => new location
	ADD	IY,BC		;IY => new vectors
;
;	check for completed
;
	LD	A,(IX+0)	;fetch table entry
	OR	(IX+1)		;=0000H?
	JR	NZ,GETINLP	;go if more to do
	RET
;
;	display current file data to video
;
SHOW	LD	IX,TABLET	;top video table
;
	IF	MOD2
	CALL	@VIDON		;enable video memory
	ENDIF
;
SHOWLP	LD	E,(IX+0)	;lsb video address
	LD	D,(IX+1)	;msb video address
	LD	C,(IX+2)	;length this field
	LD	L,(IX+3)	;offset into data
	LD	H,BUFFER<-8	;MSB page of data
	LD	B,0		;BC = length of field
	LDIR			;move into video memory
	LD	BC,4		;offset to next entry
	ADD	IX,BC		;IX => next entry
	LD	A,(IX+0)	;check for 0000 term
	OR	(IX+1)		;=000H?
	JR	NZ,SHOWLP	;go if more
;
	IF	MOD2
	CALL	@VIDOFF		;disable video memory
	ENDIF
;
RETURN	RET			;done!
;
;	display flags to video
;
SHOWF	LD	IX,TABLEB	;lower video table
	LD	DE,BUFFER+125	;offset to flags
	LD	C,1		;mask test bit
;
	IF	MOD2
	CALL	@VIDON		;enable video memory
	ENDIF
;
SHOWFLP	LD	A,(DE)		;read flag byte
	AND	C		;test current bit
	LD	L,(IX+0)	;fetch lsb video
	LD	H,(IX+1)	;fetch msb video
	LD	A,FLON		;on video char
	JR	NZ,$+4		;go if on
	LD	A,FLOFF		;off video char
	LD	(HL),A		;to video
;
;	move to next bit
;
	SLA	C		;shift left test bit
	JR	NC,SHOWFF	;go if not end
	LD	C,1		;init test bit
	INC	DE		;bump to next flag byte
SHOWFF	INC	IX		;bump table
	INC	IX
	INC	IX
	INC	IX		;4 byte entries
	LD	A,(IX+0)	;check for terminator
	OR	(IX+1)		;=0000H?
	JR	NZ,SHOWFLP	;go if more to do
;
	IF	MOD2
	CALL	@VIDOFF		;disable video memory
	ENDIF
;
	RET			;flags displayed
;
;	clear out record buffer for new
;
CLRDATA	LD	HL,BUFFER	;start of data
	LD	DE,BUFFER+1	;start +1
	LD	BC,125		;data length
	LD	(HL),SPACE	;load nil data
	LDIR			;fill record
	LD	(HL),0		;clear flag 0
	LD	C,5		;5 more to do
	LDIR			;3 flag bytes + 3 mask
	RET			;temp buffer cleared
;
;	display error message
;
ERROR	ERROR$			;display error message
	RET			;done
;
;	abort operation with (BREAK)
;
ABORT	LD	HL,ABMSG	;abort message
	CALL	DISPLAY		;display message
	CALL	INKEY		;wait for a key
	JP	REEDIT		;re-edit search mask
;
	SUBTTL	'<mailc/asm - text section>'
;
	PAGE
;
ABMSG	DEFB	SETCUR
	DEFB	12,00
	DEFB	EOF
	DEFB	CR
	DEFB	CR
	DEFM	'Operation ABORTED, (KEY):'
	DEFB	ETX
;
MSG1	DEFB	SETCUR
	DEFB	12,000
	DEFB	EOF
;
	DEFM	')1( Edit Record'
	DEFB	SETCUR
	DEFB	12,COLS/2
	DEFM	'(3) Edit Flag Mask'
	DEFB	CR
;
	DEFM	'(2) Edit Flags'
	DEFB	SETCUR
	DEFB	13,COLS/2
	DEFM	'(4) Return to Menu'
	DEFB	CR
	DEFM	'Choice ? '
	DEFB	ETX
;
MSG2	DEFM	'(KEY) to continue:'
	DEFB	ETX
;
MSG99	DEFM	'RUN PMAIL/CMD ONLY!'
MSG99L	EQU	$-MSG99
;
	SUBTTL	'<mailc/asm - tables/vectors>'
;
	PAGE
;
;	jump table for menu selections
;
TABLE1	DEFB	'1'
	DEFW	EDITR		;edit record
	DEFB	'2'
	DEFW	EDITF		;edit flags
	DEFB	'3'
	DEFW	EDITFM		;edit flag mask
	DEFB	'4'
	DEFW	EXIT		;exit to menu
	DEFB	'W'
	DEFW	SHOWWHO
	DEFB	ETBL		;end of table
;
;	table of locations for file data
;
;	+0,1	= video memory for field
;	+2	= length of entry
;	+3	= offset into data field
;
	IF	MOD1.OR.MOD3.OR.LDOSSVC
TABLET	DEFW	@VIDEO+192+8	;last
	DEFB	15,0
	DEFW	@VIDEO+192+32	;first
	DEFB	10,15
	DEFW	@VIDEO+256+11	;company
	DEFB	20,25
	DEFW	@VIDEO+320+12	;addr 1
	DEFB	20,45
	DEFW	@VIDEO+320+48	;addr 2
	DEFB	10,65
	DEFW	@VIDEO+384+8	;city
	DEFB	15,75
	DEFW	@VIDEO+384+33	;state
	DEFB	8,90
	DEFW	@VIDEO+384+48	;zip
	DEFB	10,98
	DEFW	@VIDEO+192+50	;data 1
	DEFB	5,108
	DEFW	@VIDEO+256+50	;data 2
	DEFB	12,113
	DEFW	0000H		;terminator
	ENDIF
;
	IF	MOD2
TABLET	DEFW	@VIDEO+240+9	;last
	DEFB	15,0
	DEFW	@VIDEO+240+36	;first
	DEFB	10,15
	DEFW	@VIDEO+320+12	;company
	DEFB	20,25
	DEFW	@VIDEO+400+13	;addr 1
	DEFB	20,45
	DEFW	@VIDEO+400+52	;addr 2
	DEFB	10,65
	DEFW	@VIDEO+480+9	;city
	DEFB	15,75
	DEFW	@VIDEO+480+37	;state
	DEFB	8,90
	DEFW	@VIDEO+480+58	;zip
	DEFB	10,98
	DEFW	@VIDEO+240+60	;data 1
	DEFB	5,108
	DEFW	@VIDEO+320+60	;data 2
	DEFB	12,113
	DEFW	0000H		;terminator
	ENDIF
;
;	lookup table for editing commands
;
;	each entry is offset for UP/DOWN/LEFT/RIGHT
;
TABLET2	DEFB	00,08,28,04	;last
	DEFB	04,08,00,32	;first
	DEFB	00,12,32,36	;company
	DEFB	08,20,36,16	;addr 1
	DEFB	36,28,12,20	;addr 2
	DEFB	12,20,16,24	;city
	DEFB	12,24,20,28	;state
	DEFB	16,28,24,00	;zip
	DEFB	32,36,04,08	;data 1
	DEFB	32,16,08,12	;data 2
	DEFB	00,00,00,00	;terminator
;
;	video tables for flag placement
;
	IF	MOD1.OR.MOD3.OR.LDOSSVC
TABLEB	DEFW	@VIDEO+512+12	;1
	DEFB	1,-1
	DEFW	@VIDEO+512+18	;2
	DEFB	2,-1
	DEFW	@VIDEO+512+24	;3
	DEFB	3,-1
	DEFW	@VIDEO+512+30	;4
	DEFB	4,-1
	DEFW	@VIDEO+512+36	;5
	DEFB	5,-1
	DEFW	@VIDEO+512+42	;6
	DEFB	6,-1
	DEFW	@VIDEO+512+48	;7
	DEFB	7,-1
	DEFW	@VIDEO+512+54	;8
	DEFB	8,-1
	DEFW	@VIDEO+576+12	;9
	DEFB	9,-1
	DEFW	@VIDEO+576+18	;10
	DEFB	10,-1
	DEFW	@VIDEO+576+24	;11
	DEFB	11,-1
	DEFW	@VIDEO+576+30	;12
	DEFB	12,-1
	DEFW	@VIDEO+576+36	;13
	DEFB	13,-1
	DEFW	@VIDEO+576+42	;14
	DEFB	14,-1
	DEFW	@VIDEO+576+48	;15
	DEFB	15,-1
	DEFW	@VIDEO+576+54	;16
	DEFB	16,-1
	DEFW	@VIDEO+640+12	;17
	DEFB	17,-1
	DEFW	@VIDEO+640+18	;18
	DEFB	18,-1
	DEFW	@VIDEO+640+24	;19
	DEFB	19,-1
	DEFW	@VIDEO+640+30	;20
	DEFB	20,-1
	DEFW	@VIDEO+640+36	;21
	DEFB	21,-1
	DEFW	@VIDEO+640+42	;22
	DEFB	22,-1
	DEFW	@VIDEO+640+48	;23
	DEFB	23,-1
	DEFW	@VIDEO+640+54	;24
	DEFB	24,-1
	DEFW	0000H		;terminator
	ENDIF
;
	IF	MOD2
TABLEB	DEFW	@VIDEO+640+13	;1
	DEFB	1,-1
	DEFW	@VIDEO+640+20	;2
	DEFB	2,-1
	DEFW	@VIDEO+640+27	;3
	DEFB	3,-1
	DEFW	@VIDEO+640+34	;4
	DEFB	4,-1
	DEFW	@VIDEO+640+41	;5
	DEFB	5,-1
	DEFW	@VIDEO+640+48	;6
	DEFB	6,-1
	DEFW	@VIDEO+640+55	;7
	DEFB	7,-1
	DEFW	@VIDEO+640+62	;8
	DEFB	8,-1
	DEFW	@VIDEO+720+13	;9
	DEFB	9,-1
	DEFW	@VIDEO+720+20	;10
	DEFB	10,-1
	DEFW	@VIDEO+720+27	;11
	DEFB	11,-1
	DEFW	@VIDEO+720+34	;12
	DEFB	12,-1
	DEFW	@VIDEO+720+41	;13
	DEFB	13,-1
	DEFW	@VIDEO+720+48	;14
	DEFB	14,-1
	DEFW	@VIDEO+720+55	;15
	DEFB	15,-1
	DEFW	@VIDEO+720+62	;16
	DEFB	16,-1
	DEFW	@VIDEO+800+13	;17
	DEFB	17,-1
	DEFW	@VIDEO+800+20	;18
	DEFB	18,-1
	DEFW	@VIDEO+800+27	;19
	DEFB	19,-1
	DEFW	@VIDEO+800+34	;20
	DEFB	20,-1
	DEFW	@VIDEO+800+41	;21
	DEFB	21,-1
	DEFW	@VIDEO+800+48	;22
	DEFB	22,-1
	DEFW	@VIDEO+800+55	;23
	DEFB	23,-1
	DEFW	@VIDEO+800+62	;24
	DEFB	24,-1
	DEFW	0000H		;terminator
	ENDIF
;
;	lookup table for editing flags
;
TABLEB2	DEFB	00,32,92,04	;1	-00
	DEFB	04,36,00,08	;2	-04
	DEFB	08,40,04,12	;3	-08
	DEFB	12,44,08,16	;4	-12
	DEFB	16,48,12,20	;5	-16
	DEFB	20,52,16,24	;6	-20
	DEFB	24,56,20,28	;7	-24
	DEFB	28,60,24,32	;8	-28
;
	DEFB	00,64,28,36	;9	-32
	DEFB	04,68,32,40	;10	-36
	DEFB	08,72,36,44	;11	-40
	DEFB	12,76,40,48	;12	-44
	DEFB	16,80,44,52	;13	-48
	DEFB	20,84,48,56	;14	-52
	DEFB	24,88,52,60	;15	-56
	DEFB	28,92,56,64	;16	-60
;
	DEFB	32,64,60,68	;17	-64
	DEFB	36,68,64,72	;18	-68
	DEFB	40,72,68,76	;19	‚-72
	DEFB	44,76,72,80	;20	-76
	DEFB	48,80,76,84	;21	-80
	DEFB	52,84,80,88	;22	-84
	DEFB	56,88,84,92	;23	-88
	DEFB	60,92,88,00	;24	-92
	DEFB	00,00,00,00	;terminator
;
;	lookup table for screen editing arrows
;
TABLE2	DEFB	LEFT		;left arrow
	DEFW	ADVL
	DEFB	RIGHT		;right arrow
	DEFW	ADVR
	DEFB	UP		;up arrow
	DEFW	ADVU
	DEFB	DOWN		;down arrow
	DEFW	ADVD
	DEFB	ETBL		;end of table
;
;	table for flag command vectors
;
TABLE4	DEFB	'Y'		;turn flag on?
	DEFW	SETF
	DEFB	'S'		;set flag?
	DEFW	SETF
	DEFB	'+'		;set flag?
	DEFW	SETF
	DEFB	'N'		;turn flag off?
	DEFW	RESETF
	DEFB	'R'		;reset flag?
	DEFW	RESETF
	DEFB	'-'
	DEFW	RESETF
	DEFB	UP		;up arrow?
	DEFW	UFLAG
	DEFB	DOWN		;down arrow?
	DEFW	DFLAG
	DEFB	LEFT		;left arrow?
	DEFW	LFLAG
	DEFB	RIGHT		;right arrow?
	DEFW	RFLAG
	DEFB	ETBL		;end of table
;
;	program name to link back to menu
;
PGM1	DEFM	'PMAILM/CMD'
	DEFB	SYSDRV
	DEFB	SYSDRVN
	DEFB	ETX
;
;	open param list for mod II
;
	IF	MOD2
OLIST	DEFW	0		;buffer addr
	DEFW	0		;rec buff addr
	DEFW	0		;eof xfer
	DEFB	'W'
	DEFB	0		;LRL
	DEFB	'E'
	DEFB	0		;open existing only
	DEFB	00		;list terminator
	ENDIF
;
LSTPAGE	EQU	$&0FF00H	;last even page
BUFFER	EQU	LSTPAGE+100H	;first even free page
MASK	EQU	BUFFER+100H	;next page for mask area
FLAGBUF	EQU	MASK+100H	;flag name buffer
;
PGMEND	EQU	FLAGBUF+100H	;end of buffers
;
	SUBTTL	'<mailc - symbol table>'
;
	END	ENTRY
