fix(memory): ignore CPU and DMA writes to the Game Pak ROM windows

Stores to 0x08-0x0c returned ReadOnly and stopped the machine. Hardware ignores
them, and a second game's boot code stores to a ROM mirror. Emulated writes now
pay their bus cost and change nothing. The 0x0d window stays a diagnostic until
EEPROM is modeled there, and host writes stay strict.

Tests that used a ROM store as their failing write now cross an ignored ROM
word into the 0x0d window.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HhfHfHEuzv2AUTd6erW1gU
This commit is contained in:
0xrsydn 2026-10-14 08:26:03 +07:00
commit 258fbff2fa
25 changed files with 86 additions and 74 deletions

View file

@ -52,9 +52,9 @@ Byte writes are diagnostic because the consulted bus-width description is uncert
Byte, halfword, and word reads use ordinary little-endian lanes, including register/ROM boundaries.
Only the documented first-window addresses are implemented.
Other ROM windows still expose supplied ROM bytes; their writes remain read-only diagnostics.
Other ROM windows still expose supplied ROM bytes; CPU and DMA writes there are ignored like other ROM writes.
GPIO mirroring and writes at alias addresses have not been independently validated.
Without explicit hardware selection, all these addresses remain ordinary read-only cartridge memory.
Without explicit hardware selection, all these addresses remain ordinary read-only cartridge memory, so CPU and DMA writes are ignored.
## RTC command and control transfers

View file

@ -33,9 +33,10 @@ It does not decode archives or ELF executables. Supply a raw binary with an ARM
Headerless original programs are accepted.
Reads past supplied cartridge bytes remain explicit memory errors, not open-bus values.
All three Game Pak ROM windows use the same supplied bytes and existing wait-state rules.
Ordinary cartridge bytes remain read-only.
Ordinary cartridge bytes remain read-only. CPU and DMA writes to the `0x08`–`0x0c` ROM windows pay their bus cost and are ignored, as on hardware.
Writes to the `0x0d` window remain `ReadOnly` diagnostics until EEPROM is modeled there. Host `Memory::write*` calls stay strict everywhere.
Optional `--save-type flash64` or `--save-type flash128` enables [nominal Flash programming, erase, and reads](saves.md).
Without `--save-file PATH`, changes remain volatile. With it, the frontend loads an exact-size image and persists changes on clean exit.
Without `--save-file PATH`, changes remain volatile. With it, the frontend loads an exact-size image and persists changes on clean exit or when a ROM window ends on a diagnostic.
Missing images start erased. Existing images receive unique backups before replacement; incomplete Flash operations refuse persistence.
Read the [storage safeguards and limits](saves.md#desktop-persistence) before using a valuable save.
Optional `--rtc` selection enables the bounded [Game Pak GPIO and RTC calendar interface](cartridge-gpio.md).

View file

@ -68,7 +68,7 @@ Writes into the mapped 16 KiB BIOS [complete without changing its image](bios.md
Source reads, channel data, address progression, timing, and completion IRQs still apply to these ignored writes.
DMA0–2 mask destination bit 27, so a programmed cartridge address can instead select the BIOS region.
Other accesses use the existing memory map, alignment checks, mirrors, and I/O write rules.
Other unmapped reads and cartridge writes remain diagnostics, not general DMA open-bus behavior.
Other unmapped reads remain diagnostics, not general DMA open-bus behavior. Writes to the `0x08`–`0x0c` ROM windows are ignored; the `0x0d` window remains a diagnostic.
A failed unit changes no memory, device state, or clock. Earlier units remain committed; the failed unit remains pending.
Successful units update local IWRAM lanes for their actual IWRAM reads and writes, in that order.
No CPU continuation is required; DMA can establish lanes before the first CPU instruction.

View file

@ -91,6 +91,9 @@ folding plus write-ignore semantics need independent hardware evidence and
a deliberate policy decision against the explicit-error convention. See
[the usability roadmap](../usability-roadmap.md) for sequencing.
Update: emulated writes to the `0x08`–`0x0c` ROM windows are now ignored, which removes the
`0x09fe2ffe` store diagnostic. Reads past the end of the image remain explicit errors.
## References
- [GBATEK memory map](https://problemkaputt.de/gbatek-gba-memory-map.htm):

View file

@ -75,7 +75,7 @@ Update this file when a feature lands or a limit is removed.
- Stack save/restore, PC loads, empty register lists, and ARM7 base-register overlap rules.
- `SWP`/`SWPB`, including unaligned word rotation and register aliases.
- 256 KiB external work RAM and 32 KiB internal work RAM, including mirrors.
- Read-only cartridge bytes in the three GBA cartridge windows.
- Read-only cartridge bytes in the three GBA cartridge windows; emulated writes below the `0x0d` window are ignored.
- Explicit cartridge RTC selection with first-window GPIO read enable, direction/latch behavior, and serial calendar/control transactions.
- Validated RTC date/time, BCD transfers, read snapshots, complete writes/reset, and caller-supplied battery-clock advancement.
- Desktop `--rtc` seeds UTC once and supplies host elapsed seconds independently of CPU cycles and STOP.
@ -230,7 +230,7 @@ Host inspection and instruction fetches remain strict. Other unmapped reads retu
Reads beyond the supplied cartridge bytes also return errors.
Direct memory-bus halfword and word accesses require alignment.
CPU load/store instructions apply ARM7TDMI alignment and rotation rules before accessing the bus.
Ordinary ROM writes remain read-only. Explicitly selected cartridge GPIO and supported Flash command writes are separate from ROM storage.
CPU and DMA writes to the `0x08`–`0x0c` ROM windows are ignored; the `0x0d` window stays diagnostic until EEPROM exists. Explicitly selected cartridge GPIO and supported Flash command writes are separate from ROM storage.
## Next steps

View file

@ -65,7 +65,7 @@ A reproducible source build or an accessible upstream ROM is needed before recor
Next implementation steps:
1. Visible startup/menu progress is established: attract mode reaches the start menu and Birch dialogue, and sparse taps reach the in-game start menu by 12,000 frames ([probe](research/emerald-visible-progress.md)).
The first demonstrated second-game failure is a boot-init halfword store to ROM mirror `0x09fe2ffe` (recorded, not fixed).
The first demonstrated second-game failure is a boot-init halfword store to ROM mirror `0x09fe2ffe`. ROM-window writes are now ignored; reads past the image end remain diagnostics.
Use original regressions for any hardware correction; do not invent connected serial devices.
2. Validate an external game's completed save/restart/load cycle using a disposable `--save-file` path.
Refine nominal Flash timing and polling only with independent evidence and original regressions.