home *** CD-ROM | disk | FTP | other *** search
/ Shareware Supreme Volume 6 #1 / swsii.zip / swsii / 165 / SCAV31.ZIP / SCAV31.ASM < prev    next >
Assembly Source File  |  1988-10-06  |  13KB  |  541 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. ;*    Modified 14 December 1984    *
  13. ;*        by David Gwillim        *
  14. ;*                    *
  15. ;*                    *
  16. ;****************************************
  17. ;
  18. ;See SCAV31.DOC for details on functioning, updates, etc.    v3.01
  19. ;
  20. ;Reads all sectors in logical MSDOS blocks
  21. ;and marks the file allocation tables such
  22. ;that the blocks are permanently allocated
  23. ;where CHKDSK will not deallocate them.
  24. ;
  25. ;
  26. ;This version works on any 2.xx MSDOS or
  27. ;PCDOS, on any media type, fixed or removable.
  28. ;One (major) limitation: it will not map out
  29. ;blocks that are already allocated to a file;
  30. ;it will say "block used", but won't tell you
  31. ;which file it is in.
  32. ;
  33. ;If SCAVENGE finds any bad blocks, it will ask
  34. ;you whether or not you want the disk updated.
  35. ;You can safely run it just to see if the disk 
  36. ;is OK.
  37. ;
  38. ;Enter 'Q' at any time to abort the run.            v3.01
  39.  
  40. ;MASM, LINK, then EXE2BIN this to make a COM
  41. ;file. It will not run as an EXE file. NOTE:
  42. ;LINK will give you a 'Warning: no STACK 
  43. ;segment' error: ignore it.
  44. ;
  45.  
  46. ;v3.01
  47. ; - Slight tweaking, reformatting.
  48. ; - v3.00 forced DS, SS to CS; unnecessary.
  49. ; - v3.00 had its own stack; unnecessary.
  50. ; - Removed some system functions, placing them inline.
  51. ; - Separated extensive documentation into separate file,
  52. ;   SCAVENGE.DOC.
  53. ; - No functional changes.
  54. ; David Kirschbaum
  55. ; Toad Hall
  56. ; kirsch@braggvax.ARPA
  57.  
  58. CR    equ    0dh
  59. LF    equ    0ah
  60. PutStr    macro            ;                v3.01
  61.     mov    ah,9
  62.     int    21h
  63.     endm
  64.  
  65. ;Beep procedure count values
  66. ;---------------------------
  67. ;To generate a given freqency note out of the speaker with the Beep procedure
  68. ;on the PC using Channel 2 of the 8253 timer, the channel 2 count register
  69. ;must be loaded with a value such that the 8253 input clock frequency
  70. ;(1.19318 MHz) divided by the count figure equals the audio frequency.
  71.  
  72. F176HZ    equ    6779    ; 176 Hz count value
  73. F352HZ    equ    3390    ; 352 Hz count value
  74. F704HZ    equ    1695    ; 704 Hz count value
  75. F1408HZ    equ    847    ; 1408 Hz count value
  76.  
  77. page
  78. Cseg    segment para public 'code'
  79.     assume CS:Cseg, DS:Cseg, ES:Cseg, SS:Cseg
  80. ;
  81. ;MSDOS PSP stuff.
  82. ;
  83.     org    5ch
  84. tfcb    label byte
  85.  
  86.     org    80h
  87. tbuff    label byte
  88.  
  89.     org    100h
  90.  
  91. Scavenge    proc    near
  92.     jmp    Start
  93. ;
  94. ;Disk parameters:
  95. ;
  96. blkcnt    dw    0    ;blocks this disk
  97. blksize    dw    0    ;sectors per block
  98. secsize    dw    0    ;phys. sector size
  99. badcnt    dw    0    ;# bad blocks found
  100. newbad    dw    0    ;new bad ones
  101. block    dw    0    ;current block
  102. sector    dw    0    ;sector to read
  103. disk    db    0    ;selected disk
  104. curdsk    db    0    ;current disk.
  105. fatsec    dw    0    ;1st FAT sector,
  106. fatcnt    dw    0    ;FAT sec count.
  107.  
  108. ;    dw 128 dup 0
  109. ;stack    dw    0    ;what else
  110. ;    db    16 dup('STACK    ')
  111. ;stack    equ    $
  112. Scavenge    endp
  113. page
  114. ;
  115. ;Say who we are, describe the disk we are
  116. ;about to fix, ask to continue or abort.
  117. ;
  118. Start    proc    near
  119. ;    cli            ;Disable interrupts while we move stack
  120. ;    mov    sp,offset stack
  121. ;    sti            ;Re-enable interrupts
  122.     mov    dx,offset signon
  123.     PutStr
  124.  
  125.     mov    bx,F176HZ    ;Alert user audibly
  126.     call    Beep
  127.     mov    bx,F704HZ
  128.     call    Beep
  129.     mov    bx,F352HZ
  130.     call    Beep
  131.     mov    bx,F1408HZ
  132.     call    Beep
  133.  
  134.     mov    ax,0C08H    ;flush, char in with no echo    v3.01
  135.     int    21h
  136.     or    al,20h        ;Make character lower case
  137.     cmp    al,'q'        ;Quit?
  138.     jne    St0
  139.      mov    dx,offset abort
  140.      jmp    short Msg_Exit    ;display, terminate        v3.01
  141.  
  142. St0:    call    SetUp        ;get disk stuff
  143.     jnc    St1        ;went ok
  144. Msg_Exit:            ;                v3.01
  145.      PutStr
  146.      int    20h        ;error, terminate.
  147.  
  148. St1:    call    ListStat    ;describe dsk
  149. ;
  150. ;Find all the bad blocks, if any, display them,
  151. ;ask if we should update the FAT. If so, write
  152. ;it out.
  153. ;
  154.     mov    dx,offset crlf    ;new line
  155.     PutStr
  156.     call    FindBad        ;map bad,
  157.     call    ListBad        ;list them,
  158.     cmp    newbad,0    ;if new bad
  159.     je    St2        ;blocks...
  160.  
  161.     mov    dx,offset updstr    ;ask if we
  162.     PutStr                ;should update
  163.     mov    ax,0C08H        ;flush, char in with no echo    v3.01
  164.     int    21h
  165.     and    al,5fh            ;uppercase
  166.     mov    dx,offset noupdte    ;assume no update    v3.01
  167.     cmp    al,'Y'
  168.     jne    St1B            ;nope, no update
  169.      mov    al,disk            ;write out the
  170.      mov    dx,fatsec        ;FAT,
  171.      mov    cx,fatcnt
  172.      mov    bx,offset fatbuf
  173.      int    26h
  174.      pop    ax            ;pop flags after Int 26H
  175.      mov    dx,offset update    ;fall thru to        v3.01
  176.  
  177. St1B:    PutStr                ;display msg        v3.01
  178. St2:
  179.     mov    dl,curdsk    ;reselect the original disk    v3.01
  180.     mov    ah,0eh        ;                v3.01
  181.     int    21h        ;                v3.01
  182.     int    20h        ;terminate
  183.  
  184. signon    db    CR,LF,9,'*********************************************'
  185.     db    CR,LF,9,'* DOS 2.xx Bad Sector Mapper - Version 3.01 *'
  186.     db    CR,LF,9,'* Updated by David Gwillim 18 December 1984 *'
  187.     db    CR,LF,9,'*        Again by Toad Hall, 6 Oct 88       *'
  188.     db    CR,LF,9,'* Original program by T. Jennings 5 June 83 *'
  189.     db    CR,LF,9,'*********************************************'
  190.     db    CR,LF,LF
  191.     db    'Type Q to abort at any time, any other key to continue ...'
  192.     db    CR,LF,'$'
  193. updstr    db    CR,LF,LF,'Want the disk updated? [y,n] $'
  194. noupdte    db    CR,LF,LF,'FAT not updated',CR,LF,'$'
  195. update    db    CR,LF,LF,'FAT updated'
  196. crlf    db    CR,LF,'$'        ;share this        v3.01
  197. Start    endp
  198.  
  199. page
  200. ;
  201. ;Get the data on the specified disk. Return 
  202. ;carry if no drive specified. Returns ES:DI
  203. ;pointing to the FAT for the selected drive.
  204. ;
  205. SetUp    proc    near
  206.     mov    ah,0dh            ;reset disk system    v3.01
  207.     int    21h
  208.     mov    ah,19h            ;get current disk    v3.01
  209.     int    21h
  210.     mov    curdsk,al        ;save it,
  211.     mov    al,tfcb            ;make sure a
  212.     cmp    al,0            ;new one spec'd
  213.     stc                ;quit if none,
  214.     mov    dx,offset strstr    ;'Must specify disk drive' msg
  215.     jz    gd1            ;exit
  216.  
  217.     dec    al            ;make 0-N,
  218.     mov    disk,al
  219.     mov    dl,al            ;select disk,        v3.01
  220.     mov    ah,0eh
  221.     int    21h
  222.  
  223.     mov    di,DS            ;save our DS a sec    v3.01
  224.     mov    ah,1bh
  225.     int    21h
  226.     mov    DS,di            ;restore DS        v3.01
  227.     mov    blkcnt,dx        ;save # blocks,
  228.     mov    secsize,cx        ;sector size,
  229.     xor    ah,ah            ;clear msb        v3.01
  230.     mov    blksize,ax        ;secs/block.
  231.  
  232.     mov    di,DS            ;save DS a sec        v3.01
  233.     mov    dl,disk            ;now get the
  234.     inc    dl            ;drive 1=A, b=2
  235.     mov    ah,32h            ;FAT,
  236.     int    21h            ;get the DPB,
  237.  
  238.     mov    cx,[bx+15]        ;CX= sec count,
  239.     xor    ch,ch            ;clear msb        v3.01
  240.     mov    dx,[bx+6]        ;DX= 1st sec,
  241.     mov    DS,di            ;restore DS        v3.01
  242.     mov    fatcnt,cx        ;save both,
  243.     mov    fatsec,dx
  244.  
  245.     mov    al,disk            ;AL= drive #,
  246.     mov    bx,offset fatbuf    ;DS:BX= buffer
  247.     int    25h            ;read the FAT,
  248.     pop    ax            ;pop flags after Int 25H
  249.     mov    dx,offset bscstr    ;return with msg
  250. gd1:    ret
  251.  
  252. strstr    db    CR,LF,'Must specify a disk drive.$'
  253. bscstr    db    CR,LF,'Bad FAT sector: disk not useable.$'
  254.  
  255. SetUp    endp
  256.  
  257. page
  258. ;
  259. ;Read the entire disk looking for bad blocks.
  260. ;When one is found, go mark it as an allocated
  261. ;bad block.
  262. ;
  263. FindBad    proc    near
  264.     xor    ax,ax            ;get a handy 0        v3.01
  265.     mov    block,ax        ;1st block,
  266.     mov    badcnt,ax        ;none yet,
  267.  
  268. BlockLup:
  269.     call    KbdChk            ;QUIT char input from the keyboard?
  270.     jnc    FB1A            ;nope
  271.      mov    dx,offset abort        ;'Aborting program'
  272.      PutStr
  273.      ret
  274.  
  275. FB1A:    mov    dx,offset blkstr    ;type 'block '
  276.     PutStr
  277.     mov    bx,block        ;block number,
  278.     call    OutDec
  279.     call    ReadBlk            ;read a block,
  280.     jnc    Fb3            ;if bad, 
  281.     inc    badcnt            ;count it,
  282.     mov    dx,offset badstr
  283.     PutStr                ;type 'bad'
  284.     call    MapOut            ;mark bad,
  285.     mov    dx,offset cntstr    ;'Already used'
  286.     jc    Fb2            ;error if can't
  287.     add    newbad,cx        ;count it,
  288.     mov    dx,offset alrstr    ;'Already marked'
  289.     jcxz    Fb2            ;error if already marked
  290.      mov    dx,offset mrkstr    ;'mapped out'
  291.      mov    bx,F704HZ        ;Warn user audibly
  292.      call    Beep
  293.      mov    bx,F176HZ
  294.      call    Beep
  295. Fb2:    PutStr
  296.     mov    bx,F1408HZ        ;Warn user audibly
  297.     call    Beep
  298.     mov    bx,F176HZ
  299.     call    Beep
  300.  
  301. Fb3:    inc    block            ;next block,
  302.     dec    blkcnt            ;another...
  303.     jnz    BlockLup        ;keep looking.
  304.     ret
  305.  
  306.  
  307. blkstr    db    CR,'Block $'
  308. badstr    db    ' bad,$'
  309. alrstr    db    ' already marked.',CR,LF,'$'
  310. mrkstr    db    ' mapped out.',LF,'$'
  311. cntstr    db    " already used! I don't know which file.",LF,'$'
  312. abort    db    ' ... Aborting program',CR,LF,LF,'$'
  313.  
  314. FindBad    endp
  315. page
  316. ;
  317. ;Mark the current block as bad in the FAT.
  318. ;Multiply the block number by 1.5 to find the
  319. ;block number, (actually *3, /2) and if not
  320. ;used, mark it bad. If used, report which file
  321. ;it's in. If it's already mapped as bad, 
  322. ;return CX=0, else return CX=1.
  323. ;
  324. MapOut    proc    near
  325.     mov    bx,block        ;block,
  326.     shl    bx,1            ;first times 2,
  327.     add    bx,block        ;then add one to make times 3,
  328.     shr    bx,1            ;now divide by 2,
  329.     mov    ax,word ptr fatbuf[bx]    ;get word,
  330. ;
  331. ;If carry is set, we want the high 12 bits in
  332. ;the word in AX, else the low 12 bits. Set CH
  333. ;as the shift count, DX as the mask.
  334. ;
  335.     mov    ch,0            ;assume low,
  336.     mov    dx,0fffh
  337.     jnc    Mo1
  338.      mov    ch,4            ;else high 12,
  339.      mov    dl,0F0H            ;            v3.01
  340. Mo1:    and    ax,dx            ;mask it,
  341.     mov    cl,ch
  342.     shr    ax,cl            ;shift it,
  343. ;
  344. ;AX is the block number; if it's anything
  345. ;but 000 or ff7, return with carry set,
  346. ;indicating that it's already used.
  347. ;
  348.     cmp    ax,0ff7h        ;if ff7,
  349.     je    Mo2            ;already marked
  350.      or    ax,ax            ;if allocated        v3.01
  351.      je    Mo3
  352.     stc                ;error!
  353. Mo2:    mov    cx,0            ;none mapped,
  354.     ret
  355. ;
  356. ;Bad unused block. Mark as bad in the FAT.
  357. ;
  358. Mo3:    mov    ax,0ff7h        ;marker,
  359.     mov    cl,ch
  360.     shl    ax,cl            ;shift it,
  361.     or    word ptr fatbuf[bx],ax    ;mark it.
  362.     mov    cx,1            ;1 mapped,
  363.     ret
  364. MapOut    endp
  365. page
  366. ;
  367. ;Read one block, return carry set if read
  368. ;error. Leave the useless data in the buffer
  369. ;following the end of this program.
  370. ;
  371. ReadBlk    proc    near
  372.     mov    ax,block        ;find start
  373.     mov    cx,blksize        ;sector,
  374.     mul    cx            ;CX= count,
  375.     mov    dx,ax            ;DX= sector,
  376.     mov    al,disk
  377.     mov    bx,offset blkbuf    ;our buffer,
  378.     int    25h            ;read sectors,
  379.     pop    dx            ;pop flags after Int 25H
  380.     ret
  381. ReadBlk    endp
  382. page
  383. ;
  384. ;List the general info on the disk, like
  385. ;number of blocks, block size, FAT size & location, etc.
  386. ;
  387. ListStat    proc    near
  388.     mov    al,disk            ;disk nr        v3.01
  389.     add    al,'A'            ;asciify        v3.01
  390.     mov    st2str,al        ;stuff in string    v3.01
  391.     mov    dx,offset st1str    ;'Disk %: Total of '    v3.01
  392.     PutStr                ;display str        v3.01
  393.     mov    bx,blkcnt
  394.     call    OutDec1            ;we know >9        v3.01
  395.     mov    dx,offset st3str    ;'Data blocks'
  396.     PutStr
  397.     mov    ax,512
  398.     mul    blksize
  399.     mov    bx,ax
  400.     call    OutDec1            ;we know >9        v3.01
  401.     mov    dx,offset st4str    ;' bytes each'
  402.     PutStr
  403.     mov    bx,fatcnt
  404.     call    OutDec            ;probably <10        v3.01
  405.     mov    dx,offset st5str    ;' FAT sectors, first ...'
  406.     PutStr
  407.     mov    bx,fatsec
  408.     call    OutDec            ;display first FAT sector
  409.     mov    dx,offset crlf        ;CR,LF            v3.01
  410.     PutStr
  411.     ret
  412.  
  413. ;Disk A:  Total of 12345 data blocks 1024 bytes each.
  414.  
  415. st1str    db CR,LF,'Disk '        ;            v3.01
  416. st2str    db '%: Total of $'        ;            v3.01
  417. st3str    db ' data blocks $'
  418. st4str    db ' bytes each.',CR,LF,'$'
  419. st5str    db ' FAT sectors, first FAT sector is logical sector $'
  420. ListStat    endp
  421.  
  422. ;
  423. ;List out the bad things about this disk.
  424. ;
  425. ListBad    proc    near
  426.     mov    dx,offset bd1str    ;'Total of '
  427.     PutStr
  428.     mov    bx,badcnt
  429.     call    OutDec
  430.     mov    dx,offset bd2str    ;' bad blocks'        v3.01
  431.     PutStr
  432.     mov    dx,offset crlf        ;assume no bad blocks    v3.01
  433.     cmp    badcnt,0        ;no bad blocks yet?    v3.01
  434.     jz    NoBad            ;nope, display no more    v3.01
  435.      mov    dx,offset bd3str    ;', found '        v3.01
  436.      PutStr                ;            v3.01
  437.      mov    bx,newbad
  438.      call    OutDec
  439.      mov    dx,offset bd4str    ;' more this pass.'
  440. NoBad:    PutStr                ;            v3.01
  441.     ret
  442.  
  443. ;Total of 12345 bad blocks, found 12234 more this pass.
  444. bd1str    db CR,'Total of $'        ;note no linefeed.
  445. bd2str    db ' bad blocks$'
  446. bd3str    db ', found $'
  447. bd4str    db ' more this pass.',CR,LF,'$'
  448.  
  449. ListBad    endp
  450. page
  451. ;
  452. ;Type BX in decimal, suppressing leading zeros.
  453. ;
  454. OutDec    proc    near
  455.     cmp    bx,9            ;single digit?        v3.01
  456.     ja    OutDec1            ;nope            v3.01
  457.      mov    dl,bl            ;get single digit    v3.01
  458.      add    dl,'0'            ;asciify        v3.01
  459.      mov    ah,2            ;display char
  460.      int    21h            ;            v3.01
  461.      ret                ;            v3.01
  462.  
  463. OutDec1:
  464.     xor    cl,cl            ;0 suppress flag    v3.01
  465.     mov    dx,10000
  466.     call    RsDiv
  467.     mov    dx,1000
  468.     call    RsDiv
  469.     mov    dx,100
  470.     call    RsDiv
  471.     mov    dx,10
  472.     call    RsDiv
  473.     mov    ch,bl
  474.     jmp    short Odf
  475.  
  476. RsDiv:    mov    ch,-1        ;iteration -1,
  477. Rs1:    inc    ch        ;count,
  478.     sub    bx,dx        ;subtract,
  479.     jnc    Rs1        ;til underflow,
  480.     add    bx,dx        ;adjust back,
  481.     or    ch,ch        ;if non-zero            v3.01
  482.     jne    Odf        ;type it,
  483.      test    cl,1        ;don't type 0's
  484.      jz    OdX        ;if leading            v3.01
  485.  
  486. Odf:    push    dx
  487.     mov    dl,ch
  488.     add    dl,'0'        ;ASCII,
  489.     mov    ah,2        ;display char
  490.     int    21h
  491.     pop    dx
  492.     mov    cl,1        ;no suppress,
  493. OdX:    ret            ;                v3.01
  494. OutDec    endp
  495. ;
  496. KbdChk    proc    near
  497.     mov    ah,0Bh        ;Check keyboard for character waiting
  498.     int    21h
  499.     or    al,al        ;anything there?        v3.01
  500.     jz    Chk1        ;nope                v3.01
  501.      mov    ah,8        ;Character waiting - see what it is
  502.      int    21h
  503.      or    al,20h        ;Make it lower case
  504.      cmp    al,'q'        ;Time to QUIT?
  505.      je    Chk2        ;Yes
  506. Chk1:    clc            ;No - Make sure carry flag is cleared
  507.     ret
  508.  
  509. Chk2:    stc            ;Yep - set carry flag
  510.     ret
  511. KbdChk    endp
  512.  
  513. ;
  514. ; BEEP - entry conditions BX register contains count figure for frequency
  515. ;        to be generated.
  516. ;
  517. Beep    proc    near
  518.     mov    al,0b6h        ; Channel 2, LSB then MSB, Square Wave, Binary
  519.     out    43h,al        ; Program 8253 command register
  520.     mov    ax,bx        ; Get the frequency to be generated
  521.     out    42h,al        ; Load Channel 2 count register LSB
  522.     mov    al,ah
  523.     out    42h,al        ; Load Channel 2 count register MSB
  524.     in    al,61h        ; Read settings from 8255 PPI I/O Port "PB"
  525.     mov    ah,al        ; Save original settings in AH
  526.     or    al,3        ; Enable Timer Channel 2 & Speaker data
  527.     out    61h,al        ; program the 8255 with new setting-speaker on
  528.     sub    cx,cx        ; Sneaky way to put 0FFFFH into CX when
  529. wait2:    loop    wait2        ; LOOP is first executed
  530.     mov    al,ah        ; Get original 8255 Port "PB" settings
  531.     out    61h,al        ; Reset port to original values-speaker off
  532.     ret
  533. Beep    endp
  534.  
  535. blkbuf    equ    $        ;cluster buffer
  536.  
  537. fatbuf    equ    $+16384        ;FAT buffer.
  538.  
  539. Cseg    ENDS
  540.     END    Scavenge
  541.