summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/cpu/unsp
diff options
context:
space:
mode:
author Ryan Holtz <ryan.holtz@arrowheadgs.com>2020-05-16 20:49:54 +0200
committer Ryan Holtz <ryan.holtz@arrowheadgs.com>2020-05-16 20:50:15 +0200
commit4feb71b0a7d0dc967a7bac52fa9a890ac4855bd9 (patch)
treea27c9252422f209807848d0aca67648a8f93d9ce /src/devices/cpu/unsp
parent79f08d5431b0ce3a3c177b54b2411a3a52f11f16 (diff)
-unsp: Added DIVQ and extended BIT_OP opcodes. [Ryan Holtz]
Diffstat (limited to 'src/devices/cpu/unsp')
-rw-r--r--src/devices/cpu/unsp/unsp.cpp3
-rw-r--r--src/devices/cpu/unsp/unsp.h9
-rw-r--r--src/devices/cpu/unsp/unsp_exxx.cpp133
-rw-r--r--src/devices/cpu/unsp/unsp_fxxx.cpp34
4 files changed, 150 insertions, 29 deletions
diff --git a/src/devices/cpu/unsp/unsp.cpp b/src/devices/cpu/unsp/unsp.cpp
index 6a47bf61dd2..95a2e2498ab 100644
--- a/src/devices/cpu/unsp/unsp.cpp
+++ b/src/devices/cpu/unsp/unsp.cpp
@@ -506,6 +506,9 @@ inline void unsp_device::execute_one(const uint16_t op)
const uint16_t opa = (op >> 9) & 7;
const uint16_t op1 = (op >> 6) & 7;
+ if (!op_is_divq(op))
+ m_core->m_divq_active = 0;
+
if (op0 == 0xf)
return execute_fxxx_group(op);
diff --git a/src/devices/cpu/unsp/unsp.h b/src/devices/cpu/unsp/unsp.h
index badc913808d..9af9dfdeef3 100644
--- a/src/devices/cpu/unsp/unsp.h
+++ b/src/devices/cpu/unsp/unsp.h
@@ -193,6 +193,9 @@ protected:
uint32_t m_ine;
uint32_t m_pri;
+ uint32_t m_divq_active;
+ uint32_t m_divq_dividend;
+
uint32_t m_arg0;
uint32_t m_arg1;
uint32_t m_jmpdest;
@@ -229,7 +232,7 @@ protected:
virtual void execute_fxxx_101_group(uint16_t op);
void execute_fxxx_110_group(uint16_t op);
void execute_fxxx_111_group(uint16_t op);
- void execute_fxxx_group(uint16_t op);;
+ void execute_fxxx_group(uint16_t op);
void execute_fxxx_100_group(uint16_t op);
virtual void execute_extended_group(uint16_t op);
virtual void execute_exxx_group(uint16_t op);
@@ -237,6 +240,7 @@ protected:
void unimplemented_opcode(uint16_t op);
void unimplemented_opcode(uint16_t op, uint16_t ximm);
void unimplemented_opcode(uint16_t op, uint16_t ximm, uint16_t ximm_2);
+ virtual bool op_is_divq(const uint16_t op) { return false; }
int m_iso;
@@ -369,7 +373,8 @@ protected:
virtual void execute_fxxx_101_group(uint16_t op) override;
virtual void execute_exxx_group(uint16_t op) override;
-
+ void execute_divq(uint16_t op);
+ bool op_is_divq(const uint16_t op) override;
virtual std::unique_ptr<util::disasm_interface> create_disassembler() override;
};
diff --git a/src/devices/cpu/unsp/unsp_exxx.cpp b/src/devices/cpu/unsp/unsp_exxx.cpp
index 66f16ca9099..325c81a55dc 100644
--- a/src/devices/cpu/unsp/unsp_exxx.cpp
+++ b/src/devices/cpu/unsp/unsp_exxx.cpp
@@ -49,14 +49,15 @@ void unsp_12_device::execute_exxx_group(uint16_t op)
else if (((op & 0xf1c0) == 0xe040))
{
// Register BITOP BITOP Rd,offset
- uint8_t bitop = (op & 0x0030) >> 4;
- uint8_t rd = (op & 0x0e00) >> 9;
- uint8_t offset = (op & 0x000f) >> 0;
+ const uint8_t bitop = (op & 0x0030) >> 4;
+ const uint8_t rd = (op & 0x0e00) >> 9;
+ const uint8_t offset = (op & 0x000f) >> 0;
+ m_core->m_r[REG_SR] &= ~UNSP_Z;
+ m_core->m_r[REG_SR] |= BIT(m_core->m_r[rd], offset) ? 0 : UNSP_Z;
switch (bitop)
{
- case 0x00:
- fatalerror("UNSP: unknown opcode tstb Rd,offset (%04x) at %04x\n", op, UNSP_LPC);
+ case 0x00: // tstb
return;
case 0x01: // setb
@@ -76,41 +77,123 @@ void unsp_12_device::execute_exxx_group(uint16_t op)
else if (((op & 0xf1c0) == 0xe180))
{
// Memory BITOP BITOP [Rd], offset
- uint8_t bitop = (op & 0x0030) >> 4;
- uint8_t rd = (op & 0x0e00) >> 9;
- uint8_t offset = (op & 0x000f) >> 0;
- logerror("%s [%s],%d\n", bitops[bitop], regs[rd], offset);
- unimplemented_opcode(op);
+ const uint8_t bitop = (op & 0x0030) >> 4;
+ const uint8_t rd = (op & 0x0e00) >> 9;
+ const uint8_t offset = (op & 0x000f) >> 0;
+ const uint16_t addr = m_core->m_r[rd];
+ const uint16_t orig = read16(addr);
+ m_core->m_r[REG_SR] &= ~UNSP_Z;
+ m_core->m_r[REG_SR] |= BIT(m_core->m_r[rd], offset) ? 0 : UNSP_Z;
+
+ switch (bitop)
+ {
+ case 0x00: // tstb
+ return;
+
+ case 0x01: // setb
+ write16(addr, orig | (1 << offset));
+ return;
+
+ case 0x02: // clrb
+ write16(addr, orig & ~(1 << offset));
+ return;
+
+ case 0x03:
+ write16(addr, orig ^ (1 << offset));
+ return;
+ }
return;
}
else if (((op & 0xf1c0) == 0xe1c0))
{
// Memory BITOP BITOP ds:[Rd], offset
- uint8_t bitop = (op & 0x0030) >> 4;
- uint8_t rd = (op & 0x0e00) >> 9;
- uint8_t offset = (op & 0x000f) >> 0;
- logerror("%s ds:[%s],%d\n", bitops[bitop], regs[rd], offset);
- unimplemented_opcode(op);
+ const uint8_t bitop = (op & 0x0030) >> 4;
+ const uint8_t rd = (op & 0x0e00) >> 9;
+ const uint8_t offset = (op & 0x000f) >> 0;
+ const uint16_t addr = m_core->m_r[rd] | (get_ds() << 16);
+ const uint16_t orig = read16(addr);
+ m_core->m_r[REG_SR] &= ~UNSP_Z;
+ m_core->m_r[REG_SR] |= BIT(m_core->m_r[rd], offset) ? 0 : UNSP_Z;
+
+ switch (bitop)
+ {
+ case 0x00: // tstb
+ return;
+
+ case 0x01: // setb
+ write16(addr, orig | (1 << offset));
+ return;
+
+ case 0x02: // clrb
+ write16(addr, orig & ~(1 << offset));
+ return;
+
+ case 0x03:
+ write16(addr, orig ^ (1 << offset));
+ return;
+ }
return;
}
else if (((op & 0xf1c8) == 0xe100))
{
// Memory BITOP BITOP [Rd], Rs
- uint8_t bitop = (op & 0x0030) >> 4;
- uint8_t rd = (op & 0x0e00) >> 9;
- uint8_t rs = (op & 0x0007) >> 0;
- logerror("%s [%s],%s\n", bitops[bitop], regs[rd], regs[rs]);
- unimplemented_opcode(op);
+ const uint8_t bitop = (op & 0x0030) >> 4;
+ const uint8_t rd = (op & 0x0e00) >> 9;
+ const uint8_t rs = (op & 0x0007) >> 0;
+ const uint8_t offset = (1 << m_core->m_r[rs]);
+ const uint16_t addr = m_core->m_r[rd];
+ const uint16_t orig = read16(addr);
+ m_core->m_r[REG_SR] &= ~UNSP_Z;
+ m_core->m_r[REG_SR] |= BIT(m_core->m_r[rd], offset) ? 0 : UNSP_Z;
+
+ switch (bitop)
+ {
+ case 0x00: // tstb
+ return;
+
+ case 0x01: // setb
+ write16(addr, orig | (1 << offset));
+ return;
+
+ case 0x02: // clrb
+ write16(addr, orig & ~(1 << offset));
+ return;
+
+ case 0x03:
+ write16(addr, orig ^ (1 << offset));
+ return;
+ }
return;
}
else if (((op & 0xf1c8) == 0xe140))
{
// Memory BITOP BITOP ds:[Rd], Rs
- uint8_t bitop = (op & 0x0030) >> 4;
- uint8_t rd = (op & 0x0e00) >> 9;
- uint8_t rs = (op & 0x0007) >> 0;
- logerror("%s ds:[%s],%s\n", bitops[bitop], regs[rd], regs[rs]);
- unimplemented_opcode(op);
+ const uint8_t bitop = (op & 0x0030) >> 4;
+ const uint8_t rd = (op & 0x0e00) >> 9;
+ const uint8_t rs = (op & 0x0007) >> 0;
+ const uint8_t offset = (1 << m_core->m_r[rs]);
+ const uint16_t addr = m_core->m_r[rd] | (get_ds() << 16);
+ const uint16_t orig = read16(addr);
+ m_core->m_r[REG_SR] &= ~UNSP_Z;
+ m_core->m_r[REG_SR] |= BIT(m_core->m_r[rd], offset) ? 0 : UNSP_Z;
+
+ switch (bitop)
+ {
+ case 0x00: // tstb
+ return;
+
+ case 0x01: // setb
+ write16(addr, orig | (1 << offset));
+ return;
+
+ case 0x02: // clrb
+ write16(addr, orig & ~(1 << offset));
+ return;
+
+ case 0x03:
+ write16(addr, orig ^ (1 << offset));
+ return;
+ }
return;
}
else if (((op & 0xf0f8) == 0xe008))
diff --git a/src/devices/cpu/unsp/unsp_fxxx.cpp b/src/devices/cpu/unsp/unsp_fxxx.cpp
index dc181da3989..fdfb9da02a0 100644
--- a/src/devices/cpu/unsp/unsp_fxxx.cpp
+++ b/src/devices/cpu/unsp/unsp_fxxx.cpp
@@ -248,6 +248,32 @@ inline void unsp_device::execute_fxxx_100_group(uint16_t op)
return;
}
+void unsp_12_device::execute_divq(uint16_t op)
+{
+ const uint16_t sign_a = m_core->m_aq;
+ if (m_core->m_divq_active == 0)
+ {
+ m_core->m_divq_active = 1;
+ m_core->m_divq_dividend = (m_core->m_r[REG_R4] << 16) | m_core->m_r[REG_R3];
+ m_core->m_r[REG_R3] = 0;
+ }
+ m_core->m_aq = BIT(m_core->m_divq_dividend, 31);
+ if (sign_a)
+ {
+ m_core->m_r[REG_R3] += m_core->m_r[REG_R2];
+ }
+ else
+ {
+ m_core->m_r[REG_R3] -= m_core->m_r[REG_R3];
+ }
+ m_core->m_divq_dividend <<= 1;
+ m_core->m_divq_dividend |= m_core->m_aq ? 0 : 1;
+}
+
+bool unsp_12_device::op_is_divq(const uint16_t op)
+{
+ return (op & 0xf163) == 0xf163;
+}
void unsp_12_device::execute_fxxx_101_group(uint16_t op)
{
@@ -336,8 +362,7 @@ void unsp_12_device::execute_fxxx_101_group(uint16_t op)
case 0xf16b: case 0xf36b: case 0xf56b: case 0xf76b: case 0xf96b: case 0xfb6b: case 0xfd6b: case 0xff6b:
case 0xf173: case 0xf373: case 0xf573: case 0xf773: case 0xf973: case 0xfb73: case 0xfd73: case 0xff73:
case 0xf17b: case 0xf37b: case 0xf57b: case 0xf77b: case 0xf97b: case 0xfb7b: case 0xfd7b: case 0xff7b:
- logerror("divq mr, r2\n");
- unimplemented_opcode(op);
+ execute_divq(op);
return;
case 0xf164: case 0xf364: case 0xf564: case 0xf764: case 0xf964: case 0xfb64: case 0xfd64: case 0xff64:
@@ -525,18 +550,23 @@ void unsp_device::execute_fxxx_group(uint16_t op)
switch ((op & 0x01c0) >> 6)
{
case 0x0:
+ m_core->m_divq_active = 0;
return execute_fxxx_000_group(op);
case 0x1:
+ m_core->m_divq_active = 0;
return execute_fxxx_001_group(op);
case 0x2:
+ m_core->m_divq_active = 0;
return execute_fxxx_010_group(op);
case 0x3:
+ m_core->m_divq_active = 0;
return execute_fxxx_011_group(op);
case 0x4:
+ m_core->m_divq_active = 0;
return execute_fxxx_100_group(op);
case 0x5: