diff --git a/README.md b/README.md index 7e0253c..d38d031 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,9 @@ 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 @@ -23,7 +26,10 @@ 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 +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) diff --git a/docs/STATUS.md b/docs/STATUS.md index 7dc6716..2f29419 100644 --- a/docs/STATUS.md +++ b/docs/STATUS.md @@ -1,4 +1,14 @@ -# Status & next-session handoff — session 4 in progress (2026-08-23) +# Status & next-session handoff — end of session 4 (2026-08-23) + +## Start here: is the tree still green? + +``` +./tools/bench/check.sh +``` +~40 s, needs the Blu-ray mounted. Re-runs both display regression tests from +source media and prints `ALL GREEN`. Verified green at end of session 4. +If it fails, fix that before doing anything else — everything downstream assumes +the display path is pixel-exact. ## Decisions locked @@ -65,14 +75,14 @@ rate-distortion curve, not two codecs. MAME 0.277 source**, not folklore: the palette word format, the 1024-byte GVRAM line stride, and the 256-colour page aliasing in `HARDWARE.md`. All three were already written down correctly; they are now cited. -4. **A new quality ceiling was measured** — the 15-bit+I palette alone costs - 38.88 dB, the same order as the `scsi` profile's own codec error. FINDINGS - 22.4. This bounds how much further `scsi` is worth raising. +4. ~~**A new quality ceiling was measured** — the 15-bit+I palette alone costs + 38.88 dB.~~ **Superseded by session 4:** that figure assumed the shared LSB + `I` is always 1. Chosen per entry, the ceiling is **40.81 dB**. FINDINGS 23.3. 5. **Two shell traps that wedged session 2's background jobs** are documented in the working-setup section below. They cost ~1.5 h of wall clock and a wedged CPU core, and one of them was hit again this session. -## What session 4 settled (in progress) +## What session 4 settled 1. **A real 256x256 CRTC mode exists and is verified.** `crtc_mode.lua`, derived from `x68k_crtc.cpp`'s divisor ladder rather than recalled — the derivation is @@ -220,9 +230,14 @@ Three facts the player MUST honour, none of which were guessable: | what | where | value | |---|---|---| | **Un-hide the graphics layer** | CRTC R20 `$E80028` | clear bit 11 ("G-VRAM set to buffer"); IPL leaves `0x0B16` | -| Colour setup (256c) | CRTC R20 bits 9-8 | `0x0100` -> `R20 = 0x0116` | +| Colour setup (256c) | CRTC R20 bits 9-8 | `0x0100` | | **Monitor contrast** | `$E8E001` bits 3-0 | IPL leaves **14**; write **15** or everything renders 7% dark | +The `R20 = 0x0116` value quoted here in session 3 is the **768-wide IPL timing** +with the gate cleared. The shipping value is **`R20 = 0x0110`** — see the mode +table in `tools/bench/crtc_mode.lua`, which is now the single source of truth +for all of R00-R08 and R20. + Bit 11 is the one that cost the most time: GVRAM writes land and read back correctly while the layer is invisible, so the video controller looks guilty and is not. Contrast `0` blanks the screen — free fade-to-black for transitions. @@ -231,10 +246,11 @@ Palette format is now **confirmed from MAME source**, not assumed: `GGGGGRRRRRBBBBBI` (G 15:11, R 10:6, B 5:1, shared LSB I), expanded as `pal6bit((field<<1)|I)`. With contrast at 15 the render is **pixel-exact**. -New 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 -(39.4 dB). `scsi` is close to display-transparent on real hardware. See -FINDINGS 22.4 before considering raising quality further. +Ceiling: the 15-bit+I palette costs **40.81 dB** against the 24-bit palettised +source, once `I` is chosen per entry (FINDINGS 23.3 — session 3's 38.88 dB +assumed `I = 1`). Still the same order as the `scsi` profile's own codec error +(39.4 dB), so `scsi` remains near display-transparent, with ~2 dB more headroom +than session 3 thought. Snapshot recipe that works (`-video none` CANNOT snapshot): ``` @@ -261,6 +277,20 @@ SDL_VIDEODRIVER=dummy mame x68000 -bios ipl10 -video soft -window \ validates the 38% full-frame blit estimate the whole CPU budget rests on. **This is now the top priority** — it is the only remaining unknown that can still invalidate the design. + + **Concrete first step, deliberately smaller than "write the decoder":** do + not start by parsing `DLX1`. Start by making 68000 code do the dumbest + possible full-frame blit — copy 256x192 bytes from RAM to GVRAM through the + mode set by `crtc_mode.lua` — and time it with the existing Lua harness. + That single number either confirms or kills the 38% estimate, and it needs + no bitstream, no codebooks, and no container parsing. `show_frame256.lua` + already produces the exact reference image to diff the result against, and + `verify_frame256.py` already knows how to check it. Only once that number is + in hand is it worth writing the mode dispatch. + + Assembler: `tools/vasm/vasmm68k_mot -Fbin -o out.bin in.s`. The harness + pattern for loading and running 68000 code is in `tools/bench/one.lua` and + `tools/bench/bench.lua` (working, from session 1). 2a. ~~CRTC mode table for 256x192-in-256x256.~~ **DONE, session 4.** Derived from the CRTC divisor ladder (not recalled), verified by snapshot, pixel-exact. `tools/bench/crtc_mode.lua`; write-up in FINDINGS 23; regression test @@ -323,6 +353,8 @@ mkdir -p tmp/snap_verify && cd tmp && SDL_VIDEODRIVER=dummy mame x68000 -bios ip cd .. && python3 tools/bench/verify_frame.py ``` Verified cold from the Blu-ray at end of session 3: exact match, 38.88 dB. +(That 38.88 is correct *for this test*: `show_frame.lua` still packs `I = 1`. +The 40.81 dB ceiling comes from `show_frame256.lua`, which picks `I` per entry.) `tmp/` is gitignored scratch. The frames are NOT in the repo — regenerate them with `extract.py`; the earlier ones lived in `/tmp` and do not survive a reboot. @@ -336,3 +368,19 @@ with `extract.py`; the earlier ones lived in `/tmp` and do not survive a reboot. six register-poking attempts failed against a gate that one grep found. - Blu-ray mounted at `/media/reala-misaki/BDROM` via `udisksctl loop-setup -r -f DRAGONS_LAIR.iso`. + +--- + +## Parked ideas (not scheduled, not abandoned) + +- **Cliff Hanger, retitled as Lupin III** (user, session 4). Stern's 1983 + laserdisc game was cut from *Castle of Cagliostro* and *Mystery of Mamo* with + the Lupin branding stripped; a port would restore it. Technically **cheaper + than this project**: same content class (cel animation, flat colour, hard + cuts), ~13 min of footage vs Dragon's Lair's ~22, and flatter linework than + Bluth's, so fewer blocks should escape to V4/RAW. The codec, the display path, + and `crtc_mode.lua` would all drop straight in. + **The real cost is media prep, not code:** there is no clean master cut to + Stern's scene boundaries the way `DRAGONS_LAIR.iso` is, so the footage would + have to be sourced and cut to match. Not to be started until the CPU path is + proven — it changes nothing about whether this design works. diff --git a/tools/bench/check.sh b/tools/bench/check.sh new file mode 100755 index 0000000..ac6dc82 --- /dev/null +++ b/tools/bench/check.sh @@ -0,0 +1,30 @@ +#!/bin/bash +# Green-light check: re-runs both display regression tests from the Blu-ray. +# ~40 s. Run from the repo root. Any non-zero exit means something drifted. +set -e +cd "$(dirname "$0")/../.." +[ -d /media/reala-misaki/BDROM ] || { + echo "Blu-ray not mounted. udisksctl loop-setup -r -f DRAGONS_LAIR.iso"; exit 2; } + +python3 tools/encoder/extract.py 00020 tmp/fr_00020 12 crop +mkdir -p tmp/snap_verify tmp/snap256 + +run() { # run