Forth 7 cross-compiler harness





The harness files permit you to optimise the FAT file system for speed or code size.




Sector handling

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.




Tools

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.




Alignment checking

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]



Unaligned memory access

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.




Portability words

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).