-- 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)