From 7bee6e6f1e9711558c7548dd895979bb9ffd81bc Mon Sep 17 00:00:00 2001 From: Patrick Mackinlay Date: Thu, 5 Jul 2018 21:22:05 +0700 Subject: 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. --- src/devices/bus/interpro/keyboard/lle.cpp | 54 +- src/devices/bus/interpro/mouse/mouse.cpp | 2 +- src/devices/bus/interpro/sr/sr.cpp | 4 + src/devices/bus/interpro/sr/sr.h | 5 +- src/devices/cpu/clipper/clipper.cpp | 98 +++- src/devices/cpu/clipper/clipper.h | 28 +- src/devices/cpu/clipper/common.h | 2 - src/mame/drivers/interpro.cpp | 496 +++++++++++------ src/mame/includes/interpro.h | 192 +++++-- src/mame/machine/cammu.cpp | 89 +-- src/mame/machine/cammu.h | 55 +- src/mame/machine/interpro_ioga.cpp | 873 ++++++++++++++++++------------ src/mame/machine/interpro_ioga.h | 275 ++++++---- 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 spaces = { &space(0), &space(0), &space(0), &space(0), &space(1), &space(2), nullptr, nullptr }; + std::vector 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(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(m_ssw, m_r[R1] - 4, m_r[R2])) - m_r[R1] -= 4; + get_dcammu().store(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 clipper_device::create_disassembler() { return std::make_unique(); } + +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(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(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(*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 m_d_cammu; required_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 m_d_cammu; required_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 m_mmu; required_device m_scsi; required_device m_arbga; - required_device m_flash_lo; - required_device m_flash_hi; + required_device m_flash_lsb; + required_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 std::enable_if_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(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(*device).set_out_irq_callback(DEVCB_##_out_irq); #define MCFG_INTERPRO_IOGA_IVEC_CB(_out_ivec) \ - devcb = &downcast(*device).set_out_ivec_callback(DEVCB_##_out_ivec); + devcb = &downcast(*device).set_out_irq_vector_callback(DEVCB_##_out_ivec); #define MCFG_INTERPRO_IOGA_DMA_CB(_channel, _dma_r, _dma_w) \ devcb = &downcast(*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 devcb_base &set_out_nmi_callback(Object &&cb) { return m_out_nmi_func.set_callback(std::forward(cb)); } template devcb_base &set_out_irq_callback(Object &&cb) { return m_out_irq_func.set_callback(std::forward(cb)); } - template devcb_base &set_out_ivec_callback(Object &&cb) { return m_out_ivec_func.set_callback(std::forward(cb)); } + template devcb_base &set_out_irq_vector_callback(Object &&cb) { return m_out_irq_vector_func.set_callback(std::forward(cb)); } template devcb_base &set_dma_r_callback(int channel, Object &&cb) { return m_dma_channel[channel].device_r.set_callback(std::forward(cb)); } template devcb_base &set_dma_w_callback(int channel, Object &&cb) { return m_dma_channel[channel].device_w.set_callback(std::forward(cb)); } template devcb_base &set_serial_dma_r_callback(int channel, Object &&cb) { return m_serial_dma_channel[channel].device_r.set_callback(std::forward(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 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) -- cgit v1.2.3