gameboy-rust/docs/public-thumb-tests.md
0xrsydn 08c8705904 test(cpu): integrate pinned public Thumb compatibility suite
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.
2026-10-05 20:40:37 +07:00

81 lines
4.9 KiB
Markdown

# Pinned public Thumb test
The headless runner executes the unmodified Thumb ROM from [jsmolka/gba-tests](https://github.com/jsmolka/gba-tests).
It currently reaches its result checkpoint but fails test 229 on Darwin arm64 in debug and release builds.
This is an independent compatibility baseline, not complete ARM7TDMI conformance or a hardware measurement.
## Prepare and run
```sh
direnv exec . python3 tools/prepare_gba_tests.py /tmp/gba-public-thumb --suite thumb
direnv exec . cargo run --locked --release -- --test-suite /tmp/gba-public-thumb/suite.json > /tmp/gba-public-thumb-report.json
```
Use a new directory outside the repository or inside ignored `roms/`. The parent directory must exist.
The adapter checks every selected file's byte count and SHA-256 digest before creating output.
It retains the upstream sources, license, README, ROM, generated `suite.json`, and `source-lock.json`.
No source, binary, header, expected result, or instruction is patched or skipped.
Downloaded binaries and header sources must not enter tracked files.
Offline preparation uses the same checks:
```sh
direnv exec . python3 tools/prepare_gba_tests.py /tmp/gba-public-thumb-offline --suite thumb --source-dir /path/to/gba-tests
```
The existing [ARM command](public-arm-tests.md) remains the default. Explicit `--suite arm` selects the same ARM lock.
Each preparation creates one suite. The suite name does not select the checkpoint's instruction state.
Python comes from Nix and requires no extra packages. Ordinary unit tests use original synthetic data, without downloads.
Preparation is not a compatibility verdict. Inspect the runner's JSON result and exit status.
## Provenance and result protocol
- Repository: `jsmolka/gba-tests`.
- Revision: `a7113b67e63f83a9b321696ddd7042ccfad6c881`.
- Upstream project license: MIT, copyright Julian Smolka; retained with downloaded files.
- ROM: `thumb/thumb.gba`, 3,680 bytes.
- SHA-256: `b5cb2291df4ab314b31c598acd9bff2ccfa0b38efff29daadfe97422ce369b67`.
- Selected file hashes and sizes: [`tools/gba-tests-thumb.lock.json`](../tools/gba-tests-thumb.lock.json).
The adapter uses the upstream committed binary. No FASMARM rebuild or source-to-binary reproduction was performed on Darwin.
The entry code initializes the display, switches to Thumb, and initializes r7 to zero.
Each `m_exit` failure writes its test number to r7 and calls `tmain_end`.
Branch tests also use r7 as a progress marker, then reset it to zero on their successful path.
Successful completion of the memory tests reaches the same `tmain_end` with r7 still zero.
At this revision:
- `tmain_end` is Thumb code at `0x08000930`.
- `ADR r0, eval` (`0xa000`) and `BX r0` (`0x4700`) switch execution back to ARM.
- `eval` is ARM code at `0x08000934`, starting with `0xe92d0003`, the `m_vsync` register save.
- The later result macro reads r7, not the ARM suite's r12.
The source exit paths and binary Thumb `BL` targets were checked against `tmain_end`.
The adapter verifies the bridge and initial evaluation word, in addition to whole-file hashes.
The manifest stops before `eval`, requires ARM state and `r7 == 0`, and allows 1,000,000 successful machine steps.
The budget includes the original BIOS boot. Startup and CPU tests execute normally; result rendering does not execute.
Diagnostics, timeouts, STOP, and nonzero r7 remain failures under the [runner's normal rules](rom-tests.md).
## Observed result on Darwin arm64
Initial integration, before fixing empty-list Thumb stores:
- The runner reaches `0x08000934` after 771 successful steps and 3,858 nominal cycles.
- The CPU is in System/ARM state with CPSR `0x0000001f` and r7 = 229.
- Both builds exit nonzero with `reason: assertion_failed`; there is no emulator diagnostic.
- Test 229 executes `STMIA r0!, {}` (`0xc000`) at `0x080008ba`.
- The stored PC value is `0x080008be`, but the following PC read expects `0x080008c0`.
- The public ARM ROM still passes its unchanged checkpoint.
The next CPU task is to verify the empty-list store PC offset and correct it with original regressions.
Do not change the pinned ROM or weaken the result assertion to pass this test.
No public timing, memory, BIOS, graphics, or unsafe suite is claimed as passing.
These results do not establish Pokémon Emerald compatibility.
## References
- [Pinned Thumb entry and result flow](https://github.com/jsmolka/gba-tests/blob/a7113b67e63f83a9b321696ddd7042ccfad6c881/thumb/thumb.asm).
- [Branch progress markers and successful reset](https://github.com/jsmolka/gba-tests/blob/a7113b67e63f83a9b321696ddd7042ccfad6c881/thumb/branches.asm).
- [Memory tests, including test 229](https://github.com/jsmolka/gba-tests/blob/a7113b67e63f83a9b321696ddd7042ccfad6c881/thumb/memory.asm).
- [Shared startup and result macros](https://github.com/jsmolka/gba-tests/blob/a7113b67e63f83a9b321696ddd7042ccfad6c881/lib/macros.inc).
- [Pinned license](https://github.com/jsmolka/gba-tests/blob/a7113b67e63f83a9b321696ddd7042ccfad6c881/LICENSE).