mirror of
https://github.com/A2osX/A2osX.git
synced 2024-11-25 05:32:20 +00:00
1025 lines
26 KiB
Plaintext
1025 lines
26 KiB
Plaintext
NEW
|
||
AUTO 3,1
|
||
*--------------------------------------
|
||
XDOS.DeallocAX stx bmcnt high address of block.
|
||
pha save low address.
|
||
ldx vcbptr check that bitmap block address is
|
||
lda VCBs+VCB.TBLK+1,x valid given the total # of blocks
|
||
cmp 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.
|
||
lsr bmcnt
|
||
ror get pointer to byte in block that
|
||
lsr bmcnt represents the block address.
|
||
ror
|
||
lsr bmcnt
|
||
ror
|
||
sta bmptr save pointer.
|
||
lsr bmcnt transfer bit which is page of bitmap
|
||
rol half
|
||
jsr fndbmap make sure device is correct one.
|
||
bcs L3C8B error.
|
||
|
||
lda bmacmap current map.
|
||
cmp bmcnt is in-core bitmap the correct one ?
|
||
beq L3C64 branch if yes.
|
||
|
||
jsr upbmap put current map away.
|
||
bcs L3C8B error.
|
||
|
||
lda bmcnt get map #
|
||
ldx vcbptr
|
||
|
||
sta VCBs+VCB.BMAPIDX,x and make it current.
|
||
lda bmadev
|
||
jsr gtbmap 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 bmbuf+$100,y
|
||
sta bmbuf+$100,y
|
||
bcs L3C7D always.
|
||
|
||
bmbufhi ora bmbuf,y this address + 2 is used as an absolute reference to bmbuf high byte.
|
||
sta bmbuf,y
|
||
|
||
L3C7D lda #$80 mark bitmap as modified
|
||
tsb bmastat
|
||
|
||
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)
|
||
*--------------------------------------
|
||
alc1blk jsr fndbmap 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 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 bmbuf+$100,y search 2nd half for free block
|
||
bne L3CB9
|
||
|
||
iny
|
||
bne L3CA8
|
||
|
||
inc basval add 2048 offset for next page.
|
||
jsr nxtbmap 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.
|
||
asl multiply this and basval by 8
|
||
rol scrtch+1
|
||
asl
|
||
rol scrtch+1
|
||
asl
|
||
rol scrtch+1
|
||
tax low address within 7 of actual address
|
||
sec
|
||
lda half
|
||
beq L3CDB branch if allocating from 1st half.
|
||
|
||
lda bmbuf+$100,y get pattern from 2nd page.
|
||
bcs L3CDE always.
|
||
|
||
L3CDB lda 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 bmbuf,y
|
||
beq L3CF7 always.
|
||
|
||
L3CF4 sta bmbuf+$100,y update to show allocated block in use.
|
||
|
||
L3CF7 lda #$80 indicate map is modified.
|
||
tsb bmastat
|
||
|
||
ldx vcbptr subtract 1 from total free vcb blocks
|
||
lda VCBs+VCB.FBLK,x to account for newly allocated block.
|
||
bne .7
|
||
dec VCBs+VCB.FBLK+1,x
|
||
.7 dec VCBs+VCB.FBLK,x
|
||
|
||
lda scrtch return address in y,a of newly
|
||
ldy scrtch+1 allocated block.
|
||
clc no errors.
|
||
rts
|
||
*--------------------------------------
|
||
nxtbmap ldx vcbptr inc to next bitmap, but 1st make sure there is another one.
|
||
lda VCBs+VCB.TBLK+1,x
|
||
lsr
|
||
lsr
|
||
lsr
|
||
lsr
|
||
cmp VCBs+VCB.BMAPIDX,x are there more maps ?
|
||
beq L3D60 if no more to look at.
|
||
|
||
inc VCBs+VCB.BMAPIDX,x add 1 to current map
|
||
jsr upbmap
|
||
|
||
fndbmap ldy vcbptr
|
||
lda VCBs+VCB.DEV,y get device #.
|
||
cmp bmadev does this map match this device ?
|
||
beq L3D4A yes.
|
||
|
||
jsr upbmap otherwise, save other volume's bitmap
|
||
bcs L3D5F
|
||
|
||
ldy vcbptr
|
||
lda VCBs+VCB.DEV,y
|
||
sta bmadev and read in fresh bitmap for this dev.
|
||
|
||
L3D4A ldy bmastat is it already modified ?
|
||
bmi L3D54 yes, return pointer
|
||
|
||
jsr gtbmap otherwise read in fresh bitmap.
|
||
bcs L3D5F if error.
|
||
|
||
L3D54 ldy vcbptr get relative block # of bitmap.
|
||
lda 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
|
||
*--------------------------------------
|
||
upbmap clc
|
||
lda bmastat is current map modified ?
|
||
bpl .9 no.
|
||
|
||
jsr wrtbmap update device.
|
||
bcs .9 if error on writing.
|
||
|
||
stz bmastat mark bitmap buffer as free
|
||
lda #0 MUST EXIT WITH A=0
|
||
.9 rts
|
||
*--------------------------------------
|
||
gtbmap sta bmadev read bitmap specified by dev and vcb.
|
||
|
||
ldy vcbptr get lowest map # with free blocks in it
|
||
lda VCBs+VCB.BMAPIDX,y
|
||
sta bmacmap associate offset with bitmap ctrl block.
|
||
clc add this # to the base address of
|
||
adc VCBs+VCB.BMAP,y 1st bitmap and save in bmadadr which
|
||
sta bmadadr is address of bitmap to be used.
|
||
|
||
lda VCBs+VCB.BMAP+1,y
|
||
adc #$00
|
||
sta bmadadr+1
|
||
|
||
lda #$01 read device command
|
||
.HS 2C BIT ABS
|
||
wrtbmap lda #$02 write command.
|
||
|
||
sta A4L
|
||
|
||
lda DEVNUM save current dev #
|
||
pha
|
||
lda bmadev get bitmap's dev #
|
||
sta DEVNUM
|
||
lda bmadadr and disk address
|
||
sta bloknml
|
||
lda bmadadr+1
|
||
sta bloknml+1
|
||
|
||
lda /bmbuf
|
||
* lda bmbufhi+2 address of the buffer (low = 0)
|
||
jsr XDOS.RWBlock
|
||
|
||
plx keep A=error code if CS
|
||
stx DEVNUM
|
||
|
||
L3DB6 rts
|
||
*--------------------------------------
|
||
.DO LOWERCASE=1
|
||
XDOS.WriteGBufDir
|
||
jsr XDOS.PackGBuf
|
||
bra XDOS.WriteGBuf
|
||
.FIN
|
||
*--------------------------------------
|
||
XDOS.ReadGBuf_d_frst
|
||
lda d_frst read 1st block of directory into gbuf
|
||
ldx d_frst+1
|
||
.DO LOWERCASE=1
|
||
XDOS.ReadGBufAXDir
|
||
jsr XDOS.ReadGBufAX
|
||
bcc XDOS.UnpackGBuf
|
||
rts
|
||
.FIN
|
||
XDOS.ReadGBufAX sta bloknml
|
||
stx bloknml+1
|
||
|
||
XDOS.ReadGBuf lda #$01 read command.
|
||
.HS 2C BIT ABS
|
||
|
||
XDOS.WriteGBuf lda #$02 write command
|
||
|
||
sta A4L pass to device handler.
|
||
lda /gbuf general buffer.
|
||
|
||
XDOS.RWBlock sta buf+1 buffer high.
|
||
stz buf buffer low (always on page boundary)
|
||
|
||
stz p8error clear global error code.
|
||
|
||
lda #$FF indicates reg call made to dev handler
|
||
sta ioaccess
|
||
|
||
lda DEVNUM transfer dev # for dispatcher to
|
||
sta unitnum convert to unit #.
|
||
jmp XDOS.DevCall call the driver.
|
||
*--------------------------------------
|
||
.DO LOWERCASE=1
|
||
|
||
XDOS.CheckAndUnpackGBuf
|
||
lda gbuf+$23
|
||
sta h_entln
|
||
ldy gbuf+$24
|
||
sty h_maxent
|
||
cmp #$27
|
||
bne .9
|
||
|
||
cpy #$0D
|
||
beq XDOS.UnpackGBuf
|
||
|
||
.9 lda #MLI.E.NOTPRODOS
|
||
sec
|
||
rts
|
||
|
||
XDOS.UnpackGBuf jsr XDOS.Pack.Init
|
||
|
||
XDOS.UnpackZPT .EQ *
|
||
|
||
.1 lda (zpt)
|
||
and #$0F
|
||
beq .6
|
||
|
||
ldy #$1D MIN_VERSION
|
||
lda (zpt),y
|
||
bpl .6 no lowercase information
|
||
|
||
lda (zpt)
|
||
and #$0F
|
||
tay
|
||
|
||
.2 cpy #8 CS if MIN_VERSION to use
|
||
phy
|
||
|
||
bcs .3
|
||
|
||
ldy #$1D MIN_VERSION
|
||
lda (zpt),y
|
||
|
||
ply
|
||
and whichbit,y
|
||
beq .5
|
||
|
||
bra .4
|
||
|
||
.3 ldy #$1C VERSION
|
||
lda (zpt),y
|
||
|
||
ply
|
||
and whichbit-8,y
|
||
beq .5
|
||
|
||
.4 lda (zpt),y
|
||
eor #$20 to lowercase
|
||
sta (zpt),y
|
||
|
||
.5 dey
|
||
bne .2
|
||
|
||
.6 jsr XDOS.Pack.Next
|
||
dex
|
||
bne .1
|
||
|
||
clc make sure CC
|
||
rts
|
||
*--------------------------------------
|
||
*XDOS.PackGBuf.Bitmap .BS 2
|
||
XDOS.PackGBuf.Bitmap .EQ sos
|
||
*--------------------------------------
|
||
XDOS.PackGBuf jsr XDOS.Pack.Init
|
||
|
||
.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.Pack.Next
|
||
dex
|
||
bne .1
|
||
|
||
rts
|
||
*--------------------------------------
|
||
XDOS.Pack.Init lda #4
|
||
sta zpt
|
||
lda /gbuf
|
||
sta zpt+1
|
||
|
||
ldx h_maxent
|
||
* beq * DEBUG : should never happends
|
||
rts
|
||
*--------------------------------------
|
||
XDOS.Pack.Next lda h_entln
|
||
clc
|
||
adc zpt
|
||
sta zpt
|
||
bcc .8
|
||
|
||
inc zpt+1
|
||
|
||
.8 rts
|
||
.FIN
|
||
*--------------------------------------
|
||
XDOS.GetMark ldx fcbptr index to open fcb.
|
||
|
||
ldy #$02 index to user's mark parameter.
|
||
|
||
.1 lda FCBs+FCB.MARK,x transfer current position
|
||
sta (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 fcbptr file's control block index.
|
||
inx inc by 2 for index to hi eof
|
||
inx
|
||
sec indicate comparisons are necessary.
|
||
|
||
.1 lda (A3L),y move it to 'tpos'
|
||
sta tposll-2,y
|
||
bcc .2 branch if mark < eof
|
||
|
||
cmp 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 fcbptr test to see if new position is
|
||
lda 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 FCBs+FCB.MARK+2,y
|
||
bne L3E44 branch if not.
|
||
|
||
jmp svmark if so, adj fcb, position ptr and return.
|
||
|
||
L3E44 lda 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 FCBs,y
|
||
lda #MLI.E.BADREF and report error
|
||
sec
|
||
rts
|
||
|
||
L3E59 lda FCBs+FCB.STYPE,y use storage type as # of index levels
|
||
sta levels since 1=seed, 2=sapling, 3=tree.
|
||
lda FCBs+FCB.F,y
|
||
and #FCB.F.DBLKMOD if previous data was modified then
|
||
beq L3E6B disk must be updated.
|
||
|
||
jsr wfcbdat
|
||
|
||
bcs L3ED4 if error.
|
||
|
||
L3E6B ldy fcbptr test to see if current index block
|
||
lda 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 FCBs+FCB.1stBLK,y unallocated. 1st block is only block
|
||
sta bloknml and it's data.
|
||
lda FCBs+FCB.1stBLK+1,y high block address.
|
||
jmp rnewpos go read in block and set statuses.
|
||
|
||
L3E9D lda 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 wfcbidx 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.
|
||
|
||
ldy fcbptr save newly loaded index block's address.
|
||
lda bloknml
|
||
sta FCBs+FCB.IBLK,y
|
||
lda bloknml+1
|
||
sta FCBs+FCB.IBLK+1,y
|
||
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 bloknml read in next lower index block.
|
||
lda (zpt),y (high address)
|
||
sta bloknml+1
|
||
dec zpt+1
|
||
|
||
* jsr rfcbidx read in sapling level
|
||
|
||
lda #$01 prepare to read index block : read command
|
||
sta A4L
|
||
|
||
ldx #zpt address of current index buffer.
|
||
|
||
jsr fileio1 go read index block.
|
||
bcs L3ED4 error
|
||
|
||
ldy fcbptr
|
||
lda bloknml
|
||
sta FCBs+FCB.IBLK,y save block address of this index in fcb
|
||
lda bloknml+1
|
||
sta FCBs+FCB.IBLK+1,y
|
||
|
||
datlevel lda tposhi get block address of data block
|
||
lsr
|
||
lda tposlh ( if there is one )
|
||
ror
|
||
tay
|
||
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 zipdata index block is invalid and needs to be zeroed.
|
||
bcc svmark branch if it doesn't need zeroed
|
||
|
||
jsr zeroindex zero index block in user's i/o buffer
|
||
bra svmark
|
||
*--------------------------------------
|
||
zipdata lda #$00
|
||
tay
|
||
L3F42 sta (datptr),y zero out data area
|
||
iny
|
||
bne L3F42
|
||
|
||
inc datptr+1
|
||
|
||
L3F49 sta (datptr),y
|
||
iny
|
||
bne L3F49
|
||
|
||
dec datptr+1
|
||
rts
|
||
*--------------------------------------
|
||
L3F51 sta bloknml get data block of new position
|
||
lda (zpt),y (high address)
|
||
dec zpt+1
|
||
|
||
rnewpos sta bloknml+1
|
||
jsr XDOS.ReadFCB.DBLK
|
||
bcs L3F86 if error.
|
||
|
||
jsr XDOS.ClrFCBStatus show whole chain is allocated.
|
||
*--------------------------------------
|
||
svmark ldy fcbptr update position in fcb
|
||
iny
|
||
iny
|
||
ldx #$02
|
||
|
||
L3F68 lda FCBs+FCB.MARK,y save old mark in case calling routine
|
||
sta oldmark,x fails later.
|
||
lda tposll,x
|
||
sta FCBs+FCB.MARK,y
|
||
dey
|
||
dex move 3 byte position marker
|
||
bpl L3F68
|
||
|
||
clc set up indirect address to buffer
|
||
lda datptr page pointed to by the current
|
||
sta sos position marker.
|
||
lda tposlh
|
||
and #$01
|
||
adc datptr+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.P8errv 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 FCBs+FCB.MARK+1,y test for positive direction
|
||
cmp tposlh indicated by carry.
|
||
|
||
lda 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 (datptr),y get link address of previous or next
|
||
sta bloknml directory block.
|
||
cmp #$01 test for null byte into carry
|
||
iny but first be sure there is a link.
|
||
lda (datptr),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!
|
||
L3FD6 sec error.
|
||
rts
|
||
|
||
L3FD8 sta bloknml+1
|
||
*--------------------------------------
|
||
XDOS.ReadFCB.DBLK
|
||
lda #$01 read command
|
||
sta A4L
|
||
|
||
ldx #datptr points at address of data buffer.
|
||
|
||
jsr fileio1 go do file input.
|
||
bcs L3FF2 error.
|
||
|
||
ldy fcbptr
|
||
lda bloknml
|
||
sta FCBs+FCB.DBLK,y save block # just read in fcb.
|
||
lda bloknml+1
|
||
sta FCBs+FCB.DBLK+1,y
|
||
|
||
* clc
|
||
|
||
L3FF2 rts
|
||
*--------------------------------------
|
||
*rfcbidx lda #$01 prepare to read index block : read command
|
||
* sta A4L
|
||
|
||
* ldx #zpt address of current index buffer.
|
||
|
||
* jsr fileio1 go read index block.
|
||
* bcs L400C error
|
||
|
||
* ldy fcbptr
|
||
* lda bloknml
|
||
* sta FCBs+FCB.IBLK,y save block address of this index in fcb
|
||
* lda bloknml+1
|
||
* sta FCBs+FCB.IBLK+1,y
|
||
|
||
** clc
|
||
|
||
*L400C rts
|
||
*--------------------------------------
|
||
wfcbfst jsr upbmap update the bitmap and write file's 1st block.
|
||
|
||
lda #$02 write command
|
||
.HS 2C skip next instruction
|
||
|
||
rfcbfst lda #$01 read command.
|
||
|
||
pha save the command
|
||
lda #FCB.1stBLK
|
||
ora fcbptr add offset to fcbptr
|
||
tay
|
||
pla
|
||
|
||
ldx #zpt rd block into index portion of file buf
|
||
*--------------------------------------
|
||
dofileio sta A4L command
|
||
|
||
lda FCBs,y get disk block address from fcb.
|
||
sta bloknml block 0 not legal
|
||
bne .1
|
||
|
||
lda FCBs+1,y high address of disk block
|
||
bne .2
|
||
|
||
lda #$0C Block = $0000, allocation error.
|
||
jsr GP.SysDeath doesn't return...
|
||
|
||
.1 lda FCBs+1,y
|
||
.2 sta bloknml+1
|
||
*--------------------------------------
|
||
fileio1 lda $00,x get memory address of buffer from
|
||
sta buf page zero pointed to by x register
|
||
lda $01,x
|
||
sta buf+1 and pass address to device handler
|
||
|
||
jsr XDOS.FCBDevIDSelect
|
||
|
||
lda #$FF also, set to indicate reg call made to
|
||
sta ioaccess device handler.
|
||
lda DEVNUM transfer device # for dispatcher
|
||
sta unitnum to convert to unit #.
|
||
stz p8error clear global error code.
|
||
jmp XDOS.DevCall call the driver.
|
||
*--------------------------------------
|
||
wfcbdat ldx #datptr point at memory address with x and
|
||
lda #FCB.DBLK disk address with y.
|
||
ora fcbptr add offset to fcbptr
|
||
tay and put in y.
|
||
lda #$02 write data block.
|
||
jsr dofileio
|
||
bcs L4096 if errors.
|
||
|
||
lda #$BF mark data status as current.
|
||
bra XDOS.ResetFCBStatus
|
||
|
||
wfcbidx jsr upbmap update bitmap.
|
||
|
||
ldx #zpt point to address of index buffer
|
||
lda #FCB.IBLK and block address of that index block.
|
||
ora fcbptr
|
||
tay
|
||
lda #$02
|
||
jsr dofileio go write out index block.
|
||
bcs L4096 if errors.
|
||
|
||
lda #$7F mark index status as current.
|
||
*--------------------------------------
|
||
XDOS.ResetFCBStatus
|
||
ldx fcbptr
|
||
and FCBs+FCB.F,x
|
||
sta FCBs+FCB.F,x
|
||
|
||
L4096 rts
|
||
*--------------------------------------
|
||
XDOS.Open jsr XDOS.FindFileOrVol look up the file.
|
||
bcs L4096 if not, then error.
|
||
|
||
L40A0 jsr tstopen 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 fcbptr get address of 1st free fcb found.
|
||
|
||
L40B9 ldy #FCB
|
||
|
||
L40BD stz FCBs,x but clean it first.
|
||
inx
|
||
dey
|
||
bne L40BD
|
||
|
||
ldy #0
|
||
|
||
ldx fcbptr
|
||
|
||
L40CB lda d_dev,y move ownership info.
|
||
sta 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 d_stor get storage type and
|
||
jsr XDOS.SetFCBSType
|
||
tax save in x for later comparison
|
||
|
||
lda d_attr 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 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 bloknml+1 of file and current usage count.
|
||
lda fcbptr
|
||
ora ofcbtbl,x this is done via a translation table
|
||
tay between directory info and fcb.
|
||
lda d_frst,x
|
||
sta FCBs,y
|
||
dex
|
||
bpl L4101 last loop stores hi address of 1st block
|
||
|
||
sta bloknml and this is the low one.
|
||
ldx fcbptr
|
||
lda cntent this was set up by 'tstopen'.
|
||
sta FCBs,x claim fcb for this file.
|
||
jsr alcbuffr go allocate buffer in memory tables.
|
||
bcs L4147 if errors.
|
||
|
||
ldx fcbptr
|
||
jsr XDOS.GetFCBBufX rtn addr of bufs in data & index ptrs.
|
||
lda flevel mark level at which
|
||
sta FCBs+FCB.FLEVEL,x file was opened.
|
||
|
||
lda 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 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 fcbptr free buffer space.
|
||
stz FCBs,x necessary to release fcb also.
|
||
lda 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 vcbptr index to vcb.
|
||
inc VCBs+VCB.OFCNT,x add 1 to # of files currently open
|
||
|
||
ldx fcbptr index to fcb.
|
||
lda FCBs+FCB.ID,x return ref # to user.
|
||
ldy #$05
|
||
sta (A3L),y
|
||
* clc open is successful
|
||
rts
|
||
*--------------------------------------
|
||
tstopen 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 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 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 FCBs,y all bytes must match to say that it's
|
||
cmp d_dev-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 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
|
||
*--------------------------------------
|
||
MAN
|
||
SAVE usr/src/prodos.fx/prodos.s.xdos.c
|
||
LOAD usr/src/prodos.fx/prodos.s
|
||
ASM
|