diff --git a/hash/interpro.xml b/hash/interpro.xml
new file mode 100644
index 00000000000..08a12d721a1
--- /dev/null
+++ b/hash/interpro.xml
@@ -0,0 +1,248 @@
+
+
+
+
+
+
+
+ Intergraph System Software
+ 1999
+ Intergraph
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Rebuild Floppies
+ 1998
+ Intergraph
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Diagnostic Floppies
+ 1994
+ Intergraph
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/devices/cpu/clipper/clipper.cpp b/src/devices/cpu/clipper/clipper.cpp
index d9812b4a987..33418a764df 100644
--- a/src/devices/cpu/clipper/clipper.cpp
+++ b/src/devices/cpu/clipper/clipper.cpp
@@ -8,7 +8,7 @@
*
* TODO:
* - save/restore state
- * - unimplemented C400 instructions
+ * - unimplemented C400 instructions (cdb, cnvx[ds]w, loadts, waitd)
* - correct boot logic
* - condition codes for multiply instructions
* - instruction timing
@@ -57,25 +57,29 @@ DEFINE_DEVICE_TYPE(CLIPPER_C400, clipper_c400_device, "clipper_c400", "C400 CLIP
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)
+ , 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)
+ , 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)
+ , m_cammu(*this, "^cammu")
{
}
clipper_device::clipper_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock, const endianness_t endianness, const u32 cpuid)
: cpu_device(mconfig, type, tag, owner, clock)
- , m_insn_config("insn", endianness, 32, 32, 0)
- , m_data_config("data", endianness, 32, 32, 0)
- , m_insn(nullptr)
- , m_data(nullptr)
+ , m_main_config("main", endianness, 32, 32, 0)
+ , m_io_config("io", endianness, 32, 32, 0)
+ , m_boot_config("boot", endianness, 32, 32, 0)
, m_icount(0)
, m_psw(endianness == ENDIANNESS_BIG ? PSW_BIG : 0)
, m_ssw(cpuid)
@@ -110,9 +114,12 @@ inline u64 rotr64(u64 x, u8 shift)
void clipper_device::device_start()
{
- // get our address spaces
- m_insn = &space(AS_PROGRAM);
- m_data = &space(AS_DATA);
+ // map spaces to system tags
+ std::vector spaces = { &space(0), &space(0), &space(0), &space(0), &space(1), &space(2), nullptr, nullptr };
+
+ // configure the cammu address spaces
+ get_icammu().set_spaces(spaces);
+ get_dcammu().set_spaces(spaces);
// set our instruction counter
m_icountptr = &m_icount;
@@ -156,6 +163,8 @@ void clipper_device::device_reset()
* ssw: EI, TP, M, U, K, KU, UU, P cleared, ID set from hardware, others undefined
*/
+ m_wait = false;
+
// clear the psw and ssw
set_psw(0);
set_ssw(0);
@@ -205,11 +214,15 @@ void clipper_device::execute_run()
// acknowledge interrupt
standard_irq_callback(INPUT_LINE_IRQ0);
- LOGMASKED(LOG_EXCEPTION, "transferring control to ivec 0x%02x\n", m_ivec);
m_ip = intrap(EXCEPTION_INTERRUPT_BASE + m_ivec * 8, m_ip);
+
+ LOGMASKED(LOG_EXCEPTION, "transferring control to ivec 0x%02x address 0x%08x\n", m_ivec, m_ip);
}
}
+ if (m_wait)
+ m_icount = 0;
+
while (m_icount > 0)
{
debugger_instruction_hook(this, m_ip);
@@ -282,6 +295,9 @@ void clipper_device::execute_run()
void clipper_device::execute_set_input(int inputnum, int state)
{
+ if (state)
+ m_wait = false;
+
switch (inputnum)
{
case INPUT_LINE_IRQ0:
@@ -294,15 +310,12 @@ void clipper_device::execute_set_input(int inputnum, int state)
}
}
-/*
- * The CLIPPER has a true Harvard architecture. In the InterPro, these are tied back together
- * again by the MMU, which then directs the access to one of 3 address spaces: main, i/o or boot.
- */
device_memory_interface::space_config_vector clipper_device::memory_space_config() const
{
return space_config_vector {
- std::make_pair(AS_PROGRAM, &m_insn_config),
- std::make_pair(AS_DATA, &m_data_config)
+ std::make_pair(0, &m_main_config),
+ std::make_pair(1, &m_io_config),
+ std::make_pair(2, &m_boot_config)
};
}
@@ -324,17 +337,15 @@ WRITE16_MEMBER(clipper_device::set_exception)
*/
bool clipper_device::decode_instruction()
{
- // fetch instruction word
- u16 insn = m_insn->read_word(m_ip + 0);
- if (m_exception)
+ // fetch and decode the primary parcel
+ if (!get_icammu().fetch(m_ssw, m_ip + 0, [this](u16 insn) {
+ m_info.opcode = insn >> 8;
+ m_info.subopcode = insn & 0xff;
+ m_info.r1 = (insn & 0x00f0) >> 4;
+ m_info.r2 = insn & 0x000f;
+ }))
return false;
- // decode the primary parcel
- m_info.opcode = insn >> 8;
- m_info.subopcode = insn & 0xff;
- m_info.r1 = (insn & 0x00f0) >> 4;
- m_info.r2 = insn & 0x000f;
-
// initialise the other fields
m_info.imm = 0;
m_info.macro = 0;
@@ -343,112 +354,93 @@ bool clipper_device::decode_instruction()
// default instruction size is 2 bytes
int size = 2;
- if ((insn & 0xf800) == 0x3800)
+ if ((m_info.opcode & 0xf8) == 0x38)
{
- // instruction has a 16 bit immediate operand
-
// fetch 16 bit immediate and sign extend
- m_info.imm = (s16)m_insn->read_word(m_ip + 2);
- if (m_exception)
+ if (!get_icammu().fetch(m_ssw, m_ip + 2, [this](s32 v) { m_info.imm = v; }))
return false;
size = 4;
}
- else if ((insn & 0xd300) == 0x8300)
+ else if ((m_info.opcode & 0xd3) == 0x83)
{
// instruction has an immediate operand, either 16 or 32 bit
- if (insn & 0x0080)
+ if (m_info.subopcode & 0x80)
{
// fetch 16 bit immediate and sign extend
- m_info.imm = (s16)m_insn->read_word(m_ip + 2);
- if (m_exception)
+ if (!get_icammu().fetch(m_ssw, m_ip + 2, [this](s32 v) { m_info.imm = v; }))
return false;
size = 4;
}
else
{
// fetch 32 bit immediate
- m_info.imm = m_insn->read_dword_unaligned(m_ip + 2);
- if (m_exception)
+ if (!get_icammu().fetch(m_ssw, m_ip + 2, [this](u32 v) { m_info.imm = v; }))
return false;
size = 6;
}
}
- else if ((insn & 0xc000) == 0x4000)
+ else if ((m_info.opcode & 0xc0) == 0x40)
{
// instructions with addresses
- if (insn & 0x0100)
+ if (m_info.opcode & 0x01)
{
// instructions with complex modes
- u16 temp;
-
- switch (insn & 0x00f0)
+ switch (m_info.subopcode & 0xf0)
{
case ADDR_MODE_PC32:
- m_info.address = m_ip + m_insn->read_dword_unaligned(m_ip + 2);
- if (m_exception)
+ if (!get_icammu().fetch(m_ssw, m_ip + 2, [this](u32 v) { m_info.address = m_ip + v; }))
return false;
size = 6;
break;
case ADDR_MODE_ABS32:
- m_info.address = m_insn->read_dword_unaligned(m_ip + 2);
- if (m_exception)
+ if (!get_icammu().fetch(m_ssw, m_ip + 2, [this](u32 v) { m_info.address = v; }))
return false;
size = 6;
break;
case ADDR_MODE_REL32:
- m_info.r2 = m_insn->read_word(m_ip + 2) & 0xf;
- if (m_exception)
+ if (!get_icammu().fetch(m_ssw, m_ip + 2, [this](u16 v) { m_info.r2 = v & 0xf; }))
return false;
- m_info.address = m_r[insn & 0xf] + m_insn->read_dword_unaligned(m_ip + 4);
- if (m_exception)
+ if (!get_icammu().fetch(m_ssw, m_ip + 4, [this](u32 v) { m_info.address = m_r[m_info.subopcode & 0xf] + v; }))
return false;
size = 8;
break;
case ADDR_MODE_PC16:
- m_info.address = m_ip + (s16)m_insn->read_word(m_ip + 2);
- if (m_exception)
+ if (!get_icammu().fetch(m_ssw, m_ip + 2, [this](s16 v) { m_info.address = m_ip + v; }))
return false;
size = 4;
break;
case ADDR_MODE_REL12:
- temp = m_insn->read_word(m_ip + 2);
- if (m_exception)
+ if (!get_icammu().fetch(m_ssw, m_ip + 2, [this](s16 v) {
+ m_info.r2 = v & 0xf;
+ m_info.address = m_r[m_info.subopcode & 0xf] + (v >> 4); }))
return false;
-
- m_info.r2 = temp & 0xf;
- m_info.address = m_r[insn & 0xf] + ((s16)temp >> 4);
size = 4;
break;
case ADDR_MODE_ABS16:
- m_info.address = (s16)m_insn->read_word(m_ip + 2);
- if (m_exception)
+ if (!get_icammu().fetch(m_ssw, m_ip + 2, [this](s32 v) { m_info.address = v; }))
return false;
size = 4;
break;
case ADDR_MODE_PCX:
- temp = m_insn->read_word(m_ip + 2);
- if (m_exception)
+ if (!get_icammu().fetch(m_ssw, m_ip + 2, [this](u16 v) {
+ m_info.r2 = v & 0xf;
+ m_info.address = m_ip + m_r[(v >> 4) & 0xf]; }))
return false;
-
- m_info.r2 = temp & 0xf;
- m_info.address = m_ip + m_r[(temp >> 4) & 0xf];
size = 4;
break;
case ADDR_MODE_RELX:
- temp = m_insn->read_word(m_ip + 2);
- if (m_exception)
+ if (!get_icammu().fetch(m_ssw, m_ip + 2, [this](u16 v) {
+ m_info.r2 = v & 0xf;
+ m_info.address = m_r[m_info.subopcode & 0xf] + m_r[(v >> 4) & 0xf]; }))
return false;
-
- m_info.r2 = temp & 0xf;
- m_info.address = m_r[insn & 0xf] + m_r[(temp >> 4) & 0xf];
size = 4;
break;
@@ -461,11 +453,10 @@ bool clipper_device::decode_instruction()
// relative addressing mode
m_info.address = m_r[m_info.r1];
}
- else if ((insn & 0xfd00) == 0xb400)
+ else if ((m_info.opcode & 0xfd) == 0xb4)
{
// macro instructions
- m_info.macro = m_insn->read_word(m_ip + 2);
- if (m_exception)
+ if (!get_icammu().fetch(m_ssw, m_ip + 2, [this](u16 v) { m_info.macro = v; }))
return false;
size = 4;
}
@@ -479,9 +470,6 @@ bool clipper_device::decode_instruction()
void clipper_device::execute_instruction()
{
- // memory fetch temporary
- u64 temp;
-
switch (m_info.opcode)
{
case 0x00: // noop
@@ -511,27 +499,25 @@ void clipper_device::execute_instruction()
break;
case 0x13:
// ret: return from subroutine
- temp = m_data->read_dword(m_r[R2]);
- if (!m_exception)
- {
- m_ip = temp;
+ get_dcammu().load(m_ssw, m_r[R2], [this](u32 v) {
+ m_ip = v;
m_r[R2] += 4;
- }
+ });
// TRAPS: C,U,A,P,R
break;
case 0x14:
// pushw: push word
- m_data->write_dword(m_r[R1] - 4, m_r[R2]);
- m_r[R1] -= 4;
+ if (get_dcammu().store(m_ssw, m_r[R1] - 4, m_r[R2]))
+ m_r[R1] -= 4;
// TRAPS: A,P,W
break;
case 0x16:
// popw: pop word
- m_r[R1] += 4;
- temp = m_data->read_dword(m_r[R1] - 4);
- if (!m_exception)
- m_r[R2] = temp;
+ get_dcammu().load(m_ssw, m_r[R1], [this](u32 v) {
+ m_r[R1] += 4;
+ m_r[R2] = v;
+ });
// TRAPS: C,U,A,P,R
break;
@@ -774,8 +760,7 @@ void clipper_device::execute_instruction()
case 0x44:
case 0x45:
// call: call subroutine
- m_data->write_dword(m_r[R2] - 4, m_ip);
- if (!m_exception)
+ if (get_dcammu().store(m_ssw, m_r[R2] - 4, m_ip))
{
m_ip = m_info.address;
m_r[R2] -= 4;
@@ -818,9 +803,7 @@ void clipper_device::execute_instruction()
case 0x60:
case 0x61:
// loadw: load word
- temp = m_data->read_dword(m_info.address);
- if (!m_exception)
- m_r[R2] = temp;
+ get_dcammu().load(m_ssw, m_info.address, [this](u32 v) { m_r[R2] = v; });
// TRAPS: C,U,A,P,R,I
break;
case 0x62:
@@ -832,92 +815,77 @@ void clipper_device::execute_instruction()
case 0x64:
case 0x65:
// loads: load single floating
- temp = m_data->read_dword(m_info.address);
- if (!m_exception)
- set_fp(R2, (float32)temp, F_NONE);
+ get_dcammu().load(m_ssw, m_info.address, [this](float32 v) { set_fp(R2, v, F_NONE); });
// TRAPS: C,U,A,P,R,I
break;
case 0x66:
case 0x67:
// loadd: load double floating
- temp = m_data->read_qword(m_info.address);
- if (!m_exception)
- set_fp(R2, (float64)temp, F_NONE);
+ get_dcammu().load(m_ssw, m_info.address, [this](float64 v) { set_fp(R2, float64(v), F_NONE); });
// TRAPS: C,U,A,P,R,I
break;
case 0x68:
case 0x69:
// loadb: load byte
- temp = s64(s8(m_data->read_byte(m_info.address)));
- if (!m_exception)
- m_r[R2] = temp;
+ get_dcammu().load(m_ssw, m_info.address, [this](s32 v) { m_r[R2] = v; });
// TRAPS: C,U,A,P,R,I
break;
case 0x6a:
case 0x6b:
// loadbu: load byte unsigned
- temp = m_data->read_byte(m_info.address);
- if (!m_exception)
- m_r[R2] = temp;
+ get_dcammu().load(m_ssw, m_info.address, [this](u32 v) { m_r[R2] = v; });
// TRAPS: C,U,A,P,R,I
break;
case 0x6c:
case 0x6d:
// loadh: load halfword
- temp = s64(s16(m_data->read_word(m_info.address)));
- if (!m_exception)
- m_r[R2] = temp;
+ get_dcammu().load(m_ssw, m_info.address, [this](s32 v) { m_r[R2] = v; });
// TRAPS: C,U,A,P,R,I
break;
case 0x6e:
case 0x6f:
// loadhu: load halfword unsigned
- temp = m_data->read_word(m_info.address);
- if (!m_exception)
- m_r[R2] = temp;
+ get_dcammu().load(m_ssw, m_info.address, [this](u32 v) { m_r[R2] = v; });
// TRAPS: C,U,A,P,R,I
break;
case 0x70:
case 0x71:
// storw: store word
- m_data->write_dword(m_info.address, m_r[R2]);
+ get_dcammu().store(m_ssw, m_info.address, m_r[R2]);
// TRAPS: A,P,W,I
break;
case 0x72:
case 0x73:
// tsts: test and set
- temp = m_data->read_dword(m_info.address);
- if (!m_exception)
- {
- m_data->write_dword(m_info.address, temp | 0x80000000U);
- if (!m_exception)
- m_r[R2] = temp;
- }
+ get_dcammu().modify(m_ssw, m_info.address, [this](u32 v) {
+ m_r[R2] = v;
+ return v | 0x80000000U;
+ });
// TRAPS: C,U,A,P,R,W,I
break;
case 0x74:
case 0x75:
// stors: store single floating
- m_data->write_dword(m_info.address, get_fp32(R2));
+ get_dcammu().store(m_ssw, m_info.address, get_fp32(R2));
// TRAPS: A,P,W,I
break;
case 0x76:
case 0x77:
// stord: store double floating
- m_data->write_qword(m_info.address, get_fp64(R2));
+ get_dcammu().store(m_ssw, m_info.address, get_fp64(R2));
// TRAPS: A,P,W,I
break;
case 0x78:
case 0x79:
// storb: store byte
- m_data->write_byte(m_info.address, m_r[R2]);
+ get_dcammu().store(m_ssw, m_info.address, m_r[R2]);
// TRAPS: A,P,W,I
break;
case 0x7c:
case 0x7d:
// storh: store halfword
- m_data->write_word(m_info.address, m_r[R2]);
+ get_dcammu().store(m_ssw, m_info.address, m_r[R2]);
// TRAPS: A,P,W,I
break;
@@ -1163,7 +1131,7 @@ void clipper_device::execute_instruction()
// store ri at sp - 4 * (15 - i)
for (int i = R2; i < 15 && !m_exception; i++)
- m_data->write_dword(m_r[15] - 4 * (15 - i), m_r[i]);
+ get_dcammu().store(m_ssw, m_r[15] - 4 * (15 - i), m_r[i]);
// decrement sp after push to allow restart on exceptions
if (!m_exception)
@@ -1179,11 +1147,8 @@ void clipper_device::execute_instruction()
while (m_r[0])
{
- const u8 byte = m_data->read_byte(m_r[1]);
- if (m_exception)
- break;
+ get_dcammu().load(m_ssw, m_r[1], [this](u8 byte) { get_dcammu().store(m_ssw, m_r[2], byte); });
- m_data->write_byte(m_r[2], byte);
if (m_exception)
break;
@@ -1197,8 +1162,7 @@ void clipper_device::execute_instruction()
// initc: initialise r0 bytes at r1 with value in r2
while (m_r[0])
{
- m_data->write_byte(m_r[1], m_r[2]);
- if (m_exception)
+ if (!get_dcammu().store(m_ssw, m_r[1], m_r[2]))
break;
m_r[0]--;
@@ -1215,18 +1179,15 @@ void clipper_device::execute_instruction()
while (m_r[0])
{
- // set condition codes and abort the loop if the current byte does not match
- s32 byte1 = s8(m_data->read_byte(m_r[1]));
- if (m_exception)
+ // read and compare bytes (as signed 32 bit integers)
+ get_dcammu().load(m_ssw, m_r[1], [this](s32 byte1) {
+ get_dcammu().load(m_ssw, m_r[2], [this, byte1](s32 byte2) {
+ if (byte1 != byte2)
+ FLAGS(C_SUB(byte2, byte1), V_SUB(byte2, byte1), byte2 == byte1, byte2 < byte1); }); });
+
+ // abort on exception or mismatch
+ if (m_exception || !PSW(Z))
break;
- s32 byte2 = s8(m_data->read_byte(m_r[2]));
- if (m_exception)
- break;
- if (byte1 != byte2)
- {
- FLAGS(C_SUB(byte2, byte1), V_SUB(byte2, byte1), byte2 == byte1, byte2 < byte1)
- break;
- }
m_r[0]--;
m_r[1]++;
@@ -1241,13 +1202,8 @@ void clipper_device::execute_instruction()
// restwN..restw12: pop registers rN:r14
// load ri from sp + 4 * (i - N)
- for (int i = R2; i < 15; i++)
- {
- temp = m_data->read_dword(m_r[15] + 4 * (i - R2));
- if (m_exception)
- break;
- m_r[i] = temp;
- }
+ for (int i = R2; i < 15 && !m_exception; i++)
+ get_dcammu().load(m_ssw, m_r[15] + 4 * (i - R2), [this, i](u32 v) { m_r[i] = v; });
// increment sp after pop to allow restart on exceptions
if (!m_exception)
@@ -1261,7 +1217,7 @@ void clipper_device::execute_instruction()
// store fi at sp - 8 * (8 - i)
for (int i = R2; i < 8 && !m_exception; i++)
- m_data->write_qword(m_r[15] - 8 * (8 - i), get_fp64(i));
+ get_dcammu().store(m_ssw, m_r[15] - 8 * (8 - i), get_fp64(i));
// decrement sp after push to allow restart on exceptions
if (!m_exception)
@@ -1273,13 +1229,8 @@ void clipper_device::execute_instruction()
// restd0..restd7: pop registers fN:f7
// load fi from sp + 8 * (i - N)
- for (int i = R2; i < 8; i++)
- {
- temp = m_data->read_qword(m_r[15] + 8 * (i - R2));
- if (m_exception)
- break;
- set_fp(i, (float64)temp, F_NONE);
- }
+ for (int i = R2; i < 8 && !m_exception; i++)
+ get_dcammu().load(m_ssw, m_r[15] + 8 * (i - R2), [this, i](float64 v) { set_fp(i, v, F_NONE); });
// increment sp after pop to allow restart on exceptions
if (!m_exception)
@@ -1438,7 +1389,7 @@ void clipper_device::execute_instruction()
case 0x02:
// saveur: save user registers
for (int i = 0; i < 16 && !m_exception; i++)
- m_data->write_dword(m_rs[(m_info.macro >> 4) & 0xf] - 4 * (i + 1), m_ru[15 - i]);
+ get_dcammu().store(m_ssw, m_rs[(m_info.macro >> 4) & 0xf] - 4 * (i + 1), m_ru[15 - i]);
if (!m_exception)
m_rs[(m_info.macro >> 4) & 0xf] -= 64;
@@ -1446,13 +1397,8 @@ void clipper_device::execute_instruction()
break;
case 0x03:
// restur: restore user registers
- for (int i = 0; i < 16; i++)
- {
- temp = m_data->read_dword(m_rs[(m_info.macro >> 4) & 0xf] + 4 * i);
- if (m_exception)
- break;
- m_ru[i] = temp;
- }
+ for (int i = 0; i < 16 && !m_exception; i++)
+ get_dcammu().load(m_ssw, m_rs[(m_info.macro >> 4) & 0xf] + 4 * i, [this, i](u32 v) { m_ru[i] = v; });
if (!m_exception)
m_rs[(m_info.macro >> 4) & 0xf] += 64;
@@ -1465,7 +1411,7 @@ void clipper_device::execute_instruction()
break;
case 0x05:
// wait: wait for interrupt
- m_ip = m_pc;
+ m_wait = true;
// TRAPS: S
break;
@@ -1486,17 +1432,16 @@ void clipper_device::execute_instruction()
u32 clipper_device::reti()
{
+ u32 new_psw = 0, new_ssw = 0, new_pc = 0;
+
// fetch the psw, ssw and pc from the supervisor stack
- const u32 new_psw = m_data->read_dword(m_rs[(m_info.macro >> 4) & 0xf] + 0);
- if (m_exception)
+ if (!get_dcammu().load(m_ssw, m_rs[(m_info.macro >> 4) & 0xf] + 0, [&new_psw](u32 v) { new_psw = v; }))
fatalerror("reti unrecoverable fault 0x%04x read psw address 0x%08x pc 0x%08x\n", m_exception, m_rs[(m_info.macro >> 4) & 0xf] + 0, m_pc);
- const u32 new_ssw = m_data->read_dword(m_rs[(m_info.macro >> 4) & 0xf] + 4);
- if (m_exception)
+ if (!get_dcammu().load(m_ssw, m_rs[(m_info.macro >> 4) & 0xf] + 4, [&new_ssw](u32 v) { new_ssw = v; }))
fatalerror("reti unrecoverable fault 0x%04x read ssw address 0x%08x pc 0x%08x\n", m_exception, m_rs[(m_info.macro >> 4) & 0xf] + 4, m_pc);
- const u32 new_pc = m_data->read_dword(m_rs[(m_info.macro >> 4) & 0xf] + 8);
- if (m_exception)
+ if (!get_dcammu().load(m_ssw, m_rs[(m_info.macro >> 4) & 0xf] + 8, [&new_pc](u32 v) { new_pc = v; }))
fatalerror("reti unrecoverable fault 0x%04x read pc address 0x%08x pc 0x%08x\n", m_exception, m_rs[(m_info.macro >> 4) & 0xf] + 8, m_pc);
LOGMASKED(LOG_EXCEPTION, "reti r%d ssp 0x%08x pc 0x%08x ssw 0x%08x psw 0x%08x new_pc 0x%08x new_ssw 0x%08x new_psw 0x%08x\n",
@@ -1522,6 +1467,7 @@ u32 clipper_device::intrap(const u16 vector, const u32 old_pc)
{
const u32 old_ssw = m_ssw;
const u32 old_psw = m_psw;
+ u32 new_pc = 0, new_ssw = 0;
// clear ssw bits to enable supervisor memory access
m_ssw &= ~(SSW_U | SSW_K | SSW_UU | SSW_KU);
@@ -1530,13 +1476,10 @@ u32 clipper_device::intrap(const u16 vector, const u32 old_pc)
m_exception = 0;
// fetch next pc and ssw from interrupt vector
- const u32 new_pc = m_data->read_dword(vector + get_evpc_offset());
- if (m_exception)
- fatalerror("intrap unrecoverable fault 0x%04x read pc address 0x%08x pc 0x%08x\n", m_exception, vector + get_evpc_offset(), old_pc);
-
- const u32 new_ssw = m_data->read_dword(vector + get_evssw_offset());
- if (m_exception)
- fatalerror("intrap unrecoverable fault 0x%04x read ssw address 0x%08x pc 0x%08x\n", m_exception, vector + get_evssw_offset(), old_pc);
+ if (!get_dcammu().load(m_ssw, vector + 0, [&new_pc](u32 v) { new_pc = v; }))
+ fatalerror("intrap unrecoverable fault 0x%04x load pc address 0x%08x pc 0x%08x\n", m_exception, vector + 0, old_pc);
+ if (!get_dcammu().load(m_ssw, vector + 4, [&new_ssw](u32 v) { new_ssw = v; }))
+ fatalerror("intrap unrecoverable fault 0x%04x load ssw address 0x%08x pc 0x%08x\n", m_exception, vector + 4, old_pc);
LOGMASKED(LOG_EXCEPTION, "intrap vector 0x%04x pc 0x%08x ssp 0x%08x new_pc 0x%08x new_ssw 0x%08x\n", vector, old_pc, m_rs[15], new_pc, new_ssw);
@@ -1581,18 +1524,107 @@ u32 clipper_device::intrap(const u16 vector, const u32 old_pc)
}
// push pc, ssw and psw onto supervisor stack
- m_data->write_dword(m_rs[15] - 0x4, old_pc);
- if (m_exception)
- fatalerror("intrap unrecoverable fault 0x%04x write pc address 0x%08x pc 0x%08x\n", m_exception, m_rs[15] - 0x4, old_pc);
- m_data->write_dword(m_rs[15] - 0x8, old_ssw);
- if (m_exception)
- fatalerror("intrap unrecoverable fault 0x%04x write ssw address 0x%08x pc 0x%08x\n", m_exception, m_rs[15] - 0x8, old_pc);
- m_data->write_dword(m_rs[15] - 0xc, (old_psw & ~(PSW_CTS | PSW_MTS)) | source);
- if (m_exception)
- fatalerror("intrap unrecoverable fault 0x%04x write psw address 0x%08x pc 0x%08x\n", m_exception, m_rs[15] - 0xc, old_pc);
+ if (!get_dcammu().store(m_ssw, m_rs[15] - 0x4, old_pc))
+ fatalerror("intrap unrecoverable fault 0x%04x push pc ssp 0x%08x pc 0x%08x\n", m_exception, m_rs[15] - 0x4, old_pc);
+
+ if (!get_dcammu().store(m_ssw, m_rs[15] - 0x8, old_ssw))
+ fatalerror("intrap unrecoverable fault 0x%04x push ssw ssp 0x%08x pc 0x%08x\n", m_exception, m_rs[15] - 0x8, old_pc);
+
+ if (!get_dcammu().store(m_ssw, m_rs[15] - 0xc, (old_psw & ~(PSW_CTS | PSW_MTS)) | source))
+ fatalerror("intrap unrecoverable fault 0x%04x push psw ssp 0x%08x pc 0x%08x\n", m_exception, m_rs[15] - 0xc, old_pc);
// decrement supervisor stack pointer
- m_rs[15] -= get_eframe_size();
+ m_rs[15] -= 12;
+
+ // set ssw from vector and previous mode
+ set_ssw((new_ssw & ~SSW_P) | (old_ssw & SSW_U) << 1);
+
+ // clear psw
+ set_psw(0);
+
+ // return new pc from trap vector
+ return new_pc;
+}
+
+u32 clipper_c400_device::intrap(const u16 vector, const u32 old_pc)
+{
+ const u32 old_ssw = m_ssw;
+ const u32 old_psw = m_psw;
+ u32 new_pc = 0, new_ssw = 0;
+
+ // clear ssw bits to enable supervisor memory access
+ m_ssw &= ~(SSW_U | SSW_K | SSW_UU | SSW_KU);
+
+ // clear exception state
+ m_exception = 0;
+
+ // fetch ssw and pc from interrupt vector (C400 reversed wrt C100/C300)
+ if (!get_dcammu().load(m_ssw, vector + 0, [&new_ssw](u32 v) { new_ssw = v; }))
+ fatalerror("intrap unrecoverable fault 0x%04x load ssw address 0x%08x pc 0x%08x\n", m_exception, vector + 0, old_pc);
+ if (!get_dcammu().load(m_ssw, vector + 4, [&new_pc](u32 v) { new_pc = v; }))
+ fatalerror("intrap unrecoverable fault 0x%04x load pc address 0x%08x pc 0x%08x\n", m_exception, vector + 4, old_pc);
+
+ LOGMASKED(LOG_EXCEPTION, "intrap vector 0x%04x pc 0x%08x ssp 0x%08x new_pc 0x%08x new_ssw 0x%08x\n", vector, old_pc, m_rs[15], new_pc, new_ssw);
+
+ // derive cts and mts from vector
+ u32 source = 0;
+ switch (vector)
+ {
+ // data memory trap group
+ case EXCEPTION_D_CORRECTED_MEMORY_ERROR:
+ case EXCEPTION_D_UNCORRECTABLE_MEMORY_ERROR:
+ case EXCEPTION_D_ALIGNMENT_FAULT:
+ case EXCEPTION_D_PAGE_FAULT:
+ case EXCEPTION_D_READ_PROTECT_FAULT:
+ case EXCEPTION_D_WRITE_PROTECT_FAULT:
+
+ // instruction memory trap group
+ case EXCEPTION_I_CORRECTED_MEMORY_ERROR:
+ case EXCEPTION_I_UNCORRECTABLE_MEMORY_ERROR:
+ case EXCEPTION_I_ALIGNMENT_FAULT:
+ case EXCEPTION_I_PAGE_FAULT:
+ case EXCEPTION_I_EXECUTE_PROTECT_FAULT:
+ source = (vector & MTS_VMASK) << (MTS_SHIFT - MTS_VSHIFT);
+ break;
+
+ // integer arithmetic trap group
+ case EXCEPTION_INTEGER_DIVIDE_BY_ZERO:
+ source = CTS_DIVIDE_BY_ZERO;
+ break;
+
+ // illegal operation trap group
+ case EXCEPTION_ILLEGAL_OPERATION:
+ source = CTS_ILLEGAL_OPERATION;
+ break;
+ case EXCEPTION_PRIVILEGED_INSTRUCTION:
+ source = CTS_PRIVILEGED_INSTRUCTION;
+ break;
+
+ // diagnostic trap group
+ case EXCEPTION_TRACE:
+ source = CTS_TRACE_TRAP;
+ break;
+ }
+
+ // push pc, ssw and psw onto supervisor stack
+ if (!get_dcammu().store(m_ssw, m_rs[15] - 0x4, old_pc))
+ fatalerror("intrap unrecoverable fault 0x%04x push pc ssp 0x%08x pc 0x%08x\n", m_exception, m_rs[15] - 0x4, old_pc);
+
+ if (!get_dcammu().store(m_ssw, m_rs[15] - 0x8, old_ssw))
+ fatalerror("intrap unrecoverable fault 0x%04x push ssw ssp 0x%08x pc 0x%08x\n", m_exception, m_rs[15] - 0x8, old_pc);
+
+ if (!get_dcammu().store(m_ssw, m_rs[15] - 0xc, (old_psw & ~(PSW_CTS | PSW_MTS)) | source))
+ fatalerror("intrap unrecoverable fault 0x%04x push psw ssp 0x%08x pc 0x%08x\n", m_exception, m_rs[15] - 0xc, old_pc);
+
+ // TODO: push pc1
+ // TODO: push pc2
+
+ // push delayed branch pc onto supervisor stack
+ if (!get_dcammu().store(m_ssw, m_rs[15] - 0x18, m_db_pc))
+ fatalerror("intrap unrecoverable fault 0x%04x push db_pc address 0x%08x pc 0x%08x\n", m_exception, m_rs[15] - 0x18, old_pc);
+
+ // decrement supervisor stack pointer
+ m_rs[15] -= 24;
// set ssw from vector and previous mode
set_ssw((new_ssw & ~SSW_P) | (old_ssw & SSW_U) << 1);
@@ -1736,37 +1768,119 @@ void clipper_device::fp_exception()
void clipper_c400_device::execute_instruction()
{
+ // update delay slot pointer
+ switch (PSW(DSP))
+ {
+ case DSP_S1:
+ // take delayed branch
+ m_psw &= ~PSW_DSP;
+ m_ip = m_db_pc;
+ return;
+
+ case DSP_SALL:
+ // one delay slot still active
+ m_psw &= ~PSW_DSP;
+ m_psw |= DSP_S1;
+ break;
+
+ case DSP_SETUP:
+ // two delay slots active
+ m_psw &= ~PSW_DSP;
+ m_psw |= DSP_SALL;
+ break;
+ }
+
+ // if executing a delay slot instruction, test for valid type
+ if (PSW(DSP))
+ {
+ switch (m_info.opcode)
+ {
+ case 0x13: // ret
+ case 0x44: // call
+ case 0x45:
+ case 0x48: // b*
+ case 0x49:
+ case 0x4a: // cdb
+ case 0x4b:
+ case 0x4c: // cdbeq
+ case 0x4d:
+ case 0x4e: // cdbne
+ case 0x4f:
+ case 0x50: // db*
+ case 0x51:
+ // TODO: this should throw some kind of illegal instruction trap, not abort
+ fatalerror("instruction type 0x%02x invalid in branch delay slot pc 0x%08x\n", m_info.opcode, m_pc);
+
+ default:
+ break;
+ }
+ }
+
switch (m_info.opcode)
{
-#ifdef UNIMPLEMENTED_C400
case 0x46:
case 0x47:
- // loadd2:
+ // loadd2: load double floating double
+ // TODO: 128-bit load
+ get_dcammu().load(m_ssw, m_info.address + 0, [this](float64 v) { set_fp(R2 + 0, v, F_NONE); });
+ get_dcammu().load(m_ssw, m_info.address + 8, [this](float64 v) { set_fp(R2 + 1, v, F_NONE); });
+ // TRAPS: C,U,A,P,R,I
break;
case 0x4a:
case 0x4b:
- // cdb:
- break;
+ // cdb: call with delayed branch?
+ // emulate.h: "cdb is special because it does not support all addressing modes", 2-3 parcels
+ fatalerror("cdb pc 0x%08x\n", m_pc);
case 0x4c:
case 0x4d:
- // cdbeq:
- break;
+ // cdbeq: call with delayed branch if equal?
+ fatalerror("cdbeq pc 0x%08x\n", m_pc);
case 0x4e:
case 0x4f:
- // cdbne:
- break;
+ // cdbne: call with delayed branch if not equal?
+ fatalerror("cdbne pc 0x%08x\n", m_pc);
case 0x50:
case 0x51:
- // db*:
+ // db*: delayed branch on condition
+ if (evaluate_branch())
+ {
+ m_psw |= DSP_SETUP;
+ m_db_pc = m_info.address;
+ }
break;
case 0xb0:
// abss: absolute value single floating?
+ if (float32_lt(get_fp32(R1), 0))
+ set_fp(R2, float32_mul(get_fp32(R1), int32_to_float32(-1)), F_IVUX);
+ else
+ set_fp(R2, get_fp32(R1), F_IVUX);
break;
case 0xb2:
// absd: absolute value double floating?
+ if (float64_lt(get_fp64(R1), 0))
+ set_fp(R2, float64_mul(get_fp64(R1), int32_to_float64(-1)), F_IVUX);
+ else
+ set_fp(R2, get_fp64(R1), F_IVUX);
+ break;
+
+ case 0xb4:
+ // unprivileged macro instructions
+ switch (m_info.subopcode)
+ {
+ case 0x44:
+ // cnvxsw: ??
+ fatalerror("cnvxsw pc 0x%08x\n", m_pc);
+ case 0x46:
+ // cnvxdw: ??
+ fatalerror("cnvxdw pc 0x%08x\n", m_pc);
+
+ default:
+ clipper_device::execute_instruction();
+ break;
+ }
break;
case 0xb6:
@@ -1777,19 +1891,29 @@ void clipper_c400_device::execute_instruction()
{
case 0x07:
// loadts: unknown?
+ fatalerror("loadts pc 0x%08x\n", m_pc);
+
+ default:
+ clipper_device::execute_instruction();
break;
}
}
+ else
+ m_exception = EXCEPTION_PRIVILEGED_INSTRUCTION;
break;
case 0xbc:
// waitd:
+ if (!SSW(U))
+ ; // TODO: don't know what this instruction does
+ else
+ m_exception = EXCEPTION_PRIVILEGED_INSTRUCTION;
break;
case 0xc0:
- // s*:
+ // s*: set register on condition
+ m_r[R1] = evaluate_branch() ? 1 : 0;
break;
-#endif
default:
clipper_device::execute_instruction();
diff --git a/src/devices/cpu/clipper/clipper.h b/src/devices/cpu/clipper/clipper.h
index 1781401fece..c1324d8ae27 100644
--- a/src/devices/cpu/clipper/clipper.h
+++ b/src/devices/cpu/clipper/clipper.h
@@ -10,6 +10,9 @@
#include "softfloat/milieu.h"
#include "softfloat/softfloat.h"
+#include "cpu/clipper/common.h"
+#include "machine/cammu.h"
+
// convenience macros for dealing with the psw and ssw
#define PSW(mask) (m_psw & PSW_##mask)
#define SSW(mask) (m_ssw & SSW_##mask)
@@ -17,22 +20,9 @@
class clipper_device : public cpu_device
{
public:
- DECLARE_READ32_MEMBER(get_ssw) const { return m_ssw; }
DECLARE_WRITE8_MEMBER(set_ivec) { m_ivec = data; }
DECLARE_WRITE16_MEMBER(set_exception);
- enum addressing_modes : u8
- {
- ADDR_MODE_PC32 = 0x10, // pc relative with 32 bit displacement
- ADDR_MODE_ABS32 = 0x30, // 32 bit absolute
- ADDR_MODE_REL32 = 0x60, // relative with 32 bit displacement
- ADDR_MODE_PC16 = 0x90, // pc relative with 16 bit displacement
- ADDR_MODE_REL12 = 0xa0, // relative with 12 bit displacement
- ADDR_MODE_ABS16 = 0xb0, // 16 bit absolute
- ADDR_MODE_PCX = 0xd0, // pc indexed
- ADDR_MODE_RELX = 0xe0 // relative indexed
- };
-
// branch conditions (first description for comparison, second for move/logical)
enum branch_conditions : u8
{
@@ -94,73 +84,21 @@ public:
FR_3 = 0x00018000 // round toward zero
};
- enum ssw : u32
+ enum psw_dsp : u32
{
- SSW_IN = 0x0000000f, // interrupt number (4 bits)
- SSW_IL = 0x000000f0, // interrupt level (4 bits)
- SSW_EI = 0x00000100, // enable interrupts
- SSW_ID = 0x0001fe00, // cpu rev # and type (8 bits)
- // unused (5 bits)
- SSW_FRD = 0x00400000, // floating registers dirty
- SSW_TP = 0x00800000, // trace trap pending
- SSW_ECM = 0x01000000, // enable corrected memory error
- SSW_DF = 0x02000000, // fpu disabled
- SSW_M = 0x04000000, // mapped mode
- SSW_KU = 0x08000000, // user protect key
- SSW_UU = 0x10000000, // user data mode
- SSW_K = 0x20000000, // protect key
- SSW_U = 0x40000000, // user mode
- SSW_P = 0x80000000 // previous mode
+ DSP_NONE = 0x00000000, // no delayed branch active
+ DSP_S1 = 0x00100000, // delayed branch slot 1 active
+ DSP_SALL = 0x00200000, // delayed branch slots 0 and 1 active
+ DSP_SETUP = 0x00300000 // delayed branch taken
};
enum ssw_id : u32
{
- SSW_ID_C400R0 = 0x00000,
- SSW_ID_C400R1 = 0x04000,
- SSW_ID_C400R2 = 0x08000,
- SSW_ID_C400R3 = 0x0c000,
- SSW_ID_C400R4 = 0x10000
- };
-
- enum exception_vectors : u16
- {
- // data memory trap group
- EXCEPTION_D_CORRECTED_MEMORY_ERROR = 0x108,
- EXCEPTION_D_UNCORRECTABLE_MEMORY_ERROR = 0x110,
- EXCEPTION_D_ALIGNMENT_FAULT = 0x120,
- EXCEPTION_D_PAGE_FAULT = 0x128,
- EXCEPTION_D_READ_PROTECT_FAULT = 0x130,
- EXCEPTION_D_WRITE_PROTECT_FAULT = 0x138,
-
- // floating-point arithmetic trap group
- EXCEPTION_FLOATING_INEXACT = 0x180,
- EXCEPTION_FLOATING_UNDERFLOW = 0x188,
- EXCEPTION_FLOATING_DIVIDE_BY_ZERO = 0x190,
- EXCEPTION_FLOATING_OVERFLOW = 0x1a0,
- EXCEPTION_FLOATING_INVALID_OPERATION = 0x1c0,
-
- // integer arithmetic trap group
- EXCEPTION_INTEGER_DIVIDE_BY_ZERO = 0x208,
-
- // instruction memory trap group
- EXCEPTION_I_CORRECTED_MEMORY_ERROR = 0x288,
- EXCEPTION_I_UNCORRECTABLE_MEMORY_ERROR = 0x290,
- EXCEPTION_I_ALIGNMENT_FAULT = 0x2a0,
- EXCEPTION_I_PAGE_FAULT = 0x2a8,
- EXCEPTION_I_EXECUTE_PROTECT_FAULT = 0x2b0,
-
- // illegal operation trap group
- EXCEPTION_ILLEGAL_OPERATION = 0x300,
- EXCEPTION_PRIVILEGED_INSTRUCTION = 0x308,
-
- // diagnostic trap group
- EXCEPTION_TRACE = 0x380,
-
- // supervisor calls (0x400-0x7f8)
- EXCEPTION_SUPERVISOR_CALL_BASE = 0x400,
-
- // prioritized interrupts (0x800-0xff8)
- EXCEPTION_INTERRUPT_BASE = 0x800
+ SSW_ID_C400R0 = 0x00800,
+ SSW_ID_C400R1 = 0x04800,
+ SSW_ID_C400R2 = 0x08800,
+ SSW_ID_C400R3 = 0x0c800,
+ SSW_ID_C400R4 = 0x10800
};
// trap source values are shifted into the correct field in the psw
@@ -230,13 +168,17 @@ protected:
// device_disasm_interface overrides
virtual util::disasm_interface *create_disassembler() override;
+ // mmu helpers
+ virtual cammu_device &get_icammu() const = 0;
+ virtual cammu_device &get_dcammu() const = 0;
+
// cpu execution logic
bool decode_instruction();
virtual void execute_instruction();
bool evaluate_branch() const;
// exception entry and return helpers
- u32 intrap(const u16 vector, const u32 old_pc);
+ virtual u32 intrap(const u16 vector, const u32 old_pc);
u32 reti();
// cpu state helpers
@@ -248,11 +190,6 @@ protected:
virtual int get_ireg_count() const { return 16; }
virtual int get_freg_count() const { return 8; }
- // exception vector and frame helpers
- virtual int get_eframe_size() const { return 12; }
- virtual int get_evpc_offset() const { return 0; }
- virtual int get_evssw_offset() const { return 4; }
-
// floating point helpers
float32 get_fp32(const u8 reg) const { return m_f[reg & 0xf]; }
float64 get_fp64(const u8 reg) const { return m_f[reg & 0xf]; }
@@ -317,11 +254,9 @@ protected:
};
// emulation state
- address_space_config m_insn_config;
- address_space_config m_data_config;
-
- address_space *m_insn;
- address_space *m_data;
+ address_space_config m_main_config;
+ address_space_config m_io_config;
+ address_space_config m_boot_config;
enum registers
{
@@ -333,6 +268,7 @@ protected:
};
int m_icount; // instruction cycle count
+ bool m_wait;
// program-visible cpu state
u32 m_pc; // current instruction address
@@ -372,12 +308,28 @@ class clipper_c100_device : public clipper_device
{
public:
clipper_c100_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
+
+protected:
+ virtual cammu_device &get_icammu() const override { return *m_icammu; }
+ virtual cammu_device &get_dcammu() const override { return *m_dcammu; }
+
+private:
+ required_device m_icammu;
+ required_device m_dcammu;
};
class clipper_c300_device : public clipper_device
{
public:
clipper_c300_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
+
+protected:
+ virtual cammu_device &get_icammu() const override { return *m_icammu; }
+ virtual cammu_device &get_dcammu() const override { return *m_dcammu; }
+
+private:
+ required_device m_icammu;
+ required_device m_dcammu;
};
class clipper_c400_device : public clipper_device
@@ -386,19 +338,20 @@ public:
clipper_c400_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
protected:
+ virtual u32 intrap(const u16 vector, const u32 old_pc) override;
+
// C400 has additional 8 floating point registers
virtual int get_freg_count() const override { return 16; }
- // C400 creates a 24 byte exception frame (C100/C300 is 12 bytes), but the
- // service routine must increment sp by 12 prior to executing reti
- // exception frame size
- virtual int get_eframe_size() const override { return 24; }
-
- // C400 pc and ssw are reversed in exception vector compared to C100/C300
- virtual int get_evpc_offset() const override { return 4; }
- virtual int get_evssw_offset() const override { return 0; }
-
virtual void execute_instruction() override;
+
+ virtual cammu_device &get_icammu() const override { return *m_cammu; }
+ virtual cammu_device &get_dcammu() const override { return *m_cammu; }
+
+private:
+ u32 m_db_pc; // delayed branch pc
+
+ required_device m_cammu;
};
DECLARE_DEVICE_TYPE(CLIPPER_C100, clipper_c100_device)
diff --git a/src/devices/cpu/clipper/clipperd.cpp b/src/devices/cpu/clipper/clipperd.cpp
index d328d3b4631..c11cf0a5ee8 100644
--- a/src/devices/cpu/clipper/clipperd.cpp
+++ b/src/devices/cpu/clipper/clipperd.cpp
@@ -2,6 +2,7 @@
// copyright-holders:Patrick Mackinlay
#include "emu.h"
+#include "cpu/clipper/common.h"
#include "clipperd.h"
/*
@@ -297,6 +298,10 @@ offs_t clipper_disassembler::disassemble(std::ostream &stream, offs_t pc, const
case 0x3e: util::stream_format(stream, "trapfn"); break;
case 0x3f: util::stream_format(stream, "loadfs r%d,f%d", (opcodes.r16(pc+2) & 0xf0) >> 4, opcodes.r16(pc+2) & 0xf); break;
+#if C400_INSTRUCTIONS
+ case 0x44: util::stream_format(stream, "cnvxsw f%d,f%d", (opcodes.r16(pc + 2) & 0xf0) >> 4, opcodes.r16(pc + 2) & 0xf); break;
+ case 0x46: util::stream_format(stream, "cnvxdw f%d,f%d", (opcodes.r16(pc + 2) & 0xf0) >> 4, opcodes.r16(pc + 2) & 0xf); break;
+#endif
default:
util::stream_format(stream, "macro 0x%04x 0x%04x", opcodes.r16(pc), opcodes.r16(pc+2));
break;
diff --git a/src/devices/cpu/clipper/clipperd.h b/src/devices/cpu/clipper/clipperd.h
index 1dd757fde63..cac65afdf93 100644
--- a/src/devices/cpu/clipper/clipperd.h
+++ b/src/devices/cpu/clipper/clipperd.h
@@ -16,22 +16,8 @@ public:
virtual offs_t disassemble(std::ostream &stream, offs_t pc, const data_buffer &opcodes, const data_buffer ¶ms) override;
private:
- enum addressing_modes : u8
- {
- ADDR_MODE_PC32 = 0x10, // pc relative with 32 bit displacement
- ADDR_MODE_ABS32 = 0x30, // 32 bit absolute
- ADDR_MODE_REL32 = 0x60, // relative with 32 bit displacement
- ADDR_MODE_PC16 = 0x90, // pc relative with 16 bit displacement
- ADDR_MODE_REL12 = 0xa0, // relative with 12 bit displacement
- ADDR_MODE_ABS16 = 0xb0, // 16 bit absolute
- ADDR_MODE_PCX = 0xd0, // pc indexed
- ADDR_MODE_RELX = 0xe0 // relative indexed
- };
-
static const char *const cc[];
std::string address (offs_t pc, const data_buffer &opcodes);
-
-
};
#endif
diff --git a/src/devices/cpu/clipper/common.h b/src/devices/cpu/clipper/common.h
new file mode 100644
index 00000000000..343e18c4913
--- /dev/null
+++ b/src/devices/cpu/clipper/common.h
@@ -0,0 +1,83 @@
+// license:BSD-3-Clause
+// copyright-holders:Patrick Mackinlay
+
+#ifndef MAME_CPU_CLIPPER_COMMON_H
+#define MAME_CPU_CLIPPER_COMMON_H
+
+#pragma once
+
+enum addressing_modes : u8
+{
+ ADDR_MODE_PC32 = 0x10, // pc relative with 32 bit displacement
+ ADDR_MODE_ABS32 = 0x30, // 32 bit absolute
+ ADDR_MODE_REL32 = 0x60, // relative with 32 bit displacement
+ ADDR_MODE_PC16 = 0x90, // pc relative with 16 bit displacement
+ ADDR_MODE_REL12 = 0xa0, // relative with 12 bit displacement
+ ADDR_MODE_ABS16 = 0xb0, // 16 bit absolute
+ ADDR_MODE_PCX = 0xd0, // pc indexed
+ ADDR_MODE_RELX = 0xe0 // relative indexed
+};
+
+enum ssw_mask : u32
+{
+ SSW_IN = 0x0000000f, // interrupt number (4 bits)
+ SSW_IL = 0x000000f0, // interrupt level (4 bits)
+ SSW_EI = 0x00000100, // enable interrupts
+ SSW_ID = 0x0001fe00, // cpu rev # and type (8 bits)
+ // unused (5 bits)
+ SSW_FRD = 0x00400000, // floating registers dirty
+ SSW_TP = 0x00800000, // trace trap pending
+ SSW_ECM = 0x01000000, // enable corrected memory error
+ SSW_DF = 0x02000000, // fpu disabled
+ SSW_M = 0x04000000, // mapped mode
+ SSW_KU = 0x08000000, // user protect key
+ SSW_UU = 0x10000000, // user data mode
+ 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
+{
+ // data memory trap group
+ EXCEPTION_D_CORRECTED_MEMORY_ERROR = 0x108,
+ EXCEPTION_D_UNCORRECTABLE_MEMORY_ERROR = 0x110,
+ EXCEPTION_D_ALIGNMENT_FAULT = 0x120,
+ EXCEPTION_D_PAGE_FAULT = 0x128,
+ EXCEPTION_D_READ_PROTECT_FAULT = 0x130,
+ EXCEPTION_D_WRITE_PROTECT_FAULT = 0x138,
+
+ // floating-point arithmetic trap group
+ EXCEPTION_FLOATING_INEXACT = 0x180,
+ EXCEPTION_FLOATING_UNDERFLOW = 0x188,
+ EXCEPTION_FLOATING_DIVIDE_BY_ZERO = 0x190,
+ EXCEPTION_FLOATING_OVERFLOW = 0x1a0,
+ EXCEPTION_FLOATING_INVALID_OPERATION = 0x1c0,
+
+ // integer arithmetic trap group
+ EXCEPTION_INTEGER_DIVIDE_BY_ZERO = 0x208,
+
+ // instruction memory trap group
+ EXCEPTION_I_CORRECTED_MEMORY_ERROR = 0x288,
+ EXCEPTION_I_UNCORRECTABLE_MEMORY_ERROR = 0x290,
+ EXCEPTION_I_ALIGNMENT_FAULT = 0x2a0,
+ EXCEPTION_I_PAGE_FAULT = 0x2a8,
+ EXCEPTION_I_EXECUTE_PROTECT_FAULT = 0x2b0,
+
+ // illegal operation trap group
+ EXCEPTION_ILLEGAL_OPERATION = 0x300,
+ EXCEPTION_PRIVILEGED_INSTRUCTION = 0x308,
+
+ // diagnostic trap group
+ EXCEPTION_TRACE = 0x380,
+
+ // supervisor calls (0x400-0x7f8)
+ EXCEPTION_SUPERVISOR_CALL_BASE = 0x400,
+
+ // prioritized interrupts (0x800-0xff8)
+ EXCEPTION_INTERRUPT_BASE = 0x800
+};
+
+#endif // MAME_CPU_CLIPPER_COMMON_H
diff --git a/src/mame/drivers/interpro.cpp b/src/mame/drivers/interpro.cpp
index ee65b1e6bb8..c6e455d0e89 100644
--- a/src/mame/drivers/interpro.cpp
+++ b/src/mame/drivers/interpro.cpp
@@ -7,7 +7,7 @@
*
* The first systems were built using the original C100 CLIPPER CPU, and used
* an additional Intel 80186 as an I/O processor, later moving to a C300 with
- * 80386 IOP. Around 1989, the CLIPPER became fast enough to obviate the need
+ * 80386 IOP. Around 1990, the CLIPPER became fast enough to obviate the need
* for the separate I/O processor, and systems from that point used the main
* CPU for both compute and I/O, along with some custom ASICs.
*
@@ -17,66 +17,77 @@
* Year Family Models CPU
* 1986 amethyst 32C/100/200 C100 (80186 IOP)
* 1988 topaz 300/3000/4000/5000 C300/C300Plus (80386 IOP)
- * 1989 turquoise 2000 C300
- * 1989 emerald 6000/6100/6200/6500/6600 C300/C300Plus (C4T in 6600?)
- * 1991 sapphire 2400/6400 C4T
- * 1992 sapphire 2500/2700/6700/6800/2800 C4I
+ * 1990 emerald 6000/6100/6200/6500 C300/C300Plus
+ * 1990 turquoise 2000 C300
+ * 1991 emerald? 6600 C4?
+ * 1992 sapphire 2400/6400 C4T
+ * 1993 sapphire 2500/2700/6700/6800 C4I
+ * 1994 sapphire 2800 C4I
*
* Individual models and some of their specific attributes include:
*
- * Model Year CPU Clock Family
- * 2000 1989 C300 turquoise
- * 6000 1989 C300 emerald
- * 2400 1991? C4T 40MHz? sapphire
- * 6400 1991 C4T 40MHz sapphire
- * 6600 C400 emerald (IOI, SRX bus?)
- * 6700 1992 C400I 70MHz? sapphire
- * 6800 1993 C400I 80MHz? sapphire
- * 2500 1993? C400I 50MHz? sapphire
- * 2700 1992 C400I 70MHz? sapphire
- * 2800 1994 C400I 80MHz? sapphire
+ * Model Year CPU Performance Clock Family Bus
+ * 6000 1990 C300 10 MIPS 40MHz emerald SRX
+ * 6100 1990 14 MIPS emerald IOI?, 6105 has 5-slot chassis
+ * 6500 C300+ emerald IOI, QWIC bus?
+ * 6200 1990 C300+ 14 MIPS 60MHz emerald
+ * 1991 18 MIPS
+ * 2000 1990 C300 12.5 MIPS 50MHz? turquoise CBUS
+ * 6600 1991 C400 40 MIPS emerald? IOI, SRX bus?
+ * 2400 1992 C4T 36 MIPS/33 SPECmarks 40MHz? sapphire CBUS
+ * 6400 1992 C4T 36 MIPS/33 SPECmarks 40MHz sapphire SRX
+ * 2700 1993 C400I 40.1 SPECmark89 sapphire 2 CBUS
+ * 6700 1993 C400I 40.1 SPECmark89 sapphire 2 SRX
+ * 6800 1993 C400I 67.2 SPECmark89 sapphire 3 SRX
+ * 2500 1993 C400I 19.9 SPECint92 sapphire
+ * 2800 1994 C400I sapphire 3 CBUS?
*
- * 6100 emerald (IOI)
- * 6200 1989 C300Plus 60MHz emerald
- * 6500 C300Plus emerald (IOI, QWIC bus?)
+ * IOI == I/O Interface (another type of bus?)
+ * Sapphire 2 w/CBUS supports RETRY (maybe bus retry?)
*
- * With many exceptions, the general model numbering system is ABCD, where:
+ * With some exceptions, system models are numbered ABCD, where:
*
- * A: case type (2=desktop, 6=tower)
+ * A: case type (2=desktop, 6=minicase)
* B: CPU type (0=C300, 4=C4T, 6=C400?, 7/8/5 = C400I)
- * C: graphics type (0=none, 3/5=GT, 4/8 = EDGE)
- * D: always 0?
+ * C: graphics type (0=none, 3/5=GT, 4=EDGE-1, 8 = EDGE-2)
+ * D: usually 0, 6xxx systems have 5, 7 and 9 options (backplane type?)
*
- * Both the desktop and tower units supported an expansion bus with a variety
+ * Graphics type 3 is for GT graphics fitted to a 2xxx system, and type 5 when
+ * fitted to a 6xxx system. The latter is possibly also known as GTDB.
+ *
+ * Both the desktop and minicase units supported expansion slots with a variety
* of cards, although with different profiles and connectors between 2xxx and
* 6xxx systems. The bus is referred to as SR, SRX, SR Bus, CBUS and some
- * combinations of these in various places, but all appears to be compatible or
+ * combinations of these in various places, but all appear to be compatible or
* identical, possibly with SRX being an enhanced version. The bus supported a
* range of add-in cards, ranging from expanded SCSI and serial controllers,
* to specialised scanning and plotting controllers, a VME bridge, and most
* importantly various single and dual-headed graphics boards.
*
* The InterPro graphics options included the GT range, generally fitted to the
- * desktop systems, and EDGE graphics for the towers. Systems with no graphics
- * were operated through a serial console on serial port 2, and were branded as
- * InterServe rather than InterPro systems.
+ * desktops, and EDGE graphics for the 6xxx systems. Systems with no graphics
+ * were operated through a serial terminal on serial port 2, and were branded
+ * InterServe rather than InterPro.
*
* Model Year Performance
* GT 1990? 360k 2D vec/s (in a 2020)
- * EDGE-1
- * EDGE-2
+ * EDGE-1 8 planes + 1 highlight plane, double buffered (6040)
+ * EDGE-2 24 bit, 400k 2D vec/s, 350k 3D vec/s (6280)
* GT+ 760k 2D vec/s, 530k 3D vec/s (in a 2730)
* GTII 830k 2D vec/s, 640k 3D vec/s (in a 6750)
* 900k 2D vec/s, 700k 3D vec/s (in a 6850)
* EDGE II+ 50k Gouraud-shaded poly/s (in a 6780)
*
+ * GT graphics are also referred to in various places as Memory Mapped Graphics
+ * or MMG. EDGE stands for Extensible Display Geometry Engine.
+ *
* This emulation currently supports the Turquoise and Sapphire desktop systems (i.e. models
* 2000/2400/2500/2700/2800). Base GT graphics can be used with any of these models, or the
* graphics and keyboard removed and the systems used with a serial terminal instead.
*
* Key parts lists for the supported models are as follows.
*
- * 2000 Turquoise (C300 @ 40MHz?, main board PCB962)
+ * 2000 Turquoise (C300 @ 50MHz?, main board PCB962)
*
* Ref Part Function
* U37 Intel 82072 Floppy drive controller
@@ -103,16 +114,16 @@
* U34 Xilinix XC3020-50 Plotter control FPGA?
* U35 128 kB EPROM (MPRGW510B) Boot ROM
* U43? (MPRGM610P) Bitstream for XC3020?
- * U44 Intel 82596SX Ethernet controller (20MHz)
- * U67 Intel N28F010-200 128Kx8 flash memory (200ns)
+ * U44 Intel 82596SX-20 Ethernet controller
+ * U67 Intel N28F010-200 128Kx8 flash memory (Y226 0B03 0592)
* U68 CYID21603 TC150G89AF
* U71 LSI L1A6104 CICD 95801 Intergraph I/O gate array
- * U76 Intel N28F010-200 128Kx8 flash memory (200ns)
+ * U76 Intel N28F010-200 128Kx8 flash memory (Y225 0B?? 27??)
* U81 NCR 53C94 SCSI controller
* U86 24.0 MHz crystal Clock source for 53C94?
* U87 4.9152 MHz crystal Clock source for 8530s?
* U88 20.0 MHz crystal Clock source for 82596?
- * U91 Intel N82077AA Floppy drive controller
+ * U91 Intel N82077AA-1 Floppy drive controller
* U96 32.0 MHz crystal
* U97 40.0 MHz crystal
* U112? (MPRG4230A) node ID prom?
@@ -129,23 +140,40 @@
* U34 Xilinix XC3020-70 Plotter control FPGA?
* U35 128 kB EPROM (MPRGZ530A) Boot ROM
* U43? (MPRGM610P) Bitstream for XC3020?
- * U44 Intel 82596SX? Ethernet controller
+ * U44 Intel 82596SX-20 Ethernet controller
* U68 CYID21603 TC150G89AF
- * U67 Intel N28F010 128Kx8 flash memory
+ * U67 Intel N28F010 128Kx8 flash memory (Y226 0C30 4291)
* U71 LSI L1A7374 CIDC094A3 Intergraph I/O gate array
- * U76 Intel N28F010 128Kx8 flash memory
+ * U76 Intel N28F010 128Kx8 flash memory (Y225 0C30 4220)
* U81 NCR 53C94 SCSI controller
- * U86 24.0 MHz crystal Clock source for 53C94?
+ * U86 24.0 MHz crystal Clock source for 82077
* U87 4.9152 MHz crystal Clock source for 8530s?
* U88 20.0 MHz crystal Clock source for 82596?
- * U91 Intel N82077AA? Floppy drive controller
- * U96 32.0 MHz crystal?
+ * U91 Intel N82077SL-1 Floppy drive controller
+ * U96 29.0 MHz crystal
* U97 40.0 MHz crystal
* U112? (MPRGZ260E) node ID prom?
- * U113? Dallas DS12887 RTC and NVRAM
+ * U113 Dallas DS12887 RTC and NVRAM
* U117? diagnostic 7-segment LED?
* U118? ()
* U155 CYID212?4 TC140G54AF?
+ *
+ * CPU daughter-boards
+ * PCB824 Rev J - 2000 (also has label MPCBA5507)
+ * SMT082 (MSMT0820B, 36MHz?) - 6400 (SMT046 "6400 36-MHz Series System Board")
+ * SMT03? 2400/6400 - (MSMT03804 -> rev 2 cammu, goes with "6400 36-MHz Series System Board", MSMT0380A eco 3+ use rev 3 cammu)
+ * SMT019 (MSMT019 C4E CPU Assembly)
+ * SMT104 Rev A - 2700/6700 (aka MSMT1040A "C4I CPU", C4 CPU REV 3 + C4 FPU REV 3 + C4I CAMMU)
+ *
+ * PCB962 2000 System Board MPCB824 C300
+ * SMT046 6400 36-MHz Series System Board MSMT03804 rev 2 CAMMU/30MHz Kryptonite Rev 3 CAMMU/32MHz Kryptonite Rev 3 CAMMU/MSMT0820B(36MHz)
+ * SMT047 2400 Series System Board MSMT03804 rev 2 CAMMU/MSMT0380A eco 3+ Rev 3 CAMMU
+ * SMT098A 6400 32-MHz Sapphire System Board
+ * SMT098B 6400 32-MHz Sapphire System Board
+ * SMT127 6700 Series System Board MSMT1040A C4I: C4 CPU Rev 3 + C4 FPU Rev 3 + C4I CAMMU
+ * SMT128 2700 Series System Board MSMT1040A C4I: C4 CPU Rev 3 + C4 FPU Rev 3 + C4I CAMMU
+ * SMT144 6800 Series System Board
+ * SMT145 2800 Series System Board
*/
#include "emu.h"
@@ -184,12 +212,6 @@ void interpro_state::machine_reset()
DRIVER_INIT_MEMBER(interpro_state, common)
{
-}
-
-DRIVER_INIT_MEMBER(turquoise_state, turquoise)
-{
- interpro_state::init_common();
-
// FIXME: not all memory sizes are reported properly using fdm "5 inqhw" and
// "optimum_memory" commands
@@ -200,25 +222,7 @@ DRIVER_INIT_MEMBER(turquoise_state, turquoise)
// 256 = reports 256M, 32x8
// map the configured ram
- m_d_cammu->space(0).install_ram(0, m_ram->mask(), m_ram->pointer());
- m_i_cammu->space(0).install_ram(0, m_ram->mask(), m_ram->pointer());
-}
-
-DRIVER_INIT_MEMBER(sapphire_state, sapphire)
-{
- interpro_state::init_common();
-
- // FIXME: not all memory sizes are reported properly using fdm "5 inqhw" and
- // "optimum_memory" commands
-
- // 16 = reports 16M, banks empty?
- // 32 = reports 16M, banks empty?
- // 64 = reports 128M, 16x8
- // 128 = reports 128M, 16x8
- // 256 = reports 256M, 32x8
-
- // map the configured ram
- m_mmu->space(0).install_ram(0, m_ram->mask(), m_ram->pointer());
+ m_maincpu->space(0).install_ram(0, m_ram->mask(), m_ram->pointer());
}
WRITE16_MEMBER(interpro_state::sreg_led_w)
@@ -275,7 +279,7 @@ READ16_MEMBER(interpro_state::sreg_error_r)
return result;
}
-READ32_MEMBER(interpro_state::unmapped_r)
+READ32_MEMBER(sapphire_state::unmapped_r)
{
// check if non-existent memory errors are enabled
if (!machine().side_effects_disabled())
@@ -291,7 +295,7 @@ READ32_MEMBER(interpro_state::unmapped_r)
return space.unmap();
}
-WRITE32_MEMBER(interpro_state::unmapped_w)
+WRITE32_MEMBER(sapphire_state::unmapped_w)
{
// check if non-existent memory errors are enabled
if (m_arbga->tctrl_r(space, offset, mem_mask) & interpro_arbga_device::TCTRL_ENNEM)
@@ -319,23 +323,6 @@ READ8_MEMBER(interpro_state::nodeid_r)
return space.unmap();
}
-// these maps connect the cpu virtual addresses to the mmu
-ADDRESS_MAP_START(interpro_state::c300_insn_map)
- AM_RANGE(0x00000000, 0xffffffff) AM_DEVREAD(INTERPRO_MMU_TAG "_i", cammu_device, read)
-ADDRESS_MAP_END
-
-ADDRESS_MAP_START(interpro_state::c300_data_map)
- AM_RANGE(0x00000000, 0xffffffff) AM_DEVREADWRITE(INTERPRO_MMU_TAG "_d", cammu_device, read, write)
-ADDRESS_MAP_END
-
-ADDRESS_MAP_START(interpro_state::c400_insn_map)
- AM_RANGE(0x00000000, 0xffffffff) AM_DEVREAD(INTERPRO_MMU_TAG, cammu_device, read)
-ADDRESS_MAP_END
-
-ADDRESS_MAP_START(interpro_state::c400_data_map)
- AM_RANGE(0x00000000, 0xffffffff) AM_DEVREADWRITE(INTERPRO_MMU_TAG, cammu_device, read, write)
-ADDRESS_MAP_END
-
ADDRESS_MAP_START(interpro_state::interpro_common_map)
// FIXME: don't know what this range is for
AM_RANGE(0x08000000, 0x08000fff) AM_NOP
@@ -343,7 +330,6 @@ ADDRESS_MAP_START(interpro_state::interpro_common_map)
AM_RANGE(0x4f007e00, 0x4f007eff) AM_DEVICE(INTERPRO_SGA_TAG, interpro_sga_device, map)
AM_RANGE(0x7f000100, 0x7f00011f) AM_DEVICE8(INTERPRO_FDC_TAG, upd765_family_device, map, 0x000000ff)
- AM_RANGE(0x7f000200, 0x7f0002ff) AM_DEVICE(INTERPRO_ARBGA_TAG, interpro_arbga_device, map)
AM_RANGE(0x7f000300, 0x7f000303) AM_READ16(sreg_error_r, 0x0000ffff)
AM_RANGE(0x7f000304, 0x7f000307) AM_READWRITE16(sreg_status_r, sreg_led_w, 0x0000ffff)
AM_RANGE(0x7f000308, 0x7f00030b) AM_READWRITE16(sreg_ctrl1_r, sreg_ctrl1_w, 0x0000ffff)
@@ -356,25 +342,10 @@ ADDRESS_MAP_START(interpro_state::interpro_common_map)
;map(0x7f000500, 0x7f000503).lrw8("rtc_rw", [this](address_space &space, offs_t offset, u8 mem_mask){ return m_rtc->read(space, offset^1, mem_mask); }, [this](address_space &space, offs_t offset, u8 data, u8 mem_mask){ m_rtc->write(space, offset^1, data, mem_mask); }).umask32(0x000000ff);
AM_RANGE(0x7f000600, 0x7f000603) AM_DEVWRITE8(INTERPRO_RTC_TAG, mc146818_device, write, 0x000000ff)
- AM_RANGE(0x7f000600, 0x7f00060f) AM_READ8(nodeid_r, 0xff)
// the system board id prom
AM_RANGE(0x7f000700, 0x7f00077f) AM_ROM AM_REGION(INTERPRO_IDPROM_TAG, 0)
- // scsi registers have unusual address mapping
- AM_RANGE(0x7f001000, 0x7f001003) AM_DEVREADWRITE8(INTERPRO_SCSI_DEVICE_TAG, ncr53c90a_device, tcounter_lo_r, tcount_lo_w, 0x0000ff00)
- AM_RANGE(0x7f001100, 0x7f001103) AM_DEVREADWRITE8(INTERPRO_SCSI_DEVICE_TAG, ncr53c90a_device, tcounter_hi_r, tcount_hi_w, 0x0000ff00)
- AM_RANGE(0x7f001200, 0x7f001203) AM_DEVREADWRITE8(INTERPRO_SCSI_DEVICE_TAG, ncr53c90a_device, fifo_r, fifo_w, 0x0000ff00)
- AM_RANGE(0x7f001300, 0x7f001303) AM_DEVREADWRITE8(INTERPRO_SCSI_DEVICE_TAG, ncr53c90a_device, command_r, command_w, 0x0000ff00)
- AM_RANGE(0x7f001400, 0x7f001403) AM_DEVREAD8(INTERPRO_SCSI_DEVICE_TAG, ncr53c90a_device, status_r, 0xff00) AM_DEVWRITE8(INTERPRO_SCSI_DEVICE_TAG, ncr53c90a_device, bus_id_w, 0x0000ff00)
- AM_RANGE(0x7f001500, 0x7f001503) AM_DEVREADWRITE8(INTERPRO_SCSI_DEVICE_TAG, ncr53c90a_device, istatus_r, timeout_w, 0x0000ff00)
- AM_RANGE(0x7f001600, 0x7f001603) AM_DEVREADWRITE8(INTERPRO_SCSI_DEVICE_TAG, ncr53c90a_device, seq_step_r, sync_period_w, 0x0000ff00)
- AM_RANGE(0x7f001700, 0x7f001703) AM_DEVREADWRITE8(INTERPRO_SCSI_DEVICE_TAG, ncr53c90a_device, fifo_flags_r, sync_offset_w, 0x0000ff00)
- AM_RANGE(0x7f001800, 0x7f001803) AM_DEVREADWRITE8(INTERPRO_SCSI_DEVICE_TAG, ncr53c90a_device, conf_r, conf_w, 0x0000ff00)
- AM_RANGE(0x7f001900, 0x7f001903) AM_DEVWRITE8(INTERPRO_SCSI_DEVICE_TAG, ncr53c90a_device, clock_w, 0x0000ff00)
- AM_RANGE(0x7f001a00, 0x7f001a03) AM_DEVWRITE8(INTERPRO_SCSI_DEVICE_TAG, ncr53c90a_device, test_w, 0x0000ff00)
- AM_RANGE(0x7f001b00, 0x7f001b03) AM_DEVREADWRITE8(INTERPRO_SCSI_DEVICE_TAG, ncr53c90a_device, conf2_r, conf2_w, 0x0000ff00)
-
AM_RANGE(0x7f0fff00, 0x7f0fffff) AM_DEVICE(INTERPRO_IOGA_TAG, interpro_ioga_device, map)
ADDRESS_MAP_END
@@ -382,7 +353,24 @@ ADDRESS_MAP_START(turquoise_state::turquoise_base_map)
AM_IMPORT_FROM(interpro_common_map)
AM_RANGE(0x40000000, 0x4000003f) AM_DEVICE(INTERPRO_MCGA_TAG, interpro_mcga_device, map)
+
+ // scsi registers have unusual address mapping
+ AM_RANGE(0x7f000200, 0x7f000203) AM_DEVREADWRITE8(INTERPRO_SCSI_DEVICE_TAG, ncr53c90a_device, tcounter_lo_r, tcount_lo_w, 0x0000ff00)
+ AM_RANGE(0x7f000204, 0x7f000207) AM_DEVREADWRITE8(INTERPRO_SCSI_DEVICE_TAG, ncr53c90a_device, tcounter_hi_r, tcount_hi_w, 0x0000ff00)
+ AM_RANGE(0x7f000208, 0x7f00020b) AM_DEVREADWRITE8(INTERPRO_SCSI_DEVICE_TAG, ncr53c90a_device, fifo_r, fifo_w, 0x0000ff00)
+ AM_RANGE(0x7f00020c, 0x7f00020f) AM_DEVREADWRITE8(INTERPRO_SCSI_DEVICE_TAG, ncr53c90a_device, command_r, command_w, 0x0000ff00)
+ AM_RANGE(0x7f000210, 0x7f000213) AM_DEVREADWRITE8(INTERPRO_SCSI_DEVICE_TAG, ncr53c90a_device, status_r, bus_id_w, 0x0000ff00)
+ AM_RANGE(0x7f000214, 0x7f000217) AM_DEVREADWRITE8(INTERPRO_SCSI_DEVICE_TAG, ncr53c90a_device, istatus_r, timeout_w, 0x0000ff00)
+ AM_RANGE(0x7f000218, 0x7f00021b) AM_DEVREADWRITE8(INTERPRO_SCSI_DEVICE_TAG, ncr53c90a_device, seq_step_r, sync_period_w, 0x0000ff00)
+ AM_RANGE(0x7f00021c, 0x7f00021f) AM_DEVREADWRITE8(INTERPRO_SCSI_DEVICE_TAG, ncr53c90a_device, fifo_flags_r, sync_offset_w, 0x0000ff00)
+ AM_RANGE(0x7f000220, 0x7f000223) AM_DEVREADWRITE8(INTERPRO_SCSI_DEVICE_TAG, ncr53c90a_device, conf_r, conf_w, 0x0000ff00)
+ AM_RANGE(0x7f000224, 0x7f000227) AM_DEVWRITE8(INTERPRO_SCSI_DEVICE_TAG, ncr53c90a_device, clock_w, 0x0000ff00)
+ AM_RANGE(0x7f000228, 0x7f00022b) AM_DEVWRITE8(INTERPRO_SCSI_DEVICE_TAG, ncr53c90a_device, test_w, 0x0000ff00)
+ AM_RANGE(0x7f00022c, 0x7f00022f) AM_DEVREADWRITE8(INTERPRO_SCSI_DEVICE_TAG, ncr53c90a_device, conf2_r, conf2_w, 0x0000ff00)
+
AM_RANGE(0x7f000300, 0x7f000303) AM_WRITE8(sreg_error_w, 0x000000ff)
+
+ AM_RANGE(0x7f000600, 0x7f00067f) AM_ROM AM_REGION(INTERPRO_NODEID_TAG, 0)
ADDRESS_MAP_END
ADDRESS_MAP_START(turquoise_state::turquoise_main_map)
@@ -396,6 +384,23 @@ ADDRESS_MAP_START(sapphire_state::sapphire_base_map)
AM_IMPORT_FROM(interpro_common_map)
AM_RANGE(0x40000000, 0x4000004f) AM_DEVICE(INTERPRO_MCGA_TAG, interpro_fmcc_device, map)
+ AM_RANGE(0x7f000200, 0x7f0002ff) AM_DEVICE(INTERPRO_ARBGA_TAG, interpro_arbga_device, map)
+
+ AM_RANGE(0x7f000600, 0x7f00060f) AM_READ8(nodeid_r, 0xff)
+
+ // scsi registers have unusual address mapping
+ AM_RANGE(0x7f001000, 0x7f001003) AM_DEVREADWRITE8(INTERPRO_SCSI_DEVICE_TAG, ncr53c94_device, tcounter_lo_r, tcount_lo_w, 0x0000ff00)
+ AM_RANGE(0x7f001100, 0x7f001103) AM_DEVREADWRITE8(INTERPRO_SCSI_DEVICE_TAG, ncr53c94_device, tcounter_hi_r, tcount_hi_w, 0x0000ff00)
+ AM_RANGE(0x7f001200, 0x7f001203) AM_DEVREADWRITE8(INTERPRO_SCSI_DEVICE_TAG, ncr53c94_device, fifo_r, fifo_w, 0x0000ff00)
+ AM_RANGE(0x7f001300, 0x7f001303) AM_DEVREADWRITE8(INTERPRO_SCSI_DEVICE_TAG, ncr53c94_device, command_r, command_w, 0x0000ff00)
+ AM_RANGE(0x7f001400, 0x7f001403) AM_DEVREADWRITE8(INTERPRO_SCSI_DEVICE_TAG, ncr53c94_device, status_r, bus_id_w, 0x0000ff00)
+ AM_RANGE(0x7f001500, 0x7f001503) AM_DEVREADWRITE8(INTERPRO_SCSI_DEVICE_TAG, ncr53c94_device, istatus_r, timeout_w, 0x0000ff00)
+ AM_RANGE(0x7f001600, 0x7f001603) AM_DEVREADWRITE8(INTERPRO_SCSI_DEVICE_TAG, ncr53c94_device, seq_step_r, sync_period_w, 0x0000ff00)
+ AM_RANGE(0x7f001700, 0x7f001703) AM_DEVREADWRITE8(INTERPRO_SCSI_DEVICE_TAG, ncr53c94_device, fifo_flags_r, sync_offset_w, 0x0000ff00)
+ AM_RANGE(0x7f001800, 0x7f001803) AM_DEVREADWRITE8(INTERPRO_SCSI_DEVICE_TAG, ncr53c94_device, conf_r, conf_w, 0x0000ff00)
+ AM_RANGE(0x7f001900, 0x7f001903) AM_DEVWRITE8(INTERPRO_SCSI_DEVICE_TAG, ncr53c94_device, clock_w, 0x0000ff00)
+ AM_RANGE(0x7f001a00, 0x7f001a03) AM_DEVWRITE8(INTERPRO_SCSI_DEVICE_TAG, ncr53c94_device, test_w, 0x0000ff00)
+ AM_RANGE(0x7f001b00, 0x7f001b03) AM_DEVREADWRITE8(INTERPRO_SCSI_DEVICE_TAG, ncr53c94_device, conf2_r, conf2_w, 0x0000ff00)
AM_RANGE(0x7f001c00, 0x7f001c03) AM_DEVWRITE8(INTERPRO_SCSI_DEVICE_TAG, ncr53c94_device, conf3_w, 0x0000ff00)
AM_RANGE(0x7f001f00, 0x7f001f03) AM_DEVWRITE8(INTERPRO_SCSI_DEVICE_TAG, ncr53c94_device, fifo_align_w, 0x0000ff00)
ADDRESS_MAP_END
@@ -448,9 +453,8 @@ static SLOT_INTERFACE_START(interpro_floppies)
SLOT_INTERFACE("35hd", FLOPPY_35_HD)
SLOT_INTERFACE_END
-MACHINE_CONFIG_START(interpro_state::interpro_serial1)
- MCFG_SCC85C30_ADD(INTERPRO_SCC1_TAG, XTAL(4'915'200), 0, 0, 0, 0)
-
+MACHINE_CONFIG_START(interpro_state::interpro_scc1)
+ MCFG_DEVICE_MODIFY(INTERPRO_SCC1_TAG)
MCFG_Z80SCC_OUT_TXDA_CB(DEVWRITELINE(INTERPRO_SERIAL_PORT1_TAG, rs232_port_device, write_txd))
MCFG_Z80SCC_OUT_TXDB_CB(DEVWRITELINE(INTERPRO_SERIAL_PORT2_TAG, rs232_port_device, write_txd))
MCFG_Z80SCC_OUT_INT_CB(DEVWRITELINE(INTERPRO_IOGA_TAG, interpro_ioga_device, ir11_w))
@@ -468,8 +472,8 @@ MACHINE_CONFIG_START(interpro_state::interpro_serial1)
MCFG_RS232_CTS_HANDLER(DEVWRITELINE(INTERPRO_SCC1_TAG, z80scc_device, ctsb_w))
MACHINE_CONFIG_END
-MACHINE_CONFIG_START(interpro_state::interpro_serial2)
- MCFG_SCC85C30_ADD(INTERPRO_SCC2_TAG, XTAL(4'915'200), 0, 0, 0, 0)
+MACHINE_CONFIG_START(interpro_state::interpro_scc2)
+ MCFG_DEVICE_MODIFY(INTERPRO_SCC2_TAG)
MCFG_Z80SCC_OUT_TXDA_CB(DEVWRITELINE(INTERPRO_KEYBOARD_PORT_TAG, interpro_keyboard_port_device, write_txd))
MCFG_Z80SCC_OUT_TXDB_CB(DEVWRITELINE(INTERPRO_SERIAL_PORT0_TAG, rs232_port_device, write_txd))
MCFG_Z80SCC_OUT_INT_CB(DEVWRITELINE(INTERPRO_IOGA_TAG, interpro_ioga_device, ir11_w))
@@ -542,9 +546,6 @@ MACHINE_CONFIG_START(interpro_state::interpro)
// floppy
- // srx arbiter gate array
- MCFG_DEVICE_ADD(INTERPRO_ARBGA_TAG, INTERPRO_ARBGA, 0)
-
// serial
// real-time clock/non-volatile memory
@@ -557,8 +558,8 @@ MACHINE_CONFIG_START(interpro_state::interpro)
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, "cdrom", false)
- MCFG_NSCSI_ADD(INTERPRO_SCSI_TAG ":4", 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_NSCSI_ADD(INTERPRO_SCSI_TAG ":5", interpro_scsi_devices, nullptr, false)
MCFG_NSCSI_ADD(INTERPRO_SCSI_TAG ":6", interpro_scsi_devices, nullptr, false)
@@ -568,32 +569,29 @@ MACHINE_CONFIG_START(interpro_state::interpro)
// sr bus and slots
MCFG_DEVICE_ADD(INTERPRO_SRBUS_TAG, SR, 0)
+ MCFG_SR_OUT_IRQ0_CB(DEVWRITELINE(INTERPRO_IOGA_TAG, interpro_ioga_device, ir6_w))
MCFG_SR_SLOT_ADD(INTERPRO_SRBUS_TAG, INTERPRO_SRBUS_TAG ":0", sr_cards, "mpcb963", false)
MCFG_SR_SLOT_ADD(INTERPRO_SRBUS_TAG, INTERPRO_SRBUS_TAG ":1", sr_cards, nullptr, false)
// system layout
MCFG_DEFAULT_LAYOUT(layout_interpro)
+
+ // software lists
+ MCFG_SOFTWARE_LIST_ADD("softlist", "interpro")
MACHINE_CONFIG_END
MACHINE_CONFIG_START(turquoise_state::turquoise)
interpro(config);
MCFG_CPU_ADD(INTERPRO_CPU_TAG, CLIPPER_C300, XTAL(12'500'000))
- MCFG_CPU_PROGRAM_MAP(c300_insn_map)
- MCFG_CPU_DATA_MAP(c300_data_map)
+ 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_CPU_IRQ_ACKNOWLEDGE_DEVICE(INTERPRO_IOGA_TAG, interpro_ioga_device, acknowledge_interrupt)
MCFG_DEVICE_ADD(INTERPRO_MMU_TAG "_i", CAMMU_C3, 0)
- 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_CAMMU_SSW_CB(DEVREAD32(INTERPRO_CPU_TAG, clipper_device, get_ssw))
MCFG_CAMMU_EXCEPTION_CB(DEVWRITE16(INTERPRO_CPU_TAG, clipper_device, set_exception))
MCFG_DEVICE_ADD(INTERPRO_MMU_TAG "_d", CAMMU_C3, 0)
- 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_CAMMU_SSW_CB(DEVREAD32(INTERPRO_CPU_TAG, clipper_device, get_ssw))
MCFG_CAMMU_EXCEPTION_CB(DEVWRITE16(INTERPRO_CPU_TAG, clipper_device, set_exception))
MCFG_CAMMU_LINK(INTERPRO_MMU_TAG "_i")
@@ -617,8 +615,10 @@ MACHINE_CONFIG_START(turquoise_state::turquoise)
MCFG_FLOPPY_DRIVE_SOUND(false)
// serial controllers and ports
- interpro_serial1(config);
- interpro_serial2(config);
+ MCFG_SCC85C30_ADD(INTERPRO_SCC1_TAG, XTAL(4'915'200), 0, 0, 0, 0)
+ interpro_scc1(config);
+ MCFG_SCC85C30_ADD(INTERPRO_SCC2_TAG, XTAL(4'915'200), 0, 0, 0, 0)
+ interpro_scc2(config);
// scsi controller
MCFG_NSCSI_ADD(INTERPRO_SCSI_TAG ":7", turquoise_scsi_devices, INTERPRO_SCSI_ADAPTER_TAG, true)
@@ -631,25 +631,23 @@ MACHINE_CONFIG_START(turquoise_state::turquoise)
// i/o gate array
MCFG_DEVICE_ADD(INTERPRO_IOGA_TAG, TURQUOISE_IOGA, 0)
- MCFG_INTERPRO_IOGA_MEMORY(INTERPRO_MMU_TAG "_d", 0)
+ MCFG_INTERPRO_IOGA_MEMORY(INTERPRO_CPU_TAG, 0)
ioga(config);
MCFG_DEVICE_MODIFY(INTERPRO_SRBUS_TAG)
- MCFG_SR_MEMORY(INTERPRO_MMU_TAG "_d", 0, 1)
+ MCFG_SR_MEMORY(INTERPRO_CPU_TAG, 0, 1)
MACHINE_CONFIG_END
MACHINE_CONFIG_START(sapphire_state::sapphire)
interpro(config);
MCFG_CPU_ADD(INTERPRO_CPU_TAG, CLIPPER_C400, XTAL(12'500'000))
- MCFG_CPU_PROGRAM_MAP(c400_insn_map)
- MCFG_CPU_DATA_MAP(c400_data_map)
- MCFG_CPU_IRQ_ACKNOWLEDGE_DEVICE(INTERPRO_IOGA_TAG, interpro_ioga_device, acknowledge_interrupt)
-
- MCFG_DEVICE_ADD(INTERPRO_MMU_TAG, CAMMU_C4T, 0)
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_CAMMU_SSW_CB(DEVREAD32(INTERPRO_CPU_TAG, clipper_device, get_ssw))
+ MCFG_CPU_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(DEVWRITE16(INTERPRO_CPU_TAG, clipper_device, set_exception))
// memory control gate array
@@ -665,22 +663,27 @@ MACHINE_CONFIG_START(sapphire_state::sapphire)
MCFG_FLOPPY_DRIVE_ADD("fdc: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)
+
// serial controllers and ports
- interpro_serial1(config);
- interpro_serial2(config);
+ MCFG_SCC85230_ADD(INTERPRO_SCC1_TAG, XTAL(4'915'200), 0, 0, 0, 0)
+ interpro_scc1(config);
+ MCFG_SCC85C30_ADD(INTERPRO_SCC2_TAG, XTAL(4'915'200), 0, 0, 0, 0)
+ interpro_scc2(config);
// scsi controller
MCFG_NSCSI_ADD(INTERPRO_SCSI_TAG ":7", sapphire_scsi_devices, INTERPRO_SCSI_ADAPTER_TAG, true)
MCFG_DEVICE_CARD_MACHINE_CONFIG(INTERPRO_SCSI_ADAPTER_TAG, interpro_scsi_adapter)
// ethernet controller
- MCFG_DEVICE_ADD(INTERPRO_ETH_TAG, I82596_LE32, XTAL(20'000'000))
+ MCFG_DEVICE_ADD(INTERPRO_ETH_TAG, I82596_LE16, XTAL(20'000'000))
MCFG_I82586_IRQ_CB(DEVWRITELINE(INTERPRO_IOGA_TAG, 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_INTERPRO_IOGA_MEMORY(INTERPRO_MMU_TAG, 0)
+ MCFG_INTERPRO_IOGA_MEMORY(INTERPRO_CPU_TAG, 0)
ioga(config);
// flash memory
@@ -689,42 +692,72 @@ MACHINE_CONFIG_START(sapphire_state::sapphire)
// sr bus address spaces
MCFG_DEVICE_MODIFY(INTERPRO_SRBUS_TAG)
- MCFG_SR_MEMORY(INTERPRO_MMU_TAG, 0, 1)
+ MCFG_SR_MEMORY(INTERPRO_CPU_TAG, 0, 1)
MACHINE_CONFIG_END
MACHINE_CONFIG_START(turquoise_state::ip2000)
turquoise(config);
//MCFG_DEVICE_MODIFY(INTERPRO_CPU_TAG)
//MCFG_DEVICE_CLOCK(XTAL(40'000'000))
+
+ MCFG_SOFTWARE_LIST_FILTER("softlist", "2000")
MACHINE_CONFIG_END
MACHINE_CONFIG_START(sapphire_state::ip2400)
sapphire(config);
//MCFG_DEVICE_MODIFY(INTERPRO_CPU_TAG)
- //MCFG_DEVICE_CLOCK(XTAL(40'000'000))
+ //MCFG_DEVICE_CLOCK(XTAL(50'000'000))
+
+ MCFG_DEVICE_MODIFY(INTERPRO_MMU_TAG)
+ MCFG_CAMMU_ID(cammu_c4i_device::CID_C4IR0)
+
+ MCFG_DEVICE_MODIFY(INTERPRO_SRBUS_TAG ":0")
+ MCFG_SLOT_DEFAULT_OPTION("mpcb070")
+
+ MCFG_SOFTWARE_LIST_FILTER("softlist", "2400")
MACHINE_CONFIG_END
MACHINE_CONFIG_START(sapphire_state::ip2500)
sapphire(config);
//MCFG_DEVICE_MODIFY(INTERPRO_CPU_TAG)
- //MCFG_DEVICE_CLOCK(XTAL(50'000'000))
+ //MCFG_DEVICE_CLOCK(XTAL(?)
+
+ // FIXME: don't know which cammu revision
+ MCFG_DEVICE_MODIFY(INTERPRO_MMU_TAG)
+ MCFG_CAMMU_ID(cammu_c4i_device::CID_C4IR0)
+
+ MCFG_SOFTWARE_LIST_FILTER("softlist", "2500")
MACHINE_CONFIG_END
MACHINE_CONFIG_START(sapphire_state::ip2700)
sapphire(config);
//MCFG_DEVICE_MODIFY(INTERPRO_CPU_TAG)
- //MCFG_DEVICE_CLOCK(XTAL_70MHz)
+ //MCFG_DEVICE_CLOCK(?)
+
+ MCFG_DEVICE_MODIFY(INTERPRO_MMU_TAG)
+ MCFG_CAMMU_ID(cammu_c4i_device::CID_C4IR2)
+
+ MCFG_SOFTWARE_LIST_FILTER("softlist", "2700")
MACHINE_CONFIG_END
MACHINE_CONFIG_START(sapphire_state::ip2800)
sapphire(config);
//MCFG_DEVICE_MODIFY(INTERPRO_CPU_TAG)
- //MCFG_DEVICE_CLOCK(XTAL_80MHz)
+ //MCFG_DEVICE_CLOCK(?)
+
+ // FIXME: don't know which cammu revision
+ MCFG_DEVICE_MODIFY(INTERPRO_MMU_TAG)
+ MCFG_CAMMU_ID(cammu_c4i_device::CID_C4IR2)
+
+ MCFG_SOFTWARE_LIST_FILTER("softlist", "2800")
MACHINE_CONFIG_END
ROM_START(ip2000)
+ ROM_REGION(0x80, INTERPRO_NODEID_TAG, 0)
+ ROM_LOAD32_BYTE("nodeid.bin", 0x0, 0x20, CRC(a38397a6) SHA1(9f45fb932bbe231c95b3d5470dcd1fa1c846486f))
+
ROM_REGION(0x80, INTERPRO_IDPROM_TAG, 0)
- ROM_LOAD32_BYTE("mpcb962a.bin", 0x0, 0x20, CRC(712f5ba9) SHA1(93ccdcb68be4038bb35b02cee612927ad4451190))
+ ROM_LOAD32_BYTE("mpcb962a.bin", 0x0, 0x20, CRC(e391342c) SHA1(02e03aad760b6651b8599c3a41c7c457983ee97d))
ROM_REGION(0x0040000, INTERPRO_EPROM_TAG, 0)
ROM_SYSTEM_BIOS(0, "ip2000", "InterPro 2000 EPROM")
@@ -734,7 +767,7 @@ ROM_END
ROM_START(ip2400)
ROM_REGION(0x80, INTERPRO_IDPROM_TAG, 0)
- ROM_LOAD32_BYTE("msmt047a.bin", 0x0, 0x20, CRC(3078d84d) SHA1(2876b8b8054bb7528680d259fea428db6f1712b4))
+ ROM_LOAD32_BYTE("msmt0470.bin", 0x0, 0x20, CRC(498c80df) SHA1(18a49732ac9d04b20a77747c1b946c2e88abb087))
ROM_REGION(0x0020000, INTERPRO_EPROM_TAG, 0)
ROM_SYSTEM_BIOS(0, "ip2400", "InterPro 2400 EPROM")
@@ -749,7 +782,7 @@ ROM_END
ROM_START(ip2500)
ROM_REGION(0x80, INTERPRO_IDPROM_TAG, 0)
- ROM_LOAD32_BYTE("msmt100a.bin", 0x0, 0x20, CRC(46647cdf) SHA1(581a3424a9b7028e619a7f03fa86ebdee3cf2494))
+ ROM_LOAD32_BYTE("msmt1000.bin", 0x0, 0x20, CRC(548046c0) SHA1(ce7646e868f3aa35642d7f9348f6b9e91693918e))
ROM_REGION(0x0020000, INTERPRO_EPROM_TAG, 0)
ROM_SYSTEM_BIOS(0, "ip2500", "InterPro 2500 EPROM")
@@ -764,7 +797,7 @@ ROM_END
ROM_START(ip2700)
ROM_REGION(0x80, INTERPRO_IDPROM_TAG, 0)
- ROM_LOAD32_BYTE("msmt128a.bin", 0x0, 0x20, CRC(6d8e68e8) SHA1(a649097df730c79b03bbf777b788f0721e072f03))
+ ROM_LOAD32_BYTE("msmt1280.bin", 0x0, 0x20, CRC(32d833af) SHA1(7225c5f5670fe49d86556a2cb453ae6fe09e3e19))
ROM_REGION(0x0020000, INTERPRO_EPROM_TAG, 0)
ROM_SYSTEM_BIOS(0, "ip2700", "InterPro 2700 EPROM")
@@ -779,7 +812,7 @@ ROM_END
ROM_START(ip2800)
ROM_REGION(0x80, INTERPRO_IDPROM_TAG, 0)
- ROM_LOAD32_BYTE("msmt145a.bin", 0x0, 0x20, CRC(e1c265e3) SHA1(105d646552d56c7af2f403aac1aa97b047b6a50e))
+ ROM_LOAD32_BYTE("msmt1450.bin", 0x0, 0x20, CRC(61c7a305) SHA1(efcd045cbdfda8df44eaad761b0ba99367973cd7))
ROM_REGION(0x0020000, INTERPRO_EPROM_TAG, 0)
ROM_SYSTEM_BIOS(0, "ip2800", "InterPro 2800 EPROM")
@@ -793,8 +826,8 @@ ROM_START(ip2800)
ROM_END
/* YEAR NAME PARENT COMPAT MACHINE INPUT CLASS INIT COMPANY FULLNAME FLAGS */
-COMP( 1989, ip2000, 0, 0, ip2000, interpro, turquoise_state, turquoise, "Intergraph", "InterPro 2000", MACHINE_NOT_WORKING | MACHINE_NO_SOUND)
-COMP( 1991?, ip2400, 0, 0, ip2400, interpro, sapphire_state, sapphire, "Intergraph", "InterPro 2400", MACHINE_NOT_WORKING | MACHINE_NO_SOUND)
-COMP( 1993?, ip2500, 0, 0, ip2500, interpro, sapphire_state, sapphire, "Intergraph", "InterPro 2500", MACHINE_NOT_WORKING | MACHINE_NO_SOUND)
-COMP( 1992, ip2700, 0, 0, ip2700, interpro, sapphire_state, sapphire, "Intergraph", "InterPro 2700", MACHINE_NOT_WORKING | MACHINE_NO_SOUND)
-COMP( 1994, ip2800, 0, 0, ip2800, interpro, sapphire_state, sapphire, "Intergraph", "InterPro 2800", MACHINE_NOT_WORKING | MACHINE_NO_SOUND)
+COMP( 1990, ip2000, 0, 0, ip2000, interpro, turquoise_state, common, "Intergraph", "InterPro 2000", MACHINE_NOT_WORKING | MACHINE_NO_SOUND)
+COMP( 1992, ip2400, 0, 0, ip2400, interpro, sapphire_state, common, "Intergraph", "InterPro 2400", MACHINE_NOT_WORKING | MACHINE_NO_SOUND)
+COMP( 1993, ip2500, 0, 0, ip2500, interpro, sapphire_state, common, "Intergraph", "InterPro 2500", MACHINE_NOT_WORKING | MACHINE_NO_SOUND)
+COMP( 1993, ip2700, 0, 0, ip2700, interpro, sapphire_state, common, "Intergraph", "InterPro 2700", MACHINE_NOT_WORKING | MACHINE_NO_SOUND)
+COMP( 1994, ip2800, 0, 0, ip2800, interpro, sapphire_state, common, "Intergraph", "InterPro 2800", MACHINE_NOT_WORKING | MACHINE_NO_SOUND)
diff --git a/src/mame/includes/interpro.h b/src/mame/includes/interpro.h
index c340ff99f28..676affa2fb2 100644
--- a/src/mame/includes/interpro.h
+++ b/src/mame/includes/interpro.h
@@ -33,9 +33,10 @@
#include "bus/interpro/keyboard/keyboard.h"
#include "formats/pc_dsk.h"
+#include "softlist.h"
#define INTERPRO_CPU_TAG "cpu"
-#define INTERPRO_MMU_TAG "mmu"
+#define INTERPRO_MMU_TAG "cammu"
#define INTERPRO_MCGA_TAG "mcga"
#define INTERPRO_SGA_TAG "sga"
#define INTERPRO_FDC_TAG "fdc"
@@ -53,6 +54,7 @@
#define INTERPRO_ETH_TAG "eth"
#define INTERPRO_IOGA_TAG "ioga"
+#define INTERPRO_NODEID_TAG "nodeid"
#define INTERPRO_IDPROM_TAG "idprom"
#define INTERPRO_EPROM_TAG "eprom"
#define INTERPRO_FLASH_TAG "flash"
@@ -69,12 +71,10 @@ public:
, m_mcga(*this, INTERPRO_MCGA_TAG)
, m_sga(*this, INTERPRO_SGA_TAG)
, m_fdc(*this, INTERPRO_FDC_TAG)
- , m_arbga(*this, INTERPRO_ARBGA_TAG)
, m_scc1(*this, INTERPRO_SCC1_TAG)
, m_scc2(*this, INTERPRO_SCC2_TAG)
, m_rtc(*this, INTERPRO_RTC_TAG)
, m_scsibus(*this, INTERPRO_SCSI_TAG)
- , m_scsi(*this, INTERPRO_SCSI_DEVICE_TAG)
, m_eth(*this, INTERPRO_ETH_TAG)
, m_ioga(*this, INTERPRO_IOGA_TAG)
{
@@ -86,12 +86,10 @@ public:
required_device m_mcga;
required_device m_sga;
required_device m_fdc;
- required_device m_arbga;
required_device m_scc1;
required_device m_scc2;
required_device m_rtc;
required_device m_scsibus;
- required_device m_scsi;
required_device m_eth;
required_device m_ioga;
@@ -156,22 +154,16 @@ public:
DECLARE_READ8_MEMBER(nodeid_r);
- DECLARE_READ32_MEMBER(unmapped_r);
- DECLARE_WRITE32_MEMBER(unmapped_w);
-
DECLARE_FLOPPY_FORMATS(floppy_formats);
void ioga(machine_config &config);
- void interpro_serial1(machine_config &config);
- void interpro_serial2(machine_config &config);
+ void interpro_scc1(machine_config &config);
+ void interpro_scc2(machine_config &config);
void interpro(machine_config &config);
static void interpro_scsi_adapter(device_t *device);
- void c300_data_map(address_map &map);
- void c300_insn_map(address_map &map);
- void c400_data_map(address_map &map);
- void c400_insn_map(address_map &map);
void interpro_boot_map(address_map &map);
void interpro_common_map(address_map &map);
+
protected:
virtual void machine_start() override;
virtual void machine_reset() override;
@@ -192,15 +184,16 @@ public:
: interpro_state(mconfig, type, tag)
, m_d_cammu(*this, INTERPRO_MMU_TAG "_d")
, m_i_cammu(*this, INTERPRO_MMU_TAG "_i")
+ , m_scsi(*this, INTERPRO_SCSI_DEVICE_TAG)
{
}
- DECLARE_DRIVER_INIT(turquoise);
-
DECLARE_WRITE8_MEMBER(sreg_error_w) { m_sreg_error = data; }
required_device m_d_cammu;
required_device m_i_cammu;
+ required_device m_scsi;
+
void turquoise(machine_config &config);
void ip2000(machine_config &config);
void interpro_82586_map(address_map &map);
@@ -215,19 +208,23 @@ public:
sapphire_state(const machine_config &mconfig, device_type type, const char *tag)
: interpro_state(mconfig, type, tag)
, 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")
{
}
- DECLARE_DRIVER_INIT(sapphire);
-
virtual DECLARE_WRITE16_MEMBER(sreg_ctrl2_w) override;
+ DECLARE_READ32_MEMBER(unmapped_r);
+ DECLARE_WRITE32_MEMBER(unmapped_w);
required_device m_mmu;
-
+ required_device m_scsi;
+ required_device m_arbga;
required_device m_flash_lo;
required_device m_flash_hi;
+
void sapphire(machine_config &config);
void ip2500(machine_config &config);
void ip2400(machine_config &config);
diff --git a/src/mame/machine/cammu.cpp b/src/mame/machine/cammu.cpp
index 11dafe2bfbc..99f783f4128 100644
--- a/src/mame/machine/cammu.cpp
+++ b/src/mame/machine/cammu.cpp
@@ -23,7 +23,6 @@
*
* TODO
* - fault register values
- * - alignment faults
* - c3 protection faults
* - hard-wired and dynamic tlb
* - cache
@@ -112,18 +111,17 @@ DEFINE_DEVICE_TYPE(CAMMU_C4I, cammu_c4i_device, "c4i", "C4I CAMMU")
DEFINE_DEVICE_TYPE(CAMMU_C3, cammu_c3_device, "c3", "C1/C3 CAMMU")
cammu_c4t_device::cammu_c4t_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : cammu_c4_device(mconfig, CAMMU_C4T, tag, owner, clock, CID_C4T)
+ : cammu_c4_device(mconfig, CAMMU_C4T, tag, owner, clock)
{
}
cammu_c4i_device::cammu_c4i_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : cammu_c4_device(mconfig, CAMMU_C4I, tag, owner, clock, CID_C4I)
+ : cammu_c4_device(mconfig, CAMMU_C4I, tag, owner, clock)
{
}
-cammu_c4_device::cammu_c4_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock, u32 cammu_id)
+cammu_c4_device::cammu_c4_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
: cammu_device(mconfig, type, tag, owner, clock)
- , m_control(cammu_id)
{
}
@@ -136,42 +134,13 @@ cammu_c3_device::cammu_c3_device(const machine_config &mconfig, const char *tag,
cammu_device::cammu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
: device_t(mconfig, type, tag, owner, clock)
- , device_memory_interface(mconfig, *this)
- , m_main_space_config("main", ENDIANNESS_LITTLE, 32, 32, 0)
- , m_io_space_config("io", ENDIANNESS_LITTLE, 32, 32, 0)
- , m_boot_space_config("boot", ENDIANNESS_LITTLE, 32, 32, 0)
- , m_main_space(nullptr)
- , m_io_space(nullptr)
- , m_boot_space(nullptr)
- , m_ssw_func(*this)
, m_exception_func(*this)
{
}
-device_memory_interface::space_config_vector cammu_device::memory_space_config() const
-{
- return space_config_vector {
- std::make_pair(0, &m_main_space_config),
- std::make_pair(1, &m_io_space_config),
- std::make_pair(2, &m_boot_space_config)
- };
-}
-
-void cammu_c3_device::static_add_linked(device_t &device, const char *const tag)
-{
- cammu_c3_device &parent = downcast(device);
-
- parent.m_linked.push_back(downcast(parent.siblingdevice(tag)));
-}
-
void cammu_device::device_start()
{
- m_ssw_func.resolve();
m_exception_func.resolve();
-
- m_main_space = &space(0);
- m_io_space = &space(1);
- m_boot_space = &space(2);
}
void cammu_device::device_reset()
@@ -246,238 +215,168 @@ void cammu_c3_device::device_reset()
m_reset = 0;
}
-READ32_MEMBER(cammu_device::read)
+void cammu_device::set_spaces(std::vector spaces)
{
- const u32 virtual_address = (offset << 2) | (
- (mem_mask & 0x00ffffff) == 0 ? 0x3 :
- (mem_mask & 0x0000ffff) == 0 ? 0x2 :
- (mem_mask & 0x000000ff) == 0 ? 0x1 : 0x0);
- offs_t physical_address;
+ assert_always(spaces.size() == 8, "exactly 8 address space pointers are required");
- LOGMASKED(LOG_ACCESS, "%s read address 0x%08x mem_mask 0x%08x (%s)\n",
- space.name(), virtual_address, mem_mask, machine().describe_context());
-
- address_space *physical_space = translate_address(virtual_address, space.spacenum() == AS_PROGRAM ? ACCESS_X : ACCESS_R, &physical_address);
-
- if (physical_space != nullptr)
- return physical_space->read_dword(physical_address, mem_mask);
- else
- return space.unmap();
+ for (int i = 0; i < spaces.size(); i++)
+ m_space[i] = spaces[i];
}
-WRITE32_MEMBER(cammu_device::write)
+cammu_device::translated_t cammu_device::translate_address(const u32 ssw, const u32 virtual_address, const access_size size, const access_type mode)
{
- const u32 virtual_address = (offset << 2) | (
- (mem_mask & 0x00ffffff) == 0 ? 0x3 :
- (mem_mask & 0x0000ffff) == 0 ? 0x2 :
- (mem_mask & 0x000000ff) == 0 ? 0x1 : 0x0);
- offs_t physical_address;
+ // get effective user/supervisor mode
+ const bool user = mode == EXECUTE ? ssw & SSW_U : ssw & (SSW_U | SSW_UU);
- LOGMASKED(LOG_ACCESS, "%s write address 0x%08x data 0x%08x mem_mask 0x%08x (%s)\n",
- space.name(), virtual_address, data, mem_mask, machine().describe_context());
+ // check for alignment faults
+ if (get_alignment() && !machine().side_effects_disabled())
+ {
+ 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);
- address_space *physical_space = translate_address(virtual_address, ACCESS_W, &physical_address);
-
- if (physical_space != nullptr)
- physical_space->write_dword(physical_address, data, mem_mask);
-}
-
-address_space *cammu_device::translate_address(const offs_t virtual_address, const access_t mode, offs_t *physical_address)
-{
- // get ssw and user/supervisor mode
- const u32 ssw = m_ssw_func();
- const bool user = mode == ACCESS_X ? ssw & SSW_U : ssw & (SSW_U | SSW_UU);
-
- // TODO: check for alignment faults
+ return { nullptr, 0 };
+ }
+ }
// in supervisor mode, the first 8 pages are always mapped via the hard-wired tlb
if (!user && (virtual_address & ~0x7fff) == 0)
{
switch (virtual_address & 0x7000)
{
- case 0x0000:
- case 0x1000:
- case 0x2000:
- case 0x3000:
// pages 0-3: main space pages 0-3
- *physical_address = virtual_address & 0x3fff;
- return m_main_space;
+ case 0x0000: return { m_space[ST1], virtual_address & 0x3fff };
+ case 0x1000: return { m_space[ST2], virtual_address & 0x3fff };
+ case 0x2000: return { m_space[ST3], virtual_address & 0x3fff };
+ case 0x3000: return { m_space[ST3], virtual_address & 0x3fff };
- case 0x4000:
- case 0x5000:
// pages 4-5: i/o space pages 0-1
- *physical_address = virtual_address & 0x1fff;
- return m_io_space;
+ case 0x4000: return { m_space[ST4], virtual_address & 0x1fff };
+ case 0x5000: return { m_space[ST4], virtual_address & 0x1fff };
- case 0x6000:
- case 0x7000:
// pages 6-7: boot space pages 0-1
- *physical_address = virtual_address & 0x1fff;
- return m_boot_space;
+ case 0x6000: return { m_space[ST5], virtual_address & 0x1fff };
+ case 0x7000: return { m_space[ST5], virtual_address & 0x1fff };
}
}
// if not in mapped mode, use unmapped system tag
if ((ssw & SSW_M) == 0)
- {
- *physical_address = virtual_address;
-
- return get_ust_space();
- }
+ return { m_space[get_ust_space()], virtual_address };
// get the page table entry
- const u32 pte = get_pte(virtual_address, user);
+ pte_t pte = get_pte(virtual_address, user);
// check for page faults
- if (pte & PTE_F)
+ if (pte.entry & PTE_F)
{
if (!machine().side_effects_disabled())
{
LOG("%s page fault address 0x%08x ssw 0x%08x pte 0x%08x (%s)\n",
- mode == ACCESS_X ? "instruction" : "data",
- virtual_address, ssw, pte, machine().describe_context());
+ mode == EXECUTE ? "instruction" : "data",
+ virtual_address, ssw, pte.entry, machine().describe_context());
set_fault_address(virtual_address);
- m_exception_func(mode == ACCESS_X ? EXCEPTION_I_PAGE_FAULT : EXCEPTION_D_PAGE_FAULT);
+ m_exception_func(mode == EXECUTE ? EXCEPTION_I_PAGE_FAULT : EXCEPTION_D_PAGE_FAULT);
}
- return nullptr;
+ return { nullptr, 0 };
}
// check for protection level faults
- if (!machine().side_effects_disabled() && !get_access(mode, pte, ssw))
+ if (!machine().side_effects_disabled() && !get_access(mode, pte.entry, ssw))
{
LOG("%s protection fault address 0x%08x ssw 0x%08x pte 0x%08x (%s)\n",
- mode == ACCESS_X ? "execute" : mode == ACCESS_R ? "read" : "write",
- virtual_address, ssw, pte, machine().describe_context());
+ mode == EXECUTE ? "execute" : mode == READ ? "read" : "write",
+ virtual_address, ssw, pte.entry, machine().describe_context());
set_fault_address(virtual_address);
m_exception_func(
- mode == ACCESS_X ? EXCEPTION_I_EXECUTE_PROTECT_FAULT :
- mode == ACCESS_R ? EXCEPTION_D_READ_PROTECT_FAULT :
+ mode == EXECUTE ? EXCEPTION_I_EXECUTE_PROTECT_FAULT :
+ mode == READ ? EXCEPTION_D_READ_PROTECT_FAULT :
EXCEPTION_D_WRITE_PROTECT_FAULT);
- return nullptr;
+ return { nullptr, 0 };
}
+ // set pte referenced and dirty flags
+ 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);
+
// translate the address
- *physical_address = (pte & ~CAMMU_PAGE_MASK) | (virtual_address & CAMMU_PAGE_MASK);
- LOGMASKED(LOG_DTU, "%s address translated 0x%08x\n", mode == ACCESS_X ? "instruction" : "data", *physical_address);
+ LOGMASKED(LOG_DTU, "%s address translated 0x%08x\n", mode == EXECUTE ? "instruction" : "data",
+ (pte.entry & ~CAMMU_PAGE_MASK) | (virtual_address & CAMMU_PAGE_MASK));
- // return the physical space based on the system tag
- switch (pte & PTE_ST)
- {
- case ST_0:
- case ST_1:
- case ST_2:
- case ST_3:
- // main memory space
- return m_main_space;
-
- case ST_4:
- // i/o space
- return m_io_space;
-
- case ST_5:
- // boot space
- return m_boot_space;
-
- case ST_6:
- // cache purge
- case ST_7:
- // main memory, slave mode
- if (!machine().side_effects_disabled())
- fatalerror("%s page table entry system tag %d not supported\n",
- mode == ACCESS_X ? "instruction" : "data", (pte & PTE_ST) >> 9);
- break;
- }
-
- return nullptr;
+ // return the system tag and translated address
+ return { m_space[system_tag_t((pte.entry & PTE_ST) >> PTE_ST_SHIFT)], (pte.entry & ~CAMMU_PAGE_MASK) | (virtual_address & CAMMU_PAGE_MASK) };
}
// return the page table entry for a given virtual address
-u32 cammu_device::get_pte(const u32 va, const bool user)
+cammu_device::pte_t cammu_device::get_pte(const u32 va, const bool user)
{
- const u32 tlb_index = user ? 1 : 0;
- if ((va & ~CAMMU_PAGE_MASK) != m_tlb[tlb_index].va)
- {
- // get page table directory origin from user or supervisor pdo register
- const u32 pdo = get_pdo(user);
+ // get page table directory origin from user or supervisor pdo register
+ const u32 pdo = get_pdo(user);
- // get page table directory index from top 12 bits of virtual address
- const u32 ptdi = (va & VA_PTDI) >> 20;
+ // get page table directory index from top 12 bits of virtual address
+ const u32 ptdi = (va & VA_PTDI) >> 20;
- // fetch page table directory entry
- const u32 ptde = m_main_space->read_dword(pdo | ptdi);
+ // fetch page table directory entry
+ const u32 ptde = m_space[ST0]->read_dword(pdo | ptdi);
- LOGMASKED(LOG_DTU, "get_pte pdo 0x%08x ptdi 0x%08x ptde 0x%08x\n", pdo, ptdi, ptde);
+ LOGMASKED(LOG_DTU, "get_pte pdo 0x%08x ptdi 0x%08x ptde 0x%08x\n", pdo, ptdi, ptde);
- // check for page table directory entry fault
- if (ptde & PTDE_F)
- return PTE_F;
+ // check for page table directory entry fault
+ if (ptde & PTDE_F)
+ return { PTE_F, pdo | ptdi };
- // get the page table origin from the page table directory entry
- const u32 pto = ptde & PTDE_PTO;
+ // get the page table origin from the page table directory entry
+ const u32 pto = ptde & PTDE_PTO;
- // get the page table index from the middle 12 bits of the virtual address
- const u32 pti = (va & VA_PTI) >> 10;
+ // get the page table index from the middle 12 bits of the virtual address
+ const u32 pti = (va & VA_PTI) >> 10;
- // fetch page table entry
- const u32 pte = m_main_space->read_dword(pto | pti);
+ // fetch page table entry
+ pte_t pte = { m_space[ST0]->read_dword(pto | pti), pto | pti };
- LOGMASKED(LOG_DTU, "get_pte pto 0x%08x pti 0x%08x pte 0x%08x\n", pto, pti, pte);
+ LOGMASKED(LOG_DTU, "get_pte pto 0x%08x pti 0x%08x pte 0x%08x\n", pto, pti, pte.entry);
- // check for page table entry fault
- if (pte & PTE_F)
- return PTE_F;
+ // check for page table entry fault
+ if (!(pte.entry & PTE_F))
+ LOGMASKED(LOG_DTU, "get_pte address 0x%08x pte 0x%08x (%s)\n", va, pte.entry, machine().describe_context());
- // add the pte to the tlb
- m_tlb[tlb_index].va = va & ~CAMMU_PAGE_MASK;
- m_tlb[tlb_index].pte = pte;
-
- LOGMASKED(LOG_DTU, "get_pte address 0x%08x pte 0x%08x (%s)\n", va, pte, machine().describe_context());
- }
-
- return m_tlb[tlb_index].pte;
+ return pte;
}
-address_space *cammu_c4i_device::get_ust_space() const
-{
- switch (m_control & CNTL_UMM)
- {
- case UMM_MM: return m_main_space;
- case UMM_MMRIO: return m_main_space; // FIXME: what determines main or i/o?
- case UMM_IO: return m_io_space;
- }
-
- return m_main_space;
-}
-
-bool cammu_c4_device::get_access(const access_t mode, const u32 pte, const u32 ssw) const
+bool cammu_c4_device::get_access(const access_type mode, const u32 pte, const u32 ssw) const
{
switch (mode)
{
- case ACCESS_R: return pte & 0x20;
- case ACCESS_W: return pte & 0x10;
- case ACCESS_X: return pte & 0x08;
+ case READ: return pte & 0x20;
+ case WRITE: return pte & 0x10;
+ case RMW: return (pte & 0x30) == 0x30;
+ case EXECUTE: return pte & 0x08;
}
return false;
}
-bool cammu_c3_device::get_access(const access_t mode, const u32 pte, const u32 ssw) const
+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 == ACCESS_X ? i_cammu_column : d_cammu_column)[(ssw & SSW_PL) >> 9];
+ 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 ACCESS_R: return access & R;
- case ACCESS_W: return access & W;
- case ACCESS_X: return access & E;
+ 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;
@@ -494,5 +393,3 @@ const cammu_c3_device::c3_access_t cammu_c3_device::cammu_matrix[][16] =
{ N, N, RW, RW, RW, R, R, RWE, N, N, RE, RE, N, RE, N, N },
{ N, N, N, RW, R, R, R, RWE, N, N, N, RE, RE, N, RE, N }
};
-
-
diff --git a/src/mame/machine/cammu.h b/src/mame/machine/cammu.h
index cb38c433aae..a8f6a1d9330 100644
--- a/src/mame/machine/cammu.h
+++ b/src/mame/machine/cammu.h
@@ -6,53 +6,25 @@
#pragma once
-#define MCFG_CAMMU_SSW_CB(_sswcb) \
- devcb = &downcast(*device).set_ssw_callback(DEVCB_##_sswcb);
+#include "cpu/clipper/common.h"
+
+#define MCFG_CAMMU_ID(_id) \
+ downcast(*device).set_cammu_id(_id);
#define MCFG_CAMMU_EXCEPTION_CB(_exceptioncb) \
devcb = &downcast(*device).set_exception_callback(DEVCB_##_exceptioncb);
#define MCFG_CAMMU_LINK(_tag) \
- cammu_c3_device::static_add_linked(*device, _tag);
+ downcast(*device).add_linked(_tag);
-class cammu_device : public device_t, public device_memory_interface
+class cammu_device : public device_t
{
public:
- template devcb_base &set_ssw_callback(Object &&cb) { return m_ssw_func.set_callback(std::forward