-- xie_resource.lua -- trace XIE requests and dump the created resource. -- -- Breakpoint 1: inside XieProc after A9 = client->requestBuffer. -- Breakpoint 2: 0x6CAC8, just after the create helper has A9 = new resource. -- -- Run with -debuglog (printf output is discarded otherwise): -- VT1200_SKIP_LEVEL1=1 XIE_FRAMES=2000000 \ -- /home/arti/code/k-space/mame0289/vt1200 vt1200 ... -debug -debugger none \ -- -debuglog -autoboot_script harness/mame/xie_resource.lua 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: no debugger"); machine:exit(); return end local FRAMES = tonumber(os.getenv("XIE_FRAMES") or "2000000") local WPFILE = "/tmp/opencode/xie_wp.txt" local lastwp = "" local last_elem = 0 local WORDS = tonumber(os.getenv("XIE_WORDS") or "16") local TRACE = 0x3F525D40 -- XieProc interior, a9 = request buffer local CREATE = 0x3F565640 -- 0x6CAC8: a9 = new resource pointer 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" dbg:command("bpset " .. hex(TRACE) .. ",,{ printf \"" .. fmt .. "\", a9, " .. table.concat(args, ", ") .. " ; g }") dbg:command("bpset " .. hex(CREATE) .. ",,{ printf \"RES a9=%08X id=%08X class=%02X b8=%02X b36=%02X b40=%08X b44=%08X\\n\", " .. "a9, d@(a9), b@(a9+32), b@(a9+64), b@(a9+288), d@(a9+320), d@(a9+352) ; g }") local LOOK = 0x3F55D1C0 -- 0x6BA38: a7 = resource local bytes = {} for k = 0, 15 do bytes[#bytes+1] = string.format("b@(a7+%d)", k*32) end local bfmt = string.rep(" %02X", 16) dbg:command("bpset " .. hex(LOOK) .. ",,{ printf \"LOOK a7=%08X id=%08X cls=%02X b36=%02X b40=%08X" .. bfmt .. "\\n\", " .. "a7, d@(a7), b@(a7+32), b@(a7+288), d@(a7+320), " .. table.concat(bytes, ", ") .. " ; g }") -- Debug-only nudge: when a class-2 resource reaches the lookup, make it class 3 -- so PUT_TILE's hard-coded class check passes. Proves the rest of the pixel path. -- Debug-only: skip the class-compare failure branch (0x6BAF6 -> 0x6BBCE). local BAND = 0x3F555C40 -- 0x6AB88: a11 = band record, a9 = slot20 request dbg:command("bpset " .. hex(BAND) .. ",,{ printf \"BAND a11=%08X f1=%02X f2=%02X f4=%08X f8=%08X f12=%08X f16=%08X\\n\", " .. "a11, b@(a11+8), b@(a11+16), d@(a11+32), d@(a11+64), d@(a11+96), d@(a11+128) ; g }") dbg:command("bpset 0x3F400430,,{ printf \"DDCALL a11=%08X type=%02X idx=%08X\\n\", a11, b@(a13+0xffa0), d@(a13+0x20) ; g }") dbg:command("bpset 0x3F400040,,{ printf \"DE entry a0=%08X a1=%08X type=%02X idx=%08X\\n\", d@(a13+0xffe0), d@(a13+0xffc0), b@(a13+0xffa0), d@(a13+0x20) ; g }") dbg:command("bpset 0x3F4000F0,,{ printf \"DE chk1 ret=%08X\\n\", a8 ; g }") dbg:command("bpset 0x3F400210,,{ printf \"DE chk2 ret=%08X\\n\", a8 ; g }") dbg:command("bpset 0x3F55B440,,{ printf \"HANDOFF a9=%08X\\n\", a9 ; g }") dbg:command("bpset 0x3F55B750,,{ printf \"DEARG a9=%08X a11=%08X\\n\", a9, a11 ; g }") dbg:command("bpset 0x3F553B70,,{ printf \"S19ENTRY\\n\" ; g }") dbg:command("bpset 0x3F55B440,,{ printf \"H688 a9=%08X\\n\", a9 ; g }") dbg:command("bpset 0x3F400040,,{ printf \"DEENTRY\\n\" ; g }") dbg:command("bpset 0x3F553DA0,,{ printf \"S19LOOK a8=%08X\\n\", a8 ; g }") dbg:command("bpset 0x3F554D10,,{ printf \"S19HANDOFF\\n\" ; g }") dbg:command("bpset 0x3F52DE80,,{ printf \"S43OBJ a8=%08X\\n\", a8 ; g }") dbg:command("bpset 0x3F52E230,,{ printf \"S43ID a5=%08X req8=%08X\\n\", a5, d@(a9+0x40) ; g }") dbg:command("bpset 0x3F566070,,{ printf \"RESPTR a7=%08X a9=%08X\\n\", a7, a9 ; g }") dbg:command("bpset 0x3F2D8A90,,{ printf \"EXPORTENTRY\\n\" ; g }") dbg:command("bpset 0x3F2D8BC0,,{ printf \"EXPORTFLAG f=%02X\\n\", b@(0xA6220) ; g }") dbg:command("bpset 0x3F2DC0D0,,{ printf \"EXPORTSKIPPED\\n\" ; g }") dbg:command("bpset 0x3F2DF610,,{ printf \"ELTYPE i=%d t=%02X\n\", d@(a13+0x180), b@(a9+0x58) ; g }") dbg:command("bpset 0x3F2DF530,,{ printf \"BADFUNC i=%d\n\", d@(a13+0x180) ; g }") dbg:command("bpset 0x3F2DF400,,{ printf \"PIPE_T1\n\" ; g }") dbg:command("bpset 0x3F2DEA80,,{ printf \"PIPE_T2\n\" ; g }") dbg:command("bpset 0x3F2DE990,,{ printf \"PIPE_T3\n\" ; g }") dbg:command("bpset 0x3F2DE3A0,,{ printf \"PIPE_T4\n\" ; g }") dbg:command("bpset 0x3F2DF850,,{ printf \"PIPE_LOOPEND i=%d\n\", d@(a13+0x180) ; g }") dbg:command("bpset 0x3F2D91A0,,{ printf \"EX_BAND a5=%08X elem@d8=%08X\n\", a5, d@(a5+0xd8) ; g }") dbg:command("bpset 0x3F2D91C0,,{ printf \"EX_ELEM a5=%08X f28=%08X\n\", a5, d@(a5+0x28) ; g }") dbg:command("bpset 0x3F2DD410,,{ printf \"EX_TIMING\n\" ; g }") dbg:command("bpset 0x3F55D950,,{ printf \"PUTCHK n=%d obj=%08X b8=%02X b12=%02X\n\", d@(a13+0xff20), a11, b@(a11+0x40), b@(a11+0x60) ; g }") dbg:command("bpset 0x3F55DA50,,{ printf \"PUT_BADMATCH_byte12 n=%d\n\", d@(a13+0xff20) ; g }") dbg:command("bpset 0x3F55DF10,,{ printf \"PUT_OK_byte8 n=%d\n\", d@(a13+0xff20) ; g }") dbg:command("bpset 0x3F2D91A0,,{ printf \"BANDFIELDS 48=%08X 80=%08X a0=%08X 160=%08X d8=%08X\n\", d@(a5+0x48), d@(a5+0x80), d@(a5+0xa0), d@(a5+0x160), d@(a5+0xd8) ; g }") dbg:command("bpset 0x3F2D94B0,,{ printf \"RP 5a8=%08X 5d0=%08X 5f0=%08X 610=%08X 6f8=%08X 718=%08X 738=%08X 758=%08X\n\", d@(a11+0x5a8), d@(a11+0x5d0), d@(a11+0x5f0), d@(a11+0x610), d@(a11+0x6f8), d@(a11+0x718), d@(a11+0x738), d@(a11+0x758) ; g }") dbg:command("bpset 0x3F54BFF0,,{ printf \"TRAMP minor=%02X target=%08X req=%08X\n\", b@(a10+0x8), d@(a11), a10 ; g }") dbg:command("bpset 0x3F54C000,,{ printf \"TRAMPCALL target=%08X\n\", a11 ; g }") dbg:command("bpset 0x3F53D820,,{ printf \"REGIDSTORE id=%08X obj=%08X\n\", d@(a9+0x40), a11 ; g }") dbg:command("bpset 0x3F53D9A0,,{ printf \"REGISTER id=%08X\n\", d@(a9+0x40) ; g }") -- empirical argument/return map of the slot-19 lookup helper (file 0x66FA0) dbg:command("bpset 0x3F537DA0,,{ printf \"LKARGS a0=%08X a1=%08X a2=%08X a3=%08X a4=%08X\n\", d@(a13+0xffe0), d@(a13+0xffc0), d@(a13+0xffa0), d@(a13+0xff80), d@(a13+0xff60) ; g }") dbg:command("bpset 0x3F537E70,,{ printf \"LKCALLED a8=%08X\n\", a8 ; g }") dbg:command("bpset 0x3F537E90,,{ printf \"LKDISPATCH a8=%08X\n\", a8 ; g }") dbg:command("bpset 0x3F55D630,,{ printf \"ERR_0A_badaccess\n\" ; g }") dbg:command("bpset 0x3F55DA60,,{ printf \"ERR_08_badmatch\n\" ; g }") dbg:command("bpset 0x3F55CD70,,{ printf \"ERR_0E_lookup0\n\" ; g }") dbg:command("bpset 0x3F55D2C0,,{ printf \"ERR_0E_byte40_nonzero\n\" ; g }") dbg:command("bpset 0x3F55D400,,{ printf \"ERR_0E_other\n\" ; g }") dbg:command("bpset 0x3F55D530,,{ printf \"ERR_0E_other2\n\" ; g }") dbg:command("bpset 0x3F2FD2F0,,{ printf \"EB -10=%08X -0c=%08X -8=%08X -4=%08X sp=%08X +4=%08X +8=%08X +c=%08X\n\", d@(sp-0x10), d@(sp-0xc), d@(sp-8), d@(sp-4), d@(sp), d@(sp+4), d@(sp+8), d@(sp+0xc) ; g }") dbg:command("bpset 0x3F55D7A0,,{ printf \"GATE a7=%08X a11=%08X obj=%08X objb0=%02X\n\", a7, a11, d@(a13+0xffa0), b@(d@(a13+0xffa0)) ; g }") dbg:command("bpset 0x3F55D460,,{ printf \"OBJDISP a11=%08X b0=%02X b4=%02X b8=%02X b12=%02X b16=%02X\n\", a11, b@(a11), b@(a11+0x20), b@(a11+0x40), b@(a11+0x60), b@(a11+0x80) ; g }") dbg:command("bpset 0x3F55D7B0,,{ printf \"GATEPASS\n\" ; g }") dbg:command("bpset 0x3F55DA50,,{ printf \"E8_select12\n\" ; g }") dbg:command("bpset 0x3F55DC30,,{ printf \"E8_maskcheck\n\" ; g }") dbg:command("bpset 0x3F55D7A0,,{ printf \"GATE2 a7=%08X a11=%08X\n\", a7, a11 ; g }") dbg:command("bpset 0x3F55D7C0,,{ printf \"E8_MAIN_0BAF8\n\" ; g }") dbg:command("bpset 0x3F55CE20,,{ printf \"CLASS1_PATH\n\" ; g }") dbg:command("bpset 0x3F55D440,,{ printf \"SELECTOR_DISPATCH\n\" ; g }") local frames = 0 emu.register_frame_done(function() frames = frames + 1 if frames % 1000 == 0 then print(string.format("XIE: frame %d pc=%s", frames, hex(cpu.state['PC'].value))) end local f = io.open(WPFILE, "r") if f then local txt = f:read("*l"); f:close() if txt and txt ~= lastwp then lastwp = txt local r = tonumber(txt) if r then local sp = cpu.spaces['program'] local band = sp:read_u32(r + 36*8) local p44 = sp:read_u32(r + 44*8) local b30 = sp:read_u32(band + 48*8) local elem = 0 if p44 ~= 0 then elem = sp:read_u32(p44 + 0xd8) end if elem ~= 0 and elem ~= last_elem then last_elem = elem dbg:command(string.format("wpset %08X,32,w,1,{ printf \"WPELEM addr=%08X data=%08X\\n\", wpaddr, wpdata ; g }", elem + 0x28)) print(string.format("XIE: elem=%08X wpset elem+0x28", elem)) end print(string.format("XIE: watch res=%08X band=%08X p44=%08X b30=%08X", r, band, p44, b30)) local function wp(a, label) if a and a ~= 0 then dbg:command(string.format("wpset %08X,64,w,1,{ printf \"WPHIT %s addr=%%08X data=%%08X\\n\", wpaddr, wpdata ; g }", a, label)) end end wp(r, "res"); wp(band, "band"); wp(p44, "p44"); wp(b30, "b30") end end end if frames >= FRAMES then machine:exit() end end, "vt1200-xie-resource") dbg.visible_cpu = cpu dbg.execution_state = 'run'