commit 57ffa38c4a976cdcb29848c27f59d0842843ec4c
parent 693a08ac9610a5e34e03592de960cba425596111
Author: Virgil Dupras <hsoft@hardcoded.net>
Date: Sun, 14 May 2023 07:38:14 -0400
fs/fat: consolidate
Diffstat:
2 files changed, 33 insertions(+), 26 deletions(-)
diff --git a/fs/fs/fat.fs b/fs/fs/fat.fs
@@ -113,12 +113,13 @@ $e5 const DIRFREE
r> findfreedirentry dup DirEntry SZ 0 fill ( direntry )
fnbuf( over DirEntry NAMESZ move ( direntry ) ;
-: fatnewfile ( dirid name self -- id ) >r
+: _newfile ( dirid name self -- id ) >r
r@ _newentry ( dirent ) r@ writecursector r> :getid ;
+current ' :newfile realias
: _makedir ( dirent -- dirent ) $10 over to DirEntry attr ;
-: fatnewdir ( dirid name self -- id )
+: _newdir ( dirid name self -- id )
r! allocatecluster0 >r ( dirid name ) \ V1=self V2=cluster
V1 _newentry ( dirent ) _makedir ( dirent )
V2 over to DirEntry cluster V1 writecursector ( dirent )
@@ -130,6 +131,7 @@ $e5 const DIRFREE
dup DirEntry NAMESZ SPC fill '.' over c!+ '.' swap c! ( id buf )
_makedir ( id buf ) V3 swap to DirEntry cluster
2rdrop r> writecursector ( id ) ;
+current ' :newdir realias
\ write multiple sectors from buf
: writesectors ( sec u buf self -- ) >r \ V1=self
@@ -142,11 +144,13 @@ $e5 const DIRFREE
swap r@ :FirstSectorOfCluster ( dst sec )
swap r@ secpercluster swap r> writesectors ;
-: fatinfo ( id self -- info ) FATInfo :read ;
+: _info ( id self -- info ) FATInfo :read ;
+current ' :info realias
\ TODO: deallocate the chain before clearing the entry
-: fatremove ( id self -- )
+: _remove ( id self -- )
tuck :getdirentry ( dirent ) DIRFREE swap c! writecursector ;
+current ' :remove realias
\ Read next sector if a sequential read is available, else return false.
: :nextsector? ( self -- f )
@@ -159,15 +163,13 @@ $e5 const DIRFREE
dup DirEntry :lastentry? if drop 0 else
dup DirEntry :iterable? not if V1 _next then then ( entry ) rdrop ;
-: fatiter ( dirid previd self -- id-or-0 ) >r >r ( dirid ) \ V1=self V2=previd
+: _iter ( dirid previd self -- id-or-0 ) >r >r ( dirid ) \ V1=self V2=previd
V1 :getdirentry V1 :readdir V1 :dirwin :buf( DirEntry SZ - V2 if begin ( entry )
V1 _next dup while dup V1 :getid V2 <> while repeat then then ( entry-or-0 )
dup if V1 _next dup if V1 :getid then then 2rdrop ;
+current ' :iter realias
-: :patchlo ( fs -- ) >r \ V1=fs
- ['] fatinfo r@ 12 + ! ['] fatiter r@ 20 + !
- ['] fatnewfile r@ 24 + ! ['] fatnewdir r@ 28 + ! ['] fatremove r@ 32 + !
- 1 r> to flags ;
+: :patchlo ( fs -- ) 1 swap to flags ;
: :mountvolume ( drv -- fs ) FAT :mountvolume dup :patchlo ;
create _FATTemplate
@@ -232,14 +234,14 @@ struct+[ FATFile
: _writebuf ( buf n self -- n )
dup :free? if 2drop drop 0 exit then ( buf n self )
- dup >r pos over + r@ _grow ( src n )
+ r! pos over + r@ _grow ( src n )
\ TODO: this seek below doesn't seem right. The buffer should be at all times
\ positioned properly w.r.t. pos.
r@ pos r@ :seek
r@ flags 2 or ( dirty ) r@ to flags
r@ :)buf r@ :ptr - ( src n nmax )
min ( src n ) r@ :ptr swap ( src dst n )
- dup >r move r> ( n ) r@ pos over + r> :seek ;
+ r! move r> ( n ) r@ pos over + r> :seek ;
current ' :writebuf realias
\ TODO: deallocate truncated FATs if appropriate
diff --git a/fs/fs/fatlo.fs b/fs/fs/fatlo.fs
@@ -188,6 +188,10 @@ extends File struct[ FATFile
rot min ( a n ) dup r> to+ pos ( a n ) ;
: :close ( self -- ) dup :flush :release ;
+ : :open ( direntry self -- )
+ r! :hold dup V1 :fat :getid ( dirent entryoff ) \ V1=self
+ r@ to entryoff DirEntry filesize r@ to size ( )
+ 0 to r@ pos -1 to r> clusteridx ;
: :new ( fat -- hdl )
0 align4 dup to' FAT lastcursor lladd ( fat newll ) drop here >r
@@ -196,28 +200,29 @@ extends File struct[ FATFile
['] :seek , ['] :truncate , ( fat ) , 0 ( flags ) , 0 ( cluster ) ,
-1 ( clusteridx ) , 0 ( entryoff ) ,
here r@ to bufptr r@ bufsz allot r> ;
-
- : :findfreecursor ( fat -- hdl )
- dup FAT lastcursor begin ( fat ll )
- ?dup while dup CELLSZ + :free? not while llnext repeat
- nip CELLSZ + else :new then
- 0 over to pos -1 over to clusteridx ;
]struct
struct+[ FAT
- \ This is the "low" part. Complete open is finalized in fs/fat
- : :fatopen ( id self -- hdl ) >r \ V1=self
- V1 :getdirentry
- V1 FATFile :findfreecursor ( dirent hdl ) r! FATFile :hold \ V2=hdl
- \ write the rest
- dup V1 :getid ( dirent entryoff )
- r@ to FATFile entryoff DirEntry filesize r@ to FATFile size ( ) r> rdrop ;
+ : :findfreecursor ( self -- hdl )
+ dup lastcursor begin ( fat ll )
+ ?dup while dup CELLSZ + FATFile :free? not while llnext repeat
+ nip CELLSZ + else FATFile :new then ;
+
+ : :open ( id self -- hdl )
+ tuck :getdirentry swap :findfreecursor ( dirent hdl )
+ tuck FATFile :open ;
+
+ alias abort :info
+ alias abort :iter
+ alias abort :newfile
+ alias abort :newdir
+ alias abort :remove
: :mountvolume ( drv -- fs )
dup SectorWindow :new over SectorWindow :new rot
here >r ( fatwin dirwin rot ) \ V1=fs
- dup , 0 ( flags ) , ['] :child , ['] abort , ['] :fatopen ,
- ['] abort dup , dup , dup , ,
+ dup , 0 ( flags ) , ['] :child , ['] :info , ['] :open ,
+ ['] :iter , ['] :newfile , ['] :newdir , ['] :remove ,
0 ( bufcluster ) , 0 ( lastcursor ) , rot ( fatwin ) , swap ( dirwin ) ,
\ At this point, "here" points to the FAT-header-to-be. Read the first sector
\ directly in "here": we'll have the header right here!