summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu/cpu/scudsp/scudspdasm.c
diff options
context:
space:
mode:
author Angelo Salese <angelosa@users.noreply.github.com>2011-09-06 19:30:24 +0000
committer Angelo Salese <angelosa@users.noreply.github.com>2011-09-06 19:30:24 +0000
commit5ff1b6aefcdcb362ed858e3f0db07f50b8ae19b8 (patch)
tree86ed376018bbb883a10cd7a7380defd3b2c78467 /src/emu/cpu/scudsp/scudspdasm.c
parent09b22beb5a2b9e81b255a4b4bb263d68b238b03f (diff)
WIP code for SCU DSP CPU core
Diffstat (limited to 'src/emu/cpu/scudsp/scudspdasm.c')
-rw-r--r--src/emu/cpu/scudsp/scudspdasm.c247
1 files changed, 247 insertions, 0 deletions
diff --git a/src/emu/cpu/scudsp/scudspdasm.c b/src/emu/cpu/scudsp/scudspdasm.c
new file mode 100644
index 00000000000..9c64a29361e
--- /dev/null
+++ b/src/emu/cpu/scudsp/scudspdasm.c
@@ -0,0 +1,247 @@
+/*
+ Sega Saturn SCU DSP disassembler
+
+ Written by Angelo Salese
+*/
+
+#include "emu.h"
+
+enum
+{
+ EA_PDST = 1,
+ EA_XDST,
+ EA_ADST,
+ EA_YDST,
+};
+
+typedef struct {
+ char mnemonic[32];
+ int address_mode;
+} SCUDSP_OPCODE;
+
+static const SCUDSP_OPCODE alu_table[16] =
+{
+ { "NOP", 0, }, /* 0000 */
+ { "AND", 0, }, /* 0001 */
+ { "OR ", 0, }, /* 0010 */
+ { "XOR", 0, }, /* 0011 */
+ { "ADD", 0, }, /* 0100 */
+ { "SUB", 0, }, /* 0101 */
+ { "AD2", 0, }, /* 0110 */
+ { "???", 0, }, /* 0111 */
+ { "SR ", 0, }, /* 1000 */
+ { "RR ", 0, }, /* 1001 */
+ { "SL ", 0, }, /* 1010 */
+ { "RL ", 0, }, /* 1011 */
+ { "???", 0, }, /* 1100 */
+ { "???", 0, }, /* 1101 */
+ { "???", 0, }, /* 1110 */
+ { "RL8", 0, }, /* 1111 */
+};
+
+static const SCUDSP_OPCODE xbus_table[] =
+{
+ { "NOP", 0, }, /* 000 */
+ { "???", 0, }, /* 001 */
+ { "MOV MUL,P", 0, }, /* 010 */
+ { "MOV", EA_PDST }, /* 011 */ //MOV %s,P
+ { "MOV", EA_XDST }, /* 100 */ //MOV %s,X
+ { "???", 0, }, /* 101 */
+ { "???", 0, }, /* 110 */
+ { "???", 0, }, /* 111 */
+};
+
+static const SCUDSP_OPCODE ybus_table[] =
+{
+ { "NOP", 0, }, /* 000 */
+ { "CLR A", 0, }, /* 001 */
+ { "MOV ALU,A", 0, }, /* 010 */
+ { "MOV", EA_ADST, }, /* 011 */ //MOV %s,A
+ { "MOV", EA_YDST, }, /* 100 */ //MOV %s,Y
+ { "???", 0, }, /* 101 */
+ { "???", 0, }, /* 110 */
+ { "???", 0, }, /* 111 */
+};
+
+static const SCUDSP_OPCODE ybus_table[] =
+{
+ { "NOP", 0, }, /* 000 */
+ { "MOV", 0, }, /* 001 */ //MOV %I8,%d
+ { "???", 0, }, /* 010 */
+ { "MOV", 0, }, /* 011 */ //MOV %S,%d
+};
+
+
+static const src_mem[] =
+{
+ "M0", /* 000 */
+ "M1", /* 001 */
+ "M2", /* 010 */
+ "M3", /* 011 */
+ "MC0", /* 100 */
+ "MC1", /* 101 */
+ "MC2", /* 110 */
+ "MC3", /* 111 */
+};
+
+/*****************************************************************************/
+
+static char *output;
+static const UINT32 *rombase;
+
+static void ATTR_PRINTF(1,2) print(const char *fmt, ...)
+{
+ va_list vl;
+
+ va_start(vl, fmt);
+ output += vsprintf(output, fmt, vl);
+ va_end(vl);
+}
+
+static UINT32 fetch(void)
+{
+ return *rombase++;
+}
+
+static UINT32 decode_opcode(UINT32 pc, const SCUDSP_OPCODE *op_table,UINT32 cur_opcode)
+{
+ INT8 rel8;
+ UINT32 imm32;
+ UINT8 op2;
+ UINT32 flags = 0;
+
+ //if (!strcmp(op_table->mnemonic, "jsr") || !strcmp(op_table->mnemonic, "bsr"))
+ // flags = DASMFLAG_STEP_OVER;
+ //else if (!strcmp(op_table->mnemonic, "rts") || !strcmp(op_table->mnemonic, "rti"))
+ // flags = DASMFLAG_STEP_OUT;
+
+ switch(op_table->address_mode)
+ {
+ case EA_PDST:
+ print("%s %s,P", op_table->mnemonic, src_mem[(cur_opcode & 0x00700000) >> 20]);
+ break;
+
+ case EA_XDST:
+ print("%s %s,X", op_table->mnemonic, src_mem[(cur_opcode & 0x00700000) >> 20]);
+ break;
+
+ case EA_ADST:
+ print("%s %s,A", op_table->mnemonic, src_mem[(cur_opcode & 0x0001c000) >> 14]);
+ break;
+
+ case EA_YDST:
+ print("%s %s,Y", op_table->mnemonic, src_mem[(cur_opcode & 0x0001c000) >> 14]);
+ break;
+
+
+ #if 0
+ case EA_IMM8:
+ imm8 = fetch();
+ print("%s 0x%02X", op_table->mnemonic, imm8);
+ break;
+
+ case EA_IMM16:
+ imm16 = fetch16();
+ print("%s 0x%04X", op_table->mnemonic, imm16);
+ break;
+
+ case EA_DIRECT:
+ imm8 = fetch();
+ print("%s (0x%04X)", op_table->mnemonic, imm8);
+ break;
+
+ case EA_EXT:
+ imm16 = fetch16();
+ print("%s (0x%04X)", op_table->mnemonic, imm16);
+ break;
+
+ case EA_IND_X:
+ imm8 = fetch();
+ print("%s (X+0x%02X)", op_table->mnemonic, imm8);
+ break;
+
+ case EA_REL:
+ rel8 = fetch();
+ print("%s [0x%04X]", op_table->mnemonic, pc+2+rel8);
+ break;
+
+ case EA_DIRECT_IMM8:
+ imm8 = fetch();
+ mask = fetch();
+ print("%s (0x%04X), 0x%02X", op_table->mnemonic, imm8, mask);
+ break;
+
+ case EA_IND_X_IMM8:
+ imm8 = fetch();
+ mask = fetch();
+ print("%s (X+0x%02X), 0x%02X", op_table->mnemonic, imm8, mask);
+ break;
+
+ case EA_DIRECT_IMM8_REL:
+ imm8 = fetch();
+ mask = fetch();
+ rel8 = fetch();
+ print("%s (0x%04X), 0x%02X, [0x%04X]", op_table->mnemonic, imm8, mask, pc+4+rel8);
+ break;
+
+ case EA_IND_X_IMM8_REL:
+ imm8 = fetch();
+ mask = fetch();
+ rel8 = fetch();
+ print("%s (X+0x%02X), 0x%02X, [0x%04X]", op_table->mnemonic, imm8, mask, pc+4+rel8);
+ break;
+
+ case EA_IND_Y:
+ imm8 = fetch();
+ print("%s (Y+0x%02X)", op_table->mnemonic, imm8);
+ break;
+
+ case EA_IND_Y_IMM8:
+ imm8 = fetch();
+ mask = fetch();
+ print("%s (Y+0x%02X), 0x%02X", op_table->mnemonic, imm8, mask);
+ break;
+
+ case EA_IND_Y_IMM8_REL:
+ imm8 = fetch();
+ mask = fetch();
+ rel8 = fetch();
+ print("%s (Y+0x%02X), 0x%02X, [0x%04X]", op_table->mnemonic, imm8, mask, pc+2+rel8);
+ break;
+
+ case PAGE2:
+ op2 = fetch();
+ return decode_opcode(pc, &opcode_table_page2[op2]);
+
+ case PAGE3:
+ op2 = fetch();
+ return decode_opcode(pc, &opcode_table_page3[op2]);
+
+ case PAGE4:
+ op2 = fetch();
+ return decode_opcode(pc, &opcode_table_page4[op2]);
+ #endif
+
+ default:
+ print("%s", op_table->mnemonic);
+ }
+
+ return flags;
+}
+
+CPU_DISASSEMBLE( scudsp )
+{
+ UINT32 flags = 0;
+ UINT8 opcode;
+
+ output = buffer;
+ rombase = oprom;
+
+ opcode = fetch();
+ flags = decode_opcode(pc, &alu_table [(opcode & 0x3c000000) >> 26],opcode);
+ flags |= decode_opcode(pc, &xbus_table [(opcode & 0x03800000) >> 23],opcode);
+ flags |= decode_opcode(pc, &ybus_table [(opcode & 0x000e0000) >> 17],opcode);
+ flags |= decode_opcode(pc, &d1bus_table[(opcode & 0x00003000) >> 12],opcode);
+
+ return (rombase-oprom) | flags | DASMFLAG_SUPPORTED;
+}