summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
author Patrick Mackinlay <pmackinlay@hotmail.com>2018-07-05 21:22:05 +0700
committer Olivier Galibert <galibert@pobox.com>2018-07-05 16:22:05 +0200
commit7bee6e6f1e9711558c7548dd895979bb9ffd81bc (patch)
tree5d41b9940a98689969b276923ada2cd7fe026694
parentd4e62756908f5d5553fff62b10e4017e97a3d1c5 (diff)
interpro: CLIX boots (on the ip2000) (#3730)
Too many changes to describe in detail. A rewrite of the interrupt and dma code in the ioga, and fixes to the cpu and mmu were the most important things.
-rw-r--r--src/devices/bus/interpro/keyboard/lle.cpp54
-rw-r--r--src/devices/bus/interpro/mouse/mouse.cpp2
-rw-r--r--src/devices/bus/interpro/sr/sr.cpp4
-rw-r--r--src/devices/bus/interpro/sr/sr.h5
-rw-r--r--src/devices/cpu/clipper/clipper.cpp98
-rw-r--r--src/devices/cpu/clipper/clipper.h28
-rw-r--r--src/devices/cpu/clipper/common.h2
-rw-r--r--src/mame/drivers/interpro.cpp496
-rw-r--r--src/mame/includes/interpro.h192
-rw-r--r--src/mame/machine/cammu.cpp89
-rw-r--r--src/mame/machine/cammu.h55
-rw-r--r--src/mame/machine/interpro_ioga.cpp873
-rw-r--r--src/mame/machine/interpro_ioga.h275
13 files changed, 1374 insertions, 799 deletions
diff --git a/src/devices/bus/interpro/keyboard/lle.cpp b/src/devices/bus/interpro/keyboard/lle.cpp
index e92e9a4d364..0bab0a00863 100644
--- a/src/devices/bus/interpro/keyboard/lle.cpp
+++ b/src/devices/bus/interpro/keyboard/lle.cpp
@@ -97,8 +97,8 @@
* relevant make/break codes that are then output via the serial interface.
*
* TODO
- * - upper matrix is not mapped
- * - arrow keys, keypad and some other keys are not mapped
+ * - upper matrix mapping
+ * - mappings for hold screen, superimpose, repeat
*/
/*
@@ -297,8 +297,8 @@ INPUT_PORTS_START(interpro_en_us)
PORT_START("lower.1")
// 0x08-0x0f: del 0xf5 0xab 2 w e t u
PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_DEL) PORT_NAME("Delete") PORT_CHAR(127)
- PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) // 0xf5
- PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) // 0xab
+ PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_F1) PORT_NAME("PF1") PORT_CHAR(UCHAR_MAMEKEY(F1))
+ PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_F4) PORT_NAME("PF4") PORT_CHAR(UCHAR_MAMEKEY(F4))
PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_2) PORT_CHAR('2') PORT_CHAR('@')
PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_W) PORT_CHAR('w') PORT_CHAR('W')
PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_E) PORT_CHAR('e') PORT_CHAR('E')
@@ -311,8 +311,8 @@ INPUT_PORTS_START(interpro_en_us)
PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_9) PORT_CHAR('9') PORT_CHAR('(')
PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_EQUALS) PORT_CHAR('=') PORT_CHAR('+')
PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_BACKSPACE) PORT_NAME("Backspace") PORT_CHAR(8)
- PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD) // 0xaf
- PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD) // 0xaa
+ PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_F2) PORT_NAME("PF2") PORT_CHAR(UCHAR_MAMEKEY(F2))
+ PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_F3) PORT_NAME("PF3") PORT_CHAR(UCHAR_MAMEKEY(F3))
PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_1) PORT_CHAR('1') PORT_CHAR('!')
PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_Q) PORT_CHAR('q') PORT_CHAR('Q')
@@ -325,11 +325,11 @@ INPUT_PORTS_START(interpro_en_us)
PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_P) PORT_CHAR('p') PORT_CHAR('P')
PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_CLOSEBRACE) PORT_CHAR(']') PORT_CHAR('}')
PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) // none - 0x1e never scanned?
- PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD) // 0xb7
+ PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_7_PAD) PORT_NAME("Keypad 7") PORT_CHAR(UCHAR_MAMEKEY(7_PAD))
PORT_START("lower.4")
// 0x20-0x27: 0xad ` tab s f j o '
- PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) // 0xad
+ PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_MINUS_PAD) PORT_NAME("Keypad -") PORT_CHAR(UCHAR_MAMEKEY(MINUS_PAD))
PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_TILDE) PORT_CHAR('`') PORT_CHAR('~')
PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_TAB) PORT_NAME("Tab") PORT_CHAR(9)
PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_S) PORT_CHAR('s') PORT_CHAR('S')
@@ -342,8 +342,8 @@ INPUT_PORTS_START(interpro_en_us)
// 0x28-0x2f: [ cr 0xb8 0xb9 none shift d g
PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_OPENBRACE) PORT_CHAR('[') PORT_CHAR('{')
PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_ENTER) PORT_NAME("Return") PORT_CHAR(13)
- PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) // 0xb8
- PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) // 0xb9
+ PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_8_PAD) PORT_NAME("Keypad 8") PORT_CHAR(UCHAR_MAMEKEY(8_PAD))
+ PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_9_PAD) PORT_NAME("Keypad 9") PORT_CHAR(UCHAR_MAMEKEY(9_PAD))
PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Alt Mode") PORT_TOGGLE
PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_CAPSLOCK) PORT_NAME("Caps Lock") PORT_TOGGLE PORT_CHAR(UCHAR_MAMEKEY(CAPSLOCK))
PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_D) PORT_CHAR('d') PORT_CHAR('D')
@@ -355,9 +355,9 @@ INPUT_PORTS_START(interpro_en_us)
PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_K) PORT_CHAR('k') PORT_CHAR('K')
PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_COLON) PORT_CHAR(';') PORT_CHAR(':')
PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_BACKSLASH) PORT_CHAR('\\') PORT_CHAR('|')
- PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD) // 0x85
- PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD) // 0xb4
- PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) // 0xac - superimpose?
+ PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_UP) PORT_NAME("Up") PORT_CHAR(UCHAR_MAMEKEY(UP))
+ PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_4_PAD) PORT_NAME("Keypad 4") PORT_CHAR(UCHAR_MAMEKEY(4_PAD))
+ PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_COMMA_PAD) PORT_NAME("Keypad ,") PORT_CHAR(UCHAR_MAMEKEY(COMMA_PAD))
PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_ESC) PORT_NAME("Esc") PORT_CHAR(27)
PORT_START("lower.7")
@@ -369,14 +369,14 @@ INPUT_PORTS_START(interpro_en_us)
PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_L) PORT_CHAR('l') PORT_CHAR('L')
PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_SLASH) PORT_CHAR('/') PORT_CHAR('?')
PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_RSHIFT) PORT_NAME("RShift") PORT_CHAR(UCHAR_MAMEKEY(RSHIFT))
- PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD) // 0xb1
+ PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_1_PAD) PORT_NAME("Keypad 1") PORT_CHAR(UCHAR_MAMEKEY(1_PAD))
PORT_START("lower.8")
// 0x40-0x47: 0xb5 0xb6 control 0x81 z c n .
- PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) // 0xb5
- PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) // 0xb6
- PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_LCONTROL) PORT_CODE(KEYCODE_RCONTROL)
- PORT_NAME("Control") PORT_CHAR(UCHAR_MAMEKEY(LCONTROL)) PORT_CHAR(UCHAR_MAMEKEY(RCONTROL))
+ PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_5_PAD) PORT_NAME("Keypad 5") PORT_CHAR(UCHAR_MAMEKEY(5_PAD))
+ PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_6_PAD) PORT_NAME("Keypad 6") PORT_CHAR(UCHAR_MAMEKEY(6_PAD))
+ PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_LCONTROL)
+ PORT_CODE(KEYCODE_RCONTROL) PORT_NAME("Control") PORT_CHAR(UCHAR_MAMEKEY(LCONTROL)) PORT_CHAR(UCHAR_MAMEKEY(RCONTROL))
PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) // 0x81
PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_Z) PORT_CHAR('z') PORT_CHAR('Z')
PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_C) PORT_CHAR('c') PORT_CHAR('C')
@@ -385,11 +385,11 @@ INPUT_PORTS_START(interpro_en_us)
PORT_START("lower.9")
// 0x48-0x4f: none 0x83 0x84 0xb2 0xb3 0x00 0x82 lf
- PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Repeat")
- PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) // 0x83
- PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) // 0x84
- PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) // 0xb2
- PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD) // 0xb3
+ PORT_BIT(0x01, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Repeat") // ?
+ PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_DOWN) PORT_NAME("Down") PORT_CHAR(UCHAR_MAMEKEY(DOWN))
+ PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_RIGHT) PORT_NAME("Right") PORT_CHAR(UCHAR_MAMEKEY(RIGHT))
+ PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_2_PAD) PORT_NAME("Keypad 2") PORT_CHAR(UCHAR_MAMEKEY(2_PAD))
+ PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_3_PAD) PORT_NAME("Keypad 3") PORT_CHAR(UCHAR_MAMEKEY(3_PAD))
PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD) // 0x00
PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) // 0x82
PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Line Feed") PORT_CHAR(10)
@@ -400,10 +400,10 @@ INPUT_PORTS_START(interpro_en_us)
PORT_BIT(0x02, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_M) PORT_CHAR('m') PORT_CHAR('M')
PORT_BIT(0x04, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_COMMA) PORT_CHAR(',')
PORT_BIT(0x08, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_SPACE) PORT_NAME("Space") PORT_CHAR(' ')
- PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD) // 0x80
- PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD) // 0xb0
- PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) // 0xae
- PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD) // 0x8d
+ PORT_BIT(0x10, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_LEFT) PORT_NAME("Left") PORT_CHAR(UCHAR_MAMEKEY(LEFT))
+ PORT_BIT(0x20, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_0_PAD) PORT_NAME("Keypad 0") PORT_CHAR(UCHAR_MAMEKEY(0_PAD))
+ PORT_BIT(0x40, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_NAME("Keypad .")
+ PORT_BIT(0x80, IP_ACTIVE_HIGH, IPT_KEYBOARD) PORT_CODE(KEYCODE_ENTER_PAD) PORT_NAME("Keypad Enter") PORT_CHAR(UCHAR_MAMEKEY(ENTER_PAD))
INPUT_PORTS_END
diff --git a/src/devices/bus/interpro/mouse/mouse.cpp b/src/devices/bus/interpro/mouse/mouse.cpp
index 92e9ea06ce1..8a97fe72027 100644
--- a/src/devices/bus/interpro/mouse/mouse.cpp
+++ b/src/devices/bus/interpro/mouse/mouse.cpp
@@ -96,7 +96,7 @@ INPUT_CHANGED_MEMBER(interpro_mouse_device::mouse_button)
{
const ioport_value data = field.port().read();
- LOG("mouse_button 0x%02x\n", data);
+ LOG("mouse_button 0x%08x\n", data);
state_w(machine().dummy_space(), 0, data & MOUSE_BUTTONS, MOUSE_BUTTONS);
}
diff --git a/src/devices/bus/interpro/sr/sr.cpp b/src/devices/bus/interpro/sr/sr.cpp
index bc566911ee3..e8efa39cbef 100644
--- a/src/devices/bus/interpro/sr/sr.cpp
+++ b/src/devices/bus/interpro/sr/sr.cpp
@@ -320,6 +320,10 @@ void cbus_device::device_start()
m_out_irq2_cb.resolve_safe();
m_out_vblank_cb.resolve_safe();
+ // FIXME: silence the slot address map
+ m_main_space->nop_read(CBUS_BASE, CBUS_BASE + (CBUS_STRIDE * (CBUS_COUNT - 1)) + (CBUS_SIZE - 1));
+ m_io_space->nop_read(CBUS_BASE, CBUS_BASE + (CBUS_STRIDE * (CBUS_COUNT - 1)) + (CBUS_SIZE - 1));
+
// empty the slots
m_slot_count = 0;
for (device_cbus_card_interface *&slot : m_slot)
diff --git a/src/devices/bus/interpro/sr/sr.h b/src/devices/bus/interpro/sr/sr.h
index cf987dc19e7..ec584f0b7db 100644
--- a/src/devices/bus/interpro/sr/sr.h
+++ b/src/devices/bus/interpro/sr/sr.h
@@ -85,7 +85,8 @@ public:
void set_memory(const char *const tag, const int main_spacenum, const int io_spacenum);
static const u32 CBUS_BASE = 0x87000000;
- static const u32 CBUS_SIZE = 0x08000000;
+ static const u32 CBUS_SIZE = 0x01000000;
+ static const u32 CBUS_STRIDE = 0x08000000;
static const int CBUS_COUNT = 16;
DECLARE_WRITE_LINE_MEMBER(irq0_w) { m_out_irq0_cb(state); }
@@ -100,7 +101,7 @@ public:
m_slot[m_slot_count] = &device;
// compute slot base address
- offs_t start = CBUS_BASE + m_slot_count * CBUS_SIZE;
+ offs_t start = CBUS_BASE + m_slot_count * CBUS_STRIDE;
offs_t end = start + (CBUS_SIZE - 1);
// install the device address map
diff --git a/src/devices/cpu/clipper/clipper.cpp b/src/devices/cpu/clipper/clipper.cpp
index d57e3f9ff02..adddfff71e5 100644
--- a/src/devices/cpu/clipper/clipper.cpp
+++ b/src/devices/cpu/clipper/clipper.cpp
@@ -20,8 +20,10 @@
#define LOG_GENERAL (1U << 0)
#define LOG_EXCEPTION (1U << 1)
+#define LOG_SYSCALLS (1U << 2)
//#define VERBOSE (LOG_GENERAL | LOG_EXCEPTION)
+#define VERBOSE (LOG_SYSCALLS)
#include "logmacro.h"
@@ -54,21 +56,21 @@ DEFINE_DEVICE_TYPE(CLIPPER_C300, clipper_c300_device, "clipper_c300", "C300 CLIP
DEFINE_DEVICE_TYPE(CLIPPER_C400, clipper_c400_device, "clipper_c400", "C400 CLIPPER")
clipper_c100_device::clipper_c100_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
- : clipper_device(mconfig, CLIPPER_C100, tag, owner, clock, ENDIANNESS_LITTLE, 0)
+ : clipper_device(mconfig, CLIPPER_C100, tag, owner, clock, ENDIANNESS_LITTLE, SSW_ID_C1R1)
, m_icammu(*this, "^cammu_i")
, m_dcammu(*this, "^cammu_d")
{
}
clipper_c300_device::clipper_c300_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
- : clipper_device(mconfig, CLIPPER_C300, tag, owner, clock, ENDIANNESS_LITTLE, 0)
+ : clipper_device(mconfig, CLIPPER_C300, tag, owner, clock, ENDIANNESS_LITTLE, SSW_ID_C3R1)
, m_icammu(*this, "^cammu_i")
, m_dcammu(*this, "^cammu_d")
{
}
clipper_c400_device::clipper_c400_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
- : clipper_device(mconfig, CLIPPER_C400, tag, owner, clock, ENDIANNESS_LITTLE, SSW_ID_C400R4)
+ : clipper_device(mconfig, CLIPPER_C400, tag, owner, clock, ENDIANNESS_LITTLE, SSW_ID_C4R4)
, m_cammu(*this, "^cammu")
{
}
@@ -113,7 +115,7 @@ inline u64 rotr64(u64 x, u8 shift)
void clipper_device::device_start()
{
// map spaces to system tags
- std::vector<address_space *> spaces = { &space(0), &space(0), &space(0), &space(0), &space(1), &space(2), nullptr, nullptr };
+ std::vector<address_space *> spaces = { &space(0), &space(0), &space(0), &space(0), &space(1), &space(2), &space(0), &machine().dummy_space() };
// configure the cammu address spaces
get_icammu().set_spaces(spaces);
@@ -141,7 +143,6 @@ void clipper_device::device_start()
state_add(STATE_GENPC, "GENPC", m_pc).noshow();
state_add(STATE_GENPCBASE, "CURPC", m_pc).noshow();
- state_add(STATE_GENSP, "GENSP", m_r[15]).noshow();
state_add(STATE_GENFLAGS, "GENFLAGS", m_psw).mask(0xf).formatstr("%4s").noshow();
state_add(CLIPPER_PC, "pc", m_pc);
@@ -150,7 +151,9 @@ void clipper_device::device_start()
// integer regsters
for (int i = 0; i < get_ireg_count(); i++)
- state_add(CLIPPER_IREG + i, util::string_format("r%d", i).c_str(), m_r[i]);
+ state_add(CLIPPER_UREG + i, util::string_format("ur%d", i).c_str(), m_ru[i]);
+ for (int i = 0; i < get_ireg_count(); i++)
+ state_add(CLIPPER_SREG + i, util::string_format("sr%d", i).c_str(), m_rs[i]);
// floating point registers
for (int i = 0; i < get_freg_count(); i++)
@@ -213,7 +216,7 @@ void clipper_device::execute_run()
}
else if (SSW(EI) && m_irq)
{
- LOGMASKED(LOG_EXCEPTION, "received prioritised interrupt ivec 0x%02x\n", m_ivec);
+ LOGMASKED(LOG_EXCEPTION, "prioritised interrupt vector 0x%02x\n", m_ivec);
// allow equal/higher priority interrupts
if ((m_ivec & IVEC_LEVEL) <= SSW(IL))
@@ -223,17 +226,20 @@ void clipper_device::execute_run()
m_pc = intrap(EXCEPTION_INTERRUPT_BASE + m_ivec * 8, m_pc);
- LOGMASKED(LOG_EXCEPTION, "transferring control to ivec 0x%02x address 0x%08x\n", m_ivec, m_pc);
+ LOGMASKED(LOG_EXCEPTION, "transferring control to vector 0x%02x address 0x%08x\n", m_ivec, m_pc);
}
}
- if (m_wait)
- m_icount = 0;
-
while (m_icount > 0)
{
debugger_instruction_hook(m_pc);
+ if (m_wait)
+ {
+ m_icount = 0;
+ continue;
+ }
+
// fetch and decode an instruction
if (decode_instruction())
{
@@ -249,6 +255,8 @@ void clipper_device::execute_run()
if (m_exception)
{
+ debugger_exception_hook(m_exception);
+
/*
* For traced instructions which are interrupted or cause traps, the TP
* flag is set by hardware when the interrupt or trap occurs to ensure
@@ -349,9 +357,11 @@ WRITE16_MEMBER(clipper_device::set_exception)
*/
bool clipper_device::decode_instruction()
{
+ // record the current instruction address
+ m_info.pc = m_pc;
+
// fetch and decode the primary parcel
if (!get_icammu().fetch<u16>(m_ssw, m_pc + 0, [this](u16 insn) {
- m_info.pc = m_pc;
m_info.opcode = insn >> 8;
m_info.subopcode = insn & 0xff;
m_info.r1 = (insn & 0x00f0) >> 4;
@@ -511,6 +521,14 @@ void clipper_device::execute_instruction()
case 0x12:
// calls: call supervisor
m_exception = EXCEPTION_SUPERVISOR_CALL_BASE + (m_info.subopcode & 0x7f) * 8;
+ if (VERBOSE & LOG_SYSCALLS)
+ switch (m_info.subopcode & 0x7f)
+ {
+ case 0x3b: // execve
+ LOGMASKED(LOG_SYSCALLS, "execve(\"%s\", [ %s ], envp)\n",
+ debug_string(m_r[0]), debug_string_array(m_r[1]));
+ break;
+ }
break;
case 0x13:
// ret: return from subroutine
@@ -522,8 +540,8 @@ void clipper_device::execute_instruction()
break;
case 0x14:
// pushw: push word
- if (get_dcammu().store<u32>(m_ssw, m_r[R1] - 4, m_r[R2]))
- m_r[R1] -= 4;
+ get_dcammu().store<u32>(m_ssw, m_r[R1] - 4, m_r[R2]);
+ m_r[R1] -= 4;
// TRAPS: A,P,W
break;
@@ -1500,8 +1518,6 @@ u32 clipper_device::intrap(const u16 vector, const u32 old_pc)
const u32 old_psw = m_psw;
u32 new_pc = 0, new_ssw = 0;
- debugger_exception_hook(vector);
-
// clear ssw bits to enable supervisor memory access
m_ssw &= ~(SSW_U | SSW_K | SSW_UU | SSW_KU);
@@ -1585,8 +1601,6 @@ u32 clipper_c400_device::intrap(const u16 vector, const u32 old_pc)
const u32 old_psw = m_psw;
u32 new_pc = 0, new_ssw = 0;
- debugger_exception_hook(vector);
-
// clear ssw bits to enable supervisor memory access
m_ssw &= ~(SSW_U | SSW_K | SSW_UU | SSW_KU);
@@ -1970,3 +1984,51 @@ std::unique_ptr<util::disasm_interface> clipper_device::create_disassembler()
{
return std::make_unique<clipper_disassembler>();
}
+
+std::string clipper_device::debug_string(u32 pointer)
+{
+ auto const suppressor(machine().disable_side_effects());
+
+ std::string s("");
+
+ while (true)
+ {
+ char c;
+
+ if (!get_dcammu().load<u8>(m_ssw, pointer++, [&c](u8 v) { c = v; }))
+ break;
+
+ if (c == '\0')
+ break;
+
+ s += c;
+ }
+
+ return s;
+}
+
+std::string clipper_device::debug_string_array(u32 array_pointer)
+{
+ auto const suppressor(machine().disable_side_effects());
+
+ std::string s("");
+
+ while (true)
+ {
+ u32 string_pointer;
+
+ if (!get_dcammu().load<u32>(m_ssw, array_pointer, [&string_pointer](u32 v) { string_pointer = v; }))
+ break;
+
+ if (string_pointer == 0)
+ break;
+
+ if (!s.empty())
+ s += ", ";
+
+ s += '\"' + debug_string(string_pointer) + '\"';
+ array_pointer += 4;
+ }
+
+ return s;
+}
diff --git a/src/devices/cpu/clipper/clipper.h b/src/devices/cpu/clipper/clipper.h
index 995ca53d7f7..d480100d509 100644
--- a/src/devices/cpu/clipper/clipper.h
+++ b/src/devices/cpu/clipper/clipper.h
@@ -94,11 +94,15 @@ public:
enum ssw_id : u32
{
- SSW_ID_C400R0 = 0x00800,
- SSW_ID_C400R1 = 0x04800,
- SSW_ID_C400R2 = 0x08800,
- SSW_ID_C400R3 = 0x0c800,
- SSW_ID_C400R4 = 0x10800
+ SSW_ID_C1R1 = 0x00000,
+ SSW_ID_C2R1 = 0x00200,
+ SSW_ID_C3R1 = 0x00400,
+ SSW_ID_E1R1 = 0x00600,
+ SSW_ID_C4R0 = 0x00800,
+ SSW_ID_C4R1 = 0x04800,
+ SSW_ID_C4R2 = 0x08800,
+ SSW_ID_C4R3 = 0x0c800,
+ SSW_ID_C4R4 = 0x10800
};
// trap source values are shifted into the correct field in the psw
@@ -265,6 +269,9 @@ protected:
m_ssw |= SSW_FRD;
};
+ std::string debug_string(u32 pointer);
+ std::string debug_string_array(u32 array_pointer);
+
// emulation state
address_space_config m_main_config;
address_space_config m_io_config;
@@ -272,11 +279,12 @@ protected:
enum registers
{
- CLIPPER_IREG = 0,
- CLIPPER_FREG = 16,
- CLIPPER_PSW = 32,
- CLIPPER_SSW = 33,
- CLIPPER_PC = 34,
+ CLIPPER_UREG = 0,
+ CLIPPER_SREG = 16,
+ CLIPPER_FREG = 32,
+ CLIPPER_PSW = 48,
+ CLIPPER_SSW = 49,
+ CLIPPER_PC = 50,
};
int m_icount; // instruction cycle count
diff --git a/src/devices/cpu/clipper/common.h b/src/devices/cpu/clipper/common.h
index 343e18c4913..ba3ef7bcd84 100644
--- a/src/devices/cpu/clipper/common.h
+++ b/src/devices/cpu/clipper/common.h
@@ -35,8 +35,6 @@ enum ssw_mask : u32
SSW_K = 0x20000000, // protect key
SSW_U = 0x40000000, // user mode
SSW_P = 0x80000000, // previous mode
-
- SSW_PL = 0x78000000 // protection level relevant bits
};
enum exception_vector : u16
diff --git a/src/mame/drivers/interpro.cpp b/src/mame/drivers/interpro.cpp
index bccd84dbc4d..43ff097bf93 100644
--- a/src/mame/drivers/interpro.cpp
+++ b/src/mame/drivers/interpro.cpp
@@ -241,27 +241,78 @@
void interpro_state::machine_start()
{
- m_led.resolve();
+ m_diag_led.resolve();
+ save_item(NAME(m_error));
+ save_item(NAME(m_status));
+ save_item(NAME(m_led));
+}
+
+void interpro_state::machine_reset()
+{
+ m_error = 0;
+ m_status = 0;
+ m_led = 0;
+}
+
+void emerald_state::machine_start()
+{
+ interpro_state::machine_start();
+
+ save_item(NAME(m_ctrl1));
+ save_item(NAME(m_ctrl2));
+
+ m_ctrl1 = 0;
// FIXME: disabled for now to avoid cold start diagnostic errors
- //m_sreg_ctrl2 = CTRL2_COLDSTART | CTRL2_PWRUP;
- m_sreg_ctrl2 = 0;
+ m_ctrl2 = 0; // CTRL2_COLDSTART
+}
- save_item(NAME(m_sreg_error));
- save_item(NAME(m_sreg_status));
- save_item(NAME(m_sreg_led));
- save_item(NAME(m_sreg_ctrl1));
- save_item(NAME(m_sreg_ctrl2));
+void turquoise_state::machine_start()
+{
+ interpro_state::machine_start();
+
+ save_item(NAME(m_ctrl1));
+ save_item(NAME(m_ctrl2));
- save_item(NAME(m_sreg_ctrl3));
+ m_ctrl1 = 0;
+ // FIXME: disabled for now to avoid cold start diagnostic errors
+ m_ctrl2 = 0; // CTRL2_COLDSTART
}
-void interpro_state::machine_reset()
+void sapphire_state::machine_start()
+{
+ interpro_state::machine_start();
+
+ save_item(NAME(m_ctrl1));
+ save_item(NAME(m_ctrl2));
+
+ m_ctrl1 = 0;
+ // FIXME: disabled for now to avoid cold start diagnostic errors
+ m_ctrl2 = 0; // CTRL2_COLDSTART
+}
+
+void emerald_state::machine_reset()
+{
+ interpro_state::machine_reset();
+
+ // deassert floppy ready
+ m_fdc->ready_w(true);
+}
+
+void turquoise_state::machine_reset()
+{
+ interpro_state::machine_reset();
+
+ // deassert floppy ready
+ m_fdc->ready_w(true);
+}
+
+void sapphire_state::machine_reset()
{
- // flash rom requires the following values
- m_sreg_error = 0;
- m_sreg_status = 0x400;
- m_sreg_ctrl1 = CTRL1_FLOPLOW;
+ interpro_state::machine_reset();
+
+ // flash rom requires the following
+ m_status = 0x400;
}
void interpro_state::init_common()
@@ -279,60 +330,149 @@ void interpro_state::init_common()
m_maincpu->space(0).install_ram(0, m_ram->mask(), m_ram->pointer());
}
-WRITE16_MEMBER(interpro_state::sreg_led_w)
+WRITE16_MEMBER(interpro_state::led_w)
{
// 7-segment decode patterns (hex digits) borrowed from wico.cpp (mc14495)
static const u8 patterns[16] = { 0x3f, 0x06, 0x5b, 0x4f, 0x66, 0x6d, 0x7d, 0x07, 0x7f, 0x6f, 0x77, 0x7c, 0x39, 0x5e, 0x79, 0x71 };
- m_led = patterns[data & 0xf];
+ m_diag_led = patterns[data & 0xf];
- COMBINE_DATA(&m_sreg_led);
+ COMBINE_DATA(&m_led);
}
-WRITE16_MEMBER(interpro_state::sreg_ctrl1_w)
+WRITE16_MEMBER(emerald_state::ctrl1_w)
{
LOG("control register 1 data 0x%04x mem_mask 0x%04x (%s)\n", data, mem_mask, machine().describe_context());
// check if led decimal point changes state
- if ((data ^ m_sreg_ctrl1) & CTRL1_LEDDP)
+ if ((data ^ m_ctrl1) & CTRL1_LEDDP)
m_led = (m_led + 0x80) & 0xff;
- COMBINE_DATA(&m_sreg_ctrl1);
+ // FIXME: select 3.5" or 5.25" floppy drive?
+ //if ((data ^ m_sreg_ctrl1) & CTRL1_FLOPLOW)
+ // logerror("floplow %d\n", data & CTRL1_FLOPLOW ? 1 : 0);
+
+ // FIXME: floppy ready line handling - this is strange but working
+ if (data & CTRL1_FLOPRDY)
+ m_fdc->ready_w(!(data & CTRL1_FLOPRDY));
+
+ COMBINE_DATA(&m_ctrl1);
+}
+
+WRITE16_MEMBER(turquoise_state::ctrl1_w)
+{
+ LOG("control register 1 data 0x%04x mem_mask 0x%04x (%s)\n", data, mem_mask, machine().describe_context());
+
+ // check if led decimal point changes state
+ if ((data ^ m_ctrl1) & CTRL1_LEDDP)
+ m_led = (m_led + 0x80) & 0xff;
+
+ // FIXME: select 3.5" or 5.25" floppy drive?
+ //if ((data ^ m_sreg_ctrl1) & CTRL1_FLOPLOW)
+ // logerror("floplow %d\n", data & CTRL1_FLOPLOW ? 1 : 0);
+
+ // FIXME: floppy ready line handling - this is strange but working
+ if (data & CTRL1_FLOPRDY)
+ m_fdc->ready_w(!(data & CTRL1_FLOPRDY));
+
+ COMBINE_DATA(&m_ctrl1);
+}
+
+WRITE16_MEMBER(sapphire_state::ctrl1_w)
+{
+ LOG("control register 1 data 0x%04x mem_mask 0x%04x (%s)\n", data, mem_mask, machine().describe_context());
+
+ // check if led decimal point changes state
+ if ((data ^ m_ctrl1) & CTRL1_LEDDP)
+ m_led = (m_led + 0x80) & 0xff;
+
+ // FIXME: select 3.5" or 5.25" floppy drive?
+ //if ((data ^ m_ctrl1) & CTRL1_FLOPLOW)
+ // logerror("floplow %d\n", data & CTRL1_FLOPLOW ? 1 : 0);
+
+ COMBINE_DATA(&m_ctrl1);
}
-WRITE16_MEMBER(interpro_state::sreg_ctrl2_w)
+WRITE16_MEMBER(emerald_state::ctrl2_w)
{
LOG("control register 2 data 0x%04x mem_mask 0x%04x (%s)\n", data, mem_mask, machine().describe_context());
if (data & CTRL2_RESET)
{
- m_sreg_ctrl2 &= ~CTRL2_COLDSTART;
+ m_ctrl2 &= ~CTRL2_COLDSTART;
machine().schedule_soft_reset();
}
else
- m_sreg_ctrl2 = (m_sreg_ctrl2 & ~CTRL2_MASK) | (data & CTRL2_MASK);
+ m_ctrl2 = (m_ctrl2 & ~CTRL2_WMASK) | (data & CTRL2_WMASK);
}
-WRITE16_MEMBER(sapphire_state::sreg_ctrl2_w)
+WRITE16_MEMBER(turquoise_state::ctrl2_w)
{
- interpro_state::sreg_ctrl2_w(space, offset, data, mem_mask);
+ LOG("control register 2 data 0x%04x mem_mask 0x%04x (%s)\n", data, mem_mask, machine().describe_context());
+ if (data & CTRL2_RESET)
+ {
+ m_ctrl2 &= ~CTRL2_COLDSTART;
+
+ machine().schedule_soft_reset();
+ }
+ else
+ m_ctrl2 = (m_ctrl2 & ~CTRL2_WMASK) | (data & CTRL2_WMASK);
+}
+
+WRITE16_MEMBER(sapphire_state::ctrl2_w)
+{
+ LOG("control register 2 data 0x%04x mem_mask 0x%04x (%s)\n", data, mem_mask, machine().describe_context());
+ if (data & CTRL2_RESET)
+ {
+ m_ctrl2 &= ~CTRL2_COLDSTART;
+
+ machine().schedule_soft_reset();
+ }
+ else
+ m_ctrl2 = (m_ctrl2 & ~0x4d) | (data & 0x4d);
// enable/disable programming power on both flash devices
- m_flash_lo->vpp(data & CTRL2_FLASHEN ? ASSERT_LINE : CLEAR_LINE);
- m_flash_hi->vpp(data & CTRL2_FLASHEN ? ASSERT_LINE : CLEAR_LINE);
+ m_flash_lsb->vpp(data & CTRL2_FLASHEN ? ASSERT_LINE : CLEAR_LINE);
+ m_flash_msb->vpp(data & CTRL2_FLASHEN ? ASSERT_LINE : CLEAR_LINE);
}
-READ16_MEMBER(interpro_state::sreg_error_r)
+READ16_MEMBER(interpro_state::error_r)
{
- const u16 result = m_sreg_error;
+ const u16 result = m_error;
// clear error register on read
if (!machine().side_effects_disabled())
- m_sreg_error = 0;
+ m_error = 0;
return result;
}
+READ32_MEMBER(interpro_state::unmapped_r)
+{
+ if (!machine().side_effects_disabled())
+ {
+ // flag non-existent memory error in system error register
+ m_error |= (ERROR_SRXNEM | ERROR_SRXVALID);
+
+ // tell ioga to raise a bus error
+ m_ioga->bus_error(space, interpro_ioga_device::BINFO_BERR | interpro_ioga_device::BINFO_SNAPOK, offset << 2);
+ }
+
+ return space.unmap();
+}
+
+WRITE32_MEMBER(interpro_state::unmapped_w)
+{
+ if (!machine().side_effects_disabled())
+ {
+ // flag non-existent memory error in system error register
+ m_error |= (ERROR_SRXNEM | ERROR_SRXVALID);
+
+ // tell ioga to raise a bus error
+ m_ioga->bus_error(space, interpro_ioga_device::BINFO_BERR | interpro_ioga_device::BINFO_SNAPOK, offset << 2);
+ }
+}
+
READ32_MEMBER(sapphire_state::unmapped_r)
{
// check if non-existent memory errors are enabled
@@ -340,7 +480,7 @@ READ32_MEMBER(sapphire_state::unmapped_r)
if (m_arbga->tctrl_r(space, offset, mem_mask) & interpro_arbga_device::TCTRL_ENNEM)
{
// flag non-existent memory error in system error register
- m_sreg_error |= (ERROR_SRXNEM | ERROR_SRXVALID);
+ m_error |= (ERROR_SRXNEM | ERROR_SRXVALID);
// tell ioga to raise a bus error
m_ioga->bus_error(space, interpro_ioga_device::BINFO_BERR | interpro_ioga_device::BINFO_SNAPOK, offset << 2);
@@ -355,7 +495,7 @@ WRITE32_MEMBER(sapphire_state::unmapped_w)
if (m_arbga->tctrl_r(space, offset, mem_mask) & interpro_arbga_device::TCTRL_ENNEM)
{
// flag non-existent memory error in system error register
- m_sreg_error |= (ERROR_SRXNEM | ERROR_SRXVALID);
+ m_error |= (ERROR_SRXNEM | ERROR_SRXVALID);
// tell ioga to raise a bus error
m_ioga->bus_error(space, interpro_ioga_device::BINFO_BERR | interpro_ioga_device::BINFO_SNAPOK, offset << 2);
@@ -379,18 +519,18 @@ READ8_MEMBER(interpro_state::nodeid_r)
void interpro_state::interpro_common_map(address_map &map)
{
+ //map(0x00000000, 0xffffffff).rw(FUNC(interpro_state::unmapped_r), FUNC(interpro_state::unmapped_w));
+
// FIXME: don't know what this range is for
map(0x08000000, 0x08000fff).noprw();
map(0x4f007e00, 0x4f007eff).m(m_sga, FUNC(interpro_sga_device::map));
map(0x7f000100, 0x7f00011f).m(m_fdc, FUNC(upd765_family_device::map)).umask32(0x000000ff);
- map(0x7f000300, 0x7f000301).r(FUNC(interpro_state::sreg_error_r));
- map(0x7f000304, 0x7f000305).rw(FUNC(interpro_state::sreg_status_r), FUNC(interpro_state::sreg_led_w));
- map(0x7f000308, 0x7f000309).rw(FUNC(interpro_state::sreg_ctrl1_r), FUNC(interpro_state::sreg_ctrl1_w));
- map(0x7f00030c, 0x7f00030d).rw(FUNC(interpro_state::sreg_ctrl2_r), FUNC(interpro_state::sreg_ctrl2_w));
-
- map(0x7f00031c, 0x7f00031d).rw(FUNC(interpro_state::sreg_ctrl3_r), FUNC(interpro_state::sreg_ctrl3_w));
+ map(0x7f000300, 0x7f000301).r(FUNC(interpro_state::error_r));
+ map(0x7f000304, 0x7f000305).rw(FUNC(interpro_state::status_r), FUNC(interpro_state::led_w));
+ map(0x7f000308, 0x7f000309).rw(FUNC(interpro_state::ctrl1_r), FUNC(interpro_state::ctrl1_w));
+ map(0x7f00030c, 0x7f00030d).rw(FUNC(interpro_state::ctrl2_r), FUNC(interpro_state::ctrl2_w));
map(0x7f000400, 0x7f00040f).rw(m_scc1, FUNC(z80scc_device::ba_cd_inv_r), FUNC(z80scc_device::ba_cd_inv_w)).umask32(0x000000ff);
map(0x7f000410, 0x7f00041f).rw(m_scc2, FUNC(z80scc_device::ba_cd_inv_r), FUNC(z80scc_device::ba_cd_inv_w)).umask32(0x000000ff);
@@ -429,13 +569,15 @@ void emerald_state::emerald_base_map(address_map &map)
map(0x7f000229, 0x7f000229).w(m_scsi, FUNC(ncr53c90a_device::test_w));
map(0x7f00022d, 0x7f00022d).rw(m_scsi, FUNC(ncr53c90a_device::conf2_r), FUNC(ncr53c90a_device::conf2_w));
- map(0x7f000300, 0x7f000300).w(FUNC(emerald_state::sreg_error_w));
+ map(0x7f000300, 0x7f000300).w(FUNC(emerald_state::error_w));
map(0x7f000600, 0x7f00067f).rom().region(INTERPRO_NODEID_TAG, 0);
}
void emerald_state::emerald_main_map(address_map &map)
{
+ //map(0x00000000, 0xffffffff).rw(FUNC(interpro_state::unmapped_r), FUNC(interpro_state::unmapped_w));
+
emerald_base_map(map);
map(0x00000000, 0x00ffffff).ram().share(RAM_TAG);
@@ -462,13 +604,15 @@ void turquoise_state::turquoise_base_map(address_map &map)
map(0x7f000229, 0x7f000229).w(m_scsi, FUNC(ncr53c90a_device::test_w));
map(0x7f00022d, 0x7f00022d).rw(m_scsi, FUNC(ncr53c90a_device::conf2_r), FUNC(ncr53c90a_device::conf2_w));
- map(0x7f000300, 0x7f000300).w(FUNC(turquoise_state::sreg_error_w));
+ map(0x7f000300, 0x7f000300).w(FUNC(turquoise_state::error_w));
map(0x7f000600, 0x7f00067f).rom().region(INTERPRO_NODEID_TAG, 0);
}
void turquoise_state::turquoise_main_map(address_map &map)
{
+ //map(0x00000000, 0xffffffff).rw(FUNC(interpro_state::unmapped_r), FUNC(interpro_state::unmapped_w));
+
turquoise_base_map(map);
map(0x00000000, 0x00ffffff).ram().share(RAM_TAG);
@@ -479,7 +623,7 @@ void sapphire_state::sapphire_base_map(address_map &map)
{
interpro_common_map(map);
- map(0x40000000, 0x4000004f).m(INTERPRO_MCGA_TAG, FUNC(interpro_fmcc_device::map));
+ map(0x40000000, 0x4000004f).m(m_mcga, FUNC(interpro_fmcc_device::map));
map(0x7f000200, 0x7f0002ff).m(m_arbga, FUNC(interpro_arbga_device::map));
map(0x7f000600, 0x7f00060f).r(FUNC(sapphire_state::nodeid_r)).umask32(0x000000ff);
@@ -509,8 +653,8 @@ void sapphire_state::sapphire_main_map(address_map &map)
map(0x00000000, 0x00ffffff).ram().share(RAM_TAG);
map(0x7f100000, 0x7f11ffff).rom().region(INTERPRO_EPROM_TAG, 0);
- map(0x7f180000, 0x7f1fffff).rw(INTERPRO_FLASH_TAG "_lo", FUNC(intel_28f010_device::read), FUNC(intel_28f010_device::write)).umask32(0x00ff00ff).mask(0x3ffff);
- map(0x7f180000, 0x7f1fffff).rw(INTERPRO_FLASH_TAG "_hi", FUNC(intel_28f010_device::read), FUNC(intel_28f010_device::write)).umask32(0xff00ff00).mask(0x3ffff);
+ map(0x7f180000, 0x7f1fffff).rw(m_flash_lsb, FUNC(intel_28f010_device::read), FUNC(intel_28f010_device::write)).umask32(0x00ff00ff).mask(0x3ffff);
+ map(0x7f180000, 0x7f1fffff).rw(m_flash_msb, FUNC(intel_28f010_device::read), FUNC(intel_28f010_device::write)).umask32(0xff00ff00).mask(0x3ffff);
// HACK: for SRX bus Sapphire only
//map(0x8f007f80, 0x8f007fff).rom().region(INTERPRO_IDPROM_TAG, 0);
@@ -520,24 +664,22 @@ void emerald_state::emerald_io_map(address_map &map)
{
emerald_base_map(map);
- map(0x00000800, 0x000009ff).m(INTERPRO_MMU_TAG "_d", FUNC(cammu_c3_device::map));
- map(0x00000a00, 0x00000bff).m(INTERPRO_MMU_TAG "_i", FUNC(cammu_c3_device::map));
- map(0x00000c00, 0x00000dff).m(INTERPRO_MMU_TAG "_d", FUNC(cammu_c3_device::map_global));
+ map(0x00000800, 0x000009ff).m(m_d_cammu, FUNC(cammu_c3_device::map));
+ map(0x00000a00, 0x00000bff).m(m_i_cammu, FUNC(cammu_c3_device::map));
+ map(0x00000c00, 0x00000dff).m(m_d_cammu, FUNC(cammu_c3_device::map_global));
}
void turquoise_state::turquoise_io_map(address_map &map)
{
turquoise_base_map(map);
- map(0x00000800, 0x000009ff).m(INTERPRO_MMU_TAG "_d", FUNC(cammu_c3_device::map));
- map(0x00000a00, 0x00000bff).m(INTERPRO_MMU_TAG "_i", FUNC(cammu_c3_device::map));
- map(0x00000c00, 0x00000dff).m(INTERPRO_MMU_TAG "_d", FUNC(cammu_c3_device::map_global));
+ map(0x00000800, 0x000009ff).m(m_d_cammu, FUNC(cammu_c3_device::map));
+ map(0x00000a00, 0x00000bff).m(m_i_cammu, FUNC(cammu_c3_device::map));
+ map(0x00000c00, 0x00000dff).m(m_d_cammu, FUNC(cammu_c3_device::map_global));
}
void sapphire_state::sapphire_io_map(address_map &map)
{
- //map(0x00000000, 0xffffffff).rw(FUNC(sapphire_state::unmapped_r), FUNC(sapphire_state::unmapped_w));
-
sapphire_base_map(map);
map(0x00000000, 0x00001fff).m(m_mmu, FUNC(cammu_c4_device::map));
@@ -554,17 +696,17 @@ void interpro_state::interpro_boot_map(address_map &map)
void emerald_state::interpro_82586_map(address_map &map)
{
- map(0x00000000, 0x00ffffff).rw(INTERPRO_IOGA_TAG, FUNC(turquoise_ioga_device::eth_r), FUNC(turquoise_ioga_device::eth_w));
+ map(0x00000000, 0x00ffffff).rw(m_ioga, FUNC(emerald_ioga_device::eth_r), FUNC(emerald_ioga_device::eth_w));
}
void turquoise_state::interpro_82586_map(address_map &map)
{
- map(0x00000000, 0x00ffffff).rw(INTERPRO_IOGA_TAG, FUNC(turquoise_ioga_device::eth_r), FUNC(turquoise_ioga_device::eth_w));
+ map(0x00000000, 0x00ffffff).rw(m_ioga, FUNC(turquoise_ioga_device::eth_r), FUNC(turquoise_ioga_device::eth_w));
}
void sapphire_state::interpro_82596_map(address_map &map)
{
- map(0x00000000, 0xffffffff).rw(INTERPRO_IOGA_TAG, FUNC(sapphire_ioga_device::eth_r), FUNC(sapphire_ioga_device::eth_w));
+ map(0x00000000, 0xffffffff).rw(m_ioga, FUNC(sapphire_ioga_device::eth_r), FUNC(sapphire_ioga_device::eth_w));
}
FLOPPY_FORMATS_MEMBER(interpro_state::floppy_formats)
@@ -581,35 +723,35 @@ MACHINE_CONFIG_START(interpro_state::interpro_scc1)
MCFG_DEVICE_MODIFY(INTERPRO_SCC1_TAG)
MCFG_Z80SCC_OUT_TXDA_CB(WRITELINE(INTERPRO_SERIAL_PORT1_TAG, rs232_port_device, write_txd))
MCFG_Z80SCC_OUT_TXDB_CB(WRITELINE(INTERPRO_SERIAL_PORT2_TAG, rs232_port_device, write_txd))
- MCFG_Z80SCC_OUT_INT_CB(WRITELINE(INTERPRO_IOGA_TAG, interpro_ioga_device, ir11_w))
- MCFG_Z80SCC_OUT_WREQA_CB(WRITELINE(INTERPRO_IOGA_TAG, interpro_ioga_device, drq_serial1))
- MCFG_Z80SCC_OUT_WREQB_CB(WRITELINE(INTERPRO_IOGA_TAG, interpro_ioga_device, drq_serial2))
+ MCFG_Z80SCC_OUT_INT_CB(WRITELINE(m_ioga, interpro_ioga_device, ir11_w))
+ MCFG_Z80SCC_OUT_WREQA_CB(WRITELINE(m_ioga, interpro_ioga_device, drq_serial1))
+ MCFG_Z80SCC_OUT_WREQB_CB(WRITELINE(m_ioga, interpro_ioga_device, drq_serial2))
MCFG_DEVICE_ADD(INTERPRO_SERIAL_PORT1_TAG, RS232_PORT, default_rs232_devices, nullptr)
- MCFG_RS232_RXD_HANDLER(WRITELINE(INTERPRO_SCC1_TAG, z80scc_device, rxa_w))
- MCFG_RS232_DCD_HANDLER(WRITELINE(INTERPRO_SCC1_TAG, z80scc_device, dcda_w))
- MCFG_RS232_CTS_HANDLER(WRITELINE(INTERPRO_SCC1_TAG, z80scc_device, ctsa_w))
+ MCFG_RS232_RXD_HANDLER(WRITELINE(m_scc1, z80scc_device, rxa_w))
+ MCFG_RS232_DCD_HANDLER(WRITELINE(m_scc1, z80scc_device, dcda_w))
+ MCFG_RS232_CTS_HANDLER(WRITELINE(m_scc1, z80scc_device, ctsa_w))
MCFG_DEVICE_ADD(INTERPRO_SERIAL_PORT2_TAG, RS232_PORT, default_rs232_devices, nullptr)
- MCFG_RS232_RXD_HANDLER(WRITELINE(INTERPRO_SCC1_TAG, z80scc_device, rxb_w))
- MCFG_RS232_DCD_HANDLER(WRITELINE(INTERPRO_SCC1_TAG, z80scc_device, dcdb_w))
- MCFG_RS232_CTS_HANDLER(WRITELINE(INTERPRO_SCC1_TAG, z80scc_device, ctsb_w))
+ MCFG_RS232_RXD_HANDLER(WRITELINE(m_scc1, z80scc_device, rxb_w))
+ MCFG_RS232_DCD_HANDLER(WRITELINE(m_scc1, z80scc_device, dcdb_w))
+ MCFG_RS232_CTS_HANDLER(WRITELINE(m_scc1, z80scc_device, ctsb_w))
MACHINE_CONFIG_END
MACHINE_CONFIG_START(interpro_state::interpro_scc2)
MCFG_DEVICE_MODIFY(INTERPRO_SCC2_TAG)
MCFG_Z80SCC_OUT_TXDA_CB(WRITELINE(INTERPRO_KEYBOARD_PORT_TAG, interpro_keyboard_port_device, write_txd))
MCFG_Z80SCC_OUT_TXDB_CB(WRITELINE(INTERPRO_SERIAL_PORT0_TAG, rs232_port_device, write_txd))
- MCFG_Z80SCC_OUT_INT_CB(WRITELINE(INTERPRO_IOGA_TAG, interpro_ioga_device, ir11_w))
- MCFG_Z80SCC_OUT_WREQB_CB(WRITELINE(INTERPRO_IOGA_TAG, interpro_ioga_device, drq_serial0))
+ MCFG_Z80SCC_OUT_INT_CB(WRITELINE(m_ioga, interpro_ioga_device, ir11_w))
+ MCFG_Z80SCC_OUT_WREQB_CB(WRITELINE(m_ioga, interpro_ioga_device, drq_serial0))
MCFG_INTERPRO_KEYBOARD_PORT_ADD(INTERPRO_KEYBOARD_PORT_TAG, interpro_keyboard_devices, "lle_en_us")
- MCFG_INTERPRO_KEYBOARD_RXD_HANDLER(WRITELINE(INTERPRO_SCC2_TAG, z80scc_device, rxa_w))
+ MCFG_INTERPRO_KEYBOARD_RXD_HANDLER(WRITELINE(m_scc2, z80scc_device, rxa_w))
MCFG_DEVICE_ADD(INTERPRO_SERIAL_PORT0_TAG, RS232_PORT, default_rs232_devices, nullptr)
- MCFG_RS232_RXD_HANDLER(WRITELINE(INTERPRO_SCC2_TAG, z80scc_device, rxb_w))
- MCFG_RS232_DCD_HANDLER(WRITELINE(INTERPRO_SCC2_TAG, z80scc_device, dcdb_w))
- MCFG_RS232_CTS_HANDLER(WRITELINE(INTERPRO_SCC2_TAG, z80scc_device, ctsb_w))
+ MCFG_RS232_RXD_HANDLER(WRITELINE(m_scc2, z80scc_device, rxb_w))
+ MCFG_RS232_DCD_HANDLER(WRITELINE(m_scc2, z80scc_device, dcdb_w))
+ MCFG_RS232_CTS_HANDLER(WRITELINE(m_scc2, z80scc_device, ctsb_w))
MACHINE_CONFIG_END
static void interpro_scsi_devices(device_slot_interface &device)
@@ -642,24 +784,29 @@ void interpro_state::interpro_scsi_adapter(device_t *device)
MCFG_NCR5390_DRQ_HANDLER(WRITELINE(":" INTERPRO_IOGA_TAG, interpro_ioga_device, drq_scsi))
}
+void interpro_state::interpro_cdrom(device_t *device)
+{
+ // FIXME: enable when dependent code is committed
+ //downcast<nscsi_cdrom_device &>(*device).set_block_size(512);
+}
+
MACHINE_CONFIG_START(interpro_state::ioga)
MCFG_DEVICE_MODIFY(INTERPRO_IOGA_TAG)
- MCFG_INTERPRO_IOGA_NMI_CB(INPUTLINE(INTERPRO_CPU_TAG, INPUT_LINE_NMI))
- MCFG_INTERPRO_IOGA_IRQ_CB(INPUTLINE(INTERPRO_CPU_TAG, INPUT_LINE_IRQ0))
- MCFG_INTERPRO_IOGA_IVEC_CB(WRITE8(INTERPRO_CPU_TAG, clipper_device, set_ivec))
+ MCFG_INTERPRO_IOGA_NMI_CB(INPUTLINE(m_maincpu, INPUT_LINE_NMI))
+ MCFG_INTERPRO_IOGA_IRQ_CB(INPUTLINE(m_maincpu, INPUT_LINE_IRQ0))
+ MCFG_INTERPRO_IOGA_IVEC_CB(WRITE8(m_maincpu, clipper_device, set_ivec))
// ioga dma and serial dma channels
- // TODO: check serial dma channels - scc2chanA (keyboard) has no dma
//MCFG_INTERPRO_IOGA_DMA_CB(0, unknown) // plotter
MCFG_INTERPRO_IOGA_DMA_CB(1, READ8(INTERPRO_SCSI_DEVICE_TAG, ncr53c90a_device, mdma_r), WRITE8(INTERPRO_SCSI_DEVICE_TAG, ncr53c90a_device, mdma_w))
- MCFG_INTERPRO_IOGA_DMA_CB(2, READ8(INTERPRO_FDC_TAG, upd765_family_device, mdma_r), WRITE8(INTERPRO_FDC_TAG, upd765_family_device, mdma_w))
- MCFG_INTERPRO_IOGA_SERIAL_DMA_CB(0, READ8(INTERPRO_SCC2_TAG, z80scc_device, db_r), WRITE8(INTERPRO_SCC2_TAG, z80scc_device, db_w))
- MCFG_INTERPRO_IOGA_SERIAL_DMA_CB(1, READ8(INTERPRO_SCC1_TAG, z80scc_device, da_r), WRITE8(INTERPRO_SCC1_TAG, z80scc_device, da_w))
- MCFG_INTERPRO_IOGA_SERIAL_DMA_CB(2, READ8(INTERPRO_SCC1_TAG, z80scc_device, db_r), WRITE8(INTERPRO_SCC1_TAG, z80scc_device, db_w))
+ MCFG_INTERPRO_IOGA_DMA_CB(2, READ8(m_fdc, upd765_family_device, mdma_r), WRITE8(m_fdc, upd765_family_device, mdma_w))
+ MCFG_INTERPRO_IOGA_SERIAL_DMA_CB(0, READ8(m_scc2, z80scc_device, db_r), WRITE8(m_scc2, z80scc_device, db_w))
+ MCFG_INTERPRO_IOGA_SERIAL_DMA_CB(1, READ8(m_scc1, z80scc_device, da_r), WRITE8(m_scc1, z80scc_device, da_w))
+ MCFG_INTERPRO_IOGA_SERIAL_DMA_CB(2, READ8(m_scc1, z80scc_device, db_r), WRITE8(m_scc1, z80scc_device, db_w))
// ioga floppy terminal count, ethernet channel attention
- MCFG_INTERPRO_IOGA_FDCTC_CB(WRITELINE(INTERPRO_FDC_TAG, upd765_family_device, tc_line_w))
- MCFG_INTERPRO_IOGA_ETH_CA_CB(WRITELINE(INTERPRO_ETH_TAG, i82586_base_device, ca))
+ MCFG_INTERPRO_IOGA_FDCTC_CB(WRITELINE(m_fdc, upd765_family_device, tc_line_w))
+ MCFG_INTERPRO_IOGA_ETH_CA_CB(WRITELINE(m_eth, i82586_base_device, ca))
MACHINE_CONFIG_END
static INPUT_PORTS_START(interpro)
@@ -673,25 +820,26 @@ MACHINE_CONFIG_START(interpro_state::interpro)
// memory control gate array
// srx gate array
- MCFG_DEVICE_ADD(INTERPRO_SGA_TAG, INTERPRO_SGA, 0)
- MCFG_INTERPRO_SGA_BERR_CB(WRITE32(INTERPRO_IOGA_TAG, interpro_ioga_device, bus_error))
+ MCFG_DEVICE_ADD(m_sga, INTERPRO_SGA, 0)
+ MCFG_INTERPRO_SGA_BERR_CB(WRITE32(m_ioga, interpro_ioga_device, bus_error))
// floppy
// serial
// real-time clock/non-volatile memory
- MCFG_DEVICE_ADD(INTERPRO_RTC_TAG, MC146818, 32.768_kHz_XTAL)
+ MCFG_DEVICE_ADD(m_rtc, MC146818, 32.768_kHz_XTAL)
MCFG_MC146818_UTC(true)
- MCFG_MC146818_IRQ_HANDLER(WRITELINE(INTERPRO_IOGA_TAG, interpro_ioga_device, ir9_w))
+ MCFG_MC146818_IRQ_HANDLER(WRITELINE(m_ioga, interpro_ioga_device, ir9_w))
// scsi
- MCFG_NSCSI_BUS_ADD(INTERPRO_SCSI_TAG)
+ MCFG_DEVICE_ADD(m_scsibus, NSCSI_BUS, 0)
MCFG_NSCSI_ADD(INTERPRO_SCSI_TAG ":0", interpro_scsi_devices, "harddisk", false)
MCFG_NSCSI_ADD(INTERPRO_SCSI_TAG ":1", interpro_scsi_devices, nullptr, false)
MCFG_NSCSI_ADD(INTERPRO_SCSI_TAG ":2", interpro_scsi_devices, nullptr, false)
MCFG_NSCSI_ADD(INTERPRO_SCSI_TAG ":3", interpro_scsi_devices, nullptr, false)
MCFG_NSCSI_ADD(INTERPRO_SCSI_TAG ":4", interpro_scsi_devices, "cdrom", false)
+ MCFG_SLOT_OPTION_MACHINE_CONFIG("cdrom", interpro_cdrom)
MCFG_NSCSI_ADD(INTERPRO_SCSI_TAG ":5", interpro_scsi_devices, nullptr, false)
MCFG_NSCSI_ADD(INTERPRO_SCSI_TAG ":6", interpro_scsi_devices, nullptr, false)
@@ -702,7 +850,7 @@ MACHINE_CONFIG_START(interpro_state::interpro)
// mouse
MCFG_DEVICE_ADD(INTERPRO_MOUSE_PORT_TAG, INTERPRO_MOUSE_PORT, 0)
MCFG_DEVICE_SLOT_INTERFACE(interpro_mouse_devices, "interpro_mouse", false)
- MCFG_MOUSE_STATE_CB(WRITE32(INTERPRO_IOGA_TAG, interpro_ioga_device, mouse_status_w))
+ MCFG_MOUSE_STATE_CB(WRITE32(m_ioga, interpro_ioga_device, mouse_status_w))
// system layout
MCFG_DEFAULT_LAYOUT(layout_interpro)
@@ -714,17 +862,17 @@ MACHINE_CONFIG_END
MACHINE_CONFIG_START(emerald_state::emerald)
interpro(config);
- MCFG_DEVICE_ADD(INTERPRO_CPU_TAG, CLIPPER_C300, 12.5_MHz_XTAL)
+ MCFG_DEVICE_ADD(m_maincpu, CLIPPER_C300, 12.5_MHz_XTAL)
MCFG_DEVICE_ADDRESS_MAP(0, emerald_main_map)
MCFG_DEVICE_ADDRESS_MAP(1, emerald_io_map)
MCFG_DEVICE_ADDRESS_MAP(2, interpro_boot_map)
MCFG_DEVICE_IRQ_ACKNOWLEDGE_DEVICE(INTERPRO_IOGA_TAG, interpro_ioga_device, acknowledge_interrupt)
- MCFG_DEVICE_ADD(INTERPRO_MMU_TAG "_i", CAMMU_C3, 0)
- MCFG_CAMMU_EXCEPTION_CB(WRITE16(INTERPRO_CPU_TAG, clipper_device, set_exception))
+ MCFG_DEVICE_ADD(m_i_cammu, CAMMU_C3, 0)
+ MCFG_CAMMU_EXCEPTION_CB(WRITE16(m_maincpu, clipper_device, set_exception))
- MCFG_DEVICE_ADD(INTERPRO_MMU_TAG "_d", CAMMU_C3, 0)
- MCFG_CAMMU_EXCEPTION_CB(WRITE16(INTERPRO_CPU_TAG, clipper_device, set_exception))
+ MCFG_DEVICE_ADD(m_d_cammu, CAMMU_C3, 0)
+ MCFG_CAMMU_EXCEPTION_CB(WRITE16(m_maincpu, clipper_device, set_exception))
MCFG_CAMMU_LINK(INTERPRO_MMU_TAG "_i")
// boot fails memory test without this
@@ -732,25 +880,22 @@ MACHINE_CONFIG_START(emerald_state::emerald)
MCFG_RAM_DEFAULT_VALUE(0x00)
// memory control gate array
- MCFG_DEVICE_ADD(INTERPRO_MCGA_TAG, INTERPRO_MCGA, 0)
+ MCFG_DEVICE_ADD(m_mcga, INTERPRO_MCGA, 0)
// floppy controller
- // FIXME: not sure this should really be ready connected, but prevents crash at startup
- MCFG_I82072_ADD(INTERPRO_FDC_TAG, true)
- MCFG_UPD765_INTRQ_CALLBACK(WRITELINE(INTERPRO_IOGA_TAG, interpro_ioga_device, ir1_w))
- MCFG_UPD765_DRQ_CALLBACK(WRITELINE(INTERPRO_IOGA_TAG, interpro_ioga_device, drq_floppy))
-
- // connect a 5.25" drive at id 3
- MCFG_DEVICE_ADD("fdc:0", FLOPPY_CONNECTOR, 0)
- MCFG_DEVICE_ADD("fdc:1", FLOPPY_CONNECTOR, 0)
- MCFG_DEVICE_ADD("fdc:2", FLOPPY_CONNECTOR, 0)
- MCFG_FLOPPY_DRIVE_ADD("fdc:3", interpro_floppies, "35hd", interpro_state::floppy_formats)
+ MCFG_I82072_ADD(m_fdc, false)
+ MCFG_UPD765_INTRQ_CALLBACK(WRITELINE(m_ioga, interpro_ioga_device, ir1_w))
+ MCFG_UPD765_DRQ_CALLBACK(WRITELINE(m_ioga, interpro_ioga_device, drq_floppy))
+
+ // connect a 3.5" drive at id 3
+ //MCFG_FLOPPY_DRIVE_ADD(INTERPRO_FDC_TAG ":2", interpro_floppies, "525hd", interpro_state::floppy_formats)
+ MCFG_FLOPPY_DRIVE_ADD(INTERPRO_FDC_TAG ":3", interpro_floppies, "35hd", interpro_state::floppy_formats)
MCFG_FLOPPY_DRIVE_SOUND(false)
// serial controllers and ports
- MCFG_DEVICE_ADD(INTERPRO_SCC1_TAG, SCC85C30, 4.9152_MHz_XTAL)
+ MCFG_DEVICE_ADD(m_scc1, SCC85C30, 4.9152_MHz_XTAL)
interpro_scc1(config);
- MCFG_DEVICE_ADD(INTERPRO_SCC2_TAG, SCC85C30, 4.9152_MHz_XTAL)
+ MCFG_DEVICE_ADD(m_scc2, SCC85C30, 4.9152_MHz_XTAL)
interpro_scc2(config);
// scsi controller
@@ -758,29 +903,29 @@ MACHINE_CONFIG_START(emerald_state::emerald)
MCFG_SLOT_OPTION_MACHINE_CONFIG(INTERPRO_SCSI_ADAPTER_TAG, interpro_scsi_adapter)
// ethernet controller
- MCFG_DEVICE_ADD(INTERPRO_ETH_TAG, I82586, 10_MHz_XTAL)
- MCFG_I82586_IRQ_CB(WRITELINE(INTERPRO_IOGA_TAG, interpro_ioga_device, ir12_w))
+ MCFG_DEVICE_ADD(m_eth, I82586, 10_MHz_XTAL)
+ MCFG_I82586_IRQ_CB(WRITELINE(m_ioga, interpro_ioga_device, ir12_w))
MCFG_DEVICE_ADDRESS_MAP(0, interpro_82586_map)
// i/o gate array
- MCFG_DEVICE_ADD(INTERPRO_IOGA_TAG, TURQUOISE_IOGA, 0)
+ MCFG_DEVICE_ADD(m_ioga, EMERALD_IOGA, 0)
MCFG_INTERPRO_IOGA_MEMORY(INTERPRO_CPU_TAG, 0)
ioga(config);
MACHINE_CONFIG_END
MACHINE_CONFIG_START(turquoise_state::turquoise)
interpro(config);
- MCFG_DEVICE_ADD(INTERPRO_CPU_TAG, CLIPPER_C300, 12.5_MHz_XTAL)
+ MCFG_DEVICE_ADD(m_maincpu, CLIPPER_C300, 12.5_MHz_XTAL)
MCFG_DEVICE_ADDRESS_MAP(0, turquoise_main_map)
MCFG_DEVICE_ADDRESS_MAP(1, turquoise_io_map)
MCFG_DEVICE_ADDRESS_MAP(2, interpro_boot_map)
MCFG_DEVICE_IRQ_ACKNOWLEDGE_DEVICE(INTERPRO_IOGA_TAG, interpro_ioga_device, acknowledge_interrupt)
- MCFG_DEVICE_ADD(INTERPRO_MMU_TAG "_i", CAMMU_C3, 0)
- MCFG_CAMMU_EXCEPTION_CB(WRITE16(INTERPRO_CPU_TAG, clipper_device, set_exception))
+ MCFG_DEVICE_ADD(m_i_cammu, CAMMU_C3, 0)
+ MCFG_CAMMU_EXCEPTION_CB(WRITE16(m_maincpu, clipper_device, set_exception))
- MCFG_DEVICE_ADD(INTERPRO_MMU_TAG "_d", CAMMU_C3, 0)
- MCFG_CAMMU_EXCEPTION_CB(WRITE16(INTERPRO_CPU_TAG, clipper_device, set_exception))
+ MCFG_DEVICE_ADD(m_d_cammu, CAMMU_C3, 0)
+ MCFG_CAMMU_EXCEPTION_CB(WRITE16(m_maincpu, clipper_device, set_exception))
MCFG_CAMMU_LINK(INTERPRO_MMU_TAG "_i")
// boot fails memory test without this
@@ -788,24 +933,21 @@ MACHINE_CONFIG_START(turquoise_state::turquoise)
MCFG_RAM_DEFAULT_VALUE(0x00)
// memory control gate array
- MCFG_DEVICE_ADD(INTERPRO_MCGA_TAG, INTERPRO_MCGA, 0)
+ MCFG_DEVICE_ADD(m_mcga, INTERPRO_MCGA, 0)
// floppy controller
- MCFG_I82072_ADD(INTERPRO_FDC_TAG, false)
- MCFG_UPD765_INTRQ_CALLBACK(WRITELINE(INTERPRO_IOGA_TAG, interpro_ioga_device, ir1_w))
- MCFG_UPD765_DRQ_CALLBACK(WRITELINE(INTERPRO_IOGA_TAG, interpro_ioga_device, drq_floppy))
+ MCFG_I82072_ADD(m_fdc, false)
+ MCFG_UPD765_INTRQ_CALLBACK(WRITELINE(m_ioga, interpro_ioga_device, ir1_w))
+ MCFG_UPD765_DRQ_CALLBACK(WRITELINE(m_ioga, interpro_ioga_device, drq_floppy))
// connect a 3.5" drive at id 3
- MCFG_DEVICE_ADD("fdc:0", FLOPPY_CONNECTOR, 0)
- MCFG_DEVICE_ADD("fdc:1", FLOPPY_CONNECTOR, 0)
- MCFG_DEVICE_ADD("fdc:2", FLOPPY_CONNECTOR, 0)
- MCFG_FLOPPY_DRIVE_ADD("fdc:3", interpro_floppies, "35hd", interpro_state::floppy_formats)
+ MCFG_FLOPPY_DRIVE_ADD(INTERPRO_FDC_TAG ":3", interpro_floppies, "35hd", interpro_state::floppy_formats)
MCFG_FLOPPY_DRIVE_SOUND(false)
// serial controllers and ports
- MCFG_DEVICE_ADD(INTERPRO_SCC1_TAG, SCC85C30, 4.9152_MHz_XTAL)
+ MCFG_DEVICE_ADD(m_scc1, SCC85C30, 4.9152_MHz_XTAL)
interpro_scc1(config);
- MCFG_DEVICE_ADD(INTERPRO_SCC2_TAG, SCC85C30, 4.9152_MHz_XTAL)
+ MCFG_DEVICE_ADD(m_scc2, SCC85C30, 4.9152_MHz_XTAL)
interpro_scc2(config);
// scsi controller
@@ -813,58 +955,57 @@ MACHINE_CONFIG_START(turquoise_state::turquoise)
MCFG_SLOT_OPTION_MACHINE_CONFIG(INTERPRO_SCSI_ADAPTER_TAG, interpro_scsi_adapter)
// ethernet controller
- MCFG_DEVICE_ADD(INTERPRO_ETH_TAG, I82586, 0)
- MCFG_I82586_IRQ_CB(WRITELINE(INTERPRO_IOGA_TAG, interpro_ioga_device, ir12_w))
+ MCFG_DEVICE_ADD(m_eth, I82586, 0)
+ MCFG_I82586_IRQ_CB(WRITELINE(m_ioga, interpro_ioga_device, ir12_w))
MCFG_DEVICE_ADDRESS_MAP(0, interpro_82586_map)
// i/o gate array
- MCFG_DEVICE_ADD(INTERPRO_IOGA_TAG, TURQUOISE_IOGA, 0)
+ MCFG_DEVICE_ADD(m_ioga, TURQUOISE_IOGA, 0)
MCFG_INTERPRO_IOGA_MEMORY(INTERPRO_CPU_TAG, 0)
ioga(config);
// cbus and slots
MCFG_DEVICE_ADD(INTERPRO_SLOT_TAG, CBUS, 0)
MCFG_CBUS_MEMORY(INTERPRO_CPU_TAG, 0, 1)
- MCFG_CBUS_OUT_IRQ0_CB(WRITELINE(INTERPRO_IOGA_TAG, interpro_ioga_device, ir3_w))
- MCFG_CBUS_OUT_IRQ1_CB(WRITELINE(INTERPRO_IOGA_TAG, interpro_ioga_device, ir4_w))
- MCFG_CBUS_OUT_IRQ2_CB(WRITELINE(INTERPRO_IOGA_TAG, interpro_ioga_device, ir5_w))
- MCFG_CBUS_OUT_VBLANK_CB(WRITELINE(INTERPRO_IOGA_TAG, interpro_ioga_device, ir6_w))
+ MCFG_CBUS_OUT_IRQ0_CB(WRITELINE(m_ioga, interpro_ioga_device, ir3_w))
+ MCFG_CBUS_OUT_IRQ1_CB(WRITELINE(m_ioga, interpro_ioga_device, ir4_w))
+ MCFG_CBUS_OUT_IRQ2_CB(WRITELINE(m_ioga, interpro_ioga_device, ir5_w))
+ MCFG_CBUS_OUT_VBLANK_CB(WRITELINE(m_ioga, interpro_ioga_device, ir6_w))
MCFG_CBUS_SLOT_ADD(INTERPRO_SLOT_TAG, INTERPRO_SLOT_TAG ":0", cbus_cards, nullptr, false)
MCFG_CBUS_SLOT_ADD(INTERPRO_SLOT_TAG, INTERPRO_SLOT_TAG ":1", cbus_cards, nullptr, false)
MACHINE_CONFIG_END
MACHINE_CONFIG_START(sapphire_state::sapphire)
interpro(config);
- MCFG_DEVICE_ADD(INTERPRO_CPU_TAG, CLIPPER_C400, 12.5_MHz_XTAL)
+ MCFG_DEVICE_ADD(m_maincpu, CLIPPER_C400, 12.5_MHz_XTAL)
MCFG_DEVICE_ADDRESS_MAP(0, sapphire_main_map)
MCFG_DEVICE_ADDRESS_MAP(1, sapphire_io_map)
MCFG_DEVICE_ADDRESS_MAP(2, interpro_boot_map)
MCFG_DEVICE_IRQ_ACKNOWLEDGE_DEVICE(INTERPRO_IOGA_TAG, interpro_ioga_device, acknowledge_interrupt)
// FIXME: 2400/6400 should be C4T cammu?
- MCFG_DEVICE_ADD(INTERPRO_MMU_TAG, CAMMU_C4I, 0)
- MCFG_CAMMU_EXCEPTION_CB(WRITE16(INTERPRO_CPU_TAG, clipper_device, set_exception))
+ MCFG_DEVICE_ADD(m_mmu, CAMMU_C4I, 0)
+ MCFG_CAMMU_EXCEPTION_CB(WRITE16(m_maincpu, clipper_device, set_exception))
// memory control gate array
- MCFG_DEVICE_ADD(INTERPRO_MCGA_TAG, INTERPRO_FMCC, 0)
+ MCFG_DEVICE_ADD(m_mcga, INTERPRO_FMCC, 0)
// floppy controller
- MCFG_N82077AA_ADD(INTERPRO_FDC_TAG, n82077aa_device::MODE_PS2)
- MCFG_UPD765_INTRQ_CALLBACK(WRITELINE(INTERPRO_IOGA_TAG, interpro_ioga_device, ir1_w))
- MCFG_UPD765_DRQ_CALLBACK(WRITELINE(INTERPRO_IOGA_TAG, interpro_ioga_device, drq_floppy))
+ MCFG_N82077AA_ADD(m_fdc, n82077aa_device::MODE_PS2)
+ MCFG_UPD765_INTRQ_CALLBACK(WRITELINE(m_ioga, interpro_ioga_device, ir1_w))
+ MCFG_UPD765_DRQ_CALLBACK(WRITELINE(m_ioga, interpro_ioga_device, drq_floppy))
// connect a 3.5" drive at id 1
- MCFG_DEVICE_ADD("fdc:0", FLOPPY_CONNECTOR, 0)
- MCFG_FLOPPY_DRIVE_ADD("fdc:1", interpro_floppies, "35hd", interpro_state::floppy_formats)
+ MCFG_FLOPPY_DRIVE_ADD(INTERPRO_FDC_TAG ":1", interpro_floppies, "35hd", interpro_state::floppy_formats)
MCFG_FLOPPY_DRIVE_SOUND(false)
// srx arbiter gate array
- MCFG_DEVICE_ADD(INTERPRO_ARBGA_TAG, INTERPRO_ARBGA, 0)
+ MCFG_DEVICE_ADD(m_arbga, INTERPRO_ARBGA, 0)
// serial controllers and ports
- MCFG_DEVICE_ADD(INTERPRO_SCC1_TAG, SCC85230, 4.9152_MHz_XTAL)
+ MCFG_DEVICE_ADD(m_scc1, SCC85230, 4.9152_MHz_XTAL)
interpro_scc1(config);
- MCFG_DEVICE_ADD(INTERPRO_SCC2_TAG, SCC85C30, 4.9152_MHz_XTAL)
+ MCFG_DEVICE_ADD(m_scc2, SCC85C30, 4.9152_MHz_XTAL)
interpro_scc2(config);
// scsi controller
@@ -872,18 +1013,18 @@ MACHINE_CONFIG_START(sapphire_state::sapphire)
MCFG_SLOT_OPTION_MACHINE_CONFIG(INTERPRO_SCSI_ADAPTER_TAG, interpro_scsi_adapter)
// ethernet controller
- MCFG_DEVICE_ADD(INTERPRO_ETH_TAG, I82596_LE16, 20_MHz_XTAL)
- MCFG_I82586_IRQ_CB(WRITELINE(INTERPRO_IOGA_TAG, interpro_ioga_device, ir12_w))
+ MCFG_DEVICE_ADD(m_eth, I82596_LE16, 20_MHz_XTAL)
+ MCFG_I82586_IRQ_CB(WRITELINE(m_ioga, interpro_ioga_device, ir12_w))
MCFG_DEVICE_ADDRESS_MAP(0, interpro_82596_map)
// i/o gate array
- MCFG_DEVICE_ADD(INTERPRO_IOGA_TAG, SAPPHIRE_IOGA, 0)
+ MCFG_DEVICE_ADD(m_ioga, SAPPHIRE_IOGA, 0)
MCFG_INTERPRO_IOGA_MEMORY(INTERPRO_CPU_TAG, 0)
ioga(config);
// flash memory
- MCFG_DEVICE_ADD(INTERPRO_FLASH_TAG "_lo", INTEL_28F010, 0)
- MCFG_DEVICE_ADD(INTERPRO_FLASH_TAG "_hi", INTEL_28F010, 0)
+ MCFG_DEVICE_ADD(m_flash_lsb, INTEL_28F010, 0)
+ MCFG_DEVICE_ADD(m_flash_msb, INTEL_28F010, 0)
MACHINE_CONFIG_END
MACHINE_CONFIG_START(turquoise_state::ip2000)
@@ -909,7 +1050,7 @@ MACHINE_CONFIG_START(sapphire_state::ip2400)
// cbus and slots (default to 2430 with GT+ graphics)
MCFG_DEVICE_ADD(INTERPRO_SLOT_TAG, CBUS, 0)
MCFG_CBUS_MEMORY(INTERPRO_CPU_TAG, 0, 1)
- MCFG_CBUS_OUT_IRQ0_CB(WRITELINE(INTERPRO_IOGA_TAG, interpro_ioga_device, ir6_w))
+ MCFG_CBUS_OUT_IRQ0_CB(WRITELINE(m_ioga, interpro_ioga_device, ir6_w))
MCFG_CBUS_SLOT_ADD(INTERPRO_SLOT_TAG, INTERPRO_SLOT_TAG ":0", cbus_cards, "msmt070", false)
MCFG_CBUS_SLOT_ADD(INTERPRO_SLOT_TAG, INTERPRO_SLOT_TAG ":1", cbus_cards, nullptr, false)
@@ -924,7 +1065,7 @@ MACHINE_CONFIG_START(sapphire_state::ip2500)
// cbus and slots (default to 2530 with GT+ graphics)
MCFG_DEVICE_ADD(INTERPRO_SLOT_TAG, CBUS, 0)
MCFG_CBUS_MEMORY(INTERPRO_CPU_TAG, 0, 1)
- MCFG_CBUS_OUT_IRQ0_CB(WRITELINE(INTERPRO_IOGA_TAG, interpro_ioga_device, ir6_w))
+ MCFG_CBUS_OUT_IRQ0_CB(WRITELINE(m_ioga, interpro_ioga_device, ir6_w))
MCFG_CBUS_SLOT_ADD(INTERPRO_SLOT_TAG, INTERPRO_SLOT_TAG ":0", cbus_cards, "msmt070", false)
MCFG_CBUS_SLOT_ADD(INTERPRO_SLOT_TAG, INTERPRO_SLOT_TAG ":1", cbus_cards, nullptr, false)
@@ -946,7 +1087,7 @@ MACHINE_CONFIG_START(sapphire_state::ip2700)
// cbus and slots (default to 2730 with GT+ graphics)
MCFG_DEVICE_ADD(INTERPRO_SLOT_TAG, CBUS, 0)
MCFG_CBUS_MEMORY(INTERPRO_CPU_TAG, 0, 1)
- MCFG_CBUS_OUT_IRQ0_CB(WRITELINE(INTERPRO_IOGA_TAG, interpro_ioga_device, ir6_w))
+ MCFG_CBUS_OUT_IRQ0_CB(WRITELINE(m_ioga, interpro_ioga_device, ir6_w))
MCFG_CBUS_SLOT_ADD(INTERPRO_SLOT_TAG, INTERPRO_SLOT_TAG ":0", cbus_cards, "msmt070", false)
MCFG_CBUS_SLOT_ADD(INTERPRO_SLOT_TAG, INTERPRO_SLOT_TAG ":1", cbus_cards, nullptr, false)
@@ -967,7 +1108,7 @@ MACHINE_CONFIG_START(sapphire_state::ip2800)
// cbus and slots (default to 2830 with GT+ graphics)
MCFG_DEVICE_ADD(INTERPRO_SLOT_TAG, CBUS, 0)
MCFG_CBUS_MEMORY(INTERPRO_CPU_TAG, 0, 1)
- MCFG_CBUS_OUT_IRQ0_CB(WRITELINE(INTERPRO_IOGA_TAG, interpro_ioga_device, ir6_w))
+ MCFG_CBUS_OUT_IRQ0_CB(WRITELINE(m_ioga, interpro_ioga_device, ir6_w))
MCFG_CBUS_SLOT_ADD(INTERPRO_SLOT_TAG, INTERPRO_SLOT_TAG ":0", cbus_cards, "msmt070", false)
MCFG_CBUS_SLOT_ADD(INTERPRO_SLOT_TAG, INTERPRO_SLOT_TAG ":1", cbus_cards, nullptr, false)
@@ -994,9 +1135,10 @@ MACHINE_CONFIG_START(emerald_state::ip6000)
// srx and slots (default to 6040 with EDGE-1 graphics)
MCFG_DEVICE_ADD(INTERPRO_SLOT_TAG, SRX, 0)
MCFG_SRX_MEMORY(INTERPRO_CPU_TAG, 0, 1)
- MCFG_SRX_OUT_IRQ0_CB(WRITELINE(INTERPRO_IOGA_TAG, interpro_ioga_device, ir3_w))
- MCFG_SRX_OUT_IRQ1_CB(WRITELINE(INTERPRO_IOGA_TAG, interpro_ioga_device, ir4_w))
- MCFG_SRX_OUT_IRQ2_CB(WRITELINE(INTERPRO_IOGA_TAG, interpro_ioga_device, ir5_w))
+ MCFG_SRX_OUT_IRQ0_CB(WRITELINE(m_ioga, interpro_ioga_device, ir3_w))
+ MCFG_SRX_OUT_IRQ1_CB(WRITELINE(m_ioga, interpro_ioga_device, ir4_w))
+ MCFG_SRX_OUT_IRQ2_CB(WRITELINE(m_ioga, interpro_ioga_device, ir5_w))
+ MCFG_SRX_OUT_VBLANK_CB(WRITELINE(m_ioga, interpro_ioga_device, ir6_w))
MCFG_SRX_SLOT_ADD(INTERPRO_SLOT_TAG, INTERPRO_SLOT_TAG ":1", srx_cards, "mpcb828", false)
MCFG_SRX_SLOT_ADD(INTERPRO_SLOT_TAG, INTERPRO_SLOT_TAG ":2", srx_cards, nullptr, false)
MCFG_SRX_SLOT_ADD(INTERPRO_SLOT_TAG, INTERPRO_SLOT_TAG ":3", srx_cards, nullptr, false)
@@ -1016,9 +1158,9 @@ MACHINE_CONFIG_START(sapphire_state::ip6400)
// srx and slots (default to 6450 with GT II graphics)
MCFG_DEVICE_ADD(INTERPRO_SLOT_TAG, SRX, 0)
MCFG_SRX_MEMORY(INTERPRO_CPU_TAG, 0, 1)
- MCFG_SRX_OUT_IRQ0_CB(WRITELINE(INTERPRO_IOGA_TAG, interpro_ioga_device, ir3_w))
- MCFG_SRX_OUT_IRQ1_CB(WRITELINE(INTERPRO_IOGA_TAG, interpro_ioga_device, ir4_w))
- MCFG_SRX_OUT_IRQ2_CB(WRITELINE(INTERPRO_IOGA_TAG, interpro_ioga_device, ir5_w))
+ MCFG_SRX_OUT_IRQ0_CB(WRITELINE(m_ioga, interpro_ioga_device, ir3_w))
+ MCFG_SRX_OUT_IRQ1_CB(WRITELINE(m_ioga, interpro_ioga_device, ir4_w))
+ MCFG_SRX_OUT_IRQ2_CB(WRITELINE(m_ioga, interpro_ioga_device, ir5_w))
MCFG_SRX_SLOT_ADD(INTERPRO_SLOT_TAG, INTERPRO_SLOT_TAG ":1", srx_cards, "mpcbb92", false)
MCFG_SRX_SLOT_ADD(INTERPRO_SLOT_TAG, INTERPRO_SLOT_TAG ":2", srx_cards, nullptr, false)
MCFG_SRX_SLOT_ADD(INTERPRO_SLOT_TAG, INTERPRO_SLOT_TAG ":3", srx_cards, nullptr, false)
@@ -1043,9 +1185,9 @@ MACHINE_CONFIG_START(sapphire_state::ip6700)
// srx and slots (default to 6780 with EDGE-2 Plus graphics)
MCFG_DEVICE_ADD(INTERPRO_SLOT_TAG, SRX, 0)
MCFG_SRX_MEMORY(INTERPRO_CPU_TAG, 0, 1)
- MCFG_SRX_OUT_IRQ0_CB(WRITELINE(INTERPRO_IOGA_TAG, interpro_ioga_device, ir3_w))
- MCFG_SRX_OUT_IRQ1_CB(WRITELINE(INTERPRO_IOGA_TAG, interpro_ioga_device, ir4_w))
- MCFG_SRX_OUT_IRQ2_CB(WRITELINE(INTERPRO_IOGA_TAG, interpro_ioga_device, ir5_w))
+ MCFG_SRX_OUT_IRQ0_CB(WRITELINE(m_ioga, interpro_ioga_device, ir3_w))
+ MCFG_SRX_OUT_IRQ1_CB(WRITELINE(m_ioga, interpro_ioga_device, ir4_w))
+ MCFG_SRX_OUT_IRQ2_CB(WRITELINE(m_ioga, interpro_ioga_device, ir5_w))
MCFG_SRX_SLOT_ADD(INTERPRO_SLOT_TAG, INTERPRO_SLOT_TAG ":1", srx_cards, "msmt094", false)
MCFG_SRX_SLOT_ADD(INTERPRO_SLOT_TAG, INTERPRO_SLOT_TAG ":2", srx_cards, "mpcb896", false)
MCFG_SRX_SLOT_ADD(INTERPRO_SLOT_TAG, INTERPRO_SLOT_TAG ":3", srx_cards, nullptr, false)
@@ -1070,9 +1212,9 @@ MACHINE_CONFIG_START(sapphire_state::ip6800)
// srx and slots (default to 6880 with EDGE-2 Plus graphics)
MCFG_DEVICE_ADD(INTERPRO_SLOT_TAG, SRX, 0)
MCFG_SRX_MEMORY(INTERPRO_CPU_TAG, 0, 1)
- MCFG_SRX_OUT_IRQ0_CB(WRITELINE(INTERPRO_IOGA_TAG, interpro_ioga_device, ir3_w))
- MCFG_SRX_OUT_IRQ1_CB(WRITELINE(INTERPRO_IOGA_TAG, interpro_ioga_device, ir4_w))
- MCFG_SRX_OUT_IRQ2_CB(WRITELINE(INTERPRO_IOGA_TAG, interpro_ioga_device, ir5_w))
+ MCFG_SRX_OUT_IRQ0_CB(WRITELINE(m_ioga, interpro_ioga_device, ir3_w))
+ MCFG_SRX_OUT_IRQ1_CB(WRITELINE(m_ioga, interpro_ioga_device, ir4_w))
+ MCFG_SRX_OUT_IRQ2_CB(WRITELINE(m_ioga, interpro_ioga_device, ir5_w))
MCFG_SRX_SLOT_ADD(INTERPRO_SLOT_TAG, INTERPRO_SLOT_TAG ":1", srx_cards, nullptr, false)
MCFG_SRX_SLOT_ADD(INTERPRO_SLOT_TAG, INTERPRO_SLOT_TAG ":2", srx_cards, nullptr, false)
MCFG_SRX_SLOT_ADD(INTERPRO_SLOT_TAG, INTERPRO_SLOT_TAG ":3", srx_cards, "msmt094", false)
@@ -1102,10 +1244,10 @@ ROM_START(ip2400)
ROM_SYSTEM_BIOS(0, "ip2400", "InterPro 2400 EPROM")
ROMX_LOAD("mprgw510b__05_16_92.u35", 0x00000, 0x20000, CRC(3b2c4545) SHA1(4e4c98d1cd1035a04be8527223f44d0b687ec3ef), ROM_BIOS(0))
- ROM_REGION(0x20000, INTERPRO_FLASH_TAG "_lo", 0)
+ ROM_REGION(0x20000, INTERPRO_FLASH_TAG "_lsb", 0)
ROM_LOAD_OPTIONAL("y225.u76", 0x00000, 0x20000, CRC(46c0b105) SHA1(7c4a104e4fb3d0e5e8db7c911cdfb3f5c4fb0218))
- ROM_REGION(0x20000, INTERPRO_FLASH_TAG "_hi", 0)
+ ROM_REGION(0x20000, INTERPRO_FLASH_TAG "_msb", 0)
ROM_LOAD_OPTIONAL("y226.u67", 0x00000, 0x20000, CRC(54d95730) SHA1(a4e114dee1567d8aa31eed770f7cc366588f395c))
ROM_END
@@ -1117,10 +1259,10 @@ ROM_START(ip2500)
ROM_SYSTEM_BIOS(0, "ip2500", "InterPro 2500 EPROM")
ROMX_LOAD("ip2500_eprom.bin", 0x00000, 0x20000, NO_DUMP, ROM_BIOS(0))
- ROM_REGION(0x20000, INTERPRO_FLASH_TAG "_lo", 0)
+ ROM_REGION(0x20000, INTERPRO_FLASH_TAG "_lsb", 0)
ROM_LOAD_OPTIONAL("y225.u76", 0x00000, 0x20000, CRC(46c0b105) SHA1(7c4a104e4fb3d0e5e8db7c911cdfb3f5c4fb0218))
- ROM_REGION(0x20000, INTERPRO_FLASH_TAG "_hi", 0)
+ ROM_REGION(0x20000, INTERPRO_FLASH_TAG "_msb", 0)
ROM_LOAD_OPTIONAL("y226.u67", 0x00000, 0x20000, CRC(54d95730) SHA1(a4e114dee1567d8aa31eed770f7cc366588f395c))
ROM_END
@@ -1132,10 +1274,10 @@ ROM_START(ip2700)
ROM_SYSTEM_BIOS(0, "ip2700", "InterPro 2700 EPROM")
ROMX_LOAD("mprgz530a__9405181.u35", 0x00000, 0x20000, CRC(467ce7bd) SHA1(53faee40d5df311f53b24c930e434cbf94a5c4aa), ROM_BIOS(0))
- ROM_REGION(0x20000, INTERPRO_FLASH_TAG "_lo", 0)
+ ROM_REGION(0x20000, INTERPRO_FLASH_TAG "_lsb", 0)
ROM_LOAD_OPTIONAL("y225.u76", 0x00000, 0x20000, CRC(46c0b105) SHA1(7c4a104e4fb3d0e5e8db7c911cdfb3f5c4fb0218))
- ROM_REGION(0x20000, INTERPRO_FLASH_TAG "_hi", 0)
+ ROM_REGION(0x20000, INTERPRO_FLASH_TAG "_msb", 0)
ROM_LOAD_OPTIONAL("y226.u67", 0x00000, 0x20000, CRC(54d95730) SHA1(a4e114dee1567d8aa31eed770f7cc366588f395c))
ROM_END
@@ -1147,10 +1289,10 @@ ROM_START(ip2800)
ROM_SYSTEM_BIOS(0, "ip2800", "InterPro 2800 EPROM")
ROMX_LOAD("ip2800_eprom.bin", 0x00000, 0x20000, CRC(467ce7bd) SHA1(53faee40d5df311f53b24c930e434cbf94a5c4aa), ROM_BIOS(0))
- ROM_REGION(0x20000, INTERPRO_FLASH_TAG "_lo", 0)
+ ROM_REGION(0x20000, INTERPRO_FLASH_TAG "_lsb", 0)
ROM_LOAD_OPTIONAL("y225.u76", 0x00000, 0x20000, CRC(46c0b105) SHA1(7c4a104e4fb3d0e5e8db7c911cdfb3f5c4fb0218))
- ROM_REGION(0x20000, INTERPRO_FLASH_TAG "_hi", 0)
+ ROM_REGION(0x20000, INTERPRO_FLASH_TAG "_msb", 0)
ROM_LOAD_OPTIONAL("y226.u67", 0x00000, 0x20000, CRC(54d95730) SHA1(a4e114dee1567d8aa31eed770f7cc366588f395c))
ROM_END
@@ -1176,11 +1318,11 @@ ROM_START(ip6400)
ROM_SYSTEM_BIOS(0, "ip6400", "InterPro 6400 EPROM")
ROMX_LOAD("ip6400_eprom.bin", 0x00000, 0x20000, BAD_DUMP CRC(3b2c4545) SHA1(4e4c98d1cd1035a04be8527223f44d0b687ec3ef), ROM_BIOS(0))
- ROM_REGION(0x20000, INTERPRO_FLASH_TAG "_lo", 0)
- ROM_LOAD_OPTIONAL("flash.lo", 0x00000, 0x20000, CRC(46c0b105) SHA1(7c4a104e4fb3d0e5e8db7c911cdfb3f5c4fb0218))
+ ROM_REGION(0x20000, INTERPRO_FLASH_TAG "_lsb", 0)
+ ROM_LOAD_OPTIONAL("flash.lsb", 0x00000, 0x20000, CRC(46c0b105) SHA1(7c4a104e4fb3d0e5e8db7c911cdfb3f5c4fb0218))
- ROM_REGION(0x20000, INTERPRO_FLASH_TAG "_hi", 0)
- ROM_LOAD_OPTIONAL("flash.hi", 0x00000, 0x20000, CRC(54d95730) SHA1(a4e114dee1567d8aa31eed770f7cc366588f395c))
+ ROM_REGION(0x20000, INTERPRO_FLASH_TAG "_msb", 0)
+ ROM_LOAD_OPTIONAL("flash.msb", 0x00000, 0x20000, CRC(54d95730) SHA1(a4e114dee1567d8aa31eed770f7cc366588f395c))
ROM_END
ROM_START(ip6700)
@@ -1191,10 +1333,10 @@ ROM_START(ip6700)
ROM_SYSTEM_BIOS(0, "ip6700", "InterPro 6700 EPROM")
ROMX_LOAD("mprgz530a.u144", 0x00000, 0x20000, CRC(467ce7bd) SHA1(53faee40d5df311f53b24c930e434cbf94a5c4aa), ROM_BIOS(0))
- ROM_REGION(0x20000, INTERPRO_FLASH_TAG "_lo", 0)
+ ROM_REGION(0x20000, INTERPRO_FLASH_TAG "_lsb", 0)
ROM_LOAD_OPTIONAL("y225.u117", 0x00000, 0x20000, CRC(46c0b105) SHA1(7c4a104e4fb3d0e5e8db7c911cdfb3f5c4fb0218))
- ROM_REGION(0x20000, INTERPRO_FLASH_TAG "_hi", 0)
+ ROM_REGION(0x20000, INTERPRO_FLASH_TAG "_msb", 0)
ROM_LOAD_OPTIONAL("y226.u130", 0x00000, 0x20000, CRC(54d95730) SHA1(a4e114dee1567d8aa31eed770f7cc366588f395c))
ROM_END
@@ -1206,10 +1348,10 @@ ROM_START(ip6800)
ROM_SYSTEM_BIOS(0, "ip6800", "InterPro 6800 EPROM")
ROMX_LOAD("mprgz530a__9406270.u144", 0x00000, 0x20000, CRC(467ce7bd) SHA1(53faee40d5df311f53b24c930e434cbf94a5c4aa), ROM_BIOS(0))
- ROM_REGION(0x20000, INTERPRO_FLASH_TAG "_lo", 0)
+ ROM_REGION(0x20000, INTERPRO_FLASH_TAG "_lsb", 0)
ROM_LOAD_OPTIONAL("y225.u117", 0x00000, 0x20000, CRC(46c0b105) SHA1(7c4a104e4fb3d0e5e8db7c911cdfb3f5c4fb0218))
- ROM_REGION(0x20000, INTERPRO_FLASH_TAG "_hi", 0)
+ ROM_REGION(0x20000, INTERPRO_FLASH_TAG "_msb", 0)
ROM_LOAD_OPTIONAL("y226.u130", 0x00000, 0x20000, CRC(54d95730) SHA1(a4e114dee1567d8aa31eed770f7cc366588f395c))
ROM_END
diff --git a/src/mame/includes/interpro.h b/src/mame/includes/interpro.h
index 0832f3bcc36..0dac4f4403b 100644
--- a/src/mame/includes/interpro.h
+++ b/src/mame/includes/interpro.h
@@ -79,7 +79,7 @@ public:
, m_scsibus(*this, INTERPRO_SCSI_TAG)
, m_eth(*this, INTERPRO_ETH_TAG)
, m_ioga(*this, INTERPRO_IOGA_TAG)
- , m_led(*this, "digit0")
+ , m_diag_led(*this, "digit0")
{
}
@@ -98,7 +98,10 @@ public:
void init_common();
- enum sreg_error_mask
+ virtual DECLARE_READ32_MEMBER(unmapped_r);
+ virtual DECLARE_WRITE32_MEMBER(unmapped_w);
+
+ enum error_mask : u16
{
ERROR_BPID4 = 0x0001,
ERROR_SRXMMBE = 0x0002,
@@ -110,11 +113,11 @@ public:
ERROR_BG = 0x0070,
ERROR_BUSHOG = 0x0080
};
- DECLARE_READ16_MEMBER(sreg_error_r);
+ DECLARE_READ16_MEMBER(error_r);
- DECLARE_WRITE16_MEMBER(sreg_led_w);
+ DECLARE_WRITE16_MEMBER(led_w);
- enum sreg_status_mask
+ enum status_mask : u16
{
STATUS_YELLOW_ZONE = 0x0001,
STATUS_SRNMI = 0x0002,
@@ -122,38 +125,12 @@ public:
STATUS_RED_ZONE = 0x0008,
STATUS_BP = 0x00f0
};
- DECLARE_READ16_MEMBER(sreg_status_r) { return m_sreg_status; }
+ DECLARE_READ16_MEMBER(status_r) { return m_status; }
- enum sreg_ctrl1_mask
- {
- CTRL1_FLOPLOW = 0x0001, // 0 = 5.25" floppy selected
- CTRL1_FLOPRDY = 0x0002, // 1 = plotter fifo empty?
- CTRL1_LEDENA = 0x0004, // 0 = led display disabled
- CTRL1_LEDDP = 0x0008, // 0 = led right decimal point disabled
- CTRL1_ETHLOOP = 0x0010, // 1 = mmbe enabled
- CTRL1_ETHDTR = 0x0020, // 0 = modem dtr pin activated
- CTRL1_ETHRMOD = 0x0040, // 0 = sytem configured for remote modems
- CTRL1_FIFOACTIVE = 0x0080 // 0 = plotter fifos reset
- };
- DECLARE_READ16_MEMBER(sreg_ctrl1_r) { return m_sreg_ctrl1; }
- DECLARE_WRITE16_MEMBER(sreg_ctrl1_w);
-
- enum sreg_ctrl2_mask
- {
- CTRL2_PWRUP = 0x0003, // 3 = power supply voltage adjusted up by 5%
- CTRL2_HOLDOFF = 0x0004, // 0 = power supply will shut down 0.33 seconds after switch is turned off
- CTRL2_EXTNMIENA = 0x0008, // 0 = power nmi disabled
- CTRL2_COLDSTART = 0x0010, // 1 = cold start flag
- CTRL2_RESET = 0x0020, // 0 = soft reset
- CTRL2_BUSENA = 0x0040, // 0 = clear bus grant error
- CTRL2_FLASHEN = 0x0080, // 0 = flash eprom writes disabled
-
- CTRL2_MASK = 0x004d
- };
- DECLARE_READ16_MEMBER(sreg_ctrl2_r) { return m_sreg_ctrl2; }
- virtual DECLARE_WRITE16_MEMBER(sreg_ctrl2_w);
- DECLARE_READ16_MEMBER(sreg_ctrl3_r) { return m_sreg_ctrl3; }
- DECLARE_WRITE16_MEMBER(sreg_ctrl3_w) { m_sreg_ctrl3 = data; }
+ virtual DECLARE_READ16_MEMBER(ctrl1_r) = 0;
+ virtual DECLARE_WRITE16_MEMBER(ctrl1_w) = 0;
+ virtual DECLARE_READ16_MEMBER(ctrl2_r) = 0;
+ virtual DECLARE_WRITE16_MEMBER(ctrl2_w) = 0;
DECLARE_READ8_MEMBER(nodeid_r);
@@ -164,6 +141,7 @@ public:
void interpro_scc2(machine_config &config);
void interpro(machine_config &config);
static void interpro_scsi_adapter(device_t *device);
+ static void interpro_cdrom(device_t *device);
void interpro_boot_map(address_map &map);
void interpro_common_map(address_map &map);
@@ -171,16 +149,12 @@ protected:
virtual void machine_start() override;
virtual void machine_reset() override;
- output_finder<> m_led;
+ output_finder<> m_diag_led;
emu_timer *m_reset_timer;
- u16 m_sreg_error;
- u16 m_sreg_status;
- u16 m_sreg_led;
- u16 m_sreg_ctrl1;
- u16 m_sreg_ctrl2;
-
- u16 m_sreg_ctrl3;
+ u16 m_error;
+ u16 m_status;
+ u16 m_led;
};
class emerald_state : public interpro_state
@@ -194,7 +168,38 @@ public:
{
}
- DECLARE_WRITE8_MEMBER(sreg_error_w) { m_sreg_error = data; }
+ DECLARE_WRITE8_MEMBER(error_w) { m_error = data; }
+
+ enum ctrl1_mask : u16
+ {
+ CTRL1_FLOPLOW = 0x0001, // 3.5" floppy select
+ CTRL1_FLOPRDY = 0x0002, // floppy ready enable?
+ CTRL1_LEDENA = 0x0004, // led display enable
+ CTRL1_LEDDP = 0x0008, // led right decimal point enable
+ CTRL1_ETHLOOP = 0x0010, // ethernet loopback enable?
+ CTRL1_ETHDTR = 0x0020, // modem dtr pin enable?
+ CTRL1_ETHRMOD = 0x0040, // remote modem configured (read)?
+ CTRL1_CLIPRESET = 0x0040, // hard reset (write)?
+ CTRL1_FIFOACTIVE = 0x0080 // plotter fifo active?
+ };
+ DECLARE_READ16_MEMBER(ctrl1_r) override { return m_ctrl1; }
+ DECLARE_WRITE16_MEMBER(ctrl1_w) override;
+
+ enum ctrl2_mask : u16
+ {
+ CTRL2_PWRUP = 0x0001, // power supply voltage adjust?
+ CRTL2_PWRENA = 0x0002, // ?
+ CTRL2_HOLDOFF = 0x0004, // power supply shut down delay
+ CTRL2_EXTNMIENA = 0x0008, // power nmi enable
+ CTRL2_COLDSTART = 0x0010, // cold start flag
+ CTRL2_RESET = 0x0020, // soft reset
+ CTRL2_BUSENA = 0x0040, // clear bus grant error
+ CTRL2_FRCPARITY = 0x0080, // ?
+
+ CTRL2_WMASK = 0x000f
+ };
+ DECLARE_READ16_MEMBER(ctrl2_r) override { return m_ctrl2; }
+ DECLARE_WRITE16_MEMBER(ctrl2_w) override;
required_device<cammu_c3_device> m_d_cammu;
required_device<cammu_c3_device> m_i_cammu;
@@ -206,6 +211,14 @@ public:
void emerald_base_map(address_map &map);
void emerald_main_map(address_map &map);
void emerald_io_map(address_map &map);
+
+protected:
+ virtual void machine_start() override;
+ virtual void machine_reset() override;
+
+private:
+ u16 m_ctrl1;
+ u16 m_ctrl2;
};
class turquoise_state : public interpro_state
@@ -219,7 +232,38 @@ public:
{
}
- DECLARE_WRITE8_MEMBER(sreg_error_w) { m_sreg_error = data; }
+ DECLARE_WRITE8_MEMBER(error_w) { m_error = data; }
+
+ enum ctrl1_mask : u16
+ {
+ CTRL1_FLOPLOW = 0x0001, // 3.5" floppy select
+ CTRL1_FLOPRDY = 0x0002, // floppy ready enable?
+ CTRL1_LEDENA = 0x0004, // led display enable
+ CTRL1_LEDDP = 0x0008, // led right decimal point enable
+ CTRL1_ETHLOOP = 0x0010, // ethernet loopback enable?
+ CTRL1_ETHDTR = 0x0020, // modem dtr pin enable?
+ CTRL1_ETHRMOD = 0x0040, // remote modem configured (read)?
+ CTRL1_CLIPRESET = 0x0040, // hard reset (write)?
+ CTRL1_FIFOACTIVE = 0x0080 // plotter fifo active?
+ };
+ DECLARE_READ16_MEMBER(ctrl1_r) override { return m_ctrl1; }
+ DECLARE_WRITE16_MEMBER(ctrl1_w) override;
+
+ enum ctrl2_mask : u16
+ {
+ CTRL2_PWRUP = 0x0001, // power supply voltage adjust?
+ CRTL2_PWRENA = 0x0002, // ?
+ CTRL2_HOLDOFF = 0x0004, // power supply shut down delay
+ CTRL2_EXTNMIENA = 0x0008, // power nmi enable
+ CTRL2_COLDSTART = 0x0010, // cold start flag
+ CTRL2_RESET = 0x0020, // soft reset
+ CTRL2_BUSENA = 0x0040, // clear bus grant error
+ CTRL2_FRCPARITY = 0x0080, // ?
+
+ CTRL2_WMASK = 0x000f
+ };
+ DECLARE_READ16_MEMBER(ctrl2_r) override { return m_ctrl2; }
+ DECLARE_WRITE16_MEMBER(ctrl2_w) override;
required_device<cammu_c3_device> m_d_cammu;
required_device<cammu_c3_device> m_i_cammu;
@@ -231,6 +275,14 @@ public:
void turquoise_base_map(address_map &map);
void turquoise_main_map(address_map &map);
void turquoise_io_map(address_map &map);
+
+protected:
+ virtual void machine_start() override;
+ virtual void machine_reset() override;
+
+private:
+ u16 m_ctrl1;
+ u16 m_ctrl2;
};
class sapphire_state : public interpro_state
@@ -241,20 +293,46 @@ public:
, m_mmu(*this, INTERPRO_MMU_TAG)
, m_scsi(*this, INTERPRO_SCSI_DEVICE_TAG)
, m_arbga(*this, INTERPRO_ARBGA_TAG)
- , m_flash_lo(*this, INTERPRO_FLASH_TAG "_lo")
- , m_flash_hi(*this, INTERPRO_FLASH_TAG "_hi")
+ , m_flash_lsb(*this, INTERPRO_FLASH_TAG "_lsb")
+ , m_flash_msb(*this, INTERPRO_FLASH_TAG "_msb")
{
}
- virtual DECLARE_WRITE16_MEMBER(sreg_ctrl2_w) override;
- DECLARE_READ32_MEMBER(unmapped_r);
- DECLARE_WRITE32_MEMBER(unmapped_w);
+ virtual DECLARE_READ32_MEMBER(unmapped_r) override;
+ virtual DECLARE_WRITE32_MEMBER(unmapped_w) override;
+
+ enum ctrl1_mask : u16
+ {
+ CTRL1_FLOPLOW = 0x0001, // 3.5" floppy select
+ // unused
+ CTRL1_LEDENA = 0x0004, // led display enable
+ CTRL1_LEDDP = 0x0008, // led right decimal point enable
+ CTRL1_MMBE = 0x0010, // mmbe enable
+ CTRL1_ETHDTR = 0x0020, // modem dtr pin enable
+ CTRL1_ETHRMOD = 0x0040, // 0 = sytem configured for remote modems
+ CTRL1_FIFOACTIVE = 0x0080 // 0 = plotter fifos reset
+ };
+ DECLARE_READ16_MEMBER(ctrl1_r) override { return m_ctrl1; }
+ DECLARE_WRITE16_MEMBER(ctrl1_w) override;
+
+ enum ctrl2_mask : u16
+ {
+ CTRL2_PWRUP = 0x0003, // power supply voltage adjust
+ CTRL2_HOLDOFF = 0x0004, // power supply shut down delay
+ CTRL2_EXTNMIENA = 0x0008, // power nmi enable
+ CTRL2_COLDSTART = 0x0010, // cold start flag
+ CTRL2_RESET = 0x0020, // soft reset
+ CTRL2_BUSENA = 0x0040, // clear bus grant error
+ CTRL2_FLASHEN = 0x0080, // flash eprom write enable
+ };
+ DECLARE_READ16_MEMBER(ctrl2_r) override { return m_ctrl2; }
+ DECLARE_WRITE16_MEMBER(ctrl2_w) override;
required_device<cammu_c4_device> m_mmu;
required_device<ncr53c94_device> m_scsi;
required_device<interpro_arbga_device> m_arbga;
- required_device<intel_28f010_device> m_flash_lo;
- required_device<intel_28f010_device> m_flash_hi;
+ required_device<intel_28f010_device> m_flash_lsb;
+ required_device<intel_28f010_device> m_flash_msb;
void sapphire(machine_config &config);
void ip2500(machine_config &config);
@@ -269,6 +347,14 @@ public:
void sapphire_base_map(address_map &map);
void sapphire_main_map(address_map &map);
void sapphire_io_map(address_map &map);
+
+protected:
+ virtual void machine_start() override;
+ virtual void machine_reset() override;
+
+private:
+ u16 m_ctrl1;
+ u16 m_ctrl2;
};
#endif // MAME_INCLUDES_INTERPRO_H
diff --git a/src/mame/machine/cammu.cpp b/src/mame/machine/cammu.cpp
index 604ab7d9333..721f8ed5cc9 100644
--- a/src/mame/machine/cammu.cpp
+++ b/src/mame/machine/cammu.cpp
@@ -22,8 +22,8 @@
* Another reference: http://www.eecs.berkeley.edu/Pubs/TechRpts/1986/CSD-86-289.pdf
*
* TODO
+ * - rework cammu addressing (to allow unaligned tlb access)
* - fault register values
- * - c3 protection faults
* - hard-wired and dynamic tlb
* - cache
* - bus errors
@@ -250,17 +250,21 @@ bool cammu_device::memory_translate(const u32 ssw, const int spacenum, const int
cammu_device::translated_t cammu_device::translate_address(const u32 ssw, const u32 virtual_address, const access_size size, const access_type mode)
{
// get effective user/supervisor mode
- const bool user = mode == EXECUTE ? ssw & SSW_U : ssw & (SSW_U | SSW_UU);
+ const bool user = (mode == EXECUTE) ? (ssw & SSW_U) : (ssw & (SSW_U | SSW_UU));
// check for alignment faults
if (!machine().side_effects_disabled() && get_alignment())
{
if ((mode == EXECUTE && (virtual_address & 0x1)) || (mode != EXECUTE && virtual_address & (size - 1)))
{
- set_fault_address(virtual_address);
- m_exception_func(mode == EXECUTE ? EXCEPTION_I_ALIGNMENT_FAULT : EXCEPTION_D_ALIGNMENT_FAULT);
-
- return { nullptr, 0 };
+ // FIXME: tlb access is not aligned; this hack lets us ignore for now
+ if (mode == EXECUTE || user || (virtual_address & 0xfffff900) != 0x00004800)
+ {
+ set_fault_address(virtual_address);
+ m_exception_func(mode == EXECUTE ? EXCEPTION_I_ALIGNMENT_FAULT : EXCEPTION_D_ALIGNMENT_FAULT);
+
+ return { nullptr, 0 };
+ }
}
}
@@ -309,23 +313,44 @@ cammu_device::translated_t cammu_device::translate_address(const u32 ssw, const
}
// check for protection level faults
- if (!machine().side_effects_disabled() && !get_access(mode, pte.entry, ssw))
+ if (!machine().side_effects_disabled())
{
- LOG("%s protection fault address 0x%08x ssw 0x%08x pte 0x%08x (%s)\n",
- mode == EXECUTE ? "execute" : mode == READ ? "read" : "write",
- virtual_address, ssw, pte.entry, machine().describe_context());
+ if ((mode == EXECUTE) && !get_access(mode, pte.entry, ssw))
+ {
+ LOGMASKED(LOG_ACCESS, "execute protection fault address 0x%08x ssw 0x%08x pte 0x%08x (%s)\n",
+ virtual_address, ssw, pte.entry, machine().describe_context());
- set_fault_address(virtual_address);
- m_exception_func(
- mode == EXECUTE ? EXCEPTION_I_EXECUTE_PROTECT_FAULT :
- mode == READ ? EXCEPTION_D_READ_PROTECT_FAULT :
- EXCEPTION_D_WRITE_PROTECT_FAULT);
+ set_fault_address(virtual_address);
+ m_exception_func(EXCEPTION_I_EXECUTE_PROTECT_FAULT);
- return { nullptr, 0 };
+ return { nullptr, 0 };
+ }
+
+ if ((mode & READ) && !get_access(READ, pte.entry, ssw))
+ {
+ LOGMASKED(LOG_ACCESS, "read protection fault address 0x%08x ssw 0x%08x pte 0x%08x (%s)\n",
+ virtual_address, ssw, pte.entry, machine().describe_context());
+
+ set_fault_address(virtual_address);
+ m_exception_func(EXCEPTION_D_READ_PROTECT_FAULT);
+
+ return { nullptr, 0 };
+ }
+
+ if ((mode & WRITE) && !get_access(WRITE, pte.entry, ssw))
+ {
+ LOGMASKED(LOG_ACCESS, "write protection fault address 0x%08x ssw 0x%08x pte 0x%08x (%s)\n",
+ virtual_address, ssw, pte.entry, machine().describe_context());
+
+ set_fault_address(virtual_address);
+ m_exception_func(EXCEPTION_D_WRITE_PROTECT_FAULT);
+
+ return { nullptr, 0 };
+ }
}
// set pte referenced and dirty flags
- if (mode & WRITE && !(pte.entry & PTE_D))
+ if ((mode & WRITE) && !(pte.entry & PTE_D))
m_space[ST0]->write_dword(pte.address, pte.entry | PTE_D | PTE_R);
else if (!(pte.entry & PTE_R))
m_space[ST0]->write_dword(pte.address, pte.entry | PTE_R);
@@ -380,37 +405,25 @@ bool cammu_c4_device::get_access(const access_type mode, const u32 pte, const u3
{
case READ: return pte & 0x20;
case WRITE: return pte & 0x10;
- case RMW: return (pte & 0x30) == 0x30;
case EXECUTE: return pte & 0x08;
- }
- return false;
+ default: return false;
+ }
}
bool cammu_c3_device::get_access(const access_type mode, const u32 pte, const u32 ssw) const
{
- // FIXME: logic is not correct yet
- return true;
-
- const u8 column = (mode == EXECUTE ? i_cammu_column : d_cammu_column)[(ssw & SSW_PL) >> 9];
- const u8 access = cammu_matrix[column][(pte & PTE_PL) >> 3];
-
- switch (mode)
- {
- case READ: return access & R;
- case WRITE: return access & W;
- case RMW: return (access & (R | W)) == (R | W);
- case EXECUTE: return access & E;
- }
+ const u8 pl = (pte & PTE_PL) >> 3;
- return false;
+ // special case for user data mode
+ if ((mode != EXECUTE) && !(ssw & SSW_U) && (ssw & SSW_UU))
+ return protection_matrix[(ssw & SSW_KU) ? 2 : 3][pl] & mode;
+ else
+ return protection_matrix[((ssw ^ SSW_K) & (SSW_U | SSW_K)) >> 29][pl] & mode;
}
// C100/C300 CAMMU protection level matrix
-const u8 cammu_c3_device::i_cammu_column[] = { 1, 1, 0, 0, 1, 1, 0, 0, 3, 3, 2, 2, 3, 3, 2, 2 };
-const u8 cammu_c3_device::d_cammu_column[] = { 1, 1, 0, 0, 3, 2, 3, 2, 3, 3, 2, 2, 3, 3, 2, 2 };
-
-const cammu_c3_device::c3_access_t cammu_c3_device::cammu_matrix[][16] =
+const u8 cammu_c3_device::protection_matrix[4][16] =
{
{ RW, RW, RW, RW, RW, RW, RW, RWE, RE, R, R, R, N, N, N, N },
{ N, RW, RW, RW, RW, RW, R, RWE, N, RE, R, R, RE, N, N, N },
diff --git a/src/mame/machine/cammu.h b/src/mame/machine/cammu.h
index 5060fc96518..efd08061d4f 100644
--- a/src/mame/machine/cammu.h
+++ b/src/mame/machine/cammu.h
@@ -120,7 +120,7 @@ public:
template <typename T, typename U> std::enable_if_t<std::is_convertible<U, std::function<T(T)>>::value, bool> modify(const u32 ssw, const u32 address, U &&apply)
{
- translated_t t = translate_address(ssw, address, access_size(sizeof(T)), RMW);
+ translated_t t = translate_address(ssw, address, access_size(sizeof(T)), access_type(READ | WRITE));
if (t.space != nullptr)
{
@@ -145,7 +145,32 @@ public:
switch (sizeof(T))
{
case 2: apply(T(t.space->read_word(t.address))); break;
- case 4: apply(T(t.space->read_dword_unaligned(t.address))); break;
+ case 4:
+ {
+ // check for unaligned access
+ if (address & 0x2)
+ {
+ // check for page span
+ if ((address & CAMMU_PAGE_MASK) == (CAMMU_PAGE_SIZE - 2))
+ {
+ translated_t u = translate_address(ssw, address + 2, access_size(sizeof(u16)), EXECUTE);
+ if (u.space != nullptr)
+ {
+ const u16 lsw = t.space->read_word(t.address);
+ const u16 msw = u.space->read_word(u.address);
+
+ apply((T(msw) << 16) | lsw);
+ }
+ else
+ return false;
+ }
+ else
+ apply(T(t.space->read_dword_unaligned(t.address)));
+ }
+ else
+ apply(T(t.space->read_dword(t.address)));
+ }
+ break;
default: fatalerror("unhandled fetch size %d\n", access_size(sizeof(T)));
}
@@ -177,8 +202,15 @@ protected:
{
READ = 1,
WRITE = 2,
- RMW = 3,
- EXECUTE = 4
+ EXECUTE = 4,
+
+ // matrix abbreviations and combinations
+ N = 0,
+ R = READ,
+ W = WRITE,
+ RW = READ | WRITE,
+ RE = READ | EXECUTE,
+ RWE = READ | WRITE | EXECUTE,
};
private:
@@ -512,20 +544,7 @@ protected:
virtual void set_fault_address(const u32 va) override { m_fault = va; }
private:
- enum c3_access_t : u8
- {
- N = 0, // no access
- R = 1, // read permitted
- W = 2, // write permitted
- RW = 3, // read and write permitted
- E = 4, // execute permitted
- RE = 5, // read and execute permitted
- RWE = 7 // read, write and execute permitted
- };
-
- static const u8 i_cammu_column[];
- static const u8 d_cammu_column[];
- static const c3_access_t cammu_matrix[][16];
+ static const u8 protection_matrix[4][16];
u32 m_s_pdo;
u32 m_u_pdo;
diff --git a/src/mame/machine/interpro_ioga.cpp b/src/mame/machine/interpro_ioga.cpp
index 9804d1eb7a2..0f3c0405546 100644
--- a/src/mame/machine/interpro_ioga.cpp
+++ b/src/mame/machine/interpro_ioga.cpp
@@ -8,14 +8,14 @@
* ROM and diagnostic tests.
*
* The device handles most of the I/O for the system, including timers, DMA,
- * interrupts, and target device interfacing. There is a significant amount of
- * work to be completed before the boot diagnostics will pass without errors,
- * let alone successfully booting CLIX.
+ * interrupts, and target device interfacing.
*
* TODO
- * - edge/level triggered interrupts
- * - make mouse a slot device
- * - improve dma and timers
+ * - tidy up dma control flags
+ * - timer 2 and 3
+ * - correct serial dma per-channel interrupt handling
+ * - multi-channel Ethernet?
+ * - save/restore state
*/
#include "emu.h"
@@ -54,54 +54,8 @@
#define LOGIRQ(irq, ...) do { if (VERBOSE_IRQ & (1U << irq)) (LOG_OUTPUT_FUNC)(__VA_ARGS__); } while (false)
#define LOGDMA(dma, ...) do { if (VERBOSE_DMA & (1U << dma)) (LOG_OUTPUT_FUNC)(__VA_ARGS__); } while (false)
-const interpro_ioga_device::interrupt_data_t interpro_ioga_device::m_interrupt_data[] =
-{
- { INT_HARD_IN, IRQ_TIMER2, IRQ_PENDING | IRQ_ENABLE_EXTERNAL, "internal int 3", "timer 2" }, // either external or internal?
- { INT_HARD_IN, IRQ_TIMER3, IRQ_PENDING | IRQ_ENABLE_EXTERNAL, "internal int 4", "timer 3" }, // either external or internal?
- { INT_HARD_EX, IRQ_SCSI, IRQ_PENDING | IRQ_ENABLE_EXTERNAL, "external int 0", "scsi" }, // IRQ_ENABLE_INTERNAL
- { INT_HARD_EX, IRQ_FLOPPY, IRQ_PENDING | IRQ_ENABLE_EXTERNAL, "external int 1", "floppy" }, // IRQ_ENABLE_INTERNAL
- { INT_HARD_EX, IRQ_PLOTTER, IRQ_PENDING | IRQ_ENABLE_EXTERNAL, "external int 2", "plotter" }, // IRQ_ENABLE_INTERNAL
-
- { INT_HARD_EX, IRQ_SRXCBUS0, IRQ_PENDING | IRQ_ENABLE_EXTERNAL, "external int 3", "srx/cbus 0" },
- { INT_HARD_EX, IRQ_SRXCBUS1, IRQ_PENDING | IRQ_ENABLE_EXTERNAL, "external int 4", "srx/cbus 1" },
- { INT_HARD_EX, IRQ_SRXCBUS2, IRQ_PENDING | IRQ_ENABLE_EXTERNAL, "external int 5", "srx/cbus 2" },
-
- { INT_HARD_EX, IRQ_VB, IRQ_PENDING | IRQ_ENABLE_EXTERNAL, "external int 6", "vb" },
- { INT_HARD_EX, IRQ_9, IRQ_PENDING | IRQ_ENABLE_EXTERNAL, "external int 7", "?" },
- { INT_HARD_EX, IRQ_CBUS3, IRQ_PENDING | IRQ_ENABLE_EXTERNAL, "external int 8", "cbus 3" },
- { INT_HARD_EX, IRQ_RTC, IRQ_PENDING | IRQ_ENABLE_EXTERNAL, "external int 9", "clock/calendar" },
- { INT_HARD_EX, IRQ_60HZ, IRQ_PENDING | IRQ_ENABLE_EXTERNAL, "external int 10", "60Hz" },
-
- { INT_HARD_IN, IRQ_MOUSE, IRQ_PENDING | IRQ_ENABLE_EXTERNAL, "internal int 0", "mouse" },
- { INT_HARD_IN, IRQ_TIMER0, IRQ_PENDING | IRQ_ENABLE_EXTERNAL, "internal int 1", "timer 0" },
- { INT_HARD_IN, IRQ_TIMER1, IRQ_PENDING | IRQ_ENABLE_EXTERNAL, "internal int 2", "timer 1" },
- { INT_HARD_IN, IRQ_SERDMA, IRQ_PENDING | IRQ_ENABLE_EXTERNAL, "internal int 5", "serial dma" }, // IRQ_ENABLE_EXTERNAL << 0 | IRQ_ENABLE_EXTERNAL << 1 | IRQ_ENABLE_EXTERNAL << 2
-
- { INT_HARD_EX, IRQ_SERIAL, IRQ_PENDING | IRQ_ENABLE_EXTERNAL, "external int 11", "serial" },
- { INT_HARD_EX, IRQ_ETHERNET, IRQ_PENDING | IRQ_ENABLE_EXTERNAL, "external int 12", "ethernet" }, // IRQ_ENABLE_INTERNAL
-
- { INT_SOFT_LO, IRQ_SOFT0, 0x0100, "soft int 0", "soft" },
- { INT_SOFT_LO, IRQ_SOFT1, 0x0200, "soft int 1", "soft" },
- { INT_SOFT_LO, IRQ_SOFT2, 0x0400, "soft int 2", "soft" },
- { INT_SOFT_LO, IRQ_SOFT3, 0x0800, "soft int 3", "soft" },
- { INT_SOFT_LO, IRQ_SOFT4, 0x1000, "soft int 4", "soft" },
- { INT_SOFT_LO, IRQ_SOFT5, 0x2000, "soft int 5", "soft" },
- { INT_SOFT_LO, IRQ_SOFT6, 0x4000, "soft int 6", "soft" },
- { INT_SOFT_LO, IRQ_SOFT7, 0x8000, "soft int 7", "soft" },
-
- { INT_SOFT_HI, IRQ_SOFT8, IRQ_PENDING, "soft int 8", "soft" },
- { INT_SOFT_HI, IRQ_SOFT9, IRQ_PENDING, "soft int 9", "soft" },
- { INT_SOFT_HI, IRQ_SOFT10, IRQ_PENDING, "soft int 10", "soft" },
- { INT_SOFT_HI, IRQ_SOFT11, IRQ_PENDING, "soft int 11", "soft" },
- { INT_SOFT_HI, IRQ_SOFT12, IRQ_PENDING, "soft int 12", "soft" },
- { INT_SOFT_HI, IRQ_SOFT13, IRQ_PENDING, "soft int 13", "soft" },
- { INT_SOFT_HI, IRQ_SOFT14, IRQ_PENDING, "soft int 14", "soft" },
- { INT_SOFT_HI, IRQ_SOFT15, IRQ_PENDING, "soft int 15", "soft" },
-};
-
void interpro_ioga_device::map(address_map &map)
{
-
map(0x0c, 0x1b).rw(FUNC(interpro_ioga_device::dma_plotter_r), FUNC(interpro_ioga_device::dma_plotter_w));
map(0x1c, 0x1f).rw(FUNC(interpro_ioga_device::dma_plotter_eosl_r), FUNC(interpro_ioga_device::dma_plotter_eosl_w));
map(0x20, 0x2f).rw(FUNC(interpro_ioga_device::dma_scsi_r), FUNC(interpro_ioga_device::dma_scsi_w));
@@ -113,12 +67,6 @@ void interpro_ioga_device::map(address_map &map)
map(0x50, 0x53).rw(FUNC(interpro_ioga_device::serial_dma2_addr_r), FUNC(interpro_ioga_device::serial_dma2_addr_w));
map(0x54, 0x57).rw(FUNC(interpro_ioga_device::serial_dma2_ctrl_r), FUNC(interpro_ioga_device::serial_dma2_ctrl_w));
- // 5a - sib control?
- //map(0x58, 0x5b).rw(FUNC(interpro_ioga_device::sib_r), FUNC(interpro_ioga_device::sib_w));
- map(0x5c, 0x7f).rw(FUNC(interpro_ioga_device::icr_r), FUNC(interpro_ioga_device::icr_w));
- map(0x80, 0x81).rw(FUNC(interpro_ioga_device::icr18_r), FUNC(interpro_ioga_device::icr18_w));
- map(0x82, 0x82).rw(FUNC(interpro_ioga_device::softint_r), FUNC(interpro_ioga_device::softint_w));
- map(0x83, 0x83).rw(FUNC(interpro_ioga_device::nmictrl_r), FUNC(interpro_ioga_device::nmictrl_w));
map(0x84, 0x87).rw(FUNC(interpro_ioga_device::mouse_status_r), FUNC(interpro_ioga_device::mouse_status_w));
map(0x88, 0x8b).rw(FUNC(interpro_ioga_device::prescaler_r), FUNC(interpro_ioga_device::prescaler_w));
map(0x8c, 0x8f).rw(FUNC(interpro_ioga_device::timer0_r), FUNC(interpro_ioga_device::timer0_w));
@@ -126,14 +74,18 @@ void interpro_ioga_device::map(address_map &map)
map(0x94, 0x97).r(FUNC(interpro_ioga_device::error_address_r));
map(0x98, 0x9b).r(FUNC(interpro_ioga_device::error_businfo_r));
map(0x9c, 0x9d).rw(FUNC(interpro_ioga_device::arbctl_r), FUNC(interpro_ioga_device::arbctl_w));
+}
+
+void emerald_ioga_device::map(address_map &map)
+{
+ interpro_ioga_device::map(map);
- map(0xa0, 0xa3).rw(FUNC(interpro_ioga_device::timer2_count_r), FUNC(interpro_ioga_device::timer2_count_w));
- map(0xa4, 0xa7).rw(FUNC(interpro_ioga_device::timer2_value_r), FUNC(interpro_ioga_device::timer2_value_w));
- map(0xa8, 0xab).rw(FUNC(interpro_ioga_device::timer3_r), FUNC(interpro_ioga_device::timer3_w));
- map(0xac, 0xaf).rw(FUNC(interpro_ioga_device::bus_timeout_r), FUNC(interpro_ioga_device::bus_timeout_w)); // boot writes 0x64
- map(0xb0, 0xbf).rw(FUNC(interpro_ioga_device::softint_vector_r), FUNC(interpro_ioga_device::softint_vector_w));
+ map(0x00, 0x03).rw(FUNC(emerald_ioga_device::eth_base_r), FUNC(emerald_ioga_device::eth_base_w));
+ map(0x04, 0x05).rw(FUNC(emerald_ioga_device::eth_control_r), FUNC(emerald_ioga_device::eth_control_w));
- //c0, c4, c8 -ethernet address a,b,c?
+ map(0x60, 0x83).rw(FUNC(interpro_ioga_device::hardint_r), FUNC(interpro_ioga_device::hardint_w));
+ map(0x82, 0x82).rw(FUNC(interpro_ioga_device::softint_r), FUNC(interpro_ioga_device::softint_w));
+ map(0x83, 0x83).rw(FUNC(interpro_ioga_device::nmictrl_r), FUNC(interpro_ioga_device::nmictrl_w));
}
void turquoise_ioga_device::map(address_map &map)
@@ -143,6 +95,10 @@ void turquoise_ioga_device::map(address_map &map)
map(0x00, 0x03).rw(FUNC(turquoise_ioga_device::eth_base_r), FUNC(turquoise_ioga_device::eth_base_w));
map(0x04, 0x05).rw(FUNC(turquoise_ioga_device::eth_control_r), FUNC(turquoise_ioga_device::eth_control_w));
+ map(0x60, 0x83).rw(FUNC(turquoise_ioga_device::hardint_r), FUNC(turquoise_ioga_device::hardint_w));
+ map(0x82, 0x82).rw(FUNC(turquoise_ioga_device::softint_r), FUNC(turquoise_ioga_device::softint_w));
+ map(0x83, 0x83).rw(FUNC(turquoise_ioga_device::nmictrl_r), FUNC(turquoise_ioga_device::nmictrl_w));
+
//map(0x9e, 0x9f).rw(FUNC(turquoise_ioga_device::?), FUNC(turquoise_ioga_device::?)); // ip2000 boot code writes 0x7f18
}
@@ -153,8 +109,25 @@ void sapphire_ioga_device::map(address_map &map)
map(0x00, 0x03).rw(FUNC(sapphire_ioga_device::eth_remap_r), FUNC(sapphire_ioga_device::eth_remap_w));
map(0x04, 0x07).rw(FUNC(sapphire_ioga_device::eth_mappg_r), FUNC(sapphire_ioga_device::eth_mappg_w));
map(0x08, 0x0b).rw(FUNC(sapphire_ioga_device::eth_control_r), FUNC(sapphire_ioga_device::eth_control_w));
+
+ // 5a - sib control?
+ //map(0x58, 0x5b).rw(FUNC(interpro_ioga_device::sib_r), FUNC(interpro_ioga_device::sib_w));
+
+ map(0x5c, 0x83).rw(FUNC(interpro_ioga_device::hardint_r), FUNC(interpro_ioga_device::hardint_w));
+ map(0x82, 0x82).rw(FUNC(interpro_ioga_device::softint_r), FUNC(interpro_ioga_device::softint_w));
+ map(0x83, 0x83).rw(FUNC(interpro_ioga_device::nmictrl_r), FUNC(interpro_ioga_device::nmictrl_w));
+
+ map(0xa0, 0xa3).rw(FUNC(sapphire_ioga_device::timer2_count_r), FUNC(sapphire_ioga_device::timer2_count_w));
+ map(0xa4, 0xa7).rw(FUNC(sapphire_ioga_device::timer2_value_r), FUNC(sapphire_ioga_device::timer2_value_w));
+ map(0xa8, 0xab).rw(FUNC(sapphire_ioga_device::timer3_r), FUNC(sapphire_ioga_device::timer3_w));
+ map(0xac, 0xaf).rw(FUNC(sapphire_ioga_device::bus_timeout_r), FUNC(sapphire_ioga_device::bus_timeout_w)); // boot writes 0x64
+
+ map(0xb0, 0xbf).rw(FUNC(sapphire_ioga_device::softint_vector_r), FUNC(sapphire_ioga_device::softint_vector_w));
+
+ //c0, c4, c8 -ethernet address a,b,c?
}
+DEFINE_DEVICE_TYPE(EMERALD_IOGA, emerald_ioga_device, "ioga_e", "I/O Gate Array (Emerald)")
DEFINE_DEVICE_TYPE(TURQUOISE_IOGA, turquoise_ioga_device, "ioga_t", "I/O Gate Array (Turquoise)")
DEFINE_DEVICE_TYPE(SAPPHIRE_IOGA, sapphire_ioga_device, "ioga_s", "I/O Gate Array (Sapphire)")
@@ -164,7 +137,7 @@ interpro_ioga_device::interpro_ioga_device(const machine_config &mconfig, device
, m_memory_space(nullptr)
, m_out_nmi_func(*this)
, m_out_irq_func(*this)
- , m_out_ivec_func(*this)
+ , m_out_irq_vector_func(*this)
, m_fdc_tc_func(*this)
, m_eth_ca_func(*this)
, m_dma_channel{
@@ -178,6 +151,11 @@ interpro_ioga_device::interpro_ioga_device(const machine_config &mconfig, device
{
}
+emerald_ioga_device::emerald_ioga_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : interpro_ioga_device(mconfig, EMERALD_IOGA, tag, owner, clock)
+{
+}
+
turquoise_ioga_device::turquoise_ioga_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
: interpro_ioga_device(mconfig, TURQUOISE_IOGA, tag, owner, clock)
{
@@ -200,7 +178,7 @@ void interpro_ioga_device::device_start()
// resolve callbacks
m_out_nmi_func.resolve();
m_out_irq_func.resolve();
- m_out_ivec_func.resolve();
+ m_out_irq_vector_func.resolve();
m_fdc_tc_func.resolve();
m_eth_ca_func.resolve();
@@ -223,23 +201,30 @@ void interpro_ioga_device::device_start()
m_timer0 = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(interpro_ioga_device::timer0), this));
m_timer1 = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(interpro_ioga_device::timer1), this));
- m_timer2 = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(interpro_ioga_device::timer2), this));
- m_timer3 = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(interpro_ioga_device::timer3), this));
m_timer_60hz = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(interpro_ioga_device::timer_60hz), this));
- m_mouse_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(interpro_ioga_device::mouse_timer), this));
m_eth_reset_timer = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(interpro_ioga_device::eth_reset), this));
}
+void sapphire_ioga_device::device_start()
+{
+ interpro_ioga_device::device_start();
+
+ m_timer2 = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(sapphire_ioga_device::timer2), this));
+ m_timer3 = machine().scheduler().timer_alloc(timer_expired_delegate(FUNC(sapphire_ioga_device::timer3), this));
+}
+
void interpro_ioga_device::device_reset()
{
// initialise interrupt state
- m_active_interrupt = nullptr;
+ m_active_interrupt_type = INT_NONE;
m_nmi_state = CLEAR_LINE;
m_irq_state = CLEAR_LINE;
- m_ivec = 0;
- m_hwint_forced = 0;
+ m_irq_vector = 0;
+ m_line_state = 0;
+
+ m_hwicr = std::make_unique<u16[]>(get_int_count());
// initialise dma state
for (dma_channel_t &dma_channel : m_dma_channel)
@@ -255,21 +240,40 @@ void interpro_ioga_device::device_reset()
m_timer0->enable(false);
m_timer1->enable(false);
- m_timer2->enable(false);
- m_timer3->enable(false);
- m_mouse_timer->enable(false);
m_eth_reset_timer->enable(false);
m_timer0_count = 0;
m_timer1_count = 0;
+
+ m_timer_60hz->adjust(attotime::zero, 0, attotime::from_hz(60));
+
+ m_prescaler = 0;
+}
+
+void sapphire_ioga_device::device_reset()
+{
+ interpro_ioga_device::device_reset();
+
+ m_timer2->enable(false);
+ m_timer3->enable(false);
+
m_timer2_count = 0;
m_timer2_value = 0;
m_timer3_count = 0;
+}
- m_timer_60hz->adjust(attotime::zero, 0, attotime::from_hz(60));
+/*
+ * Interrupts
+ */
+WRITE32_MEMBER(interpro_ioga_device::bus_error)
+{
+ LOG("bus_error address 0x%08x businfo 0x%08x\n", data, offset);
- m_prescaler = 0;
+ m_error_address = data;
+ m_error_businfo = offset;
+
+ set_nmi_line(ASSERT_LINE);
}
void interpro_ioga_device::set_nmi_line(int state)
@@ -294,219 +298,318 @@ void interpro_ioga_device::set_nmi_line(int state)
nmi(CLEAR_LINE);
}
-void interpro_ioga_device::set_int_line(interrupt_type type, int number, int state)
+void interpro_ioga_device::nmi(int state)
{
- LOGIRQ(number, "irq: set_int_line(%d, %d, %d)\n", type, number, state);
-#if 0
- // preliminary edge/level triggered interrupt handling
- if (type == INT_HARD_IN || type == INT_HARD_EX)
+ if (m_nmi_state != state)
{
- /*
- * existing new type result
- * clear clear edge nothing
- * clear assert edge pending if not masked
- * assert clear edge nothing
- * assert assert edge nothing
-
- * clear clear level nothing
- * clear assert level pending
- * assert clear level !pending
- * assert assert level nothing
- */
-
- u16 icr = get_icr(type, number);
- u32 mask = 1 << number;
-
- if (icr & IRQ_EDGE)
- {
- if ((m_line_state & mask) == 0 && state)
- set_pending(type, number, true);
- }
- else
- {
- if (((m_line_state & mask) == 0) ^ (state != ASSERT_LINE))
- set_pending(type, number, state == ASSERT_LINE);
- }
-
- m_line_state = (state == ASSERT_LINE) ? (m_line_state | mask) : (m_line_state & ~mask);
+ m_nmi_state = state;
+ m_out_nmi_func(state);
}
- else
-#else
- (void)m_line_state;
-#endif
- set_pending(type, number, state == ASSERT_LINE);
-
- m_interrupt_timer->adjust(attotime::zero);
}
-/*
- * Interrupts
- */
-IRQ_CALLBACK_MEMBER(interpro_ioga_device::acknowledge_interrupt)
+void interpro_ioga_device::set_int_line(int number, int state)
{
- switch (irqline)
+ const u8 offset = get_reg_offset(number);
+
+ LOGIRQ(number, "irq: hard interrupt %d state %d\n", number, state);
+
+ if (state == CLEAR_LINE)
{
- case INPUT_LINE_IRQ0:
- // clear pending flag
- set_pending(m_active_interrupt->type, m_active_interrupt->number, false);
+ m_line_state &= ~(1 << number);
+ return;
+ }
- // clear irq/ivec
- irq(CLEAR_LINE, 0);
+ // check already pending
+ if (m_hwicr[offset] & IRQ_PENDING)
+ return;
- m_active_interrupt = nullptr;
- break;
+ // record line state for level triggered interrupts
+ if (!(m_hwicr[offset] & IRQ_EDGE))
+ m_line_state |= (1 << number);
- case INPUT_LINE_NMI:
- nmi(CLEAR_LINE);
- break;
- }
+ // check enabled
+ if ((number != IRQ_SERDMA && !(m_hwicr[offset] & (IRQ_ENABLE | IRQ_ENABLE_INT)))
+ || ((number == IRQ_SERDMA && !(m_hwicr[offset] & IRQ_ENABLE_SERDMA))))
+ return;
- m_interrupt_timer->adjust(attotime::zero);
+ // set pending
+ if (BIT(m_line_state, number) || (m_hwicr[offset] & IRQ_EDGE))
+ {
+ LOGIRQ(number, "irq: hard interrupt %d pending\n", number);
+ m_hwicr[offset] |= IRQ_PENDING;
- return 0;
+ // schedule interrupt check
+ m_interrupt_timer->adjust(attotime::zero);
+ }
}
TIMER_CALLBACK_MEMBER(interpro_ioga_device::interrupt_check)
{
- // find highest priority unmasked pending interrupt
- u16 ivec = m_ivec;
- for (const interrupt_data_t &interrupt : m_interrupt_data)
- {
- u16 icr = get_icr(interrupt.type, interrupt.number);
+ // find highest priority pending interrupt
+ u16 irq_vector = get_irq_vector();
- // test for pending and not masked
- if ((icr & interrupt.mask) == interrupt.mask)
+ // hard interrupts
+ for (u8 i = 0; i < get_int_count(); i++)
+ {
+ // test interrupt pending
+ if (m_hwicr[i] & IRQ_PENDING)
{
// check priority
- if (m_active_interrupt == nullptr || (icr & IRQ_VECTOR) < ivec)
+ if (m_active_interrupt_type == INT_NONE || (m_hwicr[i] & IRQ_VECTOR) < irq_vector)
{
- m_active_interrupt = &interrupt;
- ivec = icr & IRQ_VECTOR;
+ m_active_interrupt_type = INT_HARD;
+ m_active_interrupt_number = i;
+
+ irq_vector = m_hwicr[i] & IRQ_VECTOR;
+ }
+ }
+ }
+
+ // soft interrupts
+ if (m_softint)
+ {
+ for (u8 i = 0; i < 8; i++)
+ {
+ // test interrupt pending
+ if (m_softint & (1 << i))
+ {
+ // check priority
+ if (m_active_interrupt_type == INT_NONE || (0x8f + i * 0x10) < irq_vector)
+ {
+ m_active_interrupt_type = INT_SOFT;
+ m_active_interrupt_number = i;
+
+ irq_vector = 0x8f + i * 0x10;
+ }
}
}
}
// assert irq and ivec
- if (m_active_interrupt != nullptr)
- irq(ASSERT_LINE, ivec);
+ if (m_active_interrupt_type != INT_NONE)
+ irq(ASSERT_LINE, irq_vector);
}
-void interpro_ioga_device::set_pending(interrupt_type type, int number, bool pending)
+TIMER_CALLBACK_MEMBER(sapphire_ioga_device::interrupt_check)
{
- switch (type)
+ // find highest priority pending interrupt
+ u16 irq_vector = get_irq_vector();
+
+ // hard interrupts
+ for (u8 i = 0; i < get_int_count(); i++)
{
- case INT_HARD_IN:
- case INT_HARD_EX:
- if (pending)
- m_hwicr[number] |= IRQ_PENDING;
- else
- m_hwicr[number] &= ~IRQ_PENDING;
- break;
+ // test interrupt pending
+ if (m_hwicr[i] & IRQ_PENDING)
+ {
+ // check priority
+ if (m_active_interrupt_type == INT_NONE || (m_hwicr[i] & IRQ_VECTOR) < irq_vector)
+ {
+ m_active_interrupt_type = INT_HARD;
+ m_active_interrupt_number = i;
- case INT_SOFT_LO:
- if (pending)
- m_softint |= (1 << number);
- else
- m_softint &= ~(1 << number);
- break;
+ irq_vector = m_hwicr[i] & IRQ_VECTOR;
+ }
+ }
+ }
- case INT_SOFT_HI:
- if (pending)
- m_swicr[number] |= IRQ_PENDING;
- else
- m_swicr[number] &= ~IRQ_PENDING;
- break;
+ // soft interrupts (low type)
+ if (m_softint)
+ {
+ for (u8 i = 0; i < 8; i++)
+ {
+ // test interrupt pending
+ if (m_softint & (1 << i))
+ {
+ // check priority
+ if (m_active_interrupt_type == INT_NONE || (0x8f + i * 0x10) < irq_vector)
+ {
+ m_active_interrupt_type = INT_SOFT;
+ m_active_interrupt_number = i;
+
+ irq_vector = 0x8f + i * 0x10;
+ }
+ }
+ }
}
-}
-bool interpro_ioga_device::nmi(int state)
-{
- if (m_nmi_state != state)
+ // soft interrupts (high type)
+ for (u8 i = 0; i < 8; i++)
{
- m_nmi_state = state;
- m_out_nmi_func(state);
+ // test interrupt pending
+ if (m_swicr[i] & IRQ_PENDING)
+ {
+ // check priority
+ if (m_active_interrupt_type == INT_NONE || (m_swicr[i] & IRQ_VECTOR) < irq_vector)
+ {
+ m_active_interrupt_type = INT_SOFT;
+ m_active_interrupt_number = i + 8;
- return true;
+ irq_vector = m_swicr[i] & IRQ_VECTOR;
+ }
+ }
}
- else
- return false;
+
+ // assert irq and ivec
+ if (m_active_interrupt_type != INT_NONE)
+ irq(ASSERT_LINE, irq_vector);
}
-bool interpro_ioga_device::irq(int state, u8 ivec)
+void interpro_ioga_device::irq(int state, u8 irq_vector)
{
- if (ivec != m_ivec)
+ if (irq_vector != m_irq_vector)
{
- LOGIRQ(m_active_interrupt->number, "setting ivec 0x%02x\n", ivec);
+ LOGIRQ(m_active_interrupt_number, "irq: setting irq vector 0x%02x\n", irq_vector);
- m_ivec = ivec;
- machine().scheduler().synchronize(timer_expired_delegate(FUNC(interpro_ioga_device::set_ivec), this));
+ m_irq_vector = irq_vector;
+ machine().scheduler().synchronize(timer_expired_delegate(FUNC(interpro_ioga_device::set_irq_vector), this));
}
if (m_irq_state != state)
{
- LOGIRQ(m_active_interrupt->number, "%s %s number %d source %s\n",
- state ? "asserting" : "clearing", m_active_interrupt->name, m_active_interrupt->number, m_active_interrupt->source);
+ LOGIRQ(m_active_interrupt_number, "irq: %s interrupt type %d number %d\n",
+ state ? "asserting" : "clearing",m_active_interrupt_type, m_active_interrupt_number);
m_irq_state = state;
m_out_irq_func(state);
- return true;
+ if (state == CLEAR_LINE)
+ m_active_interrupt_type = INT_NONE;
}
- else
- return false;
}
-TIMER_CALLBACK_MEMBER(interpro_ioga_device::set_ivec)
+IRQ_CALLBACK_MEMBER(interpro_ioga_device::acknowledge_interrupt)
{
- m_out_ivec_func(m_ivec);
+ switch (irqline)
+ {
+ case INPUT_LINE_IRQ0:
+ LOGIRQ(m_active_interrupt_number, "irq: interrupt type %d number %d acknowledged\n",
+ m_active_interrupt_type, m_active_interrupt_number);
+
+ // clear pending
+ switch (m_active_interrupt_type)
+ {
+ case INT_HARD:
+ m_hwicr[m_active_interrupt_number] &= ~IRQ_PENDING;
+ break;
+
+ case INT_SOFT:
+ m_softint &= ~(1 << m_active_interrupt_number);
+ break;
+
+ default:
+ // can't happen
+ fatalerror("irq: interrupt acknowledged without active interrupt\n");
+ break;
+ }
+
+ // clear irq and irq vector
+ irq(CLEAR_LINE, 0);
+ break;
+
+ case INPUT_LINE_NMI:
+ nmi(CLEAR_LINE);
+ break;
+ }
+
+ // schedule interrupt check
+ m_interrupt_timer->adjust(attotime::zero);
+
+ return 0;
}
-u16 interpro_ioga_device::get_icr(interrupt_type type, int number) const
+IRQ_CALLBACK_MEMBER(sapphire_ioga_device::acknowledge_interrupt)
{
- switch (type)
+ switch (irqline)
{
- case INT_HARD_IN:
- case INT_HARD_EX:
- return m_hwicr[number];
+ case INPUT_LINE_IRQ0:
+ LOGIRQ(m_active_interrupt_number, "irq: interrupt type %d number %d acknowledged\n",
+ m_active_interrupt_type, m_active_interrupt_number);
- case INT_SOFT_LO:
- return (m_softint << 8) | (0x8f + number * 0x10);
+ // clear pending
+ switch (m_active_interrupt_type)
+ {
+ case INT_HARD:
+ m_hwicr[m_active_interrupt_number] &= ~IRQ_PENDING;
+ break;
+
+ case INT_SOFT:
+ if (m_active_interrupt_number < 8)
+ m_softint &= ~(1 << m_active_interrupt_number);
+ else
+ m_swicr[m_active_interrupt_number - 8] &= ~IRQ_PENDING;
+ break;
+
+ default:
+ // can't happen
+ fatalerror("irq: interrupt acknowledged without active interrupt\n");
+ break;
+ }
- case INT_SOFT_HI:
- return m_swicr[number];
+ // clear irq and irq vector
+ irq(CLEAR_LINE, 0);
+ break;
+
+ case INPUT_LINE_NMI:
+ nmi(CLEAR_LINE);
+ break;
}
+ // schedule interrupt check
+ m_interrupt_timer->adjust(attotime::zero);
+
return 0;
}
-WRITE16_MEMBER(interpro_ioga_device::icr_w)
+WRITE16_MEMBER(interpro_ioga_device::hardint_w)
{
- /*
- * It appears that writing the pending flag high and then low again is
- * intended to force an interrupt to be generated. We record the initial
- * write in m_hwint_forced, and when a subsequent write occurrs, turn the
- * pending bit on to trigger the interrupt.
- *
- * FIXME: should we only flag a forced interrupt if pending is written high
- * from low? Maybe all of this can be eliminated by the edge/level trigger
- * logic in the future.
- */
+ const int number = get_int_number(offset);
+ bool force = false;
- LOGIRQ(offset, "irq: interrupt vector %d = 0x%04x (%s)\n", offset, data, machine().describe_context());
+ LOGIRQ(offset, "irq: interrupt %d offset 0x%02x data 0x%04x mem_mask 0x%04x (%s)\n", number, offset, data, mem_mask, machine().describe_context());
- // store all bits except pending
- m_hwicr[offset] = (m_hwicr[offset] & IRQ_PENDING) | (data & ~IRQ_PENDING);
+ if (!(m_hwicr[offset] & IRQ_PENDING))
+ {
+ // handle forcing
+ if (data & IRQ_PENDING)
+ {
+ LOGIRQ(number, "irq: interrupt %d force pending\n", number);
- // scan for pending interrupts
- m_interrupt_timer->adjust(attotime::zero);
+ // set force pending
+ m_force_state |= (1 << number);
+ }
+ else if (BIT(m_force_state, number))
+ {
+ LOGIRQ(number, "irq: interrupt %d forced\n", number);
+
+ // clear force pending
+ m_force_state &= ~(1 << number);
+
+ // force the interrupt
+ force = true;
+ }
+ }
+
+ // store the data
+ mem_mask &= ~IRQ_PENDING;
+ COMBINE_DATA(&m_hwicr[offset]);
+
+ if (force)
+ {
+ // force an interrupt
+ set_int_line(number, ASSERT_LINE);
+ set_int_line(number, CLEAR_LINE);
+ }
+ else if (m_line_state & (1 << number))
+ // re-assert line
+ set_int_line(number, ASSERT_LINE);
}
WRITE8_MEMBER(interpro_ioga_device::softint_w)
{
// store the written value
- // FIXME: forced interrupt handling
- COMBINE_DATA(&m_softint);
+ m_softint |= data;
+ // schedule interrupt check
m_interrupt_timer->adjust(attotime::zero);
}
@@ -515,23 +618,51 @@ WRITE8_MEMBER(interpro_ioga_device::nmictrl_w)
// check for a forced nmi (NMI_NEGPOL written from 1 to 0 with NMI_IE set)
const bool forced = (m_nmictrl & NMI_NEGPOL) && ((data & (NMI_NEGPOL | NMI_IE)) == NMI_IE);
- LOGMASKED(LOG_NMI, "nmi: nmictrl = 0x%02x (%s)\n", data, machine().describe_context());
+ LOGMASKED(LOG_NMI, "nmi: nmictrl 0x%02x (%s)\n", data, machine().describe_context());
m_nmictrl = data;
if (forced)
{
- LOGMASKED(LOG_NMI, "nmi: forcing nmi\n");
+ LOGMASKED(LOG_NMI, "nmi: forced\n");
set_nmi_line(ASSERT_LINE);
}
}
-WRITE16_MEMBER(interpro_ioga_device::softint_vector_w)
+WRITE16_MEMBER(sapphire_ioga_device::softint_vector_w)
{
- // store the written value
+ const int number = offset + 8;
+
+ LOG("irq: soft interrupt %d data 0x%04x\n", number, data);
+
+ if (!(m_swicr[offset] & IRQ_PENDING))
+ {
+ // handle forcing
+ if (data & IRQ_PENDING)
+ {
+ LOG("irq: soft interrupt %d force pending\n", number);
+
+ // set force pending
+ m_force_state |= (1 << (offset + 24));
+
+ mem_mask &= ~IRQ_PENDING;
+ }
+ else if (BIT(m_force_state, offset + 24))
+ {
+ LOG("irq: soft interrupt %d forced\n", number);
+
+ // clear force pending
+ m_force_state &= ~(1 << (offset + 24));
+
+ // set interrupt pending
+ data |= IRQ_PENDING;
+ }
+ }
+
+ // update the register
COMBINE_DATA(&m_swicr[offset]);
- // force interrupt if needed
+ // schedule interrupt check
m_interrupt_timer->adjust(attotime::zero);
}
@@ -558,36 +689,8 @@ TIMER_CALLBACK_MEMBER(interpro_ioga_device::dma)
if (!(m_arbctl & dma_channel.arb_mask))
continue;
- // translate address when DMA_CTRL_VIRTUAL is set
- // FIXME: what happens when we span a page?
- if (dma_channel.control & DMA_CTRL_VIRTUAL)
- {
- const u32 ptde = m_memory_space->read_dword(dma_channel.virtual_address);
-
- if ((ptde & 0x1) == 0)
- {
- dma_channel.real_address = (ptde & ~0xfff) | (dma_channel.real_address & 0xfff);
- dma_channel.control &= ~DMA_CTRL_VIRTUAL;
-
- LOGDMA(dma_channel.channel, "dma: translated virtual 0x%08x real 0x%08x\n", dma_channel.virtual_address, dma_channel.real_address);
-
- // FIXME: what about protection levels and system tags?
-
- // set referenced and dirty page table entry flags
- m_memory_space->write_dword(dma_channel.virtual_address, ptde | ((dma_channel.control & DMA_CTRL_WRITE) ? 0x2 : 0x6));
- }
- else
- {
- // page fault
- // FIXME: error status
- dma_channel.control |= DMA_CTRL_BERR | DMA_CTRL_ERR;
- LOGDMA(dma_channel.channel, "dma: page fault translating virtual address 0x%08x ptde 0x%08x\n", dma_channel.virtual_address, ptde);
- break;
- }
- }
-
- //LOGDMA(dma_channel.channel, "dma: transfer %s device begun, channel = %d, control 0x%08x, real address 0x%08x, virtual address 0x%08x, count 0x%08x\n",
- // (dma_channel.control & DMA_CTRL_WRITE) ? "to" : "from", dma_channel.channel, dma_channel.control, dma_channel.real_address, dma_channel.virtual_address, dma_channel.transfer_count);
+ if (dma_channel.control & DMA_CTRL_BERR)
+ continue;
// transfer from the memory to device or device to memory
while (dma_channel.transfer_count && dma_channel.drq_state)
@@ -603,22 +706,29 @@ TIMER_CALLBACK_MEMBER(interpro_ioga_device::dma)
dma_channel.transfer_count--;
// check for page wrap
- if ((dma_channel.real_address & 0xfff) == 0)
+ if ((dma_channel.real_address & 0xfff) == 0 && dma_channel.transfer_count)
{
LOGDMA(dma_channel.channel, "dma: wrapped to next memory page\n");
- dma_channel.virtual_address += 4;
- dma_channel.control |= DMA_CTRL_VIRTUAL;
+ // translate virtual address
+ if (dma_channel.control & DMA_CTRL_VIRTUAL)
+ {
+ const u32 ptde = m_memory_space->read_dword(dma_channel.virtual_address);
+ dma_channel.virtual_address += 4;
+
+ // FIXME: ignore the page fault flag?
+ dma_channel.real_address = ptde & ~0xfff;
- m_dma_timer->adjust(attotime::zero);
- break;
+ LOGDMA(dma_channel.channel, "dma: translated virtual 0x%08x real 0x%08x\n",
+ dma_channel.virtual_address, dma_channel.real_address);
+ }
}
}
// check if the transfer is complete
if (dma_channel.transfer_count == 0)
{
- LOGDMA(dma_channel.channel, "dma: transfer %s device ended, channel = %d, control 0x%08x, real address 0x%08x, virtual address 0x%08x, count 0x%08x\n",
+ LOGDMA(dma_channel.channel, "dma: transfer %s device ended channel %d control 0x%08x real address 0x%08x virtual address 0x%08x count 0x%08x\n",
(dma_channel.control & DMA_CTRL_WRITE) ? "to" : "from", dma_channel.channel, dma_channel.control, dma_channel.real_address, dma_channel.virtual_address, dma_channel.transfer_count);
if (dma_channel.channel == DMA_FLOPPY)
@@ -713,7 +823,8 @@ void interpro_ioga_device::drq(int state, int channel)
// log every 256 bytes
if ((dma_channel.transfer_count & 0xff) == 0)
- LOGDMA(channel, "dma: drq for channel %d %s transfer_count 0x%08x\n", channel, state ? "asserted" : "deasserted", dma_channel.transfer_count);
+ LOGDMA(channel, "dma: drq for channel %d %s transfer_count 0x%08x\n",
+ channel, state ? "asserted" : "deasserted", dma_channel.transfer_count);
if (state)
m_dma_timer->adjust(attotime::zero);
@@ -735,7 +846,7 @@ u32 interpro_ioga_device::dma_r(address_space &space, offs_t offset, u32 mem_mas
return dma_channel.transfer_count;
case 3:
- return dma_channel.control;
+ return dma_channel.control & ~DMA_CTRL_VIRTUAL;
default:
logerror("dma_r: unknown dma register %d\n", offset);
@@ -760,8 +871,6 @@ void interpro_ioga_device::dma_w(address_space &space, offs_t offset, u32 data,
channel, data, mem_mask, machine().describe_context());
COMBINE_DATA(&dma_channel.virtual_address);
dma_channel.virtual_address &= ~0x3;
-
- dma_channel.control |= DMA_CTRL_VIRTUAL;
break;
case 2:
@@ -773,14 +882,28 @@ void interpro_ioga_device::dma_w(address_space &space, offs_t offset, u32 data,
break;
case 3:
- dma_channel.control = (data & mem_mask & DMA_CTRL_WMASK) | (dma_channel.control & (~mem_mask | ~DMA_CTRL_WMASK));
+ LOGDMA(channel, "dma: channel %d control 0x%08x mem_mask 0x%08x (%s)\n",
+ channel, data, mem_mask, machine().describe_context());
+
+ dma_channel.control = (data & mem_mask & (DMA_CTRL_WMASK|DMA_CTRL_VIRTUAL)) | (dma_channel.control & (~mem_mask | ~(DMA_CTRL_WMASK|DMA_CTRL_VIRTUAL)));
+
+ // translate virtual address
+ if (data & DMA_CTRL_VIRTUAL)
+ {
+ const u32 ptde = m_memory_space->read_dword(dma_channel.virtual_address);
+ dma_channel.virtual_address += 4;
+
+ // FIXME: ignore the page fault flag?
+ dma_channel.real_address = (ptde & ~0xfff) | (dma_channel.real_address & 0xfff);
+
+ LOGDMA(dma_channel.channel, "dma: translated virtual 0x%08x real 0x%08x\n",
+ dma_channel.virtual_address, dma_channel.real_address);
+ }
// (7.0272) if bus error flag is written, clear existing bus error (otherwise retain existing state)
if (data & DMA_CTRL_BERR)
dma_channel.control &= ~DMA_CTRL_BERR;
- LOGDMA(channel, "dma: channel %d control 0x%08x mem_mask 0x%08x result 0x%08x (%s)\n",
- channel, data, mem_mask, dma_channel.control, machine().describe_context());
break;
}
}
@@ -811,7 +934,8 @@ TIMER_CALLBACK_MEMBER(interpro_ioga_device::serial_dma)
{
u8 data = m_memory_space->read_byte(dma_channel.address);
- LOGMASKED(LOG_SERIALDMA, "dma: transmitting byte 0x%02x to serial channel %d\n", data, dma_channel.channel);
+ LOGMASKED(LOG_SERIALDMA, "dma: transmitting byte 0x%02x to serial channel %d\n",
+ data, dma_channel.channel);
dma_channel.device_w(data);
}
@@ -819,7 +943,8 @@ TIMER_CALLBACK_MEMBER(interpro_ioga_device::serial_dma)
{
u8 data = dma_channel.device_r();
- LOGMASKED(LOG_SERIALDMA, "dma: receiving byte 0x%02x from serial channel %d\n", data, dma_channel.channel);
+ LOGMASKED(LOG_SERIALDMA, "dma: receiving byte 0x%02x from serial channel %d\n",
+ data, dma_channel.channel);
m_memory_space->write_byte(dma_channel.address, data);
}
@@ -835,7 +960,7 @@ TIMER_CALLBACK_MEMBER(interpro_ioga_device::serial_dma)
dma_channel.control |= SDMA_TCZERO;
// raise an interrupt
- set_int_line(INT_HARD_IN, IRQ_SERDMA, ASSERT_LINE);
+ set_int_line(IRQ_SERDMA, ASSERT_LINE);
}
}
}
@@ -846,7 +971,8 @@ void interpro_ioga_device::serial_drq(int state, int channel)
dma_channel.drq_state = state;
- LOGMASKED(LOG_SERIALDMA, "dma: drq for serial channel %d %s count 0x%04x\n", channel, state ? "asserted" : "deasserted", dma_channel.control & SDMA_COUNT);
+ LOGMASKED(LOG_SERIALDMA, "dma: drq for serial channel %d %s count 0x%04x\n",
+ channel, state ? "asserted" : "deasserted", dma_channel.control & SDMA_COUNT);
if (state && (dma_channel.control & SDMA_COUNT))
m_serial_dma_timer->adjust(attotime::zero);
@@ -854,7 +980,8 @@ void interpro_ioga_device::serial_drq(int state, int channel)
void interpro_ioga_device::serial_dma_addr_w(address_space &space, offs_t offset, u32 data, u32 mem_mask, int channel)
{
- LOGMASKED(LOG_SERIALDMA, "dma: serial channel %d address 0x%08x mask 0x%08x (%s)\n", channel, data, mem_mask, machine().describe_context());
+ LOGMASKED(LOG_SERIALDMA, "dma: serial channel %d address 0x%08x mask 0x%08x (%s)\n",
+ channel, data, mem_mask, machine().describe_context());
COMBINE_DATA(&m_serial_dma_channel[channel].address);
}
@@ -863,7 +990,8 @@ void interpro_ioga_device::serial_dma_ctrl_w(address_space &space, offs_t offset
{
serial_dma_channel_t &dma_channel = m_serial_dma_channel[channel];
- LOGMASKED(LOG_SERIALDMA, "dma: serial channel %d control 0x%08x mask 0x%08x (%s)\n", channel, data, mem_mask, machine().describe_context());
+ LOGMASKED(LOG_SERIALDMA, "dma: serial channel %d control 0x%08x mask 0x%08x (%s)\n",
+ channel, data, mem_mask, machine().describe_context());
COMBINE_DATA(&dma_channel.control);
@@ -876,7 +1004,8 @@ void interpro_ioga_device::serial_dma_ctrl_w(address_space &space, offs_t offset
*/
WRITE16_MEMBER(interpro_ioga_device::arbctl_w)
{
- LOGMASKED(LOG_DMA | LOG_SERIALDMA, "dma: arbctl = 0x%04x (%s)\n", data, machine().describe_context());
+ LOGMASKED(LOG_DMA | LOG_SERIALDMA, "dma: arbctl = 0x%04x (%s)\n",
+ data, machine().describe_context());
m_arbctl = data;
@@ -901,23 +1030,24 @@ READ32_MEMBER(interpro_ioga_device::error_businfo_r)
*/
READ32_MEMBER(interpro_ioga_device::timer0_r)
{
- LOGMASKED(LOG_TIMERRD, "timer0_r data 0x%08x mask 0x%08x (%s)\n", m_timer0_count, mem_mask, machine().describe_context());
+ LOGMASKED(LOG_TIMERRD, "timer0_r data 0x%08x mask 0x%08x (%s)\n",
+ m_timer0_count, mem_mask, machine().describe_context());
return m_timer0_count;
}
WRITE32_MEMBER(interpro_ioga_device::timer0_w)
{
- LOGMASKED(LOG_TIMER0, "timer0_w data 0x%08x mask 0x%08x prescaler 0x%08x (%s)\n", data, mem_mask, m_prescaler, machine().describe_context());
+ LOGMASKED(LOG_TIMER0, "timer0_w data 0x%08x mask 0x%08x prescaler 0x%08x (%s)\n",
+ data, mem_mask, m_prescaler, machine().describe_context());
// store the timer count value
m_timer0_count = data;
// restart the timer
- //if (m_prescaler & 0xffff)
- // m_timer0->adjust(attotime::zero, 0, attotime::from_ticks(m_prescaler & 0xffff, 60_Hz_XTAL));
- //else
- m_timer0->adjust(attotime::zero, 0, attotime::from_hz(60_Hz_XTAL));
+ attotime period = attotime::from_ticks(m_prescaler ? m_prescaler & 0xffff : 0x10000, 10_MHz_XTAL);
+
+ m_timer0->adjust(period, 0, period);
}
TIMER_CALLBACK_MEMBER(interpro_ioga_device::timer0)
@@ -931,14 +1061,15 @@ TIMER_CALLBACK_MEMBER(interpro_ioga_device::timer0)
m_timer0->enable(false);
// raise an interrupt
- if (m_hwicr[IRQ_TIMER0] & IRQ_ENABLE_EXTERNAL)
- set_int_line(INT_HARD_IN, IRQ_TIMER0, ASSERT_LINE);
+ set_int_line(IRQ_TIMER0, ASSERT_LINE);
+ set_int_line(IRQ_TIMER0, CLEAR_LINE);
}
}
TIMER_CALLBACK_MEMBER(interpro_ioga_device::timer_60hz)
{
- set_int_line(INT_HARD_EX, IRQ_60HZ, ASSERT_LINE);
+ set_int_line(IRQ_60HZ, ASSERT_LINE);
+ set_int_line(IRQ_60HZ, CLEAR_LINE);
}
READ32_MEMBER(interpro_ioga_device::timer1_r)
@@ -951,7 +1082,8 @@ READ32_MEMBER(interpro_ioga_device::timer1_r)
else if (m_timer1->param())
result |= TIMER1_EXPIRED;
- LOGMASKED(LOG_TIMERRD, "timer1_r data 0x%08x mask 0x%08x (%s)\n", result, mem_mask, machine().describe_context());
+ LOGMASKED(LOG_TIMERRD, "timer1_r data 0x%08x mask 0x%08x (%s)\n",
+ result, mem_mask, machine().describe_context());
return result;
}
@@ -967,10 +1099,12 @@ WRITE32_MEMBER(interpro_ioga_device::timer1_w)
// start the timer if necessary
if (data & TIMER1_START)
{
- LOGMASKED(LOG_TIMER1, "timer1_w data 0x%08x mask 0x%08x prescaler 0x%08x (%s)\n", data, mem_mask, m_prescaler, machine().describe_context());
+ LOGMASKED(LOG_TIMER1, "timer1_w data 0x%08x mask 0x%08x prescaler 0x%08x (%s)\n",
+ data, mem_mask, m_prescaler, machine().describe_context());
- // theory: timer 1 is 1MHz (typical prescaler value of 1000 and timer value of 100 giving a delay of 100ms)
- m_timer1->adjust(attotime::zero, false, attotime::from_usec((m_prescaler & 0xffff) / 50));
+ attotime period = attotime::from_ticks(m_prescaler ? m_prescaler & 0xffff : 0x10000, 10_MHz_XTAL);
+
+ m_timer1->adjust(period, 0, period);
}
}
@@ -986,44 +1120,48 @@ TIMER_CALLBACK_MEMBER(interpro_ioga_device::timer1)
// disable timer and set the zero flag
m_timer1->enable(false);
- m_timer1->set_param(true);
+ m_timer1->set_param(1);
- // throw an interrupt
- if (m_hwicr[IRQ_TIMER1] & IRQ_ENABLE_EXTERNAL)
- set_int_line(INT_HARD_IN, IRQ_TIMER1, ASSERT_LINE);
+ // raise an interrupt
+ set_int_line(IRQ_TIMER1, ASSERT_LINE);
+ set_int_line(IRQ_TIMER1, CLEAR_LINE);
}
}
-READ32_MEMBER(interpro_ioga_device::timer2_count_r)
+READ32_MEMBER(sapphire_ioga_device::timer2_count_r)
{
- LOGMASKED(LOG_TIMERRD, "timer2_count_r data 0x%08x mask 0x%08x (%s)\n", m_timer2_count, mem_mask, machine().describe_context());
+ LOGMASKED(LOG_TIMERRD, "timer2_count_r data 0x%08x mask 0x%08x (%s)\n",
+ m_timer2_count, mem_mask, machine().describe_context());
return m_timer2_count;
}
-WRITE32_MEMBER(interpro_ioga_device::timer2_count_w)
+WRITE32_MEMBER(sapphire_ioga_device::timer2_count_w)
{
m_timer2_count = data;
- LOGMASKED(LOG_TIMER2, "timer2_count_w data 0x%08x mask 0x%08x (%s)\n", data, mem_mask, machine().describe_context());
+ LOGMASKED(LOG_TIMER2, "timer2_count_w data 0x%08x mask 0x%08x (%s)\n",
+ data, mem_mask, machine().describe_context());
}
-READ32_MEMBER(interpro_ioga_device::timer2_value_r)
+READ32_MEMBER(sapphire_ioga_device::timer2_value_r)
{
- LOGMASKED(LOG_TIMERRD, "timer2_value_r data 0x%08x mask 0x%08x (%s)\n", m_timer2_value, mem_mask, machine().describe_context());
+ LOGMASKED(LOG_TIMERRD, "timer2_value_r data 0x%08x mask 0x%08x (%s)\n",
+ m_timer2_value, mem_mask, machine().describe_context());
return m_timer2_value;
}
-WRITE32_MEMBER(interpro_ioga_device::timer2_value_w)
+WRITE32_MEMBER(sapphire_ioga_device::timer2_value_w)
{
m_timer2_value = data;
m_timer2_count = data; // ?
- LOGMASKED(LOG_TIMER2, "timer2_value_w data 0x%08x mask 0x%08x (%s)\n", data, mem_mask, machine().describe_context());
+ LOGMASKED(LOG_TIMER2, "timer2_value_w data 0x%08x mask 0x%08x (%s)\n",
+ data, mem_mask, machine().describe_context());
}
-READ32_MEMBER(interpro_ioga_device::timer3_r)
+READ32_MEMBER(sapphire_ioga_device::timer3_r)
{
u32 result = m_timer3_count & TIMER3_COUNT;
@@ -1032,12 +1170,13 @@ READ32_MEMBER(interpro_ioga_device::timer3_r)
else if (m_timer3->param())
result |= TIMER3_EXPIRED;
- LOGMASKED(LOG_TIMERRD, "timer3_r data 0x%08x mask 0x%08x (%s)\n", result, mem_mask, machine().describe_context());
+ LOGMASKED(LOG_TIMERRD, "timer3_r data 0x%08x mask 0x%08x (%s)\n",
+ result, mem_mask, machine().describe_context());
return result;
}
-WRITE32_MEMBER(interpro_ioga_device::timer3_w)
+WRITE32_MEMBER(sapphire_ioga_device::timer3_w)
{
// stop the timer so it won't trigger while we're fiddling with it
m_timer3->enable(false);
@@ -1048,14 +1187,15 @@ WRITE32_MEMBER(interpro_ioga_device::timer3_w)
// start the timer if necessary
if (data & TIMER3_START)
{
- LOGMASKED(LOG_TIMER3, "timer3_w data 0x%08x mask 0x%08x (%s)\n", data, mem_mask, machine().describe_context());
+ LOGMASKED(LOG_TIMER3, "timer3_w data 0x%08x mask 0x%08x (%s)\n",
+ data, mem_mask, machine().describe_context());
// theory: timer 3 is 12.5MHz (typical value of 12500 giving a delay of 1ms)
m_timer3->adjust(attotime::zero, false, attotime::from_hz(XTAL(12'500'000)));
}
}
-TIMER_CALLBACK_MEMBER(interpro_ioga_device::timer3)
+TIMER_CALLBACK_MEMBER(sapphire_ioga_device::timer3)
{
// decrement timer count value
m_timer3_count--;
@@ -1069,45 +1209,43 @@ TIMER_CALLBACK_MEMBER(interpro_ioga_device::timer3)
m_timer3->enable(false);
m_timer3->set_param(true);
- // throw an interrupt
- set_int_line(INT_HARD_IN, IRQ_TIMER3, ASSERT_LINE);
+ // raise an interrupt
+ set_int_line(IRQ_TIMER3, ASSERT_LINE);
}
}
READ32_MEMBER(interpro_ioga_device::prescaler_r)
{
- // FIXME: prescaler only used with timer 1?
- LOGMASKED(LOG_TIMERRD, "prescaler_r data 0x%08x mask 0x%08x (%s)\n", m_prescaler, mem_mask, machine().describe_context());
-
return (m_prescaler ^ 0xffff0000) - 0x10000;
}
WRITE32_MEMBER(interpro_ioga_device::prescaler_w)
{
- LOGMASKED(LOG_TIMER0 | LOG_TIMER1, "prescaler_w data 0x%08x mask 0x%08x (%s)\n", data, mem_mask, machine().describe_context());
+ LOGMASKED(LOG_TIMER0 | LOG_TIMER1, "prescaler_w data 0x%08x mask 0x%08x (%s)\n",
+ data, mem_mask, machine().describe_context());
COMBINE_DATA(&m_prescaler);
}
/*
* Mouse
- *
- * THEORY: mouse button state changes don't generate an interrupt, but are read
- * when an interrupt is generated by movement or by the 60Hz timer.
*/
READ32_MEMBER(interpro_ioga_device::mouse_status_r)
{
- const u32 result = m_mouse_status;
+ const u32 result = m_mouse_status ^ MOUSE_BUTTONS;
- LOGMASKED(LOG_MOUSE, "mouse_status_r status 0x%08x mask 0x%08x (%s)\n", result, mem_mask, machine().describe_context());
+ LOGMASKED(LOG_MOUSE, "mouse_status_r status 0x%08x mask 0x%08x (%s)\n",
+ result, mem_mask, machine().describe_context());
- // clear xpos and ypos fields
+ // clear xpos and ypos fields and interrupt
if (!machine().side_effects_disabled())
{
if (mem_mask & MOUSE_XPOS)
m_mouse_status &= ~(MOUSE_XPOS);
if (mem_mask & MOUSE_YPOS)
m_mouse_status &= ~(MOUSE_YPOS);
+
+ set_int_line(IRQ_MOUSE, CLEAR_LINE);
}
return result;
@@ -1115,33 +1253,90 @@ READ32_MEMBER(interpro_ioga_device::mouse_status_r)
WRITE32_MEMBER(interpro_ioga_device::mouse_status_w)
{
- LOGMASKED(LOG_MOUSE, "mouse_status_w status 0x%08x mask 0x%08x (%s)\n", data, mem_mask, machine().describe_context());
+ LOGMASKED(LOG_MOUSE, "mouse_status_w status 0x%08x mask 0x%08x\n",
+ data, mem_mask);
COMBINE_DATA(&m_mouse_status);
- if (data & (MOUSE_XPOS | MOUSE_YPOS))
- m_mouse_timer->adjust(attotime::zero);
-}
-
-TIMER_CALLBACK_MEMBER(interpro_ioga_device::mouse_timer)
-{
- if (m_hwicr[IRQ_MOUSE] & IRQ_ENABLE_EXTERNAL)
- set_int_line(INT_HARD_IN, IRQ_MOUSE, ASSERT_LINE);
+ set_int_line(IRQ_MOUSE, ASSERT_LINE);
}
/*
* Ethernet
*/
+WRITE32_MEMBER(emerald_ioga_device::eth_base_w)
+{
+ LOGMASKED(LOG_NETWORK, "eth: base_w 0x%08x mem_mask 0x%08x (%s)\n",
+ data, mem_mask, machine().describe_context());
+
+ m_eth_base = ((m_eth_base & ~mem_mask) | (data & mem_mask)) & ETH_BASE_MASK;
+}
+
+WRITE16_MEMBER(emerald_ioga_device::eth_control_w)
+{
+ LOGMASKED(LOG_NETWORK, "eth: control_w 0x%04x mem_mask 0x%04x (%s)\n",
+ data, mem_mask, machine().describe_context());
+
+ m_eth_control = data;
+
+ // ethernet device reset (active low)
+ if ((data & ETH_RESET) == 0)
+ {
+ // reset the ethernet device
+ siblingdevice("eth")->reset();
+
+ // clear the reset flag (the 250ns delay is long enough to pass diagnostic tests)
+ m_eth_reset_timer->adjust(attotime::from_nsec(250));
+ }
+
+ // ethernet channel attention
+ if (data & ETH_CA)
+ {
+ m_eth_ca_func(ASSERT_LINE);
+ m_eth_ca_func(CLEAR_LINE);
+ }
+}
+
+WRITE16_MEMBER(emerald_ioga_device::eth_w)
+{
+ const u32 address = m_eth_base | ((offset << 1) & ~ETH_BASE_MASK);
+
+ LOGMASKED(LOG_NETWORK, "eth_w address 0x%08x mask 0x%04x data 0x%04x\n",
+ address, mem_mask, data);
+ m_memory_space->write_word(address, data, mem_mask);
+}
+
+READ16_MEMBER(emerald_ioga_device::eth_r)
+{
+ const u32 address = m_eth_base | ((offset << 1) & ~ETH_BASE_MASK);
+
+ const u16 data = m_memory_space->read_word(address, mem_mask);
+ LOGMASKED(LOG_NETWORK, "eth_r 0x%08x mask 0x%04x data 0x%04x\n",
+ address, mem_mask, data);
+
+ return data;
+}
+
+TIMER_CALLBACK_MEMBER(emerald_ioga_device::eth_reset)
+{
+ LOGMASKED(LOG_NETWORK, "eth: reset flag cleared\n");
+
+ // clear ethernet reset flag
+ m_eth_control &= ~ETH_RESET;
+}
+
WRITE32_MEMBER(turquoise_ioga_device::eth_base_w)
{
- LOGMASKED(LOG_NETWORK, "eth: base_w 0x%08x mem_mask 0x%08x (%s)\n", data, mem_mask, machine().describe_context());
+ LOGMASKED(LOG_NETWORK, "eth: base_w 0x%08x mem_mask 0x%08x (%s)\n",
+ data, mem_mask, machine().describe_context());
m_eth_base = ((m_eth_base & ~mem_mask) | (data & mem_mask)) & ETH_BASE_MASK;
}
WRITE16_MEMBER(turquoise_ioga_device::eth_control_w)
{
- LOGMASKED(LOG_NETWORK, "eth: control_w 0x%04x mem_mask 0x%04x (%s)\n", data, mem_mask, machine().describe_context());
+ LOGMASKED(LOG_NETWORK, "eth: control_w 0x%04x mem_mask 0x%04x (%s)\n",
+ data, mem_mask, machine().describe_context());
m_eth_control = data;
@@ -1167,7 +1362,8 @@ WRITE16_MEMBER(turquoise_ioga_device::eth_w)
{
const u32 address = m_eth_base | ((offset << 1) & ~ETH_BASE_MASK);
- LOGMASKED(LOG_NETWORK, "eth_w address 0x%08x mask 0x%04x data 0x%04x\n", address, mem_mask, data);
+ LOGMASKED(LOG_NETWORK, "eth_w address 0x%08x mask 0x%04x data 0x%04x\n",
+ address, mem_mask, data);
m_memory_space->write_word(address, data, mem_mask);
}
@@ -1176,7 +1372,8 @@ READ16_MEMBER(turquoise_ioga_device::eth_r)
const u32 address = m_eth_base | ((offset << 1) & ~ETH_BASE_MASK);
const u16 data = m_memory_space->read_word(address, mem_mask);
- LOGMASKED(LOG_NETWORK, "eth_r 0x%08x mask 0x%04x data 0x%04x\n", address, mem_mask, data);
+ LOGMASKED(LOG_NETWORK, "eth_r 0x%08x mask 0x%04x data 0x%04x\n",
+ address, mem_mask, data);
return data;
}
@@ -1191,28 +1388,32 @@ TIMER_CALLBACK_MEMBER(turquoise_ioga_device::eth_reset)
WRITE32_MEMBER(sapphire_ioga_device::eth_remap_w)
{
- LOGMASKED(LOG_NETWORK, "eth: remap = 0x%08x (%s)\n", data, machine().describe_context());
+ LOGMASKED(LOG_NETWORK, "eth: remap = 0x%08x (%s)\n",
+ data, machine().describe_context());
m_eth_remap = data & ~0xf;
}
WRITE32_MEMBER(sapphire_ioga_device::eth_mappg_w)
{
- LOGMASKED(LOG_NETWORK, "eth: map page = 0x%08x (%s)\n", data, machine().describe_context());
+ LOGMASKED(LOG_NETWORK, "eth: map page = 0x%08x (%s)\n",
+ data, machine().describe_context());
m_eth_mappg = data & ~0xf;
}
READ32_MEMBER(sapphire_ioga_device::eth_control_r)
{
- LOGMASKED(LOG_NETWORK, "eth: control_r 0x%08x (%s)\n", m_eth_control, machine().describe_context());
+ LOGMASKED(LOG_NETWORK, "eth: control_r 0x%08x (%s)\n",
+ m_eth_control, machine().describe_context());
return m_eth_control;
}
WRITE32_MEMBER(sapphire_ioga_device::eth_control_w)
{
- LOGMASKED(LOG_NETWORK, "eth: control_w 0x%08x mem_mask 0x%08x (%s)\n", data, mem_mask, machine().describe_context());
+ LOGMASKED(LOG_NETWORK, "eth: control_w 0x%08x mem_mask 0x%08x (%s)\n",
+ data, mem_mask, machine().describe_context());
m_eth_control = data & ETH_MASK;
@@ -1245,10 +1446,12 @@ WRITE16_MEMBER(sapphire_ioga_device::eth_w)
address &= ~(m_eth_mappg & ETH_MAPPG);
address |= (m_eth_remap & ETH_REMAP_ADDR);
- LOGMASKED(LOG_NETWORK, "eth_w address 0x%08x remapped 0x%08x\n", offset << 1, address);
+ LOGMASKED(LOG_NETWORK, "eth_w address 0x%08x remapped 0x%08x\n",
+ offset << 1, address);
}
- LOGMASKED(LOG_NETWORK, "eth_w channel %c address 0x%08x mask 0x%08x data 0x%04x\n", channel + 'A', address, mem_mask, data);
+ LOGMASKED(LOG_NETWORK, "eth_w channel %c address 0x%08x mask 0x%08x data 0x%04x\n",
+ channel + 'A', address, mem_mask, data);
m_memory_space->write_word(address, data, mem_mask);
}
@@ -1264,11 +1467,13 @@ READ16_MEMBER(sapphire_ioga_device::eth_r)
address |= (m_eth_remap & ETH_REMAP_ADDR);
address &= 0x3fffffff;
- LOGMASKED(LOG_NETWORK, "eth_r address 0x%08x remapped 0x%08x\n", offset << 1, address);
+ LOGMASKED(LOG_NETWORK, "eth_r address 0x%08x remapped 0x%08x\n",
+ offset << 1, address);
}
u16 data = m_memory_space->read_word(address, mem_mask);
- LOGMASKED(LOG_NETWORK, "eth_r channel %c address 0x%08x mask 0x%08x data 0x%04x\n", channel + 'A', address, mem_mask, data);
+ LOGMASKED(LOG_NETWORK, "eth_r channel %c address 0x%08x mask 0x%08x data 0x%04x\n",
+ channel + 'A', address, mem_mask, data);
return data;
}
diff --git a/src/mame/machine/interpro_ioga.h b/src/mame/machine/interpro_ioga.h
index 8b392c111c1..cb7b8529788 100644
--- a/src/mame/machine/interpro_ioga.h
+++ b/src/mame/machine/interpro_ioga.h
@@ -13,7 +13,7 @@
devcb = &downcast<interpro_ioga_device &>(*device).set_out_irq_callback(DEVCB_##_out_irq);
#define MCFG_INTERPRO_IOGA_IVEC_CB(_out_ivec) \
- devcb = &downcast<interpro_ioga_device &>(*device).set_out_ivec_callback(DEVCB_##_out_ivec);
+ devcb = &downcast<interpro_ioga_device &>(*device).set_out_irq_vector_callback(DEVCB_##_out_ivec);
#define MCFG_INTERPRO_IOGA_DMA_CB(_channel, _dma_r, _dma_w) \
devcb = &downcast<interpro_ioga_device &>(*device).set_dma_r_callback(_channel, DEVCB_##_dma_r); \
@@ -39,63 +39,33 @@ protected:
enum interrupt_type
{
- INT_HARD_IN, // hardware internal
- INT_HARD_EX, // hardware external
- INT_SOFT_LO, // soft low type
- INT_SOFT_HI // soft high type
+ INT_NONE = 0,
+ INT_HARD = 1,
+ INT_SOFT = 2,
};
enum interrupt_number
{
- IRQ_TIMER2 = 0, // internal int 3 (5c)
- IRQ_TIMER3 = 1, // internal int 4 (5e)
- IRQ_SCSI = 2, // external int 0 (60)
- IRQ_FLOPPY = 3, // external int 1 (62)
- IRQ_PLOTTER = 4, // external int 2 (64)
- IRQ_SRXCBUS0 = 5, // external int 3 (66)
- IRQ_SRXCBUS1 = 6, // external int 4 (68)
- IRQ_SRXCBUS2 = 7, // external int 5 (6a)
- IRQ_VB = 8, // external int 6 (6c)
- IRQ_9 = 9, // external int 7 (6e)
- IRQ_CBUS3 = 10, // external int 8 (70)
- IRQ_RTC = 11, // external int 9 (72)
- IRQ_60HZ = 12, // external int 10 (74)
- IRQ_MOUSE = 13, // internal int 0 (76)
- IRQ_TIMER0 = 14, // internal int 1 (78)
- IRQ_TIMER1 = 15, // internal int 2 (7a)
- IRQ_SERDMA = 16, // internal int 5 (7c)
- IRQ_SERIAL = 17, // external int 11 (7e)
- IRQ_ETHERNET = 18, // external int 12 (80)
-
- // soft interrupts (low type)
- IRQ_SOFT0 = 0,
- IRQ_SOFT1 = 1,
- IRQ_SOFT2 = 2,
- IRQ_SOFT3 = 3,
- IRQ_SOFT4 = 4,
- IRQ_SOFT5 = 5,
- IRQ_SOFT6 = 6,
- IRQ_SOFT7 = 7,
-
- // soft interrupts (high type)
- IRQ_SOFT8 = 0,
- IRQ_SOFT9 = 1,
- IRQ_SOFT10 = 2,
- IRQ_SOFT11 = 3,
- IRQ_SOFT12 = 4,
- IRQ_SOFT13 = 5,
- IRQ_SOFT14 = 6,
- IRQ_SOFT15 = 7
- };
-
- struct interrupt_data_t
- {
- const interrupt_type type;
- const interrupt_number number;
- const u16 mask;
-
- const char *const name;
- const char *const source;
+ IRQ_SCSI = 0, // external int 0 (offset 0x60)
+ IRQ_FLOPPY = 1, // external int 1 (offset 0x62)
+ IRQ_PLOTTER = 2, // external int 2 (offset 0x64)
+ IRQ_SRXCBUS0 = 3, // external int 3 (offset 0x66)
+ IRQ_SRXCBUS1 = 4, // external int 4 (offset 0x68)
+ IRQ_SRXCBUS2 = 5, // external int 5 (offset 0x6a)
+ IRQ_VB = 6, // external int 6 (offset 0x6c)
+ IRQ_7 = 7, // external int 7 (offset 0x6e)
+ IRQ_CBUS3 = 8, // external int 8 (offset 0x70)
+ IRQ_RTC = 9, // external int 9 (offset 0x72)
+ IRQ_60HZ = 10, // external int 10 (offset 0x74)
+ IRQ_MOUSE = 11, // internal int 0 (offset 0x76)
+ IRQ_TIMER0 = 12, // internal int 1 (offset 0x78)
+ IRQ_TIMER1 = 13, // internal int 2 (offset 0x7a)
+ IRQ_SERDMA = 14, // internal int 3 (offset 0x7c) // Sapphire internal int 5
+ IRQ_SERIAL = 15, // external int 11 (offset 0x7e)
+ IRQ_ETHERNET = 16, // external int 12 (offset 0x80)
+
+ IRQ_TIMER2 = 17, // internal int 3 (offset 0x5c) // Sapphire only
+ IRQ_TIMER3 = 18, // internal int 4 (offset 0x5e) // Sapphire only
};
enum dma_channel
@@ -108,7 +78,7 @@ protected:
public:
template <class Object> devcb_base &set_out_nmi_callback(Object &&cb) { return m_out_nmi_func.set_callback(std::forward<Object>(cb)); }
template <class Object> devcb_base &set_out_irq_callback(Object &&cb) { return m_out_irq_func.set_callback(std::forward<Object>(cb)); }
- template <class Object> devcb_base &set_out_ivec_callback(Object &&cb) { return m_out_ivec_func.set_callback(std::forward<Object>(cb)); }
+ template <class Object> devcb_base &set_out_irq_vector_callback(Object &&cb) { return m_out_irq_vector_func.set_callback(std::forward<Object>(cb)); }
template <class Object> devcb_base &set_dma_r_callback(int channel, Object &&cb) { return m_dma_channel[channel].device_r.set_callback(std::forward<Object>(cb)); }
template <class Object> devcb_base &set_dma_w_callback(int channel, Object &&cb) { return m_dma_channel[channel].device_w.set_callback(std::forward<Object>(cb)); }
template <class Object> devcb_base &set_serial_dma_r_callback(int channel, Object &&cb) { return m_serial_dma_channel[channel].device_r.set_callback(std::forward<Object>(cb)); }
@@ -125,21 +95,21 @@ public:
virtual void map(address_map &map) = 0;
// interrupt request lines
- DECLARE_WRITE_LINE_MEMBER(ir0_w) { set_int_line(INT_HARD_EX, IRQ_SCSI, state); }
- DECLARE_WRITE_LINE_MEMBER(ir1_w) { set_int_line(INT_HARD_EX, IRQ_FLOPPY, state); }
- DECLARE_WRITE_LINE_MEMBER(ir2_w) { set_int_line(INT_HARD_EX, IRQ_PLOTTER, state); }
- DECLARE_WRITE_LINE_MEMBER(ir3_w) { set_int_line(INT_HARD_EX, IRQ_SRXCBUS0, state); }
- DECLARE_WRITE_LINE_MEMBER(ir4_w) { set_int_line(INT_HARD_EX, IRQ_SRXCBUS1, state); }
- DECLARE_WRITE_LINE_MEMBER(ir5_w) { set_int_line(INT_HARD_EX, IRQ_SRXCBUS2, state); }
- DECLARE_WRITE_LINE_MEMBER(ir6_w) { set_int_line(INT_HARD_EX, IRQ_VB, state); }
- DECLARE_WRITE_LINE_MEMBER(ir7_w) { set_int_line(INT_HARD_EX, IRQ_9, state); }
- DECLARE_WRITE_LINE_MEMBER(ir8_w) { set_int_line(INT_HARD_EX, IRQ_CBUS3, state); }
- DECLARE_WRITE_LINE_MEMBER(ir9_w) { set_int_line(INT_HARD_EX, IRQ_RTC, state); }
- DECLARE_WRITE_LINE_MEMBER(ir10_w) { set_int_line(INT_HARD_EX, IRQ_60HZ, state); }
- DECLARE_WRITE_LINE_MEMBER(ir11_w) { set_int_line(INT_HARD_EX, IRQ_SERIAL, state); }
- DECLARE_WRITE_LINE_MEMBER(ir12_w) { set_int_line(INT_HARD_EX, IRQ_ETHERNET, state); }
-
- IRQ_CALLBACK_MEMBER(acknowledge_interrupt);
+ DECLARE_WRITE_LINE_MEMBER(ir0_w) { set_int_line(IRQ_SCSI, state); }
+ DECLARE_WRITE_LINE_MEMBER(ir1_w) { set_int_line(IRQ_FLOPPY, state); }
+ DECLARE_WRITE_LINE_MEMBER(ir2_w) { set_int_line(IRQ_PLOTTER, state); }
+ DECLARE_WRITE_LINE_MEMBER(ir3_w) { set_int_line(IRQ_SRXCBUS0, state); }
+ DECLARE_WRITE_LINE_MEMBER(ir4_w) { set_int_line(IRQ_SRXCBUS1, state); }
+ DECLARE_WRITE_LINE_MEMBER(ir5_w) { set_int_line(IRQ_SRXCBUS2, state); }
+ DECLARE_WRITE_LINE_MEMBER(ir6_w) { set_int_line(IRQ_VB, state); }
+ DECLARE_WRITE_LINE_MEMBER(ir7_w) { set_int_line(IRQ_7, state); }
+ DECLARE_WRITE_LINE_MEMBER(ir8_w) { set_int_line(IRQ_CBUS3, state); }
+ DECLARE_WRITE_LINE_MEMBER(ir9_w) { set_int_line(IRQ_RTC, state); }
+ DECLARE_WRITE_LINE_MEMBER(ir10_w) { set_int_line(IRQ_60HZ, state); }
+ DECLARE_WRITE_LINE_MEMBER(ir11_w) { set_int_line(IRQ_SERIAL, state); }
+ DECLARE_WRITE_LINE_MEMBER(ir12_w) { set_int_line(IRQ_ETHERNET, state); }
+
+ virtual IRQ_CALLBACK_MEMBER(acknowledge_interrupt);
// interrupt control
enum icr_mask
@@ -150,15 +120,15 @@ public:
IRQ_FLAGS = 0xff00,
IRQ_PENDING = 0x0100,
- IRQ_ENABLE_EXTERNAL = 0x0200,
+ IRQ_ENABLE = 0x0200,
IRQ_EDGE = 0x0400,
IRQ_NEGPOL = 0x0800,
- IRQ_ENABLE_INTERNAL = 0x1000
+ IRQ_ENABLE_INT = 0x1000,
+
+ IRQ_ENABLE_SERDMA = 0x0e00,
};
- DECLARE_READ16_MEMBER(icr_r) { return m_hwicr[offset]; }
- DECLARE_WRITE16_MEMBER(icr_w);
- DECLARE_READ16_MEMBER(icr18_r) { return icr_r(space, 18, mem_mask); }
- DECLARE_WRITE16_MEMBER(icr18_w) { icr_w(space, 18, data, mem_mask); }
+ DECLARE_READ16_MEMBER(hardint_r) { return m_hwicr[offset]; }
+ DECLARE_WRITE16_MEMBER(hardint_w);
enum nmictrl_mask
{
@@ -175,8 +145,6 @@ public:
DECLARE_READ8_MEMBER(softint_r) { return m_softint; }
DECLARE_WRITE8_MEMBER(softint_w);
- DECLARE_READ16_MEMBER(softint_vector_r) { return m_swicr[offset]; }
- DECLARE_WRITE16_MEMBER(softint_vector_w);
// dma request lines
DECLARE_WRITE_LINE_MEMBER(drq_plotter) { drq(state, DMA_PLOTTER); }
@@ -190,6 +158,7 @@ public:
enum dma_ctrl_mask
{
DMA_CTRL_TCZERO = 0x00000001, // transfer count zero
+
DMA_CTRL_TAG = 0x00000e00, // bus tag
DMA_CTRL_BERR = 0x00400000, // bus error
DMA_CTRL_ERR = 0x00800000, // checked for in scsi isr
@@ -266,7 +235,7 @@ public:
DECLARE_READ32_MEMBER(bus_timeout_r) { return m_bus_timeout; }
DECLARE_WRITE32_MEMBER(bus_timeout_w) { m_bus_timeout = data; }
- DECLARE_WRITE32_MEMBER(bus_error) { m_error_address = data; m_error_businfo = offset; }
+ DECLARE_WRITE32_MEMBER(bus_error);
// timers
DECLARE_READ32_MEMBER(timer0_r);
@@ -281,20 +250,6 @@ public:
DECLARE_READ32_MEMBER(timer1_r);
DECLARE_WRITE32_MEMBER(timer1_w);
- DECLARE_READ32_MEMBER(timer2_count_r);
- DECLARE_WRITE32_MEMBER(timer2_count_w);
- DECLARE_READ32_MEMBER(timer2_value_r);
- DECLARE_WRITE32_MEMBER(timer2_value_w);
-
- enum timer3_mask
- {
- TIMER3_COUNT = 0x3fffffff,
- TIMER3_START = 0x40000000,
- TIMER3_EXPIRED = 0x80000000
- };
- DECLARE_READ32_MEMBER(timer3_r);
- DECLARE_WRITE32_MEMBER(timer3_w);
-
DECLARE_READ32_MEMBER(prescaler_r);
DECLARE_WRITE32_MEMBER(prescaler_w);
@@ -324,32 +279,42 @@ protected:
// callbacks
devcb_write_line m_out_nmi_func;
devcb_write_line m_out_irq_func;
- devcb_write8 m_out_ivec_func;
+ devcb_write8 m_out_irq_vector_func;
devcb_write_line m_fdc_tc_func;
devcb_write_line m_eth_ca_func;
void set_nmi_line(int state);
- void set_int_line(interrupt_type type, int number, int state);
+ void set_int_line(int number, int state);
- TIMER_CALLBACK_MEMBER(interrupt_check);
- TIMER_CALLBACK_MEMBER(set_ivec);
+ virtual TIMER_CALLBACK_MEMBER(interrupt_check);
TIMER_CALLBACK_MEMBER(dma);
TIMER_CALLBACK_MEMBER(serial_dma);
TIMER_CALLBACK_MEMBER(timer0);
TIMER_CALLBACK_MEMBER(timer1);
- TIMER_CALLBACK_MEMBER(timer2) {}
- TIMER_CALLBACK_MEMBER(timer3);
TIMER_CALLBACK_MEMBER(timer_60hz);
- TIMER_CALLBACK_MEMBER(mouse_timer);
virtual TIMER_CALLBACK_MEMBER(eth_reset) = 0;
+
+ emu_timer *m_interrupt_timer;
emu_timer *m_eth_reset_timer;
+ std::unique_ptr<u16 []> m_hwicr;
+ u32 m_force_state;
+ u8 m_softint;
+
+ interrupt_type m_active_interrupt_type;
+ u8 m_active_interrupt_number;
+
+ void nmi(int state);
+ void irq(int state, u8 ivec);
+ u8 get_irq_vector() const { return m_irq_vector; }
+
+ virtual u8 get_int_count() const { return 17; }
+ virtual u8 get_reg_offset(u8 const number) const { return number; }
+ virtual u8 get_int_number(u8 const offset) const { return offset; }
+
private:
- bool nmi(int state);
- bool irq(int state, u8 ivec);
- u16 get_icr(interrupt_type type, int number) const;
- void set_pending(interrupt_type type, int number, bool pending);
+ TIMER_CALLBACK_MEMBER(set_irq_vector) { m_out_irq_vector_func(m_irq_vector); }
void drq(int state, int channel);
void serial_drq(int state, int channel);
@@ -370,20 +335,13 @@ private:
void serial_dma_ctrl_w(address_space &space, offs_t offset, u32 data, u32 mem_mask, int channel);
// interrupt state
- static const interrupt_data_t m_interrupt_data[];
- interrupt_data_t const *m_active_interrupt;
int m_nmi_state;
int m_irq_state;
- u8 m_ivec;
- u32 m_hwint_forced;
+ u8 m_irq_vector;
u32 m_line_state;
// interrupt control
- static const int INTERRUPT_COUNT = 19;
- u16 m_hwicr[INTERRUPT_COUNT];
- u8 m_softint;
u8 m_nmictrl;
- u16 m_swicr[8];
// dma state
static const int DMA_CHANNEL_COUNT = 3;
@@ -423,18 +381,12 @@ private:
// timers
u8 m_timer0_count;
u16 m_timer1_count;
- u32 m_timer2_count;
- u32 m_timer2_value;
- u32 m_timer3_count;
u32 m_prescaler;
- emu_timer *m_interrupt_timer;
emu_timer *m_dma_timer;
emu_timer *m_serial_dma_timer;
emu_timer *m_timer0;
emu_timer *m_timer1;
- emu_timer *m_timer2;
- emu_timer *m_timer3;
emu_timer *m_timer_60hz;
// bus arbitration and control
@@ -445,7 +397,48 @@ private:
// mouse
u32 m_mouse_status;
- emu_timer *m_mouse_timer;
+};
+
+class emerald_ioga_device : public interpro_ioga_device
+{
+public:
+ emerald_ioga_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
+
+ virtual void map(address_map &map) override;
+
+ DECLARE_WRITE16_MEMBER(eth_w);
+ DECLARE_READ16_MEMBER(eth_r);
+
+protected:
+ virtual TIMER_CALLBACK_MEMBER(eth_reset) override;
+
+ enum eth_base_mask
+ {
+ ETH_BASE_MASK = 0xffe00000
+ };
+ DECLARE_READ32_MEMBER(eth_base_r) { return m_eth_base; }
+ DECLARE_WRITE32_MEMBER(eth_base_w);
+
+ enum eth_control_mask
+ {
+ ETH_CA = 0x0001, // channel attention
+ ETH_FLUSH = 0x0002,
+ ETH_BUF = 0x0004,
+ ETH_QUAD = 0x0008,
+ ETH_BERR = 0x0010, // bus error
+ ETH_PERR = 0x0020, // parity error
+ ETH_RESET = 0x0040,
+ ETH_WTAG = 0x0600,
+ ETH_RTAG = 0x3000,
+
+ //ETH_MASK = 0x4ff2 // channel attention and error bits not persistent
+ };
+ DECLARE_READ16_MEMBER(eth_control_r) { return m_eth_control; }
+ DECLARE_WRITE16_MEMBER(eth_control_w);
+
+private:
+ u32 m_eth_base;
+ u16 m_eth_control;
};
class turquoise_ioga_device : public interpro_ioga_device
@@ -500,7 +493,32 @@ public:
DECLARE_WRITE16_MEMBER(eth_w);
DECLARE_READ16_MEMBER(eth_r);
+ DECLARE_READ32_MEMBER(timer2_count_r);
+ DECLARE_WRITE32_MEMBER(timer2_count_w);
+ DECLARE_READ32_MEMBER(timer2_value_r);
+ DECLARE_WRITE32_MEMBER(timer2_value_w);
+
+ enum timer3_mask
+ {
+ TIMER3_COUNT = 0x3fffffff,
+ TIMER3_START = 0x40000000,
+ TIMER3_EXPIRED = 0x80000000
+ };
+ DECLARE_READ32_MEMBER(timer3_r);
+ DECLARE_WRITE32_MEMBER(timer3_w);
+
+
+ DECLARE_READ16_MEMBER(softint_vector_r) { return m_swicr[offset]; }
+ DECLARE_WRITE16_MEMBER(softint_vector_w);
+
+ virtual IRQ_CALLBACK_MEMBER(acknowledge_interrupt) override;
+
protected:
+ // device-level overrides
+ virtual void device_start() override;
+ virtual void device_reset() override;
+
+ virtual TIMER_CALLBACK_MEMBER(interrupt_check) override;
virtual TIMER_CALLBACK_MEMBER(eth_reset) override;
enum eth_remap_mask
@@ -544,13 +562,32 @@ protected:
DECLARE_READ32_MEMBER(eth_control_r);
DECLARE_WRITE32_MEMBER(eth_control_w);
+ TIMER_CALLBACK_MEMBER(timer2) {}
+ TIMER_CALLBACK_MEMBER(timer3);
+
+ virtual u8 get_int_count() const override { return INTERRUPT_COUNT; }
+ virtual u8 get_reg_offset(u8 const number) const override { return (number + 2) % INTERRUPT_COUNT; }
+ virtual u8 get_int_number(u8 const offset) const override { return (offset + INTERRUPT_COUNT - 2) % INTERRUPT_COUNT; }
+
private:
+ static const u8 INTERRUPT_COUNT = 19;
+
u32 m_eth_remap;
u32 m_eth_mappg;
u32 m_eth_control;
+
+ u32 m_timer2_count;
+ u32 m_timer2_value;
+ u32 m_timer3_count;
+
+ emu_timer *m_timer2;
+ emu_timer *m_timer3;
+
+ u16 m_swicr[8];
};
// device type definition
+DECLARE_DEVICE_TYPE(EMERALD_IOGA, emerald_ioga_device)
DECLARE_DEVICE_TYPE(TURQUOISE_IOGA, turquoise_ioga_device)
DECLARE_DEVICE_TYPE(SAPPHIRE_IOGA, sapphire_ioga_device)