mirror of
https://github.com/holub/mame
synced 2025-05-01 12:16:56 +03:00

Extended the memory access prefixes in debugger expressions to support address space names. Made the debugger history command aware of how much history it has collected, and added a help topic for it to the built-in debugger help. Started updating the documentation for the web site, and corrected some of the more misleading built-in debugger help. Made some corrections to Chinese localisation after discussion with YuiFAN. Darkened the UI red colour a little. cpu/m6502/st2205u.h: Marked sound imperfect.
355 lines
12 KiB
ReStructuredText
355 lines
12 KiB
ReStructuredText
.. _debugger:
|
||
|
||
MAME Debugger
|
||
=============
|
||
|
||
.. contents:: :local:
|
||
|
||
|
||
.. _debugger-intro:
|
||
|
||
Introduction
|
||
------------
|
||
|
||
MAME includes an interactive low-level debugger that target the emulated
|
||
system. This can be a useful tool for diagnosing emulation issues,
|
||
developing software to run on vintage systems, creating cheats, ROM
|
||
hacking, or just looking at how software works.
|
||
|
||
Use the ``-debug`` command line option to start MAME with the debugger
|
||
activated. By default, pressing the tilde (**~**) during emulation
|
||
breaks into the debugger.
|
||
|
||
The exact appearance of the debugger depends on your operating system
|
||
and the options MAME was built with. All variants of the debugger
|
||
provide a multi-window interface for viewing the contents of memory and
|
||
disassembled code.
|
||
|
||
The debugger console window is a special window that shows the contents
|
||
of CPU registers and disassembled code around the current program
|
||
counter address, and provides a command-line interface to most of the
|
||
debugging functionality.
|
||
|
||
|
||
.. _debugger-sections-list:
|
||
|
||
Debugger commands
|
||
-----------------
|
||
|
||
Debugger commands are described in the sections below. You can also
|
||
type **help <topic>** in the debugger console, where **<topic>** is the
|
||
name of a command, to see documentation directly in MAME.
|
||
|
||
.. toctree::
|
||
:titlesonly:
|
||
|
||
general
|
||
memory
|
||
execution
|
||
breakpoint
|
||
watchpoint
|
||
registerpoints
|
||
annotation
|
||
cheats
|
||
image
|
||
|
||
|
||
.. _debugger-devicespec:
|
||
|
||
Specifying devices and address spaces
|
||
-------------------------------------
|
||
|
||
Many debugger commands accept parameters specifying which device to
|
||
operate on. If a device is not specified explicitly, the CPU currently
|
||
visible in the debugger is used. Devices can be specified by tag, or by
|
||
CPU number:
|
||
|
||
* Tags are the colon-separated paths that MAME uses to identify devices
|
||
within a system. You see them in options for configuring slot
|
||
devices, in debugger disassembly and memory viewer source lists, and
|
||
various other places within MAME’s UI.
|
||
* CPU numbers are monotonically incrementing numbers that the debugger
|
||
assigns to CPU-like devices within a system, starting at zero. The
|
||
**cpunum** symbol holds the CPU number for the currently visible CPU
|
||
in the debugger (you can see it by entering the command
|
||
**print cpunum** in the debugger console).
|
||
|
||
If a tag starts with a caret (**^**) or dot (**.**), it is interpreted
|
||
relative to the CPU currently visible in the debugger, otherwise it is
|
||
interpreted relative to the root machine device. If a device argument
|
||
is ambiguously valid as both a tag and a CPU number, it will be
|
||
interpreted as a tag.
|
||
|
||
Examples:
|
||
|
||
``maincpu``
|
||
The device with the absolute tag ``:maincpu``.
|
||
``^melodypsg``
|
||
The sibling device of the visible CPU with the tag ``melodypsg``.
|
||
``.:adc``
|
||
The child device of the visible CPU with the tag ``adc``.
|
||
``2``
|
||
The third CPU-like device in the system (zero-based index).
|
||
|
||
Commands that operate on memory extend this by allowing the device tag
|
||
or CPU number to be optionally followed by an address space identifier.
|
||
Address space identifiers are tag-like strings. You can see them in
|
||
debugger memory viewer source lists. If the address space identifier is
|
||
omitted, a default address space will be used. Usually, this is the
|
||
address space that appears first for the device. Many commands have
|
||
variants with **d**, **i** and **o** (data, I/O and opcodes) suffixes
|
||
that default to the address spaces at indices 1, 2 and 3, respectively,
|
||
as these have special significance for CPU-like devices.
|
||
|
||
In ambiguous cases, the default address space of a child device will be
|
||
used rather than a specific address space.
|
||
|
||
Examples:
|
||
|
||
``ram``
|
||
The default address space of the device with the absolute tag
|
||
``:ram``, or the ``ram`` space of the visible CPU.
|
||
``.:io``
|
||
The default address space of the child device of the visible CPU
|
||
with the tag ``io``, or the ``io`` space of the visible CPU.
|
||
``:program``
|
||
The default address space of the device with the absolute tag
|
||
``:program``, or the ``program`` space of the root machine device.
|
||
``^vdp``
|
||
The default address space of the sibling device of the visible CPU
|
||
with the tag ``vdp``.
|
||
``^:data``
|
||
The default address space of the sibling device of the visible CPU
|
||
with the tag ``data``, or the ``data`` space of the parent device
|
||
of the visible CPU.
|
||
``1:rom``
|
||
The default address space of the child device of the second CPU in
|
||
the system (zero-based index) with the tag ``rom``, or the ``rom``
|
||
space of the second CPU in the system.
|
||
``2``
|
||
The default address space of the third CPU-like device in the system
|
||
(zero-based index).
|
||
|
||
If a command takes an emulated memory address as a parameter, the
|
||
address may optionally be followed by an address space specification, as
|
||
described above.
|
||
|
||
Examples:
|
||
|
||
``0220``
|
||
Address 0220 in the default address space for the visible CPU.
|
||
``0378:io``
|
||
Address 0378 in the default address space of the device with the
|
||
absolute tag ``:io``, or the ``io`` space of the visible CPU.
|
||
``1234:.:rom``
|
||
Address 1234 in the default address space of the child device of the
|
||
visible CPU with the tag ``:rom``, or the ``rom`` space of the
|
||
visible CPU.
|
||
``1260:^vdp``
|
||
Address 1260 in the default address space of the sibling device of
|
||
the visible CPU with the tag ``vdp``.
|
||
``8008:^:data``
|
||
Address 8008 in the default address space of the sibling device of
|
||
the visible CPU with the tag ``data``, or the ``data`` space of the
|
||
parent device of the visible CPU.
|
||
``9660::ram``
|
||
Address 9660 in the default address space of the device with the
|
||
absolute tag ``:ram``, or the ``ram`` space of the root machine
|
||
device.
|
||
|
||
The examples here include a lot of corner cases, but in general the
|
||
debugger should take the most likely meaning for a device or address
|
||
space specification.
|
||
|
||
|
||
.. _debugger-expressions:
|
||
|
||
Debugger expression syntax
|
||
--------------------------
|
||
|
||
Expressions can be used anywhere a numeric or Boolean parameter is
|
||
expected. The syntax for expressions is similar to a subset of C-style
|
||
expression syntax, with full operator precedence and parentheses. There
|
||
are a few operators missing (notably the ternary conditional operator),
|
||
and a few new ones (memory accessors).
|
||
|
||
The table below lists all the operators, ordered from highest to lowest
|
||
precedence:
|
||
|
||
( )
|
||
Standard parentheses
|
||
++ --
|
||
Postfix increment/decrement
|
||
++ -- ~ ! - + b@ w@ d@ q@ b! w! d! q!
|
||
Prefix increment/decrement, binary complement, logical complement,
|
||
unary identity/negation, memory access
|
||
\* / %
|
||
Multiplication, division, modulo
|
||
\+ -
|
||
Addition, subtraction
|
||
<< >>
|
||
Bitwise left/right shift
|
||
< <= > >=
|
||
Less than, less than or equal, greater than, greater than or equal
|
||
== !=
|
||
Equal, not equal
|
||
\&
|
||
Bitwise intersection (and)
|
||
\^
|
||
Bitwise exclusive or
|
||
\|
|
||
Bitwise union (or)
|
||
\&&
|
||
Logical conjunction (and)
|
||
\||
|
||
Logical disjunction (or)
|
||
= \*= /= %= += -= <<= >>= &= \|= ^=
|
||
Assignment and modifying assignment
|
||
\,
|
||
Separate terms, function parameters
|
||
|
||
Major differences from C expression semantics:
|
||
|
||
* All numbers are unsigned 64-bit values. In particular, this means
|
||
negative numbers are not possible.
|
||
* The logical conjunction and disjunction operators ``&&`` and ``||`` do
|
||
not have short-circuit properties – both sides of the expression are
|
||
always evaluated.
|
||
|
||
|
||
Numbers
|
||
~~~~~~~
|
||
|
||
Literal numbers are prefixed according to their bases:
|
||
|
||
* Hexadecimal (base-16) with ``$`` or ``0x``
|
||
* Decimal (base-10) with ``#``
|
||
* Octal (base-8) with ``0o``
|
||
* Binary (base-2) with ``0b``
|
||
* Unprefixed numbers are hexadecimal (base-16).
|
||
|
||
Examples:
|
||
|
||
* ``123`` is 123 hexadecimal (291 decimal)
|
||
* ``$123`` is 123 hexadecimal (291 decimal)
|
||
* ``0x123`` is 123 hexadecimal (291 decimal)
|
||
* ``#123`` is 123 decimal
|
||
* ``0o123`` is 123 octal (83 decimal)
|
||
* ``0b1001`` is is 1001 binary (9 decimal)
|
||
* ``0b123`` is invalid
|
||
|
||
|
||
Boolean values
|
||
~~~~~~~~~~~~~~
|
||
|
||
Any expression that evaluates to a number can be used where a Boolean
|
||
value is required. Zero is treated as false, and all non-zero values
|
||
are treated as true. Additionally, the string ``true`` is treated as
|
||
true, and the string ``false`` is treated as false.
|
||
|
||
An empty string may be supplied as an argument for Boolean parameters to
|
||
debugger commands to use the default value, even when subsequent
|
||
parameters are specified.
|
||
|
||
|
||
Memory accesses
|
||
~~~~~~~~~~~~~~~
|
||
|
||
The memory access prefix operators allow reading from and writing to
|
||
emulated address spaces. The memory prefix operators specify the
|
||
access size and whether side effects are disabled, and may optionally be
|
||
preceded by an address space specification. The supported access sizes
|
||
and side effect modes are as follows:
|
||
|
||
* ``b`` specifies an 8-bit access (byte)
|
||
* ``w`` specifies a 16-bit access (word)
|
||
* ``d`` specifies a 32-bit access (double word)
|
||
* ``q`` specifies a 64-bit access (quadruple word)
|
||
* ``@`` suppress side effects
|
||
* ``!`` do not suppress side effects
|
||
|
||
The size may optionally be preceded by an access type specification:
|
||
|
||
* ``p`` or ``lp`` specifies a logical address defaulting to space 0
|
||
(program)
|
||
* ``d`` or ``ld`` specifies a logical address defaulting to space 1
|
||
(data)
|
||
* ``i`` or ``li`` specifies a logical address defaulting to space 1
|
||
(I/O)
|
||
* ``3`` or ``l3`` specifies a logical address defaulting to space 1
|
||
(opcodes)
|
||
* ``pp`` specifies a physical address defaulting to space 0 (program)
|
||
* ``pd`` specifies a physical address defaulting to space 1 (data)
|
||
* ``pi`` specifies a physical address defaulting to space 1 (I/O)
|
||
* ``p3`` specifies a physical address defaulting to space 1 (opcodes)
|
||
* ``r`` specifies direct read/write pointer access defaulting to space 0
|
||
(program)
|
||
* ``o`` specifies direct read/write pointer access defaulting to space 3
|
||
(opcodes)
|
||
* ``m`` specifies a memory region
|
||
|
||
Finally, this may be preceded by a tag and/or address space name
|
||
followed by a dot (``.``).
|
||
|
||
That may seem like a lot to digest, so let’s look at the simplest
|
||
examples:
|
||
|
||
``b@<addr>``
|
||
Refers to the byte at **<addr>** in the program space of the visible
|
||
CPU while suppressing side effects
|
||
``b!<addr>``
|
||
Refers to the byte at **<addr>** in the program space of the visible
|
||
CPU, *not* suppressing side effects such as reading a mailbox
|
||
clearing the pending flag, or reading a FIFO removing an item
|
||
``w@<addr>`` and ``w!<addr>``
|
||
Refer to the word at **<addr>** in the program space of the visible
|
||
CPU, suppressing or not suppressing side effects, respectively.
|
||
``d@<addr>`` and ``d!<addr>``
|
||
Refer to the double word at **<addr>** in the program space of the
|
||
visible CPU, suppressing or not suppressing side effects,
|
||
respectively.
|
||
``q@<addr>`` and ``q!<addr>``
|
||
Refer to the quadruple word at **<addr>** in the program space of
|
||
the visible CPU, suppressing or not suppressing side effects,
|
||
respectively.
|
||
|
||
Adding access types gives additional possibilities:
|
||
|
||
``dw@300``
|
||
Refers to the word at 300 in the data space of the visible CPU while
|
||
suppressing side effects
|
||
``id@400``
|
||
Refers to the double word at 400 in the I/O space of the visible CPU
|
||
CPU while suppressing side effects
|
||
``ppd!<addr>``
|
||
Refers to the double word at physical address **<addr>** in the
|
||
program space of the visible CPU while not suppressing side effects
|
||
``rw@<addr>``
|
||
Refers to the word at address **<addr>** in the program space of the
|
||
visible CPU using direct read/write pointer access
|
||
|
||
If we want to access an address space of a device other than the visible
|
||
CPU, an address space beyond the first four indices, or a memory region,
|
||
we need to include a tag or name:
|
||
|
||
``ramport.b@<addr>``
|
||
Refers to the byte at address **<addr>** in the ``ramport`` space of
|
||
the current CPU
|
||
``audiocpu.dw@<addr>``
|
||
Refers to the word at address **<addr>** in the data space of the
|
||
CPU with absolute tag ``:audiocpu``
|
||
``maincpu:status.b@<addr>``
|
||
Refers to the byte at address **<addr>** in the ``status`` space of
|
||
the CPU with the absolute tag ``:maincpu``
|
||
``monitor.mb@78``
|
||
Refers to the byte at 78 in the memory region with the absolute tag
|
||
``:monitor``
|
||
|
||
Some combinations are not useful. For example physical and logical
|
||
addresses are equivalent for some CPUs, and direct read/write pointer
|
||
accesses never have side effects. Accessing a memory region (``m``
|
||
access type) requires a tag to be specified.
|
||
|
||
Memory accesses can be used as both lvalues and rvalues, so you can write
|
||
``b@100 = ff`` to store a byte in memory.
|