⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rxdosfat.asm

📁 dos source
💻 ASM
📖 第 1 页 / 共 4 页
字号:

        getarg cx, _cluster                             ; get cluster value
        getarg dx, _value                               ; get value to update
        and dx, 0FFFh

        pop bx                                          ; word offset into FAT table
        cmp bx, word ptr [ _sectorsize ][ bp ]          ; at sector size -1 boundry ?
        jnz updateClusterValue_16                       ; no, ok to return as is -->

        call _updateCrossSectorEntry
      ; call updateAllChangedCCBBuffers                 ; optimized when commented out.

        clc                                             ; if no carry
        jmp short updateClusterValue_Return

      ; see if odd or even cluster

updateClusterValue_16:
        shr cx, 1                                       ; even or odd cluster
        jnc updateClusterValue_20                       ; even, take value -->

        shl dx, 1
        shl dx, 1
        shl dx, 1
        shl dx, 1                                       ; shift value

        mov cx, word ptr es:[ ccbData ][ bx + di ]      ; get current value
        and word ptr es:[ ccbData ][ bx + di ], 000Fh   ; clear area.
        
        shr cx, 1
        shr cx, 1
        shr cx, 1
        shr cx, 1                                       ; old value shifted correctly
        jmp short updateClusterValue_22

updateClusterValue_20:
        mov cx, word ptr es:[ ccbData ][ bx + di ]      ; get current value
        and word ptr es:[ ccbData ][ bx + di ], 0F000h  ; clear area.

updateClusterValue_22:
        or word ptr es:[ ccbData ][ bx + di ], dx       ; update FAT word

updateClusterValue_26:
        and cx, 0FFFh                                   ; mask off unwanted bits
        mov ax, cx
        and ax, 0FF8h                                   ; FAT value, 12 bit entries.
        cmp ax, 0FF8h                                   ; end of chain ?
        jnz updateClusterValue_UpdatedRet               ; no -->

        mov cx, -1                                      ; if end, set end value
        jmp short updateClusterValue_UpdatedRet

;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
;  16 bit FAT entries
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

updateClusterValue_16Bits:
        mov cx, word ptr es:[ _dpbBytesPerSector ][ bx ]
        shr cx, 1
        div cx                                          ; FAT sector/ Offset

      ; ax will contain FAT sector
      ; dx will contain byte offset into FAT sector

        add dx, dx                                      ; make word offset
        push dx

        xor cx, cx
        mov dx, word ptr es:[ _dpbFirstFAT ][ bx ]      ; where is first FAT table ?
        add dx, ax                                      ; add offset required
        mov ax, word ptr [ _drive ][ bp ]               ; get drive
        call readBuffer                                 ; read FAT Table
        or byte ptr es:[ ccbStatus ][ di ], ( ccb_isFAT )

        pop bx                                          ; word offset into FAT table
        getarg cx, _value                               ; update value
        xchg cx, word ptr es:[ ccbData ][ bx + di ]     ; update value

;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
;  update
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

updateClusterValue_UpdatedRet:
        call CCBChanged
        or cx, cx

;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
;  return
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

updateClusterValue_Return:
        restoreRegisters ax, bx, dx, si, di, es
        Return

        ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
        ;  Update Cross Sector Entry                                    ;
        ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
        ;                                                               ;
        ;  Input:                                                       ;
        ;   es:di  points to current ccb                                ;
        ;   bx     offset into buffer                                   ;
        ;   dx     value to update                                      ;
        ;   cx     cluster number                                       ;
        ;                                                               ;
        ;  Output:                                                      ;
        ;   cx     value at cluster (value before update)               ;
        ;...............................................................;

_updateCrossSectorEntry:

        Entry
        def  _sectorflag, cx
        def  _updatevalue, dx
        def  _returnvalue

        mov ax, word ptr es:[ ccbData ][ bx + di ]      ; get value at current sector
        storarg _returnvalue, ax

        shr cx, 1                                       ; even or odd cluster
        jnc _updateCrossSector_20                       ; even, take value -->

        shl dx, 1
        shl dx, 1
        shl dx, 1
        shl dx, 1
        and dx, 0FFF0h
        storarg _updatevalue, dx
        and byte ptr es:[ ccbData ][ bx + di ], 0Fh     ; init area
        or byte ptr es:[ ccbData ][ bx + di ], dl       ; set high value (just the single nibble)
        jmp short _updateCrossSector_22                 ; 

_updateCrossSector_20:
        mov byte ptr es:[ ccbData ][ bx + di ], dl      ; update low order FAT word

;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
;  update next sector
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

_updateCrossSector_22:
        call CCBChanged

        xor ah, ah
        mov al, byte ptr es:[ ccbDrive       ][ di ]
        mov cx, word ptr es:[ ccbLBN. _high  ][ di ]
        mov dx, word ptr es:[ ccbLBN. _low   ][ di ]
        inc dx
        adc cx, 0                                       ; 32 bit add
        call ReadBuffer                                 ; read next sector
        or byte ptr es:[ ccbStatus ][ di ], ( ccb_isFAT )

        getarg dx, _updatevalue
        mov ax, word ptr es:[ ccbData ][ di ]           ; get value at current sector
        test word ptr [ _sectorflag ][ bp ], 1          ; even or odd cluster
        jz _updateCrossSector_30                        ; even, take value -->
        mov byte ptr es:[ ccbData ][ di ], dh           ; set low order value

        xchg ah, al
        mov al, byte ptr [ _returnvalue ][ bp ]
        shr ax, 1
        shr ax, 1
        shr ax, 1
        shr ax, 1                                       ; return value in ax
        jmp short _updateCrossSector_32                 ; 

_updateCrossSector_30:
        and byte ptr es:[ ccbData ][ di ], 0F0h         ; clear high order
        or byte ptr es:[ ccbData ][ di ], dh            ; update high order FAT word

        xchg ah, al        
        mov al, byte ptr [ _returnvalue ][ bp ]

;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
;  rebuild original value
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

_updateCrossSector_32:
        push ax
        call CCBChanged

        pop cx
        and cx, 0FFFh
        Return

        ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
        ;  Get 12Bit FAT Table Value                                    ;
        ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
        ;                                                               ;
        ;  Input:                                                       ;
        ;   ax     drive                                                ;
        ;   dx     current cluster                                      ;
        ;                                                               ;
        ;  Output:                                                      ;
        ;   dx     value at cluster (next cluster)                      ;
        ;   zr     if end of cluster chain.                             ;
        ;...............................................................;

_get_12Bit_ClusterValue:
        Entry
        def  _drive, ax
        def  _cluster, dx
        def  _sectorsize
        ddef _sector
        ddef _dpb, es, bx

        mov ax, dx
        add ax, ax
        add ax, dx                                      ; nibble address

        xor dx, dx
        mov cx, word ptr es:[ _dpbBytesPerSector ][ bx ]
        mov word ptr [ _sectorsize ][ bp ], cx
        dec word ptr [ _sectorsize ][ bp ]
        shl cx, 1                                       ; nibbles / sector
        div cx                                          ; sector to read

      ; ax will contain sector
      ; dx will contain nibble offset

        shr dx, 1                                       ; word offset
        push dx                                         ;

        xor cx, cx                                      ; 32 bit address
        mov dx, ax
        add dx, word ptr es:[ _dpbFirstFAT ][ bx ]      ; where is first FAT table ?
        stordarg _sector, cx, dx                        ; 32 bit sector address

        mov ax, word ptr [ _drive ][ bp ]               ; get drive
        call readBuffer                                 ; read FAT Table
        or byte ptr es:[ ccbStatus ][ di ], ( ccb_isFAT )

        pop bx                                          ; word offset into FAT table
        mov dx, word ptr es:[ ccbData ][ bx + di ]      ; get FAT word

        cmp bx, word ptr [ _sectorsize ][ bp ]          ; at sector size -1 boundry ?
        jnz _get_12Bit_ClusterValue_12                  ; no, ok to return as is -->

        push dx                                         ; else save what we have
        getdarg cx, dx, _sector                         ; read next cluster sector
        add dx, 0001                                    ; incr by one
        adc cx, 0000

        mov ax, word ptr [ _drive ][ bp ]               ; get drive
        call readBuffer                                 ; read FAT Table
        or byte ptr es:[ ccbStatus ][ di ], ( ccb_isFAT )

        pop dx
        mov dh, byte ptr es:[ ccbData ][ di ]           ; get FAT word

_get_12Bit_ClusterValue_12:
        test word ptr [ _cluster ][ bp ], 1             ; is cluster Odd ?
        jz _get_12Bit_ClusterValue_14                   ; no, just take value -->

        mov cl, 4
        shr dx, cl

_get_12Bit_ClusterValue_14:
        and dx, 0FFFh                                   ; 12 bit mask
        mov ax, dx
        and ax, 00FF8h                                  ; FAT value, 12 bit entries.
        cmp ax, 00FF8h                                  ; end of chain ?
        jnz _get_12Bit_ClusterValue_16                  ; no -->
        mov dx, -1                                      ; if end, set end value

_get_12Bit_ClusterValue_16:
        Return

        ;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
        ;  Delete Cluster Chain                                         ;
        ;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
        ;                                                               ;
        ;  Removes cluster addressed in dx from *both* FAT tables and   ;
        ;  returns pointer to next cluster ( or FFFF).                  ;
        ;                                                               ;
        ;  Input:                                                       ;
        ;   ax     drive                                                ;
        ;   dx     cluster                                              ;
        ;                                                               ;
        ;  Output:                                                      ;
        ;   dx     next cluster                                         ;
        ;   zr     if end of cluster chain.                             ;
        ;...............................................................;

ReleaseClusterChain:

        saveAllRegisters
        call getAddrDPB                                 ; (es:bx) Device Parameter Block
        jc releaseClusterChain_16                       ; if device invalid -->

        or dx, dx                                       ; cluster valid ?
        jz releaseClusterChain_16                       ; no, exit -->
        cmp dx, word ptr es:[ _dpbMaxClusterNumber ][ bx ]
        jnc releaseClusterChain_16                      ; no, exit -->

releaseClusterChain_08:
        cmp word ptr es:[ _dpbFreeCount ][ bx ], -1     ; value initialized ?
        jz releaseClusterChain_12                       ; no -->
        inc word ptr es:[ _dpbFreeCount ][ bx ]         ; increment allocated unit

releaseClusterChain_12:
        xor cx, cx
        call updateClusterValue                         ; release cluster at ax:dx
        jz releaseClusterChain_16                       ; no more -->

        mov dx, cx                                      ; next cluster
        cmp dx, -1                                      ; end of chain ?

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -