diff options
author | 2011-09-07 16:11:03 +0000 | |
---|---|---|
committer | 2011-09-07 16:11:03 +0000 | |
commit | a840eec94eeaa975608f79353ba1e33832fc2940 (patch) | |
tree | 4a79f4d8400bad3e92f56bcd5af07aaff5b5e270 /src/emu/cpu/scudsp/scudspdasm.c | |
parent | e27d55610b7b7e49345580b2f8f2d05740836268 (diff) |
Improved SCU DSP disassembler
Diffstat (limited to 'src/emu/cpu/scudsp/scudspdasm.c')
-rw-r--r-- | src/emu/cpu/scudsp/scudspdasm.c | 404 |
1 files changed, 250 insertions, 154 deletions
diff --git a/src/emu/cpu/scudsp/scudspdasm.c b/src/emu/cpu/scudsp/scudspdasm.c index 9c64a29361e..8f3316b70d1 100644 --- a/src/emu/cpu/scudsp/scudspdasm.c +++ b/src/emu/cpu/scudsp/scudspdasm.c @@ -8,80 +8,199 @@ enum { - EA_PDST = 1, - EA_XDST, - EA_ADST, - EA_YDST, + EA_A = 1, + EA_ALU, + EA_D0, + EA_IMM8, + EA_IMM18, + EA_IMM25, + EA_MUL, + EA_P, + EA_X, + EA_Y, + EA_SRCMEMX, + EA_SRCMEMY, + EA_SRCMEMD1, + EA_DMADSTMEM, + EA_DSTMEM, + EA_MVIDSTMEM, }; typedef struct { char mnemonic[32]; - int address_mode; + int address_mode_1; + int address_mode_2; + int address_mode_3, } 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 */ + { "NOP", 0, 0, 0, }, /* 0000 */ + { "AND", 0, 0, 0, }, /* 0001 */ + { "OR ", 0, 0, 0, }, /* 0010 */ + { "XOR", 0, 0, 0, }, /* 0011 */ + { "ADD", 0, 0, 0, }, /* 0100 */ + { "SUB", 0, 0, 0, }, /* 0101 */ + { "AD2", 0, 0, 0, }, /* 0110 */ + { "???", 0, 0, 0, }, /* 0111 */ + { "SR ", 0, 0, 0, }, /* 1000 */ + { "RR ", 0, 0, 0, }, /* 1001 */ + { "SL ", 0, 0, 0, }, /* 1010 */ + { "RL ", 0, 0, 0, }, /* 1011 */ + { "???", 0, 0, 0, }, /* 1100 */ + { "???", 0, 0, 0, }, /* 1101 */ + { "???", 0, 0, 0, }, /* 1110 */ + { "RL8", 0, 0, 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 */ + { "NOP", 0, 0, 0, }, /* 000 */ + { "???", 0, 0, 0, }, /* 001 */ + { "MOV", EA_MUL, EA_P, 0, }, /* 010 */ + { "MOV", EA_SRCMEMX, EA_P, 0, }, /* 011 */ //MOV %s,P + { "MOV", EA_SRCMEMX, EA_X, 0, }, /* 100 */ //MOV %s,X + { "???", 0, 0, 0, }, /* 101 */ + { "???", 0, 0, 0, }, /* 110 */ + { "???", 0, 0, 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 */ + { "NOP", 0, 0, 0, }, /* 000 */ + { "CLR", 0, EA_A, 0, }, /* 001 */ + { "MOV", EA_ALU, EA_A, 0, }, /* 010 */ + { "MOV", EA_SRCMEMY, EA_A, 0, }, /* 011 */ //MOV %s,A + { "MOV", EA_SRCMEMY, EA_Y, 0, }, /* 100 */ //MOV %s,Y + { "???", 0, 0, 0, }, /* 101 */ + { "???", 0, 0, 0, }, /* 110 */ + { "???", 0, 0, 0, }, /* 111 */ }; -static const SCUDSP_OPCODE ybus_table[] = +static const SCUDSP_OPCODE d1bus_table[] = +{ + { "NOP", 0, 0, 0, }, /* 00 */ + { "MOV", EA_IMM8, EA_DSTMEM, 0, }, /* 01 */ //MOV %I8,%d + { "???", 0, 0, 0, }, /* 10 */ + { "MOV", EA_SRCMEMD1,0, 0, }, /* 11 */ //MOV %S,%d +}; + +static const SCUDSP_OPCODE mvi_table[] = +{ + { "MVI", EA_IMM25, EA_MVIDSTMEM, 0, }, /* 0 */ //"MVI %I,%d" + { "MVI", EA_IMM18, EA_MVIDSTMEM, EA_FLAGS, }, /* 1 */ //"MVI %I,%d,%f" +}; + +static const SCUDSP_OPCODE dma_table[] = +{ + { "DMA", EA_D0, EA_DMADSTMEM, EA_IMM8, }, /* 000 */ // "DMA%H%A D0,%M,%I", + { "DMA", EA_DMASRCMEM, EA_D0, EA_IMM8, }, /* 001 */ // "DMA%H%A %s,D0,%I", + { "DMA", 0, 0, 0, }, /* 010 */ // "DMA%H%A D0,%M,%s", + { "DMA", 0, 0, 0, }, /* 011 */ // "DMA%H%A %s,D0,%s", + { "DMAH", EA_D0, EA_DMADSTMEM, EA_IMM8, }, /* 100 */ // "DMA%H%A D0,%M,%I", + { "DMAH", EA_DMASRCMEM, EA_D0, EA_IMM8, }, /* 101 */ // "DMA%H%A %s,D0,%I", + { "DMAH", 0, 0, 0, }, /* 110 */ // "DMA%H%A D0,%M,%s", + { "DMAH", 0, 0, 0, }, /* 111 */ // "DMA%H%A %s,D0,%s", + +}; + +static const SCUDSP_OPCODE jmp_table[] = +{ + { "JMP", EA_IMM8, 0, 0, }, /* 0 */ // unconditional + { "JMP", EA_IMM8, 0, EA_FLAGS, }, /* 1 */ // conditional +}; + +static const SCUDSP_OPCODE loop_table[] = +{ + { "BTM", 0, 0, 0, }, /* 00 */ + { "LPS", 0, 0, 0, }, /* 01 */ +}; + +static const SCUDSP_OPCODE end_table[] = +{ + { "END", 0, 0, 0, }, /* 00 */ + { "ENDI",0, 0, 0, }, /* 01 */ +}; + + +static const char *const src_mem[] = +{ + "M0", /* 0000 */ + "M1", /* 0001 */ + "M2", /* 0010 */ + "M3", /* 0011 */ + "MC0", /* 0100 */ + "MC1", /* 0101 */ + "MC2", /* 0110 */ + "MC3", /* 0111 */ + "???", /* 1000 */ + "ALL", /* 1001 */ + "ALH", /* 1010 */ + "???", /* 1011 */ + "???", /* 1100 */ + "???", /* 1101 */ + "???", /* 1110 */ + "???", /* 1111 */ +}; + +static const char *const dst_mem[] = { - { "NOP", 0, }, /* 000 */ - { "MOV", 0, }, /* 001 */ //MOV %I8,%d - { "???", 0, }, /* 010 */ - { "MOV", 0, }, /* 011 */ //MOV %S,%d + "MC0", /* 0000 */ + "MC1", /* 0001 */ + "MC2", /* 0010 */ + "MC3", /* 0011 */ + "RX", /* 0100 */ + "PL", /* 0101 */ + "RA0", /* 0110 */ + "WA0", /* 0111 */ + "???", /* 1000 */ + "???", /* 1001 */ + "LOP", /* 1010 */ + "TOP", /* 1011 */ + "CT0", /* 1100 */ + "CT1", /* 1101 */ + "CT2", /* 1110 */ + "CT3", /* 1111 */ }; +static const char *const mvi_dst_mem[] = +{ + "MC0", /* 0000 */ + "MC1", /* 0001 */ + "MC2", /* 0010 */ + "MC3", /* 0011 */ + "RX", /* 0100 */ + "PL", /* 0101 */ + "RA0", /* 0110 */ + "WA0", /* 0111 */ + "???", /* 1000 */ + "???", /* 1001 */ + "LOP", /* 1010 */ + "???", /* 1011 */ + "PC", /* 1100 */ //??? + "???", /* 1101 */ + "???", /* 1110 */ + "???", /* 1111 */ +}; -static const src_mem[] = +static const char *const cond_flags[] = { - "M0", /* 000 */ - "M1", /* 001 */ - "M2", /* 010 */ - "M3", /* 011 */ - "MC0", /* 100 */ - "MC1", /* 101 */ - "MC2", /* 110 */ - "MC3", /* 111 */ + "??", /* 0000 */ + "Z ", /* 0001 */ + "S ", /* 0010 */ + "ZS", /* 0011 */ + "C ", /* 0100 */ + "??", /* 0101 */ + "??", /* 0110 */ + "??", /* 0111 */ + "T0", /* 1000 */ + "??", /* 1001 */ + "??", /* 1010 */ + "??", /* 1011 */ + "??", /* 1100 */ + "??", /* 1101 */ + "??", /* 1110 */ + "??", /* 1111 */ }; /*****************************************************************************/ @@ -103,6 +222,18 @@ static UINT32 fetch(void) return *rombase++; } +static UINT8 add_table(UINT32 cur_opcode) +{ + UINT8 res = (cur_opcode & 0x00038000) >> 15; + + if(res == 0) + res = 0; + else + res = 1 << (res-1); + + return res; +} + static UINT32 decode_opcode(UINT32 pc, const SCUDSP_OPCODE *op_table,UINT32 cur_opcode) { INT8 rel8; @@ -115,115 +246,51 @@ static UINT32 decode_opcode(UINT32 pc, const SCUDSP_OPCODE *op_table,UINT32 cur_ //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; + print("%s ", op_table->mnemonic); - 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; + switch(op_table->address_mode_1) + { + case EA_ALU: print("ALU "); break; + case EA_IMM8: print("%02X ",cur_opcode & 0xff); break; + case EA_IMM18: print("%08X ",cur_opcode & 0x7ffff); break; + case EA_IMM25: print("%08X ",cur_opcode & 0x1ffffff); break; + case EA_MUL: print("MUL "); break; + case EA_SRCMEMX: print("%s ", src_mem[(cur_opcode & 0x00700000) >> 20]); break; + case EA_SRCMEMY: print("%s ", src_mem[(cur_opcode & 0x0001c000) >> 14]); break; + case EA_SRCMEMD1: print("%s ", src_mem[(cur_opcode & 0x0000000f) >> 0]); break; + case EA_D0: print("%d D0 ",add_table(cur_opcode)); break; + case EA_DMASRCMEM: print("%d %s ",add_table(cur_opcode),src_mem[(cur_opcode & 0x00000300) >> 8]); 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); + default: break; + } - case EA_IND_Y: - imm8 = fetch(); - print("%s (Y+0x%02X)", op_table->mnemonic, imm8); - break; + switch(op_table->address_mode_2) + { + case EA_A: print("A"); break; + case EA_P: print("P"); break; + case EA_X: print("X"); break; + case EA_Y: print("Y"); break; + case EA_DSTMEM: print("%s ", dst_mem[(cur_opcode & 0x00000f00) >> 8]); break; + case EA_DMADSTMEM: print("%s ", dst_mem[(cur_opcode & 0x00000300) >> 8]); break; + case EA_MVIDSTMEM: print("%s ", mvi_dst_mem[(cur_opcode & 0x3c000000) >> 26]); break; + case EA_D0: print("D0 "); break; - case EA_IND_Y_IMM8: - imm8 = fetch(); - mask = fetch(); - print("%s (Y+0x%02X), 0x%02X", op_table->mnemonic, imm8, mask); + default: 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); + switch(op_table->address_mode_3) + { + case EA_IMM8: print("%02X ",cur_opcode & 0xff); break; + case EA_FLAGS: + if(!((cur_opcode >> 19) & 0x20)) + print("N"); + print("%s ", cond_flags[(cur_opcode & 0x0780000) >> 19]); 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); + break; } return flags; @@ -238,10 +305,39 @@ CPU_DISASSEMBLE( scudsp ) 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); + switch((opcode & 0xc0000000) >> 30) + { + case 0: // operation + 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); + break; + case 1: // unknown + print("???"); + flags = 0; + break; + case 2: // move immediate + flags = decode_opcode(pc, &mvi_table [(opcode & 0x02000000) >> 25],opcode); + break; + case 3: // control + switch((opcode & 0x30000000) >> 28) + { + case 0: + flags = decode_opcode(pc, &dma_table [(opcode & 0x7000) >> 12],opcode); + break; + case 1: + flags = decode_opcode(pc, &jmp_table [(opcode & 0x2000000) >> 25],opcode); + break; + case 2: + flags = decode_opcode(pc, &loop_table [(opcode & 0x8000000) >> 27],opcode); + break; + case 3: + flags = decode_opcode(pc, &end_table [(opcode & 0x8000000) >> 27],opcode); + break; + } + break; + } return (rombase-oprom) | flags | DASMFLAG_SUPPORTED; } |