NEW
PREFIX
AUTO 4,1
*/--------------------------------------
* # OpenDir
* ## C
* `int hDIR opendir (const char * dirpath);`
* ## ASM
* `>LDYA dirpath`
* `>SYSCALL opendir` 
* ## RETURN VALUE 
*  CC : success
*   A = hDIR
*  CS : error
*   A = EC
*\--------------------------------------
K.OpenDir		jsr PFT.CheckPathYA
				bcs K.ReadDir.RTS
				
				>LDYAI S.FD.DIR
				ldx #S.MEM.F.INIT0+S.MEM.F.FD
				jsr MEM.GetMem.YAX
				bcs K.ReadDir.RTS
				
				>STYA pFD
				stx IO.hFD
				
				ldy #S.FD.T
				lda #S.FD.T.DIR
				sta (pFD),y

				ldy #1 				
				lda K.Buf256,y			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.MLIOPEN
				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+15			conflict with PTime2Time
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
				bcc .10
				
				sec
.99				rts					
* pass #1 compute BufSize.....				
.10				lda #1					+1 for Ending 0
				sta	K.ReadDir.BufSize
				stz K.ReadDir.BufSize+1
				
				stz K.ReadDir.EC
				
				ldy #0

.1				lda (ZPPtr2),y
				and #$0F
				beq .2
				
				inc K.ReadDir.EC		increase entry count
				
				sec						Add Filelen +1
				adc #S.STAT				will ends with CC
				adc K.ReadDir.BufSize
				sta K.ReadDir.BufSize
				bcc .2
				inc K.ReadDir.BufSize+1
								
.2				tya
				clc
				adc #16
				tay
				bcc .1					loop until 256 bytes scanned
				
* pass #2 Fill Buffer...
				jsr K.ReadDir.GetBuf
				bcs .99
				
.3				lda (ZPPtr2)
				and #$0F
				beq .88

				tax
				inc
				sta K.MLI.PATH
				lda #'/'
				sta K.MLI.PATH+1
				ldy #1
				
.4				lda (ZPPtr2),y
				sta K.MLI.PATH+1,y
				jsr K.ReadDir.AddToBuf
				iny
				dex
				bne .4
				
				txa						Add ending 0 for C String 
				jsr K.ReadDir.AddToBuf
				
				jsr K.ReadDir.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 .80
				>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
				
.80				jsr K.ReadDir.ADDSTAT

				dec K.ReadDir.EC
				beq .5
				
.88				lda ZPPtr2
				clc
				adc #16
				sta ZPPtr2
				bcc .3
				inc ZPPtr2+1
				bra .3
				
*				lda #0					done by S.MEM.F.INIT0
*				sta (ZPPtr4)			Ending 0
				
.5				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 .6
				
.2				cmp #$E0				Dir Header ?
				bne .3
				jsr K.ReadDir.ADD.
				jsr K.ReadDir.ADD..
				bra .6
				
.3				jsr K.ReadDir.AddFNToBuf
				jsr K.ReadDir.ClrStat

				lda (ZPPtr3)
				and #$F0
				cmp #$D0					Directory ?
				bne .5
				jsr K.ReadDir.ADDD
				bra .6
				
.5				jsr K.ReadDir.ADDF

.6				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				
*				lda #0					S.MEM.F.INIT0 already did this
*				sta (ZPPtr4)			Ending 0

				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
				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
				jsr K.ReadDir.AddToBuf		Add Ending 0
				
				jsr K.ReadDir.ClrStat
				
*				ldy #$25				total_blocks
*				lda (ZPPtr3),y
*				sta K.S.STAT+S.STAT.BLOCKS
*				iny
*				lda (ZPPtr3),y
*				sta K.S.STAT+S.STAT.BLOCKS+1
*--------------------------------------
K.ReadDir.ADDD
				lda #$0F
				sta K.S.STAT+S.STAT.P.TYPE

				lda /S.STAT.MODE.DIR
				sta K.S.STAT+S.STAT.MODE+1
				bra K.ReadDir.AddAccess
*--------------------------------------
K.ReadDir.ADDF
				lda /S.STAT.MODE.REG
				sta K.S.STAT+S.STAT.MODE+1
				
				ldx #ADDF.DST-ADDF.SRC

.1				ldy ADDF.SRC-1,x
				lda (ZPPtr3),y
				ldy ADDF.DST-1,x
				sta K.S.STAT,y
				dex
				bne .1
*--------------------------------------
K.ReadDir.AddAccess
				ldy #$1E				ProDOS Access
				lda (ZPPtr3),y

				jsr STAT.Access2Mode
				
				sta K.S.STAT+S.STAT.MODE
				tya
				ora K.S.STAT+S.STAT.MODE+1		preserve DIR
				sta K.S.STAT+S.STAT.MODE+1
*--------------------------------------
K.ReadDir.AddTime
				>PUSHWI K.S.STAT+S.STAT.CTIME
				lda #$18				creation Date/time
				jsr K.ReadDir.ConvertTime

				>PUSHWI K.S.STAT+S.STAT.MTIME
				lda #$21				mod Date/time
				jsr K.ReadDir.ConvertTime
*--------------------------------------
K.ReadDir.AddStat
				ldy #S.STAT-1
				
.1				lda K.S.STAT,y
				sta (ZPPtr4),y
				dey
				bpl .1
				
				lda ZPPtr4
				clc
				adc #S.STAT
				sta ZPPtr4
				bcc .8
				inc ZPPtr4+1
.8				rts
*--------------------------------------
ADDF.SRC		.HS 1013141516171f20
ADDF.DST		.DA #S.STAT.P.TYPE
				.DA #S.STAT.BLOCKS,#S.STAT.BLOCKS+1
				.DA #S.STAT.SIZE,#S.STAT.SIZE+1,#S.STAT.SIZE+2
				.DA #S.STAT.P.AUXTYPE,#S.STAT.P.AUXTYPE+1
*--------------------------------------
K.ReadDir.ClrStat
				ldx #S.STAT-1
				
.1				stz K.S.STAT,x
				dex
				bpl .1
				rts
*--------------------------------------
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.ConvertTime
				clc
				adc ZPPtr3
				tay
				lda ZPPtr3+1
				adc #0
				ldx #SYS.PTime2Time		BANK2
				jmp K.SYSCALL2.BANK
*/-------------------------------------
* # 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
