;CONV/ASM - Convert TRSDOS 1.2, 1.3 Disks
	TITLE	<CONV - LS-DOS 6.2>
;
HOME	EQU	1CH
CLR	EQU	1FH
ETX	EQU	03H
CR	EQU	0DH
LF	EQU	10
;
FLAG	EQU	01000000B
ABB	EQU	00010000B
;
*GET	SVCMAC:3		;SVC Macro equivalents
*GET	COPYCOM:3		;Copyright message
;
	ORG	2600H
;
BEGIN
	IF	@BLD631
	LD	(STACK),SP	;<631>Save entry stack
	@@CKBRKC		;<631>Check for break
	JR	NZ,$ABORT	;<631>abort
	ELSE
	@@CKBRKC
	JR	Z,BEGINA	;Continue if no break
	LD	HL,-1
	RET			;  else abort
;
BEGINA
	LD	(STACK),SP	;Save entry stack
	ENDIF
	PUSH	HL		;Save ptr to CMD buffer
	@@DSPLY	HELLO$		;Display the signon
	LD	HL,0		;Set up to get HIGH$
	LD	B,L
	@@FLAGS			;IY => flag table base
	BIT	1,(IY+'C'-'A')	;OK if not CMDR
	JR	Z,NOTCMDR	;Use LOW$ otherwise
	INC	B
NOTCMDR	@@HIGH$			;P/u HIGH$/LOW$
	LD	(MYHIGH),HL	;Store away
	PUSH	IY		;Trans to HL
	POP	DE
	LD	HL,'K'-'A'	;Offset to KFLAG$
	ADD	HL,DE		;HL=>KFLAG$
	LD	(KFLG),HL	;Store pointer
	RES	0,(HL)		;Kick break bit off
	LD	HL,'S'-'A'	;SFLAG$ offset
	ADD	HL,DE
	LD	(SFLG),HL	;Store away
	POP	HL		;Restore cmd pointer
	CALL	PGRM		;  and continue
;
;	Exit routines
;
$EXIT	LD	HL,0		;Init to no error
$QUIT	@@CKBRKC		;Clear out break bit
	LD	SP,$-$		;P/u original stack
STACK	EQU	$-2
	RET
;
$ABORT	LD	HL,-1		;Set abort code
	JR	$QUIT		;  and quit
;
	IF	@BLD631
$CR	LD	A,CR		;<631>
	ENDIF
$DSP	PUSH	BC		;Display a character,
	LD	C,A		;  saving BC
	@@DSP
	POP	BC
	RET
;
;	Pick up drive numbers and partial filespec
;
PGRM:
	LD	A,(HL)		;Check for NOT filespec
	CP	'-'		;  char used
	JR	NZ,MVNAM1	;Go if not NOT
	LD	A,0FFH		;TRUE value
	LD	(NOTPRM),A	;Set if specified
	INC	HL
MVNAM1	LD	DE,PATTRN	;Point to possible partspec
	LD	B,8		;Max 8 chars in name
	CALL	SKIPSP		;Skip spaces
	CALL	MOVELT		;Move letters/digits/$
	CALL	SKIPLT		;Skip letters/digits/$
	LD	A,(HL)		;Check for extension
	CP	'/'
	JR	NZ,NOEXT	;Go if none
	INC	HL
	LD	DE,PATEXT	;Point to ext field
	LD	B,3		;Max 3 chars in ext
	CALL	MOVELT		;Move letters/digits/$
	CALL	SKIPLT		;Skip letters/digits/$
NOEXT	CALL	GETDRV		;Get source drive #
	LD	(SDRIVE),A	;Store drive #
	AND	A		;Be sure not drive 0
	LD	DE,NOT0		;Error msg
	EX	DE,HL
	JP	Z,PERR1		;Param error source is 0
	EX	DE,HL		;Restore cmd line ptr
	CALL	SKIPSP		;Skip spaces
	CALL	GETDRV2		;Get destination drive
	LD	(DDRIVE),A	;0FFH if no dest drv
	CALL	SKIPSP		;Move to '('
;
;	Scan parameters
;
	LD	DE,PRMTBL$	;Check parameters entered
	@@PARAM
	JP	NZ,PRMERR	;Quit on parm error
DPARM	LD	HL,$-$		;DIR only?
	LD	A,H
	OR	L
	JR	Z,SPARM		;Go if not
	LD	A,0FFH		;Set flag at DDRIVE
	LD	(DDRIVE),A	;If dest is ff, read DIR
SPARM	LD	HL,$-$		;Check if no parms S,I,V
VPARM	LD	DE,$-$
IPARM	LD	BC,$-$
	LD	A,L
	OR	E
	OR	C
	LD	(SIV+1),A	;Save S!I!V
QPARM	LD	HL,0FFFFH	;P/u Q,N,O parms
NPARM	LD	DE,0
OPARM	LD	BC,0
	LD	A,E		;Form N!O
	OR	C
	LD	(NORO+1),A	;Save that
;
;	Save old DCT
;
	LD	A,(SDRIVE)	;Pick up source drive #
	LD	C,A		;Move to C reg
	LD	A,(DDRIVE)	;Be sure not single drive
	CP	C
	LD	HL,NOTONE	;=>error msg
	JP	Z,PERR1		;Go if same
	@@GTDCT			;Point to DCT
	PUSH	BC		;Save drive #
	PUSH	IY		;Move DCT to HL reg
	POP	HL
	LD	DE,SAVDCT	;Point to save area
	LD	BC,10
	LDIR			;Move it
	POP	BC
;
;	Find directory track
;
	LD	DE,0001		;Track 0, sector 1
	LD	HL,DBUFF	;Buffer for sector
	@@RDSEC
	JR	Z,OK0		;Go if no error
	CP	6		;Was it DAM error?
	JP	NZ,IOERR	;Go if some other
	CALL	CKEARLY		;Can we do this type?
OK0	INC	HL		;Point to dir cyl #
	LD	D,(HL)		;Get it
	INC	H		;Point to TRSDOS
	DEC	HL		;  version number
	DEC	HL
	DEC	HL
	LD	A,(HL)		;Pick it up
	LD	(TRSDOS+1),A	;Save for later
;
;	Read directory records into memory
;
	LD	E,3		;Skip GAT and HIT
	LD	B,16		;Read 16 sectors
	LD	HL,DBUFF
DREAD	LD	(IY+7),18	;Chg # sectors/trk for
	@@RDSEC			;  TRSDOS & Read a sector
	JR	Z,OK1		;Go if no error
	CP	6		;Ignore record type
	JP	NZ,IOERR	;Go if error
OK1	INC	H		;Bump buffer pointer
	INC	E		;Bump sector number
	DJNZ	DREAD		;Loop till done
;
;	Loop through all entries
;
	LD	HL,DBUFF	;Point to first entry
ELOOP	EQU	$
	LD	A,($-$)		;Check system break bit
KFLG	EQU	$-2		;Address of KFLAG
	BIT	0,A
	JP	NZ,$ABORT	;Abort if set
	LD	B,(HL)		;P/U attributes
	PUSH	HL
	POP	IX
	PUSH	HL
	BIT	4,B		;Alive?
	JP	Z,SKIPIT	;Skip it if dead
	BIT	7,B		;FXDE?
	JP	NZ,SKIPIT	;Skip it if so
;
;	Check file's attributes
;
SIV	LD	A,$-$		;S, I, or V given?
	AND	A
	JR	Z,NOSIV		;Go if none given
	BIT	6,B		;SYS file?
	JR	Z,NOTSYS	;Go if not
	LD	A,(SPARM+1)	;S parm given?
	AND	A
	JP	Z,SKIPIT	;Skip file if not
	JR	NOSIV		;  else possible match
NOTSYS	BIT	3,B		;Visible or invisible?
	JR	NZ,INV		;Go if inv
	LD	A,(VPARM+1)	;V parm given?
	AND	A
	JP	Z,SKIPIT	;Skip file if not
	JR	NOSIV		;  else possible match
INV	LD	A,(IPARM+1)	;I parm given?
	AND	A
	JP	Z,SKIPIT	;Skip file if not
;
;	Check if name matches wildcard
;
NOSIV	LD	DE,5		;Offset to name field
	ADD	HL,DE
	PUSH	HL		;Compare with pattern
	LD	DE,PATTRN	;  of user partspec
	LD	B,11
CPLOOP	LD	A,(DE)		;P/U pattern byte
	INC	DE
	CP	'$'		;Matchall?
	JR	Z,MATCH
	CP	(HL)		;Match?
	JR	NZ,NMATCH	;Go if not
MATCH	INC	HL
	DJNZ	CPLOOP
NMATCH	POP	HL		;Z if match, NZ if not
	CALL	NOTCHK		;Reverse flag if NOT entered
	JP	NZ,SKIPIT	;Skip file if no match
;
	LD	DE,FCB		;Point to FCB
	LD	B,8
MVNAME	LD	A,(HL)		;Move name
	CP	' '		;Space?
	JR	Z,GOTNAM	;Go if hit one
	INC	HL
	LD	(DE),A		;Put to FCB
	INC	DE
	DJNZ	MVNAME
GOTNAM	LD	C,B		;Offset to ext field
	LD	B,0
	ADD	HL,BC
	LD	A,(HL)		;No extension?
	CP	' '
	JR	Z,GOTEXT	;Go if so
	LD	A,'/'		;Put in slash
	LD	(DE),A
	INC	DE
	LD	B,3
EXLOOP	LD	A,(HL)		;Move extension
	INC	HL
	CP	' '		;Finished?
	JR	Z,GOTEXT
	LD	(DE),A
	INC	DE
	DJNZ	EXLOOP		;Loop till done
;
	IF	@BLD631
GOTEXT:	PUSH	DE		;<631>Save current spot in FCB
	LD	HL,FNAME	;<631>Move name to buffer
	CALL	CPYFCB		;<631>Do 32 byte LDIR
	ELSE
GOTEXT	LD	A,ETX		;Put ETX at end for dsply
	LD	(DE),A
	PUSH	DE		;Save current spot in FCB
	LD	HL,FCB		;Move name to buffer
	LD	DE,FNAME	;  for printing
	LD	BC,32
	LDIR
	ENDIF
	POP	DE		;Get back where we were
;
;Print filenames if no destination drive (DDRIVE=0FFH)
;
	LD	A,(DDRIVE)	;Check for just printing DIR
	INC	A		;Set Z if FF
	JR	NZ,MOVING	;Go if not FF
	CALL	SHOW		;Print entry
	JP	SKIPIT		;  and go on to next
;
;	Check if file exists on destination disk
;
MOVING	LD	A,':'		;Now put the drive separator
	LD	(DE),A		;  in the FCB
	INC	DE
	LD	A,(DDRIVE)	;Put in drive spec
	OR	'0'		;Change number to ASCII
	LD	(DE),A
	INC	DE
	IF	@BLD631
	LD	HL,FCB2		;<631>Copy into 2nd FCB
	PUSH	HL		;<631>
	CALL	CPYFCB		;<631>
	POP	DE		;<631>
	LD	HL,TBUFF	;Point to transfer buffer
	ELSE
	LD	A,ETX		;Put in ETX to end
	LD	(DE),A
	LD	HL,FCB		;Copy into 2nd FCB
	LD	DE,FCB2
	LD	BC,32
	LDIR
	LD	DE,FCB2		;Point to start of FCB
	LD	HL,TBUFF	;Point to transfer buffer
	LD	B,0		;LRL=256
	ENDIF
	PUSH	HL
	LD	HL,$-$		;HL => SFLAG
SFLG	EQU	$-2
	SET	0,(HL)		;Set the open inhibit bit
	POP	HL
	@@OPEN			;Do the open
	LD	B,A		;Save return code
	JR	Z,NORO		;Go if opened okay
	CP	18H		;File not found?
	JP	NZ,IOERR	;  else an error
;
;	Check New and Old parms
;
NORO	LD	A,0		;N or O specified?
	AND	A
	JR	Z,CHECKQ	;Go if neither
	LD	A,(OPARM+1)	;O parm given?
	AND	A
	JR	Z,CKNEW		;Go if not
	XOR	A
	OR	B		;Did file exist?
	JR	Z,CHECKQ	;Go if so (ok)
CKNEW	LD	A,(NPARM+1)	;N parm given?
	AND	A
	IF	@BLD631
	JR	Z,TOSKIP1	;<631>Skip file if not
	ELSE
	JP	Z,SKIPIT	;Skip file if not
	ENDIF
	XOR	A
	OR	B		;Be sure it was new
	IF	@BLD631
TOSKIP1:			;<631>
	ENDIF
	JP	Z,SKIPIT	;Go if it wasn't
;
;	Ask question if Q parm was given
;
CHECKQ	LD	A,(QPARM+1)	;Check Q parm
	AND	A
	JR	NZ,QUERY	;Query if so
	LD	HL,CONVS	;"Converting..."
	@@DSPLY	
	LD	HL,FNAME	;Filename
	@@DSPLY	
	IF	@BLD631
	CALL	$CR		;<631>Display carriage return
	ELSE
	LD	A,CR		;Carriage return
	CALL	$DSP
	ENDIF
	JR	TAKEIT1		;Go & move it
;
QUERY	LD	HL,CONVQ	;"Convert file
	@@DSPLY			;Display it
	LD	HL,QMARK	;"?"
	@@DSPLY	
	LD	HL,ABUFF	;Get answer
	LD	BC,3<8		;3 char max
	@@KEYIN
	JP	C,$ABORT	;Abort if BREAK hit
	LD	A,(HL)		;Check for 'Y'
	RES	5,A		;Force upper case
	CP	'Y'
	JP	NZ,SKIPIT	;Skip it if not 'Y'
;
;	If file exists, query user
;
	LD	A,(FCB2)	;Was file opened ok?
	BIT	7,A		;Z = not found
	JR	Z,TAKEIT1	;Go if it does not exist
	LD	HL,EXISTQ	;"File exists, replace?
	@@DSPLY			;Print question
	LD	HL,ABUFF
	LD	BC,3<8
	@@KEYIN			;Get answer
	JP	C,$ABORT	;Abort if break
	LD	A,(HL)		;Check answer
	RES	5,A		;Force uppercase
	CP	'Y'
	JP	NZ,SKIPIT	;Skip if 'no'
;
;	Init file if it didn't exist
;
TAKEIT1	LD	DE,FCB2
	LD	A,(DE)		;Was file opened?
	BIT	7,A		;Z = not opened
	JR	Z,$+5		;Remove existing file
	@@REMOV			;  for new LRL
	LD	DE,FCB		;Use other FCB now
	LD	HL,TBUFF	;Create file
	LD	B,(IX+4)	;P/U Mod III LRL
	@@INIT			;Create the file
	IF	@BLD631
	JR	NZ,TOIOERR	;<631>Go if error
	ELSE
	JP	NZ,IOERR	;Go if error
	ENDIF
	PUSH	DE		;Change LRL to 0 for copy
	EX	(SP),IX		;IX to FCB start
	RES	7,(IX+1)	;Show full sector ops
	LD	(IX+9),0	;Show LRL=0
	EX	(SP),IX		;Switch back
	POP	DE
;
;	Initialize to read from source file
;
TAKEIT2	POP	HL		;Point to dir entry
	PUSH	HL
	LD	DE,20		;Point to ERN
	ADD	HL,DE
	LD	E,(HL)		;P/U ERN
	INC	HL
	LD	D,(HL)
	INC	HL		;Leave ptg to extents
TRSDOS	LD	A,0		;1.3 or later?
	CP	13H
	JR	C,EARLY		;Go if earlier than 1.3
	LD	A,(IX+3)	;Pick up EOF offset
	AND	A		;Zero?
	JR	Z,EARLY		;No adjustment if so
	INC	DE		;If nonzero, adjust ERN
EARLY	LD	B,0		;# sectors left in extent
	PUSH	DE		;Save ERN
	EXX			;Switch to alternate regs
;
;	Preallocate file
;
	POP	BC
	LD	A,B		;Empty file?
	OR	C
	JR	Z,READ		;Go if so
	DEC	BC
	LD	DE,FCB		;Point to FCB
	@@POSN			;Position to last sector
	JR	Z,OK3
	CP	1CH		;Ignore EOF errors
	JR	Z,OK3
	CP	1DH		;  or past end errors
	IF	@BLD631
TOIOERR:
	ENDIF
	JP	NZ,IOERR	;Quit on any others
OK3	@@WRITE			;Write it
	IF	@BLD631
	JR	NZ,TOIOERR	;<631>Quit on write error
	ELSE
	JP	NZ,IOERR	;Quit on write error
	ENDIF
	@@REW			;Position to start
	IF	@BLD631
	JR	NZ,TOIOERR	;<631>
	ELSE
	JP	NZ,IOERR
	ENDIF
;
;	Read sectors
;
	IF	@BLD631
READ	LD	HL,TBUFF	;<631>Point to transfer buffer
	LD	B,L		;<631>Count sectors read (L=0)
	ELSE
READ	LD	B,0		;Count sectors read
	LD	HL,TBUFF	;Point to transfer buffer
	ENDIF
	LD	DE,$-$
MYHIGH	EQU	$-2		;Stuff HIGH$ value
	DEC	D		;256 bytes back
GETONE	CALL	GETSEC		;Get next sector
	JR	NZ,WRITE	;Go if EOF
	INC	B		;Count sector
	INC	H		;Point to next spot
	CALL	CPHLDE		;Compare HL and DE
	LD	A,0		;No error code
	JR	NC,WRITE	;Go if mem full
	JR	GETONE		;  else loop for more
;
;	Write sectors to destination file
;
WRITE	PUSH	AF		;Save completion type
	LD	DE,FCB		;Point to file fcb
	LD	HL,TBUFF	;Point to transfer buffer
WRLOOP	LD	(FCB+3),HL	;Point FCB to buffer
	LD	A,B		;Zero to write?
	AND	A
	JR	Z,WRDUN		;Go if so
	@@WRITE			;Write to file
	IF	@BLD631
	JR	NZ,TOIOER2	;<631>Quit on write error
	ELSE
	JP	NZ,IOERR	;Quit on write error
	ENDIF
	INC	H
	DJNZ	WRLOOP		;Loop till done
;
;	Were we at EOF?
;
WRDUN	POP	AF		;Restore completion type
	AND	A		;At end of file?
	JR	Z,READ		;Go if not
;
;	Copy over EOF offset
;
	LD	A,(IX+3)	;P/U offset from dir
	LD	(FCB+8),A	;Put into FCB
	@@CLOSE			;  and close the file
	IF	@BLD631
TOIOER2:JR	NZ,IOERR	;<631>Quit on close error
	ELSE
	JP	NZ,IOERR	;Quit on close error
	ENDIF
;
;	Increment to next entry and loop if not done
;
SKIPIT	POP	HL
	LD	DE,48		;48 bytes per entry
	ADD	HL,DE
	LD	A,L		;End of sector?
	CP	0F0H
	JR	NZ,NOTEOS	;Go if not
	INC	H
	IF	@BLD631
	LD	L,D		;<631>D==0
	ELSE
	LD	L,0
	ENDIF
NOTEOS	LD	DE,TBUFF	;Done?
	CALL	CPHLDE		;CP HL,DE
	JP	C,ELOOP		;Loop back if not done
;
;	Finished
;
	IF	@BLD631
	CALL	$CR		;<631>Blank line
	ELSE
	LD	A,CR		;Blank line
	CALL	$DSP
	ENDIF
	CALL	BYEBYE		;Restore DCT
	JP	$EXIT
;
QUIT	CALL	BYEBYE		;Restore DCT
	IF	@BLD631
	JR	TOABORT		;<631>
	ELSE
	JP	$ABORT
	ENDIF
;
;	Error routines
;
IOERR	CALL	BYEBYE		;Restore DCT
IOERR1	LD	L,A		;Entry from PRMERR
	LD	H,0
	OR	0C0H		;Abbrev, return
	LD	C,A		;Error code to C
	@@ERROR			;  for error display
	JP	$QUIT
;
BYEBYE	PUSH	IY		;Move back DCT
	POP	DE
	LD	HL,SAVDCT	;Point to save area
	LD	BC,10
	LDIR
	RET
;
PRMERR	LD	A,44		;Init "parameter error
	JR	IOERR1
PERR1	@@LOGOT			;Display and log
	IF	@BLD631
TOABORT:			;<631>
	ENDIF
	JP	$ABORT
;
;	Sector read routine
;
GETSEC	EXX			;P/U alt registers
	LD	A,D		;Any records left?
	OR	E
	JR	NZ,NOTEND	;Go if so
BDEXT	EXX
	LD	A,1CH		;EOF code
	AND	A		;Set NZ condition
	RET
;
NOTEND	XOR	A		;Check if used up ext
	OR	B
	JR	NZ,MORE		;Go if not used up
	LD	A,(HL)		;Check next trk#
	CP	0FFH		;Non-allocated?
	JR	Z,BDEXT		;Then consider EOF
	PUSH	DE		;Save DE'
	LD	D,(HL)		;P/U track number
	INC	HL
	LD	B,(HL)		;P/U other stuff
	INC	HL
	LD	A,B		;Get starting gran
	RLCA
	RLCA			;Move to bits 0-2
	RLCA
	AND	7		;Mask off other garbage
	LD	E,A		;Multiply by 3
	RLCA
	ADD	A,E
	INC	A		;Offset from 0
	LD	E,A		;  and move to E reg
	LD	(TRKSEC),DE	;Save for later
	POP	DE		;Restore DE'
	LD	A,B		;Get number of grans
	AND	1FH
	LD	B,A		;Multiply by 3
	RLCA
	ADD	A,B
	LD	B,A		;And put in B reg
;
;	Read sector
;
MORE	DEC	B		;Count down # sec in ext
	DEC	DE		;Count down # records
	EXX			;Restore primary set
	PUSH	DE		;Save DE
	PUSH	BC		;Save BC
	LD	DE,(TRKSEC)	;P/U track and sector #
	LD	A,(SDRIVE)	;P/U source drive
	LD	C,A
	LD	(IY+7),18	;Reset sec/trk each time
	@@RDSEC			;Read sector to (HL)
	JR	Z,OK2		;Go if no errors
	CP	6		;  or address mark differs
	JP	NZ,IOERR	;Quit on any other
OK2	INC	E		;Step to next sector
	LD	A,E
	CP	19D		;End of track?
	JR	NZ,NOTEOT	;Go if not
	LD	E,1		;Reset to sector 1
	INC	D		;Next track
NOTEOT	LD	(TRKSEC),DE
	POP	BC
	POP	DE
	XOR	A
	RET
;
;	Parsing subroutines
;
GETDRV2	LD	A,(HL)
	CP	':'
	LD	A,0FFH		;'Not entered' value
	RET	NZ		;If no second drive, give DIR
;
GETDRV	LD	A,(HL)		;Parse drivespec
	CP	':'
	JR	NZ,PRMERR	;Go if missing
	INC	HL
	LD	A,(HL)		;P/U drivespec
	IF	@BLD631
	SUB	'0'		;<631>
	CP	7+1		;<631>Be sure it is a digit
	JR	NC,PRMERR	;<631>
	INC	HL		;<631>Bump cmdline ptr
	ELSE
	CP	'0'		;Be sure digit
	JR	C,PRMERR
	CP	'7'+1
	JR	NC,PRMERR
	INC	HL		;Bump cmdline ptr
	AND	7		;Make drive # binary
	ENDIF
	RET
;
SKIPSP	LD	A,(HL)		;Skip spaces
	CP	' '
	RET	NZ
	INC	HL
	JR	SKIPSP
;
SKIPLT	LD	A,(HL)		;Skip letters/digits/$
	CALL	CHKLET		;Check letter/digit/$
	RET	NZ
	INC	HL
	JR	SKIPLT
;
MOVELT	LD	A,(HL)		;Move letters/digits/$
	CALL	CHKLET
	RET	NZ
	INC	HL		;Inc from buffer
	LD	(DE),A		;Store
	INC	DE		;Inc to buffer
	JR	MOVELT
;
CHKLET	BIT	7,A		;Graphic?
	RET	NZ
	CP	'a'		;Lowercase?
	JR	C,NOTLC		;Go if not
	RES	5,A		;  else make upper case
NOTLC	CP	'$'		;Dollar sign?
	RET	Z
	CP	'0'		;Digit?
	RET	C		;Return (NZ) if less
	CP	'9'+1
	JR	NC,NOTDIG	;Go if not digit
	CP	A		;Mark as letter/digit/$
	RET
NOTDIG	CP	'A'		;Letter?
	RET	C		;Return (NZ) if less
	CP	'Z'
	RET	NC		;Z if =Z, NZ if >Z
	CP	A		;Z if <Z
	RET
;
CPHLDE	PUSH	HL		;Compare HL and DE
	AND	A
	SBC	HL,DE
	POP	HL
	RET
;
;If NOT (-) spec given, reverse Z flag setting
;
NOTCHK	PUSH	AF		;Save current setting
	LD	A,(NOTPRM)	;Was NOT entered?
	OR	A
	JR	Z,NOTNOT	;No, restore previous
	POP	AF		;Get previous
	JR	Z,SETIT		;Was Z, make NZ
	XOR	A		;  else was NZ, make Z
	RET
SETIT	OR	0FFH		;make NZ
	RET
NOTNOT	POP	AF		;Get previous flags
	RET
;
;Display mod 3 TRSDOS disk directory
;
SHOW	PUSH	HL
	PUSH	DE
	PUSH	BC		;Save registers
	LD	C,0		;Init char count
	LD	HL,FNAME	;=>name
NMDSP	LD	A,(HL)		;Get a character
	CP	ETX		;Are we done?
	JR	Z,NMEND		;Finish if so
	CALL	$DSP		;Print this char
	INC	C		;Count it
	INC	HL		;=>next char
	JR	NMDSP		;Until ETX
;
NMEND	LD	HL,$-$		;P/u line/char count
CCOUNT	EQU	$-2
	LD	A,C		;Count for this entry
	ADD	A,L		;Add to previous
	LD	L,A		;Save posn
	LD	A,16		;Spaces for entry
	SUB	C		;Less used
	LD	B,A		;Remaining to B
SPLP	LD	A,' '		;Pad remaining w/spaces
	CALL	$DSP
	INC	L		;Count it
	LD	A,L		;Check char posn
	CP	78		;End of line?
	JR	Z,ELINE		;Then print CR
	DJNZ	SPLP		;  else keep going
;
ESHOW	LD	(CCOUNT),HL	;Save line/char posn
	POP	BC		;Restore regs
	POP	DE
	POP	HL
	RET			;Done w/entry
;
	IF	@BLD631
ELINE:	CALL	$CR		;<631>Hit end of line
	ELSE
ELINE	LD	A,CR		;Hit end of line
	CALL	$DSP
	ENDIF
	INC	H		;Bump line posn
	LD	L,0		;Start on next
	LD	A,23		;Max lines
	CP	H		;There yet?
	JR	NZ,ESHOW	;Nope
	@@KEY			;Wait for a key
	IF	@BLD631
	LD	A,HOME		;<631>Cursor home
	CALL	$DSP		;<631>
	LD	A,CLR		;<631>Clear to end-of-frame
	CALL	$DSP		;<631>
	ELSE
	CALL	$CLS		;Clear the display
	ENDIF
	LD	HL,0		;Restart count
	JR	ESHOW
;
	IF	@BLD631
	ELSE
$CLS	LD	A,HOME		;Cursor home
	CALL	$DSP
	LD	A,CLR		;Clear to end-of-frame
	JP	$DSP
	ENDIF
;
CKEARLY	DB	0
	LD	A,(DBUFF+22H)	;Get type byte
	CP	0FFH		;Do we know this one?
	RET	Z		;OK to continue
	LD	A,(DDRIVE)	;Doesn't matter if
	INC	A		;  only doing DIR
	RET	Z
	LD	HL,EARLYD	;Err msg
	JP	PERR1		;Quit
;
	IF	@BLD631
CPYFCB:	LD	A,ETX		;<631>
	LD	(DE),A		;<631>
	EX	DE,HL		;<631>
	LD	HL,FCB		;<631>
	LD	BC,32		;<631>
	LDIR			;<631>
	RET			;<631>
;
	ENDIF
PRMTBL$	DB	80H
	DB	ABB!FLAG!5
	DB	'QUERY',0
	DW	QPARM+1
	DB	ABB!FLAG!3
	DB	'SYS',0
	DW	SPARM+1
	DB	ABB!FLAG!3
	DB	'INV',0
	DW	IPARM+1
	DB	ABB!FLAG!3
	DB	'VIS',0
	DW	VPARM+1
	DB	ABB!FLAG!3
	DB	'OLD',0
	DW	OPARM+1
	DB	ABB!FLAG!3
	DB	'NEW',0
	DW	NPARM+1
	DB	ABB!FLAG!3
	DB	'DIR',0
	DW	DPARM+1
	NOP
;
;	Messages and buffers
;
NOTPRM	DB	0
PATTRN	DB	'$$$$$$$$'
PATEXT	DB	'$$$'
HELLO$	DB	'CONV'
*GET	CLIENT:3
NOTONE	DB	'Source and Destination drives are the same',CR
NOT0	DB	'Source cannot be drive 0',CR
	IF	@BLD631
EARLYD	DB	'Can''t CONV Protected Disk',CR
	ELSE
EARLYD	DB	'Cannot CONV Protected Diskette',CR
	ENDIF
	IF	@BLD631
EXISTQ	DB	'  File exists -- replace it'	;<631>
QMARK	DB	'? ',ETX			;<631>
	ELSE
QMARK	DB	'? ',ETX
EXISTQ	DB	'  File exists -- replace it? ',ETX
	ENDIF
CONVS	DB	'Converting file: ',ETX
CONVQ	DB	'Convert file '
FNAME	DS	32		;Must follow CONVQ
FCB	DS	32		;For INIT/WRITE
FCB2	DS	32		;For OPEN (test for already existing)
SDRIVE	DS	1
DDRIVE	DS	1
TRKSEC	DS	2
ABUFF	DS	5
SAVDCT	DS	10
	ORG	$<-8+1<8
DBUFF	DS	1000H		;16 sectors of directory
TBUFF	EQU	$		;To end of memory
;
	END	BEGIN
