X-Git-Url: http://shamusworld.gotdns.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Fm68000%2Fm68kdasm.c;h=ab31cdb7bbb0fafd0a369adfe2d3ebfa9826cbaa;hb=b4975cbd28c54b5a8f5d7a119375fe05b46f19a1;hp=3c54b67b76e725b5d41d76095dcc155f20064cbe;hpb=2d556a3eb52664e928014a72ad18edc13281de7e;p=virtualjaguar diff --git a/src/m68000/m68kdasm.c b/src/m68000/m68kdasm.c index 3c54b67..ab31cdb 100644 --- a/src/m68000/m68kdasm.c +++ b/src/m68000/m68kdasm.c @@ -21,6 +21,9 @@ 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; @@ -35,7 +38,8 @@ 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; @@ -66,7 +70,7 @@ int32_t ShowEA(FILE * f, int reg, amodes mode, wordsizes size, char * buf) 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: @@ -100,7 +104,7 @@ int32_t ShowEA(FILE * f, int reg, amodes mode, wordsizes size, char * buf) 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); @@ -108,7 +112,7 @@ int32_t ShowEA(FILE * f, int reg, amodes mode, wordsizes size, char * buf) 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); } @@ -117,7 +121,7 @@ int32_t ShowEA(FILE * f, int reg, amodes mode, wordsizes size, char * buf) 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; @@ -160,39 +164,39 @@ int32_t ShowEA(FILE * f, int reg, amodes mode, wordsizes size, char * buf) 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: @@ -202,41 +206,124 @@ int32_t ShowEA(FILE * f, int reg, amodes mode, wordsizes size, char * buf) 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[] = - { "T ","F ","HI","LS","CC","CS","NE","EQ", + { "RA","RN","HI","LS","CC","CS","NE","EQ", "VC","VS","PL","MI","GE","LT","GT","LE" }; str[0] = 0; @@ -245,113 +332,67 @@ unsigned int m68k_disasm(char * output, uint32_t addr, uint32_t * nextpc, int cn 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; - dp = table68k + opcode; + struct instr * dp = table68k + opcode; - for(lookup=lookuptab; lookup->mnemo!=dp->mnemo; lookup++) - ; + for(lookup=lookuptab; lookup->mnemo!=dp->mnemo; lookup++) + ; - strcpy(instrname, lookup->name); - ccpt = strstr(instrname, "cc"); + strcpy(instrname, lookup->name); + char * ccpt = strstr(instrname, "cc"); - if (ccpt != 0) - { - strncpy(ccpt, ccnames[dp->cc], 2); - } + if (ccpt) + 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 "); break; - case sz_word: strcat(str, ".W "); break; - case sz_long: strcat(str, ".L "); break; - default: strcat(str, " "); 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++) @@ -369,10 +410,12 @@ unsigned int m68k_disasm(char * output, uint32_t addr, uint32_t * nextpc, int cn return numberOfBytes; } + // -// 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); } +