NEW
PREFIX
AUTO 4,1
				.LIST OFF	
*--------------------------------------
X.MAX.RECURSE	.EQ 8
*--------------------------------------
* Uses: (pData)
*  hDIRs		.BS X.MAX.RECURSE+1
*  hDIRENTs		.BS X.MAX.RECURSE+1
*  Index		.BS 1
*  hSrcBasePath	.BS 1
*  hDstBasePath	.BS 1				(optional)
*  STAT			.BS S.STAT
*  hFilter		.BS 1
*--------------------------------------
* Compare a ZPFileName against hFilter (e.g. '*test?.*')
* CC : match
* CS : no match
*--------------------------------------
FilterMatch		>LDA.G index
				dec
				bne .8					in a subdir, match everything
				
				>LDA.G hFilter
				beq	.8					No filter....
				
				>SYSCALL GetMemPtr
				>STYA ZPPtr2
				
				ldy #S.STAT.FSID
				lda (ZPFileStat),y
				bne .10					not prodos...
				
				>LDYA ZPPtr2			CI compare
				>SYSCALL strupr

.10				lda (ZPPtr2)			Get pattern 1st byte
                beq .8                  Match always if empty
				
				ldy #0

				bra .21
				
.1				inc ZPPtr2				Make PTR2 (pattern) advance to next char 
                bne .2 
				inc ZPPtr2+1 

.2				lda (ZPPtr2)       		get pattern char 
				beq .41					end of pattern...
				
.21				cmp #'*' 
				beq .5
                                        
.3				lda (ZPFileName)		we must match ? or regular char, check if at end of string 
                beq .9                  no char left, exit with error 
                                        
				lda (ZPPtr2)       		get back pattern char 
				cmp #'?' 
				beq .4                  no need to compare, any char will match 
				cmp (ZPFileName),y   	Regular Char, compare with string at Y 
				bne .9                  no match, exit 

.4				iny                     advance to next char to compare                                               				
				bra .1					continue if remaining char in pattern 

.41				lda (ZPFileName),y 		end of pattern, but end of string ? 
				
				beq .8					yes, string matched entirely 
*										no, remaining char in string, no match 
.9              sec 
                rts 

.5				inc ZPPtr2				Make PTR2 advance to next char 
				bne .6 
				inc ZPPtr2+1
				
.6				lda (ZPPtr2)			we have '*', last char of pattern ? 
				beq .8					yes, match everything, including empty string 
                                        
				lda (ZPPtr2)       		get next char of pattern 
				cmp #'*'				another '*' ? 
				beq .5					yes, '**' = '*', go next char 
				cmp #'?'				'*?' ? we must match a least one char 
				beq .3 
                                        
.7				lda (ZPFileName),y		we need at least one remaining char in string, check if at end of string 
				beq .9					no chance to match ? or regular char 
                                        
				iny 
				lda (ZPPtr2)       		get again char in pattern 
				cmp (ZPFileName),y 		compare with char in string 
                bne .7  	            not equal to next non wildcard in pattern 

				iny
				bra .1                  go check remaining char in pattern... 
                                        
.8				clc 
                rts 
*--------------------------------------
InitSrcDirYA	>SYSCALL RealPath
				bcc .10
				rts
				
.10				>STYA ZPPtr1
				txa
				>STA.G hFullPath

				ldy #1
				lda (ZPPtr1),y
				beq .5					we have '/'

				>PUSHEA.G STAT
				>LDYA ZPPtr1
				>SYSCALL Stat
				bcs .1					File/DIR does not exists, go extract pattern

				.DO X.ENTER.SUBDIR=1
				>LDA.G STAT+S.STAT.P.TYPE
				cmp #S.FI.T.DIR
				bne .4					TYPE not a DIR, extract....
				bra .5					TYPE=DIR, do not extract pattern 				
				.ELSE
				bra .4
				.FIN
				
.1				ldy #0					TYPE is not DIR, check if wc
				
.11				iny
				lda (ZPPtr1),y			Get Src Path Len
				bne .11
				
				dey
				
				ldx #0					Init Wildcard count
				
.2				lda	(ZPPtr1),y			search backward for a /
				cmp #'/'
				beq .3
				
				cmp #'?'				Test if some wildcard chars....
				beq .21
				cmp #'*'
				bne .22
				
.21				inx						inc wildcard count
.22				dey
				bne .2
				
.3				txa
				beq .91					no wc, file not found....
				
.4				ldy #0

.41				iny						Search end of string.....
				lda (ZPPtr1),y
				bne .41
				
				lda #'/'
				
.42				dey
				cmp (ZPPtr1),y			Search backward /
				bne .42
				
				tya
				sec						+1 to skip '/'
				adc ZPPtr1
				sta ZPPtr2
				tay
				lda ZPPtr1+1
				adc #0
				sta ZPPtr2+1
				
				>SYSCALL strdup
				bcs .9
				txa
				>STA.G hFilter

				lda #0
				sta (ZPPtr2)
				
.5				>LDYAI 256
				>SYSCALL GetMem			Get a 256 buffer to store BasePath
				bcs .9
				
				>STYA ZPPtr2
				txa
				>STA.G hSrcBasePath

				ldy #$ff
				
.6				iny
				lda (ZPPtr1),y
				sta (ZPPtr2),y
				bne .6
					
				dey
				lda #'/'
				cmp (ZPPtr2),y
				beq .7

				iny
				sta (ZPPtr2),y
				iny
				lda #0
				sta (ZPPtr2),y
				
.7				>LDYA ZPPtr2
				>SYSCALL OpenDir
				
				bcs .9
				
				ldy #hDIRs
				sta (pData),y			set hDIRs[0] = Src Hdir
				
				ldy #index
				lda #1
				sta (pData),y			index=hDIRs[0]
				
				jsr .9					Cleanup
				
				clc
				rts
				
.91				lda #MLI.E.FNOTFND

.9				pha
				>LDA.G hFullPath
				>SYSCALL FreeMem
				pla
				sec
InitSrcDirYA.RTS
				rts	
*--------------------------------------
				.DO X.COPY.TO.DEST=1
				
InitDstDirYA	>SYSCALL RealPath
				bcs InitSrcDirYA.RTS

				>STYA ZPPtr1
				txa
				>STA.G hFullPath
				
				>PUSHEA.G STAT
				>LDYA ZPPtr1
				>SYSCALL Stat
				bcs .1					File/DIR does not exists, go extract DstFileName
				
				>LDA.G STAT+S.STAT.P.TYPE
				cmp #S.FI.T.DIR
				beq .5					Dst is a directory...no destfilename
				
.1				ldy #0

.11				iny						Search end of string.....
				lda (ZPPtr1),y
				bne .11
				
				lda #'/'
				
.2				dey
				cmp (ZPPtr1),y			Search backward /
				bne .2
				
				tya
				sec						+1 to skip '/'
				adc ZPPtr1
				sta ZPPtr2
				tay
				lda ZPPtr1+1
				adc #0
				sta ZPPtr2+1

				>SYSCALL strdup
				bcs .9
				txa
				>STA.G hDstFileName

				lda #0
				sta (ZPPtr2)				
				
.5				>LDYAI 256
				>SYSCALL GetMem			Get a 256 buffer to store DstBasePath
				bcs .9
				
				>STYA ZPPtr2
				txa
				>STA.G hDstBasePath
				
				ldy #$ff
				
.6				iny
				lda (ZPPtr1),y
				sta (ZPPtr2),y
				bne .6
				
				dey

				lda #'/'
				cmp (ZPPtr2),y
				beq .7
				
				iny
				sta (ZPPtr2),y
				iny
				lda #0
				sta (ZPPtr2),y
	
.7				jsr .9					Cleanup

				clc
.99				rts
			
.9				pha
				>LDA.G hFullPath
				>SYSCALL FreeMem
				pla
				sec
				rts	
				
				.FIN
*--------------------------------------
GetNextEntry	jsr GetEntry
				bcs .9
				
				jsr GetFilenameLen		Save actual file len for setting up
				pha						new offset later
				
				lda ZPFileStat
				clc
				adc #S.STAT
				sta ZPFileName
				
				lda ZPFileStat+1
				adc /S.STAT
				sta ZPFileName+1		Make nDIRENTs[i] point to next DIRENT

				jsr GetFilenameLen		are we at end of this buffer ?
				beq .1					yes, go read next one ...
				
				jsr SetFileStatPtr

				jsr GetoDIRENT

				pla						Get back previous file len
				
				sec
				adc (pData),y
				sta (pData),y
				iny

				lda #0
				adc (pData),y
				sta (pData),y
				
				dey
				
				lda #S.STAT
				clc
				adc (pData),y
				sta (pData),y
				iny

				lda /S.STAT
				adc (pData),y
				sta (pData),y
				clc
				rts
				
.1				pla
				jsr GetEntry.ReadDir
				bcs .9
				
				jsr GetFilenameLen
				beq GetNextEntry.99

				jsr SetFileStatPtr
				
				clc
.9				rts

GetNextEntry.99	sec
				rts
*--------------------------------------
GetEntry		jsr GethDIRENT
				bne .1					we have a buffer to scan
				
				jsr GetEntry.ReadDir	First run, get first block
				bcs .9					ZPFileName = start of buffer

				lda (ZPFileName)		Empty !!!
				bne .8

				sec
				rts

.1				>SYSCALL GetMemPtr
				>STYA ZPFileName		
				
				jsr GetoDIRENT
				
				lda ZPFileName
				clc
				adc (pData),y
				sta ZPFileName
				
				iny
				lda ZPFileName+1
				adc (pData),y
				sta ZPFileName+1		ZPFileName=ZPFileName+oDIRENT
				
.8				jsr GetFilenameLen
				jsr SetFileStatPtr
			
				clc
.9				rts
*--------------------------------------
GetEntry.ReadDir
				jsr GethDIRENT
				beq .1

				pha
				lda #0
				sta (pData),y			reset hDIRENT
				pla
				>SYSCALL FreeMem		discard previous hDIRENT

.1				jsr GethDIR

				>SYSCALL ReadDir
				bcs .9
				>STYA ZPFileName
				
				ldy #index
				lda (pData),y
				clc
				adc #hDIRENTs-1
				tay
				txa						get hDIRENT in A
				sta (pData),y
				
				jsr GetoDIRENT
				
				lda #0					and reset offset for this buffer
				sta (pData),y
				iny
				sta (pData),y
				clc
.9				rts
*--------------------------------------
EnterSubDirYA	>STYA ZPPtr2			save SUBDIR for StrCat

				>LDA.G index
				cmp #X.MAX.RECURSE
				beq .9

				ldy #hSrcBasePath
				jsr EnterSubDirY
				
				>LDYA ZPPtr1
				>SYSCALL OpenDir

				bcs .9
				pha
				
				>INC.G index
				tax
*				clc						from BCS
				adc #hDIRs-1
				tay
				pla
				sta (pData),y
				
				txa						make sure hDIRENTs[i] is closed
				adc #hDIRENTs-1
				tay
				lda #0
				sta (pData),y
				
				.DO X.COPY.TO.DEST=1
				ldy #hDstBasePath
				jsr EnterSubDirY
				.FIN
				
				clc
.9				rts

EnterSubDirY	lda (pData),y
				>SYSCALL GetMemPtr
				
				>STYA ZPPtr1			save full path

				jsr .1					Make sure ending with /
				
				>PUSHW ZPPtr2
				>LDYA ZPPtr1
				>SYSCALL StrCat

.1				ldy #0
				
.2				iny
				lda (ZPPtr1),y
				bne .2
				
				dey
				lda #'/'
				cmp (ZPPtr1),y
				beq .8
				iny
				sta (ZPPtr1),y
				iny
				lda #0
				sta (ZPPtr1),y
				
.8				rts
*--------------------------------------
LeaveSubDir		>LDA.G index
				beq .9
				
				jsr GethDIRENT.A
				beq .1
				
				pha
				lda #0
				sta (pData),y
				pla
				>SYSCALL FreeMem

.1				jsr GethDIR
				
				pha
				lda #0
				sta (pData),y
				pla
				>SYSCALL CloseDir

				>DEC.G index
				bne .8
				
				ldy #hSrcBasePath
				lda (pData),y
				>SYSCALL FreeMem

				.DO X.COPY.TO.DEST=1
				ldy #hDstBasePath
				lda (pData),y
				>SYSCALL FreeMem
				.FIN
				
.9				sec
				rts
				
.8				clc
				rts
*--------------------------------------
BasePath..		.DO X.COPY.TO.DEST=1

				ldy #hDstBasePath
				jsr BasePath..1
				
				.FIN
				
				ldy #hSrcBasePath
				
BasePath..1		lda (pData),y
				>SYSCALL GetMemPtr
								
				>STYA ZPPtr1			save full path
				
				ldy #$ff
				
.1				iny				
				lda (ZPPtr1),y			get len
				bne .1
				
				dey 					discard ending /
				
.2				dey
				lda (ZPPtr1),y
				cmp #'/'
				bne .2
				
				iny
				
				lda #0
				sta (ZPPtr1),y			cut DIR2/ from /dir1/DIR2/

				rts
*--------------------------------------
GetFilenameLen	ldy #$ff

.1				iny
				lda (ZPFileName),y
				bne .1
				
				tya
				
				rts
*--------------------------------------
SetFileStatPtr	sec
				adc ZPFileName
				sta ZPFileStat
				lda ZPFileName+1
				adc #0
				sta ZPFileStat+1
				rts
*--------------------------------------
GethDIR			ldy #index
				lda (pData),y
				clc
				adc #hDIRs-1
				tay
				lda (pData),y
				rts
*--------------------------------------				
GethDIRENT		ldy #index
				lda (pData),y
GethDIRENT.A	clc
				adc #hDIRENTs-1
				tay
				lda (pData),y
				rts
*--------------------------------------
GetoDIRENT		ldy #index
				lda (pData),y
				asl
				clc
				adc #oDIRENTs-1
				tay
				rts
*--------------------------------------
MAN
SAVE USR/SRC/BIN/X.FILEENUM.S
LOAD USR/SRC/BIN/CP.S
ASM
