mirror of
https://github.com/holub/mame
synced 2025-06-08 05:44:09 +03:00
Debugger: [Wilbert Pol]
- Added support for registerpoints. - Added 'exit' as a synonym for 'quit'.
This commit is contained in:
parent
e7e15bca12
commit
c03729e963
@ -124,6 +124,10 @@ static void execute_wpset(running_machine &machine, int ref, int params, const c
|
|||||||
static void execute_wpclear(running_machine &machine, int ref, int params, const char **param);
|
static void execute_wpclear(running_machine &machine, int ref, int params, const char **param);
|
||||||
static void execute_wpdisenable(running_machine &machine, int ref, int params, const char **param);
|
static void execute_wpdisenable(running_machine &machine, int ref, int params, const char **param);
|
||||||
static void execute_wplist(running_machine &machine, int ref, int params, const char **param);
|
static void execute_wplist(running_machine &machine, int ref, int params, const char **param);
|
||||||
|
static void execute_rpset(running_machine &machine, int ref, int params, const char **param);
|
||||||
|
static void execute_rpclear(running_machine &machine, int ref, int params, const char **param);
|
||||||
|
static void execute_rpdisenable(running_machine &machine, int ref, int params, const char **param);
|
||||||
|
static void execute_rplist(running_machine &machine, int ref, int params, const char **param);
|
||||||
static void execute_hotspot(running_machine &machine, int ref, int params, const char **param);
|
static void execute_hotspot(running_machine &machine, int ref, int params, const char **param);
|
||||||
static void execute_save(running_machine &machine, int ref, int params, const char **param);
|
static void execute_save(running_machine &machine, int ref, int params, const char **param);
|
||||||
static void execute_load(running_machine &machine, int ref, int params, const char **param);
|
static void execute_load(running_machine &machine, int ref, int params, const char **param);
|
||||||
@ -266,6 +270,7 @@ void debug_command_init(running_machine &machine)
|
|||||||
debug_console_register_command(machine, "logerror", CMDFLAG_NONE, 0, 1, MAX_COMMAND_PARAMS, execute_logerror);
|
debug_console_register_command(machine, "logerror", CMDFLAG_NONE, 0, 1, MAX_COMMAND_PARAMS, execute_logerror);
|
||||||
debug_console_register_command(machine, "tracelog", CMDFLAG_NONE, 0, 1, MAX_COMMAND_PARAMS, execute_tracelog);
|
debug_console_register_command(machine, "tracelog", CMDFLAG_NONE, 0, 1, MAX_COMMAND_PARAMS, execute_tracelog);
|
||||||
debug_console_register_command(machine, "quit", CMDFLAG_NONE, 0, 0, 0, execute_quit);
|
debug_console_register_command(machine, "quit", CMDFLAG_NONE, 0, 0, 0, execute_quit);
|
||||||
|
debug_console_register_command(machine, "exit", CMDFLAG_NONE, 0, 0, 0, execute_quit);
|
||||||
debug_console_register_command(machine, "do", CMDFLAG_NONE, 0, 1, 1, execute_do);
|
debug_console_register_command(machine, "do", CMDFLAG_NONE, 0, 1, 1, execute_do);
|
||||||
debug_console_register_command(machine, "step", CMDFLAG_NONE, 0, 0, 1, execute_step);
|
debug_console_register_command(machine, "step", CMDFLAG_NONE, 0, 0, 1, execute_step);
|
||||||
debug_console_register_command(machine, "s", CMDFLAG_NONE, 0, 0, 1, execute_step);
|
debug_console_register_command(machine, "s", CMDFLAG_NONE, 0, 0, 1, execute_step);
|
||||||
@ -309,6 +314,13 @@ void debug_command_init(running_machine &machine)
|
|||||||
debug_console_register_command(machine, "wpenable", CMDFLAG_NONE, 1, 0, 1, execute_wpdisenable);
|
debug_console_register_command(machine, "wpenable", CMDFLAG_NONE, 1, 0, 1, execute_wpdisenable);
|
||||||
debug_console_register_command(machine, "wplist", CMDFLAG_NONE, 0, 0, 0, execute_wplist);
|
debug_console_register_command(machine, "wplist", CMDFLAG_NONE, 0, 0, 0, execute_wplist);
|
||||||
|
|
||||||
|
debug_console_register_command(machine, "rpset", CMDFLAG_NONE, 0, 1, 2, execute_rpset);
|
||||||
|
debug_console_register_command(machine, "rp", CMDFLAG_NONE, 0, 1, 2, execute_rpset);
|
||||||
|
debug_console_register_command(machine, "rpclear", CMDFLAG_NONE, 0, 0, 1, execute_rpclear);
|
||||||
|
debug_console_register_command(machine, "rpdisable", CMDFLAG_NONE, 0, 0, 1, execute_rpdisenable);
|
||||||
|
debug_console_register_command(machine, "rpenable", CMDFLAG_NONE, 1, 0, 1, execute_rpdisenable);
|
||||||
|
debug_console_register_command(machine, "rplist", CMDFLAG_NONE, 0, 0, 0, execute_rplist);
|
||||||
|
|
||||||
debug_console_register_command(machine, "hotspot", CMDFLAG_NONE, 0, 0, 3, execute_hotspot);
|
debug_console_register_command(machine, "hotspot", CMDFLAG_NONE, 0, 0, 3, execute_hotspot);
|
||||||
|
|
||||||
debug_console_register_command(machine, "save", CMDFLAG_NONE, AS_PROGRAM, 3, 4, execute_save);
|
debug_console_register_command(machine, "save", CMDFLAG_NONE, AS_PROGRAM, 3, 4, execute_save);
|
||||||
@ -1487,6 +1499,145 @@ static void execute_wplist(running_machine &machine, int ref, int params, const
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*-------------------------------------------------
|
||||||
|
execute_rpset - execute the registerpoint set
|
||||||
|
command
|
||||||
|
-------------------------------------------------*/
|
||||||
|
|
||||||
|
static void execute_rpset(running_machine &machine, int ref, int params, const char *param[])
|
||||||
|
{
|
||||||
|
device_t *cpu;
|
||||||
|
const char *action = NULL;
|
||||||
|
int bpnum;
|
||||||
|
|
||||||
|
/* CPU is implicit */
|
||||||
|
if (!debug_command_parameter_cpu(machine, NULL, &cpu))
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* param 1 is the condition */
|
||||||
|
parsed_expression condition(&cpu->debug()->symtable());
|
||||||
|
if (!debug_command_parameter_expression(machine, param[0], condition))
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* param 2 is the action */
|
||||||
|
if (!debug_command_parameter_command(machine, action = param[1]))
|
||||||
|
return;
|
||||||
|
|
||||||
|
/* set the breakpoint */
|
||||||
|
bpnum = cpu->debug()->registerpoint_set(condition.original_string(), action);
|
||||||
|
debug_console_printf(machine, "Registerpoint %X set\n", bpnum);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*-------------------------------------------------
|
||||||
|
execute_rpclear - execute the registerpoint
|
||||||
|
clear command
|
||||||
|
-------------------------------------------------*/
|
||||||
|
|
||||||
|
static void execute_rpclear(running_machine &machine, int ref, int params, const char *param[])
|
||||||
|
{
|
||||||
|
UINT64 rpindex;
|
||||||
|
|
||||||
|
/* if 0 parameters, clear all */
|
||||||
|
if (params == 0)
|
||||||
|
{
|
||||||
|
device_iterator iter(machine.root_device());
|
||||||
|
for (device_t *device = iter.first(); device != NULL; device = iter.next())
|
||||||
|
device->debug()->registerpoint_clear_all();
|
||||||
|
debug_console_printf(machine, "Cleared all registerpoints\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* otherwise, clear the specific one */
|
||||||
|
else if (!debug_command_parameter_number(machine, param[0], &rpindex))
|
||||||
|
return;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
device_iterator iter(machine.root_device());
|
||||||
|
bool found = false;
|
||||||
|
for (device_t *device = iter.first(); device != NULL; device = iter.next())
|
||||||
|
if (device->debug()->registerpoint_clear(rpindex))
|
||||||
|
found = true;
|
||||||
|
if (found)
|
||||||
|
debug_console_printf(machine, "Registerpoint %X cleared\n", (UINT32)rpindex);
|
||||||
|
else
|
||||||
|
debug_console_printf(machine, "Invalid registerpoint number %X\n", (UINT32)rpindex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*-------------------------------------------------
|
||||||
|
execute_rpdisenable - execute the registerpoint
|
||||||
|
disable/enable commands
|
||||||
|
-------------------------------------------------*/
|
||||||
|
|
||||||
|
static void execute_rpdisenable(running_machine &machine, int ref, int params, const char *param[])
|
||||||
|
{
|
||||||
|
UINT64 rpindex;
|
||||||
|
|
||||||
|
/* if 0 parameters, clear all */
|
||||||
|
if (params == 0)
|
||||||
|
{
|
||||||
|
device_iterator iter(machine.root_device());
|
||||||
|
for (device_t *device = iter.first(); device != NULL; device = iter.next())
|
||||||
|
device->debug()->registerpoint_enable_all(ref);
|
||||||
|
if (ref == 0)
|
||||||
|
debug_console_printf(machine, "Disabled all registerpoints\n");
|
||||||
|
else
|
||||||
|
debug_console_printf(machine, "Enabled all registeroints\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* otherwise, clear the specific one */
|
||||||
|
else if (!debug_command_parameter_number(machine, param[0], &rpindex))
|
||||||
|
return;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
device_iterator iter(machine.root_device());
|
||||||
|
bool found = false;
|
||||||
|
for (device_t *device = iter.first(); device != NULL; device = iter.next())
|
||||||
|
if (device->debug()->registerpoint_enable(rpindex, ref))
|
||||||
|
found = true;
|
||||||
|
if (found)
|
||||||
|
debug_console_printf(machine, "Registerpoint %X %s\n", (UINT32)rpindex, ref ? "enabled" : "disabled");
|
||||||
|
else
|
||||||
|
debug_console_printf(machine, "Invalid registerpoint number %X\n", (UINT32)rpindex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*-------------------------------------------------
|
||||||
|
execute_rplist - execute the registerpoint list
|
||||||
|
command
|
||||||
|
-------------------------------------------------*/
|
||||||
|
|
||||||
|
static void execute_rplist(running_machine &machine, int ref, int params, const char *param[])
|
||||||
|
{
|
||||||
|
int printed = 0;
|
||||||
|
astring buffer;
|
||||||
|
|
||||||
|
/* loop over all CPUs */
|
||||||
|
device_iterator iter(machine.root_device());
|
||||||
|
for (device_t *device = iter.first(); device != NULL; device = iter.next())
|
||||||
|
if (device->debug()->registerpoint_first() != NULL)
|
||||||
|
{
|
||||||
|
debug_console_printf(machine, "Device '%s' registerpoints:\n", device->tag());
|
||||||
|
|
||||||
|
/* loop over the breakpoints */
|
||||||
|
for (device_debug::registerpoint *rp = device->debug()->registerpoint_first(); rp != NULL; rp = rp->next())
|
||||||
|
{
|
||||||
|
buffer.printf("%c%4X ", rp->enabled() ? ' ' : 'D', rp->index());
|
||||||
|
buffer.catprintf("if %s", rp->condition());
|
||||||
|
if (rp->action() != NULL)
|
||||||
|
buffer.catprintf(" do %s", rp->action());
|
||||||
|
debug_console_printf(machine, "%s\n", buffer.cstr());
|
||||||
|
printed++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (printed == 0)
|
||||||
|
debug_console_printf(machine, "No registerpoints currently installed\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*-------------------------------------------------
|
/*-------------------------------------------------
|
||||||
execute_hotspot - execute the hotspot
|
execute_hotspot - execute the hotspot
|
||||||
command
|
command
|
||||||
|
@ -91,6 +91,7 @@ struct debugcpu_private
|
|||||||
|
|
||||||
UINT32 bpindex;
|
UINT32 bpindex;
|
||||||
UINT32 wpindex;
|
UINT32 wpindex;
|
||||||
|
UINT32 rpindex;
|
||||||
|
|
||||||
UINT64 wpdata;
|
UINT64 wpdata;
|
||||||
UINT64 wpaddr;
|
UINT64 wpaddr;
|
||||||
@ -150,6 +151,7 @@ void debug_cpu_init(running_machine &machine)
|
|||||||
global->execution_state = EXECUTION_STATE_STOPPED;
|
global->execution_state = EXECUTION_STATE_STOPPED;
|
||||||
global->bpindex = 1;
|
global->bpindex = 1;
|
||||||
global->wpindex = 1;
|
global->wpindex = 1;
|
||||||
|
global->rpindex = 1;
|
||||||
|
|
||||||
/* create a global symbol table */
|
/* create a global symbol table */
|
||||||
global->symtable = global_alloc(symbol_table(&machine));
|
global->symtable = global_alloc(symbol_table(&machine));
|
||||||
@ -1653,6 +1655,7 @@ device_debug::device_debug(device_t &device)
|
|||||||
m_last_total_cycles(0),
|
m_last_total_cycles(0),
|
||||||
m_pc_history_index(0),
|
m_pc_history_index(0),
|
||||||
m_bplist(NULL),
|
m_bplist(NULL),
|
||||||
|
m_rplist(NULL),
|
||||||
m_trace(NULL),
|
m_trace(NULL),
|
||||||
m_hotspots(NULL),
|
m_hotspots(NULL),
|
||||||
m_hotspot_count(0),
|
m_hotspot_count(0),
|
||||||
@ -1721,6 +1724,7 @@ device_debug::~device_debug()
|
|||||||
// free breakpoints and watchpoints
|
// free breakpoints and watchpoints
|
||||||
breakpoint_clear_all();
|
breakpoint_clear_all();
|
||||||
watchpoint_clear_all();
|
watchpoint_clear_all();
|
||||||
|
registerpoint_clear_all();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -2456,6 +2460,95 @@ void device_debug::watchpoint_enable_all(bool enable)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// registerpoint_set - set a new registerpoint,
|
||||||
|
// returning its index
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
int device_debug::registerpoint_set(const char *condition, const char *action)
|
||||||
|
{
|
||||||
|
// allocate a new one
|
||||||
|
registerpoint *rp = auto_alloc(m_device.machine(), registerpoint(m_symtable, m_device.machine().debugcpu_data->rpindex++, condition, action));
|
||||||
|
|
||||||
|
// hook it into our list
|
||||||
|
rp->m_next = m_rplist;
|
||||||
|
m_rplist = rp;
|
||||||
|
|
||||||
|
// update the flags and return the index
|
||||||
|
breakpoint_update_flags();
|
||||||
|
return rp->m_index;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// registerpoint_clear - clear a registerpoint by index,
|
||||||
|
// returning true if we found it
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
bool device_debug::registerpoint_clear(int index)
|
||||||
|
{
|
||||||
|
// scan the list to see if we own this registerpoint
|
||||||
|
for (registerpoint **rp = &m_rplist; *rp != NULL; rp = &(*rp)->m_next)
|
||||||
|
if ((*rp)->m_index == index)
|
||||||
|
{
|
||||||
|
registerpoint *deleteme = *rp;
|
||||||
|
*rp = deleteme->m_next;
|
||||||
|
auto_free(m_device.machine(), deleteme);
|
||||||
|
breakpoint_update_flags();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// we don't own it, return false
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// registerpoint_clear_all - clear all registerpoints
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
void device_debug::registerpoint_clear_all()
|
||||||
|
{
|
||||||
|
// clear the head until we run out
|
||||||
|
while (m_rplist != NULL)
|
||||||
|
registerpoint_clear(m_rplist->index());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// registerpoint_enable - enable/disable a registerpoint
|
||||||
|
// by index, returning true if we found it
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
bool device_debug::registerpoint_enable(int index, bool enable)
|
||||||
|
{
|
||||||
|
// scan the list to see if we own this conditionpoint
|
||||||
|
for (registerpoint *rp = m_rplist; rp != NULL; rp = rp->next())
|
||||||
|
if (rp->m_index == index)
|
||||||
|
{
|
||||||
|
rp->m_enabled = enable;
|
||||||
|
breakpoint_update_flags();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// we don't own it, return false
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// registerpoint_enable_all - enable/disable all
|
||||||
|
// registerpoints
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
void device_debug::registerpoint_enable_all(bool enable)
|
||||||
|
{
|
||||||
|
// apply the enable to all registerpoints we own
|
||||||
|
for (registerpoint *rp = m_rplist; rp != NULL; rp = rp->next())
|
||||||
|
registerpoint_enable(rp->index(), enable);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//-------------------------------------------------
|
//-------------------------------------------------
|
||||||
// hotspot_track - enable/disable tracking of
|
// hotspot_track - enable/disable tracking of
|
||||||
// hotspots
|
// hotspots
|
||||||
@ -2824,6 +2917,18 @@ void device_debug::breakpoint_update_flags()
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ( ! ( m_flags & DEBUG_FLAG_LIVE_BP ) )
|
||||||
|
{
|
||||||
|
// see if there are any enabled registerpoints
|
||||||
|
for (registerpoint *rp = m_rplist; rp != NULL; rp = rp->m_next)
|
||||||
|
{
|
||||||
|
if (rp->m_enabled)
|
||||||
|
{
|
||||||
|
m_flags |= DEBUG_FLAG_LIVE_BP;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// push the flags out globally
|
// push the flags out globally
|
||||||
debugcpu_private *global = m_device.machine().debugcpu_data;
|
debugcpu_private *global = m_device.machine().debugcpu_data;
|
||||||
if (global->livecpu != NULL)
|
if (global->livecpu != NULL)
|
||||||
@ -2855,6 +2960,30 @@ void device_debug::breakpoint_check(offs_t pc)
|
|||||||
debug_console_printf(m_device.machine(), "Stopped at breakpoint %X\n", bp->m_index);
|
debug_console_printf(m_device.machine(), "Stopped at breakpoint %X\n", bp->m_index);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// see if we have any matching registerpoints
|
||||||
|
for (registerpoint *rp = m_rplist; rp != NULL; rp = rp->m_next)
|
||||||
|
{
|
||||||
|
if (rp->hit())
|
||||||
|
{
|
||||||
|
// halt in the debugger by default
|
||||||
|
debugcpu_private *global = m_device.machine().debugcpu_data;
|
||||||
|
global->execution_state = EXECUTION_STATE_STOPPED;
|
||||||
|
|
||||||
|
// if we hit, evaluate the action
|
||||||
|
if (rp->m_action)
|
||||||
|
{
|
||||||
|
debug_console_execute_command(m_device.machine(), rp->m_action, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// print a notification, unless the action made us go again
|
||||||
|
if (global->execution_state == EXECUTION_STATE_STOPPED)
|
||||||
|
{
|
||||||
|
debug_console_printf(m_device.machine(), "Stopped at registerpoint %X\n", rp->m_index);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -3256,6 +3385,52 @@ bool device_debug::watchpoint::hit(int type, offs_t address, int size)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//**************************************************************************
|
||||||
|
// DEBUG REGISTERPOINT
|
||||||
|
//**************************************************************************
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// registerpoint - constructor
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
device_debug::registerpoint::registerpoint(symbol_table &symbols, int index, const char *condition, const char *action)
|
||||||
|
: m_next(NULL),
|
||||||
|
m_index(index),
|
||||||
|
m_enabled(true),
|
||||||
|
m_condition(&symbols, (condition != NULL) ? condition : "1"),
|
||||||
|
m_action((action != NULL) ? action : "")
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//-------------------------------------------------
|
||||||
|
// hit - detect a hit
|
||||||
|
//-------------------------------------------------
|
||||||
|
|
||||||
|
bool device_debug::registerpoint::hit()
|
||||||
|
{
|
||||||
|
// don't hit if disabled
|
||||||
|
if (!m_enabled)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// must satisfy the condition
|
||||||
|
if (!m_condition.is_empty())
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return (m_condition.execute() != 0);
|
||||||
|
}
|
||||||
|
catch (expression_error &)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
//**************************************************************************
|
//**************************************************************************
|
||||||
// TRACER
|
// TRACER
|
||||||
//**************************************************************************
|
//**************************************************************************
|
||||||
|
@ -136,6 +136,33 @@ public:
|
|||||||
astring m_action; // action
|
astring m_action; // action
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// registerpoint class
|
||||||
|
class registerpoint
|
||||||
|
{
|
||||||
|
friend class device_debug;
|
||||||
|
|
||||||
|
public:
|
||||||
|
// construction/destruction
|
||||||
|
registerpoint(symbol_table &symbols, int index, const char *condition, const char *action = NULL);
|
||||||
|
|
||||||
|
// getters
|
||||||
|
registerpoint *next() const { return m_next; }
|
||||||
|
int index() const { return m_index; }
|
||||||
|
bool enabled() const { return m_enabled; }
|
||||||
|
const char *condition() const { return m_condition.original_string(); }
|
||||||
|
const char *action() const { return m_action; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
// internals
|
||||||
|
bool hit();
|
||||||
|
|
||||||
|
registerpoint * m_next; // next in the list
|
||||||
|
int m_index; // user reported index
|
||||||
|
UINT8 m_enabled; // enabled?
|
||||||
|
parsed_expression m_condition; // condition
|
||||||
|
astring m_action; // action
|
||||||
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// construction/destruction
|
// construction/destruction
|
||||||
device_debug(device_t &device);
|
device_debug(device_t &device);
|
||||||
@ -200,6 +227,14 @@ public:
|
|||||||
bool watchpoint_enable(int index, bool enable = true);
|
bool watchpoint_enable(int index, bool enable = true);
|
||||||
void watchpoint_enable_all(bool enable = true);
|
void watchpoint_enable_all(bool enable = true);
|
||||||
|
|
||||||
|
// registerpoints
|
||||||
|
registerpoint *registerpoint_first() const { return m_rplist; }
|
||||||
|
int registerpoint_set(const char *condition, const char *action = NULL);
|
||||||
|
bool registerpoint_clear(int index);
|
||||||
|
void registerpoint_clear_all();
|
||||||
|
bool registerpoint_enable(int index, bool enable = true);
|
||||||
|
void registerpoint_enable_all(bool enable = true );
|
||||||
|
|
||||||
// hotspots
|
// hotspots
|
||||||
bool hotspot_tracking_enabled() const { return (m_hotspots != NULL); }
|
bool hotspot_tracking_enabled() const { return (m_hotspots != NULL); }
|
||||||
void hotspot_track(int numspots, int threshhold);
|
void hotspot_track(int numspots, int threshhold);
|
||||||
@ -286,6 +321,7 @@ private:
|
|||||||
// breakpoints and watchpoints
|
// breakpoints and watchpoints
|
||||||
breakpoint * m_bplist; // list of breakpoints
|
breakpoint * m_bplist; // list of breakpoints
|
||||||
watchpoint * m_wplist[ADDRESS_SPACES]; // watchpoint lists for each address space
|
watchpoint * m_wplist[ADDRESS_SPACES]; // watchpoint lists for each address space
|
||||||
|
registerpoint * m_rplist; // list of registerpoints
|
||||||
|
|
||||||
// tracing
|
// tracing
|
||||||
class tracer
|
class tracer
|
||||||
|
@ -66,6 +66,7 @@ static const help_item static_help_list[] =
|
|||||||
" Execution\n"
|
" Execution\n"
|
||||||
" Breakpoints\n"
|
" Breakpoints\n"
|
||||||
" Watchpoints\n"
|
" Watchpoints\n"
|
||||||
|
" Registerpoints\n"
|
||||||
" Expressions\n"
|
" Expressions\n"
|
||||||
" Comments\n"
|
" Comments\n"
|
||||||
" Cheats\n"
|
" Cheats\n"
|
||||||
@ -162,6 +163,18 @@ static const help_item static_help_list[] =
|
|||||||
" wplist -- lists all the watchpoints\n"
|
" wplist -- lists all the watchpoints\n"
|
||||||
" hotspot [<cpu>,[<depth>[,<hits>]]] -- attempt to find hotspots\n"
|
" hotspot [<cpu>,[<depth>[,<hits>]]] -- attempt to find hotspots\n"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"registerpoints",
|
||||||
|
"\n"
|
||||||
|
"Registerpoint Commands\n"
|
||||||
|
"Type help <command> for further details on each command\n"
|
||||||
|
"\n"
|
||||||
|
" rp[set] {<condition>}[,<action>] -- sets a registerpoint to trigger on <condition>\n"
|
||||||
|
" rpclear [<rpnum>] -- clears a given registerpoint or all if no <rpnum> specified\n"
|
||||||
|
" rpdisable [<rpnum>] -- disabled a given registerpoint or all if no <rpnum> specified\n"
|
||||||
|
" rpenable [<rpnum>] -- enables a given registerpoint or all if no <rpnum> specified\n"
|
||||||
|
" rplist -- lists all the registerpoints\n"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"expressions",
|
"expressions",
|
||||||
"\n"
|
"\n"
|
||||||
@ -1005,6 +1018,90 @@ static const help_item static_help_list[] =
|
|||||||
" Looks for hotspots on CPU 1 using a search buffer of 64 entries, reporting any entries which "
|
" Looks for hotspots on CPU 1 using a search buffer of 64 entries, reporting any entries which "
|
||||||
"end up with 1000 or more hits.\n"
|
"end up with 1000 or more hits.\n"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"rpset",
|
||||||
|
"\n"
|
||||||
|
" rp[set] {<condition>}[,<action>]]\n"
|
||||||
|
"\n"
|
||||||
|
"Sets a new registerpoint which will be triggered when <condition> is met. The condition must "
|
||||||
|
"be specified between curly braces to prevent the condition from being evaluated as an "
|
||||||
|
"assignment.\n"
|
||||||
|
"\n"
|
||||||
|
"The optional <action> parameter provides a command that is executed whenever the registerpoint "
|
||||||
|
"is hit. 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 rpset command "
|
||||||
|
"itself. Each registerpoint that is set is assigned an index which can be used in other "
|
||||||
|
"registerpoint commands to reference this registerpoint.\n"
|
||||||
|
"\n"
|
||||||
|
"Examples:\n"
|
||||||
|
"\n"
|
||||||
|
"rp {PC==0150}\n"
|
||||||
|
" Set a registerpoint that will halt execution whenever the PC register equals 0x150.\n"
|
||||||
|
"\n"
|
||||||
|
"temp0=0; rp {PC==0150},{temp0++; g}\n"
|
||||||
|
" Set a registerpoint that will increment the variable temp0 whenever the PC register "
|
||||||
|
"equals 0x0150.\n"
|
||||||
|
"\n"
|
||||||
|
"rp {temp0==5}\n"
|
||||||
|
" Set a registerpoint that will halt execution whenever the temp0 variable equals 5.\n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rpclear",
|
||||||
|
"\n"
|
||||||
|
" rpclear [<rpnum>]\n"
|
||||||
|
"\n"
|
||||||
|
"The rpclear command clears a registerpoint. If <rpnum> is specified, only the requested "
|
||||||
|
"registerpoint is cleared, otherwise all registerpoints are cleared.\n"
|
||||||
|
"\n"
|
||||||
|
"Examples:\n"
|
||||||
|
"\n"
|
||||||
|
"rpclear 3\n"
|
||||||
|
" Clear registerpoint index 3.\n"
|
||||||
|
"\n"
|
||||||
|
"rpclear\n"
|
||||||
|
" Clear all registerpoints.\n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rpdisable",
|
||||||
|
"\n"
|
||||||
|
" rpdisable [<rpnum>]\n"
|
||||||
|
"\n"
|
||||||
|
"The rpdisable command disables a registerpoint. If <rpnum> is specified, only the requested "
|
||||||
|
"registerpoint is disabled, otherwise all registerpoints are disabled. Note that disabling a "
|
||||||
|
"registerpoint does not delete it, it just temporarily marks the registerpoint as inactive.\n"
|
||||||
|
"\n"
|
||||||
|
"Examples:\n"
|
||||||
|
"\n"
|
||||||
|
"rpdisable 3\n"
|
||||||
|
" Disable registerpoint index 3.\n"
|
||||||
|
"\n"
|
||||||
|
"rpdisable\n"
|
||||||
|
" Disable all registerpoints.\n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rpenable",
|
||||||
|
"\n"
|
||||||
|
" rpenable [<rpnum>]\n"
|
||||||
|
"\n"
|
||||||
|
"The rpenable command enables a registerpoint. If <rpnum> is specified, only the requested "
|
||||||
|
"registerpoint is enabled, otherwise all registerpoints are enabled.\n"
|
||||||
|
"\n"
|
||||||
|
"Examples:\n"
|
||||||
|
"\n"
|
||||||
|
"rpenable 3\n"
|
||||||
|
" Enable registerpoint index 3.\n"
|
||||||
|
"\n"
|
||||||
|
"rpenable\n"
|
||||||
|
" Enable all registerpoints.\n"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rplist",
|
||||||
|
"\n"
|
||||||
|
" rplist\n"
|
||||||
|
"\n"
|
||||||
|
"The rplist command lists all the current registerpoints, along with their index and any "
|
||||||
|
"actions attached to them.\n"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"map",
|
"map",
|
||||||
"\n"
|
"\n"
|
||||||
|
Loading…
Reference in New Issue
Block a user