-newport: Improved handling of COLORHOST mode bit. [Ryan Holtz]

This commit is contained in:
MooglyGuy 2019-05-25 16:18:16 +02:00
parent bf57ca78f0
commit 7e6f1598b2
2 changed files with 153 additions and 177 deletions

View File

@ -46,6 +46,7 @@
DEFINE_DEVICE_TYPE(GIO_XL8, gio_xl8_device, "gio_xl8", "SGI 8-bit XL board")
DEFINE_DEVICE_TYPE(GIO_XL24, gio_xl24_device, "gio_xl24", "SGI 24-bit XL board")
/*static*/ const uint32_t newport_base_device::s_host_shifts[4] = { 8, 8, 16, 32 };
newport_base_device::newport_base_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, uint32_t global_mask)
: device_t(mconfig, type, tag, owner, clock)
@ -120,7 +121,17 @@ void newport_base_device::device_start()
save_item(NAME(m_xmap1.m_mode_table));
save_item(NAME(m_rex3.m_draw_mode0));
save_item(NAME(m_rex3.m_color_host));
save_item(NAME(m_rex3.m_draw_mode1));
save_item(NAME(m_rex3.m_plane_enable));
save_item(NAME(m_rex3.m_plane_depth));
save_item(NAME(m_rex3.m_rwpacked));
save_item(NAME(m_rex3.m_hostdepth));
save_item(NAME(m_rex3.m_rwdouble));
save_item(NAME(m_rex3.m_sfactor));
save_item(NAME(m_rex3.m_dfactor));
save_item(NAME(m_rex3.m_logicop));
save_item(NAME(m_rex3.m_store_shift));
save_item(NAME(m_rex3.m_write_width));
save_item(NAME(m_rex3.m_ls_mode));
save_item(NAME(m_rex3.m_ls_pattern));
@ -190,10 +201,6 @@ void newport_base_device::device_start()
save_item(NAME(m_rex3.m_config));
save_item(NAME(m_rex3.m_status));
save_item(NAME(m_rex3.m_xfer_width));
save_item(NAME(m_rex3.m_store_shift));
save_item(NAME(m_rex3.m_logic_op));
save_item(NAME(m_rex3.m_src_blend));
save_item(NAME(m_rex3.m_dst_blend));
save_item(NAME(m_cmap0.m_palette_idx));
save_item(NAME(m_cmap0.m_palette));
@ -1625,11 +1632,27 @@ READ64_MEMBER(newport_base_device::rex3_r)
return ret;
}
uint32_t newport_base_device::get_host_color()
{
static const uint32_t s_color_masks[4] = { 0xf, 0xff, 0xfff, 0xffffff };
const uint32_t color = (uint32_t)(m_rex3.m_host_dataport >> m_rex3.m_host_shift) & s_color_masks[m_rex3.m_hostdepth];
if (m_rex3.m_rwpacked)
{
if ((m_rex3.m_rwdouble && m_rex3.m_host_shift > 0) || m_rex3.m_host_shift > 32)
m_rex3.m_host_shift -= s_host_shifts[m_rex3.m_hostdepth];
else
m_rex3.m_host_shift = 64 - s_host_shifts[m_rex3.m_hostdepth];
}
return color;
}
void newport_base_device::write_pixel(uint32_t color)
{
const bool shade = BIT(m_rex3.m_draw_mode0, 18);
const bool rgbmode = BIT(m_rex3.m_draw_mode1, 15);
if (shade || rgbmode)
if (m_rex3.m_color_host)
write_pixel(m_rex3.m_x_start_i, m_rex3.m_y_start_i, get_host_color());
else if (shade || rgbmode)
write_pixel(m_rex3.m_x_start_i, m_rex3.m_y_start_i, get_rgb_color(m_rex3.m_x_start_i, m_rex3.m_y_start_i));
else
write_pixel(m_rex3.m_x_start_i, m_rex3.m_y_start_i, color);
@ -1720,8 +1743,7 @@ bool newport_base_device::pixel_clip_pass(int16_t x, int16_t y)
void newport_base_device::store_pixel(uint32_t *dest_buf, uint32_t src)
{
const uint32_t fast_mask = m_rex3.m_write_mask;//BIT(m_rex3.m_draw_mode1, 17) ? 0xffffffff : m_rex3.m_write_mask;
const uint32_t write_mask = fast_mask & m_global_mask;
const uint32_t write_mask = m_rex3.m_write_mask & m_global_mask;
const uint32_t dst = *dest_buf >> m_rex3.m_store_shift;
*dest_buf &= ~write_mask;
@ -1791,7 +1813,7 @@ void newport_base_device::store_pixel(uint32_t *dest_buf, uint32_t src)
break;
}
switch (m_rex3.m_src_blend)
switch (m_rex3.m_sfactor)
{
case 0: // 0
default:
@ -1835,7 +1857,7 @@ void newport_base_device::store_pixel(uint32_t *dest_buf, uint32_t src)
break;
}
switch (m_rex3.m_dst_blend)
switch (m_rex3.m_dfactor)
{
case 0: // 0
default:
@ -1890,9 +1912,7 @@ void newport_base_device::store_pixel(uint32_t *dest_buf, uint32_t src)
}
else
{
//src <<= m_rex3.m_store_shift;
switch (m_rex3.m_logic_op)
switch (m_rex3.m_logicop)
{
case 0: break;
case 1: *dest_buf |= ((src & dst) << m_rex3.m_store_shift) & write_mask; break;
@ -2408,7 +2428,7 @@ uint32_t newport_base_device::do_pixel_read()
ret = m_cid[src_addr];
break;
}
LOGMASKED(LOG_COMMANDS, "Read %08x from %04x, %04x\n", ret, src_x, src_y);
LOGMASKED(LOG_COMMANDS, "Read %08x (%08x) from %04x, %04x\n", ret, m_rgbci[src_addr], src_x, src_y);
m_rex3.m_x_start_i++;
if (m_rex3.m_x_start_i > m_rex3.m_x_end_i)
{
@ -2539,19 +2559,29 @@ void newport_base_device::do_rex3_command()
if (BIT(mode0, 19) && dx < 0) // LROnly
break;
if (!BIT(mode0, 8))
end_x = start_x;
end_x += dx;
end_x += dx;
int16_t prim_end_x = end_x;
bool stop_on_x = BIT(mode0, 8);
if (BIT(mode0, 15) && abs(end_x - start_x) > 32)
end_x = start_x + 32 * dx;
prim_end_x = start_x + 32 * dx;
if (m_rex3.m_color_host && m_rex3.m_rwpacked)
{
stop_on_x = true;
static const int16_t s_max_host_lengths[2][4] = { { 4, 4, 2, 1 }, { 8, 8, 4, 2 } };
const int16_t max_length = s_max_host_lengths[m_rex3.m_rwdouble ? 1 : 0][m_rex3.m_hostdepth];
int16_t length = abs(prim_end_x - start_x);
if (length > max_length)
prim_end_x = start_x + dx * max_length;
}
const bool opaque = BIT(mode0, 16) || BIT(mode0, 17);
const uint32_t pattern = BIT(mode0, 12) ? m_rex3.m_z_pattern : (BIT(mode0, 13) ? m_rex3.m_ls_pattern : 0xffffffff);
const bool shade = BIT(mode0, 18);
const bool rgbmode = BIT(mode1, 15);
const bool opaque = BIT(mode0, 16) || BIT(mode0, 17);
const bool fastclear = BIT(mode1, 17);
const uint32_t pattern = BIT(mode0, 12) ? m_rex3.m_z_pattern : (BIT(mode0, 13) ? m_rex3.m_ls_pattern : 0xffffffff);
LOGMASKED(LOG_COMMANDS, "%04x, %04x to %04x, %04x = %08x\n", start_x, start_y, end_x, end_y, pattern);
@ -2578,11 +2608,13 @@ void newport_base_device::do_rex3_command()
}
uint32_t bit = 31;
for (; start_x != end_x; start_x += dx)
do
{
if (BIT(pattern, bit))
{
if ((shade || rgbmode) && !fastclear)
if (m_rex3.m_color_host)
write_pixel(start_x, start_y, get_host_color());
else if ((shade || rgbmode) && !fastclear)
write_pixel(start_x, start_y, get_rgb_color(start_x, start_y));
else
write_pixel(start_x, start_y, color);
@ -2596,178 +2628,103 @@ void newport_base_device::do_rex3_command()
iterate_shade();
bit = (bit - 1) & 0x1f;
}
start_x += dx;
} while (start_x != prim_end_x && start_x != end_x && stop_on_x);
write_x_start(start_x << 11);
break;
}
case 1: // Block
{
if (BIT(mode0, 19) && dx < 0) // LROnly
break;
end_x += dx;
end_x += dx;
end_y += dy;
if (BIT(mode0, 6)) // ColorHost
int16_t prim_end_x = end_x;
bool stop_on_x = BIT(mode0, 8);
const bool stop_on_y = BIT(mode0, 9);
if (BIT(mode0, 15) && (end_x - start_x) >= 32)
prim_end_x = start_x + 32 * dx;
if (m_rex3.m_color_host && m_rex3.m_rwpacked)
{
stop_on_x = true;
static const int16_t s_max_host_lengths[2][4] = { { 4, 4, 2, 1 }, { 8, 8, 4, 2 } };
const int16_t max_length = s_max_host_lengths[m_rex3.m_rwdouble ? 1 : 0][m_rex3.m_hostdepth];
int16_t length = abs(prim_end_x - start_x);
if (length > max_length)
prim_end_x = start_x + dx * max_length;
}
const bool shade = BIT(mode0, 18);
const bool rgbmode = BIT(mode1, 15);
const bool opaque = BIT(mode0, 16) || BIT(mode0, 17);
const bool fastclear = BIT(mode1, 17);
const uint32_t pattern = BIT(mode0, 12) ? m_rex3.m_z_pattern : (BIT(mode0, 13) ? m_rex3.m_ls_pattern : 0xffffffff);
uint32_t color = m_rex3.m_color_i;
if (fastclear)
{
if (BIT(mode1, 7)) // Packed
switch (m_rex3.m_plane_depth)
{
const bool doubleword = BIT(mode1, 10);
LOGMASKED(LOG_COMMANDS, "%04x, %04x = %08x%08x\n", start_x, start_y, (uint32_t)(m_rex3.m_host_dataport >> 32), (uint32_t)m_rex3.m_host_dataport);
case 0: // 4bpp
color = m_rex3.m_color_vram & 0xf;
color |= color << 4;
break;
case 1: // 8bpp
color = m_rex3.m_color_vram & 0xff;
break;
case 2: // 12bpp
color = ((m_rex3.m_color_vram & 0xf00000) >> 12) | ((m_rex3.m_color_vram & 0xf000) >> 8) | ((m_rex3.m_color_vram & 0xf0) >> 4);
color |= color << 12;
break;
case 3: // 24bpp
color = m_rex3.m_color_vram & 0xffffff;
break;
}
}
uint16_t width = end_x - start_x;
uint64_t shift = 0;
switch ((m_rex3.m_draw_mode1 >> 8) & 3)
do
{
uint32_t bit = 31;
do
{
if (BIT(pattern, bit))
{
case 0: // 4bpp
{
const uint16_t max_width = doubleword ? 16 : 8;
if (width > max_width)
width = max_width;
shift = 60;
for (uint16_t i = 0; i < width; i++)
{
write_pixel(start_x, start_y, (uint32_t)(m_rex3.m_host_dataport >> shift));
start_x++;
shift -= 4;
}
break;
}
case 1: // 8bpp
{
const uint16_t max_width = doubleword ? 8 : 4;
if (width > max_width)
width = max_width;
shift = 56;
for (uint16_t i = 0; i < width; i++)
{
write_pixel(start_x, start_y, (uint32_t)(m_rex3.m_host_dataport >> shift));
start_x++;
shift -= 8;
}
break;
}
case 2: // 12bpp
{
const uint16_t max_width = doubleword ? 4 : 2;
if (width > max_width)
width = max_width;
shift = 48;
for (uint16_t i = 0; i < width; i++)
{
write_pixel(start_x, start_y, (uint32_t)(m_rex3.m_host_dataport >> shift));
start_x++;
shift -= 16;
}
break;
}
case 3: // 32bpp
{
const uint16_t max_width = doubleword ? 2 : 1;
if (width > max_width)
width = max_width;
shift = 32;
for (uint16_t i = 0; i < width; i++)
{
write_pixel(start_x, start_y, (uint32_t)(m_rex3.m_host_dataport >> shift));
start_x++;
shift -= 32;
}
break;
}
if (m_rex3.m_color_host)
write_pixel(start_x, start_y, get_host_color());
else if ((shade || rgbmode) && !fastclear)
write_pixel(start_x, start_y, get_rgb_color(start_x, start_y));
else
write_pixel(start_x, start_y, color);
}
}
else
{
LOGMASKED(LOG_COMMANDS, "%04x, %04x = %02x\n", start_x, start_y, (uint8_t)(m_rex3.m_host_dataport >> 56));
write_pixel(start_x, start_y, m_rex3.m_host_dataport >> 56);
start_x++;
}
else if (opaque)
{
write_pixel(start_x, start_y, m_rex3.m_color_back);
}
if (shade)
iterate_shade();
bit = (bit - 1) & 0x1f;
start_x += dx;
} while (start_x != prim_end_x && start_x != end_x && stop_on_x);
if (start_x == end_x)
{
start_y += dy;
start_x = m_rex3.m_x_save;
start_y += dy;
}
}
else
{
const bool stop_on_x = BIT(mode0, 8);
const bool stop_on_y = BIT(mode0, 9);
const bool shade = BIT(mode0, 18);
const bool rgbmode = BIT(mode1, 15);
const bool opaque = BIT(mode0, 16) || BIT(mode0, 17);
const bool fastclear = BIT(mode1, 17);
const uint32_t pattern = BIT(mode0, 12) ? m_rex3.m_z_pattern : (BIT(mode0, 13) ? m_rex3.m_ls_pattern : 0xffffffff);
if (BIT(mode0, 15) && (end_x - start_x) >= 32)
end_x = start_x + 32 * dx;
uint32_t color = m_rex3.m_color_i;
if (fastclear)
{
switch (m_rex3.m_plane_depth)
{
case 0: // 4bpp
color = m_rex3.m_color_vram & 0xf;
color |= color << 4;
break;
case 1: // 8bpp
color = m_rex3.m_color_vram & 0xff;
break;
case 2: // 12bpp
color = ((m_rex3.m_color_vram & 0xf00000) >> 12) | ((m_rex3.m_color_vram & 0xf000) >> 8) | ((m_rex3.m_color_vram & 0xf0) >> 4);
color |= color << 12;
break;
case 3: // 24bpp
color = m_rex3.m_color_vram & 0xffffff;
break;
}
}
do
{
uint32_t bit = 31;
do
{
if (BIT(pattern, bit))
{
if ((shade || rgbmode) && !fastclear)
write_pixel(start_x, start_y, get_rgb_color(start_x, start_y));
else
write_pixel(start_x, start_y, color);
}
else if (opaque)
{
write_pixel(start_x, start_y, m_rex3.m_color_back);
}
if (shade)
iterate_shade();
bit = (bit - 1) & 0x1f;
start_x += dx;
} while (start_x != end_x && stop_on_x);
if (start_x == end_x)
{
start_x = m_rex3.m_x_save;
start_y += dy;
}
} while (start_y != end_y && stop_on_y);
}
} while (start_y != end_y && stop_on_y);
write_x_start(start_x << 11);
write_y_start(start_y << 11);
break;
}
case 2: // I_Line
do_iline(m_rex3.m_color_i);
@ -3080,10 +3037,16 @@ WRITE64_MEMBER(newport_base_device::rex3_w)
static const uint32_t s_store_shift[4] = { 4, 0, 12, 0 };
m_rex3.m_plane_enable = m_rex3.m_draw_mode1 & 7;
m_rex3.m_plane_depth = (m_rex3.m_draw_mode1 >> 3) & 3;
m_rex3.m_rwpacked = BIT(m_rex3.m_draw_mode1, 7);
m_rex3.m_hostdepth = (m_rex3.m_draw_mode1 >> 8) & 3;
m_rex3.m_rwdouble = BIT(m_rex3.m_draw_mode1, 10);
m_rex3.m_sfactor = (m_rex3.m_draw_mode1 >> 19) & 7;
m_rex3.m_dfactor = (m_rex3.m_draw_mode1 >> 22) & 7;
m_rex3.m_logicop = (m_rex3.m_draw_mode1 >> 28) & 15;
m_rex3.m_store_shift = BIT(m_rex3.m_draw_mode1, 5) ? s_store_shift[m_rex3.m_plane_depth] : 0;
m_rex3.m_logic_op = (m_rex3.m_draw_mode1 >> 28) & 15;
m_rex3.m_src_blend = (m_rex3.m_draw_mode1 >> 19) & 7;
m_rex3.m_dst_blend = (m_rex3.m_draw_mode1 >> 22) & 7;
m_rex3.m_host_shift = 64 - s_host_shifts[m_rex3.m_hostdepth];
}
if (ACCESSING_BITS_0_31)
{
@ -3145,6 +3108,8 @@ WRITE64_MEMBER(newport_base_device::rex3_w)
LOGMASKED(LOG_REX3, " Enable End Filter: %d\n", BIT(data32, 22));
LOGMASKED(LOG_REX3, " Enable Y+2 Stride: %d\n", BIT(data32, 23));
m_rex3.m_draw_mode0 = data32;
m_rex3.m_color_host = BIT(m_rex3.m_draw_mode0, 6);
}
break;
case 0x0008/8:
@ -3512,6 +3477,7 @@ WRITE64_MEMBER(newport_base_device::rex3_w)
case 0x0230/8:
LOGMASKED(LOG_REX3, "REX3 Host Data Port Write: %08x%08x & %08x%08x\n", (uint32_t)(data >> 32), (uint32_t)data, (uint64_t)(mem_mask >> 32), (uint32_t)mem_mask);
COMBINE_DATA(&m_rex3.m_host_dataport);
m_rex3.m_host_shift = 64 - s_host_shifts[m_rex3.m_hostdepth];
break;
case 0x0238/8:
if (ACCESSING_BITS_32_63)

View File

@ -93,7 +93,20 @@ protected:
struct rex3_t
{
uint32_t m_draw_mode0;
bool m_color_host;
uint32_t m_draw_mode1;
uint8_t m_plane_enable;
uint8_t m_plane_depth;
bool m_rwpacked;
bool m_rwdouble;
uint8_t m_hostdepth;
uint8_t m_sfactor;
uint8_t m_dfactor;
uint8_t m_logicop;
uint32_t m_store_shift;
uint32_t m_host_shift;
uint32_t m_write_width;
uint32_t m_ls_mode;
uint32_t m_ls_pattern;
@ -162,12 +175,6 @@ protected:
uint32_t m_config;
uint32_t m_status;
uint8_t m_xfer_width;
uint8_t m_plane_enable;
uint8_t m_plane_depth;
uint32_t m_store_shift;
uint8_t m_src_blend;
uint8_t m_dst_blend;
uint8_t m_logic_op;
};
struct cmap_t
@ -205,6 +212,7 @@ protected:
virtual uint32_t get_cmap_revision() = 0;
virtual uint32_t get_xmap_revision() = 0;
uint32_t get_host_color();
uint32_t get_rgb_color(int16_t x, int16_t y);
struct bresenham_octant_info_t
@ -253,6 +261,8 @@ protected:
FILE *m_newview_log;
#endif
static const uint32_t s_host_shifts[4];
};
class gio_xl8_device : public newport_base_device