📄 rxdosccb.asm
字号:
; Locate from reference actual start of CCB buffer ;
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
; ;
; Input: ;
; si pointer into a CCB buffer ;
; ;
; Output: ;
; es:di pointer to CCB Header ;
; cx offset from start of data ;
;...............................................................;
locateCCBPHeader:
les di, dword ptr ss:[ _RxDOS_BufferList ]
locateCCBPHeader_04:
mov cx, si
sub cx, di ; how far from start of buffer
jl locateCCBPHeader_08 ; go to next -->
cmp cx, sizeCCB ; within a CCB buffer ?
jg locateCCBPHeader_08 ; go to next -->
or cx, cx ; no carry (leave offset alone )
ret
locateCCBPHeader_08:
mov di, word ptr es:[ ccbNext ][ di ]
cmp di, -1
jnz locateCCBPHeader_04
stc
ret
;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
; Read Buffer ;
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
; ;
; Input: ;
; cx:dx sector to read ;
; ax drive ;
; bx attributes to claim buffer ;
; ;
; Output: ;
; es:di pointer to selected buffer ;
;...............................................................;
readBuffer:
call SelBuffer ; find a buffer
jnz readBuffer_08 ; if buffer is valid -->
call readSelBuffer ; else read buffer
readBuffer_08:
ret
;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
; Read Selected Buffer ;
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
; ;
; Input: ;
; es:di pointer to selected buffer ;
; cx:dx sector to read ;
; ax drive ;
; ;
; Output: ;
; es:di pointer to selected buffer ;
; cx:dx sector to read ;
;...............................................................;
readSelBuffer:
SaveAllRegisters
push di
push es
mov byte ptr es:[ ccbDrive ][ di ], al ; set drive
mov word ptr es:[ ccbLBN. _high][ di ], cx ; set logical block number
mov word ptr es:[ ccbLBN. _low ][ di ], dx ; set logical block number
mov byte ptr es:[ ccbStatus ][ di ], 00 ; kill entry's value, validity
mov bx, 0001
lea di, offset ccbData [ di ] ; buffer address
call DevRead ; read buffer
pop es
pop di
jc readSelBuffer_08 ; if error -->
mov byte ptr es:[ ccbStatus ][ di ], (ccb_isVALID)
readSelBuffer_08:
RestoreAllRegisters
ret
;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
; Update CCB buffer, always. ;
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
; ;
; es:di pointer to selected buffer ;
; All Registers Preserved ;
;...............................................................;
updateCCB:
test byte ptr es:[ ccbStatus ][ di ], ( ccb_isVALID )
jz updateCCB_08 ; data not valid -->
test byte ptr es:[ ccbStatus ][ di ], ( ccb_isDIRTY )
jnz updateChangedCCB ; data valid and changed -->
updateCCB_08:
ret
;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
; Update Changed CCB buffer. ;
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
; ;
; es:di pointer to selected buffer ;
; All Registers Preserved ;
; ;
; CY returned in fail in write ;
;...............................................................;
updateChangedCCB:
Entry
ddef _buffer, es, di
SaveAllRegisters
mov bx, 0001
mov dx, word ptr es:[ ccbLBN. _low ][ di ] ; get sector
mov cx, word ptr es:[ ccbLBN. _high ][ di ]
mov al, byte ptr es:[ ccbDrive ][ di ] ; get drive number
cbw
lea di, offset ccbData [ di ] ; buffer address
call DevWrite ; write t\disk
jc updateCCB_12 ; if error/ fail -->
les di, dword ptr [ _buffer ][ bp ]
test byte ptr es:[ ccbStatus ][ di ], ( ccb_isFAT )
jz updateCCB_12 ; not a FAT buffer -->
call updateAlternateFATTables ; update FAT tables
; jc updateCCB_12 ; if error/ fail -->
updateCCB_12:
pushf
les di, dword ptr [ _buffer ][ bp ]
and byte ptr es:[ ccbStatus ][ di ], NOT ( ccb_isDIRTY + ccb_isONHOLD )
popf ; keep flag, but kill error buffer
RestoreAllRegisters
Return
;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
; Update Alternate FAT Table ;
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
; ;
; Given a FAT sector address, copies the sector to the alter- ;
; nate FAT Table. ;
; ;
; Input: ;
; es:di pointer to a FAT CCB Buffer ;
;...............................................................;
updateAlternateFATTables:
Entry
ddef _ccb, es, di
def _dpbNumberFat
def _dpbFATSectors
test byte ptr es:[ ccbStatus ][ di ], ( ccb_isFAT )
jz updateAlternateFATTables_22 ; not a fat designated sector -->
les bx, dword ptr es:[ ccbDPB ][ di ] ; get assigned DPB
mov ax, word ptr es:[ _dpbSectorsPerFat ][ bx ]
storarg _dpbFATSectors, ax
mov ah, 0
mov al, byte ptr es:[ _dpbNumCopiesFAT ][ bx ]
storarg _dpbNumberFat, ax
getdarg es, di, _ccb
mov dx, word ptr es:[ ccbLBN. _low ][ di ] ; get original sector
mov cx, word ptr es:[ ccbLBN. _high ][ di ]
mov al, byte ptr es:[ ccbDrive ][ di ] ; get drive number
cbw
lea di, offset ccbData [ di ] ; buffer address
updateAlternateFATTables_08:
dec word ptr [ _dpbNumberFat ][ bp ]
jle updateAlternateFATTables_22 ; if not more than 1 -->
mov bx, 0001
add dx, word ptr [ _dpbFATSectors ][ bp ] ; adjust for fat size
adc cx, 0000
SaveRegisters es, di, dx, cx, ax
call DevWrite
RestoreRegisters ax, cx, dx, di, es
jnc updateAlternateFATTables_08
updateAlternateFATTables_22:
Return
;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
; Update All Drive Buffers ;
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
; ;
; Input: ;
; ax drive ;
;...............................................................;
updateDriveBuffers:
les di, dword ptr ss:[ _RxDOS_BufferList ]
updDriveBuffer_04:
test byte ptr es:[ ccbStatus ][ di ], ( ccb_isVALID )
jz updDriveBuffer_16 ; not a valid block -->
cmp byte ptr es:[ ccbDrive ][ di ], al ; compare drives
jnz updDriveBuffer_16 ; not this block, try next -->
call updateCCB ; update block if changed
updDriveBuffer_16:
mov di, word ptr es:[ ccbNext ][ di ]
cmp di, -1
jnz updDriveBuffer_04
ret
;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
; Update All Changed Buffers ;
;...............................................................;
updateAllChangedCCBBuffers:
pushf
SaveAllRegisters
les di, dword ptr ss:[ _RxDOS_BufferList ]
updateAllChanged_04:
test byte ptr es:[ ccbStatus ][ di ], ( ccb_isVALID )
jz updateAllChanged_16 ; not a valid buffer -->
call updateCCB ; updated buffer if req'd
updateAllChanged_16:
mov di, word ptr es:[ ccbNext ][ di ]
cmp di, -1
jnz updateAllChanged_04
RestoreAllRegisters
popf
ret
;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
; Invalidate Buffers for Specific Drive ;
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
; ;
; Input: ;
; ax drive ;
;...............................................................;
invalidateBuffers:
les di, dword ptr ss:[ _RxDOS_BufferList ]
invBuffer_04:
test byte ptr es:[ ccbStatus ][ di ], ( ccb_isVALID )
jz invBuffer_16 ; not a valid buffer -->
cmp al, byte ptr es:[ ccbDrive ][ di ] ; same drive ?
jnz invBuffer_16 ; if not -->
and byte ptr es:[ ccbStatus ][ di ], NOT ( ccb_isVALID )
invBuffer_16:
mov di, word ptr es:[ ccbNext ][ di ]
cmp di, -1
jnz invBuffer_04
ret
RxDOS ENDS
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -