fix(test): gate CD boot-matrix $4000-$7FFF stage band on the BIOS handoff marker (FMV titles' real-BIOS handoff)

BrainDead 13, Dragon's Lair and Primal Rage were recorded as parking at
BIOS_INTRO in real-BIOS mode, with docs/cd-known-issues.md item 1 filing
it as a BUTCH/FIFO/DSA fidelity gap and docs/cd-bizhawk-comparison.md
ranking three timing candidates for it. It was none of them: all three
hand off and play. The stage classifier was wrong.

classify_stage() mapped all of $004000-$007FFF to BIOS_INTRO. That band is
shared. The real CD BIOS does execute there pre-handoff (jagcd_bios.c
hooks its GPU-auth path at $005E40), but games link code there too --
Dragon's Lair's boot executable loads at $004000 and Myst's at $005000,
and BrainDead 13 / Primal Rage load a second-stage player there after
their own exes land at $124000 / $080000. The rule's only cited
provenance was a single ISO row (final_pc=$0059B0), and ISO loads are now
refused outright as unbootable, so it rested on a known-broken run.

Gate the band on the "[CD-BOOTSTUB] Injected" marker the core logs when
the BIOS reaches its handoff point at $050176: marker absent keeps
BIOS_INTRO, marker present falls through to GAME_CODE. Other bands
unchanged.

Diagnosis (the comparison doc's own prescribed first step -- disassemble
the loop, don't correlate against it). Forced state dumps via
cd_wedge_probe --freeze-frames 0, disassembled at each reported PC:

  Dragon's Lair $004C0A  move.l $562E,d0 / cmp.l d0,d2 / bgt
  BrainDead 13  $004FCA  byte-identical code, $72DA instead
  Primal Rage   $004436  joypad scan: $817F/$81BF/$81DF/$81EF -> $F14000

DL and BD13 are both ReadySoft and share one FMV player linked at
different addresses -- the instruction stream is byte-for-byte identical.
The loop waits for the movie's presentation clock to reach the next
frame's timestamp; that clock is a 48-bit fixed-point accumulator the
GPU's PIT ISR advances, and it was measured still advancing across
snapshots at frames 1200/1800/2400/2900 (DL exactly 30.0/s, BD13 24.0/s).
Sampling landed mid-wait for the next tick. Primal Rage was not in a loop
at all -- its PC ring is a straight-line sweep through its input scanner.

Confirmed with cd_visual_verify in bios mode, screenshots read: DL plays
its attract FMV (79.5% non-black, RMS 1230), BD13 its castle intro
(68.1%, RMS 2651), Primal Rage its full attract cycle through DEMO
gameplay back to the title screen (93.3%, RMS 980; needs 6000 frames --
its zero-motion windows are black scene transitions, the benign pattern
already documented for Myst).

The clincher needs no visuals: DL's hle and bios rows now both report
final_pc=$004C12 and BD13's both report $004FCA -- the same instruction in
the same player, previously labelled GAME_CODE in one mode and BIOS_INTRO
in the other. Space Ace vs Dragon's Lair, the control pair the ranking was
built on, was likewise never "works vs stuck": Space Ace's copy of the
same player is linked at $00B87A, outside the band.

No src/ change: there was no emulator defect to fix.

Matrix (3000 frames, all 20 rows re-run under this build): three rows
forward, zero backward. BrainDead 13 / Dragon's Lair / Primal Rage bios
BIOS_INTRO -> GAME_CODE; every other row unchanged in stage and score, all
20 now GAME_CODE 1/1 in both modes. make TEST_EXPORTS=1 test exits 0
(audio clipping + presence both green). Battle Morph hle+bios, IS2, Myst
hle+bios and Baldies wedge probes all "ran clean"; Myst RMS bios 2548 /
hle 2698, in envelope.

Co-Authored-By: Claude Fable 5 <[email protected]>
This commit is contained in:
Joseph MattielloandClaude Fable 5 committed 2026-07-30 00:00:34 -04:00
1 parent 17375c3306
commit 5a83d3d427
4 files changed
+206 -33

No files matched your search

+28
View File
@@ -12,6 +12,34 @@ legitimate).
Nothing in `src/` was changed for this note.
> **RESOLVED 2026-07-29 -- there was no handoff gap.** All three titles do
> hand off and play in bios mode. The `BIOS_INTRO` labels came from
> `cd_boot_matrix.sh`'s stage classifier treating all of
> `$004000`-`$007FFF` as BIOS code; games link code there too. **None of
> the three ranked candidates in §3 applies** -- do not sweep them for
> this. What settled it is §3's own prescribed first step ("Do this
> first"): the per-PC disassembly. Dragon's Lair and BrainDead 13 were
> sitting in a shared ReadySoft FMV player's wait-for-next-frame loop on a
> 30 Hz / 24 Hz presentation clock that was **measured still advancing**;
> Primal Rage was in its joypad scanner. Diagnosis, clock measurements and
> screenshots: 2026-07-29 re-run notes in `docs/cd-boot-matrix.md`.
> The §2.3 control pair dissolves too: Space Ace bios (`$00B87A`) vs
> Dragon's Lair bios (`$004C12`) was "sampled outside the band vs inside
> it", not "works vs stuck" -- Space Ace runs the same player, linked
> higher. §4.1 and §4.2 remain genuine bugs on their own merits, but
> **candidate 2 is separately falsified for these titles**: BrainDead 13
> and Dragon's Lair emit only `$150A` and never leave double speed, and
> Primal Rage's `$1501` comes only after its boot read finishes.
>
> Correction to this note's §2.2/§4.2 reading of the wire format: the
> `$15nn` payload is **not** a bit field. The retail BIOS at `$808978`
> builds a **one-based** speed code -- `and.w #$1,d2 / add.w #$1,d2`
> (1 = single, 2 = double) -- then `bset #3,d2` for data mode. So `$150A`
> is double-speed + data, and `$1502` (double + audio) cannot be expressed
> under a bit-0 reading. The `CD_mode` **API** input in D0 does use bit 0
> for speed and bit 1 for data (p.10 §2.7.7, quoted in §4.2); the BIOS
> re-encodes it before it reaches the wire.
---
## 1. Does BizHawk have Jaguar CD support?
+89 -21
View File
@@ -111,29 +111,96 @@ fresh dated section; do not retrofit old ones.
| Title | Mode | Score | Stage | Watchdog | PC evidence |
|---|---|---|---|---|---|
| Baldies (USA) (Rev 1).cue | hle | 1/1 | GAME_CODE | [CRASH-DETECT] video_stall frame=384 fb_hash=$97073547 unchanged for 300 frames gpu_pc=$00F0305C gpu_run=1 dsp_pc=$00F1B1AC dsp_run=0 | [PASS] Baldies (USA) (Rev 1).cue : pc_in_ram=1 not_loop=1 not_thrash=1 ram_payload=20677B unique_pcs=19 final_pc=$04C3BC |
| Baldies (USA) (Rev 1).cue | bios | 1/1 | GAME_CODE | [CRASH-DETECT] cd_seek_wedge frame=990 seek_starts=2 seek_dones=2 fifo_drains=45895 unchanged for 300 frames gpu_pc=$00F03270 gpu_run=1 dsp_pc=$00F1B088 dsp_run=1 | [PASS] Baldies (USA) (Rev 1).cue : pc_in_ram=1 not_loop=1 not_thrash=1 ram_payload=21698B unique_pcs=55 final_pc=$05FE8A |
| Battle Morph (USA).cue | hle | 1/1 | GAME_CODE | (none) | [PASS] Battle Morph (USA).cue : pc_in_ram=1 not_loop=1 not_thrash=1 ram_payload=24963B unique_pcs=256+ final_pc=$00AC88 |
| Battle Morph (USA).cue | bios | 1/1 | GAME_CODE | [CRASH-DETECT] cd_seek_wedge frame=905 seek_starts=1 seek_dones=1 fifo_drains=28672 unchanged for 300 frames gpu_pc=$00F033AC gpu_run=1 dsp_pc=$00F1C0B0 dsp_run=1 | [PASS] Battle Morph (USA).cue : pc_in_ram=1 not_loop=1 not_thrash=1 ram_payload=30596B unique_pcs=65 final_pc=$022052 |
| BrainDead 13 (USA).cue | hle | 1/1 | GAME_CODE | (none) | [PASS] BrainDead 13 (USA).cue : pc_in_ram=1 not_loop=1 not_thrash=1 ram_payload=1471B unique_pcs=9 final_pc=$03727C; PC-SET game-band: $12434C $124342 $12438A $1243BC |
| BrainDead 13 (USA).cue | bios | 1/1 | BIOS_INTRO | [CRASH-DETECT] cd_seek_wedge frame=1106 seek_starts=2 seek_dones=2 fifo_drains=38915 unchanged for 300 frames gpu_pc=$00F03276 gpu_run=1 dsp_pc=$00F1B084 dsp_run=1 | [PASS] BrainDead 13 (USA).cue : pc_in_ram=1 not_loop=1 not_thrash=1 ram_payload=27663B unique_pcs=62 final_pc=$004FCA |
| Dragon's Lair (USA).cue | hle | 1/1 | GAME_CODE | [CRASH-DETECT] video_stall frame=522 fb_hash=$292A41FD unchanged for 300 frames gpu_pc=$00F03278 gpu_run=1 dsp_pc=$00F1B084 dsp_run=1 | [PASS] Dragon's Lair (USA).cue : pc_in_ram=1 not_loop=1 not_thrash=1 ram_payload=14268B unique_pcs=65 final_pc=$004814 |
| Dragon's Lair (USA).cue | bios | 1/1 | BIOS_INTRO | (none) | [PASS] Dragon's Lair (USA).cue : pc_in_ram=1 not_loop=1 not_thrash=1 ram_payload=29348B unique_pcs=70 final_pc=$004C12 |
| Highlander - The Last of the MacLeods (USA).cue | hle | 1/1 | GAME_CODE | (none) | [PASS] Highlander - The Last of the MacLeods (USA).cue : pc_in_ram=1 not_loop=1 not_thrash=1 ram_payload=14691B unique_pcs=21 final_pc=$00826E |
| Highlander - The Last of the MacLeods (USA).cue | bios | 1/1 | GAME_CODE | [CRASH-DETECT] cd_seek_wedge frame=1750 seek_starts=4 seek_dones=4 fifo_drains=92617 unchanged for 300 frames gpu_pc=$00F031C2 gpu_run=1 dsp_pc=$00F1B07E dsp_run=1 | [PASS] Highlander - The Last of the MacLeods (USA).cue : pc_in_ram=1 not_loop=1 not_thrash=1 ram_payload=17330B unique_pcs=57 final_pc=$0088DA |
| Hover Strike - Unconquered Lands (USA).cue | hle | 1/1 | GAME_CODE | (none) | [PASS] Hover Strike - Unconquered Lands (USA).cue : pc_in_ram=1 not_loop=0 not_thrash=1 ram_payload=3631B unique_pcs=47 final_pc=$065B36 |
| Hover Strike - Unconquered Lands (USA).cue | bios | 1/1 | GAME_CODE | (none) | [PASS] Hover Strike - Unconquered Lands (USA).cue : pc_in_ram=1 not_loop=1 not_thrash=1 ram_payload=17157B unique_pcs=60 final_pc=$05DAA6 |
| Iron Soldier 2 (USA) (Songbird).cue | hle | 1/1 | GAME_CODE | (none) | [PASS] Iron Soldier 2 (USA) (Songbird).cue : pc_in_ram=1 not_loop=1 not_thrash=1 ram_payload=472B unique_pcs=6 final_pc=$007416 |
| Iron Soldier 2 (USA) (Songbird).cue | bios | 1/1 | GAME_CODE | (none) | [PASS] Iron Soldier 2 (USA) (Songbird).cue : pc_in_ram=1 not_loop=1 not_thrash=1 ram_payload=29870B unique_pcs=39 final_pc=$00B542 |
| Primal Rage (USA).cue | hle | 1/1 | GAME_CODE | (none) | [PASS] Primal Rage (USA).cue : pc_in_ram=1 not_loop=1 not_thrash=1 ram_payload=28237B unique_pcs=100 final_pc=$016514 |
| Primal Rage (USA).cue | bios | 1/1 | BIOS_INTRO | [CRASH-DETECT] cd_seek_wedge frame=884 seek_starts=2 seek_dones=2 fifo_drains=17996 unchanged for 300 frames gpu_pc=$00F031F6 gpu_run=1 dsp_pc=$00F1B12C dsp_run=1 | [PASS] Primal Rage (USA).cue : pc_in_ram=1 not_loop=1 not_thrash=1 ram_payload=25894B unique_pcs=75 final_pc=$0044CC |
| Space Ace (USA).cue | hle | 1/1 | GAME_CODE | [CRASH-DETECT] video_stall frame=403 fb_hash=$292A41FD unchanged for 300 frames gpu_pc=$00F03276 gpu_run=1 dsp_pc=$00F1B084 dsp_run=1 | [PASS] Space Ace (USA).cue : pc_in_ram=1 not_loop=1 not_thrash=1 ram_payload=14565B unique_pcs=66 final_pc=$0055CC |
| Space Ace (USA).cue | bios | 1/1 | GAME_CODE | (none) | [PASS] Space Ace (USA).cue : pc_in_ram=1 not_loop=1 not_thrash=1 ram_payload=29417B unique_pcs=73 final_pc=$00B87A |
| baldies.cdi | hle | 1/1 | GAME_CODE | [CRASH-DETECT] video_stall frame=384 fb_hash=$97073547 unchanged for 300 frames gpu_pc=$00F0305C gpu_run=1 dsp_pc=$00F1B1AC dsp_run=0 | [PASS] baldies.cdi : pc_in_ram=1 not_loop=1 not_thrash=1 ram_payload=20677B unique_pcs=19 final_pc=$04C3BC |
| baldies.cdi | bios | 1/1 | GAME_CODE | [CRASH-DETECT] cd_seek_wedge frame=990 seek_starts=2 seek_dones=2 fifo_drains=45895 unchanged for 300 frames gpu_pc=$00F03270 gpu_run=1 dsp_pc=$00F1B088 dsp_run=1 | [PASS] baldies.cdi : pc_in_ram=1 not_loop=1 not_thrash=1 ram_payload=21698B unique_pcs=55 final_pc=$05FE8A |
| Baldies (USA) (Rev 1).cue | hle | 1/1 | GAME_CODE | (none) | [PASS] Baldies (USA) (Rev 1).cue : pc_in_ram=1 not_loop=1 not_thrash=1 ram_payload=18235B unique_pcs=29 final_pc=$05FE82 <!-- build:17375c3-dirty --> |
| Baldies (USA) (Rev 1).cue | bios | 1/1 | GAME_CODE | [CRASH-DETECT] cd_seek_wedge frame=990 seek_starts=2 seek_dones=2 fifo_drains=45895 unchanged for 300 frames gpu_pc=$00F03270 gpu_run=1 dsp_pc=$00F1B088 dsp_run=1 | [PASS] Baldies (USA) (Rev 1).cue : pc_in_ram=1 not_loop=1 not_thrash=1 ram_payload=21698B unique_pcs=55 final_pc=$05FE8A <!-- build:17375c3-dirty --> |
| Battle Morph (USA).cue | hle | 1/1 | GAME_CODE | (none) | [PASS] Battle Morph (USA).cue : pc_in_ram=1 not_loop=1 not_thrash=1 ram_payload=26701B unique_pcs=46 final_pc=$0077A2 <!-- build:17375c3-dirty --> |
| Battle Morph (USA).cue | bios | 1/1 | GAME_CODE | [CRASH-DETECT] cd_seek_wedge frame=905 seek_starts=1 seek_dones=1 fifo_drains=28672 unchanged for 300 frames gpu_pc=$00F033AC gpu_run=1 dsp_pc=$00F1C0B0 dsp_run=1 | [PASS] Battle Morph (USA).cue : pc_in_ram=1 not_loop=1 not_thrash=1 ram_payload=30596B unique_pcs=65 final_pc=$022052 <!-- build:17375c3-dirty --> |
| BrainDead 13 (USA).cue | hle | 1/1 | GAME_CODE | [CRASH-DETECT] video_stall frame=1096 fb_hash=$D8CC2B8A unchanged for 300 frames gpu_pc=$00F03278 gpu_run=1 dsp_pc=$00F1B082 dsp_run=1 | [PASS] BrainDead 13 (USA).cue : pc_in_ram=1 not_loop=1 not_thrash=1 ram_payload=17926B unique_pcs=50 final_pc=$004FCA <!-- build:17375c3-dirty --> |
| BrainDead 13 (USA).cue | bios | 1/1 | GAME_CODE | [CRASH-DETECT] cd_seek_wedge frame=1106 seek_starts=2 seek_dones=2 fifo_drains=38915 unchanged for 300 frames gpu_pc=$00F03276 gpu_run=1 dsp_pc=$00F1B084 dsp_run=1 | [PASS] BrainDead 13 (USA).cue : pc_in_ram=1 not_loop=1 not_thrash=1 ram_payload=27663B unique_pcs=62 final_pc=$004FCA <!-- build:17375c3-dirty --> |
| Dragon's Lair (USA).cue | hle | 1/1 | GAME_CODE | (none) | [PASS] Dragon's Lair (USA).cue : pc_in_ram=1 not_loop=1 not_thrash=1 ram_payload=18477B unique_pcs=69 final_pc=$004C12 <!-- build:17375c3-dirty --> |
| Dragon's Lair (USA).cue | bios | 1/1 | GAME_CODE | (none) | [PASS] Dragon's Lair (USA).cue : pc_in_ram=1 not_loop=1 not_thrash=1 ram_payload=29348B unique_pcs=70 final_pc=$004C12 <!-- build:17375c3-dirty --> |
| Highlander - The Last of the MacLeods (USA).cue | hle | 1/1 | GAME_CODE | (none) | [PASS] Highlander - The Last of the MacLeods (USA).cue : pc_in_ram=1 not_loop=1 not_thrash=1 ram_payload=21117B unique_pcs=42 final_pc=$0088D2 <!-- build:17375c3-dirty --> |
| Highlander - The Last of the MacLeods (USA).cue | bios | 1/1 | GAME_CODE | [CRASH-DETECT] cd_seek_wedge frame=1750 seek_starts=4 seek_dones=4 fifo_drains=92617 unchanged for 300 frames gpu_pc=$00F031C2 gpu_run=1 dsp_pc=$00F1B07E dsp_run=1 | [PASS] Highlander - The Last of the MacLeods (USA).cue : pc_in_ram=1 not_loop=1 not_thrash=1 ram_payload=17330B unique_pcs=57 final_pc=$0088DA <!-- build:17375c3-dirty --> |
| Hover Strike - Unconquered Lands (USA).cue | hle | 1/1 | GAME_CODE | (none) | [PASS] Hover Strike - Unconquered Lands (USA).cue : pc_in_ram=1 not_loop=1 not_thrash=1 ram_payload=23042B unique_pcs=35 final_pc=$05DAA6 <!-- build:17375c3-dirty --> |
| Hover Strike - Unconquered Lands (USA).cue | bios | 1/1 | GAME_CODE | (none) | [PASS] Hover Strike - Unconquered Lands (USA).cue : pc_in_ram=1 not_loop=1 not_thrash=1 ram_payload=17157B unique_pcs=60 final_pc=$05DAA6 <!-- build:17375c3-dirty --> |
| Iron Soldier 2 (USA) (Songbird).cue | hle | 1/1 | GAME_CODE | (none) | [PASS] Iron Soldier 2 (USA) (Songbird).cue : pc_in_ram=1 not_loop=1 not_thrash=1 ram_payload=29306B unique_pcs=21 final_pc=$00CD3A <!-- build:17375c3-dirty --> |
| Iron Soldier 2 (USA) (Songbird).cue | bios | 1/1 | GAME_CODE | (none) | [PASS] Iron Soldier 2 (USA) (Songbird).cue : pc_in_ram=1 not_loop=1 not_thrash=1 ram_payload=29870B unique_pcs=39 final_pc=$00B542 <!-- build:17375c3-dirty --> |
| Primal Rage (USA).cue | hle | 1/1 | GAME_CODE | (none) | [PASS] Primal Rage (USA).cue : pc_in_ram=1 not_loop=1 not_thrash=1 ram_payload=28237B unique_pcs=100 final_pc=$016514 <!-- build:17375c3-dirty --> |
| Primal Rage (USA).cue | bios | 1/1 | GAME_CODE | [CRASH-DETECT] cd_seek_wedge frame=884 seek_starts=2 seek_dones=2 fifo_drains=17996 unchanged for 300 frames gpu_pc=$00F031F6 gpu_run=1 dsp_pc=$00F1B12C dsp_run=1 | [PASS] Primal Rage (USA).cue : pc_in_ram=1 not_loop=1 not_thrash=1 ram_payload=25894B unique_pcs=75 final_pc=$0044CC <!-- build:17375c3-dirty --> |
| Space Ace (USA).cue | hle | 1/1 | GAME_CODE | (none) | [PASS] Space Ace (USA).cue : pc_in_ram=1 not_loop=1 not_thrash=1 ram_payload=19041B unique_pcs=73 final_pc=$0075C0 <!-- build:17375c3-dirty --> |
| Space Ace (USA).cue | bios | 1/1 | GAME_CODE | (none) | [PASS] Space Ace (USA).cue : pc_in_ram=1 not_loop=1 not_thrash=1 ram_payload=29417B unique_pcs=73 final_pc=$00B87A <!-- build:17375c3-dirty --> |
| baldies.cdi | hle | 1/1 | GAME_CODE | (none) | [PASS] baldies.cdi : pc_in_ram=1 not_loop=1 not_thrash=1 ram_payload=18235B unique_pcs=29 final_pc=$05FE82 <!-- build:17375c3-dirty --> |
| baldies.cdi | bios | 1/1 | GAME_CODE | [CRASH-DETECT] cd_seek_wedge frame=990 seek_starts=2 seek_dones=2 fifo_drains=45895 unchanged for 300 frames gpu_pc=$00F03270 gpu_run=1 dsp_pc=$00F1B088 dsp_run=1 | [PASS] baldies.cdi : pc_in_ram=1 not_loop=1 not_thrash=1 ram_payload=21698B unique_pcs=55 final_pc=$05FE8A <!-- build:17375c3-dirty --> |
Raw per-run logs are not committed; re-run the script to regenerate.
## Re-run notes -- 2026-07-29, branch fix/cd-fmv-bios-handoff @ 17375c3
Full re-sweep (3000 frames, `CD_MATRIX_TIMEOUT=400`, chunked via
`CD_MATRIX_MAX_RUNS`) after correcting the `$004000`-`$007FFF` stage rule
in `classify_stage()`. **Three rows moved forward, zero backward** -- and
no emulator code changed, because there was no emulator defect:
- **BrainDead 13 bios**: `BIOS_INTRO` -> **GAME_CODE** (`final_pc=$004FCA`)
- **Dragon's Lair bios**: `BIOS_INTRO` -> **GAME_CODE** (`final_pc=$004C12`)
- **Primal Rage bios**: `BIOS_INTRO` -> **GAME_CODE** (`final_pc=$0044CC`)
Every other row is unchanged in stage and score (all 20 rows 1/1
GAME_CODE in both modes). The at-risk bios rows the taxonomy change could
have disturbed -- Baldies, Battle Morph, Highlander, Hover Strike, Iron
Soldier 2, Space Ace -- all still report `GAME_CODE 1/1`. `final_pc` and
`unique_pcs` vary run to run inside `GAME_CODE` (the harness samples a
live game); that is not a stage move.
### Why these three rows were never stuck
`docs/cd-known-issues.md` item 1 recorded these as a real "FMV titles do
not hand off from the real BIOS" defect, with three ranked timing
candidates in `docs/cd-bizhawk-comparison.md`. It was none of them: the
band rule was wrong, and the rows were false negatives.
Method (the comparison doc's own prescribed first step -- disassemble the
loop instead of correlating against it). `cd_wedge_probe --arm N
--freeze-frames 0` forces a full state dump at a chosen frame, and the
snapshot was disassembled at each reported PC:
| Title | PC | What the code is | Polled address | Written by |
|---|---|---|---|---|
| Dragon's Lair | `$004C0A`-`$004C12` | `move.l $562E,d0 / cmp.l d0,d2 / bgt` | `$562E` | GPU PIT ISR (`$F0308A`), 30 Hz |
| BrainDead 13 | `$004FCA`-`$004FD2` | byte-identical code, `$72DA` instead | `$72DA` | GPU PIT ISR, 24 Hz |
| Primal Rage | `$004436`-`$0044EE` | joypad scan: writes `$817F/$81BF/$81DF/$81EF` to `$F14000`, de-interleaves via tables at `$44F0/$4510/$4530` | -- (not a poll loop) | -- |
Dragon's Lair and BrainDead 13 are both ReadySoft titles and share one
FMV player, linked at different addresses -- the instruction stream at
`$004BF0` and `$004FB0` is byte-for-byte identical. The loop waits for
the movie's presentation clock to reach the next frame's timestamp. That
clock is a 48-bit fixed-point accumulator (`$562E`.w integer :
`$5630`.l fraction) that the GPU's PIT ISR advances by a per-title
increment; it was **measured still advancing** across snapshots at frames
1200/1800/2400/2900 (DL: `$8E` -> `$1BA` -> `$2E6` -> `$3DF`, exactly
30.0/s; BD13: `$CD` -> `$1BD` -> `$2AC` -> `$374`, 24.0/s). Sampling
landed mid-wait for the next 1/30 s tick. Primal Rage was not even in a
loop -- its PC ring is a straight-line sweep through its input scanner.
Confirmed with `cd_visual_verify` in bios mode (screenshots read, not
just counted): Dragon's Lair plays its attract FMV (79.5% non-black,
avg RMS 1230); BrainDead 13 plays its castle-and-moon intro (68.1%,
RMS 2651); Primal Rage runs its full attract cycle -- "WHO WILL RULE THE
NEW URTH?", then DEMO gameplay with two dinosaurs fighting, then back to
the "JAGUAR VERSION 1.2" title screen (93.3%, RMS 980). Primal Rage
needed 6000 frames to show the cycle: its zero-motion windows
(3060-3359, 5280-5519) are black scene transitions, the same benign
pattern already documented for Myst, not a freeze.
The decisive datum needs no visuals at all: **Dragon's Lair's hle and
bios rows now both report `final_pc=$004C12`, and BrainDead 13's both
report `$004FCA`** -- the same instruction in the same player. Only the
bios path applied the band rule, so the same code was labelled
`GAME_CODE` in one mode and `BIOS_INTRO` in the other. Space Ace vs
Dragon's Lair (the control pair the comparison doc built its ranking on)
was likewise never "works vs stuck": Space Ace's copy of the same
ReadySoft player is linked at `$00B87A`, outside the band.
## Re-run notes -- 2026-07-27, branch feature/jaguar-cd-support @ 73438ba
Full re-sweep (3000 frames, CD_MATRIX_TIMEOUT=300) after four CD fixes.
@@ -710,7 +777,6 @@ of a command/stop/wait handshake. Raw logs: /tmp/cdmx_postfix.
LOAD_FAIL and Battle Morph (bios) pc_escape are unchanged pre-existing
backlog items (see handoff doc section 5).
Raw per-run logs: /tmp/cdmx_loadb (not committed; re-run to regenerate).
## Re-run notes -- 2026-07-15 (2), GPU internal-RAM LOADB/LOADW fix
@@ -943,3 +1009,5 @@ Deltas vs the previous table; no regressions:
| baldies.cdi | bios | 0/1 | LOAD_FAIL (harness crash) | (none) | [CRASH] baldies.cdi : child died with signal 11 (Segmentation fault: 11) |
Raw per-run logs are not committed; re-run the script to regenerate.
Raw per-run logs: /private/tmp/claude-501/-Users-jmattiello-Workspace-Provenance-virtualjaguar-libretro/3525e61d-6771-42bd-9a0c-db42acffa102/scratchpad/mxlogs (not committed; re-run to regenerate).
+49 -7
View File
@@ -8,14 +8,56 @@ backward.
## Deferred to a future point release
### 1. Real-BIOS mode depth for FMV-heavy titles
### 1. ~~Real-BIOS mode depth for FMV-heavy titles~~ -- RESOLVED (measurement artifact)
BrainDead 13, Dragon's Lair, and Primal Rage park at `BIOS_INTRO` in
real-BIOS mode (all three play in HLE mode). The real BUTCH/FIFO/DSA path
needs further fidelity for their boot handoff. Evidence and per-title logs
in the boot matrix; the BIOS RAM-driver disassembly technique that cracked
the Myst fixes (snapshot `$3000-$3DFF` from a live run) is the recommended
tool.
**Not a defect. Withdrawn 2026-07-29.** This item claimed BrainDead 13,
Dragon's Lair and Primal Rage "park at `BIOS_INTRO` in real-BIOS mode"
and that the BUTCH/FIFO/DSA path needed more fidelity for their handoff.
All three in fact hand off and play in bios mode; the `BIOS_INTRO` label
came from `cd_boot_matrix.sh`'s stage classifier, which treated the whole
`$004000`-`$007FFF` band as BIOS code.
The band is shared: the real CD BIOS does execute there before handoff
(`src/cd/jagcd_bios.c` hooks its GPU-auth path at `$005E40`), but games
link code there too -- Dragon's Lair's boot executable loads at `$004000`
and Myst's at `$005000`, and BrainDead 13 / Primal Rage load a
second-stage player there after their own exes land at `$124000` /
`$080000`. The rule's only cited provenance was a single ISO row
(`final_pc=$0059B0`), and ISO loads are now refused outright as
unbootable (see "Explicitly out of scope" below), so it rested on a
known-broken run.
The classifier now gates that band on the `[CD-BOOTSTUB] Injected`
handoff marker, and all three rows read `GAME_CODE`. Full diagnosis --
per-title disassembly of what each PC was actually executing, the
measured 30 Hz / 24 Hz FMV presentation clocks, and the screenshots --
is in the 2026-07-29 re-run notes in `docs/cd-boot-matrix.md`.
Consequence for `docs/cd-bizhawk-comparison.md`: its three ranked
candidates (achieved FIFO delivery rate, the discarded `$15nn` speed bit,
the non-hardware serialization constants) were all ranked to explain a
gap that does not exist. Its own prescribed first step -- disassemble the
loop rather than correlate against it -- is what settled it. The `$15nn`
speed-bit finding (§4.2) and the `m68ki_init_exception` supervisor-stack
bug (§4.1) remain genuine, separately-filed correctness bugs; neither is
needed for these titles.
Candidate 2 (the discarded `$15nn` Set Mode payload) is independently
falsified for these titles by a Set Mode census across 10 titles in both
modes: BrainDead 13 and Dragon's Lair emit only `$150A` and never leave
double speed at all, and Primal Rage's single-speed request (`$1501`)
comes only *after* its boot read completes. Baldies and Hover Strike do
exercise the manual's §2.6 double -> single -> double recovery flow, and
both already reach `GAME_CODE`.
Beware the wire encoding if you touch this: the `$15nn` payload is **not**
a bit field for speed. The retail BIOS at `$808978` does
`move.w d0,d2 / and.w #$1,d2 / add.w #$1,d2`, i.e. a **one-based** speed
code (1 = single, 2 = double), then `bset #3,d2` for data mode, then
`or.w #$1500,d2`. So `$150A` is double-speed + data, not single speed, and
`$1502` (double + audio) is unrepresentable under a bit-0 reading. The
expected reply is `$1700 | payload` (`bset #9`), which
`src/cd/cdrom.c:1641` already synthesizes correctly.
### 2. FMV scene-jump schedule drift (Dragon's Lair / Space Ace / BD13)
+40 -5
View File
@@ -216,13 +216,44 @@ run_one() {
# $800000-$8FFFFF CD BIOS running as cart code -> BIOS_INTRO
# $190000-$1AFFFF CD BIOS code/data relocated to
# RAM (poll loops, data formatter) -> BIOS_INTRO
# $004000-$007FFF BIOS main loop / error handler
# (confirmed via this run's ISO row,
# final_pc=$0059B0, same band) -> BIOS_INTRO
# $004000-$007FFF AMBIGUOUS -- gated on the handoff marker,
# see "the $4000-$7FFF band" below
# $080000-$08FFFF injected boot-stub ISR/poll loop/
# data (confirmed via test_cd_boot.c
# comments: $0803A0, $080250, $085D00) -> BOOT_STUB
# anything else in RAM -> GAME_CODE
#
# The $4000-$7FFF band: this range is used by the BIOS *and* by games,
# so a bare address test cannot classify it. The real CD BIOS does run
# 68K code here before handoff (jagcd_bios.c hooks its GPU-auth path at
# $005E40), but games also link code here -- Dragon's Lair's boot
# executable loads at $004000, Myst's at $005000 (jagcd_bios.c:45), and
# BrainDead 13 / Primal Rage load a second-stage player here after
# their own exes land at $124000 / $080000.
#
# So the band is gated on the BIOS handoff marker instead. The core logs
# "[CD-BOOTSTUB] Injected $<len> bytes at $<addr>" exactly when the BIOS
# reaches its handoff point ($050176, where it JSRs to the disc's boot
# executable). Before that line the BIOS owns this band; after it, the
# game does:
# marker absent -> BIOS_INTRO (BIOS never handed off)
# marker present -> falls through to GAME_CODE
#
# History: the band used to be an unconditional -> BIOS_INTRO, sourced
# from a single ISO row (final_pc=$0059B0). ISO loads are now refused
# outright as unbootable (docs/cd-known-issues.md), so that provenance is
# retired -- and the rule was producing three false BIOS_INTRO rows.
# BrainDead 13 ($004FCA), Dragon's Lair ($004C12) and Primal Rage
# ($0044CC) were each disassembled from a live RAM snapshot at the
# reported PC: the first two sit in the same ReadySoft FMV player's
# "wait for the next frame's presentation time" loop (a 30 Hz / 24 Hz
# clock that a GPU PIT ISR advances, and that was measured still
# advancing), and Primal Rage sits in its joypad-scan routine writing
# $817F/$81BF/$81DF/$81EF to $F14000. All three were then confirmed by
# cd_visual_verify to be rendering real content in bios mode. The
# clincher is Dragon's Lair itself: its hle row reports final_pc=$004814
# and its bios row $004C12 -- the same 2 KB of the same player -- and
# only the bios path applied the band rule.
# MENU vs IN_GAME is NOT distinguished: none of our harnesses read the
# composited framebuffer the way RetroArch does (documented headless
# framebuffer caveat in CLAUDE.md), so any GAME_CODE row is reported as
@@ -268,7 +299,11 @@ classify_stage() {
if [ "$pc_dec" -ge $((16#E00000)) ] && [ "$pc_dec" -le $((16#E1FFFF)) ]; then echo "BIOS_INTRO"
elif [ "$pc_dec" -ge $((16#800000)) ] && [ "$pc_dec" -le $((16#8FFFFF)) ]; then echo "BIOS_INTRO"
elif [ "$pc_dec" -ge $((16#190000)) ] && [ "$pc_dec" -le $((16#1AFFFF)) ]; then echo "BIOS_INTRO"
elif [ "$pc_dec" -ge $((16#004000)) ] && [ "$pc_dec" -le $((16#007FFF)) ]; then echo "BIOS_INTRO"
elif [ "$pc_dec" -ge $((16#004000)) ] && [ "$pc_dec" -le $((16#007FFF)) ] \
&& ! grep -aq '\[CD-BOOTSTUB\] Injected' "$log" 2>/dev/null; then
# Shared BIOS/game band -- only BIOS_INTRO while the BIOS has not yet
# reached its handoff point. See the taxonomy note above.
echo "BIOS_INTRO"
elif [ "$pc_dec" -ge $((16#080000)) ] && [ "$pc_dec" -le $((16#08FFFF)) ]; then echo "BOOT_STUB"
elif [ "$pc_dec" -lt $((16#004000)) ]; then
# $0000-$3FFF is ambiguous: it holds BIOS service routines (TOC at
@@ -406,7 +441,7 @@ else
printf 'evidence to classify further, never fabricated):\n\n'
printf '| Stage | Meaning |\n|---|---|\n'
printf '| `LOAD_FAIL` | `retro_load_game()` returned false, or the harness child crashed (segfault) before producing a usable PC trace |\n'
printf '| `BIOS_INTRO` | Real CD BIOS executing (boot ROM cube animation, BIOS main loop/error handler, or CD-read poll code) -- has not yet handed off to the boot stub or game |\n'
printf '| `BIOS_INTRO` | Real CD BIOS executing (boot ROM cube animation, BIOS main loop/error handler, or CD-read poll code) -- has not yet handed off to the boot stub or game. In the shared `$004000`-`$007FFF` band this requires the absence of the `[CD-BOOTSTUB] Injected` handoff marker: games link code there too (Dragon'"'"'s Lair at `$004000`, Myst at `$005000`), so the address alone is not evidence |\n'
printf '| `BOOT_STUB` | PC parked in the injected boot-stub ISR/poll-loop/data region (`$080000`-`$08FFFF`) |\n'
printf '| `GAME_CODE` | PC in game-owned RAM outside the BIOS/boot-stub bands (HLE: any stable multi-PC run, since HLE synthesizes past BIOS/boot-stub by design) |\n'
printf '| `MENU` / `IN_GAME` | Not distinguished by any current harness -- see "Headless framebuffer caveat" in CLAUDE.md. Reported as `GAME_CODE` with a note. |\n'