MFC0 and CFC2 overwrite a GPR, but the recompiled code did not hook them
(and neither interpreter hooked MFC0/CFC0), so the register kept the
shadow of whatever vertex it held before. Validation by value cannot
prove provenance when the new word equals the old one. Emit PGXP_ALU
after MFC0 and PGXP_COP2 after CFC2, matching the interpreters' CFC2
hook, and hook MFC0/CFC0 in both interpreters. OpenBIOS regenerated.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Decision (Alex, 2026-09-30): the recompiled BIOS carries the same risk as
the recompiled game, which titles already commit, so the retail backend is
compiled in rather than built on the player's machine. The retail image is
still never shipped: the runtime needs its data at run time and accepts only
the exact image the backend was built from, so the player supplies their
own dump as before.
- generated/{OpenBIOS,SCPH1001}_{full,dispatch}.c and their .emitter.sha
stamps are tracked (.gitignore un-ignores exactly those); regenerated with
the current emitter.
- bios_emitter_fingerprint.sh no longer hashes the ROM image: the profile's
SHA-256 pin stands for it and the emitter refuses any other image, and CI
has no dump, so hashing it made every CI configure read "stale".
- runtime.cmake: the staleness check covers every LINKED stem and
-DPSXRECOMP_BIOS_STALE_FATAL=ON makes a stale stamp fail configure.
- game-release.yml: no CI-side OpenBIOS emission (generate_openbios.sh is
gone); configure with BIOS_STALE_FATAL and assert both backends linked.
check_generated.sh asserts the submodule carries both backends tracked
and no dump is tracked anywhere.
- The player-side module build stays for a known image a build does not
link (SCPH-5552).
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>