mirror of
https://github.com/libretro/virtualjaguar-libretro.git
synced 2026-11-07 17:32:37 -10:00
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:
1 parent
17375c3306
commit
5a83d3d427
4 files changed
+206
-33
No files matched your search
@@ -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
@@ -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
@@ -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)
|
||||
|
||||
|
||||
@@ -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'
|
||||
|
||||
Reference in new issue
Block a user