mirror of
https://github.com/holub/mame
synced 2025-05-20 20:58:51 +03:00

Removed opbase globals to the address_space structure. Cleaned up names of pointers (decrypted and raw versus rom and ram). Added inline functions to read/write data via any address space. Added macros for existing functions to point them to the new functions. Other related cleanups.
694 lines
19 KiB
C
694 lines
19 KiB
C
/***************************************************************************
|
|
|
|
dsp32dis.c
|
|
Disassembler for the portable AT&T/Lucent DSP32C emulator.
|
|
Written by Aaron Giles
|
|
|
|
***************************************************************************/
|
|
|
|
#include "dsp32.h"
|
|
|
|
|
|
/***************************************************************************
|
|
MEMORY ACCESSORS
|
|
***************************************************************************/
|
|
|
|
#define ROPCODE(pc) program_decrypted_read_dword(pc)
|
|
|
|
#define ABS(x) (((x) >= 0) ? (x) : -(x))
|
|
|
|
|
|
/***************************************************************************
|
|
CODE CODE
|
|
***************************************************************************/
|
|
|
|
static const char *const sizesuffix[] = { "", "e" };
|
|
static const char *const unarysign[] = { "", "-" };
|
|
static const char *const sign[] = { "+", "-" };
|
|
static const char *const aMvals[] = { "a0", "a1", "a2", "a3", "0.0", "1.0", "Format 4", "Reserved" };
|
|
static const char *const memsuffix[] = { "h", "l", "", "e" };
|
|
static const char *const functable[] =
|
|
{
|
|
"ic", "oc", "float", "int", "round", "ifalt", "ifaeq", "ifagt",
|
|
"reserved8", "reserved9", "float24", "int24", "ieee", "dsp", "seed", "reservedf"
|
|
};
|
|
static const char *const condtable[] =
|
|
{
|
|
"false", "true",
|
|
"pl", "mi",
|
|
"ne", "eq",
|
|
"vc", "vs",
|
|
"cc", "cs",
|
|
"ge", "lt",
|
|
"gt", "le",
|
|
"hi", "ls",
|
|
"auc", "aus",
|
|
"age", "alt",
|
|
"ane", "aeq",
|
|
"avc", "avs",
|
|
"agt", "ale",
|
|
"!resd", "resd",
|
|
"!rese", "rese",
|
|
"!resf", "resf",
|
|
"ibe", "ibf",
|
|
"obf", "obe",
|
|
"pde", "pdf",
|
|
"pie", "pif",
|
|
"syc", "sys",
|
|
"fbc", "fbs",
|
|
"ireq1_lo", "ireq1_hi",
|
|
"ireq2_lo", "ireq2_hi",
|
|
"!?18", "?18",
|
|
"!?19", "?19",
|
|
"!?1a", "?1a",
|
|
"!?1b", "?1b",
|
|
"!?1c", "?1c",
|
|
"!?1d", "?1d",
|
|
"!?1e", "?1e",
|
|
"!?1f", "?1f"
|
|
};
|
|
static const char *const regname[] =
|
|
{
|
|
"0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
|
|
"r8", "r9", "r10", "r11", "r12", "r13", "r14", "pc",
|
|
"0", "r15", "r16", "r17", "r18", "r19", "-1", "1",
|
|
"r20", "r21", "dauc", "ioc", "res1c", "r22", "pcsh", "res1f"
|
|
};
|
|
static const char *const regnamee[] =
|
|
{
|
|
"0", "r1e", "r2e", "r3e", "r4e", "r5e", "r6e", "r7e",
|
|
"r8e", "r9e", "r10e", "r11e", "r12e", "r13e", "r14e", "pce",
|
|
"0", "r15e", "r16e", "r17e", "r18e", "r19e", "--", "++",
|
|
"r20e", "r21e", "dauce", "ioce", "res1ce", "r22e", "pcshe", "res1fe"
|
|
};
|
|
|
|
static char tempbuf[10][40];
|
|
|
|
INLINE char *signed_16bit_unary(INT16 val)
|
|
{
|
|
static char temp[10];
|
|
if (val < 0)
|
|
sprintf(temp, "-$%x", -val);
|
|
else
|
|
sprintf(temp, "$%x", val);
|
|
return temp;
|
|
}
|
|
|
|
INLINE char *signed_16bit_sep(INT16 val)
|
|
{
|
|
static char temp[10];
|
|
if (val < 0)
|
|
sprintf(temp, " - $%x", -val);
|
|
else
|
|
sprintf(temp, " + $%x", val);
|
|
return temp;
|
|
}
|
|
|
|
INLINE char *signed_16bit_sep_nospace(INT16 val)
|
|
{
|
|
static char temp[10];
|
|
if (val < 0)
|
|
sprintf(temp, "-$%x", -val);
|
|
else
|
|
sprintf(temp, "+$%x", val);
|
|
return temp;
|
|
}
|
|
|
|
INLINE char *unsigned_16bit_size(INT16 val, UINT8 size)
|
|
{
|
|
static char temp[10];
|
|
if (size)
|
|
sprintf(temp, "$%06x", (INT32)val & 0xffffff);
|
|
else
|
|
sprintf(temp, "$%04x", val & 0xffff);
|
|
return temp;
|
|
}
|
|
|
|
static UINT8 lastp;
|
|
static const char *dasm_XYZ(UINT8 bits, char *buffer)
|
|
{
|
|
UINT8 p = bits >> 3;
|
|
UINT8 i = bits & 7;
|
|
|
|
if (p)
|
|
{
|
|
if (p == 15) p = lastp; /* P=15 means Z inherits from Y, Y inherits from X */
|
|
lastp = p;
|
|
switch (i)
|
|
{
|
|
case 0: sprintf(buffer, "*r%d", p); break;
|
|
case 1:
|
|
case 2:
|
|
case 3:
|
|
case 4:
|
|
case 5: sprintf(buffer, "*r%d++r%d", p, i + 14); break;
|
|
case 6: sprintf(buffer, "*r%d--", p); break;
|
|
case 7: sprintf(buffer, "*r%d++", p); break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
switch (i)
|
|
{
|
|
case 0:
|
|
case 1:
|
|
case 2:
|
|
case 3: sprintf(buffer, "a%d", i); break;
|
|
case 4: sprintf(buffer, "ibuf"); break;
|
|
case 5: sprintf(buffer, "obuf"); break;
|
|
case 6: sprintf(buffer, "pdr"); break;
|
|
case 7: buffer[0] = 0; break;
|
|
}
|
|
}
|
|
return buffer;
|
|
}
|
|
|
|
|
|
static const char *dasm_PI(UINT16 bits, char *buffer)
|
|
{
|
|
UINT8 p = bits >> 5;
|
|
UINT8 i = bits & 0x1f;
|
|
|
|
if (p)
|
|
{
|
|
switch (i)
|
|
{
|
|
case 0:
|
|
case 16: sprintf(buffer, "*%s", regname[p]); break;
|
|
case 22: sprintf(buffer, "*%s--", regname[p]); break;
|
|
case 23: sprintf(buffer, "*%s++", regname[p]); break;
|
|
default: sprintf(buffer, "*%s++%s", regname[p], regname[i]); break;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
switch (i)
|
|
{
|
|
case 4: sprintf(buffer, "ibuf"); break;
|
|
case 5: sprintf(buffer, "obuf"); break;
|
|
case 6: sprintf(buffer, "pdr"); break;
|
|
case 14: sprintf(buffer, "piop"); break;
|
|
case 20: sprintf(buffer, "pdr2"); break;
|
|
case 22: sprintf(buffer, "pir"); break;
|
|
case 30: sprintf(buffer, "pcw"); break;
|
|
default: sprintf(buffer, "????"); break;
|
|
}
|
|
}
|
|
return buffer;
|
|
}
|
|
|
|
|
|
unsigned dasm_dsp32(char *buffer, unsigned pc, UINT32 op)
|
|
{
|
|
UINT32 flags = 0;
|
|
|
|
switch (op >> 25)
|
|
{
|
|
/* DA format 1 */
|
|
case 0x10: case 0x11: case 0x12: case 0x13:
|
|
case 0x14: case 0x15: case 0x16: case 0x17:
|
|
case 0x18: case 0x19: case 0x1a: case 0x1b:
|
|
{
|
|
const char *X = dasm_XYZ((op >> 14) & 0x7f, tempbuf[0]);
|
|
const char *Y = dasm_XYZ((op >> 7) & 0x7f, tempbuf[1]);
|
|
const char *Z = dasm_XYZ((op >> 0) & 0x7f, tempbuf[2]);
|
|
const char *aM = aMvals[(op >> 26) & 7];
|
|
UINT8 aN = (op >> 21) & 3;
|
|
if ((op & 0x7f) == 7)
|
|
{
|
|
if (aM[0] == '0')
|
|
sprintf(buffer, "a%d = %s%s", aN, unarysign[(op >> 24) & 1], Y);
|
|
else if (aM[0] == '1')
|
|
sprintf(buffer, "a%d = %s%s %s %s", aN, unarysign[(op >> 24) & 1], Y, sign[(op >> 23) & 1], X);
|
|
else
|
|
sprintf(buffer, "a%d = %s%s %s %s * %s", aN, unarysign[(op >> 24) & 1], Y, sign[(op >> 23) & 1], aM, X);
|
|
}
|
|
else
|
|
{
|
|
if (aM[0] == '0')
|
|
sprintf(buffer, "%s = a%d = %s%s", Z, aN, unarysign[(op >> 24) & 1], Y);
|
|
else if (aM[0] == '1')
|
|
sprintf(buffer, "%s = a%d = %s%s %s %s", Z, aN, unarysign[(op >> 24) & 1], Y, sign[(op >> 23) & 1], X);
|
|
else
|
|
sprintf(buffer, "%s = a%d = %s%s %s %s * %s", Z, aN, unarysign[(op >> 24) & 1], Y, sign[(op >> 23) & 1], aM, X);
|
|
}
|
|
break;
|
|
}
|
|
|
|
/* DA format 2 */
|
|
case 0x20: case 0x21: case 0x22: case 0x23:
|
|
case 0x24: case 0x25: case 0x26: case 0x27:
|
|
case 0x28: case 0x29: case 0x2a: case 0x2b:
|
|
{
|
|
const char *X = dasm_XYZ((op >> 14) & 0x7f, tempbuf[0]);
|
|
const char *Y = dasm_XYZ((op >> 7) & 0x7f, tempbuf[1]);
|
|
const char *Z = dasm_XYZ((op >> 0) & 0x7f, tempbuf[2]);
|
|
const char *aM = aMvals[(op >> 26) & 7];
|
|
UINT8 aN = (op >> 21) & 3;
|
|
|
|
if ((op & 0x7f) == 7)
|
|
{
|
|
if (aM[0] == '0')
|
|
sprintf(buffer, "a%d = %s%s * %s", aN, unarysign[(op >> 23) & 1], Y, X);
|
|
else
|
|
sprintf(buffer, "a%d = %s%s %s %s * %s", aN, unarysign[(op >> 24) & 1], aM, sign[(op >> 23) & 1], Y, X);
|
|
}
|
|
else
|
|
{
|
|
if (aM[0] == '0')
|
|
sprintf(buffer, "a%d = %s(%s=%s) * %s", aN, unarysign[(op >> 23) & 1], Z, Y, X);
|
|
else
|
|
sprintf(buffer, "a%d = %s%s %s (%s=%s) * %s", aN, unarysign[(op >> 24) & 1], aM, sign[(op >> 23) & 1], Z, Y, X);
|
|
}
|
|
break;
|
|
}
|
|
|
|
/* DA format 3 */
|
|
case 0x30: case 0x31: case 0x32: case 0x33:
|
|
case 0x34: case 0x35: case 0x36: case 0x37:
|
|
case 0x38: case 0x39: case 0x3a: case 0x3b:
|
|
{
|
|
const char *X = dasm_XYZ((op >> 14) & 0x7f, tempbuf[0]);
|
|
const char *Y = dasm_XYZ((op >> 7) & 0x7f, tempbuf[1]);
|
|
const char *Z = dasm_XYZ((op >> 0) & 0x7f, tempbuf[2]);
|
|
const char *aM = aMvals[(op >> 26) & 7];
|
|
UINT8 aN = (op >> 21) & 3;
|
|
|
|
if ((op & 0x7f) == 7)
|
|
{
|
|
if (aM[0] == '0')
|
|
sprintf(buffer, "a%d = %s%s * %s", aN, unarysign[(op >> 23) & 1], Y, X);
|
|
else
|
|
sprintf(buffer, "a%d = %s%s %s %s * %s", aN, unarysign[(op >> 24) & 1], aM, sign[(op >> 23) & 1], Y, X);
|
|
}
|
|
else
|
|
{
|
|
if (aM[0] == '0')
|
|
sprintf(buffer, "%s = a%d = %s%s * %s", Z, aN, unarysign[(op >> 23) & 1], Y, X);
|
|
else
|
|
sprintf(buffer, "%s = a%d = %s%s %s %s * %s", Z, aN, unarysign[(op >> 24) & 1], aM, sign[(op >> 23) & 1], Y, X);
|
|
}
|
|
break;
|
|
}
|
|
|
|
/* DA format 4 */
|
|
case 0x1c: case 0x1d:
|
|
{
|
|
const char *X = dasm_XYZ((op >> 14) & 0x7f, tempbuf[0]);
|
|
const char *Y = dasm_XYZ((op >> 7) & 0x7f, tempbuf[1]);
|
|
const char *Z = dasm_XYZ((op >> 0) & 0x7f, tempbuf[2]);
|
|
UINT8 aN = (op >> 21) & 3;
|
|
|
|
if ((op & 0x7f) == 7)
|
|
sprintf(buffer, "a%d = %s%s %s %s", aN, unarysign[(op >> 24) & 1], Y, sign[(op >> 23) & 1], X);
|
|
else
|
|
sprintf(buffer, "a%d = %s(%s=%s) %s %s", aN, unarysign[(op >> 24) & 1], Z, Y, sign[(op >> 23) & 1], X);
|
|
break;
|
|
}
|
|
|
|
/* DA format 5 */
|
|
case 0x3c: case 0x3d: case 0x3e: case 0x3f:
|
|
if ((op & 0x7f) == 7)
|
|
sprintf(buffer, "a%d = %s(%s)",
|
|
(op >> 21) & 3, // aN
|
|
functable[(op >> 23) & 15], // G
|
|
dasm_XYZ((op >> 7) & 0x7f, tempbuf[0])); // Y
|
|
else
|
|
sprintf(buffer, "%s = a%d = %s(%s)",
|
|
dasm_XYZ((op >> 0) & 0x7f, tempbuf[2]), // Z
|
|
(op >> 21) & 3, // aN
|
|
functable[(op >> 23) & 15], // G
|
|
dasm_XYZ((op >> 7) & 0x7f, tempbuf[0])); // Y
|
|
break;
|
|
|
|
/* CA formats 0/1 */
|
|
case 0x00: case 0x01: case 0x02: case 0x03:
|
|
{
|
|
const char *rH = regname[(op >> 16) & 0x1f];
|
|
UINT8 C = (op >> 21) & 0x3f;
|
|
INT16 N = (INT16)op;
|
|
|
|
if (op == 0)
|
|
sprintf(buffer, "nop");
|
|
else if (C == 1 && N == 0 && ((op >> 16) & 0x1f) == 0x1e)
|
|
sprintf(buffer, "ireturn");
|
|
else if (C == 1)
|
|
{
|
|
if (((op >> 16) & 0x1f) == 15)
|
|
sprintf(buffer, "goto %s%s [%x]", rH, signed_16bit_sep_nospace(N), (pc + 8 + N) & 0xffffff);
|
|
else if (N && rH[0] != '0')
|
|
sprintf(buffer, "goto %s%s", rH, signed_16bit_sep_nospace(N));
|
|
else if (N)
|
|
sprintf(buffer, "goto $%x", ((INT32)N & 0xffffff));
|
|
else
|
|
{
|
|
if (((op >> 16) & 0x1f) == 20)
|
|
flags = DASMFLAG_STEP_OUT;
|
|
sprintf(buffer, "goto %s", rH);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (((op >> 16) & 0x1f) == 15)
|
|
sprintf(buffer, "if (%s) goto %s%s [%x]", condtable[C], rH, signed_16bit_sep_nospace(N), (pc + 8 + N) & 0xffffff);
|
|
else if (N && rH[0] != '0')
|
|
sprintf(buffer, "if (%s) goto %s%s", condtable[C], rH, signed_16bit_sep_nospace(N));
|
|
else if (N)
|
|
sprintf(buffer, "if (%s) goto $%x", condtable[C], ((INT32)N & 0xffffff));
|
|
else
|
|
{
|
|
if (((op >> 16) & 0x1f) == 20)
|
|
flags = DASMFLAG_STEP_OUT;
|
|
sprintf(buffer, "if (%s) goto %s", condtable[C], rH);
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
|
|
/* CA format 3a */
|
|
case 0x06: case 0x07:
|
|
{
|
|
const char *rH = regname[(op >> 16) & 0x1f];
|
|
const char *rM = regname[(op >> 21) & 0x1f];
|
|
INT16 N = (INT16)op;
|
|
|
|
if (((op >> 16) & 0x1f) == 15)
|
|
{
|
|
sprintf(buffer, "if (%s-- >= 0) goto %s%s [%x]", rM, rH, signed_16bit_sep_nospace(N), (pc + 8 + N) & 0xffffff);
|
|
if (((pc + 8 + N) & 0xffffff) < pc)
|
|
flags = DASMFLAG_STEP_OVER;
|
|
}
|
|
else if (N && rH[0] != '0')
|
|
sprintf(buffer, "if (%s-- >= 0) goto %s%s", rM, rH, signed_16bit_sep_nospace(N));
|
|
else if (N)
|
|
{
|
|
sprintf(buffer, "if (%s-- >= 0) goto $%x", rM, ((INT32)N & 0xffffff));
|
|
if (((INT32)N & 0xffffff) < pc)
|
|
flags = DASMFLAG_STEP_OVER;
|
|
}
|
|
else
|
|
{
|
|
sprintf(buffer, "if (%s-- >= 0) goto %s", rM, rH);
|
|
if (((op >> 16) & 0x1f) == 20)
|
|
flags = DASMFLAG_STEP_OUT;
|
|
}
|
|
break;
|
|
}
|
|
|
|
/* CA format 3b/3c */
|
|
case 0x46:
|
|
if (((op >> 21) & 0x1f) == 0)
|
|
sprintf(buffer, "do %d,%d", (op >> 16) & 0x1f, op & 0x7ff);
|
|
else if (((op >> 21) & 0x1f) == 1)
|
|
sprintf(buffer, "do %d,%s", (op >> 16) & 0x1f, regname[op & 0x1f]);
|
|
break;
|
|
|
|
/* CA format 4 */
|
|
case 0x08: case 0x09:
|
|
{
|
|
const char *rH = regname[(op >> 16) & 0x1f];
|
|
const char *rM = regname[(op >> 21) & 0x1f];
|
|
INT16 N = (INT16)op;
|
|
|
|
if (((op >> 16) & 0x1f) == 15)
|
|
sprintf(buffer, "call %s%s (%s) [%x]", rH, signed_16bit_sep_nospace(N), rM, (pc + 8 + N) & 0xffffff);
|
|
else if (N && rH[0] != '0')
|
|
sprintf(buffer, "call %s%s (%s)", rH, signed_16bit_sep_nospace(N), rM);
|
|
else if (N)
|
|
sprintf(buffer, "call $%x (%s)", ((INT32)N & 0xffffff), rM);
|
|
else
|
|
sprintf(buffer, "call %s (%s)", rH, rM);
|
|
flags = DASMFLAG_STEP_OVER | DASMFLAG_STEP_OVER_EXTRA(1);
|
|
break;
|
|
}
|
|
|
|
/* CA format 5a/5b */
|
|
case 0x0a: case 0x0b:
|
|
case 0x4a: case 0x4b:
|
|
{
|
|
const char *rD = regname[(op >> 21) & 0x1f];
|
|
const char *rH = regname[(op >> 16) & 0x1f];
|
|
const char *s = sizesuffix[(op >> 31) & 1];
|
|
INT16 N = (INT16)op;
|
|
if (N == 0)
|
|
sprintf(buffer, "%s%s = %s%s", rD, s, rH, s);
|
|
else if (rH[0] == '0')
|
|
sprintf(buffer, "%s%s = %s", rD, s, signed_16bit_unary(N));
|
|
else
|
|
sprintf(buffer, "%s%s = %s%s%s", rD, s, rH, s, signed_16bit_sep((INT16)op));
|
|
break;
|
|
}
|
|
|
|
/* CA format 6a/6b */
|
|
case 0x0c: case 0x4c:
|
|
{
|
|
const char *rD = regname[(op >> 16) & 0x1f];
|
|
const char *rS1 = regname[(op >> 5) & 0x1f];
|
|
const char *rS2 = regname[(op >> 0) & 0x1f];
|
|
const char *s = sizesuffix[(op >> 31) & 1];
|
|
UINT8 threeop = (op >> 11) & 1;
|
|
char condbuf[40] = { 0 };
|
|
|
|
if ((op >> 10) & 1)
|
|
sprintf(condbuf, "if (%s) ", condtable[(op >> 12) & 15]);
|
|
|
|
switch ((op >> 21) & 15)
|
|
{
|
|
/* add */
|
|
case 0:
|
|
if (threeop)
|
|
{
|
|
if (rS1[0] == '0' && rS2[0] == '0')
|
|
sprintf(buffer, "%s%s%s = 0", condbuf, rD, s);
|
|
else if (rS1[0] == '0')
|
|
sprintf(buffer, "%s%s%s = %s%s", condbuf, rD, s, rS2, s);
|
|
else if (rS2[0] == '0')
|
|
sprintf(buffer, "%s%s%s = %s%s", condbuf, rD, s, rS1, s);
|
|
else
|
|
sprintf(buffer, "%s%s%s = %s%s + %s%s", condbuf, rD, s, rS2, s, rS1, s);
|
|
}
|
|
else
|
|
{
|
|
if (rS1[0] == '0')
|
|
sprintf(buffer, "%s%s%s = %s%s", condbuf, rD, s, rD, s);
|
|
else
|
|
sprintf(buffer, "%s%s%s = %s%s + %s%s", condbuf, rD, s, rD, s, rS1, s);
|
|
}
|
|
break;
|
|
|
|
case 1:
|
|
sprintf(buffer, "%s%s%s = %s%s * 2", condbuf, rD, s, rS1, s);
|
|
break;
|
|
|
|
case 2:
|
|
if (threeop)
|
|
sprintf(buffer, "%s%s%s = %s%s - %s%s", condbuf, rD, s, rS1, s, rS2, s);
|
|
else
|
|
sprintf(buffer, "%s%s%s = %s%s - %s%s", condbuf, rD, s, rS1, s, rD, s);
|
|
break;
|
|
|
|
case 3:
|
|
if (threeop)
|
|
sprintf(buffer, "%s%s%s = %s%s # %s%s", condbuf, rD, s, rS2, s, rS1, s);
|
|
else
|
|
sprintf(buffer, "%s%s%s = %s%s # %s%s", condbuf, rD, s, rD, s, rS1, s);
|
|
break;
|
|
|
|
case 4:
|
|
if (threeop)
|
|
sprintf(buffer, "%s%s%s = %s%s - %s%s", condbuf, rD, s, rS2, s, rS1, s);
|
|
else
|
|
sprintf(buffer, "%s%s%s = %s%s - %s%s", condbuf, rD, s, rD, s, rS1, s);
|
|
break;
|
|
|
|
case 5:
|
|
sprintf(buffer, "%s%s%s = -%s%s", condbuf, rD, s, rS1, s);
|
|
break;
|
|
|
|
case 6:
|
|
if (threeop)
|
|
sprintf(buffer, "%s%s%s = %s%s &~ %s%s", condbuf, rD, s, rS2, s, rS1, s);
|
|
else
|
|
sprintf(buffer, "%s%s%s = %s%s &~ %s%s", condbuf, rD, s, rD, s, rS1, s);
|
|
break;
|
|
|
|
case 7:
|
|
// if (threeop)
|
|
// sprintf(buffer, "%s%s%s - %s%s", condbuf, rS2, s, rS1, s);
|
|
// else
|
|
sprintf(buffer, "%s%s%s - %s%s", condbuf, rD, s, rS1, s);
|
|
break;
|
|
|
|
case 8:
|
|
if (threeop)
|
|
sprintf(buffer, "%s%s%s = %s%s ^ %s%s", condbuf, rD, s, rS2, s, rS1, s);
|
|
else
|
|
sprintf(buffer, "%s%s%s = %s%s ^ %s%s", condbuf, rD, s, rD, s, rS1, s);
|
|
break;
|
|
|
|
case 9:
|
|
sprintf(buffer, "%s%s%s = %s%s >>> 1", condbuf, rD, s, rS1, s);
|
|
break;
|
|
|
|
case 10:
|
|
if (threeop)
|
|
sprintf(buffer, "%s%s%s = %s%s | %s%s", condbuf, rD, s, rS2, s, rS1, s);
|
|
else
|
|
sprintf(buffer, "%s%s%s = %s%s | %s%s", condbuf, rD, s, rD, s, rS1, s);
|
|
break;
|
|
|
|
case 11:
|
|
sprintf(buffer, "%s%s%s = %s%s <<< 1", condbuf, rD, s, rS1, s);
|
|
break;
|
|
|
|
case 12:
|
|
sprintf(buffer, "%s%s%s = %s%s >> 1", condbuf, rD, s, rS1, s);
|
|
break;
|
|
|
|
case 13:
|
|
sprintf(buffer, "%s%s%s = %s%s / 2", condbuf, rD, s, rS1, s);
|
|
break;
|
|
|
|
case 14:
|
|
if (threeop)
|
|
sprintf(buffer, "%s%s%s = %s%s & %s%s", condbuf, rD, s, rS2, s, rS1, s);
|
|
else
|
|
sprintf(buffer, "%s%s%s = %s%s & %s%s", condbuf, rD, s, rD, s, rS1, s);
|
|
break;
|
|
|
|
case 15:
|
|
// if (threeop)
|
|
// sprintf(buffer, "%s%s%s & %s%s", condbuf, rS1, s, rS2, s);
|
|
// else
|
|
sprintf(buffer, "%s%s%s & %s%s", condbuf, rD, s, rS1, s);
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
|
|
/* CA format 6c/6d */
|
|
case 0x0d: case 0x4d:
|
|
{
|
|
const char *rD = regname[(op >> 16) & 0x1f];
|
|
const char *s = sizesuffix[(op >> 31) & 1];
|
|
INT16 N = (INT16)op;
|
|
|
|
switch ((op >> 21) & 15)
|
|
{
|
|
case 0:
|
|
case 1:
|
|
case 5:
|
|
case 9:
|
|
case 11:
|
|
case 12:
|
|
case 13:
|
|
sprintf(buffer, "Unexpected: %08X", op);
|
|
break;
|
|
|
|
case 2:
|
|
sprintf(buffer, "%s%s = %s - %s%s", rD, s, signed_16bit_unary(N), rD, s);
|
|
break;
|
|
|
|
case 3:
|
|
sprintf(buffer, "%s%s = %s%s # %s", rD, s, rD, s, signed_16bit_unary(N));
|
|
break;
|
|
|
|
case 4:
|
|
sprintf(buffer, "%s%s = %s%s - %s", rD, s, rD, s, signed_16bit_unary(N));
|
|
break;
|
|
|
|
case 6:
|
|
sprintf(buffer, "%s%s = %s%s &~ %s", rD, s, rD, s, unsigned_16bit_size(N, (op >> 31) & 1));
|
|
break;
|
|
|
|
case 7:
|
|
sprintf(buffer, "%s%s - %s", rD, s, signed_16bit_unary(N));
|
|
break;
|
|
|
|
case 8:
|
|
sprintf(buffer, "%s%s = %s%s ^ %s", rD, s, rD, s, unsigned_16bit_size(N, (op >> 31) & 1));
|
|
break;
|
|
|
|
case 10:
|
|
sprintf(buffer, "%s%s = %s%s | %s", rD, s, rD, s, unsigned_16bit_size(N, (op >> 31) & 1));
|
|
break;
|
|
|
|
case 14:
|
|
sprintf(buffer, "%s%s = %s%s & %s", rD, s, rD, s, unsigned_16bit_size(N, (op >> 31) & 1));
|
|
break;
|
|
|
|
case 15:
|
|
sprintf(buffer, "%s%s & %s", rD, s, unsigned_16bit_size(N, (op >> 31) & 1));
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
|
|
/* CA format 7a */
|
|
case 0x0e:
|
|
if ((op >> 24) & 1)
|
|
sprintf(buffer, "*%08X = %s%s", (INT16)op, regname[(op >> 16) & 0x1f], memsuffix[(op >> 22) & 3]);
|
|
else
|
|
sprintf(buffer, "%s%s = *%08X", regname[(op >> 16) & 0x1f], memsuffix[(op >> 22) & 3], (INT16)op);
|
|
break;
|
|
|
|
/* CA format 7b */
|
|
case 0x0f:
|
|
if ((op >> 24) & 1)
|
|
sprintf(buffer, "%s = %s%s", dasm_PI(op & 0x3ff, tempbuf[0]), regname[(op >> 16) & 0x1f], memsuffix[(op >> 22) & 3]);
|
|
else
|
|
sprintf(buffer, "%s%s = %s", regname[(op >> 16) & 0x1f], memsuffix[(op >> 22) & 3], dasm_PI(op & 0x3ff, tempbuf[0]));
|
|
break;
|
|
|
|
/* CA format 8a */
|
|
case 0x50: case 0x51: case 0x52: case 0x53:
|
|
case 0x54: case 0x55: case 0x56: case 0x57:
|
|
case 0x58: case 0x59: case 0x5a: case 0x5b:
|
|
case 0x5c: case 0x5d: case 0x5e: case 0x5f:
|
|
{
|
|
INT32 N = (op & 0xffff) | ((INT32)((op & 0x1fe00000) << 3) >> 8);
|
|
const char *rH = regname[(op >> 16) & 0x1f];
|
|
|
|
if (((op >> 16) & 0x1f) == 15)
|
|
sprintf(buffer, "goto %s%s [%x]", rH, signed_16bit_sep_nospace(N), (pc + 8 + N) & 0xffffff);
|
|
else if (N && rH[0] != '0')
|
|
sprintf(buffer, "goto %s%s", rH, signed_16bit_sep_nospace(N));
|
|
else if (N)
|
|
sprintf(buffer, "goto $%x", ((INT32)N & 0xffffff));
|
|
else
|
|
{
|
|
if (((op >> 16) & 0x1f) == 20)
|
|
flags = DASMFLAG_STEP_OUT;
|
|
sprintf(buffer, "goto %s", rH);
|
|
}
|
|
break;
|
|
}
|
|
|
|
/* CA format 8b */
|
|
case 0x60: case 0x61: case 0x62: case 0x63:
|
|
case 0x64: case 0x65: case 0x66: case 0x67:
|
|
case 0x68: case 0x69: case 0x6a: case 0x6b:
|
|
case 0x6c: case 0x6d: case 0x6e: case 0x6f:
|
|
{
|
|
INT32 immed = (op & 0xffff) | ((INT32)((op & 0x1fe00000) << 3) >> 8);
|
|
sprintf(buffer, "%s = $%x", regnamee[(op >> 16) & 0x1f], immed & 0xffffff);
|
|
break;
|
|
}
|
|
|
|
/* CA format 8c */
|
|
case 0x70: case 0x71: case 0x72: case 0x73:
|
|
case 0x74: case 0x75: case 0x76: case 0x77:
|
|
case 0x78: case 0x79: case 0x7a: case 0x7b:
|
|
case 0x7c: case 0x7d: case 0x7e: case 0x7f:
|
|
{
|
|
INT32 N = (op & 0xffff) | ((INT32)((op & 0x1fe00000) << 3) >> 8);
|
|
const char *rM = regname[(op >> 16) & 0x1f];
|
|
sprintf(buffer, "call $%x (%s)", N & 0xffffff, rM);
|
|
flags = DASMFLAG_STEP_OVER | DASMFLAG_STEP_OVER_EXTRA(1);
|
|
break;
|
|
}
|
|
}
|
|
|
|
return 4 | flags | DASMFLAG_SUPPORTED;
|
|
}
|