From 2ebea40dd48526d1ea639aa5a9e8453645ceda4e Mon Sep 17 00:00:00 2001 From: angelosa Date: Sat, 12 Aug 2023 23:43:07 +0200 Subject: video/mga2064w.cpp: revisit and complete drawing log --- src/devices/video/mga2064w.cpp | 166 +++++++++++++++++++++++++++++------- src/devices/video/mga2064w.h | 8 ++ src/devices/video/pc_vga_matrox.cpp | 4 +- 3 files changed, 143 insertions(+), 35 deletions(-) diff --git a/src/devices/video/mga2064w.cpp b/src/devices/video/mga2064w.cpp index 2261ea819a8..e65b544b055 100644 --- a/src/devices/video/mga2064w.cpp +++ b/src/devices/video/mga2064w.cpp @@ -95,8 +95,8 @@ void mga2064w_device::config_map(address_map &map) void mga2064w_device::mgabase1_map(address_map &map) { -// map(0x0000, 0x1bff).rw(FUNC(mga2064w_device::dmawin_iload_r), FUNC(mga2064w_device::dmawin_idump_w)); - map(0x1c00, 0x1cff).mirror(0x100).m(FUNC(mga2064w_device::dwgreg_map)); +// map(0x0000, 0x1bff).rw(FUNC(mga2064w_device::dmawin_idump_r), FUNC(mga2064w_device::dmawin_iload_w)); + map(0x1c00, 0x1dff).m(FUNC(mga2064w_device::dwgreg_map)); // map(0x1e00, 0x1eff) HSTREG Host registers map(0x1e10, 0x1e13).r(FUNC(mga2064w_device::fifo_status_r)); map(0x1e14, 0x1e17).r(FUNC(mga2064w_device::status_r)); @@ -116,17 +116,40 @@ void mga2064w_device::mgabase2_map(address_map &map) map(0x000000, 0x7fffff).rw(m_svga, FUNC(matrox_vga_device::mem_linear_r), FUNC(matrox_vga_device::mem_linear_w)); } -// base + $1cxx +// assume all registers to work with dword accesses only +// all signed registers are in two's complement +// TODO: accessing 0x1dxx starts the drawing engine +// will otherwise treat iload / idump access as register access, +// it's also necessary for anything like BMONOLEF to work at least. void mga2064w_device::dwgreg_map(address_map &map) { // DWGCTL map(0x0000, 0x0003).w(FUNC(mga2064w_device::dwgctl_w)); -// map(0x0004, 0x0007) MACCESS + // MACCESS + map(0x0004, 0x0007).w(FUNC(mga2064w_device::maccess_w)); // map(0x0008, 0x000b) MCTLWTST -// map(0x000c, 0x000f) ZORG -// map(0x0010, 0x0013) PAT0 -// map(0x0014, 0x0017) PAT1 -// map(0x001c, 0x001f) PLNWT + // ZORG + map(0x000c, 0x000f).lw32( + NAME([this] (offs_t offset, u32 data, u32 mem_mask) { + // must be multiple of 512 + m_dwgreg.zorg = data & 0x7fffff; + LOGDRAW("dwgreg: ZORG %08x & %08x\n", data, mem_mask); + }) + ); + // PAT0 / PAT1 + map(0x0010, 0x0017).lw32( + NAME([this] (offs_t offset, u32 data, u32 mem_mask) { + LOGDRAW("dwgreg: PAT%d %08x & %08x\n", offset, data, mem_mask); + // TODO: alternate way to load SRC registers, in 8x8 Windows format + }) + ); + // PLNWT + map(0x001c, 0x001f).lw32( + NAME([this] (offs_t offset, u32 data, u32 mem_mask) { + LOGDRAW("dwgreg: PLNWT %08x & %08x\n", data, mem_mask); + COMBINE_DATA(&m_dwgreg.plnwt); + }) + ); // BCOL / backcol map(0x0020, 0x0023).lw32( NAME([this] (offs_t offset, u32 data, u32 mem_mask) { @@ -149,16 +172,43 @@ void mga2064w_device::dwgreg_map(address_map &map) COMBINE_DATA(&m_dwgreg.src[offset]); }) ); -// map(0x0040, 0x0043) XYSTRT -// map(0x0044, 0x0047) XYEND -// map(0x0050, 0x0053) SHIFT + // XYSTRT + map(0x0040, 0x0043).lw32( + NAME([this] (offs_t offset, u32 data, u32 mem_mask) { + LOGDRAW("dwgreg: XYSTRT %08x & %08x\n", data, mem_mask); + // TODO: alternate way to load AR5 / AR6 / XDST / YDST + }) + ); + // XYEND + map(0x0044, 0x0047).lw32( + NAME([this] (offs_t offset, u32 data, u32 mem_mask) { + LOGDRAW("dwgreg: XYEND %08x & %08x\n", data, mem_mask); + // TODO: alternate way to load AR0 / AR2 + }) + ); + // SHIFT + map(0x0050, 0x0053).lw32( + NAME([this] (offs_t offset, u32 data, u32 mem_mask) { + LOGDRAW("dwgreg: SHIFT %08x & %08x\n", data, mem_mask); + LOGDRAW("\tfuncnt %d|x_off %d|y_off %d|stylelen %d|funoff %d\n" + , data & 0x7f + // funcnt and x_off / y_off are shared, x_off must really be with bit 3 off + , data & 0x0f + , (data & 0x30) >> 4 + // stylelen and funoff are shared + , (data >> 16) & 0x7f + , (data >> 16) & 0x3f + ); + // TODO: related to PAT0 / PAT1 registers + }) + ); // SGN map(0x0058, 0x005b).lw32( NAME([this] (offs_t offset, u32 data, u32 mem_mask) { - LOGDRAW("dwgreg: SGN %08x & %08x\n", offset, data, mem_mask); + LOGDRAW("dwgreg: SGN %08x & %08x\n", data, mem_mask); LOGDRAW("\tsdydxl %s|scanleft %d|sdxl %s|sdy %s|sdxr %d\n" , BIT(data, 0) ? "x major axis" : "y major axis" - // not a mistake: sdydxl and scanleft are shared + // sdydxl and scanleft are shared , BIT(data, 0) , BIT(data, 1) ? "-x delta" : "+x delta" , BIT(data, 2) ? "-y delta" : "+y delta" @@ -176,7 +226,7 @@ void mga2064w_device::dwgreg_map(address_map &map) // AR0-6 map(0x0060, 0x007b).lw32( NAME([this] (offs_t offset, u32 data, u32 mem_mask) { - // TODO: 18-bit signed + // FIXME: signed 18-bit LOGDRAW("dwgreg: AR[%01d] -> %08x & %08x\n", offset, data, mem_mask); COMBINE_DATA(&m_dwgreg.ar[offset]); }) @@ -193,61 +243,84 @@ void mga2064w_device::dwgreg_map(address_map &map) }) ); // FXBNDRY - map(0x0084, 0x0087).lw32( + map(0x0084, 0x0087).select(0x100).lw32( NAME([this] (offs_t offset, u32 data, u32 mem_mask) { + // signed 16-bit m_dwgreg.fxleft = (s16)(data & 0xffff); m_dwgreg.fxright = (s16)(data >> 16); LOGDRAW("dwgreg: FXBNDRY %08x & %08x (FXLEFT %d|FXRIGHT %d)\n" , data, mem_mask , m_dwgreg.fxleft, m_dwgreg.fxright ); - // accessed thru the mirror at $1d84 on Windows 3.1 boot + if (BIT(offset, 6)) + LOGDRAW("\tstart trigger\n"); }) ); // YDSTLEN - // alternative way to access YDST (bits 31-16) and LEN (15-0) with a single dword - map(0x0088, 0x008b).lw32( + map(0x0088, 0x008b).select(0x100).lw32( NAME([this] (offs_t offset, u32 data, u32 mem_mask) { - // TODO: YDST (bits 31-16) - // YDST is 22 bits with sign extension ... + // alternative way to access YDST (bits 31-16) and LEN (15-0) with a single dword m_dwgreg.len = data & 0xffff; + // TODO: YDST bits 31-16 with signed conversion + // ... LOGDRAW("dwgreg: YDSTLEN %08x & %08x (YDST %d|LEN %d)\n" , data, mem_mask , data >> 16, m_dwgreg.len ); + if (BIT(offset, 6)) + LOGDRAW("\tstart trigger\n"); }) ); // PITCH map(0x008c, 0x008f).lw32( NAME([this] (offs_t offset, u32 data, u32 mem_mask) { m_dwgreg.pitch = data & 0xfff; - LOGDRAW("dwgreg: PITCH %08x & %08x %d|ylin %d\n" + LOGDRAW("dwgreg: PITCH %08x & %08x %d|ylin %d %s\n" , data, mem_mask , m_dwgreg.pitch - , BIT(data, 15) + , BIT(data, 15), BIT(data, 15) ? "linear format" : "xy format" + ); + }) + ); + // YDST + map(0x0090, 0x0093).lw32( + NAME([this] (offs_t offset, u32 data, u32 mem_mask) { + // FIXME: signed 22-bits + m_dwgreg.ydst = data & 0x3fffff; + m_dwgreg.sellin = (data >> 29) & 7; + // TODO: depends on ylin for bit meaning + LOGDRAW("dwgreg: YDST %08x & %08x|ydst %08x|sellin %d\n" + , data, mem_mask + , m_dwgreg.ydst + , m_dwgreg.sellin + ); + }) + ); + // YDSTORG + map(0x0094, 0x0097).lw32( + NAME([this] (offs_t offset, u32 data, u32 mem_mask) { + // unsigned 23-bit + m_dwgreg.ydstorg = data & 0x7fffff; + LOGDRAW("dwgreg: YDSTORG %08x & %08x %d\n" + , data, mem_mask + , m_dwgreg.ydstorg ); }) ); -// map(0x0090, 0x0093) YDST -// map(0x0094, 0x0097) YDSTORG // YTOP / cytop map(0x0098, 0x009b).lw32( NAME([this] (offs_t offset, u32 data, u32 mem_mask) { + // unsigned 23-bit m_dwgreg.cytop = data & 0x7fffff; - LOGDRAW("dwgreg: YTOP %08x & %08x %d\n" - , data, mem_mask - , m_dwgreg.cytop - ); + LOGDRAW("dwgreg: YTOP %08x & %08x\n", data, mem_mask); }) ); // YBOT / cybot map(0x009c, 0x009f).lw32( NAME([this] (offs_t offset, u32 data, u32 mem_mask) { + // unsigned 23-bit m_dwgreg.cybot = data & 0x7fffff; - LOGDRAW("dwgreg: YBOT %08x & %08x %d\n" - , data, mem_mask - , m_dwgreg.cybot - ); + LOGDRAW("dwgreg: YBOT %08x & %08x\n", data, mem_mask); }) ); // CXLEFT @@ -273,6 +346,7 @@ void mga2064w_device::dwgreg_map(address_map &map) // FXLEFT map(0x00a8, 0x00ab).lw32( NAME([this] (offs_t offset, u32 data, u32 mem_mask) { + // signed 16-bit m_dwgreg.fxleft = (s16)(data & 0xffff); LOGDRAW("dwgreg: FXLEFT %08x & %08x %d\n" , data, mem_mask @@ -283,6 +357,7 @@ void mga2064w_device::dwgreg_map(address_map &map) // FXRIGHT map(0x00ac, 0x00af).lw32( NAME([this] (offs_t offset, u32 data, u32 mem_mask) { + // signed 16-bit m_dwgreg.fxright = (s16)(data & 0xffff); LOGDRAW("dwgreg: FXRIGHT %08x & %08x %d\n" , data, mem_mask @@ -290,7 +365,17 @@ void mga2064w_device::dwgreg_map(address_map &map) ); }) ); -// map(0x00b0, 0x00b3) XDST + // XDST + map(0x00b0, 0x00b3).lw32( + NAME([this] (offs_t offset, u32 data, u32 mem_mask) { + // signed 16-bit + m_dwgreg.xdst = (s16)(data & 0xffff); + LOGDRAW("dwgreg: XDST %08x & %08x %d\n" + , data, mem_mask + , m_dwgreg.xdst + ); + }) + ); // DR0-DR15 (DR1-5-9-13 ) map(0x00c0, 0x00ff).lw32( NAME([this] (offs_t offset, u32 data, u32 mem_mask) { @@ -356,6 +441,21 @@ void mga2064w_device::dwgctl_w(offs_t offset, u32 data, u32 mem_mask) ); } +void mga2064w_device::maccess_w(offs_t offset, u32 data, u32 mem_mask) +{ + const char *const pwidth_mnemonics[4] = { + "PW8", "PW16", "PW32", "PW16" + }; + COMBINE_DATA(&m_dwgreg.maccess); + LOGDRAW("dwgreg: MACCESS %08x & %08x\n", data, mem_mask); + LOGDRAW("\tpwidth %d %s|memreset %d|dither %d|dit555 %d\n" + , m_dwgreg.maccess & 3, pwidth_mnemonics[m_dwgreg.maccess & 3] + , BIT(m_dwgreg.maccess, 15) + // nodither, flipped for convenience + , !BIT(m_dwgreg.maccess, 30) + , BIT(m_dwgreg.maccess, 31) + ); +} /* * MGABASE1 + 1e10h FIFO Status (r/o) * diff --git a/src/devices/video/mga2064w.h b/src/devices/video/mga2064w.h index 779bcbca160..9ce8715830b 100644 --- a/src/devices/video/mga2064w.h +++ b/src/devices/video/mga2064w.h @@ -51,11 +51,15 @@ private: // DWGREG section void dwgctl_w(offs_t offset, u32 data, u32 mem_mask = ~0); + void maccess_w(offs_t offset, u32 data, u32 mem_mask = ~0); struct { u32 src[4]{}; u32 dr[16]{}; u32 ar[7]{}; u32 dwgctl = 0; + u32 maccess = 0; + u32 zorg = 0; + u32 plnwt = 0; u16 pitch = 0; u16 len = 0; u32 cytop = 0; @@ -64,8 +68,12 @@ private: u16 cxright = 0; s16 fxleft = 0; s16 fxright = 0; + s16 xdst = 0; + int32_t ydst = 0; + u32 ydstorg = 0; u32 bcol = 0; u32 fcol = 0; + u8 sellin = 0; } m_dwgreg; }; diff --git a/src/devices/video/pc_vga_matrox.cpp b/src/devices/video/pc_vga_matrox.cpp index 2ade6ec2006..a5fe8bca111 100644 --- a/src/devices/video/pc_vga_matrox.cpp +++ b/src/devices/video/pc_vga_matrox.cpp @@ -234,13 +234,13 @@ void matrox_vga_device::ramdac_ext_map(address_map &map) u8 matrox_vga_device::ramdac_ext_indexed_r() { // Unclear from the docs, according to usage seems to be the write index with no autoincrement - logerror("RAMDAC ext read [%02x]\n", vga.dac.write_index); +// logerror("RAMDAC ext read [%02x]\n", vga.dac.write_index); return space(EXT_REG + 1).read_byte(vga.dac.write_index); } void matrox_vga_device::ramdac_ext_indexed_w(offs_t offset, u8 data) { - logerror("RAMDAC ext [%02x] %02x\n", vga.dac.write_index, data); +// logerror("RAMDAC ext [%02x] %02x\n", vga.dac.write_index, data); space(EXT_REG + 1).write_byte(vga.dac.write_index, data); } -- cgit v1.2.3