diff options
Diffstat (limited to 'src/emu/debug/debugcmd.cpp')
-rw-r--r-- | src/emu/debug/debugcmd.cpp | 1801 |
1 files changed, 1016 insertions, 785 deletions
diff --git a/src/emu/debug/debugcmd.cpp b/src/emu/debug/debugcmd.cpp index 58cc85f7a86..b7bea75503d 100644 --- a/src/emu/debug/debugcmd.cpp +++ b/src/emu/debug/debugcmd.cpp @@ -28,6 +28,35 @@ +namespace { + +template <typename T> +inline std::string_view::size_type find_delimiter(std::string_view str, T &&is_delim) +{ + unsigned parens = 0; + for (std::string_view::size_type i = 0; str.length() > i; ++i) + { + if (str[i] == '(') + { + ++parens; + } + else if (parens) + { + if (str[i] == ')') + --parens; + } + else if (is_delim(str[i])) + { + return i; + } + } + return std::string_view::npos; +} + +} // anonymous namespace + + + /*************************************************************************** CONSTANTS ***************************************************************************/ @@ -113,34 +142,50 @@ debugger_commands::debugger_commands(running_machine& machine, debugger_cpu& cpu : m_machine(machine) , m_console(console) { + using namespace std::placeholders; m_global_array = std::make_unique<global_entry []>(MAX_GLOBALS); symbol_table &symtable = cpu.global_symtable(); - /* add a few simple global functions */ - using namespace std::placeholders; - symtable.add("min", 2, 2, std::bind(&debugger_commands::execute_min, this, _1, _2)); - symtable.add("max", 2, 2, std::bind(&debugger_commands::execute_max, this, _1, _2)); - symtable.add("if", 3, 3, std::bind(&debugger_commands::execute_if, this, _1, _2)); - symtable.add("abs", 1, 1, std::bind(&debugger_commands::execute_abs, this, _1, _2)); - symtable.add("bit", 2, 3, std::bind(&debugger_commands::execute_bit, this, _1, _2)); - symtable.add("s8", 1, 1, std::bind(&debugger_commands::execute_s8, this, _1, _2)); - symtable.add("s16", 1, 1, std::bind(&debugger_commands::execute_s16, this, _1, _2)); - symtable.add("s32", 1, 1, std::bind(&debugger_commands::execute_s32, this, _1, _2)); + // add a few simple global functions + symtable.add("min", 2, 2, // lower of two values + [] (int params, const u64 *param) -> u64 + { return (std::min)(param[0], param[1]); }); + symtable.add("max", 2, 2, // higher of two values + [] (int params, const u64 *param) -> u64 + { return (std::max)(param[0], param[1]); }); + symtable.add("if", 3, 3, // a ? b : c + [] (int params, const u64 *param) -> u64 + { return param[0] ? param[1] : param[2]; }); + symtable.add("abs", 1, 1, // absolute value of signed number + [] (int params, const u64 *param) -> u64 + { return std::abs(s64(param[0])); }); + symtable.add("bit", 2, 3, // extract bit field + [] (int params, const u64 *param) -> u64 + { return (params == 2) ? BIT(param[0], param[1]) : BIT(param[0], param[1], param[2]); }); + symtable.add("s8", 1, 1, // sign-extend from 8 bits + [] (int params, const u64 *param) -> u64 + { return s64(s8(u8(param[0]))); }); + symtable.add("s16", 1, 1, // sign-extend from 16 bits + [] (int params, const u64 *param) -> u64 + { return s64(s16(u16(param[0]))); }); + symtable.add("s32", 1, 1, // sign-extend from 32 bits + [] (int params, const u64 *param) -> u64 + { return s64(s32(u32(param[0]))); }); symtable.add("cpunum", std::bind(&debugger_commands::get_cpunum, this)); - /* add all single-entry save state globals */ + // add all single-entry save state globals for (int itemnum = 0; itemnum < MAX_GLOBALS; itemnum++) { void *base; u32 valsize, valcount, blockcount, stride; - /* stop when we run out of items */ + // stop when we run out of items const char* name = m_machine.save().indexed_item(itemnum, base, valsize, valcount, blockcount, stride); if (!name) break; - /* if this is a single-entry global, add it */ + // if this is a single-entry global, add it if ((valcount == 1) && (blockcount == 1) && strstr(name, "/globals/")) { char symname[100]; @@ -154,176 +199,176 @@ debugger_commands::debugger_commands(running_machine& machine, debugger_cpu& cpu } } - /* add all the commands */ - m_console.register_command("help", CMDFLAG_NONE, 0, 0, 1, std::bind(&debugger_commands::execute_help, this, _1, _2)); - m_console.register_command("print", CMDFLAG_NONE, 0, 1, MAX_COMMAND_PARAMS, std::bind(&debugger_commands::execute_print, this, _1, _2)); - m_console.register_command("printf", CMDFLAG_NONE, 0, 1, MAX_COMMAND_PARAMS, std::bind(&debugger_commands::execute_printf, this, _1, _2)); - m_console.register_command("logerror", CMDFLAG_NONE, 0, 1, MAX_COMMAND_PARAMS, std::bind(&debugger_commands::execute_logerror, this, _1, _2)); - m_console.register_command("tracelog", CMDFLAG_NONE, 0, 1, MAX_COMMAND_PARAMS, std::bind(&debugger_commands::execute_tracelog, this, _1, _2)); - m_console.register_command("tracesym", CMDFLAG_NONE, 0, 1, MAX_COMMAND_PARAMS, std::bind(&debugger_commands::execute_tracesym, this, _1, _2)); - m_console.register_command("cls", CMDFLAG_NONE, 0, 0, 0, std::bind(&debugger_commands::execute_cls, this, _1, _2)); - m_console.register_command("quit", CMDFLAG_NONE, 0, 0, 0, std::bind(&debugger_commands::execute_quit, this, _1, _2)); - m_console.register_command("exit", CMDFLAG_NONE, 0, 0, 0, std::bind(&debugger_commands::execute_quit, this, _1, _2)); - m_console.register_command("do", CMDFLAG_NONE, 0, 1, 1, std::bind(&debugger_commands::execute_do, this, _1, _2)); - m_console.register_command("step", CMDFLAG_NONE, 0, 0, 1, std::bind(&debugger_commands::execute_step, this, _1, _2)); - m_console.register_command("s", CMDFLAG_NONE, 0, 0, 1, std::bind(&debugger_commands::execute_step, this, _1, _2)); - m_console.register_command("over", CMDFLAG_NONE, 0, 0, 1, std::bind(&debugger_commands::execute_over, this, _1, _2)); - m_console.register_command("o", CMDFLAG_NONE, 0, 0, 1, std::bind(&debugger_commands::execute_over, this, _1, _2)); - m_console.register_command("out" , CMDFLAG_NONE, 0, 0, 0, std::bind(&debugger_commands::execute_out, this, _1, _2)); - m_console.register_command("go", CMDFLAG_NONE, 0, 0, 1, std::bind(&debugger_commands::execute_go, this, _1, _2)); - m_console.register_command("g", CMDFLAG_NONE, 0, 0, 1, std::bind(&debugger_commands::execute_go, this, _1, _2)); - m_console.register_command("gvblank", CMDFLAG_NONE, 0, 0, 0, std::bind(&debugger_commands::execute_go_vblank, this, _1, _2)); - m_console.register_command("gv", CMDFLAG_NONE, 0, 0, 0, std::bind(&debugger_commands::execute_go_vblank, this, _1, _2)); - m_console.register_command("gint", CMDFLAG_NONE, 0, 0, 1, std::bind(&debugger_commands::execute_go_interrupt, this, _1, _2)); - m_console.register_command("gi", CMDFLAG_NONE, 0, 0, 1, std::bind(&debugger_commands::execute_go_interrupt, this, _1, _2)); - m_console.register_command("gex", CMDFLAG_NONE, 0, 0, 2, std::bind(&debugger_commands::execute_go_exception, this, _1, _2)); - m_console.register_command("ge", CMDFLAG_NONE, 0, 0, 2, std::bind(&debugger_commands::execute_go_exception, this, _1, _2)); - m_console.register_command("gtime", CMDFLAG_NONE, 0, 0, 1, std::bind(&debugger_commands::execute_go_time, this, _1, _2)); - m_console.register_command("gt", CMDFLAG_NONE, 0, 0, 1, std::bind(&debugger_commands::execute_go_time, this, _1, _2)); - m_console.register_command("gp", CMDFLAG_NONE, 0, 0, 1, std::bind(&debugger_commands::execute_go_privilege, this, _1, _2)); - m_console.register_command("next", CMDFLAG_NONE, 0, 0, 0, std::bind(&debugger_commands::execute_next, this, _1, _2)); - m_console.register_command("n", CMDFLAG_NONE, 0, 0, 0, std::bind(&debugger_commands::execute_next, this, _1, _2)); - m_console.register_command("focus", CMDFLAG_NONE, 0, 1, 1, std::bind(&debugger_commands::execute_focus, this, _1, _2)); - m_console.register_command("ignore", CMDFLAG_NONE, 0, 0, MAX_COMMAND_PARAMS, std::bind(&debugger_commands::execute_ignore, this, _1, _2)); - m_console.register_command("observe", CMDFLAG_NONE, 0, 0, MAX_COMMAND_PARAMS, std::bind(&debugger_commands::execute_observe, this, _1, _2)); - m_console.register_command("suspend", CMDFLAG_NONE, 0, 0, MAX_COMMAND_PARAMS, std::bind(&debugger_commands::execute_suspend, this, _1, _2)); - m_console.register_command("resume", CMDFLAG_NONE, 0, 0, MAX_COMMAND_PARAMS, std::bind(&debugger_commands::execute_resume, this, _1, _2)); - m_console.register_command("cpulist", CMDFLAG_NONE, 0, 0, 0, std::bind(&debugger_commands::execute_cpulist, this, _1, _2)); - - m_console.register_command("comadd", CMDFLAG_NONE, 0, 1, 2, std::bind(&debugger_commands::execute_comment_add, this, _1, _2)); - m_console.register_command("//", CMDFLAG_NONE, 0, 1, 2, std::bind(&debugger_commands::execute_comment_add, this, _1, _2)); - m_console.register_command("comdelete", CMDFLAG_NONE, 0, 1, 1, std::bind(&debugger_commands::execute_comment_del, this, _1, _2)); - m_console.register_command("comsave", CMDFLAG_NONE, 0, 0, 0, std::bind(&debugger_commands::execute_comment_save, this, _1, _2)); - m_console.register_command("comlist", CMDFLAG_NONE, 0, 0, 0, std::bind(&debugger_commands::execute_comment_list, this, _1, _2)); - m_console.register_command("commit", CMDFLAG_NONE, 0, 1, 2, std::bind(&debugger_commands::execute_comment_commit, this, _1, _2)); - m_console.register_command("/*", CMDFLAG_NONE, 0, 1, 2, std::bind(&debugger_commands::execute_comment_commit, this, _1, _2)); - - m_console.register_command("bpset", CMDFLAG_NONE, 0, 1, 3, std::bind(&debugger_commands::execute_bpset, this, _1, _2)); - m_console.register_command("bp", CMDFLAG_NONE, 0, 1, 3, std::bind(&debugger_commands::execute_bpset, this, _1, _2)); - m_console.register_command("bpclear", CMDFLAG_NONE, 0, 0, 1, std::bind(&debugger_commands::execute_bpclear, this, _1, _2)); - m_console.register_command("bpdisable", CMDFLAG_NONE, 0, 0, 1, std::bind(&debugger_commands::execute_bpdisenable, this, _1, _2)); - m_console.register_command("bpenable", CMDFLAG_NONE, 1, 0, 1, std::bind(&debugger_commands::execute_bpdisenable, this, _1, _2)); - m_console.register_command("bplist", CMDFLAG_NONE, 0, 0, 0, std::bind(&debugger_commands::execute_bplist, this, _1, _2)); - - m_console.register_command("wpset", CMDFLAG_NONE, AS_PROGRAM, 3, 5, std::bind(&debugger_commands::execute_wpset, this, _1, _2)); - m_console.register_command("wp", CMDFLAG_NONE, AS_PROGRAM, 3, 5, std::bind(&debugger_commands::execute_wpset, this, _1, _2)); - m_console.register_command("wpdset", CMDFLAG_NONE, AS_DATA, 3, 5, std::bind(&debugger_commands::execute_wpset, this, _1, _2)); - m_console.register_command("wpd", CMDFLAG_NONE, AS_DATA, 3, 5, std::bind(&debugger_commands::execute_wpset, this, _1, _2)); - m_console.register_command("wpiset", CMDFLAG_NONE, AS_IO, 3, 5, std::bind(&debugger_commands::execute_wpset, this, _1, _2)); - m_console.register_command("wpi", CMDFLAG_NONE, AS_IO, 3, 5, std::bind(&debugger_commands::execute_wpset, this, _1, _2)); - m_console.register_command("wposet", CMDFLAG_NONE, AS_OPCODES, 3, 5, std::bind(&debugger_commands::execute_wpset, this, _1, _2)); - m_console.register_command("wpo", CMDFLAG_NONE, AS_OPCODES, 3, 5, std::bind(&debugger_commands::execute_wpset, this, _1, _2)); - m_console.register_command("wpclear", CMDFLAG_NONE, 0, 0, 1, std::bind(&debugger_commands::execute_wpclear, this, _1, _2)); - m_console.register_command("wpdisable", CMDFLAG_NONE, 0, 0, 1, std::bind(&debugger_commands::execute_wpdisenable, this, _1, _2)); - m_console.register_command("wpenable", CMDFLAG_NONE, 1, 0, 1, std::bind(&debugger_commands::execute_wpdisenable, this, _1, _2)); - m_console.register_command("wplist", CMDFLAG_NONE, 0, 0, 0, std::bind(&debugger_commands::execute_wplist, this, _1, _2)); - - m_console.register_command("rpset", CMDFLAG_NONE, 0, 1, 2, std::bind(&debugger_commands::execute_rpset, this, _1, _2)); - m_console.register_command("rp", CMDFLAG_NONE, 0, 1, 2, std::bind(&debugger_commands::execute_rpset, this, _1, _2)); - m_console.register_command("rpclear", CMDFLAG_NONE, 0, 0, 1, std::bind(&debugger_commands::execute_rpclear, this, _1, _2)); - m_console.register_command("rpdisable", CMDFLAG_NONE, 0, 0, 1, std::bind(&debugger_commands::execute_rpdisenable, this, _1, _2)); - m_console.register_command("rpenable", CMDFLAG_NONE, 1, 0, 1, std::bind(&debugger_commands::execute_rpdisenable, this, _1, _2)); - m_console.register_command("rplist", CMDFLAG_NONE, 0, 0, 0, std::bind(&debugger_commands::execute_rplist, this, _1, _2)); - - m_console.register_command("statesave", CMDFLAG_NONE, 0, 1, 1, std::bind(&debugger_commands::execute_statesave, this, _1, _2)); - m_console.register_command("ss", CMDFLAG_NONE, 0, 1, 1, std::bind(&debugger_commands::execute_statesave, this, _1, _2)); - m_console.register_command("stateload", CMDFLAG_NONE, 0, 1, 1, std::bind(&debugger_commands::execute_stateload, this, _1, _2)); - m_console.register_command("sl", CMDFLAG_NONE, 0, 1, 1, std::bind(&debugger_commands::execute_stateload, this, _1, _2)); - - m_console.register_command("rewind", CMDFLAG_NONE, 0, 0, 0, std::bind(&debugger_commands::execute_rewind, this, _1, _2)); - m_console.register_command("rw", CMDFLAG_NONE, 0, 0, 0, std::bind(&debugger_commands::execute_rewind, this, _1, _2)); - - m_console.register_command("save", CMDFLAG_NONE, AS_PROGRAM, 3, 4, std::bind(&debugger_commands::execute_save, this, _1, _2)); - m_console.register_command("saved", CMDFLAG_NONE, AS_DATA, 3, 4, std::bind(&debugger_commands::execute_save, this, _1, _2)); - m_console.register_command("savei", CMDFLAG_NONE, AS_IO, 3, 4, std::bind(&debugger_commands::execute_save, this, _1, _2)); - m_console.register_command("saveo", CMDFLAG_NONE, AS_OPCODES, 3, 4, std::bind(&debugger_commands::execute_save, this, _1, _2)); - m_console.register_command("saver", CMDFLAG_NONE, 0, 4, 4, std::bind(&debugger_commands::execute_saveregion, this, _1, _2)); - - m_console.register_command("load", CMDFLAG_NONE, AS_PROGRAM, 2, 4, std::bind(&debugger_commands::execute_load, this, _1, _2)); - m_console.register_command("loadd", CMDFLAG_NONE, AS_DATA, 2, 4, std::bind(&debugger_commands::execute_load, this, _1, _2)); - m_console.register_command("loadi", CMDFLAG_NONE, AS_IO, 2, 4, std::bind(&debugger_commands::execute_load, this, _1, _2)); - m_console.register_command("loado", CMDFLAG_NONE, AS_OPCODES, 2, 4, std::bind(&debugger_commands::execute_load, this, _1, _2)); - m_console.register_command("loadr", CMDFLAG_NONE, 0, 4, 4, std::bind(&debugger_commands::execute_loadregion, this, _1, _2)); - - m_console.register_command("dump", CMDFLAG_NONE, AS_PROGRAM, 3, 7, std::bind(&debugger_commands::execute_dump, this, _1, _2)); - m_console.register_command("dumpd", CMDFLAG_NONE, AS_DATA, 3, 7, std::bind(&debugger_commands::execute_dump, this, _1, _2)); - m_console.register_command("dumpi", CMDFLAG_NONE, AS_IO, 3, 7, std::bind(&debugger_commands::execute_dump, this, _1, _2)); - m_console.register_command("dumpo", CMDFLAG_NONE, AS_OPCODES, 3, 7, std::bind(&debugger_commands::execute_dump, this, _1, _2)); - - m_console.register_command("strdump", CMDFLAG_NONE, AS_PROGRAM, 3, 5, std::bind(&debugger_commands::execute_strdump, this, _1, _2)); - m_console.register_command("strdumpd", CMDFLAG_NONE, AS_DATA, 3, 5, std::bind(&debugger_commands::execute_strdump, this, _1, _2)); - m_console.register_command("strdumpi", CMDFLAG_NONE, AS_IO, 3, 5, std::bind(&debugger_commands::execute_strdump, this, _1, _2)); - m_console.register_command("strdumpo", CMDFLAG_NONE, AS_OPCODES, 3, 5, std::bind(&debugger_commands::execute_strdump, this, _1, _2)); - - m_console.register_command("cheatinit", CMDFLAG_NONE, 0, 0, 4, std::bind(&debugger_commands::execute_cheatinit, this, _1, _2)); - m_console.register_command("ci", CMDFLAG_NONE, 0, 0, 4, std::bind(&debugger_commands::execute_cheatinit, this, _1, _2)); - - m_console.register_command("cheatrange",CMDFLAG_NONE, 1, 2, 2, std::bind(&debugger_commands::execute_cheatinit, this, _1, _2)); - m_console.register_command("cr", CMDFLAG_NONE, 1, 2, 2, std::bind(&debugger_commands::execute_cheatinit, this, _1, _2)); - - m_console.register_command("cheatnext", CMDFLAG_NONE, 0, 1, 2, std::bind(&debugger_commands::execute_cheatnext, this, _1, _2)); - m_console.register_command("cn", CMDFLAG_NONE, 0, 1, 2, std::bind(&debugger_commands::execute_cheatnext, this, _1, _2)); - m_console.register_command("cheatnextf",CMDFLAG_NONE, 1, 1, 2, std::bind(&debugger_commands::execute_cheatnext, this, _1, _2)); - m_console.register_command("cnf", CMDFLAG_NONE, 1, 1, 2, std::bind(&debugger_commands::execute_cheatnext, this, _1, _2)); - - m_console.register_command("cheatlist", CMDFLAG_NONE, 0, 0, 1, std::bind(&debugger_commands::execute_cheatlist, this, _1, _2)); - m_console.register_command("cl", CMDFLAG_NONE, 0, 0, 1, std::bind(&debugger_commands::execute_cheatlist, this, _1, _2)); - - m_console.register_command("cheatundo", CMDFLAG_NONE, 0, 0, 0, std::bind(&debugger_commands::execute_cheatundo, this, _1, _2)); - m_console.register_command("cu", CMDFLAG_NONE, 0, 0, 0, std::bind(&debugger_commands::execute_cheatundo, this, _1, _2)); - - m_console.register_command("f", CMDFLAG_KEEP_QUOTES, AS_PROGRAM, 3, MAX_COMMAND_PARAMS, std::bind(&debugger_commands::execute_find, this, _1, _2)); - m_console.register_command("find", CMDFLAG_KEEP_QUOTES, AS_PROGRAM, 3, MAX_COMMAND_PARAMS, std::bind(&debugger_commands::execute_find, this, _1, _2)); - m_console.register_command("fd", CMDFLAG_KEEP_QUOTES, AS_DATA, 3, MAX_COMMAND_PARAMS, std::bind(&debugger_commands::execute_find, this, _1, _2)); - m_console.register_command("findd", CMDFLAG_KEEP_QUOTES, AS_DATA, 3, MAX_COMMAND_PARAMS, std::bind(&debugger_commands::execute_find, this, _1, _2)); - m_console.register_command("fi", CMDFLAG_KEEP_QUOTES, AS_IO, 3, MAX_COMMAND_PARAMS, std::bind(&debugger_commands::execute_find, this, _1, _2)); - m_console.register_command("findi", CMDFLAG_KEEP_QUOTES, AS_IO, 3, MAX_COMMAND_PARAMS, std::bind(&debugger_commands::execute_find, this, _1, _2)); - m_console.register_command("fo", CMDFLAG_KEEP_QUOTES, AS_OPCODES, 3, MAX_COMMAND_PARAMS, std::bind(&debugger_commands::execute_find, this, _1, _2)); - m_console.register_command("findo", CMDFLAG_KEEP_QUOTES, AS_OPCODES, 3, MAX_COMMAND_PARAMS, std::bind(&debugger_commands::execute_find, this, _1, _2)); - - m_console.register_command("fill", CMDFLAG_KEEP_QUOTES, AS_PROGRAM, 3, MAX_COMMAND_PARAMS, std::bind(&debugger_commands::execute_fill, this, _1, _2)); - m_console.register_command("filld", CMDFLAG_KEEP_QUOTES, AS_DATA, 3, MAX_COMMAND_PARAMS, std::bind(&debugger_commands::execute_fill, this, _1, _2)); - m_console.register_command("filli", CMDFLAG_KEEP_QUOTES, AS_IO, 3, MAX_COMMAND_PARAMS, std::bind(&debugger_commands::execute_fill, this, _1, _2)); - m_console.register_command("fillo", CMDFLAG_KEEP_QUOTES, AS_OPCODES, 3, MAX_COMMAND_PARAMS, std::bind(&debugger_commands::execute_fill, this, _1, _2)); - - m_console.register_command("dasm", CMDFLAG_NONE, 0, 3, 5, std::bind(&debugger_commands::execute_dasm, this, _1, _2)); - - m_console.register_command("trace", CMDFLAG_NONE, 0, 1, 4, std::bind(&debugger_commands::execute_trace, this, _1, _2)); - m_console.register_command("traceover", CMDFLAG_NONE, 0, 1, 4, std::bind(&debugger_commands::execute_traceover, this, _1, _2)); - m_console.register_command("traceflush",CMDFLAG_NONE, 0, 0, 0, std::bind(&debugger_commands::execute_traceflush, this, _1, _2)); - - m_console.register_command("history", CMDFLAG_NONE, 0, 0, 2, std::bind(&debugger_commands::execute_history, this, _1, _2)); - m_console.register_command("trackpc", CMDFLAG_NONE, 0, 0, 3, std::bind(&debugger_commands::execute_trackpc, this, _1, _2)); - - m_console.register_command("trackmem", CMDFLAG_NONE, 0, 0, 3, std::bind(&debugger_commands::execute_trackmem, this, _1, _2)); - m_console.register_command("pcatmemp", CMDFLAG_NONE, AS_PROGRAM, 1, 2, std::bind(&debugger_commands::execute_pcatmem, this, _1, _2)); - m_console.register_command("pcatmemd", CMDFLAG_NONE, AS_DATA, 1, 2, std::bind(&debugger_commands::execute_pcatmem, this, _1, _2)); - m_console.register_command("pcatmemi", CMDFLAG_NONE, AS_IO, 1, 2, std::bind(&debugger_commands::execute_pcatmem, this, _1, _2)); - m_console.register_command("pcatmemo", CMDFLAG_NONE, AS_OPCODES, 1, 2, std::bind(&debugger_commands::execute_pcatmem, this, _1, _2)); - - m_console.register_command("snap", CMDFLAG_NONE, 0, 0, 1, std::bind(&debugger_commands::execute_snap, this, _1, _2)); - - m_console.register_command("source", CMDFLAG_NONE, 0, 1, 1, std::bind(&debugger_commands::execute_source, this, _1, _2)); - - m_console.register_command("map", CMDFLAG_NONE, AS_PROGRAM, 1, 1, std::bind(&debugger_commands::execute_map, this, _1, _2)); - m_console.register_command("mapd", CMDFLAG_NONE, AS_DATA, 1, 1, std::bind(&debugger_commands::execute_map, this, _1, _2)); - m_console.register_command("mapi", CMDFLAG_NONE, AS_IO, 1, 1, std::bind(&debugger_commands::execute_map, this, _1, _2)); - m_console.register_command("mapo", CMDFLAG_NONE, AS_OPCODES, 1, 1, std::bind(&debugger_commands::execute_map, this, _1, _2)); - m_console.register_command("memdump", CMDFLAG_NONE, 0, 0, 1, std::bind(&debugger_commands::execute_memdump, this, _1, _2)); - - m_console.register_command("symlist", CMDFLAG_NONE, 0, 0, 1, std::bind(&debugger_commands::execute_symlist, this, _1, _2)); - - m_console.register_command("softreset", CMDFLAG_NONE, 0, 0, 1, std::bind(&debugger_commands::execute_softreset, this, _1, _2)); - m_console.register_command("hardreset", CMDFLAG_NONE, 0, 0, 1, std::bind(&debugger_commands::execute_hardreset, this, _1, _2)); - - m_console.register_command("images", CMDFLAG_NONE, 0, 0, 0, std::bind(&debugger_commands::execute_images, this, _1, _2)); - m_console.register_command("mount", CMDFLAG_NONE, 0, 2, 2, std::bind(&debugger_commands::execute_mount, this, _1, _2)); - m_console.register_command("unmount", CMDFLAG_NONE, 0, 1, 1, std::bind(&debugger_commands::execute_unmount, this, _1, _2)); - - m_console.register_command("input", CMDFLAG_NONE, 0, 1, 1, std::bind(&debugger_commands::execute_input, this, _1, _2)); - m_console.register_command("dumpkbd", CMDFLAG_NONE, 0, 0, 1, std::bind(&debugger_commands::execute_dumpkbd, this, _1, _2)); + // add all the commands + m_console.register_command("help", CMDFLAG_NONE, 0, 1, std::bind(&debugger_commands::execute_help, this, _1)); + m_console.register_command("print", CMDFLAG_NONE, 1, MAX_COMMAND_PARAMS, std::bind(&debugger_commands::execute_print, this, _1)); + m_console.register_command("printf", CMDFLAG_NONE, 1, MAX_COMMAND_PARAMS, std::bind(&debugger_commands::execute_printf, this, _1)); + m_console.register_command("logerror", CMDFLAG_NONE, 1, MAX_COMMAND_PARAMS, std::bind(&debugger_commands::execute_logerror, this, _1)); + m_console.register_command("tracelog", CMDFLAG_NONE, 1, MAX_COMMAND_PARAMS, std::bind(&debugger_commands::execute_tracelog, this, _1)); + m_console.register_command("tracesym", CMDFLAG_NONE, 1, MAX_COMMAND_PARAMS, std::bind(&debugger_commands::execute_tracesym, this, _1)); + m_console.register_command("cls", CMDFLAG_NONE, 0, 0, std::bind(&debugger_commands::execute_cls, this, _1)); + m_console.register_command("quit", CMDFLAG_NONE, 0, 0, std::bind(&debugger_commands::execute_quit, this, _1)); + m_console.register_command("exit", CMDFLAG_NONE, 0, 0, std::bind(&debugger_commands::execute_quit, this, _1)); + m_console.register_command("do", CMDFLAG_NONE, 1, 1, std::bind(&debugger_commands::execute_do, this, _1)); + m_console.register_command("step", CMDFLAG_NONE, 0, 1, std::bind(&debugger_commands::execute_step, this, _1)); + m_console.register_command("s", CMDFLAG_NONE, 0, 1, std::bind(&debugger_commands::execute_step, this, _1)); + m_console.register_command("over", CMDFLAG_NONE, 0, 1, std::bind(&debugger_commands::execute_over, this, _1)); + m_console.register_command("o", CMDFLAG_NONE, 0, 1, std::bind(&debugger_commands::execute_over, this, _1)); + m_console.register_command("out" , CMDFLAG_NONE, 0, 0, std::bind(&debugger_commands::execute_out, this, _1)); + m_console.register_command("go", CMDFLAG_NONE, 0, 1, std::bind(&debugger_commands::execute_go, this, _1)); + m_console.register_command("g", CMDFLAG_NONE, 0, 1, std::bind(&debugger_commands::execute_go, this, _1)); + m_console.register_command("gvblank", CMDFLAG_NONE, 0, 0, std::bind(&debugger_commands::execute_go_vblank, this, _1)); + m_console.register_command("gv", CMDFLAG_NONE, 0, 0, std::bind(&debugger_commands::execute_go_vblank, this, _1)); + m_console.register_command("gint", CMDFLAG_NONE, 0, 1, std::bind(&debugger_commands::execute_go_interrupt, this, _1)); + m_console.register_command("gi", CMDFLAG_NONE, 0, 1, std::bind(&debugger_commands::execute_go_interrupt, this, _1)); + m_console.register_command("gex", CMDFLAG_NONE, 0, 2, std::bind(&debugger_commands::execute_go_exception, this, _1)); + m_console.register_command("ge", CMDFLAG_NONE, 0, 2, std::bind(&debugger_commands::execute_go_exception, this, _1)); + m_console.register_command("gtime", CMDFLAG_NONE, 0, 1, std::bind(&debugger_commands::execute_go_time, this, _1)); + m_console.register_command("gt", CMDFLAG_NONE, 0, 1, std::bind(&debugger_commands::execute_go_time, this, _1)); + m_console.register_command("gp", CMDFLAG_NONE, 0, 1, std::bind(&debugger_commands::execute_go_privilege, this, _1)); + m_console.register_command("next", CMDFLAG_NONE, 0, 0, std::bind(&debugger_commands::execute_next, this, _1)); + m_console.register_command("n", CMDFLAG_NONE, 0, 0, std::bind(&debugger_commands::execute_next, this, _1)); + m_console.register_command("focus", CMDFLAG_NONE, 1, 1, std::bind(&debugger_commands::execute_focus, this, _1)); + m_console.register_command("ignore", CMDFLAG_NONE, 0, MAX_COMMAND_PARAMS, std::bind(&debugger_commands::execute_ignore, this, _1)); + m_console.register_command("observe", CMDFLAG_NONE, 0, MAX_COMMAND_PARAMS, std::bind(&debugger_commands::execute_observe, this, _1)); + m_console.register_command("suspend", CMDFLAG_NONE, 0, MAX_COMMAND_PARAMS, std::bind(&debugger_commands::execute_suspend, this, _1)); + m_console.register_command("resume", CMDFLAG_NONE, 0, MAX_COMMAND_PARAMS, std::bind(&debugger_commands::execute_resume, this, _1)); + m_console.register_command("cpulist", CMDFLAG_NONE, 0, 0, std::bind(&debugger_commands::execute_cpulist, this, _1)); + + m_console.register_command("comadd", CMDFLAG_NONE, 1, 2, std::bind(&debugger_commands::execute_comment_add, this, _1)); + m_console.register_command("//", CMDFLAG_NONE, 1, 2, std::bind(&debugger_commands::execute_comment_add, this, _1)); + m_console.register_command("comdelete", CMDFLAG_NONE, 1, 1, std::bind(&debugger_commands::execute_comment_del, this, _1)); + m_console.register_command("comsave", CMDFLAG_NONE, 0, 0, std::bind(&debugger_commands::execute_comment_save, this, _1)); + m_console.register_command("comlist", CMDFLAG_NONE, 0, 0, std::bind(&debugger_commands::execute_comment_list, this, _1)); + m_console.register_command("commit", CMDFLAG_NONE, 1, 2, std::bind(&debugger_commands::execute_comment_commit, this, _1)); + m_console.register_command("/*", CMDFLAG_NONE, 1, 2, std::bind(&debugger_commands::execute_comment_commit, this, _1)); + + m_console.register_command("bpset", CMDFLAG_NONE, 1, 3, std::bind(&debugger_commands::execute_bpset, this, _1)); + m_console.register_command("bp", CMDFLAG_NONE, 1, 3, std::bind(&debugger_commands::execute_bpset, this, _1)); + m_console.register_command("bpclear", CMDFLAG_NONE, 0, 1, std::bind(&debugger_commands::execute_bpclear, this, _1)); + m_console.register_command("bpdisable", CMDFLAG_NONE, 0, 1, std::bind(&debugger_commands::execute_bpdisenable, this, false, _1)); + m_console.register_command("bpenable", CMDFLAG_NONE, 0, 1, std::bind(&debugger_commands::execute_bpdisenable, this, true, _1)); + m_console.register_command("bplist", CMDFLAG_NONE, 0, 0, std::bind(&debugger_commands::execute_bplist, this, _1)); + + m_console.register_command("wpset", CMDFLAG_NONE, 3, 5, std::bind(&debugger_commands::execute_wpset, this, -1, _1)); + m_console.register_command("wp", CMDFLAG_NONE, 3, 5, std::bind(&debugger_commands::execute_wpset, this, -1, _1)); + m_console.register_command("wpdset", CMDFLAG_NONE, 3, 5, std::bind(&debugger_commands::execute_wpset, this, AS_DATA, _1)); + m_console.register_command("wpd", CMDFLAG_NONE, 3, 5, std::bind(&debugger_commands::execute_wpset, this, AS_DATA, _1)); + m_console.register_command("wpiset", CMDFLAG_NONE, 3, 5, std::bind(&debugger_commands::execute_wpset, this, AS_IO, _1)); + m_console.register_command("wpi", CMDFLAG_NONE, 3, 5, std::bind(&debugger_commands::execute_wpset, this, AS_IO, _1)); + m_console.register_command("wposet", CMDFLAG_NONE, 3, 5, std::bind(&debugger_commands::execute_wpset, this, AS_OPCODES, _1)); + m_console.register_command("wpo", CMDFLAG_NONE, 3, 5, std::bind(&debugger_commands::execute_wpset, this, AS_OPCODES, _1)); + m_console.register_command("wpclear", CMDFLAG_NONE, 0, 1, std::bind(&debugger_commands::execute_wpclear, this, _1)); + m_console.register_command("wpdisable", CMDFLAG_NONE, 0, 1, std::bind(&debugger_commands::execute_wpdisenable, this, false, _1)); + m_console.register_command("wpenable", CMDFLAG_NONE, 0, 1, std::bind(&debugger_commands::execute_wpdisenable, this, true, _1)); + m_console.register_command("wplist", CMDFLAG_NONE, 0, 0, std::bind(&debugger_commands::execute_wplist, this, _1)); + + m_console.register_command("rpset", CMDFLAG_NONE, 1, 2, std::bind(&debugger_commands::execute_rpset, this, _1)); + m_console.register_command("rp", CMDFLAG_NONE, 1, 2, std::bind(&debugger_commands::execute_rpset, this, _1)); + m_console.register_command("rpclear", CMDFLAG_NONE, 0, 1, std::bind(&debugger_commands::execute_rpclear, this, _1)); + m_console.register_command("rpdisable", CMDFLAG_NONE, 0, 1, std::bind(&debugger_commands::execute_rpdisenable, this, false, _1)); + m_console.register_command("rpenable", CMDFLAG_NONE, 0, 1, std::bind(&debugger_commands::execute_rpdisenable, this, true, _1)); + m_console.register_command("rplist", CMDFLAG_NONE, 0, 0, std::bind(&debugger_commands::execute_rplist, this, _1)); + + m_console.register_command("statesave", CMDFLAG_NONE, 1, 1, std::bind(&debugger_commands::execute_statesave, this, _1)); + m_console.register_command("ss", CMDFLAG_NONE, 1, 1, std::bind(&debugger_commands::execute_statesave, this, _1)); + m_console.register_command("stateload", CMDFLAG_NONE, 1, 1, std::bind(&debugger_commands::execute_stateload, this, _1)); + m_console.register_command("sl", CMDFLAG_NONE, 1, 1, std::bind(&debugger_commands::execute_stateload, this, _1)); + + m_console.register_command("rewind", CMDFLAG_NONE, 0, 0, std::bind(&debugger_commands::execute_rewind, this, _1)); + m_console.register_command("rw", CMDFLAG_NONE, 0, 0, std::bind(&debugger_commands::execute_rewind, this, _1)); + + m_console.register_command("save", CMDFLAG_NONE, 3, 3, std::bind(&debugger_commands::execute_save, this, -1, _1)); + m_console.register_command("saved", CMDFLAG_NONE, 3, 3, std::bind(&debugger_commands::execute_save, this, AS_DATA, _1)); + m_console.register_command("savei", CMDFLAG_NONE, 3, 3, std::bind(&debugger_commands::execute_save, this, AS_IO, _1)); + m_console.register_command("saveo", CMDFLAG_NONE, 3, 3, std::bind(&debugger_commands::execute_save, this, AS_OPCODES, _1)); + m_console.register_command("saver", CMDFLAG_NONE, 4, 4, std::bind(&debugger_commands::execute_saveregion, this, _1)); + + m_console.register_command("load", CMDFLAG_NONE, 2, 3, std::bind(&debugger_commands::execute_load, this, -1, _1)); + m_console.register_command("loadd", CMDFLAG_NONE, 2, 3, std::bind(&debugger_commands::execute_load, this, AS_DATA, _1)); + m_console.register_command("loadi", CMDFLAG_NONE, 2, 3, std::bind(&debugger_commands::execute_load, this, AS_IO, _1)); + m_console.register_command("loado", CMDFLAG_NONE, 2, 3, std::bind(&debugger_commands::execute_load, this, AS_OPCODES, _1)); + m_console.register_command("loadr", CMDFLAG_NONE, 4, 4, std::bind(&debugger_commands::execute_loadregion, this, _1)); + + m_console.register_command("dump", CMDFLAG_NONE, 3, 6, std::bind(&debugger_commands::execute_dump, this, -1, _1)); + m_console.register_command("dumpd", CMDFLAG_NONE, 3, 6, std::bind(&debugger_commands::execute_dump, this, AS_DATA, _1)); + m_console.register_command("dumpi", CMDFLAG_NONE, 3, 6, std::bind(&debugger_commands::execute_dump, this, AS_IO, _1)); + m_console.register_command("dumpo", CMDFLAG_NONE, 3, 6, std::bind(&debugger_commands::execute_dump, this, AS_OPCODES, _1)); + + m_console.register_command("strdump", CMDFLAG_NONE, 3, 4, std::bind(&debugger_commands::execute_strdump, this, -1, _1)); + m_console.register_command("strdumpd", CMDFLAG_NONE, 3, 4, std::bind(&debugger_commands::execute_strdump, this, AS_DATA, _1)); + m_console.register_command("strdumpi", CMDFLAG_NONE, 3, 4, std::bind(&debugger_commands::execute_strdump, this, AS_IO, _1)); + m_console.register_command("strdumpo", CMDFLAG_NONE, 3, 4, std::bind(&debugger_commands::execute_strdump, this, AS_OPCODES, _1)); + + m_console.register_command("cheatinit", CMDFLAG_NONE, 0, 4, std::bind(&debugger_commands::execute_cheatrange, this, true, _1)); + m_console.register_command("ci", CMDFLAG_NONE, 0, 4, std::bind(&debugger_commands::execute_cheatrange, this, true, _1)); + + m_console.register_command("cheatrange",CMDFLAG_NONE, 2, 2, std::bind(&debugger_commands::execute_cheatrange, this, false, _1)); + m_console.register_command("cr", CMDFLAG_NONE, 2, 2, std::bind(&debugger_commands::execute_cheatrange, this, false, _1)); + + m_console.register_command("cheatnext", CMDFLAG_NONE, 1, 2, std::bind(&debugger_commands::execute_cheatnext, this, false, _1)); + m_console.register_command("cn", CMDFLAG_NONE, 1, 2, std::bind(&debugger_commands::execute_cheatnext, this, false, _1)); + m_console.register_command("cheatnextf",CMDFLAG_NONE, 1, 2, std::bind(&debugger_commands::execute_cheatnext, this, true, _1)); + m_console.register_command("cnf", CMDFLAG_NONE, 1, 2, std::bind(&debugger_commands::execute_cheatnext, this, true, _1)); + + m_console.register_command("cheatlist", CMDFLAG_NONE, 0, 1, std::bind(&debugger_commands::execute_cheatlist, this, _1)); + m_console.register_command("cl", CMDFLAG_NONE, 0, 1, std::bind(&debugger_commands::execute_cheatlist, this, _1)); + + m_console.register_command("cheatundo", CMDFLAG_NONE, 0, 0, std::bind(&debugger_commands::execute_cheatundo, this, _1)); + m_console.register_command("cu", CMDFLAG_NONE, 0, 0, std::bind(&debugger_commands::execute_cheatundo, this, _1)); + + m_console.register_command("f", CMDFLAG_KEEP_QUOTES, 3, MAX_COMMAND_PARAMS, std::bind(&debugger_commands::execute_find, this, -1, _1)); + m_console.register_command("find", CMDFLAG_KEEP_QUOTES, 3, MAX_COMMAND_PARAMS, std::bind(&debugger_commands::execute_find, this, -1, _1)); + m_console.register_command("fd", CMDFLAG_KEEP_QUOTES, 3, MAX_COMMAND_PARAMS, std::bind(&debugger_commands::execute_find, this, AS_DATA, _1)); + m_console.register_command("findd", CMDFLAG_KEEP_QUOTES, 3, MAX_COMMAND_PARAMS, std::bind(&debugger_commands::execute_find, this, AS_DATA, _1)); + m_console.register_command("fi", CMDFLAG_KEEP_QUOTES, 3, MAX_COMMAND_PARAMS, std::bind(&debugger_commands::execute_find, this, AS_IO, _1)); + m_console.register_command("findi", CMDFLAG_KEEP_QUOTES, 3, MAX_COMMAND_PARAMS, std::bind(&debugger_commands::execute_find, this, AS_IO, _1)); + m_console.register_command("fo", CMDFLAG_KEEP_QUOTES, 3, MAX_COMMAND_PARAMS, std::bind(&debugger_commands::execute_find, this, AS_OPCODES, _1)); + m_console.register_command("findo", CMDFLAG_KEEP_QUOTES, 3, MAX_COMMAND_PARAMS, std::bind(&debugger_commands::execute_find, this, AS_OPCODES, _1)); + + m_console.register_command("fill", CMDFLAG_KEEP_QUOTES, 3, MAX_COMMAND_PARAMS, std::bind(&debugger_commands::execute_fill, this, -1, _1)); + m_console.register_command("filld", CMDFLAG_KEEP_QUOTES, 3, MAX_COMMAND_PARAMS, std::bind(&debugger_commands::execute_fill, this, AS_DATA, _1)); + m_console.register_command("filli", CMDFLAG_KEEP_QUOTES, 3, MAX_COMMAND_PARAMS, std::bind(&debugger_commands::execute_fill, this, AS_IO, _1)); + m_console.register_command("fillo", CMDFLAG_KEEP_QUOTES, 3, MAX_COMMAND_PARAMS, std::bind(&debugger_commands::execute_fill, this, AS_OPCODES, _1)); + + m_console.register_command("dasm", CMDFLAG_NONE, 3, 5, std::bind(&debugger_commands::execute_dasm, this, _1)); + + m_console.register_command("trace", CMDFLAG_NONE, 1, 4, std::bind(&debugger_commands::execute_trace, this, _1)); + m_console.register_command("traceover", CMDFLAG_NONE, 1, 4, std::bind(&debugger_commands::execute_traceover, this, _1)); + m_console.register_command("traceflush",CMDFLAG_NONE, 0, 0, std::bind(&debugger_commands::execute_traceflush, this, _1)); + + m_console.register_command("history", CMDFLAG_NONE, 0, 2, std::bind(&debugger_commands::execute_history, this, _1)); + m_console.register_command("trackpc", CMDFLAG_NONE, 0, 3, std::bind(&debugger_commands::execute_trackpc, this, _1)); + + m_console.register_command("trackmem", CMDFLAG_NONE, 0, 3, std::bind(&debugger_commands::execute_trackmem, this, _1)); + m_console.register_command("pcatmem", CMDFLAG_NONE, 1, 1, std::bind(&debugger_commands::execute_pcatmem, this, -1, _1)); + m_console.register_command("pcatmemd", CMDFLAG_NONE, 1, 1, std::bind(&debugger_commands::execute_pcatmem, this, AS_DATA, _1)); + m_console.register_command("pcatmemi", CMDFLAG_NONE, 1, 1, std::bind(&debugger_commands::execute_pcatmem, this, AS_IO, _1)); + m_console.register_command("pcatmemo", CMDFLAG_NONE, 1, 1, std::bind(&debugger_commands::execute_pcatmem, this, AS_OPCODES, _1)); + + m_console.register_command("snap", CMDFLAG_NONE, 0, 1, std::bind(&debugger_commands::execute_snap, this, _1)); + + m_console.register_command("source", CMDFLAG_NONE, 1, 1, std::bind(&debugger_commands::execute_source, this, _1)); + + m_console.register_command("map", CMDFLAG_NONE, 1, 1, std::bind(&debugger_commands::execute_map, this, -1, _1)); + m_console.register_command("mapd", CMDFLAG_NONE, 1, 1, std::bind(&debugger_commands::execute_map, this, AS_DATA, _1)); + m_console.register_command("mapi", CMDFLAG_NONE, 1, 1, std::bind(&debugger_commands::execute_map, this, AS_IO, _1)); + m_console.register_command("mapo", CMDFLAG_NONE, 1, 1, std::bind(&debugger_commands::execute_map, this, AS_OPCODES, _1)); + m_console.register_command("memdump", CMDFLAG_NONE, 0, 2, std::bind(&debugger_commands::execute_memdump, this, _1)); + + m_console.register_command("symlist", CMDFLAG_NONE, 0, 1, std::bind(&debugger_commands::execute_symlist, this, _1)); + + m_console.register_command("softreset", CMDFLAG_NONE, 0, 1, std::bind(&debugger_commands::execute_softreset, this, _1)); + m_console.register_command("hardreset", CMDFLAG_NONE, 0, 1, std::bind(&debugger_commands::execute_hardreset, this, _1)); + + m_console.register_command("images", CMDFLAG_NONE, 0, 0, std::bind(&debugger_commands::execute_images, this, _1)); + m_console.register_command("mount", CMDFLAG_NONE, 2, 2, std::bind(&debugger_commands::execute_mount, this, _1)); + m_console.register_command("unmount", CMDFLAG_NONE, 1, 1, std::bind(&debugger_commands::execute_unmount, this, _1)); + + m_console.register_command("input", CMDFLAG_NONE, 1, 1, std::bind(&debugger_commands::execute_input, this, _1)); + m_console.register_command("dumpkbd", CMDFLAG_NONE, 0, 1, std::bind(&debugger_commands::execute_dumpkbd, this, _1)); - /* set up the initial debugscript if specified */ + // set up the initial debugscript if specified const char* name = m_machine.options().debug_script(); if (name[0] != 0) m_console.source_script(name); @@ -331,88 +376,6 @@ debugger_commands::debugger_commands(running_machine& machine, debugger_cpu& cpu m_cheat.cpu[0] = m_cheat.cpu[1] = 0; } -//------------------------------------------------- -// execute_min - return the minimum of two values -//------------------------------------------------- - -u64 debugger_commands::execute_min(int params, const u64 *param) -{ - return (param[0] < param[1]) ? param[0] : param[1]; -} - - -//------------------------------------------------- -// execute_max - return the maximum of two values -//------------------------------------------------- - -u64 debugger_commands::execute_max(int params, const u64 *param) -{ - return (param[0] > param[1]) ? param[0] : param[1]; -} - - -//------------------------------------------------- -// execute_if - if (a) return b; else return c; -//------------------------------------------------- - -u64 debugger_commands::execute_if(int params, const u64 *param) -{ - return param[0] ? param[1] : param[2]; -} - - -//------------------------------------------------- -// execute_abs - return the absolute value -//------------------------------------------------- - -u64 debugger_commands::execute_abs(int params, const u64 *param) -{ - return std::abs(s64(param[0])); -} - - -//------------------------------------------------- -// execute_bit - extract bit field from value -//------------------------------------------------- - -u64 debugger_commands::execute_bit(int params, const u64 *param) -{ - if (params == 2) - return BIT(param[0], param[1]); - else - return BIT(param[0], param[1], param[2]); -} - - -//------------------------------------------------- -// execute_s8 - sign-extend from 8 bits -//------------------------------------------------- - -u64 debugger_commands::execute_s8(int params, const u64 *param) -{ - return s8(param[0]); -} - - -//------------------------------------------------- -// execute_s16 - sign-extend from 16 bits -//------------------------------------------------- - -u64 debugger_commands::execute_s16(int params, const u64 *param) -{ - return s16(param[0]); -} - - -//------------------------------------------------- -// execute_s32 - sign-extend from 32 bits -//------------------------------------------------- - -u64 debugger_commands::execute_s32(int params, const u64 *param) -{ - return s32(param[0]); -} - //------------------------------------------------- // get_cpunum - getter callback for the @@ -421,8 +384,18 @@ u64 debugger_commands::execute_s32(int params, const u64 *param) u64 debugger_commands::get_cpunum() { - execute_interface_enumerator iter(m_machine.root_device()); - return iter.indexof(m_console.get_visible_cpu()->execute()); + unsigned index = 0; + for (device_execute_interface &exec : execute_interface_enumerator(m_machine.root_device())) + { + if (m_console.get_visible_cpu() == &exec.device()) + return index; + + // real CPUs should have pcbase + device_state_interface const *state; + if (exec.device().interface(state) && state->state_find_entry(STATE_GENPCBASE)) + ++index; + } + return u64(s64(-1)); } @@ -438,10 +411,10 @@ u64 debugger_commands::global_get(global_entry *global) { switch (global->size) { - case 1: return *(u8 *)global->base; - case 2: return *(u16 *)global->base; - case 4: return *(u32 *)global->base; - case 8: return *(u64 *)global->base; + case 1: return *(u8 *)global->base; + case 2: return *(u16 *)global->base; + case 4: return *(u32 *)global->base; + case 8: return *(u64 *)global->base; } return ~0; } @@ -455,10 +428,10 @@ void debugger_commands::global_set(global_entry *global, u64 value) { switch (global->size) { - case 1: *(u8 *)global->base = value; break; - case 2: *(u16 *)global->base = value; break; - case 4: *(u32 *)global->base = value; break; - case 8: *(u64 *)global->base = value; break; + case 1: *(u8 *)global->base = value; break; + case 2: *(u16 *)global->base = value; break; + case 4: *(u32 *)global->base = value; break; + case 8: *(u64 *)global->base = value; break; } } @@ -468,22 +441,62 @@ void debugger_commands::global_set(global_entry *global, u64 value) PARAMETER VALIDATION HELPERS ***************************************************************************/ -/*------------------------------------------------- - validate_number_parameter - validates a - number parameter --------------------------------------------------*/ +/// \brief Validate parameter as a Boolean value +/// +/// Validates a parameter as a Boolean value. Fixed strings and +/// expressions evaluating to numeric values are recognised. The result +/// is unchanged for an empty string. +/// \param [in] param The parameter string. +/// \param [in,out] result The default value on entry, and the value of +/// the parameter interpreted as a Boolean on success. Unchanged if +/// the parameter is an empty string. +/// \return true if the parameter is a valid Boolean value or an empty +/// string, or false otherwise. +bool debugger_commands::validate_boolean_parameter(const std::string ¶m, bool &result) +{ + // nullptr parameter does nothing and returns no error + if (param.empty()) + return true; -bool debugger_commands::validate_number_parameter(const std::string ¶m, u64 &result) + // evaluate the expression; success if no error + bool const is_true = !core_stricmp(param.c_str(), "true"); + bool const is_false = !core_stricmp(param.c_str(), "false"); + + if (is_true || is_false) + { + result = is_true; + return true; + } + + // try to evaluate as a number + u64 val; + if (!validate_number_parameter(param, val)) + return false; + + result = val != 0; + return true; +} + + +/// \brief Validate parameter as a numeric value +/// +/// Parses the parameter as an expression and evaluates it as a number. +/// \param [in] param The parameter string. +/// \param [out] result The numeric value of the expression on success. +/// Unchanged on failure. +/// \return true if the parameter is a valid expression that evaluates +/// to a numeric value, or false otherwise. +bool debugger_commands::validate_number_parameter(std::string_view param, u64 &result) { - /* evaluate the expression; success if no error */ + // evaluate the expression; success if no error try { - result = parsed_expression(m_console.visible_symtable(), param.c_str()).execute(); + result = parsed_expression(m_console.visible_symtable(), param).execute(); return true; } - catch (expression_error &error) + catch (expression_error const &error) { - /* print an error pointing to the character that caused it */ + // print an error pointing to the character that caused it m_console.printf("Error in expression: %s\n", param); m_console.printf(" %*s^", error.offset(), ""); m_console.printf("%s\n", error.code_string()); @@ -492,128 +505,352 @@ bool debugger_commands::validate_number_parameter(const std::string ¶m, u64 } -/*------------------------------------------------- - validate_boolean_parameter - validates a - boolean parameter --------------------------------------------------*/ - -bool debugger_commands::validate_boolean_parameter(const std::string ¶m, bool &result) +/// \brief Validate parameter as a device +/// +/// Validates a parameter as a device identifier and retrieves the +/// device on success. A string corresponding to the tag of a device +/// refers to that device; an empty string refers to the current CPU +/// with debugger focus; any other string is parsed as an expression +/// and treated as an index of a device implementing +/// #device_execute_interface and #device_state_interface, and exposing +/// a generic PC base value. +/// \param [in] param The parameter string. +/// \param [out] result A pointer to the device on success, or unchanged +/// on failure. +/// \return true if the parameter refers to a device in the current +/// system, or false otherwise. +bool debugger_commands::validate_device_parameter(std::string_view param, device_t *&result) { - /* nullptr parameter does nothing and returns no error */ + // if no parameter, use the visible CPU if (param.empty()) + { + device_t *const current = m_console.get_visible_cpu(); + if (current) + { + result = current; + return true; + } + else + { + m_console.printf("No valid CPU is currently selected\n"); + return false; + } + } + + // next look for a tag match + std::string_view relative = param; + device_t &base = get_device_search_base(relative); + device_t *device = base.subdevice(strmakelower(relative)); + if (device) + { + result = device; return true; + } - /* evaluate the expression; success if no error */ - bool is_true = core_stricmp(param.c_str(), "true") == 0 || param == "1"; - bool is_false = core_stricmp(param.c_str(), "false") == 0 || param == "0"; + // then evaluate as an expression; on an error assume it was a tag + u64 cpunum; + try + { + cpunum = parsed_expression(m_console.visible_symtable(), param).execute(); + } + catch (expression_error &) + { + m_console.printf("Unable to find device '%s'\n", param); + return false; + } - if (!is_true && !is_false) + // attempt to find by numerical index + device = get_cpu_by_index(cpunum); + if (device) + { + result = device; + return true; + } + else { - m_console.printf("Invalid boolean '%s'\n", param); + // if out of range, complain + m_console.printf("Invalid CPU index %u\n", cpunum); return false; } +} - result = is_true; - return true; -} +/// \brief Validate a parameter as a CPU +/// +/// Validates a parameter as a CPU identifier. Uses the same rules as +/// #validate_device_parameter to identify devices, but additionally +/// checks that the device is a "CPU" for the debugger's purposes. +/// \param [in] The parameter string. +/// \param [out] result The device on success, or unchanged on failure. +/// \return true if the parameter refers to a CPU-like device in the +/// current system, or false otherwise. +bool debugger_commands::validate_cpu_parameter(std::string_view param, device_t *&result) +{ + // first do the standard device thing + device_t *device; + if (!validate_device_parameter(param, device)) + return false; + // check that it's a "CPU" for the debugger's purposes + device_execute_interface const *execute; + if (device->interface(execute)) + { + result = device; + return true; + } + + m_console.printf("Device %s is not a CPU\n", device->name()); + return false; +} -/*------------------------------------------------- - validate_cpu_parameter - validates a - parameter as a cpu --------------------------------------------------*/ -bool debugger_commands::validate_cpu_parameter(const char *param, device_t *&result) +/// \brief Validate a parameter as an address space identifier +/// +/// Validates a parameter as an address space identifier. Uses the same +/// rules as #validate_device_parameter to identify devices. If the +/// default address space number is negative, the first address space +/// exposed by the device will be used as the default. +/// \param [in] The parameter string. +/// \param [in] spacenum The default address space index. If negative, +/// the first address space exposed by the device (i.e. the address +/// space with the lowest index) will be used as the default. +/// \param [out] result The address space on success, or unchanged on +/// failure. +/// \return true if the parameter refers to an address space in the +/// current system, or false otherwise. +bool debugger_commands::validate_device_space_parameter(std::string_view param, int spacenum, address_space *&result) { - /* if no parameter, use the visible CPU */ - if (param == nullptr) + device_t *device; + std::string spacename; + if (param.empty()) { - result = m_console.get_visible_cpu(); - if (!result) + // if no parameter, use the visible CPU + device = m_console.get_visible_cpu(); + if (!device) { m_console.printf("No valid CPU is currently selected\n"); return false; } - return true; } + else + { + // look for a tag match on the whole parameter value + std::string_view relative = param; + device_t &base = get_device_search_base(relative); + device = base.subdevice(strmakelower(relative)); - /* first look for a tag match */ - result = m_machine.root_device().subdevice(strmakelower(param)); - if (result) - return true; + // if that failed, treat the last component as an address space + if (!device) + { + auto const delimiter = relative.find_last_of(":^"); + bool const found = std::string_view::npos != delimiter; + if (!found || (':' == relative[delimiter])) + { + spacename = strmakelower(relative.substr(found ? (delimiter + 1) : 0)); + relative = relative.substr(0, !found ? 0 : !delimiter ? 1 : delimiter); + if (!relative.empty()) + device = base.subdevice(strmakelower(relative)); + else if (m_console.get_visible_cpu()) + device = m_console.get_visible_cpu(); + else + device = &m_machine.root_device(); + } + } + } - /* then evaluate as an expression; on an error assume it was a tag */ - u64 cpunum; - try + // if still no device found, evaluate as an expression + if (!device) { - cpunum = parsed_expression(m_console.visible_symtable(), param).execute(); + u64 cpunum; + try + { + cpunum = parsed_expression(m_console.visible_symtable(), param).execute(); + } + catch (expression_error const &) + { + // parsing failed - assume it was a tag + m_console.printf("Unable to find device '%s'\n", param); + return false; + } + + // attempt to find by numerical index + device = get_cpu_by_index(cpunum); + if (!device) + { + // if out of range, complain + m_console.printf("Invalid CPU index %u\n", cpunum); + return false; + } } - catch (expression_error &) + + // ensure the device implements the memory interface + device_memory_interface *memory; + if (!device->interface(memory)) { - m_console.printf("Unable to find CPU '%s'\n", param); + m_console.printf("No memory interface found for device %s\n", device->name()); return false; } - // attempt to find by numerical index - int index = 0; - for (device_execute_interface &exec : execute_interface_enumerator(m_machine.root_device())) + // fall back to supplied default space if appropriate + if (spacename.empty() && (0 <= spacenum)) { - // real CPUs should have pcbase - const device_state_interface *state; - if (exec.device().interface(state) && state->state_find_entry(STATE_GENPCBASE) != nullptr && index++ == cpunum) + if (memory->has_space(spacenum)) { - result = &exec.device(); + result = &memory->space(spacenum); return true; } + else + { + m_console.printf("No matching memory space found for device '%s'\n", device->tag()); + return false; + } } - /* if out of range, complain */ - m_console.printf("Invalid CPU index %d\n", (int)cpunum); + // otherwise find the specified space or fall back to the first populated space + for (int i = 0; memory->max_space_count() > i; ++i) + { + if (memory->has_space(i) && (spacename.empty() || (memory->space(i).name() == spacename))) + { + result = &memory->space(i); + return true; + } + } + + // report appropriate error message + if (spacename.empty()) + m_console.printf("No memory spaces found for device '%s'\n", device->tag()); + else + m_console.printf("Memory space '%s' not found found for device '%s'\n", spacename, device->tag()); return false; } -/*------------------------------------------------- - validate_cpu_space_parameter - validates - a parameter as a cpu and retrieves the given - address space --------------------------------------------------*/ - -bool debugger_commands::validate_cpu_space_parameter(const char *param, int spacenum, address_space *&result) +/// \brief Validate a parameter as a target address +/// +/// Validates a parameter as an numeric expression to use as an address +/// optionally followed by a colon and a device identifier. If the +/// device identifier is not presnt, the current CPU with debugger focus +/// is assumed. See #validate_device_parameter for information on how +/// device parametersare interpreted. +/// \param [in] The parameter string. +/// \param [in] spacenum The default address space index. If negative, +/// the first address space exposed by the device (i.e. the address +/// space with the lowest index) will be used as the default. +/// \param [out] space The address space on success, or unchanged on +/// failure. +/// \param [out] addr The address on success, or unchanged on failure. +/// \return true if the address is a valid expression evaluating to a +/// number and the address space is found, or false otherwise. +bool debugger_commands::validate_target_address_parameter(std::string_view param, int spacenum, address_space *&space, u64 &addr) { - /* first do the standard CPU thing */ - device_t *cpu; - if (!validate_cpu_parameter(param, cpu)) + // check for the device delimiter + std::string_view::size_type const devdelim = find_delimiter(param, [] (char ch) { return ':' == ch; }); + std::string_view device; + if (devdelim != std::string::npos) + device = param.substr(devdelim + 1); + + // parse the address first + u64 addrval; + if (!validate_number_parameter(param.substr(0, devdelim), addrval)) return false; - /* fetch the space pointer */ - if (!cpu->memory().has_space(spacenum)) - { - m_console.printf("No matching memory space found for CPU '%s'\n", cpu->tag()); + // find the address space + if (!validate_device_space_parameter(device, spacenum, space)) return false; - } - result = &cpu->memory().space(spacenum); + + // set the address now that we have the space + addr = addrval; return true; } -/*------------------------------------------------- - validate_memory_region_parameter - validates - a parameter as a memory region name and - retrieves the given memory region --------------------------------------------------*/ - -bool debugger_commands::validate_memory_region_parameter(const std::string ¶m, memory_region *&result) +/// \brief Validate a parameter as a memory region +/// +/// Validates a parameter as a memory region tag and retrieves the +/// specified memory region. +/// \param [in] The parameter string. +/// \param [out] result The memory region on success, or unchanged on +/// failure. +/// \return true if the parameter refers to a memory region in the +/// current system, or false otherwise. +bool debugger_commands::validate_memory_region_parameter(std::string_view param, memory_region *&result) { - auto ®ions = m_machine.memory().regions(); - auto iter = regions.find(strmakelower(param)); - if(iter == regions.end()) { + auto const ®ions = m_machine.memory().regions(); + std::string_view relative = param; + device_t &base = get_device_search_base(relative); + auto const iter = regions.find(base.subtag(strmakelower(relative))); + if (regions.end() != iter) + { + result = iter->second.get(); + return true; + } + else + { m_console.printf("No matching memory region found for '%s'\n", param); return false; } - result = iter->second.get(); - return true; +} + + +/// \brief Get search base for device or address space parameter +/// +/// Handles prefix prefixes used to indicate that a device tag should be +/// interpreted relative to the selected CPU. Removes the recognised +/// prefixes from the parameter value. +/// \param [in,out] param The parameter string. Recognised prefixes +/// affecting the search base are removed, leaving a tag relative to +/// the base device. +/// \return A reference to the base device that the tag should be +/// interpreted relative to. +device_t &debugger_commands::get_device_search_base(std::string_view ¶m) +{ + if (!param.empty()) + { + // handle ".:" or ".^" prefix for tag relative to current CPU if any + if (('.' == param[0]) && ((param.size() == 1) || (':' == param[1]) || ('^' == param[1]))) + { + param.remove_prefix(((param.size() > 1) && (':' == param[1])) ? 2 : 1); + device_t *const current = m_console.get_visible_cpu(); + return current ? *current : m_machine.root_device(); + } + + // a sibling path makes most sense relative to current CPU + if ('^' == param[0]) + { + device_t *const current = m_console.get_visible_cpu(); + return current ? *current : m_machine.root_device(); + } + } + + + // default to root device + return m_machine.root_device(); +} + + +/// \brief Get CPU by index +/// +/// Looks up a CPU by the number the debugger assigns it based on its +/// position in the device tree relative to other CPUs. +/// \param [in] cpunum Zero-based index of the CPU to find. +/// \return A pointer to the CPU if found, or \c nullptr if no CPU has +/// the specified index. +device_t *debugger_commands::get_cpu_by_index(u64 cpunum) +{ + unsigned index = 0; + for (device_execute_interface &exec : execute_interface_enumerator(m_machine.root_device())) + { + // real CPUs should have pcbase + device_state_interface const *state; + if (exec.device().interface(state) && state->state_find_entry(STATE_GENPCBASE)) + { + if (index++ == cpunum) + { + return &exec.device(); + } + } + } + return nullptr; } @@ -622,17 +859,17 @@ bool debugger_commands::validate_memory_region_parameter(const std::string ¶ an expression parameter -------------------------------------------------*/ -bool debugger_commands::debug_command_parameter_expression(const std::string ¶m, parsed_expression &result) +bool debugger_commands::debug_command_parameter_expression(std::string_view param, parsed_expression &result) { - /* parse the expression; success if no error */ try { - result.parse(param.c_str()); + // parse the expression; success if no error + result.parse(param); return true; } - catch (expression_error &err) + catch (expression_error const &err) { - /* output an error */ + // output an error m_console.printf("Error in expression: %s\n", param); m_console.printf(" %*s^", err.offset(), ""); m_console.printf("%s\n", err.code_string()); @@ -668,12 +905,12 @@ bool debugger_commands::debug_command_parameter_command(const char *param) execute_help - execute the help command -------------------------------------------------*/ -void debugger_commands::execute_help(int ref, const std::vector<std::string> ¶ms) +void debugger_commands::execute_help(const std::vector<std::string> ¶ms) { if (params.size() == 0) - m_console.printf_wrap(80, "%s\n", debug_get_help("")); + m_console.printf_wrap(80, "%s\n", debug_get_help(std::string_view())); else - m_console.printf_wrap(80, "%s\n", debug_get_help(params[0].c_str())); + m_console.printf_wrap(80, "%s\n", debug_get_help(params[0])); } @@ -681,7 +918,7 @@ void debugger_commands::execute_help(int ref, const std::vector<std::string> &pa execute_print - execute the print command -------------------------------------------------*/ -void debugger_commands::execute_print(int ref, const std::vector<std::string> ¶ms) +void debugger_commands::execute_print(const std::vector<std::string> ¶ms) { /* validate the other parameters */ u64 values[MAX_COMMAND_PARAMS]; @@ -832,7 +1069,7 @@ int debugger_commands::mini_printf(char *buffer, const char *format, int params, execute_printf - execute the printf command -------------------------------------------------*/ -void debugger_commands::execute_printf(int ref, const std::vector<std::string> ¶ms) +void debugger_commands::execute_printf(const std::vector<std::string> ¶ms) { /* validate the other parameters */ u64 values[MAX_COMMAND_PARAMS]; @@ -851,7 +1088,7 @@ void debugger_commands::execute_printf(int ref, const std::vector<std::string> & execute_logerror - execute the logerror command -------------------------------------------------*/ -void debugger_commands::execute_logerror(int ref, const std::vector<std::string> ¶ms) +void debugger_commands::execute_logerror(const std::vector<std::string> ¶ms) { /* validate the other parameters */ u64 values[MAX_COMMAND_PARAMS]; @@ -870,7 +1107,7 @@ void debugger_commands::execute_logerror(int ref, const std::vector<std::string> execute_tracelog - execute the tracelog command -------------------------------------------------*/ -void debugger_commands::execute_tracelog(int ref, const std::vector<std::string> ¶ms) +void debugger_commands::execute_tracelog(const std::vector<std::string> ¶ms) { /* validate the other parameters */ u64 values[MAX_COMMAND_PARAMS]; @@ -889,7 +1126,7 @@ void debugger_commands::execute_tracelog(int ref, const std::vector<std::string> execute_tracesym - execute the tracesym command -------------------------------------------------*/ -void debugger_commands::execute_tracesym(int ref, const std::vector<std::string> ¶ms) +void debugger_commands::execute_tracesym(const std::vector<std::string> ¶ms) { // build a format string appropriate for the parameters and validate them std::stringstream format; @@ -925,7 +1162,7 @@ void debugger_commands::execute_tracesym(int ref, const std::vector<std::string> execute_cls - execute the cls command -------------------------------------------------*/ -void debugger_commands::execute_cls(int ref, const std::vector<std::string> ¶ms) +void debugger_commands::execute_cls(const std::vector<std::string> ¶ms) { text_buffer_clear(m_console.get_console_textbuf()); } @@ -935,7 +1172,7 @@ void debugger_commands::execute_cls(int ref, const std::vector<std::string> &par execute_quit - execute the quit command -------------------------------------------------*/ -void debugger_commands::execute_quit(int ref, const std::vector<std::string> ¶ms) +void debugger_commands::execute_quit(const std::vector<std::string> ¶ms) { osd_printf_warning("Exited via the debugger\n"); m_machine.schedule_exit(); @@ -946,7 +1183,7 @@ void debugger_commands::execute_quit(int ref, const std::vector<std::string> &pa execute_do - execute the do command -------------------------------------------------*/ -void debugger_commands::execute_do(int ref, const std::vector<std::string> ¶ms) +void debugger_commands::execute_do(const std::vector<std::string> ¶ms) { u64 dummy; validate_number_parameter(params[0], dummy); @@ -957,7 +1194,7 @@ void debugger_commands::execute_do(int ref, const std::vector<std::string> ¶ execute_step - execute the step command -------------------------------------------------*/ -void debugger_commands::execute_step(int ref, const std::vector<std::string> ¶ms) +void debugger_commands::execute_step(const std::vector<std::string> ¶ms) { /* if we have a parameter, use it */ u64 steps = 1; @@ -972,7 +1209,7 @@ void debugger_commands::execute_step(int ref, const std::vector<std::string> &pa execute_over - execute the over command -------------------------------------------------*/ -void debugger_commands::execute_over(int ref, const std::vector<std::string> ¶ms) +void debugger_commands::execute_over(const std::vector<std::string> ¶ms) { /* if we have a parameter, use it */ u64 steps = 1; @@ -987,7 +1224,7 @@ void debugger_commands::execute_over(int ref, const std::vector<std::string> &pa execute_out - execute the out command -------------------------------------------------*/ -void debugger_commands::execute_out(int ref, const std::vector<std::string> ¶ms) +void debugger_commands::execute_out(const std::vector<std::string> ¶ms) { m_console.get_visible_cpu()->debug()->single_step_out(); } @@ -997,7 +1234,7 @@ void debugger_commands::execute_out(int ref, const std::vector<std::string> &par execute_go - execute the go command -------------------------------------------------*/ -void debugger_commands::execute_go(int ref, const std::vector<std::string> ¶ms) +void debugger_commands::execute_go(const std::vector<std::string> ¶ms) { u64 addr = ~0; @@ -1014,7 +1251,7 @@ void debugger_commands::execute_go(int ref, const std::vector<std::string> ¶ command -------------------------------------------------*/ -void debugger_commands::execute_go_vblank(int ref, const std::vector<std::string> ¶ms) +void debugger_commands::execute_go_vblank(const std::vector<std::string> ¶ms) { m_console.get_visible_cpu()->debug()->go_vblank(); } @@ -1024,7 +1261,7 @@ void debugger_commands::execute_go_vblank(int ref, const std::vector<std::string execute_go_interrupt - execute the goint command -------------------------------------------------*/ -void debugger_commands::execute_go_interrupt(int ref, const std::vector<std::string> ¶ms) +void debugger_commands::execute_go_interrupt(const std::vector<std::string> ¶ms) { u64 irqline = -1; @@ -1039,7 +1276,7 @@ void debugger_commands::execute_go_interrupt(int ref, const std::vector<std::str execute_go_exception - execute the goex command -------------------------------------------------*/ -void debugger_commands::execute_go_exception(int ref, const std::vector<std::string> ¶ms) +void debugger_commands::execute_go_exception(const std::vector<std::string> ¶ms) { u64 exception = -1; @@ -1051,7 +1288,7 @@ void debugger_commands::execute_go_exception(int ref, const std::vector<std::str if (params.size() > 1 && !debug_command_parameter_expression(params[1], condition)) return; - m_console.get_visible_cpu()->debug()->go_exception(exception, (condition.is_empty()) ? "1" : condition.original_string()); + m_console.get_visible_cpu()->debug()->go_exception(exception, condition.is_empty() ? "1" : condition.original_string()); } @@ -1059,7 +1296,7 @@ void debugger_commands::execute_go_exception(int ref, const std::vector<std::str execute_go_time - execute the gtime command -------------------------------------------------*/ -void debugger_commands::execute_go_time(int ref, const std::vector<std::string> ¶ms) +void debugger_commands::execute_go_time(const std::vector<std::string> ¶ms) { u64 milliseconds = -1; @@ -1075,7 +1312,7 @@ void debugger_commands::execute_go_time(int ref, const std::vector<std::string> /*------------------------------------------------- execute_go_privilege - execute the gp command -------------------------------------------------*/ -void debugger_commands::execute_go_privilege(int ref, const std::vector<std::string> ¶ms) +void debugger_commands::execute_go_privilege(const std::vector<std::string> ¶ms) { parsed_expression condition(m_console.visible_symtable()); if (params.size() > 0 && !debug_command_parameter_expression(params[0], condition)) @@ -1088,7 +1325,7 @@ void debugger_commands::execute_go_privilege(int ref, const std::vector<std::str execute_next - execute the next command -------------------------------------------------*/ -void debugger_commands::execute_next(int ref, const std::vector<std::string> ¶ms) +void debugger_commands::execute_next(const std::vector<std::string> ¶ms) { m_console.get_visible_cpu()->debug()->go_next_device(); } @@ -1098,17 +1335,17 @@ void debugger_commands::execute_next(int ref, const std::vector<std::string> &pa execute_focus - execute the focus command -------------------------------------------------*/ -void debugger_commands::execute_focus(int ref, const std::vector<std::string> ¶ms) +void debugger_commands::execute_focus(const std::vector<std::string> ¶ms) { - /* validate params */ + // validate params device_t *cpu; - if (!validate_cpu_parameter(params[0].c_str(), cpu)) + if (!validate_cpu_parameter(params[0], cpu)) return; - /* first clear the ignore flag on the focused CPU */ + // first clear the ignore flag on the focused CPU cpu->debug()->ignore(false); - /* then loop over CPUs and set the ignore flags on all other CPUs */ + // then loop over CPUs and set the ignore flags on all other CPUs for (device_execute_interface &exec : execute_interface_enumerator(m_machine.root_device())) if (&exec.device() != cpu) exec.device().debug()->ignore(true); @@ -1120,17 +1357,17 @@ void debugger_commands::execute_focus(int ref, const std::vector<std::string> &p execute_ignore - execute the ignore command -------------------------------------------------*/ -void debugger_commands::execute_ignore(int ref, const std::vector<std::string> ¶ms) +void debugger_commands::execute_ignore(const std::vector<std::string> ¶ms) { - /* if there are no parameters, dump the ignore list */ if (params.empty()) { + // if there are no parameters, dump the ignore list std::string buffer; - /* loop over all executable devices */ + // loop over all executable devices for (device_execute_interface &exec : execute_interface_enumerator(m_machine.root_device())) - - /* build up a comma-separated list */ + { + // build up a comma-separated list if (!exec.device().debug()->observing()) { if (buffer.empty()) @@ -1138,27 +1375,27 @@ void debugger_commands::execute_ignore(int ref, const std::vector<std::string> & else buffer.append(string_format(", '%s'", exec.device().tag())); } + } - /* special message for none */ + // special message for none if (buffer.empty()) buffer = string_format("Not currently ignoring any devices"); m_console.printf("%s\n", buffer); } - - /* otherwise clear the ignore flag on all requested CPUs */ else { + // otherwise clear the ignore flag on all requested CPUs device_t *devicelist[MAX_COMMAND_PARAMS]; - /* validate parameters */ + // validate parameters for (int paramnum = 0; paramnum < params.size(); paramnum++) - if (!validate_cpu_parameter(params[paramnum].c_str(), devicelist[paramnum])) + if (!validate_cpu_parameter(params[paramnum], devicelist[paramnum])) return; - /* set the ignore flags */ + // set the ignore flags for (int paramnum = 0; paramnum < params.size(); paramnum++) { - /* make sure this isn't the last live CPU */ + // make sure this isn't the last live CPU bool gotone = false; for (device_execute_interface &exec : execute_interface_enumerator(m_machine.root_device())) if (&exec.device() != devicelist[paramnum] && exec.device().debug()->observing()) @@ -1183,17 +1420,17 @@ void debugger_commands::execute_ignore(int ref, const std::vector<std::string> & execute_observe - execute the observe command -------------------------------------------------*/ -void debugger_commands::execute_observe(int ref, const std::vector<std::string> ¶ms) +void debugger_commands::execute_observe(const std::vector<std::string> ¶ms) { - /* if there are no parameters, dump the ignore list */ if (params.empty()) { + // if there are no parameters, dump the ignore list std::string buffer; - /* loop over all executable devices */ + // loop over all executable devices for (device_execute_interface &exec : execute_interface_enumerator(m_machine.root_device())) - - /* build up a comma-separated list */ + { + // build up a comma-separated list if (exec.device().debug()->observing()) { if (buffer.empty()) @@ -1201,24 +1438,24 @@ void debugger_commands::execute_observe(int ref, const std::vector<std::string> else buffer.append(string_format(", '%s'", exec.device().tag())); } + } - /* special message for none */ + // special message for none if (buffer.empty()) buffer = string_format("Not currently observing any devices"); m_console.printf("%s\n", buffer); } - - /* otherwise set the ignore flag on all requested CPUs */ else { + // otherwise set the ignore flag on all requested CPUs device_t *devicelist[MAX_COMMAND_PARAMS]; - /* validate parameters */ + // validate parameters for (int paramnum = 0; paramnum < params.size(); paramnum++) - if (!validate_cpu_parameter(params[paramnum].c_str(), devicelist[paramnum])) + if (!validate_cpu_parameter(params[paramnum], devicelist[paramnum])) return; - /* clear the ignore flags */ + // clear the ignore flags for (int paramnum = 0; paramnum < params.size(); paramnum++) { devicelist[paramnum]->debug()->ignore(false); @@ -1231,17 +1468,17 @@ void debugger_commands::execute_observe(int ref, const std::vector<std::string> execute_suspend - suspend execution on cpu -------------------------------------------------*/ -void debugger_commands::execute_suspend(int ref, const std::vector<std::string> ¶ms) +void debugger_commands::execute_suspend(const std::vector<std::string> ¶ms) { - /* if there are no parameters, dump the ignore list */ + // if there are no parameters, dump the ignore list if (params.empty()) { std::string buffer; - /* loop over all executable devices */ + // loop over all executable devices for (device_execute_interface &exec : execute_interface_enumerator(m_machine.root_device())) - /* build up a comma-separated list */ + // build up a comma-separated list if (exec.device().debug()->suspended()) { if (buffer.empty()) @@ -1250,7 +1487,7 @@ void debugger_commands::execute_suspend(int ref, const std::vector<std::string> buffer.append(string_format(", '%s'", exec.device().tag())); } - /* special message for none */ + // special message for none if (buffer.empty()) buffer = string_format("No currently suspended devices"); m_console.printf("%s\n", buffer); @@ -1259,14 +1496,14 @@ void debugger_commands::execute_suspend(int ref, const std::vector<std::string> { device_t *devicelist[MAX_COMMAND_PARAMS]; - /* validate parameters */ + // validate parameters for (int paramnum = 0; paramnum < params.size(); paramnum++) - if (!validate_cpu_parameter(params[paramnum].c_str(), devicelist[paramnum])) + if (!validate_cpu_parameter(params[paramnum], devicelist[paramnum])) return; for (int paramnum = 0; paramnum < params.size(); paramnum++) { - /* make sure this isn't the last live CPU */ + // make sure this isn't the last live CPU bool gotone = false; for (device_execute_interface &exec : execute_interface_enumerator(m_machine.root_device())) if (&exec.device() != devicelist[paramnum] && !exec.device().debug()->suspended()) @@ -1290,17 +1527,17 @@ void debugger_commands::execute_suspend(int ref, const std::vector<std::string> execute_resume - Resume execution on CPU -------------------------------------------------*/ -void debugger_commands::execute_resume(int ref, const std::vector<std::string> ¶ms) +void debugger_commands::execute_resume(const std::vector<std::string> ¶ms) { - /* if there are no parameters, dump the ignore list */ + // if there are no parameters, dump the ignore list if (params.empty()) { std::string buffer; - /* loop over all executable devices */ + // loop over all executable devices for (device_execute_interface &exec : execute_interface_enumerator(m_machine.root_device())) - /* build up a comma-separated list */ + // build up a comma-separated list if (exec.device().debug()->suspended()) { if (buffer.empty()) @@ -1309,7 +1546,7 @@ void debugger_commands::execute_resume(int ref, const std::vector<std::string> & buffer.append(string_format(", '%s'", exec.device().tag())); } - /* special message for none */ + // special message for none if (buffer.empty()) buffer = string_format("No currently suspended devices"); m_console.printf("%s\n", buffer); @@ -1318,9 +1555,9 @@ void debugger_commands::execute_resume(int ref, const std::vector<std::string> & { device_t *devicelist[MAX_COMMAND_PARAMS]; - /* validate parameters */ + // validate parameters for (int paramnum = 0; paramnum < params.size(); paramnum++) - if (!validate_cpu_parameter(params[paramnum].c_str(), devicelist[paramnum])) + if (!validate_cpu_parameter(params[paramnum], devicelist[paramnum])) return; for (int paramnum = 0; paramnum < params.size(); paramnum++) @@ -1335,7 +1572,7 @@ void debugger_commands::execute_resume(int ref, const std::vector<std::string> & // execute_cpulist - list all CPUs //------------------------------------------------- -void debugger_commands::execute_cpulist(int ref, const std::vector<std::string> ¶ms) +void debugger_commands::execute_cpulist(const std::vector<std::string> ¶ms) { int index = 0; for (device_execute_interface &exec : execute_interface_enumerator(m_machine.root_device())) @@ -1350,27 +1587,26 @@ void debugger_commands::execute_cpulist(int ref, const std::vector<std::string> execute_comment - add a comment to a line -------------------------------------------------*/ -void debugger_commands::execute_comment_add(int ref, const std::vector<std::string> ¶ms) +void debugger_commands::execute_comment_add(const std::vector<std::string> ¶ms) { - device_t *cpu; + // param 1 is the address for the comment u64 address; - - /* param 1 is the address for the comment */ if (!validate_number_parameter(params[0], address)) return; - /* CPU parameter is implicit */ - if (!validate_cpu_parameter(nullptr, cpu)) + // CPU parameter is implicit + device_t *cpu; + if (!validate_cpu_parameter(std::string_view(), cpu)) return; - /* make sure param 2 exists */ + // make sure param 2 exists if (params[1].empty()) { m_console.printf("Error : comment text empty\n"); return; } - /* Now try adding the comment */ + // Now try adding the comment cpu->debug()->comment_add(address, params[1].c_str(), 0x00ff0000); cpu->machine().debug_view().update_all(DVT_DISASSEMBLY); } @@ -1380,55 +1616,54 @@ void debugger_commands::execute_comment_add(int ref, const std::vector<std::stri execute_comment_del - remove a comment from an addr --------------------------------------------------------*/ -void debugger_commands::execute_comment_del(int ref, const std::vector<std::string> ¶ms) +void debugger_commands::execute_comment_del(const std::vector<std::string> ¶ms) { - device_t *cpu; + // param 1 can either be a command or the address for the comment u64 address; - - /* param 1 can either be a command or the address for the comment */ if (!validate_number_parameter(params[0], address)) return; - /* CPU parameter is implicit */ - if (!validate_cpu_parameter(nullptr, cpu)) + // CPU parameter is implicit + device_t *cpu; + if (!validate_cpu_parameter(std::string_view(), cpu)) return; - /* If it's a number, it must be an address */ - /* The bankoff and cbn will be pulled from what's currently active */ + // If it's a number, it must be an address + // The bankoff and cbn will be pulled from what's currently active cpu->debug()->comment_remove(address); cpu->machine().debug_view().update_all(DVT_DISASSEMBLY); } /** - * @fn void execute_comment_list(running_machine &machine, int ref, int params, const char *param[]) + * @fn void execute_comment_list(const std::vector<std::string> ¶ms) * @brief Print current list of comments in debugger * * */ -void debugger_commands::execute_comment_list(int ref, const std::vector<std::string> ¶ms) +void debugger_commands::execute_comment_list(const std::vector<std::string> ¶ms) { if (!m_machine.debugger().cpu().comment_load(false)) m_console.printf("Error while parsing XML file\n"); } /** - * @fn void execute_comment_commit(running_machine &machine, int ref, int params, const char *param[]) + * @fn void execute_comment_commit(const std::vector<std::string> ¶ms) * @brief Add and Save current list of comments in debugger * */ -void debugger_commands::execute_comment_commit(int ref, const std::vector<std::string> ¶ms) +void debugger_commands::execute_comment_commit(const std::vector<std::string> ¶ms) { - execute_comment_add(ref, params); - execute_comment_save(ref, params); + execute_comment_add(params); + execute_comment_save(params); } /*------------------------------------------------- execute_comment - add a comment to a line -------------------------------------------------*/ -void debugger_commands::execute_comment_save(int ref, const std::vector<std::string> ¶ms) +void debugger_commands::execute_comment_save(const std::vector<std::string> ¶ms) { if (m_machine.debugger().cpu().comment_save()) m_console.printf("Comment successfully saved\n"); @@ -1438,7 +1673,7 @@ void debugger_commands::execute_comment_save(int ref, const std::vector<std::str // TODO: add color hex editing capabilities for comments, see below for more info /** - * @fn void execute_comment_color(running_machine &machine, int ref, int params, const char *param[]) + * @fn void execute_comment_color(const std::vector<std::string> ¶ms) * @brief Modifies comment given at address $xx with given color * Useful for marking comment with a different color scheme (for example by marking start and end of a given function visually). * @param[in] "address,color" First is the comment address in the current context, color can be hexadecimal or shorthanded to common 1bpp RGB names. @@ -1455,32 +1690,40 @@ void debugger_commands::execute_comment_save(int ref, const std::vector<std::str command -------------------------------------------------*/ -void debugger_commands::execute_bpset(int ref, const std::vector<std::string> ¶ms) +void debugger_commands::execute_bpset(const std::vector<std::string> ¶ms) { - device_t *cpu; + // param 1 is the address/CPU u64 address; - int bpnum; - const char *action = nullptr; + address_space *space; + if (!validate_target_address_parameter(params[0], AS_PROGRAM, space, address)) + return; - /* CPU is implicit */ - if (!validate_cpu_parameter(nullptr, cpu)) + device_execute_interface const *execute; + if (!space->device().interface(execute)) + { + m_console.printf("Device %s is not a CPU\n", space->device().name()); return; + } + device_debug *const debug = space->device().debug(); - /* param 1 is the address */ - if (!validate_number_parameter(params[0], address)) + if (space->spacenum() != AS_PROGRAM) + { + m_console.printf("Only program space breakpoints are supported\n"); return; + } - /* param 2 is the condition */ - parsed_expression condition(cpu->debug()->symtable()); + // param 2 is the condition + parsed_expression condition(debug->symtable()); if (params.size() > 1 && !debug_command_parameter_expression(params[1], condition)) return; - /* param 3 is the action */ + // param 3 is the action + const char *action = nullptr; if (params.size() > 2 && !debug_command_parameter_command(action = params[2].c_str())) return; - /* set the breakpoint */ - bpnum = cpu->debug()->breakpoint_set(address, (condition.is_empty()) ? nullptr : condition.original_string(), action); + // set the breakpoint + int const bpnum = debug->breakpoint_set(address, condition.is_empty() ? nullptr : condition.original_string(), action); m_console.printf("Breakpoint %X set\n", bpnum); } @@ -1490,27 +1733,29 @@ void debugger_commands::execute_bpset(int ref, const std::vector<std::string> &p clear command -------------------------------------------------*/ -void debugger_commands::execute_bpclear(int ref, const std::vector<std::string> ¶ms) +void debugger_commands::execute_bpclear(const std::vector<std::string> ¶ms) { u64 bpindex; - /* if 0 parameters, clear all */ - if (params.empty()) + if (params.empty()) // if no parameters, clear all { for (device_t &device : device_enumerator(m_machine.root_device())) device.debug()->breakpoint_clear_all(); m_console.printf("Cleared all breakpoints\n"); } - - /* otherwise, clear the specific one */ - else if (!validate_number_parameter(params[0], bpindex)) + else if (!validate_number_parameter(params[0], bpindex)) // otherwise, clear the specific one + { return; + } else { bool found = false; for (device_t &device : device_enumerator(m_machine.root_device())) if (device.debug()->breakpoint_clear(bpindex)) + { found = true; + break; + } if (found) m_console.printf("Breakpoint %X cleared\n", u32(bpindex)); else @@ -1524,32 +1769,34 @@ void debugger_commands::execute_bpclear(int ref, const std::vector<std::string> disable/enable commands -------------------------------------------------*/ -void debugger_commands::execute_bpdisenable(int ref, const std::vector<std::string> ¶ms) +void debugger_commands::execute_bpdisenable(bool enable, const std::vector<std::string> ¶ms) { u64 bpindex; - /* if 0 parameters, clear all */ - if (params.empty()) + if (params.empty()) // if 0 parameters, disable/enable all { for (device_t &device : device_enumerator(m_machine.root_device())) - device.debug()->breakpoint_enable_all(ref); - if (ref == 0) + device.debug()->breakpoint_enable_all(enable); + if (!enable) m_console.printf("Disabled all breakpoints\n"); else m_console.printf("Enabled all breakpoints\n"); } - - /* otherwise, clear the specific one */ - else if (!validate_number_parameter(params[0], bpindex)) + else if (!validate_number_parameter(params[0], bpindex)) // otherwise, disable/enable the specific one + { return; + } else { bool found = false; for (device_t &device : device_enumerator(m_machine.root_device())) - if (device.debug()->breakpoint_enable(bpindex, ref)) + if (device.debug()->breakpoint_enable(bpindex, enable)) + { found = true; + break; + } if (found) - m_console.printf("Breakpoint %X %s\n", u32(bpindex), ref ? "enabled" : "disabled"); + m_console.printf("Breakpoint %X %s\n", u32(bpindex), enable ? "enabled" : "disabled"); else m_console.printf("Invalid breakpoint number %X\n", u32(bpindex)); } @@ -1561,7 +1808,7 @@ void debugger_commands::execute_bpdisenable(int ref, const std::vector<std::stri command -------------------------------------------------*/ -void debugger_commands::execute_bplist(int ref, const std::vector<std::string> ¶ms) +void debugger_commands::execute_bplist(const std::vector<std::string> ¶ms) { int printed = 0; std::string buffer; @@ -1596,27 +1843,29 @@ void debugger_commands::execute_bplist(int ref, const std::vector<std::string> & command -------------------------------------------------*/ -void debugger_commands::execute_wpset(int ref, const std::vector<std::string> ¶ms) +void debugger_commands::execute_wpset(int spacenum, const std::vector<std::string> ¶ms) { - address_space *space; - const char *action = nullptr; u64 address, length; - read_or_write type; - int wpnum; + address_space *space; - /* CPU is implicit */ - if (!validate_cpu_space_parameter(nullptr, ref, space)) + // param 1 is the address/CPU + if (!validate_target_address_parameter(params[0], spacenum, space, address)) return; - /* param 1 is the address */ - if (!validate_number_parameter(params[0], address)) + device_execute_interface const *execute; + if (!space->device().interface(execute)) + { + m_console.printf("Device %s is not a CPU\n", space->device().name()); return; + } + device_debug *const debug = space->device().debug(); - /* param 2 is the length */ + // param 2 is the length if (!validate_number_parameter(params[1], length)) return; - /* param 3 is the type */ + // param 3 is the type + read_or_write type; if (!core_stricmp(params[2].c_str(), "r")) type = read_or_write::READ; else if (!core_stricmp(params[2].c_str(), "w")) @@ -1629,17 +1878,18 @@ void debugger_commands::execute_wpset(int ref, const std::vector<std::string> &p return; } - /* param 4 is the condition */ - parsed_expression condition(space->device().debug()->symtable()); + // param 4 is the condition + parsed_expression condition(debug->symtable()); if (params.size() > 3 && !debug_command_parameter_expression(params[3], condition)) return; - /* param 5 is the action */ + // param 5 is the action + const char *action = nullptr; if (params.size() > 4 && !debug_command_parameter_command(action = params[4].c_str())) return; - /* set the watchpoint */ - wpnum = space->device().debug()->watchpoint_set(*space, type, address, length, (condition.is_empty()) ? nullptr : condition.original_string(), action); + // set the watchpoint + int const wpnum = debug->watchpoint_set(*space, type, address, length, (condition.is_empty()) ? nullptr : condition.original_string(), action); m_console.printf("Watchpoint %X set\n", wpnum); } @@ -1649,7 +1899,7 @@ void debugger_commands::execute_wpset(int ref, const std::vector<std::string> &p clear command -------------------------------------------------*/ -void debugger_commands::execute_wpclear(int ref, const std::vector<std::string> ¶ms) +void debugger_commands::execute_wpclear(const std::vector<std::string> ¶ms) { u64 wpindex; @@ -1683,32 +1933,31 @@ void debugger_commands::execute_wpclear(int ref, const std::vector<std::string> disable/enable commands -------------------------------------------------*/ -void debugger_commands::execute_wpdisenable(int ref, const std::vector<std::string> ¶ms) +void debugger_commands::execute_wpdisenable(bool enable, const std::vector<std::string> ¶ms) { u64 wpindex; - /* if 0 parameters, clear all */ - if (params.empty()) + if (params.empty()) // if no parameters, clear all { for (device_t &device : device_enumerator(m_machine.root_device())) - device.debug()->watchpoint_enable_all(ref); - if (ref == 0) + device.debug()->watchpoint_enable_all(enable); + if (!enable) m_console.printf("Disabled all watchpoints\n"); else m_console.printf("Enabled all watchpoints\n"); } - - /* otherwise, clear the specific one */ - else if (!validate_number_parameter(params[0], wpindex)) + else if (!validate_number_parameter(params[0], wpindex)) // otherwise, clear the specific one + { return; + } else { bool found = false; for (device_t &device : device_enumerator(m_machine.root_device())) - if (device.debug()->watchpoint_enable(wpindex, ref)) + if (device.debug()->watchpoint_enable(wpindex, enable)) found = true; if (found) - m_console.printf("Watchpoint %X %s\n", u32(wpindex), ref ? "enabled" : "disabled"); + m_console.printf("Watchpoint %X %s\n", u32(wpindex), enable ? "enabled" : "disabled"); else m_console.printf("Invalid watchpoint number %X\n", u32(wpindex)); } @@ -1720,7 +1969,7 @@ void debugger_commands::execute_wpdisenable(int ref, const std::vector<std::stri command -------------------------------------------------*/ -void debugger_commands::execute_wplist(int ref, const std::vector<std::string> ¶ms) +void debugger_commands::execute_wplist(const std::vector<std::string> ¶ms) { int printed = 0; std::string buffer; @@ -1761,27 +2010,25 @@ void debugger_commands::execute_wplist(int ref, const std::vector<std::string> & command -------------------------------------------------*/ -void debugger_commands::execute_rpset(int ref, const std::vector<std::string> ¶ms) +void debugger_commands::execute_rpset(const std::vector<std::string> ¶ms) { + // CPU is implicit device_t *cpu; - const char *action = nullptr; - int bpnum; - - /* CPU is implicit */ - if (!validate_cpu_parameter(nullptr, cpu)) + if (!validate_cpu_parameter(std::string_view(), cpu)) return; - /* param 1 is the condition */ + // param 1 is the condition parsed_expression condition(cpu->debug()->symtable()); if (params.size() > 0 && !debug_command_parameter_expression(params[0], condition)) return; - /* param 2 is the action */ + // param 2 is the action + const char *action = nullptr; if (params.size() > 1 && !debug_command_parameter_command(action = params[1].c_str())) return; - /* set the breakpoint */ - bpnum = cpu->debug()->registerpoint_set(condition.original_string(), action); + // set the breakpoint + int const bpnum = cpu->debug()->registerpoint_set(condition.original_string(), action); m_console.printf("Registerpoint %X set\n", bpnum); } @@ -1791,7 +2038,7 @@ void debugger_commands::execute_rpset(int ref, const std::vector<std::string> &p clear command -------------------------------------------------*/ -void debugger_commands::execute_rpclear(int ref, const std::vector<std::string> ¶ms) +void debugger_commands::execute_rpclear(const std::vector<std::string> ¶ms) { u64 rpindex; @@ -1825,32 +2072,31 @@ void debugger_commands::execute_rpclear(int ref, const std::vector<std::string> disable/enable commands -------------------------------------------------*/ -void debugger_commands::execute_rpdisenable(int ref, const std::vector<std::string> ¶ms) +void debugger_commands::execute_rpdisenable(bool enable, const std::vector<std::string> ¶ms) { u64 rpindex; - /* if 0 parameters, clear all */ - if (params.empty()) + if (params.empty()) // if no parameters, clear all { for (device_t &device : device_enumerator(m_machine.root_device())) - device.debug()->registerpoint_enable_all(ref); - if (ref == 0) + device.debug()->registerpoint_enable_all(enable); + if (!enable) m_console.printf("Disabled all registerpoints\n"); else m_console.printf("Enabled all registeroints\n"); } - - /* otherwise, clear the specific one */ - else if (!validate_number_parameter(params[0], rpindex)) + else if (!validate_number_parameter(params[0], rpindex)) // otherwise, clear the specific one + { return; + } else { bool found = false; for (device_t &device : device_enumerator(m_machine.root_device())) - if (device.debug()->registerpoint_enable(rpindex, ref)) + if (device.debug()->registerpoint_enable(rpindex, enable)) found = true; if (found) - m_console.printf("Registerpoint %X %s\n", u32(rpindex), ref ? "enabled" : "disabled"); + m_console.printf("Registerpoint %X %s\n", u32(rpindex), enable ? "enabled" : "disabled"); else m_console.printf("Invalid registerpoint number %X\n", u32(rpindex)); } @@ -1862,7 +2108,7 @@ void debugger_commands::execute_rpdisenable(int ref, const std::vector<std::stri command -------------------------------------------------*/ -void debugger_commands::execute_rplist(int ref, const std::vector<std::string> ¶ms) +void debugger_commands::execute_rplist(const std::vector<std::string> ¶ms) { int printed = 0; std::string buffer; @@ -1893,7 +2139,7 @@ void debugger_commands::execute_rplist(int ref, const std::vector<std::string> & execute_statesave - execute the statesave command -------------------------------------------------*/ -void debugger_commands::execute_statesave(int ref, const std::vector<std::string> ¶ms) +void debugger_commands::execute_statesave(const std::vector<std::string> ¶ms) { const std::string &filename(params[0]); m_machine.immediate_save(filename.c_str()); @@ -1905,7 +2151,7 @@ void debugger_commands::execute_statesave(int ref, const std::vector<std::string execute_stateload - execute the stateload command -------------------------------------------------*/ -void debugger_commands::execute_stateload(int ref, const std::vector<std::string> ¶ms) +void debugger_commands::execute_stateload(const std::vector<std::string> ¶ms) { const std::string &filename(params[0]); m_machine.immediate_load(filename.c_str()); @@ -1924,7 +2170,7 @@ void debugger_commands::execute_stateload(int ref, const std::vector<std::string execute_rewind - execute the rewind command -------------------------------------------------*/ -void debugger_commands::execute_rewind(int ref, const std::vector<std::string> ¶ms) +void debugger_commands::execute_rewind(const std::vector<std::string> ¶ms) { bool success = m_machine.rewind_step(); if (success) @@ -1943,34 +2189,31 @@ void debugger_commands::execute_rewind(int ref, const std::vector<std::string> & execute_save - execute the save command -------------------------------------------------*/ -void debugger_commands::execute_save(int ref, const std::vector<std::string> ¶ms) +void debugger_commands::execute_save(int spacenum, const std::vector<std::string> ¶ms) { u64 offset, endoffset, length; address_space *space; - FILE *f; - /* validate parameters */ - if (!validate_number_parameter(params[1], offset)) + // validate parameters + if (!validate_target_address_parameter(params[1], spacenum, space, offset)) return; if (!validate_number_parameter(params[2], length)) return; - if (!validate_cpu_space_parameter(params.size() > 3 ? params[3].c_str() : nullptr, ref, space)) - return; - /* determine the addresses to write */ + // determine the addresses to write endoffset = (offset + length - 1) & space->addrmask(); offset = offset & space->addrmask(); - endoffset ++; + endoffset++; - /* open the file */ - f = fopen(params[0].c_str(), "wb"); + // open the file + FILE *const f = fopen(params[0].c_str(), "wb"); if (!f) { m_console.printf("Error opening file '%s'\n", params[0]); return; } - /* now write the data out */ + // now write the data out auto dis = space->device().machine().disable_side_effects(); switch (space->addr_shift()) { @@ -2023,7 +2266,7 @@ void debugger_commands::execute_save(int ref, const std::vector<std::string> &pa break; } - /* close the file */ + // close the file fclose(f); m_console.printf("Data saved successfully\n"); } @@ -2033,12 +2276,12 @@ void debugger_commands::execute_save(int ref, const std::vector<std::string> &pa execute_saveregion - execute the save command on region memory -------------------------------------------------*/ -void debugger_commands::execute_saveregion(int ref, const std::vector<std::string> ¶ms) +void debugger_commands::execute_saveregion(const std::vector<std::string> ¶ms) { u64 offset, length; memory_region *region; - /* validate parameters */ + // validate parameters if (!validate_number_parameter(params[1], offset)) return; if (!validate_number_parameter(params[2], length)) @@ -2072,18 +2315,16 @@ void debugger_commands::execute_saveregion(int ref, const std::vector<std::strin execute_load - execute the load command -------------------------------------------------*/ -void debugger_commands::execute_load(int ref, const std::vector<std::string> ¶ms) +void debugger_commands::execute_load(int spacenum, const std::vector<std::string> ¶ms) { u64 offset, endoffset, length = 0; address_space *space; // validate parameters - if (!validate_number_parameter(params[1], offset)) + if (!validate_target_address_parameter(params[1], spacenum, space, offset)) return; if (params.size() > 2 && !validate_number_parameter(params[2], length)) return; - if (!validate_cpu_space_parameter((params.size() > 3) ? params[3].c_str() : nullptr, ref, space)) - return; // open the file std::ifstream f; @@ -2110,6 +2351,7 @@ void debugger_commands::execute_load(int ref, const std::vector<std::string> &pa endoffset = (offset + length - 1) & space->addrmask(); offset = offset & space->addrmask(); u64 i = 0; + // now read the data in, ignore endoffset and load entire file if length has been set to zero (offset-1) switch (space->addr_shift()) { @@ -2180,12 +2422,12 @@ void debugger_commands::execute_load(int ref, const std::vector<std::string> &pa execute_loadregion - execute the load command on region memory -------------------------------------------------*/ -void debugger_commands::execute_loadregion(int ref, const std::vector<std::string> ¶ms) +void debugger_commands::execute_loadregion(const std::vector<std::string> ¶ms) { u64 offset, length; memory_region *region; - /* validate parameters */ + // validate parameters if (!validate_number_parameter(params[1], offset)) return; if (!validate_number_parameter(params[2], length)) @@ -2201,8 +2443,8 @@ void debugger_commands::execute_loadregion(int ref, const std::vector<std::strin if ((length <= 0) || ((length + offset) >= region->bytes())) length = region->bytes() - offset; - /* open the file */ - FILE *f = fopen(params[0].c_str(), "rb"); + // open the file + FILE *const f = fopen(params[0].c_str(), "rb"); if (!f) { m_console.printf("Error opening file '%s'\n", params[0]); @@ -2228,11 +2470,12 @@ void debugger_commands::execute_loadregion(int ref, const std::vector<std::strin execute_dump - execute the dump command -------------------------------------------------*/ -void debugger_commands::execute_dump(int ref, const std::vector<std::string> ¶ms) +void debugger_commands::execute_dump(int spacenum, const std::vector<std::string> ¶ms) { - /* validate parameters */ + // validate parameters + address_space *space; u64 offset; - if (!validate_number_parameter(params[1], offset)) + if (!validate_target_address_parameter(params[1], spacenum, space, offset)) return; u64 length; @@ -2243,12 +2486,8 @@ void debugger_commands::execute_dump(int ref, const std::vector<std::string> &pa if (params.size() > 3 && !validate_number_parameter(params[3], width)) return; - u64 ascii = 1; - if (params.size() > 4 && !validate_number_parameter(params[4], ascii)) - return; - - address_space *space; - if (!validate_cpu_space_parameter((params.size() > 6) ? params[6].c_str() : nullptr, ref, space)) + bool ascii = true; + if (params.size() > 4 && !validate_boolean_parameter(params[4], ascii)) return; u64 rowsize = space->byte_to_address(16); @@ -2258,7 +2497,7 @@ void debugger_commands::execute_dump(int ref, const std::vector<std::string> &pa int shift = space->addr_shift(); u64 granularity = shift >= 0 ? 1 : 1 << -shift; - /* further validation */ + // further validation if (width == 0) width = space->data_width() / 8; if (width < space->address_to_byte(1)) @@ -2282,15 +2521,15 @@ void debugger_commands::execute_dump(int ref, const std::vector<std::string> &pa u64 endoffset = (offset + length - 1) & space->addrmask(); offset = offset & space->addrmask(); - /* open the file */ - FILE* f = fopen(params[0].c_str(), "w"); + // open the file + FILE *const f = fopen(params[0].c_str(), "w"); if (!f) { m_console.printf("Error opening file '%s'\n", params[0]); return; } - /* now write the data out */ + // now write the data out util::ovectorstream output; output.reserve(200); @@ -2304,10 +2543,10 @@ void debugger_commands::execute_dump(int ref, const std::vector<std::string> &pa output.clear(); output.rdbuf()->clear(); - /* print the address */ + // print the address util::stream_format(output, "%0*X: ", space->logaddrchars(), i); - /* print the bytes */ + // print the bytes for (u64 j = 0; j < rowsize; j += delta) { if (i + j <= endoffset) @@ -2340,7 +2579,7 @@ void debugger_commands::execute_dump(int ref, const std::vector<std::string> &pa util::stream_format(output, " %*s", width * 2, ""); } - /* print the ASCII */ + // print the ASCII if (ascii) { util::stream_format(output, " "); @@ -2377,12 +2616,12 @@ void debugger_commands::execute_dump(int ref, const std::vector<std::string> &pa } } - /* output the result */ + // output the result auto const &text = output.vec(); fprintf(f, "%.*s\n", int(unsigned(text.size())), &text[0]); } - /* close the file */ + // close the file fclose(f); m_console.printf("Data dumped successfully\n"); } @@ -2392,7 +2631,7 @@ void debugger_commands::execute_dump(int ref, const std::vector<std::string> &pa // execute_strdump - execute the strdump command //------------------------------------------------- -void debugger_commands::execute_strdump(int ref, const std::vector<std::string> ¶ms) +void debugger_commands::execute_strdump(int spacenum, const std::vector<std::string> ¶ms) { // validate parameters u64 offset; @@ -2408,7 +2647,7 @@ void debugger_commands::execute_strdump(int ref, const std::vector<std::string> return; address_space *space; - if (!validate_cpu_space_parameter((params.size() > 4) ? params[4].c_str() : nullptr, ref, space)) + if (!validate_device_space_parameter((params.size() > 4) ? params[4] : std::string_view(), spacenum, space)) return; // further validation @@ -2564,33 +2803,28 @@ void debugger_commands::execute_strdump(int ref, const std::vector<std::string> /*------------------------------------------------- - execute_cheatinit - initialize the cheat system + execute_cheatrange - add a range to search for + cheats -------------------------------------------------*/ -void debugger_commands::execute_cheatinit(int ref, const std::vector<std::string> ¶ms) +void debugger_commands::execute_cheatrange(bool init, const std::vector<std::string> ¶ms) { - u64 offset, length = 0, real_length = 0; - address_space *space; - u32 active_cheat = 0; - u64 curaddr; - u8 i, region_count = 0; - cheat_region_map cheat_region[100]; - memset(cheat_region, 0, sizeof(cheat_region)); - /* validate parameters */ - if (!validate_cpu_space_parameter((params.size() > 3) ? params[3].c_str() : nullptr, AS_PROGRAM, space)) + // validate parameters + address_space *space; + if (!validate_device_space_parameter((params.size() > 3) ? params[3] : std::string_view(), -1, space)) return; - if (ref == 0) + if (init) { m_cheat.width = 1; m_cheat.signed_cheat = false; m_cheat.swapped_cheat = false; if (!params.empty()) { - char *srtpnt = (char*)params[0].c_str(); + char const *srtpnt = params[0].c_str(); char sspec = std::tolower((unsigned char)*srtpnt); if (sspec == 's') @@ -2625,7 +2859,9 @@ void debugger_commands::execute_cheatinit(int ref, const std::vector<std::string } } - /* initialize entire memory by default */ + // initialize entire memory by default + u64 length = 0; + u8 region_count = 0; if (params.size() <= 1) { for (address_map_entry &entry : space->map()->m_entrylist) @@ -2635,9 +2871,9 @@ void debugger_commands::execute_cheatinit(int ref, const std::vector<std::string cheat_region[region_count].share = entry.m_share; cheat_region[region_count].disabled = (entry.m_write.m_type == AMH_RAM) ? false : true; - /* disable double share regions */ + // disable double share regions if (entry.m_share != nullptr) - for (i = 0; i < region_count; i++) + for (u8 i = 0; i < region_count; i++) if (cheat_region[i].share != nullptr) if (strcmp(cheat_region[i].share, entry.m_share) == 0) cheat_region[region_count].disabled = true; @@ -2647,13 +2883,14 @@ void debugger_commands::execute_cheatinit(int ref, const std::vector<std::string } else { - /* validate parameters */ - if (!validate_number_parameter(params[(ref == 0) ? 1 : 0], offset)) + // validate parameters + u64 offset; + if (!validate_number_parameter(params[init ? 1 : 0], offset)) return; - if (!validate_number_parameter(params[(ref == 0) ? 2 : 1], length)) + if (!validate_number_parameter(params[init ? 2 : 1], length)) return; - /* force region to the specified range */ + // force region to the specified range cheat_region[region_count].offset = offset & space->addrmask(); cheat_region[region_count].endoffset = (offset + length - 1) & space->addrmask(); cheat_region[region_count].share = nullptr; @@ -2661,10 +2898,11 @@ void debugger_commands::execute_cheatinit(int ref, const std::vector<std::string region_count++; } - /* determine the writable extent of each region in total */ - for (i = 0; i < region_count; i++) + // determine the writable extent of each region in total + u64 real_length = 0; + for (u8 i = 0; i < region_count; i++) if (!cheat_region[i].disabled) - for (curaddr = cheat_region[i].offset; curaddr <= cheat_region[i].endoffset; curaddr += m_cheat.width) + for (u64 curaddr = cheat_region[i].offset; curaddr <= cheat_region[i].endoffset; curaddr += m_cheat.width) if (cheat_address_is_valid(*space, curaddr)) real_length++; @@ -2674,33 +2912,34 @@ void debugger_commands::execute_cheatinit(int ref, const std::vector<std::string return; } - if (ref == 0) + u32 active_cheat = 0; + if (init) { - /* initialize new cheat system */ + // initialize new cheat system m_cheat.cheatmap.resize(real_length); m_cheat.undo = 0; m_cheat.cpu[0] = params.size() > 3 ? params[3][0] : '0'; } else { - /* add range to cheat system */ + // add range to cheat system if (m_cheat.cpu[0] == 0) { m_console.printf("Use cheatinit before cheatrange\n"); return; } - if (!validate_cpu_space_parameter(m_cheat.cpu, AS_PROGRAM, space)) + if (!validate_device_space_parameter(m_cheat.cpu, -1, space)) return; active_cheat = m_cheat.cheatmap.size(); m_cheat.cheatmap.resize(m_cheat.cheatmap.size() + real_length); } - /* initialize cheatmap in the selected space */ - for (i = 0; i < region_count; i++) + // initialize cheatmap in the selected space + for (u8 i = 0; i < region_count; i++) if (!cheat_region[i].disabled) - for (curaddr = cheat_region[i].offset; curaddr <= cheat_region[i].endoffset; curaddr += m_cheat.width) + for (u64 curaddr = cheat_region[i].offset; curaddr <= cheat_region[i].endoffset; curaddr += m_cheat.width) if (cheat_address_is_valid(*space, curaddr)) { m_cheat.cheatmap[active_cheat].previous_value = cheat_read_extended(&m_cheat, *space, curaddr); @@ -2711,10 +2950,8 @@ void debugger_commands::execute_cheatinit(int ref, const std::vector<std::string active_cheat++; } - /* give a detailed init message to avoid searches being mistakingly carried out on the wrong CPU */ - device_t *cpu = nullptr; - validate_cpu_parameter(m_cheat.cpu, cpu); - m_console.printf("%u cheat initialized for CPU index %s ( aka %s )\n", active_cheat, m_cheat.cpu, cpu->tag()); + // give a detailed init message to avoid searches being mistakingly carried out on the wrong CPU + m_console.printf("%u cheat initialized for CPU index %s ( aka %s )\n", active_cheat, m_cheat.cpu, space->device().tag()); } @@ -2722,14 +2959,8 @@ void debugger_commands::execute_cheatinit(int ref, const std::vector<std::string execute_cheatnext - execute the search -------------------------------------------------*/ -void debugger_commands::execute_cheatnext(int ref, const std::vector<std::string> ¶ms) +void debugger_commands::execute_cheatnext(bool initial, const std::vector<std::string> ¶ms) { - address_space *space; - u64 cheatindex; - u32 active_cheat = 0; - u8 condition; - u64 comp_value = 0; - enum { CHEAT_ALL = 0, @@ -2754,14 +2985,17 @@ void debugger_commands::execute_cheatnext(int ref, const std::vector<std::string return; } - if (!validate_cpu_space_parameter(m_cheat.cpu, AS_PROGRAM, space)) + address_space *space; + if (!validate_device_space_parameter(m_cheat.cpu, AS_PROGRAM, space)) return; + u64 comp_value = 0; if (params.size() > 1 && !validate_number_parameter(params[1], comp_value)) return; comp_value = cheat_sign_extend(&m_cheat, comp_value); - /* decode condition */ + // decode condition + u8 condition; if (!core_stricmp(params[0].c_str(), "all")) condition = CHEAT_ALL; else if (!core_stricmp(params[0].c_str(), "equal") || !core_stricmp(params[0].c_str(), "eq")) @@ -2790,12 +3024,13 @@ void debugger_commands::execute_cheatnext(int ref, const std::vector<std::string m_cheat.undo++; - /* execute the search */ - for (cheatindex = 0; cheatindex < m_cheat.cheatmap.size(); cheatindex += 1) + // execute the search + u32 active_cheat = 0; + for (u64 cheatindex = 0; cheatindex < m_cheat.cheatmap.size(); cheatindex += 1) if (m_cheat.cheatmap[cheatindex].state == 1) { u64 cheat_value = cheat_read_extended(&m_cheat, *space, m_cheat.cheatmap[cheatindex].offset); - u64 comp_byte = (ref == 0) ? m_cheat.cheatmap[cheatindex].previous_value : m_cheat.cheatmap[cheatindex].first_value; + u64 comp_byte = !initial ? m_cheat.cheatmap[cheatindex].previous_value : m_cheat.cheatmap[cheatindex].first_value; u8 disable_byte = false; switch (condition) @@ -2884,12 +3119,12 @@ void debugger_commands::execute_cheatnext(int ref, const std::vector<std::string else active_cheat++; - /* update previous value */ + // update previous value m_cheat.cheatmap[cheatindex].previous_value = cheat_value; } if (active_cheat <= 5) - execute_cheatlist(0, std::vector<std::string>()); + execute_cheatlist(std::vector<std::string>()); m_console.printf("%u cheats found\n", active_cheat); } @@ -2899,57 +3134,54 @@ void debugger_commands::execute_cheatnext(int ref, const std::vector<std::string execute_cheatlist - show a list of active cheat -------------------------------------------------*/ -void debugger_commands::execute_cheatlist(int ref, const std::vector<std::string> ¶ms) +void debugger_commands::execute_cheatlist(const std::vector<std::string> ¶ms) { - char spaceletter, sizeletter; - address_space *space; - device_t *cpu; - u32 active_cheat = 0; - u64 cheatindex; - u64 sizemask; - FILE *f = nullptr; - if (m_cheat.cpu[0] == 0) { m_console.printf("Use cheatinit before cheatlist\n"); return; } - if (!validate_cpu_space_parameter(m_cheat.cpu, AS_PROGRAM, space)) + address_space *space; + if (!validate_device_space_parameter(m_cheat.cpu, -1, space)) return; - if (!validate_cpu_parameter(m_cheat.cpu, cpu)) - return; + device_t &cpu = space->device(); + FILE *f = nullptr; if (params.size() > 0) f = fopen(params[0].c_str(), "w"); + char spaceletter; switch (space->spacenum()) { default: - case AS_PROGRAM: spaceletter = 'p'; break; - case AS_DATA: spaceletter = 'd'; break; - case AS_IO: spaceletter = 'i'; break; - case AS_OPCODES: spaceletter = 'o'; break; + case AS_PROGRAM: spaceletter = 'p'; break; + case AS_DATA: spaceletter = 'd'; break; + case AS_IO: spaceletter = 'i'; break; + case AS_OPCODES: spaceletter = 'o'; break; } + char sizeletter; + u64 sizemask; switch (m_cheat.width) { default: - case 1: sizeletter = 'b'; sizemask = 0xffU; break; - case 2: sizeletter = 'w'; sizemask = 0xffffU; break; - case 4: sizeletter = 'd'; sizemask = 0xffffffffU; break; - case 8: sizeletter = 'q'; sizemask = 0xffffffffffffffffU; break; + case 1: sizeletter = 'b'; sizemask = 0xffU; break; + case 2: sizeletter = 'w'; sizemask = 0xffffU; break; + case 4: sizeletter = 'd'; sizemask = 0xffffffffU; break; + case 8: sizeletter = 'q'; sizemask = 0xffffffffffffffffU; break; } - /* write the cheat list */ + // write the cheat list + u32 active_cheat = 0; util::ovectorstream output; - for (cheatindex = 0; cheatindex < m_cheat.cheatmap.size(); cheatindex += 1) + for (u64 cheatindex = 0; cheatindex < m_cheat.cheatmap.size(); cheatindex += 1) { if (m_cheat.cheatmap[cheatindex].state == 1) { - u64 value = cheat_byte_swap(&m_cheat, cheat_read_extended(&m_cheat, *space, m_cheat.cheatmap[cheatindex].offset)) & sizemask; - offs_t address = space->byte_to_address(m_cheat.cheatmap[cheatindex].offset); + u64 const value = cheat_byte_swap(&m_cheat, cheat_read_extended(&m_cheat, *space, m_cheat.cheatmap[cheatindex].offset)) & sizemask; + offs_t const address = space->byte_to_address(m_cheat.cheatmap[cheatindex].offset); if (!params.empty()) { @@ -2964,7 +3196,7 @@ void debugger_commands::execute_cheatlist(int ref, const std::vector<std::string " </script>\n" " </cheat>\n\n", active_cheat, space->logaddrchars(), address, m_cheat.width * 2, value, - cpu->tag(), spaceletter, sizeletter, space->logaddrchars(), address, m_cheat.width * 2, cheat_byte_swap(&m_cheat, m_cheat.cheatmap[cheatindex].first_value) & sizemask); + cpu.tag(), spaceletter, sizeletter, space->logaddrchars(), address, m_cheat.width * 2, cheat_byte_swap(&m_cheat, m_cheat.cheatmap[cheatindex].first_value) & sizemask); auto const &text(output.vec()); fprintf(f, "%.*s", int(unsigned(text.size())), &text[0]); } @@ -2987,14 +3219,12 @@ void debugger_commands::execute_cheatlist(int ref, const std::vector<std::string execute_cheatundo - undo the last search -------------------------------------------------*/ -void debugger_commands::execute_cheatundo(int ref, const std::vector<std::string> ¶ms) +void debugger_commands::execute_cheatundo(const std::vector<std::string> ¶ms) { - u64 cheatindex; - u32 undo_count = 0; - if (m_cheat.undo > 0) { - for (cheatindex = 0; cheatindex < m_cheat.cheatmap.size(); cheatindex += 1) + u32 undo_count = 0; + for (u64 cheatindex = 0; cheatindex < m_cheat.cheatmap.size(); cheatindex += 1) { if (m_cheat.cheatmap[cheatindex].undo == m_cheat.undo) { @@ -3016,39 +3246,34 @@ void debugger_commands::execute_cheatundo(int ref, const std::vector<std::string execute_find - execute the find command -------------------------------------------------*/ -void debugger_commands::execute_find(int ref, const std::vector<std::string> ¶ms) +void debugger_commands::execute_find(int spacenum, const std::vector<std::string> ¶ms) { - u64 offset, endoffset, length; + u64 offset, length; address_space *space; - u64 data_to_find[256]; - u8 data_size[256]; - int cur_data_size; - int data_count = 0; - int found = 0; - /* validate parameters */ - if (!validate_number_parameter(params[0], offset)) + // validate parameters + if (!validate_target_address_parameter(params[0], spacenum, space, offset)) return; if (!validate_number_parameter(params[1], length)) return; - if (!validate_cpu_space_parameter(nullptr, ref, space)) - return; - /* further validation */ - endoffset = space->address_to_byte_end((offset + length - 1) & space->addrmask()); + // further validation + u64 const endoffset = space->address_to_byte_end((offset + length - 1) & space->addrmask()); offset = space->address_to_byte(offset & space->addrmask()); - cur_data_size = space->addr_shift() > 0 ? 2 : 1 << -space->addr_shift(); + int cur_data_size = (space->addr_shift() > 0) ? 2 : (1 << -space->addr_shift()); if (cur_data_size == 0) cur_data_size = 1; - /* parse the data parameters */ + // parse the data parameters + u64 data_to_find[256]; + u8 data_size[256]; + int data_count = 0; for (int i = 2; i < params.size(); i++) { - const char *pdata = params[i].c_str(); - size_t pdatalen = strlen(pdata) - 1; + char const *pdata = params[i].c_str(); + auto const pdatalen = params[i].length() - 1; - /* check for a string */ - if (pdata[0] == '"' && pdata[pdatalen] == '"') + if (pdata[0] == '"' && pdata[pdatalen] == '"') // check for a string { for (int j = 1; j < pdatalen; j++) { @@ -3056,36 +3281,35 @@ void debugger_commands::execute_find(int ref, const std::vector<std::string> &pa data_size[data_count++] = 1; } } - - /* otherwise, validate as a number */ - else + else // otherwise, validate as a number { - /* check for a 'b','w','d',or 'q' prefix */ + // check for a 'b','w','d',or 'q' prefix data_size[data_count] = cur_data_size; if (tolower(u8(pdata[0])) == 'b' && pdata[1] == '.') { data_size[data_count] = cur_data_size = 1; pdata += 2; } if (tolower(u8(pdata[0])) == 'w' && pdata[1] == '.') { data_size[data_count] = cur_data_size = 2; pdata += 2; } if (tolower(u8(pdata[0])) == 'd' && pdata[1] == '.') { data_size[data_count] = cur_data_size = 4; pdata += 2; } if (tolower(u8(pdata[0])) == 'q' && pdata[1] == '.') { data_size[data_count] = cur_data_size = 8; pdata += 2; } - /* look for a wildcard */ + // look for a wildcard if (!strcmp(pdata, "?")) data_size[data_count++] |= 0x10; - /* otherwise, validate as a number */ - else if (!validate_number_parameter(pdata, data_to_find[data_count++])) + // otherwise, validate as a number + else if (!validate_number_parameter(params[i], data_to_find[data_count++])) return; } } - /* now search */ + // now search device_memory_interface &memory = space->device().memory(); auto dis = space->device().machine().disable_side_effects(); + int found = 0; for (u64 i = offset; i <= endoffset; i += data_size[0]) { int suboffset = 0; bool match = true; - /* find the entire string */ + // find the entire string for (int j = 0; j < data_count && match; j++) { offs_t address = space->byte_to_address(i + suboffset); @@ -3124,13 +3348,13 @@ void debugger_commands::execute_find(int ref, const std::vector<std::string> &pa break; default: - /* all other cases are wildcards */ + // all other cases are wildcards break; } suboffset += data_size[j] & 0x0f; } - /* did we find it? */ + // did we find it? if (match) { found++; @@ -3138,7 +3362,7 @@ void debugger_commands::execute_find(int ref, const std::vector<std::string> &pa } } - /* print something if not found */ + // print something if not found if (found == 0) m_console.printf("Not found\n"); } @@ -3148,22 +3372,20 @@ void debugger_commands::execute_find(int ref, const std::vector<std::string> &pa // execute_fill - execute the fill command //------------------------------------------------- -void debugger_commands::execute_fill(int ref, const std::vector<std::string> ¶ms) +void debugger_commands::execute_fill(int spacenum, const std::vector<std::string> ¶ms) { u64 offset, length; address_space *space; // validate parameters - if (!validate_number_parameter(params[0], offset)) + if (!validate_target_address_parameter(params[0], spacenum, space, offset)) return; if (!validate_number_parameter(params[1], length)) return; - if (!validate_cpu_space_parameter(nullptr, ref, space)) - return; // further validation offset = space->address_to_byte(offset & space->addrmask()); - int cur_data_size = space->addr_shift() > 0 ? 2 : 1 << -space->addr_shift(); + int cur_data_size = (space->addr_shift() > 0) ? 2 : (1 << -space->addr_shift()); if (cur_data_size == 0) cur_data_size = 1; @@ -3255,22 +3477,22 @@ void debugger_commands::execute_fill(int ref, const std::vector<std::string> &pa execute_dasm - execute the dasm command -------------------------------------------------*/ -void debugger_commands::execute_dasm(int ref, const std::vector<std::string> ¶ms) +void debugger_commands::execute_dasm(const std::vector<std::string> ¶ms) { u64 offset, length, bytes = 1; address_space *space; - /* validate parameters */ + // validate parameters if (!validate_number_parameter(params[1], offset)) return; if (!validate_number_parameter(params[2], length)) return; if (params.size() > 3 && !validate_number_parameter(params[3], bytes)) return; - if (!validate_cpu_space_parameter(params.size() > 4 ? params[4].c_str() : nullptr, AS_PROGRAM, space)) + if (!validate_device_space_parameter(params.size() > 4 ? params[4] : std::string_view(), AS_PROGRAM, space)) return; - /* determine the width of the bytes */ + // determine the width of the bytes device_disasm_interface *dasmintf; if (!space->device().interface(dasmintf)) { @@ -3278,7 +3500,7 @@ void debugger_commands::execute_dasm(int ref, const std::vector<std::string> &pa return; } - /* build the data, check the maximum size of the opcodes and disasm */ + // build the data, check the maximum size of the opcodes and disasm std::vector<offs_t> pcs; std::vector<std::string> instructions; std::vector<std::string> tpc; @@ -3352,21 +3574,20 @@ void debugger_commands::execute_dasm(int ref, const std::vector<std::string> &pa trace over and trace info -------------------------------------------------*/ -void debugger_commands::execute_trace_internal(int ref, const std::vector<std::string> ¶ms, bool trace_over) +void debugger_commands::execute_trace_internal(const std::vector<std::string> ¶ms, bool trace_over) { const char *action = nullptr; bool detect_loops = true; bool logerror = false; device_t *cpu; - FILE *f = nullptr; const char *mode; std::string filename = params[0]; - /* replace macros */ + // replace macros strreplace(filename, "{game}", m_machine.basename()); - /* validate parameters */ - if (!validate_cpu_parameter(params.size() > 1 ? params[1].c_str() : nullptr, cpu)) + // validate parameters + if (!validate_cpu_parameter(params.size() > 1 ? params[1] : std::string_view(), cpu)) return; if (params.size() > 2) { @@ -3390,12 +3611,13 @@ void debugger_commands::execute_trace_internal(int ref, const std::vector<std::s if (!debug_command_parameter_command(action = (params.size() > 3) ? params[3].c_str() : nullptr)) return; - /* open the file */ + // open the file + FILE *f = nullptr; if (core_stricmp(filename.c_str(), "off") != 0) { mode = "w"; - /* opening for append? */ + // opening for append? if ((filename[0] == '>') && (filename[1] == '>')) { mode = "a"; @@ -3410,7 +3632,7 @@ void debugger_commands::execute_trace_internal(int ref, const std::vector<std::s } } - /* do it */ + // do it cpu->debug()->trace(f, trace_over, detect_loops, logerror, action); if (f) m_console.printf("Tracing CPU '%s' to file %s\n", cpu->tag(), filename); @@ -3423,9 +3645,9 @@ void debugger_commands::execute_trace_internal(int ref, const std::vector<std::s execute_trace - execute the trace command -------------------------------------------------*/ -void debugger_commands::execute_trace(int ref, const std::vector<std::string> ¶ms) +void debugger_commands::execute_trace(const std::vector<std::string> ¶ms) { - execute_trace_internal(ref, params, false); + execute_trace_internal(params, false); } @@ -3433,9 +3655,9 @@ void debugger_commands::execute_trace(int ref, const std::vector<std::string> &p execute_traceover - execute the trace over command -------------------------------------------------*/ -void debugger_commands::execute_traceover(int ref, const std::vector<std::string> ¶ms) +void debugger_commands::execute_traceover(const std::vector<std::string> ¶ms) { - execute_trace_internal(ref, params, true); + execute_trace_internal(params, true); } @@ -3443,7 +3665,7 @@ void debugger_commands::execute_traceover(int ref, const std::vector<std::string execute_traceflush - execute the trace flush command -------------------------------------------------*/ -void debugger_commands::execute_traceflush(int ref, const std::vector<std::string> ¶ms) +void debugger_commands::execute_traceflush(const std::vector<std::string> ¶ms) { m_machine.debugger().cpu().flush_traces(); } @@ -3453,28 +3675,34 @@ void debugger_commands::execute_traceflush(int ref, const std::vector<std::strin execute_history - execute the history command -------------------------------------------------*/ -void debugger_commands::execute_history(int ref, const std::vector<std::string> ¶ms) +void debugger_commands::execute_history(const std::vector<std::string> ¶ms) { - /* validate parameters */ + // validate parameters address_space *space; - if (!validate_cpu_space_parameter(!params.empty() ? params[0].c_str() : nullptr, AS_PROGRAM, space)) + if (!validate_device_space_parameter(!params.empty() ? params[0] : std::string_view(), AS_PROGRAM, space)) return; u64 count = device_debug::HISTORY_SIZE; if (params.size() > 1 && !validate_number_parameter(params[1], count)) return; - /* further validation */ + // further validation if (count > device_debug::HISTORY_SIZE) count = device_debug::HISTORY_SIZE; - device_debug *debug = space->device().debug(); + device_execute_interface const *execute; + if (!space->device().interface(execute)) + { + m_console.printf("Device %s is not a CPU\n", space->device().name()); + return; + } + device_debug *const debug = space->device().debug(); - /* loop over lines */ + // loop over lines device_disasm_interface *dasmintf; if (!space->device().interface(dasmintf)) { - m_console.printf("No disassembler available for %s\n", space->device().name()); + m_console.printf("No disassembler available for device %s\n", space->device().name()); return; } @@ -3482,7 +3710,7 @@ void debugger_commands::execute_history(int ref, const std::vector<std::string> for (int index = 0; index < (int) count; index++) { - offs_t pc = debug->history_pc(-index); + offs_t const pc = debug->history_pc(-index); std::string instruction; offs_t next_offset; offs_t size; @@ -3498,7 +3726,7 @@ void debugger_commands::execute_history(int ref, const std::vector<std::string> execute_trackpc - execute the trackpc command -------------------------------------------------*/ -void debugger_commands::execute_trackpc(int ref, const std::vector<std::string> ¶ms) +void debugger_commands::execute_trackpc(const std::vector<std::string> ¶ms) { // Gather the on/off switch (if present) bool turnOn = true; @@ -3507,7 +3735,7 @@ void debugger_commands::execute_trackpc(int ref, const std::vector<std::string> // Gather the cpu id (if present) device_t *cpu = nullptr; - if (!validate_cpu_parameter((params.size() > 1) ? params[1].c_str() : nullptr, cpu)) + if (!validate_cpu_parameter((params.size() > 1) ? params[1] : std::string_view(), cpu)) return; const device_state_interface *state; @@ -3547,7 +3775,7 @@ void debugger_commands::execute_trackpc(int ref, const std::vector<std::string> execute_trackmem - execute the trackmem command -------------------------------------------------*/ -void debugger_commands::execute_trackmem(int ref, const std::vector<std::string> ¶ms) +void debugger_commands::execute_trackmem(const std::vector<std::string> ¶ms) { // Gather the on/off switch (if present) bool turnOn = true; @@ -3555,8 +3783,11 @@ void debugger_commands::execute_trackmem(int ref, const std::vector<std::string> return; // Gather the cpu id (if present) + std::string_view cpuparam; + if (params.size() > 1) + cpuparam = params[1]; device_t *cpu = nullptr; - if (!validate_cpu_parameter((params.size() > 1) ? params[1].c_str() : nullptr, cpu)) + if (!validate_cpu_parameter(cpuparam, cpu)) return; // Should we clear the existing data? @@ -3566,7 +3797,7 @@ void debugger_commands::execute_trackmem(int ref, const std::vector<std::string> // Get the address space for the given cpu address_space *space; - if (!validate_cpu_space_parameter((params.size() > 1) ? params[1].c_str() : nullptr, AS_PROGRAM, space)) + if (!validate_device_space_parameter(cpuparam, AS_PROGRAM, space)) return; // Inform the CPU it's time to start tracking memory writes @@ -3582,28 +3813,19 @@ void debugger_commands::execute_trackmem(int ref, const std::vector<std::string> execute_pcatmem - execute the pcatmem command -------------------------------------------------*/ -void debugger_commands::execute_pcatmem(int ref, const std::vector<std::string> ¶ms) +void debugger_commands::execute_pcatmem(int spacenum, const std::vector<std::string> ¶ms) { - // Gather the required address parameter + // Gather the required target address/space parameter u64 address; - if (!validate_number_parameter(params[0], address)) - return; - - // Gather the cpu id (if present) - device_t *cpu = nullptr; - if (!validate_cpu_parameter((params.size() > 1) ? params[1].c_str() : nullptr, cpu)) - return; - - // Get the address space for the given cpu address_space *space; - if (!validate_cpu_space_parameter((params.size() > 1) ? params[1].c_str() : nullptr, ref, space)) + if (!validate_target_address_parameter(params[0], spacenum, space, address)) return; // Translate the address offs_t a = address & space->logaddrmask(); if (!space->device().memory().translate(space->spacenum(), TRANSLATE_READ_DEBUG, a)) { - m_console.printf("Bad address\n"); + m_console.printf("Address translation failed\n"); return; } @@ -3630,8 +3852,7 @@ void debugger_commands::execute_pcatmem(int ref, const std::vector<std::string> } // Recover the pc & print - const int space_num = (int)ref; - const offs_t result = space->device().debug()->track_mem_pc_from_space_address_data(space_num, address, data); + const offs_t result = space->device().debug()->track_mem_pc_from_space_address_data(spacenum, address, data); if (result != (offs_t)(-1)) m_console.printf("%02x\n", result); else @@ -3643,7 +3864,7 @@ void debugger_commands::execute_pcatmem(int ref, const std::vector<std::string> execute_snap - execute the snapshot command -------------------------------------------------*/ -void debugger_commands::execute_snap(int ref, const std::vector<std::string> ¶ms) +void debugger_commands::execute_snap(const std::vector<std::string> ¶ms) { /* if no params, use the default behavior */ if (params.empty()) @@ -3689,7 +3910,7 @@ void debugger_commands::execute_snap(int ref, const std::vector<std::string> &pa execute_source - execute the source command -------------------------------------------------*/ -void debugger_commands::execute_source(int ref, const std::vector<std::string> ¶ms) +void debugger_commands::execute_source(const std::vector<std::string> ¶ms) { m_console.source_script(params[0].c_str()); } @@ -3699,26 +3920,19 @@ void debugger_commands::execute_source(int ref, const std::vector<std::string> & execute_map - execute the map command -------------------------------------------------*/ -void debugger_commands::execute_map(int ref, const std::vector<std::string> ¶ms) +void debugger_commands::execute_map(int spacenum, const std::vector<std::string> ¶ms) { - address_space *space; - offs_t taddress; + // validate parameters u64 address; - int intention; - - /* validate parameters */ - if (!validate_number_parameter(params[0], address)) - return; - - /* CPU is implicit */ - if (!validate_cpu_space_parameter(nullptr, ref, space)) + address_space *space; + if (!validate_target_address_parameter(params[0], spacenum, space, address)) return; - /* do the translation first */ - for (intention = TRANSLATE_READ_DEBUG; intention <= TRANSLATE_FETCH_DEBUG; intention++) + // do the translation first + for (int intention = TRANSLATE_READ_DEBUG; intention <= TRANSLATE_FETCH_DEBUG; intention++) { static const char *const intnames[] = { "Read", "Write", "Fetch" }; - taddress = address & space->addrmask(); + offs_t taddress = address & space->addrmask(); if (space->device().memory().translate(space->spacenum(), intention, taddress)) { std::string mapname = space->get_handler_string((intention == TRANSLATE_WRITE_DEBUG) ? read_or_write::WRITE : read_or_write::READ, taddress); @@ -3739,20 +3953,28 @@ void debugger_commands::execute_map(int ref, const std::vector<std::string> &par execute_memdump - execute the memdump command -------------------------------------------------*/ -void debugger_commands::execute_memdump(int ref, const std::vector<std::string> ¶ms) +void debugger_commands::execute_memdump(const std::vector<std::string> ¶ms) { - FILE *file; - const char *filename; + device_t *root = &m_machine.root_device(); + if ((params.size() >= 2) && !validate_device_parameter(params[1], root)) + return; - filename = params.empty() ? "memdump.log" : params[0].c_str(); + char const *const filename = params.empty() ? "memdump.log" : params[0].c_str(); + FILE *const file = fopen(filename, "w"); + if (!file) + { + m_console.printf("Error opening file %s\n", filename); + return; + } - m_console.printf("Dumping memory to %s\n", filename); + m_console.printf("Dumping memory maps to %s\n", filename); - file = fopen(filename, "w"); - if (file) + try { - memory_interface_enumerator iter(m_machine.root_device()); - for (device_memory_interface &memory : iter) { + memory_interface_enumerator iter(*root); + std::vector<memory_entry> entries[2]; + for (device_memory_interface &memory : iter) + { for (int space = 0; space != memory.max_space_count(); space++) if (memory.has_space(space)) { @@ -3760,7 +3982,6 @@ void debugger_commands::execute_memdump(int ref, const std::vector<std::string> bool octal = sp.is_octal(); int nc = octal ? (sp.addr_width() + 2) / 3 : (sp.addr_width() + 3) / 4; - std::vector<memory_entry> entries[2]; sp.dump_maps(entries[0], entries[1]); for (int mode = 0; mode < 2; mode ++) { @@ -3771,8 +3992,8 @@ void debugger_commands::execute_memdump(int ref, const std::vector<std::string> fprintf(file, "%0*o - %0*o:", nc, entry.start, nc, entry.end); else fprintf(file, "%0*x - %0*x:", nc, entry.start, nc, entry.end); - for(const auto &c : entry.context) - if(c.disabled) + for (const auto &c : entry.context) + if (c.disabled) fprintf(file, " %s[off]", c.view->name().c_str()); else fprintf(file, " %s[%d]", c.view->name().c_str(), c.slot); @@ -3780,10 +4001,17 @@ void debugger_commands::execute_memdump(int ref, const std::vector<std::string> } fprintf(file, "\n"); } + entries[0].clear(); + entries[1].clear(); } } fclose(file); } + catch (...) + { + fclose(file); + throw; + } } @@ -3791,17 +4019,17 @@ void debugger_commands::execute_memdump(int ref, const std::vector<std::string> execute_symlist - execute the symlist command -------------------------------------------------*/ -void debugger_commands::execute_symlist(int ref, const std::vector<std::string> ¶ms) +void debugger_commands::execute_symlist(const std::vector<std::string> ¶ms) { - device_t *cpu = nullptr; const char *namelist[1000]; symbol_table *symtable; - int symnum, count = 0; + int count = 0; if (!params.empty()) { - /* validate parameters */ - if (!validate_cpu_parameter(params[0].c_str(), cpu)) + // validate parameters + device_t *cpu; + if (!validate_cpu_parameter(params[0], cpu)) return; symtable = &cpu->debug()->symtable(); m_console.printf("CPU '%s' symbols:\n", cpu->tag()); @@ -3812,10 +4040,10 @@ void debugger_commands::execute_symlist(int ref, const std::vector<std::string> m_console.printf("Global symbols:\n"); } - /* gather names for all symbols */ + // gather names for all symbols for (auto &entry : symtable->entries()) { - /* only display "register" type symbols */ + // only display "register" type symbols if (!entry.second->is_function()) { namelist[count++] = entry.second->name(); @@ -3824,20 +4052,23 @@ void debugger_commands::execute_symlist(int ref, const std::vector<std::string> } } - /* sort the symbols */ + // sort the symbols if (count > 1) - std::sort(&namelist[0], &namelist[count], [](const char *item1, const char *item2) { - return strcmp(item1, item2) < 0; - }); + { + std::sort( + &namelist[0], + &namelist[count], + [] (const char *item1, const char *item2) { return strcmp(item1, item2) < 0; }); + } - /* iterate over symbols and print out relevant ones */ - for (symnum = 0; symnum < count; symnum++) + // iterate over symbols and print out relevant ones + for (int symnum = 0; symnum < count; symnum++) { - const symbol_entry *entry = symtable->find(namelist[symnum]); + symbol_entry const *const entry = symtable->find(namelist[symnum]); assert(entry != nullptr); u64 value = entry->value(); - /* only display "register" type symbols */ + // only display "register" type symbols m_console.printf("%s = %X", namelist[symnum], value); if (!entry->is_lval()) m_console.printf(" (read-only)"); @@ -3850,7 +4081,7 @@ void debugger_commands::execute_symlist(int ref, const std::vector<std::string> execute_softreset - execute the softreset command -------------------------------------------------*/ -void debugger_commands::execute_softreset(int ref, const std::vector<std::string> ¶ms) +void debugger_commands::execute_softreset(const std::vector<std::string> ¶ms) { m_machine.schedule_soft_reset(); } @@ -3860,7 +4091,7 @@ void debugger_commands::execute_softreset(int ref, const std::vector<std::string execute_hardreset - execute the hardreset command -------------------------------------------------*/ -void debugger_commands::execute_hardreset(int ref, const std::vector<std::string> ¶ms) +void debugger_commands::execute_hardreset(const std::vector<std::string> ¶ms) { m_machine.schedule_hard_reset(); } @@ -3870,7 +4101,7 @@ void debugger_commands::execute_hardreset(int ref, const std::vector<std::string mounted files -------------------------------------------------*/ -void debugger_commands::execute_images(int ref, const std::vector<std::string> ¶ms) +void debugger_commands::execute_images(const std::vector<std::string> ¶ms) { image_interface_enumerator iter(m_machine.root_device()); for (device_image_interface &img : iter) @@ -3883,7 +4114,7 @@ void debugger_commands::execute_images(int ref, const std::vector<std::string> & execute_mount - execute the image mount command -------------------------------------------------*/ -void debugger_commands::execute_mount(int ref, const std::vector<std::string> ¶ms) +void debugger_commands::execute_mount(const std::vector<std::string> ¶ms) { bool done = false; for (device_image_interface &img : image_interface_enumerator(m_machine.root_device())) @@ -3906,7 +4137,7 @@ void debugger_commands::execute_mount(int ref, const std::vector<std::string> &p execute_unmount - execute the image unmount command -------------------------------------------------*/ -void debugger_commands::execute_unmount(int ref, const std::vector<std::string> ¶ms) +void debugger_commands::execute_unmount(const std::vector<std::string> ¶ms) { bool done = false; for (device_image_interface &img : image_interface_enumerator(m_machine.root_device())) @@ -3929,7 +4160,7 @@ void debugger_commands::execute_unmount(int ref, const std::vector<std::string> natural keyboard input -------------------------------------------------*/ -void debugger_commands::execute_input(int ref, const std::vector<std::string> ¶ms) +void debugger_commands::execute_input(const std::vector<std::string> ¶ms) { m_machine.natkeyboard().post_coded(params[0].c_str()); } @@ -3940,7 +4171,7 @@ void debugger_commands::execute_input(int ref, const std::vector<std::string> &p keyboard codes -------------------------------------------------*/ -void debugger_commands::execute_dumpkbd(int ref, const std::vector<std::string> ¶ms) +void debugger_commands::execute_dumpkbd(const std::vector<std::string> ¶ms) { // was there a file specified? const char *filename = !params.empty() ? params[0].c_str() : nullptr; |