#include "uae/io.h"
#include "uae/ppc.h"
#include "drawing.h"
+#include "devices.h"
int debugger_active;
static uaecptr skipaddr_start, skipaddr_end;
_T(" r Dump state of the CPU.\n")
_T(" r <reg> <value> Modify CPU registers (Dx,Ax,USP,ISP,VBR,...).\n")
_T(" m <address> [<lines>] Memory dump starting at <address>.\n")
+ _T(" a <address> Assembler.\n")
_T(" d <address> [<lines>] Disassembly starting at <address>.\n")
_T(" t [instructions] Step one or more instructions.\n")
_T(" z Step through one instruction - useful for JSR, DBRA etc.\n")
_T(" Cl List currently found trainer addresses.\n")
_T(" D[idxzs <[max diff]>] Deep trainer. i=new value must be larger, d=smaller,\n")
_T(" x = must be same, z = must be different, s = restart.\n")
- _T(" W <address> <values[.x] separated by space> Write into Amiga memory.\n")
- _T(" W <address> 'string' Write into Amiga memory.\n")
+ _T(" W <addr> <values[.x] separated by space> Write into Amiga memory.\n")
+ _T(" W <addr> 'string' Write into Amiga memory.\n")
+ _T(" Wf <addr> <endaddr> <bytes or string like above>, fill memory.\n")
+ _T(" Wc <addr> <endaddr> <destaddr>, copy memory.\n")
_T(" w <num> <address> <length> <R/W/I/F/C> [<value>[.x]] (read/write/opcode/freeze/mustchange).\n")
_T(" Add/remove memory watchpoints.\n")
_T(" wd [<0-1>] Enable illegal access logger. 1 = enable break.\n")
+ _T(" L <file> <addr> <n> Load a block of Amiga memory.\n")
_T(" S <file> <addr> <n> Save a block of Amiga memory.\n")
_T(" s \"<string>\"/<values> [<addr>] [<length>]\n")
_T(" Search for string/bytes.\n")
_T(" v <vpos> [<hpos>] Show DMA data (accurate only in cycle-exact mode).\n")
_T(" v [-1 to -4] = enable visual DMA debugger.\n")
_T(" vh [<ratio> <lines>] \"Heat map\"\n")
+ _T(" I <custom event> Send custom event string\n")
_T(" ?<value> Hex ($ and 0x)/Bin (%)/Dec (!) converter and calculator.\n")
#ifdef _WIN32
_T(" x Close debugger.\n")
static addrbank **debug_mem_banks;
static addrbank *debug_mem_area;
struct memwatch_node mwnodes[MEMWATCH_TOTAL];
+static int mwnodes_cnt;
static struct memwatch_node mwhit;
+#define MUNGWALL_SLOTS 16
+struct mungwall_data
+{
+ int slots;
+ uae_u32 start[MUNGWALL_SLOTS], end[MUNGWALL_SLOTS];
+};
+static struct mungwall_data **mungwall;
+
static uae_u8 *illgdebug, *illghdebug;
static int illgdebug_break;
}
}
+static void mungwall_memwatch(uaecptr addr, int rwi, int size, uae_u32 valp)
+{
+ struct mungwall_data *mwd = mungwall[addr >> 16];
+ if (!mwd)
+ return;
+ for (int i = 0; i < mwd->slots; i++) {
+ if (!mwd->end[i])
+ continue;
+ if (addr + size > mwd->start[i] && addr < mwd->end[i]) {
+
+ }
+ }
+}
+
static int memwatch_func (uaecptr addr, int rwi, int size, uae_u32 *valp, uae_u32 accessmask, uae_u32 reg)
{
int i, brk;
uae_u32 val = *valp;
+ if (mungwall)
+ mungwall_memwatch(addr, rwi, size, val);
+
if (illgdebug)
illg_debug_do (addr, rwi, size, val);
addr = munge24 (addr);
if (smc_table && (rwi >= 2))
smc_detector (addr, rwi, size, valp);
- for (i = 0; i < MEMWATCH_TOTAL; i++) {
+ for (i = 0; i < mwnodes_cnt; i++) {
struct memwatch_node *m = &mwnodes[i];
uaecptr addr2 = m->addr;
uaecptr addr3 = addr2 + m->size;
static void memwatch_setup (void)
{
memwatch_reset ();
+ mwnodes_cnt = 0;
for (int i = 0; i < MEMWATCH_TOTAL; i++) {
struct memwatch_node *m = &mwnodes[i];
uae_u32 size = 0;
if (!m->size)
continue;
+ mwnodes_cnt++;
while (size < m->size) {
memwatch_remap (m->addr + size);
size += 65536;
memwatch_dump (num);
}
+static void copymem(TCHAR **c)
+{
+ uae_u32 addr = 0, eaddr = 0, dst = 0;
+
+ ignore_ws(c);
+ if (!more_params (c))
+ return;
+ addr = readhex (c);
+ ignore_ws (c);
+ if (!more_params (c))
+ return;
+ eaddr = readhex (c);
+ ignore_ws (c);
+ if (!more_params (c))
+ return;
+ dst = readhex (c);
+
+ if (addr >= eaddr)
+ return;
+ uae_u32 addrb = addr;
+ uae_u32 dstb = dst;
+ uae_u32 len = eaddr - addr;
+ if (dst <= addr) {
+ while (addr < eaddr) {
+ put_byte(dst, get_byte(addr));
+ addr++;
+ dst++;
+ }
+ } else {
+ dst += eaddr - addr;
+ while (addr < eaddr) {
+ dst--;
+ eaddr--;
+ put_byte(dst, get_byte(eaddr));
+ }
+ }
+ console_out_f(_T("Copied from %08x - %08x to %08x - %08x\n"), addrb, addrb + len - 1, dstb, dstb + len - 1);
+}
+
static void writeintomem (TCHAR **c)
{
uae_u32 addr = 0;
+ uae_u32 eaddr = 0xffffffff;
uae_u32 val = 0;
TCHAR cc;
int len = 1;
+ bool fillmode = false;
+
+ if (**c == 'f') {
+ fillmode = true;
+ (*c)++;
+ } else if (**c == 'c') {
+ (*c)++;
+ copymem(c);
+ return;
+ }
ignore_ws(c);
addr = readhex (c);
-
ignore_ws (c);
+
+ if (fillmode) {
+ if (!more_params (c))
+ return;
+ eaddr = readhex(c);
+ ignore_ws (c);
+ }
+
if (!more_params (c))
return;
+ TCHAR *cb = *c;
cc = peekchar (c);
- if (cc == '\'' || cc == '\"') {
- next_char (c);
- while (more_params (c)) {
- TCHAR str[2];
- char *astr;
- cc = next_char (c);
- if (cc == '\'' || cc == '\"')
- break;
- str[0] = cc;
- str[1] = 0;
- astr = ua (str);
- put_byte (addr, astr[0]);
- xfree (astr);
- addr++;
- }
- } else {
- for (;;) {
- ignore_ws (c);
- if (!more_params (c))
- break;
- val = readhex (c, &len);
-
- if (len == 4) {
- put_long (addr, val);
- cc = 'L';
- } else if (len == 2) {
- put_word (addr, val);
- cc = 'W';
- } else if (len == 1) {
- put_byte (addr, val);
- cc = 'B';
- } else {
- break;
+ uae_u32 addrc = addr;
+ for(;;) {
+ uae_u32 addrb = addr;
+ *c = cb;
+ if (cc == '\'' || cc == '\"') {
+ next_char (c);
+ while (more_params (c)) {
+ TCHAR str[2];
+ char *astr;
+ cc = next_char (c);
+ if (cc == '\'' || cc == '\"')
+ break;
+ str[0] = cc;
+ str[1] = 0;
+ astr = ua (str);
+ put_byte (addr, astr[0]);
+ xfree (astr);
+ addr++;
+ if (addr >= eaddr)
+ break;
+ }
+ } else {
+ for (;;) {
+ ignore_ws (c);
+ if (!more_params (c))
+ break;
+ val = readhex (c, &len);
+
+ if (len == 4) {
+ put_long (addr, val);
+ cc = 'L';
+ } else if (len == 2) {
+ put_word (addr, val);
+ cc = 'W';
+ } else if (len == 1) {
+ put_byte (addr, val);
+ cc = 'B';
+ } else {
+ break;
+ }
+ if (!fillmode)
+ console_out_f (_T("Wrote %X (%u) at %08X.%c\n"), val, val, addr, cc);
+ addr += len;
+ if (addr >= eaddr)
+ break;
}
- console_out_f (_T("Wrote %X (%u) at %08X.%c\n"), val, val, addr, cc);
- addr += len;
}
+ if (eaddr == 0xffffffff || addr <= addrb || addr >= eaddr)
+ break;
}
+ if (eaddr != 0xffffffff)
+ console_out_f(_T("Wrote data to %08x - %08x\n"), addrc, addr);
}
static uae_u8 *dump_xlate (uae_u32 addr)
return 1;
}
-static void savemem (TCHAR **cc)
+static void saveloadmem (TCHAR **cc, bool save)
{
uae_u8 b;
uae_u32 src, src2, len, len2;
console_out_f (_T("Couldn't open file '%s'\n"), name);
return;
}
- while (len > 0) {
- b = get_byte_debug (src);
- src++;
- len--;
- if (fwrite (&b, 1, 1, fp) != 1) {
- console_out (_T("Error writing file\n"));
- break;
+ if (save) {
+ while (len > 0) {
+ b = get_byte_debug (src);
+ src++;
+ len--;
+ if (fwrite (&b, 1, 1, fp) != 1) {
+ console_out (_T("Error writing file\n"));
+ break;
+ }
+ }
+ if (len == 0)
+ console_out_f (_T("Wrote %08X - %08X (%d bytes) to '%s'\n"),
+ src2, src2 + len2, len2, name);
+ } else {
+ while (len > 0) {
+ if (fread(&b, 1, 1, fp) != 1) {
+ console_out (_T("Error reading file\n"));
+ break;
+ }
+ put_byte (src, b);
+ src++;
+ len--;
}
+ if (len == 0)
+ console_out_f (_T("Read %08X - %08X (%d bytes) to '%s'\n"),
+ src2, src2 + len2, len2, name);
}
fclose (fp);
- if (len == 0)
- console_out_f (_T("Wrote %08X - %08X (%d bytes) to '%s'\n"),
- src2, src2 + len2, len2, name);
return;
S_argh:
console_out (_T("S-command needs more arguments!\n"));
}
}
-static uaecptr nxdis, nxmem;
-static bool ppcmode;
+static uaecptr nxdis, nxmem, asmaddr;
+static bool ppcmode, asmmode;
static bool debug_line (TCHAR *input)
{
uaecptr addr;
inptr = input;
+
+ if (asmmode) {
+ if (more_params(&inptr)) {
+ if (!_tcsicmp(inptr, _T("x"))) {
+ asmmode = false;
+ return false;
+ }
+ uae_u16 asmout[16];
+ int inss = m68k_asm(inptr, asmout, asmaddr);
+ if (inss > 0) {
+ for (int i = 0; i < inss; i++) {
+ put_word(asmaddr + i * 2, asmout[i]);
+ }
+ m68k_disasm(asmaddr, &nxdis, 1);
+ asmaddr = nxdis;
+ }
+ console_out_f(_T("%08X "), asmaddr);
+ return false;
+ } else {
+ asmmode = false;
+ return false;
+ }
+ }
+
cmd = next_char (&inptr);
switch (cmd)
{
+ case 'I':
+ if (more_params (&inptr)) {
+ static int recursive;
+ if (!recursive) {
+ recursive++;
+ handle_custom_event(inptr, 0);
+ device_check_config();
+ recursive--;
+ }
+ }
+ break;
case 'c': dumpcia (); dumpdisk (_T("DEBUG")); dumpcustom (); break;
case 'i':
{
case 'C': cheatsearch (&inptr); break;
case 'W': writeintomem (&inptr); break;
case 'w': memwatch (&inptr); break;
- case 'S': savemem (&inptr); break;
+ case 'S': saveloadmem (&inptr, true); break;
+ case 'L': saveloadmem (&inptr, false); break;
case 's':
if (*inptr == 'c') {
screenshot (1, 1);
searchmem (&inptr);
}
break;
+ case 'a':
+ asmaddr = nxdis;
+ if (more_params(&inptr)) {
+ asmaddr = readhex(&inptr);
+ if (more_params(&inptr)) {
+ uae_u16 asmout[16];
+ int inss = m68k_asm(inptr, asmout, asmaddr);
+ if (inss > 0) {
+ for (int i = 0; i < inss; i++) {
+ put_word(asmaddr + i * 2, asmout[i]);
+ }
+ m68k_disasm(asmaddr, &nxdis, 1);
+ asmaddr = nxdis;
+ return false;
+ }
+ }
+ }
+ asmmode = true;
+ console_out_f(_T("%08X "), asmaddr);
+ break;
case 'd':
{
if (*inptr == 'i') {
break;
case absw:
addr = (uae_s32)(uae_s16)get_iword_debug (pc);
- _stprintf (buffer, _T("$%08x"), addr);
+ _stprintf (buffer, _T("$%04x"), (uae_u16)addr);
pc += 2;
break;
case absl:
break;
case immi:
offset = (uae_s32)(uae_s8)(reg & 0xff);
- _stprintf (buffer, _T("#$%08x"), (uae_u32)offset);
+ _stprintf (buffer, _T("#$%02x"), (uae_u8)offset);
addr = pc + offset;
break;
default:
}
}
+static void asm_add_extensions(uae_u16 *data, int *dcntp, int mode, uae_u32 v, uae_u16 *ext, uaecptr pc, int size)
+{
+ int dcnt = *dcntp;
+ if (mode < 0)
+ return;
+ if (mode == Ad16) {
+ data[dcnt++] = v;
+ }
+ if (mode == PC16) {
+ data[dcnt++] = v - (pc + 2);
+ }
+ if (mode == Ad8r || mode == PC8r) {
+ data[dcnt++] = ext[0];
+ }
+ if (mode == absw) {
+ data[dcnt++] = (uae_u16)v;
+ }
+ if (mode == absl) {
+ data[dcnt++] = (uae_u16)(v >> 16);
+ data[dcnt++] = (uae_u16)v;
+ }
+ if ((mode == imm && size == 0) || mode == imm0) {
+ data[dcnt++] = (uae_u8)v;
+ }
+ if ((mode == imm && size == 1) || mode == imm1) {
+ data[dcnt++] = (uae_u16)v;
+ }
+ if ((mode == imm && size == 2) || mode == imm2) {
+ data[dcnt++] = (uae_u16)(v >> 16);
+ data[dcnt++] = (uae_u16)v;
+ }
+ *dcntp = dcnt;
+}
+
+static int asm_isdreg(const TCHAR *s)
+{
+ if (s[0] == 'D' && s[1] >= '0' && s[1] <= '7')
+ return s[1] - '0';
+ return -1;
+}
+static int asm_isareg(const TCHAR *s)
+{
+ if (s[0] == 'A' && s[1] >= '0' && s[1] <= '7')
+ return s[1] - '0';
+ return -1;
+}
+static int asm_ispc(const TCHAR *s)
+{
+ if (s[0] == 'P' && s[1] == 'C')
+ return 1;
+ return 0;
+}
+
+static int asm_parse_mode(TCHAR *s, uae_u8 *reg, uae_u32 *v, uae_u16 *ext)
+{
+ TCHAR *ss = s;
+ *reg = -1;
+ *v = 0;
+ *ext = 0;
+ if (s[0] == 0)
+ return -1;
+ // Dn
+ if (asm_isdreg(s) >= 0 && s[2] == 0) {
+ *reg = asm_isdreg(s);
+ return Dreg;
+ }
+ // An
+ if (asm_isareg(s) >= 0 && s[2] == 0) {
+ *reg = asm_isareg(s);
+ return Areg;
+ }
+ // (An) and (An)+
+ if (s[0] == '(' && asm_isareg(s + 1) >= 0 && s[3] == ')') {
+ *reg = asm_isareg(s + 1);
+ if (s[4] == '+' && s[5] == 0)
+ return Aipi;
+ if (s[4] == 0)
+ return Aind;
+ return -1;
+ }
+ // -(An)
+ if (s[0] == '-' && s[1] == '(' && asm_isareg(s + 2) >= 0 && s[4] == ')' && s[5] == 0) {
+ *reg = asm_isareg(s + 2);
+ return Apdi;
+ }
+ // Immediate
+ if (s[0] == '#') {
+ if (s[1] == '!') {
+ *v = _tstol(s + 2);
+ } else {
+ TCHAR *endptr;
+ *v = _tcstol(s + 1, &endptr, 16);
+ }
+ return imm;
+ }
+ // Value
+ if (s[0] == '!') {
+ *v = _tstol(s + 1);
+ } else {
+ TCHAR *endptr;
+ *v = _tcstol(s, &endptr, 16);
+ }
+ int dots = 0;
+ for (int i = 0; i < _tcslen(s); i++) {
+ if (s[i] == ',')
+ dots++;
+ }
+ while (*s != 0) {
+ // d16(An)
+ if (dots == 0 && s[0] == '(' && asm_isareg(s + 1) >= 0 && s[3] == ')' && s[4] == 0) {
+ *reg = asm_isareg(s + 1);
+ return Ad16;
+ }
+ // d16(PC)
+ if (dots == 0 && s[0] == '(' && asm_ispc(s + 1) && s[3] == ')' && s[4] == 0) {
+ *reg = 2;
+ return PC16;
+ }
+ // (d16,An) / (d16,PC)
+ if (dots == 1 && s[0] == '(' && !asm_ispc(s + 1) && asm_isareg(s + 1) < 0 && asm_isdreg(s + 1) < 0) {
+ TCHAR *startptr, *endptr;
+ if (s[1] == '!') {
+ startptr = s + 2;
+ *v = _tcstol(startptr, &endptr, 10);
+ } else {
+ startptr = s + 1;
+ *v = _tcstol(startptr, &endptr, 16);
+ }
+ if (endptr == startptr || endptr[0] != ',')
+ return -1;
+ if (asm_ispc(endptr + 1) && endptr[3] == ')') {
+ *reg = 2;
+ return PC16;
+ }
+ if (asm_isareg(endptr + 1) >= 0 && endptr[3] == ')') {
+ *reg = asm_isareg(endptr + 1);
+ return Ad16;
+ }
+ return -1;
+ }
+ // Ad8r PC8r
+ if (s[0] == '(') {
+ TCHAR *s2 = s;
+ if (!asm_ispc(s + 1) && asm_isareg(s + 1) < 0 && asm_isdreg(s + 1) < 0) {
+ if (dots != 2)
+ return -1;
+ TCHAR *startptr, *endptr;
+ if (s[1] == '!') {
+ startptr = s + 2;
+ *v = _tcstol(startptr, &endptr, 10);
+ } else {
+ startptr = s + 1;
+ *v = _tcstol(startptr, &endptr, 16);
+ }
+ if (endptr == startptr || endptr[0] != ',')
+ return -1;
+ s2 = endptr + 1;
+ } else if ((asm_isareg(s + 1) >= 0 || asm_ispc(s + 1)) && s[3] == ',' || (asm_isdreg(s + 4) >= 0 || asm_isareg(s + 4) >= 0)) {
+ if (dots != 1)
+ return -1;
+ s2 = s + 1;
+ } else {
+ return -1;
+ }
+ uae_u8 reg2;
+ bool ispc = asm_ispc(s2);
+ if (ispc) {
+ *reg = 3;
+ } else {
+ *reg = asm_isareg(s2);
+ }
+ s2 += 2;
+ if (*s2 != ',')
+ return -1;
+ s2++;
+ if (asm_isdreg(s2) >= 0) {
+ reg2 = asm_isdreg(s2);
+ } else {
+ reg2 = asm_isareg(s2);
+ *ext |= 1 << 15;
+ }
+ s2 += 2;
+ *ext |= reg2 << 12;
+ *ext |= (*v) & 0xff;
+ if (s2[0] == '.' && s2[1] == 'W') {
+ s2 += 2;
+ } else if (s2[0] == '.' && s2[1] == 'L') {
+ *ext |= 1 << 11;
+ s2 += 2;
+ }
+ if (s2[0] == '*') {
+ TCHAR scale = s2[1];
+ if (scale == '2')
+ *ext |= 1 << 9;
+ else if (scale == '4')
+ *ext |= 2 << 9;
+ else if (scale == '8')
+ *ext |= 3 << 9;
+ else
+ return -1;
+ s2 += 2;
+ }
+ if (s2[0] == ')' && s2[1] == 0) {
+ return ispc ? PC8r : Ad8r;
+ }
+ return -1;
+ }
+ s++;
+ }
+ // abs.w
+ if (s - ss > 2 && s[-2] == '.' && s[-1] == 'W') {
+ *reg = 0;
+ return absw;
+ }
+ // abs.l
+ *reg = 1;
+ return absl;
+}
+
+static TCHAR *asm_parse_parm(TCHAR *parm, TCHAR *out)
+{
+ TCHAR *p = parm;
+ bool quote = false;
+
+ for (;;) {
+ if (*p == '(') {
+ quote = true;
+ }
+ if (*p == ')') {
+ if (!quote)
+ return NULL;
+ quote = false;
+ }
+ if ((*p == ',' || *p == 0) && !quote) {
+ TCHAR c = *p;
+ p[0] = 0;
+ _tcscpy(out, parm);
+ my_trim(out);
+ if (c)
+ p++;
+ return p;
+ }
+ p++;
+ }
+}
+
+static bool m68k_asm_parse_movec(TCHAR *s, TCHAR *d)
+{
+ for (int i = 0; m2cregs[i].regname; i++) {
+ if (!_tcscmp(s, m2cregs[i].regname)) {
+ uae_u16 v = m2cregs[i].regno;
+ if (asm_isareg(d) >= 0)
+ v |= 0x8000 | (asm_isareg(d) << 12);
+ else if (asm_isdreg(d) >= 0)
+ v |= (asm_isdreg(d) << 12);
+ else
+ return false;
+ _stprintf(s, _T("#%X"), v);
+ return true;
+ }
+ }
+ return false;
+}
+
+static bool m68k_asm_parse_movem(TCHAR *s, int dir)
+{
+ TCHAR *d = s;
+ uae_u16 regmask = 0;
+ uae_u16 mask = dir ? 0x8000 : 0x0001;
+ bool ret = false;
+ while(*s) {
+ int dreg = asm_isdreg(s);
+ int areg = asm_isareg(s);
+ if (dreg < 0 && areg < 0)
+ break;
+ int reg = dreg >= 0 ? dreg : areg + 8;
+ regmask |= dir ? (mask >> reg) : (mask << reg);
+ s += 2;
+ if (*s == 0) {
+ ret = true;
+ break;
+ } else if (*s == '/') {
+ s++;
+ continue;
+ } else if (*s == '-') {
+ s++;
+ int dreg2 = asm_isdreg(s);
+ int areg2 = asm_isareg(s);
+ if (dreg2 < 0 && areg2 < 0)
+ break;
+ int reg2 = dreg2 >= 0 ? dreg2 : areg2 + 8;
+ if (reg2 < reg)
+ break;
+ while (reg2 >= reg) {
+ regmask |= dir ? (mask >> reg) : (mask << reg);
+ reg++;
+ }
+ s += 2;
+ if (*s == 0) {
+ ret = true;
+ break;
+ }
+ } else {
+ break;
+ }
+ }
+ if (ret)
+ _stprintf(d, _T("#%X"), regmask);
+ return ret;
+}
+
+int m68k_asm(TCHAR *sline, uae_u16 *out, uaecptr pc)
+{
+ TCHAR *p;
+ const TCHAR *cp1;
+ TCHAR ins[256], parms[256];
+ TCHAR line[256];
+ TCHAR srcea[256], dstea[256];
+ uae_u16 data[16], sexts[8], dexts[8];
+ int dcnt = 0;
+ int cc = -1;
+ int quick = 0;
+ bool immrelpc = false;
+
+ if (_tcslen(sline) > 100)
+ return -1;
+
+ srcea[0] = dstea[0] = 0;
+ parms[0] = 0;
+
+ // strip all white space except first space
+ p = line;
+ bool firstsp = true;
+ for (int i = 0; sline[i]; i++) {
+ TCHAR c = sline[i];
+ if (c == 32 && firstsp) {
+ firstsp = false;
+ *p++ = 32;
+ }
+ if (c <= 32)
+ continue;
+ *p++ = c;
+ }
+ *p = 0;
+
+ to_upper(line, _tcslen(line));
+
+ p = line;
+ while (*p && *p != ' ')
+ p++;
+ if (*p == ' ') {
+ *p = 0;
+ _tcscpy(parms, p + 1);
+ my_trim(parms);
+ }
+ _tcscpy(ins, line);
+
+ if (_tcslen(ins) == 0)
+ return 0;
+
+ int size = 1;
+ int inssize = -1;
+ cp1 = _tcschr(line, '.');
+ if (cp1) {
+ size = cp1[1];
+ if (size == 'W')
+ size = 1;
+ else if (size == 'L')
+ size = 2;
+ else if (size == 'B')
+ size = 0;
+ else
+ return 0;
+ inssize = size;
+ line[cp1 - line] = 0;
+ _tcscpy(ins, line);
+ }
+
+ TCHAR *parmp = parms;
+ parmp = asm_parse_parm(parmp, srcea);
+ if (!parmp)
+ return 0;
+ if (srcea[0]) {
+ parmp = asm_parse_parm(parmp, dstea);
+ if (!parmp)
+ return 0;
+ }
+
+ int smode = -1;
+ int dmode = -1;
+ uae_u8 sreg = -1;
+ uae_u8 dreg = -1;
+ uae_u32 sval = 0;
+ uae_u32 dval = 0;
+ int ssize = -1;
+ int dsize = -1;
+
+ dmode = asm_parse_mode(dstea, &dreg, &dval, dexts);
+
+
+ // Common alias
+ if (!_tcscmp(ins, _T("BRA"))) {
+ _tcscpy(ins, _T("BT"));
+ } else if (!_tcscmp(ins, _T("MOVEM"))) {
+ if (dmode >= Aind && _tcschr(dstea, '-') == NULL && _tcschr(dstea, '/') == NULL) {
+ _tcscpy(ins, _T("MVMLE"));
+ if (!m68k_asm_parse_movem(srcea, dmode == Apdi))
+ return -1;
+ } else {
+ TCHAR tmp[256];
+ _tcscpy(ins, _T("MVMEL"));
+ _tcscpy(tmp, srcea);
+ _tcscpy(srcea, dstea);
+ _tcscpy(dstea, tmp);
+ if (!m68k_asm_parse_movem(srcea, 0))
+ return -1;
+ dmode = asm_parse_mode(dstea, &dreg, &dval, dexts);
+ }
+ } else if (!_tcscmp(ins, _T("MOVEC"))) {
+ if (dmode == Dreg || dmode == Areg) {
+ _tcscpy(ins, _T("MOVEC2"));
+ if (!m68k_asm_parse_movec(srcea, dstea))
+ return -1;
+ } else {
+ TCHAR tmp[256];
+ _tcscpy(ins, _T("MOVE2C"));
+ _tcscpy(tmp, srcea);
+ _tcscpy(srcea, dstea);
+ dstea[0] = 0;
+ if (!m68k_asm_parse_movec(srcea, tmp))
+ return -1;
+ }
+ dmode = -1;
+ }
+
+ if (dmode == Areg) {
+ int l = _tcslen(ins);
+ if (l <= 2)
+ return -1;
+ TCHAR last = ins[l- 1];
+ if (last == 'Q') {
+ last = ins[l - 2];
+ if (last != 'A') {
+ ins[l - 1] = 'A';
+ ins[l] = 'Q';
+ ins[l + 1] = 0;
+ }
+ } else if (last != 'A') {
+ _tcscat(ins, _T("A"));
+ }
+ }
+
+ if (ins[_tcslen(ins) - 1] == 'Q') {
+ quick = 1;
+ ins[_tcslen(ins) - 1] = 0;
+ }
+
+ struct mnemolookup *lookup;
+ for (lookup = lookuptab; lookup->name; lookup++) {
+ if (!_tcscmp(ins, lookup->name))
+ break;
+ }
+ if (!lookup->name) {
+ // Check cc variants
+ bool fp = ins[0] == 'F';
+ for (lookup = lookuptab; lookup->name; lookup++) {
+ const TCHAR *ccp = _tcsstr(lookup->name, _T("cc"));
+ if (ccp) {
+ TCHAR tmp[256];
+ for (int i = 0; i < (fp ? 32 : 16); i++) {
+ const TCHAR *ccname = fp ? fpccnames[i] : ccnames[i];
+ _tcscpy(tmp, lookup->name);
+ _tcscpy(tmp + (ccp - lookup->name), ccname);
+ if (tmp[_tcslen(tmp) - 1] == ' ')
+ tmp[_tcslen(tmp) - 1] = 0;
+ if (!_tcscmp(tmp, ins)) {
+ _tcscpy(ins, lookup->name);
+ cc = i;
+ // Bcc.B uses same encoding mode as MOVEQ
+ if (size == 0) {
+ quick = 2;
+ }
+ immrelpc = true;
+ break;
+ }
+ }
+ }
+ if (cc >= 0)
+ break;
+ }
+ }
+
+ if (!lookup->name)
+ return 0;
+
+ int mnemo = lookup->mnemo;
+
+ int found = 0;
+ int sizemask = 0;
+ int tsize = size;
+ int unsized = 0;
+
+ for (int round = 0; round < 9; round++) {
+
+ if (!found && round == 8)
+ return 0;
+
+ if (round == 3) {
+ // Q is always LONG sized
+ if (quick == 1) {
+ tsize = 2;
+ }
+ bool isimm = srcea[0] == '#';
+ if (immrelpc && !isimm) {
+ TCHAR tmp[256];
+ _tcscpy(tmp, srcea);
+ srcea[0] = '#';
+ _tcscpy(srcea + 1, tmp);
+ }
+ smode = asm_parse_mode(srcea, &sreg, &sval, sexts);
+ if (immrelpc && !isimm) {
+ sval = sval - (pc + 2);
+ }
+ if (quick) {
+ smode = immi;
+ sreg = sval & 0xff;
+ }
+ }
+
+ if (round == 1) {
+ if (!quick && (sizemask == 1 || sizemask == 2 || sizemask == 4)) {
+ tsize = 0;
+ if (sizemask == 2)
+ tsize = 1;
+ else if (sizemask == 4)
+ tsize = 2;
+ } else {
+ continue;
+ }
+ }
+ if (round == 2 && !found) {
+ unsized = 1;
+ }
+
+ if (round == 4 && smode == imm) {
+ smode = imm0;
+ } else if (round == 5 && smode == imm0) {
+ smode = imm1;
+ } else if (round == 6 && smode == imm1) {
+ smode = imm2;
+ } else if (round == 7 && smode == imm2) {
+ smode = immi;
+ sreg = sval & 0xff;
+ } else if (round == 4) {
+ round += 5 - 1;
+ }
+
+ for (int opcode = 0; opcode < 65536; opcode++) {
+ struct instr *table = &table68k[opcode];
+ if (table->mnemo != mnemo)
+ continue;
+ if (cc >= 0 && table->cc != cc)
+ continue;
+
+#if 0
+ if (round == 0) {
+ console_out_f(_T("%s OP=%04x S=%d SR=%d SM=%d SU=%d SP=%d DR=%d DM=%d DU=%d DP=%d SDU=%d\n"), lookup->name, opcode, table->size,
+ table->sreg, table->smode, table->suse, table->spos,
+ table->dreg, table->dmode, table->duse, table->dpos,
+ table->sduse);
+ }
+#endif
+
+ if (table->duse && !(table->dmode == dmode || (dmode >= imm && dmode <= imm2 && table->dmode >= imm && table->dmode <= imm2)))
+ continue;
+ if (round == 0) {
+ sizemask |= 1 << table->size;
+ }
+ if (unsized > 0 && !table->unsized) {
+ continue;
+ }
+
+ found++;
+
+ if (round >= 3) {
+
+ if (
+ ((table->size == tsize || table->unsized)) &&
+ ((!table->suse && smode < 0) || (table->suse && table->smode == smode)) &&
+ ((!table->duse && dmode < 0) || (table->duse && (table->dmode == dmode || (dmode == imm && (table->dmode >= imm && table->dmode <= imm2))))) &&
+ ((table->sreg == sreg || (table->smode >= absw && table->smode != immi))) &&
+ ((table->dreg == dreg || table->dmode >= absw))
+ )
+ {
+ if (inssize >= 0 && tsize != inssize)
+ continue;
+
+
+ data[dcnt++] = opcode;
+ asm_add_extensions(data, &dcnt, smode, sval, sexts, pc, tsize);
+ if (smode >= 0)
+ asm_add_extensions(data, &dcnt, dmode, dval, dexts, pc, tsize);
+ for (int i = 0; i < dcnt; i++) {
+ out[i] = data[i];
+ }
+ return dcnt;
+ }
+
+ }
+ }
+ }
+
+ return 0;
+}
+
void m68k_disasm_2 (TCHAR *buf, int bufsize, uaecptr pc, uaecptr *nextpc, int cnt, uae_u32 *seaddr, uae_u32 *deaddr, int safemode)
{
uae_u32 seaddr2;