DEV Community

Nivando Soares
Nivando Soares

Posted on

Porting Test Drive II from SNES to PC, Part 8: Closing the first 998..1005 ownership block

Porting Test Drive II from SNES to PC, Part 8: Closing the first 998..1005 ownership block

The previous checkpoint made frame 998 a real ownership anchor.

That was useful because 998 is the first frame of the direct bridge-extracted 998..1005 block. But an anchor at the start of a block is still only half the story.

The next question was the obvious one:

does the same ownership model stay intact all the way to the end of that block?

This checkpoint answers that question at frame 1005.

Why 1005 was the right next frame

1005 already mattered in the repo for a few reasons:

  • it is the end of the first direct bridge-extracted 998..1005 block
  • earlier callback-state notes already said it was still inside 01:9FE5
  • the bridge-visible renderer docs already treated 998..1005 as one coherent surface

But those were still mostly continuity notes.

The repo needed a live producer trace on 1005 itself to say something stronger:

  • not only does the block start inside the same ownership family
  • the whole block closes inside the same ownership family too

That is what changed here.

The concrete checkpoint

The workflow was the same one used for 986, 990, 994, and 998, with one deliberate difference:

the live probe window now covers the whole 998..1005 block, not just a five-frame slice.

That makes the result more useful as a block-closure proof.

The exact commands were:

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

MESEN_RELEASE_DIR=/home/nivando-soares/Mesen2/bin/linux-x64/Release \
MESEN_TIMEOUT_SECONDS=150 \
TD2_BOOT_PROBE_OUTPUT_PREFIX=tools/out/visual_contract_probe_1005_live/td2_boot_probe \
TD2_BOOT_PROBE_TOTAL_FRAMES=1006 \
TD2_BOOT_PROBE_TRACE_START_FRAME=998 \
TD2_BOOT_PROBE_TRACE_END_FRAME=1005 \
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_frame1005 \
  tools/out/visual_contract_frame1005_live_probe.json \
  --probe-json tools/out/visual_contract_probe_1005_live/td2_boot_probe.json
Enter fullscreen mode Exit fullscreen mode

I also added one small but useful supporting step: the local screenshot-backed frame for 1005 did not exist yet in this checkout, so I materialized it through the headless range dumper:

MESEN_RELEASE_DIR=/home/nivando-soares/Mesen2/bin/linux-x64/Release \
MESEN_TIMEOUT_SECONDS=150 \
TD2_BG_RANGE_START_FRAME=1005 \
TD2_BG_RANGE_END_FRAME=1005 \
TD2_BG_RANGE_STEP=1 \
TD2_BG_RANGE_DUMP_SCREENSHOTS=1 \
TD2_BG_RANGE_OUTPUT_PREFIX=tools/out/intro_loop \
./validation/run_mesen_dump_bg_range.sh
Enter fullscreen mode Exit fullscreen mode

The promoted ownership artifacts are now committed:

  • tools/out/visual_contract_probe_1005_live/td2_boot_probe.json
  • tools/out/visual_contract_frame1005_live_probe.json

What the trace showed

The live probe recorded:

  • 6432 write hits
  • 0 drops
  • exact trace window 998..1005

The important part is that the domain split still does not fork.

The whole block stays inside the same pair of producer domains:

  • OAM: 4368 writes across 998..1005
  • VRAM: 2064 writes across 998..1005

The dominant callsites are still the same late helpers:

  • OAM: 00:824F and 00:8257
  • VRAM: 00:81E5 and 00:81F2

And the callback pair still does not change:

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

That is the block-level result the repo needed.

The first direct bridge-extracted 998..1005 block is no longer just β€œa range that looks coherent.” It is now closed by live ownership evidence at both ends:

  • start anchor: 998
  • end anchor: 1005

What changed visually inside the block

The design pack for 1005 reports:

  • 53 visible sprites

That matters because the earlier 998 proof reported:

  • 32 visible sprites

So the useful reading is not that the screen froze under a static producer regime.

It is this:

  • the callback family stays the same
  • the producer domains stay the same
  • the visible overlay keeps expanding

That is exactly the kind of thing that can be misread as a control-flow change if you only look at screenshots and not producer ownership.

The live contract now makes that distinction explicit.

Validation

The fresh extracted frame was checked against the new local screenshot-backed capture:

python3 tools/compare_frames.py \
  tools/out/intro_loop_frame_01005_frame.png \
  tools/out/mesen_frame1005/main_visible.ppm \
  --diff-out tools/out/mesen_frame1005_vs_intro1005_diff.ppm
Enter fullscreen mode Exit fullscreen mode

That landed at:

  • 4466 mismatched pixels (7.788086%)

Again, that is not a solved screenshot-exact frame. But this archaeology checkpoint was not trying to claim that.

The renderer-side bounded validation stayed on the repo's stable Python surface:

python3 tools/render_mesen_snes_bg.py \
  tools/out/mesen_frame1005/vram.bin \
  tools/out/mesen_frame1005/cgram.bin \
  tools/out/mesen_frame1005/ppu_state.json \
  tools/out/mesen_frame1005_mode7ppu.ppm \
  --oam tools/out/mesen_frame1005/oam.bin \
  --obj-renderer mode7-ppu \
  --json-out tools/out/mesen_frame1005_mode7ppu.json

python3 tools/compare_frames.py \
  tools/out/mesen_frame1005/main_visible.ppm \
  tools/out/mesen_frame1005_mode7ppu.ppm \
  --diff-out tools/out/mesen_frame1005_mode7ppu_vs_mesen1005_diff.ppm
Enter fullscreen mode Exit fullscreen mode

That compare landed at:

  • 4 mismatched pixels (0.006975%)

That is the useful falsification check for this lane. It says the repo is still on the same practical bridge-visible render surface that the earlier docs already expected for frame 1005.

Why this checkpoint matters more than one more mid-block sample

At this point, another mid-block proof would have been weaker than closing the block.

1005 matters because it turns:

  • one start anchor at 998

into:

  • a closed ownership block from 998 to 1005

That is a better piece of evidence.

Now the repo can say something stricter than it could after the 998 checkpoint:

the first direct bridge-extracted block under this late 01:9FE5 regime is ownership-stable across the entire block, even while the visible overlay keeps growing.

That is not the same thing as saying the screenshot problem is solved. It is saying the remaining problem is further downstream than a missing ownership explanation for this block.

What comes next

The next step is now straightforward:

  • extend the same live ownership surface to frame 1013

That closes the next direct bridge-extracted 1006..1013 block under the same callback family and should show whether the same flat ownership story still holds one block later.

The headline for this checkpoint is simple:

the first direct bridge-extracted 998..1005 block is now closed by live ownership evidence, not just by continuity notes.

Top comments (0)