A2osX/SYS/KERNEL.S.DIRENT.txt
2020-07-16 16:53:35 +02:00

531 lines
9.6 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
*/--------------------------------------
* # 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 .9
ldx #1
jsr IO.MkFD
bcs .9
lda K.Buf256+1 One char ("/") ?
beq .8 No, Go open dir....
jsr FS.Stat
bcs .98 file/dir does not exists....quit
lda K.S.STAT+S.STAT.MODE+1
and #$f0
cmp /S.STAT.MODE.DIR
bne .97
jsr IO.MLI.OPEN
bcs .98
.8 jsr STDIO.NewHFile
bcs .98
.9 rts
.97 lda #MLI.E.UNSUPST
.98 jmp UNISTD.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 9 Bytes
K.ReadDir.hBlk .BS 1
K.ReadDir.ECIB .BS 1
K.ReadDir.EL .BS 1
K.ReadDir.EPB .BS 1
K.ReadDir.EC .BS 2
K.ReadDir.BufSize .BS 2
K.ReadDir.hBuf .BS 1
.ED
*--------------------------------------
K.ReadDir jsr PFT.CheckNodeA
bcs K.ReadDir.RTS
ldy #S.FD.REG.REF
lda (pFD),y
beq K.ReadDir.ROOT
bpl .1
jmp K.ReadDir.DEV
.1 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*S.STAT+257 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 FS.ClrStat
lda /S.STAT.MODE.BDEV
sta K.S.STAT+S.STAT.MODE+1
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 something for next time
jmp K.ReadDir.EXIT
*--------------------------------------
K.ReadDir.DEV
jmp K.ReadDir.NoMore
*--------------------------------------
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.hBlk
>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
ldx #8
ldy #16
.10 lda (ZPPtr2),y
pha
iny
dex
bne .10
ldx #8
ldy #S.FD.DIR.ACL+7
.20 pla
cpy #S.FD.DIR.MODE+1
bne .30
and #$0F
.30 sta (pFD),y
dey
dex
bne .20
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 jmp K.ReadDir.FreeBlk
.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 K.ReadDir.FreeBlk
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 K.ReadDir.AddStatACL
jsr K.ReadDir.ADD..
bra .4
.3 jsr K.ReadDir.AddFNToBuf
.4 jsr K.ReadDir.AddStatACL
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
.8 ldx #3
ldy #S.FD.DIR.EL+3
.81 lda K.ReadDir.EL,x Store back this session parameters to S.DIR
sta (pFD),y
dey
dex
bpl .81
jsr K.ReadDir.FreeBlk
K.ReadDir.EXIT ldx K.ReadDir.hBuf
txa
jmp K.GetMemPtr
*--------------------------------------
K.ReadDir.FreeBlk
pha
lda K.ReadDir.hBlk
jsr K.FreeMem
pla
sec
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.hBuf
>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.AddStatACL
jsr FS.DirEnt2Stat
ldy #S.FD.DIR.UID
ldx #S.STAT.UID
.1 lda (pFD),y
sta K.S.STAT,x
iny
inx
cpx #S.STAT.GID+2
bne .1
ldy #S.FD.DIR.MODE+1
ldx #1
.2 lda (pFD),y
ora K.S.STAT+S.STAT.MODE,x
sta K.S.STAT+S.STAT.MODE,x
dey
dex
bpl .2
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