📄 rxdosccb.asm
字号:
TITLE 'ccb - cache functions for rxdos'
PAGE 59, 132
.LALL
;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
; CCB Cache Manager 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 PARA PUBLIC 'CODE'
assume cs:RxDOS, ds:RxDOS, es:RxDOS, ss:RxDOS
;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
; Buffer Management ;
;...............................................................;
public CCBChanged
public invalidateBuffers
public linkBegCCB
public locateCCBPHeader
public readBuffer
public readSelBuffer
public SelBuffer
public unlinkCCB
public updateAllChangedCCBBuffers
public updateCCB
public updateChangedCCB
public updateDriveBuffers
extrn DevRead : near
extrn DevWrite : near
extrn getAddrDPB : near
extrn _RxDOS_BufferList : near
extrn _RxDOS_pCDS : dword
extrn _DebugInterruptTrap : near
;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
; Selected Buffer ;
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
; ;
; Input: ;
; ax drive ;
; cx:dx sector to read ;
; ;
; Output: ;
; es:di pointer to selected buffer ;
; nz buffer contains valid data ;
; all registers preserved ;
;...............................................................;
SelBuffer:
SaveRegisters ax, bx, cx, dx
les di, dword ptr ss:[ _RxDOS_BufferList ]
mov bx, -1
selBuffer_04:
test byte ptr es:[ ccbStatus ][ di ], ( ccb_isVALID )
jz selBuffer_08 ; unallocated buffer -->
cmp byte ptr es:[ ccbDrive ][ di ], al ; compare drives
jnz selBuffer_08 ; not this block, try next -->
cmp cx, word ptr es:[ ccbLBN. _high][ di ] ; compare logical block numbers
jnz selBuffer_08 ; not this block, try next -->
cmp dx, word ptr es:[ ccbLBN. _low ][ di ] ; compare logical block numbers
jz selBuffer_36 ; buffer located -->
selBuffer_08:
test byte ptr es:[ ccbStatus ][ di ], ( ccb_isONHOLD )
jnz selBuffer_12 ; if on hold, don't use -->
mov bx, di ; save last buffer address
selBuffer_12:
mov di, word ptr es:[ ccbNext ][ di ]
cmp di, -1
jnz selBuffer_04
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
; if could not find a matching buffer, find an empty buffer
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
mov di, bx
cmp di, -1 ; buffer address available ?
jnz selBuffer_30 ; use the last referenced buffer -->
les di, dword ptr ss:[ _RxDOS_BufferList ] ; else must seatch buffers again
selBuffer_16:
test byte ptr es:[ ccbStatus ][ di ], ( ccb_isVALID )
jz selBuffer_32 ; unallocated buffer -->
cmp word ptr es:[ ccbNext ][ di ], -1
jz selBuffer_30 ; must write all, use least used -->
mov di, word ptr es:[ ccbNext ][ di ]
jmp selBuffer_16
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
; prep returned buffer
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
selBuffer_30:
call updateCCB ; just in case update required
selBuffer_32:
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 ; clear status
call setFlagIfDriveIsRemote ; sets remote flag
push es
push di
call getAddrDPB ; pointer to dpb
mov dx, es ; pointer was in [es:bx]
pop di
pop es
mov word ptr es:[ ccbDPB. _segment ][ di ], dx
mov word ptr es:[ ccbDPB. _pointer ][ di ], bx
selBuffer_36:
cmp di, word ptr ss:[ _RxDOS_BufferList. _pointer ]
jz selBuffer_38 ; if already at beginning -->
call unlinkCCB ; unlink CCB buffer
call linkBegCCB ; link to front of CCB chain
selBuffer_38:
test byte ptr es:[ ccbStatus ][ di ], ( ccb_isVALID )
RestoreRegisters dx, cx, bx, ax
ret
;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
; Is Drive Remote ;
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
; ;
; al drive ;
; es:di points to ccb buffer ;
;...............................................................;
setFlagIfDriveIsRemote:
push ax
push di
push es
mov cl, sizeCDS
mul cl ; ax contains current drive
les di, dword ptr ss:[ _RxDOS_pCDS ] ; actual address of CDS
add di, ax ; current drive
test word ptr es:[ _cdsFlags ][ di ], _CDS_NETWORKEDDRIVE
pop es
pop di
jz IfDriveIsRemote_12 ; if not remote -->
or byte ptr es:[ ccbStatus ][ di ], ( ccb_isREMOTE )
IfDriveIsRemote_12:
pop ax
ret
;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
; Remove CCB Buffer from Linked List ;
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
; ;
; es:di points to ccb buffer ;
;...............................................................;
unlinkCCB:
pushf ; save current interrupt status
push ax
push di
cli ; disable interrupts
mov ax, word ptr es:[ ccbPrev ][ di ]
mov di, word ptr es:[ ccbNext ][ di ]
cmp ax, -1 ; no previous ?
jnz unlinkCCB_06 ; no -->
mov word ptr ss:[ _RxDOS_BufferList. _pointer ], di ; update beg of list if no previous
unlinkCCB_06:
cmp di, -1 ; no next pointer ?
jz unlinkCCB_08 ; skip removing its Prev pointer ->
mov word ptr es:[ ccbPrev ][ di ], ax ; next's prev fixed.
unlinkCCB_08:
cmp ax, -1 ; no previous ?
jz unlinkCCB_12 ; no -->
xchg di, ax
mov word ptr es:[ ccbNext ][ di ], ax ; prev's next fixed.
unlinkCCB_12:
pop di
mov word ptr es:[ ccbPrev ][ di ], -1 ; unlink current pointers
mov word ptr es:[ ccbNext ][ di ], -1
pop ax
popf ; restore interrupt status
ret
;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
; Link CCB Buffer to Beginning of List ;
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
; ;
; es:di points to ccb buffer ;
;...............................................................;
linkBegCCB:
pushf ; save current interrupt status
push ax
cli ; disable interrupts
mov ax, di
les di, dword ptr ss:[ _RxDOS_BufferList ]
cmp ax, di ; relinking ccb buffer to beg of list ?
jz linkBegCCB_08 ; yes, don't do it -->
mov word ptr es:[ ccbPrev ][ di ], ax ; previous to orig prev
xchg di, ax
mov word ptr es:[ ccbNext ][ di ], ax ; this next to old next
mov word ptr es:[ ccbPrev ][ di ], -1 ; current no more previous
mov word ptr ss:[ _RxDOS_BufferList. _pointer ], di
linkBegCCB_08:
pop ax
popf
ret
;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
; Mark CCB buffer changed. ;
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
; ;
; es:di pointer to selected buffer ;
;...............................................................;
CCBChanged:
or byte ptr es:[ ccbStatus ][ di ], ( ccb_isDIRTY + ccb_isVALID )
and byte ptr es:[ ccbStatus ][ di ], NOT ( ccb_isONHOLD )
ret
;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -