Cartridges, save memory & peripherals
Understand ROM access, SRAM, Flash and EEPROM protocols, plus cartridge clocks and sensors.
On this page
A GBA cartridge can contain more than the program a game executes. It may also provide persistent save memory, a clock or a sensor. Loading the ROM supplies the program and graphics data, but GBAx must separately model the behaviour of those extra devices when the game tries to use them.
This is why “the game starts” and “the game saves correctly” are different compatibility questions. The first can work even when the expected save protocol or peripheral is not behaving correctly.
ROM and save memory have different lifetimes
The ROM is the game’s program and read-only data. Working RAM holds temporary state while the game runs. Cartridge save memory stores the progress the game chooses to preserve. A saved position in the game is not the same thing as copying all of RAM or taking an emulator snapshot.
GBAx keeps an emulated save device and connects its persistent data to a host file. The game still performs the reads, writes and commands it would use on a cartridge. The emulator translates those operations into changes in the device model and, through its save-file handling, into data that can survive closing the application.
| Save hardware | How software interacts with it | What emulation must reproduce |
|---|---|---|
| SRAM | Reads and writes addressable bytes. | Addressing, byte access and persistent contents. |
| Flash | Uses command sequences for identification, programming, erasing and, where applicable, banking. | A command/state machine as well as the data array. |
| EEPROM | Sends a serial command/address/data sequence through the cartridge interface, often using DMA. | Bit-level protocol state, transfer lengths and stored blocks. |
Why Flash needs a command state machine
A Flash chip is not ordinary writable RAM. A game may send a sequence that puts it into a programming or erase mode. The meaning of a later write depends on that sequence and the device’s current state. Writing every supplied byte directly into a file would misinterpret commands as save data.
The reviewed savedata.c implementation maintains command and device state, handles Flash operations and supports the relevant save sizes/banks. When investigating a failed save, the sequence of accesses is therefore as important as the final address and value.
For example, a game that expects an erase operation followed by programming must observe the correct intermediate behaviour. It may check identification or completion-related responses before continuing. A mismatch can produce an in-game “save failed” message even though the host directory is writable.
EEPROM connects cartridge emulation to DMA
EEPROM communication is serial: a transfer carries command bits, address bits and data in a defined order. The core accumulates that protocol state, determines whether the operation is a read or a write, and produces the expected response sequence.
GBA DMA handling includes a path for EEPROM transfers. That is a concrete example of hardware components interacting: transfer length and remaining-count information can help the save device interpret what the game is sending. EEPROM cannot be treated as a normal byte array at the same address used by SRAM.
If you are tracing this path in the source, follow both GBASavedataWriteEEPROM and its caller in dma.c. Looking at only the file-writing code misses how the game’s original protocol reaches the save buffer.
Detection and game-specific configuration
The core supports save-type autodetection and explicit type selection. It also has game-specific overrides. These mechanisms help establish which device a game expects; a ROM filename alone is not a reliable description of its save hardware.
Changing the save type casually can reinterpret existing data or create a different-sized file. If a game reports a problem, preserve the original save before testing another setting. Record the exact game revision, patch status and emulator build. Two releases with the same familiar title can differ internally.
Real-time clocks and sensors
Some cartridges expose additional hardware through GPIO-style registers and other cartridge interfaces. The reviewed GPIO implementation includes real-time-clock handling and sensor-related state. A clock transaction involves control lines and command bytes; it is not simply a game asking the operating system for the current date.
The emulator must supply a meaningful input to the device model. A host clock can provide time, and frontend controls or supported devices can provide sensor values. Whether a particular sensor is conveniently exposed to a player depends on the frontend and build, not only on the presence of a core implementation.
This distinction matters for browser play. A browser having a motion sensor API does not automatically connect it to every emulated cartridge peripheral. The current website does not promise that all special cartridge hardware is supported through its player interface.
Game saves versus save states
A game save contains the data the game writes to its persistent device. A save state captures a much broader emulator state: processor registers, RAM, hardware registers, scheduling state and other details needed to continue a running session. The reviewed serialization code also records information used to recognise the state format and game.
Because a state depends on implementation details, moving it between different core versions or between native GBAx and a browser core is less predictable than transferring a compatible normal game save. Some state formats can include additional savedata, and load options affect how that data is handled. Treat restoring a state as restoring an earlier machine context, not merely selecting a screenshot.
Protect progress while investigating
First close the game cleanly and preserve a copy of its normal save. Keep the original game revision and record where GBAx is configured to store saves. Test with a copy, then confirm that the game can load the expected progress after a fresh launch—not only immediately after a state restore.
The Saves, states & backups guide gives a practical backup and transfer workflow. For the timing of EEPROM-related transfers and other cartridge accesses, continue with Timers, DMA & interrupts.
Sources & implementation
Implementation references follow GBAx 2.0.0 Preview 1, commit c1a826ae. The hardware implementation derives from mGBA; these links point to the matching GBAx source, rather than assuming a newer upstream revision behaves identically.
Need help with a specific problem? Start with troubleshooting →
