home *** CD-ROM | disk | FTP | other *** search
/ Hall of Fame / HallofFameCDROM.cdr / dos / mark231.lzh / MARK.ASM next >
Encoding:
Assembly Source File  |  1987-01-12  |  16.3 KB  |  400 lines

  1. PAGE ,132
  2. TITLE Bad Cluster Mark Program, Version 2.31, 12-Jan-1987
  3.  
  4. ;
  5. ; Written By Steven Georgiades
  6. ;
  7. ; Mark/UnMark-Bad-Cluster Program
  8. ;   This program will allow you to mark or unmark a cluster on your disk as
  9. ;   bad.  It should work under all versions of DOS 2.00 and higher, and should
  10. ;   work on the PC, XT, AT, PCJr. and all compatibles.  The programs is invoked
  11. ;   as follows:
  12. ;
  13. ;         MARK [d:] [/U | /M | /Q] n
  14. ;
  15. ;           d:   Optional drive letter.  If this is omitted, the default
  16. ;                drive is used.  
  17. ;
  18. ;           /Q   Query switch.  The status of the following clusters will be 
  19. ;                returned.  If no switch is specified, Query is assumed.
  20. ;
  21. ;           /M   Mark switch.  The following clusters will be marked bad.
  22. ;
  23. ;           /U   Un-mark switch.  The following clusters will be un-marked.
  24. ;
  25. ;           n    Cluster Number, in decimal.  The first data cluster is 2.
  26. ;
  27. ;       If you are using this program and find it of value, your
  28. ;       contribution in any amount ($10.00 suggested) will be greatly
  29. ;       appreciated.  Makes checks payable to Steven M. Georgiades.
  30. ;               Thank you.
  31. ;
  32. ;       If you have any questions or comments about this or any other
  33. ;       SMG program, write to me at the following address:
  34. ;
  35. ;               Steven M. Georgiades
  36. ;               SMG Software
  37. ;               701-H South Hayward Street
  38. ;               Anaheim, CA 92804
  39. ;
  40.  
  41. CODE      SEGMENT BYTE PUBLIC 'CODE'
  42.  
  43.           ASSUME  CS:CODE,DS:CODE,ES:CODE,SS:CODE
  44.  
  45.           ORG     80H
  46.  
  47. PARAM     LABEL   BYTE
  48.  
  49.           ORG     100H
  50.  
  51. MARK:     JMP     BEGIN
  52.  
  53. DIGIT     DB      "0123456789ABCDEF"
  54. SIGNON    DB      "Bad Cluster Mark Program, Version 2.31",13,10
  55.           DB      "SMG Software",13,10
  56.           DB      "(C) Copyright 1986,1987 Steven Georgiades",13,10,10,"$"
  57. USAGE     DB      "Usage:",13,10,10
  58.           DB      "  MARK [d:] [/U | /M | /Q] n",13,10,10
  59.           DB      "    d:   Optional drive letter.  "
  60.           DB      "If this is omitted, the default drive is used.",13,10,10
  61.           DB      "    /Q   Query switch.  "
  62.           DB      "The status of the following clusters will be returned.",13,10
  63.           DB      "         If no switch is specified, Query is assumed."
  64.           DB      13,10,10
  65.           DB      "    /M   Mark switch.  "
  66.           DB      "The following clusters will be marked as bad.",13,10,10
  67.           DB      "    /U   Un-mark switch.  "
  68.           DB      "The following clusters will be un-marked.",13,10,10
  69.           DB      "    n    Cluster Number, in decimal.  "
  70.           DB      "The first data cluster is 2.",13,10,10,"$"
  71. CLSTMSG   DB      "Cluster XXXXX$"
  72. INVALID   DB      " does not exist!",7,13,10,"$"
  73. BADMSG    DB      " is already marked as bad",13,10,"$"
  74. NOTBAD    DB      " is not marked as bad",13,10,"$"
  75. MARKMSG   DB      " has been marked as bad",13,10,"$"
  76. UNMRKMSG  DB      " has been un-marked as bad",13,10,"$"
  77. STATUS1   DB      " is available",13,10,"$"
  78. STATUS2   DB      " is Screwed Up!!",7,13,10,"$"
  79. STATUS3   DB      " is currently in use by a file",13,10,"$"
  80. STATUS4   DB      " is reserved",7,13,10,"$"
  81. STATUS5   DB      " is marked as bad",13,10,"$"
  82. STATUS6   DB      " is currently in use by a file (EOF)",7,13,10,"$"
  83.  
  84. CLSTSEC   DW      ?
  85. CLSTTOT   DW      ?
  86. CLUST     DW      ?
  87. DRIVE     DB      ?
  88. EOF       DW      ?
  89. FATSEC    DW      ?
  90. FATSIZE   DB      ?
  91. FLAG      DB      0
  92. OLDDRV    DB      -1
  93. SECSIZE   DW      ?
  94.  
  95. BEGIN:    MOV     AH,9                          ; Output Sign-On Message
  96.           MOV     DX,OFFSET SIGNON
  97.           INT     21H
  98.           MOV     AH,19H                        ; Get Default Drive Number
  99.           INT     21H
  100.           MOV     DRIVE,AL                      ;   and Save
  101.           MOV     SI,OFFSET PARAM               ; Set up Pointer to Parameter
  102.           LODSB                                 ; Read Parameter Length
  103.           CMP     AL,2                          ; If Length < 2,
  104.           JAE     OK
  105.           MOV     AH,9                          ;   Output Usage Message
  106.           MOV     DX,OFFSET USAGE
  107.           INT     21H
  108.           MOV     AX,4C01H                      ;   Exit to DOS
  109.           INT     21H
  110. OK:       CBW
  111.           MOV     BX,AX
  112.           MOV     BYTE PTR [SI][BX],0           ; Terminate Parameter String
  113. STRIP:    LODSB                                 ; Strip Off Leading Whitespace
  114.           CMP     AL,' '
  115.           JE      STRIP
  116.           CMP     AL,9
  117.           JE      STRIP
  118.           OR      AL,AL                         ; If End-of-Parameter List,
  119.           JNZ     NOTDONE
  120.           MOV     AX,4C00H                      ;   Exit to DOS
  121.           INT     21H
  122. NOTDONE:  CMP     AL,'/'                        ; If Switch, Process
  123.           JNE     NOSWITCH
  124.           LODSB                                 ; Get Switch Letter
  125.           AND     AL,0DFH                       ; Convert to Upper Case
  126.           CMP     AL,'U'                        ; If '/U', Flag = 0
  127.           JE      SWITCHU
  128.           CMP     AL,'M'                        ; If '/M', Flag = 1
  129.           JE      SWITCHM
  130.           CMP     AL,'Q'                        ; If Not '/Q', Next Character
  131.           JNE     STRIP
  132.           MOV     FLAG,0                        ; Else Flag = 0
  133.           JMP     SHORT STRIP
  134. SWITCHU:  MOV     FLAG,1                        ; Flag = 1
  135.           JMP     SHORT STRIP
  136. SWITCHM:  MOV     FLAG,2                        ; Flag = 2
  137.           JMP     SHORT STRIP
  138. NOSWITCH: MOV     BL,AL
  139.           LODSB                                 ; Get Drive Letter
  140.           CMP     AL,':'
  141.           JNE     NODRIVE
  142.           INC     SI
  143.           AND     BL,0DFH                       ; Convert to Upper Case
  144.           SUB     BL,'A'                        ; Convert to Drive Number 
  145.           MOV     DRIVE,BL                      ; Save Drive Number
  146.           JMP     STRIP                         ; Get Next Paramter
  147. NODRIVE:  SUB     SI,2                          ; ReUse Last Character
  148.           CALL    GET_WORD                      ; Read Cluster Number (Hex)
  149.           CMP     DX,2
  150.           MOV     CLUST,DX                      ; Save Cluster Number
  151.           MOV     AL,DRIVE                      ; If Different Drive,
  152.           CMP     AL,OLDDRV
  153.           JE      DRV_OK
  154.           PUSH    SI                            ;   Save Parameter Pointer
  155.           MOV     OLDDRV,AL                     ;   Save New Drive
  156.           MOV     BX,OFFSET FATBUF              ;   Read Boot Record
  157.           MOV     CX,1
  158.           MOV     DX,0
  159.           INT     25H
  160.           POPF
  161.           MOV     AX,FATBUF[11]                 ;   Read Sector Size and Save
  162.           MOV     SECSIZE,AX
  163.           MOV     AL,BYTE PTR FATBUF[13]        ;   Read Sectors/Cluster and Save
  164.           XOR     AH,AH
  165.           MOV     CLSTSEC,AX
  166.           MOV     BX,FATBUF[22]                 ;   Read Sectors/FAT and Save
  167.           MOV     FATSEC,BX
  168.           MOV     AH,36H                        ;   Get Total Data Clusters
  169.           MOV     DL,DRIVE
  170.           INC     DL
  171.           INT     21H
  172.           ADD     DX,2
  173.           MOV     CLSTTOT,DX                    ;     and Save
  174.           MOV     FATSIZE,3
  175.           MOV     EOF,0FF8H
  176.           CMP     DX,4081                       ;   If Necessary, Adjust FAT Size
  177.           JLE     FAT_OK
  178.           MOV     FATSIZE,4
  179.           MOV     EOF,0FFF8H
  180. FAT_OK:   MOV     AL,DRIVE                      ;   Read FAT
  181.           MOV     CX,FATSEC
  182.           MOV     DX,1
  183.           MOV     BX,OFFSET FATBUF
  184.           INT     25H
  185.           POPF
  186.           POP     SI                            ;   Restore Parameter Pointer
  187. DRV_OK:   MOV     BX,CLUST                      ; Get Cluster Number
  188.           MOV     AX,BX                         ; Convert Cluster No. to ASCII
  189.           MOV     DI,OFFSET CLSTMSG[13]
  190.           CALL    DEC5OUT
  191.           CALL    STRIP0                        ; Strip Off Leading Zeroes
  192.           MOV     AH,9                          ; Output Cluster Message
  193.           MOV     DX,OFFSET CLSTMSG
  194.           INT     21H
  195.           CMP     BX,CLSTTOT                    ; If Invalid, Say So
  196.           JAE     CLST_BAD
  197.           CMP     BX,2
  198.           JAE     CLST_OK
  199. CLST_BAD: MOV     DX,OFFSET INVALID
  200.           JMP     SHORT ERROUT
  201. CLST_OK:  CALL    NEXTCLST                      ; Get Next Cluster Number
  202.           MOV     AX,EOF                        ; Get EOF Value
  203.           CMP     FLAG,0                        ; If /Q, Query
  204.           JE      QUERY
  205.           CMP     FLAG,1                        ; Else If /U, Unmark
  206.           JE      UNMARK
  207.           OR      BX,BX                         ; Else Mark
  208.           JZ      IS_FREE
  209.           CMP     BX,AX                         ;   If In Use, Error
  210.           JB      NOTINUSE
  211. IN_USE:   MOV     DX,OFFSET STATUS3
  212.           JMP     SHORT ERROUT
  213. NOTINUSE: DEC     AX                            ;   If Bad, Error
  214.           CMP     BX,AX
  215.           JNE     NOT_BAD
  216.           MOV     DX,OFFSET BADMSG
  217.           JMP     SHORT ERROUT
  218. NOT_BAD:  SUB     AX,7                          ;   If In Use, Error
  219.           CMP     BX,AX
  220.           JB      IN_USE
  221. IS_RESV:  MOV     DX,OFFSET STATUS4             ;   If Reserved, Error
  222.           JMP     SHORT ERROUT
  223. IS_FREE:  MOV     BX,CLUST                      ;   Get Cluster Number
  224.           MOV     AX,EOF                        ;   New Value = Bad Cluster
  225.           DEC     AX
  226.           MOV     DX,OFFSET MARKMSG
  227.           JMP     WRT_FAT
  228. QUERY:    OR      BX,BX                         ; If Cluster = 0, Free
  229.           JNZ     NOT_FREE
  230.           MOV     DX,OFFSET STATUS1
  231.           JMP     SHORT ERROUT
  232. NOT_FREE: CMP     BX,1                          ; If 1, Invalid
  233.           JNE     NOTWEIRD
  234.           MOV     DX,OFFSET STATUS2
  235.           JMP     SHORT ERROUT
  236. NOTWEIRD: CMP     BX,AX                         ; If FF8 to FFF, InUse (EOF)
  237.           JB      NO_USE
  238.           MOV     DX,OFFSET STATUS6
  239.           JMP     SHORT ERROUT
  240. NO_USE:   DEC     AX                            ; If FF7, Bad
  241.           CMP     BX,AX
  242.           JNE     IS_OK
  243.           MOV     DX,OFFSET STATUS5
  244.           JMP     SHORT ERROUT
  245. IS_OK:    SUB     AX,7                          ; If 2 to FEF, In Use
  246.           CMP     BX,AX
  247.           JB      IN_USE
  248.           JMP     SHORT IS_RESV                 ; If FF0 to FF6, Reserved
  249. UNMARK:   DEC     AX
  250.           CMP     BX,AX                         ; If Not Bad,
  251.           JE      IS_BAD
  252.           MOV     DX,OFFSET NOTBAD
  253. ERROUT:   MOV     AH,9                          ; Output Error Message
  254.           INT     21H
  255.           JMP     STRIP
  256. IS_BAD:   MOV     BX,CLUST                      ; Get Cluster Number
  257.           XOR     AX,AX                         ; New Value = Good Cluster
  258.           MOV     DX,OFFSET UNMRKMSG
  259. WRT_FAT:  PUSH    DX
  260.           CALL    SETCLST
  261.           PUSH    SI                            ; Save Parameter Pointer
  262.           MOV     AL,DRIVE                      ; Write FAT #1
  263.           MOV     CX,FATSEC
  264.           MOV     DX,1
  265.           MOV     BX,OFFSET FATBUF
  266.           INT     26H
  267.           POPF
  268.           MOV     AL,DRIVE                      ; Write FAT #2
  269.           MOV     CX,FATSEC
  270.           MOV     DX,CX
  271.           INC     DX
  272.           MOV     BX,OFFSET FATBUF
  273.           INT     26H
  274.           POPF
  275.           POP     SI                            ; Restore Parameter Pointer
  276.           MOV     AH,9                          ; Output UnMarked Message
  277.           POP     DX
  278.           INT     21H
  279.           JMP     STRIP
  280.  
  281. NEXTCLST: CMP     FATSIZE,3                     ; If FAT Size = 16 Bits,
  282.           JE      NEXT_12
  283.           SHL     BX,1                          ;   Simply Read Next Cluster #
  284.           MOV     BX,FATBUF[BX]
  285.           RET                                   ;   Done
  286. NEXT_12:  PUSH    CX                            ; Save Registers
  287.           MOV     CX,BX                         ; Word # = Cluster # * 1.5
  288.           SHL     CX,1
  289.           ADD     BX,CX
  290.           SHR     BX,1
  291.           MOV     BX,FATBUF[BX]
  292.           JNC     NEXT_OK                       ; If Odd, Use 12 MSB's
  293.           MOV     CL,4
  294.           SHR     BX,CL
  295. NEXT_OK:  AND     BX,0FFFH                      ; Else Use 12 LSB's
  296.           POP     CX                            ; Restore Registers
  297.           RET                                   ; Done
  298.  
  299. SETCLST:  PUSH    AX                            ; Save Registers
  300.           PUSH    BX
  301.           CMP     FATSIZE,3                     ; If FAT Size = 16 Bits,
  302.           JE      SETC_12
  303.           SHL     BX,1                          ;   Simply Read Next Cluster #
  304.           MOV     FATBUF[BX],AX
  305.           JMP     SHORT SET_DONE                ;   Done
  306. SETC_12:  PUSH    CX                            ; Save Registers
  307.           MOV     CX,BX                         ; Word # = Cluster # * 1.5
  308.           SHL     CX,1
  309.           ADD     BX,CX
  310.           SHR     BX,1
  311.           MOV     CX,0F000H
  312.           JNC     SETC_OK                       ; If Odd, Use 12 MSB's
  313.           MOV     CL,4
  314.           SHL     AX,CL
  315.           MOV     CX,0FH
  316. SETC_OK:  AND     FATBUF[BX],CX
  317.           OR      FATBUF[BX],AX
  318.           POP     CX
  319. SET_DONE: POP     BX
  320.           POP     AX
  321.           RET                                   ; Done
  322.  
  323. GET_WORD: PUSH    BX                            ; Save Register
  324.           XOR     DX,DX                         ; Value = 0
  325. GET_WRD1: LODSB                                 ; Read Character
  326.           CMP     AL,'0'                        ; If Not Numeric, Done
  327.           JB      GET_WRD2
  328.           CMP     AL,'9'
  329.           JA      GET_WRD2
  330.           SUB     AL,'0'                        ; Convert to BCD
  331.           CBW
  332.           MOV     BX,AX                         ; Value = Value*10+BCD
  333.           MOV     AX,10
  334.           MUL     DX
  335.           ADD     AX,BX
  336.           MOV     DX,AX
  337.           JMP     GET_WRD1                      ; Repeat
  338. GET_WRD2: DEC     SI
  339.           POP     BX                            ; Restore Register
  340.           RET                                   ; Done
  341.  
  342. STRIP0:   CMP     BYTE PTR [DI],'0'             ; If Character != '0', Done
  343.           JNE     STRIP1
  344.           CMP     BYTE PTR [DI+1],'0'           ; If Next Character != Digit,
  345.           JL      STRIP1                        ;   Done
  346.           CMP     BYTE PTR [DI+1],'9'
  347.           JG      STRIP1
  348.           MOV     BYTE PTR [DI],' '             ; Change '0' to ' '
  349.           INC     DI                            ; Point to Next Character
  350.           JMP     SHORT STRIP0                  ; Repeat
  351. STRIP1:   RET                                   ; Done
  352.  
  353. DEC2OUT:  PUSH    AX                            ; Save Registers
  354.           PUSH    BX
  355.           XOR     AH,AH                         ; Clear AH
  356.           MOV     BL,10                         ; AH=AX%10,AL=AX/10
  357.           DIV     BL
  358.           ADD     AX,'00'                       ; Convert to ASCII
  359.           SUB     DI,2
  360.           MOV     [DI],AX                       ; Store in String
  361.           POP     BX                            ; Restore Registers
  362.           POP     AX
  363.           RET                                   ; Done
  364.  
  365. DEC4OUT:  PUSH    AX                            ; Save Registers
  366.           PUSH    BX
  367.           MOV     BL,100                        ; AH=AX%100,AL=AX/100
  368.           DIV     BL
  369.           XCHG    AH,AL                         ; Convert 2 LSD's
  370.           CALL    DEC2OUT
  371.           XCHG    AH,AL                         ; Convert 2 MSD's
  372.           CALL    DEC2OUT
  373.           POP     BX                            ; Restore Registers
  374.           POP     AX
  375.           RET                                   ; Done
  376.  
  377. DEC5OUT:  PUSH    AX                            ; Save Registers
  378.           PUSH    BX
  379.           PUSH    DX                            ; DX=AX%10000,AX=AX/10000
  380.           MOV     BX,10000
  381.           XOR     DX,DX
  382.           DIV     BX
  383.           XCHG    DX,AX                         ; Convert 4 LSD's
  384.           CALL    DEC4OUT
  385.           XCHG    DX,AX                         ; Convert MSD
  386.           ADD     AL,'0'
  387.           SUB     DI,1
  388.           MOV     [DI],AL
  389.           POP     DX                            ; Restore Registers
  390.           POP     BX
  391.           POP     AX
  392.           RET                                   ; Done
  393.  
  394. FATBUF    LABEL   WORD
  395.  
  396. CODE      ENDS
  397.  
  398.           END     MARK
  399.