summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/cpu/unsp/unspdasm_other.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/cpu/unsp/unspdasm_other.cpp')
-rw-r--r--src/devices/cpu/unsp/unspdasm_other.cpp235
1 files changed, 235 insertions, 0 deletions
diff --git a/src/devices/cpu/unsp/unspdasm_other.cpp b/src/devices/cpu/unsp/unspdasm_other.cpp
new file mode 100644
index 00000000000..b639b97e25c
--- /dev/null
+++ b/src/devices/cpu/unsp/unspdasm_other.cpp
@@ -0,0 +1,235 @@
+// license:GPL-2.0+
+// copyright-holders:Segher Boessenkool, David Haywood
+/*****************************************************************************
+
+ SunPlus ยต'nSP disassembler
+
+ Copyright 2008-2017 Segher Boessenkool <segher@kernel.crashing.org>
+ Licensed under the terms of the GNU GPL, version 2
+ http://www.gnu.org/licenses/old-licenses/gpl-2.0.txt
+
+*****************************************************************************/
+
+#include "emu.h"
+#include "unspdasm.h"
+
+offs_t unsp_disassembler::disassemble_remaining(std::ostream& stream, offs_t pc, uint16_t op, uint16_t ximm, const data_buffer& opcodes)
+{
+ uint32_t len = 1;
+ uint8_t op0 = (op >> 12);
+ uint8_t opA = (op >> 9) & 7;
+ uint8_t op1 = (op >> 6) & 7;
+ uint8_t opN = (op >> 3) & 7;
+ uint8_t opB = op & 7;
+ uint8_t opimm = op & 63;
+
+ switch ((op1 << 4) | op0)
+ {
+ case 0x05: case 0x15: case 0x25: case 0x35:
+ case 0x45: case 0x55: case 0x65: case 0x75:
+ case 0x85: case 0x95: case 0xa5: case 0xb5:
+ case 0xc5: case 0xd5:
+ case 0x07: case 0x17: case 0x27: case 0x37:
+ case 0x47: case 0x57: case 0x67: case 0x77:
+ case 0x87: case 0x97: case 0xa7: case 0xb7:
+ case 0xc7: case 0xd7:
+ case 0x1d: case 0x5d: case 0x6d:
+ case 0x20: case 0x21: case 0x22: case 0x23:
+ case 0x24: case 0x26: case 0x28: case 0x2a:
+ case 0x2b: case 0x2c:
+ util::stream_format(stream, "<BAD>");
+ return UNSP_DASM_OK;
+
+
+ // alu, base+displacement
+ case 0x00: case 0x01: case 0x02: case 0x03:
+ case 0x04: case 0x06: case 0x08: case 0x09:
+ case 0x0a: case 0x0b: case 0x0c:
+ print_alu_op_start(stream, op0, opA);
+ util::stream_format(stream, "[bp+%02x]", opimm);
+ print_alu_op_end(stream, op0);
+ return UNSP_DASM_OK;
+ case 0x0d:
+ util::stream_format(stream, "[bp+%02x] = %s", opimm, regs[opA]);
+ return UNSP_DASM_OK;
+
+
+ // alu, 6-bit immediate
+ case 0x10: case 0x11: case 0x12: case 0x13:
+ case 0x14: case 0x16: case 0x18: case 0x19:
+ case 0x1a: case 0x1b: case 0x1c:
+ print_alu_op_start(stream, op0, opA);
+ util::stream_format(stream, "%02x", opimm);
+ print_alu_op_end(stream, op0);
+ return UNSP_DASM_OK;
+
+
+ // pop insns
+ case 0x29:
+ if (op == 0x9a90)
+ util::stream_format(stream, "retf");
+ else if (op == 0x9a98)
+ util::stream_format(stream, "reti");
+ else if (opA + 1 < 8 && opA + opN < 8)
+ util::stream_format(stream, "pop %s, %s from [%s]",
+ regs[opA + 1], regs[opA + opN], regs[opB]);
+ else
+ util::stream_format(stream, "<BAD>");
+ return UNSP_DASM_OK;
+
+
+ // push insns
+ case 0x2d:
+ if (opA + 1 >= opN && opA < opN + 7)
+ util::stream_format(stream, "push %s, %s to [%s]",
+ regs[opA + 1 - opN], regs[opA], regs[opB]);
+ else
+ util::stream_format(stream, "<BAD>");
+ return UNSP_DASM_OK;
+
+
+ // alu, indirect memory
+ case 0x30: case 0x31: case 0x32: case 0x33:
+ case 0x34: case 0x36: case 0x38: case 0x39:
+ case 0x3a: case 0x3b: case 0x3c:
+ print_alu_op_start(stream, op0, opA);
+ print_indirect_op(stream, opN, opB);
+ print_alu_op_end(stream, op0);
+ return UNSP_DASM_OK;
+ case 0x3d:
+ print_indirect_op(stream, opN, opB);
+ util::stream_format(stream, " = %s", regs[opA]);
+ return UNSP_DASM_OK;
+
+
+ case 0x40: case 0x41: case 0x42: case 0x43:
+ case 0x44: case 0x46: case 0x48: case 0x49:
+ case 0x4a: case 0x4b: case 0x4c:
+ switch (opN)
+ {
+ // alu, register
+ case 0:
+ print_alu_op_start(stream, op0, opA);
+ util::stream_format(stream, "%s", regs[opB]);
+ print_alu_op_end(stream, op0);
+ return UNSP_DASM_OK;
+
+ // alu, 16-bit immediate
+ case 1:
+ if ((op0 == 4 || op0 == 12 || op0 == 6 || op0 == 9) && opA != opB)
+ {
+ util::stream_format(stream, "<BAD>");
+ return UNSP_DASM_OK;
+ }
+ if (op0 != 4 && op0 != 12)
+ util::stream_format(stream, "%s = ", regs[opA]);
+ print_alu_op3(stream, op0, opB);
+ len = 2;
+ util::stream_format(stream, "%04x", ximm);
+ print_alu_op_end(stream, op0);
+ return UNSP_DASM_OK;
+
+ // alu, direct memory
+ case 2:
+ if ((op0 == 4 || op0 == 12 || op0 == 6 || op0 == 9) && opA != opB)
+ {
+ util::stream_format(stream, "<BAD>");
+ return UNSP_DASM_OK;
+ }
+ if (op0 != 4 && op0 != 12)
+ util::stream_format(stream, "%s = ", regs[opA]);
+ print_alu_op3(stream, op0, opB);
+ len = 2;
+ util::stream_format(stream, "[%04x]", ximm);
+ print_alu_op_end(stream, op0);
+ return UNSP_DASM_OK;
+
+ // alu, direct memory
+ case 3:
+ if (op0 == 4 || op0 == 12)
+ {
+ util::stream_format(stream, "<BAD>");
+ return UNSP_DASM_OK;
+ }
+ if ((op0 == 6 || op0 == 9) && opA != opB)
+ {
+ util::stream_format(stream, "<BAD>");
+ return UNSP_DASM_OK;
+ }
+ len = 2;
+ util::stream_format(stream, "[%04x] = ", ximm);
+ print_alu_op3(stream, op0, opB);
+ util::stream_format(stream, "%s", regs[opA]);
+ print_alu_op_end(stream, op0);
+ return UNSP_DASM_OK;
+
+ // alu, with shift
+ default:
+ print_alu_op_start(stream, op0, opA);
+ util::stream_format(stream, "%s asr %x", regs[opB], (opN & 3) + 1);
+ print_alu_op_end(stream, op0);
+ return UNSP_DASM_OK;
+ }
+
+ case 0x4d:
+ switch (opN)
+ {
+ // alu, direct memory
+ case 3:
+ if (opA != opB)
+ {
+ util::stream_format(stream, "<BAD>");
+ return UNSP_DASM_OK;
+ }
+ len = 2;
+ util::stream_format(stream, "[%04x] = %s", ximm, regs[opB]);
+ return UNSP_DASM_OK;
+ default:
+ util::stream_format(stream, "<BAD>");
+ return UNSP_DASM_OK;
+ }
+
+
+ // alu, with shift
+ case 0x50: case 0x51: case 0x52: case 0x53:
+ case 0x54: case 0x56: case 0x58: case 0x59:
+ case 0x5a: case 0x5b: case 0x5c:
+ print_alu_op_start(stream, op0, opA);
+ if ((opN & 4) == 0)
+ util::stream_format(stream, "%s lsl %x", regs[opB], (opN & 3) + 1);
+ else
+ util::stream_format(stream, "%s lsr %x", regs[opB], (opN & 3) + 1);
+ print_alu_op_end(stream, op0);
+ return UNSP_DASM_OK;
+
+
+ // alu, with shift
+ case 0x60: case 0x61: case 0x62: case 0x63:
+ case 0x64: case 0x66: case 0x68: case 0x69:
+ case 0x6a: case 0x6b: case 0x6c:
+ print_alu_op_start(stream, op0, opA);
+ if ((opN & 4) == 0)
+ util::stream_format(stream, "%s rol %x", regs[opB], (opN & 3) + 1);
+ else
+ util::stream_format(stream, "%s ror %x", regs[opB], (opN & 3) + 1);
+ print_alu_op_end(stream, op0);
+ return UNSP_DASM_OK;
+
+
+ // alu, direct memory
+ case 0x70: case 0x71: case 0x72: case 0x73:
+ case 0x74: case 0x76: case 0x78: case 0x79:
+ case 0x7a: case 0x7b: case 0x7c:
+ print_alu_op_start(stream, op0, opA);
+ util::stream_format(stream, "[%02x]", opimm);
+ print_alu_op_end(stream, op0);
+ return UNSP_DASM_OK;
+ case 0x7d:
+ util::stream_format(stream, "[%02x] = %s", opimm, regs[opA]);
+ return UNSP_DASM_OK;
+
+ default:
+ util::stream_format(stream, "<UNHANDLED>");
+ return UNSP_DASM_OK;
+ }
+}