harness: capture the firmware console; it reports LEVEL1/2 VIDEO MEMORY error 22 and restarts

This commit is contained in:
SDD committed 2026-10-16 10:03:51 +03:00
1 parent fe978dee18
commit ccd03b8879
3 files changed
+120 -1

No files matched your search

+17
View File
@@ -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
+57 -1
View File
@@ -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.
+46
View File
@@ -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 <message pointer>, 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=<file> CAP_MAX=<n> <mame> 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'