duskos

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

commit c020600131c8400cac2bb523cde2025817111586
parent 1024013264e4d4ce43099f4e2a4de4670c8191fb
Author: Virgil Dupras <hsoft@hardcoded.net>
Date:   Fri,  1 Jul 2022 09:14:21 -0400

fs/boot: support files with multiple clusters

Diffstat:
Afs/fattest | 0
Mfs/fs/boot.fs | 20+++++++++++++++-----
Mfs/tests/fs/boot.fs | 12++++++++++--
3 files changed, 25 insertions(+), 7 deletions(-)

diff --git a/fs/fattest b/fs/fattest Binary files differ. diff --git a/fs/fs/boot.fs b/fs/fs/boot.fs @@ -3,7 +3,7 @@ \ This is a subset of a FAT16 implementation. It is designed to be embedded \ right after "boot.fs" and provide the means to continue bootstrapping on. -\ Its goal is to provide fopen and fread, nothing more. The rest of the FAT16 +\ Its goal is to provide fopen and fgetc, nothing more. The rest of the FAT16 \ implementation is in fs/fat16. \ This unit has access to a very small set of words, that it, words implemented @@ -67,8 +67,10 @@ create fnbuf FNAMESZ allot \ Make the current dir the root : readroot FirstRootDirSecNum RootDirSectors dirbuf( readsectors ; +: endofclusters? ( cluster -- f ) $ffff = ; + \ get cluster following this one in the FAT -: nextcluster ( cluster -- nextcluster ) abort" TODO" ; +: nextcluster ( cluster -- nextcluster ) << FAT16( + w@ ; \ File cursor \ 2b first cluster @@ -80,9 +82,11 @@ create fnbuf FNAMESZ allot : FCursorSize ClusterSize 12 + ; : FCUR_cluster0 ( fcur -- n ) w@ ; : FCUR_cluster ( fcur -- n ) 2 + w@ ; +: FCUR_cluster! ( n fcur -- ) 2 + w! ; : FCUR_pos ( fcur -- n ) 4 + @ ; \ return pos and post-inc it : FCUR_pos+ ( fcur -- n ) 4 + dup @ 1 rot +! ; +: FCUR_size ( fcur -- n ) 8 + @ ; : FCUR_buf( ( fcur -- a ) 12 + ; create fcursors( FCursorSize FCURSORCNT * allot @@ -90,17 +94,23 @@ here value )fcursor fcursors( value nextfcursor : readcluster ( cluster dst -- ) + over << BPB_BytsPerSec BPB_FATSz16 * >= if abort" cluster out of range" then swap FirstSectorOfCluster ( dst sec ) swap BPB_SecPerClus swap readsectors ; : fat16open ( direntry -- fcursor ) nextfcursor )fcursor = if abort" out of file cursors!" then dup DIR_Cluster ( dirent cluster ) dup nextfcursor FCUR_buf( readcluster - ( dirent cluster ) dup nextfcursor w! nextfcursor 2 + w! ( dirent ) + ( dirent cluster ) dup nextfcursor w! nextfcursor FCUR_cluster! ( dirent ) 0 nextfcursor 4 + ! DIR_FileSize nextfcursor 8 + ! ( ) nextfcursor FCursorSize to+ nextfcursor ( fcursor ) ; -: fat16read ( fcursor -- c ) +: fat16getc ( fcursor -- c-or-0 ) + dup FCUR_pos over FCUR_size = if drop 0 exit then dup FCUR_pos+ ClusterSize mod over FCUR_buf( + c@ ( fc c ) over FCUR_pos ClusterSize mod not if ( fc c ) \ end of cluster, read next - abort" TODO" + over FCUR_cluster nextcluster ( fc c cluster ) + dup endofclusters? if drop else + dup 2 < if abort" cluster out of range" then + rot 2dup FCUR_cluster! ( c cluster fc ) + tuck FCUR_buf( readcluster ( c fc ) swap then then ( fc c ) nip ; diff --git a/fs/tests/fs/boot.fs b/fs/tests/fs/boot.fs @@ -5,10 +5,18 @@ \ 4. It has a 512 sector size ?f<< tests/harness.fs ?f<< fs/boot.fs +: readN ( fcursor n -- ) >r begin dup fat16getc drop next drop ; testbegin \ Tests for fs/boot readFAT readroot -S" init.fs" findindir ( dirent ) -fat16open ( fcursor ) fat16read '\' #eq +S" fattest" findindir ( dirent ) +fat16open ( fcursor ) dup fat16getc 'T' #eq +dup $ff readN ( fcursor ) +dup fat16getc 'f' #eq dup fat16getc 'o' #eq dup fat16getc 'o' #eq +dup $fd readN ( fcursor ) +dup fat16getc 'b' #eq +dup $dfc readN ( fcursor ) +dup fat16getc 'E' #eq dup fat16getc 'O' #eq dup fat16getc 'F' #eq +fat16getc 0 #eq testend