Professional Documents
Culture Documents
Dhole's blog
articles categories about
Introduction
The following project consists on emulating the functionality of a GameBoy
cartridge with the development board STM32F4.
The system is fully functional
and is able to emulate real cartridges (as well as homebrew games) of the type
ROM Only and
MBC1 (Memory Block Controller 1). In this post I will explain
how I managed to achieve this.
Motivation
Current flashcart systems commonly use a design consisting on a FPGA or CPLD
controlling the logic of the emulated
cartridge (memory banking, RAM access,
etc.), a media storage (flash chip or SD card) and an SDRAM chip.
The way this flashcarts work is that upon booting the console, they present a
small program that list the ROMs available in
the media storage. The user selects
a game and the FPGA copies it from the media storage to the SDRAM to allow
fast
access. Once the ROM has been copied, the FPGA acts as a gateway mapping
the contents of the SDRAM to the original
cartridge mappings.
Since the GameBoy cartridges use small ROM chips for which one can find
compatible FLASH chips in the market, it is a
viable alternative to the FPGA
to take an original cartridge with a MBC5 and swap the original ROM chip with
a compatible
FLASH memory. A cartridge with MBC5 is often selected because with
it, games with ROM Only and games using MBC1 can
also be run (There is
compatibility). With this setup, the user is able to reprogram the FLASH many
times with different
games and play them on the GameBoy.
The FPGA system seems to allow much more freedom but it also involves more work:
the MBC5 (or the supported Memory
Block Controllers) must be implemented in
hardware, an interface to access the media storage must be designed, the circuit
must be designed too with all the components (FPGA/CPLD, FLASH/SD Reader, SDRAM,
…).
The hardware
For this project I choosed the STM32F4 Discovery. This development board features
an ARM Cortex-M4 which can run at
168MHz, with 1 MB Flash, 192 KB RAM and more than
70 GPIO. The GPIO are accessed through a peripherials bus that can
run at 100MHz.
I also considered other boards such as the Teensy 3.1 but I ended up choosing
the STM32F4 because it had
more Flash and RAM and because it was unexpensive (14€).
https://dhole.github.io/post/gameboy_cartridge_emu_1/ 1/6
2022/10/21 17:52 Emulating a GameBoy Cartridge with an STM32F4. Part 1 · Dhole's blog
On the other side, the GameBoy CPU runs at 4MHz. The comercial cartridges have
up to 512 KB of ROM and 128 KB of RAM,
although the MBC5 is capable of handling
bigger ROMs. Many cartridges have a MBC (Memory Block Controler) such as the
MBC5
or the MBC1. This controller allows the catridge to handle ROMs that don’t fit
into the GameBoy memory area
reserved for the cartridge ROM by means of bank
selection. This selections are performed by writting into specific areas of
the
memory map reserved for the ROM (So that the MBC can handle them).
logicdiscovery
The client used is the Logic Sniffer, an open source Java client compatible with
the SUMP protocol:
Logic Sniffer
In order to analyze the bus while the GameBoy was performing reads and writes to
the cartridge, I soldered an FDD ribbon to
the main board of the GameBoy,
intercepting the cartridge pins as follows:
Back of the GameBoy PCB with the cartridge pins soldered to a FDD ribbon.
Since only 16 channels are available for the logicdiscovery I decided to monitor
the CLK, RD, WR, CS, DATA {0-4} and ADDR
{0-8}. (That is, the lower 4 bits of
the data and the lower 8 bits of the address). With this we should be able to
get information
about the timings of the different operations.
https://dhole.github.io/post/gameboy_cartridge_emu_1/ 2/6
2022/10/21 17:52 Emulating a GameBoy Cartridge with an STM32F4. Part 1 · Dhole's blog
The GameBoy cartridge pinout is well known, so it’s easy to figure out what every
pin on the PCB of the GameBoy does
from a pinout picture:
Results
Upon analyzing the bus with the BATMAN game (ROM Only cartridge), the following is obtained:
The first thing I noticed is that the CLK is at 1MHz, this is good news for us:
we have more cycles for each operation. One
oddity I found with the capture is
that we can see that the WR goes low a few times (WR is active on low). The
BATMAN
cartridge doesn’t have RAM nor Memory Block Controller, so it doesn’t make
sense to write into it. Since we only have
half of the adressess, we can’t say
for certain where the data is being written, but my guess is that we are seeing
writes
being done to the internal GameBoy RAM.
We can take a closer look to a read and a write and analyze what’s happening and
when. This information will give us an
idea on when should we perform the reading
of the adresses for a write/read operation, and when to output the data on a
read operation.
Notice that we have a 20MHz sampling rate, this means that a sample is being
taken every 50 ns, leading to an error of +/-
25 ns.
https://dhole.github.io/post/gameboy_cartridge_emu_1/ 3/6
2022/10/21 17:52 Emulating a GameBoy Cartridge with an STM32F4. Part 1 · Dhole's blog
Read timings
Write timings
We can see that for a read operation, the GameBoy leaves WR and CS unactivate
(high) and the RD active (low). This is the
default. The GameBoy sets the
address 150ns after the CLK rise, and the data is available in the bus
(coming from the
cartridge) 200 ns later. We can’t say when the GameBoy reads
the data, but a guess would be around the CLK fall.
For the write operation, the RD is set to unactive at the same time the address
and the data is set in the bus (150 ns after CLK
rise). 100 ns later the CS is
activated. At the CLK fall, the WR is activated, allowing the cartridge to perform
the write for 300
ns. On the next cycle, we can see that RD and CS are reset to
the default state (low and high, active and unactive
respectively). Notice that
the CS (Chip Select) is not strictly needed, although it seems to be used only
when accessing RAM
(this is not clear).
https://dhole.github.io/post/gameboy_cartridge_emu_1/ 4/6
2022/10/21 17:52 Emulating a GameBoy Cartridge with an STM32F4. Part 1 · Dhole's blog
The writing timing analysis are sound with the analysis found in the unnoficial
GameBoy CPU Manual:
RAM timings, taken from the Game Boy CPU Manual. Click for detailed timings.
Now that we know that the information seen in the bus is not only the communication
between the GameBoy and the
cartridge but all the read/write operations of the
GameBoy to its memory map, we can understand the following capture,
which shows
a DMA operation (The GameBoy has a DMA functionality to allow to fast copy contents
from RAM or ROM to
the OAM (Object Atribute Memory), used by the screen to draw
sprites):
DMA in action
In the following post I will write about the implementation of the cartridge
emulator. Stay tunned!
Written by Dhole
https://dhole.github.io/post/gameboy_cartridge_emu_1/ 5/6
2022/10/21 17:52 Emulating a GameBoy Cartridge with an STM32F4. Part 1 · Dhole's blog
Show Comments
Later article
Older article
https://dhole.github.io/post/gameboy_cartridge_emu_1/ 6/6