--- hatari/src/debug/debugcpu.c 2019/04/09 08:50:20 1.1.1.3 +++ hatari/src/debug/debugcpu.c 2019/04/09 08:53:03 1.1.1.5 @@ -1,8 +1,8 @@ /* Hatari - debugcpu.c - This file is distributed under the GNU Public License, version 2 or at - your option any later version. Read the file gpl.txt for details. + This file is distributed under the GNU General Public License, version 2 + or at your option any later version. Read the file gpl.txt for details. debugcpu.c - function needed for the CPU debugging tasks like memory and register dumps. @@ -30,6 +30,9 @@ const char DebugCpu_fileid[] = "Hatari d #include "str.h" #include "symbols.h" #include "68kDisass.h" +#include "console.h" +#include "options.h" + #define MEMDUMP_COLS 16 /* memdump, number of bytes per row */ #define NON_PRINT_CHAR '.' /* character to display for non-printables */ @@ -139,24 +142,9 @@ static int DebugCpu_SaveBin(int nArgc, c */ static void DebugCpu_ShowAddressInfo(Uint32 addr) { - Uint32 count, cycles; - const char *symbol; - bool shown = false; - - symbol = Symbols_GetByCpuAddress(addr); + const char *symbol = Symbols_GetByCpuAddress(addr); if (symbol) - { - fprintf(debugOutput, "%s", symbol); - shown = true; - } - if (Profile_CpuAddressData(addr, &count, &cycles)) - { - fprintf(debugOutput, "%s%d/%d times/cycles", - (shown ? ", " : ""), count, cycles); - shown = true; - } - if (shown) - fprintf(debugOutput, ":\n"); + fprintf(debugOutput, "%s:\n", symbol); } /** @@ -207,7 +195,7 @@ int DebugCpu_DisAsm(int nArgc, char *psA for (insts = 0; insts < max_insts && disasm_addr < disasm_upper; insts++) { DebugCpu_ShowAddressInfo(disasm_addr); - Disasm(debugOutput, (uaecptr)disasm_addr, &nextpc, 1, DISASM_ENGINE_EXT); + Disasm(debugOutput, (uaecptr)disasm_addr, &nextpc, 1); disasm_addr = nextpc; } fflush(debugOutput); @@ -248,7 +236,7 @@ static char *DebugCpu_MatchRegister(cons /** - * Set address of the named register to given argument. + * Set address of the named 32-bit register to given argument. * Return register size in bits or zero for uknown register name. * Handles D0-7 data and A0-7 address registers, but not PC & SR * registers as they need to be accessed using UAE accessors. @@ -381,8 +369,7 @@ static int DebugCpu_BreakCond(int nArgc, */ static int DebugCpu_Profile(int nArgc, char *psArgs[]) { - Profile_Command(nArgc, psArgs, false); - return DEBUGGER_CMDDONE; + return Profile_Command(nArgc, psArgs, false); } @@ -507,6 +494,31 @@ static int DebugCpu_Continue(int nArgc, return DEBUGGER_END; } +/** + * Command: Single-step CPU + */ +static int DebugCpu_Step(int nArgc, char *psArgv[]) +{ + nCpuSteps = 1; + return DEBUGGER_END; +} + +/** + * Command: Step CPU, but proceed through subroutines + * Does this by temporary conditional breakpoint + */ +static int DebugCpu_Next(int nArgc, char *psArgv[]) +{ + char command[32]; + Uint32 nextpc = Disasm_GetNextPC(M68000_GetPC()); + sprintf(command, "pc=$%x :once :quiet\n", nextpc); + if (BreakCond_Command(command, false)) { + nCpuSteps = 0; /* using breakpoint, not steps */ + return DEBUGGER_END; + } + return DEBUGGER_CMDDONE; +} + /** * This function is called after each CPU instruction when debugging is enabled. @@ -517,25 +529,36 @@ void DebugCpu_Check(void) { Profile_CpuUpdate(); } - if (LOG_TRACE_LEVEL(TRACE_CPU_DISASM)) + if (LOG_TRACE_LEVEL((TRACE_CPU_DISASM|TRACE_CPU_SYMBOLS))) { DebugCpu_ShowAddressInfo(M68000_GetPC()); } if (nCpuActiveCBs) { if (BreakCond_MatchCpu()) + { DebugUI(REASON_CPU_BREAKPOINT); + /* make sure we don't decrease step count + * below, before even even getting out of here + */ + if (nCpuSteps) + nCpuSteps++; + } } if (nCpuSteps) { - nCpuSteps -= 1; + nCpuSteps--; if (nCpuSteps == 0) DebugUI(REASON_CPU_STEPS); } - if (bHistoryEnabled) + if (History_TrackCpu()) { History_AddCpu(); } + if (ConOutDevice != CONOUT_DEVICE_NONE) + { + Console_Check(); + } } /** @@ -548,7 +571,9 @@ void DebugCpu_SetDebugging(void) bCpuProfiling = Profile_CpuStart(); nCpuActiveCBs = BreakCond_BreakPointCount(false); - if (nCpuActiveCBs || nCpuSteps || bCpuProfiling || bHistoryEnabled) + if (nCpuActiveCBs || nCpuSteps || bCpuProfiling || History_TrackCpu() + || LOG_TRACE_LEVEL((TRACE_CPU_DISASM|TRACE_CPU_SYMBOLS)) + || ConOutDevice != CONOUT_DEVICE_NONE) M68000_SetSpecial(SPCFLAG_DEBUGGER); else M68000_UnsetSpecial(SPCFLAG_DEBUGGER); @@ -599,7 +624,7 @@ static const dbgcommand_t cpucommands[] "write bytes to memory", "address byte1 [byte2 ...]\n" "\tWrite bytes to a memory address, bytes are space separated\n" - "\thexadecimals.", + "\tvalues in current number base.", false }, { DebugCpu_LoadBin, NULL, "loadbin", "l", @@ -608,7 +633,7 @@ static const dbgcommand_t cpucommands[] "\tLoad the file into memory starting at
.", false }, { DebugCpu_SaveBin, NULL, - "savebin", "s", + "savebin", "", "save memory to a file", "filename address length\n" "\tSave the memory block at
with given to\n" @@ -619,6 +644,19 @@ static const dbgcommand_t cpucommands[] "load CPU symbols & their addresses", Symbols_Description, false }, + { DebugCpu_Step, NULL, + "step", "s", + "single-step CPU", + "\n" + "\tExecute next CPU instruction (equals 'c 1')", + false }, + { DebugCpu_Next, NULL, + "next", "n", + "step CPU, proceeding through subroutine calls", + "\n" + "\tLike the 'step' command as long as subroutine calls do not\n" + "\thappen. When they do, the call is treated as one instruction.", + false }, { DebugCpu_Continue, NULL, "cont", "c", "continue emulation / CPU single-stepping",