NEW
  AUTO 3,1
*/--------------------------------------
* # OpenDir
* ## C
* `int hDIR opendir (const char * dirpath);`
* ## ASM
* `>PUSHW dirpath`
* `>SYSCALL opendir` 
* ## RETURN VALUE 
*  CC : success
*   A = hDIR
*  CS : error
*   A = EC
*\--------------------------------------
K.OpenDir		jsr PFT.CheckPath0
				bcs K.ReadDir.RTS

				inc pStack
				inc pStack

				ldx #1
				jsr IO.MkFD
				bcs K.ReadDir.RTS

				lda K.Buf256+1			One char ("/") ?
				beq .8					No, Go open dir....

				>MLICALL MLIGETFILEINFO
				bcs .98					file/dir does not exists....quit
				lda K.MLI.PARAMS+4
				cmp #$0F				Directory ?
				bne .98
				jsr IO.MLI.OPEN
				bcs .98		

.8				lda IO.hFD
				jsr STDIO.NewHFile

				bcc K.ReadDir.RTS
.98				jmp IO.OPEN.ERR
*/--------------------------------------
* # ReadDir
* ## C
* `int readdir (int hDIR, S.DIRENT * dirent);`
* ## ASM
* `>PUSHW dirent`
* `lda hDIR`
* `>SYSCALL readdir`
* ## RETURN VALUE 
*  CC : success
*   X = hDIRENT
*   Y,A = PTR to S.DIRENT
*  CS : error
*   A = EC
*   note : A = 0 means no more entry
*\--------------------------------------
				.DUMMY 
				.OR ZPTMP				8 Bytes
K.ReadDir.hMem	.BS 1
K.ReadDir.BufSize	.BS 2
K.ReadDir.ECIB	.BS 1
K.ReadDir.EL	.BS 1
K.ReadDir.EPB	.BS 1
K.ReadDir.EC	.BS 2
				.ED
*--------------------------------------
K.ReadDir		jsr PFT.CheckNodeA
				bcs K.ReadDir.RTS
				ldy #S.FD.REG.REF
				lda (pFD),y
				beq K.ReadDir.ROOT
				jmp K.ReadDir.DIR
K.ReadDir.NoMore
				lda #MLI.E.EOF
				sec
K.ReadDir.RTS	rts
*--------------------------------------
K.ReadDir.ROOT
				ldy #S.FD.DIR.FC		did we already returned something ?
				lda (pFD),y
				bne K.ReadDir.NoMore

				stz K.MLI.PARAMS+1		All Volumes
				>LDYAI K.Buf256
				>STYA K.MLI.PARAMS+2
				>STYA ZPPtr2
				>MLICALL MLIONLINE
				bcs K.ReadDir.RTS

				>LDYAI 16*16+16*S.STAT+1	16 (Vols+Stat) + \0
				jsr K.ReadDir.GetBufYA
				bcs K.ReadDir.RTS
				
				lda #16
				sta K.ReadDir.EC
				
.1				lda (ZPPtr2)
				and #$0F
				beq .6

				tax
				inc
				sta K.MLI.PATH
				lda #'/'
				sta K.MLI.PATH+1
				ldy #1
				
.2				lda (ZPPtr2),y
				sta K.MLI.PATH+1,y
				jsr K.ReadDir.AddToBuf
				iny
				dex
				bne .2
				
				txa						Add ending 0 for C String 
				jsr K.ReadDir.AddToBuf
				
				jsr SHARED.ClrStat
				lda (ZPPtr2)

				asl						DRIVE in Carry
				pha
				lda #0
				rol
				inc
				sta K.S.STAT+S.STAT.P.DRIVE
				pla
				lsr						CC
				lsr
				lsr
				lsr
				lsr
				sta K.S.STAT+S.STAT.P.SLOT

				>LDYAI K.MLI.PATH
				>STYA K.MLI.PARAMS+1
				>MLICALL MLIGETFILEINFO
				sta K.S.STAT+S.STAT.P.DEVSTATUS

				bcs .3

				>LDYA K.MLI.PARAMS+5		AUXTYPE=TOTAL BLOCKS
				>STYA K.S.STAT+S.STAT.P.DEVBLOCKS
				>LDYA K.MLI.PARAMS+8
				>STYA K.S.STAT+S.STAT.BLOCKS

.3				jsr K.ReadDir.AddStat

.6				lda ZPPtr2
				clc
				adc #16
				sta ZPPtr2
				bcc .7
				inc ZPPtr2+1
				
.7				dec K.ReadDir.EC
				bne .1				
				
*				lda #0					done by S.MEM.F.INIT0
*				sta (ZPPtr4)			Ending 0

				ldy #S.FD.DIR.FC
				lda #16
				sta (pFD),y				Flag that we returned somthing for next time 
				jmp K.ReadDir.EXIT
*--------------------------------------
K.ReadDir.DIR  	sta K.MLI.PARAMS+1		A=#S.DIR.PRODOS.REF

				>LDYAI 512				Get a 512 bytes buffer for reading dir...
				jsr K.GetMem
				bcs .99

				stx K.ReadDir.hMem
				>STYA K.MLI.PARAMS+2	For reading
				pha
				tya
*				clc						CC from  K.GetMem
				adc #4					Skip 4 bytes linked list		
				sta ZPPtr2				PTR to Buffer for PASS #1
				sta ZPPtr3				PTR to Buffer for PASS #2
				pla
				adc #0
				sta ZPPtr2+1			PTR to Buffer for PASS #1
				sta ZPPtr3+1			PTR to Buffer for PASS #2

				>LDYAI 512
				>STYA K.MLI.PARAMS+4
				>MLICALL MLIREAD		Read A block from directory
				bcs .98

				ldy #S.FD.DIR.EL		Check if first run....
				lda (pFD),y
				bne .2					no, we have all we need....

				ldy #$1f+3
				ldx #3

.1				lda (ZPPtr2),y			Get K.ReadDir.EL....	From Block
				sta K.ReadDir.EL,x
				dey
				dex
				bpl .1

				inc K.ReadDir.EC		Add one to EC because we include VOL/DIR Header
				bne .4

				inc K.ReadDir.EC+1		...and ProDOS does NOT include header entry in EC
				bra .4

.98				jsr K.ReadDir.CLN
				sec
.99				rts

.2				ldy #S.FD.DIR.EL+3
				ldx #3

.3				lda (pFD),y				get this session parameters from S.DIR
				sta K.ReadDir.EL,x
				dey
				dex
				bpl .3

.4				lda K.ReadDir.EC
				eor #$ff
				tax

				lda K.ReadDir.EC+1
				eor #$ff
				tay

				inx						Any entry remaining ?
				bne .5

				iny
				beq .98					no...exit
* pass #1 compute BufSize...
.5				lda K.ReadDir.EPB
				sta K.ReadDir.ECIB

				lda #1					For Ending 0
				sta K.ReadDir.BufSize
				stz K.ReadDir.BufSize+1

K.ReadDir.DIR1	lda (ZPPtr2)			X = EntryCount In This Block
				beq .7					Free slot....goto next

				and #$F0				get storage_type
				cmp #$F0				Volume header ?
				beq .1

				cmp #$E0				directory header ?
				beq .2

				lda (ZPPtr2)			regular DIR or File, get LEN
				and #$F					compute filename len
				sec						add "#<filename>" + S.STAT
				adc #S.STAT
				.HS 2C					bit abs
.1				lda #2+S.STAT			add "1." string + S.STAT
				.HS 2C					bit abs
.2				lda #2+S.STAT+3+S.STAT	add "1." + S.STAT + "2.." + S.STAT...

				clc
				adc K.ReadDir.BufSize
				sta K.ReadDir.BufSize
				bcc .3

				inc K.ReadDir.BufSize+1
.3				inx
				bne .7

				iny
				bra K.ReadDir.DIR2		we reached last entry in whole DIR

.7				lda ZPPtr2
				clc
				adc K.ReadDir.EL
				sta ZPPtr2
				bcc .8

				inc ZPPtr2+1

.8				dec K.ReadDir.ECIB
				bne K.ReadDir.DIR1
* pass #2 Fill Buffer...(ZPPtr1 & Ptr2 can now be trashed)
K.ReadDir.DIR2	jsr K.ReadDir.GetBuf
				bcs .9

				lda K.ReadDir.EPB
				sta K.ReadDir.ECIB

.1				lda (ZPPtr3)
				beq .7					Empty slot, skip

				and #$F0
				cmp #$F0				Vol Header ?
				bne .2

				jsr K.ReadDir.ADD.
				bra .4

.2				cmp #$E0				Dir Header ?
				bne .3

				jsr K.ReadDir.ADD.
				jsr SHARED.DirEnt2Stat
				jsr K.ReadDir.AddStat
				jsr K.ReadDir.ADD..
				bra .4

.3				jsr K.ReadDir.AddFNToBuf
				
.4				jsr SHARED.DirEnt2Stat
				jsr K.ReadDir.AddStat

				lda K.ReadDir.EC			decrease global counter...
				sec
				sbc #1
				sta K.ReadDir.EC
				lda K.ReadDir.EC+1
				sbc #0
				sta K.ReadDir.EC+1
				ora K.ReadDir.EC
				beq .8						0! no more files in DIR

.7				dec K.ReadDir.ECIB			0! no more file in block
				beq .8

				lda ZPPtr3
				clc
				adc K.ReadDir.EL
				sta ZPPtr3
				bcc .1

				inc ZPPtr3+1	
				bra .1

.9				jsr K.ReadDir.CLN
				sec
				rts

.8				ldx #3
				ldy #S.FD.DIR.EL+3

.81				lda K.ReadDir.EL,x	Store back this session prameters to S.DIR
				sta (pFD),y
				dey
				dex
				bpl .81

				jsr K.ReadDir.CLN		Discard READBUFFER

K.ReadDir.EXIT	ldx #$ff				Self Modified : hDIRENT
				txa
				jmp K.GetMemPtr
*--------------------------------------
K.ReadDir.CLN	pha
				lda K.ReadDir.hMem
				jsr K.FreeMem
				pla
				rts			
*--------------------------------------
K.ReadDir.GetBuf
				>LDYA K.ReadDir.BufSize			Get a BufSize bytes buffer for storing results
K.ReadDir.GetBufYA
				jsr K.GetMem0			make sure 0 filled
				bcs .9
				stx K.ReadDir.EXIT+1
				>STYA ZPPtr4
.9				rts
*--------------------------------------
K.ReadDir.ADD.  ldx #1					filename="1."
				.HS 2C					bit abs
K.ReadDir.ADD..
				ldx #2					filename="2.."
				lda #'.'

.1				jsr K.ReadDir.AddToBuf		Add X dot(s)
				dex
				bne .1

				txa
				jmp K.ReadDir.AddToBuf		Add Ending 0
*--------------------------------------
K.ReadDir.AddFNToBuf
				ldy #$1C				version/min_version for lowercase bitmap
				lda (ZPPtr3),y			check bxxxxxxx.xxxxxxxx...
				bpl	.7					not set, no lowercase bitmap present

				pha
				iny
				lda (ZPPtr3),y
				pha

				lda #$1
				sta .2+1

				ldy #15

.1				pla
.2				bit #$ff
				pha
				beq .3

				lda (ZPPtr3),y
				ora #$20				convert a-z to A-Z adding from $4x to $6x 
				sta (ZPPtr3),y

.3				asl .2+1
				bne .4

				rol .2+1
				pla

.4				dey
				bne .1

				pla
.7				lda (ZPPtr3)
				and #$0F				get filename len
				tax
				ldy #1

.8				lda (ZPPtr3),y			
				jsr K.ReadDir.AddToBuf
				iny
				dex
				bne .8

				txa
*				jsr K.ReadDir.AddToBuf

*				rts
*--------------------------------------
K.ReadDir.AddToBuf
				sta (ZPPtr4)
				inc ZPPtr4
				bne .8
				inc ZPPtr4+1
.8				rts
*--------------------------------------
K.ReadDir.AddStat
				ldy #0

.1				lda K.S.STAT,y
				jsr K.ReadDir.AddToBuf
				iny
				cpy #S.STAT
				bne .1

				rts
*/-------------------------------------
* # CloseDir
* ## C
* `void closedir(hDIR);`
* ## ASM
* `lda hDIR`
* `>SYSCALL closedir`
* ## RETURN VALUE
*  none, always succeed. 
*\-------------------------------------
*K.CloseDir		.EQ K.FClose
*--------------------------------------
MAN
SAVE USR/SRC/SYS/KERNEL.S.DIRENT
LOAD USR/SRC/SYS/KERNEL.S
ASM
