Several years ago, I began work on a Chip-8 interpreter for Mac OS X. Chip-8 is an interpreted language for creating computer graphics and games applications. It was invented by Joseph Weisbecker in the late 1970s. Weisbecker worked for RCA at the time and was also responsible for designing the COSMAC VIP, an early microcomputer. This was released in 1977 and sold in a kit format. It was aimed at the home and hobbyist market.
The VIP could run programs written in machine code for the RCA 1802 microprocessor at the heart of the VIP. This required detailed technical knowledge of the 1802’s instruction set and an in-depth understanding of the VIP’s hardware. To make life easier for new programmers, Weisbecker created a simpler language, Chip-8. This included commands for drawing sprites to the VIP’s display, reading the keyboard and playing simple sounds.
If you are imagining something like BASIC, think again. The Chip-8 language is still very low level. In fact it closely resembles a machine language in that it uses a set of two-byte op codes. A more accurate comparison is the bytecode created by a Java compiler. So by today’s standards, programming in this language was no picnic. This is especially so because the program had to be entered byte by byte using the VIP’s hexadecimal keypad. Completed programs could then be saved to a tape cassette.
The COSMAC VIP shipped with a listing of the Chip-8 interpreter in the instruction book, which also contained listings for 20 Chip-8 games and graphics applications. If the user wanted to use Chip-8, they had to enter the listing by hand and then save it to tape for future use! We have it easy these days. 😉
As you might expect of a language written in the 1970s, the games created by Chip-8 are primitive compared to what we are used to now. The display is monochrome and is 64 pixels wide by 32 pixels high. To give you an idea how tiny this is by today’s standards, here’s an image of my Chip-8 interpreter running a space invaders type game at its original size on a Macbook Pro 15″ retina display. Below it is the same game with the pixels zoomed up by a factor of 10 (which makes it playable on a modern display).
Because Chip-8 is an interpreted language, it can be run on any machine that includes a suitable interpreter. This resulted in the language making an appearance on a number of other machines around that time, including the Telmac 1800 (1977) and the ETI 660 (1978). Any program written in the Chip-8 language would run successfully on these machines provided they were running the interpreter (just as Java bytecode will run on any device with a Java Virtual Machine).
In 1990 Chip-8 enjoyed a revival when Erik Bryntse developed a Chip-8 interpreter for the HP48 programmable calculator. While ensuring that his interpreter was backwardly compatible with the original Chip-8 interpreter, Bryntse also introduced some extensions. These took the form of a set of additional op codes to provide support for further features, including a larger size screen. This interpreter became known as Chip48 or Super Chip (SCHIP).
In the years since then Chip-8 interpreters have emerged for many popular microcomputers and several other devices. These programs are often called emulators, but strictly speaking they are interpreters as they are not emulating a specific hardware configuration.
Why so many interpreters and why another one? Probably because writing a Chip-8 interpreter requires many of the skills required for writing an microcomputer emulator. Because it’s less complex than an emulator, writing a Chip-8 interpreter is a good way for emulator programmers to cut their teeth before they progress to more complex projects. That’s certainly true in my case.
My Mac Chip-8 interpreter was being built as a Cocoa application in Objective C. I have previously worked in C and C++, so it wasn’t a huge leap, but it took me a while to adapt to the idiosyncrasies of the language. The more I worked with it though, the more I loved it. I found Objective C code was lot more self-documenting than C or C++ and it was often easier to read.
But back to the interpreter. I implemented a simple messaging system to keep the user informed of the current status of the app while it is running:
The interpreter was progressed to the stage where games and applications could be loaded and run and they worked fine on the whole. You can see a screenshot of the simple Invaders program running earlier in this post.
Apps could be paused (they would continue execution from the same point when restarted) or stopped (execution would begin from the machine state when the app was first loaded if the app was restarted). Chip-8 uses a timer that fires at 60hz (which was the screen refresh rate of the machine it originally ran on). Any games that use this to control their timing ran perfectly. Games that did not use the timer ran too fast. I began analysing the original Chip-8 interpreter to arrive at an ideal execution rate for my interpreter to get it as close as possible to the speed of the original.
The Chip-8 app could be resized at any point during execution. It would scale the display appropriately while maintaining the aspect ratio. There was no full screen support, but I had planned to add that at some point.
Apart from ongoing testing and addressing the speed issue, there were two more things I had wanted to do before I was ready for an initial release of the software. The first was to implement sound. The sound timer was active in the interpreter but there was no tone generation code implemented. I needed to spend some time looking into the best way to implement sound support.
Second was to finish implementing the key mapping:
Sadly at around this point in the project, Apple shifted away from Objective C in favour of Swift and I never found the time to migrate the project. So the Mac project is currently mothballed, but a JavaScript version is underway. As this project progresses I’ll be posting more information from my research into Chip-8, as well as work in progress on the interpreter.
Be First to Comment