From 57ffa38c4a976cdcb29848c27f59d0842843ec4c Mon Sep 17 00:00:00 2001 From: Virgil Dupras Date: Sun, 14 May 2023 07:38:14 -0400 Subject: [PATCH] fs/fat: consolidate --- fs/fs/fat.fs | 24 +++++++++++++----------- fs/fs/fatlo.fs | 35 ++++++++++++++++++++--------------- 2 files changed, 33 insertions(+), 26 deletions(-) diff --git a/fs/fs/fat.fs b/fs/fs/fat.fs index 3afc4ded..b91cbc58 100644 --- 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 index b4c6439c..303c0998 100644 --- 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! -- 2.45.2