Previous 199869 Revisions Next

r21807 Monday 11th March, 2013 at 21:29:51 UTC by Wilbert Pol
Debugger:  [Wilbert Pol]
- Added support for registerpoints.
- Added 'exit' as a synonym for 'quit'.
[src/emu/debug]debugcmd.c debugcpu.c debugcpu.h debughlp.c

trunk/src/emu/debug/debughlp.c
r21806r21807
6666      "  Execution\n"
6767      "  Breakpoints\n"
6868      "  Watchpoints\n"
69      "  Registerpoints\n"
6970      "  Expressions\n"
7071      "  Comments\n"
7172      "  Cheats\n"
r21806r21807
163164      "  hotspot [<cpu>,[<depth>[,<hits>]]] -- attempt to find hotspots\n"
164165   },
165166   {
167      "registerpoints",
168      "\n"
169      "Registerpoint Commands\n"
170      "Type help <command> for further details on each command\n"
171      "\n"
172      "  rp[set] {<condition>}[,<action>] -- sets a registerpoint to trigger on <condition>\n"
173      "  rpclear [<rpnum>] -- clears a given registerpoint or all if no <rpnum> specified\n"
174      "  rpdisable [<rpnum>] -- disabled a given registerpoint or all if no <rpnum> specified\n"
175      "  rpenable [<rpnum>]  -- enables a given registerpoint or all if no <rpnum> specified\n"
176      "  rplist -- lists all the registerpoints\n"
177   },
178   {
166179      "expressions",
167180      "\n"
168181      "Expressions can be used anywhere a numeric parameter is expected. The syntax for expressions is "
r21806r21807
10061019      "end up with 1000 or more hits.\n"
10071020   },
10081021   {
1022      "rpset",
1023      "\n"
1024      "  rp[set] {<condition>}[,<action>]]\n"
1025      "\n"
1026      "Sets a new registerpoint which will be triggered when <condition> is met. The condition must "
1027      "be specified between curly braces to prevent the condition from being evaluated as an "
1028      "assignment.\n"
1029      "\n"
1030      "The optional <action> parameter provides a command that is executed whenever the registerpoint "
1031      "is hit. Note that you may need to embed the action within braces { } in "
1032      "order to prevent commas and semicolons from being interpreted as applying to the rpset command "
1033      "itself. Each registerpoint that is set is assigned an index which can be used in other "
1034      "registerpoint commands to reference this registerpoint.\n"
1035      "\n"
1036      "Examples:\n"
1037      "\n"
1038      "rp {PC==0150}\n"
1039      "  Set a registerpoint that will halt execution whenever the PC register equals 0x150.\n"
1040      "\n"
1041      "temp0=0; rp {PC==0150},{temp0++; g}\n"
1042      "  Set a registerpoint that will increment the variable temp0 whenever the PC register "
1043      "equals 0x0150.\n"
1044      "\n"
1045      "rp {temp0==5}\n"
1046      "  Set a registerpoint that will halt execution whenever the temp0 variable equals 5.\n"
1047   },
1048   {
1049      "rpclear",
1050      "\n"
1051      "  rpclear [<rpnum>]\n"
1052      "\n"
1053      "The rpclear command clears a registerpoint. If <rpnum> is specified, only the requested "
1054      "registerpoint is cleared, otherwise all registerpoints are cleared.\n"
1055      "\n"
1056      "Examples:\n"
1057      "\n"
1058      "rpclear 3\n"
1059      "  Clear registerpoint index 3.\n"
1060      "\n"
1061      "rpclear\n"
1062      "  Clear all registerpoints.\n"
1063   },
1064   {
1065      "rpdisable",
1066      "\n"
1067      "  rpdisable [<rpnum>]\n"
1068      "\n"
1069      "The rpdisable command disables a registerpoint. If <rpnum> is specified, only the requested "
1070      "registerpoint is disabled, otherwise all registerpoints are disabled. Note that disabling a "
1071      "registerpoint does not delete it, it just temporarily marks the registerpoint as inactive.\n"
1072      "\n"
1073      "Examples:\n"
1074      "\n"
1075      "rpdisable 3\n"
1076      "  Disable registerpoint index 3.\n"
1077      "\n"
1078      "rpdisable\n"
1079      "  Disable all registerpoints.\n"
1080   },
1081   {
1082      "rpenable",
1083      "\n"
1084      "  rpenable [<rpnum>]\n"
1085      "\n"
1086      "The rpenable command enables a registerpoint. If <rpnum> is specified, only the requested "
1087      "registerpoint is enabled, otherwise all registerpoints are enabled.\n"
1088      "\n"
1089      "Examples:\n"
1090      "\n"
1091      "rpenable 3\n"
1092      "  Enable registerpoint index 3.\n"
1093      "\n"
1094      "rpenable\n"
1095      "  Enable all registerpoints.\n"
1096   },
1097   {
1098      "rplist",
1099      "\n"
1100      "  rplist\n"
1101      "\n"
1102      "The rplist command lists all the current registerpoints, along with their index and any "
1103      "actions attached to them.\n"
1104   },
1105   {
10091106      "map",
10101107      "\n"
10111108      "  map[{d|i}] <address>\n"
trunk/src/emu/debug/debugcpu.c
r21806r21807
9191
9292   UINT32          bpindex;
9393   UINT32          wpindex;
94   UINT32          rpindex;
9495
9596   UINT64          wpdata;
9697   UINT64          wpaddr;
r21806r21807
150151   global->execution_state = EXECUTION_STATE_STOPPED;
151152   global->bpindex = 1;
152153   global->wpindex = 1;
154   global->rpindex = 1;
153155
154156   /* create a global symbol table */
155157   global->symtable = global_alloc(symbol_table(&machine));
r21806r21807
16531655      m_last_total_cycles(0),
16541656      m_pc_history_index(0),
16551657      m_bplist(NULL),
1658      m_rplist(NULL),
16561659      m_trace(NULL),
16571660      m_hotspots(NULL),
16581661      m_hotspot_count(0),
r21806r21807
17211724   // free breakpoints and watchpoints
17221725   breakpoint_clear_all();
17231726   watchpoint_clear_all();
1727   registerpoint_clear_all();
17241728}
17251729
17261730
r21806r21807
24572461
24582462
24592463//-------------------------------------------------
2464//  registerpoint_set - set a new registerpoint,
2465//  returning its index
2466//-------------------------------------------------
2467
2468int device_debug::registerpoint_set(const char *condition, const char *action)
2469{
2470   // allocate a new one
2471   registerpoint *rp = auto_alloc(m_device.machine(), registerpoint(m_symtable, m_device.machine().debugcpu_data->rpindex++, condition, action));
2472
2473   // hook it into our list
2474   rp->m_next = m_rplist;
2475   m_rplist = rp;
2476
2477   // update the flags and return the index
2478   breakpoint_update_flags();
2479   return rp->m_index;
2480}
2481
2482
2483//-------------------------------------------------
2484//  registerpoint_clear - clear a registerpoint by index,
2485//  returning true if we found it
2486//-------------------------------------------------
2487
2488bool device_debug::registerpoint_clear(int index)
2489{
2490   // scan the list to see if we own this registerpoint
2491   for (registerpoint **rp = &m_rplist; *rp != NULL; rp = &(*rp)->m_next)
2492      if ((*rp)->m_index == index)
2493      {
2494         registerpoint *deleteme = *rp;
2495         *rp = deleteme->m_next;
2496         auto_free(m_device.machine(), deleteme);
2497         breakpoint_update_flags();
2498         return true;
2499      }
2500
2501   // we don't own it, return false
2502   return false;
2503}
2504
2505
2506//-------------------------------------------------
2507//  registerpoint_clear_all - clear all registerpoints
2508//-------------------------------------------------
2509
2510void device_debug::registerpoint_clear_all()
2511{
2512   // clear the head until we run out
2513   while (m_rplist != NULL)
2514      registerpoint_clear(m_rplist->index());
2515}
2516
2517
2518//-------------------------------------------------
2519//  registerpoint_enable - enable/disable a registerpoint
2520//  by index, returning true if we found it
2521//-------------------------------------------------
2522
2523bool device_debug::registerpoint_enable(int index, bool enable)
2524{
2525   // scan the list to see if we own this conditionpoint
2526   for (registerpoint *rp = m_rplist; rp != NULL; rp = rp->next())
2527      if (rp->m_index == index)
2528      {
2529         rp->m_enabled = enable;
2530         breakpoint_update_flags();
2531         return true;
2532      }
2533
2534   // we don't own it, return false
2535   return false;
2536}
2537
2538
2539//-------------------------------------------------
2540//  registerpoint_enable_all - enable/disable all
2541//  registerpoints
2542//-------------------------------------------------
2543
2544void device_debug::registerpoint_enable_all(bool enable)
2545{
2546   // apply the enable to all registerpoints we own
2547   for (registerpoint *rp = m_rplist; rp != NULL; rp = rp->next())
2548      registerpoint_enable(rp->index(), enable);
2549}
2550
2551
2552//-------------------------------------------------
24602553//  hotspot_track - enable/disable tracking of
24612554//  hotspots
24622555//-------------------------------------------------
r21806r21807
28242917         break;
28252918      }
28262919
2920   if ( ! ( m_flags & DEBUG_FLAG_LIVE_BP ) )
2921   {
2922      // see if there are any enabled registerpoints
2923      for (registerpoint *rp = m_rplist; rp != NULL; rp = rp->m_next)
2924      {
2925         if (rp->m_enabled)
2926         {
2927            m_flags |= DEBUG_FLAG_LIVE_BP;
2928         }
2929      }
2930   }
2931
28272932   // push the flags out globally
28282933   debugcpu_private *global = m_device.machine().debugcpu_data;
28292934   if (global->livecpu != NULL)
r21806r21807
28552960            debug_console_printf(m_device.machine(), "Stopped at breakpoint %X\n", bp->m_index);
28562961         break;
28572962      }
2963
2964   // see if we have any matching registerpoints
2965   for (registerpoint *rp = m_rplist; rp != NULL; rp = rp->m_next)
2966   {
2967      if (rp->hit())
2968      {
2969         // halt in the debugger by default
2970         debugcpu_private *global = m_device.machine().debugcpu_data;
2971         global->execution_state = EXECUTION_STATE_STOPPED;
2972
2973         // if we hit, evaluate the action
2974         if (rp->m_action)
2975         {
2976            debug_console_execute_command(m_device.machine(), rp->m_action, 0);
2977         }
2978
2979         // print a notification, unless the action made us go again
2980         if (global->execution_state == EXECUTION_STATE_STOPPED)
2981         {
2982            debug_console_printf(m_device.machine(), "Stopped at registerpoint %X\n", rp->m_index);
2983         }
2984         break;
2985      }
2986   }
28582987}
28592988
28602989
r21806r21807
32573386
32583387
32593388//**************************************************************************
3389//  DEBUG REGISTERPOINT
3390//**************************************************************************
3391
3392//-------------------------------------------------
3393//  registerpoint - constructor
3394//-------------------------------------------------
3395
3396device_debug::registerpoint::registerpoint(symbol_table &symbols, int index, const char *condition, const char *action)
3397   : m_next(NULL),
3398      m_index(index),
3399      m_enabled(true),
3400      m_condition(&symbols, (condition != NULL) ? condition : "1"),
3401      m_action((action != NULL) ? action : "")
3402{
3403}
3404
3405
3406//-------------------------------------------------
3407//  hit - detect a hit
3408//-------------------------------------------------
3409
3410bool device_debug::registerpoint::hit()
3411{
3412   // don't hit if disabled
3413   if (!m_enabled)
3414      return false;
3415
3416   // must satisfy the condition
3417   if (!m_condition.is_empty())
3418   {
3419      try
3420      {
3421         return (m_condition.execute() != 0);
3422      }
3423      catch (expression_error &)
3424      {
3425         return false;
3426      }
3427   }
3428
3429   return true;
3430}
3431
3432
3433
3434//**************************************************************************
32603435//  TRACER
32613436//**************************************************************************
32623437
trunk/src/emu/debug/debugcpu.h
r21806r21807
136136      astring             m_action;                   // action
137137   };
138138
139   // registerpoint class
140   class registerpoint
141   {
142      friend class device_debug;
143
144   public:
145      // construction/destruction
146      registerpoint(symbol_table &symbols, int index, const char *condition, const char *action = NULL);
147
148      // getters
149      registerpoint *next() const { return m_next; }
150      int index() const { return m_index; }
151      bool enabled() const { return m_enabled; }
152      const char *condition() const { return m_condition.original_string(); }
153      const char *action() const { return m_action; }
154
155   private:
156      // internals
157      bool hit();
158
159      registerpoint *    m_next;                     // next in the list
160      int                 m_index;                    // user reported index
161      UINT8               m_enabled;                  // enabled?
162      parsed_expression   m_condition;                // condition
163      astring             m_action;                   // action
164   };
165
139166public:
140167   // construction/destruction
141168   device_debug(device_t &device);
r21806r21807
200227   bool watchpoint_enable(int index, bool enable = true);
201228   void watchpoint_enable_all(bool enable = true);
202229
230   // registerpoints
231   registerpoint *registerpoint_first() const { return m_rplist; }
232   int registerpoint_set(const char *condition, const char *action = NULL);
233   bool registerpoint_clear(int index);
234   void registerpoint_clear_all();
235   bool registerpoint_enable(int index, bool enable = true);
236   void registerpoint_enable_all(bool enable = true );
237
203238   // hotspots
204239   bool hotspot_tracking_enabled() const { return (m_hotspots != NULL); }
205240   void hotspot_track(int numspots, int threshhold);
r21806r21807
286321   // breakpoints and watchpoints
287322   breakpoint *            m_bplist;                   // list of breakpoints
288323   watchpoint *            m_wplist[ADDRESS_SPACES];   // watchpoint lists for each address space
324   registerpoint *         m_rplist;                   // list of registerpoints
289325
290326   // tracing
291327   class tracer
trunk/src/emu/debug/debugcmd.c
r21806r21807
124124static void execute_wpclear(running_machine &machine, int ref, int params, const char **param);
125125static void execute_wpdisenable(running_machine &machine, int ref, int params, const char **param);
126126static void execute_wplist(running_machine &machine, int ref, int params, const char **param);
127static void execute_rpset(running_machine &machine, int ref, int params, const char **param);
128static void execute_rpclear(running_machine &machine, int ref, int params, const char **param);
129static void execute_rpdisenable(running_machine &machine, int ref, int params, const char **param);
130static void execute_rplist(running_machine &machine, int ref, int params, const char **param);
127131static void execute_hotspot(running_machine &machine, int ref, int params, const char **param);
128132static void execute_save(running_machine &machine, int ref, int params, const char **param);
129133static void execute_load(running_machine &machine, int ref, int params, const char **param);
r21806r21807
266270   debug_console_register_command(machine, "logerror",  CMDFLAG_NONE, 0, 1, MAX_COMMAND_PARAMS, execute_logerror);
267271   debug_console_register_command(machine, "tracelog",  CMDFLAG_NONE, 0, 1, MAX_COMMAND_PARAMS, execute_tracelog);
268272   debug_console_register_command(machine, "quit",      CMDFLAG_NONE, 0, 0, 0, execute_quit);
273   debug_console_register_command(machine, "exit",      CMDFLAG_NONE, 0, 0, 0, execute_quit);
269274   debug_console_register_command(machine, "do",        CMDFLAG_NONE, 0, 1, 1, execute_do);
270275   debug_console_register_command(machine, "step",      CMDFLAG_NONE, 0, 0, 1, execute_step);
271276   debug_console_register_command(machine, "s",         CMDFLAG_NONE, 0, 0, 1, execute_step);
r21806r21807
309314   debug_console_register_command(machine, "wpenable",  CMDFLAG_NONE, 1, 0, 1, execute_wpdisenable);
310315   debug_console_register_command(machine, "wplist",    CMDFLAG_NONE, 0, 0, 0, execute_wplist);
311316
317   debug_console_register_command(machine, "rpset",     CMDFLAG_NONE, 0, 1, 2, execute_rpset);
318   debug_console_register_command(machine, "rp",        CMDFLAG_NONE, 0, 1, 2, execute_rpset);
319   debug_console_register_command(machine, "rpclear",   CMDFLAG_NONE, 0, 0, 1, execute_rpclear);
320   debug_console_register_command(machine, "rpdisable", CMDFLAG_NONE, 0, 0, 1, execute_rpdisenable);
321   debug_console_register_command(machine, "rpenable",  CMDFLAG_NONE, 1, 0, 1, execute_rpdisenable);
322   debug_console_register_command(machine, "rplist",    CMDFLAG_NONE, 0, 0, 0, execute_rplist);
323
312324   debug_console_register_command(machine, "hotspot",   CMDFLAG_NONE, 0, 0, 3, execute_hotspot);
313325
314326   debug_console_register_command(machine, "save",      CMDFLAG_NONE, AS_PROGRAM, 3, 4, execute_save);
r21806r21807
14881500
14891501
14901502/*-------------------------------------------------
1503    execute_rpset - execute the registerpoint set
1504    command
1505-------------------------------------------------*/
1506
1507static void execute_rpset(running_machine &machine, int ref, int params, const char *param[])
1508{
1509   device_t *cpu;
1510   const char *action = NULL;
1511   int bpnum;
1512
1513   /* CPU is implicit */
1514   if (!debug_command_parameter_cpu(machine, NULL, &cpu))
1515      return;
1516
1517   /* param 1 is the condition */
1518   parsed_expression condition(&cpu->debug()->symtable());
1519   if (!debug_command_parameter_expression(machine, param[0], condition))
1520      return;
1521
1522   /* param 2 is the action */
1523   if (!debug_command_parameter_command(machine, action = param[1]))
1524      return;
1525
1526   /* set the breakpoint */
1527   bpnum = cpu->debug()->registerpoint_set(condition.original_string(), action);
1528   debug_console_printf(machine, "Registerpoint %X set\n", bpnum);
1529}
1530
1531
1532/*-------------------------------------------------
1533    execute_rpclear - execute the registerpoint
1534    clear command
1535-------------------------------------------------*/
1536
1537static void execute_rpclear(running_machine &machine, int ref, int params, const char *param[])
1538{
1539   UINT64 rpindex;
1540
1541   /* if 0 parameters, clear all */
1542   if (params == 0)
1543   {
1544      device_iterator iter(machine.root_device());
1545      for (device_t *device = iter.first(); device != NULL; device = iter.next())
1546         device->debug()->registerpoint_clear_all();
1547      debug_console_printf(machine, "Cleared all registerpoints\n");
1548   }
1549
1550   /* otherwise, clear the specific one */
1551   else if (!debug_command_parameter_number(machine, param[0], &rpindex))
1552      return;
1553   else
1554   {
1555      device_iterator iter(machine.root_device());
1556      bool found = false;
1557      for (device_t *device = iter.first(); device != NULL; device = iter.next())
1558         if (device->debug()->registerpoint_clear(rpindex))
1559            found = true;
1560      if (found)
1561         debug_console_printf(machine, "Registerpoint %X cleared\n", (UINT32)rpindex);
1562      else
1563         debug_console_printf(machine, "Invalid registerpoint number %X\n", (UINT32)rpindex);
1564   }
1565}
1566
1567
1568/*-------------------------------------------------
1569    execute_rpdisenable - execute the registerpoint
1570    disable/enable commands
1571-------------------------------------------------*/
1572
1573static void execute_rpdisenable(running_machine &machine, int ref, int params, const char *param[])
1574{
1575   UINT64 rpindex;
1576
1577   /* if 0 parameters, clear all */
1578   if (params == 0)
1579   {
1580      device_iterator iter(machine.root_device());
1581      for (device_t *device = iter.first(); device != NULL; device = iter.next())
1582         device->debug()->registerpoint_enable_all(ref);
1583      if (ref == 0)
1584         debug_console_printf(machine, "Disabled all registerpoints\n");
1585      else
1586         debug_console_printf(machine, "Enabled all registeroints\n");
1587   }
1588
1589   /* otherwise, clear the specific one */
1590   else if (!debug_command_parameter_number(machine, param[0], &rpindex))
1591      return;
1592   else
1593   {
1594      device_iterator iter(machine.root_device());
1595      bool found = false;
1596      for (device_t *device = iter.first(); device != NULL; device = iter.next())
1597         if (device->debug()->registerpoint_enable(rpindex, ref))
1598            found = true;
1599      if (found)
1600         debug_console_printf(machine, "Registerpoint %X %s\n", (UINT32)rpindex, ref ? "enabled" : "disabled");
1601      else
1602         debug_console_printf(machine, "Invalid registerpoint number %X\n", (UINT32)rpindex);
1603   }
1604}
1605
1606
1607/*-------------------------------------------------
1608    execute_rplist - execute the registerpoint list
1609    command
1610-------------------------------------------------*/
1611
1612static void execute_rplist(running_machine &machine, int ref, int params, const char *param[])
1613{
1614   int printed = 0;
1615   astring buffer;
1616
1617   /* loop over all CPUs */
1618   device_iterator iter(machine.root_device());
1619   for (device_t *device = iter.first(); device != NULL; device = iter.next())
1620      if (device->debug()->registerpoint_first() != NULL)
1621      {
1622         debug_console_printf(machine, "Device '%s' registerpoints:\n", device->tag());
1623
1624         /* loop over the breakpoints */
1625         for (device_debug::registerpoint *rp = device->debug()->registerpoint_first(); rp != NULL; rp = rp->next())
1626         {
1627            buffer.printf("%c%4X ", rp->enabled() ? ' ' : 'D', rp->index());
1628            buffer.catprintf("if %s", rp->condition());
1629            if (rp->action() != NULL)
1630               buffer.catprintf(" do %s", rp->action());
1631            debug_console_printf(machine, "%s\n", buffer.cstr());
1632            printed++;
1633         }
1634      }
1635
1636   if (printed == 0)
1637      debug_console_printf(machine, "No registerpoints currently installed\n");
1638}
1639
1640
1641/*-------------------------------------------------
14911642    execute_hotspot - execute the hotspot
14921643    command
14931644-------------------------------------------------*/

Previous 199869 Revisions Next


© 1997-2024 The MAME Team