-- Same as show_frame.lua, but sets a REAL 256x256 CRTC mode instead of -- borrowing the IPL's 768x512 text timing. Proves the mode table in -- crtc_mode.lua and removes the x=512 wrap of FINDINGS 22.5. M=manager.machine; SP=M.devices[":maincpu"].spaces["program"]; SUB=nil local function load_mode() for _,p in ipairs{"../tools/bench/crtc_mode.lua","tools/bench/crtc_mode.lua","crtc_mode.lua"} do local f=loadfile(p); if f then return f() end end error("crtc_mode.lua not found") end local MODE = load_mode() local GVRAM, GPAL = 0xC00000, 0xE82000 local f=io.open("frame256.bin","rb"); local d=f:read("a"); f:close() local function B(i) return string.byte(d,i) end local W,H = B(5)*256+B(6), B(7)*256+B(8) local PAL0, PIX0 = 9, 9+256*3 local YOFF = (MODE.height - H) // 2 -- letterbox 192 rows inside 256 -- GGGGGRRRRRBBBBBI, confirmed from x68k_v.cpp. The LSB "I" is SHARED by all -- three channels: each renders as pal6bit((field<<1)|I). Hardcoding I=1 (as -- show_frame.lua does) makes true black unreachable -- pal6bit(1) = 4 -- so I -- is chosen per entry to minimise summed squared error over R,G,B. local function pal6(v) return ((v<<2)|(v>>4)) & 0xff end local function pack(r,g,b) local f = {r>>3, g>>3, b>>3} local best, bestI = nil, 1 for I=0,1 do local e=0 for c=1,3 do local want = ({r,g,b})[c] local d = pal6((f[c]<<1)|I) - want e = e + d*d end if best==nil or e=YOFF+H then local base=GVRAM+y*1024 for x=0,MODE.width-1 do SP:write_u16(base+x*2,0) end end end for c=0,255 do local o=PAL0+c*3 SP:write_u16(GPAL+c*2, pack(B(o),B(o+1),B(o+2))) end for y=0,H-1 do local row,base = PIX0+y*W, GVRAM+(y+YOFF)*1024 for x=0,W-1 do SP:write_u16(base+x*2, B(row+x)) end end print(string.format("[256] R00-R08 %d %d %d %d %d %d %d %d %d R20=%04X yoff=%d t=%.3f", SP:read_u16(0xE80000),SP:read_u16(0xE80002),SP:read_u16(0xE80004),SP:read_u16(0xE80006), SP:read_u16(0xE80008),SP:read_u16(0xE8000A),SP:read_u16(0xE8000C),SP:read_u16(0xE8000E), SP:read_u16(0xE80010),SP:read_u16(0xE80028), YOFF, t)) st,tp="painted",t elseif st=="painted" and t>tp+0.30 then M.video:snapshot(); print("[256] snapshot"); st="done"; M:exit() end end)