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.
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.