📄 rxdossft.asm
字号:
;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
; Verify SFT/ JHT Available ;
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
; ;
; Returns: ;
; ax handle id # ;
;...............................................................;
VerifyAvailableHandle:
cmp word ptr ss:[ _RxDOS_CurrentPSP ], 0000
jz verifyAvailHandles_26 ; if no app -->
push es
push si
push cx
mov es, word ptr ss:[ _RxDOS_CurrentPSP ] ; get PSP
mov cx, word ptr es:[ pspFileHandleCount ]
les si, dword ptr es:[ pspFileHandlePtr ]
verifyAvailHandles_04:
cmp byte ptr es:[ si ], -1 ; empty slot ?
jz verifyAvailHandles_08 ; yes, allocate -->
inc si ; next
loop verifyAvailHandles_04 ; continue looping
stc
mov ax, offset pexterrNoHandlesAvailable ; problem, no app handles left
jmp short verifyAvailHandles_22 ; exit -->
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
; allocate App Handle
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
verifyAvailHandles_08:
call FindAvailableSFTHandle ; locate avail System Handle
jc verifyAvailHandles_22 ; if none left -->
dec word ptr es:[ sftRefCount ][ bx ] ; release reservation count
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
; return
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
verifyAvailHandles_22:
pop cx
pop si
pop es
verifyAvailHandles_26:
ret
;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
; Build Directory /SFT Entries ;
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
; ;
; Input: ;
; es:di pointer to diraccess ;
; cx attributes ;
; ;
; Output: ;
; ax handle to an SFT ;
;...............................................................;
createSFTEntry:
Entry
def _drive
def _handle, -1 ; SFT handle
def _DirEntryAttributes, cx ; directory attributes
ddef _dirAccess, ss, di
ddef _dirAddress ; address of empty loc found
ddef _sftPointer ; sft pointer
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
; find an available SFT
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
call FindAvailableSFTHandle ; find an available file handle
ifc _createSFTEntry_42 ; if none available -->
mov word ptr [ _handle ][ bp ], ax ; handle
stordarg _sftPointer, es, bx ; sft pointer
call InitSFTEntry ; clear entry
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
; if file exists, delete file by releasing its clusters
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
mov si, word ptr [ _dirAccess. _pointer ][ bp ]
mov ax, word ptr ss:[ fileAcDrive ][ si ]
storarg _drive, ax ; save drive
test ax, 8000h ; does not exist flag ?
jnz _createSFTEntry_20 ; if no file -->
mov si, word ptr [ _dirAccess. _pointer ][ bp ]
les di, dword ptr ss:[ fileAcBufferPtr ][ si ]
add di, word ptr ss:[ fileAcDirOffset ][ si ] ; offset to entry in dir
stordarg _dirAddress, es, di ; address of empty loc found
mov dx, word ptr ss:[ fileAcCluster ][ si ]
mov word ptr ss:[ fileAcCluster ][ si ], 0000
call ReleaseClusterChain
jmp short _createSFTEntry_24
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
; if no file, locate empty slot and populate
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
_createSFTEntry_20:
and ax, 7FFFh
mov word ptr ss:[ fileAcDrive ][ si ], ax
mov dx, word ptr ss:[ fileAcDirCluster ][ si ]
call LocateFreeDirSlot ; can we find a valid empty entry ?
jc _createSFTEntry_40 ; no -->
stordarg _dirAddress, es, si ; address of empty loc found
mov di, si ; convert name to dir style
mov si, word ptr [ _dirAccess. _pointer ][ bp ]
mov si, word ptr ss:[ fileAcNameOffset ][ si ]
call convFilenametoFCBString ; dir style name [si]-->[di]
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
; update latest entry
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
_createSFTEntry_24:
xor ax, ax
mov cx, sizeDIRENTRY - sizeFILENAME ; remainder of dir entry
getdarg es, di, _dirAddress ; restore di pointer
lea di, deAttributes [ di ] ; starting at attribs
rep stosb ; clear rest of entry
mov si, word ptr [ _dirAddress. _pointer ][ bp ]
mov cx, word ptr [ _DirEntryAttributes ][ bp ] ; get attributes
mov byte ptr es:[ deAttributes ][ si ], cl ; attribute byte
call getSysDateinDirFormat
mov word ptr es:[ deTime ][ si ], ax ; time created
mov word ptr es:[ deDate ][ si ], dx ; date created
mov word ptr es:[ deStartCluster ][ si ], 0000
mov word ptr es:[ deFileSize. _low ][ si ], 0000
mov word ptr es:[ deFileSize. _high ][ si ], 0000
call locateCCBPHeader ; get ccb header into es:di
call CCBChanged ; mark changes made
call updateChangedCCB ; updated buffer to disk
mov ax, offset errAccessDenied ; problem, access denied
jc _createSFTEntry_40 ; if error, release SFT -->
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
; fix-up SFT
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
push word ptr [ _dirAddress. _segment ][ bp ]
push word ptr [ _dirAddress. _pointer ][ bp ] ; dir entry
push word ptr [ _sftPointer. _segment ][ bp ]
push word ptr [ _sftPointer. _pointer ][ bp ] ; sft pointer
call initSFTfromDirEntry
getarg ax, _handle
cmp word ptr es:[ sftDevInfo ][ di ], sftIsDevice
clc
jnz _createSFTEntry_42
or word ptr es:[ sftDevInfo ][ di ], sftWritten ; is written when created
jmp short _createSFTEntry_42
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
; if error, release locked sft
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
_createSFTEntry_40:
getdarg es, bx, _sftPointer ; get sft pointer
dec word ptr es:[ sftRefCount ][ bx ] ; release completely
stc
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
; return
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
_createSFTEntry_42:
Return
;''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''';
; Build Directory /SFT Entries ;
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -;
; ;
; Input: ;
; stack pointer to directory entry ;
; stack sft pointer ;
; ;
; Output: ;
; es:di sft pointer ;
;...............................................................;
initSFTfromDirEntry:
Entry 4
darg _dirAddress
darg _sftPointer ; sft pointer
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
; init SFT
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
push ds
xor ax, ax
getdarg es, di, _sftPointer ; sft pointer
add di, 2 ; skip Count entry
mov cx, (sizeSFT - sftRefCount - 2)/ 2 ; effective count
rep stosw ; must have pointer at es: di
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
; copy filename
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
getdarg ds, si, _dirAddress ; directory
getdarg es, di, _sftPointer ; sft pointer
lea di, offset sftFileName [ di ] ; offset to filename
mov cx, sizeFILENAME ; length of name/ ext
rep movsb ; copy name
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
; populate sft
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
getdarg ds, si, _dirAddress ; directory
getdarg es, di, _sftPointer ; sft pointer
push word ptr [ deAttributes ][ si ] ; attribute byte
push word ptr [ deTime ][ si ] ; time last updated
push word ptr [ deDate ][ si ] ; date last updated
push word ptr [ deStartCluster ][ si ] ; beginning cluster
push word ptr [ deFilesize. _low ][ si ] ; file size
push word ptr [ deFilesize. _high ][ si ] ; file size
pop word ptr es:[ sftFileSize. _high ][ di ]
pop word ptr es:[ sftFileSize. _low ][ di ]
pop word ptr es:[ sftBegCluster ][ di ]
pop word ptr es:[ sftDate ][ di ]
pop word ptr es:[ sftTime ][ di ]
pop ax
mov byte ptr es:[ sftFileAttrib ][ di ], al
; set owner PSP
mov ax, word ptr ss:[ _RxDOS_CurrentPSP ] ; get owner PSP
mov word ptr es:[ sftOwnerPSP ][ di ], ax
; set where in directory
push es
push di ; pointer to sft
setES ds ; point dir buffer as [es][si]
call locateCCBPHeader ; get ccb header into es:di
mov si, di ; ccb Header at [ds:si]
pop di
pop es ; pointer to sft
mov ax, word ptr [ ccbLBN. _low ][ si ]
mov dx, word ptr [ ccbLBN. _high ][ si ]
mov word ptr es:[ sftDirSector. _low ][ di ], ax
mov word ptr es:[ sftDirSector. _high ][ di ], dx
mov cl, byte ptr [ ccbDrive ][ si ] ; get drive
and cx, sftDrivemask
or word ptr es:[ sftDevInfo ][ di ], cx ; include drive
mov ax, word ptr [ _dirAddress ][ bp ]
sub ax, si ; distance from start of ccb header
sub ax, ccbData ; distance from start of dir sector
mov cl, sizeDIRENTRY ; bytes per entry
div cl ; remainder should be zero
mov byte ptr es:[ sftDirIndex ][ di ], al
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
; record disk drive volume id
;- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
mov ax, word ptr es:[ sftDevInfo ][ di ] ; drive
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -