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: