DEV Community

Nivando Soares
Nivando Soares

Posted on

Porting Test Drive II from SNES to PC, Part 18: Closing the 1078..1085 ownership block

Porting Test Drive II from SNES to PC, Part 18: Closing the 1078..1085 ownership block

The previous checkpoint closed the direct bridge-extracted 1070..1077 block with live ownership evidence.

That result still carried the same late-window shape the recent proofs had been repeating:

  • same owner
  • same visible sprite count
  • same narrow VRAM pulse

The next useful question was whether that shape would survive once the block reached 1085.

This checkpoint answers that too, and the answer is useful because it changes shape without changing owner.

Why 1085 mattered

1085 is the end of the next direct bridge-extracted block:

  • 1078..1085

At this point the late attract lane is still not trying to rediscover ownership identity.

That part is stable.

The question is now about how the internal producer pattern changes while the callback family stays fixed.

1085 is the first good place where the answer stops being “same thing again.”

The checkpoint

The workflow stayed the same:

  1. extract frame 1085
  2. build a design pack
  3. run a bounded write-point probe across 1078..1085
  4. merge that probe into a visual contract

The exact commands were:

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

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_1085_live/td2_boot_probe \
TD2_BOOT_PROBE_TOTAL_FRAMES=1086 \
TD2_BOOT_PROBE_TRACE_START_FRAME=1078 \
TD2_BOOT_PROBE_TRACE_END_FRAME=1085 \
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_frame1085 \
  tools/out/visual_contract_frame1085_live_probe.json \
  --probe-json tools/out/visual_contract_probe_1085_live/td2_boot_probe.json
Enter fullscreen mode Exit fullscreen mode

The promoted artifacts are now committed:

  • tools/out/visual_contract_probe_1085_live/td2_boot_probe.json
  • tools/out/visual_contract_frame1085_live_probe.json

What the trace showed

The probe recorded:

  • 4368 write hits
  • 0 drops
  • exact trace window 1078..1085

The callback family still does not move:

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

But the producer shape does change this time.

Instead of the familiar OAM-plus-narrow-VRAM-pulse pattern, this block collapses to:

  • OAM: 4368 writes across 1078..1085
  • VRAM: no sampled writes in the bounded window

That is the useful new result.

The owner did not change, but the pulse did.

So the sharper reading is now:

  • ownership identity is still flat
  • visible sprite count is still flat
  • the old narrow VRAM pulse is gone in this window
  • the block is now a pure-OAM ownership block

What changed visually

The fresh design pack for 1085 reports:

  • 61 visible sprites

So the visible-sprite count is still flat.

The screenshot-backed comparison rises to:

  • 74 mismatched pixels

The Python mode7-ppu comparison lands at:

  • 69 mismatched pixels

That matters because the two surfaces are now rising together.

At 1077, the screenshot-backed side was still relatively tight while the Python renderer gap had opened more clearly.

At 1085, both gaps are already in the high double digits while the callback family is still unchanged.

Validation

The extracted frame was compared against a fresh local screenshot-backed capture for 1085:

python3 tools/compare_frames.py \
  tools/out/intro_loop_frame_01085_frame.png \
  tools/out/mesen_frame1085/main_visible.ppm \
  --diff-out tools/out/mesen_frame1085_vs_intro1085_diff.ppm
Enter fullscreen mode Exit fullscreen mode

That landed at:

  • 74 mismatched pixels (0.129046%)

The bounded renderer-side validation stayed on the stable Python mode7-ppu surface:

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

python3 tools/compare_frames.py \
  tools/out/mesen_frame1085/main_visible.ppm \
  tools/out/mesen_frame1085_mode7ppu.ppm \
  --diff-out tools/out/mesen_frame1085_mode7ppu_vs_mesen1085_diff.ppm
Enter fullscreen mode Exit fullscreen mode

That compare landed at:

  • 69 mismatched pixels (0.120326%)

Why this checkpoint is useful

After 1077, the repo could say:

  • the same ownership family still holds
  • the same narrow VRAM pulse still survives
  • the Python renderer gap is starting to matter more

After 1085, it can say something sharper:

  • the next block is also ownership-stable
  • the callback family still does not fork
  • the visible sprite count still does not move
  • but the narrow VRAM pulse disappears entirely inside this window
  • and both comparison surfaces now rise together

That is a better boundary than “same owner again.”

It means the late attract lane is now measuring a real internal transition inside the same callback family.

The late ownership chain is now closed at:

  • 998
  • 1005
  • 1013
  • 1021
  • 1029
  • 1037
  • 1045
  • 1053
  • 1061
  • 1069
  • 1077
  • 1085

What comes next

The next step is to extend the same proof surface to frame 1093 and close the next direct bridge-extracted 1086..1093 block.

The headline for this checkpoint is simple:

the 1078..1085 block is now closed by live ownership evidence, and the useful new fact is that the old narrow VRAM pulse disappears entirely while the same callback family remains in control.

Top comments (0)