mirror of
https://git.k-space.ee/arti/vt1200.git
synced 2026-10-31 12:05:05 +02:00
86 lines
2.8 KiB
Lua
86 lines
2.8 KiB
Lua
-- probe_os.lua -- private probe for the COFF loader work.
|
|
--
|
|
-- Prints the OS-phase heap free list (global list only, as HEAP.md advises),
|
|
-- and tests whether the CPU registers can be written from a frame hook while
|
|
-- the machine is running (the debugger is attached with -debug -debugger none).
|
|
--
|
|
-- VT1200_SKIP_LEVEL1=1 <mame> vt1200 ... -autoboot_script dwt/loader/probe_os.lua
|
|
--
|
|
-- Env: PROBE_AT (frame to sample, default 2500), PROBE_END (exit frame, 2520)
|
|
|
|
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
|
|
local prog = cpu.spaces['program']
|
|
|
|
if not dbg then
|
|
print("PROBE: no debugger")
|
|
machine:exit()
|
|
return
|
|
end
|
|
|
|
local AT = tonumber(os.getenv("PROBE_AT") or "2500")
|
|
local ENDF = tonumber(os.getenv("PROBE_END") or "2520")
|
|
local frames = 0
|
|
local tested = false
|
|
|
|
local function u32(a)
|
|
local ok, v = pcall(function() return prog:read_u32(a) end)
|
|
if ok then return v end
|
|
return 0xdeadbeef
|
|
end
|
|
|
|
local function heap()
|
|
print(string.format("PROBE: free counter @1E8BA0 = %d bits (%d bytes)",
|
|
u32(0x1E8BA0), math.floor(u32(0x1E8BA0) / 8)))
|
|
local head = u32(0x1E8AC0)
|
|
print(string.format("PROBE: global free-list head @1E8AC0 = %s", hex(head)))
|
|
local b = head
|
|
for i = 0, 15 do
|
|
if b == 0 then break end
|
|
local size = u32(b)
|
|
local nextp = u32(b + 0x20)
|
|
print(string.format("PROBE: block[%d] hdr=%s size=%d bits (%d B) user=%s..%s next=%s",
|
|
i, hex(b), size, math.floor(size / 8), hex(b + 0x40),
|
|
hex(b + size), hex(nextp)))
|
|
if nextp == head then break end
|
|
b = nextp
|
|
end
|
|
end
|
|
|
|
emu.register_frame_done(function()
|
|
frames = frames + 1
|
|
if frames == AT then
|
|
print(string.format("PROBE: frame %d PC=%s SP=%s A8=%s A14=%s",
|
|
frames, hex(cpu.state['PC'].value), hex(cpu.state['SP'].value),
|
|
hex(cpu.state['A8'].value), hex(cpu.state['A14'].value)))
|
|
heap()
|
|
-- Scratch return stub test: write jruc self at 01880F00, return address
|
|
-- at 01880F10, then set SP/PC from the frame hook.
|
|
prog:write_u16(0x01880F00, 0xC0FF) -- jruc 01880F00 (short, -1 word)
|
|
prog:write_u32(0x01880F10, 0x01880F00)
|
|
prog:write_u32(0x01880F20, 0xDEADBEEF)
|
|
print(string.format("PROBE: spin word readback=%04X ret=%s",
|
|
prog:read_u16(0x01880F00), hex(prog:read_u32(0x01880F10))))
|
|
cpu.state['SP'].value = 0x01880F10
|
|
cpu.state['A8'].value = 0x01880E00
|
|
cpu.state['PC'].value = 0x01880F00
|
|
tested = true
|
|
end
|
|
if tested and frames == AT + 2 then
|
|
print(string.format("PROBE: after 2 frames PC=%s SP=%s A8=%s",
|
|
hex(cpu.state['PC'].value), hex(cpu.state['SP'].value),
|
|
hex(cpu.state['A8'].value)))
|
|
end
|
|
if frames >= ENDF then
|
|
print(string.format("PROBE: marker 01880F20=%s (should be DEADBEEF, untouched)",
|
|
hex(u32(0x01880F20))))
|
|
machine:exit()
|
|
end
|
|
end, "vt1200-loader-probe")
|
|
|
|
dbg.visible_cpu = cpu
|
|
dbg.execution_state = 'run'
|