home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.shrubbery.net
/
2015-02-07.ftp.shrubbery.net.tar
/
ftp.shrubbery.net
/
pub
/
pc
/
unix
/
unx.arc
/
FINDBAD.ASM
< prev
next >
Wrap
Assembly Source File
|
1986-06-02
|
8KB
|
290 lines
;------ findbad.asm --------------------------------------------------------
; Program to read FAT table and print it out.
; Preliminary to the disk scanning bad block checking program.
; (Actually, test of pcwrite editor, but I won't tell anyone if you won't.)
;
; Uses INT 25H "Absolute Disk Read", as there is no other way to do it.
;
; Daniel (too much time on my hands) Kegel
;
;---------------------------------------------------------------------------
stdin equ 0
stdout equ 1
stderr equ 2
extrn sprintf:near
extrn strlen:near
extrn _args:near, argc:word, argv:word
extrn new:near
code segment para public 'CODE'
assume cs:code, ds:code
org 100h
_main proc near
jmp main
_main endp
; Copyright message
db 27, "[2J"
db "findbad (C) 1985 by Yoyodyne, Inc. (a growing excited"
db " company)", 0dh, 0ah, 1ah
; variables (assembler hates forward refs on these, so they're here)
byemsg: db 13, 10, "Completely done.", 13, 10
byelen equ $-byemsg
fmt1: db "Disk %c: Media id byte %x, %d sec/cluster, %d clusters, %d bytes/sec\n\O"
msg2: db "Bad cluster (sector) numbers, in decimal:", 13, 10
msg2l equ $-msg2
hexfmt: db "%5d (%-5d) \O"
hexnlfmt:
db "%5d (%-5d)\n\O"
badfmsg: db "Read error on FAT.",13,10
badflen equ $-badfmsg
obuffer dw ?
obuflen equ 128
fatbuf dw ?
fatlen dw ?
ufatbuf dw ?
curdisk db ? ; 0=A, 1=B, etc
cl_size dw ? ; how many sectors in a cluster (<256)
cl_ct dw ? ; how many clusters
secsize dw ? ; bytes per sector
data_sector_1 dw ? ; sector number of first data sector
max_col equ 4
cur_col db ? ; how many 5-column things we have left in row
cur_cl dw ? ; what cluster we're examining
main proc near
call _args
mov cx, obuflen
call new
mov obuffer, bx
mov ah, 19h
int 21h
mov curdisk, al
mov ah, 1ch
mov dl, al ; get info for current drive
inc dl ; 0 = default here
int 21h
push cx ; bytes/sec
push dx ; clusters
mov ah, 0
mov es:cl_size, ax
push ax ; sec/cluster
mov al, byte ptr [bx] ; media ID byte
push ax
push cs
pop ds ; restore DS!!!!
mov secsize, cx
mov cl_ct, dx
mov al, curdisk
add al, 'A'
push ax ; drive number
mov ax, offset fmt1
push ax ; format string
push obuffer ; output buffer
call sprintf
add sp, 14 ; pop off arguments
mov di, obuffer
call strlen
; number of bytes to write in CX
mov dx, obuffer
mov bx, stdout
mov ah, 40h ; write to stdout
int 21h
; write bad cluster table heading to stdout
mov dx, offset msg2
mov cx, msg2l
mov bx, stdout
mov ah, 40h
int 21h
; figure out how big FAT is
; cl_ct contains number of clusters in disk
; uncompressed FAT size in bytes = 2 * cl_ct
mov cx, cl_ct
shl cx, 1 ; cx = # of bytes in FAT
mov fatlen, cx
call new
mov fatbuf, bx
mov ufatbuf, bx ; used if > 4086 clusters
; If number of clusters <= 4086, allocate a second buffer for
; the compressed FAT.
cmp cl_ct, 4086
ja noalloc
mov cx, cl_ct
shr cx, 1
add cx, cl_ct
call new
mov ufatbuf, bx
noalloc:
; figure out how many sectors
mov dx, 0
mov ax, fatlen
div secsize
or dx, dx ; remainder?
jz norem
inc ax
norem: ; AX is number of sectors in FAT
; Now calculate logical sector number of first data area
; (first sector after two copies of FAT)
mov cx, ax
shl cx, 1 ; two copies
inc cx
mov data_sector_1, cx
; now read FAT sectors into ufatbuf
mov cx, ax
mov dx, 1 ; FAT is at sector 1
mov al, curdisk
mov bx, ufatbuf
int 25h
jnc goodfatread
jmp badfatread
goodfatread:
add sp, 2 ; pop off flags
; Uncompress FAT if number of clusters <= 4086
cmp cl_ct, 4086
ja dontunc
; Do two at a time, or you will fry your brain.
mov si, ufatbuf
mov di, fatbuf
mov cx, cl_ct
uncloop: lodsw
mov bh, ah
and ah, 0fh
; Check for bad sector marks.
cmp ax, 0ff0h
jb unc1
or ah, 0f0h
unc1:
stosw
dec cx
jz uncdone
; Low 4 bits now in high 4 bits of bh
lodsb ; high 8 bits in AL
mov ah, bh
rol ax,1
rol ax,1
rol ax,1
rol ax,1
and ah, 0fh
; Check for bad sector marks.
cmp ax, 0ff0h
jb unc2
or ah, 0f0h
unc2:
stosw
loop uncloop
uncdone:
dontunc:
; Loop through FAT, looking for bad clusters
mov si, fatbuf
mov cur_cl,0
mov cur_col, max_col
lloop: lodsw
cmp ax, 0fff7h
jnz lskip
push si
; sprintf(obuffer, hexfmt, cur_cl, cur_sect);
mov ax, cur_cl
; convert cluster to sector number
sub ax, 2
mul cl_size ; times sectors per cluster
add ax, data_sector_1 ; +logical sect of data area
push ax
push cur_cl
mov ax, offset hexfmt
; Check number of columns; do a newline if needed.
dec cur_col
jnz l_okycol
mov cur_col, max_col
mov ax, offset hexnlfmt
l_okycol:
push ax
push obuffer
call sprintf
add sp,8
mov di, obuffer
call strlen
mov dx, obuffer
mov bx, stdout
mov ah, 40h
int 21h
pop si
lskip:
inc cur_cl
mov ax, cur_cl
cmp ax, cl_ct
jnz lloop
mov dx, offset byemsg
mov cx, byelen
mov bx, stdout
mov ah, 40h
int 21h
; all done
mov ax, 4c00h
int 21h
badfatread:
add sp, 2
mov dx, offset badfmsg
mov cx, badflen
mov bx, stderr
mov ah, 40h
int 21h ; complain
mov ax, 4c01h ; exit with error=1
int 21h
main endp
code ends
end _main