;	RESTORE - RECOVER ERASED FILES
;
	ORG	0100H
	JMP	RESTORE
	DB	'(C) 1980 - N D H HAMMOND'
PRGNAME	DB	'RESTORE V1.1 OF 21APR80'
	DB	0DH,0AH,'$'
;
;	DEFINITIONS
;
BOOT	EQU	0000H		;CP/M BOOT VECTOR
CBIOS	EQU	BOOT+1		;^CBIOS
ENTRY	EQU	0005H		;CP/M FDOS ENTRY
FCB	EQU	005CH		;DEFAULT FCB
NAME2	EQU	006DH		;POSN OF 2ND 'FILENAME'
FNAME	EQU	FCB+1		;NAME FIELD
DIRTRK	EQU	2		;DIRECTORY TRACK NO
NDIRSEC	EQU	16		;NO OF DIR SECTORS
NDIRENT	EQU	64		;MAX NO OF DIR ENTRIES
ENTLGTH	EQU	32		;ENTRY LGTH IN BYTES
NLGTH	EQU	8		;NAME FIELD LGTH
TLGTH	EQU	3		;TYPE FIELD LGTH
FNLGTH	EQU	NLGTH+TLGTH	;LENGTH OF FILENAME
DELCHR	EQU	0E5H		;DELETED DATA CHAR
VALCHAR	EQU	00H		;VALID DATA CHAR
;
;	MAIN PROGRAM
;
RESTORE	LXI	H,0		;SAVE SYSTEM SP
	DAD	SP
	SHLD	OLDSP
	LXI	SP,STACK
	LXI	D,PRGNAME	;PRINT SIGNON MSG
	CALL	WRITESTRING
	CALL	CHKEXT
	CALL	GETDISK
	CALL	READDIR
	CALL	REST
	JC	EXIT
	CALL	WRITEDIR
	CALL	INITBDOS
	LXI	D,TERMMSG
	CALL	WRITESTRING
EXIT	LHLD	OLDSP		;RESTORE SYSTEM SP
	SPHL
	RET			;RETURN TO CP/M
;
;	SUBROUTINES
;
CHKEXT		;CHECK FOR FILE EXTENSION
	XRA	A
	STA	EXTNO
	LDA	NAME2+1
	CPI	' '
	JNZ	INVEXT
	LDA	NAME2
	CPI	' '
	RZ		;EMPTY, EXT:=0
	CPI	'0'
	JC	INVEXT
	CPI	'9'+1
	JC	NUM
	CPI	'A'
	JC	INVEXT
	CPI	'F'+1
	JNC	INVEXT
	SUI	'A'-10	;CONVERT 'A'..'F'
	STA	EXTNO
	RET
NUM	SUI	'0'	;CONVERT '0'..'9'
	STA	EXTNO
	RET
INVEXT	LXI	D,IEMSG
	CALL	WRITESTRING
	JMP	EXIT
;
;
GETDISK		;PROMPT OPERATOR FOR DISK
	LXI	D,DSKMSG
	CALL	WRITESTRING
GET1	CALL	READCHAR
	CPI	0DH		;<CR> ?
	RZ
	CPI	03H		;<^C> ?
	JZ	BOOT
	JMP	GET1
;
;
READDIR	;READ DISK DIRECTORY INTO BUFFER
	MVI	C,DIRTRK	;SET TRACK NO
	CALL	SETTRK
	LXI	H,BUFFER	;INITIALIZE BUFFPT
	SHLD	BUFFPT
	XRA	A		;INITIALIZE SECTOR
	STA	SECTOR
READLP	CALL	NEXTSEC		;SET SECTOR NO
	LHLD	BUFFPT	;SET DMA ADDRESS
	MOV	B,H
	MOV	C,L
	CALL	SETDMA
	CALL	READ		;READ SECTOR
	LHLD	BUFFPT	;UPDATE DMA ADDRESS
	LXI	D,80H
	DAD	D
	SHLD	BUFFPT
	LDA	SECTOR	;UPDATE SECTOR
	INR	A
	STA	SECTOR
	CPI	NDIRSEC
	JNZ	READLP
	RET
;
;
WRITEDIR	;WRITE DISK DIRECTORY FROM BUFFER
	MVI	C,DIRTRK	;SET TRACK NO
	CALL	SETTRK
	LXI	H,BUFFER	;INITIALIZE BUFFPT
	SHLD	BUFFPT
	XRA	A		;INITIALIZE SECTOR
	STA	SECTOR
WRITELP	CALL	NEXTSEC		;SET SECTOR NO
	LHLD	BUFFPT	;SET DMA ADDRESS
	MOV	B,H
	MOV	C,L
	CALL	SETDMA
	CALL	WRITE		;WRITE SECTOR
	LHLD	BUFFPT	;UPDATE DMA ADDRESS
	LXI	D,80H
	DAD	D
	SHLD	BUFFPT
	LDA	SECTOR	;UPDATE SECTOR
	INR	A
	STA	SECTOR
	CPI	NDIRSEC
	JNZ	WRITELP
	RET
;
;
NEXTSEC	;SET SECTOR NO TO NEXT DIRECTORY SECTOR
	;MAPS SEQUENTIAL NO IN REG-A TO PHYSICAL
	;SECTOR ON DISK.
	LXI	H,SEGTABLE
	MVI	B,0
	MOV	C,A
	DAD	B
	MOV	C,M
	CALL	SETSEC
	RET
;
SEGTABLE
	DB	01H,07H,0DH,13H
	DB	19H,05H,0BH,11H
	DB	17H,03H,09H,0FH
	DB	15H,02H,08H,0EH
;
;
REST	;FIND AND RESTORE FILE
	;RETURNS CY:=FILE NOT FOUND
	MVI	D,NDIRENT
	LXI	H,BUFFER
RESTLP	MOV	A,M		;CHECK FOR ERASED FILE
	CPI	DELCHR
	PUSH	H
	PUSH	D
	CZ	COMPARE
	POP	D
	POP	H
	JZ	FOUND
	LXI	B,ENTLGTH	;STEP TO NEXT ENTRY
	DAD	B
	DCR	D
	JNZ	RESTLP
	LXI	D,NFMSG
	CALL	WRITESTRING
	STC			;SET CARRY
	RET
FOUND	MVI	M,VALCHAR
	ORA	A		;CLEAR CARRY
	RET
;
;
COMPARE	;COMPARE FILE NAMES AT M+1^ AND FNAME
	;RETURN Z:=MATCH
	INX	H
	LXI	D,FNAME
	MVI	B,FNLGTH
COMPLP	LDAX	D
	CMP	M
	JNZ	ENDCOMP
	INX	D
	INX	H
	DCR	B
	JNZ	COMPLP
	LDA	EXTNO		;GET EXTENT NO
	CMP	M		;CHECK AGAINST ENTRY
ENDCOMP	RET
;
;	I/O ROUTINES
;
WRITESTRING	;WRITE STRING TO CONSOLE
	MVI	C,9
	JMP	ENTRY
;
;
READCHAR	;READ CHAR FROM KEYBOARD
	MVI	C,1
	JMP	ENTRY
;
;
INITBDOS	;INITIALIZE BDOS, LOG IN DRIVE A
	MVI	C,13
	JMP	ENTRY
;
;
;	WARNING - THESE LOW LEVEL DISK I/O ROUTINES
;	ACCESS THE CP/M CBIOS DIRECTLY.  THEY MAY
;	NEED MODIFICATION WITH NON STANDARD SYSTEMS.
;
;
SETTRK	;SET TRACK (C-REG)
	LHLD	CBIOS
	MVI	L,1EH
	PCHL
;
;
SETSEC	;SET SECTOR (C-REG)
	LHLD	CBIOS
	MVI	L,21H
	PCHL
;
;
SETDMA	;SET TRANSFER ADDRESS (BC-REG)
	LHLD	CBIOS
	MVI	L,24H
	PCHL
;
;
READ	;READ A SECTOR
	LHLD	CBIOS
	MVI	L,27H
	PCHL
;
;
WRITE	;WRITE A SECTOR
	LHLD	CBIOS
	MVI	L,2AH
	PCHL
;
;
;	DATA AREA
;
DSKMSG	DB	'INSERT DISK, <CR> TO CONTINUE'
	DB	0AH,0DH,'$'
IEMSG	DB	'INVALID EXTENT - USE 1 HEX DIGIT'
	DB	0AH,0DH,'$'
TERMMSG	DB	'FUNCTION COMPLETE'
	DB	0DH,0AH,'$'
NFMSG	DB	'FILE NOT FOUND'
	DB	0DH,0AH,'$'
OLDSP	DS	2	;SYSTEM STACK POINTER
SECTOR	DS	1	;CURRENT SECTOR SEQUENCE NO
EXTNO	DS	1	;REQUIRED EXTENT NO
BUFFPT	DS	2	;BUFFER POINTER
	DS	20H	;STACK SPACE
STACK	EQU	$	;GROWS DOWN
BUFFER	EQU	$	;GROWS UP
;
	END
