;	Program to recover Erased file
;
;	From Interface Age December 1981 pg 98+
;
;	I didn't type in ALL the comments, so be sure to read the article
;	and the printed program listing in the magazine
;
;
;	Proper credit given to original author:
;
;		Gene Cotton
;
;	All I did was to type this in from the magazine
;	Hopefully without added any typing errors
;
;	HBR Version 1.0 as of 11/17/81
;
;	Henry B. Rothberg
;	4 Laticrete Park North
;	Bethany, Ct 06525
;
;	VERSION 1.1 AS OF 11/19/81
;
;	ADDED CONDITIONAL EQUATES FOR CP/M 1.4 AND 2.2
; 	AS WELL AS EQUATES FOR STANDARD CP/M AND MICROPOLIS
; 	CP/M (DIFFETHRENT SECTOR SKEW TABLES)
;
;	BRUCE E. BLAKESLEE
;	906 CRESTWOOD ROAD - WEST
;	WESTFIELD, N.J. 07090
;
;
FALSE	EQU	0	;BASIC DEFINITIONS
TRUE	EQU	NOT FALSE
;
CPM1  	EQU	FALSE
CPM2  	EQU	TRUE
;
STNDRD	EQU	FALSE
MICROP	EQU	TRUE
;
;
BOOT	EQU	0	;CP/M warm boot
BDOS	EQU	5
FCB	EQU	BOOT+5CH
;
	ORG	100H
	JMP	STACK
;
	IF	CPM1
BLN	DB	42	;CP/M 1.4
	ENDIF
;
	IF	CPM2
BLN	DB	48	;CP/M 2.2
	ENDIF
;                
HMSG	DB	13,10,'Unerase Version 1.1 (11/19/81) (CP/M Version $'
MSG22	DB	'2.2)',13,10,'$'
MSG14	DB	'1.4)',13,10,'$'
;
	ORG	200H	;Good place to start program
;
STACK	LXI	SP,STACK	;Set stack pointer
	CALL 	HELLO
	CALL	PCHECK
	CALL	TRYFIX
	CALL	BYE
	JMP	BOOT
;
;	Say who we are
;
HELLO	LXI	D,HMSG
	CALL	PRINT
	RET
;
;	Check for valid parimeters and say which cp/m version
;
PCHECK	CALL	FCBCHK
	CALL	CPMCHK
	RET
;
;	Look thru directory
;
TRYFIX	CALL	NXTSECT
	RZ
	CALL	CHKENT
	JMP	TRYFIX
;
;	Sign off & reset system
;
BYE	MVI	C,13
	CALL	BDOS
	LDA	FIXCNT
	ORA	A
	JZ	NOFIND
	LXI	D,BMSG
	CALL	PRINT
	RET
;
NOFIND	LXI	D,NFMSG
	CALL	PRINT
	RET
;
;	Make sure a legal filename is spec'd
;
FCBCHK	LDA	FCB
	ORA 	A
	JNZ	FCBCK1
	MVI	C,25
	CALL	BDOS
	INR	A
;
FCBCK1	DCR	A
	STA	FCB
	LDA	FCB+1
	CPI	' '
	RNC
;	
;	IF NO FILE NAME IS SPEC'D, ABORT WITH NOTICE
;
	LXI	D,NOFMSG
	CALL 	PRINT
	JMP	BOOT
;
;	CHECK FOR CP/M VERSION AND SET THINGS
;
CPMCHK	LXI	D,80H
	MVI	C,26
	CALL	BDOS
	MVI	C,12
	CALL 	BDOS
	CPI	20H
	MVI	A,42
	LXI	D,MSG14
	CNC	CPM22
	STA	BLN
	CALL	PRINT
	CALL	GETBIOS
;
;	SELECT DISK AND SETUP DISK PARAM HEADER
;
	LDA	FCB
	MOV	C,A
	MVI	B,0
	CALL	SELDSK
	MOV	A,H
	ORA	L
	JZ	ILDISK
	LDA	BLN
	CPI	48
	RC
	MOV	E,M
	INX	H
	MOV	D,M
	XCHG
	SHLD	DPH
	RET
;
;	IF CP/M 2.2 DETERMINE # OF DIRECTORY ENTRIES ALSO
;
CPM22	MVI	C,31
	CALL	BDOS
	LXI	D,7
	DAD	D
	MOV	E,M
	INX	H
	MOV	D,M
	XCHG
	INX	H
	CALL	SHFTHL2
	MOV	A,L
	STA	DIRMAX
	LXI	H,5
	DAD	D
	MOV	A,M
	STA	TRACK
	MVI	A,48
	LXI	D,MSG22
	RET
;
;	GET BIOS JUMPS VECTORS FOR EASY REFERENCE
;
GETBIOS	LHLD	BOOT+1
	LXI	D,WBOOT
	LDA	BLN
	MOV	B,A
	CALL	MOVE
	RET
;
;	READ NEXT SECTOR (GROUP OF FOUR DIRECTORY ENTRIES)
;	RETURNS WITH ZERO FLAG SET IF NO MORE
;
NXTSECT	LDA	DIRMAX
	ORA	A
	RZ
	LDA	TRACK
	MOV	C,A
	MVI	B,0
	CALL	SETTRK
	LDA	SECTOR
	MOV	C,A
	CALL	TRANSLT
	MVI	B,0
	CALL	SETSEC
	CALL	READ
	ANI	1
	XRI	1
	RET
;
;	CHECKS THE CURRENT 4 DIR ENTRIES
;
;
CHKENT	XRA	A
	STA	REWRT
	MVI	B,4
	LXI 	H,80H
CKLUP	MOV	A,M
	CPI	0E5H
	JNZ	CKINC
	PUSH 	H
	CALL	COMPAR
	POP	H
	JNZ	CKINC
	MVI	M,0
	MVI	A,0FH
	STA	REWRT
	LDA	FIXCNT
	INR	A
	STA	FIXCNT
CKINC	LXI	D,32
	DAD	D
	DCR	B
	JNZ	CKLUP
	LDA	REWRT
	ORA	A
	JZ	CKDONE
;
;	WRITE THE DIRECTORY SECTOR BACK TO THE DISK
;
	LDA	TRACK
	MOV	C,A
	MVI	B,0
	CALL	SETTRK
	LDA	SECTOR
	MOV	C,A
	CALL	TRANSLT
	MVI	B,0
	CALL 	SETSEC
	CALL	WRITE
	ORA	A
	JNZ	ERRWRT
CKDONE	LDA	DIRMAX
	DCR	A
	STA	DIRMAX
	LDA	SECTOR
	INR	A
	STA	SECTOR
	RET
;
;	 COMPARE 11 BYTES OF DIRECTORY ENTRY AGAINST ARGUMENT
;
COMPAR	INX	H
	LXI	D,FCB+1
	XCHG
	MVI	C,11
CMPR1	LDAX	D
	ANI	7FH
	CMP	M
	RNZ
	INX	D
	INX	H
	DCR	C
	JNZ	CMPR1
	RET
;
;	GENERAL PURPOSE MOVE ROUTINE
;
MOVE	MOV	A,M
	STAX	D
	INX	D
	INX	H
	DCR	B
	JNZ	MOVE
	RET
;
;	SHIFT REGS HL RIGHT 2 BITS
;
SHFTHL2	CALL	SHFTHL
SHFTHL	XRA	A
	MOV	A,H
	RAR
	MOV	H,A
	MOV	A,L
	RAR
	MOV	L,A
	RET
;
;	GENERAL PURPOSE PRINT ROUTINE
;
PRINT	MVI	C,9
	JMP	BDOS
;
;	SPEC'D ILLEGAL DISK, SO ABORT
;
ILDISK	LXI	D,ILMSG
	CALL	PRINT
	JMP	BOOT
;
;	ERROR DURING DISK WRITE
;
ERRWRT	LXI 	D,WMSG
	CALL	PRINT
	JMP	BOOT
;
;	TRANSLATE REG C FROM LOGICAL TO PHYSICAL SECTOR #
;
TRANSLT	LHLD	DPH
	XCHG
	CALL	SECTRAN
	MOV	C,L
	RET
;
;	THIS IS WORKING COPY OF BIOS TABLE
;
;
;
WBOOT	DS	3
CONST	DS	3
CONIN	DS	3
CONOUT	DS	3
LIST	DS	3
PUNCH	DS	3
READER	DS	3
HOME	DS	3
SELDSK	DS	3
SETTRK	DS	3
SETSEC	DS	3
SETDMA	DS  	3
READ	DS	3
WRITE	DS	3
LISTST	DS	3
SECTRAN	JMP	STRAN
;
;
;
;
;	RETURNS PHYSICAL SECTOR #
;
STRAN	MVI	B,0
	XCHG
	DAD	B
	MOV	L,M
	RET
;
;	ADDRESS OF TRANSLATE TABLE
;
DPH	DW	XLT0
	DS	14
;
;	THIS IS STANDARD TRANSLATE TABLE
;
	IF	STNDRD
XLT0	DB	1,7,13,19,25,5,11,17,23,3,9,15,21
	DB	2,8,14,20,26,6,12,18,24,4,10,16,22
	ENDIF
;
;  		SECTOR TRANSLATE TABLE FOR MICROPOLIS
;		MOD II
;
	IF	MICROP
XLT0	DB	1,2,11,12,21,22,31,32
	DB	9,10,19,20,29,30,7,8
	DB	17,18,27,28,5,6,15,16
	DB	25,26,3,4,13,14,23,24
	ENDIF
;
;	WORKING STORAGE FOLLOWS
;
DIRMAX	DB	16
;
TRACK	DB	2
;
SECTOR	DB	0
;
FIXCNT	DB	0
;
REWRT	DB	0
;
WMSG	DB	10,13,'Error occured during disk Write - ABORT$'
;
ILMSG	DB	10,13,'Specified an illegal disk drive - ABORT$'
;
BMSG	DB	10,13,'Recovered - Please DOUBLE CHECK before using$'
;
NOFMSG	DB	10,13,'No File Name specified - ABORT$'
;
NFMSG	DB	10,13,'File NOT found$'
;
	END	100H
