diff options
author | 2020-05-16 20:49:54 +0200 | |
---|---|---|
committer | 2020-05-16 20:50:15 +0200 | |
commit | 4feb71b0a7d0dc967a7bac52fa9a890ac4855bd9 (patch) | |
tree | a27c9252422f209807848d0aca67648a8f93d9ce /src/devices/cpu/unsp | |
parent | 79f08d5431b0ce3a3c177b54b2411a3a52f11f16 (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.cpp | 3 | ||||
-rw-r--r-- | src/devices/cpu/unsp/unsp.h | 9 | ||||
-rw-r--r-- | src/devices/cpu/unsp/unsp_exxx.cpp | 133 | ||||
-rw-r--r-- | src/devices/cpu/unsp/unsp_fxxx.cpp | 34 |
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: |