Writing an emulator: it’s the journey that counts!

TL;DR: I started writing a Game Boy emulator in Go in June 2018 and since then, at least three distinct people have expressed polite interest in the details. I hope to show how it’s done, in mildly-to-heavily technical terms. It’s going to take a while but I hope it turns out marginally informative.

Emulators are fascinating little beasts. I’ve long pondered writing one, a bit like one ponders clearing up space in the garage someday to build a vintage car from scratch using hand-machined parts. Who’s got the time, right? I have no idea what to emulate. I wouldn’t even know where to start. I don’t even have a garage!

It might have never gone further than that, except the Internet is full of talented people, some of whom also write. That’s how, sometime in summer 2018, I randomly ended up reading Tomek Rękawek’s blog post explaining why he spent 1.5 months creating a Gameboy emulator. Please take a moment to read it, because I intend to write pretty much the same kind of thing here. However, I won’t focus on the “why” — if you’re here, you don’t need any convincing — so much as I intend to document the “how”.

Tomek’s post is fascinating, in part thanks to the detailed explanations, the numerous references to online documentation, the pretty pictures… but also in how it makes it look so easy to write a Game Boy emulator! An arbitrarily large byte array, a counter and some low-level logic. I could do that! I could at least write just enough of an emulator to execute the 256 bytes of the Game Boy’s boot ROM…

And I did!

In the very beginning, I didn’t plan on doing more than that — I mostly wanted an excuse for a quick project to hone my newfound Go skills — but it turns out that booting the Game Boy is already half the work fun, and this was too nice a project to stop there. Moreover, as work progressed, I ended up posting a lot of encouraging screenshots of almost-working games or frustrating but nice-looking glitches. It made a few friends curious, I heard the phrase “I’d love to do that but I don’t have the time” a few times, and thus thought I’d document the whole thing in a series of blog posts in which I could get as technical as I wanted. A sort of “I implemented it so you don’t have to” even though I still heartily encourage you to try.

At the time of this writing, a few of the most popular games are actually running fine — just with poor timing and no sound — but I’d like to start from scratch and take you along the whole journey. From the first lines of code only printing out some debugging info to, I hope, a fully functional Game Boy emulator someday.

Spoiler: this isn’t one of the games that work.

So far it’s taken me a year, on and off, to get there, and I regret nothing! If you want to have a look, the whole project is now available on GitHub!

What’s next?

If you’re still here and hunger for more, this is roughly how I intend to break down the next emulator-related posts (this list will be updated as I post/add chapters) based on the chronological order of the features I implemented. I’m using my git log as a rough guide right now:

  • Implementing the very basics of a Z80 processor and some RAM.
  • Throwing the Game Boy’s boot ROM at that emulated CPU.
  • Fixing the implementation of the CPU until the emulator stops crashing.
  • Implementing the very basics of a Game Boy’s GPU.
  • How do you put an actual pixel on a computer screen again?
  • Damn… the boot ROM works, now what?
  • Dicking about (or “Why won’t Tetris run dammit?”)

This list isn’t complete yet, and I’m not sure there will actually be a single post per item, but this is the general idea. It will take a while to complete, but I hope to illustrate most of these with before/after pictures and GIFs of the nicest-looking bugs and glitches.

Acknowledgements

I’m very happy I found Tomek’s blog, and from there an impressive amount of online resources describing in excruciating detail how the Game Boy works. In particular:

All of these sources (and more) are actually mentioned throughout the emulator’s code to explain some of the least obvious implementation choices. They also make for good bathroom reading if you print them out.

And this is it for today. In the next post, we’ll install vscode and get started, thank you for reading!