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...
This commit is contained in:
Andrew Gardner 2009-09-18 04:37:47 +00:00
parent e0320b80e3
commit 77a3badd32
2 changed files with 271 additions and 222 deletions

View File

@ -7,8 +7,9 @@
***************************************************************************/
/*
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);
}
/* MOVE : 011m mKKK 0rr1 0000 : A-128 */
else if ((op & 0xe09f) == 0x6010)
{
size = dsp56k_dasm_move_1(op_byte, opcode_str, arg_str);
}
/* MPY : 011m mKKK 1xx0 F0QQ : A-160 */
else if ((op & 0xe094) == 0x6080)
{
size = dsp56k_dasm_mpy_1(op_byte, opcode_str, arg_str);
}
/* MPYR : 011m mKKK 1--1 F0QQ : A-162 */
else if ((op & 0xe094) == 0x6090)
{
size = dsp56k_dasm_mpyr_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);
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)
{
/* 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, 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, 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) */
@ -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");
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)
{
/* TODO: This MOVE opcode is .identical. to the TFR one. 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);
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)
{
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");
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)
{
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(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)
static size_t dsp56k_dasm_tfr_2(const UINT16 op_byte, char* opcode_str, char* arg_str, char* d_register)
{
/* TODO - Same as move above. Investigate */
/* 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, char* d_register)
{
/* 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, char* d_register)
{
char D[32];
char S1[32];
char S2[32];
decode_QQF_table(BITS(op_byte,0x03), BITS(op_byte,0x08), 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, char* d_register)
{
char D[32];
char S1[32];
char S2[32];
decode_QQF_table(BITS(op_byte,0x03), BITS(op_byte,0x08), S1, S2, D);
sprintf(opcode_str, "mpyr");
sprintf(arg_str, "%s,%s,%s", S1, S2, D);
sprintf(d_register, "%s", 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;
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, "mpy");
sprintf(arg_str, "%s,%s,%s", S1, S2, D);
return 1;
}
/* 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;
}
@ -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 */
if (Rnum == -1)
/* Not documented, but extrapolated from docs on page A-133 */
if (D1[0] == '^' && D1[1] == 'F')
{
sprintf(ea1, "(!!)!");
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 */
}
/* D1 and D2 may not specify the same register : A-142 */
if (Rnum == 3)
{
/* 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;
}
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)
@ -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, " ");
}
}

View File

@ -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);