--- hatari/src/debug/history.c 2019/04/09 08:54:22 1.1.1.3 +++ hatari/src/debug/history.c 2019/04/09 08:56:48 1.1.1.5 @@ -1,7 +1,7 @@ /* * Hatari - history.c * - * Copyright (C) 2011-2013 by Eero Tamminen + * Copyright (C) 2011-2014 by Eero Tamminen * * 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. @@ -11,13 +11,14 @@ const char History_fileid[] = "Hatari history.c : " __DATE__ " " __TIME__; #include - +#include #include "main.h" #include "debugui.h" #include "debug_priv.h" #include "dsp.h" #include "dsp_core.h" #include "evaluate.h" +#include "file.h" #include "history.h" #include "m68000.h" #include "68kDisass.h" @@ -62,6 +63,8 @@ static const char* History_ReasonStr(deb return "CPU steps"; case REASON_DSP_STEPS: return "DSP steps"; + case REASON_PROGRAM: + return "Program break"; case REASON_USER: return "User break"; default: @@ -155,11 +158,12 @@ void History_Mark(debug_reason_t reason) } /** - * Show collected CPU/DSP debugger/breakpoint history + * Output collected CPU/DSP debugger/breakpoint history */ -void History_Show(Uint32 count) +static Uint32 History_Output(Uint32 count, FILE *fp) { bool show_all; + Uint32 retval; int i; if (History.count > History.limit) { @@ -174,9 +178,10 @@ void History_Show(Uint32 count) } } if (count <= 0) { - fprintf(stderr, "No history items to show.\n"); - return; + fprintf(stderr, "No history items to show.\n"); + return 0; } + retval = count; i = History.idx; show_all = false; @@ -190,7 +195,7 @@ void History_Show(Uint32 count) i++; i %= History.limit; if (!History.item[i].valid) { - fprintf(stderr, "ERROR: invalid history item %d!", count); + fprintf(fp, "ERROR: invalid history item %d!", count); } if (History.item[i].shown && !show_all) { continue; @@ -199,15 +204,42 @@ void History_Show(Uint32 count) if (History.item[i].for_dsp) { Uint16 pc = History.item[i].pc.dsp; - DSP_DisasmAddress(stderr, pc, pc); + DSP_DisasmAddress(fp, pc, pc); } else { Uint32 dummy; - Disasm(stderr, History.item[i].pc.cpu, &dummy, 1); + Disasm(fp, History.item[i].pc.cpu, &dummy, 1); } if (History.item[i].reason != REASON_NONE) { - fprintf(stderr, "Debugger: *%s*\n", History_ReasonStr(History.item[i].reason)); + fprintf(fp, "Debugger: *%s*\n", History_ReasonStr(History.item[i].reason)); } } + return retval; +} + +/* History_Output() helper for "info" & "lock" commands */ +void History_Show(FILE *fp, Uint32 count) +{ + History_Output(count, fp); +} + +/* + * save all history to given file + */ +static void History_Save(const char *name) +{ + Uint32 count; + FILE *fp; + + if (File_Exists(name)) { + fprintf(stderr, "ERROR: file '%s' already exists!\n", name); + + } else if ((fp = fopen(name, "w"))) { + count = History_Output(0, fp); + fprintf(stderr, "%d history items saved to '%s'.\n", count, name); + fclose(fp); + } else { + fprintf(stderr, "ERROR: opening '%s' failed (%d).\n", name, errno); + } } /* @@ -215,8 +247,8 @@ void History_Show(Uint32 count) */ char *History_Match(const char *text, int state) { - static const char* cmds[] = { "cpu", "dsp", "off" }; - return DebugUI_MatchHelper(cmds, ARRAYSIZE(cmds), text, state); + static const char* cmds[] = { "cpu", "dsp", "off", "save" }; + return DebugUI_MatchHelper(cmds, ARRAY_SIZE(cmds), text, state); } /** @@ -259,10 +291,14 @@ int History_Parse(int nArgc, char *psArg History_Enable(HISTORY_TRACK_DSP, limit); return DEBUGGER_CMDDONE; } + if (nArgc == 3 && strcmp(psArgs[1], "save") == 0) { + History_Save(psArgs[2]); + return DEBUGGER_CMDDONE; + } fprintf(stderr, "History range is 1-\n"); return DebugUI_PrintCmdHelp(psArgs[0]); } - History_Show(count); + History_Show(stderr, count); return DEBUGGER_CMDDONE; }