A2osX/ProDOS.FX/ProDOS.S.XDOS.B.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

999 lines
25 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.ZPT.SetEIB jsr XDOS.ZPT.InitGBuf
ldx XDOS.DE.DirEIB on the entry #.
.1 dex addr = XDOS.GBuf + ((d_entnum-1) * XDOS.DH.EL)
beq .8
jsr XDOS.ZPT.Next
bra .1
.8 clc
crerr3 rts carry set if error.
*--------------------------------------
XDOS.DE.Update lda GP.DATE
beq XDOS.DE.UpdateNoMTime if no clock, then don't mod date/time.
ldx #3
.1 lda GP.DATE,x move last modification date/time
sta XDOS.DE.MTime,x to entry being updated.
dex
bpl .1
sec propagate MTIME
.HS 90 BCC
*--------------------------------------
XDOS.DE.UpdateNoMTime
clc DO NOT propagate MTIME
ror scrtch save this...
lda bkbitflg (bit 5 = backup needed)
tsb XDOS.DE.Access mark entry as backupable
lda XDOS.DE.DevID get device # of directory
sta GP.DEVNUM to be revised
lda XDOS.DE.DirEBlk and address of directory block.
ldx XDOS.DE.DirEBlk+1
.DO LOWERCASE=1
jsr XDOS.ReadGBufAXDir
.ELSE
jsr XDOS.ReadGBufAX read block into general purpose buffer
.FIN
bcs crerr3
jsr XDOS.ZPT.SetEIB fix up ptr to entry location within XDOS.GBuf.
ldy XDOS.DH.EL now move DE info to directory.
dey
.1 lda XDOS.DE.Filename,y
sta (zpt),y
dey
bpl .1
lda XDOS.DE.DirHBlk is the entry block same as
cmp ZP.BLKNUM the entry's header block?
bne .2 if no, go save entry block
lda XDOS.DE.DirHBlk+1 then maybe, so test high addresses.
cmp ZP.BLKNUM+1
beq .3 branch if they are the same block.
.2 .DO LOWERCASE=1
jsr XDOS.WriteGBufDir
.ELSE
jsr XDOS.WriteGBuf go write updated directory block.
.FIN
bcs crerr3
lda XDOS.DE.DirHBlk get address of header block and
ldx XDOS.DE.DirHBlk+1
.DO LOWERCASE=1
jsr XDOS.ReadGBufAXDir
.ELSE
jsr XDOS.ReadGBufAX go read in header block to modify.
.FIN
bcs crerr3
.3 ldy #$01 update current # of files in this dir.
.4 lda XDOS.DH.FileCnt,y
sta XDOS.GBuf+37,y (current entry count)
dey
bpl .4
lda XDOS.DH.Access also update header's attributes.
sta XDOS.GBuf+34
.DO LOWERCASE=1
jsr XDOS.WriteGBufDir
.ELSE
jsr XDOS.WriteGBuf go write updated header
.FIN
bcs .9
*--------------------------------------
.5 bit scrtch nothing to do ...
bpl .8 ... if no MTIME update
lda XDOS.GBuf+4 test for 'root' directory because
and #$F0 if it is, then directory revision
eor #$F0 is complete (leaves carry clear).
beq .8 branch if done.
lda XDOS.GBuf+41 get entry #
sta XDOS.DE.DirEIB
lda XDOS.GBuf+42 and the length of entries in that dir
sta XDOS.DH.EL
lda XDOS.GBuf+39 get addr of parent entry's dir block
ldx XDOS.GBuf+40
.DO LOWERCASE=1
jsr XDOS.ReadGBufAX no need to pak/unpak....will disturb zpt
.ELSE
jsr XDOS.ReadGBufAX read it
.FIN
bcs .9
jsr XDOS.ZPT.SetEIB get indirect ptr to parent entry in XDOS.GBuf
ldx #$03 update the modification date & time
ldy #$24 for this entry too
.6 lda GP.DATE,x
sta (zpt),y
dey
dex
bpl .6
.DO LOWERCASE=1
jsr XDOS.WriteGBuf
.ELSE
jsr XDOS.WriteGBuf write updated entry back to disk.
.FIN
bcs .9 if error.
ldy #$26 compare current block # to this
lda (zpt),y entry's header block.
tax
dey
lda (zpt),y block as header.
cmp ZP.BLKNUM are low addresses the same?
bne .7 branch if entry doesn't reside in same
cpx ZP.BLKNUM+1 are high address the same?
beq .5 they are the same, continue to root dir.
.7 .DO LOWERCASE=1
jsr XDOS.ReadGBufAX
.ELSE
jsr XDOS.ReadGBufAX
.FIN
bcc .5 continue if read was good
rts
.8 clc no error
.9 rts
*--------------------------------------
XDOS.FindDirOrVol
jsr XDOS.FindFileOrVol
bcs .99
lda XDOS.DE.Filename
and #$F0
cmp #$D0
beq XDOS.ZPT.GetDE.CLCRTS
.9 lda #MLI.E.UNSUPST
sec
.99 rts
*--------------------------------------
XDOS.FindFileOrVol
jsr XDOS.CheckPath
bcc XDOS.ZPT.GetDE
cmp #MLI.E.INVPATH
bne fnderr
clc
rts
*--------------------------------------
XDOS.ZPT.GetDE ldy XDOS.DH.EL Get FileInfo From Directory Block Buffer
.1 dey
lda (zpt),y move entry into storage
sta XDOS.DE.Filename,y
tya
bne .1
XDOS.ZPT.GetDE.CLCRTS
clc
rts
*--------------------------------------
XDOS.FindFile jsr XDOS.CheckPath see if file exists
bcc XDOS.ZPT.GetDE
rts
*--------------------------------------
XDOS.CheckPath jsr XDOS.FindVol
bcs fnderr.RTS
bne XDOS.CheckPath1 branch if more than root
jsr XDOS.ZPT.InitGBuf zpt = GBUF+4
ldy #$1F move in id and date info
.1 lda (zpt),y
sta XDOS.DE.Filename,y
dey
cpy #$17
bne .1
.2 lda rootstuf-$10,y
sta XDOS.DE.Filename,y
dey
cpy #$0F
bne .2
lda #$D0 fake directory file
sta XDOS.DE.Filename
lda XDOS.GBuf+2 check forward link.
ora XDOS.GBuf+3 if non-zero, assume full sized directory
bne .3 else assume it's the slot 3 /RAM volume
lda #$02 so reset eof and blocks_used fields
sta XDOS.DE.EOF+1
lda #$01
sta XDOS.DE.BlkUsed
.3 lda #MLI.E.INVPATH bad path (carry set)
rts
*--------------------------------------
errdir lda #MLI.E.BADDIR directory error
fnderr sec
fnderr.RTS rts
*--------------------------------------
XDOS.CheckPath1 stz nofree reset free entry indicator.
sec dir to be searched has header in this block.
L37C9 stz totent reset entry counter.
jsr XDOS.LookupNameInDirBlk look for name pointed to by pnptr.
bcc namfound if name was found.
lda XDOS.FileCnt have we looked at all of the
sbc totent entries in this directory?
bcc L37E2 maybe, check hi count.
bne L37EB no, read next directory block.
lda XDOS.FileCnt+1 has the last entry been looked at?
beq errfnf yes, give 'file not found' error
L37E2 dec XDOS.FileCnt+1 should be at least one
L37EB sta XDOS.FileCnt keep a running count.
lda /XDOS.GBuf reset indirect pointer
sta zpt+1
lda XDOS.GBuf+2 get link to next dir block
bne L37FC (if there is one).
cmp XDOS.GBuf+3 are both zero, i.e. no link? if so,
beq errdir then not all entries were acct'd for.
L37FC ldx XDOS.GBuf+3 acc has value for block# (low).
.DO LOWERCASE=1
jsr XDOS.ReadGBufAXDir
.ELSE
jsr XDOS.ReadGBufAX go read the next linked directory.
.FIN
bcc L37C9 if no error.
rts return error in acc.
*--------------------------------------
errfnf lda nofree was any free entry found?
bne .2
lda XDOS.GBuf+2 test link
bne .1
cmp XDOS.GBuf+3 if both are 0 then give up.
beq .2 report 'not found'.
.1 sta XDOS.DE.DirEBlk
lda XDOS.GBuf+3
sta XDOS.DE.DirEBlk+1 assume 1st entry of next block
lda #$01 is free for use.
sta XDOS.DE.DirEIB mark as valid (for create)
sta nofree
.2 jsr nxtpnam1 'file not found' or 'path not found'?
errpath1 beq .1 if non-zero then 'path not found'
lda #MLI.E.PNOTFND path not found
.HS 2C BIT ABS
.1 lda #MLI.E.FNOTFND file not found
sec
lookfil0.RTS rts
*--------------------------------------
namfound jsr nxtpname adj index to next name in path.
beq filfound branch if that was the last name.
* ldy #$00 be sure this is a directory entry.
lda (zpt) high nibble will tell.
and #$F0
cmp #$D0 is it a subdirectory?
bne errpath1 error if not.
ldy #$12 get address of 1st subdirectory block
lda (zpt),y
sta XDOS.DE.DirHBlk+1 save as file's header block too
tax
dey
lda (zpt),y
sta XDOS.DE.DirHBlk
.DO LOWERCASE=1
jsr XDOS.ReadGBufAXDir
.ELSE
jsr XDOS.ReadGBufAX read subdirectory into XDOS.GBuf.
.FIN
bcs lookfil0.RTS if error.
lda XDOS.GBuf+37 get the # of files contained in this
sta XDOS.FileCnt directory.
lda XDOS.GBuf+38
sta XDOS.FileCnt+1
*--------------------------------------
* Check if $75 at VOL/DIR entry + $14
* (8 bytes reserved)
*--------------------------------------
.DO LOWERCASE=0
lda XDOS.GBuf+20 make sure password is disabled
ldx #$00
sec
rol
L3869 bcc L386C
inx
L386C asl
bne L3869
cpx #$05 is password disabled?
beq movhead
lda #MLI.E.INCFF directory is not compatible
sec
rts
.FIN
movhead jsr XDOS.GetDH move directory info.
jmp XDOS.CheckPath1 do next local pathname.
*--------------------------------------
XDOS.GetDH ldx #10 move this directory info
.1 lda XDOS.GBuf+28,x
sta XDOS.DH.CTime,x
dex
bpl .1
.DO ACL=1
ldx #7
lda XDOS.GBuf+20
cmp #$57
bne .20
lda XDOS.GBuf+21
bne .20
.2 lda XDOS.GBuf+20,x
sta XDOS.DH.ACL,x
dex
bpl .2
bra .21
.20 stz XDOS.DH.ACL,x
dex
bpl .20
.21 .FIN
lda XDOS.GBuf+4 if this is root, then nothing to do
and #$F0
eor #$F0 test header type.
beq .8 branch if root
ldx #$03 otherwise, save owner info about
.3 lda XDOS.GBuf+39,x this header.
sta XDOS.OH.Blk,x
dex
bpl .3
.8 rts
*--------------------------------------
filfound lda XDOS.DH.EPB figure out which entry # this is
sec
sbc cntent max entries - count entries + 1
adc #$00 = entry # (carry was set)
sta XDOS.DE.DirEIB
lda ZP.BLKNUM and indicate block # of this directory
sta XDOS.DE.DirEBlk
lda ZP.BLKNUM+1
sta XDOS.DE.DirEBlk+1
* clc done by ADC #$00
rts
*--------------------------------------
XDOS.LookupNameInDirBlk
lda XDOS.DH.EPB reset count of files per block
sta cntent
jsr XDOS.ZPT.InitGBuf reset indirect pointer to XDOS.GBuf
bcs .4 branch if this block contains a header
.1 ldy #$00
lda (zpt),y get length of name in directory.
bne .2 branch if there is a name.
lda nofree test if a free entry has been declared.
bne .4 yes, inc to next entry.
jsr filfound set address for current entry.
inc nofree indicate a free spot has been found.
bra .4
.2 and #$0F strip byte (is checked by 'filfound')
inc totent inc count of valid files found.
sta namcnt save name length as counter.
ldx namptr get index to current path.
cmp XDOS.PathBuf,x are both names the same length?
bne .4 no, inc to next entry.
.3 inx (first) next letter index
iny
lda (zpt),y compare names letter by letter
cmp XDOS.PathBuf,x
bne .4
dec namcnt all letters compared?
bne .3 no, continue.
clc a match is found.
.9 rts
.4 dec cntent checked all entries in this block?
sec
beq .9 yes, no name match.
jsr XDOS.ZPT.Next
bra .1
*--------------------------------------
XDOS.FindVol jsr XDOS.FindVolInVCBOrDev
bcs novolume
.DO ACL=1
ldx #$4A
.ELSE
ldx #$42 zero out directory temps
.FIN
.1 stz XDOS.OH.Blk,x and owner info
dex
bpl .1
lda GP.DEVNUM setup device # for this directory
sta XDOS.DE.DevID
jsr XDOS.GetDH setup other header info from directory
ldy #$01 in XDOS.GBuf and clean up misc info.
ldx XDOS.VCBPtr
inx
.2 lda XDOS.VCBs+VCB.TBLK,x misc info includes
sta XDOS.DH.BlkCnt,y total # of blocks,
lda XDOS.VCBs+VCB.BMAP,x the address of the 1st bitmap,
sta XDOS.DH.BMPtr,y
lda ZP.BLKNUM,y directory's disk address,
sta XDOS.DE.DirHBlk,y
lda XDOS.DH.FileCnt,y and setting up a counter for the # of
sta XDOS.FileCnt,y files in this directory.
dex
dey
bpl .2
*--------------------------------------
nxtpname jsr nxtpnam1 get new namptr in y and namlen in acc.
sty namptr save new pathname pointer.
rts (status reg according to accumulator)
*--------------------------------------
nxtpnam1 ldy namptr inc pathname pointer to next name
lda XDOS.PathBuf,y in the path.
sec
adc namptr if this addition results in zero,
tay then prefixed directory has been moved
* bne .1 to another device. branch if not.
* lda GP.DEVNUM revise GP.DEVNUM for prefixed directory
* sta p_dev
.1 lda XDOS.PathBuf,y test for end of name.
clc no errors
novolume rts
*-------------------------------------- OK for .
XDOS.FindVolInVCBOrDev
lda #$00
ldy GP.PFXPTR use prefix volume name to look up vcb.
bit prfxflg is this a prefixed path?
bpl L396F branch if it is
tay set ptr to volume name
L396F sty L39D4+1 and save.
sta GP.DEVNUM zero out dev# until vcb located.
lda #XDOS.VCB0
L3975 pha acc now used as vcb lookup index.
tax index pointer to x.
lda XDOS.VCBs,x get vcb volume name length.
bne L3987 branch if claimed vcb to be tested.
L397C ldy L39D4+1 restore pointer to requested vol name.
pla now adj vcb index to next vcb entry.
clc
adc #VCB
bcc L3975 branch if more vcb's to check
bcs L39D4 otherwise go look for unlogged volumes.
L3987 sta namcnt save length of vol name to be compared.
L398A cmp XDOS.PathBuf,y is it the same as requested vol name?
bne L397C branch if not
inx
iny next character
lda XDOS.VCBs,x
dec namcnt last character?
bpl L398A if not.
plx restore pointer to matching vcb.
stx XDOS.VCBPtr save it for future reference.
lda XDOS.VCBs+VCB.DEV,x get it's device #
sta GP.DEVNUM and save it.
lda #$02 assume prefix is not used and
ldx #$00 that root directory is to be used.
pha
lda L39D4+1 = 0 if no prefix.
L39AC tay if prefix then find ptr to prefixed
sta namptr dir name. save path ptr.
beq L39C2 branch if no prefix.
sec
adc XDOS.PathBuf,y inc to next dir in prefix path.
bcc L39AC branch if another dir in prefix.
pla
lda p_blok volume verification will occur at
pha
ldx p_blok+1 subdirectory level.
* verify volume name
L39C2 pla
jsr XDOS.ReadGBufAX read in directory (or prefix dir)
bcs L39CC if error then look on other devices.
.DO LOWERCASE=1
jsr XDOS.CheckAndUnpackGBuf
bcs L39CC
.FIN
jsr XDOS.CheckVolName compare dir name with path name.
bcc L39F0 if they match, stop looking.
L39CC ldx XDOS.VCBPtr check if current (matched) vcb is active
lda XDOS.VCBs+VCB.OFCNT,x i.e. does it have open files?
bne L39ED report not found if active.
L39D4 lda #$FF SELF MODIFIED vnptr : make path ptr same as volume ptr
sta namptr
jsr mvdevnums copy all device #'s to be examined.
lda GP.DEVNUM log current device 1st before searching
bne L39F1 others.
L39E2 ldx GP.DEVCNT scan look list for devices we need
L39E5 lda loklst,x to search for the requested volume.
bne L39F4 branch if we've a device to look at.
dex
bpl L39E5 look at next one.
L39ED lda #MLI.E.VNOTFND no mounted volume
sec error
L39F0 rts
L39F1 ldx GP.DEVCNT now remove the device from the list
L39F4 cmp loklst,x of prospective devices.
beq L39FE branch if match.
dex look until found.
bpl L39F4 always taken (usually) unless
bmi L39ED if dev was removed from GP.DEVLST (/RAM).
L39FE sta GP.DEVNUM preserve device to be checked next.
stz loklst,x mark this one as tested.
jsr XDOS.FindVCBForDevNum find vcb that claims this dev (if any).
bcs L3A29 branch if vcb full.
lda XDOS.VCBs,x did we find it or return free vcb?
beq L3A16 if free vcb.
lda XDOS.VCBs+VCB.OFCNT,x is this volume active?
bne L39E2 if so, no need to re-log.
L3A16 lda #$02 go read root dir into XDOS.GBuf
ldx #$00
.DO LOWERCASE=1
jsr XDOS.ReadGBufAXDir
.ELSE
jsr XDOS.ReadGBufAX
.FIN
bcs L39E2 ignore if unable to read.
jsr XDOS.VCBMount
bcs L39E2 look at next if non-xdos disk mounted.
jsr XDOS.CheckVolName is this the volume ?
bcs L39E2 if not
L3A29 rts
*--------------------------------------
mvdevnums ldx GP.DEVCNT copy all dev #'s to be checked.
.1 lda GP.DEVLST,x active device list.
and #$F0 strip device type info.
sta loklst,x copy them to a temp workspace
dex
bpl .1
ldx GP.DEVCNT
rts
*--------------------------------------
XDOS.FindVCBForDevNum
lda #XDOS.VCB0 look for vcb for GP.DEVNUM
ldy #$FF
.1 tax new index to next vcb
lda XDOS.VCBs+VCB.DEV,x check all devnums
cmp GP.DEVNUM is this the vcb?
beq .7
lda XDOS.VCBs,x is this a free vcb?
bne .3 if not
iny
bne .3 already found a free one
stx XDOS.VCBPtr save first free VCB
.3 txa
clc inc index to next vcb
adc #VCB
bcc .1
ldx XDOS.VCBPtr get found free if any
tya any free vcb's available?
bpl .8 yes, exit with X = XDOS.VCBPtr
lda #XDOS.VCB0 look for an entry to kick out
.4 tax
lda XDOS.VCBs+VCB.OFCNT,x any open files?
beq .5 no, kick this one out.
txa next vcb
clc
adc #VCB
bcc .4
lda #MLI.E.VCBFULL all vcb entries have open files
* sec
rts
.5 stz XDOS.VCBs,x free this entry
stz XDOS.VCBs+VCB.DEV,x
.7 stx XDOS.VCBPtr save entry index.
.8 clc no error.
rts
*--------------------------------------
XDOS.CheckVolName
ldx #$00 index to directory name.
ldy namptr index to pathname.
lda XDOS.GBuf+4 get dir name length and type.
cmp #$E0 is it a directory?
bcc .1 if not.
and #$0F isolate name length and
sta namcnt save as a counter.
bne .3 branch if valid length.
.1 sec indicate not found
rts
.2 lda XDOS.GBuf+4,x next char
.3 cmp XDOS.PathBuf,y
bne .1 if not the same.
inx check next char
iny
dec namcnt
bpl .2 if more to compare.
clc match found
XDOS.CheckVolName.RTS
rts
*--------------------------------------
XDOS.VCBMount ldx XDOS.VCBPtr previously logged in volume?
lda XDOS.VCBs,x (acc = 0?)
beq XDOS.VCBMountAtX no, go prepare vcb.
jsr XDOS.VCBCmpGBUF does vcb match vol read?
bcc XDOS.CheckVolName.RTS yes, do not disturb.
XDOS.VCBMountAtX
ldy #VCB zero out vcb entry
.1 stz XDOS.VCBs,x
inx
dey
bne .1
lda XDOS.GBuf pointer to previous dir block
ora XDOS.GBuf+1 must be null
bne .9
lda XDOS.GBuf+4 test for header
and #$E0
cmp #$E0
bne .9
jsr XDOS.ChkDupVol does a duplicate with open files
bcs .8 already exist? branch if yes.
lda XDOS.GBuf+4 move volume name to vcb.
and #$0F strip root marker
tay
pha
* clc
adc XDOS.VCBPtr
tax
.2 lda XDOS.GBuf+4,y
sta XDOS.VCBs,x
dex
dey
bne .2
pla get length again
sta XDOS.VCBs,x and save.
lda GP.DEVNUM last device used.
sta XDOS.VCBs+VCB.DEV,x save device # and
ldy #0
.3 lda XDOS.GBuf+39,y
sta XDOS.VCBs+VCB.BMAP,x copy BMAP+TBLK
iny
inx
cpy #4
bne .3
.8 clc indicate logged if possible
rts
.9 lda #MLI.E.NOTPRODOS not tree or dir, unrecognized type
sec
rts
*--------------------------------------
XDOS.VCBCmpGBUF lda XDOS.GBuf+4 with name in directory.
and #$0F
cmp XDOS.VCBs,x are they the same length?
stx .1+1 xvcbptr : see rev note #23
bne .9 if not the same.
tay
clc
.1 adc #$FF xvcbptr : SELF MODIFIED
tax
.2 lda XDOS.GBuf+4,y
cmp XDOS.VCBs,x
bne .9 if not the same.
dex
dey
bne .2
clc indicate match.
.HS B0 BCS
.9 sec
ldx .1+1 xvcbptr : offset to start of vcb (rev note #23)
rts
*--------------------------------------
XDOS.ChkDupVol lda #XDOS.VCB0 check for other logged in volumes with the same name.
.1 tax
jsr XDOS.VCBCmpGBUF
bcs .2 if no match.
lda XDOS.VCBs+VCB.OFCNT,x test for any open files.
bne .3 cannot look at this volume.
stz XDOS.VCBs,x take duplicate offline if no open files
stz XDOS.VCBs+VCB.DEV,x
* clc ok to log in new volume.
rts
.2 txa index to next vcb
* sec
adc #VCB-1
bcc .1 branch if more to check
clc
rts
.3 sta XDOS.VCBDupFlag duplicate has been found.
stx XDOS.VCBDupEnt save pointer to conflicting vcb.
sec error.
rts
*--------------------------------------
XDOS.CheckFree ldx XDOS.VCBPtr test if enough free blocks available for request.
lda XDOS.VCBs+VCB.FBLK+1,x check if proper count for this volume.
ora XDOS.VCBs+VCB.FBLK,x
bne XDOS.CheckFree1 branch if count is non-zero.
XDOS.GetFreeCntVCBX
jsr XDOS.GetBMCnt get # of bitmaps
sta bmcnt and save.
stz scrtch start count at 0
stz scrtch+1
lda #$FF mark 'first free' temp as unknown
sta nofree
jsr XDOS.FlushBM update volume bitmap.
bcs L3BC1 if error.
ldx XDOS.VCBPtr get address of 1st bitmap
lda XDOS.VCBs+VCB.BMAP,x
sta ZP.BLKNUM
lda XDOS.VCBs+VCB.BMAP+1,x
sta ZP.BLKNUM+1
.1 jsr XDOS.ReadGBuf use general buffer for temp space to
bcs L3BC1 count free blocks (bits).
jsr XDOS.CntFreeGBuf
dec bmcnt was that the last bitmap?
bmi .2 if so, go change fcb so not done again.
inc ZP.BLKNUM
bne .1
inc ZP.BLKNUM+1
bra .1
.2 ldx XDOS.VCBPtr mark which block had 1st free space
lda nofree
bmi L3BBE if no free space was found.
sta XDOS.VCBs+VCB.BMAPIDX,x update the free count.
lda scrtch+1
sta XDOS.VCBs+VCB.FBLK+1,x update volume control byte.
lda scrtch
sta XDOS.VCBs+VCB.FBLK,x
*--------------------------------------
XDOS.CheckFree1 lda XDOS.VCBs+VCB.FBLK,x compare total available free blocks
sec on this volume.
sbc reql
lda XDOS.VCBs+VCB.FBLK+1,x
sbc reqh
bcc L3BBE
clc
rts
L3BBE lda #MLI.E.VOLFULL
sec
L3BC1 rts
*--------------------------------------
XDOS.CntFreeGBuf
ldy #$00
.1 lda XDOS.GBuf,y bit pattern.
beq .2 don't count
jsr XDOS.CntFreeA
.2 lda XDOS.GBuf+$100,y do both pages with same loop
beq .3
jsr XDOS.CntFreeA
.3 iny
bne .1 loop until all 512 bytes counted.
bit nofree has 1st block w/free space been found?
bpl .8 if yes.
lda scrtch test to see if any blocks were counted
ora scrtch+1
beq .8 branch if none counted.
jsr XDOS.GetBMCnt get total # of maps.
sec subtract countdown from total bitmaps
sbc bmcnt
sta nofree
.8 rts
*--------------------------------------
XDOS.CntFreeA asl count the # of bits in this byte
bcc .1
inc scrtch
bne .1
inc scrtch+1
.1 tax
bne XDOS.CntFreeA loop until all bits counted
.8 rts
*--------------------------------------
XDOS.GetBMCnt ldx XDOS.VCBPtr
lda XDOS.VCBs+VCB.TBLK+1,x return the # of bitmaps
ldy XDOS.VCBs+VCB.TBLK,x possible with the total count
bne .1 found in the vcb.
dec adj for bitmap block boundary
.1 lsr divide by 16. the result is
lsr the # of bitmaps.
lsr
lsr
rts
*--------------------------------------
MAN
SAVE usr/src/prodos.fx/prodos.s.xdos.b
LOAD usr/src/prodos.fx/prodos.s
ASM