Sunday, September 06, 2015

Emulating a J1 Forth Processor on an Arduino


Emulation is a useful technique - especially when you don't actually have the processor that you are writing code for.

In the Spring of 1975, 19 year old William Gates III did not possess an 8080 microcontroller, but he and friend Paul Allen had committed to writing a BASIC interpreter for the company supplying the new 8080 based Altair microcomputer.

Fortunately Paul Allen had written an emulator for the similar 8008, which ran on a PDP-10 mainframe at Harvard, and working nights for several weeks on the PDP-10, they managed to produce the first Microsoft BASIC product - and the rest is history.

Back in April, when I had a little spare time, I started to work on a program to emulate James Bowman's J1 Forth CPU - and it was the subject of my post "One Song to the Tune of Another".
At that time I had it running on a FPGA soft core - the ZPUino, and it was complete with a VGA display. I am now taking a step back to just isolate the J1 simulation part of that project, so that I can build it into a set of simple tools that I am developing.

Now as my thought processes are starting to converge, I thought I'd dust off the code and start to see how it will fit into my grand scheme for a stand alone code development system based on a J1 running on a FPGA.

James has put a lot of effort into writing his "swapforth" for the J1, but I am treating this as a learning exercise, so rather than use James's swapforth, I am setting about writing my own tiny language - it's the journey, not the destination I am interested in at the moment.

Not being as ambitious (precocious) as Bill Gates, I set my sights a little lower and in just 200 lines of code, I have a J1 emulator that runs on an Arduino.  The code I am using has been adapted for the Arduino from Samawati's J1 simulator on  GitHub.

Slow Forth

Not renowned for high speed or vast resources, the Arduino munches through the J1 code at a pedestrian  63,000 instructions per second. That's about  1600 times slower than an actual J1.
Slow, but nevertheless useful. I can now write snippets of assembly language to run on my "J1" and test them out.

The J1 machine code is stored in an array of 16 bit integers m[xxx ] set up in memory. As the ATmega328 only has 2K bytes of RAM, I kept the array size down to  768 words.

Here is the first J1 program - a simple counter

// Load up a simple count program into first 7 locations of the memory array m[ ]

   m[0] = 0x8020;      // LIT 0x20  (0x20 is the address of the count variable
   m[1] = 0x6C00;      // Fetch   [0020]
   m[2] = 0x8001;      // LIT 1   We are going to add 1
   m[3] = 0x6200;      // ADD
   m[4] = 0x8020;      // LIT 0x20
   m[5] = 0x6020;      // Store
   m[6] = 0x0000;      // JMP 0000

Translating these 7 instructions into Forth  we get

32 @ 1 + 32 !  followed by a jump back to the first instruction

Forth is clearly a little easier than assembly language, but note how the J1 instructions translate on a one to one basis into Forth, so validating the idea from yesterday's post about using the SIMPL interpreter to create assembly language - this is the next step.

Slightly Quicker Forth

Further experiments with a  STM32F407  Discovery board - and ARM Cortex M4 clocked at 168MHz showed that the emulator would run at approximately 700,000 J1 instructions per second - about 1% of the speed of the proposed hardware.

No comments: