First pixels on an actual X68000 screen. Everything up to now was Python-side
or a headless -video none run, which cannot snapshot at all.
The blocker was not the video controller. The IPL leaves CRTC R20 = 0x0B16,
and bit 11 is "G-VRAM set to buffer", which makes MAME's draw_gfx() return
early. GVRAM writes still land and read back correctly while the layer is
invisible, so six attempts at $E82400/$E82500/$E82600 all rendered black with
every register holding the value I intended.
Two more facts, both confirmed against MAME 0.277 source rather than assumed:
- $E8E001 monitor contrast is left at 14 by the IPL, scaling all output to
93.3%. The player must set it to 15. Contrast 0 blanks the screen, which is
a free fade-to-black for scene transitions.
- The palette word is GGGGGRRRRRBBBBBI with a shared LSB, expanded as
pal6bit((field<<1)|I). With contrast at 15 the render is pixel-exact, not
merely close, which also confirms the 1024-byte GVRAM line stride.
That exactness gives a new quality ceiling: the 15-bit+I palette alone costs
38.88 dB against the 24-bit palettised source, the same order as the scsi
profile's own codec error. scsi is close to display-transparent on hardware,
which bounds how much further it is worth raising.
Unblocks next step 2, the 68000 decoder skeleton, which now has a known-good
reference image to diff against.
Claude-Session: https://claude.ai/code/session_01194oWYW8DQXK1SZ2DnChW6
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