-- 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 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'