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 .9 jsr FS.OPEN.DIR bcs .9 jmp K.FOpen.REGDIR .9 rts */-------------------------------------- * # 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 ZPTMP,9 .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 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 MLIONLINE bcs DIRENT.RTS >LDYAI 16+S.STAT*18+1 14*(Vols+Stat) + 4*(PFT+Stat) + \0 jsr K.ReadDir.GetBufYA 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 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 .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 Flt.Table.pftHI,x beq .8 sta ZPPtr2+1 lda Flt.Table.pftLO,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.FLT.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 lda /K.Buf256 read in stz K.MLI.PARAMS+2 For reading sta K.MLI.PARAMS+3 For reading ldy #4 Skip 4 bytes linked list sty ZPPtr2 PTR to Buffer for PASS #1 sty ZPPtr3 PTR to Buffer for PASS #2 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 .99 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 .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 clc beq .99 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 "#" + 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 lda K.ReadDir.EPB sta K.ReadDir.ECIB jsr K.ReadDir.GetBuf bcc .1 rts .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 K.ReadDir.EXIT ldx K.ReadDir.hBuf txa jmp K.GetMemPtr *-------------------------------------- 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 #$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