-- probe.lua -- frame snapshots + marker/PC telemetry for the GUI experiments. -- -- MSG_TRIGGER= " " -> PNG snapshots -- MSG_DIR= where PNGs go -- -- Also prints a marker line every 250 frames, so a wedged machine still leaves -- evidence of how far the injected payload got: -- 01850100 display 01850110 root 01850120 window -- 01850130 sync 01850140 stage 01850150 strlen local machine = manager.machine local dir = os.getenv("MSG_DIR") or "." local trigger = os.getenv("MSG_TRIGGER") or (dir .. "/trigger") local screen = nil for _, s in pairs(machine.screens) do screen = s; break end local cpu = machine.devices[':maincpu'] local space = cpu.spaces['program'] local frame = 0 local job = nil local function consume_trigger() local fh = io.open(trigger, "r") if not fh then return end local text = fh:read("*a") or "" fh:close() os.remove(trigger) local prefix, count, stride = text:match("(%S+)%s+(%d+)%s+(%d+)") if not prefix then print("probe: bad trigger " .. text) return end job = { prefix = prefix, left = tonumber(count), stride = tonumber(stride), next = frame } print(string.format("probe: frame %d job %s x%d every %d", frame, prefix, job.left, job.stride)) end local function u32(addr) local ok, v = pcall(function() return space:read_u32(addr) end) if ok then return v end return 0xdeadbeef end emu.register_frame_done(function() frame = frame + 1 consume_trigger() if job and frame >= job.next and screen then local out = string.format("%s/%s_frame%05d.png", dir, job.prefix, frame) local ok, err = pcall(function() return screen:snapshot(out) end) print(string.format("probe: frame %d %s ok=%s err=%s", frame, out, tostring(ok), tostring(err))) job.left = job.left - 1 job.next = frame + job.stride if job.left <= 0 then job = nil end end if frame % 250 == 0 then print(string.format("probe: frame %d PC=%08X disp=%08X root=%08X win=%08X sync=%08X stage=%d strlen=%d", frame, cpu.state['PC'].value, u32(0x01850100), u32(0x01850110), u32(0x01850120), u32(0x01850130), u32(0x01850140), u32(0x01850150))) end end, "vt1200-gui-probe") if machine.debugger then machine.debugger.execution_state = 'run' end