prosolis 09a5a50065 Measure the blit on the 68000: the 38% estimate was 53.6%
First 68000 instructions in this project to draw a pixel. Everything before
this was GVRAM filled from Lua, which costs zero 68000 cycles, so the blit
figure the whole CPU budget rests on had never been validated.

Four variants of a full-frame 256x192 paint, timed in MAME and each also
hand-derived from the MC68000 timing tables beforehand; the two agree to
0.006-0.43%, which is what makes the result trustworthy after this project's
history of false-good measurements.

  V1 movem.l blit from a word-expanded RAM frame   446,286 cyc   53.6%
  V2 naive move.b/move.w per pixel               1,284,174 cyc  154.1%
  V3 write-only floor, no source read              225,789 cyc   27.1%
  V4 same writes in 4x4 block order                637,971 cyc   76.6%

Scope: MAME's gvram_w/gvram_r carry no timing at all, so these are instruction
cycles against zero-wait-state memory -- a floor, not a hardware prediction.

V1's output snapshots pixel-exact through verify_frame256.py, closing
FINDINGS 23.5. The V1/V3 gap shows reading the source frame is exactly half
the cost, which makes the architecture question live: decode-direct-to-GVRAM
needs no RAM reference frame and scales with the non-SKIP block fraction,
crossing compose-then-blit at 70% of blocks changed. That fraction is now the
top priority and is already a by-product of vq_hybrid.py's mode decision.

Claude-Session: https://claude.ai/code/session_01194oWYW8DQXK1SZ2DnChW6
2026-08-23 13:43:56 -07:00

Dragon's Lair — Sharp X68000 port

Porting Dragon's Lair to a stock X68000 (68000 @ 10MHz, 2MB, SASI/SCSI).

This is fundamentally a video codec problem, not a game-logic problem: the game logic is a scene table with branching input windows; the difficulty is pushing ~22 minutes of Don Bluth animation through a 10MHz 68000.

Green-light check: ./tools/bench/check.sh (~40 s, needs the Blu-ray mounted) re-runs both display regression tests and prints ALL GREEN.

Read first

  • docs/FINDINGS.md — measured hardware facts, content statistics, codec decision, and a section on measurement traps that produced three separate false results. Read §4 before trusting any pipeline number.
  • docs/STATUS.md — current state, working setup, blockers, next steps. Start here. It also lists what has been explicitly abandoned, so old ideas do not get re-proposed.
  • docs/BENCHMARK.md — how to measure the storage subsystem, and why a bandwidth figure out of MAME would be meaningless.
  • docs/HARDWARE.md — X68000 GVRAM/CRTC reference.

Layout

docs/            findings, status, hardware reference
tools/analysis/  measurement scripts, numbered in the order they were written
                 (01/02 marked BROKEN deliberately, kept as regression refs).
                 Run from the repo root — they import from tools/encoder/.
tools/bench/     MAME Lua injection harness + 68000 benchmark sources.
                 `check.sh` re-runs both display regression tests (~40 s).
                 `crtc_mode.lua` is the single source of truth for CRTC R00-R08
                 and R20 — do not write CRTC values anywhere else.
tools/vasm/      vasm m68k assembler (built from source)
tools/encoder/   hybrid VQ encoder + DLX1 container writer (working)
src/player/      68000 player (not yet written)
assets/          extracted frames/audio (gitignored)

Encoder

python3 tools/encoder/extract.py 00020 /tmp/fr 12 crop
python3 tools/encoder/encode.py  /tmp/fr out.dlx --profile sasi --preview p.png

Two quality profiles ship from one codec and one decoder — sasi (110 KB/s) and scsi (280 KB/s) are two points on the same rate-distortion curve. The codec is a Cinepak-style hybrid: each 4x4 block is coded as SKIP, one 4x4 codeword, four 2x2 codewords, or RAW literal pixels, chosen per block by rate-distortion.

The RAW escape means lam=0 is pixel-exact against the palettised frame, so the quality knob spans lossless to heavily-compressed without changing the bitstream.

Profiles are derived from a bandwidth figure, not chosen by eye:

python3 tools/encoder/profile_gen.py --bw-mbps 4 --name scsi

On reading docs/FINDINGS.md: it is append-only and several later sections overturn earlier ones. Superseded sections carry a blockquote at the top pointing to the correction — heed those, especially 18 (reversed by 21).

Source media (DRAGONS_LAIR.iso) and ROMs are gitignored — supply your own.

S
Description
No description provided
Readme
25 MiB
Languages
Python 53.1%
Assembly 20.4%
Lua 15.3%
Shell 8.8%
C 2.3%
Other 0.1%