--- hatari/src/debug/68kDisass.c 2019/04/09 08:53:05 1.1.1.4 +++ hatari/src/debug/68kDisass.c 2019/04/09 08:59:19 1.1.1.9 @@ -5,16 +5,19 @@ * or at your option any later version. Read the file gpl.txt for details. ***/ -#include +#include "main.h" #include -#include -#include +#if HAVE_STRINGS_H +# include +#endif -#include "config.h" #include "sysdeps.h" -#include "main.h" #include "configuration.h" #include "newcpu.h" +#include "stMemory.h" +#ifdef WINUAE_FOR_HATARI +#include "debug.h" +#endif #include "paths.h" #include "profile.h" #include "tos.h" @@ -27,7 +30,7 @@ typedef enum { doptNoBrackets = 1, // hide brackets around absolute addressing doptOpcodesSmall = 2, // opcodes are small letters doptRegisterSmall = 4, // register names are small letters - doptStackSP = 8, // stack pointer is named "SP" instead of "A7" (except for MOVEM) + doptStackSP = 8 // stack pointer is named "SP" instead of "A7" (except for MOVEM) } Diss68kOptions; static Diss68kOptions options = doptOpcodesSmall | doptRegisterSmall | doptStackSP | doptNoBrackets; @@ -37,7 +40,7 @@ static const Diss68kOptions optionsMask // values <0 will hide the group static int optionPosAddress = 0; // current address -static int optionPosHexdump = 10; // 16-bit words at this address +static int optionPosHexdump = 12; // 16-bit words at this address static int optionPosLabel = 35; // label, if defined static int optionPosOpcode = 47; // opcode static int optionPosOperand = 57; // operands for the opcode @@ -88,7 +91,7 @@ typedef enum { dtASCString, // a 0-byte terminated ASCII string dtPointer, // a generic 32-bit pointer dtFunctionPointer, // a 32-bit pointer to a function - dtStringArray, // a specific number of ASCII bytes + dtStringArray // a specific number of ASCII bytes } Disass68kDataType; typedef struct { @@ -124,7 +127,10 @@ static disSymbolEntry *disSymbolEntries; static inline unsigned short Disass68kGetWord(long addr) { - return get_word(addr); + if ( ! valid_address ( addr , 2 ) ) + return 0; + + return STMemory_ReadWord ( addr ); } // Load a text file into memory, count the lines and replace the LF with 0-bytes. @@ -132,28 +138,31 @@ static int Disass68kLoadTextFile(const { long index; long fileLength; - int lineCount; + int lineCount = 0; char *fbuf; FILE *f; if(filebuf) *filebuf = NULL; f = fopen(filename, "r"); - if(!f) return 0; - if(fseek(f, 0, SEEK_END)) + if (!f) return 0; + if (fseek(f, 0, SEEK_END)) + goto out; fileLength = ftell(f); - if(fileLength <= 0) return 0; - if(fseek(f, 0, SEEK_SET)) - return 0; + if (fileLength <= 0) + goto out; + if (fseek(f, 0, SEEK_SET)) + goto out; fbuf = malloc(fileLength); - if(!fbuf) return 0; + if(!fbuf) + goto out; if((size_t)fileLength != fread(fbuf, sizeof(char), fileLength, f)) { free(fbuf); - return 0; + goto out; } - lineCount = 0; + for(index=0; index= 0x0 && reg <= 0x7) + { + regName[0] = (options & doptRegisterSmall) ? 'd' : 'D'; } + else if (reg >= 0x8 && reg <= 0xf) + { + regName[0] = (options & doptRegisterSmall) ? 'a' : 'A'; + } + else + { + regName[0] = '?'; + } + + regName[1] = '0' + (reg & 7); + regName[2] = 0; + return regName; } @@ -485,10 +523,10 @@ static const char *Disass68kNumber(int v sprintf(numString, "%d", val); } else { // 4 characters/numbers or underscore (e.g. for cookies) - char c0 = (val >> 24) & 0xFF; - char c1 = (val >> 16) & 0xFF; - char c2 = (val >> 8) & 0xFF; - char c3 = (val >> 0) & 0xFF; + unsigned char c0 = (val >> 24) & 0xFF; + unsigned char c1 = (val >> 16) & 0xFF; + unsigned char c2 = (val >> 8) & 0xFF; + unsigned char c3 = (val >> 0) & 0xFF; if((isalnum(c0) || c0 == '_') && (isalnum(c1) || c1 == '_') && (isalnum(c2) || c2 == '_') && (isalnum(c3) || c3 == '_')) { sprintf(numString, "'%c%c%c%c'", c0, c1, c2, c3); @@ -588,7 +626,7 @@ static const char *Disass68kSpecialRegis char *bp; strcpy(buf, sp); for (bp = buf; *bp; ++bp) - *bp = tolower(*bp); + *bp = tolower((unsigned char)*bp); return buf; } return sp; @@ -633,8 +671,6 @@ static char *Disass68kEA(char *disassbu char regName[3]; signed long pcoffset; - val = 0; - disassbuf[0] = 0; switch(ea) { @@ -816,6 +852,7 @@ static char *Disass68kEA(char *disassbu case 3: bd = Disass68kGetWord(*addr); *addr += 2; bd <<= 16; + /* fall through */ case 2: bd |= Disass68kGetWord(*addr); *addr += 2; break; @@ -886,6 +923,7 @@ static char *Disass68kEA(char *disassbu case 3: od = Disass68kGetWord(*addr); *addr += 2; od <<= 16; + /* fall through */ case 2: od |= Disass68kGetWord(*addr); *addr += 2; if(prefixComma) @@ -1004,6 +1042,7 @@ static char *Disass68kEA(char *disassbu switch(size) { case 1: eWord1 &= 0xFF; + /* fall through */ case 2: #if USE_SYMBOLS if(disassFlag) @@ -1283,7 +1322,7 @@ typedef enum { ofFPUMOVE, ofFMOVECR, ofFPU3Reg, - ofLineA, + ofLineA } Disass68kOpcodeFormat; @@ -1301,7 +1340,7 @@ typedef const struct { int disassFlag; } OpcodeTableStruct; -static const OpcodeTableStruct OpcodeTable[] = { +static OpcodeTableStruct OpcodeTable[] = { { MC_ALL, {0xff00, 0x0000}, {-1,6,2,0}, {ofI,ofEa}, "ORI.?",{0,EA_Immed|EA_PCRel|EA_An}}, { MC_ALL, {0xf1c0, 0x0100}, {4}, {ofDestDn,ofEa}, "BTST",{0,EA_An|EA_Immed} }, { MC_ALL, {0xf1c0, 0x0140}, {4}, {ofDestDn,ofEa}, "BCHG",{0,EA_Immed|EA_PCRel|EA_An}}, @@ -1516,26 +1555,26 @@ static const OpcodeTableStruct OpcodeTab { MC_PMMU|MC68030, {0xffc0, 0xf000|(PMMU_COPROC_ID<<9), 0xffff, 0x0800}, {0}, {ofEa,ofSpecReg}, "PMOVE",{EA_Dn|EA_An|EA_Anip|EA_piAn|EA_Immed|EA_PCRel,REG_TT0} }, { MC_PMMU|MC68030, {0xffc0, 0xf000|(PMMU_COPROC_ID<<9), 0xffff, 0x0900}, {0}, {ofEa,ofSpecReg}, "PMOVEFD",{EA_Dn|EA_An|EA_Anip|EA_piAn|EA_Immed|EA_PCRel,REG_TT0} }, - { MC_PMMU|MC68030, {0xffc0, 0xf000|(PMMU_COPROC_ID<<9), 0xffff, 0x0B00}, {0}, {ofSpecReg,ofEa}, "PMOVEFD",{EA_Dn|EA_An|EA_Anip|EA_piAn|EA_Immed|EA_PCRel,REG_TT0} }, + { MC_PMMU|MC68030, {0xffc0, 0xf000|(PMMU_COPROC_ID<<9), 0xffff, 0x0B00}, {0}, {ofSpecReg,ofEa}, "PMOVEFD",{REG_TT0,EA_Dn|EA_An|EA_Anip|EA_piAn|EA_Immed|EA_PCRel} }, { MC_PMMU|MC68030, {0xffc0, 0xf000|(PMMU_COPROC_ID<<9), 0xffff, 0x0C00}, {0}, {ofEa,ofSpecReg}, "PMOVE",{EA_Dn|EA_An|EA_Anip|EA_piAn|EA_Immed|EA_PCRel,REG_TT1} }, - { MC_PMMU|MC68030, {0xffc0, 0xf000|(PMMU_COPROC_ID<<9), 0xffff, 0x0C00}, {0}, {ofSpecReg,ofEa}, "PMOVE",{EA_Dn|EA_An|EA_Anip|EA_piAn|EA_Immed|EA_PCRel,REG_TT0} }, + { MC_PMMU|MC68030, {0xffc0, 0xf000|(PMMU_COPROC_ID<<9), 0xffff, 0x0C00}, {0}, {ofSpecReg,ofEa}, "PMOVE",{REG_TT0,EA_Dn|EA_An|EA_Anip|EA_piAn|EA_Immed|EA_PCRel} }, { MC_PMMU|MC68030, {0xffc0, 0xf000|(PMMU_COPROC_ID<<9), 0xffff, 0x0D00}, {0}, {ofEa,ofSpecReg}, "PMOVEFD",{EA_Dn|EA_An|EA_Anip|EA_piAn|EA_Immed|EA_PCRel,REG_TT1} }, - { MC_PMMU|MC68030, {0xffc0, 0xf000|(PMMU_COPROC_ID<<9), 0xffff, 0x0E00}, {0}, {ofSpecReg,ofEa}, "PMOVE",{EA_Dn|EA_An|EA_Anip|EA_piAn|EA_Immed|EA_PCRel,REG_TT1} }, - { MC_PMMU|MC68030, {0xffc0, 0xf000|(PMMU_COPROC_ID<<9), 0xffff, 0x0F00}, {0}, {ofSpecReg,ofEa}, "PMOVEFD",{EA_Dn|EA_An|EA_Anip|EA_piAn|EA_Immed|EA_PCRel,REG_TT1} }, + { MC_PMMU|MC68030, {0xffc0, 0xf000|(PMMU_COPROC_ID<<9), 0xffff, 0x0E00}, {0}, {ofSpecReg,ofEa}, "PMOVE",{REG_TT1,EA_Dn|EA_An|EA_Anip|EA_piAn|EA_Immed|EA_PCRel} }, + { MC_PMMU|MC68030, {0xffc0, 0xf000|(PMMU_COPROC_ID<<9), 0xffff, 0x0F00}, {0}, {ofSpecReg,ofEa}, "PMOVEFD",{REG_TT1,EA_Dn|EA_An|EA_Anip|EA_piAn|EA_Immed|EA_PCRel} }, { MC_PMMU|MC68030, {0xffc0, 0xf000|(PMMU_COPROC_ID<<9), 0xffff, 0x4000}, {0}, {ofEa,ofSpecReg}, "PMOVE",{EA_Dn|EA_An|EA_Anip|EA_piAn|EA_Immed|EA_PCRel,REG_TC} }, { MC_PMMU|MC68030, {0xffc0, 0xf000|(PMMU_COPROC_ID<<9), 0xffff, 0x4100}, {0}, {ofEa,ofSpecReg}, "PMOVEFD",{EA_Dn|EA_An|EA_Anip|EA_piAn|EA_Immed|EA_PCRel,REG_TC} }, - { MC_PMMU|MC68030, {0xffc0, 0xf000|(PMMU_COPROC_ID<<9), 0xffff, 0x4200}, {0}, {ofSpecReg,ofEa}, "PMOVE",{EA_Dn|EA_An|EA_Anip|EA_piAn|EA_Immed|EA_PCRel,REG_TC} }, - { MC_PMMU|MC68030, {0xffc0, 0xf000|(PMMU_COPROC_ID<<9), 0xffff, 0x4300}, {0}, {ofSpecReg,ofEa}, "PMOVEFD",{EA_Dn|EA_An|EA_Anip|EA_piAn|EA_Immed|EA_PCRel,REG_TC} }, + { MC_PMMU|MC68030, {0xffc0, 0xf000|(PMMU_COPROC_ID<<9), 0xffff, 0x4200}, {0}, {ofSpecReg,ofEa}, "PMOVE",{REG_TC,EA_Dn|EA_An|EA_Anip|EA_piAn|EA_Immed|EA_PCRel} }, + { MC_PMMU|MC68030, {0xffc0, 0xf000|(PMMU_COPROC_ID<<9), 0xffff, 0x4300}, {0}, {ofSpecReg,ofEa}, "PMOVEFD",{REG_TC,EA_Dn|EA_An|EA_Anip|EA_piAn|EA_Immed|EA_PCRel} }, { MC_PMMU|MC68030, {0xffc0, 0xf000|(PMMU_COPROC_ID<<9), 0xffff, 0x4800}, {0}, {ofEa,ofSpecReg}, "PMOVE",{EA_Dn|EA_An|EA_Anip|EA_piAn|EA_Immed|EA_PCRel,REG_SRP} }, { MC_PMMU|MC68030, {0xffc0, 0xf000|(PMMU_COPROC_ID<<9), 0xffff, 0x4900}, {0}, {ofEa,ofSpecReg}, "PMOVEFD",{EA_Dn|EA_An|EA_Anip|EA_piAn|EA_Immed|EA_PCRel,REG_SRP} }, - { MC_PMMU|MC68030, {0xffc0, 0xf000|(PMMU_COPROC_ID<<9), 0xffff, 0x4A00}, {0}, {ofSpecReg,ofEa}, "PMOVE",{EA_Dn|EA_An|EA_Anip|EA_piAn|EA_Immed|EA_PCRel,REG_SRP} }, - { MC_PMMU|MC68030, {0xffc0, 0xf000|(PMMU_COPROC_ID<<9), 0xffff, 0x4B00}, {0}, {ofSpecReg,ofEa}, "PMOVEFD",{EA_Dn|EA_An|EA_Anip|EA_piAn|EA_Immed|EA_PCRel,REG_SRP} }, + { MC_PMMU|MC68030, {0xffc0, 0xf000|(PMMU_COPROC_ID<<9), 0xffff, 0x4A00}, {0}, {ofSpecReg,ofEa}, "PMOVE",{REG_SRP,EA_Dn|EA_An|EA_Anip|EA_piAn|EA_Immed|EA_PCRel,REG_SRP} }, + { MC_PMMU|MC68030, {0xffc0, 0xf000|(PMMU_COPROC_ID<<9), 0xffff, 0x4B00}, {0}, {ofSpecReg,ofEa}, "PMOVEFD",{REG_SRP,EA_Dn|EA_An|EA_Anip|EA_piAn|EA_Immed|EA_PCRel,REG_SRP} }, { MC_PMMU|MC68030, {0xffc0, 0xf000|(PMMU_COPROC_ID<<9), 0xffff, 0x4C00}, {0}, {ofEa,ofSpecReg}, "PMOVE",{EA_Dn|EA_An|EA_Anip|EA_piAn|EA_Immed|EA_PCRel,REG_CRP} }, { MC_PMMU|MC68030, {0xffc0, 0xf000|(PMMU_COPROC_ID<<9), 0xffff, 0x4D00}, {0}, {ofEa,ofSpecReg}, "PMOVEFD",{EA_Dn|EA_An|EA_Anip|EA_piAn|EA_Immed|EA_PCRel,REG_CRP} }, - { MC_PMMU|MC68030, {0xffc0, 0xf000|(PMMU_COPROC_ID<<9), 0xffff, 0x4e00}, {0}, {ofSpecReg,ofEa}, "PMOVE",{EA_Dn|EA_An|EA_Anip|EA_piAn|EA_Immed|EA_PCRel,REG_CRP} }, - { MC_PMMU|MC68030, {0xffc0, 0xf000|(PMMU_COPROC_ID<<9), 0xffff, 0x4f00}, {0}, {ofSpecReg,ofEa}, "PMOVEFD",{EA_Dn|EA_An|EA_Anip|EA_piAn|EA_Immed|EA_PCRel,REG_CRP} }, + { MC_PMMU|MC68030, {0xffc0, 0xf000|(PMMU_COPROC_ID<<9), 0xffff, 0x4e00}, {0}, {ofSpecReg,ofEa}, "PMOVE",{REG_CRP,EA_Dn|EA_An|EA_Anip|EA_piAn|EA_Immed|EA_PCRel} }, + { MC_PMMU|MC68030, {0xffc0, 0xf000|(PMMU_COPROC_ID<<9), 0xffff, 0x4f00}, {0}, {ofSpecReg,ofEa}, "PMOVEFD",{REG_CRP,EA_Dn|EA_An|EA_Anip|EA_piAn|EA_Immed|EA_PCRel} }, { MC_PMMU|MC68030, {0xffc0, 0xf000|(PMMU_COPROC_ID<<9), 0xffff, 0x6000}, {0}, {ofEa,ofSpecReg}, "PMOVE",{EA_Dn|EA_An|EA_Anip|EA_piAn|EA_Immed|EA_PCRel,REG_MMUSR} }, - { MC_PMMU|MC68030, {0xffc0, 0xf000|(PMMU_COPROC_ID<<9), 0xffff, 0x6200}, {0}, {ofSpecReg,ofEa}, "PMOVE",{EA_Dn|EA_An|EA_Anip|EA_piAn|EA_Immed|EA_PCRel,REG_MMUSR} }, + { MC_PMMU|MC68030, {0xffc0, 0xf000|(PMMU_COPROC_ID<<9), 0xffff, 0x6200}, {0}, {ofSpecReg,ofEa}, "PMOVE",{REG_MMUSR,EA_Dn|EA_An|EA_Anip|EA_piAn|EA_Immed|EA_PCRel} }, { MC_PMMU, {0xffc0, 0xf000|(PMMU_COPROC_ID<<9), 0xffff, 0x2800}, {0}, {ofSpecReg,ofEa}, "PVALID",{REG_VAL,EA_Dn|EA_An|EA_Anip|EA_piAn|EA_Immed|EA_PCRel} }, { MC_PMMU, {0xffc0, 0xf000|(PMMU_COPROC_ID<<9), 0xfff8, 0x2C00}, {0}, {ofExtRegA0,ofEa}, "PVALID",{0,EA_Dn|EA_An|EA_Anip|EA_piAn|EA_Immed|EA_PCRel} }, @@ -1720,7 +1759,6 @@ static const OpcodeTableStruct OpcodeTab static int Disass68k(long addr, char *labelBuffer, char *opcodeBuffer, char *operandBuffer, char *commentBuffer) { long baseAddr = addr; - int val; int i; int count = 0; char addressLabel[256]; @@ -1821,10 +1859,10 @@ static int Disass68k(long addr, char *la case dtASCString: { - int count = 1; - unsigned short val = Disass68kGetWord(addr+0); + unsigned short opcval = Disass68kGetWord(addr+0); + count = 1; strcpy(opcodeBuffer,"DC.B"); - if((val >> 8) == 0) + if ((opcval >> 8) == 0) { strcat(operandBuffer, "0"); } else { @@ -1861,13 +1899,14 @@ static int Disass68k(long addr, char *la case dtFunctionPointer: { const char *sp; + int val; val = (Disass68kGetWord(addr) << 16) | Disass68kGetWord(addr+2); sp = Disass68kSymbolName(val, 2); strcpy(opcodeBuffer,"DC.L"); if(sp) sprintf(operandBuffer,"%s", sp); else - sprintf(operandBuffer,"$%6.6x", val); + sprintf(operandBuffer,"$%8.8x", val); return 4; } @@ -1889,12 +1928,12 @@ more: while(1) { unsigned short opcode[5]; - unsigned int i; OpcodeTableStruct *ots = &OpcodeTable[index++]; int size; char sizeChar = 0; char *dbuf; int ea; + int maxop; if(ots->opcodeName == NULL) break; @@ -1996,7 +2035,7 @@ more: strcpy(buf, sp); sp = buf; for (bp = buf; *bp; ++bp) - *bp = tolower(*bp); + *bp = tolower((unsigned char)*bp); } strcpy(dbuf, sp); dbuf += strlen(sp); @@ -2007,7 +2046,7 @@ more: if(c == '?') // size mask c = sizeChar; if(options & doptOpcodesSmall) - c = tolower(c); + c = tolower((unsigned char)c); *dbuf++ = c; } *dbuf = 0; @@ -2015,9 +2054,11 @@ more: // Parse the EAs for all operands ea = opcode[0] & 0x3F; dbuf = operandBuffer; - for(i=0; i<(sizeof(ots->op)/sizeof(ots->op[0])); ++i) + + maxop = (int)(sizeof(ots->op)/sizeof(ots->op[0])); + for(i=0; iop[i]) { @@ -2406,7 +2447,7 @@ more: if(!dbuf) goto more; // does another operand follow => add separator - if(ots->op[i+1] != ofNone) + if ( (i+1op[i+1] != ofNone) ) *dbuf++ = ','; } return addr-baseAddr; @@ -2442,15 +2483,15 @@ static void Disass68k_loop (FILE *f, uae } while (cnt-- > 0) { - const int addrWidth = 6; // 6 on an ST, 8 on a TT + const int addrWidth = 8; // 6 on an ST (24 bit addressing), 8 on a TT (32 bit addressing) char lineBuffer[1024]; char addressBuffer[32]; char hexdumpBuffer[256]; - char labelBuffer[256]; + char labelBuffer[258]; char opcodeBuffer[64]; char operandBuffer[256]; - char commentBuffer[256]; + char commentBuffer[258]; int plen, len, j; len = Disass68k(addr, labelBuffer, opcodeBuffer, operandBuffer, commentBuffer); @@ -2496,11 +2537,8 @@ static void Disass68k_loop (FILE *f, uae } if (optionPosComment >= 0) { - float percentage; - Uint32 count, cycles, misses; - if (Profile_CpuAddressData(addr, &percentage, &count, &cycles, &misses)) + if (Profile_CpuAddressDataStr(commentBuffer, sizeof(commentBuffer), addr)) { - sprintf(commentBuffer, "%5.2f%% (%u, %u, %u)", percentage, count, cycles, misses); Disass68kComposeStr(lineBuffer, commentBuffer, optionPosComment+1, 0); } /* show comments only if profile data is missing */ @@ -2541,9 +2579,13 @@ Uint32 Disasm_GetNextPC(Uint32 pc) void Disasm (FILE *f, uaecptr addr, uaecptr *nextpc, int cnt) { if (ConfigureParams.Debugger.bDisasmUAE) - return m68k_disasm (f, addr, nextpc, cnt); +#ifdef WINUAE_FOR_HATARI + m68k_disasm_file (f, addr, nextpc, addr, cnt); +#else + m68k_disasm (f, addr, nextpc, cnt); +#endif else - return Disass68k_loop (f, addr, nextpc, cnt); + Disass68k_loop (f, addr, nextpc, cnt); } static void Disasm_CheckOptionEngine(void) @@ -2619,6 +2661,28 @@ int Disasm_GetOptions(void) } /** + * Set CPU and FPU mask used for disassembly (when changed from the UI or the options) + */ +void Disasm_SetCPUType(int CPU, int FPU, bool bMMU) +{ + switch (CPU) + { + case 0: optionCPUTypeMask = MC68000; break; + case 1: optionCPUTypeMask = MC68010; break; + case 2: optionCPUTypeMask = MC68020; break; + case 3: optionCPUTypeMask = MC68030; break; + case 4: optionCPUTypeMask = MC68040; break; + default: optionCPUTypeMask = MC68000; break; + } + + if (FPU != 0) + optionCPUTypeMask |= MC_FPU; + + if (bMMU) + optionCPUTypeMask |= MC_PMMU; +} + +/** * Parse disasm command line option argument * @return error string (""=silent 'error') or NULL for success. */ @@ -2648,7 +2712,7 @@ const char *Disasm_ParseOption(const cha assert(option[i].flag == (1 << i)); fprintf(stderr, "\t%d: %s\n", option[i].flag, option[i].desc); } - fprintf(stderr, "Current settings are:\n\t--disasm %s --disasm %d\n", + fprintf(stderr, "Current settings are:\n\t--disasm %s --disasm 0x%x\n", ConfigureParams.Debugger.bDisasmUAE ? "uae" : "ext", ConfigureParams.Debugger.nDisasmOptions); return ""; @@ -2666,9 +2730,14 @@ const char *Disasm_ParseOption(const cha ConfigureParams.Debugger.bDisasmUAE = false; return NULL; } - if (isdigit(*arg)) + if (isdigit((unsigned char)*arg)) { - int newopt = atoi(arg); + char *end; + int newopt = strtol(arg, &end, 0); + if (*end) + { + return "not a number"; + } if ((newopt|optionsMask) != optionsMask) { return "unknown flags in the bitmask";