M fs/fs/boot.fs => fs/fs/boot.fs +25 -7
@@ 48,22 48,28 @@ here value )FAT16
\ can have more than BPB_RootEntCnt entries.
create dirbuf( RootDirSectors BPB_BytsPerSec * allot
here const )dirbuf
-create fnbuf FNAMESZ allot
+create fnbuf( FNAMESZ allot
+here const )fnbuf
: upcase ( c -- c ) dup 'a' - 26 < if $df and then ;
+: fnbufclr fnbuf( FNAMESZ SPC fill ;
+
\ we assume a 8.3 name. Don't call this with an inadequate name.
: _tofnbuf ( fname -- )
- A>r >A Ac@+ >r fnbuf FNAMESZ SPC fill fnbuf begin ( a )
- Ac@+ dup '.' = if ( a c ) 2drop fnbuf 8 + else upcase swap c!+ then
+ A>r >A Ac@+ >r fnbufclr fnbuf( begin ( a )
+ Ac@+ dup '.' = if ( a c ) 2drop fnbuf( 8 + else upcase swap c!+ then
next drop r>A ;
-\ Search in directory that is currently loaded in dirbuf.
-\ Return address of directory entry, abort if not found.
-: findindir ( fname -- direntry ) _tofnbuf
+
+: _findindir ( -- direntry )
dirbuf( begin ( a )
dup )dirbuf < while ( a )
- fnbuf over DIR_Name []= not while ( a ) DIRENTRYSZ + repeat
+ fnbuf( over DIR_Name []= not while ( a ) DIRENTRYSZ + repeat
( success ) else ( not found ) abort" file not found" then ( a ) ;
+\ Search in directory that is currently loaded in dirbuf.
+\ Return address of directory entry, abort if not found.
+: findindir ( fname -- direntry ) _tofnbuf _findindir ;
+
\ Make the current dir the root
: readroot FirstRootDirSecNum RootDirSectors dirbuf( readsectors ;
@@ 85,6 91,18 @@ create fnbuf FNAMESZ allot
ClusterSize + swap nextcluster swap repeat ( cluster buf )
2drop ;
+
+: findpath ( path -- direntry )
+ A>r fnbufclr fnbuf( >A c@+ >r readroot begin ( a )
+ c@+ dup emit case
+ '.' of = fnbuf( 8 + >A endof
+ '/' of = _findindir readdir fnbufclr fnbuf( >A endof
+ r@ upcase Ac!+ A> )fnbuf = if abort" filename too long!" then
+ endcase
+ next drop
+ \ at the point, the correct subdir is read and the final filename is in fnbuf(
+ _findindir r>A ;
+
\ File cursor
\ 2b first cluster 0=free cursor
\ 2b current cluster in buf
M fs/tests/fs/boot.fs => fs/tests/fs/boot.fs +1 -2
@@ 10,8 10,7 @@ testbegin
\ Tests for fs/boot
readFAT
readroot
-S" tests" findindir readdir
-S" fattest" findindir ( dirent )
+S" tests/fattest" findpath ( dirent )
openfile ( fcursor ) dup fat16getc 'T' #eq
dup $ff readN ( fcursor )
dup fat16getc 'f' #eq dup fat16getc 'o' #eq dup fat16getc 'o' #eq