summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author mooglyguy <therealmogminer@gmail.com>2019-06-09 17:00:39 +0200
committer MooglyGuy <therealmogminer@gmail.com>2019-06-09 17:01:13 +0200
commit15baaacf9be8b58ab89e57ced2a3be0340505e3a (patch)
treeafbcb839582a701ea6ed99c3cd91198067903858
parent0936ebf6c3ed5b3dd16d52a8529c1558f8777c5d (diff)
-newport: Various changes. [Ryan Holtz]
* Added support for endian swapping on host data port writes. * Added double-buffer shift support for non-RGB/CI planes. * Fixed Packed Color Fractions register handling.
-rw-r--r--src/devices/bus/gio64/newport.cpp184
-rw-r--r--src/devices/bus/gio64/newport.h4
2 files changed, 145 insertions, 43 deletions
diff --git a/src/devices/bus/gio64/newport.cpp b/src/devices/bus/gio64/newport.cpp
index 9aab1185ceb..7fc320d4a72 100644
--- a/src/devices/bus/gio64/newport.cpp
+++ b/src/devices/bus/gio64/newport.cpp
@@ -12,18 +12,6 @@
- XMAP9: Final display generator
- CMAP: Palette mapper
- VC2: Video timing controller / CRTC
-
- Taken from the Linux Newport driver, slave addresses for Newport devices are:
- VC2 0
- Both CMAPs 1
- CMAP 0 2
- CMAP 1 3
- Both XMAPs 4
- XMAP 0 5
- XMAP 1 6
- RAMDAC 7
- VIDEO (CC1) 8
- VIDEO (AB1) 9
*/
#include "emu.h"
@@ -36,11 +24,12 @@
#define LOG_XMAP0 (1 << 4)
#define LOG_XMAP1 (1 << 5)
#define LOG_REX3 (1 << 6)
-#define LOG_COMMANDS (1 << 7)
-#define LOG_REJECTS (1 << 8)
-#define LOG_ALL (LOG_UNKNOWN | LOG_VC2 | LOG_CMAP0 | LOG_CMAP1 | LOG_XMAP0 | LOG_XMAP1 | LOG_REX3 | LOG_COMMANDS | LOG_REJECTS)
+#define LOG_RAMDAC (1 << 7)
+#define LOG_COMMANDS (1 << 8)
+#define LOG_REJECTS (1 << 9)
+#define LOG_ALL (LOG_UNKNOWN | LOG_VC2 | LOG_CMAP0 | LOG_CMAP1 | LOG_XMAP0 | LOG_XMAP1 | LOG_REX3 | LOG_RAMDAC | LOG_COMMANDS | LOG_REJECTS)
-#define VERBOSE (0)//(LOG_REX3 | LOG_COMMANDS)
+#define VERBOSE (0)//(LOG_REX3 | LOG_CMAP0 | LOG_CMAP1 | LOG_XMAP0 | LOG_XMAP1)
#include "logmacro.h"
DEFINE_DEVICE_TYPE(GIO64_XL8, gio64_xl8_device, "gio64_xl8", "SGI 8-bit XL board")
@@ -350,7 +339,7 @@ uint32_t newport_base_device::screen_update(screen_device &device, bitmap_rgb32
//uint32_t *src = &m_vt_table[y * 2048];
uint32_t *src_ci = &m_rgbci[1344 * y];
uint32_t *src_pup = &m_pup[1344 * y];
- uint32_t *src_olay = &m_pup[1344 * y];
+ uint32_t *src_olay = &m_olay[1344 * y];
m_vc2.m_did_frame_ptr = m_vc2.m_did_entry + (uint16_t)y;
m_vc2.m_did_line_ptr = m_vc2.m_ram[m_vc2.m_did_frame_ptr];
@@ -469,7 +458,7 @@ uint32_t newport_base_device::screen_update(screen_device &device, bitmap_rgb32
break;
case 2: // 8-Bit Overlay
{
- const uint32_t pix_in = (*src_olay >> 8) & 0xff;
+ const uint32_t pix_in = ((*src_olay >> 8) & 0xf) | ((*src_olay >> 12) & 0xf0);
if (pix_in)
{
*dest++ = m_cmap0.m_palette[aux_msb | pix_in];
@@ -749,6 +738,7 @@ void newport_base_device::ramdac_write(uint32_t data)
switch (m_rex3.m_dcb_reg_select)
{
case 0:
+ LOGMASKED(LOG_RAMDAC, "RAMDAC LUT index write: %08x\n", data);
m_ramdac_lut_index = (uint8_t)data;
break;
case 1:
@@ -756,6 +746,10 @@ void newport_base_device::ramdac_write(uint32_t data)
m_ramdac_lut_g[m_ramdac_lut_index] = (uint8_t)(data >> 16) << 8;
m_ramdac_lut_b[m_ramdac_lut_index] = (uint8_t)(data >> 24) << 0;
m_ramdac_lut_index++;
+ LOGMASKED(LOG_RAMDAC, "RAMDAC LUT entry write: %08x\n", data);
+ break;
+ default:
+ LOGMASKED(LOG_RAMDAC | LOG_UNKNOWN, "Unknown RAMDAC register %02x write: %08x\n", m_rex3.m_dcb_reg_select, data);
break;
}
}
@@ -799,6 +793,26 @@ uint32_t newport_base_device::cmap0_read()
}
}
+void newport_base_device::cmap1_write(uint32_t data)
+{
+ switch (m_rex3.m_dcb_reg_select)
+ {
+ case 0x00:
+ LOGMASKED(LOG_CMAP1, "CMAP1 Palette Index Write: %04x\n", data & 0xffff);
+ m_cmap1.m_palette_idx = (uint16_t)data;
+ break;
+ case 0x02:
+ m_cmap1.m_palette[m_cmap1.m_palette_idx] = data >> 8;
+ //if (m_cmap1.m_palette_idx < 0x2000)
+ //set_pen_color(m_cmap1.m_palette_idx, rgb_t((uint8_t)(data >> 24), (uint8_t)(data >> 16), (uint8_t)(data >> 8)));
+ LOGMASKED(LOG_CMAP1, "CMAP1 Palette Entry %04x Write: %08x\n", m_cmap0.m_palette_idx, data >> 8);
+ break;
+ default:
+ LOGMASKED(LOG_CMAP1 | LOG_UNKNOWN, "Unknown CMAP1 Register %d Write: %08x\n", m_rex3.m_dcb_reg_select, data);
+ break;
+ }
+}
+
uint32_t newport_base_device::cmap1_read()
{
switch (m_rex3.m_dcb_reg_select)
@@ -1827,10 +1841,15 @@ READ64_MEMBER(newport_base_device::rex3_r)
return ret;
}
+uint32_t newport_base_device::do_endian_swap(uint32_t color)
+{
+ return (color >> 24) | (color << 24) | ((color >> 8) & 0x0000ff00) | ((color << 8) & 0x00ff0000);
+}
+
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];
+ static const uint32_t s_color_masks[4] = { 0xf, 0xff, 0xfff, 0xffffffff };
+ 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)
@@ -1843,33 +1862,47 @@ uint32_t newport_base_device::get_host_color()
{
default:
// No conversion needed
- return color;
+ break;
case 1: // 4bpp -> 8bpp
- return convert_4bpp_bgr_to_8bpp((uint8_t)color);
+ color = convert_4bpp_bgr_to_8bpp((uint8_t)color);
+ break;
case 2: // 4bpp -> 12bpp
- return convert_4bpp_bgr_to_12bpp((uint8_t)color);
+ color = convert_4bpp_bgr_to_12bpp((uint8_t)color);
+ break;
case 3: // 4bpp -> 24bpp
- return convert_4bpp_bgr_to_24bpp((uint8_t)color);
+ color = convert_4bpp_bgr_to_24bpp((uint8_t)color);
+ break;
case 4: // 8bpp -> 4bpp
- return convert_8bpp_bgr_to_4bpp((uint8_t)color);
+ color = convert_8bpp_bgr_to_4bpp((uint8_t)color);
+ break;
case 6: // 8bpp -> 12bpp
- return convert_8bpp_bgr_to_12bpp((uint8_t)color);
+ color = convert_8bpp_bgr_to_12bpp((uint8_t)color);
+ break;
case 7: // 8bpp -> 24bpp
- return convert_8bpp_bgr_to_24bpp((uint8_t)color);
+ color = convert_8bpp_bgr_to_24bpp((uint8_t)color);
+ break;
case 8: // 12bpp -> 4bpp
- return convert_12bpp_bgr_to_4bpp((uint16_t)color);
+ color = convert_12bpp_bgr_to_4bpp((uint16_t)color);
+ break;
case 9: // 12bpp -> 8bpp
- return convert_12bpp_bgr_to_8bpp((uint16_t)color);
+ color = convert_12bpp_bgr_to_8bpp((uint16_t)color);
+ break;
case 11: // 12bpp -> 24bpp
- return convert_12bpp_bgr_to_24bpp((uint16_t)color);
+ color = convert_12bpp_bgr_to_24bpp((uint16_t)color);
+ break;
case 12: // 32bpp -> 4bpp
- return convert_24bpp_bgr_to_4bpp(color);
+ color = convert_24bpp_bgr_to_4bpp(color);
+ break;
case 13: // 32bpp -> 8bpp
- return convert_24bpp_bgr_to_8bpp(color);
+ color = convert_24bpp_bgr_to_8bpp(color);
+ break;
case 14: // 32bpp -> 12bpp
- return convert_24bpp_bgr_to_12bpp(color);
+ color = convert_24bpp_bgr_to_12bpp(color);
+ break;
}
- return color;
+ if (BIT(m_rex3.m_draw_mode1, 11))
+ color = do_endian_swap(color);
+ return color;
}
void newport_base_device::write_pixel(uint32_t color)
@@ -3486,7 +3519,49 @@ WRITE64_MEMBER(newport_base_device::rex3_w)
}
m_rex3.m_draw_mode1 = data32;
- static const uint32_t s_store_shift[4] = { 4, 0, 12, 0 };
+ static const uint32_t s_store_shift[8][4][2] = {
+ { { 0, 0 }, // None, 4bpp, Buffer 0/1
+ { 0, 0 }, // None, 8bpp, Buffer 0/1
+ { 0, 0 }, // None, 12bpp, Buffer 0/1
+ { 0, 0 }, // None, 24bpp, Buffer 0/1 (not valid)
+ },
+ { { 0, 0 }, // RGB/CI, 4bpp, Buffer 0/1
+ { 0, 8 }, // RGB/CI, 8bpp, Buffer 0/1
+ { 0, 12 }, // RGB/CI, 12bpp, Buffer 0/1
+ { 0, 0 }, // RGB/CI, 24bpp, Buffer 0/1 (not valid)
+ },
+ { { 0, 0 }, // RGBA, 4bpp, Buffer 0/1
+ { 0, 8 }, // RGBA, 8bpp, Buffer 0/1
+ { 0, 12 }, // RGBA, 12bpp, Buffer 0/1
+ { 0, 0 }, // RGBA, 24bpp, Buffer 0/1 (not valid)
+ },
+ { { 0, 0 }, // Invalid, 4bpp, Buffer 0/1
+ { 0, 0 }, // Invalid, 8bpp, Buffer 0/1
+ { 0, 0 }, // Invalid, 12bpp, Buffer 0/1
+ { 0, 0 }, // Invalid, 24bpp, Buffer 0/1 (not valid)
+ },
+ { { 0, 8 }, // Overlay, 4bpp, Buffer 0/1
+ { 0, 8 }, // Overlay, 8bpp, Buffer 0/1
+ { 0, 8 }, // Overlay, 12bpp, Buffer 0/1
+ { 0, 8 }, // Overlay, 24bpp, Buffer 0/1 (not valid)
+ },
+ { { 0, 0 }, // Popup, 4bpp, Buffer 0/1
+ { 0, 8 }, // Popup, 8bpp, Buffer 0/1
+ { 0, 12 }, // Popup, 12bpp, Buffer 0/1
+ { 0, 0 }, // Popup, 24bpp, Buffer 0/1 (not valid)
+ },
+ { { 0, 0 }, // CID, 4bpp, Buffer 0/1
+ { 0, 8 }, // CID, 8bpp, Buffer 0/1
+ { 0, 12 }, // CID, 12bpp, Buffer 0/1
+ { 0, 0 }, // CID, 24bpp, Buffer 0/1 (not valid)
+ },
+ { { 0, 0 }, // Invalid, 4bpp, Buffer 0/1
+ { 0, 0 }, // Invalid, 8bpp, Buffer 0/1
+ { 0, 0 }, // Invalid, 12bpp, Buffer 0/1
+ { 0, 0 }, // Invalid, 24bpp, Buffer 0/1 (not valid)
+ },
+ };
+
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);
@@ -3496,8 +3571,7 @@ WRITE64_MEMBER(newport_base_device::rex3_w)
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_store_shift = s_store_shift[m_rex3.m_plane_enable][m_rex3.m_plane_depth][BIT(m_rex3.m_draw_mode1, 5)];
m_rex3.m_host_shift = 64 - s_host_shifts[m_rex3.m_hostdepth];
}
if (ACCESSING_BITS_0_31)
@@ -3804,11 +3878,25 @@ WRITE64_MEMBER(newport_base_device::rex3_w)
{
LOGMASKED(LOG_REX3, "REX3 Red/CI Full State Write: %08x\n", (uint32_t)(data >> 32));
m_rex3.m_color_red = (int32_t)((data >> 32) & 0xffffff);
- if (m_rex3.m_plane_depth == 2 && !BIT(m_rex3.m_draw_mode1, 15))
+ m_rex3.m_curr_color_red = m_rex3.m_color_red;
+ if (!BIT(m_rex3.m_draw_mode1, 15))
{
- m_rex3.m_color_i = m_rex3.m_color_red >> 9;
+ switch (m_rex3.m_plane_depth)
+ {
+ case 0: // 4bpp
+ m_rex3.m_color_i = (uint32_t)((data >> 43) & 0xf);
+ break;
+ case 1: // 8bpp
+ m_rex3.m_color_i = (uint32_t)((data >> 43) & 0xff);
+ break;
+ case 2: // 12bpp
+ m_rex3.m_color_i = (uint32_t)((data >> 41) & 0xfff);
+ break;
+ case 3: // 32bpp
+ // Invalid for CI mode
+ break;
+ }
}
- m_rex3.m_curr_color_red = m_rex3.m_color_red;
}
if (ACCESSING_BITS_0_31)
{
@@ -3914,8 +4002,18 @@ WRITE64_MEMBER(newport_base_device::rex3_w)
}
if (ACCESSING_BITS_0_31)
{
- LOGMASKED(LOG_REX3, "REX3 Packed Color Fractions Write: %08x\n", (uint32_t)data);
+ LOGMASKED(LOG_REX3, "REX3 Packed Color Write: %08x\n", (uint32_t)data);
m_rex3.m_color_i = (uint32_t)data;
+ if (BIT(m_rex3.m_draw_mode1, 15))
+ {
+ m_rex3.m_color_red = (data & 0xff) << 11;
+ m_rex3.m_color_green = (data & 0xff00) << 3;
+ m_rex3.m_color_blue = (data & 0xff0000) >> 5;
+
+ m_rex3.m_curr_color_red = m_rex3.m_color_red;
+ m_rex3.m_curr_color_green = m_rex3.m_color_green;
+ m_rex3.m_curr_color_blue = m_rex3.m_color_blue;
+ }
}
break;
case 0x0228/8:
@@ -3986,13 +4084,13 @@ WRITE64_MEMBER(newport_base_device::rex3_w)
break;
case DCB_ADDR_CMAP01:
cmap0_write(data32);
- //cmap1_write(data32);
+ cmap1_write(data32);
break;
case DCB_ADDR_CMAP0:
cmap0_write(data32);
break;
case DCB_ADDR_CMAP1:
- //cmap1_write(data32);
+ cmap1_write(data32);
break;
case DCB_ADDR_XMAP01:
xmap0_write(data32);
diff --git a/src/devices/bus/gio64/newport.h b/src/devices/bus/gio64/newport.h
index 3971411d13c..f48245df79f 100644
--- a/src/devices/bus/gio64/newport.h
+++ b/src/devices/bus/gio64/newport.h
@@ -226,6 +226,7 @@ protected:
uint32_t cmap0_read();
void cmap0_write(uint32_t data);
uint32_t cmap1_read();
+ void cmap1_write(uint32_t data);
uint32_t xmap0_read();
void xmap0_write(uint32_t data);
uint32_t xmap1_read();
@@ -271,6 +272,8 @@ protected:
uint32_t convert_8bpp_bgr_to_24bpp_rgb(uint8_t pix_in);
uint32_t convert_12bpp_bgr_to_24bpp_rgb(uint16_t pix_in);
+ uint32_t do_endian_swap(uint32_t color);
+
struct bresenham_octant_info_t
{
int16_t incrx1;
@@ -311,6 +314,7 @@ protected:
std::unique_ptr<uint32_t[]> m_cid;
std::unique_ptr<uint32_t[]> m_vt_table;
cmap_t m_cmap0;
+ cmap_t m_cmap1;
uint32_t m_global_mask;
emu_timer *m_dcb_timeout_timer;