home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.barnyard.co.uk
/
2015.02.ftp.barnyard.co.uk.tar
/
ftp.barnyard.co.uk
/
cpm
/
walnut-creek-CDROM
/
ENTERPRS
/
CPM
/
UTILS
/
S
/
UNERA31.ARC
/
UNERA31.A86
next >
Wrap
Text File
|
1991-10-05
|
19KB
|
765 lines
; DATE 02/16/84 16:16 last update
; 02/16/84 the program has been converted to support both CP/M-86 ver 3.1
; and CCP/M-86 ver 3.1.
; MP/M is not supported but only because I don't have a way to test this
; version on the MPM operating system.
TITLE 'UNERA FOR CP/M-86 VER3.1'
; UNERA31.A86
; by: H.H. Van Tassell, 120 Hill Hollow Rd, Watchung NJ 07060 (201)755-5272
;
; This is a program to recover erased files in CP/M-86 and is modelled on the
; UNERA program for CP/M-80 on SIG/M volume 76. See volumes 76 and 44 for
; author credits and more information.
;
; The program reads the directory, sector by sector, listing filenames that
; have been erase by placing an 0E5H as byte 0. The extent number is also
; listed. NO check is made to determine if the disk space has been re-allocated
; to another file after the file was erased. After listing the file names, the
; user is asked if recovery is desired. A page of help is displayed if the
; program is invoked with // as the file name.
; The direct BIOS disk call data structure was choosen for conversion to
; CP/M-86 versions 3.0 and higher (CONCURRENT and PLUS).
;
; TO GENERATE PROGRAM:
; RASM86 UNERA $SZPZ
; LINK86 UNERA [data[add [100]]]
;
;
SLINES EQU 22 ;LINES ON CONSOLE LESS 2
FALSE EQU 0
TRUE EQU NOT FALSE
CR EQU 13
LF EQU 10
TAB EQU 9
CONIN EQU 1 ;READ CONSOLE
DCONIN EQU 6 ;DIRECT CONSOLE READ
RESET EQU 13 ;SYSTEM RESET
SELDSK EQU 14 ;SELECT DISK
GETDR EQU 25 ;GET DRIVE
DIRBIOS EQU 50 ;DIRECT BIOS CALLS
; DIRECT BIOS CALL PARAMETER BLOCK DATA STRUCTURE
;
BPB_FUNC EQU BYTE PTR 0[BX]
BPB_CX EQU WORD PTR 1[BX]
BPB_DX EQU WORD PTR 3[BX]
; DISK BIOS CALLS DATA STRUCTURE
;
SELECT_DISK EQU WORD PTR 0[BX]
SET_TRACK EQU WORD PTR 2[BX]
SET_DMASEG EQU WORD PTR 4[BX]
SET_DMAOFF EQU WORD PTR 6[BX]
SET_SECTOR EQU WORD PTR 8[BX]
READ_SECTOR EQU WORD PTR 10[BX]
WRITE_SECTOR EQU WORD PTR 12[BX]
SECTOR_XLAT EQU WORD PTR 14[BX]
TBUF EQU 80H ;TRANSIT DEFAULT BUFFER
FCB EQU 5CH ;DEFAULT FILE CONTROL BLOCK
DRV_DPB equ 31 ;BDOS call 31
BIO_SELDSK equ 9 ;BIOS function number
BIO_READ equ 10 ;BIOS function number
BIO_WRITE equ 11 ;BIOS function number
; PARTIAL DATA STRUCTURE OF DPH
;
LOG_SEQN equ byte ptr 6 ;to force reset of permanent media
DPB_PTR31 equ word ptr 8 ;offset of DPB pointer in DPH (v3.1)
DPB_PTR11 equ word ptr 10 ;offset in version 1.1
DPB_SIZE equ 17 ;size of Disk Parameter Block
; DPB DATA STRUCTURE
;
SPT equ word ptr 0[bx]
BSH equ byte ptr 2[bx]
BLM equ byte ptr 3[bx]
EXM equ byte ptr 4[bx]
DSM equ word ptr 5[bx]
DRM equ word ptr 7[bx]
AL0 equ byte ptr 9[bx]
AL1 equ byte ptr 10[bx]
CKS equ word ptr 11[bx]
OFF equ word ptr 13[bx]
PHYSHF equ byte ptr 15[bx]
PHYMSK equ byte ptr 16[bx]
BIOS_PTR equ dword ptr .28h ;loc of BIOS entry in SYSDAT
UDA_SEG equ word ptr .4eh ;loc of UDA seg in system data area
;------- for CCP/M -3.1 ----------------
S_SYSDAT equ 154 ;get system data area
P_PDADR equ 156 ;get PDA address
CCPM_31 equ 1431h ;CCP/M-86 version number
P_UDA equ word ptr 10h ;User Data Area
;-----------------------------------------
CSEG
MOV CX,DS ;USING DATA SEGMENT
MOV SS,CX ;SET UP LOCAL STACK
LEA SP,STACK
CALL HELLO
CALL PCHECK
CALL TRYFIX
CMP FIXCNT,0 ;WERE ANY FIXABLE FILES FOUND?
JZ NO_RECOVER
CALL RECOVER ;YES, GO RECOVER EM
NO_RECOVER:
CALL BYE
EXIT:
MOV CL,SELDSK ;RETURN TO CURRENT DISK
MOV DL,BYTE PTR CURDR
INT 224
MOV CL,RESET ;RESET SYSTEM
INT 224
QUIT:
MOV CL,0
MOV DL,0
INT 224
; SAY WHO WE ARE
HELLO:
MOV DX,OFFSET HMSG ;POINT TO HELLO MESSAGE
CALL PRINT
RET
; CHECK FOR VALID PARAMETERS
PCHECK:
CALL FCBCHK ;MAKE SURE FILE IS SPECIFIED
CALL CPMCHK ;CHECK CP/M VERSION
RET
; ASK IF THEY WANT TO RECOVER THE REVIEWED FILES
RECOVER:
MOV DX,OFFSET RVMSG ;ASK IF RECOVERY WANTED
CALL PRINT
MOV CL,CONIN ;GET ANSWER
INT 224
AND AL,5FH ;MAKE UPPER CASE
CMP AL,'Y'
JNE EXIT ;EXIT UNLESS YES
MOV VIEW_EM,0 ;RESET THE VIEW FLAG
MOV FIX_EM,0FFH ;SET THE FIX EM FLAG
MOV AL,BYTE PTR MAXSEC ;RESTORE MAXDIR
MOV BYTE PTR MAXDIR,AL
MOV SECTOR,0 ;SECTOR
MOV FIXCNT,0 ;AND FIXCOUNT
CALL TRYFIX ;AND FIXEM
RET
; LOOK THROUGH THE DIRECTORY TRYING TO MATCH FCB FILENAME
TRYFIX:
CALL NXTSECT ;GET A DIRECTORY SECTOR
JNZ TRY_MORE ;RETURNS ZERO SET IF NO MORE
RET
TRY_MORE:
CALL CHKENT ;CHECK IT OUT AND MAYBE FIX
JMPS TRYFIX ;KEEP IT UP TILL DONE
; SIGN OFF
BYE:
CMP FIXCNT,0 ;CHECK FOR ACTIVITY
JE NOFIND
MOV DX,OFFSET BMSG ;WARN EM
CALL PRINT
RET
NOFIND:
MOV DX,OFFSET NFMSG ;SAY NOTHING FOUND
CALL PRINT
RET
; MAKE SURE A LEGAL FILENAME WAS FOUND
FCBCHK:
; scans tbuffer at 80h for a / as indication of help wanted
; returns with ZF set if '/' is found in buffer
;
push es ! push ds ! pop es ;save ES, ES=DS
xor cx,cx
mov di,80h ;point to tbuffer @ 80h
mov cl,byte ptr[di] ;CX=length of tbuf string
inc cx
mov al,'/'
repnz scasb ;scan for /
pop es ;ZF set if help signal
jz help
CMP BYTE PTR .FCB+1,' ' ;IS 1ST BYTE A NON BLANK
JBE NO_NAME
MOV CL,GETDR ;GET CURRENT DRIVE
INT 224
MOV BYTE PTR CURDR,AL ;SAVE IT
MOV AL,BYTE PTR .FCB ;SEE IF DEFAULT DRIVE SPEC
CMP AL,0
JZ DEFAULT ;YES, NO DEC
DEC AL ;ELSE DEC IT
PUSH AX
MOV CL,SELDSK ;SELECT DISK
MOV DL,AL
INT 224
POP AX
JMPS NOT_DEFAULT
DEFAULT:
MOV AL,CURDR
NOT_DEFAULT:
MOV BYTE PTR .FCB,AL ;PUT IT BACK AND
MOV DRIVE,AL
ADD AL,'A' ;MAKE IT ASCII
MOV BYTE PTR FILNAM0,AL ;AND PUT IT IN FILNAM DATA
RET
NO_NAME:
MOV DX,OFFSET NOFMSG ;CANT FIND A FILE NAME
CALL PRINT
JMP QUIT
; GIVE EM SOME HELP AND QUIT
HELP:
MOV DX,OFFSET HLPMSG
CALL PRINT
JMP QUIT
IS_MPM:
MOV DX,OFFSET MPMSG
CALL PRINT
JMP EXIT
UNK_VER:
MOV DX,OFFSET WVMSG
CALL PRINT
JMP EXIT
; CHECKS CPM VERSION AND INITIALIZES THINGS
CPMCHK:
MOV CL,12 ;GET VERSION NUMBER
INT 224
MOV CPM_VERSION,AX ;SAVE IT
TEST AH,01H ;IS IT MP/M ?
JNZ IS_MPM
CMP AL,22H ;IS IT VERSION 11
JE VER_11
CMP AL,31H ;IS IT VERSION 31
JE VER_31
JMP UNK_VER ;UNKNOWN VERSION
VER_11:
MOV CALL_TBL,OFFSET TABLE11
JMPS VER_OK
VER_31:
MOV CALL_TBL,OFFSET TABLE31
VER_OK:
MOV CL,BYTE PTR .FCB ;GET DRIVE
XOR CH,CH
XOR DX,DX ;FIRST SELECTION
MOV BX,CALL_TBL
CALL SELECT_DISK ;SELECT DISK
CMP BX,0 ;IS DISK OK
JNZ DISKOK ;TELL IF NOT OK
CALL ILDISK
DISKOK: ;A CALL TO DISK SELECT COPYS
CMP BYTE PTR CPM_VERSION,31H ! JE SETUP31
SETUP11:
MOV AX,ES:WORD PTR [BX] ;XLAT TABLE ADDRESS IN BX
MOV XLAT_ADR,AX
MOV CL,31 ;GET DISK PARAMETERS
INT 224
MOV AX,ES:WORD PTR 13[BX] ;GET DIRECTORY TRACK
MOV DX,ES:WORD PTR 7[BX] ;DX=DRM
MOV CL,2 ;SHIFT RIGHT TWICE
JMPS COM_SETUP
SETUP31:
MOV BX,OFFSET DPB ;THE DPB TO LOCAL STORAGE
MOV AX,SPT
MOV SEC_PER_TRK,AX
MOV AL,4
MOV CL,PHYSHF ;GET PHYSICAL SHIFT
CMP CL,0 ! JZ SSSD ;PHYSHF IS ZERO FOR SSSD
SHL AL,CL ;SHIFT LEFT ? TIMES GIVES
SSSD:
MOV DIR_PER_SEC,AL ;NUMBER DIR ENTRYS/SECTOR
MOV AX,OFF ;GET DIRECTORY TRACK
MOV DX,DRM ;GET NUMBER OF DIR ENTRYS-1
MOV CL,PHYSHF
ADD CL,2
COM_SETUP:
INC DX ;ACCOUNT FOR -1
SHR DX,CL ;SHIFT RIGHT ? TIMES = SECTORS
MOV MAXDIR,DX ;SAVE NUMBER OF DIR SECTORS
MOV MAXSEC,DX
MOV TRACK,AX ;SAVE DIRECTORY TRACK
MOV SECTOR,0 ;ZERO SECTOR COUNT
MOV FIXCNT,0
MOV CX,DS
MOV DMASEG,CX
MOV BX,CALL_TBL
CALL SET_DMASEG ;SET DMA SEGMENT TO DATA SEG
MOV CX,DMAOFF
MOV BX,CALL_TBL
CALL SET_DMAOFF ;SET DMA TO DIR_BUF
RET
; READS NEXT SECTOR (GROUP OF DIRECTORY ENTRIES)
; RETURN WITH ZERO SET IF NO MORE
NXTSECT:
CMP MAXDIR,0
JNZ DO_SECT
RET ;RET WITH ZERO SET
DO_SECT:
MOV CX,TRACK ;SET TRACK
MOV BX,CALL_TBL
CALL SET_TRACK
MOV CX,SECTOR
MOV BX,CALL_TBL
CALL SECTOR_XLAT ;RETURNS XLATED SECT IN BX
MOV CX,BX
MOV BX,CALL_TBL
CALL SET_SECTOR
MOV BX,CALL_TBL
CALL READ_SECTOR
AND AL,1 ;REVERSE SENSE OF ERROR FLAG
XOR AL,1 ;RETURN WITH ZERO SET IF BAD READ
RET
; CHECK THE CURRENT GROUP DIRECTORY ENTRIES AGAINST ARGUMENT
; IF MATCH, REWRITE SECTOR WITH REACTIVATED FIRST BYTE
CHKENT:
MOV REWRT,0 ;ASSUME NO REWRITE
MOV CL,DIR_PER_SEC ;# ENTRIES TO CHECK
MOV BX,OFFSET DIR_BUF ;THIS IS WHERE THEY ARE AT...
CKLOOP:
CMP BYTE PTR [BX],0E5H ;IS IT UNUSED?
JNE CKINC ;NO, GO DO ANOTHER
CMP BYTE PTR 1[BX],0E5H ;IF THIS IS AN E5 THEN ITS
JE CKINC ;...NOT A DIR NAME
CMP BYTE PTR 1[BX],00H ;IF THIS IS AN 00 THEN ITS
JE CKINC ;...NOT A DIR NAME
PUSH BX
CALL COMPAR ;COMPARE WITH ARGUMENT
POP BX
JNZ CKINC ;JMP IF ZERO NOT SET, NO MATCH
CMP FIX_EM,0FFH ;SHOULD WE FIX EM?
JNE NO_FIX
MOV BYTE PTR [BX],0 ;ELSE, REACTIVATE IT
MOV REWRT,0FFH ;SET REWRITE FLAG
NO_FIX:
INC FIXCNT ;BUMP FIX COUNTER
CMP VIEW_EM,0FFH ;IS THE VIEW FLAG SET?
JNE CKINC ;NO,JMP OVER THE SHOW-OFF
PUSH BX
CALL SHOWIT ;ELSE, TELL EM HOW GOOD YOU ARE
POP BX
CKINC: ;DO ANOTHER ENTRY
ADD BX,32
DEC CL ;ONE LESS TO DO
JNZ CKLOOP ;GO DO IT
CMP REWRT,0 ;NEED REWRITE
JZ CKDONE ;NO, THEN DONE WITH CHECK
; WRITE DIRECTORY ENTRY BACK TO THE DISK
MOV CX,TRACK ;SET TRACK
MOV BX,CALL_TBL
CALL SET_TRACK
MOV CX,SECTOR
MOV BX,CALL_TBL
CALL SECTOR_XLAT ;RETURNS XLATED SECT IN BX
MOV CX,BX
MOV BX,CALL_TBL
CALL SET_SECTOR
MOV BX,CALL_TBL
CALL WRITE_SECTOR
CMP AL,0
JZ CKDONE
JMP ERRWRT ;WOOPS
CKDONE:
DEC MAXDIR ;REDUCE SECTORS LEFT
INC SECTOR ;BUMP TO NEXT SECTOR
RET
; COMPARE 11 BYTES OF DIRECTORY ENTRY AGAINST ARGUMENT
; RETURN WITH ZERO FLAG SET IF MATCH IS MADE
COMPAR:
MOV CL,11 ;COMP 11 CHARS.
INC BX ;BX POINTS TO DIR ENTRY
MOV SI,FCB+1 ;SI POINT TO FCB ARGUMENT
CPLOOP:
MOV AL,[BX] ;GET DIR CHAR
AND AL,7FH ;STRIP PARITY
CMP [SI],AL ;ARE FCB & DIR ENTRY THE SAME?
JE DO_MORE
CMP BYTE PTR[SI],'?' ;IF FCB IS A ?, ANY THING GOES
JE DO_MORE
RET ;RETURN ZERO NOT SET IF NOT SAME
DO_MORE:
INC BX
INC SI
DEC CL
JNZ CPLOOP ;LOOP FOR 11 CHARS.
RET ;RET WITH ZERO SET IF SAME
; MOVE FILE NAME TO DATA AREA AND SHOW IT ON CONSOLE
; ENTRY BX POINTS TO NAME-1 IN DIR_BUF
SHOWIT:
PUSH DS ;MAKE SURE ES IS CORRECT
POP ES
MOV SI,BX ;POINT TO FILE NAME
INC SI ;NOW ITS CORRECT
MOV DI,OFFSET FILNAM1 ;PUT IT THERE
MOV CX,8 ;FIRST MOVE NAME
CALL MOVEIT ;USE ROUTINE TO STRIP HI BIT
INC DI ;JUMP OVER DOT
MOV CX,3 ;MOVE TYPE
CALL MOVEIT
MOV AL,[SI] ;GET EXTENT
ADD AL,'0' ;MAKE IT ASCII
MOV BYTE PTR FILNAM2,AL ;PUT IN AWAY
MOV DX,OFFSET FILNAM ;GET READY TO PRINT
CMP FIXCNT,1 ;IS IT THE FIRST RECOVERY?
JNE NOT_FIRST
MOV DX,OFFSET RCMSG ;GIVE PRAMBLE
NOT_FIRST:
CALL PRINT
INC LINES ;BUMP LINE COUNT
CMP LINES,SLINES
JB NO_WAIT
CALL WAIT
NO_WAIT:
RET
; MOVE CX BYTES FROM DS:SI TO ES:DI AND STRIP HI BIT
MOVEIT: MOV AL,[SI]
AND AL,7FH
MOV ES:[DI],AL
INC DI ! INC SI
LOOP MOVEIT
RET
; PRINT MESSAGE POINTED TO BY DX, terminated with either a 0
PRINT: MOV BX,DX
PRN_LP: MOV DL,[BX]
CMP DL,0 ! JE PRN_RET
INC BX
MOV CL,2
PUSH BX
INT 224
POP BX
JMPS PRN_LP
PRN_RET: RET
; SPECIFIED ILLEGAL DISK
ILDISK:
MOV DX,OFFSET ILMSG
CALL PRINT
JMP EXIT
; ERROR ON DISK WRITE
ERRWRT:
MOV DX,OFFSET WMSG
CALL PRINT
JMP EXIT
; DISPLAY WAIT MESSAGE AND WAIT FOR KEY PRESS
WAIT:
MOV DX,OFFSET WTMSG0
CALL PRINT
CALL KEYPRESS
MOV DX,OFFSET WTMSG1
CALL PRINT
MOV LINES,0
RET
; WAIT FOR A KEY PRESS AND RETURN IT IN AL
KEYPRESS:
MOV CL,DCONIN ;DIRECT CONSOLE IO
MOV DL,0FFH ;REQUEST AN INPUT CHECK
INT 224
CMP AL,0
JE KEYPRESS
RET
; DIRECT BIOS CALL FOR CP/M-86 VERSION 1.1
;
SELECT_DISK11:
MOV AL,9 ;BIOS FUCN 9
JMPS BIOS ;RETURNS DPH ADDR IN ES:BX
SET_TRACK11:
MOV AL,10
JMPS BIOS
SET_DMASEG11:
MOV AL,17
JMPS BIOS
SET_DMAOFF11:
MOV AL,12
JMPS BIOS
SET_SECTOR11:
MOV AL,11
JMPS BIOS
READ_SECTOR11:
MOV AL,13
JMPS BIOS
WRITE_SECTOR11:
MOV AL,14
JMPS BIOS
SECTOR_XLAT11:
MOV AL,16
MOV DX,XLAT_ADR ;RETURN XLATED SECTOR IN BX
JMPS BIOS
BIOS:
MOV BX,OFFSET BPB ;FILL IN BIOS PARAMETER BLOCK
MOV BPB_FUNC,AL
MOV BPB_CX,CX
MOV BPB_DX,DX
MOV CL,DIRBIOS ;BDOS FUNC 50
MOV DX,BX
INT 224 ;CALL IT
RET
; DIRECT BIOS CALLS FOR CP/M-86 VERSION 3.1
;
SET_SECTOR31:
mov sector,cx
ret
SET_TRACK31:
mov track,cx
ret
SECTOR_XLAT31:
mov bx,cx
ret
SET_DMASEG31: ;DMA IS SET IN CPMCHK ROUTINE
SET_DMAOFF31:
ret
;++++++++++++++++++++++++++++++++++++++
SELECT_DISK31: ;selects a drive
;------
; resets login sequence number of drive to 0, to force
; permanent media to be logged in again on disk reset
; Entry: CL = drive to select
; DL = 0 if initial select, else 1
push es ! push ds ;save context
push cx ;save drive
call getsu ;set up DS and ES
pop cx ;restore drive
mov ax,BIO_SELDSK ;do the BIOS SELDSK call
callf BIOS_ptr ;call indirect BIOS
mov LOG_SEQN[bx],0 ;force disk reset: 0 login sequence no.
pop es ! push es ;get DS into ES
mov di,offset dpb ;setup dest of dpb
mov si,DPB_PTR31[bx] ;get the info from DPH
mov cx,DPB_SIZE
rep movsb ;copy DPB into local storage
pop ds ! pop es ;restore context
ret
READ_SECTOR31: ;reads a physical sector
;----
mov bx,BIO_READ
jmp biosiopb
WRITE_SECTOR31: ;writes a physical sector
;-----
mov bx,BIO_WRITE
biosiopb: ;put the IOPB on the stack, call BIOS
push ds ;ds will contain SYSDAT seg
push es ;es will contain UDA seg
;push iopb onto stack
mov ah,mcnt
mov al,drive
push ax ;drive and multi-sector count
push track ;track #
push sector ;sector # = 0
push dmaseg ;track buffer DMA segment
push dmaoff ;track buffer DMA offset = 0
call getsu ;set up DS-SYSDAT and ES-UDA
mov ax,bx ;set I/O function into AX
callf BIOS_ptr ;call indirect the BIOS
;AL,BL = return status
add sp,10 ;restore stack
pop es ;restore original ES
pop ds ;ditto for DS
ret
;======
GETSU:
;======
CMP CPM_VERSION,CCPM_31 ;IS IT CCP/M?
JNE GETSU10
getsu14: ;get sysdat and uda addrs for CCP/M ver 1431
;-----
; entry: DS = local data seg
; exit: DS = SYSDAT seg, ES=UDA seg (for call to XIOS)
mov ax,udaaddr ;get the saved value
or ax,ax ;set flags
jz getsu14a ;uninitialized, go do the OS call
mov es,ax ;we've been here before, just load regs
mov ds,sysaddr
ret
getsu14a:
mov cl,S_SYSDAT ;will return system data seg in ES
int 224
mov sysaddr,es ;save system data segment
mov cl,P_PDADR ;will return PDA address in BX
int 224
; mov pdaddr,bx ;and save it
mov ax,es:P_UDA[bx] ;grab UDA_seg
mov udaaddr,ax ;save for future calls
push ax ;save uda_seg
mov ds,sysaddr
pop es ;restore uda_seg
ret
;----------------
getsu10: ;get sysdat and uda addrs
;-----
; entry: DS = local data seg
; exit: DS = SYSDAT seg, ES=UDA seg (for call to BIOS)
mov ax,udaaddr ;get the saved value
or ax,ax ;set flags
jz getsu10a ;uninitialized, go do the OS call
mov es,ax ;we've been here before, just load regs
mov ds,sysaddr
ret
getsu10a:
mov cl,DRV_DPB ;will return segment of SYSDAT in ES
int 224
mov ax,es:UDA_seg ;grab UDA_seg
mov udaaddr,ax ;save for future calls
push ax ;save uda_seg
mov ax,es
mov sysaddr,ax ;save for future calls
mov ds,ax
pop es ;restore uda_seg
ret
; ***** DATA STORAGE AREA*****************
DSEG
HLPMSG DB CR,LF,LF
DB 'USAGE: A>UNERA Dr:FILENAME.TYP',CR,LF,LF
DB TAB,'Filename and/or type may be wildcards.',CR,LF
DB TAB,'Wildcards may be either ? or *',CR,LF,LF
DB TAB,'CAUTION! use the * wildcard with care.',CR,LF
DB TAB,'Using *.* will recover ALL erased filenames.',CR,LF,LF
DB TAB,'The recoverable file(s) matching the FILNAME.TYP',CR,LF
DB TAB,'will be listed, you then have an option to quit.',CR,LF,LF
DB TAB,'Be SURE to check recovered files before using to',CR,LF
DB TAB,'confirm that they are OK and function properly.',CR,LF
DB TAB,'If possible, make a CRC check on recovered files.',CR,LF,LF
DB TAB,'HINT: for best results use UNERA immediately after',CR,LF
DB TAB,'making an unwanted erasure, else the space may be',CR,LF
DB TAB,'re-allocated to another file and recovery is impossible.'
DB CR,LF,0
HMSG DB CR,LF,'UNERA ver 3.1 (2-16-84) for CP/M-86, CP/M-86+ & CCP/M-86 // for HELP',0
WMSG DB CR,LF,'ERROR OCCURED DURING DISK WRITE - ABORTED',0
ILMSG DB CR,LF,'SPECIFIED AN ILLEGAL DISK DRIVE - ABORTED',0
BMSG DB CR,LF,'PLEASE! check recovered files before using them',0
NOFMSG DB CR,LF,'NO FILE NAME SPECIFIED - ABORTED',0
NFMSG DB CR,LF,'FILE NOT FOUND',0
WVMSG DB CR,LF,'Only CP/M-86 ver 1.1 & 3.1 Plus and CCP/M ver 3.1 are Supported',0
MPMSG DB CR,LF,'THE MP/M OPERATING SYSTEM IS NOT SUPPORTED',0
RVMSG DB CR,LF,'Do you wish to recover the File(s) (Y/N)? ',0
WTMSG0 DB CR,LF,' Press any key to continue ',0
WTMSG1 DB CR,' ',CR,0
RCMSG DB CR,LF,LF,'Recovered File(s) will be on '
FILNAM0 DB 'X: User 0'
FILNAM DB CR,LF
FILNAM1 DB 'FILENAME.TYP - Extent # '
FILNAM2 DB 'X',0
TABLE11 DW OFFSET SELECT_DISK11 ;DIRECT BIOS CALLS FOR CP/M-11
DW OFFSET SET_TRACK11
DW OFFSET SET_DMASEG11
DW OFFSET SET_DMAOFF11
DW OFFSET SET_SECTOR11
DW OFFSET READ_SECTOR11
DW OFFSET WRITE_SECTOR11
DW OFFSET SECTOR_XLAT11
TABLE31 DW OFFSET SELECT_DISK31 ;DIRECT BIOS CALLS FOR CP/M-31
DW OFFSET SET_TRACK31
DW OFFSET SET_DMASEG31
DW OFFSET SET_DMAOFF31
DW OFFSET SET_SECTOR31
DW OFFSET READ_SECTOR31
DW OFFSET WRITE_SECTOR31
DW OFFSET SECTOR_XLAT31
CURDR DB 0 ;CURRENT DRIVE HERE
LINES DB 2 ;LINES PRINTED ON SCREEN COUNTER
FIX_EM DB 0 ;FIX FLAG
VIEW_EM DB 0FFH ;VIEW FLAG
BPB RS 5 ;SPACE FOR BIOS PARAMETER BLOCK
CALL_TBL RW 1 ;ADDRESS OF BIOS CALL TABLE GOES HERE
XLAT_ADR RW 1 ;ADDRESS OF TRANSLATION TABLE
FIXCNT RB 1 ;NUMBER OF FIXES
REWRT RB 1 ;WRITE BACK TO DISK FLAG
MAXDIR RW 1
MAXSEC RW 1
DIR_PER_SEC DB 4 ;number directory entrys per sector
SEC_PER_TRK DW 26
CPM_VERSION DW 0 ;cpm version
sysaddr dw 0 ;save location for sysdat addr
udaaddr dw 0 ;save location for process uda addr
mcnt db 1 ;multi-sector count
drive rb 1 ;drive number (A:=1)
track rw 1 ;track number
sector rw 1 ;sector number
dmaseg rw 1 ;DMA segment for data
dmaoff dw offset dir_buf ;DMA offset for data
dpb rb DPB_SIZE
RW 32 ;32 WORD LOCAL STACK
STACK RW 1
dir_buf rs 0000 ;4K data buffer [add[100]] at link
END