Emulators

GBA Emulator: Part 1 — Getting Started

Project: GBA Emulator
My face (pixelated)
By Sa'id K on 10 Mar 2025 (Draft)
A banner for this blog post, displaying a GBA motherboard.

Why a GBA Emulator

Having completed a CHIP8 emulator, I looked for my next emulation project and landed on the GBA. It’s a big step up from CHIP8, but I think it’s a relatively manageable project, especially since I will be focusing on implementing the “GB” part before the “A” part.

My overall goal is to contribute to larger emulation projects, and I see this as a step in that direction. I am hoping that once this project is complete, I’ll have a much better understanding of emulation in general than CHIP8 could have given me.

Major Goals

Learn C++

Though I have worked with C++ a few times throughout my years programming, I have never made a real effort to truly delve into the ecosystem. All of C++ projects have been pointed and specific enough that I didn’t need to pick up C++ as a language, just whatever extensions over C I needed to complete the job at hand. This project will serve as a true C++ starter, where I will attempt to utilize C++ to the fullest extent.

RISC-V as the Primary Target

There are many GBA emulators out there. There are very likely a few that could be built for RISC-V out of the box and run with around the same level of compatibility as you would expect on any other hardware platform. However, to my knowledge, there aren’t any (or at least many) GBA emulators that were written with RISC-V in mind as the primary compilation target.

This will be the main difference between this project and other GBA emulators. I foresee a lot of problems with SDL2 or whatever I/O library I end up picking, but it will serve as an awesome experience working directly with RISC-V hardware.

To clarify, all-platform compatibility is still the goal. However, RISC-V is the main platform I will be testing this on, and ensuring compatibility with x86_64 will come after.

Design Overview

Architecture Diagrams

Firstly, while doing the preliminary research for this project, I found this absolutely amazing website dedicated to dissecting console hardware and providing historical context to the development of their hardware and software. Thank you to Rodrigo Copetti for the irreplaceable work he has done on his website. Specifically, I used his breakdown of the GBA architecture to kick-start my brainstorming. The below architecture diagram is from his site:

GBA architecture diagram.

Initial Component Breakdown

Important to implementing the GBA architecture is understanding all of its parts and how they operate. Thankfully, hundreds if not thousands of hardware gurus have compiled a vast amount of information throughout the web about the different parts of the GBA and how they operate.

CPU

The GBA actually has two processors, which enables backwards compatibility with Game Boy games and higher performance for GBA games. Inside the GBA you will find both the Sharp SM83, which is the CPU that shipped with the Game Boy originally, and the ARM7TDMI. The SM83 is much simpler to implement, hence my intention to implement this first, before working on the ARM CPU. When one CPU is being used by a game, the other is switched off. Both CPUs are never running simultaneously.

This is the most standard part of the implementation. In general, there shouldn’t be too many surprises while implementing the instruction sets of each CPU. The resources I will use to implement the instructions will be provided in a future post, once I turn my focus to implementing the CPU.

The Game Boy CPU #### Bus

Contrary to what might actually be the best way to go about this implementation, I decided to implement the bus first, and then work on the CPU. I decided to go this route because the bus will be what decides much of the remainder of the architecture, and you don’t need to know much about the rest of your implementation to get it to a nearly-complete state.

The bus has a simple job: given an address (from the CPU), communicate with the destination module what address needs to be read from or written to. The logic for writing and reading will actually be handled while implementing the memory.

Memory

The memory design of the GBA is probably the second most complicated piece of the implementation, after the PPU. The GBA has several “types” of memory, distinguished by the memory ranges each one owns. Let’s walk through an overview of the different types of memory:

Address RangeTypeCompatibilityUsage NotesSize
0x00000000-0x00003FFFSystem ROM (bank 00)GB & GBABIOS; executable only, no write16 kB
0x00004000-0x00007FFFROM (bank 01-NN)GBSwitchable memory bank, helps to expand GB memory16 kB
0x00008000-0x00009FFFVRAMGBIn GCB mode, switchable bank 0/18 kB
0x0000A000-0x0000BFFFEWRAMGBWork RAM external to the CPU (cartridge)8 kB
0x0000C000-0x0000CFFFIWRAMGBWork RAM internal to the CPU (Bank 0, fixed).4 kB
0x0000D000-0x0000DFFFIWRAMGBWork RAM internal to the CPU (Bank 1-7, CGB mode only)4 kB
0x0000E000-0x0000FDFFEcho RAMGBThis memory should not be used. It mirrors 0x0000C000-0x0000DFFF< 8 kB
0x0000FE00-0x0000FE9FObject Attribute Memory (OAM)GBUsed for spite object attributes160 B
0x0000FEA0-0x0000FEFFNot UsableGBDo note use, according to Nintendo96 B
0x0000FF00-0x0000FF7FI/O RegistersGBGB and GBA use memory for handling I/O in this range128 B
0x0000FF80-0x0000FFFEHigh RAM (HRAM)GBProvides possibly faster accesses for the GB127 B
0x0000FFFFInterrupt Enable RegisterGBSignals that any interrupt has been called1 B
0x00010000-0x01FFFFFFF----
0x02000000-0x0203FFFFEWRAMGBAExternal (on-board) work RAM256 kB
0x02040000-0x02FFFFFF----
0x03000000-0x03007FFFIWRAMGBAInternal (on-die) work RAM32 kB
0x03008000-0x03FFFFFF----
0x04000000-0x040003FEI/O RegistersGBAMemory space for communicating with I/O1023 B
0x04000400-0x04FFFFFF----
0x05000000-0x050003FFBG/OBJ Palette RAMGBAInternal Display Memory1 kB
0x05000400-0x05FFFFFF----
0x06000000-0x06017FFFVRAMGBAInternal Display Memory - VRAM96 kB
0x06018000-0x06FFFFFF----
0x07000000-0x070003FFObject Attribute MmeoryGBASame with GB1 kB
0x07000400-0x07FFFFFF----
0x08000000-0x09FFFFFFGame Pak ROMGBAExternal Memory (Game Pak), 32 mB max32 mB
0x08000000-0x09FFFFFFGame Pak ROMGBAExternal Memory (Game Pak), 32 mB max32 mB
0x0C000000-0x0DFFFFFFGame Pak ROMGBAExternal Memory (Game Pak), 32 mB max32 mB
0x0E000000-0x0E00FFFFGame Pak SRAMGBAExternal Memory (Game Pak), 64 kB max, 8-bit bus width64 kB
0x0E010000-0x0FFFFFFF----

Thank you to gbdev.io and NOCASH for compiling this information for the respective consoles. I brought them together above to give an overview of what a fully backwards compatible GBA emulator would implement. Each address range has a respective “Compatibility” field to clarify which system uses which range. In general, you can bet that the GBA will use the higher address ranges (because it can) and the GB will use the lower address ranges (because it has to).

The memory design can get a little complicated, especially when factoring in banking. This is going to be a piece of the implementation I plan to develop as I go.

Components Next Up

I think implementing the CPU, Bus, and Memory will be enough of a challenge to start off, so I won’t focus on all the components now. However, the other components in (likely) implementation order are:

  1. Cartridge Reader - pull data from actual ROMs to start testing with.
  2. PPU - get graphical output from ROMs.
  3. Key Controller - add user I/O.
  4. Sound Generator - important, but sound probably won’t come until the end.

What’s Next?

It’s time to get started on the bus! The next blog post will cover the first few functions the bus will have to allow it to read and write memory. Alongside the bus, I will likely start the memory and CPU implementations as well (you need memory to read and write from).

Resources

Below is a list of all resources I utilized (and will be utilizing moving forward) to draft this hardware overview of the GBA. Thank you to the entire community for putting in all this work.


Get post updates sent to your inbox!

No spam, just new posts!

© Copyright 2025 by Sa'id Kharboutli.