📄 rxdosfat.asm
字号:
AllocateInitCluster_12:
getarg ax, _drive
getarg dx, _cluster
restoreRegisters bx, si
Return
;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
; Append A Cluster ;
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
; ;
; Input: ;
; ax drive ;
; dx cluster to append ;
; ;
; Output: ;
; ax drive ;
; dx new cluster value ;
;...............................................................;
AppendCluster:
Entry
def _drive, ax
def _cluster, dx
cmp dx, 341
jc AppendCluster_06
nop
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
; allocate a free cluster / sector
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
AppendCluster_06:
push bx
call AllocateCluster ; allocate a cluster
jc appendCluster_08 ; if error -->
push dx ; allocated cluster
mov cx, dx ; use it to link to prev cluster
getarg dx, _cluster
call updateClusterValue ; update cluster value
pop dx ; restore allocated cluster
or dx, dx
appendCluster_08:
pop bx
Return
;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
; Read Random Buffer FAT File ;
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
; ;
; Input: ;
; ss:bx fat access control block ;
; ;
; Output: ;
; es:bx pointer in block buffer to data ;
; cx remaining bytes in block ;
; zr means end of file or wrong address ;
;...............................................................;
_FATReadRandom:
Entry
ddef _accessControl, ss, bx
ddef _reqOffset
def _bytesPerCluster
ddef _DPBPointer
ddef _BufferAddress
saveRegisters ds, di, si, dx, ax
and word ptr [ diskAcOptions ][ bx ], NOT (DISKAC_RESULT_READMULTIPLESECTORS)
mov ax, word ptr [ diskAcDrive ][ bx ]
call getAddrDPB ; (es:bx) Device Parameter Block
stordarg _DPBPointer, es, bx
mov cx, 0000 ; say none
ifc _FATReadRandom_Return ; if error, exit -->
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
; if request is before start of buffer
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
setDS ss
mov bx, word ptr [ _accessControl. _pointer ][ bp ]
mov ax, word ptr [ diskAcPosition. _low ][ bx ]
mov dx, word ptr [ diskAcPosition. _high ][ bx ]
stordarg _reqOffset, dx, ax
sub ax, word ptr [ diskAcOffAtBegCluster. _low ][ bx ]
sbb dx, word ptr [ diskAcOffAtBegCluster. _high ][ bx ]
jge _FATReadRandom_16
_FATReadRandom_08:
xor ax, ax
mov word ptr [ diskAcOffAtBegBuffer. _low ][ bx ], ax
mov word ptr [ diskAcOffAtBegBuffer. _high ][ bx ], ax
mov word ptr [ diskAcOffAtBegCluster. _low ][ bx ], ax
mov word ptr [ diskAcOffAtBegCluster. _high ][ bx ], ax
mov word ptr [ diskAcCurCluster ][ bx ], ax
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
; locate starting cluster and sector
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
_FATReadRandom_16:
cmp word ptr [ diskAcCurCluster ][ bx ], 0000
jnz _FATReadRandom_18
mov ax, word ptr [ diskAcBegCluster ][ bx ]
mov word ptr [ diskAcCurCluster ][ bx ], ax
_FATReadRandom_18:
getdarg es, si, _DPBPointer
mov ax, word ptr es:[ _dpbBytesPerSector ][ si ]
mov cl, byte ptr es:[ _dpbClusterSizeShift ][ si ]
shl ax, cl ; bytes per cluster
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
; compute a fake sector size if addressing cluster 0 (root dir).
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
cmp word ptr [ diskAcBegCluster ][ bx ], 0000
jnz _FATReadRandom_20
mov ax, word ptr es:[ _dpbMaxAllocRootDir ][ si ]
mov cx, sizeDIRENTRY
mul cx
_FATReadRandom_20:
mov word ptr [ _bytesPerCluster ][ bp ], ax
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
; see if within current cluster
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
_FATReadRandom_22:
mov dx, word ptr [ _reqOffset. _low ][ bp ]
mov cx, word ptr [ _reqOffset. _high ][ bp ]
sub dx, word ptr [ diskAcOffAtBegCluster. _low ][ bx ]
sbb cx, word ptr [ diskAcOffAtBegCluster. _high ][ bx ]
jnz _FATReadRandom_26 ; must continue searching forward -->
cmp dx, word ptr [ _bytesPerCluster ][ bp ] ; beyond cluster size ?
jc _FATReadRandom_32 ; no, current cluster is ok -->
_FATReadRandom_26:
mov ax, word ptr [ diskAcDrive ][ bx ]
mov dx, word ptr [ diskAcCurCluster ][ bx ]
or dx, dx ; zero cluster ?
jz _FATReadRandom_28 ; yes -->
call getNextCluster
jz _FATReadRandom_28 ; if end of cluster chain -->
mov cx, word ptr [ _bytesPerCluster ][ bp ]
add word ptr [ diskAcOffAtBegCluster. _low ][ bx ], cx
adc word ptr [ diskAcOffAtBegCluster. _high ][ bx ], 0000
mov word ptr [ diskAcCurCluster ][ bx ], dx
jmp _FATReadRandom_22
_FATReadRandom_28:
xor cx, cx
jmp _FATReadRandom_Return
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
; see if within current sector
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
_FATReadRandom_32:
lds bx, dword ptr [ _accessControl ][ bp ]
mov ax, word ptr [ diskAcDrive ][ bx ]
mov dx, word ptr [ diskAcCurCluster ][ bx ]
call computeLogSectorNumber ; cluster -> sector number
push cx
push dx ; save logical sector number
mov ax, word ptr [ _reqOffset. _low ][ bp ]
mov dx, word ptr [ _reqOffset. _high ][ bp ]
sub ax, word ptr [ diskAcOffAtBegCluster. _low ][ bx ]
sbb dx, word ptr [ diskAcOffAtBegCluster. _high ][ bx ]
div word ptr es:[ _dpbBytesPerSector ][ si ]
mov cx, word ptr [ _reqOffset. _low ][ bp ]
sub cx, dx ; subtract out remainder
mov word ptr [ diskAcOffAtBegBuffer. _low ][ bx ], cx
mov cx, word ptr [ _reqOffset. _high ][ bp ]
mov word ptr [ diskAcOffAtBegBuffer. _high ][ bx ], cx
pop dx
pop cx ; restore lsn
add dx, ax ; real sector offset
adc cx, 0
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
; read sector
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
mov ax, word ptr [ diskAcDrive ][ bx ]
mov word ptr [ diskAcCurSector. _low ][ bx ], dx
mov word ptr [ diskAcCurSector. _high ][ bx ], cx
test word ptr [ _reqOffset. _low ][ bp ], (SIZESECTOR - 1)
ifnz _FATReadRandom_52 ; if not on sector boundary ->
test word ptr [ diskAcOptions ][ bx ], DISKAC_READ_MULTIPLESECTORS
ifz _FATReadRandom_52 ; if not multiple sectors ->
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
; identify reads that will cross certain segment boundaries
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
mov es, word ptr [ diskAcBufferPtr. _segment ][ bx ]
mov di, word ptr [ diskAcBufferPtr. _pointer ][ bx ]
NormalizeBuffer es, di ; normalize buffer pointer
stordarg _BufferAddress, es, di
mov cx, es ;
and cx, 00FFFh ; see if segment after normalize
cmp cx, 0FE0h ; is beyond xFE0.
jnc _FATReadRandom_52 ; if tough segment boundary case
mov ax, 1000h
sub ax, cx ; # paragraphs that can be read
shl ax, 1
shl ax, 1
shl ax, 1
shl ax, 1 ; actual bytes that can be read
cmp ax, word ptr [ diskAcBytesToRead ][ bx ] ; bytes to read
jc _FATReadRandom_40 ; cx contains max bytes
mov ax, word ptr [ diskAcBytesToRead ][ bx ] ; else allow max requested
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
; identify max forward scan clusters
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
_FATReadRandom_40:
xor dx, dx
div word ptr [ _bytesPerCluster ][ bp ] ; compute max clusters to scan
mov cx, ax ; max clusters
mov dx, word ptr [ diskAcCurCluster ][ bx ]
mov ax, word ptr [ diskAcDrive ][ bx ]
call scanClusterMap ; number contiguous clusters
mov ax, word ptr [ _bytesPerCluster ][ bp ] ; compute
mul cx ; total bytes to read
xor dx, dx ; nothing way up here
cmp ax, word ptr [ diskAcBytesToRead ][ bx ] ; more than requested ?
jc _FATReadRandom_42 ; no -->
mov ax, word ptr [ diskAcBytesToRead ][ bx ] ; limit to requested size
_FATReadRandom_42:
mov cx, SIZESECTOR ; into sectors
div cx ; sectors to read
getdarg es, di, _BufferAddress
or word ptr [ diskAcOptions ][ bx ], DISKAC_RESULT_READMULTIPLESECTORS
mov dx, word ptr [ diskAcCurSector. _low ][ bx ]
mov cx, word ptr [ diskAcCurSector. _high ][ bx ]
mov bx, word ptr [ diskAcDrive ][ bx ]
xchg ax, bx
call DevRead
mov ax, SIZESECTOR ; sector size
mul cx ; actual bytes read
mov cx, ax ; actual bytes read
getdarg es, di, _BufferAddress
jmp short _FATReadRandom_Return ; return bytes read
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
; read sector (unoptimized fast read )
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
_FATReadRandom_52:
mov ax, word ptr [ diskAcDrive ][ bx ]
mov dx, word ptr [ diskAcCurSector. _low ][ bx ]
mov cx, word ptr [ diskAcCurSector. _high ][ bx ]
call ReadBuffer
mov ax, word ptr [ diskAcOptions ][ bx ]
or byte ptr es:[ ccbStatus ][ di ], al ; type of block
lea di, offset ccbData [ di ] ; point to data
mov word ptr [ diskAcBufferPtr. _segment ][ bx ], es
mov word ptr [ diskAcBufferPtr. _pointer ][ bx ], di
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
; return pointer
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
_FATReadRandom_60:
lds bx, dword ptr [ _accessControl ][ bp ]
les si, dword ptr [ _DPBPointer ][ bp ]
mov cx, word ptr es:[ _dpbBytesPerSector ][ si ]
mov ax, word ptr [ _reqOffset. _low ][ bp ]
mov dx, word ptr [ _reqOffset. _high ][ bp ]
sub ax, word ptr [ diskAcOffAtBegBuffer. _low ][ bx ]
sbb dx, word ptr [ diskAcOffAtBegBuffer. _high ][ bx ]
les bx, dword ptr [ diskAcBufferPtr ][ bx ]
add bx, ax ; offset into buffer
sub cx, ax ; bytes remaining in buffer
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
; return
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
_FATReadRandom_Return:
restoreRegisters ax, dx, si, di, ds
Return
RxDOS ENDS
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -