Close

Up to date

A project log for Gigatron Forth

Attempting to implement Forth on the Gigatron

peterPeter 11/05/2019 at 13:560 Comments

[This post brings me up to date with the work I've done so far, and corresponds to the state in commit 0e4b928083ae69bb6ae577197ac016e93a77e80e]

I've documented my design for the NEXT routines, which I've committed to Github here. It's a little sketchy, and I can already see mistakes. I haven't run, or even assembled any of the code yet, but hopefully I haven't made up any of the op-codes, even if some of my assembly syntax is invented! I think the big ideas are clear and I shan't try to explain it again here. I originally wrote that document to post to the Gigatron forum, but I decided it was a bit long to post at this stage.

One thing I will say about that design is that I'm really disappointed that the ROM-mode version of NEXT3 is so expensive. I'd really like running threads in ROM to be cheaper than running threads in RAM. I'm aware that I can encode jumps inline in my instructions, which would vastly speed things up, by removing the double-jump dispatch loop, however it would add 50% to the space usage. I think the current design will probably work, and I can switch to inline jumps later if it turns out that speed is more valuable than space. Also, I really love the double-jump trick - it's so cool!

I'd like to talk a little more about the general approach I'm planning to follow in developing my Forth. I think it can be summarised as:

  1. Try to avoid shaving any yaks.
  2. Prefer automation to manual work, except where such automation would conflict with the First Law.
  3. Prefer writing Forth to Python, except where writing Forth would conflict with the First or Second Law.
  4. Prefer using Python to write assembly to writing assembly by hand, except where writing Python would conflict with any of the other laws.

In practice, I intend to lean very heavily on Python, following the existing approach of using it as "macro assembler", but also trying to use it to unit test my code, and probably even having a Forth compiler in Python for generating embedded Forth threads.

The first 'law' about not shaving yaks is important. I find it easy to get bogged down in minor details and lose velocity. I'm going to try to enjoy, and even celebrate kicking cans down the road. To that end, here are some yaks I have left unshaven so far:

The CFFI wrapping for gtemu.c is pretty neat actually; I hadn't used CFFI before. Here's an example of using it from iPython:

In [1]: import _gtemu

In [2]: f_rom = open('dev.rom', 'rb')

In [3]: ROM_buffer = _gtemu.ffi.buffer(_gtemu.lib.ROM)

In [4]: f_rom.readinto(ROM_buffer)
Out[4]: 131072

In [5]: inital_state = {'PC': 0}

In [6]: state = inital_state

In [7]: def loop(): global state; state = _gtemu.lib.cpuCycle(state)

In [8]: loop()

In [9]: state.PC
Out[9]: 1

In [10]: state.IR
Out[10]: 0

In [11]: state.D
Out[11]: 0

In [12]: loop()

In [13]: state.PC, state.IR, state.D
Out[13]: (2, 24, 128)

This shows running the first two instructions in the ROM! I can see this being really useful.

Now that I have all my tools in place, and a clear idea of what I'm going to write, hopefully my next update will show some real progress towards the goal. 

Discussions