duskos

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

commit ea87055dff072d7d3bab004ad7570eba6642c058
parent 37a2f72e78defdd4e983df22e754822c2580e2a5
Author: Virgil Dupras <hsoft@hardcoded.net>
Date:   Tue,  9 May 2023 17:56:37 -0400

fs/fatlo: consolidate

Diffstat:
Mfs/fs/fatlo.fs | 77+++++++++++++++++++++++++++++++++--------------------------------------------
1 file changed, 33 insertions(+), 44 deletions(-)

diff --git a/fs/fs/fatlo.fs b/fs/fs/fatlo.fs @@ -42,9 +42,8 @@ here const )fnbuf c@+ ( a len ) fnbuf( swap move exit then c@+ swap >r fnbuf( swap for ( dst ) \ V1=a 8b to@+ V1 dup '.' = if - 2drop fnbuf( DirEntry EXTIDX + else - upcase swap c!+ then ( dst+1 ) - dup )fnbuf = if 1 to i then next drop rdrop ; + 2drop fnbuf( DirEntry EXTIDX + else upcase swap c!+ then ( dst+1 ) + dup )fnbuf = if break then next then drop rdrop ; \ The FAT struct in this unit is split in 2. The first part contains code needed \ by FATFile, and the second part contains the rest of the code for FAT. This @@ -62,28 +61,26 @@ 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 bytes +SZ $16 + &+w@ FATsz \ in sectors $18 const HDRSZ \ buffer for reading FAT tables and dir entries. one sector in length. SZ HDRSZ + &+ :buf( : :)buf bi :buf( | secsz + ; -: :RootDirSectors ( self -- n ) -bi rootentcnt 32 * | secsz /mod ( r q ) swap bool + ; -: :FirstDataSector ( self -- n ) >r -r@ reservedseccnt r@ FATcnt r@ FATsz * + r> :RootDirSectors + ; -: :FirstSectorOfCluster ( n self -- sec ) >r -dup << r@ secsz r@ FATsz * >= if abort" cluster out of range" then -1- 1- r@ secpercluster * r> :FirstDataSector + ; -: :FirstRootDirSecNum ( self -- n ) >r -r@ reservedseccnt r@ FATcnt r> FATsz * + ; -: :ClusterSize bi secpercluster | secsz * ; -: :DataSec ( self -- n ) >r -r@ seccnt r@ FATsz r@ FATcnt * -r@ reservedseccnt + r> :RootDirSectors + - ; +\ These words have the same sig: fat -- n +: :RootDirSectors bi rootentcnt 32 * | secsz /mod ( r q ) swap bool + ; +: :totsec bi FATcnt | FATsz * ; +: :FirstRootDirSecNum bi reservedseccnt | :totsec + ; +: :FirstDataSector bi :FirstRootDirSecNum | :RootDirSectors + ; +: :DataSec bi seccnt | :FirstDataSector - ; : :CountOfClusters bi :DataSec | secpercluster / ; +: :ClusterSize bi secpercluster | secsz * ; : :FAT12? :CountOfClusters 4085 < ; +: :FirstSectorOfCluster ( n self -- sec ) >r + dup << r@ secsz r@ FATsz * >= if abort" cluster out of range" then + 1- 1- r@ secpercluster * r> :FirstDataSector + ; + \ Read specified sector into buffer if it's not already there. \ "cnt" is the total number of sectors ahead of "sec" that are available for a \ sequential read, *including this sector*. For example, "2" means that we're @@ -92,36 +89,30 @@ r@ reservedseccnt + r> :RootDirSectors + - ; 1 max 1- to r@ bufseccnt dup r@ bufsec = if rdrop drop else dup to r@ bufsec ( sec ) r@ :buf( r> :drv :sec@ then ; +: :sec+( ( off sec self -- a ) tuck 1 swap :readsector :buf( + ; : :FAT12' ( cluster self -- 'entry ) >r - dup >> + ( cl offset ) r@ secsz /mod ( cl secoff sec ) - r@ reservedseccnt + + dup >> + ( offset ) r@ secsz /mod r@ reservedseccnt + ( secoff sec ) over 1+ r@ secsz = if \ end-of-sector cross-over! - dup 1+ 0 r@ :readsector r@ :buf( c@ r@ :)buf c! then - 0 r@ :readsector ( cl secoff ) - r> :buf( + ; + dup 1+ 1 r@ :readsector r@ :buf( c@ r@ :)buf c! then + r> :sec+( ; : :FAT12@ ( cluster self -- entry ) over swap :FAT12' w@ swap 1 and if 4 rshift else $fff and then ; : :FAT16' ( cluster self -- 'entry ) >r - << ( offset ) r@ secsz /mod ( secoff sec ) - r@ reservedseccnt + 0 r@ :readsector ( secoff ) - r> :buf( + ; + << ( offset ) r@ secsz /mod r@ reservedseccnt + ( secoff sec ) r> :sec+( ; : :FAT16@ ( cluster self -- entry ) :FAT16' w@ ; : :FAT@ ( cluster self -- entry ) - over 2 < if 2drop EOC else - dup :FAT12? if :FAT12@ else :FAT16@ then then ; + over 2 < if 2drop EOC else dup :FAT12? if :FAT12@ else :FAT16@ then then ; -: :EOC? ( cluster self -- f ) - :FAT12? if $ff8 else $fff8 then tuck and = ; +: :EOC? ( cluster self -- f ) :FAT12? if $ff8 else $fff8 then tuck and = ; \ Read next sector if a sequential read is available, else return false. -: :nextsector? ( self -- f ) >r - r@ bufseccnt if \ still on a sector streak - r@ bufsec 1+ r@ bufseccnt 1- r> :readsector 1 +: :nextsector? ( self -- f ) + dup bufseccnt if \ still on a sector streak + bi+ bufsec 1+ | bufseccnt 1- rot :readsector 1 else \ out of sector, try next cluster - r@ bufcluster r@ :FAT@ dup r@ :EOC? if rdrop drop 0 else - dup to r@ bufcluster r@ :FirstSectorOfCluster - r@ secpercluster r> :readsector 1 then - then ; + bi+ bufcluster | :FAT@ swap 2dup :EOC? if 2drop 0 else ( cl self ) + 2dup to bufcluster tuck :FirstSectorOfCluster ( self sec ) + over secpercluster rot :readsector 1 then then ; \ Find current fnbuf( in current dir buffer and return a dir entry. : :findindir ( self -- direntry-or-0 ) >r @@ -143,12 +134,11 @@ r@ reservedseccnt + r> :RootDirSectors + - ; \ Get DirEntry address from FS ID "id" : :getdirentry ( id self -- direntry ) over if - dup >r secsz /mod ( offset sec ) 1 r@ :readsector ( off ) r> :buf( + + r! secsz /mod ( offset sec ) 1 r@ :readsector ( off ) r> :buf( + else 2drop rootdirentry( then ; \ Get ID for direntry -: :getid ( direntry self -- id ) - dup >r :buf( - r@ bufsec r> secsz * + ; +: :getid ( direntry self -- id ) r! :buf( - r@ bufsec r> secsz * + ; \ read multiple sectors in buf : :readsectors ( sec u buf self -- ) >r \ V1=self @@ -222,8 +212,8 @@ extends File struct[ FATFile 0 align4 dup to' FAT lastcursor lladd ( fat newll ) swap :cursorsize allot ( newll ) CELLSZ + ( hdl ) dup :release ; - : :findfreecursor ( fat -- hdl ) >r \ V1=fat - r@ FAT lastcursor begin ( ll ) + : :findfreecursor ( fat -- hdl ) + r! FAT lastcursor begin ( ll ) \ V1=fat ?dup while dup CELLSZ + :free? not while llnext repeat CELLSZ + else r@ :createcursor then EmptyCursor over SZ move ( hdl ) @@ -236,10 +226,9 @@ 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 >r ( dirent ) r@ FATFile :hold \ V2=hdl + V1 FATFile :findfreecursor ( dirent hdl ) r! FATFile :hold \ V2=hdl \ write the rest - dup V1 :buf( - - V1 bufsec V1 secsz * + ( dirent doffset ) + dup V1 :buf( - V1 bufsec V1 secsz * + ( dirent doffset ) r@ to FATFile entryoff DirEntry filesize r@ to FATFile size ( ) r> rdrop ; : :mountvolume ( drv -- fs )