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.
This commit is contained in:
Patrick Mackinlay 2018-07-05 21:22:05 +07:00 committed by Olivier Galibert
parent d4e6275690
commit 7bee6e6f1e
13 changed files with 1407 additions and 832 deletions

View File

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

View File

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

View File

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

View File

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

View File

@ -20,8 +20,10 @@
#define LOG_GENERAL (1U << 0)
#define LOG_EXCEPTION (1U << 1)
#define LOG_SYSCALLS (1U << 2)
//#define VERBOSE (LOG_GENERAL | LOG_EXCEPTION)
#define VERBOSE (LOG_SYSCALLS)
#include "logmacro.h"
@ -54,21 +56,21 @@ DEFINE_DEVICE_TYPE(CLIPPER_C300, clipper_c300_device, "clipper_c300", "C300 CLIP
DEFINE_DEVICE_TYPE(CLIPPER_C400, clipper_c400_device, "clipper_c400", "C400 CLIPPER")
clipper_c100_device::clipper_c100_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
: clipper_device(mconfig, CLIPPER_C100, tag, owner, clock, ENDIANNESS_LITTLE, 0)
: clipper_device(mconfig, CLIPPER_C100, tag, owner, clock, ENDIANNESS_LITTLE, SSW_ID_C1R1)
, m_icammu(*this, "^cammu_i")
, m_dcammu(*this, "^cammu_d")
{
}
clipper_c300_device::clipper_c300_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
: clipper_device(mconfig, CLIPPER_C300, tag, owner, clock, ENDIANNESS_LITTLE, 0)
: clipper_device(mconfig, CLIPPER_C300, tag, owner, clock, ENDIANNESS_LITTLE, SSW_ID_C3R1)
, m_icammu(*this, "^cammu_i")
, m_dcammu(*this, "^cammu_d")
{
}
clipper_c400_device::clipper_c400_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
: clipper_device(mconfig, CLIPPER_C400, tag, owner, clock, ENDIANNESS_LITTLE, SSW_ID_C400R4)
: clipper_device(mconfig, CLIPPER_C400, tag, owner, clock, ENDIANNESS_LITTLE, SSW_ID_C4R4)
, m_cammu(*this, "^cammu")
{
}
@ -113,7 +115,7 @@ inline u64 rotr64(u64 x, u8 shift)
void clipper_device::device_start()
{
// map spaces to system tags
std::vector<address_space *> spaces = { &space(0), &space(0), &space(0), &space(0), &space(1), &space(2), nullptr, nullptr };
std::vector<address_space *> spaces = { &space(0), &space(0), &space(0), &space(0), &space(1), &space(2), &space(0), &machine().dummy_space() };
// configure the cammu address spaces
get_icammu().set_spaces(spaces);
@ -141,7 +143,6 @@ void clipper_device::device_start()
state_add(STATE_GENPC, "GENPC", m_pc).noshow();
state_add(STATE_GENPCBASE, "CURPC", m_pc).noshow();
state_add(STATE_GENSP, "GENSP", m_r[15]).noshow();
state_add(STATE_GENFLAGS, "GENFLAGS", m_psw).mask(0xf).formatstr("%4s").noshow();
state_add(CLIPPER_PC, "pc", m_pc);
@ -150,7 +151,9 @@ void clipper_device::device_start()
// integer regsters
for (int i = 0; i < get_ireg_count(); i++)
state_add(CLIPPER_IREG + i, util::string_format("r%d", i).c_str(), m_r[i]);
state_add(CLIPPER_UREG + i, util::string_format("ur%d", i).c_str(), m_ru[i]);
for (int i = 0; i < get_ireg_count(); i++)
state_add(CLIPPER_SREG + i, util::string_format("sr%d", i).c_str(), m_rs[i]);
// floating point registers
for (int i = 0; i < get_freg_count(); i++)
@ -213,7 +216,7 @@ void clipper_device::execute_run()
}
else if (SSW(EI) && m_irq)
{
LOGMASKED(LOG_EXCEPTION, "received prioritised interrupt ivec 0x%02x\n", m_ivec);
LOGMASKED(LOG_EXCEPTION, "prioritised interrupt vector 0x%02x\n", m_ivec);
// allow equal/higher priority interrupts
if ((m_ivec & IVEC_LEVEL) <= SSW(IL))
@ -223,17 +226,20 @@ void clipper_device::execute_run()
m_pc = intrap(EXCEPTION_INTERRUPT_BASE + m_ivec * 8, m_pc);
LOGMASKED(LOG_EXCEPTION, "transferring control to ivec 0x%02x address 0x%08x\n", m_ivec, m_pc);
LOGMASKED(LOG_EXCEPTION, "transferring control to vector 0x%02x address 0x%08x\n", m_ivec, m_pc);
}
}
if (m_wait)
m_icount = 0;
while (m_icount > 0)
{
debugger_instruction_hook(m_pc);
if (m_wait)
{
m_icount = 0;
continue;
}
// fetch and decode an instruction
if (decode_instruction())
{
@ -249,6 +255,8 @@ void clipper_device::execute_run()
if (m_exception)
{
debugger_exception_hook(m_exception);
/*
* For traced instructions which are interrupted or cause traps, the TP
* flag is set by hardware when the interrupt or trap occurs to ensure
@ -349,9 +357,11 @@ WRITE16_MEMBER(clipper_device::set_exception)
*/
bool clipper_device::decode_instruction()
{
// record the current instruction address
m_info.pc = m_pc;
// fetch and decode the primary parcel
if (!get_icammu().fetch<u16>(m_ssw, m_pc + 0, [this](u16 insn) {
m_info.pc = m_pc;
m_info.opcode = insn >> 8;
m_info.subopcode = insn & 0xff;
m_info.r1 = (insn & 0x00f0) >> 4;
@ -511,6 +521,14 @@ void clipper_device::execute_instruction()
case 0x12:
// calls: call supervisor
m_exception = EXCEPTION_SUPERVISOR_CALL_BASE + (m_info.subopcode & 0x7f) * 8;
if (VERBOSE & LOG_SYSCALLS)
switch (m_info.subopcode & 0x7f)
{
case 0x3b: // execve
LOGMASKED(LOG_SYSCALLS, "execve(\"%s\", [ %s ], envp)\n",
debug_string(m_r[0]), debug_string_array(m_r[1]));
break;
}
break;
case 0x13:
// ret: return from subroutine
@ -522,8 +540,8 @@ void clipper_device::execute_instruction()
break;
case 0x14:
// pushw: push word
if (get_dcammu().store<u32>(m_ssw, m_r[R1] - 4, m_r[R2]))
m_r[R1] -= 4;
get_dcammu().store<u32>(m_ssw, m_r[R1] - 4, m_r[R2]);
m_r[R1] -= 4;
// TRAPS: A,P,W
break;
@ -1500,8 +1518,6 @@ u32 clipper_device::intrap(const u16 vector, const u32 old_pc)
const u32 old_psw = m_psw;
u32 new_pc = 0, new_ssw = 0;
debugger_exception_hook(vector);
// clear ssw bits to enable supervisor memory access
m_ssw &= ~(SSW_U | SSW_K | SSW_UU | SSW_KU);
@ -1585,8 +1601,6 @@ u32 clipper_c400_device::intrap(const u16 vector, const u32 old_pc)
const u32 old_psw = m_psw;
u32 new_pc = 0, new_ssw = 0;
debugger_exception_hook(vector);
// clear ssw bits to enable supervisor memory access
m_ssw &= ~(SSW_U | SSW_K | SSW_UU | SSW_KU);
@ -1970,3 +1984,51 @@ std::unique_ptr<util::disasm_interface> clipper_device::create_disassembler()
{
return std::make_unique<clipper_disassembler>();
}
std::string clipper_device::debug_string(u32 pointer)
{
auto const suppressor(machine().disable_side_effects());
std::string s("");
while (true)
{
char c;
if (!get_dcammu().load<u8>(m_ssw, pointer++, [&c](u8 v) { c = v; }))
break;
if (c == '\0')
break;
s += c;
}
return s;
}
std::string clipper_device::debug_string_array(u32 array_pointer)
{
auto const suppressor(machine().disable_side_effects());
std::string s("");
while (true)
{
u32 string_pointer;
if (!get_dcammu().load<u32>(m_ssw, array_pointer, [&string_pointer](u32 v) { string_pointer = v; }))
break;
if (string_pointer == 0)
break;
if (!s.empty())
s += ", ";
s += '\"' + debug_string(string_pointer) + '\"';
array_pointer += 4;
}
return s;
}

View File

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

View File

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

View File

@ -241,27 +241,78 @@
void interpro_state::machine_start()
{
m_led.resolve();
m_diag_led.resolve();
// FIXME: disabled for now to avoid cold start diagnostic errors
//m_sreg_ctrl2 = CTRL2_COLDSTART | CTRL2_PWRUP;
m_sreg_ctrl2 = 0;
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));
save_item(NAME(m_sreg_ctrl3));
save_item(NAME(m_error));
save_item(NAME(m_status));
save_item(NAME(m_led));
}
void interpro_state::machine_reset()
{
// flash rom requires the following values
m_sreg_error = 0;
m_sreg_status = 0x400;
m_sreg_ctrl1 = CTRL1_FLOPLOW;
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_ctrl2 = 0; // CTRL2_COLDSTART
}
void turquoise_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 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()
{
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(interpro_state::sreg_ctrl2_w)
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(emerald_state::ctrl2_w)
{
LOG("control register 2 data 0x%04x mem_mask 0x%04x (%s)\n", data, mem_mask, machine().describe_context());
if (data & CTRL2_RESET)
{
m_sreg_ctrl2 &= ~CTRL2_COLDSTART;
m_ctrl2 &= ~CTRL2_COLDSTART;
machine().schedule_soft_reset();
}
else
m_sreg_ctrl2 = (m_sreg_ctrl2 & ~CTRL2_MASK) | (data & CTRL2_MASK);
m_ctrl2 = (m_ctrl2 & ~CTRL2_WMASK) | (data & CTRL2_WMASK);
}
WRITE16_MEMBER(sapphire_state::sreg_ctrl2_w)
WRITE16_MEMBER(turquoise_state::ctrl2_w)
{
interpro_state::sreg_ctrl2_w(space, offset, data, mem_mask);
LOG("control register 2 data 0x%04x mem_mask 0x%04x (%s)\n", data, mem_mask, machine().describe_context());
if (data & CTRL2_RESET)
{
m_ctrl2 &= ~CTRL2_COLDSTART;
machine().schedule_soft_reset();
}
else
m_ctrl2 = (m_ctrl2 & ~CTRL2_WMASK) | (data & CTRL2_WMASK);
}
WRITE16_MEMBER(sapphire_state::ctrl2_w)
{
LOG("control register 2 data 0x%04x mem_mask 0x%04x (%s)\n", data, mem_mask, machine().describe_context());
if (data & CTRL2_RESET)
{
m_ctrl2 &= ~CTRL2_COLDSTART;
machine().schedule_soft_reset();
}
else
m_ctrl2 = (m_ctrl2 & ~0x4d) | (data & 0x4d);
// enable/disable programming power on both flash devices
m_flash_lo->vpp(data & CTRL2_FLASHEN ? ASSERT_LINE : CLEAR_LINE);
m_flash_hi->vpp(data & CTRL2_FLASHEN ? ASSERT_LINE : CLEAR_LINE);
m_flash_lsb->vpp(data & CTRL2_FLASHEN ? ASSERT_LINE : CLEAR_LINE);
m_flash_msb->vpp(data & CTRL2_FLASHEN ? ASSERT_LINE : CLEAR_LINE);
}
READ16_MEMBER(interpro_state::sreg_error_r)
READ16_MEMBER(interpro_state::error_r)
{
const u16 result = m_sreg_error;
const u16 result = m_error;
// clear error register on read
if (!machine().side_effects_disabled())
m_sreg_error = 0;
m_error = 0;
return result;
}
READ32_MEMBER(interpro_state::unmapped_r)
{
if (!machine().side_effects_disabled())
{
// flag non-existent memory error in system error register
m_error |= (ERROR_SRXNEM | ERROR_SRXVALID);
// tell ioga to raise a bus error
m_ioga->bus_error(space, interpro_ioga_device::BINFO_BERR | interpro_ioga_device::BINFO_SNAPOK, offset << 2);
}
return space.unmap();
}
WRITE32_MEMBER(interpro_state::unmapped_w)
{
if (!machine().side_effects_disabled())
{
// flag non-existent memory error in system error register
m_error |= (ERROR_SRXNEM | ERROR_SRXVALID);
// tell ioga to raise a bus error
m_ioga->bus_error(space, interpro_ioga_device::BINFO_BERR | interpro_ioga_device::BINFO_SNAPOK, offset << 2);
}
}
READ32_MEMBER(sapphire_state::unmapped_r)
{
// check if non-existent memory errors are enabled
@ -340,7 +480,7 @@ READ32_MEMBER(sapphire_state::unmapped_r)
if (m_arbga->tctrl_r(space, offset, mem_mask) & interpro_arbga_device::TCTRL_ENNEM)
{
// flag non-existent memory error in system error register
m_sreg_error |= (ERROR_SRXNEM | ERROR_SRXVALID);
m_error |= (ERROR_SRXNEM | ERROR_SRXVALID);
// tell ioga to raise a bus error
m_ioga->bus_error(space, interpro_ioga_device::BINFO_BERR | interpro_ioga_device::BINFO_SNAPOK, offset << 2);
@ -355,7 +495,7 @@ WRITE32_MEMBER(sapphire_state::unmapped_w)
if (m_arbga->tctrl_r(space, offset, mem_mask) & interpro_arbga_device::TCTRL_ENNEM)
{
// flag non-existent memory error in system error register
m_sreg_error |= (ERROR_SRXNEM | ERROR_SRXVALID);
m_error |= (ERROR_SRXNEM | ERROR_SRXVALID);
// tell ioga to raise a bus error
m_ioga->bus_error(space, interpro_ioga_device::BINFO_BERR | interpro_ioga_device::BINFO_SNAPOK, offset << 2);
@ -379,18 +519,18 @@ READ8_MEMBER(interpro_state::nodeid_r)
void interpro_state::interpro_common_map(address_map &map)
{
//map(0x00000000, 0xffffffff).rw(FUNC(interpro_state::unmapped_r), FUNC(interpro_state::unmapped_w));
// FIXME: don't know what this range is for
map(0x08000000, 0x08000fff).noprw();
map(0x4f007e00, 0x4f007eff).m(m_sga, FUNC(interpro_sga_device::map));
map(0x7f000100, 0x7f00011f).m(m_fdc, FUNC(upd765_family_device::map)).umask32(0x000000ff);
map(0x7f000300, 0x7f000301).r(FUNC(interpro_state::sreg_error_r));
map(0x7f000304, 0x7f000305).rw(FUNC(interpro_state::sreg_status_r), FUNC(interpro_state::sreg_led_w));
map(0x7f000308, 0x7f000309).rw(FUNC(interpro_state::sreg_ctrl1_r), FUNC(interpro_state::sreg_ctrl1_w));
map(0x7f00030c, 0x7f00030d).rw(FUNC(interpro_state::sreg_ctrl2_r), FUNC(interpro_state::sreg_ctrl2_w));
map(0x7f00031c, 0x7f00031d).rw(FUNC(interpro_state::sreg_ctrl3_r), FUNC(interpro_state::sreg_ctrl3_w));
map(0x7f000300, 0x7f000301).r(FUNC(interpro_state::error_r));
map(0x7f000304, 0x7f000305).rw(FUNC(interpro_state::status_r), FUNC(interpro_state::led_w));
map(0x7f000308, 0x7f000309).rw(FUNC(interpro_state::ctrl1_r), FUNC(interpro_state::ctrl1_w));
map(0x7f00030c, 0x7f00030d).rw(FUNC(interpro_state::ctrl2_r), FUNC(interpro_state::ctrl2_w));
map(0x7f000400, 0x7f00040f).rw(m_scc1, FUNC(z80scc_device::ba_cd_inv_r), FUNC(z80scc_device::ba_cd_inv_w)).umask32(0x000000ff);
map(0x7f000410, 0x7f00041f).rw(m_scc2, FUNC(z80scc_device::ba_cd_inv_r), FUNC(z80scc_device::ba_cd_inv_w)).umask32(0x000000ff);
@ -429,13 +569,15 @@ void emerald_state::emerald_base_map(address_map &map)
map(0x7f000229, 0x7f000229).w(m_scsi, FUNC(ncr53c90a_device::test_w));
map(0x7f00022d, 0x7f00022d).rw(m_scsi, FUNC(ncr53c90a_device::conf2_r), FUNC(ncr53c90a_device::conf2_w));
map(0x7f000300, 0x7f000300).w(FUNC(emerald_state::sreg_error_w));
map(0x7f000300, 0x7f000300).w(FUNC(emerald_state::error_w));
map(0x7f000600, 0x7f00067f).rom().region(INTERPRO_NODEID_TAG, 0);
}
void emerald_state::emerald_main_map(address_map &map)
{
//map(0x00000000, 0xffffffff).rw(FUNC(interpro_state::unmapped_r), FUNC(interpro_state::unmapped_w));
emerald_base_map(map);
map(0x00000000, 0x00ffffff).ram().share(RAM_TAG);
@ -462,13 +604,15 @@ void turquoise_state::turquoise_base_map(address_map &map)
map(0x7f000229, 0x7f000229).w(m_scsi, FUNC(ncr53c90a_device::test_w));
map(0x7f00022d, 0x7f00022d).rw(m_scsi, FUNC(ncr53c90a_device::conf2_r), FUNC(ncr53c90a_device::conf2_w));
map(0x7f000300, 0x7f000300).w(FUNC(turquoise_state::sreg_error_w));
map(0x7f000300, 0x7f000300).w(FUNC(turquoise_state::error_w));
map(0x7f000600, 0x7f00067f).rom().region(INTERPRO_NODEID_TAG, 0);
}
void turquoise_state::turquoise_main_map(address_map &map)
{
//map(0x00000000, 0xffffffff).rw(FUNC(interpro_state::unmapped_r), FUNC(interpro_state::unmapped_w));
turquoise_base_map(map);
map(0x00000000, 0x00ffffff).ram().share(RAM_TAG);
@ -479,7 +623,7 @@ void sapphire_state::sapphire_base_map(address_map &map)
{
interpro_common_map(map);
map(0x40000000, 0x4000004f).m(INTERPRO_MCGA_TAG, FUNC(interpro_fmcc_device::map));
map(0x40000000, 0x4000004f).m(m_mcga, FUNC(interpro_fmcc_device::map));
map(0x7f000200, 0x7f0002ff).m(m_arbga, FUNC(interpro_arbga_device::map));
map(0x7f000600, 0x7f00060f).r(FUNC(sapphire_state::nodeid_r)).umask32(0x000000ff);
@ -509,8 +653,8 @@ void sapphire_state::sapphire_main_map(address_map &map)
map(0x00000000, 0x00ffffff).ram().share(RAM_TAG);
map(0x7f100000, 0x7f11ffff).rom().region(INTERPRO_EPROM_TAG, 0);
map(0x7f180000, 0x7f1fffff).rw(INTERPRO_FLASH_TAG "_lo", FUNC(intel_28f010_device::read), FUNC(intel_28f010_device::write)).umask32(0x00ff00ff).mask(0x3ffff);
map(0x7f180000, 0x7f1fffff).rw(INTERPRO_FLASH_TAG "_hi", FUNC(intel_28f010_device::read), FUNC(intel_28f010_device::write)).umask32(0xff00ff00).mask(0x3ffff);
map(0x7f180000, 0x7f1fffff).rw(m_flash_lsb, FUNC(intel_28f010_device::read), FUNC(intel_28f010_device::write)).umask32(0x00ff00ff).mask(0x3ffff);
map(0x7f180000, 0x7f1fffff).rw(m_flash_msb, FUNC(intel_28f010_device::read), FUNC(intel_28f010_device::write)).umask32(0xff00ff00).mask(0x3ffff);
// HACK: for SRX bus Sapphire only
//map(0x8f007f80, 0x8f007fff).rom().region(INTERPRO_IDPROM_TAG, 0);
@ -520,24 +664,22 @@ void emerald_state::emerald_io_map(address_map &map)
{
emerald_base_map(map);
map(0x00000800, 0x000009ff).m(INTERPRO_MMU_TAG "_d", FUNC(cammu_c3_device::map));
map(0x00000a00, 0x00000bff).m(INTERPRO_MMU_TAG "_i", FUNC(cammu_c3_device::map));
map(0x00000c00, 0x00000dff).m(INTERPRO_MMU_TAG "_d", FUNC(cammu_c3_device::map_global));
map(0x00000800, 0x000009ff).m(m_d_cammu, FUNC(cammu_c3_device::map));
map(0x00000a00, 0x00000bff).m(m_i_cammu, FUNC(cammu_c3_device::map));
map(0x00000c00, 0x00000dff).m(m_d_cammu, FUNC(cammu_c3_device::map_global));
}
void turquoise_state::turquoise_io_map(address_map &map)
{
turquoise_base_map(map);
map(0x00000800, 0x000009ff).m(INTERPRO_MMU_TAG "_d", FUNC(cammu_c3_device::map));
map(0x00000a00, 0x00000bff).m(INTERPRO_MMU_TAG "_i", FUNC(cammu_c3_device::map));
map(0x00000c00, 0x00000dff).m(INTERPRO_MMU_TAG "_d", FUNC(cammu_c3_device::map_global));
map(0x00000800, 0x000009ff).m(m_d_cammu, FUNC(cammu_c3_device::map));
map(0x00000a00, 0x00000bff).m(m_i_cammu, FUNC(cammu_c3_device::map));
map(0x00000c00, 0x00000dff).m(m_d_cammu, FUNC(cammu_c3_device::map_global));
}
void sapphire_state::sapphire_io_map(address_map &map)
{
//map(0x00000000, 0xffffffff).rw(FUNC(sapphire_state::unmapped_r), FUNC(sapphire_state::unmapped_w));
sapphire_base_map(map);
map(0x00000000, 0x00001fff).m(m_mmu, FUNC(cammu_c4_device::map));
@ -554,17 +696,17 @@ void interpro_state::interpro_boot_map(address_map &map)
void emerald_state::interpro_82586_map(address_map &map)
{
map(0x00000000, 0x00ffffff).rw(INTERPRO_IOGA_TAG, FUNC(turquoise_ioga_device::eth_r), FUNC(turquoise_ioga_device::eth_w));
map(0x00000000, 0x00ffffff).rw(m_ioga, FUNC(emerald_ioga_device::eth_r), FUNC(emerald_ioga_device::eth_w));
}
void turquoise_state::interpro_82586_map(address_map &map)
{
map(0x00000000, 0x00ffffff).rw(INTERPRO_IOGA_TAG, FUNC(turquoise_ioga_device::eth_r), FUNC(turquoise_ioga_device::eth_w));
map(0x00000000, 0x00ffffff).rw(m_ioga, FUNC(turquoise_ioga_device::eth_r), FUNC(turquoise_ioga_device::eth_w));
}
void sapphire_state::interpro_82596_map(address_map &map)
{
map(0x00000000, 0xffffffff).rw(INTERPRO_IOGA_TAG, FUNC(sapphire_ioga_device::eth_r), FUNC(sapphire_ioga_device::eth_w));
map(0x00000000, 0xffffffff).rw(m_ioga, FUNC(sapphire_ioga_device::eth_r), FUNC(sapphire_ioga_device::eth_w));
}
FLOPPY_FORMATS_MEMBER(interpro_state::floppy_formats)
@ -581,35 +723,35 @@ MACHINE_CONFIG_START(interpro_state::interpro_scc1)
MCFG_DEVICE_MODIFY(INTERPRO_SCC1_TAG)
MCFG_Z80SCC_OUT_TXDA_CB(WRITELINE(INTERPRO_SERIAL_PORT1_TAG, rs232_port_device, write_txd))
MCFG_Z80SCC_OUT_TXDB_CB(WRITELINE(INTERPRO_SERIAL_PORT2_TAG, rs232_port_device, write_txd))
MCFG_Z80SCC_OUT_INT_CB(WRITELINE(INTERPRO_IOGA_TAG, interpro_ioga_device, ir11_w))
MCFG_Z80SCC_OUT_WREQA_CB(WRITELINE(INTERPRO_IOGA_TAG, interpro_ioga_device, drq_serial1))
MCFG_Z80SCC_OUT_WREQB_CB(WRITELINE(INTERPRO_IOGA_TAG, interpro_ioga_device, drq_serial2))
MCFG_Z80SCC_OUT_INT_CB(WRITELINE(m_ioga, interpro_ioga_device, ir11_w))
MCFG_Z80SCC_OUT_WREQA_CB(WRITELINE(m_ioga, interpro_ioga_device, drq_serial1))
MCFG_Z80SCC_OUT_WREQB_CB(WRITELINE(m_ioga, interpro_ioga_device, drq_serial2))
MCFG_DEVICE_ADD(INTERPRO_SERIAL_PORT1_TAG, RS232_PORT, default_rs232_devices, nullptr)
MCFG_RS232_RXD_HANDLER(WRITELINE(INTERPRO_SCC1_TAG, z80scc_device, rxa_w))
MCFG_RS232_DCD_HANDLER(WRITELINE(INTERPRO_SCC1_TAG, z80scc_device, dcda_w))
MCFG_RS232_CTS_HANDLER(WRITELINE(INTERPRO_SCC1_TAG, z80scc_device, ctsa_w))
MCFG_RS232_RXD_HANDLER(WRITELINE(m_scc1, z80scc_device, rxa_w))
MCFG_RS232_DCD_HANDLER(WRITELINE(m_scc1, z80scc_device, dcda_w))
MCFG_RS232_CTS_HANDLER(WRITELINE(m_scc1, z80scc_device, ctsa_w))
MCFG_DEVICE_ADD(INTERPRO_SERIAL_PORT2_TAG, RS232_PORT, default_rs232_devices, nullptr)
MCFG_RS232_RXD_HANDLER(WRITELINE(INTERPRO_SCC1_TAG, z80scc_device, rxb_w))
MCFG_RS232_DCD_HANDLER(WRITELINE(INTERPRO_SCC1_TAG, z80scc_device, dcdb_w))
MCFG_RS232_CTS_HANDLER(WRITELINE(INTERPRO_SCC1_TAG, z80scc_device, ctsb_w))
MCFG_RS232_RXD_HANDLER(WRITELINE(m_scc1, z80scc_device, rxb_w))
MCFG_RS232_DCD_HANDLER(WRITELINE(m_scc1, z80scc_device, dcdb_w))
MCFG_RS232_CTS_HANDLER(WRITELINE(m_scc1, z80scc_device, ctsb_w))
MACHINE_CONFIG_END
MACHINE_CONFIG_START(interpro_state::interpro_scc2)
MCFG_DEVICE_MODIFY(INTERPRO_SCC2_TAG)
MCFG_Z80SCC_OUT_TXDA_CB(WRITELINE(INTERPRO_KEYBOARD_PORT_TAG, interpro_keyboard_port_device, write_txd))
MCFG_Z80SCC_OUT_TXDB_CB(WRITELINE(INTERPRO_SERIAL_PORT0_TAG, rs232_port_device, write_txd))
MCFG_Z80SCC_OUT_INT_CB(WRITELINE(INTERPRO_IOGA_TAG, interpro_ioga_device, ir11_w))
MCFG_Z80SCC_OUT_WREQB_CB(WRITELINE(INTERPRO_IOGA_TAG, interpro_ioga_device, drq_serial0))
MCFG_Z80SCC_OUT_INT_CB(WRITELINE(m_ioga, interpro_ioga_device, ir11_w))
MCFG_Z80SCC_OUT_WREQB_CB(WRITELINE(m_ioga, interpro_ioga_device, drq_serial0))
MCFG_INTERPRO_KEYBOARD_PORT_ADD(INTERPRO_KEYBOARD_PORT_TAG, interpro_keyboard_devices, "lle_en_us")
MCFG_INTERPRO_KEYBOARD_RXD_HANDLER(WRITELINE(INTERPRO_SCC2_TAG, z80scc_device, rxa_w))
MCFG_INTERPRO_KEYBOARD_RXD_HANDLER(WRITELINE(m_scc2, z80scc_device, rxa_w))
MCFG_DEVICE_ADD(INTERPRO_SERIAL_PORT0_TAG, RS232_PORT, default_rs232_devices, nullptr)
MCFG_RS232_RXD_HANDLER(WRITELINE(INTERPRO_SCC2_TAG, z80scc_device, rxb_w))
MCFG_RS232_DCD_HANDLER(WRITELINE(INTERPRO_SCC2_TAG, z80scc_device, dcdb_w))
MCFG_RS232_CTS_HANDLER(WRITELINE(INTERPRO_SCC2_TAG, z80scc_device, ctsb_w))
MCFG_RS232_RXD_HANDLER(WRITELINE(m_scc2, z80scc_device, rxb_w))
MCFG_RS232_DCD_HANDLER(WRITELINE(m_scc2, z80scc_device, dcdb_w))
MCFG_RS232_CTS_HANDLER(WRITELINE(m_scc2, z80scc_device, ctsb_w))
MACHINE_CONFIG_END
static void interpro_scsi_devices(device_slot_interface &device)
@ -642,24 +784,29 @@ void interpro_state::interpro_scsi_adapter(device_t *device)
MCFG_NCR5390_DRQ_HANDLER(WRITELINE(":" INTERPRO_IOGA_TAG, interpro_ioga_device, drq_scsi))
}
void interpro_state::interpro_cdrom(device_t *device)
{
// FIXME: enable when dependent code is committed
//downcast<nscsi_cdrom_device &>(*device).set_block_size(512);
}
MACHINE_CONFIG_START(interpro_state::ioga)
MCFG_DEVICE_MODIFY(INTERPRO_IOGA_TAG)
MCFG_INTERPRO_IOGA_NMI_CB(INPUTLINE(INTERPRO_CPU_TAG, INPUT_LINE_NMI))
MCFG_INTERPRO_IOGA_IRQ_CB(INPUTLINE(INTERPRO_CPU_TAG, INPUT_LINE_IRQ0))
MCFG_INTERPRO_IOGA_IVEC_CB(WRITE8(INTERPRO_CPU_TAG, clipper_device, set_ivec))
MCFG_INTERPRO_IOGA_NMI_CB(INPUTLINE(m_maincpu, INPUT_LINE_NMI))
MCFG_INTERPRO_IOGA_IRQ_CB(INPUTLINE(m_maincpu, INPUT_LINE_IRQ0))
MCFG_INTERPRO_IOGA_IVEC_CB(WRITE8(m_maincpu, clipper_device, set_ivec))
// ioga dma and serial dma channels
// TODO: check serial dma channels - scc2chanA (keyboard) has no dma
//MCFG_INTERPRO_IOGA_DMA_CB(0, unknown) // plotter
MCFG_INTERPRO_IOGA_DMA_CB(1, READ8(INTERPRO_SCSI_DEVICE_TAG, ncr53c90a_device, mdma_r), WRITE8(INTERPRO_SCSI_DEVICE_TAG, ncr53c90a_device, mdma_w))
MCFG_INTERPRO_IOGA_DMA_CB(2, READ8(INTERPRO_FDC_TAG, upd765_family_device, mdma_r), WRITE8(INTERPRO_FDC_TAG, upd765_family_device, mdma_w))
MCFG_INTERPRO_IOGA_SERIAL_DMA_CB(0, READ8(INTERPRO_SCC2_TAG, z80scc_device, db_r), WRITE8(INTERPRO_SCC2_TAG, z80scc_device, db_w))
MCFG_INTERPRO_IOGA_SERIAL_DMA_CB(1, READ8(INTERPRO_SCC1_TAG, z80scc_device, da_r), WRITE8(INTERPRO_SCC1_TAG, z80scc_device, da_w))
MCFG_INTERPRO_IOGA_SERIAL_DMA_CB(2, READ8(INTERPRO_SCC1_TAG, z80scc_device, db_r), WRITE8(INTERPRO_SCC1_TAG, z80scc_device, db_w))
MCFG_INTERPRO_IOGA_DMA_CB(2, READ8(m_fdc, upd765_family_device, mdma_r), WRITE8(m_fdc, upd765_family_device, mdma_w))
MCFG_INTERPRO_IOGA_SERIAL_DMA_CB(0, READ8(m_scc2, z80scc_device, db_r), WRITE8(m_scc2, z80scc_device, db_w))
MCFG_INTERPRO_IOGA_SERIAL_DMA_CB(1, READ8(m_scc1, z80scc_device, da_r), WRITE8(m_scc1, z80scc_device, da_w))
MCFG_INTERPRO_IOGA_SERIAL_DMA_CB(2, READ8(m_scc1, z80scc_device, db_r), WRITE8(m_scc1, z80scc_device, db_w))
// ioga floppy terminal count, ethernet channel attention
MCFG_INTERPRO_IOGA_FDCTC_CB(WRITELINE(INTERPRO_FDC_TAG, upd765_family_device, tc_line_w))
MCFG_INTERPRO_IOGA_ETH_CA_CB(WRITELINE(INTERPRO_ETH_TAG, i82586_base_device, ca))
MCFG_INTERPRO_IOGA_FDCTC_CB(WRITELINE(m_fdc, upd765_family_device, tc_line_w))
MCFG_INTERPRO_IOGA_ETH_CA_CB(WRITELINE(m_eth, i82586_base_device, ca))
MACHINE_CONFIG_END
static INPUT_PORTS_START(interpro)
@ -673,25 +820,26 @@ MACHINE_CONFIG_START(interpro_state::interpro)
// memory control gate array
// srx gate array
MCFG_DEVICE_ADD(INTERPRO_SGA_TAG, INTERPRO_SGA, 0)
MCFG_INTERPRO_SGA_BERR_CB(WRITE32(INTERPRO_IOGA_TAG, interpro_ioga_device, bus_error))
MCFG_DEVICE_ADD(m_sga, INTERPRO_SGA, 0)
MCFG_INTERPRO_SGA_BERR_CB(WRITE32(m_ioga, interpro_ioga_device, bus_error))
// floppy
// serial
// real-time clock/non-volatile memory
MCFG_DEVICE_ADD(INTERPRO_RTC_TAG, MC146818, 32.768_kHz_XTAL)
MCFG_DEVICE_ADD(m_rtc, MC146818, 32.768_kHz_XTAL)
MCFG_MC146818_UTC(true)
MCFG_MC146818_IRQ_HANDLER(WRITELINE(INTERPRO_IOGA_TAG, interpro_ioga_device, ir9_w))
MCFG_MC146818_IRQ_HANDLER(WRITELINE(m_ioga, interpro_ioga_device, ir9_w))
// scsi
MCFG_NSCSI_BUS_ADD(INTERPRO_SCSI_TAG)
MCFG_DEVICE_ADD(m_scsibus, NSCSI_BUS, 0)
MCFG_NSCSI_ADD(INTERPRO_SCSI_TAG ":0", interpro_scsi_devices, "harddisk", false)
MCFG_NSCSI_ADD(INTERPRO_SCSI_TAG ":1", interpro_scsi_devices, nullptr, false)
MCFG_NSCSI_ADD(INTERPRO_SCSI_TAG ":2", interpro_scsi_devices, nullptr, false)
MCFG_NSCSI_ADD(INTERPRO_SCSI_TAG ":3", interpro_scsi_devices, nullptr, false)
MCFG_NSCSI_ADD(INTERPRO_SCSI_TAG ":4", interpro_scsi_devices, "cdrom", false)
MCFG_SLOT_OPTION_MACHINE_CONFIG("cdrom", interpro_cdrom)
MCFG_NSCSI_ADD(INTERPRO_SCSI_TAG ":5", interpro_scsi_devices, nullptr, false)
MCFG_NSCSI_ADD(INTERPRO_SCSI_TAG ":6", interpro_scsi_devices, nullptr, false)
@ -702,7 +850,7 @@ MACHINE_CONFIG_START(interpro_state::interpro)
// mouse
MCFG_DEVICE_ADD(INTERPRO_MOUSE_PORT_TAG, INTERPRO_MOUSE_PORT, 0)
MCFG_DEVICE_SLOT_INTERFACE(interpro_mouse_devices, "interpro_mouse", false)
MCFG_MOUSE_STATE_CB(WRITE32(INTERPRO_IOGA_TAG, interpro_ioga_device, mouse_status_w))
MCFG_MOUSE_STATE_CB(WRITE32(m_ioga, interpro_ioga_device, mouse_status_w))
// system layout
MCFG_DEFAULT_LAYOUT(layout_interpro)
@ -714,17 +862,17 @@ MACHINE_CONFIG_END
MACHINE_CONFIG_START(emerald_state::emerald)
interpro(config);
MCFG_DEVICE_ADD(INTERPRO_CPU_TAG, CLIPPER_C300, 12.5_MHz_XTAL)
MCFG_DEVICE_ADD(m_maincpu, CLIPPER_C300, 12.5_MHz_XTAL)
MCFG_DEVICE_ADDRESS_MAP(0, emerald_main_map)
MCFG_DEVICE_ADDRESS_MAP(1, emerald_io_map)
MCFG_DEVICE_ADDRESS_MAP(2, interpro_boot_map)
MCFG_DEVICE_IRQ_ACKNOWLEDGE_DEVICE(INTERPRO_IOGA_TAG, interpro_ioga_device, acknowledge_interrupt)
MCFG_DEVICE_ADD(INTERPRO_MMU_TAG "_i", CAMMU_C3, 0)
MCFG_CAMMU_EXCEPTION_CB(WRITE16(INTERPRO_CPU_TAG, clipper_device, set_exception))
MCFG_DEVICE_ADD(m_i_cammu, CAMMU_C3, 0)
MCFG_CAMMU_EXCEPTION_CB(WRITE16(m_maincpu, clipper_device, set_exception))
MCFG_DEVICE_ADD(INTERPRO_MMU_TAG "_d", CAMMU_C3, 0)
MCFG_CAMMU_EXCEPTION_CB(WRITE16(INTERPRO_CPU_TAG, clipper_device, set_exception))
MCFG_DEVICE_ADD(m_d_cammu, CAMMU_C3, 0)
MCFG_CAMMU_EXCEPTION_CB(WRITE16(m_maincpu, clipper_device, set_exception))
MCFG_CAMMU_LINK(INTERPRO_MMU_TAG "_i")
// boot fails memory test without this
@ -732,25 +880,22 @@ MACHINE_CONFIG_START(emerald_state::emerald)
MCFG_RAM_DEFAULT_VALUE(0x00)
// memory control gate array
MCFG_DEVICE_ADD(INTERPRO_MCGA_TAG, INTERPRO_MCGA, 0)
MCFG_DEVICE_ADD(m_mcga, INTERPRO_MCGA, 0)
// floppy controller
// FIXME: not sure this should really be ready connected, but prevents crash at startup
MCFG_I82072_ADD(INTERPRO_FDC_TAG, true)
MCFG_UPD765_INTRQ_CALLBACK(WRITELINE(INTERPRO_IOGA_TAG, interpro_ioga_device, ir1_w))
MCFG_UPD765_DRQ_CALLBACK(WRITELINE(INTERPRO_IOGA_TAG, interpro_ioga_device, drq_floppy))
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 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)
// 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

View File

@ -79,7 +79,7 @@ public:
, m_scsibus(*this, INTERPRO_SCSI_TAG)
, m_eth(*this, INTERPRO_ETH_TAG)
, m_ioga(*this, INTERPRO_IOGA_TAG)
, m_led(*this, "digit0")
, m_diag_led(*this, "digit0")
{
}
@ -98,7 +98,10 @@ public:
void init_common();
enum sreg_error_mask
virtual DECLARE_READ32_MEMBER(unmapped_r);
virtual DECLARE_WRITE32_MEMBER(unmapped_w);
enum error_mask : u16
{
ERROR_BPID4 = 0x0001,
ERROR_SRXMMBE = 0x0002,
@ -110,11 +113,11 @@ public:
ERROR_BG = 0x0070,
ERROR_BUSHOG = 0x0080
};
DECLARE_READ16_MEMBER(sreg_error_r);
DECLARE_READ16_MEMBER(error_r);
DECLARE_WRITE16_MEMBER(sreg_led_w);
DECLARE_WRITE16_MEMBER(led_w);
enum sreg_status_mask
enum status_mask : u16
{
STATUS_YELLOW_ZONE = 0x0001,
STATUS_SRNMI = 0x0002,
@ -122,38 +125,12 @@ public:
STATUS_RED_ZONE = 0x0008,
STATUS_BP = 0x00f0
};
DECLARE_READ16_MEMBER(sreg_status_r) { return m_sreg_status; }
DECLARE_READ16_MEMBER(status_r) { return m_status; }
enum sreg_ctrl1_mask
{
CTRL1_FLOPLOW = 0x0001, // 0 = 5.25" floppy selected
CTRL1_FLOPRDY = 0x0002, // 1 = plotter fifo empty?
CTRL1_LEDENA = 0x0004, // 0 = led display disabled
CTRL1_LEDDP = 0x0008, // 0 = led right decimal point disabled
CTRL1_ETHLOOP = 0x0010, // 1 = mmbe enabled
CTRL1_ETHDTR = 0x0020, // 0 = modem dtr pin activated
CTRL1_ETHRMOD = 0x0040, // 0 = sytem configured for remote modems
CTRL1_FIFOACTIVE = 0x0080 // 0 = plotter fifos reset
};
DECLARE_READ16_MEMBER(sreg_ctrl1_r) { return m_sreg_ctrl1; }
DECLARE_WRITE16_MEMBER(sreg_ctrl1_w);
enum sreg_ctrl2_mask
{
CTRL2_PWRUP = 0x0003, // 3 = power supply voltage adjusted up by 5%
CTRL2_HOLDOFF = 0x0004, // 0 = power supply will shut down 0.33 seconds after switch is turned off
CTRL2_EXTNMIENA = 0x0008, // 0 = power nmi disabled
CTRL2_COLDSTART = 0x0010, // 1 = cold start flag
CTRL2_RESET = 0x0020, // 0 = soft reset
CTRL2_BUSENA = 0x0040, // 0 = clear bus grant error
CTRL2_FLASHEN = 0x0080, // 0 = flash eprom writes disabled
CTRL2_MASK = 0x004d
};
DECLARE_READ16_MEMBER(sreg_ctrl2_r) { return m_sreg_ctrl2; }
virtual DECLARE_WRITE16_MEMBER(sreg_ctrl2_w);
DECLARE_READ16_MEMBER(sreg_ctrl3_r) { return m_sreg_ctrl3; }
DECLARE_WRITE16_MEMBER(sreg_ctrl3_w) { m_sreg_ctrl3 = data; }
virtual DECLARE_READ16_MEMBER(ctrl1_r) = 0;
virtual DECLARE_WRITE16_MEMBER(ctrl1_w) = 0;
virtual DECLARE_READ16_MEMBER(ctrl2_r) = 0;
virtual DECLARE_WRITE16_MEMBER(ctrl2_w) = 0;
DECLARE_READ8_MEMBER(nodeid_r);
@ -164,6 +141,7 @@ public:
void interpro_scc2(machine_config &config);
void interpro(machine_config &config);
static void interpro_scsi_adapter(device_t *device);
static void interpro_cdrom(device_t *device);
void interpro_boot_map(address_map &map);
void interpro_common_map(address_map &map);
@ -171,16 +149,12 @@ protected:
virtual void machine_start() override;
virtual void machine_reset() override;
output_finder<> m_led;
output_finder<> m_diag_led;
emu_timer *m_reset_timer;
u16 m_sreg_error;
u16 m_sreg_status;
u16 m_sreg_led;
u16 m_sreg_ctrl1;
u16 m_sreg_ctrl2;
u16 m_sreg_ctrl3;
u16 m_error;
u16 m_status;
u16 m_led;
};
class emerald_state : public interpro_state
@ -194,7 +168,38 @@ public:
{
}
DECLARE_WRITE8_MEMBER(sreg_error_w) { m_sreg_error = data; }
DECLARE_WRITE8_MEMBER(error_w) { m_error = data; }
enum ctrl1_mask : u16
{
CTRL1_FLOPLOW = 0x0001, // 3.5" floppy select
CTRL1_FLOPRDY = 0x0002, // floppy ready enable?
CTRL1_LEDENA = 0x0004, // led display enable
CTRL1_LEDDP = 0x0008, // led right decimal point enable
CTRL1_ETHLOOP = 0x0010, // ethernet loopback enable?
CTRL1_ETHDTR = 0x0020, // modem dtr pin enable?
CTRL1_ETHRMOD = 0x0040, // remote modem configured (read)?
CTRL1_CLIPRESET = 0x0040, // hard reset (write)?
CTRL1_FIFOACTIVE = 0x0080 // plotter fifo active?
};
DECLARE_READ16_MEMBER(ctrl1_r) override { return m_ctrl1; }
DECLARE_WRITE16_MEMBER(ctrl1_w) override;
enum ctrl2_mask : u16
{
CTRL2_PWRUP = 0x0001, // power supply voltage adjust?
CRTL2_PWRENA = 0x0002, // ?
CTRL2_HOLDOFF = 0x0004, // power supply shut down delay
CTRL2_EXTNMIENA = 0x0008, // power nmi enable
CTRL2_COLDSTART = 0x0010, // cold start flag
CTRL2_RESET = 0x0020, // soft reset
CTRL2_BUSENA = 0x0040, // clear bus grant error
CTRL2_FRCPARITY = 0x0080, // ?
CTRL2_WMASK = 0x000f
};
DECLARE_READ16_MEMBER(ctrl2_r) override { return m_ctrl2; }
DECLARE_WRITE16_MEMBER(ctrl2_w) override;
required_device<cammu_c3_device> m_d_cammu;
required_device<cammu_c3_device> m_i_cammu;
@ -206,6 +211,14 @@ public:
void emerald_base_map(address_map &map);
void emerald_main_map(address_map &map);
void emerald_io_map(address_map &map);
protected:
virtual void machine_start() override;
virtual void machine_reset() override;
private:
u16 m_ctrl1;
u16 m_ctrl2;
};
class turquoise_state : public interpro_state
@ -219,7 +232,38 @@ public:
{
}
DECLARE_WRITE8_MEMBER(sreg_error_w) { m_sreg_error = data; }
DECLARE_WRITE8_MEMBER(error_w) { m_error = data; }
enum ctrl1_mask : u16
{
CTRL1_FLOPLOW = 0x0001, // 3.5" floppy select
CTRL1_FLOPRDY = 0x0002, // floppy ready enable?
CTRL1_LEDENA = 0x0004, // led display enable
CTRL1_LEDDP = 0x0008, // led right decimal point enable
CTRL1_ETHLOOP = 0x0010, // ethernet loopback enable?
CTRL1_ETHDTR = 0x0020, // modem dtr pin enable?
CTRL1_ETHRMOD = 0x0040, // remote modem configured (read)?
CTRL1_CLIPRESET = 0x0040, // hard reset (write)?
CTRL1_FIFOACTIVE = 0x0080 // plotter fifo active?
};
DECLARE_READ16_MEMBER(ctrl1_r) override { return m_ctrl1; }
DECLARE_WRITE16_MEMBER(ctrl1_w) override;
enum ctrl2_mask : u16
{
CTRL2_PWRUP = 0x0001, // power supply voltage adjust?
CRTL2_PWRENA = 0x0002, // ?
CTRL2_HOLDOFF = 0x0004, // power supply shut down delay
CTRL2_EXTNMIENA = 0x0008, // power nmi enable
CTRL2_COLDSTART = 0x0010, // cold start flag
CTRL2_RESET = 0x0020, // soft reset
CTRL2_BUSENA = 0x0040, // clear bus grant error
CTRL2_FRCPARITY = 0x0080, // ?
CTRL2_WMASK = 0x000f
};
DECLARE_READ16_MEMBER(ctrl2_r) override { return m_ctrl2; }
DECLARE_WRITE16_MEMBER(ctrl2_w) override;
required_device<cammu_c3_device> m_d_cammu;
required_device<cammu_c3_device> m_i_cammu;
@ -231,6 +275,14 @@ public:
void turquoise_base_map(address_map &map);
void turquoise_main_map(address_map &map);
void turquoise_io_map(address_map &map);
protected:
virtual void machine_start() override;
virtual void machine_reset() override;
private:
u16 m_ctrl1;
u16 m_ctrl2;
};
class sapphire_state : public interpro_state
@ -241,20 +293,46 @@ public:
, m_mmu(*this, INTERPRO_MMU_TAG)
, m_scsi(*this, INTERPRO_SCSI_DEVICE_TAG)
, m_arbga(*this, INTERPRO_ARBGA_TAG)
, m_flash_lo(*this, INTERPRO_FLASH_TAG "_lo")
, m_flash_hi(*this, INTERPRO_FLASH_TAG "_hi")
, m_flash_lsb(*this, INTERPRO_FLASH_TAG "_lsb")
, m_flash_msb(*this, INTERPRO_FLASH_TAG "_msb")
{
}
virtual DECLARE_WRITE16_MEMBER(sreg_ctrl2_w) override;
DECLARE_READ32_MEMBER(unmapped_r);
DECLARE_WRITE32_MEMBER(unmapped_w);
virtual DECLARE_READ32_MEMBER(unmapped_r) override;
virtual DECLARE_WRITE32_MEMBER(unmapped_w) override;
enum ctrl1_mask : u16
{
CTRL1_FLOPLOW = 0x0001, // 3.5" floppy select
// unused
CTRL1_LEDENA = 0x0004, // led display enable
CTRL1_LEDDP = 0x0008, // led right decimal point enable
CTRL1_MMBE = 0x0010, // mmbe enable
CTRL1_ETHDTR = 0x0020, // modem dtr pin enable
CTRL1_ETHRMOD = 0x0040, // 0 = sytem configured for remote modems
CTRL1_FIFOACTIVE = 0x0080 // 0 = plotter fifos reset
};
DECLARE_READ16_MEMBER(ctrl1_r) override { return m_ctrl1; }
DECLARE_WRITE16_MEMBER(ctrl1_w) override;
enum ctrl2_mask : u16
{
CTRL2_PWRUP = 0x0003, // power supply voltage adjust
CTRL2_HOLDOFF = 0x0004, // power supply shut down delay
CTRL2_EXTNMIENA = 0x0008, // power nmi enable
CTRL2_COLDSTART = 0x0010, // cold start flag
CTRL2_RESET = 0x0020, // soft reset
CTRL2_BUSENA = 0x0040, // clear bus grant error
CTRL2_FLASHEN = 0x0080, // flash eprom write enable
};
DECLARE_READ16_MEMBER(ctrl2_r) override { return m_ctrl2; }
DECLARE_WRITE16_MEMBER(ctrl2_w) override;
required_device<cammu_c4_device> m_mmu;
required_device<ncr53c94_device> m_scsi;
required_device<interpro_arbga_device> m_arbga;
required_device<intel_28f010_device> m_flash_lo;
required_device<intel_28f010_device> m_flash_hi;
required_device<intel_28f010_device> m_flash_lsb;
required_device<intel_28f010_device> m_flash_msb;
void sapphire(machine_config &config);
void ip2500(machine_config &config);
@ -269,6 +347,14 @@ public:
void sapphire_base_map(address_map &map);
void sapphire_main_map(address_map &map);
void sapphire_io_map(address_map &map);
protected:
virtual void machine_start() override;
virtual void machine_reset() override;
private:
u16 m_ctrl1;
u16 m_ctrl2;
};
#endif // MAME_INCLUDES_INTERPRO_H

View File

@ -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);
// 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 };
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 pl = (pte & PTE_PL) >> 3;
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;
}
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 },

View File

@ -120,7 +120,7 @@ public:
template <typename T, typename U> std::enable_if_t<std::is_convertible<U, std::function<T(T)>>::value, bool> modify(const u32 ssw, const u32 address, U &&apply)
{
translated_t t = translate_address(ssw, address, access_size(sizeof(T)), RMW);
translated_t t = translate_address(ssw, address, access_size(sizeof(T)), access_type(READ | WRITE));
if (t.space != nullptr)
{
@ -145,7 +145,32 @@ public:
switch (sizeof(T))
{
case 2: apply(T(t.space->read_word(t.address))); break;
case 4: apply(T(t.space->read_dword_unaligned(t.address))); break;
case 4:
{
// check for unaligned access
if (address & 0x2)
{
// check for page span
if ((address & CAMMU_PAGE_MASK) == (CAMMU_PAGE_SIZE - 2))
{
translated_t u = translate_address(ssw, address + 2, access_size(sizeof(u16)), EXECUTE);
if (u.space != nullptr)
{
const u16 lsw = t.space->read_word(t.address);
const u16 msw = u.space->read_word(u.address);
apply((T(msw) << 16) | lsw);
}
else
return false;
}
else
apply(T(t.space->read_dword_unaligned(t.address)));
}
else
apply(T(t.space->read_dword(t.address)));
}
break;
default: fatalerror("unhandled fetch size %d\n", access_size(sizeof(T)));
}
@ -177,8 +202,15 @@ protected:
{
READ = 1,
WRITE = 2,
RMW = 3,
EXECUTE = 4
EXECUTE = 4,
// matrix abbreviations and combinations
N = 0,
R = READ,
W = WRITE,
RW = READ | WRITE,
RE = READ | EXECUTE,
RWE = READ | WRITE | EXECUTE,
};
private:
@ -512,20 +544,7 @@ protected:
virtual void set_fault_address(const u32 va) override { m_fault = va; }
private:
enum c3_access_t : u8
{
N = 0, // no access
R = 1, // read permitted
W = 2, // write permitted
RW = 3, // read and write permitted
E = 4, // execute permitted
RE = 5, // read and execute permitted
RWE = 7 // read, write and execute permitted
};
static const u8 i_cammu_column[];
static const u8 d_cammu_column[];
static const c3_access_t cammu_matrix[][16];
static const u8 protection_matrix[4][16];
u32 m_s_pdo;
u32 m_u_pdo;

File diff suppressed because it is too large Load Diff

View File

@ -13,7 +13,7 @@
devcb = &downcast<interpro_ioga_device &>(*device).set_out_irq_callback(DEVCB_##_out_irq);
#define MCFG_INTERPRO_IOGA_IVEC_CB(_out_ivec) \
devcb = &downcast<interpro_ioga_device &>(*device).set_out_ivec_callback(DEVCB_##_out_ivec);
devcb = &downcast<interpro_ioga_device &>(*device).set_out_irq_vector_callback(DEVCB_##_out_ivec);
#define MCFG_INTERPRO_IOGA_DMA_CB(_channel, _dma_r, _dma_w) \
devcb = &downcast<interpro_ioga_device &>(*device).set_dma_r_callback(_channel, DEVCB_##_dma_r); \
@ -39,63 +39,33 @@ protected:
enum interrupt_type
{
INT_HARD_IN, // hardware internal
INT_HARD_EX, // hardware external
INT_SOFT_LO, // soft low type
INT_SOFT_HI // soft high type
INT_NONE = 0,
INT_HARD = 1,
INT_SOFT = 2,
};
enum interrupt_number
{
IRQ_TIMER2 = 0, // internal int 3 (5c)
IRQ_TIMER3 = 1, // internal int 4 (5e)
IRQ_SCSI = 2, // external int 0 (60)
IRQ_FLOPPY = 3, // external int 1 (62)
IRQ_PLOTTER = 4, // external int 2 (64)
IRQ_SRXCBUS0 = 5, // external int 3 (66)
IRQ_SRXCBUS1 = 6, // external int 4 (68)
IRQ_SRXCBUS2 = 7, // external int 5 (6a)
IRQ_VB = 8, // external int 6 (6c)
IRQ_9 = 9, // external int 7 (6e)
IRQ_CBUS3 = 10, // external int 8 (70)
IRQ_RTC = 11, // external int 9 (72)
IRQ_60HZ = 12, // external int 10 (74)
IRQ_MOUSE = 13, // internal int 0 (76)
IRQ_TIMER0 = 14, // internal int 1 (78)
IRQ_TIMER1 = 15, // internal int 2 (7a)
IRQ_SERDMA = 16, // internal int 5 (7c)
IRQ_SERIAL = 17, // external int 11 (7e)
IRQ_ETHERNET = 18, // external int 12 (80)
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)
// 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_TIMER2 = 17, // internal int 3 (offset 0x5c) // Sapphire only
IRQ_TIMER3 = 18, // internal int 4 (offset 0x5e) // Sapphire only
};
enum dma_channel
@ -108,7 +78,7 @@ protected:
public:
template <class Object> devcb_base &set_out_nmi_callback(Object &&cb) { return m_out_nmi_func.set_callback(std::forward<Object>(cb)); }
template <class Object> devcb_base &set_out_irq_callback(Object &&cb) { return m_out_irq_func.set_callback(std::forward<Object>(cb)); }
template <class Object> devcb_base &set_out_ivec_callback(Object &&cb) { return m_out_ivec_func.set_callback(std::forward<Object>(cb)); }
template <class Object> devcb_base &set_out_irq_vector_callback(Object &&cb) { return m_out_irq_vector_func.set_callback(std::forward<Object>(cb)); }
template <class Object> devcb_base &set_dma_r_callback(int channel, Object &&cb) { return m_dma_channel[channel].device_r.set_callback(std::forward<Object>(cb)); }
template <class Object> devcb_base &set_dma_w_callback(int channel, Object &&cb) { return m_dma_channel[channel].device_w.set_callback(std::forward<Object>(cb)); }
template <class Object> devcb_base &set_serial_dma_r_callback(int channel, Object &&cb) { return m_serial_dma_channel[channel].device_r.set_callback(std::forward<Object>(cb)); }
@ -125,21 +95,21 @@ public:
virtual void map(address_map &map) = 0;
// interrupt request lines
DECLARE_WRITE_LINE_MEMBER(ir0_w) { set_int_line(INT_HARD_EX, IRQ_SCSI, state); }
DECLARE_WRITE_LINE_MEMBER(ir1_w) { set_int_line(INT_HARD_EX, IRQ_FLOPPY, state); }
DECLARE_WRITE_LINE_MEMBER(ir2_w) { set_int_line(INT_HARD_EX, IRQ_PLOTTER, state); }
DECLARE_WRITE_LINE_MEMBER(ir3_w) { set_int_line(INT_HARD_EX, IRQ_SRXCBUS0, state); }
DECLARE_WRITE_LINE_MEMBER(ir4_w) { set_int_line(INT_HARD_EX, IRQ_SRXCBUS1, state); }
DECLARE_WRITE_LINE_MEMBER(ir5_w) { set_int_line(INT_HARD_EX, IRQ_SRXCBUS2, state); }
DECLARE_WRITE_LINE_MEMBER(ir6_w) { set_int_line(INT_HARD_EX, IRQ_VB, state); }
DECLARE_WRITE_LINE_MEMBER(ir7_w) { set_int_line(INT_HARD_EX, IRQ_9, state); }
DECLARE_WRITE_LINE_MEMBER(ir8_w) { set_int_line(INT_HARD_EX, IRQ_CBUS3, state); }
DECLARE_WRITE_LINE_MEMBER(ir9_w) { set_int_line(INT_HARD_EX, IRQ_RTC, state); }
DECLARE_WRITE_LINE_MEMBER(ir10_w) { set_int_line(INT_HARD_EX, IRQ_60HZ, state); }
DECLARE_WRITE_LINE_MEMBER(ir11_w) { set_int_line(INT_HARD_EX, IRQ_SERIAL, state); }
DECLARE_WRITE_LINE_MEMBER(ir12_w) { set_int_line(INT_HARD_EX, IRQ_ETHERNET, state); }
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); }
IRQ_CALLBACK_MEMBER(acknowledge_interrupt);
virtual IRQ_CALLBACK_MEMBER(acknowledge_interrupt);
// interrupt control
enum icr_mask
@ -150,15 +120,15 @@ public:
IRQ_FLAGS = 0xff00,
IRQ_PENDING = 0x0100,
IRQ_ENABLE_EXTERNAL = 0x0200,
IRQ_ENABLE = 0x0200,
IRQ_EDGE = 0x0400,
IRQ_NEGPOL = 0x0800,
IRQ_ENABLE_INTERNAL = 0x1000
IRQ_ENABLE_INT = 0x1000,
IRQ_ENABLE_SERDMA = 0x0e00,
};
DECLARE_READ16_MEMBER(icr_r) { return m_hwicr[offset]; }
DECLARE_WRITE16_MEMBER(icr_w);
DECLARE_READ16_MEMBER(icr18_r) { return icr_r(space, 18, mem_mask); }
DECLARE_WRITE16_MEMBER(icr18_w) { icr_w(space, 18, data, mem_mask); }
DECLARE_READ16_MEMBER(hardint_r) { return m_hwicr[offset]; }
DECLARE_WRITE16_MEMBER(hardint_w);
enum nmictrl_mask
{
@ -175,8 +145,6 @@ public:
DECLARE_READ8_MEMBER(softint_r) { return m_softint; }
DECLARE_WRITE8_MEMBER(softint_w);
DECLARE_READ16_MEMBER(softint_vector_r) { return m_swicr[offset]; }
DECLARE_WRITE16_MEMBER(softint_vector_w);
// dma request lines
DECLARE_WRITE_LINE_MEMBER(drq_plotter) { drq(state, DMA_PLOTTER); }
@ -190,6 +158,7 @@ public:
enum dma_ctrl_mask
{
DMA_CTRL_TCZERO = 0x00000001, // transfer count zero
DMA_CTRL_TAG = 0x00000e00, // bus tag
DMA_CTRL_BERR = 0x00400000, // bus error
DMA_CTRL_ERR = 0x00800000, // checked for in scsi isr
@ -266,7 +235,7 @@ public:
DECLARE_READ32_MEMBER(bus_timeout_r) { return m_bus_timeout; }
DECLARE_WRITE32_MEMBER(bus_timeout_w) { m_bus_timeout = data; }
DECLARE_WRITE32_MEMBER(bus_error) { m_error_address = data; m_error_businfo = offset; }
DECLARE_WRITE32_MEMBER(bus_error);
// timers
DECLARE_READ32_MEMBER(timer0_r);
@ -281,20 +250,6 @@ public:
DECLARE_READ32_MEMBER(timer1_r);
DECLARE_WRITE32_MEMBER(timer1_w);
DECLARE_READ32_MEMBER(timer2_count_r);
DECLARE_WRITE32_MEMBER(timer2_count_w);
DECLARE_READ32_MEMBER(timer2_value_r);
DECLARE_WRITE32_MEMBER(timer2_value_w);
enum timer3_mask
{
TIMER3_COUNT = 0x3fffffff,
TIMER3_START = 0x40000000,
TIMER3_EXPIRED = 0x80000000
};
DECLARE_READ32_MEMBER(timer3_r);
DECLARE_WRITE32_MEMBER(timer3_w);
DECLARE_READ32_MEMBER(prescaler_r);
DECLARE_WRITE32_MEMBER(prescaler_w);
@ -324,32 +279,42 @@ protected:
// callbacks
devcb_write_line m_out_nmi_func;
devcb_write_line m_out_irq_func;
devcb_write8 m_out_ivec_func;
devcb_write8 m_out_irq_vector_func;
devcb_write_line m_fdc_tc_func;
devcb_write_line m_eth_ca_func;
void set_nmi_line(int state);
void set_int_line(interrupt_type type, int number, int state);
void set_int_line(int number, int state);
TIMER_CALLBACK_MEMBER(interrupt_check);
TIMER_CALLBACK_MEMBER(set_ivec);
virtual TIMER_CALLBACK_MEMBER(interrupt_check);
TIMER_CALLBACK_MEMBER(dma);
TIMER_CALLBACK_MEMBER(serial_dma);
TIMER_CALLBACK_MEMBER(timer0);
TIMER_CALLBACK_MEMBER(timer1);
TIMER_CALLBACK_MEMBER(timer2) {}
TIMER_CALLBACK_MEMBER(timer3);
TIMER_CALLBACK_MEMBER(timer_60hz);
TIMER_CALLBACK_MEMBER(mouse_timer);
virtual TIMER_CALLBACK_MEMBER(eth_reset) = 0;
emu_timer *m_interrupt_timer;
emu_timer *m_eth_reset_timer;
std::unique_ptr<u16 []> m_hwicr;
u32 m_force_state;
u8 m_softint;
interrupt_type m_active_interrupt_type;
u8 m_active_interrupt_number;
void nmi(int state);
void irq(int state, u8 ivec);
u8 get_irq_vector() const { return m_irq_vector; }
virtual u8 get_int_count() const { return 17; }
virtual u8 get_reg_offset(u8 const number) const { return number; }
virtual u8 get_int_number(u8 const offset) const { return offset; }
private:
bool nmi(int state);
bool irq(int state, u8 ivec);
u16 get_icr(interrupt_type type, int number) const;
void set_pending(interrupt_type type, int number, bool pending);
TIMER_CALLBACK_MEMBER(set_irq_vector) { m_out_irq_vector_func(m_irq_vector); }
void drq(int state, int channel);
void serial_drq(int state, int channel);
@ -370,20 +335,13 @@ private:
void serial_dma_ctrl_w(address_space &space, offs_t offset, u32 data, u32 mem_mask, int channel);
// interrupt state
static const interrupt_data_t m_interrupt_data[];
interrupt_data_t const *m_active_interrupt;
int m_nmi_state;
int m_irq_state;
u8 m_ivec;
u32 m_hwint_forced;
u8 m_irq_vector;
u32 m_line_state;
// interrupt control
static const int INTERRUPT_COUNT = 19;
u16 m_hwicr[INTERRUPT_COUNT];
u8 m_softint;
u8 m_nmictrl;
u16 m_swicr[8];
// dma state
static const int DMA_CHANNEL_COUNT = 3;
@ -423,18 +381,12 @@ private:
// timers
u8 m_timer0_count;
u16 m_timer1_count;
u32 m_timer2_count;
u32 m_timer2_value;
u32 m_timer3_count;
u32 m_prescaler;
emu_timer *m_interrupt_timer;
emu_timer *m_dma_timer;
emu_timer *m_serial_dma_timer;
emu_timer *m_timer0;
emu_timer *m_timer1;
emu_timer *m_timer2;
emu_timer *m_timer3;
emu_timer *m_timer_60hz;
// bus arbitration and control
@ -445,7 +397,48 @@ private:
// mouse
u32 m_mouse_status;
emu_timer *m_mouse_timer;
};
class emerald_ioga_device : public interpro_ioga_device
{
public:
emerald_ioga_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
virtual void map(address_map &map) override;
DECLARE_WRITE16_MEMBER(eth_w);
DECLARE_READ16_MEMBER(eth_r);
protected:
virtual TIMER_CALLBACK_MEMBER(eth_reset) override;
enum eth_base_mask
{
ETH_BASE_MASK = 0xffe00000
};
DECLARE_READ32_MEMBER(eth_base_r) { return m_eth_base; }
DECLARE_WRITE32_MEMBER(eth_base_w);
enum eth_control_mask
{
ETH_CA = 0x0001, // channel attention
ETH_FLUSH = 0x0002,
ETH_BUF = 0x0004,
ETH_QUAD = 0x0008,
ETH_BERR = 0x0010, // bus error
ETH_PERR = 0x0020, // parity error
ETH_RESET = 0x0040,
ETH_WTAG = 0x0600,
ETH_RTAG = 0x3000,
//ETH_MASK = 0x4ff2 // channel attention and error bits not persistent
};
DECLARE_READ16_MEMBER(eth_control_r) { return m_eth_control; }
DECLARE_WRITE16_MEMBER(eth_control_w);
private:
u32 m_eth_base;
u16 m_eth_control;
};
class turquoise_ioga_device : public interpro_ioga_device
@ -500,7 +493,32 @@ public:
DECLARE_WRITE16_MEMBER(eth_w);
DECLARE_READ16_MEMBER(eth_r);
DECLARE_READ32_MEMBER(timer2_count_r);
DECLARE_WRITE32_MEMBER(timer2_count_w);
DECLARE_READ32_MEMBER(timer2_value_r);
DECLARE_WRITE32_MEMBER(timer2_value_w);
enum timer3_mask
{
TIMER3_COUNT = 0x3fffffff,
TIMER3_START = 0x40000000,
TIMER3_EXPIRED = 0x80000000
};
DECLARE_READ32_MEMBER(timer3_r);
DECLARE_WRITE32_MEMBER(timer3_w);
DECLARE_READ16_MEMBER(softint_vector_r) { return m_swicr[offset]; }
DECLARE_WRITE16_MEMBER(softint_vector_w);
virtual IRQ_CALLBACK_MEMBER(acknowledge_interrupt) override;
protected:
// device-level overrides
virtual void device_start() override;
virtual void device_reset() override;
virtual TIMER_CALLBACK_MEMBER(interrupt_check) override;
virtual TIMER_CALLBACK_MEMBER(eth_reset) override;
enum eth_remap_mask
@ -544,13 +562,32 @@ protected:
DECLARE_READ32_MEMBER(eth_control_r);
DECLARE_WRITE32_MEMBER(eth_control_w);
TIMER_CALLBACK_MEMBER(timer2) {}
TIMER_CALLBACK_MEMBER(timer3);
virtual u8 get_int_count() const override { return INTERRUPT_COUNT; }
virtual u8 get_reg_offset(u8 const number) const override { return (number + 2) % INTERRUPT_COUNT; }
virtual u8 get_int_number(u8 const offset) const override { return (offset + INTERRUPT_COUNT - 2) % INTERRUPT_COUNT; }
private:
static const u8 INTERRUPT_COUNT = 19;
u32 m_eth_remap;
u32 m_eth_mappg;
u32 m_eth_control;
u32 m_timer2_count;
u32 m_timer2_value;
u32 m_timer3_count;
emu_timer *m_timer2;
emu_timer *m_timer3;
u16 m_swicr[8];
};
// device type definition
DECLARE_DEVICE_TYPE(EMERALD_IOGA, emerald_ioga_device)
DECLARE_DEVICE_TYPE(TURQUOISE_IOGA, turquoise_ioga_device)
DECLARE_DEVICE_TYPE(SAPPHIRE_IOGA, sapphire_ioga_device)