Side project of mine where I learn how to emulate a simple processor in C++.
Over the course of a week, I wrote a simple emulator for Chip8. This emulator is capable of running existing ROMs for Chip8. It has taught me a lot about Assembly and the way processors work.
Most important things I learned
- What registries, the stack pointer, program counter, etc. are.
- Why the call-stack in Visual Studio is called a call-stack.
- How to interpret OpCodes.
- Implement an emulator based on technical documentation alone.
|Skills:||C++, emulating hardware|
|Software:||Git, CMake, Visual Studio|
Learning how to emulate a processor
In my spare time, I decided to start working on a Chip8 emulator. Chip8 is not a real computer processor. It is a virtual machine in which Chip8 assembly can be run. Nevertheless, emulating the Chip8 involves similar techniques and concepts as when you try to emulate an e.g. Gameboy chip. The big advantage of starting out with Chip8 is that it is one of the simplest things you can emulate. There is no graphics card, it only has a couple of instructions, and sounds are made out of a single beep.
The goal of the project
By taking on this project I wanted to develop a deeper understanding of how processors work. By choosing a simple platform, such as Chip8, I could learn about emulation, instruction sets, and all those things without having to bother too much with more advanced concepts such as dedicated graphics chips. I thoroughly enjoyed working on this project, as it had a focus on processor architecture and Assembly, something I had never really worked with.
I eventually managed to get Breakout, Pong, and a random Moon Lander clone to work properly. Other games crashed occasionally. The screen flickering is caused by my recording software, sorry about that!
Parse and interpret opcodes
One of the more difficult things I had to do was parsing opcodes. Reading them was fairly easy as it was just a matter of bit shifting values. But making everything work properly was fairly tricky. I learned a lot about how
Properly rendering sprites
The Chip8 architecture renders sprites by sending an OpCode, followed by the coordinates of the pixel that should be set. A pixel is XOR’ed with the existing pixel buffer. If the result is 0, the pixel is off, else, the pixel should be turned on.
I was having some issues getting the XOR to work properly. The documentation on Chip8 is a bit sparse and the resources out there can be difficult to understand. My first attempt at rendering graphics in my emulator looked like this:
Another thing that made it more difficult to render sprites correctly was that some Chip8 specifications use a looping display, while others do not. This means that some games would only
Source code: https://github.com/tntmeijs/Chip8