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
6.3 KiB
Status & next-session handoff — end of session 1 (2026-08-23)
Decisions locked
| decision | value | why |
|---|---|---|
| Target CPU | 68000 @ 10MHz (stock) | hardest honest constraint |
| Display mode | 256 colors, 256x192 in 256x256 CRTC mode | every mode is 1 word-access/pixel, so 256c is free vs 16c |
| Double buffer | none — page 1 sacrificed | enables movem.l 24px bursts; delta coding needs a RAM reference frame anyway |
| Codec | 4x4 vector quantization, per-scene codebook + block delta | CPU is idle, I/O is the ceiling — spend cycles to buy bandwidth |
| Framerate | 12 fps, explicit decimation | source has zero duplicate frames; no free "twos" win |
| Medium | SCSI HDD image (.hds) | but see SASI/SCSI split below |
| Emulator | MAME 0.277 x68000 | accurate enough that measured cycles mean something |
OPEN QUESTION for the user: stock 10MHz machines are SASI, not SCSI. Three options, not yet chosen:
- Stock 10MHz + SASI (purist) — VQ becomes mandatory
- Stock 10MHz + CZ-6BS1 SCSI board — relieves I/O, keeps CPU honest
- Super/XVI baseline — built-in SCSI, still a 10MHz 68000
Recommendation: make the codec's bitrate ceiling a build parameter, so one encoder serves all three and the target is chosen at package time.
Working setup
MAME ROMs — ~/mame/roms/x68000.zip (present, working).
Must pass -bios ipl10; the default BIOS is cz600ce, whose split
even/odd IPL halves (rh-ix0897cezz.ic12 / rh-ix0898cezz.ic11) are absent.
-verifyroms will still report those two as missing — this is expected and harmless.
Boots headless at ~430-480% speed:
mame x68000 -bios ipl10 -video none -sound none -nothrottle -seconds_to_run 3
Assembler — vasm built from source, binary at tools/vasm/vasmm68k_mot
(source tarball alongside it). Verified correct 68000 output.
tools/vasm/vasmm68k_mot -Fbin -o out.bin in.s
Blu-ray — mount with:
udisksctl loop-setup -r -f DRAGONS_LAIR.iso # -> /media/reala-misaki/BDROM
NOTE: this loop mount is still active from session 1. Re-mount if the machine rebooted.
MAME Lua harness — WORKING, reusable
tools/bench/*.lua inject 68000 machine code straight into emulated RAM and time
it against the emulated clock. No bootable disk or OS required. This is the
measurement rig for all future cycle-cost work (blit timing, decoder benchmarks).
Pattern:
mame x68000 -bios ipl10 -video none -sound none -nothrottle \
-seconds_to_run 30 -plugins -autoboot_script yourscript.lua
Three MAME Lua gotchas — all cost real time, all now solved
- Retain the notifier subscription.
emu.add_machine_frame_notifier()returns a token; if you drop it into a chunk-local it is garbage-collected and the callback silently stops firing. Assign it to a global (SUB = ...). - The stack pointer is
SP, notA7incpu.state[...]. Full list: A0-A6, D0-D7, PC, SP, SR, USP, CURPC, CURFLAGS, IR. autoboot_scriptfires at time=0, before boot (PC=0). Wait untilmachine.time>= ~5s before injecting, or IOCS is not yet initialised.
Also: piping MAME through grep block-buffers output — write raw to a file when
backgrounding, or you will see an empty log and assume a hang.
And never pkill -f 'mame x68000' — the pattern matches your own shell and kills it
(exit 144). Use pkill -x mame.
BLOCKED: disk throughput benchmark
Goal: measure real SASI/SCSI KB/s to replace the folklore figures in FINDINGS.md §5.
Status: harness fully working; the IOCS call itself fails.
IOCS _B_READ ($46 via TRAP #15; d1.hb=PDA, d2.l=position, d3.l=bytes, a1=buffer)
returns FFFFFFFF (-1), zero reads, uniformly across:
- all 16 PDA values $80-$8F
- both d1 encodings (PDA in bits 31-24 and bits 15-8)
- image sizes 10MB / 20MB / 40MB
The uniformity is the diagnostic: calls are dispatched and cleanly rejected,
so TRAP #15 and IOCS are reachable. MAME does mount the image
(:x68k_hdc: opened image file bench.hdf).
Untested hypotheses, in rough order of likelihood:
- The raw image has no X68000 SASI format, so the IPL's boot scan never registered a usable drive and IOCS refuses. Would need Human68k to format one — we have no Human68k image on this system.
- MAME's
x68k_hdcSASI implementation may be too partial for IOCS-level reads. SP=$8000may put the injected stack on top of the IOCS work area in low RAM. Try a much higher stack.- The SCSI path was never tried — this is the obvious next move and is more
relevant to the target anyway:
-exp1 cz6bs1 -hard disk.chdwithexp1:cz6bs1:scsi:0 harddisk(-listmediagains aharddiskslot accepting .chd/.hd/.hdv/.2mg/.hdi).
Honest assessment: this benchmark is NOT on the critical path. The VQ codec (~30 KB/s) is correct whether SASI does 300 or 600 KB/s. Do not let it block the encoder. Its real value is deciding whether the simpler row-span codec could have sufficed.
Caveat if resumed: MAME idealizes drive seek latency. That's acceptable because the realistic deployment is BlueSCSI/SCSI2SD (SD-backed, no mechanical seek), so what gets measured is the bus/DMAC/controller path — the genuine ceiling. The caveat only bites for a real period spinning drive.
Next steps, in priority order
- Build the VQ encoder (
tools/encoder/) — 4x4 blocks, per-scene codebook, block delta. Emit sample PNGs for visual evaluation. The open question is whether VQ softens Bluth's ink linework unacceptably — decide by eye before committing to the architecture. - Full-disc survey — all 224 streams, not 5s samples, to firm up bitrate (current numbers are +/-30%) and map streams onto the arcade scene graph.
- Check the SNES project's license, then evaluate reusing
data/events/(516 chapters / 29 scenes) as the scene-graph and input-timing layer. - Resolve the SASI/SCSI target question with the user.
- Optionally unblock the disk benchmark via the SCSI path.
- 68000 player skeleton: CRTC init for 256x192x256c,
movem.lblitter, ADPCM via HD63450 DMA.
Not yet started
- Any 68000 player code
- ADPCM audio extraction/encoding (MSM6258, 15.6kHz mono, ~7.8 KB/s, ~10MB for 22min)
- Disk image packaging / container format
- Game logic (scene branching, input windows, death clips)