mirror of
https://git.k-space.ee/arti/vt1200.git
synced 2026-10-30 12:03:54 +02:00
harness: capture the firmware console; it reports LEVEL1/2 VIDEO MEMORY error 22 and restarts
This commit is contained in:
1 parent
fe978dee18
commit
ccd03b8879
3 files changed
+120
-1
No files matched your search
@@ -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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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'
|
||||
Reference in new issue
Block a user