Small side projects are always a nice way of testing code design ideas, and it feels good to reach a tangible result over an evening hacking session. When doing some research for a potential AltDevBlogADay post, I decided to redo an old project of mine: a CHIP-8 interpreter. The idea I was trying to validate didn’t turn out so well, but the project was entertaining, so I’ll focus my post on it instead. The screenshots at the bottom of this page are from my implementation, which only took a few hours to knock together.
CHIP-8 is a programming language, but it is better described as bytecode. It was designed to simplify the creation of games for the COSMAC VIP computer (1977), which used an 8 bit RCA 1802 microprocessor, had 4096 bytes of RAM and an hexadecimal keyboard. The video output was monochrome and usually had a resolution of 64×32 or 64×64. Given the limitations of the system and the low-level aspects of the language, writing a CHIP-8 interpreter is often used as an introduction to emulation programming.
CHIP-8 has 35 16-bit opcodes that were originally handled by a 512 bytes interpreter. It also requires 16 8-bit registers (one of which serves as status register), an instruction pointer, an address pointer, two 8-bit countdown timers, and a stack for subroutine calls. Finally, you’ll also need the following 40 byte character map for numeric display (each character is 4×5, but sprites have an 8-bit pitch (opcode DXYN), so the second byte digit is always zero).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
0xF0, 0x90, 0x90, 0x90, 0xF0, // 0 0x20, 0x60, 0x20, 0x20, 0x70, // 1 0xF0, 0x10, 0xF0, 0x80, 0xF0, // 2 0xF0, 0x10, 0xF0, 0x10, 0xF0, // 3 0x90, 0x90, 0xF0, 0x10, 0x10, // 4 0xF0, 0x80, 0xF0, 0x10, 0xF0, // 5 0xF0, 0x80, 0xF0, 0x90, 0xF0, // 6 0xF0, 0x10, 0x20, 0x40, 0x40, // 7 0xF0, 0x90, 0xF0, 0x90, 0xF0, // 8 0xF0, 0x90, 0xF0, 0x10, 0xF0, // 9 0xF0, 0x90, 0xF0, 0x90, 0x90, // A 0xE0, 0x90, 0xE0, 0x90, 0xE0, // B 0xF0, 0x80, 0x80, 0x80, 0xF0, // C 0xE0, 0x90, 0x90, 0x90, 0xE0, // D 0xF0, 0x80, 0xF0, 0x80, 0xF0, // E 0xF0, 0x80, 0xF0, 0x80, 0x80, // F
The hardest part is probably finding games to run, only a few have been published back in 1977 but some enthusiasts have recently made great additions. It seems that all the programs around can be copied without infringing any copyright, but I have no idea how I could back that claim with 100% confidence.
If you ever decide to try your hand at writing such an interpreter, I recommend to start with the “maze” program, as it relies on only a few opcodes and should be the easiest to get running. Also, be careful that the end of the 4k memory should consist of 256 bytes of video ram preceded by the 16 registers, some programs rely on this layout.
And now here comes the mandatory list of links, the web is full of information about the COSMAC VIP, the CHIP-8 and the 1802, so here is a small selection of what looked the most interesting to me.
http://chip8.com/ – look for the COSMAC VIP manual, and the CHIP-8 program pack.
http://chip.emulationcollective.com/ – online java CHIP-8 interpreter
http://en.wikipedia.org/wiki/CHIP-8 – for a quick look at the full opcode table.
http://mattmik.com/pcms-programs-series/ – 1802 assembly articles, includes a CHIP-8 interpreter.
http://www.visual6502.org/images/pages/RCA_1802.html – beautiful transistor-level scans of the 1802.