home *** CD-ROM | disk | FTP | other *** search
- title scavenge Copyright (c) T. Jennings 1983
- ;
- ;****************************************
- ;* *
- ;* SCAVENGE *
- ;* *
- ;* Mark bad blocks on MSDOS *
- ;* as allocated in the FAT. *
- ;* *
- ;* T. Jennings 5 June 82 *
- ;* created 15 Sept. 82 *
- ;* *
- ;****************************************
- ;
- ;Reads all sectors in logical MSDOS blocks
- ;and marks the file allocation tables such
- ;that the blocks are permanently allocated
- ;where CHKDSK will not deallocate them.
- ;
- ;
- ;This version works on any 2.xx MSDOS or
- ;PCDOS, on any media type, fixed or removable.
- ;One (major) limitation: it will not map out
- ;blocks that are already allocated to a file;
- ;it will say "block used", but won't tell you
- ;which file it is in.
- ;
- ;If SCAVENGE finds any bad blocks, it will ask
- ;you whether or not you want the disk updated.
- ;You can safely run it just to see if the disk
- ;is OK.
- ;
- ;MASM, LINK, then EXE2BIN this to make a COM
- ;file. It will not run as an EXE file. NOTE:
- ;LINK will give you a 'Warning: no STACK
- ;segment' error: ignore it.
- ;
- cr equ 0dh
- lf equ 0ah
- page
- cgroup group code
- code segment byte public 'code'
- assume cs:cgroup,ds:cgroup,ss:cgroup
- ;
- ;MSDOS page 0 stuff.
- ;
- org 5ch
- tfcb label byte
-
- org 80h
- tbuff label byte
-
- org 100h
- scavenge:
- jmp start
- ;
- ;Disk parameters:
- ;
- blkcnt dw (?) ;blocks this disk
- blksize dw (?) ;sectors per block
- secsize dw (?) ;phys. sector size
- badcnt dw (?) ;# bad blocks found
- newbad dw (?) ;new bad ones
- block dw (?) ;current block
- sector dw (?) ;sector to read
- disk db (?) ;selected disk
- curdsk db (?) ;current disk.
- fatsec dw (?) ;1st FAT sector,
- fatcnt dw (?) ;FAT sec count.
-
- dw 128 dup (?)
- stack dw (?) ;what else
- page
- ;
- ;Say who we are, describe the disk we are
- ;about to fix, ask to continue or abort.
- ;
- start: mov ax,cs
- mov ds,ax
- mov ss,ax
- mov sp,offset stack
-
- mov dx,offset signon
- call pstr
- call setup ;get disk stuff
- jnc st1
- call pstr
- int 32 ;error.
-
- st1: call liststat ;describe dsk
- mov dx,offset contstr
- call pstr ;type any key..
- call ina
- ;
- ;Find all the bad blocks, if any, display them,
- ;ask if we should update the FAT. If so, write
- ;it out.
- ;
- mov dx,offset crlf
- call pstr
- call findbad ;map bad,
- call listbad ;list them,
- cmp newbad,0 ;if new bad
- je st2 ;blocks...
-
- mov dx,offset updstr ;ask if we
- call pstr ;should update
- call ina
- and al,5fh
- cmp al,'Y'
- jne st2
- mov al,disk ;write out the
- mov dx,fatsec ;FAT,
- mov cx,fatcnt
- mov bx,offset fatbuf
- int 26h
- pop ax ;pop flags
-
- st2: mov al,curdsk ;reselect the
- call seldsk ;original disk
- int 32
-
- signon db cr,lf,'DOS version 2 Bad Sector Mapper'
- db cr,lf,' T. Jennings 5 June 83'
- db '$'
- contstr db cr,lf,'Type ^C to abort, any '
- db 'other key to continue: $'
- updstr db cr,lf,lf,' Want the disk updated? [y,n] :$'
- crlf db cr,lf,'$'
- page
- ;
- ;Get the data on the specified disk. Return
- ;carry if no drive specified. Returns ES:DI
- ;pointing to the FAT for the selected drive.
- ;
- setup: call initdsk ;reset dsk sys,
- call getdsk ;get current,
- mov curdsk,al ;save it,
- mov al,tfcb ;make sure a
- cmp al,0 ;new one spec'd
- stc ;quit if none,
- mov dx,offset strstr
- jz gd1
- dec al ;make 0-N,
- mov disk,al
- call seldsk ;select,
-
- push ds ;save local DS,
- mov ah,1bh
- int 33
- pop ds
- mov blkcnt,dx ;save # blocks,
- mov secsize,cx ;sector size,
- mov ah,0
- mov blksize,ax ;secs/block.
-
- push ds ;now get the
- mov dl,disk
- inc dl ;drive 1=A, b=2
- mov ah,50 ;FAT,
- int 33 ;get the DPB,
- mov cx,[bx+15] ;CX= sec count,
- mov ch,0
- mov dx,[bx+6] ;DX= 1st sec,
- pop ds
- mov fatcnt,cx ;save both,
- mov fatsec,dx
-
- mov al,disk ;AL= drive #,
- mov bx,offset fatbuf ;DS:BX= buffer
- int 25h ;read the FAT,
- pop ax ;pop flags
- mov dx,offset bscstr
- gd1: ret
- strstr db cr,lf,'Must specify a disk drive.$'
- bscstr db cr,lf,'Bad FAT sector: disk not useable.$'
-
- page
- ;
- ;Read the entire disk looking for bad blocks.
- ;When one is found, go mark it as an allocated
- ;bad block.
- ;
- findbad:
- mov block,0 ;1st block,
- mov badcnt,0 ;none yet,
-
- fb1: mov dx,offset blkstr ;type 'block '
- call pstr
- mov bx,block ;block number,
- call outdec
- call readblk ;read a block,
- jnc fb3 ;if bad,
- inc badcnt ;count it,
- mov dx,offset badstr
- call pstr ;type 'bad'
- call mapout ;mark bad,
- mov dx,offset cntstr ;error if cant
- jc fb2
- add newbad,cx ;count it,
- mov dx,offset alrstr
- jcxz fb2 ;already markd
- mov dx,offset mrkstr
- fb2: call pstr
- fb3: inc block ;next block,
- dec blkcnt ;another...
- jnz fb1 ;keep looking.
- ret
-
-
- blkstr db cr,'Block $'
- badstr db ' bad,$'
- alrstr db ' already marked.',cr,lf,'$'
- mrkstr db ' mapped out.',lf,'$'
- cntstr db ' already used! I dont know'
- db ' which file.',lf,'$'
- page
- ;
- ;Mark the current block as bad in the FAT.
- ;Multiply the block number by 1.5 to find the
- ;block number, (actually *3, /2) and if not
- ;used, mark it bad. If used, report which file
- ;it's in. If it's already mapped as bad,
- ;return CX =0, else return CX=1.
- ;
- mapout:
- mov bx,block ;block,
- shl bx,1 ;times 2,
- add bx,block ;times 3,
- shr bx,1 ;divide by 2,
- mov ax,fatbuf[bx] ;get word,
- ;
- ;If carry is set, we want the high 12 bits in
- ;the word in AX, else the low 12 bits. Set CH
- ;as the shift count, DX as the mask.
- ;
- mov ch,0 ;assume low,
- mov dx,0fffh
- jnc mo1
- mov ch,4 ;else high 12,
- mov dx,0fff0h
- mo1: and ax,dx ;mask it,
- mov cl,ch
- shr ax,cl ;shift it,
- ;
- ;AX is the block number; if it's anything
- ;but 000 or ff7, return with carry set,
- ;indicating that its already used.
- ;
- cmp ax,0ff7h ;if ff7,
- je mo2 ;already marked
- cmp ax,0 ;if allocated,
- je mo3
- stc ;error!
- mo2: mov cx,0 ;none mapped,
- ret
- ;
- ;Bad unused block. Mark as bad in the FAT.
- ;
- mo3: mov ax,0ff7h ;marker,
- mov cl,ch
- shl ax,cl ;shift it,
- or fatbuf[bx],ax ;mark it.
- mov cx,1 ;1 mapped,
- ret
- page
- ;
- ;Read one block, return carry set if read
- ;error. Leave the useless data in the buffer
- ;following the end of this program.
- ;
- readblk:
- mov ax,block ;find start
- mov cx,blksize ;sector,
- mul cx ;CX= count,
- mov dx,ax ;DX= sector,
- mov al,disk
- mov bx,offset blkbuf ;our buffer,
- int 25h ;read sectors,
- pop dx ;pop flags,
- ret
- page
- ;
- ;List the general info on the disk, like
- ;sector sizes, etc.
- ;
- liststat:
- mov dx,offset st1str
- call pstr
- mov al,disk
- add al,'A'
- call outa
- mov dx,offset st2str
- call pstr
- mov bx,blkcnt
- call outdec
- mov dx,offset st3str
- call pstr
- ret
-
- ;Disk A:, total of 12345 data blocks.
-
- st1str db cr,lf,'Disk $'
- st2str db ':, total of $'
- st3str db ' data blocks.$'
- ;
- ;List out the bad things about this disk.
- ;
- listbad:
- mov dx,offset bd1str
- call pstr
- mov bx,badcnt
- call outdec
- mov dx,offset bd2str
- call pstr
- mov bx,newbad
- call outdec
- mov dx,offset bd3str
- call pstr
- ret
-
- ;Total of 12345 bad blocks, found 12234 more this pass.
- bd1str db cr,'Total of $' ;note no linefeed.
- bd2str db ' bad blocks, found $'
- bd3str db ' more this pass.$'
- page
- ;
- ;Generally useful system calls.
- ;
- pstr: mov ah,9
- int 33
- ret
- ;
- ;Type BX in decimal, suppressing leading
- ;zeros.
- ;
- outdec: mov cl,0 ;0 suppress flag,
- mov dx,10000
- call rsdiv
- mov dx,1000
- call rsdiv
- mov dx,100
- call rsdiv
- mov dx,10
- call rsdiv
- mov ch,bl
- jmp odf
-
- rsdiv: mov ch,-1 ;iteration -1,
- rs1: inc ch ;count,
- sub bx,dx ;subtract,
- jnc rs1 ;til underflow,
- add bx,dx ;adjust back,
- cmp ch,0 ;if non-zero,
- jne odf ;type it,
- test cl,1 ;dont type 0's
- jnz odf ;if leading,
- ret
-
- odf: push dx
- mov dl,ch
- add dl,'0' ;ASCII,
- mov ah,2
- int 33
- pop dx
- mov cl,1 ;no suppress,
- ret
- page
- ;
- ;More system calls.
- ;
- seldsk: mov dl,al ;select disk,
- mov ah,0eh
- int 33
- ret
-
- getdsk: mov ah,19h
- int 33
- ret
-
- initdsk:mov ah,0dh
- int 33
- ret
-
- ina: mov ah,0ch ;char in with
- mov al,1 ;flush.
- int 33
- ret
-
- outa: mov dl,al
- mov ah,2
- int 33
- ret
-
- blkbuf db 16384 dup (?) ;cluster buffer
-
- fatbuf label word ;FAT buffer.
-
- code ends
-
- end scavenge
-