diff options
Diffstat (limited to 'src/devices/cpu/unsp/unsp_extended.cpp')
-rw-r--r-- | src/devices/cpu/unsp/unsp_extended.cpp | 284 |
1 files changed, 197 insertions, 87 deletions
diff --git a/src/devices/cpu/unsp/unsp_extended.cpp b/src/devices/cpu/unsp/unsp_extended.cpp index caa66763a00..bbfbefd1844 100644 --- a/src/devices/cpu/unsp/unsp_extended.cpp +++ b/src/devices/cpu/unsp/unsp_extended.cpp @@ -5,10 +5,12 @@ #include "unsp.h" #include "unspfe.h" -#include "debugger.h" - #include "unspdasm.h" +// TODO: the call conventions and general use of 'do_basic_alu_ops' from unsp_other.cpp could be cleaned up +// at the moment things like the 'Store' opcode make things more complex than they need to be, and require +// the passing of a store address each time, they make the regular use of the code a little awkward too tho. + void unsp_device::execute_extended_group(uint16_t op) { // shouldn't get here anyway @@ -26,191 +28,299 @@ void unsp_20_device::execute_extended_group(uint16_t op) { case 0x00: case 0x10: { - // Ext Register Ra = Ra op Rb + // Ext Register + // Ra = Ra op Rb + // A = B op C uint8_t aluop = (ximm & 0xf000) >> 12; uint8_t rb = (ximm & 0x000f) >> 0; uint8_t ra = (ximm & 0x0e00) >> 9; ra |= (ximm & 0x0100) >> 5; - logerror("(Ext) %s = %s %s %s\n", (ra & 0x8) ? extregs[ra & 0x7] : regs[ra & 0x7] - , (ra & 0x8) ? extregs[ra & 0x7] : regs[ra & 0x7] - , aluops[aluop] - , (rb & 0x8) ? extregs[rb & 0x7] : regs[rb & 0x7]); + uint16_t b = m_core->m_r[ra]; + uint16_t c = m_core->m_r[rb]; + uint32_t lres; + uint32_t storeaddr = b; // dest address for STORE + + bool write = do_basic_alu_ops(aluop, lres, b, c, storeaddr, (ra != 7)); + + if (write) + { + // a = Ra + m_core->m_r[ra] = (uint16_t)lres; + } - unimplemented_opcode(op, ximm); return; } case 0x02: { - // register decoding could be incorrect here - // Ext Push/Pop if (ximm & 0x8000) { - // just skip for now, as nothing really even uses the extended registers yet - /* - uint8_t rb = (ximm & 0x000f) >> 0; + uint8_t rb = (ximm & 0x000f) >> 0; uint8_t size = (ximm & 0x7000) >> 12; - uint8_t rx = (ximm & 0x0e00) >> 9; + uint8_t rx = (ximm & 0x0e00) >> 9; if (size == 0) size = 8; - size -= 1; - - if ((rx-size) >= 0) - logerror("(Ext) push %s, %s to [%s]\n", - extregs[rx-size], extregs[rx], (rb & 0x8) ? extregs[rb & 0x7] : regs[rb & 0x7]); - else - logerror("(Ext) push <BAD>\n"); - */ - //unimplemented_opcode(op, ximm); + + while (size--) + { + push(m_core->m_r[((rx--)&7) + 8], &m_core->m_r[rb]); + } return; } else { - // just skip for now, as nothing really even uses the extended registers yet - /* - uint8_t rb = (ximm & 0x000f) >> 0; + uint8_t rb = (ximm & 0x000f) >> 0; uint8_t size = (ximm & 0x7000) >> 12; - uint8_t rx = (ximm & 0x0e00) >> 9; + uint8_t rx = (ximm & 0x0e00) >> 9; if (size == 0) size = 8; - size -= 1; - - if ((rx-size) >= 0) - logerror("(Ext) pop %s, %s from [%s]\n", - extregs[rx-size], extregs[rx], (rb & 0x8) ? extregs[rb & 0x7] : regs[rb & 0x7]); - else - logerror("(Ext) pop <BAD>\n"); - */ - //unimplemented_opcode(op, ximm); + while (size--) + { + m_core->m_r[((++rx)&7) + 8] = pop(&m_core->m_r[rb]); + } return; } return; } case 0x04: case 0x14: { - uint16_t ximm_2 = read16(UNSP_LPC); + uint16_t imm16_2 = read16(UNSP_LPC); add_lpc(1); - // Ra=Rb op IMM16 + // Ra = Rb op IMM16 + // A = B op C + uint8_t aluop = (ximm & 0xf000) >> 12; uint8_t rb = (ximm & 0x000f) >> 0; uint8_t ra = (ximm & 0x0e00) >> 9; ra |= (ximm & 0x0100) >> 5; - logerror("(Ext) %s = %s %s %04x\n", (ra & 0x8) ? extregs[ra & 0x7] : regs[ra & 0x7] - , (rb & 0x8) ? extregs[rb & 0x7] : regs[rb & 0x7] - , aluops[aluop] - , ximm_2); - unimplemented_opcode(op, ximm, ximm_2); + uint16_t b = m_core->m_r[rb]; + uint32_t lres; + uint32_t storeaddr = 0;// m_core->m_r[ra]; // dest address for STORE (invalid anyway?) + + if (aluop == 0xd) + { + // store is invalid? + unimplemented_opcode(op, ximm, imm16_2); + } + + bool write = do_basic_alu_ops(aluop, lres, b, imm16_2, storeaddr, (ra != 7)); + + if (write) + { + // a = Ra + m_core->m_r[ra] = (uint16_t)lres; + } + return; } case 0x06: case 0x16: { - uint16_t ximm_2 = read16(UNSP_LPC); + uint16_t imm16_2 = read16(UNSP_LPC); add_lpc(1); - // Ra=Rb op [A16] + // Ra = Rb op [A16] + // A = B op C + uint8_t aluop = (ximm & 0xf000) >> 12; uint8_t rb = (ximm & 0x000f) >> 0; uint8_t ra = (ximm & 0x0e00) >> 9; ra |= (ximm & 0x0100) >> 5; - logerror("(Ext) %s = %s %s [%04x]\n", (ra & 0x8) ? extregs[ra & 0x7] : regs[ra & 0x7] - , (rb & 0x8) ? extregs[rb & 0x7] : regs[rb & 0x7] - , aluops[aluop] - , ximm_2); + uint16_t b = m_core->m_r[rb]; + uint16_t c = read16(imm16_2); + uint32_t storeaddr = imm16_2; // dest address for STORE + uint32_t lres; + + bool write = do_basic_alu_ops(aluop, lres, b, c, storeaddr, (ra != 7)); + + if (write) + { + // a = Ra + m_core->m_r[ra] = (uint16_t)lres; + } - unimplemented_opcode(op, ximm, ximm_2); return; } case 0x07: case 0x17: { - uint16_t ximm_2 = read16(UNSP_LPC); + uint16_t imm16_2 = read16(UNSP_LPC); add_lpc(1); //[A16] = Ra op Rb + // A = B op C + uint8_t aluop = (ximm & 0xf000) >> 12; uint8_t rb = (ximm & 0x000f) >> 0; uint8_t ra = (ximm & 0x0e00) >> 9; ra |= (ximm & 0x0100) >> 5; - logerror("(Ext) [0x4x] = %s %s %s\n", ximm_2 - , (ra & 0x8) ? extregs[ra & 0x7] : regs[ra & 0x7] - , aluops[aluop] - , (rb & 0x8) ? extregs[rb & 0x7] : regs[rb & 0x7]); + uint16_t a = imm16_2; + uint16_t b = m_core->m_r[ra]; + uint16_t c = m_core->m_r[rb]; + uint32_t lres; + uint32_t r2 = a; - unimplemented_opcode(op, ximm, ximm_2); - return; - } + bool write = do_basic_alu_ops(aluop, lres, b, c, r2, true); - case 0x08: case 0x09: - { - // Ext Indirect Rx=Rx op [Ry@] - uint8_t aluop = (ximm & 0xf000) >> 12; - uint8_t ry = (ximm & 0x0007) >> 0; - uint8_t form = (ximm & 0x0018) >> 3; - uint8_t rx = (ximm & 0x0e00) >> 9; + if (write) + { + write16(imm16_2, lres); + } - logerror("(Ext) %s=%s %s", extregs[rx], extregs[rx], aluops[aluop]); - logerror(forms[form], extregs[ry]); - logerror("\n"); - unimplemented_opcode(op, ximm); return; } - case 0x0a: case 0x0b: + + case 0x08: case 0x09: // Ext Indirect, Rx = Rx op [Ry@] + case 0x0a: case 0x0b: // Ext Indirect, Rx = Rx op ds:[Ry@] { - // Ext DS_Indirect Rx=Rx op ds:[Ry@] - uint8_t aluop = (ximm & 0xf000) >> 12; - uint8_t ry = (ximm & 0x0007) >> 0; + uint16_t r0 = 0; + uint16_t r1 = 0; + uint32_t r2 = 0; + uint32_t lres = 0; + + uint16_t aluop = (ximm & 0xf000) >> 12; + uint8_t ry = (ximm & 0x0007) + 8; + uint8_t rx = ((ximm & 0x0e00) >> 9) + 8; + uint8_t use_ds = BIT(ximm, 5); uint8_t form = (ximm & 0x0018) >> 3; - uint8_t rx = (ximm & 0x0e00) >> 9; - logerror("(Ext) %s=%s %s ds:", extregs[rx], extregs[rx], aluops[aluop]); - logerror(forms[form], extregs[ry]); - logerror("\n"); - unimplemented_opcode(op, ximm); + r0 = m_core->m_r[rx]; + + switch (form) + { + case 0x0: // Rx, [<ds:>Ry] + r2 = use_ds ? UNSP_LREG_I(ry) : m_core->m_r[ry]; + if (aluop != 0x0d) + r1 = read16(r2); + break; + case 0x1: // Rx, [<ds:>Ry--] + r2 = use_ds ? UNSP_LREG_I(ry) : m_core->m_r[ry]; + if (aluop != 0x0d) + r1 = read16(r2); + m_core->m_r[ry] = (uint16_t)(m_core->m_r[ry] - 1); + if (m_core->m_r[ry] == 0xffff && use_ds) + m_core->m_r[REG_SR] -= 0x0400; + break; + case 0x2: // Rx, [<ds:>Ry++] + r2 = use_ds ? UNSP_LREG_I(ry) : m_core->m_r[ry]; + if (aluop != 0x0d) + r1 = read16(r2); + m_core->m_r[ry] = (uint16_t)(m_core->m_r[ry] + 1); + if (m_core->m_r[ry] == 0x0000 && use_ds) + m_core->m_r[REG_SR] += 0x0400; + break; + case 0x3: // Rx, [<ds:>++Ry] + m_core->m_r[ry] = (uint16_t)(m_core->m_r[ry] + 1); + if (m_core->m_r[ry] == 0x0000 && use_ds) + m_core->m_r[REG_SR] += 0x0400; + r2 = use_ds ? UNSP_LREG_I(ry) : m_core->m_r[ry]; + if (aluop != 0x0d) + r1 = read16(r2); + break; + } + + if (do_basic_alu_ops(aluop, lres, r0, r1, r2, (aluop != 7) ? true : false)) + { + m_core->m_r[rx] = (uint16_t)lres; + } + return; } case 0x18: case 0x19: case 0x1a: case 0x1b: { - // Ext IM6 Rx=Rx op IM6 + // Ext IM6 + // Rx = Rx op IM6 + // A = B op C + uint8_t aluop = (ximm & 0xf000) >> 12; uint8_t rx = (ximm & 0x0e00) >> 9; uint8_t imm6 = (ximm & 0x003f) >> 0; - logerror("(Ext) %s=%s %s %02x\n", extregs[rx], extregs[rx], aluops[aluop], imm6 ); - unimplemented_opcode(op, ximm); + uint16_t b = m_core->m_r[rx + 8]; + uint16_t c = imm6; + + uint32_t storeaddr = 0; // dest address for STORE + uint32_t lres; + + if (aluop == 0xd) + { + // store is invalid? + unimplemented_opcode(op, ximm); + } + + bool write = do_basic_alu_ops(aluop, lres, b, c, storeaddr, true); + + if (write) + { + // A = Rx + m_core->m_r[rx + 8] = (uint16_t)lres; + } + return; } case 0x0c: case 0x0d: case 0x0e: case 0x0f: { - // Ext Base+Disp6 Rx=Rx op [BP+IM6] + // Ext Base+Disp6 + // Rx = Rx op [BP+IM6] + // A = B op C + uint8_t aluop = (ximm & 0xf000) >> 12; uint8_t rx = (ximm & 0x0e00) >> 9; uint8_t imm6 = (ximm & 0x003f) >> 0; - logerror("(Ext) %s=%s %s [BP+%02x]\n", extregs[rx], extregs[rx], aluops[aluop], imm6 ); - unimplemented_opcode(op, ximm); + uint32_t addr = (uint16_t)(m_core->m_r[REG_BP] + (imm6 & 0x3f)); + + uint16_t b = m_core->m_r[rx + 8]; + uint16_t c = read16(addr); + + uint32_t storeaddr = addr; // dest address for STORE + uint32_t lres; + + bool write = do_basic_alu_ops(aluop, lres, b, c, storeaddr, true); + + if (write) + { + // A = Rx + m_core->m_r[rx + 8] = (uint16_t)lres; + } + return; } case 0x1c: case 0x1d: case 0x1e: case 0x1f: { - // Ext A6 Rx=Rx op [A6] + // Ext A6 + // Rx = Rx op [A6] + // A = B op C + uint8_t aluop = (ximm & 0xf000) >> 12; uint8_t rx = (ximm & 0x0e00) >> 9; uint8_t a6 = (ximm & 0x003f) >> 0; - logerror("(Ext) %s=%s %s [%02x]\n", extregs[rx], extregs[rx], aluops[aluop], a6 ); - unimplemented_opcode(op, ximm); + uint16_t b = m_core->m_r[rx + 8]; + uint16_t c = read16(a6); + + uint32_t storeaddr = a6; // dest address for STORE + uint32_t lres; + + bool write = do_basic_alu_ops(aluop, lres, b, c, storeaddr, true); + + if (write) + { + // A = Rx + m_core->m_r[rx + 8] = (uint16_t)lres; + } + return; } } |