duskos

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

commit 2ccd6bf24511e13887e3fd70a6811ae65c09c126
parent 79f180c3e50925f3cf8dcb2c335ca01e7622c0a9
Author: Virgil Dupras <hsoft@hardcoded.net>
Date:   Sat, 20 Aug 2022 07:18:08 -0400

drv/pc/ata: implement ata!

Also, add FAT :remove.

Diffstat:
Mfs/drv/pc/ata.fs | 7+++++--
Mfs/fs/fat.fs | 17++++++++++++-----
Mfs/fs/fatlo.fs | 6++++--
Mfs/tests/sys/file.fs | 8++------
4 files changed, 23 insertions(+), 15 deletions(-)

diff --git a/fs/drv/pc/ata.fs b/fs/drv/pc/ata.fs @@ -44,9 +44,12 @@ $ec const IDENTIFY : ata@ ( sec dst drv -- ) drop swap _locate $20 ( read sectors ) _cmd pc! _wait ( dst ) - A>r ( dst ) >A $100 >r begin _data pw@ A> w! A+ A+ next r>A ; + A>r >A $100 >r begin _data pw@ A> w! A+ A+ next r>A ; -: ata! abort" ATA driver doesn't support writing" ; +: ata! ( sec src drv -- ) + drop swap _locate $30 ( write sectors ) _cmd pc! _wait ( src ) + A>r >A $100 >r begin A> w@ _data pw! A+ A+ next r>A + $e7 ( flush cache ) _cmd pc! _wait ; : .ata ( -- ) atabus . ':' emit atadrive . spc> ataidentify .x1 ; : .ataall ( -- ) diff --git a/fs/fs/fat.fs b/fs/fs/fat.fs @@ -18,7 +18,6 @@ \ File and directory IDs in FAT are the offset, on disk, of their corresponding \ DirEntry. -\ TODO: in my big FAT refactoring, I broke this section. Fix it. ?f<< /fs/fatlo.fs ?f<< /lib/str.fs @@ -60,8 +59,8 @@ $ffff const EOC r@ FATLO :)buf 1+ c@ r@ FATLO :buf( c! r@ FATLO bufsec 1+ r@ FATLO :drv :sec! then rdrop ; : FAT16! ( entry cluster self -- ) FATLO :FAT16' w! ; -: FAT! ( entry cluster self -- ) - dup FATLO :FAT12? if dup FAT12! else dup FAT16! then writecursector ; +: FAT! ( entry cluster self -- ) >r + r@ FATLO :FAT12? if r@ FAT12! else r@ FAT16! then r> writecursector ; : zerocluster ( cluster self -- ) dup FATLO :buf( over FATLO secsz 0 fill ( cluster self ) @@ -73,6 +72,9 @@ $ffff const EOC : findfreecluster ( self -- cluster ) 1 begin ( self cl ) 1+ 2dup swap FATLO :FAT@ not until ( self cl ) nip ; +: allocatecluster ( self -- cluster ) + dup findfreecluster ( self cl ) tuck EOC swap rot FAT! ( cl ) ; + \ Get next FAT entry and if it's EOC, allocate a new one : FAT@+ ( cluster self -- entry ) >r dup r@ FATLO :FAT@ ( cl ncl ) dup r@ FATLO :EOC? if @@ -132,7 +134,7 @@ $ffff const EOC 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 self fat findfreecluster then ( cluster0 ) + ?dup not if self fat allocatecluster then ( cluster0 ) self :dirent 2dup DirEntry cluster! ( custer0 dirent ) self size swap to DirEntry filesize self fat writecursector ( cluster0 ) self size self fat FATLO :ClusterSize / ?dup if @@ -152,8 +154,13 @@ $ffff const EOC : fatinfo ( id self -- info ) FATInfo :read ; +\ TODO: deallocate the chain before clearing the entry +: fatremove ( id self -- ) >r + r@ FATLO :getdirentry ( dirent ) DirEntry SZ 0 fill r> writecursector ; + : _patchFS ( fs -- ) - ['] fatinfo over 8 + ! ['] fatopen over 12 + ! ['] fatnewfile swap 16 + ! ; + ['] fatinfo over 8 + ! ['] fatopen over 12 + ! ['] fatnewfile over 16 + ! + ['] fatremove swap 28 + ! ; : :mountvolume ( drv -- fs ) FATLO :mountvolume dup _patchFS ; bootfs 8 + @ ' abort = [if] bootfs _patchFS [then] diff --git a/fs/fs/fatlo.fs b/fs/fs/fatlo.fs @@ -80,10 +80,12 @@ r@ reservedseccnt + r> :RootDirSectors + - ; : :CountOfClusters dup :DataSec swap secpercluster / ; : :FAT12? :CountOfClusters 4085 < ; +\ Read specified sector into buffer if it's not already there. \ "cnt" is the number of sectors ahead of "sec" that are available for a -\ seqential read. +\ sequential read. : :readsector ( sec cnt self -- ) >r -to r@ bufseccnt dup to r@ bufsec ( sec ) +to r@ bufseccnt dup r@ bufsec = if rdrop drop exit then +dup to r@ bufsec ( sec ) r@ :buf( r> Filesystem :drv :sec@ ; : :FAT12' ( cluster self -- 'entry ) >r diff --git a/fs/tests/sys/file.fs b/fs/tests/sys/file.fs @@ -26,12 +26,8 @@ myinfo FSInfo dir? not # S" /lib" curpath :find Path :info value myinfo myinfo FSInfo dir? # \ test write, copy remove -S" atabus" sysdict find [if] - \ The ATA driver doesn't support writing yet and it breaks tests below. - \ TODO: add writing support to ATA drivers - testend \s [then] -S" foo.fs" curpath :newfile dup # dup Path id .x -( path ) Path :open value myfile myfile .x +S" foo.fs" curpath :newfile dup # +( path ) Path :open value myfile S" 42" c@+ myfile File :write myfile File :close S" /foo.fs" curpath :find# Path :fload 42 #eq \ let's copy that file