summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/cpu/unsp/unsp_other.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/cpu/unsp/unsp_other.cpp')
-rw-r--r--src/devices/cpu/unsp/unsp_other.cpp69
1 files changed, 40 insertions, 29 deletions
diff --git a/src/devices/cpu/unsp/unsp_other.cpp b/src/devices/cpu/unsp/unsp_other.cpp
index 9e9fb984cb4..efbf27d1278 100644
--- a/src/devices/cpu/unsp/unsp_other.cpp
+++ b/src/devices/cpu/unsp/unsp_other.cpp
@@ -5,8 +5,6 @@
#include "unsp.h"
#include "unspfe.h"
-#include "debugger.h"
-
#include "unspdasm.h"
void unsp_device::execute_remaining(const uint16_t op)
@@ -41,23 +39,22 @@ void unsp_device::execute_remaining(const uint16_t op)
if (op == 0x9a98) // reti
{
m_core->m_icount -= 8;
+ if (m_core->m_ine)
+ {
+ set_fr(pop(&m_core->m_r[REG_SP]));
+ }
+
m_core->m_r[REG_SR] = pop(&m_core->m_r[REG_SP]);
m_core->m_r[REG_PC] = pop(&m_core->m_r[REG_SP]);
if (m_core->m_fiq)
{
m_core->m_fiq = 0;
- m_core->m_saved_sb[2] = m_core->m_sb;
- m_core->m_sb = m_core->m_saved_sb[m_core->m_irq ? 1 : 0];
}
else if (m_core->m_irq)
{
m_core->m_irq = 0;
- m_core->m_saved_sb[1] = m_core->m_sb;
- m_core->m_sb = m_core->m_saved_sb[0];
}
- m_core->m_curirq = 0;
- check_irqs();
return;
}
else // pop
@@ -204,6 +201,7 @@ void unsp_device::execute_remaining(const uint16_t op)
r0 = m_core->m_r[opb];
r2 = read16(UNSP_LPC);
add_lpc(1);
+ // additional special case 'if (op1 == 0x04 && opn == 0x03)' write logic below
break;
default: // Shifted ops
@@ -256,7 +254,7 @@ void unsp_device::execute_remaining(const uint16_t op)
break;
}
- case 0x07: // Direct 8
+ case 0x07: // Direct 6
m_core->m_icount -= (opa == 7 ? 6 : 5);
r2 = op & 0x3f;
r1 = read16(r2);
@@ -266,12 +264,26 @@ void unsp_device::execute_remaining(const uint16_t op)
break;
}
+ bool write = do_basic_alu_ops(op0, lres, r0, r1, r2, (opa != 7) ? true : false);
+
+ if (write)
+ {
+ if (op1 == 0x04 && opn == 0x03) // store [imm16], r
+ write16(r2, lres);
+ else
+ m_core->m_r[opa] = (uint16_t)lres;
+ }
+}
+
+
+bool unsp_device::do_basic_alu_ops(const uint16_t &op0, uint32_t &lres, uint16_t &r0, uint16_t &r1, uint32_t &r2, bool update_flags)
+{
switch (op0)
{
case 0x00: // Add
{
lres = r0 + r1;
- if (opa != 7)
+ if (update_flags)
update_nzsc(lres, r0, r1);
break;
}
@@ -279,69 +291,68 @@ void unsp_device::execute_remaining(const uint16_t op)
{
uint32_t c = (m_core->m_r[REG_SR] & UNSP_C) ? 1 : 0;
lres = r0 + r1 + c;
- if (opa != 7)
+ if (update_flags)
update_nzsc(lres, r0, r1);
break;
}
case 0x02: // Subtract
lres = r0 + (uint16_t)(~r1) + uint32_t(1);
- if (opa != 7)
+ if (update_flags)
update_nzsc(lres, r0, ~r1);
break;
case 0x03: // Subtract w/ carry
{
uint32_t c = (m_core->m_r[REG_SR] & UNSP_C) ? 1 : 0;
lres = r0 + (uint16_t)(~r1) + c;
- if (opa != 7)
+ if (update_flags)
update_nzsc(lres, r0, ~r1);
break;
}
case 0x04: // Compare
lres = r0 + (uint16_t)(~r1) + uint32_t(1);
- if (opa != 7)
+ if (update_flags)
update_nzsc(lres, r0, ~r1);
- return;
+ return false;
case 0x06: // Negate
lres = -r1;
- if (opa != 7)
+ if (update_flags)
update_nz(lres);
break;
case 0x08: // XOR
lres = r0 ^ r1;
- if (opa != 7)
+ if (update_flags)
update_nz(lres);
break;
case 0x09: // Load
lres = r1;
- if (opa != 7)
+ if (update_flags)
update_nz(lres);
break;
case 0x0a: // OR
lres = r0 | r1;
- if (opa != 7)
+ if (update_flags)
update_nz(lres);
break;
case 0x0b: // AND
lres = r0 & r1;
- if (opa != 7)
+ if (update_flags)
update_nz(lres);
break;
case 0x0c: // Test
lres = r0 & r1;
- if (opa != 7)
+ if (update_flags)
update_nz(lres);
- return;
+ return false;
case 0x0d: // Store
write16(r2, r0);
- return;
+ return false;
default:
- unimplemented_opcode(op);
- return;
+ // pcp87xx 'Elevator Action' explicitly jumps into the middle of an earlier opcode (off-by-one error in the code)
+ // It looks like the illegal op should have no meaningful effect so just log rather than fatalerroring
+ logerror("UNSP: illegal ALU optype %02x at %04x\n", op0, UNSP_LPC);
+ return false;
}
- if (op1 == 0x04 && opn == 0x03) // store [imm16], r
- write16(r2, lres);
- else
- m_core->m_r[opa] = (uint16_t)lres;
+ return true;
}