summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu/debug/debugcmd.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/emu/debug/debugcmd.c')
-rw-r--r--src/emu/debug/debugcmd.c2200
1 files changed, 2200 insertions, 0 deletions
diff --git a/src/emu/debug/debugcmd.c b/src/emu/debug/debugcmd.c
new file mode 100644
index 00000000000..41fe159e064
--- /dev/null
+++ b/src/emu/debug/debugcmd.c
@@ -0,0 +1,2200 @@
+/*********************************************************************
+
+ debugcmd.h
+
+ Debugger command interface engine.
+
+ Copyright (c) 1996-2007, Nicola Salmoria and the MAME Team.
+ Visit http://mamedev.org for licensing and usage restrictions.
+
+*********************************************************************/
+
+#include "driver.h"
+#include "debugcmd.h"
+#include "debugcmt.h"
+#include "debugcon.h"
+#include "debugcpu.h"
+#include "express.h"
+#include "debughlp.h"
+#include "debugvw.h"
+#include "render.h"
+#include <stdarg.h>
+#include <ctype.h>
+
+
+
+/***************************************************************************
+ CONSTANTS
+***************************************************************************/
+
+#define MAX_GLOBALS 1000
+
+
+
+/***************************************************************************
+ GLOBAL VARIABLES
+***************************************************************************/
+
+static struct
+{
+ void * base;
+ UINT32 size;
+} global_array[MAX_GLOBALS];
+
+
+
+/***************************************************************************
+ FUNCTION PROTOTYPES
+***************************************************************************/
+
+static void debug_command_exit(running_machine *machine);
+
+static UINT64 execute_min(UINT32 ref, UINT32 params, UINT64 *param);
+static UINT64 execute_max(UINT32 ref, UINT32 params, UINT64 *param);
+static UINT64 execute_if(UINT32 ref, UINT32 params, UINT64 *param);
+
+static UINT64 global_get(UINT32 ref);
+static void global_set(UINT32 ref, UINT64 value);
+
+static void execute_help(int ref, int params, const char **param);
+static void execute_print(int ref, int params, const char **param);
+static void execute_printf(int ref, int params, const char **param);
+static void execute_logerror(int ref, int params, const char **param);
+static void execute_tracelog(int ref, int params, const char **param);
+static void execute_quit(int ref, int params, const char **param);
+static void execute_do(int ref, int params, const char **param);
+static void execute_step(int ref, int params, const char **param);
+static void execute_over(int ref, int params, const char **param);
+static void execute_out(int ref, int params, const char **param);
+static void execute_go(int ref, int params, const char **param);
+static void execute_go_vblank(int ref, int params, const char **param);
+static void execute_go_interrupt(int ref, int params, const char **param);
+static void execute_go_time(int ref, int params, const char *param[]);
+static void execute_focus(int ref, int params, const char **param);
+static void execute_ignore(int ref, int params, const char **param);
+static void execute_observe(int ref, int params, const char **param);
+static void execute_next(int ref, int params, const char **param);
+static void execute_comment(int ref, int params, const char **param);
+static void execute_comment_del(int ref, int params, const char **param);
+static void execute_comment_save(int ref, int params, const char **param);
+static void execute_bpset(int ref, int params, const char **param);
+static void execute_bpclear(int ref, int params, const char **param);
+static void execute_bpdisenable(int ref, int params, const char **param);
+static void execute_bplist(int ref, int params, const char **param);
+static void execute_wpset(int ref, int params, const char **param);
+static void execute_wpclear(int ref, int params, const char **param);
+static void execute_wpdisenable(int ref, int params, const char **param);
+static void execute_wplist(int ref, int params, const char **param);
+static void execute_hotspot(int ref, int params, const char **param);
+static void execute_save(int ref, int params, const char **param);
+static void execute_dump(int ref, int params, const char **param);
+static void execute_dasm(int ref, int params, const char **param);
+static void execute_find(int ref, int params, const char **param);
+static void execute_trace(int ref, int params, const char **param);
+static void execute_traceover(int ref, int params, const char **param);
+static void execute_traceflush(int ref, int params, const char **param);
+static void execute_history(int ref, int params, const char **param);
+static void execute_snap(int ref, int params, const char **param);
+static void execute_source(int ref, int params, const char **param);
+static void execute_map(int ref, int params, const char **param);
+static void execute_memdump(int ref, int params, const char **param);
+static void execute_symlist(int ref, int params, const char **param);
+static void execute_softreset(int ref, int params, const char **param);
+static void execute_hardreset(int ref, int params, const char **param);
+
+
+
+/***************************************************************************
+
+ Initialization
+
+***************************************************************************/
+
+/*-------------------------------------------------
+ debug_command_init - initializes the command
+ system
+-------------------------------------------------*/
+
+void debug_command_init(running_machine *machine)
+{
+ int cpunum, itemnum;
+ const char *name;
+
+ /* add a few simple global functions */
+ symtable_add_function(global_symtable, "min", 0, 2, 2, execute_min);
+ symtable_add_function(global_symtable, "max", 0, 2, 2, execute_max);
+ symtable_add_function(global_symtable, "if", 0, 3, 3, execute_if);
+
+ /* add all single-entry save state globals */
+ for (itemnum = 0; itemnum < MAX_GLOBALS; itemnum++)
+ {
+ UINT32 valsize, valcount;
+ void *base;
+
+ /* stop when we run out of items */
+ name = state_save_get_indexed_item(itemnum, &base, &valsize, &valcount);
+ if (name == NULL)
+ break;
+
+ /* if this is a single-entry global, add it */
+ if (valcount == 1 && strstr(name, "/globals/"))
+ {
+ char symname[100];
+ sprintf(symname, ".%s", strrchr(name, '/') + 1);
+ global_array[itemnum].base = base;
+ global_array[itemnum].size = valsize;
+ symtable_add_register(global_symtable, symname, itemnum, global_get, global_set);
+ }
+ }
+
+ /* add all the commands */
+ debug_console_register_command("help", CMDFLAG_NONE, 0, 0, 1, execute_help);
+ debug_console_register_command("print", CMDFLAG_NONE, 0, 1, MAX_COMMAND_PARAMS, execute_print);
+ debug_console_register_command("printf", CMDFLAG_NONE, 0, 1, MAX_COMMAND_PARAMS, execute_printf);
+ debug_console_register_command("logerror", CMDFLAG_NONE, 0, 1, MAX_COMMAND_PARAMS, execute_logerror);
+ debug_console_register_command("tracelog", CMDFLAG_NONE, 0, 1, MAX_COMMAND_PARAMS, execute_tracelog);
+ debug_console_register_command("quit", CMDFLAG_NONE, 0, 0, 0, execute_quit);
+ debug_console_register_command("do", CMDFLAG_NONE, 0, 1, 1, execute_do);
+ debug_console_register_command("step", CMDFLAG_NONE, 0, 0, 1, execute_step);
+ debug_console_register_command("s", CMDFLAG_NONE, 0, 0, 1, execute_step);
+ debug_console_register_command("over", CMDFLAG_NONE, 0, 0, 1, execute_over);
+ debug_console_register_command("o", CMDFLAG_NONE, 0, 0, 1, execute_over);
+ debug_console_register_command("out" , CMDFLAG_NONE, 0, 0, 0, execute_out);
+ debug_console_register_command("go", CMDFLAG_NONE, 0, 0, 1, execute_go);
+ debug_console_register_command("g", CMDFLAG_NONE, 0, 0, 1, execute_go);
+ debug_console_register_command("gvblank", CMDFLAG_NONE, 0, 0, 0, execute_go_vblank);
+ debug_console_register_command("gv", CMDFLAG_NONE, 0, 0, 0, execute_go_vblank);
+ debug_console_register_command("gint", CMDFLAG_NONE, 0, 0, 1, execute_go_interrupt);
+ debug_console_register_command("gi", CMDFLAG_NONE, 0, 0, 1, execute_go_interrupt);
+ debug_console_register_command("gtime", CMDFLAG_NONE, 0, 0, 1, execute_go_time);
+ debug_console_register_command("gt", CMDFLAG_NONE, 0, 0, 1, execute_go_time);
+ debug_console_register_command("next", CMDFLAG_NONE, 0, 0, 0, execute_next);
+ debug_console_register_command("n", CMDFLAG_NONE, 0, 0, 0, execute_next);
+ debug_console_register_command("focus", CMDFLAG_NONE, 0, 1, 1, execute_focus);
+ debug_console_register_command("ignore", CMDFLAG_NONE, 0, 0, MAX_COMMAND_PARAMS, execute_ignore);
+ debug_console_register_command("observe", CMDFLAG_NONE, 0, 0, MAX_COMMAND_PARAMS, execute_observe);
+
+ debug_console_register_command("comadd", CMDFLAG_NONE, 0, 1, 2, execute_comment);
+ debug_console_register_command("//", CMDFLAG_NONE, 0, 1, 2, execute_comment);
+ debug_console_register_command("comdelete", CMDFLAG_NONE, 0, 1, 1, execute_comment_del);
+ debug_console_register_command("comsave", CMDFLAG_NONE, 0, 0, 0, execute_comment_save);
+
+ debug_console_register_command("bpset", CMDFLAG_NONE, 0, 1, 3, execute_bpset);
+ debug_console_register_command("bp", CMDFLAG_NONE, 0, 1, 3, execute_bpset);
+ debug_console_register_command("bpclear", CMDFLAG_NONE, 0, 0, 1, execute_bpclear);
+ debug_console_register_command("bpdisable", CMDFLAG_NONE, 0, 0, 1, execute_bpdisenable);
+ debug_console_register_command("bpenable", CMDFLAG_NONE, 1, 0, 1, execute_bpdisenable);
+ debug_console_register_command("bplist", CMDFLAG_NONE, 0, 0, 0, execute_bplist);
+
+ debug_console_register_command("wpset", CMDFLAG_NONE, ADDRESS_SPACE_PROGRAM, 3, 5, execute_wpset);
+ debug_console_register_command("wp", CMDFLAG_NONE, ADDRESS_SPACE_PROGRAM, 3, 5, execute_wpset);
+ debug_console_register_command("wpdset", CMDFLAG_NONE, ADDRESS_SPACE_DATA, 3, 5, execute_wpset);
+ debug_console_register_command("wpd", CMDFLAG_NONE, ADDRESS_SPACE_DATA, 3, 5, execute_wpset);
+ debug_console_register_command("wpiset", CMDFLAG_NONE, ADDRESS_SPACE_IO, 3, 5, execute_wpset);
+ debug_console_register_command("wpi", CMDFLAG_NONE, ADDRESS_SPACE_IO, 3, 5, execute_wpset);
+ debug_console_register_command("wpclear", CMDFLAG_NONE, 0, 0, 1, execute_wpclear);
+ debug_console_register_command("wpdisable", CMDFLAG_NONE, 0, 0, 1, execute_wpdisenable);
+ debug_console_register_command("wpenable", CMDFLAG_NONE, 1, 0, 1, execute_wpdisenable);
+ debug_console_register_command("wplist", CMDFLAG_NONE, 0, 0, 0, execute_wplist);
+
+ debug_console_register_command("hotspot", CMDFLAG_NONE, 0, 0, 3, execute_hotspot);
+
+ debug_console_register_command("save", CMDFLAG_NONE, ADDRESS_SPACE_PROGRAM, 3, 4, execute_save);
+ debug_console_register_command("saved", CMDFLAG_NONE, ADDRESS_SPACE_DATA, 3, 4, execute_save);
+ debug_console_register_command("savei", CMDFLAG_NONE, ADDRESS_SPACE_IO, 3, 4, execute_save);
+
+ debug_console_register_command("dump", CMDFLAG_NONE, ADDRESS_SPACE_PROGRAM, 3, 6, execute_dump);
+ debug_console_register_command("dumpd", CMDFLAG_NONE, ADDRESS_SPACE_DATA, 3, 6, execute_dump);
+ debug_console_register_command("dumpi", CMDFLAG_NONE, ADDRESS_SPACE_IO, 3, 6, execute_dump);
+
+ debug_console_register_command("f", CMDFLAG_KEEP_QUOTES, ADDRESS_SPACE_PROGRAM, 3, MAX_COMMAND_PARAMS, execute_find);
+ debug_console_register_command("find", CMDFLAG_KEEP_QUOTES, ADDRESS_SPACE_PROGRAM, 3, MAX_COMMAND_PARAMS, execute_find);
+ debug_console_register_command("fd", CMDFLAG_KEEP_QUOTES, ADDRESS_SPACE_DATA, 3, MAX_COMMAND_PARAMS, execute_find);
+ debug_console_register_command("findd", CMDFLAG_KEEP_QUOTES, ADDRESS_SPACE_DATA, 3, MAX_COMMAND_PARAMS, execute_find);
+ debug_console_register_command("fi", CMDFLAG_KEEP_QUOTES, ADDRESS_SPACE_IO, 3, MAX_COMMAND_PARAMS, execute_find);
+ debug_console_register_command("findi", CMDFLAG_KEEP_QUOTES, ADDRESS_SPACE_IO, 3, MAX_COMMAND_PARAMS, execute_find);
+
+ debug_console_register_command("dasm", CMDFLAG_NONE, 0, 3, 5, execute_dasm);
+
+ debug_console_register_command("trace", CMDFLAG_NONE, 0, 1, 3, execute_trace);
+ debug_console_register_command("traceover", CMDFLAG_NONE, 0, 1, 3, execute_traceover);
+ debug_console_register_command("traceflush",CMDFLAG_NONE, 0, 0, 0, execute_traceflush);
+
+ debug_console_register_command("history", CMDFLAG_NONE, 0, 0, 2, execute_history);
+
+ debug_console_register_command("snap", CMDFLAG_NONE, 0, 0, 1, execute_snap);
+
+ debug_console_register_command("source", CMDFLAG_NONE, 0, 1, 1, execute_source);
+
+ debug_console_register_command("map", CMDFLAG_NONE, ADDRESS_SPACE_PROGRAM, 1, 1, execute_map);
+ debug_console_register_command("mapd", CMDFLAG_NONE, ADDRESS_SPACE_DATA, 1, 1, execute_map);
+ debug_console_register_command("mapi", CMDFLAG_NONE, ADDRESS_SPACE_IO, 1, 1, execute_map);
+ debug_console_register_command("memdump", CMDFLAG_NONE, 0, 0, 1, execute_memdump);
+
+ debug_console_register_command("symlist", CMDFLAG_NONE, 0, 0, 1, execute_symlist);
+
+ debug_console_register_command("softreset", CMDFLAG_NONE, 0, 0, 1, execute_softreset);
+ debug_console_register_command("hardreset", CMDFLAG_NONE, 0, 0, 1, execute_hardreset);
+
+ /* ask all the CPUs if they would like to register functions or symbols */
+ for (cpunum = 0; cpunum < cpu_gettotalcpu(); cpunum++)
+ {
+ void (*setup_commands)(void);
+ setup_commands = cpunum_get_info_fct(cpunum, CPUINFO_PTR_DEBUG_SETUP_COMMANDS);
+ if (setup_commands)
+ setup_commands();
+ }
+
+ add_exit_callback(machine, debug_command_exit);
+
+ /* set up the initial debugscript if specified */
+ name = options_get_string(mame_options(), OPTION_DEBUGSCRIPT);
+ if (name[0] != 0)
+ debug_source_script(name);
+}
+
+
+/*-------------------------------------------------
+ debug_command_exit - exit-time cleanup
+-------------------------------------------------*/
+
+static void debug_command_exit(running_machine *machine)
+{
+ int cpunum;
+
+ /* turn off all traces */
+ for (cpunum = 0; cpunum < cpu_gettotalcpu(); cpunum++)
+ debug_cpu_trace(cpunum, NULL, 0, NULL);
+}
+
+
+
+/***************************************************************************
+
+ Simple Global Functions
+
+***************************************************************************/
+
+/*-------------------------------------------------
+ execute_min - return the minimum of two values
+-------------------------------------------------*/
+
+static UINT64 execute_min(UINT32 ref, UINT32 params, UINT64 *param)
+{
+ return (param[0] < param[1]) ? param[0] : param[1];
+}
+
+
+/*-------------------------------------------------
+ execute_max - return the maximum of two values
+-------------------------------------------------*/
+
+static UINT64 execute_max(UINT32 ref, UINT32 params, UINT64 *param)
+{
+ return (param[0] > param[1]) ? param[0] : param[1];
+}
+
+
+/*-------------------------------------------------
+ execute_if - if (a) return b; else return c;
+-------------------------------------------------*/
+
+static UINT64 execute_if(UINT32 ref, UINT32 params, UINT64 *param)
+{
+ return param[0] ? param[1] : param[2];
+}
+
+
+
+/***************************************************************************
+
+ Global accessors
+
+***************************************************************************/
+
+/*-------------------------------------------------
+ global_get - symbol table getter for globals
+-------------------------------------------------*/
+
+static UINT64 global_get(UINT32 ref)
+{
+ assert(ref < MAX_GLOBALS);
+ switch (global_array[ref].size)
+ {
+ case 1: return *(UINT8 *)global_array[ref].base;
+ case 2: return *(UINT16 *)global_array[ref].base;
+ case 4: return *(UINT32 *)global_array[ref].base;
+ case 8: return *(UINT64 *)global_array[ref].base;
+ }
+ return ~0;
+}
+
+
+/*-------------------------------------------------
+ global_set - symbol table setter for globals
+-------------------------------------------------*/
+
+static void global_set(UINT32 ref, UINT64 value)
+{
+ assert(ref < MAX_GLOBALS);
+ switch (global_array[ref].size)
+ {
+ case 1: *(UINT8 *)global_array[ref].base = value; break;
+ case 2: *(UINT16 *)global_array[ref].base = value; break;
+ case 4: *(UINT32 *)global_array[ref].base = value; break;
+ case 8: *(UINT64 *)global_array[ref].base = value; break;
+ }
+}
+
+
+
+/***************************************************************************
+
+ Parameter Validation Helpers
+
+***************************************************************************/
+
+/*-------------------------------------------------
+ debug_command_parameter_number - validates a
+ number parameter
+-------------------------------------------------*/
+
+int debug_command_parameter_number(const char *param, UINT64 *result)
+{
+ EXPRERR err = expression_evaluate(param, debug_get_cpu_info(cpu_getactivecpu())->symtable, result);
+ if (err == EXPRERR_NONE)
+ return 1;
+ debug_console_printf("Error in expression: %s\n", param);
+ debug_console_printf(" %*s^", EXPRERR_ERROR_OFFSET(err), "");
+ debug_console_printf("%s\n", exprerr_to_string(err));
+ return 0;
+}
+
+
+/*-------------------------------------------------
+ debug_command_parameter_expression - validates
+ an expression parameter
+-------------------------------------------------*/
+
+static int debug_command_parameter_expression(const char *param, parsed_expression **result)
+{
+ EXPRERR err = expression_parse(param, debug_get_cpu_info(cpu_getactivecpu())->symtable, result);
+ if (err == EXPRERR_NONE)
+ return 1;
+ debug_console_printf("Error in expression: %s\n", param);
+ debug_console_printf(" %*s^", EXPRERR_ERROR_OFFSET(err), "");
+ debug_console_printf("%s\n", exprerr_to_string(err));
+ return 0;
+}
+
+
+/*-------------------------------------------------
+ debug_command_parameter_command - validates a
+ command parameter
+-------------------------------------------------*/
+
+static int debug_command_parameter_command(const char *param)
+{
+ CMDERR err = debug_console_validate_command(param);
+ if (err == CMDERR_NONE)
+ return 1;
+ debug_console_printf("Error in command: %s\n", param);
+ debug_console_printf(" %*s^", CMDERR_ERROR_OFFSET(err), "");
+ debug_console_printf("%s\n", debug_cmderr_to_string(err));
+ return 0;
+}
+
+
+
+/***************************************************************************
+
+ Command Helpers
+
+***************************************************************************/
+
+/*-------------------------------------------------
+ execute_help - execute the help command
+-------------------------------------------------*/
+
+static void execute_help(int ref, int params, const char *param[])
+{
+ if (params == 0)
+ debug_console_printf_wrap(80, "%s\n", debug_get_help(""));
+ else
+ debug_console_printf_wrap(80, "%s\n", debug_get_help(param[0]));
+}
+
+
+/*-------------------------------------------------
+ execute_print - execute the print command
+-------------------------------------------------*/
+
+static void execute_print(int ref, int params, const char *param[])
+{
+ UINT64 values[MAX_COMMAND_PARAMS];
+ int i;
+
+ /* validate the other parameters */
+ for (i = 0; i < params; i++)
+ if (!debug_command_parameter_number(param[i], &values[i]))
+ return;
+
+ /* then print each one */
+ for (i = 0; i < params; i++)
+ {
+ if ((values[i] >> 32) != 0)
+ debug_console_printf("%X%08X ", (UINT32)(values[i] >> 32), (UINT32)values[i]);
+ else
+ debug_console_printf("%X ", (UINT32)values[i]);
+ }
+ debug_console_printf("\n");
+}
+
+
+/*-------------------------------------------------
+ mini_printf - safe printf to a buffer
+-------------------------------------------------*/
+
+static int mini_printf(char *buffer, const char *format, int params, UINT64 *param)
+{
+ const char *f = format;
+ char *p = buffer;
+
+ /* parse the string looking for % signs */
+ for (;;)
+ {
+ char c = *f++;
+ if (!c) break;
+
+ /* escape sequences */
+ if (c == '\\')
+ {
+ c = *f++;
+ if (!c) break;
+ switch (c)
+ {
+ case '\\': *p++ = c; break;
+ case 'n': *p++ = '\n'; break;
+ default: break;
+ }
+ continue;
+ }
+
+ /* formatting */
+ else if (c == '%')
+ {
+ int width = 0;
+ int zerofill = 0;
+
+ /* parse out the width */
+ for (;;)
+ {
+ c = *f++;
+ if (!c || c < '0' || c > '9') break;
+ if (c == '0' && width == 0)
+ zerofill = 1;
+ width = width * 10 + (c - '0');
+ }
+ if (!c) break;
+
+ /* get the format */
+ switch (c)
+ {
+ case '%':
+ *p++ = c;
+ break;
+
+ case 'X':
+ case 'x':
+ if (params == 0)
+ {
+ debug_console_printf("Not enough parameters for format!\n");
+ return 0;
+ }
+ if ((UINT32)(*param >> 32) != 0)
+ p += sprintf(p, zerofill ? "%0*X" : "%*X", (width <= 8) ? 1 : width - 8, (UINT32)(*param >> 32));
+ else if (width > 8)
+ p += sprintf(p, zerofill ? "%0*X" : "%*X", width - 8, 0);
+ p += sprintf(p, zerofill ? "%0*X" : "%*X", (width < 8) ? width : 8, (UINT32)*param);
+ param++;
+ params--;
+ break;
+
+ case 'D':
+ case 'd':
+ if (params == 0)
+ {
+ debug_console_printf("Not enough parameters for format!\n");
+ return 0;
+ }
+ p += sprintf(p, zerofill ? "%0*d" : "%*d", width, (UINT32)*param);
+ param++;
+ params--;
+ break;
+ }
+ }
+
+ /* normal stuff */
+ else
+ *p++ = c;
+ }
+
+ /* NULL-terminate and exit */
+ *p = 0;
+ return 1;
+}
+
+
+/*-------------------------------------------------
+ execute_printf - execute the printf command
+-------------------------------------------------*/
+
+static void execute_printf(int ref, int params, const char *param[])
+{
+ UINT64 values[MAX_COMMAND_PARAMS];
+ char buffer[1024];
+ int i;
+
+ /* validate the other parameters */
+ for (i = 1; i < params; i++)
+ if (!debug_command_parameter_number(param[i], &values[i]))
+ return;
+
+ /* then do a printf */
+ if (mini_printf(buffer, param[0], params - 1, &values[1]))
+ debug_console_printf("%s\n", buffer);
+}
+
+
+/*-------------------------------------------------
+ execute_logerror - execute the logerror command
+-------------------------------------------------*/
+
+static void execute_logerror(int ref, int params, const char *param[])
+{
+ UINT64 values[MAX_COMMAND_PARAMS];
+ char buffer[1024];
+ int i;
+
+ /* validate the other parameters */
+ for (i = 1; i < params; i++)
+ if (!debug_command_parameter_number(param[i], &values[i]))
+ return;
+
+ /* then do a printf */
+ if (mini_printf(buffer, param[0], params - 1, &values[1]))
+ logerror("%s", buffer);
+}
+
+
+/*-------------------------------------------------
+ execute_tracelog - execute the tracelog command
+-------------------------------------------------*/
+
+static void execute_tracelog(int ref, int params, const char *param[])
+{
+ FILE *file = debug_get_cpu_info(cpu_getactivecpu())->trace.file;
+ UINT64 values[MAX_COMMAND_PARAMS];
+ char buffer[1024];
+ int i;
+
+ /* if no tracefile, skip */
+ if (!file)
+ return;
+
+ /* validate the other parameters */
+ for (i = 1; i < params; i++)
+ if (!debug_command_parameter_number(param[i], &values[i]))
+ return;
+
+ /* then do a printf */
+ if (mini_printf(buffer, param[0], params - 1, &values[1]))
+ fprintf(file, "%s", buffer);
+}
+
+
+/*-------------------------------------------------
+ execute_quit - execute the quit command
+-------------------------------------------------*/
+
+static void execute_quit(int ref, int params, const char *param[])
+{
+ mame_printf_error("Exited via the debugger\n");
+ mame_schedule_exit(Machine);
+}
+
+
+/*-------------------------------------------------
+ execute_do - execute the do command
+-------------------------------------------------*/
+
+static void execute_do(int ref, int params, const char *param[])
+{
+ UINT64 dummy;
+ debug_command_parameter_number(param[0], &dummy);
+}
+
+
+/*-------------------------------------------------
+ execute_step - execute the step command
+-------------------------------------------------*/
+
+static void execute_step(int ref, int params, const char *param[])
+{
+ UINT64 steps = 1;
+
+ /* if we have a parameter, use it instead */
+ if (params > 0 && !debug_command_parameter_number(param[0], &steps))
+ return;
+
+ debug_cpu_single_step(steps);
+}
+
+
+/*-------------------------------------------------
+ execute_over - execute the over command
+-------------------------------------------------*/
+
+static void execute_over(int ref, int params, const char *param[])
+{
+ UINT64 steps = 1;
+
+ /* if we have a parameter, use it instead */
+ if (params > 0 && !debug_command_parameter_number(param[0], &steps))
+ return;
+
+ debug_cpu_single_step_over(steps);
+}
+
+
+/*-------------------------------------------------
+ execute_out - execute the out command
+-------------------------------------------------*/
+
+static void execute_out(int ref, int params, const char *param[])
+{
+ debug_cpu_single_step_out();
+}
+
+
+/*-------------------------------------------------
+ execute_go - execute the go command
+-------------------------------------------------*/
+
+static void execute_go(int ref, int params, const char *param[])
+{
+ UINT64 addr = ~0;
+
+ /* if we have a parameter, use it instead */
+ if (params > 0 && !debug_command_parameter_number(param[0], &addr))
+ return;
+
+ debug_cpu_go(addr);
+}
+
+
+/*-------------------------------------------------
+ execute_go_vblank - execute the govblank
+ command
+-------------------------------------------------*/
+
+static void execute_go_vblank(int ref, int params, const char *param[])
+{
+ debug_cpu_go_vblank();
+}
+
+
+/*-------------------------------------------------
+ execute_go_interrupt - execute the goint command
+-------------------------------------------------*/
+
+static void execute_go_interrupt(int ref, int params, const char *param[])
+{
+ UINT64 irqline = -1;
+
+ /* if we have a parameter, use it instead */
+ if (params > 0 && !debug_command_parameter_number(param[0], &irqline))
+ return;
+
+ debug_cpu_go_interrupt(irqline);
+}
+
+
+/*-------------------------------------------------
+ execute_go_time - execute the gtime command
+-------------------------------------------------*/
+
+static void execute_go_time(int ref, int params, const char *param[])
+{
+ UINT64 milliseconds = -1;
+
+ /* if we have a parameter, use it instead */
+ if (params > 0 && !debug_command_parameter_number(param[0], &milliseconds))
+ return;
+
+ debug_cpu_go_milliseconds(milliseconds);
+}
+
+
+/*-------------------------------------------------
+ execute_next - execute the next command
+-------------------------------------------------*/
+
+static void execute_next(int ref, int params, const char *param[])
+{
+ debug_cpu_next_cpu();
+}
+
+
+/*-------------------------------------------------
+ execute_focus - execute the focus command
+-------------------------------------------------*/
+
+static void execute_focus(int ref, int params, const char *param[])
+{
+ UINT64 cpuwhich;
+ int cpunum;
+
+ /* validate params */
+ if (!debug_command_parameter_number(param[0], &cpuwhich))
+ return;
+ if (cpuwhich >= cpu_gettotalcpu())
+ {
+ debug_console_printf("Invalid CPU number!\n");
+ return;
+ }
+
+ /* first clear the ignore flag on the focused CPU */
+ debug_cpu_ignore_cpu(cpuwhich, 0);
+
+ /* then loop over CPUs and set the ignore flags on all other CPUs */
+ for (cpunum = 0; cpunum < MAX_CPU; cpunum++)
+ {
+ const debug_cpu_info *info = debug_get_cpu_info(cpunum);
+ if (info && info->valid && cpunum != cpuwhich)
+ debug_cpu_ignore_cpu(cpunum, 1);
+ }
+ debug_console_printf("Now focused on CPU %d\n", (int)cpuwhich);
+}
+
+
+/*-------------------------------------------------
+ execute_ignore - execute the ignore command
+-------------------------------------------------*/
+
+static void execute_ignore(int ref, int params, const char *param[])
+{
+ UINT64 cpuwhich[MAX_COMMAND_PARAMS];
+ int cpunum, paramnum;
+ char buffer[100];
+ int buflen = 0;
+
+ /* if there are no parameters, dump the ignore list */
+ if (params == 0)
+ {
+ /* loop over all CPUs */
+ for (cpunum = 0; cpunum < MAX_CPU; cpunum++)
+ {
+ const debug_cpu_info *info = debug_get_cpu_info(cpunum);
+
+ /* build up a comma-separated list */
+ if (info && info->valid && info->ignoring)
+ {
+ if (buflen == 0) buflen += sprintf(&buffer[buflen], "Currently ignoring CPU %d", cpunum);
+ else buflen += sprintf(&buffer[buflen], ",%d", cpunum);
+ }
+ }
+
+ /* special message for none */
+ if (buflen == 0)
+ sprintf(&buffer[buflen], "Not currently ignoring any CPUs");
+ debug_console_printf("%s\n", buffer);
+ }
+
+ /* otherwise clear the ignore flag on all requested CPUs */
+ else
+ {
+ /* validate parameters */
+ for (paramnum = 0; paramnum < params; paramnum++)
+ {
+ if (!debug_command_parameter_number(param[paramnum], &cpuwhich[paramnum]))
+ return;
+ if (cpuwhich[paramnum] >= cpu_gettotalcpu())
+ {
+ debug_console_printf("Invalid CPU number! (%d)\n", (int)cpuwhich[paramnum]);
+ return;
+ }
+ }
+
+ /* set the ignore flags */
+ for (paramnum = 0; paramnum < params; paramnum++)
+ {
+ /* make sure this isn't the last live CPU */
+ for (cpunum = 0; cpunum < MAX_CPU; cpunum++)
+ {
+ const debug_cpu_info *info = debug_get_cpu_info(cpunum);
+ if (cpunum != cpuwhich[paramnum] && info && info->valid && !info->ignoring)
+ break;
+ }
+ if (cpunum == MAX_CPU)
+ {
+ debug_console_printf("Can't ignore all CPUs!\n");
+ return;
+ }
+
+ debug_cpu_ignore_cpu(cpuwhich[paramnum], 1);
+ debug_console_printf("Now ignoring CPU %d\n", (int)cpuwhich[paramnum]);
+ }
+ }
+}
+
+
+/*-------------------------------------------------
+ execute_observe - execute the observe command
+-------------------------------------------------*/
+
+static void execute_observe(int ref, int params, const char *param[])
+{
+ UINT64 cpuwhich[MAX_COMMAND_PARAMS];
+ int cpunum, paramnum;
+ char buffer[100];
+ int buflen = 0;
+
+ /* if there are no parameters, dump the ignore list */
+ if (params == 0)
+ {
+ /* loop over all CPUs */
+ for (cpunum = 0; cpunum < MAX_CPU; cpunum++)
+ {
+ const debug_cpu_info *info = debug_get_cpu_info(cpunum);
+
+ /* build up a comma-separated list */
+ if (info && info->valid && !info->ignoring)
+ {
+ if (buflen == 0) buflen += sprintf(&buffer[buflen], "Currently observing CPU %d", cpunum);
+ else buflen += sprintf(&buffer[buflen], ",%d", cpunum);
+ }
+ }
+
+ /* special message for none */
+ if (buflen == 0)
+ buflen += sprintf(&buffer[buflen], "Not currently observing any CPUs");
+ debug_console_printf("%s\n", buffer);
+ }
+
+ /* otherwise set the ignore flag on all requested CPUs */
+ else
+ {
+ /* validate parameters */
+ for (paramnum = 0; paramnum < params; paramnum++)
+ {
+ if (!debug_command_parameter_number(param[paramnum], &cpuwhich[paramnum]))
+ return;
+ if (cpuwhich[paramnum] >= cpu_gettotalcpu())
+ {
+ debug_console_printf("Invalid CPU number! (%d)\n", (int)cpuwhich[paramnum]);
+ return;
+ }
+ }
+
+ /* clear the ignore flags */
+ for (paramnum = 0; paramnum < params; paramnum++)
+ {
+ debug_cpu_ignore_cpu(cpuwhich[paramnum], 0);
+ debug_console_printf("Now observing CPU %d\n", (int)cpuwhich[paramnum]);
+ }
+ }
+}
+
+
+/*-------------------------------------------------
+ execute_comment - add a comment to a line
+-------------------------------------------------*/
+
+static void execute_comment(int ref, int params, const char *param[])
+{
+ UINT64 address;
+
+ /* param 1 is the address for the comment */
+ if (!debug_command_parameter_number(param[0], &address))
+ return;
+
+ /* make sure param 2 exists */
+ if (strlen(param[1]) == 0)
+ {
+ debug_console_printf("Error : comment text empty\n");
+ return;
+ }
+
+ /* Now try adding the comment */
+ debug_comment_add(cpu_getactivecpu(), address, param[1], 0x00ff0000, debug_comment_get_opcode_crc32(address));
+ debug_view_update_type(DVT_DISASSEMBLY);
+}
+
+
+/*------------------------------------------------------
+ execute_comment_del - remove a comment from an addr
+--------------------------------------------------------*/
+
+static void execute_comment_del(int ref, int params, const char *param[])
+{
+ UINT64 address;
+
+ /* param 1 can either be a command or the address for the comment */
+ if (!debug_command_parameter_number(param[0], &address))
+ return;
+
+ /* If it's a number, it must be an address */
+ /* The bankoff and cbn will be pulled from what's currently active */
+ debug_comment_remove(cpu_getactivecpu(), address, debug_comment_get_opcode_crc32(address));
+ debug_view_update_type(DVT_DISASSEMBLY);
+}
+
+
+/*-------------------------------------------------
+ execute_comment - add a comment to a line
+-------------------------------------------------*/
+
+static void execute_comment_save(int ref, int params, const char *param[])
+{
+ if (debug_comment_save())
+ debug_console_printf("Comments successfully saved\n");
+}
+
+
+/*-------------------------------------------------
+ execute_bpset - execute the breakpoint set
+ command
+-------------------------------------------------*/
+
+static void execute_bpset(int ref, int params, const char *param[])
+{
+ parsed_expression *condition = NULL;
+ const char *action = NULL;
+ UINT64 address;
+ int bpnum;
+
+ /* make sure that there is an active CPU */
+ if (cpu_getactivecpu() < 0)
+ {
+ debug_console_printf("No active CPU!\n");
+ return;
+ }
+
+ /* param 1 is the address */
+ if (!debug_command_parameter_number(param[0], &address))
+ return;
+
+ /* param 2 is the condition */
+ if (params > 1 && !debug_command_parameter_expression(param[1], &condition))
+ return;
+
+ /* param 3 is the action */
+ if (params > 2 && !debug_command_parameter_command(action = param[2]))
+ return;
+
+ /* set the breakpoint */
+ bpnum = debug_breakpoint_set(cpu_getactivecpu(), address, condition, action);
+ debug_console_printf("Breakpoint %X set\n", bpnum);
+}
+
+
+/*-------------------------------------------------
+ execute_bpclear - execute the breakpoint
+ clear command
+-------------------------------------------------*/
+
+static void execute_bpclear(int ref, int params, const char *param[])
+{
+ UINT64 bpindex;
+
+ /* if 0 parameters, clear all */
+ if (params == 0)
+ {
+ int cpunum;
+
+ for (cpunum = 0; cpunum < MAX_CPU; cpunum++)
+ {
+ const debug_cpu_info *cpuinfo = debug_get_cpu_info(cpunum);
+ if (cpuinfo->valid)
+ {
+ debug_cpu_breakpoint *bp;
+ while ((bp = cpuinfo->first_bp) != NULL)
+ debug_breakpoint_clear(bp->index);
+ }
+ }
+ debug_console_printf("Cleared all breakpoints\n");
+ }
+
+ /* otherwise, clear the specific one */
+ else if (!debug_command_parameter_number(param[0], &bpindex))
+ return;
+ else
+ {
+ int found = debug_breakpoint_clear(bpindex);
+ if (found)
+ debug_console_printf("Breakpoint %X cleared\n", (UINT32)bpindex);
+ else
+ debug_console_printf("Invalid breakpoint number %X\n", (UINT32)bpindex);
+ }
+}
+
+
+/*-------------------------------------------------
+ execute_bpdisenable - execute the breakpoint
+ disable/enable commands
+-------------------------------------------------*/
+
+static void execute_bpdisenable(int ref, int params, const char *param[])
+{
+ UINT64 bpindex;
+
+ /* if 0 parameters, clear all */
+ if (params == 0)
+ {
+ int cpunum;
+
+ for (cpunum = 0; cpunum < MAX_CPU; cpunum++)
+ {
+ const debug_cpu_info *cpuinfo = debug_get_cpu_info(cpunum);
+ if (cpuinfo->valid)
+ {
+ debug_cpu_breakpoint *bp;
+ for (bp = cpuinfo->first_bp; bp; bp = bp->next)
+ debug_breakpoint_enable(bp->index, ref);
+ }
+ }
+ if (ref == 0)
+ debug_console_printf("Disabled all breakpoints\n");
+ else
+ debug_console_printf("Enabled all breakpoints\n");
+ }
+
+ /* otherwise, clear the specific one */
+ else if (!debug_command_parameter_number(param[0], &bpindex))
+ return;
+ else
+ {
+ int found = debug_breakpoint_enable(bpindex, ref);
+ if (found)
+ debug_console_printf("Breakpoint %X %s\n", (UINT32)bpindex, ref ? "enabled" : "disabled");
+ else
+ debug_console_printf("Invalid breakpoint number %X\n", (UINT32)bpindex);
+ }
+}
+
+
+/*-------------------------------------------------
+ execute_bplist - execute the breakpoint list
+ command
+-------------------------------------------------*/
+
+static void execute_bplist(int ref, int params, const char *param[])
+{
+ int cpunum, printed = 0;
+ char buffer[256];
+
+ /* loop over all CPUs */
+ for (cpunum = 0; cpunum < MAX_CPU; cpunum++)
+ {
+ const debug_cpu_info *cpuinfo = debug_get_cpu_info(cpunum);
+
+ if (cpuinfo->valid && cpuinfo->first_bp)
+ {
+ debug_cpu_breakpoint *bp;
+
+ debug_console_printf("CPU %d breakpoints:\n", cpunum);
+
+ /* loop over the breakpoints */
+ for (bp = cpuinfo->first_bp; bp; bp = bp->next)
+ {
+ int buflen;
+ buflen = sprintf(buffer, "%c%4X @ %08X", bp->enabled ? ' ' : 'D', bp->index, bp->address);
+ if (bp->condition)
+ buflen += sprintf(&buffer[buflen], " if %s", expression_original_string(bp->condition));
+ if (bp->action)
+ buflen += sprintf(&buffer[buflen], " do %s", bp->action);
+ debug_console_printf("%s\n", buffer);
+ printed++;
+ }
+ }
+ }
+
+ if (!printed)
+ debug_console_printf("No breakpoints currently installed\n");
+}
+
+
+/*-------------------------------------------------
+ execute_wpset - execute the watchpoint set
+ command
+-------------------------------------------------*/
+
+static void execute_wpset(int ref, int params, const char *param[])
+{
+ parsed_expression *condition = NULL;
+ const char *action = NULL;
+ UINT64 address, length;
+ int type = 0;
+ int wpnum;
+
+ /* param 1 is the address */
+ if (!debug_command_parameter_number(param[0], &address))
+ return;
+
+ /* param 2 is the length */
+ if (!debug_command_parameter_number(param[1], &length))
+ return;
+
+ /* param 3 is the type */
+ if (!strcmp(param[2], "r"))
+ type = WATCHPOINT_READ;
+ else if (!strcmp(param[2], "w"))
+ type = WATCHPOINT_WRITE;
+ else if (!strcmp(param[2], "rw") || !strcmp(param[2], "wr"))
+ type = WATCHPOINT_READWRITE;
+ else
+ {
+ debug_console_printf("Invalid watchpoint type: expected r, w, or rw\n");
+ return;
+ }
+
+ /* param 4 is the condition */
+ if (params > 3 && !debug_command_parameter_expression(param[3], &condition))
+ return;
+
+ /* param 5 is the action */
+ if (params > 4 && !debug_command_parameter_command(action = param[4]))
+ return;
+
+ /* set the watchpoint */
+ wpnum = debug_watchpoint_set(cpu_getactivecpu(), ref, type, address, length, condition, action);
+ debug_console_printf("Watchpoint %X set\n", wpnum);
+}
+
+
+/*-------------------------------------------------
+ execute_wpclear - execute the watchpoint
+ clear command
+-------------------------------------------------*/
+
+static void execute_wpclear(int ref, int params, const char *param[])
+{
+ UINT64 wpindex;
+
+ /* if 0 parameters, clear all */
+ if (params == 0)
+ {
+ int cpunum;
+
+ for (cpunum = 0; cpunum < MAX_CPU; cpunum++)
+ {
+ const debug_cpu_info *cpuinfo = debug_get_cpu_info(cpunum);
+ if (cpuinfo->valid)
+ {
+ int spacenum;
+
+ for (spacenum = 0; spacenum < ADDRESS_SPACES; spacenum++)
+ {
+ debug_cpu_watchpoint *wp;
+ while ((wp = cpuinfo->space[spacenum].first_wp) != NULL)
+ debug_watchpoint_clear(wp->index);
+ }
+ }
+ }
+ debug_console_printf("Cleared all watchpoints\n");
+ }
+
+ /* otherwise, clear the specific one */
+ else if (!debug_command_parameter_number(param[0], &wpindex))
+ return;
+ else
+ {
+ int found = debug_watchpoint_clear(wpindex);
+ if (found)
+ debug_console_printf("Watchpoint %X cleared\n", (UINT32)wpindex);
+ else
+ debug_console_printf("Invalid watchpoint number %X\n", (UINT32)wpindex);
+ }
+}
+
+
+/*-------------------------------------------------
+ execute_wpdisenable - execute the watchpoint
+ disable/enable commands
+-------------------------------------------------*/
+
+static void execute_wpdisenable(int ref, int params, const char *param[])
+{
+ UINT64 wpindex;
+
+ /* if 0 parameters, clear all */
+ if (params == 0)
+ {
+ int cpunum;
+
+ for (cpunum = 0; cpunum < MAX_CPU; cpunum++)
+ {
+ const debug_cpu_info *cpuinfo = debug_get_cpu_info(cpunum);
+ if (cpuinfo->valid)
+ {
+ int spacenum;
+
+ for (spacenum = 0; spacenum < ADDRESS_SPACES; spacenum++)
+ {
+ debug_cpu_watchpoint *wp;
+ for (wp = cpuinfo->space[spacenum].first_wp; wp; wp = wp->next)
+ debug_watchpoint_enable(wp->index, ref);
+ }
+ }
+ }
+ if (ref == 0)
+ debug_console_printf("Disabled all watchpoints\n");
+ else
+ debug_console_printf("Enabled all watchpoints\n");
+ }
+
+ /* otherwise, clear the specific one */
+ else if (!debug_command_parameter_number(param[0], &wpindex))
+ return;
+ else
+ {
+ int found = debug_watchpoint_enable(wpindex, ref);
+ if (found)
+ debug_console_printf("Watchpoint %X %s\n", (UINT32)wpindex, ref ? "enabled" : "disabled");
+ else
+ debug_console_printf("Invalid watchpoint number %X\n", (UINT32)wpindex);
+ }
+}
+
+
+/*-------------------------------------------------
+ execute_wplist - execute the watchpoint list
+ command
+-------------------------------------------------*/
+
+static void execute_wplist(int ref, int params, const char *param[])
+{
+ static const char *spacenames[ADDRESS_SPACES] = { "program", "data", "I/O" };
+ int cpunum, printed = 0;
+ char buffer[256];
+
+ /* loop over all CPUs */
+ for (cpunum = 0; cpunum < MAX_CPU; cpunum++)
+ {
+ const debug_cpu_info *cpuinfo = debug_get_cpu_info(cpunum);
+
+ if (cpuinfo->valid)
+ {
+ int spacenum;
+
+ for (spacenum = 0; spacenum < ADDRESS_SPACES; spacenum++)
+ {
+ if (cpuinfo->space[spacenum].first_wp)
+ {
+ static const char *types[] = { "unkn ", "read ", "write", "r/w " };
+ debug_cpu_watchpoint *wp;
+
+ debug_console_printf("CPU %d %s space watchpoints:\n", cpunum, spacenames[spacenum]);
+
+ /* loop over the watchpoints */
+ for (wp = cpuinfo->space[spacenum].first_wp; wp; wp = wp->next)
+ {
+ int buflen;
+ buflen = sprintf(buffer, "%c%4X @ %08X-%08X %s", wp->enabled ? ' ' : 'D',
+ wp->index, BYTE2ADDR(wp->address, cpuinfo, spacenum), BYTE2ADDR(wp->address + wp->length, cpuinfo, spacenum) - 1, types[wp->type & 3]);
+ if (wp->condition)
+ buflen += sprintf(&buffer[buflen], " if %s", expression_original_string(wp->condition));
+ if (wp->action)
+ buflen += sprintf(&buffer[buflen], " do %s", wp->action);
+ debug_console_printf("%s\n", buffer);
+ printed++;
+ }
+ }
+ }
+ }
+ }
+
+ if (!printed)
+ debug_console_printf("No watchpoints currently installed\n");
+}
+
+
+/*-------------------------------------------------
+ execute_hotspot - execute the hotspot
+ command
+-------------------------------------------------*/
+
+static void execute_hotspot(int ref, int params, const char *param[])
+{
+ UINT64 threshhold;
+ UINT64 cpunum;
+ UINT64 count;
+
+ /* if no params, and there are live hotspots, clear them */
+ if (params == 0)
+ {
+ int cleared = FALSE;
+
+ /* loop over CPUs and find live spots */
+ for (cpunum = 0; cpunum < MAX_CPU; cpunum++)
+ {
+ const debug_cpu_info *cpuinfo = debug_get_cpu_info(cpunum);
+
+ if (cpuinfo->valid && cpuinfo->hotspots)
+ {
+ debug_hotspot_track(cpunum, 0, 0);
+ debug_console_printf("Cleared hotspot tracking on CPU %d\n", (int)cpunum);
+ cleared = TRUE;
+ }
+ }
+
+ /* if we cleared, we're done */
+ if (cleared)
+ return;
+ }
+
+ /* extract parameters */
+ cpunum = cpu_getactivecpu();
+ count = 64;
+ threshhold = 250;
+ if (params > 0 && !debug_command_parameter_number(param[0], &cpunum))
+ return;
+ if (params > 1 && !debug_command_parameter_number(param[1], &count))
+ return;
+ if (params > 2 && !debug_command_parameter_number(param[2], &threshhold))
+ return;
+
+ /* attempt to install */
+ if (debug_hotspot_track(cpunum, count, threshhold))
+ debug_console_printf("Now tracking hotspots on CPU %d using %d slots with a threshhold of %d\n", (int)cpunum, (int)count, (int)threshhold);
+ else
+ debug_console_printf("Error setting up the hotspot tracking\n");
+}
+
+
+/*-------------------------------------------------
+ execute_save - execute the save command
+-------------------------------------------------*/
+
+static void execute_save(int ref, int params, const char *param[])
+{
+ UINT64 offset, endoffset, length, cpunum = cpu_getactivecpu();
+ const debug_cpu_info *info;
+ int spacenum = ref;
+ FILE *f;
+ UINT64 i;
+
+ /* validate parameters */
+ if (!debug_command_parameter_number(param[1], &offset))
+ return;
+ if (!debug_command_parameter_number(param[2], &length))
+ return;
+ if (params > 3 && !debug_command_parameter_number(param[3], &cpunum))
+ return;
+
+ /* determine the addresses to write */
+ info = debug_get_cpu_info(cpunum);
+ endoffset = ADDR2BYTE_MASKED(offset + length - 1, info, spacenum);
+ offset = ADDR2BYTE_MASKED(offset, info, spacenum);
+
+ /* open the file */
+ f = fopen(param[0], "wb");
+ if (!f)
+ {
+ debug_console_printf("Error opening file '%s'\n", param[0]);
+ return;
+ }
+
+ /* now write the data out */
+ cpuintrf_push_context(cpunum);
+ for (i = offset; i <= endoffset; i++)
+ {
+ UINT8 byte = debug_read_byte(spacenum, i, TRUE);
+ fwrite(&byte, 1, 1, f);
+ }
+ cpuintrf_pop_context();
+
+ /* close the file */
+ fclose(f);
+ debug_console_printf("Data saved successfully\n");
+}
+
+
+/*-------------------------------------------------
+ execute_dump - execute the dump command
+-------------------------------------------------*/
+
+static void execute_dump(int ref, int params, const char *param[])
+{
+ UINT64 offset, endoffset, length, width = 0, ascii = 1, cpunum = cpu_getactivecpu();
+ const debug_cpu_info *info;
+ int spacenum = ref;
+ FILE *f = NULL;
+ UINT64 i, j;
+
+ /* validate parameters */
+ if (!debug_command_parameter_number(param[1], &offset))
+ return;
+ if (!debug_command_parameter_number(param[2], &length))
+ return;
+ if (params > 3 && !debug_command_parameter_number(param[3], &width))
+ return;
+ if (params > 4 && !debug_command_parameter_number(param[4], &ascii))
+ return;
+ if (params > 5 && !debug_command_parameter_number(param[5], &cpunum))
+ return;
+
+ /* further validation */
+ if (cpunum >= cpu_gettotalcpu())
+ {
+ debug_console_printf("Invalid CPU number!\n");
+ return;
+ }
+ info = debug_get_cpu_info(cpunum);
+ if (width == 0)
+ width = info->space[spacenum].databytes;
+ if (width < ADDR2BYTE(1, info, spacenum))
+ width = ADDR2BYTE(1, info, spacenum);
+ if (width != 1 && width != 2 && width != 4 && width != 8)
+ {
+ debug_console_printf("Invalid width! (must be 1,2,4 or 8)\n");
+ return;
+ }
+ endoffset = ADDR2BYTE_MASKED(offset + length - 1, info, spacenum);
+ offset = ADDR2BYTE_MASKED(offset, info, spacenum);
+
+ /* open the file */
+ f = fopen(param[0], "w");
+ if (!f)
+ {
+ debug_console_printf("Error opening file '%s'\n", param[0]);
+ return;
+ }
+
+ /* now write the data out */
+ cpuintrf_push_context(cpunum);
+ for (i = offset; i <= endoffset; i += 16)
+ {
+ char output[200];
+ int outdex = 0;
+
+ /* print the address */
+ outdex += sprintf(&output[outdex], "%0*X: ", info->space[spacenum].logchars, (UINT32)BYTE2ADDR(i, info, spacenum));
+
+ /* print the bytes */
+ switch (width)
+ {
+ case 1:
+ for (j = 0; j < 16; j++)
+ {
+ if (i + j <= endoffset)
+ {
+ offs_t curaddr = i + j;
+ if (!info->translate || (*info->translate)(spacenum, &curaddr))
+ {
+ UINT8 byte = debug_read_byte(ref, i + j, TRUE);
+ outdex += sprintf(&output[outdex], " %02X", byte);
+ }
+ else
+ outdex += sprintf(&output[outdex], " **");
+ }
+ else
+ outdex += sprintf(&output[outdex], " ");
+ }
+ break;
+
+ case 2:
+ for (j = 0; j < 16; j += 2)
+ {
+ if (i + j <= endoffset)
+ {
+ offs_t curaddr = i + j;
+ if (!info->translate || (*info->translate)(spacenum, &curaddr))
+ {
+ UINT16 word = debug_read_word(ref, i + j, TRUE);
+ outdex += sprintf(&output[outdex], " %04X", word);
+ }
+ else
+ outdex += sprintf(&output[outdex], " ****");
+ }
+ else
+ outdex += sprintf(&output[outdex], " ");
+ }
+ break;
+
+ case 4:
+ for (j = 0; j < 16; j += 4)
+ {
+ if (i + j <= endoffset)
+ {
+ offs_t curaddr = i + j;
+ if (!info->translate || (*info->translate)(spacenum, &curaddr))
+ {
+ UINT32 dword = debug_read_dword(ref, i + j, TRUE);
+ outdex += sprintf(&output[outdex], " %08X", dword);
+ }
+ else
+ outdex += sprintf(&output[outdex], " ********");
+ }
+ else
+ outdex += sprintf(&output[outdex], " ");
+ }
+ break;
+
+ case 8:
+ for (j = 0; j < 16; j += 8)
+ {
+ if (i + j <= endoffset)
+ {
+ offs_t curaddr = i + j;
+ if (!info->translate || (*info->translate)(spacenum, &curaddr))
+ {
+ UINT64 qword = debug_read_qword(ref, i + j, TRUE);
+ outdex += sprintf(&output[outdex], " %08X%08X", (UINT32)(qword >> 32), (UINT32)qword);
+ }
+ else
+ outdex += sprintf(&output[outdex], " ****************");
+ }
+ else
+ outdex += sprintf(&output[outdex], " ");
+ }
+ break;
+ }
+
+ /* print the ASCII */
+ if (ascii)
+ {
+ outdex += sprintf(&output[outdex], " ");
+ for (j = 0; j < 16 && (i + j) <= endoffset; j++)
+ {
+ offs_t curaddr = i + j;
+ if (!info->translate || (*info->translate)(spacenum, &curaddr))
+ {
+ UINT8 byte = debug_read_byte(ref, i + j, TRUE);
+ outdex += sprintf(&output[outdex], "%c", (byte >= 32 && byte < 128) ? byte : '.');
+ }
+ else
+ outdex += sprintf(&output[outdex], " ");
+ }
+ }
+
+ /* output the result */
+ fprintf(f, "%s\n", output);
+ }
+ cpuintrf_pop_context();
+
+ /* close the file */
+ fclose(f);
+ debug_console_printf("Data dumped successfully\n");
+}
+
+
+/*-------------------------------------------------
+ execute_find - execute the find command
+-------------------------------------------------*/
+
+static void execute_find(int ref, int params, const char *param[])
+{
+ UINT64 offset, endoffset, length, cpunum = cpu_getactivecpu();
+ const debug_cpu_info *info;
+ UINT64 data_to_find[256];
+ UINT8 data_size[256];
+ int cur_data_size;
+ int data_count = 0;
+ int spacenum = ref;
+ int found = 0;
+ UINT64 i, j;
+
+ /* validate parameters */
+ if (!debug_command_parameter_number(param[0], &offset))
+ return;
+ if (!debug_command_parameter_number(param[1], &length))
+ return;
+
+ /* further validation */
+ if (cpunum >= cpu_gettotalcpu())
+ {
+ debug_console_printf("Invalid CPU number!\n");
+ return;
+ }
+ info = debug_get_cpu_info(cpunum);
+ endoffset = ADDR2BYTE_MASKED(offset + length - 1, info, spacenum);
+ offset = ADDR2BYTE_MASKED(offset, info, spacenum);
+ cur_data_size = ADDR2BYTE(1, info, spacenum);
+ if (cur_data_size == 0)
+ cur_data_size = 1;
+
+ /* parse the data parameters */
+ for (i = 2; i < params; i++)
+ {
+ const char *pdata = param[i];
+
+ /* check for a string */
+ if (pdata[0] == '"' && pdata[strlen(pdata) - 1] == '"')
+ {
+ for (j = 1; j < strlen(pdata) - 1; j++)
+ {
+ data_to_find[data_count] = pdata[j];
+ data_size[data_count++] = 1;
+ }
+ }
+
+ /* otherwise, validate as a number */
+ else
+ {
+ /* check for a 'b','w','d',or 'q' prefix */
+ data_size[data_count] = cur_data_size;
+ if (tolower(pdata[0]) == 'b' && pdata[1] == '.') { data_size[data_count] = cur_data_size = 1; pdata += 2; }
+ if (tolower(pdata[0]) == 'w' && pdata[1] == '.') { data_size[data_count] = cur_data_size = 2; pdata += 2; }
+ if (tolower(pdata[0]) == 'd' && pdata[1] == '.') { data_size[data_count] = cur_data_size = 4; pdata += 2; }
+ if (tolower(pdata[0]) == 'q' && pdata[1] == '.') { data_size[data_count] = cur_data_size = 8; pdata += 2; }
+
+ /* look for a wildcard */
+ if (!strcmp(pdata, "?"))
+ data_size[data_count++] |= 0x10;
+
+ /* otherwise, validate as a number */
+ else if (!debug_command_parameter_number(pdata, &data_to_find[data_count++]))
+ return;
+ }
+ }
+
+ /* now search */
+ cpuintrf_push_context(cpunum);
+ for (i = offset; i <= endoffset; i += data_size[0])
+ {
+ int suboffset = 0;
+ int match = 1;
+
+ /* find the entire string */
+ for (j = 0; j < data_count && match; j++)
+ {
+ switch (data_size[j])
+ {
+ case 1: match = ((UINT8)debug_read_byte(spacenum, i + suboffset, TRUE) == (UINT8)data_to_find[j]); break;
+ case 2: match = ((UINT16)debug_read_word(spacenum, i + suboffset, TRUE) == (UINT16)data_to_find[j]); break;
+ case 4: match = ((UINT32)debug_read_dword(spacenum, i + suboffset, TRUE) == (UINT32)data_to_find[j]); break;
+ case 8: match = ((UINT64)debug_read_qword(spacenum, i + suboffset, TRUE) == (UINT64)data_to_find[j]); break;
+ default: /* all other cases are wildcards */ break;
+ }
+ suboffset += data_size[j] & 0x0f;
+ }
+
+ /* did we find it? */
+ if (match)
+ {
+ found++;
+ debug_console_printf("Found at %*X\n", info->space[spacenum].logchars, (UINT32)BYTE2ADDR(i, info, spacenum));
+ }
+ }
+ cpuintrf_pop_context();
+
+ /* print something if not found */
+ if (found == 0)
+ debug_console_printf("Not found\n");
+}
+
+
+/*-------------------------------------------------
+ execute_dasm - execute the dasm command
+-------------------------------------------------*/
+
+static void execute_dasm(int ref, int params, const char *param[])
+{
+ UINT64 offset, length, bytes = 1, cpunum = cpu_getactivecpu();
+ const debug_cpu_info *info;
+ int minbytes, maxbytes, byteswidth;
+ FILE *f = NULL;
+ int i, j;
+
+ /* validate parameters */
+ if (!debug_command_parameter_number(param[1], &offset))
+ return;
+ if (!debug_command_parameter_number(param[2], &length))
+ return;
+ if (params > 3 && !debug_command_parameter_number(param[3], &bytes))
+ return;
+ if (params > 4 && !debug_command_parameter_number(param[4], &cpunum))
+ return;
+
+ /* further validation */
+ if (cpunum >= cpu_gettotalcpu())
+ {
+ debug_console_printf("Invalid CPU number!\n");
+ return;
+ }
+ info = debug_get_cpu_info(cpunum);
+
+ /* determine the width of the bytes */
+ minbytes = cpunum_min_instruction_bytes(cpunum);
+ maxbytes = cpunum_max_instruction_bytes(cpunum);
+ byteswidth = 0;
+ if (bytes)
+ {
+ byteswidth = (maxbytes + (minbytes - 1)) / minbytes;
+ byteswidth *= (2 * minbytes) + 1;
+ }
+
+ /* open the file */
+ f = fopen(param[0], "w");
+ if (!f)
+ {
+ debug_console_printf("Error opening file '%s'\n", param[0]);
+ return;
+ }
+
+ /* now write the data out */
+ cpuintrf_push_context(cpunum);
+ for (i = 0; i < length; )
+ {
+ int pcbyte = ADDR2BYTE_MASKED(offset + i, info, ADDRESS_SPACE_PROGRAM);
+ char output[200+DEBUG_COMMENT_MAX_LINE_LENGTH], disasm[200];
+ const char *comment;
+ offs_t tempaddr;
+ int outdex = 0;
+ int numbytes = 0;
+
+ /* print the address */
+ outdex += sprintf(&output[outdex], "%0*X: ", info->space[ADDRESS_SPACE_PROGRAM].logchars, (UINT32)BYTE2ADDR(pcbyte, info, ADDRESS_SPACE_PROGRAM));
+
+ /* make sure we can translate the address */
+ tempaddr = pcbyte;
+ if (!info->translate || (*info->translate)(ADDRESS_SPACE_PROGRAM, &tempaddr))
+ {
+ UINT8 opbuf[64], argbuf[64];
+
+ /* fetch the bytes up to the maximum */
+ for (numbytes = 0; numbytes < maxbytes; numbytes++)
+ {
+ opbuf[numbytes] = debug_read_opcode(pcbyte + numbytes, 1, FALSE);
+ argbuf[numbytes] = debug_read_opcode(pcbyte + numbytes, 1, TRUE);
+ }
+
+ /* disassemble the result */
+ i += numbytes = activecpu_dasm(disasm, offset + i, opbuf, argbuf) & DASMFLAG_LENGTHMASK;
+ }
+
+ /* print the bytes */
+ if (bytes)
+ {
+ int startdex = outdex;
+ numbytes = ADDR2BYTE(numbytes, info, ADDRESS_SPACE_PROGRAM);
+ switch (minbytes)
+ {
+ case 1:
+ for (j = 0; j < numbytes; j++)
+ outdex += sprintf(&output[outdex], "%02X ", (UINT32)debug_read_opcode(pcbyte + j, 1, FALSE));
+ break;
+
+ case 2:
+ for (j = 0; j < numbytes; j += 2)
+ outdex += sprintf(&output[outdex], "%04X ", (UINT32)debug_read_opcode(pcbyte + j, 2, FALSE));
+ break;
+
+ case 4:
+ for (j = 0; j < numbytes; j += 4)
+ outdex += sprintf(&output[outdex], "%08X ", (UINT32)debug_read_opcode(pcbyte + j, 4, FALSE));
+ break;
+
+ case 8:
+ for (j = 0; j < numbytes; j += 8)
+ {
+ UINT64 val = debug_read_opcode(pcbyte + j, 8, FALSE);
+ outdex += sprintf(&output[outdex], "%08X%08X ", (UINT32)(val >> 32), (UINT32)val);
+ }
+ break;
+ }
+ if (outdex - startdex < byteswidth)
+ outdex += sprintf(&output[outdex], "%*s", byteswidth - (outdex - startdex), "");
+ outdex += sprintf(&output[outdex], " ");
+ }
+
+ /* add the disassembly */
+ sprintf(&output[outdex], "%s", disasm);
+
+ /* attempt to add the comment */
+ comment = debug_comment_get_text(cpunum, tempaddr, debug_comment_get_opcode_crc32(tempaddr));
+ if (comment != NULL)
+ {
+ /* somewhat arbitrary guess as to how long most disassembly lines will be [column 60] */
+ if (strlen(output) < 60)
+ {
+ /* pad the comment space out to 60 characters and null-terminate */
+ for (outdex = (int)strlen(output); outdex < 60; outdex++)
+ output[outdex] = ' ' ;
+ output[outdex] = 0 ;
+
+ sprintf(&output[strlen(output)], "// %s", comment) ;
+ }
+ else
+ sprintf(&output[strlen(output)], "\t// %s", comment) ;
+ }
+
+ /* output the result */
+ fprintf(f, "%s\n", output);
+ }
+ cpuintrf_pop_context();
+
+ /* close the file */
+ fclose(f);
+ debug_console_printf("Data dumped successfully\n");
+}
+
+
+/*-------------------------------------------------
+ execute_trace_internal - functionality for
+ trace over and trace info
+-------------------------------------------------*/
+
+static void execute_trace_internal(int ref, int params, const char *param[], int trace_over)
+{
+ const char *action = NULL, *filename = param[0];
+ FILE *f = NULL;
+ const char *mode;
+ UINT64 cpunum;
+
+ cpunum = cpu_getactivecpu();
+
+ /* validate parameters */
+ if (params > 1 && !debug_command_parameter_number(param[1], &cpunum))
+ return;
+ if (params > 2 && !debug_command_parameter_command(action = param[2]))
+ return;
+
+ /* further validation */
+ if (!mame_stricmp(filename, "off"))
+ filename = NULL;
+ if (cpunum >= cpu_gettotalcpu())
+ {
+ debug_console_printf("Invalid CPU number!\n");
+ return;
+ }
+
+ /* open the file */
+ if (filename)
+ {
+ mode = "w";
+
+ /* opening for append? */
+ if ((filename[0] == '>') && (filename[1] == '>'))
+ {
+ mode = "a";
+ filename += 2;
+ }
+
+ f = fopen(filename, mode);
+ if (!f)
+ {
+ debug_console_printf("Error opening file '%s'\n", param[0]);
+ return;
+ }
+ }
+
+ /* do it */
+ debug_cpu_trace(cpunum, f, trace_over, action);
+ if (f)
+ debug_console_printf("Tracing CPU %d to file %s\n", (int)cpunum, filename);
+ else
+ debug_console_printf("Stopped tracing on CPU %d\n", (int)cpunum);
+}
+
+
+/*-------------------------------------------------
+ execute_trace - execute the trace command
+-------------------------------------------------*/
+
+static void execute_trace(int ref, int params, const char *param[])
+{
+ execute_trace_internal(ref, params, param, 0);
+}
+
+
+/*-------------------------------------------------
+ execute_traceover - execute the trace over command
+-------------------------------------------------*/
+
+static void execute_traceover(int ref, int params, const char *param[])
+{
+ execute_trace_internal(ref, params, param, 1);
+}
+
+
+/*-------------------------------------------------
+ execute_traceflush - execute the trace flush command
+-------------------------------------------------*/
+
+static void execute_traceflush(int ref, int params, const char *param[])
+{
+ debug_flush_traces();
+}
+
+
+/*-------------------------------------------------
+ execute_history - execute the history command
+-------------------------------------------------*/
+
+static void execute_history(int ref, int params, const char *param[])
+{
+ UINT64 count = DEBUG_HISTORY_SIZE;
+ const debug_cpu_info *info;
+ UINT64 cpunum;
+ int i;
+
+ cpunum = cpu_getactivecpu();
+
+ /* validate parameters */
+ if (params > 0 && !debug_command_parameter_number(param[0], &cpunum))
+ return;
+ if (params > 1 && !debug_command_parameter_number(param[1], &count))
+ return;
+
+ /* further validation */
+ if (cpunum >= cpu_gettotalcpu())
+ {
+ debug_console_printf("Invalid CPU number!\n");
+ return;
+ }
+ if (count > DEBUG_HISTORY_SIZE)
+ count = DEBUG_HISTORY_SIZE;
+
+ info = debug_get_cpu_info(cpunum);
+
+ /* loop over lines */
+ cpuintrf_push_context(cpunum);
+ for (i = 0; i < count; i++)
+ {
+ offs_t pc = info->pc_history[(info->pc_history_index + DEBUG_HISTORY_SIZE - count + i) % DEBUG_HISTORY_SIZE];
+ int maxbytes = activecpu_max_instruction_bytes();
+ UINT8 opbuf[64], argbuf[64];
+ char buffer[200];
+ offs_t pcbyte;
+ int numbytes;
+
+ /* fetch the bytes up to the maximum */
+ pcbyte = ADDR2BYTE_MASKED(pc, info, ADDRESS_SPACE_PROGRAM);
+ for (numbytes = 0; numbytes < maxbytes; numbytes++)
+ {
+ opbuf[numbytes] = debug_read_opcode(pcbyte + numbytes, 1, FALSE);
+ argbuf[numbytes] = debug_read_opcode(pcbyte + numbytes, 1, TRUE);
+ }
+
+ activecpu_dasm(buffer, pc, opbuf, argbuf);
+
+ debug_console_printf("%0*X: %s\n", info->space[ADDRESS_SPACE_PROGRAM].logchars, pc, buffer);
+ }
+ cpuintrf_pop_context();
+}
+
+
+/*-------------------------------------------------
+ execute_snap - execute the trace over command
+-------------------------------------------------*/
+
+static void execute_snap(int ref, int params, const char *param[])
+{
+ /* if no params, use the default behavior */
+ if (params == 0)
+ {
+ video_save_active_screen_snapshots(Machine);
+ debug_console_printf("Saved snapshot\n");
+ }
+
+ /* otherwise, we have to open the file ourselves */
+ else
+ {
+ file_error filerr;
+ mame_file *fp;
+ const char *filename = param[0];
+ int scrnum = (params > 1) ? atoi(param[1]) : 0;
+ UINT32 mask = render_get_live_screens_mask();
+ astring *fname;
+
+ if (scrnum < 0 || scrnum >= MAX_SCREENS || !(mask & (1 << scrnum)))
+ {
+ debug_console_printf("Invalid screen number '%d'\n", scrnum);
+ return;
+ }
+
+ fname = astring_dupc(filename);
+ if (astring_findc(fname, 0, ".png") == -1)
+ astring_catc(fname, ".png");
+ filerr = mame_fopen(SEARCHPATH_SCREENSHOT, astring_c(fname), OPEN_FLAG_WRITE | OPEN_FLAG_CREATE | OPEN_FLAG_CREATE_PATHS, &fp);
+ astring_free(fname);
+
+ if (filerr != FILERR_NONE)
+ {
+ debug_console_printf("Error creating file '%s'\n", filename);
+ return;
+ }
+
+ video_screen_save_snapshot(Machine, fp, scrnum);
+ mame_fclose(fp);
+ debug_console_printf("Saved screen #%d snapshot as '%s'\n", scrnum, filename);
+ }
+}
+
+
+/*-------------------------------------------------
+ execute_source - execute the source command
+-------------------------------------------------*/
+
+static void execute_source(int ref, int params, const char *param[])
+{
+ debug_source_script(param[0]);
+}
+
+
+/*-------------------------------------------------
+ execute_map - execute the map command
+-------------------------------------------------*/
+
+static void execute_map(int ref, int params, const char *param[])
+{
+ UINT64 address, cpunum = cpu_getactivecpu();
+ const debug_cpu_info *info;
+ int spacenum = ref;
+ offs_t taddress;
+
+ /* validate parameters */
+ if (!debug_command_parameter_number(param[0], &address))
+ return;
+ info = debug_get_cpu_info(cpunum);
+
+ /* do the translation first */
+ taddress = ADDR2BYTE_MASKED(address, info, spacenum);
+ if (info->translate)
+ {
+ if ((*info->translate)(spacenum, &taddress))
+ debug_console_printf("%08X logical -> %08X physical\n", (UINT32)address, BYTE2ADDR(taddress, info, spacenum));
+ else
+ {
+ debug_console_printf("%08X logical -> unmapped\n", (UINT32)address);
+ return;
+ }
+ }
+ else
+ debug_console_printf("%08X physical\n", BYTE2ADDR(taddress, info, spacenum));
+
+ /* now do the mapping */
+ debug_console_printf(" -> read: %s\n", memory_get_handler_string(0, cpunum, spacenum, taddress));
+ debug_console_printf(" -> write: %s\n", memory_get_handler_string(1, cpunum, spacenum, taddress));
+}
+
+
+/*-------------------------------------------------
+ execute_memdump - execute the memdump command
+-------------------------------------------------*/
+
+static void execute_memdump(int ref, int params, const char **param)
+{
+ FILE *file;
+ const char *filename;
+
+ filename = (params == 0) ? "memdump.log" : param[0];
+
+ debug_console_printf("Dumping memory to %s\n", filename);
+
+ file = fopen(filename, "w");
+ if (file)
+ {
+ memory_dump(file);
+ fclose(file);
+ }
+}
+
+
+/*-------------------------------------------------
+ execute_symlist - execute the symlist command
+-------------------------------------------------*/
+
+static int CLIB_DECL symbol_sort_compare(const void *item1, const void *item2)
+{
+ const char *str1 = *(const char **)item1;
+ const char *str2 = *(const char **)item2;
+ return strcmp(str1, str2);
+}
+
+static void execute_symlist(int ref, int params, const char **param)
+{
+ const char *namelist[1000];
+ symbol_table *symtable;
+ UINT64 cpunum = 100000;
+ int symnum, count = 0;
+
+ /* validate parameters */
+ if (params > 0 && !debug_command_parameter_number(param[0], &cpunum))
+ return;
+ if (cpunum != 100000 && cpunum >= cpu_gettotalcpu())
+ {
+ debug_console_printf("Invalid CPU number!\n");
+ return;
+ }
+ symtable = (cpunum == 100000) ? global_symtable : debug_get_cpu_info(cpunum)->symtable;
+
+ if (symtable == global_symtable)
+ debug_console_printf("Global symbols:\n");
+ else
+ debug_console_printf("CPU #%d symbols:\n", (UINT32)cpunum);
+
+ /* gather names for all symbols */
+ for (symnum = 0; symnum < 100000; symnum++)
+ {
+ const symbol_entry *entry;
+ const char *name = symtable_find_indexed(symtable, symnum, &entry);
+
+ /* if we didn't get anything, we're done */
+ if (name == NULL)
+ break;
+
+ /* only display "register" type symbols */
+ if (entry->type == SMT_REGISTER)
+ {
+ namelist[count++] = name;
+ if (count >= ARRAY_LENGTH(namelist))
+ break;
+ }
+ }
+
+ /* sort the symbols */
+ if (count > 1)
+ qsort((void *)namelist, count, sizeof(namelist[0]), symbol_sort_compare);
+
+ /* iterate over symbols and print out relevant ones */
+ for (symnum = 0; symnum < count; symnum++)
+ {
+ const symbol_entry *entry = symtable_find(symtable, namelist[symnum]);
+ UINT64 value = (*entry->info.reg.getter)(entry->ref);
+ assert(entry != NULL);
+
+ /* only display "register" type symbols */
+ debug_console_printf("%s = ", namelist[symnum]);
+ if ((value >> 32) != 0)
+ debug_console_printf("%X%08X", (UINT32)(value >> 32), (UINT32)value);
+ else
+ debug_console_printf("%X", (UINT32)value);
+ if (entry->info.reg.setter == NULL)
+ debug_console_printf(" (read-only)");
+ debug_console_printf("\n");
+ }
+}
+
+
+/*-------------------------------------------------
+ execute_softreset - execute the softreset command
+-------------------------------------------------*/
+
+static void execute_softreset(int ref, int params, const char **param)
+{
+ mame_schedule_soft_reset(Machine);
+}
+
+
+/*-------------------------------------------------
+ execute_hardreset - execute the hardreset command
+-------------------------------------------------*/
+
+static void execute_hardreset(int ref, int params, const char **param)
+{
+ mame_schedule_hard_reset(Machine);
+}