summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--docs/source/debugger/exceptionpoint.rst134
-rw-r--r--docs/source/debugger/index.rst1
-rw-r--r--src/emu/debug/debugcmd.cpp269
-rw-r--r--src/emu/debug/debugcmd.h4
-rw-r--r--src/emu/debug/debugcpu.cpp211
-rw-r--r--src/emu/debug/debugcpu.h45
-rw-r--r--src/emu/debug/debughlp.cpp99
-rw-r--r--src/emu/debug/dvbpoints.cpp2
-rw-r--r--src/emu/debug/dvrpoints.cpp2
-rw-r--r--src/emu/debug/points.cpp68
-rw-r--r--src/emu/debug/points.h48
-rw-r--r--src/emu/emufwd.h1
-rw-r--r--src/mame/rm/rmnimbus.h7
-rw-r--r--src/mame/rm/rmnimbus_m.cpp687
-rw-r--r--src/osd/modules/debugger/debuggdbstub.cpp6
-rw-r--r--src/osd/modules/debugger/osx/disassemblyviewer.mm2
-rw-r--r--src/osd/modules/debugger/qt/dasmwindow.cpp2
-rw-r--r--src/osd/modules/debugger/win/disasmbasewininfo.cpp2
18 files changed, 738 insertions, 852 deletions
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] <type>[,<condition>[,<action>]]**
+
+Sets a new exception point for exceptions of type **<type>**. The
+optional **<condition>** 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 **<action>**
+parameter provides a command that is executed whenever the exception
+point is hit and the **<condition>** 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 [<epnum>[,…]]**
+
+The epclear command clears exception points. If **<epnum>** 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 [<epnum>[,…]]**
+
+The epdisable command disables exception points. If **<epnum>** 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 [<epnum>[,…]]**
+
+The epenable command enables exception points. If **<epnum>** 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<std::string_view> &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<std::string_view> &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<std::string_view> &param
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<std::strin
// param 3 is the type
read_or_write type;
- if (util::streqlower(params[2], "r"))
- type = read_or_write::READ;
- else if (util::streqlower(params[2], "w"))
- type = read_or_write::WRITE;
- else if (util::streqlower(params[2], "rw") || util::streqlower(params[2], "wr"))
- type = read_or_write::READWRITE;
- else
{
- m_console.printf("Invalid watchpoint type: expected r, w, or rw\n");
- return;
+ using util::streqlower;
+ using namespace std::literals;
+ if (streqlower(params[2], "r"sv))
+ type = read_or_write::READ;
+ else if (streqlower(params[2], "w"sv))
+ type = read_or_write::WRITE;
+ else if (streqlower(params[2], "rw"sv) || streqlower(params[2], "wr"sv))
+ type = read_or_write::READWRITE;
+ else
+ {
+ m_console.printf("Invalid watchpoint type: expected r, w, or rw\n");
+ return;
+ }
}
// param 4 is the condition
@@ -1984,12 +1996,12 @@ void debugger_commands::execute_wpset(int spacenum, const std::vector<std::strin
return;
// param 5 is the action
- std::string action;
+ std::string_view action;
if (params.size() > 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<std::string_view> &param
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<std::
}
+//-------------------------------------------------
+// execute_epset - execute the exception point
+// set command
+//-------------------------------------------------
+
+void debugger_commands::execute_epset(const std::vector<std::string_view> &params)
+{
+ // 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<std::string_view> &params)
+{
+ 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<std::string_view> &params)
+{
+ 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<std::string_view> &params)
+{
+ 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<std::string_view> &para
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<std::s
// decode condition
u8 condition;
- if (util::streqlower(params[0], "all"))
- condition = CHEAT_ALL;
- else if (util::streqlower(params[0], "equal") || util::streqlower(params[0], "eq"))
- condition = (params.size() > 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<std::string_view> &params
void debugger_commands::execute_trace(const std::vector<std::string_view> &params, 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<std::string_view> &param
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<std::string_view> &param
return;
// open the file
- FILE *f = nullptr;
- if (!util::streqlower(filename, "off"))
+ std::unique_ptr<std::ofstream> 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<std::ofstream>(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<std::string_view> &param
}
// 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<std::string_view> &params);
void execute_rpdisenable(bool enable, const std::vector<std::string_view> &params);
void execute_rplist(const std::vector<std::string_view> &params);
+ void execute_epset(const std::vector<std::string_view> &params);
+ void execute_epclear(const std::vector<std::string_view> &params);
+ void execute_epdisenable(bool enable, const std::vector<std::string_view> &params);
+ void execute_eplist(const std::vector<std::string_view> &params);
void execute_statesave(const std::vector<std::string_view> &params);
void execute_stateload(const std::vector<std::string_view> &params);
void execute_rewind(const std::vector<std::string_view> &params);
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<symbol_table>(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<std::forward_list<debug_registerpoint>>())
+ , 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)
{
@@ -893,22 +920,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,12 +1410,97 @@ 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<debug_exceptionpoint>(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<std::ostream> &&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<tracer>(*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<tracer>(*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<std::ostream> &&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<std::ostream> 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<std::unique_ptr<debug_watchpoint>> &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<debug_registerpoint> &registerpoint_list() const { return *m_rplist; }
- int registerpoint_set(const char *condition, const char *action = nullptr);
+ const std::forward_list<debug_registerpoint> &registerpoint_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<std::ostream> &&file, bool trace_over, bool detect_loops, bool logerror, std::string_view action);
+ template <typename Format, typename... Params> void trace_printf(Format &&fmt, Params &&...args)
+ {
+ if (m_trace != nullptr)
+ m_trace->vprintf(util::make_format_argument_pack(std::forward<Format>(fmt), std::forward<Params>(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<symbol_table> 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<offs_t, std::unique_ptr<debug_breakpoint>> m_bplist; // list of breakpoints
std::vector<std::vector<std::unique_ptr<debug_watchpoint>>> m_wplist; // watchpoint lists for each address space
- std::unique_ptr<std::forward_list<debug_registerpoint>> m_rplist; // list of registerpoints
+ std::forward_list<debug_registerpoint> m_rplist; // list of registerpoints
+ std::multimap<offs_t, std::unique_ptr<debug_exceptionpoint>> 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<std::ostream> &&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<std::ostream> 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<std::ostream> 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"
@@ -191,6 +192,18 @@ const help_item f_static_help_list[] =
" rplist [<CPU>] -- lists all the registerpoints\n"
},
{
+ "exceptionpoints",
+ "\n"
+ "Exception Point Commands\n"
+ "Type help <command> for further details on each command\n"
+ "\n"
+ " ep[set] <type>[,<condition>[,<action>]] -- sets exception point on <type>\n"
+ " epclear [<epnum>] -- clears a given exception point or all if no <epnum> specified\n"
+ " epdisable [<epnum>] -- disabled a given exception point or all if no <epnum> specified\n"
+ " epenable [<epnum>] -- enables a given exception point or all if no <epnum> specified\n"
+ " eplist -- lists all the registerpoints\n"
+ },
+ {
"expressions",
"\n"
"Expressions can be used anywhere a numeric parameter is expected. The syntax for expressions is "
@@ -1555,6 +1568,92 @@ const help_item f_static_help_list[] =
"actions attached to them.\n"
},
{
+ "epset",
+ "\n"
+ " ep[set] <type>[,<condition>[,<action>]]\n"
+ "\n"
+ "Sets a new exception point for exceptions of type <type> on the currently visible CPU. "
+ "The optional <condition> 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 <action> parameter "
+ "provides a command that is executed whenever the exception point is hit and the "
+ "<condition> 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 [<epnum>[,...]]\n"
+ "\n"
+ "The epclear command clears exception points. If <epnum> 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 [<epnum>[,...]]\n"
+ "\n"
+ "The epdisable command disables exception points. If <epnum> 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 [<epnum>[,...]]\n"
+ "\n"
+ "The epenable command enables exception points. If <epnum> 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"
" map[{d|i|o}] <address>[:<space>]\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<device_t *, debug_registerpoint const *> con
bool cActionAscending(std::pair<device_t *, debug_registerpoint const *> const &a, std::pair<device_t *, debug_registerpoint const *> const &b)
{
- return strcmp(a.second->action(), b.second->action()) < 0;
+ return a.second->action() < b.second->action();
}
bool cActionDescending(std::pair<device_t *, debug_registerpoint const *> const &a, std::pair<device_t *, debug_registerpoint const *> 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<i80186_cpu_device> m_maincpu;
required_device<i8031_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 <functional>
#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<std::string_view> &params)
-{
- 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 <debuglevel>\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<rmnimbus_state>();
- 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;charno<plot_string_params->length;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 &params)
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