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.BufS .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.Add2B iny dex bne .2 txa Add ending 0 for C String jsr K.ReadDir.Add2B 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.Add2B 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 K.ReadDir.DIR0 >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 K.ReadDir.DIR1 iny bne K.ReadDir.DIR1 lda #MLI.E.EOF sec rts *-------------------------------------- * pass #1 compute BufS... *-------------------------------------- K.ReadDir.DIR1 lda K.ReadDir.EPB sta K.ReadDir.ECIB lda #1 For Ending 0 sta K.ReadDir.BufS stz K.ReadDir.BufS+1 jsr K.ReadDir.P3Init stz .8+1 .10 lda (ZPPtr3) beq .7 Free slot....goto next inc .8+1 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 "#" + 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.BufS sta K.ReadDir.BufS bcc .3 inc K.ReadDir.BufS+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 .10 .8 lda #$FF bne K.ReadDir.DIR2 jmp K.ReadDir.DIR0 *-------------------------------------- * pass #2 Fill Buffer...(ZPPtr1 & Ptr2 can now be trashed) *-------------------------------------- K.ReadDir.DIR2 lda K.ReadDir.EPB sta K.ReadDir.ECIB >LDYA K.ReadDir.BufS Get a BufS 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.SA2B jsr K.ReadDir.ADD.. bra .4 .3 jsr K.ReadDir.FN2B .4 jsr K.ReadDir.SA2B 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.Add2B Add X dot(s) dex bne .1 txa jmp K.ReadDir.Add2B Add Ending 0 *-------------------------------------- K.ReadDir.FN2B 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.Add2B iny dex bne .8 txa * jsr K.ReadDir.Add2B * rts *-------------------------------------- K.ReadDir.Add2B sta (ZPPtr4) inc ZPPtr4 bne .8 inc ZPPtr4+1 .8 rts *-------------------------------------- K.ReadDir.SA2B 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.Add2B 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