The harness files permit you to optimise the FAT file system for speed or code size.
How you code these will depend on the host CPU and Forth implementation.
: secs>bytes \ u -- #byes
Multiply a sector number by the number of bytes per sector.
Optimise this for performance.
: bytes>secs \ #bytes -- #secs
Divide a number of bytes by the number of bytes per sector,
returning the number of complete sectors.
Optimise this for performance.
: bytes>offsecs \ #bytes -- offset #secs
Divide a number of bytes by the number of bytes per sector,
returning the offset in a sector and the number of complete
sectors.
Optimise this for performance.
These tools should be compiled as required.
: FOR \ -- ; n -- ; R: -- n'
Starts a loop that is executed one or more times. At runtime,
the loop is entered with the loop count on the stack. In the
body of the loop the loop index is on the return stack and
counts down from n-1 to zero. Use in the form:
( -- n ) FOR ... NEXT ( -- )
: NEXT \ -- ; R: n -- ; -- [n]
Terminates a [m ... m] structure, discarding the loop
index.
: ucompare \ a1 u1 a2 u2 -- notsame?
Case insensitive string compare. Returns zero for a match.
: ucmove \ src dest len --
As CMOVE but characters are converted to upper case.
: N++ \ n1 x -- n1+1 x
Increment n1.
: byte-split \ w -- lo hi
Split a 16 bit item into its low and high bytes.
: byte-join \ lo hi -- w
Convert two bytes into a 16 bit item.
: word-split \ x -- wlo whi
Split a 32 bit item into its low and high 16 bit items.
: word-join \ wlo whi -- x
Convert two 16 bit items into a 32 bit item.
: qlog2 \ n -- log2[n]
Given n, a power of two, return its power.
Error codes. Note that the Forth200x specification allows iors to be thrown, so these numbers should be unique.
#100 dup equ err_FATfiler \ base of all FAT file system error codes dup equ err_FATread 3 + \ base read error - 3 available, H/W specific dup equ err_FATwrite 3 + \ write error - 3 available, H/W specific dup equ err_NoHandles 1+ \ not enough free file handles dup equ err_RootFull 1+ \ no room left in the root directory dup equ err_FATparams 1+ \ error in FAT parameters dup equ err_FileSize 1+ \ file size longer than 32-bit dup equ err_FileNotFound 1+ \ file was not found dup equ err_BadDir 1+ \ not a valid directory dup equ err_DirNotFound 1+ \ directory was not found dup equ err_w/o 1+ \ 14 = attempt to read W/O file dup equ err_r/o 1+ \ attempt to write R/O file or device dup equ err_BadPathName 1+ \ invalid created pathname dup equ err_BadFileName 1+ \ invalid created filename dup equ err_DirFull 1+ \ full directory dup equ err_NotDir 1+ \ invalid directory name dup equ err_BadPos 1+ \ Reposition beyond end of file dup equ err_NoDrive \ Drive not present, e.g. card removed drop
: time&date 0 0 0 1 1 1980 ;
If TIME&DATE is not available, a dummy value is returned.
Some CPUs require aligned memory accesses. The code here checks alignment at run-time.
0 [if] \ Do or do not test for unaligned memory access: : @ dup 3 and if .rs 1 abort" Unaligned 32-bit read" endif @ ; : ! dup 3 and if .rs 1 abort" Unaligned 32-bit write" endif ! ; : W@ dup 1 and if .rs 1 abort" Unaligned 16-bit read" endif w@ ; : W! dup 1 and if .rs 1 abort" Unaligned 16-bit write" endif w! ; [then]
Systems that require aligned accesses for 16 and 32 bit values must provide unaligned access words. Similarly, big-endian CPUs must provide little-endian access as all the FAT data structure items are little-endian items.
: uaLEw@ \ caddr -- w
Unaligned 16 bit little-endian fetch.
: uaLE@ \ caddr -- x
Unaligned 32 bit little-endian fetch.
: uaLEw! \ w caddr --
Unaligned 16 bit little-endian store.
: uaLE! \ w caddr --
Unaligned 32 bit little-endian store.
These words provide some portability for different CPU architectures.
: @P @ ; \ addr -- x
32 bit fetch from code space.
: W@P w@ ; \ addr -- w
16 bit fetch from code space.
: c@p c@ ; \ addr -- b
8 bit fetch from code space.
: @C @ ; \ addr -- x
Fetch 32 bits from code space (e.g. for tables).
: W@C w@ ; \ addr -- w
Fetch 16 bits from code space (e.g. for tables).
: c@C c@ ; \ addr -- b
Fetch 8 bits from code space (e.g. for tables).