mirror of
https://git.k-space.ee/arti/vt1200.git
synced 2026-10-30 12:03:54 +02:00
Add an opt-in knob (VT1200_DUART_IP3=1) that asserts DUART1 input-port bit 3. The POST gate at bit 0x3F2042D0 tests IP3 (@0x64000D0 bit 3) and, when it is high and the 0x6200000 status handshake did not return 0x55, branches to the OS cold-start 0x3F5788C0 (jauc), skipping the whole level-1 batch: the sole caller of the level-1 runner 0x3FDF72D0 is 0x3F204400, inside the skipped region. Verified from the raw opcodes against MAME's tms34010 opcode table (BTST_K sets Z=NOT bit; jane=JNE absolute-long) and empirically. Default behaviour is unchanged (no env -> the gate is not taken). The real terminal reads IP3 low, so this is a modelled board input, not a faithful POST path; results from a level-1-skipped harness are not evidence about the real hardware's POST, but are evidence about the OS/graphics route. osprobe.lua: gate/OS/Park probe (breakpoints on 0x3F2043B0 / 0x3F204400 / 0x3F5788C0, per-frame PC histogram, optional instruction trace and RAM-global dump).
102 lines
3.6 KiB
Lua
102 lines
3.6 KiB
Lua
-- osprobe.lua -- observe the DUART1-IP3 gate and the OS cold-start.
|
|
--
|
|
-- Reports:
|
|
-- * whether the boot gate at 0x3F2042D0 takes the OS branch (0x3F2043B0)
|
|
-- instead of the level-1 runner (0x3F204400),
|
|
-- * whether the OS cold-start at 0x3F5788C0 is reached,
|
|
-- * a per-frame PC histogram so the parked PC (the first wall) is explicit.
|
|
--
|
|
-- <mame> vt1200 -rompath roms ... -debug -debugger none -debuglog \
|
|
-- -autoboot_script harness/mame/osprobe.lua -autoboot_delay 0
|
|
-- OS_FRAMES overrides the frame budget (default 3000).
|
|
|
|
local machine = manager.machine
|
|
local cpu = machine.devices[':maincpu']
|
|
local dbg = machine.debugger
|
|
local pc = cpu.state['PC']
|
|
|
|
if not dbg then print("ERROR: debugger not enabled; pass -debug"); machine:exit(); return end
|
|
|
|
-- Empirical: what memory does the driver actually give the CPU?
|
|
do
|
|
local shares = machine.memory.shares
|
|
local tags = {}
|
|
for t, _ in pairs(shares) do tags[#tags + 1] = t end
|
|
table.sort(tags)
|
|
for _, t in ipairs(tags) do
|
|
local s = shares[t]
|
|
print(string.format("SHARE %s size=%d bytes bytewidth=%d length=%d",
|
|
tostring(s.tag), s.size, s.bytewidth, s.length))
|
|
end
|
|
end
|
|
|
|
local maxframes = tonumber(os.getenv("OS_FRAMES") or "3000")
|
|
local recent = tonumber(os.getenv("OS_RECENT") or "300")
|
|
local frames = 0
|
|
local hist = {}
|
|
local first = {}
|
|
local lastpc = 0
|
|
local rhist = {}
|
|
local rfirst = {}
|
|
local gate = { skip = 0, run = 0, os = 0 }
|
|
|
|
local function bp(addr, body)
|
|
dbg:command('bpset ' .. addr .. ',,{ ' .. body .. ' ; g }')
|
|
end
|
|
bp("3f2043b0", 'printf "GATE-SKIP-BRANCH\\n"')
|
|
bp("3f204400", 'printf "GATE-RUN-LEVEL1\\n"')
|
|
bp("3f5788c0", 'printf "OS-COLD-START pc=%08X\\n", pc')
|
|
bp("3fdf72d0", 'printf "LEVEL1-RUNNER-ENTER\\n"')
|
|
|
|
emu.register_frame_done(function()
|
|
frames = frames + 1
|
|
if os.getenv("OS_TRACE") and frames == tonumber(os.getenv("OS_TRACE_AT") or "1") then
|
|
dbg:command('trace ' .. os.getenv("OS_TRACE"))
|
|
print("TRACE-ON " .. os.getenv("OS_TRACE"))
|
|
end
|
|
if os.getenv("OS_TRACE") and frames == (tonumber(os.getenv("OS_TRACE_AT") or "1") + tonumber(os.getenv("OS_TRACE_FRAMES") or "1")) then
|
|
dbg:command('trace off')
|
|
print("TRACE-OFF")
|
|
end
|
|
if os.getenv("OS_GLOBALS_AT") and frames == tonumber(os.getenv("OS_GLOBALS_AT")) then
|
|
local p = cpu.spaces['program']
|
|
for _, g in ipairs({0x23cbf0, 0x23cc50, 0x23cc30, 0x1b3900, 0x1e9420, 0x16f0}) do
|
|
local v = p:read_u32(g)
|
|
print(string.format("GLOBAL @%08X = %08X", g, v))
|
|
end
|
|
end
|
|
local v = pc.value
|
|
hist[v] = (hist[v] or 0) + 1
|
|
if not first[v] then first[v] = frames end
|
|
lastpc = v
|
|
if frames > maxframes - recent then
|
|
rhist[v] = (rhist[v] or 0) + 1
|
|
if not rfirst[v] then rfirst[v] = frames end
|
|
end
|
|
if frames >= maxframes then
|
|
local n = 0
|
|
for _ in pairs(hist) do n = n + 1 end
|
|
print(string.format("--- frames=%d distinct_pcs=%d ---", frames, n))
|
|
print("--- hottest PCs (one sample per frame) ---")
|
|
local list = {}
|
|
for k, c in pairs(hist) do list[#list + 1] = { k, c } end
|
|
table.sort(list, function(a, b) return a[2] > b[2] end)
|
|
for i = 1, math.min(20, #list) do
|
|
print(string.format(" PC=%08X samples=%d first_frame=%d",
|
|
list[i][1], list[i][2], first[list[i][1]]))
|
|
end
|
|
print(string.format("--- last frame PC=%08X ; last %d frames ---", lastpc, recent))
|
|
local rlist = {}
|
|
for k, c in pairs(rhist) do rlist[#rlist + 1] = { k, c } end
|
|
table.sort(rlist, function(a, b) return a[2] > b[2] end)
|
|
for i = 1, math.min(12, #rlist) do
|
|
print(string.format(" PARK PC=%08X samples=%d first_frame=%d",
|
|
rlist[i][1], rlist[i][2], rfirst[rlist[i][1]]))
|
|
end
|
|
machine:exit()
|
|
end
|
|
end, "vt1200-osprobe")
|
|
|
|
dbg.visible_cpu = cpu
|
|
dbg.execution_state = 'run'
|