A2osX/SYS/KERNEL.S.DIRENT.txt
2023-11-04 15:42:28 +01:00

516 lines
9.3 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
* `short 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 DIRENT.RTS
jsr FS.OPEN.DIR
bcs DIRENT.RTS
jmp K.FOpen.REGDIR
*/--------------------------------------
* # ReadDir
* ## C
* `struct dirent *readdir (short int hDIR);`
* ## ASM
* `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 ZPTMP,9
.OR ZPTMP 9 Bytes
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 DIRENT.RTS
ldy #S.FD.REG.REF
lda (pFD),y
beq K.ReadDir.ROOT
bpl .1
jmp K.ReadDir.DEV
.1 jmp K.ReadDir.DIR
DIRENT.EOF lda #MLI.E.EOF
sec
DIRENT.RTS rts
*--------------------------------------
K.ReadDir.ROOT ldy #S.FD.DIR.FC did we already returned something ?
lda (pFD),y
bne DIRENT.EOF
stz K.MLI.PARAMS+1 All Volumes
>LDYAI K.Buf256
>STYA K.MLI.PARAMS+2
>STYA ZPPtr2
>MLICALL MLI.ONLINE
bcs DIRENT.RTS
>LDYAI 16+S.STAT*18+1 14*(Vols+Stat) + 4*(PFT+Stat) + \0
jsr K.ReadDir.GetBuf
bcs DIRENT.RTS
.1 lda (ZPPtr2)
and #$0F
beq .4
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 MLI.GFINFO
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
.4 lda ZPPtr2
clc
adc #16
sta ZPPtr2
bne .1
jsr FS.ClrStat
lda /S.STAT.MODE.DIR
sta K.S.STAT+S.STAT.MODE+1
ldx #0
.6 lda PFTs.pHI,x
beq .8
sta ZPPtr2+1
lda PFTs.pLO,x
sta ZPPtr2
ldy #$ff
.7 iny
lda (ZPPtr2),y
jsr K.ReadDir.AddToBuf
eor #0
bne .7
jsr K.ReadDir.AddStat
.8 inx
cpx #K.PFT.MAX
bne .6
* lda #0 done by S.MEM.F.INIT0
* sta (ZPPtr4) Ending 0
ldy #S.FD.DIR.FC
lda #255
sta (pFD),y Flag that we returned something for next time
jmp K.ReadDir.EXIT
*--------------------------------------
K.ReadDir.DEV jmp DIRENT.EOF TODO : /dev
*--------------------------------------
K.ReadDir.DIR sta K.MLI.PARAMS+1 A=#S.DIR.PRODOS.REF
stz K.MLI.PARAMS+2
lda /K.Buf256 read in Buf256+IOBuf
sta K.MLI.PARAMS+3
stz K.MLI.PARAMS+4
lda /512
sta K.MLI.PARAMS+5
>MLICALL MLI.READ Read A block from directory
bcs .99
ldy #S.FD.DIR.EL Check if first run....
lda (pFD),y
bne .2 no, we have all we need....
ldx #3
.1 lda K.Buf256+$23,x Get K.ReadDir.EL.... From Block
sta K.ReadDir.EL,x
dex
bpl .1
ldx #7
ldy #S.FD.DIR.ACL+7
.20 lda K.Buf256+$14,x
cpy #S.FD.DIR.MODE+1
bne .30
and #$0F
.30 sta (pFD),y
dey
dex
bpl .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
.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
bne .5
lda #MLI.E.EOF
sec
rts
*--------------------------------------
* 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
jsr K.ReadDir.P3Init
K.ReadDir.DIR1 lda (ZPPtr3)
beq .7 Free slot....goto next
and #$F0 get storage_type
cmp #$F0 Volume header ?
beq .1
cmp #$E0 directory header ?
beq .2
lda (ZPPtr3) 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 X,Y = !Total entry Count
bne .7
iny
beq K.ReadDir.DIR2 we reached last entry in whole DIR
.7 jsr K.ReadDir.P3Next
bne K.ReadDir.DIR1
*--------------------------------------
* pass #2 Fill Buffer...(ZPPtr1 & Ptr2 can now be trashed)
*--------------------------------------
K.ReadDir.DIR2 lda K.ReadDir.EPB
sta K.ReadDir.ECIB
>LDYA K.ReadDir.BufSize Get a BufSize bytes buffer for storing results
jsr K.ReadDir.GetBuf
bcc .10
rts
.10 jsr K.ReadDir.P3Init
.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 jsr K.ReadDir.P3Next
bne .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
K.ReadDir.EXIT ldx K.ReadDir.hBuf
txa
jmp K.GetMemPtr
*--------------------------------------
K.ReadDir.P3Init
ldy #4 Skip 4 bytes linked list
sty ZPPtr3
lda /K.Buf256
sta ZPPtr3+1
rts
*--------------------------------------
K.ReadDir.P3Next
lda ZPPtr3
clc
adc K.ReadDir.EL
sta ZPPtr3
bcc .8
inc ZPPtr3+1
.8 dec K.ReadDir.ECIB 0! no more file in block
rts
*--------------------------------------
K.ReadDir.GetBuf
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 #$1D version/min_version for lowercase bitmap
lda (ZPPtr3),y check bxxxxxxx.xxxxxxxx...
bpl .7 not set, no lowercase bitmap present
pha
dey
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