Adventures in GameBoy Emulation: Part 1

A Little Background

This is a short series I’ll be writing to document a GameBoy emulator that I’m working on (DMGe).

The project was created out of a merger between two projects.

WWGB: My own project.

ZGB: A project that I collaborated in on GitHub.

Now, I know that it’s been done time and time again. A new GameBoy emulator is nothing to get too excited about, but that’s not the point of this project. It’s a learning experience. Primarily, I want to learn more about embedded architecture, and you might learn something too by reading this series.

Why I Chose the GameBoy

Originally, I wrote a Chip8 emulator. This served as a great learning experience, but was by no means a good example of embedded system emulation. The Chip8 interpreter lacked a lot of things that are typical most bespoke computer systems. Namely the following:

  • No real MMU or memory mapping.
  • No clock cycles/machine cycles or timing to consider (apart from 60Hz timers).
  • No interrupts.
  • Very limited opcode set.
  • No variable length instructions.

The GameBoy, on the other hand, has all of these things and a simple enough opcode set too. Another key area that interested me was the memory bank switching circuits for accessing all of the cartridge data within a 16-bit address space.


Implementing an emulator is never an easy task. You’re essentially rebuilding a system from the ground up in most cases. The first place to start then is research. You have to know an awful lot about the system you’re planning to emulate before you even start to code.

I started out by finding what technical documentation I could on the Internet. Being such an old console, there is no lack of it. There has been plenty of time for people to reverse engineer the console and document it since its release. Links are included to my reference materials at the bottom of this post.

Key Points

These are the core parts of the GameBoy that I would have to consider in order to get started.

  • CPU – Custom Sharp Core (LR35902). Essentially an Intel 8080 variant that has some of the improvements introduced in the Z80 present. Two sets of opcodes. Those that are non-prefixed, and those that are prefixed with 0xCB. The 0xCB opcodes deal primarily with bit manipulation, while the others deal with typical processor operations such as load immediate, jump etc.
  • MMU – The GameBoy has a 16-bit address space, allowing for a total of 65535 bytes to be addressed, although in reality the console does not have this much memory to address. For example, reading from 0xC000 -> 0xE000 will return the same values as reading from 0xE000 -> 0xFE00 as the internal 8kB of RAM is mirrored in both these locations. It also possesses specific locations for switchable ROM and RAM banks, VRAM, sprite attribute memory, interrupts and general I/O.

Things like graphics and sound I decided to leave for a later date. They’re nice, but I wanted to get the CPU core up and running as soon as possible, but that’ll be continued in the next part.


GameBoy CPU Manual


GameBoy Opcodes


How to Get Your M-Audio ProjectMix I/O Working in Linux


As of Linux Kernel 3.19, Takashi’s work (GitHub) has been merged in. This means that on any recent Linux installation, installing the drivers shouldn’t be necessary. You can skip right to installing FFADO from source and setting up a jack sink in pulseaudio.


This is something that I wanted to do for quite a while. I’ve never really used Linux for music production because I prefer Windows and OSX software such as Pro Tools, but it’s nice to be able to listen to music while I code. And Linux is so much nicer to develop code for than Windows. This tutorial will focus on setting the desk up on a Linux Mint/Ubuntu environment.

So first off, what we are going to do is install a new kernel module which allows our Linux system to communicate with the ProjectMix (thanks to Takashi Sakamoto for that), then create a Jack sink into which we feed all of our PulseAudio sound. We’ll also be using FFADO ( to control the internal mixer in the ProjectMix.


We’re going to need several things installed before we even begin to set this up. First off, you’ll need the latest version of “Git”. Open up a terminal and install it with the following command:

 sudo apt-get install git 

We’ll also need to set up some build dependencies for FFADO. This is going to involve adding some source repositories. Open up /etc/apt/sources.list as root with the following:

 sudo gedit /etc/apt/sources.list 

Add the following lines to it. On Ubuntu, replace “saucy” with whatever version you are using. On Mint, I’ve found that it really doesn’t matter as far as FFADO build dependencies go.

deb saucy universe

deb-src saucy universe

Finally, you’ll want to update aptitude and install the build dependencies:

sudo apt-get update
sudo apt-get install build-dep libffado2
sudo apt-get install scons

Getting the Source Code and Building

We’ll start by grabbing the code for the ProjectMix driver module from GitHub and the FFADO source code from I’d also recommend that you create a “ProjectMix” folder to keep everything tidy.

git clone
tar -xvzf libffado-2.2.1.tgz

Okay, now that we have the source code and it’s extracted. We have to build and install it. We’ll start with the driver module:

sudo ln -s $(pwd)/snd-firewire-improve/ /usr/src/alsa-firewire-3.11
sudo dkms install alsa-firewire/3.11

That’s the main step complete. ALSA can now communicate with the ProjectMix. You can actually test this by rebooting your machine, and you will hear “pops” coming from the speakers as the driver sets the sample rate of the sound card.

This would now be a good opportunity to install qjackctl, as you will need it to configure the sample rate and routing of the sound card in future.

sudo apt-get install qjackctl

And with that, it’s time to install FFADO. It will have nothing to do with streaming audio to the device, but it is necessary for controlling the ProjectMix internal mixer. You can build and install it with the following commands.

cd libffado-2.2.1

sudo scons install

At this point it would be a good idea to check that you can stream audio to your device. Reboot and start up qjackctl. Go into settings and select ProjectMix as your interface under ALSA, then press the start button. Open up ffado-mixer, either in a terminal window or just click the icon in your menu, then set your output to “Aux 1/2”. Make sure your speakers are plugged into outputs 1 and 2 on the device and put the volume fader in ffado-mixer to a reasonable level. You can test the audio output by opening up any audio software that supports Jack and playing some audio through it.

Hear some sound? Great, let’s continue and set up your Jack sink for PulseAudio (this will allow desktop applications to send sound to the card). Don’t hear anything or are you having any other issues? Leave a comment below and I’ll do my best to help.

PulseAudio and Jack

Admittedly this isn’t the most ideal way to do things, but until Linux has something like CoreAudio for OSX, it will have to do. We’ll start by killing the PulseAudio service until we finish setting everything up or else it will just get in the way. This is quite simple to do.

Start by opening your PulseAudio client configuration as root:

sudo gedit /etc/pulse/client.conf

Add the line “autospawn = no”. Save it, but don’t close it yet.

Open another terminal window/tab and enter the following command:

pulseaudio --kill

This will stop the service while we install the jack-sink module. Install it with the following command:

sudo apt-get install pulseaudio-module-jack

You’ll now need to edit your PulseAudio configuration to load the new module when it starts. Open up your configuration file:

sudo gedit /etc/pulse/

Add the following line:

load-module module-jack-sink

Save it and close. Finally, go back to your “client.conf” and erase the “autospawn=no” line that we added earlier, save it and then close.

The Moment of Truth

That’s the setup completed. Close everything and reboot your computer.

Don’t panic if you don’t hear any sound immediately. Make sure you go into your sound settings and set the output to the jack sink that we installed. It should appear just like any other soundcard that you have. Also, make sure that you open ffado-mixer and set the output to “Aux 1/2”.

Test the sound output by loading up any application that uses PulseAudio. Even playing a YouTube video will do. Hopefully this will be all that you need to do. It’s also worth noting that if you do wish to use your ProjectMix for audio recording/mixing on Linux, applications like Ardour will work just fine alongside your PulseAudio sink.

If you have any issues or concerns, comment below and I’ll do my best to help.

Hope this has been of some use!