summaryrefslogtreecommitdiffstatshomepage
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/devices/bus/cbus/pc9801_86.cpp17
-rw-r--r--src/devices/bus/cbus/pc9801_86.h2
-rw-r--r--src/devices/bus/vic10/exp.cpp2
-rw-r--r--src/devices/bus/vic10/multimax.cpp61
-rw-r--r--src/devices/bus/vic10/multimax.h44
-rw-r--r--src/devices/video/hp1ll3.cpp67
-rw-r--r--src/devices/video/hp1ll3.h4
-rw-r--r--src/lib/formats/ap2_dsk.cpp5
-rw-r--r--src/mame/drivers/exidy.cpp15
-rw-r--r--src/mame/drivers/hp_ipc.cpp119
-rw-r--r--src/mame/drivers/indy_indigo2.cpp1365
-rw-r--r--src/mame/drivers/itech32.cpp2
-rw-r--r--src/mame/drivers/neogeo.cpp141
-rw-r--r--src/mame/drivers/pc9801.cpp1
-rw-r--r--src/mame/drivers/stv.cpp2
-rw-r--r--src/mame/machine/hal2.cpp175
-rw-r--r--src/mame/machine/hal2.h66
-rw-r--r--src/mame/machine/hpc3.cpp577
-rw-r--r--src/mame/machine/hpc3.h128
-rw-r--r--src/mame/machine/ioc2.cpp432
-rw-r--r--src/mame/machine/ioc2.h215
-rw-r--r--src/mame/mame.lst6
-rw-r--r--src/mame/video/pc9801.cpp2
23 files changed, 2036 insertions, 1412 deletions
diff --git a/src/devices/bus/cbus/pc9801_86.cpp b/src/devices/bus/cbus/pc9801_86.cpp
index 094a50be752..111622b5a1c 100644
--- a/src/devices/bus/cbus/pc9801_86.cpp
+++ b/src/devices/bus/cbus/pc9801_86.cpp
@@ -183,11 +183,15 @@ void pc9801_86_device::device_reset()
install_device(port_base + 0x0088, port_base + 0x008f, read8_delegate(FUNC(pc9801_86_device::opn_r), this), write8_delegate(FUNC(pc9801_86_device::opn_w), this) );
install_device(0xa460, 0xa463, read8_delegate(FUNC(pc9801_86_device::id_r), this), write8_delegate(FUNC(pc9801_86_device::mask_w), this));
install_device(0xa464, 0xa46f, read8_delegate(FUNC(pc9801_86_device::pcm_r), this), write8_delegate(FUNC(pc9801_86_device::pcm_w), this));
+ install_device(0xa66c, 0xa66f, read8_delegate([this](address_space &s, offs_t o, u8 mm){ return o == 2 ? m_pcm_mute : 0xff; }, "pc9801_86_mute_r"),
+ write8_delegate([this](address_space &s, offs_t o, u8 d, u8 mm){ if(o == 2) m_pcm_mute = d; }, "pc9801_86_mute_w"));
m_mask = 0;
m_head = m_tail = m_count = 0;
m_fmirq = m_pcmirq = false;
m_irq_rate = 0;
m_pcm_ctrl = m_pcm_mode = 0;
+ m_pcm_mute = 0;
+ m_pcm_clk = false;
memset(&m_queue[0], 0, QUEUE_SIZE);
}
@@ -234,15 +238,13 @@ READ8_MEMBER(pc9801_86_device::pcm_r)
{
case 1:
return ((queue_count() == QUEUE_SIZE) ? 0x80 : 0) |
- (!queue_count() ? 0x40 : 0);
+ (!queue_count() ? 0x40 : 0) | (m_pcm_clk ? 1 : 0);
case 2:
return m_pcm_ctrl | (m_pcmirq ? 0x10 : 0);
case 3:
return m_pcm_mode;
case 4:
return 0;
- case 5:
- return m_pcm_mute;
}
}
else // odd
@@ -263,10 +265,7 @@ WRITE8_MEMBER(pc9801_86_device::pcm_w)
break;
case 2:
m_pcm_ctrl = data & ~0x10;
- if(data & 0x80)
- m_dac_timer->adjust(attotime::from_ticks(divs[data & 7], rate), 0, attotime::from_ticks(divs[data & 7], rate));
- else
- m_dac_timer->adjust(attotime::never);
+ m_dac_timer->adjust(attotime::from_ticks(divs[data & 7], rate), 0, attotime::from_ticks(divs[data & 7], rate));
if(data & 8)
m_head = m_tail = m_count = 0;
if(!(data & 0x10))
@@ -289,9 +288,6 @@ WRITE8_MEMBER(pc9801_86_device::pcm_w)
m_count++;
}
break;
- case 5:
- m_pcm_mute = data;
- break;
}
}
else // odd
@@ -317,6 +313,7 @@ void pc9801_86_device::device_timer(emu_timer& timer, device_timer_id id, int pa
{
int16_t lsample, rsample;
+ m_pcm_clk = !m_pcm_clk;
if((m_pcm_ctrl & 0x40) || !(m_pcm_ctrl & 0x80) || !queue_count())
return;
diff --git a/src/devices/bus/cbus/pc9801_86.h b/src/devices/bus/cbus/pc9801_86.h
index 97f09328e2f..0b6ddff335a 100644
--- a/src/devices/bus/cbus/pc9801_86.h
+++ b/src/devices/bus/cbus/pc9801_86.h
@@ -55,7 +55,7 @@ private:
uint8_t m_joy_sel, m_mask, m_pcm_mode, m_vol[7], m_pcm_ctrl, m_pcm_mute;
uint16_t m_head, m_tail, m_count, m_irq_rate;
- bool m_pcmirq, m_fmirq;
+ bool m_pcmirq, m_fmirq, m_pcm_clk;
required_device<ym2608_device> m_opna;
required_device<dac_word_interface> m_ldac;
required_device<dac_word_interface> m_rdac;
diff --git a/src/devices/bus/vic10/exp.cpp b/src/devices/bus/vic10/exp.cpp
index fa9f40f5742..d840e50a105 100644
--- a/src/devices/bus/vic10/exp.cpp
+++ b/src/devices/bus/vic10/exp.cpp
@@ -231,8 +231,10 @@ WRITE_LINE_MEMBER( vic10_expansion_slot_device::p0_w ) { if (m_card != nullptr)
// slot devices
#include "std.h"
+#include "multimax.h"
SLOT_INTERFACE_START( vic10_expansion_cards )
// the following need ROMs from the software list
SLOT_INTERFACE_INTERNAL("standard", VIC10_STD)
+ SLOT_INTERFACE_INTERNAL("multimax", MULTIMAX)
SLOT_INTERFACE_END
diff --git a/src/devices/bus/vic10/multimax.cpp b/src/devices/bus/vic10/multimax.cpp
new file mode 100644
index 00000000000..de197530004
--- /dev/null
+++ b/src/devices/bus/vic10/multimax.cpp
@@ -0,0 +1,61 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+/**********************************************************************
+
+ MultiMAX 1MB ROM / 2KB RAM cartridge emulation
+
+**********************************************************************/
+
+#include "emu.h"
+#include "multimax.h"
+
+
+
+//**************************************************************************
+// DEVICE DEFINITIONS
+//**************************************************************************
+
+DEFINE_DEVICE_TYPE(MULTIMAX, multimax_t, "multimax", "MultiMAX Cartridge")
+
+
+
+//**************************************************************************
+// LIVE DEVICE
+//**************************************************************************
+
+//-------------------------------------------------
+// multimax_t - constructor
+//-------------------------------------------------
+
+multimax_t::multimax_t(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock) :
+ device_t(mconfig, MULTIMAX, tag, owner, clock), device_vic10_expansion_card_interface(mconfig, *this)
+{
+}
+
+
+//-------------------------------------------------
+// device_start - device-specific startup
+//-------------------------------------------------
+
+void multimax_t::device_start()
+{
+}
+
+
+//-------------------------------------------------
+// vic10_cd_r - cartridge data read
+//-------------------------------------------------
+
+uint8_t multimax_t::vic10_cd_r(address_space &space, offs_t offset, uint8_t data, int lorom, int uprom, int exram)
+{
+ return data;
+}
+
+
+//-------------------------------------------------
+// vic10_cd_w - cartridge data write
+//-------------------------------------------------
+
+void multimax_t::vic10_cd_w(address_space &space, offs_t offset, uint8_t data, int lorom, int uprom, int exram)
+{
+}
diff --git a/src/devices/bus/vic10/multimax.h b/src/devices/bus/vic10/multimax.h
new file mode 100644
index 00000000000..96d8cf54213
--- /dev/null
+++ b/src/devices/bus/vic10/multimax.h
@@ -0,0 +1,44 @@
+// license:BSD-3-Clause
+// copyright-holders:Curt Coder
+/**********************************************************************
+
+ MultiMAX 1MB ROM / 2KB RAM cartridge emulation
+
+**********************************************************************/
+
+#ifndef MAME_BUS_VIC10_MULTIMAX_H
+#define MAME_BUS_VIC10_MULTIMAX_H
+
+#pragma once
+
+#include "exp.h"
+
+
+
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
+
+// ======================> multimax_t
+
+class multimax_t : public device_t,
+ public device_vic10_expansion_card_interface
+{
+public:
+ // construction/destruction
+ multimax_t(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+
+protected:
+ // device-level overrides
+ virtual void device_start() override;
+
+ // device_vic10_expansion_card_interface overrides
+ virtual uint8_t vic10_cd_r(address_space &space, offs_t offset, uint8_t data, int lorom, int uprom, int exram) override;
+ virtual void vic10_cd_w(address_space &space, offs_t offset, uint8_t data, int lorom, int uprom, int exram) override;
+};
+
+
+// device type definition
+DECLARE_DEVICE_TYPE(MULTIMAX, multimax_t)
+
+#endif // MAME_BUS_VIC10_MULTIMAX_H
diff --git a/src/devices/video/hp1ll3.cpp b/src/devices/video/hp1ll3.cpp
index 175167811b7..5d15ada47e5 100644
--- a/src/devices/video/hp1ll3.cpp
+++ b/src/devices/video/hp1ll3.cpp
@@ -146,9 +146,8 @@
} while (0)
-#define HPGPU_VRAM_SIZE 16384 // *4 // experiment
-#define HPGPU_HORZ_TOTAL 512
-#define HPGPU_VERT_TOTAL 256
+// enough for 9807a and 9808a both.
+#define HPGPU_VRAM_SIZE (16384 * 4)
//**************************************************************************
@@ -180,6 +179,8 @@ hp1ll3_device::hp1ll3_device(const machine_config &mconfig, const char *tag, dev
void hp1ll3_device::device_start()
{
+ const rectangle &visarea = screen().visible_area();
+
// register for state saving
save_item(NAME(m_conf));
@@ -189,6 +190,9 @@ void hp1ll3_device::device_start()
m_sprite.allocate(16, 16);
m_videoram = std::make_unique<uint16_t[]>(HPGPU_VRAM_SIZE*2); // x2 size to make WRWIN/RDWIN easier
+
+ m_horiz_pix_total = visarea.max_x + 1;
+ m_vert_pix_total = visarea.max_y + 1;
}
void hp1ll3_device::device_reset()
@@ -203,7 +207,7 @@ inline void hp1ll3_device::point(int x, int y, int px)
{
uint16_t offset = m_sad;
- offset += y*(HPGPU_HORZ_TOTAL/16) + (x >> 4);
+ offset += y*(m_horiz_pix_total/16) + (x >> 4);
if (px)
m_videoram[offset] |= (1 << (15-(x%16)));
@@ -331,9 +335,9 @@ void hp1ll3_device::fill(int org_x, int org_y, int w, int h, int arg)
if (m_rr == RR_COPYINVERTED) gfx ^= 0xffff;
for (int x = org_x; x < max_x;) {
mask = 0xffff;
- offset = m_sad + m_org + y * (HPGPU_HORZ_TOTAL/16) + (x >> 4);
+ offset = m_sad + m_org + y * (m_horiz_pix_total/16) + (x >> 4);
- if (offset >= m_sad + (HPGPU_VERT_TOTAL * HPGPU_HORZ_TOTAL/WS))
+ if (offset >= m_sad + (m_vert_pix_total * m_horiz_pix_total/WS))
DBG_LOG(0,"HPGPU",("buffer overflow in FILL: %04x (%d, %d)\n", offset, 16*x, y));
// clipping
@@ -362,19 +366,19 @@ void hp1ll3_device::bitblt(int dstx, int dsty, uint16_t srcaddr, int width, int
int max_x, max_y;
max_x = dstx + width;
- if (max_x >= HPGPU_HORZ_TOTAL)
- max_x = HPGPU_HORZ_TOTAL;
+ if (max_x >= m_horiz_pix_total)
+ max_x = m_horiz_pix_total;
max_y = dsty + height;
- if (max_y >= HPGPU_VERT_TOTAL)
- max_y = HPGPU_VERT_TOTAL;
+ if (max_y >= m_vert_pix_total)
+ max_y = m_vert_pix_total;
for (int y = dsty; y < max_y; y++) {
mask = 0xffff;
gfx = m_videoram[srcaddr + y - dsty] & mask;
- offset = m_sad + y * (HPGPU_HORZ_TOTAL/16) + (dstx >> 4);
+ offset = m_sad + y * (m_horiz_pix_total/16) + (dstx >> 4);
- if (offset >= m_sad + (HPGPU_VERT_TOTAL * HPGPU_HORZ_TOTAL/16))
+ if (offset >= m_sad + (m_vert_pix_total * m_horiz_pix_total/16))
DBG_LOG(0,"HPGPU",("buffer overflow in bitblt: %04x (%d, %d)\n", offset, 16*dstx, y));
// are we crossing word boundary?
@@ -408,10 +412,10 @@ void hp1ll3_device::label(uint8_t chr, int width)
for (int y = 0; y < max_y; y++) {
x = m_cursor_x;
- offset = m_sad + (m_cursor_y + y) * (HPGPU_HORZ_TOTAL/16) + (x >> 4);
+ offset = m_sad + (m_cursor_y + y) * (m_horiz_pix_total/16) + (x >> 4);
gfx = m_videoram[font + y] >> (16 - width);
- if (offset >= m_sad + (HPGPU_VERT_TOTAL * HPGPU_HORZ_TOTAL/16))
+ if (offset >= m_sad + (m_vert_pix_total * m_horiz_pix_total/16))
DBG_LOG(0,"HPGPU",("buffer overflow in LABEL: %04x (%d, %d)\n", offset, 16*x, y));
// are we crossing word boundary?
@@ -452,11 +456,11 @@ uint32_t hp1ll3_device::screen_update(screen_device &screen, bitmap_ind16 &bitma
}
// XXX last line is not actually drawn on real hw
- for (y = 0; y < HPGPU_VERT_TOTAL-1; y++) {
- offset = m_sad + y*(HPGPU_HORZ_TOTAL/16);
+ for (y = 0; y < m_vert_pix_total-1; y++) {
+ offset = m_sad + y*(m_horiz_pix_total/16);
p = &m_bitmap.pix16(y);
- for (x = offset; x < offset + HPGPU_HORZ_TOTAL/16; x++)
+ for (x = offset; x < offset + m_horiz_pix_total/16; x++)
{
gfx = m_videoram[x];
@@ -524,7 +528,20 @@ READ8_MEMBER( hp1ll3_device::read )
m_memory_ptr++;
}
break;
+
+ /*
+ * 'diagb' ROM accepts either of these ID values
+ * 0x3003, 0x4004, 0x5005, 0x6006
+ */
+ case ID:
+ data = 0x40;
+ break;
}
+ break;
+
+ case 3:
+ if (m_command == ID) data = 0x04;
+ break;
}
DBG_LOG(1,"HPGPU", ("R @ %d == %02x\n", offset, data));
@@ -548,6 +565,7 @@ WRITE8_MEMBER( hp1ll3_device::write )
break;
case 2:
+ case 3:
switch (m_command)
{
case CONF:
@@ -685,6 +703,9 @@ void hp1ll3_device::command(int command)
case WRFAD:
DBG_LOG(2,"HPGPU",("command: WRFAD [%d, 0x%x] (0x%04x)\n", command, command, m_input[0]));
m_fad = m_input[0];
+
+ // ?? used by diagnostic ROM
+ case 6:
m_fontheight = m_videoram[m_fad];
m_fontdata = m_fad + m_videoram[m_fad + 1] + 2;
DBG_LOG(1,"HPGPU",("font data set: FAD %04X header %d bitmaps %04X height %d\n",
@@ -761,6 +782,18 @@ void hp1ll3_device::command(int command)
if (m_enable_sprite) bitblt(m_sprite_x, m_sprite_y, m_dad + 16, 16, 16, RR_XOR);
m_cursor_x = m_input[0];
m_cursor_y = m_input[1];
+ m_saved_x = m_cursor_x;
+ if (m_enable_cursor) bitblt(m_cursor_x, m_cursor_y, m_dad, 16, 16, RR_XOR);
+ if (m_enable_sprite) bitblt(m_sprite_x, m_sprite_y, m_dad + 16, 16, 16, RR_XOR);
+ break;
+
+ // carriage return, line feed
+ case CRLFx:
+ DBG_LOG(2,"HPGPU",("command: CRLF [%d, 0x%x] (%d, %d)\n", command, command, m_input[0], m_input[1]));
+ if (m_enable_cursor) bitblt(m_cursor_x, m_cursor_y, m_dad, 16, 16, RR_XOR);
+ if (m_enable_sprite) bitblt(m_sprite_x, m_sprite_y, m_dad + 16, 16, 16, RR_XOR);
+ m_cursor_x = m_saved_x;
+ m_cursor_y += m_fontheight;
if (m_enable_cursor) bitblt(m_cursor_x, m_cursor_y, m_dad, 16, 16, RR_XOR);
if (m_enable_sprite) bitblt(m_sprite_x, m_sprite_y, m_dad + 16, 16, 16, RR_XOR);
break;
diff --git a/src/devices/video/hp1ll3.h b/src/devices/video/hp1ll3.h
index ab8b047a977..dfeb1e83551 100644
--- a/src/devices/video/hp1ll3.h
+++ b/src/devices/video/hp1ll3.h
@@ -53,7 +53,7 @@ private:
uint16_t m_conf[11], m_input[2];
int m_input_ptr, m_memory_ptr, m_conf_ptr;
- int m_command;
+ int m_command, m_horiz_pix_total, m_vert_pix_total;
uint16_t m_sad;
uint16_t m_org;
@@ -63,7 +63,7 @@ private:
uint16_t m_udl;
bool m_enable_video, m_enable_cursor, m_enable_sprite;
- uint16_t m_cursor_x, m_cursor_y;
+ uint16_t m_cursor_x, m_cursor_y, m_saved_x;
uint16_t m_sprite_x, m_sprite_y;
struct {
uint16_t width, height, org_x, org_y, width_w;
diff --git a/src/lib/formats/ap2_dsk.cpp b/src/lib/formats/ap2_dsk.cpp
index df391194878..0105fbfa679 100644
--- a/src/lib/formats/ap2_dsk.cpp
+++ b/src/lib/formats/ap2_dsk.cpp
@@ -617,6 +617,7 @@ bool a2_16sect_format::load(io_generic *io, uint32_t form_factor, floppy_image *
static const unsigned char sos_block1[4] = { 0xc9, 0x20, 0xf0, 0x3e };
static const unsigned char a3a2emul_block1[6] = { 0x8d, 0xd0, 0x03, 0x4c, 0xc7, 0xa4 };
static const unsigned char cpm22_block1[8] = { 0xa2, 0x55, 0xa9, 0x00, 0x9d, 0x00, 0x0d, 0xca };
+ static const unsigned char subnod_block1[8] = { 0x63, 0xaa, 0xf0, 0x76, 0x8d, 0x63, 0xaa, 0x8e };
io_generic_read(io, sector_data, fpos, 256*16);
@@ -664,6 +665,10 @@ bool a2_16sect_format::load(io_generic *io, uint32_t form_factor, floppy_image *
else if (!memcmp(cpm22_block1, &sector_data[0x100], 8))
{
m_prodos_order = true;
+ } // check for subnodule disk
+ else if (!memcmp(subnod_block1, &sector_data[0x100], 8))
+ {
+ m_prodos_order = true;
}
}
diff --git a/src/mame/drivers/exidy.cpp b/src/mame/drivers/exidy.cpp
index 3ab21a67921..e96dac69b9c 100644
--- a/src/mame/drivers/exidy.cpp
+++ b/src/mame/drivers/exidy.cpp
@@ -1348,6 +1348,11 @@ ROM_START( venture )
ROM_REGION( 0x0800, "gfx1", 0 )
ROM_LOAD( "11d-cpu", 0x0000, 0x0800, CRC(b4bb2503) SHA1(67303603b7c5e6301e976ef19f81c7519648b179) )
+
+ ROM_REGION( 0x140, "proms", 0 )
+ ROM_LOAD( "hrl14h 1.h14", 0x0000, 0x0020, CRC(f76b4fcf) SHA1(197e0cc508ffeb5cefa4046bdfb158939d598225) )
+ ROM_LOAD( "vel5c 1.c5", 0x0020, 0x0100, CRC(43b35bb7) SHA1(0a0cecea8faff9f3ff4c2ceda0b5b25e8e1cd667) )
+ ROM_LOAD( "hrl6d 1.d6", 0x0120, 0x0020, CRC(e26f9053) SHA1(eec35b6aa2c2d305418306bf4a1754a0583f109f) )
ROM_END
@@ -1371,6 +1376,11 @@ ROM_START( venture2 )
ROM_REGION( 0x0800, "gfx1", 0 )
ROM_LOAD( "11d-cpu", 0x0000, 0x0800, CRC(b4bb2503) SHA1(67303603b7c5e6301e976ef19f81c7519648b179) )
+
+ ROM_REGION( 0x140, "proms", 0 )
+ ROM_LOAD( "hrl14h 1.h14", 0x0000, 0x0020, CRC(f76b4fcf) SHA1(197e0cc508ffeb5cefa4046bdfb158939d598225) )
+ ROM_LOAD( "vel5c 1.c5", 0x0020, 0x0100, CRC(43b35bb7) SHA1(0a0cecea8faff9f3ff4c2ceda0b5b25e8e1cd667) )
+ ROM_LOAD( "hrl6d 1.d6", 0x0120, 0x0020, CRC(e26f9053) SHA1(eec35b6aa2c2d305418306bf4a1754a0583f109f) )
ROM_END
@@ -1394,6 +1404,11 @@ ROM_START( venture4 )
ROM_REGION( 0x0800, "gfx1", 0 )
ROM_LOAD( "vel11d-2", 0x0000, 0x0800, CRC(ea6fd981) SHA1(46b1658e1607423d5a073f14097c2a48d59057c0) )
+
+ ROM_REGION( 0x140, "proms", 0 )
+ ROM_LOAD( "hrl14h 1.h14", 0x0000, 0x0020, CRC(f76b4fcf) SHA1(197e0cc508ffeb5cefa4046bdfb158939d598225) )
+ ROM_LOAD( "vel5c 1.c5", 0x0020, 0x0100, CRC(43b35bb7) SHA1(0a0cecea8faff9f3ff4c2ceda0b5b25e8e1cd667) )
+ ROM_LOAD( "hrl6d 1.d6", 0x0120, 0x0020, CRC(e26f9053) SHA1(eec35b6aa2c2d305418306bf4a1754a0583f109f) )
ROM_END
diff --git a/src/mame/drivers/hp_ipc.cpp b/src/mame/drivers/hp_ipc.cpp
index b2772ccb4dc..ea43edef19a 100644
--- a/src/mame/drivers/hp_ipc.cpp
+++ b/src/mame/drivers/hp_ipc.cpp
@@ -415,9 +415,16 @@ public:
emu_timer *m_bus_error_timer;
+ void hp_ipc_base(machine_config &config);
void hp_ipc(machine_config &config);
- void hp_ipc_mem_inner(address_map &map);
+
+ void hp_ipc_mem_inner_base(address_map &map);
+ void hp_ipc_mem_inner_9807a(address_map &map);
void hp_ipc_mem_outer(address_map &map);
+
+ void hp9808a(machine_config &config);
+ void hp_ipc_mem_inner_9808a(address_map &map);
+
private:
required_device<m68000_device> m_maincpu;
required_device<address_map_bank_device> m_bankdev;
@@ -469,7 +476,7 @@ void hp_ipc_state::hp_ipc_mem_outer(address_map &map)
map(0x000000, 0xFFFFFF).rw(this, FUNC(hp_ipc_state::mem_r), FUNC(hp_ipc_state::mem_w));
}
-void hp_ipc_state::hp_ipc_mem_inner(address_map &map)
+void hp_ipc_state::hp_ipc_mem_inner_base(address_map &map)
{
// bus error handler
map(0x0000000, 0x1FFFFFF).rw(this, FUNC(hp_ipc_state::trap_r), FUNC(hp_ipc_state::trap_w));
@@ -477,6 +484,7 @@ void hp_ipc_state::hp_ipc_mem_inner(address_map &map)
// user mode
map(0x1000000, 0x17FFFFF).rw(this, FUNC(hp_ipc_state::ram_r), FUNC(hp_ipc_state::ram_w));
map(0x1800000, 0x187FFFF).rom().region("maincpu", 0);
+ map(0x1E00000, 0x1E0FFFF).rw(this, FUNC(hp_ipc_state::mmu_r), FUNC(hp_ipc_state::mmu_w));
map(0x1E20000, 0x1E2000F).rw("gpu", FUNC(hp1ll3_device::read), FUNC(hp1ll3_device::write)).umask16(0x00ff);
map(0x1E40000, 0x1E4002F).rw("rtc", FUNC(mm58167_device::read), FUNC(mm58167_device::write)).umask16(0x00ff);
@@ -490,13 +498,22 @@ void hp_ipc_state::hp_ipc_mem_inner(address_map &map)
map(0x0620000, 0x062000F).rw("gpu", FUNC(hp1ll3_device::read), FUNC(hp1ll3_device::write)).umask16(0x00ff);
map(0x0630000, 0x063FFFF).noprw(); // AM_DEVREADWRITE8(TMS9914_TAG, tms9914_device, read, write, 0x00ff)
map(0x0640000, 0x064002F).rw("rtc", FUNC(mm58167_device::read), FUNC(mm58167_device::write)).umask16(0x00ff);
- map(0x0650000, 0x065FFFF).noprw(); // HP-IL Printer (optional; ROM sets _desktop to 0 if not mapped) -- sys/lpint.h
map(0x0660000, 0x06600FF).rw("mlc", FUNC(hp_hil_mlc_device::read), FUNC(hp_hil_mlc_device::write)).umask16(0x00ff); // 'caravan', scrn/caravan.h
map(0x0670000, 0x067FFFF).noprw(); // Speaker (NatSemi COP 452)
map(0x0680000, 0x068FFFF).noprw(); // 'SIMON (98628) fast HP-IB card' -- sys/simon.h
map(0x0700000, 0x07FFFFF).unmaprw(); // External I/O
map(0x0800000, 0x0FFFFFF).rw(this, FUNC(hp_ipc_state::ram_r), FUNC(hp_ipc_state::ram_w));
+}
+void hp_ipc_state::hp_ipc_mem_inner_9807a(address_map &map)
+{
+ hp_ipc_mem_inner_base(map);
+ map(0x0650000, 0x065FFFF).noprw(); // HP-IL Printer (optional; ROM sets _desktop to 0 if not mapped) -- sys/lpint.h
+}
+
+void hp_ipc_state::hp_ipc_mem_inner_9808a(address_map &map)
+{
+ hp_ipc_mem_inner_base(map);
}
static INPUT_PORTS_START(hp_ipc)
@@ -687,7 +704,7 @@ void hp_ipc_state::machine_start()
m_bankdev->set_bank(1);
m_lowest_ram_addr = 0x3c0000 - (m_ram->size() >> 1);
- m_internal_ram = (uint16_t *) m_ram->pointer();
+ m_internal_ram = (uint16_t *)m_ram->pointer();
}
void hp_ipc_state::machine_reset()
@@ -715,31 +732,10 @@ SLOT_INTERFACE_END
* 2 HP-HIL devices (keyboard, mouse)
* 1 Real-time clock
*/
-MACHINE_CONFIG_START(hp_ipc_state::hp_ipc)
+MACHINE_CONFIG_START(hp_ipc_state::hp_ipc_base)
MCFG_CPU_ADD("maincpu", M68000, XTAL(15'920'000) / 2)
MCFG_CPU_PROGRAM_MAP(hp_ipc_mem_outer)
- MCFG_DEVICE_ADD("bankdev", ADDRESS_MAP_BANK, 0)
- MCFG_DEVICE_PROGRAM_MAP(hp_ipc_mem_inner)
- MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_BIG)
- MCFG_ADDRESS_MAP_BANK_ADDR_WIDTH(25)
- MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(16)
- MCFG_ADDRESS_MAP_BANK_STRIDE(0x1000000)
-
- // horizontal time = 60 us (min)
- // ver.refresh period = ~300 us
- // ver.period = 16.7ms (~60 hz)
- MCFG_SCREEN_ADD_MONOCHROME("screen", RASTER, rgb_t::amber())
- MCFG_SCREEN_UPDATE_DEVICE("gpu", hp1ll3_device, screen_update)
- MCFG_SCREEN_RAW_PARAMS(XTAL(6'000'000) * 2, 720, 0, 512, 278, 0, 256)
-// when _desktop == 0:
-// MCFG_SCREEN_RAW_PARAMS(XTAL(6'000'000) * 2, 720, 0, 640, 480, 0, 400)
- MCFG_SCREEN_VBLANK_CALLBACK(DEVWRITELINE("mlc", hp_hil_mlc_device, ap_w)) // XXX actually it's driven by 555 (U59)
- MCFG_DEFAULT_LAYOUT(layout_lcd)
-
- MCFG_SCREEN_PALETTE("palette")
- MCFG_PALETTE_ADD_MONOCHROME("palette")
-
MCFG_HP1LL3_ADD("gpu")
// MCFG_HP1LL3_IRQ_CALLBACK(WRITELINE(hp_ipc_state, irq_4))
MCFG_VIDEO_SET_SCREEN("screen")
@@ -766,11 +762,76 @@ MACHINE_CONFIG_START(hp_ipc_state::hp_ipc)
MCFG_RAM_EXTRA_OPTIONS("768K,1M,1576K,2M,3M,4M,5M,6M,7M,7680K")
MACHINE_CONFIG_END
+MACHINE_CONFIG_START(hp_ipc_state::hp_ipc)
+ hp_ipc_base(config);
+
+ MCFG_DEVICE_ADD("bankdev", ADDRESS_MAP_BANK, 0)
+ MCFG_DEVICE_PROGRAM_MAP(hp_ipc_mem_inner_9807a)
+ MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_BIG)
+ MCFG_ADDRESS_MAP_BANK_ADDR_WIDTH(25)
+ MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(16)
+ MCFG_ADDRESS_MAP_BANK_STRIDE(0x1000000)
+
+ // horizontal time = 60 us (min)
+ // ver.refresh period = ~300 us
+ // ver.period = 16.7ms (~60 hz)
+ MCFG_SCREEN_ADD_MONOCHROME("screen", RASTER, rgb_t::amber())
+ MCFG_SCREEN_UPDATE_DEVICE("gpu", hp1ll3_device, screen_update)
+ MCFG_SCREEN_RAW_PARAMS(XTAL(6'000'000) * 2, 720, 0, 512, 278, 0, 256)
+ MCFG_SCREEN_VBLANK_CALLBACK(DEVWRITELINE("mlc", hp_hil_mlc_device, ap_w)) // XXX actually it's driven by 555 (U59)
+ MCFG_DEFAULT_LAYOUT(layout_lcd)
+
+ MCFG_SCREEN_PALETTE("palette")
+ MCFG_PALETTE_ADD_MONOCHROME("palette")
+MACHINE_CONFIG_END
+
+MACHINE_CONFIG_START(hp_ipc_state::hp9808a)
+ hp_ipc_base(config);
+
+ MCFG_DEVICE_ADD("bankdev", ADDRESS_MAP_BANK, 0)
+ MCFG_DEVICE_PROGRAM_MAP(hp_ipc_mem_inner_9808a)
+ MCFG_ADDRESS_MAP_BANK_ENDIANNESS(ENDIANNESS_BIG)
+ MCFG_ADDRESS_MAP_BANK_ADDR_WIDTH(25)
+ MCFG_ADDRESS_MAP_BANK_DATA_WIDTH(16)
+ MCFG_ADDRESS_MAP_BANK_STRIDE(0x1000000)
+
+ MCFG_SCREEN_ADD_MONOCHROME("screen", RASTER, rgb_t::amber())
+ MCFG_SCREEN_UPDATE_DEVICE("gpu", hp1ll3_device, screen_update)
+ MCFG_SCREEN_RAW_PARAMS(XTAL(6'000'000) * 2, 720, 0, 640, 480, 0, 400)
+ MCFG_SCREEN_VBLANK_CALLBACK(DEVWRITELINE("mlc", hp_hil_mlc_device, ap_w))
+ MCFG_DEFAULT_LAYOUT(layout_lcd)
+
+ MCFG_SCREEN_PALETTE("palette")
+ MCFG_PALETTE_ADD_MONOCHROME("palette")
+MACHINE_CONFIG_END
+
ROM_START(hp_ipc)
- ROM_REGION(0x100000, "maincpu" , 0)
- ROM_LOAD("hp ipc os 82991a.bin", 0x00000, 0x80000, BAD_DUMP CRC(df45a37b) SHA1(476af9923bca0d2d0f40aeb81be5145ca76fddf5)) // Should be spread across 4 x 128K ROMs
+ ROM_REGION(0x80000, "maincpu", 0)
+ ROM_DEFAULT_BIOS("v50")
+
+ ROM_SYSTEM_BIOS(0, "v10", "HP-UX 1.0")
+ ROMX_LOAD("00095-60006.bin", 0x00000, 0x80000, NO_DUMP, ROM_BIOS(1))
+
+ ROM_SYSTEM_BIOS(1, "v50", "HP-UX 5.0")
+ // Should be spread across 4 x 128K ROMs
+ ROMX_LOAD("hp ipc os 82991a.bin", 0x00000, 0x80000, BAD_DUMP CRC(df45a37b) SHA1(476af9923bca0d2d0f40aeb81be5145ca76fddf5), ROM_BIOS(2))
+
+ ROM_SYSTEM_BIOS(2, "diaga", "Diag ROM A")
+ ROMX_LOAD("boarda_u1.bin", 0x00001, 0x4000, CRC(f40e1434) SHA1(a4f633f3e0971ba3ff218c6d6f777b8253bade8c), ROM_BIOS(3)|ROM_SKIP(1))
+ ROMX_LOAD("boarda_u2.bin", 0x00000, 0x4000, CRC(80f6eb08) SHA1(ea943f72d37b43b5ba06b8e6f11824601109497c), ROM_BIOS(3)|ROM_SKIP(1))
+ ROMX_LOAD("boarda_u3.bin", 0x40001, 0x4000, CRC(0f2fd4d5) SHA1(9ed41fca947d58d7f4159336421601963e3cae17), ROM_BIOS(3)|ROM_SKIP(1))
+ ROMX_LOAD("boarda_u4.bin", 0x40000, 0x4000, CRC(d6741772) SHA1(1574a52d6658f9a7beace6572bea11ee923fc1bf), ROM_BIOS(3)|ROM_SKIP(1))
+
+ ROM_SYSTEM_BIOS(3, "diagb", "Diag ROM B")
+ ROMX_LOAD("boardb_u1.bin", 0x00001, 0x4000, CRC(597777d9) SHA1(24671499e4685f306b1b37a071adc0634f9f1e4e), ROM_BIOS(4)|ROM_SKIP(1))
+ ROMX_LOAD("boardb_u2.bin", 0x00000, 0x4000, CRC(bc2ada19) SHA1(efebab335ca8a57e77b1076050e861a3a0eb09fc), ROM_BIOS(4)|ROM_SKIP(1))
+ ROMX_LOAD("boardb_u3.bin", 0x40001, 0x2000, CRC(c227622a) SHA1(99747945dc6efaa45ce8d7d3c58830dbe46b651a), ROM_BIOS(4)|ROM_SKIP(1))
+ ROMX_LOAD("boardb_u4.bin", 0x40000, 0x2000, CRC(d99efe90) SHA1(345437007f8d728ceafc5cd97414ef94ce38e363), ROM_BIOS(4)|ROM_SKIP(1))
ROM_END
+#define rom_hp9808a rom_hp_ipc
-COMP(1985, hp_ipc, 0, 0, hp_ipc, hp_ipc, hp_ipc_state, 0, "HP", "Integral Personal Computer", MACHINE_NO_SOUND | MACHINE_IMPERFECT_GRAPHICS)
+// YEAR NAME PARENT COMPAT MACHINE INPUT STATE INIT COMPANY FULLNAME FLAGS
+COMP( 1985, hp_ipc, 0, 0, hp_ipc, hp_ipc, hp_ipc_state, 0 , "Hewlett-Packard", "Integral Personal Computer 9807A", MACHINE_NO_SOUND | MACHINE_IMPERFECT_GRAPHICS)
+COMP( 1985, hp9808a, 0, 0, hp9808a, hp_ipc, hp_ipc_state, 0 , "Hewlett-Packard", "Integral Personal Computer 9808A", MACHINE_NOT_WORKING)
diff --git a/src/mame/drivers/indy_indigo2.cpp b/src/mame/drivers/indy_indigo2.cpp
index 88f1a43a8d1..6b28199cb46 100644
--- a/src/mame/drivers/indy_indigo2.cpp
+++ b/src/mame/drivers/indy_indigo2.cpp
@@ -41,597 +41,41 @@
\*********************************************************************/
#include "emu.h"
-#include "bus/rs232/rs232.h"
#include "bus/scsi/scsi.h"
#include "bus/scsi/scsicd.h"
#include "bus/scsi/scsihd.h"
+
#include "cpu/mips/mips3.h"
-#include "machine/8042kbdc.h"
+
#include "machine/ds1386.h"
-#include "machine/pc_lpt.h"
-#include "machine/pckeybrd.h"
-#include "machine/pit8253.h"
+#include "machine/hal2.h"
+#include "machine/hpc3.h"
+#include "machine/ioc2.h"
#include "machine/sgi.h"
-#include "machine/wd33c93.h"
-#include "machine/z80scc.h"
+
#include "sound/cdda.h"
#include "sound/dac.h"
#include "sound/volt_reg.h"
+
#include "video/newport.h"
+
#include "screen.h"
#include "speaker.h"
-#define SCC_TAG "scc"
-#define PI1_TAG "pi1"
-#define KBDC_TAG "kbdc"
-#define PIT_TAG "pit"
-#define RS232A_TAG "rs232a"
-#define RS232B_TAG "rs232b"
-
-#define SCC_PCLK XTAL(10'000'000)
-#define SCC_RXA_CLK XTAL(3'686'400) // Needs verification
-#define SCC_TXA_CLK 0
-#define SCC_RXB_CLK XTAL(3'686'400) // Needs verification
-#define SCC_TXB_CLK 0
-
-#define MCFG_IOC2_GUINNESS_ADD(_tag) \
- MCFG_DEVICE_ADD(_tag, SGI_IOC2_GUINNESS, 0)
-
-#define MCFG_IOC2_FULL_HOUSE_ADD(_tag) \
- MCFG_DEVICE_ADD(_tag, SGI_IOC2_FULL_HOUSE, 0)
-
-class ioc2_device : public device_t
-{
-public:
- DECLARE_WRITE32_MEMBER( write );
- DECLARE_READ32_MEMBER( read );
-
- DECLARE_INPUT_CHANGED_MEMBER( power_button );
- DECLARE_INPUT_CHANGED_MEMBER( volume_down );
- DECLARE_INPUT_CHANGED_MEMBER( volume_up );
-
- void lower_local0_irq(uint8_t source_mask);
- void raise_local0_irq(uint8_t source_mask);
- void lower_local1_irq(uint8_t source_mask);
- void raise_local1_irq(uint8_t source_mask);
-
-protected:
- ioc2_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, uint8_t id);
-
- virtual void device_start() override;
- virtual void device_reset() override;
- virtual void device_add_mconfig(machine_config &config) override;
- virtual ioport_constructor device_input_ports() const override;
-
- required_device<mips3_device> m_maincpu;
- required_device<scc85230_device> m_scc;
- required_device<pc_lpt_device> m_pi1; // we assume standard parallel port (SPP) mode
- // TODO: SGI parallel port (SGIPP), HP BOISE high speed parallel port (HPBPP), and Ricoh scanner modes
- required_device<kbdc8042_device> m_kbdc;
- required_device<pit8254_device> m_pit;
-
- virtual void handle_reset_reg_write(uint8_t data);
-
- uint8_t m_gen_ctrl_select_reg;
- uint8_t m_gen_ctrl_reg;
- uint8_t m_front_panel_reg;
-
- uint8_t m_read_reg;
- uint8_t m_dma_sel;
- uint8_t m_reset_reg;
- uint8_t m_write_reg;
-
- uint8_t m_int3_local0_status_reg;
- uint8_t m_int3_local0_mask_reg;
- uint8_t m_int3_local1_status_reg;
- uint8_t m_int3_local1_mask_reg;
- uint8_t m_int3_map_status_reg;
- uint8_t m_int3_map_mask0_reg;
- uint8_t m_int3_map_mask1_reg;
- uint8_t m_int3_map_pol_reg;
- uint8_t m_int3_timer_clear_reg;
- uint8_t m_int3_err_status_reg;
-
- uint32_t m_par_read_cnt;
- uint32_t m_par_cntl;
- uint8_t m_system_id;
-};
-
-class ioc2_guinness_device : public ioc2_device
-{
-public:
- ioc2_guinness_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
-protected:
- ioc2_guinness_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
- : ioc2_device(mconfig, type, tag, owner, clock, 0x01)
- { }
-};
-
-class ioc2_full_house_device : public ioc2_device
-{
-public:
- ioc2_full_house_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
-protected:
- ioc2_full_house_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
- : ioc2_device(mconfig, type, tag, owner, clock, 0x20)
- { }
-};
-
-DEFINE_DEVICE_TYPE(SGI_IOC2_GUINNESS, ioc2_guinness_device, "ioc2g", "SGI IOC2 (Guiness)")
-DEFINE_DEVICE_TYPE(SGI_IOC2_FULL_HOUSE, ioc2_full_house_device, "ioc2f", "SGI IOC2 (Full House)")
-
-ioc2_guinness_device::ioc2_guinness_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : ioc2_guinness_device(mconfig, SGI_IOC2_GUINNESS, tag, owner, clock)
-{
-}
-
-ioc2_full_house_device::ioc2_full_house_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : ioc2_full_house_device(mconfig, SGI_IOC2_FULL_HOUSE, tag, owner, clock)
-{
-}
-
-static INPUT_PORTS_START( front_panel )
- PORT_START("panel_buttons")
- PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_NAME("Power") PORT_CHANGED_MEMBER(DEVICE_SELF, ioc2_device, power_button, 0)
- PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_NAME("Volume Down") PORT_CHANGED_MEMBER(DEVICE_SELF, ioc2_device, volume_down, 0)
- PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_NAME("Volume Up") PORT_CHANGED_MEMBER(DEVICE_SELF, ioc2_device, volume_up, 0)
-INPUT_PORTS_END
-
-ioport_constructor ioc2_device::device_input_ports() const
-{
- return INPUT_PORTS_NAME(front_panel);
-}
-
-MACHINE_CONFIG_START(ioc2_device::device_add_mconfig)
- MCFG_SCC85230_ADD(SCC_TAG, SCC_PCLK, SCC_RXA_CLK.value(), SCC_TXA_CLK, SCC_RXB_CLK.value(), SCC_TXB_CLK)
- MCFG_Z80SCC_OUT_TXDA_CB(DEVWRITELINE(RS232A_TAG, rs232_port_device, write_txd))
- MCFG_Z80SCC_OUT_DTRA_CB(DEVWRITELINE(RS232A_TAG, rs232_port_device, write_dtr))
- MCFG_Z80SCC_OUT_RTSA_CB(DEVWRITELINE(RS232A_TAG, rs232_port_device, write_rts))
- MCFG_Z80SCC_OUT_TXDB_CB(DEVWRITELINE(RS232B_TAG, rs232_port_device, write_txd))
- MCFG_Z80SCC_OUT_DTRB_CB(DEVWRITELINE(RS232B_TAG, rs232_port_device, write_dtr))
- MCFG_Z80SCC_OUT_RTSB_CB(DEVWRITELINE(RS232B_TAG, rs232_port_device, write_rts))
-
- MCFG_RS232_PORT_ADD(RS232A_TAG, default_rs232_devices, nullptr)
- MCFG_RS232_CTS_HANDLER(DEVWRITELINE(SCC_TAG, scc85230_device, ctsa_w))
- MCFG_RS232_DCD_HANDLER(DEVWRITELINE(SCC_TAG, scc85230_device, dcda_w))
- MCFG_RS232_RXD_HANDLER(DEVWRITELINE(SCC_TAG, scc85230_device, rxa_w))
-
- MCFG_RS232_PORT_ADD(RS232B_TAG, default_rs232_devices, nullptr)
- MCFG_RS232_CTS_HANDLER(DEVWRITELINE(SCC_TAG, scc85230_device, ctsb_w))
- MCFG_RS232_DCD_HANDLER(DEVWRITELINE(SCC_TAG, scc85230_device, dcdb_w))
- MCFG_RS232_RXD_HANDLER(DEVWRITELINE(SCC_TAG, scc85230_device, rxb_w))
-
- MCFG_DEVICE_ADD(PI1_TAG, PC_LPT, 0)
-
- MCFG_DEVICE_ADD(KBDC_TAG, KBDC8042, 0)
- MCFG_KBDC8042_KEYBOARD_TYPE(KBDC8042_STANDARD)
- MCFG_KBDC8042_SYSTEM_RESET_CB(INPUTLINE("^maincpu", INPUT_LINE_RESET))
-
- MCFG_DEVICE_ADD(PIT_TAG, PIT8254, 0)
- MCFG_PIT8253_CLK0(1000000)
- MCFG_PIT8253_CLK1(1000000)
- MCFG_PIT8253_CLK2(1000000)
- MCFG_PIT8253_OUT2_HANDLER(DEVWRITELINE(KBDC_TAG, kbdc8042_device, write_out2))
-MACHINE_CONFIG_END
-
-
-ioc2_device::ioc2_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, uint8_t id)
- : device_t(mconfig, type, tag, owner, clock)
- , m_maincpu(*this, "^maincpu")
- , m_scc(*this, SCC_TAG)
- , m_pi1(*this, PI1_TAG)
- , m_kbdc(*this, KBDC_TAG)
- , m_pit(*this, PIT_TAG)
- , m_gen_ctrl_select_reg(0)
- , m_gen_ctrl_reg(0)
- , m_front_panel_reg(0)
- , m_read_reg(0)
- , m_dma_sel(0)
- , m_reset_reg(0)
- , m_write_reg(0)
- , m_int3_local0_status_reg(0)
- , m_int3_local0_mask_reg(0)
- , m_int3_local1_status_reg(0)
- , m_int3_local1_mask_reg(0)
- , m_int3_map_status_reg(0)
- , m_int3_map_mask0_reg(0)
- , m_int3_map_mask1_reg(0)
- , m_int3_map_pol_reg(0)
- , m_int3_timer_clear_reg(0)
- , m_int3_err_status_reg(0)
- , m_par_read_cnt(0)
- , m_par_cntl(0)
- , m_system_id(id)
-{
-}
-
-#define FRONT_PANEL_POWER_STATE (0x01)
-#define FRONT_PANEL_POWER_BUTTON_INT (0x02)
-#define FRONT_PANEL_VOL_DOWN_INT (0x10)
-#define FRONT_PANEL_VOL_DOWN_HOLD (0x20)
-#define FRONT_PANEL_VOL_UP_INT (0x40)
-#define FRONT_PANEL_VOL_UP_HOLD (0x80)
-
-void ioc2_device::device_start()
-{
- m_front_panel_reg = FRONT_PANEL_POWER_STATE;
-}
-
-void ioc2_device::device_reset()
-{
- m_par_read_cnt = 0;
- m_par_cntl = 0;
-
- m_gen_ctrl_select_reg = 0;
- m_gen_ctrl_reg = 0;
- m_front_panel_reg = FRONT_PANEL_POWER_STATE;
-
- m_read_reg = 0;
- m_dma_sel = 0;
- m_reset_reg = 0;
- m_write_reg = 0;
-
- m_int3_local0_status_reg = 0;
- m_int3_local0_mask_reg = 0;
- m_int3_local1_status_reg = 0;
- m_int3_local1_mask_reg = 0;
- m_int3_map_status_reg = 0;
- m_int3_map_mask0_reg = 0;
- m_int3_map_mask1_reg = 0;
- m_int3_map_pol_reg = 0;
- m_int3_timer_clear_reg = 0;
- m_int3_err_status_reg = 0;
-}
-
-#define INT3_LOCAL0_FIFO (0x01)
-#define INT3_LOCAL0_SCSI0 (0x02)
-#define INT3_LOCAL0_SCSI1 (0x04)
-#define INT3_LOCAL0_ETHERNET (0x08)
-#define INT3_LOCAL0_MC_DMA (0x10)
-#define INT3_LOCAL0_PARALLEL (0x20)
-#define INT3_LOCAL0_GRAPHICS (0x40)
-#define INT3_LOCAL0_MAPPABLE0 (0x80)
-
-#define INT3_LOCAL1_GP0 (0x01)
-#define INT3_LOCAL1_PANEL (0x02)
-#define INT3_LOCAL1_GP2 (0x04)
-#define INT3_LOCAL1_MAPPABLE1 (0x08)
-#define INT3_LOCAL1_HPC_DMA (0x10)
-#define INT3_LOCAL1_AC_FAIL (0x20)
-#define INT3_LOCAL1_VSYNC (0x40)
-#define INT3_LOCAL1_RETRACE (0x80)
-
-void ioc2_device::raise_local0_irq(uint8_t source_mask)
-{
- m_int3_local0_status_reg |= source_mask;
- m_maincpu->set_input_line(MIPS3_IRQ0, (m_int3_local0_mask_reg & m_int3_local0_status_reg) != 0 ? ASSERT_LINE : CLEAR_LINE);
-}
-
-void ioc2_device::lower_local0_irq(uint8_t source_mask)
-{
- m_int3_local0_status_reg &= ~source_mask;
-}
-
-void ioc2_device::raise_local1_irq(uint8_t source_mask)
-{
- m_int3_local1_status_reg |= source_mask;
- m_maincpu->set_input_line(MIPS3_IRQ1, (m_int3_local1_mask_reg & m_int3_local1_status_reg) != 0 ? ASSERT_LINE : CLEAR_LINE);
-}
-
-void ioc2_device::lower_local1_irq(uint8_t source_mask)
-{
- m_int3_local1_status_reg &= ~source_mask;
-}
-
-READ32_MEMBER( ioc2_device::read )
-{
- switch (offset)
- {
- case 0x00/4: case 0x04/4: case 0x08/4:
- return m_pi1->read(space, offset, 0xff);
-
- case 0x0c/4: // Parallel Port DMA Control Register [docs?]
- case 0x10/4: // Parallel Port Interrupt Status Register [docs?]
- case 0x14/4: // Parallel Port Interrupt Mask Register [docs?]
- case 0x18/4: // Parallel Port Timer 1 Register [docs?]
- case 0x1c/4: // Parallel Port Timer 2 Register [docs?]
- case 0x20/4: // Parallel Port Timer 3 Register [docs?]
- case 0x24/4: // Parallel Port Timer 4 Register [docs?]
- return 0;
-
- case 0x30/4: // Serial Port1 Command Transfer
- case 0x34/4: // Serial Port1 Data Transfer
- case 0x38/4: // Serial Port2 Command Transfer
- case 0x3c/4: // Serial Port2 Data Transfer
- return m_scc->ba_cd_r(space, (offset - 0x30/4) ^ 3);
-
- case 0x40/4: // Keyboard/Mouse Registers
- case 0x44/4: // Keyboard/Mouse Registers
- return m_kbdc->data_r(space, (offset - 0x40/4) * 4);
-
- case 0x50/4: // Front Panel Register
- return m_front_panel_reg;
-
- case 0x58/4: // System ID Register
- return m_system_id;
-
- case 0x60/4: // Read Register
- return m_read_reg;
-
- case 0x68/4: // DMA_SEL Register
- // Bits 2-0 not quite understood, seem to be copy/paste error in SGI's own documents:
- //
- // 2 RW Parallel Port DMA Select. A high bit selects the Parallel Port DMA channel. 0\h is the default after reset. [this makes sense. -ed.]
- // 1 RW ISDN Channel B DMA Select. A high bit selects the Parallel Port DMA channel. 0\h is the default after reset. [is this a copy/paste error? perhaps "Parallel Port" should be "ISDN Channel B"?]
- // 0 RW [same text as above. Another copy/paste error, maybe? Should be channel A, with the bit selecting DMA channel 0/1 for ISDN channel A, the and the same for ISDN channel B in bit 1?]
- return m_dma_sel;
-
- case 0x70/4: // Reset Register
- return m_reset_reg;
-
- case 0x78/4: // Write Register
- // Not yet implemented, some bits unnecessary:
- //
- // Bit Oper Description
- // 7 RW Margin High. Set low for normal +5V operation, high to step supply up to +5.5V. Cleared at reset.
- // 6 RW Margin Low. Set lowf or normal +5V operation, high to step supply down to +4.5V. Cleared at reset.
- // 5 RW UART1 PC Mode. Set low to configure Port1 for RS422 Mac mode, high to select RS232 PC mode. Cleared at reset.
- // 4 RW UART2 PC Mode. Set low to configure Port2 for RS422 Mac mode, high to select RS232 PC mode. Cleared at reset.
- // 3 RW Ethernet Auto Select (active high). Set low for manual mode, high to have LXT901 automatically select TP or AUI based on link integrity. Cleared at reset.
- // 2 RW Ethernet Port Select. Set low for TP, high for AUI. This setting is only used when Auto Select is in manual mode. Cleared at reset.
- // 1 RW Ethernet UTP/STP select. Set low to select 150 ohm termination fro shielded TP (default), set high to select 100 ohm termination for unshielded TP. Cleared at reset.
- // 0 RW Ethernet Normal Threshold (NTH) select. Set low to select the normal TP squelch threshold (default), high to reduce threshold by 4.5 dB (set low when reset).
- return m_write_reg;
-
- case 0x80/4: // INT3 Local0 Status Register
- return m_int3_local0_status_reg;
-
- case 0x84/4: // INT3 Local0 Mask Register
- return m_int3_local0_mask_reg;
-
- case 0x88/4: // INT3 Local1 Status Register
- return m_int3_local1_status_reg;
-
- case 0x8c/4: // INT3 Local1 Mask Register
- return m_int3_local1_mask_reg;
-
- case 0x90/4: // INT3 Map Status Register [TODO]
- return m_int3_map_status_reg;
-
- case 0x94/4: // INT3 Map Mask0 Register [TODO]
- return m_int3_map_mask0_reg;
-
- case 0x98/4: // INT3 Map Mask1 Register [TODO]
- return m_int3_map_mask1_reg;
-
- case 0x9c/4: // INT3 Map Pol Register [TODO]
- return m_int3_map_pol_reg;
-
- case 0xa0/4: // INT3 Timer Clear Register [TODO]
- return m_int3_timer_clear_reg;
-
- case 0xa4/4: // INT3 Error Status Register [TODO]
- return m_int3_err_status_reg;
-
- case 0xb0/4: // Timer Counter 0 Register
- case 0xb4/4: // Timer Counter 1 Register
- case 0xb8/4: // Timer Counter 2 Register
- case 0xbc/4: // Timer Control Word Register
- return m_pit->read(space, offset - 0xb0/4);
- }
-
- return 0;
-}
-
-#define DMA_SEL_CLOCK_SEL_MASK (0x30)
-#define DMA_SEL_CLOCK_SEL_10MHz (0x00)
-#define DMA_SEL_CLOCK_SEL_6_67MHz (0x10)
-#define DMA_SEL_CLOCK_SEL_EXT (0x20)
-
-WRITE32_MEMBER( ioc2_device::write )
-{
- switch (offset)
- {
- case 0x00/4: case 0x04/4: case 0x08/4:
- m_pi1->write(space, offset, data & 0xff, 0xff);
- return;
-
- case 0x0c/4: // Parallel Port DMA Control Register [docs?]
- case 0x10/4: // Parallel Port Interrupt Status Register [docs?]
- case 0x14/4: // Parallel Port Interrupt Mask Register [docs?]
- case 0x18/4: // Parallel Port Timer 1 Register [docs?]
- case 0x1c/4: // Parallel Port Timer 2 Register [docs?]
- case 0x20/4: // Parallel Port Timer 3 Register [docs?]
- case 0x24/4: // Parallel Port Timer 4 Register [docs?]
- return;
-
- case 0x30/4: // Serial Port1 Command Transfer
- case 0x34/4: // Serial Port1 Data Transfer
- case 0x38/4: // Serial Port2 Command Transfer
- case 0x3c/4: // Serial Port2 Data Transfer
- m_scc->ba_cd_w(space, (offset - 0x30/4) ^ 3, data & 0xff);
- return;
-
- case 0x40/4: // Keyboard/Mouse Registers
- case 0x44/4: // Keyboard/Mouse Registers
- m_kbdc->data_w(space, (offset - 0x40/4) * 4, data & 0xff);
- return;
-
- case 0x50/4: // Front Panel Register
- m_front_panel_reg &= ~(data & (FRONT_PANEL_VOL_UP_INT | FRONT_PANEL_VOL_DOWN_INT | FRONT_PANEL_POWER_BUTTON_INT));
- return;
-
- case 0x68/4: // DMA_SEL Register
- {
- // Bits 2-0 not quite understood, seem to be copy/paste error in SGI's own documents:
- //
- // 5:4 RW Serial Port Clock Select: 00 selects a 10MHz internal clock (default), 01 selects a 6.67MHz internal clock, and 02 or 03 selects the external clock input.
- // 2 RW Parallel Port DMA Select. A high bit selects the Parallel Port DMA channel. 0\h is the default after reset. [this makes sense. -ed.]
- // 1 RW ISDN Channel B DMA Select. A high bit selects the Parallel Port DMA channel. 0\h is the default after reset. [is this a copy/paste error? perhaps "Parallel Port" should be "ISDN Channel B"?]
- // 0 RW [same text as above. Another copy/paste error, maybe? Should be channel A, with the bit selecting DMA channel 0/1 for ISDN channel A, the and the same for ISDN channel B in bit 1?]
- uint8_t old = m_dma_sel;
- m_dma_sel = data;
- uint8_t diff = old ^ m_dma_sel;
- if (diff & DMA_SEL_CLOCK_SEL_MASK)
- {
- if (diff & DMA_SEL_CLOCK_SEL_EXT)
- {
- printf("External clock select %sselected\n", (old & DMA_SEL_CLOCK_SEL_EXT) != 0 ? "de" : "");
- // TODO: verify the external Rx/Tx clock, is it fixed or programmable?
- }
- }
- // TODO: Currently we always assume a 10MHz clock as PCLK
- return;
- }
-
- case 0x70/4: // Reset Register
- handle_reset_reg_write(data);
- return;
-
- case 0x78/4: // Write Register
- m_write_reg = data;
- return;
-
- case 0x80/4: // INT3 Local0 Status Register
- case 0x88/4: // INT3 Local1 Status Register
- case 0x90/4: // INT3 Map Status Register
- case 0xa4/4: // INT3 Error Stat Register
- // Read-only registers
- return;
-
- case 0x84/4: // INT3 Local0 Mask Register
- {
- uint8_t old = m_int3_local0_mask_reg;
- m_int3_local0_mask_reg = data;
- bool old_line = (old & m_int3_local0_status_reg) != 0;
- bool new_line = (m_int3_local0_mask_reg & m_int3_local0_status_reg) != 0;
- if (old_line != new_line)
- m_maincpu->set_input_line(MIPS3_IRQ0, (m_int3_local0_mask_reg & m_int3_local0_status_reg) != 0 ? ASSERT_LINE : CLEAR_LINE);
- return;
- }
-
- case 0x8c/4: // INT3 Local1 Mask Register
- {
- uint8_t old = m_int3_local0_mask_reg;
- m_int3_local0_mask_reg = data;
- bool old_line = (old & m_int3_local0_status_reg) != 0;
- bool new_line = (m_int3_local0_mask_reg & m_int3_local0_status_reg) != 0;
- if (old_line != new_line)
- m_maincpu->set_input_line(MIPS3_IRQ0, (m_int3_local0_mask_reg & m_int3_local0_status_reg) != 0 ? ASSERT_LINE : CLEAR_LINE);
- return;
- }
-
- case 0x94/4: // INT3 Map Mask0 Register
- // TODO: Implement mappable interrupts
- m_int3_map_mask0_reg = data;
- return;
-
- case 0x98/4: // INT3 Map Mask1 Register
- // TODO: Implement mappable interrupts
- m_int3_map_mask1_reg = data;
- return;
-
- case 0x9c/4: // INT3 Map Pol Register
- // TODO: Mappable interrupt polarity select
- m_int3_map_pol_reg = data;
- return;
-
- case 0xb0/4: // Timer Counter 0 Register
- case 0xb4/4: // Timer Counter 1 Register
- case 0xb8/4: // Timer Counter 2 Register
- case 0xbc/4: // Timer Control Word Register
- m_pit->write(space, offset - 0xb0/4, data & 0xff);
- return;
- }
-}
-
-void ioc2_device::handle_reset_reg_write(uint8_t data)
-{
- // guinness/fullhouse-specific implementations can handle bit 3 being used for ISDN reset on Indy only and bit 2 for EISA reset on Indigo 2 only, but for now we do nothing with it
- m_reset_reg = data;
-}
-
-INPUT_CHANGED_MEMBER( ioc2_device::power_button )
-{
- if (!newval)
- {
- m_front_panel_reg |= FRONT_PANEL_POWER_BUTTON_INT;
- }
-}
-
-INPUT_CHANGED_MEMBER( ioc2_device::volume_up )
-{
- if (!newval)
- {
- m_front_panel_reg |= FRONT_PANEL_VOL_UP_INT;
- m_front_panel_reg |= FRONT_PANEL_VOL_UP_HOLD;
- }
- else
- {
- m_front_panel_reg &= ~FRONT_PANEL_VOL_UP_HOLD;
- }
-}
-
-INPUT_CHANGED_MEMBER( ioc2_device::volume_down )
-{
- if (!newval)
- {
- m_front_panel_reg |= FRONT_PANEL_VOL_DOWN_INT;
- m_front_panel_reg |= FRONT_PANEL_VOL_DOWN_HOLD;
- }
- else
- {
- m_front_panel_reg &= ~FRONT_PANEL_VOL_DOWN_HOLD;
- }
-}
-
-#define IOC2_TAG "ioc2"
-#define RTC_TAG "ds1386"
-
-struct hpc3_t
-{
- uint32_t m_enetr_nbdp;
- uint32_t m_enetr_cbp;
- uint32_t m_unk0;
- uint32_t m_unk1;
- uint32_t m_ic_unk0;
- uint32_t m_scsi0_desc;
- uint32_t m_scsi0_dma_ctrl;
-};
-
-struct hal2
-{
- uint32_t m_iar;
- uint32_t m_idr[4];
-};
-
-struct pbus_dma_t
-{
- uint8_t m_active;
- uint32_t m_cur_ptr;
- uint32_t m_desc_ptr;
- uint32_t m_next_ptr;
- uint32_t m_words_left;
-};
-
class ip22_state : public driver_device
{
public:
- enum
- {
- TIMER_IP22_DMA
- };
-
ip22_state(const machine_config &mconfig, device_type type, const char *tag)
: driver_device(mconfig, type, tag)
, m_maincpu(*this, "maincpu")
- , m_wd33c93(*this, "wd33c93")
- , m_unkpbus0(*this, "unkpbus0")
, m_mainram(*this, "mainram")
, m_sgi_mc(*this, "sgi_mc")
, m_newport(*this, "newport")
, m_dac(*this, "dac")
- , m_ioc2(*this, IOC2_TAG)
+ , m_scsi(*this, "wd33c93")
+ , m_hal2(*this, HAL2_TAG)
+ , m_hpc3(*this, HPC3_TAG)
+ , m_ioc2(*this, "ioc2")
, m_rtc(*this, RTC_TAG)
{
}
@@ -639,62 +83,42 @@ public:
virtual void machine_start() override;
virtual void machine_reset() override;
- DECLARE_READ32_MEMBER(hpc3_hd_enet_r);
- DECLARE_WRITE32_MEMBER(hpc3_hd_enet_w);
- DECLARE_READ32_MEMBER(hpc3_hd0_r);
- DECLARE_WRITE32_MEMBER(hpc3_hd0_w);
- DECLARE_READ32_MEMBER(hpc3_pbus4_r);
- DECLARE_WRITE32_MEMBER(hpc3_pbus4_w);
- DECLARE_READ32_MEMBER(hpc3_pbusdma_r);
- DECLARE_WRITE32_MEMBER(hpc3_pbusdma_w);
- DECLARE_READ32_MEMBER(hpc3_unkpbus0_r);
- DECLARE_WRITE32_MEMBER(hpc3_unkpbus0_w);
-
DECLARE_WRITE32_MEMBER(ip22_write_ram);
- DECLARE_READ32_MEMBER(hal2_r);
- DECLARE_WRITE32_MEMBER(hal2_w);
-
- DECLARE_WRITE_LINE_MEMBER(scsi_irq);
-
DECLARE_DRIVER_INIT(ip225015);
- TIMER_CALLBACK_MEMBER(ip22_dma);
-
- static void cdrom_config(device_t *device);
void ip225015(machine_config &config);
void ip224613(machine_config &config);
void ip244415(machine_config &config);
void ip225015_map(address_map &map);
-protected:
- virtual void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
+ static void cdrom_config(device_t *device);
+
+ static const char* HAL2_TAG;
+ static const char* HPC3_TAG;
+ static const char* RTC_TAG;
+
+protected:
required_device<mips3_device> m_maincpu;
- required_device<wd33c93_device> m_wd33c93;
- required_shared_ptr<uint32_t> m_unkpbus0;
required_shared_ptr<uint32_t> m_mainram;
required_device<sgi_mc_device> m_sgi_mc;
required_device<newport_video_device> m_newport;
required_device<dac_word_interface> m_dac;
+ required_device<wd33c93_device> m_scsi;
+ required_device<hal2_device> m_hal2;
+ required_device<hpc3_device> m_hpc3;
required_device<ioc2_device> m_ioc2;
required_device<ds1386_device> m_rtc;
- void dump_chain(address_space &space, uint32_t ch_base);
-
- hpc3_t m_hpc3;
-
- hal2 m_hal2;
-
- pbus_dma_t m_pbus_dma;
- uint8_t m_dma_buffer[4096];
-
inline void ATTR_PRINTF(3,4) verboselog(int n_level, const char *s_fmt, ... );
};
+/*static*/ const char* ip22_state::HAL2_TAG = "hal2";
+/*static*/ const char* ip22_state::HPC3_TAG = "hpc3";
+/*static*/ const char* ip22_state::RTC_TAG = "rtc";
#define VERBOSE_LEVEL ( 0 )
-
inline void ATTR_PRINTF(3,4) ip22_state::verboselog(int n_level, const char *s_fmt, ... )
{
if( VERBOSE_LEVEL >= n_level )
@@ -708,155 +132,6 @@ inline void ATTR_PRINTF(3,4) ip22_state::verboselog(int n_level, const char *s_f
}
}
-
-READ32_MEMBER(ip22_state::hpc3_hd_enet_r)
-{
- switch( offset )
- {
- case 0x0004/4:
- //verboselog((machine, 0, "HPC3 SCSI0DESC Read: %08x (%08x): %08x\n", 0x1fb90000 + ( offset << 2), mem_mask, m_hpc3.m_scsi0_desc );
- return m_hpc3.m_scsi0_desc;
- case 0x1004/4:
- //verboselog((machine, 0, "HPC3 SCSI0DMACTRL Read: %08x (%08x): %08x\n", 0x1fb90000 + ( offset << 2), mem_mask, m_hpc3.m_scsi0_dma_ctrl );
- return m_hpc3.m_scsi0_dma_ctrl;
- case 0x4000/4:
- //verboselog((machine, 2, "HPC3 ENETR CBP Read: %08x (%08x): %08x\n", 0x1fb90000 + ( offset << 2), mem_mask, m_hpc3.m_enetr_nbdp );
- return m_hpc3.m_enetr_cbp;
- case 0x4004/4:
- //verboselog((machine, 2, "HPC3 ENETR NBDP Read: %08x (%08x): %08x\n", 0x1fb90000 + ( offset << 2), mem_mask, m_hpc3.m_enetr_nbdp );
- return m_hpc3.m_enetr_nbdp;
- default:
- //verboselog((machine, 0, "Unknown HPC3 ENET/HDx Read: %08x (%08x)\n", 0x1fb90000 + ( offset << 2 ), mem_mask );
- return 0;
- }
-}
-
-WRITE32_MEMBER(ip22_state::hpc3_hd_enet_w)
-{
- switch( offset )
- {
- case 0x0004/4:
- //verboselog((machine, 2, "HPC3 SCSI0DESC Write: %08x\n", data );
- m_hpc3.m_scsi0_desc = data;
- break;
- case 0x1004/4:
- //verboselog((machine, 2, "HPC3 SCSI0DMACTRL Write: %08x\n", data );
- m_hpc3.m_scsi0_dma_ctrl = data;
- break;
- case 0x4000/4:
- //verboselog((machine, 2, "HPC3 ENETR CBP Write: %08x\n", data );
- m_hpc3.m_enetr_cbp = data;
- break;
- case 0x4004/4:
- //verboselog((machine, 2, "HPC3 ENETR NBDP Write: %08x\n", data );
- m_hpc3.m_enetr_nbdp = data;
- break;
- default:
- //verboselog((machine, 0, "Unknown HPC3 ENET/HDx write: %08x (%08x): %08x\n", 0x1fb90000 + ( offset << 2 ), mem_mask, data );
- break;
- }
-}
-
-READ32_MEMBER(ip22_state::hpc3_hd0_r)
-{
- switch( offset )
- {
- case 0x0000/4:
- case 0x4000/4:
-// //verboselog((machine, 2, "HPC3 HD0 Status Read: %08x (%08x): %08x\n", 0x1fb90000 + ( offset << 2), mem_mask, nHPC3_hd0_regs[0x17] );
- if (ACCESSING_BITS_0_7)
- {
- return m_wd33c93->read( space, 0 );
- }
- else
- {
- return 0;
- }
- case 0x0004/4:
- case 0x4004/4:
-// //verboselog((machine, 2, "HPC3 HD0 Register Read: %08x (%08x): %08x\n", 0x1fb90000 + ( offset << 2), mem_mask, nHPC3_hd0_regs[nHPC3_hd0_register] );
- if (ACCESSING_BITS_0_7)
- {
- return m_wd33c93->read( space, 1 );
- }
- else
- {
- return 0;
- }
- default:
- //verboselog((machine, 0, "Unknown HPC3 HD0 Read: %08x (%08x) [%x] PC=%x\n", 0x1fbc0000 + ( offset << 2 ), mem_mask, offset, m_maincpu->pc() );
- return 0;
- }
-}
-
-WRITE32_MEMBER(ip22_state::hpc3_hd0_w)
-{
- switch( offset )
- {
- case 0x0000/4:
- case 0x4000/4:
-// //verboselog((machine, 2, "HPC3 HD0 Register Select Write: %08x\n", data );
- if (ACCESSING_BITS_0_7)
- {
- m_wd33c93->write( space, 0, data & 0x000000ff );
- }
- break;
- case 0x0004/4:
- case 0x4004/4:
-// //verboselog((machine, 2, "HPC3 HD0 Register %d Write: %08x\n", nHPC3_hd0_register, data );
- if (ACCESSING_BITS_0_7)
- {
- m_wd33c93->write( space, 1, data & 0x000000ff );
- }
- break;
- default:
- //verboselog((machine, 0, "Unknown HPC3 HD0 Write: %08x (%08x): %08x\n", 0x1fbc0000 + ( offset << 2 ), mem_mask, data );
- break;
- }
-}
-
-
-READ32_MEMBER(ip22_state::hpc3_pbus4_r)
-{
- switch( offset )
- {
- case 0x0004/4:
- //verboselog((machine, 2, "HPC3 PBUS4 Unknown 0 Read: (%08x): %08x\n", mem_mask, m_hpc3.m_unk0 );
- return m_hpc3.m_unk0;
- case 0x000c/4:
- //verboselog((machine, 2, "Interrupt Controller(?) Read: (%08x): %08x\n", mem_mask, m_hpc3.m_ic_unk0 );
- return m_hpc3.m_ic_unk0;
- case 0x0014/4:
- //verboselog((machine, 2, "HPC3 PBUS4 Unknown 1 Read: (%08x): %08x\n", mem_mask, m_hpc3.m_unk1 );
- return m_hpc3.m_unk1;
- default:
- //verboselog((machine, 0, "Unknown HPC3 PBUS4 Read: %08x (%08x)\n", 0x1fbd9000 + ( offset << 2 ), mem_mask );
- return 0;
- }
-}
-
-WRITE32_MEMBER(ip22_state::hpc3_pbus4_w)
-{
- switch( offset )
- {
- case 0x0004/4:
- //verboselog((machine, 2, "HPC3 PBUS4 Unknown 0 Write: %08x (%08x)\n", data, mem_mask );
- m_hpc3.m_unk0 = data;
- break;
- case 0x000c/4:
- //verboselog((machine, 2, "Interrupt Controller(?) Write: (%08x): %08x\n", mem_mask, data );
- m_hpc3.m_ic_unk0 = data;
- break;
- case 0x0014/4:
- //verboselog((machine, 2, "HPC3 PBUS4 Unknown 1 Write: %08x (%08x)\n", data, mem_mask );
- m_hpc3.m_unk1 = data;
- break;
- default:
- //verboselog((machine, 0, "Unknown HPC3 PBUS4 Write: %08x (%08x): %08x\n", 0x1fbd9000 + ( offset << 2 ), mem_mask, data );
- break;
- }
-}
-
// a bit hackish, but makes the memory detection work properly and allows a big cleanup of the mapping
WRITE32_MEMBER(ip22_state::ip22_write_ram)
{
@@ -876,310 +151,20 @@ WRITE32_MEMBER(ip22_state::ip22_write_ram)
COMBINE_DATA(&m_mainram[offset]);
}
-
-#define H2_IAR_TYPE 0xf000
-#define H2_IAR_NUM 0x0f00
-#define H2_IAR_ACCESS_SEL 0x0080
-#define H2_IAR_PARAM 0x000c
-#define H2_IAR_RB_INDEX 0x0003
-
-#define H2_ISR_TSTATUS 0x01
-#define H2_ISR_USTATUS 0x02
-#define H2_ISR_QUAD_MODE 0x04
-#define H2_ISR_GLOBAL_RESET 0x08
-#define H2_ISR_CODEC_RESET 0x10
-
-READ32_MEMBER(ip22_state::hal2_r)
-{
- switch( offset )
- {
- case 0x0010/4:
- //verboselog((machine, 0, "HAL2 Status read: 0x0004\n" );
- return 0x0004;
- case 0x0020/4:
- //verboselog((machine, 0, "HAL2 Revision read: 0x4011\n" );
- return 0x4011;
- }
- //verboselog((machine, 0, "Unknown HAL2 read: 0x%08x (%08x)\n", 0x1fbd8000 + offset*4, mem_mask );
- return 0;
-}
-
-WRITE32_MEMBER(ip22_state::hal2_w)
-{
- switch( offset )
- {
- case 0x0010/4:
- //verboselog((machine, 0, "HAL2 Status Write: 0x%08x (%08x)\n", data, mem_mask );
- if( data & H2_ISR_GLOBAL_RESET )
- {
- //verboselog((machine, 0, " HAL2 Global Reset\n" );
- }
- if( data & H2_ISR_CODEC_RESET )
- {
- //verboselog((machine, 0, " HAL2 Codec Reset\n" );
- }
- break;
- case 0x0030/4:
- //verboselog((machine, 0, "HAL2 Indirect Address Register Write: 0x%08x (%08x)\n", data, mem_mask );
- m_hal2.m_iar = data;
- switch( data & H2_IAR_TYPE )
- {
- case 0x1000:
- //verboselog((machine, 0, " DMA Port\n" );
- switch( data & H2_IAR_NUM )
- {
- case 0x0100:
- //verboselog((machine, 0, " Synth In\n" );
- break;
- case 0x0200:
- //verboselog((machine, 0, " AES In\n" );
- break;
- case 0x0300:
- //verboselog((machine, 0, " AES Out\n" );
- break;
- case 0x0400:
- //verboselog((machine, 0, " DAC Out\n" );
- break;
- case 0x0500:
- //verboselog((machine, 0, " ADC Out\n" );
- break;
- case 0x0600:
- //verboselog((machine, 0, " Synth Control\n" );
- break;
- }
- break;
- case 0x2000:
- //verboselog((machine, 0, " Bresenham\n" );
- switch( data & H2_IAR_NUM )
- {
- case 0x0100:
- //verboselog((machine, 0, " Bresenham Clock Gen 1\n" );
- break;
- case 0x0200:
- //verboselog((machine, 0, " Bresenham Clock Gen 2\n" );
- break;
- case 0x0300:
- //verboselog((machine, 0, " Bresenham Clock Gen 3\n" );
- break;
- }
- break;
- case 0x3000:
- //verboselog((machine, 0, " Unix Timer\n" );
- switch( data & H2_IAR_NUM )
- {
- case 0x0100:
- //verboselog((machine, 0, " Unix Timer\n" );
- break;
- }
- break;
- case 0x9000:
- //verboselog((machine, 0, " Global DMA Control\n" );
- switch( data & H2_IAR_NUM )
- {
- case 0x0100:
- //verboselog((machine, 0, " DMA Control\n" );
- break;
- }
- break;
- }
- switch( data & H2_IAR_ACCESS_SEL )
- {
- case 0x0000:
- //verboselog((machine, 0, " Write\n" );
- break;
- case 0x0080:
- //verboselog((machine, 0, " Read\n" );
- break;
- }
- //verboselog((machine, 0, " Parameter: %01x\n", ( data & H2_IAR_PARAM ) >> 2 );
- return;
- /* FIXME: this code is never excuted */
- //verboselog((machine, 0, " Read Back Index: %01x\n", ( data & H2_IAR_RB_INDEX ) );
- //break;
- case 0x0040/4:
- //verboselog((machine, 0, "HAL2 Indirect Data Register 0 Write: 0x%08x (%08x)\n", data, mem_mask );
- m_hal2.m_idr[0] = data;
- return;
- case 0x0050/4:
- //verboselog((machine, 0, "HAL2 Indirect Data Register 1 Write: 0x%08x (%08x)\n", data, mem_mask );
- m_hal2.m_idr[1] = data;
- return;
- case 0x0060/4:
- //verboselog((machine, 0, "HAL2 Indirect Data Register 2 Write: 0x%08x (%08x)\n", data, mem_mask );
- m_hal2.m_idr[2] = data;
- return;
- case 0x0070/4:
- //verboselog((machine, 0, "HAL2 Indirect Data Register 3 Write: 0x%08x (%08x)\n", data, mem_mask );
- m_hal2.m_idr[3] = data;
- return;
- }
- //verboselog((machine, 0, "Unknown HAL2 write: 0x%08x: 0x%08x (%08x)\n", 0x1fbd8000 + offset*4, data, mem_mask );
-}
-
-#define PBUS_CTRL_ENDIAN 0x00000002
-#define PBUS_CTRL_RECV 0x00000004
-#define PBUS_CTRL_FLUSH 0x00000008
-#define PBUS_CTRL_DMASTART 0x00000010
-#define PBUS_CTRL_LOAD_EN 0x00000020
-#define PBUS_CTRL_REALTIME 0x00000040
-#define PBUS_CTRL_HIGHWATER 0x0000ff00
-#define PBUS_CTRL_FIFO_BEG 0x003f0000
-#define PBUS_CTRL_FIFO_END 0x3f000000
-
-#define PBUS_DMADESC_EOX 0x80000000
-#define PBUS_DMADESC_EOXP 0x40000000
-#define PBUS_DMADESC_XIE 0x20000000
-#define PBUS_DMADESC_IPG 0x00ff0000
-#define PBUS_DMADESC_TXD 0x00008000
-#define PBUS_DMADESC_BC 0x00003fff
-
-
-void ip22_state::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
-{
- switch (id)
- {
- case TIMER_IP22_DMA:
- ip22_dma(ptr, param);
- break;
- default:
- assert_always(false, "Unknown id in ip22_state::device_timer");
- }
-}
-
-TIMER_CALLBACK_MEMBER(ip22_state::ip22_dma)
-{
- timer_set(attotime::never, TIMER_IP22_DMA);
-#if 0
- if( m_pbus_dma.m_active )
- {
- uint16_t temp16 = ( m_mainram[(m_pbus_dma.m_cur_ptr - 0x08000000)/4] & 0xffff0000 ) >> 16;
- int16_t stemp16 = (int16_t)((temp16 >> 8) | (temp16 << 8));
-
- m_dac->write_signed16(stemp16);
-
- m_pbus_dma.m_cur_ptr += 4;
-
- m_pbus_dma.m_words_left -= 4;
- if( m_pbus_dma.m_words_left == 0 )
- {
- if( m_pbus_dma.m_next_ptr != 0 )
- {
- m_pbus_dma.m_desc_ptr = m_pbus_dma.m_next_ptr;
- m_pbus_dma.m_cur_ptr = m_mainram[(m_pbus_dma.m_desc_ptr - 0x08000000)/4];
- m_pbus_dma.m_words_left = m_mainram[(m_pbus_dma.m_desc_ptr - 0x08000000)/4+1];
- m_pbus_dma.m_next_ptr = m_mainram[(m_pbus_dma.m_desc_ptr - 0x08000000)/4+2];
- }
- else
- {
- m_pbus_dma.m_active = 0;
- return;
- }
- }
- timer_set(attotime::from_hz(44100), TIMER_IP22_DMA);
- }
-#endif
-}
-
-READ32_MEMBER(ip22_state::hpc3_pbusdma_r)
-{
- //uint32_t channel = offset / (0x2000/4);
- //verboselog((machine(), 0, "PBUS DMA Channel %d Read: 0x%08x (%08x)\n", channel, 0x1fb80000 + offset*4, mem_mask );
- return 0;
-}
-
-WRITE32_MEMBER(ip22_state::hpc3_pbusdma_w)
-{
- uint32_t channel = offset / (0x2000/4);
-
- switch( offset & 0x07ff )
- {
- case 0x0000/4:
- //verboselog((machine, 0, "PBUS DMA Channel %d Buffer Pointer Write: 0x%08x\n", channel, data );
- return;
- case 0x0004/4:
- //verboselog((machine, 0, "PBUS DMA Channel %d Descriptor Pointer Write: 0x%08x\n", channel, data );
- if( channel == 1 )
- {
- m_pbus_dma.m_desc_ptr = data;
- m_pbus_dma.m_cur_ptr = m_mainram[(m_pbus_dma.m_desc_ptr - 0x08000000)/4];
- m_pbus_dma.m_words_left = m_mainram[(m_pbus_dma.m_desc_ptr - 0x08000000)/4+1];
- m_pbus_dma.m_next_ptr = m_mainram[(m_pbus_dma.m_desc_ptr - 0x08000000)/4+2];
- //verboselog((machine, 0, "nPBUS_DMA_DescPtr = %08x\n", m_pbus_dma.m_desc_ptr );
- //verboselog((machine, 0, "nPBUS_DMA_CurPtr = %08x\n", m_pbus_dma.m_cur_ptr );
- //verboselog((machine, 0, "nPBUS_DMA_WordsLeft = %08x\n", m_pbus_dma.m_words_left );
- //verboselog((machine, 0, "nPBUS_DMA_NextPtr = %08x\n", m_pbus_dma.m_next_ptr );
- }
- return;
- case 0x1000/4:
- //verboselog((machine, 0, "PBUS DMA Channel %d Control Register Write: 0x%08x\n", channel, data );
- if( data & PBUS_CTRL_ENDIAN )
- {
- //verboselog((machine, 0, " Little Endian\n" );
- }
- else
- {
- //verboselog((machine, 0, " Big Endian\n" );
- }
- if( data & PBUS_CTRL_RECV )
- {
- //verboselog((machine, 0, " RX DMA\n" );
- }
- else
- {
- //verboselog((machine, 0, " TX DMA\n" );
- }
- if( data & PBUS_CTRL_FLUSH )
- {
- //verboselog((machine, 0, " Flush for RX\n" );
- }
- if( data & PBUS_CTRL_DMASTART )
- {
- //verboselog((machine, 0, " Start DMA\n" );
- }
- if( data & PBUS_CTRL_LOAD_EN )
- {
- //verboselog((machine, 0, " Load Enable\n" );
- }
- //verboselog((machine, 0, " High Water Mark: %04x bytes\n", ( data & PBUS_CTRL_HIGHWATER ) >> 8 );
- //verboselog((machine, 0, " FIFO Begin: Row %04x\n", ( data & PBUS_CTRL_FIFO_BEG ) >> 16 );
- //verboselog((machine, 0, " FIFO End: Rowe %04x\n", ( data & PBUS_CTRL_FIFO_END ) >> 24 );
- if( ( data & PBUS_CTRL_DMASTART ) || ( data & PBUS_CTRL_LOAD_EN ) )
- {
- timer_set(attotime::from_hz(44100), TIMER_IP22_DMA);
- m_pbus_dma.m_active = 1;
- }
- return;
- }
- //verboselog((machine, 0, "Unknown PBUS DMA Channel %d Write: 0x%08x: 0x%08x (%08x)\n", channel, 0x1fb80000 + offset*4, data, mem_mask );
-}
-
-READ32_MEMBER(ip22_state::hpc3_unkpbus0_r)
-{
- return 0;
- ////verboselog((machine(), 0, "Unknown PBUS Read: 0x%08x (%08x)\n", 0x1fbc8000 + offset*4, mem_mask );
- //return m_unkpbus0[offset];
-}
-
-WRITE32_MEMBER(ip22_state::hpc3_unkpbus0_w)
-{
- ////verboselog((machine(), 0, "Unknown PBUS Write: 0x%08x = 0x%08x (%08x)\n", 0x1fbc8000 + offset*4, data, mem_mask );
- //COMBINE_DATA(&m_unkpbus0[offset]);
-}
-
void ip22_state::ip225015_map(address_map &map)
{
map(0x00000000, 0x0007ffff).bankrw("bank1"); /* mirror of first 512k of main RAM */
map(0x08000000, 0x0fffffff).share("mainram").ram().w(this, FUNC(ip22_state::ip22_write_ram)); /* 128 MB of main RAM */
map(0x1f0f0000, 0x1f0f1fff).rw(m_newport, FUNC(newport_video_device::rex3_r), FUNC(newport_video_device::rex3_w));
map(0x1fa00000, 0x1fa1ffff).rw(m_sgi_mc, FUNC(sgi_mc_device::read), FUNC(sgi_mc_device::write));
- map(0x1fb90000, 0x1fb9ffff).rw(this, FUNC(ip22_state::hpc3_hd_enet_r), FUNC(ip22_state::hpc3_hd_enet_w));
+ map(0x1fb90000, 0x1fb9ffff).rw(m_hpc3, FUNC(hpc3_device::hd_enet_r), FUNC(hpc3_device::hd_enet_w));
map(0x1fbb0000, 0x1fbb0003).ram(); /* unknown, but read a lot and discarded */
- map(0x1fbc0000, 0x1fbc7fff).rw(this, FUNC(ip22_state::hpc3_hd0_r), FUNC(ip22_state::hpc3_hd0_w));
- map(0x1fbc8000, 0x1fbcffff).rw(this, FUNC(ip22_state::hpc3_unkpbus0_r), FUNC(ip22_state::hpc3_unkpbus0_w)).share("unkpbus0");
- map(0x1fb80000, 0x1fb8ffff).rw(this, FUNC(ip22_state::hpc3_pbusdma_r), FUNC(ip22_state::hpc3_pbusdma_w));
- map(0x1fbd8000, 0x1fbd83ff).rw(this, FUNC(ip22_state::hal2_r), FUNC(ip22_state::hal2_w));
+ map(0x1fbc0000, 0x1fbc7fff).rw(m_hpc3, FUNC(hpc3_device::hd0_r), FUNC(hpc3_device::hd0_w));
+ map(0x1fbc8000, 0x1fbcffff).rw(m_hpc3, FUNC(hpc3_device::unkpbus0_r), FUNC(hpc3_device::unkpbus0_w)).share("unkpbus0");
+ map(0x1fb80000, 0x1fb8ffff).rw(m_hpc3, FUNC(hpc3_device::pbusdma_r), FUNC(hpc3_device::pbusdma_w));
+ map(0x1fbd8000, 0x1fbd83ff).rw(m_hal2, FUNC(hal2_device::read), FUNC(hal2_device::write));
map(0x1fbd8400, 0x1fbd87ff).ram(); /* hack */
- map(0x1fbd9000, 0x1fbd93ff).rw(this, FUNC(ip22_state::hpc3_pbus4_r), FUNC(ip22_state::hpc3_pbus4_w));
+ map(0x1fbd9000, 0x1fbd93ff).rw(m_hpc3, FUNC(hpc3_device::pbus4_r), FUNC(hpc3_device::pbus4_w));
map(0x1fbd9800, 0x1fbd9bff).rw(m_ioc2, FUNC(ioc2_device::read), FUNC(ioc2_device::write));
map(0x1fbdc000, 0x1fbdc7ff).ram();
map(0x1fbdd000, 0x1fbdd3ff).ram();
@@ -1188,276 +173,14 @@ void ip22_state::ip225015_map(address_map &map)
map(0x20000000, 0x27ffffff).share("mainram").ram().w(this, FUNC(ip22_state::ip22_write_ram));
}
-
void ip22_state::machine_reset()
{
- m_hpc3.m_enetr_nbdp = 0x80000000;
- m_hpc3.m_enetr_cbp = 0x80000000;
-
// set up low RAM mirror
membank("bank1")->set_base(m_mainram);
- m_pbus_dma.m_active = 0;
-
m_maincpu->mips3drc_set_options(MIPS3DRC_COMPATIBLE_OPTIONS | MIPS3DRC_CHECK_OVERFLOWS);
}
-void ip22_state::dump_chain(address_space &space, uint32_t ch_base)
-{
- printf("node: %08x %08x %08x (len = %x)\n", space.read_dword(ch_base), space.read_dword(ch_base+4), space.read_dword(ch_base+8), space.read_dword(ch_base+4) & 0x3fff);
-
- if ((space.read_dword(ch_base+8) != 0) && !(space.read_dword(ch_base+4) & 0x80000000))
- {
- dump_chain(space, space.read_dword(ch_base+8));
- }
-}
-
-// HPC3 SCSI DMA control register bits
-#define HPC3_DMACTRL_IRQ (0x01)
-#define HPC3_DMACTRL_ENDIAN (0x02)
-#define HPC3_DMACTRL_DIR (0x04)
-#define HPC3_DMACTRL_ENABLE (0x10)
-
-
-WRITE_LINE_MEMBER(ip22_state::scsi_irq)
-{
- address_space &space = m_maincpu->space(AS_PROGRAM);
-
- if (state)
- {
- if (m_wd33c93->get_dma_count())
- {
- printf("m_wd33c93->get_dma_count() is %d\n", m_wd33c93->get_dma_count() );
- if (m_hpc3.m_scsi0_dma_ctrl & HPC3_DMACTRL_ENABLE)
- {
- if (m_hpc3.m_scsi0_dma_ctrl & HPC3_DMACTRL_IRQ) logerror("IP22: Unhandled SCSI DMA IRQ\n");
- }
-
- // HPC3 DMA: host to device
- if ((m_hpc3.m_scsi0_dma_ctrl & HPC3_DMACTRL_ENABLE) && (m_hpc3.m_scsi0_dma_ctrl & HPC3_DMACTRL_DIR))
- {
- uint32_t wptr, tmpword;
- int words, dptr, twords;
-
- words = m_wd33c93->get_dma_count();
- words /= 4;
-
- wptr = space.read_dword(m_hpc3.m_scsi0_desc);
- m_hpc3.m_scsi0_desc += words*4;
- dptr = 0;
-
- printf("DMA to device: %d words @ %x\n", words, wptr);
-
- dump_chain(space, m_hpc3.m_scsi0_desc);
-
- if (words <= (512/4))
- {
- // one-shot
- //m_wd33c93->dma_read_data(m_wd33c93->get_dma_count(), m_dma_buffer);
-
- while (words)
- {
- tmpword = space.read_dword(wptr);
-
- if (m_hpc3.m_scsi0_dma_ctrl & HPC3_DMACTRL_ENDIAN)
- {
- m_dma_buffer[dptr+3] = (tmpword>>24)&0xff;
- m_dma_buffer[dptr+2] = (tmpword>>16)&0xff;
- m_dma_buffer[dptr+1] = (tmpword>>8)&0xff;
- m_dma_buffer[dptr] = tmpword&0xff;
- }
- else
- {
- m_dma_buffer[dptr] = (tmpword>>24)&0xff;
- m_dma_buffer[dptr+1] = (tmpword>>16)&0xff;
- m_dma_buffer[dptr+2] = (tmpword>>8)&0xff;
- m_dma_buffer[dptr+3] = tmpword&0xff;
- }
-
- wptr += 4;
- dptr += 4;
- words--;
- }
-
- words = m_wd33c93->get_dma_count();
- m_wd33c93->dma_write_data(words, m_dma_buffer);
- }
- else
- {
- while (words)
- {
- //m_wd33c93->dma_read_data(512, m_dma_buffer);
- twords = 512/4;
- m_hpc3.m_scsi0_desc += 512;
- dptr = 0;
-
- while (twords)
- {
- tmpword = space.read_dword(wptr);
-
- if (m_hpc3.m_scsi0_dma_ctrl & HPC3_DMACTRL_ENDIAN)
- {
- m_dma_buffer[dptr+3] = (tmpword>>24)&0xff;
- m_dma_buffer[dptr+2] = (tmpword>>16)&0xff;
- m_dma_buffer[dptr+1] = (tmpword>>8)&0xff;
- m_dma_buffer[dptr] = tmpword&0xff;
- }
- else
- {
- m_dma_buffer[dptr] = (tmpword>>24)&0xff;
- m_dma_buffer[dptr+1] = (tmpword>>16)&0xff;
- m_dma_buffer[dptr+2] = (tmpword>>8)&0xff;
- m_dma_buffer[dptr+3] = tmpword&0xff;
- }
-
- wptr += 4;
- dptr += 4;
- twords--;
- }
-
- m_wd33c93->dma_write_data(512, m_dma_buffer);
-
- words -= (512/4);
- }
- }
-
- // clear DMA on the controller too
- m_wd33c93->clear_dma();
-#if 0
- uint32_t dptr, tmpword;
- uint32_t bc = space.read_dword(m_hpc3.m_scsi0_desc + 4);
- uint32_t rptr = space.read_dword(m_hpc3.m_scsi0_desc);
- int length = bc & 0x3fff;
- int xie = (bc & 0x20000000) ? 1 : 0;
- int eox = (bc & 0x80000000) ? 1 : 0;
-
- dump_chain(space, m_hpc3.m_scsi0_desc);
-
- printf("%s DMA to device: length %x xie %d eox %d\n", machine().describe_context().c_str(), length, xie, eox);
-
- if (length <= 0x4000)
- {
- dptr = 0;
- while (length > 0)
- {
- tmpword = space.read_dword(rptr);
- if (m_hpc3.m_scsi0_dma_ctrl & HPC3_DMACTRL_ENDIAN)
- {
- m_dma_buffer[dptr+3] = (tmpword>>24)&0xff;
- m_dma_buffer[dptr+2] = (tmpword>>16)&0xff;
- m_dma_buffer[dptr+1] = (tmpword>>8)&0xff;
- m_dma_buffer[dptr] = tmpword&0xff;
- }
- else
- {
- m_dma_buffer[dptr] = (tmpword>>24)&0xff;
- m_dma_buffer[dptr+1] = (tmpword>>16)&0xff;
- m_dma_buffer[dptr+2] = (tmpword>>8)&0xff;
- m_dma_buffer[dptr+3] = tmpword&0xff;
- }
-
- dptr += 4;
- rptr += 4;
- length -= 4;
- }
-
- length = space.read_dword(m_hpc3.m_scsi0_desc+4) & 0x3fff;
- m_wd33c93->write_data(length, m_dma_buffer);
-
- // clear DMA on the controller too
- m_wd33c93->clear_dma();
- }
- else
- {
- logerror("IP22: overly large host to device transfer, can't handle!\n");
- }
-#endif
- }
-
- // HPC3 DMA: device to host
- if ((m_hpc3.m_scsi0_dma_ctrl & HPC3_DMACTRL_ENABLE) && !(m_hpc3.m_scsi0_dma_ctrl & HPC3_DMACTRL_DIR))
- {
- uint32_t wptr, tmpword;
- int words, sptr, twords;
-
- words = m_wd33c93->get_dma_count();
- words /= 4;
-
- wptr = space.read_dword(m_hpc3.m_scsi0_desc);
- sptr = 0;
-
-// osd_printf_info("DMA from device: %d words @ %x\n", words, wptr);
-
- dump_chain(space, m_hpc3.m_scsi0_desc);
-
- if (words <= (1024/4))
- {
- // one-shot
- m_wd33c93->dma_read_data(m_wd33c93->get_dma_count(), m_dma_buffer);
-
- while (words)
- {
- if (m_hpc3.m_scsi0_dma_ctrl & HPC3_DMACTRL_ENDIAN)
- {
- tmpword = m_dma_buffer[sptr+3]<<24 | m_dma_buffer[sptr+2]<<16 | m_dma_buffer[sptr+1]<<8 | m_dma_buffer[sptr];
- }
- else
- {
- tmpword = m_dma_buffer[sptr]<<24 | m_dma_buffer[sptr+1]<<16 | m_dma_buffer[sptr+2]<<8 | m_dma_buffer[sptr+3];
- }
-
- space.write_dword(wptr, tmpword);
- wptr += 4;
- sptr += 4;
- words--;
- }
- }
- else
- {
- while (words)
- {
- m_wd33c93->dma_read_data(512, m_dma_buffer);
- twords = 512/4;
- sptr = 0;
-
- while (twords)
- {
- if (m_hpc3.m_scsi0_dma_ctrl & HPC3_DMACTRL_ENDIAN)
- {
- tmpword = m_dma_buffer[sptr+3]<<24 | m_dma_buffer[sptr+2]<<16 | m_dma_buffer[sptr+1]<<8 | m_dma_buffer[sptr];
- }
- else
- {
- tmpword = m_dma_buffer[sptr]<<24 | m_dma_buffer[sptr+1]<<16 | m_dma_buffer[sptr+2]<<8 | m_dma_buffer[sptr+3];
- }
- space.write_dword(wptr, tmpword);
-
- wptr += 4;
- sptr += 4;
- twords--;
- }
-
- words -= (512/4);
- }
- }
-
- // clear DMA on the controller too
- m_wd33c93->clear_dma();
- }
- }
-
- // clear HPC3 DMA active flag
- m_hpc3.m_scsi0_dma_ctrl &= ~HPC3_DMACTRL_ENABLE;
-
- // set the interrupt
- m_ioc2->raise_local0_irq(INT3_LOCAL0_SCSI0);
- }
- else
- {
- m_ioc2->lower_local0_irq(INT3_LOCAL0_SCSI0);
- }
-}
-
void ip22_state::machine_start()
{
}
@@ -1479,15 +202,15 @@ INPUT_PORTS_END
void ip22_state::cdrom_config(device_t *device)
{
device = device->subdevice("cdda");
- MCFG_SOUND_ROUTE(0, "^^^^lspeaker", 1.0)
- MCFG_SOUND_ROUTE(1, "^^^^rspeaker", 1.0)
+ MCFG_SOUND_ROUTE(0, ":lspeaker", 1.0)
+ MCFG_SOUND_ROUTE(1, ":rspeaker", 1.0)
}
MACHINE_CONFIG_START(ip22_state::ip225015)
- MCFG_CPU_ADD( "maincpu", R5000BE, 50000000*3 )
+ MCFG_CPU_ADD("maincpu", R5000BE, 50000000*3)
//MCFG_MIPS3_ICACHE_SIZE(32768)
//MCFG_MIPS3_DCACHE_SIZE(32768)
- MCFG_CPU_PROGRAM_MAP( ip225015_map)
+ MCFG_CPU_PROGRAM_MAP(ip225015_map)
/* video hardware */
MCFG_SCREEN_ADD("screen", RASTER)
@@ -1516,16 +239,24 @@ MACHINE_CONFIG_START(ip22_state::ip225015)
MCFG_DEVICE_ADD("wd33c93", WD33C93, 0)
MCFG_LEGACY_SCSI_PORT("scsi")
- MCFG_WD33C93_IRQ_CB(WRITELINE(ip22_state,scsi_irq))
+ MCFG_WD33C93_IRQ_CB(DEVWRITELINE(HPC3_TAG, hpc3_device, scsi_irq))
+
+ MCFG_SGI_HAL2_ADD(HAL2_TAG)
- MCFG_IOC2_GUINNESS_ADD(IOC2_TAG)
+ MCFG_IOC2_GUINNESS_ADD("ioc2")
+ MCFG_IOC2_CPU("maincpu")
+
+ MCFG_SGI_HPC3_ADD(HPC3_TAG)
+ MCFG_HPC3_CPU_TAG("maincpu")
+ MCFG_HPC3_SCSI_TAG("wd33c93")
+ MCFG_HPC3_IOC2_TAG("ioc2")
MCFG_DS1386_8K_ADD(RTC_TAG, 32768)
MACHINE_CONFIG_END
MACHINE_CONFIG_START(ip22_state::ip224613)
ip225015(config);
- MCFG_CPU_REPLACE( "maincpu", R4600BE, 133333333 )
+ MCFG_CPU_REPLACE("maincpu", R4600BE, 133333333)
//MCFG_MIPS3_ICACHE_SIZE(32768)
//MCFG_MIPS3_DCACHE_SIZE(32768)
MCFG_CPU_PROGRAM_MAP( ip225015_map)
@@ -1533,10 +264,10 @@ MACHINE_CONFIG_END
MACHINE_CONFIG_START(ip22_state::ip244415)
ip225015(config);
- MCFG_CPU_REPLACE( "maincpu", R4600BE, 150000000 )
+ MCFG_CPU_REPLACE("maincpu", R4600BE, 150000000)
//MCFG_MIPS3_ICACHE_SIZE(32768)
//MCFG_MIPS3_DCACHE_SIZE(32768)
- MCFG_CPU_PROGRAM_MAP( ip225015_map)
+ MCFG_CPU_PROGRAM_MAP(ip225015_map)
MACHINE_CONFIG_END
/* SCC init ip225015
diff --git a/src/mame/drivers/itech32.cpp b/src/mame/drivers/itech32.cpp
index cc46b4557b7..4b147d8344d 100644
--- a/src/mame/drivers/itech32.cpp
+++ b/src/mame/drivers/itech32.cpp
@@ -1937,7 +1937,7 @@ ROM_START( timekill121 ) /* Version 1.21 (3-tier board set: P/N 1050 Rev 1, P/N
ROM_LOAD16_BYTE( "tksrom02_u26.u26", 0x200000, 0x80000, CRC(051ced3e) SHA1(6b63c4837e709806ffea9a37d93933635d356a6e) ) /* Labeled TKSROM02 (U26) */
ROM_END
-ROM_START( timekill121a ) /* Version 1.32 (3-tier board set: P/N 1050 Rev 1, P/N 1049 Rev 1 & P/N 1052 Rev 2) */
+ROM_START( timekill121a ) /* Version 1.21 (3-tier board set: P/N 1050 Rev 1, P/N 1049 Rev 1 & P/N 1052 Rev 2) */
ROM_REGION16_BE( 0x80000, "user1", 0 )
ROM_LOAD16_BYTE( "tk00_v1.21_u54.u54", 0x00000, 0x40000, CRC(4938a940) SHA1(c42c5067ba0536ab22071c80a50434905acd93c2) ) /* Labeled TK00 V1.21 (U54) */
ROM_LOAD16_BYTE( "tk01_v1.21_u53.u53", 0x00001, 0x40000, CRC(0bb75c40) SHA1(99829ecb0692ea8b313bd8c2e982258c97599b06) ) /* Labeled TK01 V1.21 (U53) */
diff --git a/src/mame/drivers/neogeo.cpp b/src/mame/drivers/neogeo.cpp
index 8ccbc7145b2..f4210ca0a19 100644
--- a/src/mame/drivers/neogeo.cpp
+++ b/src/mame/drivers/neogeo.cpp
@@ -2197,38 +2197,47 @@ MACHINE_CONFIG_END
ROM_SYSTEM_BIOS( x+12, "unibios10", "Universe Bios (Hack, Ver. 1.0)" ) \
ROM_LOAD16_WORD_SWAP_BIOS( x+12, "uni-bios_1_0.rom", 0x00000, 0x020000, CRC(0ce453a0) SHA1(3b4c0cd26c176fc6b26c3a2f95143dd478f6abf9) ) /* Universe Bios v1.0 (hack) */
+/* the number shown in the top right corner (only displayed on the colour test in early versions) should be connected to the revision, the actual numbering / naming here is a mess, possibly due to upgrades where stickers weren't replaced
+ also is the colour of the outside of the test grid connected to the region? / cabinet type? (if so, why so many colours for US ones, but not other regions and are Asia + Europe really just the same thing?)
+
+ these details have been added to the comments */
+
#define NEOGEO_BIOS \
ROM_REGION16_BE( 0x80000, "mainbios", 0 ) \
ROM_SYSTEM_BIOS( 0, "euro", "Europe MVS (Ver. 2)" ) \
- ROM_LOAD16_WORD_SWAP_BIOS( 0, "sp-s2.sp1", 0x00000, 0x020000, CRC(9036d879) SHA1(4f5ed7105b7128794654ce82b51723e16e389543) ) /* Europe, 1 Slot, has also been found on 2 Slot and 4 Slot (the old hacks were designed for this one) */ \
+ ROM_LOAD16_WORD_SWAP_BIOS( 0, "sp-s2.sp1", 0x00000, 0x020000, CRC(9036d879) SHA1(4f5ed7105b7128794654ce82b51723e16e389543) ) /* 5 Dark Blue - Europe, 1 Slot, has also been found on 2 Slot and 4 Slot (the old hacks were designed for this one) */ \
ROM_SYSTEM_BIOS( 1, "euro-s1", "Europe MVS (Ver. 1)" ) \
- ROM_LOAD16_WORD_SWAP_BIOS( 1, "sp-s.sp1", 0x00000, 0x020000, CRC(c7f2fa45) SHA1(09576ff20b4d6b365e78e6a5698ea450262697cd) ) /* Europe, 4 Slot */ \
+ ROM_LOAD16_WORD_SWAP_BIOS( 1, "sp-s.sp1", 0x00000, 0x020000, CRC(c7f2fa45) SHA1(09576ff20b4d6b365e78e6a5698ea450262697cd) ) /* 3 Dark Blue - Europe, 4 Slot */ \
\
ROM_SYSTEM_BIOS( 2, "us", "US MVS (Ver. 2?)" ) \
- ROM_LOAD16_WORD_SWAP_BIOS( 2, "sp-u2.sp1", 0x00000, 0x020000, CRC(e72943de) SHA1(5c6bba07d2ec8ac95776aa3511109f5e1e2e92eb) ) /* US, 2 Slot */ \
+ ROM_LOAD16_WORD_SWAP_BIOS( 2, "sp-u2.sp1", 0x00000, 0x020000, CRC(e72943de) SHA1(5c6bba07d2ec8ac95776aa3511109f5e1e2e92eb) ) /* 5 Cyan - US, 2 Slot */ \
ROM_SYSTEM_BIOS( 3, "us-e", "US MVS (Ver. 1)" ) \
- ROM_LOAD16_WORD_SWAP_BIOS( 3, "sp-e.sp1", 0x00000, 0x020000, CRC(2723a5b5) SHA1(5dbff7531cf04886cde3ef022fb5ca687573dcb8) ) /* US, 6 Slot (V5?) */ \
+ ROM_LOAD16_WORD_SWAP_BIOS( 3, "sp-e.sp1", 0x00000, 0x020000, CRC(2723a5b5) SHA1(5dbff7531cf04886cde3ef022fb5ca687573dcb8) ) /* 5 Yellow - US, 6 Slot (V5?) */ \
ROM_SYSTEM_BIOS( 4, "us-v2", "US MVS (4 slot, Ver 2)" ) \
- ROM_LOAD16_WORD_SWAP_BIOS( 4, "v2.bin", 0x00000, 0x020000, CRC(62f021f4) SHA1(62d372269e1b3161c64ae21123655a0a22ffd1bb) ) /* US, 4 slot */ \
+ ROM_LOAD16_WORD_SWAP_BIOS( 4, "v2.bin", 0x00000, 0x020000, CRC(62f021f4) SHA1(62d372269e1b3161c64ae21123655a0a22ffd1bb) ) /* 3 Cyan - US, 4 slot */ \
+ ROM_SYSTEM_BIOS( 5, "us-u3", "US MVS (U3)" ) \
+ ROM_LOAD16_WORD_SWAP_BIOS( 5, "sp1-u3.bin", 0x00000, 0x020000, CRC(2025b7a2) SHA1(73d774746196f377111cd7aa051cc8bb5dd948b3) ) /* 2 Green - 6 Slot */ \
\
- ROM_SYSTEM_BIOS( 5, "asia", "Asia MVS (Ver. 3)" ) \
- ROM_LOAD16_WORD_SWAP_BIOS( 5, "asia-s3.rom", 0x00000, 0x020000, CRC(91b64be3) SHA1(720a3e20d26818632aedf2c2fd16c54f213543e1) ) /* Asia */ \
+ ROM_SYSTEM_BIOS( 6, "asia", "Asia MVS (Ver. 3)" ) \
+ ROM_LOAD16_WORD_SWAP_BIOS( 6, "asia-s3.rom", 0x00000, 0x020000, CRC(91b64be3) SHA1(720a3e20d26818632aedf2c2fd16c54f213543e1) ) /* 6 Dark Blue - Asia */ \
\
- ROM_SYSTEM_BIOS( 6, "japan", "Japan MVS (Ver. 3)" ) \
- ROM_LOAD16_WORD_SWAP_BIOS( 6, "vs-bios.rom", 0x00000, 0x020000, CRC(f0e8f27d) SHA1(ecf01eda815909f1facec62abf3594eaa8d11075) ) /* Japan, Ver 6 VS Bios */ \
- ROM_SYSTEM_BIOS( 7, "japan-s2", "Japan MVS (Ver. 2)" ) \
- ROM_LOAD16_WORD_SWAP_BIOS( 7, "sp-j2.sp1", 0x00000, 0x020000, CRC(acede59c) SHA1(b6f97acd282fd7e94d9426078a90f059b5e9dd91) ) /* Japan, Older */ \
- ROM_SYSTEM_BIOS( 8, "japan-s1", "Japan MVS (Ver. 1)" ) \
- ROM_LOAD16_WORD_SWAP_BIOS( 8, "sp1.jipan.1024", 0x00000, 0x020000, CRC(9fb0abe4) SHA1(18a987ce2229df79a8cf6a84f968f0e42ce4e59d) ) /* Japan, Older */ \
- ROM_SYSTEM_BIOS( 9, "mv1c", "NEO-MVH MV1C" ) \
- ROM_LOAD16_WORD_SWAP_BIOS( 9, "sp-45.sp1", 0x00000, 0x080000, CRC(03cc9f6a) SHA1(cdf1f49e3ff2bac528c21ed28449cf35b7957dc1) ) /* Latest Asia bios */ \
- ROM_SYSTEM_BIOS( 10, "japan-j3", "Japan MVS (J3)" ) \
- ROM_LOAD16_WORD_SWAP_BIOS( 10, "japan-j3.bin", 0x00000, 0x020000, CRC(dff6d41f) SHA1(e92910e20092577a4523a6b39d578a71d4de7085) ) /* Latest Japan bios; correct chip label unknown */ \
- ROM_SYSTEM_BIOS( 11, "japan-hotel", "Custom Japanese Hotel" ) \
- ROM_LOAD16_WORD_SWAP_BIOS( 11, "sp-1v1_3db8c.bin", 0x00000, 0x020000, CRC(162f0ebe) SHA1(fe1c6dd3dfcf97d960065b1bb46c1e11cb7bf271) ) /* 'rare MVS found in japanese hotels' shows v1.3 in test mode */ \
+ ROM_SYSTEM_BIOS( 7, "japan", "Japan MVS (Ver. 3)" ) \
+ ROM_LOAD16_WORD_SWAP_BIOS( 7, "vs-bios.rom", 0x00000, 0x020000, CRC(f0e8f27d) SHA1(ecf01eda815909f1facec62abf3594eaa8d11075) ) /* 6 Red - Japan, Ver 6 VS Bios */ \
+ ROM_SYSTEM_BIOS( 8, "japan-s2", "Japan MVS (Ver. 2)" ) \
+ ROM_LOAD16_WORD_SWAP_BIOS( 8, "sp-j2.sp1", 0x00000, 0x020000, CRC(acede59c) SHA1(b6f97acd282fd7e94d9426078a90f059b5e9dd91) ) /* 5 Red - Japan, Older */ \
+ ROM_SYSTEM_BIOS( 9, "japan-s1", "Japan MVS (Ver. 1)" ) \
+ ROM_LOAD16_WORD_SWAP_BIOS( 9, "sp1.jipan.1024", 0x00000, 0x020000, CRC(9fb0abe4) SHA1(18a987ce2229df79a8cf6a84f968f0e42ce4e59d) ) /* 3 Red - Japan, Older */ \
+ ROM_SYSTEM_BIOS( 10, "mv1c", "NEO-MVH MV1C" ) \
+ ROM_LOAD16_WORD_SWAP_BIOS( 10, "sp-45.sp1", 0x00000, 0x080000, CRC(03cc9f6a) SHA1(cdf1f49e3ff2bac528c21ed28449cf35b7957dc1) ) /* 6 Dark Blue - Latest Asia bios (overdump?) */ \
+ ROM_SYSTEM_BIOS( 11, "japan-j3", "Japan MVS (J3)" ) \
+ ROM_LOAD16_WORD_SWAP_BIOS( 11, "japan-j3.bin", 0x00000, 0x020000, CRC(dff6d41f) SHA1(e92910e20092577a4523a6b39d578a71d4de7085) ) /* 6 Red - Latest Japan bios; correct chip label unknown */ \
+ ROM_SYSTEM_BIOS( 12, "japan-hotel", "Custom Japanese Hotel" ) \
+ ROM_LOAD16_WORD_SWAP_BIOS( 12, "sp-1v1_3db8c.bin", 0x00000, 0x020000, CRC(162f0ebe) SHA1(fe1c6dd3dfcf97d960065b1bb46c1e11cb7bf271) ) /* 6 Red - 'rare MVS found in japanese hotels' shows v1.3 in test mode */ \
+ ROM_SYSTEM_BIOS( 13, "japan-j3a", "Japan MVS (J3, alt)" ) \
+ ROM_LOAD16_WORD_SWAP_BIOS( 13, "sp1-j3.bin", 0x00000, 0x020000, CRC(fbc6d469) SHA1(46b2b409b5b68869e367b40c846373623edb632a) ) /* 2 Red - 6 Slot */ \
\
- NEOGEO_UNIBIOS(12) \
- NEOGEO_UNIBIOS_1_2_AND_OLDER(12)
+ NEOGEO_UNIBIOS(14) \
+ NEOGEO_UNIBIOS_1_2_AND_OLDER(14)
#define NEO_BIOS_AUDIO_64K(name, hash) \
@@ -5023,6 +5032,28 @@ ROM_START( wh2 ) /* MVS AND AES VERSION */
ROM_LOAD16_BYTE( "057-c6.c6", 0x800001, 0x200000, CRC(b13d1de3) SHA1(7d749c23a33d90fe50279e884540d71cf1aaaa6b) ) /* Plane 2,3 */ /* TC5316200 */
ROM_END
+ROM_START( wh2h ) /* AES VERSION */
+ ROM_REGION( 0x200000, "cslot1:maincpu", ROMREGION_BE|ROMREGION_16BIT )
+ ROM_LOAD16_WORD_SWAP( "057-pg1.p1", 0x100000, 0x100000, CRC(cde9aff5) SHA1(003f79cbff1383b59588ccee4b372027e506235c) ) /* TC5316200 */
+ ROM_CONTINUE( 0x000000, 0x100000 )
+
+ NEO_SFIX_128K( "057-s1.s1", CRC(fcaeb3a4) SHA1(1f3f85e38b8552333261c04ae5af0d6e3b310622) ) /* TC531000 */
+
+ NEO_BIOS_AUDIO_128K( "057-m1.m1", CRC(8fa3bc77) SHA1(982f92978671e4ee66630948e6bb7565b37b5dc0) ) /* TC531001 */
+
+ ROM_REGION( 0x400000, "cslot1:ymsnd", 0 )
+ ROM_LOAD( "057-v1.v1", 0x000000, 0x200000, CRC(8877e301) SHA1(1bab988d74ea8fd12db201c257ec844622cf5f4e) ) /* TC5316200 */
+ ROM_LOAD( "057-v2.v2", 0x200000, 0x200000, CRC(c1317ff4) SHA1(4c28b2b5998abaeaa5143f2f3a9ba52c6041f4f3) ) /* TC5316200 */
+
+ ROM_REGION( 0xc00000, "cslot1:sprites", 0 )
+ ROM_LOAD16_BYTE( "057-c1.c1", 0x000000, 0x200000, CRC(21c6bb91) SHA1(a2c17d0c91dd59528d8fa7fe110af8b20b25ff99) ) /* Plane 0,1 */ /* TC5316200 */
+ ROM_LOAD16_BYTE( "057-c2.c2", 0x000001, 0x200000, CRC(a3999925) SHA1(0ee861a77850d378d03c1bf00b9692abd860c759) ) /* Plane 2,3 */ /* TC5316200 */
+ ROM_LOAD16_BYTE( "057-c3.c3", 0x400000, 0x200000, CRC(b725a219) SHA1(4857687d156a9150a69b97d2729245a51c144a0c) ) /* Plane 0,1 */ /* TC5316200 */
+ ROM_LOAD16_BYTE( "057-c4.c4", 0x400001, 0x200000, CRC(8d96425e) SHA1(0f79c868a6a33ad25e38d842f30ec4440d809033) ) /* Plane 2,3 */ /* TC5316200 */
+ ROM_LOAD16_BYTE( "057-c5.c5", 0x800000, 0x200000, CRC(b20354af) SHA1(da7609fd467f2f4d71d92970f438a04d11ab1cc1) ) /* Plane 0,1 */ /* TC5316200 */
+ ROM_LOAD16_BYTE( "057-c6.c6", 0x800001, 0x200000, CRC(b13d1de3) SHA1(7d749c23a33d90fe50279e884540d71cf1aaaa6b) ) /* Plane 2,3 */ /* TC5316200 */
+ROM_END
+
/****************************************
ID-0058
. NGM-058
@@ -8936,7 +8967,35 @@ ROM_START( sengoku3 ) /* Original Version - Encrypted GFX */
ROM_REGION( 0x200000, "cslot1:maincpu", ROMREGION_BE|ROMREGION_16BIT )
ROM_LOAD16_WORD_SWAP( "261-ph1.p1", 0x100000, 0x100000, CRC(e0d4bc0a) SHA1(8df366097f224771ca6d1aa5c1691cd46776cd12) ) /* mask rom TC5316200 */
ROM_CONTINUE( 0x000000, 0x100000 )
- /* also found MVS set with p1 label 261-PG1; older revision? */
+
+ ROM_Y_ZOOM
+
+ /* The Encrypted Boards do not have an s1 rom, data for it comes from the Cx ROMs */
+ ROM_REGION( 0x20000, "cslot1:fixed", 0 )
+ ROM_FILL( 0x000000, 0x20000, 0x000000 )
+ ROM_REGION( 0x20000, "fixedbios", 0 )
+ ROM_LOAD( "sfix.sfix", 0x000000, 0x20000, CRC(c2ea0cfd) SHA1(fd4a618cdcdbf849374f0a50dd8efe9dbab706c3) )
+
+ NEO_BIOS_AUDIO_512K( "261-m1.m1", CRC(7d501c39) SHA1(8e6bcc428f5ac7532d9c9be7e07ad0821461a080) ) /* mask rom TC534000 */
+
+ ROM_REGION( 0x0e00000, "cslot1:ymsnd", 0 )
+ ROM_LOAD( "261-v1.v1", 0x000000, 0x400000, CRC(64c30081) SHA1(f9ebd20cf59b72e864b7274c1bdb6d99ecaf4595) ) /* mask rom TC5332204 */
+ ROM_LOAD( "261-v2.v2", 0x400000, 0x400000, CRC(392a9c47) SHA1(7ab90a54089236ca6c3ef1af8e566a8025d38159) ) /* mask rom TC5332204 */
+ ROM_LOAD( "261-v3.v3", 0x800000, 0x400000, CRC(c1a7ebe3) SHA1(1d7bb481451f5ee0457e954bb5210300182c3c9c) ) /* mask rom TC5332204 */
+ ROM_LOAD( "261-v4.v4", 0xc00000, 0x200000, CRC(9000d085) SHA1(11157b355ab4eb6627e9f322ed875332d3d77349) ) /* mask rom TC5316200 */
+
+ ROM_REGION( 0x2000000, "cslot1:sprites", 0 )
+ ROM_LOAD16_BYTE( "261-c1.c1", 0x0000000, 0x800000, CRC(ded84d9c) SHA1(d960523b813d4fae06d716298d4e431a5c77a0c5) ) /* Plane 0,1 */ /* mask rom TC5364205 */
+ ROM_LOAD16_BYTE( "261-c2.c2", 0x0000001, 0x800000, CRC(b8eb4348) SHA1(619d24312549932959481fa58f43f11c048e1ca5) ) /* Plane 2,3 */ /* mask rom TC5364205 */
+ ROM_LOAD16_BYTE( "261-c3.c3", 0x1000000, 0x800000, CRC(84e2034a) SHA1(38ec4ae4b86933a25c9a03799b8cade4b1346401) ) /* Plane 0,1 */ /* mask rom TC5364205 */
+ ROM_LOAD16_BYTE( "261-c4.c4", 0x1000001, 0x800000, CRC(0b45ae53) SHA1(a19fb21408ab633aee8bbf38bf43b5e26766b355) ) /* Plane 2,3 */ /* mask rom TC5364205 */
+ROM_END
+
+// only 2 bytes differ from above set, but both have been verified on multiple carts for each label.
+ROM_START( sengoku3a ) /* Original Version - Encrypted GFX */
+ ROM_REGION( 0x200000, "cslot1:maincpu", ROMREGION_BE|ROMREGION_16BIT )
+ ROM_LOAD16_WORD_SWAP( "261-pg1.p1", 0x100000, 0x100000, CRC(5b557201) SHA1(d01421d1dc80fe7d2a46b9f79c0f344b3c81c1e7) ) /* mask rom TC5316200 */
+ ROM_CONTINUE( 0x000000, 0x100000 )
ROM_Y_ZOOM
@@ -9821,13 +9880,14 @@ ROM_END
B-V-01
. ???-????
MVS PROGV (2000.11.17) / MVS CHAV (2000.10.26)
+
+ Officially licensed? Cart has a holographic 'SNK' sticker applied
+
****************************************/
ROM_START( vliner ) /* MVS ONLY RELEASE */
- /* Officially licensed? Cart has a holographic 'SNK' sticker applied */
ROM_REGION( 0x100000, "cslot1:maincpu", ROMREGION_BE|ROMREGION_16BIT )
- ROM_LOAD16_WORD_SWAP( "epr.p1", 0x000000, 0x080000, CRC(72a2c043) SHA1(b34bcc10ff33e4465126a6865fe8bf6b6a3d6cee) ) /* AM27C400 */
- /* P on eprom, correct chip label unknown */
+ ROM_LOAD16_WORD_SWAP( "epr_7a.p1", 0x000000, 0x080000, CRC(052f93ed) SHA1(3a5330073d21fd068d44956680cfae7faa4f3951) ) /* AM27C400 */
NEO_SFIX_128K( "s-1.s1", CRC(972d8c31) SHA1(41f09ef28a3791668ea304c74b8b06c117a50e9a) )
@@ -9840,11 +9900,24 @@ ROM_START( vliner ) /* MVS ONLY RELEASE */
ROM_LOAD16_BYTE( "c-2.c2", 0x000001, 0x80000, CRC(efe9b33e) SHA1(910c651aadce9bf59e51c338ceef62287756d2e8) ) /* Plane 2,3 */
ROM_END
-ROM_START( vlinero ) /* MVS ONLY RELEASE */
- /* Officially licensed? Cart has a holographic 'SNK' sticker applied */
+ROM_START( vliner6e ) /* MVS ONLY RELEASE */
+ ROM_REGION( 0x100000, "cslot1:maincpu", ROMREGION_BE|ROMREGION_16BIT )
+ ROM_LOAD16_WORD_SWAP( "epr_6e.p1", 0x000000, 0x080000, CRC(72a2c043) SHA1(b34bcc10ff33e4465126a6865fe8bf6b6a3d6cee) ) /* AM27C400 */
+
+ NEO_SFIX_128K( "s-1.s1", CRC(972d8c31) SHA1(41f09ef28a3791668ea304c74b8b06c117a50e9a) )
+
+ NEO_BIOS_AUDIO_64K( "m-1.m1", CRC(9b92b7d1) SHA1(2c9b777feb9a8e43fa1bd942aba5afe3b5427d94) )
+
+ ROM_REGION( 0x200000, "cslot1:ymsnd", ROMREGION_ERASE00 )
+
+ ROM_REGION( 0x400000, "cslot1:sprites", 0 )
+ ROM_LOAD16_BYTE( "c-1.c1", 0x000000, 0x80000, CRC(5118f7c0) SHA1(b6fb6e9cbb660580d98e00780ebf248c0995145a) ) /* Plane 0,1 */
+ ROM_LOAD16_BYTE( "c-2.c2", 0x000001, 0x80000, CRC(efe9b33e) SHA1(910c651aadce9bf59e51c338ceef62287756d2e8) ) /* Plane 2,3 */
+ROM_END
+
+ROM_START( vliner54 ) /* MVS ONLY RELEASE */
ROM_REGION( 0x100000, "cslot1:maincpu", ROMREGION_BE|ROMREGION_16BIT )
ROM_LOAD16_WORD_SWAP( "epr_54.p1", 0x000000, 0x080000, CRC(172efc18) SHA1(8ca739f8780a9e6fa19ac2c3e931d75871603f58) )
- /* P on eprom, correct chip label unknown */
NEO_SFIX_128K( "s-1.s1", CRC(972d8c31) SHA1(41f09ef28a3791668ea304c74b8b06c117a50e9a) )
@@ -11454,7 +11527,8 @@ GAME( 2000, mslug3b6, mslug3, mslug3b6, neogeo, mvs_led_state, 0, RO
GAME( 2000, kof2000, neogeo, kof2000, neogeo, mvs_led_state, 0, ROT0, "SNK", "The King of Fighters 2000 (NGM-2570 ~ NGH-2570)" , MACHINE_SUPPORTS_SAVE ) /* Encrypted Code & GFX */
GAME( 2000, kof2000n, kof2000, kof2000n, neogeo, mvs_led_state, 0, ROT0, "SNK", "The King of Fighters 2000 (not encrypted)" , MACHINE_SUPPORTS_SAVE ) /* Encrypted GFX */
GAME( 2001, zupapa, neogeo, zupapa, neogeo, mvs_led_state, 0, ROT0, "SNK", "Zupapa!" , MACHINE_SUPPORTS_SAVE ) /* Encrypted GFX */
-GAME( 2001, sengoku3, neogeo, sengoku3, neogeo, mvs_led_state, 0, ROT0, "Noise Factory / SNK", "Sengoku 3 / Sengoku Densho 2001" , MACHINE_SUPPORTS_SAVE ) /* Encrypted GFX */
+GAME( 2001, sengoku3, neogeo, sengoku3, neogeo, mvs_led_state, 0, ROT0, "Noise Factory / SNK", "Sengoku 3 / Sengoku Densho 2001 (set 1)" , MACHINE_SUPPORTS_SAVE ) /* Encrypted GFX */
+GAME( 2001, sengoku3a, sengoku3, sengoku3, neogeo, mvs_led_state, 0, ROT0, "Noise Factory / SNK", "Sengoku 3 / Sengoku Densho 2001 (set 2)" , MACHINE_SUPPORTS_SAVE ) /* Encrypted GFX */
GAME( 2001, kof2001, neogeo, kof2001, neogeo, mvs_led_state, 0, ROT0, "Eolith / SNK", "The King of Fighters 2001 (NGM-262?)" , MACHINE_SUPPORTS_SAVE ) /* Encrypted GFX */
GAME( 2001, kof2001h, kof2001, kof2001, neogeo, mvs_led_state, 0, ROT0, "Eolith / SNK", "The King of Fighters 2001 (NGH-2621)" , MACHINE_SUPPORTS_SAVE ) /* Encrypted GFX */
GAME( 2003, cthd2003, kof2001, cthd2k3, neogeo, mvs_led_state, 0, ROT0, "bootleg", "Crouching Tiger Hidden Dragon 2003 (The King of Fighters 2001 bootleg)", MACHINE_SUPPORTS_SAVE ) /* Protected Hack / Bootleg of kof2001 */
@@ -11506,6 +11580,7 @@ GAME( 1992, wh1, neogeo, neobase, neogeo, mvs_led_state, 0, RO
GAME( 1992, wh1h, wh1, neobase, neogeo, mvs_led_state, 0, ROT0, "Alpha Denshi Co.", "World Heroes (ALH-005)", MACHINE_SUPPORTS_SAVE )
GAME( 1992, wh1ha, wh1, neobase, neogeo, mvs_led_state, 0, ROT0, "Alpha Denshi Co.", "World Heroes (set 3)", MACHINE_SUPPORTS_SAVE )
GAME( 1993, wh2, neogeo, neobase, neogeo, mvs_led_state, 0, ROT0, "ADK", "World Heroes 2 (ALM-006 ~ ALH-006)", MACHINE_SUPPORTS_SAVE )
+GAME( 1993, wh2h, wh2, neobase, neogeo, mvs_led_state, 0, ROT0, "ADK", "World Heroes 2 (ALH-006)", MACHINE_SUPPORTS_SAVE )
GAME( 1994, wh2j, neogeo, neobase, neogeo, mvs_led_state, 0, ROT0, "ADK / SNK", "World Heroes 2 Jet (ADM-007 ~ ADH-007)", MACHINE_SUPPORTS_SAVE )
GAME( 1994, aodk, neogeo, neobase, neogeo, mvs_led_state, 0, ROT0, "ADK / SNK", "Aggressors of Dark Kombat / Tsuukai GANGAN Koushinkyoku (ADM-008 ~ ADH-008)", MACHINE_SUPPORTS_SAVE )
GAME( 1995, whp, neogeo, neobase, neogeo, mvs_led_state, 0, ROT0, "ADK / SNK", "World Heroes Perfect", MACHINE_SUPPORTS_SAVE )
@@ -11641,8 +11716,10 @@ GAME( 2002, matrimbl, matrim, matrimbl, neogeo, mvs_led_state, 0, RO
// BrezzaSoft
GAME( 2001, jockeygp, neogeo, jockeygp, jockeygp, mvs_led_state, 0, ROT0, "Sun Amusement / BrezzaSoft", "Jockey Grand Prix (set 1)", MACHINE_SUPPORTS_SAVE )
GAME( 2001, jockeygpa, jockeygp, jockeygp, jockeygp, mvs_led_state, 0, ROT0, "Sun Amusement / BrezzaSoft", "Jockey Grand Prix (set 2)", MACHINE_SUPPORTS_SAVE )
-GAME( 2001, vliner, neogeo, vliner, vliner, mvs_led_state, 0, ROT0, "Dyna / BrezzaSoft", "V-Liner (set 1)", MACHINE_SUPPORTS_SAVE )
-GAME( 2001, vlinero, vliner, vliner, vliner, mvs_led_state, 0, ROT0, "Dyna / BrezzaSoft", "V-Liner (set 2)", MACHINE_SUPPORTS_SAVE )
+// ver 0.7e and ver 0.53 are known to exist
+GAME( 2001, vliner, neogeo, vliner, vliner, mvs_led_state, 0, ROT0, "Dyna / BrezzaSoft", "V-Liner (v0.7a)", MACHINE_SUPPORTS_SAVE )
+GAME( 2001, vliner6e, vliner, vliner, vliner, mvs_led_state, 0, ROT0, "Dyna / BrezzaSoft", "V-Liner (v0.6e)", MACHINE_SUPPORTS_SAVE )
+GAME( 2001, vliner54, vliner, vliner, vliner, mvs_led_state, 0, ROT0, "Dyna / BrezzaSoft", "V-Liner (v0.54)", MACHINE_SUPPORTS_SAVE )
// Kyle Hodgetts
GAME( 2000, diggerma, neogeo, neobase, neogeo, mvs_led_state, 0, ROT0, "Kyle Hodgetts", "Digger Man (prototype)", MACHINE_SUPPORTS_SAVE )
@@ -11661,7 +11738,7 @@ GAME( 2005, lasthope, neogeo, neobase, neogeo, mvs_led_state, 0, RO
// Kraut Buster (c)2016 - MVS/AES
// N.C.I - LE CORTEX
-// Treasure of the Caribbean (c)2011 - AES only (no credits system if run on an MVS, Freeplay)
+// Treasure of the Caribbean (c)2011 - AES only, see hash/neogeo.xml for entry (no credits system if run on an MVS, Freeplay)
// NEOBITZ
// Knight's Chance (c)2014 - MVS/AES
diff --git a/src/mame/drivers/pc9801.cpp b/src/mame/drivers/pc9801.cpp
index 06e7533d940..c285ffdddef 100644
--- a/src/mame/drivers/pc9801.cpp
+++ b/src/mame/drivers/pc9801.cpp
@@ -1438,6 +1438,7 @@ void pc9801_state::pc9821_map(address_map &map)
map(0x000e8000, 0x000fffff).m(m_ipl, FUNC(address_map_bank_device::amap16));
map(0x00f00000, 0x00f9ffff).ram().share("ext_gvram");
map(0xffee8000, 0xffefffff).m(m_ipl, FUNC(address_map_bank_device::amap16));
+ map(0xfff00000, 0xfff9ffff).ram().share("ext_gvram");
map(0xfffe8000, 0xffffffff).m(m_ipl, FUNC(address_map_bank_device::amap16));
}
diff --git a/src/mame/drivers/stv.cpp b/src/mame/drivers/stv.cpp
index 6239799e561..8cfba1511d2 100644
--- a/src/mame/drivers/stv.cpp
+++ b/src/mame/drivers/stv.cpp
@@ -3633,7 +3633,7 @@ GAME( 1995, fhboxers, stvbios, stv, stv, stv_state, fhboxers, ROT
GAME( 1997, findlove, stvbios, stv, stv, stv_state, stv, ROT0, "Daiki / FCF", "Zenkoku Seifuku Bishoujo Grand Prix Find Love (J 971212 V1.000)", MACHINE_IMPERFECT_SOUND | MACHINE_IMPERFECT_GRAPHICS )
GAME( 1994, gaxeduel, stvbios, stv, stv6b, stv_state, gaxeduel, ROT0, "Sega", "Golden Axe - The Duel (JUETL 950117 V1.000)", MACHINE_IMPERFECT_SOUND | MACHINE_IMPERFECT_GRAPHICS)
GAME( 1998, grdforce, stvbios, stv, stv, stv_state, grdforce, ROT0, "Success", "Guardian Force (JUET 980318 V0.105)", MACHINE_IMPERFECT_SOUND | MACHINE_IMPERFECT_GRAPHICS )
-GAME( 1998, groovef, stvbios, stv, stv6b, stv_state, groovef, ROT0, "Atlus", "Groove on Fight - Gouketsuji Ichizoku 3 (J 970416 V1.001)", MACHINE_IMPERFECT_SOUND | MACHINE_IMPERFECT_GRAPHICS )
+GAME( 1997, groovef, stvbios, stv, stv6b, stv_state, groovef, ROT0, "Atlus", "Groove on Fight - Gouketsuji Ichizoku 3 (J 970416 V1.001)", MACHINE_IMPERFECT_SOUND | MACHINE_IMPERFECT_GRAPHICS )
GAME( 1997, hanagumi, stvbios, stv, stv, stv_state, hanagumi, ROT0, "Sega", "Sakura Taisen - Hanagumi Taisen Columns (J 971007 V1.010)", MACHINE_IMPERFECT_GRAPHICS | MACHINE_IMPERFECT_SOUND )
GAME( 1996, introdon, stvbios, stv, stv, stv_state, stv, ROT0, "Sunsoft / Success", "Karaoke Quiz Intro Don Don! (J 960213 V1.000)", MACHINE_IMPERFECT_SOUND | MACHINE_IMPERFECT_GRAPHICS )
GAME( 1995, kiwames, stvbios, stv, stvmp, stv_state, stvmp, ROT0, "Athena", "Pro Mahjong Kiwame S (J 951020 V1.208)", MACHINE_IMPERFECT_SOUND | MACHINE_IMPERFECT_GRAPHICS )
diff --git a/src/mame/machine/hal2.cpp b/src/mame/machine/hal2.cpp
new file mode 100644
index 00000000000..c62f88a3980
--- /dev/null
+++ b/src/mame/machine/hal2.cpp
@@ -0,0 +1,175 @@
+// license:BSD-3-Clause
+// copyright-holders:Ryan Holtz
+/**********************************************************************
+
+ SGI HAL2 Audio Controller emulation
+
+**********************************************************************/
+
+#include "emu.h"
+#include "machine/hal2.h"
+
+DEFINE_DEVICE_TYPE(SGI_HAL2, hal2_device, "hal2", "SGI HAL2")
+
+hal2_device::hal2_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : device_t(mconfig, SGI_HAL2, tag, owner, clock)
+ , m_iar(0)
+ , m_idr{ 0, 0, 0, 0 }
+{
+}
+
+#define VERBOSE_LEVEL ( 0 )
+
+inline void ATTR_PRINTF(3,4) hal2_device::verboselog(int n_level, const char *s_fmt, ... )
+{
+ if( VERBOSE_LEVEL >= n_level )
+ {
+ va_list v;
+ char buf[ 32768 ];
+ va_start( v, s_fmt );
+ vsprintf( buf, s_fmt, v );
+ va_end( v );
+ logerror("%s: %s", machine().describe_context(), buf);
+ }
+}
+
+void hal2_device::device_start()
+{
+}
+
+void hal2_device::device_reset()
+{
+ m_iar = 0;
+ memset(m_idr, 0, sizeof(uint32_t) * 4);
+}
+
+READ32_MEMBER(hal2_device::read)
+{
+ switch( offset )
+ {
+ case STATUS_REG:
+ //verboselog((machine, 0, "HAL2 Status read: 0x0004\n" );
+ return 0x0004;
+ case REVISION_REG:
+ //verboselog((machine, 0, "HAL2 Revision read: 0x4011\n" );
+ return 0x4011;
+ }
+ //verboselog((machine, 0, "Unknown HAL2 read: 0x%08x (%08x)\n", 0x1fbd8000 + offset*4, mem_mask );
+ return 0;
+}
+
+WRITE32_MEMBER(hal2_device::write)
+{
+ switch (offset)
+ {
+ case STATUS_REG:
+ //verboselog((machine, 0, "HAL2 Status Write: 0x%08x (%08x)\n", data, mem_mask );
+ if (data & ISR_GLOBAL_RESET)
+ {
+ //verboselog((machine, 0, " HAL2 Global Reset\n" );
+ }
+ if (data & ISR_CODEC_RESET)
+ {
+ //verboselog((machine, 0, " HAL2 Codec Reset\n" );
+ }
+ break;
+ case INDIRECT_ADDRESS_REG:
+ //verboselog((machine, 0, "HAL2 Indirect Address Register Write: 0x%08x (%08x)\n", data, mem_mask );
+ m_iar = data;
+ switch (data & IAR_TYPE)
+ {
+ case 0x1000:
+ //verboselog((machine, 0, " DMA Port\n" );
+ switch (data & IAR_NUM)
+ {
+ case 0x0100:
+ //verboselog((machine, 0, " Synth In\n" );
+ break;
+ case 0x0200:
+ //verboselog((machine, 0, " AES In\n" );
+ break;
+ case 0x0300:
+ //verboselog((machine, 0, " AES Out\n" );
+ break;
+ case 0x0400:
+ //verboselog((machine, 0, " DAC Out\n" );
+ break;
+ case 0x0500:
+ //verboselog((machine, 0, " ADC Out\n" );
+ break;
+ case 0x0600:
+ //verboselog((machine, 0, " Synth Control\n" );
+ break;
+ }
+ break;
+ case 0x2000:
+ //verboselog((machine, 0, " Bresenham\n" );
+ switch (data & IAR_NUM)
+ {
+ case 0x0100:
+ //verboselog((machine, 0, " Bresenham Clock Gen 1\n" );
+ break;
+ case 0x0200:
+ //verboselog((machine, 0, " Bresenham Clock Gen 2\n" );
+ break;
+ case 0x0300:
+ //verboselog((machine, 0, " Bresenham Clock Gen 3\n" );
+ break;
+ }
+ break;
+
+ case 0x3000:
+ //verboselog((machine, 0, " Unix Timer\n" );
+ switch (data & IAR_NUM)
+ {
+ case 0x0100:
+ //verboselog((machine, 0, " Unix Timer\n" );
+ break;
+ }
+ break;
+
+ case 0x9000:
+ //verboselog((machine, 0, " Global DMA Control\n" );
+ switch (data & IAR_NUM)
+ {
+ case 0x0100:
+ //verboselog((machine, 0, " DMA Control\n" );
+ break;
+ }
+ break;
+ }
+
+ switch (data & IAR_ACCESS_SEL)
+ {
+ case 0x0000:
+ //verboselog((machine, 0, " Write\n" );
+ break;
+ case 0x0080:
+ //verboselog((machine, 0, " Read\n" );
+ break;
+ }
+ //verboselog((machine, 0, " Parameter: %01x\n", ( data & IAR_PARAM ) >> 2 );
+ return;
+
+ case INDIRECT_DATA0_REG:
+ //verboselog((machine, 0, "HAL2 Indirect Data Register 0 Write: 0x%08x (%08x)\n", data, mem_mask );
+ m_idr[0] = data;
+ return;
+
+ case INDIRECT_DATA1_REG:
+ //verboselog((machine, 0, "HAL2 Indirect Data Register 1 Write: 0x%08x (%08x)\n", data, mem_mask );
+ m_idr[1] = data;
+ return;
+
+ case INDIRECT_DATA2_REG:
+ //verboselog((machine, 0, "HAL2 Indirect Data Register 2 Write: 0x%08x (%08x)\n", data, mem_mask );
+ m_idr[2] = data;
+ return;
+
+ case INDIRECT_DATA3_REG:
+ //verboselog((machine, 0, "HAL2 Indirect Data Register 3 Write: 0x%08x (%08x)\n", data, mem_mask );
+ m_idr[3] = data;
+ return;
+ }
+ //verboselog((machine, 0, "Unknown HAL2 write: 0x%08x: 0x%08x (%08x)\n", 0x1fbd8000 + offset*4, data, mem_mask );
+}
diff --git a/src/mame/machine/hal2.h b/src/mame/machine/hal2.h
new file mode 100644
index 00000000000..c835fa69cab
--- /dev/null
+++ b/src/mame/machine/hal2.h
@@ -0,0 +1,66 @@
+// license:BSD-3-Clause
+// copyright-holders:Ryan Holtz
+/**********************************************************************
+
+ SGI HAL2 Audio Controller emulation
+
+**********************************************************************/
+
+#ifndef MAME_MACHINE_HAL2_H
+#define MAME_MACHINE_HAL2_H
+
+#pragma once
+
+#define MCFG_SGI_HAL2_ADD(_tag) \
+ MCFG_DEVICE_ADD(_tag, SGI_HAL2, 0)
+
+class hal2_device : public device_t
+{
+public:
+ hal2_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+
+ DECLARE_WRITE32_MEMBER( write );
+ DECLARE_READ32_MEMBER( read );
+
+protected:
+ virtual void device_start() override;
+ virtual void device_reset() override;
+
+ enum
+ {
+ IAR_TYPE = 0xf000,
+ IAR_NUM = 0x0f00,
+ IAR_ACCESS_SEL = 0x0080,
+ IAR_PARAM = 0x000c,
+ IAR_RB_INDEX = 0x0003,
+ };
+
+ enum
+ {
+ ISR_TSTATUS = 0x01,
+ ISR_USTATUS = 0x02,
+ ISR_QUAD_MODE = 0x04,
+ ISR_GLOBAL_RESET = 0x08,
+ ISR_CODEC_RESET = 0x10,
+ };
+
+ enum
+ {
+ STATUS_REG = 0x0010/4,
+ REVISION_REG = 0x0020/4,
+ INDIRECT_ADDRESS_REG = 0x0030/4,
+ INDIRECT_DATA0_REG = 0x0040/4,
+ INDIRECT_DATA1_REG = 0x0050/4,
+ INDIRECT_DATA2_REG = 0x0060/4,
+ INDIRECT_DATA3_REG = 0x0070/4,
+ };
+
+ uint32_t m_iar;
+ uint32_t m_idr[4];
+
+ inline void ATTR_PRINTF(3,4) verboselog(int n_level, const char *s_fmt, ... );
+};
+
+DECLARE_DEVICE_TYPE(SGI_HAL2, hal2_device)
+
+#endif // MAME_MACHINE_HAL2_H \ No newline at end of file
diff --git a/src/mame/machine/hpc3.cpp b/src/mame/machine/hpc3.cpp
new file mode 100644
index 00000000000..956edffda90
--- /dev/null
+++ b/src/mame/machine/hpc3.cpp
@@ -0,0 +1,577 @@
+// license:BSD-3-Clause
+// copyright-holders:Ryan Holtz
+/**********************************************************************
+
+ SGI HPC3 "High-performance Peripheral Controller" emulation
+
+**********************************************************************/
+
+#include "emu.h"
+#include "machine/hpc3.h"
+
+DEFINE_DEVICE_TYPE(SGI_HPC3, hpc3_device, "hpc3", "SGI HPC3")
+
+hpc3_device::hpc3_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : device_t(mconfig, SGI_HPC3, tag, owner, clock)
+ , m_maincpu(*this, finder_base::DUMMY_TAG)
+ , m_wd33c93(*this, finder_base::DUMMY_TAG)
+ , m_ioc2(*this, finder_base::DUMMY_TAG)
+ , m_mainram(*this, ":mainram")
+ , m_unkpbus0(*this, ":unkpbus0")
+{
+}
+
+#define VERBOSE_LEVEL ( 0 )
+
+inline void ATTR_PRINTF(3,4) hpc3_device::verboselog(int n_level, const char *s_fmt, ... )
+{
+ if( VERBOSE_LEVEL >= n_level )
+ {
+ va_list v;
+ char buf[ 32768 ];
+ va_start( v, s_fmt );
+ vsprintf( buf, s_fmt, v );
+ va_end( v );
+ logerror("%s: %s", machine().describe_context(), buf);
+ }
+}
+
+void hpc3_device::device_start()
+{
+}
+
+void hpc3_device::device_reset()
+{
+ m_enetr_nbdp = 0x80000000;
+ m_enetr_cbp = 0x80000000;
+ m_pbus_dma.m_active = 0;
+}
+
+void hpc3_device::device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr)
+{
+ switch (id)
+ {
+ case TIMER_DMA:
+ do_dma(ptr, param);
+ break;
+ default:
+ assert_always(false, "Unknown id in hpc3_device::device_timer");
+ }
+}
+
+TIMER_CALLBACK_MEMBER(hpc3_device::do_dma)
+{
+ timer_set(attotime::never, TIMER_DMA);
+#if 0
+ if( m_pbus_dma.m_active )
+ {
+ uint16_t temp16 = ( m_mainram[(m_pbus_dma.m_cur_ptr - 0x08000000)/4] & 0xffff0000 ) >> 16;
+ int16_t stemp16 = (int16_t)((temp16 >> 8) | (temp16 << 8));
+
+ m_dac->write_signed16(stemp16);
+
+ m_pbus_dma.m_cur_ptr += 4;
+
+ m_pbus_dma.m_words_left -= 4;
+ if( m_pbus_dma.m_words_left == 0 )
+ {
+ if( m_pbus_dma.m_next_ptr != 0 )
+ {
+ m_pbus_dma.m_desc_ptr = m_pbus_dma.m_next_ptr;
+ m_pbus_dma.m_cur_ptr = m_mainram[(m_pbus_dma.m_desc_ptr - 0x08000000)/4];
+ m_pbus_dma.m_words_left = m_mainram[(m_pbus_dma.m_desc_ptr - 0x08000000)/4+1];
+ m_pbus_dma.m_next_ptr = m_mainram[(m_pbus_dma.m_desc_ptr - 0x08000000)/4+2];
+ }
+ else
+ {
+ m_pbus_dma.m_active = 0;
+ return;
+ }
+ }
+ timer_set(attotime::from_hz(44100), TIMER_DMA);
+ }
+#endif
+}
+
+READ32_MEMBER(hpc3_device::hd_enet_r)
+{
+ switch( offset )
+ {
+ case 0x0004/4:
+ //verboselog((machine, 0, "HPC3 SCSI0DESC Read: %08x (%08x): %08x\n", 0x1fb90000 + ( offset << 2), mem_mask, m_scsi0_desc );
+ return m_scsi0_desc;
+ case 0x1004/4:
+ //verboselog((machine, 0, "HPC3 SCSI0DMACTRL Read: %08x (%08x): %08x\n", 0x1fb90000 + ( offset << 2), mem_mask, m_scsi0_dma_ctrl );
+ return m_scsi0_dma_ctrl;
+ case 0x4000/4:
+ //verboselog((machine, 2, "HPC3 ENETR CBP Read: %08x (%08x): %08x\n", 0x1fb90000 + ( offset << 2), mem_mask, m_enetr_nbdp );
+ return m_enetr_cbp;
+ case 0x4004/4:
+ //verboselog((machine, 2, "HPC3 ENETR NBDP Read: %08x (%08x): %08x\n", 0x1fb90000 + ( offset << 2), mem_mask, m_enetr_nbdp );
+ return m_enetr_nbdp;
+ default:
+ //verboselog((machine, 0, "Unknown HPC3 ENET/HDx Read: %08x (%08x)\n", 0x1fb90000 + ( offset << 2 ), mem_mask );
+ return 0;
+ }
+}
+
+WRITE32_MEMBER(hpc3_device::hd_enet_w)
+{
+ switch( offset )
+ {
+ case 0x0004/4:
+ //verboselog((machine, 2, "HPC3 SCSI0DESC Write: %08x\n", data );
+ m_scsi0_desc = data;
+ break;
+ case 0x1004/4:
+ //verboselog((machine, 2, "HPC3 SCSI0DMACTRL Write: %08x\n", data );
+ m_scsi0_dma_ctrl = data;
+ break;
+ case 0x4000/4:
+ //verboselog((machine, 2, "HPC3 ENETR CBP Write: %08x\n", data );
+ m_enetr_cbp = data;
+ break;
+ case 0x4004/4:
+ //verboselog((machine, 2, "HPC3 ENETR NBDP Write: %08x\n", data );
+ m_enetr_nbdp = data;
+ break;
+ default:
+ //verboselog((machine, 0, "Unknown HPC3 ENET/HDx write: %08x (%08x): %08x\n", 0x1fb90000 + ( offset << 2 ), mem_mask, data );
+ break;
+ }
+}
+
+READ32_MEMBER(hpc3_device::hd0_r)
+{
+ switch( offset )
+ {
+ case 0x0000/4:
+ case 0x4000/4:
+// //verboselog((machine, 2, "HPC3 HD0 Status Read: %08x (%08x): %08x\n", 0x1fb90000 + ( offset << 2), mem_mask, nHPC3_hd0_regs[0x17] );
+ if (ACCESSING_BITS_0_7)
+ {
+ return m_wd33c93->read( space, 0 );
+ }
+ else
+ {
+ return 0;
+ }
+ case 0x0004/4:
+ case 0x4004/4:
+// //verboselog((machine, 2, "HPC3 HD0 Register Read: %08x (%08x): %08x\n", 0x1fb90000 + ( offset << 2), mem_mask, nHPC3_hd0_regs[nHPC3_hd0_register] );
+ if (ACCESSING_BITS_0_7)
+ {
+ return m_wd33c93->read( space, 1 );
+ }
+ else
+ {
+ return 0;
+ }
+ default:
+ //verboselog((machine, 0, "Unknown HPC3 HD0 Read: %08x (%08x) [%x] PC=%x\n", 0x1fbc0000 + ( offset << 2 ), mem_mask, offset, m_maincpu->pc() );
+ return 0;
+ }
+}
+
+WRITE32_MEMBER(hpc3_device::hd0_w)
+{
+ switch( offset )
+ {
+ case 0x0000/4:
+ case 0x4000/4:
+// //verboselog((machine, 2, "HPC3 HD0 Register Select Write: %08x\n", data );
+ if (ACCESSING_BITS_0_7)
+ {
+ m_wd33c93->write( space, 0, data & 0x000000ff );
+ }
+ break;
+ case 0x0004/4:
+ case 0x4004/4:
+// //verboselog((machine, 2, "HPC3 HD0 Register %d Write: %08x\n", nHPC3_hd0_register, data );
+ if (ACCESSING_BITS_0_7)
+ {
+ m_wd33c93->write( space, 1, data & 0x000000ff );
+ }
+ break;
+ default:
+ //verboselog((machine, 0, "Unknown HPC3 HD0 Write: %08x (%08x): %08x\n", 0x1fbc0000 + ( offset << 2 ), mem_mask, data );
+ break;
+ }
+}
+
+
+READ32_MEMBER(hpc3_device::pbus4_r)
+{
+ switch( offset )
+ {
+ case 0x0004/4:
+ //verboselog((machine, 2, "HPC3 PBUS4 Unknown 0 Read: (%08x): %08x\n", mem_mask, m_unk0 );
+ return m_unk0;
+ case 0x000c/4:
+ //verboselog((machine, 2, "Interrupt Controller(?) Read: (%08x): %08x\n", mem_mask, m_ic_unk0 );
+ return m_ic_unk0;
+ case 0x0014/4:
+ //verboselog((machine, 2, "HPC3 PBUS4 Unknown 1 Read: (%08x): %08x\n", mem_mask, m_unk1 );
+ return m_unk1;
+ default:
+ //verboselog((machine, 0, "Unknown HPC3 PBUS4 Read: %08x (%08x)\n", 0x1fbd9000 + ( offset << 2 ), mem_mask );
+ return 0;
+ }
+}
+
+WRITE32_MEMBER(hpc3_device::pbus4_w)
+{
+ switch( offset )
+ {
+ case 0x0004/4:
+ //verboselog((machine, 2, "HPC3 PBUS4 Unknown 0 Write: %08x (%08x)\n", data, mem_mask );
+ m_unk0 = data;
+ break;
+ case 0x000c/4:
+ //verboselog((machine, 2, "Interrupt Controller(?) Write: (%08x): %08x\n", mem_mask, data );
+ m_ic_unk0 = data;
+ break;
+ case 0x0014/4:
+ //verboselog((machine, 2, "HPC3 PBUS4 Unknown 1 Write: %08x (%08x)\n", data, mem_mask );
+ m_unk1 = data;
+ break;
+ default:
+ //verboselog((machine, 0, "Unknown HPC3 PBUS4 Write: %08x (%08x): %08x\n", 0x1fbd9000 + ( offset << 2 ), mem_mask, data );
+ break;
+ }
+}
+
+READ32_MEMBER(hpc3_device::pbusdma_r)
+{
+ //uint32_t channel = offset / (0x2000/4);
+ //verboselog((machine(), 0, "PBUS DMA Channel %d Read: 0x%08x (%08x)\n", channel, 0x1fb80000 + offset*4, mem_mask );
+ return 0;
+}
+
+WRITE32_MEMBER(hpc3_device::pbusdma_w)
+{
+ uint32_t channel = offset / (0x2000/4);
+
+ switch( offset & 0x07ff )
+ {
+ case 0x0000/4:
+ //verboselog((machine, 0, "PBUS DMA Channel %d Buffer Pointer Write: 0x%08x\n", channel, data );
+ return;
+ case 0x0004/4:
+ //verboselog((machine, 0, "PBUS DMA Channel %d Descriptor Pointer Write: 0x%08x\n", channel, data );
+ if( channel == 1 )
+ {
+ m_pbus_dma.m_desc_ptr = data;
+ m_pbus_dma.m_cur_ptr = m_mainram[(m_pbus_dma.m_desc_ptr - 0x08000000)/4];
+ m_pbus_dma.m_words_left = m_mainram[(m_pbus_dma.m_desc_ptr - 0x08000000)/4+1];
+ m_pbus_dma.m_next_ptr = m_mainram[(m_pbus_dma.m_desc_ptr - 0x08000000)/4+2];
+ //verboselog((machine, 0, "nPBUS_DMA_DescPtr = %08x\n", m_pbus_dma.m_desc_ptr );
+ //verboselog((machine, 0, "nPBUS_DMA_CurPtr = %08x\n", m_pbus_dma.m_cur_ptr );
+ //verboselog((machine, 0, "nPBUS_DMA_WordsLeft = %08x\n", m_pbus_dma.m_words_left );
+ //verboselog((machine, 0, "nPBUS_DMA_NextPtr = %08x\n", m_pbus_dma.m_next_ptr );
+ }
+ return;
+ case 0x1000/4:
+ //verboselog((machine, 0, "PBUS DMA Channel %d Control Register Write: 0x%08x\n", channel, data );
+ if( data & PBUS_CTRL_ENDIAN )
+ {
+ //verboselog((machine, 0, " Little Endian\n" );
+ }
+ else
+ {
+ //verboselog((machine, 0, " Big Endian\n" );
+ }
+ if( data & PBUS_CTRL_RECV )
+ {
+ //verboselog((machine, 0, " RX DMA\n" );
+ }
+ else
+ {
+ //verboselog((machine, 0, " TX DMA\n" );
+ }
+ if( data & PBUS_CTRL_FLUSH )
+ {
+ //verboselog((machine, 0, " Flush for RX\n" );
+ }
+ if( data & PBUS_CTRL_DMASTART )
+ {
+ //verboselog((machine, 0, " Start DMA\n" );
+ }
+ if( data & PBUS_CTRL_LOAD_EN )
+ {
+ //verboselog((machine, 0, " Load Enable\n" );
+ }
+ //verboselog((machine, 0, " High Water Mark: %04x bytes\n", ( data & PBUS_CTRL_HIGHWATER ) >> 8 );
+ //verboselog((machine, 0, " FIFO Begin: Row %04x\n", ( data & PBUS_CTRL_FIFO_BEG ) >> 16 );
+ //verboselog((machine, 0, " FIFO End: Rowe %04x\n", ( data & PBUS_CTRL_FIFO_END ) >> 24 );
+ if( ( data & PBUS_CTRL_DMASTART ) || ( data & PBUS_CTRL_LOAD_EN ) )
+ {
+ timer_set(attotime::from_hz(44100), TIMER_DMA);
+ m_pbus_dma.m_active = 1;
+ }
+ return;
+ }
+ //verboselog((machine, 0, "Unknown PBUS DMA Channel %d Write: 0x%08x: 0x%08x (%08x)\n", channel, 0x1fb80000 + offset*4, data, mem_mask );
+}
+
+READ32_MEMBER(hpc3_device::unkpbus0_r)
+{
+ return 0;
+ ////verboselog((machine(), 0, "Unknown PBUS Read: 0x%08x (%08x)\n", 0x1fbc8000 + offset*4, mem_mask );
+ //return m_unkpbus0[offset];
+}
+
+WRITE32_MEMBER(hpc3_device::unkpbus0_w)
+{
+ ////verboselog((machine(), 0, "Unknown PBUS Write: 0x%08x = 0x%08x (%08x)\n", 0x1fbc8000 + offset*4, data, mem_mask );
+ //COMBINE_DATA(&m_unkpbus0[offset]);
+}
+
+void hpc3_device::dump_chain(address_space &space, uint32_t ch_base)
+{
+ logerror("node: %08x %08x %08x (len = %x)\n", space.read_dword(ch_base), space.read_dword(ch_base+4), space.read_dword(ch_base+8), space.read_dword(ch_base+4) & 0x3fff);
+
+ if ((space.read_dword(ch_base+8) != 0) && !(space.read_dword(ch_base+4) & 0x80000000))
+ {
+ dump_chain(space, space.read_dword(ch_base+8));
+ }
+}
+
+WRITE_LINE_MEMBER(hpc3_device::scsi_irq)
+{
+ address_space &space = m_maincpu->space(AS_PROGRAM);
+
+ if (state)
+ {
+ if (m_wd33c93->get_dma_count())
+ {
+ logerror("m_wd33c93->get_dma_count() is %d\n", m_wd33c93->get_dma_count() );
+ if (m_scsi0_dma_ctrl & HPC3_DMACTRL_ENABLE)
+ {
+ if (m_scsi0_dma_ctrl & HPC3_DMACTRL_IRQ) logerror("IP22: Unhandled SCSI DMA IRQ\n");
+ }
+
+ // HPC3 DMA: host to device
+ if ((m_scsi0_dma_ctrl & HPC3_DMACTRL_ENABLE) && (m_scsi0_dma_ctrl & HPC3_DMACTRL_DIR))
+ {
+ uint32_t wptr, tmpword;
+ int words, dptr, twords;
+
+ words = m_wd33c93->get_dma_count();
+ words /= 4;
+
+ wptr = space.read_dword(m_scsi0_desc);
+ m_scsi0_desc += words*4;
+ dptr = 0;
+
+ logerror("DMA to device: %d words @ %x\n", words, wptr);
+
+ dump_chain(space, m_scsi0_desc);
+
+ if (words <= (512/4))
+ {
+ // one-shot
+ //m_wd33c93->dma_read_data(m_wd33c93->get_dma_count(), m_dma_buffer);
+
+ while (words)
+ {
+ tmpword = space.read_dword(wptr);
+
+ if (m_scsi0_dma_ctrl & HPC3_DMACTRL_ENDIAN)
+ {
+ m_dma_buffer[dptr+3] = (tmpword>>24)&0xff;
+ m_dma_buffer[dptr+2] = (tmpword>>16)&0xff;
+ m_dma_buffer[dptr+1] = (tmpword>>8)&0xff;
+ m_dma_buffer[dptr] = tmpword&0xff;
+ }
+ else
+ {
+ m_dma_buffer[dptr] = (tmpword>>24)&0xff;
+ m_dma_buffer[dptr+1] = (tmpword>>16)&0xff;
+ m_dma_buffer[dptr+2] = (tmpword>>8)&0xff;
+ m_dma_buffer[dptr+3] = tmpword&0xff;
+ }
+
+ wptr += 4;
+ dptr += 4;
+ words--;
+ }
+
+ words = m_wd33c93->get_dma_count();
+ m_wd33c93->dma_write_data(words, m_dma_buffer);
+ }
+ else
+ {
+ while (words)
+ {
+ //m_wd33c93->dma_read_data(512, m_dma_buffer);
+ twords = 512/4;
+ m_scsi0_desc += 512;
+ dptr = 0;
+
+ while (twords)
+ {
+ tmpword = space.read_dword(wptr);
+
+ if (m_scsi0_dma_ctrl & HPC3_DMACTRL_ENDIAN)
+ {
+ m_dma_buffer[dptr+3] = (tmpword>>24)&0xff;
+ m_dma_buffer[dptr+2] = (tmpword>>16)&0xff;
+ m_dma_buffer[dptr+1] = (tmpword>>8)&0xff;
+ m_dma_buffer[dptr] = tmpword&0xff;
+ }
+ else
+ {
+ m_dma_buffer[dptr] = (tmpword>>24)&0xff;
+ m_dma_buffer[dptr+1] = (tmpword>>16)&0xff;
+ m_dma_buffer[dptr+2] = (tmpword>>8)&0xff;
+ m_dma_buffer[dptr+3] = tmpword&0xff;
+ }
+
+ wptr += 4;
+ dptr += 4;
+ twords--;
+ }
+
+ m_wd33c93->dma_write_data(512, m_dma_buffer);
+
+ words -= (512/4);
+ }
+ }
+
+ // clear DMA on the controller too
+ m_wd33c93->clear_dma();
+#if 0
+ uint32_t dptr, tmpword;
+ uint32_t bc = space.read_dword(m_scsi0_desc + 4);
+ uint32_t rptr = space.read_dword(m_scsi0_desc);
+ int length = bc & 0x3fff;
+ int xie = (bc & 0x20000000) ? 1 : 0;
+ int eox = (bc & 0x80000000) ? 1 : 0;
+
+ dump_chain(space, m_scsi0_desc);
+
+ logerror("%s DMA to device: length %x xie %d eox %d\n", machine().describe_context().c_str(), length, xie, eox);
+
+ if (length <= 0x4000)
+ {
+ dptr = 0;
+ while (length > 0)
+ {
+ tmpword = space.read_dword(rptr);
+ if (m_scsi0_dma_ctrl & HPC3_DMACTRL_ENDIAN)
+ {
+ m_dma_buffer[dptr+3] = (tmpword>>24)&0xff;
+ m_dma_buffer[dptr+2] = (tmpword>>16)&0xff;
+ m_dma_buffer[dptr+1] = (tmpword>>8)&0xff;
+ m_dma_buffer[dptr] = tmpword&0xff;
+ }
+ else
+ {
+ m_dma_buffer[dptr] = (tmpword>>24)&0xff;
+ m_dma_buffer[dptr+1] = (tmpword>>16)&0xff;
+ m_dma_buffer[dptr+2] = (tmpword>>8)&0xff;
+ m_dma_buffer[dptr+3] = tmpword&0xff;
+ }
+
+ dptr += 4;
+ rptr += 4;
+ length -= 4;
+ }
+
+ length = space.read_dword(m_scsi0_desc+4) & 0x3fff;
+ m_wd33c93->write_data(length, m_dma_buffer);
+
+ // clear DMA on the controller too
+ m_wd33c93->clear_dma();
+ }
+ else
+ {
+ logerror("IP22: overly large host to device transfer, can't handle!\n");
+ }
+#endif
+ }
+
+ // HPC3 DMA: device to host
+ if ((m_scsi0_dma_ctrl & HPC3_DMACTRL_ENABLE) && !(m_scsi0_dma_ctrl & HPC3_DMACTRL_DIR))
+ {
+ uint32_t wptr, tmpword;
+ int words, sptr, twords;
+
+ words = m_wd33c93->get_dma_count();
+ words /= 4;
+
+ wptr = space.read_dword(m_scsi0_desc);
+ sptr = 0;
+
+// osd_printf_info("DMA from device: %d words @ %x\n", words, wptr);
+
+ dump_chain(space, m_scsi0_desc);
+
+ if (words <= (1024/4))
+ {
+ // one-shot
+ m_wd33c93->dma_read_data(m_wd33c93->get_dma_count(), m_dma_buffer);
+
+ while (words)
+ {
+ if (m_scsi0_dma_ctrl & HPC3_DMACTRL_ENDIAN)
+ {
+ tmpword = m_dma_buffer[sptr+3]<<24 | m_dma_buffer[sptr+2]<<16 | m_dma_buffer[sptr+1]<<8 | m_dma_buffer[sptr];
+ }
+ else
+ {
+ tmpword = m_dma_buffer[sptr]<<24 | m_dma_buffer[sptr+1]<<16 | m_dma_buffer[sptr+2]<<8 | m_dma_buffer[sptr+3];
+ }
+
+ space.write_dword(wptr, tmpword);
+ wptr += 4;
+ sptr += 4;
+ words--;
+ }
+ }
+ else
+ {
+ while (words)
+ {
+ m_wd33c93->dma_read_data(512, m_dma_buffer);
+ twords = 512/4;
+ sptr = 0;
+
+ while (twords)
+ {
+ if (m_scsi0_dma_ctrl & HPC3_DMACTRL_ENDIAN)
+ {
+ tmpword = m_dma_buffer[sptr+3]<<24 | m_dma_buffer[sptr+2]<<16 | m_dma_buffer[sptr+1]<<8 | m_dma_buffer[sptr];
+ }
+ else
+ {
+ tmpword = m_dma_buffer[sptr]<<24 | m_dma_buffer[sptr+1]<<16 | m_dma_buffer[sptr+2]<<8 | m_dma_buffer[sptr+3];
+ }
+ space.write_dword(wptr, tmpword);
+
+ wptr += 4;
+ sptr += 4;
+ twords--;
+ }
+
+ words -= (512/4);
+ }
+ }
+
+ // clear DMA on the controller too
+ m_wd33c93->clear_dma();
+ }
+ }
+
+ // clear HPC3 DMA active flag
+ m_scsi0_dma_ctrl &= ~HPC3_DMACTRL_ENABLE;
+
+ // set the interrupt
+ m_ioc2->raise_local0_irq(ioc2_device::INT3_LOCAL0_SCSI0);
+ }
+ else
+ {
+ m_ioc2->lower_local0_irq(ioc2_device::INT3_LOCAL0_SCSI0);
+ }
+}
diff --git a/src/mame/machine/hpc3.h b/src/mame/machine/hpc3.h
new file mode 100644
index 00000000000..e654e56156e
--- /dev/null
+++ b/src/mame/machine/hpc3.h
@@ -0,0 +1,128 @@
+// license:BSD-3-Clause
+// copyright-holders:Ryan Holtz
+/**********************************************************************
+
+ SGI HPC3 "High-performance Peripheral Controller" emulation
+
+**********************************************************************/
+
+#ifndef MAME_MACHINE_HPC3_H
+#define MAME_MACHINE_HPC3_H
+
+#pragma once
+
+#include "cpu/mips/mips3.h"
+#include "machine/ioc2.h"
+#include "machine/wd33c93.h"
+
+#define MCFG_SGI_HPC3_ADD(_tag) \
+ MCFG_DEVICE_ADD(_tag, SGI_HPC3, 0)
+
+#define MCFG_HPC3_CPU_TAG(cpu_tag) \
+ downcast<hpc3_device &>(*device).set_cpu_tag(("^" cpu_tag));
+
+#define MCFG_HPC3_SCSI_TAG(scsi_tag) \
+ downcast<hpc3_device &>(*device).set_scsi_tag(("^" scsi_tag));
+
+#define MCFG_HPC3_IOC2_TAG(ioc2_tag) \
+ downcast<hpc3_device &>(*device).set_ioc2_tag(("^" ioc2_tag));
+
+class hpc3_device : public device_t
+{
+public:
+ hpc3_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+
+ void set_cpu_tag(const char *tag) { m_maincpu.set_tag(tag); }
+ void set_scsi_tag(const char *tag) { m_wd33c93.set_tag(tag); }
+ void set_ioc2_tag(const char *tag) { m_ioc2.set_tag(tag); }
+
+ DECLARE_READ32_MEMBER(hd_enet_r);
+ DECLARE_WRITE32_MEMBER(hd_enet_w);
+ DECLARE_READ32_MEMBER(hd0_r);
+ DECLARE_WRITE32_MEMBER(hd0_w);
+ DECLARE_READ32_MEMBER(pbus4_r);
+ DECLARE_WRITE32_MEMBER(pbus4_w);
+ DECLARE_READ32_MEMBER(pbusdma_r);
+ DECLARE_WRITE32_MEMBER(pbusdma_w);
+ DECLARE_READ32_MEMBER(unkpbus0_r);
+ DECLARE_WRITE32_MEMBER(unkpbus0_w);
+
+ DECLARE_WRITE_LINE_MEMBER(scsi_irq);
+
+ TIMER_CALLBACK_MEMBER(do_dma);
+
+protected:
+ void device_start() override;
+ void device_reset() override;
+ void device_timer(emu_timer &timer, device_timer_id id, int param, void *ptr) override;
+
+ void dump_chain(address_space &space, uint32_t ch_base);
+
+ struct pbus_dma_t
+ {
+ uint8_t m_active;
+ uint32_t m_cur_ptr;
+ uint32_t m_desc_ptr;
+ uint32_t m_next_ptr;
+ uint32_t m_words_left;
+ };
+
+ enum
+ {
+ TIMER_DMA
+ };
+
+ enum
+ {
+ PBUS_CTRL_ENDIAN = 0x00000002,
+ PBUS_CTRL_RECV = 0x00000004,
+ PBUS_CTRL_FLUSH = 0x00000008,
+ PBUS_CTRL_DMASTART = 0x00000010,
+ PBUS_CTRL_LOAD_EN = 0x00000020,
+ PBUS_CTRL_REALTIME = 0x00000040,
+ PBUS_CTRL_HIGHWATER = 0x0000ff00,
+ PBUS_CTRL_FIFO_BEG = 0x003f0000,
+ PBUS_CTRL_FIFO_END = 0x3f000000,
+ };
+
+ enum
+ {
+ PBUS_DMADESC_EOX = 0x80000000,
+ PBUS_DMADESC_EOXP = 0x40000000,
+ PBUS_DMADESC_XIE = 0x20000000,
+ PBUS_DMADESC_IPG = 0x00ff0000,
+ PBUS_DMADESC_TXD = 0x00008000,
+ PBUS_DMADESC_BC = 0x00003fff,
+ };
+
+ enum
+ {
+ HPC3_DMACTRL_IRQ = 0x01,
+ HPC3_DMACTRL_ENDIAN = 0x02,
+ HPC3_DMACTRL_DIR = 0x04,
+ HPC3_DMACTRL_ENABLE = 0x10,
+ };
+
+ required_device<mips3_device> m_maincpu;
+ required_device<wd33c93_device> m_wd33c93;
+ required_device<ioc2_device> m_ioc2;
+ required_shared_ptr<uint32_t> m_mainram;
+ required_shared_ptr<uint32_t> m_unkpbus0;
+
+ uint32_t m_enetr_nbdp;
+ uint32_t m_enetr_cbp;
+ uint32_t m_unk0;
+ uint32_t m_unk1;
+ uint32_t m_ic_unk0;
+ uint32_t m_scsi0_desc;
+ uint32_t m_scsi0_dma_ctrl;
+ pbus_dma_t m_pbus_dma;
+
+ uint8_t m_dma_buffer[4096];
+
+ inline void ATTR_PRINTF(3,4) verboselog(int n_level, const char *s_fmt, ... );
+};
+
+DECLARE_DEVICE_TYPE(SGI_HPC3, hpc3_device)
+
+#endif // MAME_MACHINE_HAL2_H \ No newline at end of file
diff --git a/src/mame/machine/ioc2.cpp b/src/mame/machine/ioc2.cpp
new file mode 100644
index 00000000000..a9019033f95
--- /dev/null
+++ b/src/mame/machine/ioc2.cpp
@@ -0,0 +1,432 @@
+// license:BSD-3-Clause
+// copyright-holders:Ryan Holtz
+/**********************************************************************
+
+ SGI IOC2 I/O Controller emulation
+
+**********************************************************************/
+
+#include "emu.h"
+#include "bus/rs232/rs232.h"
+#include "machine/ioc2.h"
+
+/*static*/ const char *ioc2_device::SCC_TAG = "scc";
+/*static*/ const char *ioc2_device::PI1_TAG = "pi1";
+/*static*/ const char *ioc2_device::KBDC_TAG = "kbdc";
+/*static*/ const char *ioc2_device::PIT_TAG = "pit";
+/*static*/ const char *ioc2_device::RS232A_TAG = "rs232a";
+/*static*/ const char *ioc2_device::RS232B_TAG = "rs232b";
+
+/*static*/ const XTAL ioc2_device::SCC_PCLK = XTAL(10'000'000);
+/*static*/ const XTAL ioc2_device::SCC_RXA_CLK = XTAL(3'686'400); // Needs verification
+/*static*/ const XTAL ioc2_device::SCC_TXA_CLK = XTAL(0);
+/*static*/ const XTAL ioc2_device::SCC_RXB_CLK = XTAL(3'686'400); // Needs verification
+/*static*/ const XTAL ioc2_device::SCC_TXB_CLK = XTAL(0);
+
+DEFINE_DEVICE_TYPE(SGI_IOC2_GUINNESS, ioc2_guinness_device, "ioc2g", "SGI IOC2 (Guiness)")
+DEFINE_DEVICE_TYPE(SGI_IOC2_FULL_HOUSE, ioc2_full_house_device, "ioc2f", "SGI IOC2 (Full House)")
+
+ioc2_guinness_device::ioc2_guinness_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : ioc2_guinness_device(mconfig, SGI_IOC2_GUINNESS, tag, owner, clock)
+{
+}
+
+ioc2_full_house_device::ioc2_full_house_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : ioc2_full_house_device(mconfig, SGI_IOC2_FULL_HOUSE, tag, owner, clock)
+{
+}
+
+static INPUT_PORTS_START( front_panel )
+ PORT_START("panel_buttons")
+ PORT_BIT(0x02, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_NAME("Power") PORT_CHANGED_MEMBER(DEVICE_SELF, ioc2_device, power_button, 0)
+ PORT_BIT(0x10, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_NAME("Volume Down") PORT_CHANGED_MEMBER(DEVICE_SELF, ioc2_device, volume_down, 0)
+ PORT_BIT(0x40, IP_ACTIVE_LOW, IPT_KEYPAD) PORT_NAME("Volume Up") PORT_CHANGED_MEMBER(DEVICE_SELF, ioc2_device, volume_up, 0)
+INPUT_PORTS_END
+
+ioport_constructor ioc2_device::device_input_ports() const
+{
+ return INPUT_PORTS_NAME(front_panel);
+}
+
+MACHINE_CONFIG_START(ioc2_device::device_add_mconfig)
+ MCFG_SCC85230_ADD(SCC_TAG, SCC_PCLK, SCC_RXA_CLK.value(), SCC_TXA_CLK.value(), SCC_RXB_CLK.value(), SCC_TXB_CLK.value())
+ MCFG_Z80SCC_OUT_TXDA_CB(DEVWRITELINE(RS232A_TAG, rs232_port_device, write_txd))
+ MCFG_Z80SCC_OUT_DTRA_CB(DEVWRITELINE(RS232A_TAG, rs232_port_device, write_dtr))
+ MCFG_Z80SCC_OUT_RTSA_CB(DEVWRITELINE(RS232A_TAG, rs232_port_device, write_rts))
+ MCFG_Z80SCC_OUT_TXDB_CB(DEVWRITELINE(RS232B_TAG, rs232_port_device, write_txd))
+ MCFG_Z80SCC_OUT_DTRB_CB(DEVWRITELINE(RS232B_TAG, rs232_port_device, write_dtr))
+ MCFG_Z80SCC_OUT_RTSB_CB(DEVWRITELINE(RS232B_TAG, rs232_port_device, write_rts))
+
+ MCFG_RS232_PORT_ADD(RS232A_TAG, default_rs232_devices, nullptr)
+ MCFG_RS232_CTS_HANDLER(DEVWRITELINE(SCC_TAG, scc85230_device, ctsa_w))
+ MCFG_RS232_DCD_HANDLER(DEVWRITELINE(SCC_TAG, scc85230_device, dcda_w))
+ MCFG_RS232_RXD_HANDLER(DEVWRITELINE(SCC_TAG, scc85230_device, rxa_w))
+
+ MCFG_RS232_PORT_ADD(RS232B_TAG, default_rs232_devices, nullptr)
+ MCFG_RS232_CTS_HANDLER(DEVWRITELINE(SCC_TAG, scc85230_device, ctsb_w))
+ MCFG_RS232_DCD_HANDLER(DEVWRITELINE(SCC_TAG, scc85230_device, dcdb_w))
+ MCFG_RS232_RXD_HANDLER(DEVWRITELINE(SCC_TAG, scc85230_device, rxb_w))
+
+ MCFG_DEVICE_ADD(PI1_TAG, PC_LPT, 0)
+
+ MCFG_DEVICE_ADD(KBDC_TAG, KBDC8042, 0)
+ MCFG_KBDC8042_KEYBOARD_TYPE(KBDC8042_PS2)
+ MCFG_KBDC8042_SYSTEM_RESET_CB(INPUTLINE("^maincpu", INPUT_LINE_RESET))
+
+ MCFG_DEVICE_ADD(PIT_TAG, PIT8254, 0)
+ MCFG_PIT8253_CLK0(1000000)
+ MCFG_PIT8253_CLK1(1000000)
+ MCFG_PIT8253_CLK2(1000000)
+ MCFG_PIT8253_OUT2_HANDLER(DEVWRITELINE(KBDC_TAG, kbdc8042_device, write_out2))
+MACHINE_CONFIG_END
+
+
+ioc2_device::ioc2_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, uint8_t id)
+ : device_t(mconfig, type, tag, owner, clock)
+ , m_maincpu(*this, finder_base::DUMMY_TAG)
+ , m_scc(*this, SCC_TAG)
+ , m_pi1(*this, PI1_TAG)
+ , m_kbdc(*this, KBDC_TAG)
+ , m_pit(*this, PIT_TAG)
+ , m_gen_ctrl_select_reg(0)
+ , m_gen_ctrl_reg(0)
+ , m_front_panel_reg(0)
+ , m_read_reg(0)
+ , m_dma_sel(0)
+ , m_reset_reg(0)
+ , m_write_reg(0)
+ , m_int3_local0_status_reg(0)
+ , m_int3_local0_mask_reg(0)
+ , m_int3_local1_status_reg(0)
+ , m_int3_local1_mask_reg(0)
+ , m_int3_map_status_reg(0)
+ , m_int3_map_mask0_reg(0)
+ , m_int3_map_mask1_reg(0)
+ , m_int3_map_pol_reg(0)
+ , m_int3_timer_clear_reg(0)
+ , m_int3_err_status_reg(0)
+ , m_par_read_cnt(0)
+ , m_par_cntl(0)
+ , m_system_id(id)
+{
+}
+
+void ioc2_device::device_start()
+{
+ m_front_panel_reg = FRONT_PANEL_POWER_STATE;
+}
+
+void ioc2_device::device_reset()
+{
+ m_par_read_cnt = 0;
+ m_par_cntl = 0;
+
+ m_gen_ctrl_select_reg = 0;
+ m_gen_ctrl_reg = 0;
+ m_front_panel_reg = FRONT_PANEL_POWER_STATE;
+
+ m_read_reg = 0;
+ m_dma_sel = 0;
+ m_reset_reg = 0;
+ m_write_reg = 0;
+
+ m_int3_local0_status_reg = 0;
+ m_int3_local0_mask_reg = 0;
+ m_int3_local1_status_reg = 0;
+ m_int3_local1_mask_reg = 0;
+ m_int3_map_status_reg = 0;
+ m_int3_map_mask0_reg = 0;
+ m_int3_map_mask1_reg = 0;
+ m_int3_map_pol_reg = 0;
+ m_int3_timer_clear_reg = 0;
+ m_int3_err_status_reg = 0;
+}
+
+void ioc2_device::raise_local0_irq(uint8_t source_mask)
+{
+ m_int3_local0_status_reg |= source_mask;
+ m_maincpu->set_input_line(MIPS3_IRQ0, (m_int3_local0_mask_reg & m_int3_local0_status_reg) != 0 ? ASSERT_LINE : CLEAR_LINE);
+}
+
+void ioc2_device::lower_local0_irq(uint8_t source_mask)
+{
+ m_int3_local0_status_reg &= ~source_mask;
+}
+
+void ioc2_device::raise_local1_irq(uint8_t source_mask)
+{
+ m_int3_local1_status_reg |= source_mask;
+ m_maincpu->set_input_line(MIPS3_IRQ1, (m_int3_local1_mask_reg & m_int3_local1_status_reg) != 0 ? ASSERT_LINE : CLEAR_LINE);
+}
+
+void ioc2_device::lower_local1_irq(uint8_t source_mask)
+{
+ m_int3_local1_status_reg &= ~source_mask;
+}
+
+READ32_MEMBER( ioc2_device::read )
+{
+ switch (offset)
+ {
+ case PI1_DATA_REG:
+ case PI1_CTRL_REG:
+ case PI1_STATUS_REG:
+ return m_pi1->read(space, offset, 0xff);
+
+ case PI1_DMA_CTRL_REG:
+ case PI1_INT_STATUS_REG:
+ case PI1_INT_MASK_REG:
+ case PI1_TIMER1_REG:
+ case PI1_TIMER2_REG:
+ case PI1_TIMER3_REG:
+ case PI1_TIMER4_REG:
+ return 0;
+
+ case SERIAL1_CMD_REG:
+ case SERIAL1_DATA_REG:
+ case SERIAL2_CMD_REG:
+ case SERIAL2_DATA_REG:
+ return m_scc->ba_cd_r(space, (offset - SERIAL1_CMD_REG) ^ 3);
+
+ case KBD_MOUSE_REGS1:
+ case KBD_MOUSE_REGS2:
+ return m_kbdc->data_r(space, (offset - KBD_MOUSE_REGS1) * 4);
+
+ case PANEL_REG:
+ return m_front_panel_reg;
+
+ case SYSID_REG:
+ return m_system_id;
+
+ case READ_REG:
+ return m_read_reg;
+
+ case DMA_SEL_REG:
+ // Bits 2-0 not quite understood, seem to be copy/paste error in SGI's own documents:
+ //
+ // 2 RW Parallel Port DMA Select. A high bit selects the Parallel Port DMA channel. 0\h is the default after reset. [this makes sense. -ed.]
+ // 1 RW ISDN Channel B DMA Select. A high bit selects the Parallel Port DMA channel. 0\h is the default after reset. [is this a copy/paste error? perhaps "Parallel Port" should be "ISDN Channel B"?]
+ // 0 RW [same text as above. Another copy/paste error, maybe? Should be channel A, with the bit selecting DMA channel 0/1 for ISDN channel A, the and the same for ISDN channel B in bit 1?]
+ return m_dma_sel;
+
+ case RESET_REG:
+ return m_reset_reg;
+
+ case WRITE_REG:
+ // Not yet implemented, some bits unnecessary:
+ //
+ // Bit Oper Description
+ // 7 RW Margin High. Set low for normal +5V operation, high to step supply up to +5.5V. Cleared at reset.
+ // 6 RW Margin Low. Set lowf or normal +5V operation, high to step supply down to +4.5V. Cleared at reset.
+ // 5 RW UART1 PC Mode. Set low to configure Port1 for RS422 Mac mode, high to select RS232 PC mode. Cleared at reset.
+ // 4 RW UART2 PC Mode. Set low to configure Port2 for RS422 Mac mode, high to select RS232 PC mode. Cleared at reset.
+ // 3 RW Ethernet Auto Select (active high). Set low for manual mode, high to have LXT901 automatically select TP or AUI based on link integrity. Cleared at reset.
+ // 2 RW Ethernet Port Select. Set low for TP, high for AUI. This setting is only used when Auto Select is in manual mode. Cleared at reset.
+ // 1 RW Ethernet UTP/STP select. Set low to select 150 ohm termination fro shielded TP (default), set high to select 100 ohm termination for unshielded TP. Cleared at reset.
+ // 0 RW Ethernet Normal Threshold (NTH) select. Set low to select the normal TP squelch threshold (default), high to reduce threshold by 4.5 dB (set low when reset).
+ return m_write_reg;
+
+ case INT3_LOCAL0_STATUS_REG:
+ return m_int3_local0_status_reg;
+
+ case INT3_LOCAL0_MASK_REG:
+ return m_int3_local0_mask_reg;
+
+ case INT3_LOCAL1_STATUS_REG:
+ return m_int3_local1_status_reg;
+
+ case INT3_LOCAL1_MASK_REG:
+ return m_int3_local1_mask_reg;
+
+ case INT3_MAP_STATUS_REG:
+ return m_int3_map_status_reg;
+
+ case INT3_MAP_MASK0_REG:
+ return m_int3_map_mask0_reg;
+
+ case INT3_MAP_MASK1_REG:
+ return m_int3_map_mask1_reg;
+
+ case INT3_MAP_POLARITY_REG:
+ return m_int3_map_pol_reg;
+
+ case INT3_TIMER_CLEAR_REG:
+ return m_int3_timer_clear_reg;
+
+ case INT3_ERROR_STATUS_REG:
+ return m_int3_err_status_reg;
+
+ case TIMER_COUNT0_REG:
+ case TIMER_COUNT1_REG:
+ case TIMER_COUNT2_REG:
+ case TIMER_CONTROL_REG:
+ return m_pit->read(space, offset - TIMER_COUNT0_REG);
+ }
+
+ return 0;
+}
+
+WRITE32_MEMBER( ioc2_device::write )
+{
+ switch (offset)
+ {
+ case PI1_DATA_REG:
+ case PI1_CTRL_REG:
+ case PI1_STATUS_REG:
+ m_pi1->write(space, offset, data & 0xff, 0xff);
+ return;
+
+ case PI1_DMA_CTRL_REG:
+ case PI1_INT_STATUS_REG:
+ case PI1_INT_MASK_REG:
+ case PI1_TIMER1_REG:
+ case PI1_TIMER2_REG:
+ case PI1_TIMER3_REG:
+ case PI1_TIMER4_REG:
+ return;
+
+ case SERIAL1_CMD_REG:
+ case SERIAL1_DATA_REG:
+ case SERIAL2_CMD_REG:
+ case SERIAL2_DATA_REG:
+ m_scc->ba_cd_w(space, (offset - SERIAL1_CMD_REG) ^ 3, data & 0xff);
+ return;
+
+ case KBD_MOUSE_REGS1:
+ case KBD_MOUSE_REGS2:
+ m_kbdc->data_w(space, (offset - KBD_MOUSE_REGS1) * 4, data & 0xff);
+ return;
+
+ case PANEL_REG:
+ m_front_panel_reg &= ~(data & (FRONT_PANEL_VOL_UP_INT | FRONT_PANEL_VOL_DOWN_INT | FRONT_PANEL_POWER_BUTTON_INT));
+ return;
+
+ case DMA_SEL_REG:
+ {
+ // Bits 2-0 not quite understood, seem to be copy/paste error in SGI's own documents:
+ //
+ // 5:4 RW Serial Port Clock Select: 00 selects a 10MHz internal clock (default), 01 selects a 6.67MHz internal clock, and 02 or 03 selects the external clock input.
+ // 2 RW Parallel Port DMA Select. A high bit selects the Parallel Port DMA channel. 0\h is the default after reset. [this makes sense. -ed.]
+ // 1 RW ISDN Channel B DMA Select. A high bit selects the Parallel Port DMA channel. 0\h is the default after reset. [is this a copy/paste error? perhaps "Parallel Port" should be "ISDN Channel B"?]
+ // 0 RW [same text as above. Another copy/paste error, maybe? Should be channel A, with the bit selecting DMA channel 0/1 for ISDN channel A, the and the same for ISDN channel B in bit 1?]
+ uint8_t old = m_dma_sel;
+ m_dma_sel = data;
+ uint8_t diff = old ^ m_dma_sel;
+ if (diff & DMA_SEL_CLOCK_SEL_MASK)
+ {
+ if (diff & DMA_SEL_CLOCK_SEL_EXT)
+ {
+ logerror("%s: External clock select %sselected\n", machine().describe_context(), (old & DMA_SEL_CLOCK_SEL_EXT) != 0 ? "de" : "");
+ // TODO: verify the external Rx/Tx clock, is it fixed or programmable?
+ }
+ }
+ // TODO: Currently we always assume a 10MHz clock as PCLK
+ return;
+ }
+
+ case RESET_REG:
+ handle_reset_reg_write(data);
+ return;
+
+ case WRITE_REG:
+ m_write_reg = data;
+ return;
+
+ case INT3_LOCAL0_STATUS_REG:
+ case INT3_LOCAL1_STATUS_REG:
+ case INT3_MAP_STATUS_REG:
+ case INT3_ERROR_STATUS_REG:
+ // Read-only registers
+ return;
+
+ case INT3_LOCAL0_MASK_REG:
+ {
+ uint8_t old = m_int3_local0_mask_reg;
+ m_int3_local0_mask_reg = data;
+ bool old_line = (old & m_int3_local0_status_reg) != 0;
+ bool new_line = (m_int3_local0_mask_reg & m_int3_local0_status_reg) != 0;
+ if (old_line != new_line)
+ {
+ const uint32_t int_bits = (m_int3_local1_mask_reg & m_int3_local1_status_reg) | (m_int3_local0_mask_reg & m_int3_local0_status_reg);
+ m_maincpu->set_input_line(MIPS3_IRQ0, int_bits != 0 ? ASSERT_LINE : CLEAR_LINE);
+ }
+ return;
+ }
+
+ case INT3_LOCAL1_MASK_REG:
+ {
+ uint8_t old = m_int3_local1_mask_reg;
+ m_int3_local1_mask_reg = data;
+ bool old_line = (old & m_int3_local1_status_reg) != 0;
+ bool new_line = (m_int3_local1_mask_reg & m_int3_local1_status_reg) != 0;
+ if (old_line != new_line)
+ {
+ const uint32_t int_bits = (m_int3_local1_mask_reg & m_int3_local1_status_reg) | (m_int3_local0_mask_reg & m_int3_local0_status_reg);
+ m_maincpu->set_input_line(MIPS3_IRQ0, int_bits != 0 ? ASSERT_LINE : CLEAR_LINE);
+ }
+ return;
+ }
+
+ case INT3_MAP_MASK0_REG:
+ // TODO: Implement mappable interrupts
+ m_int3_map_mask0_reg = data;
+ return;
+
+ case INT3_MAP_MASK1_REG:
+ // TODO: Implement mappable interrupts
+ m_int3_map_mask1_reg = data;
+ return;
+
+ case INT3_MAP_POLARITY_REG:
+ // TODO: Mappable interrupt polarity select
+ m_int3_map_pol_reg = data;
+ return;
+
+ case TIMER_COUNT0_REG:
+ case TIMER_COUNT1_REG:
+ case TIMER_COUNT2_REG:
+ case TIMER_CONTROL_REG:
+ m_pit->write(space, offset - TIMER_COUNT0_REG, data & 0xff);
+ return;
+ }
+}
+
+void ioc2_device::handle_reset_reg_write(uint8_t data)
+{
+ // guinness/fullhouse-specific implementations can handle bit 3 being used for ISDN reset on Indy only and bit 2 for EISA reset on Indigo 2 only, but for now we do nothing with it
+ m_reset_reg = data;
+}
+
+INPUT_CHANGED_MEMBER( ioc2_device::power_button )
+{
+ if (!newval)
+ {
+ m_front_panel_reg |= FRONT_PANEL_POWER_BUTTON_INT;
+ }
+}
+
+INPUT_CHANGED_MEMBER( ioc2_device::volume_up )
+{
+ if (!newval)
+ {
+ m_front_panel_reg |= FRONT_PANEL_VOL_UP_INT;
+ m_front_panel_reg |= FRONT_PANEL_VOL_UP_HOLD;
+ }
+ else
+ {
+ m_front_panel_reg &= ~FRONT_PANEL_VOL_UP_HOLD;
+ }
+}
+
+INPUT_CHANGED_MEMBER( ioc2_device::volume_down )
+{
+ if (!newval)
+ {
+ m_front_panel_reg |= FRONT_PANEL_VOL_DOWN_INT;
+ m_front_panel_reg |= FRONT_PANEL_VOL_DOWN_HOLD;
+ }
+ else
+ {
+ m_front_panel_reg &= ~FRONT_PANEL_VOL_DOWN_HOLD;
+ }
+}
diff --git a/src/mame/machine/ioc2.h b/src/mame/machine/ioc2.h
new file mode 100644
index 00000000000..94d5e8bd987
--- /dev/null
+++ b/src/mame/machine/ioc2.h
@@ -0,0 +1,215 @@
+// license:BSD-3-Clause
+// copyright-holders:Ryan Holtz
+/**********************************************************************
+
+ SGI IOC2 I/O Controller emulation
+
+**********************************************************************/
+
+#ifndef MAME_MACHINE_IOC2_H
+#define MAME_MACHINE_IOC2_H
+
+#pragma once
+
+#include "cpu/mips/mips3.h"
+#include "machine/8042kbdc.h"
+#include "machine/pc_lpt.h"
+#include "machine/pckeybrd.h"
+#include "machine/pit8253.h"
+#include "machine/z80scc.h"
+
+#define MCFG_IOC2_GUINNESS_ADD(_tag) \
+ MCFG_DEVICE_ADD(_tag, SGI_IOC2_GUINNESS, 0)
+
+#define MCFG_IOC2_FULL_HOUSE_ADD(_tag) \
+ MCFG_DEVICE_ADD(_tag, SGI_IOC2_FULL_HOUSE, 0)
+
+#define MCFG_IOC2_CPU(cpu_tag) \
+ downcast<ioc2_device &>(*device).set_cpu_tag(("^" cpu_tag));
+
+class ioc2_device : public device_t
+{
+public:
+ void set_cpu_tag(const char *tag) { m_maincpu.set_tag(tag); }
+
+ DECLARE_WRITE32_MEMBER( write );
+ DECLARE_READ32_MEMBER( read );
+
+ DECLARE_INPUT_CHANGED_MEMBER( power_button );
+ DECLARE_INPUT_CHANGED_MEMBER( volume_down );
+ DECLARE_INPUT_CHANGED_MEMBER( volume_up );
+
+ void lower_local0_irq(uint8_t source_mask);
+ void raise_local0_irq(uint8_t source_mask);
+ void lower_local1_irq(uint8_t source_mask);
+ void raise_local1_irq(uint8_t source_mask);
+
+ enum
+ {
+ INT3_LOCAL0_FIFO = 0x01,
+ INT3_LOCAL0_SCSI0 = 0x02,
+ INT3_LOCAL0_SCSI1 = 0x04,
+ INT3_LOCAL0_ETHERNET = 0x08,
+ INT3_LOCAL0_MC_DMA = 0x10,
+ INT3_LOCAL0_PARALLEL = 0x20,
+ INT3_LOCAL0_GRAPHICS = 0x40,
+ INT3_LOCAL0_MAPPABLE0 = 0x80,
+ };
+
+ enum
+ {
+ INT3_LOCAL1_GP0 = 0x01,
+ INT3_LOCAL1_PANEL = 0x02,
+ INT3_LOCAL1_GP2 = 0x04,
+ INT3_LOCAL1_MAPPABLE1 = 0x08,
+ INT3_LOCAL1_HPC_DMA = 0x10,
+ INT3_LOCAL1_AC_FAIL = 0x20,
+ INT3_LOCAL1_VSYNC = 0x40,
+ INT3_LOCAL1_RETRACE = 0x80,
+ };
+
+protected:
+ ioc2_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, uint8_t id);
+
+ virtual void device_start() override;
+ virtual void device_reset() override;
+ virtual void device_add_mconfig(machine_config &config) override;
+ virtual ioport_constructor device_input_ports() const override;
+
+ enum
+ {
+ PI1_DATA_REG = 0x00/4,
+ PI1_CTRL_REG = 0x04/4,
+ PI1_STATUS_REG = 0x08/4,
+ PI1_DMA_CTRL_REG = 0x0c/4,
+ PI1_INT_STATUS_REG = 0x10/4,
+ PI1_INT_MASK_REG = 0x14/4,
+ PI1_TIMER1_REG = 0x18/4,
+ PI1_TIMER2_REG = 0x1c/4,
+ PI1_TIMER3_REG = 0x20/4,
+ PI1_TIMER4_REG = 0x24/4,
+
+ SERIAL1_CMD_REG = 0x30/4,
+ SERIAL1_DATA_REG = 0x34/4,
+ SERIAL2_CMD_REG = 0x38/4,
+ SERIAL2_DATA_REG = 0x3c/4,
+
+ KBD_MOUSE_REGS1 = 0x40/4,
+ KBD_MOUSE_REGS2 = 0x44/4,
+
+ GENCTRL_SELECT_REG = 0x48/4,
+ GENCTRL_REG = 0x4c/4,
+
+ PANEL_REG = 0x50/4,
+ SYSID_REG = 0x58/4,
+ READ_REG = 0x60/4,
+ DMA_SEL_REG = 0x68/4,
+ RESET_REG = 0x70/4,
+ WRITE_REG = 0x78/4,
+
+ INT3_LOCAL0_STATUS_REG = 0x80/4,
+ INT3_LOCAL0_MASK_REG = 0x84/4,
+ INT3_LOCAL1_STATUS_REG = 0x88/4,
+ INT3_LOCAL1_MASK_REG = 0x8c/4,
+ INT3_MAP_STATUS_REG = 0x90/4,
+ INT3_MAP_MASK0_REG = 0x94/4,
+ INT3_MAP_MASK1_REG = 0x98/4,
+ INT3_MAP_POLARITY_REG = 0x9c/4,
+ INT3_TIMER_CLEAR_REG = 0xa0/4,
+ INT3_ERROR_STATUS_REG = 0xa4/4,
+
+ TIMER_COUNT0_REG = 0xb0/4,
+ TIMER_COUNT1_REG = 0xb4/4,
+ TIMER_COUNT2_REG = 0xb8/4,
+ TIMER_CONTROL_REG = 0xbc/4,
+ };
+
+ enum
+ {
+ FRONT_PANEL_POWER_STATE = 0x01,
+ FRONT_PANEL_POWER_BUTTON_INT = 0x02,
+ FRONT_PANEL_VOL_DOWN_INT = 0x10,
+ FRONT_PANEL_VOL_DOWN_HOLD = 0x20,
+ FRONT_PANEL_VOL_UP_INT = 0x40,
+ FRONT_PANEL_VOL_UP_HOLD = 0x80,
+ };
+
+ enum
+ {
+ DMA_SEL_CLOCK_SEL_MASK = 0x30,
+ DMA_SEL_CLOCK_SEL_10MHz = 0x00,
+ DMA_SEL_CLOCK_SEL_6_67MHz = 0x10,
+ DMA_SEL_CLOCK_SEL_EXT = 0x20,
+ };
+
+ required_device<mips3_device> m_maincpu;
+ required_device<scc85230_device> m_scc;
+ required_device<pc_lpt_device> m_pi1; // we assume standard parallel port (SPP) mode
+ // TODO: SGI parallel port (SGIPP), HP BOISE high speed parallel port (HPBPP), and Ricoh scanner modes
+ required_device<kbdc8042_device> m_kbdc;
+ required_device<pit8254_device> m_pit;
+
+ virtual void handle_reset_reg_write(uint8_t data);
+
+ uint8_t m_gen_ctrl_select_reg;
+ uint8_t m_gen_ctrl_reg;
+ uint8_t m_front_panel_reg;
+
+ uint8_t m_read_reg;
+ uint8_t m_dma_sel;
+ uint8_t m_reset_reg;
+ uint8_t m_write_reg;
+
+ uint8_t m_int3_local0_status_reg;
+ uint8_t m_int3_local0_mask_reg;
+ uint8_t m_int3_local1_status_reg;
+ uint8_t m_int3_local1_mask_reg;
+ uint8_t m_int3_map_status_reg;
+ uint8_t m_int3_map_mask0_reg;
+ uint8_t m_int3_map_mask1_reg;
+ uint8_t m_int3_map_pol_reg;
+ uint8_t m_int3_timer_clear_reg;
+ uint8_t m_int3_err_status_reg;
+
+ uint32_t m_par_read_cnt;
+ uint32_t m_par_cntl;
+ uint8_t m_system_id;
+
+ static const char *SCC_TAG;
+ static const char *PI1_TAG;
+ static const char *KBDC_TAG;
+ static const char *PIT_TAG;
+ static const char *RS232A_TAG;
+ static const char *RS232B_TAG;
+
+ static const XTAL SCC_PCLK;
+ static const XTAL SCC_RXA_CLK;
+ static const XTAL SCC_TXA_CLK;
+ static const XTAL SCC_RXB_CLK;
+ static const XTAL SCC_TXB_CLK;
+};
+
+class ioc2_guinness_device : public ioc2_device
+{
+public:
+ ioc2_guinness_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+protected:
+ ioc2_guinness_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
+ : ioc2_device(mconfig, type, tag, owner, clock, 0x01)
+ { }
+};
+
+class ioc2_full_house_device : public ioc2_device
+{
+public:
+ ioc2_full_house_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+protected:
+ ioc2_full_house_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
+ : ioc2_device(mconfig, type, tag, owner, clock, 0x20)
+ { }
+};
+
+DECLARE_DEVICE_TYPE(SGI_IOC2_GUINNESS, ioc2_guinness_device)
+DECLARE_DEVICE_TYPE(SGI_IOC2_FULL_HOUSE, ioc2_full_house_device)
+
+#endif // MAME_MACHINE_IOC2_H \ No newline at end of file
diff --git a/src/mame/mame.lst b/src/mame/mame.lst
index cdda452d544..afd81212871 100644
--- a/src/mame/mame.lst
+++ b/src/mame/mame.lst
@@ -15110,6 +15110,7 @@ hotstuff //
@source:hp_ipc.cpp
hp_ipc //
+hp9808a
@source:hp16500.cpp
hp16500b //
@@ -29809,6 +29810,7 @@ sdodgeb // 0208 (c) 1996 Technos
sengoku // 0017 (c) 1991 SNK
sengoku2 // 0040 (c) 1993 SNK
sengoku3 // 0261 (c) 2001 Noise Factory / SNK
+sengoku3a //
sengokuh // 0017 (c) 1991 SNK
shocktr2 // 0246 (c) 1998 Saurus
shocktro // 0238 (c) 1997 Saurus
@@ -29840,12 +29842,14 @@ twinspri // 0224 (c) 1996 ADK
twsoc96 // 0086 (c) 1996 Tecmo
viewpoin // 0051 (c) 1992 Sammy
vliner //
-vlinero //
+vliner6e //
+vliner54 //
wakuwak7 // 0225 (c) 1996 Sunsoft
wh1 // 0053 (c) 1992 Alpha Denshi Co.
wh1h // 0053 (c) 1992 Alpha Denshi Co.
wh1ha // 0053 (c) 1992 Alpha Denshi Co.
wh2 // 0057 (c) 1993 ADK
+wh2h //
wh2j // 0064 (c) 1994 ADK / SNK
whp // 0090 (c) 1995 ADK / SNK
wjammers // 0065 (c) 1994 Data East Corporation
diff --git a/src/mame/video/pc9801.cpp b/src/mame/video/pc9801.cpp
index b8b1fba704a..f3f0532cd3e 100644
--- a/src/mame/video/pc9801.cpp
+++ b/src/mame/video/pc9801.cpp
@@ -167,7 +167,7 @@ UPD7220_DRAW_TEXT_LINE_MEMBER( pc9801_state::hgdc_draw_text )
int res_x,res_y;
res_x = ((x+kanji_lr)*8+xi) * (m_video_ff[WIDTH40_REG]+1);
- res_y = y+yi - (m_txt_scroll_reg[3] & 0xf);
+ res_y = y+yi - (m_txt_scroll_reg[3] % 20);
if(!m_screen->visible_area().contains(res_x, res_y))
continue;