From 9007f919828032503933eaab71f5f65ad94855ca Mon Sep 17 00:00:00 2001 From: Andrew Gardner Date: Tue, 14 May 2013 04:24:31 +0000 Subject: [PATCH] Adds statesave (ss) & stateload (sl) commands to the debugger. [Andrew Gardner] --- src/emu/debug/debugcmd.c | 63 ++++++++++++++++++++++++++++++++-------- src/emu/debug/debughlp.c | 48 +++++++++++++++++++++++++----- src/emu/machine.c | 36 +++++++++++++++++++++++ src/emu/machine.h | 4 +++ 4 files changed, 131 insertions(+), 20 deletions(-) diff --git a/src/emu/debug/debugcmd.c b/src/emu/debug/debugcmd.c index 688c9f21914..6622f61fafc 100644 --- a/src/emu/debug/debugcmd.c +++ b/src/emu/debug/debugcmd.c @@ -129,6 +129,8 @@ static void execute_rpclear(running_machine &machine, int ref, int params, const 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_statesave(running_machine &machine, int ref, int params, const char **param); +static void execute_stateload(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_dump(running_machine &machine, int ref, int params, const char **param); @@ -326,6 +328,11 @@ void debug_command_init(running_machine &machine) debug_console_register_command(machine, "hotspot", CMDFLAG_NONE, 0, 0, 3, execute_hotspot); + debug_console_register_command(machine, "statesave", CMDFLAG_NONE, 0, 1, 1, execute_statesave); + debug_console_register_command(machine, "ss", CMDFLAG_NONE, 0, 1, 1, execute_statesave); + debug_console_register_command(machine, "stateload", CMDFLAG_NONE, 0, 1, 1, execute_stateload); + debug_console_register_command(machine, "sl", CMDFLAG_NONE, 0, 1, 1, execute_stateload); + debug_console_register_command(machine, "save", CMDFLAG_NONE, AS_PROGRAM, 3, 4, execute_save); debug_console_register_command(machine, "saved", CMDFLAG_NONE, AS_DATA, 3, 4, execute_save); debug_console_register_command(machine, "savei", CMDFLAG_NONE, AS_IO, 3, 4, execute_save); @@ -380,22 +387,22 @@ void debug_command_init(running_machine &machine) debug_console_register_command(machine, "source", CMDFLAG_NONE, 0, 1, 1, execute_source); - debug_console_register_command(machine, "map", CMDFLAG_NONE, AS_PROGRAM, 1, 1, execute_map); - debug_console_register_command(machine, "mapd", CMDFLAG_NONE, AS_DATA, 1, 1, execute_map); - debug_console_register_command(machine, "mapi", CMDFLAG_NONE, AS_IO, 1, 1, execute_map); - debug_console_register_command(machine, "memdump", CMDFLAG_NONE, 0, 0, 1, execute_memdump); + debug_console_register_command(machine, "map", CMDFLAG_NONE, AS_PROGRAM, 1, 1, execute_map); + debug_console_register_command(machine, "mapd", CMDFLAG_NONE, AS_DATA, 1, 1, execute_map); + debug_console_register_command(machine, "mapi", CMDFLAG_NONE, AS_IO, 1, 1, execute_map); + debug_console_register_command(machine, "memdump", CMDFLAG_NONE, 0, 0, 1, execute_memdump); - debug_console_register_command(machine, "symlist", CMDFLAG_NONE, 0, 0, 1, execute_symlist); + debug_console_register_command(machine, "symlist", CMDFLAG_NONE, 0, 0, 1, execute_symlist); - debug_console_register_command(machine, "softreset", CMDFLAG_NONE, 0, 0, 1, execute_softreset); - debug_console_register_command(machine, "hardreset", CMDFLAG_NONE, 0, 0, 1, execute_hardreset); + debug_console_register_command(machine, "softreset", CMDFLAG_NONE, 0, 0, 1, execute_softreset); + debug_console_register_command(machine, "hardreset", CMDFLAG_NONE, 0, 0, 1, execute_hardreset); - debug_console_register_command(machine, "images", CMDFLAG_NONE, 0, 0, 0, execute_images); - debug_console_register_command(machine, "mount", CMDFLAG_NONE, 0, 2, 2, execute_mount); - debug_console_register_command(machine, "unmount", CMDFLAG_NONE, 0, 1, 1, execute_unmount); + debug_console_register_command(machine, "images", CMDFLAG_NONE, 0, 0, 0, execute_images); + debug_console_register_command(machine, "mount", CMDFLAG_NONE, 0, 2, 2, execute_mount); + debug_console_register_command(machine, "unmount", CMDFLAG_NONE, 0, 1, 1, execute_unmount); - debug_console_register_command(machine, "input", CMDFLAG_NONE, 0, 1, 1, execute_input); - debug_console_register_command(machine, "dumpkbd", CMDFLAG_NONE, 0, 0, 1, execute_dumpkbd); + debug_console_register_command(machine, "input", CMDFLAG_NONE, 0, 1, 1, execute_input); + debug_console_register_command(machine, "dumpkbd", CMDFLAG_NONE, 0, 0, 1, execute_dumpkbd); machine.add_notifier(MACHINE_NOTIFY_EXIT, machine_notify_delegate(FUNC(debug_command_exit), &machine)); @@ -1694,6 +1701,38 @@ static void execute_hotspot(running_machine &machine, int ref, int params, const } +/*------------------------------------------------- + execute_statesave - execute the statesave command +-------------------------------------------------*/ + +static void execute_statesave(running_machine &machine, int ref, int params, const char *param[]) +{ + astring filename(param[0]); + machine.immediate_save(filename); + debug_console_printf(machine, "State save attempted. Please refer to window message popup for results.\n"); +} + + +/*------------------------------------------------- + execute_stateload - execute the stateload command +-------------------------------------------------*/ + +static void execute_stateload(running_machine &machine, int ref, int params, const char *param[]) +{ + astring filename(param[0]); + machine.immediate_load(filename); + + // Clear all PC & memory tracks + device_iterator iter(machine.root_device()); + for (device_t *device = iter.first(); device != NULL; device = iter.next()) + { + device->debug()->track_pc_data_clear(); + device->debug()->track_mem_data_clear(); + } + debug_console_printf(machine, "State load attempted. Please refer to window message popup for results.\n"); +} + + /*------------------------------------------------- execute_save - execute the save command -------------------------------------------------*/ diff --git a/src/emu/debug/debughlp.c b/src/emu/debug/debughlp.c index de89766aac1..1a06b2cc30a 100644 --- a/src/emu/debug/debughlp.c +++ b/src/emu/debug/debughlp.c @@ -87,14 +87,16 @@ static const help_item static_help_list[] = " printf [,[,...]] -- prints one or more s to the console using \n" " logerror [,[,...]] -- outputs one or more s to the error.log\n" " tracelog [,[,...]] -- outputs one or more s to the trace file using \n" - " history [,] -- outputs a brief history of visited opcodes.\n" - " trackpc [,,] -- visually track visited opcodes [boolean to turn on and off, for the given cpu, clear].\n" - " trackmem [,] -- record which PC writes to each memory address [boolean to turn on and off, clear].\n" - " pcatmemp
[,] -- query which PC wrote to a given program memory address for the current CPU.\n" - " pcatmemd
[,] -- query which PC wrote to a given data memory address for the current CPU.\n" - " pcatmemi
[,] -- query which PC wrote to a given I/O memory address for the current CPU.\n" - " (Note: you can also query this info by right clicking in a memory window.\n" - " snap [] -- save a screen snapshot\n" + " history [,] -- outputs a brief history of visited opcodes\n" + " trackpc [,,] -- visually track visited opcodes [boolean to turn on and off, for the given cpu, clear]\n" + " trackmem [,] -- record which PC writes to each memory address [boolean to turn on and off, clear]\n" + " pcatmemp
[,] -- query which PC wrote to a given program memory address for the current CPU\n" + " pcatmemd
[,] -- query which PC wrote to a given data memory address for the current CPU\n" + " pcatmemi
[,] -- query which PC wrote to a given I/O memory address for the current CPU\n" + " (Note: you can also query this info by right clicking in a memory window\n" + " statesave[ss] -- save a state file for the current driver\n" + " stateload[sl] -- load a state file for the current driver\n" + " snap [] -- save a screen snapshot.\n" " source -- reads commands from and executes them one by one\n" " quit -- exits MAME and the debugger\n" }, @@ -434,6 +436,36 @@ static const help_item static_help_list[] = "pcatmem 400000\n" " Print which PC wrote this CPU's memory location 0x400000.\n" }, + { + "statesave[ss]", + "\n" + " statesave[ss] \n" + "\n" + "The statesave command creates a save state at this exact moment in time. " + "The given state file gets written to the standard state directory (sta), and gets .sta to it - " + "no file extension necessary. All output for this command is currently echoed into the " + "running machine window.\n" + "\n" + "Examples:\n" + "\n" + "statesave foo\n" + " Writes file 'foo.sta' in the default state save directory.\n" + }, + { + "stateload[sl]", + "\n" + " stateload[ss] \n" + "\n" + "The stateload command retrieves a save state from disk. " + "The given state file gets read from the standard state directory (sta), and gets .sta to it - " + "no file extension necessary. All output for this command is currently echoed into the " + "running machine window. Previous memory and PC tracking statistics are cleared.\n" + "\n" + "Examples:\n" + "\n" + "stateload foo\n" + " Reads file 'foo.sta' from the default state save directory.\n" + }, { "snap", "\n" diff --git a/src/emu/machine.c b/src/emu/machine.c index 2bf51875ccd..8c9ac74acdc 100644 --- a/src/emu/machine.c +++ b/src/emu/machine.c @@ -584,6 +584,24 @@ void running_machine::schedule_save(const char *filename) } +//------------------------------------------------- +// immediate_save - save state. +//------------------------------------------------- + +void running_machine::immediate_save(const char *filename) +{ + // specify the filename to save or load + set_saveload_filename(filename); + + // set up some parameters for handle_saveload() + m_saveload_schedule = SLS_SAVE; + m_saveload_schedule_time = this->time(); + + // jump right into the save, anonymous timers can't hurt us! + handle_saveload(); +} + + //------------------------------------------------- // schedule_load - schedule a load to occur as // soon as possible @@ -603,6 +621,24 @@ void running_machine::schedule_load(const char *filename) } +//------------------------------------------------- +// immediate_load - load state. +//------------------------------------------------- + +void running_machine::immediate_load(const char *filename) +{ + // specify the filename to save or load + set_saveload_filename(filename); + + // set up some parameters for handle_saveload() + m_saveload_schedule = SLS_LOAD; + m_saveload_schedule_time = this->time(); + + // jump right into the load, anonymous timers can't hurt us + handle_saveload(); +} + + //------------------------------------------------- // pause - pause the system //------------------------------------------------- diff --git a/src/emu/machine.h b/src/emu/machine.h index 47c77f1479d..ffdaa8a7e39 100644 --- a/src/emu/machine.h +++ b/src/emu/machine.h @@ -264,6 +264,10 @@ public: void add_logerror_callback(logerror_callback callback); void set_ui_active(bool active) { m_ui_active = active; } + // TODO: Do saves and loads still require scheduling? + void immediate_save(const char *filename); + void immediate_load(const char *filename); + // scheduled operations void schedule_exit(); void schedule_hard_reset();