📄 rxdosbio.asm
字号:
storarg _relCluster, ax ; required rel cluster offset
or ax, ax ; starts at first file cluster ?
jz _LoadProgram_18 ; yes -->
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
; at start, we must position at rel cluster
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
_LoadProgram_14:
mov ax, word ptr [ BootDrive ]
mov dx, word ptr [ _currentCluster ][ bp ]
call getNextCluster ; get next cluster
jz _LoadProgram_Return ; exit if error -->
mov word ptr [ _currentCluster ][ bp ], dx ; save cluster number
dec word ptr [ _relCluster ][ bp ] ; scan more clusters ?
jnz _LoadProgram_14 ; scan more -->
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
; optimize cluster read
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
_LoadProgram_18:
mov ax, word ptr [ BootDrive ]
mov dx, word ptr [ _currentCluster ][ bp ]
call scanClusterMap
mov word ptr [ _sectorsToRead ][ bp ], cx ; # sectors to sequentially read
mov word ptr [ _scanEndCluster ][ bp ], dx ; last cluster scanned
; mov dl, byte ptr [ BootDrive_BPB. _bpbSectorsPerCluster ]
; sub dl, al ; sectors remaining
; sub word ptr [ _sectorsToRead ][ bp ], dx ; adjust sectors to read
; jnz _LoadProgram_26 ; keep reading if more required -->
; mov word ptr [ _sectorsToRead ][ bp ], 0001 ; else default to one sector
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
; get sector offset to read
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
_LoadProgram_26:
xor dx, dx
mov ax, word ptr [ _buffer. _pointer ][ bp ]
div word ptr [ BootDrive_BPB. _bpbBytesPerSector ]
div byte ptr [ BootDrive_BPB. _bpbSectorsPerCluster ]
xor bh, bh
mov bl, ah ; sector adjust for pointer
mov ax, word ptr [ _currentCluster ][ bp ]
dec ax
dec ax
xor cx, cx
mov cl, byte ptr [ BootDrive_BPB. _bpbSectorsPerCluster ]
mul cx ; compute sector
add ax, word ptr [ ReservedBeforeDataSector. _low ]
adc dx, word ptr [ ReservedBeforeDataSector. _high ]
add ax, bx ; add sector adjust
adc dx, 0000
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
; read buffer
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
mov cx, dx
mov dx, ax ; sector address
mov al, byte ptr [ BootDrive ]
getdarg es, di, _buffer
getarg bx, _sectorsToRead
call ReadBuffer ; do read
jc _LoadProgram_Abrupt ; if error -->
mov ax, word ptr [ _sectorsToRead ][ bp ]
mul word ptr [ BootDrive_BPB. _bpbBytesPerSector ]
add word ptr [ _buffer. _pointer ][ bp ], ax
getarg dx, _scanEndCluster ; last cluster scanned
storarg _currentCluster, dx ; cluster address of pgm /start
cmp dx, -1 ; was last read to end of file ?
jnz _LoadProgram_18 ; no, keep reading -->
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
; return
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
_LoadProgram_Return:
mov cx, word ptr [ _buffer. _pointer ][ bp ]
or cx, cx ; if ok return
_LoadProgram_Abrupt:
Return
;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
; Read FAT Buffer ;
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
; ;
; Input: ;
; cx:dx sector to read ;
;...............................................................;
readFATBuffer:
les di, dword ptr [ _FATbuffer ]
cmp word ptr [ _FATbuffer_SectorNumber. _low ], dx
jnz readFATBuffer_08
cmp word ptr [ _FATbuffer_SectorNumber. _high ], cx
jz readFATBuffer_12
readFATBuffer_08:
mov bx, 0001
mov al, byte ptr [ BootDrive ]
mov word ptr [ _FATbuffer_SectorNumber. _high ], cx
mov word ptr [ _FATbuffer_SectorNumber. _low ], dx
call readBuffer
readFATBuffer_12:
ret
;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
; Read Buffer ;
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
; ;
; Input: ;
; ax drive ;
; bx buffers to read ;
; cx:dx logical sector to read ;
; es:di buffer address ;
;...............................................................;
readBuffer:
Entry
ddef _bufferPtr, es, di
ddef _sector, cx, dx
; def _readSector
; def _readHead
; def _readTrack
def _drive, ax
def _buffers, bx
def _retries
SaveRegisters bp, dx, ax, cx
readBuffer_08:
mov word ptr [ _retries ][ bp ], 3
readBuffer_10:
getdarg dx, ax, _sector
add ax, word ptr [ BootDrive_BPB. _bpbHiddenSectors. _low ]
adc dx, word ptr [ BootDrive_BPB. _bpbHiddenSectors. _high ]
div word ptr [ BootDrive_BPB. _bpbSectorsPerTrack ]
inc dl
mov cl, dl ; _readSector
xor dx, dx
div word ptr [ BootDrive_BPB. _bpbHeads ]
; mov word ptr [ _readTrack ][ bp ], ax ; dont need to save track
; mov byte ptr [ _readHead ][ bp ], dl ; don't need to save heads
mov dh, dl ; head
shl ah, 1 ; high order two bits of track
shl ah, 1 ; ... moved to top end of reg
shl ah, 1
shl ah, 1
shl ah, 1
shl ah, 1
or cl, ah ; or with sector
mov ch, al ; remainder of track to ch
mov al, byte ptr [ _buffers ][ bp ] ; plus buffers to read
mov ah, al ; buffers
add ah, cl ; starting sector
sub ah, byte ptr [ BootDrive_BPB. _bpbSectorsPerTrack ]
jle readBuffer_12 ; no, ok to read -->
sub al, ah ; safe number of buffers to read
inc ax
readBuffer_12:
push ax ; # buffers requested
mov ah, 02h ; read command type
mov dl, byte ptr [ _drive ][ bp ]
getdarg es, bx, _bufferPtr
; NormalizeBuffer es, bx
int 13h
pop ax ; # buffers requested
jc readBuffer_26 ; if error -->
xor ah, ah
xor cx, cx
mov bx, ax
mul word ptr [ BootDrive_BPB. _bpbBytesPerSector ]
add word ptr [ _bufferPtr. _pointer ][ bp ], ax
add word ptr [ _sector. _low ][ bp ], bx
adc word ptr [ _sector. _high ][ bp ], cx
sub byte ptr [ _buffers ][ bp ], bl ; buffers remaining after this read
jg readBuffer_08 ; if more to read
jmp short readBuffer_28 ; exit -->
readBuffer_26:
xor ax, ax
mov dl, byte ptr [ _drive ][ bp ]
int 13h ; if error, attempt reset
dec word ptr [ _retries ][ bp ]
jnz readBuffer_10
stc ; make sure exit with error flag
readBuffer_28:
RestoreRegisters cx, ax, dx, bp
Return
;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
; Get Next Cluster ;
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
; ;
; Input: ;
; ax drive ;
; dx current cluster ;
; ;
; Output: ;
; dx next cluster ;
; zr if end of cluster chain. ;
;...............................................................;
getNextCluster:
Entry
def _drive, ax
def _cluster, dx
def _MaxClusters
saveRegisters es, di, si, cx, bx, ax
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
; determine whether its 12 or 16 bit FAT entries
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
xor cx, cx
mov cl, byte ptr [ BootDrive_BPB. _bpbSectorsPerCluster ]
mov dx, word ptr [ BootDrive_BPB. _bpbHugeSectors. _high ]
mov ax, word ptr [ BootDrive_BPB. _bpbHugeSectors. _low ]
div cx
storarg _MaxClusters, ax
mov dx, word ptr [ BootDrive_BPB. _bpbHugeSectors. _high ]
mov ax, word ptr [ BootDrive_BPB. _bpbHugeSectors. _low ]
mov dx, -1 ; presume end if error
mov ax, word ptr [ _cluster ][ bp ] ; get cluster #
or ax, ax ; invalid number
jz getNextCluster_Return ; exit -->
cmp ax, word ptr [ _MaxClusters ][ bp ]
jnc getNextCluster_Return ; if valid cluster # -->
getNextCluster_08:
xor dx, dx
test word ptr [ _MaxClusters ][ bp ], 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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -