summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/emu/debug/debugcmd.cpp298
-rw-r--r--src/emu/debug/debugcmd.h2
-rw-r--r--src/emu/debug/debughlp.cpp111
-rw-r--r--src/emu/debug/debugvw.cpp17
-rw-r--r--src/emu/debug/debugvw.h3
-rw-r--r--src/emu/debug/dvbpoints.cpp2
-rw-r--r--src/emu/debug/dvbpoints.h11
-rw-r--r--src/emu/debug/dvrpoints.cpp298
-rw-r--r--src/emu/debug/dvrpoints.h53
-rw-r--r--src/emu/debug/dvwpoints.cpp3
-rw-r--r--src/emu/debug/dvwpoints.h5
-rw-r--r--src/emu/inpttype.ipp2
-rw-r--r--src/frontend/mame/mame.h1
-rw-r--r--src/frontend/mame/ui/about.cpp222
-rw-r--r--src/frontend/mame/ui/about.h16
-rw-r--r--src/frontend/mame/ui/datmenu.cpp78
-rw-r--r--src/frontend/mame/ui/datmenu.h4
-rw-r--r--src/frontend/mame/ui/selmenu.cpp27
-rw-r--r--src/mame/drivers/apple2e.cpp2
-rw-r--r--src/osd/modules/debugger/osx/pointsviewer.mm38
-rw-r--r--src/osd/modules/debugger/osx/registerpointsview.h23
-rw-r--r--src/osd/modules/debugger/osx/registerpointsview.mm27
-rw-r--r--src/osd/modules/debugger/qt/breakpointswindow.cpp24
-rw-r--r--src/osd/modules/debugger/win/debugwininfo.h1
-rw-r--r--src/osd/modules/debugger/win/pointswininfo.cpp15
25 files changed, 973 insertions, 310 deletions
diff --git a/src/emu/debug/debugcmd.cpp b/src/emu/debug/debugcmd.cpp
index fe5bce41841..bcebb63cf92 100644
--- a/src/emu/debug/debugcmd.cpp
+++ b/src/emu/debug/debugcmd.cpp
@@ -250,9 +250,9 @@ debugger_commands::debugger_commands(running_machine& machine, debugger_cpu& cpu
m_console.register_command("bpset", CMDFLAG_NONE, 1, 3, std::bind(&debugger_commands::execute_bpset, this, _1));
m_console.register_command("bp", CMDFLAG_NONE, 1, 3, std::bind(&debugger_commands::execute_bpset, this, _1));
- m_console.register_command("bpclear", CMDFLAG_NONE, 0, 1, std::bind(&debugger_commands::execute_bpclear, this, _1));
- m_console.register_command("bpdisable", CMDFLAG_NONE, 0, 1, std::bind(&debugger_commands::execute_bpdisenable, this, false, _1));
- m_console.register_command("bpenable", CMDFLAG_NONE, 0, 1, std::bind(&debugger_commands::execute_bpdisenable, this, true, _1));
+ m_console.register_command("bpclear", CMDFLAG_NONE, 0, MAX_COMMAND_PARAMS, std::bind(&debugger_commands::execute_bpclear, this, _1));
+ m_console.register_command("bpdisable", CMDFLAG_NONE, 0, MAX_COMMAND_PARAMS, std::bind(&debugger_commands::execute_bpdisenable, this, false, _1));
+ m_console.register_command("bpenable", CMDFLAG_NONE, 0, MAX_COMMAND_PARAMS, std::bind(&debugger_commands::execute_bpdisenable, this, true, _1));
m_console.register_command("bplist", CMDFLAG_NONE, 0, 1, std::bind(&debugger_commands::execute_bplist, this, _1));
m_console.register_command("wpset", CMDFLAG_NONE, 3, 5, std::bind(&debugger_commands::execute_wpset, this, -1, _1));
@@ -263,17 +263,17 @@ debugger_commands::debugger_commands(running_machine& machine, debugger_cpu& cpu
m_console.register_command("wpi", CMDFLAG_NONE, 3, 5, std::bind(&debugger_commands::execute_wpset, this, AS_IO, _1));
m_console.register_command("wposet", CMDFLAG_NONE, 3, 5, std::bind(&debugger_commands::execute_wpset, this, AS_OPCODES, _1));
m_console.register_command("wpo", CMDFLAG_NONE, 3, 5, std::bind(&debugger_commands::execute_wpset, this, AS_OPCODES, _1));
- m_console.register_command("wpclear", CMDFLAG_NONE, 0, 1, std::bind(&debugger_commands::execute_wpclear, this, _1));
- m_console.register_command("wpdisable", CMDFLAG_NONE, 0, 1, std::bind(&debugger_commands::execute_wpdisenable, this, false, _1));
- m_console.register_command("wpenable", CMDFLAG_NONE, 0, 1, std::bind(&debugger_commands::execute_wpdisenable, this, true, _1));
+ m_console.register_command("wpclear", CMDFLAG_NONE, 0, MAX_COMMAND_PARAMS, std::bind(&debugger_commands::execute_wpclear, this, _1));
+ m_console.register_command("wpdisable", CMDFLAG_NONE, 0, MAX_COMMAND_PARAMS, std::bind(&debugger_commands::execute_wpdisenable, this, false, _1));
+ m_console.register_command("wpenable", CMDFLAG_NONE, 0, MAX_COMMAND_PARAMS, std::bind(&debugger_commands::execute_wpdisenable, this, true, _1));
m_console.register_command("wplist", CMDFLAG_NONE, 0, 1, std::bind(&debugger_commands::execute_wplist, this, _1));
m_console.register_command("rpset", CMDFLAG_NONE, 1, 2, std::bind(&debugger_commands::execute_rpset, this, _1));
m_console.register_command("rp", CMDFLAG_NONE, 1, 2, std::bind(&debugger_commands::execute_rpset, this, _1));
- m_console.register_command("rpclear", CMDFLAG_NONE, 0, 1, std::bind(&debugger_commands::execute_rpclear, this, _1));
- m_console.register_command("rpdisable", CMDFLAG_NONE, 0, 1, std::bind(&debugger_commands::execute_rpdisenable, this, false, _1));
- m_console.register_command("rpenable", CMDFLAG_NONE, 0, 1, std::bind(&debugger_commands::execute_rpdisenable, this, true, _1));
- m_console.register_command("rplist", CMDFLAG_NONE, 0, 0, std::bind(&debugger_commands::execute_rplist, this, _1));
+ m_console.register_command("rpclear", CMDFLAG_NONE, 0, MAX_COMMAND_PARAMS, std::bind(&debugger_commands::execute_rpclear, this, _1));
+ m_console.register_command("rpdisable", CMDFLAG_NONE, 0, MAX_COMMAND_PARAMS, std::bind(&debugger_commands::execute_rpdisenable, this, false, _1));
+ 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("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));
@@ -1071,6 +1071,37 @@ int debugger_commands::mini_printf(char *buffer, const char *format, int params,
/*-------------------------------------------------
+ execute_index_command - helper for commands
+ that take multiple indices as arguments
+-------------------------------------------------*/
+
+template <typename T>
+void debugger_commands::execute_index_command(std::vector<std::string> const &params, T &&apply, char const *unused_message)
+{
+ std::vector<u64> index(params.size());
+ for (int paramnum = 0; paramnum < params.size(); paramnum++)
+ {
+ if (!validate_number_parameter(params[paramnum], index[paramnum]))
+ return;
+ }
+
+ for (device_t &device : device_enumerator(m_machine.root_device()))
+ {
+ for (auto param = index.begin(); index.end() != param; )
+ {
+ if (apply(device, *param))
+ param = index.erase(param);
+ else
+ ++param;
+ }
+ }
+
+ for (auto const &param : index)
+ m_console.printf(unused_message, param);
+}
+
+
+/*-------------------------------------------------
execute_printf - execute the printf command
-------------------------------------------------*/
@@ -1740,31 +1771,24 @@ void debugger_commands::execute_bpset(const std::vector<std::string> &params)
void debugger_commands::execute_bpclear(const std::vector<std::string> &params)
{
- u64 bpindex;
-
if (params.empty()) // if no parameters, clear all
{
for (device_t &device : device_enumerator(m_machine.root_device()))
device.debug()->breakpoint_clear_all();
m_console.printf("Cleared all breakpoints\n");
}
- else if (!validate_number_parameter(params[0], bpindex)) // otherwise, clear the specific one
- {
- return;
- }
- else
+ else // otherwise, clear the specific ones
{
- bool found = false;
- for (device_t &device : device_enumerator(m_machine.root_device()))
- if (device.debug()->breakpoint_clear(bpindex))
- {
- found = true;
- break;
- }
- if (found)
- m_console.printf("Breakpoint %X cleared\n", u32(bpindex));
- else
- m_console.printf("Invalid breakpoint number %X\n", u32(bpindex));
+ execute_index_command(
+ params,
+ [this] (device_t &device, u64 param) -> bool
+ {
+ if (!device.debug()->breakpoint_clear(param))
+ return false;
+ m_console.printf("Breakpoint %X cleared\n", param);
+ return true;
+ },
+ "Invalid breakpoint number %X\n");
}
}
@@ -1776,34 +1800,24 @@ void debugger_commands::execute_bpclear(const std::vector<std::string> &params)
void debugger_commands::execute_bpdisenable(bool enable, const std::vector<std::string> &params)
{
- u64 bpindex;
-
- if (params.empty()) // if 0 parameters, disable/enable all
+ if (params.empty()) // if no parameters, disable/enable all
{
for (device_t &device : device_enumerator(m_machine.root_device()))
device.debug()->breakpoint_enable_all(enable);
- if (!enable)
- m_console.printf("Disabled all breakpoints\n");
- else
- m_console.printf("Enabled all breakpoints\n");
- }
- else if (!validate_number_parameter(params[0], bpindex)) // otherwise, disable/enable the specific one
- {
- return;
+ m_console.printf(enable ? "Enabled all breakpoints\n" : "Disabled all breakpoints\n");
}
- else
+ else // otherwise, disable/enable the specific ones
{
- bool found = false;
- for (device_t &device : device_enumerator(m_machine.root_device()))
- if (device.debug()->breakpoint_enable(bpindex, enable))
- {
- found = true;
- break;
- }
- if (found)
- m_console.printf("Breakpoint %X %s\n", u32(bpindex), enable ? "enabled" : "disabled");
- else
- m_console.printf("Invalid breakpoint number %X\n", u32(bpindex));
+ execute_index_command(
+ params,
+ [this, enable] (device_t &device, u64 param) -> bool
+ {
+ if (!device.debug()->breakpoint_enable(param, enable))
+ return false;
+ m_console.printf(enable ? "Breakpoint %X enabled\n" : "Breakpoint %X disabled\n", param);
+ return true;
+ },
+ "Invalid breakpoint number %X\n");
}
}
@@ -1922,29 +1936,24 @@ void debugger_commands::execute_wpset(int spacenum, const std::vector<std::strin
void debugger_commands::execute_wpclear(const std::vector<std::string> &params)
{
- u64 wpindex;
-
- /* if 0 parameters, clear all */
- if (params.empty())
+ if (params.empty()) // if no parameters, clear all
{
for (device_t &device : device_enumerator(m_machine.root_device()))
device.debug()->watchpoint_clear_all();
m_console.printf("Cleared all watchpoints\n");
}
-
- /* otherwise, clear the specific one */
- else if (!validate_number_parameter(params[0], wpindex))
- return;
- else
+ else // otherwise, clear the specific ones
{
- bool found = false;
- for (device_t &device : device_enumerator(m_machine.root_device()))
- if (device.debug()->watchpoint_clear(wpindex))
- found = true;
- if (found)
- m_console.printf("Watchpoint %X cleared\n", u32(wpindex));
- else
- m_console.printf("Invalid watchpoint number %X\n", u32(wpindex));
+ execute_index_command(
+ params,
+ [this] (device_t &device, u64 param) -> bool
+ {
+ if (!device.debug()->watchpoint_clear(param))
+ return false;
+ m_console.printf("Watchpoint %X cleared\n", param);
+ return true;
+ },
+ "Invalid watchpoint number %X\n");
}
}
@@ -1956,31 +1965,24 @@ void debugger_commands::execute_wpclear(const std::vector<std::string> &params)
void debugger_commands::execute_wpdisenable(bool enable, const std::vector<std::string> &params)
{
- u64 wpindex;
-
- if (params.empty()) // if no parameters, clear all
+ if (params.empty()) // if no parameters, disable/enable all
{
for (device_t &device : device_enumerator(m_machine.root_device()))
device.debug()->watchpoint_enable_all(enable);
- if (!enable)
- m_console.printf("Disabled all watchpoints\n");
- else
- m_console.printf("Enabled all watchpoints\n");
- }
- else if (!validate_number_parameter(params[0], wpindex)) // otherwise, clear the specific one
- {
- return;
+ m_console.printf(enable ? "Enabled all watchpoints\n" : "Disabled all watchpoints\n");
}
- else
+ else // otherwise, disable/enable the specific ones
{
- bool found = false;
- for (device_t &device : device_enumerator(m_machine.root_device()))
- if (device.debug()->watchpoint_enable(wpindex, enable))
- found = true;
- if (found)
- m_console.printf("Watchpoint %X %s\n", u32(wpindex), enable ? "enabled" : "disabled");
- else
- m_console.printf("Invalid watchpoint number %X\n", u32(wpindex));
+ execute_index_command(
+ params,
+ [this, enable] (device_t &device, u64 param) -> bool
+ {
+ if (!device.debug()->watchpoint_enable(param, enable))
+ return false;
+ m_console.printf(enable ? "Watchpoint %X enabled\n" : "Watchpoint %X disabled\n", param);
+ return true;
+ },
+ "Invalid watchpoint number %X\n");
}
}
@@ -2070,9 +2072,9 @@ void debugger_commands::execute_rpset(const std::vector<std::string> &params)
if (params.size() > 1 && !debug_command_parameter_command(action = params[1].c_str()))
return;
- // set the breakpoint
- int const bpnum = cpu->debug()->registerpoint_set(condition.original_string(), action);
- m_console.printf("Registerpoint %X set\n", bpnum);
+ // set the registerpoint
+ int const rpnum = cpu->debug()->registerpoint_set(condition.original_string(), action);
+ m_console.printf("Registerpoint %X set\n", rpnum);
}
@@ -2083,29 +2085,24 @@ void debugger_commands::execute_rpset(const std::vector<std::string> &params)
void debugger_commands::execute_rpclear(const std::vector<std::string> &params)
{
- u64 rpindex;
-
- /* if 0 parameters, clear all */
- if (params.empty())
+ if (params.empty()) // if no parameters, clear all
{
for (device_t &device : device_enumerator(m_machine.root_device()))
device.debug()->registerpoint_clear_all();
m_console.printf("Cleared all registerpoints\n");
}
-
- /* otherwise, clear the specific one */
- else if (!validate_number_parameter(params[0], rpindex))
- return;
- else
+ else // otherwise, clear the specific ones
{
- bool found = false;
- for (device_t &device : device_enumerator(m_machine.root_device()))
- if (device.debug()->registerpoint_clear(rpindex))
- found = true;
- if (found)
- m_console.printf("Registerpoint %X cleared\n", u32(rpindex));
- else
- m_console.printf("Invalid registerpoint number %X\n", u32(rpindex));
+ execute_index_command(
+ params,
+ [this] (device_t &device, u64 param) -> bool
+ {
+ if (!device.debug()->registerpoint_clear(param))
+ return false;
+ m_console.printf("Registerpoint %X cleared\n", param);
+ return true;
+ },
+ "Invalid registerpoint number %X\n");
}
}
@@ -2117,31 +2114,24 @@ void debugger_commands::execute_rpclear(const std::vector<std::string> &params)
void debugger_commands::execute_rpdisenable(bool enable, const std::vector<std::string> &params)
{
- u64 rpindex;
-
- if (params.empty()) // if no parameters, clear all
+ if (params.empty()) // if no parameters, disable/enable all
{
for (device_t &device : device_enumerator(m_machine.root_device()))
device.debug()->registerpoint_enable_all(enable);
- if (!enable)
- m_console.printf("Disabled all registerpoints\n");
- else
- m_console.printf("Enabled all registeroints\n");
- }
- else if (!validate_number_parameter(params[0], rpindex)) // otherwise, clear the specific one
- {
- return;
+ m_console.printf(enable ? "Enabled all registerpoints\n" : "Disabled all registerpoints\n");
}
- else
+ else // otherwise, disable/enable the specific ones
{
- bool found = false;
- for (device_t &device : device_enumerator(m_machine.root_device()))
- if (device.debug()->registerpoint_enable(rpindex, enable))
- found = true;
- if (found)
- m_console.printf("Registerpoint %X %s\n", u32(rpindex), enable ? "enabled" : "disabled");
- else
- m_console.printf("Invalid registerpoint number %X\n", u32(rpindex));
+ execute_index_command(
+ params,
+ [this, enable] (device_t &device, u64 param) -> bool
+ {
+ if (!device.debug()->registerpoint_enable(param, enable))
+ return false;
+ m_console.printf(enable ? "Registerpoint %X enabled\n" : "Breakpoint %X disabled\n", param);
+ return true;
+ },
+ "Invalid registerpoint number %X\n");
}
}
@@ -2155,26 +2145,42 @@ void debugger_commands::execute_rplist(const std::vector<std::string> &params)
{
int printed = 0;
std::string buffer;
-
- /* loop over all CPUs */
- for (device_t &device : device_enumerator(m_machine.root_device()))
- if (!device.debug()->registerpoint_list().empty())
- {
- m_console.printf("Device '%s' registerpoints:\n", device.tag());
-
- /* loop over the breakpoints */
- for (const debug_registerpoint &rp : device.debug()->registerpoint_list())
+ auto const apply =
+ [this, &printed, &buffer] (device_t &device)
{
- buffer = string_format("%c%4X if %s", rp.enabled() ? ' ' : 'D', rp.index(), rp.condition());
- if (rp.action() != nullptr)
- buffer.append(string_format(" do %s", rp.action()));
- m_console.printf("%s\n", buffer);
- printed++;
- }
- }
+ if (!device.debug()->registerpoint_list().empty())
+ {
+ m_console.printf("Device '%s' registerpoints:\n", device.tag());
+
+ // loop over the registerpoints
+ 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())
+ buffer.append(string_format(" do %s", rp.action()));
+ m_console.printf("%s\n", buffer);
+ printed++;
+ }
+ }
+ };
- if (printed == 0)
- m_console.printf("No registerpoints currently installed\n");
+ if (!params.empty())
+ {
+ device_t *cpu;
+ if (!validate_cpu_parameter(params[0], cpu))
+ return;
+ apply(*cpu);
+ if (!printed)
+ m_console.printf("No registerpoints 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 registerpoints currently installed\n");
+ }
}
diff --git a/src/emu/debug/debugcmd.h b/src/emu/debug/debugcmd.h
index 09e4b7ed7a1..0f85e80e705 100644
--- a/src/emu/debug/debugcmd.h
+++ b/src/emu/debug/debugcmd.h
@@ -99,6 +99,8 @@ private:
void global_set(global_entry *global, u64 value);
int mini_printf(char *buffer, const char *format, int params, u64 *param);
+ template <typename T>
+ void execute_index_command(std::vector<std::string> const &params, T &&apply, char const *unused_message);
void execute_help(const std::vector<std::string> &params);
void execute_print(const std::vector<std::string> &params);
diff --git a/src/emu/debug/debughlp.cpp b/src/emu/debug/debughlp.cpp
index ef19f91c3a9..c62b7299ea7 100644
--- a/src/emu/debug/debughlp.cpp
+++ b/src/emu/debug/debughlp.cpp
@@ -154,9 +154,9 @@ const help_item f_static_help_list[] =
"Type help <command> for further details on each command\n"
"\n"
" bp[set] <address>[:<CPU>][,<condition>[,<action>]] -- sets breakpoint at <address>\n"
- " bpclear [<bpnum>] -- clears a given breakpoint or all if no <bpnum> specified\n"
- " bpdisable [<bpnum>] -- disables a given breakpoint or all if no <bpnum> specified\n"
- " bpenable [<bpnum>] -- enables a given breakpoint or all if no <bpnum> specified\n"
+ " bpclear [<bpnum>[,...]] -- clears given breakpoints or all if no <bpnum> specified\n"
+ " bpdisable [<bpnum>[,...]] -- disables given breakpoints or all if no <bpnum> specified\n"
+ " bpenable [<bpnum>[,...]] -- enables given breakpoints or all if no <bpnum> specified\n"
" bplist [<CPU>] -- lists all the breakpoints\n"
},
{
@@ -169,9 +169,9 @@ const help_item f_static_help_list[] =
" wpd[set] <address>[:<space>],<length>,<type>[,<condition>[,<action>]] -- sets data space watchpoint\n"
" wpi[set] <address>[:<space>],<length>,<type>[,<condition>[,<action>]] -- sets I/O space watchpoint\n"
" wpo[set] <address>[:<space>],<length>,<type>[,<condition>[,<action>]] -- sets opcode space watchpoint\n"
- " wpclear [<wpnum>] -- clears a given watchpoint or all if no <wpnum> specified\n"
- " wpdisable [<wpnum>] -- disables a given watchpoint or all if no <wpnum> specified\n"
- " wpenable [<wpnum>] -- enables a given watchpoint or all if no <wpnum> specified\n"
+ " wpclear [<wpnum>[,...]] -- clears given watchpoints or all if no <wpnum> specified\n"
+ " wpdisable [<wpnum>[,...]] -- disables given watchpoints or all if no <wpnum> specified\n"
+ " wpenable [<wpnum>[,...]] -- enables given watchpoints or all if no <wpnum> specified\n"
" wplist [<CPU>] -- lists all the watchpoints\n"
},
{
@@ -180,11 +180,11 @@ const help_item f_static_help_list[] =
"Registerpoint Commands\n"
"Type help <command> for further details on each command\n"
"\n"
- " rp[set] {<condition>}[,<action>] -- sets a registerpoint to trigger on <condition>\n"
- " rpclear [<rpnum>] -- clears a given registerpoint or all if no <rpnum> specified\n"
- " rpdisable [<rpnum>] -- disabled a given registerpoint or all if no <rpnum> specified\n"
- " rpenable [<rpnum>] -- enables a given registerpoint or all if no <rpnum> specified\n"
- " rplist -- lists all the registerpoints\n"
+ " rp[set] <condition>[,<action>] -- sets a registerpoint to trigger on <condition>\n"
+ " rpclear [<rpnum>[,...]] -- clears given registerpoints or all if no <rpnum> specified\n"
+ " rpdisable [<rpnum>[,...]] -- disabled given registerpoints or all if no <rpnum> specified\n"
+ " rpenable [<rpnum>[,...]] -- enables given registerpoints or all if no <rpnum> specified\n"
+ " rplist [<CPU>] -- lists all the registerpoints\n"
},
{
"expressions",
@@ -1206,10 +1206,10 @@ const help_item f_static_help_list[] =
{
"bpclear",
"\n"
- " bpclear [<bpnum>]\n"
+ " bpclear [<bpnum>[,...]]\n"
"\n"
- "The bpclear command clears a breakpoint. If <bpnum> is specified, only the requested "
- "breakpoint is cleared; otherwise all breakpoints are cleared.\n"
+ "The bpclear command clears breakpoints. If <bpnum> is specified, only the requested "
+ "breakpoints are cleared; otherwise all breakpoints are cleared.\n"
"\n"
"Examples:\n"
"\n"
@@ -1222,10 +1222,10 @@ const help_item f_static_help_list[] =
{
"bpdisable",
"\n"
- " bpdisable [<bpnum>]\n"
+ " bpdisable [<bpnum>,[...]]\n"
"\n"
- "The bpdisable command disables a breakpoint. If <bpnum> is specified, only the requested "
- "breakpoint is disabled; otherwise all breakpoints are disabled. Note that disabling a "
+ "The bpdisable command disables breakpoints. If <bpnum> is specified, only the requested "
+ "breakpoints are disabled; otherwise all breakpoints are disabled. Note that disabling a "
"breakpoint does not delete it, it just temporarily marks the breakpoint as inactive.\n"
"\n"
"Examples:\n"
@@ -1239,10 +1239,10 @@ const help_item f_static_help_list[] =
{
"bpenable",
"\n"
- " bpenable [<bpnum>]\n"
+ " bpenable [<bpnum>,[...]]\n"
"\n"
- "The bpenable command enables a breakpoint. If <bpnum> is specified, only the requested "
- "breakpoint is enabled; otherwise all breakpoints are enabled.\n"
+ "The bpenable command enable breakpoints. If <bpnum> is specified, only the requested "
+ "breakpoints enabled; otherwise all breakpoints are enabled.\n"
"\n"
"Examples:\n"
"\n"
@@ -1331,10 +1331,10 @@ const help_item f_static_help_list[] =
{
"wpclear",
"\n"
- " wpclear [<wpnum>]\n"
+ " wpclear [<wpnum>[,...]]\n"
"\n"
- "The wpclear command clears a watchpoint. If <wpnum> is specified, only the requested "
- "watchpoint is cleared; otherwise all watchpoints are cleared.\n"
+ "The wpclear command clears watchpoints. If <wpnum> is specified, only the requested "
+ "watchpoints are cleared; otherwise all watchpoints are cleared.\n"
"\n"
"Examples:\n"
"\n"
@@ -1347,10 +1347,10 @@ const help_item f_static_help_list[] =
{
"wpdisable",
"\n"
- " wpdisable [<wpnum>]\n"
+ " wpdisable [<wpnum>[,...]]\n"
"\n"
- "The wpdisable command disables a watchpoint. If <wpnum> is specified, only the requested "
- "watchpoint is disabled; otherwise all watchpoints are disabled. Note that disabling a "
+ "The wpdisable command disables watchpoints. If <wpnum> is specified, only the requested "
+ "watchpoints are disabled; otherwise all watchpoints are disabled. Note that disabling a "
"watchpoint does not delete it, it just temporarily marks the watchpoint as inactive.\n"
"\n"
"Examples:\n"
@@ -1364,10 +1364,10 @@ const help_item f_static_help_list[] =
{
"wpenable",
"\n"
- " wpenable [<wpnum>]\n"
+ " wpenable [<wpnum>[,...]]\n"
"\n"
- "The wpenable command enables a watchpoint. If <wpnum> is specified, only the requested "
- "watchpoint is enabled; otherwise all watchpoints are enabled.\n"
+ "The wpenable command enables watchpoints. If <wpnum> is specified, only the requested "
+ "watchpoints are enabled; otherwise all watchpoints are enabled.\n"
"\n"
"Examples:\n"
"\n"
@@ -1401,26 +1401,26 @@ const help_item f_static_help_list[] =
{
"rpset",
"\n"
- " rp[set] {<condition>}[,<action>]]\n"
+ " rp[set] <condition>[,<action>]\n"
"\n"
- "Sets a new registerpoint which will be triggered when <condition> is met. The condition must "
- "be specified between curly braces to prevent the condition from being evaluated as an "
- "assignment.\n"
+ "Sets a new registerpoint which will be triggered when <condition> is true (evaluates to a "
+ "non-zero value). The condition must be embedded in braces { } to prevent it from being "
+ "interpreted as an assignment.\n"
"\n"
- "The optional <action> parameter provides a command that is executed whenever the registerpoint "
- "is hit. 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 rpset command "
- "itself. Each registerpoint that is set is assigned an index which can be used in other "
- "registerpoint commands to reference this registerpoint.\n"
+ "The optional <action> parameter provides a command that is executed whenever the "
+ "registerpoint is hit. 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 rpset "
+ "command itself. Each registerpoint that is set is assigned an index which can be used in "
+ "other registerpoint commands to reference this registerpoint.\n"
"\n"
"Examples:\n"
"\n"
- "rp {PC==0150}\n"
- " Set a registerpoint that will halt execution whenever the PC register equals 0x150.\n"
+ "rp {PC==150}\n"
+ " Set a registerpoint that will halt execution whenever the PC register equals 150.\n"
"\n"
- "temp0=0; rp {PC==0150},{temp0++; g}\n"
+ "temp0=0; rp {PC==150},{temp0++; g}\n"
" Set a registerpoint that will increment the variable temp0 whenever the PC register "
- "equals 0x0150.\n"
+ "equals 150.\n"
"\n"
"rp {temp0==5}\n"
" Set a registerpoint that will halt execution whenever the temp0 variable equals 5.\n"
@@ -1428,15 +1428,15 @@ const help_item f_static_help_list[] =
{
"rpclear",
"\n"
- " rpclear [<rpnum>]\n"
+ " rpclear [<rpnum>[,...]]\n"
"\n"
- "The rpclear command clears a registerpoint. If <rpnum> is specified, only the requested "
- "registerpoint is cleared, otherwise all registerpoints are cleared.\n"
+ "The rpclear command clears registerpoints. If <rpnum> is specified, only the requested "
+ "registerpoints are cleared, otherwise all registerpoints are cleared.\n"
"\n"
"Examples:\n"
"\n"
"rpclear 3\n"
- " Clear registerpoint index 3.\n"
+ " Clear the registerpoint with index 3.\n"
"\n"
"rpclear\n"
" Clear all registerpoints.\n"
@@ -1444,16 +1444,17 @@ const help_item f_static_help_list[] =
{
"rpdisable",
"\n"
- " rpdisable [<rpnum>]\n"
+ " rpdisable [<rpnum>[,...]]\n"
"\n"
- "The rpdisable command disables a registerpoint. If <rpnum> is specified, only the requested "
- "registerpoint is disabled, otherwise all registerpoints are disabled. Note that disabling a "
- "registerpoint does not delete it, it just temporarily marks the registerpoint as inactive.\n"
+ "The rpdisable command disables registerpoints. If <rpnum> is specified, only the "
+ "requested registerpoints are disabled, otherwise all registerpoints are disabled. Note "
+ "that disabling a registerpoint does not delete it, it just temporarily marks the "
+ "registerpoint as inactive.\n"
"\n"
"Examples:\n"
"\n"
"rpdisable 3\n"
- " Disable registerpoint index 3.\n"
+ " Disable the registerpoint with index 3.\n"
"\n"
"rpdisable\n"
" Disable all registerpoints.\n"
@@ -1461,15 +1462,15 @@ const help_item f_static_help_list[] =
{
"rpenable",
"\n"
- " rpenable [<rpnum>]\n"
+ " rpenable [<rpnum>[,...]]\n"
"\n"
- "The rpenable command enables a registerpoint. If <rpnum> is specified, only the requested "
- "registerpoint is enabled, otherwise all registerpoints are enabled.\n"
+ "The rpenable command enables registerpoints. If <rpnum> is specified, only the requested "
+ "registerpoints are enabled, otherwise all registerpoints are enabled.\n"
"\n"
"Examples:\n"
"\n"
"rpenable 3\n"
- " Enable registerpoint index 3.\n"
+ " Enable the registerpoint with index 3.\n"
"\n"
"rpenable\n"
" Enable all registerpoints.\n"
diff --git a/src/emu/debug/debugvw.cpp b/src/emu/debug/debugvw.cpp
index 120152b3d5f..5bcc3d057b8 100644
--- a/src/emu/debug/debugvw.cpp
+++ b/src/emu/debug/debugvw.cpp
@@ -9,16 +9,20 @@
***************************************************************************/
#include "emu.h"
-#include "express.h"
#include "debugvw.h"
-#include "dvtext.h"
-#include "dvstate.h"
+
+#include "debugcpu.h"
+#include "dvbpoints.h"
#include "dvdisasm.h"
#include "dvmemory.h"
-#include "dvbpoints.h"
+#include "dvrpoints.h"
+#include "dvstate.h"
+#include "dvtext.h"
#include "dvwpoints.h"
-#include "debugcpu.h"
+#include "express.h"
+
#include "debugger.h"
+
#include <cctype>
@@ -362,6 +366,9 @@ debug_view *debug_view_manager::alloc_view(debug_view_type type, debug_view_osd_
case DVT_WATCH_POINTS:
return append(new debug_view_watchpoints(machine(), osdupdate, osdprivate));
+ case DVT_REGISTER_POINTS:
+ return append(new debug_view_registerpoints(machine(), osdupdate, osdprivate));
+
default:
fatalerror("Attempt to create invalid debug view type %d\n", type);
}
diff --git a/src/emu/debug/debugvw.h b/src/emu/debug/debugvw.h
index 91c080bf07f..73f93d14f32 100644
--- a/src/emu/debug/debugvw.h
+++ b/src/emu/debug/debugvw.h
@@ -34,7 +34,8 @@ enum debug_view_type
DVT_MEMORY,
DVT_LOG,
DVT_BREAK_POINTS,
- DVT_WATCH_POINTS
+ DVT_WATCH_POINTS,
+ DVT_REGISTER_POINTS
};
diff --git a/src/emu/debug/dvbpoints.cpp b/src/emu/debug/dvbpoints.cpp
index 258d1dff020..b42b86a0e90 100644
--- a/src/emu/debug/dvbpoints.cpp
+++ b/src/emu/debug/dvbpoints.cpp
@@ -1,5 +1,5 @@
// license:BSD-3-Clause
-// copyright-holders:Aaron Giles
+// copyright-holders:Andrew Gardner, Vas Crabb
/*********************************************************************
dvbpoints.cpp
diff --git a/src/emu/debug/dvbpoints.h b/src/emu/debug/dvbpoints.h
index 18419434c03..1bf365f521e 100644
--- a/src/emu/debug/dvbpoints.h
+++ b/src/emu/debug/dvbpoints.h
@@ -1,5 +1,5 @@
// license:BSD-3-Clause
-// copyright-holders:Aaron Giles
+// copyright-holders:Andrew Gardner, Vas Crabb
/*********************************************************************
dvbpoints.h
@@ -7,19 +7,15 @@
Breakpoint debugger view.
***************************************************************************/
-
#ifndef MAME_EMU_DEBUG_DVBPOINTS_H
#define MAME_EMU_DEBUG_DVBPOINTS_H
#pragma once
-#include "debugvw.h"
#include "debugcpu.h"
+#include "debugvw.h"
-
-//**************************************************************************
-// CONSTANTS
-//**************************************************************************
+#include <vector>
//**************************************************************************
@@ -46,7 +42,6 @@ private:
void pad_ostream_to_length(std::ostream& str, int len);
void gather_breakpoints();
-
// internal state
bool (*m_sortType)(const debug_breakpoint *, const debug_breakpoint *);
std::vector<const debug_breakpoint *> m_buffer;
diff --git a/src/emu/debug/dvrpoints.cpp b/src/emu/debug/dvrpoints.cpp
new file mode 100644
index 00000000000..3ecadaec8e5
--- /dev/null
+++ b/src/emu/debug/dvrpoints.cpp
@@ -0,0 +1,298 @@
+// license:BSD-3-Clause
+// copyright-holders:Vas Crabb
+/*********************************************************************
+
+ dvrpoints.cpp
+
+ Registerpoint debugger view.
+
+***************************************************************************/
+
+#include "emu.h"
+#include "dvrpoints.h"
+
+#include "debugger.h"
+#include "points.h"
+
+#include <algorithm>
+#include <iomanip>
+
+
+namespace {
+
+bool cIndexAscending(std::pair<device_t *, debug_registerpoint const *> const &a, std::pair<device_t *, debug_registerpoint const *> const &b)
+{
+ return a.second->index() < b.second->index();
+}
+
+bool cIndexDescending(std::pair<device_t *, debug_registerpoint const *> const &a, std::pair<device_t *, debug_registerpoint const *> const &b)
+{
+ return a.second->index() > b.second->index();
+}
+
+bool cEnabledAscending(std::pair<device_t *, debug_registerpoint const *> const &a, std::pair<device_t *, debug_registerpoint const *> const &b)
+{
+ return !a.second->enabled() && b.second->enabled();
+}
+
+bool cEnabledDescending(std::pair<device_t *, debug_registerpoint const *> const &a, std::pair<device_t *, debug_registerpoint const *> const &b)
+{
+ return cEnabledAscending(b, a);
+}
+
+bool cCpuAscending(std::pair<device_t *, debug_registerpoint const *> const &a, std::pair<device_t *, debug_registerpoint const *> const &b)
+{
+ return strcmp(a.first->tag(), b.first->tag()) < 0;
+}
+
+bool cCpuDescending(std::pair<device_t *, debug_registerpoint const *> const &a, std::pair<device_t *, debug_registerpoint const *> const &b)
+{
+ return cCpuAscending(b, a);
+}
+
+bool cConditionAscending(std::pair<device_t *, debug_registerpoint const *> const &a, std::pair<device_t *, debug_registerpoint const *> const &b)
+{
+ return strcmp(a.second->condition(), b.second->condition()) < 0;
+}
+
+bool cConditionDescending(std::pair<device_t *, debug_registerpoint const *> const &a, std::pair<device_t *, debug_registerpoint const *> const &b)
+{
+ return cConditionAscending(b, a);
+}
+
+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;
+}
+
+bool cActionDescending(std::pair<device_t *, debug_registerpoint const *> const &a, std::pair<device_t *, debug_registerpoint const *> const &b)
+{
+ return cActionAscending(b, a);
+}
+
+
+constexpr int TABLE_BREAKS[] = { 5, 9, 31, 49, 66 };
+
+} // anonymous namespace
+
+
+//**************************************************************************
+// DEBUG VIEW REGISTER POINTS
+//**************************************************************************
+
+
+//-------------------------------------------------
+// debug_view_registerpoints - constructor
+//-------------------------------------------------
+
+debug_view_registerpoints::debug_view_registerpoints(running_machine &machine, debug_view_osd_update_func osdupdate, void *osdprivate)
+ : debug_view(machine, DVT_REGISTER_POINTS, osdupdate, osdprivate)
+ , m_sort_type(cIndexAscending)
+{
+ // fail if no available sources
+ enumerate_sources();
+ if (m_source_list.empty())
+ throw std::bad_alloc();
+}
+
+
+//-------------------------------------------------
+// ~debug_view_registerpoints - destructor
+//-------------------------------------------------
+
+debug_view_registerpoints::~debug_view_registerpoints()
+{
+}
+
+
+//-------------------------------------------------
+// enumerate_sources - enumerate all possible
+// sources for a disassembly view
+//-------------------------------------------------
+
+void debug_view_registerpoints::enumerate_sources()
+{
+ // start with an empty list
+ m_source_list.clear();
+
+ // iterate over devices with disassembly interfaces
+ for (device_disasm_interface &dasm : disasm_interface_enumerator(machine().root_device()))
+ {
+ m_source_list.emplace_back(
+ std::make_unique<debug_view_source>(
+ util::string_format("%s '%s'", dasm.device().name(), dasm.device().tag()),
+ &dasm.device()));
+ }
+
+ // reset the source to a known good entry
+ if (!m_source_list.empty())
+ set_source(*m_source_list[0]);
+}
+
+
+//-------------------------------------------------
+// view_click - handle a mouse click within the
+// current view
+//-------------------------------------------------
+
+void debug_view_registerpoints::view_click(const int button, const debug_view_xy& pos)
+{
+ bool clickedTopRow = (m_topleft.y == pos.y);
+
+ if (clickedTopRow)
+ {
+ if (pos.x < TABLE_BREAKS[0])
+ m_sort_type = (m_sort_type == &cIndexAscending) ? &cIndexDescending : &cIndexAscending;
+ else if (pos.x < TABLE_BREAKS[1])
+ m_sort_type = (m_sort_type == &cEnabledAscending) ? &cEnabledDescending : &cEnabledAscending;
+ else if (pos.x < TABLE_BREAKS[2])
+ m_sort_type = (m_sort_type == &cCpuAscending) ? &cCpuDescending : &cCpuAscending;
+ else if (pos.x < TABLE_BREAKS[3])
+ m_sort_type = (m_sort_type == &cConditionAscending) ? &cConditionDescending : &cConditionAscending;
+ else if (pos.x < TABLE_BREAKS[4])
+ m_sort_type = (m_sort_type == &cActionAscending) ? &cActionDescending : &cActionAscending;
+ }
+ else
+ {
+ // Gather a sorted list of all the breakpoints for all the CPUs
+ gather_registerpoints();
+
+ int rpIndex = pos.y - 1;
+ if ((rpIndex >= m_buffer.size()) || (rpIndex < 0))
+ return;
+
+ // Enable / disable
+ m_buffer[rpIndex].first->debug()->registerpoint_enable(
+ m_buffer[rpIndex].second->index(),
+ !m_buffer[rpIndex].second->enabled());
+ }
+
+ begin_update();
+ m_update_pending = true;
+ end_update();
+}
+
+
+void debug_view_registerpoints::pad_ostream_to_length(std::ostream& str, int len)
+{
+ auto const current = str.tellp();
+ if (current < decltype(current)(len))
+ str << std::setw(decltype(current)(len) - current) << "";
+}
+
+
+void debug_view_registerpoints::gather_registerpoints()
+{
+ m_buffer.resize(0);
+ for (auto &source : m_source_list)
+ {
+ // Collect
+ device_debug &debugInterface = *source->device()->debug();
+ for (const auto &rp : debugInterface.registerpoint_list())
+ m_buffer.emplace_back(source->device(), &rp);
+ }
+
+ // And now for the sort
+ if (!m_buffer.empty())
+ std::stable_sort(m_buffer.begin(), m_buffer.end(), m_sort_type);
+}
+
+
+//-------------------------------------------------
+// view_update - update the contents of the
+// registerpoints view
+//-------------------------------------------------
+
+void debug_view_registerpoints::view_update()
+{
+ // Gather a list of all the registerpoints for all the CPUs
+ gather_registerpoints();
+
+ // Set the view region so the scroll bars update
+ m_total.x = TABLE_BREAKS[std::size(TABLE_BREAKS) - 1];
+ m_total.y = m_buffer.size() + 1;
+ if (m_total.y < 10)
+ m_total.y = 10;
+
+ // Draw
+ debug_view_char *dest = &m_viewdata[0];
+ util::ovectorstream linebuf;
+ linebuf.reserve(std::size(TABLE_BREAKS) - 1);
+
+ // Header
+ if (m_visible.y > 0)
+ {
+ linebuf.clear();
+ linebuf.rdbuf()->clear();
+ linebuf << "ID";
+ if (m_sort_type == &cIndexAscending) linebuf.put('\\');
+ else if (m_sort_type == &cIndexDescending) linebuf.put('/');
+ pad_ostream_to_length(linebuf, TABLE_BREAKS[0]);
+ linebuf << "En";
+ if (m_sort_type == &cEnabledAscending) linebuf.put('\\');
+ else if (m_sort_type == &cEnabledDescending) linebuf.put('/');
+ pad_ostream_to_length(linebuf, TABLE_BREAKS[1]);
+ linebuf << "CPU";
+ if (m_sort_type == &cCpuAscending) linebuf.put('\\');
+ else if (m_sort_type == &cCpuDescending) linebuf.put('/');
+ pad_ostream_to_length(linebuf, TABLE_BREAKS[2]);
+ linebuf << "Condition";
+ if (m_sort_type == &cConditionAscending) linebuf.put('\\');
+ else if (m_sort_type == &cConditionDescending) linebuf.put('/');
+ pad_ostream_to_length(linebuf, TABLE_BREAKS[3]);
+ linebuf << "Action";
+ if (m_sort_type == &cActionAscending) linebuf.put('\\');
+ else if (m_sort_type == &cActionDescending) linebuf.put('/');
+ pad_ostream_to_length(linebuf, TABLE_BREAKS[4]);
+
+ auto const &text(linebuf.vec());
+ for (u32 i = m_topleft.x; i < (m_topleft.x + m_visible.x); i++, dest++)
+ {
+ dest->byte = (i < text.size()) ? text[i] : ' ';
+ dest->attrib = DCA_ANCILLARY;
+ }
+ }
+
+ for (int row = 1; row < m_visible.y; row++)
+ {
+ // Breakpoints
+ int rpi = row + m_topleft.y - 1;
+ if ((rpi < m_buffer.size()) && (rpi >= 0))
+ {
+ point_pair const &rpp = m_buffer[rpi];
+
+ linebuf.clear();
+ linebuf.rdbuf()->clear();
+ util::stream_format(linebuf, "%2X", rpp.second->index());
+ pad_ostream_to_length(linebuf, TABLE_BREAKS[0]);
+ linebuf.put(rpp.second->enabled() ? 'X' : 'O');
+ pad_ostream_to_length(linebuf, TABLE_BREAKS[1]);
+ linebuf << rpp.first->tag();
+ pad_ostream_to_length(linebuf, TABLE_BREAKS[2]);
+ linebuf << rpp.second->condition();
+ pad_ostream_to_length(linebuf, TABLE_BREAKS[3]);
+ linebuf << rpp.second->action();
+ pad_ostream_to_length(linebuf, TABLE_BREAKS[4]);
+
+ auto const &text(linebuf.vec());
+ for (u32 i = m_topleft.x; i < (m_topleft.x + m_visible.x); i++, dest++)
+ {
+ dest->byte = (i < text.size()) ? text[i] : ' ';
+ dest->attrib = DCA_NORMAL;
+
+ // Color disabled breakpoints red
+ if ((i >= TABLE_BREAKS[0]) && (i < TABLE_BREAKS[1]) && !rpp.second->enabled())
+ dest->attrib |= DCA_CHANGED;
+ }
+ }
+ else
+ {
+ // Fill the remaining vertical space
+ for (u32 i = m_topleft.x; i < (m_topleft.x + m_visible.x); i++, dest++)
+ {
+ dest->byte = ' ';
+ dest->attrib = DCA_NORMAL;
+ }
+ }
+ }
+}
diff --git a/src/emu/debug/dvrpoints.h b/src/emu/debug/dvrpoints.h
new file mode 100644
index 00000000000..307ccbc212e
--- /dev/null
+++ b/src/emu/debug/dvrpoints.h
@@ -0,0 +1,53 @@
+// license:BSD-3-Clause
+// copyright-holders:Vas Crabb
+/*********************************************************************
+
+ dvrpoints.h
+
+ Registerpoint debugger view.
+
+***************************************************************************/
+#ifndef MAME_EMU_DEBUG_DVRPOINTS_H
+#define MAME_EMU_DEBUG_DVRPOINTS_H
+
+#pragma once
+
+#include "debugcpu.h"
+#include "debugvw.h"
+
+#include <utility>
+#include <vector>
+
+
+//**************************************************************************
+// TYPE DEFINITIONS
+//**************************************************************************
+
+// debug view for breakpoints
+class debug_view_registerpoints : public debug_view
+{
+ friend class debug_view_manager;
+
+ // construction/destruction
+ debug_view_registerpoints(running_machine &machine, debug_view_osd_update_func osdupdate, void *osdprivate);
+ virtual ~debug_view_registerpoints();
+
+protected:
+ // view overrides
+ virtual void view_update() override;
+ virtual void view_click(int button, debug_view_xy const &pos) override;
+
+private:
+ using point_pair = std::pair<device_t *, debug_registerpoint const *>;
+
+ // internal helpers
+ void enumerate_sources();
+ void pad_ostream_to_length(std::ostream& str, int len);
+ void gather_registerpoints();
+
+ // internal state
+ bool (*m_sort_type)(point_pair const &, point_pair const &);
+ std::vector<point_pair> m_buffer;
+};
+
+#endif // MAME_EMU_DEBUG_DVBPOINTS_H
diff --git a/src/emu/debug/dvwpoints.cpp b/src/emu/debug/dvwpoints.cpp
index 76e74233988..21d3f30c5ca 100644
--- a/src/emu/debug/dvwpoints.cpp
+++ b/src/emu/debug/dvwpoints.cpp
@@ -1,5 +1,5 @@
// license:BSD-3-Clause
-// copyright-holders:Aaron Giles
+// copyright-holders:Andrew Gardner, Vas Crabb
/*********************************************************************
dvwpoints.cpp
@@ -10,6 +10,7 @@
#include "emu.h"
#include "dvwpoints.h"
+
#include "points.h"
#include <algorithm>
diff --git a/src/emu/debug/dvwpoints.h b/src/emu/debug/dvwpoints.h
index 753cbe62356..650a0aefad5 100644
--- a/src/emu/debug/dvwpoints.h
+++ b/src/emu/debug/dvwpoints.h
@@ -1,5 +1,5 @@
// license:BSD-3-Clause
-// copyright-holders:Aaron Giles
+// copyright-holders:Andrew Gardner, Vas Crabb
/*********************************************************************
dvwpoints.h
@@ -7,14 +7,13 @@
Watchpoint debugger view.
***************************************************************************/
-
#ifndef MAME_EMU_DEBUG_DVWPOINTS_H
#define MAME_EMU_DEBUG_DVWPOINTS_H
#pragma once
-#include "debugvw.h"
#include "debugcpu.h"
+#include "debugvw.h"
//**************************************************************************
diff --git a/src/emu/inpttype.ipp b/src/emu/inpttype.ipp
index db3b83b1a3a..8ceaf873e62 100644
--- a/src/emu/inpttype.ipp
+++ b/src/emu/inpttype.ipp
@@ -838,7 +838,7 @@ namespace {
INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_PAGE_DOWN, N_p("input-name", "UI Page Down"), input_seq(KEYCODE_PGDN) ) \
INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_FOCUS_NEXT, N_p("input-name", "UI Focus Next"), input_seq(KEYCODE_TAB, input_seq::not_code, KEYCODE_LSHIFT, input_seq::not_code, KEYCODE_RSHIFT) ) \
INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_FOCUS_PREV, N_p("input-name", "UI Focus Previous"), input_seq(KEYCODE_TAB, KEYCODE_LSHIFT, input_seq::or_code, KEYCODE_TAB, KEYCODE_RSHIFT) ) \
- INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_SELECT, N_p("input-name", "UI Select"), input_seq(KEYCODE_ENTER, input_seq::or_code, JOYCODE_BUTTON1_INDEXED(0), input_seq::or_code, KEYCODE_ENTER_PAD) ) \
+ INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_SELECT, N_p("input-name", "UI Select"), input_seq(KEYCODE_ENTER, input_seq::not_code, KEYCODE_LALT, input_seq::not_code, KEYCODE_RALT, input_seq::or_code, JOYCODE_BUTTON1_INDEXED(0), input_seq::or_code, KEYCODE_ENTER_PAD) ) \
INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_CANCEL, N_p("input-name", "UI Cancel"), input_seq(KEYCODE_ESC) ) \
INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_DISPLAY_COMMENT, N_p("input-name", "UI Display Comment"), input_seq(KEYCODE_SPACE) ) \
INPUT_PORT_DIGITAL_TYPE( 0, UI, UI_CLEAR, N_p("input-name", "UI Clear"), input_seq(KEYCODE_DEL) ) \
diff --git a/src/frontend/mame/mame.h b/src/frontend/mame/mame.h
index 037d714b39c..5fb5a2f4a81 100644
--- a/src/frontend/mame/mame.h
+++ b/src/frontend/mame/mame.h
@@ -92,5 +92,6 @@ private:
extern const char build_version[];
extern const char bare_build_version[];
+extern const char bare_vcs_revision[];
#endif // MAME_FRONTEND_MAME_MAME_H
diff --git a/src/frontend/mame/ui/about.cpp b/src/frontend/mame/ui/about.cpp
index b55267d1b96..bac2c3b4bdc 100644
--- a/src/frontend/mame/ui/about.cpp
+++ b/src/frontend/mame/ui/about.cpp
@@ -1,21 +1,23 @@
// license:BSD-3-Clause
-// copyright-holders:Ryan Holtz
+// copyright-holders:Vas Crabb
/***************************************************************************
ui/about.cpp
- "About" modal
+ About box
***************************************************************************/
#include "emu.h"
-
#include "ui/about.h"
+
#include "ui/ui.h"
#include "ui/utils.h"
#include "mame.h"
-#include "osdcore.h"
+
+#include <string_view>
+
namespace ui {
@@ -25,10 +27,9 @@ namespace {
} // anonymous namespace
-/**************************************************
-
- ABOUT MODAL
+/**************************************************
+ ABOUT BOX
**************************************************/
@@ -38,6 +39,8 @@ namespace {
menu_about::menu_about(mame_ui_manager &mui, render_container &container)
: menu(mui, container)
+ , m_title(util::string_format(_("%1$s %2$s"), emulator_info::get_appname(), bare_build_version))
+ , m_footer(util::string_format(_("Revision: %1$s"), bare_vcs_revision))
{
}
@@ -52,19 +55,174 @@ menu_about::~menu_about()
//-------------------------------------------------
-// populate - populates the about modal
+// perform our special rendering
//-------------------------------------------------
-void menu_about::populate(float &customtop, float &custombottom)
+void menu_about::custom_render(void *selectedref, float top, float bottom, float origx1, float origy1, float origx2, float origy2)
+{
+ std::string_view tempbuf[1];
+
+ // draw the title
+ tempbuf[0] = m_title;
+ draw_text_box(
+ std::begin(tempbuf), std::end(tempbuf),
+ origx1, origx2, origy1 - top, origy1 - ui().box_tb_border(),
+ text_layout::text_justify::CENTER, text_layout::word_wrapping::TRUNCATE, false,
+ ui().colors().text_color(), UI_GREEN_COLOR, 1.0f);
+
+ // draw the footer
+ tempbuf[0] = m_footer;
+ draw_text_box(
+ std::begin(tempbuf), std::end(tempbuf),
+ origx1, origx2, origy2 + ui().box_tb_border(), origy2 + bottom,
+ text_layout::text_justify::CENTER, text_layout::word_wrapping::NEVER, false,
+ ui().colors().text_color(), ui().colors().background_color(), 1.0f);
+}
+
+
+//-------------------------------------------------
+// draw - draw about
+//-------------------------------------------------
+
+void menu_about::draw(uint32_t flags)
{
- std::string title = string_format(_("%1$s %2$s"), emulator_info::get_appname(), bare_build_version);
- item_append(title, 0, nullptr);
- item_append(menu_item_type::SEPARATOR);
+ rgb_t const color = ui().colors().text_color();
+ float const aspect = machine().render().ui_aspect(&container());
+ float const line_height = ui().get_line_height();
+ float const ud_arrow_width = line_height * aspect;
+ float const gutter_width = 0.52f * line_height * aspect;
+ float const visible_width = 1.0f - (2.0f * ui().box_lr_border() * aspect);
+ float const visible_left = (1.0f - visible_width) * 0.5f;
+ float const extra_height = 2.0f * line_height;
+ float const visible_extra_menu_height = get_customtop() + get_custombottom() + extra_height;
+
+ // determine effective positions taking into account the hilighting arrows
+ float const maximum_width = visible_width - 2.0f * gutter_width;
+
+ draw_background();
+ map_mouse();
+
+ // account for extra space at the top and bottom
+ float visible_main_menu_height = 1.0f - 2.0f * ui().box_tb_border() - visible_extra_menu_height;
+ m_visible_lines = int(std::trunc(visible_main_menu_height / line_height));
+ visible_main_menu_height = float(m_visible_lines) * line_height;
+
+ // compute top/left of inner menu area by centering, if the menu is at the bottom of the extra, adjust
+ float const visible_top = ((1.0f - (visible_main_menu_height + visible_extra_menu_height)) * 0.5f) + get_customtop();
+
+ // lay out the text if necessary
+ if (!m_layout || (m_layout->width() != maximum_width))
+ {
+ m_layout.emplace(ui().create_layout(container(), maximum_width));
+ for (char const *const *line = copying_text; *line; ++line)
+ {
+ m_layout->add_text(*line, color);
+ m_layout->add_text("\n", color);
+ }
+ }
+ float const actual_width = m_layout->actual_width();
+
+ // compute text box size
+ float const x1 = visible_left + ((maximum_width - actual_width) * 0.5f);
+ float const y1 = visible_top - ui().box_tb_border();
+ float const x2 = visible_left + visible_width - ((maximum_width - actual_width) * 0.5f);
+ float const y2 = visible_top + visible_main_menu_height + ui().box_tb_border() + extra_height;
+ float const effective_left = x1 + gutter_width;
+ float const line_x0 = x1 + 0.5f * UI_LINE_WIDTH;
+ float const line_x1 = x2 - 0.5f * UI_LINE_WIDTH;
+ float const separator = visible_top + float(m_visible_lines) * line_height;
- for (char const *const *line = copying_text; *line; ++line)
- item_append(*line, 0, nullptr);
+ ui().draw_outlined_box(container(), x1, y1, x2, y2, ui().colors().background_color());
- item_append(menu_item_type::SEPARATOR);
+ int const visible_items = m_layout->lines();
+ m_visible_lines = (std::min)(visible_items, m_visible_lines);
+ top_line = (std::max)(0, top_line);
+ if (top_line + m_visible_lines >= visible_items)
+ top_line = visible_items - m_visible_lines;
+
+ clear_hover();
+ if (top_line)
+ {
+ // if we're on the top line, display the up arrow
+ rgb_t fgcolor = ui().colors().text_color();
+ if (mouse_in_rect(line_x0, visible_top, line_x1, visible_top + line_height))
+ {
+ fgcolor = ui().colors().mouseover_color();
+ highlight(
+ line_x0, visible_top,
+ line_x1, visible_top + line_height,
+ ui().colors().mouseover_bg_color());
+ set_hover(HOVER_ARROW_UP);
+ }
+ draw_arrow(
+ 0.5f * (x1 + x2) - 0.5f * ud_arrow_width, visible_top + 0.25f * line_height,
+ 0.5f * (x1 + x2) + 0.5f * ud_arrow_width, visible_top + 0.75f * line_height,
+ fgcolor, ROT0);
+ }
+ if ((top_line + m_visible_lines) < visible_items)
+ {
+ // if we're on the bottom line, display the down arrow
+ float const line_y = visible_top + float(m_visible_lines - 1) * line_height;
+ rgb_t fgcolor = ui().colors().text_color();
+ if (mouse_in_rect(line_x0, line_y, line_x1, line_y + line_height))
+ {
+ fgcolor = ui().colors().mouseover_color();
+ highlight(
+ line_x0, line_y,
+ line_x1, line_y + line_height,
+ ui().colors().mouseover_bg_color());
+ set_hover(HOVER_ARROW_DOWN);
+ }
+ draw_arrow(
+ 0.5f * (x1 + x2) - 0.5f * ud_arrow_width, line_y + 0.25f * line_height,
+ 0.5f * (x1 + x2) + 0.5f * ud_arrow_width, line_y + 0.75f * line_height,
+ fgcolor, ROT0 ^ ORIENTATION_FLIP_Y);
+ }
+
+ // return the number of visible lines, minus 1 for top arrow and 1 for bottom arrow
+ m_visible_items = m_visible_lines - (top_line ? 1 : 0) - (top_line + m_visible_lines != visible_items);
+ m_layout->emit(
+ container(),
+ top_line ? (top_line + 1) : 0, m_visible_items,
+ effective_left, visible_top + (top_line ? line_height : 0.0f));
+
+ // add visual separator before the "return to prevous menu" item
+ container().add_line(
+ x1, separator + (0.5f * line_height),
+ x2, separator + (0.5f * line_height),
+ UI_LINE_WIDTH, ui().colors().text_color(), PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA));
+
+ menu_item const &pitem = item(0);
+ std::string_view const itemtext = pitem.text;
+ float const line_y0 = separator + line_height;
+ float const line_y1 = line_y0 + line_height;
+
+ if (mouse_in_rect(line_x0, line_y0, line_x1, line_y1) && is_selectable(pitem))
+ set_hover(0);
+
+ highlight(line_x0, line_y0, line_x1, line_y1, ui().colors().selected_bg_color());
+ ui().draw_text_full(
+ container(), itemtext,
+ effective_left, line_y0, actual_width,
+ text_layout::text_justify::CENTER, text_layout::word_wrapping::TRUNCATE,
+ mame_ui_manager::NORMAL,
+ ui().colors().selected_color(), ui().colors().selected_bg_color(),
+ nullptr, nullptr);
+
+ // if there is something special to add, do it by calling the virtual method
+ custom_render(get_selection_ref(), get_customtop(), get_custombottom(), x1, y1, x2, y2);
+}
+
+
+//-------------------------------------------------
+// populate - populates the about modal
+//-------------------------------------------------
+
+void menu_about::populate(float &customtop, float &custombottom)
+{
+ // make space for the title and revision
+ customtop = ui().get_line_height() + 3.0f * ui().box_tb_border();
+ custombottom = ui().get_line_height() + 3.0f * ui().box_tb_border();
}
@@ -74,13 +232,35 @@ void menu_about::populate(float &customtop, float &custombottom)
void menu_about::handle()
{
- // process the menu
- const event *event = process(0);
-
- // process the event
- if (event && (event->iptkey == IPT_UI_SELECT))
+ const event *event = process(PROCESS_CUSTOM_NAV);
+ if (event)
{
- stack_pop();
+ switch (event->iptkey)
+ {
+ case IPT_UI_UP:
+ --top_line;
+ break;
+
+ case IPT_UI_DOWN:
+ ++top_line;
+ break;
+
+ case IPT_UI_PAGE_UP:
+ top_line -= m_visible_lines - 3;
+ break;
+
+ case IPT_UI_PAGE_DOWN:
+ top_line += m_visible_lines - 3;
+ break;
+
+ case IPT_UI_HOME:
+ top_line = 0;
+ break;
+
+ case IPT_UI_END:
+ top_line = m_layout->lines() - m_visible_lines;
+ break;
+ }
}
}
diff --git a/src/frontend/mame/ui/about.h b/src/frontend/mame/ui/about.h
index 2e68b7ed090..b96c7ee2055 100644
--- a/src/frontend/mame/ui/about.h
+++ b/src/frontend/mame/ui/about.h
@@ -1,10 +1,10 @@
// license:BSD-3-Clause
-// copyright-holders:Ryan Holtz
+// copyright-holders:Vas Crabb
/***************************************************************************
ui/about.h
- "About" modal
+ About box
***************************************************************************/
#ifndef MAME_FRONTEND_UI_ABOUT_H
@@ -14,7 +14,9 @@
#include "ui/menu.h"
-#include <vector>
+#include <optional>
+#include <string>
+
namespace ui {
@@ -24,9 +26,17 @@ public:
menu_about(mame_ui_manager &mui, render_container &container);
virtual ~menu_about() override;
+protected:
+ virtual void custom_render(void *selectedref, float top, float bottom, float x, float y, float x2, float y2) override;
+
private:
+ virtual void draw(uint32_t flags) override;
virtual void populate(float &customtop, float &custombottom) override;
virtual void handle() override;
+
+ std::string const m_title;
+ std::string const m_footer;
+ std::optional<text_layout> m_layout;
};
} // namespace ui
diff --git a/src/frontend/mame/ui/datmenu.cpp b/src/frontend/mame/ui/datmenu.cpp
index f25ece6015a..d77d3510e00 100644
--- a/src/frontend/mame/ui/datmenu.cpp
+++ b/src/frontend/mame/ui/datmenu.cpp
@@ -1,5 +1,5 @@
// license:BSD-3-Clause
-// copyright-holders:Maurizio Petrarota
+// copyright-holders:Maurizio Petrarota, Vas Crabb
/*********************************************************************
ui/datmenu.cpp
@@ -140,7 +140,7 @@ void menu_dats_view::add_info_text(text_layout &layout, std::string_view text, r
if (std::string_view::npos != split)
{
layout.add_text(line.substr(0, split), text_layout::text_justify::LEFT, color, rgb_t::transparent(), size);
- layout.add_text(" ", text_layout::text_layout::text_justify::LEFT, color, rgb_t::transparent(), size);
+ layout.add_text(" ", text_layout::text_justify::LEFT, color, rgb_t::transparent(), size);
layout.add_text(line.substr(split + 1), text_layout::text_justify::RIGHT, color, rgb_t::transparent(), size);
}
else
@@ -278,10 +278,13 @@ void menu_dats_view::draw(uint32_t flags)
if (!m_layout || (m_layout->width() != effective_width))
{
std::string buffer;
- if (m_issoft)
- get_data_sw(buffer);
- else
- get_data(buffer);
+ if (!m_items_list.empty())
+ {
+ if (m_issoft)
+ get_data_sw(buffer);
+ else
+ get_data(buffer);
+ }
m_layout.emplace(ui().create_layout(container(), effective_width));
add_info_text(*m_layout, buffer, ui().colors().text_color());
}
@@ -339,8 +342,8 @@ void menu_dats_view::draw(uint32_t flags)
// add visual separator before the "return to prevous menu" item
container().add_line(
- visible_left, separator + (0.5f * line_height),
- visible_left + visible_width, separator + (0.5f * line_height),
+ x1, separator + (0.5f * line_height),
+ x2, separator + (0.5f * line_height),
UI_LINE_WIDTH, ui().colors().text_color(), PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA));
menu_item const &pitem = item(0);
@@ -471,38 +474,41 @@ void menu_dats_view::custom_render(void *selectedref, float top, float bottom, f
}
// bottom
- std::string const revision(util::string_format(_("Revision: %1$s"), m_items_list[m_actual].revision));
- ui().draw_text_full(
- container(),
- revision,
- 0.0f, 0.0f, 1.0f,
- text_layout::text_justify::CENTER, text_layout::word_wrapping::TRUNCATE,
- mame_ui_manager::NONE, rgb_t::white(), rgb_t::black(),
- &width, nullptr);
- width += 2 * lr_border;
- maxwidth = std::max(origx2 - origx1, width);
+ if (!m_items_list.empty())
+ {
+ std::string const revision(util::string_format(_("Revision: %1$s"), m_items_list[m_actual].revision));
+ ui().draw_text_full(
+ container(),
+ revision,
+ 0.0f, 0.0f, 1.0f,
+ text_layout::text_justify::CENTER, text_layout::word_wrapping::TRUNCATE,
+ mame_ui_manager::NONE, rgb_t::white(), rgb_t::black(),
+ &width, nullptr);
+ width += 2 * lr_border;
+ maxwidth = std::max(origx2 - origx1, width);
- // compute our bounds
- x1 = 0.5f - 0.5f * maxwidth;
- x2 = x1 + maxwidth;
- y1 = origy2 + ui().box_tb_border();
- y2 = origy2 + bottom;
+ // compute our bounds
+ x1 = 0.5f - 0.5f * maxwidth;
+ x2 = x1 + maxwidth;
+ y1 = origy2 + ui().box_tb_border();
+ y2 = origy2 + bottom;
- // draw a box
- ui().draw_outlined_box(container(), x1, y1, x2, y2, UI_GREEN_COLOR);
+ // draw a box
+ ui().draw_outlined_box(container(), x1, y1, x2, y2, UI_GREEN_COLOR);
- // take off the borders
- x1 += lr_border;
- x2 -= lr_border;
- y1 += ui().box_tb_border();
+ // take off the borders
+ x1 += lr_border;
+ x2 -= lr_border;
+ y1 += ui().box_tb_border();
- // draw the text within it
- ui().draw_text_full(
- container(),
- revision,
- x1, y1, x2 - x1,
- text_layout::text_justify::CENTER, text_layout::word_wrapping::TRUNCATE,
- mame_ui_manager::NORMAL, ui().colors().text_color(), ui().colors().text_bg_color());
+ // draw the text within it
+ ui().draw_text_full(
+ container(),
+ revision,
+ x1, y1, x2 - x1,
+ text_layout::text_justify::CENTER, text_layout::word_wrapping::TRUNCATE,
+ mame_ui_manager::NORMAL, ui().colors().text_color(), ui().colors().text_bg_color());
+ }
}
//-------------------------------------------------
diff --git a/src/frontend/mame/ui/datmenu.h b/src/frontend/mame/ui/datmenu.h
index 33e3d160b84..ccc8bd8b2a4 100644
--- a/src/frontend/mame/ui/datmenu.h
+++ b/src/frontend/mame/ui/datmenu.h
@@ -1,5 +1,5 @@
// license:BSD-3-Clause
-// copyright-holders:Maurizio Petrarota
+// copyright-holders:Maurizio Petrarota, Vas Crabb
/***************************************************************************
ui/datmenu.h
@@ -76,4 +76,4 @@ private:
} // namespace ui
-#endif /* MAME_FRONTEND_UI_DATMENU_H */
+#endif // MAME_FRONTEND_UI_DATMENU_H
diff --git a/src/frontend/mame/ui/selmenu.cpp b/src/frontend/mame/ui/selmenu.cpp
index a66212c020b..303334de17b 100644
--- a/src/frontend/mame/ui/selmenu.cpp
+++ b/src/frontend/mame/ui/selmenu.cpp
@@ -855,18 +855,10 @@ void menu_select_launch::inkey_dats()
ui_software_info const *software;
ui_system_info const *system;
get_selection(software, system);
- if (software)
- {
- if (software->startempty && mame_machine_manager::instance()->lua()->call_plugin_check<const char *>("data_list", software->driver->name, true))
- menu::stack_push<menu_dats_view>(ui(), container(), system);
- else if (mame_machine_manager::instance()->lua()->call_plugin_check<const char *>("data_list", std::string(software->shortname).append(1, ',').append(software->listname).c_str()) || !software->infotext.empty())
- menu::stack_push<menu_dats_view>(ui(), container(), software);
- }
+ if (software && !software->startempty)
+ menu::stack_push<menu_dats_view>(ui(), container(), software);
else if (system)
- {
- if (mame_machine_manager::instance()->lua()->call_plugin_check<const char *>("data_list", system->driver->name, true))
- menu::stack_push<menu_dats_view>(ui(), container(), system);
- }
+ menu::stack_push<menu_dats_view>(ui(), container(), system);
}
@@ -1299,23 +1291,28 @@ void menu_select_launch::draw_toolbar(float x1, float y1, float x2, float y2)
x1 = (std::min)(backtrack_pos - (float(toolbar_count) * x_spacing), x1 + ((x2 - x1 - total_width) * 0.5f));
for (int z = 0; toolbar_count > z; ++z, x1 += x_spacing)
{
+ auto const bitmap = toolbar_bitmaps[z];
x2 = x1 + x_size;
color = rgb_t (0xffcccccc);
if (mouse_in_rect(x1, y1, x2, y2))
{
- set_hover(HOVER_B_FAV + toolbar_bitmaps[z]);
- color = rgb_t::white();
+ bool const need_selection = (TOOLBAR_BITMAP_FAVORITE == bitmap) || (TOOLBAR_BITMAP_INFO == bitmap);
+ if (!need_selection || get_selection_ptr())
+ {
+ set_hover(HOVER_B_FAV + bitmap);
+ color = rgb_t::white();
+ }
float ypos = y2 + ui().get_line_height() + 2.0f * ui().box_tb_border();
ui().draw_text_box(
container(),
- _(hover_msg[toolbar_bitmaps[z]]),
+ _(hover_msg[bitmap]),
text_layout::text_justify::CENTER, (x1 + x2) * 0.5f, ypos,
ui().colors().background_color());
}
container().add_quad(
x1, y1, x2, y2,
color,
- m_cache.toolbar_textures()[toolbar_bitmaps[z]].get(),
+ m_cache.toolbar_textures()[bitmap].get(),
PRIMFLAG_BLENDMODE(BLENDMODE_ALPHA));
}
}
diff --git a/src/mame/drivers/apple2e.cpp b/src/mame/drivers/apple2e.cpp
index 51524a2e4e8..aa6eb6eb452 100644
--- a/src/mame/drivers/apple2e.cpp
+++ b/src/mame/drivers/apple2e.cpp
@@ -1,5 +1,5 @@
-// copyright-holders:R. Belmont
// license:BSD-3-Clause
+// copyright-holders:R. Belmont
/***************************************************************************
apple2e.cpp - Apple IIe/IIc/IIc Plus and clones
diff --git a/src/osd/modules/debugger/osx/pointsviewer.mm b/src/osd/modules/debugger/osx/pointsviewer.mm
index 8bd4dad3a1b..ca3d9b356a0 100644
--- a/src/osd/modules/debugger/osx/pointsviewer.mm
+++ b/src/osd/modules/debugger/osx/pointsviewer.mm
@@ -10,6 +10,7 @@
#import "pointsviewer.h"
#import "breakpointsview.h"
+#import "registerpointsview.h"
#import "watchpointsview.h"
#include "util/xmlfile.h"
@@ -18,9 +19,9 @@
@implementation MAMEPointsViewer
- (id)initWithMachine:(running_machine &)m console:(MAMEDebugConsole *)c {
- MAMEDebugView *breakView, *watchView;
- NSScrollView *breakScroll, *watchScroll;
- NSTabViewItem *breakTab, *watchTab;
+ MAMEDebugView *breakView, *watchView, *registerView;
+ NSScrollView *breakScroll, *watchScroll, *registerScroll;
+ NSTabViewItem *breakTab, *watchTab, *registerTab;
NSPopUpButton *actionButton;
NSRect subviewFrame;
@@ -44,6 +45,9 @@
[[[subviewButton menu] addItemWithTitle:@"All Watchpoints"
action:NULL
keyEquivalent:@""] setTag:1];
+ [[[subviewButton menu] addItemWithTitle:@"All Registerpoints"
+ action:NULL
+ keyEquivalent:@""] setTag:2];
[subviewButton sizeToFit];
subviewFrame = [subviewButton frame];
subviewFrame.origin.x = subviewFrame.size.height;
@@ -82,7 +86,7 @@
[breakTab setView:breakScroll];
[breakScroll release];
- // create the breakpoints view
+ // create the watchpoints view
watchView = [[MAMEWatchpointsView alloc] initWithFrame:NSMakeRect(0, 0, 100, 100)
machine:*machine];
watchScroll = [[NSScrollView alloc] initWithFrame:[breakScroll frame]];
@@ -98,6 +102,22 @@
[watchTab setView:watchScroll];
[watchScroll release];
+ // create the registerpoints view
+ registerView = [[MAMERegisterpointsView alloc] initWithFrame:NSMakeRect(0, 0, 100, 100)
+ machine:*machine];
+ registerScroll = [[NSScrollView alloc] initWithFrame:[breakScroll frame]];
+ [registerScroll setAutoresizingMask:(NSViewWidthSizable | NSViewHeightSizable)];
+ [registerScroll setHasHorizontalScroller:YES];
+ [registerScroll setHasVerticalScroller:YES];
+ [registerScroll setAutohidesScrollers:YES];
+ [registerScroll setBorderType:NSNoBorder];
+ [registerScroll setDrawsBackground:NO];
+ [registerScroll setDocumentView:registerView];
+ [registerView release];
+ registerTab = [[NSTabViewItem alloc] initWithIdentifier:@""];
+ [registerTab setView:registerScroll];
+ [registerScroll release];
+
// create a tabless tabview for the two subviews
tabs = [[NSTabView alloc] initWithFrame:[breakScroll frame]];
[tabs setTabViewType:NSNoTabsNoBorder];
@@ -106,6 +126,8 @@
[breakTab release];
[tabs addTabViewItem:watchTab];
[watchTab release];
+ [tabs addTabViewItem:registerTab];
+ [registerTab release];
[[window contentView] addSubview:tabs];
[tabs release];
@@ -124,8 +146,12 @@
hasHorizontalScroller:YES
hasVerticalScroller:YES
borderType:[watchScroll borderType]];
- NSSize const desired = NSMakeSize(std::max(breakDesired.width, watchDesired.width),
- std::max(breakDesired.height, watchDesired.height));
+ NSSize const registerDesired = [NSScrollView frameSizeForContentSize:[registerView maximumFrameSize]
+ hasHorizontalScroller:YES
+ hasVerticalScroller:YES
+ borderType:[registerScroll borderType]];
+ NSSize const desired = NSMakeSize(std::max({ breakDesired.width, watchDesired.width, registerDesired.width }),
+ std::max({ breakDesired.height, watchDesired.height, registerDesired.height }));
[self cascadeWindowWithDesiredSize:desired forView:tabs];
// don't forget the result
diff --git a/src/osd/modules/debugger/osx/registerpointsview.h b/src/osd/modules/debugger/osx/registerpointsview.h
new file mode 100644
index 00000000000..58faf954416
--- /dev/null
+++ b/src/osd/modules/debugger/osx/registerpointsview.h
@@ -0,0 +1,23 @@
+// license:BSD-3-Clause
+// copyright-holders:Vas Crabb
+//============================================================
+//
+// registerpointsview.h - MacOS X Cocoa debug window handling
+//
+//============================================================
+
+#import "debugosx.h"
+
+#import "debugview.h"
+
+
+#import <Cocoa/Cocoa.h>
+
+
+@interface MAMERegisterpointsView : MAMEDebugView
+{
+}
+
+- (id)initWithFrame:(NSRect)f machine:(running_machine &)m;
+
+@end
diff --git a/src/osd/modules/debugger/osx/registerpointsview.mm b/src/osd/modules/debugger/osx/registerpointsview.mm
new file mode 100644
index 00000000000..a701fe733ce
--- /dev/null
+++ b/src/osd/modules/debugger/osx/registerpointsview.mm
@@ -0,0 +1,27 @@
+// license:BSD-3-Clause
+// copyright-holders:Vas Crabb
+//============================================================
+//
+// registerpointsview.m - MacOS X Cocoa debug window handling
+//
+//============================================================
+
+#import "registerpointsview.h"
+
+#include "debug/debugvw.h"
+
+
+@implementation MAMERegisterpointsView
+
+- (id)initWithFrame:(NSRect)f machine:(running_machine &)m {
+ if (!(self = [super initWithFrame:f type:DVT_REGISTER_POINTS machine:m wholeLineScroll:YES]))
+ return nil;
+ return self;
+}
+
+
+- (void)dealloc {
+ [super dealloc];
+}
+
+@end
diff --git a/src/osd/modules/debugger/qt/breakpointswindow.cpp b/src/osd/modules/debugger/qt/breakpointswindow.cpp
index 4f581137476..6af8fe7ba36 100644
--- a/src/osd/modules/debugger/qt/breakpointswindow.cpp
+++ b/src/osd/modules/debugger/qt/breakpointswindow.cpp
@@ -5,8 +5,6 @@
#include "debug/debugcon.h"
#include "debug/debugcpu.h"
-#include "debug/dvbpoints.h"
-#include "debug/dvwpoints.h"
#include <QtWidgets/QActionGroup>
#include <QtWidgets/QHBoxLayout>
@@ -48,16 +46,25 @@ BreakpointsWindow::BreakpointsWindow(running_machine &machine, QWidget *parent)
//
QActionGroup *typeGroup = new QActionGroup(this);
typeGroup->setObjectName("typegroup");
+
QAction *typeBreak = new QAction("Breakpoints", this);
typeBreak->setObjectName("typebreak");
+ typeBreak->setCheckable(true);
+ typeBreak->setActionGroup(typeGroup);
+ typeBreak->setShortcut(QKeySequence("Ctrl+1"));
+
QAction *typeWatch = new QAction("Watchpoints", this);
typeWatch->setObjectName("typewatch");
- typeBreak->setCheckable(true);
typeWatch->setCheckable(true);
- typeBreak->setActionGroup(typeGroup);
typeWatch->setActionGroup(typeGroup);
- typeBreak->setShortcut(QKeySequence("Ctrl+1"));
typeWatch->setShortcut(QKeySequence("Ctrl+2"));
+
+ QAction *typeRegister = new QAction("Registerpoints", this);
+ typeRegister->setObjectName("typeregister");
+ typeRegister->setCheckable(true);
+ typeRegister->setActionGroup(typeGroup);
+ typeRegister->setShortcut(QKeySequence("Ctrl+3"));
+
typeBreak->setChecked(true);
connect(typeGroup, &QActionGroup::triggered, this, &BreakpointsWindow::typeChanged);
@@ -89,6 +96,11 @@ void BreakpointsWindow::typeChanged(QAction* changedTo)
m_breakpointsView = new DebuggerView(DVT_WATCH_POINTS, m_machine, this);
setWindowTitle("Debug: All Watchpoints");
}
+ else if (changedTo->text() == "Registerpoints")
+ {
+ m_breakpointsView = new DebuggerView(DVT_REGISTER_POINTS, m_machine, this);
+ setWindowTitle("Debug: All Registerpoints");
+ }
// Re-register
QVBoxLayout *layout = findChild<QVBoxLayout *>("vlayout");
@@ -110,6 +122,8 @@ void BreakpointsWindowQtConfig::buildFromQWidget(QWidget *widget)
m_bwType = 0;
else if (typeGroup->checkedAction()->text() == "Watchpoints")
m_bwType = 1;
+ else if (typeGroup->checkedAction()->text() == "Registerpoints")
+ m_bwType = 2;
}
diff --git a/src/osd/modules/debugger/win/debugwininfo.h b/src/osd/modules/debugger/win/debugwininfo.h
index b930189fffa..80561dd2a05 100644
--- a/src/osd/modules/debugger/win/debugwininfo.h
+++ b/src/osd/modules/debugger/win/debugwininfo.h
@@ -97,6 +97,7 @@ protected:
ID_SHOW_BREAKPOINTS,
ID_SHOW_WATCHPOINTS,
+ ID_SHOW_REGISTERPOINTS,
ID_CLEAR_LOG,
diff --git a/src/osd/modules/debugger/win/pointswininfo.cpp b/src/osd/modules/debugger/win/pointswininfo.cpp
index eb2ca1875e2..93926a697ae 100644
--- a/src/osd/modules/debugger/win/pointswininfo.cpp
+++ b/src/osd/modules/debugger/win/pointswininfo.cpp
@@ -31,6 +31,7 @@ pointswin_info::pointswin_info(debugger_windows_interface &debugger) :
HMENU const optionsmenu = CreatePopupMenu();
AppendMenu(optionsmenu, MF_ENABLED, ID_SHOW_BREAKPOINTS, TEXT("Breakpoints\tCtrl+1"));
AppendMenu(optionsmenu, MF_ENABLED, ID_SHOW_WATCHPOINTS, TEXT("Watchpoints\tCtrl+2"));
+ AppendMenu(optionsmenu, MF_ENABLED, ID_SHOW_REGISTERPOINTS, TEXT("Registerpoints\tCtrl+3"));
AppendMenu(GetMenu(window()), MF_ENABLED | MF_POPUP, (UINT_PTR)optionsmenu, TEXT("Options"));
// compute a client rect
@@ -69,6 +70,10 @@ bool pointswin_info::handle_key(WPARAM wparam, LPARAM lparam)
case '2':
SendMessage(window(), WM_COMMAND, ID_SHOW_WATCHPOINTS, 0);
return true;
+
+ case '3':
+ SendMessage(window(), WM_COMMAND, ID_SHOW_REGISTERPOINTS, 0);
+ return true;
}
}
@@ -83,6 +88,7 @@ void pointswin_info::update_menu()
HMENU const menu = GetMenu(window());
CheckMenuItem(menu, ID_SHOW_BREAKPOINTS, MF_BYCOMMAND | (m_views[0]->type() == DVT_BREAK_POINTS ? MF_CHECKED : MF_UNCHECKED));
CheckMenuItem(menu, ID_SHOW_WATCHPOINTS, MF_BYCOMMAND | (m_views[0]->type() == DVT_WATCH_POINTS ? MF_CHECKED : MF_UNCHECKED));
+ CheckMenuItem(menu, ID_SHOW_REGISTERPOINTS, MF_BYCOMMAND | (m_views[0]->type() == DVT_REGISTER_POINTS ? MF_CHECKED : MF_UNCHECKED));
}
@@ -111,6 +117,15 @@ bool pointswin_info::handle_command(WPARAM wparam, LPARAM lparam)
win_set_window_text_utf8(window(), "All Watchpoints");
recompute_children();
return true;
+
+ case ID_SHOW_REGISTERPOINTS:
+ m_views[0].reset();
+ m_views[0].reset(new debugview_info(debugger(), *this, window(), DVT_REGISTER_POINTS));
+ if (!m_views[0]->is_valid())
+ m_views[0].reset();
+ win_set_window_text_utf8(window(), "All Registerpoints");
+ recompute_children();
+ return true;
}
break;
}