summaryrefslogtreecommitdiffstatshomepage
path: root/trunk/src/emu/cpu/dsp16/dsp16dis.c
diff options
context:
space:
mode:
Diffstat (limited to 'trunk/src/emu/cpu/dsp16/dsp16dis.c')
-rw-r--r--trunk/src/emu/cpu/dsp16/dsp16dis.c567
1 files changed, 567 insertions, 0 deletions
diff --git a/trunk/src/emu/cpu/dsp16/dsp16dis.c b/trunk/src/emu/cpu/dsp16/dsp16dis.c
new file mode 100644
index 00000000000..1c8ab0f0c7a
--- /dev/null
+++ b/trunk/src/emu/cpu/dsp16/dsp16dis.c
@@ -0,0 +1,567 @@
+#include "emu.h"
+#include "dsp16.h"
+
+astring disasmF1Field(const UINT8& F1, const UINT8& D, const UINT8& S)
+{
+ astring ret = "";
+ switch (F1)
+ {
+ case 0x00: ret.printf("a%d = p, p = x*y", D); break;
+ case 0x01: ret.printf("a%d = a%d + p, p = x*y", D, S); break;
+ case 0x02: ret.printf("p = x*y"); break;
+ case 0x03: ret.printf("a%d = a%d - p, p = x*y", D, S); break;
+ case 0x04: ret.printf("a$d = p", D); break;
+ case 0x05: ret.printf("a%d = a%d + p", D, S); break;
+ case 0x06: ret.printf("NOP"); break;
+ case 0x07: ret.printf("a%d = a%d - p", D, S); break;
+ case 0x08: ret.printf("a%d = a%d | y", D, S); break;
+ case 0x09: ret.printf("a%d = a%d ^ y", D, S); break;
+ case 0x0a: ret.printf("a%d & y", S); break;
+ case 0x0b: ret.printf("a%d - y", S); break;
+ case 0x0c: ret.printf("a%d = y", D); break;
+ case 0x0d: ret.printf("a%d = a%d + y", D, S); break;
+ case 0x0e: ret.printf("a%d = a%d & y", D, S); break;
+ case 0x0f: ret.printf("a%d = a%d - y", D, S); break;
+
+ default: return "UNKNOWN";
+ }
+ return ret;
+}
+
+astring disasmYField(const UINT8& Y)
+{
+ switch (Y)
+ {
+ case 0x00: return "*r0";
+ case 0x01: return "*r0++";
+ case 0x02: return "*r0--";
+ case 0x03: return "*r0++j";
+
+ case 0x04: return "*r1";
+ case 0x05: return "*r1++";
+ case 0x06: return "*r1--";
+ case 0x07: return "*r1++j";
+
+ case 0x08: return "*r2";
+ case 0x09: return "*r2++";
+ case 0x0a: return "*r2--";
+ case 0x0b: return "*r2++j";
+
+ case 0x0c: return "*r3";
+ case 0x0d: return "*r3++";
+ case 0x0e: return "*r3--";
+ case 0x0f: return "*r3++j";
+
+ default: return "UNKNOWN";
+ }
+ return "";
+}
+
+astring disasmZField(const UINT8& Z)
+{
+ switch (Z)
+ {
+ case 0x00: return "*r0zp";
+ case 0x01: return "*r0pz";
+ case 0x02: return "*r0m2";
+ case 0x03: return "*r0jk";
+
+ case 0x04: return "*r1zp";
+ case 0x05: return "*r1pz";
+ case 0x06: return "*r1m2";
+ case 0x07: return "*r1jk";
+
+ case 0x08: return "*r2zp";
+ case 0x09: return "*r2pz";
+ case 0x0a: return "*r2m2";
+ case 0x0b: return "*r2jk";
+
+ case 0x0c: return "*r3zp";
+ case 0x0d: return "*r3pz";
+ case 0x0e: return "*r3m2";
+ case 0x0f: return "*r3jk";
+
+ default: return "UNKNOWN";
+ }
+ return "";
+}
+
+astring disasmF2Field(const UINT8& F2, const UINT8& D, const UINT8& S)
+{
+ astring ret = "";
+ switch (F2)
+ {
+ case 0x00: ret.printf("a%d = a%d >> 1", D, S); break;
+ case 0x01: ret.printf("a%d = a%d << 1", D, S); break;
+ case 0x02: ret.printf("a%d = a%d >> 4", D, S); break;
+ case 0x03: ret.printf("a%d = a%d << 4", D, S); break;
+ case 0x04: ret.printf("a%d = a%d >> 8", D, S); break;
+ case 0x05: ret.printf("a%d = a%d << 8", D, S); break;
+ case 0x06: ret.printf("a%d = a%d >> 16", D, S); break;
+ case 0x07: ret.printf("a%d = a%d << 16", D, S); break;
+
+ case 0x08: ret.printf("a%d = p", D); break;
+ case 0x09: ret.printf("a%dh = a%dh + 1", D, S); break;
+ case 0x0a: ret.printf("RESERVED"); break;
+ case 0x0b: ret.printf("a%d = rnd(a%d)", D, S); break;
+ case 0x0c: ret.printf("a%d = y", D); break;
+ case 0x0d: ret.printf("a%d = a%d + 1", D, S); break;
+ case 0x0e: ret.printf("a%d = a%d", D, S); break;
+ case 0x0f: ret.printf("a%d = -a%d", D, S); break;
+
+ default: return "UNKNOWN";
+ }
+ return "";
+}
+
+astring disasmCONField(const UINT8& CON)
+{
+ switch (CON)
+ {
+ case 0x00: return "mi";
+ case 0x01: return "pl";
+ case 0x02: return "eq";
+ case 0x03: return "ne";
+ case 0x04: return "lvs";
+ case 0x05: return "lvc";
+ case 0x06: return "mvs";
+ case 0x07: return "mvc";
+ case 0x08: return "heads";
+ case 0x09: return "tails";
+ case 0x0a: return "c0ge";
+ case 0x0b: return "c0lt";
+ case 0x0c: return "c1ge";
+ case 0x0d: return "c1lt";
+ case 0x0e: return "true";
+ case 0x0f: return "false";
+ case 0x10: return "gt";
+ case 0x11: return "le";
+
+ default: return "RESERVED";
+ }
+ return "";
+}
+
+astring disasmBField(const UINT8& B)
+{
+ switch (B)
+ {
+ case 0x00: return "return";
+ case 0x01: return "ireturn";
+ case 0x02: return "goto pt";
+ case 0x03: return "call pt";
+ case 0x04:
+ case 0x05:
+ case 0x06:
+ case 0x07: return "RESERVED";
+
+ default: return "UNKNOWN";
+ }
+ return "";
+}
+
+astring disasmRImmediateField(const UINT8& R)
+{
+ switch (R)
+ {
+ case 0x00: return "j";
+ case 0x01: return "k";
+ case 0x02: return "rb";
+ case 0x03: return "re";
+ case 0x04: return "r0";
+ case 0x05: return "r1";
+ case 0x06: return "r2";
+ case 0x07: return "r3";
+
+ default: return "UNKNOWN";
+ }
+ return "";
+}
+
+astring disasmRField(const UINT8& R)
+{
+ switch (R)
+ {
+ case 0x00: return "r0";
+ case 0x01: return "r1";
+ case 0x02: return "r2";
+ case 0x03: return "r3";
+ case 0x04: return "j";
+ case 0x05: return "k";
+ case 0x06: return "rb";
+ case 0x07: return "re";
+ case 0x08: return "pt";
+ case 0x09: return "pr";
+ case 0x0a: return "pi";
+ case 0x0b: return "i";
+
+ case 0x10: return "x";
+ case 0x11: return "y";
+ case 0x12: return "yl";
+ case 0x13: return "auc";
+ case 0x14: return "psw";
+ case 0x15: return "c0";
+ case 0x16: return "c1";
+ case 0x17: return "c2";
+ case 0x18: return "soic";
+ case 0x19: return "srta";
+ case 0x1a: return "sdx";
+ case 0x1b: return "tdms";
+ case 0x1c: return "pioc";
+ case 0x1d: return "pdx0";
+ case 0x1e: return "pdx1";
+
+ default: return "RESERVED";
+ }
+ return "";
+}
+
+astring disasmIField(const UINT8& I)
+{
+ switch (I)
+ {
+ case 0x00: return "r0/j";
+ case 0x01: return "r1/k";
+ case 0x02: return "r2/rb";
+ case 0x03: return "r3/re";
+
+ default: return "UNKNOWN";
+ }
+ return "";
+}
+
+bool disasmSIField(const UINT8& SI)
+{
+ switch (SI)
+ {
+ case 0x00: return 0; // Not a software interrupt
+ case 0x01: return 1; // Software Interrupt
+ }
+ return false;
+}
+
+
+/* execute instructions on this CPU until icount expires */
+CPU_DISASSEMBLE( dsp16a )
+{
+ UINT8 opSize = 1;
+ UINT32 dasmflags = 0;
+ UINT16 op = oprom[0] | (oprom[1] << 8);
+ UINT16 op2 = oprom[2] | (oprom[3] << 8);
+
+ // TODO: Test for previous "if CON" instruction and tab the next instruction in?
+
+ const UINT8 opcode = (op >> 11) & 0x1f;
+ switch(opcode)
+ {
+ // Format 1: Multiply/ALU Read/Write Group
+ case 0x06:
+ {
+ // F1, Y
+ const UINT8 Y = (op & 0x000f);
+ const UINT8 S = (op & 0x0200) >> 9;
+ const UINT8 D = (op & 0x0400) >> 10;
+ const UINT8 F1 = (op & 0x01e0) >> 5;
+ astring yString = disasmYField(Y);
+ astring fString = disasmF1Field(F1, D, S);
+ sprintf(buffer, "%s, %s", fString.cstr(), yString.cstr());
+ break;
+ }
+ case 0x04: case 0x1c:
+ {
+ // F1 Y=a0[1] | F1 Y=a1[1]
+ const UINT8 Y = (op & 0x000f);
+ const UINT8 S = (op & 0x0200) >> 9;
+ const UINT8 D = (op & 0x0400) >> 10;
+ const UINT8 F1 = (op & 0x01e0) >> 5;
+ astring yString = disasmYField(Y);
+ astring fString = disasmF1Field(F1, D, S);
+ astring aString = (opcode == 0x1c) ? "a0" : "a1";
+ sprintf(buffer, "%s = %s, %s", yString.cstr(), aString.cstr(), fString.cstr());
+ break;
+ }
+ case 0x16:
+ {
+ // F1, x = Y
+ const UINT8 Y = (op & 0x000f);
+ const UINT8 S = (op & 0x0200) >> 9;
+ const UINT8 D = (op & 0x0400) >> 10;
+ const UINT8 F1 = (op & 0x01e0) >> 5;
+ astring yString = disasmYField(Y);
+ astring fString = disasmF1Field(F1, D, S);
+ sprintf(buffer, "%s, x = %s", fString.cstr(), yString.cstr());
+ break;
+ }
+ case 0x17:
+ {
+ // F1, y[l] = Y
+ const UINT8 Y = (op & 0x000f);
+ const UINT8 X = (op & 0x0010) >> 4;
+ const UINT8 S = (op & 0x0200) >> 9;
+ const UINT8 D = (op & 0x0400) >> 10;
+ const UINT8 F1 = (op & 0x01e0) >> 5;
+ astring yString = disasmYField(Y);
+ astring fString = disasmF1Field(F1, D, S);
+ astring xString = (X ? "y" : "y1");
+ sprintf(buffer, "%s, %s = %s", fString.cstr(), xString.cstr(), yString.cstr());
+ break;
+ }
+ case 0x1f:
+ {
+ // F1, y = Y, x = *pt++[i]
+ const UINT8 Y = (op & 0x000f);
+ const UINT8 X = (op & 0x0010) >> 4;
+ const UINT8 S = (op & 0x0200) >> 9;
+ const UINT8 D = (op & 0x0400) >> 10;
+ const UINT8 F1 = (op & 0x01e0) >> 5;
+ astring yString = disasmYField(Y);
+ astring fString = disasmF1Field(F1, D, S);
+ astring xString = (X ? "*pt++i" : "*pt++");
+ sprintf(buffer, "%s, y = %s, x = %s", fString.cstr(), yString.cstr(), xString.cstr());
+ break;
+ }
+ case 0x19: case 0x1b:
+ {
+ // F1, y = a0|1, x = *pt++[i]
+ const UINT8 Y = (op & 0x000f);
+ const UINT8 X = (op & 0x0010) >> 4;
+ const UINT8 S = (op & 0x0200) >> 9;
+ const UINT8 D = (op & 0x0400) >> 10;
+ const UINT8 F1 = (op & 0x01e0) >> 5;
+ astring fString = disasmF1Field(F1, D, S);
+ astring xString = (X ? "*pt++i" : "*pt++");
+ astring aString = (opcode == 0x19) ? "a0" : "a1";
+ sprintf(buffer, "%s, y = %s, x = %s", fString.cstr(), aString.cstr(), xString.cstr());
+ if (Y != 0x00) sprintf(buffer, "UNKNOWN");
+ break;
+ }
+ case 0x14:
+ {
+ // F1, Y = y[1]
+ const UINT8 Y = (op & 0x000f);
+ const UINT8 X = (op & 0x0010) >> 4;
+ const UINT8 S = (op & 0x0200) >> 9;
+ const UINT8 D = (op & 0x0400) >> 10;
+ const UINT8 F1 = (op & 0x01e0) >> 5;
+ astring yString = disasmYField(Y);
+ astring xString = (X ? "y" : "y1");
+ astring fString = disasmF1Field(F1, D, S);
+ sprintf(buffer, "%s, %s = %s", fString.cstr(), yString.cstr(), xString.cstr());
+ break;
+ }
+
+ // Format 1a: Multiply/ALU Read/Write Group (major typo in docs on p3-51)
+ case 0x07:
+ {
+ // F1, At[1] = Y
+ const UINT8 Y = (op & 0x000f);
+ const UINT8 S = (op & 0x0200) >> 9;
+ const UINT8 aT = (op & 0x0400) >> 10;
+ const UINT8 F1 = (op & 0x01e0) >> 5;
+ astring yString = disasmYField(Y);
+ astring atString = (aT ? "a0" : "a1");
+ astring fString = disasmF1Field(F1, aT, S);
+ sprintf(buffer, "%s, %s = %s", fString.cstr(), atString.cstr(), yString.cstr());
+ break;
+ }
+
+ // Format 2: Multiply/ALU Read/Write Group
+ case 0x15:
+ {
+ // F1, Z : y[1]
+ const UINT8 Z = (op & 0x000f);
+ const UINT8 X = (op & 0x0010) >> 4;
+ const UINT8 S = (op & 0x0200) >> 9;
+ const UINT8 D = (op & 0x0400) >> 10;
+ const UINT8 F1 = (op & 0x01e0) >> 5;
+ astring zString = disasmZField(Z);
+ astring xString = (X ? "y" : "y1");
+ astring fString = disasmF1Field(F1, D, S);
+ sprintf(buffer, "%s, %s <=> %s", fString.cstr(), xString.cstr(), zString.cstr());
+ break;
+ }
+ case 0x1d:
+ {
+ // F1, Z : y, x=*pt++[i]
+ const UINT8 Z = (op & 0x000f);
+ const UINT8 X = (op & 0x0010) >> 4;
+ const UINT8 S = (op & 0x0200) >> 9;
+ const UINT8 D = (op & 0x0400) >> 10;
+ const UINT8 F1 = (op & 0x01e0) >> 5;
+ astring zString = disasmZField(Z);
+ astring xString = (X ? "*pt++i" : "*pt++");
+ astring fString = disasmF1Field(F1, D, S);
+ sprintf(buffer, "%s, %s <=> y, x = %s", fString.cstr(), zString.cstr(), xString.cstr());
+ break;
+ }
+
+ // Format 2a: Multiply/ALU Read/Write Group
+ case 0x05:
+ {
+ // F1, Z : aT[1]
+ const UINT8 Z = (op & 0x000f);
+ const UINT8 X = (op & 0x0010) >> 4;
+ const UINT8 S = (op & 0x0200) >> 9;
+ const UINT8 aT = (op & 0x0400) >> 10;
+ const UINT8 F1 = (op & 0x01e0) >> 5;
+ astring zString = disasmZField(Z);
+ astring atString = (aT ? "a0" : "a1");
+ atString += X ? "" : "1"; // TODO: Figure out unclear wording.
+ astring fString = disasmF1Field(F1, aT, S);
+ sprintf(buffer, "%s, %s <=> %s", fString.cstr(), zString.cstr(), atString.cstr());
+ break;
+ }
+
+ // Format 3: Special Functions
+ case 0x12:
+ case 0x13:
+ {
+ // if|ifc CON F2
+ const UINT8 CON = (op & 0x001f);
+ const UINT8 S = (op & 0x0200) >> 9;
+ const UINT8 D = (op & 0x0400) >> 10;
+ const UINT8 F2 = (op & 0x01e0) >> 5;
+ astring fString = disasmF2Field(F2, D, S);
+ astring conString = disasmCONField(CON);
+ if (op & 0x0800) sprintf(buffer, "if %s : %s", conString.cstr(), fString.cstr());
+ else sprintf(buffer, "ifc %s : %s", conString.cstr(), fString.cstr());
+ break;
+ }
+
+ // Format 4: Branch Direct Group
+ case 0x00: case 0x01:
+ case 0x10: case 0x11:
+ {
+ // goto|call JA
+ const UINT16 JA = (op & 0x0fff) | (pc & 0xf000);
+ if (op & 0x8000) sprintf(buffer, "call 0x%04x", JA);
+ else sprintf(buffer, "goto 0x%04x", JA);
+ break;
+ }
+
+ // Format 5: Branch Indirect Group
+ case 0x18:
+ {
+ // goto B
+ const UINT8 B = (op & 0x0700) >> 8;
+ astring bString = disasmBField(B);
+ sprintf(buffer, "%s", bString.cstr());
+ break;
+ }
+
+ // Format 6: Contitional Branch Qualifier/Software Interrupt (icall)
+ case 0x1a:
+ {
+ // if CON [goto/call/return]
+ const UINT8 CON = (op & 0x001f);
+ astring conString = disasmCONField(CON);
+ sprintf(buffer, "if %s:", conString.cstr());
+ // TODO: Test for invalid ops
+ // icall
+ if (op == 0xd40e) sprintf(buffer, "icall");
+ break;
+ }
+
+ // Format 7: Data Move Group
+ case 0x09: case 0x0b:
+ {
+ // R = aS
+ const UINT8 R = (op & 0x03f0) >> 4;
+ const UINT8 S = (op & 0x1000) >> 12;
+ astring rString = disasmRField(R);
+ sprintf(buffer, "%s = %s", rString.cstr(), (S ? "a1" : "a0"));
+ break;
+ }
+ case 0x08:
+ {
+ // aT = R
+ const UINT8 R = (op & 0x03f0) >> 4;
+ const UINT8 aT = (op & 0x0400) >> 10;
+ astring rString = disasmRField(R);
+ sprintf(buffer, "%s = %s", (aT ? "a0" : "a1"), rString.cstr());
+ break;
+ }
+ case 0x0f:
+ {
+ // R = Y
+ const UINT8 Y = (op & 0x000f);
+ const UINT8 R = (op & 0x03f0) >> 4;
+ astring yString = disasmYField(Y);
+ astring rString = disasmRField(R);
+ sprintf(buffer, "%s = %s", rString.cstr(), yString.cstr());
+ // TODO: Special case the R == [y, y1, or x] case
+ break;
+ }
+ case 0x0c:
+ {
+ // Y = R
+ const UINT8 Y = (op & 0x000f);
+ const UINT8 R = (op & 0x03f0) >> 4;
+ astring yString = disasmYField(Y);
+ astring rString = disasmRField(R);
+ sprintf(buffer, "%s = %s", yString.cstr(), rString.cstr());
+ break;
+ }
+ case 0x0d:
+ {
+ // Z : R
+ const UINT8 Z = (op & 0x000f);
+ const UINT8 R = (op & 0x03f0) >> 4;
+ astring zString = disasmZField(Z);
+ astring rString = disasmRField(R);
+ sprintf(buffer, "%s <=> %s", zString.cstr(), rString.cstr());
+ break;
+ }
+
+ // Format 8: Data Move (immediate operand - 2 words)
+ case 0x0a:
+ {
+ // R = N
+ const UINT8 R = (op & 0x03f0) >> 4;
+ astring rString = disasmRField(R);
+ sprintf(buffer, "%s = 0x%x", rString.cstr(), op2);
+ opSize = 2;
+ break;
+ }
+
+ // Format 9: Short Immediate Group
+ case 0x02: case 0x03:
+ {
+ // R = M
+ const UINT8 M = (op & 0x00ff);
+ const UINT8 R = (op & 0x0e00) >> 9;
+ astring rString = disasmRImmediateField(R);
+ sprintf(buffer, "%s = 0x%02x", rString.cstr(), M);
+ break;
+ }
+
+ // Format 10: do - redo
+ case 0x0e:
+ {
+ // do|redo K
+ const UINT8 K = (op & 0x007f);
+ const UINT8 NI = (op & 0x0780) >> 7;
+ sprintf(buffer, "do (next %d inst) %d times", NI, K);
+ // TODO: Limits on K & NI
+ if (NI == 0x00)
+ sprintf(buffer, "redo %d\n", K);
+ break;
+ }
+
+ // RESERVED
+ case 0x1e:
+ {
+ sprintf(buffer, "RESERVED");
+ break;
+ }
+
+ // UNKNOWN
+ default:
+ {
+ sprintf(buffer, "UNKNOWN");
+ break;
+ }
+ }
+
+ return opSize | dasmflags | DASMFLAG_SUPPORTED;
+}