~vdupras/duskos

86f2afbb95547c0184d7710a12cc64e13e00b16e — Virgil Dupras a month ago ddd1c94
fs/boot: can read subdirs
3 files changed, 20 insertions(+), 8 deletions(-)

M fs/fs/boot.fs
R fs/{fattest => tests/fattest}
M fs/tests/fs/boot.fs
M fs/fs/boot.fs => fs/fs/boot.fs +18 -7
@@ 67,11 67,24 @@ create fnbuf FNAMESZ allot
\ Make the current dir the root
: readroot FirstRootDirSecNum RootDirSectors dirbuf( readsectors ;

: endofclusters? ( cluster -- f ) $ffff = ;
: EOC? ( cluster -- f ) $fff8 and $fff8 = ;

\ get cluster following this one in the FAT
: nextcluster ( cluster -- nextcluster ) << FAT16( + w@ ;

: readcluster ( cluster dst -- )
  over << BPB_BytsPerSec BPB_FATSz16 * >= if abort" cluster out of range" then
  swap FirstSectorOfCluster ( dst sec ) swap BPB_SecPerClus swap readsectors ;

\ Read specified "direntry" in dirbuf(
\ Errors out if it has more entries that BPB_RootEntCnt
: readdir ( direntry -- )
  DIR_Cluster ( cluster ) dirbuf( begin ( cluster buf )
    over EOC? not while
    2dup readcluster
    ClusterSize + swap nextcluster swap repeat ( cluster buf )
  2drop ;

\ File cursor
\ 2b first cluster
\ 2b current cluster in buf


@@ 93,11 106,9 @@ create fcursors( FCursorSize FCURSORCNT * allot
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 )
\ Open the specified "direntry" into one of the free cursors and return that
\ cursor.
: openfile ( 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 FCUR_cluster! ( dirent )


@@ 109,7 120,7 @@ fcursors( value nextfcursor
  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
    over FCUR_cluster nextcluster ( fc c cluster )
    dup endofclusters? if drop else
    dup EOC? 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

R fs/fattest => fs/tests/fattest +0 -0
M fs/tests/fs/boot.fs => fs/tests/fs/boot.fs +2 -1
@@ 10,8 10,9 @@ testbegin
\ Tests for fs/boot
readFAT
readroot
S" tests" findindir readdir
S" fattest" findindir ( dirent )
fat16open ( fcursor ) dup fat16getc 'T' #eq
openfile ( 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 )