Michael Piper, Senior
TECHNOLOGY EDITOR
If you were to look back at my past articles, you would notice right away that I’ve been somewhat obsessed with learning about the way that computers work. Up until recently, however, my obsession was an entirely academic matter: I would read diagrams and datasheets for hours on end without putting anything into practice. But my new project, an emulator, has finally provided me with an avenue for realizing what I have learned.
Formally, an emulator is a piece of hardware or software that allows programs written for one machine to run on another. Mine is a software emulator, which is much easier to make than a hardware emulator considering that I don’t own a semiconductor factory. The idea of a software emulator has been around for a surprisingly long time: IBM wrote emulators in the 1960s to replicate the behaviors of earlier machines, and some video games have run on emulators since the 1970s.
One of the most famous early emulators was CHIP-8, which was written 1977 to provide some level of compatibility between the vastly different early hobbyist computers of the time. Thanks to its simplicity, CHIP-8 is still used today by many hobbyists as a first step before creating a more complex emulator or as a project to help them learn a new programming language. This was the context that I first heard of it: I was trying to learn the Rust programming language from other projects, but found that I needed something simpler yet still comprehensive to learn from. However, I decided against just following the CHIP-8 structure. As I am loath to imitate the work of others — I find it boring — I figured that I should tweak the design to make it more my own.
The primary commonality between my emulator and CHIP-8 is a set of sixteen 8-bit registers. Unlike the von Neumann architecture of the CHIP-8 which stores data and programs in the same memory, I implemented a Harvard architecture which separates the two. Having separate program memory makes accessing it slightly simpler, as each instruction can be one 16-bit value instead of two 8-bit values accessed separately. Non-structurally, I decided not to follow the CHIP-8 instruction set, opting instead to write my own.
My emulator is currently simpler than CHIP-8, but I intend to make it just as complex, if not more so. My immediate task is to add more instructions beyond basic arithmetic, but down the road I want to implement variable-length instructions, fully emulated peripherals, and some graphics capability.