summaryrefslogtreecommitdiffstatshomepage
path: root/docs/source
diff options
context:
space:
mode:
Diffstat (limited to 'docs/source')
-rw-r--r--docs/source/_templates/versions.html7
-rw-r--r--docs/source/advanced/bgfx.rst263
-rw-r--r--docs/source/advanced/ctrlr_config.rst309
-rw-r--r--docs/source/advanced/devicemap.rst121
-rw-r--r--docs/source/advanced/hlsl.rst2
-rw-r--r--docs/source/advanced/index.rst19
-rw-r--r--docs/source/advanced/multiconfig.rst52
-rw-r--r--docs/source/commandline/commandline-all.rst2485
-rw-r--r--docs/source/commandline/commandline-index.rst106
-rw-r--r--docs/source/commandline/index.rst14
-rw-r--r--docs/source/commandline/sdlconfig.rst87
-rw-r--r--docs/source/commandline/windowsconfig.rst59
-rw-r--r--docs/source/conf.py28
-rw-r--r--docs/source/contributing/cxx.rst573
-rw-r--r--docs/source/contributing/index.rst157
-rw-r--r--docs/source/contributing/softlist.rst175
-rw-r--r--docs/source/debugger/annotation.rst140
-rw-r--r--docs/source/debugger/breakpoint.rst238
-rw-r--r--docs/source/debugger/cheats.rst485
-rw-r--r--docs/source/debugger/exceptionpoint.rst134
-rw-r--r--docs/source/debugger/execution.rst768
-rw-r--r--docs/source/debugger/expressions.rst77
-rw-r--r--docs/source/debugger/general.rst784
-rw-r--r--docs/source/debugger/image.rst97
-rw-r--r--docs/source/debugger/index.rst445
-rw-r--r--docs/source/debugger/memory.rst506
-rw-r--r--docs/source/debugger/registerpoints.rst216
-rw-r--r--docs/source/debugger/watchpoint.rst248
-rw-r--r--docs/source/healthwarning.rst29
-rw-r--r--docs/source/images/MAMElogo.svg71
-rw-r--r--docs/source/index.rst6
-rw-r--r--docs/source/initialsetup/compilingmame.rst793
-rw-r--r--docs/source/initialsetup/configuringmame.rst66
-rw-r--r--docs/source/initialsetup/index.rst4
-rw-r--r--docs/source/initialsetup/installingmame.rst12
-rw-r--r--docs/source/initialsetup/mameintro.rst118
-rw-r--r--docs/source/license.rst15
-rw-r--r--docs/source/luascript/index.rst235
-rw-r--r--docs/source/luascript/ref-common.rst124
-rw-r--r--docs/source/luascript/ref-core.rst631
-rw-r--r--docs/source/luascript/ref-debugger.rst451
-rw-r--r--docs/source/luascript/ref-devices.rst819
-rw-r--r--docs/source/luascript/ref-input.rst766
-rw-r--r--docs/source/luascript/ref-mem.rst459
-rw-r--r--docs/source/luascript/ref-render.rst1374
-rw-r--r--docs/source/plugins/autofire.rst109
-rw-r--r--docs/source/plugins/console.rst9
-rw-r--r--docs/source/plugins/data.rst58
-rw-r--r--docs/source/plugins/discord.rst10
-rw-r--r--docs/source/plugins/dummy.rst8
-rw-r--r--docs/source/plugins/gdbstub.rst13
-rw-r--r--docs/source/plugins/hiscore.rst28
-rw-r--r--docs/source/plugins/index.rst74
-rw-r--r--docs/source/plugins/inputmacro.rst230
-rw-r--r--docs/source/plugins/layout.rst9
-rw-r--r--docs/source/plugins/timecode.rst21
-rw-r--r--docs/source/plugins/timer.rst22
-rw-r--r--docs/source/security.rst2
-rw-r--r--docs/source/techspecs/audio_effects.rst147
-rw-r--r--docs/source/techspecs/cpu_device.rst229
-rw-r--r--docs/source/techspecs/device_disasm_interface.rst10
-rw-r--r--docs/source/techspecs/device_memory_interface.rst174
-rw-r--r--docs/source/techspecs/device_rom_interface.rst123
-rw-r--r--docs/source/techspecs/device_sound_interface.rst286
-rw-r--r--docs/source/techspecs/floppy.rst8
-rw-r--r--docs/source/techspecs/index.rst33
-rw-r--r--docs/source/techspecs/inputsystem.rst460
-rw-r--r--docs/source/techspecs/layout_files.rst950
-rw-r--r--docs/source/techspecs/layout_script.rst786
-rw-r--r--docs/source/techspecs/luaengine.rst158
-rw-r--r--docs/source/techspecs/m6502.rst14
-rw-r--r--docs/source/techspecs/memory.rst964
-rw-r--r--docs/source/techspecs/naming.rst95
-rw-r--r--docs/source/techspecs/object_finders.rst1039
-rw-r--r--docs/source/techspecs/osd_audio.rst348
-rw-r--r--docs/source/techspecs/poly_manager.rst1084
-rw-r--r--docs/source/techspecs/uml_instructions.rst1582
-rw-r--r--docs/source/tools/castool.rst4
-rw-r--r--docs/source/tools/chdman.rst457
-rw-r--r--docs/source/tools/floptool.rst4
-rw-r--r--docs/source/tools/imgtool.rst10
-rw-r--r--docs/source/tools/index.rst16
-rw-r--r--docs/source/tools/othertools.rst20
-rw-r--r--docs/source/usingmame/aboutromsets.rst24
-rw-r--r--docs/source/usingmame/assetsearch.rst398
-rw-r--r--docs/source/usingmame/commonissues.rst174
-rw-r--r--docs/source/usingmame/defaultkeys.rst854
-rw-r--r--docs/source/usingmame/frontends.rst53
-rw-r--r--docs/source/usingmame/images/mahjongpanel.svg215
-rw-r--r--docs/source/usingmame/index.rst23
-rw-r--r--docs/source/usingmame/mamemenus.rst402
-rw-r--r--docs/source/usingmame/ui.rst538
-rw-r--r--docs/source/usingmame/usingmame.rst92
-rw-r--r--docs/source/whatis.rst67
94 files changed, 23916 insertions, 3086 deletions
diff --git a/docs/source/_templates/versions.html b/docs/source/_templates/versions.html
new file mode 100644
index 00000000000..e4d2ae4731a
--- /dev/null
+++ b/docs/source/_templates/versions.html
@@ -0,0 +1,7 @@
+{% if mamedev_site %}
+ <div class="rst-versions" data-toggle="rst-versions" role="note" aria-label="{{ _('Downloads') }}">
+ <span class="rst-current-version" data-toggle="rst-current-version">
+ Download documentation as <a href="https://docs.mamedev.org/_files/MAME.pdf">PDF</a> or <a href="https://docs.mamedev.org/_files/MAME.epub">EPUB</a>
+ </span>
+ </div>
+{% endif %}
diff --git a/docs/source/advanced/bgfx.rst b/docs/source/advanced/bgfx.rst
index 72a61f6a546..bb6e4205fa3 100644
--- a/docs/source/advanced/bgfx.rst
+++ b/docs/source/advanced/bgfx.rst
@@ -1,119 +1,218 @@
BGFX Effects for (nearly) Everyone
==================================
-By default, MAME outputs an idealized version of the video as it would be on the way to the arcade cabinet's monitor, with minimal modification of the output (primarily to stretch the game image back to the aspect ratio the monitor would traditionally have, usually 4:3) -- this works well, but misses some of the nostalgia factor. Arcade monitors were never ideal, even in perfect condition, and the nature of a CRT display distorts that image in ways that change the appearance significantly.
+.. contents:: :local:
-Modern LCD monitors simply do not look the same, and even computer CRT monitors cannot match the look of an arcade monitor without help.
-That's where the new BGFX renderer with HLSL comes into the picture.
+Introduction
+------------
-HLSL simulates most of the effects that a CRT arcade monitor has on the video, making the result look a lot more authentic. However, HLSL requires some effort on the user's part: the settings you use are going to be tailored to your PC's system specs, and especially the monitor you're using. Additionally, there were hundreds of thousands of monitors out there in arcades. Each was tuned and maintained differently, meaning there is no one correct appearance to judge by either. Basic guidelines will be provided here to help you, but you may also wish to ask for opinions on popular MAME-centric forums.
+By default, MAME outputs an idealized version of the video as it would be on the
+way to the arcade cabinet’s monitor, with minimal modification of the output
+(primarily to stretch the game image back to the aspect ratio the monitor would
+traditionally have, usually 4:3). This works well, but misses some of the
+nostalgia factor. Arcade monitors were never ideal, even in perfect condition,
+and the nature of a CRT display distorts that image in ways that change the
+appearance significantly.
+
+Modern LCD monitors simply do not look the same, and even computer CRT monitors
+cannot match the look of an arcade monitor without help.
+
+That’s where the new BGFX renderer with HLSL comes into the picture.
+
+HLSL simulates most of the effects that a CRT arcade monitor has on the video,
+making the result look a lot more authentic. However, HLSL requires some effort
+on the user’s part: the settings you use are going to be tailored to your PC’s
+system specs, and especially the monitor you’re using. Additionally, there were
+hundreds of thousands of monitors out there in arcades. Each was tuned and
+maintained differently, meaning there is no one correct appearance to judge by
+either. Basic guidelines will be provided here to help you, but you may also
+wish to ask for opinions on popular MAME-centric forums.
Resolution and Aspect Ratio
---------------------------
-Resolution is a very important subject for HLSL settings. You will want MAME to be using the native resolution of your monitor to avoid additional distortion and lag created by your monitor upscaling the display image.
+Resolution is a very important subject for HLSL settings. You will want MAME to
+be using the native resolution of your monitor to avoid additional distortion
+and lag caused by your monitor upscaling the display image.
-While most arcade machines used a 4:3 ratio display (or 3:4 for vertically oriented monitors like Pac-Man), it's difficult to find a consumer display that is 4:3 at this point. The good news is that that extra space on the sides isn't wasted. Many arcade cabinets used bezel artwork around the main display, and should you have the necessary artwork files, MAME will display that artwork. Turn the artwork view to Cropped for best results.
+While most arcade machines used a 4:3 ratio display (or 3:4 for vertically
+oriented monitors like Pac-Man), it’s difficult to find a consumer display that
+is 4:3 at this point. The good news is that that extra space on the sides isn’t
+wasted. Many arcade cabinets used bezel artwork around the main display, and
+should you have the necessary artwork files, MAME will display that artwork.
+Turn the **Zoom to Screen Area** setting in the video options menu to scale and
+crop the artwork so the emulated screen fills your display in one direction.
-Some older LCD displays used a native resolution of 1280x1024 and were a 5:4 aspect ratio. There's not enough extra space to display artwork, and you'll end up with some very slight pillarboxing, but the results will be still be good and on-par with a 4:3 monitor.
+Some older LCD displays used a native resolution of 1280×1024 and were a 5:4
+aspect ratio. There’s not enough extra space to display artwork, and you’ll end
+up with some very slight pillarboxing, but the results will be still be good and
+on-par with a 4:3 monitor.
Getting Started with BGFX
-------------------------
-You will need to have followed the initial MAME setup instructions elsewhere in this manual before beginning. Official MAME distributions include BGFX as of MAME 0.172, so you don't need to download any additional files.
+You will need to have followed the initial MAME setup instructions elsewhere in
+this manual before beginning. Official MAME distributions include BGFX as of
+MAME 0.172, so you don’t need to download any additional files.
-Open your ``mame.ini`` in your text editor of choice (e.g. Notepad), and make sure the following options are set correctly:
+Open your ``mame.ini`` file in your text editor of choice (e.g. Notepad), and
+make sure the following options are set correctly:
* ``video bgfx``
-Now, you may want to take a moment to look below at the Configuration Settings section to see how to set up these next options.
+Now, you may want to take a moment to look below at the Configuration Settings
+section to see how to set up these next options.
-As referenced in :ref:`advanced-multi-CFG`, MAME has a order in which it processes INI files. The BGFX settings can be edited in ``mame.ini``, but to take full advantage of the power of MAME's config files, you'll want to copy the BGFX settings from ``mame.ini`` to one of the other config files and make changes there.)
+As explained in :ref:`advanced-multi-CFG`, MAME has a order in which it
+processes INI files. The BGFX settings can be edited in ``mame.ini``, but to
+take full advantage of the power of MAME’s configuration files, you’ll want to
+copy the BGFX settings from ``mame.ini`` to one of the other configuration files
+and make changes there.
-In particular, you will want the ``bgfx_screen_chains`` to be specific to each game.
+In particular, you will want the ``bgfx_screen_chains`` to be specific to each
+game.
+
+Save your INI file(s) and you’re ready to begin.
-Save your .INI file(s) and you're ready to begin.
Configuration Settings
----------------------
-| **bgfx_path**
-|
-| This is where your BGFX shader files are stored. By default, this will be the BGFX folder in your MAME installation.
-|
-| **bgfx_backend**
-|
-| Selects a rendering backend for BGFX to use. Possible choices include ``d3d9``, ``d3d11``, ``opengl``, and ``metal``. The default is ``**auto**``, which will let MAME choose the best selection for you.
-|
-| ``d3d9`` -- Direct3D 9.0 Renderer (Requires Windows XP or higher)
-| ``d3d11`` -- Direct3D 11.0 Renderer (Requires Windows Vista with D3D11 update or Windows 7 or higher)
-| ``opengl`` -- OpenGL Renderer (Requires OpenGL drivers, may work better on some poorly designed video cards, supported on Linux/Mac OS X)
-| ``metal`` -- Metal Apple Graphics API (Requires OS X 10.11 El Capitan or newer)
-|
-| **bgfx_debug**
-|
-| Enables BGFX debugging features. Most users will not need to use this.
-|
-| **bgfx_screen_chains**
-|
-| This dictates how to handle BGFX rendering on a per-display basis. Possible choices include ``hlsl``, ``unfiltered``, and ``default``.
-|
-| ``default`` -- **default** bilinear filterered output
-| ``unfiltered`` -- nearest neighbor unfiltered output
-| ``hlsl`` -- HLSL display simulation through shaders
-|
-| We make a distinction between emulated device screens (which we'll call a **screen**) and physical displays (which we'll call a **window**, set by ``-numscreens``) here. We use colons (:) to seperate windows, and commas (,) to seperate screens. Commas always go on the outside of the chain (see House Mannequin example)
-|
-| On a combination of a single window, single screen case, such as Pac-Man on one physical PC monitor, you can specify one entry like:
-|
-| **bgfx_screen_chains hlsl**
-|
-| Things get only slightly more complicated when we get to multiple windows and multiple screens.
-|
-| On a single window, multiple screen game, such as Darius on one physical PC monitor, specify multiple entries (one per window) like:
-|
-| bgfx_screen_chains hlsl,hlsl,hlsl
-|
-| This also works with single screen games where you are mirroring the output to more than one physical display. For instance, you could set up Pac-Man to have one unfiltered output for use with video broadcasting while a second display is set up HLSL for playing on.
-|
-| On a mulitple window, multiple screen game, such as Darius on three physical PC monitors, specify multiple entries (one per window) like:
-|
-| ``bgfx_screen_chains hlsl:hlsl:hlsl``
-|
-| Another example game would be Taisen Hot Gimmick, which used two CRTs to show individual player hands to just that player. If using two windows (two physical displays):
-|
-| ``bgfx_screen_chains hlsl:hlsl``
-|
-| One more special case is that Nichibutsu had a special cocktail mahjongg cabinet that used a CRT in the middle along with two LCD displays to show each player their hand. We would want the LCDs to be unfiltered and untouched as they were, while the CRT would be improved through HLSL. Since we want to give each player their own full screen display (two physical monitors) along with the LCD, we'll go with:
-|
-| **-numscreens 2 -view0 "Player 1" -view1 "Player 2" -video bgfx -bgfx_screen_chains hlsl,unfiltered,unfiltered:hlsl,unfiltered,unfiltered**
-|
-| This sets up the view for each display respectively, keeping HLSL effect on the CRT for each window (physical display) while going unfiltered for the LCD screens.
-|
-| If using only one window (one display), keep in mind the game still has three screens, so we would use:
-|
-| ``bgfx_screen_chains hlsl,unfiltered,unfiltered``
-|
-|
-| Note that the commas are on the outside edges, and any colons are in the middle.
-|
-| ``bgfx_shadow_mask``
-|
-| This specifies the shadow mask effect PNG file. By default this is ``**slot-mask.png**``.
-|
-|
+bgfx_path
+ This is where your BGFX shader files are stored. By default, this will be
+ the *bgfx* folder in your MAME installation folder.
+bgfx_backend
+ Selects a rendering backend for BGFX to use. Possible choices include
+ ``d3d9``, ``d3d11``, ``d3d12``, ``opengl``, ``gles``, ``metal``, and
+ ```vulkan``. The default is ``**auto**``, which will let MAME choose the
+ best selection for you.
+
+ * ``d3d9`` -- Direct3D 9.0 Renderer (Requires Windows XP or higher)
+ * ``d3d11`` -- Direct3D 11.0 Renderer (Requires Windows Vista with
+ Direct3D 11 update, or Windows 7 or higher)
+ * ``d3d12`` -- Direct3D 12.0 Renderer (Requires Windows 10 or higher)
+ * ``opengl`` -- OpenGL Renderer (Requires OpenGL drivers, may work better on
+ some video cards, supported on Linux and macOS)
+ * ``gles`` -- OpenGL ES Renderer (Supported with some low-power GPUs)
+ * ``metal`` -- Apple Metal Graphics API (Requires macOS 10.11 El Capitan or
+ newer)
+ * ``vulkan`` -- Vulkan Renderer (Requires Windows or Linux with compatible
+ GPU drivers.
+bgfx_debug
+ Enables BGFX debugging features. Most users will not need to use this.
+bgfx_screen_chains
+ This dictates how to handle BGFX rendering on a per-display basis. Possible
+ choices include ``hlsl``, ``unfiltered``, and ``default``.
+
+ * ``default`` -- **default** bilinear filtered output
+ * ``unfiltered`` -- nearest neighbor sampled output
+ * ``hlsl`` -- display simulation through shaders
+ * ``crt-geom`` -- lightweight CRT simulation
+ * ``crt-geom-deluxe`` -- more detailed CRT simulation
+ * ``lcd-grid`` -- LCD matrix simulation
+
+ We make a distinction between emulated screens (which we’ll call a *screen*)
+ and output windows or monitors (which we’ll call a *window*, set by the
+ ``-numscreens`` option) here. Use colons (:) to separate windows, and
+ commas (,) to separate screens in the ``-bgfx_screen_chains`` setting value.
+
+ For the simple single window, single screen case, such as Pac-Man on one
+ physical PC monitor, you can specify one entry like::
+
+ bgfx_screen_chains hlsl
+
+ Things get only slightly more complicated when we get to multiple windows
+ and multiple screens.
+
+ On a single window, multiple screen game, such as Darius on one physical PC
+ monitor, specify screen chains (one per window) like::
+
+ bgfx_screen_chains hlsl,hlsl,hlsl
+
+ This also works with single screen games where you are mirroring the output
+ to more than one physical display. For instance, you could set up Pac-Man
+ to have one unfiltered output for use with video broadcasting while a second
+ display is set up HLSL for playing on.
+
+ On a multiple window, multiple screen game, such as Darius on three physical
+ PC monitors, specify multiple entries (one per window) like::
+
+ bgfx_screen_chains hlsl:hlsl:hlsl
+
+ Another example game would be Taisen Hot Gimmick, which used two CRTs to
+ show individual player hands to just that player. If using two windows (two
+ physical displays)::
+
+ bgfx_screen_chains hlsl:hlsl
+
+ One more special case is that Nichibutsu had a special cocktail mahjong
+ cabinet that used a CRT in the middle along with two LCD displays to show
+ each player their hand. We would want the LCDs to be unfiltered and
+ untouched as they were, while the CRT would be improved through HLSL. Since
+ we want to give each player their own full screen display (two physical
+ monitors) along with the LCD, we’ll go with::
+
+ -numscreens 2 -view0 "Player 1" -view1 "Player 2" -video bgfx -bgfx_screen_chains hlsl,unfiltered:hlsl,unfiltered
+
+ This sets up the view for each display respectively, keeping HLSL effect on
+ the CRT for each window (physical display) while going unfiltered for the
+ LCD screens.
+
+ If using only one window (one display), keep in mind the game still has
+ three screens, so we would use::
+
+ bgfx_screen_chains hlsl,unfiltered,unfiltered
+
+ Note that the commas are on the outside edges, and any colons are in the
+ middle.
+bgfx_shadow_mask
+ This specifies the shadow mask effect PNG file. By default this is
+ **slot-mask.png**.
Tweaking BGFX HLSL Settings inside MAME
---------------------------------------
-*Warning: Currently BGFX HLSL settings are not saved or loaded from any configuration files. This is expected to change in the future.*
+Start by loading MAME with the game of your choice (e.g. **mame pacman**).
+
+The tilde key (**~**) brings up the on-screen display options. Use up and down
+to go through the various settings, while left and right will allow you to
+change that setting. Results will be shown in real time as you’re changing
+these settings.
+
+Note that settings are individually changeable on a per-screen basis.
+
+BGFX slider settings are saved per-system in CFG files. If the
+``bgfx_screen_chains`` setting has been set (either in an INI file or on the
+command line), it will set the initial effects. If the ``bgfx_screen_chains``
+setting has not been set, MAME will use the effects you chose the last time you
+ran the system.
+
+
+Using the included pillarbox filters
+------------------------------------
+
+MAME includes example BGFX shaders and layouts for filling unused space on a
+16:9 widescreen display with a blurred version of the emulated video. The all
+the necessary files are included, and just need to be enabled.
+
+For systems using 4:3 horizontal monitors, use these options::
+
+ -override_artwork bgfx/border_blur -view Horizontal -bgfx_screen_chains crt-geom,pillarbox_left_horizontal,pillarbox_right_horizontal
-Start by loading MAME with the game of your choice (e.g. **mame pacman**)
+For systems using 3:4 vertical monitors, use these options::
-The tilde key (**~**) brings up the on-screen display options. Use up and down to go through the various settings, while left and right will allow you to change that setting. Results will be shown in real time as you're changing these settings.
+ -override_artwork bgfx/border_blur -view Vertical -bgfx_screen_chains crt-geom,pillarbox_left_vertical,pillarbox_right_vertical
-Note that settings are individually changable on a per-screen basis.
+* You can use a different setting in place of ``crt-geom`` for the effect to
+ apply to the primary screen image in the centre (e.g. ``default``, ``hlsl`` or
+ ``lcd-grid``).
+* If you’ve previously changed the view for the system in MAME, the correct
+ pillarboxed view will not be selected by default. Use the video options menu
+ to select the correct view.
+* You can add these settings to an INI file to have them apply to certain
+ systems automatically (e.g. **horizont.ini** or **vertical.ini**, or the INI
+ file for a specific system).
diff --git a/docs/source/advanced/ctrlr_config.rst b/docs/source/advanced/ctrlr_config.rst
new file mode 100644
index 00000000000..13ffa34b050
--- /dev/null
+++ b/docs/source/advanced/ctrlr_config.rst
@@ -0,0 +1,309 @@
+.. _ctrlrcfg:
+
+Controller Configuration Files
+==============================
+
+.. contents:: :local:
+
+
+.. _ctrlrcfg-intro:
+
+Introduction
+------------
+
+Controller configuration files can be used to modify MAME’s default input
+settings. Controller configuration files may be supplied with an input device
+to provide more suitable defaults, or used as profiles that can be selected for
+different situations. MAME includes a few sample controller configuration files
+in the **ctrlr** folder, designed to provide useful defaults for certain
+arcade-style controllers.
+
+Controller configuration files are an XML application, using the ``.cfg``
+filename extension. MAME searches for controller configuration files in the
+directories specified using the :ref:`ctrlrpath <mame-commandline-ctrlrpath>`
+option. A controller configuration file is selected by setting the ``ctrlr``
+option to its filename, excluding the ``.cfg`` extension (e.g. set the ``ctrlr``
+option to ``scorpionxg`` to use **scorpionxg.cfg**). It is an error if the
+specified controller configuration file does not exist, or if it contains no
+sections applicable to the emulated system.
+
+Controller configuration files use implementation-dependent input tokens. The
+values available and their precise meanings depend on the exact version of MAME
+used, the input devices connected, the selected input provider modules
+(:ref:`keyboardprovider <mame-commandline-keyboardprovider>`,
+:ref:`mouseprovider <mame-commandline-mouseprovider>`, :ref:`lightgunprovider
+<mame-commandline-lightgunprovider>` and :ref:`joystickprovider
+<mame-commandline-joystickprovider>` options), and possibly other settings.
+
+
+.. _ctrlrcfg-structure:
+
+Basic structure
+---------------
+
+Controller configuration files follow a similar format to the system
+configuration files that MAME uses to save things like input settings and
+bookkeeping data (created in the folder specified using the
+:ref:`cfg_directory option <mame-commandline-cfgdirectory>`). This example
+shows the overall structure of a controller configuration file:
+
+.. code-block:: XML
+
+ <?xml version="1.0"?>
+ <mameconfig version="10">
+ <system name="default">
+ <input>
+ <!-- settings affecting all emulated systems go here -->
+ </input>
+ </system>
+ <system name="neogeo">
+ <input>
+ <!-- settings affecting neogeo and clones go here -->
+ </input>
+ </system>
+ <system name="intellec4.cpp">
+ <input>
+ <!-- settings affecting all systems defined in intellec4.cpp go here -->
+ </input>
+ </system>
+ </mameconfig>
+
+The root of a controller configuration file must be a ``mameconfig`` element,
+with a ``version`` attribute specifying the configuration format version
+(currently ``10`` – MAME will not load a file using a different version). The
+``mameconfig`` element contains one or more ``system`` elements, each of which
+has a ``name`` attribute specifying the system(s) it applies to. Each
+``system`` element may contain an ``input`` element which holds the actual
+``remap`` and ``port`` configuration elements, which will be described later.
+Each ``system`` element may also contain a ``pointer_input`` element to set
+pointer input options for systems with interactive artwork.
+
+When launching an emulated system, MAME will apply configuration from ``system``
+elements where the value of the ``name`` attribute meets one of the following
+criteria:
+
+* If the ``name`` attribute has the value ``default``, it will always be applied
+ (including for the system/software selection menus).
+* If the value of the ``name`` attribute matches the system’s short name, the
+ short name of its parent system, or the short name of its BIOS system (if
+ applicable).
+* If the value of the ``name`` attribute matches the name of the source file
+ where the system is defined.
+
+For example, for the game “DaeJeon! SanJeon SuJeon (AJTUE 990412 V1.000)”,
+``system`` elements will be applied if their ``name`` attribute has the value
+``default`` (applies to all systems), ``sanjeon`` (short name of the system
+itself), ``sasissu`` (short name of the parent system), ``stvbios`` (short
+name of the BIOS system), or ``stv.cpp`` (source file where the system is
+defined).
+
+As another example, a ``system`` element whose ``name`` attribute has the value
+``zac2650.cpp`` will be applied for the systems “The Invaders”, “Super Invader
+Attack (bootleg of The Invaders)”, and “Dodgem”.
+
+Applicable ``system`` elements are applied in the order they appear in the
+controller configuration file. Settings from elements that appear later in the
+file may modify or override settings from elements that appear earlier. Within
+a ``system`` element, ``remap`` elements are applied before ``port`` elements.
+
+
+.. _ctrlrcfg-substitute:
+
+Substituting default controls
+-----------------------------
+
+You can use a ``remap`` element to substitute one host input for another in
+MAME’s default input configuration. For example, this substitutes keys on the
+numeric keypad for the cursor direction keys:
+
+.. code-block:: XML
+
+ <input>
+ <remap origcode="KEYCODE_UP" newcode="KEYCODE_8PAD" />
+ <remap origcode="KEYCODE_DOWN" newcode="KEYCODE_2PAD" />
+ <remap origcode="KEYCODE_LEFT" newcode="KEYCODE_4PAD" />
+ <remap origcode="KEYCODE_RIGHT" newcode="KEYCODE_6PAD" />
+ </input>
+
+The ``origcode`` attribute specifies the token for the host input to be
+substituted, and the ``newcode`` attribute specifies the token for the
+replacement host input. In this case, assignments using the cursor up, down,
+left and right arrows will be replaced with the numeric 8, 2, 4 and 6 keys on
+the numeric keypad, respectively.
+
+Note that substitutions specified using ``remap`` elements only apply to inputs
+that use MAME’s default assignment for the input type. That is, they only apply
+to default assignments for control types set in the “Input Assignments
+(general)” menus. They *do not* apply to default control assignments set in
+driver/device I/O port definitions (using the ``PORT_CODE`` macro).
+
+MAME applies ``remap`` elements found inside any applicable ``system`` element.
+
+
+.. _ctrlrcfg-typeoverride:
+
+Overriding defaults by input type
+---------------------------------
+
+Use ``port`` elements with ``type`` attributes but without ``tag`` attributes to
+override the default control assignments for emulated inputs by type:
+
+.. code-block:: XML
+
+ <input>
+ <port type="UI_MENU">
+ <newseq type="standard">KEYCODE_TAB OR KEYCODE_1 KEYCODE_5</newseq>
+ </port>
+ <port type="UI_CANCEL">
+ <newseq type="standard">KEYCODE_ESC OR KEYCODE_2 KEYCODE_6</newseq>
+ </port>
+
+ <port type="P1_BUTTON1">
+ <newseq type="standard">KEYCODE_C OR JOYCODE_1_BUTTON1</newseq>
+ </port>
+ <port type="P1_BUTTON2">
+ <newseq type="standard">KEYCODE_LSHIFT OR JOYCODE_1_BUTTON2</newseq>
+ </port>
+ <port type="P1_BUTTON3">
+ <newseq type="standard">KEYCODE_Z OR JOYCODE_1_BUTTON3</newseq>
+ </port>
+ <port type="P1_BUTTON4">
+ <newseq type="standard">KEYCODE_X OR JOYCODE_1_BUTTON4</newseq>
+ </port>
+ </input>
+
+This sets the following default input assignments:
+
+Show/Hide Menu (User Interface)
+ Tab key, or 1 and 2 keys pressed simultaneously
+UI Cancel (User Interface)
+ Escape key, or 2 and 6 keys pressed simultaneously
+P1 Button 1 (Player 1 Controls)
+ C key, or joystick 1 button 1
+P1 Button 2 (Player 1 Controls)
+ Left Shift key, or joystick 1 button 2
+P1 Button 3 (Player 1 Controls)
+ Z key, or joystick 1 button 3
+P1 Button 4 (Player 1 Controls)
+ X key, or joystick 1 button 4
+
+Note that this will only apply for inputs that use MAME’s default assignment for
+the input type. That is, ``port`` elements without ``tag`` attributes only
+override default assignments for control types set in the “Input Assignments
+(general)” menus. They *do not* override default control assignments set in
+driver/device I/O port definitions (using the ``PORT_CODE`` macro).
+
+MAME applies ``port`` elements without ``tag`` attributes found inside any
+applicable ``system`` element.
+
+
+.. _ctrlrcfg-ctrloverride:
+
+Overriding defaults for specific inputs
+---------------------------------------
+
+Use ``port`` elements with ``tag``, ``type``, ``mask`` and ``defvalue``
+attributes to override defaults for specific inputs. These ``port`` elements
+should only occur inside ``system`` elements that apply to particular systems or
+source files (i.e. they should not occur inside ``system`` elements where the
+``name`` attribute has the value ``default``). The default control assignments
+can be overridden, as well as the toggle setting for digital inputs.
+
+The ``tag``, ``type``, ``mask`` and ``defvalue`` are used to identify the
+affected input. You can find out the values to use for a particular input by
+changing its control assignment, exiting MAME, and checking the values in the
+system configuration file (created in the folder specified using the
+:ref:`cfg_directory option <mame-commandline-cfgdirectory>`). Note that these
+values are not guaranteed to be stable, and may change between MAME versions.
+
+Here’s an example that overrides defaults for 280-ZZZAP:
+
+.. code-block:: XML
+
+ <system name="280zzzap">
+ <input>
+ <port tag=":IN0" type="P1_BUTTON2" mask="16" defvalue="0" toggle="no" />
+ <port tag=":IN1" type="P1_PADDLE" mask="255" defvalue="127">
+ <newseq type="increment">KEYCODE_K</newseq>
+ <newseq type="decrement">KEYCODE_J</newseq>
+ </port>
+ </input>
+ </system>
+
+This sets the controls to steer left and right to the K and J keys,
+respectively, and disables the toggle setting for the gear shift input.
+
+
+.. _ctrlrcfg-mapdevice:
+
+Assigning input device numbers
+------------------------------
+
+Use ``mapdevice`` elements with ``device`` and ``controller`` attributes to
+assign stable numbers to input devices. Note that all devices explicitly
+configured in this way must be connected when MAME starts for this to work as
+expected.
+
+Set the ``device`` attribute to the device ID of the input device, and set the
+``controller`` attribute to the desired input device token (device type and
+number).
+
+Here’s an example numbering two light guns and two XInput game controllers:
+
+.. code-block:: XML
+
+ <system name="default">
+ <input>
+ <mapdevice device="VID_D209&amp;PID_1601" controller="GUNCODE_1" />
+ <mapdevice device="VID_D209&amp;PID_1602" controller="GUNCODE_2" />
+ <mapdevice device="XInput Player 1" controller="JOYCODE_1" />
+ <mapdevice device="XInput Player 2" controller="JOYCODE_2" />
+ </input>
+ </system>
+
+MAME applies ``mapdevice`` elements found inside the first applicable ``system``
+element only. To avoid confusion, it’s simplest to place the ``system`` element
+applying to all systems (``name`` attribute set to ``default``) first in the
+file, and use it to assign input device numbers.
+
+
+.. _ctrlrcfg-pointers:
+
+Setting pointer input options
+-----------------------------
+
+A ``pointer_input`` element may contain ``target`` elements to set pointer input
+options for each output screen or window. Each ``target`` element must have an
+``index`` attribute containing the zero-based index of the screen to which it
+applies.
+
+Each ``target`` element may have an ``activity_timeout`` attribute to set the
+time after which a mouse pointer that has not moved and has no buttons pressed
+will be considered inactive. The value is specified in seconds, and must be in
+the range of 0.1 seconds to 10 seconds, inclusive.
+
+Each ``target`` element may have a ``hide_inactive`` element to set whether
+inactive pointers may be hidden. If the value is ``0`` (zero), inactive
+pointers will not be hidden. If the value is ``1``, inactive pointers may be
+hidden, but layout views can still specify that inactive pointers should not be
+hidden.
+
+Here’s an example demonstrating the use of this feature:
+
+.. code-block:: XML
+
+ <system name="default">
+ <pointer_input>
+ <target index="0" activity_timeout="1.5" />
+ </pointer_input>
+ </system>
+ <system name="intellec4.cpp">
+ <pointer_input>
+ <target index="0" hide_inactive="0" />
+ </pointer_input>
+ </system>
+
+For all systems, pointers over the first output screen or window will be
+considered inactive after not moving for 1.5 seconds with no buttons pressed.
+For systems defined in ``intellec4.cpp``, inactive pointers over the first
+window will not be hidden.
diff --git a/docs/source/advanced/devicemap.rst b/docs/source/advanced/devicemap.rst
index 38dcc3a2641..9cfd88e6c56 100644
--- a/docs/source/advanced/devicemap.rst
+++ b/docs/source/advanced/devicemap.rst
@@ -1,26 +1,52 @@
+.. _devicemap:
+
Stable Controller IDs
-===============================
+=====================
+
+By default, MAME does not assign stable numbers to input devices. For instance,
+a game pad controller may be assigned to “Joy 1” initially, but after
+restarting, the same game pad may be reassigned to “Joy 3”.
+
+The reason is that MAME assigns numbers to input devices in the based on
+enumeration order. Factors that can cause this to change include disconnecting
+and reconnecting USB or Bluetooth devices, changing ports/hubs, and even just
+restarting the computer. Input device numbers can be quite unpredictable.
-By default, the mapping between devices and controller IDs is not stable. For instance, a gamepad controller may be assigned to "Joy 1" initially, but after a reboot, it may get re-assigned to "Joy 3".
+This is where the ``mapdevice`` configuration setting comes into the picture.
+By adding this setting to a :ref:`controller configuration file <ctrlrcfg>`, you
+can ensure that a given input device is always assigned the same number in MAME.
-The reason is that MAME enumerates attached devices and assigns controller IDs based on the enumeration order. Factors that can cause controller IDs to change include plugging / unplugging USB devices, changing ports / hubs and even system reboots.
-It is quite cumbersome to ensure that controller IDs are always correct.
+Using mapdevice
+---------------
-That's where the "mapdevice" configuration setting comes into the picture. This setting allows you to map a device id to a controller ID, ensuring that the specified device always maps to the same controller ID in MAME.
+The ``mapdevice`` XML element is added to the ``input`` XML element in the
+controller configuration file. It requires two attributes, ``device`` and
+``controller``. Note that ``mapdevice`` elements only take effect in the
+controller configuration file (set using the :ref:`-ctrlr option
+<mame-commandline-ctrlr>`) – they are ignored in system configuration files and
+the default configuration file.
-Usage of mapdevice
-------------------
-The "mapdevice" xml element is specified under the input xml element in the controller configuration file. It requires two attributes, "device" and "controller".
-NOTE: This setting only take effect when added to the **ctrlr** config file.
+The ``device`` attribute specifies the device ID of the input device to match.
+It may also be a substring of the device ID. To obtain the device ID for an
+input device, select it in the :ref:`menus-inputdevices`, and then select **Copy
+Device ID**. The device ID will be copied to the clipboard. You can also see
+input device IDs by turning on verbose logging (more on this later). The format
+of device IDs depends the type of device, selected input provider module and
+operating system. Your input device IDs may look very different to the examples
+here.
-The "device" attribute specifies the id of the device to match. It may also be a substring of the id. To see the list of available devices, enable verbose output and available devices will then be listed to the console at startup (more on this below).
+The ``controller`` attribute specifies the input token for the input device type
+(i.e. ``JOYCODE``, ``GUNCODE``, ``MOUSECODE``) and number to assign to the
+device, separated by an underscore. Numbering starts from 1. For example the
+token for the first joystick device will be ``JOYCODE_1``, the second will be
+``JOYCODE_2``, and so on.
-The "controller" attribute specifies the MAME controller ID. It is made up of a controller class (i.e. ``JOYCODE``, ``GUNCODE``, ``MOUSECODE``) and controller index. For example: ``JOYCODE_1``.
Example
-------
-Here's an example:
+
+Here’s an example:
| <mameconfig version="10">
| <system name="default">
@@ -40,37 +66,68 @@ Here's an example:
In the above example, we have four device mappings specified:
-The first two mapdevice entries map player 1 and 2 lightguns to Gun 1 and Gun 2, respectively. We use a substring of the full raw device names to match each devices. Note that, since this is XML, we needed to escape the ``&`` using ``&amp;``.
+* The first two ``mapdevice`` elements map player 1 and 2 light guns to Gun 1
+ and Gun 2, respectively. We use a substring of the full device IDs to match
+ each devices. Note that, since this is XML, we needed to escape the
+ ampersands (``&``) as ``&amp;``.
+* The last two ``mapdevices`` elements map player 1 and player 2 gamepad
+ controllers to Joy 1 and Joy 2, respectively. In this case, these are XInput
+ game controllers.
-The last two mapdevices entries map player 1 and player 2 gamepad controllers to Joy 1 and Joy 2, respectively. In this case, these are XInput devices.
Listing Available Devices
-------------------------
-How did we obtain the device id's in the above example? Easy!
-Run MAME with -v parameter to enable verbose output. It will then list available devices include the corresponding "device id" to the console.
+There are two ways to obtain device IDs: by copying them from the
+:ref:`menus-inputdevices`, or by :ref:`turning on verbose logging
+<mame-commandline-verbose>` and finding the messages logged when input devices
+are added.
+
+To reach the Input Devices menu from the system selection menu, select **General
+Settings**, and the select **Input Devices**. To reach the input devices menu
+from the :ref:`main menu <menus-main>`, select **Input Settings**, then select
+**Input Devices**. From the Input Devices menu, select a device, then select
+**Copy Device ID** to copy its device ID to the clipboard.
+
+To use verbose logging, run MAME with the ``-v`` or ``-verbose`` option on the
+command line. Search the output for messages starting with “Input: Adding…”
+that show recognised input devices and their respective IDs.
Here an example:
-| Input: Adding Gun #0:
-| Input: Adding Gun #1:
-| Input: Adding Gun #2: HID-compliant mouse (**device id: \\?\HID#VID_045E&PID_0053#7&18297dcb&0&0000#{378de44c-56ef-11d1-bc8c-00a0c91405dd}**)
-| Input: Adding Gun #3: HID-compliant mouse (**device id: \\?\HID#IrDeviceV2&Col08#2&2818a073&0&0007#{378de44c-56ef-11d1-bc8c-00a0c91405dd}**)
-| Input: Adding Gun #4: HID-compliant mouse (**device id: \\?\HID#VID_D209&PID_1602&MI_02#8&389ab7f3&0&0000#{378de44c-56ef-11d1-bc8c-00a0c91405dd}**)
-| Input: Adding Gun #5: HID-compliant mouse (**device id: \\?\HID#VID_D209&PID_1601&MI_02#9&375eebb1&0&0000#{378de44c-56ef-11d1-bc8c-00a0c91405dd}**)
-| Input: Adding Gun #6: HID-compliant mouse (**device id: \\?\HID#VID_1241&PID_1111#8&198f3adc&0&0000#{378de44c-56ef-11d1-bc8c-00a0c91405dd}**)
+| Input: Adding lightgun #1:
+| Input: Adding lightgun #2:
+| Input: Adding lightgun #3: HID-compliant mouse (**device id: \\\\?\\HID#VID_045E&PID_0053#7&18297dcb&0&0000#{378de44c-56ef-11d1-bc8c-00a0c91405dd}**)
+| Input: Adding lightgun #4: HID-compliant mouse (**device id: \\\\?\\HID#IrDeviceV2&Col08#2&2818a073&0&0007#{378de44c-56ef-11d1-bc8c-00a0c91405dd}**)
+| Input: Adding lightgun #5: HID-compliant mouse (**device id: \\\\?\\HID#VID_D209&PID_1602&MI_02#8&389ab7f3&0&0000#{378de44c-56ef-11d1-bc8c-00a0c91405dd}**)
+| Input: Adding lightgun #6: HID-compliant mouse (**device id: \\\\?\\HID#VID_D209&PID_1601&MI_02#9&375eebb1&0&0000#{378de44c-56ef-11d1-bc8c-00a0c91405dd}**)
+| Input: Adding lightgun #7: HID-compliant mouse (**device id: \\\\?\\HID#VID_1241&PID_1111#8&198f3adc&0&0000#{378de44c-56ef-11d1-bc8c-00a0c91405dd}**)
| Skipping DirectInput for XInput compatible joystick Controller (XBOX 360 For Windows).
-| Input: Adding Joy #0: ATRAK Device #1 (**device id: ATRAK Device #1**)
+| Input: Adding joystick #1: ATRAK Device #1 (**device id: ATRAK Device #1**)
| Skipping DirectInput for XInput compatible joystick Controller (XBOX 360 For Windows).
-| Input: Adding Joy #1: ATRAK Device #2 (**device id: ATRAK Device #2**)
-| Input: Adding Joy #2: XInput Player 1 (**device id: XInput Player 1**)
-| Input: Adding Joy #3: XInput Player 2 (**device id: XInput Player 2**)
+| Input: Adding joystick #2: ATRAK Device #2 (**device id: ATRAK Device #2**)
+| Input: Adding joystick #3: XInput Player 1 (**device id: XInput Player 1**)
+| Input: Adding joystick #4: XInput Player 2 (**device id: XInput Player 2**)
|
-Furthermore, when devices are mapped using mapdevice, you'll see that in the verbose logging too, such as:
+Furthermore, when devices are reassigned using ``mapdevice`` elements in the
+controller configuration file, you’ll see that in the verbose log output, too,
+such as:
-| Input: Remapped Gun #0: HID-compliant mouse (device id: \\?\HID#VID_D209&PID_1601&MI_02#9&375eebb1&0&0000#{378de44c-56ef-11d1-bc8c-00a0c91405dd})
-| Input: Remapped Gun #1: HID-compliant mouse (device id: \\?\HID#VID_D209&PID_1602&MI_02#8&389ab7f3&0&0000#{378de44c-56ef-11d1-bc8c-00a0c91405dd})
-| Input: Remapped Joy #0: XInput Player 1 (device id: XInput Player 1)
-| Input: Remapped Joy #1: XInput Player 2 (device id: XInput Player 2)
+| Input: Remapped lightgun #1: HID-compliant mouse (device id: \\\\?\\HID#VID_D209&PID_1601&MI_02#9&375eebb1&0&0000#{378de44c-56ef-11d1-bc8c-00a0c91405dd})
+| Input: Remapped lightgun #2: HID-compliant mouse (device id: \\\\?\\HID#VID_D209&PID_1602&MI_02#8&389ab7f3&0&0000#{378de44c-56ef-11d1-bc8c-00a0c91405dd})
+| Input: Remapped joystick #1: XInput Player 1 (device id: XInput Player 1)
+| Input: Remapped joystick #2: XInput Player 2 (device id: XInput Player 2)
|
+
+
+Limitations
+-----------
+
+You can only assign stable numbers to devices if MAME receives stable, unique
+device IDs from the input device provider and operating system. This is not
+always the case. For example the SDL joystick provider is not capable of
+providing unique IDs for many USB game controllers.
+
+If not all configured devices are connected when MAME starts, the devices that
+are connected may not be numbered as expected.
diff --git a/docs/source/advanced/hlsl.rst b/docs/source/advanced/hlsl.rst
index 3e22203df78..218e3be0564 100644
--- a/docs/source/advanced/hlsl.rst
+++ b/docs/source/advanced/hlsl.rst
@@ -129,7 +129,7 @@ Configuration Settings
|
| **cubic_distortion** (*Cubic Distortion Amount*)
|
-| This setting determines strength of the qubic distortion of the screen image.
+| This setting determines strength of the cubic distortion of the screen image.
|
| Both distortion factors can be negative to compensate each other. e.g. distortion 0.5 and cubic_distortion -0.5
|
diff --git a/docs/source/advanced/index.rst b/docs/source/advanced/index.rst
index 187ddac7267..9c73762697c 100644
--- a/docs/source/advanced/index.rst
+++ b/docs/source/advanced/index.rst
@@ -2,13 +2,14 @@ Advanced configuration
----------------------
.. toctree::
- :titlesonly:
+ :titlesonly:
- multiconfig
- paths
- shiftertoggle
- bgfx
- hlsl
- glsl
- devicemap
- linux-lightguns
+ multiconfig
+ paths
+ shiftertoggle
+ bgfx
+ hlsl
+ glsl
+ ctrlr_config
+ devicemap
+ linux-lightguns
diff --git a/docs/source/advanced/multiconfig.rst b/docs/source/advanced/multiconfig.rst
index abae10f5a78..d81853d4734 100644
--- a/docs/source/advanced/multiconfig.rst
+++ b/docs/source/advanced/multiconfig.rst
@@ -27,12 +27,7 @@ Order of Config Loading
Systems with no monitors, multiple monitors with different orientations, or
monitors connected to slot devices will usually load ``horizont.ini``.
-5. System type INI file (``arcade.ini``, ``console.ini``, ``computer.ini``, or
- ``othersys.ini``). Both Pac-Man and Street Fighter Alpha are arcade games,
- so ``arcade.ini`` will be loaded here, while Atari 2600 will load
- ``console.ini`` as it is a home game console.
-
-6. Monitor type INI file (``vector.ini`` for vector monitors, ``raster.ini`` for
+5. Monitor type INI file (``vector.ini`` for vector monitors, ``raster.ini`` for
CRT raster monitors, or ``lcd.ini`` for LCD/EL/plasma matrix monitors).
Pac-Man and Street Fighter Alpha use raster CRTs, so ``raster.ini`` is loaded
here, while Tempest uses a vector monitor, so ``vector.ini`` is loaded here.
@@ -43,7 +38,7 @@ Order of Config Loading
monitors or with other kinds of monitors will not load an INI file for this
step.
-7. Driver source file INI file. MAME will attempt to load
+6. Driver source file INI file. MAME will attempt to load
``source/``\ *<sourcefile>*\ ``.ini`` where *<sourcefile>* is the base name
of the source code file where the system driver is defined. A system's
source file can be found using **mame -listsource <pattern>** at the command
@@ -54,16 +49,16 @@ Order of Config Loading
``cave.cpp`` source file, so they will all load ``source/cave.ini`` at this
step.
-8. BIOS set INI file (if applicable). For example The Last Soldier uses the
+7. BIOS set INI file (if applicable). For example The Last Soldier uses the
Neo-Geo MVS BIOS, so it will load ``neogeo.ini``. Systems that don't use a
BIOS set won't load an INI file for this step.
-9. Parent system INI file. For example The Last Soldier is a clone of The Last
+8. Parent system INI file. For example The Last Soldier is a clone of The Last
Blade / Bakumatsu Roman - Gekka no Kenshi, so it will load ``lastblad.ini``.
Parent systems will not load an INI file for this step.
-10. System INI file. Using the previous example, The Last Soldier will load
- ``lastsold.ini``.
+9. System INI file. Using the previous example, The Last Soldier will load
+ ``lastsold.ini``.
Examples of Config Loading Order
@@ -75,12 +70,11 @@ Examples of Config Loading Order
2. ``mame.ini`` (global)
3. (debugger not enabled, no extra INI file loaded)
4. ``vertical.ini`` (screen orientation)
- 5. ``arcade.ini`` (system type)
- 6. ``raster.ini`` (monitor type)
- 7. ``source/jack.ini`` (driver source file)
- 8. (no BIOS set)
- 9. ``zzyzzyxx.ini`` (parent system)
- 10. ``brix.ini`` (system)
+ 5. ``raster.ini`` (monitor type)
+ 6. ``source/jack.ini`` (driver source file)
+ 7. (no BIOS set)
+ 8. ``zzyzzyxx.ini`` (parent system)
+ 9. ``brix.ini`` (system)
* Super Street Fighter 2 Turbo (**mame ssf2t**)
@@ -88,12 +82,11 @@ Examples of Config Loading Order
2. ``mame.ini`` (global)
3. (debugger not enabled, no extra INI file loaded)
4. ``horizont.ini`` (screen orientation)
- 5. ``arcade.ini`` (system type)
- 6. ``raster.ini`` (monitor type)
- 7. ``source/cps2.ini`` (driver source file)
- 8. (no BIOS set)
- 9. (no parent system)
- 10. ``ssf2t.ini`` (system)
+ 5. ``raster.ini`` (monitor type)
+ 6. ``source/cps2.ini`` (driver source file)
+ 7. (no BIOS set)
+ 8. (no parent system)
+ 9. ``ssf2t.ini`` (system)
* Final Arch (**mame finlarch**)
@@ -101,12 +94,11 @@ Examples of Config Loading Order
2. ``mame.ini`` (global)
3. (debugger not enabled, no extra INI file loaded)
4. ``horizont.ini`` (screen orientation)
- 5. ``arcade.ini`` (system type)
- 6. ``raster.ini`` (monitor type)
- 7. ``source/stv.ini`` (driver source file)
- 8. ``stvbios.ini`` (BIOS set)
- 9. ``smleague.ini`` (parent system)
- 10. ``finlarch.ini`` (system)
+ 5. ``raster.ini`` (monitor type)
+ 6. ``source/stv.ini`` (driver source file)
+ 7. ``stvbios.ini`` (BIOS set)
+ 8. ``smleague.ini`` (parent system)
+ 9. ``finlarch.ini`` (system)
*Remember command line parameters take precedence over all else!*
@@ -118,5 +110,3 @@ Some users may have a wall-mounted or otherwise rotatable monitor, and may wish
to actually play vertical games with the rotated display. The easiest way to
accomplish this is to put your rotation modifiers into ``vertical.ini``, where
they will only affect vertical games.
-
-[todo: more practical examples]
diff --git a/docs/source/commandline/commandline-all.rst b/docs/source/commandline/commandline-all.rst
index c5bced793c5..9f058e10dff 100644
--- a/docs/source/commandline/commandline-all.rst
+++ b/docs/source/commandline/commandline-all.rst
@@ -1,10 +1,12 @@
-.. _universal-command-line:
+.. _mame-commandline-universal:
-Universal Commandline Options
-=============================
+Universal Command-line Options
+==============================
This section contains configuration options that are applicable to *all* MAME
-sub-builds (both SDL and Windows native).
+configurations (including both SDL and Windows native).
+
+.. contents:: :local:
Commands and Verbs
@@ -17,6 +19,8 @@ Verbs are actions to take upon something with the command (e.g.
**mame -validate pacman** has *mame* as a command and *-validate* as a verb)
+.. _mame-commandline-patterns:
+
Patterns
--------
@@ -36,8 +40,8 @@ File Names and Directory Paths
------------------------------
A number of options for specifying directories support multiple paths (for
-for example to search for ROMs in multiple locations). MAME expects multiple
-paths to be separated with semicolons (``;``).
+example to search for ROMs in multiple locations). MAME expects multiple
+paths to be separated with semicolons ( ``;`` ).
MAME expands environment variable expressions in paths. The syntax used depends
on your operating system. On Windows, ``%`` (percent) syntax is used. For
@@ -47,46 +51,63 @@ Linux), Bourne shell syntax is used, and a leading ``~`` expands to the current
user's home directory. For example, ``~/.mame/${HOSTNAME}/cfg`` expands to
a host-specific path inside the ``.mame`` directory in the current user's home
directory. Note that only simple variable substitutions are supported; more
-complex expressions supported by Bash, ksh or zsh are not recognised by MAME.
+complex expressions supported by Bash, ksh or zsh are not recognized by MAME.
Relative paths are resolved relative to the current working directory. If you
start MAME by double-clicking it in Windows Explorer, the working directory is
set to the folder containing the MAME executable. If you start MAME by
double-clicking it in the macOS Finder, it will open a Terminal window with the
-working directory is set to your home directory (usually ``/Users/<username>``)
+working directory is set to your home directory (usually ``/Users/<username>`` )
and start MAME.
If you want behaviour similar to what Windows Explorer provides on macOS, create
a script file containing these lines in the directory containing the MAME
-executable (for example you could call it ``mame-here``)::
+executable (for example you could call it ``mame-here`` )::
#!/bin/sh
cd "`dirname "$0"`"
- exec ./mame64
+ exec ./mame
You should be able to use any text editor. If you have a choice of file format
-or line ending style, chose UNIX. I've assumed you're using a 64-bit release
-build of MAME, but if you aren't you just need to change ``mame64`` to the name
-of your MAME executable. Once you've created the file, you need to mark is as
-executable. You can do this by opening a Terminal window, typing **chmod a+x**
-followed by a space, dragging the file you created onto the window (this causes
-Terminal to insert the full escaped path to the file), and then ensuring the
-Terminal window is active and hitting **Return** (or **Enter**) on your
-keyboard. You can close the Terminal window after doing this. Now if you
-double-click the script in the Finder, it will open a Terminal window, set the
-working directory to the location of the script (i.e. the folder containing
-MAME), and then start MAME.
+or line ending style, choose UNIX. This assumes you're using a 64-bit release
+build of MAME, but if you aren't you just need to change ``mame`` to the name
+of your MAME executable (e.g. mamed, mamep, mamedp). Once you've created the
+file, you need to mark it as executable. You can do this by opening a Terminal
+window, typing **chmod a+x** followed by a space, dragging the file you created
+onto the window (this causes Terminal to insert the full escaped path to the
+file), and then ensuring the Terminal window is active and hitting **Return**
+(or **Enter**) on your keyboard. You can close the Terminal window after doing
+this. Now if you double-click the script in the Finder, it will open a
+Terminal window, set the working directory to the location of the script
+(i.e. the folder containing MAME), and then start MAME.
+
+.. _mame-commandline-coreverbs:
Core Verbs
----------
+.. Tip:: Examples that have the output abbreviated for space reasons will show
+ "**...**" in the output where needed. For instance:
+ .. code-block:: bash
+
+ A
+ B
+ C
+ ...
+ Z
+
.. _mame-commandline-help:
**-help** / **-h** / **-?**
Displays current MAME version and copyright notice.
+ Example:
+ .. code-block:: bash
+
+ mame -help
+
.. _mame-commandline-validate:
**-validate** / **-valid** [*<pattern>*]
@@ -100,8 +121,28 @@ Core Verbs
is specified, it will be matched against systems only (not other devices),
and no device type validation will be performed.
+ Example:
+ .. code-block:: bash
+
+ mame -validate
+ Driver ace100 (file apple2.cpp): 1 errors, 0 warnings
+ Errors:
+ Software List device 'flop525_orig': apple2_flop_orig.xml: Errors parsing software list:
+ apple2_flop_orig.xml(126.2): Unknown tag: year
+ apple2_flop_orig.xml(126.8): Unexpected content
+ apple2_flop_orig.xml(127.2): Unknown tag: publisher
+ apple2_flop_orig.xml(127.13): Unexpected content
+ apple2_flop_orig.xml(128.2): Unknown tag: info
+ apple2_flop_orig.xml(129.2): Unknown tag: sharedfeat
+ apple2_flop_orig.xml(132.2): Unknown tag: part
+ apple2_flop_orig.xml(133.3): Tag dataarea found outside of software context
+ apple2_flop_orig.xml(134.4): Tag rom found outside of part context
+ apple2_flop_orig.xml(137.3): mismatched tag
+
+.. _mame-commandline-configverbs:
+
Configuration Verbs
-------------------
@@ -113,16 +154,24 @@ Configuration Verbs
verbs) described below can be permanently changed by editing this
configuration file.
+ Example:
+ .. code-block:: bash
+
+ mame -createconfig
+
.. _mame-commandline-showconfig:
**-showconfig** / **-sc**
Displays the current configuration settings. If you route this to a file,
- you can use it as an INI file. For example, the command:
+ you can use it as an INI file.
+
+ Example:
+ .. code-block:: bash
- **mame -showconfig > mame.ini**
+ mame -showconfig > mame.ini
- is equivalent to **-createconfig**.
+ This example is equivalent to **-createconfig**.
.. _mame-commandline-showusage:
@@ -133,6 +182,7 @@ Configuration Verbs
a sufficient description.
+.. _mame-commandline-fronendverbs:
Frontend Verbs
--------------
@@ -145,20 +195,19 @@ command:
**>** *filename*
where *filename* is the name of the file to save the output in (e.g.
-``list.txt``). Note that if this file already exists, it will be completely
+``list.txt`` ). Note that if this file already exists, it will be completely
overwritten.
-Example:
+ Example:
+ .. code-block:: bash
-| **mame -listcrc puckman > list.txt**
-|
+ mame -listcrc puckman > list.txt
This creates (or overwrites the existing file if already there) ``list.txt``
and fills the file with the results of **-listcrc puckman**. In other
words, the list of each ROM used in Puckman and the CRC for that ROM are
written into that file.
-
.. _mame-commandline-listxml:
**-listxml** / **-lx** [*<pattern>*...]
@@ -172,10 +221,57 @@ Example:
front-ends and ROM managers), or processed with scripts query detailed
information.
+ Example:
+ .. code-block:: bash
+
+ mame galaxian -listxml
+ <?xml version="1.0"?>
+ <!DOCTYPE mame [
+ <!ELEMENT mame (machine+)>
+ <!ATTLIST mame build CDATA #IMPLIED>
+ <!ATTLIST mame debug (yes|no) "no">
+ <!ATTLIST mame mameconfig CDATA #REQUIRED>
+ <!ELEMENT machine (description, year?, manufacturer?, biosset*, rom*, disk*, device_ref*, sample*, chip*, display*, sound?, input?, dipswitch*, configuration*, port*, adjuster*, driver?, feature*, device*, slot*, softwarelist*, ramoption*)>
+ <!ATTLIST machine name CDATA #REQUIRED>
+ <!ATTLIST machine sourcefile CDATA #IMPLIED>
+ ...
+ <mame build="0.216 (mame0216-154-gabddfb0404c-dirty)" debug="no" mameconfig="10">
+ <machine name="galaxian" sourcefile="galaxian.cpp">
+ <description>Galaxian (Namco set 1)</description>
+ <year>1979</year>
+ <manufacturer>Namco</manufacturer>
+ ...
+ <machine name="z80" sourcefile="src/devices/cpu/z80/z80.cpp" isdevice="yes" runnable="no">
+ <description>Zilog Z80</description>
+ </machine>
+ </mame>
+
+.. Tip:: Output from this command is typically more useful if redirected to
+ an output file. For instance, doing
+ **mame -listxml galaxian > galax.xml** will make ``galax.xml`` or
+ overwrite any existing data in the file with the results of
+ **-listxml**; this will allow you to view it in a text editor or parse
+ it with external tools.
+
.. _mame-commandline-listfull:
**-listfull** / **-ll** [*<pattern>*...]
+ Example:
+ .. code-block:: bash
+
+ mame -listfull galaxian*
+ Name: Description:
+ galaxian "Galaxian (Namco set 1)"
+ galaxiana "Galaxian (Namco set 2)"
+ galaxianbl "Galaxian (bootleg, set 2)"
+ galaxianbl2 "Galaxian (bootleg, set 4)"
+ galaxiani "Galaxian (Irem)"
+ galaxianm "Galaxian (Midway set 1)"
+ galaxianmo "Galaxian (Midway set 2)"
+ galaxiant "Galaxian (Taito)"
+ galaxian_sound "Galaxian Custom Sound"
+
Displays a list of system driver names and descriptions. By default all
systems and devices are listed; however, you can limit this list by
specifying one or more *patterns* after the **-listfull** verb.
@@ -190,6 +286,12 @@ Example:
you can limit this list by specifying one or more *pattern* after the
**-listsource** verb.
+ Example:
+ .. code-block:: bash
+
+ mame galaga -listsource
+ galaga galaga.cpp
+
.. _mame-commandline-listclones:
**-listclones** / **-lc** [*<pattern>*]
@@ -199,6 +301,26 @@ Example:
verb. If a pattern is specified, MAME will list clones of systems that
match the pattern, as well as clones that match the pattern themselves.
+ Example 1:
+ .. code-block:: bash
+
+ mame pacman -listclones
+ Name: Clone of:
+ pacman puckman
+
+ Example 2:
+ .. code-block:: bash
+
+ mame puckman -listclones
+ Name: Clone of:
+ abscam puckman
+ bucaner puckman
+ crockman puckman
+ crockmnf puckman
+ ...
+ puckmod puckman
+ titanpac puckman
+
.. _mame-commandline-listbrothers:
**-listbrothers** / **-lb** [*<pattern>*]
@@ -206,6 +328,18 @@ Example:
Displays a list of *brothers*, i.e. other systems that are defined in the
same source file as a system that matches the specified *pattern*.
+ Example:
+ .. code-block:: bash
+
+ mame galaxian -listbrothers
+ Source file: Name: Parent:
+ galaxian.cpp amidar
+ galaxian.cpp amidar1 amidar
+ galaxian.cpp amidarb amidar
+ ...
+ galaxian.cpp zigzagb
+ galaxian.cpp zigzagb2 zigzagb
+
.. _mame-commandline-listcrc:
**-listcrc** [*<pattern>*...]
@@ -215,6 +349,31 @@ Example:
specified, ROMs referenced by all supported systems and devices will be
included.
+ Example:
+ .. code-block:: bash
+
+ mame playch10 -listcrc
+ d52fa07a pch1-c__8t_e-2.8t playch10 PlayChoice-10 BIOS
+ 503ee8b1 pck1-c.8t playch10 PlayChoice-10 BIOS
+ 123ffa37 pch1-c_8te.8t playch10 PlayChoice-10 BIOS
+ 0be8ceb4 pck1-c_fix.8t playch10 PlayChoice-10 BIOS
+ 9acffb30 pch1-c__8k.8k playch10 PlayChoice-10 BIOS
+ c1232eee pch1-c__8m_e-1.8m playch10 PlayChoice-10 BIOS
+ 30c15e23 pch1-c__8p_e-1.8p playch10 PlayChoice-10 BIOS
+ 9acffb30 pch1-c__8k.8k playch10 PlayChoice-10 BIOS
+ c1232eee pch1-c__8m_e-1.8m playch10 PlayChoice-10 BIOS
+ 30c15e23 pch1-c__8p_e-1.8p playch10 PlayChoice-10 BIOS
+ 9acffb30 pch1-c__8k.8k playch10 PlayChoice-10 BIOS
+ 83ebc7a3 pch1-c_8m.8m playch10 PlayChoice-10 BIOS
+ 90e1b80c pch1-c_8p-8p playch10 PlayChoice-10 BIOS
+ 9acffb30 pch1-c__8k.8k playch10 PlayChoice-10 BIOS
+ c1232eee pch1-c__8m_e-1.8m playch10 PlayChoice-10 BIOS
+ 30c15e23 pch1-c__8p_e-1.8p playch10 PlayChoice-10 BIOS
+ e5414ca3 pch1-c-6f.82s129an.6f playch10 PlayChoice-10 BIOS
+ a2625c6e pch1-c-6e.82s129an.6e playch10 PlayChoice-10 BIOS
+ 1213ebd4 pch1-c-6d.82s129an.6d playch10 PlayChoice-10 BIOS
+ 48de65dc rp2c0x.pal playch10 PlayChoice-10 BIOS
+
.. _mame-commandline-listroms:
**-listroms** / **-lr** [*<pattern>*...]
@@ -223,6 +382,20 @@ Example:
match the specified pattern(s). If no patterns are specified, the results
will include *all* supported systems and devices.
+ Example:
+ .. code-block:: bash
+
+ mame neogeo -listroms
+ ROMs required for driver "neogeo".
+ Name Size Checksum
+ sp-s2.sp1 131072 CRC(9036d879) SHA1(4f5ed7105b7128794654ce82b51723e16e389543)
+ sp-s.sp1 131072 CRC(c7f2fa45) SHA1(09576ff20b4d6b365e78e6a5698ea450262697cd)
+ sp-45.sp1 524288 CRC(03cc9f6a) SHA1(cdf1f49e3ff2bac528c21ed28449cf35b7957dc1)
+ ...
+ sm1.sm1 131072 CRC(94416d67) SHA1(42f9d7ddd6c0931fd64226a60dc73602b2819dcf)
+ 000-lo.lo 131072 CRC(5a86cff2) SHA1(5992277debadeb64d1c1c64b0a92d9293eaf7e4a)
+ sfix.sfix 131072 CRC(c2ea0cfd) SHA1(fd4a618cdcdbf849374f0a50dd8efe9dbab706c3)
+
.. _mame-commandline-listsamples:
**-listsamples** [<*pattern*>]
@@ -231,6 +404,19 @@ Example:
device names. If no pattern is specified, the results will be *all* systems
and devices.
+ Example:
+ .. code-block:: bash
+
+ mame armorap -listsamples
+ Samples required for driver "armorap".
+ loexp
+ jeepfire
+ hiexp
+ tankfire
+ tankeng
+ beep
+ chopper
+
.. _mame-commandline-verifyroms:
**-verifyroms** [<*pattern*>]
@@ -239,6 +425,13 @@ Example:
valid ZIP files or directories in the rompath are verified; however, you can
limit this list by specifying a *pattern* after the **-verifyroms** command.
+ Example:
+ .. code-block:: bash
+
+ mame gradius -verifyroms
+ romset gradius [nemesis] is good
+ 1 romsets found, 1 were OK.
+
.. _mame-commandline-verifysamples:
**-verifysamples** [<*pattern*>]
@@ -248,19 +441,33 @@ Example:
can limit this list by specifying a *pattern* after the **-verifyroms**
command.
+ Example:
+ .. code-block:: bash
+
+ mame armorap -verifysamples
+ sampleset armorap [armora] is good
+ 1 samplesets found, 1 were OK.
+
.. _mame-commandline-romident:
-**-romident** [*path\\to\\romstocheck.zip*]
+**-romident** [*path/to/romstocheck.zip*]
Attempts to identify ROM files, if they are known to MAME, in the specified
.zip file or directory. This command can be used to try and identify ROM
sets taken from unknown boards. On exit, the errorlevel is returned as one
of the following:
- * 0: means all files were identified
- * 7: means all files were identified except for 1 or more "non-ROM" files
- * 8: means some files were identified
- * 9: means no files were identified
+ * 0: means all files were identified
+ * 7: means all files were identified except for 1 or more "non-ROM" files
+ * 8: means some files were identified
+ * 9: means no files were identified
+
+ Example:
+ .. code-block:: bash
+
+ mame unknown.rom -romident
+ Identifying unknown.rom....
+ unknown.rom = 456-a07.17l gradius Gradius (Japan, ROM version)
.. _mame-commandline-listdevices:
@@ -274,6 +481,23 @@ Example:
provide will be visible with **-listdevices** as well. For instance,
installing a floppy controller into a PC will expose the disk drive slots.
+ Example:
+ .. code-block:: bash
+
+ mame apple2e -listdevices
+ Driver apple2e (Apple //e):
+ <root> Apple //e
+ a2bus Apple II Bus
+ a2common Apple II Common Components @ 14.31 MHz
+ a2video Apple II video @ 14.31 MHz
+ aux Apple IIe AUX Slot
+ ext80 Apple IIe Extended 80-Column Card
+ auxbus Apple IIe AUX Bus
+ ay3600 AY-5-3600 Keyboard Encoder
+ ...
+ speaker Filtered 1-bit DAC
+ tape Cassette
+
.. _mame-commandline-listslots:
**-listslots** / **-lslot** [<*pattern*>]
@@ -289,6 +513,54 @@ Example:
The slot name (e.g. **ctrl1**) can be used from the command
line (**-ctrl1** in this case)
+ Example:
+ .. code-block:: bash
+
+ mame apple2e -listslots
+ SYSTEM SLOT NAME SLOT OPTIONS SLOT DEVICE NAME
+ ---------------- ---------------- ---------------- ----------------------------
+ apple2e sl1 4play 4play Joystick Card (rev. B)
+ ...
+ aevm80 Applied Engineering Viewmaster 80
+ alfam2 ALF MC1 / Apple Music II
+ ...
+ zipdrive Zip Technologies ZipDrive
+
+ ...
+ aux ext80 Apple IIe Extended 80-Column Card
+ rw3 Applied Engineering RamWorks III
+ std80 Apple IIe Standard 80-Column Card
+
+ gameio compeyes Digital Vision ComputerEyes
+ joy Apple II analog joysticks
+ paddles Apple II paddles
+
+.. _mame-commandline-listbios:
+
+**-listbios** [*<pattern>*]
+
+ Show available BIOS options for a system (if available). BIOS options may
+ be available for the system or any devices selected as slot options.
+
+ If no pattern is specified, the results will include *all* supported
+ systems.
+
+ Example:
+ .. code-block:: bash
+
+ mamed -listbios apple2 -sl2 grapplus -sl4 videoterm
+ BIOS options for system Apple ][ (apple2):
+ default Original Monitor
+ autostart Autostart Monitor
+
+ BIOS options for device Orange Micro Grappler+ Printer Interface (-sl2 grapplus):
+ v30 ROM 3.0
+ v32 ROM 3.2
+
+ BIOS options for device Videx Videoterm 80 Column Display (-sl4 videoterm):
+ v24_60hz Firmware v2.4 (60 Hz)
+ v24_50hz Firmware v2.4 (50 Hz)
+
.. _mame-commandline-listmedia:
**-listmedia** / **-lm** [<*pattern*>]
@@ -297,13 +569,54 @@ Example:
includes media types (cartridge, cassette, diskette and more) as well as
common file extensions which are supported.
+ Example:
+ .. code-block:: bash
+
+ mame coco3 -listmedia
+ SYSTEM MEDIA NAME (brief) IMAGE FILE EXTENSIONS SUPPORTED
+ ---------------- --------------------------- -------------------------------
+ coco3 cassette (cass) .wav .cas
+ printout (prin) .prn
+ cartridge (cart) .ccc .rom
+ floppydisk1 (flop1) .dmk .jvc .dsk .vdk .sdf .os9 .d77 .d88 .1dd .dfi .hfe .imd .ipf .mfi .mfm .td0 .cqm .cqi
+ floppydisk2 (flop2) .dmk .jvc .dsk .vdk .sdf .os9 .d77 .d88 .1dd .dfi .hfe .imd .ipf .mfi .mfm .td0 .cqm .cqi
+ harddisk1 (hard1) .vhd
+ harddisk2 (hard2) .vhd
+
.. _mame-commandline-listsoftware:
**-listsoftware** / **-lsoft** [<*pattern*>]
- Posts to screen all software lists which can be used by the entered
- *pattern* or system. Note that this is simply a copy/paste of the .XML file
- which reside in the HASH folder which are allowed to be used.
+ Displays the contents of all software lists that can be used by the system
+ or systems represented by *pattern*.
+
+ Example:
+ .. code-block:: bash
+
+ mame coco3 -listsoftware
+ <?xml version="1.0"?>
+ <!DOCTYPE softwarelists [
+ <!ELEMENT softwarelists (softwarelist*)>
+ <!ELEMENT softwarelist (software+)>
+ <!ATTLIST softwarelist name CDATA #REQUIRED>
+ <!ATTLIST softwarelist description CDATA #IMPLIED>
+ <!ELEMENT software (description, year, publisher, info*, sharedfeat*, part*)>
+ ...
+ <softwarelists>
+ <softwarelist name="coco_cart" description="Tandy Radio Shack Color Computer cartridges">
+ <software name="7cardstd">
+ <description>7 Card Stud</description>
+ <year>1983</year>
+ <publisher>Tandy</publisher>
+ <info name="developer" value="Intelligent Software"/>
+ <info name="serial" value="26-3074"/>
+ <part name="cart" interface="coco_cart">
+ <dataarea name="rom" size="8192">
+ <rom name="7 card stud (1983) (26-3074) (intelligent software).rom" size="8192" crc="f38d8c97" sha1="5cfcb699ce09840dbb52714c8d91b3d86d3a86c3"/>
+ </dataarea>
+ </part>
+ </software>
+ ...
.. _mame-commandline-verifysoftware:
@@ -314,12 +627,49 @@ Example:
verified; however, you can limit this list by specifying a specific driver
name or *pattern* after the **-verifysoftware** command.
+ Example:
+ .. code-block:: bash
+
+ mame coco3 -verifysoftware
+ romset coco_cart:7cardstd is good
+ coco_cart:amazing: a mazing world of malcom mortar (1987)(26-3160)(zct systems).rom (16384 bytes) - NEEDS REDUMP
+ romset coco_cart:amazing is best available
+ coco_cart:amazing1: a mazing world of malcom mortar (1987)(26-3160)(zct systems)[a].rom (16384 bytes) - NEEDS REDUMP
+ romset coco_cart:amazing1 is best available
+ romset coco_cart:androne is good
+ ...
+
.. _mame-commandline-getsoftlist:
**-getsoftlist** / **-glist** [<*pattern*>]
- Posts to screen a specific software list which matches with the system name
- provided.
+ Displays the contents of a specific softlist with the filename represented
+ by *pattern*.
+
+ Example:
+ .. code-block:: bash
+
+ mame -getsoftlist apple2_flop_orig
+ <?xml version="1.0"?>
+ <!DOCTYPE softwarelists [
+ <!ELEMENT softwarelists (softwarelist*)>
+ <!ELEMENT softwarelist (software+)>
+ <!ATTLIST softwarelist name CDATA #REQUIRED>
+ <!ATTLIST softwarelist description CDATA #IMPLIED>
+ <!ELEMENT software (description, year, publisher, info*, sharedfeat*, part*)>
+ <!ATTLIST software name CDATA #REQUIRED>
+ <!ATTLIST software cloneof CDATA #IMPLIED>
+ <!ATTLIST software supported (yes|partial|no) "yes">
+ <!ELEMENT description (#PCDATA)>
+ <!ELEMENT year (#PCDATA)>
+ <!ELEMENT publisher (#PCDATA)>
+ <!ELEMENT info EMPTY>
+ <!ATTLIST info name CDATA #REQUIRED>
+ <!ATTLIST info value CDATA #IMPLIED>
+ <!ELEMENT sharedfeat EMPTY>
+ <!ATTLIST sharedfeat name CDATA #REQUIRED>
+ <!ATTLIST sharedfeat value CDATA #IMPLIED>
+ ...
.. _mame-commandline-verifysoftlist:
@@ -331,8 +681,26 @@ Example:
by specifying a specific softwarelistname (without .XML) after the
-verifysoftlist command.
+ Example:
+ .. code-block:: bash
+
+ mame -verifysoftlist apple2_flop_orig
+ romset apple2_flop_orig:agentusa is good
+ romset apple2_flop_orig:airheart is good
+ romset apple2_flop_orig:aplpanic is good
+ romset apple2_flop_orig:alambush is good
+ romset apple2_flop_orig:ankh is good
+ romset apple2_flop_orig:aplcdspd is good
+ romset apple2_flop_orig:agalxian is good
+ romset apple2_flop_orig:aquatron is good
+ romset apple2_flop_orig:archon is good
+ romset apple2_flop_orig:archon2 is good
+ romset apple2_flop_orig:ardyardv is good
+ romset apple2_flop_orig:autobahn is good
+ ...
-.. _osd-commandline-options:
+
+.. _mame-commandline-osdoptions:
OSD-related Options
-------------------
@@ -346,99 +714,376 @@ OSD-related Options
**SCRLOCK** on other operating systems (including Windows and Linux). Use
**FN-Delete** on Macintosh computers with notebook/compact keyboards.
+ Example:
+ .. code-block:: bash
+
+ mame ibm5150 -uimodekey DEL
+
+.. _mame-commandline-controllermap:
+
+**-controller_map** / **-ctrlmap** *<filename>*
+
+ Path to a text file containing game controller button and axis mappings in
+ the format used by SDL2 and Steam, or ``none`` to use only built-in
+ mappings. Must use an ASCII-compatible text encoding with native line
+ endings (e.g. CRLF on Windows). Currently only supported when using the
+ ``sdlgame`` joystick provider. The default setting is ``none``.
+
+ A `community-sourced list of game controller mappings
+ <https://github.com/gabomdq/SDL_GameControllerDB>`_ can be found on GitHub.
+ Besides using a text editor, several tools are available for creating game
+ controller mappings, including `SDL2 Gamepad Mapper
+ <https://gitlab.com/ryochan7/sdl2-gamepad-mapper/-/releases>`_ and SDL2
+ ControllerMap which is `supplied with SDL
+ <https://github.com/libsdl-org/SDL/releases/latest>`_. You can also
+ configure your controller in Steam’s Big Picture mode, then copy the
+ mappings from ``SDL_GamepadBind`` entries in the **config.vdf** file found
+ in the **config** folder inside your Steam installation folder.
+
+ Example:
+ .. code-block:: bash
+
+ mame -controller_map gamecontrollerdb.txt sf2ce
+
+.. _mame-commandline-backgroundinput:
+
+**-[no]background_input**
+
+ Sets whether input is accepted or ignored when MAME does not have UI focus.
+ This setting is ignored when the debugger is enabled. The default is OFF
+ (**-nobackground_input**).
+
+ Currently supported for RawInput mouse/keyboard input, DirectInput
+ mouse/keyboard/joystick input and XInput joystick input on Windows, and SDL
+ game controller/joystick input.
+
+ Example:
+ .. code-block:: bash
+
+ mame -background_input ssf2tb
+
.. _mame-commandline-uifontprovider:
-**-uifontprovider**
+**-uifontprovider** *<module>*
+
+ Chooses provider for UI font rendering. The default setting is ``auto``.
+
+.. list-table:: Supported UI font providers per-platform
+ :header-rows: 0
+ :stub-columns: 0
+
+ * - **Microsoft Windows**
+ - win
+ - dwrite
+ - auto
+ -
+ - sdl [#UIFPSDLWindows]_
+ - none
+ * - **macOS**
+ -
+ -
+ - auto
+ - osx
+ - sdl
+ - none
+ * - **Linux**
+ -
+ -
+ - auto
+ -
+ - sdl
+ - none
+
+.. rubric:: Footnotes
+
+.. [#UIFPSDLWindows] SDL support on Windows requires that you compile MAME with
+ the support in. By default SDL is not included in Windows
+ builds of MAME.
- Chooses provider for UI font rendering.
+Example:
+ .. code-block:: bash
-| On Windows, you can choose from: ``win``, ``dwrite``, ``none`` or ``auto``.
-| On macOS, you can choose from: ``osx``, ``none`` or ``auto``.
-| On other platforms, you can choose from: ``sdl``, ``none`` or ``auto``.
-|
-| Default setting is ``auto``.
-|
+ mame ajax -uifontprovider dwrite
.. _mame-commandline-keyboardprovider:
-**-keyboardprovider**
+**-keyboardprovider** *<module>*
+
+ Chooses how MAME will get keyboard input. The default is ``auto``.
+
+.. list-table:: Supported keyboard input providers per-platform
+ :header-rows: 0
+ :stub-columns: 0
+
+ * - **Microsoft Windows**
+ - auto [#KBIPAutoWindows]_
+ - rawinput
+ - dinput
+ - win32
+ - sdl [#KBIPSDLWindows]_
+ - none
+ * - **SDL (macOS and Linux)**
+ - auto [#KBIPAutoSDL]_
+ -
+ -
+ -
+ - sdl
+ - none
+
+.. rubric:: Footnotes
+
+.. [#KBIPAutoWindows] ``auto`` on Windows will try ``rawinput`` with
+ fallback to ``dinput``.
- Chooses how MAME will get keyboard input.
+.. [#KBIPSDLWindows] SDL support on Windows requires that you compile MAME with
+ the support in. By default SDL is not included in Windows
+ builds of MAME.
-| On Windows, you can choose from: ``auto``, ``rawinput``, ``dinput``, ``win32``, or ``none``
-| On SDL, you can choose from: ``auto``, ``sdl``, ``none``
-|
-| The default is ``auto``.
-|
-| On Windows, ``auto`` will try ``rawinput`` with fallback to ``dinput``.
-| On SDL, ``auto`` will default to ``sdl``.
-|
+.. [#KBIPAutoSDL] ``auto`` on SDL will default to ``sdl``.
+
+.. Tip:: Note that user-mode keyboard emulation tools such as joy2key will
+ almost certainly require the use of **-keyboardprovider win32** on
+ Windows machines.
+
+Example:
+ .. code-block:: bash
+
+ mame c64 -keyboardprovider win32
.. _mame-commandline-mouseprovider:
-**\-mouseprovider**
+**-mouseprovider** *<module>*
+
+ Chooses how MAME will get mouse input. The default is ``auto``.
+
+.. list-table:: Supported mouse input providers per-platform
+ :header-rows: 0
+ :stub-columns: 0
+
+ * - **Microsoft Windows**
+ - auto [#MIPAutoWindows]_
+ - rawinput
+ - dinput
+ - win32
+ - sdl [#MIPSDLWindows]_
+ - none
+ * - **SDL (macOS and Linux)**
+ - auto [#MIPAutoSDL]_
+ -
+ -
+ -
+ - sdl
+ - none
+
+.. rubric:: Footnotes
- Chooses how MAME will get mouse input.
+.. [#MIPAutoWindows] On Windows, ``auto`` will try ``rawinput`` with fallback
+ to ``dinput``.
-| On Windows, you can choose from: ``auto``, ``rawinput``, ``dinput``, ``win32``, or ``none``
-| On SDL, you can choose from: ``auto``, ``sdl``, ``none``
-|
-| The default is ``auto``.
-|
-| On Windows, ``auto`` will try ``rawinput`` with fallback to ``dinput``.
-| On SDL, ``auto`` will default to ``sdl``.
-|
+.. [#MIPSDLWindows] SDL support on Windows requires that you compile MAME with
+ the support in. By default SDL is not included in Windows
+ builds of MAME.
+
+.. [#MIPAutoSDL] ``auto`` on SDL will default to ``sdl``.
+
+Example:
+ .. code-block:: bash
+
+ mame indy_4610 -mouseprovider win32
.. _mame-commandline-lightgunprovider:
-**\-lightgunprovider**
+**-lightgunprovider** *<module>*
+
+ Chooses how MAME will get light gun input. The default is ``auto``.
+
+.. list-table:: Supported light gun input providers per-platform
+ :header-rows: 0
+ :stub-columns: 0
+
+ * - **Microsoft Windows**
+ - auto [#LGIPAutoWindows]_
+ - rawinput
+ - win32
+ - sdl [#LGIPSDLWindows]_
+ -
+ - none
+ * - **macOS**
+ - auto [#LGIPAutoSDL]_
+ -
+ -
+ - sdl
+ -
+ - none
+ * - **Linux**
+ - auto [#LGIPAutoSDL]_
+ -
+ -
+ - sdl
+ - x11
+ - none
+
+.. rubric:: Footnotes
+
+.. [#LGIPAutoWindows] On Windows, auto will try ``rawinput`` with fallback to
+ ``win32``, or ``none`` if it doesn't find any.
+
+.. [#LGIPSDLWindows] SDL support on Windows requires that you compile MAME with
+ the support in. By default SDL is not included in Windows
+ builds of MAME.
+
+.. [#LGIPAutoSDL] On SDL, ``auto`` will default to ``sdl``.
- Chooses how MAME will get light gun input.
+Example:
+ .. code-block:: bash
-| On Windows, you can choose from: ``auto``, ``rawinput``, ``win32``, or ``none``
-| On SDL, you can choose from: ``auto``, ``x11`` or ``none``
-|
-| The default is ``auto``.
-|
-| On Windows, auto will try ``rawinput`` with fallback to ``win32``, or ``none`` if it doesn't find any.
-| On SDL/Linux, ``auto`` will default to ``x11``, or ``none`` if it doesn't find any.
-| On other SDL, ``auto`` will default to ``none``.
-|
+ mame lethalen -lightgunprovider x11
.. _mame-commandline-joystickprovider:
-**\-joystickprovider**
+**-joystickprovider** *<module>*
+
+ Chooses how MAME will get joystick and other game controller input. The
+ default is ``auto``.
+
+.. list-table:: Supported joystick input providers per-platform
+ :header-rows: 0
+ :stub-columns: 0
+
+ * - **Microsoft Windows**
+ - auto [#JIPAutoWindows]_
+ - winhybrid
+ - dinput
+ - xinput
+ - sdlgame [#JIPSDLWindows]_
+ - sdljoy [#JIPSDLWindows]_
+ - none
+ * - **SDL**
+ - auto [#JIPAutoSDL]_
+ -
+ -
+ -
+ - sdlgame
+ - sdljoy
+ - none
+
+.. rubric:: Footnotes
+
+.. [#JIPAutoWindows] On Windows native, auto will default to ``winhybrid``.
+
+.. [#JIPSDLWindows] SDL support on Windows requires that you compile MAME with
+ the support in. By default SDL is not included in Windows
+ builds of MAME.
+
+.. [#JIPAutoSDL] On SDL, auto will default to ``sdlgame``.
+
+winhybrid
+ Uses XInput for compatible game controllers, falling back to DirectInput for
+ other game controllers. Typically provides the best experience on Windows.
+dinput
+ Uses DirectInput for all game controllers. May be useful if you want to use
+ more than four XInput game controllers simultaneously. Note that LT and RT
+ controls are combined with using XInput game controllers via DirectInput.
+xinput
+ Supports up to four XInput game controllers.
+sdlgame
+ Uses the SDL game controller API for game controllers with button/axis
+ mappings available, falling back to the SDL joystick API for other game
+ controllers. Provides consistent button and axis assignment and meaningful
+ control names for popular game controllers. Use the :ref:`controller_map
+ option <mame-commandline-controllermap>` to supply mappings for additional
+ game controllers or override built-in mappings.
+sdljoy
+ Uses the SDL joystick API for all game controllers.
+none
+ Ignores all game controllers.
+
+Example:
+ .. code-block:: bash
+
+ mame mk2 -joystickprovider winhybrid
- Chooses how MAME will get joystick input.
+.. _mame-commandline-midiprovider:
-| On Windows, you can choose from: ``auto, ``winhybrid``, ``dinput``, ``xinput``, or ``none``
-| On SDL, you can choose from: ``auto``, ``sdl``, ``none``
-|
-| The default is ``auto``.
-|
-| On Windows, auto will default to ``dinput``.
-|
-| Note that Microsoft XBox 360 and XBox One controllers connected to Windows will work best with ``winhybrid`` or ``xinput``. The ``winhybrid`` option supports a mix of DirectInput and XInput controllers at the same time.
-| On SDL, auto will default to ``sdl``.
-|
+**-midiprovider** *<module>*
+ Chooses how MAME will communicate with MIDI devices and applications (e.g.
+ music keyboards and synthesisers). Supported options are ``pm`` to use the
+ PortMidi library, or ``none`` to disable MIDI input and output (MIDI files
+ can still be played). The default is ``auto``, which will use PortMidi if
+ available.
-OSD CLI Options
----------------
+Example:
+ .. code-block:: bash
+
+ mame -midiprovider none dx100 -midiin canyon.mid
+
+.. _mame-commandline-networkprovider:
+
+**-networkprovider** *<module>*
+
+ Chooses how MAME will provide communication for emulated packet-oriented
+ network interfaces (e.g. Ethernet cards). Supported options are ``taptun``
+ to use the TUN/TAP, TAP-Windows or similar, ``pcap`` to use a pcap library,
+ or ``none`` to disable communication for emulated network interfaces.
+ Available options depend on your operating system. By default, ``taptun``
+ and ``none`` are available on Windows and Linux, and ``pcap`` and ``none``
+ are available on macOS.
+
+ The default is ``auto`` which will use ``taptun`` if available, falling back
+ to ``pcap``.
+
+Example:
+ .. code-block:: bash
+
+ mame -networkprovider pcap apple2ee -sl3 uthernet
+
+
+.. _mame-commandline-cliverbs:
+
+OSD Command-Line Verbs
+----------------------
.. _mame-commandline-listmidi:
-**\-listmidi**
+**-listmidi**
- Create a list of available MIDI I/O devices for use with emulation.
+ List available MIDI I/O devices for use with emulation.
+
+ Example:
+ .. code-block:: bash
+
+ mame -listmidi
+ MIDI input ports:
+
+ MIDI output ports:
+ Microsoft MIDI Mapper (default)
+ Microsoft GS Wavetable Synth
.. _mame-commandline-listnetwork:
-**\-listnetwork**
+**-listnetwork**
+
+ List available network adapters for use with emulation.
- Create a list of available Network Adapters for use with emulation.
+ Example 1:
+ .. code-block:: bash
+ mame -listnetwork
+ No network adapters were found
+ Example 2:
+ .. code-block:: bash
+
+ mame -listnetwork
+ Available network adapters:
+ Local Area Connection
+
+.. Tip:: On Windows, you'll need the TAP driver from OpenVPN for MAME to see
+ any network adapters.
+
+
+.. _mame-commandline-osdoutput:
OSD Output Options
------------------
@@ -447,13 +1092,26 @@ OSD Output Options
**\-output**
- Chooses how MAME will handle processing of output notifiers.
+ Chooses how MAME will handle processing of output notifiers. These are used
+ to connect external outputs such as the LED lights for the Player 1/2 start
+ buttons on certain arcade machines.
You can choose from: ``auto``, ``none``, ``console`` or ``network``
Note that network port is fixed at 8000.
+ Example:
+ .. code-block:: bash
+ mame asteroid -output console
+ led0 = 1
+ led0 = 0
+ ...
+ led0 = 1
+ led0 = 0
+
+
+.. _mame-commandline-configoptions:
Configuration Options
---------------------
@@ -487,7 +1145,13 @@ Configuration Options
The default is ON (**-readconfig**).
+ Example:
+ .. code-block:: bash
+
+ mame apple2ee -noreadconfig -sl6 diskii -sl7 cffa2 -hard1 TotalReplay.2mg
+
+.. _mame-commandline-pathoptions:
Core Search Path Options
------------------------
@@ -500,9 +1164,14 @@ Core Search Path Options
The default is ``.`` (that is, in the current working directory).
+ Example:
+ .. code-block:: bash
+
+ mame -homepath C:\mame\lua
+
.. _mame-commandline-rompath:
-**-rompath** / **-rp** / **-biospath** / **-bp** *<path>*
+**-rompath** / **-rp** *<path>*
Specifies one or more paths within which to find ROM or disk images.
Multiple paths can be specified by separating them with semicolons.
@@ -510,6 +1179,11 @@ Core Search Path Options
The default is ``roms`` (that is, a directory ``roms`` in the current
working directory).
+ Example:
+ .. code-block:: bash
+
+ mame -rompath C:\mame\roms;C:\roms\another
+
.. _mame-commandline-hashpath:
**-hashpath** / **-hash_directory** / **-hash** *<path>*
@@ -520,6 +1194,11 @@ Core Search Path Options
The default is ``hash`` (that is, a directory ``hash`` in the current
working directory).
+ Example:
+ .. code-block:: bash
+
+ mame -hashpath C:\mame\hash;C:\roms\softlists
+
.. _mame-commandline-samplepath:
**-samplepath** / **-sp** *<path>*
@@ -530,9 +1209,14 @@ Core Search Path Options
The default is ``samples`` (that is, a directory ``samples`` in the current
working directory).
+ Example:
+ .. code-block:: bash
+
+ mame -samplepath C:\mame\samples;C:\roms\samples
+
.. _mame-commandline-artpath:
-**-artpath** *<path>* *<path>*
+**-artpath** *<path>*
Specifies one or more paths within which to find external layout and artwork
files. Multiple paths can be specified by separating them with semicolons.
@@ -540,16 +1224,27 @@ Core Search Path Options
The default is ``artwork`` (that is, a directory ``artwork`` in the current
working directory).
+ Example:
+ .. code-block:: bash
+
+ mame -artpath C:\mame\artwork;C:\emu\shared-artwork
+
.. _mame-commandline-ctrlrpath:
**-ctrlrpath** *<path>*
- Specifies one or more paths within which to find default input configuration
+ Specifies one or more paths within which to find controller configuration
files. Multiple paths can be specified by separating them with semicolons.
+ Used in conjunction with the ``-ctrlr`` option.
The default is ``ctrlr`` (that is, a directory ``ctrlr`` in the current
working directory).
+ Example:
+ .. code-block:: bash
+
+ mame -ctrlrpath C:\mame\ctrlr;C:\emu\controllers
+
.. _mame-commandline-inipath:
**-inipath** *<path>*
@@ -574,6 +1269,11 @@ Core Search Path Options
directory, followed by the current working directory, and finally the
directory ``ini`` in the current working directory).
+ Example:
+ .. code-block:: bash
+
+ mame -inipath C:\Users\thisuser\documents\mameini
+
.. _mame-commandline-fontpath:
**-fontpath** *<path>*
@@ -584,6 +1284,11 @@ Core Search Path Options
The default is ``.`` (that is, search in the current working directory).
+ Example:
+ .. code-block:: bash
+
+ mame -fontpath C:\mame\;C:\emu\artwork\mamefonts
+
.. _mame-commandline-cheatpath:
**-cheatpath** *<path>*
@@ -594,6 +1299,11 @@ Core Search Path Options
The default is ``cheat`` (that is, a folder called ``cheat`` located in the
current working directory).
+ Example:
+ .. code-block:: bash
+
+ mame -cheatpath C:\mame\cheat;C:\emu\cheats
+
.. _mame-commandline-crosshairpath:
**-crosshairpath** *<path>*
@@ -604,6 +1314,11 @@ Core Search Path Options
The default is ``crsshair`` (that is, a directory ``crsshair`` in the
current working directory).
+ Example:
+ .. code-block:: bash
+
+ mame -crosshairpath C:\mame\crsshair;C:\emu\artwork\crosshairs
+
.. _mame-commandline-pluginspath:
**-pluginspath** *<path>*
@@ -613,6 +1328,11 @@ Core Search Path Options
The default is ``plugins`` (that is, a directory ``plugins`` in the current
working directory).
+ Example:
+ .. code-block:: bash
+
+ mame -pluginspath C:\mame\plugins;C:\emu\lua
+
.. _mame-commandline-languagepath:
**-languagepath** *<path>*
@@ -623,6 +1343,11 @@ Core Search Path Options
The default is ``language`` (that is, a directory ``language`` in the
current working directory).
+ Example:
+ .. code-block:: bash
+
+ mame -languagepath C:\mame\language;C:\emu\mame-languages
+
.. _mame-commandline-swpath:
**-swpath** *<path>*
@@ -632,6 +1357,13 @@ Core Search Path Options
The default is ``sofware`` (that is, a directory ``software`` in the current
working directory).
+ Example:
+ .. code-block:: bash
+
+ mame -swpath C:\mame\software;C:\emu\mydisks
+
+
+.. _mame-commandline-coreoutdir:
Core Output Directory Options
-----------------------------
@@ -650,6 +1382,11 @@ Core Output Directory Options
directory). If this directory does not exist, it will be created
automatically.
+ Example:
+ .. code-block:: bash
+
+ mame -cfg_directory C:\mame\cfg
+
.. _mame-commandline-nvramdirectory:
**-nvram_directory** *<path>*
@@ -663,6 +1400,11 @@ Core Output Directory Options
working directory)). If this directory does not exist, it will be created
automatically.
+ Example:
+ .. code-block:: bash
+
+ mame -nvram_directory C:\mame\nvram
+
.. _mame-commandline-inputdirectory:
**-input_directory** *<path>*
@@ -675,6 +1417,11 @@ Core Output Directory Options
directory). If this directory does not exist, it will be created
automatically.
+ Example:
+ .. code-block:: bash
+
+ mame -input_directory C:\mame\inp
+
.. _mame-commandline-statedirectory:
**-state_directory** *<path>*
@@ -687,6 +1434,11 @@ Core Output Directory Options
directory). If this directory does not exist, it will be created
automatically.
+ Example:
+ .. code-block:: bash
+
+ mame -state_directory C:\mame\sta
+
.. _mame-commandline-snapshotdirectory:
**-snapshot_directory** *<path>*
@@ -698,6 +1450,11 @@ Core Output Directory Options
working directory). If this directory does not exist, it will be created
automatically.
+ Example:
+ .. code-block:: bash
+
+ mame -snapshot_directory C:\mame\snap
+
.. _mame-commandline-diffdirectory:
**-diff_directory** *<path>*
@@ -712,6 +1469,11 @@ Core Output Directory Options
working directory). If this directory does not exist, it will be created
automatically.
+ Example:
+ .. code-block:: bash
+
+ mame -diff_directory C:\mame\diff
+
.. _mame-commandline-commentdirectory:
**-comment_directory** *<path>*
@@ -724,7 +1486,13 @@ Core Output Directory Options
current working directory). If this directory does not exist, it will be
created automatically.
+ Example:
+ .. code-block:: bash
+
+ mame -comment_directory C:\mame\comments
+
+.. _mame-commandline-savestate:
Core State/Playback Options
---------------------------
@@ -745,6 +1513,11 @@ Core State/Playback Options
states can be loaded by executing the debugger **rewind** (or **rw**)
command.
+ Example:
+ .. code-block:: bash
+
+ mame -norewind
+
.. _mame-commandline-rewindcapacity:
**-rewind_capacity** *<value>*
@@ -755,6 +1528,11 @@ Core State/Playback Options
current savestate size disables rewind. Values below 0 are automatically
clamped to 0.
+ Example:
+ .. code-block:: bash
+
+ mame -rewind_capacity 30
+
.. _mame-commandline-state:
**-state** *<slot>*
@@ -762,6 +1540,11 @@ Core State/Playback Options
Immediately after starting the specified system, will cause the save state
in the specified <slot> to be loaded.
+ Example:
+ .. code-block:: bash
+
+ mame -state 1
+
.. _mame-commandline-noautosave:
**-[no]autosave**
@@ -773,18 +1556,31 @@ Core State/Playback Options
The default is OFF (**-noautosave**).
+ Example:
+ .. code-block:: bash
+
+ mame -autosave
+
.. _mame-commandline-playback:
**-playback** / **-pb** *<filename>*
Specifies a file from which to play back a series of inputs. This feature
does not work reliably for all systems, but can be used to watch a
- previously recorded game session from start to finish. In order to make
- things consistent, you should only record and playback with all
- configuration (.cfg), NVRAM (.nv), and memory card files deleted.
+ previously recorded game session from start to finish.
The default is ``NULL`` (no playback).
+ Example:
+ .. code-block:: bash
+
+ mame pacman -playback worldrecord
+
+.. Tip:: You may experience desync in playback if the configuration, NVRAM, and
+ memory card files don't match the original; this is why it is suggested
+ you should only record and playback with all configuration (.cfg),
+ NVRAM (.nv), and memory card files deleted.
+
.. _mame-commandline-exitafterplayback:
**-[no]exit_after_playback**
@@ -795,29 +1591,30 @@ Core State/Playback Options
The default is OFF (**-noexit_after_playback**).
+ Example:
+ .. code-block:: bash
+
+ mame pacman -playback worldrecord -exit_after_playback
+
.. _mame-commandline-record:
**-record** / **-rec** *<filename>*
Specifies a file to record all input from a session. This can be used to
record a session for later playback. This feature does not work reliably
- for all systems, but can be used to watch a previously recorded session from
- start to finish. In order to make things consistent, you should only record
- and playback with all configuration (.cfg), NVRAM (.nv), and memory card
- files deleted.
+ for all systems, but can be used to record a session from start to finish.
The default is ``NULL`` (no recording).
-.. _mame-commandline-recordtimecode:
+ Example:
+ .. code-block:: bash
-**-record_timecode**
+ mame pacman -record worldrecord
- Tells MAME to create a timecode file. It contains a line with elapsed times
- on each press of timecode shortcut key (default is **F12**). This option
- works only when recording mode is enabled (**-record** option). The
- timecode file is saved in the ``inp`` folder.
-
- By default, no timecode file is saved.
+.. Tip:: You may experience desync in playback if the configuration, NVRAM, and
+ memory card files don't match the original; this is why it is suggested
+ you should only record and playback with all configuration (.cfg),
+ NVRAM (.nv), and memory card files deleted.
.. _mame-commandline-mngwrite:
@@ -831,6 +1628,11 @@ Core State/Playback Options
The default is ``NULL`` (no recording).
+ Example:
+ .. code-block:: bash
+
+ mame pacman -mngwrite pacman-video
+
.. _mame-commandline-aviwrite:
**-aviwrite** *<filename>*
@@ -846,6 +1648,11 @@ Core State/Playback Options
The default is ``NULL`` (no recording).
+ Example:
+ .. code-block:: bash
+
+ mame pacman -playback worldrecord -exit_after_playback -aviwrite worldrecord
+
.. _mame-commandline-wavwrite:
**-wavwrite** *<filename>*
@@ -855,6 +1662,11 @@ Core State/Playback Options
The default is ``NULL`` (no recording).
+ Example:
+ .. code-block:: bash
+
+ mame pacman -wavwrite pacsounds
+
.. _mame-commandline-snapname:
**-snapname** *<name>*
@@ -877,16 +1689,26 @@ Core State/Playback Options
floppy disks, you can also use the ``%d_[media]`` indicator. Replace [media]
with the media switch you want to use.
- A few examples:
+ Example 1:
+ .. code-block:: bash
+
+ mame robby -snapname foo\%g%i
+
+ Snapshots will be saved as ``snaps\foo\robby0000.png``, ``snaps\foo\robby0001.png`` and so on.
+
+ Example 2:
+ .. code-block:: bash
+
+ mame nes -cart robby -snapname %g\%d_cart
+
+ Snapshots will be saved as ``snaps\nes\robby.png``.
- If you use **mame robby -snapname foo/%g%i** snapshots will be saved as
- ``snaps\\foo\\robby0000.png`` , ``snaps\\foo\\robby0001.png`` and so on.
+ Example 3:
+ .. code-block:: bash
- If you use **mame nes -cart robby -snapname %g/%d_cart** snapshots will be
- saved as ``snaps\\nes\\robby.png``.
+ mame c64 -flop1 robby -snapname %g\%d_flop1/%i
- If you use **mame c64 -flop1 robby -snapname %g/%d_flop1/%i** snapshots will
- be saved as ``snaps\\c64\\robby\\0000.png``.
+ Snapshots will be saved as ``snaps\c64\robby\0000.png``.
.. _mame-commandline-snapsize:
@@ -896,39 +1718,62 @@ Core State/Playback Options
will create snapshots at the system's current resolution in raw pixels, and
will create movies at the system's starting resolution in raw pixels. If
you specify this option, then MAME will create both snapshots and movies at
- the size specified, and will bilinear filter the result. Note that this
- size does not automatically rotate if the system is vertically oriented.
+ the size specified, and will bilinear filter the result.
The default is ``auto``.
+ Example:
+ .. code-block:: bash
+
+ mame pacman -snapsize 1920x1080
+
+.. Tip:: -snapsize does not automatically rotate if the system is vertically
+ oriented, so for vertical systems you'll want to swap the width and
+ height options.
+
.. _mame-commandline-snapview:
**-snapview** *<viewname>*
- Specifies the view to use when rendering snapshots and movies.
+ Specifies the view to use when rendering snapshots and videos. The
+ *<viewname>* does not need to be the full name of a view, MAME will choose
+ the first view with a name that has the *<viewname>* as a prefix. For
+ example **-snapview "screen 0 pixel"** will match the
+ “\ *Screen 0 Pixel Aspect (10:7)*\ ” view.
+
+ If the *<viewname>* is ``auto`` or an empty string, MAME will select a view
+ based on the number of emulated screens in the system, and the available
+ external and internal artwork. MAME tries to select a view that shows all
+ emulated screens by default.
- By default, both use a special 'internal' view, which renders a separate
- snapshot per screen or renders movies only of the first screen. By
- specifying this option, you can override this default behavior and select a
- single view that will apply to all snapshots and movies. Note that
- <viewname> does not need to be a perfect match; rather, it will select the
- first view whose name matches all the characters specified by <viewname>.
+ If the *<viewname>* is ``native``, MAME uses special internal view to save a
+ separate snapshot for each visible emulated screen, or to record a video for
+ the first visible screen only. The snapshot(s) or video will have the same
+ resolution as the emulated screen(s) with no artwork elements drawn or
+ effects applied.
- For example, **-snapview native** will match the "Native (15:14)" view even
- though it is not a perfect match. <viewname> can also be 'auto', which
- selects the first view with all screens present.
+ The default value is ``auto``.
+
+ Example:
+ .. code-block:: bash
+
+ mame wrecking -snapview cocktail
- The default value is ``internal``.
.. _mame-commandline-nosnapbilinear:
**-[no]snapbilinear**
Specify if the snapshot or movie should have bilinear filtering applied.
- Shutting this off can improve performance while recording video to a file.
+ Disabling this off can improve performance while recording video to a file.
The default is ON (**-snapbilinear**).
+ Example:
+ .. code-block:: bash
+
+ mame pacman -nosnapbilinear
+
.. _mame-commandline-statename:
**-statename** *<name>*
@@ -947,16 +1792,27 @@ Core State/Playback Options
floppy disks, you can also use the ``%d_[media]`` indicator. Replace
``[media]`` with the media switch you want to use.
- A few examples:
+ Example 1:
+ .. code-block:: bash
- If you use **mame robby -statename foo/%g** save states will be stored
- inside ``sta\\foo\\robby\\``.
+ mame robby -statename foo\%g
+ All save states will be stored inside sta\foo\robby\
- If you use **mame nes -cart robby -statename %g/%d_cart** save states will
- be stored inside ``sta\\nes\\robby\\``.
+ Example 2:
+ .. code-block:: bash
+
+ mame nes -cart robby -statename %g/%d_cart
+ All save states will be stored inside sta\nes\robby\
+
+ Example 3:
+ .. code-block:: bash
+
+ mame c64 -flop1 robby -statename %g/%d_flop1
+ All save states will be stored inside sta\c64\robby\
+
+.. Tip:: Note that even on Microsoft Windows, you should use ``/`` as your
+ path seperator for **-statename**
- If you use **mame c64 -flop1 robby -statename %g/%d_flop1** save states will
- be stored inside 'sta\\c64\\robby\\'.
.. _mame-commandline-noburnin:
@@ -976,7 +1832,13 @@ Core State/Playback Options
The default is OFF (**-noburnin**).
+ Example:
+ .. code-block:: bash
+ mame neogeo -burnin
+
+
+.. _mame-commandline-perf:
Core Performance Options
------------------------
@@ -991,6 +1853,11 @@ Core Performance Options
This is off by default (**-noautoframeskip**).
+ Example:
+ .. code-block:: bash
+
+ mame gradius4 -autoframeskip
+
.. _mame-commandline-frameskip:
**-frameskip** / **-fs** *<level>*
@@ -1003,6 +1870,11 @@ Core Performance Options
The default value is **-frameskip 0**, which skips no frames.
+ Example:
+ .. code-block:: bash
+
+ mame gradius4 -frameskip 2
+
.. _mame-commandline-secondstorun:
**-seconds_to_run** / **-str** *<seconds>*
@@ -1012,14 +1884,19 @@ Core Performance Options
benchmarking and automated testing. By combining this with a fixed set of
other command line options, you can set up a consistent environment for
benchmarking MAME's emulation performance. In addition, upon exit, the
- **-str** option will write a screenshot called ``final.png`` to the system's
- snapshot directory.
+ **-str** option will write a screenshot to the system's snapshot directory
+ with the file name determined by the **-snapname** option.
+
+ Example:
+ .. code-block:: bash
+
+ mame pacman -seconds_to_run 60
.. _mame-commandline-nothrottle:
**-[no]throttle**
- Enable or disable thottling emulation speed. When throttling is enabled,
+ Enable or disable throttling emulation speed. When throttling is enabled,
MAME limits emulation speed to so the emulated system will not run faster
than the original hardware. When throttling is disabled, MAME runs the
emulation as fast as possible. Depending on your settings and the
@@ -1028,6 +1905,11 @@ Core Performance Options
The default is to enable throttling (**-throttle**).
+ Example:
+ .. code-block:: bash
+
+ mame pacman -nothrottle
+
.. _mame-commandline-nosleep:
**-[no]sleep**
@@ -1040,6 +1922,11 @@ Core Performance Options
The default is on (**-sleep**).
+ Example:
+ .. code-block:: bash
+
+ mame gradius 4 -nosleep
+
.. _mame-commandline-speed:
**-speed** *<factor>*
@@ -1054,6 +1941,11 @@ Core Performance Options
The default is ``1.0`` (normal speed).
+ Example:
+ .. code-block:: bash
+
+ mame pacman -speed 1.25
+
.. _mame-commandline-norefreshspeed:
**-[no]refreshspeed** / **-[no]rs**
@@ -1067,6 +1959,11 @@ Core Performance Options
The default is off (**-norefreshspeed**).
+ Example:
+ .. code-block:: bash
+
+ mame pacman -refreshspeed
+
.. _mame-commandline-numprocessors:
**-numprocessors** / **-np** **auto**\ \|\ *<value>*
@@ -1078,6 +1975,11 @@ Core Performance Options
The default is ``auto``.
+ Example:
+ .. code-block:: bash
+
+ mame gradius4 -numprocessors 2
+
.. _mame-commandline-bench:
**-bench** *<n>*
@@ -1087,7 +1989,30 @@ Core Performance Options
**-str** *<n>* **-video none -sound none -nothrottle**
+ Example:
+ .. code-block:: bash
+
+ mame gradius4 -bench 300
+
+.. _mame-commandline-lowlatency:
+
+**-[no]lowlatency**
+ This tells MAME to draw a new frame before throttling to reduce input
+ latency. This is particularly effective with VRR (Variable Refresh Rate)
+ displays.
+
+ This may cause frame pacing issues in the form of jitter with some
+ systems (especially newer 3D-based systems or systems that run software
+ akin to an operating system), so the default is off (**-nolowlatency**).
+
+ Example:
+ .. code-block:: bash
+
+ mame bgaregga -lowlatency
+
+
+.. _mame-commandline-rotation:
Core Rotation Options
---------------------
@@ -1104,6 +2029,10 @@ Core Rotation Options
The default is ON (**-rotate**).
+ Example:
+ .. code-block:: bash
+
+ mame pacman -norotate
.. _mame-commandline-noror:
@@ -1120,6 +2049,16 @@ Core Rotation Options
The default for both of these options is OFF (**-noror -norol**).
+ Example 1:
+ .. code-block:: bash
+
+ mame pacman -ror
+
+ Example 2:
+ .. code-block:: bash
+
+ mame pacman -rol
+
.. _mame-commandline-noautoror:
@@ -1136,6 +2075,20 @@ Core Rotation Options
vertically in one of the directions you can handle. If your screen only
pivots counter-clockwise, use **-autoror**.
+ Example 1:
+ .. code-block:: bash
+
+ mame pacman -autoror
+
+ Example 2:
+ .. code-block:: bash
+
+ mame pacman -autorol
+
+.. Tip:: If you have a display that can be rotated, **-autorol** or
+ **-autoror** will allow you to get a larger display for both horizontal
+ and vertical systems.
+
.. _mame-commandline-noflipx:
**-[no]flipx**
@@ -1150,6 +2103,18 @@ Core Rotation Options
The default for both of these options is OFF (**-noflipx -noflipy**).
+ Example 1:
+ .. code-block:: bash
+
+ mame -flipx pacman
+
+ Example 2:
+ .. code-block:: bash
+
+ mame -flipy suprmrio
+
+
+.. _mame-commandline-videooptions:
Core Video Options
------------------
@@ -1163,48 +2128,65 @@ Core Video Options
Generally Available:
- | Using ``bgfx`` specifies the new hardware accelerated renderer.
- |
- | Using ``opengl`` tells MAME to render video using OpenGL acceleration.
- |
- | Using ``none`` displays no windows and does no drawing. This is primarily present for doing CPU benchmarks without the overhead of the video system.
- |
+ * Using ``bgfx`` specifies the new hardware accelerated renderer.
+ * Using ``opengl`` tells MAME to render video using OpenGL acceleration.
+ * Using ``none`` displays no windows and does no drawing. This is primarily
+ intended for benchmarking emulation without the overhead of the video
+ system.
On Windows:
- | Using ``gdi`` tells MAME to render video using older standard Windows graphics drawing calls. This is the slowest but most compatible option on older versions of Windows.
- |
- | Using ``d3d`` tells MAME to use Direct3D for rendering. This produces the better quality output than ``gdi`` and enables additional rendering options. It is recommended if you have a semi-recent (2002+) video card or onboard Intel video of the HD3000 line or better.
- |
+ * Using ``gdi`` tells MAME to render video using older standard Windows
+ graphics drawing calls. This is the slowest but most compatible option on
+ older versions of Windows or buggy graphics hardware drivers.
+ * Using ``d3d`` tells MAME to use Direct3D 9 for rendering. This produces
+ better quality output than ``gdi`` and enables additional rendering
+ options. It is recommended if you have a 3D-capable video card or onboard
+ Intel video of the HD3000 line or better.
On other platforms (including SDL on Windows):
- | Using ``accel`` tells MAME to render video using SDL's 2D acceleration if possible.
- |
- | Using ``soft`` uses software rendering for video output. This isn't as fast or as nice as OpenGL but will work on any platform.
- |
+ * Using ``accel`` tells MAME to render video using SDL’s 2D acceleration if
+ possible.
+ * Using ``soft`` uses software rendering for video output. This isn’t as
+ fast or as nice as OpenGL, but it will work on any platform.
Defaults:
- | The default on Windows is ``d3d``.
- |
- | The default for Mac OS X is ``opengl`` because OS X is guaranteed to have a compliant OpenGL stack.
- |
- | The default on all other systems is ``soft``.
- |
+ * The default on Windows is ``d3d``.
+ * The default for macOS is ``opengl`` because OS X is guaranteed to have a
+ compliant OpenGL stack.
+ * The default on all other systems is ``soft``.
+
+ Example:
+ .. code-block:: bash
+
+ mame gradius3 -video bgfx
.. _mame-commandline-numscreens:
**-numscreens** *<count>*
- Tells MAME how many output windows to create. For most systems, a single
- output window is all you need, but some systems originally used multipl
- screens (*e.g. Darius and PlayChoice-10 arcade machines*). Each screen
- (up to 4) has its own independent settings for physical monitor, aspect
- ratio, resolution, and view, which can be set using the options below.
+ Tells MAME how many output windows or screens to create. For most systems,
+ a single output window is all you need, but some systems originally used
+ multiple screens (*e.g. Darius and PlayChoice-10 arcade machines*). Some
+ systems with front panel controls and/or status lights also may let you put
+ these in different windows/screens. Each screen (up to 4) has its own
+ independent settings for physical monitor, aspect ratio, resolution, and
+ view, which can be set using the options below.
The default is ``1``.
+ Example 1:
+ .. code-block:: bash
+
+ mame darius -numscreens 3
+
+ Example 2:
+ .. code-block:: bash
+
+ mame pc_cntra -numscreens 2
+
.. _mame-commandline-window:
**-[no]window** / **-[no]w**
@@ -1213,6 +2195,11 @@ Core Video Options
The default is OFF (**-nowindow**).
+ Example:
+ .. code-block:: bash
+
+ mame coco3 -window
+
.. _mame-commandline-maximize:
**-[no]maximize** / **-[no]max**
@@ -1226,6 +2213,11 @@ Core Video Options
The default is ON (**-maximize**).
+ Example:
+ .. code-block:: bash
+
+ mame apple2e -window -nomaximize
+
.. _mame-commandline-keepaspect:
**-[no]keepaspect** / **-[no]ka**
@@ -1256,6 +2248,11 @@ Core Video Options
systems beyond their original aspect ratio will mangle the appearance of the
system in ways that no filtering or shaders can repair.
+ Example:
+ .. code-block:: bash
+
+ mame sf2ua -nokeepaspect
+
.. _mame-commandline-waitvsync:
**-[no]waitvsync**
@@ -1290,6 +2287,11 @@ Core Video Options
The default is OFF (**-nowaitvsync**).
+ Example:
+ .. code-block:: bash
+
+ mame gradius2 -waitvsync
+
.. _mame-commandline-syncrefresh:
**-[no]syncrefresh**
@@ -1307,6 +2309,11 @@ Core Video Options
.. _mame-commandline-prescale:
+ Example:
+ .. code-block:: bash
+
+ mame mk -syncrefresh
+
**-prescale** *<amount>*
Controls the size of the screen images when they are passed off to the
@@ -1318,8 +2325,13 @@ Core Video Options
The default is ``1``.
- This is supported with all video output types (``bgfx``, ``d3d``, etc) on
- Windows and is **ONLY** supported with OpenGL on other platforms.
+ This is supported with all video output types ( ``bgfx``, ``d3d``, etc.) on
+ Windows and is supported with BGFX and OpenGL on other platforms.
+
+ Example:
+ .. code-block:: bash
+
+ mame pacman -video d3d -prescale 3
.. _mame-commandline-filter:
@@ -1338,15 +2350,27 @@ Core Video Options
Use ``bgfx_screen_chains`` in your INI file(s) to adjust filtering with the
BGFX video system.
+ Example:
+ .. code-block:: bash
+
+ mame pacman -nofilter
+
.. _mame-commandline-unevenstretch:
**-[no]unevenstretch**
Allow non-integer scaling factors allowing for great window sizing
- flexability.
+ flexibility.
The default is ON. (**-unevenstretch**)
+ Example:
+ .. code-block:: bash
+
+ mame dkong -nounevenstretch
+
+
+.. _mame-commandline-fullscreen:
Core Full Screen Options
------------------------
@@ -1360,22 +2384,26 @@ Core Full Screen Options
On modern video cards, there is little reason to switch resolutions unless
you are trying to achieve the "exact" pixel resolutions of the original
- systems, which requires significant tweaking. This option is also useful
+ systems, which requires significant tweaking. This is also true
on LCD displays, since they run with a fixed resolution and switching
resolutions on them is just silly. This option does not work with
- **-video gdi**.
+ **-video gdi** and **-video bgfx**.
The default is OFF (**-noswitchres**).
+ Example:
+ .. code-block:: bash
+
+ mame kof97 -video d3d -switchres -resolution 1280x1024
+
+
+.. _mame-commandline-windowoptions:
Core Per-Window Options
-----------------------
.. _mame-commandline-screen:
-NOTE: **Multiple Screens may fail to work correctly on some Mac machines as of
-right now.**
-
**-screen** *<display>*
**-screen0** *<display>*
@@ -1402,6 +2430,22 @@ right now.**
to the specific window. The **-screen** parameter applies to all windows.
The window-specific options override values from the all window option.
+ Example 1:
+ .. code-block:: bash
+
+ mame pc_cntra -numscreens 2 -screen0 \\.\DISPLAY1 -screen1 \\.\DISPLAY2
+
+ Example 2:
+ .. code-block:: bash
+
+ mame darius -numscreens 3 -screen0 \\.\DISPLAY1 -screen1 \\.\DISPLAY3 -screen2 \\.\DISPLAY2
+
+.. Tip:: Using **-verbose** will tell you which displays you have on your
+ system, where they are connected, and what their current resolutions
+ are.
+
+.. Tip:: **Multiple Screens may fail to work correctly on some Mac machines as
+ of right now.**
.. _mame-commandline-aspect:
@@ -1430,6 +2474,16 @@ right now.**
to the specific window. The **-aspect** parameter applies to all windows.
The window-specific options override values from the all window option.
+ Example 1:
+ .. code-block:: bash
+
+ mame contra -aspect 16:9
+
+ Example 2:
+ .. code-block:: bash
+
+ mame pc_cntra -numscreens 2 -aspect0 16:9 -aspect1 5:4
+
.. _mame-commandline-resolution:
@@ -1463,6 +2517,10 @@ right now.**
applies to all windows. The window-specific options override values from
the all window option.
+ Example:
+ .. code-block:: bash
+
+ mame pc_cntra -numscreens 2 -resolution0 1920x1080 -resolution1 1280x1024
.. _mame-commandline-view:
@@ -1476,20 +2534,38 @@ right now.**
**-view3** *<viewname>*
- Specifies the initial view setting for each window. The *<viewname>* does
- not need to be a perfect match; rather, it will select the first view whose
- name matches all the characters specified by *<viewname>*. For example,
- **-view native** will match the "*Native (15:14)*" view even though it is
- not a perfect match. The value ``auto`` is also supported, and requests
- that MAME perform a default selection.
+ Specifies the initial view setting for each window/screen. The *<viewname>*
+ does not need to be the full name of a view, MAME will choose the first view
+ with a name that has the *<viewname>* as a prefix. For example
+ **-view "screen 0 pixel"** will match the
+ “\ *Screen 0 Pixel Aspect (10:7)*\ ” view.
+
+ If the *<viewname>* is ``auto`` or an empty string, MAME will select views
+ based on the number of emulated screens in the system, the number of
+ windows/screens MAME is using, and the available external and internal
+ artwork. MAME tries to select views so that all emulated screens are
+ visible by default.
The default value for these options is ``auto``.
The **-view0**, **-view1**, **-view2**, **-view3** parameters apply to the
- specific window. The **-view** parameter applies to all windows. The
- window-specific options override values from the all window option.
+ specific window. The **-view** parameter applies to all windows. The
+ window-specific options override values from the all windows option.
+
+ Note that view settings saved in the configuration file for the machine take
+ precedence over the initial view settings. If you change the selected views
+ in the Video Options menu, this will be saved in the configuration file for
+ the machine and take precedence over any initial views specified in INI
+ files or on the command line.
+
+ Example:
+ .. code-block:: bash
+
+ mame contra -view native
+.. _mame-commandline-artwork:
+
Core Artwork Options
--------------------
@@ -1504,12 +2580,32 @@ Core Artwork Options
The default is OFF **-noartwork_crop**.
+ Example:
+ .. code-block:: bash
+
+ mame pacman -artwork_crop
+
+.. Tip:: **-artwork_crop** is great for widescreen displays. You will get a
+ full-sized system display and the artwork will fill the empty space on
+ the sides as much as possible.
+
.. _mame-commandline-fallbackartwork:
**-fallback_artwork**
Specifies fallback artwork if no external artwork or internal driver layout
- is defined.
+ is defined. If external artwork for the system is present or a layout is
+ included in the driver for the system, then that will take precedence.
+
+ Example:
+ .. code-block:: bash
+
+ mame coco -fallback_artwork suprmrio
+
+.. Tip:: You can use **fallback_artwork <artwork name>** in
+ ``horizontal.ini`` and ``vertical.ini`` to specify different
+ fallback artwork choices for horizontal and vertical systems.
+
.. _mame-commandline-overrideartwork:
@@ -1517,7 +2613,13 @@ Core Artwork Options
Specifies override artwork for external artwork and internal driver layout.
+ Example:
+ .. code-block:: bash
+ mame galaga -override_artwork puckman
+
+
+.. _mame-commandline-screenoptions:
Core Screen Options
-------------------
@@ -1530,11 +2632,14 @@ Core Screen Options
This option does not affect the artwork or other parts of the display.
Using the MAME UI, you can individually set the brightness for each system
screen; this option controls the initial value for all visible system
- screens. The standard value is ``1.0``. Selecting lower values
+ screens. The standard and default value is ``1.0``. Selecting lower values
(down to 0.1) will produce a darkened display, while selecting higher values
(up to 2.0) will give a brighter display.
- The default is ``1.0``.
+ Example:
+ .. code-block:: bash
+
+ mame pacman -brightness 0.5
.. _mame-commandline-contrast:
@@ -1544,11 +2649,14 @@ Core Screen Options
does not affect the artwork or other parts of the display. Using the MAME
UI, you can individually set the contrast for each system screen; this
option controls the initial value for all visible system screens. The
- standard value is ``1.0``. Selecting lower values (down to 0.1) will
- produce a dimmer display, while selecting higher values (up to 2.0) will
- give a more saturated display.
+ standard and default value is ``1.0``. Selecting lower values (down to 0.1)
+ will produce a dimmer display, while selecting higher values (up to 2.0)
+ will give a more saturated display.
- The default is ``1.0``.
+ Example:
+ .. code-block:: bash
+
+ mame pacman -contrast 0.5
.. _mame-commandline-gamma:
@@ -1558,13 +2666,18 @@ Core Screen Options
ramp, for the system screens. This option does not affect the artwork or
other parts of the display. Using the MAME UI, you can individually set
the gamma for each system screen; this option controls the initial value for
- all visible system screens. The standard value is ``1.0``, which gives a
- linear ramp from black to white. Selecting lower values (down to 0.1) will
- increase the nonlinearity toward black, while selecting higher values
- (up to 3.0) will push the nonlinearity toward white.
+ all visible system screens. The standard and default value is ``1.0``,
+ which gives a linear ramp from black to white. Selecting lower values
+ (down to 0.1) will increase the nonlinearity toward black, while
+ selecting higher values (up to 3.0) will push the nonlinearity toward white.
The default is ``1.0``.
+ Example:
+ .. code-block:: bash
+
+ mame pacman -gamma 0.8
+
.. _mame-commandline-pausebrightness:
**-pause_brightness** *<value>*
@@ -1573,6 +2686,11 @@ Core Screen Options
The default value is ``0.65``.
+ Example:
+ .. code-block:: bash
+
+ mame pacman -pause_brightness 0.33
+
.. _mame-commandline-effect:
**-effect** *<filename>*
@@ -1591,7 +2709,13 @@ Core Screen Options
The default is ``none``, meaning no effect.
+ Example:
+ .. code-block:: bash
+
+ mame pacman -effect scanlines
+
+.. _mame-commandline-vectoroptions:
Core Vector Options
-------------------
@@ -1600,19 +2724,62 @@ Core Vector Options
**-beam_width_min** *<width>*
- Sets the vector beam minimum width.
+ Sets the vector beam minimum width. The beam width varies between
+ the minimum and maximum beam widths as the intensity of the vector
+ drawn changes. To disable vector width changes based on intensity,
+ set the maximum equal to the minimum.
+
+ Example:
+ .. code-block:: bash
+
+ mame asteroid -beam_width_min 0.1
.. _mame-commandline-beamwidthmax:
**-beam_width_max** *<width>*
- Sets the vector beam maximum width.
+ Sets the vector beam maximum width. The beam width varies between
+ the minimum and maximum beam widths as the intensity of the vector
+ drawn changes. To disable vector width changes based on intensity,
+ set the maximum equal to the minimum.
+
+ Example:
+ .. code-block:: bash
+
+ mame asteroid -beam_width_max 2
.. _mame-commandline-beamintensityweight:
**-beam_intensity_weight** *<weight>*
- Sets the vector beam intensity weight.
+ Sets the vector beam intensity weight. This value determines how the
+ intensity of the vector drawn affects the width. A value of 0 creates
+ a linear mapping from intensity to width. Negative values mean that
+ lower intensities will increase the width toward maximum faster,
+ while positive values will increase the width toward maximum more
+ slowly.
+
+ Example:
+ .. code-block:: bash
+
+ mame asteroid -beam_intensity_weight 0.5
+
+.. _mame-commandline-beamdotsize:
+
+**-beam_dot_size** *<scale>*
+
+ Scale factor to apply to the size of single-point dots in vector games.
+ Normally these are rendered according to the computed beam width; however,
+ it is common for this to produce dots that are difficult to see. The
+ beam_dot_size option applies a scale factor on top of the beam width to
+ help them show up better.
+
+ The default is ``1``.
+
+ Example:
+ .. code-block:: bash
+
+ mame asteroid -beam_dot_size 2
.. _mame-commandline-flicker:
@@ -1624,15 +2791,25 @@ Core Vector Options
The default is ``0``.
+ Example:
+ .. code-block:: bash
-Core Video OpenGL Debugging Options
------------------------------------
+ mame asteroid -flicker 0.15
+
+
+.. _mame-commandline-opengloptions:
+
+Core Video OpenGL Feature Options
+---------------------------------
These options are for compatibility in **-video opengl**. If you report
-rendering artifacts you may be asked to try messing with them by the devs, but
-normally they should be left at their defaults which results in the best
+rendering artifacts you may be asked to try messing with them by the developers,
+but normally they should be left at their defaults which results in the best
possible video performance.
+.. Tip:: Examples are not provided for these options as MAMEdev will provide
+ suitable test options in the case of needing them for debugging.
+
.. _mame-commandline-glforcepow2texture:
**-[no]gl_forcepow2texture**
@@ -1661,21 +2838,28 @@ possible video performance.
**-[no]gl_pbo**
- Enable OpenGL PBO (Pixel Buffer Objects), if available (default ``on``)
+ Enable OpenGL PBO (Pixel Buffer Objects), if available (default ``on`` )
The default is ON. (**-gl_pbo**)
+.. _mame-commandline-openglglsl:
+
Core Video OpenGL GLSL Options
------------------------------
.. _mame-commandline-glglsl:
-**-gl_glsl**
+**-[no]gl_glsl**
Enable OpenGL GLSL, if available.
- The default is OFF.
+ The default is OFF (**-nogl_glsl**).
+
+ Example:
+ .. code-block:: bash
+
+ mame galaxian -gl_glsl
.. _mame-commandline-glglslfilter:
@@ -1688,6 +2872,11 @@ Core Video OpenGL GLSL Options
The default is 1. (**-gl_glsl_filter 1**)
+ Example:
+ .. code-block:: bash
+
+ mame galaxian -gl_glsl -gl_glsl_filter 0
+
.. _mame-commandline-glslshadermame:
**-glsl_shader_mame0**
@@ -1698,18 +2887,17 @@ Core Video OpenGL GLSL Options
**-glsl_shader_mame9**
+ Set a custom OpenGL GLSL shader effect to the internal system screen in the
+ given slot. MAME does not include a vast selection of shaders by default;
+ more can be found online.
- Custom OpenGL GLSL shader set MAME bitmap in the provided slot (0-9); one
- can be applied to each slot.
-
- [todo: better details on usage at some point.
- See http://forums.bannister.org/ubbthreads.php?ubb=showflat&Number=100988#Post100988 ]
-
+ Example:
+ .. code-block:: bash
+ mame suprmrio -gl_glsl -glsl_shader_mame0 NTSC/NTSC_chain -glsl_shader_mame1 CRT-geom/CRT-geom
.. _mame-commandline-glslshaderscreen:
-
**-glsl_shader_screen0**
**-glsl_shader_screen1**
@@ -1719,21 +2907,17 @@ Core Video OpenGL GLSL Options
**-glsl_shader_screen9**
- Custom OpenGL GLSL shader screen bitmap in the provided slot (0-9).
-
- [todo: better details on usage at some point.
- See http://forums.bannister.org/ubbthreads.php?ubb=showflat&Number=100988#Post100988 ]
-
-
-.. _mame-commandline-glglslvidattr:
+ Set a custom OpenGL GLSL shader effect to the whole scaled-up output screen
+ that will be rendered by your graphics card. MAME does not include a vast
+ selection of shaders by default; more can be found online.
-**-gl_glsl_vid_attr**
+ Example:
+ .. code-block:: bash
- Enable OpenGL GLSL handling of brightness and contrast.
- Better RGB system performance.
+ mame suprmrio -gl_glsl -glsl_shader_screen0 gaussx -glsl_shader_screen1 gaussy -glsl_shader_screen2 CRT-geom-halation
- Default is ``on``.
+.. _mame-commandline-soundoptions:
Core Sound Options
------------------
@@ -1748,6 +2932,11 @@ Core Sound Options
The default is ``48000``.
+ Example:
+ .. code-block:: bash
+
+ mame galaga -samplerate 44100
+
.. _mame-commandline-nosamples:
**-[no]samples**
@@ -1756,30 +2945,50 @@ Core Sound Options
The default is ON (**-samples**).
+ Example:
+ .. code-block:: bash
+
+ mame qbert -nosamples
+
+.. _mame-commandline-nocompressor:
+
+**-[no]compressor**
+
+ Enable audio compressor. It temporarily reduces the overall volume when
+ the audio output is overdriven.
+
+ The default is ON (**-compressor**).
+
+ Example:
+ .. code-block:: bash
+
+ mame popeye -nocompressor
+
.. _mame-commandline-volume:
**-volume** / **-vol** *<value>*
- Sets the startup volume. It can later be changed with the user interface
- (see Keys section). The volume is an attenuation in dB: e.g.,
- "**-volume -12**" will start with -12dB attenuation.
+ Sets the initial sound volume. It can be changed later with the user
+ interface (see Keys section). The volume is in decibels:
+ e.g. "**-volume -12**" will start with -12 dB attenuation. Note that if the
+ volume is changed in the user interface it will be saved to the
+ configuration file for the system. The value from the configuration file
+ for the system has priority over ``volume`` settings in general INI files.
- The default is ``0``.
+ The default is ``0`` (no attenuation, or full volume).
+
+ Example:
+ .. code-block:: bash
+
+ mame pacman -volume -30
.. _mame-commandline-sound:
-**-sound** *<``dsound``|``coreaudio``|``sdl``|``xaudio2``|``portaudio``|``none``>*
+**-sound** *<dsound | coreaudio | sdl | xaudio2 | portaudio | none>*
Specifies which sound subsystem to use. Selecting ``none`` disables sound
output altogether (sound hardware is still emulated).
-| On Windows, ``dsound``, ``xaudio2``, ``portaudio`` and ``none`` are available.
-| On macOS, ``coreaudio``, ``sdl``, ``portaudio`` and ``none`` are available.
-| On other operating systems, ``sdl``, ``portaudio`` and ``none`` are available. (Special build options allow ``sdl`` to be used on Windows, or ``portaudio`` to be disabled.)
-|
-| The default is ``dsound`` on Windows. On Mac, ``coreaudio`` is the default. On all other platforms, ``sdl`` is the default.
-|
-
On Windows and Linux, *portaudio* is likely to give the lowest possible
latency, while Mac users will find *coreaudio* provides the best results.
@@ -1788,6 +2997,45 @@ Core Sound Options
depend on the operating system. On Windows, it may be necessary to set
``SDL_AUDIODRIVER=directsound`` if no sound output is produced by default.
+ The default is ``dsound`` on Windows. On Mac, ``coreaudio`` is the default.
+ On all other platforms, ``sdl`` is the default.
+
+ Example:
+ .. code-block:: bash
+
+ mame pacman -sound portaudio
+
+.. list-table:: Supported sound subsystems per-platform
+ :header-rows: 0
+ :stub-columns: 0
+
+ * - **Microsoft Windows**
+ - dsound
+ - xaudio2
+ - portaudio
+ -
+ - sdl [#SoundWinSDL]_.
+ - none
+ * - **macOS**
+ -
+ -
+ - portaudio
+ - coreaudio
+ - sdl
+ - none
+ * - **Linux** and others
+ -
+ -
+ - portaudio
+ -
+ - sdl
+ - none
+
+
+.. rubric:: Footnotes
+
+.. [#SoundWinSDL] While SDL is not a supported option on official builds for Windows, you can compile MAME with SDL support on Windows.
+
.. _mame-commandline-audiolatency:
**-audio_latency** *<value>*
@@ -1799,6 +3047,19 @@ Core Sound Options
The default is ``1``.
+ * For PortAudio, see the section on :ref:`-pa_latency <mame-commandline-palatency>`.
+ * XAudio2 calculates audio_latency as 10ms steps.
+ * DSound calculates audio_latency as 10ms steps.
+ * CoreAudio calculates audio_latency as 25ms steps.
+ * SDL calculates audio_latency as Xms steps.
+
+ Example:
+ .. code-block:: bash
+
+ mame galaga -audio_latency 1
+
+
+.. _mame-commandline-inputoptions:
Core Input Options
------------------
@@ -1817,15 +3078,27 @@ Core Input Options
The default is ON (**-coin_lockout**).
+ Example:
+ .. code-block:: bash
+
+ mame suprmrio -coin_lockout
+
.. _mame-commandline-ctrlr:
**-ctrlr** *<controller>*
- Enables support for special controllers. Configuration files are loaded from
- the ctrlrpath. They are in the same format as the .cfg files that are
- saved, but only control configuration data is read from the file.
+ Specifies a controller configuration file, typically used to set more
+ suitable default input assignments for special controllers. Directories
+ specified using the ``ctrlrpath`` option are searched. Controller
+ configuration files use a similar format to ``.cfg`` used to save system
+ settings. See :ref:`ctrlrcfg` for more details.
- The default is ``NULL`` (no controller file).
+ The default is ``NULL`` (no controller configuration file).
+
+ Example:
+ .. code-block:: bash
+
+ mame dkong -ctrlr xarcade
.. _mame-commandline-nomouse:
@@ -1833,31 +3106,67 @@ Core Input Options
Controls whether or not MAME makes use of mouse controllers. When this is
enabled, you will likely be unable to use your mouse for other purposes
- until you exit or pause the system.
+ until you exit or pause the system. Supported mouse controllers depend on
+ your :ref:`mouseprovider setting <mame-commandline-mouseprovider>`.
+
+ Note that if this setting is off (**-nomouse**), mouse input may still be
+ enabled depending on the inputs present on the emulated system and your
+ :ref:`automatic input enable settings <mame-commandline-inputenable>`. In
+ particular, the default is to enable mouse input when the emulated system
+ has mouse inputs (**-mouse_device mouse**), so MAME will capture your mouse
+ pointer when you run a system with mouse inputs unless you also change
+ the **mouse_device** setting.
The default is OFF (**-nomouse**).
+ Example:
+ .. code-block:: bash
+
+ mame centiped -mouse
+
.. _mame-commandline-nojoystick:
**-[no]joystick** / **-[no]joy**
- Controls whether or not MAME makes use of joystick/gamepad controllers.
+ Controls whether or not MAME makes use of game controllers (e.g. joysticks,
+ gamepads and simulation controls). Supported game controllers depend on
+ your :ref:`joystickprovider setting <mame-commandline-joystickprovider>`.
When this is enabled, MAME will ask the system about which controllers are
connected.
+ Note that if this setting is off (**-nojoystick**), joystick input may still
+ be enabled depending on the inputs present on the emulated system and your
+ :ref:`automatic input enable settings <mame-commandline-inputenable>`.
+
The default is OFF (**-nojoystick**).
+ Example:
+ .. code-block:: bash
+
+ mame mappy -joystick
+
.. _mame-commandline-nolightgun:
**-[no]lightgun** / **-[no]gun**
Controls whether or not MAME makes use of lightgun controllers. Note that
- most lightguns map to the mouse, so using **-lightgun** and **-mouse**
- together may produce strange results.
+ most lightguns also produce mouse input, so enabling mouse and lightgun
+ controllers simultaneously (using **-lightgun** and **-mouse** together) may
+ produce strange behaviour. Supported lightgun controllers depend on your
+ :ref:`lightgunprovider setting <mame-commandline-lightgunprovider>`.
+
+ Note that if this setting is off (**-nolightgun**), lightgun input may still
+ be enabled depending on the inputs present on the emulated system and your
+ :ref:`automatic input enable settings <mame-commandline-inputenable>`.
The default is OFF (**-nolightgun**).
+ Example:
+ .. code-block:: bash
+
+ mame lethalen -lightgun
+
.. _mame-commandline-nomultikeyboard:
**-[no]multikeyboard** / **-[no]multikey**
@@ -1871,6 +3180,11 @@ Core Input Options
The default is OFF (**-nomultikeyboard**).
+ Example:
+ .. code-block:: bash
+
+ mame sf2ceua -multikey
+
.. _mame-commandline-nomultimouse:
**-[no]multimouse**
@@ -1883,6 +3197,11 @@ Core Input Options
The default is OFF (**-nomultimouse**).
+ Example:
+ .. code-block:: bash
+
+ mame warlords -multimouse
+
.. _mame-commandline-nosteadykey:
**-[no]steadykey** / **-[no]steady**
@@ -1896,6 +3215,11 @@ Core Input Options
The default is OFF (**-nosteadykey**)
+ Example:
+ .. code-block:: bash
+
+ mame sf2ua -steadykey
+
.. _mame-commandline-uiactive:
**-[no]ui_active**
@@ -1904,6 +3228,11 @@ Core Input Options
The default is OFF (**-noui_active**)
+ Example:
+ .. code-block:: bash
+
+ mame apple2e -ui_active
+
.. _mame-commandline-nooffscreenreload:
**-[no]offscreen_reload** / **-[no]reload**
@@ -1917,37 +3246,71 @@ Core Input Options
The default is OFF (**-nooffscreen_reload**).
+ Example:
+ .. code-block:: bash
+
+ mame lethalen -offscreen_reload
+
.. _mame-commandline-joystickmap:
**-joystick_map** *<map>* / **-joymap** *<map>*
- Controls how joystick values map to digital joystick controls. MAME accepts
- all joystick input from the system as analog data. For true analog
- joysticks, this needs to be mapped down to the usual 4-way or 8-way digital
- joystick values. To do this, MAME divides the analog range into a 9x9 grid.
- It then takes the joystick axis position (for X and Y axes only), maps it to
- this grid, and then looks up a translation from a joystick map. This
+ Controls how analog joystick values map to digital joystick controls.
+
+ Systems such as Pac-Man use a 4-way digital joystick and will exhibit
+ undesired behavior when a diagonal is triggered; in the case of Pac-Man,
+ movement will stop completely at intersections when diagonals are triggered
+ and the game will be considerably harder to play correctly. Many other
+ arcade cabinets used 4-way or 8-way joysticks (as opposed to full analog
+ joysticks), so for true analog joysticks such as flight sticks and analog
+ thumb sticks, this then needs to be mapped down to the expected
+ 4-way or 8-way digital joystick values.
+
+ To do this, MAME divides the analog range into a 9x9 grid that looks
+ like this:
+
+ **insert 9x9 grid picture here**
+
+ MAME then takes the joystick axis position (for X and Y axes only), maps it
+ to this grid, and then looks up a translation from a joystick map. This
parameter allows you to specify the map.
+ For instance, an 8-way joystick map traditionally looks like this:
+
+ **insert 8-way map picture here**
+
+ This mapping gives considerable leeway to the angles accepted for a given
+ direction, so that being approximately in the area of the direction you want
+ will give you the results you want. Without that, if you were slightly off
+ center while holding the stick left, it would not recognize the action
+ correctly.
+
The default is ``auto``, which means that a standard 8-way, 4-way, or 4-way
diagonal map is selected automatically based on the input port configuration
of the current system.
+ Generally you will want to set up the **-joystick_map** setting in the
+ per-system ``<system>.ini`` file as opposed to the main ``MAME.INI``
+ file so that the mapping only affects the systems you want it to. See
+ :ref:`Multiple Configuration Files <advanced-multi-CFG>` for further
+ details on per-system configuration.
+
Maps are defined as a string of numbers and characters. Since the grid is
- 9x9, there are a total of 81 characters necessary to define a complete map.
- Below is an example map for an 8-way joystick:
-
- +-------------+---------------------------------------------------------+
- | | 777888999 | |
- | | 777888999 | | Note that the numeric digits correspond to the keys |
- | | 777888999 | | on a numeric keypad. So '7' maps to up+left, '4' maps |
- | | 444555666 | | to left, '5' maps to neutral, etc. In addition to the |
- | | 444555666 | | numeric values, you can specify the character 's', |
- | | 444555666 | | which means "sticky". In this case, the value of the |
- | | 111222333 | | map is the same as it was the last time a non-sticky |
- | | 111222333 | | value was read. |
- | | 111222333 | |
- +-------------+---------------------------------------------------------+
+ 9x9, there are a total of 81 characters necessary to define a complete
+ map. Below is an example map for an 8-way joystick that matches the
+ picture shown above:
+
+ +-------------+--------------------------------------------------------+
+ | | 777888999 | |
+ | | 777888999 | | Note that the numeric digits correspond to the keys |
+ | | 777888999 | | on a numeric keypad. So '7' maps to up+left, '4' maps|
+ | | 444555666 | | to left, '5' maps to neutral, etc. In addition to the|
+ | | 444555666 | | numeric values, you can specify the character 's', |
+ | | 444555666 | | which means "sticky". Sticky map positions will keep|
+ | | 111222333 | | the output the same as the last non-sticky input sent|
+ | | 111222333 | | to the system. |
+ | | 111222333 | |
+ +-------------+--------------------------------------------------------+
To specify the map for this parameter, you can specify a string of rows
separated by a '.' (which indicates the end of a row), like so:
@@ -1983,16 +3346,62 @@ Core Input Options
up/down mirrors of the first three rows, giving three final rows of
111222333.
+ With 4-way games, sticky becomes important to avoid problems with
+ diagonals. Typically you would choose a map that looks something like this:
+
+ **insert 9x9 4-way sticky grid picture here**
+
+ This means that if you press left, then roll the stick towards up (without
+ re-centering it) you'll pass through the sticky section in the corner. As
+ you do, MAME will read that sticky corner as **left** as that's the last
+ non-sticky input it received. As the roll gets into the upward space of
+ the map, this then switches to an up motion.
+
+ This map would look somewhat like:
+
+ +-------------+---------------------------------------------------------+
+ | | s8888888s | |
+ | | 4s88888s6 | | For this mapping, we have a wide range for the |
+ | | 44s888s66 | | cardinal directions on 8, 4, 6, and 2. We have sticky|
+ | | 444555666 | | on the meeting points between those cardinal |
+ | | 444555666 | | directions where the appropriate direction isn't |
+ | | 444555666 | | going to be completely obvious. |
+ | | 44s222s66 | |
+ | | 4s22222s6 | |
+ | | s2222222s | |
+ +-------------+---------------------------------------------------------+
+
+ To specify the map for this parameter, you can specify a string of rows
+ separated by a '.' (which indicates the end of a row), like so:
+
+ +-------------------------------------------------------------------------------------------------------+
+ | **-joymap s8888888s.4s88888s6.44s888s66.444555666.444555666.444555666.44s222s66.4s22222s6.s2222222s** |
+ +-------------------------------------------------------------------------------------------------------+
+
+ Like before, because of the symmetry between top and bottom and left and
+ right, we can shorten this down to:
+
+ +------------------------------+
+ | **-joymap s8.4s8.44s8.4445** |
+ +------------------------------+
+
+
+
.. _mame-commandline-joystickdeadzone:
**-joystick_deadzone** *<value>* / **-joy_deadzone** *<value>* / **-jdz** *<value>*
- If you play with an analog joystick, the center can drift a little.
- joystick_deadzone tells how far along an axis you must move before the axis
- starts to change. This option expects a float in the range of 0.0 to 1.0.
- Where 0 is the center of the joystick and 1 is the outer limit.
+ If you play with an analog joystick, the center can drift a little.
+ joystick_deadzone tells how far along an axis you must move before the axis
+ starts to change. This option expects a float in the range of 0.0 to 1.0.
+ Where 0 is the center of the joystick and 1 is the outer limit.
- The default is ``0.3``.
+ The default is ``0.15``.
+
+ Example:
+ .. code-block:: bash
+
+ mame sinistar -joystick_deadzone 0.3
.. _mame-commandline-joysticksaturation:
@@ -2006,13 +3415,41 @@ Core Input Options
The default is ``0.85``.
+ Example:
+ .. code-block:: bash
+
+ mame sinistar -joystick_saturation 1.0
+
+.. _mame-commandline-joystickthreshold:
+
+**-joystick_threshold** *<value>* / **joy_threshold** *<value>* / **-jthresh** *<value>*
+
+ When a joystick axis (or other absolute analog axis) is assigned to a
+ digital input, this controls how far it must be moved from the neutral
+ position (or centre) to be considered active or switched on. This option
+ expects a float in the range of 0.0 to 1.0, where 0 means any movement from
+ the neutral position is considered active, and 1 means only the outer limits
+ are considered active. This threshold is **not** adjusted to the range
+ between the dead zone and saturation point.
+
+ Note that if a :ref:`joystick map <mame-commandline-joystickmap>` is
+ configured, that will take precedence over this setting when a joystick’s
+ main X/Y axes are assigned to digital inputs.
+
+ The default is ``0.3``.
+
+ Example:
+ .. code-block:: bash
+
+ mame raiden -joystick_threshold 0.2
+
.. _mame-commandline-natural:
-**\-natural**
+**\-[no]natural**
Allows user to specify whether or not to use a natural keyboard or not.
This allows you to start your system in a 'native' mode, depending on your
- region, allowing compatability for non-"QWERTY" style keyboards.
+ region, allowing compatibility for non-"QWERTY" style keyboards.
The default is OFF (**-nonatural**)
@@ -2022,28 +3459,42 @@ Core Input Options
presses/releases the emulated key.
In "natural keyboard" mode, MAME attempts to translate characters to
- keystrokes. The OS translates keystrokes to characters
- (similarly when you type into a text editor), and MAME attempts to translate
- these characters to emulated keystrokes.
+ keystrokes. The OS translates keystrokes to characters (similarly to when
+ you type into a text editor), and MAME attempts to translate these
+ characters to emulated keystrokes.
**There are a number of unavoidable limitations in "natural keyboard" mode:**
- * The emulated system driver and/or keyboard device or has to support it.
- * The selected keyboard *must* match the keyboard layout selected in the emulated OS!
- * Keystrokes that don't produce characters can't be translated. (e.g. pressing a modifier on its own such as **shift**, **ctrl**, or **alt**)
- * Holding a key until the character repeats will cause the emulated key to be pressed repeatedly as opposed to being held down.
- * Dead key sequences are cumbersome to use at best.
- * It won't work at all if IME edit is involved. (e.g. for Chinese/Japanese/Korean)
+ * The emulated system driver and/or keyboard device has to support it.
+ * The selected keyboard layout *must* match the keyboard layout selected in
+ the emulated OS!
+ * Keystrokes that don’t produce characters can’t be translated (e.g.
+ pressing a modifier on its own such as **shift**, **ctrl**, or **alt**).
+ * Holding a key until the character repeats will cause the emulated key to
+ be pressed repeatedly as opposed to being held down.
+ * Dead key sequences are cumbersome to use at best.
+ * It won’t work at all if IME edit is involved (e.g. for Chinese, Japanese
+ or Korean language input).
+
+ Example:
+ .. code-block:: bash
+
+ mame coco2 -natural
.. _mame-commandline-joystickcontradictory:
-**-joystick_contradictory**
+**-[no]joystick_contradictory**
Enable contradictory direction digital joystick input at the same time such
as **Left and Right** or **Up and Down** at the same time.
The default is OFF (**-nojoystick_contradictory**)
+ Example:
+ .. code-block:: bash
+
+ mame pc_smb -joystick_contradictory
+
.. _mame-commandline-coinimpulse:
**-coin_impulse** *[n]*
@@ -2053,54 +3504,78 @@ Core Input Options
Default is ``0``.
+ Example:
+ .. code-block:: bash
+
+ mame contra -coin_impulse 1
+
+.. _mame-commandline-inputenable:
Core Input Automatic Enable Options
-----------------------------------
.. _mame-commandline-paddledevice:
-**-paddle_device** (``none``|``keyboard``|``mouse``|``lightgun``|``joystick``)
+**-paddle_device** ( ``none`` | ``keyboard`` | ``mouse`` | ``lightgun`` | ``joystick`` )
.. _mame-commandline-adstickdevice:
-**-adstick_device** (``none``|``keyboard``|``mouse``|``lightgun``|``joystick``)
+**-adstick_device** ( ``none`` | ``keyboard`` | ``mouse`` | ``lightgun`` | ``joystick`` )
.. _mame-commandline-pedaldevice:
-**-pedal_device** (``none``|``keyboard``|``mouse``|```lightgun``|``joystick``)
+**-pedal_device** ( ``none`` | ``keyboard`` | ``mouse`` | ```lightgun`` | ``joystick`` )
.. _mame-commandline-dialdevice:
-**-dial_device** (``none``|``keyboard``|``mouse``|``lightgun``|``joystick``)
+**-dial_device** ( ``none`` | ``keyboard`` | ``mouse`` | ``lightgun`` | ``joystick`` )
.. _mame-commandline-trackballdevice:
-**-trackball_device** (``none``|``keyboard``|``mouse``|``lightgun``|``joystick``)
+**-trackball_device** ( ``none`` | ``keyboard`` | ``mouse`` | ``lightgun`` | ``joystick`` )
.. _mame-commandline-lightgundevice:
-**-lightgun_device** (``none``|``keyboard``|``mouse``|``lightgun``|``joystick``)
+**-lightgun_device** ( ``none`` | ``keyboard`` | ``mouse`` | ``lightgun`` | ``joystick`` )
.. _mame-commandline-positionaldevice:
-**-positional_device** (``none``|``keyboard``|``mouse``|``lightgun``|``joystick``)
+**-positional_device** ( ``none`` | ``keyboard`` | ``mouse`` | ``lightgun`` | ``joystick`` )
.. _mame-commandline-mousedevice:
-**-mouse_device** (``none``|``keyboard``|``mouse``|``lightgun``|``joystick``)
+**-mouse_device** ( ``none`` | ``keyboard`` | ``mouse`` | ``lightgun`` | ``joystick`` )
+
+ Each of these options sets whether mouse, joystick or lightgun controllers
+ should be enabled when running an emulated system that uses a particular
+ class of analog inputs. These options can effectively set
+ :ref:`-mouse <mame-commandline-nomouse>`, :ref:`-joystick
+ <mame-commandline-nojoystick>` and/or :ref:`-lightgun
+ <mame-commandline-nolightgun>` depending on the type of inputs present on
+ the emulated system. Note that these options *will not* override explicit
+ **-nomouse**, **-nojoystick** and/or **-nolightgun** settings at a higher
+ priority level (e.g. in a more specific INI file or on the command line).
+
+ For example, if you specify the option **-paddle_device mouse**, then mouse
+ controls will automatically be enabled when you run a game that has paddle
+ controls (e.g. Super Breakout), even if you specified **-nomouse** .
+
+ The default is to automatically enable mouse controls when running emulated
+ systems with mouse inputs (**-mouse_device mouse**).
+
+ Example:
+ .. code-block:: bash
- Each of these options controls autoenabling the mouse, joystick, or lightgun
- depending on the presence of a particular class of analog control for a
- particular system. For example, if you specify the option
- **-paddle mouse**, then any game that has a paddle control will
- automatically enable mouse controls just as if you had explicitly specified
- **-mouse**.
+ mame sbrkout -paddle_device mouse
- Note that these controls override the values of **-[no]mouse**,
- **-[no]joystick**, etc.
+.. Tip:: Note that these settings can override **-nomouse**, **-nojoystick**
+ and/or **-nolightgun** depending on the inputs present on the emulated
+ system.
+.. _mame-commandline-debugging:
+
Debugging Options
-----------------
@@ -2109,12 +3584,18 @@ Debugging Options
**-[no]verbose** / **-[no]v**
Displays internal diagnostic information. This information is very useful
- for debugging problems with your configuration. IMPORTANT: when reporting
- bugs, please run with **mame -verbose** and include the resulting
- information.
+ for debugging problems with your configuration.
The default is OFF (**-noverbose**).
+ Example:
+ .. code-block:: bash
+
+ mame polepos -verbose
+
+.. Tip:: IMPORTANT: When reporting bugs to MAMEdev, please run with **-verbose**
+ and include the resulting information.
+
.. _mame-commandline-oslog:
**-[no]oslog**
@@ -2129,26 +3610,82 @@ Debugging Options
The default is OFF (**-nooslog**).
+ Example:
+ .. code-block:: bash
+
+ mame mappy -oslog
+
.. _mame-commandline-log:
**-[no]log**
Creates a file called error.log which contains all of the internal log
messages generated by the MAME core and system drivers. This can be used at
- the same time as **-log** to output the log data to both targets as well.
+ the same time as **-oslog** to output the log data to both targets as well.
The default is OFF (**-nolog**).
+ Example 1:
+ .. code-block:: bash
+
+ mame qbert -log
+
+ Example 2:
+ .. code-block:: bash
+
+ mame qbert -oslog -log
+
.. _mame-commandline-debug:
**-[no]debug**
- Activates the integrated debugger. By default, the debugger is entered by
- pressing the tilde (**~**) key during emulation. It is also entered
- immediately at startup.
+ Activates the integrated debugger. By default, pressing the backtick/tilde
+ (**~**) key during emulation breaks into the debugger. MAME also breaks
+ into the debugger after the initial soft reset on startup if the debugger is
+ active. See :ref:`debugger` for information on using the debugger.
The default is OFF (**-nodebug**).
+ Example:
+ .. code-block:: bash
+
+ mame indy_4610 -debug
+
+.. _mame-commandline-debugger:
+
+**-debugger** *<module>*
+
+ Chooses the module to use for debugging the target system when the
+ :ref:`debug <mame-commandline-debug>` option is on. Available debugger
+ modules depend on the host platform and build options.
+
+ Supported debugger modules:
+
+ windows
+ Win32 GUI debugger (default on Windows). Only supported on Windows.
+ qt
+ Qt GUI debugger (default on Linux). Supported on Windows, Linux and
+ macOS, but only included on Linux by default. Set ``USE_QTDEBUG=1``
+ when compiling MAME to include the Qt debugger on Windows or macOS.
+ osx
+ Cocoa GUI debugger (default on macOS). Only supported on macOS.
+ imgui
+ ImgUi GUI debugger displayed in first MAME window. Requires
+ :ref:`video <mame-commandline-video>` option to be set to **bgfx**.
+ Supported on all platforms with BGFX video output support.
+ gdbstub
+ Acts as a remote debugging server for the GNU debugger (GDB). Only a
+ small subset of the CPUs emulated by MAME are supported. Use the
+ :ref:`debugger_port <mame-commandline-debuggerport>` option to set the
+ listening port and the
+ :ref:`debugger_host <mame-commandline-debuggerhost>` option to set the
+ address to bind to. Supported on all platforms with TCP socket support.
+
+ Example:
+ .. code-block:: bash
+
+ mame ambush -debug -debugger qt
+
.. _mame-commandline-debugscript:
**-debugscript** *<filename>*
@@ -2158,6 +3695,11 @@ Debugging Options
The default is ``NULL`` (*no commands*).
+ Example:
+ .. code-block:: bash
+
+ mame galaga -debug -debugscript testscript.txt
+
.. _mame-commandline-updateinpause:
**-[no]update_in_pause**
@@ -2168,6 +3710,11 @@ Debugging Options
The default is OFF (**-noupdate_in_pause**).
+ Example:
+ .. code-block:: bash
+
+ mame indy_4610 -update_in_pause
+
.. _mame-commandline-watchdog:
**-watchdog** *<duration>* / **-wdog** *<duration>*
@@ -2181,6 +3728,41 @@ Debugging Options
By default there is no watchdog.
+ Example:
+ .. code-block:: bash
+
+ mame ibm_5150 -watchdog 30
+
+.. _mame-commandline-debuggerhost:
+
+**-debugger_host** *<address>*
+
+ Set the IP address to listen on to accept GDB connections when using the
+ GDB stub debugger module (see the
+ :ref:`debugger <mame-commandline-debugger>` option).
+
+ The default is ``localhost``.
+
+ Example:
+ .. code-block:: bash
+
+ mame rfjet -debug -debugger gdbstub -debugger_host 0.0.0.0
+
+.. _mame-commandline-debuggerport:
+
+**-debugger_port** *<port>*
+
+ Set the TCP port number to accept GDB connections on when using the GDB
+ stub debugger module (see the :ref:`debugger <mame-commandline-debugger>`
+ option).
+
+ The default is ``23946``.
+
+ Example:
+ .. code-block:: bash
+
+ mame rfjet -debug -debugger gdbstub -debugger_port 2159
+
.. _mame-commandline-debuggerfont:
**-debugger_font** *<fontname>* / **-dfont** *<fontname>*
@@ -2191,6 +3773,11 @@ Debugging Options
| The Mac (Cocoa) default font is system fixed-pitch font default (typically ``Monaco``).
| The Qt default font is ``Courier New``.
+ Example:
+ .. code-block:: bash
+
+ mame marble -debug -debugger_font "Comic Sans MS"
+
.. _mame-commandline-debuggerfontsize:
**-debugger_font_size** *<points>* / **-dfontsize** *<points>*
@@ -2201,6 +3788,13 @@ Debugging Options
| The Qt default size is ``11`` points.
| The Mac (Cocoa) default size is the system default size.
+ Example:
+ .. code-block:: bash
+
+ mame marble -debug -debugger_font "Comic Sans MS" -debugger_font_size 16
+
+
+.. _mame-commandline-commoptions:
Core Communication Options
--------------------------
@@ -2212,9 +3806,14 @@ Core Communication Options
Local address to bind to. This can be a traditional ``xxx.xxx.xxx.xxx``
address or a string containing a resolvable hostname.
- The default is value is "``0.0.0.0``" (which binds to all local IPv4
+ The default is value is ``0.0.0.0`` (which binds to all local IPv4
addresses).
+ Example:
+ .. code-block:: bash
+
+ mame arescue -comm_localhost 192.168.1.2
+
.. _mame-commandline-commlocalport:
**-comm_localport** *<string>*
@@ -2222,7 +3821,12 @@ Core Communication Options
Local port to bind to. This can be any traditional communications port as
an unsigned 16-bit integer (0-65535).
- The default value is "``15122``".
+ The default value is ``15122``.
+
+ Example:
+ .. code-block:: bash
+
+ mame arescue -comm_localhost 192.168.1.2 -comm_localport 30100
.. _mame-commandline-commremotehost:
@@ -2234,6 +3838,11 @@ Core Communication Options
The default is value is "``0.0.0.0``" (which binds to all local IPv4
addresses).
+ Example:
+ .. code-block:: bash
+
+ mame arescue -comm_remotehost 192.168.1.2
+
.. _mame-commandline-commremoteport:
**-comm_remoteport** *<string>*
@@ -2243,6 +3852,11 @@ Core Communication Options
The default value is "``15122``".
+ Example:
+ .. code-block:: bash
+
+ mame arescue -comm_remotehost 192.168.1.2 -comm_remoteport 30100
+
.. _mame-commandline-commframesync:
**-[no]comm_framesync**
@@ -2251,6 +3865,13 @@ Core Communication Options
The default is OFF (**-nocomm_framesync**).
+ Example:
+ .. code-block:: bash
+
+ mame arescue -comm_remotehost 192.168.1.3 -comm_remoteport 30100 -comm_framesync
+
+
+.. _mame-commandline-miscoptions:
Core Misc Options
-----------------
@@ -2263,40 +3884,65 @@ Core Misc Options
The default is ON (**-drc**).
+ Example:
+ .. code-block:: bash
+
+ mame ironfort -nodrc
+
.. _mame-commandline-drcusec:
-**\-drc_use_c**
+**\-[no]drc_use_c**
Force DRC to use the C code backend.
The default is OFF (**-nodrc_use_c**).
+ Example:
+ .. code-block:: bash
+
+ mame ironfort -drc_use_c
+
.. _mame-commandline-drcloguml:
-**\-drc_log_uml**
+**\-[no]drc_log_uml**
Write DRC UML disassembly log.
The default is OFF (**-nodrc_log_uml**).
+ Example:
+ .. code-block:: bash
+
+ mame ironfort -drc_log_uml
+
.. _mame-commandline-drclognative:
-**\-drc_log_native**
+**\-[no]drc_log_native**
Write DRC native disassembly log.
The default is OFF (**-nodrc_log_native**).
+ Example:
+ .. code-block:: bash
+
+ mame ironfort -drc_log_native
+
.. _mame-commandline-bios:
**-bios** *<biosname>*
Specifies the specific BIOS to use with the current system, for systems that
- make use of a BIOS. The **-listxml** output will list all of the possible
- BIOS names for a system.
+ make use of a BIOS. The **-listbios** output will list all of the possible
+ BIOS names for a system, as does the **-listxml** output.
The default is ``default``.
+ Example:
+ .. code-block:: bash
+
+ mame mslug -bios unibios33
+
.. _mame-commandline-cheat:
**-[no]cheat** / **-[no]c**
@@ -2310,6 +3956,11 @@ Core Misc Options
The default is OFF (**-nocheat**).
+ Example:
+ .. code-block:: bash
+
+ mame dkong -cheat
+
.. _mame-commandline-skipgameinfo:
**-[no]skip_gameinfo**
@@ -2318,6 +3969,11 @@ Core Misc Options
The default is OFF (**-noskip_gameinfo**).
+ Example:
+ .. code-block:: bash
+
+ mame samsho5 -skip_gameinfo
+
.. _mame-commandline-uifont:
**-uifont** *<fontname>*
@@ -2329,13 +3985,23 @@ Core Misc Options
The default is ``default`` (use the OSD-determined default font).
+ Example:
+ .. code-block:: bash
+
+ mame -uifont "Comic Sans MS"
+
.. _mame-commandline-ui:
**-ui** *<type>*
Specifies the type of UI to use, either ``simple`` or ``cabinet``.
- The default is Cabinet (**-ui cabinet**).
+ The default is cabinet (**-ui cabinet**).
+
+ Example:
+ .. code-block:: bash
+
+ mame -ui simple
.. _mame-commandline-ramsize:
@@ -2343,29 +4009,49 @@ Core Misc Options
Allows you to change the default RAM size (if supported by driver).
+ Example:
+ .. code-block:: bash
+
+ mame coco -ramsize 16K
+
.. _mame-commandline-confirmquit:
-**\-confirm_quit**
+**\-[no]confirm_quit**
- Display a Confirm Quit dialong to screen on exit, requiring one extra step
+ Display a Confirm Quit dialog to screen on exit, requiring one extra step
to exit MAME.
The default is OFF (**-noconfirm_quit**).
+ Example:
+ .. code-block:: bash
+
+ mame pacman -confirm_quit
+
.. _mame-commandline-uimouse:
-**\-ui_mouse**
+**\-[no]ui_mouse**
- Displays a mouse cursor when using the built-in UI for MAME.
+ Displays a mouse cursor when using the built-in MAME user interface.
- The default is (**-noui_mouse**).
+ The default is ON (**-ui_mouse**).
.. _mame-commandline-language:
+ Example:
+ .. code-block:: bash
+
+ mame -ui_mouse
+
**-language** *<language>*
Specify a localization language found in the ``languagepath`` tree.
+ Example:
+ .. code-block:: bash
+
+ mame -language Japanese
+
.. _mame-commandline-nvramsave:
**-[no]nvram_save**
@@ -2377,8 +4063,14 @@ Core Misc Options
The default is ON (**-nvram_save**).
+ Example:
+ .. code-block:: bash
+
+ mame galaga88 -nonvram_save
+.. _mame-commandline-scripting:
+
Scripting Options
-----------------
@@ -2387,12 +4079,15 @@ Scripting Options
**-autoboot_command** *"<command>"*
Command string to execute after machine boot (in quotes " "). To issue a
- quote to the emulation, use """ in the string. Using **\\n** will issue a
- create a new line, issuing what was typed prior as a command.
+ quote to the emulation, use """ in the string. Using **\\n** will create
+ a new line, issuing what was typed prior as a command.
This works only with systems that support natural keyboard mode.
- Example: **-autoboot_command "load """$""",8,1\\n"**
+ Example:
+ .. code-block:: bash
+
+ mame c64 -autoboot_delay 5 -autoboot_command "load """$""",8,1\n"
.. _mame-commandline-autobootdelay:
@@ -2400,12 +4095,22 @@ Scripting Options
Timer delay (in seconds) to trigger command execution on autoboot.
+ Example:
+ .. code-block:: bash
+
+ mame c64 -autoboot_delay 5 -autoboot_command "load """$""",8,1\n"
+
.. _mame-commandline-autobootscript:
**-autoboot_script** / **-script** *[filename.lua]*
File containing scripting to execute after machine boot.
+ Example:
+ .. code-block:: bash
+
+ mame ibm5150 -autoboot_script myscript.lua
+
.. _mame-commandline-console:
**-[no]console**
@@ -2414,6 +4119,11 @@ Scripting Options
The default of OFF (**-noconsole**).
+ Example:
+ .. code-block:: bash
+
+ mame ibm5150 -console
+
.. _mame-commandline-plugins:
**-plugins**
@@ -2422,22 +4132,39 @@ Scripting Options
The default is ON (**-plugins**).
+ Example:
+ .. code-block:: bash
+
+ mame apple2e -plugins
+
.. _mame-commandline-plugin:
**-plugin** *[plugin shortname]*
A list of Lua Plugins to enable, comma separated.
+ Example:
+ .. code-block:: bash
+
+ mame alcon -plugin cheat,discord,autofire
+
.. _mame-commandline-noplugin:
**-noplugin** *[plugin shortname]*
A list of Lua Plugins to disable, comma separated.
+ Example:
+ .. code-block:: bash
+
+ mame alcon -noplugin cheat
+
+.. _mame-commandline-webserver:
HTTP Server Options
-------------------
+
.. _mame-commandline-http:
**-[no]http**
@@ -2446,18 +4173,126 @@ HTTP Server Options
The default is OFF (**-nohttp**).
+ Example:
+ .. code-block:: bash
+
+ mame -http
+
.. _mame-commandline-httpport:
-**-http_port** *[port]*
+**-http_port** *<port>*
Choose HTTP server port.
The default is ``8080``.
+ Example:
+ .. code-block:: bash
+
+ mame apple2 -http -http_port 6502
+
.. _mame-commandline-httproot:
-**-http_root** *[rootfolder]*
+**-http_root** *<rootfolder>*
Choose HTTP server document root.
The default is ``web``.
+
+ Example:
+ .. code-block:: bash
+
+ mame apple2 -http -http_port 6502 -http_root C:\Users\me\appleweb\root
+
+
+.. _mame-commandline-portaudio:
+
+PortAudio Options
+-----------------
+
+.. _mame-commandline-paapi:
+
+**-pa_api** *API*
+
+ Choose which API that PortAudio should use to talk to your sound hardware. You can use **-verbose** to see which APIs are available.
+
+ The default is ``none``.
+
+ Example 1:
+ .. code-block:: bash
+
+ mame -sound portaudio -verbose
+ Attempting load of mame.ini
+ ...
+ PortAudio: API MME has 20 devices
+ PortAudio: MME: " - Input"
+ PortAudio: MME: "Microphone (3- USB Camera-B4.09"
+ PortAudio: MME: "Line (AVerMedia Live Gamer HD 2"
+ PortAudio: MME: "Digital Audio Interface (AVerMe"
+ PortAudio: MME: "Headset Microphone (Razer Krake"
+ ...
+ PortAudio: MME: " - Output"
+ PortAudio: MME: "Headset Earphone (Razer Kraken "
+ PortAudio: MME: "Digital Audio (S/PDIF) (High De"
+ PortAudio: MME: "NX-EDG27 (NVIDIA High Definitio"
+ ...
+ PortAudio: API Windows DirectSound has 20 devices
+ PortAudio: Windows DirectSound: "Primary Sound Capture Driver"
+ PortAudio: Windows DirectSound: "Headset Microphone (Razer Kraken 7.1 V2)"
+ PortAudio: Windows DirectSound: "Primary Sound Driver" (default)
+ PortAudio: Windows DirectSound: "Headset Earphone (Razer Kraken 7.1 V2)"
+ PortAudio: Windows DirectSound: "Digital Audio (S/PDIF) (High Definition Audio Device)"
+ PortAudio: Windows DirectSound: "NX-EDG27 (NVIDIA High Definition Audio)"
+ ...
+ PortAudio: API Windows WASAPI has 18 devices
+ PortAudio: Windows WASAPI: "Headset Earphone (Razer Kraken 7.1 V2)"
+ PortAudio: Windows WASAPI: "Digital Audio (S/PDIF) (High Definition Audio Device)"
+ PortAudio: Windows WASAPI: "NX-EDG27 (NVIDIA High Definition Audio)"
+ PortAudio: Windows WASAPI: "Headset Microphone (Razer Kraken 7.1 V2)"
+ ...
+ PortAudio: API Windows WDM-KS has 22 devices
+ PortAudio: Windows WDM-KS: "Output (NVIDIA High Definition Audio)"
+ PortAudio: Windows WDM-KS: "SPDIF Out (HD Audio SPDIF out)"
+ PortAudio: Windows WDM-KS: "Headset Microphone (Razer Kraken 7.1 V2)"
+ PortAudio: Windows WDM-KS: "Headset Earphone (Razer Kraken 7.1 V2)"
+ PortAudio: Windows WDM-KS: "Microphone (VDVAD Wave)"
+ PortAudio: Windows WDM-KS: "Speakers (VDVAD Wave)"
+ ...
+ PortAudio: Sample rate is 48000 Hz, device output latency is 218.67 ms
+ PortAudio: Allowed additional buffering latency is 18.00 ms/864 frames
+
+ Example 2:
+ .. code-block:: bash
+
+ mame suprmrio -sound portaudio -pa_api "Windows WASAPI"
+
+.. _mame-commandline-padevice:
+
+**-pa_device** *device*
+
+ Choose which sound device to output through. This would typically be one of
+ the outputs on your sound card or a USB headset.
+
+ The default is ``none``.
+
+ Example:
+ .. code-block:: bash
+
+ mame suprmrio -sound portaudio -pa_api "Windows WASAPI" -pa_device "NX-EDG27 (NVIDIA High Definition Audio)"
+
+.. _mame-commandline-palatency:
+
+**-pa_latency** *latency*
+
+ Choose the buffer size for PortAudio output; this is specified in seconds.
+ Lower numbers have less latency but may increase stutter in the sound.
+ Decimal places are supported. Try starting from 0.20 and decrease or
+ increase until you find the best number your hardware and OS are capable of
+ handling.
+
+ The default is ``0``.
+
+ Example:
+ .. code-block:: bash
+
+ mame suprmrio -sound portaudio -pa_api "Windows WASAPI" -pa_device "NX-EDG27 (NVIDIA High Definition Audio)" -pa_latency 0.20
diff --git a/docs/source/commandline/commandline-index.rst b/docs/source/commandline/commandline-index.rst
index b2caa063d14..cb6b9a7dfb4 100644
--- a/docs/source/commandline/commandline-index.rst
+++ b/docs/source/commandline/commandline-index.rst
@@ -1,33 +1,36 @@
.. _index-commandline:
-Commandline Index
-=================
+Command-line Index
+==================
-This is a complete index of all commandline options and commands for MAME, suitable for quickly finding a given command.
+This is a complete index of all command-line options and verbs for MAME,
+suitable for quickly finding a given option.
-Universal Commandline Options
------------------------------
-This section contains configuration options that are applicable to *all* MAME sub-builds (both SDL and Windows native).
+Universal Command-line Options
+------------------------------
+This section contains configuration options that are applicable to *all* MAME
+configurations (including both SDL and Windows native).
-Core Commands
-~~~~~~~~~~~~~
+
+Core Verbs
+~~~~~~~~~~
| :ref:`help <mame-commandline-help>`
| :ref:`validate <mame-commandline-validate>`
-Configuration Commands
-~~~~~~~~~~~~~~~~~~~~~~
+Configuration Verbs
+~~~~~~~~~~~~~~~~~~~
| :ref:`createconfig <mame-commandline-createconfig>`
| :ref:`showconfig <mame-commandline-showconfig>`
| :ref:`showusage <mame-commandline-showusage>`
-Frontend Commands
-~~~~~~~~~~~~~~~~~
+Frontend Verbs
+~~~~~~~~~~~~~~
| :ref:`listxml <mame-commandline-listxml>`
| :ref:`listfull <mame-commandline-listfull>`
@@ -36,6 +39,7 @@ Frontend Commands
| :ref:`listbrothers <mame-commandline-listbrothers>`
| :ref:`listcrc <mame-commandline-listcrc>`
| :ref:`listroms <mame-commandline-listroms>`
+| :ref:`listbios <mame-commandline-listbios>`
| :ref:`listsamples <mame-commandline-listsamples>`
| :ref:`verifyroms <mame-commandline-verifyroms>`
| :ref:`verifysamples <mame-commandline-verifysamples>`
@@ -53,15 +57,19 @@ OSD-related Options
~~~~~~~~~~~~~~~~~~~
| :ref:`uimodekey <mame-commandline-uimodekey>`
+| :ref:`controller_map <mame-commandline-controllermap>`
+| :ref:`background_input <mame-commandline-backgroundinput>`
| :ref:`uifontprovider <mame-commandline-uifontprovider>`
| :ref:`keyboardprovider <mame-commandline-keyboardprovider>`
| :ref:`mouseprovider <mame-commandline-mouseprovider>`
| :ref:`lightgunprovider <mame-commandline-lightgunprovider>`
| :ref:`joystickprovider <mame-commandline-joystickprovider>`
+| :ref:`midiprovider <mame-commandline-midiprovider>`
+| :ref:`networkprovider <mame-commandline-networkprovider>`
-OSD CLI Options
-~~~~~~~~~~~~~~~
+OSD CLI Verbs
+~~~~~~~~~~~~~
| :ref:`listmidi <mame-commandline-listmidi>`
| :ref:`listnetwork <mame-commandline-listnetwork>`
@@ -117,9 +125,8 @@ Core State/Playback Options
| :ref:`state <mame-commandline-state>`
| :ref:`[no]autosave <mame-commandline-noautosave>`
| :ref:`playback <mame-commandline-playback>`
-| :ref:`exit_after_playback <mame-commandline-exitafterplayback>`
+| :ref:`[no]exit_after_playback <mame-commandline-exitafterplayback>`
| :ref:`record <mame-commandline-record>`
-| :ref:`record_timecode <mame-commandline-recordtimecode>`
| :ref:`mngwrite <mame-commandline-mngwrite>`
| :ref:`aviwrite <mame-commandline-aviwrite>`
| :ref:`wavwrite <mame-commandline-wavwrite>`
@@ -143,6 +150,7 @@ Core Performance Options
| :ref:`[no]refreshspeed <mame-commandline-norefreshspeed>`
| :ref:`numprocessors <mame-commandline-numprocessors>`
| :ref:`bench <mame-commandline-bench>`
+| :ref:`[no]lowlatency <mame-commandline-lowlatency>`
Core Rotation Options
@@ -211,6 +219,7 @@ Core Vector Options
| :ref:`beam_width_min <mame-commandline-beamwidthmin>`
| :ref:`beam_width_max <mame-commandline-beamwidthmax>`
| :ref:`beam_intensity_weight <mame-commandline-beamintensityweight>`
+| :ref:`beam_dot_size <mame-commandline-beamdotsize>`
| :ref:`flicker <mame-commandline-flicker>`
@@ -226,19 +235,18 @@ Core Video OpenGL Debugging Options
Core Video OpenGL GLSL Options
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-| :ref:`gl_glsl <mame-commandline-glglsl>`
+| :ref:`[no]gl_glsl <mame-commandline-glglsl>`
| :ref:`gl_glsl_filter <mame-commandline-glglslfilter>`
| :ref:`glsl_shader_mame[0-9] <mame-commandline-glslshadermame>`
| :ref:`glsl_shader_screen[0-9] <mame-commandline-glslshaderscreen>`
-| :ref:`gl_glsl_vid_attr <mame-commandline-glglslvidattr>`
Core Sound Options
~~~~~~~~~~~~~~~~~~
-
| :ref:`samplerate <mame-commandline-samplerate>`
| :ref:`[no]samples <mame-commandline-nosamples>`
+| :ref:`[no]compressor <mame-commandline-nocompressor>`
| :ref:`volume <mame-commandline-volume>`
| :ref:`sound <mame-commandline-sound>`
| :ref:`audio_latency <mame-commandline-audiolatency>`
@@ -260,8 +268,9 @@ Core Input Options
| :ref:`joystick_map <mame-commandline-joystickmap>`
| :ref:`joystick_deadzone <mame-commandline-joystickdeadzone>`
| :ref:`joystick_saturation <mame-commandline-joysticksaturation>`
-| :ref:`natural <mame-commandline-natural>`
-| :ref:`joystick_contradictory <mame-commandline-joystickcontradictory>`
+| :ref:`joystick_threshold <mame-commandline-joystickthreshold>`
+| :ref:`[no]natural <mame-commandline-natural>`
+| :ref:`[no]joystick_contradictory <mame-commandline-joystickcontradictory>`
| :ref:`coin_impulse <mame-commandline-coinimpulse>`
@@ -285,9 +294,12 @@ Core Debugging Options
| :ref:`[no]oslog <mame-commandline-oslog>`
| :ref:`[no]log <mame-commandline-log>`
| :ref:`[no]debug <mame-commandline-debug>`
+| :ref:`debugger <mame-commandline-debugger>`
| :ref:`debugscript <mame-commandline-debugscript>`
| :ref:`[no]update_in_pause <mame-commandline-updateinpause>`
| :ref:`watchdog <mame-commandline-watchdog>`
+| :ref:`debugger_host <mame-commandline-debuggerhost>`
+| :ref:`debugger_port <mame-commandline-debuggerport>`
| :ref:`debugger_font <mame-commandline-debuggerfont>`
| :ref:`debugger_font_size <mame-commandline-debuggerfontsize>`
@@ -306,23 +318,23 @@ Core Misc Options
~~~~~~~~~~~~~~~~~
| :ref:`[no]drc <mame-commandline-drc>`
-| :ref:`drc_use_c <mame-commandline-drcusec>`
-| :ref:`drc_log_uml <mame-commandline-drcloguml>`
-| :ref:`drc_log_native <mame-commandline-drclognative>`
+| :ref:`[no]drc_use_c <mame-commandline-drcusec>`
+| :ref:`[no]drc_log_uml <mame-commandline-drcloguml>`
+| :ref:`[no]drc_log_native <mame-commandline-drclognative>`
| :ref:`bios <mame-commandline-bios>`
| :ref:`[no]cheat <mame-commandline-cheat>`
| :ref:`[no]skip_gameinfo <mame-commandline-skipgameinfo>`
| :ref:`uifont <mame-commandline-uifont>`
| :ref:`ui <mame-commandline-ui>`
| :ref:`ramsize <mame-commandline-ramsize>`
-| :ref:`confirm_quit <mame-commandline-confirmquit>`
-| :ref:`ui_mouse <mame-commandline-uimouse>`
+| :ref:`[no]confirm_quit <mame-commandline-confirmquit>`
+| :ref:`[no]ui_mouse <mame-commandline-uimouse>`
| :ref:`language <mame-commandline-language>`
| :ref:`[no]nvram_save <mame-commandline-nvramsave>`
Scripting Options
------------------
+~~~~~~~~~~~~~~~~~
| :ref:`autoboot_command <mame-commandline-autobootcommand>`
| :ref:`autoboot_delay <mame-commandline-autobootdelay>`
@@ -334,15 +346,26 @@ Scripting Options
HTTP Server Options
--------------------
+~~~~~~~~~~~~~~~~~~~
| :ref:`http <mame-commandline-http>`
| :ref:`http_port <mame-commandline-httpport>`
| :ref:`http_root <mame-commandline-httproot>`
-Windows-Specific Commandline Options
-------------------------------------
+PortAudio Options
+~~~~~~~~~~~~~~~~~
+
+| :ref:`pa_api <mame-commandline-paapi>`
+| :ref:`pa_device <mame-commandline-padevice>`
+| :ref:`pa_latency <mame-commandline-palatency>`
+
+
+Windows-Specific Command-line Options
+-------------------------------------
+
+This section contains configuration options that are specific to the native
+(non-SDL) Windows version of MAME.
Windows Performance Options
@@ -367,16 +390,18 @@ Windows Input Device Options
| :ref:`[no]dual_lightgun <mame-wcommandline-duallightgun>`
-SDL-Specific Commandline Options
---------------------------------
-This section contains configuration options that are specific to any build supported by SDL (including Windows where compiled as SDL instead of native).
+SDL-Specific Command-line Options
+---------------------------------
+
+This section contains configuration options that are specific to any build
+supported by SDL (including Windows when built with SDL instead of native).
SDL Performance Options
~~~~~~~~~~~~~~~~~~~~~~~
-| :ref:`sdlvideofps <mame-scommandline-sdlvideofps>`
+| :ref:`[no]sdlvideofps <mame-scommandline-sdlvideofps>`
SDL Video Options
@@ -399,11 +424,18 @@ SDL Keyboard Mapping
| :ref:`keymap_file <mame-scommandline-keymapfile>`
-SDL Joystick Mapping
+SDL Input Options
+~~~~~~~~~~~~~~~~~~~~
+
+| :ref:`[no]enable_touch <mame-scommandline-enabletouch>`
+| :ref:`[no]sixaxis <mame-scommandline-sixaxis>`
+| :ref:`[no]dual_lightgun <mame-scommandline-duallightgun>`
+
+
+SDL Lightgun Mapping
~~~~~~~~~~~~~~~~~~~~
-| :ref:`joyidx <mame-scommandline-joyidx>`
-| :ref:`sixaxis <mame-scommandline-sixaxis>`
+| :ref:`lightgun_index <mame-scommandline-lightgunindex>`
SDL Low-level Driver Options
diff --git a/docs/source/commandline/index.rst b/docs/source/commandline/index.rst
index 4237c7f30f4..a03fe113708 100644
--- a/docs/source/commandline/index.rst
+++ b/docs/source/commandline/index.rst
@@ -1,11 +1,11 @@
-MAME Commandline Usage and OS-Specific Configuration
-----------------------------------------------------
+MAME Command-line Usage and OS-Specific Configuration
+-----------------------------------------------------
.. toctree::
- :titlesonly:
+ :titlesonly:
- commandline-all
- windowsconfig
- sdlconfig
+ commandline-all
+ windowsconfig
+ sdlconfig
- commandline-index
+ commandline-index
diff --git a/docs/source/commandline/sdlconfig.rst b/docs/source/commandline/sdlconfig.rst
index 0da5f4c526e..a6f3a7d8e51 100644
--- a/docs/source/commandline/sdlconfig.rst
+++ b/docs/source/commandline/sdlconfig.rst
@@ -1,8 +1,8 @@
-SDL-Specific Commandline Options
-================================
+SDL-Specific Command-line Options
+=================================
-
-This section contains configuration options that are specific to any build supported by SDL (including Windows where compiled as SDL instead of native).
+This section contains configuration options that are specific to any build
+supported by SDL (including Windows when built with SDL instead of native).
@@ -11,9 +11,11 @@ Performance Options
.. _mame-scommandline-sdlvideofps:
-**-sdlvideofps**
+**-[no]sdlvideofps**
- Enable output of benchmark data on the SDL video subsystem, including your system's video driver, X server (if applicable), and OpenGL stack in **-video opengl** mode.
+ Enable output of benchmark data on the SDL video subsystem, including your
+ system’s video driver, X server (if applicable), and OpenGL stack in
+ **-video opengl** mode.
Video Options
@@ -23,13 +25,13 @@ Video Options
**-[no]centerh**
- Center horizontally within the view area. Default is ON (**-centerh**).
+ Center horizontally within the view area. Default is ON (**-centerh**).
.. _mame-scommandline-centerv:
**-[no]centerv**
- Center vertically within the view area. Default is ON (**-centerv**).
+ Center vertically within the view area. Default is ON (**-centerv**).
Video Soft-Specific Options
@@ -39,7 +41,8 @@ Video Soft-Specific Options
**-scalemode**
- Scale mode: none, async, yv12, yuy2, yv12x2, yuy2x2 (**-video soft** only). Default is *none*.
+ Scale mode: none, async, yv12, yuy2, yv12x2, yuy2x2 (**-video soft** only).
+ Default is *none*.
SDL Keyboard Mapping
@@ -49,54 +52,84 @@ SDL Keyboard Mapping
**-keymap**
- Enable keymap. Default is OFF (**-nokeymap**)
+ Enable keymap. Default is OFF (**-nokeymap**)
.. _mame-scommandline-keymapfile:
**-keymap_file** *<file>*
- Keymap Filename. Default is ``keymap.dat``.
-
+ Keymap file name. Default is ``keymap.dat``.
-SDL Joystick Mapping
---------------------
-.. _mame-scommandline-joyidx:
+SDL Input Options
+-----------------
-|
-| **-joy_idx1** *<name>*
-| **-joy_idx2** *<name>*
-| ...
-| **-joy_idx8** *<name>*
-|
+.. _mame-scommandline-enabletouch:
-Name of joystick mapped to a given joystick slot, default is *auto*.
+**-enable_touch**
+ Enable support for touch input. If this option is switched off, mouse input
+ simulated from touch devices will be used instead. Default is OFF
+ (**-noenable_touch**)
.. _mame-scommandline-sixaxis:
**-sixaxis**
- Use special handling for PS3 SixAxis controllers. Default is OFF (**-nosixaxis**)
+ Use special handling for PlayStation 3 SixAxis controllers. May cause
+ undesirable behaviour with other controllers. Only affects the ``sdljoy``
+ joystick provider. Default is OFF (**-nosixaxis**)
+
+.. _mame-scommandline-duallightgun:
+
+**-[no]dual_lightgun** / **-[no]dual**
+
+ Controls whether or not MAME attempts to track two lightguns that appear as
+ a single mouse. This option requires the :ref:`lightgun option
+ <mame-commandline-nolightgun>` to be on and the :ref:`lightgunprovider
+ option <mame-commandline-lightgunprovider>` to be set to *sdl*.
+
+ This option supports dual lightgun setups that work by setting the mouse
+ pointer location at the moment a lightgun trigger is activated. The primary
+ and secondary triggers on the first lightgun correspond to the first and
+ second mouse buttons, and the primary and secondary triggers on the second
+ lightgun correspond to the third and fourth mouse buttons.
+
+ The default is OFF (**-nodual_lightgun**).
+
+
+SDL Lightgun Mapping
+--------------------
+
+.. _mame-scommandline-lightgunindex:
+
+|
+| **-lightgun_index1** *<name>*
+| **-lightgun_index2** *<name>*
+| ...
+| **-lightgun_index8** *<name>*
+|
+
+Device name or ID mapped to a given lightgun slot.
SDL Low-level Driver Options
-~---------------------------
+----------------------------
.. _mame-scommandline-videodriver:
**-videodriver** *<driver>*
- SDL video driver to use ('x11', 'directfb', ... or '*auto*' for SDL default)
+ SDL video driver to use ('x11', 'directfb', ... or '*auto*' for SDL default)
.. _mame-scommandline-audiodriver:
**-audiodriver** *<driver>*
- SDL audio driver to use ('alsa', 'arts', ... or '*auto*' for SDL default)
+ SDL audio driver to use ('alsa', 'arts', ... or '*auto*' for SDL default)
.. _mame-scommandline-gllib:
**-gl_lib** *<driver>*
- Alternative **libGL.so** to use; '*auto*' for system default
+ Alternative **libGL.so** to use; '*auto*' for system default
diff --git a/docs/source/commandline/windowsconfig.rst b/docs/source/commandline/windowsconfig.rst
index 85f555e9a21..1c41476854c 100644
--- a/docs/source/commandline/windowsconfig.rst
+++ b/docs/source/commandline/windowsconfig.rst
@@ -1,7 +1,8 @@
-Windows-Specific Commandline Options
-====================================
+Windows-Specific Command-line Options
+=====================================
-This section contains configuration options that are specific to the native (non-SDL) Windows version of MAME.
+This section contains configuration options that are specific to the native
+(non-SDL) Windows version of MAME.
@@ -12,7 +13,10 @@ Performance options
**-priority** *<priority>*
- Sets the thread priority for the MAME threads. By default the priority is left alone to guarantee proper cooperation with other applications. The valid range is -15 to 1, with 1 being the highest priority. The default is *0* (*NORMAL priority*).
+ Sets the thread priority for the MAME threads. By default the priority is
+ left alone to guarantee proper cooperation with other applications. The
+ valid range is -15 to 1, with 1 being the highest priority. The default is
+ *0* (*NORMAL priority*).
.. _mame-wcommandline-profile:
@@ -28,25 +32,46 @@ Full screen options
**-[no]triplebuffer** / **-[no]tb**
- Enables or disables "triple buffering". Normally, MAME just draws directly to the screen, without any fancy buffering. But with this option enabled, MAME creates three buffers to draw to, and cycles between them in order. It attempts to keep things flowing such that one buffer is currently displayed, the second buffer is waiting to be displayed, and the third buffer is being drawn to. **-triplebuffer** will override **-waitvsync**, if the buffer is successfully created. This option does not work with **-video gdi**. The default is OFF (**-notriplebuffer**).
+ Enables or disables “triple buffering”. Normally, MAME just draws directly
+ to the screen, without any fancy buffering. But with this option enabled,
+ MAME creates three buffers to draw to, and cycles between them in order. It
+ attempts to keep things flowing such that one buffer is currently displayed,
+ the second buffer is waiting to be displayed, and the third buffer is being
+ drawn to. **-triplebuffer** will override **-waitvsync**, if the buffer is
+ successfully created. This option does not work with **-video gdi**. The
+ default is OFF (**-notriplebuffer**).
.. _mame-wcommandline-fullscreenbrightness:
**-full_screen_brightness** *<value>* / **-fsb** *<value>*
- Controls the brightness, or black level, of the entire display. The standard value is 1.0. Selecting lower values (down to 0.1) will produce a darkened display, while selecting higher values (up to 2.0) will give a brighter display. Note that not all video cards have hardware to support this option. This option does not work with **-video gdi**. The default is ``1.0``.
+ Controls the brightness, or black level, of the entire display. The
+ standard value is 1.0. Lower values (down to 0.1) will produce a darkened
+ display, while higher values (up to 2.0) will give a brighter display. Note
+ that not all video cards have hardware to support this option. This option
+ does not work with **-video gdi**. The default is *1.0*.
.. _mame-wcommandline-fullscreencontrast:
**-full_screen_contrast** *<value>* / **-fsc** *<value>*
- Controls the contrast, or white level, of the entire display. The standard value is 1.0. Selecting lower values (down to 0.1) will produce a dimmer display, while selecting higher values (up to 2.0) will give a more saturated display. Note that not all video cards have hardware to support this option. This option does not work with **-video gdi**. The default is ``1.0``.
+ Controls the contrast, or white level, of the entire display. The standard
+ value is 1.0. Lower values (down to 0.1) will produce a dimmer display,
+ while higher values (up to 2.0) will give a more saturated display. Note
+ that not all video cards have hardware to support this option. This option
+ does not work with **-video gdi**. The default is *1.0*.
.. _mame-wcommandline-fullscreengamma:
**-full_screen_gamma** *<value>* / **-fsg** *<value>*
- Controls the gamma, which produces a potentially nonlinear black to white ramp, for the entire display. The standard value is 1.0, which gives a linear ramp from black to white. Selecting lower values (down to 0.1) will increase the nonlinearity toward black, while selecting higher values (up to 3.0) will push the nonlinearity toward white. Note that not all video cards have hardware to support this option. This option does not work with **-video gdi**. The default is ``1.0``.
+ Controls the gamma, which produces a potentially nonlinear black to white
+ ramp, for the entire display. The standard value is 1.0, which gives a
+ linear ramp from black to white. Lower values (down to 0.1) will increase
+ the nonlinearity toward black, while higher values (up to 3.0) will push the
+ nonlinearity toward white. Note that not all video cards have hardware to
+ support this option. This option does not work with **-video gdi**. The
+ default is *1.0*.
@@ -57,4 +82,20 @@ Input device options
**-[no]dual_lightgun** / **-[no]dual**
- Controls whether or not MAME attempts to track two lightguns connected at the same time. This option requires -lightgun. This option is a hack for supporting certain older dual lightgun setups. If you have multiple lightguns connected, you will probably just need to enable -mouse and configure each lightgun independently. The default is *OFF* (**-nodual_lightgun**).
+ Controls whether or not MAME attempts to track two lightguns that appear as
+ a single mouse. This option requires the :ref:`lightgun option
+ <mame-commandline-nolightgun>` to be on and the :ref:`lightgunprovider
+ option <mame-commandline-lightgunprovider>` to be set to *win32*.
+
+ This option supports certain older dual lightgun setups that work by setting
+ the mouse pointer location at the moment a lightgun trigger is activated.
+ The primary and secondary triggers on the first lightgun correspond to the
+ first and second mouse buttons, and the primary and secondary triggers on
+ the second lightgun correspond to the third and fourth mouse buttons.
+
+ If you have multiple lightguns connected, you will probably just need to
+ enable the :ref:`lightgun option <mame-commandline-nolightgun>`, use the
+ default :ref:`lightgunprovider option <mame-commandline-lightgunprovider>`
+ of *rawinput*, and configure each lightgun individually.
+
+ The default is OFF (**-nodual_lightgun**).
diff --git a/docs/source/conf.py b/docs/source/conf.py
index 4130e982e30..dd4277f9919 100644
--- a/docs/source/conf.py
+++ b/docs/source/conf.py
@@ -11,9 +11,10 @@
# All configuration values have a default; values that are commented out
# serve to show the default.
-import sys, os
+import os.path
+import sys
-sys.path.insert(0, os.path.abspath('_ext'))
+sys.path.insert(0, os.path.join(os.path.dirname(os.path.abspath(__file__)), '_ext'))
# If extensions (or modules to document with autodoc) are in another directory,
# add these directories to sys.path here. If the directory is relative to the
@@ -31,8 +32,8 @@ extensions = [
'sphinx.ext.autodoc',
'sphinx.ext.mathjax',
'sphinx.ext.viewcode',
- 'edit_on_github',
- 'sphinxcontrib.rsvgconverter'
+ 'sphinxcontrib.rsvgconverter',
+ 'edit_on_github'
]
edit_on_github_project = 'mamedev/mame'
@@ -55,16 +56,16 @@ master_doc = 'index'
# General information about the project.
project = u'MAME Documentation'
-copyright = u'2019, MAMEdev Team'
+copyright = u'1997-2025, MAMEdev and contributors'
# The version info for the project you're documenting, acts as replacement for
# |version| and |release|, also used in various other places throughout the
# built documents.
#
# The short X.Y version.
-version = '0.205'
+version = '0.277'
# The full version, including alpha/beta/rc tags.
-release = '0.205'
+release = '0.277'
# The language for content autogenerated by Sphinx. Refer to documentation
# for a list of supported languages.
@@ -145,8 +146,12 @@ html_theme_path = ["../themes/"]
# If true, SmartyPants will be used to convert quotes and dashes to
# typographically correct entities.
+# This was deprecated in Sphinx 1.6.6
#html_use_smartypants = True
+# We don't want smartquotes in general.
+smartquotes = False
+
# Custom sidebar templates, maps document names to template names.
#html_sidebars = {}
@@ -257,3 +262,12 @@ texinfo_documents = [
# How to display URL addresses: 'footnote', 'no', or 'inline'.
#texinfo_show_urls = 'footnote'
+
+# Add download links at bottom left when the MAMEDEV environment
+# varaible is set. See versions.html in the _template folder.
+try:
+ html_context
+except NameError:
+ html_context = dict()
+if os.getenv("MAMEDEV") != None:
+ html_context['mamedev_site'] = True
diff --git a/docs/source/contributing/cxx.rst b/docs/source/contributing/cxx.rst
new file mode 100644
index 00000000000..918c72032d2
--- /dev/null
+++ b/docs/source/contributing/cxx.rst
@@ -0,0 +1,573 @@
+.. _contributing-cxx:
+
+C++ Coding Guidelines
+=====================
+
+.. contents:: :local:
+
+
+.. _contributing-cxx-intro:
+
+Introduction
+------------
+
+**In terms of coding conventions, the style present within an existing
+source file should be favoured over the standards found below.**
+
+When a new source file is being created, the following coding
+conventions should be observed if creating a new file within the MAME
+core (``src/emu`` and ``src/lib``). If the source file is outside the
+core, deference can be given to a contributor’s preferred style,
+although it is strongly encouraged to code with the understanding that
+the file may need to be comprehensible by more than one person as time
+marches forward.
+
+
+.. _contributing-cxx-definitions:
+
+Definitions
+-----------
+
+Snake case
+ All lowercase letters with words separated by underscores:
+ ``this_is_snake_case``
+Screaming snake case
+ All uppercase letters with words separated by underscores:
+ ``SCREAMING_SNAKE_CASE``
+Camel case:
+ Lowercase initial letter, first letter of each subsequent word
+ capitalised, with no separators between words: ``exampleCamelCase``
+Llama case:
+ Uppercase initial letter, first letter of each subsequent word
+ capitalised, with no separators between words: ``LlamaCaseSample``
+
+
+.. _contributing-cxx-fileformat:
+
+Source file format
+------------------
+
+MAME C++ source files are encoded as UTF-8 text, assuming fixed-width
+characters, with tab stops at four-space intervals. Source files should
+end with a terminating end-of-line. Any valid printable Unicode text is
+permitted in comments. Outside comments and strings, only the printable
+ASCII subset of Unicode is permitted.
+
+The ``srcclean`` tool is used to enforce file format rules before each
+release. You can build this tool and apply it to the files you modify
+before opening a pull request to avoid conflicts or surprising changes
+later.
+
+
+.. _contributing-cxx-naming:
+
+Naming conventions
+------------------
+
+Preprocessor macros
+ Macro names should use screaming snake case. Macros are always
+ global and name conflicts can cause confusing errors – think
+ carefully about what macros really need to be in headers and name
+ them carefully.
+Include guards
+ Include guard macros should begin with ``MAME_``, and end with a
+ capitalised version of the file name, with separators replaced by
+ underscores.
+Constants
+ Constants should use screaming snake case, whether they are constant
+ globals, constant data members, enumerators or preprocessor
+ constants.
+Functions
+ Free functions names should use snake case. (There are some utility
+ function that were previously implemented as preprocessor macros
+ that still use screaming snake case.)
+Classes
+ Class names should use snake case. Abstract class names should end
+ in ``_base``. Public member functions (including static member
+ functions) should use snake case.
+Device classes
+ Concrete driver ``driver_device`` implementation names
+ conventionally end in ``_state``, while other concrete device class
+ names end in ``_device``. Concrete ``device_interface`` names
+ conventionally begin with ``device_`` and end with ``_interface``.
+Device types
+ Device types should use screaming snake case. Remember that device
+ types are names in the global namespace, so choose explicit,
+ unambiguous names.
+Enumerations
+ The enumeration name should use snake case. The enumerators should
+ use screaming snake case.
+Template parameters
+ Template parameters should use llama case (both type and value
+ parameters).
+
+Identifiers containing two consecutive underscores or starting with an
+underscore followed by an uppercase letter are always reserved and
+should not be used.
+
+Type names and other identifiers with a leading underscore should be
+avoided within the global namespace, as they are explicitly reserved
+according to the C++ standard. Additionally, identifiers suffixed with
+``_t`` should be avoided within the global namespace, as they are also
+reserved according to POSIX standards. While MAME violates this policy
+occasionally – most notably with ``device_t`` – it’s considered to be an
+unfortunate legacy decision that should be avoided in any new code.
+
+
+.. _contributing-cxx-literals:
+
+Variables and literals
+----------------------
+
+Octal literals are discouraged from use outside of specific cases. They
+lack the obvious letter-based prefixes found in hexadecimal and binary
+literals, and therefore can be difficult to distinguish at a glance from
+a decimal literal to coders who are unfamiliar with octal notation.
+
+Lower-case hexadecimal literals are preferred, e.g. ``0xbadc0de`` rather
+than ``0xBADC0DE``. For clarity, try not to exceed the bit width of the
+variable which will be used to store it.
+
+Binary literals have rarely been used in the MAME source code due to the
+``0b`` prefix not being standardised until C++14, but there is no policy
+to avoid their use.
+
+Integer suffix notation should be used when specifying 64-bit literals,
+but is not strictly required in other cases. It can, however, clarify
+the intended use of a given literal at a glance. Uppercase long integer
+literal suffixes should be used to avoid confusion with the digit 1,
+e.g. ``7LL`` rather than ``7ll``.
+
+Digit grouping should be used for longer numeric literals, as it aids in
+recognising order of magnitude or bit field positions at a glance.
+Decimal literals should use groups of three digits, and hexadecimal
+literals should use groups of four digits, outside of specific
+situations where different grouping would be easier to understand, e.g.
+``4'433'619`` or ``0xfff8'1fff``.
+
+Types that do not have a specifically defined size should be avoided if
+they are to be registered with MAME’s save-state system, as it harms
+portability. In general, this means avoiding the use of ``int`` for
+these members.
+
+It's encouraged, but not required, for class data members to be prefixed
+with ``m_`` for non-static instance members and ``s_`` for static
+members. This does not apply to nested classes or structs.
+
+
+.. _contributing-cxx-braceindent:
+
+Bracing and indentation
+-----------------------
+
+Tabs are used for initial indentation of lines, with one tab used per
+nested scope level. Statements split across multiple lines should be
+indented by two tabs. Spaces are used for alignment at other places
+within a line.
+
+Either K&R or Allman-style bracing is preferred. There is no specific
+preference for bracing on single-line statements, although bracing
+should be consistent for a given ``if/else`` block, as shown:
+
+.. code-block:: C++
+
+ if (x == 0)
+ {
+ return;
+ }
+ else
+ {
+ call_some_function();
+ x--;
+ }
+
+When using a series of ``if``/``else`` or ``if``/``else if``/``else``
+blocks with comments at the top indentation level, avoid extraneous
+newlines. The use of additional newlines may lead to ``else if`` or
+``else`` blocks being missed due to the newlines pushing the blocks
+outside the visible editor height:
+
+.. code-block:: C++
+
+ // Early-out if our hypothetical counter has run out.
+ if (x == 0)
+ {
+ return;
+ }
+ // We should do something if the counter is running.
+ else
+ {
+ call_some_function();
+ x--;
+ }
+
+Indentation for ``case`` statements inside a ``switch`` body can either
+be on the same level as the ``switch`` statement or inward by one level.
+There is no specific style which is used across all core files, although
+indenting by one level appears to be used most often.
+
+
+.. _contributing-cxx-spacing:
+
+Spacing
+-------
+
+Consistent single-spacing between binary operators, variables, and
+literals is strongly preferred. The following examples exhibit
+reasonably consistent spacing:
+
+.. code-block:: C++
+
+ uint8_t foo = (((bar + baz) + 3) & 7) << 1;
+ uint8_t foo = ((bar << 1) + baz) & 0x0e;
+ uint8_t foo = bar ? baz : 5;
+
+The following examples exhibit extremes in either direction, although
+having extra spaces is less difficult to read than having too few:
+
+.. code-block:: C++
+
+ uint8_t foo = ( ( ( bar + baz ) + 3 ) & 7 ) << 1;
+ uint8_t foo = ((bar<<1)+baz)&0x0e;
+ uint8_t foo = (bar?baz:5);
+
+A space should be used between a fundamental C++ statement and its
+opening parenthesis, e.g.:
+
+.. code-block:: C++
+
+ switch (value) ...
+ if (a != b) ...
+ for (int i = 0; i < foo; i++) ...
+
+
+.. _contributing-cxx-scoping:
+
+Scoping
+-------
+
+Variables should be scoped as narrowly as is reasonably possible. There
+are many instances of C89-style local variable declaration in the MAME
+codebase, but this is largely a hold-over from MAME’s early days, which
+pre-date the C99 specification.
+
+The following two snippets exhibit the legacy style of local variable
+declaration, followed by the more modern and preferred style:
+
+.. code-block:: C++
+
+ void example_device::some_function()
+ {
+ int i;
+ uint8_t data;
+
+ for (i = 0; i < std::size(m_buffer); i++)
+ {
+ data = m_buffer[i];
+ if (data)
+ {
+ some_other_function(data);
+ }
+ }
+ }
+
+.. code-block:: C++
+
+ void example_device::some_function()
+ {
+ for (int i = 0; i < std::size(m_buffer); i++)
+ {
+ const uint8_t data = m_buffer[i];
+ if (data)
+ {
+ some_other_function(data);
+ }
+ }
+ }
+
+Enumerated values, structs, and classes used only by one specific device
+should be declared within the device's class itself. This avoids
+pollution of the global namespace and makes the device-specific use of
+them more obvious at a glance.
+
+
+.. _contributing-cxx-const:
+
+Const Correctness
+-----------------
+
+Const-correctness has not historically been a strict requirement of code
+that goes into MAME, but there’s increasing value in it as the amount of
+code refactoring increases and technical debt decreases.
+
+When writing new code, it’s worth taking the time to determine if a
+local variable can be declared ``const``. Similarly, it's encouraged to
+consider which member functions of a new class can be ``const``
+qualified.
+
+In a similar vein, arrays of constants should be declared ``constexpr``
+and should use screaming snake case, as outlined towards the top of this
+document. Lastly, arrays of C-style strings should be declared as both
+a const array of const strings, as so:
+
+.. code-block:: C++
+
+ static const char *const EXAMPLE_NAMES[4] =
+ {
+ "1-bit",
+ "2-bit",
+ "4-bit",
+ "Invalid"
+ };
+
+
+.. _contributing-cxx-comments:
+
+Comments
+--------
+
+While ``/* ANSI C comments */`` are often found in the codebase, there
+has been a gradual shift towards ``// C++-style comments`` for
+single-line comments. This is very much a guideline, and coders are
+encouraged to use whichever style is most comfortable.
+
+Unless specifically quoting content from a machine or ancillary
+materials, comments should be in English so as to match the predominant
+language that the MAME team shares worldwide.
+
+Commented-out code should typically be removed prior to authoring a pull
+request, as it has a tendency to rot due to the fast-moving nature of
+MAME’s core API. If there is a desire known beforehand for the code to
+eventually be included, it should be bookended in ``if (0)`` or
+``if (false)``, as code removed through a preprocessor macro will rot at
+the same rate.
+
+
+.. _contributing-cxx-helpers:
+
+MAME-Specific Helpers
+---------------------
+
+When at all possible, use helper functions and macros for bit
+manipulation operations.
+
+The ``BIT(value, bit)`` helper can be used to extract the state of a bit
+at a given position from an integer value. The resulting value will be
+aligned to the least significant bit position, i.e. will be either 0 or
+1.
+
+An overload of the same function, ``BIT(value, bit, width)`` can be used
+to extract a bit field of a specified width from an integer value,
+starting at the specified bit position. The result will also be
+right-justified and will be of the same type as the incoming value.
+
+There are, additionally, a number of helpers for functionality such as
+counting leading zeroes/ones, population count, and signed/unsigned
+integer multiplication and division for both 32-bit and 64-bit results.
+Not all of these helpers have wide use in the MAME codebase, but using
+them in new code is strongly preferred when that code is performance-
+critical, as they utilise inline assembly or compiler intrinsics per-
+platform when available.
+
+``count_leading_zeros_32/64(T value)``
+ Accepts an unsigned 32/64-bit value and returns an unsigned 8-bit
+ value containing the number of consecutive zeros starting from the
+ most significant bit.
+``count_leading_ones_32/64(T value)``
+ Same functionality as above, but examining consecutive one-bits.
+``population_count_32/64(T value)``
+ Accepts an unsigned 32/64-bit value and returns the number of
+ one-bits found, i.e. the Hamming weight of the value.
+``rotl_32/64(T value, int shift)``
+ Performs a circular/barrel left shift of an unsigned 32/64-bit value
+ with the specified shift value. The shift value will be masked to
+ the valid bit range for a 32-bit or 64-bit value.
+``rotr_32/64(T value, int shift)``
+ Same functionality as above, but with a right shift.
+
+For documentation on helpers related to multiplication and division,
+refer to ``src/osd/eminline.h``.
+
+
+.. _contributing-cxx-logging:
+
+Logging
+-------
+
+MAME has multiple logging function for different purposes. Two of the
+most frequently used logging functions are ``logerror`` and
+``osd_printf_verbose``:
+
+* Devices inherit a ``logerror`` member function. This automatically
+ includes the fully-qualified tag of the invoking device in log
+ messages. Output is sent to MAME’s debugger’s rotating log buffer if
+ the debugger is enabled. If the
+ :ref:`-log option <mame-commandline-log>` is enabled, it’s also
+ written to the file ``error.log`` in the working directory. If the
+ :ref:`-oslog option <mame-commandline-oslog>` is enabled, it’s
+ additionally sent to the OS diagnostic output (the host debugger
+ diagnostic log on Windows if a host debugger is attached, or standard
+ error otherwise).
+* The output of the ``osd_printf_verbose`` function is sent to standard
+ error if the :ref:`-verbose option <mame-commandline-verbose>` is
+ enabled.
+
+The ``osd_printf_verbose`` function should be used for logging that is
+useful for diagnosing user issues, while ``logerror`` should be used for
+messages more relevant to developers (either developing MAME itself, or
+developing software for emulated systems using MAME’s debugger).
+
+For debug logging, a channel-based logging system exists via the header
+``logmacro.h``. It can be used as a generic logging system as follows,
+without needing to make use of its ability to mask out specific
+channels:
+
+.. code-block:: C++
+
+ // All other headers in the .cpp file should be above this line.
+ #define VERBOSE (1)
+ #include "logmacro.h"
+ ...
+ void some_device::some_reg_write(u8 data)
+ {
+ LOG("%s: some_reg_write: %02x\n", machine().describe_context(), data);
+ }
+
+The above example also makes use of a helper function which is available
+in all derivatives of ``device_t``: ``machine().describe_context()``.
+This function will return a string that describes the emulation context
+in which the function is being run. This includes the fully-qualified
+tag of the currently executing device (if any). If the relevant device
+implements ``device_state_interface``, it will also include the current
+program-counter value reported by the device.
+
+For more fine-grained control, specific bit masks can be defined and
+used via the ``LOGMASKED`` macro:
+
+.. code-block:: C++
+
+ // All other headers in the .cpp file should be above this line.
+ #define LOG_FOO (1 << 1U)
+ #define LOG_BAR (1 << 2U)
+
+ #define VERBOSE (LOG_FOO | LOG_BAR)
+ #include "logmacro.h"
+ ...
+ void some_device::some_reg_write(u8 data)
+ {
+ LOGMASKED(LOG_FOO, "some_reg_write: %02x\n", data);
+ }
+
+ void some_device::another_reg_write(u8 data)
+ {
+ LOGMASKED(LOG_BAR, "another_reg_write: %02x\n", data);
+ }
+
+Note that the least significant bit position for user-supplied masks is
+1, as bit position 0 is reserved for ``LOG_GENERAL``.
+
+By default, ``LOG`` and ``LOGMASKED`` will use the device-supplied
+``logerror`` function. However, this can be redirected as desired. The
+most common use case would be to direct output to the standard output
+instead, which can be accomplished by explicitly defining
+``LOG_OUTPUT_FUNC`` as so:
+
+.. code-block:: C++
+
+ #define LOG_OUTPUT_FUNC osd_printf_info
+
+A developer should always ensure that ``VERBOSE`` is set to 0 and that
+any definition of ``LOG_OUTPUT_FUNC`` is commented out prior to opening
+a pull request.
+
+
+.. _contributing-cxx-structure:
+
+Structural organization
+-----------------------
+
+All C++ source files must begin with a two comments listing the
+distribution license and copyright holders in a standard format.
+Licenses are specified by their SPDX short identifier if available.
+Here is an example of the standard format:
+
+.. code-block:: C++
+
+ // license:BSD-3-Clause
+ // copyright-holders:David Haywood, Tomasz Slanina
+
+Header includes should generally be grouped from most-dependent to
+least-dependent, and sorted alphabetically within said groups:
+
+* The project prefix header, ``emu.h``, must be the first thing in a
+ translation unit
+* Local project headers (i.e. headers found in the same source
+ directory)
+* Headers in ``src/devices``
+* Headers in ``src/emu``
+* Headers in ``src/lib/formats``
+* Headers in ``src/lib/util``
+* Headers from the OSD layer
+* C++ standard library headers
+* C standard library headers
+* OS-specific headers
+* Layout headers
+
+Finally, task-specific headers such as ``logmacro.h`` - described in the
+previous section - should be included last. A practical example
+follows:
+
+.. code-block:: C++
+
+ #include "emu.h"
+
+ #include "cpu/m68000/m68000.h"
+ #include "machine/mc68328.h"
+ #include "machine/ram.h"
+ #include "sound/dac.h"
+ #include "video/mc68328lcd.h"
+ #include "video/sed1375.h"
+
+ #include "emupal.h"
+ #include "screen.h"
+ #include "speaker.h"
+
+ #include "pilot1k.lh"
+
+ #define VERBOSE (0)
+ #include "logmacro.h"
+
+In most cases, the class declaration for a system driver should be
+within the corresponding source file along with the implementation. In
+such cases, the class declaration and all contents of the source file,
+excluding the ``GAME``, ``COMP``, or ``CONS`` macro, should be enclosed
+in an anonymous namespace (this produces better compiler diagnostics,
+allows more aggressive optimisation, reduces the chance of duplicate
+symbols, and reduces linking time).
+
+Within a class declaration, there should be one section for each member
+access level (``public``, ``protected`` and ``private``) if practical.
+This may not be possible in cases where private constants and/or types
+need to be declared before public members. Members should use the least
+public access level necessary. Overridden virtual member functions
+should generally use the same access level as the corresponding member
+function in the base class.
+
+Class member declarations should be grouped to aid understanding:
+
+* Within a member access level section, constants, types, data members,
+ instance member functions and static member functions should be
+ grouped.
+* In device classes, configuration member functions should be grouped
+ separately from live signal member functions.
+* Overridden virtual member functions should be grouped according to the
+ base classes they are inherited from.
+
+For classes with multiple overloaded constructors, constructor
+delegation should be used where possible to avoid repeated member
+initialiser lists.
+
+Constants which are used by a device or machine driver should be in the
+form of explicitly-sized enumerated values within the class declaration,
+or be relegated to ``#define`` macros within the source file. This
+helps avoid polluting the preprocessor.
diff --git a/docs/source/contributing/index.rst b/docs/source/contributing/index.rst
new file mode 100644
index 00000000000..a3dc9e4bec9
--- /dev/null
+++ b/docs/source/contributing/index.rst
@@ -0,0 +1,157 @@
+.. _contributing:
+
+Contributing to MAME
+====================
+
+So you want to contribute to MAME but aren’t sure where to start? Well
+the great news is that there’s always plenty to do for people with a
+variety of skill sets.
+
+
+.. _contributing-testing:
+
+Testing and reporting bugs
+--------------------------
+
+One thing MAME can always do with is more testing and bug reports. If
+you’re familiar with a system that MAME emulates and notice something
+wrong, or if you find a bug in MAME’s user interface, you can head over
+to `MAME Testers <https://mametesters.org/>`_ and, assuming it isn’t
+already reported, register an account and open an issue. Be sure to
+read the `FAQ <https://mametesters.org/faq.html>`_ and
+`rules <https://mametesters.org/rules.html>`_ first to ensure you start
+out on the right foot. Please note that MAME Testers only accepts
+user-facing bugs in tagged release versions.
+
+For other kinds of issues, we have
+`GitHub Issues <https://github.com/mamedev/mame/issues/>`_. There’s a
+bit more leeway here. For example we accept developer-facing issues
+(e.g. bugs in internal APIs, or build system inadequacies), feature
+requests, and major regressions before they make it into a released
+version. Please respect the fact that the issue tracker is *not* a
+discussion or support forum, it’s only for reporting reproducible
+issues. Don’t open issues to ask questions or request support. Also,
+keep in mind that the ``master`` branch is unstable. If the current
+revision doesn’t compile at all or is completely broken, we’re probably
+already aware of it and don’t need issues opened for that. Wait a while
+and see if there’s an update. You might want to comment on the commit
+in question with the compiler error message, particularly if you’re
+compiling in an unorthodox but supported configuration.
+
+When opening an issue, remember to provide as much information as
+possible to help others understand, reproduce, and diagnose the issue.
+Things that are helpful to include:
+
+* The incorrect behaviour, and expected or correct behaviour. Be
+ specific: just saying it “doesn’t work” usually isn’t enough detail.
+* Environment details, including your operating system, CPU
+ architecture, system locale, and display language, if applicable. For
+ video output bugs, note your video hardware (GPU), driver version, and
+ the MAME video output module you’re using. For input handling bugs,
+ include the input peripherals and MAME input modules you’re using.
+* The exact version of MAME you’re using, including a git commit digest
+ if it isn’t a tagged release version, and any non-standard build
+ options.
+* The exact system and software being emulated (may not be applicable
+ for issues with parts of MAME’s UI, like the system selection menu).
+ Include things like the selected BIOS version, and emulated peripheral
+ (slot device) configuration.
+* Steps to reproduce the issue. Assume the person reading is familiar
+ with MAME itself, but not necessarily familiar with the emulated
+ system and software in question. For emulation issues, input
+ recordings and/or saved state files for reproducing the issue can be
+ invaluable.
+* An original reference for the correct behaviour. If you have access
+ to the original hardware for the emulated system, it helps to make a
+ recording of the correct behaviour for comparison.
+
+
+.. _contributing-code:
+
+Contributing to MAME’s source code
+----------------------------------
+
+MAME itself is written in C++, but that isn’t the sum total of the
+source code. The source code also includes:
+
+* The documentation hosted on this site (and also included in releases
+ as a PDF), written in
+ `reStructuredText <https://www.sphinx-doc.org/en/master/usage/restructuredtext/basics.html>`_
+ markup.
+* The supplied :ref:`plugins <plugins>`, written in
+ `Lua 5.3 <https://www.lua.org/manual/5.3/>`_.
+* Internal layouts for emulated machines that need to display more than
+ a simple video screen. These are an XML application
+ :ref:`described here <layfile>`.
+* The software lists, describing known software media for systems that
+ MAME emulates. MAME software lists are an XML application.
+* The user interface translations, in GNU gettext PO format. They can
+ be edited with a good text editor, or a dedicated tool like
+ `Poedit <https://poedit.net/>`_.
+
+Our primary source code repository is
+`hosted on GitHub <https://github.com/mamedev/mame/>`_. We prefer to
+receive source code contributions in the form of
+`pull requests <https://github.com/mamedev/mame/pulls>`_. You’ll need
+to learn the basics of git distributed version control and familiarise
+yourself with the git tools. The basic process for creating a pull
+request is as follows:
+
+* Sign up for an account on GitHub.
+* Create a fork of the mamedev/mame repository.
+* Create a new branch off the ``master`` branch in your forked
+ repository.
+* Clone your forked repository, and check out your new branch.
+* Make your changes, and build and test them locally.
+* Commit your changes, and push your branch to GitHub.
+* Optionally enable GitHub Actions for your forked repository, allowing
+ your changes to be built on Windows, macOS and Linux.
+* Open a pull request to merge your changes into the ``master`` branch
+ in the mamedev/mame repository.
+
+Please keep the following in mind (note that not all points are relevant
+to all kinds of changes):
+
+* Make your commit messages descriptive. Please include what the change
+ affects, and what it’s supposed to achieve. A person reading the
+ commit log shouldn’t need to resort to examining the diff to get a
+ basic idea of what a commit is supposed to do. The default commit
+ messages provided by GitHub are completely useless, as they don’t give
+ any indication of what a change is supposed to do.
+* Test your changes. Ensure that a full build of MAME completes, and
+ that the code you changed works. It’s a good idea to build with
+ ``DEBUG=1`` to check that assertions compile and don’t trigger.
+* Use an enlightening pull request title and description. The title
+ should give a one-line summary of what the overall change affects and
+ what it’s supposed to do. The description should contain more detail.
+ Don’t leave the description empty and describe the change in comments,
+ as this makes searching and filtering more difficult.
+* Be aware that GitHub Actions has opaque resource limits. It isn’t
+ clear when you’re close to the limits, and we’ve had contributors
+ banned from GitHub Actions for violating the limits. Even if you
+ appeal the ban, they still won’t tell you what the actual limits are,
+ justifying this by saying that if you know the limits, you can take
+ steps to evade them. If you enable GitHub Actions, consider not
+ pushing individual commits if you don’t need them to be automatically
+ built, or cancelling workflow runs when you don’t need the results.
+* If your submission is a computer or other device such as a synthesizer
+ or sampler which requires a disk, tape, cartridge, or other media to
+ start up and run, please consider creating a software list containing
+ at least one example of that media. This helps everyone making changes
+ to shared MAME components to easily verify if the changes negatively
+ impact your code.
+* When submitting any new non-arcade machine, but especially a machine
+ which does not auto-boot and requires some interaction to start up
+ and be usable, consider adding usage instructions to the
+ `System-Specific Setup and Information <https://wiki.mamedev.org/index.php/System-Specific_Setup_and_Information>`_
+ page of the `MAME Wiki <https://wiki.mamedev.org>`_. Anyone can edit
+ the wiki after creating an account, and sub-pages for your system
+ which discuss technical details of the system are also welcome.
+
+We have guidelines for specific parts of the source:
+
+.. toctree::
+ :titlesonly:
+
+ cxx
+ softlist
diff --git a/docs/source/contributing/softlist.rst b/docs/source/contributing/softlist.rst
new file mode 100644
index 00000000000..afcfa78ffb0
--- /dev/null
+++ b/docs/source/contributing/softlist.rst
@@ -0,0 +1,175 @@
+.. _contributing-softlist:
+
+Guidelines for Software Lists
+=============================
+
+.. contents:: :local:
+
+
+.. _contributing-softlist-intro:
+
+Introduction
+------------
+
+MAME’s software lists describe known software media for emulated
+systems in a form that can be used to identify media image files for
+known software, verify media image file integrity, and load media
+image files for emulation. Software lists are implemented as XML
+files in the ``hash`` folder. The XML structure is described in the
+file ``hash/softwarelist.dtd``.
+
+Philosophically, software list items should represent the original
+media, rather than a specific dump of the media. Ideally, it should be
+possible for anyone with the media to dump it and produce the same image
+file. Of course, this isn’t always possible in practice – in particular
+it’s problematic for inherently analog media, like home computer
+software stored on audio tape cassettes.
+
+MAME strives to document the best available media images. It is not our
+intention to propagate corrupted, truncated, defaced, watermarked, or
+otherwise bad media images. Where possible, file structures matching
+the original media structure are preferred. For example we prefer
+individual files for separate ROM chips in cartridge media, and we use
+disk images rather than archives of files extracted from the original
+disks.
+
+
+.. _contributing-softlist-itempart:
+
+Items and parts
+---------------
+
+A software list is a collection of *items* and each item may have
+multiple *parts*. An item represents a piece of software, as
+distributed as a complete package. A part represents a single piece of
+media within the package. Parts can be mounted individually in
+emulated media devices. For example a piece of software distributed on
+three floppy disks will be a single item, while each floppy disk will be
+one part within that item.
+
+Sometimes, logically separate parts of a single physical piece of media
+are represented as separate parts within a software item. For example
+each side of an audio tape cassette is represented as a separate part.
+However individual ROM chips within a cartridge may be separate files,
+but they are *not* separate parts, as the cartridge is mounted as a
+whole.
+
+Each item is a ``software`` element. The ``software`` element may have
+the following attributes:
+
+name (required)
+ The short name identifying the item. This is used for file names,
+ command line arguments, database keys, URL fragments, and many other
+ purposes. It should be terse but still recognisable. It must be
+ unique within the software list. Valid characters are lowercase
+ English letters, decimal digits and underscores. The maximum
+ allowed length is sixteen characters.
+cloneof (optional)
+ The short name of the parent item if the item is a clone. The
+ parent must be within the same software list – parent/clone
+ relationships spanning multiple software lists are not supported.
+supported (optional)
+ One of the values ``yes`` (fully usable in emulation), ``no`` (not
+ usable in emulation), or ``partial`` (usable in emulation with
+ limitations). If the attribute is not present, it is equivalent to
+ ``yes``. Examples of partially supported software include games
+ that are playable with graphical glitches, and office software where
+ some but not all functionality works.
+
+Each part is a ``part`` element within the ``software`` element. The
+``part`` element must have the following attributes:
+
+name (required)
+ The short name identifying the part. This is used for command line
+ arguments, database keys, URL fragments, and many other purposes.
+ It must be unique within the item. It is also used as the display
+ name if a separate display name is not provided. Valid characters
+ are lowercase English letters, decimal digits and underscores. The
+ maximum allowed length is sixteen characters.
+interface (required)
+ This attribute is used to identify suitable emulated media devices
+ for mounting the software part. Applicable values depend on the
+ emulated system.
+
+
+.. _contributing-softlist-metadata:
+
+Metadata
+--------
+
+Software lists support various kinds of metadata. All software list
+items require the following metadata elements to be present:
+
+description
+ This is the primary display name for the software item. It should
+ be the original name of the software, transliterated into English
+ Latin script if necessary. It must be unique within the software
+ list. If extra text besides the title itself is required for
+ disambiguation, use lowercase outside of proper nouns, initialisms
+ and verbatim quotes.
+year
+ The year of release or copyright year for the software. If unknown,
+ use an estimate with a question mark. Items can be filtered by year
+ in the software selection menu.
+publisher
+ The publisher of the software. This may be the same as the
+ developer if the software was self-published. Items can be filtered
+ by published in the software selection menu.
+
+Most user-visible software item metadata is provided using ``info``
+elements. Each ``info`` element must have a ``name`` attribute and a
+``value`` attribute. The ``name`` attribute identifies the type of
+metadata, and the ``value`` attribute is the metadata value itself.
+Note that ``name`` attributes do not need to be unique within an item.
+Multiple ``info`` elements with the same ``name`` may be present if
+appropriate. This is frequently seen for software sold using different
+titles in different regions.
+
+MAME displays metadata from ``info`` elements in the software selection
+menu. The following ``name`` attributes are recognised specifically,
+and can show localised names:
+
+alt_title
+ Used for alternate titles. Examples are different tiles used in
+ different languages, scripts or regions, or different titles used
+ on the title screen and packaging. MAME searches alternate titles
+ as well as the description.
+author
+ Author of the software. Items can be filtered by author in the
+ software selection menu.
+barcode
+ Barcode number identifying the software package (typically an EAN).
+developer
+ Developer responsible for implementing the software. Items can be
+ filtered by developer in the software selection menu.
+distributor
+ Party responsible for distributing the software to retailers (or
+ customers in the case of direct sales). Items can be filtered by
+ distributor in the software selection menu.
+install
+ Installation instructions.
+isbn
+ ISBN for software included with a commercial book.
+oem
+ Original equipment manufacturer, typically used with customised
+ versions of software distributed by a hardware vendor.
+original_publisher
+ The original publisher, for items representing software re-released
+ by a different publisher.
+partno
+ Distributor’s part number for the software.
+pcb
+ Printed circuit board identifier, typically for cartridge media.
+programmer
+ Programmer who wrote the code for the software.
+release
+ Fine-grained release date for the software, if known. Use
+ YYYYMMDD format with no punctuation. If only the month is known,
+ use “xx” for the day digits. For example ``199103xx`` or
+ ``19940729``.
+serial
+ Number identifying the software within a series of releases.
+usage
+ Usage instructions.
+version
+ Version number of the software.
diff --git a/docs/source/debugger/annotation.rst b/docs/source/debugger/annotation.rst
index 9d897d140c9..4e766257099 100644
--- a/docs/source/debugger/annotation.rst
+++ b/docs/source/debugger/annotation.rst
@@ -3,101 +3,107 @@
Code Annotation Debugger Commands
=================================
+:ref:`debugger-command-comadd`
+ adds a comment to the disassembled code at given address
+:ref:`debugger-command-comdelete`
+ removes a comment from the given address
+:ref:`debugger-command-comsave`
+ save the current comments to file
+:ref:`debugger-command-comlist`
+ list comments stored in the comment file for the system
+:ref:`debugger-command-commit`
+ combined ``comadd`` and ``comsave`` command
-You can also type **help <command>** for further details on each command in the MAME Debugger interface.
-| :ref:`debugger-command-comadd` -- adds a comment to the disassembled code at given address
-| :ref:`debugger-command-comdelete` -- removes a comment from the given address
-| :ref:`debugger-command-comsave` -- save the current comments to a file
-| :ref:`debugger-command-comlist` -- print currently available comments from file
-| :ref:`debugger-command-commit` -- gives a bulk comadd then comsave command
-
-
- .. _debugger-command-comadd:
+.. _debugger-command-comadd:
comadd
------
-| **comadd[//] <address>,<comment>**
-|
-| Adds a string <comment> to the disassembled code at <address>. The shortcut for this command is simply '//'
-|
-| Examples:
-|
-| comadd 0, hello world.
-|
-| Adds the comment 'hello world.' to the code at address 0x0
-|
-| // 10, undocumented opcode!
-|
-| Adds the comment 'undocumented opcode!' to the code at address 0x10
+**comadd <address>,<comment>**
+
+Sets the specified comment for the specified address in the disassembled
+code for the visible CPU. This command may be abbreviated to ``//``.
+
+Examples:
+
+``comadd 0,hello world.``
+ Adds the comment “hello world.” to the code at address 0.
+``// 10,undocumented opcode!``
+ Adds the comment “undocumented opcode!” to the code at address 10.
- .. _debugger-command-comdelete:
+.. _debugger-command-comdelete:
comdelete
---------
-| **comdelete**
-|
-| Deletes the comment at the specified memory offset. The comment which is deleted is in the currently active memory bank.
-|
-| Examples:
-|
-| comdelete 10
-|
-| Deletes the comment at code address 0x10 (using the current memory bank settings)
+**comdelete**
+Deletes the comment at the specified address for the visible CPU.
- .. _debugger-command-comsave:
+Examples:
+
+``comdelete 10``
+ Deletes the comment at code address 10 for the visible CPU.
+
+
+.. _debugger-command-comsave:
comsave
-------
-| **comsave**
-|
-| Saves the working comments to the driver's XML comment file.
-|
-| Examples:
-|
-| comsave
-|
-| Saves the comments to the driver's comment file
+**comsave**
+
+Saves the current comments to the XML comment file for the emulated
+system. This file will be loaded by the debugger the next time the
+system is run with debugging enabled. The directory for saving these
+files is set using the
+:ref:`comment_directory <mame-commandline-commentdirectory>` option.
+Examples:
- .. _debugger-command-comlist:
+``comsave``
+ Saves the current comments to the comment file for the system.
+
+
+.. _debugger-command-comlist:
comlist
-------
-| **comlist**
-|
-| Prints the currently available comment file in human readable form in debugger output window.
-|
-| Examples:
-|
-| comlist
-|
-| Shows currently available comments.
+**comlist**
+
+Reads the comments stored in the XML comment file for the emulated
+system and prints them to the debugger console. This command does not
+affect the comments for the current session, it reads the file directly.
+The directory for these files is set using the
+:ref:`comment_directory <mame-commandline-commentdirectory>` option.
+
+Examples:
+
+comlist
+ Shows comments stored in the comment file for the system.
- .. _debugger-command-commit:
+.. _debugger-command-commit:
commit
------
-| **commit[/*] <address>,<comment>**
-|
-| Adds a string <comment> to the disassembled code at <address> then saves to file. Basically same as comadd + comsave via a single line.
-| The shortcut for this command is simply \'\/\*\'
-|
-| Examples:
-|
-| commit 0, hello world.
-|
-| Adds the comment 'hello world.' to the code at address 0x0
-|
-| /* 10, undocumented opcode!
-|
-| Adds the comment 'undocumented opcode!' to the code at address 0x10
+**commit <address>,<comment>**
+
+Sets the specified comment for the specified address in the disassembled
+code for the visible CPU, and saves comments to the file for the current
+emulated system (equivalent to :ref:`debugger-command-comadd` followed
+by :ref:`debugger-command-comsave`). This command may be abbreviated to
+``/*``.
+
+Examples:
+``commit 0,hello world.``
+ Adds the comment “hello world.” to the code at address 0 for the
+ visible CPU and saves comments.
+``/* 10,undocumented opcode!``
+ Adds the comment “undocumented opcode!” to the code at address 10
+ for the visible CPU and saves comments.
diff --git a/docs/source/debugger/breakpoint.rst b/docs/source/debugger/breakpoint.rst
index 7dede5475be..f30605b2daa 100644
--- a/docs/source/debugger/breakpoint.rst
+++ b/docs/source/debugger/breakpoint.rst
@@ -3,126 +3,166 @@
Breakpoint Debugger Commands
============================
+:ref:`debugger-command-bpset`
+ sets a breakpoint at <address>
+:ref:`debugger-command-bpclear`
+ clears a specific breakpoint or all breakpoints
+:ref:`debugger-command-bpdisable`
+ disables a specific breakpoint or all breakpoints
+:ref:`debugger-command-bpenable`
+ enables a specific breakpoint or all breakpoints
+:ref:`debugger-command-bplist`
+ lists breakpoints
-You can also type **help <command>** for further details on each command in the MAME Debugger interface.
+Breakpoints halt execution and activate the debugger before a CPU
+executes an instruction at a particular address.
-| :ref:`debugger-command-bpset` -- sets breakpoint at <address>
-| :ref:`debugger-command-bpclear` -- clears a given breakpoint or all if no <bpnum> specified
-| :ref:`debugger-command-bpdisable` -- disables a given breakpoint or all if no <bpnum> specified
-| :ref:`debugger-command-bpenable` -- enables a given breakpoint or all if no <bpnum> specified
-| :ref:`debugger-command-bplist` -- lists all the breakpoints
-
- .. _debugger-command-bpset:
+.. _debugger-command-bpset:
bpset
-----
-| **bp[set] <address>[,<condition>[,<action>]]**
-|
-| Sets a new execution breakpoint at the specified <address>.
-| The optional <condition> parameter lets you specify an expression that will be evaluated each time the breakpoint is hit. If the result of the expression is true (non-zero), the breakpoint will actually halt execution; otherwise, execution will continue with no notification.
-| The optional <action> parameter provides a command that is executed whenever the breakpoint is hit and the <condition> is true. Note that you may need to embed the action within braces { } in order to prevent commas and semicolons from being interpreted as applying to the bpset command itself. Each breakpoint that is set is assigned an index which can be used in other breakpoint commands to reference this breakpoint.
-|
-| Examples:
-|
-| bp 1234
-|
-| Set a breakpoint that will halt execution whenever the PC is equal to 1234.
-|
-| bp 23456,a0 == 0 && a1 == 0
-|
-| Set a breakpoint that will halt execution whenever the PC is equal to 23456 AND the expression (a0 == 0 && a1 == 0) is true.
-|
-| bp 3456,1,{printf "A0=%08X\\n",a0; g}
-|
-| Set a breakpoint that will halt execution whenever the PC is equal to 3456. When this happens, print A0=<a0val> and continue executing.
-|
-| bp 45678,a0==100,{a0 = ff; g}
-|
-| Set a breakpoint that will halt execution whenever the PC is equal to 45678 AND the expression (a0 == 100) is true. When that happens, set a0 to ff and resume execution.
-|
-| temp0 = 0; bp 567890,++temp0 >= 10
-|
-| Set a breakpoint that will halt execution whenever the PC is equal to 567890 AND the expression (++temp0 >= 10) is true. This effectively breaks only after the breakpoint has been hit 16 times.
-|
-| Back to :ref:`debugger-breakpoint-list`
-
-
- .. _debugger-command-bpclear:
+**bp[set] <address>[:<CPU>][,<condition>[,<action>]]**
+
+Sets a new execution breakpoint at the specified **<address>**. The
+**<address>** may optionally be followed by a colon and a tag or
+debugger CPU number to set a breakpoint for a specific CPU. If no CPU
+is specified, the breakpoint will be set for the CPU currently visible
+in the debugger.
+
+The optional **<condition>** parameter lets you specify an expression
+that will be evaluated each time the breakpoint address is hit. If the
+result of the expression is true (non-zero), the breakpoint will halt
+execution; otherwise, execution will continue with no notification. The
+optional **<action>** parameter provides a command to be executed
+whenever the breakpoint is hit and the **<condition>** is true. 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 ``bpset`` command itself.
+
+Each breakpoint that is set is assigned a numeric index which can be
+used to refer to it in other breakpoint commands. Breakpoint indices
+are unique throughout a session.
+
+Examples:
+
+``bp 1234``
+ Set a breakpoint for the visible CPU that will halt execution
+ whenever the PC is equal to 1234.
+``bp 23456,a0 == 0 && a1 == 0``
+ Set a breakpoint for the visible CPU that will halt execution
+ whenever the PC is equal to 23456 *and* the expression
+ ``a0 == 0 && a1 == 0`` is true.
+``bp 3456:audiocpu,1,{ printf "A0=%08X\n",a0 ; g }``
+ Set a breakpoint for the CPU with the absolute tag path
+ ``:audiocpu`` that will halt execution whenever the PC is equal to
+ 3456. When this happens, print **A0=<a0val>** to the debugger
+ console and resume execution.
+``bp 45678:2,a0==100,{ a0 = ff ; g }``
+ Set a breakpoint on the third CPU in the system (zero-based index)
+ that will halt execution whenever the PC is equal to 45678 and the
+ expression ``a0 == 100`` is true. When that happens, set **a0** to
+ ff and resume execution.
+``temp0 = 0 ; bp 567890,++temp0 >= 10``
+ Set a breakpoint for the visible CPU that will halt execution
+ whenever the PC is equal to 567890 and the expression
+ ``++temp0 >= 10`` is true. This effectively breaks only after the
+ breakpoint has been hit sixteen times.
+
+Back to :ref:`debugger-breakpoint-list`
+
+
+.. _debugger-command-bpclear:
bpclear
-------
-| **bpclear [<bpnum>]**
-|
-| The bpclear command clears a breakpoint. If <bpnum> is specified, only the requested breakpoint is cleared, otherwise all breakpoints are cleared.
-|
-| Examples:
-|
-| bpclear 3
-|
-| Clear breakpoint index 3.
-|
-| bpclear
-|
-| Clear all breakpoints.
-|
-| Back to :ref:`debugger-breakpoint-list`
-
-
- .. _debugger-command-bpdisable:
+**bpclear [<bpnum>[,…]]**
+
+Clear breakpoints. If **<bpnum>** is specified, the breakpoints
+referred to will be cleared. If **<bpnum>** is not specified, all
+breakpoints will be cleared.
+
+Examples:
+
+``bpclear 3``
+ Clear the breakpoint with index 3.
+``bpclear``
+ Clear all breakpoints.
+
+Back to :ref:`debugger-breakpoint-list`
+
+
+.. _debugger-command-bpdisable:
bpdisable
---------
-| **bpdisable [<bpnum>]**
-|
-| 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 breakpoint does not delete it, it just temporarily marks the breakpoint as inactive.
-|
-| Examples:
-|
-| bpdisable 3
-|
-| Disable breakpoint index 3.
-|
-| bpdisable
-|
-| Disable all breakpoints.
-|
-| Back to :ref:`debugger-breakpoint-list`
-
-
- .. _debugger-command-bpenable:
+**bpdisable [<bpnum>[,…]]**
+
+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
+marks the breakpoint as inactive. Disabled breakpoints will not cause
+execution to halt, their associated condition expressions will not be
+evaluated, and their associated commands will not be executed.
+
+Examples:
+
+``bpdisable 3``
+ Disable the breakpoint with index 3.
+``bpdisable``
+ Disable all breakpoints.
+
+Back to :ref:`debugger-breakpoint-list`
+
+
+.. _debugger-command-bpenable:
bpenable
--------
-| **bpenable [<bpnum>]**
-|
-| The bpenable command enables a breakpoint. If <bpnum> is specified, only the requested breakpoint is enabled, otherwise all breakpoints are enabled.
-|
-| Examples:
-|
-| bpenable 3
-|
-| Enable breakpoint index 3.
-|
-| bpenable
-|
-| Enable all breakpoints.
-|
-| Back to :ref:`debugger-breakpoint-list`
-
-
- .. _debugger-command-bplist:
+**bpenable [<bpnum>[,…]]**
+
+Enable breakpoints. If **<bpnum>** is specified, the breakpoint
+referred to will be enabled. If **<bpnum>** is not specified, all
+breakpoints will be enabled.
+
+Examples:
+
+``bpenable 3``
+ Enable the breakpoint with index 3.
+``bpenable``
+ Enable all breakpoints.
+
+Back to :ref:`debugger-breakpoint-list`
+
+
+.. _debugger-command-bplist:
bplist
------
-| **bplist**
-|
-| The bplist command lists all the current breakpoints, along with their index and any conditions or actions attached to them.
-|
-| Back to :ref:`debugger-breakpoint-list`
+**bplist [<CPU>]**
+
+List current breakpoints, along with their indices and any associated
+conditions or actions. If no **<CPU>** is specified, breakpoints for
+all CPUs in the system will be listed; if a **<CPU>** is specified, only
+breakpoints 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:
+
+``bplist``
+ List all breakpoints.
+``bplist .``
+ List all breakpoints for the visible CPU.
+``bplist maincpu``
+ List all breakpoints for the CPU with the absolute tag path
+ ``:maincpu``.
+Back to :ref:`debugger-breakpoint-list`
diff --git a/docs/source/debugger/cheats.rst b/docs/source/debugger/cheats.rst
index 1b6764c8e79..52f81259907 100644
--- a/docs/source/debugger/cheats.rst
+++ b/docs/source/debugger/cheats.rst
@@ -3,144 +3,191 @@
Cheat Debugger Commands
=======================
+:ref:`debugger-command-cheatinit`
+ initialize the cheat search to the selected memory area
+:ref:`debugger-command-cheatrange`
+ add selected memory area to cheat search
+:ref:`debugger-command-cheatnext`
+ filter cheat candidates by comparing to previous values
+:ref:`debugger-command-cheatnextf`
+ filter cheat candidates by comparing to initial value
+:ref:`debugger-command-cheatlist`
+ show the list of cheat search matches or save them to a file
+:ref:`debugger-command-cheatundo`
+ undo the last cheat search (state only)
-You can also type **help <command>** for further details on each command in the MAME Debugger interface.
+The debugger includes basic cheat search functionality, which works
+by saving the contents of memory, and then filtering locations according
+to how the values change.
-| :ref:`debugger-command-cheatinit` -- initialize the cheat search to the selected memory area
-| :ref:`debugger-command-cheatrange` -- add to the cheat search the selected memory area
-| :ref:`debugger-command-cheatnext` -- continue cheat search comparing with the last value
-| :ref:`debugger-command-cheatnextf` -- continue cheat search comparing with the first value
-| :ref:`debugger-command-cheatlist` -- show the list of cheat search matches or save them to <filename>
-| :ref:`debugger-command-cheatundo` -- undo the last cheat search (state only)
+We’ll demonstrate use of the cheat search functionality to make an
+infinite lives cheat for Raiden (``raiden``):
- .. _debugger-command-cheatinit:
+* Start the game with the debugger active. Allow the game to run,
+ insert a coin, and start a game, then break into the debugger.
+* Ensure the main CPU is visible, and start a search for 8-bit unsigned
+ values using the
+ :ref:`cheatinit command <debugger-command-cheatinit>`::
+
+ >cheatinit ub
+ 36928 cheat locations initialized for NEC V30 ':maincpu' program space
+* Allow the game to run, lose a life and break into the debugger.
+* Use the :ref:`cheatnext command <debugger-command-cheatnext>` to
+ filter locations that have decreased by 1::
+
+ >cheatnext -,1
+ 12 cheats found
+* Allow the game to run, lose another life, break into the
+ debugger, and filter locations that have decreased by 1 again::
+
+ >cheatnext -,1
+ Address=0B85 Start=03 Current=01
+ 1 cheats found
+* Use the :ref:`cheatlist command <debugger-command-cheatlist>` to save
+ the cheat candidate to a file::
+
+ >cheatlist raiden-p1-lives.xml
+* The file now contains an XML fragment with cheat to set the candidate
+ location to the initial value:
+
+ .. code-block:: XML
+
+ <cheat desc="Possibility 1: 00B85 (01)">
+ <script state="run">
+ <action>:maincpu.pb@0x00B85=0x03</action>
+ </script>
+ </cheat>
+
+
+.. _debugger-command-cheatinit:
cheatinit
---------
-| **cheatinit [<sign><width><swap>,[<address>,<length>[,<cpu>]]]**
-|
-| The cheatinit command initializes the cheat search to the selected memory area.
-|
-| If no parameter is specified the cheat search is initialized to all changeable memory of the main CPU.
-|
-| <sign> can be s(signed) or u(unsigned)
-| <width> can be b(8 bit), w(16 bit), d(32 bit) or q(64 bit)
-| <swap> append s for swapped search
-|
-| Examples:
-|
-| cheatinit ub,0x1000,0x10
-|
-| Initialize the cheat search from 0x1000 to 0x1010 of the first CPU.
-|
-| cheatinit sw,0x2000,0x1000,1
-|
-| Initialize the cheat search with width of 2 byte in signed mode from 0x2000 to 0x3000 of the second CPU.
-|
-| cheatinit uds,0x0000,0x1000
-|
-| Initialize the cheat search with width of 4 byte swapped from 0x0000 to 0x1000.
-|
-| Back to :ref:`debugger-cheats-list`
-
-
- .. _debugger-command-cheatrange:
+**cheatinit [[<sign>[<width>[<swap>]]],[<address>,<length>[,<space>]]]**
+
+Initialize the cheat search to writable RAM areas in the specified
+address space. May be abbreviated to ``ci``.
+
+The first argument specifies the data format to search for. The
+**<sign>** may be **u** for unsigned or **s** for signed, the
+**<width>** may be **b** for 8-bit (byte), **w** for 16-bit (word),
+**d** for 32-bit (double word), or **q** for 64-bit (quadruple word);
+**<swap>** may be **s** for reversed byte order. If the first argument
+is omitted or empty, the data format from the previous cheat search is
+used, or unsigned 8-bit format if this is the first cheat search.
+
+The **<address>** specifies the address to start searching from, and the
+**<length>** specifies how much memory to search. If specified,
+writable RAM in the range **<address>** through
+**<address>+<length>-1**, inclusive, will be searched; otherwise, all
+writable RAM in the address space will be searched.
+
+See :ref:`debugger-devicespec` for details on specifying address spaces.
+If the address space is not specified, it defaults to the first address
+space exposed by the visible CPU.
+
+Examples:
+
+``cheatinit ub,0x1000,0x10``
+ Initialize the cheat search for unsigned 8-bit values in addresses
+ 0x1000-0x100f in the program space of the visible CPU.
+``cheatinit sw,0x2000,0x1000,1``
+ Initialize the cheat search for signed 16-bit values in addresses
+ 0x2000-0x2fff in the program space of the second CPU in the system
+ (zero-based index).
+``cheatinit uds,0x0000,0x1000``
+ Initialize the cheat search for unsigned 64-bit values with reverse
+ byte order in addresses 0x0000-0x0fff in the program space of the
+ visible CPU.
+
+Back to :ref:`debugger-cheats-list`
+
+
+.. _debugger-command-cheatrange:
cheatrange
----------
-| **cheatrange <address>,<length>**
-|
-| The cheatrange command adds the selected memory area to the cheat search.
-|
-| Before using cheatrange it is necessary to initialize the cheat search with cheatinit.
-|
-| Examples:
-|
-| cheatrange 0x1000,0x10
-|
-| Add the bytes from 0x1000 to 0x1010 to the cheat search.
-|
-| Back to :ref:`debugger-cheats-list`
+**cheatrange <address>,<length>**
+
+Add writable RAM areas to the cheat search. May be abbreviated to
+``cr``. Before using this command, the
+:ref:`cheatinit command <debugger-command-cheatinit>` must be used to
+initialize the cheat search and set the address space and data format.
+The **<address>** specifies the address to start searching from, and the
+**<length>** specifies how much memory to search. Writable RAM in the
+range **<address>** through **<address>+<length>-1**, inclusive, will be
+added to the areas to search.
- .. _debugger-command-cheatnext:
+Examples:
+
+``cheatrange 0x1000,0x10``
+ Add addresses 0x1000-0x100f to the areas to search for cheats.
+
+Back to :ref:`debugger-cheats-list`
+
+
+.. _debugger-command-cheatnext:
cheatnext
---------
-| **cheatnext <condition>[,<comparisonvalue>]**
-|
-| The cheatnext command will make comparisons with the last search matches.
-|
-| Possible <condition>:
-|
-| **all**
-|
-| No <comparisonvalue> needed.
-|
-| Use to update the last value without changing the current matches.
-|
-| **equal [eq]**
-|
-| Without <comparisonvalue> search for all bytes that are equal to the last search.
-| With <comparisonvalue> search for all bytes that are equal to the <comparisonvalue>.
-|
-| **notequal [ne]**
-|
-| Without <comparisonvalue> search for all bytes that are not equal to the last search.
-| With <comparisonvalue> search for all bytes that are not equal to the <comparisonvalue>.
-|
-| **decrease [de, +]**
-|
-| Without <comparisonvalue> search for all bytes that have decreased since the last search.
-| With <comparisonvalue> search for all bytes that have decreased by the <comparisonvalue> since the last search.
-|
-| **increase [in, -]**
-|
-| Without <comparisonvalue> search for all bytes that have increased since the last search.
-| With <comparisonvalue> search for all bytes that have increased by the <comparisonvalue> since the last search.
-|
-| **decreaseorequal [deeq]**
-|
-| No <comparisonvalue> needed.
-|
-| Search for all bytes that have decreased or have same value since the last search.
-|
-| **increaseorequal [ineq]**
-|
-| No <comparisonvalue> needed.
-|
-| Search for all bytes that have decreased or have same value since the last search.
-|
-| **smallerof [lt]**
-|
-| Without <comparisonvalue> this condition is invalid
-| With <comparisonvalue> search for all bytes that are smaller than the <comparisonvalue>.
-|
-| **greaterof [gt]**
-|
-| Without <comparisonvalue> this condition is invalid
-| With <comparisonvalue> search for all bytes that are larger than the <comparisonvalue>.
-|
-| **changedby [ch, ~]**
-|
-| Without <comparisonvalue> this condition is invalid
-| With <comparisonvalue> search for all bytes that have changed by the <comparisonvalue> since the last search.
-|
-|
-| Examples:
-|
-| cheatnext increase
-|
-| Search for all bytes that have increased since the last search.
-|
-| cheatnext decrease, 1
-|
-| Search for all bytes that have decreased by 1 since the last search.
-|
-| Back to :ref:`debugger-cheats-list`
+**cheatnext <condition>[,<comparisonvalue>]**
+
+Filter candidates by comparing to the previous search values. If five
+or fewer candidates remain, they will be shown in the debugger console.
+May be abbreviated to ``cn``.
+
+Possible **<condition>** arguments:
+
+``all``
+ Use to update the last value without changing the current matches
+ (the **<comparisonvalue>** is not used).
+``equal`` (``eq``)
+ Without **<comparisonvalue>**, search for values that are equal to
+ the previous search; with **<comparisonvalue>**, search for values
+ that are equal to the **<comparisonvalue>**.
+``notequal`` (``ne``)
+ Without **<comparisonvalue>**, search for values that are not equal
+ to the previous search; with **<comparisonvalue>**, search for
+ values that are not equal to the **<comparisonvalue>**.
+``decrease`` (``de``, ``-``)
+ Without **<comparisonvalue>**, search for values that have decreased
+ since the previous search; with **<comparisonvalue>**, search for
+ values that have decreased by the **<comparisonvalue>** since the
+ previous search.
+``increase`` (``in``, ``+``)
+ Without **<comparisonvalue>**, search for values that have increased
+ since the previous search; with **<comparisonvalue>**, search for
+ values that have increased by the **<comparisonvalue>** since the
+ previous search.
+``decreaseorequal`` (``deeq``)
+ Search for values that have decreased or are unchanged since the
+ previous search (the **<comparisonvalue>** is not used).
+``increaseorequal`` (``ineq``)
+ Search for values that have increased or are unchanged since the
+ previous search (the **<comparisonvalue>** is not used).
+``smallerof`` (``lt``, ``<``)
+ Search for values that are less than the **<comparisonvalue>** (the
+ **<comparisonvalue>** is required).
+``greaterof`` (``gt``, ``>``)
+ Search for values that are greater than the **<comparisonvalue>**
+ (the **<comparisonvalue>** is required).
+``changedby`` (``ch``, ``~``)
+ Search for values that have changed by the **<comparisonvalue>**
+ since the previous search (the **<comparisonvalue>** is required).
+
+Examples:
+
+``cheatnext increase``
+ Search for all values that have increased since the previous search.
+``cheatnext decrease,1``
+ Search for all values that have decreased by 1 since the previous
+ search.
+
+Back to :ref:`debugger-cheats-list`
.. _debugger-command-cheatnextf:
@@ -148,120 +195,100 @@ cheatnext
cheatnextf
----------
-| **cheatnextf <condition>[,<comparisonvalue>]**
-|
-| The cheatnextf command will make comparisons with the initial search.
-|
-| Possible <condition>:
-|
-| **all**
-|
-| No <comparisonvalue> needed.
-|
-| Use to update the last value without changing the current matches.
-|
-| **equal [eq]**
-|
-| Without <comparisonvalue> search for all bytes that are equal to the initial search.
-| With <comparisonvalue> search for all bytes that are equal to the <comparisonvalue>.
-|
-| **notequal [ne]**
-|
-| Without <comparisonvalue> search for all bytes that are not equal to the initial search.
-| With <comparisonvalue> search for all bytes that are not equal to the <comparisonvalue>.
-|
-| **decrease [de, +]**
-|
-| Without <comparisonvalue> search for all bytes that have decreased since the initial search.
-| With <comparisonvalue> search for all bytes that have decreased by the <comparisonvalue> since the initial search.
-|
-| **increase [in, -]**
-|
-| Without <comparisonvalue> search for all bytes that have increased since the initial search.
-|
-| With <comparisonvalue> search for all bytes that have increased by the <comparisonvalue> since the initial search.
-|
-| **decreaseorequal [deeq]**
-|
-| No <comparisonvalue> needed.
-|
-| Search for all bytes that have decreased or have same value since the initial search.
-|
-| **increaseorequal [ineq]**
-|
-| No <comparisonvalue> needed.
-|
-| Search for all bytes that have decreased or have same value since the initial search.
-|
-| **smallerof [lt]**
-|
-| Without <comparisonvalue> this condition is invalid.
-| With <comparisonvalue> search for all bytes that are smaller than the <comparisonvalue>.
-|
-| **greaterof [gt]**
-|
-| Without <comparisonvalue> this condition is invalid.
-| With <comparisonvalue> search for all bytes that are larger than the <comparisonvalue>.
-|
-| **changedby [ch, ~]**
-|
-| Without <comparisonvalue> this condition is invalid
-| With <comparisonvalue> search for all bytes that have changed by the <comparisonvalue> since the initial search.
-|
-|
-| Examples:
-|
-| cheatnextf increase
-|
-| Search for all bytes that have increased since the initial search.
-|
-| cheatnextf decrease, 1
-|
-| Search for all bytes that have decreased by 1 since the initial search.
-|
-| Back to :ref:`debugger-cheats-list`
-
-
- .. _debugger-command-cheatlist:
+**cheatnextf <condition>[,<comparisonvalue>]**
+
+Filter candidates by comparing to the initial search values. If five or
+fewer candidates remain, they will be shown in the debugger console.
+May be abbreviated to ``cn``.
+
+Possible **<condition>** arguments:
+
+``all``
+ Use to update the last value without changing the current matches
+ (the **<comparisonvalue>** is not used).
+``equal`` (``eq``)
+ Without **<comparisonvalue>**, search for values that are equal to
+ the initial search; with **<comparisonvalue>**, search for values
+ that are equal to the **<comparisonvalue>**.
+``notequal`` (``ne``)
+ Without **<comparisonvalue>**, search for values that are not equal
+ to the initial search; with **<comparisonvalue>**, search for values
+ that are not equal to the **<comparisonvalue>**.
+``decrease`` (``de``, ``-``)
+ Without **<comparisonvalue>**, search for values that have decreased
+ since the initial search; with **<comparisonvalue>**, search for
+ values that have decreased by the **<comparisonvalue>** since the
+ initial search.
+``increase`` (``in``, ``+``)
+ Without **<comparisonvalue>**, search for values that have increased
+ since the initial search; with **<comparisonvalue>**, search for
+ values that have increased by the **<comparisonvalue>** since the
+ initial search.
+``decreaseorequal`` (``deeq``)
+ Search for values that have decreased or are unchanged since the
+ initial search (the **<comparisonvalue>** is not used).
+``increaseorequal`` (``ineq``)
+ Search for values that have increased or are unchanged since the
+ initial search (the **<comparisonvalue>** is not used).
+``smallerof`` (``lt``, ``<``)
+ Search for values that are less than the **<comparisonvalue>** (the
+ **<comparisonvalue>** is required).
+``greaterof`` (``gt``, ``>``)
+ Search for values that are greater than the **<comparisonvalue>**
+ (the **<comparisonvalue>** is required).
+``changedby`` (``ch``, ``~``)
+ Search for values that have changed by the **<comparisonvalue>**
+ since the initial search (the **<comparisonvalue>** is required).
+
+Examples:
+
+``cheatnextf increase``
+ Search for all values that have increased since the initial search.
+``cheatnextf decrease,1``
+ Search for all values that have decreased by 1 since the initial
+ search.
+
+Back to :ref:`debugger-cheats-list`
+
+
+.. _debugger-command-cheatlist:
cheatlist
---------
-| **cheatlist [<filename>]**
-|
-| Without <filename> show the list of matches in the debug console.
-| With <filename> save the list of matches in basic XML format to <filename>.
-|
-| Examples:
-|
-| cheatlist
-|
-| Show the current matches in the debug console.
-|
-| cheatlist cheat.txt
-|
-| Save the current matches in XML format to cheat.txt.
-|
-| Back to :ref:`debugger-cheats-list`
-
-
- .. _debugger-command-cheatundo:
+**cheatlist [<filename>]**
+
+Without **<filename>**, show the current cheat matches in the debugger
+console; with **<filename>**, save the current cheat matches in basic
+XML format to the specified file. May be abbreviated to ``cl``.
+
+Examples:
+
+``cheatlist``
+ Show the current matches in the console.
+``cheatlist cheat.xml``
+ Save the current matches to the file **cheat.xml** in XML format.
+
+Back to :ref:`debugger-cheats-list`
+
+
+.. _debugger-command-cheatundo:
cheatundo
---------
-| **cheatundo**
-|
-| Undo the results of the last search.
-|
-| The undo command has no effect on the last value.
-|
-|
-| Examples:
-|
-| cheatundo
-|
-| Undo the last search (state only).
-|
-| Back to :ref:`debugger-cheats-list`
+**cheatundo**
+
+Undo filtering of cheat candidates by the most recent
+:ref:`cheatnext <debugger-command-cheatnext>` or
+:ref:`cheatnextf <debugger-command-cheatnextf>` command. Note that the
+previous values *are not* rolled back. May be abbreviated to ``cu``.
+
+Examples:
+
+``cheatundo``
+ Restore cheat candidates filtered out by the most recent
+ :ref:`cheatnext <debugger-command-cheatnext>` or
+ :ref:`cheatnextf <debugger-command-cheatnextf>` command.
+Back to :ref:`debugger-cheats-list`
diff --git a/docs/source/debugger/exceptionpoint.rst b/docs/source/debugger/exceptionpoint.rst
new file mode 100644
index 00000000000..46ce7b8d41a
--- /dev/null
+++ b/docs/source/debugger/exceptionpoint.rst
@@ -0,0 +1,134 @@
+.. _debugger-exceptionpoint-list:
+
+Exceptionpoint Debugger Commands
+================================
+
+:ref:`debugger-command-epset`
+ sets a new exceptionpoint
+:ref:`debugger-command-epclear`
+ clears a specific exceptionpoint or all exceptionpoints
+:ref:`debugger-command-epdisable`
+ disables a specific exceptionpoint or all exceptionpoints
+:ref:`debugger-command-epenable`
+ enables a specific exceptionpoint or all exceptionpoints
+:ref:`debugger-command-eplist`
+ lists exceptionpoints
+
+Exceptionpoints halt execution and activate the debugger when a CPU
+raises a particular exception number.
+
+
+.. _debugger-command-epset:
+
+epset
+-----
+
+**ep[set] <type>[,<condition>[,<action>]]**
+
+Sets a new exceptionpoint for exceptions of type **<type>**. The
+optional **<condition>** parameter lets you specify an expression that
+will be evaluated each time the exceptionpoint is hit. If the result
+of the expression is true (non-zero), the exceptionpoint will actually
+halt execution at the start of the exception handler; otherwise,
+execution will continue with no notification. The optional **<action>**
+parameter provides a command that is executed whenever the
+exceptionpoint is hit and the **<condition>** is true. Note that you
+may need to embed the action within braces ``{ }`` in order to prevent
+commas and semicolons from being interpreted as applying to the
+``epset`` command itself.
+
+The numbering of exceptions depends upon the CPU type. Causes of
+exceptions may include internally or externally vectored interrupts,
+errors occurring within instructions and system calls.
+
+Each exceptionpoint that is set is assigned an index which can be used
+in other exceptionpoint commands to reference this exceptionpoint.
+
+Examples:
+
+``ep 2``
+ Set an exception that will halt execution whenever the visible CPU
+ raises exception number 2.
+
+Back to :ref:`debugger-exceptionpoint-list`
+
+
+.. _debugger-command-epclear:
+
+epclear
+-------
+
+**epclear [<epnum>[,…]]**
+
+The epclear command clears exceptionpoints. If **<epnum>** is
+specified, only the requested exceptionpoints are cleared, otherwise
+all exceptionpoints are cleared.
+
+Examples:
+
+``epclear 3``
+ Clear exceptionpoint index 3.
+
+``epclear``
+ Clear all exceptionpoints.
+
+Back to :ref:`debugger-exceptionpoint-list`
+
+
+.. _debugger-command-epdisable:
+
+epdisable
+---------
+
+**epdisable [<epnum>[,…]]**
+
+The epdisable command disables exceptionpoints. If **<epnum>** is
+specified, only the requested exceptionpoints are disabled, otherwise
+all exceptionpoints are disabled. Note that disabling an
+exceptionpoint does not delete it, it just temporarily marks the
+exceptionpoint as inactive.
+
+Examples:
+
+``epdisable 3``
+ Disable exceptionpoint index 3.
+
+``epdisable``
+ Disable all exceptionpoints.
+
+Back to :ref:`debugger-exceptionpoint-list`
+
+
+.. _debugger-command-epenable:
+
+epenable
+--------
+
+**epenable [<epnum>[,…]]**
+
+The epenable command enables exceptionpoints. If **<epnum>** is
+specified, only the requested exceptionpoints are enabled, otherwise
+all exceptionpoints are enabled.
+
+Examples:
+
+``epenable 3``
+ Enable exceptionpoint index 3.
+
+``epenable``
+ Enable all exceptionpoints.
+
+Back to :ref:`debugger-exceptionpoint-list`
+
+
+.. _debugger-command-eplist:
+
+eplist
+------
+
+**eplist**
+
+The eplist command lists all the current exceptionpoints, along with
+their index and any conditions or actions attached to them.
+
+Back to :ref:`debugger-exceptionpoint-list`
diff --git a/docs/source/debugger/execution.rst b/docs/source/debugger/execution.rst
index fd2cc597f26..b4de833b43f 100644
--- a/docs/source/debugger/execution.rst
+++ b/docs/source/debugger/execution.rst
@@ -3,358 +3,548 @@
Execution Debugger Commands
===========================
+:ref:`debugger-command-step`
+ single step for <count> instructions (F11)
+:ref:`debugger-command-over`
+ single step over <count> instructions (F10)
+:ref:`debugger-command-out`
+ single step until the current subroutine/exception handler returns
+ (Shift-F11)
+:ref:`debugger-command-go`
+ resume execution (F5)
+:ref:`debugger-command-gbt`
+ resume execution until next true branch is executed
+:ref:`debugger-command-gbf`
+ resume execution until next false branch is executed
+:ref:`debugger-command-gex`
+ resume execution until exception is raised
+:ref:`debugger-command-gint`
+ resume execution until interrupt is taken (F7)
+:ref:`debugger-command-gni`
+ resume execution until next further instruction
+:ref:`debugger-command-gtime`
+ resume execution until the given delay has elapsed
+:ref:`debugger-command-gvblank`
+ resume execution until next vertical blanking interval (F8)
+:ref:`debugger-command-next`
+ resume execution until the next CPU switch (F6)
+:ref:`debugger-command-focus`
+ focus debugger only on <CPU>
+:ref:`debugger-command-ignore`
+ stop debugging on <CPU>
+:ref:`debugger-command-observe`
+ resume debugging on <CPU>
+:ref:`debugger-command-trace`
+ trace the specified CPU to a file
+:ref:`debugger-command-traceover`
+ trace the specified CPU to a file skipping subroutines
+:ref:`debugger-command-traceflush`
+ flush all open trace files.
+
+
+.. _debugger-command-step:
-You can also type **help <command>** for further details on each command in the MAME Debugger interface.
+step
+----
-| :ref:`debugger-command-step` -- single steps for <count> instructions (F11)
-| :ref:`debugger-command-over` -- single steps over <count> instructions (F10)
-| :ref:`debugger-command-out` -- single steps until the current subroutine/exception handler is exited (Shift-F11)
-| :ref:`debugger-command-go` -- resumes execution, sets temp breakpoint at <address> (F5)
-| :ref:`debugger-command-gint` -- resumes execution, setting temp breakpoint if <irqline> is taken (F7)
-| :ref:`debugger-command-gtime` -- resumes execution until the given delay has elapsed
-| :ref:`debugger-command-gvblank` -- resumes execution, setting temp breakpoint on the next VBLANK (F8)
-| :ref:`debugger-command-next` -- executes until the next CPU switch (F6)
-| :ref:`debugger-command-focus` -- focuses debugger only on <cpu>
-| :ref:`debugger-command-ignore` -- stops debugging on <cpu>
-| :ref:`debugger-command-observe` -- resumes debugging on <cpu>
-| :ref:`debugger-command-trace` -- trace the given CPU to a file (defaults to active CPU)
-| :ref:`debugger-command-traceover` -- trace the given CPU to a file, but skip subroutines (defaults to active CPU)
-| :ref:`debugger-command-traceflush` -- flushes all open trace files.
+**s[tep] [<count>]**
+Single steps one or more instructions on the currently executing CPU.
+Executes one instruction if **<count>** is omitted, or steps **<count>**
+instructions if it is supplied.
- .. _debugger-command-step:
+Examples:
-step
-----
+``s``
+ Steps forward one instruction on the current CPU.
+``step 4``
+ Steps forward four instructions on the current CPU.
-| **s[tep] [<count>=1]**
-|
-| The step command single steps one or more instructions in the currently executing CPU. By default, step executes one instruction each time it is issued. You can also tell step to step multiple instructions by including the optional <count> parameter.
-|
-| Examples:
-|
-| s
-|
-| Steps forward one instruction on the current CPU.
-|
-| step 4
-|
-| Steps forward four instructions on the current CPU.
-|
-| Back to :ref:`debugger-execution-list`
-
-
- .. _debugger-command-over:
+Back to :ref:`debugger-execution-list`
+
+
+.. _debugger-command-over:
over
----
-| **o[ver] [<count>=1]**
-|
-| The over command single steps "over" one or more instructions in the currently executing CPU, stepping over subroutine calls and exception handler traps and counting them as a single instruction. Note that when stepping over a subroutine call, code may execute on other CPUs before the subroutine call completes. By default, over executes one instruction each time it is issued. You can also tell step to step multiple instructions by including the optional <count> parameter.
-|
-| Note that the step over functionality may not be implemented on all CPU types. If it is not implemented, then 'over' will behave exactly like 'step'.
-|
-| Examples:
-|
-| o
-|
-| Steps forward over one instruction on the current CPU.
-|
-| over 4
-|
-| Steps forward over four instructions on the current CPU.
-|
-| Back to :ref:`debugger-execution-list`
-
-
- .. _debugger-command-out:
+**o[ver] [<count>]**
+
+The over command single steps “over” one or more instructions on the
+currently executing CPU, stepping over subroutine calls and exception
+handler traps and counting them as a single instruction. Note that when
+stepping over a subroutine call, code may execute on other CPUs before
+the subroutine returns.
+
+Steps over one instruction if **<count>** is omitted, or steps over
+**<count>** instructions if it is supplied.
+
+Note that the step over functionality may not be implemented for all CPU
+types. If it is not implemented, then ``over`` will behave exactly like
+:ref:`debugger-command-step`.
+
+Examples:
+
+``o``
+ Steps forward over one instruction on the current CPU.
+``over 4``
+ Steps forward over four instructions on the current CPU.
+
+Back to :ref:`debugger-execution-list`
+
+
+.. _debugger-command-out:
out
---
-| **out**
-|
-| The out command single steps until it encounters a return from subroutine or return from exception instruction. Note that because it detects return from exception conditions, if you attempt to step out of a subroutine and an interrupt/exception occurs before you hit the end, then you may stop prematurely at the end of the exception handler.
-|
-| Note that the step out functionality may not be implemented on all CPU types. If it is not implemented, then 'out' will behave exactly like 'step'.
-|
-| Examples:
-|
-| out
-|
-| Steps until the current subroutine or exception handler returns.
-|
-| Back to :ref:`debugger-execution-list`
+**out**
+
+Single steps until a return from subroutine or return from exception
+instruction is encountered. Note that because it detects return from
+exception conditions, if you attempt to step out of a subroutine and an
+interrupt/exception occurs before the subroutine completes, execution
+may stop prematurely at the end of the exception handler.
+Note that the step out functionality may not be implemented for all CPU
+types. If it is not implemented, then ``out`` will behave exactly like
+:ref:`debugger-command-step`.
- .. _debugger-command-go:
+Example:
+
+``out``
+ Steps until a subroutine or exception handler returns.
+
+Back to :ref:`debugger-execution-list`
+
+
+.. _debugger-command-go:
go
--
-| **g[o] [<address>]**
-|
-| The go command resumes execution of the current code. Control will not be returned to the debugger until a breakpoint or watchpoint is hit, or until you manually break in using the assigned key. The go command takes an optional <address> parameter which is a temporary unconditional breakpoint that is set before executing, and automatically removed when hit.
-|
-| Examples:
-|
-| g
-|
-| Resume execution until the next break/watchpoint or until a manual break.
-|
-| g 1234
-|
-| Resume execution, stopping at address 1234 unless something else stops us first.
-|
-| Back to :ref:`debugger-execution-list`
-
-
- .. _debugger-command-gvblank:
+**g[o] [<address>]**
-gvblank
--------
+Resumes execution. Control will not be returned to the debugger until a
+breakpoint or watchpoint is triggered, or a debugger break is manually
+requested. If the optional **<address>** is supplied, a temporary
+unconditional breakpoint will be set for the visible CPU at the
+specified address. It will be cleared automatically when triggered.
+
+Examples:
+
+``g``
+ Resume execution until a breakpoint/watchpoint is triggered, or a
+ break is manually requested.
+``g 1234``
+ Resume execution, stopping at address 1234, unless another condition
+ causes execution to stop before then.
+
+Back to :ref:`debugger-execution-list`
+
+
+.. _debugger-command-gbf:
+
+gbf
+---
+
+**gbf [<condition>]**
-| **gv[blank]**
-|
-| The gvblank command resumes execution of the current code. Control will not be returned to the debugger until a breakpoint or watchpoint is hit, or until the next VBLANK occurs in the emulator.
-|
-| Examples:
-|
-| gv
-|
-| Resume execution until the next break/watchpoint or until the next VBLANK.
-|
-| Back to :ref:`debugger-execution-list`
+Resumes execution. Control will not be returned to the debugger until
+a breakpoint or watchpoint is triggered, or until a conditional branch
+or skip instruction is not taken, following any delay slots.
+The optional **<condition>** parameter lets you specify an expression
+that will be evaluated each time a conditional branch is encountered.
+If the result of the expression is true (non-zero), execution will be
+halted after the branch if it is not taken; otherwise, execution will
+continue with no notification.
- .. _debugger-command-gint:
+Examples:
+
+``gbf``
+ Resume execution until a breakpoint/watchpoint is triggered, or
+ until the next false branch.
+``gbf {pc != 1234}``
+ Resume execution until the next false branch, disregarding the
+ instruction at address 1234.
+
+Back to :ref:`debugger-execution-list`
+
+
+.. _debugger-command-gbt:
+
+gbt
+---
+
+**gbt [<condition>]**
+
+Resumes execution. Control will not be returned to the debugger until
+a breakpoint or watchpoint is triggered, or until a conditional branch
+or skip instruction is taken, following any delay slots.
+
+The optional **<condition>** parameter lets you specify an expression
+that will be evaluated each time a conditional branch is encountered.
+If the result of the expression is true (non-zero), execution will be
+halted after the branch if it is taken; otherwise, execution will
+continue with no notification.
+
+Examples:
+
+``gbt``
+ Resume execution until a breakpoint/watchpoint is triggered, or
+ until the next true branch.
+``gbt {pc != 1234}``
+ Resume execution until the next true branch, disregarding the
+ instruction at address 1234.
+
+Back to :ref:`debugger-execution-list`
+
+
+.. _debugger-command-gex:
+
+gex
+---
+
+**ge[x] [<exception>,[<condition>]]**
+
+Resumes execution. Control will not be returned to the debugger until
+a breakpoint or watchpoint is triggered, or until an exception condition
+is raised on the current CPU. Use the optional **<exception>**
+parameter to stop execution only for a specific exception condition. If
+**<exception>** is omitted, execution will stop for any exception
+condition.
+
+The optional **<condition>** parameter lets you specify an expression
+that will be evaluated each time the specified exception condition
+is raised. If the result of the expression is true (non-zero), the
+exception will halt execution; otherwise, execution will continue with
+no notification.
+
+Examples:
+
+``gex``
+ Resume execution until a breakpoint/watchpoint is triggered, or
+ until any exception condition is raised on the current CPU.
+``ge 2``
+ Resume execution until a breakpoint/watchpoint is triggered, or
+ until exception condition 2 is raised on the current CPU.
+
+Back to :ref:`debugger-execution-list`
+
+
+.. _debugger-command-gint:
gint
----
-| **gi[nt] [<irqline>]**
-|
-| The gint command resumes execution of the current code. Control will not be returned to the debugger until a breakpoint or watchpoint is hit, or until an IRQ is asserted and acknowledged on the current CPU. You can specify <irqline> if you wish to stop execution only on a particular IRQ line being asserted and acknowledged. If <irqline> is omitted, then any IRQ line will stop execution.
-|
-| Examples:
-|
-| gi
-|
-| Resume execution until the next break/watchpoint or until any IRQ is asserted and acknowledged on the current CPU.
-|
-| gint 4
-|
-| Resume execution until the next break/watchpoint or until IRQ line 4 is asserted and acknowledged on the current CPU.
-|
-| Back to :ref:`debugger-execution-list`
-
-
- .. _debugger-command-gtime:
+**gi[nt] [<irqline>]**
+
+Resumes execution. Control will not be returned to the debugger until a
+breakpoint or watchpoint is triggered, or until an interrupt is asserted
+and acknowledged on the current CPU. Use the optional **<irqline>**
+parameter to stop execution only for a specific interrupt line being
+asserted and acknowledged. If **<irqline>** is omitted, execution will
+stop when any interrupt is acknowledged.
+
+Examples:
+
+``gi``
+ Resume execution until a breakpoint/watchpoint is triggered, or
+ any interrupt is asserted and acknowledged on the current CPU.
+``gint 4``
+ Resume execution until a breakpoint/watchpoint is triggered, or
+ interrupt request line 4 is asserted and acknowledged on the current
+ CPU.
+
+Back to :ref:`debugger-execution-list`
+
+
+.. _debugger-command-gni:
+
+gni
+---
+
+**gni [<count>]**
+
+Resumes execution. Control will not be returned to the debugger until a
+breakpoint or watchpoint is triggered. A temporary unconditional breakpoint
+is set at the program address **<count>** instructions sequentially past the
+current one. When this breakpoint is hit, it is automatically removed.
+
+The **<count>** parameter is optional and defaults to 1 if omitted. If
+**<count>** is specified as zero, the command does nothing. **<count>** is
+not permitted to exceed 512 decimal.
+
+Examples:
+
+``gni``
+ Resume execution until a breakpoint/watchpoint is triggered, including
+ the temporary breakpoint set at the address of the following instruction.
+``gni 2``
+ Resume execution until a breakpoint/watchpoint is triggered. A temporary
+ breakpoint is set two instructions past the current one.
+
+Back to :ref:`debugger-execution-list`
+
+
+.. _debugger-command-gtime:
gtime
-----
-| **gt[ime] <milliseconds>**
-|
-| The gtime command resumes execution of the current code. Control will not be returned to the debugger until a specified delay has elapsed. The delay is in milliseconds.
-|
-| Example:
-|
-| gtime #10000
-|
-| Resume execution for ten seconds
-|
-| Back to :ref:`debugger-execution-list`
+**gt[ime] <milliseconds>**
+
+Resumes execution. Control will not be returned to the debugger until a
+specified interval of emulated time has elapsed. The interval is
+specified in milliseconds.
+
+Example:
+
+``gtime #10000``
+ Resume execution for ten seconds of emulated time.
+
+Back to :ref:`debugger-execution-list`
- .. _debugger-command-next:
+.. _debugger-command-gvblank:
+
+gvblank
+-------
+
+**gv[blank]**
+
+Resumes execution. Control will not be returned to the debugger until a
+breakpoint or watchpoint is triggered, or until the beginning of the
+vertical blanking interval for an emulated screen.
+
+Example:
+
+``gv``
+ Resume execution until a breakpoint/watchpoint is triggered, or a
+ vertical blanking interval starts.
+
+Back to :ref:`debugger-execution-list`
+
+
+.. _debugger-command-next:
next
----
-| **n[ext]**
-|
-| The next command resumes execution and continues executing until the next time a different CPU is scheduled. Note that if you have used 'ignore' to ignore certain CPUs, you will not stop until a non-'ignore'd CPU is scheduled.
-|
-| Back to :ref:`debugger-execution-list`
+**n[ext]**
+
+Resumes execution until a different CPU is scheduled. Execution will
+not stop when a CPU is scheduled if it is ignored due to the use of
+:ref:`debugger-command-ignore` or :ref:`debugger-command-focus`.
+
+Example:
+
+``n``
+ Resume execution, stopping when a different CPU that is not ignored
+ is scheduled.
+
+Back to :ref:`debugger-execution-list`
- .. _debugger-command-focus:
+.. _debugger-command-focus:
focus
-----
-| **focus <cpu>**
-|
-| Sets the debugger focus exclusively to the given <cpu>. This is equivalent to specifying 'ignore' on all other CPUs.
-|
-| Example:
-|
-| focus 1
-|
-| Focus exclusively CPU #1 while ignoring all other CPUs when using the debugger.
-|
-| Back to :ref:`debugger-execution-list`
+**focus <CPU>**
+Focus exclusively on to the specified **<CPU>**, ignoring all other
+CPUs. The **<CPU>** argument can be a device tag or debugger CPU number
+(see :ref:`debugger-devicespec` for details). This is equivalent to
+using the :ref:`debugger-command-ignore` command to ignore all CPUs
+besides the specified CPU.
- .. _debugger-command-ignore:
+Examples:
+
+``focus 1``
+ Focus exclusively on the second CPU in the system (zero-based
+ index), ignoring all other CPUs.
+``focus audiopcb:melodycpu``
+ Focus exclusively on the CPU with the absolute tag path
+ ``:audiopcb:melodycpu``.
+
+Back to :ref:`debugger-execution-list`
+
+
+.. _debugger-command-ignore:
ignore
------
-| **ignore [<cpu>[,<cpu>[,...]]]**
-|
-| Ignores the specified <cpu> in the debugger. This means that you won't ever see execution on that CPU, nor will you be able to set breakpoints on that CPU. To undo this change use the 'observe' command. You can specify multiple <cpu>s in a single command. Note also that you are not permitted to ignore all CPUs; at least one must be active at all times.
-|
-| Examples:
-|
-| ignore 1
-|
-| Ignore CPU #1 when using the debugger.
-|
-| ignore 2,3,4
-|
-| Ignore CPU #2, #3 and #4 when using the debugger.
-|
-| ignore
-|
-| List the CPUs that are currently ignored.
-|
-| Back to :ref:`debugger-execution-list`
-
-
- .. _debugger-command-observe:
+**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).
+The debugger never shows execution for ignored CPUs, and breakpoints or
+watchpoints on ignored CPUs have no effect. If no CPUs are specified,
+currently ignored CPUs will be listed. Use the
+:ref:`debugger-command-observe` command to stop ignoring a CPU.
+
+Note that you cannot ignore all CPUs; at least CPU must be observed at
+all times.
+
+Examples:
+
+``ignore audiocpu``
+ Ignore the CPU with the absolute tag path ``:audiocpu`` when using
+ the debugger.
+``ignore 2,3,4``
+ Ignore the third, fourth and fifth CPUs in the system (zero-based
+ indices) when using the debugger.
+``ignore``
+ List the CPUs that are currently being ignored by the debugger.
+
+Back to :ref:`debugger-execution-list`
+
+
+.. _debugger-command-observe:
observe
-------
-| **observe [<cpu>[,<cpu>[,...]]]**
-|
-| Re-enables interaction with the specified <cpu> in the debugger. This command undoes the effects of the 'ignore' command. You can specify multiple <cpu>s in a single command.
-|
-| Examples:
-|
-| observe 1
-|
-| Stop ignoring CPU #1 when using the debugger.
-|
-| observe 2,3,4
-|
-| Stop ignoring CPU #2, #3 and #4 when using the debugger.
-|
-| observe
-|
-| List the CPUs that are currently observed.
-|
-| Back to :ref:`debugger-execution-list`
-
-
- .. _debugger-command-trace:
+**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`
+for details). This command reverses the effects of the
+:ref:`debugger-command-ignore` command. If no CPUs are specified,
+currently observed CPUs will be listed.
+
+Examples:
+
+``observe audiocpu``
+ Stop ignoring the CPU with the absolute tag path ``:audiocpu`` when
+ using the debugger.
+``observe 2,3,4``
+ Stop ignoring the third, fourth and fifth CPUs in the system
+ (zero-based indices) when using the debugger.
+``observe``
+ List the CPUs that are currently being observed by the debugger.
+
+Back to :ref:`debugger-execution-list`
+
+
+.. _debugger-command-trace:
trace
-----
-| **trace {<filename>|OFF}[,<cpu>[,[noloop|logerror][,<action>]]]**
-|
-| Starts or stops tracing of the execution of the specified <cpu>. If <cpu> is omitted, the currently active CPU is specified.
-|
-| When enabling tracing, specify the filename in the <filename> parameter. To disable tracing, substitute the keyword 'off' for <filename>.
-|
-| <detectloops> should be either true or false.
-|
-| If 'noloop' is omitted, the trace will have loops detected and condensed to a single line. If 'noloop' is specified, the trace will contain every opcode as it is executed.
-|
-| If 'logerror' is specified, logerror output will augment the trace. If you wish to log additional information on each trace, you can append an <action> parameter which is a command that is executed before each trace is logged. Generally, this is used to include a 'tracelog' command. 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 trace command itself.
-|
-|
-| Examples:
-|
-| trace joust.tr
-|
-| Begin tracing the currently active CPU, logging output to joust.tr.
-|
-| trace dribling.tr,0
-|
-| Begin tracing the execution of CPU #0, logging output to dribling.tr.
-|
-| trace starswep.tr,0,noloop
-|
-| Begin tracing the execution of CPU #0, logging output to starswep.tr, with loop detection disabled.
-|
-| trace starswep.tr,0,logerror
-|
-| Begin tracing the execution of CPU #0, logging output (along with logerror output) to starswep.tr.
-|
-| trace starswep.tr,0,logerror|noloop
-|
-| Begin tracing the execution of CPU #0, logging output (along with logerror output) to starswep.tr, with loop detection disabled.
-|
-| trace >>pigskin.tr
-|
-| Begin tracing the currently active CPU, appending log output to pigskin.tr.
-|
-| trace off,0
-|
-| Turn off tracing on CPU #0.
-|
-| trace asteroid.tr,0,,{tracelog "A=%02X ",a}
-|
-| Begin tracing the execution of CPU #0, logging output to asteroid.tr. Before each line, output A=<aval> to the tracelog.
-|
-| Back to :ref:`debugger-execution-list`
-
-
- .. _debugger-command-traceover:
+**trace {<filename>|off}[,<CPU>[,[noloop|logerror][,<action>]]]**
+
+Starts or stops tracing for execution of the specified **<CPU>**, or the
+currently visible CPU if no CPU is specified. To enable tracing,
+specify the trace log file name in the **<filename>** parameter. To
+disable tracing, use the keyword ``off`` for the **<filename>**
+parameter. If the **<filename>** argument begins with two right angle
+brackets (**>>**), it is treated as a directive to open the file for
+appending rather than overwriting.
+
+The optional third parameter is a flags field. The supported flags are
+``noloop`` and ``logerror``. Multiple flags must be separated by ``|``
+(pipe) characters. By default, loops are detected and condensed to a
+single line. If the ``noloop`` flag is specified, loops will not be
+detected and every instruction will be logged as executed. If the
+``logerror`` flag is specified, error log output will be included in the
+trace log.
+
+The optional **<action>** parameter is a debugger command to execute
+before each trace message is logged. Generally, this will include a
+:ref:`debugger-command-tracelog` or :ref:`debugger-command-tracesym`
+command to include additional information in the trace log. Note that
+you may need to surround the action within braces ``{ }`` to ensure
+commas and semicolons within the command are not interpreted in the
+context of the ``trace`` command itself.
+
+Examples:
+
+``trace joust.tr``
+ Begin tracing the execution of the currently visible CPU, logging
+ output to the file **joust.tr**.
+``trace dribling.tr,maincpu``
+ Begin tracing the execution of the CPU with the absolute tag path
+ ``:maincpu:``, logging output to the file **dribling.tr**.
+``trace starswep.tr,,noloop``
+ Begin tracing the execution of the currently visible CPU, logging
+ output to the file **starswep.tr**, with loop detection disabled.
+``trace starswep.tr,1,logerror``
+ Begin tracing the execution of the second CPU in the system
+ (zero-based index), logging output along with error log output to
+ the file **starswep.tr**.
+``trace starswep.tr,0,logerror|noloop``
+ Begin tracing the execution of the first CPU in the system
+ (zero-based index), logging output along with error log output to
+ the file **starswep.tr**, with loop detection disabled.
+``trace >>pigskin.tr``
+ Begin tracing execution of the currently visible CPU, appending log
+ output to the file **pigskin.tr**.
+``trace off,0``
+ Turn off tracing for the first CPU in the system (zero-based index).
+``trace asteroid.tr,,,{tracelog "A=%02X ",a}``
+ Begin tracing the execution of the currently visible CPU, logging
+ output to the file **asteroid.tr**. Before each line, output
+ **A=<aval>** to the trace log.
+
+Back to :ref:`debugger-execution-list`
+
+
+.. _debugger-command-traceover:
traceover
---------
-| **traceover {<filename>|OFF}[,<cpu>[,<detectloops>[,<action>]]]**
-|
-| Starts or stops tracing of the execution of the specified <cpu>.
-|
-| When tracing reaches a subroutine or call, tracing will skip over the subroutine. The same algorithm is used as is used in the step over command. This means that traceover will not work properly when calls are recursive or the return address is not immediately following the call instruction.
-|
-| <detectloops> should be either true or false. If <detectloops> is *true or omitted*, the trace will have loops detected and condensed to a single line. If it is false, the trace will contain every opcode as it is executed.
-| If <cpu> is omitted, the currently active CPU is specified.
-| When enabling tracing, specify the filename in the <filename> parameter.
-| To disable tracing, substitute the keyword 'off' for <filename>.
-| If you wish to log additional information on each trace, you can append an <action> parameter which is a command that is executed before each trace is logged. Generally, this is used to include a 'tracelog' command. 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 trace command itself.
-|
-|
-| Examples:
-|
-| traceover joust.tr
-|
-| Begin tracing the currently active CPU, logging output to joust.tr.
-|
-| traceover dribling.tr,0
-|
-| Begin tracing the execution of CPU #0, logging output to dribling.tr.
-|
-| traceover starswep.tr,0,false
-|
-| Begin tracing the execution of CPU #0, logging output to starswep.tr, with loop detection disabled.
-|
-| traceover off,0
-|
-| Turn off tracing on CPU #0.
-|
-| traceover asteroid.tr,0,true,{tracelog "A=%02X ",a}
-|
-| Begin tracing the execution of CPU #0, logging output to asteroid.tr. Before each line, output A=<aval> to the tracelog.
-|
-| Back to :ref:`debugger-execution-list`
-
-
- .. _debugger-command-traceflush:
+**traceover {<filename>|off}[,<CPU>[,[noloop|logerror][,<action>]]]**
+
+Starts or stops tracing for execution of the specified **<CPU>**, or the
+currently visible CPU if no CPU is specified. When a subroutine call is
+encountered, tracing will skip over the subroutine. The same algorithm
+is used as is used in the :ref:`step over <debugger-command-over>`
+command. It will not work properly with recursive functions, or if the
+return address does not immediately follow the call instruction.
+
+This command accepts the same parameters as the
+:ref:`debugger-command-trace` command. Please refer to the
+corresponding section for a detailed description of options and more
+examples.
+
+Examples:
+
+``traceover joust.tr``
+ Begin tracing the execution of the currently visible CPU, logging
+ output to the file **joust.tr**.
+``traceover dribling.tr,maincpu``
+ Begin tracing the execution of the CPU with the absolute tag path
+ ``:maincpu:``, logging output to the file **dribling.tr**.
+``traceover starswep.tr,,noloop``
+ Begin tracing the execution of the currently visible CPU, logging
+ output to the file **starswep.tr**, with loop detection disabled.
+``traceover off,0``
+ Turn off tracing for the first CPU in the system (zero-based index).
+``traceover asteroid.tr,,,{tracelog "A=%02X ",a}``
+ Begin tracing the execution of the currently visible CPU, logging
+ output to the file **asteroid.tr**. Before each line, output
+ **A=<aval>** to the trace log.
+
+Back to :ref:`debugger-execution-list`
+
+
+.. _debugger-command-traceflush:
traceflush
----------
-| **traceflush**
-|
-| Flushes all open trace files.
-|
-| Back to :ref:`debugger-execution-list`
+**traceflush**
+
+Flushes all open trace log files to disk.
+
+Example:
+
+``traceflush``
+ Flush trace log files.
+
+Back to :ref:`debugger-execution-list`
diff --git a/docs/source/debugger/expressions.rst b/docs/source/debugger/expressions.rst
deleted file mode 100644
index cc6ad27377a..00000000000
--- a/docs/source/debugger/expressions.rst
+++ /dev/null
@@ -1,77 +0,0 @@
-.. _debugger-expressions-list:
-
-Debugger Expressions Guide
-==========================
-
-
-Expressions can be used anywhere a numeric parameter is expected. The syntax for expressions is very close to standard C-style syntax with full operator ordering and parentheses. There are a few operators missing (notably the trinary ? : operator), and a few new ones (memory accessors). The table below lists all the operators in their order, highest precedence operators first.
-
-|
-| ( ) : standard parentheses
-| ++ -- : postfix increment/decrement
-| ++ -- ~ ! - + b@ w@ d@ q@ : prefix inc/dec, binary NOT, logical NOT, unary +/-, memory access
-| * / % : multiply, divide, modulus
-| + - : add, subtract
-| << >> : shift left/right
-| < <= > >= : less than, less than or equal, greater than, greater than or equal
-| == != : equal, not equal
-| & : binary AND
-| ^ : binary XOR
-| | : binary OR
-| && : logical AND
-| || : logical OR
-| = \*= /= %= += -= <<= >>= &= \|= ^= : assignment
-| , : separate terms, function parameters
-|
-|
-
-Numbers
--------
-
-Numbers are prefixed according to their bases:
-
-- Hexadecimal (base-16) numbers are prefixed with :code:`$` or :code:`0x`.
-
-- Decimal (base-10) numbers are prefixed with :code:`#`.
-
-- Octal (base-8) numbers are prefixed with :code:`0o`.
-
-- Binary (base-2) numbers are prefixed with :code:`0b`.
-
-- Unprefixed numbers are hexadecimal (base-16).
-
-Examples:
-
-- :code:`123` is 123 hexadecimal (291 decimal).
-
-- :code:`$123` is 123 hexadecimal (291 decimal).
-
-- :code:`0x123` is 123 hexadecimal (291 decimal).
-
-- :code:`#123` is 123 decimal.
-
-- :code:`0o123` is 123 octal (83 decimal).
-
-- :code:`0b1001` is 9 decimal.
-
-- :code:`0b123` is invalid.
-
-Differences from C Behaviors
-----------------------------
-
-
-- First, all math is performed on full 64-bit unsigned values, so things like **a < 0** won't work as expected.
-
-- Second, the logical operators **&&** and **||** do not have short-circuit properties -- both halves are always evaluated.
-
-- Finally, the new memory operators work like this:
-
- - **b!<addr>** refers to the byte at <addr> but does *NOT* suppress side effects such as reading a mailbox clearing the pending flag, or reading a FIFO removing an item.
-
- - **b@<addr>** refers to the byte at <addr> while suppressing side effects.
-
- - Similarly, **w@** and **w!** refer to a *word* in memory, **d@** and **d!** refer to a *dword* in memory, and **q@** and **q!** refer to a *qword* in memory.
-
- The memory operators can be used as both lvalues and rvalues, so you can write **b\@100 = ff** to store a byte in memory. By default these operators read from the program memory space, but you can override that by prefixing them with a 'd' or an 'i'.
-
- As such, **dw\@300** refers to data memory word at address 300 and **id\@400** refers to an I/O memory dword at address 400.
diff --git a/docs/source/debugger/general.rst b/docs/source/debugger/general.rst
index 752ec677841..c01ef20dea8 100644
--- a/docs/source/debugger/general.rst
+++ b/docs/source/debugger/general.rst
@@ -3,383 +3,585 @@
General Debugger Commands
=========================
+:ref:`debugger-command-help`
+ displays built-in help in the console
+:ref:`debugger-command-do`
+ evaluates the given expression
+:ref:`debugger-command-symlist`
+ lists registered symbols
+:ref:`debugger-command-softreset`
+ executes a soft reset
+:ref:`debugger-command-hardreset`
+ executes a hard reset
+:ref:`debugger-command-print`
+ prints one or more <item>s to the console
+:ref:`debugger-command-printf`
+ prints one or more <item>s to the console using <format>
+:ref:`debugger-command-logerror`
+ outputs one or more <item>s to the error.log
+:ref:`debugger-command-tracelog`
+ outputs one or more <item>s to the trace file using <format>
+:ref:`debugger-command-tracesym`
+ outputs one or more <item>s to the trace file
+:ref:`debugger-command-history`
+ displays recently visited PC addresses and opcodes
+:ref:`debugger-command-trackpc`
+ visually track visited opcodes
+:ref:`debugger-command-trackmem`
+ record which PC writes to each memory address
+:ref:`debugger-command-pcatmem`
+ query which PC wrote to a given memory address
+:ref:`debugger-command-rewind`
+ go back in time by loading the most recent rewind state
+:ref:`debugger-command-statesave`
+ save a state file for the emulated system
+:ref:`debugger-command-stateload`
+ load a state file for the emulated system
+:ref:`debugger-command-snap`
+ save a screen snapshot
+:ref:`debugger-command-source`
+ read commands from file and executes them one by one
+:ref:`debugger-command-time`
+ prints the current machine time to the console
+:ref:`debugger-command-quit`
+ exit the debugger and end the emulation session
+
+
+.. _debugger-command-help:
+
+help
+----
+
+**help [<topic>]**
+
+Displays built-in debugger help in the debugger console. If no
+**<topic>** is specified, top-level topics are listed. Most debugger
+commands have correspondingly named help topics.
+
+Examples:
-You can also type **help <command>** for further details on each command in the MAME Debugger interface.
-
-| :ref:`debugger-command-do` -- evaluates the given expression
-| :ref:`debugger-command-symlist` -- lists registered symbols
-| :ref:`debugger-command-softreset` -- executes a soft reset
-| :ref:`debugger-command-hardreset` -- executes a hard reset
-| :ref:`debugger-command-print` -- prints one or more <item>s to the console
-| :ref:`debugger-command-printf` -- prints one or more <item>s to the console using <format>
-| :ref:`debugger-command-logerror` -- outputs one or more <item>s to the error.log
-| :ref:`debugger-command-tracelog` -- outputs one or more <item>s to the trace file using <format>
-| :ref:`debugger-command-tracesym` -- outputs one or more <item>s to the trace file
-| history -- outputs a brief history of visited opcodes (**to fix: help missing for this command**)
-| :ref:`debugger-command-trackpc` -- visually track visited opcodes [boolean to turn on and off, for the given CPU, clear]
-| :ref:`debugger-command-trackmem` -- record which PC writes to each memory address [boolean to turn on and off, clear]
-| :ref:`debugger-command-pcatmem` -- query which PC wrote to a given memory address for the current CPU
-| :ref:`debugger-command-rewind` -- go back in time by loading the most recent rewind state
-| :ref:`debugger-command-statesave` -- save a state file for the current driver
-| :ref:`debugger-command-stateload` -- load a state file for the current driver
-| :ref:`debugger-command-snap` -- save a screen snapshot.
-| :ref:`debugger-command-source` -- reads commands from <filename> and executes them one by one
-| :ref:`debugger-command-quit` -- exits MAME and the debugger
-
-
- .. _debugger-command-do:
+``help``
+ Lists top-level help topics.
+``help expressions``
+ Displays built-in help for debugger expression syntax.
+``help wpiset``
+ Displays built-in help for the
+ :ref:`wpiset <debugger-command-wpset>` command.
+
+Back to :ref:`debugger-general-list`
+
+
+.. _debugger-command-do:
do
--
-| **do <expression>**
-|
-| The do command simply evaluates the given <expression>. This is typically used to set or modify variables.
-|
-| Examples:
-|
-| do pc = 0
-|
-| Sets the register 'pc' to 0.
-|
-| Back to :ref:`debugger-general-list`
+**do <expression>**
+
+The **do** command simply evaluates the supplied expression. This is
+often used to set or modify device state variable (e.g. CPU registers),
+or to write to memory. See :ref:`debugger-express` for details about
+expression syntax.
- .. _debugger-command-symlist:
+Examples:
+
+``do pc = 0``
+ Sets the register **pc** to 0.
+
+Back to :ref:`debugger-general-list`
+
+
+.. _debugger-command-symlist:
symlist
-------
-| **symlist [<cpu>]**
-|
-| Lists registered symbols. If <cpu> is not specified, then symbols in the global symbol table are displayed; otherwise, the symbols for <cpu>'s specific CPU are displayed. Symbols are listed alphabetically. Read-only symbols are flagged with an asterisk.
-|
-| Examples:
-|
-| symlist
-|
-| Displays the global symbol table.
-|
-| symlist 2
-|
-| Displays the symbols specific to CPU #2.
-|
-| Back to :ref:`debugger-general-list`
-
-
- .. _debugger-command-softreset:
+**symlist [<cpu>]**
+
+Lists registered symbols and their values. If **<cpu>** is not
+specified, symbols in the global symbol table are displayed; otherwise,
+symbols specific to the device **<cpu>** are displayed. Symbols are
+listed alphabetically. Read-only symbols are noted. See
+:ref:`debugger-devicespec` for details on how to specify a CPU.
+
+Examples:
+
+``symlist``
+ Displays the global symbol table.
+``symlist 2``
+ Displays the symbols for the third CPU in the system (zero-based
+ index).
+``symlist audiocpu``
+ Displays symbols for the CPU with the absolute tag ``:audiocpu``.
+
+Back to :ref:`debugger-general-list`
+
+
+.. _debugger-command-softreset:
softreset
---------
-| **softreset**
-|
-| Executes a soft reset.
-|
-| Examples:
-|
-| softreset
-|
-| Executes a soft reset.
-|
-| Back to :ref:`debugger-general-list`
+**softreset**
+
+Executes a soft reset. This calls the reset member functions of all the
+devices in the system (by default, pressing **F3** during emulation has
+the same effect).
+
+Examples:
+
+``softreset``
+ Executes a soft reset.
+
+Back to :ref:`debugger-general-list`
- .. _debugger-command-hardreset:
+.. _debugger-command-hardreset:
hardreset
---------
-| **hardreset**
-|
-| Executes a hard reset.
-|
-| Examples:
-|
-| hardreset
-|
-| Executes a hard reset.
-|
-| Back to :ref:`debugger-general-list`
+**hardreset**
+Executes a hard reset. This tears down the emulation session and starts
+another session with the same system and options (by default, pressing
+**Shift+F3** during emulation has the same effect). Note that this will
+lose history in the debugger console and error log.
- .. _debugger-command-print:
+Examples:
+
+``hardreset``
+ Executes a hard reset.
+
+Back to :ref:`debugger-general-list`
+
+
+.. _debugger-command-print:
print
-----
-| **print <item>[,...]**
-|
-| The print command prints the results of one or more expressions to the debugger console as hexadecimal values.
-|
-| Examples:
-|
-| print pc
-|
-| Prints the value of 'pc' to the console as a hex number.
-|
-| print a,b,a+b
-|
-| Prints a, b, and the value of a+b to the console as hex numbers.
-|
-| Back to :ref:`debugger-general-list`
-
-
- .. _debugger-command-printf:
+**print <item>[,…]**
+
+The **print** command prints the results of one or more expressions to
+the debugger console as hexadecimal numbers.
+
+Examples:
+
+``print pc``
+ Prints the value of the **pc** register the console as a hex number.
+``print a,b,a+b``
+ Prints **a**, **b**, and the value of **a+b** to the console as hex
+ numbers.
+
+Back to :ref:`debugger-general-list`
+
+
+.. _debugger-command-printf:
printf
------
-| **printf <format>[,<item>[,...]]**
-|
-| The printf command performs a C-style printf to the debugger console. Only a very limited set of formatting options are available:
-|
-| %[0][<n>]d -- prints <item> as a decimal value with optional digit count and zero-fill
-| %[0][<n>]x -- prints <item> as a hexadecimal value with optional digit count and zero-fill
-|
-| All remaining formatting options are ignored. Use %% together to output a % character. Multiple lines can be printed by embedding a \\n in the text.
-|
-| Examples:
-|
-| printf "PC=%04X",pc
-|
-| Prints PC=<pcval> where <pcval> is displayed in hexadecimal with 4 digits with zero-fill.
-|
-| printf "A=%d, B=%d\\nC=%d",a,b,a+b
-|
-| Prints A=<aval>, B=<bval> on one line, and C=<a+bval> on a second line.
-|
-| Back to :ref:`debugger-general-list`
-
-
- .. _debugger-command-logerror:
+**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
+available:
+
+%c
+ Prints the corresponding argument as an 8-bit character.
+%[-][0][<n>]d
+ Prints the corresponding argument as a decimal number with optional
+ left justification, zero fill and minimum field width.
+%[-][0][<n>]o
+ Prints the corresponding argument as an octal number with optional
+ left justification, zero fill and minimum field width.
+%[-][0][<n>]x
+ Prints the corresponding argument as a lowercase hexadecimal number
+ with optional left justification, zero fill and minimum field width.
+%[-][0][<n>]X
+ Prints the corresponding argument as an uppercase hexadecimal number
+ with optional left justification, zero fill and minimum field width.
+%[-][<n>][.[<n>]]s
+ Prints a null-terminated string of 8-bit characters from the address
+ and address space given by the corresponding argument, with optional
+ left justification, minimum and maximum field widths.
+\%%
+ Prints a literal percent symbol.
+\\n
+ Prints a line break.
+**\\\\**
+ Prints a literal backslash.
+
+All other format specifiers are ignored.
+
+Examples:
+
+``printf "PC=%04X",pc``
+ Prints ``PC=<pcval>`` where **<pcval>** is the hexadecimal value of
+ the **pc** register with a minimum of four digits and zero fill.
+``printf "A=%d, B=%d\\nC=%d",a,b,a+b``
+ Prints ``A=<aval>, B=<bval>`` on one line, and ``C=<a+bval>`` on a
+ second line.
+
+Back to :ref:`debugger-general-list`
+
+
+.. _debugger-command-logerror:
logerror
--------
-| **logerror <format>[,<item>[,...]]**
-|
-| The logerror command performs a C-style printf to the error log. Only a very limited set of formatting options are available:
-|
-| %[0][<n>]d -- logs <item> as a decimal value with optional digit count and zero-fill
-| %[0][<n>]x -- logs <item> as a hexadecimal value with optional digit count and zero-fill
-|
-| All remaining formatting options are ignored. Use %% together to output a % character. Multiple lines can be printed by embedding a \\n in the text.
-|
-| Examples:
-|
-| logerror "PC=%04X",pc
-|
-| Logs PC=<pcval> where <pcval> is displayed in hexadecimal with 4 digits with zero-fill.
-|
-| logerror "A=%d, B=%d\\nC=%d",a,b,a+b
-|
-| Logs A=<aval>, B=<bval> on one line, and C=<a+bval> on a second line.
-|
-| Back to :ref:`debugger-general-list`
-
-
- .. _debugger-command-tracelog:
+**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
+supported format specifiers and escape sequences.
+
+Examples:
+
+``logerror "PC=%04X",pc``
+ Logs ``PC=<pcval>`` where **<pcval>** is the hexadecimal value of
+ the **pc** register with a minimum of four digits and zero fill.
+``logerror "A=%d, B=%d\\nC=%d",a,b,a+b``
+ Logs ``A=<aval>, B=<bval>`` on one line, and ``C=<a+bval>`` on a
+ second line.
+
+Back to :ref:`debugger-general-list`
+
+
+.. _debugger-command-tracelog:
tracelog
--------
-| **tracelog <format>[,<item>[,...]]**
-|
-| The tracelog command performs a C-style printf and routes the output to the currently open trace file (see the 'trace' command for details). If no file is currently open, tracelog does nothing. Only a very limited set of formatting options are available. See the :ref:`debugger-command-printf` help for details.
-|
-| Examples:
-|
-| tracelog "PC=%04X",pc
-|
-| Outputs PC=<pcval> where <pcval> is displayed in hexadecimal with 4 digits with zero-fill.
-|
-| printf "A=%d, B=%d\\nC=%d",a,b,a+b
-|
-| Outputs A=<aval>, B=<bval> on one line, and C=<a+bval> on a second line.
-|
-| Back to :ref:`debugger-general-list`
-
-
- .. _debugger-command-tracesym:
+**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
+is open, this command has no effect. See :ref:`debugger-command-printf`
+for details about the limited set of supported format specifiers and
+escape sequences.
+
+Examples:
+
+``tracelog "PC=%04X",pc``
+ Outputs ``PC=<pcval>`` where **<pcval>** is the hexadecimal value of
+ the **pc** register with a minimum of four digits and zero fill if a
+ trace log file is open.
+``tracelog "A=%d, B=%d\\nC=%d",a,b,a+b``
+ Outputs ``A=<aval>, B=<bval>`` on one line, and ``C=<a+bval>`` on a
+ second line if a trace log file is open.
+
+Back to :ref:`debugger-general-list`
+
+
+.. _debugger-command-tracesym:
tracesym
--------
-| **tracesym <item>[,...]**
-|
-| The tracesym command prints the specified symbols and routes the output to the currently open trace file (see the 'trace' command for details). If no file is currently open, tracesym does nothing.
-|
-| Examples:
-|
-| tracelog pc
-|
-| Outputs PC=<pcval> where <pcval> is displayed in the default format.
-|
-| Back to :ref:`debugger-general-list`
+**tracesym <item>[,…]**
+
+Prints the specified symbols to the currently open trace file (see
+:ref:`debugger-command-trace` for more information). If no trace file
+is open, this command has no effect.
+
+Examples:
+
+``tracesym pc``
+ Outputs ``PC=<pcval>`` where **<pcval>** is the value of the **pc**
+ register in its default format if a trace log file is open.
+
+Back to :ref:`debugger-general-list`
+
+
+.. _debugger-command-history:
+history
+-------
+
+**history [<CPU>[,<length>]]**
+
+Displays recently visited PC addresses, and disassembly of the
+instructions at those addresses. If present, the first argument selects
+the CPU (see :ref:`debugger-devicespec` for details); if no CPU is
+specified, the visible CPU is assumed. The second argument, if present,
+limits the maximum number of addresses shown. Addresses are shown in
+order from least to most recently visited.
+
+Examples:
- .. _debugger-command-trackpc:
+``history ,5``
+ Displays up to five most recently visited PC addresses and
+ instructions for the visible CPU.
+``history 3``
+ Displays recently visited PC addresses and instructions for the
+ fourth CPU in the system (zero-based index).
+``history audiocpu,1``
+ Displays the most recently visited PC address and instruction for
+ the CPU with the absolute tag ``:audiocpu``.
+
+
+.. _debugger-command-trackpc:
trackpc
-------
-| **trackpc [<bool>,<cpu>,<bool>]**
-|
-| The trackpc command displays which program counters have already been visited in all disassembler windows. The first boolean argument toggles the process on and off. The second argument is a CPU selector; if no CPU is specified, the current CPU is automatically selected. The third argument is a boolean denoting if the existing data should be cleared or not.
-|
-| Examples:
-|
-| trackpc 1
-|
-| Begin tracking the current CPU's pc.
-|
-| trackpc 1, 0, 1
-|
-| Continue tracking pc on CPU 0, but clear existing track info.
-|
-| Back to :ref:`debugger-general-list`
-
-
- .. _debugger-command-trackmem:
+**trackpc [<enable>[,<CPU>[,<clear>]]]**
+
+Turns visited PC address tracking for disassembly views on or off.
+Instructions at addresses visited while tracking is on are highlighted
+in debugger disassembly views. The first argument is a Boolean
+specifying whether tracking should be turned on or off (defaults to on).
+The second argument specifies the CPU to enable or disable tracking for
+(see :ref:`debugger-devicespec` for details); if no CPU is specified,
+the visible CPU is assumed. The third argument is a Boolean specifying
+whether existing data should be cleared (defaults to false).
+
+Examples:
+
+``trackpc 1``
+ Begin or tracking the current CPU’s PC.
+``trackpc 1,0,1``
+ Begin or continue tracking PC on the first CPU in the system
+ (zero-based index), but clear the history tracked so far.
+
+Back to :ref:`debugger-general-list`
+
+
+.. _debugger-command-trackmem:
trackmem
--------
-| **trackmem [<bool>,<cpu>,<bool>]**
-|
-| The trackmem command logs the PC at each time a memory address is written to. The first boolean argument toggles the process on and off. The second argument is a CPU selector; if no CPU is specified, the current CPU is automatically selected. The third argument is a boolean denoting if the existing data should be cleared or not. Please refer to the pcatmem command for information on how to retrieve this data. Also, right clicking in a memory window will display the logged PC for the given address.
-|
-| Examples:
-|
-| trackmem
-|
-| Begin tracking the current CPU's pc.
-|
-| trackmem 1, 0, 1
-|
-| Continue tracking memory writes on CPU 0, but clear existing track info.
-|
-| Back to :ref:`debugger-general-list`
-
-
- .. _debugger-command-pcatmem:
+**trackmem [<enable>,[<CPU>,[<clear>]]]**
+
+Enables or disables logging the PC address each time a memory address is
+written to. The first argument is a Boolean specifying whether tracking
+should be enabled or disabled (defaults to enabled). The second
+argument specifies the CPU to enable or disable tracking for (see
+:ref:`debugger-devicespec` for details); if no CPU is specified, the
+visible CPU is assumed. The third argument is a Boolean specifying
+whether existing data should be cleared (defaults to false).
+
+Use :ref:`debugger-command-pcatmem` to retrieve this data.
+Right-clicking a debugger memory view will also display the logged PC
+value for the given address in some configurations.
+
+Examples:
+
+``trackmem``
+ Begin or continue tracking memory writes for the visible CPU.
+``trackmem 1,0,1``
+ Begin or continue tracking memory writes for the first CPU in the
+ system (zero-based index), but clear existing tracking data.
+
+Back to :ref:`debugger-general-list`
+
+
+.. _debugger-command-pcatmem:
pcatmem
-------
-| **pcatmem(p/d/i) <address>[,<cpu>]**
-|
-| **pcatmemp <address>[,<cpu>]** -- query which PC wrote to a given program memory address for the current CPU
-| **pcatmemd <address>[,<cpu>]** -- query which PC wrote to a given data memory address for the current CPU
-| **pcatmemi <address>[,<cpu>]** -- query which PC wrote to a given I/O memory address for the current CPU (you can also query this info by right clicking in a memory window)
-|
-| The pcatmem command returns which PC wrote to a given memory address for the current CPU. The first argument is the requested address. The second argument is a CPU selector; if no CPU is specified, the current CPU is automatically selected. Right clicking in a memory window will also display the logged PC for the given address.
-|
-| Examples:
-|
-| pcatmem 400000
-|
-| Print which PC wrote this CPU's memory location 0x400000.
-|
-| Back to :ref:`debugger-general-list`
-
-
- .. _debugger-command-rewind:
+**pcatmem[{d|i|o}] <address>[:<space>]**
+
+Returns the PC value at the time the specified address was most recently
+written to. The argument is the requested address, optionally followed
+by a colon and a CPU and/or address space (see
+:ref:`debugger-devicespec` for details). The optional **d**, **i** or
+**o** suffix controls the default address space for the command.
+
+Tracking must be enabled for the data this command uses to be recorded
+(see :ref:`debugger-command-trackmem`). Right-clicking a debugger
+memory view will also display the logged PC value for the given address
+in some configurations.
+
+Examples:
+
+``pcatmem 400000``
+ Print the PC value when location 400000 in the visible CPU’s program
+ space was most recently written.
+``pcatmem 3bc:io``
+ Print the PC value when location 3bc in the visible CPU’s ``io``
+ space was most recently written.
+``pcatmem 1400:audiocpu``
+ Print the PC value when location 1400 in the CPU ``:audiocpu``’s
+ program space was most recently written.
+
+Back to :ref:`debugger-general-list`
+
+
+.. _debugger-command-rewind:
rewind
------
-| **rewind[rw]**
-|
-| The rewind command loads the most recent RAM-based state. Rewind states, when enabled, are saved when "step", "over", or "out" command gets executed, storing the machine state as of the moment before actually stepping. Consecutively loading rewind states can work like reverse execution. Depending on which steps forward were taken previously, the behavior can be similar to GDB's "reverse-stepi" or "reverse-next". All output for this command is currently echoed into the running machine window. Previous memory and PC tracking statistics are cleared, actual reverse execution does not occur.
-|
-| Back to :ref:`debugger-general-list`
+**rewind**
+
+Loads the most recent RAM-based saved state. When enabled, rewind
+states are saved when :ref:`debugger-command-step`,
+:ref:`debugger-command-over` and :ref:`debugger-command-out` commands
+are used, storing the machine state as of the moment before stepping.
+May be abbreviated to ``rw``.
+
+Consecutively loading rewind states can work like reverse execution.
+Depending on which steps forward were taken previously, the behavior can
+be similar to GDB's **reverse-stepi** and **reverse-next** commands.
+All output for this command is currently echoed into the running machine
+window.
+
+Previous memory and PC tracking statistics are cleared. Actual reverse
+execution does not occur.
+Examples:
- .. _debugger-command-statesave:
+``rewind``
+ Load the previous RAM-based save state.
+``rw``
+ Abbreviated form of the command.
+
+Back to :ref:`debugger-general-list`
+
+
+.. _debugger-command-statesave:
statesave
---------
-| **statesave[ss] <filename>**
-|
-| The statesave command creates a save state at this exact moment in time. The given state file gets written to the standard state directory (sta), and gets .sta added to it - no file extension necessary. All output for this command is currently echoed into the running machine window.
-|
-| Examples:
-|
-| statesave foo
-|
-| Writes file 'foo.sta' in the default state save directory.
-|
-| Back to :ref:`debugger-general-list`
+**statesave <filename>**
+
+Creates a save state at the current moment in emulated time. The state
+file is written to the configured save state directory (see the
+:ref:`state_directory <mame-commandline-statedirectory>` option), and
+the **.sta** extension is automatically appended to the specified file
+name. May be abbreviates to ``ss``.
+
+All output from this command is currently echoed into the running machine
+window.
+
+Examples:
+
+``statesave foo``
+ Saves the emulated machine state to the file **foo.sta** in the
+ configured save state directory.
+``ss bar``
+ Abbreviated form of the command – saves the emulated machine state
+ to **bar.sta**.
+Back to :ref:`debugger-general-list`
- .. _debugger-command-stateload:
+
+.. _debugger-command-stateload:
stateload
---------
-| **stateload[sl] <filename>**
-|
-| The stateload command retrieves a save state from disk. The given state file gets read from the standard state directory (sta), and gets .sta added to it - no file extension necessary. All output for this command is currently echoed into the running machine window. Previous memory and PC tracking statistics are cleared.
-|
-| Examples:
-|
-| stateload foo
-|
-| Reads file 'foo.sta' from the default state save directory.
-|
-| Back to :ref:`debugger-general-list`
+**stateload <filename>**
+
+Restores a saved state file from disk. The specified state file is read
+from the configured save state directory (see the
+:ref:`state_directory <mame-commandline-statedirectory>` option), and the
+**.sta** extension is automatically appended to the specified file name.
+May be abbreviated to ``sl``.
+
+All output for this command is currently echoed into the running machine
+window. Previous memory and PC tracking statistics are cleared.
+
+Examples:
+``stateload foo``
+ Loads state from file **foo.sta** to the configured save state
+ directory.
+``sl bar``
+ Abbreviated form of the command – loads the file **bar.sta**.
- .. _debugger-command-snap:
+Back to :ref:`debugger-general-list`
+
+
+.. _debugger-command-snap:
snap
----
-| **snap [[<filename>], <scrnum>]**
-|
-| The snap command takes a snapshot of the current video display and saves it to the configured snapshot directory. If <filename> is specified explicitly, a single screenshot for <scrnum> is saved under the requested filename. If <filename> is omitted, all screens are saved using the same default rules as the "save snapshot" key in MAME proper.
-|
-| Examples:
-|
-| snap
-|
-| Takes a snapshot of the current video screen and saves to the next non-conflicting filename in the configured snapshot directory.
-|
-| snap shinobi
-|
-| Takes a snapshot of the current video screen and saves it as 'shinobi.png' in the configured snapshot directory.
-|
-| Back to :ref:`debugger-general-list`
-
-
- .. _debugger-command-source:
+**snap [<filename>[,<scrnum>]]**
+
+Takes a snapshot of the emulated video display and saves it to the
+configured snapshot directory (see the
+:ref:`snapshot_directory <mame-commandline-snapshotdirectory>` option).
+If a file name is specified, a single screenshot for the specified
+screen is saved using the specified filename (or the first emulated
+screen in the system if a screen is not specified). If a file name is
+not specified, the configured snapshot view and file name pattern are
+used (see the :ref:`snapview <mame-commandline-snapview>` and
+:ref:`snapname <mame-commandline-snapname>` options).
+
+If a file name is specified, the **.png** extension is automatically
+appended. The screen number is specified as a zero-based index, as
+seen in the names of automatically-generated single-screen views in
+MAME’s video options menus.
+
+Examples:
+
+``snap``
+ Takes a snapshot using the configured snapshot view and file name
+ options.
+``snap shinobi``
+ Takes a snapshot of the first emulated video screen and saves it as
+ **shinobi.png** in the configured snapshot directory.
+
+Back to :ref:`debugger-general-list`
+
+
+.. _debugger-command-source:
source
------
-| **source <filename>**
-|
-| The source command reads in a set of debugger commands from a file and executes them one by one, similar to a batch file.
-|
-| Examples:
-|
-| source break_and_trace.cmd
-|
-| Reads in debugger commands from break_and_trace.cmd and executes them.
-|
-| Back to :ref:`debugger-general-list`
+**source <filename>**
+
+Reads the specified file in text mode and executes each line as a
+debugger command. This is similar to running a shell script or batch
+file.
+Examples:
- .. _debugger-command-quit:
+``source break_and_trace.cmd``
+ Reads and executes debugger commands from **break_and_trace.cmd**.
+
+Back to :ref:`debugger-general-list`
+
+
+.. _debugger-command-time:
+
+time
+----
+
+Prints the total elapsed emulated time to the debugger console.
+
+Examples:
+
+``time``
+ Prints the elapsed emulated time.
+
+Back to :ref:`debugger-general-list`
+
+
+.. _debugger-command-quit:
quit
----
-| **quit**
-|
-| The quit command exits MAME immediately.
-|
-| Back to :ref:`debugger-general-list`
+**quit**
+
+Closes the debugger and ends the emulation session immediately. Either
+exits MAME or returns to the system selection menu, depending on whether
+the system was specified on the command line when starting MAME.
+
+Examples:
+
+``quit``
+ Exits the emulation session immediately.
+Back to :ref:`debugger-general-list`
diff --git a/docs/source/debugger/image.rst b/docs/source/debugger/image.rst
index d52c3ed3f43..f02388062a7 100644
--- a/docs/source/debugger/image.rst
+++ b/docs/source/debugger/image.rst
@@ -1,63 +1,80 @@
.. _debugger-image-list:
-Image Debugger Commands
-=======================
+Media Image Debugger Commands
+=============================
+:ref:`debugger-command-images`
+ lists all image devices and mounted media images
+:ref:`debugger-command-mount`
+ mounts a media image file to an image device
+:ref:`debugger-command-unmount`
+ unmounts the media image from a device
-You can also type **help <command>** for further details on each command in the MAME Debugger interface.
-| :ref:`debugger-command-images` -- lists all image devices and mounted files
-| :ref:`debugger-command-mount` -- mounts file to named device
-| :ref:`debugger-command-unmount` -- unmounts file from named device
-
-
- .. _debugger-command-images:
+.. _debugger-command-images:
images
------
-| **images**
-|
-| Used to display list of available image devices.
-|
-| Examples:
-|
-| images
-|
-| Show list of devices and mounted files for current driver.
+**images**
+
+Lists the instance names for media images devices in the system and the
+currently mounted media images, if any. Brief instance names, as
+allowed for command line media options, are listed. Mounted software
+list items are displayed as the list name, software item short name, and
+part name, separated by colons; other mounted images are displayed as
+file names.
+
+Example:
+``images``
+ Lists image device instance names and mounted media.
- .. _debugger-command-mount:
+Back to :ref:`debugger-image-list`
+
+
+.. _debugger-command-mount:
mount
-----
-| **mount <device>,<filename>**
-|
-| Mount <filename> to image <device>.
-|
-| <filename> can be softlist item or full path to file.
-|
-| Examples:
-|
-| mount cart,aladdin
-|
-| Mounts softlist item aladdin on cart device.
+**mount <instance>,<filename>**
+
+Mounts a file on a media device. The device may be specified by its
+instance name or brief instance name, as allowed for command line media
+options.
+Some media devices allow software list items to be mounted using this
+command by supplying the short name of the software list item in place
+of a filename for the **<filename>** parameter.
- .. _debugger-command-unmount:
+Examples:
+
+``mount flop1,os1xutls.td0``
+ Mount the file **os1xutls.td0** on the media device with instance
+ name **flop1**.
+``mount cart,10yard``
+ Mount the software list item with short name **10yard** on the media
+ device with instance name **cart**.
+
+Back to :ref:`debugger-image-list`
+
+
+.. _debugger-command-unmount:
unmount
-------
-| **unmount <device>**
-|
-| Unmounts file from image <device>.
-|
-| Examples:
-|
-| unmount cart
-|
-| Unmounts any file mounted on device named cart.
+**unmount <instance>**
+
+Unmounts the mounted media image (if any) from a device. The device may
+be specified by its instance name or brief instance name, as allowed for
+command line media options.
+
+Examples:
+unmount cart
+ Unmounts any media image mounted on the device with instance name
+ **cart**.
+Back to :ref:`debugger-image-list`
diff --git a/docs/source/debugger/index.rst b/docs/source/debugger/index.rst
index 3d89733a37f..2947d0253ac 100644
--- a/docs/source/debugger/index.rst
+++ b/docs/source/debugger/index.rst
@@ -1,18 +1,435 @@
+.. _debugger:
+
MAME Debugger
--------------------
+=============
+
+.. contents:: :local:
+
+
+.. _debugger-intro:
+
+Introduction
+------------
+
+MAME includes an interactive low-level debugger that targets 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 investigating how software works.
+
+Use the ``-debug`` command line option to start MAME with the debugger
+activated. By default, pressing the backtick/tilde (**~**) during
+emulation breaks into the debugger (this can be changed by reassigning
+the **Break in Debugger** input).
+
+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.
+
-This section covers the built-in MAME debugger
+.. _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
- expressions
+ :titlesonly:
+
+ general
+ memory
+ execution
+ breakpoint
+ watchpoint
+ registerpoints
+ exceptionpoint
+ 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-express:
+
+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.
+
+
+.. _debugger-express-num:
+
+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 1001 binary (9 decimal)
+* ``0b123`` is invalid
+
+
+.. _debugger-express-bool:
+
+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.
+
+
+.. _debugger-express-mem:
+
+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
+
+Suppressing side effects of a read access yields the value reading from
+address would, with no further effects. For example reading a mailbox
+with side effects disabled will not clear the pending flag, and reading
+a FIFO with side effects disabled will not remove an item.
+
+For write accesses, suppressing side effects doesn’t change behaviour in
+most cases – you want to see the effects of writing to a location.
+However, there are some exceptions where it is useful to separate
+multiple effects of a write access. For example:
+
+* Some registers need to be written in sequence to avoid race
+ conditions. The debugger can issue multiple writes at the same point
+ in emulated time, so these race conditions can be avoided trivially.
+ For example writing to the MC68HC05 output compare register high byte
+ (OCRH) inhibits compare until the output compare register low byte
+ (OCRL) is written to prevent race conditions. Since the debugger can
+ write to both locations at the same instant from the emulated
+ machine’s point of view, the race condition is not usually relevant.
+ It’s more error-prone if you can accidentally set hidden state when
+ all you really want to do is change the value, so writing to OCRH with
+ side effects suppressed does not inhibit compare, it just changes the
+ value in the output compare register.
+* Writing to some registers has multiple effects that may be useful to
+ separate for debugging purposes. Using the MC68HC05 as an example
+ again, writing to OCRL changes the value in the output compare
+ register, and also clears the output compare flag (OCF) and enables
+ compare if it was previously inhibited by writing to OCRH. Writing to
+ OCRL with side effects disabled just changes the value in the register
+ without clearing OCF or enabling compare, since it’s useful for
+ debugging purposes. Writing to OCRL with side effects enabled has the
+ additional 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 2
+ (I/O)
+* ``3`` or ``l3`` specifies a logical address defaulting to space 3
+ (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 2 (I/O)
+* ``p3`` specifies a physical address defaulting to space 3 (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 current
+ CPU while suppressing side effects
+``b!<addr>``
+ Refers to the byte at **<addr>** in the program space of the current
+ 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 current
+ 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
+ current 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 current 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 current CPU while
+ suppressing side effects
+``id@400``
+ Refers to the double word at 400 in the I/O space of the current CPU
+ while suppressing side effects
+``ppd!<addr>``
+ Refers to the double word at physical address **<addr>** in the
+ program space of the current CPU while not suppressing side effects
+``rw@<addr>``
+ Refers to the word at address **<addr>** in the program space of the
+ current CPU using direct read/write pointer access
+
+If we want to access an address space of a device other than the current
+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``
+``..md@202``
+ Refers to the double word at address 202 in the memory region with
+ the same tag path as the current CPU.
+
+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.
+
+
+.. _debugger-express-func:
+
+Functions
+~~~~~~~~~
+
+The debugger supports a number of useful utility functions in expressions.
+
+min(<a>, <b>)
+ Returns the lesser of the two arguments.
+max(<a>, <b>)
+ Returns the greater of the two arguments.
+if(<cond>, <trueval>, <falseval>)
+ Returns **<trueval>** if **<cond>** is true (non-zero), or
+ **<falseval>** otherwise. Note that the expressions for
+ **<trueval>** and **<falseval>** are both evaluated irrespective of
+ whether **<cond>** is true or false.
+abs(<x>)
+ Reinterprets the argument as a 64-bit signed integer and returns the
+ absolute value.
+bit(<x>, <n>[, <w>])
+ Extracts and right-aligns a bit field **<w>** bits wide from **<x>**
+ with least significant bit position **<n>**, counting from the
+ least significant bit. If **<w>** is omitted, a single bit is
+ extracted.
+s8(<x>)
+ Sign-extends the argument from 8 bits to 64 bits (overwrites bits 8
+ through 63, inclusive, with the value of bit 7, counting from the
+ least significant bit).
+s16(<x>)
+ Sign-extends the argument from 16 bits to 64 bits (overwrites bits
+ 16 through 63, inclusive, with the value of bit 15, counting from
+ the least significant bit).
+s32(<x>)
+ Sign-extends the argument from 32 bits to 64 bits (overwrites bits
+ 32 through 63, inclusive, with the value of bit 31, counting from
+ the least significant bit).
diff --git a/docs/source/debugger/memory.rst b/docs/source/debugger/memory.rst
index 7f9414e085f..dfb5914b5a9 100644
--- a/docs/source/debugger/memory.rst
+++ b/docs/source/debugger/memory.rst
@@ -3,165 +3,405 @@
Memory Debugger Commands
========================
+:ref:`debugger-command-dasm`
+ disassemble code to a file
+:ref:`debugger-command-find`
+ search emulated memory for data
+:ref:`debugger-command-fill`
+ fill emulated memory with specified pattern
+:ref:`debugger-command-dump`
+ dump emulated memory to a file as text
+:ref:`debugger-command-strdump`
+ dump delimited strings from emulated memory to a file
+:ref:`debugger-command-save`
+ save binary data from emulated memory to a file
+:ref:`debugger-command-saver`
+ save binary data from a memory region to a file
+:ref:`debugger-command-load`
+ load binary data from a file to emulated memory
+:ref:`debugger-command-loadr`
+ load binary data from a file to a memory region
+:ref:`debugger-command-map`
+ map a logical address to the corresponding physical address and
+ handler
+:ref:`debugger-command-memdump`
+ dump current memory maps to a file
-You can also type **help <command>** for further details on each command in the MAME Debugger interface.
-| :ref:`debugger-command-dasm` -- disassemble to the given file
-| :ref:`debugger-command-find` -- search program memory, data memory, or I/O memory for data
-| :ref:`debugger-command-dump` -- dump program memory, data memory, or I/O memory as text
-| :ref:`debugger-command-save` -- save binary program, data, or I/O memory to the given file
-| :ref:`debugger-command-load` -- load binary program memory, data memory, or I/O memory from the given file
-| :ref:`debugger-command-map` -- map logical program, data, or I/O address to physical address and bank
+.. _debugger-command-dasm:
+dasm
+----
+**dasm <filename>,<address>,<length>[,<opcodes>[,<CPU>]]**
+Disassembles program memory to the file specified by the **<filename>**
+parameter. The **<address>** parameter specifies the address to start
+disassembling from, and the **<length>** parameter specifies how much
+memory to disassemble. The range **<address>** through
+**<address>+<length>-1**, inclusive, will be disassembled to the file.
+By default, raw opcode data is output with each line. The optional
+**<opcodes>** parameter is a Boolean that enables disables this feature.
+By default, program memory for the visible CPU is disassembled. To
+disassemble program memory for a different CPU, specify it using the
+optional fifth parameter (see :ref:`debugger-devicespec` for details).
- .. _debugger-command-dasm:
+Examples:
-dasm
-----
+``dasm venture.asm,0,10000``
+ Disassembles addresses 0-ffff for the visible CPU, including raw
+ opcode data, to the file **venture.asm**.
+``dasm harddriv.asm,3000,1000,0,2``
+ Disassembles addresses 3000-3fff for the third CPU in the system
+ (zero-based index), without raw opcode data, to the file
+ **harddriv.asm**.
+
+Back to :ref:`debugger-memory-list`
-| **dasm <filename>,<address>,<length>[,<opcodes>[,<cpu>]]**
-|
-| The dasm command disassembles program memory to the file specified in the <filename> parameter. <address> indicates the address of the start of disassembly, and <length> indicates how much memory to disassemble. The range <address> through <address>+<length>-1 inclusive will be output to the file. By default, the raw opcode data is output with each line. The optional <opcodes> parameter can be used to enable (1) or disable (0) this feature. Finally, you can disassemble code from another CPU by specifying the <cpu> parameter.
-|
-| Examples:
-|
-| dasm venture.asm,0,10000
-|
-| Disassembles addresses 0-ffff in the current CPU, including raw opcode data, to the file 'venture.asm'.
-|
-| dasm harddriv.asm,3000,1000,0,2
-|
-| Disassembles addresses 3000-3fff from CPU #2, with no raw opcode data, to the file 'harddriv.asm'.
-|
-| Back to :ref:`debugger-memory-list`
-
-
- .. _debugger-command-find:
+
+.. _debugger-command-find:
find
----
-| **f[ind][{d|i}] <address>,<length>[,<data>[,...]]**
-|
-| The **find**/**findd**/**findi** commands search through memory for the specified sequence of data. 'find' will search program space memory, while 'findd' will search data space memory and 'findi' will search I/O space memory. <address> indicates the address to begin searching, and <length> indicates how much memory to search. <data> can either be a quoted string or a numeric value or expression or the wildcard character '?'. Strings by default imply a byte-sized search; non-string data is searched by default in the native word size of the CPU. To override the search size for non-strings, you can prefix the value with b. to force byte- sized search, w. for word-sized search, d. for dword-sized, and q. for qword-sized. Overrides are remembered, so if you want to search for a series of words, you need only to prefix the first value with a w. Note also that you can intermix sizes in order to perform more complex searches. The entire range <address> through <address>+<length>-1 inclusive will be searched for the sequence, and all occurrences will be displayed.
-|
-| Examples:
-|
-| find 0,10000,"HIGH SCORE",0
-|
-| Searches the address range 0-ffff in the current CPU for the string "HIGH SCORE" followed by a 0 byte.
-|
-| findd 3000,1000,w.abcd,4567
-|
-| Searches the data memory address range 3000-3fff for the word-sized value abcd followed by the word-sized value 4567.
-|
-| find 0,8000,"AAR",d.0,"BEN",w.0
-|
-| Searches the address range 0000-7fff for the string "AAR" followed by a dword-sized 0 followed by the string "BEN", followed by a word-sized 0.
-|
-| Back to :ref:`debugger-memory-list`
-
-
- .. _debugger-command-dump:
+**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
+followed by a device and/or address space (see
+:ref:`debugger-devicespec` for details); the **<length>** specifies
+how much memory to search. If an address space is not specified, the
+command suffix sets the address space: ``find`` defaults to the first
+address space exposed by the device, ``findd`` defaults to the space
+with index 1 (data), ``findi`` default to the space with index 2 (I/O),
+and ``findo`` defaults to the space with index 3 (opcodes).
+
+The **<data>** can either be a quoted string, a numeric value or
+expression, or the wildcard character ``?``. By default, strings imply
+a byte-sized search; by default non-string data is searched using the
+native word size of the address space. To override the search size for
+non-string data, you can prefix values with ``b.`` to force byte-sized
+search, ``w.`` for word-sized search, ``d.`` for double word-sized
+search, and ``q.`` for quadruple word-sized search. Overrides propagate
+to subsequent values, so if you want to search for a sequence of words,
+you need only prefix the first value with ``w.``. Also note that you
+can intermix sizes to perform more complex searches.
+
+The entire range **<address>** through **<address>+<length>-1**,
+inclusive, will be searched for the sequence, and all occurrences will
+be displayed.
+
+Examples:
+
+``find 0,10000,"HIGH SCORE",0``
+ Searches the address range 0-ffff in the program space of the
+ visible CPU for the string “HIGH SCORE” followed by a 0 byte.
+``find 300:tms9918a,100,w.abcd,4567``
+ Searches the address range 300-3ff in the first address space
+ exposed by the device with the absolute tag ``:tms9918a`` for the
+ word-sized value abcd followed by the word-sized value 4567.
+``find 0,8000,"AAR",d.0,"BEN",w.0``
+ Searches the address range 0000-7fff for the string “AAR” followed
+ by a dword-sized 0 followed by the string “BEN”, followed by a
+ word-sized 0.
+
+Back to :ref:`debugger-memory-list`
+
+
+.. _debugger-command-fill:
+
+fill
+----
+
+**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
+followed by a device and/or address space (see
+:ref:`debugger-devicespec` for details); the **<length>** specifies how
+much memory to fill. If an address space is not specified, the command
+suffix sets the address space: ``fill`` defaults to the first
+address space exposed by the device, ``filld`` defaults to the space
+with index 1 (data), ``filli`` default to the space with index 2 (I/O),
+and ``fillo`` defaults to the space with index 3 (opcodes).
+
+The **<data>** can either be a quoted string, or a numeric value or
+expression. By default, non-string data is written using the native
+word size of the address space. To override the data size for non-string
+data, you can prefix values with ``b.`` to force byte-sized fill, ``w.``
+for word-sized fill, ``d.`` for double word-sized fill, and ``q.`` for
+quadruple word-sized fill. Overrides propagate to subsequent values, so
+if you want to fill with a series of words, you need only prefix the
+first value with ``w.``. Also note that you can intermix sizes to
+perform more complex fills. The fill operation may be truncated if a
+page fault occurs or if part of the sequence or string would fall beyond
+**<address>+<length>-1**.
+
+Back to :ref:`debugger-memory-list`
+
+
+.. _debugger-command-dump:
dump
----
-| **dump[{d|i}] <filename>,<address>,<length>[,<size>[,<ascii>[,<cpu>]]]**
-|
-| The **dump**/**dumpd**/**dumpi** commands dump memory to the text file specified in the <filename> parameter.
-| 'dump' will dump program space memory, while 'dumpd' will dump data space memory and 'dumpi' will dump I/O space memory.
-| <address> indicates the address of the start of dumping, and <length> indicates how much memory to dump. The range <address> through <address>+<length>-1 inclusive will be output to the file.
-| By default, the data will be output in byte format, unless the underlying address space is word/dword/qword-only. You can override this by specifying the <size> parameter, which can be used to group the data in 1, 2, 4 or 8-byte chunks.
-| The optional <ascii> parameter can be used to enable (1) or disable (0) the output of ASCII characters to the right of each line; by default, this is enabled.
-| Finally, you can dump memory from another CPU by specifying the <cpu> parameter.
-|
-|
-| Examples:
-|
-| dump venture.dmp,0,10000
-|
-| Dumps addresses 0-ffff in the current CPU in 1-byte chunks, including ASCII data, to the file 'venture.dmp'.
-|
-| dumpd harddriv.dmp,3000,1000,4,0,3
-|
-| Dumps data memory addresses 3000-3fff from CPU #3 in 4-byte chunks, with no ASCII data, to the file 'harddriv.dmp'.
-|
-| Back to :ref:`debugger-memory-list`
-
-
- .. _debugger-command-save:
+**dump[{d|i|o}] <filename>,<address>[:<space>],<length>[,<group>[,<ascii>[,<rowsize>]]]**
+
+Dump memory to the text file specified by the **<filename>** parameter.
+The **<address>** specifies the address to start dumping from,
+optionally followed by a device and/or address space (see
+:ref:`debugger-devicespec` for details); the **<length>** specifies how
+much memory to dump. If an address space is not specified, the command
+suffix sets the address space: ``dump`` defaults to the first
+address space exposed by the device, ``dumpd`` defaults to the space
+with index 1 (data), ``dumpi`` default to the space with index 2 (I/O),
+and ``dumpo`` defaults to the space with index 3 (opcodes).
+
+The range **<address>** through **<address>+<length>-1**, inclusive,
+will be output to the file. By default, the data will be output using
+the native word size of the address space. You can override this by
+specifying the **<group>** parameter, which can be used to group the
+data in 1-, 2-, 4- or 8-byte chunks. The optional **<ascii>** parameter
+is a Boolean value used to enable or disable output of ASCII characters
+on the right of each line (enabled by default). The optional
+**<rowsize>** parameter specifies the amount of data on each line in
+address units (defaults to 16 bytes).
+
+Examples:
+
+``dump venture.dmp,0,10000``
+ Dumps addresses 0-ffff from the program space of the visible CPU in
+ 1-byte chunks, including ASCII data, to the file **venture.dmp**.
+``dumpd harddriv.dmp,3000:3,1000,4,0``
+ Dumps data memory addresses 3000-3fff from the fourth CPU in the
+ system (zero-based index) in 4-byte chunks, without ASCII data, to
+ the file **harddriv.dmp**.
+``dump vram.dmp,0:sms_vdp:videoram,4000,1,false,8``
+ Dumps ``videoram`` space addresses 0000-3fff from the device with
+ the absolute tag path ``:sms_vdp`` in 1-byte chunks, without ASCII
+ data, with 8 bytes per line, to the file **vram.dmp**.
+
+Back to :ref:`debugger-memory-list`
+
+
+.. _debugger-command-strdump:
+
+strdump
+-------
+
+**strdump[{d|i|o}] <filename>,<address>[:<space>],<length>[,<term>]**
+
+Dump memory to the text file specified by the **<filename>** parameter.
+The **<address>** specifies the address to start dumping from,
+optionally followed by a device and/or address space (see
+:ref:`debugger-devicespec` for details); the **<length>** specifies how
+much memory to dump. If an address space is not specified, the command
+suffix sets the address space: ``strdump`` defaults to the first
+address space exposed by the device, ``strdumpd`` defaults to the space
+with index 1 (data), ``strdumpi`` default to the space with index 2
+(I/O), and ``strdumpo`` defaults to the space with index 3 (opcodes).
+
+By default, the data will be interpreted as a series of NUL-terminated
+(ASCIIZ) strings, the dump will have one string per line, and C-style
+escapes sequences will be used for bytes that do not represent printable
+ASCII characters. The optional **<term>** parameter can be used to
+specify a different string terminator character.
+
+Back to :ref:`debugger-memory-list`
+
+
+.. _debugger-command-save:
save
----
-| **save[{d|i}] <filename>,<address>,<length>[,<cpu>]**
-|
-| The **save**/**saved**/**savei** commands save raw memory to the binary file specified in the <filename> parameter.
-| 'save' will save program space memory, while 'saved' will save data space memory and 'savei' will save I/O space memory.
-| <address> indicates the address of the start of saving, and <length> indicates how much memory to save. The range <address> through <address>+<length>-1 inclusive will be output to the file.
-| You can also save memory from another CPU by specifying the <cpu> parameter.
-|
-|
-| Examples:
-|
-| save venture.bin,0,10000
-|
-| Saves addresses 0-ffff in the current CPU to the binary file 'venture.bin'.
-|
-| saved harddriv.bin,3000,1000,3
-|
-| Saves data memory addresses 3000-3fff from CPU #3 to the binary file 'harddriv.bin'.
-|
-| Back to :ref:`debugger-memory-list`
-
-
- .. _debugger-command-load:
+**save[{d|i|o}] <filename>,<address>[:<space>],<length>**
+
+Save raw memory to the binary file specified by the **<filename>**
+parameter. The **<address>** specifies the address to start saving
+from, optionally followed by a device and/or address space (see
+:ref:`debugger-devicespec` for details); the **<length>** specifies how
+much memory to save. If an address space is not specified, the command
+suffix sets the address space: ``save`` defaults to the first address
+space exposed by the device, ``saved`` defaults to the space with index
+1 (data), ``savei`` default to the space with index 2 (I/O), and
+``saveo`` defaults to the space with index 3 (opcodes).
+
+The range **<address>** through **<address>+<length>-1**, inclusive,
+will be output to the file.
+
+Examples:
+
+``save venture.bin,0,10000``
+ Saves addresses 0-ffff from the program space of the current CPU to
+ the binary file **venture.bin**
+``saved harddriv.bin,3000:3,1000``
+ Saves data memory addresses 3000-3fff from the fourth CPU in the
+ system (zero-based index) to the binary file **harddriv.bin**.
+``save vram.bin,0:sms_vdp:videoram,4000``
+ Saves ``videoram`` space addresses 0000-3fff from the device with
+ the absolute tag path ``:sms_vdp`` to the binary file **vram.bin**.
+
+Back to :ref:`debugger-memory-list`
+
+
+.. _debugger-command-saver:
+
+saver
+-----
+
+**saver <filename>,<address>,<length>,<region>**
+
+Save raw content of memory region specified by the **<region>**
+parameter to the binary file specified by the **<filename>** parameter.
+Regions tags follow the same rules as device tags (see
+:ref:`debugger-devicespec`). The **<address>** specifies the address to
+start saving from, and the **<length>** specifies how much memory to
+save. The range **<address>** through **<address>+<length>-1**,
+inclusive, will be output to the file.
+
+Examples:
+
+``saver data.bin,200,100,:monitor``
+ Saves ``:monitor`` region addresses 200-2ff to the binary file
+ **data.bin**.
+``saver cpurom.bin,1000,400,.``
+ Saves addresses 1000-13ff from the memory region with the same tag
+ as the visible CPU to the binary file **cpurom.bin**.
+
+Back to :ref:`debugger-memory-list`
+
+
+.. _debugger-command-load:
load
----
-| **load[{d|i}] <filename>,<address>[,<length>,<cpu>]**
-|
-| The **load**/**loadd**/**loadi** commands load raw memory from the binary file specified in the <filename> parameter.
-| 'load' will load program space memory, while 'loadd' will load data space memory and 'loadi' will load I/O space memory.
-| <address> indicates the address of the start of saving, and <length> indicates how much memory to load. The range <address> through <address>+<length>-1 inclusive will be read in from the file.
-| If you specify <length> = 0 or a length greater than the total length of the file it will load the entire contents of the file and no more.
-| You can also load memory from another CPU by specifying the <cpu> parameter.
-|
-| NOTE: This will only actually write memory that is possible to overwrite in the Memory Window
-|
-|
-| Examples:
-|
-| load venture.bin,0,10000
-|
-| Loads addresses 0-ffff in the current CPU from the binary file 'venture.bin'.
-|
-| loadd harddriv.bin,3000,1000,3
-|
-| Loads data memory addresses 3000-3fff from CPU #3 from the binary file 'harddriv.bin'.
-|
-| Back to :ref:`debugger-memory-list`
-
-
- .. _debugger-command-map:
+**load[{d|i|o}] <filename>,<address>[:<space>][,<length>]**
+
+Load raw memory from the binary file specified by the **<filename>**
+parameter. The **<address>** specifies the address to start loading to,
+optionally followed by a device and/or address space (see
+:ref:`debugger-devicespec` for details); the **<length>** specifies how
+much memory to load. If an address space is not specified, the command
+suffix sets the address space: ``load`` defaults to the first address
+space exposed by the device, ``loadd`` defaults to the space with index
+1 (data), ``loadi`` default to the space with index 2 (I/O), and
+``loado`` defaults to the space with index 3 (opcodes).
+
+The range **<address>** through **<address>+<length>-1**, inclusive,
+will be read in from the file. If the **<length>** is omitted, if it is
+zero, or if it is greater than the total length of the file, the entire
+contents of the file will be loaded but no more.
+
+Note that this has the same effect as writing to the address space from
+a debugger memory view, or using the ``b@``, ``w@``, ``d@`` or ``q@``
+memory accessors in debugger expressions. Read-only memory will not be
+overwritten, and writing to I/O addresses may have effects beyond
+setting register values.
+
+Examples:
+
+``load venture.bin,0,10000``
+ Loads addresses 0-ffff in the program space for the visible CPU from
+ the binary file **venture.bin**.
+``loadd harddriv.bin,3000,1000,3``
+ Loads data memory addresses 3000-3fff in the program space for the
+ fourth CPU in the system (zero-based index) from the binary file
+ **harddriv.bin**.
+``load vram.bin,0:sms_vdp:videoram``
+ Loads the ``videoram`` space for the device with the absolute tag
+ path ``:sms_vdp`` starting at address 0000 with the entire content
+ of the binary file **vram.bin**.
+
+Back to :ref:`debugger-memory-list`
+
+
+.. _debugger-command-loadr:
+
+loadr
+-----
+
+**loadr <filename>,<address>,<length>,<region>**
+
+Load memory in the memory region specified by the **<region>** with raw
+data from the binary file specified by the **<filename>** parameter.
+Regions tags follow the same rules as device tags (see
+:ref:`debugger-devicespec`). The **<address>** specifies the address to
+start loading to, and the
+**<length>** specifies how much memory to load. The range **<address>**
+through **<address>+<length>-1**, inclusive, will be read in from the
+file. If the **<length>** is zero, or is greater than the total length
+of the file, the entire contents of the file will be loaded but no more.
+
+Examples:
+
+``loadr data.bin,200,100,:monitor``
+ Loads ``:monitor`` region addresses 200-2ff from the binary file
+ **data.bin**.
+``loadr cpurom.bin,1000,400,.``
+ Loads addresses 1000-13ff in the memory region with the same tag as
+ the visible CPU from the binary file **cpurom.bin**.
+
+Back to :ref:`debugger-memory-list`
+
+
+.. _debugger-command-map:
map
---
-| **map[{d|i}] <address>**
-|
-| The map/mapd/mapi commands map a logical address in memory to the correct physical address, as well as specifying the bank.
-| 'map' will map program space memory, while 'mapd' will map data space memory and 'mapi' will map I/O space memory.
-|
-| Example:
-|
-| map 152d0
-|
-| Gives physical address and bank for logical address 152d0 in program memory
-|
-| Back to :ref:`debugger-memory-list`
+**map[{d|i|o}] <address>[:<space>]**
+
+Map a logical memory address to the corresponding physical address, as
+well as reporting the handler name. The address may optionally be
+followed by a colon and device and/or address space (see
+:ref:`debugger-devicespec` for details). If an address space is not
+specified, the command suffix sets the address space: ``map`` defaults
+to the first address space exposed by the device, ``mapd`` defaults to
+the space with index 1 (data), ``mapi`` default to the space with index
+2 (I/O), and ``mapo`` defaults to the space with index 3 (opcodes).
+
+Examples:
+
+``map 152d0``
+ Gives the physical address and handler name for logical address
+ 152d0 in program memory for the visible CPU.
+``map 107:sms_vdp``
+ Gives the physical address and handler name for logical address 107
+ in the first address space for the device with the absolute tag path
+ ``:sms_vdp``.
+
+Back to :ref:`debugger-memory-list`
+
+
+.. _debugger-command-memdump:
+
+memdump
+-------
+
+**memdump [<filename>,[<device>]]**
+
+Dumps the current memory maps to the file specified by **<filename>**,
+or **memdump.log** if omitted. If **<device>** is specified (see
+:ref:`debugger-devicespec`), only memory maps for the part of the device
+tree rooted at this device will be dumped.
+
+Examples:
+
+``memdump mylog.log``
+ Dumps memory maps for all devices in the system to the file
+ **mylog.log**.
+``memdump``
+ Dumps memory maps for all devices in the system to the file
+ **memdump.log**.
+``memdump audiomaps.log,audiopcb``
+ Dumps memory maps for the device with the absolute tag path
+ ``:audiopcb`` and all its child devices to the file
+ **audiomaps.log**.
+``memdump mylog.log,1``
+ Dumps memory maps for the second CPU device in the system
+ (zero-based index) and all its child devices to the file
+ **mylog.log**.
+Back to :ref:`debugger-memory-list`
diff --git a/docs/source/debugger/registerpoints.rst b/docs/source/debugger/registerpoints.rst
index 355a31c29eb..ebd531f219d 100644
--- a/docs/source/debugger/registerpoints.rst
+++ b/docs/source/debugger/registerpoints.rst
@@ -1,120 +1,150 @@
.. _debugger-registerpoints-list:
-Registerpoints Debugger Commands
+Registerpoint Debugger Commands
================================
+: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
-You can also type **help <command>** for further details on each command in the MAME Debugger interface.
+Registerpoints evaluate an expression each time a CPU executes an
+instruction and halt execution and activate the debugger if the result
+is true (non-zero).
-| :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
-
-
- .. _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`
-
-
- .. _debugger-command-rpclear:
+**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:
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`
-
-
- .. _debugger-command-rpdisable:
+**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:
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`
-
-
- .. _debugger-command-rpenable:
+**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:
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`
-
-
- .. _debugger-command-rplist:
+**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:
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. 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`
diff --git a/docs/source/debugger/watchpoint.rst b/docs/source/debugger/watchpoint.rst
index f80fa152197..0f4bd12902f 100644
--- a/docs/source/debugger/watchpoint.rst
+++ b/docs/source/debugger/watchpoint.rst
@@ -3,126 +3,176 @@
Watchpoint Debugger Commands
============================
+:ref:`debugger-command-wpset`
+ sets memory access watchpoints
+:ref:`debugger-command-wpclear`
+ clears watchpoints
+:ref:`debugger-command-wpdisable`
+ disables watchpoints
+:ref:`debugger-command-wpenable`
+ enables enables watchpoints
+:ref:`debugger-command-wplist`
+ lists watchpoints
-You can also type **help <command>** for further details on each command in the MAME Debugger interface.
+Watchpoints halt execution and activate the debugger when a CPU accesses
+a location in a particular memory range.
-| :ref:`debugger-command-wpset` -- sets program, data, or I/O space watchpoint
-| :ref:`debugger-command-wpclear` -- clears a given watchpoint or all if no <wpnum> specified
-| :ref:`debugger-command-wpdisable` -- disables a given watchpoint or all if no <wpnum> specified
-| :ref:`debugger-command-wpenable` -- enables a given watchpoint or all if no <wpnum> specified
-| :ref:`debugger-command-wplist` -- lists all the watchpoints
- .. _debugger-command-wpset:
+.. _debugger-command-wpset:
wpset
-----
-| **wp[{d|i}][set] <address>,<length>,<type>[,<condition>[,<action>]]**
-|
-| Sets a new watchpoint starting at the specified <address> and extending for <length>. The inclusive range of the watchpoint is <address> through <address> + <length> - 1.
-| The 'wpset' command sets a watchpoint on program memory; the 'wpdset' command sets a watchpoint on data memory; and the 'wpiset' sets a watchpoint on I/O memory.
-| The <type> parameter specifies which sort of accesses to trap on. It can be one of three values: 'r' for a read watchpoint 'w' for a write watchpoint, and 'rw' for a read/write watchpoint.
-|
-| The optional <condition> parameter lets you specify an expression that will be evaluated each time the watchpoint is hit. If the result of the expression is true (non-zero), the watchpoint will actually halt execution; otherwise, execution will continue with no notification.
-| The optional <action> parameter provides a command that is executed whenever the watchpoint is hit and the <condition> is true. Note that you may need to embed the action within braces { } in order to prevent commas and semicolons from being interpreted as applying to the wpset command itself.
-| Each watchpoint that is set is assigned an index which can be used in other watchpoint commands to reference this watchpoint.
-| In order to help <condition> expressions, two variables are available. For all watchpoints, the variable 'wpaddr' is set to the address that actually triggered the watchpoint. For write watchpoints, the variable 'wpdata' is set to the data that is being written.
-|
-| Examples:
-|
-| wp 1234,6,rw
-|
-| Set a watchpoint that will halt execution whenever a read or write occurs in the address range 1234-1239 inclusive.
-|
-| wp 23456,a,w,wpdata == 1
-|
-| Set a watchpoint that will halt execution whenever a write occurs in the address range 23456-2345f AND the data written is equal to 1.
-|
-| wp 3456,20,r,1,{printf "Read @ %08X\\n",wpaddr; g}
-|
-| Set a watchpoint that will halt execution whenever a read occurs in the address range 3456-3475. When this happens, print Read @ <wpaddr> and continue executing.
-|
-| temp0 = 0; wp 45678,1,w,wpdata==f0,{temp0++; g}
-|
-| Set a watchpoint that will halt execution whenever a write occurs to the address 45678 AND the value being written is equal to f0. When that happens, increment the variable temp0 and resume execution.
-|
-| Back to :ref:`debugger-watchpoints-list`
-
-
- .. _debugger-command-wpclear:
+**wp[{d|i|o}][set] <address>[:<space>],<length>,<type>[,<condition>[,<action>]]**
+
+Sets a new watchpoint starting at the specified **<address>** and
+extending for **<length>**. The range of the watchpoint is
+**<address>** through **<address>+<length>-1**, inclusive. The
+**<address>** may optionally be followed by a CPU and/or address space
+(see :ref:`debugger-devicespec` for details). If an address space is
+not specified, the command suffix sets the address space: ``wpset``
+defaults to the first address space exposed by the CPU, ``wpdset``
+defaults to the space with index 1 (data), ``wpiset`` defaults to the
+space with index 2 (I/O), and ``wposet`` defaults to the space with
+index 3 (opcodes). The **<type>** parameter specifies the access types
+to trap on – it can be one of three values: ``r`` for read accesses,
+``w`` for write accesses, or ``rw`` for both read and write accesses.
+
+The optional **<condition>** parameter lets you specify an expression
+that will be evaluated each time the watchpoint is triggered. If the
+result of the expression is true (non-zero), the watchpoint will halt
+execution; otherwise, execution will continue with no notification. The
+optional **<action>** parameter provides a command to be executed
+whenever the watchpoint is triggered and the **<condition>** is true.
+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 ``wpset`` command itself.
+
+Each watchpoint that is set is assigned a numeric index which can be
+used to refer to it in other watchpoint commands. Watchpoint indices
+are unique throughout a session.
+
+To make **<condition>** expressions more useful, two variables are
+available: for all watchpoints, the variable **wpaddr** is set to the
+access address that triggered the watchpoint; for write watchpoints, the
+variable **wpdata** is set to the data being written.
+
+Examples:
+
+``wp 1234,6,rw``
+ Set a watchpoint for the visible CPU that will halt execution
+ whenever a read or write to the first address space occurs in the
+ address range 1234-1239, inclusive.
+``wp 23456:data,a,w,wpdata == 1``
+ Set a watchpoint for the visible CPU that will halt execution
+ whenever a write to the ``data`` space occurs in the address range
+ 23456-2345f and the data written is equal to 1.
+``wp 3456:maincpu,20,r,1,{ printf "Read @ %08X\n",wpaddr ; g }``
+ Set a watchpoint for the CPU with the absolute tag path ``:maincpu``
+ that will halt execution whenever a read from the first address
+ space occurs in the address range 3456-3475. When this happens,
+ print **Read @ <wpaddr>** to the debugger console and resume
+ execution.
+``temp0 = 0 ; wp 45678,1,w,wpdata==f0,{ temp0++ ; g }``
+ Set a watchpoint for the visible CPU that will halt execution
+ whenever a write to the first address space occurs at address 45678
+ where the value being written is equal to f0. When this happens,
+ increment the variable **temp0** and resume execution.
+
+Back to :ref:`debugger-watchpoints-list`
+
+
+.. _debugger-command-wpclear:
wpclear
-------
-| **wpclear [<wpnum>]**
-|
-| The wpclear command clears a watchpoint. If <wpnum> is specified, only the requested watchpoint is cleared, otherwise all watchpoints are cleared.
-|
-| Examples:
-|
-| wpclear 3
-|
-| Clear watchpoint index 3.
-|
-| wpclear
-|
-| Clear all watchpoints.
-|
-| Back to :ref:`debugger-watchpoints-list`
-
-
- .. _debugger-command-wpdisable:
+**wpclear [<wpnum>[,…]]**
+
+Clear watchpoints. If **<wpnum>** is specified, the watchpoints
+referred to will be cleared. If **<wpnum>** is not specified, all
+watchpoints will be cleared.
+
+Examples:
+
+``wpclear 3``
+ Clear the watchpoint with index 3.
+``wpclear``
+ Clear all watchpoints.
+
+Back to :ref:`debugger-watchpoints-list`
+
+
+.. _debugger-command-wpdisable:
wpdisable
---------
-| **wpdisable [<wpnum>]**
-|
-| 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 watchpoint does not delete it, it just temporarily marks the watchpoint as inactive.
-|
-| Examples:
-|
-| wpdisable 3
-|
-| Disable watchpoint index 3.
-|
-| wpdisable
-|
-| Disable all watchpoints.
-|
-| Back to :ref:`debugger-watchpoints-list`
-
-
- .. _debugger-command-wpenable:
+**wpdisable [<wpnum>[,…]]**
+
+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
+marks the watchpoint as inactive. Disabled watchpoints will not cause
+execution to halt, their associated condition expressions will not be
+evaluated, and their associated commands will not be executed.
+
+Examples:
+
+``wpdisable 3``
+ Disable the watchpoint with index 3.
+``wpdisable``
+ Disable all watchpoints.
+
+Back to :ref:`debugger-watchpoints-list`
+
+
+.. _debugger-command-wpenable:
wpenable
--------
-| **wpenable [<wpnum>]**
-|
-| The wpenable command enables a watchpoint. If <wpnum> is specified, only the requested watchpoint is enabled, otherwise all watchpoints are enabled.
-|
-| Examples:
-|
-| wpenable 3
-|
-| Enable watchpoint index 3.
-|
-| wpenable
-|
-| Enable all watchpoints.
-|
-| Back to :ref:`debugger-watchpoints-list`
-
-
- .. _debugger-command-wplist:
+**wpenable [<wpnum>[,…]]**
+
+Enable watchpoints. If **<wpnum>** is specified, the watchpoints
+referred to will be enabled. If **<wpnum>** is not specified, all
+watchpoints will be enabled.
+
+Examples:
+
+``wpenable 3``
+ Enable the watchpoint with index 3.
+``wpenable``
+ Enable all watchpoints.
+
+Back to :ref:`debugger-watchpoints-list`
+
+
+.. _debugger-command-wplist:
wplist
------
-| **wplist**
-|
-| The wplist command lists all the current watchpoints, along with their index and any conditions or actions attached to them.
-|
-| Back to :ref:`debugger-watchpoints-list`
+**wplist [<CPU>]**
+
+List current watchpoints, along with their indices and any associated
+conditions or actions. If no **<CPU>** is specified, watchpoints for
+all CPUs in the system will be listed; if a **<CPU>** is specified, only
+watchpoints 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:
+
+``wplist``
+ List all watchpoints.
+``wplist .``
+ List all watchpoints for the visible CPU.
+``wplist maincpu``
+ List all watchpoints for the CPU with the absolute tag path
+ ``:maincpu``.
+
+Back to :ref:`debugger-watchpoints-list`
diff --git a/docs/source/healthwarning.rst b/docs/source/healthwarning.rst
new file mode 100644
index 00000000000..6ca5929b662
--- /dev/null
+++ b/docs/source/healthwarning.rst
@@ -0,0 +1,29 @@
+Health Warnings
+===============
+
+Epilepsy Warning
+----------------
+
+A very small percentage of individuals may experience epileptic seizures when
+exposed to certain light patterns or flashing lights. Exposure to certain
+patterns or backgrounds on a television screen or computer monitor, or while
+playing video games may induce an epileptic seizure in these individuals.
+
+Certain conditions may induce previously undetected epileptic symptoms even in
+persons who have no history of prior seizures or epilepsy. These conditions can
+include emulation accuracy or inaccuracy, computer performance at the time of
+running MAME, video card drivers, your monitor, and a lot of other factors.
+If you, or anyone in your family, has an epileptic condition, consult your
+physician prior to using MAME.
+
+If you experience any of the following while using MAME, **IMMEDIATELY**
+discontinue use and consult your physician before resuming use of MAME.
+
+* Dizziness
+* Altered vision
+* Eye or muscle twitches
+* Loss of awareness
+* Disorientation
+* Any involuntary movement
+* Convulsions
+
diff --git a/docs/source/images/MAMElogo.svg b/docs/source/images/MAMElogo.svg
index b45bc7ebdb3..a728ab92a31 100644
--- a/docs/source/images/MAMElogo.svg
+++ b/docs/source/images/MAMElogo.svg
@@ -1,68 +1,25 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<svg
- xmlns:dc="http://purl.org/dc/elements/1.1/"
- xmlns:cc="http://creativecommons.org/ns#"
- xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
- xmlns:xlink="http://www.w3.org/1999/xlink"
- id="svg4563"
+ id="svg-mamelogo"
version="1.1"
- viewBox="0 0 321.26581 91.07238"
- height="91.07238mm"
- width="321.26581mm">
- <defs
- id="defs4557">
- <linearGradient
- id="left-dark">
- <stop
- style="stop-color:#00274f;stop-opacity:1"
- offset="0"
- id="stop5213" />
- <stop
- style="stop-color:#68cafb;stop-opacity:1"
- offset="1"
- id="stop5215" />
+ viewBox="0 0 1214 344"
+ height="344px"
+ width="1214px">
+ <defs>
+ <linearGradient id="left-dark" x1="0" x2="1" y1="0" y2="0">
+ <stop id="left-dark-0" offset="0" stop-color="#00274f" />
+ <stop id="left-dark-1" offset="1" stop-color="#68cafb" />
</linearGradient>
- <linearGradient
- gradientUnits="userSpaceOnUse"
- y2="299.328"
- x2="11"
- y1="299.328"
- x1="1213.16"
- id="right-dark">
- <stop
- id="stop4"
- stop-color="#68cafb"
- offset="0" />
- <stop
- id="stop6"
- stop-color="#00274f"
- offset="1" />
+ <linearGradient id="right-dark" x1="0" x2="1" y1="0" y2="0">
+ <stop id="right-dark-0" offset="0" stop-color="#68cafb" />
+ <stop id="right-dark-1" offset="1" stop-color="#00274f" />
</linearGradient>
- <linearGradient
- gradientUnits="userSpaceOnUse"
- y2="162.44048"
- x2="237.65611"
- y1="162.44048"
- x1="-80.41803"
- id="linearGradient5175"
- xlink:href="#right-dark" />
- <linearGradient
- gradientUnits="userSpaceOnUse"
- y2="162.44048"
- x2="237.65611"
- y1="162.44048"
- x1="-80.41803"
- id="linearGradient5211"
- xlink:href="#left-dark" />
</defs>
- <g
- transform="translate(82.012688,-116.4355)"
- id="layer1">
+ <g>
<path
- style="fill:url(#linearGradient5175);fill-rule:evenodd;stroke:url(#linearGradient5211);stroke-width:1.32291663px;stroke-linejoin:miter;stroke-opacity:0.75"
- d="m -80.418029,184.88601 66.4546,-66.5869 v 28.92769 l 29.05998,-28.92769 v 46.56667 l 46.74315,-46.83125 v 52.51979 l 52.519789,-52.51979 v 29.19227 l 29.01579,-28.92769 v 44.6704 l 43.56815,-43.65625 h 50.71269 l -16.36184,16.36025 h -25.83921 l -7.40833,7.40833 h 13.44877 l -17.02064,17.24184 h -13.80332 l -7.67291,7.54062 h 44.93418 l -17.15293,17.02171 h -68.74748 l 4.14496,-4.54211 V 161.91118 L 101.6153,186.07663 V 158.0308 L 74.715911,184.88601 H 44.421121 V 162.17576 L -0.24927857,206.84642 H -26.707609 L -2.1013586,182.1518 V 162.17576 L -26.707609,186.6058 v -29.10417 l -27.25209,27.38438 z"
- class="cls-1" />
+ fill="url(#right-dark)" stroke="url(#left-dark)" stroke-width="5" stroke-linejoin="miter" stroke-opacity="0.75"
+ d="M 6,259 257,7 V 116 L 367,7 V 183 L 544,6 V 204 L 742,7 V 116 L 852,7 V 176 L 1017,11 H 1208 L 1146,73 H 1049 L 1021,101 H 1072 L 1007,166 H 955 L 926,195 H 1096 L 1031,259 H 771 L 787,241 V 172 L 694,263 V 157 L 592,259 H 478 V 172 L 309,341 H 209 L 302,248 V 172 L 209,263 V 157 L 106,259 z" />
</g>
</svg>
diff --git a/docs/source/index.rst b/docs/source/index.rst
index bf90036aa92..e2e54a4ee2b 100644
--- a/docs/source/index.rst
+++ b/docs/source/index.rst
@@ -11,21 +11,25 @@ MAME Documentation
==================
.. note::
- This documentation is a work in progress. You can track the status of these topics through MAME's `issue tracker <https://github.com/mamedev/mame/issues>`_. Learn how you can `contribute <https://github.com/mamedev/mame/blob/master/docs/CONTRIBUTING.md>`_ on GitHub.
+ This documentation is a work in progress. You can track the status of these topics through MAME's `issue tracker <https://github.com/mamedev/mame/issues>`_. Learn how you can :ref:`contribute <contributing>`.
.. toctree::
:titlesonly:
whatis
+ healthwarning
initialsetup/index
usingmame/index
commandline/index
+ plugins/index
advanced/index
debugger/index
+ luascript/index
tools/index
+ contributing/index
techspecs/index
security
diff --git a/docs/source/initialsetup/compilingmame.rst b/docs/source/initialsetup/compilingmame.rst
index 177e22fb072..a4559842b39 100644
--- a/docs/source/initialsetup/compilingmame.rst
+++ b/docs/source/initialsetup/compilingmame.rst
@@ -8,27 +8,74 @@ Compiling MAME
All Platforms
-------------
-* Whenever you are changing build parameters, (such as switching between a SDL-based build and a native Windows renderer one, or adding tools to the compile list) you need to run a **make REGENIE=1** to allow the settings to be regenerated. Failure to do this will cause you very difficult to troubleshoot problems.
+* To compile MAME, you need a C++17 compiler and runtime library. We
+ support building with GCC version 10.3 or later and clang version 11
+ or later. MAME should run with GNU libstdc++ version 10.3 or later or
+ libc++ version 11 or later. The initial release of any major version
+ of GCC should be avoided. For example, if you want to compile MAME
+ with GCC 12, you should use version 12.1 or later.
+
+* Whenever you are changing build parameters, (for example changing
+ optimisation settings, or adding tools to the compile list), or system
+ drivers sources are added, removed, or renamed, the project files need
+ to be regenerated. You can do this by adding **REGENIE=1** to the
+ make arguments, or updating the modification time of the makefile (for
+ example using the **touch** command). Failure to do this may cause
+ difficult to troubleshoot problems.
+
+* If you want to add various additional tools to the compile, such as
+ *chdman*, add a **TOOLS=1** to your make command, like
+ **make REGENIE=1 TOOLS=1**
+
+* You can build an emulator for a subset of the systems supported by
+ MAME by using *SOURCES=<driver>,...* in your make command. For
+ example
+ **make SUBTARGET=pacem SOURCES=src/mame/pacman/pacman.cpp REGENIE=1**
+ would build an emulator called *pacem* including the system drivers
+ from the source file pacman.cpp (*REGENIE=1* is specified to ensure
+ project files are regenerated). You can specify folders to include
+ their entire contents, and you can separate multiple files/folders
+ with commas. You can also omit the *src/mame/* prefix in many cases.
+
+ If you encounter linking errors after changing the included sources,
+ delete the static libraries for the subtarget from the build folder.
+ For the previous example on Windows using GCC, these would be in
+ *build/mingw-gcc/bin/x64/Release/mame_pacem* by default.
+
+* On a system with multiple CPU cores, compilation can be sped up by
+ compiling multiple source files in parallel. This is done with the
+ **-j** parameter. For instance, **make -j5** is a good starting point
+ on a system with a quad-core CPU.
+
+ *Note: a good number to start with is the total number of CPU cores
+ in your system plus one. An excessive number of concurrent jobs will
+ increase compilation time, particularly if the compiler jobs exhaust
+ available memory. The optimal number depends on many factors,
+ including number of CPU cores, available RAM, disk and filesystem
+ performance, and memory bandwidth.*
+
+* Debugging information can be added to a compile using *SYMBOLS=1*
+ though most users will not want or need to use this. This increases
+ compile time and disk space used. Note that a full build of MAME
+ including internal debugging symbols will exceed the maximum size for
+ an executable on Windows, and will not be possible to run without
+ first stripping the symbols.
-* If you want to add various additional tools to the compile, such as *CHDMAN*, add a **TOOLS=1** to your make statement, like **make REGENIE=1 TOOLS=1**
-
-* You can do driver specific builds by using *SOURCES=<driver>* in your make statement. For instance, building Pac-Man by itself would be **make SOURCES=src/mame/drivers/pacman.cpp REGENIE=1** including the necessary *REGENIE* for rebuilding the settings.
+Putting all of these together, we get a couple of examples:
-* Speeding up the compilation can be done by using more cores from your CPU. This is done with the **-j** parameter. *Note: the maximum number you should use is the number of cores your CPU has, plus one. No higher than that will speed up the compilation, and may in fact slow it down.* For instance, **make -j5** on a quad-core CPU will provide optimal speed.
+Rebuilding MAME on a dual-core (e.g. i3 or laptop i5) machine::
-* Debugging information can be added to a compile using *SYMBOLS=1* though most users will not want or need to use this.
+ make -j3
-Putting all of these together, we get a couple of examples:
+Rebuilding MAME for just the Pac-Man and Galaxian families of systems,
+with tools, on a quad-core (e.g. i5 or i7) machine::
-Rebuilding MAME for just the Pac-Man driver, with tools, on a quad-core (e.g. i5 or i7) machine:
+ make SUBTARGET=pacem SOURCES=src/mame/pacman,src/mame/galaxian TOOLS=1 REGENIE=1 -j5
-| **make SOURCES=src/mame/drivers/pacman.cpp TOOLS=1 REGENIE=1 -j5**
-|
+Rebuilding MAME for just the Apple II systems, compiling up to six
+sources in parallel::
-Rebuilding MAME on a dual-core (e.g. i3 or laptop i5) machine:
-
-| **make -j3**
-|
+ make SUBTARGET=appulator SOURCES=apple/apple2.cpp,apple/apple2e.cpp,apple/apple2gs.cpp REGENIE=1 -j6
.. _compiling-windows:
@@ -39,10 +86,11 @@ Microsoft Windows
MAME for Windows is built using the MSYS2 environment. You will need Windows 7
or later and a reasonably up-to-date MSYS2 installation. We strongly recommend
building MAME on a 64-bit system. Instructions may need to be adjusted for
-32-bit systems.
+32-bit systems. Building for 64-bit ARM (AArch64) requires a 64-bit ARM system
+running Windows 11 or later.
* A pre-packaged MSYS2 installation including the prerequisites for building
- MAME can be downloaded from the `MAME Build Tools
+ MAME for 64-bit x86-64 can be downloaded from the `MAME Build Tools
<http://mamedev.org/tools/>`_ page.
* After initial installation, you can update the MSYS2 environment using the
**pacman** (Arch package manage) command.
@@ -50,9 +98,9 @@ building MAME on a 64-bit system. Instructions may need to be adjusted for
window management, audio/video output, font rendering, etc. If you want to
use the portable SDL (Simple DirectMedia Layer) interfaces instead, you can
add **OSD=sdl** to the make options. The main emulator binary will have an
- ``sdl`` prefix prepended (e.g. ``sdlmame64.exe`` or ``sdlmame.exe``). You
- will need to install the MSYS2 packages for SDL 2 version 2.0.3 or later.
-* By default, MAME will include the native Windows debugger. To also inculde
+ ``sdl`` prefix prepended (e.g. ``sdlmame.exe``). You
+ will need to install the MSYS2 packages for SDL 2 version 2.0.14 or later.
+* By default, MAME will include the native Windows debugger. To also include
the portable Qt debugger, add **USE_QTDEBUG=1** to the make options. You
will need to install the MSYS2 packages for Qt 5.
@@ -68,71 +116,207 @@ with MSYS2 and the **pacman** package manager.
* Download the latest version of the ``mame-essentials`` package from the
`MAME package repository <https://repo.mamedev.org/x86_64/>`_ and install it
using the **pacman** command.
-* Add the ``mame`` repository to ``/etc/pacman.conf`` using
- ``/etc/pacman.d/mirrorlist.mame`` for locations.
-* Install packages necessary to build MAME. At the very least, you'll need
+* Add the ``mame`` package repository to ``/etc/pacman.conf`` using
+ ``/etc/pacman.d/mirrorlist.mame`` for locations, and disable signature
+ verification for this repository (``SigLevel = Never``).
+* Install packages necessary to build MAME. At the very least, you’ll need
``bash``, ``git``, ``make``.
-* For 64-bit builds you'll need ``mingw-w64-x86_64-gcc`` and
- ``mingw-w64-x86_64-python2``.
-* For 32-bit builds you'll need ``mingw-w64-i686-gcc`` and
- ``mingw-w64-i686-python2``.
* For debugging you may want to install ``gdb``.
-* To build against the portable SDL interfaces, you'll need
- ``mingw-w64-x86_64-SDL2`` and ``mingw-w64-x86_64-SDL2_ttf`` for 64-bit builds,
- or ``mingw-w64-i686-SDL2`` and ``mingw-w64-i686-SDL2_ttf`` for 32-bit builds.
-* To build the Qt debugger, you'll need ``mingw-w64-x86_64-qt5`` for 64-bit
- builds, or ``mingw-w64-i686-qt5`` for 32-bit builds.
-* To generate API documentation from source, you'll need ``doxygen``.
-* For 64-bit builds, open **MSYS2 MinGW 64-bit** from the start menu, and set
- up the environment variables ``MINGW64`` to ``/mingw64`` and ``MINGW32`` to an
- empty string (e.g. using the command **export MINGW64=/mingw64 MINGW32=** in
- the Bash shell).
-* For 32-bit builds, open **MSYS2 MinGW 32-bit** from the start menu, and set
- up the environment variables ``MINGW32`` to ``/mingw32`` and ``MINGW64`` to an
- empty string (e.g. using the command **export MINGW32=/mingw32 MINGW64=** in
- the Bash shell).
+* To build the HTML user/developer documentation, you’ll need
+ ``mingw-w64-x86_64-librsvg``, ``mingw-w64-x86_64-python-sphinx``,
+ ``mingw-w64-x86_64-python-sphinx_rtd_theme`` and
+ ``mingw-w64-x86_64-python-sphinxcontrib-svg2pdfconverter`` for a 64-bit MinGW
+ environment (or alternatively ``mingw-w64-i686-librsvg``,
+ ``mingw-w64-i686-python-sphinx``, ``mingw-w64-i686-python-sphinx_rtd_theme``
+ and ``mingw-w64-x86_64-python-sphinxcontrib-svg2pdfconverter`` a 32-bit MinGW
+ environment).
+* To build the PDF documentation, you’ll additionally need
+ ``mingw-w64-x86_64-texlive-latex-extra`` and
+ ``mingw-w64-x86_64-texlive-fonts-recommended`` (or
+ ``mingw-w64-i686-texlive-latex-extra`` and
+ ``mingw-w64-i686-texlive-fonts-recommended`` for a 32-bit MinGW environment).
+* To generate API documentation from source, you’ll need ``doxygen``.
+* If you plan to rebuild bgfx shaders and you want to rebuild the GLSL parser,
+ you’ll need ``bison``.
+
+The additional packages you’ll need depend on the CPU architecture you’re
+building for.
+
+**64-bit x86-64**
+
+* You’ll need ``mingw-w64-x86_64-gcc`` and ``mingw-w64-x86_64-python``.
+* To link using the LLVM linker (generally much faster than the GNU linker),
+ you’ll need ``mingw-w64-x86_64-lld``, ``mingw-w64-x86_64-llvm`` and
+ ``mingw-w64-x86_64-libc++``.
+* To build against the portable SDL interfaces, you’ll need
+ ``mingw-w64-x86_64-SDL2`` and ``mingw-w64-x86_64-SDL2_ttf``.
+* To build the Qt debugger, you’ll need ``mingw-w64-x86_64-qt5``.
+* Open the **mingw64.exe** helper from the **msys64** installation folder or the
+ **MSYS2 MinGW 64-bit** shortcut from the start menu to start a Bash shell
+ configured with the correct paths and environment variables.
+
+**32-bit x86**
+
+* You’ll need ``mingw-w64-i686-gcc`` and ``mingw-w64-i686-python``.
+* To link using the LLVM linker (generally much faster than the GNU linker),
+ you’ll need ``mingw-w64-i686-lld``, ``mingw-w64-i686-llvm`` and
+ ``mingw-w64-i686-libc++``.
+* To build against the portable SDL interfaces, you’ll need
+ ``mingw-w64-i686-SDL2`` and ``mingw-w64-i686-SDL2_ttf``.
+* To build the Qt debugger, you’ll need ``mingw-w64-i686-qt5``.
+* Open the **mingw32.exe** helper from the **msys64** installation folder or the
+ **MSYS2 MinGW 32-bit** shortcut from the start menu to start a Bash shell
+ configured with the correct paths and environment variables.
+
+**64-bit ARM (AArch64)**
+
+* You’ll need ``mingw-w64-clang-aarch64-clang``,
+ ``mingw-w64-clang-aarch64-python`` and ``mingw-w64-clang-aarch64-gcc-compat``.
+* To link using the LLVM linker (generally much faster than the GNU linker),
+ you’ll need ``mingw-w64-clang-aarch64-lld``, ``mingw-w64-clang-aarch64-llvm``
+ and ``mingw-w64-clang-aarch64-libc++``.
+* To build against the portable SDL interfaces, you’ll need
+ ``mingw-w64-clang-aarch64-SDL2`` and ``mingw-w64-clang-aarch64-SDL2_ttf``.
+* To build the Qt debugger, you’ll need ``mingw-w64-clang-aarch64-qt5``.
+* Open the **clangarm64.exe** helper from the **msys64** installation folder to
+ start a Bash shell configured with the correct paths and environment
+ variables.
+
+For example you could use these commands to ensure you have the packages you
+need to compile MAME, omitting the ones for configurations you don’t plan to
+build for or combining multiple **pacman** commands to install more packages at
+once::
+
+ pacman -Syu
+ pacman -S curl git make
+ pacman -S mingw-w64-x86_64-gcc mingw-w64-x86_64-python
+ pacman -S mingw-w64-x86_64-llvm mingw-w64-x86_64-libc++ mingw-w64-x86_64-lld
+ pacman -S mingw-w64-x86_64-SDL2 mingw-w64-x86_64-SDL2_ttf
+ pacman -S mingw-w64-x86_64-qt5
+ pacman -S mingw-w64-i686-gcc mingw-w64-i686-python
+ pacman -S mingw-w64-i686-llvm mingw-w64-i686-libc++ mingw-w64-i686-lld
+ pacman -S mingw-w64-i686-SDL2 mingw-w64-i686-SDL2_ttf
+ pacman -S mingw-w64-i686-qt5
+ pacman -S mingw-w64-clang-aarch64-clang mingw-w64-clang-aarch64-python mingw-w64-clang-aarch64-gcc-compat
+ pacman -S mingw-w64-clang-aarch64-lld mingw-w64-clang-aarch64-llvm mingw-w64-clang-aarch64-libc++
+ pacman -S mingw-w64-clang-aarch64-SDL2 mingw-w64-clang-aarch64-SDL2_ttf
+ pacman -S mingw-w64-clang-aarch64-qt5
+
+You could use these commands to install the current version of the
+mame-essentials package and add the MAME package repository to your pacman
+configuration::
+
+ curl -O "https://repo.mamedev.org/x86_64/mame-essentials-1.0.6-1-x86_64.pkg.tar.xz"
+ pacman -U mame-essentials-1.0.6-1-x86_64.pkg.tar.xz
+ echo -e '\n[mame]\nInclude = /etc/pacman.d/mirrorlist.mame\nSigLevel = Never' >> /etc/pacman.conf
Building with Microsoft Visual Studio
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-* You can generate Visual Studio 2017 projects using **make vs2017**. The
+* You can generate Visual Studio 2022 projects using **make vs2022**. The
solution and project files will be created in
- ``build/projects/windows/mame/vs2017`` by default (the name of the ``build``
+ ``build/projects/windows/mame/vs2022`` by default (the name of the ``build``
folder can be changed using the ``BUILDDIR`` option). This will always
regenerate the settings, so **REGENIE=1** is *not* needed.
-* Adding **MSBUILD=1** to the make options will build build the solution using
+* Adding **MSBUILD=1** to the make options will build the solution using
the Microsoft Build Engine after generating the project files. Note that this
requires paths and environment variables to be configured so the correct
- Visual Studio tools can be located.
-* MAME can only be compiled with the Visual Studio 15.7.6 tools. Bugs in newer
- versions of the Microsoft Visual C/C++ compiler prevent it from compiling
- MAME.
+ Visual Studio tools can be located; please refer to the Microsoft-provided
+ instructions on `using the Microsoft C++ toolset from the command line
+ <https://docs.microsoft.com/en-us/cpp/build/building-on-the-command-line>`_.
+ You may find it easier to not use **MSBUILD=1** and load the project file into
+ Visual Studio’s GUI for compilation.
* The MSYS2 environment is still required to generate the project files, convert
built-in layouts, compile UI translations, etc.
+Some notes about the MSYS2 environment
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+MSYS2 uses the pacman tool from Arch Linux for package management. There is a
+`page on the Arch Linux wiki <https://wiki.archlinux.org/index.php/Pacman>`_
+with helpful information on using the pacman package management tool.
+
+The MSYS2 environment includes two kinds of tools: MSYS2 tools designed to work
+in a UNIX-like environment on top of Windows, and MinGW tools designed to work
+in a more Windows-like environment. The MSYS2 tools are installed in
+``/usr/bin`` while the MinGW tools are installed in ``/ming64/bin``,
+``/mingw32/bin`` and/or ``/clangarm64/bin`` (relative to the MSYS2 installation
+directory). MSYS2 tools work best in an MSYS2 terminal, while MinGW tools work
+best in a Microsoft command prompt.
+
+The most obvious symptom of this is that arrow keys don’t work in interactive
+programs if you run them in the wrong kind of terminal. If you run MinGW gdb or
+python from an MSYS2 terminal window, command history won’t work and it may not
+be possible to interrupt an attached program with gdb. Similarly it may be very
+difficult to edit using MSYS2 vim in a Microsoft command prompt window.
+
+MAME is built using the MinGW compilers, so the MinGW directories are included
+earlier in the ``PATH`` environment variable for the build environments. If you
+want to use an interactive MSYS2 program from an MSYS2 shell, you may need to
+type the absolute path to avoid using the MinGW equivalent instead.
+
+MSYS2 gdb may have issues debugging MinGW programs like MAME. You may get
+better results by installing the MinGW version of gdb and running it from a
+Microsoft command prompt window to debug MAME.
+
+GNU make supports both POSIX-style shells (e.g. bash) and the Microsoft cmd.exe
+shell. One issue to be aware of when using the cmd.exe shell is that the
+``copy`` command doesn’t provide a useful exit status, so file copy tasks can
+fail silently. This may cause your build to appear to succeed while producing
+incorrect results.
+
+It is not possible to cross-compile a 32-bit version of MAME using 64-bit MinGW
+tools on Windows, the 32-bit MinGW tools must be used. This causes issues due
+to the size of MAME. It’s impossible to make a 32-bit build with full local
+variable symbols. GCC may run out of memory, and certain source files may
+exceed the limit of 32,768 sections imposed by the PE/COFF object file format.
+
+A complete build of MAME including line number symbols exceeds the size limit
+imposed by the PE file format and cannot be run. Workarounds include including
+only a subset of the systems supported by MAME or extracting symbols to a
+separate file and stripping excess symbols from the MAME executable.
+
.. _compiling-fedora:
Fedora Linux
------------
-You'll need a few prerequisites from your distro. Make sure you get SDL2 2.0.3 or 2.0.4 as earlier versions are buggy.
+You’ll need a few prerequisites from your Linux distribution. Make sure you get
+SDL 2 version 2.0.14 or later as earlier versions lack required functionality::
+
+ sudo dnf install gcc gcc-c++ SDL2-devel SDL2_ttf-devel libXi-devel libXinerama-devel qt5-qtbase-devel qt5-qttools expat-devel fontconfig-devel alsa-lib-devel pulseaudio-libs-devel
-**sudo dnf install gcc gcc-c++ SDL2-devel SDL2_ttf-devel libXi-devel libXinerama-devel qt5-qtbase-devel qt5-qttools expat-devel fontconfig-devel alsa-lib-devel**
+If you want to use the more efficient LLVM tools for archiving static libraries
+and linking, you’ll need to install the corresponding packages::
+
+ sudo dnf install lld llvm
Compilation is exactly as described above in All Platforms.
+To build the HTML user/developer documentation, you’ll need Sphinx, as well as
+the theme and the SVG converter::
+
+ sudo dnf install python3-sphinx python3-sphinx_rtd_theme python3-sphinxcontrib-rsvgconverter
+
+The HTML documentation can be built with this command::
+
+ make -C docs SPHINXBUILD=sphinx-build-3 html
+
.. _compiling-ubuntu:
Debian and Ubuntu (including Raspberry Pi and ODROID devices)
-------------------------------------------------------------
-You'll need a few prerequisites from your distro. Make sure you get SDL2 2.0.3 or 2.0.4 as earlier versions are buggy.
+You’ll need a few prerequisites from your Linux distribution. Make sure you get
+SDL 2 version 2.0.14 or later as earlier versions lack required functionality::
-**sudo apt-get install git build-essential python libsdl2-dev libsdl2-ttf-dev libfontconfig-dev qt5-default**
+ sudo apt-get install git build-essential python3 libsdl2-dev libsdl2-ttf-dev libfontconfig-dev libpulse-dev qtbase5-dev qtbase5-dev-tools qtchooser qt5-qmake
-Compilation is exactly as described above in All Platforms.
+Compilation is exactly as described above in All Platforms. Note the Ubuntu
+Linux modifies GCC to enable the GNU C Library “fortify source” feature by
+default, which may cause issues compiling MAME (see :ref:`compiling-issues`).
.. _compiling-arch:
@@ -140,44 +324,60 @@ Compilation is exactly as described above in All Platforms.
Arch Linux
----------
-You'll need a few prerequisites from your distro.
+You’ll need a few prerequisites from your distro::
-**sudo pacman -S base-devel git sdl2 gconf sdl2_ttf gcc qt5**
+ sudo pacman -S base-devel git sdl2_ttf python libxinerama libpulse alsa-lib qt5-base
Compilation is exactly as described above in All Platforms.
.. _compiling-macos:
-Apple Mac OS X
---------------
-
-You'll need a few prerequisites to get started. Make sure you're on OS X 10.9 Mavericks or later. You will NEED SDL2 2.0.4 for OS X.
-
-* Install **Xcode** from the Mac App Store
-* Launch **Xcode**. It will download a few additional prerequisites. Let this run through before proceeding.
-* Once that's done, quit **Xcode** and open a **Terminal** window
+Apple macOS
+-----------
+
+You’ll need a few prerequisites to get started. Make sure you’re on macOS 11.0
+Big Sur or later. You will need SDL 2 version 2.0.14 or later. You’ll also
+need to install Python 3 – it’s currently included with the Xcode command line
+tools, but you can also install a stand-alone version or get it via the Homebrew
+package manager.
+
+* Install **Xcode** from the Mac App Store or
+ `ADC <https://developer.apple.com/download/more/>`_ (AppleID required).
+* To find the corresponding Xcode for your MacOS release please visit
+ `xcodereleases.com <https://xcodereleases.com>`_ to find the latest version of
+ Xcode available to you.
+* Launch **Xcode**. It will download a few additional prerequisites. Let this
+ run through before proceeding.
+* Once that’s done, quit **Xcode** and open a **Terminal** window.
* Type **xcode-select --install** to install additional tools necessary for MAME
+ (also available as a package on ADC).
-Next you'll need to get SDL2 installed.
-
-* Go to `this site <http://libsdl.org/download-2.0.php>`_ and download the *Mac OS X* .dmg file
-* If the .dmg doesn't auto-open, open it
-* Click 'Macintosh HD' (or whatever your Mac's hard disk is named) in the left pane of a **Finder** window, then open the **Library** folder and drag the **SDL2.framework** folder from the SDL disk image into the **Frameworks** folder
+Next you’ll need to get SDL 2 installed.
-Lastly to begin compiling, use Terminal to navigate to where you have the MAME source tree (*cd* command) and follow the normal compilation instructions from above in All Platforms.
+* Go to `this site <http://libsdl.org/download-2.0.php>`_ and download the
+ *macOS* .dmg file
+* If the .dmg doesn’t open automatically, open it
+* Click “Macintosh HD” (or whatever your Mac’s hard disk is named) in the left
+ pane of a **Finder** window, then open the **Library** folder and drag the
+ **SDL2.framework** folder from the SDL disk image into the **Frameworks**
+ folder. You will have to authenticate with your user password.
-It's possible to get MAME working from 10.6, but a bit more complicated:
+If you don’t already have it, get Python 3 set up:
-* You'll need to install clang-3.7, ld64, libcxx and python27 from MacPorts
-* Then add these options to your make command or useroptions.mak:
+* Go to the official Python site, navigate to the
+ `releases for macOS <https://www.python.org/downloads/macos/>`_, and click the
+ link to download the installer for the latest stable release (this was
+ `Python 3.10.4 <https://www.python.org/ftp/python/3.10.4/python-3.10.4-macos11.pkg>`_
+ at the time of writing).
+* Scroll down to the “Files” section, and download the macOS version (called
+ “macOS 64-bit universal2 installer” or similar).
+* Once the package downloads, open it and follow the standard installation
+ process.
-|
-| OVERRIDE_CC=/opt/local/bin/clang-mp-3.7
-| OVERRIDE_CXX=/opt/local/bin/clang++-mp-3.7
-| PYTHON_EXECUTABLE=/opt/local/bin/python2.7
-| ARCHOPTS=-stdlib=libc++
-|
+Finally to begin compiling, use Terminal to navigate to where you have the MAME
+source tree (*cd* command) and follow the normal compilation instructions from
+above in All Platforms.
.. _compiling-emscripten:
@@ -185,38 +385,135 @@ It's possible to get MAME working from 10.6, but a bit more complicated:
Emscripten Javascript and HTML
------------------------------
-First, download and install Emscripten 1.37.29 or later by following the instructions at the `official site <https://kripken.github.io/emscripten-site/docs/getting_started/downloads.html>`_
+First, download and install Emscripten 3.1.35 or later by following the
+instructions at the `official site <https://emscripten.org/docs/getting_started/downloads.html>`_.
+
+Once Emscripten has been installed, it should be possible to compile MAME
+out-of-the-box using Emscripten’s **emmake** tool. Because a full MAME
+compile is too large to load into a web browser at once, you will want to use
+the SOURCES parameter to compile only a subset of the project, e.g. (in the
+MAME directory):
+
+.. code-block:: bash
+
+ emmake make SUBTARGET=pacmantest SOURCES=src/mame/pacman/pacman.cpp
+
+The **SOURCES** parameter should have the path to at least one driver **.cpp**
+file. The make process will attempt to locate and include all dependencies
+necessary to produce a complete build including the specified driver(s).
+However, sometimes it is necessary to manually specify additional files (using
+commas) if this process misses something. e.g.
+
+.. code-block:: bash
+
+ emmake make SUBTARGET=apple2e SOURCES=src/mame/apple/apple2e.cpp,src/devices/machine/applefdc.cpp
+
+The value of the **SUBTARGET** parameter serves only to differentiate multiple
+builds and need not be set to any specific value.
+
+Emscripten supports compiling to WebAssembly with a JavaScript loader instead of
+all-JavaScript, and in later versions this is actually the default. To force
+WebAssembly on or off, add **WEBASSEMBLY=1** or **WEBASSEMBLY=0** to the make
+command line, respectively.
+
+Other make parameters can also be used, e.g. **-j** for multithreaded
+compilation as described earlier.
+
+When the compilation reaches the emcc phase, you may see a number of
+*"unresolved symbol"* warnings. At the moment, this is expected for
+OpenGL-related functions such as glPointSize. Any others may indicate that an
+additional dependency file needs to be specified in the **SOURCES** list.
+Unfortunately this process is not automated and you will need to search the
+source tree to locate the files supplying the missing symbols. You may also be
+able to get away with ignoring the warnings if the code path referencing them is
+not used at run-time.
+
+If all goes well, a **.js** file will be output to the current directory. This
+file cannot be run by itself, but requires an HTML loader to provide it with a
+canvas to draw to and to pass in command-line parameters. The
+`Emularity project <https://github.com/db48x/emularity>`_ provides such a
+loader.
+
+There are example **.html** files in that repository which can be edited to
+point to your newly compiled MAME **.js** file and pass in whatever parameters
+you desire. You will then need to place all of the following on a web server:
+
+* The compiled MAME **.js** file
+* The compiled MAME **.wasm** file if using WebAssembly
+* The **.js** files from the Emularity package (**loader.js**, **browserfs.js**,
+ etc.)
+* A **.zip** file with the ROMs for the MAME driver you would like to run (if
+ any)
+* Any software files you would like to run with the MAME driver
+* An Emularity loader **.html** modified to point to all of the above
-Once Emscripten has been installed, it should be possible to compile MAME out-of-the-box using Emscripten's '**emmake**' tool. Because a full MAME compile is too large to load into a web browser at once, you will want to use the SOURCES parameter to compile only a subset of the project, e.g. (in the mame directory):
+You need to use a web server instead of opening the local files directly due to
+security restrictions in modern web browsers.
-**emmake make SUBTARGET=pacmantest SOURCES=src/mame/drivers/pacman.cpp**
+If the result fails to run, you can open the Web Console in your browser to see
+any error output which may have been produced (e.g. missing or incorrect ROM
+files). A “ReferenceError: foo is not defined” error most likely indicates that
+a needed source file was omitted from the **SOURCES** list.
-The SOURCES parameter should have the path to at least one driver .cpp file. The make process will attempt to locate and include all dependencies necessary to produce a complete build including the specified driver(s). However, sometimes it is necessary to manually specify additional files (using commas) if this process misses something. E.g.:
-**emmake make SUBTARGET=apple2e SOURCES=src/mame/drivers/apple2e.cpp,src/mame/machine/applefdc.cpp**
+.. _compiling-docs:
-The value of the SUBTARGET parameter serves only to differentiate multiple builds and need not be set to any specific value.
+Compiling the Documentation
+---------------------------
-Emscripten supports compiling to WebAssembly with a JavaScript loader instead of all-JavaScript, and in later versions this is actually the default. To force WebAssembly on or off, add WEBASSEMBLY=1 or WEBASSEMBLY=0 to the make command line.
+Compiling the documentation will require you to install several packages
+depending on your operating system.
-Other make parameters can also be used, e.g. *-j* for multithreaded compilation as described earlier.
+.. _compiling-docs-windows:
-When the compilation reaches the emcc phase, you may see a number of *"unresolved symbol"* warnings. At the moment, this is expected for OpenGL-related functions such as glPointSize. Any others may indicate that an additional dependency file needs to be specified in the SOURCES list. Unfortunately this process is not automated and you will need to search the source tree to locate the files supplying the missing symbols. You may also be able to get away with ignoring the warnings if the code path referencing them is not used at run-time.
+Compiling the Documentation on Microsoft Windows
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-If all goes well, a .js file will be output to the current directory. This file cannot be run by itself, but requires an HTML loader to provide it with a canvas to output to and pass in command-line parameters. The `Emularity project <https://github.com/db48x/emularity>`_ provides such a loader.
+On Windows, you’ll need a couple of packages from the MSYS2 environment. You
+can install these packages with
-There are example .html files in that repository which can be edited to point to your newly compiled MAME js filename and pass in whatever parameters you desire. You will then need to place all of the following on a web server:
+.. code-block:: bash
-* The compiled MAME .js file
-* The compiled MAME .wasm file if using WebAssembly
-* The .js files from the Emularity package (loader.js, browserfs.js, etc.)
-* A .zip file with the ROMs for the MAME driver you would like to run (if any)
-* Any software files you would like to run with the MAME driver
-* An Emularity loader .html modified to point to all of the above
+ pacman -S mingw-w64-x86_64-librsvg mingw-w64-x86_64-python-sphinx mingw-w64-x86_64-python-sphinxcontrib-svg2pdfconverter
-You need to use a web server instead of opening the local files directly due to security restrictions in modern web browsers.
+If you intend to make a PDF via LaTeX, you’ll need to install a LaTeX
+distribution such as TeX Live:
-If the result fails to run, you can open the Web Console in your browser to see any error output which may have been produced (e.g. missing or incorrect ROM files). A "ReferenceError: foo is not defined" error most likely indicates that a needed source file was omitted from the SOURCES list.
+.. code-block:: bash
+
+ pacman -S mingw-w64-x86_64-texlive-fonts-recommended mingw-w64-x86_64-texlive-latex-extra
+
+.. _compiling-docs-debian:
+
+Compiling the Documentation on Debian and Ubuntu
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+On Debian/Ubuntu flavors of Linux, you’ll need **python3-sphinx/python-sphinx**
+and the **python3-pip/python-pip** packages:
+
+.. code-block:: bash
+
+ sudo apt-get install python3-sphinx python3-pip
+ pip3 install sphinxcontrib-svg2pdfconverter
+
+On Debian, you’ll need to install the **librsvg2-bin** package:
+
+.. code-block:: bash
+
+ sudo apt-get install librsvg2-bin
+
+If you intend to make a PDF via LaTeX, you’ll need to install a LaTeX
+distribution such as TeX Live:
+
+.. code-block:: bash
+
+ sudo apt-get install librsvg2-bin latexmk texlive texlive-science texlive-formats-extra
+
+From this point you can do ``make html`` or ``make latexpdf`` from the **docs**
+folder to generate the output of your choice. Typing ``make`` by itself will
+tell you all available formats. The output will be in the docs/build folder in
+a subfolder based on the type chosen (e.g. ``make html`` will create
+*docs/build/html* with the output.)
.. _compiling-options:
@@ -236,160 +533,198 @@ Overall build options
~~~~~~~~~~~~~~~~~~~~~
PREFIX_MAKEFILE
- Name of a makefile to include for additional options if found (defaults to
- **useroptions.mak**). May be useful if you want to quickly switch between
- different build configurations.
+ Name of a makefile to include for additional options if found (defaults to
+ **useroptions.mak**). May be useful if you want to quickly switch between
+ different build configurations.
BUILDDIR
- Set to change the name of the subfolder used for project files, generated
- sources, object files, and intermediate libraries (defaults to **build**).
+ Set to change the name of the subfolder used for project files, generated
+ sources, object files, and intermediate libraries (defaults to **build**).
REGENIE
- Set to **1** to force project files to be regenerated.
+ Set to **1** to force project files to be regenerated.
VERBOSE
- Set to **1** to show full commands when using GNU make as the build tool.
- This option applies immediately without needing regenerate project files.
+ Set to **1** to show full commands when using GNU make as the build tool.
+ This option applies immediately without needing regenerate project files.
IGNORE_GIT
- Set to **1** to skip the working tree scan and not attempt to embed a git
- revision description in the version string.
+ Set to **1** to skip the working tree scan and not attempt to embed a git
+ revision description in the version string.
Tool locations
~~~~~~~~~~~~~~
OVERRIDE_CC
- Set the C/Objective-C compiler command. (This sets the target C compiler
- command when cross-compiling.)
+ Set the C/Objective-C compiler command. (This sets the target C compiler
+ command when cross-compiling.)
OVERRIDE_CXX
- Set the C++/Objective-C++ compiler command. (This sets the target C++
- compiler command when cross-compiling.)
+ Set the C++/Objective-C++ compiler command. (This sets the target C++
+ compiler command when cross-compiling.)
OVERRIDE_LD
- Set the linker command. This is often not necessary or useful because the C
- or C++ compiler command is used to invoke the linker. (This sets the target
- linker command when cross-compiling.)
+ Set the linker command. This is often not necessary or useful because the C
+ or C++ compiler command is used to invoke the linker. (This sets the target
+ linker command when cross-compiling.)
PYTHON_EXECUTABLE
- Set the Python interpreter command. You need Python 2.7 or Python 3 to build
- MAME.
+ Set the Python interpreter command. You need Python 3.2 or later to build
+ MAME.
CROSS_BUILD
- Set to **1** to use separate host and target compilers and linkers, as
- required for cross-compilation. In this case, **OVERRIDE_CC**,
- **OVERRIDE_CXX** and **OVERRIDE_LD** set the target C compiler, C++ compiler
- and linker commands, while **CC**, **CXX** and **LD** set the host C
- compiler, C++ compiler and linker commands.
+ Set to **1** to use separate host and target compilers and linkers, as
+ required for cross-compilation. In this case, **OVERRIDE_CC**,
+ **OVERRIDE_CXX** and **OVERRIDE_LD** set the target C compiler, C++ compiler
+ and linker commands, while **CC**, **CXX** and **LD** set the host C
+ compiler, C++ compiler and linker commands.
+
+Including subsets of supported systems
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+SUBTARGET
+ Set emulator subtarget to build. Some pre-defined subtargets are provided,
+ using Lua scripts in *scripts/target/mame* and system driver filter files in
+ *src/mame*. User-defined substargets can be created using the **SOURCES**
+ or **SOURCEFILTER** option.
+SOURCES
+ Specify system driver source files and/or folders to include. Usually used
+ in conjunction with the **SUBTARGET** option. Separate multiple
+ files/folders with commas.
+SOURCEFILTER
+ Specify a system driver filter file. Usually used in conjunction with the
+ **SUBTARGET** option. The filter file can specify source files to include
+ system drivers from, and individual system drivers to include or exclude.
+ There are some example system driver filter files in the *src/mame* folder.
Optional features
~~~~~~~~~~~~~~~~~
TOOLS
- Set to **1** to build additional tools along with the emulator, including
- **unidasm**, **chdman**, **romcmp**, and **srcclean**.
+ Set to **1** to build additional tools along with the emulator, including
+ **unidasm**, **chdman**, **romcmp**, and **srcclean**.
+EMULATOR
+ When set to **0**, the main emulator target will not be created. This is
+ intended to be used in conjunction with setting **TOOLS** to **1** to build
+ the additional tools without building the emulator.
+NO_OPENGL
+ Set to **1** to disable building the OpenGL video output module.
NO_USE_PORTAUDIO
- Set to **1** to disable building the PortAudio sound output module.
+ Set to **1** to disable building the PortAudio sound output module and the
+ PortAudio library.
+NO_USE_PULSEAUDIO
+ Set to **1** to disable building the PulseAudio sound output module on
+ Linux.
+USE_WAYLAND
+ Set to **1** to include support for bgfx video output with the Wayland
+ display server.
+USE_TAPTUN
+ Set to **1** to include the tap/tun network module, or set to **0** to
+ disable building the tap/tun network module. The tap/tun network module is
+ included by default on Windows and Linux.
+USE_PCAP
+ Set to **1** to include the pcap network module, or set to **0** to disable
+ building the pcap network module. The pcap network module is included by
+ default on macOS and NetBSD.
USE_QTDEBUG
- Set to **1** to include the Qt debugger on platforms where it's not built by
- default (e.g. Windows or MacOS), or to **0** to disable it. You'll need to
- install Qt development libraries and tools to build the Qt debugger. The
- process depends on the platform.
+ Set to **1** to include the Qt debugger on platforms where it’s not built by
+ default (e.g. Windows or macOS), or to **0** to disable it. You’ll need to
+ install Qt development libraries and tools to build the Qt debugger. The
+ process depends on the platform.
Compilation options
~~~~~~~~~~~~~~~~~~~
NOWERROR
- Set to **1** to disable treating compiler warnings as errors. This may be
- needed in marginally supported configurations.
+ Set to **1** to disable treating compiler warnings as errors. This may be
+ needed in marginally supported configurations.
DEPRECATED
- Set to **0** to disable deprecation warnings (note that deprecation warnings
- are not treated as errors).
+ Set to **0** to disable deprecation warnings (note that deprecation warnings
+ are not treated as errors).
DEBUG
- Set to **1** to enable runtime assertion checks and additional diagnostics.
- Note that this has a performance cost, and is most useful for developers.
+ Set to **1** to enable runtime assertion checks and additional diagnostics.
+ Note that this has a performance cost, and is most useful for developers.
OPTIMIZE
- Set optimisation level. The default is **3** to favour performance at the
- expense of larger executable size. Set to **0** to disable optimisation (can
- make debugging easier), **1** for basic optimisation that doesn't have a
- space/speed trade-off and doesn't have a large impact on compile time, **2**
- to enable most optimisation that improves performance and reduces size, or
- **s** to enable only optimisations that generally don't increase executable
- size. The exact set of supported values depends on your compiler.
+ Set optimisation level. The default is **3** to favour performance at the
+ expense of larger executable size. Set to **0** to disable optimisation
+ (can make debugging easier), **1** for basic optimisation that doesn’t have
+ a space/speed trade-off and doesn’t have a large impact on compile time,
+ **2** to enable most optimisation that improves performance and reduces
+ size, or **s** to enable only optimisations that generally don’t increase
+ executable size. The exact set of supported values depends on your
+ compiler.
SYMBOLS
- Set to **1** to include additional debugging symbols over the default for the
- target platform (many target platforms include function name symbols by
- default).
+ Set to **1** to include additional debugging symbols over the default for
+ the target platform (many target platforms include function name symbols by
+ default).
SYMLEVEL
- Numeric value that controls the level of detail in debugging symbols. Higher
- numbers make debugging easier at the cost of increased build time and
- executable size. The supported values depend on your compiler. For GCC and
- similar compilers, **1** includes line number tables and external variables,
- **2** also includes local variables, and **3** also includes macro
- definitions.
+ Numeric value that controls the level of detail in debugging symbols.
+ Higher numbers make debugging easier at the cost of increased build time and
+ executable size. The supported values depend on your compiler. For GCC and
+ similar compilers, **1** includes line number tables and external variables,
+ **2** also includes local variables, and **3** also includes macro
+ definitions.
ARCHOPTS
- Additional command-line options to pass to the compiler and linker. This is
- useful for supplying code generation or ABI options, for example to enable
- support for optional CPU features.
+ Additional command-line options to pass to the compiler and linker. This is
+ useful for supplying code generation or ABI options, for example to enable
+ support for optional CPU features.
ARCHOPTS_C
- Additional command-line options to pass to the compiler when compiling C
- source files.
+ Additional command-line options to pass to the compiler when compiling C
+ source files.
ARCHOPTS_CXX
- Additional command-line options to pass to the compiler when compiling C++
- source files.
+ Additional command-line options to pass to the compiler when compiling C++
+ source files.
ARCHOPTS_OBJC
- Additional command-line options to pass to the compiler when compiling
- Objective-C source files.
+ Additional command-line options to pass to the compiler when compiling
+ Objective-C source files.
ARCHOPTS_OBJCXX
- Additional command-line options to pass to the compiler when compiling
- Objective-C++ source files.
+ Additional command-line options to pass to the compiler when compiling
+ Objective-C++ source files.
Library/framework locations
~~~~~~~~~~~~~~~~~~~~~~~~~~~
SDL_INSTALL_ROOT
- SDL installation root directory for shared library style SDL.
+ SDL installation root directory for shared library style SDL.
SDL_FRAMEWORK_PATH
- Search path for SDL framework.
+ Search path for SDL framework.
USE_LIBSDL
- Set to **1** to use shared library style SDL on targets where framework is
- default.
+ Set to **1** to use shared library style SDL on targets where framework is
+ default.
USE_SYSTEM_LIB_ASIO
- Set to **1** to prefer the system installation of the Asio C++ asynchronous
- I/O library over the version provided with the MAME source.
+ Set to **1** to prefer the system installation of the Asio C++ asynchronous
+ I/O library over the version provided with the MAME source.
USE_SYSTEM_LIB_EXPAT
- Set to **1** to prefer the system installation of the Expat XML parser
- library over the version provided with the MAME source.
+ Set to **1** to prefer the system installation of the Expat XML parser
+ library over the version provided with the MAME source.
USE_SYSTEM_LIB_ZLIB
- Set to **1** to prefer the system installation of the zlib data compression
- library over the version provided with the MAME source.
+ Set to **1** to prefer the system installation of the zlib data compression
+ library over the version provided with the MAME source.
+USE_SYSTEM_LIB_ZSTD
+ Set to **1** to prefer the system installation of the Zstandard data
+ compression library over the version provided with the MAME source.
USE_SYSTEM_LIB_JPEG
- Set to **1** to prefer the system installation of the libjpeg image
- compression library over the version provided with the MAME source.
+ Set to **1** to prefer the system installation of the libjpeg image
+ compression library over the version provided with the MAME source.
USE_SYSTEM_LIB_FLAC
- Set to **1** to prefer the system installation of the libFLAC audio
- compression library over the version provided with the MAME source.
+ Set to **1** to prefer the system installation of the libFLAC audio
+ compression library over the version provided with the MAME source.
USE_SYSTEM_LIB_LUA
- Set to **1** to prefer the system installation of the embedded Lua
- interpreter over the version provided with the MAME source.
+ Set to **1** to prefer the system installation of the embedded Lua
+ interpreter over the version provided with the MAME source.
USE_SYSTEM_LIB_SQLITE3
- Set to **1** to prefer the system installation of the SQLITE embedded
- database engine over the version provided with the MAME source.
+ Set to **1** to prefer the system installation of the SQLITE embedded
+ database engine over the version provided with the MAME source.
USE_SYSTEM_LIB_PORTMIDI
- Set to **1** to prefer the system installation of the PortMidi library over
- the version provided with the MAME source.
+ Set to **1** to prefer the system installation of the PortMidi library over
+ the version provided with the MAME source.
USE_SYSTEM_LIB_PORTAUDIO
- Set to **1** to prefer the system installation of the PortAudio library over
- the version provided with the MAME source.
-USE_BUNDLED_LIB_SDL2
- Set to **1** to prefer the version of SDL provided with the MAME source over
- the system installation. (This is enabled by default for Visual Studio and
- Android builds. For other configurations, the system installation of SDL is
- preferred.)
+ Set to **1** to prefer the system installation of the PortAudio library over
+ the version provided with the MAME source.
USE_SYSTEM_LIB_UTF8PROC
- Set to **1** to prefer the system installation of the Julia utf8proc library
- over the version provided with the MAME source.
+ Set to **1** to prefer the system installation of the Julia utf8proc library
+ over the version provided with the MAME source.
USE_SYSTEM_LIB_GLM
- Set to **1** to prefer the system installation of the GLM OpenGL Mathematics
- library over the version provided with the MAME source.
+ Set to **1** to prefer the system installation of the GLM OpenGL Mathematics
+ library over the version provided with the MAME source.
USE_SYSTEM_LIB_RAPIDJSON
- Set to **1** to prefer the system installation of the Tencent RapidJSON
- library over the version provided with the MAME source.
+ Set to **1** to prefer the system installation of the Tencent RapidJSON
+ library over the version provided with the MAME source.
USE_SYSTEM_LIB_PUGIXML
- Set to **1** to prefer the system installation of the pugixml library over
- the version provided with the MAME source.
+ Set to **1** to prefer the system installation of the pugixml library over
+ the version provided with the MAME source.
.. _compiling-issues:
@@ -400,15 +735,9 @@ Known Issues
Issues with specific compiler versions
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-* GCC 5 for Linux reports spurious errors on encountering deprecation warnings.
- Adding **DEPRECATED=0** to your build options works around this by disabling
- deprecation warnings.
-* MinGW GCC 7 for Windows i386 produces spurious out-of-bounds access warnings.
+* GCC 7 for 32-bit x86 targets produces spurious out-of-bounds access warnings.
Adding **NOWERROR=1** to your build options works around this by not treating
warnings as errors.
-* Initial versions of GNU libstdc++ 6 have a broken ``std::unique_ptr``
- implementation. If you encounter errors with ``std::unique_ptr`` you need to
- upgrade to a newer version of libstdc++ that fixes the issue.
GNU C Library fortify source feature
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -422,12 +751,12 @@ support building with ``_FORTIFY_SOURCE`` defined.
Some Linux distributions (including Gentoo and Ubuntu) have patched GCC to
define ``_FORTIFY_SOURCE`` to ``1`` as a built-in macro. This is problematic
for more projects than just MAME, as it makes it hard to disable the additional
-checks (e.g. if you don't want the performance impact of the run-time checks),
+checks (e.g. if you don’t want the performance impact of the run-time checks),
and it also makes it hard to define ``_FORTIFY_SOURCE`` to ``2`` if you want to
enable stricter checks. You should really take it up with the distribution
-maintainers, and make it clear you don't want non-standard GCC behaviour. It
+maintainers, and make it clear you don’t want non-standard GCC behaviour. It
would be better if these distributions defined this macro by default in their
-packaging environments if they think it's important, rather than trying to force
+packaging environments if they think it’s important, rather than trying to force
it on everything compiled on their distributions. (This is what Red Hat does:
the ``_FORTIFY_SOURCE`` macro is set in the RPM build environment, and not by
distributing a modified version of GCC.)
@@ -445,24 +774,60 @@ around it by adding **-U_FORTIFY_SOURCE** to the compiler flags (e.g. by using
the **ARCHOPTS** setting, or setting the **CFLAGS** and **CXXFLAGS** environment
variables.
+Issues affecting Microsoft Visual Studio
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Microsoft introduced a new version of XAudio2 with Windows 8 that’s incompatible
+with the version included with DirectX for prior Windows versions at the API
+level. Newer versions of the Microsoft Windows SDK include headers and libraries
+for the new version of XAudio2. By default, the target Windows version is set to
+Windows Vista (6.0) when compiling MAME, which prevents the use of this version
+of the XAudio2 headers and libraries. To build MAME with XAudio2 support using
+the Microsoft Windows SDK, you must do one of the following:
+
+* Add ``MODERN_WIN_API=1`` to the options passed to make when generating the
+ Visual Studio project files. This will set the target Windows version to
+ Windows 8 (6.2). The resulting binaries may not run on earlier versions of
+ Windows.
+* Install the `DirectX SDK <https://www.microsoft.com/en-US/download/details.aspx?id=6812>`_ (already included since Windows 8.0 SDK and
+ automatically installed with Visual Studio 2013 and later). Configure the
+ **osd_windows** project to search the DirectX header/library paths before
+ searching the Microsoft Windows SDK paths.
+
+The MSVC compiler produces spurious warnings about potentially uninitialised
+local variables. You currently need to add ``NOWERROR=1`` to the options passed
+to make when generating the Visual Studio project files. This stops warnings
+from being treated as errors. (MSVC seems to lack options to control which
+specific warnings are treated as errors, which other compilers support.)
+
.. _compiling-unusual:
Unusual Build Configurations
----------------------------
+Linking using the LLVM linker
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The LLVM linker is generally faster than the GNU linker that GCC uses by
+default. This is more pronounced on systems with a high overhead for file
+system operations (e.g. Microsoft Windows, or when compiling on a disk mounted
+over a network). To use the LLVM linker with GCC, ensure the LLVM linker is
+installed and add ``-fuse-ld=lld`` to the linker options (e.g. in the
+**LDFLAGS** environment variable or in the **ARCHOPTS** setting).
+
Cross-compiling MAME
~~~~~~~~~~~~~~~~~~~~
-MAME's build system has basic support for cross-compilation. Set
+MAME’s build system has basic support for cross-compilation. Set
**CROSS_BUILD=1** to enable separate host and target compilers, set
**OVERRIDE_CC** and **OVERRIDE_CXX** to the target C/C++ compiler commands, and
if necessary set **CC** and **CXX** to the host C/C++ compiler commands. If the
target OS is different to the host OS, set it with **TARGETOS**. For example it
may be possible to build a MinGW32 x64 build on a Linux host using a command
-like this:
+like this::
-**make TARGETOS=windows PTR64=1 OVERRIDE_CC=x86_64-w64-mingw32-gcc OVERRIDE_CXX=x86_64-w64-mingw32-g++ OVERRIDE_LD=x86_64-w64-mingw32-ld MINGW64=/usr**
+ make TARGETOS=windows PTR64=1 OVERRIDE_CC=x86_64-w64-mingw32-gcc OVERRIDE_CXX=x86_64-w64-mingw32-g++ OVERRIDE_LD=x86_64-w64-mingw32-ld MINGW64=/usr**
(The additional packages required for producing a standard MinGW32 x64 build on
a Fedora Linux host are ``mingw64-gcc-c++``, ``mingw64-winpthreads-static`` and
@@ -471,14 +836,14 @@ their dependencies. Non-standard builds may require additional packages.)
Using libc++ on Linux
~~~~~~~~~~~~~~~~~~~~~
-MAME may be built using the LLVM project's "libc++" C++ Standard Library. The
+MAME may be built using the LLVM project’s “libc++” C++ Standard Library. The
prerequisites are a working clang/LLVM installation, and the libc++ development
libraries. On Fedora Linux, the necessary packages are **libcxx**,
**libcxx-devel**, **libcxxabi** and **libcxxabi-devel**. Set the C and C++
compiler commands to use clang, and add **-stdlib=libc++** to the C++ compiler
-and linker options. You could use a command like this:
+and linker options. You could use a command like this::
-**env LDFLAGS=-stdlib=libc++ make OVERRIDE_CC=clang OVERRIDE_CXX=clang++ ARCHOPTS_CXX=-stdlib=libc++ ARCHOPTS_OBJCXX=-stdlib=libc++**
+ env LDFLAGS=-stdlib=libc++ make OVERRIDE_CC=clang OVERRIDE_CXX=clang++ ARCHOPTS_CXX=-stdlib=libc++ ARCHOPTS_OBJCXX=-stdlib=libc++
The options following the **make** command may be placed in a prefix makefile if
you want to use this configuration regularly, but **LDFLAGS** needs to be be set
@@ -490,12 +855,12 @@ Using a GCC/GNU libstdc++ installation in a non-standard location on Linux
GCC may be built and installed to a custom location, typically by supplying the
**--prefix=** option to the **configure** command. This may be useful if you
want to build MAME on a Linux distribution that still uses a version of GNU
-libstdC++ that predates C++14 support. To use an alternate GCC installation to,
+libstdC++ that predates C++17 support. To use an alternate GCC installation to,
build MAME, set the C and C++ compilers to the full paths to the **gcc** and
**g++** commands, and add the library path to the run-time search path. If you
-installed GCC in /opt/local/gcc63, you might use a command like this:
+installed GCC in /opt/local/gcc72, you might use a command like this::
-**make OVERRIDE_CC=/opt/local/gcc63/bin/gcc OVERRIDE_CXX=/opt/local/gcc63/bin/g++ ARCHOPTS=-Wl,-R,/opt/local/gcc63/lib64**
+ make OVERRIDE_CC=/opt/local/gcc72/bin/gcc OVERRIDE_CXX=/opt/local/gcc72/bin/g++ ARCHOPTS=-Wl,-R,/opt/local/gcc72/lib64
You can add these options to a prefix makefile if you plan to use this
configuration regularly.
diff --git a/docs/source/initialsetup/configuringmame.rst b/docs/source/initialsetup/configuringmame.rst
new file mode 100644
index 00000000000..77eaf1e7a97
--- /dev/null
+++ b/docs/source/initialsetup/configuringmame.rst
@@ -0,0 +1,66 @@
+Configuring MAME
+================
+
+.. contents:: :local:
+
+Getting Started: A Quick Preface
+--------------------------------
+
+Once you have MAME installed, the next step is to configure it. There are
+several ways to do this, and each will be covered in turn.
+
+If you are on Windows, the MAME executable will be called ``mame.exe``.
+
+If you are on Linux or MacOS, the MAME executable will be called ``mame``.
+
+
+Initial Setup: Creating mame.ini From Command Line on Windows
+-------------------------------------------------------------
+
+First, you will need to *cd* to the directory where you installed MAME into.
+If, for instance, you have MAME installed in ``C:\Users\Public\MAME`` you will
+need to type ``cd C:\Users\Public\MAME`` into the command prompt.
+
+Then you have MAME create the config file by typing ``mame
+-createconfig``. MAME will then create the ``mame.ini`` file in the
+MAME installation folder. This file contains the default
+configuration settings for a new MAME installation.
+
+
+Initial Setup: Creating mame.ini From Command Line on Linux or MacOS
+--------------------------------------------------------------------
+
+The steps for Linux and MacOS are similar to those of Windows. If you
+installed MAME using the package manager that came from a Linux distro, you will
+type ``mame -createconfig`` into your terminal of choice.
+
+If you have compiled from source or downloaded a binary package of MAME,
+you will ``cd`` into the directory you put the MAME files into.
+
+For instance, ``cd /home/myusername/mame``
+
+Then you will type ``./mame -createconfig`` into
+your terminal of choice.
+
+You can then need to edit the ``mame.ini`` file in your favorite text editor,
+e.g. *Notepad* on Windows or *vi* on Linux/MacOS, or you can change settings
+from inside of MAME.
+
+
+Initial Setup: Graphical Setup
+------------------------------
+
+This is the easiest way to get started. Start MAME by opening the MAME
+icon in the location where you installed it. This will be ``mame.exe``
+on Windows, ``mame`` on Linux and macOS.
+
+Once MAME has started, you can either use your mouse to click on the
+**Configure Options** menu selection at the bottom center of your screen,
+or you can switch panes to the bottom one (default key is Tab), then press
+the menu accept button (default key is Return/Enter) to go into the
+Configuration menu.
+
+Choose **Save Configuration** to create the ``mame.ini`` file with default
+settings. From here, you can either continue to configure things from the
+graphical user interface or edit the ``mame.ini`` file in your favorite
+text editor.
diff --git a/docs/source/initialsetup/index.rst b/docs/source/initialsetup/index.rst
index bd3b3a0d80d..32319dd7367 100644
--- a/docs/source/initialsetup/index.rst
+++ b/docs/source/initialsetup/index.rst
@@ -1,7 +1,8 @@
Getting MAME prepared
---------------------
-This section covers initial preparation work needed to use MAME, including downloading and compiling MAME.
+This section covers initial preparation work needed to use MAME, including
+downloading MAME, compiling MAME from source, and configuring MAME.
.. toctree::
:titlesonly:
@@ -9,3 +10,4 @@ This section covers initial preparation work needed to use MAME, including downl
mameintro
installingmame
compilingmame
+ configuringmame
diff --git a/docs/source/initialsetup/installingmame.rst b/docs/source/initialsetup/installingmame.rst
index 3ace07ade80..c276b3d7a5c 100644
--- a/docs/source/initialsetup/installingmame.rst
+++ b/docs/source/initialsetup/installingmame.rst
@@ -4,10 +4,18 @@ Installing MAME
Microsoft Windows
-----------------
-You simply have to download the latest binary archive available from http://www.mamedev.org and to extract its content to a folder. You will end up with many files (below you will find explanations about some of these), and in particular ``MAME.EXE``. This is a command line program. The installation procedure ends here. Easy, isn't it?
+You simply have to download the latest binary archive available from
+http://www.mamedev.org and to extract its content to a folder. You will end up
+with many files (below you will find explanations about some of these), and in
+particular **mame.exe**. This is a command line program. The installation
+procedure ends here. Easy, isn’t it?
Other Operating Systems
-----------------------
-In this case, you can either look for pre-compiled (SDL)MAME binaries (e.g. in the repositories of your favorite Linux distro) which should simply extract all the needed files in a folder you choose, or compile the source code by yourself. In the latter case, see our section on :ref:`compiling-all`.
+In this case, you can either look for pre-compiled (SDL)MAME binaries (e.g. in
+the repositories of your favorite Linux distro) which should simply extract all
+the needed files in a folder you choose, or compile the source code by
+yourself. In the latter case, see our section on
+:ref:`compiling MAME <compiling-all>`.
diff --git a/docs/source/initialsetup/mameintro.rst b/docs/source/initialsetup/mameintro.rst
index b63a6b3beda..61be99b68a9 100644
--- a/docs/source/initialsetup/mameintro.rst
+++ b/docs/source/initialsetup/mameintro.rst
@@ -1,64 +1,122 @@
An Introduction to MAME
-=======================
+-----------------------
-MAME, formerly was an acronym which stood for Multi Arcade Machine Emulator, documents and reproduces through emulation the inner components of arcade machines, computers, consoles, chess computers, calculators, and many other types of electronic amusement machines. As a nice side-effect, MAME allows to use on a modern PC those programs and games which were originally developed for the emulated machines.
+MAME, formerly an acronym which stood for Multi Arcade Machine Emulator,
+documents and reproduces through emulation the inner components of arcade
+machines, computers, consoles, chess computers, calculators, and many other
+types of electronic amusement machines. As a nice side-effect, MAME allows to
+use on a modern PC those programs and games which were originally developed for
+the emulated machines.
-At one point there were actually two separate projects, MAME and MESS. MAME covered arcade machines, while MESS covered everything else. They are now merged into the one MAME.
+At one point there were actually two separate projects, MAME and MESS. MAME
+covered arcade video games, while MESS covered home and business systems. They
+are now merged into the one MAME.
-MAME is mostly programmed in C with some core components in C++. MAME can currently emulate over 32000 individual systems from the last 5 decades.
+MAME is written in C++ and can currently emulate over 32,000 individual systems
+from the last five decades.
Purpose of MAME
-===============
+---------------
-The primary purpose of MAME is to preserve decades of arcade, computer, and console history. As technology continues to rush forward, MAME prevents these important “vintage” systems from being lost and forgotten.
+The primary purpose of MAME is to preserve decades of arcade, computer, and
+console history. As technology continues to rush forward, MAME prevents these
+important “vintage” systems from being lost and forgotten.
Systems Emulated by MAME
-========================
-
-
-ProjectMESS contains a complete list of the systems currently emulated. As you will notice, being supported does not always mean that the status of the emulation is perfect. You may want
-
-1. to check the status of the emulation in the wiki pages of each system, accessible from the drivers page (e.g. for Apple Macintosh, from the page for the mac.c driver you can reach the pages for both **macplus** and **macse**),
-2. to read the corresponding **sysinfo.dat** entry in order to better understand which issues you may encounter while running a system in MAME (again, for Apple Macintosh Plus you have to check this entry).
-
-Alternatively, you can simply see the status by yourself, launching the system emulation and taking a look to the red or yellow warning screen which appears before the emulation starts, if any. Notice that if you have information which can help to improve the emulation of a supported system, or if you can directly contribute fixes and/or addition to the current source, you can follow the instructions at the contact page or post to the MAME Forums at http://forum.mamedev.org/
+------------------------
+
+The `Arcade Database <http://adb.arcadeitalia.net/>`_ contains a complete list
+of the systems currently emulated. As you will notice, being supported does not
+always mean that the status of the emulation is perfect. You may want
+
+1. to check the status of the emulation in the wiki pages of each system,
+ accessible from the drivers page (e.g. for Apple Macintosh, from the page for
+ the mac128.cpp driver you can reach the pages for both **macplus** and
+ **macse**),
+2. to read the corresponding **sysinfo.dat** entry in order to better understand
+ which issues you may encounter while running a system in MAME (again, for
+ Apple Macintosh Plus you have to check this entry).
+
+Alternatively, you can simply see the status by yourself, launching the system
+emulation and taking a look at the red or yellow warning screen which appears
+before the emulation starts, if any. Notice that if you have information which
+can help to improve the emulation of a supported system, or if you can directly
+contribute fixes and/or addition to the current source, you can do any of the
+following:
+
+* Send in a pull request (for code) or open an issue (information) on our
+ `GitHub page <https://github.com/mamedev/mame/>`_
+* Post the information or code on the
+ `MAME Forums <https://forum.mamedev.org/>`_
+* Follow the instructions on our
+ `contact page <https://www.mamedev.org/contact.html>`_
Supported OS
-============
-
-The current source code can be directly compiled under all the main OSes: Microsoft Windows (both with DirectX/BGFX native support or with SDL support), Linux, FreeBSD, and Mac OS X. Also, both 32-bit and 64-bit are supported, but be aware 64-bit often shows significant speed increases.
+------------
+The current source code can be directly compiled under all the main operating
+systems: Microsoft Windows (both with DirectX/BGFX native support or with SDL
+support), Linux, FreeBSD, and macOS.
System Requirements
-===================
+-------------------
-MAME is written in fairly generic C/C++, and has been ported to numerous platforms. Over time, as computer hardware has evolved, the MAME code has evolved as well to take advantage of the greater processing power and hardware capabilities offered.
+MAME is written in C++, and has been ported to numerous platforms. Over time, as
+computer hardware has evolved, the MAME code has evolved as well to take
+advantage of the greater processing power and hardware capabilities offered.
-The official MAME binaries are compiled and designed to run on a standard Windows-based system. The minimum requirements are:
+The official MAME binaries are compiled and designed to run on a standard
+Windows-based system. The minimum requirements are:
-* Intel Core series CPU or equivalent, at least 2.0 GHz
-* 32-bit OS (Vista SP1 or later on Windows, 10.9 or later on Mac)
+* Intel Core 2-series CPU or equivalent, at least 2.0 GHz
+* 64-bit OS (Windows 7 or later on Windows, macOS 10.9 or later on Mac)
* 4 GB RAM
* DirectX 9.0c for Windows
* A Direct3D, or OpenGL capable graphics card
-* Any DirectSound capable sound card/onboard audio
-Of course, the minimum requirements are just that: minimal. You may not get optimal performance from such a system, but MAME should run. Modern versions of MAME require more power than older versions, so if you have a less-capable PC, you may find that using an older version of MAME may get you better performance, at the cost of greatly lowered accuracy and fewer supported systems.
+Of course, the minimum requirements are just that: minimal. You may not get
+optimal performance from such a system, but MAME should run. Modern versions of
+MAME require more power than older versions, so if you have a less-capable PC,
+you may find that using an older version of MAME may get you better
+performance, at the cost of greatly lowered accuracy and fewer supported
+systems.
-MAME will take advantage of 3D hardware for compositing artwork and scaling the games to full screen. To make use of this, you should have a modern Direct3D 8-capable video card with at least 16MB of video RAM.
+MAME will take advantage of 3D hardware for compositing artwork and scaling
+displayed software to full screen. To make use of this, you should have at least
+a semi-modern computer with semi-modern 3D hardware made within the last five
+to ten years.
-HLSL or GLSL special effects such as CRT simulation will put a very heavy load on your video card, especially at higher resolutions. You will need a fairly powerful modern video card, and the load on your video card goes up exponentially as your resolution increases. If HLSL or GLSL are too intensive, try dropping your output resolution.
+HLSL or GLSL special effects such as CRT simulation will put a very heavy load
+on your video card, especially at higher resolutions. You will need a fairly
+powerful modern video card, and the load on your video card goes up
+exponentially as your resolution increases. If HLSL or GLSL are too intensive,
+try reducing your output resolution.
-Keep in mind that even on the fastest computers available, MAME is still incapable of playing some systems at full speed. The goal of the project isn't to make all system run speedy on your system; the goal is to document the hardware and reproduce the behavior of the hardware as faithfully as possible.
+Keep in mind that even on the fastest computers available, MAME is still
+incapable of playing some systems at full speed. The goal of the project isn’t
+to make all system run speedy on your system; the goal is to document the
+hardware and reproduce the behavior of the hardware as faithfully as possible.
BIOS Dumps and Software
-----------------------
-Most of the systems emulated by MAME requires a dump of the internal chips of the original system. These can be obtained by extracting the data from an original unit, or finding them (at your own risk) in the WorldWideWeb. Being copyrighted material, MAME does not come with any of these.
+Most of the systems emulated by MAME requires a dump of the internal chips of
+the original system. These can be obtained by extracting the data from an
+original unit, or finding them (at your own risk) on various place on the
+Internet. Being copyrighted material, MAME does not come with any of these.
+
+Also, you may want to find some software to be run on the emulated machine
+where it does not have internal software (e.g. some computers will need a
+disk to boot to an operating system).
-Also, you may want to find some software to be run on the emulated machine. Again, Google and other search engines are your best friends. MAME does not provide any software to be run on the emulated machines because it is very often (almost always, in the case of console software) copyrighted material.
+Again, Google and other search engines are your best friends. MAME does not
+provide any software in the MAME package to be run on the emulated machines
+because it is very often (almost always, in the case of console software)
+protected by copyright.
+The MAME team has been permitted to redistribute some old software, which can be
+found in the `ROMS section of the MAME site <https://www.mamedev.org/roms/>`_.
diff --git a/docs/source/license.rst b/docs/source/license.rst
index db2eb2f41d0..b8fae5d341b 100644
--- a/docs/source/license.rst
+++ b/docs/source/license.rst
@@ -2,11 +2,17 @@ The MAME License
================
-The MAME project as a whole is distributed under the terms of the `GNU General Public License, version 2 or later <http://opensource.org/licenses/GPL-2.0>`_ (GPL-2.0+), since it contains code made available under multiple GPL-compatible licenses. A great majority of files (over 90% including core files) are under the `BSD-3-Clause License <http://opensource.org/licenses/BSD-3-Clause>`_ and we would encourage new contributors to distribute files under this license.
+The MAME project as a whole is distributed under the terms of the
+`GNU General Public License, version 2 or later <http://opensource.org/licenses/GPL-2.0>`_ (GPL-2.0+),
+since it contains code made available under multiple GPL-compatible licenses.
+A great majority of files (over 90% including core files) are under the
+`3-Clause BSD License <http://opensource.org/licenses/BSD-3-Clause>`_ and we
+would encourage new contributors to distribute files under this license.
-Please note that MAME is a registered trademark of Gregory Ember, and permission is required to use the "MAME" name, logo, or wordmark.
+Please note that MAME is a registered trademark of Gregory Ember, and permission
+is required to use the “MAME” name, logo, or wordmark.
- Copyright (C) 1997-2019 MAMEDev and contributors
+ Copyright (c) 1997-2025 MAMEDev and contributors
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -22,4 +28,5 @@ Please note that MAME is a registered trademark of Gregory Ember, and permission
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
-Please see `LICENSE.md <https://github.com/mamedev/mame/blob/master/LICENSE.md>`_ for further details.
+Please see the `license information <https://github.com/mamedev/mame/blob/master/COPYING>`_
+for further details.
diff --git a/docs/source/luascript/index.rst b/docs/source/luascript/index.rst
new file mode 100644
index 00000000000..7ba5a0a8caf
--- /dev/null
+++ b/docs/source/luascript/index.rst
@@ -0,0 +1,235 @@
+.. _luascript:
+
+Lua Scripting Interface
+=======================
+
+.. contents:: :local:
+
+
+.. _luascript-intro:
+
+Introduction
+------------
+
+MAME provides Lua script bindings for a useful set of core functionality. This
+feature first appeared in version 0.148, when a minimal Lua interface was
+implemented. Today, the Lua interface is rich enough to let you inspect and
+manipulate device state, access CPU registers, read and write memory, and draw
+custom graphical overlays.
+
+There are three ways to use MAME’s Lua scripting capabilities:
+
+* Using the :ref:`interactive Lua console <luascript-console>`, enabled by the
+ :ref:`console option <mame-commandline-console>`.
+* By providing a script file to run using the :ref:`-autoboot_script option
+ <mame-commandline-autobootscript>`. The :ref:`-autoboot_delay option
+ <mame-commandline-autobootdelay>` controls how long MAME waits after starting
+ the emulated system before running the script.
+* By writing :ref:`Lua plugins <plugins>`. Several plugins are included with
+ MAME.
+
+Internally, MAME makes extensive use of `Sol3 <https://github.com/ThePhD/sol2>`_
+to implement Lua bindings.
+
+The Lua API is not yet declared stable and may suddenly change without prior
+notice. However, we expose methods to let you know at runtime which API version
+you are running against, and most objects support some level of runtime
+introspection.
+
+
+.. _luascript-features:
+
+Features
+--------
+
+The API is not yet complete, but this is a partial list of capabilities exposed
+to Lua scripts:
+
+* Session information (application version, current emulated system)
+* Session control (starting, pausing, resetting, stopping)
+* Event hooks (on frame painting and on user events)
+* Device introspection (device tree listing, memory and register enumeration)
+* Screen introspection (screens listing, screen details, frame counting)
+* Screen overlay drawing (text, lines, boxes on multiple screens)
+* Memory read/write (8/16/32/64 bits, signed and unsigned)
+* Register and state control (state enumeration, get and set)
+
+
+.. _luascript-api:
+
+API reference
+-------------
+
+.. toctree::
+ :maxdepth: 2
+
+ ref-common
+ ref-core
+ ref-devices
+ ref-mem
+ ref-input
+ ref-render
+ ref-debugger
+
+
+.. _luascript-console:
+
+Interactive Lua console tutorial
+--------------------------------
+
+First run an arcade game in MAME at the command prompt with the ``-console``
+and ``-window`` options to enable the Lua console:
+
+::
+
+ $ mame -console -window YOUR_SYSTEM
+ /| /| /| /| /| _______
+ / | / | / | / | / | / /
+ / |/ | / | / |/ | / ____/
+ / | / | / | / /_
+ / |/ | / |/ __/
+ / /| /| /| |/ /| /| /____
+ / / | / | / | / | / | /
+ / _/ |/ / / |___/ |/ /_______/
+ / /
+ / _/
+
+ mame 0.255
+ Copyright (C) Nicola Salmoria and the MAME team
+
+ Lua 5.4
+ Copyright (C) Lua.org, PUC-Rio
+
+ [MAME]>
+
+At this point, your game is probably running in attract mode. Let’s pause it:
+
+::
+
+ [MAME]> emu.pause()
+ [MAME]>
+
+Even without textual feedback on the console, you’ll notice the game is now
+paused. In general, commands are quiet and only print error messages.
+
+You can check the version of MAME you are running with:
+
+::
+
+ [MAME]> print(emu.app_name() .. " " .. emu.app_version())
+ mame 0.255
+
+Let’s examine the emulated screens. First, enumerate the :ref:`screen devices
+<luascript-ref-screendev>` in the system:
+
+::
+
+ [MAME]> for tag, screen in pairs(manager.machine.screens) do print(tag) end
+ :screen
+
+``manager.machine`` is the :ref:`running machine <luascript-ref-machine>` object
+for the current emulation session. We will be using this frequently.
+``screens`` is a :ref:`device enumerator <luascript-ref-devenum>` that yields
+all emulated screens in the system. Most arcade games only have one main
+screen. In our case, the main and only screen has the absolute tag ``:screen``.
+We can examine it further:
+
+::
+
+ [MAME]> -- keep a reference to the main screen in a variable
+ [MAME]> s = manager.machine.screens[':screen']
+ [MAME]> print(s.width .. 'x' .. s.height)
+ 320x224
+
+Several methods are available for drawing an overlay on the screen using lines,
+rectangles and text:
+
+::
+
+ [MAME]> -- define a function for drawing an overlay and call it
+ [MAME]> function draw_overlay()
+ [MAME]>> s:draw_text(40, 40, 'foo') -- (x0, y0, msg)
+ [MAME]>> s:draw_box(20, 20, 80, 80, 0xff00ffff, 0) -- (x0, y0, x1, y1, line-color, fill-color)
+ [MAME]>> s:draw_line(20, 20, 80, 80, 0xff00ffff) -- (x0, y0, x1, y1, line-color)
+ [MAME]>> end
+ [MAME]> draw_overlay()
+
+This will draw some useless lines and text over the screen. However, when the
+emulated system is resumed, your overlay needs to be refreshed or it will just
+disappear. In order to do this, you have to register your function to be called
+on every video update:
+
+::
+
+ [MAME]> emu.register_frame_done(draw_overlay, 'frame')
+
+All colors are specified in ARGB format (eight bits per channel). The
+coordinate origin (0,0) normally corresponds to the top-left corner of the
+screen.
+
+As with screens, you can examine all the emulated devices in the running system:
+
+::
+
+ [MAME]> for tag, device in pairs(manager.machine.devices) do print(tag) end
+ :audiocpu
+ :maincpu
+ :saveram
+ :screen
+ :palette
+ [...]
+
+For some of them, you can also inspect and manipulate memory and state:
+
+::
+
+ [MAME]> cpu = manager.machine.devices[':maincpu']
+ [MAME]> -- enumerate, read and write register state
+ [MAME]> for k, v in pairs(cpu.state) do print(k) end
+ CURPC
+ rPC
+ IR
+ CURFLAGS
+ SSR
+ D0
+ [...]
+ [MAME]> print(cpu.state["D0"].value)
+ 303
+ [MAME]> cpu.state['D0'].value = 255
+ [MAME]> print(cpu.state['D0'].value)
+ 255
+
+::
+
+ [MAME]> -- inspect memory
+ [MAME]> for name, space in pairs(cpu.spaces) do print(name) end
+ program
+ cpu_space
+ [MAME]> mem = cpu.spaces['program']
+ [MAME]> print(mem:read_i8(0xc000))
+ 41
+
+Note that many objects support symbol completion if you type part of a method or
+property name and press the Tab key:
+
+::
+
+ [MAME]>print(mem:read_<TAB>
+ read_direct_i8
+ read_u16
+ read_range
+ read_direct_u16
+ read_direct_i64
+ read_i64
+ read_i32
+ read_direct_u64
+ read_i8
+ read_u32
+ read_u8
+ read_u64
+ read_direct_u32
+ read_direct_i16
+ read_direct_i32
+ read_direct_u8
+ read_i16
+ [MAME]>print(mem:read_direct_i8
diff --git a/docs/source/luascript/ref-common.rst b/docs/source/luascript/ref-common.rst
new file mode 100644
index 00000000000..6a7c735951c
--- /dev/null
+++ b/docs/source/luascript/ref-common.rst
@@ -0,0 +1,124 @@
+.. _luascript-ref-common:
+
+Lua Common Types and Globals
+============================
+
+.. contents::
+ :local:
+ :depth: 1
+
+
+.. _luascript-ref-containers:
+
+Containers
+----------
+
+Many properties yield container wrappers. Container wrappers are cheap to
+create, and provide an interface that is similar to a read-only table. The
+complexity of operations may vary. Container wrappers usually provide most of
+these operations:
+
+#c
+ Get the number of items in the container.
+c[k]
+ Returns the item corresponding to the key ``k``, or ``nil`` if the key is
+ not present.
+pairs(c)
+ Iterate over container by key and value. The key is what you would pass to
+ the index operator or the ``get`` method to get the value.
+ipairs(c)
+ Iterate over container by index and value. The index is what you would pass
+ to the ``at`` method to get the value (this may be the same as the key for
+ some containers).
+c:empty()
+ Returns a Boolean indicating whether there are no items in the container.
+c:get(k)
+ Returns the item corresponding to the key ``k``, or ``nil`` if the key is
+ not present. Usually equivalent to the index operator.
+c:at(i)
+ Returns the value at the 1-based index ``i``, or ``nil`` if it is out of
+ range.
+c:find(v)
+ Returns the key for item ``v``, or ``nil`` if it is not in the container.
+ The key is what you would pass to the index operator to get the value.
+c:index_of(v)
+ Returns the 1-based index for item ``v``, or ``nil`` if it is not in the
+ container. The index is what you would pass to the ``at`` method to get the
+ value.
+
+
+.. _luascript-ref-emu:
+
+Emulator interface
+------------------
+
+The emulator interface ``emu`` provides access to core functionality. Many
+classes are also available as properties of the emulator interface.
+
+Methods
+~~~~~~~
+
+emu.wait(duration, …)
+ Yields for the specified duration in terms of emulated time. The duration
+ may be specified as an :ref:`attotime <luascript-ref-attotime>` or a number
+ in seconds. Any additional arguments are returned from the coroutine.
+ Returns a Boolean indicating whether the duration expired normally.
+
+ All outstanding calls to ``emu.wait`` will return ``false`` immediately if a
+ saved state is loaded or the emulation session ends. Calling this function
+ from callbacks that are not run as coroutines will raise an error.
+emu.wait_next_update(…)
+ Yields until the next video/UI update. Any arguments are returned from the
+ coroutine. Calling this function from callbacks that are not run as coroutines
+ will raise an error.
+emu.wait_next_frame(…)
+ Yields until the next emulated frame completes. Any arguments are returned
+ from the coroutine. Calling this function from callbacks that are not run as
+ coroutines will raise an error.
+emu.add_machine_reset_notifier(callback)
+ Add a callback to receive notifications when the emulated system is reset.
+ Returns a :ref:`notifier subscription <luascript-ref-notifiersub>`.
+emu.add_machine_stop_notifier(callback)
+ Add a callback to receive notifications when the emulated system is stopped.
+ Returns a :ref:`notifier subscription <luascript-ref-notifiersub>`.
+emu.add_machine_pause_notifier(callback)
+ Add a callback to receive notifications when the emulated system is paused.
+ Returns a :ref:`notifier subscription <luascript-ref-notifiersub>`.
+emu.add_machine_resume_notifier(callback)
+ Add a callback to receive notifications when the emulated system is resumed
+ after being paused. Returns a
+ :ref:`notifier subscription <luascript-ref-notifiersub>`.
+emu.add_machine_frame_notifier(callback)
+ Add a callback to receive notifications when an emulated frame completes.
+ Returns a :ref:`notifier subscription <luascript-ref-notifiersub>`.
+emu.add_machine_pre_save_notifier(callback)
+ Add a callback to receive notification before the emulated system state is
+ saved. Returns a
+ :ref:`notifier subscription <luascript-ref-notifiersub>`.
+emu.add_machine_post_load_notifier(callback)
+ Add a callback to receive notification after the emulated system is restored
+ to a previously saved state. Returns a
+ :ref:`notifier subscription <luascript-ref-notifiersub>`.
+emu.register_sound_update(callback)
+ Add a callback to receive new samples that have been created. The samples
+ are coming from the sound devices for which the hook property has been set
+ to true. The callback gets one parameter which is a hash with device tag
+ as key and a (channel-sized) vector of (buffer-sized) vector of samples
+ in the -1..1 range.
+emu.print_error(message)
+ Print an error message.
+emu.print_warning(message)
+ Print a warning message.
+emu.print_info(message)
+ Print an informational message.
+emu.print_verbose(message)
+ Print a verbose diagnostic message (disabled by default).
+emu.print_debug(message)
+ Print a debug message (only enabled for debug builds by default).
+emu.lang_translate([context], message)
+ Look up a message with optional context in the current localised message
+ catalog. Returns the message unchanged if no corresponding localised
+ message is found.
+emu.subst_env(string)
+ Substitute environment variables in a string. The syntax is dependent on
+ the host operating system.
diff --git a/docs/source/luascript/ref-core.rst b/docs/source/luascript/ref-core.rst
new file mode 100644
index 00000000000..ad6dc24d330
--- /dev/null
+++ b/docs/source/luascript/ref-core.rst
@@ -0,0 +1,631 @@
+.. _luascript-ref-core:
+
+Lua Core Classes
+================
+
+Many of MAME’s core classes used to implement an emulation session are available
+to Lua scripts.
+
+.. contents::
+ :local:
+ :depth: 1
+
+
+.. _luascript-ref-notifiersub:
+
+Notifier subscription
+---------------------
+
+Wraps MAME’s ``util::notifier_subscription`` class, which manages a subscription
+to a broadcast notification.
+
+Methods
+~~~~~~~
+
+subscription:unsubscribe()
+ Unsubscribes from notifications. The subscription will become inactive and
+ no future notifications will be received.
+
+Properties
+~~~~~~~~~~
+
+subscription.is_active (read-only)
+ A Boolean indicating whether the subscription is active. A subscription
+ becomes inactive after explicitly unsubscribing or if the underlying
+ notifier is destroyed.
+
+
+.. _luascript-ref-attotime:
+
+Attotime
+--------
+
+Wraps MAME’s ``attotime`` class, which represents a high-precision time
+interval. Attotime values support addition and subtraction with other attotime
+values, and multiplication and division by integers.
+
+Instantiation
+~~~~~~~~~~~~~
+
+emu.attotime()
+ Creates an attotime value representing zero (i.e. no elapsed time).
+emu.attotime(seconds, attoseconds)
+ Creates an attotime with the specified whole and fractional parts.
+emu.attotime(attotime)
+ Creates a copy of an existing attotime value.
+emu.attotime.from_double(seconds)
+ Creates an attotime value representing the specified number of seconds.
+emu.attotime.from_ticks(periods, frequency)
+ Creates an attotime representing the specified number of periods of the
+ specified frequency in Hertz.
+emu.attotime.from_seconds(seconds)
+ Creates an attotime value representing the specified whole number of
+ seconds.
+emu.attotime.from_msec(milliseconds)
+ Creates an attotime value representing the specified whole number of
+ milliseconds.
+emu.attotime.from_usec(microseconds)
+ Creates an attotime value representing the specified whole number of
+ microseconds.
+emu.attotime.from_nsec(nanoseconds)
+ Creates an attotime value representing the specified whole number of
+ nanoseconds.
+
+Methods
+~~~~~~~
+
+t:as_double()
+ Returns the time interval in seconds as a floating-point value.
+t:as_hz()
+ Interprets the interval as a period and returns the corresponding frequency
+ in Hertz as a floating-point value. Returns zero if ``t.is_never`` is true.
+ The interval must not be zero.
+t:as_khz()
+ Interprets the interval as a period and returns the corresponding frequency
+ kilohertz as a floating-point value. Returns zero if ``t.is_never`` is
+ true. The interval must not be zero.
+t:as_mhz()
+ Interprets the interval as a period and returns the corresponding frequency
+ megahertz as a floating-point value. Returns zero if ``t.is_never`` is
+ true. The interval must not be zero.
+t:as_ticks(frequency)
+ Returns the interval as a whole number of periods at the specified
+ frequency. The frequency is specified in Hertz.
+
+Properties
+~~~~~~~~~~
+
+t.is_zero (read-only)
+ A Boolean indicating whether the value represents no elapsed time.
+t.is_never (read-only)
+ A Boolean indicating whether the value is greater than the maximum number of
+ whole seconds that can be represented (treated as an unreachable time in the
+ future or overflow).
+t.attoseconds (read-only)
+ The fraction seconds portion of the interval in attoseconds.
+t.seconds (read-only)
+ The number of whole seconds in the interval.
+t.msec (read-only)
+ The number of whole milliseconds in the fractional seconds portion of the
+ interval.
+t.usec (read-only)
+ The number of whole microseconds in the fractional seconds portion of the
+ interval.
+t.nsec (read-only)
+ The number of whole nanoseconds in the fractional seconds portion of the
+ interval.
+
+
+.. _luascript-ref-mameman:
+
+MAME machine manager
+--------------------
+
+Wraps MAME’s ``mame_machine_manager`` class, which holds the running machine, UI
+manager, and other global components.
+
+Instantiation
+~~~~~~~~~~~~~
+
+manager
+ The MAME machine manager is available as a global variable in the Lua
+ environment.
+
+Properties
+~~~~~~~~~~
+
+manager.machine (read-only)
+ The :ref:`running machine <luascript-ref-machine>` for the current emulation
+ session.
+manager.ui (read-only)
+ The :ref:`UI manager <luascript-ref-uiman>` for the current session.
+manager.options (read-only)
+ The :ref:`emulation options <luascript-ref-emuopts>` for the current
+ session.
+manager.plugins[] (read-only)
+ Gets information about the :ref:`Lua plugins <luascript-ref-plugin>` that
+ are present, indexed by name. The index get, ``at`` and ``index_of``
+ methods have O(n) complexity.
+
+
+.. _luascript-ref-machine:
+
+Running machine
+---------------
+
+Wraps MAME’s ``running_machine`` class, which represents an emulation session.
+It provides access to the other core objects that implement an emulation session
+as well as the emulated device tree.
+
+Instantiation
+~~~~~~~~~~~~~
+
+manager.machine
+ Gets the running machine instance for the current emulation session.
+
+Methods
+~~~~~~~
+
+machine:exit()
+ Schedules an exit from the current emulation session. This will either
+ return to the system selection menu or exit the application, depending on
+ how it was started. This method returns immediately, before the scheduled
+ exit takes place.
+machine:hard_reset()
+ Schedules a hard reset. This is implemented by tearing down the emulation
+ session and starting another emulation session for the same system. This
+ method returns immediately, before the scheduled reset takes place.
+machine:soft_reset()
+ Schedules a soft reset. This is implemented by calling the reset method of
+ the root device, which is propagated down the device tree. This method
+ returns immediately, before the scheduled reset takes place.
+machine:save(filename)
+ Schedules saving machine state to the specified file. If the file name is a
+ relative path, it is considered to be relative to the first configured save
+ state directory. This method returns immediately, before the machine state
+ is saved. If this method is called when a save or load operation is already
+ pending, the previously pending operation will be cancelled.
+machine:load(filename)
+ Schedules loading machine state from the specified file. If the file name
+ is a relative path, the configured save state directories will be searched.
+ This method returns immediately, before the machine state is saved. If this
+ method is called when a save or load operation is already pending, the
+ previously pending operation will be cancelled.
+machine:popmessage([msg])
+ Displays a pop-up message to the user. If the message is not provided, the
+ currently displayed pop-up message (if any) will be hidden.
+machine:logerror(msg)
+ Writes the message to the machine error log. This may be displayed in a
+ debugger window, written to a file, or written to the standard error output.
+
+Properties
+~~~~~~~~~~
+
+machine.time (read-only)
+ The elapsed emulated time for the current session as an
+ :ref:`attotime <luascript-ref-attotime>`.
+machine.system (read-only)
+ The :ref:`driver metadata <luascript-ref-driver>` for the current
+ system.
+machine.parameters (read-only)
+ The :ref:`parameters manager <luascript-ref-paramman>` for the current
+ emulation session.
+machine.video (read-only)
+ The :ref:`video manager <luascript-ref-videoman>` for the current emulation
+ session.
+machine.sound (read-only)
+ The :ref:`sound manager <luascript-ref-soundman>` for the current emulation
+ session.
+machine.output (read-only)
+ The :ref:`output manager <luascript-ref-outputman>` for the current
+ emulation session.
+machine.memory (read-only)
+ The :ref:`emulated memory manager <luascript-ref-memman>` for the current
+ session.
+machine.ioport (read-only)
+ The :ref:`I/O port manager <luascript-ref-ioportman>` for the current
+ emulation session.
+machine.input (read-only)
+ The :ref:`input manager <luascript-ref-inputman>` for the current emulation
+ session.
+machine.natkeyboard (read-only)
+ Gets the :ref:`natural keyboard manager <luascript-ref-natkbdman>`, used for
+ controlling keyboard and keypad input to the emulated system.
+machine.uiinput (read-only)
+ The :ref:`UI input manager <luascript-ref-uiinputman>` for the current
+ emulation session.
+machine.render (read-only)
+ The :ref:`render manager <luascript-ref-renderman>` for the current
+ emulation session.
+machine.debugger (read-only)
+ The :ref:`debugger manager <luascript-ref-debugman>` for the current
+ emulation session, or ``nil`` if the debugger is not enabled.
+machine.options (read-only)
+ The user-specified :ref:`options <luascript-ref-emuopts>` for the current
+ emulation session.
+machine.samplerate (read-only)
+ The output audio sample rate in Hertz.
+machine.paused (read-only)
+ A Boolean indicating whether emulation is not currently running, usually
+ because the session has been paused or the emulated system has not completed
+ starting.
+machine.exit_pending (read-only)
+ A Boolean indicating whether the emulation session is scheduled to exit.
+machine.hard_reset_pending (read-only)
+ A Boolean indicating whether a hard reset of the emulated system is pending.
+machine.devices (read-only)
+ A :ref:`device enumerator <luascript-ref-devenum>` that yields all
+ :ref:`devices <luascript-ref-device>` in the emulated system.
+machine.palettes (read-only)
+ A :ref:`device enumerator <luascript-ref-devenum>` that yields all
+ :ref:`palette devices <luascript-ref-dipalette>` in the emulated system.
+machine.screens (read-only)
+ A :ref:`device enumerator <luascript-ref-devenum>` that yields all
+ :ref:`screen devices <luascript-ref-screendev>` in the emulated system.
+machine.cassettes (read-only)
+ A :ref:`device enumerator <luascript-ref-devenum>` that yields all
+ :ref:`cassette image devices <luascript-ref-cassdev>` in the emulated
+ system.
+machine.images (read-only)
+ A :ref:`device enumerator <luascript-ref-devenum>` that yields all
+ :ref:`media image devices <luascript-ref-diimage>` in the emulated system.
+machine.slots (read-only)
+ A :ref:`device enumerator <luascript-ref-devenum>` that yields all
+ :ref:`slot devices <luascript-ref-dislot>` in the emulated system.
+
+
+.. _luascript-ref-videoman:
+
+Video manager
+-------------
+
+Wraps MAME’s ``video_manager`` class, which is responsible for coordinating
+emulated video drawing, speed throttling, and reading host inputs.
+
+Instantiation
+~~~~~~~~~~~~~
+
+manager.machine.video
+ Gets the video manager for the current emulation session.
+
+Methods
+~~~~~~~
+
+video:frame_update()
+ Updates emulated screens, reads host inputs, and updates video output.
+video:snapshot()
+ Saves snapshot files according to the current configuration. If MAME is
+ configured to take native emulated screen snapshots, one snapshot will be
+ saved for each emulated screen that is visible in a host window/screen with
+ the current view configuration. If MAME is not configured to use take
+ native emulated screen snapshots or if the system has no emulated screens, a
+ single snapshot will be saved using the currently selected snapshot view.
+video:begin_recording([filename], [format])
+ Stops any video recordings currently in progress and starts recording either
+ the visible emulated screens or the current snapshot view, depending on
+ whether MAME is configured to take native emulated screen snapshots.
+
+ If the file name is not supplied, the configured snapshot file name is used.
+ If the file name is a relative path, it is interpreted relative to the first
+ configured snapshot directory. If the format is supplied, it must be
+ ``"avi"`` or ``"mng"``. If the format is not supplied, it defaults to AVI.
+video:end_recording()
+ Stops any video recordings that are in progress.
+video:snapshot_size()
+ Returns the width and height in pixels of snapshots created with the current
+ snapshot target configuration and emulated screen state. This may be
+ configured explicitly by the user, or calculated based on the selected
+ snapshot view and the resolution of any visible emulated screens.
+video:snapshot_pixels()
+ Returns the pixels of a snapshot created using the current snapshot target
+ configuration as 32-bit integers packed into a binary string in host Endian
+ order. Pixels are organised in row-major order, from left to right then top
+ to bottom. Pixel values are colours in RGB format packed into 32-bit
+ integers.
+
+Properties
+~~~~~~~~~~
+
+video.speed_factor (read-only)
+ Configured emulation speed adjustment in per mille (i.e. the ratio to normal
+ speed multiplied by 1,000).
+video.throttled (read/write)
+ A Boolean indicating whether MAME should wait before video updates to avoid
+ running faster than the target speed.
+video.throttle_rate (read/write)
+ The target emulation speed as a ratio of full speed adjusted by the speed
+ factor (i.e. 1 is normal speed adjusted by the speed factor, larger numbers
+ are faster, and smaller numbers are slower).
+video.frameskip (read/write)
+ The number of emulated video frames to skip drawing out of every twelve, or
+ -1 to automatically adjust the number of frames to skip to maintain the
+ target emulation speed.
+video.speed_percent (read-only)
+ The current emulated speed as a percentage of the full speed adjusted by the
+ speed factor.
+video.effective_frameskip (read-only)
+ The number of emulated frames that are skipped out of every twelve.
+video.skip_this_frame (read-only)
+ A Boolean indicating whether the video manager will skip drawing emulated
+ screens for the current frame.
+video.snap_native (read-only)
+ A Boolean indicating whether the video manager will take native emulated
+ screen snapshots. In addition to the relevant configuration setting, the
+ emulated system must have at least one emulated screen.
+video.is_recording (read-only)
+ A Boolean indicating whether any video recordings are currently in progress.
+video.snapshot_target (read-only)
+ The :ref:`render target <luascript-ref-rendertarget>` used to produce
+ snapshots and video recordings.
+
+
+.. _luascript-ref-soundman:
+
+Sound manager
+-------------
+
+Wraps MAME’s ``sound_manager`` class, which manages the emulated sound stream
+graph and coordinates sound output.
+
+Instantiation
+~~~~~~~~~~~~~
+
+manager.machine.sound
+ Gets the sound manager for the current emulation session.
+
+Methods
+~~~~~~~
+
+sound:start_recording([filename])
+ Starts recording to a WAV file. Has no effect if currently recording. If
+ the file name is not supplied, uses the configured WAV file name (from
+ command line or INI file), or has no effect if no WAV file name is
+ configured. Returns ``true`` if recording started, or ``false`` if
+ recording is already in progress, opening the output file failed, or no file
+ name was supplied or configured.
+sound:stop_recording()
+ Stops recording and closes the file if currently recording to a WAV file.
+sound:get_samples()
+ Returns the current contents of the output sample buffer as a binary string.
+ Samples are 16-bit integers in host byte order. Samples for left and right
+ stereo channels are interleaved.
+
+Properties
+~~~~~~~~~~
+
+sound.muted (read-only)
+ A Boolean indicating whether sound output is muted for any reason.
+sound.ui_mute (read/write)
+ A Boolean indicating whether sound output is muted at the request of the
+ user.
+sound.debugger_mute (read/write)
+ A Boolean indicating whether sound output is muted at the request of the
+ debugger.
+sound.system_mute (read/write)
+ A Boolean indicating whether sound output is muted at the request of the
+ emulated system.
+sound.volume (read/write)
+ The output volume in decibels. Should generally be a negative or zero.
+sound.recording (read-only)
+ A Boolean indicating whether sound output is currently being recorded to a
+ WAV file.
+
+
+.. _luascript-ref-outputman:
+
+Output manager
+--------------
+
+Wraps MAME’s ``output_manager`` class, providing access to system outputs that
+can be used for interactive artwork or consumed by external programs.
+
+Instantiation
+~~~~~~~~~~~~~
+
+manager.machine.output
+ Gets the output manager for the current emulation session.
+
+Methods
+~~~~~~~
+
+output:set_value(name, val)
+ Sets the specified output value. The value must be an integer. The output
+ will be created if it does not already exist.
+output:set_indexed_value(prefix, index, val)
+ Appends the index (formatted as a decimal integer) to the prefix and sets
+ the value of the corresponding output. The value must be an integer. The
+ output will be created if it does not already exist.
+output:get_value(name)
+ Returns the value of the specified output, or zero if it doesn’t exist.
+output:get_indexed_value(prefix, index)
+ Appends the index (formatted as a decimal integer) to the prefix and returns
+ the value of the corresponding output, or zero if it doesn’t exist.
+output:name_to_id(name)
+ Gets the per-session unique integer ID for the specified output, or zero if
+ it doesn’t exist.
+output:id_to_name(id)
+ Gets the name for the output with the specified per-session unique ID, or
+ ``nil`` if it doesn’t exist. This method has O(n) complexity, so avoid
+ calling it when performance is important.
+
+
+.. _luascript-ref-paramman:
+
+Parameters manager
+------------------
+
+Wraps MAME’s ``parameters_manager`` class, which provides a simple key-value
+store for metadata from system ROM definitions.
+
+Instantiation
+~~~~~~~~~~~~~
+
+manager.machine.parameters
+ Gets the parameters manager for the current emulation session.
+
+Methods
+~~~~~~~
+
+parameters:lookup(tag)
+ Gets the value for the specified parameter if it is set, or an empty string
+ if it is not set.
+parameters:add(tag, value)
+ Sets the specified parameter if it is not set. Has no effect if the
+ specified parameter is already set.
+
+
+.. _luascript-ref-uiman:
+
+UI manager
+----------
+
+Wraps MAME’s ``mame_ui_manager`` class, which handles menus and other user
+interface functionality.
+
+Instantiation
+~~~~~~~~~~~~~
+
+manager.ui
+ Gets the UI manager for the current session.
+
+Methods
+~~~~~~~
+
+ui:get_char_width(ch)
+ Gets the width of a Unicode character as a proportion of the width of the UI
+ container in the current font at the configured UI line height.
+ui:get_string_width(str)
+ Gets the width of a string as a proportion of the width of the UI container
+ in the current font at the configured UI line height.
+ui:set_aggressive_input_focus(enable)
+ On some platforms, this controls whether MAME should accept input focus in
+ more situations than when its windows have UI focus.
+ui:get_general_input_setting(type, [player])
+ Gets a description of the configured
+ :ref:`input sequence <luascript-ref-inputseq>` for the specified input type
+ and player suitable for using in prompts. The input type is an enumerated
+ value. The player number is a zero-based index. If the player number is
+ not supplied, it is assumed to be zero.
+
+Properties
+~~~~~~~~~~
+
+ui.options (read-only)
+ The UI :ref:`options <luascript-ref-coreopts>` for the current session.
+ui.line_height (read-only)
+ The configured UI text line height as a proportion of the height of the UI
+ container.
+ui.menu_active (read-only)
+ A Boolean indicating whether an interactive UI element is currently active.
+ Examples include menus and slider controls.
+ui.ui_active (read/write)
+ A Boolean indicating whether UI control inputs are currently enabled.
+ui.single_step (read/write)
+ A Boolean controlling whether the emulated system should be automatically
+ paused when the next frame is drawn. This property is automatically reset
+ when the automatic pause happens.
+ui.show_fps (read/write)
+ A Boolean controlling whether the current emulation speed and frame skipping
+ settings should be displayed.
+ui.show_profiler (read/write)
+ A Boolean controlling whether profiling statistics should be displayed.
+
+
+.. _luascript-ref-driver:
+
+System driver metadata
+----------------------
+
+Provides some metadata for an emulated system.
+
+Instantiation
+~~~~~~~~~~~~~
+
+emu.driver_find(name)
+ Gets the driver metadata for the system with the specified short name, or
+ ``nil`` if no such system exists.
+manager.machine.system
+ Gets the driver metadata for the current system.
+
+Properties
+~~~~~~~~~~
+
+driver.name (read-only)
+ The short name of the system, as used on the command line, in configuration
+ files, and when searching for resources.
+driver.description (read-only)
+ The full display name for the system.
+driver.year (read-only)
+ The release year for the system. May contain question marks if not known
+ definitively.
+driver.manufacturer (read-only)
+ The manufacturer, developer or distributor of the system.
+driver.parent (read-only)
+ The short name of parent system for organisation purposes, or ``"0"`` if the
+ system has no parent.
+driver.compatible_with (read-only)
+ The short name of a system that this system is compatible with software for,
+ or ``nil`` if the system is not listed as compatible with another system.
+driver.source_file (read-only)
+ The source file where this system driver is defined. The path format
+ depends on the toolchain the emulator was built with.
+driver.rotation (read-only)
+ A string indicating the rotation applied to all screens in the system after
+ the screen orientation specified in the machine configuration is applied.
+ Will be one of ``"rot0"``, ``"rot90"``, ``"rot180"`` or ``"rot270"``.
+driver.not_working (read-only)
+ A Boolean indicating whether the system is marked as not working.
+driver.supports_save (read-only)
+ A Boolean indicating whether the system supports save states.
+driver.no_cocktail (read-only)
+ A Boolean indicating whether screen flipping in cocktail mode is
+ unsupported.
+driver.is_bios_root (read-only)
+ A Boolean indicating whether this system represents a system that runs
+ software from removable media without media present.
+driver.requires_artwork (read-only)
+ A Boolean indicating whether the system requires external artwork to be
+ usable.
+driver.unofficial (read-only)
+ A Boolean indicating whether this is an unofficial but common user
+ modification to a system.
+driver.no_sound_hw (read-only)
+ A Boolean indicating whether the system has no sound output hardware.
+driver.mechanical (read-only)
+ A Boolean indicating whether the system depends on mechanical features that
+ cannot be properly simulated.
+driver.is_incomplete (read-only)
+ A Boolean indicating whether the system is a prototype with incomplete
+ functionality.
+
+
+.. _luascript-ref-plugin:
+
+Lua plugin
+----------
+
+Provides a description of an available Lua plugin.
+
+Instantiation
+~~~~~~~~~~~~~
+
+manager.plugins[name]
+ Gets the description of the Lua plugin with the specified name, or ``nil``
+ if no such plugin is available
+
+Properties
+~~~~~~~~~~
+
+plugin.name (read-only)
+ The short name of the plugin, used in configuration and when accessing the
+ plugin programmatically.
+plugin.description (read-only)
+ The display name for the plugin.
+plugin.type (read-only)
+ The plugin type. May be ``"plugin"`` for user-loadable plugins, or
+ ``"library"`` for libraries providing common functionality to multiple
+ plugins.
+plugin.directory (read-only)
+ The path to the directory containing the plugin’s files.
+plugin.start (read-only)
+ A Boolean indicating whether the plugin enabled.
diff --git a/docs/source/luascript/ref-debugger.rst b/docs/source/luascript/ref-debugger.rst
new file mode 100644
index 00000000000..e347b7303ff
--- /dev/null
+++ b/docs/source/luascript/ref-debugger.rst
@@ -0,0 +1,451 @@
+.. _luascript-ref-debugger:
+
+Lua Debugger Classes
+====================
+
+Some of MAME’s core debugging features can be controlled from Lua script. The
+debugger must be enabled to use the debugger features (usually by passing
+``-debug`` on the command line).
+
+.. contents::
+ :local:
+ :depth: 1
+
+
+.. _luascript-ref-debugsymtable:
+
+Symbol table
+------------
+
+Wrap’s MAME’s ``symbol_table`` class, providing named symbols that can be used
+in expressions. Note that symbol tables can be created and used even when the
+debugger is not enabled.
+
+Instantiation
+~~~~~~~~~~~~~
+
+emu.symbol_table(machine)
+ Creates a new symbol table in the context of the specified machine,
+emu.symbol_table(parent, [device])
+ Creates a new symbol table with the specified parent symbol table. If a
+ device is specified and it implements ``device_memory_interface``, it will
+ be used as the base for looking up address spaces and memory regions. Note
+ that if a device that does not implement ``device_memory_interface`` is
+ supplied, it will not be used (address spaces and memory regions will be
+ looked up relative to the root device).
+emu.symbol_table(device)
+ Creates a new symbol table in the context of the specified device. If the
+ device implements ``device_memory_interface``, it will be used as the base
+ for looking up address spaces and memory regions. Note that if a device
+ that does not implement ``device_memory_interface`` is supplied, it will
+ only be used to determine the machine context (address spaces and memory
+ regions will be looked up relative to the root device).
+
+Methods
+~~~~~~~
+
+symbols:set_memory_modified_func(cb)
+ Set a function to call when memory is modified via the symbol table. No
+ arguments are passed to the function and any return values are ignored.
+ Call with ``nil`` to remove the callback.
+symbols:add(name, [value])
+ Adds a named integer symbol. The name must be a string. If a value is
+ supplied, it must be an integer. If a value is supplied, a read-only symbol
+ is added with the supplied value. If no value is supplied, a read/write
+ symbol is created with and initial value of zero. If a symbol entry with
+ the specified name already exists in the symbol table, it will be replaced.
+
+ Returns the new :ref:`symbol entry <luascript-ref-debugsymentry>`.
+symbols:add(name, getter, [setter], [format])
+ Adds a named integer symbol using getter and optional setter callbacks. The
+ name must be a string. The getter must be a function returning an integer
+ for the symbol value. If supplied, the setter must be a function that
+ accepts a single integer argument for the new value of the symbol. A format
+ string for displaying the symbol value may optionally be supplied. If a
+ symbol entry with the specified name already exists in the symbol table, it
+ will be replaced.
+
+ Returns the new :ref:`symbol entry <luascript-ref-debugsymentry>`.
+symbols:add(name, minparams, maxparams, execute)
+ Adds a named function symbol. The name must be a string. The minimum and
+ maximum numbers of parameters must be integers. If a symbol entry with the
+ specified name already exists in the symbol table, it will be replaced.
+
+ Returns the new :ref:`symbol entry <luascript-ref-debugsymentry>`.
+symbols:find(name)
+ Returns the :ref:`symbol entry <luascript-ref-debugsymentry>` with the
+ specified name, or ``nil`` if there is no symbol with the specified name in
+ the symbol table.
+symbols:find_deep(name)
+ Returns the :ref:`symbol entry <luascript-ref-debugsymentry>` with the
+ specified name, or ``nil`` if there is no symbol with the specified name in
+ the symbol table or any of its parent symbol tables.
+symbols:value(name)
+ Returns the integer value of the symbol with the specified name, or zero if
+ there is no symbol with the specified name in the symbol table or any of its
+ parent symbol tables. Raises an error if the symbol with specified name is
+ a function symbol.
+symbols:set_value(name, value)
+ Sets the value of the symbol with the specified name. Raises an error if
+ the symbol with the specified name is a read-only integer symbol or if it is
+ a function symbol. Has no effect if there is no symbol with the specified
+ name in the symbol table or any of its parent symbol tables.
+symbols:memory_value(name, space, offset, size, disable_se)
+ Read a value from memory. Supply the name or tag of the address space or
+ memory region to read from, or ``nil`` to use the address space or memory
+ region implied by the ``space`` argument. See
+ :ref:`memory accesses in debugger expressions <debugger-express-mem>` for
+ access type specifications that can be used for the ``space`` argument.
+ The access size is specified in bytes, and must be 1, 2, 4 or 8. The
+ ``disable_se`` argument specifies whether memory access side effects should
+ be disabled.
+symbols:set_memory_value(name, space, offset, value, size, disable_se)
+ Write a value to memory. Supply the name or tag of the address space or
+ memory region to write to, or ``nil`` to use the address space or memory
+ region implied by the ``space`` argument. See
+ :ref:`memory accesses in debugger expressions <debugger-express-mem>` for
+ access type specifications that can be used for the ``space`` argument.
+ The access size is specified in bytes, and must be 1, 2, 4 or 8. The
+ ``disable_se`` argument specifies whether memory access side effects should
+ be disabled.
+symbols:read_memory(space, address, size, apply_translation)
+ Read a value from an address space. The access size is specified in bytes,
+ and must be 1, 2, 4, or 8. If the ``apply_translation`` argument is true,
+ the address will be translated with debug read intention. Returns a value
+ of the requested size with all bits set if address translation fails.
+symbols:write_memory(space, address, data, size, apply_translation)
+ Write a value to an address space. The access size is specified in bytes,
+ and must be 1, 2, 4, or 8. If the ``apply_translation`` argument is true,
+ the address will be translated with debug write intention. The symbol
+ table’s memory modified function will be called after the value is written.
+ The value will not be written and the symbol table’s memory modified
+ function will not be called if address translation fails.
+
+Properties
+~~~~~~~~~~
+
+symbols.entries[]
+ The :ref:`symbol entries <luascript-ref-debugsymentry>` in the symbol table,
+ indexed by name. The ``at`` and ``index_of`` methods have O(n) complexity;
+ all other supported operations have O(1) complexity.
+symbols.parent (read-only)
+ The parent symbol table, or ``nil`` if the symbol table has no parent.
+
+
+.. _luascript-ref-debugexpression:
+
+Parsed expression
+-----------------
+
+Wraps MAME’s ``parsed_expression`` class, which represents a tokenised debugger
+expression. Note that parsed expressions can be created and used even when the
+debugger is not enabled.
+
+Instantiation
+~~~~~~~~~~~~~
+
+emu.parsed_expression(symbols)
+ Creates an empty expression that will use the supplied
+ :ref:`symbol table <luascript-ref-debugsymtable>` to look up symbols.
+emu.parsed_expression(symbols, string, [default_base])
+ Creates an expression by parsing the supplied string, looking up symbols in
+ the supplied :ref:`symbol table <luascript-ref-debugsymtable>`. If the
+ default base for interpreting integer literals is not supplied, 16 is used
+ (hexadecimal). Raises an :ref:`expression error
+ <luascript-ref-debugexpressionerror>` if the string contains syntax errors
+ or uses undefined symbols.
+
+Methods
+~~~~~~~
+
+expression:set_default_base(base)
+ Set the default base for interpreting numeric literals. The base must be a
+ positive integer.
+expression:parse(string)
+ Parse a debugger expression string. Replaces the current contents of the
+ expression if it is not empty. Raises an :ref:`expression error
+ <luascript-ref-debugexpressionerror>` if the string contains syntax errors
+ or uses undefined symbols. The previous content of the expression is not
+ preserved when attempting to parse an invalid expression string.
+expression:execute()
+ Evaluates the expression, returning an unsigned integer result. Raises an
+ :ref:`expression error <luascript-ref-debugexpressionerror>` if the
+ expression cannot be evaluated (e.g. attempting to call a function with an
+ invalid number of arguments).
+
+Properties
+~~~~~~~~~~
+
+expression.is_empty (read-only)
+ A Boolean indicating whether the expression contains no tokens.
+expression.original_string (read-only)
+ The original string that was parsed to create the expression.
+expression.symbols (read/write)
+ The :ref:`symbol table <luascript-ref-debugsymtable>` used for to look up
+ symbols in the expression.
+
+
+.. _luascript-ref-debugsymentry:
+
+Symbol entry
+------------
+
+Wraps MAME’s ``symbol_entry`` class, which represents an entry in a
+:ref:`symbol table <luascript-ref-debugsymtable>`. Note that symbol entries
+must not be used after the symbol table they belong to is destroyed.
+
+Instantiation
+~~~~~~~~~~~~~
+
+symbols:add(name, [value])
+ Adds an integer symbol to a
+ :ref:`symbol table <luascript-ref-debugsymtable>`, returning the new symbol
+ entry.
+symbols:add(name, getter, [setter], [format])
+ Adds an integer symbol to a
+ :ref:`symbol table <luascript-ref-debugsymtable>`, returning the new symbol
+ entry.
+symbols:add(name, minparams, maxparams, execute)
+ Adds function symbol to a
+ :ref:`symbol table <luascript-ref-debugsymtable>`, returning the new symbol
+ entry.
+
+Properties
+~~~~~~~~~~
+
+entry.name (read-only)
+ The name of the symbol entry.
+entry.format (read-only)
+ The format string used to convert the symbol entry to text for display.
+entry.is_function (read-only)
+ A Boolean indicating whether the symbol entry is a callable function.
+entry.is_lval (read-only)
+ A Boolean indicating whether the symbol entry is an integer symbol that can
+ be set (i.e. whether it can be used on the left-hand side of assignment
+ expressions).
+entry.value (read/write)
+ The integer value of the symbol entry. Attempting to set the value raises
+ an error if the symbol entry is read-only. Attempting to get or set the
+ value of a function symbol raises an error.
+
+
+.. _luascript-ref-debugman:
+
+Debugger manager
+----------------
+
+Wraps MAME’s ``debugger_manager`` class, providing the main interface to control
+the debugger.
+
+Instantiation
+~~~~~~~~~~~~~
+
+manager.machine.debugger
+ Returns the global debugger manager instance, or ``nil`` if the debugger is
+ not enabled.
+
+Methods
+~~~~~~~
+
+debugger:command(str)
+ Execute a debugger console command. The argument is the command string.
+ The output is sent to both the debugger console and the Lua console.
+
+Properties
+~~~~~~~~~~
+
+debugger.consolelog[] (read-only)
+ The lines in the console log (output from debugger commands). This
+ container only supports index and length operations.
+debugger.errorlog[] (read-only)
+ The lines in the error log (``logerror`` output). This container only
+ supports index and length operations.
+debugger.visible_cpu (read/write)
+ The CPU device with debugger focus. Changes become visible in the debugger
+ console after the next step. Setting to a device that is not a CPU has no
+ effect.
+debugger.execution_state (read/write)
+ Either ``"run"`` if the emulated system is running, or ``"stop"`` if it is
+ stopped in the debugger.
+
+
+.. _luascript-ref-devdebug:
+
+Device debugger interface
+-------------------------
+
+Wraps MAME’s ``device_debug`` class, providing the debugger interface to an
+emulated CPU device.
+
+Instantiation
+~~~~~~~~~~~~~
+
+manager.machine.devices[tag].debug
+ Returns the debugger interface for an emulated CPU device, or ``nil`` if the
+ device is not a CPU.
+
+Methods
+~~~~~~~
+
+debug:step([cnt])
+ Step by the specified number of instructions. If the instruction count is
+ not provided, it defaults to a single instruction.
+debug:go()
+ Run the emulated CPU.
+debug:bpset(addr, [cond], [act])
+ Set a breakpoint at the specified address, with an optional condition and
+ action. If the action is not specified, it defaults to just breaking into
+ the debugger. Returns the breakpoint number for the new breakpoint.
+
+ If specified, the condition must be a debugger expression that will be
+ evaluated each time the breakpoint is hit. Execution will only be stopped
+ if the expression evaluates to a non-zero value. If the condition is not
+ specified, it defaults to always active.
+debug:bpenable([bp])
+ Enable the specified breakpoint, or all breakpoints for the device if no
+ breakpoint number is specified. Returns whether the specified number
+ matched a breakpoint if a breakpoint number is specified, or ``nil`` if no
+ breakpoint number is specified.
+debug:bpdisable([bp])
+ Disable the specified breakpoint, or all breakpoints for the device if no
+ breakpoint number is specified. Returns whether the specified number
+ matched a breakpoint if a breakpoint number is specified, or ``nil`` if no
+ breakpoint number is specified.
+debug:bpclear([bp])
+ Clear the specified breakpoint, or all breakpoints for the device if no
+ breakpoint number is specified. Returns whether the specified number
+ matched a breakpoint if a breakpoint number is specified, or ``nil`` if no
+ breakpoint number is specified.
+debug:bplist()
+ Returns a table of breakpoints for the device. The keys are the breakpoint
+ numbers, and the values are
+ :ref:`breakpoint objects <luascript-ref-breakpoint>`.
+debug:wpset(space, type, addr, len, [cond], [act])
+ Set a watchpoint over the specified address range, with an optional
+ condition and action. The type must be ``"r"``, ``"w"`` or ``"rw"`` for a
+ read, write or read/write breakpoint. If the action is not specified, it
+ defaults to just breaking into the debugger. Returns the watchpoint number
+ for the new watchpoint.
+
+ If specified, the condition must be a debugger expression that will be
+ evaluated each time the breakpoint is hit. Execution will only be stopped
+ if the expression evaluates to a non-zero value. The variable 'wpaddr' is
+ set to the address that actually triggered the watchpoint, the variable
+ 'wpdata' is set to the data that is being read or written, and the variable
+ 'wpsize' is set to the size of the data in bytes. If the condition is not
+ specified, it defaults to always active.
+debug:wpenable([wp])
+ Enable the specified watchpoint, or all watchpoints for the device if no
+ watchpoint number is specified. Returns whether the specified number
+ matched a watchpoint if a watchpoint number is specified, or ``nil`` if no
+ watchpoint number is specified.
+debug:wpdisable([wp])
+ Disable the specified watchpoint, or all watchpoints for the device if no
+ watchpoint number is specified. Returns whether the specified number
+ matched a watchpoint if a watchpoint number is specified, or ``nil`` if no
+ watchpoint number is specified.
+debug:wpclear([wp])
+ Clear the specified watchpoint, or all watchpoints for the device if no
+ watchpoint number is specified. Returns whether the specified number
+ matched a watchpoint if a watchpoint number is specified, or ``nil`` if no
+ watchpoint number is specified.
+debug:wplist(space)
+ Returns a table of watchpoints for the specified address space of the
+ device. The keys are the watchpoint numbers, and the values are
+ :ref:`watchpoint objects <luascript-ref-watchpoint>`.
+
+
+.. _luascript-ref-breakpoint:
+
+Breakpoint
+----------
+
+Wraps MAME’s ``debug_breakpoint`` class, representing a breakpoint for an
+emulated CPU device.
+
+Instantiation
+~~~~~~~~~~~~~
+
+manager.machine.devices[tag].debug:bplist()[bp]
+ Gets the specified breakpoint for an emulated CPU device, or ``nil`` if no
+ breakpoint corresponds to the specified index.
+
+Properties
+~~~~~~~~~~
+
+breakpoint.index (read-only)
+ The breakpoint’s index. The can be used to enable, disable or clear the
+ breakpoint via the
+ :ref:`CPU debugger interface <luascript-ref-devdebug>`.
+breakpoint.enabled (read/write)
+ A Boolean indicating whether the breakpoint is currently enabled.
+breakpoint.address (read-only)
+ The breakpoint’s address.
+breakpoint.condition (read-only)
+ A debugger expression evaluated each time the breakpoint is hit. The action
+ will only be triggered if this expression evaluates to a non-zero value. An
+ empty string if no condition was specified.
+breakpoint.action (read-only)
+ An action the debugger will run when the breakpoint is hit and the condition
+ evaluates to a non-zero value. An empty string if no action was specified.
+
+
+.. _luascript-ref-watchpoint:
+
+Watchpoint
+----------
+
+Wraps MAME’s ``debug_watchpoint`` class, representing a watchpoint for an
+emulated CPU device.
+
+Instantiation
+~~~~~~~~~~~~~
+
+manager.machine.devices[tag].debug:wplist(space)[wp]
+ Gets the specified watchpoint for an address space of an emulated CPU
+ device, or ``nil`` if no watchpoint in the address space corresponds to the
+ specified index.
+
+Properties
+~~~~~~~~~~
+
+watchpoint.index (read-only)
+ The watchpoint’s index. The can be used to enable, disable or clear the
+ watchpoint via the
+ :ref:`CPU debugger interface <luascript-ref-devdebug>`.
+watchpoint.enabled (read/write)
+ A Boolean indicating whether the watchpoint is currently enabled.
+watchpoint.type (read-only)
+ Either ``"r"``, ``"w"`` or ``"rw"`` for a read, write or read/write
+ watchpoint.
+watchpoint.address (read-only)
+ The starting address of the watchpoint’s address range.
+watchpoint.length (read-only)
+ The length of the watchpoint’s address range.
+watchpoint.condition (read-only)
+ A debugger expression evaluated each time the watchpoint is hit. The action
+ will only be triggered if this expression evaluates to a non-zero value. An
+ empty string if no condition was specified.
+watchpoint.action (read-only)
+ An action the debugger will run when the watchpoint is hit and the condition
+ evaluates to a non-zero value. An empty string if no action was specified.
+
+
+.. _luascript-ref-debugexpressionerror:
+
+Expression error
+----------------
+
+Wraps MAME’s ``expression_error`` class, describing an error occurring while
+parsing or executing a debugger expression. Raised on errors when using
+:ref:`parsed expressions <luascript-ref-debugexpression>`. Can be converted to
+a string to provide a description of the error.
+
+Properties
+~~~~~~~~~~
+
+err.code (read-only)
+ An implementation-dependent number representing the category of error.
+ Should not be displayed to the user.
+err.offset (read-only)
+ The offset within the expression string where the error was encountered.
diff --git a/docs/source/luascript/ref-devices.rst b/docs/source/luascript/ref-devices.rst
new file mode 100644
index 00000000000..fe25e0b0591
--- /dev/null
+++ b/docs/source/luascript/ref-devices.rst
@@ -0,0 +1,819 @@
+.. _luascript-ref-dev:
+
+Lua Device Classes
+==================
+
+Several device classes and device mix-ins classes are exposed to Lua. Devices
+can be looked up by tag or enumerated.
+
+.. contents::
+ :local:
+ :depth: 1
+
+
+.. _luascript-ref-devenum:
+
+Device enumerators
+------------------
+
+Device enumerators are special containers that allow iterating over devices and
+looking up devices by tag. A device enumerator can be created to find any kind
+of device, to find devices of a particular type, or to find devices that
+implement a particular interface. When iterating using ``pairs`` or ``ipairs``,
+devices are returned by walking the device tree depth-first in creation order.
+
+The index get operator looks up a device by tag. It returns ``nil`` if no
+device with the specified tag is found, or if the device with the specified tag
+does not meet the type/interface requirements of the device enumerator. The
+complexity is O(1) if the result is cached, but an uncached device lookup is
+expensive. The ``at`` method has O(n) complexity.
+
+If you create a device enumerator with a starting point other than the root
+machine device, passing an absolute tag or a tag containing parent references to
+the index operator may return a device that would not be discovered by
+iteration. If you create a device enumerator with restricted depth, devices
+that would not be found due to being too deep in the hierarchy can still be
+looked up by tag.
+
+Creating a device enumerator with depth restricted to zero can be used to
+downcast a device or test whether a device implements a certain interface. For
+example this will test whether a device implements the media image interface:
+
+.. code-block:: Lua
+
+ image_intf = emu.image_enumerator(device, 0):at(1)
+ if image_intf then
+ print(string.format("Device %s mounts images", device.tag))
+ end
+
+Instantiation
+~~~~~~~~~~~~~
+
+manager.machine.devices
+ Returns a device enumerator that will iterate over
+ :ref:`devices <luascript-ref-device>` in the system.
+manager.machine.palettes
+ Returns a device enumerator that will iterate over
+ :ref:`palette devices <luascript-ref-dipalette>` in the system.
+manager.machine.screens
+ Returns a device enumerator that will iterate over
+ :ref:`screen devices <luascript-ref-screendev>` in the system.
+manager.machine.cassettes
+ Returns a device enumerator that will iterate over
+ :ref:`cassette image devices <luascript-ref-cassdev>` in the system.
+manager.machine.images
+ Returns a device enumerator that will iterate over
+ :ref:`media image devices <luascript-ref-diimage>` in the system.
+manager.machine.slots
+ Returns a device enumerator that will iterate over
+ :ref:`slot devices <luascript-ref-dislot>` in the system.
+manager.machine.sounds
+ Returns a device enumerator that will iterate over
+ :ref:`sound devices <luascript-ref-disound>` in the system.
+emu.device_enumerator(device, [depth])
+ Returns a device enumerator that will iterate over
+ :ref:`devices <luascript-ref-device>` in the sub-tree starting at the
+ specified device. The specified device will be included. If the depth is
+ provided, it must be an integer specifying the maximum number of levels to
+ iterate below the specified device (i.e. 1 will limit iteration to the
+ device and its immediate children).
+emu.palette_enumerator(device, [depth])
+ Returns a device enumerator that will iterate over
+ :ref:`palette devices <luascript-ref-dipalette>` in the sub-tree starting at
+ the specified device. The specified device will be included if it is a
+ palette device. If the depth is provided, it must be an integer specifying
+ the maximum number of levels to iterate below the specified device (i.e. 1
+ will limit iteration to the device and its immediate children).
+emu.screen_enumerator(device, [depth])
+ Returns a device enumerator that will iterate over
+ :ref:`screen devices <luascript-ref-screendev>` in the sub-tree starting at
+ the specified device. The specified device will be included if it is a
+ screen device. If the depth is provided, it must be an integer specifying
+ the maximum number of levels to iterate below the specified device (i.e. 1
+ will limit iteration to the device and its immediate children).
+emu.cassette_enumerator(device, [depth])
+ Returns a device enumerator that will iterate over
+ :ref:`cassette image devices <luascript-ref-cassdev>` in the sub-tree
+ starting at the specified device. The specified device will be included if
+ it is a cassette image device. If the depth is provided, it must be an
+ integer specifying the maximum number of levels to iterate below the
+ specified device (i.e. 1 will limit iteration to the device and its
+ immediate children).
+emu.image_enumerator(device, [depth])
+ Returns a device enumerator that will iterate over
+ :ref:`media image devices <luascript-ref-diimage>` in the sub-tree starting
+ at the specified device. The specified device will be included if it is a
+ media image device. If the depth is provided, it must be an integer
+ specifying the maximum number of levels to iterate below the specified
+ device (i.e. 1 will limit iteration to the device and its immediate
+ children).
+emu.slot_enumerator(device, [depth])
+ Returns a device enumerator that will iterate over
+ :ref:`slot devices <luascript-ref-dislot>` in the sub-tree starting at the
+ specified device. The specified device will be included if it is a slot
+ device. If the depth is provided, it must be an integer specifying the
+ maximum number of levels to iterate below the specified device (i.e. 1 will
+ limit iteration to the device and its immediate children).
+
+
+.. _luascript-ref-device:
+
+Device
+------
+
+Wraps MAME’s ``device_t`` class, which is a base of all device classes.
+
+Instantiation
+~~~~~~~~~~~~~
+
+manager.machine.devices[tag]
+ Gets a device by tag relative to the root machine device, or ``nil`` if no
+ such device exists.
+manager.machine.devices[tag]:subdevice(tag)
+ Gets a device by tag relative to another arbitrary device, or ``nil`` if no
+ such device exists.
+
+Methods
+~~~~~~~
+
+device:subtag(tag)
+ Converts a tag relative to the device to an absolute tag.
+device:siblingtag(tag)
+ Converts a tag relative to the device’s parent device to an absolute tag.
+device:memshare(tag)
+ Gets a :ref:`memory share <luascript-ref-memshare>` by tag relative to the
+ device, or ``nil`` if no such memory share exists.
+device:membank(tag)
+ Gets a :ref:`memory bank <luascript-ref-membank>` by tag relative to the
+ device, or ``nil`` if no such memory bank exists.
+device:memregion(tag)
+ Gets a :ref:`memory region <luascript-ref-memregion>` by tag relative to the
+ device, or ``nil`` if no such memory region exists.
+device:ioport(tag)
+ Gets an :ref:`I/O port <luascript-ref-ioport>` by tag relative to the
+ device, or ``nil`` if no such I/O port exists.
+device:subdevice(tag)
+ Gets a device by tag relative to the device.
+device:siblingdevice(tag)
+ Gets a device by tag relative to the device’s parent.
+device:parameter(tag)
+ Gets a parameter value by tag relative to the device, or an empty string if
+ the parameter is not set.
+
+Properties
+~~~~~~~~~~
+
+device.tag (read-only)
+ The device’s absolute tag in canonical form.
+device.basetag (read-only)
+ The last component of the device’s tag (i.e. its tag relative to its
+ immediate parent), or ``"root"`` for the root machine device.
+device.name (read-only)
+ The full display name for the device’s type.
+device.shortname (read-only)
+ The short name of the devices type (this is used, e.g. on the command line,
+ when looking for resource like ROMs or artwork, and in various data files).
+device.owner (read-only)
+ The device’s immediate parent in the device tree, or ``nil`` for the root
+ machine device.
+device.configured (read-only)
+ A Boolean indicating whether the device has completed configuration.
+device.started (read-only)
+ A Boolean indicating whether the device has completed starting.
+device.debug (read-only)
+ The :ref:`debugger interface <luascript-ref-devdebug>` to the device if it
+ is a CPU device, or ``nil`` if it is not a CPU device or the debugger is not
+ enabled.
+device.state[] (read-only)
+ The :ref:`state entries <luascript-ref-distateentry>` for devices that
+ expose the register state interface, indexed by symbol, or ``nil`` for other
+ devices. The index operator and ``index_of`` methods have O(n) complexity;
+ all other supported operations have O(1) complexity.
+device.spaces[] (read-only)
+ A table of the device’s :ref:`address spaces <luascript-ref-addrspace>`,
+ indexed by name. Only valid for devices that implement the memory
+ interface. Note that the names are specific to the device type and have no
+ special significance.
+
+
+.. _luascript-ref-dipalette:
+
+Palette device
+--------------
+
+Wraps MAME’s ``device_palette_interface`` class, which represents a device that
+translates pen values to colours.
+
+Colours are represented in alpha/red/green/blue (ARGB) format. Channel values
+range from 0 (transparent or off) to 255 (opaque or full intensity), inclusive.
+Colour channel values are not pre-multiplied by the alpha value. Channel values
+are packed into the bytes of 32-bit unsigned integers, in the order alpha, red,
+green, blue from most-significant to least-significant byte.
+
+Instantiation
+~~~~~~~~~~~~~
+
+manager.machine.palettes[tag]
+ Gets a palette device by tag relative to the root machine device, or ``nil``
+ if no such device exists or it is not a palette device.
+
+Methods
+~~~~~~~
+
+palette:pen(index)
+ Gets the remapped pen number for the specified palette index.
+palette:pen_color(pen)
+ Gets the colour for the specified pen number.
+palette:pen_contrast(pen)
+ Gets the contrast value for the specified pen number. The contrast is a
+ floating-point number.
+palette:pen_indirect(index)
+ Gets the indirect pen index for the specified palette index.
+palette:indirect_color(index)
+ Gets the indirect pen colour for the specified palette index.
+palette:set_pen_color(pen, color)
+ Sets the colour for the specified pen number. The colour may be specified
+ as a single packed 32-bit value; or as individual red, green and blue
+ channel values, in that order.
+palette:set_pen_red_level(pen, level)
+ Sets the red channel value of the colour for the specified pen number.
+ Other channel values are not affected.
+palette:set_pen_green_level(pen, level)
+ Sets the green channel value of the colour for the specified pen number.
+ Other channel values are not affected.
+palette:set_pen_blue_level(pen, level)
+ Sets the blue channel value of the colour for the specified pen number.
+ Other channel values are not affected.
+palette:set_pen_contrast(pen, factor)
+ Sets the contrast value for the specified pen number. The value must be a
+ floating-point number.
+palette:set_pen_indirect(pen, index)
+ Sets the indirect pen index for the specified pen number.
+palette:set_indirect_color(index, color)
+ Sets the indirect pen colour for the specified palette index. The colour
+ may be specified as a single packed 32-bit value; or as individual red,
+ green and blue channel values, in that order.
+palette:set_shadow_factor(factor)
+ Sets the contrast value for the current shadow group. The value must be a
+ floating-point number.
+palette:set_highlight_factor(factor)
+ Sets the contrast value for the current highlight group. The value must be
+ a floating-point number.
+palette:set_shadow_mode(mode)
+ Sets the shadow mode. The value is the index of the desired shadow table.
+
+Properties
+~~~~~~~~~~
+
+palette.palette (read-only)
+ The underlying :ref:`palette <luascript-ref-palette>` managed by the
+ device.
+palette.entries (read-only)
+ The number of colour entries in the palette.
+palette.indirect_entries (read-only)
+ The number of indirect pen entries in the palette.
+palette.black_pen (read-only)
+ The index of the fixed black pen entry.
+palette.white_pen (read-only)
+ The index of the fixed white pen.
+palette.shadows_enabled (read-only)
+ A Boolean indicating whether shadow colours are enabled.
+palette.highlights_enabled (read-only)
+ A Boolean indicating whether highlight colours are enabled.
+palette.device (read-only)
+ The underlying :ref:`device <luascript-ref-device>`.
+
+
+.. _luascript-ref-screendev:
+
+Screen device
+-------------
+
+Wraps MAME’s ``screen_device`` class, which represents an emulated video output.
+
+Instantiation
+~~~~~~~~~~~~~
+
+manager.machine.screens[tag]
+ Gets a screen device by tag relative to the root machine device, or ``nil``
+ if no such device exists or it is not a screen device.
+
+Base classes
+~~~~~~~~~~~~
+
+* :ref:`luascript-ref-device`
+
+Methods
+~~~~~~~
+
+screen:orientation()
+ Returns the rotation angle in degrees (will be one of 0, 90, 180 or 270),
+ whether the screen is flipped left-to-right, and whether the screen is
+ flipped top-to-bottom. This is the final screen orientation after the
+ screen orientation specified in the machine configuration and the rotation
+ for the system driver are applied.
+screen:time_until_pos(v, [h])
+ Gets the time remaining until the raster reaches the specified position. If
+ the horizontal component of the position is not specified, it defaults to
+ zero (0, i.e. the beginning of the line). The result is a floating-point
+ number in units of seconds.
+screen:time_until_vblank_start()
+ Gets the time remaining until the start of the vertical blanking interval.
+ The result is a floating-point number in units of seconds.
+screen:time_until_vblank_end()
+ Gets the time remaining until the end of the vertical blanking interval.
+ The result is a floating-point number in units of seconds.
+screen:snapshot([filename])
+ Saves a screen snapshot in PNG format. If no filename is supplied, the
+ configured snapshot path and name format will be used. If the supplied
+ filename is not an absolute path, it is interpreted relative to the first
+ configured snapshot path. The filename may contain conversion specifiers
+ that will be replaced by the system name or an incrementing number.
+
+ Returns a file error if opening the snapshot file failed, or ``nil``
+ otherwise.
+screen:pixel(x, y)
+ Gets the pixel at the specified location. Coordinates are in pixels, with
+ the origin at the top left corner of the visible area, increasing to the
+ right and down. Returns either a palette index or a colour in RGB format
+ packed into a 32-bit integer. Returns zero (0) if the specified point is
+ outside the visible area.
+screen:pixels()
+ Returns all visible pixels, the visible area width and visible area height.
+
+ Pixels are returned as 32-bit integers packed into a binary string in host
+ Endian order. Pixels are organised in row-major order, from left to right
+ then top to bottom. Pixels values are either palette indices or colours in
+ RGB format packed into 32-bit integers.
+screen:draw_box(left, top, right, bottom, [line], [fill])
+ Draws an outlined rectangle with edges at the specified positions.
+
+ Coordinates are floating-point numbers in units of emulated screen pixels,
+ with the origin at (0, 0). Note that emulated screen pixels often aren’t
+ square. The coordinate system is rotated if the screen is rotated, which is
+ usually the case for vertical-format screens. Before rotation, the origin
+ is at the top left, and coordinates increase to the right and downwards.
+ Coordinates are limited to the screen area.
+
+ The fill and line colours are in alpha/red/green/blue (ARGB) format.
+ Channel values are in the range 0 (transparent or off) to 255 (opaque or
+ full intensity), inclusive. Colour channel values are not pre-multiplied by
+ the alpha value. The channel values must be packed into the bytes of a
+ 32-bit unsigned integer, in the order alpha, red, green, blue from
+ most-significant to least-significant byte. If the line colour is not
+ provided, the UI text colour is used; if the fill colour is not provided,
+ the UI background colour is used.
+screen:draw_line(x0, y0, x1, y1, [color])
+ Draws a line from (x0, y0) to (x1, y1).
+
+ Coordinates are floating-point numbers in units of emulated screen pixels,
+ with the origin at (0, 0). Note that emulated screen pixels often aren’t
+ square. The coordinate system is rotated if the screen is rotated, which is
+ usually the case for vertical-format screens. Before rotation, the origin
+ is at the top left, and coordinates increase to the right and downwards.
+ Coordinates are limited to the screen area.
+
+ The line colour is in alpha/red/green/blue (ARGB) format. Channel values
+ are in the range 0 (transparent or off) to 255 (opaque or full intensity),
+ inclusive. Colour channel values are not pre-multiplied by the alpha value.
+ The channel values must be packed into the bytes of a 32-bit unsigned
+ integer, in the order alpha, red, green, blue from most-significant to
+ least-significant byte. If the line colour is not provided, the UI text
+ colour is used.
+screen:draw_text(x|justify, y, text, [foreground], [background])
+ Draws text at the specified position. If the screen is rotated the text
+ will be rotated.
+
+ If the first argument is a number, the text will be left-aligned at this X
+ coordinate. If the first argument is a string, it must be ``"left"``,
+ ``"center"`` or ``"right"`` to draw the text left-aligned at the
+ left edge of the screen, horizontally centred on the screen, or
+ right-aligned at the right edge of the screen, respectively. The second
+ argument specifies the Y coordinate of the maximum ascent of the text.
+
+ Coordinates are floating-point numbers in units of emulated screen pixels,
+ with the origin at (0, 0). Note that emulated screen pixels often aren’t
+ square. The coordinate system is rotated if the screen is rotated, which is
+ usually the case for vertical-format screens. Before rotation, the origin
+ is at the top left, and coordinates increase to the right and downwards.
+ Coordinates are limited to the screen area.
+
+ The foreground and background colours are in alpha/red/green/blue (ARGB)
+ format. Channel values are in the range 0 (transparent or off) to 255
+ (opaque or full intensity), inclusive. Colour channel values are not
+ pre-multiplied by the alpha value. The channel values must be packed into
+ the bytes of a 32-bit unsigned integer, in the order alpha, red, green, blue
+ from most-significant to least-significant byte. If the foreground colour
+ is not provided, the UI text colour is used; if the background colour is not
+ provided, it is fully transparent.
+
+Properties
+~~~~~~~~~~
+
+screen.width (read-only)
+ The width of the bitmap produced by the emulated screen in pixels.
+screen.height (read-only)
+ The height of the bitmap produced by the emulated screen in pixels.
+screen.refresh (read-only)
+ The screen’s configured refresh rate in Hertz (this may not reflect the
+ current value).
+screen.refresh_attoseconds (read-only)
+ The screen’s configured refresh interval in attoseconds (this may not
+ reflect the current value).
+screen.xoffset (read-only)
+ The screen’s default X position offset. This is a floating-point number
+ where one (1) corresponds to the X size of the screen’s container. This may
+ be useful for restoring the default after adjusting the X offset via the
+ screen’s container.
+screen.yoffset (read-only)
+ The screen’s default Y position offset. This is a floating-point number
+ where one (1) corresponds to the Y size of the screen’s container. This may
+ be useful for restoring the default after adjusting the Y offset via the
+ screen’s container.
+screen.xscale (read-only)
+ The screen’s default X scale factor, as a floating-point number. This may
+ be useful for restoring the default after adjusting the X scale via the
+ screen’s container.
+screen.yscale (read-only)
+ The screen’s default Y scale factor, as a floating-point number. This may
+ be useful for restoring the default after adjusting the Y scale via the
+ screen’s container.
+screen.pixel_period (read-only)
+ The interval taken to draw a horizontal pixel, as a floating-point number in
+ units of seconds.
+screen.scan_period (read-only)
+ The interval taken to draw a scan line (including the horizontal blanking
+ interval), as a floating-point number in units of seconds.
+screen.frame_period (read-only)
+ The interval taken to draw a complete frame (including blanking intervals),
+ as a floating-point number in units of seconds.
+screen.frame_number (read-only)
+ The current frame number for the screen. This increments monotonically each
+ frame interval.
+screen.container (read-only)
+ The :ref:`render container <luascript-ref-rendercontainer>` used to draw the
+ screen.
+screen.palette (read-only)
+ The :ref:`palette device <luascript-ref-dipalette>` used to translate pixel
+ values to colours, or ``nil`` if the screen uses a direct colour pixel
+ format.
+
+
+.. _luascript-ref-cassdev:
+
+Cassette image device
+---------------------
+
+Wraps MAME’s ``cassette_image_device`` class, representing a compact cassette
+mechanism typically used by a home computer for program storage.
+
+Instantiation
+~~~~~~~~~~~~~
+
+manager.machine.cassettes[tag]
+ Gets a cassette image device by tag relative to the root machine device, or
+ ``nil`` if no such device exists or it is not a cassette image device.
+
+Base classes
+~~~~~~~~~~~~
+
+* :ref:`luascript-ref-device`
+* :ref:`luascript-ref-diimage`
+
+Methods
+~~~~~~~
+
+cassette:stop()
+ Disables playback.
+cassette:play()
+ Enables playback. The cassette will play if the motor is enabled.
+cassette:forward()
+ Sets forward play direction.
+cassette:reverse()
+ Sets reverse play direction.
+cassette:seek(time, whence)
+ Jump to the specified position on the tape. The time is a floating-point
+ number in units of seconds, relative to the point specified by the whence
+ argument. The whence argument must be one of ``"set"``, ``"cur"`` or
+ ``"end"`` to seek relative to the start of the tape, the current position,
+ or the end of the tape, respectively.
+
+Properties
+~~~~~~~~~~
+
+cassette.is_stopped (read-only)
+ A Boolean indicating whether the cassette is stopped (i.e. not recording and
+ not playing).
+cassette.is_playing (read-only)
+ A Boolean indicating whether playback is enabled (i.e. the cassette will
+ play if the motor is enabled).
+cassette.is_recording (read-only)
+ A Boolean indicating whether recording is enabled (i.e. the cassette will
+ record if the motor is enabled).
+cassette.motor_state (read/write)
+ A Boolean indicating whether the cassette motor is enabled.
+cassette.speaker_state (read/write)
+ A Boolean indicating whether the cassette speaker is enabled.
+cassette.position (read-only)
+ The current position as a floating-point number in units of seconds relative
+ to the start of the tape.
+cassette.length (read-only)
+ The length of the tape as a floating-point number in units of seconds, or
+ zero (0) if no tape image is mounted.
+
+
+.. _luascript-ref-diimage:
+
+Image device interface
+----------------------
+
+Wraps MAME’s ``device_image_interface`` class which is a mix-in implemented by
+devices that can load media image files.
+
+Instantiation
+~~~~~~~~~~~~~
+
+manager.machine.images[tag]
+ Gets an image device by tag relative to the root machine device, or ``nil``
+ if no such device exists or it is not a media image device.
+
+Methods
+~~~~~~~
+
+image:load(filename)
+ Loads the specified file as a media image. Returns ``nil`` if no error
+ or a string describing an error if an error occurred.
+image:load_software(name)
+ Loads a media image described in a software list. Returns ``nil`` if no
+ error or a string describing an error if an error occurred.
+image:unload()
+ Unloads the mounted image.
+image:create(filename)
+ Creates and mounts a media image file with the specified name. Returns
+ ``nil`` if no error or a string describing an error if an error
+ occurred.
+image:display()
+ Returns a “front panel display” string for the device, if supported. This
+ can be used to show status information, like the current head position or
+ motor state.
+image:add_media_change_notifier(callback)
+ Add a callback to receive notifications when a media image is loaded or
+ unloaded for the device. The callback is passed a single string argument
+ which will be ``"loaded"`` if a media image has been loaded or
+ ``"unloaded"`` if the previously loaded media image has been unloaded.
+ Returns a :ref:`notifier subscription <luascript-ref-notifiersub>`.
+
+Properties
+~~~~~~~~~~
+
+image.is_readable (read-only)
+ A Boolean indicating whether the device supports reading.
+image.is_writeable (read-only)
+ A Boolean indicating whether the device supports writing.
+image.must_be_loaded (read-only)
+ A Boolean indicating whether the device requires a media image to be loaded
+ in order to start.
+image.is_reset_on_load (read-only)
+ A Boolean indicating whether the device requires a hard reset to change
+ media images (usually for cartridge slots that contain hardware in addition
+ to memory chips).
+image.image_type_name (read-only)
+ A string for categorising the media device.
+image.instance_name (read-only)
+ The instance name of the device in the current configuration. This is used
+ for setting the media image to load on the command line or in INI files.
+ This is not stable, it may have a number appended that may change depending
+ on slot configuration.
+image.brief_instance_name (read-only)
+ The brief instance name of the device in the current configuration. This is
+ used for setting the media image to load on the command line or in INI
+ files. This is not stable, it may have a number appended that may change
+ depending on slot configuration.
+image.formatlist[] (read-only)
+ The :ref:`media image formats <luascript-ref-imagefmt>` supported by the
+ device, indexed by name. The index operator and ``index_of`` methods have
+ O(n) complexity; all other supported operations have O(1) complexity.
+image.exists (read-only)
+ A Boolean indicating whether a media image file is mounted.
+image.readonly (read-only)
+ A Boolean indicating whether a media image file is mounted in read-only
+ mode.
+image.filename (read-only)
+ The full path to the mounted media image file, or ``nil`` if no media image
+ is mounted.
+image.crc (read-only)
+ The 32-bit cyclic redundancy check of the content of the mounted image file
+ if the mounted media image was not loaded from a software list, is mounted
+ read-only and is not a CD-ROM, or zero (0) otherwise.
+image.loaded_through_softlist (read-only)
+ A Boolean indicating whether the mounted media image was loaded from a
+ software list, or ``false`` if no media image is mounted.
+image.software_list_name (read-only)
+ The short name of the software list if the mounted media image was loaded
+ from a software list.
+image.software_longname (read-only)
+ The full name of the software item if the mounted media image was loaded
+ from a software list, or ``nil`` otherwise.
+image.software_publisher (read-only)
+ The publisher of the software item if the mounted media image was loaded
+ from a software list, or ``nil`` otherwise.
+image.software_year (read-only)
+ The release year of the software item if the mounted media image was loaded
+ from a software list, or ``nil`` otherwise.
+image.software_parent (read-only)
+ The short name of the parent software item if the mounted media image was
+ loaded from a software list, or ``nil`` otherwise.
+image.device (read-only)
+ The underlying :ref:`device <luascript-ref-device>`.
+
+
+.. _luascript-ref-disound:
+
+Sound device interface
+---------------------
+
+Wraps MAME’s ``device_sound_interface`` class which is a mix-in implemented by
+devices that input and/or output sound.
+
+Instantiation
+~~~~~~~~~~~~~
+
+manager.machine.sounds[tag]
+ Gets an sound device by tag relative to the root machine device, or ``nil``
+ if no such device exists or it is not a slot device.
+
+Properties
+~~~~~~~~~~
+
+sound.inputs (read-only)
+ Number of sound inputs of the device.
+
+sound.outputs (read-only)
+ Number of sound outputs of the device.
+
+sound.microphone (read-only)
+ True if the device is a microphone, false otherwise
+
+sound.speaker (read-only)
+ True if the device is a speaker, false otherwise
+
+sound.io_positions[] (read-only)
+ Non-empty only for microphones and speakers, indicates the positions of
+ the inputs or outputs as (x, y, z) coordinates (e.g. [-0.2, 0.0, 1.0])
+
+sound.io_names[] (read-only)
+ Non-empty only for microphones and speakers, indicates the positions of
+ the inputs or outputs as strings (e.g. Front Left)
+
+sound.hook
+ A boolean indicating whether to tap the output samples of this device in
+ the global sound hook.
+
+sound.device (read-only)
+ The underlying :ref:`device <luascript-ref-device>`.
+
+
+.. _luascript-ref-dislot:
+
+Slot device interface
+---------------------
+
+Wraps MAME’s ``device_slot_interface`` class which is a mix-in implemented by
+devices that instantiate a user-specified child device.
+
+Instantiation
+~~~~~~~~~~~~~
+
+manager.machine.slots[tag]
+ Gets an slot device by tag relative to the root machine device, or ``nil``
+ if no such device exists or it is not a slot device.
+
+Properties
+~~~~~~~~~~
+
+slot.fixed (read-only)
+ A Boolean indicating whether this is a slot with a card specified in machine
+ configuration that cannot be changed by the user.
+slot.has_selectable_options (read-only)
+ A Boolean indicating whether the slot has any user-selectable options (as
+ opposed to options that can only be selected programmatically, typically for
+ fixed slots or to load media images).
+slot.options[] (read-only)
+ The :ref:`slot options <luascript-ref-slotopt>` describing the child devices
+ that can be instantiated by the slot, indexed by option value. The ``at``
+ and ``index_of`` methods have O(n) complexity; all other supported
+ operations have O(1) complexity.
+slot.device (read-only)
+ The underlying :ref:`device <luascript-ref-device>`.
+
+
+.. _luascript-ref-distateentry:
+
+Device state entry
+------------------
+
+Wraps MAME’s ``device_state_entry`` class, which allows access to named
+registers exposed by a :ref:`device <luascript-ref-device>`. Supports
+conversion to string for display.
+
+Instantiation
+~~~~~~~~~~~~~
+
+manager.machine.devices[tag].state[symbol]
+ Gets a state entry for a given device by symbol.
+
+Properties
+~~~~~~~~~~
+
+entry.value (read/write)
+ The numeric value of the state entry, as either an integer or floating-point
+ number. Attempting to set the value of a read-only state entry raises an
+ error.
+entry.symbol (read-only)
+ The state entry’s symbolic name.
+entry.visible (read-only)
+ A Boolean indicating whether the state entry should be displayed in the
+ debugger register view.
+entry.writeable (read-only)
+ A Boolean indicating whether it is possible to modify the state entry’s
+ value.
+entry.is_float (read-only)
+ A Boolean indicating whether the state entry’s value is a floating-point
+ number.
+entry.datamask (read-only)
+ A bit mask of the valid bits of the value for integer state entries.
+entry.datasize (read-only)
+ The size of the underlying value in bytes for integer state entries.
+entry.max_length (read-only)
+ The maximum display string length for the state entry.
+
+
+.. _luascript-ref-imagefmt:
+
+Media image format
+------------------
+
+Wraps MAME’s ``image_device_format`` class, which describes a media file format
+supported by a :ref:`media image device <luascript-ref-diimage>`.
+
+Instantiation
+~~~~~~~~~~~~~
+
+manager.machine.images[tag].formatlist[name]
+ Gets a media image format supported by a given device by name.
+
+Properties
+~~~~~~~~~~
+
+format.name (read-only)
+ An abbreviated name used to identify the format. This often matches the
+ primary filename extension used for the format.
+format.description (read-only)
+ The full display name of the format.
+format.extensions[] (read-only)
+ Yields a table of filename extensions used for the format.
+format.option_spec (read-only)
+ A string describing options available when creating a media image using this
+ format. The string is not intended to be human-readable.
+
+
+.. _luascript-ref-slotopt:
+
+Slot option
+-----------
+
+Wraps MAME’s ``device_slot_interface::slot_option`` class, which represents a
+child device that a :ref:`slot device <luascript-ref-dislot>` can be
+configured to instantiate.
+
+Instantiation
+~~~~~~~~~~~~~
+
+manager.machine.slots[tag].options[name]
+ Gets a slot option for a given :ref:`slot device <luascript-ref-dislot>` by
+ name (i.e. the value used to select the option).
+
+Properties
+~~~~~~~~~~
+
+option.name (read-only)
+ The name of the slot option. This is the value used to select this option
+ on the command line or in an INI file.
+option.device_fullname (read-only)
+ The full display name of the device type instantiated by this option.
+option.device_shortname (read-only)
+ The short name of the device type instantiated by this option.
+option.selectable (read-only)
+ A Boolean indicating whether the option may be selected by the user (options
+ that are not user-selectable are typically used for fixed slots or to load
+ media images).
+option.default_bios (read-only)
+ The default BIOS setting for the device instantiated using this option, or
+ ``nil`` if the default BIOS specified in the device’s ROM definitions will
+ be used.
+option.clock (read-only)
+ The configured clock frequency for the device instantiated using this
+ option. This is an unsigned 32-bit integer. If the eight most-significant
+ bits are all set, it is a ratio of the parent device’s clock frequency, with
+ the numerator in bits 12-23 and the denominator in bits 0-11. If the eight
+ most-significant bits are not all set, it is a frequency in Hertz.
diff --git a/docs/source/luascript/ref-input.rst b/docs/source/luascript/ref-input.rst
new file mode 100644
index 00000000000..f146d6c78ff
--- /dev/null
+++ b/docs/source/luascript/ref-input.rst
@@ -0,0 +1,766 @@
+.. _luascript-ref-input:
+
+Lua Input System Classes
+========================
+
+Allows scripts to get input from the user, and access I/O ports in the emulated
+system.
+
+.. contents::
+ :local:
+ :depth: 1
+
+
+.. _luascript-ref-ioportman:
+
+I/O port manager
+----------------
+
+Wraps MAME’s ``ioport_manager`` class, which provides access to emulated I/O
+ports and handles input configuration.
+
+Instantiation
+~~~~~~~~~~~~~
+
+manager.machine.ioport
+ Gets the global I/O port manager instance for the emulated machine.
+
+Methods
+~~~~~~~
+
+ioport:count_players()
+ Returns the number of player controllers in the system.
+ioport:type_pressed(type, [player])
+ Returns a Boolean indicating whether the specified input is currently
+ pressed. The input type may be an enumerated value or an
+ :ref:`input type <luascript-ref-inputtype>` entry. If the input type is an
+ enumerated value, the player number may be supplied as a zero-based index;
+ if the player number is not supplied, it is assumed to be zero. If the
+ input type is an input type entry, the player number may not be supplied
+ separately.
+ioport:type_name(type, [player])
+ Returns the display name for the specified input type and player number.
+ The input type is an enumerated value. The player number is a zero-based
+ index. If the player number is not supplied, it is assumed to be zero.
+ioport:type_group(type, player)
+ Returns the input group for the specified input type and player number. The
+ input type is an enumerated value. The player number is a zero-based index.
+ Returns an integer giving the grouping for the input. If the player number
+ is not supplied, it is assumed to be zero.
+
+ This should be called with values obtained from I/O port fields to provide
+ canonical grouping in an input configuration UI.
+ioport:type_seq(type, [player], [seqtype])
+ Get the configured :ref:`input sequence <luascript-ref-inputseq>` for the
+ specified input type, player number and sequence type. The input type may
+ be an enumerated value or an
+ :ref:`input type <luascript-ref-inputtype>` entry. If the input type is an
+ enumerated value, the player number may be supplied as a zero-based index;
+ if the player number is not supplied, it is assumed to be zero. If the
+ input type is an input type entry, the player number may not be supplied
+ separately. If the sequence type is supplied, it must be ``"standard"``,
+ ``"increment"`` or ``"decrement"``; if it is not supplied, it is assumed to
+ be ``"standard"``.
+
+ This provides access to general input assignments.
+ioport:set_type_seq(type, [player], seqtype, seq)
+ Set the configured :ref:`input sequence <luascript-ref-inputseq>` for the
+ specified input type, player number and sequence type. The input type may
+ be an enumerated value or an
+ :ref:`input type <luascript-ref-inputtype>` entry. If the input type is an
+ enumerated value, the player number must be supplied as a zero-based index.
+ If the input type is an input type entry, the player number may not be
+ supplied separately. The sequence type must be ``"standard"``,
+ ``"increment"`` or ``"decrement"``.
+
+ This allows general input assignments to be set.
+ioport:token_to_input_type(string)
+ Returns the input type and player number for the specified input type token
+ string.
+ioport:input_type_to_token(type, [player])
+ Returns the token string for the specified input type and player number. If
+ the player number is not supplied, it assumed to be zero.
+
+Properties
+~~~~~~~~~~
+
+ioport.types[] (read-only)
+ Gets the supported :ref:`input types <luascript-ref-inputtype>`. Keys are
+ arbitrary indices. All supported operations have O(1) complexity.
+ioport.ports[]
+ Gets the emulated :ref:`I/O ports <luascript-ref-ioport>` in the system.
+ Keys are absolute tags. The ``at`` and ``index_of`` methods have O(n)
+ complexity; all other supported operations have O(1) complexity.
+
+
+.. _luascript-ref-natkbdman:
+
+Natural keyboard manager
+------------------------
+
+Wraps MAME’s ``natural_keyboard`` class, which manages emulated keyboard and
+keypad inputs.
+
+Instantiation
+~~~~~~~~~~~~~
+
+manager.machine.natkeyboard
+ Gets the global natural keyboard manager instance for the emulated machine.
+
+Methods
+~~~~~~~
+
+natkeyboard:post(text)
+ Post literal text to the emulated machine. The machine must have keyboard
+ inputs with character bindings, and the correct keyboard input device must
+ be enabled.
+natkeyboard:post_coded(text)
+ Post text to the emulated machine. Brace-enclosed codes are interpreted in
+ the text. The machine must have keyboard inputs with character bindings,
+ and the correct keyboard input device must be enabled.
+
+ The recognised codes are ``{BACKSPACE}``, ``{BS}``, ``{BKSP}``, ``{DEL}``,
+ ``{DELETE}``, ``{END}``, ``{ENTER}``, ``{ESC}``, ``{HOME}``, ``{INS}``,
+ ``{INSERT}``, ``{PGDN}``, ``{PGUP}``, ``{SPACE}``, ``{TAB}``, ``{F1}``,
+ ``{F2}``, ``{F3}``, ``{F4}``, ``{F5}``, ``{F6}``, ``{F7}``, ``{F8}``,
+ ``{F9}``, ``{F10}``, ``{F11}``, ``{F12}``, and ``{QUOTE}``.
+natkeyboard:paste()
+ Post the contents of the host clipboard to the emulated machine. The
+ machine must have keyboard inputs with character bindings, and the correct
+ keyboard input device must be enabled.
+natkeyboard:dump()
+ Returns a string with a human-readable description of the keyboard and
+ keypad input devices in the system, whether they are enabled, and their
+ character bindings.
+
+Properties
+~~~~~~~~~~
+
+natkeyboard.empty (read-only)
+ A Boolean indicating whether the natural keyboard manager’s input buffer is
+ empty.
+natkeyboard.full (read-only)
+ A Boolean indicating whether the natural keyboard manager’s input buffer is
+ full.
+natkeyboard.can_post (read-only)
+ A Boolean indicating whether the emulated system supports posting character
+ data via the natural keyboard manager.
+natkeyboard.is_posting (read-only)
+ A Boolean indicating whether posted character data is currently being
+ delivered to the emulated system.
+natkeyboard.in_use (read/write)
+ A Boolean indicating whether “natural keyboard” mode is enabled. When
+ “natural keyboard” mode is enabled, the natural keyboard manager translates
+ host character input to emulated system keystrokes.
+natkeyboard.keyboards[]
+ Gets the :ref:`keyboard/keypad input devices <luascript-ref-natkbddev>` in
+ the emulated system, indexed by absolute device tag. Index get has O(n)
+ complexity; all other supported operations have O(1) complexity.
+
+
+.. _luascript-ref-natkbddev:
+
+Keyboard input device
+---------------------
+
+Represents a keyboard or keypad input device managed by the
+:ref:`natural keyboard manager <luascript-ref-natkbdman>`. Note that this is
+not a :ref:`device <luascript-ref-device>` class.
+
+Instantiation
+~~~~~~~~~~~~~
+
+manager.machine.natkeyboard.keyboards[tag]
+ Gets the keyboard input device with the specified tag, or ``nil`` if the tag
+ does not correspond to a keyboard input device.
+
+Properties
+~~~~~~~~~~
+
+keyboard.device (read-only)
+ The underlying :ref:`device <luascript-ref-device>`.
+keyboard.tag (read-only)
+ The absolute tag of the underlying device.
+keyboard.basetag (read-only)
+ The last component of the tag of the underlying device, or ``"root"`` for
+ the root machine device.
+keyboard.name (read-only)
+ The human-readable description of the underlying device type.
+keyboard.shortname (read-only)
+ The identifier for the underlying device type.
+keyboard.is_keypad (read-only)
+ A Boolean indicating whether the underlying device has keypad inputs but no
+ keyboard inputs. This is used when determining which keyboard input devices
+ should be enabled by default.
+keyboard.enabled (read/write)
+ A Boolean indicating whether the device’s keyboard and/or keypad inputs are
+ enabled.
+
+
+.. _luascript-ref-ioport:
+
+I/O port
+--------
+
+Wraps MAME’s ``ioport_port`` class, representing an emulated I/O port.
+
+Instantiation
+~~~~~~~~~~~~~
+
+manager.machine.ioport.ports[tag]
+ Gets an emulated I/O port by absolute tag, or ``nil`` if the tag does not
+ correspond to an I/O port.
+manager.machine.devices[devtag]:ioport(porttag)
+ Gets an emulated I/O port by tag relative to a device, or ``nil`` if no such
+ I/O port exists.
+
+Methods
+~~~~~~~
+
+port:read()
+ Read the current input value. Returns a 32-bit integer.
+port:write(value, mask)
+ Write to the I/O port output fields that are set in the specified mask. The
+ value and mask must be 32-bit integers. Note that this does not set values
+ for input fields.
+port:field(mask)
+ Get the first :ref:`I/O port field <luascript-ref-ioportfield>`
+ corresponding to the bits that are set in the specified mask, or ``nil`` if
+ there is no corresponding field.
+
+Properties
+~~~~~~~~~~
+
+port.device (read-only)
+ The device that owns the I/O port.
+port.tag (read-only)
+ The absolute tag of the I/O port
+port.active (read-only)
+ A mask indicating which bits of the I/O port correspond to active fields
+ (i.e. not unused or unassigned bits).
+port.live (read-only)
+ The live state of the I/O port.
+port.fields[] (read-only)
+ Gets a table of :ref:`fields <luascript-ref-ioportfield>` indexed by name.
+
+
+.. _luascript-ref-ioportfield:
+
+I/O port field
+--------------
+
+Wraps MAME’s ``ioport_field`` class, representing a field within an I/O port.
+
+Instantiation
+~~~~~~~~~~~~~
+
+manager.machine.ioport.ports[tag]:field(mask)
+ Gets a field for the given port by bit mask.
+manager.machine.ioport.ports[tag].fields[name]
+ Gets a field for the given port by display name.
+
+Methods
+~~~~~~~
+
+field:set_value(value)
+ Set the value of the I/O port field. For digital fields, the value is
+ compared to zero to determine whether the field should be active; for
+ analog fields, the value must be right-aligned and in the correct range.
+field:clear_value()
+ Clear programmatically overridden value and restore the field’s regular
+ behaviour.
+field:set_input_seq(seqtype, seq)
+ Set the :ref:`input sequence <luascript-ref-inputseq>` for the specified
+ sequence type. This is used to configure per-machine input settings. The
+ sequence type must be ``"standard"``, ``"increment"`` or ``"decrement"``.
+field:input_seq(seq_type)
+ Get the configured :ref:`input sequence <luascript-ref-inputseq>` for the
+ specified sequence type. This gets per-machine input assignments. The
+ sequence type must be ``"standard"``, ``"increment"`` or ``"decrement"``.
+field:set_default_input_seq(seq_type, seq)
+ Set the default :ref:`input sequence <luascript-ref-inputseq>` for the
+ specified sequence type. This overrides the default input assignment for a
+ specific input. The sequence type must be ``"standard"``, ``"increment"``
+ or ``"decrement"``.
+field:default_input_seq(seq_type)
+ Gets the default :ref:`input sequence <luascript-ref-inputseq>` for the
+ specified sequence type. If the default assignment is not overridden, this
+ returns the general input assignment for the field’s input type. The
+ sequence type must be ``"standard"``, ``"increment"`` or ``"decrement"``.
+field:keyboard_codes(shift)
+ Gets a table of characters corresponding to the field for the specified
+ shift state. The shift state is a bit mask of active shift keys.
+
+Properties
+~~~~~~~~~~
+
+field.device (read-only)
+ The device that owns the port that the field belongs to.
+field.port (read-only)
+ The :ref:`I/O port <luascript-ref-ioport>` that the field belongs to.
+field.live (read-only)
+ The :ref:`live state <luascript-ref-ioportfieldlive>` of the field.
+field.type (read-only)
+ The input type of the field. This is an enumerated value.
+field.name (read-only)
+ The display name for the field.
+field.default_name (read-only)
+ The name for the field from the emulated system’s configuration (cannot be
+ overridden by scripts or plugins).
+field.player (read-only)
+ Zero-based player number for the field.
+field.mask (read-only)
+ Bits in the I/O port corresponding to this field.
+field.defvalue (read-only)
+ The field’s default value.
+field.minvalue (read-only)
+ The minimum allowed value for analog fields, or ``nil`` for digital fields.
+field.maxvalue (read-only)
+ The maximum allowed value for analog fields, or ``nil`` for digital fields.
+field.sensitivity (read-only)
+ The sensitivity or gain for analog fields, or ``nil`` for digital fields.
+field.way (read-only)
+ The number of directions allowed by the restrictor plate/gate for a digital
+ joystick, or zero (0) for other inputs.
+field.type_class (read-only)
+ The type class for the input field – one of ``"keyboard"``,
+ ``"controller"``, ``"config"``, ``"dipswitch"`` or ``"misc"``.
+field.is_analog (read-only)
+ A Boolean indicating whether the field is an analog axis or positional
+ control.
+field.is_digital_joystick (read-only)
+ A Boolean indicating whether the field corresponds to a digital joystick
+ switch.
+field.enabled (read-only)
+ A Boolean indicating whether the field is enabled.
+field.optional (read-only)
+ A Boolean indicating whether the field is optional and not required to use
+ the emulated system.
+field.cocktail (read-only)
+ A Boolean indicating whether the field is only used when the system is
+ configured for a cocktail table cabinet.
+field.toggle (read-only)
+ A Boolean indicating whether the field corresponds to a hardware toggle
+ switch or push-on, push-off button.
+field.rotated (read-only)
+ A Boolean indicating whether the field corresponds to a control that is
+ rotated relative its standard orientation.
+field.analog_reverse (read-only)
+ A Boolean indicating whether the field corresponds to an analog control that
+ increases in the opposite direction to the convention (e.g. larger values
+ when a pedal is released or a joystick is moved to the left).
+field.analog_reset (read-only)
+ A Boolean indicating whether the field corresponds to an incremental
+ position input (e.g. a dial or trackball axis) that should be reset to zero
+ for every video frame.
+field.analog_wraps (read-only)
+ A Boolean indicating whether the field corresponds to an analog input that
+ wraps from one end of its range to the other (e.g. an incremental position
+ input like a dial or trackball axis).
+field.analog_invert (read-only)
+ A Boolean indicating whether the field corresponds to an analog input that
+ has its value ones-complemented.
+field.impulse (read-only)
+ A Boolean indicating whether the field corresponds to a digital input that
+ activates for a fixed amount of time.
+field.crosshair_scale (read-only)
+ The scale factor for translating the field’s range to crosshair position. A
+ value of one (1) translates the field’s full range to the full width or
+ height the screen.
+field.crosshair_offset (read-only)
+ The offset for translating the field’s range to crosshair position.
+field.user_value (read/write)
+ The value for DIP switch or configuration settings.
+field.settings[] (read-only)
+ Gets a table of the currently enabled settings for a DIP switch or
+ configuration field, indexed by value.
+
+
+.. _luascript-ref-ioportfieldlive:
+
+Live I/O port field state
+-------------------------
+
+Wraps MAME’s ``ioport_field_live`` class, representing the live state of an I/O
+port field.
+
+Instantiation
+~~~~~~~~~~~~~
+
+manager.machine.ioport.ports[tag]:field(mask).live
+ Gets the live state for an I/O port field.
+
+Properties
+~~~~~~~~~~
+
+live.name
+ Display name for the field.
+
+
+.. _luascript-ref-inputtype:
+
+Input type
+----------
+
+Wraps MAME’s ``input_type_entry`` class, representing an emulated input type or
+emulator UI input type. Input types are uniquely identified by the combination
+of their enumerated type value and player index.
+
+Instantiation
+~~~~~~~~~~~~~
+
+manager.machine.ioport.types[index]
+ Gets a supported input type.
+
+Properties
+~~~~~~~~~~
+
+type.type (read-only)
+ An enumerated value representing the type of input.
+type.group (read-only)
+ An integer giving the grouping for the input type. Should be used to
+ provide canonical grouping in an input configuration UI.
+type.player (read-only)
+ The zero-based player number, or zero for non-player controls.
+type.token (read-only)
+ The token string for the input type, used in configuration files.
+type.name (read-only)
+ The display name for the input type.
+type.is_analog (read-only)
+ A Boolean indicating whether the input type is analog or digital. Inputs
+ that only have on and off states are considered digital, while all other
+ inputs are considered analog, even if they can only represent discrete
+ values or positions.
+
+
+.. _luascript-ref-inputman:
+
+Input manager
+-------------
+
+Wraps MAME’s ``input_manager`` class, which reads host input devices and checks
+whether configured inputs are active.
+
+Instantiation
+~~~~~~~~~~~~~
+
+manager.machine.input
+ Gets the global input manager instance for the emulated system.
+
+Methods
+~~~~~~~
+
+input:code_value(code)
+ Gets the current value for the host input corresponding to the specified
+ code. Returns a signed integer value, where zero is the neutral position.
+input:code_pressed(code)
+ Returns a Boolean indicating whether the host input corresponding to the
+ specified code has a non-zero value (i.e. it is not in the neutral
+ position).
+input:code_pressed_once(code)
+ Returns a Boolean indicating whether the host input corresponding to the
+ specified code has moved away from the neutral position since the last time
+ it was checked using this function. The input manager can track a limited
+ number of inputs this way.
+input:code_name(code)
+ Get display name for an input code.
+input:code_to_token(code)
+ Get token string for an input code. This should be used when saving
+ configuration.
+input:code_from_token(token)
+ Convert a token string to an input code. Returns the invalid input code if
+ the token is not valid or belongs to an input device that is not present.
+input:seq_pressed(seq)
+ Returns a Boolean indicating whether the supplied
+ :ref:`input sequence <luascript-ref-inputseq>` is currently pressed.
+input:seq_clean(seq)
+ Remove invalid elements from the supplied
+ :ref:`input sequence <luascript-ref-inputseq>`. Returns the new, cleaned
+ input sequence.
+input:seq_name(seq)
+ Get display text for an :ref:`input sequence <luascript-ref-inputseq>`.
+input:seq_to_tokens(seq)
+ Convert an :ref:`input sequence <luascript-ref-inputseq>` to a token string.
+ This should be used when saving configuration.
+input:seq_from_tokens(tokens)
+ Convert a token string to an
+ :ref:`input sequence <luascript-ref-inputseq>`. This should be used when
+ loading configuration.
+input:axis_code_poller()
+ Returns an :ref:`input code poller <luascript-ref-inputcodepoll>` for
+ obtaining an analog host input code.
+input:switch_code_poller()
+ Returns an :ref:`input code poller <luascript-ref-inputcodepoll>` for
+ obtaining a host switch input code.
+input:keyboard_code_poller()
+ Returns an :ref:`input code poller <luascript-ref-inputcodepoll>` for
+ obtaining a host switch input code that only considers keyboard input
+ devices.
+input:axis_sequence_poller()
+ Returns an :ref:`input sequence poller <luascript-ref-inputseqpoll>` for
+ obtaining an :ref:`input sequence <luascript-ref-inputseq>` for configuring
+ an analog input assignment.
+input:axis_sequence_poller()
+ Returns an :ref:`input sequence poller <luascript-ref-inputseqpoll>` for
+ obtaining an :ref:`input sequence <luascript-ref-inputseq>` for configuring
+ a digital input assignment.
+
+Properties
+~~~~~~~~~~
+
+input.device_classes[] (read-only)
+ Gets a table of host
+ :ref:`input device classes <luascript-ref-inputdevclass>` indexed by name.
+
+
+.. _luascript-ref-inputcodepoll:
+
+Input code poller
+-----------------
+
+Wraps MAME’s ``input_code_poller`` class, used to poll for host inputs being
+activated.
+
+Instantiation
+~~~~~~~~~~~~~
+
+manager.machine.input:axis_code_poller()
+ Returns an input code poller that polls for analog inputs being activated.
+manager.machine.input:switch_code_poller()
+ Returns an input code poller that polls for host switch inputs being
+ activated.
+manager.machine.input:keyboard_code_poller()
+ Returns an input code poller that polls for host switch inputs being
+ activated, only considering keyboard input devices.
+
+Methods
+~~~~~~~
+
+poller:reset()
+ Resets the polling logic. Active switch inputs are cleared and initial
+ analog input positions are set.
+poller:poll()
+ Returns an input code corresponding to the first relevant host input that
+ has been activated since the last time the method was called. Returns the
+ invalid input code if no relevant input has been activated.
+
+
+.. _luascript-ref-inputseqpoll:
+
+Input sequence poller
+---------------------
+
+Wraps MAME’s ``input_sequence_poller`` poller class, which allows users to
+assign host input combinations to emulated inputs and other actions.
+
+Instantiation
+~~~~~~~~~~~~~
+
+manager.machine.input:axis_sequence_poller()
+ Returns an input sequence poller for assigning host inputs to an analog
+ input.
+manager.machine.input:switch_sequence_poller()
+ Returns an input sequence poller for assigning host inputs to a switch
+ input.
+
+Methods
+~~~~~~~
+
+poller:start([seq])
+ Start polling. If a sequence is supplied, it is used as a starting
+ sequence: for analog inputs, the user can cycle between the full range, and
+ the positive and negative portions of an axis; for switch inputs, an “or”
+ code is appended and the user can add an alternate host input combination.
+poller:poll()
+ Polls for user input and updates the sequence if appropriate. Returns a
+ Boolean indicating whether sequence input is complete. If this method
+ returns false, you should continue polling.
+
+Properties
+~~~~~~~~~~
+
+poller.sequence (read-only)
+ The current :ref:`input sequence <luascript-ref-inputseq>`. This is updated
+ while polling. It is possible for the sequence to become invalid.
+poller.valid (read-only)
+ A Boolean indicating whether the current input sequence is valid.
+poller.modified (read-only)
+ A Boolean indicating whether the sequence was changed by any user input
+ since starting polling.
+
+
+.. _luascript-ref-inputseq:
+
+Input sequence
+--------------
+
+Wraps MAME’s ``input_seq`` class, representing a combination of host inputs that
+can be read or assigned to an emulated input. Input sequences can be
+manipulated using :ref:`input manager <luascript-ref-inputman>` methods. Use an
+:ref:`input sequence poller <luascript-ref-inputseqpoll>` to obtain an input
+sequence from the user.
+
+Instantiation
+~~~~~~~~~~~~~
+
+emu.input_seq()
+ Creates an empty input sequence.
+emu.input_seq(seq)
+ Creates a copy of an existing input sequence.
+
+Methods
+~~~~~~~
+
+seq:reset()
+ Clears the input sequence, removing all items.
+seq:set_default()
+ Sets the input sequence to a single item containing the metavalue specifying
+ that the default setting should be used.
+
+Properties
+~~~~~~~~~~
+
+seq.empty (read-only)
+ A Boolean indicating whether the input sequence is empty (contains no items,
+ indicating an unassigned input).
+seq.length (read-only)
+ The number of items in the input sequence.
+seq.is_valid (read-only)
+ A Boolean indicating whether the input sequence is a valid. To be valid, it
+ must contain at least one item, all items must be valid codes, all product
+ groups must contain at least one item that is not negated, and items
+ referring to absolute and relative axes must not be mixed within a product
+ group.
+seq.is_default (read-only)
+ A Boolean indicating whether the input sequence specifies that the default
+ setting should be used.
+
+
+.. _luascript-ref-inputdevclass:
+
+Host input device class
+-----------------------
+
+Wraps MAME’s ``input_class`` class, representing a category of host input
+devices (e.g. keyboards or joysticks).
+
+Instantiation
+~~~~~~~~~~~~~
+
+manager.machine.input.device_classes[name]
+ Gets an input device class by name.
+
+Properties
+~~~~~~~~~~
+
+devclass.name (read-only)
+ The device class name.
+devclass.enabled (read-only)
+ A Boolean indicating whether the device class is enabled.
+devclass.multi (read-only)
+ A Boolean indicating whether the device class supports multiple devices, or
+ inputs from all devices in the class are combined and treated as a single
+ device.
+devclass.devices[] (read-only)
+ Gets a table of :ref:`host input devices <luascript-ref-inputdev>` in the
+ class. Keys are one-based indices.
+
+
+.. _luascript-ref-inputdev:
+
+Host input device
+-----------------
+
+Wraps MAME’s ``input_device`` class, representing a host input device.
+
+Instantiation
+~~~~~~~~~~~~~
+
+manager.machine.input.device_classes[name].devices[index]
+ Gets a specific host input device.
+
+Properties
+~~~~~~~~~~
+
+inputdev.name (read-only)
+ Display name for the device. This is not guaranteed to be unique.
+inputdev.id (read-only)
+ Unique identifier string for the device. This may not be human-readable.
+inputdev.devindex (read-only)
+ Device index within the device class. This is not necessarily the same as
+ the index in the ``devices`` property of the device class – the ``devindex``
+ indices may not be contiguous.
+inputdev.items (read-only)
+ Gets a table of :ref:`input items <luascript-ref-inputdevitem>`, indexed
+ by item ID. The item ID is an enumerated value.
+
+
+.. _luascript-ref-inputdevitem:
+
+Host input device item
+----------------------
+
+Wraps MAME’s ``input_device_item`` class, representing a single host input (e.g.
+a key, button, or axis).
+
+Instantiation
+~~~~~~~~~~~~~
+
+manager.machine.input.device_classes[name].devices[index].items[id]
+ Gets an individual host input item. The item ID is an enumerated value.
+
+Properties
+~~~~~~~~~~
+
+item.name (read-only)
+ The display name of the input item. Note that this is just the name of the
+ item itself, and does not include the device name. The full display name
+ for the item can be obtained by calling the ``code_name`` method on the
+ :ref:`input manager <luascript-ref-inputman>` with the item’s code.
+item.code (read-only)
+ The input item’s identification code. This is used by several
+ :ref:`input manager <luascript-ref-inputman>` methods.
+item.token (read-only)
+ The input item’s token string. Note that this is a token fragment for the
+ item itself, and does not include the device portion. The full token for
+ the item can be obtained by calling the ``code_to_token`` method on the
+ :ref:`input manager <luascript-ref-inputman>` with the item’s code.
+item.current (read-only)
+ The item’s current value. This is a signed integer where zero is the
+ neutral position.
+
+
+.. _luascript-ref-uiinputman:
+
+UI input manager
+----------------
+
+Wraps MAME’s ``ui_input_manager`` class, which is used for high-level input.
+
+Instantiation
+~~~~~~~~~~~~~
+
+manager.machine.uiinput
+ Gets the global UI input manager instance for the machine.
+
+Methods
+~~~~~~~
+
+uiinput:reset()
+ Clears pending events and UI input states. Should be called when leaving a
+ modal state where input is handled directly (e.g. configuring an input
+ combination).
+uiinput:pressed(type)
+ Returns a Boolean indicating whether the specified UI input has been
+ pressed. The input type is an enumerated value.
+uiinput:pressed_repeat(type, speed)
+ Returns a Boolean indicating whether the specified UI input has been
+ pressed or auto-repeat has been triggered at the specified speed. The input
+ type is an enumerated value; the speed is an interval in sixtieths of a
+ second.
+
+Properties
+~~~~~~~~~~
+
+uiinput.presses_enabled (read/write)
+ Whether the UI input manager will check for UI inputs frame updates.
diff --git a/docs/source/luascript/ref-mem.rst b/docs/source/luascript/ref-mem.rst
new file mode 100644
index 00000000000..0987889d3dc
--- /dev/null
+++ b/docs/source/luascript/ref-mem.rst
@@ -0,0 +1,459 @@
+.. _luascript-ref-mem:
+
+Lua Memory System Classes
+=========================
+
+MAME’s Lua interface exposes various memory system objects, including address
+spaces, memory shares, memory banks, and memory regions. Scripts can read from
+and write to the emulated memory system.
+
+.. contents::
+ :local:
+ :depth: 1
+
+
+.. _luascript-ref-memman:
+
+Memory manager
+--------------
+
+Wraps MAME’s ``memory_manager`` class, which allows the memory shares, banks and
+regions in a system to be enumerated.
+
+Instantiation
+~~~~~~~~~~~~~
+
+manager.machine.memory
+ Gets the global memory manager instance for the emulated system.
+
+Properties
+~~~~~~~~~~
+
+memory.shares[]
+ The :ref:`memory shares <luascript-ref-memshare>` in the system, indexed by
+ absolute tag. The ``at`` and ``index_of`` methods have O(n) complexity; all
+ other supported operations have O(1) complexity.
+memory.banks[]
+ The :ref:`memory banks <luascript-ref-membank>` in the system, indexed by
+ absolute tag. The ``at`` and ``index_of`` methods have O(n) complexity; all
+ other supported operations have O(1) complexity.
+memory.regions[]
+ The :ref:`memory regions <luascript-ref-memregion>` in the system, indexed
+ by absolute tag. The ``at`` and ``index_of`` methods have O(n) complexity;
+ all other supported operations have O(1) complexity.
+
+
+.. _luascript-ref-addrspace:
+
+Address space
+-------------
+
+Wraps MAME’s ``address_space`` class, which represents an address space
+belonging to a device.
+
+Instantiation
+~~~~~~~~~~~~~
+
+manager.machine.devices[tag].spaces[name]
+ Gets the address space with the specified name for a given device. Note
+ that names are specific to the device type.
+
+Methods
+~~~~~~~
+
+space:read_i{8,16,32,64}(addr)
+ Reads a signed integer value of the size in bits from the specified address.
+space:read_u{8,16,32,64}(addr)
+ Reads an unsigned integer value of the size in bits from the specified
+ address.
+space:write_i{8,16,32,64}(addr, val)
+ Writes a signed integer value of the size in bits to the specified address.
+space:write_u{8,16,32,64}(addr, val)
+ Writes an unsigned integer value of the size in bits to the specified
+ address.
+space:readv_i{8,16,32,64}(addr)
+ Reads a signed integer value of the size in bits from the specified virtual
+ address. The address is translated with the debug read intent. Returns
+ zero if address translation fails.
+space:readv_u{8,16,32,64}(addr)
+ Reads an unsigned integer value of the size in bits from the specified
+ virtual address. The address is translated with the debug read intent.
+ Returns zero if address translation fails.
+space:writev_i{8,16,32,64}(addr, val)
+ Writes a signed integer value of the size in bits to the specified virtual
+ address. The address is translated with the debug write intent. Does not
+ write if address translation fails.
+space:writev_u{8,16,32,64}(addr, val)
+ Writes an unsigned integer value of the size in bits to the specified
+ virtual address. The address is translated with the debug write intent.
+ Does not write if address translation fails.
+space:read_direct_i{8,16,32,64}(addr)
+ Reads a signed integer value of the size in bits from the specified address
+ one byte at a time by obtaining a read pointer for each byte address. If
+ a read pointer cannot be obtained for a byte address, the corresponding
+ result byte will be zero.
+space:read_direct_u{8,16,32,64}(addr)
+ Reads an unsigned integer value of the size in bits from the specified
+ address one byte at a time by obtaining a read pointer for each byte
+ address. If a read pointer cannot be obtained for a byte address, the
+ corresponding result byte will be zero.
+space:write_direct_i{8,16,32,64}(addr, val)
+ Writes a signed integer value of the size in bits to the specified address
+ one byte at a time by obtaining a write pointer for each byte address. If
+ a write pointer cannot be obtained for a byte address, the corresponding
+ byte will not be written.
+space:write_direct_u{8,16,32,64}(addr, val)
+ Writes an unsigned integer value of the size in bits to the specified
+ address one byte at a time by obtaining a write pointer for each byte
+ address. If a write pointer cannot be obtained for a byte address, the
+ corresponding byte will not be written.
+space:read_range(start, end, width, [step])
+ Reads a range of addresses as a binary string. The end address must be
+ greater than or equal to the start address. The width must be 8, 16, 30 or
+ 64. If the step is provided, it must be a positive number of elements.
+space:add_change_notifier(callback)
+ Add a callback to receive notifications for handler changes in address
+ space. The callback function is passed a single string as an argument,
+ either ``r`` if read handlers have potentially changed, ``w`` if write
+ handlers have potentially changed, or ``rw`` if both read and write handlers
+ have potentially changed.
+
+ Returns a :ref:`notifier subscription <luascript-ref-notifiersub>`.
+space:install_read_tap(start, end, name, callback)
+ Installs a :ref:`pass-through handler <luascript-ref-addrspacetap>` that
+ will receive notifications on reads from the specified range of addresses in
+ the address space. The start and end addresses are inclusive. The name
+ must be a string, and the callback must be a function.
+
+ The callback is passed three arguments for the access offset, the data read,
+ and the memory access mask. The offset is the absolute offset into the
+ address space. To modify the data being read, return the modified value
+ from the callback function as an integer. If the callback does not return
+ an integer, the data will not be modified.
+space:install_write_tap(start, end, name, callback)
+ Installs a :ref:`pass-through handler <luascript-ref-addrspacetap>` that
+ will receive notifications on write to the specified range of addresses in
+ the address space. The start and end addresses are inclusive. The name
+ must be a string, and the callback must be a function.
+
+ The callback is passed three arguments for the access offset, the data
+ written, and the memory access mask. The offset is the absolute offset into
+ the address space. To modify the data being written, return the modified
+ value from the callback function as an integer. If the callback does not
+ return an integer, the data will not be modified.
+
+Properties
+~~~~~~~~~~
+
+space.name (read-only)
+ The display name for the address space.
+space.shift (read-only)
+ The address granularity for the address space specified as the shift
+ required to translate a byte address to a native address. Positive values
+ shift towards the most significant bit (left) and negative values shift
+ towards the least significant bit (right).
+space.index (read-only)
+ The zero-based space index. Some space indices have special meanings for
+ the debugger.
+space.address_mask (read-only)
+ The address mask for the space.
+space.data_width (read-only)
+ The data width for the space in bits.
+space.endianness (read-only)
+ The Endianness of the space (``"big"`` or ``"little"``).
+space.map (read-only)
+ The configured :ref:`address map <luascript-ref-addrmap>` for the space or
+ ``nil``.
+
+
+.. _luascript-ref-addrspacetap:
+
+Pass-through handler
+--------------------
+
+Tracks a pass-through handler installed in an
+:ref:`address space <luascript-ref-addrspace>`. A memory pass-through handler
+receives notifications on accesses to a specified range of addresses, and can
+modify the data that is read or written if desired. Note that pass-through handler
+callbacks are not run as coroutines.
+
+Instantiation
+~~~~~~~~~~~~~
+
+manager.machine.devices[tag].spaces[name]:install_read_tap(start, end, name, callback)
+ Installs a pass-through handler that will receive notifications on reads
+ from the specified range of addresses in an
+ :ref:`address space <luascript-ref-addrspace>`.
+manager.machine.devices[tag].spaces[name]:install_write_tap(start, end, name, callback)
+ Installs a pass-through handler that will receive notifications on writes to
+ the specified range of addresses in an
+ :ref:`address space <luascript-ref-addrspace>`.
+
+Methods
+~~~~~~~
+
+passthrough:reinstall()
+ Reinstalls the pass-through handler in the address space. May be necessary
+ if the handler is removed due to other changes to handlers in the address
+ space.
+passthrough:remove()
+ Removes the pass-through handler from the address space. The associated
+ callback will not be called in response to future memory accesses.
+
+Properties
+~~~~~~~~~~
+
+passthrough.addrstart (read-only)
+ The inclusive start address of the address range monitored by the
+ pass-through handler (i.e. the lowest address that the handler will be
+ notified for).
+passthrough.addrend (read-only)
+ The inclusive end address of the address range monitored by the pass-through
+ handler (i.e. the highest address that the handler will be notified for).
+passthrough.name (read-only)
+ The display name for the pass-through handler.
+
+
+.. _luascript-ref-addrmap:
+
+Address map
+-----------
+
+Wraps MAME’s ``address_map`` class, used to configure handlers for an address
+space.
+
+Instantiation
+~~~~~~~~~~~~~
+
+manager.machine.devices[tag].spaces[name].map
+ Gets the configured address map for an address space, or ``nil`` if no map
+ is configured.
+
+Properties
+~~~~~~~~~~
+
+map.spacenum (read-only)
+ The address space number of the address space the map is associated with.
+map.device (read-only)
+ The device that owns the address space the map is associated with.
+map.unmap_value (read-only)
+ The constant value to return from unmapped reads.
+map.global_mask (read-only)
+ Global mask to be applied to all addresses when accessing the space.
+map.entries[] (read-only)
+ The configured :ref:`entries <luascript-ref-addrmapentry>` in the address
+ map. Uses 1-based integer indices. The index operator and the ``at``
+ method have O(n) complexity.
+
+
+.. _luascript-ref-addrmapentry:
+
+Address map entry
+-----------------
+
+Wraps MAME’s ``address_map_entry`` class, representing an entry in a configured
+address map.
+
+Instantiation
+~~~~~~~~~~~~~
+
+manager.machine.devices[tag].spaces[name].map.entries[index]
+ Gets an entry from the configured map for an address space.
+
+Properties
+~~~~~~~~~~
+
+entry.address_start (read-only)
+ Start address of the entry’s range.
+entry.address_end (read-only)
+ End address of the entry’s range (inclusive).
+entry.address_mirror (read-only)
+ Address mirror bits.
+entry.address_mask (read-only)
+ Address mask bits. Only valid for handlers.
+entry.mask (read-only)
+ Lane mask, indicating which data lines on the bus are connected to the
+ handler.
+entry.cswidth (read-only)
+ The trigger width for a handler that isn’t connected to all the data lines.
+entry.read (read-only)
+ :ref:`Additional data <luascript-ref-memhandlerdata>` for the read handler.
+entry.write (read-only)
+ :ref:`Additional data <luascript-ref-memhandlerdata>` for the write handler.
+entry.share (read-only)
+ Memory share tag for making RAM entries accessible or ``nil``.
+entry.region (read-only)
+ Explicit memory region tag for ROM entries, or ``nil``. For ROM entries,
+ ``nil`` infers the region from the device tag.
+entry.region_offset (read-only)
+ Starting offset in memory region for ROM entries.
+
+
+.. _luascript-ref-memhandlerdata:
+
+Address map handler data
+------------------------
+
+Wraps MAME’s ``map_handler_data`` class, which provides configuration data to
+handlers in address maps.
+
+Instantiation
+~~~~~~~~~~~~~
+
+manager.machine.devices[tag].spaces[name].map.entries[index].read
+ Gets the read handler data for an address map entry.
+manager.machine.devices[tag].spaces[name].map.entries[index].write
+ Gets the write handler data for an address map entry.
+
+Properties
+~~~~~~~~~~
+
+data.handlertype (read-only)
+ Handler type. Will be one of ``"none"``, ``"ram"``, ``"rom"``, ``"nop"``,
+ ``"unmap"``, ``"delegate"``, ``"port"``, ``"bank"``, ``"submap"``, or
+ ``"unknown"``. Note that multiple handler type values can yield
+ ``"delegate"`` or ``"unknown"``.
+data.bits (read-only)
+ Data width for the handler in bits.
+data.name (read-only)
+ Display name for the handler, or ``nil``.
+data.tag (read-only)
+ Tag for I/O ports and memory banks, or ``nil``.
+
+
+.. _luascript-ref-memshare:
+
+Memory share
+------------
+
+Wraps MAME’s ``memory_share`` class, representing a named allocated memory zone.
+
+Instantiation
+~~~~~~~~~~~~~
+
+manager.machine.memory.shares[tag]
+ Gets a memory share by absolute tag, or ``nil`` if no such memory share
+ exists.
+manager.machine.devices[tag]:memshare(tag)
+ Gets a memory share by tag relative to a device, or ``nil`` if no such
+ memory share exists.
+
+Methods
+~~~~~~~
+
+share:read_i{8,16,32,64}(offs)
+ Reads a signed integer value of the size in bits from the specified offset
+ in the memory share.
+share:read_u{8,16,32,64}(offs)
+ Reads an unsigned integer value of the size in bits from the specified
+ offset in the memory share.
+share:write_i{8,16,32,64}(offs, val)
+ Writes a signed integer value of the size in bits to the specified offset in
+ the memory share.
+share:write_u{8,16,32,64}(offs, val)
+ Writes an unsigned integer value of the size in bits to the specified offset
+ in the memory share.
+
+Properties
+~~~~~~~~~~
+
+share.tag (read-only)
+ The absolute tag of the memory share.
+share.size (read-only)
+ The size of the memory share in bytes.
+share.length (read-only)
+ The length of the memory share in native width elements.
+share.endianness (read-only)
+ The Endianness of the memory share (``"big"`` or ``"little"``).
+share.bitwidth (read-only)
+ The native element width of the memory share in bits.
+share.bytewidth (read-only)
+ The native element width of the memory share in bytes.
+
+
+.. _luascript-ref-membank:
+
+Memory bank
+-----------
+
+Wraps MAME’s ``memory_bank`` class, representing a named memory zone
+indirection.
+
+Instantiation
+~~~~~~~~~~~~~
+
+manager.machine.memory.banks[tag]
+ Gets a memory region by absolute tag, or ``nil`` if no such memory bank
+ exists.
+manager.machine.devices[tag]:membank(tag)
+ Gets a memory region by tag relative to a device, or ``nil`` if no such
+ memory bank exists.
+
+Properties
+~~~~~~~~~~
+
+bank.tag (read-only)
+ The absolute tag of the memory bank.
+bank.entry (read/write)
+ The currently selected zero-based entry number.
+
+
+.. _luascript-ref-memregion:
+
+Memory region
+-------------
+
+Wraps MAME’s ``memory_region`` class, representing a memory region used to store
+read-only data like ROMs or the result of fixed decryptions.
+
+Instantiation
+~~~~~~~~~~~~~
+
+manager.machine.memory.regions[tag]
+ Gets a memory region by absolute tag, or ``nil`` if no such memory region
+ exists.
+manager.machine.devices[tag]:memregion(tag)
+ Gets a memory region by tag relative to a device, or ``nil`` if no such
+ memory region exists.
+
+Methods
+~~~~~~~
+
+region:read(offs, len)
+ Reads up to the specified length in bytes from the specified offset in the
+ memory region. The bytes read will be returned as a string. If the
+ specified length extends beyond the end of the memory region, the returned
+ string will be shorter than requested. Note that the data will be in host
+ byte order.
+region:read_i{8,16,32,64}(offs)
+ Reads a signed integer value of the size in bits from the specified offset
+ in the memory region. The offset is specified in bytes. Reading beyond the
+ end of the memory region returns zero.
+region:read_u{8,16,32,64}(offs)
+ Reads an unsigned integer value of the size in bits from the specified
+ offset in the memory region. The offset is specified in bytes. Reading
+ beyond the end of the memory region returns zero.
+region:write_i{8,16,32,64}(offs, val)
+ Writes a signed integer value of the size in bits to the specified offset in
+ the memory region. The offset is specified in bytes. Attempting to write
+ beyond the end of the memory region has no effect.
+region:write_u{8,16,32,64}(offs, val)
+ Writes an unsigned integer value of the size in bits to the specified offset
+ in the memory region. The offset is specified in bytes. Attempting to
+ write beyond the end of the memory region has no effect.
+
+Properties
+~~~~~~~~~~
+
+region.tag (read-only)
+ The absolute tag of the memory region.
+region.size (read-only)
+ The size of the memory region in bytes.
+region.length (read-only)
+ The length of the memory region in native width elements.
+region.endianness (read-only)
+ The Endianness of the memory region (``"big"`` or ``"little"``).
+region.bitwidth (read-only)
+ The native element width of the memory region in bits.
+region.bytewidth (read-only)
+ The native element width of the memory region in bytes.
diff --git a/docs/source/luascript/ref-render.rst b/docs/source/luascript/ref-render.rst
new file mode 100644
index 00000000000..1ebe11df3e1
--- /dev/null
+++ b/docs/source/luascript/ref-render.rst
@@ -0,0 +1,1374 @@
+.. _luascript-ref-render:
+
+Lua Render System Classes
+=========================
+
+The render system is responsible for drawing what you see in MAME’s windows,
+including emulated screens, artwork, and UI elements.
+
+.. contents::
+ :local:
+ :depth: 1
+
+
+.. _luascript-ref-renderbounds:
+
+Render bounds
+-------------
+
+Wraps MAME’s ``render_bounds`` class, which represents a rectangle using
+floating-point coordinates.
+
+Instantiation
+~~~~~~~~~~~~~
+
+emu.render_bounds()
+ Creates a render bounds object representing a unit square, with top left
+ corner at (0, 0) and bottom right corner at (1, 1). Note that render
+ target coordinates don’t necessarily have equal X and Y scales, so this may
+ not represent a square in the final output.
+emu.render_bounds(left, top, right, bottom)
+ Creates a render bounds object representing a rectangle with top left
+ corner at (x0, y0) and bottom right corner at (x1, y1).
+
+ The arguments must all be floating-point numbers.
+
+Methods
+~~~~~~~
+
+bounds:includes(x, y)
+ Returns a Boolean indicating whether the specified point falls within the
+ rectangle. The rectangle must be normalised for this to work (right greater
+ than left and bottom greater than top).
+
+ The arguments must both be floating-point numbers.
+bounds:set_xy(left, top, right, bottom)
+ Set the rectangle’s position and size in terms of the positions of the
+ edges.
+
+ The arguments must all be floating-point numbers.
+bounds:set_wh(left, top, width, height)
+ Set the rectangle’s position and size in terms of the top left corner
+ position, and the width and height.
+
+ The arguments must all be floating-point numbers.
+
+Properties
+~~~~~~~~~~
+
+bounds.x0 (read/write)
+ The leftmost coordinate in the rectangle (i.e. the X coordinate of the left
+ edge or the top left corner).
+bounds.x1 (read/write)
+ The rightmost coordinate in the rectangle (i.e. the X coordinate of the
+ right edge or the bottom right corner).
+bounds.y0 (read/write)
+ The topmost coordinate in the rectangle (i.e. the Y coordinate of the top
+ edge or the top left corner).
+bounds.y1 (read/write)
+ The bottommost coordinate in the rectangle (i.e. the Y coordinate of the
+ bottom edge or the bottom right corner).
+bounds.width (read/write)
+ The width of the rectangle. Setting this property changes the position of
+ the rightmost edge.
+bounds.height (read/write)
+ The height of the rectangle. Setting this property changes the position of
+ the bottommost edge.
+bounds.aspect (read-only)
+ The width-to-height aspect ratio of the rectangle. Note that this is often
+ in render target coordinates which don’t necessarily have equal X and Y
+ scales. A rectangle representing a square in the final output doesn’t
+ necessarily have an aspect ratio of 1.
+
+
+.. _luascript-ref-rendercolor:
+
+Render colour
+-------------
+
+Wraps MAME’s ``render_color`` class, which represents an ARGB (alpha, red,
+green, blue) format colour. Channels are floating-point values ranging from
+zero (0, transparent alpha or colour off) to one (1, opaque or full colour
+intensity). Colour channel values are not pre-multiplied by the alpha channel
+value.
+
+Instantiation
+~~~~~~~~~~~~~
+
+emu.render_color()
+ Creates a render colour object representing opaque white (all channels set
+ to 1). This is the identity value – ARGB multiplication by this value will
+ not change a colour.
+emu.render_color(a, r, g, b)
+ Creates a render colour object with the specified alpha, red, green and
+ blue channel values.
+
+ The arguments must all be floating-point numbers in the range from zero (0)
+ to one (1), inclusive.
+
+Methods
+~~~~~~~
+
+color:set(a, r, g, b)
+ Sets the colour object’s alpha, red, green and blue channel values.
+
+ The arguments must all be floating-point numbers in the range from zero (0)
+ to one (1), inclusive.
+
+Properties
+~~~~~~~~~~
+
+color.a (read/write)
+ Alpha value, in the range of zero (0, transparent) to one (1, opaque).
+color.r (read/write)
+ Red channel value, in the range of zero (0, off) to one (1, full intensity).
+color.g (read/write)
+ Green channel value, in the range of zero (0, off) to one (1, full
+ intensity).
+color.b (read/write)
+ Blue channel value, in the range of zero (0, off) to one (1, full
+ intensity).
+
+
+.. _luascript-ref-palette:
+
+Palette
+-------
+
+Wraps MAME’s ``palette_t`` class, which represents a table of colours that can
+be looked up by zero-based index. Palettes always contain additional special
+entries for black and white.
+
+Each colour has an associated contrast adjustment value. Each adjustment group
+has associated brightness and contrast adjustment values. The palette also has
+overall brightness, contrast and gamma adjustment values.
+
+Colours are represented in alpha/red/green/blue (ARGB) format. Channel values
+range from 0 (transparent or off) to 255 (opaque or full intensity), inclusive.
+Colour channel values are not pre-multiplied by the alpha value. Channel values
+are packed into the bytes of 32-bit unsigned integers, in the order alpha, red,
+green, blue from most-significant to least-significant byte.
+
+Instantiation
+~~~~~~~~~~~~~
+
+emu.palette(colors, [groups])
+ Creates a palette with the specified number of colours and
+ brightness/contrast adjustment groups. The number of colour groups defaults
+ to one if not specified. Colours are initialised to black, brightness
+ adjustment is initialised to 0.0, contrast adjustment initialised to 1.0,
+ and gamma adjustment is initialised to 1.0.
+
+Methods
+~~~~~~~
+
+palette:entry_color(index)
+ Gets the colour at the specified zero-based index.
+
+ Index values range from zero to the number of colours in the palette minus
+ one. Returns black if the index is greater than or equal to the number of
+ colours in the palette.
+palette:entry_contrast(index)
+ Gets the contrast adjustment for the colour at the specified zero-based
+ index. This is a floating-point number.
+
+ Index values range from zero to the number of colours in the palette minus
+ one. Returns 1.0 if the index is greater than or equal to the number of
+ colours in the palette.
+palette:entry_adjusted_color(index, [group])
+ Gets a colour with brightness, contrast and gamma adjustments applied.
+
+ If the group is specified, colour index values range from zero to the number
+ of colours in the palette minus one, and group values range from zero to the
+ number of adjustment groups in the palette minus one.
+
+ If the group is not specified, index values range from zero to the number of
+ colours multiplied by the number of adjustment groups plus one. Index
+ values may be calculated by multiplying the zero-based group index by the
+ number of colours in the palette, and adding the zero-based colour index.
+ The last two index values correspond to the special entries for black and
+ white, respectively.
+
+ Returns black if the specified combination of index and adjustment group is
+ invalid.
+palette:entry_set_color(index, color)
+ Sets the colour at the specified zero-based index. The colour may be
+ specified as a single packed 32-bit value; or as individual red, green and
+ blue channel values, in that order.
+
+ Index values range from zero to the number of colours in the palette minus
+ one. Raises an error if the index value is invalid.
+palette:entry_set_red_level(index, level)
+ Sets the red channel value of the colour at the specified zero-based index.
+ Other channel values are not affected.
+
+ Index values range from zero to the number of colours in the palette minus
+ one. Raises an error if the index value is invalid.
+palette:entry_set_green_level(index, level)
+ Sets the green channel value of the colour at the specified zero-based
+ index. Other channel values are not affected.
+
+ Index values range from zero to the number of colours in the palette minus
+ one. Raises an error if the index value is invalid.
+palette:entry_set_blue_level(index, level)
+ Sets the blue channel value of the colour at the specified zero-based index.
+ Other channel values are not affected.
+
+ Index values range from zero to the number of colours in the palette minus
+ one. Raises an error if the index value is invalid.
+palette:entry_set_contrast(index, level)
+ Sets the contrast adjustment value for the colour at the specified
+ zero-based index. This must be a floating-point number.
+
+ Index values range from zero to the number of colours in the palette minus
+ one. Raises an error if the index value is invalid.
+palette:group_set_brightness(group, brightness)
+ Sets the brightness adjustment value for the adjustment group at the
+ specified zero-based index. This must be a floating-point number.
+
+ Group values range from zero to the number of adjustment groups in the
+ palette minus one. Raises an error if the index value is invalid.
+palette:group_set_contrast(group, contrast)
+ Sets the contrast adjustment value for the adjustment group at the specified
+ zero-based index. This must be a floating-point number.
+
+ Group values range from zero to the number of adjustment groups in the
+ palette minus one. Raises an error if the index value is invalid.
+
+Properties
+~~~~~~~~~~
+
+palette.colors (read-only)
+ The number of colour entries in each group of colours in the palette.
+palette.groups (read-only)
+ The number of groups of colours in the palette.
+palette.max_index (read-only)
+ The number of valid colour indices in the palette.
+palette.black_entry (read-only)
+ The index of the special entry for the colour black.
+palette.white_entry (read-only)
+ The index of the special entry for the colour white.
+palette.brightness (write-only)
+ The overall brightness adjustment for the palette. This is a floating-point
+ number.
+palette.contrast (write-only)
+ The overall contrast adjustment for the palette. This is a floating-point
+ number.
+palette.gamma (write-only)
+ The overall gamma adjustment for the palette. This is a floating-point
+ number.
+
+
+.. _luascript-ref-bitmap:
+
+Bitmap
+------
+
+Wraps implementations of MAME’s ``bitmap_t`` and ``bitmap_specific`` classes,
+which represent two-dimensional bitmaps stored in row-major order. Pixel
+coordinates are zero-based, increasing to the right and down. Several pixel
+formats are supported.
+
+Instantiation
+~~~~~~~~~~~~~
+
+emu.bitmap_ind8(palette, [width, height], [xslop, yslop])
+ Creates an 8-bit indexed bitmap. Each pixel is a zero-based, unsigned 8-bit
+ index into a :ref:`palette <luascript-ref-palette>`.
+
+ If no width and height are specified, they are assumed to be zero. If the
+ width is specified, the height must also be specified. The X and Y slop
+ values set the amount of extra storage in pixels to reserve at the
+ left/right of each row and top/bottom of each column, respectively. If an X
+ slop value is specified, a Y slop value must be specified as well. If no X
+ and Y slop values are specified, they are assumed to be zero (the storage
+ will be sized to fit the bitmap content). If the width and/or height is
+ less than or equal to zero, no storage will be allocated, irrespective of
+ the X and Y slop values, and the width and height of the bitmap will both be
+ set to zero.
+
+ The initial clipping rectangle is set to the entirety of the bitmap.
+emu.bitmap_ind16(palette, [width, height], [xslop, yslop])
+ Creates a 16-bit indexed bitmap. Each pixel is a zero-based, unsigned
+ 16-bit index into a :ref:`palette <luascript-ref-palette>`.
+
+ If no width and height are specified, they are assumed to be zero. If the
+ width is specified, the height must also be specified. The X and Y slop
+ values set the amount of extra storage in pixels to reserve at the
+ left/right of each row and top/bottom of each column, respectively. If an X
+ slop value is specified, a Y slop value must be specified as well. If no X
+ and Y slop values are specified, they are assumed to be zero (the storage
+ will be sized to fit the bitmap content). If the width and/or height is
+ less than or equal to zero, no storage will be allocated, irrespective of
+ the X and Y slop values, and the width and height of the bitmap will both be
+ set to zero.
+
+ The initial clipping rectangle is set to the entirety of the bitmap.
+emu.bitmap_ind32(palette, [width, height], [xslop, yslop])
+ Creates a 32-bit indexed bitmap. Each pixel is a zero-based, unsigned
+ 32-bit index into a :ref:`palette <luascript-ref-palette>`.
+
+ If no width and height are specified, they are assumed to be zero. If the
+ width is specified, the height must also be specified. The X and Y slop
+ values set the amount of extra storage in pixels to reserve at the
+ left/right of each row and top/bottom of each column, respectively. If an X
+ slop value is specified, a Y slop value must be specified as well. If no X
+ and Y slop values are specified, they are assumed to be zero (the storage
+ will be sized to fit the bitmap content). If the width and/or height is
+ less than or equal to zero, no storage will be allocated, irrespective of
+ the X and Y slop values, and the width and height of the bitmap will both be
+ set to zero.
+
+ The initial clipping rectangle is set to the entirety of the bitmap.
+emu.bitmap_ind64(palette, [width, height], [xslop, yslop])
+ Creates a 64-bit indexed bitmap. Each pixel is a zero-based, unsigned
+ 64-bit index into a :ref:`palette <luascript-ref-palette>`.
+
+ If no width and height are specified, they are assumed to be zero. If the
+ width is specified, the height must also be specified. The X and Y slop
+ values set the amount of extra storage in pixels to reserve at the
+ left/right of each row and top/bottom of each column, respectively. If an X
+ slop value is specified, a Y slop value must be specified as well. If no X
+ and Y slop values are specified, they are assumed to be zero (the storage
+ will be sized to fit the bitmap content). If the width and/or height is
+ less than or equal to zero, no storage will be allocated, irrespective of
+ the X and Y slop values, and the width and height of the bitmap will both be
+ set to zero.
+
+ The initial clipping rectangle is set to the entirety of the bitmap.
+emu.bitmap_yuy16([width, height], [xslop], yslop])
+ Creates a Y'CbCr format bitmap with 4:2:2 chroma subsampling (horizontal
+ pairs of pixels have individual luma values but share chroma values). Each
+ pixel is a 16-bit integer value. The most significant byte of the pixel
+ value is the unsigned 8-bit Y' (luma) component of the pixel colour. For
+ each horizontal pair of pixels, the least significant byte of the first
+ pixel (even zero-based X coordinate) value is the signed 8-bit Cb value for
+ the pair of pixels, and the least significant byte of the second pixel (odd
+ zero-based X coordinate) value is the signed 8-bit Cr value for the pair of
+ pixels.
+
+ If no width and height are specified, they are assumed to be zero. If the
+ width is specified, the height must also be specified. The X and Y slop
+ values set the amount of extra storage in pixels to reserve at the
+ left/right of each row and top/bottom of each column, respectively. If an X
+ slop value is specified, a Y slop value must be specified as well. If no X
+ and Y slop values are specified, they are assumed to be zero (the storage
+ will be sized to fit the bitmap content). If the width and/or height is
+ less than or equal to zero, no storage will be allocated, irrespective of
+ the X and Y slop values, and the width and height of the bitmap will both be
+ set to zero.
+
+ The initial clipping rectangle is set to the entirety of the bitmap.
+emu.bitmap_rgb32([width, height], [xslop, yslop])
+ Creates an RGB format bitmap with no alpha (transparency) channel. Each
+ pixel is represented by a 32-bit integer value. The most significant byte
+ of the pixel value is ignored. The remaining three bytes, from most
+ significant to least significant, are the unsigned 8-bit unsigned red, green
+ and blue channel values (larger values correspond to higher intensities).
+
+ If no width and height are specified, they are assumed to be zero. If the
+ width is specified, the height must also be specified. The X and Y slop
+ values set the amount of extra storage in pixels to reserve at the
+ left/right of each row and top/bottom of each column, respectively. If an X
+ slop value is specified, a Y slop value must be specified as well. If no X
+ and Y slop values are specified, they are assumed to be zero (the storage
+ will be sized to fit the bitmap content). If the width and/or height is
+ less than or equal to zero, no storage will be allocated, irrespective of
+ the X and Y slop values, and the width and height of the bitmap will both be
+ set to zero.
+
+ The initial clipping rectangle is set to the entirety of the bitmap.
+emu.bitmap_argb32([width, height], [xslop, yslop])
+ Creates an ARGB format bitmap. Each pixel is represented by a 32-bit
+ integer value. The most significant byte of the pixel is the 8-bit unsigned
+ alpha (transparency) channel value (smaller values are more transparent).
+ The remaining three bytes, from most significant to least significant, are
+ the unsigned 8-bit unsigned red, green and blue channel values (larger
+ values correspond to higher intensities). Colour channel values are not
+ pre-multiplied by the alpha channel value.
+
+ If no width and height are specified, they are assumed to be zero. If the
+ width is specified, the height must also be specified. The X and Y slop
+ values set the amount of extra storage in pixels to reserve at the
+ left/right of each row and top/bottom of each column, respectively. If an X
+ slop value is specified, a Y slop value must be specified as well. If no X
+ and Y slop values are specified, they are assumed to be zero (the storage
+ will be sized to fit the bitmap content). If the width and/or height is
+ less than or equal to zero, no storage will be allocated, irrespective of
+ the X and Y slop values, and the width and height of the bitmap will both be
+ set to zero.
+
+ The initial clipping rectangle is set to the entirety of the bitmap.
+emu.bitmap_ind8(source, [x0, y0, x1, y1])
+ Creates an 8-bit indexed bitmap representing a view of a portion of an
+ existing bitmap. The initial clipping rectangle is set to the bounds of the
+ view. The source bitmap will be locked, preventing resizing and
+ reallocation.
+
+ If no coordinates are specified, the new bitmap will represent a view of the
+ source bitmap’s current clipping rectangle. If coordinates are specified,
+ the new bitmap will represent a view of the rectangle with top left corner
+ at (x0, y0) and bottom right corner at (x1, y1) in the source bitmap.
+ Coordinates are in units of pixels. The bottom right coordinates are
+ inclusive.
+
+ The source bitmap must be owned by the Lua script and must use the 8-bit
+ indexed format. Raises an error if coordinates are specified representing a
+ rectangle not fully contained within the source bitmap’s clipping rectangle.
+emu.bitmap_ind16(source, [x0, y0, x1, y1])
+ Creates a 16-bit indexed bitmap representing a view of a portion of an
+ existing bitmap. The initial clipping rectangle is set to the bounds of the
+ view. The source bitmap will be locked, preventing resizing and
+ reallocation.
+
+ If no coordinates are specified, the new bitmap will represent a view of the
+ source bitmap’s current clipping rectangle. If coordinates are specified,
+ the new bitmap will represent a view of the rectangle with top left corner
+ at (x0, y0) and bottom right corner at (x1, y1) in the source bitmap.
+ Coordinates are in units of pixels. The bottom right coordinates are
+ inclusive.
+
+ The source bitmap must be owned by the Lua script and must use the 16-bit
+ indexed format. Raises an error if coordinates are specified representing a
+ rectangle not fully contained within the source bitmap’s clipping rectangle.
+emu.bitmap_ind32(source, [x0, y0, x1, y1])
+ Creates a 32-bit indexed bitmap representing a view of a portion of an
+ existing bitmap. The initial clipping rectangle is set to the bounds of the
+ view. The source bitmap will be locked, preventing resizing and
+ reallocation.
+
+ If no coordinates are specified, the new bitmap will represent a view of the
+ source bitmap’s current clipping rectangle. If coordinates are specified,
+ the new bitmap will represent a view of the rectangle with top left corner
+ at (x0, y0) and bottom right corner at (x1, y1) in the source bitmap.
+ Coordinates are in units of pixels. The bottom right coordinates are
+ inclusive.
+
+ The source bitmap must be owned by the Lua script and must use the 32-bit
+ indexed format. Raises an error if coordinates are specified representing a
+ rectangle not fully contained within the source bitmap’s clipping rectangle.
+emu.bitmap_ind64(source, [x0, y0, x1, y1])
+ Creates a 64-bit indexed bitmap representing a view of a portion of an
+ existing bitmap. The initial clipping rectangle is set to the bounds of the
+ view. The source bitmap will be locked, preventing resizing and
+ reallocation.
+
+ If no coordinates are specified, the new bitmap will represent a view of the
+ source bitmap’s current clipping rectangle. If coordinates are specified,
+ the new bitmap will represent a view of the rectangle with top left corner
+ at (x0, y0) and bottom right corner at (x1, y1) in the source bitmap.
+ Coordinates are in units of pixels. The bottom right coordinates are
+ inclusive.
+
+ The source bitmap must be owned by the Lua script and must use the 64-bit
+ indexed format. Raises an error if coordinates are specified representing a
+ rectangle not fully contained within the source bitmap’s clipping rectangle.
+emu.bitmap_yuy16(source, [x0, y0, x1, y1])
+ Creates a Y'CbCr format bitmap with 4:2:2 chroma subsampling representing a
+ view of a portion of an existing bitmap. The initial clipping rectangle is
+ set to the bounds of the view. The source bitmap will be locked, preventing
+ resizing and reallocation.
+
+ If no coordinates are specified, the new bitmap will represent a view of the
+ source bitmap’s current clipping rectangle. If coordinates are specified,
+ the new bitmap will represent a view of the rectangle with top left corner
+ at (x0, y0) and bottom right corner at (x1, y1) in the source bitmap.
+ Coordinates are in units of pixels. The bottom right coordinates are
+ inclusive.
+
+ The source bitmap must be owned by the Lua script and must use the Y'CbCr
+ format. Raises an error if coordinates are specified representing a
+ rectangle not fully contained within the source bitmap’s clipping rectangle.
+emu.bitmap_rgb32(source, [x0, y0, x1, y1])
+ Creates an RGB format bitmap representing a view of a portion of an existing
+ bitmap. The initial clipping rectangle is set to the bounds of the view.
+ The source bitmap will be locked, preventing resizing and reallocation.
+
+ If no coordinates are specified, the new bitmap will represent a view of the
+ source bitmap’s current clipping rectangle. If coordinates are specified,
+ the new bitmap will represent a view of the rectangle with top left corner
+ at (x0, y0) and bottom right corner at (x1, y1) in the source bitmap.
+ Coordinates are in units of pixels. The bottom right coordinates are
+ inclusive.
+
+ The source bitmap must be owned by the Lua script and must use the RGB
+ format. Raises an error if coordinates are specified representing a
+ rectangle not fully contained within the source bitmap’s clipping rectangle.
+emu.bitmap_argb32(source, [x0, y0, x1, y1])
+ Creates an ARGB format bitmap representing a view of a portion of an
+ existing bitmap. The initial clipping rectangle is set to the bounds of the
+ view. The source bitmap will be locked, preventing resizing and
+ reallocation.
+
+ If no coordinates are specified, the new bitmap will represent a view of the
+ source bitmap’s current clipping rectangle. If coordinates are specified,
+ the new bitmap will represent a view of the rectangle with top left corner
+ at (x0, y0) and bottom right corner at (x1, y1) in the source bitmap.
+ Coordinates are in units of pixels. The bottom right coordinates are
+ inclusive.
+
+ The source bitmap must be owned by the Lua script and must use the ARGB
+ format. Raises an error if coordinates are specified representing a
+ rectangle not fully contained within the source bitmap’s clipping rectangle.
+emu.bitmap_argb32.load(data)
+ Creates an ARGB format bitmap from data in PNG, JPEG (JFIF/EXIF) or
+ Microsoft DIB (BMP) format. Raises an error if the data invalid or not a
+ supported format.
+
+Methods
+~~~~~~~
+
+bitmap:cliprect()
+ Returns the left, top, right and bottom coordinates of the bitmap’s clipping
+ rectangle. Coordinates are in units of pixels; the bottom and right
+ coordinates are inclusive.
+bitmap:reset()
+ Sets the width and height to zero, and frees the pixel storage if the bitmap
+ owns its own storage, or releases the source bitmap if the it represents a
+ view of another bitmap.
+
+ The bitmap must be owned by the Lua script. Raises an error if the bitmap’s
+ storage is referenced by another bitmap or a :ref:`texture
+ <luascript-ref-rendertexture>`.
+bitmap:allocate(width, height, [xslop, yslop])
+ Reallocates storage for the bitmap, sets its width and height, and sets the
+ clipping rectangle to the entirety of the bitmap. If the bitmap already
+ owns allocated storage, it will always be freed and reallocated; if the
+ bitmap represents a view of another bitmap, the source bitmap will be
+ released. The storage will be filled with pixel value zero.
+
+ The X and Y slop values set the amount of extra storage in pixels to reserve
+ at the left/right of each row and top/bottom of each column, respectively.
+ If an X slop value is specified, a Y slop value must be specified as well.
+ If no X and Y slop values are specified, they are assumed to be zero (the
+ storage will be sized to fit the bitmap content). If the width and/or
+ height is less than or equal to zero, no storage will be allocated,
+ irrespective of the X and Y slop values, and the width and height of the
+ bitmap will both be set to zero.
+
+ The bitmap must be owned by the Lua script. Raises an error if the bitmap’s
+ storage is referenced by another bitmap or a :ref:`texture
+ <luascript-ref-rendertexture>`.
+bitmap:resize(width, height, [xslop, yslop])
+ Changes the width and height, and sets the clipping rectangle to the
+ entirety of the bitmap.
+
+ The X and Y slop values set the amount of extra storage in pixels to reserve
+ at the left/right of each row and top/bottom of each column, respectively.
+ If an X slop value is specified, a Y slop value must be specified as well.
+ If no X and Y slop values are specified, they are assumed to be zero (rows
+ will be stored contiguously, and the top row will be placed at the beginning
+ of the bitmap’s storage).
+
+ If the bitmap already owns allocated storage and it is large enough for the
+ updated size, it will be used without being freed; if it is too small for
+ the updated size, it will always be freed and reallocated. If the bitmap
+ represents a view of another bitmap, the source bitmap will be released. If
+ storage is allocated, it will be filled with pixel value zero (if existing
+ storage is used, its contents will not be changed).
+
+ Raises an error if the bitmap’s storage is referenced by another bitmap or a
+ :ref:`texture <luascript-ref-rendertexture>`.
+bitmap:wrap(source, [x0, y0, x1, y1])
+ Makes the bitmap represent a view of a portion of another bitmap and sets
+ the clipping rectangle to the bounds of the view.
+
+ If no coordinates are specified, the target bitmap will represent a view of
+ the source bitmap’s current clipping rectangle. If coordinates are
+ specified, the target bitmap will represent a view of the rectangle with top
+ left corner at (x0, y0) and bottom right corner at (x1, y1) in the source
+ bitmap. Coordinates are in units of pixels. The bottom right coordinates
+ are inclusive.
+
+ The source bitmap will be locked, preventing resizing and reallocation. If
+ the target bitmap owns allocated storage, it will be freed; if it represents
+ a view of another bitmap, the current source bitmap will be released.
+
+ The source and target bitmaps must both be owned by the Lua script and must
+ use the same pixel format. Raises an error if coordinates are specified
+ representing a rectangle not fully contained within the source bitmap’s
+ clipping rectangle; if the bitmap’s storage is referenced by another bitmap
+ or a :ref:`texture <luascript-ref-rendertexture>`; or if the source and
+ target are the same bitmap.
+bitmap:pix(x, y)
+ Returns the colour value of the pixel at the specified location.
+ Coordinates are zero-based in units of pixels.
+bitmap:pixels([x0, y0, x1, y1])
+ Returns the pixels, width and height of the portion of the bitmap with top
+ left corner at (x0, y0) and bottom right corner at (x1, y1). Coordinates
+ are in units of pixels. The bottom right coordinates are inclusive. If
+ coordinates are not specified, the bitmap’s clipping rectangle is used.
+
+ Pixels are returned packed into a binary string in host Endian order.
+ Pixels are organised in row-major order, from left to right then top to
+ bottom. The size and format of the pixel values depends on the format of
+ the bitmap. Raises an error if coordinates are specified representing a
+ rectangle not fully contained within the bitmap’s clipping rectangle.
+bitmap:fill(color, [x0, y0, x1, y1])
+ Fills a portion of the bitmap with the specified colour value. If
+ coordinates are not specified, the clipping rectangle is filled; if
+ coordinates are specified, the intersection of the clipping rectangle and
+ the rectangle with top left corner at (x0, y0) and bottom right corner at
+ (x1, y1) is filled. Coordinates are in units of pixels. The bottom right
+ coordinates are inclusive.
+bitmap:plot(x, y, color)
+ Sets the colour value of the pixel at the specified location if it is within
+ the clipping rectangle. Coordinates are zero-based in units of pixels.
+bitmap:plot_box(x, y, width, height, color)
+ Fills the intersection of the clipping rectangle and the rectangle with top
+ left (x, y) and the specified height and width with the specified colour
+ value. Coordinates and dimensions are in units of pixels.
+bitmap:resample(dest, [color])
+ Copies the bitmap into the destination bitmap, scaling to fill the
+ destination bitmap and using a re-sampling filter. Only ARGB format source
+ and destination bitmaps are supported. The source pixel values will be
+ multiplied by the colour if it is supplied. It must be a
+ :ref:`render colour <luascript-ref-rendercolor>`.
+
+Properties
+~~~~~~~~~~
+
+bitmap.palette (read/write)
+ The :ref:`palette <luascript-ref-palette>` used to translate pixel
+ values to colours. Only applicable for bitmaps that use indexed pixel
+ formats.
+bitmap.width (read-only)
+ Width of the bitmap in pixels.
+bitmap.height (read-only)
+ Height of the bitmap in pixels.
+bitmap.rowpixels (read-only)
+ Row stride of the bitmap’s storage in pixels. That is, the difference in
+ pixel offsets of the pixels at the same horizontal location in consecutive
+ rows. May be greater than the width.
+bitmap.rowbytes (read-only)
+ Row stride of the bitmap’s storage in bytes. That is, the difference in
+ byte addresses of the pixels at the same horizontal location in consecutive
+ rows.
+bitmap.bpp (read-only)
+ Size of the type used to represent pixels in the bitmap in bits (may be
+ larger than the number of significant bits).
+bitmap.valid (read-only)
+ A Boolean indicating whether the bitmap has storage available (may be false
+ for empty bitmaps).
+bitmap.locked (read-only)
+ A Boolean indicating whether the bitmap’s storage is referenced by another
+ bitmap or a :ref:`texture <luascript-ref-rendertexture>`.
+
+
+.. _luascript-ref-rendertexture:
+
+Render texture
+--------------
+
+Wraps MAME’s ``render_texture`` class, representing a texture that cam be drawn
+in a :ref:`render container <luascript-ref-rendercontainer>`. Render textures
+must be freed before the emulation session ends.
+
+Instantiation
+~~~~~~~~~~~~~
+
+manager.machine.render:texture_alloc(bitmap)
+ Creates a render texture based on a :ref:`bitmap
+ <luascript-ref-bitmap>`. The bitmap must be owned by the Lua script, and
+ must use the Y'CbCr, RGB or ARGB format. The bitmap’s storage will be
+ locked, preventing resizing and reallocation.
+
+Methods
+~~~~~~~
+
+texture:free()
+ Frees the texture. The storage of the underlying bitmap will be released.
+
+Properties
+~~~~~~~~~~
+
+texture.valid (read-only)
+ A Boolean indicating whether the texture is valid (false if the texture has
+ been freed).
+
+
+.. _luascript-ref-renderman:
+
+Render manager
+--------------
+
+Wraps MAME’s ``render_manager`` class, responsible for managing render targets
+and textures.
+
+Instantiation
+~~~~~~~~~~~~~
+
+manager.machine.render
+ Gets the global render manager instance for the emulation session.
+
+Methods
+~~~~~~~
+
+render:texture_alloc(bitmap)
+ Creates a :ref:`render texture <luascript-ref-rendertexture>` based on a
+ :ref:`bitmap <luascript-ref-bitmap>`. The bitmap must be owned by the Lua
+ script, and must use the Y'CbCr, RGB or ARGB pixel format. The bitmap’s
+ storage will be locked, preventing resizing and reallocation. Render
+ textures must be freed before the emulation session ends.
+
+Properties
+~~~~~~~~~~
+
+render.max_update_rate (read-only)
+ The maximum update rate in Hertz. This is a floating-point number.
+render.ui_target (read-only)
+ The :ref:`render target <luascript-ref-rendertarget>` used to draw the user
+ interface (including menus, sliders and pop-up messages). This is usually
+ the first host window or screen.
+render.ui_container (read-only)
+ The :ref:`render container <luascript-ref-rendercontainer>` used for drawing
+ the user interface.
+render.targets[] (read-only)
+ The list of render targets, including output windows and screens, as well as
+ hidden render targets used for things like rendering screenshots. Uses
+ 1-based integer indices. The index operator and the ``at`` method have O(n)
+ complexity.
+
+
+.. _luascript-ref-rendertarget:
+
+Render target
+-------------
+
+Wrap’s MAME’s ``render_target`` class, which represents a video output channel.
+This could be a host window or screen, or a hidden target used for rendering
+screenshots.
+
+Instantiation
+~~~~~~~~~~~~~
+
+manager.machine.render.targets[index]
+ Gets a render target by index.
+manager.machine.render.ui_target
+ Gets the render target used to display the user interface (including menus,
+ sliders and pop-up messages). This is usually the first host window or
+ screen.
+manager.machine.video.snapshot_target
+ Gets the render target used to produce snapshots and video recordings.
+
+Properties
+~~~~~~~~~~
+
+target.ui_container (read-only)
+ The :ref:`render container <luascript-ref-rendercontainer>` for drawing user
+ interface elements over this render target, or ``nil`` for hidden render
+ targets (targets that are not shown to the user directly).
+target.index (read-only)
+ The 1-based index of the render target. This has O(n) complexity.
+target.width (read-only)
+ The width of the render target in output pixels. This is an integer.
+target.height (read-only)
+ The height of the render target in output pixels. This is an integer.
+target.pixel_aspect (read-only)
+ The width-to-height aspect ratio of the render target’s pixels. This is a
+ floating-point number.
+target.hidden (read-only)
+ A Boolean indicating whether this is an internal render target that is not
+ displayed to the user directly (e.g. the render target used to draw
+ screenshots).
+target.is_ui_target (read-only)
+ A Boolean indicating whether this is the render target used to display the
+ user interface.
+target.max_update_rate (read/write)
+ The maximum update rate for the render target in Hertz.
+target.orientation (read/write)
+ The target orientation flags. This is an integer bit mask, where bit 0
+ (0x01) is set to mirror horizontally, bit 1 (0x02) is set to mirror
+ vertically, and bit 2 (0x04) is set to mirror along the top left-bottom
+ right diagonal.
+target.view_names[]
+ The names of the available views for this render target. Uses 1-based
+ integer indices. The ``find`` and ``index_of`` methods have O(n)
+ complexity; all other supported operations have O(1) complexity.
+target.current_view (read-only)
+ The currently selected view for the render target. This is a
+ :ref:`layout view <luascript-ref-renderlayview>` object.
+target.view_index (read/write)
+ The 1-based index of the selected view for this render target.
+target.visibility_mask (read-only)
+ An integer bit mask indicating which item collections are currently visible
+ for the current view.
+target.screen_overlay (read/write)
+ A Boolean indicating whether screen overlays are enabled.
+target.zoom_to_screen (read/write)
+ A Boolean indicating whether the render target is configured to scale so
+ that the emulated screen(s) fill as much of the output window/screen as
+ possible.
+
+
+.. _luascript-ref-rendercontainer:
+
+Render container
+----------------
+
+Wraps MAME’s ``render_container`` class.
+
+Instantiation
+~~~~~~~~~~~~~
+
+manager.machine.render.ui_container
+ Gets the render container used to draw the user interface, including menus,
+ sliders and pop-up messages.
+manager.machine.render.targets[index].ui_container
+ Gets the render container used to draw user interface elements over a
+ particular render target.
+manager.machine.screens[tag].container
+ Gets the render container used to draw a given screen.
+
+Methods
+~~~~~~~
+
+container:draw_box(left, top, right, bottom, [line], [fill])
+ Draws an outlined rectangle with edges at the specified positions.
+
+ Coordinates are floating-point numbers in the range of 0 (zero) to 1 (one),
+ with (0, 0) at the top left and (1, 1) at the bottom right of the window or
+ the screen that shows the user interface. Note that the aspect ratio is
+ usually not square. Coordinates are limited to the window or screen area.
+
+ The fill and line colours are in alpha/red/green/blue (ARGB) format.
+ Channel values are in the range 0 (transparent or off) to 255 (opaque or
+ full intensity), inclusive. Colour channel values are not pre-multiplied by
+ the alpha value. The channel values must be packed into the bytes of a
+ 32-bit unsigned integer, in the order alpha, red, green, blue from
+ most-significant to least-significant byte. If the line colour is not
+ provided, the UI text colour is used; if the fill colour is not provided,
+ the UI background colour is used.
+container:draw_line(x0, y0, x1, y1, [color])
+ Draws a line from (x0, y0) to (x1, y1).
+
+ Coordinates are floating-point numbers in the range of 0 (zero) to 1 (one),
+ with (0, 0) at the top left and (1, 1) at the bottom right of the window or
+ the screen that shows the user interface. Note that the aspect ratio is
+ usually not square. Coordinates are limited to the window or screen area.
+
+ The line colour is in alpha/red/green/blue (ARGB) format. Channel values
+ are in the range 0 (transparent or off) to 255 (opaque or full intensity),
+ inclusive. Colour channel values are not pre-multiplied by the alpha value.
+ The channel values must be packed into the bytes of a 32-bit unsigned
+ integer, in the order alpha, red, green, blue from most-significant to
+ least-significant byte. If the line colour is not provided, the UI text
+ colour is used.
+container:draw_quad(texture, x0, y0, x1, y1, [color])
+ Draws a textured rectangle with top left corner at (x0, y0) and bottom right
+ corner at (x1, y1). If a colour is specified, the ARGB channel values of
+ the texture’s pixels are multiplied by the corresponding values of the
+ specified colour.
+
+ Coordinates are floating-point numbers in the range of 0 (zero) to 1 (one),
+ with (0, 0) at the top left and (1, 1) at the bottom right of the window or
+ the screen that shows the user interface. Note that the aspect ratio is
+ usually not square. If the rectangle extends beyond the container’s bounds,
+ it will be cropped.
+
+ The colour is in alpha/red/green/blue (ARGB) format. Channel values are in
+ the range 0 (transparent or off) to 255 (opaque or full intensity),
+ inclusive. Colour channel values are not pre-multiplied by the alpha value.
+ The channel values must be packed into the bytes of a 32-bit unsigned
+ integer, in the order alpha, red, green, blue from most-significant to
+ least-significant byte.
+container:draw_text(x|justify, y, text, [foreground], [background])
+ Draws text at the specified position. If the screen is rotated the text
+ will be rotated.
+
+ If the first argument is a number, the text will be left-aligned at this X
+ coordinate. If the first argument is a string, it must be ``"left"``,
+ ``"center"`` or ``"right"`` to draw the text left-aligned at the
+ left edge of the window or screen, horizontally centred in the window or
+ screen, or right-aligned at the right edge of the window or screen,
+ respectively. The second argument specifies the Y coordinate of the maximum
+ ascent of the text.
+
+ Coordinates are floating-point numbers in the range of 0 (zero) to 1 (one),
+ with (0, 0) at the top left and (1, 1) at the bottom right of the window or
+ the screen that shows the user interface. Note that the aspect ratio is
+ usually not square. Coordinates are limited to the window or screen area.
+
+ The foreground and background colours are in alpha/red/green/blue (ARGB)
+ format. Channel values are in the range 0 (transparent or off) to 255
+ (opaque or full intensity), inclusive. Colour channel values are not
+ pre-multiplied by the alpha value. The channel values must be packed into
+ the bytes of a 32-bit unsigned integer, in the order alpha, red, green, blue
+ from most-significant to least-significant byte. If the foreground colour
+ is not provided, the UI text colour is used; if the background colour is not
+ provided, it is fully transparent.
+
+Properties
+~~~~~~~~~~
+
+container.user_settings (read/write)
+ The container’s :ref:`user settings <luascript-ref-rendercntnrsettings>`.
+ This can be used to control a number of image adjustments.
+container.orientation (read/write)
+ The container orientation flags. This is an integer bit mask, where bit 0
+ (0x01) is set to mirror horizontally, bit 1 (0x02) is set to mirror
+ vertically, and bit 2 (0x04) is set to mirror along the top left-bottom
+ right diagonal.
+container.xscale (read/write)
+ The container’s X scale factor. This is a floating-point number.
+container.yscale (read/write)
+ The container’s Y scale factor. This is a floating-point number.
+container.xoffset (read/write)
+ The container’s X offset. This is a floating-point number where one (1)
+ corresponds to the X size of the container.
+container.yoffset (read/write)
+ The container’s Y offset. This is a floating-point number where one (1)
+ corresponds to the Y size of the container.
+container.is_empty (read-only)
+ A Boolean indicating whether the container has no items.
+
+
+.. _luascript-ref-rendercntnrsettings:
+
+Container user settings
+-----------------------
+
+Wraps MAME’s ``render_container::user_settings`` class, representing image
+adjustments applied to a
+:ref:`render container <luascript-ref-rendercontainer>`.
+
+Instantiation
+~~~~~~~~~~~~~
+
+manager.machine.screens[tag].container
+ Gets the current render container user settings for a given emulated screen.
+
+Properties
+~~~~~~~~~~
+
+settings.orientation (read/write)
+ The container orientation flags. This is an integer bit mask, where bit 0
+ (0x01) is set to mirror horizontally, bit 1 (0x02) is set to mirror
+ vertically, and bit 2 (0x04) is set to mirror along the top left-bottom
+ right diagonal.
+settings.brightness (read/write)
+ The brightness adjustment applied to the container. This is a
+ floating-point number.
+settings.contrast (read/write)
+ The contrast adjustment applied to the container. This is a floating-point
+ number.
+settings.gamma (read/write)
+ The gamma adjustment applied to the container. This is a floating-point
+ number.
+settings.xscale (read/write)
+ The container’s X scale factor. This is a floating-point number.
+settings.yscale (read/write)
+ The container’s Y scale factor. This is a floating-point number.
+settings.xoffset (read/write)
+ The container’s X offset. This is a floating-point number where one (1)
+ represents the X size of the container.
+settings.yoffset (read/write)
+ The container’s Y offset. This is a floating-point number where one (1)
+ represents the Y size of the container.
+
+
+.. _luascript-ref-renderlayfile:
+
+Layout file
+-----------
+
+Wraps MAME’s ``layout_file`` class, representing the views loaded from a layout
+file for use by a render target. Note that layout file callbacks are not run as
+coroutines.
+
+Instantiation
+~~~~~~~~~~~~~
+
+A layout file object is supplied to its layout script in the ``file`` variable.
+Layout file objects are not instantiated directly from Lua scripts.
+
+Methods
+~~~~~~~
+
+layout:set_resolve_tags_callback(cb)
+ Set a function to perform additional tasks after the emulated machine has
+ finished starting, tags in the layout views have been resolved, and the
+ default view item handlers have been set up. The function must accept no
+ arguments.
+
+ Call with ``nil`` to remove the callback.
+
+Properties
+~~~~~~~~~~
+
+layout.device (read-only)
+ The device that caused the layout file to be loaded. Usually the root
+ machine device for external layouts.
+layout.elements[] (read-only)
+ The :ref:`elements <luascript-ref-renderlayelem>` created from the layout
+ file. Elements are indexed by name (i.e. the value of the ``name``
+ attribute). The index get method has O(1) complexity, and the ``at`` and
+ ``index_of`` methods have O(n) complexity.
+layout.views[] (read-only)
+ The :ref:`views <luascript-ref-renderlayview>` created from the layout file.
+ Views are indexed by unqualified name (i.e. the value of the ``name``
+ attribute). Views are ordered how they appear in the layout file when
+ iterating or using the ``at`` method. The index get, ``at`` and
+ ``index_of`` methods have O(n) complexity.
+
+ Note that some views in the XML file may not be created. For example views
+ that reference screens provided by slot card devices will not be created if
+ said slot card devices are not present in the emulated system.
+
+
+.. _luascript-ref-renderlayview:
+
+Layout view
+-----------
+
+Wraps MAME’s ``layout_view`` class, representing a view that can be displayed in
+a render target. Views are created from XML layout files, which may be loaded
+from external artwork, internal to MAME, or automatically generated based on the
+screens in the emulated system. Note that layout view callbacks are not run as
+coroutines.
+
+Instantiation
+~~~~~~~~~~~~~
+
+manager.machine.render.targets[index].current_view
+ Gets the currently selected view for a given render target.
+file.views[name]
+ Gets the view with the specified name from a
+ :ref:`layout file <luascript-ref-renderlayfile>`. This is how layout
+ scripts generally obtain views.
+
+Methods
+~~~~~~~
+
+view:has_screen(screen)
+ Returns a Boolean indicating whether the screen is present in the view.
+ This is true for screens that are present but not visible because the user
+ has hidden the item collection they belong to.
+view:set_prepare_items_callback(cb)
+ Set a function to perform additional tasks before the view items are added
+ to the render target in preparation for drawing a video frame. The function
+ must accept no arguments. Call with ``nil`` to remove the callback.
+view:set_preload_callback(cb)
+ Set a function to perform additional tasks after preloading visible view
+ items. The function must accept no arguments. Call with ``nil`` to remove
+ the callback.
+
+ This function may be called when the user selects a view or makes an item
+ collection visible. It may be called multiple times for a view, so avoid
+ repeating expensive tasks.
+view:set_recomputed_callback(cb)
+ Set a function to perform additional tasks after the view’s dimensions are
+ recomputed. The function must accept no arguments. Call with ``nil`` to
+ remove the callback.
+
+ View coordinates are recomputed in various events, including the window
+ being resized, entering or leaving full-screen mode, and changing the zoom
+ to screen area setting.
+view:set_pointer_updated_callback(cb)
+ Set a function to receive notifications when a pointer enters, moves or
+ changes button states over the view. The function must accept nine
+ arguments:
+
+ * The pointer type (``mouse``, ``pen``, ``touch`` or ``unknown``).
+ * The pointer ID (a non-negative integer that will not change for the
+ lifetime of a pointer).
+ * The device ID for grouping pointers to recognise multi-touch gestures
+ (non-negative integer).
+ * Horizontal position in layout coordinates.
+ * Vertical position in layout coordinates.
+ * A bit mask representing the currently pressed buttons.
+ * A bit mask representing the buttons that were pressed in this update.
+ * A bit mask representing the buttons that were released in this update.
+ * The click count (positive for multi-click actions, or negative if a click
+ is turned into a hold or drag).
+
+ Call with ``nil`` to remove the callback.
+view:set_pointer_left_callback(cb)
+ Set a function to receive notifications when a pointer leaves the view
+ normally. The function must accept seven arguments:
+
+ * The pointer type (``mouse``, ``pen``, ``touch`` or ``unknown``).
+ * The pointer ID (a non-negative integer that will not change for the
+ lifetime of a pointer). The ID may be reused for a new pointer after
+ receiving this notification.
+ * The device ID for grouping pointers to recognise multi-touch gestures
+ (non-negative integer).
+ * Horizontal position in layout coordinates.
+ * Vertical position in layout coordinates.
+ * A bit mask representing the buttons that were released in this update.
+ * The click count (positive for multi-click actions, or negative if a click
+ is turned into a hold or drag).
+
+ Call with ``nil`` to remove the callback.
+view:set_pointer_aborted_callback(cb)
+ Set a function to receive notifications when a pointer leaves the view
+ abnormally. The function must accept seven arguments:
+
+ * The pointer type (``mouse``, ``pen``, ``touch`` or ``unknown``).
+ * The pointer ID (a non-negative integer that will not change for the
+ lifetime of a pointer). The ID may be reused for a new pointer after
+ receiving this notification.
+ * The device ID for grouping pointers to recognise multi-touch gestures
+ (non-negative integer).
+ * Horizontal position in layout coordinates.
+ * Vertical position in layout coordinates.
+ * A bit mask representing the buttons that were released in this update.
+ * The click count (positive for multi-click actions, or negative if a click
+ is turned into a hold or drag).
+
+ Call with ``nil`` to remove the callback.
+view:set_forget_pointers_callback(cb)
+ Set a function to receive notifications when the view should stop processing
+ pointer input. The function must accept no arguments. Call with ``nil`` to
+ remove the callback.
+
+ This can happen in a number of situations, including the view configuration
+ changing or a menu taking over input handling.
+
+Properties
+~~~~~~~~~~
+
+view.items[] (read-only)
+ The screen and layout element :ref:`items <luascript-ref-renderlayitem>` in
+ the view. This container does not support iteration by key using ``pairs``;
+ only iteration by index using ``ipairs`` is supported. The key is the value
+ of the ``id`` attribute if present. Only items with ``id`` attributes can
+ be looked up by key. The index get method has O(1) complexity, and the
+ ``at`` and ``index_of`` methods have O(n) complexity.
+view.name (read-only)
+ The display name for the view. This may be qualified to indicate the device
+ that caused the layout file to be loaded when it isn’t the root machine
+ device.
+view.unqualified_name (read-only)
+ The unqualified name of the view, exactly as it appears in the ``name``
+ attribute in the XML layout file.
+view.visible_screen_count (read-only)
+ The number of screens items currently enabled in the view.
+view.effective_aspect (read-only)
+ The effective width-to-height aspect ratio of the view in its current
+ configuration.
+view.bounds (read-only)
+ A :ref:`render bounds <luascript-ref-renderbounds>` object representing the
+ effective bounds of the view in its current configuration. The coordinates
+ are in view units, which are arbitrary but assumed to have square aspect
+ ratio.
+view.has_art (read-only)
+ A Boolean indicating whether the view has any non-screen items, including
+ items that are not visible because the user has hidden the item collection
+ that they belong to.
+view.show_pointers (read/write)
+ A Boolean that sets whether mouse and pen pointers should be displayed for
+ the view.
+view.hide_inactive_pointers (read/write)
+ A Boolean that sets whether mouse pointers for the view should be hidden
+ after a period of inactivity.
+
+
+.. _luascript-ref-renderlayitem:
+
+Layout view item
+----------------
+
+Wraps MAME’s ``layout_view_item`` class, representing an item in a :ref:`layout
+view <luascript-ref-renderlayview>`. An item is drawn as a rectangular textured
+surface. The texture is supplied by an emulated screen or a layout element.
+Note that layout view item callbacks are not run as coroutines.
+
+Instantiation
+~~~~~~~~~~~~~
+
+layout.views[name].items[id]
+ Get a view item by ID. The item must have an ``id`` attribute in the XML
+ layout file to be looked up by ID.
+
+Methods
+~~~~~~~
+
+item:set_state(state)
+ Set the value used as the element state and animation state in the absence
+ of bindings. The argument must be an integer.
+item:set_element_state_callback(cb)
+ Set a function to call to obtain the element state for the item. The
+ function must accept no arguments and return an integer. Call with ``nil``
+ to restore the default element state callback (based on bindings in the XML
+ layout file).
+
+ Note that the function must not access the item’s ``element_state``
+ property, as this will result in infinite recursion.
+
+ This callback will not be used to obtain the animation state for the item,
+ even if the item lacks explicit animation state bindings in the XML layout
+ file.
+item:set_animation_state_callback(cb)
+ Set a function to call to obtain the animation state for the item. The
+ function must accept no arguments and return an integer. Call with ``nil``
+ to restore the default animation state callback (based on bindings in the
+ XML layout file).
+
+ Note that the function must not access the item’s ``animation_state``
+ property, as this will result in infinite recursion.
+item:set_bounds_callback(cb)
+ Set a function to call to obtain the bounds for the item. The function must
+ accept no arguments and return a
+ :ref:`render bounds <luascript-ref-renderbounds>` object in render target
+ coordinates. Call with ``nil`` to restore the default bounds callback
+ (based on the item’s animation state and ``bounds`` child elements in the
+ XML layout file).
+
+ Note that the function must not access the item’s ``bounds`` property, as
+ this will result in infinite recursion.
+item:set_color_callback(cb)
+ Set a function to call to obtain the multiplier colour for the item. The
+ function must accept no arguments and return a
+ :ref:`render colour <luascript-ref-rendercolor>` object. Call with ``nil``
+ to restore the default colour callback (based on the item’s animation state
+ and ``color`` child elements in the XML layout file).
+
+ Note that the function must not access the item’s ``color`` property, as
+ this will result in infinite recursion.
+item:set_scroll_size_x_callback(cb)
+ Set a function to call to obtain the size of the horizontal scroll window as
+ a proportion of the associated element’s width. The function must accept no
+ arguments and return a floating-point value. Call with ``nil`` to restore
+ the default horizontal scroll window size callback (based on the ``xscroll``
+ child element in the XML layout file).
+
+ Note that the function must not access the item’s ``scroll_size_x``
+ property, as this will result in infinite recursion.
+item:set_scroll_size_y_callback(cb)
+ Set a function to call to obtain the size of the vertical scroll window as a
+ proportion of the associated element’s height. The function must accept no
+ arguments and return a floating-point value. Call with ``nil`` to restore
+ the default vertical scroll window size callback (based on the ``yscroll``
+ child element in the XML layout file).
+
+ Note that the function must not access the item’s ``scroll_size_y``
+ property, as this will result in infinite recursion.
+item:set_scroll_pos_x_callback(cb)
+ Set a function to call to obtain the horizontal scroll position. A value of
+ zero places the horizontal scroll window at the left edge of the associated
+ element. If the item does not wrap horizontally, a value of 1.0 places the
+ horizontal scroll window at the right edge of the associated element; if the
+ item wraps horizontally, a value of 1.0 corresponds to wrapping back to the
+ left edge of the associated element. The function must accept no arguments
+ and return a floating-point value. Call with ``nil`` to restore the default
+ horizontal scroll position callback (based on bindings in the ``xscroll``
+ child element in the XML layout file).
+
+ Note that the function must not access the item’s ``scroll_pos_x`` property,
+ as this will result in infinite recursion.
+item:set_scroll_pos_y_callback(cb)
+ Set a function to call to obtain the vertical scroll position. A value of
+ zero places the vertical scroll window at the top edge of the associated
+ element. If the item does not wrap vertically, a value of 1.0 places the
+ vertical scroll window at the bottom edge of the associated element; if the
+ item wraps vertically, a value of 1.0 corresponds to wrapping back to the
+ left edge of the associated element. The function must accept no arguments
+ and return a floating-point value. Call with ``nil`` to restore the default
+ vertical scroll position callback (based on bindings in the ``yscroll``
+ child element in the XML layout file).
+
+ Note that the function must not access the item’s ``scroll_pos_y`` property,
+ as this will result in infinite recursion.
+
+Properties
+~~~~~~~~~~
+
+item.id (read-only)
+ Get the optional item identifier. This is the value of the ``id`` attribute
+ in the XML layout file if present, or ``nil``.
+item.element (read-only)
+ The :ref:`element <luascript-ref-renderlayelem>` used to draw the item, or
+ ``nil`` for screen items.
+item.bounds_animated (read-only)
+ A Boolean indicating whether the item’s bounds depend on its animation
+ state.
+item.color_animated (read-only)
+ A Boolean indicating whether the item’s colour depends on its animation
+ state.
+item.bounds (read-only)
+ The item’s bounds for the current state. This is a
+ :ref:`render bounds <luascript-ref-renderbounds>` object in render target
+ coordinates.
+item.color (read-only)
+ The item’s colour for the current state. The colour of the screen or
+ element texture is multiplied by this colour. This is a
+ :ref:`render colour <luascript-ref-rendercolor>` object.
+item.scroll_wrap_x (read-only)
+ A Boolean indicating whether the item wraps horizontally.
+item.scroll_wrap_y (read-only)
+ A Boolean indicating whether the item wraps vertically.
+item.scroll_size_x (read/write)
+ Get the item’s horizontal scroll window size for the current state, or set
+ the horizontal scroll window size to use in the absence of bindings. This
+ is a floating-point value representing a proportion of the associated
+ element’s width.
+item.scroll_size_y (read/write)
+ Get the item’s vertical scroll window size for the current state, or set the
+ vertical scroll window size to use in the absence of bindings. This is a
+ floating-point value representing a proportion of the associated element’s
+ height.
+item.scroll_pos_x (read/write)
+ Get the item’s horizontal scroll position for the current state, or set the
+ horizontal scroll position size to use in the absence of bindings. This is
+ a floating-point value.
+item.scroll_pos_y (read/write)
+ Get the item’s vertical scroll position for the current state, or set the
+ vertical position size to use in the absence of bindings. This is a
+ floating-point value.
+item.blend_mode (read-only)
+ Get the item’s blend mode. This is an integer value, where 0 means no
+ blending, 1 means alpha blending, 2 means RGB multiplication, 3 means
+ additive blending, and -1 allows the items within a container to specify
+ their own blending modes.
+item.orientation (read-only)
+ Get the item orientation flags. This is an integer bit mask, where bit 0
+ (0x01) is set to mirror horizontally, bit 1 (0x02) is set to mirror
+ vertically, and bit 2 (0x04) is set to mirror along the top left-bottom
+ right diagonal.
+item.element_state (read-only)
+ Get the current element state. This will call the element state callback
+ function to handle bindings.
+item.animation_state (read-only)
+ Get the current animation state. This will call the animation state
+ callback function to handle bindings.
+
+
+.. _luascript-ref-renderlayelem:
+
+Layout element
+--------------
+
+Wraps MAME’s ``layout_element`` class, representing a visual element that can be
+drawn in a :ref:`layout view <luascript-ref-renderlayview>`. Elements are
+created from XML layout files, which may be loaded from external artwork or
+internal to MAME. Note that layout element callbacks are not run as coroutines.
+
+Instantiation
+~~~~~~~~~~~~~
+
+layout.elements[name]
+ Gets a layout element by name.
+layout.views[name].items[id].element
+ Gets the layout element used to draw a
+ :ref:`view item <luascript-ref-renderlayitem>`.
+
+Methods
+~~~~~~~
+
+element:invalidate()
+ Invalidate all cached textures for the element, ensuring it will be redrawn
+ when the next video frame is drawn.
+element.set_draw_callback(cb)
+ Set a function to call the perform additional drawing after the element’s
+ components have been drawn. The function is passed two arguments: the
+ element state (an integer) and the 32-bit ARGB
+ :ref:`bitmap <luascript-ref-bitmap>` at the required size. The function
+ must not attempt to resize the bitmap. Call with ``nil`` to remove the
+ callback.
+
+Properties
+~~~~~~~~~~
+
+element.default_state (read-only)
+ The integer default state for the element if set or ``nil``.
diff --git a/docs/source/plugins/autofire.rst b/docs/source/plugins/autofire.rst
new file mode 100644
index 00000000000..2cb974626d2
--- /dev/null
+++ b/docs/source/plugins/autofire.rst
@@ -0,0 +1,109 @@
+.. _plugins-autofire:
+
+Autofire Plugin
+===============
+
+.. contents:: :local:
+
+
+.. _plugins-autofire-intro:
+
+Introduction
+------------
+
+The autofire plugin allows you to simulate repeatedly pressing an emulated
+button by holding down a key or button combination. This can help people with
+certain disabilities or injuries play shooting games, and may help reduce the
+risk of repetitive strain injuries (or keyboard damage).
+
+To configure the autofire plugin, activate the main menu (press **Tab** during
+emulation by default), select **Plugin Options**, and then select **Autofire**.
+Configured autofire buttons for the current system are listed, along with their
+repetition rates and activation hotkeys (initially there will be no autofire
+buttons configured). Select an autofire button to change settings, or choose
+**Add autofire button** to set up a new autofire button. See
+:ref:`plugins-autofire-settings` for details on setting up an autofire button.
+You can delete an autofire button by highlighting it in the menu and pressing
+the UI Clear key (Del/Delete/Forward Delete on the keyboard by default).
+
+Autofire settings are saved in the **autofire** folder in the plugin data
+folder (see the :ref:`homepath option <mame-commandline-homepath>`). A file is
+created for each system with autofire buttons configured, named according to the
+system’s short name (or ROM set name), with the extension ``.cfg``. For
+example, autofire settings for Super-X will be saved in the file **superx.cfg**
+in the **autofire** folder in your plugin data folder. The autofire settings
+are stored in JSON format.
+
+
+.. _plugins-autofire-settings:
+
+Autofire buttons settings
+-------------------------
+
+The options for adding a new autofire button or modifying an existing autofire
+button are the same.
+
+Select **Input** to set the emulated button that you want to simulate pressing
+repeatedly. Currently, only player buttons are supported. Typically you’ll set
+this to the primary fire button for shooting games. This is most often *P1
+Button 1* or the equivalent for another player, but it might have a
+different name. On Konami’s Gradius games, *P1 Button 2* is the primary fire
+button.
+
+Select **Hotkey** to set the control (or combination of controls) you’ll use to
+activate the autofire button. This can be any combination that MAME supports
+for activating a digital input.
+
+**On frames** and **Off frames** are the number of consecutive emulated video
+frames that the emulated button will be held and released for, respectively.
+Adjust the value with the UI Left/Right keys, or click the arrows. Press the UI
+Clear key to reset the values to one frame. Lower values correspond to pressing
+the button at a faster rate. Depending on how fast the system reads inputs, you
+may need higher numbers than 1 for the system to recognise the button being
+released and pressed again (e.g. 2 on frames and 2 off frames works for Alcon).
+Experiment with different values to get the best effect.
+
+When adding a new autofire button, there is a **Cancel** option that changes to
+**Create** after you set the input and hotkey. Select **Create** to finish
+creating the autofire button and return to the list of autofire buttons. The
+new autofire button will be added at the end of the list. Press the UI Back key
+(Escape/Esc on the keyboard by default), or select **Cancel** before setting the
+input/hotkey, to return to the previous menu without creating the new autofire
+button.
+
+When modifying an existing autofire button, select **Done** or press the UI
+Cancel key to return to the list of autofire buttons. Changes take effect
+immediately.
+
+
+.. _plugins-autofire-notes:
+
+Notes and potential pitfalls
+----------------------------
+
+Autofire buttons act as if they’re wired in parallel with MAME’s regular
+controls. This means that if you set the activation hotkey for an autofire
+button to a button or key that’s also assigned to one of the emulated inputs
+directly, you may get unexpected results. Using Gradius as an example:
+
+* Suppose you set button 1 on your controller to fire, and set an autofire
+ hotkey to button 1 as well. Holding the button down to shoot will not trigger
+ the autofire effect: the button will never be released as you’re holding the
+ non-autofire button 1 down. This will also happen if you set a different
+ button as autofire (say, button 3 in this case), and hold button 1 down while
+ also pressing button 3.
+* If you set button 3 on your controller to autofire and assign button 3 to
+ powerup as well, you will trigger the powerup action every time you grab a
+ powerup because the powerup button is also being held down along with the
+ autofire button.
+
+It is recommended that you choose control combinations for autofire hotkeys that
+are not assigned to any other emulated inputs in the system.
+
+Autofire is not necessarily desirable in all situations. For example using
+autofire in Super-X with the blue “lightning” weapon equipped at high power
+levels will only produce a single beam, greatly reducing the weapon’s
+effectiveness. The fire button must be held down to produce all beams. Some
+shooting games (e.g. Raiden Fighters) require the primary fire button to be held
+down for a charged special attack. This means it’s often necessary to have a
+non-autofire input for the primary fire button assigned to play effectively.
diff --git a/docs/source/plugins/console.rst b/docs/source/plugins/console.rst
new file mode 100644
index 00000000000..79aa6c929a3
--- /dev/null
+++ b/docs/source/plugins/console.rst
@@ -0,0 +1,9 @@
+.. _plugins-console:
+
+Console Plugin
+==============
+
+The console plugin provides functionality for MAME’s interactive Lua console.
+It is not used directly. Use the
+:ref:`console option <mame-commandline-console>` to activate the interactive Lua
+console. See :ref:`luascript` for more information about MAME’s Lua API.
diff --git a/docs/source/plugins/data.rst b/docs/source/plugins/data.rst
new file mode 100644
index 00000000000..01c5d641307
--- /dev/null
+++ b/docs/source/plugins/data.rst
@@ -0,0 +1,58 @@
+.. _plugins-data:
+
+Data Plugin
+===========
+
+The data plugin loads information from various external support files so it can
+be displayed in MAME. If the plugin is enabled, info is show in the **Infos**
+tab of the right-hand pane on the system and software selection menus. The info
+viewer can be shown by clicking the toolbar button on the system and software
+selection menus, or by choosing **External DAT View** from the main menu during
+emulation (this menu item will not appear if the data plugin is not enabled, or
+if no information is available for the emulated system).
+
+To set the folders where the data plugin looks for supported files, choose
+**Configure Options** on the system selection menu, then choose
+**Configure Directories**, and then choose **DATs**. You can also set the
+``historypath`` option in your **ui.ini** file.
+
+Loading large data files like **history.xml** can take quite a while, so please
+be patient the first time you start MAME after updating or adding new data
+files.
+
+The following files are supported:
+
+history.xml
+ From Gaming-History (formerly Arcade-History)
+mameinfo.dat
+ From `MASH’s MAMEINFO <https://mameinfo.mameworld.info/>`_
+messinfo.dat
+ From `progetto-SNAPS MESSINFO.dat
+ <https://www.progettosnaps.net/messinfo/>`_
+gameinit.dat
+ From `progetto-SNAPS GameInit.dat
+ <https://www.progettosnaps.net/gameinit/>`_
+command.dat
+ from `progetto-SNAPS Command.dat
+ <https://www.progettosnaps.net/command/>`_
+score3.htm
+ `Top Scores <http://replay.marpirc.net/txt/scores3.htm>`_ from
+ the `MAME Action Replay Page <http://replay.marpirc.net/>`_
+Japanese mameinfo.dat and command.dat
+ From `MAME E2J <https://e2j.net/downloads/>`_
+sysinfo.dat
+ From the defunct Progetto EMMA site
+story.dat
+ From the defunct MAMESCORE site
+
+If you install `hi2txt <https://greatstoneex.github.io/hi2txt-doc/>`_, the data
+plugin can also show high scores from non-volatile memory or saved by the
+:ref:`hiscore support plugin <plugins-hiscore>` for supported games.
+
+Note that you can only use a single file of each type at a time. You cannot,
+for example, use the English and Japanese **mameinfo.dat** files simultaneously.
+
+The data plugin creates a **history.db** file in the **data** folder in the
+plugin data folder (see the :ref:`homepath option <mame-commandline-homepath>`).
+This file stores the information from the support files in a format suitable for
+rapid loading. It uses the SQLite3 database format.
diff --git a/docs/source/plugins/discord.rst b/docs/source/plugins/discord.rst
new file mode 100644
index 00000000000..7d0aac9c90d
--- /dev/null
+++ b/docs/source/plugins/discord.rst
@@ -0,0 +1,10 @@
+.. _plugins-discord:
+
+Discord Presence Plugin
+=======================
+
+The Discord presence plugin works with the Discord app for Windows, macOS or
+Linux to set your activity to show what you’re doing in MAME. The activity is
+set to *In menu* if you’re using the system or software selection menu,
+*Playing* if emulation is running, or *Paused* if emulation is paused. The
+details are set to show the system name and software description if applicable.
diff --git a/docs/source/plugins/dummy.rst b/docs/source/plugins/dummy.rst
new file mode 100644
index 00000000000..21c4c72309c
--- /dev/null
+++ b/docs/source/plugins/dummy.rst
@@ -0,0 +1,8 @@
+.. _plugins-dummy:
+
+Dummy Test Plugin
+=================
+
+This is a sample plugin that shows how to set necessary plugin metadata,
+register callbacks, and display a simple menu. It prints status messages, and
+it adds a **Dummy** option to the **Plugin Options** menu.
diff --git a/docs/source/plugins/gdbstub.rst b/docs/source/plugins/gdbstub.rst
new file mode 100644
index 00000000000..bf2fd9ce67a
--- /dev/null
+++ b/docs/source/plugins/gdbstub.rst
@@ -0,0 +1,13 @@
+.. _plugins-gdbstub:
+
+GDB Stub Plugin
+===============
+
+The GDB stub plugin acts as a remote debugging server for the GNU debugger
+(GDB). This allows you to connect to MAME and debug supported systems using
+GDB. The plugin listens for connections on port 2159 on the IPv4 loopback
+address (127.0.0.1). Only Intel 80386 (i386) family processors are supported.
+
+See the :ref:`debugger option <mame-commandline-debugger>` for another GDB
+remote debugging implementation with support for more CPUs and configurable
+listening ports.
diff --git a/docs/source/plugins/hiscore.rst b/docs/source/plugins/hiscore.rst
new file mode 100644
index 00000000000..389dea598ac
--- /dev/null
+++ b/docs/source/plugins/hiscore.rst
@@ -0,0 +1,28 @@
+.. _plugins-hiscore:
+
+Hiscore Support Plugin
+======================
+
+The hiscore support plugin saves and restores high scores for games that did not
+originally save high scores in non-volatile memory. Note that this plugin
+modifies the contents of memory directly with no coordination with the emulated
+software, and hence changes behaviour. This may have undesirable effects,
+including broken gameplay or causing the emulated software to crash.
+
+The plugin includes a **hiscore.dat** file that contains the information on how
+to save and restore high scores for supported systems. This file must be kept
+up-to-date when system definitions change in MAME.
+
+High scores can be saved automatically either on exit, or a few seconds after
+they’re updated in memory. To change the setting, activate the main menu (press
+**Tab** during emulation by default), select **Plugin Options**, and then select
+**Hiscore Support**. Change the **Save scores** option by highlighting it and
+using the UI Left/Right keys, or clicking the arrows.
+
+High score data is saved in the **hiscore** folder in the plugin data folder
+(see the :ref:`homepath option <mame-commandline-homepath>`). A file with a
+name corresponding the system short name (or ROM set name) with the extension
+``.hi``. For example, high scores for the game Moon Cresta will be saved in the
+file **mooncrst.hi** in the **hiscore** folder in your plugin data folder. The
+settings for the hiscore support plugin are stored in the file **plugin.cfg** in
+the **hiscore** folder in the plugin data folder (this file is in JSON format).
diff --git a/docs/source/plugins/index.rst b/docs/source/plugins/index.rst
new file mode 100644
index 00000000000..38dfb393f3e
--- /dev/null
+++ b/docs/source/plugins/index.rst
@@ -0,0 +1,74 @@
+.. _plugins:
+
+Plugins
+=======
+
+.. contents:: :local:
+
+
+.. _plugins-intro:
+
+Introduction
+------------
+
+MAME supports plugins that can provide additional functionality. Plugins
+have been written to communicate with external programs, play games
+automatically, display internal game structures like hitboxes, provide alternate
+user interfaces, and automatically test emulation. See :ref:`luascript` for
+more information about MAME’s Lua API.
+
+
+.. _plugins-using:
+
+Using plugins
+-------------
+
+To enable plugins, you need to turn on the
+:ref:`plugins option <mame-commandline-plugins>`, and make sure the
+:ref:`pluginspath option <mame-commandline-pluginspath>` includes the folder
+where your plugins are stored. You can set the plugins option in an INI file
+or on the command line. You can set the pluginspath option by selecting
+**Configure Options** from the system selection menu, then selecting
+**Configure Directories**, and then selecting **Plugins** (you can also set it
+in an INI file or on the command line).
+
+Many plugins need to store settings and/or data. The
+:ref:`homepath option <mame-commandline-homepath>` sets the folder where plugins
+should save data (defaults to the working directory). You can change this by
+selecting **Configure Options** from the system selection menu, then selecting
+**Configure Directories**, and then selecting **Plugin Data**.
+
+To turn individual plugins on or off, first make sure plugins are enabled, then
+select **Configure Options** from the system selection menu, and then select
+**Plugins**. You will need to completely exit MAME and start it again for
+changes to the enabled plugins to take effect. You can also use the
+:ref:`plugin option <mame-commandline-plugin>` on the command line, or change
+the settings in the **plugin.ini** file.
+
+If an enabled plugin needs additional configuration, or if it needs to show
+information, a **Plugin Options** item will appear in the main menu (accessed by
+pressing **Tab** during emulation by default).
+
+
+.. _plugins-included:
+
+Included plugins
+----------------
+
+MAME includes several plugins providing useful functionality, and serving as
+sample code that you can use as a starting point when writing your own plugins.
+
+.. toctree::
+ :titlesonly:
+
+ autofire
+ console
+ data
+ discord
+ dummy
+ gdbstub
+ hiscore
+ inputmacro
+ layout
+ timecode
+ timer
diff --git a/docs/source/plugins/inputmacro.rst b/docs/source/plugins/inputmacro.rst
new file mode 100644
index 00000000000..959faa05fbe
--- /dev/null
+++ b/docs/source/plugins/inputmacro.rst
@@ -0,0 +1,230 @@
+.. _plugins-inputmacro:
+
+Input Macro Plugin
+==================
+
+.. contents:: :local:
+
+
+.. _plugins-inputmacro-intro:
+
+Introduction
+------------
+
+The input macro plugin allows you to trigger a sequence of emulated input
+actions with a key or button combination. This can help people with
+disabilities or injuries that make some input sequences difficult. It can also
+be used as a way to cheat in games that require rapid sequences of inputs, like
+the running events in Track & Field, or the eating minigame in Daisu-Kiss.
+
+To configure the input macro plugin, activate the main menu (press **Tab**
+during emulation by default), select **Plugin Options**, and then select **Input
+Macros**. Configured input macros for the current system are listed, along with
+their activation sequences (initially there will be no input macros configured).
+Select a macro to edit it, or choose **Add macro** to set up a new input macro.
+See :ref:`plugins-inputmacro-settings` for details on editing input macros. You
+can delete an input macro by highlighting it in the menu and pressing the UI
+Clear key (Del/Delete/Forward Delete on the keyboard by default).
+
+Input macros are saved in the **inputmacro** folder in the plugin data folder
+(see the :ref:`homepath option <mame-commandline-homepath>`). A file is created
+for each system with input macros configured, named according to the system’s
+short name (or ROM set name), with the extension ``.cfg``. For example, input
+macros for Daisu-Kiss will be saved in the file **daiskiss.cfg** in the
+**inputmacro** folder in your plugin data folder. The input macros are stored
+in JSON format.
+
+
+.. _plugins-inputmacro-settings:
+
+Editing input macros
+--------------------
+
+The options for editing input macros are the same whether you’re creating a new
+macro or editing an existing macro. Input macros consist of a sequence of
+*steps*. Each step optionally waits for a configurable delay, then activates
+one or more emulated inputs for a specified duration. You can choose what
+should happen if the activation sequence is still held when the final step of
+the macro completes: the emulated inputs can be released, the final step can be
+prolonged, or the macro can loop back to any step in the sequence.
+
+The settings in first section of the macro editing menu apply to the macro as a
+whole:
+
+* The **Name** will be used in the list of input macros, so it helps to make it
+ descriptive. Press the UI Select key (Return/Enter on the keyboard or the
+ first button on the first joystick by default) to edit the current name, or
+ press the UI Clear key to type a new name. Press the UI Select key before
+ moving to another menu item to save the new name; press the UI Back key
+ (Escape/Esc on the keyboard by default) to change discard the new name.
+* Select **Activation combination** to set the control (or combination of
+ controls) you want to use to activate the macro. Keep in mind that regular
+ input assignments still apply, so you will probably want to use a combination
+ that isn’t being used for any other emulated input in the system.
+* Set **On release** to specify what should happen if the activation sequence is
+ released before the macro completes. When set to *Stop immediately*, any
+ emulated inputs activated by the macro will be released immediately, and no
+ further steps will be processed; when set to *Complete macro*, the macro will
+ continue to be processed until the end of the final step.
+* Set **When held** to specify what should happen if the activation sequence is
+ held after the final step of the macro completes. When set to *Release*, any
+ inputs activated by the macro will be released, and the macro will not be
+ reactivated until the activation sequence is released and pressed again; when
+ set to *Prolong step <n>* where *<n>* is the number of the final step of the
+ macro, the emulated inputs activated by the final step of the macro will
+ remain active until the activation sequence is released; when set to *Loop to
+ step <n>* where *<n>* is a step number, macro processing will return to that
+ step, including its delay, if the activation sequence is held after the final
+ step completes.
+
+Each step has delay, duration and input settings:
+
+* Set the **Delay** to the number of emulated video frame intervals to wait
+ before activating the inputs for the step. During the delay, no emulated
+ inputs will be activated by the macro. You can reset the setting to zero by
+ pressing the UI Clear key.
+* Set the **Duration** to the number of emulated video frame intervals to hold
+ the emulated inputs for the step active before moving to the next step (or
+ completing the macro in the case of the final step). You can reset the
+ setting to one frame by pressing the UI Clear key.
+* Set the **Input** settings to the emulated inputs to activate for the step.
+ Only non-toggle digital inputs are supported. Select **Add input** to set
+ multiple inputs for a step (this option will only appear after you set the
+ first input for the initially created step when creating a new macro). If
+ the step has multiple inputs, you can highlight an input on the menu and press
+ the UI Clear key to delete it (all steps must have at least one input, so you
+ can’t delete the only input for a step).
+* If the macro has multiple steps, you can select **Delete step** to delete a
+ step (this options does not appear if the macro only has a single step).
+ Remember to check that the **On release** and **When held** settings are
+ correct after deleting steps.
+
+To add a step to the macro, highlight **Add step at position** (below the
+existing steps), use the UI Left/Right keys or click the arrows to set the
+position where you’d like to insert the new step, and then press the UI Select
+key (or double-click the menu item) to add the new step. You will be prompted
+to set the first input for the new step. Remember to check the **On release**
+and **When held** settings after adding steps. The **Add step at position**
+item will only appear after you set the first input for the initially created
+step when creating a new macro.
+
+When creating a new macro, there is a **Cancel** option that changes to
+**Create** after you set the activating sequence and the first input for the
+initially created step. Select **Create** to finish creating the macro and
+return to the list of input macros. The new macro will be added at the end of
+the list. Press the UI Back key, or select **Cancel** before setting the
+activation sequence/input, to return to the previous menu without creating the
+new macro.
+
+When editing an existing macro, select **Done** or press the UI Back key to
+return to the list of input macros. Changes take effect immediately.
+
+
+.. _plugins-inputmacro-examples:
+
+Example macros
+--------------
+
+Raiden autofire
+~~~~~~~~~~~~~~~
+
+This provides player 1 autofire functionality using the space bar. The same
+thing could be achieved using the :ref:`plugins-autofire`, but this demonstrates
+a simple looping macro:
+
+* **Name**: P1 Autofire
+* **Activation combination**: Kbd Space
+* **On release**: Stop immediately
+* **When held**: Loop to step 2
+* **Step 1**:
+
+ * **Delay (frames)**: 0
+ * **Duration (frames)**: 2
+ * **Input 1**: P1 Button 1
+* **Step 2**:
+
+ * **Delay (frames)**: 4
+ * **Duration (frames)**: 2
+ * **Input 1**: P1 Button 1
+
+The first step has no delay so that firing begins as soon as the space bar is
+pressed. The second step has sufficient delay to ensure the game recognises the
+button being pressed and released again. The second step is repeated as long as
+the space bar is held down.
+
+Track & Field sprint cheat
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+This allows you to run in Konami Track & Field by holding a single button. This
+takes most of the skill (and fun) out of the game:
+
+* **Name**: P1 Sprint
+* **Activation combination**: Kbd Shift
+* **On release**: Stop immediately
+* **When held**: Loop to step 2
+* **Step 1**:
+
+ * **Delay (frames)**: 0
+ * **Duration (frames)**: 1
+ * **Input 1**: P1 Button 1
+* **Step 2**:
+
+ * **Delay (frames)**: 1
+ * **Duration (frames)**: 1
+ * **Input 1**: P1 Button 3
+* **Step 3**:
+
+ * **Delay (frames)**: 1
+ * **Duration (frames)**: 1
+ * **Input 1**: P1 Button 1
+
+This macro rapidly alternates pressing buttons 1 and 3 – the pattern required to
+run in the game.
+
+Street Fighter II Shoryuken
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+This macro allows you to perform a right-facing Shōryūken (Dragon Punch) by
+pressing a single key:
+
+* **Name**: 1P Shoryuken LP
+* **Activation combination**: Kbd M
+* **On release**: Complete macro
+* **When held**: Prolong step 6
+* **Step 1**:
+
+ * **Delay (frames)**: 0
+ * **Duration (frames)**: 1
+ * **Input 1**: P1 Right
+* **Step 2**:
+
+ * **Delay (frames)**: 1
+ * **Duration (frames)**: 1
+ * **Input 1**: P1 Down
+* **Step 3**:
+
+ * **Delay (frames)**: 0
+ * **Duration (frames)**: 1
+ * **Input 1**: P1 Down
+ * **Input 2**: P1 Right
+* **Step 4**:
+
+ * **Delay (frames)**: 0
+ * **Duration (frames)**: 1
+ * **Input 1**: P1 Right
+* **Step 5**:
+
+ * **Delay (frames)**: 0
+ * **Duration (frames)**: 1
+ * **Input 1**: P1 Right
+ * **Input 2**: P1 Jab Punch
+* **Step 6**:
+
+ * **Delay (frames)**: 0
+ * **Duration (frames)**: 1
+ * **Input 1**: P1 Jab Punch
+
+This macro involves steps that activate multiple inputs. The macro will
+complete if the activation sequence is released early, allowing you to tap the
+key momentarily to perform the move. Holding the activation sequence holds down
+the attack button.
diff --git a/docs/source/plugins/layout.rst b/docs/source/plugins/layout.rst
new file mode 100644
index 00000000000..5c57afccb7a
--- /dev/null
+++ b/docs/source/plugins/layout.rst
@@ -0,0 +1,9 @@
+.. _plugins-layout:
+
+Layout Plugin
+=============
+
+When enabled, the layout plugin allows embedded Lua scripts in layout files to
+run. Built-in artwork for some machines and some external artwork packages can
+use Lua scripts to provide enhanced interactive features. See :ref:`layscript`
+for an introduction to layout file scripting.
diff --git a/docs/source/plugins/timecode.rst b/docs/source/plugins/timecode.rst
new file mode 100644
index 00000000000..c24847b3453
--- /dev/null
+++ b/docs/source/plugins/timecode.rst
@@ -0,0 +1,21 @@
+.. _plugins-timecode:
+
+Timecode Recorder Plugin
+========================
+
+The timecode recorder plugin logs time codes to a text file in conjunction with
+creating an input recording file to assist people creating gameplay videos. The
+time code log file is *only* created when making an input recording. The time
+code log file has the same name as the input recording file with the extension
+**.timecode** appended. Use the :ref:`record <mame-commandline-record>` and
+:ref:`input_directory <mame-commandline-inputdirectory>` options to create an
+input recording and specify the location for the output files.
+
+By default, the plugin records a time code when you press the **F12** key on the
+keyboard while not pressing either **Shift** or **Alt** key. You can change
+this setting in the options menu for the plugin (choose **Plugin Options** from
+the main menu during emulation, and then choose **Timecode Recorder**).
+
+Settings for the plugin are stored in JSON format in the file **plugin.cfg** in
+the **timecode** folder inside your plugin data folder (see the
+:ref:`homepath option <mame-commandline-homepath>`).
diff --git a/docs/source/plugins/timer.rst b/docs/source/plugins/timer.rst
new file mode 100644
index 00000000000..578dd2beb50
--- /dev/null
+++ b/docs/source/plugins/timer.rst
@@ -0,0 +1,22 @@
+.. _plugins-timer:
+
+Game Play Timer Plugin
+======================
+
+The timer plugin records the total time spent emulating each combination of a
+system and a software list item, as well as the number of times each combination
+has been launched. To see the statistics, bring up the main menu (press **Tab**
+during emulation by default), choose **Plugin Options**, and then choose
+**Timer**.
+
+This plugin records wall clock time (the real time duration elapsed while
+emulation is running, according to the host OS) as well as emulated time. The
+elapsed wall clock time may be shorter than the elapsed emulated time if you
+turn off throttling or use MAME’s “fast forward” feature, or it may be longer
+than the elapsed emulated time if you pause the emulation of if the emulation is
+too demanding to run at full speed.
+
+The statistics are stored in the file **timer.db** in the **timer** folder
+inside your plugin data folder (see the
+:ref:`homepath option <mame-commandline-homepath>`). The file is a SQLite3
+database.
diff --git a/docs/source/security.rst b/docs/source/security.rst
index d8fc372c614..4e26c4ae97a 100644
--- a/docs/source/security.rst
+++ b/docs/source/security.rst
@@ -1,7 +1,7 @@
MAME and security concerns
==========================
-MAME is not intended or designed to run in secure sites. It has not been security audited for such types of usage, and has been known in the past to have flaws that could be used for malicious intent if run as administator or root.
+MAME is not intended or designed to run in secure sites. It has not been security audited for such types of usage, and has been known in the past to have flaws that could be used for malicious intent if run as administrator or root.
**We do not suggest or condone the use of MAME as administrator or root and use as such is done at your own risk.**
diff --git a/docs/source/techspecs/audio_effects.rst b/docs/source/techspecs/audio_effects.rst
new file mode 100644
index 00000000000..12228b97444
--- /dev/null
+++ b/docs/source/techspecs/audio_effects.rst
@@ -0,0 +1,147 @@
+Audio effects
+=============
+
+.. contents:: :local:
+
+
+1. Generalities
+---------------
+
+The audio effects are effects that are applied to the sound between
+the speaker devices and the actual sound output. In the current
+implementation the effect chain is fixed (but not the effect
+parameters), and the parameters are stored in the cfg files. They are
+honestly not really designed for extensibility yet, if ever.
+
+Adding an effect requires working on four parts:
+
+* audio_effects/aeffects.* for effect object creation and "publishing"
+* audio_effects/youreffect.* for the effect implementation
+* frontend/mame/ui/audioeffects.cpp to be able to instantiate the effect configuration menu
+* frontend/mame/ui/audioyoureffect.* to implement the effect configuration menu
+
+2. audio_effects/aeffects.*
+---------------------------
+
+The audio_effect class in the aeffect sources provides three things:
+
+* an enum value to designate the effect type and which must match its
+ position in the chain (iow, the effect chain follows the enum order),
+ in the .h
+* the effect name in the audio_effect::effect_names array in the .cpp
+* the creation of a correct effect object in audio_effect::create in the .cpp
+
+
+
+3. audio_effects/youreffect.*
+-----------------------------
+
+This is where you implement the effect. It takes the shape of an
+audio_effect_youreffect class which derives from audio_effect.
+
+The methods to implement are:
+
+.. code-block:: C++
+
+ audio_effect_youreffect(u32 sample_rate, audio_effect *def);
+
+ virtual int type() const override;
+ virtual void config_load(util::xml::data_node const *ef_node) override;
+ virtual void config_save(util::xml::data_node *ef_node) const override;
+ virtual void default_changed() override;
+ virtual u32 history_size() const; // optional
+
+The constructor must pass the parameters to ``audio_effect`` and
+initialize the effect parameters. ``type`` must return the enum value
+for the effect. ``config_load`` and ``config_save`` should load or
+save the effect parameters from/to the cfg file xml tree.
+``default_changed`` is called when the parameters in ``m_default`` are
+changed and the parameters may need to be updated. ``history_size``
+allows to tell how many samples should still be available of the
+previous input frame. Note that this number must not depend on the
+parameters and only on the sample rate.
+
+An effect has a number of parameters that can come from three sources:
+
+* fixed default value
+* equivalent effect object from the default effect chain
+* user setting through the UI
+
+The first two are recognized through the value of ``m_default`` which
+gets the value of ``def`` in the constructor. When it's nullptr, the
+value to use when not set by the user is the fixed one, otherwise it's
+the one in ``m_default``.
+
+At minimum an effect should have a parameter allowing to bypass it.
+
+Managing a parameter uses four methods:
+
+* ``type param() const;`` returns the current parameter value
+* ``void set_param(type value);`` sets the current parameter value and marks it as set by the user
+* ``bool isset_param() const;`` returns true is the parameter was set by the user
+* ``void reset_param();`` resets the parameter to the default value (from m_default or fixed) and marks it as not set by the user
+
+``config_save`` must only save the user-set parameters.
+``config_load`` must retrieve the parameters that are present and mark
+them as set by the user and reset all the others.
+
+Finally the actual implementation goes into the ``apply`` method:
+
+.. code-block:: C++
+
+ virtual void apply(const emu::detail::output_buffer_flat<sample_t> &src, emu::detail::output_buffer_flat<sample_t> &dest) override;
+
+That method takes two buffers with the same number of channels and has
+to apply the effect to ``src`` to produce ``dest``. The
+``output_buffer_flat`` is non-interleaved with independant per-channel
+buffers.
+
+To make bypassing easier, the ``copy(src, dest)`` method of
+audio_effect allows to copy the samples from ``src`` to ``dest``
+without changing them.
+
+The effect application part should looks like:
+
+.. code-block:: C++
+
+ u32 samples = src.available_samples();
+ dest.prepare_space(samples);
+ u32 channels = src.channels();
+
+ // generate channels * samples results and put them in dest
+
+ dest.commit(samples);
+
+To get pointers to the buffers, one uses:
+
+.. code-block:: C++
+
+ const sample_t *source = src.ptrs(channel, source_index); // source_index must be in [-history_size()..samples-1]
+ sample_t *destination = dest.ptrw(channel, destination_index); // destination_index must be in [0..samples-1]
+
+The samples pointed by source and destination are contiguous. The
+number of channels will not change from one apply call to another, the
+number of samples will vary though. Also the call happens in a
+different thread than the main thread and also in a different thread
+than the parameter setting calls are made from.
+
+
+
+
+4. frontend/mame/ui/audioeffects.cpp
+------------------------------------
+
+Here it suffices to add a creation of the menu
+menu_audio_effect_youreffect in menu_audio_effects::handle. The menu
+effect will pick the effect names from audio_effect (in aeffect.*).
+
+
+5. frontend/mame/ui/audioyoureffect.*
+-------------------------------------
+
+This is used to implement the configuration menu for the effect. It's
+a little complicated because it needs to generate the list of
+parameters and their values, set left or right arrow flags depending
+on the possible modifications, dim them (FLAG_INVERT) when not set by
+the user, and manage the arrows and clear keys to change them. Just
+copy an existing one and change it as needed.
diff --git a/docs/source/techspecs/cpu_device.rst b/docs/source/techspecs/cpu_device.rst
new file mode 100644
index 00000000000..c21a20a4fe7
--- /dev/null
+++ b/docs/source/techspecs/cpu_device.rst
@@ -0,0 +1,229 @@
+CPU devices
+===========
+
+.. contents:: :local:
+
+
+1. Overview
+-----------
+
+CPU devices derivatives are used, unsurprisingly, to implement the
+emulation of CPUs, MCUs and SOCs. A CPU device is first a combination
+of ``device_execute_interface``, ``device_memory_interface``,
+``device_state_interface`` and ``device_disasm_interface``. Refer to
+the associated documentations when they exist.
+
+Two more functionalities are specific to CPU devices which are the DRC
+and the interruptibility support.
+
+
+2. DRC
+------
+
+TODO.
+
+
+3. Interruptibility
+-------------------
+
+3.1 Definition
+~~~~~~~~~~~~~~
+
+An interruptible CPU is defined as a core which is able to suspend the
+execution of one instruction at any time, exit execute_run, then at
+the next call of ``execute_run`` keep going from where it was. This
+includes being able to abort an issued memory access, quit
+execute_run, then upon the next call of execute_run reissue the exact
+same access.
+
+
+3.2 Implementation requirements
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Memory accesses must be done with ``read_interruptible`` or
+``write_interruptible`` on a ``memory_access_specific`` or a
+``memory_access_cache``. The access must be done as bus width and bus
+alignment.
+
+After each access the core must test whether ``icount <= 0``. This
+test should be done after ``icount`` is decremented of the time taken
+by the access itself, to limit the number of tests. When ``icount``
+reaches 0 or less it means that the instruction emulation needs to be
+suspended.
+
+To know whether the access needs to be re-issued,
+``access_to_be_redone()`` needs to be called. If it returns true then
+the time taken by the access needs to be credited back, since it
+hasn't yet happened, and the access will need to be re-issued. The
+call to ``access_to_be_redone()`` clears the reissue flag. If you
+need to check the flag without clearing it use
+``access_to_be_redone_noclear()``.
+
+The core needs to do enough bookkeeping to eventually restart the
+instruction execution just before the access or just after the test,
+depending on the need of reissue.
+
+Finally, to indicate to the rest of the infrastructure the support, it
+must override cpu_is_interruptible() to return true.
+
+
+3.3 Example implementation with generators
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+To ensure decent performance, the current implementations (h8, 6502
+and 68000) use a python generator to generate two versions of each
+instruction interpreter, one for the normal emulation, and one for
+restarting the instruction.
+
+The restarted version looks like that (for a 4-cycles per access cpu):
+
+.. code-block:: C++
+
+ void device::execute_inst_restarted()
+ {
+ switch(m_inst_substate) {
+ case 0:
+ [...]
+
+ m_address = [...];
+ m_mask = [...];
+ [[fallthrough]];
+ case 42:
+ m_result = specific.read_interruptible(m_address, m_mask);
+ m_icount -= 4;
+ if(m_icount <= 0) {
+ if(access_to_be_redone()) {
+ m_icount += 4;
+ m_inst_substate = 42;
+ } else
+ m_inst_substate = 43;
+ return;
+ }
+ [[fallthrough]];
+ case 43:
+ [...] = m_result;
+ [...]
+ }
+ m_inst_substate = 0;
+ return;
+ }
+
+The non-restarted version is the same thing with the switch and the
+final ``m_inst_substate`` clearing removed.
+
+.. code-block:: C++
+
+ void device::execute_inst_non_restarted()
+ {
+ [...]
+ m_address = [...];
+ m_mask = [...];
+ m_result = specific.read_interruptible(m_address, m_mask);
+ m_icount -= 4;
+ if(m_icount <= 0) {
+ if(access_to_be_redone()) {
+ m_icount += 4;
+ m_inst_substate = 42;
+ } else
+ m_inst_substate = 43;
+ return;
+ }
+ [...] = m_result;
+ [...]
+ return;
+ }
+
+The main loop then looks like this:
+
+.. code-block:: C++
+
+ void device::execute_run()
+ {
+ if(m_inst_substate)
+ call appropriate restarted instruction handler
+ while(m_icount > 0) {
+ debugger_instruction_hook(m_pc);
+ call appropriate non-restarted instruction handler
+ }
+ }
+
+The idea is thus that ``m_inst_substate`` indicates where in an
+instruction one is, but only when an interruption happens. It
+otherwise stays at 0 and is essentially never looked at. Having two
+versions of the interpretation allows to remove the overhead of the
+switch and the end-of-instruction substate clearing.
+
+It is not a requirement to use a generator-based that method, but a
+different one which does not have unacceptable performance
+implications has not yet been found.
+
+3.4 Bus contention cpu_device interface
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The main way to setup bus contention is through the memory maps.
+Lower-level access can be obtained through some methods on cpu_device
+though.
+
+.. code-block:: C++
+
+ bool cpu_device::access_before_time(u64 access_time, u64 current_time) noexcept;
+
+The method ``access_before_time`` allows to try to run an access at a
+given time in cpu cycles. It takes the current time
+(``total_cycles()``) and the expected time for the access. If there
+aren't enough cycles to reach that time the remaining cycles are eaten
+and the method returns true to tell not to do the access and call the
+method again eventually. Otherwise enough cycles are eaten to reach
+the access time and false is returned to tell to do the access.
+
+
+.. code-block:: C++
+
+ bool cpu_device::access_before_delay(u32 cycles, const void *tag) noexcept;
+
+The method ``access_before_delay`` allows to try to run an access
+after a given delay. The tag is an opaque, non-nullptr value used to
+characterize the source of the delay, so that the delay is not applied
+multiple times. Similarly to the previous method cycles are eaten and
+true is returned to abort the access, false to execute it.
+
+.. code-block:: C++
+
+ void cpu_device::access_after_delay(u32 cycles) noexcept;
+
+The method ``access_after_delay`` allows to add a delay after an
+access is done. There is no abort possible, hence no return boolean.
+
+.. code-block:: C++
+
+ void cpu_device::defer_access() noexcept;
+
+The method ``defer_access`` tells the cpu that we need to wait for an
+external event. It marks the access as to be redone, and eats all the
+remaining cycles of the timeslice. The idea is then that the access
+will be retried after time advances up to the next global system
+synchronisation event (sync, timer timeout or set_input_line). This
+is the method to use when for instance waiting on a magic latch for
+data expected from scsi transfers, which happen on timer timeouts.
+
+.. code-block:: C++
+
+ void cpu_device::retry_access() noexcept;
+
+The method ``retry_access`` tells the cpu that the access will need to
+be retried, and nothing else. This can easily reach a situation of
+livelock, so be careful. It is used for instance to simulate a wait
+line (for the z80 for instance) which is controlled through
+set_input_line. The idea is that the device setting wait does the
+set_input_line and a retry_access. The cpu core, as long as the wait
+line is set just eats cycles. Then, when the line is cleared the core
+will retry the access.
+
+
+3.5 Interaction with DRC
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+At this point, interruptibility and DRC are entirely incompatible. We
+do not have a method to quit the generated code before or after an
+access. It's theorically possible but definitely non-trivial.
+
diff --git a/docs/source/techspecs/device_disasm_interface.rst b/docs/source/techspecs/device_disasm_interface.rst
index beacaf8e6df..a2ab4fa7eec 100644
--- a/docs/source/techspecs/device_disasm_interface.rst
+++ b/docs/source/techspecs/device_disasm_interface.rst
@@ -168,7 +168,7 @@ A CPU core derives from **device_disasm_interface** through
That method must return a pointer to a newly allocated disassembler
object. The caller takes ownership and handles the lifetime.
-THis method will be called at most one in the lifetime of the cpu
+This method will be called at most one in the lifetime of the cpu
object.
4. Disassembler configuration and communication
@@ -184,7 +184,7 @@ model name), feel free to use a parameter. Otherwise derive the
class.
Dynamic configuration must be done by first defining a nested public
-struct called "config" in the disassembler, with virtual destructor
+struct called ``config`` in the disassembler, with virtual destructor
and pure virtual methods to pull the required information. A pointer
to that struct should be passed to the disassembler constructor. The
cpu core should then add a derivation from that config struct and
@@ -195,9 +195,9 @@ the config class to give the information.
----------------
There currently is no way for the debugger GUI to add per-core
-configuration. It is needed for in particular the s2650 and the
-saturn cores. It should go through the cpu core class itself, since
-it's pulled from the config struct.
+configuration. In particular, it is needed for the s2650 and Saturn
+cores. It should go through the cpu core class itself, since it's
+pulled from the config struct.
There is support missing in unidasm for per-cpu configuration. That's
needed for a lot of things, see the unidasm source code for the
diff --git a/docs/source/techspecs/device_memory_interface.rst b/docs/source/techspecs/device_memory_interface.rst
index 4efa6a75234..1f8e2b1c37b 100644
--- a/docs/source/techspecs/device_memory_interface.rst
+++ b/docs/source/techspecs/device_memory_interface.rst
@@ -1,18 +1,22 @@
The device_memory_interface
===========================
+.. contents:: :local:
+
+
1. Capabilities
---------------
The device memory interface provides devices with the capability of
creating address spaces, to which address maps can be associated.
-It's used for any device that provides a (logically) address/data bus
-other devices can be connected to. It's mainly, but not only, cpus.
+It’s used for any device that provides a (logical) address/data bus
+that other devices can be connected to. That’s mainly, but not solely,
+CPUs.
The interface allows for an unlimited set of address spaces, numbered
-with small positive values. The IDs should stay small because they
-index vectors to keep the lookup fast. Spaces number 0-3 have an
-associated constant name:
+with small, non-negative values. The IDs index vectors, so they should
+stay small to keep the lookup fast. Spaces numbered 0-3 have associated
+constant name:
+----+---------------+
| ID | Name |
@@ -26,91 +30,139 @@ associated constant name:
| 3 | AS_OPCODES |
+----+---------------+
-Spaces 0 and 3, e.g. AS_PROGRAM and AS_OPCODE, are special for the
-debugger and some CPUs. AS_PROGRAM is use by the debugger and the
-cpus as the space from with the cpu reads its instructions for the
-disassembler. When present, AS_OPCODE is used by the debugger and
-some cpus to read the opcode part of the instruction. What opcode
-means is device-dependant, for instance for the z80 it's the initial
-byte(s) which are read with the M1 signal asserted. For the 68000 is
-means every instruction word plus the PC-relative accesses. The main,
-but not only, use of AS_OPCODE is to implement hardware decrypting
-instructions separately from the data.
+Spaces 0 and 3, i.e. ``AS_PROGRAM`` and ``AS_OPCODES``, are special for
+the debugger and some CPUs. ``AS_PROGRAM`` is use by the debugger and
+the CPUs as the space from which the CPU reads its instructions for the
+disassembler. When present, ``AS_OPCODES`` is used by the debugger and
+some CPUs to read the opcode part of the instruction. What opcode means
+is device-dependant, for instance for the Z80 it's the initial byte(s)
+which are read with the M1 signal asserted, while for the 68000 is means
+every instruction word plus PC-relative accesses. The main, but not
+only, use of ``AS_OPCODES`` is to implement hardware decryption of
+instructions separately from data.
+
2. Setup
--------
-| std::vector<std::pair<int, const address_space_config \*>>\ **memory_space_config**\ (int spacenum) const
+.. code-block:: C++
+
+ std::vector<std::pair<int, const address_space_config *>> memory_space_config() const;
The device must override that method to provide a vector of pairs
-comprising of a space number and its associated
-**address_space_config** describing its configuration. Some examples
-to look up when needed:
+comprising of a space number and an associated ``address_space_config``
+describing its configuration. Some examples to look up when needed:
-* Standard two-space vector: v60_device
-* Conditional AS_OPCODE: z80_device
-* Inherit config and add a space: m6801_device
-* Inherit config and patch a space: tmpz84c011_device
+* Standard two-space vector:
+ `v60_device <https://git.redump.net/mame/tree/src/devices/cpu/v60/v60.cpp?h=mame0226>`_
+* Conditional ``AS_OPCODES``:
+ `z80_device <https://git.redump.net/mame/tree/src/devices/cpu/z80/z80.cpp?h=mame0226>`_
+* Inherit configuration and add a space:
+ `hd647180x_device <https://git.redump.net/mame/tree/src/devices/cpu/z180/hd647180x.cpp?h=mame0226>`_
+* Inherit configuration and modify a space:
+ `tmpz84c011_device <https://git.redump.net/mame/tree/src/devices/cpu/z80/tmpz84c011.cpp?h=mame0226>`_
+.. code-block:: C++
-| bool **has_configured_map**\ () const
-| bool **has_configured_map**\ (int index) const
+ bool has_configured_map(int index = 0) const;
+
+The ``has_configured_map`` method allows to test whether an
+``address_map`` has been associated with a given space in the
+``memory_space_config`` method. That allows optional memory spaces to
+be implemented, such as ``AS_OPCODES`` in certain CPU cores.
-The **has_configured_map** method allows to test in the
-**memory_space_config** method whether an **address_map** has been
-associated with a given space. That allows to implement optional
-memory spaces, such as AS_OPCODES in certain cpu cores. The
-parameterless version tests for space 0.
3. Associating maps to spaces
-----------------------------
-Associating maps to spaces is done at the machine config level, after the device declaration.
+Associating maps to spaces is done at the machine configuration level,
+after the device is instantiated.
+
+.. code-block:: C++
+
+ void set_addrmap(int spacenum, T &obj, Ret (U::*func)(Params...));
+ void set_addrmap(int spacenum, Ret (T::*func)(Params...));
+ void set_addrmap(int spacenum, address_map_constructor map);
+
+These function associate a map with a given space. Address maps
+associated with non-existent spaces are ignored (no warning given). The
+first form takes a reference to an object and a method to call on that
+object. The second form takes a method to call on the current device
+being configured. The third form takes an ``address_map_constructor``
+to copy. In each case, the function must be callable with reference to
+an ``address_map`` object as an argument.
-| **MCFG_DEVICE_ADDRESS_MAP**\ (_space, _map)
-| **MCFG_DEVICE_PROGRAM_MAP**\ (_map)
-| **MCFG_DEVICE_DATA_MAP**\ (_map)
-| **MCFG_DEVICE_IO_MAP**\ (_map)
-| **MCFG_DEVICE_OPCODES_MAP**\ (_map)
+To remove a previously configured address map, call ``set_addrmap`` with
+a default-constructed ``address_map_constructor`` (useful for removing a
+map for an optional space in a derived machine configuration).
-The generic macro and the four specific ones associate a map to a
-given space. Address maps associated to non-existing spaces are
-ignored (no warning given). devcpu.h defines MCFG_CPU_*_MAP aliases
-to the specific macros.
+As an example, here’s the address map configuration for the main CPU in
+the Hana Yayoi and Hana Fubuki machines, with all distractions removed:
-| **MCFG_DEVICE_REMOVE_ADDRESS_MAP**\ (_space)
+.. code-block:: C++
-That macro removes a memory map associated to a given space. Useful
-when removing a map for an optional space in a machine config
-derivative.
+ class hnayayoi_state : public driver_device
+ {
+ public:
+ void hnayayoi(machine_config &config);
+ void hnfubuki(machine_config &config);
+
+ private:
+ required_device<cpu_device> m_maincpu;
+
+ void hnayayoi_map(address_map &map);
+ void hnayayoi_io_map(address_map &map);
+ void hnfubuki_map(address_map &map);
+ };
+
+ void hnayayoi_state::hnayayoi(machine_config &config)
+ {
+ Z80(config, m_maincpu, 20000000/4);
+ m_maincpu->set_addrmap(AS_PROGRAM, &hnayayoi_state::hnayayoi_map);
+ m_maincpu->set_addrmap(AS_IO, &hnayayoi_state::hnayayoi_io_map);
+ }
+
+ void hnayayoi_state::hnfubuki(machine_config &config)
+ {
+ hnayayoi(config);
+
+ m_maincpu->set_addrmap(AS_PROGRAM, &hnayayoi_state::hnfubuki_map);
+ m_maincpu->set_addrmap(AS_IO, address_map_constructor());
+ }
4. Accessing the spaces
-----------------------
-| address_space &\ **space**\ () const
-| address_space &\ **space**\ (int index) const
+.. code-block:: C++
+
+ address_space &space(int index = 0) const;
-Returns a given address space post-initialization. The parameterless
-version tests for AS_PROGRAM/AS_0. Aborts if the space doesn't exist.
+Returns the specified address space post-initialization. The specified
+address space must exist.
-| bool **has_space**\ () const
-| bool **has_space**\ (int index) const
+.. code-block:: C++
-Indicates whether a given space actually exists. The parameterless
-version tests for AS_PROGRAM/AS_0.
+ bool has_space(int index = 0) const;
+
+Indicates whether a given space actually exists.
5. MMU support for disassembler
-------------------------------
-| bool **translate**\ (int spacenum, int intention, offs_t &address)
+.. code-block:: C++
+
+ bool translate(int spacenum, int intention, offs_t &address, address_space *&target_space);
Does a logical to physical address translation through the device's
-MMU. spacenum gives the space number, intention the type of the
-future access (TRANSLATE_(READ\|WRITE\|FETCH)(\|_USER\|_DEBUG)) and
-address is an inout parameter with the address to translate and its
-translated version. Should return true if the translation went
-correctly, false if the address is unmapped.
-
-Note that for some historical reason the device itself must override
-the virtual method **memory_translate** with the same signature.
+MMU. spacenum gives the space number, intention for the type of the
+future access (``TR_(READ\|WRITE\|FETCH)``), address is an in/out
+parameter holding the address to translate on entry and the translated
+version on return, and finally target_space is the actual space the
+access would end up in, which may be in a different device. Should
+return ``true`` if the translation went correctly, or ``false`` if the
+address is unmapped. The call must not change the state of the
+device.
+
+Note that for some historical reason, the device itself must override
+the virtual method ``memory_translate`` with the same signature.
diff --git a/docs/source/techspecs/device_rom_interface.rst b/docs/source/techspecs/device_rom_interface.rst
index 576800e634a..4125bc9536a 100644
--- a/docs/source/techspecs/device_rom_interface.rst
+++ b/docs/source/techspecs/device_rom_interface.rst
@@ -1,92 +1,113 @@
The device_rom_interface
========================
+.. contents:: :local:
+
+
1. Capabilities
---------------
-This interface is designed for devices which expect to have a rom
-connected to them on a dedicated bus. It's mostly designed for sound
+This interface is designed for devices that expect to have a ROM
+connected to them on a dedicated bus. It’s mostly designed for sound
chips. Other devices types may be interested but other considerations
-may make it impratical (graphics decode caching for instance). The
-interface provides the capability of either connecting a ROM_REGION,
-connecting an ADDRESS_MAP or dynamically setting up a block of memory
-as rom. In the region/block cases, banking is automatically handled.
+may make it impractical (graphics decode caching, for instance). The
+interface provides the capability to connect a ROM region, connect an
+address map, or dynamically set up a block of memory as ROM. In the
+region/memory block cases, banking is handled automatically.
+
2. Setup
--------
-| **device_rom_interface**\ (const machine_config &mconfig, device_t &device, u8 addrwidth, endianness_t endian = ENDIANNESS_LITTLE, u8 datawidth = 8)
+.. code-block:: C++
+
+ device_rom_interface<AddrWidth, DataWidth=0, AddrShift=0, Endian=ENDIANNESS_LITTLE>
-The constructor of the interface wants, in addition to the standard
-parameters, the address bus width of the dedicated bus. In addition
-the endianness (if not little endian or byte-sized bus) and data bus
-width (if not byte) can be provided.
+The interface is a template that takes the address width of the
+dedicated bus as a parameter. In addition the data bus width (if not
+byte), address shift (if non-zero) and Endianness (if not little Endian
+or byte-sized bus) can be provided. Data bus width is 0 for byte, 1
+for word, etc.
-| **MCFG_DEVICE_ADDRESS_MAP**\ (AS_0, map)
+.. code-block:: C++
-Use that method at machine config time to provide an address map for
-the bus to connect to. It has priority over a rom region if one is
+ void set_map(map);
+
+Use that method at machine configuration time to provide an address map
+for the bus to connect to. It has priority over a ROM region if one is
also present.
-| **MCFG_DEVICE_ROM**\ (tag)
+.. code-block:: C++
+
+ void set_device_rom_tag(tag);
+
+Used to specify a ROM region to use if a device address map is not
+given. Defaults to ``DEVICE_SELF``, i.e. the device’s tag.
-Used to select a rom region to use if a device address map is not
-given. Defaults to DEVICE_SELF, e.g. the device tag.
+.. code-block:: C++
-| **ROM_REGION**\ (length, tag, flags)
+ ROM_REGION(length, tag, flags)
-If a rom region with a tag as given with **MCFG_DEVICE_ROM** if
+If a ROM region with the tag specified using ``set_device_rom_tag`` if
present, or identical to the device tag otherwise, is provided in the
-rom description for the system, it will be automatically picked up as
-the connected rom. An address map has priority over the region if
-present in the machine config.
+ROM definitions for the system, it will be automatically picked up as
+the connected ROM. An address map has priority over the region if
+present in the machine configuration.
-| void **set_rom_endianness**\ (endianness_t endian)
-| void **set_rom_data_width**\ (u8 width)
-| void **set_rom_addr_width**\ (u8 width)
+.. code-block:: C++
-These methods, intended for generic devices with indefinite hardware
-specifications, override the endianness, data bus width and address
-bus width assigned through the constructor. They must be called from
-within the device before **config_complete** time.
+ void override_address_width(u8 width);
-| void **set_rom**\ (const void \*base, u32 size);
+This method allows the address bus width to be overridden. It must be
+called from within the device before **config_complete** time.
-At any time post- **interface_pre_start**, a memory block can be
-setup as the connected rom with that method. It overrides any
+.. code-block:: C++
+
+ void set_rom(const void *base, u32 size);
+
+At any time post-\ ``interface_pre_start``, a memory block can be
+set up as the connected ROM with that method. It overrides any
previous setup that may have been provided. It can be done multiple
times.
-3. Rom access
+
+3. ROM access
-------------
-| u8 **read_byte**\ (offs_t byteaddress)
-| u16 **read_word**\ (offs_t byteaddress)
-| u32 **read_dword**\ (offs_t byteaddress)
-| u64 **read_qword**\ (offs_t byteaddress)
+.. code-block:: C++
+
+ u8 read_byte(offs_t addr);
+ u16 read_word(offs_t addr);
+ u32 read_dword(offs_t addr);
+ u64 read_qword(offs_t addr);
-These methods provide read access to the connected rom. Out-of-bounds
-access results in standard unmapped read logerror messages.
+These methods provide read access to the connected ROM. Out-of-bounds
+access results in standard unmapped read ``logerror`` messages.
-4. Rom banking
+
+4. ROM banking
--------------
-If the rom region or the memory block in set_rom is larger than the
-address bus, banking is automatically setup.
+If the ROM region or the memory block in ``set_rom`` is larger than the
+address bus can access, banking is automatically set up.
+
+.. code-block:: C++
-| void **set_rom_bank**\ (int bank)
+ void set_rom_bank(int bank);
That method selects the current bank number.
+
5. Caveats
----------
Using that interface makes the device derive from
-**device_memory_interface**. If the device wants to actually use the
-memory interface for itself, remember that AS_0/AS_PROGRAM is used by
-the rom interface, and don't forget to upcall **memory_space_config**.
-
-For devices which have outputs that can be used to address ROMs but
-only to forward the data to another device for processing, it may be
-helpful to disable the interface when it is not required. This can be
-done by overriding **memory_space_config** to return an empty vector.
+``device_memory_interface``. If the device wants to actually use the
+memory interface for itself, remember that space zero (0, or
+``AS_PROGRAM``) is used by the ROM interface, and don’t forget to call
+the base ``memory_space_config`` method.
+
+For devices which have outputs that can be used to address ROMs but only
+to forward the data to another device for processing, it may be helpful
+to disable the interface when it is not required. This can be done by
+overriding ``memory_space_config`` to return an empty vector.
diff --git a/docs/source/techspecs/device_sound_interface.rst b/docs/source/techspecs/device_sound_interface.rst
new file mode 100644
index 00000000000..859d2497477
--- /dev/null
+++ b/docs/source/techspecs/device_sound_interface.rst
@@ -0,0 +1,286 @@
+The device_sound_interface
+==========================
+
+.. contents:: :local:
+
+
+1. The sound system
+-------------------
+
+The device sound interface is the entry point for devices that handle
+sound input and/or output. The sound system is built on the concept
+of *streams* which connect devices together with resampling and mixing
+applied transparently as needed. Microphones (audio input) and
+speakers (audio output) are specific known devices which use the same
+interface.
+
+2. Devices using device_sound_interface
+---------------------------------------
+
+2.1 Initialisation
+~~~~~~~~~~~~~~~~~~
+
+Sound streams must be created in the device_start (or
+interface_pre_start) method.
+
+.. code-block:: C++
+
+ sound_stream *stream_alloc(int inputs, int outputs, int sample_rate, sound_stream_flags flags = STREAM_DEFAULT_FLAGS);
+
+A stream is created with ``stream_alloc``. It takes the number of
+input and output channels, the sample rate and optionally flags.
+
+The sample rate can be SAMPLE_RATE_INPUT_ADAPTIVE,
+SAMPLE_RATE_OUTPUT_ADAPTIVE or SAMPLE_RATE_ADAPTIVE. In that case the
+chosen sample rate is the highest one among the inputs, outputs or
+both respectively. In case of loop, the chosen sample rate is the
+configured global sample rate.
+
+The only available non-default flag is STREAM_SYNCHRONOUS. When set,
+the sound generation method will be called for every sample
+individually. It's necessary for DSPs that run a program on every
+sample. but on the other hand it's expensive, so only to be used when
+required.
+
+Devices can create multiple streams. It's rare though. Some Yamaha
+chips should but don't. Inputs and outputs are numbered from 0 and
+arrange all streams in the order they are created.
+
+
+2.2 Sound input/output
+~~~~~~~~~~~~~~~~~~~~~~
+
+.. code-block:: C++
+
+ virtual void sound_stream_update(sound_stream &stream);
+
+This method is required to be implemented to consume the input samples
+and/or compute the output ones. The stream to update for is passed as
+the parameter. See the streams section, specifically sample access,
+to see how to write the method.
+
+
+2.3 Stream information
+~~~~~~~~~~~~~~~~~~~~~~
+
+.. code-block:: C++
+
+ int inputs() const;
+ int outputs() const;
+ std::pair<sound_stream *, int> input_to_stream_input(int inputnum) const;
+ std::pair<sound_stream *, int> output_to_stream_output(int outputnum) const;
+
+The method ``inputs`` returns the total number of inputs in the
+streams created by the device. The method ``outputs`` similarly
+counts the outputs. The other two methods allow to grab the stream
+and channel number for the device corresponding to the global input or
+output number.
+
+
+2.4 Gain management
+~~~~~~~~~~~~~~~~~~~
+
+.. code-block:: C++
+
+ float input_gain(int inputnum) const;
+ float output_gain(int outputnum) const;
+ void set_input_gain(int inputnum, float gain);
+ void set_output_gain(int outputnum, float gain);
+ void set_route_gain(int source_channel, device_sound_interface *target, int target_channel, float gain);
+
+ float user_output_gain() const;
+ float user_output_gain(int outputnum) const;
+ void set_user_output_gain(float gain);
+ void set_user_output_gain(int outputnum, float gain);
+
+Those methods allow to set the gain on every step of the routes
+between streams. All gains are multipliers, with default value 1.0.
+The steps are, from samples output in ``sound_stream_update`` to
+samples read in the next device's ``sound_stream_update``:
+
+* Per-channel output gain
+* Per-channel user output gain
+* Per-device user output gain
+* Per-route gain
+* Per-channel input gain
+
+The user gains must not be set from the driver, they're for use by the
+user interface (the sliders) and are saved in the game configuration.
+The other gains are for driver/device use, and are saved in save
+states.
+
+
+2.5 Routing setup
+~~~~~~~~~~~~~~~~~
+
+.. code-block:: C++
+
+ device_sound_interface &add_route(u32 output, const device_finder<T, R> &target, double gain, u32 channel = 0)
+ device_sound_interface &add_route(u32 output, const char *target, double gain, u32 channel = 0);
+ device_sound_interface &add_route(u32 output, device_sound_interface &target, double gain, u32 channel = 0);
+
+ device_sound_interface &reset_routes();
+
+Routes between devices, e.g. between streams, are set at configuration
+time. The method ``add_route`` must be called on the source device
+and gives the channel on the source device, the target device, the
+gain, and optionally the channel on the target device. The constant
+``ALL_OUTPUTS`` can be used to add a route from every channel of the
+source to a given channel of the destination.
+
+The method ``reset_routes`` is used to remove all the routes setup on
+a given source device.
+
+
+.. code-block:: C++
+
+ u32 get_sound_requested_inputs() const;
+ u32 get_sound_requested_outputs() const;
+ u64 get_sound_requested_inputs_mask() const;
+ u64 get_sound_requested_outputs_mask() const;
+
+Those methods are useful for devices which want to behave differently
+depending on what routes are set up on them. You get either the max
+number of requested channel plus one (which is the number of channels
+when all channels are routed, but is more useful when there are gaps)
+or a mask of use for channels 0-63. Note that ``ALL_OUTPUTS`` does
+not register any specific output or output count.
+
+
+
+3. Streams
+----------
+
+3.1 Generalities
+~~~~~~~~~~~~~~~~
+
+Streams are endpoints associated with devices and, when connected
+together, ensure the transmission of audio data between them. A
+stream has a number of inputs (which can be zero) and outputs (same)
+and one sample rate which is common to all inputs and outputs. The
+connections are set up at the machine configuration level and the sound
+system ensures mixing and resampling is done transparently.
+
+Samples in streams are encoded as sample_t. In the current
+implementation, this is a float. Nominal values are between -1 and 1,
+but clamping at the device level is not recommended (unless that's
+what happens in hardware of course) because the gain values, volume
+and effects can easily avoid saturation.
+
+They are implemented in the class ``sound_stream``.
+
+
+3.2 Characteristics
+~~~~~~~~~~~~~~~~~~~
+
+.. code-block:: C++
+
+ device_t &device() const;
+ bool input_adaptive() const;
+ bool output_adaptive() const;
+ bool synchronous() const;
+ u32 input_count() const;
+ u32 output_count() const;
+ u32 sample_rate() const;
+ attotime sample_period() const;
+
+
+3.3 Sample access
+~~~~~~~~~~~~~~~~~
+
+.. code-block:: C++
+
+ s32 samples() const;
+
+ void put(s32 output, s32 index, sample_t sample);
+ void put_clamp(s32 output, s32 index, sample_t sample, sample_t clamp = 1.0);
+ void put_int(s32 output, s32 index, s32 sample, s32 max);
+ void put_int_clamp(s32 output, s32 index, s32 sample, s32 maxclamp);
+ void add(s32 output, s32 index, sample_t sample);
+ void add_int(s32 output, s32 index, s32 sample, s32 max);
+ void fill(s32 output, sample_t value, s32 start, s32 count);
+ void fill(s32 output, sample_t value, s32 start);
+ void fill(s32 output, sample_t value);
+ void copy(s32 output, s32 input, s32 start, s32 count);
+ void copy(s32 output, s32 input, s32 start);
+ void copy(s32 output, s32 input);
+ sample_t get(s32 input, s32 index) const;
+ sample_t get_output(s32 output, s32 index) const;
+
+Those are the methods used to implement ``sound_stream_update``.
+First ``samples`` tells how many samples to consume and/or generate.
+The to-generate samples, if any, are pre-cleared (e.g. set to zero).
+
+Input samples are retrieved with ``get``, where ``input`` is the
+stream channel number and ``index`` the sample number.
+
+Generated samples are written with the put variants. ``put`` sets a
+sample_t in channel ``output`` at position ``index``. ``put_clamp``
+does the same but first clamps the value to +/-``clamp``. ``put_int``
+does it with an integer ``sample`` but pre-divides it by ``max``.
+``put_int_clamp`` does the same but also pre-clamps within
+-``maxclamp`` and ``maxclamp``-1, which is the normal range for a
+2-complement value.
+
+``add`` and ``add_int`` are similar but add the value of the sample to
+what's there instead of replacing. ``get_output`` gets the currently
+stored output value.
+
+``fill`` sets a range of an output channel to a given ``value``.
+``start`` tells where to start (default index 0), ``count`` how many
+(default up to the end of the buffer).
+
+``copy`` does the same as fill but gets its value from the indentical
+position in an input channel.
+
+Note that clamping should not be used unless it actually happens in
+hardware. Between gains and effects there is a fair chance saturation
+can be avoided later in the chain.
+
+
+
+3.4 Gain management
+~~~~~~~~~~~~~~~~~~~
+
+.. code-block:: C++
+
+ float user_output_gain() const;
+ void set_user_output_gain(float gain);
+ float user_output_gain(s32 output) const;
+ void set_user_output_gain(s32 output, float gain);
+
+ float input_gain(s32 input) const;
+ void set_input_gain(s32 input, float gain);
+ void apply_input_gain(s32 input, float gain);
+ float output_gain(s32 output) const;
+ void set_output_gain(s32 output, float gain);
+ void apply_output_gain(s32 output, float gain);
+
+
+This is similar to the device gain control, with a twist: apply
+multiplies the current gain by the given value.
+
+
+3.5 Misc. actions
+~~~~~~~~~~~~~~~~~
+
+.. code-block:: C++
+
+ void set_sample_rate(u32 sample_rate);
+ void update();
+
+The method ``set_sample_rate`` allows to change the sample rate of the
+stream. The method ``update`` triggers a call of
+``sound_stream_update`` on the stream and the ones it depends on to
+reach the current time in terms of samples.
+
+
+4. Devices using device_mixer_interface
+---------------------------------------
+
+The device mixer interface is used for devices that want to relay
+sound in the device tree without acting on it. It's very useful on
+for instance slot devices connectors, where the slot device may have
+an audio connection with the main system. They are routed like every
+other sound device, create the streams automatically and copy input to
+output. Nothing needs to be done in the device.
diff --git a/docs/source/techspecs/floppy.rst b/docs/source/techspecs/floppy.rst
index 609e5c53013..39060d4eddf 100644
--- a/docs/source/techspecs/floppy.rst
+++ b/docs/source/techspecs/floppy.rst
@@ -23,7 +23,7 @@ The new floppy subsystem aims at emulating the behaviour of floppies and floppy
A floppy disk is a disc that stores magnetic orientations on their surface disposed in a series on concentric circles called tracks or cylinders [1]_. Its main characteristics are its size (goes from a diameter of around 2.8" to 8") , its number of writable sides (1 or 2) and its magnetic resistivity. The magnetic resistivity indicates how close magnetic orientation changes can happen and the information kept. That's one third of what defines the term "density" that is so often used for floppies (the other two are floppy drive head size and bit-level encoding).
-The magnetic orientations are always binary, e.g. they're one way or the opposite, there's no intermediate state. Their direction can either be tengentially to the track, e.g in the direction or opposite to the rotation, or in the case of perpendicular recording the direction is perpendicular to the disc surface (hence the name). Perpendicular recording allows for closer orientation changes by writing the magnetic information more deeply, but arrived late in the technology lifetime. 2.88Mb disks and the floppy children (Zip drives, etc) used perpendicular recording. For simulation purposes the direction is not important, only the fact that only two orientations are possible is. Two more states are possible though: a portion of a track can be demagnetized (no orientation) or damaged (no orientation and can't be written to).
+The magnetic orientations are always binary, e.g. they're one way or the opposite, there's no intermediate state. Their direction can either be tangentially to the track, i.e. in the direction of or opposite to the rotation, or in the case of perpendicular recording the direction is perpendicular to the disc surface (hence the name). Perpendicular recording allows for closer orientation changes by writing the magnetic information more deeply, but arrived late in the technology lifetime. 2.88Mb disks and the floppy children (Zip drives, etc.) used perpendicular recording. For simulation purposes the direction is not important, only the fact that only two orientations are possible is. Two more states are possible though: a portion of a track can be demagnetized (no orientation) or damaged (no orientation and can't be written to).
A specific position in the disk rotation triggers an index pulse. That position can be detected through a hole in the surface (very visible in 5.25" and 3" floppies for instance) or through a specific position of the rotating center (3.5" floppies, perhaps others). This index pulse is used to designate the beginning of the track, but is not used by every system. Older 8" floppies have multiple index holes used to mark the beginning of sectors (called hard sectoring) but one of them is positioned differently to be recognized as the track start, and the others are at fixed positions relative to the origin one.
@@ -70,7 +70,7 @@ In every cell there may or may not be a magnetic orientation transition, e.g. a
Of course protections play with that to make formats not reproducible by the system controller, either breaking the three-zeroes rule or playing with the cells durations/sizes.
-Bit endocing is then the art of transforming raw data into a cell 0/1 configuration that respects the two constraints.
+Bit encoding is then the art of transforming raw data into a cell 0/1 configuration that respects the two constraints.
2.3.1.2. FM encoding
````````````````````
@@ -108,9 +108,9 @@ Other encodings exist, like M2FM, but they're very rare and system-specific.
2.3.1.6. Reading back encoded data
``````````````````````````````````
-Writing encoded data is easy, you only need a clock at the appropriate frequency and send or not a pulse on the clock edges. Reading back the data is where the fun is. Cells are a logical construct and not a physical measurable entity. Rotational speeds very around the defined one (+/- 2% is not rare) and local perturbations (air turbulence, surface distance...) make the instant speed very variable in general. So to extract the cell values stream the controller must dynamically synchronize with the pulse train that the floppy head picks up. The principle is simple: a cell-sized duration window is build within which the presence of at least one pulse indicates the cell is a '1', and the absence of any a '0'. After reaching the end of the window the starting time is moved appropriately to try to keep the observed pulse at the exact middle of the window. This allows to correct the phase on every '1' cell, making the synchronization work if the rotational speed is not too off. Subsequent generations of controllers used a Phase-Locked Loop (PLL) which vary both phase and window duration to adapt better to wrong rotational speeds, with usually a tolerance of +/- 15%.
+Writing encoded data is easy: you only need a clock at the appropriate frequency and send or not a pulse on the clock edges. Reading back the data is where the fun is. Cells are a logical construct and not a physical measurable entity. Rotational speeds very around the defined one (±2% is not rare), and local perturbations (air turbulence, surface distance…) make the instantaneous speed very variable in general. So to extract the cell values stream, the controller must dynamically synchronize with the pulse train that the floppy head picks up. The principle is simple: a cell-sized duration window is built within which the presence of at least one pulse indicates the cell is a '1', and the absence of any a '0'. After reaching the end of the window, the starting time is moved appropriately to try to keep the observed pulse at the exact middle of the window. This allows the phase to be corrected on every '1' cell, making the synchronization work if the rotational speed is not too off. Subsequent generations of controllers used Phase-Locked Loops (PLLs) which vary both phase and window duration to adapt better to inaccuarate rotational speeds, usually with a tolerance of ±15%.
-Once the cell data stream is extracted decoding depends on the encoding. In the FM and MFM case the only question is to recognize data bits from clock bits, while in GCR the start position of the first group should be found. That second level of synchronization is handled at a higher level using patterns not found in a normal stream.
+Once the cell data stream is extracted, decoding depends on the encoding. In the FM and MFM case the only question is to recognize data bits from clock bits, while in GCR the start position of the first group should be found. That second level of synchronization is handled at a higher level using patterns not found in a normal stream.
2.3.2. Sector-level organization
diff --git a/docs/source/techspecs/index.rst b/docs/source/techspecs/index.rst
index 67775ae3a74..72c678b4ca6 100644
--- a/docs/source/techspecs/index.rst
+++ b/docs/source/techspecs/index.rst
@@ -1,16 +1,27 @@
Technical Specifications
-------------------------
+========================
-This section covers technical specifications useful to programmers working on MAME's source or working on LUA scripts that run within the MAME framework.
+This section covers technical specifications useful to programmers working on
+MAME’s source or working on scripts that run within the MAME framework.
.. toctree::
- :titlesonly:
+ :titlesonly:
- layout_files
- device_memory_interface
- device_rom_interface
- device_disasm_interface
- floppy
- nscsi
- luaengine
- m6502
+ naming
+ layout_files
+ layout_script
+ object_finders
+ inputsystem
+ device_memory_interface
+ device_rom_interface
+ device_disasm_interface
+ device_sound_interface
+ memory
+ cpu_device
+ floppy
+ nscsi
+ m6502
+ uml_instructions
+ poly_manager
+ audio_effects
+ osd_audio
diff --git a/docs/source/techspecs/inputsystem.rst b/docs/source/techspecs/inputsystem.rst
new file mode 100644
index 00000000000..7a027b0ff22
--- /dev/null
+++ b/docs/source/techspecs/inputsystem.rst
@@ -0,0 +1,460 @@
+.. _inputsystem:
+
+Input System
+============
+
+.. contents::
+ :local:
+ :depth: 2
+
+
+.. _inputsystem-intro:
+
+Introduction
+------------
+
+The variety of systems MAME emulates, as well as the variation in host
+systems and peripherals, necessitates a flexible, configurable input
+system.
+
+Note that the input system is concerned with low-level user input.
+High-level user interaction, involving things like text input and
+pointing devices, is handled separately.
+
+
+.. _inputsystem-components:
+
+Components
+----------
+
+From the emulated system’s point of view, the input system has the
+following conceptual components.
+
+Input device
+~~~~~~~~~~~~
+
+Input devices supply input values. An input device typically
+corresponds to a physical device in the host system, for example a
+keyboard, mouse or game controller. However, there isn’t always a
+one-to-one correspondence between input devices and physical devices.
+For example the SDL keyboard provider module aggregates all keyboards
+into a single input device, and the Win32 lightgun provider module can
+present two input devices using input from a single mouse.
+
+Input devices are identified by their device class (keyboard, mouse,
+joystick or lightgun) and device number within the class. Input
+provider modules can also supply an implementation-dependent identifier
+to allow the user to configure stable device numbering.
+
+Note that input devices are unrelated to emulated devices (``device_t``
+implementations) despite the similar name.
+
+Input device item
+~~~~~~~~~~~~~~~~~
+
+Also known as a **control**, and input device item corresponds to a
+input source that produces a single value. This usually corresponds to
+a physical control or sensor, for example a joystick axis, a button or
+an accelerometer.
+
+MAME supports three kinds of controls: **switches**, **absolute axes**
+and **relative axes**:
+
+* Switches produce the value 0 when inactive (released or off) or 1 when
+ active (pressed or on).
+* Absolute axes produce a value normalised to the range -65,536 to
+ 65,536 with zero corresponding to the neutral position.
+* Relative axes produce a value corresponding to the movement since the
+ previous input update. Mouse-like devices scale values to
+ approximately 512 per nominal 100 DPI pixel.
+
+Negative axis values should correspond to directions up, to the left,
+away from the player, or anti-clockwise. For single-ended axes (e.g.
+pedals or displacement-sensitive triggers and buttons), only zero and
+the negative portion of the range should be used.
+
+Switches are used to represent controls that naturally have two distinct
+states, like buttons and toggle switches.
+
+Absolute axes are used to represent controls with a definite range
+and/or neutral position. Examples include steering wheels with limit
+stops, joystick axes, and displacement-sensitive triggers.
+
+Relative axes are used to represent controls with an effectively
+infinite range. Examples include mouse/trackball axes, incremental
+encoder dials, and gyroscopes.
+
+Accelerometers and force sensing joystick axes should be represented as
+absolute axes, even though the range is theoretically open-ended. In
+practice, there is a limit to the range the transducers can report,
+which is usually substantially larger than needed for normal operation.
+
+Input device items are identified by their associated device’s class and
+device number along with an **input item ID**. MAME supplies item IDs
+for common types of controls. Additional controls or controls that do
+not correspond to a common type are dynamically assigned item IDs. MAME
+supports hundreds to items per input device.
+
+I/O port field
+~~~~~~~~~~~~~~
+
+An I/O port field represents an input source in an emulated device or
+system. Most types of I/O port fields can be assigned one or more
+combinations of controls, allowing the user to control the input to
+the emulated system.
+
+Similarly to input device items, there are multiple types of I/O port
+fields:
+
+* **Digital fields** function as switches that produce one of two
+ distinct values. They are used for keyboard keys, eight-way joystick
+ direction switches, toggle switches, photointerruptors and other
+ emulated inputs that function as two-position switches.
+* **Absolute analog fields** have a range with defined minimum, maximum
+ and neutral positions. They are used for analog joystick axes,
+ displacement-sensitive pedals, paddle knobs, and other emulated inputs
+ with a defined range.
+* **Relative analog fields** have a range with defined minimum, maximum
+ and starting positions. On each update, the value accumulates and
+ wraps when it passes either end of the range. Functionally, this is
+ like the output of an up/down counter connected to an incremental
+ encoder. They are used for mouse/trackball axes, steering wheels
+ without limit stops, and other emulated inputs that have no range
+ limits.
+* DIP switch, configuration and adjuster fields allow the user to set
+ the value through MAME’s user interface.
+* Additional special field types are used to produce fixed or
+ programmatically generated values.
+
+A digital field appears to the user as a single assignable input, which
+accepts switch values.
+
+An analog field appears to the user as three assignable inputs: an
+**axis input**, which accepts axis values; and an **increment input**
+and a **decrement input** which accept switch values.
+
+Input manager
+~~~~~~~~~~~~~
+
+The input manager has several responsibilities:
+
+* Tracking the available input devices in the system.
+* Reading input values.
+* Converting between internal identifier values, configuration token
+ strings and display strings.
+
+In practice, emulated devices and systems rarely interact with the input
+manager directly. The most common reason to access the input manager is
+implementing special debug controls, which should be disabled in release
+builds. Plugins that respond to input need to call the input manager to
+read inputs.
+
+I/O port manager
+~~~~~~~~~~~~~~~~
+
+The I/O port manager’s primary responsibilities include:
+
+* Managing assignments of controls to I/O port fields and user interface
+ actions.
+* Reading input values via the input manager and updating I/O port field
+ values.
+
+Like the input manager, the I/O port manager is largely transparent to
+emulated devices and systems. You just need to set up your I/O ports
+and fields, and the I/O port manager handles the rest.
+
+
+.. _inputsystem-structures:
+
+Structures and data types
+-------------------------
+
+The following data types are used for dealing with input.
+
+Input code
+~~~~~~~~~~
+
+An input code specifies an input device item and how it should be
+interpreted. It is a tuple consisting of the following values: **device
+class**, **device number**, **item class**, **item modifier** and **item
+ID**:
+
+* The device class, device number and item ID together identify the
+ input device item to read.
+* The item class specifies the type of output value desired: switch,
+ absolute axis or relative axis. Axis values can be converted to
+ switch values by specifying an appropriate modifier.
+* The modifier specifies how a value should be interpreted. Valid
+ options depend on the type of input device item and the specified
+ item class.
+
+If the specified input item is a switch, it can only be read using the
+switch class, and no modifiers are supported. Attempting to read a
+switch as an absolute or relative axis always returns zero.
+
+If the specified input item is an absolute axis, it can be read as an
+absolute axis or as a switch:
+
+* Reading an absolute axis item as an absolute axis returns the current
+ state of the control, potentially transformed if a modifier is
+ specified. Supported modifiers are **reverse** to reverse the range
+ of the control, **positive** to map the positive range of the control
+ onto the output (zero corresponding to -65,536 and 65,536
+ corresponding to 65,536), and **negative** to map the negative range
+ of the control onto the output (zero corresponding to -65,536 and
+ -65,536 corresponding to 65,536).
+* Reading an absolute axis item as a switch returns zero or 1 depending
+ on whether the control is past a threshold in the direction specified
+ by the modifier. Use the **negative** modifier to return 1 when the
+ control is beyond the threshold in the negative direction (up or
+ left), or the **positive** modifier to return 1 when the control is
+ beyond the threshold in the positive direction (down or right). There
+ are two special pairs of modifiers, **left**/**right** and
+ **up**/**down** that are only applicable to the primary X/Y axes of
+ joystick devices. The user can specify a *joystick map* to control
+ how these modifiers interpret joystick movement.
+* Attempting to read an absolute axis item as a relative axis always
+ returns zero.
+
+If the specified input item is a relative axis, it can be read as a
+relative axis or as a switch:
+
+* Reading a relative axis item as a relative axis returns the change in
+ value since the last input update. The only supported modifier is
+ **reverse**, which negates the value, reversing the direction.
+* Reading a relative axis as a switch returns 1 if the control moved in
+ the direction specified by the modifier since the last input update.
+ Use the **negative**/**left**/**up** modifiers to return 1 when the
+ control has been moved in the negative direction (up or left), or the
+ **positive**/**right**/**down** modifiers to return 1 when the control
+ has moved in the positive direction (down or right).
+* Attempting to read a relative axis item as an absolute axis always
+ returns zero.
+
+There are also special input codes used for specifying how multiple
+controls are to be combined in an input sequence.
+
+The most common place you’ll encounter input codes in device and system
+driver code is when specifying initial assignments for I/O port fields
+that don’t have default assignments supplied by the core. The
+``PORT_CODE`` macro is used for this purpose.
+
+MAME provides macros and helper functions for producing commonly used
+input codes, including standard keyboard keys and
+mouse/joystick/lightgun axes and buttons.
+
+Input sequence
+~~~~~~~~~~~~~~
+
+An input sequence specifies a combination controls that can be assigned
+to an input. The name refers to the fact that it is implemented as a
+sequence container with input codes as elements. It is somewhat
+misleading, as input sequences are interpreted using instantaneous
+control values. Input sequences are interpreted differently for switch
+and axis input.
+
+Input sequences for switch input must only contain input codes with the
+item class set to switch along with the special **or** and **not** input
+codes. The input sequence is interpreted using sum-of-products logic.
+A **not** code causes the value returned by the immediately following
+code to be inverted. The conjunction of values returned by successive
+codes is evaluated until an **or** code is encountered. If the current
+value is 1 when an **or** code is encountered it is returned, otherwise
+evaluation continues.
+
+Input sequences for axis input can contain input codes with the item
+class set to switch, absolute axis or relative axis along with the
+special **or** and **not** codes. It’s helpful to think of the input
+sequence as containing one or more groups of input codes separated by
+**or** codes:
+
+* A **not** code causes the value returned by an immediately following
+ switch code to be inverted. It has no effect on absolute or relative
+ axis codes.
+* Within a group, the conjunction of the values returned by switch codes
+ is evaluated. If it is zero, the group is ignored.
+* Within a group, multiple axis values of the same type are summed.
+ Values returned by absolute axis codes are summed, and values returned
+ by relative axis codes are summed.
+* If any absolute axis code in a group returns a non-zero value, the sum
+ of relative axes in the group is ignored. Any non-zero absolute axis
+ value takes precedence over relative axis values.
+* The same logic is applied when combining group values: group values
+ produced from the same axis type are summed, and values produced from
+ absolute axes take precedence over values produced from relative axes.
+* After the group values are summed, if the value was produced from
+ absolute axes it is clamped to the range -65,536 to 65,536 (values
+ produced from relative axes are not clamped).
+
+Emulation code rarely needs to deal with input sequences directly, as
+they’re handled internally between the I/O port manager and input
+manager. The input manager also converts input sequences to and from
+the token strings stored in configuration files and produces text for
+displaying input sequences to users.
+
+Plugins with controls or hotkeys need to use input sequences to allow
+configuration. Utility classes are provided to allow input sequences to
+be entered by the user in a consistent way, and the input manager can be
+used for conversions to and from configuration and display strings. It
+is very rare to need to directly manipulate input sequences.
+
+
+.. _inputsystem-providermodules:
+
+Input provider modules
+----------------------
+
+Input provider modules are part of the OS-dependent layer (OSD), and are
+not directly exposed to emulation and user interface code. Input
+provider modules are responsible for detecting available host input
+devices, setting up input devices for the input manager, and providing
+callbacks to read the current state of input device items. Input
+provider modules may also provide additional default input assignments
+suitable for host input devices that are present.
+
+The user is given a choice of input modules to use. One input provider
+module is used for each of the four input device classes (keyboard,
+mouse, joystick and lightgun). The available modules depend on the host
+operating system and OSD implementation. Different modules may use
+different APIs, support different kinds of devices, or present devices
+in different ways.
+
+
+.. _inputsystem-playerpositions:
+
+Player positions
+----------------
+
+MAME uses a concept called *player positions* to help manage input
+assignments. The number of player positions supported depends on the
+I/O port field type:
+
+* Ten player positions are supported for common game inputs, including
+ joystick, pedal, paddle, dial, trackball, lightgun and mouse.
+* Four player positions are supported for mahjong and hanafuda inputs.
+* One player position is supported for gambling system inputs.
+* Other inputs do not use player positions. This includes coin slots,
+ arcade start buttons, tilt switches, service switches and
+ keyboard/keypad keys.
+
+The user can configure default input assignments per player position for
+supported I/O port field types which are saved in the file
+**default.cfg**. These assignments are used for all systems unless the
+device/system driver supplies its own default assignments, or the user
+configures system-specific input assignments.
+
+In order to facilitate development of reusable emulated devices with
+inputs, particularly slot devices, the I/O port manager automatically
+renumbers player positions when setting up the emulated system:
+
+* The I/O port manager starts at player position 1 and begins
+ iterating the emulated device tree in depth first order, starting from
+ the root device.
+* If a device has I/O port fields that support player positions, they
+ are renumbered to start from the I/O port manager’s current player
+ position.
+* Before advancing to the next device, the I/O port manager sets its
+ current player position to the last seen player position plus one.
+
+For a simple example, consider what happens when you run a Sega Mega
+Drive console with two game pads connected:
+
+* The I/O port manager starts at player position 1 at the root device.
+* The first device encountered with I/O port fields that support player
+ positions is the first game pad. The inputs are renumbered to start
+ at player position 1. This has no visible effect, as the I/O port
+ fields are initially numbered starting at player position 1.
+* Before moving to the next device, the I/O port manager sets its
+ current player position to 2 (the last player position seen plus one).
+* The next device encountered with I/O port fields that support player
+ positions is the second game pad. The inputs are renumbered to start
+ at player position 2. This avoids I/O port field type conflicts with
+ the first game pad.
+* Before moving to the next device, the I/O port manager sets its
+ current player position to 3 (the last player position seen plus one).
+* No more devices with I/O port fields that support player positions are
+ encountered.
+
+
+.. _inputsystem-updatingfields:
+
+Updating I/O port fields
+------------------------
+
+The I/O port manager updates I/O port fields once for each video frame
+produced by the first emulated screen in the system. How a field is
+updated depends on whether it is a digital or analog field.
+
+Updating digital fields
+~~~~~~~~~~~~~~~~~~~~~~~
+
+Updating digital I/O port fields is simple:
+
+* The I/O port manager reads the current value for the field’s assigned
+ input sequence (via the input manager).
+* If the value is zero, the field’s default value is set.
+* If the value is non-zero, the binary complement of the field’s default
+ value is set.
+
+Updating absolute analog fields
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Updating absolute analog I/O port fields is more complex due to the need
+to support a variety of control setups:
+
+* The I/O port manager reads the current value for the field’s assigned
+ axis input sequence (via the input manager).
+* If the current value changed since the last update and the input
+ device item that produced the current value was an absolute axis, the
+ field’s value is set to the current value scaled to the correct range,
+ and no further processing is performed.
+* If the current value is non-zero and the input device item that
+ produced the current value was a relative axis, the current value is
+ added to the field’s value, scaled by the field’s sensitivity setting.
+* The I/O port manager reads the current value for the field’s assigned
+ increment input sequence (via the input manager); if this value is
+ non-zero, the field’s increment/decrement speed setting value is added
+ to its value, scaled by its sensitivity setting.
+* The I/O port manager reads the current value for the field’s assigned
+ decrement input sequence (via the input manager); if this value is
+ non-zero, the field’s increment/decrement speed setting value is
+ subtracted from its value, scaled by its sensitivity setting.
+* If the current axis input, increment input and decrement input values
+ are all zero, but either or both of the increment input and decrement
+ input values were non-zero the last time the field’s value changed in
+ response to user input, the field’s auto-centring speed setting value
+ is added to or subtracted from its value to move it toward its default
+ value.
+
+Note that the sensitivity setting value for absolute analog fields
+affects the response to relative axis input device items and
+increment/decrement inputs, but it does not affect the response to
+absolute axis input device items or the auto-centring speed.
+
+Updating relative analog fields
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Relative analog I/O port fields also need special handling to cater for
+multiple control setups, but they are a little simpler than absolute
+analog fields:
+
+* The I/O port manager reads the current value for the field’s assigned
+ axis input sequence (via the input manager).
+* If the current value is non-zero and the input device item that
+ produced the current value was an absolute axis, the current value is
+ added to the field’s value, scaled by the field’s sensitivity setting,
+ and no further processing is performed.
+* If the current value is non-zero and the input device item that
+ produced the current value was a relative axis, the current value is
+ added to the field’s value, scaled by the field’s sensitivity setting.
+* The I/O port manager reads the current value for the field’s assigned
+ increment input sequence (via the input manager); if this value is
+ non-zero, the field’s increment/decrement speed setting value is added
+ to its value, scaled by its sensitivity setting.
+* The I/O port manager reads the current value for the field’s assigned
+ decrement input sequence (via the input manager); if this value is
+ non-zero, the field’s increment/decrement speed setting value is
+ subtracted from its value, scaled by its sensitivity setting.
+
+Note that the sensitivity setting value for relative analog fields
+affects the response to all user input.
diff --git a/docs/source/techspecs/layout_files.rst b/docs/source/techspecs/layout_files.rst
index 52b944ec246..a014756a32b 100644
--- a/docs/source/techspecs/layout_files.rst
+++ b/docs/source/techspecs/layout_files.rst
@@ -1,10 +1,12 @@
+.. _layfile:
+
MAME Layout Files
=================
.. contents:: :local:
-.. _layout-intro:
+.. _layfile-intro:
Introduction
------------
@@ -18,12 +20,12 @@ screens, built and linked into the MAME binary, or provided externally. MAME
layout files are an XML application, using the ``.lay`` filename extension.
-.. _layout-concepts:
+.. _layfile-concepts:
Core concepts
-------------
-.. _layout-concepts-numbers:
+.. _layfile-concepts-numbers:
Numbers
~~~~~~~
@@ -53,18 +55,18 @@ found, the number will be interpreted as an integer.
Numbers are parsed using the "C" locale for portability.
-.. _layout-concepts-coordinates:
+.. _layfile-concepts-coordinates:
Coordinates
~~~~~~~~~~~
Layout coordinates are internally represented as IEEE754 32-bit binary
-floating-point numbers (also known as "single precision"). Coordinates increase
+floating-point numbers (also known as “single precision”). Coordinates increase
in the rightward and downward directions. The origin (0,0) has no particular
significance, and you may freely use negative coordinates in layouts.
Coordinates are supplied as floating-point numbers.
-MAME assumes that view coordinates have the same aspect ratio as pixel on the
+MAME assumes that view coordinates have the same aspect ratio as pixels on the
output device (host screen or window). Assuming square pixels and no rotation,
this means equal distances in X and Y axes correspond to equal horizontal and
vertical distances in the rendered output.
@@ -73,29 +75,43 @@ Views, groups and elements all have their own internal coordinate systems. When
an element or group is referenced from a view or another group, its coordinates
are scaled as necessary to fit the specified bounds.
-Objects are positioned and sized using ``bounds`` elements. A bounds element
-may specify the position of the top left corner and the size using ``x``, ``y``,
-``width`` and ``height`` attributes, or it may specify the coordinates of the
-edges with the ``left``, ``top``, ``right`` and ``bottom`` attributes. These
-two ``bounds`` elements are equivalent::
+Objects are positioned and sized using ``bounds`` elements. The horizontal
+position and size may be specified in three ways: left edge and width using
+``x`` and ``width`` attributes, horizontal centre and width using ``xc`` and
+``width`` attributes, or left and right edges using ``left`` and ``right``
+attributes. Similarly, the vertical position and size may be specified in terms
+of the top edge and height using ``y`` and ``height`` attributes, vertical
+centre and height using ``yc`` and ``height`` attributes, or top and bottom
+edges using ``top`` and ``bottom`` attributes.
+
+These three ``bounds`` elements are equivalent:
+
+.. code-block:: XML
+
+ <bounds x="455" y="120" width="12" height="8" />
+ <bounds xc="461" yc="124" width="12" height="8" />
+ <bounds left="455" top="120" right="467" bottom="128" />
- <bounds x="455" y="120" width="11" height="7" />
- <bounds left="455" top="120" right="466" bottom="127" />
+It’s possible to use different schemes in the horizontal and vertical
+directions. For example, these equivalent ``bounds`` elements are also valid:
-Either the ``x`` or ``left`` attribute must be present to distinguish between
-the two schemes. The ``width`` and ``height`` or ``right`` and ``bottom``
-default to 1.0 if not supplied. It is an error if ``width`` or ``height`` are
-negative, if ``right`` is less than ``left``, or if ``bottom`` is less than
-``top``.
+.. code-block:: XML
+ <bounds x="455" top="120" width="12" bottom="128" />
+ <bounds left="455" yc="124" right="467" height="8" />
-.. _layout-concepts-colours:
+The ``width``/``height`` or ``right``/``bottom`` default to 1.0 if not supplied.
+It is an error if ``width`` or ``height`` are negative, if ``right`` is less
+than ``left``, or if ``bottom`` is less than ``top``.
+
+
+.. _layfile-concepts-colours:
Colours
~~~~~~~
Colours are specified in RGBA space. MAME is not aware of colour profiles and
-gamuts, so colours will typically be interpreted as sRGB with your system's
+gamuts, so colours will typically be interpreted as sRGB with your system’s
target gamma (usually 2.2). Channel values are specified as floating-point
numbers. Red, green and blue channel values range from 0.0 (off) to 1.0 (full
intensity). Alpha ranges from 0.0 (fully transparent) to 1.0 (opaque). Colour
@@ -103,7 +119,9 @@ channel values are not pre-multiplied by the alpha value.
Component and view item colour is specified using ``color`` elements.
Meaningful attributes are ``red``, ``green``, ``blue`` and ``alpha``. This
-example ``color`` element specifies all channel values::
+example ``color`` element specifies all channel values:
+
+.. code-block:: XML
<color red="0.85" green="0.4" blue="0.3" alpha="1.0" />
@@ -112,7 +130,7 @@ is an error if any channel value falls outside the range of 0.0 to 1.0
(inclusive).
-.. _layout-concepts-params:
+.. _layfile-concepts-params:
Parameters
~~~~~~~~~~
@@ -120,8 +138,10 @@ Parameters
Parameters are named variables that can be used in most attributes. To use
a parameter in an attribute, surround its name with tilde (~) characters. If a
parameter is not defined, no substitution occurs. Here is an examples showing
-two instances of parameter use -- the values of the ``digitno`` and ``x``
-parameters will be substituted for ``~digitno~`` and ``~x~``::
+two instances of parameter use – the values of the ``digitno`` and ``x``
+parameters will be substituted for ``~digitno~`` and ``~x~``:
+
+.. code-block:: XML
<element name="digit~digitno~" ref="digit">
<bounds x="~x~" y="80" width="25" height="40" />
@@ -137,7 +157,7 @@ scope level corresponds to the top-level ``mamelayout`` element. Each
Internally a parameter can hold a string, integer, or floating-point number, but
this is mostly transparent. Integers are stored as 64-bit signed
twos-complement values, and floating-point numbers are stored as IEEE754 64-bit
-binary floating-point numbers (also known as "double precision"). Integers are
+binary floating-point numbers (also known as “double precision”). Integers are
substituted in decimal notation, and floating point numbers are substituted in
default format, which may be decimal fixed-point or scientific notation
depending on the value). There is no way to override the default formatting of
@@ -156,16 +176,20 @@ Value parameters are assigned using a ``param`` element with ``name`` and
``view`` elements other ``group`` definition elements). A value parameter may
be reassigned at any point.
-Here's an example assigning the value "4" to the value parameter "firstdigit"::
+Here’s an example assigning the value “4” to the value parameter “firstdigit”:
+
+.. code-block:: XML
<param name="firstdigit" value="4" />
Generator parameters are assigned using a ``param`` element with ``name`` and
``start`` attributes, and ``increment``, ``lshift`` and/or ``rshift``
attributes. Generator parameters may only appear inside ``repeat`` elements
-(see :ref:`layout-parts-repeats` for details). A generator parameter must not
+(see :ref:`layfile-parts-repeats` for details). A generator parameter must not
be reassigned in the same scope (an identically named parameter may be defined
-in a child scope). Here are some example generator parameters::
+in a child scope). Here are some example generator parameters:
+
+.. code-block:: XML
<param name="nybble" start="3" increment="-1" />
<param name="switchpos" start="74" increment="156" />
@@ -176,28 +200,27 @@ in a child scope). Here are some example generator parameters::
* The ``mask`` parameter generates values 2048, 128, 8...
The ``increment`` attribute must be an integer or floating-point number to be
-added to the parameter's value. The ``lshift`` and ``rshift`` attributes must
-be non-negative integers specifying numbers of bits to shift the parameter's
+added to the parameter’s value. The ``lshift`` and ``rshift`` attributes must
+be non-negative integers specifying numbers of bits to shift the parameter’s
value to the left or right. The increment and shift are applied at the end of
-the repeating block before the next iteration starts. If both an increment and
-shift are supplied, the increment is applied before the shift.
+the repeating block before the next iteration starts. The parameter’s value
+will be interpreted as an integer or floating-point number before the increment
+and/or shift are applied. If both an increment and shift are supplied, the
+increment is applied before the shift.
If the ``increment`` attribute is present and is a floating-point number, the
-parameter's value will be interpreted as an integer or floating-point number and
-converted to a floating-point number before the increment is added. If the
-``increment`` attribute is present and is an integer, the parameter's value will
-be interpreted as an integer or floating number before the increment is added.
-The increment will be converted to a floating-point number before the addition
-if the parameter's value is a floating-point number.
+parameter’s value will be converted to a floating-point number if necessary
+before the increment is added. If the ``increment`` attribute is present and is
+an integer while the parameter’s value is a floating-point number, the increment
+will be converted to a floating-point number before the addition.
If the ``lshift`` and/or ``rshift`` attributes are present and not equal, the
-parameter's value will be interpreted as an integer or floating-point number,
-converted to an integer as necessary, and shifted accordingly. Shifting to the
-left is defined as shifting towards the most significant bit. If both
-``lshift`` and ``rshift`` are supplied, they are netted off before being
-applied. This means you cannot, for example, use equal ``lshift`` and
-``rshift`` attributes to clear bits at one end of a parameter's value after the
-first iteration.
+parameter’s value will be converted to an integer if necessary, and shifted
+accordingly. Shifting to the left is defined as shifting towards the most
+significant bit. If both ``lshift`` and ``rshift`` are supplied, they are
+netted off before being applied. This means you cannot, for example, use equal
+``lshift`` and ``rshift`` attributes to clear bits at one end of a parameter’s
+value after the first iteration.
It is an error if a ``param`` element has neither ``value`` nor ``start``
attributes, and it is an error if a ``param`` element has both a ``value``
@@ -209,7 +232,7 @@ innermost scope. It is not possible to define or reassign parameters in a
containing scope.
-.. _layout-concepts-predef-params:
+.. _layfile-concepts-predef-params:
Pre-defined parameters
~~~~~~~~~~~~~~~~~~~~~~
@@ -245,21 +268,21 @@ scr0physicalyaspect
fraction. Note that this is the vertical component *before* rotation is
applied. This parameter is an integer defined at layout (global) scope.
scr0nativexaspect
- The horizontal part of the pixel aspect ratio of the first screen's visible
+ The horizontal part of the pixel aspect ratio of the first screen’s visible
area (if present). The pixel aspect ratio is provided as a reduced improper
fraction. Note that this is the horizontal component *before* rotation is
applied. This parameter is an integer defined at layout (global) scope.
scr0nativeyaspect
- The vertical part of the pixel aspect ratio of the first screen's visible
+ The vertical part of the pixel aspect ratio of the first screen’s visible
area (if present). The pixel aspect ratio is provided as a reduced improper
fraction. Note that this is the vertical component *before* rotation is
applied. This parameter is an integer defined at layout (global) scope.
scr0width
- The width of the first screen's visible area (if present) in emulated
+ The width of the first screen’s visible area (if present) in emulated
pixels. Note that this is the width *before* rotation is applied. This
parameter is an integer defined at layout (global) scope.
scr0height
- The height of the first screen's visible area (if present) in emulated
+ The height of the first screen’s visible area (if present) in emulated
pixels. Note that this is the height *before* rotation is applied. This
parameter is an integer defined at layout (global) scope.
scr1physicalxaspect
@@ -269,18 +292,18 @@ scr1physicalyaspect
The vertical part of the physical aspect ratio of the second screen (if
present). This parameter is an integer defined at layout (global) scope.
scr1nativexaspect
- The horizontal part of the pixel aspect ratio of the second screen's visible
+ The horizontal part of the pixel aspect ratio of the second screen’s visible
area (if present). This parameter is an integer defined at layout (global)
scope.
scr1nativeyaspect
- The vertical part of the pixel aspect ratio of the second screen's visible
+ The vertical part of the pixel aspect ratio of the second screen’s visible
area (if present). This parameter is an integer defined at layout (global)
scope.
scr1width
- The width of the second screen's visible area (if present) in emulated
+ The width of the second screen’s visible area (if present) in emulated
pixels. This parameter is an integer defined at layout (global) scope.
scr1height
- The height of the second screen's visible area (if present) in emulated
+ The height of the second screen’s visible area (if present) in emulated
pixels. This parameter is an integer defined at layout (global) scope.
scr\ *N*\ physicalxaspect
The horizontal part of the physical aspect ratio of the (zero-based) *N*\ th
@@ -292,18 +315,18 @@ scr\ *N*\ physicalyaspect
(global) scope.
scr\ *N*\ nativexaspect
The horizontal part of the pixel aspect ratio of the (zero-based) *N*\ th
- screen's visible area (if present). This parameter is an integer defined at
+ screen’s visible area (if present). This parameter is an integer defined at
layout (global) scope.
scr\ *N*\ nativeyaspect
The vertical part of the pixel aspect ratio of the (zero-based) *N*\ th
- screen's visible area (if present). This parameter is an integer defined at
+ screen’s visible area (if present). This parameter is an integer defined at
layout (global) scope.
scr\ *N*\ width
- The width of the (zero-based) *N*\ th screen's visible area (if present) in
+ The width of the (zero-based) *N*\ th screen’s visible area (if present) in
emulated pixels. This parameter is an integer defined at layout (global)
scope.
scr\ *N*\ height
- The height of the (zero-based) *N*\ th screen's visible area (if present) in
+ The height of the (zero-based) *N*\ th screen’s visible area (if present) in
emulated pixels. This parameter is an integer defined at layout (global)
scope.
viewname
@@ -319,7 +342,7 @@ end of configuration. Values are not updated and layouts are not recomputed if
the system reconfigures the screen while running.
-.. _layout-parts:
+.. _layfile-parts:
Parts of a layout
-----------------
@@ -332,7 +355,9 @@ are supported.
The top-level element of a MAME layout file must be a ``mamelayout`` element
with a ``version`` attribute. The ``version`` attribute must be an integer.
Currently MAME only supports version 2, and will not load any other version.
-This is an example opening tag for a top-level ``mamelayout`` element::
+This is an example opening tag for a top-level ``mamelayout`` element:
+
+.. code-block:: XML
<mamelayout version="2">
@@ -345,47 +370,48 @@ and groups that appear after them.
The following elements are allowed inside the top-level ``mamelayout`` element:
param
- Defines or reassigns a value parameter. See :ref:`layout-concepts-params`
+ Defines or reassigns a value parameter. See :ref:`layfile-concepts-params`
for details.
element
- Defines an element -- one of the basic objects that can be arranged in a
- view. See :ref:`layout-parts-elements` for details.
+ Defines an element – one of the basic objects that can be arranged in a
+ view. See :ref:`layfile-parts-elements` for details.
group
Defines a reusable group of elements/screens that may be referenced from
- views or other groups. See :ref:`layout-parts-groups` for details.
+ views or other groups. See :ref:`layfile-parts-groups` for details.
repeat
- A repeating group of elements -- may contain ``param``, ``element``,
- ``group``, and ``repeat`` elements. See :ref:`layout-parts-repeats` for
+ A repeating group of elements – may contain ``param``, ``element``,
+ ``group``, and ``repeat`` elements. See :ref:`layfile-parts-repeats` for
details.
view
An arrangement of elements and/or screens that can be displayed on an output
- device (a host screen/window). See :ref:`layout-parts-views` for details.
+ device (a host screen/window). See :ref:`layfile-parts-views` for details.
script
- Allows lua script to be supplied for enhanced interactive layouts.
+ Allows Lua script to be supplied for enhanced interactive layouts. See
+ :ref:`layscript` for details.
-.. _layout-parts-elements:
+.. _layfile-parts-elements:
Elements
~~~~~~~~
Elements are one of the basic visual objects that may be arranged, along with
-screens, to make up a view. Elements may be built up one or more *components*,
-but an element is treated as as single surface when building the scene graph
+screens, to make up a view. Elements may be built up of one or more *components*,
+but an element is treated as a single surface when building the scene graph
and rendering. An element may be used in multiple views, and may be used
multiple times within a view.
-An element's appearance depends on its *state*. The state is an integer which
-usually comes from an I/O port field or an emulated output (see the discussion
-of :ref:`layout-parts-views` for information on connecting an element to an I/O
-port or output). Any component of an element may be restricted to only drawing
-when the element's state is a particular value. Some components (e.g.
-multi-segment displays and reels) use the state directly to determine their
+An element’s appearance depends on its *state*. The state is an integer which
+usually comes from an I/O port field or an emulated output (see
+:ref:`layfile-interact-elemstate` for information on connecting an element to an
+emulated I/O port or output). Any component of an element may be restricted to
+only drawing when the element’s state is a particular value. Some components
+(e.g. multi-segment displays) use the state directly to determine their
appearance.
Each element has its own internal coordinate system. The bounds of the
-element's coordinate system are computed as the union of the bounds of the
-individual components it's composed of.
+element’s coordinate system are computed as the union of the bounds of the
+individual components it’s composed of.
Every element must have a ``name`` attribute specifying its name. Elements are
referred to by name when instantiated in groups or views. It is an error for a
@@ -395,22 +421,63 @@ attribute, to be used if not connected to an emulated output or I/O port. If
present, the ``defstate`` attribute must be a non-negative integer.
Child elements of the ``element`` element instantiate components, which are
-drawn in reading order from first to last (components draw on top of components
-that come before them). All components support a few common features:
-
-* Each component may have a ``state`` attribute. If present, the component will
- only be drawn when the element's state matches its value (if absent, the
- component will always be drawn). If present, the ``state`` attribute must be
- a non-negative integer.
+drawn into the element texture in reading order from first to last using alpha
+blending (components draw over and may obscure components that come before
+them). All components support a few common features:
+
+* Components may be conditionally drawn depending on the element’s state by
+ supplying ``state`` and/or ``statemask`` attributes. If present, these
+ attributes must be non-negative integers. If only the ``state`` attribute is
+ present, the component will only be drawn when the element’s state matches its
+ value. If only the ``statemask`` attribute is present, the component will
+ only be drawn when all the bits that are set in its value are set in the
+ element’s state.
+
+ If both the ``state`` and ``statemask`` attributes are present, the component
+ will only be drawn when the bits in the element’s state corresponding to the
+ bits that are set in the ``statemask`` attribute’s value match the value of the
+ corresponding bits in the ``state`` attribute’s value.
+
+ (The component will always be drawn if neither ``state`` nor ``statemask``
+ attributes are present, or if the ``statemask`` attribute’s value is zero.)
* Each component may have a ``bounds`` child element specifying its position and
- size (see :ref:`layout-concepts-coordinates`). If no such element is present,
- the bounds default to a unit square (width and height of 1.0) with the top
- left corner at (0,0).
+ size (see :ref:`layfile-concepts-coordinates`). If no such element is
+ present, the bounds default to a unit square (width and height of 1.0) with
+ the top left corner at (0,0).
+
+ A component’s position and/or size may be animated according to the element’s
+ state by supplying multiple ``bounds`` child elements with ``state``
+ attributes. The ``state`` attribute of each ``bounds`` child element must be
+ a non-negative integer. The ``state`` attributes must not be equal for any
+ two ``bounds`` elements within a component.
+
+ If the element’s state is lower than the ``state`` value of any ``bounds``
+ child element, the position/size specified by the ``bounds`` child element
+ with the lowest ``state`` value will be used. If the element’s state is
+ higher than the ``state`` value of any ``bounds`` child element, the
+ position/size specified by the ``bounds`` child element with the highest
+ ``state`` value will be used. If the element’s state is between the ``state``
+ values of two ``bounds`` child elements, the position/size will be
+ interpolated linearly.
* Each component may have a ``color`` child element specifying an RGBA colour
- (see :ref:`layout-concepts-colours` for details). This can be used to control
- the colour of geometric, algorithmically drawn, or textual components. It is
- ignored for ``image`` components. If no such element is present, the colour
- defaults to opaque white.
+ (see :ref:`layfile-concepts-colours` for details). This can be used to
+ control the colour of geometric, algorithmically drawn, or textual components.
+ For ``image`` components, the colour of the image pixels is multiplied by the
+ specified colour. If no such element is present, the colour defaults to
+ opaque white.
+
+ A component’s color may be animated according to the element’s state by
+ supplying multiple ``color`` child elements with ``state`` attributes. The
+ ``state`` attributes must not be equal for any two ``color`` elements within a
+ component.
+
+ If the element’s state is lower than the ``state`` value of any ``color``
+ child element, the colour specified by the ``color`` child element with the
+ lowest ``state`` value will be used. If the element’s state is higher than
+ the ``state`` value of any ``color`` child element, the colour specified by
+ the ``color`` child element with the highest ``state`` value will be used. If
+ the element’s state is between the ``state`` values of two ``color`` child
+ elements, the RGBA colour components will be interpolated linearly.
The following components are supported:
@@ -419,18 +486,30 @@ rect
disk
Draws a uniform colour ellipse fitted to its bounds.
image
- Draws an image loaded from a PNG or JPEG file. The name of the file to load
- (including the file name extension) is supplied with the required ``file``
- attribute. Additionally, an optional ``alphafile`` attribute may be used to
- specify the name of a PNG file (including the file name extension) to load
- into the alpha channel of the image. The image file(s) should be placed in
- the same directory/archive as the layout file. If the ``alphafile``
- attribute refers refers to a file, it must have the same dimensions as the
- file referred to by the ``file`` attribute, and must have a bit depth no
- greater than eight bits per channel per pixel. The intensity from this
- image (brightness) is copied to the alpha channel, with full intensity (white
- in a greyscale image) corresponding to fully opaque, and black corresponding
- to fully transparent.
+ Draws an image loaded from a PNG, JPEG, Windows DIB (BMP) or SVG file. The
+ name of the file to load (including the file name extension) is supplied
+ using the ``file`` attribute. Additionally, an optional ``alphafile``
+ attribute may be used to specify the name of a PNG file (including the file
+ name extension) to load into the alpha channel of the image.
+
+ Alternatively, image data may be supplied in the layout file itself using a
+ ``data`` child element. This can be useful for supplying simple,
+ human-readable SVG graphics. A ``file`` attribute or ``data`` child element
+ must be supplied; it is an error if neither or both are supplied.
+
+ If the ``alphafile`` attribute refers to a file, it must have the same
+ dimensions (in pixels) as the file referred to by the ``file`` attribute,
+ and must have a bit depth no greater than eight bits per channel per pixel.
+ The intensity from this image (brightness) is copied to the alpha channel,
+ with full intensity (white in a greyscale image) corresponding to fully
+ opaque, and black corresponding to fully transparent. The ``alphafile``
+ attribute will be ignored if the ``file`` attribute refers to an SVG image
+ or the ``data`` child element contains SVG data; it is only used in
+ conjunction with bitmap images.
+
+ The image file(s) should be placed in the same directory/archive as the
+ layout file. Image file formats are detected by examining the content of
+ the files, file name extensions are ignored.
text
Draws text in using the UI font in the specified colour. The text to draw
must be supplied using a ``string`` attribute. An ``align`` attribute may
@@ -438,39 +517,16 @@ text
be an integer, where 0 (zero) means centred, 1 (one) means left-aligned, and
2 (two) means right-aligned. If the ``align`` attribute is absent, the text
will be centred.
-dotmatrix
- Draws an eight-pixel horizontal segment of a dot matrix display, using
- circular pixels in the specified colour. The bits of the element's state
- determine which pixels are lit, with the least significant bit corresponding
- to the leftmost pixel. Unlit pixels are drawn at low intensity (0x20/0xff).
-dotmatrix5dot
- Draws a five-pixel horizontal segment of a dot matrix display, using
- circular pixels in the specified colour. The bits of the element's state
- determine which pixels are lit, with the least significant bit corresponding
- to the leftmost pixel. Unlit pixels are drawn at low intensity (0x20/0xff).
-dotmatrixdot
- Draws a single element of a dot matrix display as a circular pixels in the
- specified colour. The least significant bit of the element's state
- determines whether the pixel is lit. An unlit pixel is drawn at low
- intensity (0x20/0xff).
led7seg
Draws a standard seven-segment (plus decimal point) digital LED/fluorescent
- display in the specified colour. The low eight bits of the element's state
+ display in the specified colour. The low eight bits of the element’s state
control which segments are lit. Starting from the least significant bit,
the bits correspond to the top segment, the upper right-hand segment,
continuing clockwise to the upper left segment, the middle bar, and the
decimal point. Unlit segments are drawn at low intensity (0x20/0xff).
-led8seg_gts1
- Draws an eight-segment digital fluorescent display of the type used in
- Gottlieb System 1 pinball machines (actually a Futaba part). Compared to
- standard seven-segment displays, these displays have no decimal point, the
- horizontal middle bar is broken in the centre, and there is a broken
- vertical middle bar controlled by the bit that would control the decimal
- point in a standard seven-segment display. Unlit segments are drawn at low
- intensity (0x20/0xff).
led14seg
Draws a standard fourteen-segment alphanumeric LED/fluorescent display in
- the specified colour. The low fourteen bits of the element's state control
+ the specified colour. The low fourteen bits of the element’s state control
which segments are lit. Starting from the least significant bit, the bits
correspond to the top segment, the upper right-hand segment, continuing
clockwise to the upper left segment, the left-hand and right-hand halves of
@@ -480,13 +536,13 @@ led14seg
led14segsc
Draws a standard fourteen-segment alphanumeric LED/fluorescent display with
decimal point/comma in the specified colour. The low sixteen bits of the
- element's state control which segments are lit. The low fourteen bits
+ element’s state control which segments are lit. The low fourteen bits
correspond to the same segments as in the ``led14seg`` component. Two
additional bits correspond to the decimal point and comma tail. Unlit
segments are drawn at low intensity (0x20/0xff).
led16seg
Draws a standard sixteen-segment alphanumeric LED/fluorescent display in the
- specified colour. The low sixteen bits of the element's state control which
+ specified colour. The low sixteen bits of the element’s state control which
segments are lit. Starting from the least significant bit, the bits
correspond to the left-hand half of the top bar, the right-hand half of the
top bar, continuing clockwise to the upper left segment, the left-hand and
@@ -496,12 +552,12 @@ led16seg
led16segsc
Draws a standard sixteen-segment alphanumeric LED/fluorescent display with
decimal point/comma in the specified colour. The low eighteen bits of the
- element's state control which segments are lit. The low sixteen bits
+ element’s state control which segments are lit. The low sixteen bits
correspond to the same segments as in the ``led16seg`` component. Two
additional bits correspond to the decimal point and comma tail. Unlit
segments are drawn at low intensity (0x20/0xff).
simplecounter
- Displays the numeric value of the element's state using the system font in
+ Displays the numeric value of the element’s state using the system font in
the specified colour. The value is formatted in decimal notation. A
``digits`` attribute may be supplied to specify the minimum number of digits
to display. If present, the ``digits`` attribute must be a positive
@@ -512,27 +568,28 @@ simplecounter
to set text alignment. If present, the ``align`` attribute must be an
integer, where 0 (zero) means centred, 1 (one) means left-aligned, and 2
(two) means right-aligned; if absent, the text will be centred.
-reel
- Used for drawing slot machine reels. Supported attributes include
- ``symbollist``, ``stateoffset``, ``numsymbolsvisible``, ``reelreversed``,
- and ``beltreel``.
-An example element that draws a static left-aligned text string::
+An example element that draws a static left-aligned text string:
+
+.. code-block:: XML
<element name="label_reset_cpu">
<text string="CPU" align="1"><color red="1.0" green="1.0" blue="1.0" /></text>
</element>
-
An example element that displays a circular LED where the intensity depends on
-the state of an active-high output::
+the state of an active-high output:
+
+.. code-block:: XML
<element name="led" defstate="0">
- <rect state="0"><color red="0.43" green="0.35" blue="0.39" /></rect>
- <rect state="1"><color red="1.0" green="0.18" blue="0.20" /></rect>
+ <disk state="0"><color red="0.43" green="0.35" blue="0.39" /></disk>
+ <disk state="1"><color red="1.0" green="0.18" blue="0.20" /></disk>
</element>
-An example element for a button that gives visual feedback when clicked::
+An example element for a button that gives visual feedback when clicked:
+
+.. code-block:: XML
<element name="btn_rst">
<rect state="0"><bounds x="0.0" y="0.0" width="1.0" height="1.0" /><color red="0.2" green="0.2" blue="0.2" /></rect>
@@ -543,8 +600,59 @@ An example element for a button that gives visual feedback when clicked::
<text string="RESET"><bounds x="0.1" y="0.4" width="0.8" height="0.2" /><color red="1.0" green="1.0" blue="1.0" /></text>
</element>
+An example of an element that draws a seven-segment LED display using external
+segment images:
+
+.. code-block:: XML
+
+ <element name="digit_a" defstate="0">
+ <image file="a_off.png" />
+ <image file="a_a.png" statemask="0x01" />
+ <image file="a_b.png" statemask="0x02" />
+ <image file="a_c.png" statemask="0x04" />
+ <image file="a_d.png" statemask="0x08" />
+ <image file="a_e.png" statemask="0x10" />
+ <image file="a_f.png" statemask="0x20" />
+ <image file="a_g.png" statemask="0x40" />
+ <image file="a_dp.png" statemask="0x80" />
+ </element>
+
+An example of a bar graph that grows vertically and changes colour from green,
+through yellow, to red as the state increases:
+
+.. code-block:: XML
+
+ <element name="pedal">
+ <rect>
+ <bounds state="0x000" left="0.0" top="0.9" right="1.0" bottom="1.0" />
+ <bounds state="0x610" left="0.0" top="0.0" right="1.0" bottom="1.0" />
+ <color state="0x000" red="0.0" green="1.0" blue="0.0" />
+ <color state="0x184" red="1.0" green="1.0" blue="0.0" />
+ <color state="0x610" red="1.0" green="0.0" blue="0.0" />
+ </rect>
+ </element>
+
+An example of a bar graph that grows horizontally to the left or right and
+changes colour from green, through yellow, to red as the state changes from the
+neutral position:
+
+.. code-block:: XML
+
+ <element name="wheel">
+ <rect>
+ <bounds state="0x800" left="0.475" top="0.0" right="0.525" bottom="1.0" />
+ <bounds state="0x280" left="0.0" top="0.0" right="0.525" bottom="1.0" />
+ <bounds state="0xd80" left="0.475" top="0.0" right="1.0" bottom="1.0" />
+ <color state="0x800" red="0.0" green="1.0" blue="0.0" />
+ <color state="0x3e0" red="1.0" green="1.0" blue="0.0" />
+ <color state="0x280" red="1.0" green="0.0" blue="0.0" />
+ <color state="0xc20" red="1.0" green="1.0" blue="0.0" />
+ <color state="0xd80" red="1.0" green="0.0" blue="0.0" />
+ </rect>
+ </element>
+
-.. _layout-parts-views:
+.. _layfile-parts-views:
Views
~~~~~
@@ -558,18 +666,20 @@ load views from the layout file. This is particularly useful for systems where
a screen is optional, for example computer systems with front panel controls and
an optional serial terminal.
-Views are identified by name in MAME's user interface and in command-line
+Views are identified by name in MAME’s user interface and in command-line
options. For layouts files associated with devices other than the root driver
-device, view names are prefixed with the device's tag (with the initial colon
-omitted) -- for example a view called "Keyboard LEDs" loaded for the device
-``:tty:ie15`` will be called "tty:ie15 Keyboard LEDs" in MAME's user interface.
+device, view names are prefixed with the device’s tag (with the initial colon
+omitted) – for example a view called “Keyboard LEDs” loaded for the device
+``:tty:ie15`` will be called “tty:ie15 Keyboard LEDs” in MAME’s user interface.
Views are listed in the order they are loaded. Within a layout file, views are
loaded in the order they appear, from top to bottom.
Views are created with ``view`` elements inside the top-level ``mamelayout``
element. Each ``view`` element must have a ``name`` attribute, supplying its
human-readable name for use in the user interface and command-line options.
-This is an example of a valid opening tag for a ``view`` element::
+This is an example of a valid opening tag for a ``view`` element:
+
+.. code-block:: XML
<view name="Control panel">
@@ -580,27 +690,36 @@ element. This means a view can reference elements and groups that appear after
it in the file, and parameters from the enclosing scope will have their final
values from the end of the ``mamelayout`` element.
+A ``view`` element may have a ``showpointers`` attribute to set whether mouse
+and pen pointers should be shown for the view. If present, the value must be
+either ``yes`` or ``no``. If the ``showpointers`` attribute is not present, pen
+and mouse pointers are shown for views that contain items bound to I/O ports.
+
The following child elements are allowed inside a ``view`` element:
bounds
- Sets the origin and size of the view's internal coordinate system if
- present. See :ref:`layout-concepts-coordinates` for details. If absent,
+ Sets the origin and size of the view’s internal coordinate system if
+ present. See :ref:`layfile-concepts-coordinates` for details. If absent,
the bounds of the view are computed as the union of the bounds of all
screens and elements within the view. It only makes sense to have one
``bounds`` as a direct child of a view element. Any content outside the
- view's bounds is cropped, and the view is scaled proportionally to fit the
+ view’s bounds is cropped, and the view is scaled proportionally to fit the
output window or screen.
param
- Defines or reassigns a value parameter in the view's scope. See
- :ref:`layout-concepts-params` for details.
+ Defines or reassigns a value parameter in the view’s scope. See
+ :ref:`layfile-concepts-params` for details.
element
- Adds an element to the view (see :ref:`layout-parts-elements`). The name of
- the element to add is specified using the required ``ref`` attribute. It is
- an error if no element with this name is defined in the layout file. May
- optionally be connected to an emulated I/O port using ``inputtag`` and
+ Adds an element to the view (see :ref:`layfile-parts-elements`). The name
+ of the element to add is specified using the required ``ref`` attribute. It
+ is an error if no element with this name is defined in the layout file.
+ Within a view, elements are drawn in the order they appear in the layout
+ file, from front to back. See below for more details.
+
+ May optionally be connected to an emulated I/O port using ``inputtag`` and
``inputmask`` attributes, and/or an emulated output using a ``name``
- attribute. Within a layer, elements are drawn in the order they appear in
- the layout file, from front to back. See below for more details.
+ attribute. See :ref:`layfile-interact-clickable` for details. See
+ :ref:`layfile-interact-elemstate` for details on supplying a state value to
+ the instantiated element.
screen
Adds an emulated screen image to the view. The screen must be identified
using either an ``index`` attribute or a ``tag`` attribute (it is an error
@@ -610,8 +729,17 @@ screen
zero (0). If present, the ``tag`` attribute must be the tag path to the
screen relative to the device that causes the layout to be loaded. Screens
are drawn in the order they appear in the layout file, from front to back.
+
+ May optionally be connected to an emulated I/O port using ``inputtag`` and
+ ``inputmask`` attributes, and/or an emulated output using a ``name``
+ attribute. See :ref:`layfile-interact-clickable` for details.
+collection
+ Adds screens and/or items in a collection that can be shown or hidden by the
+ user (see :ref:`layfile-parts-collections`). The name of the collection is
+ specified using the required ``name`` attribute. There is a limit of 32
+ collections per view.
group
- Adds the content of the group to the view (see :ref:`layout-parts-groups`).
+ Adds the content of the group to the view (see :ref:`layfile-parts-groups`).
The name of the group to add is specified using the required ``ref``
attribute. It is an error if no group with this name is defined in the
layout file. See below for more details on positioning.
@@ -620,9 +748,15 @@ repeat
attribute. The ``count`` attribute must be a positive integer. A
``repeat`` element in a view may contain ``element``, ``screen``, ``group``,
and further ``repeat`` elements, which function the same way they do when
- placed in a view directly. See :ref:`layout-parts-repeats` for discussion
+ placed in a view directly. See :ref:`layfile-parts-repeats` for discussion
on using ``repeat`` elements.
+Screens (``screen`` elements) and layout elements (``element`` elements) may
+have an ``id`` attribute. If present, the ``id`` attribute must not be empty,
+and must be unique within a view, including screens and elements instantiated
+via reusable groups and repeating blocks. Screens and layout elements with
+``id`` attributes can be looked up by Lua scripts (see :ref:`layscript`).
+
Screens (``screen`` elements), layout elements (``element`` elements) and groups
(``group`` elements) may have their orientation altered using an ``orientation``
child element. For screens, the orientation modifiers are applied in addition
@@ -631,7 +765,7 @@ The ``orientation`` element supports the following attributes, all of which are
optional:
rotate
- If present, applies clockwise rotation in ninety degree implements. Must be
+ If present, applies clockwise rotation in ninety degree increments. Must be
an integer equal to 0, 90, 180 or 270.
swapxy
Allows the screen, element or group to be mirrored along a line at
@@ -656,13 +790,15 @@ layout elements is alpha blending.
Screens (``screen`` elements), layout elements (``element`` elements) and groups
(``group`` elements) may be positioned and sized using a ``bounds`` child
-element (see :ref:`layout-concepts-coordinates` for details). In the absence of
-a ``bounds`` child element, screens' and layout elements' bounds default to a
+element (see :ref:`layfile-concepts-coordinates` for details). In the absence
+of a ``bounds`` child element, screens’ and layout elements’ bounds default to a
unit square (origin at 0,0 and height and width both equal to 1). In the
absence of a ``bounds`` child element, groups are expanded with no
translation/scaling (note that groups may position screens/elements outside
their bounds). This example shows a view instantiating and positioning a
-screen, an individual layout element, and two element groups::
+screen, an individual layout element, and two element groups:
+
+.. code-block:: XML
<view name="LED Displays, Terminal and Keypad">
<screen index="0"><bounds x="0" y="132" width="320" height="240" /></screen>
@@ -673,57 +809,101 @@ screen, an individual layout element, and two element groups::
Screens (``screen`` elements), layout elements (``element`` elements) and groups
(``group`` elements) may have a ``color`` child element (see
-:ref:`layout-concepts-colours`) specifying a modifier colour. The component
+:ref:`layfile-concepts-colours`) specifying a modifier colour. The component
colours of the screen or layout element(s) are multiplied by this colour.
-If an ``element`` element has ``inputtag`` and ``inputmask`` attributes,
-clicking it is equivalent to pressing a key/button mapped to the corresponding
-input(s). The ``inputtag`` specifies the tag path of an I/O port relative to
-the device that caused the layout file to be loaded. The ``inputmask``
-attribute must be an integer specifying the bits of the I/O port that the
-element should activate. This sample shows instantiation of clickable buttons::
-
- <element ref="btn_3" inputtag="X2" inputmask="0x10">
- <bounds x="2.30" y="4.325" width="1.0" height="1.0" />
- </element>
- <element ref="btn_0" inputtag="X0" inputmask="0x20">
- <bounds x="0.725" y="5.375" width="1.0" height="1.0" />
- </element>
- <element ref="btn_rst" inputtag="RESET" inputmask="0x01">
- <bounds x="1.775" y="5.375" width="1.0" height="1.0" />
- </element>
-
-If an ``element`` element has a ``name`` attribute, it will take its state from
-the value of the correspondingly named emulated output. Note that output names
-are global, which can become an issue when a machine uses multiple instances of
-the same type of device. See :ref:`layout-parts-elements` for details on how an
-element's state affects its appearance. This example shows how digital displays
-may be connected to emulated outputs::
+Screens (``screen`` elements) and layout elements (``element`` elements) may
+have their colour and position/size animated by supplying multiple ``color``
+and/or ``bounds`` child elements with ``state`` attributes. See
+:ref:`layfile-interact-itemanim` for details.
+
+Layout elements (``element`` elements) may be configured to show only part of
+the element’s width or height using ``xscroll`` and/or ``yscroll`` child
+elements. This can be used for devices like slot machine reels. The
+``xscroll`` and ``yscroll`` elements support the same attributes:
+
+size
+ The size of the horizontal or vertical scroll window, as a proportion of the
+ element’s width or height, respectively. Must be in the range 0.01 to 1.0,
+ inclusive, if present (1% of the width/height to the full width/height). By
+ default, the entire width and height of the element is shown.
+wrap
+ Whether the element should wrap horizontally or vertically. Must be either
+ ``yes`` or ``no`` if present. By default, items do not wrap horizontally or
+ vertically.
+inputtag
+ If present, the horizontal or vertical scroll position will be taken from
+ the value of the corresponding I/O port. Specifies the tag path of an I/O
+ port relative to the device that caused the layout file to be loaded. The
+ raw value from the input port is used, active-low switch values are not
+ normalised.
+name
+ If present, the horizontal or vertical scroll position will be taken from
+ the correspondingly named output.
+mask
+ If present, the horizontal or vertical scroll position will be masked with
+ the value and shifted to the right to remove trailing zeroes (for example a
+ mask of 0x05 will result in no shift, while a mask of 0x68 will result in
+ the value being shifted three bits to the right). Note that this applies to
+ output values (specified with the ``name`` attribute) as well as input port
+ values (specified with the ``inputtag`` attribute). Must be an integer
+ value if present. If not present, it is equivalent to all 32 bits being
+ set.
+min
+ Minimum horizontal or vertical scroll position value. When the horizontal
+ or vertical scroll position has this value, the left or top edge or the
+ scroll window will be aligned with the left or top edge of the element.
+ Must be an integer value if present. Defaults to zero.
+max
+ Maximum horizontal or vertical scroll position value. Must be an integer
+ value if present. Defaults to the ``mask`` value shifted to the right to
+ remove trailing zeroes.
+
+
+.. _layfile-parts-collections:
+
+Collections
+~~~~~~~~~~~
- <element name="digit6" ref="digit"><bounds x="16" y="16" width="48" height="80" /></element>
- <element name="digit5" ref="digit"><bounds x="64" y="16" width="48" height="80" /></element>
- <element name="digit4" ref="digit"><bounds x="112" y="16" width="48" height="80" /></element>
- <element name="digit3" ref="digit"><bounds x="160" y="16" width="48" height="80" /></element>
- <element name="digit2" ref="digit"><bounds x="208" y="16" width="48" height="80" /></element>
- <element name="digit1" ref="digit"><bounds x="256" y="16" width="48" height="80" /></element>
+Collections of screens and/or layout elements can be shown or hidden by the user
+as desired. For example, a single view could include both displays and a
+clickable keypad, and allow the user to hide the keypad leaving only the
+displays visible. Collections are created using ``collection`` elements inside
+``view``, ``group`` and other ``collection`` elements.
+
+A collection element must have a ``name`` attribute providing the display name
+for the collection. Collection names must be unique within a view. The initial
+visibility of a collection may be specified by providing a ``visible``
+attribute. Set the ``visible`` attribute to ``yes`` if the collection should be
+initially visible, or ``no`` if it should be initially hidden. Collections are
+initially visible by default.
+
+Here is an example demonstrating the use of collections to allow parts of a view
+to be hidden by the user:
+
+.. code-block:: XML
+
+ <view name="LED Displays, CRT and Keypad">
+ <collection name="LED Displays">
+ <group ref="displays"><bounds x="240" y="0" width="320" height="47" /></group>
+ </collection>
+ <collection name="Keypad">
+ <group ref="keypad"><bounds x="650" y="57" width="148" height="140" /></group>
+ </collection>
+ <screen tag="screen"><bounds x="0" y="57" width="640" height="480" /></screen>
+ </view>
-If an element instantiating a layout element has ``inputtag`` and ``inputmask``
-attributes but lacks a ``name`` attribute, it will take its state from the value
-of the corresponding I/O port, masked with the ``inputmask`` value and XORed
-with the I/O port default field value. The latter is useful for inputs that are
-active-low. If the result is non-zero, the state is 1, otherwise it's 0. This
-is often used to allow clickable buttons and toggle switches to provide visible
-feedback. By using ``inputraw="1"``, it's possible to obtain the raw data from
-the I/O port, masked with the ``inputmask`` value and shifted to the right to
-remove trailing zeroes (for example a mask of 0x05 will result in no shift, while
-a mask of 0xb0 will result in the value being shifted four bits to the right).
-When handling mouse input, MAME treats all layout elements as being rectangular,
-and only activates the frontmost element whose area includes the location of the
-mouse pointer.
+A collection creates a nested parameter scope. Any ``param`` elements inside
+the collection element set parameters in the local scope for the collection.
+See :ref:`layfile-concepts-params` for more detail on parameters. (Note that
+the collection’s name and default visibility are not part of its content, and
+any parameter references in the ``name`` and ``visible`` attributes themselves
+will be substituted using parameter values from the collection’s parent’s
+scope.)
-.. _layout-parts-groups:
+.. _layfile-parts-groups:
Reusable groups
~~~~~~~~~~~~~~~
@@ -740,20 +920,24 @@ identifier. It is an error if a layout file contains multiple group definitions
with identical ``name`` attributes. The value of the ``name`` attribute is used
when instantiating the group from a view or another group. This is an example
opening tag for a group definition element inside the top-level ``mamelayout``
-element::
+element:
+
+.. code-block:: XML
<group name="panel">
This group may then be instantiated in a view or another group element using a
group reference element, optionally supplying destination bounds, orientation,
and/or modifier colour. The ``ref`` attribute identifies the group to
-instantiate -- in this example, destination bounds are supplied::
+instantiate – in this example, destination bounds are supplied:
+
+.. code-block:: XML
<group ref="panel"><bounds x="87" y="58" width="23" height="23.5" /></group>
Group definition elements allow all the same child elements as views.
Positioning and orienting screens, layout elements and nested groups works the
-same way as for views. See :ref:`layout-parts-views` for details. A group may
+same way as for views. See :ref:`layfile-parts-views` for details. A group may
instantiate other groups, but recursive loops are not permitted. It is an error
if a group directly or indirectly instantiates itself.
@@ -761,12 +945,14 @@ Groups have their own internal coordinate systems. If a group definition
element has no ``bounds`` element as a direct child, its bounds are computed as
the union of the bounds of all the screens, layout elements and/or nested groups
it instantiates. A ``bounds`` child element may be used to explicitly specify
-group bounds (see :ref:`layout-concepts-coordinates` for details). Note that
-groups' bounds are only used for the purpose of calculating the coordinate
+group bounds (see :ref:`layfile-concepts-coordinates` for details). Note that
+groups’ bounds are only used for the purpose of calculating the coordinate
transform when instantiating a group. A group may position screens and/or
elements outside its bounds, and they will not be cropped.
-To demonstrate how bounds calculation works, consider this example::
+To demonstrate how bounds calculation works, consider this example:
+
+.. code-block:: XML
<group name="autobounds">
<!-- bounds automatically calculated with origin at (5,10), width 30, and height 15 -->
@@ -785,8 +971,10 @@ To demonstrate how bounds calculation works, consider this example::
</view>
This is relatively straightforward, as all elements inherently fall within the
-group's automatically computed bounds. Now consider what happens if a group
-positions elements outside its explicit bounds::
+group’s automatically computed bounds. Now consider what happens if a group
+positions elements outside its explicit bounds:
+
+.. code-block:: XML
<group name="periphery">
<!-- elements are above the top edge and to the right of the right edge of the bounds -->
@@ -805,8 +993,8 @@ positions elements outside its explicit bounds::
<group ref="periphery"><bounds x="5" y="5" width="30" height="25" /></group>
</view>
-The group's elements are translated and scaled as necessary to distort the
-group's internal bounds to the destination bounds in the view. The group's
+The group’s elements are translated and scaled as necessary to distort the
+group’s internal bounds to the destination bounds in the view. The group’s
content is not restricted to its bounds. The view considers the bounds of the
actual layout elements when computing its bounds, not the destination bounds
specified for the group.
@@ -817,20 +1005,20 @@ the group is instantiated (*not* its lexical parent, the top-level
``mamelayout`` element). Any ``param`` elements inside the group definition
element set parameters in the local scope for the group instantiation. Local
parameters do not persist across multiple instantiations. See
-:ref:`layout-concepts-params` for more detail on parameters. (Note that the
-group's name is not part of its content, and any parameter references in the
+:ref:`layfile-concepts-params` for more detail on parameters. (Note that the
+group’s name is not part of its content, and any parameter references in the
``name`` attribute itself will be substituted at the point where the group
-definition appears in the top-level ``mamelayout`` element's scope.)
+definition appears in the top-level ``mamelayout`` element’s scope.)
-.. _layout-parts-repeats:
+.. _layfile-parts-repeats:
Repeating blocks
~~~~~~~~~~~~~~~~
Repeating blocks provide a concise way to generate or arrange large numbers of
similar elements. Repeating blocks are generally used in conjunction with
-generator parameters (see :ref:`layout-concepts-params`). Repeating blocks may
+generator parameters (see :ref:`layfile-concepts-params`). Repeating blocks may
be nested for more complex arrangements.
Repeating blocks are created with ``repeat`` elements. Each ``repeat`` element
@@ -848,12 +1036,14 @@ elements allowed inside a ``repeat`` element depend on where it appears:
A repeating block effectively repeats its contents the number of times specified
by its ``count`` attribute. See the relevant sections for details on how the
-child elements are used (:ref:`layout-parts`, :ref:`layout-parts-groups`, and
-:ref:`layout-parts-views`). A repeating block creates a nested parameter scope
+child elements are used (:ref:`layfile-parts`, :ref:`layfile-parts-groups`, and
+:ref:`layfile-parts-views`). A repeating block creates a nested parameter scope
inside the parameter scope of its lexical (DOM) parent element.
Generating white number labels from zero to eleven named ``label_0``,
-``label_1``, and so on (inside the top-level ``mamelayout`` element)::
+``label_1``, and so on (inside the top-level ``mamelayout`` element):
+
+.. code-block:: XML
<repeat count="12">
<param name="labelnum" start="0" increment="1" />
@@ -864,7 +1054,9 @@ Generating white number labels from zero to eleven named ``label_0``,
A horizontal row of forty digital displays, with five units space between them,
controlled by outputs ``digit0`` to ``digit39`` (inside a ``group`` or ``view``
-element)::
+element):
+
+.. code-block:: XML
<repeat count="40">
<param name="i" start="0" increment="1" />
@@ -875,7 +1067,9 @@ element)::
</repeat>
Eight five-by-seven dot matrix displays in a row, with pixels controlled by
-outputs ``Dot_000`` to ``Dot_764`` (inside a ``group`` or ``view`` element)::
+outputs ``Dot_000`` to ``Dot_764`` (inside a ``group`` or ``view`` element):
+
+.. code-block:: XML
<repeat count="8"> <!-- 8 digits -->
<param name="digitno" start="1" increment="1" />
@@ -894,7 +1088,9 @@ outputs ``Dot_000`` to ``Dot_764`` (inside a ``group`` or ``view`` element)::
</repeat>
Two horizontally separated, clickable, four-by-four keypads (inside a ``group``
-or ``view`` element)::
+or ``view`` element):
+
+.. code-block:: XML
<repeat count="2">
<param name="group" start="0" increment="4" />
@@ -924,7 +1120,9 @@ takes its initial value from the correspondingly named parameter in the
enclosing scope, but does not modify it.
Generating a chequerboard pattern with alternating alpha values 0.4 and 0.2
-(inside a ``group`` or ``view`` element)::
+(inside a ``group`` or ``view`` element):
+
+.. code-block:: XML
<repeat count="4">
<param name="pairy" start="3" increment="20" />
@@ -958,7 +1156,220 @@ tiles on each iteration. Rows are connected to I/O ports ``board:IN.7`` at the
top to ``board.IN.0`` at the bottom.
-.. _layout-errors:
+.. _layfile-interact:
+
+Interactivity
+-------------
+
+Interactive views are supported by allowing items to be bound to emulated
+outputs and I/O ports. Five kinds of interactivity are supported:
+
+Clickable items
+ If an item in a view is bound to an I/O port switch field, clicking the
+ item will activate the emulated switch.
+State-dependent components
+ Some components will be drawn differently depending on the containing
+ element’s state. These include the dot matrix, multi-segment LED display
+ and simple counter elements. See :ref:`layfile-parts-elements` for details.
+Conditionally-drawn components
+ Components may be conditionally drawn or hidden depending on the containing
+ element’s state by supplying ``state`` and/or ``statemask`` attributes. See
+ :ref:`layfile-parts-elements` for details.
+Component parameter animation
+ Components’ colour and position/size within their containing element may be
+ animated according the element’s state by providing multiple ``color``
+ and/or ``bounds`` elements with ``state`` attributes. See
+ :ref:`layfile-parts-elements` for details.
+Item parameter animation
+ Items’ colour and position/size within their containing view may be animated
+ according to their animation state.
+
+
+.. _layfile-interact-clickable:
+
+Clickable items
+~~~~~~~~~~~~~~~
+
+If a view item (``element`` or ``screen`` element) has ``inputtag`` and
+``inputmask`` attribute values that correspond to a digital switch field in the
+emulated system, clicking the element will activate the switch. The switch
+will remain active as long as the primary button is held down and the pointer is
+within the item’s current bounds. (Note that the bounds may change depending on
+the item’s animation state, see :ref:`layfile-interact-itemanim`).
+
+The ``inputtag`` attribute specifies the tag path of an I/O port relative to the
+device that caused the layout file to be loaded. The ``inputmask`` attribute
+must be an integer specifying the bits of the I/O port field that the item
+should activate. This sample shows instantiation of clickable buttons:
+
+The ``clickthrough`` attribute controls whether clicks can pass through the view
+item to other view items drawn above it. The ``clickthrough`` attribute must be
+``yes`` or ``no`` if present. The default is ``no`` (clicks do not pass
+through) for view items with ``inputtag`` and ``inputmask`` attributes, and
+``yes`` (clicks pass through) for other view items.
+
+.. code-block:: XML
+
+ <element ref="btn_3" inputtag="X2" inputmask="0x10">
+ <bounds x="2.30" y="4.325" width="1.0" height="1.0" />
+ </element>
+ <element ref="btn_0" inputtag="X0" inputmask="0x20">
+ <bounds x="0.725" y="5.375" width="1.0" height="1.0" />
+ </element>
+ <element ref="btn_rst" inputtag="RESET" inputmask="0x01">
+ <bounds x="1.775" y="5.375" width="1.0" height="1.0" />
+ </element>
+
+When handling pointer input, MAME treats all layout elements as being
+rectangular.
+
+
+.. _layfile-interact-elemstate:
+
+Element state
+~~~~~~~~~~~~~
+
+A view item that instantiates an element (``element`` element) may supply a
+state value to the element from an emulated I/O port or output. See
+:ref:`layfile-parts-elements` for details on how an element’s state affects its
+appearance.
+
+If the ``element`` element has a ``name`` attribute, the element state value
+will be taken from the value of the correspondingly named emulated output. Note
+that output names are global, which can become an issue when a machine uses
+multiple instances of the same type of device. This example shows how digital
+displays may be connected to emulated outputs:
+
+.. code-block:: XML
+
+ <element name="digit6" ref="digit"><bounds x="16" y="16" width="48" height="80" /></element>
+ <element name="digit5" ref="digit"><bounds x="64" y="16" width="48" height="80" /></element>
+ <element name="digit4" ref="digit"><bounds x="112" y="16" width="48" height="80" /></element>
+ <element name="digit3" ref="digit"><bounds x="160" y="16" width="48" height="80" /></element>
+ <element name="digit2" ref="digit"><bounds x="208" y="16" width="48" height="80" /></element>
+ <element name="digit1" ref="digit"><bounds x="256" y="16" width="48" height="80" /></element>
+
+If the ``element`` element has ``inputtag`` and ``inputmask`` attributes but
+lacks a ``name`` attribute, the element state value will be taken from the value
+of the corresponding I/O port, masked with the ``inputmask`` value. The
+``inputtag`` attribute specifies the tag path of an I/O port relative to the
+device that caused the layout file to be loaded. The ``inputmask`` attribute
+must be an integer specifying the bits of the I/O port field to use.
+
+If the ``element`` element has no ``inputraw`` attribute, or if the value of the
+``inputraw`` attribute is ``no``, the I/O port’s value is masked with the
+``inputmask`` value and XORed with the I/O port default field value. If the
+result is non-zero, the element state is 1, otherwise it’s 0. This is often
+used or provide visual feedback for clickable buttons, as values for active-high
+and active-low switches are normalised.
+
+If the ``element`` element has an ``inputraw`` attribute with the value ``yes``,
+the element state will be taken from the I/O port’s value masked with the
+``inputmask`` value and shifted to the right to remove trailing zeroes (for
+example a mask of 0x05 will result in no shift, while a mask of 0xb0 will result
+in the value being shifted four bits to the right). This is useful for
+obtaining the value of analog or positional inputs.
+
+
+.. _layfile-interact-itemanim:
+
+View item animation
+~~~~~~~~~~~~~~~~~~~
+
+Items’ colour and position/size within their containing view may be animated.
+This is achieved by supplying multiple ``color`` and/or ``bounds`` child
+elements with ``state`` attributes. The ``state`` attribute of each ``color``
+or ``bounds`` child element must be a non-negative integer. Within a view
+item, no two ``color`` elements may have equal state ``state`` attributes, and
+no two ``bounds`` elements may have equal ``state`` attributes.
+
+If the item’s animation state is lower than the ``state`` value of any
+``bounds`` child element, the position/size specified by the ``bounds`` child
+element with the lowest ``state`` value will be used. If the item’s
+animation state is higher than the ``state`` value of any ``bounds`` child
+element, the position/size specified by the ``bounds`` child element with the
+highest ``state`` value will be used. If the item’s animation state is between
+the ``state`` values of two ``bounds`` child elements, the position/size will be
+interpolated linearly.
+
+If the item’s animation state is lower than the ``state`` value of any ``color``
+child element, the colour specified by the ``color`` child element with the
+lowest ``state`` value will be used. If the item’s animation state is higher
+than the ``state`` value of any ``color`` child element, the colour specified by
+the ``color`` child element with the highest ``state`` value will be used. If
+the item’s animation state is between the ``state`` values of two ``color``
+child elements, the RGBA colour components will be interpolated linearly.
+
+An item’s animation state may be bound to an emulated output or input port by
+supplying an ``animate`` child element. If present, the ``animate`` element
+must have either an ``inputtag`` attribute or a ``name`` attribute (but not
+both). If the ``animate`` child element is not present, the item’s animation
+state is the same as its element state (see :ref:`layfile-interact-elemstate`).
+
+If the ``animate`` child element is present and has an ``inputtag``
+attribute, the item’s animation state will be taken from the value of the
+corresponding I/O port. The ``inputtag`` attribute specifies the tag path of an
+I/O port relative to the device that caused the layout file to be loaded. The
+raw value from the input port is used, active-low switch values are not
+normalised.
+
+If the ``animate`` child element is present and has a ``name`` attribute, the
+item’s animation state will be taken from the value of the correspondingly named
+emulated output. Note that output names are global, which can become an issue
+when a machine uses multiple instances of the same type of device.
+
+If the ``animate`` child element has a ``mask`` attribute, the item’s animation
+state will be masked with the ``mask`` value and shifted to the right to remove
+trailing zeroes (for example a mask of 0x05 will result in no shift, while a
+mask of 0xb0 will result in the value being shifted four bits to the right).
+Note that the ``mask`` attribute applies to output values (specified with the
+``name`` attribute) as well as input port values (specified with the
+``inputtag`` attribute). If the ``mask`` attribute is present, it must be an
+integer value. If the ``mask`` attribute is not present, it is equivalent to
+all 32 bits being set.
+
+This example shows elements with independent element state and animation state,
+using the animation state taken from emulated outputs to control their
+position:
+
+.. code-block:: XML
+
+ <repeat count="5">
+ <param name="x" start="10" increment="9" />
+ <param name="i" start="0" increment="1" />
+ <param name="mask" start="0x01" lshift="1" />
+
+ <element name="cg_sol~i~" ref="cosmo">
+ <animate name="cg_count~i~" />
+ <bounds state="0" x="~x~" y="10" width="6" height="7" />
+ <bounds state="255" x="~x~" y="48.5" width="6" height="7" />
+ </element>
+
+ <element ref="nothing" inputtag="FAKE1" inputmask="~mask~">
+ <animate name="cg_count~i~" />
+ <bounds state="0" x="~x~" y="10" width="6" height="7" />
+ <bounds state="255" x="~x~" y="48.5" width="6" height="7" />
+ </element>
+ </repeat>
+
+This example shows elements with independent element state and animation state,
+using the animation state taken from an emulated positional input to control
+their positions:
+
+.. code-block:: XML
+
+ <repeat count="4">
+ <param name="y" start="1" increment="3" />
+ <param name="n" start="0" increment="1" />
+ <element ref="ledr" name="~n~.7">
+ <animate inputtag="IN.1" mask="0x0f" />
+ <bounds state="0" x="0" y="~y~" width="1" height="1" />
+ <bounds state="11" x="16.5" y="~y~" width="1" height="1" />
+ </element>
+ </repeat>
+
+
+.. _layfile-errors:
Error handling
--------------
@@ -974,7 +1385,7 @@ Error handling
screens are considered unviable and not available to the user.
-.. _layout-autogen:
+.. _layfile-autogen:
Automatically-generated views
-----------------------------
@@ -984,24 +1395,24 @@ layouts, MAME automatically generates views based on the machine configuration.
The following views will be automatically generated:
* If the system has no screens and no viable views were found in the internal
- and external layouts, MAME will load a view that shows the message "No screens
- attached to the system".
+ and external layouts, MAME will load a view that shows the message “No screens
+ attached to the system”.
* For each emulated screen, MAME will generate a view showing the screen at its
physical aspect ratio with rotation applied.
-* For each emulated screen where the configured pixel aspect ratio doesn't match
+* For each emulated screen where the configured pixel aspect ratio doesn’t match
the physical aspect ratio, MAME will generate a view showing the screen at an
aspect ratio that produces square pixels, with rotation applied.
* If the system has a single emulated screen, MAME will generate a view showing
two copies of the screen image above each other with a small gap between them.
The upper copy will be rotated by 180 degrees. This view can be used in a
- "cocktail table" cabinet for simultaneous two-player games, or alternating
- play games that don't automatically rotate the display for the second player.
+ “cocktail table” cabinet for simultaneous two-player games, or alternating
+ play games that don’t automatically rotate the display for the second player.
The screen will be displayed at its physical aspect ratio, with rotation
applied.
* If the system has exactly two emulated screens, MAME will generate a view
showing the second screen above the first screen with a small gap between
them. The second screen will be rotated by 180 degrees. This view can be
- used to play a dual-screen two-player game on a "cocktail table" cabinet with
+ used to play a dual-screen two-player game on a “cocktail table” cabinet with
a single screen. The screens will be displayed at their physical aspect
ratios, with rotation applied.
* If the system has exactly two emulated screens and no view in the internal or
@@ -1017,23 +1428,23 @@ The following views will be automatically generated:
will be displayed at physical aspect ratio, with rotation applied.
-.. _layout-complay:
+.. _layfile-complay:
Using complay.py
----------------
The MAME source contains a Python script called ``complay.py``, found in the
-``scripts/build`` subdirectory. This script is used as part of MAME's build
+``scripts/build`` subdirectory. This script is used as part of MAME’s build
process to reduce the size of data for internal layouts and convert it to a form
that can be built into the executable. However, it can also detect many common
layout file format errors, and generally provides better error messages than
-MAME does when loading a layout file. Note that it doesn't actually run the
-whole layout engine, so it can't detect errors like undefined element references
+MAME does when loading a layout file. Note that it doesn’t actually run the
+whole layout engine, so it can’t detect errors like undefined element references
when parameters are used, or recursively nested groups. The ``complay.py``
script is compatible with both Python 2.7 and Python 3 interpreters.
-The ``complay.py`` script takes three parameters -- an input file name, an
-output file name, and a base name for variables in the output:
+The ``complay.py`` script takes three parameters – an input file name, an output
+file name, and a base name for variables in the output:
**python scripts/build/complay.py** *<input>* [*<output>* [*<varname>*]]
@@ -1047,6 +1458,49 @@ in case of an I/O error. If an output file name is specified, the file will be
created/overwritten on success or removed on failure.
To check a layout file for common errors, run the script with the path to the
-file no check and no output file name or base variable name. For example:
+file to check and no output file name or base variable name. For example:
**python scripts/build/complay.py artwork/dino/default.lay**
+
+
+.. _layfile-examples:
+
+Example layout files
+--------------------
+
+These layout files demonstrate various artwork system features. They are all
+internal layouts included in MAME.
+
+`sstrangr.lay <https://git.redump.net/mame/tree/src/mame/layout/sstrangr.lay?h=mame0261>`_
+ A simple case of using translucent colour overlays to visually separate and
+ highlight elements on a black and white screen.
+`seawolf.lay <https://git.redump.net/mame/tree/src/mame/layout/seawolf.lay?h=mame0261>`_
+ This system uses lamps for key gameplay elements. Blending modes are used
+ for the translucent colour overlay placed over the monitor, and the lamps
+ reflected in front of the monitor. Also uses collections to allow parts of
+ the layout to be disabled selectively.
+`armora.lay <https://git.redump.net/mame/tree/src/mame/layout/armora.lay?h=mame0261>`_
+ This game’s monitor is viewed directly through a translucent colour overlay
+ rather than being reflected from inside the cabinet. This means the overlay
+ reflects ambient light as well as affecting the colour of the video image.
+ The shapes on the overlay are drawn using embedded SVG images.
+`tranz330.lay <https://git.redump.net/mame/tree/src/mame/layout/tranz330.lay?h=mame0261>`_
+ A multi-segment alphanumeric display and keypad. The keys are clickable,
+ and provide visual feedback when pressed.
+`esq2by16.lay <https://git.redump.net/mame/tree/src/mame/layout/esq2by16.lay?h=mame0261>`_
+ Builds up a multi-line dot matrix character display. Repeats are used to
+ avoid repetition for the rows in a character, characters in a line, and
+ lines in a page. Group colors allow a single element to be used for all
+ four display colours.
+`cgang.lay <https://git.redump.net/mame/tree/src/mame/layout/cgang.lay?h=mame0261>`_
+ Animates the position of element items to simulate an electromechanical
+ shooting gallery game. Also demonstrates effective use of components to
+ build up complex graphics.
+`minspace.lay <https://git.redump.net/mame/tree/src/mame/layout/minspace.lay?h=mame0261>`_
+ Shows the position of a slider control with LEDs on it.
+`md6802.lay <https://git.redump.net/mame/tree/src/mame/layout/md6802.lay?h=mame0261>`_
+ Effectively using groups as a procedural programming language to build up an
+ image of a trainer board.
+`beena.lay <https://git.redump.net/mame/tree/src/mame/layout/beena.lay?h=mame0261>`_
+ Using event-based scripting to dynamically position elements and draw elemnt
+ content programmatically.
diff --git a/docs/source/techspecs/layout_script.rst b/docs/source/techspecs/layout_script.rst
new file mode 100644
index 00000000000..f3ff505c9df
--- /dev/null
+++ b/docs/source/techspecs/layout_script.rst
@@ -0,0 +1,786 @@
+.. _layscript:
+
+MAME Layout Scripting
+=====================
+
+.. contents:: :local:
+
+
+.. _layscript-intro:
+
+Introduction
+------------
+
+MAME layout files can embed Lua script to provide enhanced functionality.
+Although there’s a lot you can do with conditionally drawn components and
+parameter animation, some things can only be done with scripting. MAME uses an
+event-based model. Scripts can supply functions that will be called after
+certain events, or when certain data is required.
+
+Layout scripting requires the :ref:`layout plugin <plugins-layout>` to be
+enabled. For example, to run BWB Double Take with the Lua script in the layout
+enabled, you might use this command::
+
+ mame -plugins -plugin layout v4dbltak
+
+You may want to add the settings to enable the layout plugin to an INI file to
+save having to enable it every time you start a system. See :ref:`plugins` for
+more information about using plugins with MAME.
+
+
+.. _layscript-examples:
+
+Practical examples
+------------------
+
+Before diving into the technical details of how it works, we’ll start with some
+example layout files using Lua script for enhancement. It’s assumed that you’re
+familiar with MAME’s artwork system and have a basic understanding of Lua
+scripting. For details on MAME’s layout file, see :ref:`layfile`; for detailed
+descriptions of MAME’s Lua interface, see :ref:`luascript`.
+
+.. _layscript-examples-espial:
+
+Espial: joystick split across ports
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Take a look at the player input definitions for Espial:
+
+.. code-block:: C++
+
+ PORT_START("IN1")
+ PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_START1 )
+ PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_START2 )
+ PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_8WAY PORT_COCKTAIL
+ PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_8WAY PORT_COCKTAIL
+ PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP ) PORT_8WAY PORT_COCKTAIL
+ PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN ) PORT_8WAY
+ PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_JOYSTICK_DOWN ) PORT_8WAY PORT_COCKTAIL
+ PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_BUTTON2 ) PORT_COCKTAIL
+
+ PORT_START("IN2")
+ PORT_BIT( 0x01, IP_ACTIVE_HIGH, IPT_UNKNOWN )
+ PORT_BIT( 0x02, IP_ACTIVE_HIGH, IPT_COIN1 )
+ PORT_BIT( 0x04, IP_ACTIVE_HIGH, IPT_UNKNOWN )
+ PORT_BIT( 0x08, IP_ACTIVE_HIGH, IPT_JOYSTICK_RIGHT ) PORT_8WAY
+ PORT_BIT( 0x10, IP_ACTIVE_HIGH, IPT_JOYSTICK_UP ) PORT_8WAY
+ PORT_BIT( 0x20, IP_ACTIVE_HIGH, IPT_BUTTON1 ) PORT_COCKTAIL
+ PORT_BIT( 0x40, IP_ACTIVE_HIGH, IPT_BUTTON1 )
+ PORT_BIT( 0x80, IP_ACTIVE_HIGH, IPT_JOYSTICK_LEFT ) PORT_8WAY
+
+There are two joysticks, one used for both players on an upright cabinet or the
+first player on a cocktail cabinet, and one used for the second player on a
+cocktail cabinet. Notice that the switches for the first joystick are split
+across the two I/O ports.
+
+There’s no layout file syntax to build the element state using bits from
+multiple I/O ports. It’s also inconvenient if each joystick needs to be defined
+as a separate element because the bits for the switches aren’t arranged the same
+way.
+
+We can overcome these limitations using a script to read the player inputs and
+set the items’ element state:
+
+.. code-block:: XML
+
+ <?xml version="1.0"?>
+ <mamelayout version="2">
+
+ <!-- element for drawing a joystick -->
+ <!-- up = 1 (bit 0), down = 2 (bit 1), left = 4 (bit 2), right = 8 (bit 3) -->
+ <element name="stick" defstate="0">
+ <image state="0x0" file="stick_c.svg" />
+ <image state="0x1" file="stick_u.svg" />
+ <image state="0x9" file="stick_ur.svg" />
+ <image state="0x8" file="stick_r.svg" />
+ <image state="0xa" file="stick_dr.svg" />
+ <image state="0x2" file="stick_d.svg" />
+ <image state="0x6" file="stick_dl.svg" />
+ <image state="0x4" file="stick_l.svg" />
+ <image state="0x5" file="stick_ul.svg" />
+ </element>
+
+ <!-- we'll warn the user if the layout plugin isn't enabled -->
+ <!-- draw only when state is 1, and set the default state to 1 so warning is visible initially -->
+ <element name="warning" defstate="1">
+ <text state="1" string="This view requires the layout plugin." />
+ </element>
+
+ <!-- view showing the screen and joysticks on a cocktail cabinet -->
+ <view name="Joystick Display">
+ <!-- draw the screen with correct aspect ratio -->
+ <screen index="0">
+ <bounds x="0" y="0" width="4" height="3" />
+ </screen>
+
+ <!-- first joystick, id attribute allows script to find item -->
+ <!-- no bindings, state will be set by the script -->
+ <element id="joy_p1" ref="stick">
+ <!-- position below the screen -->
+ <bounds xc="2" yc="3.35" width="0.5" height="0.5" />
+ </element>
+
+ <!-- second joystick, id attribute allows script to find item -->
+ <!-- no bindings, state will be set by the script -->
+ <element id="joy_p2" ref="stick">
+ <!-- screen is flipped for second player, so rotate by 180 degrees -->
+ <orientation rotate="180" />
+ <!-- position above the screen -->
+ <bounds xc="2" yc="-0.35" width="0.5" height="0.5" />
+ </element>
+
+ <!-- warning text item also has id attribute so the script can find it -->
+ <element id="warning" ref="warning">
+ <!-- position over the screen near the bottom -->
+ <bounds x="0.2" y="2.6" width="3.6" height="0.2" />
+ </element>
+ </view>
+
+ <!-- the content of the script element will be called as a function by the layout plugin -->
+ <!-- use CDATA block to avoid the need to escape angle brackets and ampersands -->
+ <script><![CDATA[
+ -- file is the layout file object
+ -- set a function to call after resolving tags
+ file:set_resolve_tags_callback(
+ function ()
+ -- file.device is the device that caused the layout to be loaded
+ -- in this case, it's the root machine driver for espial
+ -- look up the two I/O ports we need to be able to read
+ local in1 = file.device:ioport("IN1")
+ local in2 = file.device:ioport("IN2")
+
+ -- look up the view items for showing the joystick state
+ local p1_stick = file.views["Joystick Display"].items["joy_p1"]
+ local p2_stick = file.views["Joystick Display"].items["joy_p2"]
+
+ -- set a function to call before adding the view items to the render target
+ file.views["Joystick Display"]:set_prepare_items_callback(
+ function ()
+ -- read the two player input I/O ports
+ local in1_val = in1:read()
+ local in2_val = in2:read()
+
+ -- set element state for first joystick
+ p1_stick:set_state(
+ ((in2_val & 0x10) >> 4) | -- shift up from IN2 bit 4 to bit 0
+ ((in1_val & 0x20) >> 4) | -- shift down from IN1 bit 5 to bit 1
+ ((in2_val & 0x80) >> 5) | -- shift left from IN2 bit 7 to bit 2
+ (in2_val & 0x08)) -- right is in IN2 bit 3
+
+ -- set element state for second joystick
+ p2_stick:set_state(
+ ((in1_val & 0x10) >> 4) | -- shift up from IN1 bit 4 to bit 0
+ ((in1_val & 0x40) >> 5) | -- shift down from IN1 bit 6 to bit 1
+ (in1_val & 0x04) | -- left is in IN1 bit 2
+ (in1_val & 0x08)) -- right is in IN1 bit 3
+ end)
+
+ -- hide the warning, since if we got here the script is running
+ file.views["Joystick Display"].items["warning"]:set_state(0)
+ end)
+ ]]></script>
+
+ </mamelayout>
+
+The layout has a ``script`` element containing the Lua script. This is called
+as a function by the layout plugin when the layout file is loaded. The layout
+views have been built at this point, but the emulated system has not finished
+starting. In particular, it’s not safe to access inputs and outputs at this
+time. The key variable in the script environment is ``file``, which gives the
+script access to its :ref:`layout file <luascript-ref-renderlayfile>`.
+
+We supply a function to be called after tags in the layout file have been
+resolved. At this point, the emulated system will have completed starting.
+This function does the following tasks:
+
+* Looks up the two :ref:`I/O ports <luascript-ref-ioport>` used for player
+ input. I/O ports can be looked up by tag relative to the device that caused
+ the layout file to be loaded.
+* Looks up the two :ref:`view items <luascript-ref-renderlayitem>` used to
+ display joystick state. Views can be looked up by name (i.e. value of the
+ ``name`` attribute), and items within a view can be looked up by ID (i.e. the
+ value of the ``id`` attribute).
+* Supplies a function to be called before view items are added to the render
+ target when drawing a frame.
+* Hides the warning that reminds the user to enable the layout plugin by setting
+ the element state for the item to 0 (the text component is only drawn when
+ the element state is 1).
+
+The function called before view items are added to the render target reads the
+player inputs, and shuffles the bits into the order needed by the joystick
+element.
+
+.. _layscript-examples-starwars:
+
+Star Wars: animation on two axes
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+We’ll make a layout that shows the position of the flight yoke for Atari Star
+Wars. The input ports are straightforward – each analog axis produces a value
+in the range from 0x00 (0) to 0xff (255), inclusive:
+
+.. code-block:: C++
+
+ PORT_START("STICKY")
+ PORT_BIT( 0xff, 0x80, IPT_AD_STICK_Y ) PORT_SENSITIVITY(70) PORT_KEYDELTA(30)
+
+ PORT_START("STICKX")
+ PORT_BIT( 0xff, 0x80, IPT_AD_STICK_X ) PORT_SENSITIVITY(50) PORT_KEYDELTA(30)
+
+Here’s our layout file:
+
+.. code-block:: XML
+
+ <?xml version="1.0"?>
+ <mamelayout version="2">
+
+ <!-- a square with a white outline 1% of its width -->
+ <element name="outline">
+ <rect><bounds x="0.00" y="0.00" width="1.00" height="0.01" /></rect>
+ <rect><bounds x="0.00" y="0.99" width="1.00" height="0.01" /></rect>
+ <rect><bounds x="0.00" y="0.00" width="0.01" height="1.00" /></rect>
+ <rect><bounds x="0.99" y="0.00" width="0.01" height="1.00" /></rect>
+ </element>
+
+ <!-- a rectangle with a vertical line 10% of its width down the middle -->
+ <element name="line">
+ <!-- use a transparent rectangle to force element dimensions -->
+ <rect>
+ <bounds x="0" y="0" width="0.1" height="1" />
+ <color alpha="0" />
+ </rect>
+ <!-- this is the visible white line -->
+ <rect><bounds x="0.045" y="0" width="0.01" height="1" /></rect>
+ </element>
+
+ <!-- an outlined square inset by 20% with lines 10% of the element width/height -->
+ <element name="box">
+ <!-- use a transparent rectangle to force element dimensions -->
+ <rect>
+ <bounds x="0" y="0" width="0.1" height="0.1" />
+ <color alpha="0" />
+ </rect>
+ <!-- draw the outline of a square -->
+ <rect><bounds x="0.02" y="0.02" width="0.06" height="0.01" /></rect>
+ <rect><bounds x="0.02" y="0.07" width="0.06" height="0.01" /></rect>
+ <rect><bounds x="0.02" y="0.02" width="0.01" height="0.06" /></rect>
+ <rect><bounds x="0.07" y="0.02" width="0.01" height="0.06" /></rect>
+ </element>
+
+ <!-- we'll warn the user if the layout plugin isn't enabled -->
+ <!-- draw only when state is 1, and set the default state to 1 so warning is visible initially -->
+ <element name="warning" defstate="1">
+ <text state="1" string="This view requires the layout plugin." />
+ </element>
+
+ <!-- view showing the screen and flight yoke position -->
+ <view name="Analog Control Display">
+ <!-- draw the screen with correct aspect ratio -->
+ <screen index="0">
+ <bounds x="0" y="0" width="4" height="3" />
+ </screen>
+
+ <!-- draw the white outlined square to the right of the screen near the bottom -->
+ <!-- the script uses the size of this item to determine movement ranges -->
+ <element id="outline" ref="outline">
+ <bounds x="4.1" y="1.9" width="1.0" height="1.0" />
+ </element>
+
+ <!-- vertical line for displaying X axis input -->
+ <element id="vertical" ref="line">
+ <!-- element draws a vertical line, no need to rotate it -->
+ <orientation rotate="0" />
+ <!-- centre it in the square horizontally, using the full height -->
+ <bounds x="4.55" y="1.9" width="0.1" height="1" />
+ </element>
+
+ <!-- horizontal line for displaying Y axis input -->
+ <element id="horizontal" ref="line">
+ <!-- rotate the element by 90 degrees to get a horizontal line -->
+ <orientation rotate="90" />
+ <!-- centre it in the square vertically, using the full width -->
+ <bounds x="4.1" y="2.35" width="1" height="0.1" />
+ </element>
+
+ <!-- draw a small box at the intersection of the vertical and horizontal lines -->
+ <element id="box" ref="box">
+ <bounds x="4.55" y="2.35" width="0.1" height="0.1" />
+ </element>
+
+ <!-- draw the warning text over the screen near the bottom -->
+ <element id="warning" ref="warning">
+ <bounds x="0.2" y="2.6" width="3.6" height="0.2" />
+ </element>
+ </view>
+
+ <!-- the content of the script element will be called as a function by the layout plugin -->
+ <!-- use CDATA block to avoid the need to escape angle brackets and ampersands -->
+ <script><![CDATA[
+ -- file is the layout file object
+ -- set a function to call after resolving tags
+ file:set_resolve_tags_callback(
+ function ()
+ -- file.device is the device that caused the layout to be loaded
+ -- in this case, it's the root machine driver for starwars
+ -- find the analog axis inputs
+ local x_input = file.device:ioport("STICKX")
+ local y_input = file.device:ioport("STICKY")
+
+ -- find the outline item
+ local outline_item = file.views["Analog Control Display"].items["outline"]
+
+ -- variables for keeping state across callbacks
+ local outline_bounds -- bounds of the outlined square
+ local width, height -- width and height for animated items
+ local x_scale, y_scale -- ratios of axis units to render coordinates
+ local x_pos, y_pos -- display positions for the animated items
+
+ -- set a function to call when view dimensions have been recalculated
+ -- this can happen when when the window is resized or scaling options are changed
+ file.views["Analog Control Display"]:set_recomputed_callback(
+ function ()
+ -- get the bounds of the outlined square
+ outline_bounds = outline_item.bounds
+ -- animated items use 10% of the width/height of the square
+ width = outline_bounds.width * 0.1
+ height = outline_bounds.height * 0.1
+ -- calculate ratios of axis units to render coordinates
+ -- animated items leave 90% of the width/height for the movement range
+ -- the end of the range of each axis is at 0xff
+ x_scale = outline_bounds.width * 0.9 / 0xff
+ y_scale = outline_bounds.height * 0.9 / 0xff
+ end)
+
+ -- set a function to call before adding the view items to the render target
+ file.views["Analog Control Display"]:set_prepare_items_callback(
+ function ()
+ -- read analog axes, reverse Y axis as zero is at the bottom
+ local x = x_input:read() & 0xff
+ local y = 0xff - (y_input:read() & 0xff)
+ -- convert the input values to layout coordinates
+ -- use the top left corner of the outlined square as the origin
+ x_pos = outline_bounds.x0 + (x * x_scale)
+ y_pos = outline_bounds.y0 + (y * y_scale)
+ end)
+
+ -- set a function to supply the bounds for the vertical line
+ file.views["Analog Control Display"].items["vertical"]:set_bounds_callback(
+ function ()
+ -- create a new render bounds object (starts as a unit square)
+ local result = emu.render_bounds()
+ -- set left, top, width and height
+ result:set_wh(
+ x_pos, -- calculated X position for animated items
+ outline_bounds.y0, -- top of outlined square
+ width, -- 10% of width of outlined square
+ outline_bounds.height) -- full height of outlined square
+ return result
+ end)
+
+ -- set a function to supply the bounds for the horizontal line
+ file.views["Analog Control Display"].items["horizontal"]:set_bounds_callback(
+ function ()
+ -- create a new render bounds object (starts as a unit square)
+ local result = emu.render_bounds()
+ -- set left, top, width and height
+ result:set_wh(
+ outline_bounds.x0, -- left of outlined square
+ y_pos, -- calculated Y position for animated items
+ outline_bounds.width, -- full width of outlined square
+ height) -- 10% of height of outlined square
+ return result
+ end)
+
+ -- set a function to supply the bounds for the box at the intersection of the lines
+ file.views["Analog Control Display"].items["box"]:set_bounds_callback(
+ function ()
+ -- create a new render bounds object (starts as a unit square)
+ local result = emu.render_bounds()
+ -- set left, top, width and height
+ result:set_wh(
+ x_pos, -- calculated X position for animated items
+ y_pos, -- calculated Y position for animated items
+ width, -- 10% of width of outlined square
+ height) -- 10% of height of outlined square
+ return result
+ end)
+
+ -- hide the warning, since if we got here the script is running
+ file.views["Analog Control Display"].items["warning"]:set_state(0)
+ end)
+ ]]></script>
+
+ </mamelayout>
+
+The layout has a ``script`` element containing the Lua script, to be called as a
+function by the layout plugin when the layout file is loaded. This happens
+after the layout views have been build, but before the emulated system has
+finished starting. The :ref:`layout file <luascript-ref-renderlayfile>` object
+is supplied to the script in the ``file`` variable.
+
+We supply a function to be called after tags in the layout file have been
+resolved. This function does the following:
+
+* Looks up the analog axis :ref:`inputs <luascript-ref-ioport>`.
+* Looks up the :ref:`view item <luascript-ref-renderlayitem>` that draws the
+ outline of area where the yoke position is displayed.
+* Declares some variables to hold calculated values across function calls.
+* Supplies a function to be called when the view’s dimensions have been
+ recomputed.
+* Supplies a function to be called before adding view items to the render
+ container when drawing a frame.
+* Supplies functions that will supply the bounds for the animated items.
+* Hides the warning that reminds the user to enable the layout plugin by setting
+ the element state for the item to 0 (the text component is only drawn when
+ the element state is 1).
+
+The view is looked up by name (value of its ``name`` attribute), and items
+within the view are looked up by ID (values of their ``id`` attributes).
+
+Layout view dimensions are recomputed in response to several events, including
+the window being resized, entering/leaving full screen mode, toggling visibility
+of item collections, and changing the zoom to screen area setting. When this
+happens, we need to update our size and animation scale factors. We get the
+bounds of the square where the yoke position is displayed, calculate the size
+for the animated items, and calculate the ratios of axis units to render target
+coordinates in each direction. It’s more efficient to do these calculations
+only when the results may change.
+
+Before view items are added to the render target, we read the analog axis inputs
+and convert the values to coordinates positions for the animated items. The Y
+axis input uses larger values to aim higher, so we need to reverse the value by
+subtracting it from 0xff (255). We add in the coordinates of the top left
+corner of the square where we’re displaying the yoke position. We do this once
+each time the layout is drawn for efficiency, since we can use the values for
+all three animated items.
+
+Finally, we supply bounds for the animated items when required. These functions
+need to return ``render_bounds`` objects giving the position and size of the
+items in render target coordinates.
+
+(Since the vertical and horizontal line elements each only move on a single
+axis, it would be possible to animate them using the layout file format’s item
+animation features. Only the box at the intersection of the line actually
+requires scripting. It’s done entirely using scripting here for illustrative
+purposes.)
+
+
+.. _layscript-environment:
+
+The layout script environment
+-----------------------------
+
+The Lua environment is provided by the layout plugin. It’s fairly minimal, only
+providing what’s needed:
+
+* ``file`` giving the script’s :ref:`layout file <luascript-ref-renderlayfile>`
+ object. Has a ``device`` property for obtaining the :ref:`device
+ <luascript-ref-device>` that caused the layout file to be loaded, and a
+ ``views`` property for obtaining the layout’s :ref:`views
+ <luascript-ref-renderlayview>` (indexed by name).
+* ``machine`` giving MAME’s current :ref:`running machine
+ <luascript-ref-machine>`.
+* ``emu.device_enumerator``, ``emu.palette_enumerator``,
+ ``emu.screen_enumerator``, ``emu.cassette_enumerator``,
+ ``emu.image_enumerator`` and ``emu.slot_enumerator`` functions for obtaining
+ specific device interfaces.
+* ``emu.attotime``, ``emu.render_bounds`` and ``emu.render_color`` functions for
+ creating :ref:`attotime <luascript-ref-attotime>`, :ref:`bounds
+ <luascript-ref-renderbounds>` and :ref:`colour <luascript-ref-rendercolor>`
+ objects.
+* ``emu.bitmap_ind8``, ``emu.bitmap_ind16``, ``emu.bitmap_ind32``,
+ ``emu.bitmap_ind64``, ``emu.bitmap_yuy16``, ``emu.bitmap_rgb32`` and
+ ``emu.bitmap_argb32`` objects for creating
+ :ref:`bitmaps <luascript-ref-bitmap>`.
+* ``emu.print_verbose``, ``emu.print_error``, ``emu.print_warning``,
+ ``emu.print_info`` and ``emu.print_debug`` functions for diagnostic output.
+* Standard Lua ``tonumber``, ``tostring``, ``pairs`` and ``ipairs`` functions,
+ and ``math``, ``table`` and ``string`` objects for manipulating numbers,
+ strings, tables and other containers.
+* Standard Lua ``print`` function for text output to the console.
+
+
+.. _layscript-events:
+
+Layout events
+-------------
+
+MAME layout scripting uses an event-based model. Scripts can supply functions
+to be called after events occur, or when data is needed. There are three levels
+of events: layout file events, layout view events, and layout view item events.
+
+.. _layscript-events-file:
+
+Layout file events
+~~~~~~~~~~~~~~~~~~
+
+Layout file events apply to the file as a whole, and not to an individual view.
+
+Resolve tags
+ ``file:set_resolve_tags_callback(cb)``
+
+ Called after the emulated system has finished starting, input and output
+ tags in the layout have been resolved, and default item callbacks have been
+ set up. This is a good time to look up inputs and set up view item event
+ handlers.
+
+ The callback function has no return value and takes no parameters. Call
+ with ``nil`` as the argument to remove the event handler.
+
+.. _layscript-events-view:
+
+Layout view events
+~~~~~~~~~~~~~~~~~~
+
+Layout view events apply to an individual view.
+
+Prepare items
+ ``view:set_prepare_items_callback(cb)``
+
+ Called before the view’s items are added to the render target in preparation
+ for drawing a video frame.
+
+ The callback function has no return value and takes no parameters. Call
+ with ``nil`` as the argument to remove the event handler.
+Preload
+ ``view:set_preload_callback(cb)``
+
+ Called after pre-loading visible view elements. This can happen when the
+ view is selected for the first time in a session, or when the user toggles
+ visibility of an element collection on. Be aware that this can be called
+ multiple times in a session and avoid repeating expensive tasks.
+
+ The callback function has no return value and takes no parameters. Call
+ with ``nil`` as the argument to remove the event handler.
+Dimensions recomputed
+ ``view:set_recomputed_callback(cb)``
+
+ Called after view dimensions are recomputed. This happens in several
+ situations, including the window being resized, entering or leaving full
+ screen mode, toggling visibility of item collections, and changes to the
+ rotation and zoom to screen area settings. If you’re animating the position
+ of view items, this is a good time to calculate positions and scale factors.
+
+ The callback function has no return value and takes no parameters. Call
+ with ``nil`` as the argument to remove the event handler.
+Pointer updated
+ ``view:set_pointer_updated_callback(cb)``
+
+ Called when a pointer enters, moves or changes button state over the view.
+
+ The callback function is passed nine arguments:
+
+ * The pointer type as a string. This will be ``mouse``, ``pen``, ``touch``
+ or ``unknown``, and will not change for the lifetime of a pointer.
+ * The pointer ID. This will be a non-negative integer that will not change
+ for the lifetime of a pointer. Pointer ID values are recycled
+ aggressively.
+ * The device ID. This will be a non-negative integer that can be used to
+ group pointers for recognising multi-touch gestures.
+ * The horizontal position of the pointer in layout coordinates.
+ * The vertical position of the pointer in layout coordinates.
+ * A bit mask representing the currently pressed buttons. The primary button
+ is the least significant bit.
+ * A bit mask representing the buttons that were pressed in this update. The
+ primary button is the least significant bit.
+ * A bit mask representing the buttons that were released in this update.
+ The primary button is the least significant bit.
+ * The click count. This is positive for multi-click actions, or negative if
+ a click is turned into a hold or drag. This only applies to the primary
+ button.
+
+ The callback function has no return value. Call with ``nil`` as the
+ argument to remove the event handler.
+Pointer left
+ ``view:set_pointer_left_callback(cb)``
+
+ Called when a pointer leaves the view normally. After receiving this event,
+ the pointer ID may be reused for a new pointer.
+
+ The callback function is passed seven arguments:
+
+ * The pointer type as a string. This will be ``mouse``, ``pen``, ``touch``
+ or ``unknown``, and will not change for the lifetime of a pointer.
+ * The pointer ID. This will be a non-negative integer that will not change
+ for the lifetime of a pointer. Pointer ID values are recycled
+ aggressively.
+ * The device ID. This will be a non-negative integer that can be used to
+ group pointers for recognising multi-touch gestures.
+ * The horizontal position of the pointer in layout coordinates.
+ * The vertical position of the pointer in layout coordinates.
+ * A bit mask representing the buttons that were released in this update.
+ The primary button is the least significant bit.
+ * The click count. This is positive for multi-click actions, or negative if
+ a click is turned into a hold or drag. This only applies to the primary
+ button.
+
+ The callback function has no return value. Call with ``nil`` as the
+ argument to remove the event handler.
+Pointer aborted
+ ``view:set_pointer_aborted_callback(cb)``
+
+ Called when a pointer leaves the view abnormally. After receiving this
+ event, the pointer ID may be reused for a new pointer.
+
+ The callback function is passed seven arguments:
+
+ * The pointer type as a string. This will be ``mouse``, ``pen``, ``touch``
+ or ``unknown``, and will not change for the lifetime of a pointer.
+ * The pointer ID. This will be a non-negative integer that will not change
+ for the lifetime of a pointer. Pointer ID values are recycled
+ aggressively.
+ * The device ID. This will be a non-negative integer that can be used to
+ group pointers for recognising multi-touch gestures.
+ * The horizontal position of the pointer in layout coordinates.
+ * The vertical position of the pointer in layout coordinates.
+ * A bit mask representing the buttons that were released in this update.
+ The primary button is the least significant bit.
+ * The click count. This is positive for multi-click actions, or negative if
+ a click is turned into a hold or drag. This only applies to the primary
+ button.
+
+ The callback function has no return value. Call with ``nil`` as the
+ argument to remove the event handler.
+Forget pointers
+ ``view:set_forget_pointers_callback(cb)``
+
+ Called when the view should stop processing pointer input. This can happen
+ in a number of situations, including:
+
+ * The user activated a menu.
+ * The view configuration will change.
+ * The view will be deactivated.
+
+ The callback function has no return value and takes no parameters. Call
+ with ``nil`` as the argument to remove the event handler.
+
+.. _layscript-events-item:
+
+Layout view item events
+~~~~~~~~~~~~~~~~~~~~~~~
+
+Layout view item callbacks apply to individual items within a view. They are
+used to override items’ default element state, animation state, bounds and
+colour behaviour.
+
+Get element state
+ ``item:set_element_state_callback(cb)``
+
+ Set callback for getting the item’s element state. This controls how the
+ item’s element is drawn, for components that change appearance depending on
+ state, conditionally-drawn components, and component bounds/colour
+ animation. Do not attempt to access the item’s ``element_state`` property
+ from the callback, as it will result in infinite recursion.
+
+ The callback function must return an integer, and takes no parameters. Call
+ with ``nil`` as the argument to restore the default element state
+ handler (based on the item’s XML attributes).
+Get animation state
+ ``item:set_animation_state_callback(cb)``
+
+ Set callback for getting the item’s animation state. This is used for item
+ bounds/colour animation. Do not attempt to access the item’s
+ ``animation_state`` property from the callback, as it will result in
+ infinite recursion.
+
+ The callback function must return an integer, and takes no parameters. Call
+ with ``nil`` as the argument to restore the default animation state handler
+ (based on the item’s XML attributes and ``animate`` child element).
+Get item bounds
+ ``item:set_bounds_callback(cb)``
+
+ Set callback for getting the item’s bounds (position and size). Do not
+ attempt to access the item’s ``bounds`` property from the callback, as it
+ will result in infinite recursion.
+
+ The callback function must return a render bounds object representing the
+ item’s bounds in render target coordinates (usually created by calling
+ ``emu.render_bounds``), and takes no parameters. Call with ``nil`` as the
+ argument to restore the default bounds handler (based on the item’s
+ animation state and ``bounds`` child elements).
+Get item colour
+ ``item:set_color_callback(cb)``
+
+ Set callback for getting the item’s colour (the element texture’s colours
+ multiplied by this colour). Do not attempt to access the item’s ``color``
+ property from the callback, as it will result in infinite recursion.
+
+ The callback function must return a render colour object representing the
+ ARGB colour (usually created by calling ``emu.render_color``), and takes no
+ parameters. Call with ``nil`` as the argument to restore the default colour
+ handler (based on the item’s animation state and ``color`` child elements).
+Get item horizontal scroll window size
+ ``item:set_scroll_size_x_callback(cb)``
+
+ Set callback for getting the item’s horizontal scroll window size. This
+ allows the script to control how much of the element is displayed by the
+ item. Do not attempt to access the item’s ``scroll_size_x`` property from
+ the callback, as it will result in infinite recursion.
+
+ The callback function must return a floating-point number representing the
+ horizontal window size as a proportion of the associated element’s width,
+ and takes no parameters. A value of 1.0 will display the entire width of
+ the element; smaller values will display proportionally smaller parts of the
+ element. Call with ``nil`` as the argument to restore the default
+ horizontal scroll window size handler (based on the ``xscroll`` child
+ element).
+Get item vertical scroll window size
+ ``item:set_scroll_size_y_callback(cb)``
+
+ Set callback for getting the item’s vertical scroll window size. This
+ allows the script to control how much of the element is displayed by the
+ item. Do not attempt to access the item’s ``scroll_size_y`` property from
+ the callback, as it will result in infinite recursion.
+
+ The callback function must return a floating-point number representing the
+ vertical window size as a proportion of the associated element’s height, and
+ takes no parameters. A value of 1.0 will display the entire height of the
+ element; smaller values will display proportionally smaller parts of the
+ element. Call with ``nil`` as the argument to restore the default
+ vertical scroll window size handler (based on the ``xscroll`` child
+ element).
+Get item horizontal scroll position
+ ``item:set_scroll_pos_x_callback(cb)``
+
+ Set callback for getting the item’s horizontal scroll position. This allows
+ the script to control which part of the element is displayed by the item.
+ Do not attempt to access the item’s ``scroll_pos_x`` property from the
+ callback, as this will result in infinite recursion.
+
+ The callback must return a floating-point number, and takes no parameters.
+ A value of 0.0 aligns the left edge of the element with the left edge of the
+ item; larger values pan right. Call with ``nil`` as the argument to restore
+ the default horizontal scroll position handler (based on bindings in the
+ ``xscroll`` child element).
+Get item vertical scroll position
+ ``item:set_scroll_pos_y_callback(cb)``
+
+ Set callback for getting the item’s vertical scroll position. This allows
+ the script to control which part of the element is displayed by the item.
+ Do not attempt to access the item’s ``scroll_pos_y`` property from the
+ callback, as this will result in infinite recursion.
+
+ The callback must return a floating-point number, and takes no parameters.
+ A value of 0.0 aligns the top edge of the element with the top edge of the
+ item; larger values pan down. Call with ``nil`` as the argument to restore
+ the default vertical scroll position handler (based on bindings in the
+ ``yscroll`` child element).
+
+.. _layscript-events-element:
+
+Layout element events
+~~~~~~~~~~~~~~~~~~~~~
+
+Layout element events apply to an individual visual element definition.
+
+Draw
+ ``element:set_draw_callback(cb)``
+
+ Set callback for additional drawing after the element’s components have been
+ drawn. This gives the script direct control over the final texture when an
+ element item is drawn.
+
+ The callback is passed two arguments: the element state (an integer) and the
+ 32-bit ARGB bitmap at the required size. The callback must not attempt to
+ resize the bitmap. Call with ``nil`` as the argument to remove the event
+ handler.
diff --git a/docs/source/techspecs/luaengine.rst b/docs/source/techspecs/luaengine.rst
deleted file mode 100644
index 26d6da6a253..00000000000
--- a/docs/source/techspecs/luaengine.rst
+++ /dev/null
@@ -1,158 +0,0 @@
-Scripting MAME via LUA
-======================
-
-Introduction
-------------
-
-It is now possible to externally drive MAME via LUA scripts. This feature initially appeared in version 0.148, when a minimal
-``luaengine`` was implemented. Nowadays, the LUA interface is rich enough to let you inspect and manipulate devices state, access CPU
-registers, read and write memory, and draw a custom HUD on screen.
-
-Internally, MAME makes extensive use of ``luabridge`` to implement this feature: the idea is to transparently expose as many of the useful internals as possible.
-
-Finally, a warning: The LUA API is not yet declared stable and may suddenly change without prior notice. However, we expose methods to let you know at runtime which API version you are running against, and you can introspect most of the objects at runtime.
-
-Features
---------
-
-The API is not yet complete, but this is a partial list of capabilities currently available to LUA scripts:
-
-- machine metadata (app version, current rom, rom details)
-- machine control (starting, pausing, resetting, stopping)
-- machine hooks (on frame painting and on user events)
-- devices introspection (device tree listing, memory and register
- enumeration)
-- screens introspection (screens listing, screen details, frames
- counting)
-- screen HUD drawing (text, lines, boxes on multiple screens)
-- memory read/write (8/16/32/64 bits, signed and unsigned)
-- registers and states control (states enumeration, get and set)
-
-Usage
------
-
-MAME supports external scripting via LUA (>= 5.3) scripts, either written on the interactive console or loaded as a file. To reach the
-console, just run MAME with **-console** and you will be greeted by a naked ``>`` prompt where you can input your script.
-
-To load a whole script at once, store it in a plain text file and pass it via **-autoboot_script**. Please note that script loading may be delayed (few seconds by default), but you can override the default with the **-autoboot_delay** argument.
-
-To control the execution of your code, you can use a loop-based or an event-based approach. The former is not encouraged as it is
-resource-intensive and makes control flow unnecessarily complex. Instead, we suggest to register custom hooks to be invoked on specific
-events (eg. at each frame rendering).
-
-Walkthrough
------------
-
-Let's first run MAME in a terminal to reach the LUA console:
-
-::
-
- $ mame -console YOUR_ROM
- _/ _/ _/_/ _/ _/ _/_/_/_/
- _/_/ _/_/ _/ _/ _/_/ _/_/ _/
- _/ _/ _/ _/_/_/_/ _/ _/ _/ _/_/_/
- _/ _/ _/ _/ _/ _/ _/
- _/ _/ _/ _/ _/ _/ _/_/_/_/
- mame v0.205
- Copyright (C) Nicola Salmoria and the MAME team
-
- Lua 5.3
- Copyright (C) Lua.org, PUC-Rio
-
- [MAME]>
-
-At this point, your game is probably running in demo mode, let's pause it:
-
-::
-
- [MAME]> emu.pause()
- [MAME]>
-
-Even without textual feedback on the console, you'll notice the game is
-now paused. In general, commands are quiet and only print back error
-messages.
-
-You can check at runtime which version of MAME you are running, with:
-
-::
-
- [MAME]> print(emu.app_name() .. " " .. emu.app_version())
- mame 0.205
-
-We now start exploring screen related methods. First, let's enumerate available screens:
-
-::
-
- [MAME]> for i,v in pairs(manager:machine().screens) do print(i) end
- :screen
-
-**manager:machine()** is the root object of your currently running machine: we will be using this often. **screens** is a table with all
-available screens; most machines only have one main screen. In our case, the main and only screen is tagged as **:screen**, and we can further inspect it:
-
-::
-
- [MAME]> -- let's define a shorthand for the main screen
- [MAME]> s = manager:machine().screens[":screen"]
- [MAME]> print(s:width() .. "x" .. s:height())
- 320x224
-
-We have several methods to draw on the screen a HUD composed of lines, boxes and text:
-
-::
-
- [MAME]> -- we define a HUD-drawing function, and then call it
- [MAME]> function draw_hud()
- [MAME]>> s:draw_text(40, 40, "foo"); -- (x0, y0, msg)
- [MAME]>> s:draw_box(20, 20, 80, 80, 0, 0xff00ffff); -- (x0, y0, x1, y1, fill-color, line-color)
- [MAME]>> s:draw_line(20, 20, 80, 80, 0xff00ffff); -- (x0, y0, x1, y1, line-color)
- [MAME]>> end
- [MAME]> draw_hud();
-
-This will draw some useless art on the screen. However, when unpausing the game, your HUD needs to be refreshed otherwise it will just disappear. In order to do this, you have to register your hook to be called on every frame repaint:
-
-::
-
- [MAME]> emu.register_frame_done(draw_hud, "frame")
-
-All colors are expected in ARGB format (32b unsigned), while screen origin (0,0) normally corresponds to the top-left corner.
-
-Similarly to screens, you can inspect all the devices attached to a machine:
-
-::
-
- [MAME]> for k,v in pairs(manager:machine().devices) do print(k) end
- :audiocpu
- :maincpu
- :saveram
- :screen
- :palette
- [...]
-
-On some of them, you can also inspect and manipulate memory and state:
-
-::
-
- [MAME]> cpu = manager:machine().devices[":maincpu"]
- [MAME]> -- enumerate, read and write state registers
- [MAME]> for k,v in pairs(cpu.state) do print(k) end
- D5
- SP
- A4
- A3
- D0
- PC
- [...]
- [MAME]> print(cpu.state["D0"].value)
- 303
- [MAME]> cpu.state["D0"].value = 255
- [MAME]> print(cpu.state["D0"].value)
- 255
-
-::
-
- [MAME]> -- inspect memory
- [MAME]> for k,v in pairs(cpu.spaces) do print(k) end
- program
- [MAME]> mem = cpu.spaces["program"]
- [MAME]> print(mem:read_i8(0xC000))
- 41
diff --git a/docs/source/techspecs/m6502.rst b/docs/source/techspecs/m6502.rst
index c4cb45f5cea..f5d55fc9af4 100644
--- a/docs/source/techspecs/m6502.rst
+++ b/docs/source/techspecs/m6502.rst
@@ -18,7 +18,7 @@ Point 1 has been ensured through bisimulation with the gate-level simulation per
The 6502 family
---------------
-The MOS 6502 family has been large and productive. A large number of variants exist, varying on bus sizes, I/O, and even opcodes. Some offshots (g65c816, hu6280) even exist that live elsewhere in the mame tree. The final class hierarchy is this:
+The MOS 6502 family has been large and productive. A large number of variants exist, varying on bus sizes, I/O, and even opcodes. Some offshoots (g65c816, hu6280) even exist that live elsewhere in the mame tree. The final class hierarchy is this:
::
@@ -26,7 +26,7 @@ The MOS 6502 family has been large and productive. A large number of variants ex
|
+------+--------+--+--+-------+-------+
| | | | | |
- 6510 deco16 6504 6509 n2a03 65c02
+ 6510 deco16 6504 6509 rp2a03 65c02
| |
+-----+-----+ r65c02
| | | |
@@ -38,7 +38,7 @@ The MOS 6502 family has been large and productive. A large number of variants ex
-The 6510 adds an up to 8 bits I/O port, with the 6510t, 7501 and 8502 being software-identical variants with different pin count (hence I/O count), die process (NMOS, HNMOS, etc) and clock support.
+The 6510 adds an up to 8 bits I/O port, with the 6510t, 7501 and 8502 being software-identical variants with different pin count (hence I/O count), die process (NMOS, HNMOS, etc.) and clock support.
The deco16 is a Deco variant with a small number of not really understood additional instructions and some I/O.
@@ -46,7 +46,7 @@ The 6504 is a pin and address-bus reduced version.
The 6509 adds internal support for paging.
-The n2a03 is the NES variant with the D flag disabled and sound functionality integrated.
+The rp2a03 is the NES variant with the D flag disabled and sound functionality integrated.
The 65c02 is the very first cmos variant with some additional instructions, some fixes, and most of the undocumented instructions turned into nops. The R (Rockwell, but eventually produced by WDC too among others) variant adds a number of bitwise instructions and also stp and wai. The SC variant, used by the Lynx portable console, looks identical to the R variant. The 'S' probably indicates a static-ram-cell process allowing full DC-to-max clock control.
@@ -92,7 +92,7 @@ At a minimum, the class must include a constructor and an enum picking up the co
If the CPU has its own dispatch table, the class must also include the declaration (but not definition) of **disasm_entries**, **do_exec_full** and **do_exec_partial**, the declaration and definition of **disasm_disassemble** (identical for all classes but refers to the class-specific **disasm_entries** array) and include the .inc file (which provides the missing definitions). Support for the generation must also be added to CPU.mak.
-If the CPU has in addition its own opcodes, their declaration must be done through a macro, see f.i. m65c02. The .inc file will provide the definitions.
+If the CPU has in addition its own opcodes, their declaration must be done through a macro, see e.g. m65c02. The .inc file will provide the definitions.
Dispatch tables
@@ -365,7 +365,7 @@ A negative icount means that the CPU won't be able to do anything for some time
Multi-dispatch variants
-----------------------
-Some variants currently in the process of being supported change instruction set depending on an internal flag, either switching to a 16-bits mode or changing some register accesses to memory accesses. This is handled by having multiple dispatch tables for the CPU, the d<CPU>.lst not being 257 entries anymore but 256*n+1. The variable **inst_state_base** must select which instruction table to use at a given time. It must be a multiple of 256, and is in fact simply OR-ed to the first instruction byte to get the dispatch table index (aka inst_state).
+Some variants currently in the process of being supported change instruction set depending on an internal flag, either switching to a 16-bit mode or changing some register accesses to memory accesses. This is handled by having multiple dispatch tables for the CPU, the d<CPU>.lst not being 257 entries anymore but 256*n+1. The variable **inst_state_base** must select which instruction table to use at a given time. It must be a multiple of 256, and is in fact simply OR-ed to the first instruction byte to get the dispatch table index (aka inst_state).
Current TO-DO:
--------------
@@ -374,6 +374,6 @@ Current TO-DO:
- Integrate the I/O subsystems in the 4510
-- Possibly integrate the sound subsytem in the n2a03
+- Possibly integrate the sound subsytem in the rp2a03
- Add decent hookups for the Apple 3 madness
diff --git a/docs/source/techspecs/memory.rst b/docs/source/techspecs/memory.rst
new file mode 100644
index 00000000000..9f0a31758c7
--- /dev/null
+++ b/docs/source/techspecs/memory.rst
@@ -0,0 +1,964 @@
+Emulated system memory and address spaces management
+====================================================
+
+.. contents:: :local:
+
+
+1. Overview
+-----------
+
+The memory subsystem (emumem and addrmap) combines multiple functions
+useful for system emulation:
+
+* address bus decoding and dispatching with caching
+* static descriptions of an address map
+* RAM allocation and registration for state saving
+* interaction with memory regions to access ROM
+
+Devices create address spaces, e.g. decodable buses, through the
+``device_memory_interface``. The machine configuration sets up address
+maps to put in the address spaces, then the device can do read and
+writes through the bus.
+
+2. Basic concepts
+-----------------
+
+2.1 Address spaces
+~~~~~~~~~~~~~~~~~~
+
+An address space, implemented in the class **address_space**,
+represents an addressable bus with potentially multiple sub-devices
+connected requiring a decode. It has a number of data lines (8, 16,
+32 or 64) called data width, a number of address lines (1 to 32)
+called address width and an Endianness. In addition an address shift
+allows for buses that have an atomic granularity different than a
+byte.
+
+Address space objects provide a series of methods for read and write
+access, and a second series of methods for dynamically changing the
+decode.
+
+
+2.2 Address maps
+~~~~~~~~~~~~~~~~
+
+An address map is a static description of the decode expected when
+using a bus. It connects to memory, other devices and methods, and is
+installed, usually at startup, in an address space. That description
+is stored in an **address_map** structure which is filled
+programmatically.
+
+
+2.3 Shares, banks and regions
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Memory shares are allocated memory zones that can be put in multiple
+places in the same or different address spaces, and can also be
+directly accessed from devices.
+
+Memory banks are zones that indirect memory access, giving the
+possibility to dynamically and efficiently change where a zone
+actually points to.
+
+Memory regions are read-only memory zones in which ROMs are loaded.
+
+All of these have names allowing to access them.
+
+2.4 Views
+~~~~~~~~~
+
+Views are a way to multiplex different submaps over a memory range
+with fast switching. It is to be used when multiple devices map at
+the same addresses and are switched in externally. They must be
+created as an object of the device and then setup either statically in
+a memory map or dynamically through ``install_*`` calls.
+
+Switchable submaps, aka variants, are named through an integer. An
+internal indirection through a map ensures that any integer value can
+be used.
+
+
+3. Memory objects
+-----------------
+
+3.1 Shares - memory_share
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. code-block:: C++
+
+ class memory_share {
+ const std::string &name() const;
+ void *ptr() const;
+ size_t bytes() const;
+ endianness_t endianness() const;
+ u8 bitwidth() const;
+ u8 bytewidth() const;
+ };
+
+A memory share is a named allocated memory zone that is automatically
+saved in save states and can be mapped in address spaces. It is the
+standard container for memory that is shared between spaces, but also
+shared between an emulated CPU and a driver. As such one has easy
+access to its contents from the driver class.
+
+.. code-block:: C++
+
+ required_shared_ptr<uNN> m_share_ptr;
+ optional_shared_ptr<uNN> m_share_ptr;
+ required_shared_ptr_array<uNN, count> m_share_ptr_array;
+ optional_shared_ptr_array<uNN, count> m_share_ptr_array;
+
+ [device constructor] m_share_ptr(*this, "name"),
+ [device constructor] m_share_ptr_array(*this, "name%u", 0U),
+
+At the device level, a pointer to the memory zone can easily be
+retrieved by building one of these four finders. Note that like for
+every finder calling ``target()`` on the finder gives you the base
+pointer of the ``memory_share`` object.
+
+.. code-block:: C++
+
+ memory_share_creator<uNN> m_share;
+
+ [device constructor] m_share(*this, "name", size, endianness),
+
+A memory share can be created if it doesn’t exist in a memory map
+through that creator class. If it already exists it is just
+retrieved. That class behaves like a pointer but also has the
+``target()``, ``length()``, ``bytes()``, ``endianness()``,
+``bitwidth()`` and ``bytewidth()`` methods for share information. The
+desired size is specified in bytes.
+
+.. code-block:: C++
+
+ memory_share *memshare(string tag) const;
+
+The ``memshare`` device method retrieves a memory share by name. Beware
+that the lookup can be expensive, prefer finders instead.
+
+3.2 Banks - memory_bank
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. code-block:: C++
+
+ class memory_bank {
+ const std::string &tag() const;
+ int entry() const;
+ void set_entry(int entrynum);
+ void configure_entry(int entrynum, void *base);
+ void configure_entries(int startentry, int numentry, void *base, offs_t stride);
+ void set_base(void *base);
+ void *base() const;
+ };
+
+A memory bank is a named memory zone indirection that can be mapped in
+address spaces. It points to ``nullptr`` when created.
+``configure_entry`` associates an entry number and a base pointer.
+``configure_entries`` does the same for multiple consecutive entries
+spanning a memory zone.
+
+``set_base`` sets the base address for the active entry. If there are
+no entries, entry 0 (zero) is automatically created and selected. Use
+of ``set_base`` should be avoided in favour of pre-configured entries
+unless there are an impractically large number of possible base
+addresses.
+
+``set_entry`` dynamically and efficiently selects the active entry,
+``entry()`` returns the active entry number, and ``base()`` gets the
+associated base pointer.
+
+.. code-block:: C++
+
+ required_memory_bank m_bank;
+ optional_memory_bank m_bank;
+ required_memory_bank_array<count> m_bank_array;
+ optional_memory_bank_array<count> m_bank_array;
+
+ [device constructor] m_bank(*this, "name"),
+ [device constructor] m_bank_array(*this, "name%u", 0U),
+
+At the device level, a pointer to the memory bank object can easily be
+retrieved by building one of these four finders.
+
+.. code-block:: C++
+
+ memory_bank_creator m_bank;
+
+ [device constructor] m_bank(*this, "name"),
+
+A memory bank can be created if it doesn’t exist in a memory map
+through that creator class. If it already exists it is just
+retrieved.
+
+.. code-block:: C++
+
+ memory_bank *membank(string tag) const;
+
+The ``membank`` device method retrieves a memory bank by name. Beware
+that the lookup can be expensive, prefer finders instead.
+
+
+3.3 Regions - memory_region
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. code-block:: C++
+
+ class memory_region {
+ u8 *base();
+ u8 *end();
+ u32 bytes() const;
+ const std::string &name() const;
+ endianness_t endianness() const;
+ u8 bitwidth() const;
+ u8 bytewidth() const;
+ u8 &as_u8(offs_t offset = 0);
+ u16 &as_u16(offs_t offset = 0);
+ u32 &as_u32(offs_t offset = 0);
+ u64 &as_u64(offs_t offset = 0);
+ }
+
+A region is used to store read-only data like ROMs or the result of
+fixed decryptions. Their contents are not saved, which is why they
+should not being written to from the emulated system. They don’t
+really have an intrinsic width (``base()`` returns an ``u8 *`` always),
+which is historical and pretty much unfixable at this point. The
+``as_*`` methods allow for accessing them at a given width.
+
+.. code-block:: C++
+
+ required_memory_region m_region;
+ optional_memory_region m_region;
+ required_memory_region_array<count> m_region_array;
+ optional_memory_region_array<count> m_region_array;
+
+ [device constructor] m_region(*this, "name"),
+ [device constructor] m_region_array(*this, "name%u", 0U),
+
+At the device level, a pointer to the memory region object can easily be
+retrieved by building one of these four finders.
+
+.. code-block:: C++
+
+ memory_region *memregion(string tag) const;
+
+The ``memregion`` device method retrieves a memory region by name.
+Beware that the lookup can be expensive, prefer finders instead.
+
+
+3.4 Views - memory_view
+~~~~~~~~~~~~~~~~~~~~~~~
+
+.. code-block:: C++
+
+ class memory_view {
+ memory_view(device_t &device, std::string name);
+ memory_view_entry &operator[](int slot);
+
+ void select(int entry);
+ void disable();
+
+ const std::string &name() const;
+ }
+
+A view allows to switch part of a memory map between multiple
+possibilities, or even disable it entirely to see what was there
+before. It is created as an object of the device.
+
+.. code-block:: C++
+
+ memory_view m_view;
+
+ [device constructor] m_view(*this, "name"),
+
+It is then setup through the address map API or dynamically. At
+runtime, a numbered variant can be selected using the ``select`` method,
+or the view can be disabled using the ``disable`` method. A disabled
+view can be re-enabled at any time.
+
+
+.. _3.5:
+
+3.5 Bus contention handling
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Some specific CPUs have been upgraded to be interruptible which allows
+to add bus contention and wait states capabitilites. Being
+interruptible means, in practice, that an instruction can be
+interrupted at any time and the execute_run method of the core exited.
+Other devices can then run, then eventually controls returns to the
+core and the instruction continues from the point it was started.
+Importantly, this can be triggered from a handler and even be used to
+interrupt just before the access that is currently done
+(e.g. continuation will redo the access).
+
+The CPUs supporting that declare their capability by overriding the
+method ``cpu_is_interruptible`` to return true.
+
+Three intermediate contention handlers can be added to accesses:
+
+* ``before_delay``: wait a number of cycles before doing the access.
+* ``after_delay``: wait a number of cycles after doing the access.
+* ``before_time``: wait for a given time before doing the access.
+
+For the delay handlers, a method or lambda is called which returns the
+number of cycles to wait (as a u32).
+
+The ``before_time`` is special. First, the time is compared to the
+current value of cpu->total_cycles(). That value is the number of
+cycles elapsed since the last reset of the cpu. It is passed as a
+parameter to the method as a u64 and must return the earliest time as
+a u64 when the access can be done, which can be equal to the passed-in
+time. From there two things can happen: either the running cpu has
+enough cycles left to consume to reach that time. In that case, the
+necessary number of cycles is consumed, and the access is done.
+Otherwise, when there isn't enough, the remaining cycles are consumed,
+the access aborted, scheduling happens, and eventually the access is
+redone. In that case the method is called again with the new current
+time, and must return the (probably same) earliest time again. This
+will happen until enough cycles to consume are available to directly
+do the access.
+
+This approach allows to for instance handle consecutive DMAs. A first
+DMA grabs the bus for a transfer. This shows up as the method
+answering for the earliest time for access the time of the end of the
+dma. If no timer happens until that time the access will then happen
+just after the dma finishes. But if a timer elapses before that and
+as a consequence another dma is queued while the first is running, the
+cycle will be aborted for lack of remaining time, and the method will
+eventually be called again. It will then give the time of when the
+second dma will finish, and all will be well.
+
+It can also allow to reduce said earlier time when circumstances
+require it. For instance a PIO latch that waits up to 64 cycles that
+data arrives can indicate that current time + 64 as a target (which
+will trigger a bus error for instance) but if a timer elapses and
+fills the latch meanwhile the method will be called again and that
+time can just return the current time to let the access pass though.
+Beware that if the timer elapsing did not fill the latch then the
+method must return the time it returned previously, e.g. the initial
+access time + 64, otherwise irrelevant timers happening or simply
+scheduling quantum effects will delay the timeout, possibly to
+infinity if the quantum is small enough.
+
+Contention handlers on the same address are taken into account in the
+``before_time``, ``before_delay`` then ``after_delay`` order.
+Contention handlers of the same type on the same address at
+last-one-wins. Installing any non-contention handler on a range where
+a contention handler was removes it.
+
+
+4. Address maps API
+-------------------
+
+4.1 General API structure
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+An address map is a method of a device which fills an **address_map**
+structure, usually called **map**, passed by reference. The method
+then can set some global configuration through specific methods and
+then provide address range-oriented entries which indicate what should
+happen when a specific range is accessed.
+
+The general syntax for entries uses method chaining:
+
+.. code-block:: C++
+
+ map(start, end).handler(...).handler_qualifier(...).range_qualifier().contention();
+
+The values start and end define the range, the handler() block
+determines how the access is handled, the handler_qualifier() block
+specifies some aspects of the handler (memory sharing for instance)
+and the range_qualifier() block refines the range (mirroring, masking,
+lane selection, etc.). The contention methods handle bus contention
+and wait states for cpus supporting them.
+
+The map follows a “last one wins” principle, where the handler specified
+last is selected when multiple handlers match a given address.
+
+
+4.2 Global configurations
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+4.2.1 Global masking
+''''''''''''''''''''
+
+.. code-block:: C++
+
+ map.global_mask(offs_t mask);
+
+Specifies a mask to be applied to all addresses when accessing the space
+that map is installed in.
+
+
+4.2.2 Returned value on unmapped/nop-ed read
+''''''''''''''''''''''''''''''''''''''''''''
+
+.. code-block:: C++
+
+ map.unmap_value_low();
+ map.unmap_value_high();
+ map.unmap_value(u8 value);
+
+Sets the value to return on reads to an unmapped or nopped-out address.
+Low means 0, high ~0.
+
+
+4.3 Handler setting
+~~~~~~~~~~~~~~~~~~~
+
+4.3.1 Method on the current device
+''''''''''''''''''''''''''''''''''
+
+.. code-block:: C++
+
+ (...).r(FUNC(my_device::read_method))
+ (...).w(FUNC(my_device::write_method))
+ (...).rw(FUNC(my_device::read_method), FUNC(my_device::write_method))
+
+ uNN my_device::read_method(address_space &space, offs_t offset, uNN mem_mask)
+ uNN my_device::read_method(address_space &space, offs_t offset)
+ uNN my_device::read_method(address_space &space)
+ uNN my_device::read_method(offs_t offset, uNN mem_mask)
+ uNN my_device::read_method(offs_t offset)
+ uNN my_device::read_method()
+
+ void my_device::write_method(address_space &space, offs_t offset, uNN data, uNN mem_mask)
+ void my_device::write_method(address_space &space, offs_t offset, uNN data)
+ void my_device::write_method(address_space &space, uNN data)
+ void my_device::write_method(offs_t offset, uNN data, uNN mem_mask)
+ void my_device::write_method(offs_t offset, uNN data)
+ void my_device::write_method(uNN data)
+
+Sets a method of the current device or driver to read, write or both
+for the current entry. The prototype of the method can take multiple
+forms making some elements optional. ``uNN`` represents ``u8``,
+``u16``, ``u32`` or ``u64`` depending on the data width of the handler.
+The handler can be narrower than the bus itself (for instance an 8-bit
+device on a 32-bit bus).
+
+The offset passed in is built from the access address. It starts at
+zero at the start of the range, and increments for each ``uNN`` unit.
+An ``u8`` handler will get an offset in bytes, an ``u32`` one in double
+words. The ``mem_mask`` has its bits set where the accessors actually
+drive the bit. It’s usually built in byte units, but in some cases of
+I/O chips ports with per-bit direction registers the resolution can be
+at the bit level.
+
+
+4.3.2 Method on a different device
+''''''''''''''''''''''''''''''''''
+
+.. code-block:: C++
+
+ (...).r(m_other_device, FUNC(other_device::read_method))
+ (...).r("other-device-tag", FUNC(other_device::read_method))
+ (...).w(m_other_device, FUNC(other_device::write_method))
+ (...).w("other-device-tag", FUNC(other_device::write_method))
+ (...).rw(m_other_device, FUNC(other_device::read_method), FUNC(other_device::write_method))
+ (...).rw("other-device-tag", FUNC(other_device::read_method), FUNC(other_device::write_method))
+
+Sets a method of another device, designated by an object finder
+(usually ``required_device`` or ``optional_device``) or its tag, to
+read, write or both for the current entry.
+
+
+4.3.3 Lambda function
+'''''''''''''''''''''
+
+.. code-block:: C++
+
+ (...).lr{8,16,32,64}(NAME([...](address_space &space, offs_t offset, uNN mem_mask) -> uNN { ... }))
+ (...).lr{8,16,32,64}([...](address_space &space, offs_t offset, uNN mem_mask) -> uNN { ... }, "name")
+ (...).lw{8,16,32,64}(NAME([...](address_space &space, offs_t offset, uNN data, uNN mem_mask) -> void { ... }))
+ (...).lw{8,16,32,64}([...](address_space &space, offs_t offset, uNN data, uNN mem_mask) -> void { ... }, "name")
+ (...).lrw{8,16,32,64}(NAME(read), NAME(write))
+ (...).lrw{8,16,32,64}(read, "name_r", write, "name_w")
+
+Sets a lambda called on read, write or both. The lambda prototype can
+be any of the six available for methods. One can either use ``NAME()``
+over the whole lambda, or provide a name after the lambda definition.
+The number is the data width of the access, e.g. the NN.
+
+
+4.3.4 Direct memory access
+''''''''''''''''''''''''''
+
+.. code-block:: C++
+
+ (...).rom()
+ (...).writeonly()
+ (...).ram()
+
+Selects the range to access a memory zone as read-only, write-only or
+read/write respectively. Specific handler qualifiers specify the
+location of this memory zone. There are two cases when no qualifier is
+acceptable:
+
+* ``ram()`` gives an anonymous RAM zone not accessible outside of the
+ address space.
+
+* ``rom()`` when the memory map is used in an ``AS_PROGRAM``
+ space of a (CPU) device which names is also the name of a region.
+ Then the memory zone points to that region at the offset
+ corresponding to the start of the zone.
+
+.. code-block:: C++
+
+ (...).rom().region("name", offset)
+
+The ``region`` qualifier causes a read-only zone point to the contents
+of a given region at a given offset.
+
+.. code-block:: C++
+
+ (...).rom().share("name")
+ (...).writeonly.share("name")
+ (...).ram().share("name")
+
+The ``share`` qualifier causes the zone point to a shared memory region
+identified by its name. If the share is present in multiple spaces, the
+size, bus width, and, if the bus is more than byte-wide, the Endianness
+must match.
+
+
+4.3.5 Bank access
+'''''''''''''''''
+
+.. code-block:: C++
+
+ (...).bankr("name")
+ (...).bankw("name")
+ (...).bankrw("name")
+
+Sets the range to point at the contents of a memory bank in read, write
+or read/write mode.
+
+
+4.3.6 Port access
+'''''''''''''''''
+
+.. code-block:: C++
+
+ (...).portr("name")
+ (...).portw("name")
+ (...).portrw("name")
+
+Sets the range to point at an I/O port.
+
+
+4.3.7 Dropped access
+''''''''''''''''''''
+
+.. code-block:: C++
+
+ (...).nopr()
+ (...).nopw()
+ (...).noprw()
+
+Sets the range to drop the access without logging. When reading, the
+unmap value is returned.
+
+
+4.3.8 Unmapped access
+'''''''''''''''''''''
+
+.. code-block:: C++
+
+ (...).unmapr()
+ (...).unmapw()
+ (...).unmaprw()
+
+Sets the range to drop the access with logging. When reading, the
+unmap value is returned.
+
+
+4.3.9 Subdevice mapping
+'''''''''''''''''''''''
+
+.. code-block:: C++
+
+ (...).m(m_other_device, FUNC(other_device::map_method))
+ (...).m("other-device-tag", FUNC(other_device::map_method))
+
+Includes a device-defined submap. The start of the range indicates
+where the address zero of the submap ends up, and the end of the range
+clips the submap if needed. Note that range qualifiers (defined
+later) apply.
+
+Currently, only handlers are allowed in submaps and not memory zones
+or banks.
+
+
+4.4 Range qualifiers
+~~~~~~~~~~~~~~~~~~~~
+
+4.4.1 Mirroring
+'''''''''''''''
+
+.. code-block:: C++
+
+ (...).mirror(mask)
+
+Duplicate the range on the addresses reachable by setting any of the 1
+bits present in mask. For instance, a range 0-0x1f with mirror 0x300
+will be present on 0-0x1f, 0x100-0x11f, 0x200-0x21f and 0x300-0x31f.
+The addresses passed in to the handler stay in the 0-0x1f range, the
+mirror bits are not seen by the handler.
+
+
+4.4.2 Masking
+'''''''''''''
+
+.. code-block:: C++
+
+ (...).mask(mask)
+
+Only valid with handlers, the address will be masked with the mask
+before being passed to the handler.
+
+
+4.4.3 Selection
+'''''''''''''''
+
+.. code-block:: C++
+
+ (...).select(mask)
+
+Only valid with handlers, the range will be mirrored as with mirror,
+but the mirror address bits are preserved in the offset passed to the
+handler when it is called. This is useful for devices like sound
+chips where the low bits of the address select a function and the high
+bits a voice number.
+
+
+4.4.4 Sub-unit selection
+''''''''''''''''''''''''
+
+.. code-block:: C++
+
+ (...).umask16(16-bits mask)
+ (...).umask32(32-bits mask)
+ (...).umask64(64-bits mask)
+
+Only valid with handlers and submaps, selects which data lines of the
+bus are actually connected to the handler or the device. The mask value
+should be a multiple of a byte, e.g. the mask is a series of 00 and ff.
+The offset will be adjusted accordingly, so that a difference of 1 means
+the next handled unit in the access.
+
+If the mask is narrower than the bus width, the mask is replicated in
+the upper lines.
+
+
+4.4.5 Chip select handling on sub-unit
+''''''''''''''''''''''''''''''''''''''
+
+.. code-block:: C++
+
+ (...).cselect(16/32/64)
+
+When a device is connected to part of the bus, like a byte on a
+16-bits bus, the target handler is only activated when that part is
+actually accessed. In some cases, very often byte access on a 68000
+16-bits bus, the actual hardware only checks the word address and not
+if the correct byte is accessed. ``cswidth`` tells the memory system to
+trigger the handler if a wider part of the bus is accessed. The
+parameter is that trigger width (would be 16 in the 68000 case).
+
+
+4.4.6 User flags
+''''''''''''''''
+
+.. code-block:: C++
+
+ (...).flags(16-bits mask)
+
+This parameter allows to set user-defined flags on the handler which
+can then be retrieved by an accessing device to change their
+behaviour. An example of use the i960 which marks burstable zones
+that way (they have a specific hardware-level support).
+
+
+4.5 Contention
+~~~~~~~~~~~~~~
+
+.. code-block:: C++
+
+ (...).before_time(method).(...)
+ (...).before_delay(method).(...)
+ (...).after_delay(method).(...)
+
+These three methods allow to add the contention methods to a handler.
+See section `3.5`_. Multiple methods can be handler to one handler.
+
+
+4.6 View setup
+~~~~~~~~~~~~~~
+
+.. code-block:: C++
+
+ map(start, end).view(m_view);
+ m_view[0](start1, end1).[...];
+
+A view is setup in a address map with the view method. The only
+qualifier accepted is mirror. The “disabled” version of the view will
+include what was in the range prior to the view setup.
+
+The different variants are setup by indexing the view with the variant
+number and setting up an entry in the usual way. The entries within a
+variant must of course stay within the range. There are no other
+additional constraints. The contents of a variant, by default, are
+what was there before, i.e. the contents of the disabled view, and
+setting it up allows part or all of it to be overridden.
+
+Variants can only be setup once the view itself has been setup with
+the ``view`` method.
+
+A view can only be put in one address map and in only one position.
+If multiple views have identical or similar contents, remember that
+setting up a map is nothing more than a method call, and creating a
+second method to setup a view is perfectly reasonable. A view is of
+type ``memory_view`` and an indexed entry (e.g. a variant to setup) is
+of type ``memory_view::memory_view_entry &``.
+
+A view can be installed in another view, but don’t forget that a view
+can be installed only once. A view can also be part of “what was there
+before”.
+
+
+
+5. Address space dynamic mapping API
+------------------------------------
+
+5.1 General API structure
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+A series of methods allow the bus decoding of an address space to be
+changed on-the-fly. They’re powerful but have some issues:
+
+* changing the mappings repeatedly can be slow
+* the address space state is not saved in the saved states, so it has to
+ be rebuilt after state load
+* they can be hidden anywhere rather than be grouped in an address map,
+ which can be less readable
+
+The methods, rather than decomposing the information in handler, handler
+qualifier and range qualifier, put them all together as method
+parameters. To make things a little more readable, lots of them are
+optional.
+
+
+5.2 Handler mapping
+~~~~~~~~~~~~~~~~~~~
+
+.. code-block:: C++
+
+ uNN my_device::read_method(address_space &space, offs_t offset, uNN mem_mask)
+ uNN my_device::read_method_m(address_space &space, offs_t offset)
+ uNN my_device::read_method_mo(address_space &space)
+ uNN my_device::read_method_s(offs_t offset, uNN mem_mask)
+ uNN my_device::read_method_sm(offs_t offset)
+ uNN my_device::read_method_smo()
+
+ void my_device::write_method(address_space &space, offs_t offset, uNN data, uNN mem_mask)
+ void my_device::write_method_m(address_space &space, offs_t offset, uNN data)
+ void my_device::write_method_mo(address_space &space, uNN data)
+ void my_device::write_method_s(offs_t offset, uNN data, uNN mem_mask)
+ void my_device::write_method_sm(offs_t offset, uNN data)
+ void my_device::write_method_smo(uNN data)
+
+ readNN_delegate (device, FUNC(read_method))
+ readNNm_delegate (device, FUNC(read_method_m))
+ readNNmo_delegate (device, FUNC(read_method_mo))
+ readNNs_delegate (device, FUNC(read_method_s))
+ readNNsm_delegate (device, FUNC(read_method_sm))
+ readNNsmo_delegate(device, FUNC(read_method_smo))
+
+ writeNN_delegate (device, FUNC(write_method))
+ writeNNm_delegate (device, FUNC(write_method_m))
+ writeNNmo_delegate (device, FUNC(write_method_mo))
+ writeNNs_delegate (device, FUNC(write_method_s))
+ writeNNsm_delegate (device, FUNC(write_method_sm))
+ writeNNsmo_delegate(device, FUNC(write_method_smo))
+
+To be added to a map, a method call and the device it is called onto
+have to be wrapped in the appropriate delegate type. There are twelve
+types, for read and for write and for all six possible prototypes.
+Note that as all delegates, they can also wrap lambdas.
+
+.. code-block:: C++
+
+ space.install_read_handler(addrstart, addrend, read_delegate, unitmask, cswidth, flags)
+ space.install_read_handler(addrstart, addrend, addrmask, addrmirror, addrselect, read_delegate, unitmask, cswidth, flags)
+ space.install_write_handler(addrstart, addrend, write_delegate, unitmask, cswidth, flags)
+ space.install_write_handler(addrstart, addrend, addrmask, addrmirror, addrselect, write_delegate, unitmask, cswidth, flags)
+ space.install_readwrite_handler(addrstart, addrend, read_delegate, write_delegate, unitmask, cswidth, flags)
+ space.install_readwrite_handler(addrstart, addrend, addrmask, addrmirror, addrselect, read_delegate, write_delegate, unitmask, cswidth, flags)
+
+These six methods allow to install delegate-wrapped handlers in a live
+address space. Either plain or with mask, mirror and select. In the
+read/write case both delegates must be of the same flavor (``smo``
+stuff) to avoid a combinatorial explosion of method types. The
+``unitmask``, ``cswidth`` and ``flags`` arguments are optional.
+
+5.3 Direct memory range mapping
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. code-block:: C++
+
+ space.install_rom(addrstart, addrend, void *pointer)
+ space.install_rom(addrstart, addrend, addrmirror, void *pointer)
+ space.install_rom(addrstart, addrend, addrmirror, flags, void *pointer)
+ space.install_writeonly(addrstart, addrend, void *pointer)
+ space.install_writeonly(addrstart, addrend, addrmirror, void *pointer)
+ space.install_writeonly(addrstart, addrend, addrmirror, flags, void *pointer)
+ space.install_ram(addrstart, addrend, void *pointer)
+ space.install_ram(addrstart, addrend, addrmirror, void *pointer)
+ space.install_ram(addrstart, addrend, addrmirror, flags, void *pointer)
+
+Installs a memory block in an address space, with or without mirror
+and flags. ``_rom`` is read-only, ``_ram`` is read/write,
+``_writeonly`` is write-only. The pointer must be non-null, this
+method will not allocate the memory.
+
+5.4 Bank mapping
+~~~~~~~~~~~~~~~~
+
+.. code-block:: C++
+
+ space.install_read_bank(addrstart, addrend, memory_bank *bank)
+ space.install_read_bank(addrstart, addrend, addrmirror, memory_bank *bank)
+ space.install_read_bank(addrstart, addrend, addrmirror, flags, memory_bank *bank)
+ space.install_write_bank(addrstart, addrend, memory_bank *bank)
+ space.install_write_bank(addrstart, addrend, addrmirror, memory_bank *bank)
+ space.install_write_bank(addrstart, addrend, addrmirror, flags, memory_bank *bank)
+ space.install_readwrite_bank(addrstart, addrend, memory_bank *bank)
+ space.install_readwrite_bank(addrstart, addrend, addrmirror, memory_bank *bank)
+ space.install_readwrite_bank(addrstart, addrend, addrmirror, flags, memory_bank *bank)
+
+Install an existing memory bank for reading, writing or both in an
+address space.
+
+5.5 Port mapping
+~~~~~~~~~~~~~~~~
+
+.. code-block:: C++
+
+ space.install_read_port(addrstart, addrend, const char *rtag)
+ space.install_read_port(addrstart, addrend, addrmirror, const char *rtag)
+ space.install_read_port(addrstart, addrend, addrmirror, flags, const char *rtag)
+ space.install_write_port(addrstart, addrend, const char *wtag)
+ space.install_write_port(addrstart, addrend, addrmirror, const char *wtag)
+ space.install_write_port(addrstart, addrend, addrmirror, flags, const char *wtag)
+ space.install_readwrite_port(addrstart, addrend, const char *rtag, const char *wtag)
+ space.install_readwrite_port(addrstart, addrend, addrmirror, const char *rtag, const char *wtag)
+ space.install_readwrite_port(addrstart, addrend, addrmirror, flags, const char *rtag, const char *wtag)
+
+Install ports by name for reading, writing or both.
+
+5.6 Dropped accesses
+~~~~~~~~~~~~~~~~~~~~
+
+.. code-block:: C++
+
+ space.nop_read(addrstart, addrend, addrmirror, flags)
+ space.nop_write(addrstart, addrend, addrmirror, flags)
+ space.nop_readwrite(addrstart, addrend, addrmirror, flags)
+
+Drops the accesses for a given range with an optional mirror and flags;
+
+5.7 Unmapped accesses
+~~~~~~~~~~~~~~~~~~~~~
+
+.. code-block:: C++
+
+ space.unmap_read(addrstart, addrend, addrmirror, flags)
+ space.unmap_write(addrstart, addrend, addrmirror, flags)
+ space.unmap_readwrite(addrstart, addrend, addrmirror, flags)
+
+Unmaps the accesses (e.g. logs the access as unmapped) for a given range
+with an optional mirror and flags.
+
+5.8 Device map installation
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. code-block:: C++
+
+ space.install_device(addrstart, addrend, device, map, unitmask, cswidth, flags)
+
+Install a device address with an address map in a space. The
+``unitmask``, ``cswidth`` and ``flags`` arguments are optional.
+
+5.9 Contention
+~~~~~~~~~~~~~~
+
+.. code-block:: C++
+
+ using ws_time_delegate = device_delegate<u64 (offs_t, u64)>;
+ using ws_delay_delegate = device_delegate<u32 (offs_t)>;
+
+ space.install_read_before_time(addrstart, addrend, addrmirror, ws_time_delegate)
+ space.install_write_before_time(addrstart, addrend, addrmirror, ws_time_delegate)
+ space.install_readwrite_before_time(addrstart, addrend, addrmirror, ws_time_delegate)
+
+ space.install_read_before_delay(addrstart, addrend, addrmirror, ws_delay_delegate)
+ space.install_write_before_delay(addrstart, addrend, addrmirror, ws_delay_delegate)
+ space.install_readwrite_before_delay(addrstart, addrend, addrmirror, ws_delay_delegate)
+
+ space.install_read_after_delay(addrstart, addrend, addrmirror, ws_delay_delegate)
+ space.install_write_after_delay(addrstart, addrend, addrmirror, ws_delay_delegate)
+ space.install_readwrite_after_delay(addrstart, addrend, addrmirror, ws_delay_delegate)
+
+Install a contention handler in the decode path. The addrmirror
+parameter is optional.
+
+
+5.10 View installation
+~~~~~~~~~~~~~~~~~~~~~~
+
+.. code-block:: C++
+
+ space.install_view(addrstart, addrend, view)
+ space.install_view(addrstart, addrend, addrmirror, view)
+
+ view[0].install...
+
+Installs a view in a space. This can be only done once and in only
+one space, and the view must not have been setup through the address
+map API before. Once the view is installed, variants can be selected
+by indexing to call a dynamic mapping method on it.
+
+A view can be installed into a variant of another view without issues,
+with only the usual constraint of single installation.
+
+5.11 Taps
+~~~~~~~~~
+
+.. code-block:: C++
+
+ using tap = std::function<void (offs_t offset, uNN &data, uNN mem_mask)
+
+ memory_passthrough_handler mph = space.install_read_tap(addrstart, addrend, name, read_tap, &mph);
+ memory_passthrough_handler mph = space.install_write_tap(addrstart, addrend, name, write_tap, &mph);
+ memory_passthrough_handler mph = space.install_readwrite_tap(addrstart, addrend, name, read_tap, write_tap, &mph);
+
+ mph.remove();
+
+A tap is a method that is be called when a specific range of addresses
+is accessed without overriding the actual access. Taps can change the
+data passed around. A write tap happens before the access, and can
+change the value to be written. A read tap happens after the access,
+and can change the value returned.
+
+Taps must be of the same width and alignement than the bus. Multiple
+taps can act over the same addresses.
+
+The ``memory_passthrough_handler`` object collates a number of taps
+and allow to remove them all in one call. The ``mph`` parameter is
+optional and a new one will be created if absent.
+
+Taps are lost when a new handler is installed at the same addresses
+(under the usual principle of last one wins). If they need to be
+preserved, one should install a change notifier on the address space,
+and remove + reinstall the taps when notified.
+
diff --git a/docs/source/techspecs/naming.rst b/docs/source/techspecs/naming.rst
new file mode 100644
index 00000000000..4846876c0cd
--- /dev/null
+++ b/docs/source/techspecs/naming.rst
@@ -0,0 +1,95 @@
+.. _naming:
+
+MAME Naming Conventions
+=======================
+
+.. contents:: :local:
+
+
+.. _naming-intro:
+
+Introduction
+------------
+
+To promote consistency and readability in MAME source code, we have some
+naming conventions for various elements.
+
+
+.. _naming-transliteration:
+
+Transliteration
+---------------
+
+For better or worse, the most broadly recognised script in the world is
+English Latin. Conveniently, it’s also included in almost all character
+encodings. To make MAME more globally accessible, we require Latin
+transliterations of titles and other metadata from other scripts. Do
+not use translations in metadata – translations are inherently
+subjective and error-prone. Translations may be included in comments if
+they may be helpful.
+
+If general, if an official Latin script name is known, it should be used
+in favour of a naïve transliteration. For titles containing foreign
+loanwords, the conventional Latin spelling should be used for the
+loanwords (the most obvious example of this is the use of “Mahjong” in
+Japanese titles rather than “Maajan”).
+
+Chinese
+ Where the primary audience was Mandarin-speaking, Hanyu Pinyin
+ should be used. In contexts where diacritics are not permitted
+ (e.g. when limited to ASCII), tone numbers should be omitted. When
+ tones are being indicated using diacritics, tone sandhi rules should
+ be applied. Where the primary audience was Cantonese-speaking
+ (primarily Hong Kong and Guandong), Jyutping should be used with
+ tone numbers omitted. If in doubt, use Hanyu Pinyin.
+Greek
+ Use ISO 843:1997 type 2 (TR) rules. Do not use traditional English
+ spellings for Greek names (people or places).
+Japanese
+ Modified Hepburn rules should generally be used. Use an apostrophe
+ between syllabic N and a following vowel (including iotised vowels).
+ Do not use hyphens to transliterate prolonged vowels.
+Korean
+ Use Revised Romanisation of Korean (RR) rules with traditional
+ English spelling for Korean surnames. Do not use ALA-LC rules for
+ word division and use of hyphens.
+Vietnamese
+ When diacritics can’t be used, omit the tones and replace the vowels
+ with single English vowels – do not use VIQR or TELEX conventions
+ (“an chuot nuong” rather than “a(n chuo^.t nu*o*'ng” or “awn chuootj
+ nuowngs”).
+
+
+.. _naming-titles:
+
+Titles and descriptions
+-----------------------
+
+Try to reproduce the original title faithfully where possible. Try to
+preserve the case convention used by the manufacturer/publisher. If no
+official English Latin title is known, use a standard transliteration.
+For software list entries where a transliteration is used for the
+``description`` element, put the title in an ``info`` element with a
+``name="alt_title"`` attribute.
+
+For software items that have multiple titles (for example different
+regional titles with the same installation media), use the most
+widespread English Latin title for the ``description`` element, and put
+the other titles in ``info`` elements with ``name="alt_title"``
+attributes.
+
+If disambiguation is needed, try to be descriptive as possible. For
+example, use the manufacturer’s version number, regional licensee’s
+name, or terse description of hardware differences in preference to
+arbitrary set numbers. Surround the disambiguation text with
+parentheses, preserve original case for names and version text, but
+use lowercase for anything else besides proper nouns and initialisms.
+
+
+.. _naming-cplusplus:
+
+C++ naming conventions
+----------------------
+
+For C++ naming conventions, see the relevant section in the C++
+Coding Guidelines: :ref:`contributing-cxx-naming`
diff --git a/docs/source/techspecs/object_finders.rst b/docs/source/techspecs/object_finders.rst
new file mode 100644
index 00000000000..27fe42fdd50
--- /dev/null
+++ b/docs/source/techspecs/object_finders.rst
@@ -0,0 +1,1039 @@
+Object Finders
+==============
+
+.. contents:: :local:
+
+
+Introduction
+------------
+
+Object finders are an important part of the glue MAME provides to tie the
+devices that make up an emulated system together. Object finders are used to
+specify connections between devices, to efficiently access resources, and to
+check that necessary resources are available on validation.
+
+Object finders search for a target object by tag relative to a base device.
+Some types of object finder require additional parameters.
+
+Most object finders have required and optional versions. The required versions
+will raise an error if the target object is not found. This will prevent a
+device from starting or cause a validation error. The optional versions will
+log a verbose message if the target object is not found, and provide additional
+members for testing whether the target object was found or not.
+
+Object finder classes are declared in the header src/emu/devfind.h and have
+Doxygen format API documentation.
+
+
+Types of object finder
+----------------------
+
+required_device<DeviceClass>, optional_device<DeviceClass>
+ Finds a device. The template argument ``DeviceClass`` should be a class
+ derived from ``device_t`` or ``device_interface``.
+required_memory_region, optional_memory_region
+ Finds a memory region, usually from ROM definitions. The target is the
+ ``memory_region`` object.
+required_memory_bank, optional_memory_bank
+ Finds a memory bank instantiated in an address map. The target is the
+ ``memory_bank`` object.
+memory_bank_creator
+ Finds a memory bank instantiated in an address map, or creates it if it
+ doesn’t exist. The target is the ``memory_bank`` object. There is no
+ optional version, because the target object will always be found or
+ created.
+required_ioport, optional_ioport
+ Finds an I/O port from a device’s input port definitions. The target is the
+ ``ioport_port`` object.
+required_address_space, optional_address_space
+ Finds a device’s address space. The target is the ``address_space`` object.
+required_region_ptr<PointerType>, optional_region_ptr<PointerType>
+ Finds the base pointer of a memory region, usually from ROM definitions.
+ The template argument ``PointerType`` is the target type (usually an
+ unsigned integer type). The target is the first element in the memory
+ region.
+required_shared_ptr<PointerType>, optional_shared_ptr<PointerType>
+ Finds the base pointer of a memory share instantiated in an address map.
+ The template argument ``PointerType`` is the target type (usually an
+ unsigned integer type). The target is the first element in the memory
+ share.
+memory_share_creator<PointerType>
+ Finds the base pointer of a memory share instantiated in an address map, or
+ creates it if it doesn’t exist. The template argument ``PointerType`` is
+ the target type (usually an unsigned integer type). The target is the first
+ element in the memory share. There is no optional version, because the
+ target object will always be found or created.
+
+
+Finding resources
+-----------------
+
+We’ll start with a simple example of a device that uses object finders to access
+its own child devices, inputs and ROM region. The code samples here are based
+on the Apple II Parallel Printer Interface card, but a lot of things have been
+removed for clarity.
+
+Object finders are declared as members of the device class:
+
+.. code-block:: C++
+
+ class a2bus_parprn_device : public device_t, public device_a2bus_card_interface
+ {
+ public:
+ a2bus_parprn_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock);
+
+ virtual void write_c0nx(u8 offset, u8 data) override;
+ virtual u8 read_cnxx(u8 offset) override;
+
+ protected:
+ virtual tiny_rom_entry const *device_rom_region() const override;
+ virtual void device_add_mconfig(machine_config &config) override;
+ virtual ioport_constructor device_input_ports() const override;
+
+ private:
+ required_device<centronics_device> m_printer_conn;
+ required_device<output_latch_device> m_printer_out;
+ required_ioport m_input_config;
+ required_region_ptr<u8> m_prom;
+ };
+
+We want to find a ``centronics_device``, an ``output_latch_device``, an I/O
+port, and an 8-bit memory region.
+
+In the constructor, we set the initial target for the object finders:
+
+.. code-block:: C++
+
+ a2bus_parprn_device::a2bus_parprn_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock) :
+ device_t(mconfig, A2BUS_PARPRN, tag, owner, clock),
+ device_a2bus_card_interface(mconfig, *this),
+ m_printer_conn(*this, "prn"),
+ m_printer_out(*this, "prn_out"),
+ m_input_config(*this, "CFG"),
+ m_prom(*this, "prom")
+ {
+ }
+
+Each object finder takes a base device and tag as constructor arguments. The
+base device supplied at construction serves two purposes. Most obviously, the
+tag is specified relative to this device. Possibly more importantly, the object
+finder registers itself with this device so that it will be called to perform
+validation and object resolution.
+
+Note that the object finders *do not* copy the tag strings. The caller must
+ensure the tag string remains valid until after validation and/or object
+resolution is complete.
+
+The memory region and I/O port come from the ROM definition and input
+definition, respectively:
+
+.. code-block:: C++
+
+ namespace {
+
+ ROM_START(parprn)
+ ROM_REGION(0x100, "prom", 0)
+ ROM_LOAD( "prom.b4", 0x0000, 0x0100, BAD_DUMP CRC(00b742ca) SHA1(c67888354aa013f9cb882eeeed924e292734e717) )
+ ROM_END
+
+ INPUT_PORTS_START(parprn)
+ PORT_START("CFG")
+ PORT_CONFNAME(0x01, 0x00, "Acknowledge latching edge")
+ PORT_CONFSETTING( 0x00, "Falling (/Y-B)")
+ PORT_CONFSETTING( 0x01, "Rising (Y-B)")
+ PORT_CONFNAME(0x06, 0x02, "Printer ready")
+ PORT_CONFSETTING( 0x00, "Always (S5-C-D)")
+ PORT_CONFSETTING( 0x02, "Acknowledge latch (Z-C-D)")
+ PORT_CONFSETTING( 0x04, "ACK (Y-C-D)")
+ PORT_CONFSETTING( 0x06, "/ACK (/Y-C-D)")
+ PORT_CONFNAME(0x08, 0x00, "Strobe polarity")
+ PORT_CONFSETTING( 0x00, "Negative (S5-A-/X, GND-X)")
+ PORT_CONFSETTING( 0x08, "Positive (S5-X, GND-A-/X)")
+ PORT_CONFNAME(0x10, 0x10, "Character width")
+ PORT_CONFSETTING( 0x00, "7-bit")
+ PORT_CONFSETTING( 0x10, "8-bit")
+ INPUT_PORTS_END
+
+ } // anonymous namespace
+
+ tiny_rom_entry const *a2bus_parprn_device::device_rom_region() const
+ {
+ return ROM_NAME(parprn);
+ }
+
+ ioport_constructor a2bus_parprn_device::device_input_ports() const
+ {
+ return INPUT_PORTS_NAME(parprn);
+ }
+
+Note that the tags ``"prom"`` and ``"CFG"`` match the tags passed to the object
+finders on construction.
+
+Child devices are instantiated in the device’s machine configuration member
+function:
+
+.. code-block:: C++
+
+ void a2bus_parprn_device::device_add_mconfig(machine_config &config)
+ {
+ CENTRONICS(config, m_printer_conn, centronics_devices, "printer");
+ m_printer_conn->ack_handler().set(FUNC(a2bus_parprn_device::ack_w));
+
+ OUTPUT_LATCH(config, m_printer_out);
+ m_printer_conn->set_output_latch(*m_printer_out);
+ }
+
+Object finders are passed to device types to provide tags when instantiating
+child devices. After instantiating a child device in this way, the object
+finder can be used like a pointer to the device until the end of the machine
+configuration member function. Note that to use an object finder like this,
+its base device must be the same as the device being configured (the ``this``
+pointer of the machine configuration member function).
+
+After the emulated machine has been started, the object finders can be used in
+much the same way as pointers:
+
+.. code-block:: C++
+
+ void a2bus_parprn_device::write_c0nx(u8 offset, u8 data)
+ {
+ ioport_value const cfg(m_input_config->read());
+
+ m_printer_out->write(data & (BIT(cfg, 8) ? 0xffU : 0x7fU));
+ m_printer_conn->write_strobe(BIT(~cfg, 3));
+ }
+
+
+ u8 a2bus_parprn_device::read_cnxx(u8 offset)
+ {
+ offset ^= 0x40U;
+ return m_prom[offset];
+ }
+
+For convenience, object finders that target the base pointer of memory regions
+and shares can be indexed like arrays.
+
+
+Connections between devices
+---------------------------
+
+Devices need to be connected together within a system. For example the Sun SBus
+device needs access to the host CPU and address space. Here’s how we declare
+the object finders in the device class (with all distractions removed):
+
+.. code-block:: C++
+
+ DECLARE_DEVICE_TYPE(SBUS, sbus_device)
+
+ class sbus_device : public device_t, public device_memory_interface
+ {
+ template <typename T, typename U>
+ sbus_device(
+ machine_config const &mconfig, char const *tag, device_t *owner, u32 clock,
+ T &&cpu_tag,
+ U &&space_tag, int space_num) :
+ sbus_device(mconfig, tag, owner, clock)
+ {
+ set_cpu(std::forward<T>(cpu_tag));
+ set_type1space(std::forward<U>(space_tag), space_num);
+ }
+
+ sbus_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock) :
+ device_t(mconfig, SBUS, tag, owner, clock),
+ device_memory_interface(mconfig, *this),
+ m_maincpu(*this, finder_base::DUMMY_TAG),
+ m_type1space(*this, finder_base::DUMMY_TAG, -1)
+ {
+ }
+
+ template <typename T> void set_cpu(T &&tag) { m_maincpu.set_tag(std::forward<T>(tag)); }
+ template <typename T> void set_type1space(T &&tag, int num) { m_type1space.set_tag(std::forward<T>(tag), num); }
+
+ protected:
+ required_device<sparc_base_device> m_maincpu;
+ required_address_space m_type1space;
+ };
+
+There are several things to take note of here:
+
+* Object finder members are declared for the things the device needs to access.
+* The device doesn’t know how it will fit into a larger system, the object
+ finders are constructed with dummy arguments.
+* Configuration member functions are provided to set the tag for the host CPU,
+ and the tag and index for the type 1 address space.
+* In addition to the standard device constructor, a constructor with additional
+ parameters for setting the CPU and type 1 address space is provided.
+
+The constant ``finder_base::DUMMY_TAG`` is guaranteed to be invalid and will not
+resolve to an object. This makes it easy to detect incomplete configuration and
+report an error. Address spaces are numbered from zero, so a negative address
+space number is invalid.
+
+The member functions for configuring object finders take a universal reference
+to a tag-like object (templated type with ``&&`` qualifier), as well as any
+other parameters needed by the specific type of object finder. An address space
+finder needs an address space number in addition to a tag-like object.
+
+So what’s a tag-like object? Three things are supported:
+
+* A C string pointer (``char const *``) representing a tag relative to the
+ device being configured. Note that the object finder will not copy the
+ string. The caller must ensure it remains valid until resolution and/or
+ validation is complete.
+* Another object finder. The object finder will take on its current target.
+* For device finders, a reference to an instance of the target device type,
+ setting the target to that device. Note that this will not work if the device
+ is subsequently replaced in the machine configuration. It’s most often used
+ with ``*this``.
+
+The additional constructor that sets initial configuration delegates to the
+standard constructor and then calls the configuration member functions. It’s
+purely for convenience.
+
+When we want to instantiate this device and hook it up, we do this::
+
+ SPARCV7(config, m_maincpu, 20'000'000);
+
+ ADDRESS_MAP_BANK(config, m_type1space);
+
+ SBUS(config, m_sbus, 20'000'000);
+ m_sbus->set_cpu(m_maincpu);
+ m_sbus->set_type1space(m_type1space, 0);
+
+We supply the same object finders to instantiate the CPU and address space
+devices, and to configure the SBus device.
+
+Note that we could also use literal C strings to configure the SBus device, at
+the cost of needing to update the tags in multiple places if they change::
+
+ SBUS(config, m_sbus, 20'000'000);
+ m_sbus->set_cpu("maincpu");
+ m_sbus->set_type1space("type1", 0);
+
+If we want to use the convenience constructor, we just supply additional
+arguments when instantiating the device::
+
+ SBUS(config, m_sbus, 20'000'000, m_maincpu, m_type1space, 0);
+
+
+Object finder arrays
+--------------------
+
+Many systems have multiple similar devices, I/O ports or other resources that
+can be logically organised as an array. To simplify these use cases, object
+finder array types are provided. The object finder array type names have
+``_array`` added to them:
+
++------------------------+------------------------------+
+| required_device | required_device_array |
++------------------------+------------------------------+
+| optional_device | optional_device_array |
++------------------------+------------------------------+
+| required_memory_region | required_memory_region_array |
++------------------------+------------------------------+
+| optional_memory_region | optional_memory_region_array |
++------------------------+------------------------------+
+| required_memory_bank | required_memory_bank_array |
++------------------------+------------------------------+
+| optional_memory_bank | optional_memory_bank_array |
++------------------------+------------------------------+
+| memory_bank_creator | memory_bank_array_creator |
++------------------------+------------------------------+
+| required_ioport | required_ioport_array |
++------------------------+------------------------------+
+| optional_ioport | optional_ioport_array |
++------------------------+------------------------------+
+| required_address_space | required_address_space_array |
++------------------------+------------------------------+
+| optional_address_space | optional_address_space_array |
++------------------------+------------------------------+
+| required_region_ptr | required_region_ptr_array |
++------------------------+------------------------------+
+| optional_region_ptr | optional_region_ptr_array |
++------------------------+------------------------------+
+| required_shared_ptr | required_shared_ptr_array |
++------------------------+------------------------------+
+| optional_shared_ptr | optional_shared_ptr_array |
++------------------------+------------------------------+
+| memory_share_creator | memory_share_array_creator |
++------------------------+------------------------------+
+
+A common case for an object array finder is a key matrix:
+
+.. code-block:: C++
+
+ class keyboard_base : public device_t, public device_mac_keyboard_interface
+ {
+ protected:
+ keyboard_base(machine_config const &mconfig, device_type type, char const *tag, device_t *owner, u32 clock) :
+ device_t(mconfig, type, tag, owner, clock),
+ device_mac_keyboard_interface(mconfig, *this),
+ m_rows(*this, "ROW%u", 0U)
+ {
+ }
+
+ u8 bus_r()
+ {
+ u8 result(0xffU);
+ for (unsigned i = 0U; m_rows.size() > i; ++i)
+ {
+ if (!BIT(m_row_drive, i))
+ result &= m_rows[i]->read();
+ }
+ return result;
+ }
+
+ required_ioport_array<10> m_rows;
+ };
+
+Constructing an object finder array is similar to constructing an object finder,
+except that rather than just a tag you supply a tag format string and index
+offset. In this case, the tags of the I/O ports in the array will be ``ROW0``,
+``ROW1``, ``ROW2``, … ``ROW9``. Note that the object finder array allocates
+dynamic storage for the tags, which remain valid until destruction.
+
+The object finder array is used in much the same way as a ``std::array`` of the
+underlying object finder type. It supports indexing, iterators, and range-based
+``for`` loops.
+
+Because an index offset is specified, the tags don’t need to use zero-based
+indices. It’s common to use one-based indexing like this:
+
+.. code-block:: C++
+
+ class dooyong_state : public driver_device
+ {
+ protected:
+ dooyong_state(machine_config const &mconfig, device_type type, char const *tag) :
+ driver_device(mconfig, type, tag),
+ m_bg(*this, "bg%u", 1U),
+ m_fg(*this, "fg%u", 1U)
+ {
+ }
+
+ optional_device_array<dooyong_rom_tilemap_device, 2> m_bg;
+ optional_device_array<dooyong_rom_tilemap_device, 2> m_fg;
+ };
+
+This causes ``m_bg`` to find devices with tags ``bg1`` and ``bg2``, while
+``m_fg`` finds devices with tags ``fg1`` and ``fg2``. Note that the indexes
+into the object finder arrays are still zero-based like any other C array.
+
+It’s also possible to other format conversions, like hexadecimal (``%x`` and
+``%X``) or character (``%c``):
+
+.. code-block:: C++
+
+ class eurit_state : public driver_device
+ {
+ public:
+ eurit_state(machine_config const &mconfig, device_type type, char const *tag) :
+ driver_device(mconfig, type, tag),
+ m_keys(*this, "KEY%c", 'A')
+ {
+ }
+
+ private:
+ required_ioport_array<5> m_keys;
+ };
+
+In this case, the key matrix ports use tags ``KEYA``, ``KEYB``, ``KEYC``,
+``KEYD`` and ``KEYE``.
+
+When the tags don’t follow a simple ascending sequence, you can supply a
+brace-enclosed initialiser list of tags:
+
+.. code-block:: C++
+
+ class seabattl_state : public driver_device
+ {
+ public:
+ seabattl_state(machine_config const &mconfig, device_type type, char const *tag) :
+ driver_device(mconfig, type, tag),
+ m_digits(*this, { "sc_thousand", "sc_hundred", "sc_half", "sc_unity", "tm_half", "tm_unity" })
+ {
+ }
+
+ private:
+ required_device_array<dm9368_device, 6> m_digits;
+ };
+
+If the underlying object finders require additional constructor arguments,
+supply them after the tag format and index offset (the same values will be used
+for all elements of the array):
+
+.. code-block:: C++
+
+ class dreamwld_state : public driver_device
+ {
+ public:
+ dreamwld_state(machine_config const &mconfig, device_type type, char const *tag) :
+ driver_device(mconfig, type, tag),
+ m_vram(*this, "vram_%u", 0U, 0x2000U, ENDIANNESS_BIG)
+ {
+ }
+
+ private:
+ memory_share_array_creator<u16, 2> m_vram;
+ };
+
+This finds or creates memory shares with tags ``vram_0`` and ``vram_1``, each of
+which is 8 KiB organised as 4,096 big-Endian 16-bit words.
+
+
+Optional object finders
+-----------------------
+
+Optional object finders don’t raise an error if the target object isn’t found.
+This is useful in two situations: ``driver_device`` implementations (state
+classes) representing a family of systems where some components aren’t present
+in all configurations, and devices that can optionally use a resource. Optional
+object finders provide additional member functions for testing whether the
+target object was found.
+
+Optional system components
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Often a class is used to represent a family of related systems. If a component
+isn’t present in all configurations, it may be convenient to use an optional
+object finder to access it. We’ll use the Sega X-board device as an example:
+
+.. code-block:: C++
+
+ class segaxbd_state : public device_t
+ {
+ protected:
+ segaxbd_state(machine_config const &mconfig, device_type type, char const *tag, device_t *owner, u32 clock) :
+ device_t(mconfig, type, tag, owner, clock),
+ m_soundcpu(*this, "soundcpu"),
+ m_soundcpu2(*this, "soundcpu2"),
+ m_segaic16vid(*this, "segaic16vid"),
+ m_pc_0(0),
+ m_lastsurv_mux(0),
+ m_adc_ports(*this, "ADC%u", 0),
+ m_mux_ports(*this, "MUX%u", 0)
+ {
+ }
+
+ optional_device<z80_device> m_soundcpu;
+ optional_device<z80_device> m_soundcpu2;
+ required_device<mb3773_device> m_watchdog;
+ required_device<segaic16_video_device> m_segaic16vid;
+ bool m_adc_reverse[8];
+ u8 m_pc_0;
+ u8 m_lastsurv_mux;
+ optional_ioport_array<8> m_adc_ports;
+ optional_ioport_array<4> m_mux_ports;
+ };
+
+The ``optional_device`` and ``optional_ioport_array`` members are declared and
+constructed in the usual way. Before accessing the target object, we call an
+object finder’s ``found()`` member function to check whether it’s present in the
+system (the explicit cast-to-Boolean operator can be used for the same purpose):
+
+.. code-block:: C++
+
+ void segaxbd_state::pc_0_w(u8 data)
+ {
+ m_pc_0 = data;
+
+ m_watchdog->write_line_ck(BIT(data, 6));
+
+ m_segaic16vid->set_display_enable(data & 0x20);
+
+ if (m_soundcpu.found())
+ m_soundcpu->set_input_line(INPUT_LINE_RESET, (data & 0x01) ? CLEAR_LINE : ASSERT_LINE);
+ if (m_soundcpu2.found())
+ m_soundcpu2->set_input_line(INPUT_LINE_RESET, (data & 0x01) ? CLEAR_LINE : ASSERT_LINE);
+ }
+
+Optional I/O ports provide a convenience member function called ``read_safe``
+that reads the port value if present, or returns the supplied default value
+otherwise:
+
+.. code-block:: C++
+
+ u8 segaxbd_state::analog_r()
+ {
+ int const which = (m_pc_0 >> 2) & 7;
+ u8 value = m_adc_ports[which].read_safe(0x10);
+
+ if (m_adc_reverse[which])
+ value = 255 - value;
+
+ return value;
+ }
+
+ u8 segaxbd_state::lastsurv_port_r()
+ {
+ return m_mux_ports[m_lastsurv_mux].read_safe(0xff);
+ }
+
+The ADC ports return 0x10 (16 decimal) if they are not present, while the
+multiplexed digital ports return 0xff (255 decimal) if they are not present.
+Note that ``read_safe`` is a member of the ``optional_ioport`` itself, and not
+a member of the target ``ioport_port`` object (the ``optional_ioport`` is not
+dereferenced when using it).
+
+There are some disadvantages to using optional object finders:
+
+* There’s no way to distinguish between the target not being present, and the
+ target not being found due to mismatched tags, making it more error-prone.
+* Checking whether the target is present may use CPU branch prediction
+ resources, potentially hurting performance if it happens very frequently.
+
+Consider whether optional object finders are the best solution, or whether
+creating a derived class for the system with additional components is more
+appropriate.
+
+Optional resources
+~~~~~~~~~~~~~~~~~~
+
+Some devices can optionally use certain resources. If the host system doesn’t
+supply them, the device will still function, although some functionality may not
+be available. For example, the Virtual Boy cartridge slot responds to three
+address spaces, called EXP, CHIP and ROM. If the host system will never use one
+or more of them, it doesn’t need to supply a place for the cartridge to install
+the corresponding handlers. (For example a copier may only use the ROM space.)
+
+Let’s look at how this is implemented. The Virtual Boy cartridge slot device
+declares ``optional_address_space`` members for the three address spaces,
+``offs_t`` members for the base addresses in these spaces, and inline member
+functions for configuring them:
+
+.. code-block:: C++
+
+ class vboy_cart_slot_device :
+ public device_t,
+ public device_image_interface,
+ public device_single_card_slot_interface<device_vboy_cart_interface>
+ {
+ public:
+ vboy_cart_slot_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock = 0U);
+
+ template <typename T> void set_exp(T &&tag, int no, offs_t base)
+ {
+ m_exp_space.set_tag(std::forward<T>(tag), no);
+ m_exp_base = base;
+ }
+ template <typename T> void set_chip(T &&tag, int no, offs_t base)
+ {
+ m_chip_space.set_tag(std::forward<T>(tag), no);
+ m_chip_base = base;
+ }
+ template <typename T> void set_rom(T &&tag, int no, offs_t base)
+ {
+ m_rom_space.set_tag(std::forward<T>(tag), no);
+ m_rom_base = base;
+ }
+
+ protected:
+ virtual void device_start() override;
+
+ private:
+ optional_address_space m_exp_space;
+ optional_address_space m_chip_space;
+ optional_address_space m_rom_space;
+ offs_t m_exp_base;
+ offs_t m_chip_base;
+ offs_t m_rom_base;
+
+ device_vboy_cart_interface *m_cart;
+ };
+
+ DECLARE_DEVICE_TYPE(VBOY_CART_SLOT, vboy_cart_slot_device)
+
+The object finders are constructed with dummy values for the tags and space
+numbers (``finder_base::DUMMY_TAG`` and -1):
+
+.. code-block:: C++
+
+ vboy_cart_slot_device::vboy_cart_slot_device(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock) :
+ device_t(mconfig, VBOY_CART_SLOT, tag, owner, clock),
+ device_image_interface(mconfig, *this),
+ device_single_card_slot_interface<device_vboy_cart_interface>(mconfig, *this),
+ m_exp_space(*this, finder_base::DUMMY_TAG, -1, 32),
+ m_chip_space(*this, finder_base::DUMMY_TAG, -1, 32),
+ m_rom_space(*this, finder_base::DUMMY_TAG, -1, 32),
+ m_exp_base(0U),
+ m_chip_base(0U),
+ m_rom_base(0U),
+ m_cart(nullptr)
+ {
+ }
+
+To help detect configuration errors, we’ll check for cases where address spaces
+have been configured but aren’t present:
+
+.. code-block:: C++
+
+ void vboy_cart_slot_device::device_start()
+ {
+ if (!m_exp_space && ((m_exp_space.finder_tag() != finder_base::DUMMY_TAG) || (m_exp_space.spacenum() >= 0)))
+ throw emu_fatalerror("%s: Address space %d of device %s not found (EXP)\n", tag(), m_exp_space.spacenum(), m_exp_space.finder_tag());
+
+ if (!m_chip_space && ((m_chip_space.finder_tag() != finder_base::DUMMY_TAG) || (m_chip_space.spacenum() >= 0)))
+ throw emu_fatalerror("%s: Address space %d of device %s not found (CHIP)\n", tag(), m_chip_space.spacenum(), m_chip_space.finder_tag());
+
+ if (!m_rom_space && ((m_rom_space.finder_tag() != finder_base::DUMMY_TAG) || (m_rom_space.spacenum() >= 0)))
+ throw emu_fatalerror("%s: Address space %d of device %s not found (ROM)\n", tag(), m_rom_space.spacenum(), m_rom_space.finder_tag());
+
+ m_cart = get_card_device();
+ }
+
+
+Object finder types in more detail
+----------------------------------
+
+All object finders provide configuration functionality:
+
+.. code-block:: C++
+
+ char const *finder_tag() const { return m_tag; }
+ std::pair<device_t &, char const *> finder_target();
+ void set_tag(device_t &base, char const *tag);
+ void set_tag(char const *tag);
+ void set_tag(finder_base const &finder);
+
+The ``finder_tag`` and ``finder_target`` member function provides access to the
+currently configured target. Note that the tag returned by ``finder`` tag is
+relative to the base device. It is not sufficient on its own to identify the
+target.
+
+The ``set_tag`` member functions configure the target of the object finder.
+These members must not be called after the object finder is resolved. The first
+form configures the base device and relative tag. The second form sets the
+relative tag and also implicitly sets the base device to the device that is
+currently being configured. This form must only be called from machine
+configuration functions. The third form sets the base object and relative tag
+to the current target of another object finder.
+
+Note that the ``set_tag`` member functions **do not** copy the relative tag. It
+is the caller’s responsibility to ensure the C string remains valid until the
+object finder is resolved (or reconfigured with a different tag). The base
+device must also be valid at resolution time. This may not be the case if the
+device could be removed or replaced later.
+
+All object finders provide the same interface for accessing the target object:
+
+.. code-block:: C++
+
+ ObjectClass *target() const;
+ operator ObjectClass *() const;
+ ObjectClass *operator->() const;
+
+These members all provide access to the target object. The ``target`` member
+function and cast-to-pointer operator will return ``nullptr`` if the target has
+not been found. The pointer member access operator asserts that the target has
+been found.
+
+Optional object finders additionally provide members for testing whether the
+target object has been found:
+
+.. code-block:: C++
+
+ bool found() const;
+ explicit operator bool() const;
+
+These members return ``true`` if the target was found, on the assumption
+that the target pointer will be non-null if the target was found.
+
+Device finders
+~~~~~~~~~~~~~~
+
+Device finders require one template argument for the expected device class.
+This should derive from either ``device_t`` or ``device_interface``. The target
+device object must either be an instance of this class, an instance of a class
+that derives from it. A warning message is logged if a matching device is found
+but it is not an instance of the expected class.
+
+Device finders provide an additional ``set_tag`` overload:
+
+.. code-block:: C++
+
+ set_tag(DeviceClass &object);
+
+This is equivalent to calling ``set_tag(object, DEVICE_SELF)``. Note that the
+device object must not be removed or replaced before the object finder is
+resolved.
+
+Memory system object finders
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The memory system object finders, ``required_memory_region``,
+``optional_memory_region``, ``required_memory_bank``, ``optional_memory_bank``
+and ``memory_bank_creator``, do not have any special functionality. They are
+often used in place of literal tags when installing memory banks in an address
+space.
+
+Example using memory bank finders in an address map:
+
+.. code-block:: C++
+
+ class qvt70_state : public driver_device
+ {
+ public:
+ qvt70_state(machine_config const &mconfig, device_type type, char const *tag) :
+ driver_device(mconfig, type, tag),
+ m_rombank(*this, "rom"),
+ m_rambank(*this, "ram%d", 0U),
+ { }
+
+ private:
+ required_memory_bank m_rombank;
+ required_memory_bank_array<2> m_rambank;
+
+ void mem_map(address_map &map);
+
+ void rombank_w(u8 data);
+ };
+
+ void qvt70_state::mem_map(address_map &map)
+ {
+ map(0x0000, 0x7fff).bankr(m_rombank);
+ map(0x8000, 0x8000).w(FUNC(qvt70_state::rombank_w));
+ map(0xa000, 0xbfff).ram();
+ map(0xc000, 0xdfff).bankrw(m_rambank[0]);
+ map(0xe000, 0xffff).bankrw(m_rambank[1]);
+ }
+
+Example using a memory bank creator to install a memory bank dynamically:
+
+.. code-block:: C++
+
+ class vegaeo_state : public eolith_state
+ {
+ public:
+ vegaeo_state(machine_config const &mconfig, device_type type, char const *tag) :
+ eolith_state(mconfig, type, tag),
+ m_qs1000_bank(*this, "qs1000_bank")
+ {
+ }
+
+ void init_vegaeo();
+
+ private:
+ memory_bank_creator m_qs1000_bank;
+ };
+
+ void vegaeo_state::init_vegaeo()
+ {
+ // Set up the QS1000 program ROM banking, taking care not to overlap the internal RAM
+ m_qs1000->cpu().space(AS_IO).install_read_bank(0x0100, 0xffff, m_qs1000_bank);
+ m_qs1000_bank->configure_entries(0, 8, memregion("qs1000:cpu")->base() + 0x100, 0x10000);
+
+ init_speedup();
+ }
+
+I/O port finders
+~~~~~~~~~~~~~~~~
+
+Optional I/O port finders provide an additional convenience member function:
+
+.. code-block:: C++
+
+ ioport_value read_safe(ioport_value defval);
+
+This will read the port’s value if the target I/O port was found, or return
+``defval`` otherwise. It is useful in situations where certain input devices
+are not always present.
+
+
+Address space finders
+~~~~~~~~~~~~~~~~~~~~~
+
+Address space finders accept an additional argument for the address space number
+to find. A required data width can optionally be supplied to the constructor.
+
+.. code-block:: C++
+
+ address_space_finder(device_t &base, char const *tag, int spacenum, u8 width = 0);
+ void set_tag(device_t &base, char const *tag, int spacenum);
+ void set_tag(char const *tag, int spacenum);
+ void set_tag(finder_base const &finder, int spacenum);
+ template <bool R> void set_tag(address_space_finder<R> const &finder);
+
+The base device and tag must identify a device that implements
+``device_memory_interface``. The address space number is a zero-based index to
+one of the device’s address spaces.
+
+If the width is non-zero, it must match the target address space’s data width in
+bits. If the target address space exists but has a different data width, a
+warning message will be logged, and it will be treated as not being found. If
+the width is zero (the default argument value), the target address space’s data
+width won’t be checked.
+
+Member functions are also provided to get the configured address space number
+and set the required data width:
+
+.. code-block:: C++
+
+ int spacenum() const;
+ void set_data_width(u8 width);
+
+Memory pointer finders
+~~~~~~~~~~~~~~~~~~~~~~
+
+The memory pointer finders, ``required_region_ptr``, ``optional_region_ptr``,
+``required_shared_ptr``, ``optional_shared_ptr`` and ``memory_share_creator``,
+all require one template argument for the element type of the memory area. This
+should usually be an explicitly-sized unsigned integer type (``u8``, ``u16``,
+``u32`` or ``u64``). The size of this type is compared to the width of the
+memory area. If it doesn’t match, a warning message is logged and the region or
+share is treated as not being found.
+
+The memory pointer finders provide an array access operator, and members for
+accessing the size of the memory area:
+
+.. code-block:: C++
+
+ PointerType &operator[](int index) const;
+ size_t length() const;
+ size_t bytes() const;
+
+The array access operator returns a non-\ ``const`` reference to an element of
+the memory area. The index is in units of the element type; it must be
+non-negative and less than the length of the memory area. The ``length`` member
+returns the number of elements in the memory area. The ``bytes`` member returns
+the size of the memory area in bytes. These members should not be called if the
+target region/share has not been found.
+
+The ``memory_share_creator`` requires additional constructor arguments for the
+size and Endianness of the memory share:
+
+.. code-block:: C++
+
+ memory_share_creator(device_t &base, char const *tag, size_t bytes, endianness_t endianness);
+
+The size is specified in bytes. If an existing memory share is found, it is an
+error if its size does not match the specified size. If the width is wider than
+eight bits and an existing memory share is found, it is an error if its
+Endianness does not match the specified Endianness.
+
+The ``memory_share_creator`` provides additional members for accessing
+properties of the memory share:
+
+.. code-block:: C++
+
+ endianness_t endianness() const;
+ u8 bitwidth() const;
+ u8 bytewidth() const;
+
+These members return the Endianness, width in bits and width in bytes of the
+memory share, respectively. They must not be called if the memory share has not
+been found.
+
+
+Output finders
+--------------
+
+Output finders are used for exposing outputs that can be used by the artwork
+system, or by external programs. A common application using an external program
+is a control panel or cabinet lighting controller.
+
+Output finders are not really object finders, but they’re described here because
+they’re used in a similar way. There are a number of important differences to
+be aware of:
+
+* Output finders always create outputs if they do not exist.
+* Output finders must be manually resolved, they are not automatically resolved.
+* Output finders cannot have their target changed after construction.
+* Output finders are array-like, and support an arbitrary number of dimensions.
+* Output names are global, the base device has no influence. (This will change
+ in the future.)
+
+Output finders take a variable number of template arguments corresponding to the
+number of array dimensions you want. Let’s look at an example that uses zero-,
+one- and two-dimensional output finders:
+
+.. code-block:: C++
+
+ class mmd2_state : public driver_device
+ {
+ public:
+ mmd2_state(machine_config const &mconfig, device_type type, char const *tag) :
+ driver_device(mconfig, type, tag),
+ m_digits(*this, "digit%u", 0U),
+ m_p(*this, "p%u_%u", 0U, 0U),
+ m_led_halt(*this, "led_halt"),
+ m_led_hold(*this, "led_hold")
+ { }
+
+ protected:
+ virtual void machine_start() override;
+
+ private:
+ void round_leds_w(offs_t, u8);
+ void digit_w(u8 data);
+ void status_callback(u8 data);
+
+ u8 m_digit;
+
+ output_finder<9> m_digits;
+ output_finder<3, 8> m_p;
+ output_finder<> m_led_halt;
+ output_finder<> m_led_hold;
+ };
+
+The ``m_led_halt`` and ``m_led_hold`` members are zero-dimensional output
+finders. They find a single output each. The ``m_digits`` member is a
+one-dimensional output finder. It finds nine outputs organised as a
+single-dimensional array. The ``m_p`` member is a two-dimensional output
+finder. It finds 24 outputs organised as three rows of eight columns each.
+Larger numbers of dimensions are supported.
+
+The output finder constructor takes a base device reference, a format string,
+and an index offset for each dimension. In this case, all the offsets are
+zero. The one-dimensional output finder ``m_digits`` will find outputs
+``digit0``, ``digit1``, ``digit2``, … ``digit8``. The two-dimensional output
+finder ``m_p`` will find the outputs ``p0_0``, ``p0_1``, … ``p0_7`` for the
+first row, ``p1_0``, ``p1_1``, … ``p1_7`` for the second row, and ``p2_0``,
+``p2_1``, … ``p2_7`` for the third row.
+
+You must call ``resolve`` on each output finder before it can be used. This
+should be done at start time for the output values to be included in save
+states:
+
+.. code-block:: C++
+
+ void mmd2_state::machine_start()
+ {
+ m_digits.resolve();
+ m_p.resolve();
+ m_led_halt.resolve();
+ m_led_hold.resolve();
+
+ save_item(NAME(m_digit));
+ }
+
+Output finders provide operators allowing them to be assigned from or cast to
+32-bit signed integers. The assignment operator will send a notification if the
+new value is different to the output’s current value.
+
+.. code-block:: C++
+
+ operator s32() const;
+ s32 operator=(s32 value);
+
+To set output values, assign through the output finders, as you would with an
+array of the same rank:
+
+.. code-block:: C++
+
+ void mmd2_state::round_leds_w(offs_t offset, u8 data)
+ {
+ for (u8 i = 0; i < 8; i++)
+ m_p[offset][i] = BIT(~data, i);
+ }
+
+ void mmd2_state::digit_w(u8 data)
+ {
+ if (m_digit < 9)
+ m_digits[m_digit] = data;
+ }
+
+ void mmd2_state::status_callback(u8 data)
+ {
+ m_led_halt = (~data & i8080_cpu_device::STATUS_HLTA) ? 1 : 0;
+ m_led_hold = (data & i8080_cpu_device::STATUS_WO) ? 1 : 0;
+ }
diff --git a/docs/source/techspecs/osd_audio.rst b/docs/source/techspecs/osd_audio.rst
new file mode 100644
index 00000000000..82e03d999ef
--- /dev/null
+++ b/docs/source/techspecs/osd_audio.rst
@@ -0,0 +1,348 @@
+OSD audio support
+=================
+
+Introduction
+------------
+
+The audio support in Mame tries to allow the user to freely map
+between the emulated system audio outputs (called speakers) and the
+host system audio. A part of it is the OSD support, where a
+host-specific module ensures the interface between Mame and the host.
+This is the documentation for that module.
+
+Note: this is currenty output-only, but input should follow.
+
+
+Capabitilies
+------------
+
+The OSD interface is designed to allow three levels of support,
+depending on what the API allows and the amount of effort to expend.
+Those are:
+
+* Level 1: One or more audio targets, only one stream allowed per target
+ (aka exclusive mode)
+* Level 2: One or more audio targets, multiple streams per target
+* Level 3: One or more audio targets, multiple streams per target, user-visible
+ per-stream-channel volume control
+
+In any case we support having the user use an external interface to
+change the target of a stream and, in level 3, change the volumes. By
+support we mean storing the information in the per-game configuration
+and keeping the internal UI in sync.
+
+
+Terminology
+-----------
+
+For this module, we use the terms:
+
+* node: some object we can send audio to. Can be physical, like speakers,
+ or virtual, like an effect system. It should have a unique, user-presentable
+ name for the UI.
+* port: a channel of a node, has a name (non-unique, like "front left") and a
+ 3D position
+* stream: a connection to a node with allows to send audio to it
+
+
+Reference documentation
+-----------------------
+
+Adding a module
+~~~~~~~~~~~~~~~
+
+Adding a module is done by adding a cpp file to src/osd/modules/sound
+which follows this structure,
+
+.. code-block:: C++
+
+ // License/copyright
+ #include "sound_module.h"
+ #include "modules/osdmodules.h"
+
+ #ifdef MODULE_SUPPORT_KEY
+
+ #include "modules/lib/osdobj_common.h"
+
+ // [...]
+ namespace osd {
+ namespace {
+
+ class sound_module_class : public osd_module, public sound_module
+ {
+ sound_module_class() : osd_module(OSD_SOUND_PROVIDER, "module_name"),
+ sound_module()
+ // ...
+ };
+
+ }
+ }
+ #else
+ namespace osd { namespace {
+ MODULE_NOT_SUPPORTED(sound_module_class, OSD_SOUND_PROVIDER, "module_name")
+ }}
+ #endif
+
+ MODULE_DEFINITION(SOUND_MODULE_KEY, osd::sound_module_class)
+
+In that code, four names must be chosen:
+
+* MODULE_SUPPORT_KEY some #define coming from the genie scripts to tell that
+ this particular module can be compiled (like NO_USE_PIPEWIRE or SDLMAME_MACOSX)
+* sound_module_class is the name of the class which makes up the module
+ (like sound_coreaudio)
+* module_name is the name to be used in -sound <xxx> to select that particular
+ module (like coreaudio)
+* SOUND_MODULE_KEY is a symbol that represents the module internally (like
+ SOUND_COREAUDIO)
+
+The file path needs to be added to scripts/src/osd/modules.lua in
+osdmodulesbuild() and the module reference to
+src/osd/modules/lib/osdobj_common.cpp in
+osd_common_t::register_options with the line:
+
+.. code-block:: C++
+
+ REGISTER_MODULE(m_mod_man, SOUND_MODULE_KEY);
+
+This should ensure that the module is reachable through -sound <xxx>
+on the appropriate hosts.
+
+
+Interface
+~~~~~~~~~
+
+The full interface is:
+
+.. code-block:: C++
+
+ virtual bool split_streams_per_source() const override;
+ virtual bool external_per_channel_volume() const override;
+
+ virtual int init(osd_interface &osd, osd_options const &options) override;
+ virtual void exit() override;
+
+ virtual uint32_t get_generation() override;
+ virtual osd::audio_info get_information() override;
+ virtual uint32_t stream_sink_open(uint32_t node, std::string name, uint32_t rate) override;
+ virtual uint32_t stream_source_open(uint32_t node, std::string name, uint32_t rate) override;
+ virtual void stream_set_volumes(uint32_t id, const std::vector<float> &db) override;
+ virtual void stream_close(uint32_t id) override;
+ virtual void stream_sink_update(uint32_t id, const int16_t *buffer, int samples_this_frame) override;
+ virtual void stream_source_update(uint32_t id, int16_t *buffer, int samples_this_frame) override;
+
+
+The class sound_module provides defaults for minimum capabilities: one
+stereo target and stream at default sample rate. To support that,
+only *init*, *exit* and *stream_update* need to be implemented.
+*init* is called at startup and *exit* when quitting and can do
+whatever they need to do. *stream_sink_update* will be called on a
+regular basis with a buffer of sample_this_frame * 2 * int16_t with the
+audio to play. From this point in the documentation we'll assume more
+than a single stereo channel is wanted.
+
+
+Capabilities
+~~~~~~~~~~~~
+
+Two methods are used by the module to indicate the level of capability
+of the module:
+
+* split_streams_per_source() should return true when having multiple streams
+ for one target is expected (e.g. Level 2 or 3)
+* external_per_channel_volume() should return true when the streams have
+ per-channel volume control that can be externally controlled (e.g. Level 3)
+
+
+Hardware information and generations
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The core runs on the assumption that the host hardware capabilities
+can change at any time (bluetooth devices coming and going, usb
+hot-plugging...) and that the module has some way to keep tabs on what
+is happening, possibly using multi-threading. To keep it
+lightweight-ish, we use the concept of a *generation* which is a
+32-bit number that is incremented by the module every time something
+changes. The core checks the current generation value at least once
+every update (once per frame, usually) and if it changed asks for the
+new state and detects and handles the differences. *generation*
+should be "eventually stable", e.g. it eventually stops changing when
+the user stops changing things all the time. A systematic increment
+every frame would be a bad idea.
+
+.. code-block:: C++
+
+ virtual uint32_t get_generation() override;
+
+That method returns the current generation number. It's called at a
+minimum once per update, which usually means per frame. It whould be
+reasonably lightweight when nothing special happens.
+
+.. code-block: C++
+
+ virtual osd::audio_info get_information() override;
+
+ struct audio_rate_range {
+ uint32_t m_default_rate;
+ uint32_t m_min_rate;
+ uint32_t m_max_rate;
+ };
+
+ struct audio_info {
+ struct node_info {
+ std::string m_name;
+ uint32_t m_id;
+ audio_rate_range m_rate;
+ std::vector<std::string> m_port_names;
+ std::vector<std::array<double, 3>> m_port_positions;
+ uint32_t m_sinks;
+ uint32_t m_sources;
+ };
+
+ struct stream_info {
+ uint32_t m_id;
+ uint32_t m_node;
+ std::vector<float> m_volumes;
+ };
+
+ uint32_t m_generation;
+ uint32_t m_default_sink;
+ uint32_t m_default_source;
+ std::vector<node_info> m_nodes;
+ std::vector<stream_info> m_streams;
+ };
+
+This method must provide all the information about the current state
+of the host and the module. This state is:
+
+* m_generation: The current generation number
+* m_nodes: The vector available nodes (*node_info*)
+
+ * m_name: The name of the node
+ * m_id: The numeric ID of the node
+ * m_rate: The minimum, maximum and preferred sample rate for the node
+ * m_port_names: The vector of port names
+ * m_port_positions: The vector of 3D position of the ports. Refer to
+ src/emu/speaker.h for the "standard" positions
+ * m_sinks: Number of sinks (inputs)
+ * m_sources: Number of sources (outputs)
+
+* m_default_sink: ID of the node that is the current "system default" for
+ audio output, 0 if there's no such concept
+* m_default_source: same for audio input (currently unused)
+* m_streams: The vector of active streams (*stream_info*)
+
+ * m_id: The numeric ID of the stream
+ * m_node: The target node of the stream
+ * m_volumes: empty if *external_per_channel_volume* is false, current volume
+ value per-channel otherwise
+
+IDs, for nodes and streams, are (independant) 32-bit unsigned non-zero
+values associated to respectively nodes and streams. IDs should not
+be reused. A node that goes away then comes back should get a new ID.
+A stream closing does not allow reuse of its ID.
+
+If a node has both sources and sinks, the sources are *monitors* of
+the sinks, e.g. they're loopbacks. They should have the same count in
+such a case.
+
+When external control exists, a module should change the value of
+*stream_info::m_node* when the user changes it, and same for
+*stream_info::m_volumes*. Generation number should be incremented
+when this happens, so that the core knows to look for changes.
+
+Volumes are floats in dB, where 0 means 100% and -96 means no sound.
+audio.h provides osd::db_to_linear and osd::linear_to_db if such a
+conversion is needed.
+
+There is an inherent race condition with this system, because things
+can change at any point after returning for the method. The idea is
+that the information returned must be internally consistent (a stream
+should not point to a node ID that does not exist in the structure,
+same for default sink) and that any external change from that state
+should increment the generation number, but that's it. Through the
+generation system the core will eventually be in sync with reality.
+
+
+Input and output streams
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. code-block:: C++
+
+ virtual uint32_t stream_sink_open(uint32_t node, std::string name, uint32_t rate) override;
+ virtual uint32_t stream_source_open(uint32_t node, std::string name, uint32_t rate) override;
+ virtual void stream_set_volumes(uint32_t id, const std::vector<float> &db) override;
+ virtual void stream_close(uint32_t id) override;
+ virtual void stream_sink_update(uint32_t id, const int16_t *buffer, int samples_this_frame) override;
+ virtual void stream_source_update(uint32_t id, int16_t *buffer, int samples_this_frame) override;
+
+Streams are the concept used to send or receive audio from/to the host
+audio system. A stream is first opened through *stream_sink_open* for
+speakers and *stream_source_open* for microphones and targets a
+specific node at a specific sample rate. It is given a name for use
+by the host sound services for user UI purposes (currently the game
+name if split_streams_per_source is false, the
+speaker_device/microphone_device tag if true). The returned ID must
+be a non-zero, never-used-before for streams value in case of success.
+Failures, like when the node went away between the *get_information*
+call and the open one, should be silent and return zero.
+
+*stream_set_volumes* is used only when *external_per_channel_volume*
+is true and is used by the core to set the per-channel volume. The
+call should just be ignored if the stream ID does not exist (or is
+zero). Do not try to apply volumes in the module if the host API
+doesn't provide for it, let the core handle it.
+
+*stream_close* closes a stream, The call should just be ignored if the
+stream ID does not exist (or is zero).
+
+Opening a stream, closing a stream or changing the volume does not
+need to touch the generation number.
+
+*stream_sink_update* is the method used to send data to the node
+through a given stream. It provides a buffer of *samples_this_frame*
+* *node channel count* channel-interleaved int16_t values. The
+lifetime of the data in the buffer or the buffer pointer itself is
+undefined after return from the method call. The call should just be
+ignored if the stream ID does not exist (or is zero).
+
+*stream_source_update* is the equivalent to retrieve data from a node,
+writing to the buffer instead of reading from it. The constraints are
+identical.
+
+When a stream goes away because the target node is lost it should just
+be removed from the information, and the core will pick up the node
+departure and close the stream.
+
+Given the assumed raceness of the interface, all the methods should be
+tolerant of obsolete or zero IDs being used by the core, and that is
+why ID reuse must be avoided. Also the update methods and the
+open/close/volume ones may be called at the same time in different
+threads.
+
+
+Helper class *abuffer*
+~~~~~~~~~~~~~~~~~~~~~~
+
+.. code-block:: C++
+
+ class abuffer {
+ public:
+ abuffer(uint32_t channels);
+ void get(int16_t *data, uint32_t samples);
+ void push(const int16_t *data, uint32_t samples);
+ uint32_t channels() const;
+ };
+
+The class *abuffer* is a helper provided by *sound_module* to buffer
+audio input or output. It automatically drops data when there is
+an overflow and duplicates the last sample on underflow. It must
+first be initialized with the number of channels, which can be
+retrieved with *channels()* if needed. *push* sends
+*samples* * *channels* 16-bit samples in the buffer. *get* retrieves
+*samples* * *channels* 16-bit samples from the buffer, on a FIFO basis.
+
+It is not protected against multithreading, but uses no class
+variables. So just don't read and write from one specific abuffer
+instance at the same time. The system sound interface mandated
+locking should be enough to ensure that.
diff --git a/docs/source/techspecs/poly_manager.rst b/docs/source/techspecs/poly_manager.rst
new file mode 100644
index 00000000000..d30a57c39c3
--- /dev/null
+++ b/docs/source/techspecs/poly_manager.rst
@@ -0,0 +1,1084 @@
+Software 3D Rendering in MAME
+=============================
+
+.. contents:: :local:
+
+
+Background
+----------
+
+Beginning in the late 1980s, many arcade games began incorporating hardware-rendered
+3D graphics into their video. These 3D graphics are typically rendered from low-level
+primitives into a frame buffer (usually double- or triple-buffered), then perhaps
+combined with traditional tilemaps or sprites, before being presented to the player.
+
+When it comes to emulating 3D games, there are two general approaches. The first
+approach is to leverage modern 3D hardware by mapping the low-level primitives onto
+modern equivalents. For a cross-platform emulator like MAME, this requires having an
+API that is flexible enough to describe the primitives and all their associated
+behaviors with high accuracy. It also requires the emulator to be able to read back
+from the rendered frame buffer (since many games do this) and combine it with other
+elements, in a way that is properly synchronized with background rendering.
+
+The alternative approach is to render the low-level primitives directly in software.
+This has the advantage of being able to achieve pretty much any behavior exhibited by
+the original hardware, but at the cost of speed. In MAME, since all emulation happens
+on one thread, this is particularly painful. However, just as with the 3D hardware
+approach, in theory a software-based approach could be spun off to other threads to
+handle the work, as long as mechanisms were present to synchronize when necessary,
+for example, when reading/writing directly to/from the frame buffer.
+
+For the time being, MAME has opted for the second approach, leveraging a templated
+helper class called **poly_manager** to handle common situations.
+
+
+Concepts
+--------
+
+At its core, **poly_manager** is a mechanism to support multi-threaded rendering of
+low-level 3D primitives. Callers provide **poly_manager** with a set of *vertices* for a
+primitive plus a *render callback*. **poly_manager** breaks the primitive into
+clipped scanline *extents* and distributes the work among a pool of *worker
+threads*. The render callback is then called on the worker thread for each extent,
+where game-specific logic can do whatever needs to happen to render the data.
+
+One key responsibility that **poly_manager** takes care of is ensuring order. Given a
+pool of threads and a number of work items to complete, it is important that—at least
+within a given scanline—all work is performed serially in order. The basic approach is
+to assign each extent to a *bucket* based on the Y coordinate. **poly_manager** then ensures
+that only one worker thread at a time is responsible for processing work in a given bucket.
+
+Vertices in **poly_manager** consist of simple 2D X and Y *coordinates*, plus zero or
+more additional *iterated parameters*. These iterated parameters can be anything: intensity
+values for lighting; RGB(A) colors for Gouraud shading; normalized U, V coordinates for
+texture mapping; 1/Z values for Z buffering; etc. Iterated parameters, regardless of what
+they represent, are interpolated linearly across the primitive in screen space and provided
+as part of the extent to the render callback.
+
+
+ObjectType
+~~~~~~~~~~
+
+When creating a **poly_manager** class, you must provide it a special type that you define,
+known as **ObjectType**.
+
+Because rendering happens asynchronously on worker threads, the idea is that the
+**ObjectType** class will hold a snapshot of all the relevant data needed for rendering.
+This allows the main thread to proceed—potentially modifying some of the relevant state—while
+rendering happens elsewhere.
+
+In theory, we could allocate a new **ObjectType** class for each primitive rendered;
+however, that would be rather inefficient. It is quite common to set up the rendering
+state and then render several primitives using the same state.
+
+For this reason, **poly_manager** maintains an internal array of **ObjectType** objects and
+keeps a copy of the last **ObjectType** used. Before submitting a new primitive, callers
+can see if the rendering state has changed. If it has, it can ask **poly_manager** to allocate
+a new **ObjectType** class and fill it in. When the primitive is submitted for rendering, the
+most recently allocated **ObjectType** instance is implicitly captured and provided to the
+render callbacks.
+
+For more complex scenarios, where data might change even more infrequently, there is a
+**poly_array** template, which can be used to manage data in a similar way. In fact,
+internally **poly_manager** uses the **poly_array** class to manage its **ObjectType**
+allocations. More information on the **poly_array** class is provided later.
+
+
+
+Primitives
+~~~~~~~~~~
+
+**poly_manager** supports several different types of primitives:
+
+* The most commonly-used primitive in **poly_manager** is the *triangle*, which has the
+ nice property that iterated parameters have constant deltas across the full surface.
+ Arbitrary-length *triangle fans* and *triangle strips* are also supported.
+
+* In addition to triangles, **poly_manager** also supports *polygons* with an arbitrary
+ number of vertices. The list of vertices is expected to be in either clockwise or
+ anticlockwise order. **poly_manager** will walk the edges to compute deltas across
+ each extent.
+
+* As a special case, **poly_manager** supports a *tile* primitive, which is a simple quad
+ defined by two vertices, a top-left vertex and a bottom-right vertex. Like triangles,
+ tiles have constant iterated parameter deltas across their surface.
+
+* Finally, **poly_manager** supports a fully custom mechanism where the caller provides
+ a list of extents that are more or less fed directly to the worker threads.
+ This is useful if emulating a system that has unusual primitives or requires highly
+ specific behaviors for its edges.
+
+
+Synchronization
+~~~~~~~~~~~~~~~
+
+One of the key requirements of providing an asynchronous rendering mechanism is
+synchronization. Synchronization in **poly_manager** is super simple: just
+call the ``wait()`` function.
+
+There are several common reasons for issuing a wait:
+
+* At display time, the pixel data must be copied to the screen. If any primitives were
+ queued which touch the portion of the display that is going to be shown, you need to
+ wait for rendering to be complete before copying. Note that this wait may not be
+ strictly necessary in some situations (for example, a triple-buffered system).
+
+* If the emulated system has a mechanism to read back from the framebuffer after
+ rendering, then a wait must be issued prior to the read in order to ensure that
+ asynchronous rendering is complete.
+
+* If the emulated system modifies any state that is not cached in the **ObjectType**
+ or elsewhere (for example, texture memory), then a wait must be issued to ensure
+ that pending primitives which might consume that state have finished their work.
+
+* If the emulated system can use a previous render target as, say, the texture source
+ for a new primitive, then submitting the second primitive must wait until the first
+ completes. **poly_manager** provides no internal mechanism to help detect this, so it
+ is on the caller to determine when or if this is necessary.
+
+Because the wait operation knows after it is done that all rendering is complete,
+**poly_manager** also takes this opportunity to reclaim all memory allocated for its
+internal structures, as well as memory allocated for **ObjectType** structures. Thus it is
+important that you don’t hang onto any **ObjectType** pointers after a wait is called.
+
+
+The poly_manager class
+----------------------
+
+In most applications, **poly_manager** is not used directly, but rather serves as
+the base class for a more complete rendering class. The **poly_manager** class
+itself is a template::
+
+ template<typename BaseType, class ObjectType, int MaxParams, u8 Flags = 0>
+ class poly_manager;
+
+and the template parameters are:
+
+* **BaseType** is the type used internally for coordinates and iterated parameters, and
+ should generally be either ``float`` or ``double``. In theory, a fixed-point integral
+ type could also be used, though the math logic has not been designed for that, so you
+ may encounter problems.
+
+* **ObjectType** is the user-defined per-object data structure described above.
+ Internally, **poly_manager** will manage a **poly_array** of these, and a pointer to
+ the most-recently allocated one at the time a primitive is submitted will be implicitly
+ passed to the render callback for each corresponding extent.
+
+* **MaxParams** is the maximum number of iterated parameters that may be specified in a
+ vertex. Iterated parameters are generic and treated identically, so the mapping of
+ parameter indices is completely up to the contract between the caller and the render
+ callback. It is permitted for **MaxParams** to be 0.
+
+* **Flags** is zero or more of the following flags:
+
+ - POLY_FLAG_NO_WORK_QUEUE — specify this flag to disable asynchronous rendering; this
+ can be useful for debugging. When this option is enabled, all primitives are queued
+ and then processed in order on the calling thread when ``wait()`` is called on the
+ **poly_manager** class.
+
+ - POLY_FLAG_NO_CLIPPING — specify this if you want **poly_manager** to skip its
+ internal clipping. Use this if your render callbacks do their own clipping, or if
+ the caller always handles clipping prior to submitting primitives.
+
+
+Types & Constants
+~~~~~~~~~~~~~~~~~
+
+vertex_t
+++++++++
+
+Within the **poly_manager** class, you’ll find a **vertex_t** type that describes a
+single vertex. All primitive drawing methods accept 2 or more of these **vertex_t**
+objects. The **vertex_t** includes the X and Y coordinates along with an array of
+iterated parameter values at that vertex::
+
+ struct vertex_t
+ {
+ vertex_t() { }
+ vertex_t(BaseType _x, BaseType _y) { x = _x; y = _y; }
+
+ BaseType x, y; // X, Y coordinates
+ std::array<BaseType, MaxParams> p; // iterated parameters
+ };
+
+Note that **vertex_t** itself is defined in terms of the **BaseType** and **MaxParams**
+template values of the owning **poly_manager** class.
+
+All of **poly_manager**’s primitives operate in screen space, where (0,0) represents the
+top-left corner of the top-left pixel, and (0.5,0.5) represents the center of that pixel.
+Left and top pixel values are inclusive, while right and bottom pixel values are exclusive.
+
+Thus, a *tile* rendered from (2,2)-(4,3) will completely cover 2 pixels: (2,2) and (3,2).
+
+When calling a primitive drawing method, the iterated parameter array **p** need not be
+completely filled out. The number of valid iterated parameter values is specified as a
+template parameter to the primitive drawing methods, so only that many parameters need to
+actually be populated in the **vertex_t** structures that are passed in.
+
+
+extent_t
+++++++++
+
+**poly_manager** breaks primitives into extents, which are contiguous horizontal spans
+contained within a single scanline. These extents are then distributed to worker threads,
+who will call the render callback with information on how to render each extent. The
+**extent_t** type describes one such extent, providing the bounding X coordinates along with
+an array of iterated parameter start values and deltas across the span::
+
+ struct extent_t
+ {
+ struct param_t
+ {
+ BaseType start; // parameter value at start
+ BaseType dpdx; // dp/dx relative to start
+ };
+ int16_t startx, stopx; // starting (inclusive)/ending (exclusive) endpoints
+ std::array<param_t, MaxParams> param; // array of parameter start/deltas
+ void *userdata; // custom per-span data
+ };
+
+For each iterated parameter, the **start** value contains the value at the left side of
+the span. The **dpdx** value contains the change of the parameter’s value per X coordinate.
+
+There is also a **userdata** field in the **extent_t** structure, which is not normally used,
+except when performing custom rendering.
+
+
+render_delegate
++++++++++++++++
+
+When rendering a primitive, in addition to the vertices, you must also provide a
+**render_delegate** callback of the form::
+
+ void render(int32_t y, extent_t const &extent, ObjectType const &object, int threadid)
+
+This callback is responsible for the actual rendering. It will be called at a later time,
+likely on a different thread, for each extent. The parameters passed are:
+
+* **y** is the Y coordinate (scanline) of the current extent.
+
+* **extent** is a reference to a **extent_t** structure, described above, which specifies for
+ this extent the start/stop X values along with the start/delta values for each iterated
+ parameter.
+
+* **object** is a reference to the most recently allocated **ObjectType** at the time the
+ primitive was submitted for rendering; in theory it should contain most of not all of the
+ necessary data to perform rendering.
+
+* **threadid** is a unique ID indicating the index of the thread you’re running on; this value
+ is useful if you are keeping any kind of statistics and don’t want to add contention over
+ shared values. In this situation, you can allocate **WORK_MAX_THREADS** instances of your
+ data and update the instance for the **threadid** you are passed. When you want to display
+ the statistics, the main thread can accumulate and reset the data from all threads when it’s
+ safe to do so (e.g., after a wait).
+
+
+Methods
+~~~~~~~
+
+poly_manager
+++++++++++++
+::
+
+ poly_manager(running_machine &machine);
+
+The **poly_manager** constructor takes just one parameter, a reference to the
+**running_machine**. This grants **poly_manager** access to the work queues needed for
+multithreaded running.
+
+wait
+++++
+::
+
+ void wait(char const *debug_reason = "general");
+
+Calling ``wait()`` stalls the calling thread until all outstanding rendering is complete:
+
+* **debug_reason** is an optional parameter specifying the reason for the wait. It is
+ useful if the compile-time constant **TRACK_POLY_WAITS** is enabled, as it will print a
+ summary of wait times and reasons at the end of execution.
+
+**Return value:** none.
+
+object_data
++++++++++++
+::
+
+ objectdata_array &object_data();
+
+This method just returns a reference to the internally-maintained **poly_array** of the
+**ObjectType** you specified when creating **poly_manager**. For most applications, the
+only interesting thing to do with this object is call the ``next()`` method to allocate
+a new object to fill out.
+
+**Return value:** reference to a **poly_array** of **ObjectType**.
+
+register_poly_array
++++++++++++++++++++
+::
+
+ void register_poly_array(poly_array_base &array);
+
+For advanced applications, you may choose to create your own **poly_array** objects to
+manage large chunks of infrequently-changed data, such a palettes. After each ``wait()``,
+**poly_manager** resets all the **poly_array** objects it knows about in order to reclaim all
+outstanding allocated memory. By registering your **poly_array** objects here, you can ensure
+that your arrays will also be reset after an ``wait()`` call.
+
+**Return value:** none.
+
+render_tile
++++++++++++
+::
+
+ template<int ParamCount>
+ uint32_t render_tile(rectangle const &cliprect, render_delegate callback,
+ vertex_t const &v1, vertex_t const &v2);
+
+This method enqueues a single *tile* primitive for rendering:
+
+* **ParamCount** is the number of live values in the iterated parameter array within each
+ **vertex_t** provided; it must be no greater than the **MaxParams** value specified in the
+ **poly_manager** template instantiation.
+
+* **cliprect** is a reference to a clipping rectangle. All pixels and parameter values are
+ clipped to stay within these bounds before being added to the work queues for rendering,
+ unless **POLY_FLAG_NO_CLIPPING** was specified as a flag parameter to **poly_manager**.
+
+* **callback** is the render callback delegate that will be called to render each extent.
+
+* **v1** contains the coordinates and iterated parameters for the top-left corner of the tile.
+
+* **v2** contains the coordinates and iterated parameters for the bottom-right corner of the tile.
+
+**Return value:** the total number of clipped pixels represented by the enqueued extents.
+
+render_triangle
++++++++++++++++
+::
+
+ template<int ParamCount>
+ uint32_t render_triangle(rectangle const &cliprect, render_delegate callback,
+ vertex_t const &v1, vertex_t const &v2, vertex_t const &v3);
+
+This method enqueues a single *triangle* primitive for rendering:
+
+* **ParamCount** is the number of live values in the iterated parameter array within each
+ **vertex_t** provided; it must be no greater than the **MaxParams** value specified in the
+ **poly_manager** template instantiation.
+
+* **cliprect** is a reference to a clipping rectangle. All pixels and parameter values are
+ clipped to stay within these bounds before being added to the work queues for rendering,
+ unless **POLY_FLAG_NO_CLIPPING** was specified as a flag parameter to **poly_manager**.
+
+* **callback** is the render callback delegate that will be called to render each extent.
+
+* **v1**, **v2**, **v3** contain the coordinates and iterated parameters for each vertex
+ of the triangle.
+
+**Return value:** the total number of clipped pixels represented by the enqueued extents.
+
+render_triangle_fan
++++++++++++++++++++
+::
+
+ template<int ParamCount>
+ uint32_t render_triangle_fan(rectangle const &cliprect, render_delegate callback,
+ int numverts, vertex_t const *v);
+
+This method enqueues one or more *triangle* primitives for rendering, specified in fan order:
+
+* **ParamCount** is the number of live values in the iterated parameter array within each
+ **vertex_t** provided; it must be no greater than the **MaxParams** value specified in the
+ **poly_manager** template instantiation.
+
+* **cliprect** is a reference to a clipping rectangle. All pixels and parameter values are
+ clipped to stay within these bounds before being added to the work queues for rendering,
+ unless **POLY_FLAG_NO_CLIPPING** was specified as a flag parameter to **poly_manager**.
+
+* **callback** is the render callback delegate that will be called to render each extent.
+
+* **numverts** is the total number of vertices provided; it must be at least 3.
+
+* **v** is a pointer to an array of **vertex_t** objects containing the coordinates and iterated
+ parameters for all the triangles, in fan order. This means that the first vertex is fixed.
+ So if 5 vertices are provided, indicating 3 triangles, the vertices used will be:
+ (0,1,2) (0,2,3) (0,3,4)
+
+**Return value:** the total number of clipped pixels represented by the enqueued extents.
+
+render_triangle_strip
++++++++++++++++++++++
+::
+
+ template<int ParamCount>
+ uint32_t render_triangle_strip(rectangle const &cliprect, render_delegate callback,
+ int numverts, vertex_t const *v);
+
+This method enqueues one or more *triangle* primitives for rendering, specified in strip order:
+
+* **ParamCount** is the number of live values in the iterated parameter array within each
+ **vertex_t** provided; it must be no greater than the **MaxParams** value specified in the
+ **poly_manager** template instantiation.
+
+* **cliprect** is a reference to a clipping rectangle. All pixels and parameter values are
+ clipped to stay within these bounds before being added to the work queues for rendering,
+ unless **POLY_FLAG_NO_CLIPPING** was specified as a flag parameter to **poly_manager**.
+
+* **callback** is the render callback delegate that will be called to render each extent.
+
+* **numverts** is the total number of vertices provided; it must be at least 3.
+
+* **v** is a pointer to an array of **vertex_t** objects containing the coordinates and iterated
+ parameters for all the triangles, in strip order.
+ So if 5 vertices are provided, indicating 3 triangles, the vertices used will be:
+ (0,1,2) (1,2,3) (2,3,4)
+
+**Return value:** the total number of clipped pixels represented by the enqueued extents.
+
+render_polygon
+++++++++++++++
+::
+
+ template<int NumVerts, int ParamCount>
+ uint32_t render_polygon(rectangle const &cliprect, render_delegate callback, vertex_t const *v);
+
+This method enqueues a single *polygon* primitive for rendering:
+
+* **NumVerts** is the number of vertices in the polygon.
+
+* **ParamCount** is the number of live values in the iterated parameter array within each
+ **vertex_t** provided; it must be no greater than the **MaxParams** value specified in the
+ **poly_manager** template instantiation.
+
+* **cliprect** is a reference to a clipping rectangle. All pixels and parameter values are
+ clipped to stay within these bounds before being added to the work queues for rendering,
+ unless **POLY_FLAG_NO_CLIPPING** was specified as a flag parameter to **poly_manager**.
+
+* **callback** is the render callback delegate that will be called to render each extent.
+
+* **v** is a pointer to an array of **vertex_t** objects containing the coordinates and iterated
+ parameters for the polygon. Vertices are assumed to be in either clockwise or anticlockwise
+ order.
+
+**Return value:** the total number of clipped pixels represented by the enqueued extents.
+
+render_extents
+++++++++++++++
+::
+
+ template<int ParamCount>
+ uint32_t render_extents(rectangle const &cliprect, render_delegate callback,
+ int startscanline, int numscanlines, extent_t const *extents);
+
+This method enqueues custom extents directly:
+
+* **ParamCount** is the number of live values in the iterated parameter array within each
+ **vertex_t** provided; it must be no greater than the **MaxParams** value specified in the
+ **poly_manager** template instantiation.
+
+* **cliprect** is a reference to a clipping rectangle. All pixels and parameter values are
+ clipped to stay within these bounds before being added to the work queues for rendering,
+ unless **POLY_FLAG_NO_CLIPPING** was specified as a flag parameter to **poly_manager**.
+
+* **callback** is the render callback delegate that will be called to render each extent.
+
+* **startscanline** is the Y coordinate of the first extent provided.
+
+* **numscanlines** is the number of extents provided.
+
+* **extents** is a pointer to an array of **extent_t** objects containing the start/stop
+ X coordinates and iterated parameters. The **userdata** field of the source extents is
+ copied to the target as well (this field is otherwise unused for all other types of
+ rendering).
+
+**Return value:** the total number of clipped pixels represented by the enqueued extents.
+
+zclip_if_less
++++++++++++++
+::
+
+ template<int ParamCount>
+ int zclip_if_less(int numverts, vertex_t const *v, vertex_t *outv, BaseType clipval);
+
+This method is a helper method to clip a polygon against a provided Z value. It assumes
+that the first iterated parameter in **vertex_t** represents the Z coordinate. If any edge
+crosses the Z plane represented by **clipval** that edge is clipped.
+
+* **ParamCount** is the number of live values in the iterated parameter array within each
+ **vertex_t** provided; it must be no greater than the **MaxParams** value specified in the
+ **poly_manager** template instantiation.
+
+* **numverts** is the number of vertices in the input array.
+
+* **v** is a pointer to the input array of **vertex_t** objects.
+
+* **outv** is a pointer to the output array of **vertex_t** objects. **v** and **outv**
+ cannot overlap or point to the same memory.
+
+* **clipval** is the value to compare parameter 0 against for clipping.
+
+**Return value:** the number of output vertices written to **outv**.
+Note that by design it is possible for this method to produce more vertices than the
+input array, so callers should ensure there is enough room in the output buffer to
+accommodate this.
+
+
+Example Renderer
+----------------
+
+Here is a complete example of how to create a software 3D renderer using **poly_manager**.
+Our example renderer will only handle flat and Gouraud-shaded triangles with depth (Z)
+buffering.
+
+
+Types
+~~~~~
+
+The first thing we need to define is our *externally-visible* vertex format, which is distinct
+from the internal **vertex_t** that **poly_manager** will define. In theory you could
+use **vertex_t** directly, but the generic nature of **poly_manager**’s iterated parameters
+make it awkward::
+
+ struct example_vertex
+ {
+ float x, y, z; // X,Y,Z coordinates
+ rgb_t color; // color at this vertex
+ };
+
+Next we define the **ObjectType** needed by **poly_manager**. For our simple case, we
+define an **example_object_data** struct that consists of pointers to our rendering buffers,
+plus a couple of fixed values that are consumed in some cases. More complex renderers would
+typically have many more object-wide parameters defined here::
+
+ struct example_object_data
+ {
+ bitmap_rgb32 *dest; // pointer to the rendering bitmap
+ bitmap_ind16 *depth; // pointer to the depth bitmap
+ rgb_t color; // overall color (for clearing and flat shaded case)
+ uint16_t depthval; // fixed depth v alue (for clearing)
+ };
+
+Now it’s time to define our renderer class, which we derive from **poly_manager**. As
+template parameters we specify ``float`` as the base type for our data, since that will
+be enough accuracy for this example, and we also provide our **example_object_data** as
+the **ObjectType** class, plus the maximum number of iterated parameters our renderer
+will ever need (4 in this case)::
+
+ class example_renderer : public poly_manager<float, example_object_data, 4>
+ {
+ public:
+ example_renderer(running_machine &machine, uint32_t width, uint32_t height);
+
+ bitmap_rgb32 *swap_buffers();
+
+ void clear_buffers(rgb_t color, uint16_t depthval);
+ void draw_triangle(example_vertex const *verts);
+
+ private:
+ static uint16_t ooz_to_depthval(float ooz);
+
+ void draw_triangle_flat(example_vertex const *verts);
+ void draw_triangle_gouraud(example_vertex const *verts);
+
+ void render_clear(int32_t y, extent_t const &extent, example_object_data const &object, int threadid);
+ void render_flat(int32_t y, extent_t const &extent, example_object_data const &object, int threadid);
+ void render_gouraud(int32_t y, extent_t const &extent, example_object_data const &object, int threadid);
+
+ int m_draw_buffer;
+ bitmap_rgb32 m_display[2];
+ bitmap_ind16 m_depth;
+ };
+
+
+Constructor
+~~~~~~~~~~~
+
+The constructor for our example renderer just initializes **poly_manager** and allocates
+the rendering and depth buffers::
+
+ example_renderer::example_renderer(running_machine &machine, uint32_t width, uint32_t height) :
+ poly_manager(machine),
+ m_draw_buffer(0)
+ {
+ // allocate two display buffers and a depth buffer
+ m_display[0].allocate(width, height);
+ m_display[1].allocate(width, height);
+ m_depth.allocate(width, height);
+ }
+
+
+swap_buffers
+~~~~~~~~~~~~
+
+The first interesting method in our renderer is ``swap_buffers()``, which returns a pointer to
+the buffer we’ve been drawing to, and sets up the other buffer as the new drawing target. The
+idea is that the display update handler will call this method to get ahold of the bitmap to
+display to the user::
+
+ bitmap_rgb32 *example_renderer::swap_buffers()
+ {
+ // wait for any rendering to complete before returning the buffer
+ wait("swap_buffers");
+
+ // return the current draw buffer and then switch to the other
+ // for future drawing
+ bitmap_rgb32 *result = &m_display[m_draw_buffer];
+ m_draw_buffer ^= 1;
+ return result;
+ }
+
+The most important thing here to note here is the call to **poly_manager**’s ``wait()``, which
+will block the current thread until all rendering is complete. This is important because
+otherwise the caller may receive a bitmap that is still being drawn to, leading to torn
+or corrupt visuals.
+
+
+clear_buffers
+~~~~~~~~~~~~~
+
+One of the most common operations to perform when doing 3D rendering is to initialize or
+clear the display and depth buffers to a known value. This method below leverages
+the *tile* primitive to render a rectangle over the screen by passing in (0,0) and (width,height)
+for the two vertices.
+
+Because the color and depth values to clear the buffer to are constant, they are stored in
+a freshly-allocated **example_object_data** object, along with a pointer to the buffers in
+question. The ``render_tile()`` call is made with a ``<0>`` suffix indicating that there are
+no iterated parameters to worry about::
+
+ void example_renderer::clear_buffers(rgb_t color, uint16_t depthval)
+ {
+ // allocate object data and populate it with information needed
+ example_object_data &object = object_data().next();
+ object.dest = &m_display[m_draw_buffer];
+ object.depth = &m_depth;
+ object.color = color;
+ object.depthval = depthval;
+
+ // top,left coordinate is always (0,0)
+ vertex_t topleft;
+ topleft.x = 0;
+ topleft.y = 0;
+
+ // bottom,right coordinate is (width,height)
+ vertex_t botright;
+ botright.x = m_display[0].width();
+ botright.y = m_display[0].height();
+
+ // render as a tile with 0 iterated parameters
+ render_tile<0>(m_display[0].cliprect(),
+ render_delegate(&example_renderer::render_clear, this),
+ topleft, botright);
+ }
+
+The render callback provided to ``render_tile()`` is also defined (privately) in our class,
+and handles a single span. Note how the rendering parameters are extracted from the
+**example_object_data** struct provided::
+
+ void example_renderer::render_clear(int32_t y, extent_t const &extent, example_object_data const &object, int threadid)
+ {
+ // get pointers to the start of the depth buffer and destination scanlines
+ uint16_t *depth = &object.depth->pix(y);
+ uint32_t *dest = &object.dest->pix(y);
+
+ // loop over the full extent and just store the constant values from the object
+ for (int x = extent.startx; x < extent.stopx; x++)
+ {
+ dest[x] = object.color;
+ depth[x] = object.depthval;
+ }
+ }
+
+Another important point to make is that the X coordinates provided by extent struct are
+inclusive of startx but exclusive of stopx. Clipping is performed ahead of time so that
+the render callback can focus on laying down pixels as quickly as possible with minimal
+overhead.
+
+
+draw_triangle
+~~~~~~~~~~~~~
+
+Next up, we have our actual triangle rendering function, which will draw a single triangle
+given an array of three vertices provided in the external **example_vertex** format::
+
+ void example_renderer::draw_triangle(example_vertex const *verts)
+ {
+ // flat shaded case
+ if (verts[0].color == verts[1].color && verts[0].color == verts[2].color)
+ draw_triangle_flat(verts);
+ else
+ draw_triangle_gouraud(verts);
+ }
+
+Because it is simpler and faster to render a flat shaded triangle, the code checks to see
+if the colors are the same on all three vertices. If they are, we call through to a special
+flat-shaded case, otherwise we process it as a full Gouraud-shaded triangle.
+
+This is a common technique to optimize rendering performance: identify special cases that
+reduce the per-pixel work, and route them to separate render callbacks that are optimized
+for that special case.
+
+
+draw_triangle_flat
+~~~~~~~~~~~~~~~~~~
+
+Here’s the setup code for rendering a flat-shaded triangle::
+
+ void example_renderer::draw_triangle_flat(example_vertex const *verts)
+ {
+ // allocate object data and populate it with information needed
+ example_object_data &object = object_data().next();
+ object.dest = &m_display[m_draw_buffer];
+ object.depth = &m_depth;
+
+ // in this case the color is constant and specified in the object data
+ object.color = verts[0].color;
+
+ // copy X, Y, and 1/Z into poly_manager vertices
+ vertex_t v[3];
+ for (int vertnum = 0; vertnum < 3; vertnum++)
+ {
+ v[vertnum].x = verts[vertnum].x;
+ v[vertnum].y = verts[vertnum].y;
+ v[vertnum].p[0] = 1.0f / verts[vertnum].z;
+ }
+
+ // render the triangle with 1 iterated parameter (1/Z)
+ render_triangle<1>(m_display[0].cliprect(),
+ render_delegate(&example_renderer::render_flat, this),
+ v[0], v[1], v[2]);
+ }
+
+First, we put the fixed color into the **example_object_data** directly, and then fill
+out three **vertex_t** objects with the X and Y coordinates in the usual spot, and 1/Z
+as our one and only iterated parameter. (We use 1/Z here because iterated parameters are
+interpolated linearly in screen space. Z is not linear in screen space, but 1/Z is due to
+perspective correction.)
+
+Our flat-shaded case then calls ``render_trangle`` specifying ``<1>`` iterated parameter to
+interpolate, and pointing to a special-case flat render callback::
+
+ void example_renderer::render_flat(int32_t y, extent_t const &extent, example_object_data const &object, int threadid)
+ {
+ // get pointers to the start of the depth buffer and destination scanlines
+ uint16_t *depth = &object.depth->pix(y);
+ uint32_t *dest = &object.dest->pix(y);
+
+ // get the starting 1/Z value and the delta per X
+ float ooz = extent.param[0].start;
+ float doozdx = extent.param[0].dpdx;
+
+ // iterate over the extent
+ for (int x = extent.startx; x < extent.stopx; x++)
+ {
+ // convert the 1/Z value into an integral depth value
+ uint16_t depthval = ooz_to_depthval(ooz);
+
+ // if closer than the current pixel, copy the color and depth value
+ if (depthval < depth[x])
+ {
+ dest[x] = object.color;
+ depth[x] = depthval;
+ }
+
+ // regardless, update the 1/Z value for the next pixel
+ ooz += doozdx;
+ }
+ }
+
+This render callback is a bit more involved than the clearing case.
+
+First, we have an iterated parameter (1/Z) to deal with, whose starting and X-delta
+values we extract from the extent before the start of the inner loop.
+
+Second, we perform depth buffer testing, using ``ooz_to_depthval()`` as a helper
+to transform the floating-point 1/Z value into a 16-bit integer. We compare this value against
+the current depth buffer value, and only store the pixel/depth value if it’s less.
+
+At the end of each iteration, we advance the 1/Z value by the X-delta in preparation for the
+next pixel.
+
+
+draw_triangle_gouraud
+~~~~~~~~~~~~~~~~~~~~~
+
+Finally we get to the code for the full-on Gouraud-shaded case::
+
+ void example_renderer::draw_triangle_gouraud(example_vertex const *verts)
+ {
+ // allocate object data and populate it with information needed
+ example_object_data &object = object_data().next();
+ object.dest = &m_display[m_draw_buffer];
+ object.depth = &m_depth;
+
+ // copy X, Y, 1/Z, and R,G,B into poly_manager vertices
+ vertex_t v[3];
+ for (int vertnum = 0; vertnum < 3; vertnum++)
+ {
+ v[vertnum].x = verts[vertnum].x;
+ v[vertnum].y = verts[vertnum].y;
+ v[vertnum].p[0] = 1.0f / verts[vertnum].z;
+ v[vertnum].p[1] = verts[vertnum].color.r();
+ v[vertnum].p[2] = verts[vertnum].color.g();
+ v[vertnum].p[3] = verts[vertnum].color.b();
+ }
+
+ // render the triangle with 4 iterated parameters (1/Z, R, G, B)
+ render_triangle<4>(m_display[0].cliprect(),
+ render_delegate(&example_renderer::render_gouraud, this),
+ v[0], v[1], v[2]);
+ }
+
+Here we have 4 iterated parameters: the 1/Z depth value, plus red, green, and blue,
+stored as floating point values. We call ``render_triangle()`` with ``<4>`` as the
+number of iterated parameters to process, and point to the full Gouraud render callback::
+
+ void example_renderer::render_gouraud(int32_t y, extent_t const &extent, example_object_data const &object, int threadid)
+ {
+ // get pointers to the start of the depth buffer and destination scanlines
+ uint16_t *depth = &object.depth->pix(y);
+ uint32_t *dest = &object.dest->pix(y);
+
+ // get the starting 1/Z value and the delta per X
+ float ooz = extent.param[0].start;
+ float doozdx = extent.param[0].dpdx;
+
+ // get the starting R,G,B values and the delta per X as 8.24 fixed-point values
+ uint32_t r = uint32_t(extent.param[1].start * float(1 << 24));
+ uint32_t drdx = uint32_t(extent.param[1].dpdx * float(1 << 24));
+ uint32_t g = uint32_t(extent.param[2].start * float(1 << 24));
+ uint32_t dgdx = uint32_t(extent.param[2].dpdx * float(1 << 24));
+ uint32_t b = uint32_t(extent.param[3].start * float(1 << 24));
+ uint32_t dbdx = uint32_t(extent.param[3].dpdx * float(1 << 24));
+
+ // iterate over the extent
+ for (int x = extent.startx; x < extent.stopx; x++)
+ {
+ // convert the 1/Z value into an integral depth value
+ uint16_t depthval = ooz_to_depthval(ooz);
+
+ // if closer than the current pixel, assemble the color
+ if (depthval < depth[x])
+ {
+ dest[x] = rgb_t(r >> 24, g >> 24, b >> 24);
+ depth[x] = depthval;
+ }
+
+ // regardless, update the 1/Z and R,G,B values for the next pixel
+ ooz += doozdx;
+ r += drdx;
+ g += dgdx;
+ b += dbdx;
+ }
+ }
+
+This follows the same pattern as the flat-shaded callback, except we have 4 iterated parameters
+to step through.
+
+Note that even though the iterated parameters are of ``float`` type, we convert the
+color values to fixed-point integers when iterating over them. This saves us doing 3
+float-to-int conversions each pixel. The original RGB values were 0-255, so interpolation
+can only produce values in the 0-255 range. Thus we can use 24 bits of a 32-bit integer as
+the fraction, which is plenty accurate for this case.
+
+
+Advanced Topic: the poly_array class
+------------------------------------
+
+**poly_array** is a template class that is used to manage a dynamically-sized vector of
+objects whose lifetime starts at allocation and ends when ``reset()`` is called. The
+**poly_manager** class uses several **poly_array** objects internally, including one for
+allocated **ObjectType** data, one for each primitive rendered, and one for holding all
+allocated extents.
+
+**poly_array** has an additional property where after a reset it retains a copy of the most
+recently allocated object. This ensures that callers can always call ``last()`` and get
+a valid object, even immediately after a reset.
+
+The **poly_array** class requires two template parameters::
+
+ template<class ArrayType, int TrackingCount>
+ class poly_array;
+
+These parameters are:
+
+* **ArrayType** is the type of object you wish to allocate and manage.
+
+* **TrackingCount** is the number of objects you wish to preserve after a reset. Typically
+ this value is either 0 (you don’t care to track any objects) or 1 (you only need one
+ object); however, if you are using **poly_array** to manage a shared collection of
+ objects across several independent consumers, it can be higher. See below for an example
+ where this might be handy.
+
+Note that objects allocated by **poly_array** are owned by **poly_array** and will be
+automatically freed upon exit.
+
+**poly_array** is optimized for use in high frequency multi-threaded systems. Therefore,
+one added feature of the class is that it rounds the allocation size of **ArrayType** to
+the nearest cache line boundary, on the assumption that neighboring entries could be
+accessed by different cores simultaneously. Keeping each **ArrayType** object in its
+own cache line ensures no false sharing performance impacts.
+
+Currently, **poly_array** has no mechanism to determine cache line size at runtime, so
+it presumes that 64 bytes is a typical cache line size, which is true for most x64 and ARM
+chips as of 2021. This value can be altered by changing the **CACHE_LINE_SHIFT** constant
+defined at the top of the class.
+
+Objects allocated by **poly_array** are created in 64k chunks. At construction time, one
+chunk’s worth of objects is allocated up front. The chunk size is controlled by the
+**CHUNK_GRANULARITY** constant defined at the top of the class.
+
+As more objects are allocated, if **poly_array** runs out of space, it will dynamically
+allocate more. This will produce discontiguous chunks of objects until the next ``reset()``
+call, at which point **poly_array** will reallocate all the objects into a contiguous
+vector once again.
+
+For the case where **poly_array** is used to manage a shared pool of objects, it can be
+configured to retain multiple most recently allocated items by using a **TrackingCount**
+greater than 1. For example, if **poly_array** is managing objects for two texture units,
+then it can set **TrackingCount** equal to 2, and pass the index of the texture unit in
+calls to ``next()`` and ``last()``. After a reset, **poly_array** will remember the most
+recently allocated object for each of the units independently.
+
+
+Methods
+~~~~~~~
+
+poly_array
+++++++++++
+::
+
+ poly_array();
+
+The **poly_array** constructor requires no parameters and simply pre-allocates one
+chunk of objects in preparation for future allocations.
+
+count
++++++
+::
+
+ u32 count() const;
+
+**Return value:** the number of objects currently allocated.
+
+max
++++
+::
+
+ u32 max() const;
+
+**Return value:** the maximum number of objects ever allocated at one time.
+
+itemsize
+++++++++
+::
+
+ size_t itemsize() const;
+
+**Return value:** the size of an object, rounded up to the nearest cache line boundary.
+
+allocated
++++++++++
+::
+
+ u32 allocated() const;
+
+**Return value:** the number of objects that fit within what’s currently been allocated.
+
+byindex
++++++++
+::
+
+ ArrayType &byindex(u32 index);
+
+Returns a reference to an object in the array by index. Equivalent to [**index**] on a
+normal array:
+
+* **index** is the index of the item you wish to reference.
+
+**Return value:** a reference to the object in question. Since a reference is returned,
+it is your responsibility to ensure that **index** is less than ``count()`` as there
+is no mechanism to return an invalid result.
+
+contiguous
+++++++++++
+::
+
+ ArrayType *contiguous(u32 index, u32 count, u32 &chunk);
+
+Returns a pointer to the base of a contiguous section of **count** items starting at
+**index**. Because **poly_array** dynamically resizes, it may not be possible to access
+all **count** objects contiguously, so the number of actually contiguous items is
+returned in **chunk**:
+
+* **index** is the index of the first item you wish to access contiguously.
+
+* **count** is the number of items you wish to access contiguously.
+
+* **chunk** is a reference to a variable that will be set to the actual number of
+ contiguous items available starting at **index**. If **chunk** is less than **count**,
+ then the caller should process the **chunk** items returned, then call ``countiguous()``
+ again at (**index** + **chunk**) to access the rest.
+
+**Return value:** a pointer to the first item in the contiguous chunk. No range checking
+is performed, so it is your responsibility to ensure that **index** + **count** is less
+than or equal to ``count()``.
+
+indexof
++++++++
+::
+
+ int indexof(ArrayType &item) const;
+
+Returns the index within the array of the given item:
+
+* **item** is a reference to an item in the array.
+
+**Return value:** the index of the item. It should always be the case that::
+
+ array.indexof(array.byindex(index)) == index
+
+reset
++++++
+::
+
+ void reset();
+
+Resets the **poly_array** by semantically deallocating all objects. If previous allocations
+created a discontiguous array, a fresh vector is allocated at this time so that future
+allocations up to the same level will remain contiguous.
+
+Note that the **ArrayType** destructor is *not* called on objects as they are deallocated.
+
+**Return value:** none.
+
+next
+++++
+::
+
+ ArrayType &next(int tracking_index = 0);
+
+Allocates a new object and returns a reference to it. If there is not enough space for
+a new object in the current array, a new discontiguous array is created to hold it:
+
+* **tracking_index** is the tracking index you wish to assign the new item to. In the
+ common case this is 0, but could be non-zero if using a **TrackingCount** greater than 1.
+
+**Return value:** a reference to the object. Note that the placement new operator is
+called on this object, so the default **ArrayType** constructor will be invoked here.
+
+last
+++++
+::
+
+ ArrayType &last(int tracking_index = 0) const;
+
+Returns a reference to the last object allocated:
+
+* **tracking_index** is the tracking index whose object you want. In the
+ common case this is 0, but could be non-zero if using a **TrackingCount** greater than 1.
+ **poly_array** remembers the most recently allocated object independently for each
+ **tracking_index**.
+
+**Return value:** a reference to the last allocated object.
diff --git a/docs/source/techspecs/uml_instructions.rst b/docs/source/techspecs/uml_instructions.rst
new file mode 100644
index 00000000000..5d379dd1c60
--- /dev/null
+++ b/docs/source/techspecs/uml_instructions.rst
@@ -0,0 +1,1582 @@
+.. _umlinst:
+
+UML Instruction Reference
+=========================
+
+.. contents::
+ :local:
+ :depth: 2
+
+
+.. _umlinst-intro:
+
+Introduction
+------------
+
+UML is the instruction set used by MAME’s recompiler framework.
+Front-ends translate code running on the guest CPUs to UML instructions,
+and back-ends convert the UML instructions to a form that can be
+executed or interpreted on the host system.
+
+
+.. _umlinst-flow:
+
+Flow control
+------------
+
+.. _umlinst-comment:
+
+COMMENT
+~~~~~~~
+
+Insert a comment into logged UML code.
+
++--------------------+---------------------------------+
+| Disassembly | Usage |
++====================+=================================+
+| .. code-block:: | .. code-block:: C++ |
+| | |
+| comment string | UML_COMMENT(block, string); |
++--------------------+---------------------------------+
+
+Operands
+^^^^^^^^
+
+string
+ The comment text as a pointer to a NUL-terminated string. This must
+ remain valid until code is generated for the block.
+
+Flags
+^^^^^
+
++---------------+------------+
+| carry (C) | Unchanged. |
++---------------+------------+
+| overflow (V) | Unchanged. |
++---------------+------------+
+| zero (Z) | Unchanged. |
++---------------+------------+
+| sign (S) | Unchanged. |
++---------------+------------+
+| unordered (U) | Unchanged. |
++---------------+------------+
+
+.. _umlinst-nop:
+
+NOP
+~~~
+
+No operation.
+
++-----------------+---------------------+
+| Disassembly | Usage |
++=================+=====================+
+| .. code-block:: | .. code-block:: C++ |
+| | |
+| nop | UML_NOP(block); |
++-----------------+---------------------+
+
+Flags
+^^^^^
+
++---------------+------------+
+| carry (C) | Unchanged. |
++---------------+------------+
+| overflow (V) | Unchanged. |
++---------------+------------+
+| zero (Z) | Unchanged. |
++---------------+------------+
+| sign (S) | Unchanged. |
++---------------+------------+
+| unordered (U) | Unchanged. |
++---------------+------------+
+
+.. _umlinst-label:
+
+LABEL
+~~~~~
+
+Associate a location with a label number local to the current generated
+code block. Label numbers must not be reused within a generated code
+block. The :ref:`JMP <umlinst-jmp>` instruction may be used to transfer
+control to the location associated with a label number.
+
++-------------------+------------------------------+
+| Disassembly | Usage |
++===================+==============================+
+| .. code-block:: | .. code-block:: C++ |
+| | |
+| label label | UML_LABEL(block, label); |
++-------------------+------------------------------+
+
+Operands
+^^^^^^^^
+
+label (label number)
+ The label number to associate with the current location. A label
+ number must not be used more than once within a generated code
+ block.
+
+Flags
+^^^^^
+
++---------------+------------+
+| carry (C) | Unchanged. |
++---------------+------------+
+| overflow (V) | Unchanged. |
++---------------+------------+
+| zero (Z) | Unchanged. |
++---------------+------------+
+| sign (S) | Unchanged. |
++---------------+------------+
+| unordered (U) | Unchanged. |
++---------------+------------+
+
+.. _umlinst-handle:
+
+HANDLE
+~~~~~~
+
+Mark a location as an entry point of a subroutine. Subroutines may be
+called using the :ref:`CALLH <umlinst-callh>` and :ref:`EXH
+<umlinst-exh>` instructions, and also by the `HASHJMP <umlinst-hashjmp>`
+if no location is associated with the specified mode and emulated
+program counter.
+
++--------------------+--------------------------------+
+| Disassembly | Usage |
++====================+================================+
+| .. code-block:: | .. code-block:: C++ |
+| | |
+| handle handle | UML_HANDLE(block, handle); |
++--------------------+--------------------------------+
+
+Operands
+^^^^^^^^
+
+handle (code handle)
+ The code handle to bind to the current location. The handle must
+ already be allocated, and must not have been bound since the last
+ generated code reset (all handles are implicitly unbound when
+ resetting the generated code cache).
+
+Flags
+^^^^^
+
++---------------+------------+
+| carry (C) | Unchanged. |
++---------------+------------+
+| overflow (V) | Unchanged. |
++---------------+------------+
+| zero (Z) | Unchanged. |
++---------------+------------+
+| sign (S) | Unchanged. |
++---------------+------------+
+| unordered (U) | Unchanged. |
++---------------+------------+
+
+.. _umlinst-hash:
+
+HASH
+~~~~
+
+Associate a location with the specified mode and emulated program
+counter values. The :ref:`HASHJMP <umlinst-hashjmp>` instruction may be
+used to transfer control to the location associated with a mode and
+emulated program counter value.
+
+This is usually used to mark the location of the generated code for an
+emulated instruction or sequence of instructions.
+
++---------------------+------------------------------+
+| Disassembly | Usage |
++=====================+==============================+
+| .. code-block:: | .. code-block:: C++ |
+| | |
+| hash mode,pc | UML_HASH(block, mode, pc); |
++---------------------+------------------------------+
+
+Operands
+^^^^^^^^
+
+mode (32-bit – immediate, map variable)
+ The mode to associate with the current location in the generated
+ code. Must be greater than or equal to zero and less than the
+ number of modes specified when creating the recompiler context.
+pc (32-bit – immediate, map variable)
+ The emulated program counter value to associate with the current
+ location in the generated code.
+
+Flags
+^^^^^
+
++---------------+------------+
+| carry (C) | Unchanged. |
++---------------+------------+
+| overflow (V) | Unchanged. |
++---------------+------------+
+| zero (Z) | Unchanged. |
++---------------+------------+
+| sign (S) | Unchanged. |
++---------------+------------+
+| unordered (U) | Unchanged. |
++---------------+------------+
+
+.. _umlinst-jmp:
+
+JMP
+~~~
+
+Jump to the location associated with a label number within the current
+block.
+
++------------------------+-----------------------------------+
+| Disassembly | Usage |
++========================+===================================+
+| .. code-block:: | .. code-block:: C++ |
+| | |
+| jmp label | UML_JMP(block, label); |
+| jmp label,cond | UML_JMPc(block, cond, label); |
++------------------------+-----------------------------------+
+
+Operands
+^^^^^^^^
+
+label (label number)
+ The label number associated with the location to jump to in the
+ current generated code block. The label number must be associated
+ with a location in the generated code block before the block is
+ finalised.
+cond (condition)
+ If supplied, a condition that must be met to jump to the specified
+ label. If the condition is not met, execution will continue with
+ the following instruction.
+
+Flags
+^^^^^
+
++---------------+------------+
+| carry (C) | Unchanged. |
++---------------+------------+
+| overflow (V) | Unchanged. |
++---------------+------------+
+| zero (Z) | Unchanged. |
++---------------+------------+
+| sign (S) | Unchanged. |
++---------------+------------+
+| unordered (U) | Unchanged. |
++---------------+------------+
+
+.. _umlinst-callh:
+
+CALLH
+~~~~~
+
+Call the subroutine beginning at the specified code handle.
+
++-------------------------+--------------------------------------+
+| Disassembly | Usage |
++=========================+======================================+
+| .. code-block:: | .. code-block:: C++ |
+| | |
+| callh handle | UML_CALLH(block, handle); |
+| callh handle,cond | UML_CALLHc(block, handle, cond); |
++-------------------------+--------------------------------------+
+
+Operands
+^^^^^^^^
+
+handle (code handle)
+ Handle located at the entry point of the subroutine to call. The
+ handle must already be allocated but does not need to be bound until
+ the instruction is executed. Calling a handle that was unbound at
+ code generation time may produce less efficient code than calling a
+ handle that was already bound.
+cond (condition)
+ If supplied, a condition that must be met for the subroutine to be
+ called. If the condition is not met, the subroutine will not be
+ called.
+
+Flags
+^^^^^
+
++---------------+------------+
+| carry (C) | Unchanged. |
++---------------+------------+
+| overflow (V) | Unchanged. |
++---------------+------------+
+| zero (Z) | Unchanged. |
++---------------+------------+
+| sign (S) | Unchanged. |
++---------------+------------+
+| unordered (U) | Unchanged. |
++---------------+------------+
+
+.. _umlinst-exh:
+
+EXH
+~~~
+
+Set the ``EXP`` register and call the subroutine beginning at the
+specified code handle. The ``EXP`` register is a 32-bit special
+function register that may be retrieved with the :ref:`GETEXP
+<umlinst-getexp>` instruction.
+
++-----------------------------+-----------------------------------------+
+| Disassembly | Usage |
++=============================+=========================================+
+| .. code-block:: | .. code-block:: C++ |
+| | |
+| exh handle,arg | UML_EXH(block, handle, arg); |
+| exh handle,arg,cond | UML_EXHc(block, handle, arg, cond); |
++-----------------------------+-----------------------------------------+
+
+Operands
+^^^^^^^^
+
+handle (code handle)
+ Handle located at the entry point of the subroutine to call. The
+ handle must already be allocated but does not need to be bound until
+ the instruction is executed. Calling a handle that was unbound at
+ code generation time may produce less efficient code than calling a
+ handle that was already bound.
+arg (32-bit – memory, integer register, immediate, map variable)
+ Value to store in the ``EXP`` register.
+cond (condition)
+ If supplied, a condition that must be met for the subroutine to be
+ called. If the condition is not met, the subroutine will not be
+ called and the ``EXP`` register will not be modified.
+
+Flags
+^^^^^
+
++---------------+------------+
+| carry (C) | Unchanged. |
++---------------+------------+
+| overflow (V) | Unchanged. |
++---------------+------------+
+| zero (Z) | Unchanged. |
++---------------+------------+
+| sign (S) | Unchanged. |
++---------------+------------+
+| unordered (U) | Unchanged. |
++---------------+------------+
+
+Simplification rules
+^^^^^^^^^^^^^^^^^^^^
+
+* Immediate values for the ``arg`` operand are truncated to 32 bits.
+
+.. _umlinst-ret:
+
+RET
+~~~
+
+Return from a subroutine, transferring control to the instruction
+following the :ref:`CALLH <umlinst-callh>` or :ref:`EXH <umlinst-exh>`
+instruction used to call the subroutine. This instruction must only be
+used within generated code subroutines. The :ref:`EXIT <umlinst-exit>`
+instruction must be used to exit from the generated code.
+
++------------------+----------------------------+
+| Disassembly | Usage |
++==================+============================+
+| .. code-block:: | .. code-block:: C++ |
+| | |
+| ret | UML_RET(block); |
+| ret cond | UML_RETc(block, cond); |
++------------------+----------------------------+
+
+Operands
+^^^^^^^^
+
+cond (condition)
+ If supplied, a condition that must be met to return from the
+ subroutine. If the condition is not met, execution will continue
+ with the following instruction.
+
+Flags
+^^^^^
+
++---------------+------------+
+| carry (C) | Unchanged. |
++---------------+------------+
+| overflow (V) | Unchanged. |
++---------------+------------+
+| zero (Z) | Unchanged. |
++---------------+------------+
+| sign (S) | Unchanged. |
++---------------+------------+
+| unordered (U) | Unchanged. |
++---------------+------------+
+
+.. _umlinst-hashjmp:
+
+HASHJMP
+~~~~~~~
+
+Unwind all nested generated code subroutine frames and transfer control
+to the location associated with the specified mode and emulated program
+counter values. If no location is associated with the specified mode
+and program counter values, call the subroutine beginning at the
+specified code handle. Note that all nested generated code subroutine
+frames are unwound in either case.
+
+This is usually used to jump to the generated code corresponding to the
+emulated code at a particular address when it is not known to be in the
+current generated code block or when the mode changes.
+
++----------------------------+-----------------------------------------+
+| Disassembly | Usage |
++============================+=========================================+
+| .. code-block:: | .. code-block:: C++ |
+| | |
+| hashjmp mode,pc,handle | UML_HASHJMP(block, mode, pc, handle); |
++----------------------------+-----------------------------------------+
+
+Operands
+^^^^^^^^
+
+mode (32-bit – memory, integer register, immediate, map variable)
+ The mode associated with the location in the generated code to
+ transfer control to. Must be greater than or equal to zero and less
+ than the number of modes specified when creating the recompiler
+ context.
+pc (32-bit – memory, integer register, immediate, map variable)
+ The emulated program counter value associated with the location in
+ the generated code to transfer control to.
+handle (code handle)
+ Handle located at the entry point of the subroutine to call if no
+ location in the generated code is associated with the specified mode
+ and emulated program counter values. The handle must already be
+ allocated but does not need to be bound until the instruction is
+ executed. Calling a handle that was unbound at code generation time
+ may produce less efficient code than calling a handle that was
+ already bound.
+
+Flags
+^^^^^
+
++---------------+------------+
+| carry (C) | Undefined. |
++---------------+------------+
+| overflow (V) | Undefined. |
++---------------+------------+
+| zero (Z) | Undefined. |
++---------------+------------+
+| sign (S) | Undefined. |
++---------------+------------+
+| unordered (U) | Undefined. |
++---------------+------------+
+
+.. _umlinst-exit:
+
+EXIT
+~~~~
+
+Exit from the generated code, returning control to the caller. May be
+used from within any level of nested subroutine calls in the generated
+code.
+
++-----------------------+----------------------------------+
+| Disassembly | Usage |
++=======================+==================================+
+| .. code-block:: | .. code-block:: C++ |
+| | |
+| exit arg, | UML_EXIT(block, arg); |
+| exit arg,,cond | UML_EXITc(block, arg, cond); |
++-----------------------+----------------------------------+
+
+Operands
+^^^^^^^^
+
+arg (32-bit – memory, integer register, immediate, map variable)
+ The value to return to the caller.
+cond (condition)
+ If supplied, a condition that must be met to exit from the generated
+ code. If the condition is not met, execution will continue with the
+ following instruction.
+
+Flags
+^^^^^
+
++---------------+------------+
+| carry (C) | Unchanged. |
++---------------+------------+
+| overflow (V) | Unchanged. |
++---------------+------------+
+| zero (Z) | Unchanged. |
++---------------+------------+
+| sign (S) | Unchanged. |
++---------------+------------+
+| unordered (U) | Unchanged. |
++---------------+------------+
+
+Simplification rules
+^^^^^^^^^^^^^^^^^^^^
+
+* Immediate values for the ``arg`` operand are truncated to 32 bits.
+
+.. _umlinst-callc:
+
+CALLC
+~~~~~
+
+Call a C function with the signature ``void (*)(void *)``.
+
++---------------------------+-----------------------------------------+
+| Disassembly | Usage |
++===========================+=========================================+
+| .. code-block:: | .. code-block:: C++ |
+| | |
+| callc func,arg | UML_CALLC(block, func, arg); |
+| callc func,arg,cond | UML_CALLCc(block, func, arg, cond); |
++---------------------------+-----------------------------------------+
+
+Operands
+^^^^^^^^
+
+func (C function)
+ Function pointer to the function to call.
+arg (memory)
+ Argument to pass to the function.
+cond (condition)
+ If supplied, a condition that must be met for the function to be
+ called. If the condition is not met, the function will not be
+ called.
+
+Flags
+^^^^^
+
++---------------+------------+
+| carry (C) | Undefined. |
++---------------+------------+
+| overflow (V) | Undefined. |
++---------------+------------+
+| zero (Z) | Undefined. |
++---------------+------------+
+| sign (S) | Undefined. |
++---------------+------------+
+| unordered (U) | Undefined. |
++---------------+------------+
+
+.. _umlinst-debug:
+
+DEBUG
+~~~~~
+
+Call the debugger instruction hook function if appropriate.
+
+If the debugger is active, this should be executed before each emulated
+instruction. Any emulated CPU state kept in UML registers should be
+flushed to memory before executing this instruction and reloaded
+afterwards to ensure the debugger can display and modify values
+correctly.
+
++-----------------+---------------------------+
+| Disassembly | Usage |
++=================+===========================+
+| .. code-block:: | .. code-block:: C++ |
+| | |
+| debug pc | UML_DEBUG(block, pc); |
++-----------------+---------------------------+
+
+Operands
+^^^^^^^^
+
+pc (32-bit – memory, integer register, immediate, map variable)
+ The emulated program counter value to supply to the debugger
+ instruction hook function.
+
+Flags
+^^^^^
+
++---------------+------------+
+| carry (C) | Undefined. |
++---------------+------------+
+| overflow (V) | Undefined. |
++---------------+------------+
+| zero (Z) | Undefined. |
++---------------+------------+
+| sign (S) | Undefined. |
++---------------+------------+
+| unordered (U) | Undefined. |
++---------------+------------+
+
+Simplification rules
+^^^^^^^^^^^^^^^^^^^^
+
+* Immediate values for the ``pc`` operand are truncated to 32 bits.
+
+.. _umlinst-break:
+
+BREAK
+~~~~~
+
+Break into the host debugger if attached. Has no effect or crashes if
+no host debugger is attached depending on the host system and
+configuration. This is intended as a developer aid and should not be
+left in final code.
+
++-----------------+-----------------------+
+| Disassembly | Usage |
++=================+=======================+
+| .. code-block:: | .. code-block:: C++ |
+| | |
+| break | UML_BREAK(block); |
++-----------------+-----------------------+
+
+Flags
+^^^^^
+
++---------------+------------+
+| carry (C) | Undefined. |
++---------------+------------+
+| overflow (V) | Undefined. |
++---------------+------------+
+| zero (Z) | Undefined. |
++---------------+------------+
+| sign (S) | Undefined. |
++---------------+------------+
+| unordered (U) | Undefined. |
++---------------+------------+
+
+
+.. _umlinst-datamove:
+
+Data movement
+-------------
+
+.. _umlinst-mov:
+
+MOV
+~~~
+
+Copy an integer value.
+
++--------------------------+---------------------------------------+
+| Disassembly | Usage |
++==========================+=======================================+
+| .. code-block:: | .. code-block:: C++ |
+| | |
+| mov dst,src | UML_MOV(block, dst, src); |
+| mov dst,src,cond | UML_MOVc(block, cond, dst, src); |
+| dmov dst,src | UML_DMOV(block, dst, src); |
+| dmov dst,src,cond | UML_DMOVc(block, cond, dst, src); |
++--------------------------+---------------------------------------+
+
+Operands
+^^^^^^^^
+
+dst (32-bit or 64-bit – memory, integer register)
+ The destination where the value will be copied to.
+src (32-bit or 64-bit – memory, integer register, immediate, map variable)
+ The source value to copy.
+cond (condition)
+ If supplied, a condition that must be met to copy the value. If the
+ condition is not met, the instruction will have no effect.
+
+Flags
+^^^^^
+
++---------------+------------+
+| carry (C) | Unchanged. |
++---------------+------------+
+| overflow (V) | Unchanged. |
++---------------+------------+
+| zero (Z) | Unchanged. |
++---------------+------------+
+| sign (S) | Unchanged. |
++---------------+------------+
+| unordered (U) | Unchanged. |
++---------------+------------+
+
+Simplification rules
+^^^^^^^^^^^^^^^^^^^^
+
+* Immediate values for the ``src`` operand are truncated to the
+ instruction size.
+* Converted to :ref:`NOP <umlinst-nop>` if the ``src`` and ``dst``
+ operands refer to the same memory location or register and the
+ instruction size is no larger than the destination size.
+
+.. _umlinst-fmov:
+
+FMOV
+~~~~
+
+Copy a floating point value. The binary value will be preserved even if
+it is not a valid representation of a floating point number.
+
++--------------------------+----------------------------------------+
+| Disassembly | Usage |
++==========================+========================================+
+| .. code-block:: | .. code-block:: C++ |
+| | |
+| fsmov dst,src | UML_FSMOV(block, dst, src); |
+| fsmov dst,src,cond | UML_FSMOVc(block, cond, dst, src); |
+| fdmov dst,src | UML_FDMOV(block, dst, src); |
+| fdmov dst,src,cond | UML_FDMOVc(block, cond, dst, src); |
++--------------------------+----------------------------------------+
+
+Operands
+^^^^^^^^
+
+dst (32-bit or 64-bit – memory, floating point register)
+ The destination where the value will be copied to.
+src (32-bit or 64-bit – memory, floating point register)
+ The source value to copy.
+cond (condition)
+ If supplied, a condition that must be met to copy the value. If the
+ condition is not met, the instruction will have no effect.
+
+Flags
+^^^^^
+
++---------------+------------+
+| carry (C) | Unchanged. |
++---------------+------------+
+| overflow (V) | Unchanged. |
++---------------+------------+
+| zero (Z) | Unchanged. |
++---------------+------------+
+| sign (S) | Unchanged. |
++---------------+------------+
+| unordered (U) | Unchanged. |
++---------------+------------+
+
+Simplification rules
+^^^^^^^^^^^^^^^^^^^^
+
+* Converted to :ref:`NOP <umlinst-nop>` if the ``src`` and ``dst``
+ operands refer to the same memory location or register.
+
+.. _umlinst-fcopyi:
+
+FCOPYI
+~~~~~~
+
+Reinterpret an integer value as a floating point value. The binary
+value will be preserved even if it is not a valid representation of a
+floating point number.
+
++---------------------+-----------------------------------+
+| Disassembly | Usage |
++=====================+===================================+
+| .. code-block:: | .. code-block:: C++ |
+| | |
+| fscopyi dst,src | UML_FSCOPYI(block, dst, src); |
+| fdcopyi dst,src | UML_FDCOPYI(block, dst, src); |
++---------------------+-----------------------------------+
+
+Operands
+^^^^^^^^
+
+dst (32-bit or 64-bit – memory, floating point register)
+ The destination where the value will be copied to.
+src (32-bit or 64-bit – memory, integer register)
+ The source value to copy.
+
+Flags
+^^^^^
+
++---------------+------------+
+| carry (C) | Unchanged. |
++---------------+------------+
+| overflow (V) | Unchanged. |
++---------------+------------+
+| zero (Z) | Unchanged. |
++---------------+------------+
+| sign (S) | Unchanged. |
++---------------+------------+
+| unordered (U) | Unchanged. |
++---------------+------------+
+
+.. _umlinst-icopyf:
+
+ICOPYF
+~~~~~~
+
+Reinterpret a floating point value as an integer value. The binary
+value will be preserved even if it is not a valid representation of a
+floating point number.
+
++---------------------+-----------------------------------+
+| Disassembly | Usage |
++=====================+===================================+
+| .. code-block:: | .. code-block:: C++ |
+| | |
+| icopyfs dst,src | UML_ICOPYFS(block, dst, src); |
+| icopyfd dst,src | UML_ICOPYFD(block, dst, src); |
++---------------------+-----------------------------------+
+
+Operands
+^^^^^^^^
+
+dst (32-bit or 64-bit – memory, integer register)
+ The destination where the value will be copied to.
+src (32-bit or 64-bit – memory, floating point register)
+ The source value to copy.
+
+Flags
+^^^^^
+
++---------------+------------+
+| carry (C) | Unchanged. |
++---------------+------------+
+| overflow (V) | Unchanged. |
++---------------+------------+
+| zero (Z) | Unchanged. |
++---------------+------------+
+| sign (S) | Unchanged. |
++---------------+------------+
+| unordered (U) | Unchanged. |
++---------------+------------+
+
+.. _umlinst-load:
+
+LOAD
+~~~~
+
+Load an unsigned integer value from a memory location with variable
+displacement. The value is zero-extended to the size of the
+destination. Host system rules for integer alignment must be followed.
+
++---------------------------------------+------------------------------------------------------+
+| Disassembly | Usage |
++=======================================+======================================================+
+| .. code-block:: | .. code-block:: C++ |
+| | |
+| load dst,base,index,size_scale | UML_LOAD(block, dst, base, index, size, scale); |
+| dload dst,base,index,size_scale | UML_DLOAD(block, dst, base, index, size, scale); |
++---------------------------------------+------------------------------------------------------+
+
+Operands
+^^^^^^^^
+
+dst (32-bit or 64-bit – memory, integer register)
+ The destination where the value read from memory will be stored.
+base (memory)
+ The base address of the area of memory to read from.
+index (32-bit – memory, integer register, immediate, map variable)
+ The displacement value added to the base address to calculate the
+ address to read from. This value may be scaled by a factor of 1, 2,
+ 4 or 8 depending on the ``scale`` operand. Note that this is always
+ a 32-bit operand interpreted as a signed integer, irrespective of
+ the instruction size.
+size (access size)
+ The size of the value to read. Must be ``SIZE_BYTE`` (8-bit),
+ ``SIZE_WORD`` (16-bit), ``SIZE_DWORD`` (32-bit) or ``SIZE_QWORD``
+ (64-bit). Note that this operand controls the size of the value
+ read from memory while the instruction size sets the size of the
+ ``dst`` operand.
+scale (index scale)
+ The scale factor to apply to the ``index`` operand. Must be
+ ``SCALE_x1``, ``SCALE_x2``, ``SCALE_x4`` or ``SCALE_x8`` to multiply
+ by 1, 2, 4 or 8, respectively (shift left by 0, 1, 2 or 3 bits).
+
+Flags
+^^^^^
+
++---------------+------------+
+| carry (C) | Unchanged. |
++---------------+------------+
+| overflow (V) | Unchanged. |
++---------------+------------+
+| zero (Z) | Unchanged. |
++---------------+------------+
+| sign (S) | Unchanged. |
++---------------+------------+
+| unordered (U) | Unchanged. |
++---------------+------------+
+
+.. _umlinst-loads:
+
+LOADS
+~~~~~
+
+Load a signed integer value from a memory location with variable
+displacement. The value is sign-extended to the size of the
+destination. Host system rules for integer alignment must be followed.
+
++---------------------------------------+-------------------------------------------------------+
+| Disassembly | Usage |
++=======================================+=======================================================+
+| .. code-block:: | .. code-block:: C++ |
+| | |
+| loads dst,base,index,size_scale | UML_LOADS(block, dst, base, index, size, scale); |
+| dloads dst,base,index,size_scale | UML_DLOADS(block, dst, base, index, size, scale); |
++---------------------------------------+-------------------------------------------------------+
+
+Operands
+^^^^^^^^
+
+dst (32-bit or 64-bit – memory, integer register)
+ The destination where the value read from memory will be stored.
+base (memory)
+ The base address of the area of memory to read from.
+index (32-bit – memory, integer register, immediate, map variable)
+ The displacement value added to the base address to calculate the
+ address to read from. This value may be scaled by a factor of 1, 2,
+ 4 or 8 depending on the ``scale`` operand. Note that this is always
+ a 32-bit operand interpreted as a signed integer, irrespective of
+ the instruction size.
+size (access size)
+ The size of the value to read. Must be ``SIZE_BYTE`` (8-bit),
+ ``SIZE_WORD`` (16-bit), ``SIZE_DWORD`` (32-bit) or ``SIZE_QWORD``
+ (64-bit). Note that this operand controls the size of the value
+ read from memory while the instruction size sets the size of the
+ ``dst`` operand.
+scale (index scale)
+ The scale factor to apply to the ``index`` operand. Must be
+ ``SCALE_x1``, ``SCALE_x2``, ``SCALE_x4`` or ``SCALE_x8`` to multiply
+ by 1, 2, 4 or 8, respectively (shift left by 0, 1, 2 or 3 bits).
+
+Flags
+^^^^^
+
++---------------+------------+
+| carry (C) | Unchanged. |
++---------------+------------+
+| overflow (V) | Unchanged. |
++---------------+------------+
+| zero (Z) | Unchanged. |
++---------------+------------+
+| sign (S) | Unchanged. |
++---------------+------------+
+| unordered (U) | Unchanged. |
++---------------+------------+
+
+.. _umlinst-store:
+
+STORE
+~~~~~
+
+Store an integer value to a location in memory with variable
+displacement. Host system rules for integer alignment must be followed.
+
++---------------------------------------+-------------------------------------------------------+
+| Disassembly | Usage |
++=======================================+=======================================================+
+| .. code-block:: | .. code-block:: C++ |
+| | |
+| store base,index,src,size_scale | UML_STORE(block, base, index, src, size, scale); |
+| dstore base,index,src,size_scale | UML_DSTORE(block, base, index, src, size, scale); |
++---------------------------------------+-------------------------------------------------------+
+
+Operands
+^^^^^^^^
+
+base (memory)
+ The base address of the area of memory to write to.
+index (32-bit – memory, integer register, immediate, map variable)
+ The displacement value added to the base address to calculate the
+ address to write to. This value may be scaled by a factor of 1, 2,
+ 4 or 8 depending on the ``scale`` operand. Note that this is always
+ a 32-bit operand interpreted as a signed integer, irrespective of
+ the instruction size.
+src (32-bit or 64-bit – memory, integer register, immediate, map variable)
+ The value to write to memory.
+size (access size)
+ The size of the value to write. Must be ``SIZE_BYTE`` (8-bit),
+ ``SIZE_WORD`` (16-bit), ``SIZE_DWORD`` (32-bit) or ``SIZE_QWORD``
+ (64-bit). Note that this operand controls the size of the value
+ written to memory while the instruction size sets the size of the
+ ``src`` operand.
+scale (index scale)
+ The scale factor to apply to the ``index`` operand. Must be
+ ``SCALE_x1``, ``SCALE_x2``, ``SCALE_x4`` or ``SCALE_x8`` to multiply
+ by 1, 2, 4 or 8, respectively (shift left by 0, 1, 2 or 3 bits).
+
+Flags
+^^^^^
+
++---------------+------------+
+| carry (C) | Unchanged. |
++---------------+------------+
+| overflow (V) | Unchanged. |
++---------------+------------+
+| zero (Z) | Unchanged. |
++---------------+------------+
+| sign (S) | Unchanged. |
++---------------+------------+
+| unordered (U) | Unchanged. |
++---------------+------------+
+
+.. _umlinst-fload:
+
+FLOAD
+~~~~~
+
+Load a floating point value from a memory location with variable
+displacement. The binary value will be preserved even if it is not a
+valid representation of a floating point number. Host system rules for
+memory access alignment must be followed.
+
++----------------------------+------------------------------------------+
+| Disassembly | Usage |
++============================+==========================================+
+| .. code-block:: | .. code-block:: C++ |
+| | |
+| fsload dst,base,index | UML_FSLOAD(block, dst, base, index); |
+| fdload dst,base,index | UML_FDLOAD(block, dst, base, index); |
++----------------------------+------------------------------------------+
+
+Operands
+^^^^^^^^
+
+dst (32-bit or 64-bit – memory, floating point register)
+ The destination where the value read from memory will be stored.
+base (memory)
+ The base address of the area of memory to read from.
+index (32-bit – memory, integer register, immediate, map variable)
+ The displacement value added to the base address to calculate the
+ address to read from. This value will be scaled by the instruction
+ size (multiplied by 4 or 8). Note that this is always a 32-bit
+ operand interpreted as a signed integer, irrespective of the
+ instruction size.
+
+Flags
+^^^^^
+
++---------------+------------+
+| carry (C) | Unchanged. |
++---------------+------------+
+| overflow (V) | Unchanged. |
++---------------+------------+
+| zero (Z) | Unchanged. |
++---------------+------------+
+| sign (S) | Unchanged. |
++---------------+------------+
+| unordered (U) | Unchanged. |
++---------------+------------+
+
+.. _umlinst-fstore:
+
+FSTORE
+~~~~~~
+
+Store a floating point value to a memory location with variable
+displacement. The binary value will be preserved even if it is not a
+valid representation of a floating point number. Host system rules for
+memory access alignment must be followed.
+
++----------------------------+-------------------------------------------+
+| Disassembly | Usage |
++============================+===========================================+
+| .. code-block:: | .. code-block:: C++ |
+| | |
+| fsstore base,index,src | UML_FSSTORE(block, base, index, src); |
+| fdstore base,index,src | UML_FDSTORE(block, base, index, src); |
++----------------------------+-------------------------------------------+
+
+Operands
+^^^^^^^^
+
+base (memory)
+ The base address of the area of memory to write to.
+index (32-bit – memory, integer register, immediate, map variable)
+ The displacement value added to the base address to calculate the
+ address to write to. This value will be scaled by the instruction
+ size (multiplied by 4 or 8). Note that this is always a 32-bit
+ operand interpreted as a signed integer, irrespective of the
+ instruction size.
+src (32-bit or 64-bit – memory, floating point register)
+ The value to write to memory.
+
+Flags
+^^^^^
+
++---------------+------------+
+| carry (C) | Unchanged. |
++---------------+------------+
+| overflow (V) | Unchanged. |
++---------------+------------+
+| zero (Z) | Unchanged. |
++---------------+------------+
+| sign (S) | Unchanged. |
++---------------+------------+
+| unordered (U) | Unchanged. |
++---------------+------------+
+
+.. _umlinst-getexp:
+
+GETEXP
+~~~~~~
+
+Copy the value of the ``EXP`` register. The ``EXP`` register can be set
+using the :ref:`EXH <umlinst-exh>` instruction.
+
++-----------------+-----------------------------+
+| Disassembly | Usage |
++=================+=============================+
+| .. code-block:: | .. code-block:: C++ |
+| | |
+| getexp dst | UML_GETEXP(block, dst); |
++-----------------+-----------------------------+
+
+Operands
+^^^^^^^^
+
+dst (32-bit – memory, integer register)
+ The destination to copy the value of the ``EXP`` register to. Note
+ that the ``EXP`` register can only hold a 32-bit value.
+
+Flags
+^^^^^
+
++---------------+------------+
+| carry (C) | Unchanged. |
++---------------+------------+
+| overflow (V) | Unchanged. |
++---------------+------------+
+| zero (Z) | Unchanged. |
++---------------+------------+
+| sign (S) | Unchanged. |
++---------------+------------+
+| unordered (U) | Unchanged. |
++---------------+------------+
+
+.. _umlinst-mapvar:
+
+MAPVAR
+~~~~~~
+
+Set the value of a map variable starting at the current location in the
+current generated code block.
+
++--------------------------+---------------------------------------+
+| Disassembly | Usage |
++==========================+=======================================+
+| .. code-block:: | .. code-block:: C++ |
+| | |
+| mapvar mapvar,value | UML_MAPVAR(block, mapvar, value); |
++--------------------------+---------------------------------------+
+
+Operands
+^^^^^^^^
+
+mapvar (map variable)
+ The map variable to set the value of.
+value (32-bit – immediate, map variable)
+ The value to set the map variable to. Note that map variables can
+ only hold 32-bit values.
+
+Flags
+^^^^^
+
++---------------+------------+
+| carry (C) | Unchanged. |
++---------------+------------+
+| overflow (V) | Unchanged. |
++---------------+------------+
+| zero (Z) | Unchanged. |
++---------------+------------+
+| sign (S) | Unchanged. |
++---------------+------------+
+| unordered (U) | Unchanged. |
++---------------+------------+
+
+.. _umlinst-recover:
+
+RECOVER
+~~~~~~~
+
+Retrieve the value of a map variable at the location of the call
+instruction in the outermost generated code frame. This instruction
+should only be used from within a generated code subroutine. Results
+are undefined if this instruction is executed from outside any
+generated code subroutines.
+
++------------------------+--------------------------------------+
+| Disassembly | Usage |
++========================+======================================+
+| .. code-block:: | .. code-block:: C++ |
+| | |
+| recover dst,mapvar | UML_RECOVER(block, dst, mapvar); |
++------------------------+--------------------------------------+
+
+Operands
+^^^^^^^^
+
+dst (32-bit – memory, integer register)
+ The destination to copy the value of the map variable to. Note that
+ map variables can only hold 32-bit values.
+mapvar (map variable)
+ The map variable to retrieve the value of from the outermost
+ generated code frame.
+
+Flags
+^^^^^
+
++---------------+------------+
+| carry (C) | Undefined. |
++---------------+------------+
+| overflow (V) | Undefined. |
++---------------+------------+
+| zero (Z) | Undefined. |
++---------------+------------+
+| sign (S) | Undefined. |
++---------------+------------+
+| unordered (U) | Undefined. |
++---------------+------------+
+
+
+.. _umlinst-memaccess:
+
+Emulated memory access
+----------------------
+
+.. _umlinst-read:
+
+READ
+~~~~
+
+Read from an emulated address space. The access mask is implied to have
+all bits set.
+
++---------------------------------+-----------------------------------------------+
+| Disassembly | Usage |
++=================================+===============================================+
+| .. code-block:: | .. code-block:: C++ |
+| | |
+| read dst,addr,space_size | UML_READ(block, dst, addr, size, space); |
+| dread dst,addr,space_size | UML_DREAD(block, dst, addr, size, space); |
++---------------------------------+-----------------------------------------------+
+
+Operands
+^^^^^^^^
+
+dst (32-bit or 64-bit – memory, integer register)
+ The destination where the value read from the emulated address space
+ will be stored.
+addr (32-bit – memory, integer register, immediate, map variable)
+ The address to read from in the emulated address space. Note that
+ this is always a 32-bit operand, irrespective of the instruction
+ size.
+size (access size)
+ The size of the emulated memory access. Must be ``SIZE_BYTE``
+ (8-bit), ``SIZE_WORD`` (16-bit), ``SIZE_DWORD`` (32-bit) or
+ ``SIZE_QWORD`` (64-bit). Note that this operand controls the size
+ of the emulated memory access while the instruction size sets the
+ size of the ``dst`` operand.
+space (address space number)
+ An integer identifying the address space to read from. May be
+ ``SPACE_PROGRAM``, ``SPACE_DATA``, ``SPACE_IO`` or ``SPACE_OPCODES``
+ for one of the common CPU address spaces, or a non-negative integer
+ cast to ``memory_space``.
+
+Flags
+^^^^^
+
++---------------+------------+
+| carry (C) | Undefined. |
++---------------+------------+
+| overflow (V) | Undefined. |
++---------------+------------+
+| zero (Z) | Undefined. |
++---------------+------------+
+| sign (S) | Undefined. |
++---------------+------------+
+| unordered (U) | Undefined. |
++---------------+------------+
+
+Simplification rules
+^^^^^^^^^^^^^^^^^^^^
+
+* Immediate values for the ``addr`` operand are truncated to 32 bits.
+
+.. _umlinst-readm:
+
+READM
+~~~~~
+
+Read from an emulated address space with access mask specified.
+
++--------------------------------------+------------------------------------------------------+
+| Disassembly | Usage |
++======================================+======================================================+
+| .. code-block:: | .. code-block:: C++ |
+| | |
+| readm dst,addr,mask,space_size | UML_READM(block, dst, addr, mask, size, space); |
+| dreadm dst,addr,mask,space_size | UML_DREADM(block, dst, addr, mask, size, space); |
++--------------------------------------+------------------------------------------------------+
+
+Operands
+^^^^^^^^
+
+dst (32-bit or 64-bit – memory, integer register)
+ The destination where the value read from the emulated address space
+ will be stored.
+addr (32-bit – memory, integer register, immediate, map variable)
+ The address to read from in the emulated address space. Note that
+ this is always a 32-bit operand, irrespective of the instruction
+ size.
+mask (32-bit or 64-bit – memory, integer register, immediate, map variable)
+ The access mask for the emulated memory access.
+size (access size)
+ The size of the emulated memory access. Must be ``SIZE_BYTE``
+ (8-bit), ``SIZE_WORD`` (16-bit), ``SIZE_DWORD`` (32-bit) or
+ ``SIZE_QWORD`` (64-bit). Note that this operand controls the size
+ of the emulated memory access while the instruction size sets the
+ size of the ``dst`` and ``mask`` operands.
+space (address space number)
+ An integer identifying the address space to read from. May be
+ ``SPACE_PROGRAM``, ``SPACE_DATA``, ``SPACE_IO`` or ``SPACE_OPCODES``
+ for one of the common CPU address spaces, or a non-negative integer
+ cast to ``memory_space``.
+
+Flags
+^^^^^
+
++---------------+------------+
+| carry (C) | Undefined. |
++---------------+------------+
+| overflow (V) | Undefined. |
++---------------+------------+
+| zero (Z) | Undefined. |
++---------------+------------+
+| sign (S) | Undefined. |
++---------------+------------+
+| unordered (U) | Undefined. |
++---------------+------------+
+
+Simplification rules
+^^^^^^^^^^^^^^^^^^^^
+
+* Immediate values for the ``addr`` operand are truncated to 32 bits.
+* Immediate values for the ``mask`` operand are truncated to the access
+ size.
+* Converted to :ref:`READ <umlinst-read>` if the ``mask`` operand is an
+ immediate value with all bits set.
+
+.. _umlinst-write:
+
+WRITE
+~~~~~
+
+Write to an emulated address space. The access mask is implied to have
+all bits set.
+
++---------------------------------+------------------------------------------------+
+| Disassembly | Usage |
++=================================+================================================+
+| .. code-block:: | .. code-block:: C++ |
+| | |
+| write addr,src,space_size | UML_WRITE(block, addr, src, size, space); |
+| dwrite addr,src,space_size | UML_DWRITE(block, addr, src, size, space); |
++---------------------------------+------------------------------------------------+
+
+Operands
+^^^^^^^^
+
+addr (32-bit – memory, integer register, immediate, map variable)
+ The address to write to in the emulated address space. Note that
+ this is always a 32-bit operand, irrespective of the instruction
+ size.
+src (32-bit or 64-bit – memory, integer register, immediate, map variable)
+ The value to write to the emulated address space.
+size (access size)
+ The size of the emulated memory access. Must be ``SIZE_BYTE``
+ (8-bit), ``SIZE_WORD`` (16-bit), ``SIZE_DWORD`` (32-bit) or
+ ``SIZE_QWORD`` (64-bit). Note that this operand controls the size
+ of the emulated memory access while the instruction size sets the
+ size of the ``src`` operand.
+space (address space number)
+ An integer identifying the address space to read from. May be
+ ``SPACE_PROGRAM``, ``SPACE_DATA``, ``SPACE_IO`` or ``SPACE_OPCODES``
+ for one of the common CPU address spaces, or a non-negative integer
+ cast to ``memory_space``.
+
+Flags
+^^^^^
+
++---------------+------------+
+| carry (C) | Undefined. |
++---------------+------------+
+| overflow (V) | Undefined. |
++---------------+------------+
+| zero (Z) | Undefined. |
++---------------+------------+
+| sign (S) | Undefined. |
++---------------+------------+
+| unordered (U) | Undefined. |
++---------------+------------+
+
+Simplification rules
+^^^^^^^^^^^^^^^^^^^^
+
+* Immediate values for the ``addr`` operand are truncated to 32 bits.
+* Immediate values for the ``src`` operand are truncated to the access
+ size.
+
+.. _umlinst-writem:
+
+WRITEM
+~~~~~~
+
+Write to an emulated address space with access mask specified.
+
++--------------------------------------+-------------------------------------------------------+
+| Disassembly | Usage |
++======================================+=======================================================+
+| .. code-block:: | .. code-block:: C++ |
+| | |
+| writem addr,src,mask,space_size | UML_WRITEM(block, addr, src, mask, size, space); |
+| dwritem addr,src,mask,space_size | UML_DWRITEM(block, addr, src, mask, size, space); |
++--------------------------------------+-------------------------------------------------------+
+
+Operands
+^^^^^^^^
+
+addr (32-bit – memory, integer register, immediate, map variable)
+ The address to write to in the emulated address space. Note that
+ this is always a 32-bit operand, irrespective of the instruction
+ size.
+src (32-bit or 64-bit – memory, integer register, immediate, map variable)
+ The value to write to the emulated address space.
+mask (32-bit or 64-bit – memory, integer register, immediate, map variable)
+ The access mask for the emulated memory access.
+size (access size)
+ The size of the emulated memory access. Must be ``SIZE_BYTE``
+ (8-bit), ``SIZE_WORD`` (16-bit), ``SIZE_DWORD`` (32-bit) or
+ ``SIZE_QWORD`` (64-bit). Note that this operand controls the size
+ of the emulated memory access while the instruction size sets the
+ size of the ``src`` and ``mask`` operands.
+space (address space number)
+ An integer identifying the address space to read from. May be
+ ``SPACE_PROGRAM``, ``SPACE_DATA``, ``SPACE_IO`` or ``SPACE_OPCODES``
+ for one of the common CPU address spaces, or a non-negative integer
+ cast to ``memory_space``.
+
+Flags
+^^^^^
+
++---------------+------------+
+| carry (C) | Undefined. |
++---------------+------------+
+| overflow (V) | Undefined. |
++---------------+------------+
+| zero (Z) | Undefined. |
++---------------+------------+
+| sign (S) | Undefined. |
++---------------+------------+
+| unordered (U) | Undefined. |
++---------------+------------+
+
+Simplification rules
+^^^^^^^^^^^^^^^^^^^^
+
+* Immediate values for the ``addr`` operand are truncated to 32 bits.
+* Immediate values for the ``src`` and ``mask`` operands are truncated
+ to the access size.
+* Converted to :ref:`WRITE <umlinst-read>` if the ``mask`` operand is an
+ immediate value with all bits set.
+
+.. _umlinst-fread:
+
+FREAD
+~~~~~
+
+Read a floating point value from an emulated address space. The binary
+value will be preserved even if it is not a valid representation of a
+floating point number. The access mask is implied to have all bits set.
+
++---------------------------------+------------------------------------------+
+| Disassembly | Usage |
++=================================+==========================================+
+| .. code-block:: | .. code-block:: C++ |
+| | |
+| fsread dst,addr,space_size | UML_FSREAD(block, dst, addr, space); |
+| fdread dst,addr,space_size | UML_FDREAD(block, dst, addr, space); |
++---------------------------------+------------------------------------------+
+
+Operands
+^^^^^^^^
+
+dst (32-bit or 64-bit – memory, floating point register)
+ The destination where the value read from the emulated address space
+ will be stored.
+addr (32-bit – memory, integer register, immediate, map variable)
+ The address to read from in the emulated address space. Note that
+ this is always a 32-bit operand, irrespective of the instruction
+ size.
+space (address space number)
+ An integer identifying the address space to read from. May be
+ ``SPACE_PROGRAM``, ``SPACE_DATA``, ``SPACE_IO`` or ``SPACE_OPCODES``
+ for one of the common CPU address spaces, or a non-negative integer
+ cast to ``memory_space``.
+
+Flags
+^^^^^
+
++---------------+------------+
+| carry (C) | Undefined. |
++---------------+------------+
+| overflow (V) | Undefined. |
++---------------+------------+
+| zero (Z) | Undefined. |
++---------------+------------+
+| sign (S) | Undefined. |
++---------------+------------+
+| unordered (U) | Undefined. |
++---------------+------------+
+
+Simplification rules
+^^^^^^^^^^^^^^^^^^^^
+
+* Immediate values for the ``addr`` operand are truncated to 32 bits.
+
+.. _umlinst-fwrite:
+
+FWRITE
+~~~~~~
+
+Write a floating point value to an emulated address space. The binary
+value will be preserved even if it is not a valid representation of a
+floating point number. The access mask is implied to have all bits set.
+
++---------------------------------+-------------------------------------------+
+| Disassembly | Usage |
++=================================+===========================================+
+| .. code-block:: | .. code-block:: C++ |
+| | |
+| fswrite addr,src,space_size | UML_FSWRITE(block, addr, src, space); |
+| fdwrite addr,src,space_size | UML_FDWRITE(block, addr, src, space); |
++---------------------------------+-------------------------------------------+
+
+Operands
+^^^^^^^^
+
+addr (32-bit – memory, integer register, immediate, map variable)
+ The address to write to in the emulated address space. Note that
+ this is always a 32-bit operand, irrespective of the instruction
+ size.
+src (32-bit or 64-bit – memory, floating point register)
+ The value to write to the emulated address space.
+ will be stored.
+space (address space number)
+ An integer identifying the address space to read from. May be
+ ``SPACE_PROGRAM``, ``SPACE_DATA``, ``SPACE_IO`` or ``SPACE_OPCODES``
+ for one of the common CPU address spaces, or a non-negative integer
+ cast to ``memory_space``.
+
+Flags
+^^^^^
+
++---------------+------------+
+| carry (C) | Undefined. |
++---------------+------------+
+| overflow (V) | Undefined. |
++---------------+------------+
+| zero (Z) | Undefined. |
++---------------+------------+
+| sign (S) | Undefined. |
++---------------+------------+
+| unordered (U) | Undefined. |
++---------------+------------+
+
+Simplification rules
+^^^^^^^^^^^^^^^^^^^^
+
+* Immediate values for the ``addr`` operand are truncated to 32 bits.
diff --git a/docs/source/tools/castool.rst b/docs/source/tools/castool.rst
index b4d8f81467f..73fb095d9b1 100644
--- a/docs/source/tools/castool.rst
+++ b/docs/source/tools/castool.rst
@@ -9,7 +9,7 @@ Castool is part of the MAME project. It shares large portions of code with MAME,
Using Castool
-=============
+-------------
Castool is a command line program that contains a simple set of instructions. Commands are invoked in a manner along the lines of this:
@@ -30,7 +30,7 @@ Example usage:
Castool Formats
-===============
+---------------
These are the formats supported by Castool for conversion to .WAV files.
diff --git a/docs/source/tools/chdman.rst b/docs/source/tools/chdman.rst
new file mode 100644
index 00000000000..cbf16fcba75
--- /dev/null
+++ b/docs/source/tools/chdman.rst
@@ -0,0 +1,457 @@
+.. _chdman:
+
+chdman – CHD (Compressed Hunks of Data) File Manager
+====================================================
+
+chdman can be used to create, convert, check the integrity of and extract data
+from media images in CHD (Compressed Hunks of Data) format.
+
+The basic usage is ``chdman <command> <option>...``
+
+.. contents:: :local:
+
+
+.. _chdman-commonopts:
+
+Common options
+--------------
+
+The options available depend on the command, but the following options are
+used by multiple commands:
+
+--input <file> / -i <file>
+ Specify the input file. This option is required for most commands. The
+ input file formats supported depend on the command
+--inputparent <chdfile> / -ip <chdfile>
+ Specify the parent CHD file for the input file. This option is supported for
+ most commands that operate on CHD format input files. This option must be
+ used if the input file is a *delta CHD*, storing only the hunks that differ
+ from its parent CHD,
+--inputstartbyte <offset> / -isb <offset>
+ Specify the offset to the data in the input file in bytes. This is useful
+ for creating CHD format files from input files that contain a header before
+ the start of the data, or for extracting partial content from a CHD format
+ file. May not be specified in combination with the
+ ``--inputstarthunk``/``-ish`` option.
+--inputstarthunk <offset> / -ish <offset>
+ Specify the offset to the data in the input file in hunks. May not be
+ specified in combination with the ``--inputstartbyte``/``-isb`` option.
+--inputbytes <length> / -ib <length>
+ Specify the amount of input data to use in bytes, starting from the offset
+ to the data in the input file. This is useful for creating CHD format files
+ from input files that contain additional content after the data, or for
+ extracting partial content from a CHD format file. May not be specified in
+ combination with the ``--inputhunks``/``-ih`` option.
+--inputhunks <length> / -ih <length>
+ Specify the amount of input data to use in hunks, starting from the offset
+ to the data in the input file. May not be specified in combination with the
+ ``--inputbytes``/``-ib`` option.
+--output <file> / -o <file>
+ Specify the output file name. This option is required for commands that
+ produce output files. The output file formats supported depend on the
+ command.
+--outputparent <chdfile> / -op <chdfile>
+ Specify the parent CHD file for the output file. This option is supported
+ for commands that produce CHD format output files. Using this option
+ produces a *delta CHD*, storing only the hunks that differ from its parent
+ CHD. The parent CHD should be the same media type and size, with the same
+ hunk size.
+--compression none|<type>[,<type>]... / -c none|<type>[,<type>]...
+ Specify compression algorithms to use. This option is supported for commands
+ that produce CHD format output files. Specify ``none`` to disable
+ compression, or specify up to four comma-separated compression algorithms.
+ See :ref:`compression algorithms <chdman-compression>` for supported
+ compression algorithms. Compression must be disable to create writable media
+ image files.
+--hunksize <bytes> / -hs <bytes>
+ Specifies the hunk size in bytes. This option is supported for commands that
+ produce CHD format output files. The hunk size must be no smaller than
+ 16 bytes and no larger than 1048576 bytes (1 MiB). The hunk size must be a
+ multiple of the sector size or unit size of the media. Larger hunk sizes may
+ give better compression ratios, but reduce performance for small random
+ reads as an entire hunk needs to be read and decompressed at a time.
+--force / -f
+ Overwrite output files if they already exist. This option is supported for
+ commands that produce output files.
+--verbose / -v
+ Enable verbose output. This prints more detailed information for some
+ commands.
+--numprocessors <count> / -np <count>
+ Limit the maximum number of concurrent threads used for data compression.
+ This option is supported for commands that produce CHD format output files.
+
+
+.. _chdman-commands:
+
+Commands
+--------
+
+info
+~~~~
+
+Display information about a CHD format file. Information includes:
+
+* CHD format version and compression algorithms used.
+* Compressed and uncompressed sizes and overall compression ratio.
+* Hunk size, unit size and number of hunks in the file.
+* SHA1 digests of the data and metadata.
+
+Common options supported:
+
+* ``--input <file>`` / ``-i <file>`` (required)
+* ``--verbose`` / ``-v``
+
+verify
+~~~~~~
+
+Verify the integrity of a CHD format file. The input file must be a read-only
+CHD format file (the integrity of writable CHD files cannot be verified). Note
+that this command modifies its input file if the ``--fix``/``-f`` option is
+specified.
+
+Common options supported:
+
+* ``--input <file>`` / ``-i <file>`` (required)
+* ``--inputparent <chdfile>`` / ``-ip <chdfile>``
+
+Additional options:
+
+* ``--fix`` / ``-f``
+
+createraw
+~~~~~~~~~
+
+Create a CHD format file from a raw media image.
+
+Common options supported:
+
+* ``--input <file>`` / ``-i <file>`` (required)
+* ``--inputstartbyte <offset>`` / ``-isb <offset>``
+* ``--inputstarthunk <offset>`` / ``-ish <offset>``
+* ``--inputbytes <length>`` / ``-ib <length>``
+* ``--inputhunks <length>`` / ``-ih <length>``
+* ``--output <file>`` / ``-o <file>`` (required)
+* ``--outputparent <chdfile>`` / ``-op <chdfile>``
+* ``--compression none|<type>[,<type>]...`` / ``-c none|<type>[,<type>]...``
+* ``--hunksize <bytes>`` / ``-hs <bytes>``
+* ``--force`` / ``-f``
+* ``--numprocessors <count>`` / ``-np <count>``
+
+Additional options:
+
+--unitsize <bytes> / -us <bytes> (required)
+ The unit size for the output CHD file in bytes. This is the smallest unit
+ of data that can be addressed within the CHD file. It should match the
+ sector size or page size of the source media. The hunk size must be a whole
+ multiple of the unit size. The unit size must be specified if no parent CHD
+ file for the output is supplied. If a parent CHD file for the output is
+ supplied, the unit size must match the unit size of the parent CHD file.
+
+If the ``--hunksize`` or ``-hs`` option is not supplied, the default will be:
+
+* The hunk size of the parent CHD file if a parent CHD file for the output is
+ supplied.
+* The smallest whole multiple of the unit size not larger than 4 KiB if the unit
+ size is not larger than 4 KiB (4096 bytes).
+* The unit size if it is larger than 4 KiB (4096 bytes).
+
+If the ``--compression`` or ``-c`` option is not supplied, it defaults to
+``lzma,zlib,huff,flac``.
+
+createhd
+~~~~~~~~
+
+Create a CHD format hard disk image file.
+
+Common options supported:
+
+* ``--input <file>`` / ``-i <file>``
+* ``--inputstartbyte <offset>`` / ``-isb <offset>``
+* ``--inputstarthunk <offset>`` / ``-ish <offset>``
+* ``--inputbytes <length>`` / ``-ib <length>``
+* ``--inputhunks <length>`` / ``-ih <length>``
+* ``--output <file>`` / ``-o <file>`` (required)
+* ``--outputparent <chdfile>`` / ``-op <chdfile>``
+* ``--compression none|<type>[,<type>]...`` / ``-c none|<type>[,<type>]...``
+* ``--hunksize <bytes>`` / ``-hs <bytes>`` (required)
+* ``--force`` / ``-f``
+* ``--numprocessors <count>`` / ``-np <count>``
+
+Additional options:
+
+* ``--sectorsize <bytes>`` / ``-ss <bytes>``
+* ``--size <bytes>`` / ``-s <bytes>``
+* ``--chs <cylinders>,<heads>,<sectors>`` / ``-chs <cylinders>,<heads>,<sectors>``
+* ``--template <template>`` / ``-tp <template>``
+
+Creates a blank (zero-filled) hard disk image if no input file is supplied. The
+input start/length (``--inputstartbyte``/``-isb``,
+``--inputstarthunk``/``-ish``, ``--inputbytes``/``-ib`` and
+``--inputhunks``/``-ih`` options) cannot be used if no input file is supplied.
+
+If the ``--hunksize`` or ``-hs`` option is not supplied, the default will be:
+
+* The hunk size of the parent CHD file if a parent CHD file for the output is
+ supplied.
+* The smallest whole multiple of the sector size not larger than 4 KiB if the
+ sector size is not larger than 4 KiB (4096 bytes).
+* The sector size if it is larger than 4 KiB (4096 bytes).
+
+If the ``--compression`` or ``-c`` option is not supplied, it defaults to
+``lzma,zlib,huff,flac`` if an input file is supplied, or ``none`` if no input
+file is supplied.
+
+createcd
+~~~~~~~~
+
+Create a CHD format CD-ROM image file.
+
+Common options supported:
+
+* ``--input <file>`` / ``-i <file>`` (required)
+* ``--output <file>`` / ``-o <file>`` (required)
+* ``--outputparent <chdfile>`` / ``-op <chdfile>``
+* ``--compression none|<type>[,<type>]...`` / ``-c none|<type>[,<type>]...``
+* ``--hunksize <bytes>`` / ``-hs <bytes>`` (required)
+* ``--force`` / ``-f``
+* ``--numprocessors <count>`` / ``-np <count>``
+
+If the ``--hunksize`` or ``-hs`` option is not supplied, the default will be
+the hunk size of the parent CHD if a parent CHD file for the output is supplied,
+or eight sectors per hunk (18,816 bytes) otherwise.
+
+If the ``--compression`` or ``-c`` option is not supplied, it defaults to
+``cdlz,cdzl,cdfl``.
+
+createdvd
+~~~~~~~~~
+
+Create a CHD format DVD-ROM image file.
+
+Common options supported:
+
+* ``--input <file>`` / ``-i <file>`` (required)
+* ``--inputstartbyte <offset>`` / ``-isb <offset>``
+* ``--inputstarthunk <offset>`` / ``-ish <offset>``
+* ``--inputbytes <length>`` / ``-ib <length>``
+* ``--inputhunks <length>`` / ``-ih <length>``
+* ``--output <file>`` / ``-o <file>`` (required)
+* ``--outputparent <chdfile>`` / ``-op <chdfile>``
+* ``--compression none|<type>[,<type>]...`` / ``-c none|<type>[,<type>]...``
+* ``--hunksize <bytes>`` / ``-hs <bytes>`` (required)
+* ``--force`` / ``-f``
+* ``--numprocessors <count>`` / ``-np <count>``
+
+If the ``--hunksize`` or ``-hs`` option is not supplied, the default will be
+the hunk size of the parent CHD if a parent CHD file for the output is supplied,
+or two sectors per hunk (4096 bytes) otherwise.
+
+If the ``--compression`` or ``-c`` option is not supplied, it defaults to
+``lzma,zlib,huff,flac``.
+
+createld
+~~~~~~~~
+
+Create a CHD format LaserDisc image file.
+
+Common options supported:
+
+* ``--input <file>`` / ``-i <file>`` (required)
+* ``--output <file>`` / ``-o <file>`` (required)
+* ``--outputparent <chdfile>`` / ``-op <chdfile>``
+* ``--compression none|<type>[,<type>]...`` / ``-c none|<type>[,<type>]...``
+* ``--hunksize <bytes>`` / ``-hs <bytes>`` (required)
+* ``--force`` / ``-f``
+* ``--numprocessors <count>`` / ``-np <count>``
+
+Additional options:
+
+* ``--inputstartframe <offset>`` / ``-isf <offset>``
+* ``--inputframes <length>`` / ``-if <length>``
+
+If the ``--compression`` or ``-c`` option is not supplied, it defaults to
+``avhu``.
+
+extractraw
+~~~~~~~~~~
+
+Extract data from a CHD format raw media image.
+
+Common options supported:
+
+* ``--input <file>`` / ``-i <file>`` (required)
+* ``--inputparent <chdfile>`` / ``-ip <chdfile>``
+* ``--inputstartbyte <offset>`` / ``-isb <offset>``
+* ``--inputstarthunk <offset>`` / ``-ish <offset>``
+* ``--inputbytes <length>`` / ``-ib <length>``
+* ``--inputhunks <length>`` / ``-ih <length>``
+* ``--output <file>`` / ``-o <file>`` (required)
+* ``--force`` / ``-f``
+
+extracthd
+~~~~~~~~~
+
+Extract data from a CHD format hard disk image.
+
+Common options supported:
+
+* ``--input <file>`` / ``-i <file>`` (required)
+* ``--inputparent <chdfile>`` / ``-ip <chdfile>``
+* ``--inputstartbyte <offset>`` / ``-isb <offset>``
+* ``--inputstarthunk <offset>`` / ``-ish <offset>``
+* ``--inputbytes <length>`` / ``-ib <length>``
+* ``--inputhunks <length>`` / ``-ih <length>``
+* ``--output <file>`` / ``-o <file>`` (required)
+* ``--force`` / ``-f``
+
+extractcd
+~~~~~~~~~
+
+Extract data from a CHD format CD-ROM image.
+
+Common options supported:
+
+* ``--input <file>`` / ``-i <file>`` (required)
+* ``--inputparent <chdfile>`` / ``-ip <chdfile>``
+* ``--output <file>`` / ``-o <file>`` (required)
+* ``--force`` / ``-f``
+
+Additional options:
+
+* ``--outputbin <file>`` / ``-ob <file>``
+* ``--splitbin`` / ``-sb``
+
+extractdvd
+~~~~~~~~~~
+
+Extract data from a CHD format DVD-ROM image.
+
+Common options supported:
+
+* ``--input <file>`` / ``-i <file>`` (required)
+* ``--inputparent <chdfile>`` / ``-ip <chdfile>``
+* ``--inputstartbyte <offset>`` / ``-isb <offset>``
+* ``--inputstarthunk <offset>`` / ``-ish <offset>``
+* ``--inputbytes <length>`` / ``-ib <length>``
+* ``--inputhunks <length>`` / ``-ih <length>``
+* ``--output <file>`` / ``-o <file>`` (required)
+* ``--force`` / ``-f``
+
+extractld
+~~~~~~~~~
+
+Extract data from a CHD format DVD-ROM image.
+
+Common options supported:
+
+* ``--input <file>`` / ``-i <file>`` (required)
+* ``--inputparent <chdfile>`` / ``-ip <chdfile>``
+* ``--output <file>`` / ``-o <file>`` (required)
+* ``--force`` / ``-f``
+
+Additional options:
+
+* ``--inputstartframe <offset>`` / ``-isf <offset>``
+* ``--inputframes <length>`` / ``-if <length>``
+
+addmeta
+~~~~~~~
+
+Add a metadata item to a CHD format file. Note that this command modifies its
+input file.
+
+Common options supported:
+
+* ``--input <file>`` / ``-i <file>`` (required)
+
+Additional options:
+
+* ``--tag <tag>`` / ``-t <tag>`` (required)
+* ``--index <index>`` / ``-ix <index>``
+* ``--valuetext <text>`` / ``-vt <text>``
+* ``--valuefile <file>`` / ``-vf <file>``
+* ``--nochecksum`` / ``-nocs``
+
+delmeta
+~~~~~~~
+
+Delete a metadata item from a CHD format file. Note that this command modifies
+its input file.
+
+Common options supported:
+
+* ``--input <file>`` / ``-i <file>`` (required)
+
+Additional options:
+
+* ``--tag <tag>`` / ``-t <tag>`` (required)
+* ``--index <index>`` / ``-ix <index>``
+
+dumpmeta
+~~~~~~~~
+
+Extract metadata items from a CHD format file to the standard output or to a
+file.
+
+Common options supported:
+
+* ``--input <file>`` / ``-i <file>`` (required)
+* ``--output <file>`` / ``-o <file>``
+* ``--force`` / ``-f``
+
+Additional options:
+
+* ``--tag <tag>`` / ``-t <tag>`` (required)
+* ``--index <index>`` / ``-ix <index>``
+
+listtemplates
+~~~~~~~~~~~~~
+
+List available hard disk templates. This command does not accept any options.
+
+
+.. _chdman-compression:
+
+Compression algorithms
+----------------------
+
+The following compression algorithms are supported:
+
+zlib – zlib deflate
+ Compresses data using the zlib deflate algorithm.
+zstd – Zstandard
+ Compresses data using the Zstandard algorithm. This gives very good
+ compression and decompression performance with better compression ratios than
+ zlib deflate, but older software may not support CHD files that use Zstandard
+ compression.
+lzma – Lempel-Ziv-Markov chain algorithm
+ Compresses data using the Lempel-Ziv-Markov-chain algorithm (LZMA). This
+ gives high compression ratios at the cost of poor compression and
+ decompression performance.
+huff – Huffman coding
+ Compresses data using 8-bit Huffman entropy coding.
+flac – Free Lossless Audio Codec
+ Compresses data as two-channel (stereo) 16-bit 44.1 kHz PCM audio using the
+ Free Lossless Audio Codec (FLAC). This gives good compression ratios if the
+ media contains 16-bit PCM audio data.
+cdzl – zlib deflate for CD-ROM data
+ Compresses audio data and subchannel data from CD-ROM sectors separately
+ using the zlib deflate algorithm.
+cdzs – Zstandard for CD-ROM data
+ Compresses audio data and subchannel data from CD-ROM sectors separately
+ using the Zstandard algorithm. This gives very good compression and
+ decompression performance with better compression ratios than zlib deflate,
+ but older software may not support CHD files that use Zstandard compression.
+cdlz - Lempel-Ziv-Markov chain algorithm/zlib deflate for CD-ROM data
+ Compresses audio data and subchannel data from CD-ROM sectors separately
+ using the Lempel-Ziv-Markov chain algorithm (LZMA) for audio data and the
+ zlib deflate algorithm for subchannel data. This gives high compression
+ ratios at the cost of poor compression and decompression performance.
+cdfl – Free Lossless Audio Codec/zlib deflate for CD-ROM data
+ Compresses audio data and subchannel data from CD-ROM sectors separately
+ using the Free Lossless Audio Codec (FLAC) for audio data and the zlib
+ deflate algorithm for subchannel data. This gives good compression ratios
+ for audio CD tracks.
+avhu – Huffman coding for audio-visual data
+ This is a specialised compression algorithm for audio-visual (A/V) data. It
+ should only be used for LaserDisc CHD files.
diff --git a/docs/source/tools/floptool.rst b/docs/source/tools/floptool.rst
index f2e24eac56f..bf71c296aee 100644
--- a/docs/source/tools/floptool.rst
+++ b/docs/source/tools/floptool.rst
@@ -9,7 +9,7 @@ Floptool is part of the MAME project. It shares large portions of code with MAME
Using Floptool
-==============
+--------------
Floptool is a command line program that contains a simple set of instructions. Commands are invoked in a manner along the lines of this:
@@ -33,7 +33,7 @@ Example usage:
Floptool Formats
-================
+----------------
These are the formats supported by Floptool for conversion to other formats.
diff --git a/docs/source/tools/imgtool.rst b/docs/source/tools/imgtool.rst
index b874fdfe215..e54638ea59b 100644
--- a/docs/source/tools/imgtool.rst
+++ b/docs/source/tools/imgtool.rst
@@ -10,7 +10,7 @@ Imgtool is part of the MAME project. It shares large portions of code with MAME,
**Some portions of Imgtool are Copyright (c) 1989, 1993 The Regents of the University of California. All rights reserved.**
Using Imgtool
-=============
+-------------
Imgtool is a command line program that contains several "subcommands" that actually do all of the work. Most commands are invoked in a manner along the lines of this:
@@ -32,7 +32,7 @@ Further details vary with each subcommand. Also note that not all subcommands a
Imgtool Subcommands
-===================
+-------------------
**create**
@@ -64,7 +64,7 @@ Imgtool Subcommands
**put**
- **imgtool put <format> <imagename> <filename>... <destname> [--(fileoption)==value] [--filter=filter] [--fork=fork]**
+ **imgtool put <format> <imagename> <filename>... <destname> [--(fileoption)=value] [--filter=filter] [--fork=fork]**
* <format> is the image format, e.g. coco_jvc_rsdos
* <imagename> is the image filename; can specify a ZIP file for image name
@@ -151,7 +151,7 @@ Imgtool Subcommands
Imgtool Filters
-===============
+---------------
Filters are a means to process data being written into or read out of an image in a certain way. Filters can be specified on the get, put, and getall commands by specifying --filter=xxxx on the command line. Currently, the following filters are supported:
@@ -173,7 +173,7 @@ Filters are a means to process data being written into or read out of an image i
**vzsnapshot**
- [todo: VZ Snapshot? Find out what this is....]
+ [todo: VZ Snapshot? Find out what this is...]
**vzbas**
diff --git a/docs/source/tools/index.rst b/docs/source/tools/index.rst
index 6d0551bf1d1..4086f924b99 100644
--- a/docs/source/tools/index.rst
+++ b/docs/source/tools/index.rst
@@ -1,12 +1,14 @@
MAME External Tools
--------------------
+===================
-This section covers various extra tools that come with your MAME distribution (e.g. *imgtool*)
+This section describes additional tools that are built alongside and typically
+distributed with MAME.
.. toctree::
- :titlesonly:
+ :titlesonly:
- imgtool
- castool
- floptool
- othertools
+ chdman
+ imgtool
+ castool
+ floptool
+ othertools
diff --git a/docs/source/tools/othertools.rst b/docs/source/tools/othertools.rst
index eb4c479b846..5a24dc6c5bb 100644
--- a/docs/source/tools/othertools.rst
+++ b/docs/source/tools/othertools.rst
@@ -25,32 +25,40 @@ This tool is used in regression testing to compare PNG screenshot results with t
nltool
------
-Discrete component conversion tool. Most users will not need to work with this.
+Discrete component conversion tool.
+
nlwav
-----
-Discrete component conversion and testing tool. Most users will not need to work with this.
+Discrete component conversion and testing tool.
jedutil
-------
-PAL/PLA/PLD/GAL dump handling tool. It can convert between the industry-standard JED format and MAME's proprietary packed binary format and it can show logic equations for the types of devices it knows the internal logic of. Most users will not need to work with this.
+PAL/PLA/PLD/GAL dump handling tool. It can convert between the industry-standard JED format and MAME's proprietary packed binary format and it can show logic equations for the types of devices it knows the internal logic of.
ldresample
----------
-This tool recompresses video data for laserdisc and VHS dumps. Most users will not need to work with this.
+This tool recompresses video data for laserdisc and VHS dumps.
ldverify
--------
-This tool is used for comparing laserdisc or VHS CHD images with the source AVI. Most users will not need to work with this.
+This tool is used for comparing laserdisc or VHS CHD images with the source AVI.
+
+
+romcmp
+------
+
+This tool is used to perform basic data comparisons and integrity checks on binary dumps. With the -h switch, it can also be used to calculate hash functions.
+
unidasm
-------
-Universal disassembler for many of the architectures supported in MAME. Most users will not need to work with this.
+Universal disassembler for many of the architectures supported in MAME.
diff --git a/docs/source/usingmame/aboutromsets.rst b/docs/source/usingmame/aboutromsets.rst
index 51c72d0ce41..3a5197a3159 100644
--- a/docs/source/usingmame/aboutromsets.rst
+++ b/docs/source/usingmame/aboutromsets.rst
@@ -68,6 +68,24 @@ If you hit problems with a set not working, there are several things to check--
ROMs and CHDs
-------------
-ROM chip data tends to be relatively small and gets loaded to system memory outright. Some games also used additional storage mediums such as hard drives, CD-ROMs, DVDs, and Laserdiscs. Those storage mediums are, for multiple technical reasons, not well-suited to being stored the same way as ROM data and won't fit completely in memory in some cases.
-
-Thus, a new format was created for these in the CHD file. **Compressed Hunks of Data**, or CHD for short, are designed very specifically around the needs of mass storage media. Some arcade games, consoles, and PCs will require a CHD to run. As CHDs are already compressed, they should **NOT** be stored in a ZIP or 7Z file as you would for ROM images.
+ROM chip data tends to be relatively small and are loaded into system memory in
+their entirety. Some games also used additional storage media such as hard
+disks, CD-ROMs, DVDs, and LaserDiscs. Those storage media are, for multiple
+technical reasons, not well-suited to being stored the same way as ROM data and
+won’t fully fit in memory in some cases.
+
+Thus, a new format was created for these in the CHD file. **Compressed Hunks of
+Data** files, or CHD files for short, are designed very specifically around the
+needs of mass storage media. Some arcade games, consoles, and PCs will require
+one or more CHD files to run. As CHD files are already compressed, they
+**should not** be stored PKZIP or 7-Zip archives as ROM images would be.
+
+To save space when multiple variants of a system or software item are present,
+MAME supports *delta CHD* files. A delta CHD file only stores the parts of the
+data that differ from its *parent CHD* file. This allows large space savings
+when different variants share a lot of data. Delta CHD files can only be used
+for clone systems, devices with a parent ROM device, and clone software items.
+A delta CHD file must use a (non-delta) CHD file from the parent system, parent
+ROM device or parent software item as its parent CHD file. The parent CHD file
+must be present to use a delta CHD file, or MAME will not be able to read the
+shared data from it.
diff --git a/docs/source/usingmame/assetsearch.rst b/docs/source/usingmame/assetsearch.rst
new file mode 100644
index 00000000000..325d4bcfd7e
--- /dev/null
+++ b/docs/source/usingmame/assetsearch.rst
@@ -0,0 +1,398 @@
+.. _assetsearch:
+
+How does MAME look for files?
+=============================
+
+.. contents:: :local:
+
+Introduction
+------------
+
+Unlike typical desktop applications where you browse your disk and select a file
+to open or a location to save to, MAME has settings to tell it where to look for
+the files it needs. You can change these settings by starting MAME without
+specifying a system, selecting **Configure Options** from the system selection
+menu, and then selecting **Configure Directories** (remember to select **Save
+Configuration** if you want to keep your changes). You can also change settings
+by editing your mame.ini and ui.ini files directly, or specify settings on the
+command line. For information on available options for controlling where MAME
+searches for files, see :ref:`mame-commandline-pathoptions`.
+
+Terminology
+~~~~~~~~~~~
+
+It’s necessary to understand some MAME-specific terminology used in the
+explanations here:
+
+System
+ A system is a complete machine that can be emulated by MAME. Some systems
+ run fixed software, while others can load software from software list items
+ and/or media files.
+Device
+ An emulated component that can be used by multiple systems, or by other
+ devices. Some devices require ROM dumps, and some devices allow software
+ from additional software lists to be used with a system.
+Parent system
+ MAME uses so-called parent/clone relationships to group related systems.
+ One system in the group is chosen to be the *parent* and the others are
+ called *clones*. (The choice of the parent system is somewhat arbitrary.
+ It is not necessarily the original or definitive variant.)
+BIOS system
+ A system configured with no software. This is mostly applicable for arcade
+ systems that used interchangeable game cartridges or ROM boards. Note that
+ this is *not* the same as the BIOS selection settings that allow you to
+ select system boot ROMs or device firmware.
+Software item
+ A software package described in a software list. Software items may consist
+ of multiple *parts* that can be mounted independently. Due to the large
+ variety of media supported by MAME, software parts may use different
+ *loaders*. These include the *ROM loader*, typically used for cartridge
+ media, and the *image file loader*, used for software parts consisting of a
+ single media image (including floppy disk and cassette media).
+Parent software item
+ Related software items are grouped using parent/clone relationships, in a
+ similar way to related systems. This is usually used to group different
+ versions or releases of the same piece of software. If a software item has
+ a parent item, it will always be in the same software list.
+Short name
+ MAME uses *short names* to uniquely identify systems and devices, to
+ uniquely identify software lists, to uniquely identify software items within
+ a software list, and to uniquely identify software parts within a software
+ item.
+
+ You can see the short name for a system by highlighting it in the system
+ selection menu, ensuring the info panel is visible on the right, and
+ showing the **General Info** in the **Infos** tab. For example the short
+ name for the Nintendo Virtual Boy is ``vboy``. System and device short
+ names can also be seen in the output of various command line verbs,
+ including ``-listxml``, ``-listfull``, ``-listroms`` and ``-listcrc``.
+
+ You can see the short names for a software item and the software list it
+ belongs to by highlighting it in the software selection menu, ensuring the
+ info panel is visible on the right, and showing the **Software List Info**
+ in the **Infos** tab. For example the short name for Macintosh System
+ Software 6.0.3 is ``sys603`` and the short name of the software list it
+ belongs to is ``mac_flop``. Software list short names match their file
+ names (for example the Sega Mega Drive/Genesis cartridge software list is
+ called **megadriv.xml** and its short name is ``megadriv``). You can also
+ see the short names software lists, software items and parts by finding the
+ ``name`` attributes in the XML software list files.
+
+
+Search path options
+-------------------
+
+Most options for specifying locations to search allow multiple directories to be
+specified, separated by semicolon (``;``) characters. Environment variables are
+expanded, using CMD shell syntax on Windows, or Bourne shell syntax on UNIX-like
+systems.
+
+Relative paths are interpreted relative to the current working directory at the
+time of use. If you start MAME by double-clicking it in Windows Explorer, the
+working directory is set to the folder containing the MAME executable. If you
+start MAME by double-clicking it in the macOS Finder or from most Linux desktop
+environments, the working directory will be set to your home directory.
+
+
+Archive files
+-------------
+
+MAME can load files from PKZIP and 7-Zip archives (these must have ``.zip`` and
+``.7z`` file name extensions, respectively). A number of extensions to the
+PKZIP format are supported, including Zip64 for large archives, NTFS timestamps,
+and LZMA compression. Only ASCII or UTF-8 filenames are supported in PKZIP
+archives (7-Zip archives always use UTF-16 filenames).
+
+MAME *does not* load files from nested archives. MAME will not load files
+stored in a PKZIP or 7-Zip archive which is itself contained within a PKZIP or
+7-Zip archive. Multi-segment archives and encrypted archives are not supported.
+The legacy “implode” compression method in PKZIP archives is not supported.
+
+MAME may perform poorly with archives containing large numbers of files. Files
+compressed using the LZMA compression algorithm are inherently more
+CPU-intensive to decompress than files compressed using simpler algorithms.
+MAME does not take the archive layout into consideration when loading files from
+archives, so using “solid compression” often results in MAME decompressing the
+same data repeatedly when loading media.
+
+
+How does MAME search for media?
+-------------------------------
+
+Use the :ref:`rompath <mame-commandline-rompath>` option sets the folders where
+searches for ROM dumps, disk images, and other media. By default MAME looks for
+media in a folder called **roms** in the working directory. For the purpose of
+this discussion, floppy disk, cassette, paper tape and other media images that
+are not stored in CHD format are treated as ROM dumps.
+
+When searching for system, device and software ROM dumps, MAME treats folders
+and archives inside the folders configured in you ``rompath`` setting as
+equivalent, but remember the limitation that MAME cannot load files from an
+archive contained within another archive. MAME looks for a folder first, then a
+PKZIP archive, and finally a 7-Zip archive. When searching for a ROM dump in an
+archive, MAME first looks for a file with the expected name and CRC. If no
+matching file is found, MAME looks for a file with the expected CRC ignoring the
+name. If no matching file is found, MAME finally looks for a file with the
+expected name, ignoring the CRC.
+
+While MAME can load disk images in CHD format from inside archives, this is not
+recommended. CHD files contain compressed data stored in a format allowing
+random access. If a CHD format disk image is stored in a PKZIP or 7-Zip
+archive, MAME needs to load the entire file into memory in order to use it. For
+hard disk or LaserDisc images in particular, this will likely use an excessive
+amount of swap file space, hurting performance and possibly reducing the life
+expectancy of your disks or SSDs. It’s best to keep CHD format disk images in
+folders.
+
+System ROMs
+~~~~~~~~~~~
+
+For each folder configured in your ``rompath`` setting, MAME looks for system
+ROMs in the following locations:
+
+* A folder or archive matching the short name of the system itself.
+* A folder or archive matching the short name of the system’s parent system, if
+ applicable.
+* A folder or archive matching the short name of the corresponding BIOS system,
+ if applicable.
+
+Using Shiritsu Justice Gakuen as an example, MAME will search for system ROMs as
+follows:
+
+* The short name of the system is ``jgakuen``, so MAME will look for a folder
+ called **jgakuen**, a PKZIP archive called **jgakuen.zip**, or a 7-Zip archive
+ called **jgakuen.7z**.
+* The parent system is the European version of Rival Schools, which has the
+ short name ``rvschool``, so MAME will look for a folder called **rvschool**, a
+ PKZIP archive called **rvschool.zip**, or a 7-Zip archive called
+ **rvschool.7z**.
+* The corresponding BIOS system is the Capcom ZN2 board, which has the short
+ name ``coh3002c``, so MAME will look for a folder called **coh3002c**, a PKZIP
+ archive called **coh3002c.zip**, or a 7-Zip archive called **coh3002c.7z**.
+
+Device ROMs
+~~~~~~~~~~~
+
+For each folder configured in your ``rompath`` setting, MAME looks for device
+ROMs in the following locations:
+
+* A folder or archive matching the short name of the device.
+* A folder or archive matching the short name of the device’s parent ROM device,
+ if applicable.
+* A folder or archive matching the short name of the system.
+* A folder or archive matching the short name of the system’s parent system, if
+ applicable.
+* A folder or archive matching the short name of the corresponding BIOS system,
+ if applicable.
+
+Using a Unitron 1024 Macintosh clone with a French Macintosh Plus keyboard with
+integrated numeric keypad attached as an example, MAME will look for the
+keyboard microcontroller ROM as follows:
+
+* The short name of the French Macintosh Plus keyboard is ``mackbd_m0110a_f``,
+ so MAME will look for a folder called **mackbd_m0110a_f**, a PKZIP archive
+ called **mackbd_m0110a_f.zip**, or a 7-Zip archive called
+ **mackbd_m0110a_f.7z**.
+* The parent ROM device is the U.S. Macintosh Plus keyboard with integrated
+ numeric keypad, which has the short name ``mackbd_m0110a``, so MAME will look
+ for a folder called **mackbd_m0110a**, a PKZIP archive called
+ **mackbd_m0110a.zip**, or a 7-Zip archive called **mackbd_m0110a.7z**.
+* The short name of the Unitron 1024 system is ``utrn1024``, so MAME will look
+ for a folder called **utrn1024**, a PKZIP archive called **utrn1024.zip**, or
+ a 7-Zip archive called **utrn1024.7z**.
+* The parent system of the Unitron 1024 is the Macintosh Plus, which has the
+ short name ``macplus``, so MAME will look for a folder called **macplus**, a
+ PKZIP archive called **macplus.zip**, or a 7-Zip archive called
+ **macplus.7z**.
+* There is no corresponding BIOS system, so MAME will not search in any further
+ locations.
+
+Software Item ROMs
+~~~~~~~~~~~~~~~~~~
+
+For each folder configured in your ``rompath`` setting, MAME looks for software
+item ROMs in the following locations:
+
+* A folder or archive matching the short name of the software item inside a
+ folder matching the short name of the software list (or a folder matching the
+ short name of the software item inside an archive matching the name of the
+ software list).
+* A folder or archive matching the short name of the parent software item inside
+ a folder matching the short name of the software list, if applicable (or a
+ folder matching the short name of the parent software item in an archive
+ matching the name of the software list).
+* A folder or archive matching the short name of the software item. (This is
+ for convenience for software items that also run as stand-alone systems with
+ the same short name, such as Neo Geo games.)
+* A folder or archive matching the short name of the parent software item, if
+ applicable. (This is for convenience for software items that also run as
+ stand-alone systems with the same short name, such as Neo Geo games.)
+
+If you load the German version of Dune II from the Mega Drive/Genesis cartridge
+software list in the PAL Mega Drive console, MAME will look for the cartridge
+ROM as follows:
+
+* The short name of the software item for the German version of Dune II is
+ ``dune2g`` and the short name of the Mega Drive/Genesis cartridge software
+ list is ``megadriv``, so MAME will look for a folder called **dune2g**, a
+ PKZIP archive called **dune2g.zip** or a 7-Zip archive called **dune2g.7z**
+ inside a folder called **megadriv** (or a folder called **dune2g** inside a
+ PKZIP archive called **megadriv.zip** or a 7-Zip archive called
+ **megadriv.7z**).
+* The parent software item is the general European PAL version of Dune II in the
+ same software list, which has the short name ``dune2``, so MAME will look for
+ a folder called **dune2**, a PKZIP archive called **dune2.zip** or a 7-Zip
+ archive called **dune2.7z** inside a folder called **megadriv** (or a folder
+ called **dune2** inside a PKZIP archive called **megadriv.zip** or a 7-Zip
+ archive called **megadriv.7z**).
+* Next MAME will ignore the short name of the software list and use the short
+ name of the software item only, looking for a folder called **dune2g**, a
+ PKZIP archive called **dune2g.zip** or a 7-Zip archive called **dune2g.7z**.
+* Still ignoring the short name of the software list, MAME will use the short
+ name of the parent software item only, looking for a folder called **dune2**,
+ a PKZIP archive called **dune2.zip** or a 7-Zip archive called **dune2.7z**.
+
+CHD format disk images
+~~~~~~~~~~~~~~~~~~~~~~
+
+MAME searches for system, device and software item CHD format disk images in
+almost the same way it searches for ROMs, with just a few differences:
+
+* For systems and software items, MAME will check the parent system or software
+ item if applicable for alternate names for a disk image with the same content
+ digest. This allows you to keep a single copy of a CHD format disk image for
+ a parent system or software item and any clones that expect a disk image with
+ the same content, irrespective of the name the clones expect.
+* For software items, MAME will look for CHD format disk images in a folder
+ matching the short name of the software list. This is for convenience when
+ all items in a software list only contain a single CHD format disk image each.
+* We recommend that you *do not* store CHD format disk images inside PKZIP or
+ 7-Zip archives. However, if you do decide to do this, MAME will only find CHD
+ format disk images inside archives with an expected name. This is because
+ MAME uses the content digest from the CHD header, not the checksum of the CHD
+ file itself. The checksum of the CHD file itself can vary depending on
+ compression options.
+
+To save space, MAME allows delta CHD files to be used for clone systems, devices
+with parent ROM devices and clone software items. The delta CHD file must use a
+CHD format disk image from the parent system, parent ROM device or parent
+software item as its parent CHD file. The space saved depends on how much
+content can be reused from the parent CHD file. MAME searches the same
+locations for parent CHD files that it would search for the disk image itself.
+
+Loose software
+~~~~~~~~~~~~~~
+
+Many systems support loading media from a file by supplying the path on the
+command line for one of the media options. Relative paths are interpreted
+relative to the current working directory.
+
+You can specify a path to a file inside a PKZIP or 7-Zip archive similarly to
+specifying a path to a file in a folder (keep in mind that you can have at most
+a single archive file in a path, as MAME does not support loading files from
+archives contained within other archives). If you specify a path to a PKZIP or
+7-Zip archive, MAME will use the first file found in the archive (this depends
+on the order that files are stored in the archive – it’s most useful for
+archives containing a single file).
+
+Start the Nintendo Entertainment System/Famicom system with the file
+**amazon_diet_EN.nes** mounted in the cartridge slot:
+
+.. code-block:: bash
+
+ mame nes -cart amazon_diet_EN.nes
+
+Start the Osborne-1 system with the first file in the archive **os1xutls.zip**
+mounted in the first floppy disk drive:
+
+.. code-block:: bash
+
+ mame osborne1 -flop1 os1xutils.zip
+
+Start the Macintosh Plus system with the file **system tools.img** in the
+archive **sys603.zip** mounted in the first floppy disk drive:
+
+.. code-block:: bash
+
+ mame macplus -flop1 "sys603.zip/system tools.img"
+
+Diagnosing missing media
+~~~~~~~~~~~~~~~~~~~~~~~~
+
+When starting a system from MAME’s system selection menu or software selection
+menu, MAME will list any missing system or device ROM dumps or disk images, as
+long as at least one ROM dump or disk image for the system is present. For
+clone systems, at least one ROM dump or disk image *unique to the clone* must be
+present for MAME to list missing ROM dumps and disk images.
+
+If all system and device ROM dump and disk images are present and the system is
+being started with a software item, MAME will check that ROM dumps and disk
+images for the software item are present. If at least one ROM dump or disk
+image for the software item is present, MAME will list any missing ROM dumps or
+disk images.
+
+For example if you try to start the Macintosh Plus system and the keyboard
+microcontroller ROM dump is missing, MAME displays the following error message:
+
+ Required ROM/disk images for the selected system are missing or incorrect.
+ Please acquire the correct files or select a different system.
+
+ 341-0332-a.bin (mackbd_m0110a) - not found
+
+ Press any key to continue.
+
+The name of the missing ROM dump is shown (**341-0332-a.bin**), as well as the
+short name of the device it belongs to (``mackbd_m0110a``). When a missing ROM
+dump or disk image is not specific to the selected system, the short name of the
+system or device it belongs to is shown.
+
+If you start a system in MAME from a command prompt, MAME will show where it
+searched for any ROM dumps or disk images that were not found.
+
+Using the example of a Unitron 1024 Macintosh clone with a French keyboard
+connected, MAME will show the following error messages if no ROMs are present::
+
+ mame utrn1024 -kbd frp
+ 342-0341-a.u6d NOT FOUND (tried in utrn1024 macplus)
+ 342-0342-a.u8d NOT FOUND (tried in utrn1024 macplus)
+ 341-0332-a.bin NOT FOUND (tried in mackbd_m0110a_f mackbd_m0110a utrn1024 macplus)
+
+MAME used the system short name ``utrn1024`` and the parent system short name
+``macplus`` when searching for system ROMs. When searching for the keyboard
+microcontroller ROM, MAME used the device short name ``mackbd_m0110a_f``, the
+parent ROM device short name ``mackbd_m0110a``, the system short name
+``utrn1024``, and the parent system short name ``macplus``.
+
+Software parts that use the ROM loader (typically cartridge media) show similar
+messages when ROM dumps are not found. Using the example of the German version
+of Dune II on a PAL Mega Drive, MAME will show the following error messages if
+no ROMs are present::
+
+ mame megadriv dune2g
+ mpr-16838-f.u1 NOT FOUND (tried in megadriv\dune2g megadriv\dune2 dune2g dune2 megadriv genesis)
+ Fatal error: Required files are missing, the machine cannot be run.
+
+MAME searched for the cartridge ROM using:
+
+* The software list short name ``megadriv`` and the software item short name
+ ``dune2g``.
+* The software list short name ``megadriv`` and the parent software item short
+ name ``dune2``.
+* The software item short name ``dune2g`` only.
+* The parent software item short name ``dune2`` only.
+* The locations that would be searched for the PAL Mega Drive system (the system
+ short name ``megadriv`` and the parent system short name ``genesis``).
+
+Software parts that use the image file loader (including floppy disk and
+cassette media) only check for media after ROM images are loaded, and missing
+media files are shown differently. Using the example of Macintosh System 6.0.3,
+MAME will show these error messages if the software is missing::
+
+ mame macplus -flop1 sys603:flop1
+ :fdc:0:35dd: error opening image file system tools.img: No such file or directory (generic:2) (tried in mac_flop\sys603 sys603 macplus)
+ Fatal error: Device Apple/Sony 3.5 DD (400/800K GCR) load (-floppydisk1 sys603:flop1) failed: No such file or directory
+
+The error messages show where MAME searched for the image file in the same
+format. In this case, it used the software list short name ``mac_flop`` and the
+software short name ``sys603``, the software short name ``sys603`` only, and
+the locations that would be searched for system ROMs.
diff --git a/docs/source/usingmame/commonissues.rst b/docs/source/usingmame/commonissues.rst
index bf489fdd9fb..50f81671934 100644
--- a/docs/source/usingmame/commonissues.rst
+++ b/docs/source/usingmame/commonissues.rst
@@ -25,6 +25,8 @@ Common Issues and Questions (FAQ)
19. :ref:`Blackscreen-DirectX`
20. :ref:`ControllerIssues`
21. :ref:`ExternalOPL`
+22. :ref:`Autofire`
+23. :ref:`gsync-freesync`
.. _rapid-coins:
@@ -32,9 +34,14 @@ Common Issues and Questions (FAQ)
Why does my game show an error screen if I insert coins rapidly?
----------------------------------------------------------------
-This is not a bug in MAME. On original arcade hardware, you simply could not insert coins as fast as you can mashing the button. The only ways you could get credit feeding at that kind of pace was if the coin mech hardware was defective or if you were physically trying to cheat the coin mech.
+This is not a bug in MAME. On original arcade hardware, you simply could not
+insert coins as fast as you can mash the button. The only ways you could feed
+credits at that kind of pace was if the coin mech hardware was defective or if
+you were physically trying to cheat the coin mech.
-In either case, the game would display an error for the operator to look into the situation to prevent cheating them out of their hard-earned cash. Keep a slow, coin-insert-ish pace and you'll not trigger this.
+In either case, the game would display an error for the operator to look into
+the situation to prevent cheating them out of their hard-earned cash. Keep a
+slow, coin-insert-ish pace and you won’t trigger this.
.. _broken-package:
@@ -42,11 +49,25 @@ In either case, the game would display an error for the operator to look into th
Why is my non-official MAME package (e.g. EmuCR build) broken? Why is my official update broken?
------------------------------------------------------------------------------------------------
-In many cases, updates to various subsystems such as HLSL, BGFX, or Lua plugins come as updates to the external shader files as well as to the core MAME code. Unfortunately, builds that come from third parties may come as just a main MAME executable or with outdated external files, which can break the coupling between these external files and MAME core code. Despite repeated attempts at contacting some of these third parties to warn them, they persist in distributing broken MAME updates.
+Many MAME features, such as software lists, HLSL or BGFX shaders, Lua plugins
+and UI translations, use external files. Updates to these features often
+require the external files to be updated along with MAME. Unfortunately, builds
+provided by third parties may only include the main MAME executable, or may
+include outdated external files. Using an updated MAME executable with outdated
+external files causes issues with features reliant on the external files.
+Despite repeated requests that they distribute MAME complete with matching
+external files, some of these third parties persist in distributing incomplete
+or broken MAME updates.
-As we have no control over how third parties distribute these, all we really can do is disclaim the use of sites like EmuCR and say that we cannot provide support for packages we didn't build. Compile your own MAME or use one of the official packages provided by us.
+As we have no control over how third parties distribute MAME, all we really can
+do is recommend against obtaining MAME from sites like EmuCR. We cannot provide
+any support for packages we didn’t build ourselves. You can completely avoid
+these issues by compiling MAME yourself, or using an official package we
+provide.
-You may also run into this problem if you have not replaced the contents of the HLSL and BGFX folders with the latest files when updating your MAME install with a new official build.
+You may also encounter this problem if you do not update the contents of the
+``hlsl``, ``bgfx`` or ``plugins`` folders when updating your MAME installation
+with a new official build.
.. _faster-if-X:
@@ -68,7 +89,7 @@ There's still room for improvements in MAME's speed, but chances are that if you
Why do my Neo Geo ROMs no longer work? How do I get the Humble Bundle Neo Geo sets working?
-------------------------------------------------------------------------------------------
-Recently the Neo Geo BIOS was updated to add a new version of the Universal BIOS. This was done between 0.171 and 0.172, and results in an error trying to load Neo Geo games with an un-updated **neogeo.zip** set.
+Recently the Neo Geo BIOS was updated to add a new version of the Universe BIOS. This was done between 0.171 and 0.172, and results in an error trying to load Neo Geo games with an un-updated **neogeo.zip** set.
This also affects the Humble Bundle set: the games themselves are correct and up to date as of MAME 0.173 (and most likely will remain so) though you'll have to pull the ROM set .ZIP files out of the package somehow yourself. However, the Neo Geo BIOS set (**neogeo.zip**) included in the Humble Bundle set is incomplete as of the 0.172 release of MAME.
@@ -116,15 +137,32 @@ If you have several games and you wish to verify that they are compatible with t
.. _Parent-Sets:
Why is it that some games have the US version as the main set, some have Japanese, and some are the World?
------------------------------------------------------------------------------------------------------------
+----------------------------------------------------------------------------------------------------------
-While this rule isn't always true, there is typically a method to how sets are arranged. The usual priority is to go with the **World** set if it's available, **US** if no World English set exists, and **Japanese** or other origin region if no World or US English set.
+Parent and clone sets are a convenience feature to help keep different versions
+of the same system or software together. The decision on which set to make the
+parent will always be somewhat arbitrary, but we do have some guidelines:
-Exceptions arise where the US or World sets have significant censorship/changes from the original version. For instance, Gals Panic (set **galsnew**) uses the US version as parent because it has additional features compared to the world export version (set **galsnewa**). These features are optional censorship, an additional control layout option (stick with no button use), and English-language voice clips.
+* Prefer latest release version
+* Prefer English language
+* Prefer most widespread release
+* Prefer most complete version
+* Prefer versions that are uncensored, and have story/cutscenes intact
+* Prefer versions that keep the original gameplay balance
+* Prefer releases from original developers/publishers rather than licensees
+* Prefer releases without region-specific notices or warnings
-Another exception comes for games where it was licensed to a third party for export release. Pac-Man, for instance, was published by Midway in the US though it was created by Namco. As a result, the parent set is the Japanese **puckman** set, which retains the Namco copyright.
+It’s not always possible to choose a set that’s preferred according to all
+criteria.
-Lastly, a developer adding a new set can choose to use whatever naming and parent scheme they wish and are not restricted to the above rules. Most follow these guidelines, however.
+As an example, the World release of Ghouls’n Ghosts (*ghouls*) is the parent of
+the US release (*ghoulsu*) and the Japanese original Daimakaimura, as it is the
+most widespread English-language release, and has the story and cutscenes
+intact.
+
+Another example is Midway Pac-Man (*pacman*), which is a clone of Namco Puck
+Man (*puckman*), because Pac-Man is a licensed version for the US market, while
+Puck Man was released by Namco themselves.
.. _Legal-ROMs:
@@ -134,9 +172,12 @@ How do I legally obtain ROMs or disk images to run on MAME?
You have several options:
-* You can obtain a license to them by purchasing one via a distributor or vendor who has proper authority to do so.
-* You can download one of the ROM sets that have been released for free to the public for non-commerical use.
-* You can purchase an actual arcade PCB, read the ROMs or disks yourself, and let MAME use that data.
+* You can obtain a license to them by purchasing one via a distributor or vendor
+ who has proper authority to do so.
+* You can download one of the ROM sets that have been released for free to the
+ public for non-commercial use.
+* You can purchase an actual arcade PCB, read the ROMs or disks yourself, and
+ let MAME use that data.
Beyond these options, you are on your own.
@@ -146,7 +187,8 @@ Beyond these options, you are on your own.
Isn't copying ROMs a legal gray area?
-------------------------------------
-No, it's not. You are not permitted to make copies of software without the copyright owner's permission. This is a black & white issue.
+No, it’s not. You are not permitted to make copies of software without the
+copyright owner’s permission. This is a black and white issue.
.. _Abandonware:
@@ -154,7 +196,8 @@ No, it's not. You are not permitted to make copies of software without the copyr
Can't game ROMs be considered abandonware?
------------------------------------------
-No. Even the companies that went under had their assets purchased by somebody, and that person is the copyright owner.
+No. Even the companies that went under had their assets purchased by somebody,
+and that person is the copyright owner.
.. _Old-Sets:
@@ -170,7 +213,13 @@ As time passes, MAME is perfecting the emulation of older games, even when the r
What about those arcade cabinets on eBay that come with all the ROMs?
---------------------------------------------------------------------
-If the seller does not have a proper license to include the ROMs with his system, he is not allowed to legally include any ROMs with his system. If he has purchased a license to the ROMs in your name from a distributor or vendor with legitimate licenses, then he is okay to include them with the cabinet. After signing an agreement, cabinet owners that include legitimate licensed ROMs may be permitted to include a version of MAME that runs those ROMs and nothing more.
+If the seller does not have a proper license to include the ROMs with their
+system, they are not legally permitted to include any ROMs with the system.
+If they have purchased a license to the ROMs in your name from a distributor or
+vendor with legitimate licenses, then they may include the ROMs with the
+cabinet. After signing an agreement, cabinet owners that include legitimate
+licensed ROMs may be permitted to include a version of MAME that runs those ROMs
+and nothing more.
.. _ROM-DVDs:
@@ -178,9 +227,17 @@ If the seller does not have a proper license to include the ROMs with his system
What about those guys who burn DVDs of ROMs for the price of the media?
-----------------------------------------------------------------------
-What they are doing is just as illegal as selling the ROMs outright. As long as somebody owns the copyright, making illegal copies is illegal, period. If someone went on the internet and started a business of selling cheap copies of the latest U2 album for the price of media, do you think they would get away with it?
+What they are doing is just as unlawful as selling the ROMs outright. As long
+as somebody holds the copyright, making unauthorised copies is unlawful. If
+someone went on the internet and started a business of selling cheap copies of
+U2 albums for the price of media, do you think they would get away with it?
-Even worse, a lot of these folks like to claim that they are helping the project. In fact, they only create more problems for the MAME team. We are not associated with these people in any way regardless of how "official" they may attempt to appear. You are only helping criminals make a profit through selling software they have no right to sell. **Anybody using the MAME name and/or logo to sell such products is also in violation of the MAME trademark.**
+Even worse, a lot of these people like to claim that they are helping the
+project. In reality, they only create more problems for the MAME team. We are
+not associated with these people in any way, regardless of how “official” they
+may attempt to appear. By buying from them, you only help criminals profit from
+selling software they have no right to sell. **Anyone using the MAME name
+and/or logo to sell such products is also in violation of the MAME trademark.**
.. _DMCA-exemption:
@@ -188,7 +245,12 @@ Even worse, a lot of these folks like to claim that they are helping the project
But isn't there a special DMCA exemption that makes ROM copying legal?
----------------------------------------------------------------------
-No, you have misread the exemptions. The exemption allows people to reverse engineer the copy protection or encryption in computer programs that are obsolete. The exemption simply means that figuring out how these obsolete programs worked is not illegal according to the DMCA. It does not have any effect on the legality of violating the copyright on computer programs, which is what you are doing if you make copies of ROMs.
+No, you have misread the exemptions. The exemption allows people to
+reverse-engineer the copy protection or encryption in computer programs that are
+obsolete. The exemption simply means that figuring out how these obsolete
+programs worked is not illegal according to the DMCA. It does not have any
+effect on the legality of making unauthorised copies of computer programs, which
+is what you are doing if you make copies of ROMs.
.. _24-hours:
@@ -196,7 +258,9 @@ No, you have misread the exemptions. The exemption allows people to reverse engi
But isn't it OK to download and "try" ROMs for 24 hours?
--------------------------------------------------------
-This is an urban legend that was made up by people who put ROMs up for download on their sites, in order to justify the fact that they were breaking the law. There is nothing like this in any copyright law.
+This is an urban legend that was made up by people who made ROMs available for
+download from their web sites, in order to justify the fact that they were
+breaking the law. There is no provision like this in any copyright law.
.. _commercial-use:
@@ -230,9 +294,22 @@ Additional troubleshooting information can be found on Microsoft's website at ht
I have a controller that doesn't want to work with the standard Microsoft Windows version of MAME, what can I do?
-----------------------------------------------------------------------------------------------------------------
-By default, MAME on Microsoft Windows tries to do raw reads of the joystick(s), mouse/mice, and keyboard(s). This works with most devices and provides the most stable results. However, some devices need special drivers to translate their output and these drivers may not work with raw input.
+By default, MAME on Microsoft Windows tries to read joystick(s), mouse/mice and
+keyboard(s) using the RawInput API. This works with most devices, and allows
+multiple keyboards and mice to be used independently. However, some device
+drivers are not compatible with RawInput, and it may be necessary to use
+DirectInput or window events to receive input. This is also the case for most
+software that simulates mouse or keyboard input, like JoyToKey, VNC or Remote
+Desktop.
-One thing you can try is setting the keyboardprovider, mouseprovider, or joystickprovider setting (depending on which kind of device your input device acts as) from rawinput to one of the other options such as dinput or win32. See :ref:`osd-commandline-options` for details on supported providers.
+You can try changing the
+:ref:`keyboardprovider <mame-commandline-keyboardprovider>`,
+:ref:`mouseprovider <mame-commandline-mouseprovider>`,
+:ref:`joystickprovider <mame-commandline-joystickprovider>` or
+:ref:`lightgunprovider <mame-commandline-lightgunprovider>` setting (depending
+on which kind of device you’re having issues with) from ``rawinput`` to one of
+the other options such as ``dinput`` or ``win32``. See
+:ref:`mame-commandline-osdoptions` for details on input provider options
.. _ExternalOPL:
@@ -240,6 +317,53 @@ One thing you can try is setting the keyboardprovider, mouseprovider, or joystic
What happened to the MAME support for external OPL2-carrying soundcards?
------------------------------------------------------------------------
-MAME added support in version 0.23 for the use of a soundcard's onboard OPL2 (Yamaha YM3812 chip) instead of emulating the OPL2. This feature was never supported on the official Windows version of MAME and was dropped entirely as of MAME 0.60, because the OPL2 emulation in MAME had become advanced enough to be a better solution in almost all cases as of that time; now it's superior to using a sound card's YM3812 in all cases, especially as modern cards lack a YM3812.
+MAME 0.23 added support for using a sound card’s onboard OPL2 (Yamaha YM3812
+chip) instead of emulating the OPL2. This feature was only supported for DOS –
+it was never supported in official Windows versions of MAME. It dropped
+entirely as of MAME 0.60, as the OPL2 emulation in MAME had become advanced
+enough to be a better solution in almost all cases. MAME’s OPL2 emulation is
+now superior to using a sound card’s YM3812 in all cases, especially as modern
+sound cards lack a YM3812.
+
+
+.. _Autofire:
+
+What happened to the MAME support for autofire?
+-----------------------------------------------
+
+A Lua plugin providing enhanced autofire support was added in MAME 0.210, and
+the built-in autofire functionality was removed in MAME 0.216. This plugin has
+more functionality than the built-in autofire feature it replaced; for example,
+you can configure alternate buttons for different autofire rates.
+
+You can enable and configure the new autofire system with the following steps:
+
+* Start MAME with no system selected.
+* Choose **Configure Options** at the bottom (use **Tab** to move focus, or
+ double-click the menu item).
+* Choose **Plugins** near the bottom of the Settings menu.
+* Turn **Autofire plugin** on (use **Left**/**Right** or click the arrows to
+ change options).
+* Exit MAME completely and start MAME again so the setting takes effect.
+
+The setting will be automatically saved for future use.
+
+See :ref:`plugins-autofire` for more information about using the autofire
+plugin, or :ref:`plugins` for more information about using plugins with MAME in
+general.
+
+
+.. _gsync-freesync:
+
+Does MAME support G-Sync or FreeSync? How do I configure MAME to use them?
+--------------------------------------------------------------------------
+
+MAME supports both G-Sync and FreeSync right out of the box for Windows and Linux, however macOS does not support G-Sync or FreeSync.
+
+* Make sure your monitor is capable of at least 120Hz G-Sync/FreeSync. If your monitor is only capable of 60Hz in G-Sync/FreeSync modes, you will hit problems with drivers such as *Pac-Man* that run at 60.60606Hz and may hit problems with others that are very close to but not quite 60Hz.
+* If playing MAME windowed or using the BGFX video system, you'll need to make sure that you have G-Sync/FreeSync turned on for windowed applications as well as full screen in your video driver.
+* Be sure to leave triple buffering turned off.
+* Turning VSync on is suggested in general with G-Sync and FreeSync.
+* Low Latency Mode will not affect MAME performance with G-Sync/FreeSync.
-Unofficial builds of MAME may have supported it for varying amounts of time as well. \ No newline at end of file
+The effects of G-Sync and FreeSync will be most noticeable in drivers that run at refresh rates that are very different from normal PC refresh rates. For instance, the first three *Mortal Kombat* titles run at 54.706841Hz.
diff --git a/docs/source/usingmame/defaultkeys.rst b/docs/source/usingmame/defaultkeys.rst
index 73bcb1c12fe..9892c86cb1f 100644
--- a/docs/source/usingmame/defaultkeys.rst
+++ b/docs/source/usingmame/defaultkeys.rst
@@ -1,106 +1,748 @@
-.. _default-keys:
-
-Default Keys
-============
-
-All the keys below are fully configurable in the user interface. This list shows the standard keyboard configuration.
-
-
-================ ===============================================================================
- Key | Action
----------------- -------------------------------------------------------------------------------
-**Tab** | Toggles the configuration menu.
-**~** | Toggles the On Screen Display. When the on-screen display is
- | visible, you can use the following keys to control it:
- |
- | * **Up** - select previous parameter to modify
- | * **Down** - select next parameter to modify
- | * **Left** - decrease the value of the selected parameter
- | * **Right** - increase the value of the selected parameter
- | * **Enter** - reset parameter value to its default
- | * **Control+Left** - decrease the value by 10x
- | * **Shift+Left** - decrease the value by 0.1x
- | * **Alt+Left** - decrease the value by the smallest amount
- | * **Control+Right** - increase the value by 10x
- | * **Shift+Right** - increase the value by 0.1x
- | * **Alt+Right** - increase the value by the smallest amount
- |
- | If you are running with -debug, this key sends a 'break' in emulation.
-**P** | Pauses the game.
-**Shift+P** | While paused, advances to next frame. If rewind is enabled, a new rewind save state is also captured.
-**Shift+~** | While paused, loads the most recent rewind save state.
-**F2** | Service Mode for games that support it.
-**F3** | Resets the game.
-**Shift+F3** | Performs a "hard reset", which tears everything down and re-creates it
- | from scratch. This is a more thorough and complete reset than the reset
- | you get from hitting F3.
-**LCtrl+F3** | [SDL ONLY] - Toggle uneven stretch.
-**F4** | Shows the game palette, decoded GFX, and any tilemaps. Use the Enter key to
- | switch between the three modes (palette, graphics, and tilemaps). Press F4
- | again to turn off the display. The key controls in each mode vary slightly:
- |
- | Palette/colortable mode:
- | * **[ ]** - switch between palette and colortable modes
- | * **Up/Down** - scroll up/down one line at a time
- | * **Page Up/Page Down** - scroll up/down one page at a time
- | * **Home/End** - move to top/bottom of list
- | * **-/+** - increase/decrease the number of colors per row
- | * **Enter** - switch to graphics viewer
- |
- | Graphics mode:
- | * **[ ]** - switch between different graphics sets
- | * **Up/Down** - scroll up/down one line at a time
- | * **Page Up/Page Down** - scroll up/down one page at a time
- | * **Home/End** - move to top/bottom of list
- | * **Left/Right** - change color displayed
- | * **R** - rotate tiles 90 degrees clockwise
- | * **-/+** - increase/decrease the number of tiles per row
- | * **Enter** - switch to tilemap viewer
- |
- | Tilemap mode:
- | * **[ ]** - switch between different tilemaps
- | * **Up/Down/Left/Right** - scroll 8 pixels at a time
- | * **Shift+Up/Down/Left/Right** - scroll 1 pixel at a time
- | * **Control+Up/Down/Left/Right** - scroll 64 pixels at a time
- | * **R** - rotate tilemap view 90 degrees clockwise
- | * **-/+** - increase/decrease the zoom factor
- | * **Enter** - switch to palette/colortable mode
- |
- | Note: Not all games have decoded graphics and/or tilemaps.
-**LCtrl+F4** | [*SDL ONLY*] - Toggles keeping aspect ratio.
-**LCtrl+F5** | [*SDL ONLY*] - Toggle Filter.
-**Alt+Ctrl+F5** | [*NON SDL MS WINDOWS ONLY*] - Toggle HLSL Post-Processing.
-**F6** | Toggle cheat mode (if started with "-cheat").
-**LCtrl+F6** | Decrease Prescaling.
-**F7** | Load a save state. You will be requested to press a key to determine which
- | save state you wish to load.
- |
- | *Note that the save state feature is not supported for a large number of*
- | *drivers. If support is not enabled for a given driver, you will receive*
- | *a warning when attempting to save or load.*
-**LCtrl+F7** | Increase Prescaling.
-**Shift+F7** | Create a save state. Requires an additional keypress to identify the state,
- | similar to the load option above.
-**F8** | Decrease frame skip on the fly.
-**F9** | Increase frame skip on the fly.
-**F10** | Toggle speed throttling.
-**F11** | Toggles speed display.
-**Shift+F11** | Toggles internal profiler display (if compiled in).
-**Alt+F11** | Record HLSL Rendered Video.
-**F12** | Saves a screen snapshot.
-**Alt+F12** | Take HLSL Rendered Snapshot.
-**Insert** | [*WINDOW ONLY, NON-SDL*] Fast forward. While held, runs game with
- | throttling disabled and with the maximum frameskip.
-**Page DN** | [*SDL ONLY*] Fast forward. While held, runs the game with throttling
- | disabled and with the maximum frameskip.
-**Alt+ENTER** | Toggles between full-screen and windowed mode.
-**Scroll Lock** | Default mapping for the **uimodekey**.
- |
- | This key allows users to disable and enable the emulated keyboard
- | in machines that require it. All emulations which require emulated
- | keyboards will start in that mode and you can only access the internal
- | UI (hitting TAB) by first hitting this key. You can change the initial
- | status of the emulated keyboard as presented upon start by using
- | **-ui_active** as detailed below.
-**Escape** | Exits emulator.
-================ ===============================================================================
+Default Keyboard Controls
+=========================
+
+.. contents:: :local:
+
+
+.. _default-keys-foreword:
+
+Controls Foreword
+-----------------
+
+MAME supports a vast array of different types of machines, with a
+significantly different array of inputs across them. This means that some
+keyboard keys, mouse buttons, and joystick buttons will be used for multiple
+functions. As a result, the control charts below are separated by machine-types
+to make it easier to find what you’re looking for.
+
+All of the controls below are fully configurable in the user interface. These
+charts show the default configuration.
+
+Note that the defaults shown here are arranged by US ANSI key positioning. If
+you are using a different layout, the keys will vary.
+
+MAME User Interface Controls
+----------------------------
+
+The controls here cover MAME functions such as MAME’s menus, machine pause,
+and saving/loading save states.
+
+
+**Tab**
+ Toggles the configuration menu.
+**`**/**~** (backtick/tilde key)
+ Toggles the On-Screen Display.
+
+ If you are running with -debug, this key sends a ‘break’ in emulation.
+
+ When a slider control is visible, you can use the following keys to control
+ it:
+
+ * **Up** - select previous parameter to modify.
+ * **Down** - select next parameter to modify.
+ * **Left** - decrease the value of the selected parameter.
+ * **Right** - increase the value of the selected parameter.
+ * **Enter** - reset parameter value to its default.
+ * **Control+Left** - decrease the value by 10x.
+ * **Shift+Left** - decrease the value by 0.1x.
+ * **Alt+Left** - decrease the value by the smallest amount.
+ * **Control+Right** - increase the value by 10x.
+ * **Shift+Right** - increase the value by 0.1x.
+ * **Alt+Right** - increase the value by the smallest amount.
+ * **End** - temporarily hide the On Screen Display.
+ * **Home** - bring the On Screen Display back after hiding it.
+**Up Arrow**
+ Highlight previous UI menu option.
+**Down Arrow**
+ Highlight next UI menu option.
+**Left Arrow**
+ Change current UI option setting when an arrow is present on it.
+**Right Arrow**
+ Change current UI option setting when an arrow is present on it.
+**Home**/**End**
+ Highlight first or last UI menu option.
+**[** **]**
+ Move to previous or next group in UI menus that support it (e.g. move to the
+ inputs for the previous or next device in the **Input Assignments (this
+ System)** menu).
+**Enter**/**Joystick 1 Button 1**
+ Select currently highlighted UI menu option.
+**Space**
+ Show comment on currently highlighted UI menu option.
+**Delete**
+ Clear/reset to default when highlighting an entry on the input
+ configuration, cheat options, and plugin options pages.
+**F1**
+ Power the machine on for machines that have specific power button behavior.
+**F2**
+ Power the machine off for machines that have specific power button behavior.
+**F3**
+ Soft resets the machine.
+**Left Shift+F3**
+ Performs a “hard reset”, which tears everything down and re-creates it from
+ scratch. This is a more thorough and complete reset than the reset you get
+ from hitting F3.
+**F4**
+ Shows the game palette, decoded graphics tiles/characters and any tilemaps.
+
+ Use the Enter key to switch between the three modes (palette, graphics, and
+ tilemaps).
+
+ Press F4 again to turn off the display.
+ The key controls in each mode vary slightly:
+
+ Palette/colortable mode:
+
+ * **[** **]** - switch between palette devices.
+ * **Up**/**Down** - scroll up/down one line at a time.
+ * **Page Up**/**Page Down** - scroll up/down one page at a time.
+ * **Home**/**End** - move to top/bottom of list.
+ * **-**/**+** - increase/decrease the number of colors per row.
+ * **0** - restore the default number of colors per row.
+ * **Enter** - switch to graphics viewer.
+
+ Graphics mode:
+
+ * **[** **]** - switch between different graphics sets.
+ * **Up**/**Down** - scroll up/down one line at a time.
+ * **Page Up**/**Page Down** - scroll up/down one page at a time.
+ * **Home**/**End** - move to top/bottom of list.
+ * **Left**/**Right** - change color displayed.
+ * **R** - rotate tiles 90 degrees clockwise.
+ * **-**/**+** - increase/decrease the number of tiles per row (hold Shift to
+ restrict to integer scale factors).
+ * **0** - restore the default number of tiles per row (hold Shift to
+ restrict to integer scale factors).
+ * **Enter** - switch to tilemap viewer.
+
+ Tilemap mode:
+
+ * **[** **]** - switch between different tilemaps.
+ * **Up**/**Down**/**Left**/**Right** - scroll 8 pixels at a time.
+ * **Shift+Up**/**Down**/**Left**/**Right** - scroll 1 pixel at a time.
+ * **Control+Up**/**Down**/**Left**/**Right** - scroll 64 pixels at a time.
+ * **R** - rotate tilemap view 90 degrees clockwise.
+ * **-**/**+** - decrease/increase the zoom factor.
+ * **0** - expand small tilemaps to fill the display.
+ * **Enter** - switch to palette/colortable mode.
+
+ Note: Not all systems have decoded graphics and/or tilemaps.
+**Left Shift+F4**
+ While paused, loads the most recent rewind save state.
+**F5**
+ Pauses the emulated machine.
+**Left Shift+F5**
+ While paused, advances to next frame. If rewind is enabled, a new rewind
+ save state is also captured.
+**F6**
+ Create a save state. Requires an additional keypress to identify the state,
+ similar to the load option above. If an existing save state is present, it
+ will also appear in the selection menu to allow overwriting of that save
+ state.
+**Left Shift+F6**
+ Create a quick save state.
+**F7**
+ Load a save state. You will be prompted to press a key or select from the
+ menu to determine which save state you wish to load.
+
+ *Note that the save state feature is not supported for a large number of
+ drivers. If a given driver is not known to work perfectly, you will
+ receive a warning that the save state may not be valid when attempting to
+ save or load.*
+**Left Shift+F7**
+ Load a quick save state.
+**F8**
+ Decrease frame skipping on the fly.
+**Left Shift+F8**
+ Toggle cheat mode. (if started with “-cheat”)
+**Left Alt+F8**
+ Decrease Prescaling.
+ (*SDL MAME only*)
+**F9**
+ Increase frame skipping on the fly.
+**Left Alt+F9**
+ Increase Prescaling.
+ (*SDL MAME only*)
+**F10**
+ Toggle speed throttling.
+**Left Alt+F10**
+ Toggle HLSL Post-Processing.
+ (*Windows non-SDL MAME only*)
+**Left Alt+F10**
+ Toggle Filter.
+ (*SDL MAME only*)
+**F11**
+ Toggles speed display.
+**Left Shift+F11**
+ Toggles internal profiler display (if compiled in).
+**Left Alt+F11**
+ Record HLSL Rendered Video.
+**F12**
+ Saves a screen snapshot.
+**Left Shift+F12**
+ Begin recording MNG video.
+**Left Control+Left Shift+F12**
+ Begin recording AVI video.
+**Left Alt+F12**
+ Take HLSL Rendered Snapshot.
+**Insert** (Windows non-SDL MAME)/**Page Down** (SDL MAME)
+ Fast forward. While held, runs game with throttling disabled and with the
+ maximum frameskip.
+**Left Alt+Enter**
+ Toggles between full-screen and windowed mode.
+**Scroll Lock**/**Forward Delete** (Mac Desktop)/**fn-Delete** (Mac Laptop)
+ Default mapping for the **uimodekey**.
+
+ This key toggles MAME’s response to user interface keys such as the
+ (by default) **Tab** key being used for menus. All emulated machines
+ which require emulated keyboards will start with UI controls disabled by
+ default and you can only access the internal UI by first hitting this
+ **uimodekey** key. You can change the initial status of the emulated
+ keyboard as presented upon start by using
+ :ref:`-uimodekey<mame-commandline-uimodekey>`
+**Escape**
+ Exit emulator, return to the previous menu, or cancel the current UI option.
+
+
+.. _default-selmenu-keys:
+
+System and software selection menus
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The system and software selection menus use additional controls
+
+**Tab**
+ Moves keyboard/controller focus to the next UI panel.
+**Shift+Tab**
+ Moves keyboard/controller focus to the previous UI panel.
+**Left Alt+F**
+ Adds or removes the selected system or software list item from the favorites
+ list.
+**Left Alt+E**
+ Exports the currently displayed list of systems.
+**Left Alt+D**
+ Shows the full-size info viewer if info is available for the selected system
+ or software list item. (Shows information loaded by the data plugin from
+ external files, including history.xml and mameinfo.dat.)
+**F1**
+ Audits system ROMs and disk images.
+
+
+.. _default-arcade-keys:
+
+Default Arcade Machine Controls
+-------------------------------
+
+This section covers controls that are applicable to most kinds of arcade
+machines. Note that not all machines will have all of these controls. All the
+controls below are fully configurable in the user interface. This list shows
+the standard keyboard configuration.
+
+**5** *(not numeric keypad)*
+ Coin slot 1
+**6** *(not numeric keypad)*
+ Coin slot 2
+**7** *(not numeric keypad)*
+ Coin slot 3
+**8** *(not numeric keypad)*
+ Coin slot 4
+**Backspace**
+ Bill 1 (For machines that have a bill receptor/note reader)
+**T**
+ Tilt
+
+ Usually a tilt switch or shock sensor that will end the current game, reset
+ credits and/or reset the machine if the machine is knocked excessively hard
+ or moved. Most commonly found on pinball machines.
+**-** *(not numeric keypad)*
+ Volume Down
+
+ For machines that have an electronic volume control.
+**=** *(not numeric keypad)*
+ Volume Up
+
+ For machines that have an electronic volume control.
+**F1**
+ Memory Reset
+
+ This resets high scores, credits/winnings, statistics, and/or operator
+ settings on machines that support it.
+**F2**
+ Service Mode
+
+ This is a momentary push-button on some machines, while it is a toggle
+ switch or DIP switch on others.
+**9** *(not numeric keypad)*
+ Service 1
+
+ Service buttons are typically used to give free credits or to navigate the
+ operator service menus.
+**0** *(not numeric keypad)*
+ Service 2
+**-** *(not numeric keypad)*
+ Service 3
+**=** *(not numeric keypad)*
+ Service 4
+
+
+.. _default-game-keys:
+
+Default Arcade Game Controls
+----------------------------
+
+This section covers controls for arcade games using common joystick/button
+control schemes. All the controls below are fully configurable in the user
+interface. This list shows the standard keyboard configuration.
+
+**5** *(not numeric keypad)*
+ Coin slot 1
+**6** *(not numeric keypad)*
+ Coin slot 2
+**7** *(not numeric keypad)*
+ Coin slot 3
+**8** *(not numeric keypad)*
+ Coin slot 4
+**1** *(not numeric keypad)*
+ Player 1 start or 1 player mode
+**2** *(not numeric keypad)*
+ Player 2 start or 2 players mode
+**3** *(not numeric keypad)*
+ Player 3 start or 3 players mode
+**4** *(not numeric keypad)*
+ Player 4 start or 4 players mode
+
+
+.. _default-player1-keys:
+
+Player 1 Controls
+~~~~~~~~~~~~~~~~~
+
+**Up Arrow**
+ Player 1 Up
+**Down Arrow**
+ Player 1 Down
+**Left Arrow**
+ Player 1 Left
+**Right Arrow**
+ Player 1 Right
+**E**
+ Player 1 Up on Left Stick for dual-stick machines (e.g. Robotron)
+**D**
+ Player 1 Down on Left Stick for dual-stick machines (e.g. Robotron)
+**S**
+ Player 1 Left on Left Stick for dual-stick machines (e.g. Robotron)
+**F**
+ Player 1 Right on Left Stick for dual-stick machines (e.g. Robotron)
+**I**
+ Player 1 Up on Right Stick for dual-stick machines (e.g. Robotron)
+**K**
+ Player 1 Down on Right Stick for dual-stick machines (e.g. Robotron)
+**J**
+ Player 1 Left on Right Stick for dual-stick machines (e.g. Robotron)
+**L**
+ Player 1 Right on Right Stick for dual-stick machines (e.g. Robotron)
+**Left Ctrl**/**Mouse B0**/**Gun 1 Button 0**
+ Player 1 Button 1
+**Left Alt**/**Mouse B2**/**Gun 1 Button 1**
+ Player 1 Button 2
+**Spacebar**/**Mouse B1**/**Joystick 1 Button 1 or B**
+ Player 1 Button 3
+**Left Shift**
+ Player 1 Button 4
+**Z**
+ Player 1 Button 5
+**X**
+ Player 1 Button 6
+**C**
+ Player 1 Button 7
+**V**
+ Player 1 Button 8
+**B**
+ Player 1 Button 9
+**N**
+ Player 1 Button 10
+**M**
+ Player 1 Button 11
+**,**
+ Player 1 Button 12
+**.**
+ Player 1 Button 13
+**/**
+ Player 1 Button 14
+**Right Shift**
+ Player 1 Button 15
+
+
+.. _default-player2-keys:
+
+Player 2 Controls
+~~~~~~~~~~~~~~~~~
+
+**R**
+ Player 2 Up
+**F**
+ Player 2 Down
+**D**
+ Player 2 Left
+**G**
+ Player 2 Right
+**A**
+ Player 2 Button 1
+**S**
+ Player 2 Button 2
+**Q**
+ Player 2 Button 3
+**W**
+ Player 2 Button 4
+**E**
+ Player 2 Button 5
+
+
+.. _default-player3-keys:
+
+Player 3 Controls
+~~~~~~~~~~~~~~~~~
+
+**I**
+ Player 3 Up
+**K**
+ Player 3 Down
+**J**
+ Player 3 Left
+**L**
+ Player 3 Right
+**Right Control**
+ Player 3 Button 1
+**Right Shift**
+ Player 3 Button 2
+**Enter** *(not numeric keypad)*
+ Player 3 Button 3
+
+
+.. _default-player4-keys:
+
+Player 4 Controls
+~~~~~~~~~~~~~~~~~
+
+**8** *(on numeric keypad)*
+ Player 4 Up
+**2** *(on numeric keypad)*
+ Player 4 Down
+**4** *(on numeric keypad)*
+ Player 4 Left
+**6** *(on numeric keypad)*
+ Player 4 Right
+**0** *(on numeric keypad)*
+ Player 4 Button 1
+**.** *(on numeric keypad)*
+ Player 4 Button 2
+**Enter** *(on numeric keypad)*
+ Player 4 Button 3
+
+
+.. _default-mahjong-hanafuda-keys:
+
+Default Mahjong and Hanafuda Keys
+---------------------------------
+
+Most mahjong and hanafuda games use a standard control panel layout. Some keys
+may not be present, depending on the kind of game. For example games without a
+bonus game feature may lack the Take Score, Double Up, Big and Small keys, and
+games without gambling features may also lack the Bet key. Some games may not
+use all keys that are present. For example many games do not use the Flip Flop
+and Last Chance keys.
+
+.. image:: images/mahjongpanel.svg
+ :width: 100%
+ :align: center
+ :alt: Standard mahjong control panel layout
+
+Due to the large number of keys, MAME only provides default input configuration
+for a single set of player controls. For multi-player mahjong/hanafuda games,
+or mahjong/hanafuda games with multiple player positions, manual configuration
+is required. All the keys below are fully configurable in the user interface.
+This list shows the standard keyboard configuration.
+
+
+**5** *(not numeric keypad)*
+ Coin slot 1
+**6** *(not numeric keypad)*
+ Coin slot 2
+**7** *(not numeric keypad)*
+ Coin slot 3
+**8** *(not numeric keypad)*
+ Coin slot 4
+**Y**
+ Player 1 Mahjong/Hanafuda Flip Flop
+**1** *(not numeric keypad)*
+ Player 1 start or 1 player mode
+**2** *(not numeric keypad)*
+ Player 2 start or 2 players mode
+**3** *(not numeric keypad)*
+ Player 3 start or 3 players mode
+
+ Mahjong Bet
+**4** *(not numeric keypad)*
+ Player 4 start or 4 players mode
+**Right Ctrl**
+ Player 1 Mahjong/Hanafuda Take Score
+**Right Shift**
+ Player 1 Mahjong/Hanafuda Double Up
+**Enter**
+ Player 1 Mahjong/Hanafuda Big
+**Backspace**
+ Player 1 Mahjong/Hanafuda Small
+**Right Alt**
+ Player 1 Mahjong/Hanafuda Last Chance
+**Ctrl**
+ Mahjong Kan
+**Alt**
+ Mahjong Pon
+**Spacebar**
+ Mahjong Chi
+**Shift**
+ Mahjong Reach
+**Z**
+ Mahjong Ron
+**A**
+ Player 1 Mahjong/Hanafuda A
+**B**
+ Player 1 Mahjong/Hanafuda B
+**C**
+ Player 1 Mahjong/Hanafuda C
+**D**
+ Player 1 Mahjong/Hanafuda D
+**E**
+ Player 1 Mahjong/Hanafuda E
+**F**
+ Player 1 Mahjong/Hanafuda F
+**G**
+ Player 1 Mahjong/Hanafuda G
+**H**
+ Player 1 Mahjong/Hanafuda H
+**I**
+ Player 1 Mahjong I
+**J**
+ Player 1 Mahjong J
+**K**
+ Player 1 Mahjong K
+**L**
+ Player 1 Mahjong L
+**M**
+ Player 1 Mahjong M
+
+ Player 1 Hanafuda Yes
+**N**
+ Player 1 Mahjong N
+
+ Player 1 Hanafuda No
+**O**
+ Player 1 Taiwanese Mahjong O
+**Semicolon**
+ Player 1 Taiwanese Mahjong P
+**Q**
+ Player 1 Taiwanese Mahjong Q
+
+
+.. _default-gambling-keys:
+
+Default Gambling Keys
+---------------------
+
+All the keys below are fully configurable in the user interface. This list shows
+the standard keyboard configuration.
+
+Note that many gambling games use buttons for multiple functions. For example a
+slots game may use the Start button to stop all reels, lacking a dedicated Stop
+All Reels button, or a poker game may use the hold buttons to control the
+double-up bonus game, lacking dedicated Take Score, Double Up, High and Low
+buttons.
+
+
+**5**
+ Coin slot 1
+**6**
+ Coin slot 2
+**7**
+ Coin slot 3
+**8**
+ Coin slot 4
+**Backspace**
+ Bill 1 (For machines that have a bill receptor/note reader)
+**I**
+ Payout
+**Q**
+ Key In
+**W**
+ Key Out
+**F1**
+ Memory Reset
+**9** *(not numeric keypad)*
+ Service 1 (Service buttons are typically used to give free credits or to
+ navigate the internal operator service menus)
+**0** *(not numeric keypad)*
+ Service 2
+ Book-Keeping (for machines that have this functionality)
+**-** *(not numeric keypad)*
+ Service 3
+**=** *(not numeric keypad)*
+ Service 4
+**M**
+ Bet
+**1** *(not numeric keypad)*
+ Player 1 start or 1 player mode
+**2** *(not numeric keypad)*
+ Deal
+**L**
+ Stand
+**4** *(not numeric keypad)*
+ Take Score
+
+ For games that allow gambling winnings in a double-or-nothing bonus game,
+ this takes the winnings from the main game.
+**3** *(not numeric keypad)*
+ Double Up
+
+ For games that allow gambling winnings in a double-or-nothing bonus game,
+ this gambles the winnings from the main game in the bonus game.
+**D**
+ Half Gamble
+
+ Used by games that allow gambling half or all of the winnings from the main
+ game in the bonus game.
+**A**
+ High
+**S**
+ Low
+**O**
+ Door
+
+
+.. _default-blackjack-keys:
+
+Default Blackjack Keys
+~~~~~~~~~~~~~~~~~~~~~~
+
+All the keys below are fully configurable in the user interface. This list shows
+the standard keyboard configuration.
+
+
+**1**
+ Player 1 start or 1 player mode
+
+ Used to deal a new hand for games that have separate buttons to deal a new
+ hand and draw an additional card.
+**2**
+ Deal (hit)
+
+ Used to draw an additional card, and to deal a new hand in games that don’t
+ use separate buttons to deal a new hand and draw an additional card.
+**L**
+ Stand
+
+
+.. _default-poker-keys:
+
+Default Poker Keys
+~~~~~~~~~~~~~~~~~~
+
+All the keys below are fully configurable in the user interface. This list shows
+the standard keyboard configuration.
+
+
+**1**
+ Player 1 start or 1 player mode
+
+ Used to deal a new hand for games that have separate buttons to deal a new
+ hand and draw replacement cards.
+**2**
+ Deal
+
+ Used to draw replacement cards, and to deal a new hand in games that don’t
+ use separate buttons to deal a new hand and draw replacement cards.
+**Z**
+ Hold 1/discard 1
+**X**
+ Hold 2/discard 2
+**C**
+ Hold 3/discard 3
+**V**
+ Hold 4/discard 4
+**B**
+ Hold 5/discard 5
+**N**
+ Cancel
+
+ Used by some games to cancel current selection for cards to hold/discard.
+
+
+.. _default-slots-keys:
+
+Default Slots Keys
+~~~~~~~~~~~~~~~~~~
+
+All the keys below are fully configurable in the user interface. This list shows
+the standard keyboard configuration.
+
+
+**1**
+ Player 1 start or 1 player mode
+**X**
+ Stop Reel 1
+**C**
+ Stop Reel 2
+**V**
+ Stop Reel 3
+**B**
+ Stop Reel 4
+**Z**
+ Stop All Reels
+
+
+.. _default-computer-keys:
+
+Default Computer Keys
+---------------------
+
+All the keys below are fully configurable in the user interface. This list shows
+the standard keyboard configuration.
+
+Note that controls can vary widely by computer type, so not all keys are shown
+here. See the **Input Assignments (this system)** section of MAME’s Input
+Settings menu for details for the machine you are currently using.
+
+
+**Tab**
+ Toggles the configuration menu.
+**Scroll Lock**/**Forward Delete** (Mac Desktop)/**fn-Delete** (Mac Laptop)
+ Default mapping for the **uimodekey**.
+
+ This key toggles MAME’s response to user interface keys such as the
+ (by default) **Tab** key being used for menus. All emulated machines
+ which require emulated keyboards will start with UI controls disabled by
+ default and you can only access the internal UI by first hitting this
+ **uimodekey** key. You can change the initial status of the emulated
+ keyboard as presented upon start by using
+ :ref:`-uimodekey<mame-commandline-uimodekey>`
+**F2**
+ Start tape for machines that have cassette tape drives.
+**Shift+F2**
+ Stop tape for machines that have cassette tape drives.
+**Left Shift+Scroll Lock**
+ Pastes from system clipboard into the emulated machine.
+**Alphanumeric Keys**
+ These keys are mapped to their equivalents in the emulated machine by
+ default.
+
+
+.. _default-othermachine-keys:
+
+Other Machines
+--------------
+
+All the keys are fully configurable in the user interface.
+
+Note that controls can vary widely by machine type, so default keys are not
+shown here and defaults will vary considerably based on the manufacturer and
+style. See the **Input Assignments (this system)** section of MAME’s Input
+Settings menu for details for the machine you are currently using.
diff --git a/docs/source/usingmame/frontends.rst b/docs/source/usingmame/frontends.rst
index 88ef7052a65..730b84cef6a 100644
--- a/docs/source/usingmame/frontends.rst
+++ b/docs/source/usingmame/frontends.rst
@@ -1,20 +1,45 @@
.. _frontends:
-Frontends
-=========
+Front-ends
+==========
-There are a number of third party tools for MAME to make system and software selection simpler. These tools are called "Frontends", and there are far too many to list conclusively here. Some are free, some are commercial-- caveat emptor. Some older frontends predate the merging of MAME and MESS and do not support the additional console, handheld, etc functionality that MAME inherited from MESS.
+A number of third party tools for MAME to make system and software selection
+simpler are available. These tools are called “front-ends”, and there are far
+too many to list exhaustively here. Some are free, some are commercial –
+caveat emptor. Some older front-ends predate the merging of MAME and MESS and
+do not support the additional console, hand-held, and computer functionality
+inherited from MESS.
-This following list is not an endorsement of any of these frontends by the MAME team, but simply showing a number of commonly used free frontends as a good starting point to begin from.
+This following list is not an endorsement of any of these front-ends by the MAME
+team. It simply shows a number of commonly used free front-ends to provide a
+starting point.
-| QMC2 (multiple platforms)
-| Download: http://qmc2.batcom-it.net/
-|
-| IV/Play (Microsoft Windows)
-| Download: http://www.mameui.info/
-|
-| EmuLoader (Microsoft Windows)
-| Download: http://emuloader.mameworld.info/
-|
+`QMC2 <http://qmc2.batcom-it.net/>`__ (multiple platforms)
+ Provides a graphical interface for configuring many of MAME’s settings and
+ features. Also includes ROM management and media auditing features.
+ Written in C++ using the Qt toolkit, the
+ `source code is on SourceForge <https://sourceforge.net/projects/qmc2/>`__.
+`Negatron <http://negatron.net/>`__ (multiple platforms)
+ Negatron emphasises features for configuring emulated computers and
+ consoles. Written in Java, the
+ `source code is on GitHub <https://github.com/xinyingho/Negatron>`__.
+`BletchMAME <https://www.bletchmame.org/>`__ (multiple platforms)
+ BletchMAME takes advantage of MAME’s Lua scripting interface to integrate
+ tightly and effectively replace MAME’s internal user interface. It has
+ many useful features for home computer emulation. Written in C++, the
+ `source code is on GitHub <https://github.com/npwoods/bletchmame>`__.
+`IV/Play <http://www.mameui.info/>`__ (Microsoft Windows)
+ A simple Windows program for launching systems in MAME. Written in C#, the
+ `source code is on GitHub <https://github.com/Mataniko/IV-Play>`__.
+`Emu Loader <http://emuloader.mameworld.info/>`__ (Microsoft Windows)
+ Emu Loader provides a Windows interface for launching systems in multiple
+ emulators, including MAME, Supermodel and DEMUL. Written in Delphi Pascal,
+ the source code is available
+ `on the download page <https://emuloader.mameworld.info/downloads.htm>`__.
+`Retrofire <https://e2j.net/downloads/>`__ (Japanese, Microsoft Windows)
+ Provides a Japanese-language graphical interface for launching systems or
+ software in MAME.
-The MAME team will not provide support for issues with frontends. For support, we suggest contacting the frontend author or trying any of the popular MAME-friendly forums on the internet.
+The MAME team will not provide support for issues with front-ends. For support,
+we suggest contacting the front-end author or asking on one of the popular
+MAME-friendly forums on the Internet.
diff --git a/docs/source/usingmame/images/mahjongpanel.svg b/docs/source/usingmame/images/mahjongpanel.svg
new file mode 100644
index 00000000000..963ca2e0be0
--- /dev/null
+++ b/docs/source/usingmame/images/mahjongpanel.svg
@@ -0,0 +1,215 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<svg
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ id="svg-mahjong"
+ version="1.1"
+ viewBox="0 0 1136 176"
+ height="176"
+ width="1136">
+ <g id="buttons" stroke="none">
+ <rect y="0" x="0" height="64" width="64" id="button-a" fill="#cccccc" />
+ <rect y="0" x="80" height="64" width="64" id="button-b" fill="#cccccc" />
+ <rect y="0" x="160" height="64" width="64" id="button-c" fill="#cccccc" />
+ <rect y="0" x="240" height="64" width="64" id="button-d" fill="#cccccc" />
+ <rect y="0" x="320" height="64" width="64" id="button-e" fill="#cccccc" />
+ <rect y="0" x="400" height="64" width="64" id="button-f" fill="#cccccc" />
+ <rect y="0" x="480" height="64" width="64" id="button-g" fill="#cccccc" />
+ <rect y="0" x="560" height="64" width="64" id="button-h" fill="#cccccc" />
+ <rect y="0" x="640" height="64" width="64" id="button-i" fill="#cccccc" />
+ <rect y="0" x="720" height="64" width="64" id="button-j" fill="#cccccc" />
+ <rect y="0" x="800" height="64" width="64" id="button-k" fill="#cccccc" />
+ <rect y="0" x="880" height="64" width="64" id="button-l" fill="#cccccc" />
+ <rect y="0" x="960" height="64" width="64" id="button-m" fill="#cccccc" />
+ <rect y="0" x="1072" height="64" width="64" id="button-n" fill="#ff3333" />
+ <rect y="112" x="0" height="64" width="64" id="button-flipflop" fill="#ffff33" />
+ <rect y="112" x="80" height="64" width="64" id="button-start" fill="#ffff33" />
+ <rect y="112" x="160" height="64" width="64" id="button-bet" fill="#ffff33" />
+ <rect y="112" x="280" height="64" width="64" id="button-take" fill="#ff66cc" />
+ <rect y="112" x="360" height="64" width="64" id="button-dup" fill="#ff66cc" />
+ <rect y="112" x="440" height="64" width="64" id="button-big" fill="#ff66cc" />
+ <rect y="112" x="520" height="64" width="64" id="button-small" fill="#ff66cc" />
+ <rect y="112" x="640" height="64" width="64" id="button-last" fill="#33ff99" />
+ <rect y="112" x="720" height="64" width="64" id="button-kan" fill="#33ff99" />
+ <rect y="112" x="800" height="64" width="64" id="button-pon" fill="#33ff99" />
+ <rect y="112" x="880" height="64" width="64" id="button-chi" fill="#33ff99" />
+ <rect y="112" x="960" height="64" width="64" id="button-reach" fill="#33ff99" />
+ <rect y="112" x="1072" height="64" width="64" id="button-ron" fill="#ff9933" />
+ </g>
+ <g id="labels"
+ font-family="sans-serif" font-style="normal" font-variant="normal" font-weight="bold" font-stretch="normal"
+ text-anchor="middle"
+ fill="#000000" stroke="none"
+ style="text-align:center;line-height:1.25;letter-spacing:0px;word-spacing:0px">
+ <text id="label-a"
+ y="47.5104" x="32"
+ style="font-size:42.66666794px"
+ xml:space="preserve"><tspan
+ y="47.5104" x="32"
+ id="tspan-a0">A</tspan></text>
+ <text id="label-b"
+ y="47.5104" x="112"
+ style="font-size:42.66666794px"
+ xml:space="preserve"><tspan
+ y="47.5104" x="112"
+ id="tspan-b0">B</tspan></text>
+ <text id="label-c"
+ y="47.5104" x="192"
+ style="font-size:42.66666794px"
+ xml:space="preserve"><tspan
+ y="47.5104" x="192"
+ id="tspan-c0">C</tspan></text>
+ <text id="label-d"
+ y="47.5104" x="272"
+ style="font-size:42.66666794px"
+ xml:space="preserve"><tspan
+ y="47.5104" x="272"
+ id="tspan-d0">D</tspan></text>
+ <text id="label-e"
+ y="47.5104" x="352"
+ style="font-size:42.66666794px"
+ xml:space="preserve"><tspan
+ y="47.5104" x="352"
+ id="tspan-e0">E</tspan></text>
+ <text id="label-f"
+ y="47.5104" x="432"
+ style="font-size:42.66666794px"
+ xml:space="preserve"><tspan
+ y="47.5104" x="432"
+ id="tspan-f0">F</tspan></text>
+ <text id="label-g"
+ y="47.5104" x="512"
+ style="font-size:42.66666794px"
+ xml:space="preserve"><tspan
+ y="47.5104" x="512"
+ id="tspan-g0">G</tspan></text>
+ <text id="label-h"
+ y="47.5104" x="592"
+ style="font-size:42.66666794px"
+ xml:space="preserve"><tspan
+ y="47.5104" x="592"
+ id="tspan-h0">H</tspan></text>
+ <text id="label-i"
+ y="47.5104" x="672"
+ style="font-size:42.66666794px"
+ xml:space="preserve"><tspan
+ y="47.5104" x="672"
+ id="tspan-i0">I</tspan></text>
+ <text id="label-j"
+ y="47.5104" x="752"
+ style="font-size:42.66666794px"
+ xml:space="preserve"><tspan
+ y="47.5104" x="752"
+ id="tspan-j0">J</tspan></text>
+ <text id="label-k"
+ y="47.5104" x="832"
+ style="font-size:42.66666794px"
+ xml:space="preserve"><tspan
+ y="47.5104" x="832"
+ id="tspan-k0">K</tspan></text>
+ <text id="label-l"
+ y="47.5104" x="912"
+ style="font-size:42.66666794px"
+ xml:space="preserve"><tspan
+ y="47.5104" x="912"
+ id="tspan-l0">L</tspan></text>
+ <text id="label-m"
+ y="47.5104" x="992"
+ style="font-size:42.66666794px"
+ xml:space="preserve"><tspan
+ y="47.5104" x="992"
+ id="tspan-m0">M</tspan></text>
+ <text id="label-n"
+ y="47.5104" x="1104"
+ style="font-size:42.66666794px"
+ xml:space="preserve"><tspan
+ y="47.5104" x="1104"
+ id="tspan-n0">N</tspan></text>
+ <text id="label-flipflop"
+ y="140.4128" x="32"
+ style="font-size:13.33333302px"
+ xml:space="preserve"><tspan
+ y="140.4128" x="32"
+ id="tspan-flipflop0">FLIP</tspan><tspan
+ y="157.17379" x="32"
+ id="tspan-flipflop1">FLOP</tspan></text>
+ <text id="label-start"
+ y="148.84703" x="112"
+ style="font-size:13.33333302px"
+ xml:space="preserve"><tspan
+ y="148.84703" x="112"
+ id="tspan-start0">START</tspan></text>
+ <text id="label-bet"
+ y="148.84703" x="192"
+ style="font-size:13.33333302px"
+ xml:space="preserve"><tspan
+ y="148.84703" x="192"
+ id="tspan-bet0">BET</tspan></text>
+ <text id="label-take"
+ y="140.4128" x="312"
+ style="font-size:13.33333302px"
+ xml:space="preserve"><tspan
+ y="140.4128" x="312"
+ id="tspan-take0">TAKE</tspan><tspan
+ y="157.17379" x="312"
+ id="tspan-take1">SCORE</tspan></text>
+ <text id="label-dup"
+ y="140.4128" x="392"
+ style="font-size:13.33333302px"
+ xml:space="preserve"><tspan
+ y="140.4128" x="392"
+ id="tspan-dup0">DOUBLE</tspan><tspan
+ y="157.17379" x="392"
+ id="tspan-dup1">UP</tspan></text>
+ <text id="label-big"
+ y="148.84703" x="472"
+ style="font-size:13.33333302px"
+ xml:space="preserve"><tspan
+ y="148.84703" x="472"
+ id="tspan-big0">BIG</tspan></text>
+ <text id="label-small"
+ y="148.84703" x="552"
+ style="font-size:13.33333302px"
+ xml:space="preserve"><tspan
+ y="148.84703" x="552"
+ id="tspan-small0">SMALL</tspan></text>
+ <text id="label-last"
+ y="140.4128" x="672"
+ style="font-size:13.33333302px"
+ xml:space="preserve"><tspan
+ y="140.4128" x="672"
+ id="tspan-last0">LAST</tspan><tspan
+ y="157.17379" x="672"
+ id="tspan-last1">CHANCE</tspan></text>
+ <text id="label-kan"
+ y="148.84703" x="752"
+ style="font-size:13.33333302px"
+ xml:space="preserve"><tspan
+ y="148.84703" x="752"
+ id="tspan-kan0">KAN</tspan></text>
+ <text id="label-pon"
+ y="148.84703" x="832"
+ style="font-size:13.33333302px"
+ xml:space="preserve"><tspan
+ y="148.84703" x="832"
+ id="tspan-pon0">PON</tspan></text>
+ <text id="label-chi"
+ y="148.84703" x="912"
+ style="font-size:13.33333302px"
+ xml:space="preserve"><tspan
+ y="148.84703" x="912"
+ id="tspan-chi0">CHI</tspan></text>
+ <text id="label-reach"
+ y="148.84703" x="992"
+ style="font-size:13.33333302px"
+ xml:space="preserve"><tspan
+ y="148.84703" x="992"
+ id="tspan-reach0">REACH</tspan></text>
+ <text id="label-ron"
+ y="148.84703" x="1104"
+ style="font-size:13.33333302px"
+ xml:space="preserve"><tspan
+ y="148.84703" x="1104"
+ id="tspan-ron0">RON</tspan></text>
+ </g>
+</svg>
diff --git a/docs/source/usingmame/index.rst b/docs/source/usingmame/index.rst
index 7e85a5bd871..615d3f34c4b 100644
--- a/docs/source/usingmame/index.rst
+++ b/docs/source/usingmame/index.rst
@@ -1,16 +1,19 @@
Basic MAME Usage and Configuration
----------------------------------
-This section describes general usage information about MAME. It is intended to cover aspects of using and configuring MAME that are common across all operating systems. For additional OS-specific options, please see the separate documentation for your platform of choice.
+This section describes general usage information about MAME. It is intended to
+cover aspects of using and configuring MAME that are common across all operating
+systems. For additional OS-specific options, please see the separate
+documentation for your platform of choice.
.. toctree::
- :titlesonly:
-
- usingmame
- defaultkeys
- mamemenus
- frontends
- aboutromsets
- commonissues
-
+ :titlesonly:
+ usingmame
+ ui
+ defaultkeys
+ mamemenus
+ assetsearch
+ frontends
+ aboutromsets
+ commonissues
diff --git a/docs/source/usingmame/mamemenus.rst b/docs/source/usingmame/mamemenus.rst
index 38e66c81a35..963bb42ecae 100644
--- a/docs/source/usingmame/mamemenus.rst
+++ b/docs/source/usingmame/mamemenus.rst
@@ -1,7 +1,405 @@
+.. _menus:
+
MAME Menus
==========
-If you started MAME without any command line parameters, you'll be shown the game selection menu immediately. While the keys listed above will let you navigate the menus, you can also use a mouse.
+.. contents:: :local:
+
+
+.. _menus-intro:
+
+Introduction
+------------
+
+To show the :ref:`main menu <menus-main>` while running an emulated system in
+MAME, press the **Show/Hide Menu** key or button (**Tab** by default). If the
+emulated system has keyboard inputs, you may need to press the
+**Toggle UI Controls** key or button (**Scroll Lock**, or **Forward Delete** on
+macOS, by default) to enable user interface controls first. You can dismiss a
+menu by pressing the **UI Back** key or button (**Escape** by default).
+Dismissing a menu will return to its parent menu, or to the running system in
+the case of the main menu.
+
+You can hide a menu and return to the running system by pressing the
+**Show/Hide Menu** key or button. Pressing the **Show/Hide Menu** key or button
+again will jump back to the same menu. This is useful when testing changes to
+settings.
+
+Emulated system inputs are ignored while menus are displayed. You can still
+pause or resume the running system while most menus are displayed by pressing
+the **Pause** key or button (**F5** on the keyboard by default).
+
+If you start MAME without specifying a system on the command line, the system
+selection menu will be shown (assuming the
+:ref:`ui option <mame-commandline-ui>` is set to **cabinet**). The system
+selection menu is also shown if you select **Select New System** from the main
+menu during emulation.
+
+For more information on navigating menus, :ref:`see the relevant section
+<ui-menus>`.
+
+
+.. _menus-main:
+
+Main menu
+---------
+
+The main menu is shown when you press the **Show/Hide Menu** key or button while
+running an emulated system or while the system information screen is displayed.
+It provides access to menus used to change settings, control various features,
+and show information about the running system and MAME itself.
+
+If you press the **Show/Hide Menu** key or button to show the main menu while
+the system information screen is displayed, the emulated system will not start
+until the main menu is dismissed (either by selecting **Start System**, pressing
+the **UI Back** key or button, or pressing the **Show/Hide Menu** key or
+button). This can be useful for mounting media images or changing DIP switches
+and machine configuration settings before the emulated system starts.
+
+Input Settings
+ Shows the :ref:`Input Settings <menus-inputopts>` menu, where you can assign
+ controls to emulated inputs, adjust analog control settings, control toggle
+ inputs, and test input devices.
+DIP Switches
+ Shows the DIP Switches menu, where configuration switches for the running
+ system can be changed. This item is not shown if the running system has no
+ DIP switches.
+Machine Configuration
+ Shows the Machine Configuration menu, where various settings specific to the
+ emulated system can be changed. This item is not shown if the running
+ system has no configuration settings.
+Bookkeeping
+ Shows uptime, coin counter and ticket dispenser statistics (if relevant) for
+ the running system.
+System Information
+ Shows information about the running system as emulated in MAME, including
+ CPU, sound and video devices.
+Warning Information
+ Shows information about imperfectly emulated features of the running system.
+ This item is not shown if there are no relevant warnings.
+Media Image Information
+ Shows information about mounted media images (if any). This item is only
+ shown if the running system has one or more media devices (e.g. floppy disk
+ drives or memory card slots).
+File Manager
+ Shows the File Manager menu, where you can mount new or existing media image
+ files, or unmount currently mounted media images. This item is only shown
+ if the running system has one or more media devices (e.g. floppy disk
+ drives or memory card slots).
+Tape Control
+ Shows the Tape Control menu, where you can control emulated cassette tape
+ mechanisms. This item is only shown for systems that use cassette tape
+ media.
+Pseudo Terminals
+ Shows the status of any pseudo terminal devices in the running system (used
+ to connect the emulated system to host pseudo terminals, for example via
+ emulated serial ports). This item is not shown if there are no pseudo
+ terminal devices in the running system.
+BIOS Selection
+ Shows the BIOS Selection menu, where you can select the BIOS/boot
+ ROM/firmware for the system and slot cards it contains. This item is not
+ shown if no BIOS options are available.
+Slot Devices
+ Shows the Slot Devices menu, where you can choose between emulated
+ peripherals. This item is not shown for systems that have no slot devices.
+Barcode Reader
+ Shows the Barcode Reader menu, where you can simulate scanning barcodes with
+ emulated barcode readers. This item is not shown if there are no barcode
+ readers in the running system.
+Network Devices
+ Shows the Network Devices menu, where you can set up emulated network
+ adapters that support bridging to a host network. This item is not shown if
+ there are no network adaptors that support bridging in the running system.
+Audio Mixer
+ Shows the :ref:`Audio Mixer <menus-audiomixer>` menu, where you
+ decide how to connect your system audio inputs and outputs to the
+ emulated system's microphones and speakers.
+Audio Effects
+ Shows the :ref:`Audio Effects <menus-audioeffects>` menu, which
+ allows to configure the audio effects applied between the emulated
+ system's speakers and the actual system audio outputs.
+Slider Controls
+ Shows the Slider Controls menu, where you can adjust various settings,
+ including video adjustments and individual sound channel levels.
+Video Options
+ Shows the Video Options menu, where you can change the view for each
+ screen/window, as well as for screenshots.
+Crosshair Options
+ Shows the Crosshair Options menu, where you can adjust the appearance of
+ crosshairs used to show the location of emulated light guns and other
+ absolute pointer inputs. This item is not shown if the emulated system has
+ no absolute pointer inputs.
+Cheat
+ Shows the Cheat menu, for controlling the built-in cheat engine. This item
+ is only shown if the built-in chat engine is enabled. Note that the cheat
+ plugin’s menu is accessed via the Plugin Options menu.
+Plugin Options
+ Shows the Plugin Options menu, where you can access settings for enabled
+ plugins. This item is not shown if no plugins are enabled, or if the main
+ menu is shown before the emulated system starts (by pressing the Show/Hide
+ Menu key/button while the system information screen is displayed).
+External DAT View
+ Shows the info viewer, which displays information loaded from various
+ external support files. This item is not shown if the :ref:`data plugin
+ <plugins-data>` is not enabled, or if the main menu is shown before the
+ emulated system starts (by pressing the Show/Hide Menu key/button while the
+ system information screen is displayed).
+Add To Favorites/Remove From Favorites
+ Adds the running system to the favourites list, or removes it if it’s
+ already in the favourites list. The favourites list can be used as a
+ filter for the system selection menu.
+About MAME
+ Shows the emulator version, data model, and copyright license information.
+Select New System
+ Shows the system selection menu, where you can select a system to start a
+ new emulation session. This item is not shown if the main menu is shown
+ before the emulated system starts (by pressing the Show/Hide Menu key/button
+ while the system information screen is displayed).
+Close Menu/Start System
+ Closes the main menu, returning control of the running system. Shows
+ **Start System** if the main menu is shown before the emulated system
+ starts (by pressing the Show/Hide Menu key/button while the system
+ information screen is displayed).
+
+
+.. _menus-inputopts:
+
+Input Settings menu
+-------------------
+
+The Input Settings provides options for assigning controls to emulated inputs,
+adjusting analog control settings, controlling toggle inputs, and testing input
+devices. You can reach the Input Settings menu by selecting **Input Settings**
+from the :ref:`main menu <menus-main>`. The items shown on this menu depend on
+available emulated inputs for the running system. Available emulated inputs may
+depend on slot options, machine configuration settings and DIP switch settings.
+
+Input Assignments (this system)
+ Lets you select assign controls to emulated inputs for the running system.
+ See the section on :ref:`configuring inputs <ui-inptcfg>` for more details.
+ This item is not shown if the running system has no enabled inputs that can
+ be assigned controls.
+Analog Input Adjustments
+ Shows the Analog Input Adjustments menu, where you can adjust sensitivity,
+ auto-centring speed and inversion settings for emulated analog inputs, and
+ see how the emulated analog inputs respond to controls with your settings.
+ For more details, see the :ref:`analog input settings <ui-inptcfg-analog>`
+ section for more details. This item is not shown if the running system has
+ no enabled analog inputs.
+Keyboard Selection
+ Shows the :ref:`Keyboard Selection menu <menus-keyboard>`, where you can
+ select between emulated and natural keyboard modes, and enable and disable
+ keyboard and keypad inputs for individual emulated devices. This item is
+ not shown if the running system has no keyboard or keypad inputs.
+Toggle Inputs
+ Shows the :ref:`Toggle Inputs menu <menus-inputtoggle>`, where you can view
+ and adjust the state of multi-position or toggle inputs. This item is not
+ shown if the running system has no enabled toggle inputs.
+Input Assignments (general)
+ Lets you select assign user interface controls, or assign default controls
+ for all emulated systems. See the section on :ref:`configuring inputs
+ <ui-inptcfg>` for more details.
+Input Devices
+ Shows the :ref:`Input Devices menu <menus-inputdevices>`, which lists the
+ input devices recognised by MAME.
+
+
+.. _menus-inputtoggle:
+
+Toggle Inputs menu
+------------------
+
+The Toggle Inputs menu shows the current state of multi-position or toggle
+inputs. Common examples include mechanically locking Caps Lock keys on
+computers, and two-position gear shit levers on driving games. You can reach
+the Toggle Inputs menu by selecting **Toggle Inputs** from the :ref:`Input
+Settings menu <menus-inputopts>`. Note that available emulated inputs may
+depend on slot options, machine configuration settings and DIP switch settings.
+
+Inputs are grouped by the emulated device they belong to. You can move between
+devices using the **Next Group** and **Previous Group** keys or buttons. Names
+of inputs are shown on the left, and the current settings are shown on the
+right.
+
+To change the state of an input, highlight it and use the **UI Left** and **UI
+Right** keys or buttons, or click the arrows beside the current setting.
+
+
+.. _menus-keyboard:
+
+Keyboard Selection menu
+-----------------------
+
+The Keyboard Selection menu lets your switch between emulated and natural
+keyboard modes, and enable or disable keyboard inputs for individual emulated
+devices. You can reach the Keyboard Selection menu by selecting **Keyboard
+Selection** from the :ref:`Input Settings menu <menus-inputopts>`.
+
+In emulated keyboard mode, keyboard and keypad inputs behave like any other
+digital inputs, responding to their assigned controls. In natural keyboard
+mode, MAME attempts to translate typed characters to emulated keystrokes. The
+initial keyboard mode is set using the :ref:`natural option
+<mame-commandline-natural>`.
+
+There are a number of unavoidable limitations in natural keyboard mode:
+
+* The emulated system must to support it.
+* The selected keyboard *must* match the keyboard layout selected in the
+ emulated software.
+* Keystrokes that don’t produce characters can’t be translated. (e.g. pressing a
+ modifier key on its own, such as **Shift** or **Control**).
+* Holding a key until the character repeats will cause the emulated key to be
+ pressed repeatedly as opposed to being held down.
+* Dead key sequences are cumbersome to use at best.
+* Complex input methods will not work at all (e.g. for Chinese/Japanese/Korean).
+
+Each emulated device in the system that has keyboard and/or keypad inputs is
+listed on the menu, allowing keyboard/keypad inputs to be enabled or disabled
+for individual devices. By default, keyboard/keypad inputs are enabled for the
+first device with keyboard inputs (if any), and for all other devices that have
+keypad inputs but no keyboard inputs. The enabled keyboard/keypad inputs are
+automatically saved to the configuration file for the system when the emulation
+session ends.
+
+
+.. _menus-inputdevices:
+
+Input Devices menu
+------------------
+
+The Input Devices menu lists input devices recognised by MAME and enabled with
+your current settings. Recognised input devices depend on the
+:ref:`keyboardprovider <mame-commandline-keyboardprovider>`, :ref:`mouseprovider
+<mame-commandline-mouseprovider>`, :ref:`lightgunprovider
+<mame-commandline-lightgunprovider>` and :ref:`joystickprovider
+<mame-commandline-joystickprovider>` options. Classes of input devices can be
+enabled or disabled using the :ref:`mouse <mame-commandline-nomouse>`,
+:ref:`lightgun <mame-commandline-nolightgun>` and :ref:`joystick
+<mame-commandline-nojoystick>` options. You can reach the Input Devices menu by
+selecting **Input Devices** from the :ref:`Input Settings menu
+<menus-inputopts>` or the General Settings menu.
+
+Input devices are grouped by device class (for example keyboards or light guns).
+You can move between device classes using the **Next Group** and **Previous
+Group** keys or buttons. For each device, the device number (within its class)
+is shown on the left, and the name is shown on the right.
+
+Select a device to show the supported controls for the device. The name of
+each control is displayed on the left and its current state is shown on the
+right. When an analog axis control is highlighted, its state is also shown in
+graphical form below the menu. Digital control states are either zero
+(inactive) or one (active). Analog axis input states range from -65,536 to
+65,536 with the neutral position at zero. You can also select **Copy Device
+ID** to copy the device’s ID to the clipboard. This is useful for setting up
+:ref:`stable controller IDs <devicemap>` in :ref:`controller configuration files
+<ctrlrcfg>`.
+
+
+.. _menus-audiomixer:
+
+Audio Mixer menu
+----------------
+
+The Audio Mixer menu allows to establish connections between emulated
+speakers and microphones, and system audio inputs and outputs. It
+uses the standard up/down arrows to select a device and/or current
+mapping, left/right arrows to change a value (system audio port,
+level, channel...) and [ ] to change column. In addition the (by
+default) F key adds a full mapping, C a channel mapping, and Delete
+clears a mapping.
+
+A full mapping sends all channels of a speaker to the appropriate(s)
+channel(s) of the system output, and similarly retrieves all channels
+of a microphone from the appropriate(s) input(s) of a system input.
+For instance a mono speaker will send audio to both channels of a
+stereo system output.
+
+A channel mapping maps between one channel of speaker or a microphone
+and one channel of a system input or output. It can be a little
+tedious, but it allows for instance to take two mono speakers and turn
+it into the left and right channels of a system output, which is
+useful for some cabinets.
+
+Every mapping has a configurable volume associated. When changing the
+volume, optionally hold shift/ctrl/alt keys to adjust the step amount.
+
+The mapping configuration is saved in the system cfg file.
+
+Some OSes propose an external interface to change mappings and volumes
+dynamically, for instance pipewire on linux. Mame does its best to
+follow that and keep the information in the cfg file for future runs.
+
+
+.. _menus-audioeffects:
+
+Audio Effects menu
+------------------
+
+This menu allows to configure the audio effects that are applied to
+the speaker outputs between the speaker device and the audio mixer.
+In other words, the output channels as seen in the audio mixer are the
+outputs of the effect chains. Each speaker has an independant effect
+chain applied.
+
+The chain itself is not configurable it is always in order:
+
+* Filter
+* Compressor
+* Reverb
+* EQ
+
+The parameters of each are fully configurable though. A configured
+parameter shows as white, a default as grey, and Clear allows to go
+back to the default value. The default parameters for the chain of a
+given speaker are the parameters of the Default chain, and the default
+parameters of the Default chain are fixed. The default chain allows
+to create a global setup that one likes and have it applied everywhere
+by default.
+
+In addition, this menu allows to choose the resampler to use when
+converting sample rates between emulated devices. The type allows to
+choose between a fast, lower quality one, "LoFi", and a slow, high
+quality one "HQ". The HQ resampler is configurable. The latency
+indicates the max latency of the resampler, which allows better
+quality when higher, the filter length balances quality and speed
+where a high value is highest quality but slowest speed, and phases
+balances quality and resampler creation time, with one again higher
+means better but slower.
+
+
+Filter effect
+~~~~~~~~~~~~~
+
+This effect proposes an order-2 high-pass and order-2 low-pass filter.
+The high-pass filter allows to remove the DC offset some emulated
+hardware has which can create saturation when not needed. The
+low-pass filter (defaulting to off) allows to reproduce how muffled
+the sound of a number of cabinets and TVs were.
+
+The Q factor defines how sharp the transition is, the higher the
+sharper. Over 0.7 the filter starts amplifying the frequencies around
+the cutoff though, which can be surprising.
+
+
+Compression effect
+~~~~~~~~~~~~~~~~~~
+
+Not implemented yet.
+
+
+Reverb effect
+~~~~~~~~~~~~~
+
+Not implemented yet.
+
+
+EQ effect
+~~~~~~~~~
-[todo: This needs SERIOUS expansion. Waiting on answer to a few questions..]
+The 5-band parametric equalizer allows to amplify or reduce certain
+bands of frequency in the spectrum. The three middle filters, and
+also the extreme ones if configured as "Peak", change frequencies
+around the cutoff. The Q factor selects the sharpness of the peak,
+the higher the sharper. The extreme filters in "Shelf" mode move all
+the frequencies under (or over) the cutoff frequency.
diff --git a/docs/source/usingmame/ui.rst b/docs/source/usingmame/ui.rst
new file mode 100644
index 00000000000..94c7eba413d
--- /dev/null
+++ b/docs/source/usingmame/ui.rst
@@ -0,0 +1,538 @@
+.. _ui:
+
+MAME’s User Interface
+=====================
+
+.. contents:: :local:
+
+
+.. _ui-intro:
+
+Introduction
+------------
+
+MAME provides a simple user interface for selecting the system and software to
+run and changing settings while running an emulated system. MAME’s user
+interface is designed to be usable with a keyboard, game controller, or pointing
+device, but will require a keyboard for initial configuration.
+
+The default settings for the most important controls to know when running an
+emulated system, and the settings they correspond to in case you want to change
+them, are as follows:
+
+Scroll Lock, or Forward Delete on macOS (Toggle UI Controls)
+ For emulated systems with keyboard inputs, enable or disable UI controls.
+ (MAME starts with UI controls disabled for systems with keyboard inputs
+ unless the :ref:`ui_active option <mame-commandline-uiactive>` is on.)
+Tab (Show/Hide Menu)
+ Show or hide the menu during emulation.
+Escape (UI Back and UI Cancel)
+ Return to the system selection menu, or exit if MAME was started with a
+ system specified (from the command line or using an
+ :ref:`external front-end <frontends>`).
+
+
+.. _ui-menus:
+
+Navigating menus
+----------------
+
+By default, MAME menus can be navigated using the keyboard cursor keys. All
+the UI controls can be changed by going to the **General Inputs** menu and then
+selecting **User Interface**. The default keyboard controls on a US ANSI QWERTY
+layout keyboard, and the settings they correspond to, are as follows:
+
+Up Arrow (UI Up)
+ Highlight the previous menu item, or the last item if the first item is
+ highlighted.
+Down Arrow (UI Down)
+ Highlight the next menu item, or the first item if the last item is
+ highlighted.
+Left Arrow (UI Left)
+ For menu items that are adjustable settings, reduce the value or select the
+ previous setting (these menu items show left- and right-facing triangles
+ beside the value).
+Right Arrow (UI Left)
+ For menu items that are adjustable settings, increase the value or select
+ the next setting (these menu items show left- and right-facing triangles
+ beside the value).
+Return/Enter keypad Enter (UI Select)
+ Select the highlighted menu item.
+Forward Delete, or Fn+Delete on some compact keyboards (UI Clear)
+ Clear setting or reset to default value.
+Escape (UI Back and UI Cancel)
+ Clear the search if searching the menu, otherwise close the menu, returning
+ to the previous menu, or returning to the emulated system in the case of the
+ main menu (there’s usually an item at the bottom of the menu for the same
+ purpose).
+Home (UI Home)
+ Highlight the first menu item and scroll to the top of the menu.
+End (UI End)
+ Highlight the last menu item and scroll to the bottom of the menu.
+Page Up (UI Page Up)
+ Scroll the menu up by one screen.
+Page Down (UI Page Down)
+ Scroll the menu down by one screen.
+[ (UI Previous Group)
+ Move to the previous group of items (not used by all menus).
+] (UI Next Group)
+ Move to the next group of items (not used by all menus).
+
+
+.. _ui-menus-gamectrl:
+
+Using a game controller
+~~~~~~~~~~~~~~~~~~~~~~~
+
+MAME supports navigating menus with a game controller or joystick, but only the
+most important UI controls have joystick assignments by default:
+
+* Move the first joystick up or down in the Y axis to highlight the previous or
+ next menu item.
+* Move the first joystick left or right in the X axis to adjust settings.
+* Press the first button on the first joystick to select the highlighted menu
+ item.
+* If the first joystick has at least three buttons, press the second button on
+ the first joystick to close the menu, returning to the previous menu, or
+ returning to the emulated system in the case of the main menu (there’s usually
+ an item at the bottom of the menu for the same purpose).
+
+For gamepad-style controllers, the left analog thumb stick and directional pad
+usually control UI navigation. Depending on the controller, the right analog
+thumb stick, triggers and additional buttons may automatically be assigned to UI
+inputs. Check the **User Interface** input assignments menu to see how controls
+are assigned.
+
+If you want to be able to use MAME with a game controller without needing a
+keyboard, you’ll need to assign joystick buttons (or combinations of buttons) to
+these controls as well:
+
+* **Show/Hide Menu** to show or hide the menu during emulation
+* **UI Back** to close menus
+* **UI Cancel** to return to the system selection menu or exit MAME
+* **UI Clear** isn’t essential for basic emulation, but it’s used to clear or
+ reset some settings to defaults
+* **UI Home**, **UI End**, **UI Page Up**, **UI Page Down**, **UI Previous
+ Group** and **UI Next Group** are not essential, but make navigating some
+ menus easier
+
+If you’re not using an external front-end to launch systems in MAME, you should
+assign joystick buttons (or combinations of buttons) to these controls to make
+full use of the system and software selection menus:
+
+* **UI Focus Next**/**UI Focus Previous** to navigate between panes
+* **UI Add/Remove favorite**, **UI Export List** and **UI Audit Media** if you
+ want access to these features without using a keyboard or pointing device
+
+
+.. _ui-menus-mouse:
+
+Using a mouse or trackball
+~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+MAME supports navigating menus using a mouse or trackball that works as a system
+pointing device:
+
+* Click menu items to highlight them.
+* Double-click menu items to select them.
+* Click the left- or right-pointing triangle to adjust settings.
+* For menus or text boxes with too many items or lines to fit on the screen,
+ press on the upward- or downward-pointing triangle at the top or bottom to
+ scroll up or down.
+* Use vertical scrolling gestures to scroll menus or text boxes with too many
+ items or lines to fit on the screen.
+* Click toolbar items to select them, or hover over them to see a description.
+
+If you have enough additional mouse buttons, you may want to assign button
+combinations to the **Show/Hide Menu**, **Pause**, **UI Back** and/or
+**UI Cancel** inputs to make it possible to use MAME without a keyboard.
+
+
+.. _ui-menus-touch:
+
+Using a touch screen
+~~~~~~~~~~~~~~~~~~~~
+
+MAME has basic support for navigating menus using a touch screen:
+
+* Tap menu items to highlight them.
+* Double-tap menu items to select them.
+* Swipe left or right (horizontally) on the highlighted menu item to adjust the
+ setting if applicable.
+* Swipe up or down (vertically) to scroll menus or text boxes with too many
+ items to fit on the screen.
+* For menus or text boxes with too many items or lines to fit on the screen,
+ press on the upward- or downward-pointing triangle at the top or bottom to
+ scroll up or down.
+
+Note that for SDL-based MAME, the
+:ref:`enable_touch <mame-scommandline-enabletouch>` option must be switched on
+to use touch screen support.
+
+
+.. _ui-inptcfg:
+
+Configuring inputs
+------------------
+
+MAME needs a flexible input system to support the control schemes of the vast
+array of systems it emulates. In MAME, inputs that only have two distinct
+states, on and off or active and inactive, are called *digital inputs*, and all
+other inputs are called *analog inputs*, even if this is not strictly true (for
+example multi-position switches are called analog inputs in MAME).
+
+To assign MAME’s user interface controls or the default inputs for all systems,
+select **Input Settings** from the main menu during emulation and then select
+**Input Assignments (general)** from the Input Settings menu, or select
+**General Settings** from the system selection menu and then select **Input
+Assignments** from the General Settings menu. From there, select a category.
+
+To assign inputs for the currently running system, select **Input Settings**
+from the main menu during emulation and then select **Input Assignments (this
+system)** from the Input Settings menu. Inputs are grouped by device and sorted
+by type. You can move between devices with the next group and previous group
+keys/buttons (opening/closing brackets **[** and **]** on the keyboard by
+default).
+
+The input assignment menus show the name of the emulated input or user interface
+control on the left, and the controls (or combination of controls) assigned to
+it on the right.
+
+To adjust the sensitivity, auto-centre speed and inversion settings, or to see
+how emulated analog controls react to your inputs, select **Input Settings**
+from the main menu during emulation, and then select **Analog Input
+Adjustments** from the Input Settings Menu (this item only appears on the Input
+Settings menu for systems with analog controls).
+
+
+.. _ui-inptcfg-digital:
+
+Digital input settings
+~~~~~~~~~~~~~~~~~~~~~~
+
+Each emulated digital input has a single assignment setting. For flexibility,
+MAME can combine controls (keys, buttons and joystick axes) using logical
+**and**, **not** and **or** operations. This is best illustrated with some
+examples:
+
+Kbd 1
+ In this simple case, pressing the **1** key on the keyboard activates the
+ emulated input or user interface control.
+Kbd Down or Joy 1 Down
+ Pressing the down arrow on the keyboard or moving the first joystick down
+ activates the emulated input or user interface control.
+Kbd P not Kbd Shift not Kbd Right Shift
+ Pressing the **P** key on the keyboard while not pressing either **Shift**
+ key activates the emulated input or user interface control. MAME does not
+ show the implicit **and** operations.
+Kbd P Kbd Shift or Kbd P Kbd Right Shift
+ Pressing the **P** key while also pressing either of the **Shift** keys
+ activates the emulated input or user interface control. Once again, the
+ implicit **and** operations are not shown.
+
+(In technical terms, MAME uses Boolean sum of products logic to combine inputs.)
+
+When a digital input setting is highlighted, the prompt below the menu shows
+whether selecting it will replace the current assignment or append an **or**
+operation to it. Press **UI Left/Right** before selecting the setting to switch
+between replacing the assignment or appending an **or** operation to it. Press
+**UI Clear** (**Delete** or **Forward Delete** by default) to clear the
+highlighted setting, or restore the default assignment if it is currently
+cleared.
+
+When you select a digital input setting, MAME will wait for you to enter an
+input or a combination of inputs for a logical **and** operation:
+
+* Press a key or button or move an analog control once to add it to the **and**
+ operation.
+* Press a key or button or move an analog control twice to add a **not** item to
+ the **and** operation. Pressing the same key or button or moving the same
+ analog control additional times toggles the **not** on and off.
+* Press **UI Cancel** (**Escape** by default) to leave the setting unchanged.
+* The new setting is shown below the menu. Wait one second after activating an
+ input to accept the new setting.
+
+Here’s how to produce some example settings:
+
+Kbd 1
+ Press the **1** key on the keyboard once, then wait one second to accept the
+ setting.
+Kbd F12 Kbd Shift Keyboard Alt
+ Press the **F12** key on the keyboard once, press the left **Shift** key
+ once, press the left **Alt** key once, then wait one second to accept the
+ setting.
+Kbd P not Kbd Shift not Kbd Right Shift
+ Press the **P** key on the keyboard once, press the left **Shift** key
+ twice, press the right **Shift** key twice, then wait one second to accept
+ the setting.
+
+
+.. _ui-inptcfg-analog:
+
+Analog input settings
+~~~~~~~~~~~~~~~~~~~~~
+
+Each emulated analog input has three assignment settings:
+
+* Use the *axis setting* to assign an analog axis to control the emulated analog
+ input. The axis setting uses the name of the input with the suffix “Analog”.
+ For example the axis setting for the steering wheel in Ridge Racer is called
+ **Steering Wheel Analog**.
+* Use the *increment setting* assign a control (or combination of controls) to
+ increase the value of the emulated analog input. The increment setting uses
+ the name of the input with the suffix “Analog Inc”. For example the increment
+ setting for the steering wheel in Ridge Racer is called **Steering Wheel
+ Analog Inc**. This is a digital input setting – if an analog axis is
+ assigned to it, MAME will not increase the emulated input value at a
+ proportional speed.
+* Use the *decrement setting* assign a control (or combination of controls) to
+ decrease the value of the emulated analog input. The decrement setting uses
+ the name of the input with the suffix “Analog Dec”. For example the decrement
+ setting for the steering wheel in Ridge Racer is called **Steering Wheel
+ Analog Dec**. This is a digital input setting – if an analog axis is
+ assigned to it, MAME will not decrease the emulated input value at a
+ proportional speed.
+
+The increment and decrement settings are most useful for controlling an emulated
+analog input using digital controls (for example keyboard keys, joystick
+buttons, or a directional pad). They are configured in the same way as emulated
+digital inputs (:ref:`see above <ui-inptcfg-digital>`). **It’s important that
+you don’t assign the same control to the axis setting as well as the increment
+and/or decrement settings for the same emulated input at the same time.** For
+example if you assign Ridge Racer’s **Steering Wheel Analog** setting to the X
+axis of the left analog stick on your controller, you *should not* assign either
+the **Steering Wheel Analog Inc** or **Steering Wheel Analog Dec** setting to
+the X axis of the same analog stick.
+
+You can assign one or more analog axes to the axis setting for an emulated
+analog input. When multiple axes are assigned to an axis setting, they will be
+added together, but absolute position controls will override relative position
+controls. For example suppose for Arkanoid you assign the **Dial Analog** axis
+setting to **Mouse X or Joy 1 LSX or Joy 1 RSX** on a mouse and Xbox-style
+controller. You will be able to control the paddle with the mouse or either
+analog stick, but the mouse will only take effect if both analog sticks are in
+the neutral position (centred) on the X axis. If either analog stick is *not*
+centred on the X axis, the mouse will have no effect, because a mouse is a
+relative position control while joysticks are absolute position controls.
+
+For absolute position controls like joysticks and pedals, MAME allows you to
+assign either the full range of an axis or the range on one side of the neutral
+position (a *half axis*) to an axis setting. Assigning a half axis is usually
+used for pedals or other absolute inputs where the neutral position is at one
+end of the input range. For example suppose for **Ridge Racer** you assign the
+**Brake Pedal Analog** setting to the portion of a vertical joystick axis below
+the neutral position. If the joystick is at or above the neutral position
+vertically, the brake pedal will be released; if the joystick is below the
+neutral position vertically, the brake pedal will be applied proportionally.
+Half axes are displayed as the name of the axis followed by a plus or minus sign
+(**+** or **-**). Plus refers to the portion of the axis below or to the right
+of the neutral position; minus refers to the portion of the axis above or to the
+left of the neutral position. For pedal or analog trigger controls, the active
+range is treated as being above the neutral position (the half axis indicated by
+a minus sign).
+
+When keys or buttons are assigned to an axis setting, they conditionally enable
+analog controls assigned to the setting. This can be used in conjunction with
+an absolute position control to create a “sticky” control.
+
+Here are some examples of some possible axis setting assignments, assuming an
+Xbox-style controller and a mouse are used:
+
+Joy 1 RSY
+ Use vertical movement of the right analog stick to control the emulated
+ input.
+Mouse X or Joy 1 LT or Joy 1 RT Reverse
+ Use horizontal mouse movement, or the left and right triggers to control the
+ emulated input. The right trigger is reversed so it acts in the opposite
+ direction to the left trigger.
+Joy 1 LB Joy 1 LSX
+ Use horizontal movement of the left analog stick to control the emulated
+ input, but *only* while holding the left shoulder button. If the left
+ shoulder button is released while the left analog stick is not centred
+ horizontally, the emulated input will hold its value until the left shoulder
+ button is pressed again (a “sticky” control).
+not Joy 1 RB Joy 1 RSX or Joy 1 RB Joy 1 RSX Reverse
+ Use horizontal movement of the right analog stick to control the emulated
+ input, but invert the control if the right shoulder button is held.
+
+When you select an axis setting, MAME will wait for you to enter an input:
+
+* Move an analog control to assign it to the axis setting.
+* Press a key or button (or a combination of keys or buttons) *before* moving an
+ analog control to conditionally enable the analog control.
+* When appending to a setting, if the last assigned control is an absolute
+ position control, move the same control again to cycle between the full range
+ of the axis, the portion of the axis on either side of the neutral position,
+ and the full range of the axis reversed.
+* When appending to a setting, if the last assigned control is a relative
+ position control, move the same control again to toggle reversing the
+ direction of the control on or off.
+* When appending to a setting, move an analog control other than the last
+ assigned control or press a key or button to add an **or** operation.
+* Pressing **UI Cancel** (**Escape** by default) leaves the setting unchanged.
+* The new setting is shown below the menu. Wait one second after moving an
+ analog control to accept the new setting.
+
+To adjust sensitivity, auto-centring speed and inversion settings for emulated
+analog inputs, or to see how they respond to controls with your settings, select
+**Input Settings** from the main menu during emulation, and then select **Analog
+Input Adjustments** from the Input Settings Menu. Settings for emulated analog
+inputs are grouped by device and sorted by type. You can move between devices
+with the next group and previous group keys/buttons (opening/closing brackets
+**[** and **]** on the keyboard by default). The state of the emulated analog
+inputs is shown below the menu, and reacts in real time. Press the **On Screen
+Display** key or button (the backtick/tilde key by default on a US ANSI QWERTY
+keyboard) to hide the menu to make it easier to test without changing settings.
+Press the same key or button to show the menu again.
+
+Each emulated input has four settings on the **Analog Controls** menu:
+
+* The *increment/decrement speed* setting controls how fast the input value
+ increases or decreases in response to the controls assigned to the
+ increment/decrement settings.
+* The *auto-centering speed* setting controls how fast the input value returns
+ to the neutral state when the controls assigned to the increment/decrement
+ settings are released. Setting it to zero (**0**) will result in the value
+ not automatically returning to the neutral position.
+* The *reverse* setting allows the direction of the emulated input’s response
+ to controls to be inverted. This applies to controls assigned to the axis
+ setting *and* the increment/decrement settings.
+* The *sensitivity* setting adjusts the input value’s response to the control
+ assigned to the axis setting.
+
+
+Use the UI left/right keys or buttons to adjust the highlighted setting.
+Selecting a setting or pressing the UI clear key/button (**Forward Delete** by
+default) restores its default value.
+
+The units for the increment/decrement speed, auto-centering speed and
+sensitivity settings are tied to the driver/device implementation. The
+increment/decrement speed and auto-centering speed settings are also tied to the
+frame rate of the first emulated screen in the system. The response to controls
+assigned to the increment/decrement settings will change if the system changes
+the frame rate of this screen.
+
+
+.. _ui-selmenu:
+
+The system and software selection menus
+---------------------------------------
+
+If you start MAME without specifying a system on the command line, the system
+selection menu will be shown (assuming the
+:ref:`ui option <mame-commandline-ui>` is set to **cabinet**). The system
+selection menu is also shown if you select **Select New System** from the main
+menu during emulation. Selecting a system that uses software lists shows the
+similar software selection menu.
+
+The system and software selection menus have the following parts:
+
+* The heading area at the top, showing the emulator name and version, the number
+ of systems or software items in the menu, and the current search text. The
+ software selection menu also shows the name of the selected system.
+* The toolbar immediately below the heading area. The exact toolbar buttons
+ shown depend on the menu. Hover the mouse pointer over a button to see a
+ description. Click a button to select it.
+
+ Toolbar buttons are add/remove highlighted system/software from favourites
+ (star), export displayed list to file (diskette), audit media (magnifying
+ glass), show info viewer (“i” emblazoned on blue circle), return to previous
+ menu (bent arrow on blue), and exit (cross on red).
+* The list of systems or software in the centre. For the system selection menu,
+ there are configuration options below the list of systems. Clones are shown
+ with a different text colour (grey by default). You can right-click a system
+ name as a shortcut to show the System Settings menu for the system.
+
+ Systems or software items are sorted by full name or description, keeping
+ clones immediately below their parents. This may appear confusing if your
+ filter settings cause a parent system or software item to be hidden while one
+ or more of its clones are visible.
+* The info panel at the bottom, showing summary information about the
+ highlighted system or software. The background colour changes depending on
+ the emulation status: green for working, amber for imperfectly emulated
+ features or known issues, or red for more serious issues.
+
+ A yellow star is show at the top left of the info panel if the highlighted
+ system or software is in your favourites list.
+* The collapsible list of filter options on the left. Click a filter to apply
+ it to the list of systems/software. Some filters show a menu with additional
+ options (e.g. specifying the manufacturer for the **Manufacturer** filter, or
+ specifying a file and group for the **Category** filter).
+
+ Click **Unfiltered** to display all items. Click **Custom Filter** to combine
+ multiple filters. Click the strip between the list of filters and the list of
+ systems/software to show or hide the list of filters. Be aware that filters
+ still apply when the list of filters is hidden.
+* The collapsible info viewer on the right. This has two tabs for showing
+ images and information. Click a tab to switch tabs; click the left- or
+ right-facing triangles next to the image/info title to switch between images
+ or information sources.
+
+ Emulation information is automatically shown for systems, and information from
+ the software list is shown for software items. Additional information from
+ external files can be shown using the :ref:`Data plugin <plugins-data>`.
+
+You can type to search the displayed list of systems or software. Systems are
+searched by full name, manufacturer and full name, and short name. If you are
+using localised system names, phonetic names will also be searched if present.
+Software items are searched by description, alternate titles (``alt_title``
+info elements in the software lists), and short name. **UI Cancel** (Escape by
+default) will clear the search if currently searching.
+
+
+.. _ui-selmenu-nav:
+
+Navigation controls
+~~~~~~~~~~~~~~~~~~~
+
+In addition to the usual :ref:`menu navigation controls <ui-menus>`, the system
+and software selection menus have additional configurable controls for
+navigating the multi-pane layout, and providing alternatives to toolbar buttons
+if you don’t want to use a pointing device. The default additional controls
+(with a US ANSI QWERTY keyboard), and the settings they correspond to, are:
+
+Tab (UI Focus Next)
+ Move focus to the next area. The order is system/software list,
+ configuration options (if visible), filter list (if visible), info/image
+ tabs (if visible), info/image source (if visible).
+Shift+Tab (UI Focus Previous)
+ Move focus to the previous area.
+Alt+D (UI External DAT View)
+ Show the full-size info viewer.
+Alt+F (UI Add/Remove favorite)
+ Add or remove the highlighted system or software item from the favourites
+ list.
+F1 (UI Audit Media)
+ Audit ROMs and/or disk images for systems. The results are saved for use
+ with the **Available** and **Unavailable** filters.
+
+When focus is on the filter list, you can use the menu navigation controls (up,
+down, home and end) to highlight a filter, and **UI Select** (Return/Enter by
+default) apply it.
+
+When focus is on any area besides the info/image tabs, you can change the image
+or info source with left/right. When focus is on the info/image tabs,
+left/right switch between tabs. When focus is on the image/info tabs or source,
+you can scroll the info using up, down, page up, page down, home and end.
+
+You can move focus to an area by clicking on it with the middle mouse button.
+
+
+.. _ui-simpleselmenu:
+
+The simple system selection menu
+--------------------------------
+
+If you start MAME without specifying a system on the command line (or choose
+**Select New System** from the main menu during emulation) with the
+:ref:`ui option <mame-commandline-ui>` set to **simple**, the simple system
+selection menu will be shown. The simple system selection menu shows fifteen
+randomly selected systems that have ROM sets present in your configured
+:ref:`ROM folder(s) <mame-commandline-rompath>`. You can type to search for a
+system. Clearing the search causes fifteen systems to be randomly selected
+again.
+
+The info panel below the menu shows summary information about the highlighted
+system. The background colour changes depending on the emulation status: green
+for working, amber for imperfectly emulated features or known issues, or red for
+more serious issues.
diff --git a/docs/source/usingmame/usingmame.rst b/docs/source/usingmame/usingmame.rst
index 4163158aba6..4fa014fe3da 100644
--- a/docs/source/usingmame/usingmame.rst
+++ b/docs/source/usingmame/usingmame.rst
@@ -1,11 +1,20 @@
Using MAME
----------
-If you want to dive right in and skip the command line, there's a nice graphical way to use MAME without the need to download and set up a front end. Simply start MAME with no parameters, by doubleclicking the **mame.exe** file or running it directly from the command line. If you're looking to harness the full power of MAME, keep reading further.
+If you want to dive right in and skip the command line, there's a nice graphical
+way to use MAME without the need to download and set up a front end. Simply
+start MAME with no parameters, by double-clicking the **mame.exe** file or
+running it directly from the command line. If you're looking to harness the
+full power of MAME, keep reading further.
-On Macintosh OS X and \*nix-based platforms, please be sure to set your font up to match your locale before starting, otherwise you may not be able to read the text due to missing glyphs.
+On macOS and \*nix-based platforms, please be sure to set your font up to match
+your locale before starting, otherwise you may not be able to read the text due
+to missing glyphs.
-If you are a new MAME user, you could find this emulator a bit complex at first. Let's take a moment to talk about softlists, as they can simplify matters quite a bit. If the content you are trying to play is a documented entry on one of the MAME softlists, starting the content is as easy as
+If you are a new MAME user, you could find this emulator a bit complex at
+first. Let's take a moment to talk about software lists, as they can simplify
+matters quite a bit. If the content you are trying to play is a documented
+entry on one of the MAME software lists, starting the content is as easy as
**mame.exe** *<system>* *<software>*
@@ -18,55 +27,86 @@ will load the USA version of Metroid for the Nintendo Entertainment System.
Alternatively, you could start MAME with
- **mame.exe nes**
-
-and choose the *software list* from the cartridge slot. From there, you could pick any softlist-compatible software you have in your roms folders. Please note that many older dumps of cartridges and discs may either be bad or require renaming to match up to the softlist in order to work in this way.
+ **mame.exe nes**
+and choose the *software list* from the cartridge slot. From there, you could
+pick any software list-compatible software you have in your roms folders. Please
+note that many older dumps of cartridges and discs may either be bad or require
+renaming to match up to the software list in order to work in this way.
-If you are loading an arcade board or other non-softlist content, things are only a little more complicated:
+If you are loading an arcade board or other non-software list content, things
+are only a little more complicated:
The basic usage, from command line, is
- **mame.exe** *<system>* *<media>* *<software>* *<options>*
+ **mame.exe** *<system>* *<media>* *<software>* *<options>*
where
-* *<system>* is the shortname of the system you want to emulate (e.g. nes, c64, etc.)
-* *<media>* is the switch for the media you want to load (if it's a cartridge, try **-cart** or **-cart1**; if it's a floppy disk, try **-flop** or **-flop1**; if it's a CD-ROM, try **-cdrom**)
-* *<software>* is the program / game you want to load (and it can be given either as the fullpath to the file to load, or as the shortname of the file in our software lists)
-* *<options>* is any additional command line option for controllers, video, sound, etc.
+* *<system>* is the short name of the system you want to emulate (e.g. nes, c64,
+ etc.)
+* *<media>* is the switch for the media you want to load (if it's a cartridge,
+ try **-cart** or **-cart1**; if it's a floppy disk, try **-flop** or
+ **-flop1**; if it's a CD-ROM, try **-cdrom**)
+* *<software>* is the program / game you want to load (and it can be given
+ either as the fullpath to the file to load, or as the shortname of the file in
+ our software lists)
+* *<options>* is any additional command line option for controllers, video,
+ sound, etc.
-Remember that if you type a <system> name which does not correspond to any emulated system, MAME will suggest you some possible choices which are close to what you typed; and if you don't know which <media> switch are available, you can always launch
+Remember that if you type a *<system>* name which does not correspond to any
+emulated system, MAME will suggest some possible choices which are close to
+what you typed; and if you don't know which *<media>* switch are available, you
+can always launch
- **mame.exe** *<system>* **-listmedia**
+ **mame.exe** *<system>* **-listmedia**
-If you don't know what *<options>* are available, there are a few things you can do. First of all, you can check the command line options section of this manual. You can also try one of the many :ref:`frontends` available for MAME.
+If you don't know what *<options>* are available, there are a few things you
+can do. First of all, you can check the command line options section of this
+manual. You can also try one of the many :ref:`frontends` available for MAME.
-Alternatively, you should keep in mind the following command line options, which might be very useful on occasion:
+Alternatively, you should keep in mind the following command line options,
+which might be very useful on occasion:
- **mame.exe -help**
+ **mame.exe -help**
-tells what MAME is the basic structure of MAME launching options, i.e. as explained above.
+gives a basic summary of command line options for MAME, as explained above.
- **mame.exe -showusage**
+ **mame.exe -showusage**
-gives you the (quite long) list of available command line options for MAME. The main options are described, in the :ref:`universal-command-line` section of this manual.
+gives you the (quite long) list of available command line options for MAME.
+The main options are described, in the :ref:`mame-commandline-universal` section
+of this manual.
- **mame.exe -showconfig**
+ **mame.exe -showconfig**
-gives you a (quite long) list of available configuration options for MAME. These configuration can always be modified at command line, or by editing them in mame.ini which is the main configuration file for MAME. You can find a description of some configuration options in the :ref:`universal-command-line` section of the manual (in most cases, each configuration option has a corresponding command line option to configure and modify it).
+gives you a (quite long) list of available configuration options for MAME.
+These options can always be modified at command line, or by editing them in
+mame.ini which is the main configuration file for MAME. You can find a
+description of some configuration options in the
+:ref:`mame-commandline-universal` section of the manual (in most cases, each
+configuration option has a corresponding command line option to configure and
+modify it).
- **mame.exe -createconfig**
+ **mame.exe -createconfig**
-creates a brand new **mame.ini** file, with default configuration settings. Notice that mame.ini is basically a plain text file, hence you can open it with any text editor (e.g. Notepad, Emacs or TextEdit) and configure every option you need. However, no particular tweaks are needed to start, so you can basically leave most of the options unaltered.
+creates a brand new **mame.ini** file, with default configuration settings.
+Notice that mame.ini is basically a plain text file, so you can open it with any
+text editor (e.g. Notepad, Emacs or TextEdit) and configure every option you
+need. However, no particular tweaks are needed to start, so you can leave most
+of the options unaltered.
-If you execute **mame64 -createconfig** when you already have an existing mame.ini from a previous MAME version, MAME automatically updates the pre-existing mame.ini by copying changed options into it.
+If you execute **mame -createconfig** when you already have an existing
+mame.ini from a previous MAME version, MAME automatically updates the
+pre-existing mame.ini by copying changed options into it.
-Once you are more confident with MAME options, you may want to configure a bit more your setup. In this case, keep in mind the order in which options are read; see :ref:`advanced-multi-CFG` for details.
+Once you are more confident with MAME options, you may want to adjust the
+configuration of your setup a bit more. In this case, keep in mind the order in
+which options are read; see :ref:`advanced-multi-CFG` for details.
diff --git a/docs/source/whatis.rst b/docs/source/whatis.rst
index 51f9d244226..9e6218042dc 100644
--- a/docs/source/whatis.rst
+++ b/docs/source/whatis.rst
@@ -3,68 +3,85 @@ What is MAME
MAME is a multi-purpose emulation framework.
-MAME's purpose is to preserve decades of software history. As electronic technology continues to rush forward, MAME prevents this important "vintage" software from being lost and forgotten. This is achieved by documenting the hardware and how it functions. The source code to MAME serves as this documentation. The fact that the software is usable serves primarily to validate the accuracy of the documentation (how else can you prove that you have recreated the hardware faithfully?). Over time, MAME (originally stood for Multiple Arcade Machine Emulator) absorbed the sister-project MESS (Multi Emulator Super System), so MAME now documents a wide variety of (mostly vintage) computers, video game consoles and calculators, in addition to the arcade video games that were its initial focus.
+MAME’s purpose is to preserve decades of software history. As
+electronic technology continues to rush forward, MAME prevents this
+important “vintage” software from being lost and forgotten. This is
+achieved by documenting the hardware and how it functions. The source
+code to MAME serves as this documentation. The fact that the software
+is usable serves primarily to validate the accuracy of the documentation
+(how else can you prove that you have recreated the hardware
+faithfully?). MAME, originally the Multiple Arcade Machine Emulator,
+absorbed sister-projects, including MESS (Multi-Emulator Super System)
+and AGEMAME (Arcade Gambling Extensions for MAME), so MAME now documents
+a wide variety of (mostly vintage) computers, video game consoles,
+calculators and gambling machines, in addition to the arcade video games
+that were its initial focus.
|
| **MAME®**
-| **Copyright © 1997-2019 by Nicola Salmoria and the MAME team**
-| **MAME is a registered trademark owned by Gregory Ember**
+| **Copyright © 1997-2025 MAMEdev and contributors**
+| **MAME is a registered trademark of Gregory Ember**
|
I. Purpose
----------
-MAME's main purpose is to be a reference to the inner workings of the
-emulated machines. This is done both for educational purposes and for
+MAME’s main purpose is to be a reference to the inner workings of the
+emulated machines. This is done both for educational purposes and for
preservation purposes, in order to prevent historical software from
-disappearing forever once the hardware it runs on stops working. Of
+disappearing forever once the hardware it runs on stops working. Of
course, in order to preserve the software and demonstrate that the
emulated behavior matches the original, one must also be able to
-actually use the software. This is considered a nice side effect, and is
-not MAME's primary focus.
+actually use the software. This is considered a nice side effect, and
+is not MAME’s primary focus.
It is not our intention to infringe on any copyrights or patents on the
-original games. All of MAME's source code is either our own or freely
-available. To operate, the emulator requires images of the original
-ROMs, CDs, hard disks or other media from the machines, which must be
-provided by the user. No portions of the original game code are included
-in the executable.
+original software and systems. All of MAME’s source code is either our
+own or freely available. To operate, the emulator requires images of
+the original ROMs, CDs, hard disks or other media from the machines,
+which must be provided by the user. No portions of the original
+software are included in the MAME executable.
II. Cost
--------
-MAME is free. Its source code is free. The project as whole is
-distributed under the GNU General Public License, version 2 or later
-(GPL-2.0+), but most of code (including core functionality) is also
-available under the 3-clause BSD license (BSD-3-clause).
+
+MAME is made available at no cost. Its source code is freely available.
+The project as whole is distributed under the terms of the GNU General
+Public License, version 2 or later (GPL-2.0+), but most of code,
+including core functionality, is also available under the terms of the
+more permissive 3-clause BSD license (BSD-3-clause).
III. Software Image Files
-------------------------
ROM, CD, hard disk and other media images are all copyrighted material.
-They cannot be distributed without the explicit permission of the
-copyright holder(s). They are not "abandonware", nor has any of the
-software supported by MAME passed out of copyright.
+They may not be lawfully distributed without the explicit permission of
+the copyright holder(s). They are not “abandonware”, nor has copyright
+expired on any of the software supported by MAME.
MAME is not intended to be used as a tool for mass copyright
-infringement. Therefore, it is strongly against the authors' wishes to
+infringement. Therefore, it is strongly against the authors’ wishes to
sell, advertise, or link to resources that provide illegal copies of
ROM, CD, hard disk or other media images.
IV. Derivative Works
--------------------
+
Because the name MAME is trademarked, you must abide by the rules set
-out for trademark usage if you wish to use "MAME" as part of the name
-your derivative work. In general, this means you must request
+out for trademark usage if you wish to use “MAME” as part of the name
+your derivative work. In general, this means you must request
permission, which requires that you follow the guidelines above.
The version number of any derivative work should reflect the version
-number of the MAME release from which it was was derived.
+number of the MAME release from which it was derived.
V. Official Contact Information
-------------------------------
-For questions regarding the MAME license, trademark, or other usage, go to http://www.mamedev.org/
+
+For questions regarding the MAME license, trademark, or other usage, see
+https://www.mamedev.org/legal.html