📄 rxdosfat.asm
字号:
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 + -