You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit c034f1d
Browse filesBrowse the repository at this point in the historyBrowse files
test(accuracysnes): C7.06 — Time Over reads set by V = YLOC + 1
C7 on-cart coverage 7 -> 8 of 16.
8x8 sprites can NEVER reach Time Over. The budget is 34 tiles per line,
but range evaluation stops at the 33rd in-range sprite, so 8x8 caps at 32
-- under the limit, permanently. C7.05's forty 8x8 sprites set Range Over
and leave Time Over clear, and the eval-line probe reports the same for
the same reason.
Twenty 16x16 sprites give 40 tiles while staying under the 32-sprite
range limit. That separation is itself an assertion: Time Over must set
while Range Over stays clear, so a core raising the two together fails.
The bracket runs across the line boundary rather than within a line,
because the asserted position is fixed and there is no index to sweep:
clear on the eval line V = 100, set on V = 101. Phase B samples on line
101 deliberately -- RustySNES raises the flag at HBLANK_START_DOT of the
eval line, EARLIER than the assertion requires, and pinning that exact
dot would fail a core raising it at (101, 0) exactly, which the assertion
permits.
A low-tile control (the same 20 sprites at 8x8, 20 tiles) must read clear
at phase B's sampling point; without it "set" would only have meant
"sprites are present". Four injections, each failing its own code:
flagging on any sprite fails code 4 (the control), never setting fails
code 2, setting at dot 0 fails code 1.
snes9x fails it and is recorded as an expected divergence
(SNES9X_KNOWN_FAILURES 13 -> 14): it already reads Time Over set on
V = 100, flagging the overflow a line early because it evaluates and
paints in one pass. The control passes there, so it is the position that
is wrong, not the budget.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
**293 of 443** enumerated assertion rows covered by an on-cart test, plus **53** covered only by a rendered scene (`docs/adr/0013`) — **346 of 443** in total.
55
+
**294 of 443** enumerated assertion rows covered by an on-cart test, plus **53** covered only by a rendered scene (`docs/adr/0013`) — **347 of 443** in total.
56
56
57
57
The two columns are kept apart on purpose. An on-cart result means the same thing on any emulator and on real hardware; a rendered scene needs a host holding the golden. Adding them into one figure would quietly change what the number claims.
Copy file name to clipboardExpand all lines: docs/accuracysnes-plan.md
+24-1Lines changed: 24 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -469,7 +469,7 @@ before the H counter wraps and silently returns a plausible small number.
469
469
|`A5.18`|**parked** — needs a cheaper instrument | The design is sound and the numbers came out exactly as predicted, but a `BRK` round trip is 39 dots and only 3 fit inside the budget, leaving 6 dots of signal against `TOL` 2 in a difference-of-differences. See below. |
470
470
|`A6.15`| needs its own design | "all 256 opcodes defined" is a *definedness* assertion, not a timing one, and `sweep.rs` deliberately covers only the unambiguous subset — its own module docs list why control flow, `BRK`/`COP`, `STP`, `WAI` and memory-addressing modes are excluded. Citing the sweep would be coverage by restatement. |
471
471
|`C7.05`|**landed**| Not a fixed bracket — the set dot has to *move with the index*. See below. |
472
-
|`C7.06`|reachable, same technique |`C7.05`'s far-IRQ shim and sprite setup are reusable; `time_over` needs >34 sprite-tiles, which 40 8x8 sprites do **not** produce (range evaluation caps at 32, so 32 tiles). Use larger sprites. |
472
+
|`C7.06`|**landed**| 8x8 sprites can *never* reach Time Over — evaluation stops at 32 sprites, so 32 tiles is the ceiling against a 34 budget. Twenty 16x16 sprites give 40 tiles while staying under the range limit, which also keeps the two flags independently observable. |
473
473
|`B2.07`| gated on `B2.02`|`B2.04` covers the 262-line count, not the clock total, so the frequency is not implied by it. Getting to 60.0988 Hz needs clocks-per-frame, and the frame alternates 357,368/357,364 because of the short scanline — which *is*`B2.02`, a `T-06-A` dot-model residual scheduled for `v1.29.0`. |
474
474
|`B2.09`|`v1.29.0` by its own dossier note | the picture window is "not CPU-observable directly; reachable through the framebuffer oracle once the dot-resolution compositor lands". |
475
475
@@ -540,6 +540,29 @@ its Range Over does not track the index — a scanline-granularity flag. RustySN
540
540
anchored to MesenCE on the *line* by `scripts/probes/eval-line-213e`; the *dot* is
541
541
documentation-anchored only, because the Mesen2 headless runner times out in this environment.
542
542
543
+
#### `C7.06` — 8x8 sprites cannot reach Time Over at all
544
+
545
+
The tile budget is 34 per line, but range evaluation **stops** at the 33rd in-range sprite, so 8x8
546
+
sprites cap out at 32 tiles — under the limit, permanently. `C7.05`'s forty 8x8 sprites set Range
547
+
Over and leave Time Over clear, and the `eval-line-213e` probe reports the same for the same reason.
548
+
Twenty 16x16 sprites give 40 tiles while staying under the 32-sprite range limit, so Time Over trips
549
+
and Range Over must **not** — which the row asserts, since a core raising the two together fails it.
550
+
551
+
The bracket is across the line boundary rather than within a line, because the asserted position is
552
+
fixed and there is no index to sweep: clear on the eval line `V = 100`, set on `V = 101 = YLOC + 1`.
553
+
Phase B deliberately samples on line 101 rather than late on line 100 — RustySNES raises the flag at
554
+
`HBLANK_START_DOT` of the eval line, *earlier* than the assertion requires, and pinning that exact
555
+
dot would fail a core that raises it at `(101, 0)` exactly, which the assertion permits.
556
+
557
+
A low-tile control completes it: the same 20 sprites at 8x8 (20 tiles) must read Time Over **clear**
558
+
at phase B's sampling point. Without it, a core reporting Time Over whenever any sprite is on the
559
+
line passes both A and B. Four injections, each failing its own code — flag on any sprite fails
560
+
**code 4** (the control), never setting fails **code 2**, and setting at dot 0 fails **code 1**.
561
+
562
+
snes9x fails this row too, and is recorded as an expected divergence: it already reads Time Over set
563
+
on `V = 100`, flagging the overflow a line early because it evaluates and paints in one pass. The
564
+
control passes there, so it is the position that is wrong, not the budget.
565
+
543
566
#### `C7.05`/`C7.06` — the probe, and the two sampling traps
544
567
545
568
An earlier revision of the table above said RustySNES sets `range_over` a line late against MesenCE.
Copy file name to clipboardExpand all lines: tests/roms/AccuracySNES/ERROR_CODES.md
+11Lines changed: 11 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1274,6 +1274,17 @@ Provenance: **Documented** (fullsnes and the SNESdev Wiki: range evaluation walk
1274
1274
| 2 |`$04`| Range Over was already set at dot ~105 with the 33rd in-range sprite at OAM index 72 (dot 145) — the set dot does not track OAM.INDEX * 2 |
1275
1275
| 3 |`$06`| Range Over never set at all in phase B, so its clear reading at dot ~105 proved nothing |
1276
1276
1277
+
### C7.06 — TimeOver by YLOC+1
1278
+
1279
+
Provenance: **Documented** (fullsnes and the SNESdev Wiki: the sprite tile budget is 34 per line and Time Over is raised by the fetch phase, so it reads set by the start of the line the sprites paint on). Kind: scored.
1280
+
1281
+
| Code | Byte | Meaning |
1282
+
|---|---|---|
1283
+
| 1 |`$02`| Time Over was already set on the sprites' own line (V = 100), earlier than V = YLOC + 1 |
1284
+
| 2 |`$04`| Time Over had not set by V = YLOC + 1 with 40 sprite-tiles due on the line |
1285
+
| 3 |`$06`| Range Over set alongside Time Over with only 20 sprites on the line — the two flags are being raised together instead of on their own conditions |
1286
+
| 4 |`$08`| Time Over set with only 20 sprite-tiles due, so phase B's reading meant 'sprites are present', not 'the tile budget was exceeded' |
0 commit comments