duskos

dusk os fork
git clone git://git.alexwennerberg.com/duskos
Log | Files | Refs | README | LICENSE

commit 50af07158cfa2a6c2c768f4d290847821a4e45c5
parent 3eaeea42fcd2fcb7655c1aac70bdd73d2ca45f6c
Author: Virgil Dupras <hsoft@hardcoded.net>
Date:   Fri, 12 May 2023 08:02:29 -0400

fs/fat: consolidate

Diffstat:
Mfs/doc/lib/drive.txt | 3+++
Mfs/fs/fat.fs | 64+++++++++++++++++++++++++++++-----------------------------------
Mfs/fs/fatlo.fs | 35+++++++++++++++++------------------
Mfs/lib/drivelo.fs | 1+
Mfs/xcomp/i386/pc/init.fs | 1+
5 files changed, 51 insertions(+), 53 deletions(-)

diff --git a/fs/doc/lib/drive.txt b/fs/doc/lib/drive.txt @@ -62,6 +62,9 @@ Words: Move window to "fsec" with "cnt" sectors. This doesn't change or flush the current buffer. +:fulldrv ( self -- ) + Move the window so that it spans the whole drive. + :load ( sec self -- ) Load sector "sec" in the buffer. Aborts if outside the window. diff --git a/fs/fs/fat.fs b/fs/fs/fat.fs @@ -100,8 +100,8 @@ $e5 const DIRFREE else nip then rdrop ; \ try to find in current buffer -: _findinsec ( self -- a-or-0 ) >r - r@ :dirwin :buf( begin ( a ) +: _findinsec ( self -- a-or-0 ) + r! :dirwin :buf( begin ( a ) \ V1=self dup c@ dup DIRFREE = swap not or if ( free! ) rdrop exit then DirEntry SZ + dup r@ :dirwin :)buf >= until rdrop drop 0 ; @@ -126,26 +126,24 @@ $e5 const DIRFREE : _makedir ( dirent -- dirent ) $10 over to DirEntry attr ; -0 value _self 0 value _cluster 0 value _parentcl -: fatnewdir ( dirid name self -- id ) to _self - _self allocatecluster0 to _cluster ( dirid name ) - _self _newentry ( dirent ) _makedir ( dirent ) - _cluster over to DirEntry cluster _self writecursector ( dirent ) - _self :getid ( id ) _self bufcluster to _parentcl +: fatnewdir ( 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 ) + V1 :getid ( id ) V1 bufcluster >r \ V3=parentcl \ Cluster allocated, now let's initialize it with "." and ".." - _cluster _self :FirstSectorOfCluster 1 _self :readsector - _self :dirwin :buf( dup DirEntry NAMESZ SPC fill '.' over c! _makedir ( id buf ) - _cluster over to DirEntry cluster ( id buf ) DirEntry SZ + + V2 V1 :FirstSectorOfCluster 1 V1 :readsector + V1 :dirwin :buf( dup DirEntry NAMESZ SPC fill '.' over c! _makedir ( id buf ) + V2 over to DirEntry cluster ( id buf ) DirEntry SZ + dup DirEntry NAMESZ SPC fill '.' over c!+ '.' swap c! ( id buf ) - _makedir ( id buf ) _parentcl swap to DirEntry cluster - _self writecursector ( id ) ; + _makedir ( id buf ) V3 swap to DirEntry cluster + 2rdrop r> writecursector ( id ) ; -0 value self \ write multiple sectors from buf -: writesectors ( sec u buf self -- ) to self - rot >r swap for ( buf ) \ V1=sec - V1 over self :drv :sec! to1+ V1 self :drv secsz + next ( buf ) - drop rdrop ; +: writesectors ( sec u buf self -- ) >r \ V1=self + rot >r swap for ( buf ) \ V2=sec + V2 over V1 :drv :sec! to1+ V2 V1 :drv secsz + next ( buf ) + drop 2rdrop ; : writecluster ( cluster src self -- ) >r over 2 - $fff6 > if abort" cluster out of range!" then @@ -196,8 +194,8 @@ $e5 const DIRFREE : fatinfo ( id self -- info ) FATInfo :read ; \ TODO: deallocate the chain before clearing the entry -: fatremove ( id self -- ) >r - r@ :getdirentry ( dirent ) DIRFREE swap c! r> writecursector ; +: fatremove ( id self -- ) + tuck :getdirentry ( dirent ) DIRFREE swap c! writecursector ; \ This approach to iteration is inefficient, but simple. I keep it as-is for now : _next ( entry self -- entry-or-0 ) >r \ V1=self @@ -211,7 +209,7 @@ $e5 const DIRFREE 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 ; -: _patchFS ( fs -- ) >r \ V1=fs +: :patchlo ( fs -- ) >r \ V1=fs ['] fatinfo r@ 12 + ! ['] fatiter r@ 20 + ! ['] fatnewfile r@ 24 + ! ['] fatnewdir r@ 28 + ! ['] fatremove r@ 32 + ! ['] fatwritebuf FATFile EmptyCursor 8 + ! @@ -219,9 +217,7 @@ $e5 const DIRFREE ['] fatflush FATFile EmptyCursor 12 + ! ['] fattruncate FATFile EmptyCursor 40 + ! 1 r> to flags ; -: :mountvolume ( drv -- fs ) FAT :mountvolume dup _patchFS ; - -bootfs 12 + @ ' abort = [if] bootfs _patchFS [then] +: :mountvolume ( drv -- fs ) FAT :mountvolume dup :patchlo ; create _FATTemplate ( jmp ) $eb c, $3c c, $90 c, ( OEMName ) ," DuskFAT " ( BytsPerSec ) 0 c, 0 c, @@ -232,14 +228,12 @@ create _FATTemplate ( BootSig ) $29 c, ( VolID ) 0 , ( VolLabel ) ," NONAME " ( FilSysType ) ," FAT12 " -0 value fatseccnt -0 value secsz : newFAT12 ( drv -- ) - fatopts clustercnt 341 / 1+ to fatseccnt - ( drv ) dup Drive secsz to secsz ( drv ) - here secsz 0 fill + fatopts clustercnt 341 / 1+ >r \ V1=fatseccnt + ( drv ) dup Drive secsz >r ( drv ) \ V2=secsz + here V2 0 fill _FATTemplate here $3e move ( drv ) - secsz here $0b + w! + V2 here $0b + w! fatopts secpertrk here $18 + w! fatopts numheads here $1a + w! fatopts drvnum here $24 + c! @@ -247,16 +241,16 @@ create _FATTemplate fatopts rsvdsec here $0e + w! fatopts rootentsec DirEntry SZ * here $11 + w! fatopts clustercnt fatopts secperclus * fatopts rootentsec + - fatopts rsvdsec + fatseccnt + dup here $13 + w! + fatopts rsvdsec + V1 + dup here $13 + w! ." TotSec " . nl> - fatseccnt here $16 + w! + V1 here $16 + w! $aa55 here $1fe + w! ( drv ) dup 0 here rot Drive :sec! ( drv ) \ header done. Now, zero-out all FAT and root dir entries - here secsz 0 fill - fatopts rootentsec fatseccnt + 1- fatopts rsvdsec 1+ swap for ( drv sec ) + here V2 0 fill + fatopts rootentsec V1 + 1- fatopts rsvdsec 1+ swap for ( drv sec ) 2dup here rot Drive :sec! next ( drv sec ) drop \ finally, initialize the first FAT sector $fffff0 here ! - ( drv ) fatopts rsvdsec here rot Drive :sec! ; + ( drv ) fatopts rsvdsec here rot Drive :sec! 2rdrop ; ]struct diff --git a/fs/fs/fatlo.fs b/fs/fs/fatlo.fs @@ -54,15 +54,16 @@ sfield bufcluster \ cluster number of current buf sfield lastcursor sfield fatwin \ FAT secwin sfield dirwin \ DirEntry secwin - -SZ &+ :hdr( -SZ $0b + &+w@ secsz \ in bytes -SZ $0d + &+c@ secpercluster -SZ $0e + &+w@ reservedseccnt \ number of sectors reserved before FAT starts -SZ $10 + &+c@ FATcnt \ >1 means backup FATs -SZ $11 + &+w@ rootentcnt \ count of 32b entries -SZ $13 + &+w@ seccnt -SZ $16 + &+w@ FATsz \ in sectors +\ FAT header now +$0b sallot +sfieldw secsz \ in bytes +sfieldb secpercluster +sfieldw reservedseccnt +sfieldb FATcnt +sfieldw rootentcnt +sfieldw seccnt +1 sallot +sfieldw FATsz \ in sectors $18 const HDRSZ : :fatwin [compile] fatwin [compile] SectorWindow ; immediate : :dirwin [compile] dirwin [compile] SectorWindow ; immediate @@ -77,13 +78,13 @@ $18 const HDRSZ : :ClusterSize bi secpercluster | secsz * ; : :FAT12? :CountOfClusters 4085 < ; +: cl# ( n -- ) not if abort" cluster out of range" then ; : :FirstSectorOfCluster ( n self -- sec ) >r - dup << r@ secsz r@ FATsz * >= if abort" cluster out of range" then - 1- 1- r@ secpercluster * r> :FirstDataSector + ; + dup << r@ secsz r@ FATsz * < cl# + 2 - r@ secpercluster * r> :FirstDataSector + ; : :readsector ( sec cnt self -- ) r! :dirwin :move 0 r> :dirwin :seek 2drop ; -: cl# ( n -- ) not if abort" cluster out of range" then ; : :FAT12@ ( cluster self -- entry ) >r dup dup >> + ( cl offset ) dup r@ :fatwin :seek cl# c@ ( cl off lsb ) swap 1+ r> :fatwin :seek cl# c@ 8 lshift or ( cl entry ) @@ -121,9 +122,7 @@ $18 const HDRSZ \ Get DirEntry address from FS ID "id" : :getdirentry ( id self -- direntry ) - over if - r! secsz /mod ( offset sec ) 1 r@ :readsector ( off ) r> :dirwin :buf( + - else 2drop rootdirentry( then ; + over if dup :dirwin :fulldrv :dirwin :seek cl# else 2drop rootdirentry( then ; \ Get ID for direntry : :getid ( direntry self -- id ) @@ -185,7 +184,7 @@ extends File struct[ FATFile r@ :ptr r@ :)buf over - ( n a nmax ) rot min ( a n ) dup r> to+ pos ( a n ) ; - : :fatclose ( self -- ) dup IO :flush :release ; + : :fatclose ( self -- ) dup :flush :release ; \ these words below are "static" words not called with "self" as an argument, \ but "fat". @@ -223,8 +222,8 @@ struct+[ FAT : :mountvolume ( drv -- fs ) dup SectorWindow :new over SectorWindow :new rot here >r ( fatwin dirwin rot ) \ V1=fs - dup , 0 ( flags ) , ['] :child , ['] abort , ['] :fatopen , ['] abort , - ['] abort , ['] abort , ['] abort , + dup , 0 ( flags ) , ['] :child , ['] abort , ['] :fatopen , + ['] abort dup , dup , dup , , 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! diff --git a/fs/lib/drivelo.fs b/fs/lib/drivelo.fs @@ -15,6 +15,7 @@ struct[ SectorWindow 2dup tuck fsec - swap cnt >= if abort" secwin oor" then ( sec self ) dup :flush 2dup to sec tuck :buf( rot :drv :sec@ else 2drop then ; : :move ( fsec cnt self -- ) swap 1 max over to cnt to fsec ; + : :fulldrv ( self -- ) 0 over :drv seccnt rot :move ; : :seek ( pos self -- a? n-or-0 ) r! :drv secsz /mod ( off relsec ) \ V1=self dup r@ cnt < if ( off relsec ) diff --git a/fs/xcomp/i386/pc/init.fs b/fs/xcomp/i386/pc/init.fs @@ -31,6 +31,7 @@ f<< /drv/pc/pic.fs pic$ idt$ f<< /fs/fat.fs +bootfs FAT :patchlo f<< /sys/kbd.fs f<< /sys/mouse.fs