duskos

dusk os fork
git clone git://git.alexwennerberg.com/duskos
Log | Files | Refs | README | LICENSE

commit 631b02f502a29fdca53ce35fa214f89b8035e048
parent a70c4f5510032143bb0e0100fac5aecafca079a1
Author: Virgil Dupras <hsoft@hardcoded.net>
Date:   Sun, 21 Aug 2022 11:26:37 -0400

fs/fat: implement :iter and :next

Also, fix an edge case bug in FSInfo :read where we wouldn't properly handle
filenames using all 11 characters in the name field.

Diffstat:
Mfs/fs/fat.fs | 10++++++----
Mfs/fs/fatlo.fs | 21+++++++++++++++++++--
Mfs/xcomp/bootlo.fs | 1+
3 files changed, 26 insertions(+), 6 deletions(-)

diff --git a/fs/fs/fat.fs b/fs/fs/fat.fs @@ -22,17 +22,19 @@ ?f<< /lib/str.fs extends FSInfo struct[ FATInfo - create _buf DirEntry NAMESZ 1+ 1+ allot + DirEntry NAMESZ 2 + const BUFSZ \ 1 for the '.' and 1 for len + create _buf BUFSZ allot + SPC c, \ always have a SPC suffix create _struct _buf ( name ) , 0 ( size ) , 0 ( dir? ) , create _rootname 6 c, ," (root)" create _root _rootname , 0 , 1 , - : spcidx ( name -- idx ) SPC swap DirEntry NAMESZ [c]? ; + : spcidx ( name -- idx ) SPC swap BUFSZ [c]? ; : :read ( id fat -- info ) over not if 2drop _root exit then - _buf DirEntry NAMESZ 1+ SPC fill + _buf BUFSZ SPC fill _FAT :getdirentry dup _buf 1+ DirEntry EXTIDX move ( dirent ) _buf 1+ spcidx ( dirent namelen ) - over DirEntry EXTIDX + c@ SPC = not if ( dirent namelen ) + over DirEntry EXTIDX + c@ SPC <> if ( dirent namelen ) over DirEntry EXTIDX + swap _buf + 1+ '.' swap c!+ ( dir src dst ) DirEntry EXTSZ move else drop then ( dirent ) _buf 1+ spcidx ( dirent len ) _buf c! ( dirent ) diff --git a/fs/fs/fatlo.fs b/fs/fs/fatlo.fs @@ -23,6 +23,9 @@ struct[ DirEntry 26 &+w@ cluster : cluster! ( n self -- ) 26 + w! ; 28 field filesize + : :lastentry? ( self -- f ) c@ not ; + : :valid? ( self -- f ) dup :lastentry? not swap c@ $e5 <> and ; + : :iterable? ( self -- f ) dup :valid? swap c@ '.' <> and ; ]struct \ Just a dummy entry so that we can reference the root directory as a "direntry" @@ -184,7 +187,6 @@ extends File struct[ FATFile : :dirent ( self -- dirent ) dup entryoff swap :fat :getdirentry ; : :cluster0 ( self -- cl ) :dirent DirEntry cluster ; - \ TODO _dst :seek is broken for FAT when file is empty. fix. 0 value self \ set self to pos. If new pos crosses cluster boundaries compared to current \ pos, flush current buffer and read a new sector from disk. @@ -239,6 +241,21 @@ extends File struct[ FATFile ]struct extends _FAT struct[ FATLO + 0 value _dirent + : :next ( self -- id-or-0 ) + _dirent not if abort" invalid iterator" then >r + DirEntry SZ to+ _dirent _dirent r@ _FAT :)buf = if + r@ _FAT :nextsector? not if + rootdirentry( to _dirent else \ parses as "lastentry" + r@ _FAT :buf( to _dirent then then + _dirent DirEntry :lastentry? if rdrop 0 to _dirent 0 else + _dirent DirEntry :iterable? if _dirent r> _FAT :getid else r> :next then + then ; + + : :iter ( dirid self -- id-or-0 ) >r + r@ _FAT :getdirentry r@ _FAT :readdir + r@ _FAT :buf( DirEntry SZ - to _dirent r> :next ; + : :child ( dirid name self -- id-or-0 ) >r fnbuf! r@ _FAT :getdirentry r@ _FAT :readdir r@ _FAT :findindir dup if r@ _FAT :getid then rdrop ; @@ -256,7 +273,7 @@ extends _FAT struct[ FATLO : :mountvolume ( drv -- fs ) align4 here >r dup , ( drv R:fs ) 0 ( flags ) , - ['] :child , ['] abort , ['] :fatopen , ['] abort , ['] abort , ['] abort , + ['] :child , ['] abort , ['] :fatopen , ['] :iter , ['] :next , ['] abort , ['] abort , ['] abort , 0 , 0 , 0 , 0 , ( drv ) \ At this point, "here" points to the FAT-header-to-be. Read the first sector diff --git a/fs/xcomp/bootlo.fs b/fs/xcomp/bootlo.fs @@ -47,6 +47,7 @@ code : ] code ] ; : 0>= 0< not ; : >= < not ; : <= > not ; +: <> = not ; : -^ swap - ; : / /mod nip ; : mod /mod drop ;