; mailde/asm - kjw/bqsd - version 2.00 - 01/83
;
; revised 02/24/83 - kjw
;
	SUBTTL	'<mailde/asm - SEPARATE module>'
;
;	system data usage
;
;	+7,8,9		- current record # adder
;	+10,11,12	- current physical record 3
;	+13		- data offset
;	+14,15,16	- current record # data
;	+17,18,19	- physical record # data
;	+20		- data offset in I/O buff
;	+21		- drive #
;
SEPARAT	BIT	7,(IY+0)	;adder available?
	LD	HL,MSGEC	;'not available!'
	JP	Z,CANNOT	;cannot perform operation
;
	CALL	INITCNT		;clear counters
	LD	(IY+1),0	;clear all flags
	LD	HL,MSGE1	;'separate data => adder'
	CALL	GETDRV		;get drive from user
	JP	C,MENU		;go on BREAK
	LD	(IY+21),A	;save drive #
	CALL	LOCFCB		;locate FCB block
	BIT	7,(IX+0)	;file open?
	JR	Z,SEPARAT	;go if not!
	LD	A,(IX+10)	;get # records used
	OR	(IX+11)
	OR	(IX+12)		;anything?
	JR	Z,SEPARAT	;nope, another drive
;
SEPAR1	LD	HL,MSGE2	;'use flag mask?'
	CALL	DISPLAY		;display prompt
	LD	B,1		;one key input
	CALL	GETSTR		;get from keyboard
	JP	C,MENU		;go on break
	JR	Z,SEPAR1	;go if nil input
	CALL	UCASE		;make input upper case
	CP	'X'		;alternate BREAK?
	JP	Z,MENU		;go if yes
	CP	'N'		;no?
	RES	0,(IY+0)	;set NO mask
	JR	Z,SEPAR2	;go if no
	CP	'Y'		;yes?
	JR	NZ,SEPAR1	;neither, ask again
	SET	0,(IY+0)	;set YES mask
;
;	read flag mask into buffer
;
SEPAR2	LD	E,(IX+15)	;get FCB address
	LD	D,(IX+16)
	LD	BC,REWIND	;3 00's
;
	POSN$			;position file
	JP	NZ,DERROR	;go if disk error!
	READ$			;read first record
	JP	NZ,DERROR	;go on disk error
;
	LD	L,(IX+17)	;get I/O buffer
	LD	H,(IX+18)
	LD	DE,15H		;offset to flag mask
	ADD	HL,DE		;HL => mask
	LD	DE,FLAGMSK	;storage buffer
	LD	BC,6		;flag length
	LDIR			;move it in
;
;	see if records to be deleted after separate
;
SEPAR3	LD	HL,MSGE3	;'delete after separate?'
	CALL	DISPLAY		;display prompt
	LD	B,1		;one char input
	CALL	GETSTR		;from keyboard
	JP	C,MENU		;go on BREAK
	JR	Z,SEPAR3	;nil, no default
	CALL	UCASE		;make upper case
	CP	'X'		;alternate BREAK?
	JP	Z,MENU		;go if yes!
	RES	3,(IY+0)	;set NO delete
	CP	'N'		;no?
	JR	Z,SEPAR4	;go if no
	CP	'Y'		;yes?
	JR	NZ,SEPAR3	;neither, ask again
	SET	3,(IY+0)	;get YES delete
;
SEPAR4	LD	HL,MSGE4	;'separating'
	CALL	DISPLAY		;display message
	XOR	A		;load zero
	LD	(IY+7),A	;set current record
	LD	(IY+8),A
	LD	(IY+9),A
;
SEPAR5	CALL	STROBE		;strobe keyboard
	CP	BREAK		;break key?
	JP	Z,ABORT		;yes, abort operation
;
	CALL	SEPREAD		;read source record
	JP	NZ,DERROR	;go on disk error
	CALL	SEPMATC		;flag match?
	JP	NZ,SEPAR6	;nope, go next record
;
	LD	B,(IY+4)	;get # records in adder
	LD	H,(IY+5)
	LD	L,(IY+6)
	CALL	COMPSEC		;compute phys sector
	LD	(IY+20),A	;save offset
	PUSH	AF		;save offset
	CALL	INCBHL		;+1 for index sector
	POP	AF		;restore offset
	OR	A		;offset = 0?
	JP	Z,SEPAR5C	;go if yes
;
	BIT	6,(IY+1)	;record in memory?
	RES	6,(IY+1)	;set NO record
	JR	Z,SEPAR5A	;go if no!
	LD	C,(IY+17)	;get phys record
	LD	D,(IY+18)
	LD	E,(IY+19)
	CALL	CMPBHL		;BHL = CDE?
	JR	Z,SEPAR5D	;go if yes
;
SEPAR5A	LD	(IY+17),B	;update phys record
	LD	(IY+18),H
	LD	(IY+19),L
	LD	DE,FCBA		;adder FCB
	LD	BC,SYSTEM+17	;point to rec #
;
	POSN$			;position to record
	JP	NZ,DERROR	;go on disk error
	READ$			;read the record
	JP	NZ,DERROR	;go on disk error
	JR	SEPAR5D		;continue
;
SEPAR5C	LD	(IY+17),B	;update phys sector
	LD	(IY+18),H
	LD	(IY+19),L
;
SEPAR5D	SET	6,(IY+1)	;set record in memory
;
	LD	DE,BUFFA	;adder I/O buffer
	LD	L,(IY+20)	;get adder offset
	LD	H,0		;HL = offset
	ADD	HL,DE		;HL => dest record
	EX	DE,HL		;DE => dest record
	LD	L,(IX+17)	;get source buff pointer
	LD	H,(IX+18)
	LD	C,(IY+13)	;get source offset
	LD	B,0		;BC = offset
	ADD	HL,BC		;HL => source
	LD	C,128		;BC = record length
	LDIR			;move into adder buffer
;
;	write record to adder file
;
	LD	DE,FCBA		;adder FCB address
	LD	BC,SYSTEM+17	;point to rec #
;
	POSN$			;position file
	JR	Z,SEP1		;go if no error
	CP	1CH		;out of range?
	JR	Z,SEP1		;go if yes
	CP	1DH		;out of range?
	JP	NZ,DERROR	;go if neither!
SEP1	WRITE$			;write the record!
	JP	NZ,DERROR	;go if disk error
;
;	bump # records in adder file
;
	LD	B,(IY+4)	;get # records
	LD	H,(IY+5)
	LD	L,(IY+6)
	CALL	INCBHL		;bump count
	LD	(IY+4),B	;update
	LD	(IY+5),H
	LD	(IY+6),L
	CALL	ADDCNTA		;bump counter A
;
;	check if source record is to be deleted
;
	BIT	3,(IY+0)	;yes?
	JP	Z,SEPAR6	;go if no
;
	LD	L,(IX+17)	;get buffer pointer
	LD	H,(IX+18)
	LD	C,(IY+13)	;source offset
	LD	B,0		;BC = offset
	ADD	HL,BC		;HL => data start
	CALL	DELREC		;flag as deleted
;
;	write sector back to disk
;
	LD	BC,SYSTEM+10	;point to rec #
	LD	E,(IX+15)	;get FCB address
	LD	D,(IX+16)
;
	POSN$			;position file
	JP	NZ,DERROR	;go if posit error
	WRITE$			;write record
	JP	NZ,DERROR	;go on disk error
	CALL	ADDCNTB		;bump counter B
;
;	advance to next record
;
SEPAR6	LD	B,(IY+7)	;get source record
	LD	H,(IY+8)
	LD	L,(IY+9)
	CALL	INCBHL		;increment it
	LD	(IY+7),B	;update
	LD	(IY+8),H
	LD	(IY+9),L
	LD	C,(IX+10)	;get # records in file
	LD	D,(IX+11)
	LD	E,(IX+12)
	CALL	CMPBHL		;BHL = CDE?
	JP	NZ,SEPAR5	;go if not
;
	LD	DE,MSGEXA	;'records moved'
	LD	B,(IY+32)	;get counter A
	LD	H,(IY+33)
	LD	L,(IY+34)
	CALL	BINASC		;binary => ascii
	LD	DE,MSGEXB	;'records deleted'
	LD	B,(IY+35)
	LD	H,(IY+36)
	LD	L,(IY+37)
	CALL	BINASC		;binary => ascii
	LD	HL,MSGEX	;start of message
	JP	CANNOT		;display & go menu
;
;	check if flags match current file
;
SEPMATC	BIT	0,(IY+0)	;mask check on?
	RET	Z		;nope, everything matches
;
	LD	L,(IX+17)	;get buffer pointer
	LD	H,(IX+18)
	LD	E,(IY+13)	;get data offset
	LD	D,0		;DE = offset
	ADD	HL,DE		;HL => source data
	LD	E,125		;offset to flags
	ADD	HL,DE		;HL => flags
	PUSH	IX		;save IX
	LD	IX,FLAGMSK	;stored flag mask
	LD	B,3		;3 bytes to check
	LD	A,(IX+3)	;any mask?
	OR	(IX+4)
	OR	(IX+5)
	JR	Z,CKFLER	;no, match!
;
CKFLGM	LD	A,(IX+3)	;get flag mask
	AND	(HL)		;keep test bits only
	CP	(IX+0)		;match?
	JR	NZ,CKFLER	;nope, return NZ
	INC	IX		;bump mask
	INC	HL		;bump data
	DJNZ	CKFLGM		;test all 3
CKFLER	POP	IX		;unstack IX
	RET			;return with Z/NZ status
;
;	read source file for convert
;
SEPREAD	LD	B,(IY+7)	;get source record #
	LD	H,(IY+8)
	LD	L,(IY+9)
	LD	E,(IX+15)	;get FCB address
	LD	D,(IX+16)
	CALL	COMPSEC		;compute sector #
	LD	(IY+13),A	;save offset
	LD	C,(IX+4)	;get start record #
	LD	D,(IX+5)
	LD	E,(IX+6)
	CALL	ADDIT		;add BHL = BHL + CDE
	BIT	7,(IY+1)	;record in memory?
	JR	Z,SEPR1		;go if not
	LD	C,(IY+10)	;get phys record in mem
	LD	D,(IY+11)
	LD	E,(IY+12)
	CALL	CMPBHL		;CDE = BHL?
	JR	Z,SEPR2		;go if yes!
;
SEPR1	RES	7,(IY+1)	;set NO record
	LD	(IY+10),B	;update current sector
	LD	(IY+11),H
	LD	(IY+12),L
	LD	E,(IX+15)	;get FCB address
	LD	D,(IX+16)
	LD	BC,SYSTEM+10	;point to record
;
	POSN$			;position to record
	RET	NZ		;go if error
	READ$			;read the sector
	RET	NZ		;go if disk error
;
SEPR2	SET	7,(IY+1)	;set record in memory
	XOR	A		;return no error
	RET			;done
;
;##
;
MSGE1	DEFB	SETCUR
	DEFB	12,00
	DEFB	EOF
	DEFM	'Separating DATA => ADDER'
	DEFB	CR
	DEFB	ETX
;
MSGEX	DEFB	SETCUR
	DEFB	14,00
	DEFB	EOF
MSGEXA	DEFM	'xxxxxxxx Records Separated, '
MSGEXB	DEFM	'xxxxxxxx Records Deleted, (KEY):'
	DEFB	ETX
;
MSGEC	DEFB	SETCUR
	DEFB	12,00
	DEFB	EOF
	DEFM	'Cannot Separate, Adder File '
	DEFM	'NOT AVAILABLE, (KEY):'
	DEFB	ETX
;
MSGE2	DEFB	SETCUR
	DEFB	14,00
	DEFB	EOF
	DEFM	'Use Flag Mask as Condition ? '
	DEFB	ETX
;
MSGE3	DEFB	SETCUR
	DEFB	14,00
	DEFB	EOF
	DEFM	'Delete Records from Data after '
	DEFM	'Separating ? '
	DEFB	ETX
;
MSGE4	DEFB	SETCUR
	DEFB	14,00
	DEFB	EOF
	DEFM	'Separating - '
	DEFB	ETX
;
;	delete current record
;
DELREC	LD	DE,14		;offset to end of name
	ADD	HL,DE		;HL => last char
	LD	D,H		;pass to DE
	LD	E,L		;DE => last
	DEC	HL		;HL = last -1
	LD	BC,14		;length -1
	LDDR			;move it up
	LD	A,-1		;delete flag
	LD	(DE),A		;to first char
	RET			;done
;
