📄 rxdosfat.asm
字号:
TITLE 'fat - walk through FAT Tables for rxdos'
PAGE 59, 132
.LALL
;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
; FAT Walk Through FAT Tables for rxdos ;
;...............................................................;
;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
; Real Time Dos ;
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
; ;
; This material was created as a published version of a DOS ;
; equivalent product. This program logically functions in ;
; the same way as MSDOS functions and it is internal data ;
; structure compliant with MSDOS 6.0 ;
; ;
; This product is distributed AS IS and contains no warranty ;
; whatsoever, including warranty of merchantability or ;
; fitness for a particular purpose. ;
; ;
; ;
; (c) Copyright 1990, 1997. Api Software and Mike Podanoffsky ;
; All Rights Reserved Worldwide. ;
; ;
; This product is protected under copyright laws and may not ;
; be reproduced in whole or in part, in any form or media, ;
; included but not limited to source listing, facsimile, data ;
; transmission, cd-rom, or floppy disk without the expressed ;
; written consent of the author. ;
; ;
; License for distribution for commercial use or resale ;
; required from: ;
; ;
; Api Software ;
; 12 South Walker Street ;
; Lowell, MA 01851 ;
; ;
; internet: mikep@world.std.com ;
; ;
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
; Compile with MASM 5.1 ;
;...............................................................;
include rxdosmac.asm
include rxdosdef.asm
RxDOS SEGMENT PUBLIC 'CODE'
assume cs:RxDOS, ds:RxDOS, es:RxDOS, ss:RxDOS
;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
; Walk Through FAT Tables ;
;...............................................................;
public AllocateCluster
public AllocateInitCluster
public AmountFreeSpace
public AppendCluster
public getNextCluster
public ReleaseClusterChain
public scanClusterMap
public updateClusterValue
public _FATReadRandom
extrn CCBChanged : near
extrn computeLogSectorNumber : near
extrn getDPB : near
extrn getAddrDPB : near
extrn readBuffer : near
extrn readSelBuffer : near
extrn SelBuffer : near
extrn CCBChanged : near
extrn updateChangedCCB : near
extrn updateAllChangedCCBBuffers : near
extrn _DebugInterruptTrap : near
extrn DevRead : near
;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
; Definitions ;
;...............................................................;
MINCLUSTER EQU 2 ; min cluster value
;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
; Get Next Cluster ;
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
; ;
; Input: ;
; ax drive ;
; dx current cluster ;
; ;
; Output: ;
; ax drive ;
; dx next cluster ;
; zr if end of cluster chain. ;
; ;
; Preserves: ;
; es, di, si, cx, bx, ax ;
;...............................................................;
getNextCluster:
Entry
def _drive, ax
def _cluster, dx
saveRegisters es, di, si, cx, bx, ax
call getAddrDPB ; (es:bx) Device Parameter Block
mov dx, -1 ; presume end if error
jc getNextCluster_Return ; exit if error -->
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
; determine whether its 12 or 16 bit FAT entries
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
mov ax, word ptr [ _cluster ][ bp ] ; get cluster #
cmp ax, MINCLUSTER ; less than min cluster ?
jc getNextCluster_04 ; exit with -1 -->
cmp ax, word ptr es:[ _dpbMaxClusterNumber ][ bx ]
jc getNextCluster_08 ; if valid cluster # -->
getNextCluster_04:
jmp short getNextCluster_Return
getNextCluster_08:
xor dx, dx
test word ptr es:[ _dpbMaxClusterNumber ][ bx ], 0F000h
jnz getNextCluster_16Bits ; if 16 -->
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
; 12 bit FAT entries
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
getNextCluster_12Bits:
mov ax, word ptr [ _drive ][ bp ] ; get drive
mov dx, word ptr [ _cluster ][ bp ] ; and cluster
call _get_12Bit_ClusterValue
jmp short getNextCluster_Return
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
; 16 bit FAT entries
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
getNextCluster_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
mov dx, word ptr es:[ ccbData ][ bx + di ] ; get FAT word
mov ax, dx
and ax, 0FFF8h ; FAT value, 12 bit entries.
cmp ax, 0FFF8h ; end of chain ?
jnz getNextCluster_Return ; no -->
mov dx, -1 ; if end, set end value
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
; return
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
getNextCluster_Return:
restoreRegisters ax, bx, cx, si, di, es
cmp dx, -1 ; set if end of chain
Return
;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
; Scan Ahead Cluster Map ;
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
; ;
; Input: ;
; ax drive ;
; cx max clusters to scan ;
; dx current cluster ;
; ;
; Output: ;
; cx # clusters that can be sequentially read ;
; dx last cluster value ;
;...............................................................;
scanClusterMap:
Entry
def _drive, ax
def _cluster, dx
def _maxClustersToScan, cx
def _nextCluster
def _clusterCount, 0001
or cx, cx ; zero max clusters ?
jz scanClusterMap_22 ; yes, exit -->
mov word ptr [ _clusterCount ][ bp ], 0000 ; cluster count
scanClusterMap_12:
inc word ptr [ _clusterCount ][ bp ] ; cluster count
mov cx, dx ; save original request
call getNextCluster ; get next cluster
cmp dx, -1 ; end ?
jz scanClusterMap_22 ; yes -->
sub cx, dx ; sequential clusters are ...
cmp cx, -1 ; ... identified by a -1 offset
jnz scanClusterMap_22 ; if still sequential -->
dec word ptr [ _maxClustersToScan ][ bp ] ; scan more ?
jnz scanClusterMap_12 ; yes -->
scanClusterMap_22:
mov cx, word ptr [ _clusterCount ][ bp ] ; # sequential clusters
Return
;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
; Update Cluster Value ;
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
; ;
; Updates the value given for any cluster. ;
; ;
; Input: ;
; ax drive ;
; dx cluster ;
; cx update value ;
; ;
; Returns: ;
; cx original contents in cluster cell ;
; ;
;...............................................................;
updateClusterValue:
Entry
def _drive, ax
def _cluster, dx
def _value, cx
def _sectorsize
ddef _sector
saveRegisters es, di, si, dx, bx, ax
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
; determine whether its 12 or 16 bit FAT entries
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
call getAddrDPB ; (es:bx) Device Parameter Block
jc updateClusterValue_04 ; if error -->
mov ax, word ptr [ _cluster ][ bp ] ; get cluster #
cmp ax, MINCLUSTER ; invalid number
jc updateClusterValue_04 ; exit -->
cmp ax, word ptr es:[ _dpbMaxClusterNumber ][ bx ]
jc updateClusterValue_08 ; if valid cluster # -->
updateClusterValue_04:
mov dx, -1
cmp dx, -1 ; sets zero (end of list)
stc ; and set carry (error )
jmp updateClusterValue_Return
updateClusterValue_08:
xor dx, dx
test word ptr es:[ _dpbMaxClusterNumber ][ bx ], 0F000h
jz updateClusterValue_12Bits ; if 12 -->
jmp updateClusterValue_16Bits ; if 16 -->
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
; 12 bit FAT entries
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
updateClusterValue_12Bits:
mov cx, ax
add ax, ax
add ax, cx ; nibble address
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 ; word offset
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 ; read next cluster sector
mov ax, word ptr [ _drive ][ bp ] ; get drive
call readBuffer ; read FAT Table
or byte ptr es:[ ccbStatus ][ di ], ( ccb_isFAT )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -