commit 311c464ecb3f900c02bef592232fc8bcc55b125e
parent 1f7a1e549f7c55c219c3a22caaf3e7cba30c4a28
Author: Virgil Dupras <hsoft@hardcoded.net>
Date: Thu, 30 Jun 2022 07:43:29 -0400
fs/boot: add directory entries buffer
Allows to search in more than 16 entries
Diffstat:
3 files changed, 24 insertions(+), 15 deletions(-)
diff --git a/fs/fs/boot.fs b/fs/fs/boot.fs
@@ -12,8 +12,8 @@
$18 const BPBSZ \ we only care about a part of the BPB
create bpb BPBSZ allot
+0 drv@ drvbuf( bpb BPBSZ move
-: fat16$ 0 drv@ drvbuf( bpb BPBSZ move ;
: BPB_BytsPerSec bpb $0b + w@ ;
: BPB_SecPerClus bpb $0d + c@ ;
: BPB_RsvdSecCnt bpb $0e + w@ ;
@@ -28,18 +28,28 @@ create bpb BPBSZ allot
: FirstRootDirSecNum BPB_RsvdSecCnt BPB_NumFATs BPB_FATSz16 * + ;
32 const DIRENTRYSZ
-create fnbuf 11 allot
+\ A buffer where dir entries are copied before we search in them. It's big
+\ enough to hold the root dir entries. This means that no directory in the FS
+\ can have more than BPB_RootEntCnt entries.
+create dirbuf( RootDirSectors BPB_BytsPerSec * allot
+here const )dirbuf
+11 const FNAMESZ
+create fnbuf FNAMESZ allot
: upcase ( c -- c ) dup 'a' - 26 < if $df and then ;
\ we assume a 8.3 name. Don't call this with an inadequate name.
: _tofnbuf ( fname -- )
- A>r >A Ac@+ >r fnbuf 11 SPC fill fnbuf begin ( a )
+ 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
next drop r>A ;
-\ Search in directory that is currently loaded in drvbuf.
-\ Return address of directory entry, or 0 if not found.
-\ TODO: support more than 1 sector dir entry
-: findindir ( fname -- ) _tofnbuf
- 16 >r drvbuf( begin ( a )
- fnbuf over 11 []= if r~ exit then DIRENTRYSZ + next
- abort" file not found" ;
+\ Search in directory that is currently loaded in dirbuf.
+\ Return address of directory entry, abort if not found.
+: findindir ( fname -- direntry ) _tofnbuf
+ dirbuf( begin ( a )
+ dup )dirbuf < while ( a )
+ fnbuf over FNAMESZ []= not while ( a ) DIRENTRYSZ + repeat
+ ( success ) else ( not found ) abort" file not found" then ( a ) ;
+
+\ Make the current dir the root
+: readroot A>r RootDirSectors >r FirstRootDirSecNum >A dirbuf( begin ( a )
+ A> over (drv@) A+ drvblksz + next ( a ) drop r>A ;
diff --git a/fs/sys/drive.fs b/fs/sys/drive.fs
@@ -29,8 +29,8 @@ alias abort (drv@)
( blkno buf -- )
alias abort (drv!)
-: drv@ ( blkno -- ) dup to drvblksz drvbuf( (drv@) ;
-: ?drv@ ( blkno -- ) dup drvblksz = if drop else drv@ then ;
+: drv@ ( blkno -- ) dup to drvcurblk drvbuf( (drv@) ;
+: ?drv@ ( blkno -- ) dup drvcurblk = if drop else drv@ then ;
\ Ensure that the block containing offset "off" (in bytes) is loaded and that
\ there's at least u bytes following that offset that is present in the buffer.
diff --git a/fs/tests/fs/boot.fs b/fs/tests/fs/boot.fs
@@ -7,8 +7,7 @@
?f<< fs/boot.fs
testbegin
\ Tests for fs/boot
-fat16$
-FirstRootDirSecNum drv@
+readroot
S" init.fs" findindir
-11 []>str S" INIT FS " #s=
+FNAMESZ []>str S" INIT FS " #s=
testend