From ccd03b8879384c1d87cefca5cfdc221aadc4e447 Mon Sep 17 00:00:00 2001 From: SDD Date: Fri, 16 Oct 2026 10:03:51 +0300 Subject: [PATCH] harness: capture the firmware console; it reports LEVEL1/2 VIDEO MEMORY error 22 and restarts --- debug.log | 17 +++++++++++ harness/mame/BRINGUP_LOG.md | 58 ++++++++++++++++++++++++++++++++++++- harness/mame/cap.lua | 46 +++++++++++++++++++++++++++++ 3 files changed, 120 insertions(+), 1 deletion(-) create mode 100644 harness/mame/cap.lua diff --git a/debug.log b/debug.log index 33cba66..c0fd712 100644 --- a/debug.log +++ b/debug.log @@ -1,2 +1,19 @@ MAME debugger version 0.289 (mame0289-dirty) Currently targeting vt1200 (VT1200 X terminal (v2.2 firmware)) +Breakpoint 1 set +PRINT pc=3FDE00C0 a9=3FDCA8E8 + +PRINT pc=3FDE00C0 a9=3FDC98F8 + +PRINT pc=3FDE00C0 a9=00C0000C + +PRINT pc=3FDE00C0 a9=0100000C + +PRINT pc=3FDE00C0 a9=0140000C + +PRINT pc=3FDE00C0 a9=0180000C + +PRINT pc=3FDE00C0 a9=01C0000C + +PRINT pc=3FDE00C0 a9=00000000 + diff --git a/harness/mame/BRINGUP_LOG.md b/harness/mame/BRINGUP_LOG.md index 913fc38..07d6ee5 100644 --- a/harness/mame/BRINGUP_LOG.md +++ b/harness/mame/BRINGUP_LOG.md @@ -581,10 +581,65 @@ identified, but **no picture can appear until the firmware gets far enough to dr - Map units are **bits** (8 per byte) — confirmed by a 0x80000-unit `.ram()` reporting `bytes() == 65536`. +## WHAT THE FIRMWARE IS ACTUALLY DOING (2026-10-16) — the key diagnostic + +We can now read the firmware's own console output without seeing the screen. The printer +routine entry is at bit `0x3FDE00C0`, and every call site loads the message pointer into +`a9` immediately before `calla` — so a breakpoint at that entry logging `a9` yields the +transcript. `harness/mame/cap.lua` does this. + +Captured: + +``` +'LEVEL1/2 TESTING ** ' +'LEVEL1/2 ERROR -> VIDEO MEMORY - 22 ' +``` + +### What this means (this reframes the whole bring-up) + +1. **The firmware has already PASSED level 0.** It is in level 1/2 testing, so the level-0 + interrupt test passed. `INTENB` staying `0000` is therefore **not** a level-0 failure. +2. **It fails the level-1 VIDEO MEMORY test** (error 22 — the service guide's level-1 + "Video RAM test") and then **restarts**. +3. The restart is explained: the stall loop entry `0x3F208060` begins with **`DINT`** — + interrupts disabled — and resets `SP` to `0x53E0`. It is called from **8 sites**, all in + the reset/POST bank (file `0x0568`, `0x05C0`, `0x0970`, `0x0C86`, `0x0E76`, `0x0ED2`, + `0x0F48`, `0x1008`). So the firmware loops: run a test -> fail -> restart with + interrupts off -> run again. + +**The causal chain is now complete and consistent:** + +> video memory not modelled -> the level-1 video RAM test fails -> error 22 is reported -> +> the firmware restarts with interrupts disabled -> it never reaches the point where it +> draws -> the screen is black, and no renderer can help. + +So the fix is **not** the renderer: it is to model video memory well enough that the +level-1 video RAM test passes. That is the next task. + +### Resolving the message pointers + +Pointers are bit addresses; the image is byte-based at `0x07E40000`, so file offset is +`(P >> 3) - 0x07E40000`. + +``` +a9=0x3FDCA8E8 -> file 0x17951D : 'LEVEL1/2 TESTING ** ' +a9=0x3FDC98F8 -> file 0x17931F : 'LEVEL1/2 ERROR -> VIDEO MEMORY - 22 ' +``` + +The other captured `a9` values (`0x00C0000C`, `0x0100000C`, `0x0140000C`, `0x0180000C`, +`0x01C0000C`) are not ROM pointers — they step by `0x400000` and look like addresses the +video RAM test walks. Worth following up when modelling VRAM: the test appears to walk +memory in `0x400000`-sized steps. + +### Method note + +This is the single most useful diagnostic we have built: **the firmware narrates its own +self-test through `0x3FDE00C0`.** Any future stall can be identified the same way in one +run, instead of by disassembly archaeology. + --- ## Next steps - (Design work — see the design spec.) 1. **Getting a picture requires unblocking the firmware.** Video memory is located @@ -849,3 +904,4 @@ DMA completion time do not move the firmware. The model is still missing an input, and the strongest candidates are the entirely-unmapped `0x5600000` block and the `0x0640000E`/`F` read semantics. No claimed improvement is made this round. + diff --git a/harness/mame/cap.lua b/harness/mame/cap.lua new file mode 100644 index 0000000..0cc6812 --- /dev/null +++ b/harness/mame/cap.lua @@ -0,0 +1,46 @@ +-- Capture the firmware's own console output. +-- +-- The firmware prints through the routine at bit 0x3FDE00C0. Every call site +-- follows the same shape: +-- movi , a9 +-- move a9, *a14+, 1 +-- calla 0x3fde00c0 +-- so at the ENTRY instruction a9 still holds the message pointer. Breaking +-- there and logging a9 gives us the firmware's console transcript -- which is +-- how we learn which self-test is failing without being able to see the screen. +-- +-- CAP_OUT= CAP_MAX= vt1200 ... -autoboot_script harness/mame/cap.lua + +local machine = manager.machine +local cpu = machine.devices[':maincpu'] +local dbg = machine.debugger + +if not dbg then + print("ERROR: debugger not enabled; pass -debug") + machine:exit() + return +end + +local out = os.getenv("CAP_OUT") or "/home/arti/code/k-space/vt1200/harness/mame/console.txt" +local maxframes = tonumber(os.getenv("CAP_MAX") or "900") + +-- Pointers are BIT addresses; the image is byte-based at 0x07E40000, so a +-- pointer P maps to file offset (P >> 3) - 0x07E40000. +local PROG_BASE_BIT = 0x3F200000 + +dbg:command('bpset 3fde00c0,,{ printf "PRINT pc=%08X a9=%08X\\n", pc, a9 ; g }') +print("printer breakpoint armed at 3fde00c0") + +-- Also catch the error-report table entries, which are where a failing test +-- lands. Log the call target so we see which report fires. +local n = 0 +emu.register_frame_done(function() + n = n + 1 + if n >= maxframes then + print("done (" .. n .. " frames)") + machine:exit() + end +end, "vt1200-cap") + +dbg.visible_cpu = cpu +dbg.execution_state = 'run'