399 lines
16 KiB
ArmAsm
399 lines
16 KiB
ArmAsm
***********************************************************
|
|
* Close Call
|
|
|
|
Close LDY #c_refNum ;Close all?
|
|
LDA (parm),Y
|
|
BNE Close1 ;No, just one of 'em
|
|
STA clsFlshErr ;Clear global close error
|
|
LDA #$00 ;Begin at the beginning
|
|
ClsAll STA fcbPtr ;Save current low byte of pointer
|
|
TAY ;Fetch the level at which
|
|
LDA fcb+fcbLevel,Y ; file was opened
|
|
CMP Level ;Test against current global level
|
|
BCC NxtClose ;Don't close if files level is < global level
|
|
LDA fcb+fcbRefNum,Y ;Is this reference file open?
|
|
BEQ NxtClose ;No, try next
|
|
JSR FlushZ ;Clean it out...
|
|
BCS ClosErr ;Return flush errors
|
|
|
|
JSR CloseZ ;Update FCB & VCB
|
|
LDY #c_refNum
|
|
LDA (parm),Y
|
|
BEQ NxtClose ;No err if close all
|
|
BCS ClosErr
|
|
NxtClose LDA fcbPtr
|
|
CLC
|
|
ADC #fcbSize
|
|
BCC ClsAll ;Branch if within same page
|
|
|
|
LDA clsFlshErr ;On final close of close all report logged errors
|
|
BEQ ClosEnd ;Branch if errors
|
|
RTS ;Carry already set (see BCC)
|
|
|
|
Close1 JSR Flush1 ;Flush file first (including updating bit map)
|
|
BCS ClosErr ;Report errors immediately!!
|
|
|
|
CloseZ LDY fcbPtr
|
|
LDA fcb+fcbFileBuf,Y;Release file buffer
|
|
JSR ReleaseBuf
|
|
BCS ClosErr
|
|
LDA #$00
|
|
LDY fcbPtr
|
|
STA fcb+fcbRefNum,Y ;Free file control block too
|
|
LDA fcb+fcbDevNum,Y
|
|
STA DevNum
|
|
JSR ScanVCB ;Go look for associated VCB
|
|
LDX vcbPtr ;Get vcbptr
|
|
DEC vcb+vcbOpenCnt,X;Indicate one less file open
|
|
BNE ClosEnd ;Branch if that wasn't the last...
|
|
LDA vcb+vcbStatus,X
|
|
AND #$7F ;Strip 'files open' bit
|
|
STA vcb+vcbStatus,X
|
|
ClosEnd CLC
|
|
RTS
|
|
|
|
ClosErr BCS FlushErr ;Don't report close all err now
|
|
|
|
Flush LDY #c_refNum ;Flush all?
|
|
LDA (parm),Y
|
|
BNE Flush1 ;No, just one of 'em
|
|
|
|
STA clsFlshErr ;Clear global flush error
|
|
LDA #$00 ;Begin at the beginning
|
|
:loop STA fcbPtr ;Save current low byte of pointer
|
|
TAY ;Index to reference number
|
|
LDA fcb+fcbRefNum,Y ;Is this reference file open?
|
|
BEQ :1 ;No, try next
|
|
JSR FlushZ ;Clean it out..
|
|
BCS FlushErr ;Return any errors
|
|
:1 LDA fcbPtr ;Bump pointer to next file control block
|
|
CLC
|
|
ADC #fcbSize
|
|
BCC :loop ;Branch if within same page
|
|
|
|
FlushEnd CLC
|
|
LDA clsFlshErr ;On last flush of a flush(0)
|
|
BEQ :Ret ;Branch if no logged errors
|
|
SEC ;Report error now
|
|
:Ret RTS
|
|
|
|
FlushZ JSR FndFCBuf ;Must set up assoc vcb & buffer locations first
|
|
BCC Flush2a ;Branch if no error encountered
|
|
FlushErr JMP GlbErr ;Check for close or flush all
|
|
|
|
Flush1 STZ clsFlshErr ;Clear gbl flush error for normal refnum flush
|
|
JSR FindFCB ;set up pointer to fcb user references
|
|
BCS FlushErr ;return any errors
|
|
|
|
Flush2a EQU * ;Test to see if file is modified
|
|
LDA fcb+fcbAttr,Y ;First test write enabled
|
|
AND #writeEnable
|
|
BEQ FlushEnd ;Branch if 'read only'
|
|
LDA fcb+fcbDirty,Y ;See if eof has been modified
|
|
BMI :11 ;Branch if it has
|
|
|
|
JSR GetFCBStat ;now test for data modified
|
|
AND #useMod+eofMod+dataMod; was written to while it's been open?
|
|
BEQ FlushEnd ;Branch if file not modified
|
|
|
|
:11 JSR GetFCBStat ;Now test for data modified
|
|
AND #dataMod ;Does current data buffer need
|
|
BEQ :12 ; to be written? Branch if not
|
|
JSR WrFCBData ;If so, go write it stupid!
|
|
BCS FlushErr
|
|
|
|
:12 JSR GetFCBStat ;Check to see if the index block
|
|
AND #idxMod ; (tree files only) needs to be written
|
|
BEQ :13 ;Branch if not...
|
|
JSR WrFCBIdx
|
|
BCS FlushErr ;Return any errors
|
|
|
|
:13 LDA #fcbEntNum ;Now prepare to update directory
|
|
TAX
|
|
ORA fcbPtr ;(This should preserved Carry-bit)
|
|
TAY
|
|
OwnerMov LDA fcb,Y ;Note: this code depends on the
|
|
STA d_dev-1,X ; defined order of the file control
|
|
DEY ; block and the temporary directory
|
|
DEX ; area in 'workspc'! *************
|
|
BNE OwnerMov
|
|
|
|
STA DevNum
|
|
LDA d_head ;Read the directory header for this file
|
|
LDX d_head+1
|
|
JSR RdBlkAX ;Read it into the general purpose buffer
|
|
BCS FlushErr ;Branch if error
|
|
JSR MoveHeadZ ;Move header info
|
|
LDA d_entBlk ;Get address of directory block
|
|
LDY d_entBlk+1 ; that contains the file entry
|
|
CMP d_head ;Test to see if it's the same block that
|
|
BNE FlsHdrBlk ; the header is in. Branch if not
|
|
CPY d_head+1
|
|
BEQ Flush5 ;Branch if header block = entry block
|
|
|
|
FlsHdrBlk STA blockNum
|
|
STY blockNum+1
|
|
JSR RdGBuf ;Get block with file entry in general buffer
|
|
|
|
Flush5 JSR EntCalc ;Set up pointer to entry
|
|
JSR MovEntry ;Move entry to temp entry buffer in 'workspc'
|
|
|
|
LDY fcbPtr ;Update 'blocks used' count
|
|
LDA fcb+fcbBlksUsed,Y
|
|
STA d_file+d_usage
|
|
LDA fcb+fcbBlksUsed+1,Y
|
|
STA d_file+d_usage+1;hi byte too...
|
|
|
|
LDX #$00 ;and move in end of file mark
|
|
EOFupdate LDA fcb+fcbEOF,Y ; whether we need to or not
|
|
STA d_file+d_eof,X
|
|
INX ;Move all three bytes
|
|
CPX #$03
|
|
BEQ :21
|
|
LDA fcb+fcbFirst,Y ;Also move in the address of
|
|
STA d_file+d_first-1,X; the file's first block since
|
|
INY ; it might have changed since the file
|
|
BNE EOFupdate ; first opened. Branch always taken
|
|
|
|
:21 LDA fcb+fcbStorTyp-2,Y;the last thing to update
|
|
ASL ; is storage type (y=fcbPtr+2)
|
|
ASL ;(shift it into the hi nibble)
|
|
ASL
|
|
ASL
|
|
STA scrtch
|
|
LDA d_file+d_stor ;Get old type byte (it might be the same)
|
|
AND #$0F ;Strip off old type
|
|
ORA scrtch ;Add in the new type,
|
|
STA d_file+d_stor ; & put it away
|
|
JSR ReviseDir ;Go update directory!
|
|
BCS GlbErr
|
|
|
|
LDY fcbPtr ;Mark
|
|
LDA fcb+fcbDirty,Y ; FCB/directory
|
|
AND #$FF-fcbMod ; as not
|
|
STA fcb+fcbDirty,Y ; dirty
|
|
LDA d_dev ;See if bitmap should be written
|
|
CMP bmaDev ;Is it in same as current file?
|
|
BNE :22 ;Yes, put it on the disk if necessary
|
|
JSR UpdateBitMap ;Go put it away
|
|
BCS GlbErr
|
|
:22 CLC
|
|
RTS
|
|
|
|
GlbErr LDY #c_refNum ;Report error immediately
|
|
PHA ; only if not a close all or flush all
|
|
LDA (parm),Y
|
|
BNE :31 ;Not an 'all' so report now
|
|
CLC
|
|
PLA
|
|
STA clsFlshErr ;Save for later
|
|
RTS
|
|
:31 PLA
|
|
RTS
|
|
|
|
* Get status of FCB
|
|
|
|
GetFCBStat LDY fcbPtr ;Index to fcb
|
|
LDA fcb+fcbStatus,Y ;Return status byte
|
|
RTS ;That is all...
|
|
|
|
SetErr LDA #invalidAccess
|
|
SEC
|
|
EOFret RTS
|
|
|
|
***********************************************************
|
|
* SETEOF Call
|
|
|
|
SetEOF JSR GfcbStorTyp ;Only know how to move eof of tree, sapling, or seed
|
|
CMP #tree+1
|
|
BCS SetErr
|
|
ASL
|
|
ASL
|
|
ASL
|
|
ASL ;=$10,$20,$30
|
|
STA storType ;May be used later for trimming the tree...
|
|
LDA fcb+fcbAttr,Y ;Now check to insure write is enabled
|
|
AND #writeEnable ;Can we set new eof?
|
|
BEQ SetErr ;Nope, access error
|
|
|
|
JSR TestWrProt ;Find out if mod is posible (H/W write protect)
|
|
BCS SetErr
|
|
|
|
LDY fcbPtr ;Save old EOF
|
|
INY
|
|
INY
|
|
LDX #$02 ; so it can be seen
|
|
SetSave LDA fcb+fcbEOF,Y ; whether blocks need
|
|
STA oldEOF,X ; to be released
|
|
DEY ; upon
|
|
DEX ; contraction
|
|
BPL SetSave ;All three bytes of the eof
|
|
|
|
LDY #c_eof+2
|
|
LDX #$02
|
|
NewEOFPos LDA (parm),Y ;Position mark to new EOF
|
|
STA tPosll,X
|
|
DEY
|
|
DEX
|
|
BPL NewEOFPos
|
|
|
|
LDX #$02 ;Point to third byte
|
|
PurgeTest LDA oldEOF,X ;See if EOF moved backwards
|
|
CMP tPosll,X ; so blocks can
|
|
BCC EOFset ; be released (branch if not)
|
|
BNE Purge ;Branch if blocks to be released
|
|
DEX
|
|
BPL PurgeTest ;All three bytes
|
|
|
|
EOFset LDY #c_eof+2
|
|
LDX fcbPtr ;Place new end of file into FCB
|
|
INX
|
|
INX
|
|
:loop LDA (parm),Y
|
|
STA fcb+fcbEOF,X
|
|
DEX
|
|
DEY
|
|
CPY #c_eof ;All three bytes moved?
|
|
BCS :loop ;Branch if not...
|
|
JMP FCBUsed ;Mark fcb as dirty... all done
|
|
|
|
Purge JSR Flush1 ;Make sure file is current
|
|
BCS EOFret
|
|
LDX dataPtr+1 ;Restore pointer to index block
|
|
INX
|
|
INX ;(zero page conflict with dirPtr)
|
|
STX tIndex+1
|
|
LDX dataPtr
|
|
STX tIndex
|
|
LDY fcbPtr ;Find out if eof < mark
|
|
INY
|
|
INY
|
|
LDX #$02
|
|
NewEOFtest LDA fcb+fcbMark,Y
|
|
CMP tPosll,X ;Compare until not equal or carry clear
|
|
BCC SetEOF1 ;branch if eof>mark (mark is b4 new EOF)
|
|
BNE SetEOF0 ;branch if eof<mark
|
|
DEY
|
|
DEX
|
|
BPL NewEOFtest ;Loop on all three bytes
|
|
|
|
SetEOF0 LDY fcbPtr
|
|
LDX #$00
|
|
FakeEOF LDA tPosll,X ;Fake position, correct position
|
|
STA fcb+fcbMark,Y
|
|
INY ; will be made below...
|
|
INX ;Move all three bytes
|
|
CPX #$03
|
|
BNE FakeEOF
|
|
|
|
SetEOF1 JSR TakeFreeCnt ;Force proper free blk cnt before releasing blocks
|
|
LDA tPosll ;Now prepare for purge of excess blocks...
|
|
STA dSeed ;All blocks and bytes beyond new
|
|
LDA tPoslh ; EOF must be zeroed!
|
|
STA dSap
|
|
AND #$01
|
|
STA dSeed+1 ;(=0/1)
|
|
LDA tPosHi
|
|
LSR
|
|
STA dTree
|
|
ROR dSap ;Pass position in terms of block & bytes
|
|
LDA dSeed ;Now adjust for boundaries of $200
|
|
ORA dSeed+1 ;(block boundaries)
|
|
BNE SetEOF3 ;Branch if no adjustment necessary
|
|
|
|
LDA dSap ;Get correct block positions
|
|
SEC ; for sap & tree levels
|
|
SBC #$01
|
|
STA dSap ;Deallocate for last (phantom) block
|
|
LDA #$02 ; & don't modify last data block
|
|
BCS SetEOF2 ;branch if tree level unaffected
|
|
DEC dTree ;But if it is affected, make sure new eof # 0
|
|
BPL SetEOF2 ;Branch if new eof not zero
|
|
|
|
LDA #$00 ;Otherwise, just make a null seed out of it
|
|
STA dTree
|
|
STA dSap
|
|
SetEOF2 STA dSeed+1 ;(On fall thru, =0 else = 2)
|
|
SetEOF3 LDY fcbPtr ;Also must pass file's first block addr
|
|
LDA fcb+fcbFirst,Y ; which is its keyblk
|
|
STA firstBlkL
|
|
LDA fcb+fcbFirst+1,Y
|
|
STA firstBlkH
|
|
|
|
STZ deBlock ;Lastly, number of blocks to be
|
|
STZ deBlock+1 ; freed should be initialized
|
|
JSR DeTree ;Go defoliate...
|
|
PHP ;Save any error status until
|
|
PHA ; FCB is cleaned up!
|
|
|
|
SEC
|
|
LDY fcbPtr
|
|
LDX #$00
|
|
AdjFCB LDA firstBlkL,X
|
|
STA fcb+fcbFirst,Y ;Move in posible new first file block addr
|
|
LDA fcb+fcbBlksUsed,Y;Adjust usage count also
|
|
SBC deBlock,X
|
|
STA fcb+fcbBlksUsed,Y
|
|
INY
|
|
INX
|
|
TXA
|
|
AND #$01 ;Test for both bytes adjusted
|
|
BNE AdjFCB ; without disturbing carry
|
|
|
|
LDA storType ;get possibly modified storage type
|
|
LSR
|
|
LSR
|
|
LSR
|
|
LSR
|
|
LDY fcbPtr ;save it in fcb
|
|
STA fcb+fcbStorTyp,Y
|
|
JSR ClrStats ;Make it look as though position has
|
|
JSR DvcbRev ; nothing allocated, update total blocks in VCB
|
|
|
|
LDY fcbPtr ;Now correct position stuff
|
|
INY
|
|
INY
|
|
LDX #$02
|
|
CorrectPos LDA fcb+fcbMark,Y ;Tell RdPosn to go to correct
|
|
STA tPosll,X
|
|
EOR #$80 ; position from incorrect place
|
|
STA fcb+fcbMark,Y
|
|
DEY
|
|
DEX
|
|
BPL CorrectPos
|
|
|
|
JSR RdPosn ;Go do it!!!
|
|
BCC Purge1 ;Branch if no error
|
|
TAX ;Otherwise report latest error
|
|
PLA
|
|
PLP
|
|
TXA ;Restore latest error code to stack
|
|
SEC
|
|
PHP
|
|
PHA ;Save new error
|
|
Purge1 EQU * ;Mark file as in need of a flush and
|
|
JSR EOFset ; update FCB with new end of file
|
|
JSR Flush1 ;Now go do flush
|
|
BCC :1 ;Branch if no error
|
|
|
|
TAX ;Save latest error
|
|
PLA ;Clean previous error off stack
|
|
PLP
|
|
TXA ;Restore latest error code to stack
|
|
SEC ;Set the carry to show error condition
|
|
PHP ;Restore error status to stack
|
|
PHA ; & the error code
|
|
:1 PLA ;Report any errors that may have cropped up
|
|
PLP
|
|
RTS
|
|
|
|
GetEOF LDX fcbPtr ;Index to end of file mark
|
|
LDY #c_eof ; & index to user's call parameters
|
|
OutEOF LDA fcb+fcbEOF,X
|
|
STA (parm),Y
|
|
INX
|
|
INY
|
|
CPY #c_eof+3
|
|
BNE OutEOF ;Loop until all three bytes are moved
|
|
CLC ;No errors
|
|
RTS |