-- CRTC mode table: 256x256, 256 colours, 31.5kHz, graphics double-scanned. -- -- DERIVED from MAME 0.277 src/mame/sharp/x68k_crtc.cpp, not recalled. The -- derivation is self-checking, which is why it is trustworthy: -- -- refresh_mode() picks the dot clock as (reg20 bit4 ? 69.55199MHz : 38.86363MHz)/div -- with div from the (reg20 & 0x1f) ladder: 0x16 -> 2 (IPL's 768x512) -- 0x11 -> 3 (512 wide) -- 0x10 -> 6 (256 wide, double-scan) -- -- IPL 768 mode: div 2 -> 34.776 MHz, m_htotal = (137+1)*8 = 1104 dots -- 34.776e6 / 1104 = 31500.0 Hz exactly. -- 256 mode: div 6 -> 11.592 MHz. Same 31.5kHz line rate requires -- 11.592e6 / 31500 = 368 dots = 46 chars -> R00 = 45. -- -- 368 = 1104/3 exactly, so EVERY horizontal register is the 768-mode value -- divided by 3 -- no rounding for the active window: -- visible chars (124-28) / 3 = 32 -> 32*8 = 256 dots exact -- Only the blanking split needs rounding. 768 mode is sync/back/front = -- 14/14/14 chars; /3 = 4.67 each; the closest integer triple summing to -- 46-32 = 14 is 5/5/4. -> R01=5, R02=10, R03=42. -- -- Total blanking time is identical to the 768 mode (112 dots @ 11.592MHz = -- 336 dots @ 34.776MHz = 9.66us), which is what a real monitor needs. -- -- VERTICAL registers are NOT halved. The CRTC still generates a 568-line -- 31.5kHz raster (31500/568 = 55.46 Hz); "256 lines" is a graphics-layer -- double-scan (draw_gfx() halves gfxrect, x68k_v.cpp:401). Halving them would -- ask the monitor for 110 Hz. So R04-R07 keep the 31kHz text-mode values. -- MAME logerrors "visarea larger then reg[20]" for this; it is cosmetic. local M = {} M.regs = { [0] = 45, -- H total (46 chars = 368 dots @ 11.592MHz = 31500.0 Hz) [1] = 5, -- H sync end (5 chars = 3.45us) [2] = 10, -- H disp begin (hbegin = 10*8+1 = 81) [3] = 42, -- H disp end (hend = 336; inclusive width = 336-81+1 = 256) [4] = 567, -- V total (568 scanlines -> 55.46 Hz) [5] = 5, -- V sync end [6] = 40, -- V disp begin (vbegin = 41) [7] = 552, -- V disp end (512 scanlines -> 256 gfx rows, double-scanned) [8] = 27, -- H sync adjust (MAME stores but does not use it; IPL value) } -- R20: bit11=0 display (not buffer), bits9-8=01 256-colour, -- bit4=1 31.5kHz, bits3-2=00 256 lines, bits1-0=00 256 dots M.r20 = 0x0110 M.width, M.height = 256, 256 function M.apply(SP) for r, v in pairs(M.regs) do SP:write_u16(0xE80000 + r*2, v) end SP:write_u16(0xE80000 + 20*2, M.r20) SP:write_u16(0xE82400, 0x0001) -- video ctrl reg 0: 256 colours SP:write_u16(0xE82600, 0x001F) -- reg 2: graphics on, all 4 pages, text/PCG off SP:write_u8 (0xE8E001, 15) -- monitor contrast (IPL leaves 14 = 7% dark) end return M