Skip to content

feat(accuracysnes): cover C11.03, and retract the interlace-gate claim (T-04-H) - #302

Merged
doublegate merged 1 commit into
mainfrom
feat/c11-03-mode7-mask
Aug 1, 2026
Merged

feat(accuracysnes): cover C11.03, and retract the interlace-gate claim (T-04-H)#302
doublegate merged 1 commit into
mainfrom
feat/c11-03-mode7-mask

Conversation

@doublegate

Copy link
Copy Markdown
Owner

Two things: a row covered, and a claim from PR #299 retracted.

Retraction first

#299 said the field gate had turned C7.12's three-way emulator split into a two-way one, citing snes9x and Mesen2 producing the identical hash. That was one run, and it does not hold. The identical ROM, run twice under Mesen2:

run c7-obj-interlace-halves-height under Mesen2
1 0x16f7ab8c7f97b7f8
2 0x266241e43ab85064

Exactly the two field-parity outcomes, alternating run to run on one build. RustySNES and snes9x are each stable; Mesen2 is not.

The gate is necessary but not sufficient, and the missing half is host-side. The cart is deterministic — it publishes only on its chosen field. What is not pinned is which rendered frame a host associates with the R_SCENE value it read, and Mesen2's headless runner does not make that association deterministically.

So the interlace scene is withdrawn, not left unblessed: a scene reporting a different hash each run is noise in the gate output, and "the references agree" was an artifact of looking once. The gate itself stays — it is the cart-side half, it moves no golden, and it costs only battery runtime — but nothing exploits it until a host can pin the frame it hashes. C9.03/C9.06 stay unwritten for the same reason.

The lesson is E8.01's, twice in one session: a result that depends on a phase nobody controls looks stable until you run it twice.

C11.03 — each M7x * ORG product is masked before accumulation

A Mode 7 scene with M7A and M7B both $0101, deliberately not round numbers. With M7B = $0101 the discarded part is line MOD 64 — a different amount on every line — so a core that accumulates the full products samples a different texel on roughly a quarter of the columns of most lines. Every other Mode 7 scene here uses round matrix values, which hide this completely; none of them was evidence for the row.

Blessed at 0xc032679c9076440a, which all three references produce, stable across repeated runs.

Non-vacuity confirmed by injection: removing the mask from fetch_mode7_column moves this scene's hash. Worth stating that c11-mode7-rotate-scale and c11-mode7-window also move under that injection — the mask was already witnessed in aggregate. What this adds is a scene whose stated purpose is the mask, which is what makes the coverage claim mean something rather than being a coincidence of two scenes about other things.

Coverage is unchanged, and that is correct

Still 350 of 443. C11.03 replaces C7.12 one-for-one, because the withdrawn scene was being counted as C7.12's scene-cover while it was still unblessed. What changed is that the row now counted has a golden all three references agree on.

Verification

  • cargo fmt --check, cargo clippy --workspace --exclude rustysnes-android --all-targets -- -D warnings — clean.
  • cargo test -p rustysnes-test-harness --test accuracysnes --test accuracysnes_scenes --features test-roms58 passed, 0 failed.
  • REF_PROJ=$PWD/ref-proj bash scripts/accuracysnes/crossval.shsnes9x: 54 scene(s) match, 0 unblessed, 0 mismatched, Mesen2: 54 scene(s) match, 0 unblessed, 0 mismatched, cross-validation: 2 reference(s) agree with the cart.

🤖 Generated with Claude Code

…m (T-04-H)

C11.03 -- each M7x * ORG product is masked to a multiple of 64 before the
terms accumulate -- is now covered by a Mode 7 scene with M7A and M7B both
$0101, deliberately not round numbers. With M7B = $0101 the discarded part is
`line MOD 64`, a different amount on every line, so a core that accumulates
the full products samples a different texel on roughly a quarter of the
columns of most lines. Every other Mode 7 scene uses round matrix values,
which hide this completely -- none of them was evidence for the row.

Blessed at 0xc032679c9076440a, which all three references produce, stable
across repeated runs. Non-vacuity confirmed by removing the mask from
fetch_mode7_column: this scene's hash moves. Two existing scenes move under
that injection too, so the mask was already witnessed in aggregate -- what
this adds is a scene whose stated purpose is the mask.

RETRACTION. PR #299 claimed the field gate turned C7.12's three-way emulator
split into a two-way one, citing snes9x and Mesen2 producing the identical
hash. That was ONE RUN and it does not hold: the identical ROM run twice under
Mesen2 gives 0x16f7ab8c7f97b7f8 then 0x266241e43ab85064, the two field
parities alternating run to run. RustySNES and snes9x are each stable; Mesen2
is not.

The gate is necessary but not sufficient and the missing half is host-side:
the cart publishes only on its chosen field, but which RENDERED frame a host
associates with the R_SCENE value it read is not pinned, and Mesen2's headless
runner does not make that association deterministically. The interlace scene
is withdrawn rather than left unblessed, because a scene reporting a different
hash each run is noise in the gate output. The gate itself stays -- cart-side
half, moves no golden, costs only battery runtime.

Coverage is unchanged at 350 of 443: C11.03 replaces C7.12 one-for-one,
because the withdrawn scene was being counted as C7.12's scene-cover while
still unblessed. What changed is that the row now counted has a golden all
three references agree on.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings August 1, 2026 08:43
@coderabbitai

coderabbitai Bot commented Aug 1, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@doublegate, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 2 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 593b7947-cad5-40f3-b769-0e87af76026e

📥 Commits

Reviewing files that changed from the base of the PR and between ba1ea3a and 56a3a80.

⛔ Files ignored due to path filters (6)
  • docs/accuracysnes-coverage.md is excluded by !docs/accuracysnes-coverage.md and included by docs/**
  • tests/golden/accuracysnes-scenes.tsv is excluded by !**/*.tsv, !tests/golden/** and included by tests/**
  • tests/roms/AccuracySNES/asm/scenes.s is excluded by !tests/roms/AccuracySNES/asm/scenes.s and included by tests/**
  • tests/roms/AccuracySNES/build/accuracysnes-pal.sfc is excluded by !tests/roms/AccuracySNES/build/** and included by tests/**
  • tests/roms/AccuracySNES/build/accuracysnes.sfc is excluded by !tests/roms/AccuracySNES/build/** and included by tests/**
  • tests/roms/AccuracySNES/build/scenes.tsv is excluded by !**/*.tsv, !tests/roms/AccuracySNES/build/** and included by tests/**
📒 Files selected for processing (3)
  • CHANGELOG.md
  • docs/accuracysnes-plan.md
  • tests/roms/AccuracySNES/gen/src/scenes.rs

Comment @coderabbitai help to get the list of available commands.

@github-actions

github-actions Bot commented Aug 1, 2026

Copy link
Copy Markdown

Antigravity review (Gemini via Ultra)

This pull request updates the AccuracySNES test ROM suite by replacing the unblessable OBJ interlace scene (C7.12) with a Mode 7 product low-bit masking scene (C11.03), updates the corresponding golden vectors and coverage documentation, and documents the retraction of the interlace-gate claim in the AccuracySNES plan.

Blocking issues

None found.

Suggestions

  • CHANGELOG.md: The added changelog section includes an unrelated entry regarding H-IRQ comparator timing changes (T-06-A) which are not present in this PR's diff. Additionally, lines 86–90 duplicate the first paragraph of that H-IRQ entry. Remove the unrelated and duplicated changelog text.
  • tests/roms/AccuracySNES/gen/src/scenes.rs#L1898: The what string literal in the C11.03 scene definition contains large clusters of inline whitespace (16+ spaces) across line breaks. Clean up the string formatting so whitespace isn't compiled directly into the string asset.
  • tests/roms/AccuracySNES/asm/scenes.s#L2251: The header comment for .proc scene_c11_mode7_product_low_bits_masked has irregular 16-space padding before words across line wraps. Fix the comment indentation to match surrounding assembly style.

Nitpicks

  • CHANGELOG.md: The changelog header has two consecutive Added sections without an intervening version header.

Automated first-pass review by agy on a self-hosted runner -- not a human review.

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Not ready to approve

CHANGELOG.md currently contains duplicated and internally contradictory entries (retraction text plus the older unretracted claim), which should be consolidated before merging.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

This review doesn't count toward merge requirements. Sign up for the private preview to control whether Copilot approvals count.

Pull request overview

Updates AccuracySNES rendered-scene coverage by replacing the withdrawn, field-dependent C7.12 interlace scene with a new deterministic Mode 7 scene covering C11.03, and documents the retraction of the prior “interlace gate made references agree” claim.

Changes:

  • Replaced scene c7-obj-interlace-halves-height (C7.12) with c11-mode7-product-low-bits-masked (C11.03) and added its golden hash.
  • Updated generated scene catalogs/dispatch to include the new scene.
  • Updated planning/coverage docs and changelog text to reflect the scene swap and the interlace-gate retraction.
File summaries
File Description
tests/roms/AccuracySNES/gen/src/scenes.rs Swaps the scene definition to C11.03 and defines its Mode 7 setup.
tests/roms/AccuracySNES/build/scenes.tsv Updates the generated scene index mapping to the new scene ID/dossier row.
tests/roms/AccuracySNES/asm/scenes.s Updates generated scene implementation/dispatch table for the new scene.
tests/golden/accuracysnes-scenes.tsv Adds the blessed golden hash for the new C11.03 scene.
docs/accuracysnes-plan.md Updates high-level counts and narrative around the interlace-gate conclusion.
docs/accuracysnes-coverage.md Updates the listed covered rendered-scene dossier row from C7.12 to C11.03.
CHANGELOG.md Adds changelog entries covering the retraction and the new C11.03 scene coverage.
Review details
  • Files reviewed: 7/9 changed files
  • Comments generated: 3
  • Review effort level: Lite

We're testing this review assessment. Please use 👍 or 👎 to tell us if it's correct.

emulators, the only three-way split any scene has produced.",
id: "c11-mode7-product-low-bits-masked",
dossier: "C11.03",
what: "Mode 7 with `M7A` and `M7B` both `$0101` — deliberately NOT round numbers. Each `M7x * ORG` product has its low six bits masked off (`AND NOT $3F`) before the terms are accumulated, so the per-line origin is quantised to a multiple of 64 in the 1/256-texel fixed point. With `M7B = $0101` the discarded part is `line MOD 64`, which is a different amount on every line — a core that accumulates the full products samples a different texel on roughly a quarter of the columns of most lines, and the two pictures are nothing alike. Round matrix values hide this completely, which is why every other Mode 7 scene here uses them and none of them is evidence for this row.",
Comment thread CHANGELOG.md
Comment on lines +44 to +49
- **AccuracySNES: the scene protocol publishes on a known field.** `run_scenes` now sets the scene
ID only on frames whose `$213F` bit 7 is set, so every sighting the host counts is the same
*cart-side* field. `SCENE_FRAMES` grew 8 → 12: at half the publication rate the old value put the
host's fourth sighting on the window's *last* frame, one of the two ends the capture protocol
exists to avoid. The 53 blessed scenes are unaffected on all three hosts — a still picture hashes
the same on either field.
Comment thread docs/accuracysnes-plan.md
Comment on lines 16 to +18
| Tests | **338** (scoring + golden vectors + region SKIP per image) — *tests, not assertions; see the note below the table* |
| Assertion coverage | **350 of 443** dossier assertions — **297 on-cart** + **53 rendered scenes**, kept as separate columns (`docs/accuracysnes-coverage.md`) |
| Rendered scenes | **53**, all cross-validated (`docs/adr/0013`) |
| Rendered scenes | **54** declared and all cross-validated (`docs/adr/0013`); **53** are the dossier rows they are the only cover for |
@doublegate
doublegate merged commit 390848e into main Aug 1, 2026
17 checks passed
@doublegate
doublegate deleted the feat/c11-03-mode7-mask branch August 1, 2026 09:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants