mirror of
https://github.com/Microsoft/MS-DOS.git
synced 2025-08-21 14:03:34 -07:00
MS-DOS v2.0 Release
This commit is contained in:
parent
fce0f75959
commit
80ab2fddfd
156 changed files with 56403 additions and 0 deletions
876
v2.0/source/RECOVER.ASM
Normal file
876
v2.0/source/RECOVER.ASM
Normal file
|
@ -0,0 +1,876 @@
|
|||
TITLE RECOVER MS-DOS File/Disk Recovery Utility
|
||||
;----------------------------------------------------------
|
||||
;
|
||||
; Recover - Program to rebuild an ms.dos directory
|
||||
;
|
||||
; Copyright 1982 by Microsoft Corporation
|
||||
; Written by Chris Peters, April 1982
|
||||
;
|
||||
;-----------------------------------------------------------
|
||||
;
|
||||
;REV 1.5 added header message ARR
|
||||
;
|
||||
|
||||
FALSE EQU 0
|
||||
TRUE EQU NOT FALSE
|
||||
|
||||
|
||||
IBMVER EQU true
|
||||
KANJI EQU FALSE
|
||||
|
||||
bdos equ 21h
|
||||
boot equ 20h
|
||||
aread equ 25h
|
||||
awrite equ 26h
|
||||
|
||||
INCLUDE DOSSYM.ASM
|
||||
|
||||
;
|
||||
cr equ 0dh
|
||||
lf equ 0ah
|
||||
;
|
||||
fcb equ 5ch
|
||||
|
||||
code segment public
|
||||
code ends
|
||||
|
||||
const segment public byte
|
||||
const ends
|
||||
|
||||
data segment public byte
|
||||
data ends
|
||||
|
||||
|
||||
dg group code,const,data
|
||||
|
||||
code segment public
|
||||
assume cs:dg,ds:dg,es:dg,ss:dg
|
||||
|
||||
PUBLIC PCRLF,PRINT,INT_23,convert
|
||||
EXTRN dskwrt:NEAR,dskrd:NEAR,DSKERR:NEAR,report:NEAR
|
||||
|
||||
org 100h
|
||||
|
||||
recover:jmp rec_start
|
||||
|
||||
HEADER DB "Vers 1.50"
|
||||
|
||||
;-----------------------------------------------------------------------;
|
||||
hardch dd ?
|
||||
|
||||
the_root db 0 ;root directory flag
|
||||
|
||||
fudge db 0 ;directory changed flag
|
||||
user_drive db 0
|
||||
drive db 0
|
||||
|
||||
|
||||
dirchar db "/",0
|
||||
|
||||
|
||||
userdir db "/",0
|
||||
db (dirstrlen) dup(0)
|
||||
|
||||
fname_buffer db 128 dup(0)
|
||||
;-----------------------------------------------------------------------;
|
||||
|
||||
pcrlf: mov dx,offset dg: crlf
|
||||
print: mov ah,STD_CON_STRING_OUTPUT
|
||||
int bdos
|
||||
pret: ret
|
||||
;
|
||||
convert:push bx
|
||||
xor ax,ax
|
||||
mov bx,ax
|
||||
mov bp,ax
|
||||
mov cx,32
|
||||
convlp: shl si,1
|
||||
rcl di,1
|
||||
xchg ax,bp
|
||||
call convwrd
|
||||
xchg ax,bp
|
||||
xchg ax,bx
|
||||
call convwrd
|
||||
xchg ax,bx
|
||||
adc al,0
|
||||
loop convlp
|
||||
|
||||
mov cx,1810h
|
||||
xchg dx,ax
|
||||
call digit
|
||||
xchg ax,bx
|
||||
call outword
|
||||
mov ax,bp
|
||||
call outword
|
||||
pop dx
|
||||
call print
|
||||
ret2: ret
|
||||
;
|
||||
outword:push ax
|
||||
mov dl,ah
|
||||
call outbyte
|
||||
pop dx
|
||||
outbyte:mov dh,dl
|
||||
shr dl,1
|
||||
shr dl,1
|
||||
shr dl,1
|
||||
shr dl,1
|
||||
call digit
|
||||
mov dl,dh
|
||||
digit: and dl,0fh
|
||||
jz blankzer
|
||||
xor cl,cl
|
||||
blankzer:
|
||||
dec ch
|
||||
and cl,ch
|
||||
or dl,30h
|
||||
sub dl,cl
|
||||
cmp dl,30h
|
||||
jl ret2
|
||||
mov ah,STD_CON_OUTPUT
|
||||
int bdos
|
||||
ret
|
||||
;
|
||||
convwrd:adc al,al
|
||||
daa
|
||||
xchg al,ah
|
||||
adc al,al
|
||||
daa
|
||||
xchg al,ah
|
||||
ret
|
||||
;
|
||||
; bx = fat[ax]
|
||||
;
|
||||
getfat: mov bx,offset dg: fattbl
|
||||
push ax
|
||||
mov si,ax
|
||||
sar ax,1
|
||||
pushf
|
||||
add si,ax
|
||||
mov bx,word ptr [bx][si]
|
||||
popf
|
||||
jnc getfat1
|
||||
mov cl,4
|
||||
shr bx,cl
|
||||
getfat1:and bh,00001111b
|
||||
pop ax
|
||||
mov cx,secsiz
|
||||
ret
|
||||
;
|
||||
; fat[ax] = dx
|
||||
;
|
||||
setfat: mov bx,offset dg: fattbl
|
||||
push ax
|
||||
push dx
|
||||
mov si,ax
|
||||
sar ax,1
|
||||
pushf
|
||||
add si,ax
|
||||
mov ax,word ptr [bx][si]
|
||||
popf
|
||||
jnc setfat2
|
||||
and ax,000fh
|
||||
mov cl,4
|
||||
shl dx,cl
|
||||
setfat1:or ax,dx
|
||||
mov word ptr [bx][si],ax
|
||||
pop dx
|
||||
pop ax
|
||||
ret
|
||||
|
||||
setfat2:and ax,0f000h
|
||||
jmp setfat1
|
||||
|
||||
load: mov dx,firfat
|
||||
mov al,byte ptr fatnum
|
||||
mov byte ptr fatcnt,al
|
||||
mov al,byte ptr drive
|
||||
mov cx,fatsiz
|
||||
mov bx,offset dg: fattbl
|
||||
ret66: ret
|
||||
|
||||
readft: call load
|
||||
readit: call dskrd
|
||||
cmp [fndfat],0 ;save location of readable fat sector
|
||||
jnz fdfat
|
||||
mov [fndfat],dx
|
||||
fdfat: cmp word ptr [bx+1],-1
|
||||
jz ret66
|
||||
|
||||
add dx,cx ;try to read the other fats
|
||||
dec byte ptr fatcnt
|
||||
jnz readit
|
||||
|
||||
mov dx,[fndfat] ;see if any readable at all
|
||||
or dx,dx
|
||||
jz readft ;if not disk is blown, keep trying
|
||||
call dskrd
|
||||
ret
|
||||
|
||||
wrtfat: call load
|
||||
wrtit: push ax
|
||||
push bx
|
||||
push cx
|
||||
push dx
|
||||
call dskwrt
|
||||
pop dx
|
||||
pop cx
|
||||
pop bx
|
||||
pop ax
|
||||
|
||||
wrtok: add dx,cx
|
||||
dec byte ptr fatcnt
|
||||
jnz wrtit
|
||||
ret
|
||||
|
||||
printerr:
|
||||
call print
|
||||
jmp rabort
|
||||
|
||||
|
||||
rec_start:
|
||||
|
||||
;Code to print header
|
||||
; PUSH AX
|
||||
; MOV DX,OFFSET DG:HEADER
|
||||
; CALL print
|
||||
; POP AX
|
||||
|
||||
DOSVER_HIGH EQU 0200H ;2.00 in hex
|
||||
PUSH AX ;Save DRIVE validity info
|
||||
MOV AH,GET_VERSION
|
||||
INT 21H
|
||||
XCHG AH,AL ;Turn it around to AH.AL
|
||||
CMP AX,DOSVER_HIGH
|
||||
JAE OKDOS
|
||||
GOTBADDOS:
|
||||
MOV DX,OFFSET DG:BADVER
|
||||
CALL PRINT
|
||||
INT 20H
|
||||
|
||||
OKDOS: POP AX
|
||||
|
||||
cmp al,0ffH
|
||||
JZ BADDRVSPECJ
|
||||
mov si,80h
|
||||
lodsb
|
||||
or al,al
|
||||
jz noparm
|
||||
look: lodsb
|
||||
cmp al," "
|
||||
jz look
|
||||
cmp al,9
|
||||
jz look
|
||||
cmp al,13
|
||||
jnz gotparm
|
||||
noparm:
|
||||
jmp noname
|
||||
|
||||
BADDRVSPECJ: JMP BADDRVSPEC
|
||||
|
||||
gotparm:
|
||||
mov ah,DISK_RESET
|
||||
int bdos ;empty buffer queue
|
||||
|
||||
mov ah,get_default_drive ;save current drive
|
||||
int 21h
|
||||
mov [user_drive],al
|
||||
|
||||
mov bx,fcb ;determine input command
|
||||
mov al,[bx]
|
||||
dec al
|
||||
cmp al,-1
|
||||
jnz drvok1
|
||||
mov al,[user_drive]
|
||||
drvok1:
|
||||
mov [drive],al
|
||||
add [drvlet],al
|
||||
add [drvlet1],al
|
||||
mov dx,offset dg: askmsg
|
||||
call print
|
||||
mov ah,STD_CON_INPUT_FLUSH
|
||||
mov al,1 ;wait for a key
|
||||
int bdos
|
||||
|
||||
cmp al,17h
|
||||
jnz drvok2
|
||||
mov dx,offset dg: egomes
|
||||
jmp printerr
|
||||
egomes: db "Chris Peters helped with the new dos!",cr,lf
|
||||
db "Microsoft rules ok$"
|
||||
|
||||
drvok2:
|
||||
IF IBMVER
|
||||
MOV AL,DRIVE ;This is for ibm's single drive sys
|
||||
PUSH DS
|
||||
MOV BX,50H
|
||||
MOV DS,BX
|
||||
MOV DS:(BYTE PTR 4),AL ;Indicate drive changed
|
||||
POP DS
|
||||
ENDIF
|
||||
|
||||
;----- Process Pathnames -----------------------------------------------;
|
||||
mov ax,(char_oper shl 8) ;get switch character
|
||||
int 21h
|
||||
cmp dl,"/"
|
||||
jnz slashok ;if not / , then not PC
|
||||
mov [dirchar],"\" ;in PC, dir separator = \
|
||||
mov [userdir],"\"
|
||||
|
||||
slashok:
|
||||
mov si,81h ;point to cammand line
|
||||
mov di,offset dg: fname_buffer
|
||||
xor cx,cx ;zero pathname length
|
||||
|
||||
kill_bl:
|
||||
lodsb ;get rid of blanks
|
||||
cmp al,9
|
||||
je kill_bl
|
||||
cmp al,' '
|
||||
je kill_bl
|
||||
cmp al,13 ;A carriage return?
|
||||
jne next_char
|
||||
jmp noname ;yes, file name missing
|
||||
|
||||
next_char:
|
||||
stosb ;put patname in buffer
|
||||
inc cx
|
||||
lodsb
|
||||
cmp al,' '
|
||||
je name_copied
|
||||
cmp al,9
|
||||
je name_copied
|
||||
cmp al,13 ; a CR ?
|
||||
jne next_char
|
||||
|
||||
name_copied:
|
||||
mov byte ptr [di],0 ;nul terminate the pathname
|
||||
dec di ;adjust to the end of the pathname
|
||||
|
||||
;----- Scan for directory ----------------------------------------------;
|
||||
|
||||
IF KANJI
|
||||
mov dx,offset dg: [fname_buffer]
|
||||
PUSH DX
|
||||
PUSH DI
|
||||
MOV BX,DI
|
||||
MOV DI,DX
|
||||
DELLOOP:
|
||||
CMP DI,BX
|
||||
JZ GOTDELE
|
||||
MOV AL,[DI]
|
||||
INC DI
|
||||
CALL TESTKANJ
|
||||
JZ NOTKANJ11
|
||||
INC DI
|
||||
JMP DELLOOP
|
||||
|
||||
NOTKANJ11:
|
||||
cmp al,[dirchar]
|
||||
JNZ DELLOOP
|
||||
MOV DX,DI ;Point to char after '/'
|
||||
DEC DX
|
||||
DEC DX ;Point to char before '/'
|
||||
JMP DELLOOP
|
||||
|
||||
GOTDELE:
|
||||
MOV DI,DX
|
||||
POP AX ;Initial DI
|
||||
POP DX
|
||||
SUB AX,DI ;Distance moved
|
||||
SUB CX,AX ;Set correct CX
|
||||
CMP DX,DI
|
||||
JB sja ;Found a pathsep
|
||||
JA sjb ;Started with a pathsep, root
|
||||
MOV AX,[DI]
|
||||
CALL TESTKANJ
|
||||
JNZ same_dirj
|
||||
XCHG AH,AL
|
||||
cmp al,[dirchar]
|
||||
jz sja ;One character directory
|
||||
same_dirj:
|
||||
ELSE
|
||||
mov al,[dirchar] ;get directory separator character
|
||||
std ;scan backwards
|
||||
repnz scasb ;(cx has the pathname length)
|
||||
cld ;reset direction, just in case
|
||||
jz sja
|
||||
ENDIF
|
||||
|
||||
jmp same_dir ;no dir separator char. found, the
|
||||
; file is in the current directory
|
||||
; of the corresponding drive. Ergo,
|
||||
; the FCB contains the data already.
|
||||
|
||||
sja:
|
||||
jcxz sjb ;no more chars left, it refers to root
|
||||
cmp byte ptr [di],':' ;is the prvious character a disk def?
|
||||
jne not_root
|
||||
sjb:
|
||||
mov [the_root],01h ;file is in the root
|
||||
not_root:
|
||||
inc di ;point to dir separator char.
|
||||
mov al,0
|
||||
stosb ;nul terminate directory name
|
||||
pop ax
|
||||
push di ;save pointer to file name
|
||||
mov [fudge],01h ;remember that the current directory
|
||||
; has been changed.
|
||||
|
||||
;----- Save current directory for exit ---------------------------------;
|
||||
mov dl,byte ptr ds:[fcb] ;get specified drive if any
|
||||
or dl,dl ;default disk?
|
||||
jz same_drive
|
||||
dec dl ;adjust to real drive (a=0,b=1,...)
|
||||
mov ah,set_default_drive ;change disks
|
||||
int 21h
|
||||
cmp al,-1 ;error?
|
||||
jne same_drive
|
||||
BADDRVSPEC:
|
||||
mov dx,offset dg: baddrv
|
||||
jmp printerr
|
||||
|
||||
same_drive:
|
||||
mov ah,get_default_dpb
|
||||
int 21h
|
||||
|
||||
assume ds:nothing
|
||||
|
||||
cmp al,-1 ;bad drive? (should always be ok)
|
||||
jne drvisok
|
||||
mov dx,offset dg: baddrv
|
||||
jmp printerr
|
||||
|
||||
drvisok:
|
||||
cmp [bx.dpb_current_dir],0
|
||||
je curr_is_root
|
||||
mov si,bx
|
||||
add si,dpb_dir_text
|
||||
mov di,offset dg: userdir + 1
|
||||
|
||||
dir_save_loop:
|
||||
lodsb
|
||||
stosb
|
||||
or al,al
|
||||
jnz dir_save_loop
|
||||
|
||||
curr_is_root:
|
||||
push cs
|
||||
pop ds
|
||||
|
||||
assume ds:dg
|
||||
|
||||
|
||||
;----- Change directories ----------------------------------------------;
|
||||
cmp [the_root],01h
|
||||
mov dx,offset dg: [dirchar] ;assume the root
|
||||
je sj1
|
||||
mov dx,offset dg: [fname_buffer]
|
||||
sj1:
|
||||
mov ah,chdir ;change directory
|
||||
int 21h
|
||||
mov dx,offset dg: baddrv
|
||||
jnc no_errors
|
||||
jmp printerr
|
||||
no_errors:
|
||||
|
||||
;----- Set Up int 24 intercept -----------------------------------------;
|
||||
|
||||
mov ax,(get_interrupt_vector shl 8) or 24h
|
||||
int 21h
|
||||
mov word ptr [hardch],bx
|
||||
mov word ptr [hardch+2],es
|
||||
mov ax,(set_interrupt_vector shl 8) or 23h
|
||||
mov dx,offset dg: int_23
|
||||
int 21h
|
||||
mov ax,(set_interrupt_vector shl 8) or 24h
|
||||
mov dx,offset dg: int_24
|
||||
int 21h
|
||||
push cs
|
||||
pop es
|
||||
|
||||
;----- Parse filename to FCB -------------------------------------------;
|
||||
pop si
|
||||
mov di,fcb
|
||||
mov ax,(parse_file_descriptor shl 8) or 1
|
||||
int 21h
|
||||
push ax
|
||||
;-----------------------------------------------------------------------;
|
||||
same_dir:
|
||||
pop ax
|
||||
|
||||
mov bx,fcb
|
||||
cmp byte ptr [bx+1],' ' ;must specify file name
|
||||
jnz drvok
|
||||
cmp byte ptr [bx],0 ;or drive specifier
|
||||
jnz drvok
|
||||
noname: mov dx,offset dg: drverr
|
||||
call print
|
||||
jmp int_23
|
||||
|
||||
drvok: push ds
|
||||
mov dl,drive
|
||||
inc dl
|
||||
mov ah,GET_DPB
|
||||
int bdos
|
||||
mov ax,word ptr [bx+2] ;get physical sector size
|
||||
mov cl,byte ptr [bx+4] ;get sectors/cluster - 1
|
||||
xor ch,ch
|
||||
inc cx
|
||||
mov cs:secall,cx ;save sectors per cluster
|
||||
mul cx ;ax = bytes per cluster
|
||||
mov bp,word ptr [bx+11] ;get record of first sector
|
||||
mov dx,word ptr [bx+16] ;get record of first directory entry
|
||||
mov si,word ptr [bx+6] ;get record of first fat
|
||||
mov cl,byte ptr [bx+15] ;get size of fat
|
||||
mov di,word ptr [bx+13] ;get number of clusters
|
||||
mov ch,byte ptr [bx+8] ;get number of fats on drive
|
||||
mov bx,word ptr [bx+9] ;get max number of dir entries
|
||||
pop ds
|
||||
|
||||
mov maxent,bx
|
||||
mov firfat,si
|
||||
mov firrec,bp
|
||||
mov firdir,dx
|
||||
mov byte ptr fatsiz,cl
|
||||
mov lastfat,di ;number of fat entries
|
||||
mov byte ptr fatnum,ch ;save number of fats on disk
|
||||
|
||||
mov secsiz,ax
|
||||
|
||||
mov di,table ;di points into constructed directory
|
||||
mov ax,0e5e5h ;deleted file magic number
|
||||
shl bx,1 ;16 words in a dir entry
|
||||
shl bx,1
|
||||
shl bx,1
|
||||
shl bx,1
|
||||
mov cx,bx
|
||||
rep stosw
|
||||
|
||||
call readft
|
||||
mov bx,fcb
|
||||
cmp byte ptr [bx+1],' '
|
||||
jz recdsk
|
||||
jmp recfil
|
||||
|
||||
recdsk: mov di,table
|
||||
mov fatptr,2
|
||||
mov ax,fatptr
|
||||
step1: call getfat
|
||||
cmp bx,0fffh
|
||||
jz step1a
|
||||
jmp step6
|
||||
step1a: mov filsiz,0
|
||||
mov word ptr filsiz+2,0
|
||||
mov dx,lastfat
|
||||
mov target,ax
|
||||
step2: mov ax,2
|
||||
add filsiz,cx
|
||||
adc word ptr filsiz+2,0
|
||||
step3: call getfat
|
||||
cmp bx,target
|
||||
jne step4
|
||||
mov target,ax
|
||||
jmp step2
|
||||
step4: inc ax
|
||||
cmp ax,dx
|
||||
jle step3
|
||||
;
|
||||
; at this point target = head of list, filsiz = file size
|
||||
;
|
||||
inc filcnt ;increment file count
|
||||
mov ax,maxent
|
||||
cmp filcnt,ax ;compare with max number of entries
|
||||
ja direrr
|
||||
|
||||
mov si,(offset dg: dirent)+7
|
||||
nam0: inc byte ptr [si] ;increment file name
|
||||
cmp byte ptr [si],'9'
|
||||
jle nam1
|
||||
mov byte ptr [si],'0'
|
||||
dec si
|
||||
jmp nam0
|
||||
|
||||
nam1: mov ah,GET_DATE
|
||||
int bdos ;set the date
|
||||
sub cx,1980
|
||||
add dh,dh
|
||||
add dh,dh
|
||||
add dh,dh
|
||||
add dh,dh
|
||||
add dh,dh
|
||||
rcl cl,1
|
||||
or dh,dl
|
||||
mov byte ptr dirent+24,dh
|
||||
mov byte ptr dirent+25,cl
|
||||
mov ah,GET_TIME
|
||||
int bdos ;set the time
|
||||
shr dh,1
|
||||
add cl,cl
|
||||
add cl,cl
|
||||
add cl,cl
|
||||
rcl ch,1
|
||||
add cl,cl
|
||||
rcl ch,1
|
||||
add cl,cl
|
||||
rcl ch,1
|
||||
or dh,cl
|
||||
mov byte ptr dirent+22,dh
|
||||
mov byte ptr dirent+23,ch
|
||||
|
||||
mov ax,filsiz ;set file size
|
||||
mov word ptr dirent+28,ax
|
||||
mov ax,word ptr filsiz+2
|
||||
mov word ptr dirent+30,ax
|
||||
mov ax,target ;set first cluster location
|
||||
mov word ptr dirent+26,ax
|
||||
|
||||
mov si,offset dg: dirent ;copy in new dir entry
|
||||
mov cx,32
|
||||
rep movsb
|
||||
|
||||
step6: inc fatptr ;keep looking for eof's
|
||||
mov ax,fatptr
|
||||
cmp ax,lastfat
|
||||
jg step7
|
||||
jmp step1
|
||||
|
||||
direrr: dec filcnt
|
||||
mov dx,offset dg: dirmsg
|
||||
call print
|
||||
|
||||
step7:
|
||||
mov al,drive
|
||||
mov dx,firdir ;write out constructed directory
|
||||
mov cx,firrec
|
||||
sub cx,dx
|
||||
mov bx,table
|
||||
call dskwrt
|
||||
call pcrlf
|
||||
mov dx,offset dg: recmsg_pre
|
||||
call print
|
||||
mov bx,offset dg: recmsg_post
|
||||
mov si,filcnt
|
||||
xor di,di ;output number of files created
|
||||
call convert
|
||||
jmp rexit
|
||||
recfil: mov dx,fcb
|
||||
mov ah,FCB_OPEN
|
||||
int bdos
|
||||
inc al
|
||||
jnz recfil0
|
||||
mov dx,offset dg: opnerr
|
||||
call print
|
||||
jmp rexit
|
||||
|
||||
recfil0:mov lastfat,1 ;indicate location of list head
|
||||
mov di,fcb
|
||||
mov ax,[di+16] ;get file size
|
||||
mov filsiz,ax
|
||||
mov siztmp,ax
|
||||
mov ax,[di+18]
|
||||
mov filsiz+2,ax
|
||||
mov siztmp+2,ax
|
||||
mov ax,[di+25] ;get list head
|
||||
or ax,ax
|
||||
mov fatptr,ax
|
||||
jnz recfil1
|
||||
recvec: jmp recfil6
|
||||
|
||||
recfil1:cmp fatptr,0fffh
|
||||
jz recvec ;terminate loop at e-o-f
|
||||
|
||||
mov cx,secall
|
||||
mov ax,fatptr
|
||||
dec ax
|
||||
dec ax
|
||||
mul cx
|
||||
add ax,firrec
|
||||
mov dx,ax
|
||||
mov bx,table
|
||||
mov al,drive
|
||||
int aread
|
||||
pop di ;restore stack pointer
|
||||
mov di,fcb ;restore pointer to fcb
|
||||
jnc recfil4 ;if no error continue reading
|
||||
|
||||
mov ax,fatptr
|
||||
call getfat
|
||||
cmp lastfat,1
|
||||
jnz recfil2
|
||||
|
||||
cmp bx,0fffh
|
||||
jnz noteof
|
||||
xor bx,bx
|
||||
noteof: mov word ptr [di+25],bx
|
||||
jmp recfil3
|
||||
|
||||
recfil2:mov dx,bx ;jump around bad sector
|
||||
mov ax,lastfat
|
||||
call setfat
|
||||
|
||||
recfil3:mov ax,fatptr ;mark sector bad
|
||||
mov dx,0ff7h
|
||||
call setfat
|
||||
mov ax,secsiz ;prepare to dec filsiz by secsiz
|
||||
cmp siztmp+2,0
|
||||
jnz recfilx
|
||||
cmp siztmp,ax
|
||||
ja recfilx
|
||||
mov ax,siztmp
|
||||
|
||||
recfilx:sub word ptr [di+16],ax
|
||||
sbb word ptr [di+18],0
|
||||
sub siztmp,ax
|
||||
sbb siztmp,0
|
||||
|
||||
and byte ptr [di+24],10111111b ;mark file dirty
|
||||
|
||||
mov ax,lastfat ;point to next sector to check
|
||||
jmp recfil5
|
||||
|
||||
recfil4:
|
||||
mov ax,secsiz ;set bytes remaining to be read
|
||||
sub siztmp,ax
|
||||
sbb siztmp+2,0
|
||||
jnc recok
|
||||
xor ax,ax ;if < 0, then set to zero
|
||||
mov siztmp,ax
|
||||
mov siztmp+2,ax
|
||||
|
||||
recok: mov ax,fatptr ;get next sector to test
|
||||
mov lastfat,ax
|
||||
recfil5:call getfat
|
||||
mov fatptr,bx
|
||||
jmp recfil1
|
||||
|
||||
recfil6: ;all done
|
||||
mov dx,fcb
|
||||
mov ah,FCB_CLOSE
|
||||
int bdos ;close the file
|
||||
call pcrlf
|
||||
call report
|
||||
|
||||
;
|
||||
rexit: mov ah,DISK_RESET
|
||||
int bdos
|
||||
call wrtfat ;save the fat
|
||||
int_23: call rest_dir
|
||||
rabort: int boot ;home, james...
|
||||
|
||||
;----- Restore INT 24 vector and old current directory -----------------;
|
||||
rest_dir:
|
||||
cmp [fudge],0
|
||||
je no_fudge
|
||||
|
||||
mov ax,(set_interrupt_vector shl 8) or 24h
|
||||
lds dx,[hardch]
|
||||
int 21h
|
||||
push cs
|
||||
pop ds
|
||||
|
||||
mov dx,offset dg: userdir ;restore directory
|
||||
mov ah,chdir
|
||||
int 21h
|
||||
mov dl,[user_drive] ;restore old current drive
|
||||
mov ah,set_default_drive
|
||||
int 21h
|
||||
|
||||
no_fudge:
|
||||
ret
|
||||
|
||||
;----- INT 24 Processing -----------------------------------------------;
|
||||
|
||||
int_24_retaddr dw int_24_back
|
||||
|
||||
int_24 proc far
|
||||
assume ds:nothing,es:nothing,ss:nothing
|
||||
|
||||
pushf
|
||||
push cs
|
||||
push [int_24_retaddr]
|
||||
push word ptr [hardch+2]
|
||||
push word ptr [hardch]
|
||||
ret
|
||||
int_24 endp
|
||||
|
||||
int_24_back:
|
||||
cmp al,2 ;abort?
|
||||
jnz ireti
|
||||
push cs
|
||||
pop ds
|
||||
|
||||
assume ds:dg
|
||||
|
||||
call rest_dir
|
||||
int 20h
|
||||
ireti:
|
||||
iret
|
||||
|
||||
IF KANJI
|
||||
TESTKANJ:
|
||||
CMP AL,81H
|
||||
JB NOTLEAD
|
||||
CMP AL,9FH
|
||||
JBE ISLEAD
|
||||
CMP AL,0E0H
|
||||
JB NOTLEAD
|
||||
CMP AL,0FCH
|
||||
JBE ISLEAD
|
||||
NOTLEAD:
|
||||
PUSH AX
|
||||
XOR AX,AX ;Set zero
|
||||
POP AX
|
||||
RET
|
||||
|
||||
ISLEAD:
|
||||
PUSH AX
|
||||
XOR AX,AX ;Set zero
|
||||
INC AX ;Reset zero
|
||||
POP AX
|
||||
RET
|
||||
ENDIF
|
||||
|
||||
code ends
|
||||
|
||||
const segment public byte
|
||||
|
||||
EXTRN BADVER:BYTE,askmsg:BYTE,drvlet:BYTE,dirmsg:BYTE
|
||||
EXTRN recmsg_pre:BYTE,DRVLET1:BYTE,recmsg_post:BYTE
|
||||
EXTRN crlf:BYTE,drverr:BYTE,baddrv:BYTE,opnerr:BYTE
|
||||
|
||||
const ends
|
||||
|
||||
data segment byte
|
||||
|
||||
PUBLIC filsiz
|
||||
|
||||
dirent db 'FILE0000REC'
|
||||
db 21 dup (00)
|
||||
|
||||
fndfat dw 0000 ;sector of first good fat
|
||||
filcnt dw 0000
|
||||
fatcnt db 00
|
||||
fatnum db 00
|
||||
fatsiz dw 0000
|
||||
firfat dw 0000
|
||||
fatptr dw 0000
|
||||
secall dw 0000 ;sectors per cluster
|
||||
target dw 0000
|
||||
maxent dw 0000
|
||||
firrec dw 0000
|
||||
firdir dw 0000
|
||||
secsiz dw 0000
|
||||
siztmp dw 0000
|
||||
dw 0000
|
||||
filsiz dw 0000
|
||||
dw 0000
|
||||
lastfat dw 0000
|
||||
;
|
||||
table dw offset dg:fattbl + 6 * 1024
|
||||
fattbl db 0
|
||||
|
||||
data ends
|
||||
|
||||
end recover
|
||||
|