Emulating Chip8 in C++

Side project of mine where I learn how to emulate a simple processor in C++.


Project summary

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.

Role:C++ Programmer
When:2018
Duration:1 week
Skills:C++, emulating hardware
Software:Git, CMake, Visual Studio
Team size:1

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!

Showing-off my first emulated Chip8 game!

Achievements

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 Assembly works. Things such as the program counter, stack pointer, and registries were all new to me.

Reading a Chip8 ROM

Challenges

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:

First attempt at rendering a Space Invaders clone

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 functions with a looping display. I decided to only support a non-looping screen.

Source code: https://github.com/tntmeijs/emulators


Leave a Reply

Your email address will not be published. Required fields are marked *