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:
+76
-12
@@ -56,6 +56,24 @@ pairing. **B2 now decides which packed CONTAINER exists, not only which player**
|
||||
(63.4). The fallback is 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. **K3 is next.**
|
||||
|
||||
Amended end of session 32: **K3 IS DONE, AND IT FOUND THE THING THAT DECIDES
|
||||
THE BRANCH (FINDINGS 64).** `src/player/packed.s` brings up its own display,
|
||||
builds its own 193-entry chain, keeps its own clock off V-DISP and fetches every
|
||||
record itself off a CZ-6BS1: **120 of 120 frames pixel-exact, every one
|
||||
compared, in both palette orders.** Two things came with it. **(1) The write
|
||||
window is the frame.** A packed write needs R20 bit 11, buffer mode blanks the
|
||||
layer, and a DMAC-direct player holds the window open for the whole data phase
|
||||
— so the dark fraction of a slot is `record / (DATA-PHASE rate x slot)` and a
|
||||
medium that exactly meets the 582.0 KB/s sustained requirement **displays none
|
||||
of the frames it delivers on time**. The rate that matters here is the BURST
|
||||
rate, which is a third hardware number **B1 has no test for**. It also
|
||||
**reverses 61.5's ranking**: a packed player that DMAs to RAM and paints with
|
||||
the CPU opens the window only for the measured 27.3% blit, so it 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**. **(2) A held channel costs the frame clock half its ticks and
|
||||
the clock cannot tell** — 46.9% of V-DISP edges lost, zero late frames reported,
|
||||
the player believing 12 fps while the screen ran at 6.37. **The open item is now
|
||||
K4.**
|
||||
**THE COMPLETION TARGET IS M3, THE VERTICAL SLICE** (USER DECISION): one scene
|
||||
tree — a decision point, two outcomes, a death clip — with audio, streaming from
|
||||
a real SCSI volume on a stock 2 MB machine, playable. That is the point at which
|
||||
@@ -108,7 +126,16 @@ None of these block M2 or M3 software work, because session 18 forced every rate
|
||||
to be an explicit argument. They set constants, and two of them decide how much
|
||||
headroom the finished player has.
|
||||
|
||||
**B1. Measure the BlueSCSI — throughput AND seek time.** **Session 29 gave this
|
||||
**B1. Measure the BlueSCSI — throughput, seek time AND the DATA-PHASE BURST
|
||||
RATE.** The third one is session 32's (FINDINGS 64.2) and it is not a refinement
|
||||
of the first: sustained throughput decides whether record *i* arrives before
|
||||
slot *i*, and the **burst rate during the data phase** decides how much of the
|
||||
slot the picture is on screen, because a DMAC-direct packed player holds the
|
||||
GVRAM write window open for exactly as long as the transfer takes and buffer
|
||||
mode blanks the layer. A drive with a read-ahead cache can pass the first and
|
||||
fail the second. The acceptance test is **`record / (burst x slot)` = the dark
|
||||
fraction**; at the container's own 582.0 KB/s it is 1.0, and the picture is never
|
||||
displayed. **Session 29 gave this
|
||||
a second acceptance test that is not a codec figure at all: 576 KB/s SUSTAINED,
|
||||
which is what a decoder-free packed literal frame costs and cannot be talked down
|
||||
from (FINDINGS 61.5).** A codec's bitrate is a lever; a literal frame's is
|
||||
@@ -286,9 +313,37 @@ frame is not tied to a scene palette the codec's codewords index into. It costs
|
||||
codec's ceiling, so the whole +2.31 dB is the per-frame palette; 90% of that
|
||||
palette changes every frame; and a mismatched paint is 12.8 dB worse, for
|
||||
roughly half of every frame slot, if buffer mode does not blank.
|
||||
- **K3. End to end, off the disc.** Palette, page-1 X-scroll 384, priority
|
||||
`vc1 = 0x0002`, R20 bit 11; one chained DMA a frame. Gated pixel-exact over the
|
||||
same 120-frame window the decoder is gated on.
|
||||
- ~~**K3. End to end, off the disc.**~~ **DONE, session 32 — FINDINGS 64.**
|
||||
`src/player/packed.s`, `tools/bench/packed.lua`, `tools/bench/packed_run.sh`,
|
||||
`tools/bench/verify_packed.py`, `tools/analysis/31_display_duty.py`. Palette,
|
||||
page-1 X-scroll 384, priority `vc1 = 0x0002`, R20 bit 11, one chained DMA a
|
||||
frame, **120 of 120 pixel-exact in both palette orders** — and the gate checks
|
||||
every frame rather than the last, because a packed frame is a literal and the
|
||||
codec's recursion was what made one comparison audit 120.
|
||||
|
||||
**What it found is K4's whole content**, and it is in the amendment above: the
|
||||
window is the frame, the burst rate decides visibility, and a held channel
|
||||
eats the clock.
|
||||
|
||||
- **K4. THE PACKED PLAYER THAT IS ON SCREEN.** 64.2's option B: DMA the record
|
||||
into one of two RAM buffers with the window SHUT, then paint it with the
|
||||
packed `movem` blit (`blit.s` V8, **measured** at 227,553 clocks = 27.3% of a
|
||||
slot). **82.2% of a frame at the 9 clk/B dual-address floor** against A's
|
||||
54.9%, **99,328 B of RAM**, and a picture on screen **72.7% of every slot at
|
||||
any delivery rate** instead of 0% at the container's own wire.
|
||||
|
||||
It is not a rewrite of K3: `packed.s` keeps its display bring-up, its clock,
|
||||
its transport and its record arithmetic, and what changes is the chain's
|
||||
destination and the addition of a paint. **The one thing in it that has never
|
||||
been run is the overlap** — a channel filling buffer *i+1* while the CPU
|
||||
paints buffer *i*, which is the first time in this project that the DMAC and
|
||||
the 68000 have had to want the bus at the same time for a whole scene.
|
||||
|
||||
**K4 is conditional on B2 the same way K3's ranking was**, and the condition
|
||||
now cuts the other way: if buffer mode does NOT blank, A is on screen the whole
|
||||
slot and K4 is 27.3% of a frame spent on nothing. **Do not build K4 before B2
|
||||
is answered** — that is the same rule 61.7 wrote for the codec, applied to the
|
||||
branch that replaced it.
|
||||
|
||||
**What K3 deletes, and why that is a risk and not a win to be banked:** a
|
||||
DMAC-direct packed player has **no ring** — `ring.i`, `xfer.i` and most of
|
||||
@@ -719,17 +774,26 @@ P2 re-encode bundle DONE (60): DLX5, records ARE sectors ───────
|
||||
E7/E4/C1 PARKED session 29: encoder work waits on B2 ───────────┤
|
||||
│
|
||||
K1 palette-register DMA? ─> K2 packed container ─> K3 end to end ──┤
|
||||
(61.9; K1/K2 survive a bad B2, K3 does not) │
|
||||
K1 DONE s30 (62), K2 DONE s31 (63) ── K3 is the open one │
|
||||
K1 DONE s30 (62), K2 DONE s31 (63), K3 DONE s32 (64): │
|
||||
120/120 pixel-exact, both palette orders, off a real volume │
|
||||
└─> and K3 found that the WRITE WINDOW IS THE FRAME, so: │
|
||||
K4 (DMA to RAM + the measured 27.3% paint) is the player │
|
||||
that is ON SCREEN below a 2,131 KB/s BURST rate -- which │
|
||||
is 3.7x the wire, so below every rate anyone has proposed │
|
||||
P4a WIRING (the channel behind ring.i's mailbox) <- THE LAST ITEM ─┤
|
||||
P1 P2 P3 P4b P5 P7, P6 bus cost (52), G1 scene graph (56) ────────┼─> M2 ─>
|
||||
B1 seek+rate (sets HEADROOM, not fit) ─────────────────────────────┘ M3 ─> M4
|
||||
B2 blanking ─┬─ NOT blanked ─> the DECODER-FREE PACKED player is live (61):
|
||||
│ 55.2% of a frame at the 9 clk/B FLOOR, against
|
||||
│ the codec's 110.4% -- and then B1 decides it,
|
||||
│ because it wants 576 KB/s FIXED (61.4, 61.5)
|
||||
└─ blanked ──────> a 27..113% duty strobe; there is no version of
|
||||
it that is merely expensive (48.3, 61.6)
|
||||
B2 blanking ─┬─ NOT blanked ─> K3's DMAC-DIRECT player is the one: 54.9% of a
|
||||
│ frame at the 9 clk/B floor against the codec's
|
||||
│ 110.4%, on screen the whole slot, and K4's paint
|
||||
│ would be 27.3% spent on nothing (61.4, 61.5)
|
||||
└─ blanked ──────> K3's player is on screen for
|
||||
1 - record/(BURST x slot) of every slot, which is
|
||||
ZERO at the container's own wire -- so K4 is the
|
||||
player, at 82.2% of a frame and 99,328 B of RAM
|
||||
(64.2). Neither answer kills the branch and each
|
||||
picks a different player.
|
||||
B1 BURST rate (NEW, 64.2) ──> which of the two K3/K4 wins, if B2 blanks
|
||||
```
|
||||
|
||||
**Read that top-left branch as the project's live question.** Everything else
|
||||
|
||||
Reference in New Issue
Block a user