Home Projects Articles

Gameboy emulator

Currently working on it.

I first wrote a good bit (instructions + memory mapping + timers) without much testing, so there was so much to fix. I also went with global variables for the state back then (I thought that it should be fine since the actual gameboy hardware kinda is global to the components in it), but it was so annoying since the code was written with those globals in mind - for example, I couldn't just make a separate .c file to test the CPU instructions (with way simplified memory). I also don't like how the state could be changed by everything. A lot of people say that globals are bad exactly for those reasons, but I wanted to experience it myself (I mean a database is like a global variable, no? So globals aren't ALWAYS bad...).

I'm currently rewriting it with much cleaner architecture (according to the 2026 me, at least). That means explicitly passing the states, thoroughly testing everything non-trivial I implement before moving on (not TDD, but something more like this - I found this article clarified the "HOWTO" for testing for me enormously - before, I was trying out things myself on smaller projects with mixed results).

I also decided to do a unity build this time aroundd - the way Handmade Hero does it. This way it will be really easy to port it to STM32 later on, which I plan to do. I mean how cool would it be to have a handheld gameboy console of your own making? For the desktop layer I went with raylib, as with it I can compile on Linux and Windows really easily (and I'm also familiar with it already).

Another thing I realized after my first attempt is that I should be spamming asserts whenever I can. It's not that obvious with smaller projects, I feel like, but with something of that scale it starts to get a bit more complicated. Asserts help find programmer errors (which are really hard to find, since usually you assert something you were assuming was true - without that assert you don't know that your assumption was incorrect, so you don't even think to check for it), which is a big time (and fun) save.