mirror of
https://github.com/A2osX/A2osX.git
synced 2024-11-25 05:32:20 +00:00
8dea8d82c3
A2osX : bugfixes in KERNEL
978 lines
26 KiB
Plaintext
978 lines
26 KiB
Plaintext
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 tposll-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 tposlh 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 tposhi 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
|
||
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 tposhi 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 tposlh is new position < 512 ?
|
||
lsr
|
||
ora tposhi
|
||
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 tposhi 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 tposhi 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 tposll,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 tposlh
|
||
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 tposlh indicated by carry.
|
||
|
||
lda XDOS.FCBs+FCB.MARK+2,y
|
||
sbc tposhi
|
||
|
||
bcc L3FB9 if set, position forward. otherwise,
|
||
|
||
L3FAB ldy #$00 read directory file in reverse order.
|
||
jsr dirpos1 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 dirpos1 read next directory block
|
||
bcs L3FD6 if error.
|
||
|
||
dec cntent
|
||
bne L3FB9 loop if position not found in this block
|
||
|
||
beq svmark branch always.
|
||
*--------------------------------------
|
||
dirpos1 lda (ZP.DataPtr),y get link address of previous or next
|
||
sta ZP.BLKNUM directory block.
|
||
cmp #$01 test for null byte into carry
|
||
iny but first be sure there is a link.
|
||
lda (ZP.DataPtr),y get the rest of the link.
|
||
bne L3FD8 branch if certain link exists.
|
||
|
||
bcs L3FD8 was the low part null as well ?
|
||
|
||
lda #MLI.E.EOF something is wrong with directory file!
|
||
|
||
sec error.
|
||
|
||
L3FD6 rts
|
||
|
||
L3FD8 sta ZP.BLKNUM+1
|
||
*--------------------------------------
|
||
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
|
||
*--------------------------------------
|
||
*rfcbidx lda #$01 prepare to read index block : read command
|
||
* sta ZP.CMDNUM
|
||
|
||
* ldx #zpt address of current index buffer.
|
||
* XDOS.FileIOPtrX go read index block.
|
||
* bcs L400C error
|
||
|
||
* 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
|
||
|
||
** clc
|
||
|
||
*L400C 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 ofcbtbl,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 tposll,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
|