-- xie_trace.lua -- capture XIE 2.3 request buffers as they reach the server. -- -- The breakpoint sits INSIDE XieProc, immediately after it loads -- A9 = client->requestBuffer (0x64BA2) and before it reads stuff->opcode, -- i.e. at Ghidra 0x64BA8 = bit 0x3F525D40. At that point A9 is the request -- buffer pointer, so the whole request can be read with w@ (16-bit words, which -- is the CPU's native access width on this bit-addressed space). -- -- M=/home/arti/code/k-space/mame0289/vt1200 -- XIE_FRAMES=1500 $M vt1200 -rompath harness/mame/roms -video none -sound none \ -- -nothrottle -debug -debugger none \ -- -autoboot_script harness/mame/xie_trace.lua -autoboot_delay 0 -- -- Env: -- XIE_FRAMES frame budget (default 1500) -- XIE_WORDS request words dumped per hit (default 8 = 16 bytes) -- XIE_JIT if set, jump to this bit address at XIE_AT (debugger entry) -- XIE_AT frame at which XIE_JIT is taken (default 400) local function hex(v, w) return string.format("%0" .. (w or 8) .. "X", v) end local machine = manager.machine local cpu = machine.devices[':maincpu'] local dbg = machine.debugger if not dbg then print("XIE ERROR: debugger not enabled; pass -debug") machine:exit() return end local FRAMES = tonumber(os.getenv("XIE_FRAMES") or "1500") local WORDS = tonumber(os.getenv("XIE_WORDS") or "8") local JIT = os.getenv("XIE_JIT") local AT = tonumber(os.getenv("XIE_AT") or "400") local IDLE = 0x3FDCE400 -- level-0 diagnostics menu idle loop -- XieProc interior: A9 = request buffer. XIE_TRACE overrides it, which is only -- useful as a control: point it at a hot PC (e.g. the menu idle 3FDCE400) and -- confirm the breakpoint+printf machinery actually fires. local TRACE = tonumber(os.getenv("XIE_TRACE") or "0x3F525D40") -- XieProc entry (count only) local ENTRY = 0x3F525CC0 local action if WORDS == 0 then -- control mode: prove the breakpoint fires at all action = '{ printf "XIEHIT pc=%08X\\n", pc ; g }' else local args = {} for i = 0, WORDS - 1 do args[#args + 1] = string.format("w@(a9+%d)", i * 16) end local fmt = "XIEHIT buf=%08X" for i = 0, WORDS - 1 do fmt = fmt .. " %04X" end fmt = fmt .. "\\n" action = string.format('{ printf "%s", a9, %s ; g }', fmt, table.concat(args, ", ")) end dbg:command("bpset " .. hex(TRACE) .. ",," .. action) print("XIE: breakpoint at " .. hex(TRACE) .. " -> " .. action) if JIT then dbg:command("bpset " .. hex(IDLE) .. ",,{ pc = " .. JIT .. " ; g }") print("XIE: entry jump armed at " .. hex(IDLE) .. " -> " .. JIT) end local frames = 0 emu.register_frame_done(function() frames = frames + 1 if frames % 100 == 0 then print(string.format("XIE: frame %d pc=%s", frames, hex(cpu.state['PC'].value))) end if frames >= FRAMES then print("XIE: done at frame " .. frames) machine:exit() end end, "vt1200-xie-trace") dbg.visible_cpu = cpu dbg.execution_state = 'run'