joeylib2/patches/x68k-crtc-probe.lua

71 lines
2.6 KiB
Lua

-- CRTC high-speed-clear timing probe.
--
-- Discriminator 1 (unambiguous): write a pattern into GVRAM, reserve the
-- clear, then read GVRAM back IMMEDIATELY. Stock MAME performs the whole
-- clear synchronously inside the register write, so the pattern is already
-- gone. Real hardware (and the patched build) only RESERVES the clear, so the
-- pattern must still be intact until the next vertical display start.
--
-- Discriminator 2: the busy bit (operation port $E80480 bit 1) sampled once
-- per frame. Patched: 0 until VDISP, then set for exactly one frame.
local cpu = manager.machine.devices[":maincpu"]
local mem = cpu.spaces["program"]
local frame = 0
local OPPORT = 0xE80480 -- CRTC operation port
local R21 = 0xE8002A -- clear page select
local GVRAM = 0xC00000
local PAT = { 0x1234, 0x5678, 0x9ABC, 0xDEF0 }
local probeAt = 240
local done = false
local log = {}
local function writePattern()
for i = 0, 3 do
mem:write_u16(GVRAM + i * 2, PAT[i + 1])
end
-- a couple of rows in as well, so we are not only sampling row 0
mem:write_u16(GVRAM + 512 * 2 * 4, 0x4321)
end
local function readPattern()
local v = {}
for i = 0, 3 do
v[#v + 1] = string.format("%04X", mem:read_u16(GVRAM + i * 2))
end
v[#v + 1] = string.format("%04X", mem:read_u16(GVRAM + 512 * 2 * 4))
return table.concat(v, " ")
end
local function busy()
return (mem:read_u16(OPPORT) & 0x02) ~= 0 and 1 or 0
end
emu.register_frame_done(function()
frame = frame + 1
if frame == probeAt then
writePattern()
io.write("CRTCPROBE pattern_written gvram=" .. readPattern() .. "\n")
io.write(string.format("CRTCPROBE busy_before=%d r21_before=%04X\n",
busy(), mem:read_u16(R21)))
mem:write_u16(R21, 0x000F) -- select all four clear pages
mem:write_u16(OPPORT, 0x0002) -- reserve the high-speed clear
-- IMMEDIATELY after the write, in the same emulated instant:
io.write("CRTCPROBE after_write gvram=" .. readPattern() ..
string.format(" busy=%d\n", busy()))
log[#log + 1] = string.format("f+0 busy=%d gv=%s", busy(), readPattern())
elseif frame > probeAt and frame <= probeAt + 6 then
log[#log + 1] = string.format("f+%d busy=%d gv=%s",
frame - probeAt, busy(), readPattern())
elseif frame == probeAt + 7 and not done then
done = true
for _, l in ipairs(log) do
io.write("CRTCPROBE " .. l .. "\n")
end
io.write("CRTCPROBE end\n")
io.flush()
manager.machine:exit()
end
end)