diff options
author | 2009-09-18 04:37:47 +0000 | |
---|---|---|
committer | 2009-09-18 04:37:47 +0000 | |
commit | 77a3badd3294082f706fb3f93698443b32d2081c (patch) | |
tree | b3f24990097d2ca91031a1f7a89667682570f744 /src/emu/cpu/dsp56k | |
parent | e0320b80e34c5fc3d3133a38ce5862164c87ab99 (diff) |
Fixed various issues with the dsp56156 disassembler. [Andrew Gardner]
(Off the record)
I verified this thing against IDA Pro's 56156 disassembler and the docs.
Every time I found a bug in IDA's disassembler, I cross-referenced the
manual. There remain 3 opcodes which are questionably disassembled,
since even the manual is ambiguous on the details, but beyond that,
this thing should be 100% correct.
Whew. This might have actually fleshed out a bug in the
disassembly/execution. Time will tell...
Diffstat (limited to 'src/emu/cpu/dsp56k')
-rw-r--r-- | src/emu/cpu/dsp56k/dsp56dsm.c | 415 | ||||
-rw-r--r-- | src/emu/cpu/dsp56k/dsp56ops.c | 20 |
2 files changed, 242 insertions, 193 deletions
diff --git a/src/emu/cpu/dsp56k/dsp56dsm.c b/src/emu/cpu/dsp56k/dsp56dsm.c index 7173b517acf..67952b92100 100644 --- a/src/emu/cpu/dsp56k/dsp56dsm.c +++ b/src/emu/cpu/dsp56k/dsp56dsm.c @@ -1,14 +1,15 @@ /*************************************************************************** - dsp56dsm.c - Disassembler for the portable Motorola/Freescale dsp56k emulator. - Written by Andrew Gardner + dsp56dsm.c + Disassembler for the portable Motorola/Freescale dsp56k emulator. + Written by Andrew Gardner ***************************************************************************/ /* - 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 95% verified against the docs and a different disassembler. + The docs list some conflicting and confusing behaviors. These are mareked with an asterisk + and need to be tested on real hardware before this disassembler is considered 100% complete. */ #include "dsp56k.h" @@ -16,13 +17,13 @@ /*******************/ /* Dasm prototypes */ /*******************/ -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_tfr_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, char* d_register); +static size_t dsp56k_dasm_mac_1 (const UINT16 op_byte, char* opcode_str, char* arg_str, char* d_register); +static size_t dsp56k_dasm_macr_1 (const UINT16 op_byte, char* opcode_str, char* arg_str, char* d_register); +static size_t dsp56k_dasm_tfr_2 (const UINT16 op_byte, char* opcode_str, char* arg_str, char* d_register); +static size_t dsp56k_dasm_move_1 (const UINT16 op_byte, char* opcode_str, char* arg_str, char* d_register); +static size_t dsp56k_dasm_mpy_1 (const UINT16 op_byte, char* opcode_str, char* arg_str, char* d_register); +static size_t dsp56k_dasm_mpyr_1 (const UINT16 op_byte, char* opcode_str, char* arg_str, char* d_register); 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); static size_t dsp56k_dasm_clr (const UINT16 op_byte, char* opcode_str, char* arg_str, char* d_register); @@ -79,10 +80,10 @@ static size_t dsp56k_dasm_debug (const UINT16 op, char* opcode_str, char* arg_s static size_t dsp56k_dasm_debugcc (const UINT16 op, char* opcode_str, char* arg_str); static size_t dsp56k_dasm_div (const UINT16 op, char* opcode_str, char* arg_str); static size_t dsp56k_dasm_dmac (const UINT16 op, char* opcode_str, char* arg_str); -static size_t dsp56k_dasm_do (const UINT16 op, const UINT16 op2, char* opcode_str, char* arg_str); -static size_t dsp56k_dasm_do_1 (const UINT16 op, const UINT16 op2, char* opcode_str, char* arg_str); -static size_t dsp56k_dasm_do_2 (const UINT16 op, const UINT16 op2, char* opcode_str, char* arg_str); -static size_t dsp56k_dasm_doforever (const UINT16 op, const UINT16 op2, char* opcode_str, char* arg_str); +static size_t dsp56k_dasm_do (const UINT16 op, const UINT16 op2, char* opcode_str, char* arg_str, const offs_t pc); +static size_t dsp56k_dasm_do_1 (const UINT16 op, const UINT16 op2, char* opcode_str, char* arg_str, const offs_t pc); +static size_t dsp56k_dasm_do_2 (const UINT16 op, const UINT16 op2, char* opcode_str, char* arg_str, const offs_t pc); +static size_t dsp56k_dasm_doforever (const UINT16 op, const UINT16 op2, char* opcode_str, char* arg_str, const offs_t pc); static size_t dsp56k_dasm_enddo (const UINT16 op, char* opcode_str, char* arg_str); static size_t dsp56k_dasm_ext (const UINT16 op, char* opcode_str, char* arg_str); static size_t dsp56k_dasm_illegal (const UINT16 op, char* opcode_str, char* arg_str); @@ -189,12 +190,13 @@ static INT8 get_6_bit_signed_value(UINT16 bits); /**********************************/ static void decode_x_memory_data_move(const UINT16 op, char* parallel_move_str); static void decode_x_memory_data_move2(const UINT16 op, char* parallel_move_str, char* d_register); -static void decode_dual_x_memory_data_read(const UINT16 op, char* parallel_move_str, char* parallel_move_str2); +static void decode_dual_x_memory_data_read(const UINT16 op, char* parallel_move_str, char* parallel_move_str2, char* d_register); static void decode_register_to_register_data_move(const UINT16 op, char* parallel_move_str, char* d_register); static void decode_x_memory_data_write_and_register_data_move(const UINT16 op, char* parallel_move_str, char* parallel_move_str2); static void decode_address_register_update(const UINT16 op, char* parallel_move_str); static void decode_x_memory_data_move_with_short_displacement(const UINT16 op, const UINT16 op2, char* parallel_move_str); + /********************/ /* Helper functions */ /********************/ @@ -202,7 +204,8 @@ static void decode_x_memory_data_move_with_short_displacement(const UINT16 op, c static UINT16 dsp56k_op_mask(UINT16 op, UINT16 mask); static void pad_string(const int dest_length, char* string); -enum bbbType { BBB_UPPER, BBB_MIDDLE, BBB_LOWER }; +enum bbbType { BBB_UPPER, BBB_MIDDLE, BBB_LOWER, BBB_INVALID }; + /*****************************/ @@ -222,53 +225,62 @@ CPU_DISASSEMBLE( dsp56k ) const UINT16 op = oprom[0] | (oprom[1] << 8); const UINT16 op2 = oprom[2] | (oprom[3] << 8); - /* Dual X Memory Data Read : 011m mKKK -rr- ---- : A-142*/ + /* Dual X Memory Data Read : 011m mKKK .rr. .... : A-142*/ if ((op & 0xe000) == 0x6000) { + char d_register[32] = ""; + /* 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) + /* Note: 0x0094 check allows command to drop through to MOVE and TFR */ + if (((op & 0xe080) == 0x6000) && ((op & 0x0094) != 0x0010)) { - size = dsp56k_dasm_addsub_2(op_byte, opcode_str, arg_str); + size = dsp56k_dasm_addsub_2(op_byte, opcode_str, arg_str, d_register); } /* MAC : 011m mKKK 1xx0 F1QQ : A-122 */ else if ((op & 0xe094) == 0x6084) { - size = dsp56k_dasm_mac_1(op_byte, opcode_str, arg_str); + size = dsp56k_dasm_mac_1(op_byte, opcode_str, arg_str, d_register); } /* MACR: 011m mKKK 1--1 F1QQ : A-124 */ else if ((op & 0xe094) == 0x6094) { - size = dsp56k_dasm_macr_1(op_byte, opcode_str, arg_str); + size = dsp56k_dasm_macr_1(op_byte, opcode_str, arg_str, d_register); + } + /* TFR : 011m mKKK 0rr1 F0DD : A-212 */ + else if ((op & 0xe094) == 0x6010) + { + size = dsp56k_dasm_tfr_2(op_byte, opcode_str, arg_str, d_register); } /* MOVE : 011m mKKK 0rr1 0000 : A-128 */ else if ((op & 0xe09f) == 0x6010) { - size = dsp56k_dasm_move_1(op_byte, opcode_str, arg_str); + /* Note: The opcode encoding : 011x xxxx 0xx1 0000 (move + double memory read) + is .identical. to (tfr X0,A + two parallel reads). This sparks the notion + that these 'move' opcodes don't actually exist and are just there as + documentation. Real-world examples would need to be examined to come + to a satisfactory conclusion, but as it stands, tfr will override this + move operation. */ + size = dsp56k_dasm_move_1(op_byte, opcode_str, arg_str, d_register); } /* MPY : 011m mKKK 1xx0 F0QQ : A-160 */ else if ((op & 0xe094) == 0x6080) { - size = dsp56k_dasm_mpy_1(op_byte, opcode_str, arg_str); + size = dsp56k_dasm_mpy_1(op_byte, opcode_str, arg_str, d_register); } /* MPYR : 011m mKKK 1--1 F0QQ : A-162 */ else if ((op & 0xe094) == 0x6090) { - size = dsp56k_dasm_mpyr_1(op_byte, opcode_str, arg_str); - } - /* TFR : 011m mKKK 0rr1 F0DD : A-212 */ - else if ((op & 0xe094) == 0x6010) - { - size = dsp56k_dasm_tfr_2(op_byte, opcode_str, arg_str); + size = dsp56k_dasm_mpyr_1(op_byte, opcode_str, arg_str, d_register); } /* Now evaluate the parallel data move */ - decode_dual_x_memory_data_read(op, parallel_move_str, parallel_move_str2); + decode_dual_x_memory_data_read(op, parallel_move_str, parallel_move_str2, 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) */ @@ -344,10 +356,10 @@ CPU_DISASSEMBLE( dsp56k ) /* 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 - */ + 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)) @@ -734,7 +746,7 @@ CPU_DISASSEMBLE( dsp56k ) { size = dsp56k_dasm_bscc(op, op2, opcode_str, arg_str, pc); } - /* BScc: 0000 0111 RR00 cccc : A-54 */ + /* BScc : 0000 0111 RR00 cccc : A-54 */ else if ((op & 0xff30) == 0x0700) { size = dsp56k_dasm_bscc_1(op, opcode_str, arg_str); @@ -765,7 +777,6 @@ CPU_DISASSEMBLE( dsp56k ) size = dsp56k_dasm_debugcc(op, opcode_str, arg_str); } /* DIV : 0001 0101 0--0 F1DD : A-76 */ - /* WARNING : DOCS SAY THERE IS A PARALLEL MOVE HERE !!! */ else if ((op & 0xff94) == 0x1504) { size = dsp56k_dasm_div(op, opcode_str, arg_str); @@ -778,22 +789,22 @@ CPU_DISASSEMBLE( dsp56k ) /* DO : 0000 0000 110- --RR xxxx xxxx xxxx xxxx : A-82 */ else if (((op & 0xffe0) == 0x00c0) && ((op2 & 0x0000) == 0x0000)) { - size = dsp56k_dasm_do(op, op2, opcode_str, arg_str); + size = dsp56k_dasm_do(op, op2, opcode_str, arg_str, pc); } /* DO : 0000 1110 iiii iiii xxxx xxxx xxxx xxxx : A-82 */ else if (((op & 0xff00) == 0x0e00) && ((op2 & 0x0000) == 0x0000)) { - size = dsp56k_dasm_do_1(op, op2, opcode_str, arg_str); + size = dsp56k_dasm_do_1(op, op2, opcode_str, arg_str, pc); } /* DO : 0000 0100 000D DDDD xxxx xxxx xxxx xxxx : A-82 */ else if (((op & 0xffe0) == 0x0400) && ((op2 & 0x0000) == 0x0000)) { - size = dsp56k_dasm_do_2(op, op2, opcode_str, arg_str); + size = dsp56k_dasm_do_2(op, op2, opcode_str, arg_str, pc); } /* DO FOREVER : 0000 0000 0000 0010 xxxx xxxx xxxx xxxx : A-88 */ else if (((op & 0xffff) == 0x0002) && ((op2 & 0x0000) == 0x0000)) { - size = dsp56k_dasm_doforever(op, op2, opcode_str, arg_str); + size = dsp56k_dasm_doforever(op, op2, opcode_str, arg_str, pc); } /* ENDDO : 0000 0000 0000 1001 : A-92 */ else if ((op & 0xffff) == 0x0009) @@ -1080,7 +1091,7 @@ CPU_DISASSEMBLE( dsp56k ) /* ADD : 011m mKKK 0rru Fuuu : A-22 */ /* SUB : 011m mKKK 0rru Fuuu : A-202 */ -static size_t dsp56k_dasm_addsub_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, char* d_register) { /* TODO: How strange. Same as SUB? Investigate */ char D[32]; @@ -1089,117 +1100,112 @@ static size_t dsp56k_dasm_addsub_2(const UINT16 op_byte, char* opcode_str, char* 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); + sprintf(d_register, "%s", D); return 1; } /* MAC : 011m mKKK 1xx0 F1QQ : A-122 */ -static size_t dsp56k_dasm_mac_1(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, char* d_register) { char D[32]; char S1[32]; char S2[32]; - /* Oddly, these 4 mpxx ops have identical operand ordering as compared to single memory move equivalents */ decode_QQF_table(BITS(op_byte,0x03), BITS(op_byte,0x08), S1, S2, D); - sprintf(arg_str, "%s,%s,%s", S1, S2, D); sprintf(opcode_str, "mac"); + sprintf(arg_str, "%s,%s,%s", S1, S2, D); + sprintf(d_register, "%s", D); return 1; } /* MACR: 011m mKKK 1--1 F1QQ : A-124 */ -static size_t dsp56k_dasm_macr_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, char* d_register) { char D[32]; char S1[32]; char S2[32]; - /* Oddly, these 4 mpxx ops have identical operand ordering as compared to single memory move equivalents */ decode_QQF_table(BITS(op_byte,0x03), BITS(op_byte,0x08), S1, S2, D); - sprintf(arg_str, "%s,%s,%s", S1, S2, D); sprintf(opcode_str, "macr"); + sprintf(arg_str, "%s,%s,%s", S1, S2, D); + sprintf(d_register, "%s", 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, char* d_register) +{ + /* Note: This opcode collides with move_1 when F0DD is 0000. Needs verifying on a real CPU. */ + char D[32]; + char S1[32]; + decode_DDF_table(BITS(op_byte,0x03), BITS(op_byte,0x08), S1, D); + sprintf(opcode_str, "tfr"); + if (BITS(op_byte,0x0f) == 0x00) + strcat(opcode_str, "*"); /* This asterisk is to denote that this opcode may have an error with its disassembly */ + sprintf(arg_str, "%s,%s", S1, D); + sprintf(d_register, "%s", D); return 1; } /* MOVE : 011m mKKK 0rr1 0000 : A-128 */ -static size_t dsp56k_dasm_move_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, char* d_register) { - /* TODO: This MOVE opcode is .identical. to the TFR one. Investigate */ + /* Note: This opcode collides with tfr_2 & will never be disassembled. Needs verifying on a real CPU. */ char D[32]; char S1[32]; decode_DDF_table(BITS(op_byte,0x03), BITS(op_byte,0x08), S1, D); sprintf(opcode_str, "tfr"); sprintf(arg_str, "%s,%s", S1, D); + sprintf(d_register, "%s", D); return 1; } /* MPY : 011m mKKK 1xx0 F0QQ : A-160 */ -static size_t dsp56k_dasm_mpy_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, char* d_register) { char D[32]; char S1[32]; char S2[32]; - /* Oddly, these 4 mpxx ops have identical operand ordering as compared to single memory move equivalents */ decode_QQF_table(BITS(op_byte,0x03), BITS(op_byte,0x08), S1, S2, D); - sprintf(arg_str, "%s,%s,%s", S1, S2, D); sprintf(opcode_str, "mpy"); + sprintf(arg_str, "%s,%s,%s", S1, S2, D); + sprintf(d_register, "%s", D); return 1; } /* MPYR : 011m mKKK 1--1 F0QQ : A-162 */ -static size_t dsp56k_dasm_mpyr_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, char* d_register) { char D[32]; char S1[32]; char S2[32]; - /* Oddly, these 4 mpxx ops have identical operand ordering as compared to single memory move equivalents */ decode_QQF_table(BITS(op_byte,0x03), BITS(op_byte,0x08), S1, S2, D); - sprintf(arg_str, "%s,%s,%s", S1, S2, D); sprintf(opcode_str, "mpyr"); + sprintf(arg_str, "%s,%s,%s", S1, S2, D); + sprintf(d_register, "%s", 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) +/* MPY : 0001 0110 RRDD FQQQ : A-160 */ +static size_t dsp56k_dasm_mpy_2(const UINT16 op_byte, char* opcode_str, char* arg_str) { - /* TODO - Same as move above. Investigate */ char D[32]; char S1[32]; - decode_DDF_table(BITS(op_byte,0x03), BITS(op_byte,0x08), S1, D); - sprintf(opcode_str, "tfr"); - sprintf(arg_str, "%s,%s", S1, D); + char S2[32]; + decode_QQQF_table(BITS(op_byte,0x0007), BITS(op_byte,0x0008), S1, S2, D); + sprintf(opcode_str, "mpy"); + sprintf(arg_str, "%s,%s,%s", S1, S2, D); return 1; } -/* MPY : 0001 0110 RRDD FQQQ : A-160 */ -static size_t dsp56k_dasm_mpy_2(const UINT16 op_byte, char* opcode_str, char* arg_str) -{ -/* TODO - // MPY - 0001 0110 RRDD FQQQ - decode_k_table(BITS(op,0x0100), Dnot); - Rnum = decode_RR_table(BITS(op,0x00c0)); - decode_DD_table(BITS(op,0x0030), S); - decode_QQQF_table(BITS(op,0x0007), BITS(op,0x0008), S1, S2, D); - sprintf(buffer, "mpy %s,%s,%s %s,(R%d)+N%d %s,%s", S1, S2, D, Dnot, Rnum, Rnum, S, Dnot); - // Strange, but not entirely out of the question - this 'k' parameter is hardcoded - // I cheat here and do the parallel memory data move above - this specific one is only used twice - retSize = 1; -*/ - return 0; -} - /* MAC : 0001 0111 RRDD FQQQ : A-122 */ static size_t dsp56k_dasm_mac_2(const UINT16 op_byte, char* opcode_str, char* arg_str) { -/* TODO - // MAC - 0001 0111 RRDD FQQQ - decode_k_table(BITS(op,0x0100), Dnot); - Rnum = decode_RR_table(BITS(op,0x00c0)); - decode_DD_table(BITS(op,0x0030), S); - decode_QQQF_table(BITS(op,0x0007), BITS(op,0x0008), S1, S2, D); - sprintf(buffer, "mac %s,%s,%s %s,(R%d)+N%d %s,%s", S1, S2, D, Dnot, Rnum, Rnum, S, Dnot); - // Strange, but not entirely out of the question - this 'k' parameter is hardcoded - // I cheat here and do the parallel memory data move above - this specific one is only used twice - retSize = 1; -*/ - return 0; + char D[32]; + char S1[32]; + char S2[32]; + decode_QQQF_table(BITS(op_byte,0x0007), BITS(op_byte,0x0008), S1, S2, D); + sprintf(opcode_str, "mac"); + sprintf(arg_str, "%s,%s,%s", S1, S2, D); + return 1; } /* CLR : .... .... 0000 F001 : A-60 */ @@ -1364,7 +1370,7 @@ static size_t dsp56k_dasm_subl(const UINT16 op_byte, char* opcode_str, char* arg { sprintf(opcode_str, "subl"); - /* Only one option for the F table */ + /* There is only one option for the F table. This is a very strange opcode. */ if (!BITS(op_byte,0x08)) { sprintf(arg_str, "B,A"); @@ -1372,7 +1378,8 @@ static size_t dsp56k_dasm_subl(const UINT16 op_byte, char* opcode_str, char* arg } else { - sprintf(arg_str, "!"); + sprintf(arg_str, "!,!"); + sprintf(d_register, "!"); } return 1; @@ -1418,10 +1425,11 @@ static size_t dsp56k_dasm_cmp(const UINT16 op_byte, char* opcode_str, char* arg_ { char D[32]; char S1[32]; + /* Note: This is a JJJF limited in the docs, but other opcodes sneak + in before cmp, so the same decode function can be used. */ decode_JJJF_table(BITS(op_byte,0x07), BITS(op_byte,0x08), S1, D); - /* TODO: This is a JJJF limited */ sprintf(opcode_str, "cmp"); - sprintf(arg_str, "%s,%s", S1,D); + sprintf(arg_str, "%s,%s", S1, D); sprintf(d_register, "%s", D); return 1; } @@ -1520,10 +1528,11 @@ static size_t dsp56k_dasm_cmpm(const UINT16 op_byte, char* opcode_str, char* arg { char D[32]; char S1[32]; + /* Note: This is a JJJF limited in the docs, but other opcodes sneak + in before cmp, so the same decode function can be used. */ decode_JJJF_table(BITS(op_byte,0x07), BITS(op_byte,0x08), S1, D); - /* TODO: This is JJJF limited */ sprintf(opcode_str, "cmpm"); - sprintf(arg_str, "%s,%s", S1,D); + sprintf(arg_str, "%s,%s", S1, D); sprintf(d_register, "%s", D); return 1; } @@ -1531,14 +1540,19 @@ static size_t dsp56k_dasm_cmpm(const UINT16 op_byte, char* opcode_str, char* arg /* MPY : .... .... 1k00 FQQQ : A-160 -- CONFIRMED TYPO IN DOCS (HHHH vs HHHW) */ static size_t dsp56k_dasm_mpy(const UINT16 op_byte, char* opcode_str, char* arg_str, char* d_register) { + /* There are inconsistencies with the S1 & S2 operand ordering in the docs, + but since it's a multiply it doesn't matter */ char D[32]; char S1[32]; char S2[32]; - char SIGN[32]; + char sign[32]; decode_QQQF_table(BITS(op_byte,0x07), BITS(op_byte,0x08), S1, S2, D); - decode_kSign_table(BITS(op_byte,0x40), SIGN); + decode_kSign_table(BITS(op_byte,0x40), sign); sprintf(opcode_str, "mpy"); - sprintf(arg_str, "(%s)%s,%s,%s", SIGN, S2, S1, D); + if (sign[0] == '-') + sprintf(arg_str, "-%s,%s,%s", S1, S2, D); + else + sprintf(arg_str, "%s,%s,%s", S1, S2, D); sprintf(d_register, "%s", D); return 1; } @@ -1546,14 +1560,19 @@ static size_t dsp56k_dasm_mpy(const UINT16 op_byte, char* opcode_str, char* arg_ /* MPYR : .... .... 1k01 FQQQ : A-162 */ static size_t dsp56k_dasm_mpyr(const UINT16 op_byte, char* opcode_str, char* arg_str, char* d_register) { + /* There are inconsistencies with the S1 & S2 operand ordering in the docs, + but since it's a multiply it doesn't matter */ char D[32]; char S1[32]; char S2[32]; - char SIGN[32]; + char sign[32]; decode_QQQF_table(BITS(op_byte,0x07), BITS(op_byte,0x08), S1, S2, D); - decode_kSign_table(BITS(op_byte,0x40), SIGN); + decode_kSign_table(BITS(op_byte,0x40), sign); sprintf(opcode_str, "mpyr"); - sprintf(arg_str, "(%s)%s,%s,%s", SIGN, S2, S1, D); + if (sign[0] == '-') + sprintf(arg_str, "-%s,%s,%s", S1, S2, D); + else + sprintf(arg_str, "%s,%s,%s", S1, S2, D); sprintf(d_register, "%s", D); return 1; } @@ -1564,11 +1583,14 @@ static size_t dsp56k_dasm_mac(const UINT16 op_byte, char* opcode_str, char* arg_ char D[32]; char S1[32]; char S2[32]; - char SIGN[32]; + char sign[32]; decode_QQQF_table(BITS(op_byte,0x07), BITS(op_byte,0x08), S1, S2, D); - decode_kSign_table(BITS(op_byte,0x40), SIGN); + decode_kSign_table(BITS(op_byte,0x40), sign); sprintf(opcode_str, "mac"); - sprintf(arg_str, "(%s)%s,%s,%s", SIGN, S2, S1, D); + if (sign[0] == '-') + sprintf(arg_str, "-%s,%s,%s", S1, S2, D); + else + sprintf(arg_str, "%s,%s,%s", S1, S2, D); sprintf(d_register, "%s", D); return 1; } @@ -1576,15 +1598,19 @@ static size_t dsp56k_dasm_mac(const UINT16 op_byte, char* opcode_str, char* arg_ /* MACR : .... .... 1k11 FQQQ : A-124 -- DRAMA - rr vs xx (805) */ static size_t dsp56k_dasm_macr(const UINT16 op_byte, char* opcode_str, char* arg_str, char* d_register) { + /* There are inconsistencies with the S1 & S2 operand ordering in the docs, + but since it's a multiply it doesn't matter */ char D[32]; char S1[32]; char S2[32]; - char SIGN[32]; + char sign[32]; decode_QQQF_table(BITS(op_byte,0x07), BITS(op_byte,0x08), S1, S2, D); - decode_kSign_table(BITS(op_byte,0x40), SIGN); + decode_kSign_table(BITS(op_byte,0x40), sign); sprintf(opcode_str, "macr"); - /* TODO: It's a little odd that macr is S1,S2 while everyone else (mac, mpy, mpyr) is S2,S1. Check! */ - sprintf(arg_str, "(%s)%s,%s,%s", SIGN, S1, S2, D); + if (sign[0] == '-') + sprintf(arg_str, "-%s,%s,%s", S1, S2, D); + else + sprintf(arg_str, "%s,%s,%s", S1, S2, D); sprintf(d_register, "%s", D); return 1; } @@ -1611,7 +1637,7 @@ static size_t dsp56k_dasm_andi(const UINT16 op, char* opcode_str, char* arg_str) char D[32]; decode_EE_table(BITS(op,0x0600), D); sprintf(opcode_str, "and(i)"); - sprintf(arg_str, "#%02x,%s", BITS(op,0x00ff), D); + sprintf(arg_str, "#$%02x,%s", BITS(op,0x00ff), D); return 1; } @@ -1693,7 +1719,15 @@ static size_t dsp56k_dasm_bfop(const UINT16 op, const UINT16 op2, char* opcode_s decode_DDDDD_table(BITS(op,0x001f), D); break; } - sprintf(arg_str, "#%04x,%s", iVal, D); + + if (upperMiddleLower != BBB_INVALID) + { + sprintf(arg_str, "#$%04x,%s", iVal, D); + } + else + { + sprintf(arg_str, "[[invalid]],%s", D); + } switch(BITS(op2,0x1f00)) { @@ -1713,7 +1747,7 @@ static size_t dsp56k_dasm_bcc(const UINT16 op, const UINT16 op2, char* opcode_st char M[32]; decode_cccc_table(BITS(op,0x000f), M); sprintf(opcode_str, "b.%s", M); - sprintf(arg_str, "%d (0x%04x)", (INT16)op2, pc + 2 + (INT16)op2); + sprintf(arg_str, "$%04x (%d)", pc + 2 + (INT16)op2, (INT16)op2); return 2; } @@ -1725,7 +1759,7 @@ static size_t dsp56k_dasm_bcc_1(const UINT16 op, char* opcode_str, char* arg_str decode_cccc_table(BITS(op,0x3c0), M); relativeInt = get_6_bit_signed_value(BITS(op,0x003f)); sprintf(opcode_str, "b.%s", M); - sprintf(arg_str, "%d (0x%04x)", relativeInt, pc + 1 + relativeInt); + sprintf(arg_str, "$%04x (%d)", pc + 1 + relativeInt, relativeInt); return 1; } @@ -1745,15 +1779,16 @@ static size_t dsp56k_dasm_bcc_2(const UINT16 op, char* opcode_str, char* arg_str static size_t dsp56k_dasm_bra(const UINT16 op, const UINT16 op2, char* opcode_str, char* arg_str, const offs_t pc) { sprintf(opcode_str, "bra"); - sprintf(arg_str, "%d (0x%04x)", (INT16)op2, pc + 2 + op2); + sprintf(arg_str, "$%04x (%d)", pc + 2 + op2, (INT16)op2); return 2; } /* BRA : 0000 1011 aaaa aaaa : A-50 */ static size_t dsp56k_dasm_bra_1(const UINT16 op, char* opcode_str, char* arg_str, const offs_t pc) { + INT8 iVal = (INT8)BITS(op,0x00ff); sprintf(opcode_str, "bra"); - sprintf(arg_str, "%d (0x%02x)", (INT8)BITS(op,0x00ff), pc + 1 + (INT8)BITS(op,0x00ff)); + sprintf(arg_str, "$%04x (%d)", pc + 1 + iVal, iVal); return 1; } @@ -1783,8 +1818,8 @@ static size_t dsp56k_dasm_bscc(const UINT16 op, const UINT16 op2, char* opcode_s char M[32]; decode_cccc_table(BITS(op,0x000f), M); sprintf(opcode_str, "bs.%s", M); - sprintf(arg_str, "%d (0x%04x)", (INT16)op2, pc + 2 + (INT16)op2); - return (2 | DASMFLAG_STEP_OVER); /* probably */ + sprintf(arg_str, "$%04x (%d)", pc + 2 + (INT16)op2, (INT16)op2); + return (2 | DASMFLAG_STEP_OVER); } /* BScc: 0000 0111 RR00 cccc : A-54 */ @@ -1796,14 +1831,14 @@ static size_t dsp56k_dasm_bscc_1(const UINT16 op, char* opcode_str, char* arg_st Rnum = decode_RR_table(BITS(op,0x00c0)); sprintf(opcode_str, "bs.%s", M); sprintf(arg_str, "R%d", Rnum); - return (1 | DASMFLAG_STEP_OVER); /* probably. What's the diff between a branch and a jump? */ + return (1 | DASMFLAG_STEP_OVER); } /* BSR : 0000 0001 0011 10-- xxxx xxxx xxxx xxxx : A-56 */ 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, "%d (0x%04x)", (INT16)op2, pc + 2 + (INT16)op2); + sprintf(arg_str, "$%04x (%d)", pc + 2 + (INT16)op2, (INT16)op2); return (2 | DASMFLAG_STEP_OVER); } @@ -1844,9 +1879,10 @@ static size_t dsp56k_dasm_debugcc(const UINT16 op, char* opcode_str, char* arg_s } /* DIV : 0001 0101 0--0 F1DD : A-76 */ -/* WARNING : DOCS SAY THERE IS A PARALLEL MOVE HERE !!! */ static size_t dsp56k_dasm_div(const UINT16 op, char* opcode_str, char* arg_str) { + /* The docs on page A-76 claim there is potential for a parallel move here, + but various other sources (including elsewhere in the family manual) disagree */ char D[32]; char S1[32]; decode_DDF_table(BITS(op,0x0003), BITS(op,0x0008), S1, D); @@ -1870,38 +1906,38 @@ static size_t dsp56k_dasm_dmac(const UINT16 op, char* opcode_str, char* arg_str) } /* DO : 0000 0000 110- --RR xxxx xxxx xxxx xxxx : A-82 */ -static size_t dsp56k_dasm_do(const UINT16 op, const UINT16 op2, char* opcode_str, char* arg_str) +static size_t dsp56k_dasm_do(const UINT16 op, const UINT16 op2, char* opcode_str, char* arg_str, const offs_t pc) { int Rnum; Rnum = decode_RR_table(BITS(op,0x0003)); sprintf(opcode_str, "do"); - sprintf(arg_str, "X:(R%d),%02x", Rnum, op2); + sprintf(arg_str, "X:(R%d),$%02x", Rnum, pc + 2 + op2); return 2; } /* DO : 0000 1110 iiii iiii xxxx xxxx xxxx xxxx : A-82 */ -static size_t dsp56k_dasm_do_1(const UINT16 op, const UINT16 op2, char* opcode_str, char* arg_str) +static size_t dsp56k_dasm_do_1(const UINT16 op, const UINT16 op2, char* opcode_str, char* arg_str, const offs_t pc) { sprintf(opcode_str, "do"); - sprintf(arg_str, "#%02x,%04x", BITS(op,0x00ff), op2); + sprintf(arg_str, "#$%02x,$%04x", BITS(op,0x00ff), pc + 2 + op2); return 2; } /* DO : 0000 0100 000D DDDD xxxx xxxx xxxx xxxx : A-82 */ -static size_t dsp56k_dasm_do_2(const UINT16 op, const UINT16 op2, char* opcode_str, char* arg_str) +static size_t dsp56k_dasm_do_2(const UINT16 op, const UINT16 op2, char* opcode_str, char* arg_str, const offs_t pc) { char S1[32]; decode_DDDDD_table(BITS(op,0x001f), S1); sprintf(opcode_str, "do"); - sprintf(arg_str, "%s,%04x", S1, op2); + sprintf(arg_str, "%s,$%04x", S1, pc + 2 + op2); return 2; } /* DO FOREVER : 0000 0000 0000 0010 xxxx xxxx xxxx xxxx : A-88 */ -static size_t dsp56k_dasm_doforever(const UINT16 op, const UINT16 op2, char* opcode_str, char* arg_str) +static size_t dsp56k_dasm_doforever(const UINT16 op, const UINT16 op2, char* opcode_str, char* arg_str, const offs_t pc) { - sprintf(opcode_str, "doForever"); - sprintf(arg_str, "%04x", op2); + sprintf(opcode_str, "do forever"); + sprintf(arg_str, "$%04x", pc + 2 + op2); return 2; } @@ -1961,7 +1997,7 @@ static size_t dsp56k_dasm_jcc(const UINT16 op, const UINT16 op2, char* opcode_st char M[32]; decode_cccc_table(BITS(op,0x000f), M); sprintf(opcode_str, "j.%s", M); - sprintf(arg_str, "%04x", op2); + sprintf(arg_str, "$%04x", op2); return 2; } @@ -1981,7 +2017,7 @@ static size_t dsp56k_dasm_jcc_1(const UINT16 op, char* opcode_str, char* arg_str static size_t dsp56k_dasm_jmp(const UINT16 op, const UINT16 op2, char* opcode_str, char* arg_str) { sprintf(opcode_str, "jmp"); - sprintf(arg_str, "%04x", op2); + sprintf(arg_str, "$%04x", op2); return 2; } @@ -2001,8 +2037,8 @@ static size_t dsp56k_dasm_jscc(const UINT16 op, const UINT16 op2, char* opcode_s char M[32]; decode_cccc_table(BITS(op,0x000f), M); sprintf(opcode_str, "js.%s", M); - sprintf(arg_str, "%04x", op2); - return (2 |DASMFLAG_STEP_OVER); /* probably */ + sprintf(arg_str, "$%04x", op2); + return (2 | DASMFLAG_STEP_OVER); } /* JScc : 0000 0110 RR00 cccc : A-112 */ @@ -2014,14 +2050,14 @@ static size_t dsp56k_dasm_jscc_1(const UINT16 op, char* opcode_str, char* arg_st Rnum = decode_RR_table(BITS(op,0x00c0)); sprintf(opcode_str, "js.%s", M); sprintf(arg_str, "R%d", Rnum); - return (1 | DASMFLAG_STEP_OVER); /* probably. What's the diff between a branch and a jump? */ + return (1 | DASMFLAG_STEP_OVER); } /* JSR : 0000 0001 0011 00-- xxxx xxxx xxxx xxxx : A-114 */ static size_t dsp56k_dasm_jsr(const UINT16 op, const UINT16 op2, char* opcode_str, char* arg_str) { sprintf(opcode_str, "jsr"); - sprintf(arg_str, "%04x", op2); + sprintf(arg_str, "$%04x", op2); return (2 | DASMFLAG_STEP_OVER); } @@ -2029,7 +2065,7 @@ static size_t dsp56k_dasm_jsr(const UINT16 op, const UINT16 op2, char* opcode_st static size_t dsp56k_dasm_jsr_1(const UINT16 op, char* opcode_str, char* arg_str) { sprintf(opcode_str, "jsr"); - sprintf(arg_str, "%d (0x%02x)", BITS(op,0x00ff), BITS(op,0x00ff)); + sprintf(arg_str, "#$%02x", BITS(op,0x00ff)); return (1 | DASMFLAG_STEP_OVER); } @@ -2194,7 +2230,7 @@ static size_t dsp56k_dasm_movei(const UINT16 op, char* opcode_str, char* arg_str char D1[32]; decode_DD_table(BITS(op,0x0300), D1); sprintf(opcode_str, "move(i)"); - sprintf(arg_str, "#%02x,%s", BITS(op,0x00ff), D1); + sprintf(arg_str, "#$%02x,%s", BITS(op,0x00ff), D1); return 1; } @@ -2224,7 +2260,7 @@ static size_t dsp56k_dasm_movem_1(const UINT16 op, char* opcode_str, char* arg_s assemble_eas_from_m_table(BITS(op,0x000c), BITS(op,0x00c0), BITS(op,0x0003), ea, ea2); sprintf(SD, "P:%s", ea); assemble_arguments_from_W_table(BITS(op,0x0100), args, 'X', SD, ea2); - sprintf(opcode_str, "move(m)"); + sprintf(opcode_str, "move(m)*"); /* This asterisk is to denote that this opcode may have an error with its disassembly */ sprintf(arg_str, "%s", args); return 1; } @@ -2240,7 +2276,6 @@ static size_t dsp56k_dasm_movem_2(const UINT16 op, const UINT16 op2, char* opcod assemble_reg_from_W_table(BITS(op2,0x0100), args, 'P', SD, B); sprintf(opcode_str, "move(m)"); sprintf(arg_str, "%s", args); - /* !!! The docs list the read/write order backwards for all move(m)'s - crackbabies ??? */ return 2; } @@ -2250,10 +2285,10 @@ static size_t dsp56k_dasm_movep(const UINT16 op, char* opcode_str, char* arg_str char A[32]; char SD[32]; char args[32]; - char fullAddy[128]; + char fullAddy[128]; /* Convert Short Absolute Address to full 16-bit */ decode_HH_table(BITS(op,0x00c0), SD); - assemble_address_from_IO_short_address(BITS(op,0x001f), fullAddy); /* Convert Short Absolute Address to full 16-bit */ - sprintf(A, "%02x (%s)", BITS(op,0x001f), fullAddy); + assemble_address_from_IO_short_address(BITS(op,0x001f), fullAddy); + sprintf(A, "$%s", fullAddy); assemble_arguments_from_W_table(BITS(op,0x0100), args, 'X', SD, A); sprintf(opcode_str, "move(p)"); sprintf(arg_str, "%s", args); @@ -2271,9 +2306,9 @@ static size_t dsp56k_dasm_movep_1(const UINT16 op, char* opcode_str, char* arg_s Rnum = decode_RR_table(BITS(op,0x00c0)); assemble_ea_from_m_table(BITS(op,0x0020), Rnum, ea); assemble_address_from_IO_short_address(BITS(op,0x001f), fullAddy); - sprintf(SD, "X:%02x (%s)", BITS(op,0x001f), fullAddy); + sprintf(SD, "X:$%s", fullAddy); assemble_arguments_from_W_table(BITS(op,0x0100), args, 'X', SD, ea); - sprintf(opcode_str, "move(p)"); + sprintf(opcode_str, "move(p)*"); /* This asterisk is to denote that this opcode may have an error with its disassembly */ sprintf(arg_str, "%s", args); return 1; } @@ -2285,7 +2320,7 @@ static size_t dsp56k_dasm_moves(const UINT16 op, char* opcode_str, char* arg_str char SD[32]; char args[32]; decode_HH_table(BITS(op,0x00c0), SD); - sprintf(A, "00%02x", BITS(op,0x001f)); + sprintf(A, "$%02x", BITS(op,0x001f)); assemble_arguments_from_W_table(BITS(op,0x0100), args, 'X', SD, A); sprintf(opcode_str, "move(s)"); sprintf(arg_str, "%s", args); @@ -2342,7 +2377,7 @@ static size_t dsp56k_dasm_ori(const UINT16 op, char* opcode_str, char* arg_str) char D[32]; decode_EE_table(BITS(op,0x0600), D); sprintf(opcode_str, "or(i)"); - sprintf(arg_str, "#%02x,%s", BITS(op,0x00ff), D); + sprintf(arg_str, "#$%02x,%s", BITS(op,0x00ff), D); return 1; } @@ -2360,7 +2395,7 @@ static size_t dsp56k_dasm_rep(const UINT16 op, char* opcode_str, char* arg_str) static size_t dsp56k_dasm_rep_1(const UINT16 op, char* opcode_str, char* arg_str) { sprintf(opcode_str, "rep"); - sprintf(arg_str, "%d (0x%02x)", BITS(op,0x00ff), BITS(op,0x00ff)); + sprintf(arg_str, "#$%02x (%d)", BITS(op,0x00ff), BITS(op,0x00ff)); return 1; } @@ -2449,12 +2484,11 @@ static size_t dsp56k_dasm_tcc(const UINT16 op, char* opcode_str, char* arg_str) decode_h0hF_table(BITS(op,0x0007),BITS(op,0x0008), S, D); sprintf(arg_str, "%s,%s R0,R%d", S, D, Rnum); - /* TODO: Investigate - if (S1[0] == D[0] && D[0] == 'A') - sprintf(buffer, "t.%s %s,%s", M, S1, D); - else - sprintf(buffer, "t.%s %s,%s R0,R%d", M, S1, D, Rnum); - */ + /* Note: S == 'A' && D == 'A' is used by the assembler when "no Data ALU + transfer is specified in the instruction." The Data ALU contains the + X,Y,A,B registers. The AGU holds the R registers. This comment means + the assembler will create Tcc A,A when it wants to conditionally transfer + only a R register to another R register. */ return 1; } @@ -2478,7 +2512,7 @@ static size_t dsp56k_dasm_tfr3(const UINT16 op, char* opcode_str, char* arg_str) char S1[32]; char SD[32]; char args[32]; - decode_DDF_table(BITS(op,0x0030), BITS(op,0x0008), D1, S1); /* Intentionally switched */ + decode_DDF_table(BITS(op,0x0030), BITS(op,0x0008), D1, S1); /* Intentionally switched */ decode_HHH_table(BITS(op,0x0007), SD); Rnum = decode_RR_table(BITS(op,0x00c0)); assemble_ea_from_m_table(BITS(op,0x0200), Rnum, ea); @@ -2558,7 +2592,7 @@ static void decode_x_memory_data_move2(const UINT16 op, char* parallel_move_str, } /* Dual X Memory Data Read : 011m mKKK -rr- ---- : A-142*/ -static void decode_dual_x_memory_data_read(const UINT16 op, char* parallel_move_str, char* parallel_move_str2) +static void decode_dual_x_memory_data_read(const UINT16 op, char* parallel_move_str, char* parallel_move_str2, char* d_register) { int Rnum; char D1[32] = ""; @@ -2570,11 +2604,22 @@ static void decode_dual_x_memory_data_read(const UINT16 op, char* parallel_move_ decode_KKK_table(BITS(op,0x0700), D1, D2); assemble_eas_from_m_table(BITS(op,0x1800), Rnum, 3, ea1, ea2); - /* TODO : The ^F's should likely be replaced */ + /* Not documented, but extrapolated from docs on page A-133 */ + if (D1[0] == '^' && D1[1] == 'F') + { + if (d_register[0] == 'B') + sprintf(D1, "A"); + else if (d_register[0] == 'A') + sprintf(D1, "B"); + else + sprintf(D1, "A"); /* In the case of no data ALU operation */ + } - if (Rnum == -1) + /* D1 and D2 may not specify the same register : A-142 */ + if (Rnum == 3) { - sprintf(ea1, "(!!)!"); + /* Replace the R3 with !! */ + ea1[1] = ea1[2] = '!'; } sprintf(parallel_move_str, "X:%s,%s", ea1, D1); @@ -2625,14 +2670,10 @@ static void decode_x_memory_data_write_and_register_data_move(const UINT16 op, c char S[32]; char Dnot[32]; - /* TODO : Cross-check the Dnot stuff against the MPY & MAC things. */ - /* It's likely correct as-is, since the ALU op and this guy probably decode the same bit, */ - /* but i may have to pass in d_register just to be sure? */ decode_k_table(BITS(op,0x0100), Dnot); Rnum = decode_RR_table(BITS(op,0x00c0)); decode_DD_table(BITS(op,0x0030), S); - /* TODO : is Nn correct here? */ sprintf(parallel_move_str, "%s,X:(R%d)+N%d", Dnot, Rnum, Rnum); sprintf(parallel_move_str2, "%s,%s", S, Dnot); } @@ -2664,7 +2705,7 @@ static int decode_BBB_table(UINT16 BBB) case 0x1: return BBB_LOWER; } - return BBB_LOWER; /* Not really safe... */ + return BBB_INVALID; } static void decode_cccc_table(UINT16 cccc, char *mnemonic) @@ -2918,7 +2959,6 @@ 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; @@ -3008,10 +3048,7 @@ static int decode_RR_table(UINT16 RR) static int decode_rr_table(UINT16 rr) { - if (rr != 0x3) - return rr; - else - return -1; + return rr; } static void decode_s_table(UINT16 s, char *arithmetic) @@ -3038,9 +3075,8 @@ 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(S, "add"); sprintf(arg, "invalid"); switch(switchVal) @@ -3092,13 +3128,13 @@ static void assemble_eas_from_m_table(UINT16 mm, int n1, int n2, char *ea1, char switch(mm) { case 0x0: sprintf(ea1, "(R%d)+", n1) ; - sprintf(ea2, "(R%d)+", n2) ; break; + sprintf(ea2, "(R%d)+", n2) ; break; case 0x1: sprintf(ea1, "(R%d)+", n1) ; - sprintf(ea2, "(R%d)+N%d", n2, n2); break; + sprintf(ea2, "(R%d)+N%d", n2, n2); break; case 0x2: sprintf(ea1, "(R%d)+N%d", n1, n1); - sprintf(ea2, "(R%d)+", n2) ; break; + sprintf(ea2, "(R%d)+", n2) ; break; case 0x3: sprintf(ea1, "(R%d)+N%d", n1, n1); - sprintf(ea2, "(R%d)+N%d", n2, n2); break; + sprintf(ea2, "(R%d)+N%d", n2, n2); break; } } @@ -3126,9 +3162,8 @@ static void assemble_ea_from_t_table(UINT16 t, UINT16 val, char *ea) { switch(t) { - /* !!! Looking at page 336 of UM, I'm not sure if 0 is X: or if 0 is just # !!! */ - case 0x0: sprintf(ea, "X:%04x", val); break; - case 0x1: sprintf(ea, "#%04x", val); break; + case 0x0: sprintf(ea, "X:$%04x", val); break; + case 0x1: sprintf(ea, "#$%04x", val); break; } } @@ -3147,10 +3182,10 @@ static void assemble_D_from_P_table(UINT16 P, UINT16 ppppp, char *D) switch(P) { - case 0x0: sprintf(D, "X:%02x", ppppp); break; + case 0x0: sprintf(D, "X:$%02x", ppppp); break; case 0x1: assemble_address_from_IO_short_address(ppppp, fullAddy); - sprintf(D, "X:%02x (%s)", ppppp, fullAddy); + sprintf(D, "X:$%s", fullAddy); break; } } @@ -3166,11 +3201,20 @@ 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, INT8 xx) { - /* TODO : xx is said to be signed on page A-139. Nowhere else. Are they all signed? */ + UINT8 abs_xx; + char operation[32]; + + if(xx < 0) + sprintf(operation,"-"); + else + sprintf(operation,"+"); + + abs_xx = abs(xx); + switch(W) { - case 0x0: sprintf(args, "%s,%c:(R2+%02x)", SD, ma, xx); break; - case 0x1: sprintf(args, "%c:(R2+%02x),%s", ma, xx, SD); break; + case 0x0: sprintf(args, "%s,%c:(R2%s$%02x)", SD, ma, operation, abs_xx); break; + case 0x1: sprintf(args, "%c:(R2%s$%02x),%s", ma, operation, abs_xx, SD); break; } } @@ -3224,4 +3268,3 @@ static void pad_string(const int dest_length, char* string) strcat(string, " "); } } - diff --git a/src/emu/cpu/dsp56k/dsp56ops.c b/src/emu/cpu/dsp56k/dsp56ops.c index f3064d5ddd9..d4d6e923400 100644 --- a/src/emu/cpu/dsp56k/dsp56ops.c +++ b/src/emu/cpu/dsp56k/dsp56ops.c @@ -260,7 +260,8 @@ static void execute_one(dsp56k_core* cpustate) /* ADD : 011m mKKK 0rru Fuuu : A-22 */ /* SUB : 011m mKKK 0rru Fuuu : A-202 */ - if ((op & 0xe080) == 0x6000) + /* Note: 0x0094 check allows command to drop through to MOVE and TFR */ + if (((op & 0xe080) == 0x6000) && ((op & 0x0094) != 0x0010)) { size = dsp56k_op_addsub_2(cpustate, op_byte, &d_register, &cycle_count); } @@ -274,9 +275,20 @@ static void execute_one(dsp56k_core* cpustate) { size = dsp56k_op_macr_1(cpustate, op_byte, &d_register, &cycle_count); } + /* TFR : 011m mKKK 0rr1 F0DD : A-212 */ + else if ((op & 0xe094) == 0x6010) + { + size = dsp56k_op_tfr_2(cpustate, op_byte, &d_register, &cycle_count); + } /* MOVE : 011m mKKK 0rr1 0000 : A-128 */ else if ((op & 0xe09f) == 0x6010) { + /* Note: The opcode encoding : 011x xxxx 0xx1 0000 (move + double memory read) + is .identical. to (tfr X0,A + two parallel reads). This sparks the notion + that these 'move' opcodes don't actually exist and are just there as + documentation. Real-world examples would need to be examined to come + to a satisfactory conclusion, but as it stands, tfr will override this + move operation. */ size = dsp56k_op_move_1(cpustate, op_byte, &d_register, &cycle_count); } /* MPY : 011m mKKK 1xx0 F0QQ : A-160 */ @@ -289,11 +301,6 @@ static void execute_one(dsp56k_core* cpustate) { size = dsp56k_op_mpyr_1(cpustate, op_byte, &d_register, &cycle_count); } - /* TFR : 011m mKKK 0rr1 F0DD : A-212 */ - else if ((op & 0xe094) == 0x6010) - { - size = dsp56k_op_tfr_2(cpustate, op_byte, &d_register, &cycle_count); - } /* Now evaluate the parallel data move */ execute_dual_x_memory_data_read(cpustate, op, &d_register); @@ -788,7 +795,6 @@ static void execute_one(dsp56k_core* cpustate) size = dsp56k_op_debugcc(cpustate, op, &cycle_count); } /* DIV : 0001 0101 0--0 F1DD : A-76 */ - /* WARNING : DOCS SAY THERE IS A PARALLEL MOVE HERE !!! */ else if ((op & 0xff94) == 0x1504) { size = dsp56k_op_div(cpustate, op, &cycle_count); |