home *** CD-ROM | disk | FTP | other *** search
/ Power-Programmierung / CD1.mdf / assemblr / library / asm_kit / findbad.asm < prev    next >
Assembly Source File  |  1985-11-08  |  8KB  |  402 lines

  1. title scavenge Copyright (c) T. Jennings 1983
  2. ;
  3. ;****************************************
  4. ;*                    *
  5. ;*        SCAVENGE        *
  6. ;*                    *
  7. ;*    Mark bad blocks on MSDOS     *
  8. ;*    as allocated in the FAT.    *
  9. ;*                    *
  10. ;*    T. Jennings 5 June 82        *
  11. ;*      created 15 Sept. 82        *
  12. ;*                    *
  13. ;****************************************
  14. ;
  15. ;Reads all sectors in logical MSDOS blocks
  16. ;and marks the file allocation tables such
  17. ;that the blocks are permanently allocated
  18. ;where CHKDSK will not deallocate them.
  19. ;
  20. ;
  21. ;This version works on any 2.xx MSDOS or
  22. ;PCDOS, on any media type, fixed or removable.
  23. ;One (major) limitation: it will not map out
  24. ;blocks that are already allocated to a file;
  25. ;it will say "block used", but won't tell you
  26. ;which file it is in.
  27. ;
  28. ;If SCAVENGE finds any bad blocks, it will ask
  29. ;you whether or not you want the disk updated.
  30. ;You can safely run it just to see if the disk 
  31. ;is OK.
  32. ;
  33. ;MASM, LINK, then EXE2BIN this to make a COM
  34. ;file. It will not run as an EXE file. NOTE:
  35. ;LINK will give you a 'Warning: no STACK 
  36. ;segment' error: ignore it.
  37. ;
  38. cr    equ    0dh
  39. lf    equ    0ah
  40. page
  41. cgroup group code
  42. code segment byte public 'code'
  43. assume cs:cgroup,ds:cgroup,ss:cgroup
  44. ;
  45. ;MSDOS page 0 stuff.
  46. ;
  47.     org    5ch
  48. tfcb label byte
  49.  
  50.     org    80h
  51. tbuff label byte
  52.  
  53.     org    100h
  54. scavenge:
  55.     jmp    start
  56. ;
  57. ;Disk parameters:
  58. ;
  59. blkcnt    dw    (?)    ;blocks this disk
  60. blksize    dw    (?)    ;sectors per block
  61. secsize    dw    (?)    ;phys. sector size
  62. badcnt    dw    (?)    ;# bad blocks found
  63. newbad    dw    (?)    ;new bad ones
  64. block    dw    (?)    ;current block
  65. sector    dw    (?)    ;sector to read
  66. disk    db    (?)    ;selected disk
  67. curdsk    db    (?)    ;current disk.
  68. fatsec    dw    (?)    ;1st FAT sector,
  69. fatcnt    dw    (?)    ;FAT sec count.
  70.  
  71.     dw 128 dup (?)
  72. stack    dw    (?)    ;what else
  73. page
  74. ;
  75. ;Say who we are, describe the disk we are
  76. ;about to fix, ask to continue or abort.
  77. ;
  78. start:    mov    ax,cs
  79.     mov    ds,ax
  80.     mov    ss,ax
  81.     mov    sp,offset stack
  82.  
  83.     mov    dx,offset signon
  84.     call    pstr
  85.     call    setup        ;get disk stuff
  86.     jnc    st1
  87.         call    pstr
  88.         int    32    ;error.
  89.  
  90. st1:    call    liststat    ;describe dsk
  91.     mov    dx,offset contstr
  92.     call    pstr        ;type any key..
  93.     call    ina
  94. ;
  95. ;Find all the bad blocks, if any, display them,
  96. ;ask if we should update the FAT. If so, write
  97. ;it out.
  98. ;
  99.     mov    dx,offset crlf
  100.     call    pstr
  101.     call    findbad        ;map bad,
  102.     call    listbad        ;list them,
  103.     cmp    newbad,0    ;if new bad
  104.     je    st2        ;blocks...
  105.  
  106.     mov    dx,offset updstr ;ask if we
  107.     call    pstr        ;should update
  108.     call    ina
  109.     and    al,5fh
  110.     cmp    al,'Y'
  111.     jne    st2
  112.     mov    al,disk        ;write out the
  113.     mov    dx,fatsec    ;FAT,
  114.     mov    cx,fatcnt
  115.     mov    bx,offset fatbuf
  116.     int    26h
  117.     pop    ax        ;pop flags
  118.  
  119. st2:    mov    al,curdsk    ;reselect the
  120.     call    seldsk        ;original disk
  121.     int    32
  122.  
  123. signon    db    cr,lf,'DOS version 2 Bad Sector Mapper'
  124.     db    cr,lf,'  T. Jennings 5 June 83'
  125.     db    '$'
  126. contstr    db    cr,lf,'Type ^C to abort, any '
  127.     db    'other key to continue: $'
  128. updstr    db    cr,lf,lf,' Want the disk updated? [y,n] :$'
  129. crlf    db    cr,lf,'$'
  130. page
  131. ;
  132. ;Get the data on the specified disk. Return 
  133. ;carry if no drive specified. Returns ES:DI
  134. ;pointing to the FAT for the selected drive.
  135. ;
  136. setup:    call    initdsk        ;reset dsk sys,
  137.     call    getdsk        ;get current,
  138.     mov    curdsk,al    ;save it,
  139.     mov    al,tfcb        ;make sure a
  140.     cmp    al,0        ;new one spec'd
  141.     stc            ;quit if none,
  142.     mov    dx,offset strstr
  143.     jz    gd1
  144.     dec    al        ;make 0-N,
  145.     mov    disk,al
  146.     call    seldsk        ;select,
  147.  
  148.     push    ds        ;save local DS,
  149.     mov    ah,1bh
  150.     int    33
  151.     pop    ds
  152.     mov    blkcnt,dx    ;save # blocks,
  153.     mov    secsize,cx    ;sector size,
  154.     mov    ah,0
  155.     mov    blksize,ax    ;secs/block.
  156.  
  157.     push    ds        ;now get the
  158.     mov    dl,disk
  159.     inc    dl        ;drive 1=A, b=2
  160.     mov    ah,50        ;FAT,
  161.     int    33        ;get the DPB,
  162.     mov    cx,[bx+15]    ;CX= sec count,
  163.     mov    ch,0
  164.     mov    dx,[bx+6]    ;DX= 1st sec,
  165.     pop    ds
  166.     mov    fatcnt,cx    ;save both,
  167.     mov    fatsec,dx
  168.  
  169.     mov    al,disk        ;AL= drive #,
  170.     mov    bx,offset fatbuf ;DS:BX= buffer
  171.     int    25h        ;read the FAT,
  172.     pop    ax        ;pop flags
  173.     mov    dx,offset bscstr
  174. gd1:    ret
  175. strstr    db    cr,lf,'Must specify a disk drive.$'
  176. bscstr    db    cr,lf,'Bad FAT sector: disk not useable.$'
  177.  
  178. page
  179. ;
  180. ;Read the entire disk looking for bad blocks.
  181. ;When one is found, go mark it as an allocated
  182. ;bad block.
  183. ;
  184. findbad:
  185.     mov    block,0        ;1st block,
  186.     mov    badcnt,0    ;none yet,
  187.  
  188. fb1:    mov    dx,offset blkstr ;type 'block '
  189.     call    pstr
  190.     mov    bx,block    ;block number,
  191.     call    outdec
  192.     call    readblk        ;read a block,
  193.     jnc    fb3        ;if bad, 
  194.     inc    badcnt        ;count it,
  195.     mov    dx,offset badstr
  196.     call    pstr        ;type 'bad'
  197.     call    mapout        ;mark bad,
  198.     mov    dx,offset cntstr ;error if cant
  199.     jc    fb2
  200.     add    newbad,cx    ;count it,
  201.     mov    dx,offset alrstr
  202.     jcxz    fb2        ;already markd
  203.     mov    dx,offset mrkstr
  204. fb2:    call    pstr
  205. fb3:    inc    block        ;next block,
  206.     dec    blkcnt        ;another...
  207.     jnz    fb1        ;keep looking.
  208.     ret
  209.  
  210.  
  211. blkstr    db    cr,'Block $'
  212. badstr    db    ' bad,$'
  213. alrstr    db    ' already marked.',cr,lf,'$'
  214. mrkstr    db    ' mapped out.',lf,'$'
  215. cntstr    db    ' already used! I dont know'
  216.     db    ' which file.',lf,'$'
  217. page
  218. ;
  219. ;Mark the current block as bad in the FAT.
  220. ;Multiply the block number by 1.5 to find the
  221. ;block number, (actually *3, /2) and if not
  222. ;used, mark it bad. If used, report which file
  223. ;it's in. If it's already mapped as bad, 
  224. ;return CX =0, else return CX=1.
  225. ;
  226. mapout:
  227.     mov    bx,block    ;block,
  228.     shl    bx,1        ;times 2,
  229.     add    bx,block    ;times 3,
  230.     shr    bx,1        ;divide by 2,
  231.     mov    ax,fatbuf[bx]    ;get word,
  232. ;
  233. ;If carry is set, we want the high 12 bits in
  234. ;the word in AX, else the low 12 bits. Set CH
  235. ;as the shift count, DX as the mask.
  236. ;
  237.     mov    ch,0        ;assume low,
  238.     mov    dx,0fffh
  239.     jnc    mo1
  240.     mov    ch,4        ;else high 12,
  241.     mov    dx,0fff0h
  242. mo1:    and    ax,dx        ;mask it,
  243.     mov    cl,ch
  244.     shr    ax,cl        ;shift it,
  245. ;
  246. ;AX is the block number; if it's anything
  247. ;but 000 or ff7, return with carry set, 
  248. ;indicating that its already used.
  249. ;
  250.     cmp    ax,0ff7h    ;if ff7,
  251.     je    mo2        ;already marked
  252.     cmp    ax,0        ;if allocated,
  253.     je    mo3
  254.     stc            ;error!
  255. mo2:    mov    cx,0        ;none mapped,
  256.     ret
  257. ;
  258. ;Bad unused block. Mark as bad in the FAT.
  259. ;
  260. mo3:    mov    ax,0ff7h    ;marker,
  261.     mov    cl,ch
  262.     shl    ax,cl        ;shift it,
  263.     or    fatbuf[bx],ax    ;mark it.
  264.     mov    cx,1        ;1 mapped,
  265.     ret
  266. page
  267. ;
  268. ;Read one block, return carry set if read
  269. ;error. Leave the useless data in the buffer
  270. ;following the end of this program.
  271. ;
  272. readblk:
  273.     mov    ax,block    ;find start
  274.     mov    cx,blksize    ;sector,
  275.     mul    cx        ;CX= count,
  276.     mov    dx,ax        ;DX= sector,
  277.     mov    al,disk
  278.     mov    bx,offset blkbuf ;our buffer,
  279.     int    25h        ;read sectors,
  280.     pop    dx        ;pop flags,
  281.     ret
  282. page
  283. ;
  284. ;List the general info on the disk, like
  285. ;sector sizes, etc.
  286. ;
  287. liststat:
  288.     mov    dx,offset st1str
  289.     call    pstr
  290.     mov    al,disk
  291.     add    al,'A'
  292.     call    outa
  293.     mov    dx,offset st2str
  294.     call    pstr
  295.     mov    bx,blkcnt
  296.     call    outdec
  297.     mov    dx,offset st3str
  298.     call    pstr
  299.     ret
  300.  
  301. ;Disk A:, total of 12345 data blocks.
  302.  
  303. st1str    db cr,lf,'Disk $'
  304. st2str    db ':, total of $'
  305. st3str    db ' data blocks.$'
  306. ;
  307. ;List out the bad things about this disk.
  308. ;
  309. listbad:
  310.     mov    dx,offset bd1str
  311.     call    pstr
  312.     mov    bx,badcnt
  313.     call    outdec
  314.     mov    dx,offset bd2str
  315.     call    pstr
  316.     mov    bx,newbad
  317.     call    outdec
  318.     mov    dx,offset bd3str
  319.     call    pstr
  320.     ret
  321.  
  322. ;Total of 12345 bad blocks, found 12234 more this pass.
  323. bd1str    db cr,'Total of $'        ;note no linefeed.
  324. bd2str    db ' bad blocks, found $'
  325. bd3str    db ' more this pass.$'
  326. page
  327. ;
  328. ;Generally useful system calls.
  329. ;
  330. pstr:    mov    ah,9
  331.     int    33
  332.     ret
  333. ;
  334. ;Type BX in decimal, suppressing leading
  335. ;zeros.
  336. ;
  337. outdec:    mov    cl,0    ;0 suppress flag,
  338.     mov    dx,10000
  339.     call    rsdiv
  340.     mov    dx,1000
  341.     call    rsdiv
  342.     mov    dx,100
  343.     call    rsdiv
  344.     mov    dx,10
  345.     call    rsdiv
  346.     mov    ch,bl
  347.     jmp    odf
  348.  
  349. rsdiv:    mov    ch,-1    ;iteration -1,
  350. rs1:    inc    ch    ;count,
  351.     sub    bx,dx    ;subtract,
  352.     jnc    rs1    ;til underflow,
  353.     add    bx,dx    ;adjust back,
  354.     cmp    ch,0    ;if non-zero,
  355.     jne    odf    ;type it,
  356.     test    cl,1    ;dont type 0's
  357.     jnz    odf    ;if leading,
  358.     ret
  359.  
  360. odf:    push    dx
  361.     mov    dl,ch
  362.     add    dl,'0'    ;ASCII,
  363.     mov    ah,2
  364.     int    33
  365.     pop    dx
  366.     mov    cl,1    ;no suppress,
  367.     ret
  368. page
  369. ;
  370. ;More system calls.
  371. ;
  372. seldsk:    mov    dl,al        ;select disk,
  373.     mov    ah,0eh
  374.     int    33
  375.     ret
  376.  
  377. getdsk:    mov    ah,19h
  378.     int    33
  379.     ret
  380.  
  381. initdsk:mov    ah,0dh
  382.     int    33
  383.     ret
  384.  
  385. ina:    mov    ah,0ch        ;char in with
  386.     mov    al,1        ;flush.
  387.     int    33
  388.     ret
  389.  
  390. outa:    mov    dl,al
  391.     mov    ah,2
  392.     int    33
  393.     ret
  394.  
  395. blkbuf    db 16384 dup (?)    ;cluster buffer
  396.  
  397. fatbuf label word        ;FAT buffer.
  398.  
  399. code ends
  400.  
  401.     end    scavenge
  402.