Close

NEXT

A project log for Gigatron Forth

Attempting to implement Forth on the Gigatron

peterPeter 11/04/2019 at 22:380 Comments

My knowledge of Forth originally comes from the really fascinating jonesforth by Richard W.M. Jones, which I first saw through Lambda the Ultimate back in 2007. It takes the form of two files, one assembly file, which provides just enough machinery to stand up a Forth runtime, and one Forth file which builds upon it to provide a usable (although almost certainly incomplete) environment. The code is written in a literate style, being so heavily commented as to be at least as much a document as a program. I strongly recommend checking it out for an interesting read.

This style of writing a small assembly kernel in order to bootstrap a Forth system is apparently a common approach, and it's this that makes me think that a native Gigatron Forth might be a tractable endeavour. Hopefully I can fairly quickly get to the point where I'm copying existing Forth implementations of core words instead of writing lots of ASM by hand.

I'm also alive to the scepticism of the other posters on the Gigatron Forum, and must acknowledge that I'm likely to fail. This is also the first truly low-level programming I've ever done.

I've also read (many times) the Moving Forth papers by Brad Rodriguez, which explain (amongst other things) the difference between a few important implementation strategies, particularly Direct Threaded and Indirect Threaded code (jonesforth follows the more traditional indirect threaded code model).

I'm not going to try to re-explain any of what either of these excellent sources cover. To follow what is to come, you'll probably want to be familiar with Forth terminology like 'thread', 'word', etc. Ideally not too familiar though, as I'm likely to misuse the terms - I'm no Forth programmer myself!

What both jonesforth and Moving Forth make clear is that the heart of a Forth implementation is 'NEXT', the code which dispatches to the next word in the currently executing thread, and moves the interpreter pointer (IP) forward. NEXT for the Gigatron could never be as short as the two instructions in jonesforth, because the instruction set is not so rich as i386, but ours will be a lot more complicated because of the timing constraints.

My Forth is effectively going to be a third virtual CPU for the Gigatron, and as such must follow the same rules as the vCPU and the v6502 - which are basically that you are told how much time to run for (in ticks - two clocks, which means two instructions), and you must run for that long, and not an instruction more or less. In the vCPU this is done by the dispatch loop (itself called NEXT - no coincidence, I'd guess) seeing if there's time for the longest possible op-code to complete. However we won't know what the longest 'native' Forth word is (well perhaps we could, but it could be pretty long) and we don't really want to scatter all of our words with book-keeping and continue/abort decisions. So my plan is to have each native word describe it's worst-case runtime before starting, and NEXT will have to decide whether to enter it, or not. Upon completion the word will report the actual time taken (they could be different where there is code that loops or branches). This is similar to how SYS routines work. All of this book keeping and decision making will make NEXT a lot more costly, and the shortest call to the vCPU is 36 ticks - so there isn't much time to get much of anything done!

There's another fly in the ointment: to be usable as an interactive environment we need to be able to compile Forth code to RAM, and to make use of other Forth code in RAM, but native code needs to live in ROM, and we'll certainly want compiled Forth code in ROM as well - so sometimes we'll be executing a thread in RAM where the addresses are to other threads in RAM, sometimes we'll be executing a thread in RAM, but the addresses are to words in ROM, and sometimes we'll be executing threads in ROM, so our NEXT implementation needs to keep all of this straight.


I've sketched out a design for all of this, which I'll post about next time.

Discussions