#include "core.h"
#include "m68kd.h"
#include "scsp.h"
typedef struct
{
u16 mask;
u16 inst;
const char *name;
int (*disasm)(u32, u16, char *);
} m68kdis_struct;
static int setsizestr(u16 size, char *outstring)
{
switch (size & 0x3)
{
case 0x1:
return sprintf(outstring, ".b ");
case 0x3:
return sprintf(outstring, ".w ");
case 0x2:
return sprintf(outstring, ".l ");
default:
return sprintf(outstring, " ");
}
}
static int setsizestr2(u16 size, char *outstring)
{
switch (size & 0x3)
{
case 0x0:
return sprintf(outstring, ".b ");
case 0x1:
return sprintf(outstring, ".w ");
case 0x2:
return sprintf(outstring, ".l ");
default:
return sprintf(outstring, " ");
}
}
static int setimmstr(u32 addr, u16 size, int *addsize, char *outstring)
{
switch (size & 0x3)
{
case 0x0:
*addsize+=2;
return sprintf(outstring, "#0x%X", (unsigned int)(c68k_word_read(addr) & 0xFF));
case 0x1:
*addsize+=2;
return sprintf(outstring, "#0x%X", (unsigned int)c68k_word_read(addr));
case 0x2:
*addsize+=4;
return sprintf(outstring, "#0x%X", (unsigned int)((c68k_word_read(addr) << 16) | c68k_word_read(addr+2)));
default:
return 0;
}
}
static int seteafieldstr(u32 addr, u16 modereg, int *addsize, char *outstring)
{
switch ((modereg >> 3) & 0x7)
{
case 0x0:
return sprintf(outstring, "d%d", modereg & 0x7);
case 0x1:
return sprintf(outstring, "a%d", modereg & 0x7);
case 0x2:
return sprintf(outstring, "(a%d)", modereg & 0x7);
case 0x3:
return sprintf(outstring, "(a%d)+", modereg & 0x7);
case 0x4:
return sprintf(outstring, "-(a%d)", modereg & 0x7);
case 0x5:
*addsize += 2;
return sprintf(outstring, "0x%X(a%d)", (unsigned int)c68k_word_read(addr), modereg & 0x7);
case 0x6:
*addsize += 2;
return sprintf(outstring, "0x%X(a%d, Xn)", (unsigned int)(c68k_word_read(addr) & 0xFF), modereg & 0x7);
case 0x7:
switch (modereg & 0x7)
{
case 0x0:
*addsize += 2;
return sprintf(outstring, "(0x%X).w", (unsigned int)c68k_word_read(addr));
case 0x1:
*addsize += 4;
return sprintf(outstring, "(0x%X).l", (unsigned int)((c68k_word_read(addr) << 16) | c68k_word_read(addr+2)));
case 0x4:
*addsize += 2;
return sprintf(outstring, "#0x%X", (unsigned int)c68k_word_read(addr));
case 0x2:
*addsize += 2;
return sprintf(outstring, "0x%X(PC)", (unsigned int)c68k_word_read(addr));
case 0x3:
return 0;
default: break;
}
default: break;
}
return 0;
}
static int setcondstr(u16 cond, char *outstring)
{
switch (cond & 0xF)
{
case 0x0:
return sprintf(outstring, "t ");
case 0x1:
return sprintf(outstring, "f ");
case 0x2:
return sprintf(outstring, "hi");
case 0x3:
return sprintf(outstring, "ls");
case 0x4:
return sprintf(outstring, "cc");
case 0x5:
return sprintf(outstring, "cs");
case 0x6:
return sprintf(outstring, "ne");
case 0x7:
return sprintf(outstring, "eq");
case 0x8:
return sprintf(outstring, "vc");
case 0x9:
return sprintf(outstring, "vs");
case 0xA:
return sprintf(outstring, "pl");
case 0xB:
return sprintf(outstring, "mi");
case 0xC:
return sprintf(outstring, "ge");
case 0xD:
return sprintf(outstring, "lt");
case 0xE:
return sprintf(outstring, "gt");
case 0xF:
return sprintf(outstring, "le");
default: break;
}
return 0;
}
static int setbranchdispstr(u32 addr, u16 op, int *addsize, char *outstring)
{
if ((op & 0xFF) == 0xFF)
{
*addsize += 4;
return sprintf(outstring, ".l %X", (unsigned int)(addr + ((c68k_word_read(addr) << 16) | c68k_word_read(addr+2))));
}
else if ((op & 0xFF) == 0x00)
{
*addsize += 2;
return sprintf(outstring, ".w %X", (unsigned int)((s32)addr + (s32)(s16)c68k_word_read(addr)));
}
return sprintf(outstring, ".s %X", (unsigned int)((s32)addr + (s32)(s8)(op & 0xFF)));
}
static int disabcd(UNUSED u32 addr, UNUSED u16 op, char *outstring)
{
int size=2;
outstring += sprintf(outstring, "abcd");
return size;
}
static int disadd(u32 addr, u16 op, char *outstring)
{
int size=2;
outstring += sprintf(outstring, "add");
outstring += setsizestr2(op >> 6, outstring);
outstring += sprintf(outstring, " ");
if (op & 0x100)
{
outstring += sprintf(outstring, "d%d, ", (op >> 9) & 7);
seteafieldstr(addr+size, op, &size, outstring);
}
else
{
outstring += seteafieldstr(addr+size, op, &size, outstring);
sprintf(outstring, ", d%d", (op >> 9) & 7);
}
return size;
}
static int disadda(u32 addr, u16 op, char *outstring)
{
int size=2;
outstring += sprintf(outstring, "adda");
if ((op & 0x1C0) == 0xC0)
outstring += sprintf(outstring, ".w ");
else
outstring += sprintf(outstring, ".l ");
outstring += seteafieldstr(addr+size, op, &size, outstring);
outstring += sprintf(outstring, ", a%d", (op >> 9) & 0x7);
return size;
}
static int disaddi(u32 addr, u16 op, char *outstring)
{
int size=2;
outstring += sprintf(outstring, "addi");
outstring += setsizestr2(op >> 6, outstring);
outstring += setimmstr(addr+size, op >> 6, &size, outstring);
outstring += sprintf(outstring, ", ");
seteafieldstr(addr+size, op, &size, outstring);
return size;
}
static int disaddq(u32 addr, u16 op, char *outstring)
{
int size=2;
outstring += sprintf(outstring, "addq");
outstring += setsizestr2(op >> 6, outstring);
outstring += sprintf(outstring, " ");
outstring += sprintf(outstring, "#%d, ", (op >> 9) & 7);
seteafieldstr(addr+size, op, &size, outstring);
return size;
}
static int disaddx(UNUSED u32 addr, UNUSED u16 op, char *outstring)
{
int size=2;
outstring += sprintf(outstring, "addx");
return size;
}
static int disand(UNUSED u32 addr, UNUSED u16 op, char *outstring)
{
int size=2;
outstring += sprintf(outstring, "and");
return size;
}
static int disandi(u32 addr, u16 op, char *outstring)
{
int size=2;
outstring += sprintf(outstring, "andi");
outstring += setsizestr2(op >> 6, outstring);
outstring += sprintf(outstring, " ");
outstring += setimmstr(addr+size, op >> 6, &size, outstring);
outstring += sprintf(outstring, ", ");
seteafieldstr(addr+size, op, &size, outstring);
return size;
}
static int disanditoccr(UNUSED u32 addr, UNUSED u16 op, char *outstring)
{
int size=2;
outstring += sprintf(outstring, "andi to CCR");
return size;
}
static int disasl(UNUSED u32 addr, UNUSED u16 op, char *outstring)
{
int size=2;
outstring += sprintf(outstring, "asl");
return size;
}
static int disasr(UNUSED u32 addr, UNUSED u16 op, char *outstring)
{
int size=2;
outstring += sprintf(outstring, "asr");
return size;
}
static int disbcc(u32 addr, u16 op, char *outstring)
{
int size=2;
outstring += sprintf(outstring, "b");
outstring += setcondstr(op >> 8, outstring);
setbranchdispstr(addr+size, op, &size, outstring);
return size;
}
static int disbkpt(UNUSED u32 addr, UNUSED u16 op, char *outstring)
{
int size=2;
outstring += sprintf(outstring, "bkpt");
return size;
}
static int disbra(u32 addr, u16 op, char *outstring)
{
int size=2;
outstring += sprintf(outstring, "bra");
setbranchdispstr(addr+size, op, &size, outstring);
return size;
}
static int disbchg(UNUSED u32 addr, UNUSED u16 op, char *outstring)
{
int size=2;
outstring += sprintf(outstring, "bchg");
return size;
}
static int disbclrd(UNUSED u32 addr, UNUSED u16 op, char *outstring)
{
int size=2;
outstring += sprintf(outstring, "bclr");
return size;
}
static int disbclrs(u32 addr, u16 op, char *outstring)
{
int size=2;
outstring += sprintf(outstring, "bclr ");
outstring += setimmstr(addr+size, 0, &size, outstring);
outstring += sprintf(outstring, ", ");
seteafieldstr(addr+size, op, &size, outstring);
return size;
}
static int disbsetd(UNUSED u32 addr, UNUSED u16 op, char *outstring)
{
int size=2;
outstring += sprintf(outstring, "bset");
return size;
}
static int disbsets(u32 addr, u16 op, char *outstring)
{
int size=2;
outstring += sprintf(outstring, "bset ");
outstring += setimmstr(addr+size, 0, &size, outstring);
outstring += sprintf(outstring, ", ");
seteafieldstr(addr+size, op, &size, outstring);
return size;
}
static int disbtstd(UNUSED u32 addr, UNUSED u16 op, char *outstring)
{
int size=2;
outstring += sprintf(outstring, "btst");
return size;
}
static int disbtsts(u32 addr, u16 op, char *outstring)
{
int size=2;
outstring += sprintf(outstring, "btst ");
outstring += setimmstr(addr+size, 0, &size, outstring);
outstring += sprintf(outstring, ", ");
seteafieldstr(addr+size, op, &size, outstring);
return size;
}
static int disbsr(u32 addr, u16 op, char *outstring)
{
int size=2;
outstring += sprintf(outstring, "bsr");
setbranchdispstr(addr+size, op, &size, outstring);
return size;
}
static int dischk(UNUSED u32 addr, UNUSED u16 op, char *outstring)
{
int size=2;
outstring += sprintf(outstring, "chk");
return size;
}
static int disclr(u32 addr, u16 op, char *outstring)
{
int size=2;
outstring += sprintf(outstring, "clr");
outstring += setsizestr2((op >> 6), outstring);
outstring += sprintf(outstring, " ");
seteafieldstr(addr+size, op, &size, outstring);
return size;
}
static int disdbcc(u32 addr, u16 op, char *outstring)
{
outstring += sprintf(outstring, "db");
outstring += setcondstr(op >> 8, outstring);
outstring += sprintf(outstring, " ");
sprintf(outstring, " d%d, %X", op & 0x7, (unsigned int)((s32)addr+2+(s32)(s16)c68k_word_read(addr+2)));
return 4;
}
static int discmpb(u32 addr, u16 op, char *outstring)
{
int size=2;
outstring += sprintf(outstring, "cmp.b ");
outstring += seteafieldstr(addr+size, op, &size, outstring);
outstring += sprintf(outstring, ", d%d", (op >> 9) & 0x7);
return size;
}
static int discmpw(u32 addr, u16 op, char *outstring)
{
int size=2;
outstring += sprintf(outstring, "cmp.w ");
outstring += seteafieldstr(addr+size, op, &size, outstring);
outstring += sprintf(outstring, ", d%d", (op >> 9) & 0x7);
return size;
}
static int discmpl(u32 addr, u16 op, char *outstring)
{
int size=2;
outstring += sprintf(outstring, "cmp.l ");
outstring += seteafieldstr(addr+size, op, &size, outstring);
outstring += sprintf(outstring, ", d%d", (op >> 9) & 0x7);
return size;
}
static int discmpaw(UNUSED u32 addr, UNUSED u16 op, char *outstring)
{
int size=2;
outstring += sprintf(outstring, "cmpa.w");
return size;
}
static int discmpal(UNUSED u32 addr, UNUSED u16 op, char *outstring)
{
int size=2;
outstring += sprintf(outstring, "cmpa.l");
return size;
}
static int discmpi(u32 addr, u16 op, char *outstring)
{
int size=2;
outstring += sprintf(outstring, "cmpi");
outstring += setsizestr2((op >> 6), outstring);
outstring += sprintf(outstring, " ");
outstring += setimmstr(addr+size, op >> 6, &size, outstring);
outstring += sprintf(outstring, ", ");
seteafieldstr(addr+size, op, &size, outstring);
return size;
}
static int disdivs(UNUSED u32 addr, UNUSED u16 op, char *outstring)
{
int size=2;
outstring += sprintf(outstring, "divs.w");
return size;
}
static int disdivu(UNUSED u32 addr, UNUSED u16 op, char *outstring)
{
int size=2;
outstring += sprintf(outstring, "divu.w");
return size;
}
static int discmpm(UNUSED u32 addr, UNUSED u16 op, char *outstring)
{
int size=2;
outstring += sprintf(outstring, "cmpm");
return size;
}
static int diseorb(UNUSED u32 addr, UNUSED u16 op, char *outstring)
{
int size=2;
outstring += sprintf(outstring, "eor.b");
return size;
}
static int diseorw(UNUSED u32 addr, UNUSED u16 op, char *outstring)
{
int size=2;
outstring += sprintf(outstring, "eor.w");
return size;
}
static int diseorl(UNUSED u32 addr, UNUSED u16 op, char *outstring)
{
int size=2;
outstring += sprintf(outstring, "eor.l");
return size;
}
static int diseori(UNUSED u32 addr, UNUSED u16 op, char *outstring)
{
int size=2;
outstring += sprintf(outstring, "eori");
return size;
}
static int diseoritoccr(UNUSED u32 addr, UNUSED u16 op, char *outstring)
{
int size=2;
outstring += sprintf(outstring, "eori to ccr");
return size;
}
static int disexg(UNUSED u32 addr, UNUSED u16 op, char *outstring)
{
int size=2;
outstring += sprintf(outstring, "exg");
return size;
}
static int disext(UNUSED u32 addr, UNUSED u16 op, char *outstring)
{
int size=2;
outstring += sprintf(outstring, "ext");
return size;
}
static int disillegal(UNUSED u32 addr, UNUSED u16 op, char *outstring)
{
sprintf(outstring, "illegal");
return 2;
}
static int disjmp(u32 addr, u16 op, char *outstring)
{
int size=2;
outstring += sprintf(outstring, "jmp ");
seteafieldstr(addr+size, op, &size, outstring);
return size;
}
static int disjsr(u32 addr, u16 op, char *outstring)
{
int size=2;
outstring += sprintf(outstring, "jsr ");
seteafieldstr(addr+size, op, &size, outstring);
return size;
}
static int dislea(u32 addr, u16 op, char *outstring)
{
int size=2;
outstring += sprintf(outstring, "lea ");
outstring += seteafieldstr(addr+size, op, &size, outstring);
outstring += sprintf(outstring, ", a%d", (op >> 9) & 0x7);
return size;
}
static int dislink(UNUSED u32 addr, UNUSED u16 op, char *outstring)
{
int size=2;
outstring += sprintf(outstring, "link");
return size;
}
static int dislsl(UNUSED u32 addr, u16 op, char *outstring)
{
int size=2;
outstring += sprintf(outstring, "lsl");
outstring += setsizestr2(op >> 6, outstring);
return size;
}
static int dislsr(UNUSED u32 addr, u16 op, char *outstring)
{
int size=2;
outstring += sprintf(outstring, "lsr");
outstring += setsizestr2(op >> 6, outstring);
return size;
}
static int dismove(u32 addr, u16 op, char *outstring)
{
int size=2;
outstring += sprintf(outstring, "move");
outstring += setsizestr((op >> 12), outstring);
outstring += sprintf(outstring, " ");
outstring += seteafieldstr(addr+size, op, &size, outstring);
outstring += sprintf(outstring, ", ");
seteafieldstr(addr+size, ((op >> 3) & 0x38) | ((op >> 9) & 0x7), &size, outstring);
return size;
}
static int dismovea(u32 addr, u16 op, char *outstring)
{
int size=2;
outstring += sprintf(outstring, "movea");
outstring += setsizestr((op >> 12), outstring);
outstring += seteafieldstr(addr+size, op, &size, outstring);
outstring += sprintf(outstring, ", a%d", (op >> 9) & 0x7);
return size;
}
static int dismovetoccr(UNUSED u32 addr, UNUSED u16 op, char *outstring)
{
int size=2;
outstring += sprintf(outstring, "move to ccr");
return size;
}
static int dismovefromsr(UNUSED u32 addr, UNUSED u16 op, char *outstring)
{
int size=2;
outstring += sprintf(outstring, "move from sr");
return size;
}
static int dismovetosr(u32 addr, u16 op, char *outstring)
{
int size=2;
outstring += sprintf(outstring, "move ");
outstring += seteafieldstr(addr+size, op, &size, outstring);
sprintf(outstring, ", sr");
return size;
}
static int dismovem(UNUSED u32 addr, UNUSED u16 op, char *outstring)
{
outstring += sprintf(outstring, "movem");
return 4;
}
static int dismovep(UNUSED u32 addr, UNUSED u16 op, char *outstring)
{
int size=2;
outstring += sprintf(outstring, "movep");
return size;
}
static int dismoveq(UNUSED u32 addr, u16 op, char *outstring)
{
int size=2;
outstring += sprintf(outstring, "moveq #0x%X, d%d", op & 0xFF, (op >> 9) & 0x7);
return size;
}
static int dismuls(UNUSED u32 addr, UNUSED u16 op, char *outstring)
{
int size=2;
outstring += sprintf(outstring, "muls");
return size;
}
static int dismulu(UNUSED u32 addr, UNUSED u16 op, char *outstring)
{
int size=2;
outstring += sprintf(outstring, "mulu");
return size;
}
static int disnbcd(UNUSED u32 addr, UNUSED u16 op, char *outstring)
{
int size=2;
outstring += sprintf(outstring, "nbcd");
return size;
}
static int disneg(u32 addr, u16 op, char *outstring)
{
int size=2;
outstring += sprintf(outstring, "neg");
outstring += setsizestr2((op >> 6), outstring);
outstring += sprintf(outstring, " ");
seteafieldstr(addr+size, op, &size, outstring);
return size;
}
static int disnegx(UNUSED u32 addr, UNUSED u16 op, char *outstring)
{
int size=2;
outstring += sprintf(outstring, "negx");
return size;
}
static int disnop(UNUSED u32 addr, UNUSED u16 op, char *outstring)
{
sprintf(outstring, "nop");
return 2;
}
static int disnot(UNUSED u32 addr, UNUSED u16 op, char *outstring)
{
int size=2;
outstring += sprintf(outstring, "not");
return size;
}
static int disor(UNUSED u32 addr, UNUSED u16 op, char *outstring)
{
int size=2;
outstring += sprintf(outstring, "ori to CCR");
return size;
}
static int disori(UNUSED u32 addr, UNUSED u16 op, char *outstring)
{
int size=2;
outstring += sprintf(outstring, "ori");
return size;
}
static int disoritoccr(UNUSED u32 addr, UNUSED u16 op, char *outstring)
{
int size=2;
outstring += sprintf(outstring, "ori to CCR");
return size;
}
static int dispea(UNUSED u32 addr, UNUSED u16 op, char *outstring)
{
int size=2;
outstring += sprintf(outstring, "pea");
return size;
}
static int disrol(UNUSED u32 addr, UNUSED u16 op, char *outstring)
{
int size=2;
outstring += sprintf(outstring, "rol");
return size;
}
static int disror(UNUSED u32 addr, UNUSED u16 op, char *outstring)
{
int size=2;
outstring += sprintf(outstring, "ror");
return size;
}
static int disroxl(UNUSED u32 addr, UNUSED u16 op, char *outstring)
{
int size=2;
outstring += sprintf(outstring, "roxl");
return size;
}
static int disroxr(UNUSED u32 addr, UNUSED u16 op, char *outstring)
{
int size=2;
outstring += sprintf(outstring, "roxr");
return size;
}
static int disrtr(UNUSED u32 addr, UNUSED u16 op, char *outstring)
{
sprintf(outstring, "rtr");
return 2;
}
static int disrts(UNUSED u32 addr, UNUSED u16 op, char *outstring)
{
sprintf(outstring, "rts");
return 2;
}
static int dissbcd(UNUSED u32 addr, UNUSED u16 op, char *outstring)
{
int size=2;
outstring += sprintf(outstring, "sbcd");
return size;
}
static int disscc(UNUSED u32 addr, UNUSED u16 op, char *outstring)
{
int size=2;
outstring += sprintf(outstring, "scc");
return size;
}
static int dissub(UNUSED u32 addr, UNUSED u16 op, char *outstring)
{
int size=2;
outstring += sprintf(outstring, "sub");
return size;
}
static int dissuba(UNUSED u32 addr, UNUSED u16 op, char *outstring)
{
int size=2;
outstring += sprintf(outstring, "suba");
return size;
}
static int dissubi(u32 addr, u16 op, char *outstring)
{
int size=2;
outstring += sprintf(outstring, "subi");
outstring += setsizestr2(op >> 6, outstring);
outstring += sprintf(outstring, " ");
outstring += setimmstr(addr+size, op >> 6, &size, outstring);
outstring += sprintf(outstring, ", ");
seteafieldstr(addr+size, op, &size, outstring);
return size;
}
static int dissubq(u32 addr, u16 op, char *outstring)
{
int size=2;
outstring += sprintf(outstring, "subq");
outstring += setsizestr2(op >> 6, outstring);
outstring += sprintf(outstring, " #%d, ", (op >> 9) & 7);
seteafieldstr(addr+size, op, &size, outstring);
return size;
}
static int dissubx(UNUSED u32 addr, UNUSED u16 op, char *outstring)
{
int size=2;
outstring += sprintf(outstring, "subx");
return size;
}
static int disswap(UNUSED u32 addr, u16 op, char *outstring)
{
sprintf(outstring, "swap d%d", op & 0x7);
return 2;
}
static int distas(UNUSED u32 addr, UNUSED u16 op, char *outstring)
{
int size=2;
outstring += sprintf(outstring, "tas");
return size;
}
static int distrap(UNUSED u32 addr, UNUSED u16 op, char *outstring)
{
int size=2;
outstring += sprintf(outstring, "trap");
return size;
}
static int distrapv(UNUSED u32 addr, UNUSED u16 op, char *outstring)
{
sprintf(outstring, "trapv");
return 2;
}
static int distst(UNUSED u32 addr, UNUSED u16 op, char *outstring)
{
int size=2;
outstring += sprintf(outstring, "tst");
return size;
}
static int disunlk(UNUSED u32 addr, UNUSED u16 op, char *outstring)
{
int size=2;
outstring += sprintf(outstring, "unlk");
return size;
}
static m68kdis_struct instruction[] = {
{ 0xFFFF, 0x023C, "andi #??, CCR", disanditoccr },
{ 0xFFFF, 0x0A3C, "eori #??, CCR", diseoritoccr },
{ 0xFFFF, 0x4AFC, "illegal", disillegal },
{ 0xFFFF, 0x4E71, "nop", disnop },
{ 0xFFFF, 0x003C, "ori #??, CCR", disoritoccr },
{ 0xFFFF, 0x4E77, "rtr", disrtr },
{ 0xFFFF, 0x4E75, "rts", disrts },
{ 0xFFFF, 0x4E76, "trapv", distrapv },
{ 0xFFF8, 0x4848, "bkpt", disbkpt },
{ 0xFFF8, 0x4E50, "link", dislink },
{ 0xFFF8, 0x4840, "swap", disswap },
{ 0xFFF8, 0x4E58, "unlk", disunlk },
{ 0xFFF0, 0x4E40, "trap", distrap },
{ 0xF1F8, 0xD100, "addx.b", disaddx },
{ 0xF1F8, 0xD140, "addx.w", disaddx },
{ 0xF1F8, 0xD180, "addx.l", disaddx },
{ 0xF1F8, 0xB108, "cmpm.b", discmpm },
{ 0xF1F8, 0xB148, "cmpm.w", discmpm },
{ 0xF1F8, 0xB188, "cmpm.l", discmpm },
{ 0xFFC0, 0xE1C0, "asl", disasl },
{ 0xFFC0, 0xE0C0, "asr", disasr },
{ 0xFFC0, 0x0880, "bclr", disbclrs },
{ 0xFFC0, 0x08C0, "bset", disbsets },
{ 0xFFC0, 0x0800, "btst", disbtsts },
{ 0xFFC0, 0x4EC0, "jmp", disjmp },
{ 0xFFC0, 0x4E80, "jsr", disjsr },
{ 0xFFC0, 0x44C0, "move ??, CCR", dismovetoccr },
{ 0xFFC0, 0x40C0, "move SR, ??", dismovefromsr },
{ 0xFFC0, 0x46C0, "move ??, SR", dismovetosr },
{ 0xFFC0, 0x4800, "nbcd", disnbcd },
{ 0xFFC0, 0x4840, "pea", dispea },
{ 0xFFC0, 0x4AC0, "tas", distas },
{ 0xFE38, 0x4800, "ext", disext },
{ 0xF1F0, 0xC100, "abcd", disabcd },
{ 0xF1F0, 0x8100, "sbcd", dissbcd },
{ 0xF0F8, 0x50C8, "dbcc", disdbcc },
{ 0xFB80, 0x4880, "movem", dismovem },
{ 0xFF00, 0x0600, "addi", disaddi },
{ 0xFF00, 0x0200, "andi", disandi },
{ 0xFF00, 0x6000, "bra", disbra },
{ 0xFF00, 0x6100, "bsr", disbsr },
{ 0xFF00, 0x4200, "clr", disclr },
{ 0xFF00, 0x0C00, "cmpi", discmpi },
{ 0xFF00, 0x0A00, "eori", diseori },
{ 0xFF00, 0x4400, "neg", disneg },
{ 0xFF00, 0x4000, "negx", disnegx },
{ 0xFF00, 0x4600, "not", disnot },
{ 0xFF00, 0x0000, "ori", disori },
{ 0xFF00, 0x0400, "subi", dissubi },
{ 0xFF00, 0x4A00, "tst", distst },
{ 0xF118, 0xE108, "lsl", dislsl },
{ 0xF118, 0xE008, "lsr", dislsr },
{ 0xF118, 0xE118, "rol", disrol },
{ 0xF118, 0xE018, "ror", disror },
{ 0xF118, 0xE110, "roxl", disroxl },
{ 0xF118, 0xE010, "roxr", disroxr },
{ 0xF1C0, 0xD0C0, "adda.w", disadda },
{ 0xF1C0, 0xD1C0, "adda.l", disadda },
{ 0xF1C0, 0x0140, "bchg", disbchg },
{ 0xF1C0, 0x0180, "bclr", disbclrd },
{ 0xF1C0, 0x01C0, "bset", disbsetd },
{ 0xF1C0, 0x0100, "btst", disbtstd },
{ 0xF1C0, 0xB000, "cmp.b", discmpb },
{ 0xF1C0, 0xB040, "cmp.w", discmpw },
{ 0xF1C0, 0xB080, "cmp.l", discmpl },
{ 0xF1C0, 0xB0C0, "cmpa.w", discmpaw },
{ 0xF1C0, 0xB1C0, "cmpa.l", discmpal },
{ 0xF1C0, 0x81C0, "divs.w", disdivs },
{ 0xF1C0, 0x80C0, "divu.w", disdivu },
{ 0xF1C0, 0xB100, "eor.b", diseorb },
{ 0xF1C0, 0xB140, "eor.w", diseorw },
{ 0xF1C0, 0xB180, "eor.l", diseorl },
{ 0xF1C0, 0x41C0, "lea", dislea },
{ 0xF1C0, 0xC1C0, "muls", dismuls },
{ 0xF1C0, 0xC0C0, "mulu", dismulu },
{ 0xF130, 0x9100, "subx", dissubx },
{ 0xF038, 0x0008, "movep", dismovep },
{ 0xF0C0, 0x50C0, "scc", disscc },
{ 0xC1C0, 0x0040, "movea", dismovea },
{ 0xF040, 0x4000, "chk", dischk },
{ 0xF100, 0x5000, "addq", disaddq },
{ 0xF100, 0xC100, "exg", disexg },
{ 0xF100, 0x7000, "moveq", dismoveq },
{ 0xF100, 0x5100, "subq", dissubq },
{ 0xF000, 0xD000, "add", disadd },
{ 0xF000, 0xC000, "and", disand },
{ 0xF000, 0x6000, "bcc", disbcc },
{ 0xF000, 0x8000, "or", disor },
{ 0xF000, 0x9000, "sub", dissub },
{ 0xF000, 0x9000, "suba", dissuba },
{ 0xC000, 0x0000, "move", dismove },
{ 0x0000, 0x0000, NULL, NULL }
};
u32 M68KDisasm(u32 addr, char *outstring)
{
int i;
outstring += sprintf(outstring, "%05X: ", (unsigned int)addr);
for (i = 0; instruction[i].name != NULL; i++)
{
u16 op = (u16)c68k_word_read(addr);
if ((op & instruction[i].mask) == instruction[i].inst)
{
addr += instruction[i].disasm(addr, op, outstring);
return addr;
}
}
sprintf(outstring, "unknown");
return (addr+2);
}