mirror of
https://github.com/holub/mame
synced 2025-06-06 04:43:45 +03:00
Still more user experience improvements:
Changed the default mapping for UI select to not trigger on Alt+Enter fullscreen toggle. (Fullscreen toggle still doesn't work in menus - actually fixing that is complicated.) frontend: Made the about box wrap text properly, made the title and backtrack menu item always visible, and added a footer with the VCS revision. frontend: Don't highlight the favourites and info toolbar buttons if there's no selection (can happen if filters produce no results). Also made the info viewer appear even if no info is available - it's less confusing to see an empty menu than wonder why clicking the button does nothing. debugger: Added a register points view to the GUI debuggers, to go with the breakpoints and watchpoints views. debugger: Extended [brw]p(clear|(en|dis)able) commands to accept multiple arguments to perform the same action on multiple (break|watch|register)points at once. Also made rplist accept a CPU for showing a single CPU's register points ([bw]plist already support this). docs: Updated registerpoints debugger commands page, and updated other pages for latest extensions to syntax.
This commit is contained in:
parent
0a82b82684
commit
40a30af10f
@ -75,10 +75,10 @@ Back to :ref:`debugger-breakpoint-list`
|
||||
bpclear
|
||||
-------
|
||||
|
||||
**bpclear [<bpnum>]**
|
||||
**bpclear [<bpnum>[,…]]**
|
||||
|
||||
Clear breakpoints. If **<bpnum>** is specified, the breakpoint it
|
||||
refers to will be cleared. If **<bpnum>** is not specified, all
|
||||
Clear breakpoints. If **<bpnum>** is specified, the breakpoints
|
||||
referred to will be cleared. If **<bpnum>** is not specified, all
|
||||
breakpoints will be cleared.
|
||||
|
||||
Examples:
|
||||
@ -96,10 +96,10 @@ Back to :ref:`debugger-breakpoint-list`
|
||||
bpdisable
|
||||
---------
|
||||
|
||||
**bpdisable [<bpnum>]**
|
||||
**bpdisable [<bpnum>[,…]]**
|
||||
|
||||
Disable breakpoints. If **<bpnum>** is specified, the breakpoint it
|
||||
refers to will be disabled. If **<bpnum>** is not specified, all
|
||||
Disable breakpoints. If **<bpnum>** is specified, the breakpoints
|
||||
referred to will be disabled. If **<bpnum>** is not specified, all
|
||||
breakpoints will be disabled.
|
||||
|
||||
Note that disabling a breakpoint does not delete it, it just temporarily
|
||||
@ -122,10 +122,10 @@ Back to :ref:`debugger-breakpoint-list`
|
||||
bpenable
|
||||
--------
|
||||
|
||||
**bpenable [<bpnum>]**
|
||||
**bpenable [<bpnum>[,…]]**
|
||||
|
||||
Enable breakpoints. If **<bpnum>** is specified, the breakpoint it
|
||||
refers to will be enabled. If **<bpnum>** is not specified, all
|
||||
Enable breakpoints. If **<bpnum>** is specified, the breakpoint
|
||||
referred to will be enabled. If **<bpnum>** is not specified, all
|
||||
breakpoints will be enabled.
|
||||
|
||||
Examples:
|
||||
|
@ -285,7 +285,7 @@ Back to :ref:`debugger-execution-list`
|
||||
ignore
|
||||
------
|
||||
|
||||
**ignore [<CPU>[,<CPU>[,...]]]**
|
||||
**ignore [<CPU>[,<CPU>[,…]]]**
|
||||
|
||||
Ignores the specified CPUs in the debugger. CPUs can be specified by
|
||||
tag or debugger CPU number (see :ref:`debugger-devicespec` for details).
|
||||
@ -316,7 +316,7 @@ Back to :ref:`debugger-execution-list`
|
||||
observe
|
||||
-------
|
||||
|
||||
**observe [<CPU>[,<CPU>[,...]]]**
|
||||
**observe [<CPU>[,<CPU>[,…]]]**
|
||||
|
||||
Allow interaction with the specified CPUs in the debugger. CPUs can be
|
||||
specified by tag or debugger CPU number (see :ref:`debugger-devicespec`
|
||||
|
@ -159,7 +159,7 @@ Back to :ref:`debugger-general-list`
|
||||
print
|
||||
-----
|
||||
|
||||
**print <item>[,...]**
|
||||
**print <item>[,…]**
|
||||
|
||||
The **print** command prints the results of one or more expressions to
|
||||
the debugger console as hexadecimal numbers.
|
||||
@ -180,7 +180,7 @@ Back to :ref:`debugger-general-list`
|
||||
printf
|
||||
------
|
||||
|
||||
**printf <format>[,<argument>[,...]]**
|
||||
**printf <format>[,<argument>[,…]]**
|
||||
|
||||
Prints a C-style formatted message to the debugger console. Only a
|
||||
very limited subset of format specifiers and escape sequences are
|
||||
@ -223,7 +223,7 @@ Back to :ref:`debugger-general-list`
|
||||
logerror
|
||||
--------
|
||||
|
||||
**logerror <format>[,<argument>[,...]]**
|
||||
**logerror <format>[,<argument>[,…]]**
|
||||
|
||||
Prints a C-style formatted message to the error log. See
|
||||
:ref:`debugger-command-printf` for details about the limited set of
|
||||
@ -246,7 +246,7 @@ Back to :ref:`debugger-general-list`
|
||||
tracelog
|
||||
--------
|
||||
|
||||
**tracelog <format>[,<argument>[,...]]**
|
||||
**tracelog <format>[,<argument>[,…]]**
|
||||
|
||||
Prints a C-style formatted message to the currently open trace file (see
|
||||
:ref:`debugger-command-trace` for more information). If no trace file
|
||||
@ -272,7 +272,7 @@ Back to :ref:`debugger-general-list`
|
||||
tracesym
|
||||
--------
|
||||
|
||||
**tracesym <item>[,...]**
|
||||
**tracesym <item>[,…]**
|
||||
|
||||
Prints the specified symbols to the currently open trace file (see
|
||||
:ref:`debugger-command-trace` for more information). If no trace file
|
||||
|
@ -64,7 +64,7 @@ Back to :ref:`debugger-memory-list`
|
||||
find
|
||||
----
|
||||
|
||||
**f[ind][{d|i|o}] <address>[:<space>],<length>[,<data>[,...]]**
|
||||
**f[ind][{d|i|o}] <address>[:<space>],<length>[,<data>[,…]]**
|
||||
|
||||
Search through memory for the specified sequence of data. The
|
||||
**<address>** is the address to begin searching from, optionally
|
||||
@ -113,7 +113,7 @@ Back to :ref:`debugger-memory-list`
|
||||
fill
|
||||
----
|
||||
|
||||
**fill[{d|i|o}] <address>[:<space>],<length>[,<data>[,...]]**
|
||||
**fill[{d|i|o}] <address>[:<space>],<length>[,<data>[,…]]**
|
||||
|
||||
Overwrite a block of memory with copies of the supplied data sequence.
|
||||
The **<address>** specifies the address to begin writing at, optionally
|
||||
|
@ -1,120 +1,146 @@
|
||||
.. _debugger-registerpoints-list:
|
||||
|
||||
Registerpoints Debugger Commands
|
||||
Registerpoint Debugger Commands
|
||||
================================
|
||||
|
||||
|
||||
You can also type **help <command>** for further details on each command in the MAME Debugger interface.
|
||||
|
||||
| :ref:`debugger-command-rpset` -- sets a registerpoint to trigger on <condition>
|
||||
| :ref:`debugger-command-rpclear` -- clears a given registerpoint or all if no <rpnum> specified
|
||||
| :ref:`debugger-command-rpdisable` -- disabled a given registerpoint or all if no <rpnum> specified
|
||||
| :ref:`debugger-command-rpenable` -- enables a given registerpoint or all if no <rpnum> specified
|
||||
| :ref:`debugger-command-rplist` -- lists all the registerpoints
|
||||
:ref:`debugger-command-rpset`
|
||||
sets a registerpoint to trigger on a condition
|
||||
:ref:`debugger-command-rpclear`
|
||||
clears registerpoints
|
||||
:ref:`debugger-command-rpdisable`
|
||||
disables a registerpoint
|
||||
:ref:`debugger-command-rpenable`
|
||||
enables registerpoints
|
||||
:ref:`debugger-command-rplist`
|
||||
lists registerpoints
|
||||
|
||||
|
||||
|
||||
.. _debugger-command-rpset:
|
||||
.. _debugger-command-rpset:
|
||||
|
||||
rpset
|
||||
-----
|
||||
|
||||
| **rp[set] {<condition>}[,<action>]]**
|
||||
|
|
||||
| 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.
|
||||
| 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.
|
||||
|
|
||||
| Examples:
|
||||
|
|
||||
| rp {PC==0150}
|
||||
|
|
||||
| Set a registerpoint that will halt execution whenever the PC register equals 0x150.
|
||||
|
|
||||
| temp0=0; rp {PC==0150},{temp0++; g}
|
||||
|
|
||||
| Set a registerpoint that will increment the variable temp0 whenever the PC register equals 0x0150.
|
||||
|
|
||||
| rp {temp0==5}
|
||||
|
|
||||
| Set a registerpoint that will halt execution whenever the temp0 variable equals 5.
|
||||
|
|
||||
| Back to :ref:`debugger-registerpoints-list`
|
||||
**rp[set] <condition>[,<action>]**
|
||||
|
||||
Sets a new registerpoint which will be triggered when the expression
|
||||
supplied as the **<condition>** evaluates to true (non-zero). Note that
|
||||
the condition may need to be surrounded with braces ``{ }`` to prevent
|
||||
it from being interpreted as an assignment. The optional **<action>**
|
||||
parameter provides a command to be executed whenever the registerpoint
|
||||
is triggered. Note that you may need to surround the action with braces
|
||||
``{ }`` to ensure commas and semicolons within the command are not
|
||||
interpreted in the context of the ``rpset`` command itself.
|
||||
|
||||
Each registerpoint that is set is assigned a numeric index which can be
|
||||
used to refer to it in other registerpoint commands. Registerpoint
|
||||
indices are unique throughout a session.
|
||||
|
||||
Examples:
|
||||
|
||||
``rp {PC==150}``
|
||||
Set a registerpoint that will halt execution whenever the **PC**
|
||||
register equals 150.
|
||||
``temp0=0; rp {PC==150},{temp0++; g}``
|
||||
Set a registerpoint that will increment the variable **temp0**
|
||||
whenever the **PC** register equals 150.
|
||||
``rp {temp0==5}``
|
||||
Set a registerpoint that will halt execution whenever the **temp0**
|
||||
variable equals 5.
|
||||
|
||||
Back to :ref:`debugger-registerpoints-list`
|
||||
|
||||
|
||||
.. _debugger-command-rpclear:
|
||||
.. _debugger-command-rpclear:
|
||||
|
||||
rpclear
|
||||
-------
|
||||
|
||||
| **rpclear [<rpnum>]**
|
||||
|
|
||||
| The rpclear command clears a registerpoint. If <rpnum> is specified, only the requested registerpoint is cleared, otherwise all registerpoints are cleared.
|
||||
|
|
||||
| Examples:
|
||||
|
|
||||
| rpclear 3
|
||||
|
|
||||
| Clear registerpoint index 3.
|
||||
|
|
||||
| rpclear
|
||||
|
|
||||
| Clear all registerpoints.
|
||||
|
|
||||
| Back to :ref:`debugger-registerpoints-list`
|
||||
**rpclear [<rpnum>,[,…]]**
|
||||
|
||||
Clears registerpoints. If **<rpnum>** is specified, the registerpoints
|
||||
referred to will be cleared. If **<rpnum>** is not specified, all
|
||||
registerpoints will be cleared.
|
||||
|
||||
Examples:
|
||||
|
||||
``rpclear 3``
|
||||
Clear the registerpoint with index 3.
|
||||
``rpclear``
|
||||
Clear all registerpoints.
|
||||
|
||||
Back to :ref:`debugger-registerpoints-list`
|
||||
|
||||
|
||||
.. _debugger-command-rpdisable:
|
||||
.. _debugger-command-rpdisable:
|
||||
|
||||
rpdisable
|
||||
---------
|
||||
|
||||
| **rpdisable [<rpnum>]**
|
||||
|
|
||||
| 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.
|
||||
|
|
||||
| Examples:
|
||||
|
|
||||
| rpdisable 3
|
||||
|
|
||||
| Disable registerpoint index 3.
|
||||
|
|
||||
| rpdisable
|
||||
|
|
||||
| Disable all registerpoints.
|
||||
|
|
||||
| Back to :ref:`debugger-registerpoints-list`
|
||||
**rpdisable [<rpnum>[,…]]**
|
||||
|
||||
Disables registerpoints. If **<rpnum>** is specified, the
|
||||
registerpoints referred to will be disabled. If **<rpnum>** is not
|
||||
specified, all registerpoints will be disabled.
|
||||
|
||||
Note that disabling a registerpoint does not delete it, it just
|
||||
temporarily marks the registerpoint as inactive. Disabled
|
||||
registerpoints will not cause execution to halt, their condition
|
||||
expressions will not be evaluated, and their associated commands will
|
||||
not be executed.
|
||||
|
||||
Examples:
|
||||
|
||||
``rpdisable 3``
|
||||
Disable the registerpoint with index 3.
|
||||
``rpdisable``
|
||||
Disable all registerpoints.
|
||||
|
||||
Back to :ref:`debugger-registerpoints-list`
|
||||
|
||||
|
||||
.. _debugger-command-rpenable:
|
||||
.. _debugger-command-rpenable:
|
||||
|
||||
rpenable
|
||||
--------
|
||||
|
||||
| **rpenable [<rpnum>]**
|
||||
|
|
||||
| The rpenable command enables a registerpoint. If <rpnum> is specified, only the requested registerpoint is enabled, otherwise all registerpoints are enabled.
|
||||
|
|
||||
| Examples:
|
||||
|
|
||||
| rpenable 3
|
||||
|
|
||||
| Enable registerpoint index 3.
|
||||
|
|
||||
| rpenable
|
||||
|
|
||||
| Enable all registerpoints.
|
||||
|
|
||||
| Back to :ref:`debugger-registerpoints-list`
|
||||
**rpenable [<rpnum>[,…]]**
|
||||
|
||||
Enables registerpoints. If **<rpnum>** is specified, the registerpoints
|
||||
referred to will be enabled. If **<rpnum>** is not specified, all
|
||||
registerpoints will be enabled.
|
||||
|
||||
Examples:
|
||||
|
||||
``rpenable 3``
|
||||
Enable the registerpoint with index 3.
|
||||
``rpenable``
|
||||
Enable all registerpoints.
|
||||
|
||||
Back to :ref:`debugger-registerpoints-list`
|
||||
|
||||
|
||||
.. _debugger-command-rplist:
|
||||
.. _debugger-command-rplist:
|
||||
|
||||
rplist
|
||||
------
|
||||
|
||||
| **rplist**
|
||||
|
|
||||
| The rplist command lists all the current registerpoints, along with their index and any actions attached to them.
|
||||
|
|
||||
| Back to :ref:`debugger-registerpoints-list`
|
||||
**rplist [<CPU>]**
|
||||
|
||||
List current registerpoints, along with their indices and conditions,
|
||||
and any associated actions actions. If no **<CPU>** is specified,
|
||||
registerpoints for all CPUs in the system will be listed; if a **<CPU>**
|
||||
is specified, only registerpoints for that CPU will be listed. The
|
||||
**<CPU>** can be specified by tag or by debugger CPU number (see
|
||||
:ref:`debugger-devicespec` for details).
|
||||
|
||||
Examples:
|
||||
|
||||
``rplist``
|
||||
List all registerpoints.
|
||||
``rplist .``
|
||||
List all registerpoints for the visible CPU.
|
||||
``rplist maincpu``
|
||||
List all registerpoints for the CPU with the absolute tag path
|
||||
``:maincpu``.
|
||||
|
||||
Back to :ref:`debugger-registerpoints-list`
|
||||
|
@ -83,10 +83,10 @@ Back to :ref:`debugger-watchpoints-list`
|
||||
wpclear
|
||||
-------
|
||||
|
||||
**wpclear [<wpnum>]**
|
||||
**wpclear [<wpnum>[,…]]**
|
||||
|
||||
Clear watchpoints. If **<wpnum>** is specified, the watchpoint it
|
||||
refers to will be cleared. If **<wpnum>** is not specified, all
|
||||
Clear watchpoints. If **<wpnum>** is specified, the watchpoints
|
||||
referred to will be cleared. If **<wpnum>** is not specified, all
|
||||
watchpoints will be cleared.
|
||||
|
||||
Examples:
|
||||
@ -104,10 +104,10 @@ Back to :ref:`debugger-watchpoints-list`
|
||||
wpdisable
|
||||
---------
|
||||
|
||||
**wpdisable [<wpnum>]**
|
||||
**wpdisable [<wpnum>[,…]]**
|
||||
|
||||
Disable watchpoints. If **<wpnum>** is specified, the watchpoint it
|
||||
refers to will be disabled. If **<wpnum>** is not specified, all
|
||||
Disable watchpoints. If **<wpnum>** is specified, the watchpoints
|
||||
referred to will be disabled. If **<wpnum>** is not specified, all
|
||||
watchpoints will be disabled.
|
||||
|
||||
Note that disabling a watchpoint does not delete it, it just temporarily
|
||||
@ -130,10 +130,10 @@ Back to :ref:`debugger-watchpoints-list`
|
||||
wpenable
|
||||
--------
|
||||
|
||||
**wpenable [<wpnum>]**
|
||||
**wpenable [<wpnum>[,…]]**
|
||||
|
||||
Enable watchpoints. If **<wpnum>** is specified, the watchpoint it
|
||||
refers to will be enabled. If **<wpnum>** is not specified, all
|
||||
Enable watchpoints. If **<wpnum>** is specified, the watchpoints
|
||||
referred to will be enabled. If **<wpnum>** is not specified, all
|
||||
watchpoints will be enabled.
|
||||
|
||||
Examples:
|
||||
|
12
makefile
12
makefile
@ -1073,7 +1073,7 @@ endif
|
||||
ifneq ($(GIT_AVAILABLE),git)
|
||||
IGNORE_GIT := 1
|
||||
endif
|
||||
ifeq ($(wildcard .git/*),)
|
||||
ifeq ($(filter .git,$(wildcard .*)),)
|
||||
IGNORE_GIT := 1
|
||||
endif
|
||||
|
||||
@ -1757,17 +1757,23 @@ endif
|
||||
ifeq (posix,$(SHELLTYPE))
|
||||
$(GENDIR)/version.cpp: makefile $(GENDIR)/git_desc | $(GEN_FOLDERS)
|
||||
@echo '#define BARE_BUILD_VERSION "0.236"' > $@
|
||||
@echo '#define BARE_VCS_REVISION "$(NEW_GIT_VERSION)"' >> $@
|
||||
@echo 'extern const char bare_build_version[];' >> $@
|
||||
@echo 'extern const char bare_vcs_revision[];' >> $@
|
||||
@echo 'extern const char build_version[];' >> $@
|
||||
@echo 'const char bare_build_version[] = BARE_BUILD_VERSION;' >> $@
|
||||
@echo 'const char build_version[] = BARE_BUILD_VERSION " ($(NEW_GIT_VERSION))";' >> $@
|
||||
@echo 'const char bare_vcs_revision[] = BARE_VCS_REVISION;' >> $@
|
||||
@echo 'const char build_version[] = BARE_BUILD_VERSION " (" BARE_VCS_REVISION ")";' >> $@
|
||||
else
|
||||
$(GENDIR)/version.cpp: makefile $(GENDIR)/git_desc | $(GEN_FOLDERS)
|
||||
@echo #define BARE_BUILD_VERSION "0.236" > $@
|
||||
@echo #define BARE_VCS_REVISION "$(NEW_GIT_VERSION)" >> $@
|
||||
@echo extern const char bare_build_version[]; >> $@
|
||||
@echo extern const char bare_vcs_revision[]; >> $@
|
||||
@echo extern const char build_version[]; >> $@
|
||||
@echo const char bare_build_version[] = BARE_BUILD_VERSION; >> $@
|
||||
@echo const char build_version[] = BARE_BUILD_VERSION " ($(NEW_GIT_VERSION))"; >> $@
|
||||
@echo const char bare_vcs_revision[] = BARE_VCS_REVISION; >> $@
|
||||
@echo const char build_version[] = BARE_BUILD_VERSION " (" BARE_VCS_REVISION ")"; >> $@
|
||||
endif
|
||||
|
||||
|
||||
|
@ -238,6 +238,8 @@ files {
|
||||
MAME_DIR .. "src/emu/debug/dvmemory.h",
|
||||
MAME_DIR .. "src/emu/debug/dvbpoints.cpp",
|
||||
MAME_DIR .. "src/emu/debug/dvbpoints.h",
|
||||
MAME_DIR .. "src/emu/debug/dvrpoints.cpp",
|
||||
MAME_DIR .. "src/emu/debug/dvrpoints.h",
|
||||
MAME_DIR .. "src/emu/debug/dvwpoints.cpp",
|
||||
MAME_DIR .. "src/emu/debug/dvwpoints.h",
|
||||
MAME_DIR .. "src/emu/debug/dvstate.cpp",
|
||||
|
@ -108,6 +108,8 @@ project ("osd_" .. _OPTIONS["osd"])
|
||||
MAME_DIR .. "src/osd/modules/debugger/osx/memoryviewer.h",
|
||||
MAME_DIR .. "src/osd/modules/debugger/osx/pointsviewer.mm",
|
||||
MAME_DIR .. "src/osd/modules/debugger/osx/pointsviewer.h",
|
||||
MAME_DIR .. "src/osd/modules/debugger/osx/registerpointsview.mm",
|
||||
MAME_DIR .. "src/osd/modules/debugger/osx/registerpointsview.h",
|
||||
MAME_DIR .. "src/osd/modules/debugger/osx/registersview.mm",
|
||||
MAME_DIR .. "src/osd/modules/debugger/osx/registersview.h",
|
||||
MAME_DIR .. "src/osd/modules/debugger/osx/watchpointsview.mm",
|
||||
|
@ -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));
|
||||
@ -1070,6 +1070,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 ¶ms, 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 ¶m : 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> ¶ms)
|
||||
|
||||
void debugger_commands::execute_bpclear(const std::vector<std::string> ¶ms)
|
||||
{
|
||||
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
|
||||
else // otherwise, clear the specific ones
|
||||
{
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
bool found = false;
|
||||
for (device_t &device : device_enumerator(m_machine.root_device()))
|
||||
if (device.debug()->breakpoint_clear(bpindex))
|
||||
{
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
if (found)
|
||||
m_console.printf("Breakpoint %X cleared\n", u32(bpindex));
|
||||
else
|
||||
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> ¶ms)
|
||||
|
||||
void debugger_commands::execute_bpdisenable(bool enable, const std::vector<std::string> ¶ms)
|
||||
{
|
||||
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");
|
||||
m_console.printf(enable ? "Enabled all breakpoints\n" : "Disabled all breakpoints\n");
|
||||
}
|
||||
else if (!validate_number_parameter(params[0], bpindex)) // otherwise, disable/enable the specific one
|
||||
else // otherwise, disable/enable the specific ones
|
||||
{
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
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> ¶ms)
|
||||
{
|
||||
u64 wpindex;
|
||||
|
||||
/* if 0 parameters, clear all */
|
||||
if (params.empty())
|
||||
if (params.empty()) // if no parameters, clear all
|
||||
{
|
||||
for (device_t &device : device_enumerator(m_machine.root_device()))
|
||||
device.debug()->watchpoint_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> ¶ms)
|
||||
|
||||
void debugger_commands::execute_wpdisenable(bool enable, const std::vector<std::string> ¶ms)
|
||||
{
|
||||
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");
|
||||
m_console.printf(enable ? "Enabled all watchpoints\n" : "Disabled all watchpoints\n");
|
||||
}
|
||||
else if (!validate_number_parameter(params[0], wpindex)) // otherwise, clear the specific one
|
||||
else // otherwise, disable/enable the specific ones
|
||||
{
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
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> ¶ms)
|
||||
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> ¶ms)
|
||||
|
||||
void debugger_commands::execute_rpclear(const std::vector<std::string> ¶ms)
|
||||
{
|
||||
u64 rpindex;
|
||||
|
||||
/* if 0 parameters, clear all */
|
||||
if (params.empty())
|
||||
if (params.empty()) // if no parameters, clear all
|
||||
{
|
||||
for (device_t &device : device_enumerator(m_machine.root_device()))
|
||||
device.debug()->registerpoint_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> ¶ms)
|
||||
|
||||
void debugger_commands::execute_rpdisenable(bool enable, const std::vector<std::string> ¶ms)
|
||||
{
|
||||
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");
|
||||
m_console.printf(enable ? "Enabled all registerpoints\n" : "Disabled all registerpoints\n");
|
||||
}
|
||||
else if (!validate_number_parameter(params[0], rpindex)) // otherwise, clear the specific one
|
||||
else // otherwise, disable/enable the specific ones
|
||||
{
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
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> ¶ms)
|
||||
{
|
||||
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());
|
||||
|
||||
if (printed == 0)
|
||||
m_console.printf("No registerpoints currently installed\n");
|
||||
// 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 (!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");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -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 ¶ms, T &&apply, char const *unused_message);
|
||||
|
||||
void execute_help(const std::vector<std::string> ¶ms);
|
||||
void execute_print(const std::vector<std::string> ¶ms);
|
||||
|
@ -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"
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -34,7 +34,8 @@ enum debug_view_type
|
||||
DVT_MEMORY,
|
||||
DVT_LOG,
|
||||
DVT_BREAK_POINTS,
|
||||
DVT_WATCH_POINTS
|
||||
DVT_WATCH_POINTS,
|
||||
DVT_REGISTER_POINTS
|
||||
};
|
||||
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
// license:BSD-3-Clause
|
||||
// copyright-holders:Aaron Giles
|
||||
// copyright-holders:Andrew Gardner, Vas Crabb
|
||||
/*********************************************************************
|
||||
|
||||
dvbpoints.cpp
|
||||
|
@ -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;
|
||||
|
298
src/emu/debug/dvrpoints.cpp
Normal file
298
src/emu/debug/dvrpoints.cpp
Normal file
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
53
src/emu/debug/dvrpoints.h
Normal file
53
src/emu/debug/dvrpoints.h
Normal file
@ -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
|
@ -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>
|
||||
|
@ -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"
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
|
@ -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) ) \
|
||||
|
@ -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
|
||||
|
@ -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))
|
||||
{
|
||||
}
|
||||
|
||||
@ -51,20 +54,175 @@ menu_about::~menu_about()
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// perform our special rendering
|
||||
//-------------------------------------------------
|
||||
|
||||
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)
|
||||
{
|
||||
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;
|
||||
|
||||
ui().draw_outlined_box(container(), x1, y1, x2, y2, ui().colors().background_color());
|
||||
|
||||
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)
|
||||
{
|
||||
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);
|
||||
|
||||
for (char const *const *line = copying_text; *line; ++line)
|
||||
item_append(*line, 0, nullptr);
|
||||
|
||||
item_append(menu_item_type::SEPARATOR);
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
|
@ -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
|
||||
|
@ -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));
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
23
src/osd/modules/debugger/osx/registerpointsview.h
Normal file
23
src/osd/modules/debugger/osx/registerpointsview.h
Normal file
@ -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
|
27
src/osd/modules/debugger/osx/registerpointsview.mm
Normal file
27
src/osd/modules/debugger/osx/registerpointsview.mm
Normal file
@ -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
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
@ -97,6 +97,7 @@ protected:
|
||||
|
||||
ID_SHOW_BREAKPOINTS,
|
||||
ID_SHOW_WATCHPOINTS,
|
||||
ID_SHOW_REGISTERPOINTS,
|
||||
|
||||
ID_CLEAR_LOG,
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user