summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu/debug
diff options
context:
space:
mode:
author therealmogminer@gmail.com <therealmogminer@gmail.com>2016-07-14 16:13:52 +0200
committer therealmogminer@gmail.com <therealmogminer@gmail.com>2016-07-14 16:13:52 +0200
commitc643372753b8e5823d2ff5b68475a6b60e0a672d (patch)
treebc66495d9ecdbf7f66ab086b897d39a80f576e70 /src/emu/debug
parentd3dd9f8f95c5ebca51a691c7a6bc915a75276fd8 (diff)
Make loop collation optional for debugger trace and traceover commands
Diffstat (limited to 'src/emu/debug')
-rw-r--r--src/emu/debug/debugcmd.cpp31
-rw-r--r--src/emu/debug/debugcmd.h3
-rw-r--r--src/emu/debug/debugcpu.cpp54
-rw-r--r--src/emu/debug/debugcpu.h5
-rw-r--r--src/emu/debug/debughlp.cpp47
5 files changed, 93 insertions, 47 deletions
diff --git a/src/emu/debug/debugcmd.cpp b/src/emu/debug/debugcmd.cpp
index bdfd4dbf826..ff734e9f65d 100644
--- a/src/emu/debug/debugcmd.cpp
+++ b/src/emu/debug/debugcmd.cpp
@@ -380,6 +380,30 @@ bool debugger_commands::validate_number_parameter(const char *param, UINT64 *res
/*-------------------------------------------------
+ validate_boolean_parameter - validates a
+ boolean parameter
+-------------------------------------------------*/
+
+bool debugger_commands::validate_boolean_parameter(const char *param, bool *result)
+{
+ /* nullptr parameter does nothing and returns no error */
+ if (param == nullptr)
+ return true;
+
+ /* evaluate the expression; success if no error */
+ bool is_true = (strcmp(param, "true") == 0 || strcmp(param, "TRUE") == 0 || strcmp(param, "1") == 0);
+ bool is_false = (strcmp(param, "false") == 0 || strcmp(param, "FALSE") == 0 || strcmp(param, "0") == 0);
+
+ if (!is_true && !is_false)
+ return false;
+
+ *result = is_true;
+
+ return true;
+}
+
+
+/*-------------------------------------------------
validate_cpu_parameter - validates a
parameter as a cpu
-------------------------------------------------*/
@@ -2444,6 +2468,7 @@ void debugger_commands::execute_dasm(int ref, int params, const char *param[])
void debugger_commands::execute_trace_internal(int ref, int params, const char *param[], bool trace_over)
{
const char *action = nullptr;
+ bool detect_loops = true;
device_t *cpu;
FILE *f = nullptr;
const char *mode;
@@ -2455,7 +2480,9 @@ void debugger_commands::execute_trace_internal(int ref, int params, const char *
/* validate parameters */
if (!validate_cpu_parameter((params > 1) ? param[1] : nullptr, &cpu))
return;
- if (!debug_command_parameter_command(action = param[2]))
+ if (!validate_boolean_parameter((params > 2) ? param[2] : nullptr, &detect_loops))
+ return;
+ if (!debug_command_parameter_command(action = param[3]))
return;
/* open the file */
@@ -2479,7 +2506,7 @@ void debugger_commands::execute_trace_internal(int ref, int params, const char *
}
/* do it */
- cpu->debug()->trace(f, trace_over, action);
+ cpu->debug()->trace(f, trace_over, detect_loops, action);
if (f)
m_console.printf("Tracing CPU '%s' to file %s\n", cpu->tag(), filename.c_str());
else
diff --git a/src/emu/debug/debugcmd.h b/src/emu/debug/debugcmd.h
index 7ecfc87958b..eae6fc611d3 100644
--- a/src/emu/debug/debugcmd.h
+++ b/src/emu/debug/debugcmd.h
@@ -25,6 +25,9 @@ class debugger_commands
public:
debugger_commands(running_machine& machine, debugger_cpu& cpu, debugger_console& console);
+ /* validates a parameter as a boolean value */
+ bool validate_boolean_parameter(const char *param, bool *result);
+
/* validates a parameter as a numeric value */
bool validate_number_parameter(const char *param, UINT64 *result);
diff --git a/src/emu/debug/debugcpu.cpp b/src/emu/debug/debugcpu.cpp
index d28a15bd79b..b9062d3894d 100644
--- a/src/emu/debug/debugcpu.cpp
+++ b/src/emu/debug/debugcpu.cpp
@@ -2637,14 +2637,14 @@ UINT32 device_debug::compute_opcode_crc32(offs_t pc) const
// trace - trace execution of a given device
//-------------------------------------------------
-void device_debug::trace(FILE *file, bool trace_over, const char *action)
+void device_debug::trace(FILE *file, bool trace_over, bool detect_loops, const char *action)
{
// delete any existing tracers
m_trace = nullptr;
// if we have a new file, make a new tracer
if (file != nullptr)
- m_trace = std::make_unique<tracer>(*this, *file, trace_over, action);
+ m_trace = std::make_unique<tracer>(*this, *file, trace_over, detect_loops, action);
}
@@ -3305,14 +3305,15 @@ bool device_debug::registerpoint::hit()
// tracer - constructor
//-------------------------------------------------
-device_debug::tracer::tracer(device_debug &debug, FILE &file, bool trace_over, const char *action)
- : m_debug(debug),
- m_file(file),
- m_action((action != nullptr) ? action : ""),
- m_loops(0),
- m_nextdex(0),
- m_trace_over(trace_over),
- m_trace_over_target(~0)
+device_debug::tracer::tracer(device_debug &debug, FILE &file, bool trace_over, bool detect_loops, const char *action)
+ : m_debug(debug)
+ , m_file(file)
+ , m_action((action != nullptr) ? action : "")
+ , m_detect_loops(detect_loops)
+ , m_loops(0)
+ , m_nextdex(0)
+ , m_trace_over(trace_over)
+ , m_trace_over_target(~0)
{
memset(m_history, 0, sizeof(m_history));
}
@@ -3344,23 +3345,26 @@ void device_debug::tracer::update(offs_t pc)
m_trace_over_target = ~0;
}
- // check for a loop condition
- int count = 0;
- for (auto & elem : m_history)
- if (elem == pc)
- count++;
-
- // if more than 1 hit, just up the loop count and get out
- if (count > 1)
+ if (m_detect_loops)
{
- m_loops++;
- return;
- }
+ // check for a loop condition
+ int count = 0;
+ for (auto & elem : m_history)
+ if (elem == pc)
+ count++;
+
+ // if more than 1 hit, just up the loop count and get out
+ if (count > 1)
+ {
+ m_loops++;
+ return;
+ }
- // if we just finished looping, indicate as much
- if (m_loops != 0)
- fprintf(&m_file, "\n (loops for %d instructions)\n\n", m_loops);
- m_loops = 0;
+ // if we just finished looping, indicate as much
+ if (m_loops != 0)
+ fprintf(&m_file, "\n (loops for %d instructions)\n\n", m_loops);
+ m_loops = 0;
+ }
// execute any trace actions first
if (!m_action.empty())
diff --git a/src/emu/debug/debugcpu.h b/src/emu/debug/debugcpu.h
index bc4ee3675cf..aa2018201dd 100644
--- a/src/emu/debug/debugcpu.h
+++ b/src/emu/debug/debugcpu.h
@@ -263,7 +263,7 @@ public:
void track_mem_data_clear() { m_track_mem_set.clear(); }
// tracing
- void trace(FILE *file, bool trace_over, const char *action);
+ void trace(FILE *file, bool trace_over, bool detect_loops, const char *action);
void trace_printf(const char *fmt, ...) ATTR_PRINTF(2,3);
void trace_flush() { if (m_trace != nullptr) m_trace->flush(); }
@@ -336,7 +336,7 @@ private:
class tracer
{
public:
- tracer(device_debug &debug, FILE &file, bool trace_over, const char *action);
+ tracer(device_debug &debug, FILE &file, bool trace_over, bool detect_loops, const char *action);
~tracer();
void update(offs_t pc);
@@ -350,6 +350,7 @@ private:
FILE & m_file; // tracing file for this CPU
std::string m_action; // action to perform during a trace
offs_t m_history[TRACE_LOOPS]; // history of recent PCs
+ bool m_detect_loops; // whether or not we should detect loops
int m_loops; // number of instructions in a loop
int m_nextdex; // next index
bool m_trace_over; // true if we're tracing over
diff --git a/src/emu/debug/debughlp.cpp b/src/emu/debug/debughlp.cpp
index 8d66f59d85a..6f14f4d3e64 100644
--- a/src/emu/debug/debughlp.cpp
+++ b/src/emu/debug/debughlp.cpp
@@ -140,8 +140,8 @@ static const help_item static_help_list[] =
" focus <cpu> -- focuses debugger only on <cpu>\n"
" ignore [<cpu>[,<cpu>[,...]]] -- stops debugging on <cpu>\n"
" observe [<cpu>[,<cpu>[,...]]] -- resumes debugging on <cpu>\n"
- " trace {<filename>|OFF}[,<cpu>[,<action>]] -- trace the given CPU to a file (defaults to active CPU)\n"
- " traceover {<filename>|OFF}[,<cpu>[,<action>]] -- trace the given CPU to a file, but skip subroutines (defaults to active CPU)\n"
+ " trace {<filename>|OFF}[,<cpu>[,<detectloops>[,<action>]]] -- trace the given CPU to a file (defaults to active CPU)\n"
+ " traceover {<filename>|OFF}[,<cpu>[,<detectloops>[,<action>]]] -- trace the given CPU to a file, but skip subroutines (defaults to active CPU)\n"
" traceflush -- flushes all open trace files\n"
},
{
@@ -818,11 +818,14 @@ static const help_item static_help_list[] =
{
"trace",
"\n"
- " trace {<filename>|OFF}[,<cpu>[,<action>]]\n"
+ " trace {<filename>|OFF}[,<cpu>[,<detectloops>[,<action>]]]\n"
"\n"
"Starts or stops tracing of the execution of the specified <cpu>. If <cpu> is omitted, "
"the currently active CPU is specified. When enabling tracing, specify the filename in the "
- "<filename> parameter. To disable tracing, substitute the keyword 'off' for <filename>. If you "
+ "<filename> parameter. To disable tracing, substitute the keyword 'off' for <filename>. "
+ "<detectloops> should be either true or false. If <detectloops> is true or omitted, the trace "
+ "will have loops detected and condensed to a single line. If it is false, the trace will contain "
+ "every opcode as it is executed. If you "
"wish to log additional information on each trace, you can append an <action> parameter which "
"is a command that is executed before each trace is logged. Generally, this is used to include "
"a 'tracelog' command. Note that you may need to embed the action within braces { } in order "
@@ -831,11 +834,14 @@ static const help_item static_help_list[] =
"\n"
"Examples:\n"
"\n"
+ "trace joust.tr\n"
+ " Begin tracing the currently active CPU, logging output to joust.tr.\n"
+ "\n"
"trace dribling.tr,0\n"
" Begin tracing the execution of CPU #0, logging output to dribling.tr.\n"
"\n"
- "trace joust.tr\n"
- " Begin tracing the currently active CPU, logging output to joust.tr.\n"
+ "trace starswep.tr,0,false\n"
+ " Begin tracing the execution of CPU #0, logging output to starswep.tr, with loop detection disabled.\n"
"\n"
"trace >>pigskin.tr\n"
" Begin tracing the currently active CPU, appending log output to pigskin.tr.\n"
@@ -843,39 +849,44 @@ static const help_item static_help_list[] =
"trace off,0\n"
" Turn off tracing on CPU #0.\n"
"\n"
- "trace asteroid.tr,0,{tracelog \"A=%02X \",a}\n"
+ "trace asteroid.tr,0,true,{tracelog \"A=%02X \",a}\n"
" Begin tracing the execution of CPU #0, logging output to asteroid.tr. Before each line, "
"output A=<aval> to the tracelog.\n"
},
{
"traceover",
"\n"
- " traceover {<filename>|OFF}[,<cpu>[,<action>]]\n"
+ " traceover {<filename>|OFF}[,<cpu>[,<detectloops>[,<action>]]]\n"
"\n"
"Starts or stops tracing of the execution of the specified <cpu>. When tracing reaches "
"a subroutine or call, tracing will skip over the subroutine. The same algorithm is used as is "
"used in the step over command. This means that traceover will not work properly when calls "
"are recusive or the return address is not immediately following the call instruction. If "
- "<cpu> is omitted, the currently active CPU is specified. When enabling tracing, specify the "
- "filename in the <filename> parameter. To disable tracing, substitute the keyword 'off' for "
- "<filename>. If you wish to log additional information on each trace, you can append an <action> "
- "parameter which is a command that is executed before each trace is logged. Generally, this is "
- "used to include a 'tracelog' command. Note that you may need to embed the action within braces "
- "{ } in order to prevent commas and semicolons from being interpreted as applying to the trace "
- "command itself.\n"
+ "<detectloops> should be either true or false. If <detectloops> is true or omitted, the trace "
+ "will have loops detected and condensed to a single line. If it is false, the trace will contain "
+ "every opcode as it is executed. If <cpu> is omitted, the currently active CPU is specified. When "
+ "enabling tracing, specify the filename in the <filename> parameter. To disable tracing, substitute "
+ "the keyword 'off' for <filename>. If you wish to log additional information on each trace, you can "
+ "append an <action> parameter which is a command that is executed before each trace is logged. "
+ "Generally, this is used to include a 'tracelog' command. Note that you may need to embed the "
+ "action within braces { } in order to prevent commas and semicolons from being interpreted as "
+ "applying to the trace command itself.\n"
"\n"
"Examples:\n"
"\n"
+ "traceover joust.tr\n"
+ " Begin tracing the currently active CPU, logging output to joust.tr.\n"
+ "\n"
"traceover dribling.tr,0\n"
" Begin tracing the execution of CPU #0, logging output to dribling.tr.\n"
"\n"
- "traceover joust.tr\n"
- " Begin tracing the currently active CPU, logging output to joust.tr.\n"
+ "traceover starswep.tr,0,false\n"
+ " Begin tracing the execution of CPU #0, logging output to starswep.tr, with loop detection disabled.\n"
"\n"
"traceover off,0\n"
" Turn off tracing on CPU #0.\n"
"\n"
- "traceover asteroid.tr,0,{tracelog \"A=%02X \",a}\n"
+ "traceover asteroid.tr,0,true,{tracelog \"A=%02X \",a}\n"
" Begin tracing the execution of CPU #0, logging output to asteroid.tr. Before each line, "
"output A=<aval> to the tracelog.\n"
},