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
