Select them with --save-type eeprom512 or eeprom8k. The part follows GBATEK's
protocol on Game Pak data bit 0: DMA3 sends one bit per halfword, '11' +
address + '0' requests a 64-bit block that reads back after four dummy bits,
and '10' + address + data + '0' writes one. A write reports busy for a nominal
108,368 cycles before the block is stored. 8 KiB parts decode the low 10
address bits. ROMs above 16 MiB map EEPROM only at 0x0dffff00..0x0dffffff.
Bits shift out only inside machine steps, so failed steps roll back. CPU
stores, byte/word accesses, CPU reads during a read-out, and malformed or
overlapping requests are diagnostics. Blocks are stored first-bit-as-MSB,
matching common .sav layouts, and work with save files and save states.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HhfHfHEuzv2AUTd6erW1gU
CPU and DMA reads past the supplied image returned Unmapped and stopped the
machine; a second game's boot code reads 0x09fe20f8 past a 16 MiB image. The
Game Pak shares data lines with the low address lines, so where no chip drives
the bus a read returns the halfword address, (A >> 1) & 0xffff, per lane
(GBATEK; mGBA uses the same pattern).
The chip is the image size rounded up to a power of two. Bytes between a
trimmed image's end and that boundary are unknown and stay diagnostic, as do
host reads and instruction fetches. Two truncation fixtures move into that gap.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HhfHfHEuzv2AUTd6erW1gU
Select it with --save-type sram (SaveDevice::Sram). The array is byte-wide,
starts erased, and repeats every 32 KiB through the 0x0e00xxxx save window.
A CPU byte store is staged and committed when its step completes, so failed
steps roll back and reads later in the step see the byte. Unlike Flash, SRAM
can be read from ROM code. Halfword/word access and DMA stay diagnostic until
the 8-bit bus behavior for those widths is verified.
SRAM shares the save-image API, host save files, and save states. Its device
code is new, so existing save states keep loading.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HhfHfHEuzv2AUTd6erW1gU
Stores to I/O addresses with no register returned Unmapped and stopped the
machine. Hardware ignores them. Emulated writes there now pay their bus cost and
change nothing; host writes stay strict. The unmodeled internal memory control
register at 0x04xx0800 and all unused I/O reads remain diagnostics.
Rollback tests that used unused I/O as their failing word now run the block on
to a register that rejects the stored value: SIOMULTI2 outside multiplayer
mode, an RCNT GPIO serial IRQ, or 64-sample wave playback. Where no reachable
register can fail (JOYSTAT, POSTFLG/HALTCNT, IME, DMA3CNT), the test now checks
that the block commits and the unused word is ignored.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HhfHfHEuzv2AUTd6erW1gU
MUL/MLA with Rd=Rm and long multiplies with RdHi or RdLo equal to Rm returned
UnsupportedInstruction and stopped the machine. The ARM7TDMI reads every
operand before writing the result, so these forms execute normally. R15
operands and RdHi=RdLo remain diagnostics.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HhfHfHEuzv2AUTd6erW1gU
DISPCNT enable bits for BG3 in Mode 1, BG0/BG1 in Mode 2, and every background
but BG2 in Modes 3-5 failed the whole frame with UnsupportedLayers, and the
window turned that into a stopped session. Hardware has no such backgrounds and
ignores the bits, so the renderer now masks them. The error variant is removed.
Prohibited OBJ mode 3 and shape 3 stay diagnostics: their hardware output is
not established here.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HhfHfHEuzv2AUTd6erW1gU
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
A core, DMA, rendering, window, or audio error returned before the save was
written, so every completed in-game save since launch was lost. The window now
writes changed bytes on that path too. The diagnostic stays the session error;
a refused or failed write is reported as output. A failed state restore leaves
save memory undefined and is never written. Terminal runs keep the strict rule.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HhfHfHEuzv2AUTd6erW1gU
Machine::save_state and load_state encode the CPU, every RAM, and every device
through Snapshot impls into a versioned, checksummed format. Rejected loads leave
the machine unchanged. The ROM window saves to and loads from one state file
with F5 and F9.
Buffer ARM sequential fetch results and refill target pairs after branches, PC writes, and machine exception entry. Stage advances transactionally, defer speculative fetch diagnostics, and preserve buffered words across CPU/DMA stores and host edits. Add explicit CPU pipeline invalidation for debugger repair and memory rebinding.
Add 15 original instruction-buffer regressions. Keep full-state rollback equality while distinguishing architectural comparisons in semantic tests. Update the display error test for an already buffered branch. Document evidence and separate remaining Thumb, bus-history, and timing work.
Validated on Darwin arm64: 967 workspace and 898 core/demo tests in each debug/release profile, 39 Python tests, native ROM windows, ten window smoke modes, fmt, clippy, and rustdoc. Public ARM/Thumb/memory/BIOS reports and nominal cycles remain unchanged.
Retain one pending non-sequential resume after successful DMA. Apply it to the next nominal non-refill code access and consume it only on successful CPU or IRQ progress. Preserve failed-step atomicity, host and idle isolation, existing refill costs, and WAITCNT ordering.
Add 13 original regressions for ARM/Thumb widths, ROM wait settings, sources, preemption, retries, mixed APIs, idle states, and interrupt timing. Record pinned hardware-test source and emulator evidence without claiming physical-hardware or full-pipeline conformance.
Validated on Darwin arm64: 952 workspace and 883 core/demo tests per debug/release profile, 39 Python tests, native ROM windows, ten window smoke modes, fmt, clippy, and rustdoc. Public ARM/Thumb/memory/BIOS reports remain unchanged.
Update existing Thumb IWRAM continuation lanes from successful DMA reads and writes before the resumed PC+4 snapshot. Keep channel halfword duplication separate from actual lane accesses. Preserve atomic errors, cold-entry diagnostics, IRQ invalidation, and nominal timing.
Add original DMA matrices and resume regressions; update prior invalidation expectations. Record pinned ares and jgenesis evidence and explicit limits for cross-state history, general open bus, and sub-instruction arbitration.
Validated on Darwin arm64: 939 workspace and 870 core/demo tests per debug/release profile, 39 Python tests, native ROM windows, ten window smoke modes, fmt, clippy, and rustdoc. Public ARM/Thumb/memory/BIOS reports remain identical to the previous results.
Retain independent known data across DMA blocks. Duplicate mapped halfword sources and select the destination lane for blocked sources below work RAM. Keep cold history diagnostic, commit only successful units, and preserve separate CPU/BIOS history rules.
Add 13 original regressions and pinned source research. CPU resume ownership, general DMA open bus, and IWRAM DMA lane effects remain explicit limits.
Validated on Darwin arm64: 930 workspace and 861 core/demo tests in debug and release, 39 Python tests, native ROM windows, ten window smoke modes, fmt, clippy, and rustdoc. Public ARM/Thumb/memory/BIOS reports match the previous results exactly.
After successful refill instructions, sample the Thumb IWRAM target and target+2 halfwords to establish bus history. Share ARM/Thumb refill classification with nominal timing. Respect restored instruction state, completed data accesses, region limits, and diagnostic rollback; keep instruction execution and nominal costs unchanged.
Add original regressions for ARM/Thumb BX, Thumb branches and BL, PC writes, stack/block PC loads, status-restoring returns, real SWI/IRQ returns, both target alignments, mirrors/wrap, captured sample ordering, load lanes, failure retention, BIOS isolation, and DMA invalidation. Document official ARM7TDMI refill evidence and the distinction from a full pipeline.
Darwin arm64 validation: 917 workspace tests and 848 core/demo tests per debug/release profile; 39 preparation tests; native ROM windows in both profiles; ten graphics/window smoke modes; fmt, clippy, and rustdoc. Public ARM, Thumb, memory, and BIOS reports remain identical to prior passing results and between profiles. Cold startup, ARM-target refill history, and DMA-to-CPU ordering remain incomplete; no hardware-conformance or commercial-game claim.
Track a separate IWRAM latch with known lanes and transactional updates. Sequential Thumb prefetches and IWRAM byte/halfword/word reads and writes drive only addressed lanes. Other regions and host inspection do not replace the latch. Failed instructions discard staged changes.
Keep cold, refill, discontinuous-entry, IRQ, and DMA-transition history conservative. Share Thumb refill classification with nominal timing, including PC writes to fallthrough. Successful DMA and accepted machine IRQs invalidate history; failed DMA preserves it. Document source evidence, bounded scope, and remaining hardware-validation limits.
Add original lane, alignment, mirror/wrap, signed/unaligned-load, mode, block-transfer, rollback, isolation, control-flow, IRQ/DMA, and nominal-cost regressions. Darwin arm64 validation: 905 workspace tests and 836 core/demo tests per debug/release profile; 39 preparation tests; native ROM windows in both profiles; ten graphics/window smoke modes; fmt, clippy, and rustdoc. Public ARM, Thumb, memory, and BIOS reports remain identical to prior passing reports and between profiles.