summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/bus/gio64/newport.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/bus/gio64/newport.cpp')
-rw-r--r--src/devices/bus/gio64/newport.cpp1587
1 files changed, 799 insertions, 788 deletions
diff --git a/src/devices/bus/gio64/newport.cpp b/src/devices/bus/gio64/newport.cpp
index d1099c94647..dbd7b67026b 100644
--- a/src/devices/bus/gio64/newport.cpp
+++ b/src/devices/bus/gio64/newport.cpp
@@ -1,47 +1,742 @@
// license:BSD-3-Clause
// copyright-holders:Ryan Holtz
-/*
- SGI "Newport" graphics board used in the Indy and some Indigo2s
+/*********************************************************************
+
+ newport.cpp
+
+ SGI "Newport" graphics board emulation
Newport is modular, consisting of the following custom chips:
- - REX3: Raster Engine, which is basically a blitter which can also draw antialiased lines.
- REX also acts as the interface to the rest of the system - all the other chips on
- a Newport board are accessed through it.
+ - REX3: Raster Engine, essentially a blitter which can also draw
+ antialiased lines. REX also acts as the interface to the
+ rest of the system - all the other chips on a Newport
+ board are accessed through it.
- RB2: Frame buffer input controller
- RO1: Frame buffer output controller
- XMAP9: Final display generator
- CMAP: Palette mapper
- VC2: Video timing controller / CRTC
-*/
+
+ Newport-derived graphics boards were shipped for the Indy
+ workstation and some Indigo 2 workstations.
+
+ Known Issues:
+ - Antialiased line drawing currently uses the fractional line
+ drawing routine instead.
+ - Timing-wise, all draw commands complete instantly and all
+ FIFOs are always empty. Thus the performance of an emulated
+ Newport board is likely to be better than real life in scenes
+ that would otherwise be drawing-bound.
+
+*********************************************************************/
#include "emu.h"
#include "newport.h"
#define LOG_UNKNOWN (1 << 0)
#define LOG_VC2 (1 << 1)
-#define LOG_CMAP0 (1 << 2)
-#define LOG_CMAP1 (1 << 3)
-#define LOG_XMAP0 (1 << 4)
-#define LOG_XMAP1 (1 << 5)
+#define LOG_CMAP (1 << 2)
+#define LOG_XMAP (1 << 4)
#define LOG_REX3 (1 << 6)
#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 LOG_ALL (LOG_UNKNOWN | LOG_VC2 | LOG_CMAP | LOG_XMAP | LOG_REX3 | LOG_RAMDAC | LOG_COMMANDS | LOG_REJECTS)
-#define VERBOSE (0)//(LOG_REX3 | LOG_CMAP0 | LOG_CMAP1 | LOG_XMAP0 | LOG_XMAP1)
+#define VERBOSE (0)//(LOG_REX3 | LOG_CMAP | LOG_XMAP)
#include "logmacro.h"
+DEFINE_DEVICE_TYPE(XMAP9, xmap9_device, "xmap9", "SGI XMAP9")
+DEFINE_DEVICE_TYPE(CMAP, cmap_device, "cmap", "SGI CMAP")
+DEFINE_DEVICE_TYPE(VC2, vc2_device, "vc2", "SGI VC2")
DEFINE_DEVICE_TYPE(GIO64_XL8, gio64_xl8_device, "gio64_xl8", "SGI 8-bit XL board")
DEFINE_DEVICE_TYPE(GIO64_XL24, gio64_xl24_device, "gio64_xl24", "SGI 24-bit XL board")
+/*************************************
+ *
+ * XMAP9 Device
+ *
+ *************************************/
+
+xmap9_device::xmap9_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : device_t(mconfig, XMAP9, tag, owner, clock)
+{
+}
+
+void xmap9_device::device_start()
+{
+ save_item(NAME(m_config));
+ save_item(NAME(m_revision));
+ save_item(NAME(m_fifo_available));
+ save_item(NAME(m_cursor_cmap));
+ save_item(NAME(m_popup_cmap));
+ save_item(NAME(m_mode_table_idx));
+ save_item(NAME(m_mode_table));
+}
+
+void xmap9_device::device_reset()
+{
+ m_config = 0;
+ m_fifo_available = 0x2;
+ m_cursor_cmap = 0;
+ m_popup_cmap = 0;
+ m_mode_table_idx = 0;
+ memset(m_mode_table, 0, sizeof(uint32_t) * ARRAY_LENGTH(m_mode_table));
+}
+
+uint32_t xmap9_device::read(uint32_t offset)
+{
+ switch (offset)
+ {
+ case 0:
+ LOGMASKED(LOG_XMAP, "Config Read: %08x\n", m_config);
+ return m_config;
+ case 1:
+ LOGMASKED(LOG_XMAP, "Revision Read: %08x\n", m_revision);
+ return m_revision;
+ case 2:
+ LOGMASKED(LOG_XMAP, "FIFO Availability Read: %08x\n", m_fifo_available);
+ return m_fifo_available;
+ case 3:
+ LOGMASKED(LOG_XMAP, "Cursor CMAP MSB Read: %08x\n", m_cursor_cmap);
+ return m_cursor_cmap;
+ case 4:
+ LOGMASKED(LOG_XMAP, "Pop Up CMAP MSB Read: %08x\n", m_popup_cmap);
+ return m_popup_cmap;
+ case 5:
+ {
+ const uint8_t mode_idx = (m_mode_table_idx & 0x7c) >> 2;
+ switch (m_mode_table_idx & 3)
+ {
+ case 0:
+ {
+ const uint8_t ret = (uint8_t)(m_mode_table[mode_idx] >> 16);
+ LOGMASKED(LOG_XMAP, "Mode Register Read: %02x (Byte 0): %08x\n", mode_idx, ret);
+ return ret;
+ }
+ case 1:
+ {
+ const uint8_t ret = (uint8_t)(m_mode_table[mode_idx] >> 8);
+ LOGMASKED(LOG_XMAP, "Mode Register Read: %02x (Byte 1): %08x\n", mode_idx, ret);
+ return ret;
+ }
+ case 2:
+ {
+ const uint8_t ret = (uint8_t)m_mode_table[mode_idx];
+ LOGMASKED(LOG_XMAP, "Mode Register Read: %02x (Byte 2): %08x\n", mode_idx, ret);
+ return ret;
+ }
+ }
+ break;
+ }
+ case 6:
+ LOGMASKED(LOG_XMAP, "Unused Read: %08x\n", 0);
+ return 0;
+ case 7:
+ LOGMASKED(LOG_XMAP, "Mode Table Address Read: %08x\n", m_mode_table_idx);
+ return m_mode_table_idx;
+ default:
+ LOGMASKED(LOG_XMAP | LOG_UNKNOWN, "Unknown DCB Register Select Value: %02x, returning 0\n", offset);
+ return 0;
+ }
+ return 0;
+}
+
+void xmap9_device::write(uint32_t offset, uint32_t data)
+{
+ switch (offset)
+ {
+ case 0:
+ LOGMASKED(LOG_XMAP, "Config Write: %02x\n", (uint8_t)data);
+ m_config = (uint8_t)data;
+ break;
+ case 1:
+ LOGMASKED(LOG_XMAP, "Revision Write (Ignored): %02x\n", (uint8_t)data);
+ break;
+ case 2:
+ LOGMASKED(LOG_XMAP, "FIFO Availability Write (Ignored): %02x\n", (uint8_t)data);
+ break;
+ case 3:
+ LOGMASKED(LOG_XMAP, "Cursor CMAP MSB Write: %02x\n", (uint8_t)data);
+ m_cursor_cmap = (uint8_t)data;
+ break;
+ case 4:
+ LOGMASKED(LOG_XMAP, "Pop Up CMAP MSB Write: %02x\n", (uint8_t)data);
+ m_popup_cmap = (uint8_t)data;
+ break;
+ case 5:
+ LOGMASKED(LOG_XMAP, "Mode Register Write: %02x = %06x\n", data >> 24, data & 0xffffff);
+ m_mode_table[data >> 24] = data & 0xffffff;
+ break;
+ case 6:
+ LOGMASKED(LOG_XMAP, "Unused Write (Ignored): %08x\n", data);
+ break;
+ case 7:
+ LOGMASKED(LOG_XMAP, "Mode Table Address Write: %02x\n", (uint8_t)data);
+ m_mode_table_idx = (uint8_t)data;
+ break;
+ default:
+ LOGMASKED(LOG_XMAP | LOG_UNKNOWN, "Unknown DCB Register Select Value: %02x = %08x\n", offset, data);
+ break;
+ }
+}
+
+
+/*************************************
+ *
+ * CMAP Device
+ *
+ *************************************/
+
+cmap_device::cmap_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : device_t(mconfig, CMAP, tag, owner, clock)
+ , device_palette_interface(mconfig, *this)
+{
+}
+
+void cmap_device::device_start()
+{
+ save_item(NAME(m_status));
+ save_item(NAME(m_revision));
+ save_item(NAME(m_palette_idx));
+ save_item(NAME(m_palette));
+}
+
+void cmap_device::device_reset()
+{
+ m_status = 8;
+ m_palette_idx = 0;
+ memset(m_palette, 0, sizeof(uint32_t) * ARRAY_LENGTH(m_palette));
+}
+
+void cmap_device::write(uint32_t offset, uint32_t data)
+{
+ switch (offset)
+ {
+ case 0x00:
+ LOGMASKED(LOG_CMAP, "Palette Index Write: %04x\n", data & 0xffff);
+ m_palette_idx = (uint16_t)data;
+ break;
+ case 0x02:
+ m_palette[m_palette_idx] = data >> 8;
+ if (m_palette_idx < 0x2000)
+ set_pen_color(m_palette_idx, rgb_t((uint8_t)(data >> 24), (uint8_t)(data >> 16), (uint8_t)(data >> 8)));
+ LOGMASKED(LOG_CMAP, "Palette Entry %04x Write: %08x\n", m_palette_idx, data >> 8);
+ break;
+ default:
+ LOGMASKED(LOG_CMAP | LOG_UNKNOWN, "Unknown Register %d Write: %08x\n", offset, data);
+ break;
+ }
+}
+
+uint32_t cmap_device::read(uint32_t offset)
+{
+ switch (offset)
+ {
+ case 0x04:
+ LOGMASKED(LOG_CMAP, "Status Read: %08x\n", m_status);
+ return m_status;
+ case 0x06:
+ LOGMASKED(LOG_CMAP, "Revision Read: %08x\n", m_revision);
+ return m_revision;
+ default:
+ LOGMASKED(LOG_CMAP | LOG_UNKNOWN, "Unknown Register %d Read\n", offset);
+ return 0;
+ }
+}
+
+
+/*************************************
+ *
+ * VC2 Device
+ *
+ *************************************/
+
+/*static*/ const size_t vc2_device::RAM_SIZE = 0x8000;
+
+vc2_device::vc2_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : device_t(mconfig, VC2, tag, owner, clock)
+ , m_vert_int(*this)
+ , m_screen_timing_changed(*this)
+{
+}
+
+void vc2_device::device_start()
+{
+ m_vert_int.resolve_safe();
+
+ m_ram = std::make_unique<uint16_t[]>(RAM_SIZE);
+ m_vt_table = make_unique_clear<uint32_t[]>(2048 * 2048);
+
+ save_item(NAME(m_vid_entry));
+ save_item(NAME(m_cursor_entry));
+ save_item(NAME(m_cursor_x));
+ save_item(NAME(m_cursor_y));
+ save_item(NAME(m_cur_cursor_x));
+ save_item(NAME(m_did_entry));
+ save_item(NAME(m_scanline_len));
+ save_item(NAME(m_ram_addr));
+ save_item(NAME(m_vt_frame_ptr));
+ save_item(NAME(m_vt_line_ptr));
+ save_item(NAME(m_vt_line_run));
+ save_item(NAME(m_vt_line_count));
+ save_item(NAME(m_cursor_table_ptr));
+ save_item(NAME(m_work_cursor_y));
+ save_item(NAME(m_did_frame_ptr));
+ save_item(NAME(m_did_line_ptr));
+ save_item(NAME(m_display_ctrl));
+ save_item(NAME(m_config));
+ save_item(NAME(m_reg_idx));
+ save_item(NAME(m_reg_data));
+ save_pointer(NAME(&m_ram[0]), RAM_SIZE);
+
+ save_pointer(NAME(&m_vt_table[0]), 2048 * 2048);
+
+ save_item(NAME(m_readout_x0));
+ save_item(NAME(m_readout_y0));
+ save_item(NAME(m_readout_x1));
+ save_item(NAME(m_readout_y1));
+
+ save_item(NAME(m_enable_cursor));
+}
+
+void vc2_device::device_reset()
+{
+ m_vid_entry = 0;
+ m_cursor_entry = 0;
+ m_cursor_x = 0;
+ m_cursor_y = 0;
+ m_cur_cursor_x = 0;
+ m_did_entry = 0;
+ m_scanline_len = 0;
+ m_ram_addr = 0;
+ m_vt_frame_ptr = 0;
+ m_vt_line_ptr = 0;
+ m_vt_line_run = 0;
+ m_vt_line_count = 0;
+ m_cursor_table_ptr = 0;
+ m_work_cursor_y = 0;
+ m_did_frame_ptr = 0;
+ m_did_line_ptr = 0;
+ m_display_ctrl = 0;
+ m_config = 0;
+ m_reg_idx = 0;
+ m_reg_data = 0;
+ memset(&m_ram[0], 0, sizeof(uint16_t) * RAM_SIZE);
+
+ memset(&m_vt_table[0], 0, sizeof(uint32_t) * 2048 * 2048);
+
+ m_readout_x0 = 0;
+ m_readout_y0 = 0;
+ m_readout_x1 = 0;
+ m_readout_y1 = 0;
+
+ m_enable_cursor = false;
+}
+
+void vc2_device::write(uint32_t offset, uint32_t data, uint32_t mem_mask)
+{
+ if (mem_mask == 0x000000ff)
+ {
+ // Register Select
+ if (offset == 0)
+ {
+ m_reg_idx = (uint8_t)data;
+ LOGMASKED(LOG_VC2, "Register Select: %02x\n", m_reg_idx);
+ }
+ else
+ {
+ LOGMASKED(LOG_VC2 | LOG_UNKNOWN, "Unknown Register Select: Register %02x, data = %08x\n", offset, data);
+ }
+ }
+ else if (mem_mask == 0x0000ffff)
+ {
+ // RAM Word
+ if (offset == 3)
+ {
+ LOGMASKED(LOG_VC2, "RAM Write: %04x = %08x\n", m_ram_addr, (uint16_t)data);
+ m_ram[m_ram_addr] = (uint16_t)data;
+ m_ram_addr++;
+ if (m_ram_addr >= RAM_SIZE)
+ {
+ m_ram_addr = 0;
+ }
+ }
+ else
+ {
+ LOGMASKED(LOG_VC2 | LOG_UNKNOWN, "Unknown Word Write: Register %02x, data = %08x\n", offset, data);
+ }
+ }
+ else if (mem_mask == 0xffffffff)
+ {
+ // Register Write
+ if (offset == 0)
+ {
+ LOGMASKED(LOG_VC2, "Register Setup:\n");
+ m_reg_idx = data >> 24;
+ m_reg_data = (uint16_t)(data >> 8);
+ switch (m_reg_idx)
+ {
+ case 0x00:
+ m_vid_entry = m_reg_data;
+ LOGMASKED(LOG_VC2, "Register Write: Video Entry Pointer, %04x\n", m_vid_entry);
+ update_screen_size();
+ break;
+ case 0x01:
+ m_cursor_entry = m_reg_data;
+ LOGMASKED(LOG_VC2, "Register Write: Cursor Entry Pointer, %04x\n", m_cursor_entry);
+ break;
+ case 0x02:
+ m_cursor_x = m_reg_data;
+ LOGMASKED(LOG_VC2, "Register Write: Cursor X, %04x\n", m_cursor_x);
+ break;
+ case 0x03:
+ m_cursor_y = m_reg_data;
+ LOGMASKED(LOG_VC2, "Register Write: Cursor Y, %04x\n", m_cursor_y);
+ m_cur_cursor_x = m_cursor_x;
+ break;
+ case 0x04:
+ m_cur_cursor_x = m_reg_data;
+ LOGMASKED(LOG_VC2, "Register Write: Current Cursor X, %04x\n", m_cur_cursor_x);
+ break;
+ case 0x05:
+ m_did_entry = m_reg_data;
+ LOGMASKED(LOG_VC2, "Register Write: DID Entry Pointer, %04x\n", m_did_entry);
+ break;
+ case 0x06:
+ m_scanline_len = m_reg_data;
+ LOGMASKED(LOG_VC2, "Register Write: Scanline Length, %04x\n", m_scanline_len);
+ break;
+ case 0x07:
+ m_ram_addr = m_reg_data;
+ LOGMASKED(LOG_VC2, "Register Write: RAM Address, %04x\n", m_ram_addr);
+ break;
+ case 0x08:
+ m_vt_frame_ptr = m_reg_data;
+ LOGMASKED(LOG_VC2, "Register Write: VT Frame Table Ptr, %04x\n", m_vt_frame_ptr);
+ break;
+ case 0x09:
+ m_vt_line_ptr = m_reg_data;
+ LOGMASKED(LOG_VC2, "Register Write: VT Line Sequence Pointer, %04x\n", m_vt_line_ptr);
+ break;
+ case 0x0a:
+ m_vt_line_run = m_reg_data;
+ LOGMASKED(LOG_VC2, "Register Write: VT Lines in Run, %04x\n", m_vt_line_run);
+ break;
+ case 0x0b:
+ m_vt_line_count = m_reg_data;
+ LOGMASKED(LOG_VC2, "Register Write: Vertical Line Count, %04x\n", m_vt_line_count);
+ break;
+ case 0x0c:
+ m_cursor_table_ptr = m_reg_data;
+ LOGMASKED(LOG_VC2, "Register Write: Cursor Table Pointer, %04x\n", m_cursor_table_ptr);
+ break;
+ case 0x0d:
+ m_work_cursor_y = m_reg_data;
+ LOGMASKED(LOG_VC2, "Register Write: Working Cursor Y, %04x\n", m_work_cursor_y);
+ break;
+ case 0x0e:
+ m_did_frame_ptr = m_reg_data;
+ LOGMASKED(LOG_VC2, "Register Write: DID Frame Table Pointer, %04x\n", m_did_frame_ptr);
+ break;
+ case 0x0f:
+ m_did_line_ptr = m_reg_data;
+ LOGMASKED(LOG_VC2, "Register Write: DID Line Table Pointer, %04x\n", m_did_line_ptr);
+ break;
+ case 0x10:
+ m_display_ctrl = m_reg_data;
+ LOGMASKED(LOG_VC2, "Register Write: Display Control, %04x\n", m_display_ctrl);
+ m_enable_cursor = BIT(m_display_ctrl, CURSOR_FUNC_ENABLE_BIT) != 0
+ && BIT(m_display_ctrl, CURSOR_ENABLE_BIT) != 0
+ && BIT(m_display_ctrl, CURSOR_MODE_BIT) == CURSOR_MODE_GLYPH;
+ break;
+ case 0x1f:
+ m_config = m_reg_data;
+ LOGMASKED(LOG_VC2, "Register Write: Configuration, %04x\n", m_config);
+ break;
+ default:
+ LOGMASKED(LOG_VC2 | LOG_UNKNOWN, "Register Write: Unknown Register: %02x = %04x\n", m_reg_idx, m_reg_data);
+ break;
+ }
+ }
+ else
+ {
+ LOGMASKED(LOG_VC2 | LOG_UNKNOWN, "Unknown Register Write: %02x = %08x\n", offset, data);
+ }
+ }
+ else
+ {
+ LOGMASKED(LOG_VC2 | LOG_UNKNOWN, "Unknown Memory Mask: %08x, Offset %02x, Value %08x\n", mem_mask, offset, data);
+ }
+}
+
+uint32_t vc2_device::read(uint32_t offset)
+{
+ switch (offset)
+ {
+ case 0x01: /* Register Read */
+ switch (m_reg_idx)
+ {
+ case 0x00:
+ LOGMASKED(LOG_VC2, "Register Read: Video Entry Pointer, %08x\n", m_vid_entry);
+ return m_vid_entry;
+ case 0x01:
+ LOGMASKED(LOG_VC2, "Register Read: Cursor Entry Pointer, %08x\n", m_cursor_entry);
+ return m_cursor_entry;
+ case 0x02:
+ LOGMASKED(LOG_VC2, "Register Read: Cursor X, %08x\n", m_cursor_x);
+ return m_cursor_x;
+ case 0x03:
+ LOGMASKED(LOG_VC2, "Register Read: Cursor Y, %08x\n", m_cursor_y);
+ return m_cursor_y;
+ case 0x04:
+ LOGMASKED(LOG_VC2, "Register Read: Current Cursor X, %08x\n", m_cur_cursor_x);
+ return m_cur_cursor_x;
+ case 0x05:
+ LOGMASKED(LOG_VC2, "Register Read: DID Entry, %08x\n", m_did_entry);
+ return m_did_entry;
+ case 0x06:
+ LOGMASKED(LOG_VC2, "Register Read: Scanline Length, %08x\n", m_scanline_len);
+ return m_scanline_len;
+ case 0x07:
+ LOGMASKED(LOG_VC2, "Register Read: RAM Address, %08x\n", m_ram_addr);
+ return m_ram_addr;
+ case 0x08:
+ LOGMASKED(LOG_VC2, "Register Read: VT Frame Pointer, %08x\n", m_vt_frame_ptr);
+ return m_vt_frame_ptr;
+ case 0x09:
+ LOGMASKED(LOG_VC2, "Register Read: VT Line Sequence Pointer, %08x\n", m_vt_line_ptr);
+ return m_vt_line_ptr;
+ case 0x0a:
+ LOGMASKED(LOG_VC2, "Register Read: VT Lines in Run, %08x\n", m_vt_line_run);
+ return m_vt_line_run;
+ case 0x0b:
+ LOGMASKED(LOG_VC2, "Register Read: Vertical Line Count, %08x\n", m_vt_line_count);
+ return m_vt_line_count;
+ case 0x0c:
+ LOGMASKED(LOG_VC2, "Register Read: Cursor Table Pointer, %08x\n", m_cursor_table_ptr);
+ return m_cursor_table_ptr;
+ case 0x0d:
+ LOGMASKED(LOG_VC2, "Register Read: Working Cursor Y, %08x\n", m_work_cursor_y);
+ return m_work_cursor_y;
+ case 0x0e:
+ LOGMASKED(LOG_VC2, "Register Read: DID Frame Pointer, %08x\n", m_did_frame_ptr);
+ return m_did_frame_ptr;
+ case 0x0f:
+ LOGMASKED(LOG_VC2, "Register Read: DID Line Pointer, %08x\n", m_did_line_ptr);
+ return m_did_line_ptr;
+ case 0x10:
+ LOGMASKED(LOG_VC2, "Register Read: Display Control, %08x\n", m_display_ctrl);
+ return m_display_ctrl;
+ case 0x1f:
+ LOGMASKED(LOG_VC2, "Register Read: Configuration, %08x\n", m_config);
+ return m_config;
+ default:
+ return 0;
+ }
+ break;
+ case 0x03: /* RAM Read */
+ {
+ LOGMASKED(LOG_VC2, "RAM Read: %04x = %08x\n", m_ram_addr, m_ram[m_ram_addr]);
+ uint16_t ret = m_ram[m_ram_addr];
+ m_ram_addr++;
+ if (m_ram_addr >= RAM_SIZE)
+ {
+ m_ram_addr = 0;
+ }
+ return ret;
+ }
+ default:
+ LOGMASKED(LOG_VC2 | LOG_UNKNOWN, "Unknown Register Read: %02x\n", offset);
+ return 0;
+ }
+}
+
+uint16_t vc2_device::begin_did_line(int y)
+{
+ m_did_frame_ptr = m_did_entry + (uint16_t)y;
+ m_did_line_ptr = m_ram[m_did_frame_ptr];
+ return m_ram[m_did_line_ptr];
+}
+
+uint16_t vc2_device::next_did_line_entry()
+{
+ m_did_line_ptr++;
+ return m_ram[m_did_line_ptr];
+}
+
+void vc2_device::decode_vt_line(uint32_t line, uint32_t line_seq_ptr)
+{
+ bool eol_sa = false;
+ bool eol_sb = false;
+ uint32_t vt_entry = 0;
+ uint32_t i = 0;
+ do
+ {
+ vt_entry &= ~(0x7f << 14);
+ vt_entry |= (m_ram[line_seq_ptr] & 0x7f) << 14;
+ eol_sa = BIT(m_ram[line_seq_ptr], 15);
+ if (!BIT(m_ram[line_seq_ptr], 7))
+ {
+ eol_sb = BIT(m_ram[line_seq_ptr + 1], 15);
+ vt_entry &= (0x7f << 14);
+ vt_entry |= (m_ram[line_seq_ptr + 1] & 0x7f00) >> 1;
+ vt_entry |= m_ram[line_seq_ptr + 1] & 0x7f;
+ line_seq_ptr += 2;
+ }
+ else
+ {
+ eol_sb = true;
+ line_seq_ptr++;
+ }
+ for (uint32_t j = 0; j < ((m_ram[line_seq_ptr] & 0x7f00) >> 7); i++, j++)
+ {
+ const uint8_t sa = ((vt_entry >> 14) & 0x7f) << 1;
+ const uint8_t sb = ((vt_entry >> 7) & 0x7f) << 1;
+ const uint8_t sc = ((vt_entry >> 0) & 0x7f) << 1;
+ m_vt_table[line * 2048 + i] = 0xff000000 | (sa << 16) | (sb << 8) | sc;
+ }
+ } while (!(eol_sa && eol_sb));
+}
+
+void vc2_device::decode_vt_table()
+{
+ memset(&m_vt_table[0], 0, sizeof(uint32_t) * 2048 * 2048);
+ uint32_t curr_vt_entry = m_vid_entry;
+ uint32_t line_counter = 0;
+ uint32_t line_seq_len = 0;
+ do
+ {
+ const uint32_t line_seq_ptr = m_ram[curr_vt_entry];
+ line_seq_len = m_ram[curr_vt_entry + 1];
+ if (line_seq_len)
+ {
+ for (uint32_t i = 0; i < line_seq_len; i++, line_counter++)
+ {
+ decode_vt_line(line_counter, line_seq_ptr);
+ }
+ }
+ curr_vt_entry += 2;
+ } while (line_seq_len != 0);
+}
+
+void vc2_device::update_screen_size()
+{
+ decode_vt_table();
+
+ bool x_started = false;
+ bool y_started = false;
+ bool x_done = false;
+ bool y_done = false;
+ bool done = false;
+ m_readout_x0 = 0;
+ m_readout_y0 = 0;
+ m_readout_x1 = 0;
+ m_readout_y1 = 0;
+
+ for (int y = 0; y < 2048 && !done; y++)
+ {
+ uint32_t *src = &m_vt_table[y * 2048];
+ for (int x = 0; x < 2048 && !done; x++)
+ {
+ if (BIT(*src, 7))
+ {
+ if (!x_started)
+ {
+ x_started = true;
+ m_readout_x0 = x;
+ }
+ if (!y_started)
+ {
+ y_started = true;
+ m_readout_y0 = y;
+ }
+ }
+ else
+ {
+ if (x_started && !x_done)
+ {
+ m_readout_x1 = x;
+ x_done = true;
+ }
+ if (y_started && !y_done && x == m_readout_x0)
+ {
+ m_readout_y1 = y;
+ y_done = true;
+ }
+ }
+ done = x_done && y_done;
+ src++;
+ }
+ }
+}
+
+bool vc2_device::is_cursor_active(int x, int y)
+{
+ return x >= (m_cursor_x - 31) && x <= m_cursor_x && y >= (m_cursor_y - 31) && y <= m_cursor_y && m_enable_cursor;
+}
+
+uint8_t vc2_device::get_cursor_pixel(int x, int y)
+{
+ if (!is_cursor_active(x, y))
+ return 0;
+
+ x -= (int)m_cursor_x - 31;
+ y -= (int)m_cursor_y - 31;
+
+ if (x < 0 || y < 0)
+ return 0;
+
+ bool monochrome_cursor = BIT(m_display_ctrl, CURSOR_SIZE_BIT) == CURSOR_SIZE_64;
+
+ int size = monochrome_cursor ? 64 : 32;
+ if (x >= size || y >= size)
+ return 0;
+
+ const int shift = 15 - (x % 16);
+
+ if (monochrome_cursor)
+ {
+ const int address = y * 4 + (x / 16);
+ const uint16_t word = m_ram[m_cursor_entry + address];
+ return BIT(word, shift);
+ }
+ else
+ {
+ const int address = y * 2 + (x / 16);
+ const uint16_t word0 = m_ram[m_cursor_entry + address];
+ const uint16_t word1 = m_ram[m_cursor_entry + address + 64];
+ return BIT(word0, shift) | (BIT(word1, shift) << 1);
+ }
+}
+
+WRITE_LINE_MEMBER(vc2_device::vblank_w)
+{
+ if (state)
+ {
+ if (BIT(m_display_ctrl, 0))
+ {
+ m_vert_int(1);
+ }
+ }
+}
+
+
+/*************************************
+ *
+ * Newport Device
+ *
+ *************************************/
+
/*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)
- , device_palette_interface(mconfig, *this)
, device_gio64_card_interface(mconfig, *this)
, m_screen(*this, "screen")
+ , m_xmap(*this, "xmap%u", 0U)
+ , m_cmap(*this, "cmap%u", 0U)
+ , m_vc2(*this, "vc2")
, m_global_mask(global_mask)
{
}
@@ -66,7 +761,6 @@ void newport_base_device::device_start()
m_olay = make_unique_clear<uint32_t[]>((1280+64) * (1024+64));
m_pup = make_unique_clear<uint32_t[]>((1280+64) * (1024+64));
m_cid = make_unique_clear<uint32_t[]>((1280+64) * (1024+64));
- m_vt_table = make_unique_clear<uint32_t[]>(2048 * 2048);
m_dcb_timeout_timer = timer_alloc(DCB_TIMEOUT);
@@ -74,42 +768,6 @@ void newport_base_device::device_start()
save_pointer(NAME(m_olay), (1280+64) * (1024+64));
save_pointer(NAME(m_pup), (1280+64) * (1024+64));
save_pointer(NAME(m_cid), (1280+64) * (1024+64));
- save_item(NAME(m_vc2.m_vid_entry));
- save_item(NAME(m_vc2.m_cursor_entry));
- save_item(NAME(m_vc2.m_cursor_x));
- save_item(NAME(m_vc2.m_cursor_y));
- save_item(NAME(m_vc2.m_cur_cursor_x));
- save_item(NAME(m_vc2.m_did_entry));
- save_item(NAME(m_vc2.m_scanline_len));
- save_item(NAME(m_vc2.m_ram_addr));
- save_item(NAME(m_vc2.m_vt_frame_ptr));
- save_item(NAME(m_vc2.m_vt_line_ptr));
- save_item(NAME(m_vc2.m_vt_line_run));
- save_item(NAME(m_vc2.m_vt_line_count));
- save_item(NAME(m_vc2.m_cursor_table_ptr));
- save_item(NAME(m_vc2.m_work_cursor_y));
- save_item(NAME(m_vc2.m_did_frame_ptr));
- save_item(NAME(m_vc2.m_did_line_ptr));
- save_item(NAME(m_vc2.m_display_ctrl));
- save_item(NAME(m_vc2.m_config));
- save_item(NAME(m_vc2.m_ram));
- save_item(NAME(m_vc2.m_reg_idx));
- save_item(NAME(m_vc2.m_reg_data));
-
- save_item(NAME(m_xmap0.m_config));
- save_item(NAME(m_xmap0.m_revision));
- save_item(NAME(m_xmap0.m_entries));
- save_item(NAME(m_xmap0.m_cursor_cmap));
- save_item(NAME(m_xmap0.m_popup_cmap));
- save_item(NAME(m_xmap0.m_mode_table_idx));
- save_item(NAME(m_xmap0.m_mode_table));
- save_item(NAME(m_xmap1.m_config));
- save_item(NAME(m_xmap1.m_revision));
- save_item(NAME(m_xmap1.m_entries));
- save_item(NAME(m_xmap1.m_cursor_cmap));
- save_item(NAME(m_xmap1.m_popup_cmap));
- save_item(NAME(m_xmap1.m_mode_table_idx));
- save_item(NAME(m_xmap1.m_mode_table));
save_item(NAME(m_rex3.m_draw_mode0));
save_item(NAME(m_rex3.m_color_host));
@@ -195,15 +853,7 @@ void newport_base_device::device_start()
save_item(NAME(m_rex3.m_clip_mode));
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_cmap0.m_palette_idx));
- save_item(NAME(m_cmap0.m_palette));
-
- save_item(NAME(m_readout_x0));
- save_item(NAME(m_readout_y0));
- save_item(NAME(m_readout_x1));
- save_item(NAME(m_readout_y1));
+ save_item(NAME(m_rex3.m_dcb_mask));
save_item(NAME(m_ramdac_lut_r));
save_item(NAME(m_ramdac_lut_g));
@@ -217,11 +867,7 @@ void newport_base_device::device_start()
void newport_base_device::device_reset()
{
- memset(&m_vc2, 0, sizeof(vc2_t));
- memset(&m_xmap0, 0, sizeof(xmap_t));
- memset(&m_xmap1, 0, sizeof(xmap_t));
memset(&m_rex3, 0, sizeof(rex3_t));
- memset(&m_cmap0, 0, sizeof(cmap_t));
memset(m_ramdac_lut_r, 0, sizeof(uint32_t) * 256);
memset(m_ramdac_lut_g, 0, sizeof(uint32_t) * 256);
memset(m_ramdac_lut_b, 0, sizeof(uint32_t) * 256);
@@ -232,14 +878,6 @@ void newport_base_device::device_reset()
m_rex3.m_x_window = 0x1000;
m_rex3.m_y_window = 0x1000;
- m_xmap0.m_entries = 0x2;
- m_xmap1.m_entries = 0x2;
-
- m_readout_x0 = 0;
- m_readout_y0 = 0;
- m_readout_x1 = 0;
- m_readout_y1 = 0;
-
#if ENABLE_NEWVIEW_LOG
m_newview_log = nullptr;
#endif
@@ -267,11 +905,13 @@ void newport_base_device::start_logging()
popmessage("Recording Newport to %s", log_name_buf);
- fwrite(&m_vc2, sizeof(vc2_t), 1, m_newview_log);
- fwrite(&m_xmap0, sizeof(xmap_t), 1, m_newview_log);
- fwrite(&m_xmap1, sizeof(xmap_t), 1, m_newview_log);
+ // TODO
+ //fwrite(&m_vc2, sizeof(vc2_t), 1, m_newview_log);
+ //fwrite(&m_xmap0, sizeof(xmap_t), 1, m_newview_log);
+ //fwrite(&m_xmap1, sizeof(xmap_t), 1, m_newview_log);
fwrite(&m_rex3, sizeof(rex3_t), 1, m_newview_log);
- fwrite(&m_cmap0, sizeof(cmap_t), 1, m_newview_log);
+ // TODO
+ //fwrite(&m_cmap0, sizeof(cmap_t), 1, m_newview_log);
fwrite(&m_rgbci[0], sizeof(uint32_t), (1280+64)*(1024+64), m_newview_log);
fwrite(&m_olay[0], sizeof(uint32_t), (1280+64)*(1024+64), m_newview_log);
fwrite(&m_pup[0], sizeof(uint32_t), (1280+64)*(1024+64), m_newview_log);
@@ -294,59 +934,26 @@ void newport_base_device::device_timer(emu_timer &timer, device_timer_id id, int
}
}
-uint8_t newport_base_device::get_cursor_pixel(int x, int y)
-{
- if (x < 0 || y < 0)
- return 0;
-
- bool monochrome_cursor = BIT(m_vc2.m_display_ctrl, DCR_CURSOR_SIZE_BIT) == DCR_CURSOR_SIZE_64;
-
- int size = monochrome_cursor ? 64 : 32;
- if (x >= size || y >= size)
- return 0;
-
- const int shift = 15 - (x % 16);
-
- if (monochrome_cursor)
- {
- const int address = y * 4 + (x / 16);
- const uint16_t word = m_vc2.m_ram[m_vc2.m_cursor_entry + address];
- return BIT(word, shift);
- }
- else
- {
- const int address = y * 2 + (x / 16);
- const uint16_t word0 = m_vc2.m_ram[m_vc2.m_cursor_entry + address];
- const uint16_t word1 = m_vc2.m_ram[m_vc2.m_cursor_entry + address + 64];
- return BIT(word0, shift) | (BIT(word1, shift) << 1);
- }
-}
-
uint32_t newport_base_device::screen_update(screen_device &device, bitmap_rgb32 &bitmap, const rectangle &cliprect)
{
- bool enable_cursor = BIT(m_vc2.m_display_ctrl, DCR_CURSOR_FUNC_ENABLE_BIT) != 0
- && BIT(m_vc2.m_display_ctrl, DCR_CURSOR_ENABLE_BIT) != 0
- && BIT(m_vc2.m_display_ctrl, DCR_CURSOR_MODE_BIT) == DCR_CURSOR_MODE_GLYPH;
+ const uint16_t cursor_msb = (uint16_t)m_xmap[0]->cursor_cmap() << 5;
+ const uint16_t popup_msb = (uint16_t)m_xmap[0]->popup_cmap() << 5;
+ const uint32_t *palette = m_cmap[0]->palette_base();
- const uint16_t cursor_msb = (uint16_t)m_xmap0.m_cursor_cmap << 5;
- const uint16_t popup_msb = (uint16_t)m_xmap0.m_popup_cmap << 5;
+ const int y_start = m_vc2->readout_y0();
+ const int y_end = m_vc2->readout_y1();
/* loop over rows and copy to the destination */
- for (int y = cliprect.min_y, sy = m_readout_y0; y <= cliprect.max_y && sy < m_readout_y1; y++, sy++)
- //for (int y = cliprect.min_y; y <= cliprect.max_y; y++)
+ for (int y = cliprect.min_y, sy = y_start; y <= cliprect.max_y && sy < y_end; y++, sy++)
{
uint32_t *dest = &bitmap.pix32(y, cliprect.min_x);
- //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_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];
-
// Fetch the initial DID entry
- uint16_t curr_did_entry = m_vc2.m_ram[m_vc2.m_did_line_ptr];
- uint32_t table_entry = m_xmap0.m_mode_table[curr_did_entry & 0x1f];
+ uint16_t curr_did_entry = m_vc2->begin_did_line(y);
+ uint32_t table_entry = m_xmap[0]->mode_entry(curr_did_entry & 0x1f);
uint8_t pix_mode = (table_entry >> 8) & 3;
uint8_t pix_size = (table_entry >> 10) & 3;
uint8_t aux_pix_mode = (table_entry >> 16) & 7;
@@ -354,63 +961,56 @@ uint32_t newport_base_device::screen_update(screen_device &device, bitmap_rgb32
uint16_t ci_msb = 0;
switch ((table_entry >> 8) & 3)
{
- case 0: ci_msb = (m_xmap0.m_mode_table[curr_did_entry & 0x1f] & 0xf8) << 5; break;
+ case 0: ci_msb = (table_entry & 0xf8) << 5; break;
case 1: ci_msb = 0x1d00; break;
case 2: ci_msb = 0x1e00; break;
case 3: ci_msb = 0x1f00; break;
}
// Prepare for the next DID entry
- m_vc2.m_did_line_ptr++;
- curr_did_entry = m_vc2.m_ram[m_vc2.m_did_line_ptr];
+ curr_did_entry = m_vc2->next_did_line_entry();
// loop over columns
for (int x = cliprect.min_x; x < cliprect.max_x; x++)
{
- //*dest++ = *src++;
if ((uint16_t)x == (curr_did_entry >> 5))
{
- table_entry = m_xmap0.m_mode_table[curr_did_entry & 0x1f];
+ table_entry = m_xmap[0]->mode_entry(curr_did_entry & 0x1f);
pix_mode = (table_entry >> 8) & 3;
pix_size = (table_entry >> 10) & 3;
aux_pix_mode = (table_entry >> 16) & 7;
aux_msb = (table_entry >> 11) & 0x1f00;
switch ((table_entry >> 8) & 3)
{
- case 0: ci_msb = (m_xmap0.m_mode_table[curr_did_entry & 0x1f] & 0xf8) << 5; break;
+ case 0: ci_msb = (table_entry & 0xf8) << 5; break;
case 1: ci_msb = 0x1d00; break;
case 2: ci_msb = 0x1e00; break;
case 3: ci_msb = 0x1f00; break;
}
- m_vc2.m_did_line_ptr++;
- curr_did_entry = m_vc2.m_ram[m_vc2.m_did_line_ptr];
- }
- uint8_t cursor_pixel = 0;
- if (x >= (m_vc2.m_cursor_x - 31) && x <= m_vc2.m_cursor_x && y >= (m_vc2.m_cursor_y - 31) && y <= m_vc2.m_cursor_y && enable_cursor)
- {
- cursor_pixel = get_cursor_pixel(x - ((int)m_vc2.m_cursor_x - 31), y - ((int)m_vc2.m_cursor_y - 31));
+ curr_did_entry = m_vc2->next_did_line_entry();
}
+ uint8_t cursor_pixel = m_vc2->get_cursor_pixel(x, y);
bool pixel_replaced = false;
if (cursor_pixel)
{
- *dest++ = m_cmap0.m_palette[cursor_msb | cursor_pixel];
+ *dest++ = palette[cursor_msb | cursor_pixel];
pixel_replaced = true;
}
else if (*src_pup)
{
const uint32_t src = (*src_pup >> 2) & 3;
- *dest++ = m_cmap0.m_palette[popup_msb | src];
+ *dest++ = palette[popup_msb | src];
pixel_replaced = true;
}
else if (aux_pix_mode != 0)
{
- if (BIT(m_xmap0.m_config, 2))
+ if (m_xmap[0]->is_8bpp())
{
switch (aux_pix_mode)
{
case 1: // 2-Bit Underlay
- *dest++ = m_cmap0.m_palette[aux_msb | ((*src_olay >> 8) & 3)];
+ *dest++ = palette[aux_msb | ((*src_olay >> 8) & 3)];
pixel_replaced = true;
continue;
case 2: // 2-Bit Overlay
@@ -418,7 +1018,7 @@ uint32_t newport_base_device::screen_update(screen_device &device, bitmap_rgb32
const uint32_t pix_in = (*src_olay >> 8) & 3;
if (pix_in)
{
- *dest++ = m_cmap0.m_palette[aux_msb | pix_in];
+ *dest++ = palette[aux_msb | pix_in];
pixel_replaced = true;
}
break;
@@ -429,7 +1029,7 @@ uint32_t newport_base_device::screen_update(screen_device &device, bitmap_rgb32
const uint32_t pix_in = (*src_olay >> shift) & 1;
if (pix_in)
{
- *dest++ = m_cmap0.m_palette[aux_msb | pix_in];
+ *dest++ = palette[aux_msb | pix_in];
pixel_replaced = true;
}
break;
@@ -438,9 +1038,9 @@ uint32_t newport_base_device::screen_update(screen_device &device, bitmap_rgb32
{
const uint32_t pix_in = (*src_olay >> 8) & 1;
if (pix_in)
- *dest++ = m_cmap0.m_palette[aux_msb | pix_in];
+ *dest++ = palette[aux_msb | pix_in];
else
- *dest++ = m_cmap0.m_palette[aux_msb | ((*src_olay >> 9) & 1)];
+ *dest++ = palette[aux_msb | ((*src_olay >> 9) & 1)];
pixel_replaced = true;
break;
}
@@ -453,7 +1053,7 @@ uint32_t newport_base_device::screen_update(screen_device &device, bitmap_rgb32
switch (aux_pix_mode)
{
case 1: // 8-Bit Underlay
- *dest++ = m_cmap0.m_palette[aux_msb | ((*src_olay >> 8) & 0xff)];
+ *dest++ = palette[aux_msb | ((*src_olay >> 8) & 0xff)];
pixel_replaced = true;
break;
case 2: // 8-Bit Overlay
@@ -461,7 +1061,7 @@ uint32_t newport_base_device::screen_update(screen_device &device, bitmap_rgb32
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];
+ *dest++ = palette[aux_msb | pix_in];
pixel_replaced = true;
}
break;
@@ -472,7 +1072,7 @@ uint32_t newport_base_device::screen_update(screen_device &device, bitmap_rgb32
const uint32_t pix_in = (*src_olay >> shift) & 0xf;
if (pix_in)
{
- *dest++ = m_cmap0.m_palette[aux_msb | pix_in];
+ *dest++ = palette[aux_msb | pix_in];
pixel_replaced = true;
}
break;
@@ -481,9 +1081,9 @@ uint32_t newport_base_device::screen_update(screen_device &device, bitmap_rgb32
{
const uint32_t pix_in = (*src_pup >> 8) & 0xf;
if (pix_in)
- *dest++ = m_cmap0.m_palette[aux_msb | pix_in];
+ *dest++ = palette[aux_msb | pix_in];
else
- *dest++ = m_cmap0.m_palette[aux_msb | ((*src_pup >> 12) & 0xf)];
+ *dest++ = palette[aux_msb | ((*src_pup >> 12) & 0xf)];
pixel_replaced = true;
break;
}
@@ -504,17 +1104,17 @@ uint32_t newport_base_device::screen_update(screen_device &device, bitmap_rgb32
{
const uint8_t shift = BIT(table_entry, 0) ? 4 : 0;
const uint32_t pix_in = *src_ci;
- *dest++ = m_cmap0.m_palette[ci_msb | ((pix_in >> shift) & 0x0f)];
+ *dest++ = palette[ci_msb | ((pix_in >> shift) & 0x0f)];
break;
}
case 1: // 8bpp
- *dest++ = m_cmap0.m_palette[ci_msb | (uint8_t)*src_ci];
+ *dest++ = palette[ci_msb | (uint8_t)*src_ci];
break;
case 2: // 12bpp
{
const uint8_t shift = BIT(table_entry, 0) ? 12 : 0;
const uint32_t pix_in = (*src_ci >> shift) & 0x00000fff;
- *dest++ = m_cmap0.m_palette[(ci_msb & 0x1000) | pix_in];
+ *dest++ = palette[(ci_msb & 0x1000) | pix_in];
break;
}
case 3: // 24bpp (not yet supported)
@@ -754,640 +1354,27 @@ void newport_base_device::ramdac_write(uint32_t data)
}
}
-void newport_base_device::cmap0_write(uint32_t data)
-{
- switch (m_rex3.m_dcb_reg_select)
- {
- case 0x00:
- LOGMASKED(LOG_CMAP0, "CMAP0 Palette Index Write: %04x\n", data & 0xffff);
- m_cmap0.m_palette_idx = (uint16_t)data;
- break;
- case 0x02:
- m_cmap0.m_palette[m_cmap0.m_palette_idx] = data >> 8;
- if (m_cmap0.m_palette_idx < 0x2000)
- set_pen_color(m_cmap0.m_palette_idx, rgb_t((uint8_t)(data >> 24), (uint8_t)(data >> 16), (uint8_t)(data >> 8)));
- LOGMASKED(LOG_CMAP0, "CMAP0 Palette Entry %04x Write: %08x\n", m_cmap0.m_palette_idx, data >> 8);
- break;
- default:
- LOGMASKED(LOG_CMAP0 | LOG_UNKNOWN, "Unknown CMAP0 Register %d Write: %08x\n", m_rex3.m_dcb_reg_select, data);
- break;
- }
-}
-
-uint32_t newport_base_device::cmap0_read()
-{
- switch (m_rex3.m_dcb_reg_select)
- {
- case 0x04:
- LOGMASKED(LOG_CMAP0, "CMAP0 Status Read: %08x\n", 0x8);
- return 0x8;
- case 0x06: /* Revision */
- {
- const uint32_t ret = get_cmap_revision();;
- LOGMASKED(LOG_CMAP0, "CMAP0 Revision Read: %08x\n", ret);
- return ret;
- }
- default:
- LOGMASKED(LOG_CMAP0 | LOG_UNKNOWN, "Unknown CMAP0 Register %d Read\n", m_rex3.m_dcb_reg_select);
- return 0;
- }
-}
-
-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)
- {
- case 0x04:
- LOGMASKED(LOG_CMAP1, "CMAP1 Status Read: %08x\n", 0x8);
- return 0x8;
- case 0x06: /* Revision */
- {
- const uint32_t ret = get_cmap_revision();;
- LOGMASKED(LOG_CMAP1, "CMAP1 Revision Read: %08x\n", ret);
- return ret;
- }
- default:
- LOGMASKED(LOG_CMAP1 | LOG_UNKNOWN, "Unknown CMAP0 Register %d Read\n", m_rex3.m_dcb_reg_select);
- return 0;
- }
-}
-
-uint32_t gio64_xl8_device::get_cmap_revision()
-{
- return 0xa1;
-}
-
-uint32_t gio64_xl24_device::get_cmap_revision()
-{
- return 0x02;
-}
-
-uint32_t newport_base_device::xmap0_read()
+WRITE_LINE_MEMBER(newport_base_device::vrint_w)
{
- switch (m_rex3.m_dcb_reg_select)
- {
- case 0:
- LOGMASKED(LOG_XMAP0, "XMAP0 Config Read: %08x\n", m_xmap0.m_config);
- return m_xmap0.m_config;
- case 1:
- {
- const uint32_t ret = get_xmap_revision();
- LOGMASKED(LOG_XMAP0, "XMAP0 Revision Read: %08x\n", ret);
- return ret;
- }
- case 2:
- LOGMASKED(LOG_XMAP0, "XMAP0 FIFO Availability Read: %08x\n", 0x2);
- return 0x2;
- case 3:
- LOGMASKED(LOG_XMAP0, "XMAP0 Cursor CMAP MSB Read: %08x\n", m_xmap0.m_cursor_cmap);
- return m_xmap0.m_cursor_cmap;
- case 4:
- LOGMASKED(LOG_XMAP0, "XMAP0 Pop Up CMAP MSB Read: %08x\n", m_xmap0.m_popup_cmap);
- return m_xmap0.m_popup_cmap;
- case 5:
- {
- uint8_t mode_idx = (m_xmap0.m_mode_table_idx & 0x7c) >> 2;
- switch (m_xmap0.m_mode_table_idx & 3)
- {
- case 0:
- {
- uint8_t ret = (uint8_t)(m_xmap0.m_mode_table[mode_idx] >> 16);
- LOGMASKED(LOG_XMAP0, "XMAP0 Mode Register Read: %02x (Byte 0): %08x\n", mode_idx, ret);
- return ret;
- }
- case 1:
- {
- uint8_t ret = (uint8_t)(m_xmap0.m_mode_table[mode_idx] >> 8);
- LOGMASKED(LOG_XMAP0, "XMAP0 Mode Register Read: %02x (Byte 1): %08x\n", mode_idx, ret);
- return ret;
- }
- case 2:
- {
- uint8_t ret = (uint8_t)m_xmap0.m_mode_table[mode_idx];
- LOGMASKED(LOG_XMAP0, "XMAP0 Mode Register Read: %02x (Byte 2): %08x\n", mode_idx, ret);
- return ret;
- }
- }
- break;
- }
- case 6:
- LOGMASKED(LOG_XMAP0, "XMAP0 Unused Read: %08x\n", 0);
- return 0;
- case 7:
- LOGMASKED(LOG_XMAP0, "XMAP0 Mode Table Address Read: %08x\n", m_xmap0.m_mode_table_idx);
- return m_xmap0.m_mode_table_idx;
- default:
- LOGMASKED(LOG_XMAP0 | LOG_UNKNOWN, "XMAP0 Unknown DCB Register Select Value: %02x, returning 0\n", m_rex3.m_dcb_reg_select);
- return 0;
- }
- return 0;
-}
-
-void newport_base_device::xmap0_write(uint32_t data)
-{
- switch (m_rex3.m_dcb_reg_select)
- {
- case 0:
- LOGMASKED(LOG_XMAP0, "XMAP0 Config Write: %02x\n", (uint8_t)data);
- m_xmap0.m_config = (uint8_t)data;
- break;
- case 1:
- LOGMASKED(LOG_XMAP0, "XMAP0 Revision Write (Ignored): %02x\n", (uint8_t)data);
- break;
- case 2:
- LOGMASKED(LOG_XMAP0, "XMAP0 FIFO Availability Write (Ignored): %02x\n", (uint8_t)data);
- break;
- case 3:
- LOGMASKED(LOG_XMAP0, "XMAP0 Cursor CMAP MSB Write: %02x\n", (uint8_t)data);
- m_xmap0.m_cursor_cmap = (uint8_t)data;
- break;
- case 4:
- LOGMASKED(LOG_XMAP0, "XMAP0 Pop Up CMAP MSB Write: %02x\n", (uint8_t)data);
- m_xmap0.m_popup_cmap = (uint8_t)data;
- break;
- case 5:
- LOGMASKED(LOG_XMAP0, "XMAP0 Mode Register Write: %02x = %06x\n", data >> 24, data & 0xffffff);
- m_xmap0.m_mode_table[data >> 24] = data & 0xffffff;
- break;
- case 6:
- LOGMASKED(LOG_XMAP0, "XMAP0 Unused Write (Ignored): %08x\n", data);
- break;
- case 7:
- LOGMASKED(LOG_XMAP0, "XMAP0 Mode Table Address Write: %02x\n", (uint8_t)data);
- m_xmap0.m_mode_table_idx = (uint8_t)data;
- break;
- default:
- LOGMASKED(LOG_XMAP0 | LOG_UNKNOWN, "XMAP0 Unknown DCB Register Select Value: %02x = %08x\n", m_rex3.m_dcb_reg_select, data);
- break;
- }
-}
-
-uint32_t newport_base_device::xmap1_read()
-{
- switch (m_rex3.m_dcb_reg_select)
- {
- case 0:
- LOGMASKED(LOG_XMAP1, "XMAP1 Config Read: %08x\n", m_xmap1.m_config);
- return m_xmap1.m_config;
- case 1:
- {
- const uint32_t ret = get_xmap_revision();
- LOGMASKED(LOG_XMAP1, "XMAP1 Revision Read: %08x\n", ret);
- return ret;
- }
- case 2:
- LOGMASKED(LOG_XMAP1, "XMAP1 FIFO Availability Read: %08x\n", 0x02);
- return 0x2;
- case 3:
- LOGMASKED(LOG_XMAP1, "XMAP1 Cursor CMAP MSB Read: %08x\n", m_xmap1.m_cursor_cmap);
- return m_xmap1.m_cursor_cmap;
- case 4:
- LOGMASKED(LOG_XMAP1, "XMAP1 Pop Up CMAP MSB Read: %08x\n", m_xmap1.m_popup_cmap);
- return m_xmap1.m_popup_cmap;
- case 5:
- {
- const uint8_t mode_idx = (m_xmap1.m_mode_table_idx & 0x7c) >> 2;
- switch (m_xmap1.m_mode_table_idx & 3)
- {
- case 0:
- {
- uint8_t ret = (uint8_t)(m_xmap1.m_mode_table[mode_idx] >> 16);
- LOGMASKED(LOG_XMAP1, "XMAP1 Mode Register Read: %02x (Byte 0): %08x\n", mode_idx, ret);
- return ret;
- }
- case 1:
- {
- uint8_t ret = (uint8_t)(m_xmap1.m_mode_table[mode_idx] >> 8);
- LOGMASKED(LOG_XMAP1, "XMAP1 Mode Register Read: %02x (Byte 1): %08x\n", mode_idx, ret);
- return ret;
- }
- case 2:
- {
- uint8_t ret = (uint8_t)m_xmap1.m_mode_table[mode_idx];
- LOGMASKED(LOG_XMAP1, "XMAP1 Mode Register Read: %02x (Byte 2): %08x\n", mode_idx, ret);
- return ret;
- }
- }
- break;
- }
- case 6:
- LOGMASKED(LOG_XMAP1, "XMAP1 Unused Read: %08x\n", 0);
- return 0;
- case 7:
- LOGMASKED(LOG_XMAP1, "XMAP1 Mode Table Address Read: %08x\n", m_xmap0.m_mode_table_idx);
- return m_xmap1.m_mode_table_idx;
- default:
- LOGMASKED(LOG_XMAP1 | LOG_UNKNOWN, "XMAP1 Unknown DCB Register Select Value: %02x, returning 0\n", m_rex3.m_dcb_reg_select);
- return 0;
- }
- return 0;
-}
-
-void newport_base_device::xmap1_write(uint32_t data)
-{
- switch (m_rex3.m_dcb_reg_select)
- {
- case 0:
- LOGMASKED(LOG_XMAP1, "XMAP1 Config Write: %02x\n", (uint8_t)data);
- m_xmap1.m_config = (uint8_t)data;
- break;
- case 1:
- LOGMASKED(LOG_XMAP1, "XMAP1 Revision Write (Ignored): %02x\n", (uint8_t)data);
- break;
- case 2:
- LOGMASKED(LOG_XMAP1, "XMAP1 FIFO Availability Write (Ignored): %02x\n", (uint8_t)data);
- break;
- case 3:
- LOGMASKED(LOG_XMAP1, "XMAP1 Cursor CMAP MSB Write: %02x\n", (uint8_t)data);
- m_xmap1.m_cursor_cmap = (uint8_t)data;
- break;
- case 4:
- LOGMASKED(LOG_XMAP1, "XMAP1 Pop Up CMAP MSB Write: %02x\n", (uint8_t)data);
- m_xmap1.m_popup_cmap = (uint8_t)data;
- break;
- case 5:
- LOGMASKED(LOG_XMAP1, "XMAP1 Mode Register Write: %02x = %06x\n", data >> 24, data & 0xffffff);
- m_xmap1.m_mode_table[data >> 24] = data & 0xffffff;
- break;
- case 6:
- LOGMASKED(LOG_XMAP1, "XMAP1 Unused Write (Ignored): %08x\n", data);
- break;
- case 7:
- LOGMASKED(LOG_XMAP1, "XMAP1 Mode Table Address Write: %02x\n", (uint8_t)data);
- m_xmap1.m_mode_table_idx = (uint8_t)data;
- break;
- default:
- LOGMASKED(LOG_XMAP0 | LOG_UNKNOWN, "XMAP0 Unknown DCB Register Select Value: %02x = %08x\n", m_rex3.m_dcb_reg_select, data);
- break;
- }
-}
-
-uint32_t gio64_xl8_device::get_xmap_revision()
-{
- return 1;
-}
-
-uint32_t gio64_xl24_device::get_xmap_revision()
-{
- return 3;
-}
-
-uint32_t newport_base_device::vc2_read()
-{
- switch (m_rex3.m_dcb_reg_select)
- {
- case 0x01: /* Register Read */
- switch (m_vc2.m_reg_idx)
- {
- case 0x00:
- LOGMASKED(LOG_VC2, "VC2 Register Read: Video Entry Pointer, %08x\n", m_vc2.m_vid_entry);
- return m_vc2.m_vid_entry;
- case 0x01:
- LOGMASKED(LOG_VC2, "VC2 Register Read: Cursor Entry Pointer, %08x\n", m_vc2.m_cursor_entry);
- return m_vc2.m_cursor_entry;
- case 0x02:
- LOGMASKED(LOG_VC2, "VC2 Register Read: Cursor X, %08x\n", m_vc2.m_cursor_x);
- return m_vc2.m_cursor_x;
- case 0x03:
- LOGMASKED(LOG_VC2, "VC2 Register Read: Cursor Y, %08x\n", m_vc2.m_cursor_y);
- return m_vc2.m_cursor_y;
- case 0x04:
- LOGMASKED(LOG_VC2, "VC2 Register Read: Current Cursor X, %08x\n", m_vc2.m_cur_cursor_x);
- return m_vc2.m_cur_cursor_x;
- case 0x05:
- LOGMASKED(LOG_VC2, "VC2 Register Read: DID Entry, %08x\n", m_vc2.m_did_entry);
- return m_vc2.m_did_entry;
- case 0x06:
- LOGMASKED(LOG_VC2, "VC2 Register Read: Scanline Length, %08x\n", m_vc2.m_scanline_len);
- return m_vc2.m_scanline_len;
- case 0x07:
- LOGMASKED(LOG_VC2, "VC2 Register Read: RAM Address, %08x\n", m_vc2.m_ram_addr);
- return m_vc2.m_ram_addr;
- case 0x08:
- LOGMASKED(LOG_VC2, "VC2 Register Read: VT Frame Pointer, %08x\n", m_vc2.m_vt_frame_ptr);
- return m_vc2.m_vt_frame_ptr;
- case 0x09:
- LOGMASKED(LOG_VC2, "VC2 Register Read: VT Line Sequence Pointer, %08x\n", m_vc2.m_vt_line_ptr);
- return m_vc2.m_vt_line_ptr;
- case 0x0a:
- LOGMASKED(LOG_VC2, "VC2 Register Read: VT Lines in Run, %08x\n", m_vc2.m_vt_line_run);
- return m_vc2.m_vt_line_run;
- case 0x0b:
- LOGMASKED(LOG_VC2, "VC2 Register Read: Vertical Line Count, %08x\n", m_vc2.m_vt_line_count);
- return m_vc2.m_vt_line_count;
- case 0x0c:
- LOGMASKED(LOG_VC2, "VC2 Register Read: Cursor Table Pointer, %08x\n", m_vc2.m_cursor_table_ptr);
- return m_vc2.m_cursor_table_ptr;
- case 0x0d:
- LOGMASKED(LOG_VC2, "VC2 Register Read: Working Cursor Y, %08x\n", m_vc2.m_work_cursor_y);
- return m_vc2.m_work_cursor_y;
- case 0x0e:
- LOGMASKED(LOG_VC2, "VC2 Register Read: DID Frame Pointer, %08x\n", m_vc2.m_did_frame_ptr);
- return m_vc2.m_did_frame_ptr;
- case 0x0f:
- LOGMASKED(LOG_VC2, "VC2 Register Read: DID Line Pointer, %08x\n", m_vc2.m_did_line_ptr);
- return m_vc2.m_did_line_ptr;
- case 0x10:
- LOGMASKED(LOG_VC2, "VC2 Register Read: Display Control, %08x\n", m_vc2.m_display_ctrl);
- return m_vc2.m_display_ctrl;
- case 0x1f:
- LOGMASKED(LOG_VC2, "VC2 Register Read: Configuration, %08x\n", m_vc2.m_config);
- return m_vc2.m_config;
- default:
- return 0;
- }
- break;
- case 0x03: /* RAM Read */
+ if (state)
{
- LOGMASKED(LOG_VC2, "VC2 RAM Read: %04x = %08x\n", m_vc2.m_ram_addr, m_vc2.m_ram[m_vc2.m_ram_addr]);
- uint16_t ret = m_vc2.m_ram[m_vc2.m_ram_addr];
- m_vc2.m_ram_addr++;
- if (m_vc2.m_ram_addr == 0x8000)
- {
- m_vc2.m_ram_addr = 0x0000;
- }
- return ret;
- }
- default:
- LOGMASKED(LOG_VC2 | LOG_UNKNOWN, "Unknown VC2 Register Read: %02x\n", m_rex3.m_dcb_reg_select);
- return 0;
+ m_rex3.m_status |= STATUS_VRINT;
+ m_gio64->interrupt<2>(ASSERT_LINE);
}
}
-void newport_base_device::decode_vt_line(uint32_t line, uint32_t line_seq_ptr)
-{
- bool eol_sa = false;
- bool eol_sb = false;
- uint32_t vt_entry = 0;
- uint32_t i = 0;
- do
- {
- vt_entry &= ~(0x7f << 14);
- vt_entry |= (m_vc2.m_ram[line_seq_ptr] & 0x7f) << 14;
- eol_sa = BIT(m_vc2.m_ram[line_seq_ptr], 15);
- if (!BIT(m_vc2.m_ram[line_seq_ptr], 7))
- {
- eol_sb = BIT(m_vc2.m_ram[line_seq_ptr + 1], 15);
- vt_entry &= (0x7f << 14);
- vt_entry |= (m_vc2.m_ram[line_seq_ptr + 1] & 0x7f00) >> 1;
- vt_entry |= m_vc2.m_ram[line_seq_ptr + 1] & 0x7f;
- line_seq_ptr += 2;
- }
- else
- {
- eol_sb = true;
- line_seq_ptr++;
- }
- for (uint32_t j = 0; j < ((m_vc2.m_ram[line_seq_ptr] & 0x7f00) >> 7); i++, j++)
- {
- const uint8_t sa = ((vt_entry >> 14) & 0x7f) << 1;
- const uint8_t sb = ((vt_entry >> 7) & 0x7f) << 1;
- const uint8_t sc = ((vt_entry >> 0) & 0x7f) << 1;
- //m_vt_table[line * 2048 + i] = vt_entry;
- m_vt_table[line * 2048 + i] = 0xff000000 | (sa << 16) | (sb << 8) | sc;
- }
- } while (!(eol_sa && eol_sb));
-}
-
-void newport_base_device::decode_vt_table()
-{
- memset(&m_vt_table[0], 0, sizeof(uint32_t) * 2048 * 2048);
- uint32_t curr_vt_entry = m_vc2.m_vid_entry;
- uint32_t line_counter = 0;
- uint32_t line_seq_len = 0;
- do
- {
- const uint32_t line_seq_ptr = m_vc2.m_ram[curr_vt_entry];
- line_seq_len = m_vc2.m_ram[curr_vt_entry + 1];
- if (line_seq_len)
- {
- for (uint32_t i = 0; i < line_seq_len; i++, line_counter++)
- {
- decode_vt_line(line_counter, line_seq_ptr);
- }
- }
- curr_vt_entry += 2;
- } while (line_seq_len != 0);
-}
-
-void newport_base_device::update_screen_size()
+// TOOD: Figure out a better way of doing this
+WRITE_LINE_MEMBER(newport_base_device::update_screen_size)
{
- decode_vt_table();
+ const int x_start = m_vc2->readout_x0();
+ const int y_start = m_vc2->readout_y0();
+ const int x_end = m_vc2->readout_x1();
+ const int y_end = m_vc2->readout_y1();
- bool x_started = false;
- bool y_started = false;
- bool x_done = false;
- bool y_done = false;
- bool done = false;
- m_readout_x0 = 0;
- m_readout_y0 = 0;
- m_readout_x1 = 0;
- m_readout_y1 = 0;
-
- for (int y = 0; y < 2048 && !done; y++)
- {
- uint32_t *src = &m_vt_table[y * 2048];
- for (int x = 0; x < 2048 && !done; x++)
- {
- if (BIT(*src, 7))
- {
- if (!x_started)
- {
- x_started = true;
- m_readout_x0 = x;
- }
- if (!y_started)
- {
- y_started = true;
- m_readout_y0 = y;
- }
- }
- else
- {
- if (x_started && !x_done)
- {
- m_readout_x1 = x;
- x_done = true;
- }
- if (y_started && !y_done && x == m_readout_x0)
- {
- m_readout_y1 = y;
- y_done = true;
- }
- }
- done = x_done && y_done;
- src++;
- }
- }
-
- m_screen->set_size((uint16_t)(m_readout_x1 - m_readout_x0), (uint16_t)(m_readout_y1 - m_readout_y0));
+ m_screen->set_size((uint16_t)(x_end - x_start), (uint16_t)(y_end - y_start));
m_screen->set_visarea_full();
}
-void newport_base_device::vc2_write(uint32_t data)
-{
- switch (m_rex3.m_xfer_width)
- {
- case 0x01: /* Register Select */
- switch (m_rex3.m_dcb_reg_select)
- {
- case 0x00:
- m_vc2.m_reg_idx = (uint8_t)data;
- LOGMASKED(LOG_VC2, "VC2 Register Select: %02x\n", m_vc2.m_reg_idx);
- break;
- default:
- LOGMASKED(LOG_VC2 | LOG_UNKNOWN, "Unknown VC2 Register Select: DCB Register %02x, data = %08x\n", m_rex3.m_dcb_reg_select, data);
- break;
- }
- break;
- case 0x02: /* RAM Write */
- switch (m_rex3.m_dcb_reg_select)
- {
- case 0x03:
- LOGMASKED(LOG_VC2, "VC2 RAM Write: %04x = %08x\n", m_vc2.m_ram_addr, (uint16_t)data);
- m_vc2.m_ram[m_vc2.m_ram_addr] = (uint16_t)data;
- m_vc2.m_ram_addr++;
- if (m_vc2.m_ram_addr >= 0x8000)
- {
- m_vc2.m_ram_addr = 0x0000;
- }
- break;
- default:
- LOGMASKED(LOG_VC2 | LOG_UNKNOWN, "Unknown Word Write: DCB Register %02x, data = %08x\n", m_rex3.m_dcb_reg_select, data);
- break;
- }
- break;
- case 0x03: /* Register Write */
- switch (m_rex3.m_dcb_reg_select)
- {
- case 0x00:
- LOGMASKED(LOG_VC2, "VC2 Register Setup:\n");
- m_vc2.m_reg_idx = data >> 24;
- m_vc2.m_reg_data = (uint16_t)(data >> 8);
- switch (m_vc2.m_reg_idx)
- {
- case 0x00:
- m_vc2.m_vid_entry = m_vc2.m_reg_data;
- LOGMASKED(LOG_VC2, "VC2 Register Write: Video Entry Pointer, %04x\n", m_vc2.m_vid_entry);
- update_screen_size();
- break;
- case 0x01:
- m_vc2.m_cursor_entry = m_vc2.m_reg_data;
- LOGMASKED(LOG_VC2, "VC2 Register Write: Cursor Entry Pointer, %04x\n", m_vc2.m_cursor_entry);
- break;
- case 0x02:
- m_vc2.m_cursor_x = m_vc2.m_reg_data;
- LOGMASKED(LOG_VC2, "VC2 Register Write: Cursor X, %04x\n", m_vc2.m_cursor_x);
- break;
- case 0x03:
- m_vc2.m_cursor_y = m_vc2.m_reg_data;
- LOGMASKED(LOG_VC2, "VC2 Register Write: Cursor Y, %04x\n", m_vc2.m_cursor_y);
- m_vc2.m_cur_cursor_x = m_vc2.m_cursor_x;
- break;
- case 0x04:
- m_vc2.m_cur_cursor_x = m_vc2.m_reg_data;
- LOGMASKED(LOG_VC2, "VC2 Register Write: Current Cursor X, %04x\n", m_vc2.m_cur_cursor_x);
- break;
- case 0x05:
- m_vc2.m_did_entry = m_vc2.m_reg_data;
- LOGMASKED(LOG_VC2, "VC2 Register Write: DID Entry Pointer, %04x\n", m_vc2.m_did_entry);
- break;
- case 0x06:
- m_vc2.m_scanline_len = m_vc2.m_reg_data;
- LOGMASKED(LOG_VC2, "VC2 Register Write: Scanline Length, %04x\n", m_vc2.m_scanline_len);
- break;
- case 0x07:
- m_vc2.m_ram_addr = m_vc2.m_reg_data;
- LOGMASKED(LOG_VC2, "VC2 Register Write: RAM Address, %04x\n", m_vc2.m_ram_addr);
- break;
- case 0x08:
- m_vc2.m_vt_frame_ptr = m_vc2.m_reg_data;
- LOGMASKED(LOG_VC2, "VC2 Register Write: VT Frame Table Ptr, %04x\n", m_vc2.m_vt_frame_ptr);
- break;
- case 0x09:
- m_vc2.m_vt_line_ptr = m_vc2.m_reg_data;
- LOGMASKED(LOG_VC2, "VC2 Register Write: VT Line Sequence Pointer, %04x\n", m_vc2.m_vt_line_ptr);
- break;
- case 0x0a:
- m_vc2.m_vt_line_run = m_vc2.m_reg_data;
- LOGMASKED(LOG_VC2, "VC2 Register Write: VT Lines in Run, %04x\n", m_vc2.m_vt_line_run);
- break;
- case 0x0b:
- m_vc2.m_vt_line_count = m_vc2.m_reg_data;
- LOGMASKED(LOG_VC2, "VC2 Register Write: Vertical Line Count, %04x\n", m_vc2.m_vt_line_count);
- break;
- case 0x0c:
- m_vc2.m_cursor_table_ptr = m_vc2.m_reg_data;
- LOGMASKED(LOG_VC2, "VC2 Register Write: Cursor Table Pointer, %04x\n", m_vc2.m_cursor_table_ptr);
- break;
- case 0x0d:
- m_vc2.m_work_cursor_y = m_vc2.m_reg_data;
- LOGMASKED(LOG_VC2, "VC2 Register Write: Working Cursor Y, %04x\n", m_vc2.m_work_cursor_y);
- break;
- case 0x0e:
- m_vc2.m_did_frame_ptr = m_vc2.m_reg_data;
- LOGMASKED(LOG_VC2, "VC2 Register Write: DID Frame Table Pointer, %04x\n", m_vc2.m_did_frame_ptr);
- break;
- case 0x0f:
- m_vc2.m_did_line_ptr = m_vc2.m_reg_data;
- LOGMASKED(LOG_VC2, "VC2 Register Write: DID Line Table Pointer, %04x\n", m_vc2.m_did_line_ptr);
- break;
- case 0x10:
- m_vc2.m_display_ctrl = m_vc2.m_reg_data;
- LOGMASKED(LOG_VC2, "VC2 Register Write: Display Control, %04x\n", m_vc2.m_display_ctrl);
- break;
- case 0x1f:
- m_vc2.m_config = m_vc2.m_reg_data;
- LOGMASKED(LOG_VC2, "VC2 Register Write: Configuration, %04x\n", m_vc2.m_config);
- break;
- default:
- LOGMASKED(LOG_VC2 | LOG_UNKNOWN, "VC2 Register Write: Unknown VC2 Register: %02x = %04x\n", m_vc2.m_reg_idx, m_vc2.m_reg_data);
- break;
- }
- break;
- default:
- LOGMASKED(LOG_VC2 | LOG_UNKNOWN, "Unknown VC2 Register Write: %02x = %08x\n", m_rex3.m_dcb_reg_select, data);
- break;
- }
- break;
- default:
- LOGMASKED(LOG_VC2 | LOG_UNKNOWN, "Unknown VC2 Transfer Width: Width %02x, DCB Register %02x, Value %08x\n", m_rex3.m_xfer_width, m_rex3.m_dcb_reg_select, data);
- break;
- }
-}
-
-WRITE_LINE_MEMBER(newport_base_device::vblank_w)
-{
- if (state)
- {
- if (BIT(m_vc2.m_display_ctrl, 0))
- {
- m_rex3.m_status |= STATUS_VRINT;
- m_gio64->interrupt<2>(ASSERT_LINE);
- }
- }
-}
-
READ64_MEMBER(newport_base_device::rex3_r)
{
uint64_t ret = 0;
@@ -1693,19 +1680,19 @@ READ64_MEMBER(newport_base_device::rex3_r)
switch (m_rex3.m_dcb_slave_select)
{
case DCB_ADDR_VC2:
- ret |= (uint64_t)vc2_read() << 32;
+ ret |= (uint64_t)m_vc2->read(m_rex3.m_dcb_reg_select) << 32;
break;
case DCB_ADDR_CMAP0:
- ret |= (uint64_t)cmap0_read() << 32;
+ ret |= (uint64_t)m_cmap[0]->read(m_rex3.m_dcb_reg_select) << 32;
break;
case DCB_ADDR_CMAP1:
- ret |= (uint64_t)cmap1_read() << 32;
+ ret |= (uint64_t)m_cmap[1]->read(m_rex3.m_dcb_reg_select) << 32;
break;
case DCB_ADDR_XMAP0:
- ret |= (uint64_t)xmap0_read() << 32;
+ ret |= (uint64_t)m_xmap[0]->read(m_rex3.m_dcb_reg_select) << 32;
break;
case DCB_ADDR_XMAP1:
- ret |= (uint64_t)xmap1_read() << 32;
+ ret |= (uint64_t)m_xmap[1]->read(m_rex3.m_dcb_reg_select) << 32;
break;
case DCB_ADDR_RAMDAC:
LOGMASKED(LOG_REX3, "REX3 Display Control Bus Data MSW Read from RAMDAC (not yet implemented)\n");
@@ -4042,19 +4029,19 @@ WRITE64_MEMBER(newport_base_device::rex3_w)
{
case 0x00:
LOGMASKED(LOG_REX3, " Transfer Width: 4 bytes\n");
- m_rex3.m_xfer_width = 4;
+ m_rex3.m_dcb_mask = 0xffffffff;
break;
case 0x01:
LOGMASKED(LOG_REX3, " Transfer Width: 1 bytes\n");
- m_rex3.m_xfer_width = 1;
+ m_rex3.m_dcb_mask = 0x000000ff;
break;
case 0x02:
LOGMASKED(LOG_REX3, " Transfer Width: 2 bytes\n");
- m_rex3.m_xfer_width = 2;
+ m_rex3.m_dcb_mask = 0x0000ffff;
break;
case 0x03:
LOGMASKED(LOG_REX3, " Transfer Width: 3 bytes\n");
- m_rex3.m_xfer_width = 3;
+ m_rex3.m_dcb_mask = 0xffffffff;
break;
}
LOGMASKED(LOG_REX3, " Enable Data Packing: %d\n", BIT(data, 2));
@@ -4080,27 +4067,27 @@ WRITE64_MEMBER(newport_base_device::rex3_w)
switch (m_rex3.m_dcb_slave_select)
{
case DCB_ADDR_VC2:
- vc2_write(data32);
+ m_vc2->write(m_rex3.m_dcb_reg_select, data32, m_rex3.m_dcb_mask);
break;
case DCB_ADDR_CMAP01:
- cmap0_write(data32);
- cmap1_write(data32);
+ m_cmap[0]->write(m_rex3.m_dcb_reg_select, data32);
+ m_cmap[1]->write(m_rex3.m_dcb_reg_select, data32);
break;
case DCB_ADDR_CMAP0:
- cmap0_write(data32);
+ m_cmap[0]->write(m_rex3.m_dcb_reg_select, data32);
break;
case DCB_ADDR_CMAP1:
- cmap1_write(data32);
+ m_cmap[1]->write(m_rex3.m_dcb_reg_select, data32);
break;
case DCB_ADDR_XMAP01:
- xmap0_write(data32);
- xmap1_write(data32);
+ m_xmap[0]->write(m_rex3.m_dcb_reg_select, data32);
+ m_xmap[1]->write(m_rex3.m_dcb_reg_select, data32);
break;
case DCB_ADDR_XMAP0:
- xmap0_write(data32);
+ m_xmap[0]->write(m_rex3.m_dcb_reg_select, data32);
break;
case DCB_ADDR_XMAP1:
- xmap1_write(data32);
+ m_xmap[1]->write(m_rex3.m_dcb_reg_select, data32);
break;
case DCB_ADDR_RAMDAC:
ramdac_write(data32);
@@ -4239,6 +4226,10 @@ void newport_base_device::install_device()
void newport_base_device::device_add_mconfig(machine_config &config)
{
+ VC2(config, m_vc2, 0);
+ m_vc2->vert_int().set(FUNC(newport_base_device::vrint_w));
+ m_vc2->screen_timing_changed().set(FUNC(newport_base_device::update_screen_size));
+
/* video hardware */
SCREEN(config, m_screen, SCREEN_TYPE_RASTER);
m_screen->set_refresh_hz(60);
@@ -4248,5 +4239,25 @@ void newport_base_device::device_add_mconfig(machine_config &config)
m_screen->set_size(1280+64, 1024+64);
m_screen->set_visarea(0, 1279, 0, 1023);
m_screen->set_screen_update(FUNC(newport_base_device::screen_update));
- m_screen->screen_vblank().set(FUNC(newport_base_device::vblank_w));
+ m_screen->screen_vblank().set(m_vc2, FUNC(vc2_device::vblank_w));
+}
+
+void newport_base_device::device_add_mconfig(machine_config &config, uint32_t xmap_revision, uint32_t cmap_revision)
+{
+ newport_base_device::device_add_mconfig(config);
+
+ XMAP9(config, m_xmap[0], 0, xmap_revision);
+ XMAP9(config, m_xmap[1], 0, xmap_revision);
+ CMAP(config, m_cmap[0], 0, cmap_revision);
+ CMAP(config, m_cmap[1], 0, cmap_revision);
+}
+
+void gio64_xl8_device::device_add_mconfig(machine_config &config)
+{
+ newport_base_device::device_add_mconfig(config, 1, 0xa1);
+}
+
+void gio64_xl24_device::device_add_mconfig(machine_config &config)
+{
+ newport_base_device::device_add_mconfig(config, 3, 0x02);
}