duskos

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

commit 311c464ecb3f900c02bef592232fc8bcc55b125e
parent 1f7a1e549f7c55c219c3a22caaf3e7cba30c4a28
Author: Virgil Dupras <hsoft@hardcoded.net>
Date:   Thu, 30 Jun 2022 07:43:29 -0400

fs/boot: add directory entries buffer

Allows to search in more than 16 entries

Diffstat:
Mfs/fs/boot.fs | 30++++++++++++++++++++----------
Mfs/sys/drive.fs | 4++--
Mfs/tests/fs/boot.fs | 5++---
3 files changed, 24 insertions(+), 15 deletions(-)

diff --git a/fs/fs/boot.fs b/fs/fs/boot.fs @@ -12,8 +12,8 @@ $18 const BPBSZ \ we only care about a part of the BPB create bpb BPBSZ allot +0 drv@ drvbuf( bpb BPBSZ move -: fat16$ 0 drv@ drvbuf( bpb BPBSZ move ; : BPB_BytsPerSec bpb $0b + w@ ; : BPB_SecPerClus bpb $0d + c@ ; : BPB_RsvdSecCnt bpb $0e + w@ ; @@ -28,18 +28,28 @@ create bpb BPBSZ allot : FirstRootDirSecNum BPB_RsvdSecCnt BPB_NumFATs BPB_FATSz16 * + ; 32 const DIRENTRYSZ -create fnbuf 11 allot +\ A buffer where dir entries are copied before we search in them. It's big +\ enough to hold the root dir entries. This means that no directory in the FS +\ can have more than BPB_RootEntCnt entries. +create dirbuf( RootDirSectors BPB_BytsPerSec * allot +here const )dirbuf +11 const FNAMESZ +create fnbuf FNAMESZ allot : upcase ( c -- c ) dup 'a' - 26 < if $df and then ; \ we assume a 8.3 name. Don't call this with an inadequate name. : _tofnbuf ( fname -- ) - A>r >A Ac@+ >r fnbuf 11 SPC fill fnbuf begin ( a ) + A>r >A Ac@+ >r fnbuf FNAMESZ SPC fill fnbuf begin ( a ) Ac@+ dup '.' = if ( a c ) 2drop fnbuf 8 + else upcase swap c!+ then next drop r>A ; -\ Search in directory that is currently loaded in drvbuf. -\ Return address of directory entry, or 0 if not found. -\ TODO: support more than 1 sector dir entry -: findindir ( fname -- ) _tofnbuf - 16 >r drvbuf( begin ( a ) - fnbuf over 11 []= if r~ exit then DIRENTRYSZ + next - abort" file not found" ; +\ Search in directory that is currently loaded in dirbuf. +\ Return address of directory entry, abort if not found. +: findindir ( fname -- direntry ) _tofnbuf + dirbuf( begin ( a ) + dup )dirbuf < while ( a ) + fnbuf over FNAMESZ []= not while ( a ) DIRENTRYSZ + repeat + ( success ) else ( not found ) abort" file not found" then ( a ) ; + +\ Make the current dir the root +: readroot A>r RootDirSectors >r FirstRootDirSecNum >A dirbuf( begin ( a ) + A> over (drv@) A+ drvblksz + next ( a ) drop r>A ; diff --git a/fs/sys/drive.fs b/fs/sys/drive.fs @@ -29,8 +29,8 @@ alias abort (drv@) ( blkno buf -- ) alias abort (drv!) -: drv@ ( blkno -- ) dup to drvblksz drvbuf( (drv@) ; -: ?drv@ ( blkno -- ) dup drvblksz = if drop else drv@ then ; +: drv@ ( blkno -- ) dup to drvcurblk drvbuf( (drv@) ; +: ?drv@ ( blkno -- ) dup drvcurblk = if drop else drv@ then ; \ Ensure that the block containing offset "off" (in bytes) is loaded and that \ there's at least u bytes following that offset that is present in the buffer. diff --git a/fs/tests/fs/boot.fs b/fs/tests/fs/boot.fs @@ -7,8 +7,7 @@ ?f<< fs/boot.fs testbegin \ Tests for fs/boot -fat16$ -FirstRootDirSecNum drv@ +readroot S" init.fs" findindir -11 []>str S" INIT FS " #s= +FNAMESZ []>str S" INIT FS " #s= testend