extern unsigned long IllegalOpcode(uint32_t opcode);
extern cpuop_func * cpuFunctionTable[65536];
+// Prototypes
+void HandleMovem(char * output, uint16_t data, int direction);
+
// Local "global" variables
static long int m68kpc_offset;
#endif
-int32_t ShowEA(FILE * f, int reg, amodes mode, wordsizes size, char * buf)
+//int32_t ShowEA(FILE * f, int reg, amodes mode, wordsizes size, char * buf)
+int32_t ShowEA(int mnemonic, int reg, amodes mode, wordsizes size, char * buf)
{
uint16_t dp;
int8_t disp8;
case Ad16:
disp16 = get_iword_1(m68kpc_offset); m68kpc_offset += 2;
addr = m68k_areg(regs,reg) + (int16_t)disp16;
- sprintf(buffer,"(A%d,$%04X) == $%08lX", reg, disp16 & 0xFFFF,
+ sprintf(buffer,"(A%d,$%X) == $%lX", reg, disp16 & 0xFFFF,
(unsigned long)addr);
break;
case Ad8r:
if (dp & 4) base += dispreg;
addr = base + outer;
- sprintf(buffer,"(%s%c%d.%c*%d+%ld)+%ld == $%08lX", name,
+ sprintf(buffer,"(%s%c%d.%c*%d+%ld)+%ld == $%lX", name,
dp & 0x8000 ? 'A' : 'D', (int)r, dp & 0x800 ? 'L' : 'W',
1 << ((dp >> 9) & 3),
(long)disp, (long)outer, (unsigned long)addr);
else
{
addr = m68k_areg(regs,reg) + (int32_t)((int8_t)disp8) + dispreg;
- sprintf (buffer,"(A%d, %c%d.%c*%d, $%02X) == $%08lX", reg,
+ sprintf (buffer,"(A%d, %c%d.%c*%d, $%X) == $%lX", reg,
dp & 0x8000 ? 'A' : 'D', (int)r, dp & 0x800 ? 'L' : 'W',
1 << ((dp >> 9) & 3), disp8, (unsigned long)addr);
}
addr = m68k_getpc() + m68kpc_offset;
disp16 = get_iword_1(m68kpc_offset); m68kpc_offset += 2;
addr += (int16_t)disp16;
- sprintf(buffer,"(PC,$%04X) == $%08lX", disp16 & 0xffff,(unsigned long)addr);
+ sprintf(buffer,"(PC, $%X) == $%lX", disp16 & 0xFFFF, (unsigned long)addr);
break;
case PC8r:
addr = m68k_getpc() + m68kpc_offset;
if (dp & 4) base += dispreg;
addr = base + outer;
- sprintf(buffer,"(%s%c%d.%c*%d+%ld)+%ld == $%08lX", name,
+ sprintf(buffer,"(%s%c%d.%c*%d+%ld)+%ld == $%lX", name,
dp & 0x8000 ? 'A' : 'D', (int)r, dp & 0x800 ? 'L' : 'W',
1 << ((dp >> 9) & 3), (long)disp, (long)outer, (unsigned long)addr);
}
else
{
addr += (int32_t)((int8_t)disp8) + dispreg;
- sprintf(buffer,"(PC, %c%d.%c*%d, $%02X) == $%08lX", dp & 0x8000 ? 'A' : 'D',
+ sprintf(buffer,"(PC, %c%d.%c*%d, $%X) == $%lX", dp & 0x8000 ? 'A' : 'D',
(int)r, dp & 0x800 ? 'L' : 'W', 1 << ((dp >> 9) & 3),
disp8, (unsigned long)addr);
}
break;
case absw:
- sprintf(buffer,"$%08lX", (unsigned long)(int32_t)(int16_t)get_iword_1(m68kpc_offset));
+ sprintf(buffer,"$%lX", (unsigned long)(int32_t)(int16_t)get_iword_1(m68kpc_offset));
m68kpc_offset += 2;
break;
case absl:
- sprintf(buffer,"$%08lX", (unsigned long)get_ilong_1(m68kpc_offset));
+ sprintf(buffer,"$%lX", (unsigned long)get_ilong_1(m68kpc_offset));
m68kpc_offset += 4;
break;
case imm:
switch (size)
{
case sz_byte:
- sprintf(buffer,"#$%02X", (unsigned int)(get_iword_1(m68kpc_offset) & 0xFF));
+ sprintf(buffer,"#$%X", (unsigned int)(get_iword_1(m68kpc_offset) & 0xFF));
m68kpc_offset += 2;
break;
case sz_word:
- sprintf(buffer,"#$%04X", (unsigned int)(get_iword_1(m68kpc_offset) & 0xFFFF));
+ sprintf(buffer,"#$%X", (unsigned int)(get_iword_1(m68kpc_offset) & 0xFFFF));
m68kpc_offset += 2;
break;
case sz_long:
- sprintf(buffer,"#$%08lX", (unsigned long)(get_ilong_1(m68kpc_offset)));
+ sprintf(buffer,"#$%lX", (unsigned long)(get_ilong_1(m68kpc_offset)));
m68kpc_offset += 4;
break;
default:
case imm0:
offset = (int32_t)(int8_t)get_iword_1(m68kpc_offset);
m68kpc_offset += 2;
- sprintf (buffer,"#$%02X", (unsigned int)(offset & 0xFF));
+ sprintf(buffer,"#$%X", (unsigned int)(offset & 0xFF));
break;
case imm1:
offset = (int32_t)(int16_t)get_iword_1(m68kpc_offset);
m68kpc_offset += 2;
- sprintf (buffer,"#$%04X", (unsigned int)(offset & 0xFFFF));
+
+ if (mnemonic == i_MVMEL)
+ HandleMovem(buffer, offset, 0);
+ else if (mnemonic == i_MVMLE)
+ HandleMovem(buffer, offset, 1);
+ else
+ sprintf(buffer,"#$%X", (unsigned int)(offset & 0xFFFF));
+
break;
case imm2:
offset = (int32_t)get_ilong_1(m68kpc_offset);
m68kpc_offset += 4;
- sprintf(buffer,"#$%08lX", (unsigned long)offset);
+ sprintf(buffer,"#$%lX", (unsigned long)(offset & 0xFFFFFFFF));
break;
case immi:
offset = (int32_t)(int8_t)(reg & 0xFF);
- sprintf(buffer,"#$%08lX", (unsigned long)offset);
+ sprintf(buffer,"#$%lX", (unsigned long)(offset & 0xFFFFFFFF));
break;
default:
break;
}
- if (buf == 0)
- fprintf(f, "%s", buffer);
- else
- strcat(buf, buffer);
+// if (buf == 0)
+// fprintf(f, "%s", buffer);
+// else
+ strcat(buf, buffer);
return offset;
}
-//void m68k_disasm(FILE * f, uint32_t addr, uint32_t * nextpc, int cnt)
-unsigned int m68k_disasm(char * output, uint32_t addr, uint32_t * nextpc, int cnt)
+void HandleMovem(char * output, uint16_t data, int direction)
+{
+ uint16_t ascending[16] = {
+ 0x0001, 0x0002, 0x0004, 0x0008, 0x0010, 0x0020, 0x0040, 0x0080,
+ 0x0100, 0x0200, 0x0400, 0x0800, 0x1000, 0x2000, 0x4000, 0x8000 };
+ uint16_t descending[16] = {
+ 0x8000, 0x4000, 0x2000, 0x1000, 0x0800, 0x0400, 0x0200, 0x0100,
+ 0x0080, 0x0040, 0x0020, 0x0010, 0x0008, 0x0004, 0x0002, 0x0001 };
+
+ int i, j, first, runLength, firstPrint = 1;
+ char buf[16];
+ uint16_t * bitMask;
+
+ bitMask = (direction ? descending : ascending);
+ output[0] = 0;
+
+ // Handle D0-D7...
+ for(i=0; i<8; i++)
+ {
+ if (data & bitMask[i])
+ {
+ first = i;
+ runLength = 0;
+
+ for(j=i+1; j<8 && (data & bitMask[j]); j++)
+ runLength++;
+
+ i += runLength;
+
+ if (firstPrint)
+ firstPrint = 0;
+ else
+ strcat(output, "/");
+
+ sprintf(buf, "D%d", first);
+ strcat(output, buf);
+
+ if (runLength > 0)
+ {
+ sprintf(buf, "-D%d", first + runLength);
+ strcat(output, buf);
+ }
+ }
+ }
+
+ // Handle A0-A7...
+ for(i=0; i<8; i++)
+ {
+ if (data & bitMask[i + 8])
+ {
+ first = i;
+ runLength = 0;
+
+ for(j=i+1; j<8 && (data & bitMask[j+8]); j++)
+ runLength++;
+
+ i += runLength;
+
+ if (firstPrint)
+ firstPrint = 0;
+ else
+ strcat(output, "/");
+
+ sprintf(buf, "A%d", first);
+ strcat(output, buf);
+
+ if (runLength > 0)
+ {
+ sprintf(buf, "-A%d", first + runLength);
+ strcat(output, buf);
+ }
+ }
+ }
+}
+
+
+unsigned int M68KDisassemble(char * output, uint32_t addr)
{
char f[256], str[256];
+ char src[256], dst[256];
static const char * const ccnames[] =
{ "RA","RN","HI","LS","CC","CS","NE","EQ",
"VC","VS","PL","MI","GE","LT","GT","LE" };
m68kpc_offset = addr - m68k_getpc();
long int pcOffsetSave = m68kpc_offset;
int opwords;
+ char instrname[20];
+ const struct mnemolookup * lookup;
- while (cnt-- > 0)
- {
- char instrname[20], * ccpt;
- uint32_t opcode;
- const struct mnemolookup * lookup;
- struct instr * dp;
-// sprintf(f, "%06lX: ", m68k_getpc() + m68kpc_offset);
-// strcat(str, f);
+ uint32_t opcode = get_iword_1(m68kpc_offset);
+ m68kpc_offset += 2;
-#if 0
- for(opwords=0; opwords<5; opwords++)
- {
- sprintf(f, "%04X ", get_iword_1(m68kpc_offset + opwords * 2));
- strcat(str, f);
- }
-#endif
-
- opcode = get_iword_1(m68kpc_offset);
- m68kpc_offset += 2;
+ if (cpuFunctionTable[opcode] == IllegalOpcode)
+ opcode = 0x4AFC;
- if (cpuFunctionTable[opcode] == IllegalOpcode)
- {
- opcode = 0x4AFC;
- }
+ struct instr * dp = table68k + opcode;
- dp = table68k + opcode;
+ for(lookup=lookuptab; lookup->mnemo!=dp->mnemo; lookup++)
+ ;
- for(lookup=lookuptab; lookup->mnemo!=dp->mnemo; lookup++)
- ;
+ strcpy(instrname, lookup->name);
+ char * ccpt = strstr(instrname, "cc");
- strcpy(instrname, lookup->name);
- ccpt = strstr(instrname, "cc");
+ if (ccpt)
+ strncpy(ccpt, ccnames[dp->cc], 2);
- if (ccpt != 0)
- {
- strncpy(ccpt, ccnames[dp->cc], 2);
- }
+ sprintf(f, "%s", instrname);
+ strcat(str, f);
- sprintf(f, "%s", instrname);
- strcat(str, f);
-
-#if 0
- switch (dp->size)
- {
- case sz_byte: sprintf(f, ".B "); break;
- case sz_word: sprintf(f, ".W "); break;
- case sz_long: sprintf(f, ".L "); break;
- default: sprintf(f, " "); break;
- }
- strcat(str, f);
-#else
- switch (dp->size)
- {
- case sz_byte: strcat(str, ".B\t"); break;
- case sz_word: strcat(str, ".W\t"); break;
- case sz_long: strcat(str, ".L\t"); break;
- default: strcat(str, "\t"); break;
- }
-#endif
+ switch (dp->size)
+ {
+ case sz_byte: strcat(str, ".B\t"); break;
+ case sz_word: strcat(str, ".W\t"); break;
+ case sz_long: strcat(str, ".L\t"); break;
+ default: strcat(str, "\t"); break;
+ }
- if (dp->suse)
- {
- f[0] = 0;
- newpc = m68k_getpc() + m68kpc_offset;
- newpc += ShowEA(0, dp->sreg, dp->smode, dp->size, f);
- strcat(str, f);
- }
+ // Get source and destination operands (if any)
+ src[0] = dst[0] = f[0] = 0;
-#if 1
- if (dp->suse && dp->duse)
- {
-// sprintf(f, ",");
-// strcat(str, f);
- strcat(str, ", ");
- }
-#endif
+ if (dp->suse)
+ newpc = m68k_getpc() + m68kpc_offset
+ + ShowEA(dp->mnemo, dp->sreg, dp->smode, dp->size, src);
- if (dp->duse)
- {
- f[0] = 0;
- newpc = m68k_getpc() + m68kpc_offset;
- newpc += ShowEA(0, dp->dreg, dp->dmode, dp->size, f);
- strcat(str, f);
- }
+ if (dp->duse)
+ newpc = m68k_getpc() + m68kpc_offset
+ + ShowEA(dp->mnemo, dp->dreg, dp->dmode, dp->size, dst);
- if (ccpt != 0)
- {
- if (cctrue(dp->cc))
- sprintf(f, " == %08lX (TRUE)", (long)newpc);
- else
- sprintf(f, " == %08lX (FALSE)", (long)newpc);
+ // Handle execptions to the standard rules
+ if (dp->mnemo == i_BSR || dp->mnemo == i_Bcc)
+ sprintf(f, "$%lX", (long)newpc);
+ else if (dp->mnemo == i_DBcc)
+ sprintf(f, "%s, $%lX", src, (long)newpc);
+ else if (dp->mnemo == i_MVMEL)
+ sprintf(f, "%s, %s", dst, src);
+ else
+ sprintf(f, "%s%s%s", src, (dp->suse && dp->duse ? ", " : ""), dst);
- strcat(str, f);
- }
- else if ((opcode & 0xFF00) == 0x6100) // BSR
- {
- sprintf(f, " == %08lX", (long)newpc);
- strcat(str, f);
- }
+ strcat(str, f);
-// fprintf(f, "\n");
+ if (ccpt)
+ {
+ sprintf(f, " (%s)", (cctrue(dp->cc) ? "true" : "false"));
+ strcat(str, f);
}
-// if (nextpc)
-// *nextpc = m68k_getpc() + m68kpc_offset;
-
+ // Add byte(s) display to front of disassembly
long int numberOfBytes = m68kpc_offset - pcOffsetSave;
for(opwords=0; opwords<5; opwords++)
//
-// Disasemble one instruction at pc and store in str_buff
+// Disassemble one instruction at pc and store in str_buff
//
unsigned int m68k_disassemble(char * str_buff, unsigned int pc, unsigned int cpu_type)
{
- return m68k_disasm(str_buff, pc, 0, 1);
+ return M68KDisassemble(str_buff, pc);
}