A2osX/ProDOS.FX/ProDOS.S.XDOS.C.txt
burniouf 74acfeccd1 KERNEL & DRVs : lot of fixes around DEV.Open() , KCONFIG
SH : fiw for line wrap
ProDOS.FX : removed a strange bug inherited from 2.0.3 trashing FCBs
2023-11-26 14:17:41 +01:00

955 lines
26 KiB
Plaintext
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

NEW
AUTO 3,1
*--------------------------------------
XDOS.DeallocAX stx bmcnt high address of block.
* pha save low address.
ldx XDOS.VCBPtr check that bitmap block address is
ldy XDOS.VCBs+VCB.TBLK+1,x valid given the total # of blocks
cpy bmcnt on the volume.
* pla
bcc L3C8C branch if invalid
tax
and #$07 bit to be or'd in
tay
lda whichbit,y (shifting takes 7 bytes, but is slower)
sta nofree save bit pattern.
txa low block address.
ldx #3
.1 lsr bmcnt
ror
dex
bne .1
* lsr bmcnt
* ror
* lsr bmcnt
* ror
sta bmptr save pointer.
lsr bmcnt transfer bit which is page of bitmap
rol half
jsr XDOS.GetBM make sure device is correct one.
bcs L3C8B error.
lda XDOS.BM.Idx current map.
cmp bmcnt is in-core bitmap the correct one ?
beq L3C64 branch if yes.
jsr XDOS.FlushBM put current map away.
bcs L3C8B error.
lda bmcnt get map #
ldx XDOS.VCBPtr
sta XDOS.VCBs+VCB.BMAPIDX,x and make it current.
lda XDOS.BM.DevID
jsr XDOS.ReadBMDevA read it into buffer
bcs L3C8B
L3C64 ldy bmptr index to byte
lsr half
lda nofree (get indiviual bit)
bcc bmbufhi branch if on page 1 of bitmap
ora XDOS.BMBuf+$100,y
sta XDOS.BMBuf+$100,y
bcs L3C7D always.
bmbufhi ora XDOS.BMBuf,y this address + 2 is used as an absolute reference to XDOS.BMBuf high byte.
sta XDOS.BMBuf,y
L3C7D sec mark bitmap as modified
ror XDOS.BM.Status
inc deblock inc count of blocks deallocated
bne L3C8A
inc deblock+1
L3C8A clc
L3C8B rts
L3C8C lda #MLI.E.BADFS bitmap block # impossible.
sec bitmap disk address wrong
rts (maybe data masquerading as indx block)
*--------------------------------------
XDOS.GetFreeBlk jsr XDOS.GetBM get address of bitmap.
bcs L3CB8 error.
L3C95 ldy #$00 begin search at start of bitmap block.
sty half which half (page) to search
L3C9A lda XDOS.BMBuf,y
bne L3CB9 free blocks indicated by 'on' bits
iny
bne L3C9A check all in 1st page.
inc half now search page 2.
inc basval base value = base address / 2048.
L3CA8 lda XDOS.BMBuf+$100,y search 2nd half for free block
bne L3CB9
iny
bne L3CA8
inc basval add 2048 offset for next page.
jsr XDOS.NextBM get next bitmap (if exists) and
bcc L3C95 update vcb. branch if no error.
L3CB8 rts return error.
L3CB9 sty bmptr save index pointer to valid bit group.
lda basval prep for block address calculation
sta scrtch+1
tya address of bit pattern.
ldx #3
.1 asl multiply this and basval by 8
rol scrtch+1
dex
bne .1
tax low address within 7 of actual address
sec
lda half
beq L3CDB branch if allocating from 1st half.
lda XDOS.BMBuf+$100,y get pattern from 2nd page.
bcs L3CDE always.
L3CDB lda XDOS.BMBuf,y get bit pattern from 1st page.
L3CDE rol find left most 'on' bit
bcs L3CE4 if found.
inx adjust low address.
bne L3CDE always.
L3CE4 lsr restore pos'n of all but left most bit.
bcc L3CE4 loop until mark moves into carry.
stx scrtch save low address.
ldx half which half of bitmap ?
bne L3CF4 if page 2.
sta XDOS.BMBuf,y
beq L3CF7 always.
L3CF4 sta XDOS.BMBuf+$100,y update to show allocated block in use.
L3CF7 sec indicate map is modified.
ror XDOS.BM.Status
ldx XDOS.VCBPtr subtract 1 from total free vcb blocks
lda XDOS.VCBs+VCB.FBLK,x to account for newly allocated block.
bne .7
dec XDOS.VCBs+VCB.FBLK+1,x
.7 dec XDOS.VCBs+VCB.FBLK,x
lda scrtch return address in y,a of newly
ldy scrtch+1 allocated block.
clc no errors.
rts
*--------------------------------------
XDOS.NextBM ldx XDOS.VCBPtr inc to next bitmap, but 1st make sure there is another one.
lda XDOS.VCBs+VCB.TBLK+1,x
lsr
lsr
lsr
lsr
cmp XDOS.VCBs+VCB.BMAPIDX,x are there more maps ?
beq L3D60 if no more to look at.
inc XDOS.VCBs+VCB.BMAPIDX,x add 1 to current map
jsr XDOS.FlushBM
XDOS.GetBM ldy XDOS.VCBPtr
lda XDOS.VCBs+VCB.DEV,y get device #.
cmp XDOS.BM.DevID does this map match this device ?
beq L3D4A yes.
jsr XDOS.FlushBM otherwise, save other volume's bitmap
bcs L3D5F
ldy XDOS.VCBPtr
lda XDOS.VCBs+VCB.DEV,y
sta XDOS.BM.DevID and read in fresh bitmap for this dev.
L3D4A bit XDOS.BM.Status is it already modified ?
bmi L3D54 yes, return pointer
jsr XDOS.ReadBMDevA otherwise read in fresh bitmap.
bcs L3D5F if error.
L3D54 ldy XDOS.VCBPtr get relative block # of bitmap.
lda XDOS.VCBs+VCB.BMAPIDX,y
asl 2 pages per block
sta basval
clc no errors.
L3D5F rts
L3D60 lda #MLI.E.VOLFULL request can't be filled
sec error
rts
*--------------------------------------
XDOS.FlushBM clc
bit XDOS.BM.Status is current map modified ?
bpl .9 no.
jsr XDOS.WriteBM update device.
bcs .9 if error on writing.
stz XDOS.BM.Status mark bitmap buffer as free
lda #0 MUST EXIT WITH A=0
.9 rts
*--------------------------------------
XDOS.ReadBMDevA sta XDOS.BM.DevID read bitmap specified by dev and vcb.
ldy XDOS.VCBPtr get lowest map # with free blocks in it
lda XDOS.VCBs+VCB.BMAPIDX,y
sta XDOS.BM.Idx associate offset with bitmap ctrl block.
clc add this # to the base address of
adc XDOS.VCBs+VCB.BMAP,y 1st bitmap and save in bmadadr which
sta XDOS.BM.BlkNum is address of bitmap to be used.
lda XDOS.VCBs+VCB.BMAP+1,y
adc #$00
sta XDOS.BM.BlkNum+1
lda #$01 read device command
.HS 2C BIT ABS
XDOS.WriteBM lda #$02 write command.
sta ZP.CMDNUM
lda GP.DEVNUM save current dev #
pha
lda XDOS.BM.DevID get bitmap's dev #
sta GP.DEVNUM
lda XDOS.BM.BlkNum and disk address
sta ZP.BLKNUM
lda XDOS.BM.BlkNum+1
sta ZP.BLKNUM+1
lda /XDOS.BMBuf
* lda bmbufhi+2 address of the buffer (low = 0)
jsr XDOS.RWBlock
plx keep A=error code if CS
stx GP.DEVNUM
rts
*--------------------------------------
.DO LOWERCASE=1
XDOS.WriteGBufDir
jsr XDOS.PackGBuf
bra XDOS.WriteGBuf
.FIN
*--------------------------------------
XDOS.ReadGBufDEKeyPtr
lda XDOS.DE.KeyPtr read 1st block of directory into XDOS.GBuf
ldx XDOS.DE.KeyPtr+1
.DO LOWERCASE=1
XDOS.ReadGBufAXDir
jsr XDOS.ReadGBufAX
bcc XDOS.UnpackGBuf
rts
.FIN
XDOS.ReadGBufAX sta ZP.BLKNUM
stx ZP.BLKNUM+1
XDOS.ReadGBuf lda #$01 read command.
.HS 2C BIT ABS
XDOS.WriteGBuf lda #$02 write command
sta ZP.CMDNUM pass to device handler.
lda /XDOS.GBuf general buffer.
XDOS.RWBlock sta ZP.BUFPTR+1 buffer high.
stz ZP.BUFPTR buffer low (always on page boundary)
jmp XDOS.FileIO2
*--------------------------------------
.DO LOWERCASE=1
XDOS.CheckAndUnpackGBuf
lda XDOS.GBuf+35
sta XDOS.DH.EL
ldy XDOS.GBuf+36
sty XDOS.DH.EPB
cmp #$27
bne .9
cpy #$0D
beq XDOS.UnpackGBuf
.9 lda #MLI.E.NOTPRODOS
sec
rts
XDOS.UnpackGBuf jsr XDOS.ZPT.InitGBuf
ldx XDOS.DH.EPB
.1 jsr XDOS.ZPT.Unpack
dex
beq .8
jsr XDOS.ZPT.Next
bra .1
.8 clc make sure CC
rts
*--------------------------------------
*XDOS.PackGBuf.Bitmap .BS 2
XDOS.PackGBuf.Bitmap .EQ sos
*--------------------------------------
XDOS.PackGBuf jsr XDOS.ZPT.InitGBuf
ldx XDOS.DH.EPB
.1 lda (zpt)
and #$0F
beq .6
stz XDOS.PackGBuf.Bitmap
stz XDOS.PackGBuf.Bitmap+1
tay
.2 lda (zpt),y
cmp #'a'
bcc .5
cmp #'z'+1
bcs .5
eor #$20 to uppercase
sta (zpt),y
cpy #8 CS if MIN_VERSION to use
bcs .3
lda whichbit,y
tsb XDOS.PackGBuf.Bitmap+1
bra .4
.3 lda whichbit-8,y
tsb XDOS.PackGBuf.Bitmap
.4 lda #$80
tsb XDOS.PackGBuf.Bitmap+1
.5 dey
bne .2
ldy #$1C VERSION
lda XDOS.PackGBuf.Bitmap
sta (zpt),y
iny MIN_VERSION
lda XDOS.PackGBuf.Bitmap+1
sta (zpt),y
.6 jsr XDOS.ZPT.Next
dex
bne .1
rts
.FIN
*--------------------------------------
XDOS.GetMark ldx XDOS.FCBPtr index to open fcb.
ldy #$02 index to user's mark parameter.
.1 lda XDOS.FCBs+FCB.MARK,x transfer current position
sta (ZP.A3L),y to user's parameter list
inx
iny
cpy #$05 transfer 3 bytes
bne .1
clc
rts
L3DFD lda #MLI.E.BEYEOF invalid position
sec
rts
*--------------------------------------
XDOS.SetMark ldy #$04 index to user's desired position.
ldx XDOS.FCBPtr file's control block index.
inx inc by 2 for index to hi eof
inx
sec indicate comparisons are necessary.
.1 lda (ZP.A3L),y move it to 'tpos'
sta XDOS.TmpPos-2,y
bcc .2 branch if mark < eof
cmp XDOS.FCBs+FCB.EOF,x
bcc .2 branch if mark qualifies.
bne L3DFD branch if mark > eof (invalid position)
dex
.2 dey move/compare next lower byte of mark.
tya test for all bytes moved/tested.
eor #$01 preserves carry status.
bne .1 branch if more.
*--------------------------------------
rdposn ldy XDOS.FCBPtr test to see if new position is
lda XDOS.FCBs+FCB.MARK+1,y within the same (current) data block.
and #$FE
sta scrtch
lda XDOS.TmpPos+1 middle byte of new position
sec
sbc scrtch
sta scrtch
bcc L3E44 branch if < current position.
cmp #$02 must be within 512 bytes of beginning
bcs L3E44 of current position.
lda XDOS.TmpPos+2 make sure within the same 64k.
cmp XDOS.FCBs+FCB.MARK+2,y
bne L3E44 branch if not.
jmp svmark if so, adj fcb, position ptr and return.
L3E44 lda XDOS.FCBs+FCB.STYPE,y determine file type for positioning.
beq L3E50 0 = invalid file type.
cmp #$04 tree class file?
bcc L3E59 yes, go position.
jmp dirmark no, test for dir type.
L3E50
* ldy #$A4 ??????? clear illegal filetype entry in fcb
* sta XDOS.FCBs,y ??????? WILL TRASH anther FCB
lda #MLI.E.BADREF and report error
sec
rts
L3E59 lda XDOS.FCBs+FCB.STYPE,y use storage type as # of index levels
sta levels since 1=seed, 2=sapling, 3=tree.
lda XDOS.FCBs+FCB.F,y
and #FCB.F.DBLKMOD if previous data was modified then
beq L3E6B disk must be updated.
jsr XDOS.WriteDBLK
bcs L3ED4 if error.
L3E6B ldy XDOS.FCBPtr test to see if current index block
lda XDOS.FCBs+FCB.MARK+2,y is usable by checking if new
and #$FE position is within 128k of the
sta scrtch beginning of current sapling level
lda XDOS.TmpPos+2 chunk.
sec
sbc scrtch
bcc L3E9D branch if a new index block is needed.
cmp #$02 is new position within 128k of old ?
bcs L3E9D branch if not.
ldx levels is it a seed file ?
dex
bne datlevel1 no, use current indexes.
L3E89 lda XDOS.TmpPos+1 is new position < 512 ?
lsr
ora XDOS.TmpPos+2
bne L3EEF no, mark both data and index block as
lda XDOS.FCBs+FCB.1stBLK,y unallocated. 1st block is only block
sta ZP.BLKNUM and it's data.
lda XDOS.FCBs+FCB.1stBLK+1,y high block address.
jmp rnewpos go read in block and set statuses.
L3E9D lda XDOS.FCBs+FCB.F,y check to see if previous index block
and #FCB.F.IBLKMOD was modified.
beq L3EA9 read in over it if current up to date.
jsr XDOS.WriteIBLK go update index on disk (fcb block addr)
bcs L3ED4
L3EA9 ldx levels be sure there is a top index
cpx #$03 before reading it...
beq posindex branch if file is a tree.
lda XDOS.TmpPos+2 is new position within range of a
lsr sapling file (less than 128k) ?
php save results
lda #$07 (no level is allocated for new pos'n)
plp restore z-flag.
bne L3F18 go mark all as dummy.
jsr XDOS.ClrFCBStatus clr status bits 0,1,2 (index/data/alloc)
dex check for seed
beq L3E89 if seed, check for position < 512.
jsr rfcbfst go get only index block.
bcs L3ED4 if error.
jsr XDOS.UpdateFCBIBlk save newly loaded index block's address.
datlevel1 bra datlevel branch always
L3ED4 rts
posindex jsr XDOS.ClrFCBStatus clr all alloc requirements for previous
jsr rfcbfst position. get highest level index block
bcs L3ED4
lda XDOS.TmpPos+2 then test for a sap level index block
lsr
tay
lda (zpt),y
inc zpt+1
cmp (zpt),y (both high and low = 0 if no index exists)
bne saplevel
tax are both bytes 0 ?
bne saplevel
dec zpt+1
L3EEF lda #$03 show neither index or data block alloc'd
bra L3F18
saplevel sta ZP.BLKNUM read in next lower index block.
lda (zpt),y (high address)
sta ZP.BLKNUM+1
dec zpt+1
* jsr rfcbidx read in sapling level
lda #$01 prepare to read index block : read command
sta ZP.CMDNUM
ldx #zpt address of current index buffer.
jsr XDOS.FileIOPtrX go read index block.
bcs L3ED4 error
jsr XDOS.UpdateFCBIBlk save block address of this index in fcb
datlevel jsr XDOS.Tpos2Y get block address of data block
lda (zpt),y data block address low
inc zpt+1
cmp (zpt),y
bne L3F51
tax
bne L3F51
lda #$01 show data block as never been allocated
dec zpt+1
L3F18 jsr XDOS.SetFCBStatus set status to show what's missing
lsr discard bit that says data block
lsr unallocated because carry indicates if
jsr XDOS.ZeroData index block is invalid and needs to be zeroed.
bcc svmark branch if it doesn't need zeroed
jsr XDOS.ZeroIndex zero index block in user's i/o buffer
bra svmark
*--------------------------------------
XDOS.ZeroData lda #$00
tay
inc ZP.DataPtr+1
jsr .1
dec ZP.DataPtr+1
.1 sta (ZP.DataPtr),y
iny
bne .1
rts
*--------------------------------------
L3F51 sta ZP.BLKNUM get data block of new position
lda (zpt),y (high address)
dec zpt+1
rnewpos sta ZP.BLKNUM+1
jsr XDOS.ReadFCB.DBLK
bcs L3F86 if error.
jsr XDOS.ClrFCBStatus show whole chain is allocated.
*--------------------------------------
svmark ldy XDOS.FCBPtr update position in fcb
iny
iny
ldx #$02
L3F68 lda XDOS.FCBs+FCB.MARK,y save old mark in case calling routine
sta oldmark,x fails later.
lda XDOS.TmpPos,x
sta XDOS.FCBs+FCB.MARK,y
dey
dex move 3 byte position marker
bpl L3F68
clc set up indirect address to buffer
lda ZP.DataPtr page pointed to by the current
sta sos position marker.
lda XDOS.TmpPos+1
and #$01
adc ZP.DataPtr+1
sta sos+1
L3F86 rts carry set if error
*--------------------------------------
dirmark cmp #$0D is it a directory ?
beq L3F9C yes...
lda #MLI.E.INCFF no, so compatability problem.
jsr GP.SYSERR should not have been opened !!!
L3F9C lda scrtch recover results of previous subtraction.
lsr use difference as counter for how many
sta cntent blocks must be read to get to new pos'n.
lda XDOS.FCBs+FCB.MARK+1,y test for positive direction
cmp XDOS.TmpPos+1 indicated by carry.
lda XDOS.FCBs+FCB.MARK+2,y
sbc XDOS.TmpPos+2
bcc L3FB9 if set, position forward. otherwise,
L3FAB ldy #$00 read directory file in reverse order.
jsr XDOS.DirSeek read previous block.
bcs L3FD6 if error.
inc cntent count up to 128.
bpl L3FAB loop if more blocks to pass over.
bmi svmark always.
L3FB9 ldy #$02 position is forward from current.
jsr XDOS.DirSeek read next directory block
bcs L3FD6 if error.
dec cntent
bne L3FB9 loop if position not found in this block
beq svmark branch always.
*--------------------------------------
XDOS.DirSeek lda (ZP.DataPtr),y get link address of previous or next
sta ZP.BLKNUM directory block.
iny
lda (ZP.DataPtr),y get the rest of the link.
sta ZP.BLKNUM+1
ora ZP.BLKNUM but first be sure there is a link.
bne XDOS.ReadFCB.DBLK branch if certain link exists.
lda #MLI.E.EOF something is wrong with directory file!
sec error.
L3FD6 rts
*--------------------------------------
XDOS.ReadFCB.DBLK
lda #$01 read command
sta ZP.CMDNUM
ldx #ZP.DataPtr points at address of data buffer.
jsr XDOS.FileIOPtrX go do file input.
bcs .9 error.
ldy XDOS.FCBPtr
lda ZP.BLKNUM
sta XDOS.FCBs+FCB.DBLK,y save block # just read in fcb.
lda ZP.BLKNUM+1
sta XDOS.FCBs+FCB.DBLK+1,y
* clc
.9 rts
*--------------------------------------
wfcbfst jsr XDOS.FlushBM update the bitmap and write file's 1st block.
ldx #$02 write command
.HS 2C BIT ABS
rfcbfst ldx #$01 read command.
lda #FCB.1stBLK
ora XDOS.FCBPtr add offset to XDOS.FCBPtr
tay
txa get back command
ldx #zpt rd block into index portion of file buf
*--------------------------------------
XDOS.FileIOPtrXCmdABlkY
sta ZP.CMDNUM command
lda XDOS.FCBs,y get disk block address from fcb.
sta ZP.BLKNUM block 0 not legal
bne .1
lda XDOS.FCBs+1,y high address of disk block
bne .2
lda #$0C Block = $0000, allocation error.
jsr GP.SYSDEATH doesn't return...
.1 lda XDOS.FCBs+1,y
.2 sta ZP.BLKNUM+1
*--------------------------------------
XDOS.FileIOPtrX lda $00,x get memory address of buffer from
sta ZP.BUFPTR page zero pointed to by x register
lda $01,x
sta ZP.BUFPTR+1 and pass address to device handler
jsr XDOS.FCBDevIDSelect
XDOS.FileIO2 sec also, set to indicate reg call made to
ror ioaccess device handler.
lda GP.DEVNUM transfer device # for dispatcher
sta ZP.UNITNUM to convert to unit #.
stz GP.ERROR clear global error code.
jmp XDOS.DevCall call the driver.
*--------------------------------------
XDOS.WriteDBLK ldx #ZP.DataPtr point at memory address with x and
lda #FCB.DBLK disk address with y.
ora XDOS.FCBPtr add offset to XDOS.FCBPtr
tay and put in y.
lda #$02 write data block.
jsr XDOS.FileIOPtrXCmdABlkY
bcs L4096 if errors.
lda #$BF mark data status as current.
bra XDOS.ResetFCBStatus
XDOS.WriteIBLK jsr XDOS.FlushBM update bitmap.
ldx #zpt point to address of index buffer
lda #FCB.IBLK and block address of that index block.
ora XDOS.FCBPtr
tay
lda #$02
jsr XDOS.FileIOPtrXCmdABlkY
bcs L4096 if errors.
lda #$7F mark index status as current.
*--------------------------------------
XDOS.ResetFCBStatus
ldx XDOS.FCBPtr
and XDOS.FCBs+FCB.F,x
sta XDOS.FCBs+FCB.F,x
L4096 rts
*--------------------------------------
XDOS.Open jsr XDOS.FindFileOrVol look up the file.
bcs L4096 if not, then error.
L40A0 jsr XDOS.IsOpened are any other files writing to this
bcc L40AD same file ? branch if not.
L40A5 lda #MLI.E.OPEN file is busy, shared access not allowed.
.HS 2C
L40A9 lda #MLI.E.UNSUPST file is wrong storage type.
.HS 2C
L40AB lda #MLI.E.FCBFULL fcb full error.
sec
rts
L40AD lda fcbflg if this byte <> 0 then free fcb found
beq L40AB and available for use.
ldx XDOS.FCBPtr get address of 1st free fcb found.
L40B9 ldy #FCB
L40BD stz XDOS.FCBs,x but clean it first.
inx
dey
bne L40BD
ldy #0
ldx XDOS.FCBPtr
L40CB lda XDOS.DE.DevID,y move ownership info.
sta XDOS.FCBs+FCB.DEVID,x note: this code depends upon the defined
inx order of both the fcb and directory entry buffer.
iny
cpy #6
bne L40CB
lda XDOS.DE.Filename get storage type and
jsr XDOS.SetFCBSType
tax save in x for later comparison
lda XDOS.DE.Access get file's attributes and use it
and #$03 as a default access request.
cpx #$0D if directory, don't allow write enable.
bne L40EB
and #$01 read enabled bit
L40EB sta XDOS.FCBs+FCB.ACCESS,y
and #$02 check for write enabled request.
beq L40F7 branch for open as read-only
lda totent otherwise, be sure no one else is
bne L40A5 reading the same file. branch if busy.
L40F7 cpx #$04 is it a tree file type ?
bcc L40FF yes.
cpx #$0D is it a directory type ?
bne L40A9 if not, wrong storage type.
L40FF ldx #$06 move address of 1st block of file, end
L4101 sta ZP.BLKNUM+1 of file and current usage count.
lda XDOS.FCBPtr
ora XDOS.DE2FCB,x this is done via a translation table
tay between directory info and fcb.
lda XDOS.DE.KeyPtr,x
sta XDOS.FCBs,y
dex
bpl L4101 last loop stores hi address of 1st block
sta ZP.BLKNUM and this is the low one.
ldx XDOS.FCBPtr
lda cntent this was set up by 'tstopen'.
sta XDOS.FCBs,x claim fcb for this file.
jsr alcbuffr go allocate buffer in memory tables.
bcs L4147 if errors.
ldx XDOS.FCBPtr
jsr XDOS.GetFCBBufX rtn addr of bufs in data & index ptrs.
lda GP.FLEVEL mark level at which
sta XDOS.FCBs+FCB.FLEVEL,x file was opened.
lda XDOS.FCBs+FCB.STYPE,x file must be positioned at beginning.
cmp #$04 is it a tree file ?
bcs L415E no, assume a directory.
lda #$FF fool the position routine into giving
sta XDOS.FCBs+FCB.MARK+2,x a valid position with preloaded data,
ldy #$02 etc. set desired position to 0.
lda #$00
L413C sta XDOS.TmpPos,y
dey
bpl L413C
jsr rdposn let tree position routine do the rest.
bcc L4163 if successful.
L4147 pha save error code.
ldx XDOS.FCBPtr free buffer space.
stz XDOS.FCBs,x necessary to release fcb also.
lda XDOS.FCBs+FCB.BUFID,x
beq L4156 if no bufnum, ok because never alloc'd.
jsr relbuffr go release buffer.
L4156 pla error code.
sec
rts
L415E jsr XDOS.ReadFCB.DBLK read in 1st block of directory file.
bcs L4147 return error after freeing buffer & fcb.
L4163 ldx XDOS.VCBPtr index to vcb.
inc XDOS.VCBs+VCB.OFCNT,x add 1 to # of files currently open
ldx XDOS.FCBPtr index to fcb.
lda XDOS.FCBs+FCB.ID,x return ref # to user.
ldy #$05
sta (ZP.A3L),y
* clc open is successful
rts
*--------------------------------------
XDOS.IsOpened stz cntent returns the ref # of a free fcb.
stz totent flag to indicate file already open.
stz fcbflg flag indicates a free fcb is available.
lda #$00
L4188 tay index to next fcb.
ldx fcbflg test for free fcb found.
bne L4191 if already found.
inc cntent
L4191 lda XDOS.FCBs,y is this fcb in use ?
bne L41A3 yes.
txa if not, should we claim it ?
bne L41C1 branch if free fcb already found.
sty XDOS.FCBPtr save index to new free fcb.
lda #$FF set fcb flag to indicate
sta fcbflg free fcb found.
bne L41C1 branch always to test next fcb.
L41A3 tya add offset to index to ownership info
ora #$06
tay and put it back in y.
ldx #$06 index to directory entry owner info.
L41A9 lda XDOS.FCBs,y all bytes must match to say that it's
cmp XDOS.DE.DevID-1,x the same file again.
bne L41C1 if not, then next fcb.
dey index to next lower bytes.
dex
bne L41A9 loop to check all owner info.
inc totent file is already open, now see
lda XDOS.FCBs+FCB.ACCESS,y if it's already opened for write. and #$02 if so report file busy (with carry set).
and #$02 if so report file busy (with carry set).
beq L41C1 branch if this file is read access only.
sec
rts
L41C1 tya calc position of next fcb.
and #$E0 first strip any possible index offsets.
clc
adc #FCB inc to next fcb.
bcc L4188 branch if more to compare.
clc report no conflicts.
rts
*--------------------------------------
XDOS.UpdateFCBIBlk
ldy XDOS.FCBPtr
lda ZP.BLKNUM
sta XDOS.FCBs+FCB.IBLK,y save block address of this index in fcb
lda ZP.BLKNUM+1
sta XDOS.FCBs+FCB.IBLK+1,y
rts
*--------------------------------------
MAN
SAVE usr/src/prodos.fx/prodos.s.xdos.c
LOAD usr/src/prodos.fx/prodos.s
ASM