71 lines
2.6 KiB
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)
|