Writing my first Gameboy Emulator

Okay so today’s post might be a bit of a cheat because I’m nowhere near complete on this project. But I’m really excited, because I just got the Tetris title screen working!

This is the first time I’ve worked on an emulator and oh boy do I regret taking this long to get around to it. This has been one of the most rewarding projects I’ve worked on. Not only do I feel like I’m truly gaining a more fundamental understanding of the internals of a machine (which is sort of the point), but it is SO exciting suddenly seeing someone else’s software pop up on the screen.

I’m still working on this journey myself but I thought I’d share what I’ve done so far to hopefully encourage others to give this a go.

It all started with the bootrom. The gameboy didn’t have an operating system. It simply had a simple bootrom that showed you that famous Nintendo logo (which is actually a novel DRM scheme). It’s a very simple program that you can read line by line making it pretty easy to work out where I was going wrong. I started by making a “CPU” which was just a big ol switch statement going through each opcode. This is definitely the most labour intensive part of the project. There are a lot of opcodes.

What you quickly discover while implementing opcodes is that the gameboy memory is basically just an array. So next I created registers and an “MMU” (the gameboy didn’t really have an MMU but this made things easier to manage). After around four days, I had the Nintendo logo rendering!

Simple rendering is pretty straightforward. The Gameboy would write to a certain region of memory reserved for video so all you need to do is read from there to know what you should render. Once I got that far - I was completely hooked. My approach of just implementing more and more Gameboy hardware was working.

There are already a ton of resources that go into far more detail:

If you have the time and you’re interested, I would strongly suggest you give this project a go. It is very fun. Happy coding!

You can find the code here: