diff options
Diffstat (limited to 'src/devices/bus/gio64/newport.cpp')
-rw-r--r-- | src/devices/bus/gio64/newport.cpp | 1587 |
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); } |