summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/cpu/clipper/clipperd.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/devices/cpu/clipper/clipperd.cpp')
-rw-r--r--src/devices/cpu/clipper/clipperd.cpp351
1 files changed, 351 insertions, 0 deletions
diff --git a/src/devices/cpu/clipper/clipperd.cpp b/src/devices/cpu/clipper/clipperd.cpp
new file mode 100644
index 00000000000..735804b2742
--- /dev/null
+++ b/src/devices/cpu/clipper/clipperd.cpp
@@ -0,0 +1,351 @@
+// license:BSD-3-Clause
+// copyright-holders:Patrick Mackinlay
+
+#include "emu.h"
+
+/*
+ * TODO
+ * - dynamically switch between C400 and C100/C300 instruction sets
+ * - handle failures of addressing mode decoding more elegantly
+ * - improve address decoding to use streams
+ * - detect various cases of illegal instruction encoding
+ */
+
+// enable C400 instruction decoding
+#define C400_INSTRUCTIONS 1
+
+// the CLIPPER addressing modes (unshifted)
+enum
+{
+ ADDR_MODE_PC32 = 0x10,
+ ADDR_MODE_ABS32 = 0x30,
+ ADDR_MODE_REL32 = 0x60,
+ ADDR_MODE_PC16 = 0x90,
+ ADDR_MODE_REL12 = 0xa0,
+ ADDR_MODE_ABS16 = 0xb0,
+ ADDR_MODE_PCX = 0xd0,
+ ADDR_MODE_RELX = 0xe0
+};
+
+// macros for decoding various operand fields
+#define R1 ((insn[0] & 0x00f0) >> 4)
+#define R2 (insn[0] & 0x000f)
+
+#define I16 ((int16_t)insn[1])
+#define I32 (*(int32_t *)&insn[1])
+#define IMM_VALUE (insn[0] & 0x0080 ? I16 : I32)
+#define IMM_SIZE (insn[0] & 0x0080 ? 2 : 4)
+
+#define ADDR_MODE (insn[0] & 0x00f0)
+#define ADDR_R2 ((insn[0] & 0x0050) == 0x0010 ? (insn[0] & 0x000f) : (insn[1] & 0x000f))
+#define ADDR_SIZE (ADDR_MODE > ADDR_MODE_REL32 ? 2 : ADDR_MODE == ADDR_MODE_REL32 ? 6 : 4)
+#define ADDR_RX ((insn[1] & 0xf0) >> 4)
+#define ADDR_I12 (((int16_t)insn[1]) >> 4)
+
+/*
+ * Branch condition code mnemonics - the forms beginning with 'c' are
+ * supposed to be used for branches following comparison instructions,
+ * while those beginning with 'r' are for use after move or logical
+ * instructions. We use the first form because we can't know which type
+ * should be used without some kind of dynamic information.
+ */
+static const char *const cc[] =
+{
+ "",
+ "clt", // rgt
+ "cle", // rge
+ "ceq", // req
+ "cgt", // rlt
+ "cge", // rle
+ "cne", // rne
+ "cltu", // rgtu
+ "cleu", // rgeu, nc
+ "cgtu", // rltu, c
+ "cgeu", // rleu
+ "v",
+ "nv",
+ "n",
+ "nn",
+ "fn"
+};
+
+/*
+ * Decode an addressing mode into a string.
+ */
+char *address (offs_t pc, u16 *insn)
+{
+ static char buffer[32];
+
+ switch (ADDR_MODE)
+ {
+ case ADDR_MODE_PC32: sprintf(buffer, "0x%x", pc + I32); break;
+ case ADDR_MODE_ABS32: sprintf(buffer, "0x%x", I32); break;
+ case ADDR_MODE_REL32: sprintf(buffer, "%d(r%d)", *(int32_t *)&insn[2], R2); break;
+ case ADDR_MODE_PC16: sprintf(buffer, "0x%x", pc + I16); break;
+ case ADDR_MODE_REL12: sprintf(buffer, "%d(r%d)", ADDR_I12, R2); break;
+ case ADDR_MODE_ABS16: sprintf(buffer, "0x%x", I16); break;
+ case ADDR_MODE_PCX: sprintf(buffer, "[r%d](pc)", ADDR_RX); break;
+ case ADDR_MODE_RELX: sprintf(buffer, "[r%d](r%d)", ADDR_RX, R2); break;
+ default: sprintf(buffer, "ERROR"); break;
+ }
+
+ return buffer;
+}
+
+/*
+ * CLIPPER instructions are composed of 1, 2, 3 or 4 16-bit "parcels". The first parcel contains
+ * the opcode and enough information to work out how many additional parcels might be required. The
+ * instruction set is fairly typically RISC-ish, except for these variable length instructions, the
+ * 8 addressing modes, and the "macro instructions", which are actually "subroutines" embedded in
+ * an on-CPU macro instruction ROM. It appears at least some of these macro instructions were removed
+ * from the C400 and generate traps which can be used to implement them in software instead.
+ */
+CPU_DISASSEMBLE(clipper)
+{
+ u16 *insn = (u16 *)oprom;
+ u32 flags = DASMFLAG_SUPPORTED;
+ offs_t bytes;
+
+ switch (insn[0] >> 8)
+ {
+ case 0x00:
+ if (oprom[0] == 0)
+ util::stream_format(stream, "noop");
+ else
+ util::stream_format(stream, "noop $%d", oprom[0]);
+ bytes = 2;
+ break;
+
+ case 0x10: util::stream_format(stream, "movwp r%d,%s", R2, R1 == 0 ? "psw" : R1 == 1 ? "ssw" : "sswf"); bytes = 2; break;
+ case 0x11: util::stream_format(stream, "movpw %s,r%d", R1 == 0 ? "psw" : "ssw", R2); bytes = 2; break;
+ case 0x12: util::stream_format(stream, "calls $%d", insn[0] & 0x7F); bytes = 2; flags |= DASMFLAG_STEP_OVER; break;
+ case 0x13: util::stream_format(stream, "ret r%d", R2); bytes = 2; flags |= DASMFLAG_STEP_OUT; break;
+ case 0x14: util::stream_format(stream, "pushw r%d,r%d", R2, R1); bytes = 2; break;
+
+ case 0x16: util::stream_format(stream, "popw r%d,r%d", R1, R2); bytes = 2; break;
+
+ case 0x20: util::stream_format(stream, "adds f%d,f%d", R1, R2); bytes = 2; break;
+ case 0x21: util::stream_format(stream, "subs f%d,f%d", R1, R2); bytes = 2; break;
+ case 0x22: util::stream_format(stream, "addd f%d,f%d", R1, R2); bytes = 2; break;
+ case 0x23: util::stream_format(stream, "subd f%d,f%d", R1, R2); bytes = 2; break;
+ case 0x24: util::stream_format(stream, "movs f%d,f%d", R1, R2); bytes = 2; break;
+ case 0x25: util::stream_format(stream, "cmps f%d,f%d", R1, R2); bytes = 2; break;
+ case 0x26: util::stream_format(stream, "movd f%d,f%d", R1, R2); bytes = 2; break;
+ case 0x27: util::stream_format(stream, "cmpd f%d,f%d", R1, R2); bytes = 2; break;
+ case 0x28: util::stream_format(stream, "muls f%d,f%d", R1, R2); bytes = 2; break;
+ case 0x29: util::stream_format(stream, "divs f%d,f%d", R1, R2); bytes = 2; break;
+ case 0x2a: util::stream_format(stream, "muld f%d,f%d", R1, R2); bytes = 2; break;
+ case 0x2b: util::stream_format(stream, "divd f%d,f%d", R1, R2); bytes = 2; break;
+ case 0x2c: util::stream_format(stream, "movsw f%d,r%d", R1, R2); bytes = 2; break;
+ case 0x2d: util::stream_format(stream, "movws r%d,f%d", R1, R2); bytes = 2; break;
+ case 0x2e: util::stream_format(stream, "movdl f%d,r%d:%d", R1, R2 + 0, R2 + 1); bytes = 2; break;
+ case 0x2f: util::stream_format(stream, "movld r%d:r%d,f%d", R1 + 0, R1 + 1, R2); bytes = 2; break;
+
+ case 0x30: util::stream_format(stream, "shaw r%d,r%d", R1, R2); bytes = 2; break;
+ case 0x31: util::stream_format(stream, "shal r%d,r%d:r%d", R1, R2 + 0, R2 + 1); bytes = 2; break;
+ case 0x32: util::stream_format(stream, "shlw r%d,r%d", R1, R2); bytes = 2; break;
+ case 0x33: util::stream_format(stream, "shll r%d,r%d:r%d", R1, R2 + 0, R2 + 1); bytes = 2; break;
+ case 0x34: util::stream_format(stream, "rotw r%d,r%d", R1, R2); bytes = 2; break;
+ case 0x35: util::stream_format(stream, "rotl r%d,r%d:r%d", R1, R2 + 0, R2 + 1); bytes = 2; break;
+
+ case 0x38: util::stream_format(stream, "shai $%d,r%d", I16, R2); bytes = 4; break;
+ case 0x39: util::stream_format(stream, "shali $%d,r%d:r%d", I16, R2 + 0, R2 + 1); bytes = 4; break;
+ case 0x3a: util::stream_format(stream, "shli $%d,r%d", I16, R2); bytes = 4; break;
+ case 0x3b: util::stream_format(stream, "shlli $%d,r%d:r%d", I16, R2 + 0, R2 + 1); bytes = 4; break;
+ case 0x3c: util::stream_format(stream, "roti $%d,r%d", I16, R2); bytes = 4; break;
+ case 0x3d: util::stream_format(stream, "rotli $%d,r%d:r%d", I16, R2 + 0, R2 + 1); bytes = 4; break;
+
+ case 0x44: util::stream_format(stream, "call r%d,(r%d)", R2, R1); bytes = 2; flags |= DASMFLAG_STEP_OVER; break;
+ case 0x45: util::stream_format(stream, "call r%d,%s", ADDR_R2, address(pc, insn)); bytes = 2 + ADDR_SIZE; flags |= DASMFLAG_STEP_OVER; break;
+#if C400_INSTRUCTIONS
+ case 0x46: util::stream_format(stream, "loadd2 (r%d),f%d", R1, R2); bytes = 2; break;
+ case 0x47: util::stream_format(stream, "loadd2 %s,f%d", address(pc, insn), ADDR_R2); bytes = 2 + ADDR_SIZE; break;
+#endif
+ case 0x48: util::stream_format(stream, "b%-4s (r%d)", cc[R2], R1); bytes = 2; break;
+ case 0x49: util::stream_format(stream, "b%-4s %s", cc[ADDR_R2], address(pc, insn)); bytes = 2 + ADDR_SIZE; break;
+#if C400_INSTRUCTIONS
+ // delayed branches
+ case 0x4a: util::stream_format(stream, "cdb r%d,(r%d)", R2, R1); bytes = 2; break;
+ case 0x4b: util::stream_format(stream, "cdb r%d,%s", ADDR_R2, address(pc, insn)); bytes = 2 + ADDR_SIZE; break;
+ case 0x4c: util::stream_format(stream, "cdbeq r%d,(r%d)", R2, R1); bytes = 2; break;
+ case 0x4d: util::stream_format(stream, "cdbeq r%d,%s", ADDR_R2, address(pc, insn)); bytes = 2 + ADDR_SIZE; break;
+ case 0x4e: util::stream_format(stream, "cdbne r%d,(r%d)", R2, R1); bytes = 2; break;
+ case 0x4f: util::stream_format(stream, "cdbne r%d,%s", ADDR_R2, address(pc, insn)); bytes = 2 + ADDR_SIZE; break;
+ case 0x50: util::stream_format(stream, "db%-4s (r%d)", cc[R2], R1); bytes = 2; break;
+ case 0x51: util::stream_format(stream, "db%-4s %s", cc[ADDR_R2], address(pc, insn)); bytes = 2 + ADDR_SIZE; break;
+#else
+ // these instructions are in the C300 documentation, but appear to be replaced in the C400
+ case 0x4c: util::stream_format(stream, "bf%s (r%d)", R2 == 0 ? "any" : "bad", R1); bytes = 2; break;
+ case 0x4d: util::stream_format(stream, "bf%s %s", ADDR_R2 == 0 ? "any" : "bad", address(pc, insn)); bytes = 2 + ADDR_SIZE; break;
+#endif
+
+ case 0x60: util::stream_format(stream, "loadw (r%d),r%d", R1, R2); bytes = 2; break;
+ case 0x61: util::stream_format(stream, "loadw %s,r%d", address(pc, insn), ADDR_R2); bytes = 2 + ADDR_SIZE; break;
+ case 0x62: util::stream_format(stream, "loada (r%d),r%d", R1, R2); bytes = 2; break;
+ case 0x63: util::stream_format(stream, "loada %s,r%d", address(pc, insn), ADDR_R2); bytes = 2 + ADDR_SIZE; break;
+ case 0x64: util::stream_format(stream, "loads (r%d),f%d", R1, R2); bytes = 2; break;
+ case 0x65: util::stream_format(stream, "loads %s,f%d", address(pc, insn), ADDR_R2); bytes = 2 + ADDR_SIZE; break;
+ case 0x66: util::stream_format(stream, "loadd (r%d),f%d", R1, R2); bytes = 2; break;
+ case 0x67: util::stream_format(stream, "loadd %s,f%d", address(pc, insn), ADDR_R2); bytes = 2 + ADDR_SIZE; break;
+ case 0x68: util::stream_format(stream, "loadb (r%d),r%d", R1, R2); bytes = 2; break;
+ case 0x69: util::stream_format(stream, "loadb %s,r%d", address(pc, insn), ADDR_R2); bytes = 2 + ADDR_SIZE; break;
+ case 0x6a: util::stream_format(stream, "loadbu (r%d),r%d", R1, R2); bytes = 2; break;
+ case 0x6b: util::stream_format(stream, "loadbu %s,r%d", address(pc, insn), ADDR_R2); bytes = 2 + ADDR_SIZE; break;
+ case 0x6c: util::stream_format(stream, "loadh (r%d),r%d", R1, R2); bytes = 2; break;
+ case 0x6d: util::stream_format(stream, "loadh %s,r%d", address(pc, insn), ADDR_R2); bytes = 2 + ADDR_SIZE; break;
+ case 0x6e: util::stream_format(stream, "loadhu (r%d),r%d", R1, R2); bytes = 2; break;
+ case 0x6f: util::stream_format(stream, "loadhu %s,r%d", address(pc, insn), ADDR_R2); bytes = 2 + ADDR_SIZE; break;
+
+ case 0x70: util::stream_format(stream, "storw r%d,(r%d)", R2, R1); bytes = 2; break;
+ case 0x71: util::stream_format(stream, "storw r%d,%s", ADDR_R2, address(pc, insn)); bytes = 2 + ADDR_SIZE; break;
+ case 0x72: util::stream_format(stream, "tsts (r%d),r%d", R1, R2); bytes = 2; break;
+ case 0x73: util::stream_format(stream, "tsts %s,r%d", address(pc, insn), ADDR_R2); bytes = 2 + ADDR_SIZE; break;
+ case 0x74: util::stream_format(stream, "stors f%d,(r%d)", R2, R1); bytes = 2; break;
+ case 0x75: util::stream_format(stream, "stors f%d,%s", ADDR_R2, address(pc, insn)); bytes = 2 + ADDR_SIZE; break;
+ case 0x76: util::stream_format(stream, "stord f%d,(r%d)", R2, R1); bytes = 2; break;
+ case 0x77: util::stream_format(stream, "stord f%d,%s", ADDR_R2, address(pc, insn)); bytes = 2 + ADDR_SIZE; break;
+ case 0x78: util::stream_format(stream, "storb r%d,(r%d)", R2, R1); bytes = 2; break;
+ case 0x79: util::stream_format(stream, "storb r%d,%s", ADDR_R2, address(pc, insn)); bytes = 2 + ADDR_SIZE; break;
+
+ case 0x7c: util::stream_format(stream, "storh r%d,(r%d)", R2, R1); bytes = 2; break;
+ case 0x7d: util::stream_format(stream, "storh r%d,%s", ADDR_R2, address(pc, insn)); bytes = 2 + ADDR_SIZE; break;
+
+ case 0x80: util::stream_format(stream, "addw r%d,r%d", R1, R2); bytes = 2; break;
+
+ case 0x82: util::stream_format(stream, "addq $%d,r%d", R1, R2); bytes = 2; break;
+ case 0x83: util::stream_format(stream, "addi $%d,r%d", IMM_VALUE, R2); bytes = 2 + IMM_SIZE; break;
+ case 0x84: util::stream_format(stream, "movw r%d,r%d", R1, R2); bytes = 2; break;
+
+ case 0x86: util::stream_format(stream, "loadq $%d,r%d", R1, R2); bytes = 2; break;
+ case 0x87: util::stream_format(stream, "loadi $%d,r%d", IMM_VALUE, R2); bytes = 2 + IMM_SIZE; break;
+ case 0x88: util::stream_format(stream, "andw r%d,r%d", R1, R2); bytes = 2; break;
+
+ case 0x8b: util::stream_format(stream, "andi $%d,r%d", IMM_VALUE, R2); bytes = 2 + IMM_SIZE; break;
+ case 0x8c: util::stream_format(stream, "orw r%d,r%d", R1, R2); bytes = 2; break;
+
+ case 0x8f: util::stream_format(stream, "ori $%d,r%d", IMM_VALUE, R2); bytes = 2 + IMM_SIZE; break;
+
+ case 0x90: util::stream_format(stream, "addwc r%d,r%d", R1, R2); bytes = 2; break;
+ case 0x91: util::stream_format(stream, "subwc r%d,r%d", R1, R2); bytes = 2; break;
+
+ case 0x93: util::stream_format(stream, "negw r%d,r%d", R1, R2); bytes = 2; break;
+
+ case 0x98: util::stream_format(stream, "mulw r%d,r%d", R1, R2); bytes = 2; break;
+ case 0x99: util::stream_format(stream, "mulwx r%d,r%d:r%d", R1, R2 + 0, R2 + 1); bytes = 2; break;
+ case 0x9a: util::stream_format(stream, "mulwu r%d,r%d", R1, R2); bytes = 2; break;
+ case 0x9b: util::stream_format(stream, "mulwux r%d,r%d:r%d", R1, R2 + 0, R2 + 1); bytes = 2; break;
+ case 0x9c: util::stream_format(stream, "divw r%d,r%d", R1, R2); bytes = 2; break;
+ case 0x9d: util::stream_format(stream, "modw r%d,r%d", R1, R2); bytes = 2; break;
+ case 0x9e: util::stream_format(stream, "divwu r%d,r%d", R1, R2); bytes = 2; break;
+ case 0x9f: util::stream_format(stream, "modwu r%d,r%d", R1, R2); bytes = 2; break;
+
+ case 0xa0: util::stream_format(stream, "subw r%d,r%d", R1, R2); bytes = 2; break;
+
+ case 0xa2: util::stream_format(stream, "subq $%d,r%d", R1, R2); bytes = 2; break;
+ case 0xa3: util::stream_format(stream, "subi $%d,r%d", IMM_VALUE, R2); bytes = 2 + IMM_SIZE; break;
+ case 0xa4: util::stream_format(stream, "cmpw r%d,r%d", R1, R2); bytes = 2; break;
+
+ case 0xa6: util::stream_format(stream, "cmpq $%d,r%d", R1, R2); bytes = 2; break;
+ case 0xa7: util::stream_format(stream, "cmpi $%d,r%d", IMM_VALUE, R2); bytes = 2 + IMM_SIZE; break;
+ case 0xa8: util::stream_format(stream, "xorw r%d,r%d", R1, R2); bytes = 2; break;
+
+ case 0xab: util::stream_format(stream, "xori $%d,r%d", IMM_VALUE, R2); bytes = 2 + IMM_SIZE; break;
+ case 0xac: util::stream_format(stream, "notw r%d,r%d", R1, R2); bytes = 2; break;
+
+ case 0xae: util::stream_format(stream, "notq $%d,r%d", R1, R2); bytes = 2; break;
+
+#if C400_INSTRUCTIONS
+ case 0xb0: util::stream_format(stream, "abss f%d,f%d", R1, R2); bytes = 2; break;
+ case 0xb2: util::stream_format(stream, "absd f%d,f%d", R1, R2); bytes = 2; break;
+#endif
+
+ case 0xb4:
+ case 0xb5:
+ // unprivileged macro instructions
+ switch (insn[0] & 0xff)
+ {
+ case 0x00: case 0x01: case 0x02: case 0x03:
+ case 0x04: case 0x05: case 0x06: case 0x07:
+ case 0x08: case 0x09: case 0x0a: case 0x0b:
+ case 0x0c:
+ util::stream_format(stream, "savew%d", R2);
+ break;
+
+ case 0x0d: util::stream_format(stream, "movc"); break;
+ case 0x0e: util::stream_format(stream, "initc"); break;
+ case 0x0f: util::stream_format(stream, "cmpc"); break;
+
+ case 0x10: case 0x11: case 0x12: case 0x13:
+ case 0x14: case 0x15: case 0x16: case 0x17:
+ case 0x18: case 0x19: case 0x1a: case 0x1b:
+ case 0x1c:
+ util::stream_format(stream, "restw%d", R2);
+ break;
+
+ case 0x20: case 0x21: case 0x22: case 0x23:
+ case 0x24: case 0x25: case 0x26: case 0x27:
+ util::stream_format(stream, "saved%d", R2);
+ break;
+
+ case 0x28: case 0x29: case 0x2a: case 0x2b:
+ case 0x2c: case 0x2d: case 0x2e: case 0x2f:
+ util::stream_format(stream, "restd%d", R2);
+ break;
+
+ case 0x30: util::stream_format(stream, "cnvsw f%d,r%d", (insn[1] & 0xf0) >> 4, insn[1] & 0xf); break;
+ case 0x31: util::stream_format(stream, "cnvrsw f%d,r%d", (insn[1] & 0xf0) >> 4, insn[1] & 0xf); break;
+ case 0x32: util::stream_format(stream, "cnvtsw f%d,r%d", (insn[1] & 0xf0) >> 4, insn[1] & 0xf); break;
+ case 0x33: util::stream_format(stream, "cnvws r%d,f%d", (insn[1] & 0xf0) >> 4, insn[1] & 0xf); break;
+ case 0x34: util::stream_format(stream, "cnvdw f%d,r%d", (insn[1] & 0xf0) >> 4, insn[1] & 0xf); break;
+ case 0x35: util::stream_format(stream, "cnvrdw f%d,r%d", (insn[1] & 0xf0) >> 4, insn[1] & 0xf); break;
+ case 0x36: util::stream_format(stream, "cnvtdw f%d,r%d", (insn[1] & 0xf0) >> 4, insn[1] & 0xf); break;
+ case 0x37: util::stream_format(stream, "cnvwd r%d,f%d", (insn[1] & 0xf0) >> 4, insn[1] & 0xf); break;
+ case 0x38: util::stream_format(stream, "cnvsd f%d,f%d", (insn[1] & 0xf0) >> 4, insn[1] & 0xf); break;
+ case 0x39: util::stream_format(stream, "cnvds f%d,f%d", (insn[1] & 0xf0) >> 4, insn[1] & 0xf); break;
+ case 0x3a: util::stream_format(stream, "negs f%d,f%d", (insn[1] & 0xf0) >> 4, insn[1] & 0xf); break;
+ case 0x3b: util::stream_format(stream, "negd f%d,f%d", (insn[1] & 0xf0) >> 4, insn[1] & 0xf); break;
+ case 0x3c: util::stream_format(stream, "scalbs r%d,f%d", (insn[1] & 0xf0) >> 4, insn[1] & 0xf); break;
+ case 0x3d: util::stream_format(stream, "scalbd r%d,f%d", (insn[1] & 0xf0) >> 4, insn[1] & 0xf); break;
+ case 0x3e: util::stream_format(stream, "trapfn"); break;
+ case 0x3f: util::stream_format(stream, "loadfs r%d,f%d", (insn[1] & 0xf0) >> 4, insn[1] & 0xf); break;
+
+ default:
+ util::stream_format(stream, "macro 0x%04x 0x%04x", insn[0], insn[1]);
+ break;
+ }
+ bytes = 4;
+ break;
+ case 0xb6:
+ case 0xb7:
+ // privileged macro instructions
+ switch (insn[0] & 0xff)
+ {
+ case 0x00: util::stream_format(stream, "movus r%d,r%d", (insn[1] & 0xf0) >> 4, insn[1] & 0xf); break;
+ case 0x01: util::stream_format(stream, "movsu r%d,r%d", (insn[1] & 0xf0) >> 4, insn[1] & 0xf); break;
+ case 0x02: util::stream_format(stream, "saveur r%d", (insn[1] & 0xf0) >> 4); break;
+ case 0x03: util::stream_format(stream, "restur r%d", (insn[1] & 0xf0) >> 4); break;
+ case 0x04: util::stream_format(stream, "reti r%d", (insn[1] & 0xf0) >> 4); flags |= DASMFLAG_STEP_OUT; break;
+ case 0x05: util::stream_format(stream, "wait"); break;
+#if C400_INSTRUCTIONS
+ case 0x07: util::stream_format(stream, "loadts r%d,f%d", (insn[1] & 0xf0) >> 4, insn[1] & 0xf); break;
+#endif
+ default:
+ util::stream_format(stream, "macro 0x%04x 0x%04x", insn[0], insn[1]);
+ break;
+ }
+ bytes = 4;
+ break;
+
+#if C400_INSTRUCTIONS
+ case 0xbc: util::stream_format(stream, "waitd"); bytes = 2; break;
+ case 0xc0: util::stream_format(stream, "s%-4s r%d", cc[R2], R1); bytes = 2; break;
+#endif
+
+ default:
+ util::stream_format(stream, ".word 0x%04x", insn[0]);
+ bytes = 2;
+ break;
+ }
+
+ return bytes | flags;
+} \ No newline at end of file