Files
vt1200/harness/mame/resolve_console.py
T
SDD c06cf7096b harness: skip run is STUCK at the X11 weave -- wall is unmodelled DUART2 (phantom ISR read at 0x06200005); add multi-timestamp dumps + console string resolver
The skip gate reaches the root weave and stops: video RAM and the rendered
frame are byte-identical at frames 3000/10000/30000/45000/60000 (42 s -> 14
min), and all 4 MiB of main RAM is identical at every sample except one byte
that oscillates.  The PC histogram is tight: entered at frame ~611, dominated
by 0x3FB30390/0x3FB30110.

Wall: DUART2 (0x0620000, keyboard/mouse) is unmodelled, so the read-only ISR
at 0x06200005 is served by the board write-back latch and returns the value
the OS wrote to the write-only IMR (0x0033).  The OS's DUART dispatcher
(0x3FB43800) masks 0x66 -> 0x22, so it services a phantom interrupt that can
never clear, spinning in the channel handler 0x3FB42410 and queue routine
0x3FB300F0.  Forcing only 0x06200005 to 0 reproduces the full DUART2-mapped
run byte-for-byte; with VT1200_DUART2=1 the Terminal Manager dialog box from
the reference video appears at frame 3000 and the machine runs on.

Defaults unchanged: no-env still reaches HOST PORT - 15, skip still reaches
the weave.  New opt-in knobs VT1200_DUMP_{FRAME,RAM_FRAMES,VRAM_FRAMES} and
resolve_console.py; progress.lua untouched.
2026-10-16 13:39:37 +03:00

52 lines
1.6 KiB
Python

#!/usr/bin/env python3
"""Resolve the a9 message pointers from a cap.lua debug.log capture.
cap.lua breaks at the firmware's console-print entry (bit 0x3FDE00C0) and logs
`PRINT pc=.. a9=.. a11=.. a5=..` lines (they land in MAME's -debuglog file,
i.e. `debug.log` in the CWD). a9 is a BIT address; the ROM image is byte-based
at 0x07E40000, so the string bytes are at file offset (a9 >> 3) - 0x07E40000.
Usage: resolve_console.py <debug.log> [rom.bin]
"""
import sys
ROM_BASE_BYTE = 0x07E40000
def main() -> int:
log = sys.argv[1]
rompath = sys.argv[2] if len(sys.argv) > 2 else "vt1200_v22.bin"
with open(rompath, "rb") as f:
rom = f.read()
seen = set()
with open(log, "r", errors="replace") as f:
for line in f:
if "PRINT pc=" not in line:
continue
fields = dict(
kv.split("=", 1) for kv in line.split() if "=" in kv
)
a9 = fields.get("a9")
a11 = fields.get("a11")
if a9 is None:
continue
bit = int(a9, 16)
off = (bit >> 3) - ROM_BASE_BYTE
key = (a9, a11)
if key in seen:
continue
seen.add(key)
if 0 <= off < len(rom):
end = rom.find(b"\x00", off)
raw = rom[off:end if end != -1 else off + 80]
txt = raw.decode("latin-1").replace("\n", "\\n")
print(f"a9={a9} a11={a11} {txt!r}")
else:
print(f"a9={a9} a11={a11} <not a ROM pointer: off={off:#x}>")
return 0
if __name__ == "__main__":
sys.exit(main())