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.cpp128
1 files changed, 97 insertions, 31 deletions
diff --git a/src/devices/cpu/8x300/8x300.cpp b/src/devices/cpu/8x300/8x300.cpp
index 1b0aecfc4c4..dbc7614748a 100644
--- a/src/devices/cpu/8x300/8x300.cpp
+++ b/src/devices/cpu/8x300/8x300.cpp
@@ -12,7 +12,6 @@
#include "emu.h"
#include "8x300.h"
#include "8x300dasm.h"
-#include "debugger.h"
#define FETCHOP(a) (m_cache.read_word(a))
#define CYCLES(x) do { m_icount -= (x); } while (0)
@@ -47,6 +46,11 @@ n8x300_cpu_device::n8x300_cpu_device(const machine_config &mconfig, device_type
, m_program_config("program", ENDIANNESS_BIG, 16, 13, -1)
, m_io_config("io", ENDIANNESS_BIG, 8, 9, 0)
, m_sc_callback(*this)
+ , m_wc_callback(*this)
+ , m_lb_callback(*this)
+ , m_rb_callback(*this)
+ , m_mclk_callback(*this)
+ , m_iv_callback(*this)
{
}
@@ -68,15 +72,49 @@ device_memory_interface::space_config_vector n8x300_cpu_device::memory_space_con
};
}
-void n8x300_cpu_device::xmit_lb(uint8_t dst, uint8_t mask)
+void n8x300_cpu_device::xmit_lb(uint8_t dst, uint8_t mask, bool with_sc, bool with_wc)
{
m_IV_latch = (m_IV_latch & ~mask) | (dst & mask);
+
+ if(with_sc)
+ {
+ m_sc_callback(1);
+ m_wc_callback(0);
+ m_lb_callback(1);
+ m_iv_callback(m_IVL);
+ }
+
+ if(with_wc)
+ {
+ m_sc_callback(0);
+ m_wc_callback(1);
+ m_lb_callback(1);
+ m_iv_callback(m_IV_latch);
+ }
+
WRITEPORT(m_IVL, m_IV_latch);
}
-void n8x300_cpu_device::xmit_rb(uint8_t dst, uint8_t mask)
+void n8x300_cpu_device::xmit_rb(uint8_t dst, uint8_t mask, bool with_sc, bool with_wc)
{
m_IV_latch = (m_IV_latch & ~mask) | (dst & mask);
+
+ if(with_sc)
+ {
+ m_sc_callback(1);
+ m_wc_callback(0);
+ m_rb_callback(1);
+ m_iv_callback(m_IVL);
+ }
+
+ if(with_wc)
+ {
+ m_sc_callback(0);
+ m_wc_callback(1);
+ m_rb_callback(1);
+ m_iv_callback(m_IV_latch);
+ }
+
WRITEPORT(m_IVR + 0x100, m_IV_latch);
}
@@ -91,11 +129,11 @@ void n8x300_cpu_device::set_reg(uint8_t reg, uint8_t val, bool xmit)
case 0x04: m_R4 = val; break;
case 0x05: m_R5 = val; break;
case 0x06: m_R6 = val; break;
- case 0x07: m_IVL = val; m_sc_callback(0, val); break;
+ case 0x07: m_IVL = val; xmit_lb(val, 0xFF, true, false); break;
// OVF is read-only
case 0x09: m_R11 = val; break;
- case 0x0f: m_IVR = val; m_sc_callback(1, val); break;
- default: logerror("8X300: Invalid register %02x written to.\n",reg); break;
+ case 0x0f: m_IVR = val; xmit_rb(val, 0xFF, true, false); break;
+ default: logerror("8X300: Tried to write to invalid register %02x.\n",reg); break;
}
}
@@ -103,8 +141,8 @@ 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 0x0a: if (xmit) xmit_lb(val, 0xff, true, true); else m_R12 = val; break;
+ case 0x0b: if (xmit) xmit_rb(val, 0xff, true, true); else m_R13 = val; break;
case 0x0c: m_R14 = val; break;
case 0x0d: m_R15 = val; break;
case 0x0e: m_R16 = val; break;
@@ -146,11 +184,6 @@ uint8_t n8x305_cpu_device::get_reg(uint8_t reg)
}
}
-void n8x300_cpu_device::device_resolve_objects()
-{
- m_sc_callback.resolve_safe();
-}
-
void n8x300_cpu_device::device_start()
{
space(AS_PROGRAM).cache(m_cache);
@@ -271,6 +304,10 @@ void n8x300_cpu_device::device_reset()
m_AR = 0;
m_genPC = 0;
m_increment_pc = true;
+
+ m_lb_callback(0);
+ m_rb_callback(0);
+ m_mclk_callback(0);
}
void n8x300_cpu_device::execute_run()
@@ -282,12 +319,21 @@ void n8x300_cpu_device::execute_run()
uint8_t dst;
uint8_t rotlen; // rotate amount or I/O field length
uint8_t mask;
+ bool with_sc;
+ bool with_wc;
/* fetch the opcode */
m_genPC = m_AR;
debugger_instruction_hook(m_genPC);
opcode = FETCHOP(m_genPC);
+ /* reset I/O lines for this instruction */
+ m_lb_callback(0);
+ m_rb_callback(0);
+ m_sc_callback(0);
+ m_wc_callback(0);
+ m_mclk_callback(0);
+
if (m_increment_pc)
{
m_PC++;
@@ -322,9 +368,9 @@ void n8x300_cpu_device::execute_run()
src = (get_reg(SRC)) << (7-DST_LSB);
mask <<= (7-DST_LSB);
if(DST_IS_RIGHT_BANK)
- xmit_rb(src, mask);
+ xmit_rb(src, mask, false, true);
else
- xmit_lb(src, mask);
+ xmit_lb(src, mask, false, true);
}
else if(!(is_src_reg(opcode)) && is_dst_reg(opcode))
{ // MOVE IV,reg
@@ -343,9 +389,9 @@ void n8x300_cpu_device::execute_run()
dst <<= (7-DST_LSB);
mask <<= (7-DST_LSB);
if(DST_IS_RIGHT_BANK) // untouched source IV bits are preserved and sent to destination IV
- xmit_rb(dst, mask);
+ xmit_rb(dst, mask, false, true);
else
- xmit_lb(dst, mask);
+ xmit_lb(dst, mask, false, true);
}
}
break;
@@ -373,9 +419,9 @@ void n8x300_cpu_device::execute_run()
mask <<= DST_LSB;
SET_OVF;
if(DST_IS_RIGHT_BANK)
- xmit_rb(dst, mask);
+ xmit_rb(dst, mask, false, true);
else
- xmit_lb(dst, mask);
+ xmit_lb(dst, mask, false, true);
}
else if(!(is_src_reg(opcode)) && is_dst_reg(opcode))
{ // ADD IV,reg
@@ -396,9 +442,9 @@ void n8x300_cpu_device::execute_run()
dst = (result << (7-DST_LSB)) & 0xff;
mask <<= (7-DST_LSB);
if(DST_IS_RIGHT_BANK) // unused destination IV data is not preserved, is merged with input IV data
- xmit_rb(dst, mask);
+ xmit_rb(dst, mask, false, true);
else
- xmit_lb(dst, mask);
+ xmit_lb(dst, mask, false, true);
}
}
break;
@@ -424,9 +470,9 @@ void n8x300_cpu_device::execute_run()
dst <<= (7-DST_LSB);
mask <<= (7-DST_LSB);
if(DST_IS_RIGHT_BANK)
- xmit_rb(dst, mask);
+ xmit_rb(dst, mask, false, true);
else
- xmit_lb(dst, mask);
+ xmit_lb(dst, mask, false, true);
}
else if(!(is_src_reg(opcode)) && is_dst_reg(opcode))
{ // AND IV,reg
@@ -445,9 +491,9 @@ void n8x300_cpu_device::execute_run()
dst <<= (7-DST_LSB);
mask <<= (7-DST_LSB);
if(DST_IS_RIGHT_BANK)
- xmit_rb(dst, mask);
+ xmit_rb(dst, mask, false, true);
else
- xmit_lb(dst, mask);
+ xmit_lb(dst, mask, false, true);
}
}
break;
@@ -472,9 +518,9 @@ void n8x300_cpu_device::execute_run()
dst <<= (7-DST_LSB);
mask <<= (7-DST_LSB);
if(DST_IS_RIGHT_BANK)
- xmit_rb(dst, mask);
+ xmit_rb(dst, mask, false, true);
else
- xmit_lb(dst, mask);
+ xmit_lb(dst, mask, false, true);
}
else if(!(is_src_reg(opcode)) && is_dst_reg(opcode))
{ // XOR IV,reg
@@ -493,9 +539,9 @@ void n8x300_cpu_device::execute_run()
dst <<= (7-DST_LSB);
mask <<= (7-DST_LSB);
if(DST_IS_RIGHT_BANK)
- xmit_rb(dst, mask);
+ xmit_rb(dst, mask, false, true);
else
- xmit_lb(dst, mask);
+ xmit_lb(dst, mask, false, true);
}
}
break;
@@ -553,16 +599,36 @@ void n8x300_cpu_device::execute_run()
dst = IMM5;
mask <<= (7-SRC_LSB);
dst <<= (7-SRC_LSB);
+
+ if(opcode & 0xA00 || opcode & 0xB00)
+ {
+ // Imm -> IV Data
+ with_sc = false;
+ with_wc = true;
+ }
+ else
+ {
+ // Imm -> IV Address
+ with_sc = false;
+ with_wc = true;
+ }
+
if(SRC_IS_RIGHT_BANK)
- xmit_rb(dst, mask);
+ {
+ xmit_rb(dst, mask, with_sc, with_wc);
+ }
else
- xmit_lb(dst, mask);
+ {
+ xmit_lb(dst, mask, with_sc, with_wc);
+ }
+
}
break;
case 0x07: // JMP
SET_PC(ADDR);
break;
}
+ m_mclk_callback(1);
CYCLES(1); // all instructions take 1 cycle (250ns)
} while (m_icount > 0);
}