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 >
Assembly Source File  |  1986-06-02  |  8KB  |  290 lines

  1. ;------ findbad.asm --------------------------------------------------------
  2. ; Program to read FAT table and print it out.
  3. ; Preliminary to the disk scanning bad block checking program.
  4. ; (Actually, test of pcwrite editor, but I won't tell anyone if you won't.)
  5. ;
  6. ; Uses INT 25H "Absolute Disk Read", as there is no other way to do it.
  7. ;
  8. ; Daniel (too much time on my hands) Kegel
  9. ;
  10. ;---------------------------------------------------------------------------
  11.  
  12. stdin   equ     0
  13. stdout  equ     1
  14. stderr  equ     2
  15.  
  16.         extrn   sprintf:near
  17.         extrn   strlen:near
  18.         extrn   _args:near, argc:word, argv:word
  19.         extrn   new:near
  20.  
  21. code    segment para public 'CODE'
  22.         assume cs:code, ds:code
  23.  
  24.         org     100h
  25.  
  26. _main   proc    near
  27.         jmp     main
  28. _main   endp
  29.  
  30.         ; Copyright message
  31.         db      27, "[2J"
  32.         db      "findbad (C) 1985 by Yoyodyne, Inc. (a growing excited"
  33.         db      " company)", 0dh, 0ah, 1ah
  34.  
  35.         ; variables (assembler hates forward refs on these, so they're here)
  36.  
  37. byemsg: db      13, 10, "Completely done.", 13, 10
  38. byelen  equ     $-byemsg
  39.  
  40. fmt1:   db      "Disk %c:  Media id byte %x, %d sec/cluster, %d clusters, %d bytes/sec\n\O"
  41. msg2:   db      "Bad cluster (sector) numbers, in decimal:", 13, 10
  42. msg2l   equ     $-msg2
  43. hexfmt: db      "%5d (%-5d)  \O"
  44. hexnlfmt:
  45.         db      "%5d (%-5d)\n\O"
  46.  
  47. badfmsg:        db      "Read error on FAT.",13,10
  48. badflen equ     $-badfmsg
  49.  
  50. obuffer dw      ?
  51. obuflen equ     128
  52.  
  53. fatbuf  dw      ?
  54. fatlen  dw      ?
  55. ufatbuf dw      ?
  56.  
  57. curdisk db      ?       ; 0=A, 1=B, etc
  58. cl_size dw      ?       ; how many sectors in a cluster (<256)
  59. cl_ct   dw      ?       ; how many clusters
  60. secsize dw      ?       ; bytes per sector
  61.  
  62. data_sector_1   dw      ?       ; sector number of first data sector
  63.  
  64. max_col         equ     4
  65. cur_col         db      ?       ; how many 5-column things we have left in row
  66. cur_cl          dw      ?       ; what cluster we're examining
  67.  
  68. main    proc    near
  69.  
  70.         call    _args
  71.  
  72.         mov     cx, obuflen
  73.         call    new
  74.         mov     obuffer, bx
  75.  
  76.         mov     ah, 19h
  77.         int     21h
  78.         mov     curdisk, al
  79.  
  80.         mov     ah, 1ch
  81.         mov     dl, al                  ; get info for current drive
  82.         inc     dl                      ; 0 = default here
  83.         int     21h
  84.         
  85.         push    cx                      ; bytes/sec
  86.         push    dx                      ; clusters
  87.         mov     ah, 0
  88.         mov     es:cl_size, ax
  89.         push    ax                      ; sec/cluster
  90.  
  91.         mov     al, byte ptr [bx]       ; media ID byte
  92.         push    ax
  93.  
  94.         push    cs
  95.         pop     ds                      ; restore DS!!!!
  96.         
  97.         mov     secsize, cx
  98.         mov     cl_ct, dx
  99.  
  100.         mov     al, curdisk
  101.         add     al, 'A'
  102.         push    ax                      ; drive number
  103.         mov     ax, offset fmt1
  104.         push    ax                      ; format string
  105.         push    obuffer                 ; output buffer
  106.  
  107.         call    sprintf
  108.         add     sp, 14                  ; pop off arguments
  109.  
  110.         mov     di, obuffer
  111.         call    strlen
  112.         ; number of bytes to write in CX
  113.  
  114.         mov     dx, obuffer
  115.         mov     bx, stdout
  116.         mov     ah, 40h                 ; write to stdout
  117.         int     21h
  118.  
  119.         ; write bad cluster table heading to stdout
  120.         mov     dx, offset msg2
  121.         mov     cx, msg2l
  122.         mov     bx, stdout
  123.         mov     ah, 40h
  124.         int     21h
  125.  
  126.         ; figure out how big FAT is
  127.         ; cl_ct contains number of clusters in disk
  128.         ; uncompressed FAT size in bytes = 2 * cl_ct
  129.         mov     cx, cl_ct
  130.         shl     cx, 1           ; cx = # of bytes in FAT
  131.  
  132.         mov     fatlen, cx
  133.         call    new
  134.         mov     fatbuf, bx
  135.         mov     ufatbuf, bx     ; used if > 4086 clusters
  136.  
  137.         ; If number of clusters <= 4086, allocate a second buffer for
  138.         ; the compressed FAT.
  139.         cmp     cl_ct, 4086
  140.         ja      noalloc
  141.                 mov     cx, cl_ct
  142.                 shr     cx, 1
  143.                 add     cx, cl_ct
  144.                 call    new
  145.                 mov     ufatbuf, bx
  146. noalloc:
  147.  
  148.         ; figure out how many sectors
  149.         mov     dx, 0
  150.         mov     ax, fatlen
  151.         div     secsize
  152.         or      dx, dx          ; remainder?
  153.         jz      norem
  154.                 inc     ax
  155. norem:  ; AX is number of sectors in FAT
  156.         ; Now calculate logical sector number of first data area
  157.         ; (first sector after two copies of FAT)
  158.         mov     cx, ax
  159.         shl     cx, 1           ; two copies
  160.         inc     cx
  161.         mov     data_sector_1, cx
  162.  
  163.         ; now read FAT sectors into ufatbuf
  164.         mov     cx, ax
  165.         mov     dx, 1           ; FAT is at sector 1
  166.         mov     al, curdisk
  167.         mov     bx, ufatbuf
  168.         int     25h
  169.         jnc     goodfatread
  170.         jmp     badfatread
  171. goodfatread:
  172.         add     sp, 2           ; pop off flags
  173.  
  174.         ; Uncompress FAT if number of clusters <= 4086
  175.         cmp     cl_ct, 4086
  176.         ja      dontunc
  177.                 ; Do two at a time, or you will fry your brain.
  178.                 mov     si, ufatbuf
  179.                 mov     di, fatbuf
  180.                 mov     cx, cl_ct
  181. uncloop:                lodsw
  182.                         mov     bh, ah
  183.                         and     ah, 0fh
  184.                         ; Check for bad sector marks.
  185.                         cmp     ax, 0ff0h
  186.                         jb      unc1
  187.                                 or      ah, 0f0h
  188. unc1:
  189.                         stosw
  190.                         dec     cx
  191.                         jz      uncdone
  192.                         ; Low 4 bits now in high 4 bits of bh
  193.                         lodsb           ; high 8 bits in AL
  194.                         mov     ah, bh
  195.                         rol     ax,1
  196.                         rol     ax,1
  197.                         rol     ax,1
  198.                         rol     ax,1
  199.                         and     ah, 0fh
  200.                         ; Check for bad sector marks.
  201.                         cmp     ax, 0ff0h
  202.                         jb      unc2
  203.                                 or      ah, 0f0h
  204. unc2:
  205.                         stosw
  206.                         loop    uncloop
  207. uncdone:
  208. dontunc:
  209.  
  210.         ; Loop through FAT, looking for bad clusters
  211.         mov     si, fatbuf
  212.         mov     cur_cl,0
  213.         mov     cur_col, max_col
  214.  
  215. lloop:  lodsw
  216.         cmp     ax, 0fff7h
  217.         jnz     lskip
  218.                 push    si
  219.  
  220.                 ; sprintf(obuffer, hexfmt, cur_cl, cur_sect);
  221.                 mov     ax, cur_cl
  222.                 ; convert cluster to sector number
  223.                 sub     ax, 2
  224.                 mul     cl_size                 ; times sectors per cluster
  225.                 add     ax, data_sector_1       ; +logical sect of data area
  226.                 push    ax
  227.  
  228.                 push    cur_cl
  229.                 mov     ax, offset hexfmt
  230.                 ; Check number of columns; do a newline if needed.
  231.                 dec     cur_col
  232.                 jnz     l_okycol
  233.                         mov     cur_col, max_col
  234.                         mov     ax, offset hexnlfmt
  235. l_okycol:
  236.                 push    ax
  237.                 push    obuffer
  238.                 call    sprintf
  239.                 add     sp,8
  240.  
  241.                 mov     di, obuffer
  242.                 call    strlen
  243.                 mov     dx, obuffer
  244.                 mov     bx, stdout
  245.                 mov     ah, 40h
  246.                 int     21h
  247.  
  248.                 pop     si
  249. lskip:
  250.         inc     cur_cl
  251.         mov     ax, cur_cl
  252.         cmp     ax, cl_ct
  253.         jnz     lloop
  254.  
  255.         mov     dx, offset byemsg
  256.         mov     cx, byelen
  257.         mov     bx, stdout
  258.         mov     ah, 40h
  259.         int     21h
  260.  
  261.         ; all done
  262.         mov     ax, 4c00h
  263.         int     21h
  264.  
  265. badfatread:
  266.         add     sp, 2
  267.         mov     dx, offset badfmsg
  268.         mov     cx, badflen
  269.         mov     bx, stderr
  270.         mov     ah, 40h
  271.         int     21h             ; complain
  272.  
  273.         mov     ax, 4c01h       ; exit with error=1
  274.         int     21h
  275.  
  276.  
  277. main    endp
  278.  
  279.         code    ends
  280.  
  281.         end     _main
  282.  
  283.  
  284.  
  285.  
  286.  
  287.  
  288.  
  289.  
  290.