A C Based Emulator for the One-Page CPU
2015-02-26 - By Robert Elder
One of my favourite side-projects is a collection of compiler, microkernel and emulator tools, that I've collectively called RECC. A core part of the project is a specification for a very simple and easy to emulate 14 instruction machine language. The project includes a compiler that works for a very large subset of ANSI C89 and can cross-compile to the op-cpu assembly language. Here is an example of the One-Page CPU assembly language:
ll r1 0x0
ll r2 0x10
shl r1 r2
ll r2 0x4C
or r1 r1 r2
loa r2 SP
In addition to the 14 machine instructions that the One-Page CPU supports it also features preemptive context switching, a timer interrupt, and I/O interrupts. Traditional manuals that document CPUs are hundreds of pages, so I wanted to create one that would be simple enough that you could describe it on one sheet of paper. Admittedly, however, if you haven't written a kernel before you might have trouble understanding the specification at first.
As far as compilers go, they aren't particularly useful unless they can compile non-trivial programs, so I wrote a small microkernel that supports context switching and interrupts, which I've cross compiled and run successfully inside a javascript emulator.
Since the machine language is so simple, an emulator for the One-Page CPU can be written in a few hundred lines. Recently, I decided to make a C based implementation of the emulator, which now means you can run a trivial microkernel as if it were a single program inside of C or Javascript. In the future, I hope to write emulators for a large number of languages, so that C programs and microkernels can be embedded into the majority of other languages.
The kernel doesn't do much at the moment, but since it supports inter-process communication and preemptive context switching, you can easily add your own user tasks. You can try it out for yourself by running the commands below (assuming you're on Linux):
# Clone the repo
git clone https://github.com/RobertElderSoftware/recc.git && cd recc && git checkout 1657a285a190316a94a734e9a5fbc7e3986d6e40
# Build the kernel and the linux-based C emulator
make bootstrap-datatypes && make build-kernel && make emulators/linux-emulator-example
# Use the emulator to run the kernel directly from the command-line
emulators/linux-emulator-example kernel/kernel.l1
After running these commands, you should see something similar to this:
You'll also get the same thing if you run the kernel in the Javascript emulator:
A live version of the Javascript emulator running the full kernel is can be found here. The Javascript version of the emulator also comes with a nice visualization for debugging:
You're not limited to running the kernel either. If you want, you can create arbitrary programs that have multiple external symbols and link them together. As long as they have a main method, they should run fine in either emulator.
How to Get Fired Using Switch Statements & Statement Expressions
Published 2016-10-27 |
$40.00 CAD |
Should I use Signed or Unsigned Ints In C? (Part 1)
Published 2015-07-27 |
The Jim Roskind C and C++ Grammars
Published 2018-02-15 |
7 Scandalous Weird Old Things About The C Preprocessor
Published 2015-09-20 |
GCC's Signed Overflow Trapping With -ftrapv Silently Doesn't Work
Published 2016-05-25 |
Should I use Signed or Unsigned Ints In C? (Part 2)
Published 2015-08-16 |
Strange Corners of C
Published 2015-05-25 |
Join My Mailing List Privacy Policy |
Why Bother Subscribing?
|