Files
vt1200/harness/mame/dispatch_walk.lua
T

41 lines
1.5 KiB
Lua

-- Dump the call chain when the level-1 error dispatcher runs.
--
-- The dispatcher reads the failing status code from its ARGUMENT (*A13(0xffe0)),
-- so the routine is a function and its caller is the failing test. Breaking at
-- the dispatcher and walking the stack gives us that caller's return address --
-- a ROM bit address we can convert to a file offset and disassemble.
--
-- Dispatcher: Ghidra 0x07FBE0C6 -> file 0x17E0C6 -> bit 0x3F200000 + 0x17E0C6*8
--
-- DW_FRAMES=600 <mame> vt1200 ... -autoboot_script harness/mame/dispatch_walk.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 DSP = os.getenv("DW_PC") or "3fdf0630"
-- Print SP and a window of stack words once, then keep going. ROM bit
-- addresses (0x3F2xxxxx-0x3FFFFFFF) among them are return addresses.
dbg:command(string.format(
'bpset %s,,{ printf "DISPATCH sp=%%08X w0=%%08X w1=%%08X w2=%%08X w3=%%08X w4=%%08X w5=%%08X w6=%%08X w7=%%08X\\n", sp, d@sp, d@(sp+20h), d@(sp+40h), d@(sp+60h), d@(sp+80h), d@(sp+0a0h), d@(sp+0c0h), d@(sp+0e0h) ; g }', DSP))
print("breakpoint armed at dispatcher " .. DSP)
local maxframes = tonumber(os.getenv("DW_FRAMES") or "600")
local n = 0
emu.register_frame_done(function()
n = n + 1
if n >= maxframes then
print("done (" .. n .. " frames)")
machine:exit()
end
end, "vt1200-dispatch")
dbg.visible_cpu = cpu
dbg.execution_state = 'run'