Put the player on a real volume, and find the write window is the frame

ROADMAP K3. src/player/packed.s (2,898 B) brings up its own display, builds
its own 193-entry DMA chain, keeps its own frame clock off V-DISP and fetches
every record itself with READ(10) off a CZ-6BS1. The rig writes no picture
byte, no palette entry and no CRTC register.

120 of 120 frames pixel-exact, every one compared, in both palette orders --
the gate had to grow to do it, because a packed frame is a LITERAL and the
codec's recursion was what made one comparison audit 120.

And the write window turns out to be the frame. A packed write requires R20
bit 11, buffer mode blanks the layer, and a DMAC-direct player holds the
window open for the whole data phase, so

    dark fraction of a slot = record bytes / (DATA-PHASE rate x slot)

which is 1.0 at the container's own 582.0 KB/s: every frame delivered, on
time, pixel-exact, and none of them displayed. The rate in that expression is
the BURST rate, a third hardware number B1 has no test for. It reverses 61.5's
ranking -- a packed player that DMAs to RAM and paints with the measured 27.3%
blit is on screen 72.7% of every slot at any rate, and the two are equal only
at 2,131 KB/s = 3.7x the wire.

And a held channel costs the frame clock half its ticks without the clock
being able to tell: 487 of 1,038 V-DISP edges lost, zero late frames reported,
the player believing 12 fps while the screen ran at 6.37.

FINDINGS 64. ROADMAP K4 opened and fenced behind B2.
check.sh ALL GREEN before and after.

Claude-Session: https://claude.ai/code/session_01194oWYW8DQXK1SZ2DnChW6
This commit is contained in:
prosolis
2026-08-25 09:10:48 -07:00
parent f1007a0dbc
commit 6f698ca226
14 changed files with 2091 additions and 23 deletions
+52 -2
View File
@@ -292,6 +292,53 @@ ships**. The fallback is already a flag: `--scene-palette --no-palette` is
30.79 dB, zero churn, **576.0 KB/s**, and still +2.07 dB on the shipping codec as
the display renders both (FINDINGS 63).
**And the packed player runs, end to end, off the disc — the strongest
result in this tree, next to the worst news in it.** `src/player/packed.s` is
2,898 bytes: the 68000 brings up its own display, builds its own 193-entry DMA
chain, keeps its own frame clock off the CRTC's V-DISP, and fetches every record
itself with `READ(10)` off a real volume. The rig writes **no picture byte, no
palette entry and no CRTC register**. **120 of 120 frames are pixel-exact — every
one compared, in both palette orders** — and the gate had to grow to do it,
because a packed frame is a *literal*: the codec's last frame audits all 120
through its own recursion, and frame 119 here says nothing about frame 60.
![Blu-ray source next to the packed player's own screen](docs/img/packed-player.png)
Left, the source. Right, **MAME's own snapshot** of what the 68000 put on
screen with no decoder in the machine at all — the frame whose PSNR is closest
to the mean, so it is not the flattering one. The window's mean is **33.10 dB**,
which is the packed container's predicted GRB555 figure to the digit.
**And the write window turns out to be the frame.** Free-running — which is what
a 12 fps player becomes once the transfer is longer than the slot — the run
reported a number no budget here has a column for: **the GVRAM write window was
open on 99.5% of the host frames**. Every frame pixel-exact, and almost none of them visible. It is
arithmetic, not an emulator artefact — a packed write *requires* R20 bit 11,
buffer mode blanks the layer, and a DMAC-direct player holds the window open for
the whole data phase, because the packed layout spends both 256-colour pages and
there is no second page to hide behind:
dark fraction of a slot = record bytes / (DATA-PHASE rate x slot)
**The rate in that expression is the BURST rate, not the sustained one**, and
that is a third hardware number the acceptance test did not have. At the
container's own **582.0 KB/s the dark fraction is 1.0**: every frame delivered,
on time, pixel-exact, and none of them displayed. It also **reverses the
ranking**: a packed player that DMAs into RAM with the window shut and paints
with the measured 27.3% blit is on screen **72.7% of every slot at any rate**,
and the two are equal only at **2,131 KB/s — 3.7x the wire**. Below that, which
is every rate anyone has proposed, the player with the CPU in the loop is the
one you can see (FINDINGS 64.2).
**And a held channel costs the frame clock half its ticks, without the clock
being able to tell.** `clock.i` counts V-DISP interrupts; a held channel halts
the 68000; the MFP's pending bit is one bit. Held at 12 fps, **487 of 1,038
edges are lost** — and the player reports **zero late frames**, because the tick
it grades itself against is advanced by the interrupt the channel stopped it
from taking. It believed it was at 12 fps; the screen was at **6.37**. Only the
host's raster count contradicts it, and the gate asserts on the difference
(FINDINGS 64.3).
**The scene graph is in, and the worst gap between two decision points is
zero.** `tools/import/scenegraph.py` imports the arcade scene graph — 40 scenes,
516 sequences, 906 input windows — and 5.4% of the game's 612 branch transitions
@@ -317,12 +364,15 @@ on for eight sessions.
**Current encode:** 496.7 KB/s at 29.19 dB, 1 frame of 120 over the 12fps
budget, and that one is frame 0, the intra frame, late on purpose.
**Green-light check:** `./tools/bench/check.sh` (~4 min, needs the Blu-ray
**Green-light check:** `./tools/bench/check.sh` (~6 min, needs the Blu-ray
mounted) re-runs both display regression tests, the rate-control drift gate, the
display-path coherency counterexample, a 120-frame 68000 decode on two CPU
cores, the ring and paced-ring passes, the DMAC configuration gate and the
load-time transforms on both cores, then imports and gates the scene graph
when a DirkSimple checkout is present, then prints `ALL GREEN`.
when a DirkSimple checkout is present, then builds the packed container and
renders it through px68k's own GVRAM model, then **runs the packed player for
120 frames off a real volume and compares every one of them**, then prints
`ALL GREEN`.
## Reproducing this