Session 1: hardware research, content measurement, codec decision, MAME harness

Verified GVRAM is one word-access per pixel in ALL color modes; chose 256-color
256x192 with movem.l bursts (page 1 sacrificed as double-buffer).

Measured 8 scenes from the Blu-ray source: blit costs under 8% of the 12fps
cycle budget, so I/O is the bottleneck, not CPU. Naive delta+RLE reaches only
3.2:1 (365 KB/s, 470MB) -> decision to use 4x4 vector quantization (~30 KB/s).

"Shot on twos" assumption failed: the transfer has zero duplicate frames, so
12fps requires explicit decimation.

Documents three false measurement results and their root causes (per-frame
Floyd-Steinberg dithering, temporal denoise, exact-match dedupe on noisy source).

MAME Lua injection harness works and is reusable for cycle-cost measurement;
the IOCS _B_READ disk benchmark is blocked returning -1.

Claude-Session: https://claude.ai/code/session_01194oWYW8DQXK1SZ2DnChW6
This commit is contained in:
reala-misaki
2026-08-23 11:23:49 -07:00
commit 65112b9305
19 changed files with 842 additions and 0 deletions
+52
View File
@@ -0,0 +1,52 @@
# X68000 hardware facts (verified, not assumed)
Target baseline: X68000 ACE/Expert class. 68000 @ 10MHz, 2MB RAM, SCSI HDD.
## Cycle budget
Content is cel animation shot on twos -> 12fps effective.
10,000,000 / 12 = **833,333 cycles per frame**. This is the wall.
## GVRAM layout [verified: JC-000/x68000-dev-guide docs/graphics.md]
- 512KB physical, mapped at $C00000-$DFFFFF as aliased page windows.
- **One 16-bit word per pixel position, in EVERY color mode.**
Bit depth does NOT change VRAM bandwidth. It only subdivides the word.
- Address formula (512-wide page): `addr = page_base + y*1024 + x*2`
- Horizontally adjacent pixels are 2 bytes apart in all modes.
| Mode | Pages | Word subdivision | Page aliases |
|-------|-------|-----------------------------|-----------------------------------|
| 16 | 4 | nibble per page (P3..P0) | $C00000/$C80000/$D00000/$D80000 |
| 256 | 2 | byte per page (P0=lo,P1=hi) | $C00000 (P0) / $C80000 (P1) |
| 65536 | 1 | whole word | $C00000 |
Writes via a page alias are **auto-masked and shifted by hardware** into that
page's field. No software read-modify-write is needed for 16-color mode.
## Chosen mode: 256 colors, 256x192 active area
Rationale: since every mode is one word-access per pixel, low bit depth buys
no speed. 256-color halves on-disk data vs 65536-color for identical blit cost.
Coalescing trick: in 256-color mode a `move.l` spans two pixel positions across
BOTH pages. We sacrifice page 1 as a double-buffer and let it take duplicate
data, which lets us use `movem.l` bursts:
movem.l d0-d7/a0-a3,(a6) ; 12 regs = 48 bytes = 24 pixels
Full-frame refresh cost: 49,152 px / 24 = 2,048 bursts
~104 cyc/burst + VRAM waits (~1.5x) = ~320k cycles << 833k budget
A hard scene cut fits. Delta frames cost far less.
## Audio
MSM6258 ADPCM via HD63450 DMAC. ~7.8KB/s at 15.6kHz mono, near-zero CPU.
22 min ~= 10MB.
## Storage estimate
~15,800 frames. Target ~3-5KB/frame compressed -> 50-80MB video + 10MB audio.
Stream rate ~40-60KB/s. Well within SCSI sustained throughput.
---
## Corrections applied after session-1 measurement
- Storage estimate below was optimistic. Measured naive codec gives ~470MB @24fps.
See FINDINGS.md §3. VQ codec targets ~40MB.
- "Content is cel animation shot on twos -> 12fps effective" — **the transfer has
zero duplicate frames**; 12fps requires explicit decimation. See FINDINGS.md §3.
- 10MHz models are **SASI**, not SCSI. See FINDINGS.md §5.