--- hatari/src/debug/debugcpu.c 2019/04/09 08:54:20 1.1.1.6 +++ hatari/src/debug/debugcpu.c 2019/04/09 08:58:02 1.1.1.9 @@ -11,6 +11,7 @@ const char DebugCpu_fileid[] = "Hatari d #include #include +#include #include "config.h" @@ -33,6 +34,7 @@ const char DebugCpu_fileid[] = "Hatari d #include "68kDisass.h" #include "console.h" #include "options.h" +#include "vars.h" #define MEMDUMP_COLS 16 /* memdump, number of bytes per row */ @@ -66,7 +68,6 @@ static int DebugCpu_LoadBin(int nArgc, c fprintf(stderr, "Invalid address!\n"); return DEBUGGER_CMDDONE; } - address &= 0x00FFFFFF; if ((fp = fopen(psArgs[1], "rb")) == NULL) { @@ -74,6 +75,12 @@ static int DebugCpu_LoadBin(int nArgc, c return DEBUGGER_CMDDONE; } + /* TODO: more efficient would be to: + * - check file size + * - verify that it fits into valid memory area + * - flush emulated CPU data cache + * - read file contents directly into memory + */ c = fgetc(fp); while (!feof(fp)) { @@ -108,7 +115,6 @@ static int DebugCpu_SaveBin(int nArgc, c fprintf(stderr, " Invalid address!\n"); return DEBUGGER_CMDDONE; } - address &= 0x00FFFFFF; if (!Eval_Number(psArgs[3], &bytes)) { @@ -138,12 +144,18 @@ static int DebugCpu_SaveBin(int nArgc, c /** * Check whether given address matches any CPU symbol and whether * there's profiling information available for it. If yes, show it. + * + * @return true if symbol was shown, false otherwise */ -static void DebugCpu_ShowAddressInfo(Uint32 addr) +static bool DebugCpu_ShowAddressInfo(Uint32 addr, FILE *fp) { - const char *symbol = Symbols_GetByCpuAddress(addr); + const char *symbol = Symbols_GetByCpuAddress(addr, SYMTYPE_ALL); if (symbol) - fprintf(debugOutput, "%s:\n", symbol); + { + fprintf(fp, "%s:\n", symbol); + return true; + } + return false; } /** @@ -152,7 +164,7 @@ static void DebugCpu_ShowAddressInfo(Uin int DebugCpu_DisAsm(int nArgc, char *psArgs[]) { Uint32 disasm_upper = 0; - int insts, max_insts; + int shown, lines = INT_MAX; uaecptr nextpc; if (nArgc > 1) @@ -167,7 +179,6 @@ int DebugCpu_DisAsm(int nArgc, char *psA break; case 1: /* range */ - disasm_upper &= 0x00FFFFFF; break; } } @@ -177,23 +188,19 @@ int DebugCpu_DisAsm(int nArgc, char *psA if(!disasm_addr) disasm_addr = M68000_GetPC(); } - disasm_addr &= 0x00FFFFFF; /* limit is topmost address or instruction count */ - if (disasm_upper) - { - max_insts = INT_MAX; - } - else + if (!disasm_upper) { - disasm_upper = 0x00FFFFFF; - max_insts = ConfigureParams.Debugger.nDisasmLines; + disasm_upper = 0xFFFFFFFF; + lines = DebugUI_GetPageLines(ConfigureParams.Debugger.nDisasmLines, 8); } /* output a range */ - for (insts = 0; insts < max_insts && disasm_addr < disasm_upper; insts++) + for (shown = 0; shown < lines && disasm_addr < disasm_upper; shown++) { - DebugCpu_ShowAddressInfo(disasm_addr); + if (DebugCpu_ShowAddressInfo(disasm_addr, debugOutput)) + shown++; Disasm(debugOutput, (uaecptr)disasm_addr, &nextpc, 1); disasm_addr = nextpc; } @@ -215,7 +222,7 @@ static char *DebugCpu_MatchRegister(cons "d0", "d1", "d2", "d3", "d4", "d5", "d6", "d7", "pc", "sr" }; - return DebugUI_MatchHelper(regs, ARRAYSIZE(regs), text, state); + return DebugUI_MatchHelper(regs, ARRAY_SIZE(regs), text, state); } @@ -272,7 +279,11 @@ int DebugCpu_Register(int nArgc, char *p { uaecptr nextpc; /* use the UAE function instead */ +#ifdef WINUAE_FOR_HATARI + m68k_dumpstate_file(debugOutput, &nextpc); +#else m68k_dumpstate(debugOutput, &nextpc); +#endif fflush(debugOutput); return DEBUGGER_CMDDONE; } @@ -381,17 +392,16 @@ int DebugCpu_MemDump(int nArgc, char *ps break; } } /* continue */ - memdump_addr &= 0x00FFFFFF; if (!memdump_upper) { - memdump_upper = memdump_addr + MEMDUMP_COLS * ConfigureParams.Debugger.nMemdumpLines; + int lines = DebugUI_GetPageLines(ConfigureParams.Debugger.nMemdumpLines, 8); + memdump_upper = memdump_addr + MEMDUMP_COLS * lines; } - memdump_upper &= 0x00FFFFFF; while (memdump_addr < memdump_upper) { - fprintf(debugOutput, "%6.6X: ", memdump_addr); /* print address */ + fprintf(debugOutput, "%8.8X: ", memdump_addr); /* print address */ for (i = 0; i < MEMDUMP_COLS; i++) /* print hex data */ fprintf(debugOutput, "%2.2x ", STMemory_ReadByte(memdump_addr++)); fprintf(debugOutput, " "); /* print ASCII data */ @@ -431,7 +441,6 @@ static int DebugCpu_MemWrite(int nArgc, return DEBUGGER_CMDDONE; } - write_addr &= 0x00FFFFFF; numBytes = 0; /* get bytes data */ @@ -497,7 +506,7 @@ static char *DebugCpu_MatchNext(const ch static const char* ntypes[] = { "branch", "exception", "exreturn", "return", "subcall", "subreturn" }; - return DebugUI_MatchHelper(ntypes, ARRAYSIZE(ntypes), text, state); + return DebugUI_MatchHelper(ntypes, ARRAY_SIZE(ntypes), text, state); } /** @@ -534,15 +543,25 @@ static int DebugCpu_Next(int nArgc, char Uint32 optype, nextpc; optype = DebugCpu_OpcodeType(); - /* can this instruction be stepped normally? */ - if (optype != CALL_SUBROUTINE && optype != CALL_EXCEPTION) + /* should this instruction be stepped normally, or is it + * - subroutine call + * - exception + * - loop branch backwards + */ + if (optype == CALL_SUBROUTINE || + optype == CALL_EXCEPTION || + (optype == CALL_BRANCH && + (STMemory_ReadWord(M68000_GetPC()) & 0xf0f8) == 0x50c8 && + (Sint16)STMemory_ReadWord(M68000_GetPC()+SIZE_WORD) < 0)) + { + nextpc = Disasm_GetNextPC(M68000_GetPC()); + sprintf(command, "pc=$%x :once :quiet\n", nextpc); + } + else { nCpuSteps = 1; return DEBUGGER_END; } - - nextpc = Disasm_GetNextPC(M68000_GetPC()); - sprintf(command, "pc=$%x :once :quiet\n", nextpc); } /* use breakpoint, not steps */ if (BreakCond_Command(command, false)) @@ -586,7 +605,7 @@ Uint32 DebugCpu_OpcodeType(void) /* TODO: fbcc, fdbcc */ if ((opcode & 0xf000) == 0x6000 || /* BRA / BCC */ (opcode & 0xffc0) == 0x4ec0 || /* JMP */ - (opcode & 0xf080) == 0x50c8) /* DBCC */ + (opcode & 0xf0f8) == 0x50c8) /* DBCC */ return CALL_BRANCH; return CALL_UNKNOWN; @@ -614,7 +633,16 @@ void DebugCpu_Check(void) } if (LOG_TRACE_LEVEL((TRACE_CPU_DISASM|TRACE_CPU_SYMBOLS))) { - DebugCpu_ShowAddressInfo(M68000_GetPC()); + DebugCpu_ShowAddressInfo(M68000_GetPC(), TraceFile); + } + if (LOG_TRACE_LEVEL(TRACE_CPU_REGS)) + { + uaecptr nextpc; +#ifdef WINUAE_FOR_HATARI + m68k_dumpstate_file(TraceFile, &nextpc); +#else + m68k_dumpstate(TraceFile, &nextpc); +#endif } if (nCpuActiveCBs) { @@ -652,10 +680,10 @@ void DebugCpu_Check(void) void DebugCpu_SetDebugging(void) { bCpuProfiling = Profile_CpuStart(); - nCpuActiveCBs = BreakCond_BreakPointCount(false); + nCpuActiveCBs = BreakCond_CpuBreakPointCount(); if (nCpuActiveCBs || nCpuSteps || bCpuProfiling || History_TrackCpu() - || LOG_TRACE_LEVEL((TRACE_CPU_DISASM|TRACE_CPU_SYMBOLS)) + || LOG_TRACE_LEVEL((TRACE_CPU_DISASM|TRACE_CPU_SYMBOLS|TRACE_CPU_REGS)) || ConOutDevice != CONOUT_DEVICE_NONE) { M68000_SetSpecial(SPCFLAG_DEBUGGER); @@ -675,7 +703,7 @@ static const dbgcommand_t cpucommands[] "set CPU PC address breakpoints", BreakAddr_Description, true }, - { DebugCpu_BreakCond, BreakCond_MatchCpuVariable, + { DebugCpu_BreakCond, Vars_MatchCpuVariable, "breakpoint", "b", "set/remove/list conditional CPU breakpoints", BreakCond_Description, @@ -771,7 +799,7 @@ int DebugCpu_Init(const dbgcommand_t **t disasm_addr = 0; *table = cpucommands; - return ARRAYSIZE(cpucommands); + return ARRAY_SIZE(cpucommands); } /**