diff options
Diffstat (limited to 'src/devices/cpu/unsp/unsp_exxx.cpp')
-rw-r--r-- | src/devices/cpu/unsp/unsp_exxx.cpp | 292 |
1 files changed, 221 insertions, 71 deletions
diff --git a/src/devices/cpu/unsp/unsp_exxx.cpp b/src/devices/cpu/unsp/unsp_exxx.cpp index 5eb74881b7b..ac8a09d59ee 100644 --- a/src/devices/cpu/unsp/unsp_exxx.cpp +++ b/src/devices/cpu/unsp/unsp_exxx.cpp @@ -5,10 +5,16 @@ #include "unsp.h" #include "unspfe.h" -#include "debugger.h" - #include "unspdasm.h" +#define LOG_UNSP_MULS (1U << 1) +#define LOG_UNSP_SHIFTS (1U << 2) + +#define VERBOSE (LOG_UNSP_SHIFTS) + +#include "logmacro.h" + + void unsp_device::execute_exxx_group(uint16_t op) { // several exxx opcodes have already been decoded as jumps by the time we get here @@ -34,21 +40,43 @@ void unsp_12_device::execute_exxx_group(uint16_t op) 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 offset = (m_core->m_r[rs] & 0xf); + + 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 + m_core->m_r[rd] |= (1 << offset); + return; + + case 0x02: // clrb + m_core->m_r[rd] &= ~(1 << offset); + return; + + case 0x03: + m_core->m_r[rd] ^= (1 << offset); + return; + } return; } 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 @@ -60,7 +88,7 @@ void unsp_12_device::execute_exxx_group(uint16_t op) return; case 0x03: - fatalerror("UNSP: unknown opcode invb Rd,offset (%04x) at %04x\n", op, UNSP_LPC); + m_core->m_r[rd] ^= (1 << offset); return; } return; @@ -68,79 +96,161 @@ 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(orig, 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 uint32_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(orig, 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 = (m_core->m_r[rs] & 0xf); + 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(orig, 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 = (m_core->m_r[rs] & 0xf); + const uint32_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(orig, 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)) + else if (((op & 0xf1f8) == 0xe008)) { // MUL operations // MUL 1 1 1 0* r r r S* 0 0 0 0 1 r r r (* = sign bit, fixed here) /* - print_mul(stream, op); // MUL uu or MUL su (invalid?) + print_mul(stream, op); // MUL uu */ + // only valid if S is 1, otherwise falls through to shifter - if (op & 0x0100) - { - logerror("MUL su\n"); - fatalerror("UNSP: unknown opcode MUL su (invalid?) (%04x) at %04x\n", op, UNSP_LPC); - return; - } - else - { - uint32_t lres = 0; - const uint16_t opa = (op >> 9) & 7; - const uint16_t opb = op & 7; + // MUL uu (unsigned * unsigned) + uint32_t lres = 0; + const uint16_t opa = (op >> 9) & 7; + const uint16_t opb = op & 7; + + m_core->m_icount -= 12; // unknown + + LOGMASKED(LOG_UNSP_MULS, "%s: MUL uu with %04x (unsigned) * %04x (unsigned) (fra:%d) :\n", machine().describe_context(), m_core->m_r[opa], m_core->m_r[opb], m_core->m_fra); + + lres = m_core->m_r[opa] * m_core->m_r[opb]; + m_core->m_r[REG_R4] = lres >> 16; + m_core->m_r[REG_R3] = (uint16_t)lres; + + LOGMASKED(LOG_UNSP_MULS, "result was : %08x\n", lres); - m_core->m_icount -= 12; // unknown - lres = m_core->m_r[opa] * m_core->m_r[opb]; - m_core->m_r[REG_R4] = lres >> 16; - m_core->m_r[REG_R3] = (uint16_t)lres; - return; - } return; } - else if (((op & 0xf080) == 0xe080)) + else if (((op & 0xf180) == 0xe080)) { // MULS 1 1 1 0* r r r S* 1 s s s s r r r (* = sign bit, fixed here) /* - // MULS uu or MULS su (invalid?) + // MULS uu + // only valid if S is 1? otherwise falls through to shifter + print_muls(stream, op); */ - logerror("MULS uu or su\n"); + LOGMASKED(LOG_UNSP_MULS, "MULS uu or su\n"); unimplemented_opcode(op); return; } @@ -153,48 +263,88 @@ void unsp_12_device::execute_exxx_group(uint16_t op) switch (shift) { - case 0x00: - logerror("%s = %s asr %s\n", regs[rd], regs[rd], regs[rs]); - unimplemented_opcode(op); + case 0x00: // jak_smwm train movement + { + LOGMASKED(LOG_UNSP_SHIFTS, "%s = %s asr %s\n", regs[rd], regs[rd], regs[rs]); + int16_t rdval = (int16_t)((uint16_t)m_core->m_r[rd]); + int shift = (m_core->m_r[rs] & 0x1f); + uint32_t res; + res = rdval >> shift; + LOGMASKED(LOG_UNSP_SHIFTS, "result: %08x\n", res); + m_core->m_r[rd] = res; return; + } - case 0x01: - logerror("%s = %s asror %s\n", regs[rd], regs[rd], regs[rs]); - unimplemented_opcode(op); + case 0x01: // jak_car2 on starting a game, myac220 'piggy golf' ball movement + { + LOGMASKED(LOG_UNSP_SHIFTS, "%s = %s asror %s (%04x %04x)\n", regs[rd], regs[rd], regs[rs], m_core->m_r[rd], m_core->m_r[rs]); + + const int32_t rdval = (int32_t)(m_core->m_r[rd] << 16); + const int shift = (m_core->m_r[rs] & 0x1f); + const uint32_t res = rdval >> shift; + m_core->m_r[REG_R3] |= (uint16_t)res; + m_core->m_r[REG_R4] = (uint16_t)(res >> 16); + LOGMASKED(LOG_UNSP_SHIFTS, "result: %04x%04x\n", m_core->m_r[REG_R4], m_core->m_r[REG_R3]); return; + } case 0x02: - logerror("pc:%06x: %s = %s lsl %s (%04x %04x)\n", UNSP_LPC, regs[rd], regs[rd], regs[rs], m_core->m_r[rd], m_core->m_r[rs]); - m_core->m_r[rd] = m_core->m_r[rd] << m_core->m_r[rs]; + { + LOGMASKED(LOG_UNSP_SHIFTS, "pc:%06x: %s = %s lsl %s (%04x %04x)\n", UNSP_LPC, regs[rd], regs[rd], regs[rs], m_core->m_r[rd], m_core->m_r[rs]); + const uint32_t rdval = (uint16_t)(m_core->m_r[rd]); + const int shift = (m_core->m_r[rs] & 0x1f); + const uint32_t res = (uint16_t)(rdval << shift); + LOGMASKED(LOG_UNSP_SHIFTS, "result: %08x\n", res); + m_core->m_r[rd] = res; return; + } case 0x03: - logerror("%s = %s lslor %s\n", regs[rd], regs[rd], regs[rs]); - unimplemented_opcode(op); + { + // wrlshunt uses this + LOGMASKED(LOG_UNSP_SHIFTS, "pc:%06x: %s = %s lslor %s (%04x %04x)\n", UNSP_LPC, regs[rd], regs[rd], regs[rs], m_core->m_r[rd], m_core->m_r[rs]); + + const uint32_t rdval = (uint16_t)m_core->m_r[rd]; + const int shift = (m_core->m_r[rs] & 0x1f); + const uint32_t res = rdval << shift; + m_core->m_r[REG_R3] = (uint16_t)res; + m_core->m_r[REG_R4] |= (uint16_t)(res >> 16); + LOGMASKED(LOG_UNSP_SHIFTS, "result: %04x%04x\n", m_core->m_r[REG_R4], m_core->m_r[REG_R3]); return; + } case 0x04: - // smartfp loops increasing shift by 4 up to values of 28? (but regs are 16-bit?) - logerror("pc:%06x: %s = %s lsr %s (%04x %04x)\n", UNSP_LPC, regs[rd], regs[rd], regs[rs], m_core->m_r[rd], m_core->m_r[rs]); - m_core->m_r[rd] = m_core->m_r[rd] >> m_core->m_r[rs]; + { + // smartfp loops increasing shift by 4 up to values of 28 + LOGMASKED(LOG_UNSP_SHIFTS, "pc:%06x: %s = %s lsr %s (%04x %04x)\n", UNSP_LPC, regs[rd], regs[rd], regs[rs], m_core->m_r[rd], m_core->m_r[rs]); + + const uint32_t rdval = (uint16_t)(m_core->m_r[rd]); + const int shift = (m_core->m_r[rs] & 0x1f); + const uint32_t res = (uint16_t)(rdval >> shift); + LOGMASKED(LOG_UNSP_SHIFTS, "result: %08x\n", res); + m_core->m_r[rd] = res; return; + } case 0x05: { - logerror("pc:%06x: %s = %s lsror %s (%04x %04x)\n", UNSP_LPC, regs[rd], regs[rd], regs[rs], m_core->m_r[rd], m_core->m_r[rs]); - uint16_t tmp = m_core->m_r[rd]; - m_core->m_r[rd] = m_core->m_r[rd] >> m_core->m_r[rs]; - m_core->m_r[rd] |= tmp; // guess + LOGMASKED(LOG_UNSP_SHIFTS, "pc:%06x: %s = %s lsror %s (%04x %04x)\n", UNSP_LPC, regs[rd], regs[rd], regs[rs], m_core->m_r[rd], m_core->m_r[rs]); + const uint32_t rdval = m_core->m_r[rd] << 16; + const int shift = (m_core->m_r[rs] & 0x1f); + const uint32_t res = rdval >> shift; + m_core->m_r[REG_R3] |= (uint16_t)res; + m_core->m_r[REG_R4] = (uint16_t)(res >> 16); + LOGMASKED(LOG_UNSP_SHIFTS, "result: %04x%04x\n", m_core->m_r[REG_R4], m_core->m_r[REG_R3]); return; } case 0x06: - logerror("%s = %s rol %s\n", regs[rd], regs[rd], regs[rs]); + LOGMASKED(LOG_UNSP_SHIFTS, "%s = %s rol %s\n", regs[rd], regs[rd], regs[rs]); unimplemented_opcode(op); return; case 0x07: - logerror("%s = %s ror %s\n", regs[rd], regs[rd], regs[rs]); + LOGMASKED(LOG_UNSP_SHIFTS, "%s = %s ror %s\n", regs[rd], regs[rd], regs[rs]); unimplemented_opcode(op); return; } |