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.
Repeat the mapped PC+4 halfword for Thumb code in EWRAM, palette RAM, VRAM, and ROM. Use the aligned PC+4 word for BIOS/OAM. Keep retained BIOS history separate from current unused-memory reads. Reuse one instruction snapshot without extra data cycles or host/fetch/DMA fallbacks.
Keep IWRAM and 16 MiB region-crossing fetches diagnostic until prior bus history is modeled. Add original regressions for regions, alignments, mirrors, physical wrap, signed and unaligned loads, block/stack/PC loads, aliases, modes, short ROMs, strict errors, BIOS isolation, and nominal device progression. Record documented rules and remaining limits.
Darwin arm64 validation: 890 workspace tests and 821 core/demo tests in each of debug and release; 39 preparation tests; native ROM windows in both profiles; ten window/graphics smoke modes; fmt, clippy, and rustdoc. Public ARM, Thumb, memory, and BIOS reports remain identical to previous passing results and between profiles. No physical-hardware or independent public Thumb open-bus conformance claim.
Snapshot the full word at (executing PC+4)&~3 for Thumb BIOS execution, using strict image reads and incoming instruction state. Keep ARM PC+8 open bus separate and unchanged. Commit snapshots only after successful steps; preserve diagnostic behavior for unavailable lookahead.
Add original regression coverage for both code alignments, load widths and lanes, signed and unaligned values, processor modes, sequential fetches, ARM/Thumb transitions, SWI, RAM-backed POP exits, BIOS boundaries, failure retention, and nominal device progression. Record source evidence and explicit pipeline/hardware-validation limits.
Darwin arm64 validation: 878 workspace tests and 809 core/demo tests in each of debug and release; 39 Python tests; native ROM window tests in both profiles; ten window/graphics smoke modes; fmt, clippy, and rustdoc. Public ARM, Thumb, memory, and BIOS reports match prior passing reports and match between profiles. No physical-hardware validation claimed.
Place skipped compatibility data at boot, SoftReset, SWI, and IRQ exit PC+8 locations. Preserve the real IRQ callback return instruction as its readback word. Keep CPU and memory behavior image-derived, including caller-supplied images.
Add original boundary, load-lane, caller-state, wait, supplied-image, and builder-fixup regressions. Document the historical failures, research decision, passing public BIOS checkpoint, and remaining fetch-history limits.
Validated on Darwin arm64: 868 workspace tests in debug and release; 799 core/demo tests separately in both profiles; 39 preparation tests; native ROM window tests in both profiles; ten graphics/window smoke modes; fmt, clippy, and rustdoc. Hash-verified public ARM, Thumb, memory, and BIOS suites pass unchanged with identical debug/release reports. BIOS: r12=0, 17606 steps, 197456 nominal cycles, one IRQ entry.
Compare the current trace with GBATEK, the pinned public test, Smolka firmware analysis, and mGBA software BIOS behavior. Distinguish generic image-derived protection from replacement firmware compatibility. Plan guarded PC+8 compatibility data in the generated BIOS instead of test-specific bus overrides.
Retain the supplied image PC+8 snapshot after successful ARM BIOS instructions. CPU data reads from outside BIOS use its byte lanes; reads inside BIOS and host inspection remain mapped reads. Keep nominal timing and diagnostic atomicity. Unknown history, Thumb BIOS execution, and missing lookahead remain explicit limits rather than guessed values.
Add original regressions for ARM/Thumb callers, all CPU modes, widths and rotation, synthetic SWI/IRQ returns, original boot provenance, context isolation, history invalidation, and device progress. No Nintendo firmware or opcode constants are used to synthesize results.
Darwin arm64 validation: 861 workspace tests and 792 core/demo tests in debug and release; 39 Python tests; native ROM windows; all ten demo smoke tests; fmt, clippy, rustdoc, and docs links. Public ARM, Thumb, and memory ROMs still pass. The public BIOS ROM still fails firmware-specific test 1, now reading its actual replacement-BIOS prefetch rather than raw vector bytes.
Add --suite bios with hash-verified upstream files and the ARM evaluation checkpoint at 0x08000248. Preserve the r12=0 assertion, original BIOS boot, and all test bytes. Add synthetic adapter and CLI regressions.
On Darwin arm64 the public ROM fails test 1 in debug and release after 64 steps and 543 nominal cycles. Document that this tests protected reads of Nintendo firmware opcodes, not general BIOS service compatibility. Online and offline preparation agree; 39 Python tests pass. Core behavior is unchanged.
Add --suite memory with verified source hashes, ARM eval checkpoint 0x08000350, and the r12 result assertion. Keep default ARM and explicit Thumb preparation unchanged. Extend offline adapter and CLI tests; retain public binaries outside tracked files.
The unmodified memory ROM passes in debug and release after 174 steps and 1478 nominal cycles, without changing core behavior. Document weak byte-write assertions and mode-selection caveats. Add original CPU-driven tests with exact sentinels, mode/mirror boundaries, byte lanes, forced blank, readback, and nominal device timing.
Validated on Darwin arm64: 851 workspace tests in debug and release; 782 core/demo tests separately; 30 Python tests; all three pinned public suites in both profiles; native ROM windows; all ten demo smoke tests; fmt, clippy, rustdoc, and local documentation links.
Correct the shared Thumb block-store PC offset from four to six bytes. Retain ARM PC+12, 64-byte empty-list writeback, normal load behavior, alignment, flags, and nominal timing. Correct prior internal expectations and add original regressions for bases, banks, alignment, ROM windows, writeback, clocks, and atomic errors.
The pinned public Thumb ROM now passes its unchanged ARM-state r7 checkpoint after 807 steps and 4170 nominal cycles. The pinned ARM ROM still passes. Neither external ROM nor result assertion is modified.
Validated on Darwin arm64: 848 workspace tests in debug and release; 779 core/demo tests separately; 21 Python adapter tests; both public suites in both profiles; native ROM-window tests; all ten demo window smoke tests; fmt, clippy, rustdoc, and local documentation links.
Add --suite thumb while retaining default ARM preparation. Verify hashes, the Thumb-to-ARM evaluation bridge, and the result checkpoint; retain upstream provenance outside tracked files. Expand offline synthetic adapter and CLI regressions.
Darwin arm64 baseline: the unmodified Thumb ROM reaches ARM eval at 0x08000934 after 771 steps with r7=229 in debug and release. ARM remains passing. Online/offline preparation agrees and all 21 Python tests pass. CPU behavior is unchanged.
Snapshot mapped PC+8 bytes for ARM data reads in the documented unused ranges. Preserve strict host/fetch/Thumb/DMA diagnostics, missing-ROM errors, existing write rules, and nominal timing. Add original regressions and document the bounded model.
The unmodified pinned jsmolka ARM ROM now reaches its verified checkpoint with r12=0 in debug and release: 1344 steps and 11257 nominal cycles. No ROM, manifest, or assertion changes.
Validated on Darwin arm64: 842 workspace tests in debug and release; 773 core/demo tests separately; Python adapter tests; native ROM windows; all ten demo window smoke tests; fmt, clippy, and rustdoc.
Allow ARM LDR/LDRB/LDRH/LDRSB/LDRSH to share non-PC base and destination registers with writeback. Keep the loaded value after computing addresses from incoming operands. Preserve PC restrictions, unsupported user transfers, store behavior, and atomic memory diagnostics.
Add original regressions for index modes, offsets, widths, alignment, sign extension, all active banks, timing, I/O/IRQ ordering, and failures. The unchanged pinned public ARM ROM progresses past tests 360 and 361, then fails at test 362 on an unmapped 0x80000000 read; no full-suite pass is claimed.
Verified on Darwin arm64: debug/release workspace and core suites, Python adapter tests, Clippy, rustdoc, native ROM-window checks, and all ten demo smoke tests. Document the new behavior and next memory-access blocker.
Add a standard-library Python adapter and SHA-256/size lock for jsmolka/gba-tests ARM at a7113b67e63f83a9b321696ddd7042ccfad6c881. Retain sources and license locally, refuse tracked output paths or overwrites, verify offline inputs, and generate the source-verified eval/r12 suite checkpoint without patching the ROM.
Add Python to the pinned Nix shell, offline adapter regressions, and public-test provenance/results documentation. Verified on Darwin arm64: Rust debug/release workspace tests, adapter tests, Clippy, rustdoc, native ROM and all demo window checks. The public test remains a failing baseline at instruction 0xe5b00004, PC 0x0800132c, in test 360.
Restore CPSR from SPSR for ARM TST/TEQ/CMP/CMN with unused Rd=15 when the current mode has an SPSR. Preserve sequential PC and nominal timing; use normal ALU flags in User/System. Keep ordinary result-writing PC return validation unchanged.
Reproduced independent jsmolka/gba-tests ARM failure 234 before this fix. Original regressions cover flags, masks, bank restoration, operand forms, conditions, timing, and atomic errors. The public ROM progresses to a separate unsupported load/writeback alias at test 360; no full public-suite pass is claimed.
Read strict versioned suite manifests with independent ROM cases, explicit ARM/Thumb checkpoints, register/CPSR/memory assertions, and aggregate step limits. Report every case deterministically and fail on timeouts, STOP, diagnostics, missing files, or mismatches. Keep host JSON dependencies outside the core.
Add an original ARM/Thumb/BIOS suite generator, unit and process-level regressions, and schema/usage documentation. Verified on Darwin arm64 with debug/release workspace and core suites, Clippy, rustdoc, native ROM-window tests, all ten demo smoke tests, repeatable release reports, and a deliberate assertion failure. Independent public hardware-test ROM validation remains next.
Add --rom PATH --window with optional bounded --frames execution. Capture from BIOS boot, pump native events between bounded machine slices, retain frames during STOP, and sample keypad input for wake-up. Share final machine reports with terminal mode.
Add an original file-exportable input ROM, controller and CLI regressions, and opt-in native window tests. Document controls, frame limits, STOP behavior, and compatibility limits. Verified on Darwin arm64: debug/release workspace and core tests, Clippy, rustdoc, native ROM diagnostics, all ten demo smoke tests, and a 60-frame release ROM run.
Load read-only raw ROM files with bounded size checks and original BIOS boot. Require a machine-step budget and report CPU state, STOP, and explicit diagnostics without opening a window. Keep file access in the desktop crate.
Cover argument parsing, Darwin paths, file boundaries, ARM/Thumb execution, DMA/IRQ budgets, HALT/STOP, and error reports. Document limits and usage. Verified on native Darwin arm64: debug/release workspace tests, core-only tests, Clippy, rustdoc, all ten window smoke tests, and a release raw-ROM run.
Separate Running, Halt, and Stop states. Complete the entering instruction before freezing CPU, DMA, timers, display, and externally supplied clock advances. Wake STOP through the live enabled keypad condition without creating a clock-off IF request.
Implement original ARM SWI 0x03, preserve caller state, and expose zero-cycle StopIdle plus stopped frame-runner results. Retain DMA state, timer phase, and captured frames across sleep. Document keypad-only wake and unverified oscillator/edge timing.
Add core, BIOS, and demo regression tests; preserve BIOS-only access and failed-store isolation. Validated on Darwin arm64 with debug/release workspace and core/demo suites, Clippy, rustdoc, ten native window smoke tests, and terminal demos.
Add a dependency-free keypad state machine in gba-core, map KEYCNT, latch IF bit 12, and wake HALT through the existing interrupt gates. Sample complete CPU/DMA control writes once so transient byte values cannot create false requests.
Document the mGBA-style polling policy and its unverified hardware retrigger limits. Cover every button-state/selection pair, register masks, repeated requests, byte/word writes, failed-store isolation, DMA priority, ARM/Thumb IRQ return, BIOS IntrWait, and retained BIOS reset state.
Follow the restructured workspace and modular documentation. Validated on Darwin arm64: workspace and core/demo tests pass in debug and release, with Clippy, rustdoc, ten native window smoke tests, and terminal demos passing.
Move the README's hardware notes, demo controls, environment setup, test
notes, file map, and references into docs/ and docs/hardware/. The README
is now an overview with a docs index. AGENTS.md gives coding agents a short
map of crates, commands, and where to read and write documentation.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Move the emulator into crates/gba-core, the original demo programs into
crates/gba-demos, and the minifb frontend into crates/desktop. The binary
is now gameboy-rust. Imports change from gba_rust to gba_core/gba_demos;
no behavior changes.
gba-core has no dependencies. Its integration tests use gba-demos as a
development dependency.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Execute SWI 0x01 through original ARM code. Clear selected work RAM, palette RAM, VRAM, and OAM; force blank; reset supported display, DMA, timer, and interrupt registers through normal bus writes. Preserve caller state and excluded BIOS work RAM apart from the common SWI frame.
Reject serial/sound reset flags before display or reset writes. Document the supported subset, timer counter behavior, DMA ordering, and RAM caller hazards. Add fifteen tests covering memory flags and boundaries, I/O defaults, rendering, register preservation, hidden device latches, diagnostics, and device progress.
Validated on Darwin arm64: 720 default and 709 core-only tests in debug and release; formatting, Clippy, rustdoc, ten native window smoke tests, and CPU/timer demos pass.
Execute SWI 0x00 through original ARM code. Read the restart flag before clearing 512 bytes of BIOS work RAM, reset System/SVC/IRQ stacks and specified registers, then branch to ROM or EWRAM in ARM System mode.
Keep device state and clocks active, preserve unrelated CPU banks, and document the deterministic IRQ-masked restart status. Add eleven tests for every flag byte, ARM/Thumb and User/System callers, exact memory bounds, bank state, restart execution, DMA/timers, and unsupported exception callers.
Validated on Darwin arm64: 705 default and 694 core-only tests in debug and release; formatting, Clippy, rustdoc, ten native window smoke tests, and CPU/timer demos pass.
Execute BgAffineSet and ObjAffineSet through original ARM routines with a mathematically generated sine table. Preserve caller state, validate record spans and strides, and use normal bus writes for background registers and sprite matrices.
Add independent matrix/origin references, all-phase coverage, rendering integration, diagnostics, stack and DMA checks. Extend image construction with multiple literal pools and reserved table bounds. Document formats and compatibility limits.
Validated on Darwin arm64: 694 default and 683 core-only tests in debug and release; formatting, Clippy, rustdoc, ten native window smoke tests, and CPU/timer demos pass.
Add SWI 0x09 and 0x0a as original ARM routines. Evaluate the fixed-point angle polynomial with wrapped products, reduce ArcTan2 ratios with integer division, and handle axes and quadrants. Require sign-extended 16-bit inputs and preserve non-result caller registers.
Add 15 regression tests for fixed-point and floating-point references, signed limits, rounding, quadrant boundaries, caller flags, stack bounds, repeated calls, and DMA/IRQ progress. Validate 671 default and 660 core-only tests in debug and release, plus all 10 native Darwin ARM64 window smoke tests.
Implement SWI 0x13 for 4-bit and 8-bit symbols. Traverse forward-offset trees using MSB-first input words and pack symbols into complete output words. Validate visited edges, leaf widths, alignment, output lengths, and address bounds.
Add 21 regression tests with independent tree serialization and path encoding, deep/max-size trees, word-boundary refills, malformed input, partial failures, caller state, and DMA/IRQ progress. Validate 656 default and 645 core-only tests in debug and release, plus all 10 native Darwin ARM64 window smoke tests.
Add SWI 0x16, 0x17, and 0x18 as original ARM routines. Reconstruct samples with modular addition and byte or halfword output. Validate headers, alignment, lengths, and address ranges; preserve earlier completed writes on failure.
Add 17 regression tests for sample round trips, wraparound, large byte lengths, caller state, partial failures, bus behavior, and DMA/IRQ progress. Validate 635 default and 624 core-only tests in debug and release, plus all 10 native Darwin ARM64 window smoke tests.
Document the complete integrated implementation and native Darwin validation. This ordered initial import groups existing code by subsystem; earlier chunks can depend on later integration commits.