Files
vt1200/apps/termtris/HANDOFF.md
T
opencode 8df2320d6d docs(termtris): re-run acceptance at the VR319 default
The branch's evidence was captured on an older MAME binary whose frames
were VR150 (1024x864).  Rebuild MAME from this tree's driver and re-run
verify.sh --skip-mame at the VR319 default (1280x1024 active).

All six tests pass.  Event counts, focus=00400001, tick=887 and quit=1
are unchanged; only the main-loop counts moved with the frame cadence:
move 650, panels 648, quit 555 (was 354/346/300).  The evidence PNGs are
regenerated at 1280x1024.  Record the numbers and the geometry change in
VT1200.md, TERMTRIS_REPORT.md and HANDOFF.md, and note the qemu-i386
toolchain fallback.
2026-11-12 05:56:56 +00:00

7.3 KiB
Raw Blame History

Handoff — termtris running inside the VT1200

Everything here is on branch termtris of https://git.wut.ee/opencode.energia.arti.ee/vt1200.git (remote origin). The branch was developed in a worktree at /home/arti/.local/share/opencode/worktree/26e92e/termtris; any checkout of the branch is equivalent.

git fetch origin termtris
git checkout -b termtris origin/termtris
apps/termtris/verify.sh

verify.sh is the whole acceptance run: ROM checksum, toolchain check, MAME build (skip with --skip-mame), the six tests, the acceptance summary and the evidence list. It exits non-zero on the first failure and keeps every test log under apps/termtris/build/verify_<name>.log. RUNTIME is roughly 12 minutes once MAME is built; the MAME build itself is the long part.

What is done

The upstream game (John Tsiombikas' termtris, commit 7c5435d) builds as a native TMS34010 program with the 1990 TI r5.01 C toolchain under 2ine, loads into VT1200 RAM through dwt/loader, opens a 480×312 window on the terminal's own X server through the ROM Xlib, and reads real X11 key events. It is the actual game: board, score/level/lines panels, piece preview, help and high-score panels, moving/rotating/dropping pieces, and q to quit.

task state commit
vendor + toolchain + XG smoke test done, smoke.sh PASS a861268
sprintf/stdio compat done, fmt.sh PASS a804181
cell-grid X11 backend done, render.sh PASS 264b53a
key map, clock, main loop done, input.sh PASS c1945cf
game integration, scores, COFF done, play.sh/play_keys.sh PASS 41d3cec
docs + harness report done 3e2ddde
review pass (seed, focus, expose, assertions) done 7a2cef5
handoff script + this note done a12fb47
qemu-i386 fallback for kernels without 16-bit LDT done, verify.sh PASS ce40582
VR319 re-run, regenerated evidence, updated numbers done, verify.sh PASS (this commit)

VT1200.md is the port documentation; harness/mame/TERMTRIS_REPORT.md is the harness-side report; the design and plan are in docs/superpowers/specs/2026-11-03-termtris-vt1200-design.md and docs/superpowers/plans/2026-11-03-termtris-vt1200.md.

The VR319 re-run — done

The screenshots and the acceptance numbers used to come from an older MAME binary (/home/arti/code/k-space/mame0289/vt1200d, 30 Oct) that predates the driver's VR319 default. That binary has no VT1200_MONITOR, and its frames are 1024×864, i.e. the old VR150 geometry. The driver in this tree defaults to VR319 (1280×1024 active, 1696×1063 raster), which changes the frame cadence and therefore the frame at which the loader and the tests act.

The branch has now been re-run against a fresh MAME 0.289 build of this tree's driver at the VR319 default. apps/termtris/verify.sh --skip-mame passes all six tests, the evidence PNGs were regenerated at 1280×1024, and the new DIAG values are in VT1200.md and harness/mame/TERMTRIS_REPORT.md. The behaviour did not change: same events, same window (focus=00400001), same quit=1, board/panels/preview all visible. Only the loop counts moved, because the VR319 raster runs at a different emulated frame rate. The loader still acts at frame 2500 and the keys at 3095–3190; no re-timing was needed.

Prerequisites on the new box

  • a MAME 0.289 checkout (MAME_SRC, default /home/arti/code/k-space/mame0289);
  • the 2ine build with lx_loader (NINE=, default /home/arti/os2-work/2ine/build);
  • the r5.01 SDK zips, already in the repo under tools/tms34010-sdk/1990-11 TMS340 Family SDK/;
  • vt1200_v22.bin in the repo root (the harness ROM dir symlinks to it).

The r5.01 tools are 16-bit OS/2 NE programs. If the host kernel was built without CONFIG_X86_16BIT, lx_loader cannot create their 16-bit LDT segments and aborts at its first one; build.sh detects that and runs the same loader under qemu-i386 (install qemu-user), or honours an explicit LX_RUNNER=. This box's cloud kernel is one of those; the generated COFF is unchanged.

verify.sh checks the ROM and the 2ine loader before doing anything, and harness/mame/build.sh re-registers the driver in mame.lst and builds the single-driver vt1200 subtarget.

Expected results

Last full run (MAME 0.289, this tree's driver, VR319 default, 1280×1024 frames; the earlier figures were VR150):

smoke    PASS   type=2 keycode=194 lookup_n=1 ch=61 ks=0061
fmt      PASS   six formats exact
render   PASS   flus=464C5553 progress=00FFFFFF
input    PASS   bytes 61 9B 41 9B 42 9B 44 9B 43 30 0A 7F 71 70
                (a/up/down/left/right/0/Return/Delete/q/p)
play     PASS   DIAG: tick=887 quit=0
play_keys PASS  move   DIAG: loops=650 events=18 last=3 focus=00400001 rev=0 quit=0
                panels DIAG: loops=648 events=12 last=3 focus=00400001 rev=0 quit=0
                quit   DIAG: loops=555 events=10 last=3 focus=00400001 rev=0 quit=1

focus=00400001 is the window the process created; quit=1 is the game's own global after q — that is the proof the key reached the game and not just the window.

Known failure modes (all seen, all diagnosed)

symptom cause handling
build stage "fails" with exit 139 but produced its file 2ine-hosted TI tools crash during teardown build.sh retries only when the output is missing; gspac needs -i.
linker points cinit into .text empty .cinit section build.sh relinks with the one-word CINITZ.obj terminator
XNextEvent never returns an event, keycode zero child's per-process Xlib context is NULL src/vt1200/xgfix.c writes a zeroed 1 KiB block before XOpenDisplay (RAM only)
the game exits immediately at startup, sometimes XOpenDisplay/window creation while the display server settles main() retries 40 × 50 ms, then returns 1
window paints once, then hangs; a debug marker stops mid-flush per-cell flushing overflowed the X socket / XSync per row deadlocked the client flush repaints whole rows (fill + one 80-char string + inverse spans + one XFlush)
playfield is a white block with invisible pieces the 1-bit raster cannot show colour backend drops colour and uses bold (0x80) as reverse; pieces are [/] glyphs
blanked well border with stray X tiles at the top ExposureMask + map-time Expose runs the game's full redraw before it has a piece do not select ExposureMask (current code); if repainting on expose is ever needed, guard full_redraw against cur_piece < 0

Layout

apps/termtris/
├── build.sh            TI r5.01 -> COFF (OUTNAME=termtris for the game)
├── run.sh              interactive MAME session (lightgun/tablet input)
├── verify.sh           one-command acceptance (see above)
├── VT1200.md           port documentation
├── src/game.c          upstream game; only srand(vt_rand_seed()) differs
├── src/vt1200/         main.c x11.c xgfix.c compat.c xlib.h scoredb.c *.asm
├── tests/              smoke fmt render input play play_keys (+ .lua drivers)
├── evidence/           screenshots
└── build/termtris.coff the built image (tracked for convenience)

The tests build from source every run (play.sh/play_keys.sh rebuild termtris.coff), so an edit cannot silently pass by using a stale binary.