From d8d588262de1f11a529b208e470cff9b89a4cba6 Mon Sep 17 00:00:00 2001 From: AJR Date: Sun, 28 Aug 2022 13:27:35 -0400 Subject: [PATCH] Debugger changes - Added exception points as a new class of "points" triggering on specific exception numbers, with a similar set of commands to breakpoints and registerpoints. - Removed the per-instruction callback hook from device_debug. Only one driver was using this (rmnimbus.cpp), and what it was doing with it could be done more cleanly with exception points. - Change the type of the action string parameter for "points"-creating methods and make some parameters optional for those. - Change trace file logging to use a std::ostream instead of FILE * to take better advantage of strformat. --- docs/source/debugger/exceptionpoint.rst | 134 ++++ docs/source/debugger/index.rst | 1 + src/emu/debug/debugcmd.cpp | 269 +++++-- src/emu/debug/debugcmd.h | 4 + src/emu/debug/debugcpu.cpp | 211 ++++-- src/emu/debug/debugcpu.h | 45 +- src/emu/debug/debughlp.cpp | 99 +++ src/emu/debug/dvbpoints.cpp | 2 +- src/emu/debug/dvrpoints.cpp | 2 +- src/emu/debug/points.cpp | 68 +- src/emu/debug/points.h | 48 +- src/emu/emufwd.h | 1 + src/mame/rm/rmnimbus.h | 7 - src/mame/rm/rmnimbus_m.cpp | 687 ------------------ src/osd/modules/debugger/debuggdbstub.cpp | 6 +- .../modules/debugger/osx/disassemblyviewer.mm | 2 +- src/osd/modules/debugger/qt/dasmwindow.cpp | 2 +- .../debugger/win/disasmbasewininfo.cpp | 2 +- 18 files changed, 738 insertions(+), 852 deletions(-) create mode 100644 docs/source/debugger/exceptionpoint.rst diff --git a/docs/source/debugger/exceptionpoint.rst b/docs/source/debugger/exceptionpoint.rst new file mode 100644 index 00000000000..52a8ee67a19 --- /dev/null +++ b/docs/source/debugger/exceptionpoint.rst @@ -0,0 +1,134 @@ +.. _debugger-exceptionpoint-list: + +Exception Point Debugger Commands +================================= + +:ref:`debugger-command-epset` + sets a new exception point +:ref:`debugger-command-epclear` + clears a specific exception point or all exception points +:ref:`debugger-command-epdisable` + disables a specific exception point or all exception points +:ref:`debugger-command-epenable` + enables a specific exception point or all exception points +:ref:`debugger-command-eplist` + lists exception points + +Exception points halt execution and activate the debugger when +a CPU raises a particular exception number. + + +.. _debugger-command-epset: + +epset +----- + +**ep[set] [,[,]]** + +Sets a new exception point for exceptions of type ****. The +optional **** parameter lets you specify an expression that +will be evaluated each time the exception point is hit. If the result +of the expression is true (non-zero), the exception point will actually +halt execution at the start of the exception handler; otherwise, +execution will continue with no notification. The optional **** +parameter provides a command that is executed whenever the exception +point is hit and the **** is true. Note that you may need to +embed the action within braces ``{ }`` in order to prevent commas and +semicolons from being interpreted as applying to the ``epset`` command +itself. + +The numbering of exceptions depends upon the CPU type. Causes of +exceptions may include internally or externally vectored interrupts, +errors occurring within instructions and system calls. + +Each exception point that is set is assigned an index which can be used +in other exception point commands to reference this exception point. + +Examples: + +``ep 2`` + Set an exception that will halt execution whenever the visible CPU + raises exception number 2. + +Back to :ref:`debugger-exceptionpoint-list` + + +.. _debugger-command-epclear: + +epclear +------- + +**epclear [[,…]]** + +The epclear command clears exception points. If **** is +specified, only the requested exception points are cleared, otherwise +all exception points are cleared. + +Examples: + +``epclear 3`` + Clear exception point index 3. + +``epclear`` + Clear all exception points. + +Back to :ref:`debugger-exceptionpoint-list` + + +.. _debugger-command-epdisable: + +epdisable +--------- + +**epdisable [[,…]]** + +The epdisable command disables exception points. If **** is +specified, only the requested exception points are disabled, otherwise +all exception points are disabled. Note that disabling an exception +point does not delete it, it just temporarily marks the exception +point as inactive. + +Examples: + +``epdisable 3`` + Disable exception point index 3. + +``epdisable`` + Disable all exception points. + +Back to :ref:`debugger-exceptionpoint-list` + + +.. _debugger-command-epenable: + +epenable +-------- + +**epenable [[,…]]** + +The epenable command enables exception points. If **** is +specified, only the requested exception points are enabled, otherwise +all exception points are enabled. + +Examples: + +``epenable 3`` + Enable exception point index 3. + +``epenable`` + Enable all exception points. + +Back to :ref:`debugger-exceptionpoint-list` + + +.. _debugger-command-eplist: + +eplist +------ + +**eplist** + +The eplist command lists all the current exception points, along with +their index and any conditions or actions attached to them. + +Back to :ref:`debugger-exceptionpoint-list` diff --git a/docs/source/debugger/index.rst b/docs/source/debugger/index.rst index 4b6cd02d2ba..3db394f7516 100644 --- a/docs/source/debugger/index.rst +++ b/docs/source/debugger/index.rst @@ -50,6 +50,7 @@ name of a command, to see documentation directly in MAME. breakpoint watchpoint registerpoints + exceptionpoint annotation cheats image diff --git a/src/emu/debug/debugcmd.cpp b/src/emu/debug/debugcmd.cpp index 7ef0110031e..30ad53d762b 100644 --- a/src/emu/debug/debugcmd.cpp +++ b/src/emu/debug/debugcmd.cpp @@ -282,6 +282,13 @@ debugger_commands::debugger_commands(running_machine& machine, debugger_cpu& cpu m_console.register_command("rpenable", CMDFLAG_NONE, 0, MAX_COMMAND_PARAMS, std::bind(&debugger_commands::execute_rpdisenable, this, true, _1)); m_console.register_command("rplist", CMDFLAG_NONE, 0, 1, std::bind(&debugger_commands::execute_rplist, this, _1)); + m_console.register_command("epset", CMDFLAG_NONE, 1, 3, std::bind(&debugger_commands::execute_epset, this, _1)); + m_console.register_command("ep", CMDFLAG_NONE, 1, 3, std::bind(&debugger_commands::execute_epset, this, _1)); + m_console.register_command("epclear", CMDFLAG_NONE, 0, MAX_COMMAND_PARAMS, std::bind(&debugger_commands::execute_epclear, this, _1)); + m_console.register_command("epdisable", CMDFLAG_NONE, 0, MAX_COMMAND_PARAMS, std::bind(&debugger_commands::execute_epdisenable, this, false, _1)); + m_console.register_command("epenable", CMDFLAG_NONE, 0, MAX_COMMAND_PARAMS, std::bind(&debugger_commands::execute_epdisenable, this, true, _1)); + m_console.register_command("eplist", CMDFLAG_NONE, 0, 1, std::bind(&debugger_commands::execute_eplist, 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)); @@ -471,8 +478,9 @@ bool debugger_commands::validate_boolean_parameter(std::string_view param, bool return true; // evaluate the expression; success if no error - bool const is_true = util::streqlower(param, "true"); - bool const is_false = util::streqlower(param, "false"); + using namespace std::literals; + bool const is_true = util::streqlower(param, "true"sv); + bool const is_false = util::streqlower(param, "false"sv); if (is_true || is_false) { @@ -1153,7 +1161,7 @@ void debugger_commands::execute_tracelog(const std::vector &pa /* then do a printf */ std::ostringstream buffer; if (mini_printf(buffer, params[0], params.size() - 1, &values[1])) - m_console.get_visible_cpu()->debug()->trace_printf("%s", std::move(buffer).str().c_str()); + m_console.get_visible_cpu()->debug()->trace_printf("%s", std::move(buffer).str()); } @@ -1189,7 +1197,7 @@ void debugger_commands::execute_tracesym(const std::vector &pa // then do a printf std::ostringstream buffer; if (mini_printf(buffer, format.str(), params.size(), values)) - m_console.get_visible_cpu()->debug()->trace_printf("%s", std::move(buffer).str().c_str()); + m_console.get_visible_cpu()->debug()->trace_printf("%s", std::move(buffer).str()); } @@ -1819,12 +1827,12 @@ void debugger_commands::execute_bpset(const std::vector ¶m return; // param 3 is the action - std::string action; + std::string_view action; if (params.size() > 2 && !debug_command_parameter_command(action = params[2])) return; // set the breakpoint - int const bpnum = debug->breakpoint_set(address, condition.is_empty() ? nullptr : condition.original_string(), action.c_str()); + int const bpnum = debug->breakpoint_set(address, condition.is_empty() ? nullptr : condition.original_string(), action); m_console.printf("Breakpoint %X set\n", bpnum); } @@ -1966,16 +1974,20 @@ void debugger_commands::execute_wpset(int spacenum, const std::vector 4 && !debug_command_parameter_command(action = params[4])) return; // set the watchpoint - int const wpnum = debug->watchpoint_set(*space, type, address, length, (condition.is_empty()) ? nullptr : condition.original_string(), action.c_str()); + 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); } @@ -2133,12 +2145,12 @@ void debugger_commands::execute_rpset(const std::vector ¶m return; // param 2 is the action - std::string action; + std::string_view action; if (params.size() > 1 && !debug_command_parameter_command(action = params[1])) return; // set the registerpoint - int const rpnum = cpu->debug()->registerpoint_set(condition.original_string(), action.c_str()); + int const rpnum = cpu->debug()->registerpoint_set(condition.original_string(), action); m_console.printf("Registerpoint %X set\n", rpnum); } @@ -2201,6 +2213,148 @@ void debugger_commands::execute_rpdisenable(bool enable, const std::vector ¶ms) +{ + // CPU is implicit + device_t *cpu; + if (!validate_cpu_parameter(std::string_view(), cpu)) + return; + + // param 1 is the exception type + u64 type; + if (!validate_number_parameter(params[0], type)) + return; + + // param 2 is the condition + parsed_expression condition(cpu->debug()->symtable()); + if (params.size() > 1 && !debug_command_parameter_expression(params[1], condition)) + return; + + // param 3 is the action + std::string_view action; + if (params.size() > 2 && !debug_command_parameter_command(action = params[2])) + return; + + // set the exception point + int epnum = cpu->debug()->exceptionpoint_set(type, (condition.is_empty()) ? nullptr : condition.original_string(), action); + m_console.printf("Exception point %X set\n", epnum); +} + + +//------------------------------------------------- +// execute_epclear - execute the exception point +// clear command +//------------------------------------------------- + +void debugger_commands::execute_epclear(const std::vector ¶ms) +{ + if (params.empty()) // if no parameters, clear all + { + for (device_t &device : device_enumerator(m_machine.root_device())) + device.debug()->exceptionpoint_clear_all(); + m_console.printf("Cleared all exception points\n"); + } + else // otherwise, clear the specific ones + { + execute_index_command( + params, + [this] (device_t &device, u64 param) -> bool + { + if (!device.debug()->exceptionpoint_clear(param)) + return false; + m_console.printf("Exception point %X cleared\n", param); + return true; + }, + "Invalid exception point number %X\n"); + } +} + + +//------------------------------------------------- +// execute_epdisenable - execute the exception +// point disable/enable commands +//------------------------------------------------- + +void debugger_commands::execute_epdisenable(bool enable, const std::vector ¶ms) +{ + if (params.empty()) // if no parameters, disable/enable all + { + for (device_t &device : device_enumerator(m_machine.root_device())) + device.debug()->exceptionpoint_enable_all(enable); + m_console.printf(enable ? "Enabled all exception points\n" : "Disabled all exception points\n"); + } + else // otherwise, disable/enable the specific ones + { + execute_index_command( + params, + [this, enable] (device_t &device, u64 param) -> bool + { + if (!device.debug()->exceptionpoint_enable(param, enable)) + return false; + m_console.printf(enable ? "Exception point %X enabled\n" : "Exception point %X disabled\n", param); + return true; + }, + "Invalid exception point number %X\n"); + } +} + + +//------------------------------------------------- +// execute_eplist - execute the exception point +// list command +//------------------------------------------------- + +void debugger_commands::execute_eplist(const std::vector ¶ms) +{ + int printed = 0; + std::string buffer; + auto const apply = + [this, &printed, &buffer] (device_t &device) + { + if (!device.debug()->exceptionpoint_list().empty()) + { + m_console.printf("Device '%s' exception points:\n", device.tag()); + + // loop over the exception points + for (const auto &epp : device.debug()->exceptionpoint_list()) + { + debug_exceptionpoint &ep = *epp.second; + buffer = string_format("%c%4X : %X", ep.enabled() ? ' ' : 'D', ep.index(), ep.type()); + if (std::string(ep.condition()).compare("1") != 0) + buffer.append(string_format(" if %s", ep.condition())); + if (!ep.action().empty()) + buffer.append(string_format(" do %s", ep.action())); + m_console.printf("%s\n", buffer); + printed++; + } + } + }; + + if (!params.empty()) + { + device_t *cpu; + if (!validate_cpu_parameter(params[0], cpu)) + return; + apply(*cpu); + if (!printed) + m_console.printf("No exception points currently installed for CPU %s\n", cpu->tag()); + } + else + { + // loop over all CPUs + for (device_t &device : device_enumerator(m_machine.root_device())) + apply(device); + if (!printed) + m_console.printf("No exception points currently installed\n"); + } +} + + /*------------------------------------------------- execute_rplist - execute the registerpoint list command @@ -2221,7 +2375,7 @@ void debugger_commands::execute_rplist(const std::vector ¶ for (const auto &rp : device.debug()->registerpoint_list()) { buffer = string_format("%c%4X if %s", rp.enabled() ? ' ' : 'D', rp.index(), rp.condition()); - if (rp.action() && *rp.action()) + if (!rp.action().empty()) buffer.append(string_format(" do %s", rp.action())); m_console.printf("%s\n", buffer); printed++; @@ -3129,30 +3283,34 @@ void debugger_commands::execute_cheatnext(bool initial, const std::vector 1) ? CHEAT_EQUALTO : CHEAT_EQUAL; - else if (util::streqlower(params[0], "notequal") || util::streqlower(params[0], "ne")) - condition = (params.size() > 1) ? CHEAT_NOTEQUALTO : CHEAT_NOTEQUAL; - else if (util::streqlower(params[0], "decrease") || util::streqlower(params[0], "de") || params[0] == "-") - condition = (params.size() > 1) ? CHEAT_DECREASEOF : CHEAT_DECREASE; - else if (util::streqlower(params[0], "increase") || util::streqlower(params[0], "in") || params[0] == "+") - condition = (params.size() > 1) ? CHEAT_INCREASEOF : CHEAT_INCREASE; - else if (util::streqlower(params[0], "decreaseorequal") || util::streqlower(params[0], "deeq")) - condition = CHEAT_DECREASE_OR_EQUAL; - else if (util::streqlower(params[0], "increaseorequal") || util::streqlower(params[0], "ineq")) - condition = CHEAT_INCREASE_OR_EQUAL; - else if (util::streqlower(params[0], "smallerof") || util::streqlower(params[0], "lt") || params[0] == "<") - condition = CHEAT_SMALLEROF; - else if (util::streqlower(params[0], "greaterof") || util::streqlower(params[0], "gt") || params[0] == ">") - condition = CHEAT_GREATEROF; - else if (util::streqlower(params[0], "changedby") || util::streqlower(params[0], "ch") || params[0] == "~") - condition = CHEAT_CHANGEDBY; - else { - m_console.printf("Invalid condition type\n"); - return; + using util::streqlower; + using namespace std::literals; + if (streqlower(params[0], "all"sv)) + condition = CHEAT_ALL; + else if (streqlower(params[0], "equal"sv) || streqlower(params[0], "eq"sv)) + condition = (params.size() > 1) ? CHEAT_EQUALTO : CHEAT_EQUAL; + else if (streqlower(params[0], "notequal"sv) || streqlower(params[0], "ne"sv)) + condition = (params.size() > 1) ? CHEAT_NOTEQUALTO : CHEAT_NOTEQUAL; + else if (streqlower(params[0], "decrease"sv) || streqlower(params[0], "de"sv) || params[0] == "-"sv) + condition = (params.size() > 1) ? CHEAT_DECREASEOF : CHEAT_DECREASE; + else if (streqlower(params[0], "increase"sv) || streqlower(params[0], "in"sv) || params[0] == "+"sv) + condition = (params.size() > 1) ? CHEAT_INCREASEOF : CHEAT_INCREASE; + else if (streqlower(params[0], "decreaseorequal"sv) || streqlower(params[0], "deeq"sv)) + condition = CHEAT_DECREASE_OR_EQUAL; + else if (streqlower(params[0], "increaseorequal"sv) || streqlower(params[0], "ineq"sv)) + condition = CHEAT_INCREASE_OR_EQUAL; + else if (streqlower(params[0], "smallerof"sv) || streqlower(params[0], "lt"sv) || params[0] == "<"sv) + condition = CHEAT_SMALLEROF; + else if (streqlower(params[0], "greaterof"sv) || streqlower(params[0], "gt"sv) || params[0] == ">"sv) + condition = CHEAT_GREATEROF; + else if (streqlower(params[0], "changedby"sv) || streqlower(params[0], "ch"sv) || params[0] == "~"sv) + condition = CHEAT_CHANGEDBY; + else + { + m_console.printf("Invalid condition type\n"); + return; + } } m_cheat.undo++; @@ -3754,17 +3912,16 @@ void debugger_commands::execute_dasm(const std::vector ¶ms void debugger_commands::execute_trace(const std::vector ¶ms, bool trace_over) { - std::string action; + std::string_view action; bool detect_loops = true; bool logerror = false; - device_t *cpu; - const char *mode; std::string filename(params[0]); // replace macros strreplace(filename, "{game}", m_machine.basename()); // validate parameters + device_t *cpu; if (!validate_cpu_parameter(params.size() > 1 ? params[1] : std::string_view(), cpu)) return; if (params.size() > 2) @@ -3775,9 +3932,10 @@ void debugger_commands::execute_trace(const std::vector ¶m std::string flag; while (std::getline(stream, flag, '|')) { - if (util::streqlower(flag, "noloop")) + using namespace std::literals; + if (util::streqlower(flag, "noloop"sv)) detect_loops = false; - else if (util::streqlower(flag, "logerror")) + else if (util::streqlower(flag, "logerror"sv)) logerror = true; else { @@ -3790,19 +3948,22 @@ void debugger_commands::execute_trace(const std::vector ¶m return; // open the file - FILE *f = nullptr; - if (!util::streqlower(filename, "off")) + std::unique_ptr f; + using namespace std::literals; + if (!util::streqlower(filename, "off"sv)) { - mode = "w"; + std::ios_base::openmode mode = std::ios_base::out; // opening for append? if ((filename[0] == '>') && (filename[1] == '>')) { - mode = "a"; + mode |= std::ios_base::ate; filename = filename.substr(2); } + else + mode |= std::ios_base::trunc; - f = fopen(filename.c_str(), mode); + f = std::make_unique(filename.c_str(), mode); if (!f) { m_console.printf("Error opening file '%s'\n", params[0]); @@ -3811,7 +3972,7 @@ void debugger_commands::execute_trace(const std::vector ¶m } // do it - cpu->debug()->trace(f, trace_over, detect_loops, logerror, action.c_str()); + cpu->debug()->trace(std::move(f), trace_over, detect_loops, logerror, action); if (f) m_console.printf("Tracing CPU '%s' to file %s\n", cpu->tag(), filename); else diff --git a/src/emu/debug/debugcmd.h b/src/emu/debug/debugcmd.h index 9ede662511a..8c5e29fecae 100644 --- a/src/emu/debug/debugcmd.h +++ b/src/emu/debug/debugcmd.h @@ -148,6 +148,10 @@ private: void execute_rpclear(const std::vector ¶ms); void execute_rpdisenable(bool enable, const std::vector ¶ms); void execute_rplist(const std::vector ¶ms); + void execute_epset(const std::vector ¶ms); + void execute_epclear(const std::vector ¶ms); + void execute_epdisenable(bool enable, const std::vector ¶ms); + void execute_eplist(const std::vector ¶ms); void execute_statesave(const std::vector ¶ms); void execute_stateload(const std::vector ¶ms); void execute_rewind(const std::vector ¶ms); diff --git a/src/emu/debug/debugcpu.cpp b/src/emu/debug/debugcpu.cpp index 820d9e72688..aba79d74036 100644 --- a/src/emu/debug/debugcpu.cpp +++ b/src/emu/debug/debugcpu.cpp @@ -47,6 +47,7 @@ debugger_cpu::debugger_cpu(running_machine &machine) , m_bpindex(1) , m_wpindex(1) , m_rpindex(1) + , m_epindex(1) , m_wpdata(0) , m_wpaddr(0) , m_wpsize(0) @@ -424,7 +425,6 @@ device_debug::device_debug(device_t &device) , m_disasm(nullptr) , m_flags(0) , m_symtable(std::make_unique(device.machine(), &device.machine().debugger().cpu().global_symtable(), &device)) - , m_instrhook(nullptr) , m_stepaddr(0) , m_stepsleft(0) , m_delay_steps(0) @@ -438,7 +438,8 @@ device_debug::device_debug(device_t &device) , m_pc_history_index(0) , m_pc_history_valid(0) , m_bplist() - , m_rplist(std::make_unique>()) + , m_rplist() + , m_eplist() , m_triggered_breakpoint(nullptr) , m_triggered_watchpoint(nullptr) , m_trace(nullptr) @@ -549,6 +550,7 @@ device_debug::~device_debug() breakpoint_clear_all(); watchpoint_clear_all(); registerpoint_clear_all(); + exceptionpoint_clear_all(); } void device_debug::write_tracking(address_space &space, offs_t address, u64 data) @@ -672,10 +674,39 @@ void device_debug::exception_hook(int exception) if (matched) { m_device.machine().debugger().cpu().set_execution_stopped(); - m_device.machine().debugger().console().printf("Stopped on exception (CPU '%s', exception %d, PC=%X)\n", m_device.tag(), exception, m_state->pcbase()); + m_device.machine().debugger().console().printf("Stopped on exception (CPU '%s', exception %X, PC=%X)\n", m_device.tag(), exception, m_state->pcbase()); compute_debug_flags(); } } + + // see if any exception points match + if (!m_eplist.empty()) + { + auto epitp = m_eplist.equal_range(exception); + for (auto epit = epitp.first; epit != epitp.second; ++epit) + { + debug_exceptionpoint &ep = *epit->second; + if (ep.hit(exception)) + { + // halt in the debugger by default + debugger_cpu &debugcpu = m_device.machine().debugger().cpu(); + debugcpu.set_execution_stopped(); + + // if we hit, evaluate the action + if (!ep.m_action.empty()) + m_device.machine().debugger().console().execute_command(ep.m_action, false); + + // print a notification, unless the action made us go again + if (debugcpu.is_stopped()) + { + debugcpu.set_execution_stopped(); + m_device.machine().debugger().console().printf("Stopped at exception point %X (CPU '%s', PC=%X)\n", ep.m_index, m_device.tag(), exception, m_state->pcbase()); + compute_debug_flags(); + } + break; + } + } + } } @@ -744,10 +775,6 @@ void device_debug::instruction_hook(offs_t curpc) if (m_trace != nullptr) m_trace->update(curpc); - // per-instruction hook? - if (!debugcpu.is_stopped() && (m_flags & DEBUG_FLAG_HOOKED) != 0 && (*m_instrhook)(m_device, curpc)) - debugcpu.set_execution_stopped(); - // handle single stepping if (!debugcpu.is_stopped() && (m_flags & DEBUG_FLAG_STEPPING_ANY) != 0) { @@ -892,22 +919,6 @@ void device_debug::instruction_hook(offs_t curpc) } -//------------------------------------------------- -// set_instruction_hook - set a hook to be -// called on each instruction for a given device -//------------------------------------------------- - -void device_debug::set_instruction_hook(debug_instruction_hook_func hook) -{ - // set the hook and also the CPU's flag for fast knowledge of the hook - m_instrhook = hook; - if (hook != nullptr) - m_flags |= DEBUG_FLAG_HOOKED; - else - m_flags &= ~DEBUG_FLAG_HOOKED; -} - - //------------------------------------------------- // ignore - ignore/observe a given device //------------------------------------------------- @@ -1151,7 +1162,7 @@ const debug_breakpoint *device_debug::breakpoint_find(offs_t address) const // returning its index //------------------------------------------------- -int device_debug::breakpoint_set(offs_t address, const char *condition, const char *action) +int device_debug::breakpoint_set(offs_t address, const char *condition, std::string_view action) { // allocate a new one and hook it into our list u32 id = m_device.machine().debugger().cpu().get_breakpoint_index(); @@ -1238,7 +1249,7 @@ void device_debug::breakpoint_enable_all(bool enable) // returning its index //------------------------------------------------- -int device_debug::watchpoint_set(address_space &space, read_or_write type, offs_t address, offs_t length, const char *condition, const char *action) +int device_debug::watchpoint_set(address_space &space, read_or_write type, offs_t address, offs_t length, const char *condition, std::string_view action) { if (space.spacenum() >= int(m_wplist.size())) m_wplist.resize(space.spacenum()+1); @@ -1325,15 +1336,15 @@ void device_debug::watchpoint_enable_all(bool enable) // returning its index //------------------------------------------------- -int device_debug::registerpoint_set(const char *condition, const char *action) +int device_debug::registerpoint_set(const char *condition, std::string_view action) { // allocate a new one u32 id = m_device.machine().debugger().cpu().get_registerpoint_index(); - m_rplist->emplace_front(*m_symtable, id, condition, action); + m_rplist.emplace_front(*m_symtable, id, condition, action); // update the flags and return the index breakpoint_update_flags(); - return m_rplist->front().m_index; + return m_rplist.front().m_index; } @@ -1345,10 +1356,10 @@ int device_debug::registerpoint_set(const char *condition, const char *action) bool device_debug::registerpoint_clear(int index) { // scan the list to see if we own this registerpoint - for (auto brp = m_rplist->before_begin(); std::next(brp) != m_rplist->end(); ++brp) + for (auto brp = m_rplist.before_begin(); std::next(brp) != m_rplist.end(); ++brp) if (std::next(brp)->m_index == index) { - m_rplist->erase_after(brp); + m_rplist.erase_after(brp); breakpoint_update_flags(); return true; } @@ -1365,7 +1376,7 @@ bool device_debug::registerpoint_clear(int index) void device_debug::registerpoint_clear_all() { // clear the list - m_rplist->clear(); + m_rplist.clear(); breakpoint_update_flags(); } @@ -1378,7 +1389,7 @@ void device_debug::registerpoint_clear_all() bool device_debug::registerpoint_enable(int index, bool enable) { // scan the list to see if we own this conditionpoint - for (debug_registerpoint &rp : *m_rplist) + for (debug_registerpoint &rp : m_rplist) if (rp.m_index == index) { rp.m_enabled = enable; @@ -1399,11 +1410,96 @@ bool device_debug::registerpoint_enable(int index, bool enable) void device_debug::registerpoint_enable_all(bool enable) { // apply the enable to all registerpoints we own - for (debug_registerpoint &rp : *m_rplist) + for (debug_registerpoint &rp : m_rplist) registerpoint_enable(rp.index(), enable); } +//------------------------------------------------- +// exceptionpoint_set - set a new exception +// point, returning its index +//------------------------------------------------- + +int device_debug::exceptionpoint_set(int exception, const char *condition, std::string_view action) +{ + // allocate a new one and hook it into our list + u32 id = m_device.machine().debugger().cpu().get_exceptionpoint_index(); + m_eplist.emplace(exception, std::make_unique(this, *m_symtable, id, exception, condition, action)); + + // return the index + return id; +} + + +//------------------------------------------------- +// exceptionpoint_clear - clear an exception +// point by index, returning true if we found it +//------------------------------------------------- + +bool device_debug::exceptionpoint_clear(int index) +{ + // scan the list to see if we own this breakpoint + for (auto epit = m_eplist.begin(); epit != m_eplist.end(); ++epit) + if (epit->second->m_index == index) + { + m_eplist.erase(epit); + return true; + } + + // we don't own it, return false + return false; +} + + +//------------------------------------------------- +// exceptionpoint_clear_all - clear all exception +// points +//------------------------------------------------- + +void device_debug::exceptionpoint_clear_all() +{ + // clear the list + m_eplist.clear(); +} + + +//------------------------------------------------- +// exceptionpoint_enable - enable/disable an +// exception point by index, returning true if we +// found it +//------------------------------------------------- + +bool device_debug::exceptionpoint_enable(int index, bool enable) +{ + // scan the list to see if we own this exception point + for (auto &epp : m_eplist) + { + debug_exceptionpoint &ep = *epp.second; + if (ep.m_index == index) + { + ep.m_enabled = enable; + return true; + } + } + + // we don't own it, return false + return false; +} + + +//------------------------------------------------- +// exceptionpoint_enable_all - enable/disable all +// exception points +//------------------------------------------------- + +void device_debug::exceptionpoint_enable_all(bool enable) +{ + // apply the enable to all exception points we own + for (auto &epp : m_eplist) + exceptionpoint_enable(epp.second->index(), enable); +} + + //------------------------------------------------- // history_pc - return an entry from the PC // history @@ -1600,31 +1696,14 @@ u32 device_debug::compute_opcode_crc32(offs_t pc) const // trace - trace execution of a given device //------------------------------------------------- -void device_debug::trace(FILE *file, bool trace_over, bool detect_loops, bool logerror, const char *action) +void device_debug::trace(std::unique_ptr &&file, bool trace_over, bool detect_loops, bool logerror, std::string_view action) { // delete any existing tracers m_trace = nullptr; // if we have a new file, make a new tracer if (file != nullptr) - m_trace = std::make_unique(*this, *file, trace_over, detect_loops, logerror, action); -} - - -//------------------------------------------------- -// trace_printf - output data into the given -// device's tracefile, if tracing -//------------------------------------------------- - -void device_debug::trace_printf(const char *fmt, ...) -{ - if (m_trace != nullptr) - { - va_list va; - va_start(va, fmt); - m_trace->vprintf(fmt, va); - va_end(va); - } + m_trace = std::make_unique(*this, std::move(file), trace_over, detect_loops, logerror, action); } @@ -1652,7 +1731,7 @@ void device_debug::compute_debug_flags() // if we're tracking history, or we're hooked, or stepping, or stopping at a breakpoint // make sure we call the hook - if ((m_flags & (DEBUG_FLAG_HISTORY | DEBUG_FLAG_HOOKED | DEBUG_FLAG_STEPPING_ANY | DEBUG_FLAG_STOP_PC | DEBUG_FLAG_LIVE_BP)) != 0) + if ((m_flags & (DEBUG_FLAG_HISTORY | DEBUG_FLAG_STEPPING_ANY | DEBUG_FLAG_STOP_PC | DEBUG_FLAG_LIVE_BP)) != 0) machine.debug_flags |= DEBUG_FLAG_CALL_HOOK; // also call if we are tracing @@ -1753,7 +1832,7 @@ void device_debug::breakpoint_update_flags() if (!(m_flags & DEBUG_FLAG_LIVE_BP)) { // see if there are any enabled registerpoints - for (debug_registerpoint &rp : *m_rplist) + for (debug_registerpoint &rp : m_rplist) { if (rp.m_enabled) { @@ -1803,7 +1882,7 @@ void device_debug::breakpoint_check(offs_t pc) } // see if we have any matching registerpoints - for (debug_registerpoint &rp : *m_rplist) + for (debug_registerpoint &rp : m_rplist) { if (rp.hit()) { @@ -1836,10 +1915,10 @@ void device_debug::breakpoint_check(offs_t pc) // tracer - constructor //------------------------------------------------- -device_debug::tracer::tracer(device_debug &debug, FILE &file, bool trace_over, bool detect_loops, bool logerror, const char *action) +device_debug::tracer::tracer(device_debug &debug, std::unique_ptr &&file, bool trace_over, bool detect_loops, bool logerror, std::string_view action) : m_debug(debug) - , m_file(file) - , m_action((action != nullptr) ? action : "") + , m_file(std::move(file)) + , m_action(action) , m_detect_loops(detect_loops) , m_logerror(logerror) , m_loops(0) @@ -1858,7 +1937,7 @@ device_debug::tracer::tracer(device_debug &debug, FILE &file, bool trace_over, b device_debug::tracer::~tracer() { // make sure we close the file if we can - fclose(&m_file); + m_file.reset(); } @@ -1894,7 +1973,7 @@ void device_debug::tracer::update(offs_t pc) // if we just finished looping, indicate as much if (m_loops != 0) - fprintf(&m_file, "\n (loops for %d instructions)\n\n", m_loops); + util::stream_format(*m_file, "\n (loops for %d instructions)\n\n", m_loops); m_loops = 0; } @@ -1909,7 +1988,7 @@ void device_debug::tracer::update(offs_t pc) buffer.disassemble(pc, instruction, next_pc, size, dasmresult); // output the result - fprintf(&m_file, "%s: %s\n", buffer.pc_to_string(pc).c_str(), instruction.c_str()); + util::stream_format(*m_file, "%s: %s\n", buffer.pc_to_string(pc), instruction); // do we need to step the trace over this instruction? if (m_trace_over && (dasmresult & util::disasm_interface::SUPPORTED) != 0 && (dasmresult & util::disasm_interface::STEP_OVER) != 0) @@ -1927,7 +2006,7 @@ void device_debug::tracer::update(offs_t pc) // log this PC m_nextdex = (m_nextdex + 1) % TRACE_LOOPS; m_history[m_nextdex] = pc; - fflush(&m_file); + m_file->flush(); } @@ -1935,11 +2014,11 @@ void device_debug::tracer::update(offs_t pc) // vprintf - generic print to the trace file //------------------------------------------------- -void device_debug::tracer::vprintf(const char *format, va_list va) +void device_debug::tracer::vprintf(util::format_argument_pack const &args) { // pass through to the file - vfprintf(&m_file, format, va); - fflush(&m_file); + util::stream_format(*m_file, args); + m_file->flush(); } @@ -1950,7 +2029,7 @@ void device_debug::tracer::vprintf(const char *format, va_list va) void device_debug::tracer::flush() { - fflush(&m_file); + m_file->flush(); } diff --git a/src/emu/debug/debugcpu.h b/src/emu/debug/debugcpu.h index d9fc3f64eae..416581071a7 100644 --- a/src/emu/debug/debugcpu.h +++ b/src/emu/debug/debugcpu.h @@ -29,9 +29,6 @@ constexpr int COMMENT_VERSION = 1; // TYPE DEFINITIONS //************************************************************************** -typedef int (*debug_instruction_hook_func)(device_t &device, offs_t curpc); - - // ======================> device_debug // [TODO] This whole thing is terrible. @@ -59,9 +56,6 @@ public: void privilege_hook(); void instruction_hook(offs_t curpc); - // hooks into our operations - void set_instruction_hook(debug_instruction_hook_func hook); - // debugger focus void ignore(bool ignore = true); bool observing() const { return ((m_flags & DEBUG_FLAG_OBSERVING) != 0); } @@ -94,7 +88,7 @@ public: // breakpoints const auto &breakpoint_list() const { return m_bplist; } const debug_breakpoint *breakpoint_find(offs_t address) const; - int breakpoint_set(offs_t address, const char *condition = nullptr, const char *action = nullptr); + int breakpoint_set(offs_t address, const char *condition = nullptr, std::string_view action = {}); bool breakpoint_clear(int index); void breakpoint_clear_all(); bool breakpoint_enable(int index, bool enable = true); @@ -104,7 +98,7 @@ public: // watchpoints int watchpoint_space_count() const { return m_wplist.size(); } const std::vector> &watchpoint_vector(int spacenum) const { return m_wplist[spacenum]; } - int watchpoint_set(address_space &space, read_or_write type, offs_t address, offs_t length, const char *condition, const char *action); + int watchpoint_set(address_space &space, read_or_write type, offs_t address, offs_t length, const char *condition = nullptr, std::string_view action = {}); bool watchpoint_clear(int wpnum); void watchpoint_clear_all(); bool watchpoint_enable(int index, bool enable = true); @@ -113,12 +107,20 @@ public: debug_watchpoint *triggered_watchpoint() { debug_watchpoint *ret = m_triggered_watchpoint; m_triggered_watchpoint = nullptr; return ret; } // registerpoints - const std::forward_list ®isterpoint_list() const { return *m_rplist; } - int registerpoint_set(const char *condition, const char *action = nullptr); + const std::forward_list ®isterpoint_list() const { return m_rplist; } + int registerpoint_set(const char *condition, std::string_view action = {}); bool registerpoint_clear(int index); void registerpoint_clear_all(); bool registerpoint_enable(int index, bool enable = true); - void registerpoint_enable_all(bool enable = true ); + void registerpoint_enable_all(bool enable = true); + + // exception points + const auto &exceptionpoint_list() const { return m_eplist; } + int exceptionpoint_set(int exception, const char *condition = nullptr, std::string_view action = {}); + bool exceptionpoint_clear(int index); + void exceptionpoint_clear_all(); + bool exceptionpoint_enable(int index, bool enable = true); + void exceptionpoint_enable_all(bool enable = true); // comments void comment_add(offs_t address, const char *comment, rgb_t color); @@ -147,8 +149,12 @@ public: void track_mem_data_clear() { m_track_mem_set.clear(); } // tracing - void trace(FILE *file, bool trace_over, bool detect_loops, bool logerror, const char *action); - void trace_printf(const char *fmt, ...) ATTR_PRINTF(2,3); + void trace(std::unique_ptr &&file, bool trace_over, bool detect_loops, bool logerror, std::string_view action); + template void trace_printf(Format &&fmt, Params &&...args) + { + if (m_trace != nullptr) + m_trace->vprintf(util::make_format_argument_pack(std::forward(fmt), std::forward(args)...)); + } void trace_flush() { if (m_trace != nullptr) m_trace->flush(); } void reset_transient_flag() { m_flags &= ~DEBUG_FLAG_TRANSIENT; } @@ -182,7 +188,6 @@ private: // global state u32 m_flags; // debugging flags for this CPU std::unique_ptr m_symtable; // symbol table for expression evaluation - debug_instruction_hook_func m_instrhook; // per-instruction callback hook // stepping information offs_t m_stepaddr; // step target address for DEBUG_FLAG_STEPPING_OVER or DEBUG_FLAG_STEPPING_BRANCH @@ -208,7 +213,8 @@ private: // breakpoints and watchpoints std::multimap> m_bplist; // list of breakpoints std::vector>> m_wplist; // watchpoint lists for each address space - std::unique_ptr> m_rplist; // list of registerpoints + std::forward_list m_rplist; // list of registerpoints + std::multimap> m_eplist; // list of exception points debug_breakpoint * m_triggered_breakpoint; // latest breakpoint that was triggered debug_watchpoint * m_triggered_watchpoint; // latest watchpoint that was triggered @@ -217,11 +223,11 @@ private: class tracer { public: - tracer(device_debug &debug, FILE &file, bool trace_over, bool detect_loops, bool logerror, const char *action); + tracer(device_debug &debug, std::unique_ptr &&file, bool trace_over, bool detect_loops, bool logerror, std::string_view action); ~tracer(); void update(offs_t pc); - void vprintf(const char *format, va_list va); + void vprintf(util::format_argument_pack const &args); void flush(); bool logerror() const { return m_logerror; } @@ -229,7 +235,7 @@ private: static const int TRACE_LOOPS = 64; device_debug & m_debug; // reference to our owner - FILE & m_file; // tracing file for this CPU + std::unique_ptr m_file; // tracing file for this CPU std::string m_action; // action to perform during a trace offs_t m_history[TRACE_LOOPS]; // history of recent PCs bool m_detect_loops; // whether or not we should detect loops @@ -312,7 +318,6 @@ private: static constexpr u32 DEBUG_FLAG_HISTORY = 0x00000002; // tracking this CPU's history static constexpr u32 DEBUG_FLAG_TRACING = 0x00000004; // tracing this CPU static constexpr u32 DEBUG_FLAG_TRACING_OVER = 0x00000008; // tracing this CPU with step over behavior - static constexpr u32 DEBUG_FLAG_HOOKED = 0x00000010; // per-instruction callback hook static constexpr u32 DEBUG_FLAG_STEPPING = 0x00000020; // CPU is single stepping static constexpr u32 DEBUG_FLAG_STEPPING_OVER = 0x00000040; // CPU is stepping over a function static constexpr u32 DEBUG_FLAG_STEPPING_OUT = 0x00000080; // CPU is stepping out of a function @@ -384,6 +389,7 @@ public: u32 get_breakpoint_index() { return m_bpindex++; } u32 get_watchpoint_index() { return m_wpindex++; } u32 get_registerpoint_index() { return m_rpindex++; } + u32 get_exceptionpoint_index() { return m_epindex++; } // setters void set_break_cpu(device_t * breakcpu) { m_breakcpu = breakcpu; } @@ -426,6 +432,7 @@ private: u32 m_bpindex; u32 m_wpindex; u32 m_rpindex; + u32 m_epindex; u64 m_wpdata; u64 m_wpaddr; diff --git a/src/emu/debug/debughlp.cpp b/src/emu/debug/debughlp.cpp index a62704c5472..85de3984020 100644 --- a/src/emu/debug/debughlp.cpp +++ b/src/emu/debug/debughlp.cpp @@ -46,6 +46,7 @@ const help_item f_static_help_list[] = " Breakpoints\n" " Watchpoints\n" " Registerpoints\n" + " Exception Points\n" " Expressions\n" " Comments\n" " Cheats\n" @@ -190,6 +191,18 @@ const help_item f_static_help_list[] = " rpenable [[,...]] -- enables given registerpoints or all if no specified\n" " rplist [] -- lists all the registerpoints\n" }, + { + "exceptionpoints", + "\n" + "Exception Point Commands\n" + "Type help for further details on each command\n" + "\n" + " ep[set] [,[,]] -- sets exception point on \n" + " epclear [] -- clears a given exception point or all if no specified\n" + " epdisable [] -- disabled a given exception point or all if no specified\n" + " epenable [] -- enables a given exception point or all if no specified\n" + " eplist -- lists all the registerpoints\n" + }, { "expressions", "\n" @@ -1554,6 +1567,92 @@ const help_item f_static_help_list[] = "The rplist command lists all the current registerpoints, along with their index and any " "actions attached to them.\n" }, + { + "epset", + "\n" + " ep[set] [,[,]]\n" + "\n" + "Sets a new exception point for exceptions of type on the currently visible CPU. " + "The optional parameter lets you specify an expression that will be evaluated " + "each time the exception point is hit. If the result of the expression is true (non-zero), " + "the exception point will actually halt execution at the start of the exception handler; " + "otherwise, execution will continue with no notification. The optional parameter " + "provides a command that is executed whenever the exception point is hit and the " + " is true. Note that you may need to embed the action within braces { } in order " + "to prevent commas and semicolons from being interpreted as applying to the epset command " + "itself.\n" + "\n" + "The numbering of exceptions depends upon the CPU type. Causes of exceptions may include " + "internally or externally vectored interrupts, errors occurring within instructions and " + "system calls.\n" + "\n" + "Each exception point that is set is assigned an index which can be used in other " + "exception point commands to reference this exception point.\n" + "\n" + "Examples:\n" + "\n" + "ep 2\n" + " Set an exception that will halt execution whenever the visible CPU raises exception " + "number 2.\n" + }, + { + "epclear", + "\n" + " epclear [[,...]]\n" + "\n" + "The epclear command clears exception points. If is specified, only the requested " + "exception points are cleared, otherwise all exception points are cleared.\n" + "\n" + "Examples:\n" + "\n" + "epclear 3\n" + " Clear exception point index 3.\n" + "\n" + "epclear\n" + " Clear all exception points.\n" + }, + { + "epdisable", + "\n" + " epdisable [[,...]]\n" + "\n" + "The epdisable command disables exception points. If is specified, only the requested " + "exception points are disabled, otherwise all exception points are disabled. Note that " + "disabling an exception point does not delete it, it just temporarily marks the exception " + "point as inactive.\n" + "\n" + "Examples:\n" + "\n" + "epdisable 3\n" + " Disable exception point index 3.\n" + "\n" + "epdisable\n" + " Disable all exception points.\n" + }, + { + "epenable", + "\n" + " epenable [[,...]]\n" + "\n" + "The epenable command enables exception points. If is specified, only the " + "requested exception points are enabled, otherwise all exception points are enabled.\n" + "\n" + "Examples:\n" + "\n" + "epenable 3\n" + " Enable exception point index 3.\n" + "\n" + "epenable\n" + " Enable all exception points.\n" + }, + { + "eplist", + "\n" + " eplist\n" + "\n" + "The eplist command lists all the current exception points, along with their index and " + "any conditions or actions attached to them.\n" + }, { "map", "\n" diff --git a/src/emu/debug/dvbpoints.cpp b/src/emu/debug/dvbpoints.cpp index b42b86a0e90..d7be62c1eaa 100644 --- a/src/emu/debug/dvbpoints.cpp +++ b/src/emu/debug/dvbpoints.cpp @@ -71,7 +71,7 @@ static bool cConditionDescending(const debug_breakpoint *a, const debug_breakpoi static bool cActionAscending(const debug_breakpoint *a, const debug_breakpoint *b) { - return strcmp(a->action(), b->action()) < 0; + return a->action() < b->action(); } static bool cActionDescending(const debug_breakpoint *a, const debug_breakpoint *b) diff --git a/src/emu/debug/dvrpoints.cpp b/src/emu/debug/dvrpoints.cpp index 3ecadaec8e5..7295a1b2170 100644 --- a/src/emu/debug/dvrpoints.cpp +++ b/src/emu/debug/dvrpoints.cpp @@ -62,7 +62,7 @@ bool cConditionDescending(std::pair con bool cActionAscending(std::pair const &a, std::pair const &b) { - return strcmp(a.second->action(), b.second->action()) < 0; + return a.second->action() < b.second->action(); } bool cActionDescending(std::pair const &a, std::pair const &b) diff --git a/src/emu/debug/points.cpp b/src/emu/debug/points.cpp index a19f0ab5619..961488eebb2 100644 --- a/src/emu/debug/points.cpp +++ b/src/emu/debug/points.cpp @@ -28,13 +28,13 @@ debug_breakpoint::debug_breakpoint( int index, offs_t address, const char *condition, - const char *action) : + std::string_view action) : m_debugInterface(debugInterface), m_index(index), m_enabled(true), m_address(address), m_condition(symbols, condition ? condition : "1"), - m_action(action ? action : "") + m_action(action) { } @@ -88,7 +88,7 @@ debug_watchpoint::debug_watchpoint( offs_t address, offs_t length, const char *condition, - const char *action) : + std::string_view action) : m_debugInterface(debugInterface), m_phr(nullptr), m_phw(nullptr), @@ -99,7 +99,7 @@ debug_watchpoint::debug_watchpoint( m_address(address & space.addrmask()), m_length(length), m_condition(symbols, condition ? condition : "1"), - m_action(action ? action : ""), + m_action(action), m_installing(false) { std::fill(std::begin(m_start_address), std::end(m_start_address), 0); @@ -431,11 +431,11 @@ void debug_watchpoint::triggered(read_or_write type, offs_t address, u64 data, u // debug_registerpoint - constructor //------------------------------------------------- -debug_registerpoint::debug_registerpoint(symbol_table &symbols, int index, const char *condition, const char *action) +debug_registerpoint::debug_registerpoint(symbol_table &symbols, int index, const char *condition, std::string_view action) : m_index(index), m_enabled(true), m_condition(symbols, (condition != nullptr) ? condition : "1"), - m_action((action != nullptr) ? action : "") + m_action(action) { } @@ -465,3 +465,59 @@ bool debug_registerpoint::hit() return true; } + + +//************************************************************************** +// DEBUG EXCEPTION POINT +//************************************************************************** + +//------------------------------------------------- +// debug_exceptionpoint - constructor +//------------------------------------------------- + +debug_exceptionpoint::debug_exceptionpoint( + device_debug *debugInterface, + symbol_table &symbols, + int index, + int type, + const char *condition, + std::string_view action) + : m_debugInterface(debugInterface), + m_index(index), + m_enabled(true), + m_type(type), + m_condition(symbols, (condition != nullptr) ? condition : "1"), + m_action(action) +{ +} + + +//------------------------------------------------- +// hit - detect a hit +//------------------------------------------------- + +bool debug_exceptionpoint::hit(int exception) +{ + // don't hit if disabled + if (!m_enabled) + return false; + + // must match our type + if (m_type != exception) + return false; + + // must satisfy the condition + if (!m_condition.is_empty()) + { + try + { + return (m_condition.execute() != 0); + } + catch (expression_error &) + { + return false; + } + } + + return true; +} diff --git a/src/emu/debug/points.h b/src/emu/debug/points.h index 62ad953626c..42abd46398f 100644 --- a/src/emu/debug/points.h +++ b/src/emu/debug/points.h @@ -36,7 +36,7 @@ public: int index, offs_t address, const char *condition = nullptr, - const char *action = nullptr); + std::string_view action = {}); // getters const device_debug *debugInterface() const { return m_debugInterface; } @@ -44,7 +44,7 @@ public: bool enabled() const { return m_enabled; } offs_t address() const { return m_address; } const char *condition() const { return m_condition.original_string(); } - const char *action() const { return m_action.c_str(); } + const std::string &action() const { return m_action; } // setters void setEnabled(bool value) { m_enabled = value; } // FIXME: need to update breakpoint flags but it's a private method @@ -77,7 +77,7 @@ public: offs_t address, offs_t length, const char *condition = nullptr, - const char *action = nullptr); + std::string_view action = {}); ~debug_watchpoint(); // getters @@ -128,13 +128,13 @@ class debug_registerpoint public: // construction/destruction - debug_registerpoint(symbol_table &symbols, int index, const char *condition, const char *action = nullptr); + debug_registerpoint(symbol_table &symbols, int index, const char *condition, std::string_view action = {}); // getters int index() const { return m_index; } bool enabled() const { return m_enabled; } const char *condition() const { return m_condition.original_string(); } - const char *action() const { return m_action.c_str(); } + const std::string &action() const { return m_action; } private: // internals @@ -146,4 +146,42 @@ private: std::string m_action; // action }; +// ======================> debug_exceptionpoint + +class debug_exceptionpoint +{ + friend class device_debug; + +public: + // construction/destruction + debug_exceptionpoint( + device_debug* debugInterface, + symbol_table &symbols, + int index, + int type, + const char *condition = nullptr, + std::string_view action = {}); + + // getters + const device_debug *debugInterface() const { return m_debugInterface; } + int index() const { return m_index; } + bool enabled() const { return m_enabled; } + int type() const { return m_type; } + const char *condition() const { return m_condition.original_string(); } + const std::string &action() const { return m_action; } + + // setters + void setEnabled(bool value) { m_enabled = value; } + +private: + // internals + bool hit(int exception); + const device_debug * m_debugInterface; // the interface we were created from + int m_index; // user reported index + bool m_enabled; // enabled? + int m_type; // exception type + parsed_expression m_condition; // condition + std::string m_action; // action +}; + #endif // MAME_EMU_DEBUG_POINTS_H diff --git a/src/emu/emufwd.h b/src/emu/emufwd.h index 48146615bce..323a0f14898 100644 --- a/src/emu/emufwd.h +++ b/src/emu/emufwd.h @@ -99,6 +99,7 @@ class symbol_table; class debug_breakpoint; class debug_watchpoint; class debug_registerpoint; +class debug_exceptionpoint; // declared in debugger.h class debugger_manager; diff --git a/src/mame/rm/rmnimbus.h b/src/mame/rm/rmnimbus.h index 0fe2e2d83da..fd8ed6909bf 100644 --- a/src/mame/rm/rmnimbus.h +++ b/src/mame/rm/rmnimbus.h @@ -87,13 +87,6 @@ public: void nimbus(machine_config &config); - uint32_t m_debug_machine = 0; - uint32_t m_debug_trap = 0; - - void decode_subbios(device_t *device, offs_t pc); - void decode_subbios_return(device_t *device, offs_t pc); - void decode_dos21(device_t *device, offs_t pc); - private: required_device m_maincpu; required_device m_iocpu; diff --git a/src/mame/rm/rmnimbus_m.cpp b/src/mame/rm/rmnimbus_m.cpp index 39b9ea304f2..cc1bde464de 100644 --- a/src/mame/rm/rmnimbus_m.cpp +++ b/src/mame/rm/rmnimbus_m.cpp @@ -63,10 +63,6 @@ chdman createhd -o ST125N.chd -chs 41921,1,1 -ss 512 #include #include "rmnimbus.h" -#include "debugger.h" -#include "debug/debugcmd.h" -#include "debug/debugcon.h" -#include "debug/debugcpu.h" #include "imagedev/floppy.h" @@ -136,52 +132,6 @@ chdman createhd -o ST125N.chd -chs 41921,1,1 -ss 512 #define LOG_IOU 0 #define LOG_RAM 0 -/* Debugging */ - -#define DEBUG_SET(flags) ((m_debug_machine & (flags))==(flags)) -#define DEBUG_SET_STATE(flags) ((state->m_debug_machine & (flags))==(flags)) - -#define DEBUG_NONE 0x0000000 -#define DECODE_BIOS 0x0000002 -#define DECODE_BIOS_RAW 0x0000004 -#define DECODE_DOS21 0x0000008 - -/* Nimbus sub-bios structures for debugging */ - -struct t_area_params -{ - uint16_t ofs_brush; - uint16_t seg_brush; - uint16_t ofs_data; - uint16_t seg_data; - uint16_t count; -}; - -struct t_plot_string_params -{ - uint16_t ofs_font; - uint16_t seg_font; - uint16_t ofs_data; - uint16_t seg_data; - uint16_t x; - uint16_t y; - uint16_t length; -}; - -struct t_nimbus_brush -{ - uint16_t style; - uint16_t style_index; - uint16_t colour1; - uint16_t colour2; - uint16_t transparency; - uint16_t boundary_spec; - uint16_t boundary_colour; - uint16_t save_colour; -}; - - -static int instruction_hook(device_t &device, offs_t curpc); void rmnimbus_state::external_int(uint8_t vector, bool state) { @@ -218,648 +168,11 @@ void rmnimbus_state::machine_start() { m_nimbus_mouse.m_mouse_timer = timer_alloc(FUNC(rmnimbus_state::do_mouse), this); - /* setup debug commands */ - if (machine().debug_flags & DEBUG_FLAG_ENABLED) - { - using namespace std::placeholders; - machine().debugger().console().register_command("nimbus_debug", CMDFLAG_NONE, 0, 1, std::bind(&rmnimbus_state::debug_command, this, _1)); - - /* set up the instruction hook */ - m_maincpu->debug()->set_instruction_hook(instruction_hook); - } - - m_debug_machine=DEBUG_NONE; - m_debug_trap=0; m_voice_enabled=false; m_fdc->dden_w(0); //m_fdc->overide_delays(64,m_fdc->get_cmd_delay()); } -void rmnimbus_state::debug_command(const std::vector ¶ms) -{ - if (params.size() > 0) - { - uint64_t temp; - if (!machine().debugger().commands().validate_number_parameter(params[0], temp)) - return; - m_debug_machine = temp; - } - else - { - machine().debugger().console().printf("Error usage : nimbus_debug \n"); - machine().debugger().console().printf("Current debuglevel=%02X\n", m_debug_machine); - } -} - -/*----------------------------------------------- - instruction_hook - per-instruction hook ------------------------------------------------*/ - -static int instruction_hook(device_t &device, offs_t curpc) -{ - rmnimbus_state *state = device.machine().driver_data(); - address_space &space = device.memory().space(AS_PROGRAM); - uint8_t *addr_ptr; - uint8_t first; - - addr_ptr = (uint8_t*)space.get_read_ptr(curpc); - - first = (curpc & 0x01) ? 1 : 0; - - if(DEBUG_SET_STATE(DECODE_BIOS) && (curpc == state->m_debug_trap) && (0 != state->m_debug_trap)) - { - state->decode_subbios_return(&device,curpc); - } - - if ((addr_ptr !=nullptr) && (addr_ptr[first]==0xCD)) - { - if(DEBUG_SET_STATE(DECODE_BIOS) && (addr_ptr[first+1]==0xF0)) - state->decode_subbios(&device,curpc); - - if(DEBUG_SET_STATE(DECODE_DOS21) && (addr_ptr[first+1]==0x21)) - state->decode_dos21(&device,curpc); - } - - return 0; -} - -void rmnimbus_state::decode_subbios_return(device_t *device, offs_t pc) -{ - uint16_t ax = m_maincpu->state_int(I8086_AX); - uint16_t ds = m_maincpu->state_int(I8086_DS); - uint16_t si = m_maincpu->state_int(I8086_SI); - - if(!DEBUG_SET(DECODE_BIOS_RAW)) - { - logerror("at %05X sub-bios return code : %04X\n",pc,ax); - decode_dssi_generic(ds,si); - logerror("=======================================================================\n"); - } - else - logerror("%05X :: %04X\n",pc,ax); - - m_debug_trap=0; -} - -#define set_type(type_name) sprintf(type_str,type_name) -#define set_drv(drv_name) sprintf(drv_str,drv_name) -#define set_func(func_name) sprintf(func_str,func_name) - -void rmnimbus_state::decode_subbios(device_t *device,offs_t pc) -{ - char type_str[80]; - char drv_str[80]; - char func_str[80]; - - void (rmnimbus_state::*dump_dssi)(uint16_t, uint16_t) = &rmnimbus_state::decode_dssi_none; - - uint16_t ax = m_maincpu->state_int(I8086_AX); - uint16_t bx = m_maincpu->state_int(I8086_BX); - uint16_t cx = m_maincpu->state_int(I8086_CX); - uint16_t ds = m_maincpu->state_int(I8086_DS); - uint16_t si = m_maincpu->state_int(I8086_SI); - - // Set the address to trap after the sub-bios call. - m_debug_trap=pc+2; - - // *** TEMP Don't show f_enquire_display_line calls ! - if((cx==6) && (ax==43)) - return; - // *** END TEMP - - if(!DEBUG_SET(DECODE_BIOS_RAW)) - { - logerror("=======================================================================\n"); - logerror("Sub-bios call at %08X, AX=%04X, BX=%04X, CX=%04X, DS:SI=%04X:%04X\n",pc,ax,bx,cx,ds,si); - } - - set_type("invalid"); - set_drv("invalid"); - set_func("invalid"); - - switch (cx) - { - case 0 : - { - set_type("t_mummu"); - set_drv("d_mummu"); - - switch (ax) - { - case 0 : set_func("f_get_version_number"); break; - case 1 : set_func("f_add_type_code"); break; - case 2 : set_func("f_del_typc_code"); break; - case 3 : set_func("f_get_TCB"); break; - case 4 : set_func("f_add_driver_code"); break; - case 5 : set_func("f_del_driver_code"); break; - case 6 : set_func("f_get_DCB"); break; - case 7 : set_func("f_get_copyright"); break; - } - }; break; - - case 1 : - { - set_type("t_character"); - set_drv("d_printer"); - - switch(ax) - { - case 0 : set_func("f_get_version_number"); break; - case 1 : set_func("f_get_output_status"); break; - case 2 : set_func("f_output_character"); break; - case 3 : set_func("f_get_input_status"); break; - case 4 : set_func("f_get_and_remove"); break; - case 5 : set_func("f_get_no_remove"); break; - case 6 : set_func("f_get_last_and_remove"); break; - case 7 : set_func("f_get_last_no_remove"); break; - case 8 : set_func("f_set_IO_parameters"); break; - } - }; break; - - case 2 : - { - set_type("t_disk"); - - switch(bx) - { - case 0 : set_drv("d_floppy"); break; - case 1 : set_drv("d_winchester"); break; - case 2 : set_drv("d_tape"); break; - case 3 : set_drv("d_rompack"); break; - case 4 : set_drv("d_eeprom"); break; - } - - dump_dssi = &rmnimbus_state::decode_dssi_generic; - - switch(ax) - { - case 0 : set_func("f_get_version_number"); break; - case 1 : set_func("f_initialise_unit"); break; - case 2 : set_func("f_pseudo_init_unit"); break; - case 3 : set_func("f_get_device_status"); break; - case 4 : set_func("f_read_n_sectors"); dump_dssi = &rmnimbus_state::decode_dssi_f_rw_sectors; break; - case 5 : set_func("f_write_n_sectors"); dump_dssi = &rmnimbus_state::decode_dssi_f_rw_sectors; break; - case 6 : set_func("f_verify_n_sectors"); dump_dssi = &rmnimbus_state::decode_dssi_f_rw_sectors; break; - case 7 : set_func("f_media_check"); break; - case 8 : set_func("f_recalibrate"); break; - case 9 : set_func("f_motors_off"); break; - } - - }; break; - - case 3 : - { - set_type("t_piconet"); - set_drv("d_piconet"); - - switch(ax) - { - case 0 : set_func("f_get_version_number"); break; - case 1 : set_func("f_get_slave_status"); break; - case 2 : set_func("f_get_slave_map"); break; - case 3 : set_func("f_change_slave_addr"); break; - case 4 : set_func("f_read_slave_control"); break; - case 5 : set_func("f_write_slave_control"); break; - case 6 : set_func("f_send_data_byte"); break; - case 7 : set_func("f_request_data_byte"); break; - case 8 : set_func("f_send_data_block"); break; - case 9 : set_func("f_request_data_block"); break; - case 10 : set_func("f_reset_slave"); break; - - } - }; break; - - case 4 : - { - set_type("t_tick"); - set_drv("d_tick"); - - switch(ax) - { - case 0 : set_func("f_get_version_number"); break; - case 1 : set_func("f_ticks_per_second"); break; - case 2 : set_func("f_link_tick_routine"); break; - case 3 : set_func("f_unlink_tick_routine"); break; - } - }; break; - - case 5 : - { - set_type("t_graphics_input"); - - switch(bx) - { - case 0 : set_drv("d_mouse"); break; - case 1 : set_drv("d_joystick_1"); break; - case 2 : set_drv("d_joystick_2"); break; - } - - - switch(ax) - { - case 0 : set_func("f_get_version_number"); break; - case 1 : set_func("f_graphics_input_cold_start"); break; - case 2 : set_func("f_graphics_input_device_off"); break; - case 3 : set_func("f_return_button_status"); break; - case 4 : set_func("f_return_switch_and_button_stat"); break; - case 5 : set_func("f_start_tracking"); break; - case 6 : set_func("f_stop_tracking"); break; - case 7 : set_func("f_enquire_position"); break; - case 8 : set_func("f_set_position"); break; - - case 10 : set_func("f_return_button_press_info"); break; - case 11 : set_func("f_return_button_release_info"); break; - case 12 : set_func("f_set_gain/f_set_squeaks_per_pixel_ratio"); break; - case 13 : set_func("f_enquire_graphics_in_misc_data"); break; - } - }; break; - - case 6 : - { - set_type("t_graphics_output"); - set_drv("d_ngc_screen"); - - switch(ax) - { - case 0 : set_func("f_get_version_number"); break; - case 1 : set_func("f_graphics_output_cold_start"); break; - case 2 : set_func("f_graphics_output_warm_start"); break; - case 3 : set_func("f_graphics_output_off"); break; - case 4 : set_func("f_reinit_graphics_output"); break; - case 5 : set_func("f_polymarker"); break; - case 6 : set_func("f_polyline"); dump_dssi = &rmnimbus_state::decode_dssi_f_fill_area; break; - case 7 : set_func("f_fill_area"); dump_dssi = &rmnimbus_state::decode_dssi_f_fill_area; break; - case 8 : set_func("f_flood_fill_area"); break; - case 9 : set_func("f_plot_character_string"); dump_dssi = &rmnimbus_state::decode_dssi_f_plot_character_string; break; - case 10 : set_func("f_define_graphics_clipping_area"); break; - case 11 : set_func("f_enquire_clipping_area_limits"); break; - case 12 : set_func("f_select_graphics_clipping_area"); break; - case 13 : set_func("f_enq_selctd_graphics_clip_area"); break; - case 14 : set_func("f_set_clt_element"); break; - case 15 : set_func("f_enquire_clt_element"); break; - case 16 : set_func("f_set_new_clt"); dump_dssi = &rmnimbus_state::decode_dssi_f_set_new_clt; break; - case 17 : set_func("f_enquire_clt_contents"); break; - case 18 : set_func("f_define_dithering_pattern"); break; - case 19 : set_func("f_enquire_dithering_pattern"); break; - case 20 : set_func("f_draw_sprite"); break; - case 21 : set_func("f_move_sprite"); break; - case 22 : set_func("f_erase_sprite"); break; - case 23 : set_func("f_read_pixel"); break; - case 24 : set_func("f_read_to_limit"); break; - case 25 : set_func("f_read_area_pixel"); break; - case 26 : set_func("f_write_area_pixel"); break; - case 27 : set_func("f_copy_area_pixel"); break; - - case 29 : set_func("f_read_area_word"); break; - case 30 : set_func("f_write_area_word"); break; - case 31 : set_func("f_copy_area_word"); break; - case 32 : set_func("f_swap_area_word"); break; - case 33 : set_func("f_set_border_colour"); break; - case 34 : set_func("f_enquire_border_colour"); break; - case 35 : set_func("f_enquire_miscellaneous_data"); break; - case 36 : set_func("f_circle"); break; - - case 38 : set_func("f_arc_of_ellipse"); break; - case 39 : set_func("f_isin"); break; - case 40 : set_func("f_icos"); break; - case 41 : set_func("f_define_hatching_pattern"); break; - case 42 : set_func("f_enquire_hatching_pattern"); break; - case 43 : set_func("f_enquire_display_line"); break; - case 44 : set_func("f_plonk_logo"); break; - } - }; break; - - case 7 : - { - set_type("t_zend"); - switch(ax) - { - case 0 : set_func("f_get_version_number"); break; - } - }; break; - - case 8 : - { - set_type("t_zep"); - switch(ax) - { - case 0 : set_func("f_get_version_number"); break; - } - }; break; - - case 9 : - { - set_type("t_raw_console"); - - switch(bx) - { - case 0 : - { - set_drv("d_screen"); - - switch(ax) - { - case 0 : set_func("f_get_version_number"); break; - case 1 : set_func("f_plonk_char"); dump_dssi = &rmnimbus_state::decode_dssi_f_plonk_char; break; - case 2 : set_func("f_plonk_cursor"); break; - case 3 : set_func("f_kill_cursor"); break; - case 4 : set_func("f_scroll"); break; - case 5 : set_func("f_width"); dump_dssi = &rmnimbus_state::decode_dssi_generic; break; - case 6 : set_func("f_get_char_set"); break; - case 7 : set_func("f_set_char_set"); break; - case 8 : set_func("f_reset_char_set"); break; - case 9 : set_func("f_set_plonk_parameters"); break; - case 10 : set_func("f_set_cursor_flash_rate"); break; - } - }; break; - - case 1 : - { - set_drv("d_keyboard"); - - switch(ax) - { - case 0 : set_func("f_get_version_number"); break; - case 1 : set_func("f_init_keyboard"); break; - case 2 : set_func("f_get_last_key_code"); break; - case 3 : set_func("f_get_bitmap"); break; - } - }; break; - } - }; break; - - case 10 : - { - set_type("t_acoustics"); - - switch(bx) - { - case 0 : - { - set_drv("d_sound"); - - switch(ax) - { - case 0 : set_func("f_get_version_number"); break; - case 1 : set_func("f_sound_enable"); break; - case 2 : set_func("f_play_note"); break; - case 3 : set_func("f_get_queue_status"); break; - } - }; break; - - case 1 : - { - set_drv("d_voice"); - - switch(ax) - { - case 0 : set_func("f_get_version_number"); break; - case 1 : set_func("f_talk"); break; - case 2 : set_func("f_wait_and_talk"); break; - case 3 : set_func("f_test_talking"); break; - } - } - } - }; break; - - case 11 : - { - set_type("t_hard_sums"); - switch(ax) - { - case 0 : set_func("f_get_version_number"); break; - } - }; break; - } - - if(DEBUG_SET(DECODE_BIOS_RAW)) - { - (this->*dump_dssi)(ds, si); - } - else - { - logerror("Type=%s, Driver=%s, Function=%s\n",type_str,drv_str,func_str); - - (this->*dump_dssi)(ds, si); - logerror("=======================================================================\n"); - } -} - -static inline void *get_regpair_ptr(address_space &space, uint16_t segment, uint16_t offset) -{ - int addr; - - addr=((segment<<4)+offset); - - return space.get_read_ptr(addr); -} - -void rmnimbus_state::decode_dssi_none(uint16_t ds, uint16_t si) -{ -} - -void rmnimbus_state::decode_dssi_generic(uint16_t ds, uint16_t si) -{ - address_space &space = m_maincpu->space(AS_PROGRAM); - uint16_t *params; - int count; - - if(DEBUG_SET(DECODE_BIOS_RAW)) - return; - - params=(uint16_t *)get_regpair_ptr(space,ds,si); - - for(count=0; count<10; count++) - logerror("%04X ",params[count]); - - logerror("\n"); -} - - -void rmnimbus_state::decode_dssi_f_fill_area(uint16_t ds, uint16_t si) -{ - address_space &space = m_maincpu->space(AS_PROGRAM); - - uint16_t *addr_ptr; - t_area_params *area_params; - t_nimbus_brush *brush; - int cocount; - - area_params = (t_area_params *)get_regpair_ptr(space,ds,si); - - if (!DEBUG_SET(DECODE_BIOS_RAW)) - OUTPUT_SEGOFS("SegBrush:OfsBrush",area_params->seg_brush,area_params->ofs_brush); - - brush=(t_nimbus_brush *)space.get_read_ptr(LINEAR_ADDR(area_params->seg_brush,area_params->ofs_brush)); - - if(DEBUG_SET(DECODE_BIOS_RAW)) - { - logerror("\tdw\t%04X, %04X, %04X, %04X, %04X, %04X, %04X, %04X, %04X, ", - brush->style,brush->style_index,brush->colour1,brush->colour2, - brush->transparency,brush->boundary_spec,brush->boundary_colour,brush->save_colour, - area_params->count); - } - else - { - logerror("Brush params\n"); - logerror("Style=%04X, StyleIndex=%04X\n",brush->style,brush->style_index); - logerror("Colour1=%04X, Colour2=%04X\n",brush->colour1,brush->colour2); - logerror("transparency=%04X, boundary_spec=%04X\n",brush->transparency,brush->boundary_spec); - logerror("boundary colour=%04X, save colour=%04X\n",brush->boundary_colour,brush->save_colour); - - - OUTPUT_SEGOFS("SegData:OfsData",area_params->seg_data,area_params->ofs_data); - } - - addr_ptr = (uint16_t *)space.get_read_ptr(LINEAR_ADDR(area_params->seg_data,area_params->ofs_data)); - for(cocount=0; cocount < area_params->count; cocount++) - { - if(DEBUG_SET(DECODE_BIOS_RAW)) - { - if(cocount!=(area_params->count-1)) - logerror("%04X, %04X, ",addr_ptr[cocount*2],addr_ptr[(cocount*2)+1]); - else - logerror("%04X, %04X ",addr_ptr[cocount*2],addr_ptr[(cocount*2)+1]); - } - else - logerror("x=%d y=%d\n",addr_ptr[cocount*2],addr_ptr[(cocount*2)+1]); - } - - if(DEBUG_SET(DECODE_BIOS_RAW)) - logerror("\n"); -} - -void rmnimbus_state::decode_dssi_f_plot_character_string(uint16_t ds, uint16_t si) -{ - address_space &space = m_maincpu->space(AS_PROGRAM); - - uint8_t *char_ptr; - t_plot_string_params *plot_string_params; - int charno; - - if(DEBUG_SET(DECODE_BIOS_RAW)) - return; - - plot_string_params=(t_plot_string_params *)get_regpair_ptr(space,ds,si); - - OUTPUT_SEGOFS("SegFont:OfsFont",plot_string_params->seg_font,plot_string_params->ofs_font); - OUTPUT_SEGOFS("SegData:OfsData",plot_string_params->seg_data,plot_string_params->ofs_data); - - logerror("x=%d, y=%d, length=%d\n",plot_string_params->x,plot_string_params->y,plot_string_params->length); - - char_ptr=(uint8_t*)space.get_read_ptr(LINEAR_ADDR(plot_string_params->seg_data,plot_string_params->ofs_data)); - - if (plot_string_params->length==0xFFFF) - logerror("%s",char_ptr); - else - for(charno=0;charnolength;charno++) - logerror("%c",char_ptr[charno]); - - logerror("\n"); -} - -void rmnimbus_state::decode_dssi_f_set_new_clt(uint16_t ds, uint16_t si) -{ - address_space &space = m_maincpu->space(AS_PROGRAM); - uint16_t *new_colours; - int colour; - new_colours=(uint16_t *)get_regpair_ptr(space,ds,si); - - if(DEBUG_SET(DECODE_BIOS_RAW)) - return; - - OUTPUT_SEGOFS("SegColours:OfsColours",ds,si); - - for(colour=0;colour<16;colour++) - logerror("colour #%02X=%04X\n",colour,new_colours[colour]); - -} - -void rmnimbus_state::decode_dssi_f_plonk_char(uint16_t ds, uint16_t si) -{ - address_space &space = m_maincpu->space(AS_PROGRAM); - uint16_t *params; - params=(uint16_t *)get_regpair_ptr(space,ds,si); - - if(DEBUG_SET(DECODE_BIOS_RAW)) - return; - - OUTPUT_SEGOFS("SegParams:OfsParams",ds,si); - - logerror("plonked_char=%c\n",params[0]); -} - -void rmnimbus_state::decode_dssi_f_rw_sectors(uint16_t ds, uint16_t si) -{ - address_space &space = m_maincpu->space(AS_PROGRAM); - uint16_t *params; - int param_no; - - if(DEBUG_SET(DECODE_BIOS_RAW)) - return; - - params=(uint16_t *)get_regpair_ptr(space,ds,si); - - logerror("unitno=%04X, count=%02X, first_sector=%08X buffer=%04X:%04X (%05X)\n", - params[0], - params[1], - ((params[3] * 65536)+params[2]), - params[5],params[4], - ((params[5]*16)+params[4]) - ); - - for(param_no=0;param_no<16;param_no++) - logerror("%04X ",params[param_no]); - - logerror("\n"); -} - -void rmnimbus_state::decode_dos21(device_t *device,offs_t pc) -{ - address_space &space = m_maincpu->space(AS_PROGRAM); - //uint16_t *params; - char *path; - - uint16_t ax = m_maincpu->state_int(I8086_AX); - uint16_t bx = m_maincpu->state_int(I8086_BX); - uint16_t cx = m_maincpu->state_int(I8086_CX); - uint16_t dx = m_maincpu->state_int(I8086_DX); - uint16_t cs = m_maincpu->state_int(I8086_CS); - uint16_t ds = m_maincpu->state_int(I8086_DS); - uint16_t es = m_maincpu->state_int(I8086_ES); - uint16_t ss = m_maincpu->state_int(I8086_SS); - - uint16_t si = m_maincpu->state_int(I8086_SI); - uint16_t di = m_maincpu->state_int(I8086_DI); - uint16_t bp = m_maincpu->state_int(I8086_BP); - - uint8_t dosfn = ax >> 8; // Dos function is AH, upper half of AX. - - logerror("=======================================================================\n"); - logerror("DOS Int 0x21 call at %05X\n",pc); - logerror("AX=%04X, BX=%04X, CX=%04X, DX=%04X\n",ax,bx,cx,dx); - logerror("CS=%04X, DS=%04X, ES=%04X, SS=%04X\n",cs,ds,es,ss); - logerror("SI=%04X, DI=%04X, BP=%04X\n",si,di,bp); - logerror("=======================================================================\n"); - - if (((dosfn >= 0x39) && (dosfn <= 0x3d)) - || (0x43 == dosfn) - || (0x4e == dosfn) - || (0x56 == dosfn) - || ((dosfn >= 0x5a) && (dosfn <= 0x5b)) ) - { - path=(char *)get_regpair_ptr(space,ds,dx); - logerror("Path at DS:DX=%s\n",path); - - if (0x56 == dosfn) - { - path=(char *)get_regpair_ptr(space,es,di); - logerror("Path at ES:DI=%s\n",path); - } - logerror("=======================================================================\n"); - } -} - #define CBUFLEN 32 offs_t rmnimbus_state::dasm_override(std::ostream &stream, offs_t pc, const util::disasm_interface::data_buffer &opcodes, const util::disasm_interface::data_buffer ¶ms) diff --git a/src/osd/modules/debugger/debuggdbstub.cpp b/src/osd/modules/debugger/debuggdbstub.cpp index 485322ecc27..2b060670cb7 100644 --- a/src/osd/modules/debugger/debuggdbstub.cpp +++ b/src/osd/modules/debugger/debuggdbstub.cpp @@ -1211,15 +1211,15 @@ debug_gdbstub::cmd_reply debug_gdbstub::handle_Z(const char *buf) return REPLY_OK; case 2: // write watchpoint - debug->watchpoint_set(*m_address_space, read_or_write::WRITE, offset, kind, nullptr, nullptr); + debug->watchpoint_set(*m_address_space, read_or_write::WRITE, offset, kind); return REPLY_OK; case 3: // read watchpoint - debug->watchpoint_set(*m_address_space, read_or_write::READ, offset, kind, nullptr, nullptr); + debug->watchpoint_set(*m_address_space, read_or_write::READ, offset, kind); return REPLY_OK; case 4: // access watchpoint - debug->watchpoint_set(*m_address_space, read_or_write::READWRITE, offset, kind, nullptr, nullptr); + debug->watchpoint_set(*m_address_space, read_or_write::READWRITE, offset, kind); return REPLY_OK; } diff --git a/src/osd/modules/debugger/osx/disassemblyviewer.mm b/src/osd/modules/debugger/osx/disassemblyviewer.mm index 1f286a6bfc4..64d665a31cb 100644 --- a/src/osd/modules/debugger/osx/disassemblyviewer.mm +++ b/src/osd/modules/debugger/osx/disassemblyviewer.mm @@ -182,7 +182,7 @@ // if it doesn't exist, add a new one if (bp == nullptr) { - uint32_t const bpnum = device.debug()->breakpoint_set(address, nullptr, nullptr); + uint32_t const bpnum = device.debug()->breakpoint_set(address); machine->debugger().console().printf("Breakpoint %X set\n", bpnum); } else diff --git a/src/osd/modules/debugger/qt/dasmwindow.cpp b/src/osd/modules/debugger/qt/dasmwindow.cpp index 44ce8bac988..21e2520d712 100644 --- a/src/osd/modules/debugger/qt/dasmwindow.cpp +++ b/src/osd/modules/debugger/qt/dasmwindow.cpp @@ -149,7 +149,7 @@ void DasmWindow::toggleBreakpointAtCursor(bool changedTo) // If none exists, add a new one if (!bp) { - int32_t bpindex = cpuinfo->breakpoint_set(address, nullptr, nullptr); + int32_t bpindex = cpuinfo->breakpoint_set(address); m_machine.debugger().console().printf("Breakpoint %X set\n", bpindex); } else diff --git a/src/osd/modules/debugger/win/disasmbasewininfo.cpp b/src/osd/modules/debugger/win/disasmbasewininfo.cpp index f68a7652c77..4f8a58ad0d1 100644 --- a/src/osd/modules/debugger/win/disasmbasewininfo.cpp +++ b/src/osd/modules/debugger/win/disasmbasewininfo.cpp @@ -174,7 +174,7 @@ bool disasmbasewin_info::handle_command(WPARAM wparam, LPARAM lparam) { if (bp == nullptr) { - int32_t bpindex = debug->breakpoint_set(address, nullptr, nullptr); + int32_t bpindex = debug->breakpoint_set(address); machine().debugger().console().printf("Breakpoint %X set\n", bpindex); } else