summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/cpu/8x300/8x300.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/cpu/8x300/8x300.cpp')
-rw-r--r--src/devices/cpu/8x300/8x300.cpp330
1 files changed, 153 insertions, 177 deletions
diff --git a/src/devices/cpu/8x300/8x300.cpp b/src/devices/cpu/8x300/8x300.cpp
index 130df2dd7e3..a8a9b9dcdad 100644
--- a/src/devices/cpu/8x300/8x300.cpp
+++ b/src/devices/cpu/8x300/8x300.cpp
@@ -34,17 +34,29 @@
// for XEC intruction, which sets the AR, but not PC, so that after the instruction at the relative address is done, execution
// returns back to next instruction after XEC, unless a JMP or successful NZT is there.
#define SET_AR(x) do { m_AR = (x); m_increment_pc = false; } while (0)
-#define SRC_LATCH do { if(SRC_IS_RIGHT_BANK) m_right_IV = READPORT(m_IVR+0x100); else m_left_IV = READPORT(m_IVL); } while (0)
-#define DST_LATCH do { if(DST_IS_RIGHT_BANK) m_right_IV = READPORT(m_IVR+0x100); else m_left_IV = READPORT(m_IVL); } while (0)
+#define SRC_LATCH do { if(SRC_IS_RIGHT_BANK) m_IV_latch = READPORT(m_IVR+0x100); else m_IV_latch = READPORT(m_IVL); } while (0)
+#define DST_LATCH do { if(DST_IS_RIGHT_BANK) m_IV_latch = READPORT(m_IVR+0x100); else m_IV_latch = READPORT(m_IVL); } while (0)
#define SET_OVF do { if(result & 0xff00) m_OVF = 1; else m_OVF = 0; } while (0)
DEFINE_DEVICE_TYPE(N8X300, n8x300_cpu_device, "8x300", "Signetics 8X300")
+DEFINE_DEVICE_TYPE(N8X305, n8x305_cpu_device, "8x305", "Signetics 8X305")
-n8x300_cpu_device::n8x300_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
- : cpu_device(mconfig, N8X300, tag, owner, clock)
- , m_program_config("program", ENDIANNESS_BIG, 16, 14, 0)
+n8x300_cpu_device::n8x300_cpu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
+ : cpu_device(mconfig, type, tag, owner, clock)
+ , m_program_config("program", ENDIANNESS_BIG, 16, 13, -1)
, m_io_config("io", ENDIANNESS_BIG, 8, 9, 0)
+ , m_sc_callback(*this)
+{
+}
+
+n8x300_cpu_device::n8x300_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : n8x300_cpu_device(mconfig, N8X300, tag, owner, clock)
+{
+}
+
+n8x305_cpu_device::n8x305_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
+ : n8x300_cpu_device(mconfig, N8X305, tag, owner, clock)
{
}
@@ -56,9 +68,21 @@ device_memory_interface::space_config_vector n8x300_cpu_device::memory_space_con
};
}
-void n8x300_cpu_device::set_reg(uint8_t reg, uint8_t val)
+void n8x300_cpu_device::xmit_lb(uint8_t dst, uint8_t mask)
{
- switch(reg)
+ m_IV_latch = (m_IV_latch & ~mask) | (dst & mask);
+ WRITEPORT(m_IVL, m_IV_latch);
+}
+
+void n8x300_cpu_device::xmit_rb(uint8_t dst, uint8_t mask)
+{
+ m_IV_latch = (m_IV_latch & ~mask) | (dst & mask);
+ WRITEPORT(m_IVR + 0x100, m_IV_latch);
+}
+
+void n8x300_cpu_device::set_reg(uint8_t reg, uint8_t val, bool xmit)
+{
+ switch (reg)
{
case 0x00: m_AUX = val; break;
case 0x01: m_R1 = val; break;
@@ -67,17 +91,30 @@ void n8x300_cpu_device::set_reg(uint8_t reg, uint8_t val)
case 0x04: m_R4 = val; break;
case 0x05: m_R5 = val; break;
case 0x06: m_R6 = val; break;
- case 0x07: m_IVL = val; break;
+ case 0x07: m_IVL = val; m_sc_callback(0, val); break;
// OVF is read-only
case 0x09: m_R11 = val; break;
- case 0x0f: m_IVR = val; break;
+ case 0x0f: m_IVR = val; m_sc_callback(1, val); break;
default: logerror("8X300: Invalid register %02x written to.\n",reg); break;
}
}
+void n8x305_cpu_device::set_reg(uint8_t reg, uint8_t val, bool xmit)
+{
+ switch (reg)
+ {
+ case 0x0a: if (xmit) xmit_lb(val, 0xff); else m_R12 = val; break;
+ case 0x0b: if (xmit) xmit_rb(val, 0xff); else m_R13 = val; break;
+ case 0x0c: m_R14 = val; break;
+ case 0x0d: m_R15 = val; break;
+ case 0x0e: m_R16 = val; break;
+ default: n8x300_cpu_device::set_reg(reg, val, xmit); break;
+ }
+}
+
uint8_t n8x300_cpu_device::get_reg(uint8_t reg)
{
- switch(reg)
+ switch (reg)
{
case 0x00: return m_AUX;
case 0x01: return m_R1;
@@ -86,18 +123,38 @@ uint8_t n8x300_cpu_device::get_reg(uint8_t reg)
case 0x04: return m_R4;
case 0x05: return m_R5;
case 0x06: return m_R6;
-// IVL is write-only
+// IVL is write-only on the 8X300
case 0x08: return m_OVF;
case 0x09: return m_R11;
-// IVR is write-only
+// IVR is write-only on the 8X300
default: logerror("8X300: Invalid register %02x read.\n",reg); return 0;
}
}
+uint8_t n8x305_cpu_device::get_reg(uint8_t reg)
+{
+ switch (reg)
+ {
+ case 0x07: return m_IVL;
+ case 0x0a: return m_R12;
+ case 0x0b: return m_R13;
+ case 0x0c: return m_R14;
+ case 0x0d: return m_R15;
+ case 0x0e: return m_R16;
+ case 0x0f: return m_IVR;
+ default: return n8x300_cpu_device::get_reg(reg);
+ }
+}
+
+void n8x300_cpu_device::device_resolve_objects()
+{
+ m_sc_callback.resolve_safe();
+}
+
void n8x300_cpu_device::device_start()
{
m_program = &space(AS_PROGRAM);
- m_cache = m_program->cache<1, 0, ENDIANNESS_BIG>();
+ m_cache = m_program->cache<1, -1, ENDIANNESS_BIG>();
m_io = &space(AS_IO);
save_item(NAME(m_PC));
@@ -110,12 +167,19 @@ void n8x300_cpu_device::device_start()
save_item(NAME(m_R5));
save_item(NAME(m_R6));
save_item(NAME(m_R11));
+ if (type() == N8X305)
+ {
+ save_item(NAME(m_R12));
+ save_item(NAME(m_R13));
+ save_item(NAME(m_R14));
+ save_item(NAME(m_R15));
+ save_item(NAME(m_R16));
+ }
save_item(NAME(m_AUX));
save_item(NAME(m_IVL));
save_item(NAME(m_IVR));
save_item(NAME(m_OVF));
- save_item(NAME(m_left_IV));
- save_item(NAME(m_right_IV));
+ save_item(NAME(m_IV_latch));
save_item(NAME(m_genPC));
save_item(NAME(m_increment_pc));
@@ -127,6 +191,14 @@ void n8x300_cpu_device::device_start()
m_R5 = 0;
m_R6 = 0;
m_R11 = 0;
+ if (type() == N8X305)
+ {
+ m_R12 = 0;
+ m_R13 = 0;
+ m_R14 = 0;
+ m_R15 = 0;
+ m_R16 = 0;
+ }
m_IVL = 0;
m_IVR = 0;
m_AUX = 0;
@@ -146,11 +218,19 @@ void n8x300_cpu_device::device_start()
state_add( _8X300_R5, "R5", m_R5).mask(0xff).formatstr("%02X");
state_add( _8X300_R6, "R6", m_R6).mask(0xff).formatstr("%02X");
state_add( _8X300_R11, "R11", m_R11).mask(0xff).formatstr("%02X");
+ if (type() == N8X305)
+ {
+ state_add( _8X300_R12, "R12", m_R12).mask(0xff).formatstr("%02X");
+ state_add( _8X300_R13, "R13", m_R13).mask(0xff).formatstr("%02X");
+ state_add( _8X300_R14, "R14", m_R14).mask(0xff).formatstr("%02X");
+ state_add( _8X300_R15, "R15", m_R15).mask(0xff).formatstr("%02X");
+ state_add( _8X300_R16, "R16", m_R16).mask(0xff).formatstr("%02X");
+ }
state_add( _8X300_OVF, "OVF", m_OVF).mask(0x01).formatstr("%01X");
state_add( _8X300_IVL, "IVL", m_IVL).mask(0xff).formatstr("%02X");
state_add( _8X300_IVR, "IVR", m_IVR).mask(0xff).formatstr("%02X");
- state_add(STATE_GENPC, "GENPC", m_genPC).mask(0x3ffe).callimport().noshow();
- state_add(STATE_GENPCBASE, "CURPC", m_genPC).mask(0x3ffe).callimport().noshow();
+ state_add(STATE_GENPC, "GENPC", m_genPC).mask(0x1fff).callimport().noshow();
+ state_add(STATE_GENPCBASE, "CURPC", m_genPC).mask(0x1fff).callimport().noshow();
set_icountptr(m_icount);
}
@@ -166,12 +246,12 @@ void n8x300_cpu_device::state_import(const device_state_entry &entry)
{
case _8X300_PC:
m_AR = m_PC;
- m_genPC = m_AR << 1;
+ m_genPC = m_AR;
m_increment_pc = true;
break;
case _8X300_AR:
- m_genPC = m_AR << 1;
+ m_genPC = m_AR;
m_increment_pc = false;
break;
@@ -202,10 +282,9 @@ void n8x300_cpu_device::execute_run()
uint8_t dst;
uint8_t rotlen; // rotate amount or I/O field length
uint8_t mask;
- uint16_t result;
/* fetch the opcode */
- m_genPC = m_AR << 1;
+ m_genPC = m_AR;
debugger_instruction_hook(m_genPC);
opcode = FETCHOP(m_genPC);
@@ -230,7 +309,7 @@ void n8x300_cpu_device::execute_run()
{
src = get_reg(SRC);
dst = rotate(src,rotlen);
- set_reg(DST,dst);
+ set_reg(DST,dst,false);
}
else
{
@@ -243,62 +322,42 @@ void n8x300_cpu_device::execute_run()
src = (get_reg(SRC)) << (7-DST_LSB);
mask <<= (7-DST_LSB);
if(DST_IS_RIGHT_BANK)
- {
- dst = (m_right_IV & ~mask) | (src & mask);
- m_right_IV = dst;
- WRITEPORT(m_IVR+0x100,m_right_IV);
- }
+ xmit_rb(src, mask);
else
- {
- dst = (m_left_IV & ~mask) | (src & mask);
- m_left_IV = dst;
- WRITEPORT(m_IVL,m_left_IV);
- }
+ xmit_lb(src, mask);
}
else if(!(is_src_reg(opcode)) && is_dst_reg(opcode))
{ // MOVE IV,reg
SRC_LATCH;
- if(SRC_IS_RIGHT_BANK)
- src = rotate(m_right_IV,7-SRC_LSB);
- else
- src = rotate(m_left_IV,7-SRC_LSB);
+ src = rotate(m_IV_latch,7-SRC_LSB);
mask = ((1 << rotlen)-1);
dst = src & mask;
- set_reg(DST,dst);
+ set_reg(DST,dst,false);
}
else if(!(is_src_reg(opcode)) && !(is_dst_reg(opcode)))
{ // MOVE IV,IV
SRC_LATCH;
- if(SRC_IS_RIGHT_BANK)
- src = rotate(m_right_IV,7-SRC_LSB);
- else
- src = rotate(m_left_IV,7-SRC_LSB);
+ src = rotate(m_IV_latch,7-SRC_LSB);
mask = ((1 << rotlen)-1);
dst = src & mask;
dst <<= (7-DST_LSB);
mask <<= (7-DST_LSB);
- if(SRC_IS_RIGHT_BANK) // untouched source IV bits are preserved and sent to destination IV
- {
- dst = (m_right_IV & ~mask) | (dst & mask);
- m_right_IV = dst;
- WRITEPORT(m_IVR+0x100,m_right_IV);
- }
+ if(DST_IS_RIGHT_BANK) // untouched source IV bits are preserved and sent to destination IV
+ xmit_rb(dst, mask);
else
- {
- dst = (m_left_IV & ~mask) | (dst & mask);
- m_left_IV = dst;
- WRITEPORT(m_IVL,m_left_IV);
- }
+ xmit_lb(dst, mask);
}
}
break;
case 0x01: // ADD
+ {
+ uint16_t result;
rotlen = ROTLEN;
if(is_rot(opcode))
{ // ADD reg,reg
src = rotate(get_reg(SRC),rotlen);
result = src + m_AUX;
- set_reg(DST,result & 0xff);
+ set_reg(DST,result & 0xff,false);
SET_OVF;
}
else
@@ -314,65 +373,43 @@ void n8x300_cpu_device::execute_run()
mask <<= DST_LSB;
SET_OVF;
if(DST_IS_RIGHT_BANK)
- {
- dst = (m_right_IV & ~mask) | (dst & mask);
- m_right_IV = dst;
- WRITEPORT(m_IVR+0x100,m_right_IV);
- }
+ xmit_rb(dst, mask);
else
- {
- dst = (m_left_IV & ~mask) | (dst & mask);
- m_left_IV = dst;
- WRITEPORT(m_IVL,m_left_IV);
- }
+ xmit_lb(dst, mask);
}
else if(!(is_src_reg(opcode)) && is_dst_reg(opcode))
{ // ADD IV,reg
SRC_LATCH;
mask = ((1 << rotlen)-1);
- if(SRC_IS_RIGHT_BANK)
- src = rotate(m_right_IV,7-SRC_LSB) & mask;
- else
- src = rotate(m_left_IV,7-SRC_LSB) & mask;
+ src = rotate(m_IV_latch,7-SRC_LSB) & mask;
result = src + m_AUX;
SET_OVF;
- set_reg(DST,result & 0xff);
+ set_reg(DST,result & 0xff,false);
}
else if(!(is_src_reg(opcode)) && !(is_dst_reg(opcode)))
{ // ADD IV,IV
SRC_LATCH;
- DST_LATCH;
mask = ((1 << rotlen)-1);
- if(SRC_IS_RIGHT_BANK)
- src = rotate(m_right_IV,7-SRC_LSB) & mask;
- else
- src = rotate(m_left_IV,7-SRC_LSB) & mask;
+ src = rotate(m_IV_latch,7-SRC_LSB) & mask;
result = src + m_AUX;
SET_OVF;
dst = (result << (7-DST_LSB)) & 0xff;
mask <<= (7-DST_LSB);
- if(SRC_IS_RIGHT_BANK) // unused destination IV data is not preserved, is merged with input IV data
- {
- dst = (m_right_IV & ~mask) | (dst & mask);
- m_right_IV = dst;
- WRITEPORT(m_IVR+0x100,m_right_IV);
- }
+ if(DST_IS_RIGHT_BANK) // unused destination IV data is not preserved, is merged with input IV data
+ xmit_rb(dst, mask);
else
- {
- dst = (m_left_IV & ~mask) | (dst & mask);
- m_left_IV = dst;
- WRITEPORT(m_IVL,m_left_IV);
- }
+ xmit_lb(dst, mask);
}
}
break;
+ }
case 0x02: // AND
rotlen = ROTLEN;
if(is_rot(opcode))
{ // AND reg,reg
src = rotate(get_reg(SRC),rotlen);
dst = src & m_AUX;
- set_reg(DST,dst);
+ set_reg(DST,dst,false);
}
else
{
@@ -381,60 +418,36 @@ void n8x300_cpu_device::execute_run()
if(is_src_reg(opcode) && !(is_dst_reg(opcode)))
{ // AND reg,IV
DST_LATCH;
- src = get_reg(SRC) & m_AUX;
+ src = get_reg(SRC);
+ dst = src & m_AUX;
mask = ((1 << rotlen)-1);
- src <<= (7-DST_LSB);
+ dst <<= (7-DST_LSB);
mask <<= (7-DST_LSB);
if(DST_IS_RIGHT_BANK)
- {
- dst = (m_right_IV & ~mask) | (src & mask);
- m_right_IV = dst;
- WRITEPORT(m_IVR+0x100,m_right_IV);
- }
+ xmit_rb(dst, mask);
else
- {
- dst = (m_left_IV & ~mask) | (src & mask);
- m_left_IV = dst;
- WRITEPORT(m_IVL,m_left_IV);
- }
+ xmit_lb(dst, mask);
}
else if(!(is_src_reg(opcode)) && is_dst_reg(opcode))
{ // AND IV,reg
SRC_LATCH;
mask = ((1 << rotlen)-1);
- if(SRC_IS_RIGHT_BANK)
- src = rotate(m_right_IV,7-SRC_LSB) & mask;
- else
- src = rotate(m_left_IV,7-SRC_LSB) & mask;
- src &= mask;
+ src = rotate(m_IV_latch,7-SRC_LSB) & mask;
dst = src & m_AUX;
- set_reg(DST,dst);
+ set_reg(DST,dst,false);
}
else if(!(is_src_reg(opcode)) && !(is_dst_reg(opcode)))
{ // AND IV,IV
SRC_LATCH;
- DST_LATCH;
mask = ((1 << rotlen)-1);
- if(SRC_IS_RIGHT_BANK)
- src = rotate(m_right_IV,7-SRC_LSB) & mask;
- else
- src = rotate(m_left_IV,7-SRC_LSB) & mask;
- src &= mask;
+ src = rotate(m_IV_latch,7-SRC_LSB) & mask;
dst = src & m_AUX;
dst <<= (7-DST_LSB);
mask <<= (7-DST_LSB);
- if(SRC_IS_RIGHT_BANK)
- {
- dst = (m_right_IV & ~mask) | (src & mask);
- m_right_IV = dst;
- WRITEPORT(m_IVR+0x100,m_right_IV);
- }
+ if(DST_IS_RIGHT_BANK)
+ xmit_rb(dst, mask);
else
- {
- dst = (m_left_IV & ~mask) | (src & mask);
- m_left_IV = dst;
- WRITEPORT(m_IVL,m_left_IV);
- }
+ xmit_lb(dst, mask);
}
}
break;
@@ -444,69 +457,45 @@ void n8x300_cpu_device::execute_run()
{ // AND reg,reg
src = rotate(get_reg(SRC),rotlen);
dst = src ^ m_AUX;
- set_reg(DST,dst);
+ set_reg(DST,dst,false);
}
else
{
if(rotlen == 0)
rotlen = 8; // 0 = 8-bit I/O field length
if(is_src_reg(opcode) && !(is_dst_reg(opcode)))
- { // AND reg,IV
+ { // XOR reg,IV
DST_LATCH;
- src = get_reg(SRC) ^ m_AUX;
+ src = get_reg(SRC);
+ dst = src ^ m_AUX;
mask = ((1 << rotlen)-1);
- src <<= (7-DST_LSB);
+ dst <<= (7-DST_LSB);
mask <<= (7-DST_LSB);
if(DST_IS_RIGHT_BANK)
- {
- dst = (m_right_IV & ~mask) | (src & mask);
- m_right_IV = dst;
- WRITEPORT(m_IVR+0x100,m_right_IV);
- }
+ xmit_rb(dst, mask);
else
- {
- dst = (m_left_IV & ~mask) | (src & mask);
- m_left_IV = dst;
- WRITEPORT(m_IVL,m_left_IV);
- }
+ xmit_lb(dst, mask);
}
else if(!(is_src_reg(opcode)) && is_dst_reg(opcode))
- { // AND IV,reg
+ { // XOR IV,reg
SRC_LATCH;
mask = ((1 << rotlen)-1);
- if(SRC_IS_RIGHT_BANK)
- src = rotate(m_right_IV,7-SRC_LSB) & mask;
- else
- src = rotate(m_left_IV,7-SRC_LSB) & mask;
- src &= mask;
+ src = rotate(m_IV_latch,7-SRC_LSB) & mask;
dst = src ^ m_AUX;
- set_reg(DST,dst);
+ set_reg(DST,dst,false);
}
else if(!(is_src_reg(opcode)) && !(is_dst_reg(opcode)))
- { // AND IV,IV
+ { // XOR IV,IV
SRC_LATCH;
- DST_LATCH;
mask = ((1 << rotlen)-1);
- if(SRC_IS_RIGHT_BANK)
- src = rotate(m_right_IV,7-SRC_LSB) & mask;
- else
- src = rotate(m_left_IV,7-SRC_LSB) & mask;
- src &= mask;
+ src = rotate(m_IV_latch,7-SRC_LSB) & mask;
dst = src ^ m_AUX;
dst <<= (7-DST_LSB);
mask <<= (7-DST_LSB);
- if(SRC_IS_RIGHT_BANK)
- {
- dst = (m_right_IV & ~mask) | (src & mask);
- m_right_IV = dst;
- WRITEPORT(m_IVR+0x100,m_right_IV);
- }
+ if(DST_IS_RIGHT_BANK)
+ xmit_rb(dst, mask);
else
- {
- dst = (m_left_IV & ~mask) | (src & mask);
- m_left_IV = dst;
- WRITEPORT(m_IVL,m_left_IV);
- }
+ xmit_lb(dst, mask);
}
}
break;
@@ -524,10 +513,7 @@ void n8x300_cpu_device::execute_run()
if(rotlen == 0)
rotlen = 8; // 0 = 8-bit I/O field length
mask = ((1 << rotlen)-1);
- if(SRC_IS_RIGHT_BANK)
- src = rotate(m_right_IV,7-SRC_LSB);
- else
- src = rotate(m_left_IV,7-SRC_LSB);
+ src = rotate(m_IV_latch,7-SRC_LSB);
src &= mask;
src += IMM5;
SET_AR((m_AR & 0x1fe0) | (src & 0x1f));
@@ -547,11 +533,7 @@ void n8x300_cpu_device::execute_run()
if(rotlen == 0)
rotlen = 8; // 0 = 8-bit I/O field length
mask = ((1 << rotlen)-1);
- if(SRC_IS_RIGHT_BANK)
- src = rotate(m_right_IV,7-SRC_LSB);
- else
- src = rotate(m_left_IV,7-SRC_LSB);
- rotate(src,SRC_LSB);
+ src = rotate(m_IV_latch,7-SRC_LSB);
src &= mask;
if(src != 0)
SET_PC((m_PC & 0x1fe0) | IMM5);
@@ -560,7 +542,7 @@ void n8x300_cpu_device::execute_run()
case 0x06: // XMIT (Transmit)
// the source is actually the destination for this instruction
if(is_src_reg(opcode))
- set_reg(SRC,IMM8);
+ set_reg(SRC,IMM8,true);
else
{
SRC_LATCH;
@@ -572,15 +554,9 @@ void n8x300_cpu_device::execute_run()
mask <<= (7-SRC_LSB);
dst <<= (7-SRC_LSB);
if(SRC_IS_RIGHT_BANK)
- {
- m_right_IV = (m_right_IV & ~mask) | (dst & mask);
- WRITEPORT(m_IVR+0x100,m_right_IV);
- }
+ xmit_rb(dst, mask);
else
- {
- m_left_IV = (m_left_IV & ~mask) | (dst & mask);
- WRITEPORT(m_IVL,m_left_IV);
- }
+ xmit_lb(dst, mask);
}
break;
case 0x07: // JMP