It is said that any processor, given enough time, can emulate the operation of any other processor. With this in mind, this week I have been having a retrospective look at some simple tools to help with low level microcontroller hacking.
This week in the spare evenings, I have written some low level tools to help me debug a J1 Forth processor - which is a softcore that runs on a FPGA.
In order to first understand the operation of the J1, I first used a simulator - so that I can try simple test programs - of only a few bytes, and single step through them to view the effect each instruction has on memory.
These screen shots have been created by a softcore procesor called ZPUino - which runs on a FPGA and produces an 800 x 600 VGA output.
My code is written in "Arduino" and is compiled to run on the ZPUino - a 96MHz 32 bit soft cpu.
The early version of this code can be found on this Github Gist
https://gist.github.com/anonymous/4f45827b32a1fc66db27
It has been written by way of a quick demonstrator of what is achievable with simple coded tools - and no way constitutes a finished design.
Thanks to Alvaro Lopez, Jack Gassett @Gadget Factory and James Bowman @GameDuino for their support.
The memory dump window - where up to 1K 16-bit words are displayed in hexadecimal. May be individually highlighted. |
Tools in the Toolbox
Here is a non-exhaustive list of what I think is needed to support new processor code development.
1. A graphical view of memory and key registers such as program counter, top of stack, stack pointer etc - each cell highlighted with a change in colour when its contents are changed
2. A disassembled listing of the memory, showing the immediate area from which the cpu is executing instructions. A single step facility to execute each instruction in turn and view the changes to RAM and registers.
3. A model of the cpu emulated in software. Again - single stepping through code is essential.
4. An assembler. The means to type in mnemonics and data and have these converted to legitimate instructions. Produces an output file which may then be loaded into the RAM of the cpu - or the cpu simulator.
5. Ultimately, a higher level language, such as Forth, which may replace the low level assembler and provide an interactive experience with the processor.
A Historical Note
30 years ago, as a college student, it was commonplace to write machine code using the laborious task of hand assembly. Processors were generally clocked at less than 5MHz and had a rich, 8 bit instruction set. Often it took several clock cycles to execute the simplest of instructions. Additionally, a lot of the processor's time was spent handling the graphics interface. Face it, 1980's were slow.
The most sophisticated tools for this were a pencil and a supply of paper - plus a databook that detailed the instruction set for the particular micro that you were coding for.
Op-codes were written down on paper in hex, and then using some form of hexadecimal input program, they would be entered into the RAM of the microcontroller. We quickly learned the trick of using a battery backed RAM, instead of an EEPROM for program development - and when your code finally worked, you would program an EEPROM.
Move on Up
As time goes by, tools become more sophisticated, and further layers of abstraction are put between you and the bare metal of the processor.
By the late 1980s, assemblers became available to the hobbyist community, and so you at least had the easier task of programming in standard mnemonics, rather than raw hex. About this same time, I wrote a simple Z80 disassembler in Basic, which at least allowed you to get a crude listing of the code stored in RAM - showing the main instructions, calls, jumps etc.
These low level tools make the task of dealing with a new microcontroller much simpler, and so this week I decided that I would look at providing myself with a suite of tools to simplify the code development on the J1 soft core Forth processor.
Disassembler Window - bottom right allows instructions to be displayed in human readable Mnemonic format |
The J1 is the processor used on GameDuino, blown into a Xilinx FPGA. It has a simple instruction set, which makes the task of assembly and disassembly somewhat easier. It's also quite easy to simulate - or rather emulate, using another microcontroller.
I have decide to use the Arduino language to program up these tools. Firstly it is very accessible, secondly it runs on AVR, ARM and FPGA processors - so it has almost become a lingua franca for these various devices.
Additionally, I have bought a Classic Computing Shield from Gadget Factory - which in addition to the VGA interface, provides PS2 keyboard and mouse, microSD card and Atari style game controller ports to my Papilio Duo FPGA board.
So hopefully I will be all set to start developing in a usable computing environment.
The first task was to get the VGA graphics to provide a memory dump facility from the SRAM that accompanies the FPGA. This shows the memory address and the data stored at each RAM address. It's about as basic as you can get - showing 1K x 16 bit words on the screen at any time.
With the ability to display graphical text fields, in different colours on a VGA monitor, I decided that it was about time to start on a new voyage of discovery - and to create a set of tools from scratch to help understand the operation of the FPGA softcore microprocessor.