mirror of
https://github.com/holub/mame
synced 2025-04-28 11:11:48 +03:00
Added suspend and resume debugger commands (#3411)
This commit is contained in:
parent
729c0ca3ed
commit
06a09d3821
@ -163,6 +163,8 @@ debugger_commands::debugger_commands(running_machine& machine, debugger_cpu& cpu
|
||||
m_console.register_command("focus", CMDFLAG_NONE, 0, 1, 1, std::bind(&debugger_commands::execute_focus, this, _1, _2));
|
||||
m_console.register_command("ignore", CMDFLAG_NONE, 0, 0, MAX_COMMAND_PARAMS, std::bind(&debugger_commands::execute_ignore, this, _1, _2));
|
||||
m_console.register_command("observe", CMDFLAG_NONE, 0, 0, MAX_COMMAND_PARAMS, std::bind(&debugger_commands::execute_observe, this, _1, _2));
|
||||
m_console.register_command("suspend", CMDFLAG_NONE, 0, 0, MAX_COMMAND_PARAMS, std::bind(&debugger_commands::execute_suspend, this, _1, _2));
|
||||
m_console.register_command("resume", CMDFLAG_NONE, 0, 0, MAX_COMMAND_PARAMS, std::bind(&debugger_commands::execute_resume, this, _1, _2));
|
||||
|
||||
m_console.register_command("comadd", CMDFLAG_NONE, 0, 1, 2, std::bind(&debugger_commands::execute_comment_add, this, _1, _2));
|
||||
m_console.register_command("//", CMDFLAG_NONE, 0, 1, 2, std::bind(&debugger_commands::execute_comment_add, this, _1, _2));
|
||||
@ -1023,6 +1025,109 @@ void debugger_commands::execute_observe(int ref, const std::vector<std::string>
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------------
|
||||
execute_suspend - suspend execution on cpu
|
||||
-------------------------------------------------*/
|
||||
|
||||
void debugger_commands::execute_suspend(int ref, const std::vector<std::string> ¶ms)
|
||||
{
|
||||
/* if there are no parameters, dump the ignore list */
|
||||
if (params.empty())
|
||||
{
|
||||
std::string buffer;
|
||||
|
||||
/* loop over all executable devices */
|
||||
for (device_execute_interface &exec : execute_interface_iterator(m_machine.root_device()))
|
||||
|
||||
/* build up a comma-separated list */
|
||||
if (exec.device().debug()->suspended())
|
||||
{
|
||||
if (buffer.empty())
|
||||
buffer = string_format("Currently suspended device '%s'", exec.device().tag());
|
||||
else
|
||||
buffer.append(string_format(", '%s'", exec.device().tag()));
|
||||
}
|
||||
|
||||
/* special message for none */
|
||||
if (buffer.empty())
|
||||
buffer = string_format("No currently suspended devices");
|
||||
m_console.printf("%s\n", buffer.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
device_t *devicelist[MAX_COMMAND_PARAMS];
|
||||
|
||||
/* validate parameters */
|
||||
for (int paramnum = 0; paramnum < params.size(); paramnum++)
|
||||
if (!validate_cpu_parameter(params[paramnum].c_str(), devicelist[paramnum]))
|
||||
return;
|
||||
|
||||
for (int paramnum = 0; paramnum < params.size(); paramnum++)
|
||||
{
|
||||
/* make sure this isn't the last live CPU */
|
||||
bool gotone = false;
|
||||
for (device_execute_interface &exec : execute_interface_iterator(m_machine.root_device()))
|
||||
if (&exec.device() != devicelist[paramnum] && !exec.device().debug()->suspended())
|
||||
{
|
||||
gotone = true;
|
||||
break;
|
||||
}
|
||||
if (!gotone)
|
||||
{
|
||||
m_console.printf("Can't suspend all devices!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
devicelist[paramnum]->debug()->suspend(true);
|
||||
m_console.printf("Suspended device '%s'\n", devicelist[paramnum]->tag());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------------
|
||||
execute_resume - Resume execution on CPU
|
||||
-------------------------------------------------*/
|
||||
|
||||
void debugger_commands::execute_resume(int ref, const std::vector<std::string> ¶ms)
|
||||
{
|
||||
/* if there are no parameters, dump the ignore list */
|
||||
if (params.empty())
|
||||
{
|
||||
std::string buffer;
|
||||
|
||||
/* loop over all executable devices */
|
||||
for (device_execute_interface &exec : execute_interface_iterator(m_machine.root_device()))
|
||||
|
||||
/* build up a comma-separated list */
|
||||
if (exec.device().debug()->suspended())
|
||||
{
|
||||
if (buffer.empty())
|
||||
buffer = string_format("Currently suspended device '%s'", exec.device().tag());
|
||||
else
|
||||
buffer.append(string_format(", '%s'", exec.device().tag()));
|
||||
}
|
||||
|
||||
/* special message for none */
|
||||
if (buffer.empty())
|
||||
buffer = string_format("No currently suspended devices");
|
||||
m_console.printf("%s\n", buffer.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
device_t *devicelist[MAX_COMMAND_PARAMS];
|
||||
|
||||
/* validate parameters */
|
||||
for (int paramnum = 0; paramnum < params.size(); paramnum++)
|
||||
if (!validate_cpu_parameter(params[paramnum].c_str(), devicelist[paramnum]))
|
||||
return;
|
||||
|
||||
for (int paramnum = 0; paramnum < params.size(); paramnum++)
|
||||
{
|
||||
devicelist[paramnum]->debug()->suspend(false);
|
||||
m_console.printf("Resumed device '%s'\n", devicelist[paramnum]->tag());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*-------------------------------------------------
|
||||
execute_comment - add a comment to a line
|
||||
|
@ -110,6 +110,8 @@ private:
|
||||
void execute_focus(int ref, const std::vector<std::string> ¶ms);
|
||||
void execute_ignore(int ref, const std::vector<std::string> ¶ms);
|
||||
void execute_observe(int ref, const std::vector<std::string> ¶ms);
|
||||
void execute_suspend(int ref, const std::vector<std::string> ¶ms);
|
||||
void execute_resume(int ref, const std::vector<std::string> ¶ms);
|
||||
void execute_next(int ref, const std::vector<std::string> ¶ms);
|
||||
void execute_comment_add(int ref, const std::vector<std::string> ¶ms);
|
||||
void execute_comment_del(int ref, const std::vector<std::string> ¶ms);
|
||||
|
@ -1820,6 +1820,29 @@ void device_debug::ignore(bool ignore)
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// suspend
|
||||
//-------------------------------------------------
|
||||
|
||||
void device_debug::suspend(bool suspend)
|
||||
{
|
||||
assert(m_exec != nullptr);
|
||||
|
||||
if (suspend) {
|
||||
m_flags |= DEBUG_FLAG_SUSPENDED;
|
||||
m_exec->suspend(SUSPEND_REASON_HALT, 1);
|
||||
}
|
||||
else {
|
||||
m_flags &= ~DEBUG_FLAG_SUSPENDED;
|
||||
m_exec->resume(SUSPEND_REASON_HALT);
|
||||
}
|
||||
|
||||
if (&m_device == m_device.machine().debugger().cpu().live_cpu() && suspend)
|
||||
{
|
||||
assert(m_exec != nullptr);
|
||||
go_next_device();
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// single_step - single step the device past the
|
||||
|
@ -189,6 +189,10 @@ public:
|
||||
void ignore(bool ignore = true);
|
||||
bool observing() const { return ((m_flags & DEBUG_FLAG_OBSERVING) != 0); }
|
||||
|
||||
// debugger suspend/unsuspend
|
||||
void suspend(bool suspend = true);
|
||||
bool suspended() const { return ((m_flags & DEBUG_FLAG_SUSPENDED) != 0); }
|
||||
|
||||
// single stepping
|
||||
void single_step(int numsteps = 1);
|
||||
void single_step_over(int numsteps = 1);
|
||||
@ -447,6 +451,7 @@ private:
|
||||
static constexpr u32 DEBUG_FLAG_STOP_EXCEPTION = 0x00000800; // there is a pending stop on the next exception
|
||||
static constexpr u32 DEBUG_FLAG_STOP_VBLANK = 0x00001000; // there is a pending stop on the next VBLANK
|
||||
static constexpr u32 DEBUG_FLAG_STOP_TIME = 0x00002000; // there is a pending stop at cpu->stoptime
|
||||
static constexpr u32 DEBUG_FLAG_SUSPENDED = 0x00004000; // CPU currently suspended
|
||||
static constexpr u32 DEBUG_FLAG_LIVE_BP = 0x00010000; // there are live breakpoints for this CPU
|
||||
|
||||
static constexpr u32 DEBUG_FLAG_STEPPING_ANY = DEBUG_FLAG_STEPPING | DEBUG_FLAG_STEPPING_OVER | DEBUG_FLAG_STEPPING_OUT;
|
||||
|
@ -142,6 +142,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"
|
||||
" suspend [<CPU>[,<CPU>[,...]]] -- suspends execution on <CPU>\n"
|
||||
" resume [<CPU>[,<CPU>[,...]]] -- resumes execution on <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"
|
||||
|
Loading…
Reference in New Issue
Block a user