diff --git a/scripts/target/mame/mess.lua b/scripts/target/mame/mess.lua index 714f6a56732..b1382c637e8 100644 --- a/scripts/target/mame/mess.lua +++ b/scripts/target/mame/mess.lua @@ -3097,6 +3097,8 @@ files { MAME_DIR .. "src/mame/drivers/crimson.cpp", MAME_DIR .. "src/mame/drivers/o2.cpp", MAME_DIR .. "src/mame/drivers/octane.cpp", + MAME_DIR .. "src/mame/machine/vino.cpp", + MAME_DIR .. "src/mame/machine/vino.h", MAME_DIR .. "src/mame/machine/sgi.cpp", MAME_DIR .. "src/mame/machine/sgi.h", MAME_DIR .. "src/mame/machine/hal2.cpp", diff --git a/src/devices/bus/gio/newport.cpp b/src/devices/bus/gio/newport.cpp index 07d1be903c8..e6875bc883d 100644 --- a/src/devices/bus/gio/newport.cpp +++ b/src/devices/bus/gio/newport.cpp @@ -1353,7 +1353,7 @@ READ64_MEMBER(newport_base_device::rex3_r) } break; case 0x0230/8: - if ((m_rex3.m_draw_mode0 & 7) == 5) + if ((m_rex3.m_draw_mode0 & 3) == 1) m_rex3.m_host_dataport = do_pixel_word_read(); LOGMASKED(LOG_REX3, "%s: REX3 Host Data Port Read: %08x%08x\n", machine().describe_context(), (uint32_t)(m_rex3.m_host_dataport >> 32), (uint32_t)m_rex3.m_host_dataport); @@ -2262,8 +2262,27 @@ void newport_base_device::do_iline(uint32_t color) uint32_t newport_base_device::do_pixel_read() { m_rex3.m_bres_octant_inc1 = 0; - const uint32_t ret = m_rgbci[m_rex3.m_y_start_i * (1280 + 64) + m_rex3.m_x_start_i]; - LOGMASKED(LOG_COMMANDS, "Read %08x from %04x, %04x\n", ret, m_rex3.m_x_start_i, m_rex3.m_y_start_i); + const int16_t src_x = m_rex3.m_x_start_i + m_rex3.m_x_window - 0x1000; + const int16_t src_y = m_rex3.m_y_start_i + m_rex3.m_y_window - 0x1000; + const uint32_t src_addr = src_y * (1280 + 64) + src_x; + uint32_t ret = 0; + switch (m_rex3.m_plane_enable) + { + case 1: // RGB/CI planes + case 2: // RGBA planes + ret = m_rgbci[src_addr]; + break; + case 4: // Overlay planes + ret = m_olay[src_addr]; + break; + case 5: // Popup planes + ret = m_pup[src_addr]; + break; + case 6: // CID planes + ret = m_cid[src_addr]; + break; + } + LOGMASKED(LOG_COMMANDS, "Read %08x from %04x, %04x\n", ret, src_x, src_y); m_rex3.m_x_start_i++; if (m_rex3.m_x_start_i > m_rex3.m_x_end_i) { @@ -2376,322 +2395,295 @@ void newport_base_device::do_rex3_command() LOGMASKED(LOG_COMMANDS, "REX3 Command: %08x|%08x - %s %s\n", mode0, mode1, s_opcode_str[mode0 & 3], s_adrmode_str[(mode0 >> 2) & 7]); - switch (mode0) + const uint8_t opcode = mode0 & 3; + const uint8_t adrmode = (mode0 >> 2) & 7; + + switch (opcode) { - case 0x00000000: // NoOp - break; - case 0x00000006: // Block, Draw - { - LOGMASKED(LOG_COMMANDS, "%04x, %04x = %02x\n", start_x, start_y, m_rex3.m_color_i); - m_rex3.m_bres_octant_inc1 = 0; - write_pixel(m_rex3.m_color_i); - start_x++; - if (start_x > end_x) - { - start_y += dy; - start_x = m_rex3.m_x_save; - } - - write_x_start(start_x << 11); - write_y_start(start_y << 11); - break; - } - case 0x00000046: // ColorHost, Block, Draw - case 0x00000066: // ColorHost, DoSetup, Block, Draw - { - m_rex3.m_bres_octant_inc1 = 0; - if (BIT(mode1, 7)) // Packed - { - const bool doubleword = BIT(mode1, 10); - LOGMASKED(LOG_COMMANDS, "%04x, %04x = %08x%08x\n", start_x, start_y, (uint32_t)(m_rex3.m_host_dataport >> 32), (uint32_t)m_rex3.m_host_dataport); - - uint16_t width = (end_x - start_x) + 1; - uint64_t shift = 0; - switch ((m_rex3.m_draw_mode1 >> 8) & 3) - { - case 0: // 4bpp - { - const uint16_t max_width = doubleword ? 16 : 8; - if (width > max_width) - width = max_width; - - shift = 60; - for (uint16_t i = 0; i < width; i++) - { - write_pixel(start_x, start_y, (uint32_t)(m_rex3.m_host_dataport >> shift)); - start_x++; - shift -= 4; - } - break; - } - - case 1: // 8bpp - { - const uint16_t max_width = doubleword ? 8 : 4; - if (width > max_width) - width = max_width; - - shift = 56; - for (uint16_t i = 0; i < width; i++) - { - write_pixel(start_x, start_y, (uint32_t)(m_rex3.m_host_dataport >> shift)); - start_x++; - shift -= 8; - } - break; - } - - case 2: // 12bpp - { - const uint16_t max_width = doubleword ? 4 : 2; - if (width > max_width) - width = max_width; - - shift = 48; - for (uint16_t i = 0; i < width; i++) - { - write_pixel(start_x, start_y, (uint32_t)(m_rex3.m_host_dataport >> shift)); - start_x++; - shift -= 16; - } - break; - } - - case 3: // 32bpp - { - const uint16_t max_width = doubleword ? 2 : 1; - if (width > max_width) - width = max_width; - - shift = 32; - for (uint16_t i = 0; i < width; i++) - { - write_pixel(start_x, start_y, (uint32_t)(m_rex3.m_host_dataport >> shift)); - start_x++; - shift -= 32; - } - break; - } - } - } - else - { - LOGMASKED(LOG_COMMANDS, "%04x, %04x = %02x\n", start_x, start_y, (uint8_t)(m_rex3.m_host_dataport >> 56)); - write_pixel(start_x, start_y, m_rex3.m_host_dataport >> 56); - start_x++; - } - if (start_x > end_x) - { - start_y += dy; - start_x = m_rex3.m_x_save; - } - write_x_start(start_x << 11); - write_y_start(start_y << 11); - break; - } - case 0x00000045: // ColorHost, Block, Read - case 0x00000065: // ColorHost, Block, Read - { - break; - } - case 0x00000022: // DoSetup, Span, Draw - case 0x00000102: // StopOnX, Span, Draw - case 0x00000122: // StopOnX, DoSetup, Span, Draw - case 0x00022102: // LSOpaque, EnLSPattern, StopOnX, Span, Draw - case 0x00080122: // LROnly, StopOnX, DoSetup, Span, Draw - case 0x00089102: // LROnly, Length32, EnZPattern, StopOnX, Span, Draw - case 0x000c0122: // LROnly, Shade, StopOnX, DoSetup, Span, Draw - case 0x000c9102: // LROnly, Shade, Length32, EnZPattern, StopOnX, Span, Draw - { - if (BIT(mode0, 19) && dx < 0) // LROnly + case 0: // NoOp break; - - if (!BIT(mode0, 8)) - end_x = start_x; - - end_x += dx; - - if (BIT(mode0, 15) && abs(end_x - start_x) > 32) - end_x = start_x + 32 * dx; - - const bool opaque = BIT(mode0, 16) || BIT(mode0, 17); - const uint32_t pattern = BIT(mode0, 12) ? m_rex3.m_z_pattern : (BIT(mode0, 13) ? m_rex3.m_ls_pattern : 0xffffffff); - const bool shade = BIT(mode0, 18); - const bool rgbmode = BIT(mode1, 15); - - LOGMASKED(LOG_COMMANDS, "%04x, %04x to %04x, %04x = %08x\n", start_x, start_y, end_x, end_y, pattern); - - uint32_t bit = 31; - for (; start_x != end_x; start_x += dx) - { - if (BIT(pattern, bit)) + case 1: // Read + // Handled on HOSTRW read + break; + case 2: // Draw + switch (adrmode) { - if (shade || rgbmode) - write_pixel(start_x, start_y, get_rgb_color(start_x, start_y)); - else - write_pixel(start_x, start_y, m_rex3.m_color_i); - } - else if (opaque) - { - write_pixel(start_x, start_y, m_rex3.m_color_back); - } + case 0: // Span + { + if (BIT(mode0, 19) && dx < 0) // LROnly + break; - if (shade) - iterate_shade(); + if (!BIT(mode0, 8)) + end_x = start_x; - bit = (bit - 1) & 0x1f; - } + end_x += dx; - write_x_start(start_x << 11); - break; - } - case 0x00000326: // StopOnX, StopOnY, DoSetup, Block, Draw - { - end_x += dx; - end_y += dy; + if (BIT(mode0, 15) && abs(end_x - start_x) > 32) + end_x = start_x + 32 * dx; - uint32_t color = m_rex3.m_color_i; - if (BIT(mode1, 17)) - { - switch (m_rex3.m_plane_depth) - { - case 0: // 4bpp - color = m_rex3.m_color_vram & 0xf; + const bool opaque = BIT(mode0, 16) || BIT(mode0, 17); + const uint32_t pattern = BIT(mode0, 12) ? m_rex3.m_z_pattern : (BIT(mode0, 13) ? m_rex3.m_ls_pattern : 0xffffffff); + const bool shade = BIT(mode0, 18); + const bool rgbmode = BIT(mode1, 15); + + LOGMASKED(LOG_COMMANDS, "%04x, %04x to %04x, %04x = %08x\n", start_x, start_y, end_x, end_y, pattern); + + uint32_t bit = 31; + for (; start_x != end_x; start_x += dx) + { + if (BIT(pattern, bit)) + { + if (shade || rgbmode) + write_pixel(start_x, start_y, get_rgb_color(start_x, start_y)); + else + write_pixel(start_x, start_y, m_rex3.m_color_i); + } + else if (opaque) + { + write_pixel(start_x, start_y, m_rex3.m_color_back); + } + + if (shade) + iterate_shade(); + + bit = (bit - 1) & 0x1f; + } + + write_x_start(start_x << 11); break; - case 1: // 8bpp - color = m_rex3.m_color_vram & 0xff; + } + + case 1: // Block + if (BIT(mode0, 19) && dx < 0) // LROnly + break; + + end_x += dx; + end_y += dy; + + if (BIT(mode0, 6)) // ColorHost + { + if (BIT(mode1, 7)) // Packed + { + const bool doubleword = BIT(mode1, 10); + LOGMASKED(LOG_COMMANDS, "%04x, %04x = %08x%08x\n", start_x, start_y, (uint32_t)(m_rex3.m_host_dataport >> 32), (uint32_t)m_rex3.m_host_dataport); + + uint16_t width = end_x - start_x; + uint64_t shift = 0; + switch ((m_rex3.m_draw_mode1 >> 8) & 3) + { + case 0: // 4bpp + { + const uint16_t max_width = doubleword ? 16 : 8; + if (width > max_width) + width = max_width; + + shift = 60; + for (uint16_t i = 0; i < width; i++) + { + write_pixel(start_x, start_y, (uint32_t)(m_rex3.m_host_dataport >> shift)); + start_x++; + shift -= 4; + } + break; + } + + case 1: // 8bpp + { + const uint16_t max_width = doubleword ? 8 : 4; + if (width > max_width) + width = max_width; + + shift = 56; + for (uint16_t i = 0; i < width; i++) + { + write_pixel(start_x, start_y, (uint32_t)(m_rex3.m_host_dataport >> shift)); + start_x++; + shift -= 8; + } + break; + } + + case 2: // 12bpp + { + const uint16_t max_width = doubleword ? 4 : 2; + if (width > max_width) + width = max_width; + + shift = 48; + for (uint16_t i = 0; i < width; i++) + { + write_pixel(start_x, start_y, (uint32_t)(m_rex3.m_host_dataport >> shift)); + start_x++; + shift -= 16; + } + break; + } + + case 3: // 32bpp + { + const uint16_t max_width = doubleword ? 2 : 1; + if (width > max_width) + width = max_width; + + shift = 32; + for (uint16_t i = 0; i < width; i++) + { + write_pixel(start_x, start_y, (uint32_t)(m_rex3.m_host_dataport >> shift)); + start_x++; + shift -= 32; + } + break; + } + } + } + else + { + LOGMASKED(LOG_COMMANDS, "%04x, %04x = %02x\n", start_x, start_y, (uint8_t)(m_rex3.m_host_dataport >> 56)); + write_pixel(start_x, start_y, m_rex3.m_host_dataport >> 56); + start_x++; + } + + if (start_x == end_x) + { + start_y += dy; + start_x = m_rex3.m_x_save; + } + } + else + { + const bool stop_on_x = BIT(mode0, 8); + const bool stop_on_y = BIT(mode0, 9); + const bool shade = BIT(mode0, 18); + const bool rgbmode = BIT(mode1, 15); + const bool opaque = BIT(mode0, 16) || BIT(mode0, 17); + const uint32_t pattern = BIT(mode0, 12) ? m_rex3.m_z_pattern : (BIT(mode0, 13) ? m_rex3.m_ls_pattern : 0xffffffff); + + if (BIT(mode0, 15) && (end_x - start_x) >= 32) + end_x = start_x + 32 * dx; + + uint32_t color = m_rex3.m_color_i; + if (BIT(mode1, 17)) + { + switch (m_rex3.m_plane_depth) + { + case 0: // 4bpp + color = m_rex3.m_color_vram & 0xf; + break; + case 1: // 8bpp + color = m_rex3.m_color_vram & 0xff; + break; + case 2: // 12bpp + color = ((m_rex3.m_color_vram & 0xf00000) >> 12) | ((m_rex3.m_color_vram & 0xf000) >> 8) | ((m_rex3.m_color_vram & 0xf0) >> 4); + break; + case 3: // 24bpp + color = m_rex3.m_color_vram & 0xffffff; + break; + } + } + + do + { + uint32_t bit = 31; + do + { + if (BIT(pattern, bit)) + { + if (shade || rgbmode) + write_pixel(start_x, start_y, get_rgb_color(start_x, start_y)); + else + write_pixel(start_x, start_y, color); + } + else if (opaque) + { + write_pixel(start_x, start_y, m_rex3.m_color_back); + } + + if (shade) + iterate_shade(); + + bit = (bit - 1) & 0x1f; + start_x += dx; + } while (start_x != end_x && stop_on_x); + + if (start_x == end_x) + { + start_x = m_rex3.m_x_save; + start_y += dy; + } + } while (start_y != end_y && stop_on_y); + } + + write_x_start(start_x << 11); + write_y_start(start_y << 11); break; - case 2: // 12bpp - color = ((m_rex3.m_color_vram & 0xf00000) >> 12) | ((m_rex3.m_color_vram & 0xf000) >> 8) | ((m_rex3.m_color_vram & 0xf0) >> 4); + + case 2: // I_Line + do_iline(m_rex3.m_color_i); break; - case 3: // 24bpp - color = m_rex3.m_color_vram & 0xffffff; + + case 3: // F_Line + do_fline(m_rex3.m_color_i); + break; + + case 4: // A_Line + do_iline(m_rex3.m_color_i); // FIXME + break; + + default: // Invalid break; } - } - LOGMASKED(LOG_COMMANDS, "%04x, %04x to %04x, %04x = %08x, %04x\n", start_x, start_y, end_x, end_y, m_cmap0.m_palette[color], m_rex3.m_x_save); - for (; start_y != end_y; start_y += dy) - { - for (; start_x != end_x; start_x += dx) + break; + case 3: // Scr2Scr + if (adrmode < 2) { - write_pixel(start_x, start_y, color); + const bool stop_on_x = BIT(mode0, 8); + const bool stop_on_y = BIT(mode0, 9); + + end_x += dx; + end_y += dy; + + LOGMASKED(LOG_COMMANDS, "%04x, %04x - %04x, %04x to %04x, %04x\n", start_x, start_y, end_x, end_y, start_x + m_rex3.m_x_move, start_y + m_rex3.m_y_move); + do + { + do + { + const uint32_t src_addr = (start_y + m_rex3.m_y_window - 0x1000) * (1280 + 64) + (start_x + m_rex3.m_x_window - 0x1000); + uint32_t src = 0; + switch (mode1 & 7) + { + case 1: // RGB/CI planes + src = m_rgbci[src_addr]; + break; + case 2: // RGBA planes (not yet implemented) + break; + case 4: // Overlay planes + src = m_olay[src_addr]; + break; + case 5: // Popup planes + src = m_pup[src_addr] >> 2; + break; + case 6: // CID planes + src = m_cid[src_addr]; + break; + default: + break; + } + write_pixel(start_x + m_rex3.m_x_move, start_y + m_rex3.m_y_move, src); + + start_x += dx; + } while (start_x != end_x && stop_on_x); + + if (start_x == end_x) + { + start_x = m_rex3.m_x_save; + start_y += dy; + } + } while (start_y != end_y && stop_on_y); + + write_x_start(start_x << 11); + write_y_start(start_y << 11); } - start_x = m_rex3.m_x_save; - } - - write_x_start(start_x << 11); - write_y_start(start_y << 11); - break; - } - case 0x00000327: // StopOnX, StopOnY, DoSetup, Block, Scr2Scr - { - end_x += dx; - end_y += dy; - LOGMASKED(LOG_COMMANDS, "%04x, %04x - %04x, %04x to %04x, %04x\n", start_x, start_y, end_x, end_y, start_x + m_rex3.m_x_move, start_y + m_rex3.m_y_move); - for (; start_y != end_y; start_y += dy) - { - for (; start_x != end_x; start_x += dx) - { - const uint32_t src_addr = (start_y + m_rex3.m_y_window - 0x1000) * (1280 + 64) + (start_x + m_rex3.m_x_window - 0x1000); - uint32_t src = 0; - switch (mode1 & 7) - { - case 1: // RGB/CI planes - src = m_rgbci[src_addr]; - break; - case 2: // RGBA planes (not yet implemented) - break; - case 4: // Overlay planes - src = m_olay[src_addr]; - break; - case 5: // Popup planes - src = m_pup[src_addr] >> 2; - break; - case 6: // CID planes - src = m_cid[src_addr]; - break; - default: - break; - } - write_pixel(start_x + m_rex3.m_x_move, start_y + m_rex3.m_y_move, src); - } - start_x = m_rex3.m_x_save; - } - write_x_start(start_x << 11); - write_y_start(start_y << 11); - break; - } - case 0x0000000a: // I_Line, Draw - case 0x0000032a: // StopOnX, StopOnY, DoSetup, I_Line, Draw - case 0x00000b2a: // SkipLast, StopOnX, StopOnY, DoSetup, I_Line, Draw - case 0x0000232e: // EnLSPattern, StopOnX, StopOnY, DoSetup, F_Line, Draw - case 0x0000930e: // Length32, EnZPattern, StopOnX, StopOnY, F_Line, Draw - case 0x0004930e: // Shade, Length32, EnZPattern, StopOnX, StopOnY, F_Line, Draw - case 0x0004232e: // Shade, EnLSPattern, StopOnX, StopOnY, DoSetup, F_Line, Draw - case 0x00200b2e: // CIClamp, SkipLast, StopOnX, StopOnY, DoSetup, F_Line, Draw - case 0x00442332: // EndFilter, Shade, EnLSPattern, StopOnX, StopOnY, DoSetp, A_Line, Draw - { - LOGMASKED(LOG_COMMANDS, "%cLine: %04x, %04x to %04x, %04x = %08x\n", ((mode0 & 0x1c) >> 2) == 3 ? 'F' : 'I', - start_x, start_y, end_x, end_y, m_rex3.m_color_i); - if (start_x == end_x && start_y == end_y) - write_pixel(m_rex3.m_color_i); - else if (((mode0 & 0x1c) >> 2) == 3) - do_fline(m_rex3.m_color_i); - else - do_iline(m_rex3.m_color_i); - break; - } - case 0x00001106: // EnZPattern, StopOnX, Block, Draw - case 0x00002106: // EnLSPattern, StopOnX, Block, Draw - case 0x00009106: // Length32, EnZPattern, StopOnX, Block, Draw - case 0x00022106: // LSOpaque, EnLSPattern, StopOnX, Block, Draw - case 0x00019106: // ZPOpaque, EnLSPattern, StopOnX, Block, Draw - case 0x002c9126: // CIClamp, LROnly, Shade, Length32, EnZPattern, StopOnX, DoSetup, Block, Draw - { - if (BIT(mode0, 19) && dx < 0) // LROnly - break; - - const bool opaque = BIT(mode0, 16) || BIT(mode0, 17); - const uint32_t pattern = BIT(mode0, 12) ? m_rex3.m_z_pattern : m_rex3.m_ls_pattern; - const bool shade = BIT(mode0, 18); - const bool rgbmode = BIT(mode1, 15); - LOGMASKED(LOG_COMMANDS, "%08x at %04x, %04x color %08x\n", pattern, start_x, start_y, m_rex3.m_color_i); - - end_x += dx; - - if (BIT(mode0, 15) && (end_x - start_x) >= 32) - end_x = start_x + 32 * dx; - - uint32_t bit = 31; - for (; start_x != end_x; start_x += dx) - { - if (BIT(pattern, bit)) - { - if (shade || rgbmode) - write_pixel(start_x, start_y, get_rgb_color(start_x, start_y)); - else - write_pixel(start_x, start_y, m_rex3.m_color_i); - } - else if (opaque) - { - write_pixel(start_x, start_y, m_rex3.m_color_back); - } - - if (shade) - iterate_shade(); - - bit = (bit - 1) & 0x1f; - } - start_y += dy; - - start_x = m_rex3.m_x_save; - write_x_start(start_x << 11); - write_y_start(start_y << 11); - break; - } - default: - LOGMASKED(LOG_COMMANDS | LOG_UNKNOWN, "Draw command %08x not recognized\n", m_rex3.m_draw_mode0); - break; + break; } } diff --git a/src/mame/drivers/indy_indigo2.cpp b/src/mame/drivers/indy_indigo2.cpp index 0c874c8d582..8814f4137a9 100644 --- a/src/mame/drivers/indy_indigo2.cpp +++ b/src/mame/drivers/indy_indigo2.cpp @@ -12,7 +12,7 @@ * Memory map: * * 00000000 - 0007ffff Alias for first 512kbyte of RAM -* 00080000 - 0008ffff EISA I/O space (pullups on Indy) +* 00080000 - 0008ffff EISA I/O space (VINO on Indy) * 00090000 - 0009ffff EISA I/O space Alias (pullups on Indy) * 000a0000 - 07ffffff EISA Memory * 08000000 - 17ffffff Low System Memory @@ -63,6 +63,7 @@ #include "machine/nscsi_cd.h" #include "machine/nscsi_hd.h" #include "machine/sgi.h" +#include "machine/vino.h" #include "sound/cdda.h" @@ -79,6 +80,7 @@ public: , m_mem_ctrl(*this, "memctrl") , m_scsi_ctrl(*this, "scsibus:0:wd33c93") , m_hpc3(*this, "hpc3") + , m_vino(*this, "vino") , m_gio(*this, "gio") , m_gio_gfx(*this, "gio_gfx") , m_gio_exp0(*this, "gio_exp0") @@ -93,11 +95,10 @@ public: protected: virtual void machine_reset() override; - DECLARE_READ32_MEMBER(eisa_io_r); - DECLARE_WRITE64_MEMBER(write_ram); void ip22_map(address_map &map); + void ip22_base_map(address_map &map); void wd33c93(device_t *device); @@ -108,6 +109,7 @@ protected: required_device m_mem_ctrl; required_device m_scsi_ctrl; required_device m_hpc3; + optional_device m_vino; optional_device m_gio; optional_device m_gio_gfx; optional_device m_gio_exp0; @@ -126,12 +128,16 @@ public: void ip244415(machine_config &config); private: + DECLARE_READ32_MEMBER(eisa_io_r); + void wd33c93_2(device_t *device); + void ip24_map(address_map &map); + required_device m_scsi_ctrl2; }; -READ32_MEMBER(ip22_state::eisa_io_r) +READ32_MEMBER(ip24_state::eisa_io_r) { return 0xffffffff; } @@ -155,10 +161,9 @@ WRITE64_MEMBER(ip22_state::write_ram) COMBINE_DATA(&m_mainram[offset]); } -void ip22_state::ip22_map(address_map &map) +void ip22_state::ip22_base_map(address_map &map) { map(0x00000000, 0x0007ffff).bankrw("bank1"); /* mirror of first 512k of main RAM */ - map(0x00080000, 0x0009ffff).r(FUNC(ip22_state::eisa_io_r)); map(0x08000000, 0x0fffffff).share("mainram").ram().w(FUNC(ip22_state::write_ram)); /* 128 MB of main RAM */ map(0x1f000000, 0x1f9fffff).rw(m_gio, FUNC(gio_device::read), FUNC(gio_device::write)); map(0x1fa00000, 0x1fa1ffff).rw(m_mem_ctrl, FUNC(sgi_mc_device::read), FUNC(sgi_mc_device::write)); @@ -167,6 +172,18 @@ void ip22_state::ip22_map(address_map &map) map(0x20000000, 0x27ffffff).share("mainram").ram().w(FUNC(ip22_state::write_ram)); } +void ip22_state::ip22_map(address_map &map) +{ + ip22_base_map(map); + map(0x00080000, 0x0009ffff).rw(m_vino, FUNC(vino_device::read), FUNC(vino_device::write)); +} + +void ip24_state::ip24_map(address_map &map) +{ + ip22_base_map(map); + map(0x00080000, 0x0009ffff).r(FUNC(ip24_state::eisa_io_r)); +} + void ip22_state::machine_reset() { // set up low RAM mirror @@ -236,6 +253,8 @@ void ip22_state::ip225015(machine_config &config) m_maincpu->set_addrmap(AS_PROGRAM, &ip22_state::ip22_map); SGI_HPC3(config, m_hpc3, m_maincpu, m_scsi_ctrl); + + VINO(config, m_vino); } void ip22_state::ip224613(machine_config &config) @@ -248,6 +267,8 @@ void ip22_state::ip224613(machine_config &config) m_maincpu->set_addrmap(AS_PROGRAM, &ip22_state::ip22_map); SGI_HPC3(config, m_hpc3, m_maincpu, m_scsi_ctrl); + + VINO(config, m_vino); } void ip24_state::wd33c93_2(device_t *device) @@ -264,7 +285,7 @@ void ip24_state::ip244415(machine_config &config) R4400(config, m_maincpu, 50000000*3); //m_maincpu->set_icache_size(32768); //m_maincpu->set_dcache_size(32768); - m_maincpu->set_addrmap(AS_PROGRAM, &ip24_state::ip22_map); + m_maincpu->set_addrmap(AS_PROGRAM, &ip24_state::ip24_map); NSCSI_BUS(config, "scsibus2", 0); NSCSI_CONNECTOR(config, "scsibus2:0").option_set("wd33c93", WD33C93B) diff --git a/src/mame/machine/hpc3.cpp b/src/mame/machine/hpc3.cpp index 715fda748c9..8cc75dfa594 100644 --- a/src/mame/machine/hpc3.cpp +++ b/src/mame/machine/hpc3.cpp @@ -40,10 +40,13 @@ hpc3_device::hpc3_device(const machine_config &mconfig, const char *tag, device_ void hpc3_device::device_start() { + save_item(NAME(m_intstat)); save_item(NAME(m_enetr_nbdp)); save_item(NAME(m_enetr_cbp)); save_item(NAME(m_cpu_aux_ctrl)); save_item(NAME(m_pio_config)); + save_item(NAME(m_volume_l)); + save_item(NAME(m_volume_r)); for (uint32_t i = 0; i < 2; i++) { @@ -130,12 +133,15 @@ void hpc3_device::map(address_map &map) { map(0x00000000, 0x0000ffff).rw(FUNC(hpc3_device::pbusdma_r), FUNC(hpc3_device::pbusdma_w)); map(0x00010000, 0x0001ffff).rw(FUNC(hpc3_device::hd_enet_r), FUNC(hpc3_device::hd_enet_w)); + map(0x00030000, 0x00030003).r(FUNC(hpc3_device::intstat_r)); map(0x00030008, 0x0003000b).rw(FUNC(hpc3_device::eeprom_r), FUNC(hpc3_device::eeprom_w)); + map(0x0003000c, 0x0003000f).r(FUNC(hpc3_device::intstat_r)); map(0x00040000, 0x00047fff).rw(FUNC(hpc3_device::hd_r<0>), FUNC(hpc3_device::hd_w<0>)); map(0x00048000, 0x0004ffff).rw(FUNC(hpc3_device::hd_r<1>), FUNC(hpc3_device::hd_w<1>)); map(0x00054000, 0x000544ff).rw(FUNC(hpc3_device::enet_r), FUNC(hpc3_device::enet_w)); map(0x00058000, 0x000583ff).rw(m_hal2, FUNC(hal2_device::read), FUNC(hal2_device::write)); map(0x00058400, 0x000587ff).ram(); // hack + map(0x00058800, 0x00058807).rw(FUNC(hpc3_device::volume_r), FUNC(hpc3_device::volume_w)); map(0x00059000, 0x000593ff).rw(FUNC(hpc3_device::pbus4_r), FUNC(hpc3_device::pbus4_w)); map(0x00059800, 0x00059bff).rw(m_ioc2, FUNC(ioc2_device::read), FUNC(ioc2_device::write)); map(0x0005c000, 0x0005cfff).rw(FUNC(hpc3_device::dma_config_r), FUNC(hpc3_device::dma_config_w)); @@ -147,12 +153,12 @@ void hpc3_device::device_timer(emu_timer &timer, device_timer_id id, int param, { switch (id) { + case TIMER_PBUS_DMA+0: case TIMER_PBUS_DMA+1: case TIMER_PBUS_DMA+2: + case TIMER_PBUS_DMA+3: do_pbus_dma(id - TIMER_PBUS_DMA); break; - case TIMER_PBUS_DMA+0: - case TIMER_PBUS_DMA+3: case TIMER_PBUS_DMA+4: case TIMER_PBUS_DMA+5: case TIMER_PBUS_DMA+6: @@ -168,14 +174,14 @@ void hpc3_device::do_pbus_dma(uint32_t channel) { pbus_dma_t &dma = m_pbus_dma[channel]; - if (dma.m_active && (channel == 1 || channel == 2)) + if (dma.m_active && channel < 4) { uint16_t temp16 = m_cpu_space->read_dword(dma.m_cur_ptr) >> 16; int16_t stemp16 = (int16_t)((temp16 >> 8) | (temp16 << 8)); if (channel == 1) m_ldac->write(stemp16); - else + else if (channel == 2) m_rdac->write(stemp16); dma.m_cur_ptr += 4; @@ -354,6 +360,28 @@ WRITE32_MEMBER(hpc3_device::hd_w) } } +READ32_MEMBER(hpc3_device::volume_r) +{ + if (offset == 0) + return m_volume_r; + else + return m_volume_l; +} + +WRITE32_MEMBER(hpc3_device::volume_w) +{ + if (offset == 0) + { + m_volume_r = (uint8_t)data; + m_rdac->set_output_gain(ALL_OUTPUTS, m_volume_r / 255.0f); + } + else + { + m_volume_l = (uint8_t)data; + m_ldac->set_output_gain(ALL_OUTPUTS, m_volume_l / 255.0f); + } +} + template READ32_MEMBER(hpc3_device::hd_r<0>); template READ32_MEMBER(hpc3_device::hd_r<1>); template WRITE32_MEMBER(hpc3_device::hd_w<0>); @@ -825,15 +853,14 @@ WRITE_LINE_MEMBER(hpc3_device::scsi0_irq) if (state) { LOGMASKED(LOG_SCSI_IRQ, "Raising SCSI 0 IRQ\n"); - //if (m_wd33c93->get_dma_count() && m_scsi_dma[0].m_active) - // scsi_dma(0); - m_ioc2->raise_local_irq(0, ioc2_device::INT3_LOCAL0_SCSI0); + m_intstat |= 0x100; } else { LOGMASKED(LOG_SCSI_IRQ, "Lowering SCSI 0 IRQ\n"); m_ioc2->lower_local_irq(0, ioc2_device::INT3_LOCAL0_SCSI0); + m_intstat &= ~0x100; } } @@ -842,20 +869,22 @@ WRITE_LINE_MEMBER(hpc3_device::scsi1_irq) if (state) { LOGMASKED(LOG_SCSI_IRQ, "Raising SCSI 1 IRQ\n"); - - //if (m_wd33c93_2->get_dma_count() && m_scsi_dma[1].m_active) - // scsi_dma(1); - m_ioc2->raise_local_irq(0, ioc2_device::INT3_LOCAL0_SCSI1); + m_intstat |= 0x200; } else { LOGMASKED(LOG_SCSI_IRQ, "Lowering SCSI 0 IRQ\n"); - m_ioc2->lower_local_irq(0, ioc2_device::INT3_LOCAL0_SCSI1); + m_intstat &= ~0x200; } } +READ32_MEMBER(hpc3_device::intstat_r) +{ + return m_intstat; +} + READ32_MEMBER(hpc3_device::eeprom_r) { // Disabled - we don't have a dump from real hardware, and IRIX 5.x freaks out with default contents. diff --git a/src/mame/machine/hpc3.h b/src/mame/machine/hpc3.h index 10c658bd362..be4bee3da6a 100644 --- a/src/mame/machine/hpc3.h +++ b/src/mame/machine/hpc3.h @@ -62,8 +62,11 @@ protected: DECLARE_WRITE32_MEMBER(hd_enet_w); template DECLARE_READ32_MEMBER(hd_r); template DECLARE_WRITE32_MEMBER(hd_w); + DECLARE_READ32_MEMBER(intstat_r); DECLARE_READ32_MEMBER(eeprom_r); DECLARE_WRITE32_MEMBER(eeprom_w); + DECLARE_READ32_MEMBER(volume_r); + DECLARE_WRITE32_MEMBER(volume_w); DECLARE_READ32_MEMBER(pbus4_r); DECLARE_WRITE32_MEMBER(pbus4_w); DECLARE_READ32_MEMBER(pbusdma_r); @@ -141,9 +144,12 @@ protected: required_device m_ldac; required_device m_rdac; + uint32_t m_intstat; uint32_t m_enetr_nbdp; uint32_t m_enetr_cbp; uint32_t m_cpu_aux_ctrl; + uint8_t m_volume_l; + uint8_t m_volume_r; struct scsi_dma_t { diff --git a/src/mame/machine/vino.cpp b/src/mame/machine/vino.cpp new file mode 100644 index 00000000000..af88fa129fc --- /dev/null +++ b/src/mame/machine/vino.cpp @@ -0,0 +1,400 @@ +// license:BSD-3-Clause +// copyright-holders:Ryan Holtz +/********************************************************************* + + vino.c + + Silicon Graphics VINO (Video-In, No Out) controller emulation + +*********************************************************************/ + +#include "emu.h" +#include "vino.h" + +#define LOG_UNKNOWN (1 << 0) +#define LOG_READS (1 << 1) +#define LOG_WRITES (1 << 2) +#define LOG_DEFAULT (LOG_READS | LOG_WRITES | LOG_UNKNOWN) + +#define VERBOSE (LOG_DEFAULT) +#include "logmacro.h" + +DEFINE_DEVICE_TYPE(VINO, vino_device, "vino", "SGI VINO Controller") + +vino_device::vino_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) + : device_t(mconfig, VINO, tag, owner, clock) +{ +} + +//------------------------------------------------- +// device_start - device-specific startup +//------------------------------------------------- + +void vino_device::device_start() +{ + save_item(NAME(m_rev_id)); + save_item(NAME(m_control)); + save_item(NAME(m_int_status)); + save_item(NAME(m_i2c_ctrl)); + save_item(NAME(m_i2c_data)); + + for (uint32_t i = CHAN_A; i < CHAN_COUNT; i++) + { + save_item(NAME(m_channels[i].m_alpha), i); + save_item(NAME(m_channels[i].m_clip_start), i); + save_item(NAME(m_channels[i].m_clip_end), i); + save_item(NAME(m_channels[i].m_frame_rate), i); + save_item(NAME(m_channels[i].m_field_counter), i); + save_item(NAME(m_channels[i].m_line_size), i); + save_item(NAME(m_channels[i].m_line_counter), i); + save_item(NAME(m_channels[i].m_page_index), i); + save_item(NAME(m_channels[i].m_next_desc_ptr), i); + save_item(NAME(m_channels[i].m_start_desc_ptr), i); + save_item(NAME(m_channels[i].m_descriptors[0]), i); + save_item(NAME(m_channels[i].m_descriptors[1]), i); + save_item(NAME(m_channels[i].m_descriptors[2]), i); + save_item(NAME(m_channels[i].m_descriptors[3]), i); + save_item(NAME(m_channels[i].m_fifo_threshold), i); + save_item(NAME(m_channels[i].m_fifo_gio_ptr), i); + save_item(NAME(m_channels[i].m_fifo_video_ptr), i); + } +} + +void vino_device::device_reset() +{ + m_rev_id = 0xb0; + m_control = 0; + m_int_status = 0; + + for (uint32_t i = CHAN_A; i < CHAN_COUNT; i++) + { + m_channels[i].m_field_counter = 0; + m_channels[i].m_line_size = 0; + m_channels[i].m_line_counter = 0; + m_channels[i].m_page_index = 0; + m_channels[i].m_next_desc_ptr = 0; + m_channels[i].m_start_desc_ptr = 0; + for (uint32_t j = 0; j < 4; j++) + { + m_channels[i].m_descriptors[j] = DESC_VALID_BIT; + } + } +} + +READ32_MEMBER(vino_device::read) +{ + switch (offset & ~1) + { + case 0x0000/4: // Rev/ID + LOGMASKED(LOG_READS, "%s: Rev/ID read: %08x & %08x\n", machine().describe_context(), m_rev_id, mem_mask); + return m_rev_id; + case 0x0008/4: // Control + LOGMASKED(LOG_READS, "%s: Control read: %08x & %08x\n", machine().describe_context(), m_control, mem_mask); + return m_control; + case 0x0010/4: // Interrupt Status + LOGMASKED(LOG_READS, "%s: Interrupt Status read: %08x & %08x\n", machine().describe_context(), m_int_status, mem_mask); + return m_int_status; + case 0x0018/4: // I2C Control + LOGMASKED(LOG_READS, "%s: I2C Control read: %08x & %08x\n", machine().describe_context(), m_i2c_ctrl, mem_mask); + return m_i2c_ctrl; + case 0x0020/4: // I2C Data + LOGMASKED(LOG_READS, "%s: I2C Data read: %08x & %08x\n", machine().describe_context(), m_i2c_data, mem_mask); + return m_i2c_data; + case 0x0028/4: // ChA Alpha + case 0x00b0/4: // ChB ... + { + const uint32_t channel = (offset < 0x00b0/4) ? 0 : 1; + LOGMASKED(LOG_READS, "%s: Ch%c Alpha read: %08x & %08x\n", machine().describe_context(), channel ? 'B' : 'A', m_channels[channel].m_alpha, mem_mask); + return m_channels[channel].m_alpha; + } + case 0x0030/4: // ChA Clipping Start + case 0x00b8/4: // ChB ... + { + const uint32_t channel = (offset < 0x00b0/4) ? 0 : 1; + LOGMASKED(LOG_READS, "%s: Ch%c Clipping Start read: %08x & %08x\n", machine().describe_context(), channel ? 'B' : 'A', m_channels[channel].m_clip_start, mem_mask); + return m_channels[channel].m_clip_start; + } + case 0x0038/4: // ChA Clipping End + case 0x00c0/4: // ChB ... + { + const uint32_t channel = (offset < 0x00b0/4) ? 0 : 1; + LOGMASKED(LOG_READS, "%s: Ch%c Clipping End read: %08x & %08x\n", machine().describe_context(), channel ? 'B' : 'A', m_channels[channel].m_clip_end, mem_mask); + return m_channels[channel].m_clip_end; + } + case 0x0040/4: // ChA Frame Rate + case 0x00c8/4: // ChB ... + { + const uint32_t channel = (offset < 0x00b0/4) ? 0 : 1; + LOGMASKED(LOG_READS, "%s: Ch%c Frame Rate read: %08x & %08x\n", machine().describe_context(), channel ? 'B' : 'A', m_channels[channel].m_frame_rate, mem_mask); + return m_channels[channel].m_frame_rate; + } + case 0x0048/4: // ChA Field Counter + case 0x00d0/4: // ChB ... + { + const uint32_t channel = (offset < 0x00b0/4) ? 0 : 1; + LOGMASKED(LOG_READS, "%s: Ch%c Field Counter read: %08x & %08x\n", machine().describe_context(), channel ? 'B' : 'A', m_channels[channel].m_field_counter, mem_mask); + return m_channels[channel].m_field_counter; + } + case 0x0050/4: // ChA Line Size + case 0x00d8/4: // ChB ... + { + const uint32_t channel = (offset < 0x00b0/4) ? 0 : 1; + LOGMASKED(LOG_READS, "%s: Ch%c Line Size read: %08x & %08x\n", machine().describe_context(), channel ? 'B' : 'A', m_channels[channel].m_line_size, mem_mask); + return m_channels[channel].m_line_size; + } + case 0x0058/4: // ChA Line Counter + case 0x00e0/4: // ChB ... + { + const uint32_t channel = (offset < 0x00b0/4) ? 0 : 1; + LOGMASKED(LOG_READS, "%s: Ch%c Line Counter read: %08x & %08x\n", machine().describe_context(), channel ? 'B' : 'A', m_channels[channel].m_line_counter, mem_mask); + return m_channels[channel].m_line_counter; + } + case 0x0060/4: // ChA Page Index + case 0x00e8/4: // ChB ... + { + const uint32_t channel = (offset < 0x00b0/4) ? 0 : 1; + LOGMASKED(LOG_READS, "%s: Ch%c Page Index read: %08x & %08x\n", machine().describe_context(), channel ? 'B' : 'A', m_channels[channel].m_page_index, mem_mask); + return m_channels[channel].m_page_index; + } + case 0x0068/4: // ChA Pointer to Next Four Descriptors + case 0x00f0/4: // ChB ... + { + const uint32_t channel = (offset < 0x00b0/4) ? 0 : 1; + LOGMASKED(LOG_READS, "%s: Ch%c Pointer to Next Four Descriptors read: %08x & %08x\n", machine().describe_context(), channel ? 'B' : 'A', m_channels[channel].m_next_desc_ptr, mem_mask); + return m_channels[channel].m_next_desc_ptr; + } + case 0x0070/4: // ChA Pointer to Start of Descriptor Table + case 0x00f8/4: // ChB ... + { + const uint32_t channel = (offset < 0x00b0/4) ? 0 : 1; + LOGMASKED(LOG_READS, "%s: Ch%c Pointer to Start of Descriptor Table read: %08x & %08x\n", machine().describe_context(), channel ? 'B' : 'A', m_channels[channel].m_start_desc_ptr, mem_mask); + return m_channels[channel].m_start_desc_ptr; + } + case 0x0078/4: // ChA Descriptor 0 + case 0x0100/4: // ChB ... + { + const uint32_t channel = (offset < 0x00b0/4) ? 0 : 1; + LOGMASKED(LOG_READS, "%s: Ch%c Descriptor 0 Data read: %08x & %08x\n", machine().describe_context(), channel ? 'B' : 'A', m_channels[channel].m_descriptors[0], mem_mask); + return m_channels[channel].m_descriptors[0]; + } + case 0x0080/4: // ChA Descriptor 1 + case 0x0108/4: // ChB ... + { + const uint32_t channel = (offset < 0x00b0/4) ? 0 : 1; + LOGMASKED(LOG_READS, "%s: Ch%c Descriptor 1 Data read: %08x & %08x\n", machine().describe_context(), channel ? 'B' : 'A', m_channels[channel].m_descriptors[1], mem_mask); + return m_channels[channel].m_descriptors[1]; + } + case 0x0088/4: // ChA Descriptor 2 + case 0x0110/4: // ChB ... + { + const uint32_t channel = (offset < 0x00b0/4) ? 0 : 1; + LOGMASKED(LOG_READS, "%s: Ch%c Descriptor 2 Data read: %08x & %08x\n", machine().describe_context(), channel ? 'B' : 'A', m_channels[channel].m_descriptors[2], mem_mask); + return m_channels[channel].m_descriptors[2]; + } + case 0x0090/4: // ChA Descriptor 3 + case 0x0118/4: // ChB ... + { + const uint32_t channel = (offset < 0x00b0/4) ? 0 : 1; + LOGMASKED(LOG_READS, "%s: Ch%c Descriptor 3 Data read: %08x & %08x\n", machine().describe_context(), channel ? 'B' : 'A', m_channels[channel].m_descriptors[3], mem_mask); + return m_channels[channel].m_descriptors[3]; + } + case 0x0098/4: // ChA FIFO Threshold + case 0x0120/4: // ChB ... + { + const uint32_t channel = (offset < 0x00b0/4) ? 0 : 1; + LOGMASKED(LOG_READS, "%s: Ch%c FIFO Threshold read: %08x & %08x\n", machine().describe_context(), channel ? 'B' : 'A', m_channels[channel].m_fifo_threshold, mem_mask); + return m_channels[channel].m_fifo_threshold; + } + case 0x00a0/4: // ChA FIFO Read Pointer + case 0x0128/4: // ChB ... + { + const uint32_t channel = (offset < 0x00b0/4) ? 0 : 1; + LOGMASKED(LOG_READS, "%s: Ch%c FIFO Read Pointer read: %08x & %08x\n", machine().describe_context(), channel ? 'B' : 'A', m_channels[channel].m_fifo_gio_ptr, mem_mask); + return m_channels[channel].m_fifo_gio_ptr; + } + case 0x00a8/4: // ChA FIFO Write Pointer + case 0x0130/4: // ChB ... + { + const uint32_t channel = (offset < 0x00b0/4) ? 0 : 1; + LOGMASKED(LOG_READS, "%s: Ch%c FIFO Write Pointer read: %08x & %08x\n", machine().describe_context(), channel ? 'B' : 'A', m_channels[channel].m_fifo_video_ptr, mem_mask); + return m_channels[channel].m_fifo_video_ptr; + } + default: + LOGMASKED(LOG_READS | LOG_UNKNOWN, "%s: Unknown VINO read: %08x & %08x\n", machine().describe_context(), 0x00080000 + offset*4, mem_mask); + return 0; + } + return 0; +} + +WRITE32_MEMBER(vino_device::write) +{ + switch (offset & ~1) + { + case 0x0000/4: // Rev/ID + LOGMASKED(LOG_WRITES, "%s: Rev/ID write (ignored): %08x & %08x\n", machine().describe_context(), data, mem_mask); + break; + case 0x0008/4: // Control + LOGMASKED(LOG_WRITES, "%s: Control write: %08x & %08x\n", machine().describe_context(), data, mem_mask); + m_control = data & CTRL_MASK; + break; + case 0x0010/4: // Interrupt Status + LOGMASKED(LOG_WRITES, "%s: Interrupt Status write: %08x & %08x\n", machine().describe_context(), data, mem_mask); + for (uint32_t i = 0; i < 6; i++) + { + if (!BIT(data, i)) + { + m_int_status &= ~(1 << i); + } + } + // TODO: Handle interrupt all-clear + break; + case 0x0018/4: // I2C Control + LOGMASKED(LOG_WRITES, "%s: I2C Control write: %08x & %08x\n", machine().describe_context(), data, mem_mask); + m_i2c_ctrl = data & I2C_CTRL_MASK; + break; + case 0x0020/4: // I2C Data + LOGMASKED(LOG_WRITES, "%s: I2C Data write: %08x & %08x\n", machine().describe_context(), data, mem_mask); + m_i2c_data = data & I2C_DATA_MASK; + break; + case 0x0028/4: // ChA Alpha + case 0x00b0/4: // ChB ... + { + const uint32_t channel = (offset < 0x00b0/4) ? 0 : 1; + LOGMASKED(LOG_WRITES, "%s: Ch%c Alpha write: %08x & %08x\n", machine().describe_context(), channel ? 'B' : 'A', data, mem_mask); + m_channels[channel].m_alpha = data & ALPHA_MASK; + break; + } + case 0x0030/4: // ChA Clipping Start + case 0x00b8/4: // ChB ... + { + const uint32_t channel = (offset < 0x00b0/4) ? 0 : 1; + LOGMASKED(LOG_WRITES, "%s: Ch%c Clipping Start write: %08x & %08x\n", machine().describe_context(), channel ? 'B' : 'A', data, mem_mask); + m_channels[channel].m_clip_start = data & CLIP_REG_MASK; + break; + } + case 0x0038/4: // ChA Clipping End + case 0x00c0/4: // ChB ... + { + const uint32_t channel = (offset < 0x00b0/4) ? 0 : 1; + LOGMASKED(LOG_WRITES, "%s: Ch%c Clipping End write: %08x & %08x\n", machine().describe_context(), channel ? 'B' : 'A', data, mem_mask); + m_channels[channel].m_clip_end = data & CLIP_REG_MASK; + break; + } + case 0x0040/4: // ChA Frame Rate + case 0x00c8/4: // ChB ... + { + const uint32_t channel = (offset < 0x00b0/4) ? 0 : 1; + LOGMASKED(LOG_WRITES, "%s: Ch%c Frame Rate write: %08x & %08x\n", machine().describe_context(), channel ? 'B' : 'A', data, mem_mask); + m_channels[channel].m_frame_rate = data & FRAME_RATE_REG_MASK; + break; + } + case 0x0048/4: // ChA Field Counter + case 0x00d0/4: // ChB ... + { + const uint32_t channel = (offset < 0x00b0/4) ? 0 : 1; + LOGMASKED(LOG_WRITES, "%s: Ch%c Field Counter write (ignored): %08x & %08x\n", machine().describe_context(), channel ? 'B' : 'A', data, mem_mask); + break; + } + case 0x0050/4: // ChA Line Size + case 0x00d8/4: // ChB ... + { + const uint32_t channel = (offset < 0x00b0/4) ? 0 : 1; + LOGMASKED(LOG_WRITES, "%s: Ch%c Line Size write: %08x & %08x\n", machine().describe_context(), channel ? 'B' : 'A', data, mem_mask); + m_channels[channel].m_line_size = data & LINE_SIZE_MASK; + break; + } + case 0x0058/4: // ChA Line Counter + case 0x00e0/4: // ChB ... + { + const uint32_t channel = (offset < 0x00b0/4) ? 0 : 1; + LOGMASKED(LOG_WRITES, "%s: Ch%c Line Counter write: %08x & %08x\n", machine().describe_context(), channel ? 'B' : 'A', data, mem_mask); + m_channels[channel].m_line_counter = data & LINE_COUNTER_MASK; + break; + } + case 0x0060/4: // ChA Page Index + case 0x00e8/4: // ChB ... + { + const uint32_t channel = (offset < 0x00b0/4) ? 0 : 1; + LOGMASKED(LOG_WRITES, "%s: Ch%c Page Index write: %08x & %08x\n", machine().describe_context(), channel ? 'B' : 'A', data, mem_mask); + m_channels[channel].m_page_index = data & PAGE_INDEX_MASK; + break; + } + case 0x0068/4: // ChA Pointer to Next Four Descriptors + case 0x00f0/4: // ChB ... + { + const uint32_t channel = (offset < 0x00b0/4) ? 0 : 1; + LOGMASKED(LOG_WRITES, "%s: Ch%c Pointer to Next Four Descriptors write: %08x & %08x\n", machine().describe_context(), channel ? 'B' : 'A', data, mem_mask); + m_channels[channel].m_next_desc_ptr = data & DESC_PTR_MASK; + break; + } + case 0x0070/4: // ChA Pointer to Start of Descriptor Table + case 0x00f8/4: // ChB ... + { + const uint32_t channel = (offset < 0x00b0/4) ? 0 : 1; + LOGMASKED(LOG_WRITES, "%s: Ch%c Pointer to Start of Descriptor Table write: %08x & %08x\n", machine().describe_context(), channel ? 'B' : 'A', data, mem_mask); + m_channels[channel].m_start_desc_ptr = data & DESC_PTR_MASK; + break; + } + case 0x0078/4: // ChA Descriptor 0 + case 0x0100/4: // ChB ... + { + const uint32_t channel = (offset < 0x00b0/4) ? 0 : 1; + LOGMASKED(LOG_WRITES, "%s: Ch%c Descriptor 0 Data write: %08x & %08x\n", machine().describe_context(), channel ? 'B' : 'A', data, mem_mask); + m_channels[channel].m_descriptors[0] = (data & DESC_PTR_MASK); + m_channels[channel].m_descriptors[0] |= DESC_VALID_BIT; // TODO: Unsure if this is right + break; + } + case 0x0080/4: // ChA Descriptor 1 + case 0x0108/4: // ChB ... + { + const uint32_t channel = (offset < 0x00b0/4) ? 0 : 1; + LOGMASKED(LOG_WRITES, "%s: Ch%c Descriptor 1 Data write: %08x & %08x\n", machine().describe_context(), channel ? 'B' : 'A', data, mem_mask); + m_channels[channel].m_descriptors[1] = (data & DESC_PTR_MASK); + m_channels[channel].m_descriptors[1] |= DESC_VALID_BIT; // TODO: Unsure if this is right + break; + } + case 0x0088/4: // ChA Descriptor 2 + case 0x0110/4: // ChB ... + { + const uint32_t channel = (offset < 0x00b0/4) ? 0 : 1; + LOGMASKED(LOG_WRITES, "%s: Ch%c Descriptor 2 Data write: %08x & %08x\n", machine().describe_context(), channel ? 'B' : 'A', data, mem_mask); + m_channels[channel].m_descriptors[2] = (data & DESC_PTR_MASK); + m_channels[channel].m_descriptors[2] |= DESC_VALID_BIT; // TODO: Unsure if this is right + break; + } + case 0x0090/4: // ChA Descriptor 3 + case 0x0118/4: // ChB ... + { + const uint32_t channel = (offset < 0x00b0/4) ? 0 : 1; + LOGMASKED(LOG_WRITES, "%s: Ch%c Descriptor 3 Data write: %08x & %08x\n", machine().describe_context(), channel ? 'B' : 'A', data, mem_mask); + m_channels[channel].m_descriptors[3] = (data & DESC_PTR_MASK); + m_channels[channel].m_descriptors[3] |= DESC_VALID_BIT; // TODO: Unsure if this is right + break; + } + case 0x0098/4: // ChA FIFO Threshold + case 0x0120/4: // ChB ... + { + const uint32_t channel = (offset < 0x00b0/4) ? 0 : 1; + LOGMASKED(LOG_WRITES, "%s: Ch%c FIFO Threshold write: %08x & %08x\n", machine().describe_context(), channel ? 'B' : 'A', data, mem_mask); + m_channels[channel].m_fifo_threshold = data & FIFO_MASK; + break; + } + case 0x00a0/4: // ChA FIFO Read Pointer + case 0x0128/4: // ChB ... + { + const uint32_t channel = (offset < 0x00b0/4) ? 0 : 1; + LOGMASKED(LOG_WRITES, "%s: Ch%c FIFO Read Pointer write (ignored): %08x & %08x\n", machine().describe_context(), channel ? 'B' : 'A', data, mem_mask); + break; + } + case 0x00a8/4: // ChA FIFO Write Pointer + case 0x0130/4: // ChB ... + { + const uint32_t channel = (offset < 0x00b0/4) ? 0 : 1; + LOGMASKED(LOG_WRITES, "%s: Ch%c FIFO Write Pointer write (ignored): %08x & %08x\n", machine().describe_context(), channel ? 'B' : 'A', data, mem_mask); + break; + } + default: + LOGMASKED(LOG_WRITES | LOG_UNKNOWN, "%s: Unknown VINO write: %08x = %08x & %08x\n", machine().describe_context(), 0x00080000 + offset*4, data, mem_mask); + break; + } +} diff --git a/src/mame/machine/vino.h b/src/mame/machine/vino.h new file mode 100644 index 00000000000..0280e8d6ae2 --- /dev/null +++ b/src/mame/machine/vino.h @@ -0,0 +1,162 @@ +// license:BSD-3-Clause +// copyright-holders:Ryan Holtz +/********************************************************************* + + vino.h + + Silicon Graphics VINO (Video-In, No Out) controller emulation + +*********************************************************************/ + +#ifndef MAME_MACHINE_VINO_H +#define MAME_MACHINE_VINO_H + +#pragma once + +class vino_device : public device_t +{ +public: + vino_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock = 0U); + + DECLARE_READ32_MEMBER(read); + DECLARE_WRITE32_MEMBER(write); + +protected: + // device-level overrides + virtual void device_start() override; + virtual void device_reset() override; + +private: + enum channel_num_t : uint32_t + { + CHAN_A, + CHAN_B, + CHAN_COUNT + }; + + enum + { + CTRL_MASK = 0x7fffffff, + + CTRL_ENDIAN_BIG = (0 << 0), + CTRL_ENDIAN_LITTLE = (1 << 0), + + CTRL_CHA_FIELD_INT_EN = (1 << 1), + CTRL_CHA_FIFO_INT_EN = (1 << 2), + CTRL_CHA_DESC_INT_EN = (1 << 3), + + CTRL_CHB_FIELD_INT_EN = (1 << 4), + CTRL_CHB_FIFO_INT_EN = (1 << 5), + CTRL_CHB_DESC_INT_EN = (1 << 6), + + CTRL_CHA_DMA_EN = (1 << 7), + CTRL_CHA_INTERLEAVE_EN = (1 << 8), + CTRL_CHA_SYNC_EN = (1 << 9), + CTRL_CHA_SELECT_PHILIPS = (0 << 10), + CTRL_CHA_SELECT_D1 = (1 << 10), + CTRL_CHA_COLOR_SPACE_YUV = (0 << 11), + CTRL_CHA_COLOR_SPACE_RGB = (1 << 11), + CTRL_CHA_LUMA_ONLY = (1 << 12), + CTRL_CHA_DECIMATE_EN = (1 << 13), + CTRL_CHA_DECIMATION_SHIFT = 14, + CTRL_CHA_DECIMATION_MASK = 0x7, + CTRL_CHA_DECIMATE_HORIZ_EN = (1 << 17), + CTRL_CHA_DITHER_EN = (1 << 18), + + CTRL_CHB_DMA_EN = (1 << 19), + CTRL_CHB_INTERLEAVE_EN = (1 << 20), + CTRL_CHB_SYNC_EN = (1 << 21), + CTRL_CHB_SELECT_PHILIPS = (0 << 22), + CTRL_CHB_SELECT_D1 = (1 << 22), + CTRL_CHB_COLOR_SPACE_YUV = (0 << 23), + CTRL_CHB_COLOR_SPACE_RGB = (1 << 23), + CTRL_CHB_LUMA_ONLY = (1 << 24), + CTRL_CHB_DECIMATE_EN = (1 << 25), + CTRL_CHB_DECIMATION_SHIFT = 26, + CTRL_CHB_DECIMATION_MASK = 0x7, + CTRL_CHB_DECIMATE_HORIZ_EN = (1 << 29), + CTRL_CHB_DITHER_EN = (1 << 30), + + ISR_CHA_EOF = (1 << 0), + ISR_CHA_FIFO = (1 << 1), + ISR_CHA_DESC = (1 << 2), + ISR_CHB_EOF = (1 << 3), + ISR_CHB_FIFO = (1 << 4), + ISR_CHB_DESC = (1 << 5), + + ALPHA_MASK = 0xff, + + CLIP_X_SHIFT = 0, + CLIP_X_MASK = 0x03ff, + CLIP_YODD_SHIFT = 10, + CLIP_YODD_MASK = 0x01ff, + CLIP_YEVEN_SHIFT = 19, + CLIP_YEVEN_MASK = 0x01ff, + CLIP_REG_MASK = (CLIP_X_MASK << CLIP_X_SHIFT) | (CLIP_YODD_MASK << CLIP_YODD_SHIFT) | (CLIP_YEVEN_MASK << CLIP_YEVEN_SHIFT), + + FRAME_RATE_NTSC = (0 << 0), + FRAME_RATE_PAL = (1 << 0), + FRAME_RATE_SHIFT = 1, + FRAME_RATE_MASK = 0x0fff, + FRAME_RATE_REG_MASK = 0x1fff, + + FIELD_COUNTER_MASK = 0xffff, + LINE_SIZE_MASK = 0x0ff8, + LINE_COUNTER_MASK = 0x0ff8, + PAGE_INDEX_MASK = 0x0ff8, + + DESC_PTR_MASK = 0xfffffff0, + + DESC_VALID_BIT = (1ULL << 32), + DESC_STOP_BIT = (1ULL << 31), + DESC_JUMP_BIT = (1ULL << 30), + DESC_DATA_MASK = 0x00000000ffffffffULL, + + FIFO_MASK = 0x03f8, + + I2C_CTRL_IDLE = (0 << 0), + I2C_CTRL_BUSY = (1 << 0), + I2C_CTRL_FORCE_IDLE = (0 << 0), + I2C_BUS_DIR_WRITE = (0 << 1), + I2C_BUS_DIR_READ = (1 << 1), + I2C_LAST_RELEASE = (0 << 2), + I2C_LAST_HOLD = (1 << 2), + I2C_XFER_DONE = (0 << 4), + I2C_XFER_BUSY = (1 << 4), + I2C_ACK_RECEIVED = (0 << 5), + I2C_ACK_NOT_RECEIVED = (1 << 5), + I2C_BUS_ERROR = (1 << 7), + I2C_CTRL_MASK = 0xb7, + + I2C_DATA_MASK = 0xff + }; + + struct channel_t + { + uint32_t m_alpha; + uint32_t m_clip_start; + uint32_t m_clip_end; + uint32_t m_frame_rate; + uint32_t m_field_counter; + uint32_t m_line_size; + uint32_t m_line_counter; + uint32_t m_page_index; + uint32_t m_next_desc_ptr; + uint32_t m_start_desc_ptr; + uint64_t m_descriptors[4]; + uint32_t m_fifo_threshold; + uint32_t m_fifo_gio_ptr; + uint32_t m_fifo_video_ptr; + }; + + uint32_t m_rev_id; + uint32_t m_control; + uint32_t m_int_status; + uint32_t m_i2c_ctrl; + uint32_t m_i2c_data; + channel_t m_channels[2]; +}; + +DECLARE_DEVICE_TYPE(VINO, vino_device) + +#endif // MAME_MACHINE_VINO_H