commit e6c21f63613c8a6bb2d019ff3ed723f7c828c6cf
parent 9e5cc459f60bd4cae3a4e10cdce71c4d9eb99dde
Author: Virgil Dupras <hsoft@hardcoded.net>
Date: Mon, 15 Aug 2022 08:32:40 -0400
fs/fat: FAT write tests are back online
Diffstat:
3 files changed, 36 insertions(+), 42 deletions(-)
diff --git a/fs/fs/fat.fs b/fs/fs/fat.fs
@@ -21,10 +21,11 @@
\ TODO: in my big FAT refactoring, I broke this section. Fix it.
?f<< fs/fatlo.fs
+extends FAT struct[ FATHI
$ffff const EOC
: writecursector ( self -- )
- dup FAT bufsec over FAT :buf( rot ( sec dst drv ) Drive :sec! ;
+ dup FAT bufsec over FAT :buf( rot ( sec dst self ) FAT :drv :sec! ;
: FAT12! ( entry cluster self -- ) >r
dup r@ FAT :FAT@ ( entry cl old ) over r@ FAT :FAT12' ( entry cl old a )
@@ -48,7 +49,7 @@ $ffff const EOC
\ find a free cluster in the FAT
: findfreecluster ( self -- cluster )
- 1 swap begin ( cl self ) 1+ 2dup FAT :FAT@ not until ( cluster self ) drop ;
+ 1 begin ( self cl ) 1+ 2dup swap FAT :FAT@ not until ( self cl ) nip ;
\ Get next FAT entry and if it's EOC, allocate a new one
: FAT@+ ( cluster self -- entry ) >r
@@ -59,7 +60,7 @@ $ffff const EOC
\ try to find in current buffer
: _findinsec ( self -- a-or-0 ) >r
- dup r@ FAT :buf( begin ( a )
+ r@ FAT :buf( begin ( a )
dup c@ dup $e5 = swap not or if ( free! ) rdrop exit then
DirEntry SZ + dup r@ FAT :)buf >= until rdrop drop 0 ;
@@ -101,18 +102,18 @@ $ffff const EOC
\ undirty the cursor
r@ FATFile flags $fffffffd and to r> FATFile flags ;
-0 value self 0 value fat
+0 structbind FATFile self
\ grow fcursor to newsz, if needed
-: fatgrow ( newsz self -- ) to self self FATFile fat to fat
- dup self FATFile size <= if drop exit then ( newsz )
- to self FATFile size self FATFile :cluster0 ( cluster0 )
+: fatgrow ( newsz self -- ) ['] self rebind
+ dup self size <= if drop exit then ( newsz )
+ to self size self :cluster0 ( cluster0 )
\ special case: if :cluster0 is zero, we have an empty file. We need to
\ update its direntry to record the file's first cluster.
- ?dup not if fat findfreecluster then ( cluster0 )
- self FATFile :dirent 2dup DirEntry cluster! ( custer0 dirent )
- self FATFile size swap to DirEntry filesize fat writecursector ( cluster0 )
- self FATFile size fat FAT :ClusterSize / ?dup if
- >r begin ( cluster ) fat FAT@+ next then ( cluster ) drop ;
+ ?dup not if self fat findfreecluster then ( cluster0 )
+ self :dirent 2dup DirEntry cluster! ( custer0 dirent )
+ self size swap to DirEntry filesize self fat writecursector ( cluster0 )
+ self size self fat FAT :ClusterSize / ?dup if
+ >r begin ( cluster ) self fat FAT@+ next then ( cluster ) drop ;
: fatwritebuf ( buf n self -- n )
dup FATFile :free? if 2drop drop 0 exit then ( buf n self )
@@ -124,7 +125,10 @@ $ffff const EOC
dup >r move r> ( n ) ;
: fatopen ( id self -- hdl )
- FAT :open ['] fatwritebuf over 4 + ! ['] fatflush over 8 + ! ;
+ FATFS:open ['] fatwritebuf over 4 + ! ['] fatflush over 8 + ! ;
+
+: :mountVolume ( drv -- fs )
+ mountFATvolume ['] fatopen over 8 + ! ['] fatnewfile over 12 + ! ;
create _FATTemplate
( jmp ) $eb c, $3c c, $90 c, ( OEMName ) ," DuskFAT " ( BytsPerSec ) 0 c, 0 c,
@@ -155,6 +159,12 @@ create _FATTemplate
fatseccnt here $16 + w!
$aa55 here $1fe + w!
( drv ) dup 0 here rot Drive :sec! ( drv )
- \ header done. Now, initial FAT with zeroed entries
- here secsz 0 fill $fffff0 here !
+ \ header done. Now, zero-out all FAT and root dir entries
+ here secsz 0 fill
+ rootentsec fatseccnt + 1- >r rsvdsec 1+ begin ( drv sec )
+ 2dup here rot Drive :sec! next ( drv sec ) drop
+ \ finally, initialize the first FAT sector
+ $fffff0 here !
( drv ) rsvdsec here rot Drive :sec! ;
+]struct
+alias FATHI FAT immediate
diff --git a/fs/tests/fs/fat.fs b/fs/tests/fs/fat.fs
@@ -5,6 +5,16 @@ testbegin
\ Tests for fs/fat
100 const TOTSEC
512 TOTSEC RAMDrive :new value mydrv
-mydrv 16 1 1 TOTSEC 17 - newFAT12
+mydrv 16 1 1 TOTSEC 17 - FAT newFAT12
+mydrv FAT :mountVolume value myfat
+' activefs structbind' @ value oldfs
+myfat ' activefs rebind
+0 S" newfile" activefs :newfile #
+S" /newfile" findpath# ( fsid ) \ found!
+activefs :open ( hdl )
+dup FATFile :cluster0 0 #eq \ no cluster allocated yet
+dup S" 42" c@+ rot File :writebuf 2 #eq ( fc ) File :close
+f<< /newfile 42 #eq
+oldfs ' activefs rebind
testend
diff --git a/fs/tests/fs/fat_.fs b/fs/tests/fs/fat_.fs
@@ -1,26 +0,0 @@
-\ TODO: these tests below have been broken by the recent FAT refactoring. They
-\ will be fixed soon.
-?f<< tests/harness.fs
-testrequires fs/fat.fs
-: fatgetc ( fcursor -- c ) 1 swap fatreadbuf if c@ else -1 ( EOF ) then ;
-testbegin
-\ Tests for fs/fat
-S" tests/fattest" findpath# fatopen ( fcursor )
-dup fatgetc 'T' #eq
-$100 over fatseek
-dup fatgetc 'f' #eq dup fatgetc 'o' #eq dup fatgetc 'o' #eq
-$200 over fatseek
-dup fatgetc 'b' #eq
-$ffd over fatseek
-dup fatgetc 'E' #eq dup fatgetc 'O' #eq dup fatgetc 'F' #eq
-dup fatgetc -1 #eq
-fatclose
-\ can we create a new file?
-0 S" newfile" fatnewfile #
-S" /newfile" findpath# \ found!
-\ let's try writing to it
-fatopen ( fc )
-dup FCUR_cluster0 0 #eq \ no cluster allocated yet
-dup S" 42" c@+ rot fatwritebuf 2 #eq ( fc ) File :close
-f<< /newfile 42 #eq
-testend