diff options
-rw-r--r-- | src/emu/cpu/dsp56k/dsp56dsm.c | 78 | ||||
-rw-r--r-- | src/emu/cpu/dsp56k/dsp56k.c | 2 | ||||
-rw-r--r-- | src/emu/cpu/dsp56k/dsp56ops.c | 785 | ||||
-rw-r--r-- | src/mame/drivers/plygonet.c | 28 |
4 files changed, 751 insertions, 142 deletions
diff --git a/src/emu/cpu/dsp56k/dsp56dsm.c b/src/emu/cpu/dsp56k/dsp56dsm.c index 98b94e06284..59e51dde150 100644 --- a/src/emu/cpu/dsp56k/dsp56dsm.c +++ b/src/emu/cpu/dsp56k/dsp56dsm.c @@ -7,18 +7,8 @@ ***************************************************************************/ /* -NOTES: -*** There seems to be a disagreement in dasm with bytes like this : 0500 0307 - On one hand, you can dasm it like this : add Y1,A X:(R2+00),Y0 - On the other, you can dasm it like this : move(m) P:(R2+00),B0 - The interesting doc pages for this are the following : move(m) . A-155 - mem move + short displacement . A-139 - add . A-23 - (POSSIBILITY : Maybe Add can't have a mem move + short displacement parallel move?) - (CURRENT SOLUTION : I'm completely ignoring mem move + short displacements for now) - -*** This disassembler has been 75% tested. There may remain some bugs, but it disassembles - Polygonet Commanders' memtest code 100% accurate (to my knowledge). + This disassembler has been 75% tested. There may remain some bugs, but it disassembles + Polygonet Commanders' memtest code 100% accurate (to my knowledge). */ #include "dsp56k.h" @@ -26,13 +16,12 @@ NOTES: /*******************/ /* Dasm prototypes */ /*******************/ -static size_t dsp56k_dasm_add_2 (const UINT16 op_byte, char* opcode_str, char* arg_str); +static size_t dsp56k_dasm_addsub_2 (const UINT16 op_byte, char* opcode_str, char* arg_str); static size_t dsp56k_dasm_mac_1 (const UINT16 op_byte, char* opcode_str, char* arg_str); static size_t dsp56k_dasm_macr_1 (const UINT16 op_byte, char* opcode_str, char* arg_str); static size_t dsp56k_dasm_move_1 (const UINT16 op_byte, char* opcode_str, char* arg_str); static size_t dsp56k_dasm_mpy_1 (const UINT16 op_byte, char* opcode_str, char* arg_str); static size_t dsp56k_dasm_mpyr_1 (const UINT16 op_byte, char* opcode_str, char* arg_str); -static size_t dsp56k_dasm_sub_1 (const UINT16 op_byte, char* opcode_str, char* arg_str); static size_t dsp56k_dasm_tfr_2 (const UINT16 op_byte, char* opcode_str, char* arg_str); static size_t dsp56k_dasm_mpy_2 (const UINT16 op_byte, char* opcode_str, char* arg_str); static size_t dsp56k_dasm_mac_2 (const UINT16 op_byte, char* opcode_str, char* arg_str); @@ -189,7 +178,7 @@ static void assemble_ea_from_z_table (UINT16 z, int n, char *ea); static void assemble_D_from_P_table(UINT16 P, UINT16 ppppp, char *D); static void assemble_arguments_from_W_table(UINT16 W, char *args, char ma, char *SD, char *ea); -static void assemble_reg_from_W_table(UINT16 W, char *args, char ma, char *SD, UINT8 xx); +static void assemble_reg_from_W_table(UINT16 W, char *args, char ma, char *SD, INT8 xx); static void assemble_address_from_IO_short_address(UINT16 pp, char *ea); static INT8 get_6_bit_signed_value(UINT16 bits); @@ -240,9 +229,10 @@ offs_t dsp56k_dasm(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opr UINT16 op_byte = op & 0x00ff; /* ADD : 011m mKKK 0rru Fuuu : A-22 */ + /* SUB : 011m mKKK 0rru Fuuu : A-202 */ if ((op & 0xe080) == 0x6000) { - size = dsp56k_dasm_add_2(op_byte, opcode_str, arg_str); + size = dsp56k_dasm_addsub_2(op_byte, opcode_str, arg_str); } /* MAC : 011m mKKK 1xx0 F1QQ : A-122 */ else if ((op & 0xe094) == 0x6084) @@ -269,11 +259,6 @@ offs_t dsp56k_dasm(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opr { size = dsp56k_dasm_mpyr_1(op_byte, opcode_str, arg_str); } - /* SUB : 011m mKKK 0rru Fuuu : A-202 */ - else if ((op & 0xe080) == 0x6000) - { - size = dsp56k_dasm_sub_1(op_byte, opcode_str, arg_str); - } /* TFR : 011m mKKK 0rr1 F0DD : A-212 */ else if ((op & 0xe094) == 0x6010) { @@ -356,10 +341,20 @@ offs_t dsp56k_dasm(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opr /* X Memory Data Move with short displacement : 0000 0101 BBBB BBBB ---- HHHW ---- ---- : A-139 */ else if ((op & 0xff00) == 0x0500) { - /* See notes at top of file! */ - /* op_byte = op2 & 0x00ff; */ - /* parallelType = kXMemoryDataMoveWithDisp; */ - /* DO NOTHING FOR NOW */ + /* Now check it against all the other potential collisions */ + /* This is necessary because "don't care bits" get in the way. */ + /* + MOVE(M) : 0000 0101 BBBB BBBB 0000 001W --0- -HHH : A-152 + MOVE(C) : 0000 0101 BBBB BBBB 0011 1WDD DDD0 ---- : A-144 + MOVE : 0000 0101 BBBB BBBB ---- HHHW 0001 0001 : A-128 + */ + if (((op2 & 0xfe20) != 0x0200) && + ((op2 & 0xf810) != 0x3800) && + ((op2 & 0x00ff) != 0x0011)) + { + op_byte = op2 & 0x00ff; + parallelType = kXMemoryDataMoveWithDisp; + } } @@ -1084,7 +1079,8 @@ offs_t dsp56k_dasm(char *buffer, offs_t pc, const UINT8 *oprom, const UINT8 *opr /*******************************/ /* ADD : 011m mKKK 0rru Fuuu : A-22 */ -static size_t dsp56k_dasm_add_2(const UINT16 op_byte, char* opcode_str, char* arg_str) +/* SUB : 011m mKKK 0rru Fuuu : A-202 */ +static size_t dsp56k_dasm_addsub_2(const UINT16 op_byte, char* opcode_str, char* arg_str) { /* TODO: How strange. Same as SUB? Investigate */ char D[32]; @@ -1160,19 +1156,6 @@ static size_t dsp56k_dasm_mpyr_1(const UINT16 op_byte, char* opcode_str, char* a return 1; } -/* SUB : 011m mKKK 0rru Fuuu : A-202 */ -static size_t dsp56k_dasm_sub_1(const UINT16 op_byte, char* opcode_str, char* arg_str) -{ - /* TODO - overlap with ADD (up above) */ - char D[32]; - char S1[32]; - char arg[32]; - decode_uuuuF_table(BITS(op_byte,0x17), BITS(op_byte,0x08), arg, S1, D); - sprintf(opcode_str, "%s", arg); - sprintf(arg_str, "%s,%s", S1, D); - return 1; -} - /* TFR : 011m mKKK 0rr1 F0DD : A-212 */ static size_t dsp56k_dasm_tfr_2(const UINT16 op_byte, char* opcode_str, char* arg_str) { @@ -1820,7 +1803,7 @@ static size_t dsp56k_dasm_bscc_1(const UINT16 op, char* opcode_str, char* arg_st static size_t dsp56k_dasm_bsr(const UINT16 op, const UINT16 op2, char* opcode_str, char* arg_str, const offs_t pc) { sprintf(opcode_str, "bsr"); - sprintf(arg_str, "%x (0x%04x)", (INT16)op2, pc + 2 + (INT16)op2); + sprintf(arg_str, "%d (0x%04x)", (INT16)op2, pc + 2 + (INT16)op2); return (2 | DASMFLAG_STEP_OVER); } @@ -2105,7 +2088,7 @@ static size_t dsp56k_dasm_macsuuu(const UINT16 op, char* opcode_str, char* arg_s /* MOVE : 0000 0101 BBBB BBBB ---- HHHW 0001 0001 : A-128 */ static size_t dsp56k_dasm_move_2(const UINT16 op, const UINT16 op2, char* opcode_str, char* arg_str) { - UINT8 B; + INT8 B; char SD[32]; char args[32]; B = BITS(op,0x00ff); @@ -2194,7 +2177,7 @@ static size_t dsp56k_dasm_movec_4(const UINT16 op, char* opcode_str, char* arg_s /* MOVE(C) : 0000 0101 BBBB BBBB 0011 1WDD DDD0 ---- : A-144 */ static size_t dsp56k_dasm_movec_5(const UINT16 op, const UINT16 op2, char* opcode_str, char* arg_str) { - UINT8 B; + INT8 B; char SD[32]; char args[32]; B = BITS(op,0x00ff); @@ -2249,7 +2232,7 @@ static size_t dsp56k_dasm_movem_1(const UINT16 op, char* opcode_str, char* arg_s /* MOVE(M) : 0000 0101 BBBB BBBB 0000 001W --0- -HHH : A-152 */ static size_t dsp56k_dasm_movem_2(const UINT16 op, const UINT16 op2, char* opcode_str, char* arg_str) { - UINT8 B; + INT8 B; char SD[32]; char args[32]; B = BITS(op,0x00ff); @@ -2935,6 +2918,7 @@ static void decode_kSign_table(UINT16 k, char *plusMinus) static void decode_KKK_table(UINT16 KKK, char *D1, char *D2) { + /* TODO: Fix ^Fs */ switch(KKK) { case 0x0: sprintf(D1, "^F"); sprintf(D2, "X0"); break; @@ -3054,6 +3038,11 @@ static void decode_uuuuF_table(UINT16 uuuu, UINT16 F, char *arg, char *S, char * { UINT16 switchVal = (uuuu << 1) | F; + /* An invalid uuuuF has been seen in the wild */ + sprintf(D, "sub?"); + sprintf(S, "add?"); + sprintf(arg, "invalid"); + switch(switchVal) { case 0x00: sprintf(arg, "add"); sprintf(S, "X0"); sprintf(D, "A"); break; @@ -3175,8 +3164,9 @@ static void assemble_arguments_from_W_table(UINT16 W, char *args, char ma, char } } -static void assemble_reg_from_W_table(UINT16 W, char *args, char ma, char *SD, UINT8 xx) +static void assemble_reg_from_W_table(UINT16 W, char *args, char ma, char *SD, INT8 xx) { + /* TODO : xx is said to be signed on page A-139. Nowhere else. Are they all signed? */ switch(W) { case 0x0: sprintf(args, "%s,%c:(R2+%02x)", SD, ma, xx); break; diff --git a/src/emu/cpu/dsp56k/dsp56k.c b/src/emu/cpu/dsp56k/dsp56k.c index 8c3bf2255e9..299e1ba66d3 100644 --- a/src/emu/cpu/dsp56k/dsp56k.c +++ b/src/emu/cpu/dsp56k/dsp56k.c @@ -598,7 +598,7 @@ void dsp56k_get_info(UINT32 state, cpuinfo *info) case CPUINFO_INT_DEFAULT_IRQ_VECTOR: info->i = 0x0000; break; case CPUINFO_INT_ENDIANNESS: info->i = CPU_IS_LE; break; case CPUINFO_INT_CLOCK_MULTIPLIER: info->i = 1; break; - case CPUINFO_INT_CLOCK_DIVIDER: info->i = 1; break; + case CPUINFO_INT_CLOCK_DIVIDER: info->i = 2; break; case CPUINFO_INT_MIN_INSTRUCTION_BYTES: info->i = 2; break; case CPUINFO_INT_MAX_INSTRUCTION_BYTES: info->i = 4; break; case CPUINFO_INT_MIN_CYCLES: info->i = 1; break; // ? diff --git a/src/emu/cpu/dsp56k/dsp56ops.c b/src/emu/cpu/dsp56k/dsp56ops.c index 25e8197f8ec..4138635fc31 100644 --- a/src/emu/cpu/dsp56k/dsp56ops.c +++ b/src/emu/cpu/dsp56k/dsp56ops.c @@ -18,6 +18,10 @@ /************************/ /* Datatypes and macros */ /************************/ +enum addSubOpType { OP_ADD, + OP_SUB, + OP_OTHER }; + enum dataType { DT_BYTE, DT_WORD, DT_DOUBLE_WORD, @@ -30,7 +34,6 @@ struct _typed_pointer }; typedef struct _typed_pointer typed_pointer; - #define WORD(X) (X<<1) #define BITS(CUR,MASK) (Dsp56kOpMask(CUR,MASK)) @@ -39,14 +42,13 @@ typedef struct _typed_pointer typed_pointer; /*********************/ /* Opcode prototypes */ /*********************/ -static size_t dsp56k_op_add_2 (const UINT16 op_byte, UINT8* cycles); -static size_t dsp56k_op_mac_1 (const UINT16 op_byte, UINT8* cycles); -static size_t dsp56k_op_macr_1 (const UINT16 op_byte, UINT8* cycles); -static size_t dsp56k_op_move_1 (const UINT16 op_byte, UINT8* cycles); -static size_t dsp56k_op_mpy_1 (const UINT16 op_byte, UINT8* cycles); -static size_t dsp56k_op_mpyr_1 (const UINT16 op_byte, UINT8* cycles); -static size_t dsp56k_op_sub_1 (const UINT16 op_byte, UINT8* cycles); -static size_t dsp56k_op_tfr_2 (const UINT16 op_byte, UINT8* cycles); +static size_t dsp56k_op_addsub_2 (const UINT16 op_byte, typed_pointer* d_register, UINT8* cycles); +static size_t dsp56k_op_mac_1 (const UINT16 op_byte, typed_pointer* d_register, UINT8* cycles); +static size_t dsp56k_op_macr_1 (const UINT16 op_byte, typed_pointer* d_register, UINT8* cycles); +static size_t dsp56k_op_move_1 (const UINT16 op_byte, typed_pointer* d_register, UINT8* cycles); +static size_t dsp56k_op_mpy_1 (const UINT16 op_byte, typed_pointer* d_register, UINT8* cycles); +static size_t dsp56k_op_mpyr_1 (const UINT16 op_byte, typed_pointer* d_register, UINT8* cycles); +static size_t dsp56k_op_tfr_2 (const UINT16 op_byte, typed_pointer* d_register, UINT8* cycles); static size_t dsp56k_op_mpy_2 (const UINT16 op_byte, UINT8* cycles); static size_t dsp56k_op_mac_2 (const UINT16 op_byte, UINT8* cycles); static size_t dsp56k_op_clr (const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles); @@ -167,7 +169,8 @@ static void execute_register_to_register_data_move(const UINT16 op, typed_pointe static void execute_address_register_update(const UINT16 op, typed_pointer* d_register, UINT64* prev_accum_value); static void execute_x_memory_data_move (const UINT16 op, typed_pointer* d_register, UINT64* prev_accum_value); static void execute_x_memory_data_move2(const UINT16 op, typed_pointer* d_register); - +static void execute_dual_x_memory_data_read(const UINT16 op, typed_pointer* d_register); +static void execute_x_memory_data_move_with_short_displacement(const UINT16 op, const UINT16 op2); static UINT16 decode_BBB_bitmask(UINT16 BBB, UINT16 *iVal); static int decode_cccc_table(UINT16 cccc); @@ -177,15 +180,20 @@ static void decode_F_table(UINT16 F, typed_pointer* ret); static void decode_h0hF_table(UINT16 h0h, UINT16 F, typed_pointer* src_ret, typed_pointer* dst_ret); static void decode_HH_table(UINT16 HH, typed_pointer* ret); static void decode_HHH_table(UINT16 HHH, typed_pointer* ret); -static void decode_IIII_table(UINT16 IIII, typed_pointer* src_ret, typed_pointer* dst_ret, void *working); +static void decode_IIII_table(UINT16 IIII, typed_pointer* src_ret, typed_pointer* dst_ret, void* working); static void decode_JJJF_table(UINT16 JJJ, UINT16 F, typed_pointer* src_ret, typed_pointer* dst_ret); static void decode_JJF_table(UINT16 JJ, UINT16 F, typed_pointer* src_ret, typed_pointer* dst_ret); +static void decode_KKK_table(UINT16 KKK, typed_pointer* dst_ret1, typed_pointer* dst_ret2, void* working); +static void decode_QQF_table(UINT16 QQ, UINT16 F, void **S1, void **S2, void **D); static void decode_QQF_special_table(UINT16 QQ, UINT16 F, void **S1, void **S2, void **D); -static void decode_QQQF_special_table(UINT16 QQQ, UINT16 F, void **S1, void **S2, void **D); +static void decode_QQQF_table(UINT16 QQQ, UINT16 F, void **S1, void **S2, void **D); static void decode_RR_table(UINT16 RR, typed_pointer* ret); +static void decode_TT_table(UINT16 TT, typed_pointer* ret); +static void decode_uuuuF_table(UINT16 uuuu, UINT16 F, UINT8 add_sub_other, typed_pointer* src_ret, typed_pointer* dst_ret); static void decode_Z_table(UINT16 Z, typed_pointer* ret); static void execute_m_table(int x, UINT16 m); +static void execute_mm_table(UINT16 rnum, UINT16 mm); static void execute_MM_table(UINT16 rnum, UINT16 MM); static UINT16 execute_q_table(int RR, UINT16 q); static void execute_z_table(int RR, UINT16 z); @@ -233,58 +241,55 @@ static void execute_one(void) /* DECODE */ - /* Dual X Memory Data Read : 011m mKKK -rr- ---- : A-142*/ + /* Dual X Memory Data Read : 011m mKKK .rr. .... : A-142*/ if ((op & 0xe000) == 0x6000) { + typed_pointer d_register = {NULL, DT_BYTE}; + /* Quote: (MOVE, MAC(R), MPY(R), ADD, SUB, TFR) */ UINT16 op_byte = op & 0x00ff; /* ADD : 011m mKKK 0rru Fuuu : A-22 */ + /* SUB : 011m mKKK 0rru Fuuu : A-202 */ if ((op & 0xe080) == 0x6000) { - size = dsp56k_op_add_2(op_byte, &cycle_count); + size = dsp56k_op_addsub_2(op_byte, &d_register, &cycle_count); } /* MAC : 011m mKKK 1xx0 F1QQ : A-122 */ else if ((op & 0xe094) == 0x6084) { - size = dsp56k_op_mac_1(op_byte, &cycle_count); + size = dsp56k_op_mac_1(op_byte, &d_register, &cycle_count); } /* MACR: 011m mKKK 1--1 F1QQ : A-124 */ else if ((op & 0xe094) == 0x6094) { - size = dsp56k_op_macr_1(op_byte, &cycle_count); + size = dsp56k_op_macr_1(op_byte, &d_register, &cycle_count); } /* MOVE : 011m mKKK 0rr1 0000 : A-128 */ else if ((op & 0xe09f) == 0x6010) { - size = dsp56k_op_move_1(op_byte, &cycle_count); + size = dsp56k_op_move_1(op_byte, &d_register, &cycle_count); } /* MPY : 011m mKKK 1xx0 F0QQ : A-160 */ else if ((op & 0xe094) == 0x6080) { - size = dsp56k_op_mpy_1(op_byte, &cycle_count); + size = dsp56k_op_mpy_1(op_byte, &d_register, &cycle_count); } /* MPYR : 011m mKKK 1--1 F0QQ : A-162 */ else if ((op & 0xe094) == 0x6090) { - size = dsp56k_op_mpyr_1(op_byte, &cycle_count); - } - /* SUB : 011m mKKK 0rru Fuuu : A-202 */ - else if ((op & 0xe080) == 0x6000) - { - size = dsp56k_op_sub_1(op_byte, &cycle_count); + size = dsp56k_op_mpyr_1(op_byte, &d_register, &cycle_count); } /* TFR : 011m mKKK 0rr1 F0DD : A-212 */ else if ((op & 0xe094) == 0x6010) { - size = dsp56k_op_tfr_2(op_byte, &cycle_count); + size = dsp56k_op_tfr_2(op_byte, &d_register, &cycle_count); } /* Now evaluate the parallel data move */ - // TODO // decode_dual_x_memory_data_read(op, parallel_move_str, parallel_move_str2); - logerror("DSP56k: Unemulated Dual X Memory Data Move @ 0x%x\n", PC); + execute_dual_x_memory_data_read(op, &d_register); } - /* X Memory Data Write and Register Data Move : 0001 011k RRDD ---- : A-140 */ + /* X Memory Data Write and Register Data Move : 0001 011k RRDD .... : A-140 */ else if ((op & 0xfe00) == 0x1600) { /* Quote: (MPY or MAC) */ @@ -326,43 +331,53 @@ static void execute_one(void) UINT64 prev_accum_value = U64(0x0000000000000000); /* Note: it's important that NPDM comes before RtRDM here */ - /* No Parallel Data Move : 0100 1010 ---- ---- : A-131 */ + /* No Parallel Data Move : 0100 1010 .... .... : A-131 */ if ((op & 0xff00) == 0x4a00) { op_byte = op & 0x00ff; parallelType = kNoParallelDataMove; } - /* Register to Register Data Move : 0100 IIII ---- ---- : A-133 */ + /* Register to Register Data Move : 0100 IIII .... .... : A-133 */ else if ((op & 0xf000) == 0x4000) { op_byte = op & 0x00ff; parallelType = kRegisterToRegister; } - /* Address Register Update : 0011 0zRR ---- ---- : A-135 */ + /* Address Register Update : 0011 0zRR .... .... : A-135 */ else if ((op & 0xf800) == 0x3000) { op_byte = op & 0x00ff; parallelType = kAddressRegister; } - /* X Memory Data Move : 1mRR HHHW ---- ---- : A-137 */ + /* X Memory Data Move : 1mRR HHHW .... .... : A-137 */ else if ((op & 0x8000) == 0x8000) { op_byte = op & 0x00ff; parallelType = kXMemoryDataMove; } - /* X Memory Data Move : 0101 HHHW ---- ---- : A-137 */ + /* X Memory Data Move : 0101 HHHW .... .... : A-137 */ else if ((op & 0xf000) == 0x5000) { op_byte = op & 0x00ff; parallelType = kXMemoryDataMove2; } - /* X Memory Data Move with short displacement : 0000 0101 BBBB BBBB ---- HHHW ---- ---- : A-139 */ + /* X Memory Data Move with short displacement : 0000 0101 BBBB BBBB ---- HHHW .... .... : A-139 */ else if ((op & 0xff00) == 0x0500) { - /* See notes at top of file! */ - /* op_byte = op2 & 0x00ff; */ - /* parallelType = kXMemoryDataMoveWithDisp; */ - /* DO NOTHING FOR NOW */ + /* Now check it against all the other potential collisions */ + /* This is necessary because "don't care bits" get in the way. */ + /* + MOVE(M) : 0000 0101 BBBB BBBB 0000 001W --0- -HHH : A-152 + MOVE(C) : 0000 0101 BBBB BBBB 0011 1WDD DDD0 ---- : A-144 + MOVE : 0000 0101 BBBB BBBB ---- HHHW 0001 0001 : A-128 + */ + if (((op2 & 0xfe20) != 0x0200) && + ((op2 & 0xf810) != 0x3800) && + ((op2 & 0x00ff) != 0x0011)) + { + op_byte = op2 & 0x00ff; + parallelType = kXMemoryDataMoveWithDisp; + } } @@ -568,8 +583,8 @@ static void execute_one(void) execute_x_memory_data_move2(op, &d_register); break; case kXMemoryDataMoveWithDisp: - // TODO // decode_x_memory_data_move_with_short_displacement(op, op2, parallel_move_str); - logerror("DSP56k: Unemulated Memory Data Move With Disp Parallel move @ 0x%x\n", PC); + execute_x_memory_data_move_with_short_displacement(op, op2); + size = 2; break; } } @@ -1086,23 +1101,109 @@ static void execute_one(void) /*******************************/ /* ADD : 011m mKKK 0rru Fuuu : A-22 */ -static size_t dsp56k_op_add_2(const UINT16 op_byte, UINT8* cycles) +/* SUB : 011m mKKK 0rru Fuuu : A-202 */ +static size_t dsp56k_op_addsub_2(const UINT16 op_byte, typed_pointer* d_register, UINT8* cycles) { + UINT64 useVal = 0; + UINT8 op_type = OP_OTHER; + typed_pointer S = {NULL, DT_BYTE}; + typed_pointer D = {NULL, DT_BYTE}; + + decode_uuuuF_table(BITS(op_byte,0x0017), BITS(op_byte,0x0008), op_type, &S, &D); + + /* If you gave an invalid operation type, presume it's a nop and move on with the parallel move */ + if (op_type == OP_OTHER) + { + d_register->addr = NULL; + d_register->data_type = DT_BYTE; + cycles += 2; + return 1; + } + + /* It's a real operation. Get on with it. */ + switch(S.data_type) + { + case DT_WORD: useVal = (UINT64)*((UINT16*)S.addr) << 16; break; + case DT_DOUBLE_WORD: useVal = (UINT64)*((UINT32*)S.addr); break; + case DT_LONG_WORD: useVal = (UINT64)*((UINT64*)S.addr); break; + } + + /* TODO: Verify : Sign-extend everyone for proper add/sub op */ + if (useVal & U64(0x0000000080000000)) + useVal |= U64(0xffffffff00000000); + + /* Operate*/ + if (op_type == OP_ADD) + *((UINT64*)D.addr) += useVal; + else if (op_type == OP_SUB) + *((UINT64*)D.addr) -= useVal; + + d_register->addr = D.addr; + d_register->data_type = D.data_type; + /* S L E U N Z V C */ /* * * * * * * * * */ - return 0; + /* TODO S, L, E, U, V, C */ + if (*((UINT64*)D.addr) & U64(0x0000008000000000)) N_bit_set(1); + if (*((UINT64*)D.addr) == 0) Z_bit_set(1); + + cycles += 2; /* TODO: + mv oscillator cycles */ + return 1; } /* MAC : 011m mKKK 1xx0 F1QQ : A-122 */ -static size_t dsp56k_op_mac_1(const UINT16 op_byte, UINT8* cycles) +static size_t dsp56k_op_mac_1(const UINT16 op_byte, typed_pointer* d_register, UINT8* cycles) { + INT64 opD = 0; + INT64 result = 0; + + INT32 s1 = 0; + INT32 s2 = 0; + + void* D = NULL; + void* S1 = NULL; + void* S2 = NULL; + + decode_QQF_table(BITS(op_byte,0x0003), BITS(op_byte,0x0008), &S1, &S2, &D); + + /* Cast both values as being signed */ + s1 = *((INT16*)S1); + s2 = *((INT16*)S2); + + /* Fixed-point 2's complement multiplication requires a shift */ + result = (s1 * s2) << 1; + + /* Sign extend D into a temp variable */ + opD = (*((UINT64*)D)); + if (opD & U64(0x0000008000000000)) + opD |= U64(0xffffff0000000000); + else + opD &= U64(0x000000ffffffffff); + + /* Accumulate */ + opD += result; + + /* And out the bits that don't live in the register */ + opD &= U64(0x000000ffffffffff); + + (*((UINT64*)D)) = (UINT64)opD; + + /* For the parallel move */ + d_register->addr = D; + d_register->data_type = DT_LONG_WORD; + /* S L E U N Z V C */ /* * * * * * * * - */ - return 0; + /* TODO: S, L, E, V */ + if ( *((UINT64*)D) & U64(0x0000008000000000)) N_bit_set(1); + if ((*((UINT64*)D) & U64(0x000000ffffffffff)) == 0) Z_bit_set(1); + + cycles += 2; /* TODO: +mv oscillator cycles */ + return 1; } /* MACR: 011m mKKK 1--1 F1QQ : A-124 */ -static size_t dsp56k_op_macr_1(const UINT16 op_byte, UINT8* cycles) +static size_t dsp56k_op_macr_1(const UINT16 op_byte, typed_pointer* d_register, UINT8* cycles) { /* S L E U N Z V C */ /* * * * * * * * - */ @@ -1110,7 +1211,7 @@ static size_t dsp56k_op_macr_1(const UINT16 op_byte, UINT8* cycles) } /* MOVE : 011m mKKK 0rr1 0000 : A-128 */ -static size_t dsp56k_op_move_1(const UINT16 op_byte, UINT8* cycles) +static size_t dsp56k_op_move_1(const UINT16 op_byte, typed_pointer* d_register, UINT8* cycles) { /* S L E U N Z V C */ /* * * - - - - - - */ @@ -1118,31 +1219,53 @@ static size_t dsp56k_op_move_1(const UINT16 op_byte, UINT8* cycles) } /* MPY : 011m mKKK 1xx0 F0QQ : A-160 */ -static size_t dsp56k_op_mpy_1(const UINT16 op_byte, UINT8* cycles) +static size_t dsp56k_op_mpy_1(const UINT16 op_byte, typed_pointer* d_register, UINT8* cycles) { + INT64 result = 0; + + INT32 s1 = 0; + INT32 s2 = 0; + + void* D = NULL; + void* S1 = NULL; + void* S2 = NULL; + + decode_QQF_table(BITS(op_byte,0x0003), BITS(op_byte,0x0008), &S1, &S2, &D); + + /* Cast both values as being signed */ + s1 = *((INT16*)S1); + s2 = *((INT16*)S2); + + /* Fixed-point 2's complement multiplication requires a shift */ + result = (s1 * s2) << 1; + + /* And out the bits that don't live in the register */ + (*((UINT64*)D)) = result & U64(0x000000ffffffffff); + + /* For the parallel move */ + d_register->addr = D; + d_register->data_type = DT_LONG_WORD; + /* S L E U N Z V C */ /* * * * * * * * - */ - return 0; + /* TODO: S, L, E, V */ + if ( *((UINT64*)D) & U64(0x0000008000000000)) N_bit_set(1); + if ((*((UINT64*)D) & U64(0x000000ffffffffff)) == 0) Z_bit_set(1); + + cycles += 2; /* TODO: +mv oscillator cycles */ + return 1; } /* MPYR : 011m mKKK 1--1 F0QQ : A-162 */ -static size_t dsp56k_op_mpyr_1(const UINT16 op_byte, UINT8* cycles) +static size_t dsp56k_op_mpyr_1(const UINT16 op_byte, typed_pointer* d_register, UINT8* cycles) { /* S L E U N Z V C */ /* * * * * * * * - */ return 0; } -/* SUB : 011m mKKK 0rru Fuuu : A-202 */ -static size_t dsp56k_op_sub_1(const UINT16 op_byte, UINT8* cycles) -{ - /* S L E U N Z V C */ - /* * * * * * * * * */ - return 0; -} - /* TFR : 011m mKKK 0rr1 F0DD : A-212 */ -static size_t dsp56k_op_tfr_2(const UINT16 op_byte, UINT8* cycles) +static size_t dsp56k_op_tfr_2(const UINT16 op_byte, typed_pointer* d_register, UINT8* cycles) { /* S L E U N Z V C */ /* - - - - - - - - */ @@ -1307,9 +1430,29 @@ static size_t dsp56k_op_tst(const UINT16 op_byte, typed_pointer* d_register, UIN /* INC : .... .... 0010 F010 : A-104 */ static size_t dsp56k_op_inc(const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles) { + typed_pointer D = {NULL, DT_BYTE}; + decode_F_table(BITS(op_byte,0x0008), &D); + + /* Save some data for the parallel move */ + *p_accum = *((UINT64*)D.addr); + + /* Increment */ + *((UINT64*)D.addr) = *((UINT64*)D.addr) + 1; + + /* And out the bits that don't live in the register */ + *((UINT64*)D.addr) &= U64(0x000000ffffffffff); + + d_register->addr = D.addr; + d_register->data_type = D.data_type; + /* S L E U N Z V C */ /* * * * * * * * * */ - return 0; + /* TODO: S, L, E, U, V, C */ + if ( *((UINT64*)D.addr) & U64(0x0000008000000000)) N_bit_set(1); + if ((*((UINT64*)D.addr) & U64(0x000000ffffff0000)) == 0) Z_bit_set(1); + + cycles += 2; /* TODO: +mv oscillator cycles */ + return 1; } /* INC24 : .... .... 0010 F011 : A-106 */ @@ -1671,9 +1814,61 @@ static size_t dsp56k_op_rol(const UINT16 op_byte, typed_pointer* d_register, UIN /* CMPM : .... .... 0111 FJJJ : A-66 */ static size_t dsp56k_op_cmpm(const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles) { + INT64 absS; + INT64 absD; + INT64 absResult; + + typed_pointer S = {NULL, DT_BYTE}; + typed_pointer D = {NULL, DT_BYTE}; + + decode_JJJF_table(BITS(op_byte,0x0007),BITS(op_byte,0x0008), &S, &D); + + *p_accum = *((UINT64*)D.addr); + + /* Sign extend and get absolute value of the source */ + if (S.addr == &A || S.addr == &B) + { + absS = *((UINT64*)S.addr); + if (absS & U64(0x0000008000000000)) + absS |= U64(0xffffff8000000000); + } + else + { + absS = (*((UINT16*)S.addr)) << 16; + if (absS & U64(0x0000000080000000)) + absS |= U64(0xffffffff80000000); + } + absS = abs(absS); + + /* Sign extend and get absolute value of the destination */ + if (D.addr == &A || D.addr == &B) + { + absD = *((UINT64*)D.addr); + if (absD & U64(0x0000008000000000)) + absD |= U64(0xffffff8000000000); + } + else + { + absD = (*((UINT16*)D.addr)) << 16; + if (absS & U64(0x0000000080000000)) + absS |= U64(0xffffffff80000000); + } + absD = abs(absD); + + /* Compare */ + absResult = absD - absS; + + d_register->addr = D.addr; + d_register->data_type = D.data_type; + /* S L E U N Z V C */ /* * * * * * * * * */ - return 0; + /* TODO: S, L, E, U, V, C */ + if ( (absResult) & U64(0x0000008000000000)) N_bit_set(1); else N_bit_set(0); + if (((absResult) & U64(0x000000ffffffffff)) == 0) Z_bit_set(1); else Z_bit_set(0); + + cycles += 2; /* TODO: +mv oscillator cycles */ + return 1; } /* MPY : .... .... 1k00 FQQQ : A-160 -- CONFIRMED TYPO IN DOCS (HHHH vs HHHW) */ @@ -1689,20 +1884,20 @@ static size_t dsp56k_op_mpy(const UINT16 op_byte, typed_pointer* d_register, UIN void* S1 = NULL; void* S2 = NULL; - decode_QQQF_special_table(BITS(op_byte,0x0007), BITS(op_byte,0x0008), &S1, &S2, &D); + decode_QQQF_table(BITS(op_byte,0x0007), BITS(op_byte,0x0008), &S1, &S2, &D); k = BITS(op_byte,0x0040); - /* Negative sign */ - if (!k) - s1 = *((INT16*)S1); - else - s1 = (*((INT16*)S1)) * -1; - + /* Cast both values as being signed */ + s1 = *((INT16*)S1); s2 = *((INT16*)S2); /* Fixed-point 2's complement multiplication requires a shift */ - result = ( s1 * s2 ) << 1; + result = (s1 * s2) << 1; + + /* Negate the product if necessary */ + if (k) + result *= -1; (*((UINT64*)D)) = result & U64(0x000000ffffffffff); @@ -1727,17 +1922,122 @@ static size_t dsp56k_op_mpyr(const UINT16 op_byte, typed_pointer* d_register, UI /* MAC : .... .... 1k10 FQQQ : A-122 */ static size_t dsp56k_op_mac(const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles) { + UINT16 k = 0; + INT64 opD = 0; + INT64 result = 0; + + INT32 s1 = 0; + INT32 s2 = 0; + + void* D = NULL; + void* S1 = NULL; + void* S2 = NULL; + + decode_QQQF_table(BITS(op_byte,0x0007), BITS(op_byte,0x0008), &S1, &S2, &D); + + k = BITS(op_byte,0x0040); + + /* Cast both values as being signed */ + s1 = *((INT16*)S1); + s2 = *((INT16*)S2); + + /* Fixed-point 2's complement multiplication requires a shift */ + result = (s1 * s2) << 1; + + /* Sign extend D into a temp variable */ + opD = (*((UINT64*)D)); + if (opD & U64(0x0000008000000000)) + opD |= U64(0xffffff0000000000); + else + opD &= U64(0x000000ffffffffff); + + /* Negate if necessary */ + if (k) + result *= -1; + + /* Accumulate */ + opD += result; + + /* And out the bits that don't live in the register */ + opD &= U64(0x000000ffffffffff); + + (*((UINT64*)D)) = (UINT64)opD; + + /* For the parallel move */ + d_register->addr = D; + d_register->data_type = DT_LONG_WORD; + /* S L E U N Z V C */ /* * * * * * * * - */ - return 0; + /* TODO: S, L, E, V */ + if ( *((UINT64*)D) & U64(0x0000008000000000)) N_bit_set(1); + if ((*((UINT64*)D) & U64(0x000000ffffffffff)) == 0) Z_bit_set(1); + + cycles += 2; /* TODO: +mv oscillator cycles */ + return 1; } /* MACR : .... .... 1k11 FQQQ : A-124 -- DRAMA - rr vs xx (805) */ static size_t dsp56k_op_macr(const UINT16 op_byte, typed_pointer* d_register, UINT64* p_accum, UINT8* cycles) { + UINT16 k = 0; + INT64 opD = 0; + INT64 result = 0; + + INT32 s1 = 0; + INT32 s2 = 0; + + void* D = NULL; + void* S1 = NULL; + void* S2 = NULL; + + decode_QQQF_table(BITS(op_byte,0x0007), BITS(op_byte,0x0008), &S1, &S2, &D); + + k = BITS(op_byte,0x0040); + + /* Cast both values as being signed */ + s1 = *((INT16*)S1); + s2 = *((INT16*)S2); + + /* Fixed-point 2's complement multiplication requires a shift */ + result = (s1 * s2) << 1; + + /* Sign extend D into a temp variable */ + opD = (*((UINT64*)D)); + if (opD & U64(0x0000008000000000)) + opD |= U64(0xffffff0000000000); + else + opD &= U64(0x000000ffffffffff); + + /* Negate if necessary */ + if (k) + result *= -1; + + /* Accumulate */ + opD += result; + + /* Round the result */ + /* WARNING : ROUNDING NOT FULLY IMPLEMENTED YET! */ + opD &= U64(0x000000ffffff0000); + + /* And out the bits that don't live in the register */ + opD &= U64(0x000000ffffffffff); + + /* Store the result */ + (*((UINT64*)D)) = (UINT64)opD; + + /* For the parallel move */ + d_register->addr = D; + d_register->data_type = DT_LONG_WORD; + /* S L E U N Z V C */ /* * * * * * * * - */ - return 0; + /* TODO: S, L, E, V */ + if ( *((UINT64*)D) & U64(0x0000008000000000)) N_bit_set(1); + if ((*((UINT64*)D) & U64(0x000000ffffffffff)) == 0) Z_bit_set(1); + + cycles += 2; /* TODO: +mv oscillator cycles */ + return 1; } @@ -1846,10 +2146,30 @@ static size_t dsp56k_op_asr4(const UINT16 op, UINT8* cycles) /* ASR16 : 0001 0101 0111 F000 : A-36 */ static size_t dsp56k_op_asr16(const UINT16 op, UINT8* cycles) { + UINT64 backupVal; + typed_pointer D = {NULL, DT_BYTE}; + + decode_F_table(BITS(op,0x0008), &D); + + backupVal = *((UINT64*)D.addr); + + *((UINT64*)D.addr) = *((UINT64*)D.addr) >> 16; + + if(backupVal & U64(0x0000008000000000)) + *((UINT64*)D.addr) |= U64(0x000000ffff000000); + else + *((UINT64*)D.addr) &= U64(0x0000000000ffffff); + /* S L E U N Z V C */ /* - * * * * * 0 ? */ - /* C - Set if bit 15 of source operand is set. Cleared otherwise. */ - return 0; + /* TODO: E, U */ + if (*((UINT64*)D.addr) & U64(0x0000008000000000)) N_bit_set(1); else N_bit_set(0); + if (*((UINT64*)D.addr) == 0) Z_bit_set(1); else Z_bit_set(0); + V_bit_set(0); + if (backupVal & U64(0x0000000000008000)) C_bit_set(1); else C_bit_set(0); + + cycles += 2; + return 1; } /* BFCHG : 0001 0100 11Pp pppp BBB1 0010 iiii iiii : A-38 */ @@ -2522,6 +2842,33 @@ static size_t dsp56k_op_jmp_1(const UINT16 op, UINT8* cycles) /* JScc : 0000 0110 --01 cccc xxxx xxxx xxxx xxxx : A-112 */ static size_t dsp56k_op_jscc(const UINT16 op, const UINT16 op2, UINT8* cycles) { + int shouldJump = decode_cccc_table(BITS(op,0x000f)); + + if(shouldJump) + { + /* TODO: It says "signed" absolute offset. Weird. */ + UINT16 branchOffset = op2; + + /* TODO: Verify, since it's not in the docs, but it must be true */ + PC += 2; + + SP++; + SSH = PC; + SSL = SR; + + core.ppc = PC; + PC = branchOffset; + change_pc(PC); + + cycles += 4; /* TODO: +jx oscillator clock cycles */ + return 0; + } + else + { + cycles += 4; /* TODO: +jx oscillator clock cycles */ + return 2; + } + /* S L E U N Z V C */ /* - - - - - - - - */ return 0; @@ -2577,9 +2924,37 @@ static size_t dsp56k_op_jsr_2(const UINT16 op, UINT8* cycles) /* LEA : 0000 0001 11TT MMRR : A-116 */ static size_t dsp56k_op_lea(const UINT16 op, UINT8* cycles) { + UINT16 ea = 0; + UINT16 *rX = NULL; + UINT16 *nX = NULL; + typed_pointer D = {NULL, DT_BYTE}; + decode_TT_table(BITS(op,0x0030), &D); + + /* TODO: change the execute_mm_functions to return values. Maybe */ + /* Because this calculation isn't applied, do everything locally */ + /* RR table */ + switch(BITS(op,0x0003)) + { + case 0x0: rX = &R0; nX = &N0; break; + case 0x1: rX = &R1; nX = &N1; break; + case 0x2: rX = &R2; nX = &N2; break; + case 0x3: rX = &R3; nX = &N3; break; + } + + /* MM table */ + switch(BITS(op,0x000c)) + { + case 0x0: ea = *rX; break; + case 0x1: ea = *rX + 1; break; + case 0x2: ea = *rX - 1; break; + case 0x3: ea = *rX + *nX; break; + } + + *((UINT16*)D.addr) = ea; + /* S L E U N Z V C */ /* - - - - - - - - */ - return 0; + return 1; } /* LEA : 0000 0001 10NN MMRR : A-116 */ @@ -2856,12 +3231,45 @@ static size_t dsp56k_op_movec_4(const UINT16 op, UINT8* cycles) /* MOVE(C) : 0000 0101 BBBB BBBB 0011 1WDD DDD0 ---- : A-144 */ static size_t dsp56k_op_movec_5(const UINT16 op, const UINT16 op2, UINT8* cycles) { + INT8 xx; + UINT8 W; + UINT16 memOffset; + typed_pointer SD = { NULL, DT_BYTE }; + + xx = (INT8)(op & 0x00ff); + W = BITS(op2,0x0400); + decode_DDDDD_table(BITS(op2,0x03e0), &SD); + + memOffset = R2 + (INT16)xx; + + if (W) + { + /* Write D */ + UINT16 tempData = data_read_word_16le(WORD(memOffset)); + typed_pointer temp_src = { (void*)&tempData, DT_WORD }; + SetDestinationValue(temp_src, SD); + } + else + { + /* Read S */ + UINT16 tempData = *((UINT16*)SD.addr); + typed_pointer temp_src = { (void*)&tempData, DT_WORD }; + SetDataMemoryValue(temp_src, WORD(memOffset)); + } + /* S L E U N Z V C */ /* * ? ? ? ? ? ? ? */ /* All ? bits - If SR is specified as a destination operand, set according to the corresponding bit of the source operand. If SR is not specified as a destination operand, L is set if data limiting occurred. All ? bits are not affected otherwise.*/ - return 0; + if (W && (SD.addr != &SR)) + { + /* If you're writing to something other than the SR */ + /* TODO */ + } + + cycles += 2; /* TODO: + mvc oscillator clock cycles */ + return 2; } /* MOVE(I) : 0010 00DD BBBB BBBB : A-150 */ @@ -3511,6 +3919,43 @@ static void decode_JJF_table(UINT16 JJ, UINT16 F, typed_pointer* src_ret, typed_ } } +static void decode_KKK_table(UINT16 KKK, typed_pointer* dst_ret1, typed_pointer* dst_ret2, void* working) +{ + void *opposite = 0x00 ; + + if (working == &A) opposite = &B ; + else opposite = &A ; + + switch(KKK) + { + case 0x0: dst_ret1->addr = opposite; dst_ret1->data_type = DT_LONG_WORD; dst_ret2->addr = &X0; dst_ret2->data_type = DT_WORD; break; + case 0x1: dst_ret1->addr = &Y0; dst_ret1->data_type = DT_WORD; dst_ret2->addr = &X0; dst_ret2->data_type = DT_WORD; break; + case 0x2: dst_ret1->addr = &X1; dst_ret1->data_type = DT_WORD; dst_ret2->addr = &X0; dst_ret2->data_type = DT_WORD; break; + case 0x3: dst_ret1->addr = &Y1; dst_ret1->data_type = DT_WORD; dst_ret2->addr = &X0; dst_ret2->data_type = DT_WORD; break; + case 0x4: dst_ret1->addr = &X0; dst_ret1->data_type = DT_WORD; dst_ret2->addr = &X1; dst_ret2->data_type = DT_WORD; break; + case 0x5: dst_ret1->addr = &Y0; dst_ret1->data_type = DT_WORD; dst_ret2->addr = &X1; dst_ret2->data_type = DT_WORD; break; + case 0x6: dst_ret1->addr = opposite; dst_ret1->data_type = DT_LONG_WORD; dst_ret2->addr = &Y0; dst_ret2->data_type = DT_WORD; break; + case 0x7: dst_ret1->addr = &Y1; dst_ret1->data_type = DT_WORD; dst_ret2->addr = &X1; dst_ret2->data_type = DT_WORD; break; + } +} + +static void decode_QQF_table(UINT16 QQ, UINT16 F, void **S1, void **S2, void **D) +{ + UINT16 switchVal = (QQ << 1) | F ; + + switch(switchVal) + { + case 0x0: *S1 = &X0; *S2 = &Y0; *D = &A; break; + case 0x1: *S1 = &X0; *S2 = &Y0; *D = &B; break; + case 0x2: *S1 = &X0; *S2 = &Y1; *D = &A; break; + case 0x3: *S1 = &X0; *S2 = &Y1; *D = &B; break; + case 0x4: *S1 = &X1; *S2 = &Y0; *D = &A; break; + case 0x5: *S1 = &X1; *S2 = &Y0; *D = &B; break; + case 0x6: *S1 = &X1; *S2 = &Y1; *D = &A; break; + case 0x7: *S1 = &X1; *S2 = &Y1; *D = &B; break; + } +} + static void decode_QQF_special_table(UINT16 QQ, UINT16 F, void **S1, void **S2, void **D) { UINT16 switchVal = (QQ << 1) | F ; @@ -3528,7 +3973,7 @@ static void decode_QQF_special_table(UINT16 QQ, UINT16 F, void **S1, void **S2, } } -static void decode_QQQF_special_table(UINT16 QQQ, UINT16 F, void **S1, void **S2, void **D) +static void decode_QQQF_table(UINT16 QQQ, UINT16 F, void **S1, void **S2, void **D) { UINT16 switchVal = (QQQ << 1) | F; @@ -3564,6 +4009,92 @@ static void decode_RR_table(UINT16 RR, typed_pointer* ret) } } +static void decode_TT_table(UINT16 TT, typed_pointer* ret) +{ + switch(TT) + { + case 0x00: ret->addr = &R0; ret->data_type = DT_WORD; break; + case 0x01: ret->addr = &R1; ret->data_type = DT_WORD; break; + case 0x02: ret->addr = &R2; ret->data_type = DT_WORD; break; + case 0x03: ret->addr = &R3; ret->data_type = DT_WORD; break; + } +} + + +static void decode_uuuuF_table(UINT16 uuuu, UINT16 F, UINT8 add_sub_other, typed_pointer* src_ret, typed_pointer* dst_ret) +{ + UINT16 switchVal = (uuuu << 1) | F; + + /* Unknown uuuuFs have been seen in the wild */ + add_sub_other = OP_OTHER; + src_ret->addr = NULL; src_ret->data_type = DT_BYTE; + dst_ret->addr = NULL; dst_ret->data_type = DT_BYTE; + + switch(switchVal) + { + case 0x00: add_sub_other = OP_ADD; + src_ret->addr = &X0; src_ret->data_type = DT_WORD; + dst_ret->addr = &A; dst_ret->data_type = DT_LONG_WORD; break; + case 0x08: add_sub_other = OP_SUB; + src_ret->addr = &X0; src_ret->data_type = DT_WORD; + dst_ret->addr = &A; dst_ret->data_type = DT_LONG_WORD; break; + case 0x01: add_sub_other = OP_ADD; + src_ret->addr = &X0; src_ret->data_type = DT_WORD; + dst_ret->addr = &B; dst_ret->data_type = DT_LONG_WORD; break; + case 0x09: add_sub_other = OP_SUB; + src_ret->addr = &X0; src_ret->data_type = DT_WORD; + dst_ret->addr = &B; dst_ret->data_type = DT_LONG_WORD; break; + case 0x02: add_sub_other = OP_ADD; + src_ret->addr = &Y0; src_ret->data_type = DT_WORD; + dst_ret->addr = &A; dst_ret->data_type = DT_LONG_WORD; break; + case 0x0a: add_sub_other = OP_SUB; + src_ret->addr = &Y0; src_ret->data_type = DT_WORD; + dst_ret->addr = &A; dst_ret->data_type = DT_LONG_WORD; break; + case 0x03: add_sub_other = OP_ADD; + src_ret->addr = &Y0; src_ret->data_type = DT_WORD; + dst_ret->addr = &B; dst_ret->data_type = DT_LONG_WORD; break; + case 0x0b: add_sub_other = OP_SUB; + src_ret->addr = &Y0; src_ret->data_type = DT_WORD; + dst_ret->addr = &B; dst_ret->data_type = DT_LONG_WORD; break; + case 0x04: add_sub_other = OP_ADD; + src_ret->addr = &X1; src_ret->data_type = DT_WORD; + dst_ret->addr = &A; dst_ret->data_type = DT_LONG_WORD; break; + case 0x0c: add_sub_other = OP_SUB; + src_ret->addr = &X1; src_ret->data_type = DT_WORD; + dst_ret->addr = &A; dst_ret->data_type = DT_LONG_WORD; break; + case 0x05: add_sub_other = OP_ADD; + src_ret->addr = &X1; src_ret->data_type = DT_WORD; + dst_ret->addr = &B; dst_ret->data_type = DT_LONG_WORD; break; + case 0x0d: add_sub_other = OP_SUB; + src_ret->addr = &X1; src_ret->data_type = DT_WORD; + dst_ret->addr = &B; dst_ret->data_type = DT_LONG_WORD; break; + case 0x06: add_sub_other = OP_ADD; + src_ret->addr = &Y1; src_ret->data_type = DT_WORD; + dst_ret->addr = &A; dst_ret->data_type = DT_LONG_WORD; break; + case 0x0e: add_sub_other = OP_SUB; + src_ret->addr = &Y1; src_ret->data_type = DT_WORD; + dst_ret->addr = &A; dst_ret->data_type = DT_LONG_WORD; break; + case 0x07: add_sub_other = OP_ADD; + src_ret->addr = &Y1; src_ret->data_type = DT_WORD; + dst_ret->addr = &B; dst_ret->data_type = DT_LONG_WORD; break; + case 0x0f: add_sub_other = OP_SUB; + src_ret->addr = &Y1; src_ret->data_type = DT_WORD; + dst_ret->addr = &B; dst_ret->data_type = DT_LONG_WORD; break; + case 0x18: add_sub_other = OP_ADD; + src_ret->addr = &B; src_ret->data_type = DT_LONG_WORD; + dst_ret->addr = &A; dst_ret->data_type = DT_LONG_WORD; break; + case 0x1a: add_sub_other = OP_SUB; + src_ret->addr = &B; src_ret->data_type = DT_LONG_WORD; + dst_ret->addr = &A; dst_ret->data_type = DT_LONG_WORD; break; + case 0x19: add_sub_other = OP_ADD; + src_ret->addr = &A; src_ret->data_type = DT_LONG_WORD; + dst_ret->addr = &B; dst_ret->data_type = DT_LONG_WORD; break; + case 0x1b: add_sub_other = OP_SUB; + src_ret->addr = &A; src_ret->data_type = DT_LONG_WORD; + dst_ret->addr = &B; dst_ret->data_type = DT_LONG_WORD; break; + } +} + static void decode_Z_table(UINT16 Z, typed_pointer* ret) { switch(Z) @@ -3594,6 +4125,28 @@ static void execute_m_table(int x, UINT16 m) } } +static void execute_mm_table(UINT16 rnum, UINT16 mm) +{ + UINT16 *rX = NULL; + UINT16 *nX = NULL; + + switch(rnum) + { + case 0x0: rX = &R0; nX = &N0; break; + case 0x1: rX = &R1; nX = &N1; break; + case 0x2: rX = &R2; nX = &N2; break; + case 0x3: fatalerror("Dsp56k: Error. execute_mm_table specified R3 as its first source!"); break; + } + + switch(mm) + { + case 0x0: (*rX)++; R3++; break; + case 0x1: (*rX)++; R3 = R3 + N3; break; + case 0x2: (*rX) = (*rX) + (*nX); R3++; break; + case 0x3: (*rX) = (*rX) + (*nX); R3 = R3 + N3; break; + } +} + static void execute_MM_table(UINT16 rnum, UINT16 MM) { UINT16 *rX = 0x00 ; @@ -3637,8 +4190,8 @@ static UINT16 execute_q_table(int RR, UINT16 q) } /* Should not get here */ - exit(1); - return 0x00; + fatalerror("dsp56k: execute_q_table did something impossible!"); + return 0; } static void execute_z_table(int RR, UINT16 z) @@ -3757,7 +4310,7 @@ static void dsp56k_process_rep(size_t repSize) /*************************************************************************** Parallel Memory Ops ***************************************************************************/ -/* Register to Register Data Move : 0100 IIII ---- ---- : A-132 */ +/* Register to Register Data Move : 0100 IIII .... .... : A-132 */ static void execute_register_to_register_data_move(const UINT16 op, typed_pointer* d_register, UINT64* prev_accum_value) { typed_pointer S = {NULL, DT_BYTE}; @@ -3779,13 +4332,13 @@ static void execute_register_to_register_data_move(const UINT16 op, typed_pointe } } -/* Address Register Update : 0011 0zRR ---- ---- : A-135 */ +/* Address Register Update : 0011 0zRR .... .... : A-135 */ static void execute_address_register_update(const UINT16 op, typed_pointer* d_register, UINT64* prev_accum_value) { execute_z_table(BITS(op,0x0300), BITS(op,0x0400)); } -/* X Memory Data Move : 1mRR HHHW ---- ---- : A-137 */ +/* X Memory Data Move : 1mRR HHHW .... .... : A-137 */ static void execute_x_memory_data_move(const UINT16 op, typed_pointer* d_register, UINT64* prev_accum_value) { UINT16 W; @@ -3828,8 +4381,7 @@ static void execute_x_memory_data_move(const UINT16 op, typed_pointer* d_registe execute_m_table(BITS(op,0x3000), BITS(op,0x4000)); } - -/* X Memory Data Move : 0101 HHHW ---- ---- : A-137 */ +/* X Memory Data Move : 0101 HHHW .... .... : A-137 */ /* NOTE: previous accumulator value is not needed since ^F1 is always the opposite accumulator */ static void execute_x_memory_data_move2(const UINT16 op, typed_pointer* d_register) { @@ -3859,6 +4411,73 @@ static void execute_x_memory_data_move2(const UINT16 op, typed_pointer* d_regist } } +/* X Memory Data Move With Short Displacement : 0000 0101 BBBB BBBB ---- HHHW .... .... : A-139 */ +static void execute_x_memory_data_move_with_short_displacement(const UINT16 op, const UINT16 op2) +{ + INT8 xx; + UINT8 W; + UINT16 memOffset; + typed_pointer SD = { NULL, DT_BYTE }; + + xx = (INT8)(op & 0x00ff); + W = BITS(op2,0x0100); + decode_HHH_table(BITS(op2,0x0e00), &SD); + + memOffset = R2 + (INT16)xx; + + if (W) + { + /* Write D */ + UINT16 tempData = data_read_word_16le(WORD(memOffset)); + typed_pointer temp_src = { (void*)&tempData, DT_WORD }; + SetDestinationValue(temp_src, SD); + } + else + { + /* Read S */ + UINT16 tempData = *((UINT16*)SD.addr); + typed_pointer temp_src = { (void*)&tempData, DT_WORD }; + SetDataMemoryValue(temp_src, WORD(memOffset)); + } +} + +/* Dual X Memory Data Read : 011m mKKK .rr. .... : A-142*/ +static void execute_dual_x_memory_data_read(const UINT16 op, typed_pointer* d_register) +{ + typed_pointer tempV; + UINT16 srcVal1 = 0x0000; + UINT16 srcVal2 = 0x0000; + typed_pointer R = {NULL, DT_BYTE}; + typed_pointer D1 = {NULL, DT_BYTE}; + typed_pointer D2 = {NULL, DT_BYTE}; + + decode_RR_table(BITS(op,0x0060), &R); + decode_KKK_table(BITS(op,0x0700), &D1, &D2, d_register->addr); + + /* Can't do an R3 for S1 */ + if (R.addr == &R3) + fatalerror("Dsp56k: Error. Dual x memory data read specified R3 as its first source!"); + + /* The note on A-142 is very interesting. + You can effectively access external memory in the last 64 bytes of X data memory! */ + if (*((UINT16*)D2.addr) >= 0xffc0) + fatalerror("Dsp56k: Unimplemented access to external X Data Memory >= 0xffc0 in Dual X Memory Data Read."); + + /* First memmove */ + srcVal1 = data_read_word_16le(WORD(*((UINT16*)R.addr))); + tempV.addr = &srcVal1; + tempV.data_type = DT_WORD; + SetDestinationValue(tempV, D1); + + /* Second memmove */ + srcVal2 = data_read_word_16le(WORD(R3)); + tempV.addr = &srcVal2; + tempV.data_type = DT_WORD; + SetDestinationValue(tempV, D2); + + /* Touch up the R regs after all the moves */ + execute_mm_table(BITS(op,0x0060), BITS(op,0x1800)); +} /*************************************************************************** Helper Functions @@ -3909,7 +4528,7 @@ static void SetDestinationValue(typed_pointer source, typed_pointer dest) case DT_BYTE: *((UINT16*)dest.addr) = (*((UINT8*) source.addr)) & 0xff; break; case DT_WORD: *((UINT16*)dest.addr) = (*((UINT16*)source.addr)) & 0xffff; break; case DT_DOUBLE_WORD: *((UINT16*)dest.addr) = (*((UINT32*)source.addr)) & 0x0000ffff; break; - case DT_LONG_WORD: *((UINT16*)dest.addr) = (*((UINT64*)source.addr)) & U64(0x000000000000ffff); break; /* Shift limiter action? */ + case DT_LONG_WORD: *((UINT16*)dest.addr) = (*((UINT64*)source.addr)) & U64(0x000000000000ffff); break; /* TODO: Shift limiter action! A-147 */ } break ; diff --git a/src/mame/drivers/plygonet.c b/src/mame/drivers/plygonet.c index 4ef9f8f2cc0..1ca7e934fa4 100644 --- a/src/mame/drivers/plygonet.c +++ b/src/mame/drivers/plygonet.c @@ -596,7 +596,7 @@ static MACHINE_DRIVER_START( plygonet ) MDRV_CPU_PROGRAM_MAP(main_map, 0) MDRV_CPU_VBLANK_INT("main", polygonet_interrupt) - MDRV_CPU_ADD("dsp", DSP56156, 10000000) /* xtal is 40.0 MHz */ + MDRV_CPU_ADD("dsp", DSP56156, 40000000) /* xtal is 40.0 MHz */ MDRV_CPU_PROGRAM_MAP(dsp_program_map, 0) MDRV_CPU_DATA_MAP(dsp_data_map, 0) @@ -641,24 +641,24 @@ MACHINE_DRIVER_END static INPUT_PORTS_START( polygonet ) PORT_START("IN0") - PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_BUTTON1 ) /* Service */ - PORT_SERVICE_NO_TOGGLE( 0x02, IP_ACTIVE_LOW ) /* Test Switch */ - PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_BUTTON2 ) /* Coin Mech Switch 1 */ + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_SERVICE1 ) + PORT_SERVICE_NO_TOGGLE( 0x02, IP_ACTIVE_LOW ) + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_COIN1 ) PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_BUTTON3 ) - PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON4 ) /* SW1 */ - PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON5 ) /* SW2 */ + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON4 ) /* SW1 (changes player color). It's mapped on the JAMMA connector and plugs into an external switch mech. */ + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON5 ) /* SW2 (changes player color). It's mapped on the JAMMA connector and plugs into an external switch mech. */ PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_BUTTON6 ) PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_BUTTON7 ) PORT_START("IN1") - PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_BUTTON8 ) /* Joy2 Up */ - PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_BUTTON9 ) /* Joy2 Down */ - PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_BUTTON10 ) /* Joy1 Up */ - PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_BUTTON11 ) /* Joy1 Down */ - PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON12 ) /* Joy1 Fire */ - PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON13 ) /* Joy2 Fire */ - PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_BUTTON14 ) - PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_BUTTON15 ) + PORT_BIT( 0x01, IP_ACTIVE_LOW, IPT_JOYSTICKRIGHT_UP ) PORT_PLAYER(1) + PORT_BIT( 0x02, IP_ACTIVE_LOW, IPT_JOYSTICKRIGHT_DOWN ) PORT_PLAYER(1) + PORT_BIT( 0x04, IP_ACTIVE_LOW, IPT_JOYSTICKLEFT_UP ) PORT_PLAYER(1) + PORT_BIT( 0x08, IP_ACTIVE_LOW, IPT_JOYSTICKLEFT_DOWN ) PORT_PLAYER(1) + PORT_BIT( 0x10, IP_ACTIVE_LOW, IPT_BUTTON1 ) PORT_PLAYER(1) + PORT_BIT( 0x20, IP_ACTIVE_LOW, IPT_BUTTON2 ) PORT_PLAYER(1) + PORT_BIT( 0x40, IP_ACTIVE_LOW, IPT_BUTTON8 ) + PORT_BIT( 0x80, IP_ACTIVE_LOW, IPT_BUTTON9 ) INPUT_PORTS_END static DRIVER_INIT(polygonet) |