-vino: Added skeleton device for SGI VINO (Video In, No Out) chip. [Ryan Holtz]

-newport: Unified command handling, should function better and faster as a result. [Ryan Holtz]

-hpc3: Added intstat register and DAC volume controls. [Ryan Holtz]
This commit is contained in:
mooglyguy 2019-05-10 23:58:46 +02:00 committed by MooglyGuy
parent deaa0b5da5
commit 463c53087f
7 changed files with 936 additions and 324 deletions

View File

@ -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",

View File

@ -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;
}
}

View File

@ -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<sgi_mc_device> m_mem_ctrl;
required_device<wd33c93b_device> m_scsi_ctrl;
required_device<hpc3_device> m_hpc3;
optional_device<vino_device> m_vino;
optional_device<gio_device> m_gio;
optional_device<gio_slot_device> m_gio_gfx;
optional_device<gio_slot_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<wd33c93b_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)

View File

@ -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.

View File

@ -62,8 +62,11 @@ protected:
DECLARE_WRITE32_MEMBER(hd_enet_w);
template <uint32_t index> DECLARE_READ32_MEMBER(hd_r);
template <uint32_t index> 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<dac_16bit_r2r_twos_complement_device> m_ldac;
required_device<dac_16bit_r2r_twos_complement_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
{

400
src/mame/machine/vino.cpp Normal file
View File

@ -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;
}
}

162
src/mame/machine/vino.h Normal file
View File

@ -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