DEV Community

Nivando Soares
Nivando Soares

Posted on

Porting Test Drive II from SNES to PC, Part 6: Extending late-window ownership through frame 994

Porting Test Drive II from SNES to PC, Part 6: Extending late-window ownership through frame 994

The previous checkpoint proved something important at frame 986: the repo could now generate a real late-window live producer trace, not just an early proof at frame 300 and not just a blocked timed-input experiment at 7051.

That immediately raised the next question:

was 986 only a cheap local win, or does the same ownership story hold as the late attract overlay comes back on screen?

The natural follow-up frames were 990 and 994.

They were already good archaeology targets for three reasons:

  • both frames already had queue-side and bridge-visible artifacts
  • both sat inside the same late 01:9FE5 attract family
  • 994 was the point where the remaining screenshot gap was still visible, even though the committed OAM variants had already converged

So this checkpoint was not about adding a new renderer feature. It was about extending the ownership proof far enough to say something useful about the remaining gap.

The concrete checkpoint

The workflow stayed the same as the 986 proof:

  1. extract a fresh raw frame bundle
  2. build a design pack
  3. run a bounded write-point trace around the frame
  4. merge the probe into a visual contract

For 990, the exact commands were:

MESEN_RELEASE_DIR=/home/nivando-soares/Mesen2/bin/linux-x64/Release \
make -C tools mesen-design-pack MESEN_FRAME=990

MESEN_RELEASE_DIR=/home/nivando-soares/Mesen2/bin/linux-x64/Release \
MESEN_TIMEOUT_SECONDS=120 \
TD2_BOOT_PROBE_OUTPUT_PREFIX=tools/out/visual_contract_probe_990_live/td2_boot_probe \
TD2_BOOT_PROBE_TOTAL_FRAMES=991 \
TD2_BOOT_PROBE_TRACE_START_FRAME=986 \
TD2_BOOT_PROBE_TRACE_END_FRAME=990 \
TD2_BOOT_PROBE_TRACE_WRITE_POINTS='objsel=00:2101,oamaddl=00:2102,oamaddh=00:2103,oamdata=00:2104,vmaddl=00:2116,vmaddh=00:2117,vmdatal=00:2118,vmdatah=00:2119,cgadd=00:2121,cgdata=00:2122' \
TD2_BOOT_PROBE_WRITE_POINT_MAX_HITS=8192 \
./validation/run_mesen_probe_boot.sh

python3 tools/build_mesen_visual_contract.py \
  tools/out/design_frame990 \
  tools/out/visual_contract_frame990_live_probe.json \
  --probe-json tools/out/visual_contract_probe_990_live/td2_boot_probe.json
Enter fullscreen mode Exit fullscreen mode

For 994, I ended up recording a small but real reproducibility detail. The first extractor attempt timed out when I launched it in parallel with the live probe. Running the extractor by itself with a larger frame timeout closed the frame cleanly:

MESEN_RELEASE_DIR=/home/nivando-soares/Mesen2/bin/linux-x64/Release \
./tools/run_mesen_ppu_extract.sh \
  --rom ./game.smc \
  --frame 994 \
  --frame-timeout-seconds 120 \
  --out-dir ./tools/out/mesen_frame994

python3 tools/build_mesen_design_pack.py \
  tools/out/mesen_frame994 \
  tools/out/design_frame994 \
  --clean-out

MESEN_RELEASE_DIR=/home/nivando-soares/Mesen2/bin/linux-x64/Release \
MESEN_TIMEOUT_SECONDS=120 \
TD2_BOOT_PROBE_OUTPUT_PREFIX=tools/out/visual_contract_probe_994_live/td2_boot_probe \
TD2_BOOT_PROBE_TOTAL_FRAMES=995 \
TD2_BOOT_PROBE_TRACE_START_FRAME=990 \
TD2_BOOT_PROBE_TRACE_END_FRAME=994 \
TD2_BOOT_PROBE_TRACE_WRITE_POINTS='objsel=00:2101,oamaddl=00:2102,oamaddh=00:2103,oamdata=00:2104,vmaddl=00:2116,vmaddh=00:2117,vmdatal=00:2118,vmdatah=00:2119,cgadd=00:2121,cgdata=00:2122' \
TD2_BOOT_PROBE_WRITE_POINT_MAX_HITS=8192 \
./validation/run_mesen_probe_boot.sh

python3 tools/build_mesen_visual_contract.py \
  tools/out/design_frame994 \
  tools/out/visual_contract_frame994_live_probe.json \
  --probe-json tools/out/visual_contract_probe_994_live/td2_boot_probe.json
Enter fullscreen mode Exit fullscreen mode

Those four JSON artifacts are now committed in the repo:

  • tools/out/visual_contract_probe_990_live/td2_boot_probe.json
  • tools/out/visual_contract_frame990_live_probe.json
  • tools/out/visual_contract_probe_994_live/td2_boot_probe.json
  • tools/out/visual_contract_frame994_live_probe.json

What changed between 990 and 994

The most useful result is that the ownership story did not fork.

Both windows still sit under the same callback pair:

  • active main callback: 01:9FE5
  • active IRQ callback: 00:835F

The raw numbers are:

  • frame 990
    • 3762 write hits
    • 0 drops
    • exact trace window 986..990
    • 2730 OAM writes across 986..990
    • 1032 VRAM writes across 986/988/989/990
    • 5 visible sprites
  • frame 994
    • 4020 write hits
    • 0 drops
    • exact trace window 990..994
    • 2730 OAM writes across 990..994
    • 1290 VRAM writes across 990..994
    • 19 visible sprites

That is a clean late-window reading:

  • OAM upload volume stays flat
  • VRAM traffic grows
  • the visible overlay expands from 5 sprites to 19
  • the callback family does not change

That is a much stronger statement than “the screenshot is still off.”

It says the repo now knows that the late 986 -> 994 edge is still one continuous ownership surface, not a mystery fork where different code suddenly takes over.

The validation numbers that matter

The new frame dumps were checked against both the local screenshot-backed captures and the already-committed bridge-object scenes.

For frame 990:

python3 tools/compare_frames.py \
  tools/out/intro_loop_frame_00990_frame.png \
  tools/out/mesen_frame990/main_visible.ppm \
  --diff-out tools/out/mesen_frame990_vs_intro990_diff.ppm

python3 tools/compare_frames.py \
  tools/out/mesen_frame990/main_visible.ppm \
  tools/out/bank1_bootstrap_queue_990_bridgeobj.ppm \
  --diff-out tools/out/mesen_frame990_vs_bridgeobj990_diff.ppm
Enter fullscreen mode Exit fullscreen mode

Results:

  • 1516 mismatched pixels (2.643694%) against the local screenshot
  • 2 mismatched pixels (0.003488%) against the committed bridge-object scene

For frame 994:

python3 tools/compare_frames.py \
  tools/out/intro_loop_frame_00994_frame.png \
  tools/out/mesen_frame994/main_visible.ppm \
  --diff-out tools/out/mesen_frame994_vs_intro994_diff.ppm

python3 tools/compare_frames.py \
  tools/out/mesen_frame994/main_visible.ppm \
  tools/out/bank1_bootstrap_queue_994_bridgeobj.ppm \
  --diff-out tools/out/mesen_frame994_vs_bridgeobj994_diff.ppm
Enter fullscreen mode Exit fullscreen mode

Results:

  • 2622 mismatched pixels (4.572405%) against the local screenshot
  • 96 mismatched pixels (0.167411%) against the committed bridge-object scene

That split is the important part.

994 is still not screenshot-accurate. But the repo can now say something stricter about why:

  • it is not blocked on missing late-window producer ownership
  • it is not blocked on a separate committed OAM fork
  • it is downstream of that

In other words, the remaining 994 gap is no longer an “I still do not know who is writing this” problem.

Why this was the right move instead of going back to 7051

The timed-input 7051 path is still useful. It is just still a bad place to spend retries in the current environment.

Two bounded power-on attempts had already exited 255 before producing a probe JSON. The right response to that was not to keep asking the same broken path to tell a new story.

The right response was:

  • take the cheaper late-window proof that already matters
  • keep the lane moving
  • return to 7051 only with a better starting surface

That is exactly what 990 and 994 accomplished.

This checkpoint turned the previous 986 proof from an isolated anchor into a short continuous ownership strip:

  • 986
  • 990
  • 994

That strip is enough to make the next decision obvious.

What comes next

The next target is not another blind 7051 retry.

The next target is 998.

That is where the direct bridge-extracted 01:9FE5 continuation already begins, so extending the same live ownership surface there should say more than another timed-input failure would.

The headline for this checkpoint is simple:

the repo now has live late-window producer-trace-backed visual contracts not only at 986, but also at 990 and 994, and that is enough to show that the remaining 994 gap is downstream of ownership, not blocked by it.

Top comments (0)