Close

FORTH 25.01.13 HW considerations

A project log for MHF-002 (Mega Home FORTH)

ATmega2560 based SBC with VGA, PS/2 and SD cards - meant to run FORTH now and serve as graphic card later.

gilhadGilhad 01/13/2026 at 21:340 Comments

There are many strategies, how to implement FORTH, but I will refer mainly to Moving FORTH from Brad Rodriguez, author of CamelForth.

Pleas read the  Moving FORTH alongside with this log, as I will just answer or paraphrase questions laid there, without reapeating everything

16 bit or 32 bits? 24 bits! and CELL size:

Target platform is ATmega2560, which has this types of memory:

To address all types in pointer is needed at least 20 bits, so I will use CELL size 24bit (3 bytes, 3 registers) for arithmetic and pointers.

THE THREADING TECHNIQUE: 

Code can be executed only in flash, which is not (simply and repeatadly) writable, while new data can be only stored in some RAM. So new (user defined) words must be placed in RAM and therefor cannot contain executable code. Only ITC (Indirect Threaded Code) allows it (and I like it most too). Also as NEXT is here long, then JMP to NEXT is way for me. And Token threaded code needs the table allocated in RAM to contain the tokens, which consumes RAM and limits number of user defined names (they use the token space too) so I will not use it.

Intermezzo:

In current stage of implementation it looks, like NEXT would take aroud 70 clocks (~4.4 μs) so DOUBLE as compound have 3xNEXT and some code, DOUBLE as phrase have 1x NEXT, and 3 clocks code (which is shorter, then any code in compound DOUBLE). I will use phrases for many usual combination of words (yes, phrases), like 1 +, 1 CELL +, ... as well as for some more complicated parts.

While Flash is little slower than internal RAM, there is a lot of it and RAM is also needed for graphics, file operations, stacks, variables, etc. etc. so I want to prefere Flash to store as much of usual load as possible (common words, vocabularies ...).

Things in Flash must be compiled and uploaded before use whith the rest of FORTH code (~slow and complicated Arduino way).

Things in RAM may be easily changed anytime (added, edited and deleted).

Primitives have native code in flash obviously.

Phrases are just more complicated primitives and so are in Flash too. 

Compound words may be placed in RAM at runtime, or placed in Flash at compilation of FORTH as data, like this:

Some words (like words using CREATE DOES> ) needs executable part, so such words have to be compiled into Flash. 

If compound word's definition contains any IMMEDIATE word inside, then such word have to be resolved before it may be compiled into Flash. (All the IF-THEN, BEGIN-UNTIL and other constructs.)

End od intermezzo

REGISTER ALLOCATION 

Here is my register allocation (also classical C API) and possible stack implementations on AVR:


Best of stack implementation are for me register stacks growing down, as the stack pointer points on lower byte of the value and is easy to manipulate.

DOES and company

In Part 3: Demystifying DOES> are discussed words like CODE; or DOES> which compiles native code into new words. This is complicated on ATmega2560.

Such words may used to define new words, but the new words will not work as they are in RAM. But the new words may be dumped and transformed into Flash compatible byte defintions, which may be then compiled into FORTH and uploaded as new program.

So I will build my FORTH with lot of such words in the core, either as compound words or as phrases.

See also How do you build a Forth system for the Very First Time?

Discussions