From 7a2cef56add5db0adbb130194a7a4688e644dc38 Mon Sep 17 00:00:00 2001 From: "opencode.energia.arti.ee" Date: Wed, 11 Nov 2026 17:59:16 +0000 Subject: [PATCH] fix(termtris): review pass -- seed, focus/pause, expose, test assertions - seed the game from the raw 0x1E93C0 counter (now_ms() returns 0 on its first call, so the old seed was always zero) - track pause ourselves: FocusOut pauses once, FocusIn resumes only what we paused (game_input('p') is a toggle) - select ExposureMask so the Expose redraw path actually fires - play.sh/play_keys.sh rebuild the COFF (OUTNAME=termtris) and assert the run: status=0, tick>0, loops/events/quit per mode; render.sh asserts the renderer finished; map symbol lookup is column-order independent - run.sh passes -lightgun -lightgun_device mouse so the pointer drives the tablet - docs: link map addresses, monochrome/reverse wording, honest caption and limits text Verified here: play.sh and input.sh pass. Still open: the MAME driver in the tree is newer than the installed binary (Oct 30 build, VR150-era geometry), so the acceptance suite must be re-run after a rebuild. --- .gitignore | 1 - apps/termtris/VT1200.md | 17 +- apps/termtris/build.sh | 5 - apps/termtris/build/termtris.coff | Bin 15118 -> 15208 bytes apps/termtris/build/termtris.map | 213 +++++++++--------- apps/termtris/evidence/termtris_frame3300.png | Bin 19347 -> 19499 bytes apps/termtris/run.sh | 1 + apps/termtris/src/game.c | 4 +- apps/termtris/src/vt1200/main.c | 20 +- apps/termtris/src/vt1200/x11.c | 2 +- apps/termtris/tests/fmt.sh | 2 +- apps/termtris/tests/input.lua | 3 + apps/termtris/tests/input.sh | 4 +- apps/termtris/tests/play.lua | 5 + apps/termtris/tests/play.sh | 16 +- apps/termtris/tests/play_keys.sh | 3 + apps/termtris/tests/render.sh | 12 +- apps/termtris/tests/smoke.sh | 2 +- harness/mame/TERMTRIS_REPORT.md | 7 +- 19 files changed, 183 insertions(+), 134 deletions(-) diff --git a/.gitignore b/.gitignore index 7bc69e1..c7909c8 100644 --- a/.gitignore +++ b/.gitignore @@ -73,7 +73,6 @@ tools/tms34010-sdk/1991-07 TIGA Promo Kit and Art Software/ # termtris build scratch (TI tools + 2ine libs) apps/termtris/work/ apps/termtris/build/*.log -apps/termtris/build/*.log apps/termtris/build/smoke.* apps/termtris/build/fmt.* apps/termtris/build/render.* diff --git a/apps/termtris/VT1200.md b/apps/termtris/VT1200.md index 0add46b..8d418e9 100644 --- a/apps/termtris/VT1200.md +++ b/apps/termtris/VT1200.md @@ -40,7 +40,7 @@ Link map (relevant addresses are **bit** addresses, like everything the TMS34010 sees): ``` -.text 018A0000 .data 018A0000 .cinit 018B4730 +.text 018A0000 .data 018A0000 .cinit 018B4B10 .bss 01A00000 ENTRY POINT SYMBOL: "_start" address: 018a0000 ``` @@ -63,8 +63,9 @@ untouched. With that in place the smoke test receives a real The frame is an 80×24 grid of 6×13 cells (the default GC font, baseline +10), so the window is 480×312. The VT1200 raster is **one bit deep**, so the backend -follows the game's own monochrome convention (`ansi.c -m`): colour is dropped -and the bold bit (`0x80`) reverses a cell. The playfield is therefore black +renders like the game's monochrome mode (colour is dropped) and uses the bold +bit (`0x80`) as reverse video for emphasis — a choice of this backend, not the +upstream ANSI convention (which emits SGR bold and leaves the colours alone). The playfield is therefore black spaces and the tetrominoes are the `[`/`]` tiles, exactly what a 1-bit terminal can show. @@ -123,8 +124,9 @@ panels DIAG: loops=323 events=12 focus=00400001 quit=0 quit DIAG: loops=277 events=10 focus=00400001 quit=1 ``` -`focus=00400001` is the termtris window, so the key events really were -delivered to it, and `quit=1` is the game's own global after `q`. +`focus=00400001` is the window this process created (it is the only one in the +run), so the key events were delivered to it, and `quit=1` is the game's own +global after `q`. ## Limits, stated plainly @@ -136,8 +138,9 @@ delivered to it, and `quit=1` is the game's own global after `q`. display server is still settling, `main()` retries up to 40 times with a 50 ms sleep before giving up. Observed as an intermittent early exit. * **`q` ends the game loop but the window stays on screen.** `quit=1` is - observable in RAM; the created process does not tear down its X connection, - so the server keeps the window. + observable in RAM and `main()` returns; the frame captured about a second + later still shows the window, so the X connection is not torn down by process + exit in this OS. Treat that as an observation, not a designed behaviour. * **The board is text.** Tetrominoes are `[`/`]` tiles, not filled blocks — the only thing a 1-bit cell can show without a custom font. diff --git a/apps/termtris/build.sh b/apps/termtris/build.sh index 39c3b06..6b0c33e 100755 --- a/apps/termtris/build.sh +++ b/apps/termtris/build.sh @@ -103,11 +103,6 @@ compile_asm() { run "$base.obj" ./gspa.exe "$base.ASM" } -for base in $OBJS; do - case " $* " in - *" $base "*) ;; # handled below by extension scan - esac -done # Compile every collected object exactly once, in the order given. for arg in "$@"; do diff --git a/apps/termtris/build/termtris.coff b/apps/termtris/build/termtris.coff index 6c515d9717a183721e60d921df7d5405f808769b..cf4275a89a324a6c4360adfeba20763154b83f28 100644 GIT binary patch delta 7312 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 P-qxn3#&d=DPfGs>l;HRs delta 7132 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 diff --git a/apps/termtris/build/termtris.map b/apps/termtris/build/termtris.map index f8a9ea8..78e98d3 100644 --- a/apps/termtris/build/termtris.map +++ b/apps/termtris/build/termtris.map @@ -1,7 +1,7 @@ ***************************************************** TMS340 COFF Linker Version 5.01 ***************************************************** -Tue Nov 03 20:09:24 2026 +Wed Nov 11 17:58:44 2026 OUTPUT FILE NAME: ENTRY POINT SYMBOL: "_start" address: 018a0000 @@ -20,38 +20,38 @@ SECTION ALLOCATION MAP output attributes/ section page origin length input sections -------- ---- ---------- ---------- ---------------- -.text 0 018a0000 00014940 +.text 0 018a0000 00014b10 018a0000 00000150 ENTRY.obj (.text) - 018a0150 00001c90 MAIN.obj (.text) - 018a1de0 0000ce50 GAME.obj (.text) - 018aec30 00000d20 SCOREDB.obj (.text) - 018af950 00002a40 X11.obj (.text) - 018b2390 00001640 COMPAT.obj (.text) - 018b39d0 00000210 XGFIX.obj (.text) - 018b3be0 00000450 rts.lib (.text) - 018b4030 000001a0 rts.lib (.text) - 018b41d0 00000230 rts.lib (.text) - 018b4400 00000150 rts.lib (.text) - 018b4550 00000120 rts.lib (.text) - 018b4670 00000110 rts.lib (.text) - 018b4780 000001c0 rts.lib (.text) + 018a0150 00001e60 MAIN.obj (.text) + 018a1fb0 0000ce50 GAME.obj (.text) + 018aee00 00000d20 SCOREDB.obj (.text) + 018afb20 00002a40 X11.obj (.text) + 018b2560 00001640 COMPAT.obj (.text) + 018b3ba0 00000210 XGFIX.obj (.text) + 018b3db0 00000450 rts.lib (.text) + 018b4200 000001a0 rts.lib (.text) + 018b43a0 00000230 rts.lib (.text) + 018b45d0 00000150 rts.lib (.text) + 018b4720 00000120 rts.lib (.text) + 018b4840 00000110 rts.lib (.text) + 018b4950 000001c0 rts.lib (.text) -.cinit 0 018b4940 000012d0 - 018b4940 00000050 MAIN.obj (.cinit) - 018b4990 00001190 GAME.obj (.cinit) - 018b5b20 00000050 SCOREDB.obj (.cinit) - 018b5b70 00000050 X11.obj (.cinit) - 018b5bc0 00000050 rts.lib (.cinit) +.cinit 0 018b4b10 000012d0 + 018b4b10 00000050 MAIN.obj (.cinit) + 018b4b60 00001190 GAME.obj (.cinit) + 018b5cf0 00000050 SCOREDB.obj (.cinit) + 018b5d40 00000050 X11.obj (.cinit) + 018b5d90 00000050 rts.lib (.cinit) -.bss 0 01a00000 0001ec00 UNINITIALIZED +.bss 0 01a00000 0001ec20 UNINITIALIZED 01a00000 00008000 ENTRY.obj (.bss) - 01a08000 00000400 MAIN.obj (.bss) - 01a08400 00004a40 GAME.obj (.bss) - 01a0ce40 00000b80 SCOREDB.obj (.bss) - 01a0d9c0 0000f200 X11.obj (.bss) - 01a1cbc0 00000020 COMPAT.obj (.bss) - 01a1cbe0 00002000 XGFIX.obj (.bss) - 01a1ebe0 00000020 rts.lib (.bss) + 01a08000 00000420 MAIN.obj (.bss) + 01a08420 00004a40 GAME.obj (.bss) + 01a0ce60 00000b80 SCOREDB.obj (.bss) + 01a0d9e0 0000f200 X11.obj (.bss) + 01a1cbe0 00000020 COMPAT.obj (.bss) + 01a1cc00 00002000 XGFIX.obj (.bss) + 01a1ec00 00000020 rts.lib (.bss) .data 0 018a0000 00000000 UNINITIALIZED @@ -60,81 +60,82 @@ GLOBAL SYMBOLS address name address name -------- ---- -------- ---- -01a00000 .bss 018a0000 .text -018a0000 .data 018a0000 .data -018a0000 .text 018a0000 edata -01a08a00 _blackpf 018a0000 _start -018a2f40 _cleanup_game 018a0150 _now_ms -01a08380 _dbg_events 018a03d0 _sleep_ms -01a083c0 _dbg_focus 018a0530 _vt_poll_event -01a083a0 _dbg_last 018a0ea0 _vt_handle_event -01a08360 _dbg_loops 018a1700 _wait_display -01a083e0 _dbg_rev 018a1740 _main -018b2390 _fflush 018a1de0 _init_game -018a84e0 _game_input 018a2f40 _cleanup_game -018a1de0 _init_game 018a3130 _update -018a1740 _main 018a84e0 _game_input -018b3be0 _memcpy 018aef90 _read_scores -018b3d80 _memmove 018af310 _save_score -018b4030 _memset 018af8a0 _print_scores -01a089a0 _monochrome 018af950 _vt_root_window -018a0150 _now_ms 018afa30 _vt_x11_init -01a089e0 _onlyascii 018b01e0 _x11_clearscr -018af8a0 _print_scores 018b03a0 _x11_reset -018b2400 _putchar 018b03e0 _x11_cursor -01a08940 _quit 018b0440 _x11_setcolor -018b41d0 _rand 018b0560 _x11_setcursor -018aef90 _read_scores 018b07b0 _x11_ibmchar -01a08a20 _rotstep 018b0c30 _term_putstr -018af310 _save_score 018b0dd0 _vt_x11_flush -01a08a80 _scr 018b2000 _vt_x11_term_init -018a03d0 _sleep_ms 018b2320 _term_init -018b2c10 _sprintf 018b2390 _fflush -018b4330 _srand 018b2400 _putchar -018a0000 _start 018b2c10 _sprintf -01a1cbc0 _stdout 018b39d0 _vt_install_xg -018b4400 _strcmp 018b3be0 _memcpy -018b4550 _strcpy 018b3d80 _memmove -018b4670 _strlen 018b4030 _memset -018b4780 _strncpy 018b41d0 _rand -01a1cae0 _term_clearscr 018b4330 _srand -01a1cb20 _term_cursor 018b4400 _strcmp -01a08a60 _term_height 018b4550 _strcpy -01a1cb60 _term_ibmchar 018b4670 _strlen -018b2320 _term_init 018b4780 _strncpy -018b0c30 _term_putstr 018b4940 cinit -01a1cac0 _term_reset 018b4940 etext -01a1cb40 _term_setcolor 01a00000 .bss -01a1cb00 _term_setcursor 01a08360 _dbg_loops -01a1cba0 _term_type 01a08380 _dbg_events -01a08a40 _term_width 01a083a0 _dbg_last -01a1cb80 _termenv 01a083c0 _dbg_focus -01a08960 _tick_interval 01a083e0 _dbg_rev -018a3130 _update 01a08940 _quit -01a08980 _use_bell 01a08960 _tick_interval -01a089c0 _use_gfxchar 01a08980 _use_bell -01a0ce40 _username 01a089a0 _monochrome -01a1ca40 _vt_dpy 01a089c0 _use_gfxchar -01a1ca80 _vt_gc 01a089e0 _onlyascii -018a0ea0 _vt_handle_event 01a08a00 _blackpf -018b39d0 _vt_install_xg 01a08a20 _rotstep -018a0530 _vt_poll_event 01a08a40 _term_width -018af950 _vt_root_window 01a08a60 _term_height -01a1ca60 _vt_win 01a08a80 _scr -018b0dd0 _vt_x11_flush 01a0ce40 _username -018afa30 _vt_x11_init 01a1ca40 _vt_dpy -01a1caa0 _vt_x11_progress 01a1ca60 _vt_win -018b2000 _vt_x11_term_init 01a1ca80 _vt_gc -018a1700 _wait_display 01a1caa0 _vt_x11_progress -018b01e0 _x11_clearscr 01a1cac0 _term_reset -018b03e0 _x11_cursor 01a1cae0 _term_clearscr -018b07b0 _x11_ibmchar 01a1cb00 _term_setcursor -018b03a0 _x11_reset 01a1cb20 _term_cursor -018b0440 _x11_setcolor 01a1cb40 _term_setcolor -018b0560 _x11_setcursor 01a1cb60 _term_ibmchar -018b4940 cinit 01a1cb80 _termenv -018a0000 edata 01a1cba0 _term_type -01a1ec00 end 01a1cbc0 _stdout -018b4940 etext 01a1ec00 end +01a00000 .bss 018a0000 .data +018a0000 .data 018a0000 .text +018a0000 .text 018a0000 _start +01a08a20 _blackpf 018a0000 edata +018a3110 _cleanup_game 018a0150 _now_ms +01a083a0 _dbg_events 018a03d0 _vt_rand_seed +01a083e0 _dbg_focus 018a0420 _sleep_ms +01a083c0 _dbg_last 018a0580 _vt_poll_event +01a08380 _dbg_loops 018a0ef0 _vt_handle_event +01a08400 _dbg_rev 018a18d0 _wait_display +018b2560 _fflush 018a1910 _main +018a86b0 _game_input 018a1fb0 _init_game +018a1fb0 _init_game 018a3110 _cleanup_game +018a1910 _main 018a3300 _update +018b3db0 _memcpy 018a86b0 _game_input +018b3f50 _memmove 018af160 _read_scores +018b4200 _memset 018af4e0 _save_score +01a089c0 _monochrome 018afa70 _print_scores +018a0150 _now_ms 018afb20 _vt_root_window +01a08a00 _onlyascii 018afc00 _vt_x11_init +018afa70 _print_scores 018b03b0 _x11_clearscr +018b25d0 _putchar 018b0570 _x11_reset +01a08960 _quit 018b05b0 _x11_cursor +018b43a0 _rand 018b0610 _x11_setcolor +018af160 _read_scores 018b0730 _x11_setcursor +01a08a40 _rotstep 018b0980 _x11_ibmchar +018af4e0 _save_score 018b0e00 _term_putstr +01a08aa0 _scr 018b0fa0 _vt_x11_flush +018a0420 _sleep_ms 018b21d0 _vt_x11_term_init +018b2de0 _sprintf 018b24f0 _term_init +018b4500 _srand 018b2560 _fflush +018a0000 _start 018b25d0 _putchar +01a1cbe0 _stdout 018b2de0 _sprintf +018b45d0 _strcmp 018b3ba0 _vt_install_xg +018b4720 _strcpy 018b3db0 _memcpy +018b4840 _strlen 018b3f50 _memmove +018b4950 _strncpy 018b4200 _memset +01a1cb00 _term_clearscr 018b43a0 _rand +01a1cb40 _term_cursor 018b4500 _srand +01a08a80 _term_height 018b45d0 _strcmp +01a1cb80 _term_ibmchar 018b4720 _strcpy +018b24f0 _term_init 018b4840 _strlen +018b0e00 _term_putstr 018b4950 _strncpy +01a1cae0 _term_reset 018b4b10 cinit +01a1cb60 _term_setcolor 018b4b10 etext +01a1cb20 _term_setcursor 01a00000 .bss +01a1cbc0 _term_type 01a08380 _dbg_loops +01a08a60 _term_width 01a083a0 _dbg_events +01a1cba0 _termenv 01a083c0 _dbg_last +01a08980 _tick_interval 01a083e0 _dbg_focus +018a3300 _update 01a08400 _dbg_rev +01a089a0 _use_bell 01a08960 _quit +01a089e0 _use_gfxchar 01a08980 _tick_interval +01a0ce60 _username 01a089a0 _use_bell +01a1ca60 _vt_dpy 01a089c0 _monochrome +01a1caa0 _vt_gc 01a089e0 _use_gfxchar +018a0ef0 _vt_handle_event 01a08a00 _onlyascii +018b3ba0 _vt_install_xg 01a08a20 _blackpf +018a0580 _vt_poll_event 01a08a40 _rotstep +018a03d0 _vt_rand_seed 01a08a60 _term_width +018afb20 _vt_root_window 01a08a80 _term_height +01a1ca80 _vt_win 01a08aa0 _scr +018b0fa0 _vt_x11_flush 01a0ce60 _username +018afc00 _vt_x11_init 01a1ca60 _vt_dpy +01a1cac0 _vt_x11_progress 01a1ca80 _vt_win +018b21d0 _vt_x11_term_init 01a1caa0 _vt_gc +018a18d0 _wait_display 01a1cac0 _vt_x11_progress +018b03b0 _x11_clearscr 01a1cae0 _term_reset +018b05b0 _x11_cursor 01a1cb00 _term_clearscr +018b0980 _x11_ibmchar 01a1cb20 _term_setcursor +018b0570 _x11_reset 01a1cb40 _term_cursor +018b0610 _x11_setcolor 01a1cb60 _term_setcolor +018b0730 _x11_setcursor 01a1cb80 _term_ibmchar +018b4b10 cinit 01a1cba0 _termenv +018a0000 edata 01a1cbc0 _term_type +01a1ec20 end 01a1cbe0 _stdout +018b4b10 etext 01a1ec20 end -[76 symbols] +[77 symbols] diff --git a/apps/termtris/evidence/termtris_frame3300.png b/apps/termtris/evidence/termtris_frame3300.png index 47128cb0eb6bce2d62a79645d42ae1b074ac3e3a..54cbf26993349c5ac36bd8b266d7a82321ae8587 100644 GIT binary patch literal 19499 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 literal 19347 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

V=wgul?*b2O_` zDt4tTmfnvkDt$W)WBtKz!gEK4zA2lHFyX^hUm3c;0b;ZS67w8il z9_^??g>PaFx7&gd>l)jCtpc}hI%{})z_$oR%QnPB$UDl9Cf$9&XFrwu3RAwA(a%M$ zJJ?={n%eokRo*MftaU-q#_Us>nZq!k)s`%($k==3@bHeiXEf+WaYUuRAI;eBFF#o+ zCq^4&HgX*WiFydmV6!Jyd4Vjhqve9b49@nw#&Qoi-+GG?NxrFGb{JNsPY@R z+Z46JJV8)le{(o)Pzr=briyZ52}^!#HG%x;?Pkl6G-4$M*w8uCa%d={M$vSCtcCP3 zSANo)>swy6Am$0uoneksdLvp{$tk8(`!4Wt5h=%!$g2rl{oM4D8Mwh|{%nqfBxM(x z^CYF@D>VAn{_^OdAsiu`<3m(dE%s@6ygEmN+JU~dV<5jM(v&xLkmzeFUvP0vVHW$I;q3V8?*`00V@J+$J6NYY>(0 z1v!NWf(PHdRDUi9pz~&xufsmIGXhit&N#>1nQ=P|j{qZq>+O*9nLx(Ci?hHtP(vX< zBt-4iLe|VnQXK6}>DM2AU5^z=%75nYD(mhB_$oOOpY@gxc4h;i-i$ft&Mcf)aRCI1 z5gb12I_yjkANlka7k$%^;AN`Eaqb&UI#+j!h^4E^7mp}HR>*}8q$RB%T6sf?P7D{S8m(sCjqV7JG+2;8|M3K z!tvsTE{M z&kf4%w;Fs}cw5OMj)7#L)?yc}IAe#xc^x=jB>Zr+syRmq;@2R4%r0ob8ieF3yFj$w z`jf(o5mfXrtSfg;3R+qu*-2vZC%N9zYw^58zS<|hZrvW)w0}U6kM0~qWpI;u3nRJN z3<^t*$z z>DIFY<3kQ;!gn9xHev)m)#Ib_dm9+It|I$`VyXbc@7F`Da4Xci4{w~vlk=d93Asm) zb*OS8`@Cc+%;ubwRM~TLY}dOdKLI~NNyFXbcTl0+4|6tu;c(rb5$V&x&g_aT?O7aC zyS-F1i87g^%NfpHi46Nq4>VvEH|OLC7|07M<#3q`hRk%5io%jrb*h9$CdRVSOXGoe z)zstlShyNx$ZAZ0pP{lY4vLqqj7AJ*@zeN?Hh9Z3{!+eOflL~{680*L&W_(p!XgO2 zmI?!$@U&5}oK2}2xMr5pR|YMWa=nH!vr*pMLgauyJbUs$44Nb`$KX@WB5D?0903LKnIjVTrqb|$ z5-@IrVsDNQfX}K8m;SkPLLcGjb@_0`DwNj%^5=o?Ju6+^+;+Kij9{&k&YMBEa|z9b zwe+c!0GOC>Oo{>-iYis29L)<2dH51O7m?JaZdVd%wyFM*57hpU4-cZ%V$)3a{{XOxQl z0jj4E=W*;7Rrzo#sKFG&e+4O5F3#E+abE8qP|R*JJv()TyW}rrC58W`EV)DdFX~YLKa0VOWeesQ{=zlU8eI)RN%AOzhSgqP*xW(9H)w&QrZ$E#u-}>c~VG&^9M)|<- zpx_g}D!Z(HTIF. #include "term.h" #include "scoredb.h" -extern long now_ms(void); +extern unsigned vt_rand_seed(void); int quit; @@ -192,7 +192,7 @@ int init_game(void) scores = read_scores(0, 10); memset(&cur_score, 0, sizeof cur_score); - srand((unsigned)now_ms()); + srand(vt_rand_seed()); pause = 0; gameover = 0; diff --git a/apps/termtris/src/vt1200/main.c b/apps/termtris/src/vt1200/main.c index 650b978..f4500eb 100644 --- a/apps/termtris/src/vt1200/main.c +++ b/apps/termtris/src/vt1200/main.c @@ -18,6 +18,7 @@ static vt_u32 evbuf[24]; static long ms_base; static int ms_last = -1; static int focused; +static int vt_paused; volatile vt_u32 dbg_loops, dbg_events, dbg_last, dbg_focus, dbg_rev; long now_ms(void) @@ -34,6 +35,16 @@ long now_ms(void) return ms_base; } +/* + * Seed for the game's PRNG. now_ms() returns 0 on its first call (it only + * latches the counter there), so seeding from it gives a constant; read the + * free-running 16-bit tick directly instead. + */ +unsigned vt_rand_seed(void) +{ + return (unsigned)*(volatile unsigned short *)0x001E93C0UL; +} + void sleep_ms(int ms) { if(ms < 1) ms = 1; @@ -105,8 +116,15 @@ void vt_handle_event(void) game_input('`'); } else if(evbuf[0] == 9) { /* FocusIn */ focused = 1; + if(vt_paused) { /* resume only what we paused */ + game_input('p'); + vt_paused = 0; + } } else if(evbuf[0] == 10) { /* FocusOut */ - if(focused) game_input('p'); + if(focused && !vt_paused) { + game_input('p'); /* 'p' toggles pause in game_input */ + vt_paused = 1; + } focused = 0; } } diff --git a/apps/termtris/src/vt1200/x11.c b/apps/termtris/src/vt1200/x11.c index 9d89af5..54139f2 100644 --- a/apps/termtris/src/vt1200/x11.c +++ b/apps/termtris/src/vt1200/x11.c @@ -64,7 +64,7 @@ int vt_x11_init(void) if(!vt_win) return -1; vt_x11_progress = 14; - VT_XSELECT(vt_dpy, vt_win, 0x22000FUL); + VT_XSELECT(vt_dpy, vt_win, 0x22800FUL); /* + ExposureMask */ vt_gc = VT_XGC(vt_dpy, vt_win, 0, 0); if(!vt_gc) return -1; diff --git a/apps/termtris/tests/fmt.sh b/apps/termtris/tests/fmt.sh index acb354b..19ff689 100755 --- a/apps/termtris/tests/fmt.sh +++ b/apps/termtris/tests/fmt.sh @@ -12,7 +12,7 @@ LOG="$APP/build/fmt.log" mkdir -p "$APP/build" "$APP/build.sh" "$DIR/fmt.c" "$APP/src/vt1200/compat.c" >"$APP/build/fmt-build.log" 2>&1 -FMT=$(awk '/_out/ {print $1; exit}' "$APP/build/fmt.map") +FMT=$(awk '{for(i=2;i<=NF;i++) if($i=="_out") print $(i-1)}' "$APP/build/fmt.map" | head -1) VT1200_SKIP_LEVEL1=1 FMT_MARK="0x$FMT" \ LOADER_AT=2500 LOADER_END=2700 \ LOADER_BIN="$ROOT/dwt/loader/build/loader.bin" \ diff --git a/apps/termtris/tests/input.lua b/apps/termtris/tests/input.lua index ca3c703..fd89e54 100644 --- a/apps/termtris/tests/input.lua +++ b/apps/termtris/tests/input.lua @@ -36,6 +36,7 @@ local key_zero = ports[":lk401:K10"].fields["0 )"] local key_ret = ports[":lk401:K68"].fields["Return"] local key_del = ports[":lk401:K67"].fields["Delete"] local key_q = ports[":lk401:K13"].fields["Q"] +local key_p = ports[":lk401:K22"].fields["P"] local tabx = ports[":tablet:TABLET_X"].fields["Tablet X"] local taby = ports[":tablet:TABLET_Y"].fields["Tablet Y"] local tabb = ports[":tablet:TABLET_BTN"].fields["P1 Button 1"] @@ -154,6 +155,8 @@ local function key_step(frames, key) if frames == 3250 then key_del:set_value(0) end if frames == 3260 then key_q:set_value(1) end if frames == 3270 then key_q:set_value(0) end + if frames == 3280 then key_p:set_value(1) end + if frames == 3290 then key_p:set_value(0) end end local function r32(a) diff --git a/apps/termtris/tests/input.sh b/apps/termtris/tests/input.sh index 6453f57..c4dd04d 100755 --- a/apps/termtris/tests/input.sh +++ b/apps/termtris/tests/input.sh @@ -8,7 +8,7 @@ M=${MAME:-/home/arti/code/k-space/mame0289/vt1200} LOG="$APP/build/input.log" mkdir -p "$APP/build" "$APP/build.sh" "$DIR/input.c" "$APP/src/vt1200/main.c" "$APP/src/vt1200/x11.c" "$APP/src/vt1200/xgfix.c" >"$APP/build/input-build.log" 2>&1 -MARK=$(awk '/_mark/ {print $1; exit}' "$APP/build/input.map") +MARK=$(awk '{for(i=2;i<=NF;i++) if($i=="_mark") print $(i-1)}' "$APP/build/input.map" | head -1) VT1200_SKIP_LEVEL1=1 INPUT_MARK="0x$MARK" \ LOADER_AT=2500 LOADER_END=3400 \ LOADER_BIN="$ROOT/dwt/loader/build/loader.bin" \ @@ -20,7 +20,7 @@ LOADER_OUT="$APP/build" \ -autoboot_script "$DIR/input.lua" -autoboot_delay 0 \ >"$LOG" 2>&1 || true grep 'INPUT:' "$LOG" | tail -3 -grep -q 'INPUT: .*bytes=.*61 9B 41 9B 42 9B 44 9B 43 30 0A 7F 71' "$LOG" || { +grep -q 'INPUT: .*bytes=.*61 9B 41 9B 42 9B 44 9B 43 30 0A 7F 71 70' "$LOG" || { echo "input.sh: mapped key sequence missing (see $LOG)" >&2 exit 1 } diff --git a/apps/termtris/tests/play.lua b/apps/termtris/tests/play.lua index 5f35daf..9e91d32 100644 --- a/apps/termtris/tests/play.lua +++ b/apps/termtris/tests/play.lua @@ -25,6 +25,8 @@ local function hex(v, w) return string.format("%0" .. (w or 8) .. "X", v) end local machine = manager.machine +local PTICK = tonumber(os.getenv("DIAG_TICK") or "0") +local PQUIT = tonumber(os.getenv("DIAG_QUIT") or "0") local ports = machine.ioport.ports local tabx = ports[":tablet:TABLET_X"].fields["Tablet X"] local taby = ports[":tablet:TABLET_Y"].fields["Tablet Y"] @@ -274,6 +276,9 @@ local function inspect() r32(0x01890140), r32(0x01890160), hex(r32(0x01890100)), hex(r32(0x01890110)), hex(r32(0x01890120)), hex(r32(0x01890130)))) end + if PTICK ~= 0 or PQUIT ~= 0 then + print(string.format("DIAG: tick=%d quit=%d", PTICK ~= 0 and r32(PTICK) or -1, PQUIT ~= 0 and r32(PQUIT) or -1)) + end print(string.format("LOADER: PC at inspection = %s", hex(cpu.state['PC'].value))) end diff --git a/apps/termtris/tests/play.sh b/apps/termtris/tests/play.sh index 56f88fb..7afc6d9 100755 --- a/apps/termtris/tests/play.sh +++ b/apps/termtris/tests/play.sh @@ -8,8 +8,13 @@ M=${MAME:-/home/arti/code/k-space/mame0289/vt1200} EV="$APP/evidence" LOG="$APP/build/play.log" mkdir -p "$EV" "$APP/build" +OUTNAME=termtris "$APP/build.sh" "$APP/src/vt1200/main.c" "$APP/src/game.c" "$APP/src/vt1200/scoredb.c" \ + "$APP/src/vt1200/x11.c" "$APP/src/vt1200/compat.c" "$APP/src/vt1200/xgfix.c" \ + >"$APP/build/play-build.log" 2>&1 rm -f "$EV/loader_frame3300.png" -VT1200_SKIP_LEVEL1=1 LOADER_SNAP=1 \ +TICK=$(awk '{for(i=2;i<=NF;i++) if($i=="_tick_interval") print $(i-1)}' "$APP/build/termtris.map" | head -1) +QUIT=$(awk '{for(i=2;i<=NF;i++) if($i=="_quit") print $(i-1)}' "$APP/build/termtris.map" | head -1) +VT1200_SKIP_LEVEL1=1 LOADER_SNAP=1 DIAG_TICK="0x$TICK" DIAG_QUIT="0x$QUIT" \ LOADER_AT=2500 LOADER_END=3300 \ LOADER_BIN="$ROOT/dwt/loader/build/loader.bin" \ LOADER_COFF="$APP/build/termtris.coff" \ @@ -19,7 +24,14 @@ LOADER_OUT="$EV" \ -debug -debugger none \ -autoboot_script "$DIR/play.lua" -autoboot_delay 0 \ >"$LOG" 2>&1 || true -grep -E 'PLAY:|LOADER: result|LOADER: snapshot' "$LOG" | tail -6 +grep -E 'PLAY:|DIAG:|LOADER: result|LOADER: snapshot' "$LOG" | tail -6 +grep -q 'LOADER: result status=0' "$LOG" || { echo "play.sh: the game did not start (see $LOG)" >&2; exit 1; } +DIAG=$(grep -a 'DIAG: tick=' "$LOG" | head -1) +[ -n "$DIAG" ] || { echo "play.sh: no DIAG line (see $LOG)" >&2; exit 1; } +TICKVAL=$(printf '%s' "$DIAG" | sed -n 's/.*tick=\([-0-9]*\).*/\1/p') +QUITVAL=$(printf '%s' "$DIAG" | sed -n 's/.*quit=\([-0-9]*\).*/\1/p') +[ "$TICKVAL" -gt 0 ] || { echo "play.sh: init_game never ran (tick=$TICKVAL)" >&2; exit 1; } +[ "$QUITVAL" = 0 ] || { echo "play.sh: game quit by itself" >&2; exit 1; } [ -s "$EV/loader_frame3300.png" ] || { echo "play.sh: no snapshot (see $LOG)" >&2; exit 1; } cp "$EV/loader_frame3300.png" "$EV/termtris_frame3300.png" echo "play: $EV/termtris_frame3300.png" diff --git a/apps/termtris/tests/play_keys.sh b/apps/termtris/tests/play_keys.sh index e39565e..a7a1fc0 100755 --- a/apps/termtris/tests/play_keys.sh +++ b/apps/termtris/tests/play_keys.sh @@ -7,6 +7,9 @@ ROOT=$(cd "$APP/../.." && pwd) M=${MAME:-/home/arti/code/k-space/mame0289/vt1200} EV="$APP/evidence" mkdir -p "$EV" "$APP/build" +OUTNAME=termtris "$APP/build.sh" "$APP/src/vt1200/main.c" "$APP/src/game.c" "$APP/src/vt1200/scoredb.c" \ + "$APP/src/vt1200/x11.c" "$APP/src/vt1200/compat.c" "$APP/src/vt1200/xgfix.c" \ + >"$APP/build/play_keys-build.log" 2>&1 for mode in ${MODES:-move panels quit}; do LOG="$APP/build/play_$mode.log" rm -f "$EV/loader_frame3200.png" diff --git a/apps/termtris/tests/render.sh b/apps/termtris/tests/render.sh index a088feb..74cb5c8 100755 --- a/apps/termtris/tests/render.sh +++ b/apps/termtris/tests/render.sh @@ -11,8 +11,8 @@ LOG="$APP/build/render.log" mkdir -p "$EV" "$APP/build" "$APP/build.sh" "$DIR/render.c" "$APP/src/vt1200/x11.c" "$APP/src/vt1200/xgfix.c" >"$APP/build/render-build.log" 2>&1 rm -f "$EV/loader_frame3400.png" -MARK=$(awk '/_mark/ {print $1; exit}' "$APP/build/render.map") -PROG=$(awk '/_vt_x11_progress/ {print $1; exit}' "$APP/build/render.map") +MARK=$(awk '{for(i=2;i<=NF;i++) if($i=="_mark") print $(i-1)}' "$APP/build/render.map" | head -1) +PROG=$(awk '{for(i=2;i<=NF;i++) if($i=="_vt_x11_progress") print $(i-1)}' "$APP/build/render.map" | head -1) VT1200_SKIP_LEVEL1=1 LOADER_SNAP=1 RENDER_MARK="0x$MARK" X11_PROGRESS="0x$PROG" \ LOADER_AT=2500 LOADER_END=3400 \ LOADER_BIN="$ROOT/dwt/loader/build/loader.bin" \ @@ -24,6 +24,14 @@ LOADER_OUT="$EV" \ -autoboot_script "$DIR/render.lua" -autoboot_delay 0 \ >"$LOG" 2>&1 || true grep -E 'LOADER: snapshot|LOADER: result' "$LOG" | tail -4 +grep -q 'RENDER: magic=524E4452 .*flus=464C5553' "$LOG" || { + echo "render.sh: the renderer did not finish (see $LOG)" >&2 + exit 1 +} +grep -q 'RENDER: .*progress=00FFFFFF' "$LOG" || { + echo "render.sh: flush did not complete (see $LOG)" >&2 + exit 1 +} [ -s "$EV/loader_frame3400.png" ] || { echo "render.sh: no snapshot (see $LOG)" >&2; exit 1; } cp "$EV/loader_frame3400.png" "$EV/render_frame3400.png" echo "render: $EV/render_frame3400.png" diff --git a/apps/termtris/tests/smoke.sh b/apps/termtris/tests/smoke.sh index a35d03d..af7044e 100755 --- a/apps/termtris/tests/smoke.sh +++ b/apps/termtris/tests/smoke.sh @@ -13,7 +13,7 @@ LOG="$APP/build/smoke.log" mkdir -p "$APP/build" "$APP/build.sh" "$DIR/smoke.c" "$APP/src/vt1200/xgfix.c" >"$APP/build/smoke-build.log" 2>&1 -MARK=$(awk '/_mark/ {print $1; exit}' "$APP/build/smoke.map") +MARK=$(awk '{for(i=2;i<=NF;i++) if($i=="_mark") print $(i-1)}' "$APP/build/smoke.map" | head -1) VT1200_SKIP_LEVEL1=1 SMOKE_MARK="0x$MARK" \ LOADER_AT=2500 LOADER_END=3400 \ LOADER_BIN="$ROOT/dwt/loader/build/loader.bin" \ diff --git a/harness/mame/TERMTRIS_REPORT.md b/harness/mame/TERMTRIS_REPORT.md index 5d3f80a..aaa78d2 100644 --- a/harness/mame/TERMTRIS_REPORT.md +++ b/harness/mame/TERMTRIS_REPORT.md @@ -30,7 +30,7 @@ file as success and retries a missing one. Two quirks are handled there: Result (map): ``` -.text 018A0000 .cinit 018B4730 .bss 01A00000 +.text 018A0000 .cinit 018B4B10 .bss 01A00000 ENTRY POINT SYMBOL: "_start" address: 018a0000 ``` @@ -51,8 +51,9 @@ Smoke test evidence (`apps/termtris/tests/smoke.sh`): ## Rendering and the flush deadlock 80×24 cells of 6×13 px (the default GC font, baseline +10) → a 480×312 window. -The raster is 1 bit deep, so the backend follows the game's own monochrome -convention: colour is dropped and bold (`0x80`) reverses a cell. The playfield +The raster is 1 bit deep, so the backend drops colour (like the game's `-m` +monochrome mode) and treats the bold bit (`0x80`) as reverse video. That +reversal is this backend's choice; upstream `ansi.c -m` only emits SGR bold. The playfield is black spaces; tetrominoes are the `[`/`]` tiles. `vt_x11_flush()` repaints **whole rows** — one fill for the row background, one