video/mga2064w.cpp: revisit and complete drawing log

This commit is contained in:
angelosa 2023-08-12 23:43:07 +02:00
parent 81743ee3b9
commit 2ebea40dd4
3 changed files with 143 additions and 35 deletions

View File

@ -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) <reserved> 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 <reserved>)
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)
*

View File

@ -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;
};

View File

@ -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);
}