home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
CP/M
/
CPM_CDROM.iso
/
beehive
/
utilitys
/
unera3.arc
/
U3.ASM
next >
Wrap
Assembly Source File
|
1991-08-11
|
9KB
|
370 lines
; U3 - UTILITY FOR RECOVERING ERASED FILES FOR CP/M PLUS
; This program is based on UNERASE.COM in the public domain.
; It has been modified to work with CP/M 3.0 and later.
; It currently works with sector sizes of 128, 256 and 512 bytes.
; It is placed in the public domain by Advanced Logic Systems for public
; use. Advanced Logic Systems makes no warrantee on the operation or use
; of this program or its applicabilty for any given application.
; HISTORY
;12/29/83 FIRST PASS AT DISASSEMBLY OF UNERASE.COM AND MODIFICATIONS
; TO MAKE IT COMPATIBLE WITH CP/M PLUS
; I ALSO DIS A SELECT DISK IN DSKPRM SO THAT IF YOU TRY TO
; RECOVER A FILE FROM A DISK THAT IS A DIFFERENT FORMAT FROM
; THE ONE THAT YOU ARE CURRENTLY LOGGED ON TO, ITS GETS THE
; RIGHT DPH. AT THE SAME TIME I CHANGED THE SIZE OF THE AREA
; WHERE THE NUMBER OF RESERVED SYSTEM TRACKS IS KEPT. THIS
; ALLOWS THE NUMBER OF RESERVED TRACKS TO BE GREATER THAN 256.
; - GALE WOLFENBARGER
; ADDRESSES
BDOS: EQU 05H ;BDOS VECTOR ADDRESS
WRMBOOT:EQU 00H ;WARM BOOT VECTOR ADDRESS
DEFFCB: EQU 5CH ;ADDRESS OF THE DEFAULT FCB
DEFFCB2:EQU 6DH ;ADDRESS OF THE SECOND DEFAULT FCB
; BDOS FUNCTIONS
DIRCALL:EQU 32H ;CPM 3.0 DIRECT BIOS CALL
DRESET: EQU 0DH ;RESET DISK SYSTEM
GETCUR: EQU 19H ;GET CURRENTLY LOGGED IN DISK
CONIN: EQU 01H ;GET A CHARACTER FROM THE CONSOLE
CONOUT: EQU 02H ;PRINT A CHARACTER TO THE CONSOLE
SETDMA: EQU 1AH ;SET DMA FUNCTION
GETVER: EQU 0CH ;GET CPM VERSION #
GETPARM:EQU 1FH ;GET ADDRESS OF DISK PARAMETERS
PRINT: EQU 09H ;PRINT STRING TO CONSOLE
; ASCII CHARACTERS
CR: EQU 0DH ;CARRIAGE RETURN
LF: EQU 0AH ;LINE FEED
; I USED MACROS FROM Z80.LIB TO IMPLEMENT SOME Z80 COMMANDS
; BECAUSE MAC.COM AND Z80.LIB COME WITH CP/M PLUS.
; IF YOU ARE USING ASM.COM OR NOT USING A Z80 PROCESSOR
; YOU WILL HAVE TO USE EQUATES OR INSERT INLINE CODE FOR THE
; Z80 MACROS - gw
MACLIB Z80
ORG 100H
JMP START
DB 'U3 ver 1.0'
DB 'UNERASE FOR CPM 3.0'
DB '12/29/83 - gw'
ORG 200H
START:
LXI SP,START
CALL SETUP
CALL RDDIR
CALL FINISH
JMP WRMBOOT
SETUP:
CALL CKNAME ;CHECK FOR VALID FILE NAME
CALL SETBIOS ;COPY BIOS JUMP VECTOR
RET
RDDIR:
CALL GETDIR ;READ A DIRECTORY SECTOR
RZ ;END OR READ ERROR
CALL CKENT ;CHECK ENTRIES FOR FILE TO RECOVER
JMP RDDIR
FINISH:
MVI C,DRESET ;RESET DISK SYSTEM
CALL BDOS
LDA NOREC ;GET NUMBER RECOVERED
ORA A
JZ NOTFND ;NO RECOVERIES
LXI D,RECMSG
CALL PRTMSG ;PRINT NUMBER OF FILES RECOVERED
RET
NOTFND:
LXI D,FILERR
CALL PRTMSG
RET
CKNAME:
LDA DEFFCB ;GET DRIVE FOR FILE
ORA A ;USE DEFAULT?
JNZ NODEF ;NO CONVERT TO FCB FORMAT
MVI C,GETCUR ;GET CURRENT DISK
CALL BDOS
INR A ;SET UP FOR DECREMENT
NODEF:
DCR A ;CONVERT TO FCB FORMAT
STA DEFFCB ;SAVE IT
LDA DEFFCB+1 ;CHECK FOR NO FILE
CPI ' '
RNC ;RETURN IF OK
LXI D,NAMERR ;PRINT FILE ERROR
CALL PRTMSG
JMP WRMBOOT ;GIVE UP
SETBIOS: ;SET UP LOCAL BIOS JUMP VECTOR
LXI B,LOCDMA ;GET DEFAULT DMA ADDRESS
SBCD BCREG
MVI A,12 ;SET DMA TO DEFAULT
STA FUNC
CALL CALLBIOS
MVI C,GETVER ;GET CPM VERSION #
CALL BDOS
CPI 30H ;IS IT 3.0 OR GREATER
JC ONLY30 ;THIS VERSION FOR CPM 3.0 AND LATER
CALL DSKPRM ;GET DISK PARAMETERS FROM BDOS
LDA DEFFCB ;SELECT DRIVE
MOV C,A
MVI B,0
MOV E,B
SBCD BCREG ;BIOS SELDSK FUNCTION
SDED DEREG
MVI A,9 ;SELDSK
STA FUNC
CALL CALLBIOS
MOV A,H
ORA L ;CHECK FOR DRIVE ERROR
JZ NODRV ;GO REPORT IT
MOV E,M ;GET DPH ADDRESS
INX H
MOV D,M
XCHG
SHLD DPHADD ;SAVE ADDRESS TO DPH
RET
DSKPRM:
LDA DEFFCB
MOV E,A
MVI C,14 ;SELECT DISK
CALL BDOS
MVI C,GETPARM ;GET ADDRESS OF DISK PARMS
CALL BDOS
LXI D,7 ;OFFSET TO DRM (# OF DIRECTORY ENTRIES)
DAD D ;ADD OFFSET
MOV E,M ;GET DRM
INX H
MOV D,M
PUSH D
PUSH H
LXI D,7 ;POINT TO PSH
DAD D
MOV A,M ;GET IT
STA PSH ;SAVE IT
POP H
POP D
XCHG
INX H ;ADD 1 FOR TOTAL DIRECTORY ENTRIES
LDA PSH
CPI 2 ;512 BYTE SECTORS
CZ DIV16
LDA PSH
CPI 1 ;256 BYTE SECTORS
CZ DIV8
LDA PSH
ORA A ;128 BYTE SECTORS
CZ DIV4
MOV A,L ;SAVE # OF DIRECTORY ENTRIES MAX 1024
STA DIRENT
LXI H,5 ;ADD OFFSET TO NUMBER OF RESERVED TRACKS
DAD D
MOV E,M ;GET NUMBER OF RESERVED TRACKS
INX H
MOV D,M
SDED RESTKS ;SAVE RESERVED TRACKS FOR LATER
RET
ONLY30:
LXI D,ERR30 ;PRINT MESSAGE FOR CPM PLUS ONLY
CALL PRTMSG
JMP WRMBOOT
GETDIR:
LDA DIRENT ;GET # OF DIRECTORY ENTRIES
ORA A
RZ ;RETURN IF NONE
LBCD RESTKS ;GET NUMBER OF RESERVED TRACKS
SBCD BCREG ;SET TRACK TO DIRECTORY
MVI A,10 ;SETTRK
STA FUNC
CALL CALLBIOS
LDA SECTOR ;GET CURRENT SECTOR
MOV C,A
CALL TRNSEC ;TRANSLATE SECTOR IF NECESSARY
MVI B,0
SBCD BCREG ;POINT TO CURRENT SECTOR
MVI A,11 ;SETSEC
STA FUNC
CALL CALLBIOS
MVI A,13 ;READ SECTOR OF DIRECTORY
STA FUNC
CALL CALLBIOS
ANI 1
XRI 1
RET
CKENT:
XRA A ;ZERO RECOVER FLAG
STA RECFLG
LDA DVD ;GET NUMBER OF DIRECTORY ENTRIES PER SECTOR
MOV B,A
LXI H,LOCDMA
CKNXT:
MOV A,M ;GET BYTE
CPI 0E5H ;CHECK FOR DELETED
JNZ GETNXT ;NOPE SKIP
PUSH H
CALL CKDEL ;YES CHECK FOR RECOVERY
POP H
RECENT:
JNZ GETNXT
MVI M,0 ;RECOVER THE ENTRY
MVI A,0FH ;SET RECOVERED FLAG
STA RECFLG
LDA NOREC ;INCREMENT NUMBER OF RECORDS RECOVERED
INR A
STA NOREC
GETNXT:
LXI D,32 ;ADVANCE TO NEXT ENTRY
DAD D
DCR B ;DECREMENT COUNTER
JNZ CKNXT
LDA RECFLG ;CHECK FOR RECOVERED ENTRY
ORA A
JZ LOOP ;NOPE CONTINUE LOOP
LBCD RESTKS ;GET # RESERVED TRACKS
SBCD BCREG ;POINT TO DIRECTORY
MVI A,10 ;SETTRK
STA FUNC
CALL CALLBIOS
LDA SECTOR ;GET CURRENT SECTOR
MOV C,A
CALL TRNSEC ;TRANSLATE SECTOR
MVI B,0
SBCD BCREG ;POINT TO CURRENT SECTOR
MVI A,11 ;SETSEC
STA FUNC
CALL CALLBIOS
LXI B,1 ;NONE DEFERRED WRITE
SBCD BCREG
MVI A,14 ;WRITE
STA FUNC
CALL CALLBIOS ;UPDATE DIRECTORY
ORA A ;CHECK FOR WRITE ERROR
JNZ WRTERROR ;REPORT ERROR
LOOP:
LDA DIRENT ;DECREMENT DIRECTORY ENTRIES
DCR A
STA DIRENT
LDA SECTOR ;INCREMENT SECTOR
INR A
STA SECTOR
RET
CKDEL:
INX H ;CHECK DELETED ENTRY FOR RECOVERY
LXI D,DEFFCB+1 ;POINT AT FILE TO BE RECOVERED
XCHG
MVI C,11 ;LOOK AT 11 CHARACTERS
CMPDEL:
LDAX D ;GET CHARACTER IN NAME
ANI 7FH ;TURN OFF HIGH BIT
CMP M ;ARE THEY EQUAL?
RNZ ;NOPE GO GET ANOTHER ENTRY
INX D ;YES, CONTINUE
INX H
DCR C
JNZ CMPDEL
RET
DIV16: ;DIVIDE HL BY 16
MVI A,16 ;SET NUMBER OF DIRECTORY ENTRIES PER SECTOR
STA DVD
CALL DIV2 ;/2
CALL DIV2 ;/4
CALL DIV2 ;/8
CALL DIV2 ;/16
RET
DIV8: ;DIVIDE HL BY 8
MVI A,8 ;SET NUMBER OF DIRECTORY ENTRIES PER SECTOR
STA DVD
CALL DIV2 ;/2
CALL DIV2 ;/4
CALL DIV2 ;/8
RET
DIV4: ;DIVIDE HL BY 4
MVI A,4 ;SET NUMBER OF DIRECTORY ENTRIES PER SECTOR
STA DVD
CALL DIV2 ;CALL DIVIDE BY 2 THEN FALL INTO IT FOR 4
DIV2: ;DIVIDE BY 2 ROUTINE
XRA A ;CLEAR CARRY
MOV A,H ;GET HIGH ORDER BYTE
RAR ;SHIFT RIGHT FOR A DIVIDE BY 2
MOV H,A
MOV A,L ;GET LOW ORDER BYTE
RAR ;SHIFT RIGHT FOR A DIVIDE BY 2
MOV L,A
RET
PRTMSG:
MVI C,PRINT ;PRINT STRING TO CONSOLE
JMP BDOS
NODRV: ;PRINT DRIVE ERROR MESSAGE
LXI D,DRVERR
CALL PRTMSG
JMP WRMBOOT
WRTERROR: ;PRINT WRITE ERROR MESSAGE
LXI D,WRTERR
CALL PRTMSG
JMP WRMBOOT
TRNSEC:
LHLD DPHADD ;GET TRANSLATE TABLE ADDRESS
XCHG
SBCD BCREG
SDED DEREG
MVI A,16 ;SECTRAN
STA FUNC
CALL CALLBIOS
MOV C,L
RET
CALLBIOS: ;CPM 3.0 DIRECT BIOS CALL
MVI C,DIRCALL
LXI D,FUN50
CALL BDOS
RET
FUN50:
FUNC: DS 1
AREG: DS 1
BCREG: DS 2
DEREG: DS 2
HLREG: DS 2
DPHADD:
DS 2
DIRENT: DS 1
RESTKS: DS 2
SECTOR: DB 0
NOREC: DB 0
RECFLG: DB 0
PSH: DS 1
DVD: DB 0
WRTERR:
DB CR,LF,'Error occured during disk Write - ABORT$'
DRVERR:
DB CR,LF,'Specified an illegal disk drive - ABORT$'
RECMSG:
DB 'File recovered.$'
NAMERR:
DB CR,LF
DB 'No File Name specified - ABORT$'
FILERR:
DB CR,LF,'File NOT found$'
ERR30:
DB CR,LF
DB 'THIS VERSION OF UNERASE ONLY WORKS',CR,LF
DB 'FOR CPM 3.0 OR LATER',CR,LF
DB 'U2.COM FOR EARLIER RELEASES OF CP/M',CR,LF
DB 'IS AVAILABLE FROM Advanced Logic Systems',CR,LF
DB 'AT NO CHARGE. SOURCE FOR THIS PROGRAM AND U2',CR,LF
DB 'ARE ALSO AVAILABLE. FOR MORE INFORMATION CALL',CR,LF
DB '800-538-8177 OR 408-730-0306 (IN CALIFORNIA).',CR,LF,'$'
LOCDMA:
DS 512 ;LOCAL DMA BUFFER
END
ATION CALL',CR,LF
DB '800-538-8177 OR 408-730-0306 (IN CALIFORNIA).',CR,LF,'$'
LOCDMA:
DS 512 ;LOCAL DMA BUFFE