Skip site navigation (1)Skip section navigation (2)

FreeBSD Manual Pages

  
 
  

home | help
MAME(1)			      MAME Documentation		       MAME(1)

NAME
       MAME - MAME Documentation [image: MAME] [image]

       NOTE:
	  This	documentation is a work	in progress.  You can track the	status
	  of these topics through MAME's issue	tracker.  Learn	 how  you  can
	  contribute.

WHAT IS	MAME
       MAME is a multi-purpose emulation framework.

       MAMEs  purpose  is  to  preserve	decades	of software history.  As elec-
       tronic technology continues to rush forward, MAME prevents this	impor-
       tant  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 us-
       able serves primarily to	validate the  accuracy	of  the	 documentation
       (how  else  can	you  prove that	you have recreated the hardware	faith-
       fully?).	 MAME, originally the Multiple Arcade  Machine	Emulator,  ab-
       sorbed  sister-projects,	 including  MESS (Multi-Emulator Super System)
       and AGEMAME (Arcade Gambling Extensions for MAME), so  MAME  now	 docu-
       ments  a	 wide  variety	of (mostly vintage) computers, video game con-
       soles, calculators and gambling machines, in  addition  to  the	arcade
       video games that	were its initial focus.

       MAME
       Copyright  1997-2025 MAMEdev and	contributors
       MAME is a registered trademark of Gregory Ember

   I. Purpose
       MAMEs  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
       course, in order	to preserve the	software and demonstrate that the emu-
       lated  behavior matches the original, one must also be able to actually
       use the software.  This is considered a nice side effect,  and  is  not
       MAMEs primary focus.

       It is not our intention to infringe on any copyrights or	patents	on the
       original	 software and systems.	All of MAMEs 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	 soft-
       ware are	included in the	MAME executable.

   II. Cost
       MAME  is	 made  available at no cost.  Its source code is freely	avail-
       able.  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 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  infringe-
       ment.   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  permis-
       sion, 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 derived.

   V. Official Contact Information
       For questions regarding the MAME	license, trademark,  or	 other	usage,
       see https://www.mamedev.org/legal.html

HEALTH WARNINGS
   Epilepsy Warning
       A  very	small  percentage  of  individuals  may	 experience  epileptic
       seizures	when exposed to	certain	light patterns or flashing lights. Ex-
       posure 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 moni-
       tor, 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

GETTING	MAME PREPARED
       This  section  covers  initial preparation work needed to use MAME, in-
       cluding downloading MAME, compiling MAME	from source,  and  configuring
       MAME.

   An Introduction to MAME
       MAME,  formerly	an acronym which stood for Multi Arcade	Machine	Emula-
       tor, 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-ef-
       fect,  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 video games, while	MESS covered home and business
       systems.	They are now merged into the one MAME.

       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 pre-
       vents these important vintage systems from being	lost and forgotten.

   Systems Emulated by MAME
       The Arcade Database  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 sys-
	  tem, 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  un-
	  derstand  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

        Post the information or code on the MAME Forums

        Follow	the instructions on our	contact	page

   Supported OS
       The current source code can be directly compiled	under all the main op-
       erating systems:	Microsoft Windows (both	with DirectX/BGFX native  sup-
       port or with SDL	support), Linux, FreeBSD, and macOS.

   System Requirements
       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 ca-
       pabilities offered.

       The official MAME binaries are compiled and designed to run on a	 stan-
       dard Windows-based system. The minimum requirements are:

        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

       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 displayed software to full screen. To make  use	of  this,  you
       should  have  at	least a	semi-modern computer with semi-modern 3D hard-
       ware 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 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 isnt 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) on vari-
       ous 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 ma-
       chine where it does not have internal  software	(e.g.  some  computers
       will need a disk	to boot	to an operating	system).

       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  con-
       sole 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.

   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, isnt 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
       compiling MAME.

   Compiling MAME
        All Platforms

        Microsoft Windows

	  Using a standard MSYS2 installation

	  Building with Microsoft Visual Studio

	  Some	notes about the	MSYS2 environment

        Fedora	Linux

        Debian	and Ubuntu (including Raspberry	Pi and ODROID devices)

        Arch Linux

        Apple macOS

        Emscripten Javascript and HTML

        Compiling the Documentation

	  Compiling the Documentation on Microsoft Windows

	  Compiling the Documentation on Debian and Ubuntu

        Useful	Options

	  Overall build options

	  Tool	locations

	  Including subsets of	supported systems

	  Optional features

	  Compilation options

	  Library/framework locations

        Known Issues

	  Issues with specific	compiler versions

	  GNU C Library fortify source	feature

	  Issues affecting Microsoft Visual Studio

        Unusual Build Configurations

	  Linking using the LLVM linker

	  Cross-compiling MAME

	  Using libc++	on Linux

	  Using a GCC/GNU libstdc++ installation in a	non-standard  location
	   on Linux

   All Platforms
        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 ver-
	 sion 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 op-
	 timisation  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,  in-
	 cluding  number of CPU	cores, available RAM, disk and filesystem per-
	 formance, 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 in-
	 cluding 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.

       Putting all of these together, we get a couple of examples:

       Rebuilding MAME on a dual-core (e.g. i3 or laptop i5) machine:

	  make -j3

       Rebuilding MAME for just	the Pac-Man and	Galaxian families of  systems,
       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

       Rebuilding  MAME	 for  just  the	 Apple II systems, compiling up	to six
       sources in parallel:

	  make SUBTARGET=appulator SOURCES=apple/apple2.cpp,apple/apple2e.cpp,apple/apple2gs.cpp REGENIE=1 -j6

   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.

        A  pre-packaged  MSYS2	 installation  including the prerequisites for
	 building MAME can be downloaded from the MAME Build Tools page.

        After initial installation, you can update the	MSYS2 environment  us-
	 ing the pacman	(Arch package manage) command.

        By default, MAME will be built	using native Windows OS	interfaces 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.  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 op-
	 tions.	 You will need to install the MSYS2 packages for Qt 5.

   Using a standard MSYS2 installation
       You may also build MAME using a standard	MSYS2 installation and	adding
       the tools needed	for building MAME.  These instructions assume you have
       some familiarity	with MSYS2 and the pacman package manager.

        Install the MSYS2 environment from  the MSYS2 homepage.

        Download  the	latest version of the mame-essentials package from the
	 MAME package repository and install it	using the pacman command.

        Add the mame package repository to /etc/pacman.conf  using  /etc/pac-
	 man.d/mirrorlist.mame	for locations, and disable signature verifica-
	 tion for this repository (SigLevel = Never).

        Install packages necessary to build MAME.  At the very	 least,	 youll
	 need bash, git, make.

        For	64-bit	  builds    youll    need   mingw-w64-x86_64-gcc   and
	 mingw-w64-x86_64-python.

        For	32-bit	  builds    youll    need    mingw-w64-i686-gcc	   and
	 mingw-w64-i686-python.

        For debugging you may want to install gdb.

        To  link  using  the  LLVM linker (generally much faster than the GNU
	 linker), youll	need mingw-w64-x86_64-lld and  mingw-w64-x86_64-libc++
	 for  64-bit  builds,  or mingw-w64-i686-lld and mingw-w64-i686-libc++
	 for 32-bit builds.

        To  build  against  the   portable   SDL   interfaces,	  youll	  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, youll need mingw-w64-x86_64-qt5 for	64-bit
	 builds, or mingw-w64-i686-qt5 for 32-bit builds.

        To   build   the   HTML   user/developer  documentation,  youll  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,   youll   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-but MinGW  environ-
	 ment).

        To generate API documentation from source, youll need doxygen.

        If  you plan to rebuild bgfx shaders and you want to rebuild the GLSL
	 parser, youll need bison.

        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).

       For example you could use these commands	to ensure you have  the	 pack-
       ages you	need to	compile	MAME, omitting the ones	for configurations you
       dont 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-libc++ mingw-w64-x86_64-lld mingw-w64-x86_64-python
	  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-libc++ mingw-w64-i686-lld	mingw-w64-i686-python
	  pacman -S mingw-w64-i686-SDL2	mingw-w64-i686-SDL2_ttf
	  pacman -S mingw-w64-i686-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 2022 projects using make vs2022.  The
	 solution and project files will  be  created  in  build/projects/win-
	 dows/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 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;  please  refer  to
	 the  Microsoft-provided  instructions	on  using  the	Microsoft  C++
	 toolset from the command line.	 You may find it easier	to not use MS-
	 BUILD=1 and load the project file into	Visual Studios GUI for	compi-
	 lation.

        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 with helpful information	on us-
       ing 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 and/or /mingw32/bin (relative to the	MSYS2 installation di-
       rectory).   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 dont	work in	inter-
       active 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
       wont 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 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	doesnt provide a useful	exit status,  so  file
       copy tasks can fail silently.

       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 is not possible to link
       a  full	32-bit MAME build including the	SDL OS-dependent layer and the
       Qt debugger.  GNU ld and	lld will both run out of  memory,  leaving  an
       output  file  that  doesnt  work.  Its also 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.

   Fedora Linux
       Youll 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

       If you want to use the more efficient LLVM tools	for  archiving	static
       libraries  and  linking,	 youll need to install the corresponding pack-
       ages:

	  sudo dnf install lld llvm

       Compilation is exactly as described above in All	Platforms.

       To build	the HTML user/developer	documentation, youll 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

   Debian and Ubuntu (including	Raspberry Pi and ODROID	devices)
       Youll 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 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.  Note the
       Ubuntu Linux modifies GCC to enable the GNU C  Library  fortify	source
       feature	by  default,  which may	cause issues compiling MAME (see Known
       Issues).

   Arch	Linux
       Youll need a few	prerequisites from your	distro:

	  sudo pacman -S base-devel git	sdl2_ttf python	libxinerama libpulse alsa-lib qt5-base

       Compilation is exactly as described above in All	Platforms.

   Apple macOS
       Youll need a few	prerequisites to get started.  Make sure youre on  ma-
       cOS  11.0  Big  Sur  or	later.	 You will need SDL 2 version 2.0.14 or
       later.  Youll also need to install Python  3   its  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 (AppleID required).

        To find the corresponding Xcode for your MacOS	release	 please	 visit
	 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 thats 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 youll need to get SDL 2 installed.

        Go to this site and download the macOS	.dmg file

        If the	.dmg doesnt open automatically,	open it

        Click	Macintosh HD (or whatever your Macs 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.

       If you dont already have	it, get	Python 3 set up:

        Go  to	 the official Python site, navigate to the releases for	macOS,
	 and click the link to download	the installer for  the	latest	stable
	 release (this was Python 3.10.4 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 installa-
	 tion process.

       Finally to begin	compiling, use Terminal	to navigate to where you  have
       the MAME	source tree (cd	command) and follow the	normal compilation in-
       structions from above in	All Platforms.

   Emscripten Javascript and HTML
       First, download and install Emscripten 2.0.25 or	later by following the
       instructions at the official site.

       Once  Emscripten	 has  been installed, it should	be possible to compile
       MAME out-of-the-box using Emscriptens 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):

	  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	depen-
       dencies	necessary  to produce a	complete build including the specified
       driver(s).  However, sometimes it is necessary to manually specify  ad-
       ditional	files (using commas) if	this process misses something. e.g.

	  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 mul-
       tiple 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 WEBASSEM-
       BLY=0 to	the make command line, respectively.

       Other make parameters can also be used, e.g. -j for multithreaded  com-
       pilation	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  sym-
       bols.   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 pro-
       vide it with a canvas to	draw to	and to pass  in	 command-line  parame-
       ters.  The Emularity project 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 parame-
       ters  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

       You need	to use a web server instead of opening	the  local  files  di-
       rectly due to security restrictions in modern web browsers.

       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.

   Compiling the Documentation
       Compiling  the  documentation will require you to install several pack-
       ages depending on your operating	system.

   Compiling the Documentation on Microsoft Windows
       On Windows, youll need a	couple of packages from	the MSYS2 environment.
       You can install these packages with

	  pacman -S mingw-w64-x86_64-librsvg mingw-w64-x86_64-python-sphinx mingw-w64-x86_64-python-sphinxcontrib-svg2pdfconverter

       If you intend to	make a PDF via LaTeX, youll need to  install  a	 LaTeX
       distribution such as TeX	Live:

	  pacman -S mingw-w64-x86_64-texlive-fonts-recommended mingw-w64-x86_64-texlive-latex-extra

   Compiling the Documentation on Debian and Ubuntu
       On      Debian/Ubuntu	  flavors     of     Linux,	youll	  need
       python3-sphinx/python-sphinx and	the python3-pip/python-pip packages:

	  sudo apt-get install python3-sphinx python3-pip
	  pip3 install sphinxcontrib-svg2pdfconverter

       On Debian, youll	need to	install	the librsvg2-bin package:

	  sudo apt-get install librsvg2-bin

       If you intend to	make a PDF via LaTeX, youll need to  install  a	 LaTeX
       distribution such as TeX	Live:

	  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.)

   Useful Options
       This  section  summarises some of the more useful options recognised by
       the main	makefile.  You use these options by appending them to the make
       command,	setting	them as	environment variables, or adding them to  your
       prefix  makefile.   Note	 that in order to apply	many of	these settings
       when rebuilding,	you need to set	REGENIE=1 the first time you build af-
       ter changing the	option(s).  Also note that GENie  does	not  automati-
       cally  rebuild  affected	 files	when you change	an option that affects
       compiler	settings.

   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.

       BUILDDIR
	      Set to change the	name of	the subfolder used for project	files,
	      generated	sources, object	files, and intermediate	libraries (de-
	      faults to	build).

       REGENIE
	      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  regener-
	      ate 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.

   Tool	locations
       OVERRIDE_CC
	      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 tar-
	      get 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-compil-
	      ing.)

       PYTHON_EXECUTABLE
	      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++ com-
	      piler  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 sys-
	      tem 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  conjunc-
	      tion  with  the  SUBTARGET  option.  The filter file can specify
	      source files to include system drivers from, and individual sys-
	      tem drivers to include or	exclude.  There	are some example  sys-
	      tem driver filter	files in the src/mame folder.

   Optional features
       TOOLS  Set  to 1	to build additional tools along	with the emulator, in-
	      cluding 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
	      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 Way-
	      land 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 net-
	      work 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 dis-
	      able 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 its not
	      built by default (e.g. Windows or	macOS),	or to 0	to disable it.
	      Youll 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.

       DEPRECATED
	      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 diag-
	      nostics.	 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  optimisa-
	      tion  that doesnt	have a space/speed trade-off and doesnt	have a
	      large impact on compile time, 2 to enable	most optimisation that
	      improves performance and reduces size, or	s to enable only opti-
	      misations	that generally dont increase executable	size.  The ex-
	      act set of supported values depends on your compiler.

       SYMBOLS
	      Set to 1 to include additional debugging symbols	over  the  de-
	      fault  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 in-
	      cludes line number tables	and external  variables,  2  also  in-
	      cludes 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 op-
	      tions, 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.

       ARCHOPTS_CXX
	      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.

       ARCHOPTS_OBJCXX
	      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_FRAMEWORK_PATH
	      Search path for SDL framework.

       USE_LIBSDL
	      Set to 1 to use shared library style SDL on targets where	frame-
	      work is default.

       USE_SYSTEM_LIB_ASIO
	      Set to 1 to prefer the system installation of the	Asio C++ asyn-
	      chronous 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.

       USE_SYSTEM_LIB_ZLIB
	      Set to 1 to prefer the system installation of the	zlib data com-
	      pression 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.

       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.

       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.

       USE_SYSTEM_LIB_SQLITE3
	      Set to 1 to prefer the system installation of the	SQLITE	embed-
	      ded  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  li-
	      brary over the version provided with the MAME source.

       USE_SYSTEM_LIB_PORTAUDIO
	      Set  to 1	to prefer the system installation of the PortAudio li-
	      brary 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.

       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.

       USE_SYSTEM_LIB_RAPIDJSON
	      Set to 1 to prefer the system installation of the	Tencent	Rapid-
	      JSON library over	the version provided with the MAME source.

       USE_SYSTEM_LIB_PUGIXML
	      Set to 1 to prefer the system installation of  the  pugixml  li-
	      brary over the version provided with the MAME source.

   Known Issues
   Issues with specific	compiler versions
        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.

   GNU C Library fortify source	feature
       The  GNU	 C  Library  has  options  to  perform additional compile- and
       run-time	checks on string operations, enabled  by  defining  the	 _FOR-
       TIFY_SOURCE  preprocessor  macro.  This is intended to improve security
       at the cost of a	small amount of	overhead.  MAME	is  not	 secure	 soft-
       ware, and we do not 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 problem-
       atic for	more projects than just	MAME, as it makes it hard  to  disable
       the  additional checks (e.g. if you dont	want the performance impact of
       the run-time checks), and  it  also  makes  it  hard  to	 define	 _FOR-
       TIFY_SOURCE to 2	if you want to enable stricter checks.	You should re-
       ally  take  it  up with the distribution	maintainers, and make it clear
       you dont	want non-standard GCC behaviour. It would be better  if	 these
       distributions defined this macro	by default in their packaging environ-
       ments  if  they	think its 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.)

       If  you	get  compilation  errors in bits/string_fortified.h you	should
       first ensure that the _FORTIY_SOURCE macro is defined via the  environ-
       ment  (e.g.  a CFLAGS or	CXXFLAGS environment variable).	 You can check
       to see whether the _FORTIFY_SOURCE macro	is a built-in macro with  your
       version of GCC with a command like this:

       gcc -dM -E - < /dev/null	| grep _FORTIFY_SOURCE

       If  _FORTIFY_SOURCE  is defined to a non-zero value by default, you can
       work around it by adding	-U_FORTIFY_SOURCE to the compiler flags	 (e.g.
       by using	the ARCHOPTS setting, or setting the CFLAGS and	CXXFLAGS envi-
       ronment variables.

   Issues affecting Microsoft Visual Studio
       Microsoft  introduced a new version of XAudio2 with Windows 8 thats in-
       compatible 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 de-
       fault, 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 (already included since Windows 8.0  SDK  and
	 automatically	installed with Visual Studio 2013 and later).  Config-
	 ure 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	unini-
       tialised	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.)

   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
       MAMEs build  system  has	 basic	support	 for  cross-compilation.   Set
       CROSS_BUILD=1  to  enable separate host and target compilers, set OVER-
       RIDE_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 exam-
       ple it may be possible to build a MinGW32 x64 build on a	Linux host us-
       ing a command 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**

       (The additional packages	required for producing a standard MinGW32  x64
       build	 on    a    Fedora    Linux    host    are    mingw64-gcc-c++,
       mingw64-winpthreads-static and their dependencies.  Non-standard	builds
       may require additional packages.)

   Using libc++	on Linux
       MAME may	be built using the LLVM	projects 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++  com-
       piler 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++

       The  options following the make command may be placed in	a prefix make-
       file if you want	to use this configuration regularly, but LDFLAGS needs
       to be be	set in the environment.

   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  sup-
       plying the --prefix= option to the configure command.  This may be use-
       ful if you want to build	MAME on	a Linux	distribution that still	uses a
       version of GNU libstdC++	that predates C++17 support.  To use an	alter-
       nate  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/gcc72,
       you might use a command like this:

	  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.

   Configuring MAME
        Getting Started: A Quick Preface

        Initial Setup:	Creating mame.ini From Command Line on Windows

        Initial Setup:	Creating mame.ini From Command Line on Linux or	MacOS

        Initial Setup:	Graphical Setup

   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\Pub-
       lic\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 edi-
       tor, 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 set-
       tings.  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.

BASIC MAME USAGE AND CONFIGURATION
       This  section describes general usage information about MAME. It	is in-
       tended 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.

   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 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  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 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 con-
       tent is as easy as
	  mame.exe <system> <software>

       For instance:
	  mame.exe nes metroidu

       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 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-software	list  content,
       things are only a little	more complicated:

       The basic usage,	from command line, is
	  mame.exe <system> <media> <software> <options>

       where

        <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  car-
	 tridge,  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 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

       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 sec-
       tion of this manual. You	can also try one of the	many Front-ends	avail-
       able for	MAME.

       Alternatively, you should keep in mind the following command  line  op-
       tions, which might be very useful on occasion:
	  mame.exe -help

       gives  a	 basic	summary	of command line	options	for MAME, as explained
       above.
	  mame.exe -showusage

       gives you the (quite long) list of available command line  options  for
       MAME.   The  main  options are described, in the	Universal Command-line
       Options section of this manual.
	  mame.exe -showconfig

       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
       Universal  Command-line	Options	 section of the	manual (in most	cases,
       each configuration option has a corresponding command  line  option  to
       configure and modify it).
	  mame.exe -createconfig

       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	 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	adjust
       the configuration of your setup a bit more. In this case, keep in  mind
       the  order  in  which options are read; see Order of Config Loading for
       details.

   MAMEs User Interface
        Introduction

        Navigating menus

	  Using a game	controller

	  Using a mouse or trackball

	  Using a touch screen

        Configuring inputs

	  Digital input settings

	  Analog input	settings

        The system and	software selection menus

	  Navigation controls

        The simple system selection menu

   Introduction
       MAME provides a simple user interface  for  selecting  the  system  and
       software	to run and changing settings while running an emulated system.
       MAMEs  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  run-
       ning  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 ui_active	option 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
	      external front-end).

   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 emu-
	      lated system in the case of the main  menu  (theres  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).

   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 de-
       fault:

        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 set-
	 tings.

        Press the first button	on the first  joystick	to  select  the	 high-
	 lighted 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 pre-
	 vious menu, or	returning to the emulated system in the	 case  of  the
	 main  menu  (theres usually an	item at	the bottom of the menu for the
	 same purpose).

       For gamepad-style controllers, the left analog thumb stick  and	direc-
       tional pad usually control UI navigation.  Depending on the controller,
       the right analog	thumb stick, triggers and additional buttons may auto-
       matically be assigned to	UI inputs.  Check the User Interface input as-
       signments menu to see how controls are assigned.

       If you want to be able to use MAME with a game controller without need-
       ing  a keyboard,	youll 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 isnt essential for basic emulation, but its 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 youre	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

   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  de-
	 scription.

       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.

   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 enable_touch option must be  switched
       on to use touch screen support.

   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 dig-
       ital  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  MAMEs 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  se-
       lect Input Assignments from the General Settings	menu.  From there, se-
       lect a category.

       To  assign  inputs  for the currently running system, select Input Set-
       tings from the main menu	during emulation and then select Input Assign-
       ments (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 con-
       trols) 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).

   Digital input settings
       Each emulated digital input has a single	assignment setting.  For flex-
       ibility,	 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 acti-
	      vates the	emulated input or user interface control.

       Kbd Down	or Joy 1 Down
	      Pressing the down	arrow on the keyboard or moving	the first joy-
	      stick down activates the emulated	input or user  interface  con-
	      trol.

       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  con-
	      trol.  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  ap-
       pend  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 en-
       ter 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 acti-
	 vating	an input to accept the new setting.

       Heres 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  ac-
	      cept 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.

   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 con-
	 trols)	to increase the	value of the emulated analog input.   The  in-
	 crement  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 in-
	 crease	the emulated input value at a proportional speed.

        Use the decrement setting assign a control (or	 combination  of  con-
	 trols)	 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 de-
	 crease	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 (see	above).	 Its important
       that you	dont 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 Racers  Steering	 Wheel
       Analog  setting	to  the	 X  axis of the	left analog stick on your con-
       troller,	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  emu-
       lated  analog  input.   When multiple axes are assigned to an axis set-
       ting, 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  por-
       tion  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	 posi-
       tion (the half axis indicated by	a minus	sign).

       When  keys  or buttons are assigned to an axis setting, they condition-
       ally 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,  as-
       suming 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 in-
       put:

        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  ab-
	 solute	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 rela-
	 tive position control,	move the same control again to toggle  revers-
	 ing 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	opera-
	 tion.

        Pressing UI Cancel (Escape by default)	leaves the setting unchanged.

        The  new setting is shown below the menu.  Wait one second after mov-
	 ing 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	emula-
       tion,  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	incre-
	 ment/decrement	 settings  are	released.  Setting it to zero (0) will
	 result	in the value not automatically returning to the	neutral	 posi-
	 tion.

        The  reverse  setting allows the direction of the emulated inputs re-
	 sponse	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 values response to the con-
	 trol assigned to the axis setting.

       Use the UI left/right keys or buttons to	adjust	the  highlighted  set-
       ting.  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.

   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 ui option 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 cir-
	 cle), 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	selec-
	 tion 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 Set-
	 tings menu for	the system.

	 Systems or software items are sorted by  full	name  or  description,
	 keeping clones	immediately below their	parents.  This may appear con-
	 fusing	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  de-
	 pending  on the emulation status: green for working, amber for	imper-
	 fectly	emulated features or known issues, or red for more serious is-
	 sues.

	 A yellow star is show at the top left of the info panel if the	 high-
	 lighted 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 Cate-
	 gory filter).

	 Click Unfiltered to display all items.	 Click Custom Filter  to  com-
	 bine  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	infor-
	 mation	from the software list is shown	 for  software	items.	 Addi-
	 tional	 information  from  external files can be shown	using the Data
	 plugin.

       You can type to search the displayed list of systems or software.  Sys-
       tems 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  descrip-
       tion, 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.

   Navigation controls
       In addition to the usual	menu navigation	controls, the system and soft-
       ware selection menus have additional configurable controls for navigat-
       ing  the	 multi-pane layout, and	providing alternatives to toolbar but-
       tons if you dont	want to	use a pointing device.	The default additional
       controls	(with a	US ANSI	QWERTY keyboard), and the settings they	corre-
       spond 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 con-
       trols (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.

   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
       ui  option  set	to  simple,  the  simple system	selection menu will be
       shown.  The simple system selection menu	 shows	fifteen	 randomly  se-
       lected  systems	that  have  ROM	 sets  present	in your	configured ROM
       folder(s).  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 high-
       lighted	system.	 The background	colour changes depending on the	emula-
       tion status: green for working, amber for imperfectly emulated features
       or known	issues,	or red for more	serious	issues.

   Default Keyboard Controls
        Controls Foreword

        MAME User Interface Controls

	  System and software selection menus

        Default Arcade	Machine	Controls

        Default Arcade	Game Controls

	  Player 1 Controls

	  Player 2 Controls

	  Player 3 Controls

	  Player 4 Controls

        Default Mahjong and Hanafuda Keys

        Default Gambling Keys

	  Default Blackjack Keys

	  Default Poker Keys

	  Default Slots Keys

        Default Computer Keys

        Other Machines

   Controls Foreword
       MAME supports a vast array of different types of	machines, with a  sig-
       nificantly  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 youre 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 position-
       ing. If you are using a different layout, the keys will vary.

   MAME	User Interface Controls
       The  controls  here  cover  MAME	functions such as MAMEs	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	emula-
	      tion.

	      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  but-
	      ton behavior.

       F2     Power the	machine	off for	machines that have specific power but-
	      ton behavior.

       F3     Soft resets the machine.

       Left Shift+F3
	      Performs	a  hard	reset, which tears everything down and re-cre-
	      ates 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 per-
	      fectly, 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 MAMEs response	to user	interface keys such as
	      the (by default) Tab key being used for menus. All emulated  ma-
	      chines  which require emulated keyboards will start with UI con-
	      trols disabled by	default	and you	can only access	 the  internal
	      UI  by first hitting this	uimodekey key. You can change the ini-
	      tial status of the emulated keyboard as presented	upon start  by
	      using -uimodekey

       Escape Exit  emulator,  return to the previous menu, or cancel the cur-
	      rent UI option.

   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 se-
	      lected  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 Machine Controls
       This  section  covers controls that are applicable to most kinds	of ar-
       cade machines.  Note that not all machines will have all	of these  con-
       trols.	All  the controls below	are fully configurable in the user in-
       terface.	 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  pin-
	      ball 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 Arcade Game Controls
       This section  covers  controls  for  arcade  games  using  common  joy-
       stick/button control schemes.  All the controls below are fully config-
       urable  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

   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.	Robot-
	      ron)

       D      Player 1 Down on Left Stick for dual-stick machines (e.g.	Robot-
	      ron)

       S      Player 1 Left on Left Stick for dual-stick machines (e.g.	Robot-
	      ron)

       F      Player  1	 Right on Left Stick for dual-stick machines (e.g. Ro-
	      botron)

       I      Player 1 Up on Right Stick for dual-stick	machines (e.g.	Robot-
	      ron)

       K      Player  1	 Down on Right Stick for dual-stick machines (e.g. Ro-
	      botron)

       J      Player 1 Left on Right Stick for dual-stick machines  (e.g.  Ro-
	      botron)

       L      Player  1	Right on Right Stick for dual-stick machines (e.g. Ro-
	      botron)

       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

   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

   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

   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 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 exam-
       ple  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: Standard	mahjong	control	panel layout] [image]

       Due  to the large number	of keys, MAME only provides default input con-
       figuration 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
       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, lack-
       ing 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 cred-
	      its or to	navigate the internal operator service menus)

       0 (not numeric keypad)
	      Service  2 Book-Keeping (for machines that have this functional-
	      ity)

       - (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
       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 dont	use separate buttons to	deal a new hand	 and  draw  an
	      additional card.

       L      Stand

   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 dont	use separate buttons to	deal a new hand	and  draw  re-
	      placement	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
       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
       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
       MAMEs 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 MAMEs response to user interface	keys  such  as
	      the  (by default)	Tab key	being used for menus. All emulated ma-
	      chines which require emulated keyboards will start with UI  con-
	      trols  disabled  by default and you can only access the internal
	      UI by first hitting this uimodekey key. You can change the  ini-
	      tial  status of the emulated keyboard as presented upon start by
	      using -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  ma-
	      chine by default.

   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 manu-
       facturer	and style. See the Input Assignments (this system) section  of
       MAMEs Input Settings menu for details for the machine you are currently
       using.

   MAME	Menus
        Introduction

        Main menu

        Input Settings	menu

        Toggle	Inputs menu

        Keyboard Selection menu

        Input Devices menu

   Introduction
       To  show	 the main menu 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 Con-
       trols key or button (Scroll Lock, or Forward Delete on  macOS,  by  de-
       fault) 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  but-
       ton 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 ui option 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, see the relevant section.

   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 be-
       fore the	emulated system	starts.

       Input Settings
	      Shows the	Input Settings 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 cas-
	      sette 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  ter-
	      minals,  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 con-
	      tains.  This item	is not shown if	no BIOS	options	are available.

       Slot Devices
	      Shows the	Slot Devices menu, where you can choose	 between  emu-
	      lated 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.

       Slider Controls
	      Shows the	Slider Controls	menu, where  you  can  adjust  various
	      settings,	including video	adjustments and	individual sound chan-
	      nel 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  ap-
	      pearance	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 plugins menu is accessed via the Plugin  Op-
	      tions 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 en-
	      abled, or	if the main menu is shown before the  emulated	system
	      starts (by pressing the Show/Hide	Menu key/button	while the sys-
	      tem 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
	      data  plugin 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
	      its  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	press-
	      ing  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).

   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 main	menu.  The items shown on this
       menu depend on  available  emulated  inputs  for	 the  running  system.
       Available  emulated inputs may depend on	slot options, machine configu-
       ration settings and DIP switch settings.

       Input Assignments (this system)
	      Lets you select assign controls to emulated inputs for the  run-
	      ning system.  See	the section on configuring inputs for more de-
	      tails.   This item is not	shown if the running system has	no en-
	      abled 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 emu-
	      lated  analog inputs, and	see how	the emulated analog inputs re-
	      spond to controls	with your settings.  For more details, see the
	      analog input settings section for	more details.	This  item  is
	      not shown	if the running system has no enabled analog inputs.

       Keyboard	Selection
	      Shows  the Keyboard Selection menu, where	you can	select between
	      emulated and natural keyboard modes, and enable and disable key-
	      board and	keypad inputs for individual emulated  devices.	  This
	      item  is not shown if the	running	system has no keyboard or key-
	      pad inputs.

       Toggle Inputs
	      Shows the	Toggle Inputs menu, 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  de-
	      fault  controls  for  all	 emulated systems.  See	the section on
	      configuring inputs for more details.

       Input Devices
	      Shows the	Input Devices menu,  which  lists  the	input  devices
	      recognised by MAME.

   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  Input  Settings menu.  Note	that available emulated	inputs may de-
       pend 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 but-
       tons.  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  set-
       ting.

   Keyboard Selection menu
       The  Keyboard Selection menu lets your switch between emulated and nat-
       ural keyboard modes, and	enable or disable keyboard inputs for individ-
       ual emulated devices.  You can reach the	Keyboard Selection menu	by se-
       lecting Keyboard	Selection from the Input Settings menu.

       In emulated keyboard mode, keyboard and keypad inputs behave  like  any
       other  digital  inputs, responding to their assigned controls.  In nat-
       ural keyboard mode, MAME	attempts to translate typed characters to emu-
       lated keystrokes.  The initial keyboard mode is set using  the  natural
       option.

       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 dont produce characters  cant	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/Japan-
	 ese/Korean).

       Each emulated device in the system that has keyboard and/or keypad  in-
       puts  is	 listed	on the menu, allowing keyboard/keypad inputs to	be en-
       abled 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  in-
       puts.   The  enabled  keyboard/keypad inputs are	automatically saved to
       the configuration file for the system when the emulation	session	ends.

   Input Devices menu
       The Input Devices menu lists input devices recognised by	MAME  and  en-
       abled  with  your current settings.  Recognised input devices depend on
       the    keyboardprovider,	   mouseprovider,     lightgunprovider	   and
       joystickprovider	 options.   Classes of input devices can be enabled or
       disabled	using the mouse, lightgun and joystick options.	 You can reach
       the Input Devices menu by selecting Input Devices from the  Input  Set-
       tings menu 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 devices ID to the	 clip-
       board.	This  is  useful  for  setting	up  stable  controller	IDs in
       controller configuration	files.

   How does MAME look for files?
        Introduction

	  Terminology

        Search	path options

        Archive files

        How does MAME search for media?

	  System ROMs

	  Device ROMs

	  Software Item ROMs

	  CHD format disk images

	  Loose software

	  Diagnosing missing media

   Introduction
       Unlike typical desktop applications where you browse your disk and  se-
       lect 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 Op-
       tions from the system selection menu, and then selecting	Configure  Di-
       rectories  (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 Core Search Path	Options.

   Terminology
       Its  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 de-
	      vices 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	selec-
	      tion settings that allow you to select system boot ROMs  or  de-
	      vice 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  (in-
	      cluding floppy disk and cassette media).

       Parent software item
	      Related  software	items are grouped using	parent/clone relation-
	      ships, 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  al-
	      ways 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	 soft-
	      ware  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 show-
	      ing 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 directo-
       ries to be specified, separated by semicolon (;)	characters.   Environ-
       ment  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	direc-
       tory  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 di-
       rectory 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 file-
       names).

       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 in-
       herently	more CPU-intensive to decompress than files  compressed	 using
       simpler algorithms.  MAME does not take the archive layout into consid-
       eration	when  loading  files from archives, so using solid compression
       often results in	MAME decompressing the same data repeatedly when load-
       ing media.

   How does MAME search	for media?
       Use the 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 set-
       ting 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  mem-
       ory  in order to	use it.	 For hard disk or LaserDisc images in particu-
       lar, this will likely use an excessive amount of	swap file space, hurt-
       ing performance and possibly reducing the life expectancy of your disks
       or SSDs.	 Its best to keep CHD format disk images in folders.

   System ROMs
       For each	folder configured in your rompath setting, MAME	looks for sys-
       tem 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  systems	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 sys-
       tem 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  de-
       vice 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 devices 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	systems	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  key-
       board  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 inte-
	 grated	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  in-
	 side  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 soft-
	 ware 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  im-
       ages  in	almost the same	way it searches	for ROMs, with just a few dif-
       ferences:

        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 ex-
	 pected	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 sys-
       tems, 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  in-
       terpreted relative to the current working directory.

       You  can	specify	a path to a file inside	a PKZIP	or 7-Zip archive simi-
       larly 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 sup-
       port 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  its 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:

	  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:

	  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:

	  mame macplus -flop1 "sys603.zip/system tools.img"

   Diagnosing missing media
       When starting a system from MAMEs system	selection menu or software se-
       lection	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 key-
       board microcontroller ROM dump is missing, MAME displays	the  following
       error message:
	  Required  ROM/disk images for	the selected system are	missing	or in-
	  correct.  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 key-
       board 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 gen-
	 esis).

       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.

   Front-ends
       A number	of third party tools for MAME to make system and software  se-
       lection	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 merg-
       ing 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 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)
	      Provides a graphical interface for  configuring  many  of	 MAMEs
	      settings	and  features.	Also includes ROM management and media
	      auditing features.  Written in C++ using	the  Qt	 toolkit,  the
	      source code is on	SourceForge.

       Negatron	(multiple platforms)
	      Negatron	emphasises features for	configuring emulated computers
	      and consoles.  Written in	Java, the source code is on GitHub.

       BletchMAME (multiple platforms)
	      BletchMAME takes advantage of MAMEs Lua scripting	 interface  to
	      integrate	 tightly  and  effectively replace MAMEs internal user
	      interface.  It has many useful features for home computer	emula-
	      tion.  Written in	C++, the source	code is	on GitHub.

       IV/Play (Microsoft Windows)
	      A	simple Windows program for launching systems in	MAME.  Written
	      in C#, the source	code is	on GitHub.

       Emu Loader (Microsoft Windows)
	      Emu Loader provides a Windows interface for launching systems in
	      multiple emulators, including MAME, Supermodel and DEMUL.	 Writ-
	      ten in Delphi Pascal, the	source code is available on the	 down-
	      load page.

       Retrofire (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 front-ends.  For
       support,	we suggest contacting the front-end author or asking on	one of
       the popular MAME-friendly forums	on the Internet.

   About ROMs and Sets
       Handling	and updating of	ROMs and Sets used in  MAME  is	 probably  the
       biggest	area  of  confusion  and  frustration that MAME	users will run
       into. This section aims to clear	up a lot of the	most common  questions
       and cover simple	details	you'll need to know to use MAME	effectively.

       Let's start with	a simple definition of what a ROM is.

   What	is a ROM image?
       For  arcade games, a ROM	image or file is a copy	of all of the data in-
       side a given chip on the	arcade	motherboard.  For  most	 consoles  and
       handhelds,  the individual chips	are frequently (but not	always)	merged
       into a single file. As arcade machines are  much	 more  complicated  in
       their design, you'll typically need the data from a number of different
       chips  on  the  board.  Grouping	all of the files from Puckman together
       will get	you a ROM set of Puckman.

       An example ROM image would be the file pm1_prg1.6e stored in the	 Puck-
       man ROM set.

   Why ROM and not some	other name?
       ROM  stands for Read-Only Memory. The chips used	to store the game data
       were not	rewritable and were permanent (as long as the chip wasn't dam-
       aged or aged to death!)

       As such,	a copy of the data necessary to	 reconstitute  and  replace  a
       dead  data  chip	 on  a board became known as a "ROM image" or ROMs for
       short.

   Parents, Clones, Splitting, and Merging
       As the MAME developers received	their  third  or  fourth  revision  of
       Pac-Man,	 with bugfixes and other code changes, they quickly discovered
       that nearly all of the board and	chips were identical to	the previously
       dumped version. In order	to save	space, MAME was	adjusted to use	a par-
       ent/clone set system.

       A given set, usually (but not necessarily)  the	most  recent  bugfixed
       World  revision	of  a game, will be designated as the parent. All sets
       that use	mostly the same	chips (e.g.  Japanese  Puckman	and  USA/World
       Pac-Man)	 will be clones	that contain only the changed data compared to
       the parent set.

       This typically comes up as an error message to the user when trying  to
       run  a  Clone  set without having the Parent set	handy. Using the above
       example,	trying to play the USA version of Pac-Man without  having  the
       PUCKMAN.ZIP  parent  set	will result in an error	message	that there are
       missing files.

       Now we add the final pieces  of	the  puzzle:  non-merged,  split,  and
       merged sets.

       MAME  is	 extremely  versatile  about  where ROM	data is	located	and is
       quite intelligent about looking for what	it needs. This allows us to do
       some magic with how we store these ROM sets to save further space.

       A non-merged set	is one that contains absolutely	 everything  necessary
       for  a  given  game  to	run  in	 one ZIP file. This is ordinarily very
       space-inefficient, but is a good	way to go if you want to have very few
       sets and	want everything	self-contained and easy	to work	 with.	We  do
       not recommend this for most users.

       A split set is one where	the parent set contains	all of the normal data
       it should, and the clone	sets contain only what has changed as compared
       to  the parent set. This	saves some space, but isn't quite as efficient
       as

       A merged	set takes the parent set and one or more clone sets  and  puts
       them  all  inside the parent set's storage. For instance, if we combine
       the Puckman sets, Midway	Pac-Man	(USA) sets, and	various	other  related
       official	 and  bootleg sets all into PUCKMAN.ZIP, the result would be a
       merged set. A complete merged set with the parent and all  clones  uses
       less disk space than a split set.

       With those basic	principles, there are two other	kinds of set that will
       come up in MAME use from	time to	time.

       First,  the  BIOS  set:	Some  arcade machines shared a common hardware
       platform, such as the Neo-Geo arcade hardware. As the  main  board  had
       data necessary to start up and self-test	the hardware before passing it
       off  to	the  game cartridge, it's not really appropriate to store that
       data as part of the game	ROM sets. Instead, it is stored	as a BIOS  im-
       age for the system itself (e.g. NEOGEO.ZIP for Neo-Geo games)

       Secondly,  the  device  set.  Frequently	the arcade manufacturers would
       reuse pieces of their designs multiple times in order to	save on	 costs
       and time. Some of these smaller circuits	would reappear in later	boards
       that  had  minimal common ground	with the previous boards that used the
       circuit,	so you couldn't	just have  them	 share	the  circuit/ROM  data
       through	a normal parent/clone relationship. Instead, these re-used de-
       signs and ROM data are categorized as a Device, with the	data stored as
       a Device	set. For instance, Namco used the Namco	51xx custom  I/O  chip
       to handle the joystick and DIP switches for Galaga and other games, and
       as  such	 you'll	 also  need  the NAMCO51.ZIP device set	as well	as any
       needed for the game.

   Troubleshooting your	ROM sets and the history of ROMs
       A lot of	the frustration	users feel towards MAME	can be	directly  tied
       to  what	may feel like pointless	ROM changes that seem to only serve to
       make life more difficult	for end-users.	Understanding  the  source  of
       these  changes  and why they are	necessary will help you	to avoid being
       blindsided by change and	to know	what you need to do to keep your  sets
       running.

       A  large	 chunk	of  arcade ROMs	and sets existed before	emulation did.
       These early sets	were created by	arcade owners and used to repair  bro-
       ken  boards by replacing	damaged	chips. Unfortunately, these sets even-
       tually proved to	be missing critical information.  Many	of  the	 early
       dumps  missed  a	 new  type of chip that	contained, for instance, color
       palette information for the screen. The earliest	emulators approximated
       colors until the	authors	discovered  the	 existence  of	these  missing
       chips.  This resulted in	a need to go back and get the missing data and
       update the sets to add the new dumps as needed.

       It wouldn't be much longer before it would be discovered	that  many  of
       the existing sets had bad data for one or more chips. These, too, would
       need to be re-dumped, and many sets would need complete overhauls.

       Occasionally  games  would be discovered	to be completely wrongly docu-
       mented. Some games thought to be	 legitimate  ended  up	being  bootleg
       copies  from  pirate  manufacturers.  Some games	thought	to be bootlegs
       ended up	being legit. Some games	were completely	mistaken as  to	 which
       region  the  board  was actually	from (e.g. World as compared to	Japan)
       and this	too would require adjustments and renaming.

       Even now, occasional miracle finds occur	that change our	 understanding
       of  these games.	As accurate documentation is critical to detailing the
       history of the arcades, MAME will change	sets as	needed to keep	things
       as  accurate as possible	within what the	team knows at the time of each
       release.

       This results in very spotty compatibility for ROM sets  designated  for
       older  versions	of  MAME.  Some	games may not have changed much	within
       20-30 revisions of MAME,	and others may have drastically	changed	multi-
       ple times.

       If you hit problems with	a set not working, there are several things to
       check-- are you trying to run a set meant for an	older version of MAME?
       Do you have any necessary BIOS or Device	ROMs? Is this a	Clone set that
       would need to have the Parent as	well? MAME will	tell  you  what	 files
       are missing as well as where it looked for these	files. Use that	to de-
       termine which set(s) may	be missing files.

   ROMs	and CHDs
       ROM  chip  data tends to	be relatively small and	are loaded into	system
       memory in their entirety.  Some games also used additional storage  me-
       dia  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 wont 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 specifi-
       cally  around the needs of mass storage media.  Some arcade games, con-
       soles, 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 al-
       lows large space	savings	when different variants	share a	lot  of	 data.
       Delta CHD files can only	be used	for clone systems, devices with	a par-
       ent  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  par-
       ent  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.

   Common Issues and Questions (FAQ)
       Disclaimer:  The	 following information is not legal advice and was not
       written by a lawyer.

       1.  Why does my game show an error screen if I insert coins rapidly?

       2.  Why is my non-official MAME package (e.g. EmuCR build) broken?  Why
	   is my official update broken?

       3.  Why does MAME support console games and dumb	terminals? Wouldn't it
	   be  faster if MAME had just the arcade games? Wouldn't it take less
	   RAM?	Wouldn't MAME be faster	if you just X?

       4.  Why do my Neo Geo ROMs no longer work? How do I get the Humble Bun-
	   dle Neo Geo sets working?

       5.  How can I use the Sega Genesis &  Mega  Drive  Classics  collection
	   from	Steam with MAME?

       6.  Why does MAME report	"missing files"	even if	I have the ROMs?

       7.  How can I be	sure I have the	right ROMs?

       8.  Why is it that some games have the US version as the	main set, some
	   have	Japanese, and some are the World?

       9.  How do I legally obtain ROMs	or disk	images to run on MAME?

       10. Isn't copying ROMs a	legal gray area?

       11. Can't game ROMs be considered abandonware?

       12. I  had  ROMs	 that  worked with an old version of MAME and now they
	   don't. What happened?

       13. What	about those arcade cabinets on eBay that  come	with  all  the
	   ROMs?

       14. What	 about	those  guys who	burn DVDs of ROMs for the price	of the
	   media?

       15. But isn't there a special DMCA exemption that makes ROM copying le-
	   gal?

       16. But isn't it	OK to download and "try" ROMs for 24 hours?

       17. If I	buy a cabinet with legitimate ROMs, can	I set it up in a  pub-
	   lic place to	make money?

       18. But I've seen Ultracade and Global VR Classics cabinets out in pub-
	   lic places? Why can they do it?

       19. HELP!  I'm getting a	black screen or	an error message in regards to
	   DirectX on Windows!

       20. I have a controller that doesn't want to work with the standard Mi-
	   crosoft Windows version of MAME, what can I do?

       21. What	happened to the	MAME support for external OPL2-carrying	sound-
	   cards?

       22. What	happened to the	MAME support for autofire?

       23. Does	MAME support G-Sync or FreeSync? How do	I  configure  MAME  to
	   use them?

   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 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 wont trig-
       ger this.

   Why	is  my	non-official MAME package (e.g.	EmuCR build) broken? Why is my
       official	update broken?
       Many MAME features, such	as software lists, HLSL	or BGFX	 shaders,  Lua
       plugins and UI translations, use	external files.	 Updates to these fea-
       tures  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 MAME,	all we
       really can do is	recommend  against  obtaining  MAME  from  sites  like
       EmuCR.	We cannot provide any support for packages we didnt build our-
       selves.	You can	completely avoid these issues by compiling MAME	 your-
       self, or	using an official package we provide.

       You  may	 also encounter	this problem if	you do not update the contents
       of the hlsl, bgfx or plugins folders when updating your MAME  installa-
       tion with a new official	build.

   Why	does  MAME  support  console  games and	dumb terminals?	Wouldn't it be
       faster if MAME had just the arcade games? Wouldn't it  take  less  RAM?
       Wouldn't	MAME be	faster if you just X?
       This  is	 a  common  misconception.  The	 actual	 size of the MAME file
       doesn't affect the speed	of it; only the	parts that are actively	 being
       used are	in memory at any given time.

       In truth, the additional	supported devices are a	good thing for MAME as
       they  allow  us	to  stress  test sections of the various CPU cores and
       other parts of the emulation that don't normally	see heavy utilization.
       While a computer	and an arcade machine may use the exact	same CPU,  how
       they use	that CPU can differ pretty dramatically.

       No  part	 of  MAME  is  a second-class citizen to any other part. Video
       poker machines are just as important to document	and preserve as	arcade
       games.

       There's still room for improvements in MAME's speed,  but  chances  are
       that if you're not already a skilled programmer any ideas you have will
       have already been covered. Don't	let that discourage you-- MAME is open
       source, and improvements	are always welcome.

   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  Uni-
       verse  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  cor-
       rect  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.

       We suggest you contact the provider of your  sets  (Humble  Bundle  and
       DotEmu) and ask them to update their content to the newest revision. If
       enough people ask nicely, maybe they'll update the package.

   How	can I use the Sega Genesis & Mega Drive	Classics collection from Steam
       with MAME?
       As of the April 2016 update to the program, the ROM images included  in
       the  set	are now	100% compatible	with MAME and other Genesis/Mega Drive
       emulators. The ROMs are contained in the	steamapps\Sega Classics\uncom-
       pressed ROMs folder as a	series of .68K and .SGD	 images	 that  can  be
       loaded  directly	 into  MAME. PDF manuals for the games can be found in
       steamapps\Sega Classics\manuals as well.

   Why does MAME report	"missing files"	even if	I have the ROMs?
       There can be several reasons for	this:

        It is not unusual for the ROMs	to change for a	game between  releases
	 of  MAME.  Why	would this happen? Oftentimes, better or more complete
	 ROM dumps are made, or	errors are found in the	way the	ROMs were pre-
	 viously defined. Early	versions of MAME were not as meticulous	 about
	 this  issue, but more recent MAME builds are. Additionally, there can
	 be more features of a game emulated in	a later	release	of  MAME  than
	 an earlier release, requiring more ROM	code to	run.

        You  may find that some games require CHD files. A CHD	file is	a com-
	 pressed representation	of a game's hard disk, CD-ROM,	or  laserdisc,
	 and  is  generally not	included as part of a game's ROMs. However, in
	 most cases, these files are required to run the game, and  MAME  will
	 complain if they cannot be found.

        Some  games such as Neo-Geo, Playchoice-10, Convertible Video System,
	 Deco Cassette,	MegaTech, MegaPlay, ST-V Titan,	and others need	 their
	 BIOS  ROMs  in	addition to the	game ROMs. The BIOS ROMs often contain
	 ROM code that is used for booting the machine,	menu processor code on
	 multi-game systems, and code common to	all games on  a	 system.  BIOS
	 ROMS must be named correctly and left zipped inside your ROMs folder.

        Older	versions of MAME needed	decryption tables in order for MAME to
	 emulate Capcom	Play System 2 (a.k.a. CPS2) games. These  are  created
	 by team CPS2Shock.

        Some  games  in MAME are considered "Clones" of another game. This is
	 often the case	when the game in question is simply an alternate  ver-
	 sion  of  the	same  game. Common alternate versions of games include
	 versions with text in other languages,	versions with different	 copy-
	 right dates, later versions or	updates, bootlegs, etc.	"Cloned" games
	 often	overlap	 some of the ROM code as the original or "parent" ver-
	 sion of the game. To see if you have any "clones" type	 "MAME	-list-
	 clones".  To  run a "cloned game" you simply need to place its	parent
	 ROM file in your ROMs folder (leave it	zipped).

   How can I be	sure I have the	right ROMs?
       MAME checks to be sure you have the right ROMs before emulation begins.
       If you see any error messages, your ROMs	are not	those tested  to  work
       properly	 with  MAME.  You  will	 need  to obtain a correct set of ROMs
       through legal methods.

       If you have several games and you wish to verify	that they are compati-
       ble with	the current version of MAME, you can use the -verifyroms para-
       meter. For example:

       mame -verifyroms	robby ...checks	your ROMs for the game Robby Roto  and
       displays	the results on the screen.

       mame  -verifyroms  * >verify.txt	...checks the validity of ALL the ROMs
       in your ROMS directory, and writes the results  to  a  textfile	called
       verify.txt.

   Why	is  it	that some games	have the US version as the main	set, some have
       Japanese, and some are the World?
       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:

        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 li-
	 censees

        Prefer	releases without region-specific notices or warnings

       Its not always possible to choose a set thats  preferred	 according  to
       all criteria.

       As an example, the World	release	of Ghoulsn Ghosts (ghouls) is the par-
       ent 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.

   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-commercial use.

        You  can  purchase an actual arcade PCB, read the ROMs	or disks your-
	 self, and let MAME use	that data.

       Beyond these options, you are on	your own.

   Isn't copying ROMs a	legal gray area?
       No, its not.  You are not permitted to make copies of software  without
       the copyright owners permission.	 This is a black and white issue.

   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.

   I had ROMs that worked with an old version of MAME and now they don't. What
       happened?
       As time passes, MAME is perfecting the emulation	of older  games,  even
       when  the  results  aren't immediately obvious to the user. Often times
       the better emulation requires more data from the	original game to oper-
       ate. Sometimes the data was overlooked, sometimes it simply wasn't fea-
       sible to	get at it (for instance, chip "decapping" is a technique  that
       only became affordable very recently for	people not working in high-end
       laboratories).  In  other  cases	it's much simpler: more	sets of	a game
       were dumped and it was decided to change	which sets were	which version.

   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
       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  in-
       clude a version of MAME that runs those ROMs and	nothing	more.

   What	about those guys who burn DVDs of ROMs for the price of	the media?
       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 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.

   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  making  unauthorised
       copies  of  computer  programs, which is	what you are doing if you make
       copies of ROMs.

   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 made ROMs	avail-
       able 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.

   If I	buy a cabinet with legitimate ROMs, can	I set it up in a public	 place
       to make money?
       Probably	 not.  ROMs are	typically only licensed	for personal, non-com-
       mercial purposes.

   But I've seen Ultracade and Global  VR  Classics  cabinets  out  in	public
       places? Why can they do it?
       Ultracade had two separate products. The	Ultracade product is a commer-
       cial machine with commercial licenses to	the games. These machines were
       designed	 to be put on location and make	money, like traditional	arcade
       machines. Their other product is	the Arcade Legends series.  These  are
       home machines with non- commercial licenses for the games, and can only
       be  legally  operated  in  a private environment. Since their buyout by
       Global VR they only offer the Global  VR	 Classics  cabinet,  which  is
       equivalent to the earlier Ultracade product.

   HELP!  I'm getting a	black screen or	an error message in regards to DirectX
       on Windows!
       You probably have missing or damaged DirectX runtimes. You can download
       the    latest	DirectX	   setup    tool     from     Microsoft	    at
       https://www.microsoft.com/en-us/download/details.aspx?displaylang=en&id=35

       Additional troubleshooting information can be found on Microsoft's web-
       site at https://support.microsoft.com/en-us/kb/179113

   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  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	 inde-
       pendently.  However, some device	drivers	are not	compatible with	RawIn-
       put, and	it may be necessary to use DirectInput or window events	to re-
       ceive  input.   This  is	also the case for most software	that simulates
       mouse or	keyboard input,	like JoyToKey, VNC or Remote Desktop.

       You   can   try	 changing   the	   keyboardprovider,	mouseprovider,
       joystickprovider	 or  lightgunprovider setting (depending on which kind
       of device youre having issues with) from	rawinput to one	of  the	 other
       options	such  as dinput	or win32.  See OSD-related Options for details
       on input	provider options

   What	happened to the	MAME support for external OPL2-carrying	soundcards?
       MAME 0.23 added support for using a sound cards	onboard	 OPL2  (Yamaha
       YM3812 chip) instead of emulating the OPL2.  This feature was only sup-
       ported  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.  MAMEs OPL2 emulation is now superior to	using  a  sound	 cards
       YM3812 in all cases, especially as modern sound cards lack a YM3812.

   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 ef-
	 fect.

       The setting will	be automatically saved for future use.

       See Autofire Plugin for more information	about using the	autofire  plu-
       gin,  or	 Plugins for more information about using plugins with MAME in
       general.

   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 ap-
	 plications 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.

       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 re-
       fresh rates. For	instance, the first three Mortal Kombat	titles run  at
       54.706841Hz.

MAME COMMAND-LINE USAGE	AND OS-SPECIFIC	CONFIGURATION
   Universal Command-line Options
       This  section contains configuration options that are applicable	to all
       MAME configurations (including both SDL and Windows native).

        Commands and Verbs

        Patterns

        File Names and	Directory Paths

        Core Verbs

        Configuration Verbs

        Frontend Verbs

        OSD-related Options

        OSD Command-Line Verbs

        OSD Output Options

        Configuration Options

        Core Search Path Options

        Core Output Directory Options

        Core State/Playback Options

        Core Performance Options

        Core Rotation Options

        Core Video Options

        Core Full Screen Options

        Core Per-Window Options

        Core Artwork Options

        Core Screen Options

        Core Vector Options

        Core Video OpenGL Feature Options

        Core Video OpenGL GLSL	Options

        Core Sound Options

        Core Input Options

        Core Input Automatic Enable Options

        Debugging Options

        Core Communication Options

        Core Misc Options

        Scripting Options

        HTTP Server Options

        PortAudio Options

   Commands and	Verbs
       Commands	include	mame itself as well as various tools included with the
       MAME distribution such as romcmp	and srcclean.

       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)

   Patterns
       Many  verbs  support  the use of	patterns, which	are either a system or
       device short name (e.g.	a2600,	zorba_kbd)  or	a  glob	 pattern  that
       matches either (e.g. zorba_*).

       Depending  on the command you're	using the pattern with,	pattern	match-
       ing may match systems or	systems	and devices.  It  is  advised  to  put
       quotes  around  your  patterns to avoid having your shell try to	expand
       them against filenames (e.g.  mame -validate "pac*").

   File	Names and Directory Paths
       A number	of options for specifying directories support  multiple	 paths
       (for  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 example %APPDATA%\mame\cfg	will  expand  the  application
       data  path for the current user's roaming profile.  On UNIX-like	system
       (including macOS	and 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 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 work-
       ing 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	direc-
       tory (usually /Users/<username> ) and start MAME.

       If you want behaviour similar to	what Windows Explorer provides on  ma-
       cOS,  create a script file containing these lines in the	directory con-
       taining the MAME	executable (for	example	you could call it mame-here ):

	  #!/bin/sh
	  cd "`dirname "$0"`"
	  exec ./mame

       You should be able to use any text editor.  If you  have	 a  choice  of
       file  format or line ending style, choose UNIX. This assumes you're us-
       ing 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  exe-
       cutable.	  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 En-
       ter) 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.

   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

       -help / -h / -?
	  Displays current MAME	version	and copyright notice.

	  Example:

		     mame -help

       -validate / -valid [<pattern>]
	  Performs  internal  validation on one	or more	drivers	and devices in
	  the system.  Run this	before submitting changes to ensure  that  you
	  haven't violated any of the core system rules.

	  If  a	 pattern  is  specified, it will validate systems matching the
	  pattern, otherwise it	will validate all systems and  devices.	  Note
	  that	if  a pattern is specified, it will be matched against systems
	  only (not other devices), and	no device type validation will be per-
	  formed.

	  Example:

		     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

   Configuration Verbs
       -createconfig / -cc
	  Creates the default mame.ini file.  All  the	configuration  options
	  (not	verbs)	described  below can be	permanently changed by editing
	  this configuration file.

	  Example:

		     mame -createconfig

       -showconfig / -sc
	  Displays the current configuration settings.	If you route this to a
	  file,	you can	use it as an INI file.

	  Example:

		     mame -showconfig >	mame.ini

		 This example is equivalent to -createconfig.

       -showusage / -su
	  Displays a summary of	all the	command	 line  options.	  For  options
	  that	are  not  mentioned  here,  the	 short	summary	given by "mame
	  -showusage" is usually a sufficient description.

   Frontend Verbs
       Note: By	default, all the '-list' verbs below write info	to  the	 stan-
       dard  output  (usually  the terminal/command window where you typed the
       command).  If you wish to write the info	to a text  file	 instead,  add
       this to the end of your 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  com-
       pletely overwritten.

	  Example:

		     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.

       -listxml	/ -lx [<pattern>...]
	  List	comprehensive details for all of the supported systems and de-
	  vices	in XML format.	The output is quite long,  so  it  is  usually
	  better  to  redirect	this  into a file.  By default all systems are
	  listed; however, you can limit this list by specifying one  or  more
	  patterns after the -listxml verb.

	  This XML output is typically imported	into other tools (like graphi-
	  cal  front-ends  and	ROM managers), or processed with scripts query
	  detailed information.

	  Example:

		     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.

       -listfull / -ll [<pattern>...]

	  Example:

		     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.

       -listsource / -ls [<pattern>...]
	  Displays  a  list  of	 system	 drivers/devices  and the names	of the
	  source files where they are defined.	Useful for finding which  dri-
	  ver  a  system runs on in order to fix bugs.	By default all systems
	  and devices are listed; however, you can limit this list by specify-
	  ing one or more pattern after	the -listsource	verb.

	  Example:

		     mame galaga -listsource
		     galaga	      galaga.cpp

       -listclones / -lc [<pattern>]
	  Displays a list of clones.  By default all clones are	 listed;  how-
	  ever,	 you  can  limit  this	list by	specifying a pattern after the
	  -listsource 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:

		     mame pacman -listclones
		     Name:	      Clone of:
		     pacman	      puckman

	  Example 2:

		     mame puckman -listclones
		     Name:	      Clone of:
		     abscam	      puckman
		     bucaner	      puckman
		     crockman	      puckman
		     crockmnf	      puckman
		     ...
		     puckmod	      puckman
		     titanpac	      puckman

       -listbrothers / -lb [<pattern>]
	  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:

		     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

       -listcrc	[<pattern>...]
	  Displays  a full list	of CRCs	and names of all ROM images referenced
	  by systems and devices matching the  specified  pattern(s).	If  no
	  patterns are specified, ROMs referenced by all supported systems and
	  devices will be included.

	  Example:

		     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

       -listroms / -lr [<pattern>...]
	  Displays  a  list  of	ROM images referenced by supported systems/de-
	  vices	that match the specified pattern(s). If	no patterns are	speci-
	  fied,	the results will include all supported systems and devices.

	  Example:

		     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)

       -listsamples [<pattern>]
	  Displays a list of samples referenced	by the	specified  pattern  of
	  system or device names. If no	pattern	is specified, the results will
	  be all systems and devices.

	  Example:

		     mame armorap -listsamples
		     Samples required for driver "armorap".
		     loexp
		     jeepfire
		     hiexp
		     tankfire
		     tankeng
		     beep
		     chopper

       -verifyroms [<pattern>]
	  Checks  for  invalid	or  missing ROM	images.	By default all drivers
	  that have valid ZIP files or directories in the  rompath  are	 veri-
	  fied;	however, you can limit this list by specifying a pattern after
	  the -verifyroms command.

	  Example:

		     mame gradius -verifyroms
		     romset gradius [nemesis] is good
		     1 romsets found, 1	were OK.

       -verifysamples [<pattern>]
	  Checks  for  invalid or missing samples. By default all drivers that
	  have valid ZIP files or directories in the samplepath	are  verified;
	  however,  you	 can limit this	list by	specifying a pattern after the
	  -verifyroms command.

	  Example:

		     mame armorap -verifysamples
		     sampleset armorap [armora]	is good
		     1 samplesets found, 1 were	OK.

       -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	error-
	  level	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

	  Example:

		     mame unknown.rom -romident
		     Identifying unknown.rom....
		     unknown.rom	 = 456-a07.17l		 gradius    Gradius (Japan, ROM	version)

       -listdevices / -ld [<pattern>]
	  Displays  a  list  of	all devices known to be	hooked up to a system.
	  The ":" is considered	the system itself with the devices list	 being
	  attached  to give the	user a better understanding of what the	emula-
	  tion is using.

	  If slots are populated with devices, any additional slots those  de-
	  vices	 provide  will	be  visible with -listdevices as well. For in-
	  stance, installing a floppy controller into a	 PC  will  expose  the
	  disk drive slots.

	  Example:

		     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

       -listslots / -lslot [<pattern>]
	  Show	available slots	and options for	each slot (if available). Pri-
	  marily used for MAME to allow	control	over internal  plug-in	cards,
	  much like PCs	needing	video, sound and other expansion cards.

	  If  slots are	populated with devices,	any additional slots those de-
	  vices	provide	will be	visible	with -listslots	as well. For instance,
	  installing a floppy controller into a	PC will	expose the disk	 drive
	  slots.

	  The slot name	(e.g. ctrl1) can be used from the command line (-ctrl1
	  in this case)

	  Example:

		     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

       -listbios [<pattern>]
	  Show	available  BIOS	options	for a system (if available).  BIOS op-
	  tions	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:

		     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)

       -listmedia / -lm	[<pattern>]
	  List available media that the	chosen system allows to	be used.  This
	  includes  media  types  (cartridge,  cassette, diskette and more) as
	  well as common file extensions which are supported.

	  Example:

		     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

       -listsoftware / -lsoft [<pattern>]
	  Displays the contents	of all software	lists that can be used by  the
	  system or systems represented	by pattern.

	  Example:

		     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>
			     ...

       -verifysoftware / -vsoft	[<pattern>]
	  Checks  for invalid or missing ROM images in your software lists. By
	  default all drivers that have	valid ZIP files	or directories in  the
	  rompath are verified;	however, you can limit this list by specifying
	  a specific driver name or pattern after the -verifysoftware command.

	  Example:

		     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
		     ...

       -getsoftlist / -glist [<pattern>]
	  Displays  the	contents of a specific softlist	with the filename rep-
	  resented by pattern.

	  Example:

		     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>
				 ...

       -verifysoftlist / -vlist	[softwarelistname]
	  Checks a specified software list for missing ROM images if files ex-
	  ist for issued softwarelistname. By default, all drivers  that  have
	  valid	ZIP files or directories in the	rompath	are verified; however,
	  you  can  limit  this	list by	specifying a specific softwarelistname
	  (without .XML) after the -verifysoftlist command.

	  Example:

		     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-related Options
       -uimodekey [keystring]
	  Key used to enable/disable MAME keyboard controls when the  emulated
	  system  has  keyboard	inputs.	 The default setting is	Forward	Delete
	  on macOS or SCRLOCK on other operating  systems  (including  Windows
	  and Linux).  Use FN-Delete on	Macintosh computers with notebook/com-
	  pact keyboards.

	  Example:

		     mame ibm5150 -uimodekey DEL

       -controller_map / -ctrlmap <filename>
	  Path	to a text file containing game controller button and axis map-
	  pings	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  sup-
	  ported  when	using the sdlgame joystick provider.  The default set-
	  ting is none.

	  A community-sourced list of game controller mappings can be found on
	  GitHub.  Besides using a text	editor,	several	 tools	are  available
	  for creating game controller mappings, including SDL2	Gamepad	Mapper
	  and  SDL2  ControllerMap  which  is supplied with SDL.  You can also
	  configure your controller in Steams 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:

		     mame -controller_map gamecontrollerdb.txt sf2ce

       -[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:

		     mame -background_input ssf2tb

       -uifontprovider <module>
	  Chooses provider for UI font rendering. The default setting is auto.

   Supported UI	font providers per-platform
	     +-----------+-----+--------+------+-----+---------+------+
	     | Microsoft | win | dwrite	| auto |     | sdl [1] | none |
	     | Windows	 |     |	|      |     |	       |      |
	     +-----------+-----+--------+------+-----+---------+------+
	     | macOS	 |     |	| auto | osx | sdl     | none |
	     +-----------+-----+--------+------+-----+---------+------+
	     | Linux	 |     |	| auto |     | sdl     | none |
	     +-----------+-----+--------+------+-----+---------+------+

FOOTNOTES
       [1]  SDL	 support  on  Windows  requires	that you compile MAME with the
	    support in.	By default SDL is not included in  Windows  builds  of
	    MAME.

       Example:

		 mame ajax -uifontprovider dwrite

       -keyboardprovider <module>
	  Chooses how MAME will	get keyboard input. The	default	is auto.

   Supported keyboard input providers per-platform
       +------------+----------+----------+--------+-------+---------+------+
       | Microsoft  | auto [2] | rawinput | dinput | win32 | sdl [3] | none |
       | Windows    |	       |	  |	   |	   |	     |	    |
       +------------+----------+----------+--------+-------+---------+------+
       | SDL (macOS | auto [4] |	  |	   |	   | sdl     | none |
       | and Linux) |	       |	  |	   |	   |	     |	    |
       +------------+----------+----------+--------+-------+---------+------+

FOOTNOTES
       [2]  auto on Windows will try rawinput with fallback to dinput.

       [3]  SDL	 support  on  Windows  requires	that you compile MAME with the
	    support in.	By default SDL is not included in  Windows  builds  of
	    MAME.

       [4]  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  Win-
	  dows machines.

       Example:

		 mame c64 -keyboardprovider win32

       -mouseprovider <module>
	  Chooses how MAME will	get mouse input. The default is	auto.

   Supported mouse input providers per-platform
       +------------+----------+----------+--------+-------+---------+------+
       | Microsoft  | auto [5] | rawinput | dinput | win32 | sdl [6] | none |
       | Windows    |	       |	  |	   |	   |	     |	    |
       +------------+----------+----------+--------+-------+---------+------+
       | SDL (macOS | auto [7] |	  |	   |	   | sdl     | none |
       | and Linux) |	       |	  |	   |	   |	     |	    |
       +------------+----------+----------+--------+-------+---------+------+

FOOTNOTES
       [5]  On Windows,	auto will try rawinput with fallback to	dinput.

       [6]  SDL	 support  on  Windows  requires	that you compile MAME with the
	    support in.	By default SDL is not included in  Windows  builds  of
	    MAME.

       [7]  auto on SDL	will default to	sdl.

       Example:

		 mame indy_4610	-mouseprovider win32

       -lightgunprovider <module>
	  Chooses how MAME will	get light gun input. The default is auto.

   Supported light gun input providers per-platform
	+-----------+-----------+----------+-------+---------+-----+------+
	| Microsoft | auto [8]	| rawinput | win32 | sdl [9] |	   | none |
	| Windows   |		|	   |	   |	     |	   |	  |
	+-----------+-----------+----------+-------+---------+-----+------+
	| macOS	    | auto [10]	|	   |	   | sdl     |	   | none |
	+-----------+-----------+----------+-------+---------+-----+------+
	| Linux	    | auto [10]	|	   |	   | sdl     | x11 | none |
	+-----------+-----------+----------+-------+---------+-----+------+

FOOTNOTES
       [8]  On Windows,	auto will try rawinput with fallback to	win32, or none
	    if it doesn't find any.

       [9]  SDL	 support  on  Windows  requires	that you compile MAME with the
	    support in.	By default SDL is not included in  Windows  builds  of
	    MAME.

       [10] On SDL, auto will default to sdl.

       Example:

		 mame lethalen -lightgunprovider x11

       -joystickprovider <module>
	  Chooses  how MAME will get joystick and other	game controller	input.
	  The default is auto.

   Supported joystick input providers per-platform
  +-----------+-----------+-----------+--------+--------+---------+--------+------+
  | Microsoft |	auto [11] | winhybrid |	dinput | xinput	| sdlgame | sdljoy | none |
  | Windows   |		  |	      |	       |	| [12]	  | [12]   |	  |
  +-----------+-----------+-----------+--------+--------+---------+--------+------+
  | SDL	      |	auto [13] |	      |	       |	| sdlgame | sdljoy | none |
  +-----------+-----------+-----------+--------+--------+---------+--------+------+

FOOTNOTES
       [11] On Windows native, auto will default to winhybrid.

       [12] SDL	support	on Windows requires that you  compile  MAME  with  the
	    support  in.  By  default SDL is not included in Windows builds of
	    MAME.

       [13] On SDL, auto will default to sdlgame.

       winhybrid
	      Uses XInput for compatible game controllers, falling back	to Di-
	      rectInput	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 simultane-
	      ously.  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 but-
	      ton/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 controller_map option 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:

		 mame mk2 -joystickprovider winhybrid

       -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 out-
	  put (MIDI files can still be played).	 The default  is  auto,	 which
	  will use PortMidi if available.

       Example:

		 mame -midiprovider none dx100 -midiin canyon.mid

       -networkprovider	<module>
	  Chooses how MAME will	provide	communication for emulated packet-ori-
	  ented	 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:

		 mame -networkprovider pcap apple2ee -sl3 uthernet

   OSD Command-Line Verbs
       -listmidi
	  List available MIDI I/O devices for use with emulation.

	  Example:

		     mame -listmidi
		     MIDI input	ports:

		     MIDI output ports:
		     Microsoft MIDI Mapper (default)
		     Microsoft GS Wavetable Synth

       -listnetwork
	  List available network adapters for use with emulation.

	  Example 1:

		     mame -listnetwork
		     No	network	adapters were found

	  Example 2:

		     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.

   OSD Output Options
       -output
	  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:

		     mame asteroid -output console
		     led0 = 1
		     led0 = 0
		     ...
		     led0 = 1
		     led0 = 0

   Configuration Options
       -[no]readconfig / -[no]rc
	  Enables or disables the reading of the config	 files.	 When  enabled
	  (which is the	default), MAME reads the following config files	in or-
	  der:

	      	mame.ini

	      	debug.ini			(if the	debugger is enabled)

	      	source/<driver>.ini    (based  on  the	source filename	of the
		driver)

	      	vertical.ini			 (for  systems	with  vertical
		monitor	orientation)

	      	horizont.ini			 (for  systems with horizontal
		monitor	orientation)

	      	arcade.ini			(for systems in	 source	 added
		with GAME() macro)

	      	console.ini			 (for  systems in source added
		with CONS() macro)

	      	computer.ini			(for systems in	 source	 added
		with COMP() macro)

	      	othersys.ini			 (for  systems in source added
		with SYST() macro)

	      	vector.ini			(for vector systems only)

	      	<parent>.ini		    (for clones	only,  may  be	called
		recursively)

	      	<systemname>.ini

	      (See Order of Config Loading for further details)

	  The  settings	 in the	later INIs override those in the earlier INIs.
	  So, for example, if you wanted to disable  overlay  effects  in  the
	  vector systems, you can create a vector.ini with line	effect none in
	  it,  and  it	will  override	whatever effect	value you have in your
	  mame.ini.

	  The default is ON (-readconfig).

	  Example:

		     mame apple2ee -noreadconfig -sl6 diskii -sl7 cffa2	-hard1 TotalReplay.2mg

   Core	Search Path Options
       -homepath <path>
	  Specifies a path for Lua plugins to store data.

	  The default is . (that is, in	the current working directory).

	  Example:

		     mame -homepath C:\mame\lua

       -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.

	  The default is roms (that is,	a directory roms in the	current	 work-
	  ing directory).

	  Example:

		     mame -rompath C:\mame\roms;C:\roms\another

       -hashpath / -hash_directory / -hash <path>
	  Specifies one	or more	paths within which to find software definition
	  files.   Multiple  paths  can	 be  specified by separating them with
	  semicolons.

	  The default is hash (that is,	a directory hash in the	current	 work-
	  ing directory).

	  Example:

		     mame -hashpath C:\mame\hash;C:\roms\softlists

       -samplepath / -sp <path>
	  Specifies one	or more	paths within which to find audio sample	files.
	  Multiple paths can be	specified by separating	them with semicolons.

	  The  default is samples (that	is, a directory	samples	in the current
	  working directory).

	  Example:

		     mame -samplepath C:\mame\samples;C:\roms\samples

       -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.

	  The  default is artwork (that	is, a directory	artwork	in the current
	  working directory).

	  Example:

		     mame -artpath C:\mame\artwork;C:\emu\shared-artwork

       -ctrlrpath <path>
	  Specifies one	or more	paths within which to find controller configu-
	  ration 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:

		     mame -ctrlrpath C:\mame\ctrlr;C:\emu\controllers

       -inipath	<path>
	  Specifies one	or more	paths within which to find INI files.	Multi-
	  ple paths can	be specified by	separating them	with semicolons.

	  On Windows, the default is .;ini;ini/presets (that is, search	in the
	  current  directory  first,  then in the directory ini	in the current
	  working directory, and finally the directory presets inside that di-
	  rectory).

	  On   macOS,	the   default	is   $HOME/Library/Application	  Sup-
	  port/mame;$HOME/.mame;.;ini  (that is, search	the mame folder	inside
	  the current user's Application Support folder, followed by the .mame
	  folder in the	current	user's home directory, then the	current	 work-
	  ing  directory, and finally the directory ini	in the current working
	  directory).

	  On   other   platforms   (including	Linux),	  the	 default    is
	  $HOME/.mame;.;ini (that is search the	.mame directory	in the current
	  user's  home	directory,  followed by	the current working directory,
	  and finally the directory ini	in the current working directory).

	  Example:

		     mame -inipath C:\Users\thisuser\documents\mameini

       -fontpath <path>
	  Specifies one	or more	paths within which to find  BDF	 (Adobe	 Glyph
	  Bitmap Distribution Format) font files.  Multiple paths can be spec-
	  ified	by separating them with	semicolons.

	  The default is . (that is, search in the current working directory).

	  Example:

		     mame -fontpath C:\mame\;C:\emu\artwork\mamefonts

       -cheatpath <path>
	  Specifies  one  or  more paths within	which to find XML cheat	files.
	  Multiple paths can be	specified by separating	them with semicolons.

	  The default is cheat (that is, a folder called cheat located in  the
	  current working directory).

	  Example:

		     mame -cheatpath C:\mame\cheat;C:\emu\cheats

       -crosshairpath <path>
	  Specifies  one  or  more  paths within which to find crosshair image
	  files.  Multiple paths can be	 specified  by	separating  them  with
	  semicolons.

	  The  default	is crsshair (that is, a	directory crsshair in the cur-
	  rent working directory).

	  Example:

		     mame -crosshairpath C:\mame\crsshair;C:\emu\artwork\crosshairs

       -pluginspath <path>
	  Specifies one	or more	paths within which to  find  Lua  plugins  for
	  MAME.

	  The  default is plugins (that	is, a directory	plugins	in the current
	  working directory).

	  Example:

		     mame -pluginspath C:\mame\plugins;C:\emu\lua

       -languagepath <path>
	  Specifies one	or more	paths within which to find language files  for
	  localized UI text.

	  The  default	is language (that is, a	directory language in the cur-
	  rent working directory).

	  Example:

		     mame -languagepath	C:\mame\language;C:\emu\mame-languages

       -swpath <path>
	  Specifies the	default	path from which	to load	loose  software	 image
	  files.

	  The default is sofware (that is, a directory software	in the current
	  working directory).

	  Example:

		     mame -swpath C:\mame\software;C:\emu\mydisks

   Core	Output Directory Options
       -cfg_directory <path>
	  Specifies  the directory where configuration files are stored.  Con-
	  figuration files are read when starting MAME or when starting	an em-
	  ulated machine, and written on exit.	Configuration  files  preserve
	  settings  including input assignment,	DIP switch settings, bookkeep-
	  ing statistics, and debugger window arrangement.

	  The default is cfg (that is, a directory cfg in the current  working
	  directory). If this directory	does not exist,	it will	be created au-
	  tomatically.

	  Example:

		     mame -cfg_directory C:\mame\cfg

       -nvram_directory	<path>
	  Specifies  the  directory where NVRAM	files are stored.  NVRAM files
	  store	the contents of	EEPROM,	non-volatile RAM  (NVRAM),  and	 other
	  programmable	devices	 for  systems that used	this type of hardware.
	  This data is read when starting an emulated machine and  written  on
	  exit.

	  The  default	is  nvram  (that  is, a	directory nvram	in the current
	  working directory)).	If this	directory does not exist, it  will  be
	  created automatically.

	  Example:

		     mame -nvram_directory C:\mame\nvram

       -input_directory	<path>
	  Specifies the	directory where	input recording	files are stored.  In-
	  put  recordings are created using the	-record	option and played back
	  using	the -playback option.

	  The default is inp (that is, a directory inp in the current  working
	  directory).	If  this  directory does not exist, it will be created
	  automatically.

	  Example:

		     mame -input_directory C:\mame\inp

       -state_directory	<path>
	  Specifies the	directory where	save state  files  are	stored.	  Save
	  state	 files	are read and written either upon user request, or when
	  using	the -autosave option.

	  The default is sta (that is, a directory sta in the current  working
	  directory).	If  this  directory does not exist, it will be created
	  automatically.

	  Example:

		     mame -state_directory C:\mame\sta

       -snapshot_directory <path>
	  Specifies the	directory where	screen snapshots and video  recordings
	  are stored when requested by the user.

	  The  default is snap (that is, a directory snap in the current work-
	  ing directory). If this directory does not exist, it will be created
	  automatically.

	  Example:

		     mame -snapshot_directory C:\mame\snap

       -diff_directory <path>
	  Specifies the	 directory  where  hard	 drive	difference  files  are
	  stored.  Hard	drive difference files store data that is written back
	  to  an  emulated  hard disk, in order	to preserve the	original image
	  file.	 The difference	files are created when	starting  an  emulated
	  system with a	compressed hard	disk image.

	  The  default is diff (that is, a directory diff in the current work-
	  ing directory).  If this directory does not exist, it	will  be  cre-
	  ated automatically.

	  Example:

		     mame -diff_directory C:\mame\diff

       -comment_directory <path>
	  Specifies  a directory where debugger	comment	files are stored.  De-
	  bugger comment files are written by the debugger when	 comments  are
	  added	to the disassembly for a system.

	  The  default	is comments (that is, a	directory comments in the cur-
	  rent working directory).  If this directory does not exist, it  will
	  be created automatically.

	  Example:

		     mame -comment_directory C:\mame\comments

   Core	State/Playback Options
       -[no]rewind
	  When	enabled	 and emulation is paused, automatically	creates	a save
	  state	in memory every	time a frame is	advanced.  Rewind save	states
	  can  then be loaded consecutively by pressing	the rewind single step
	  shortcut key (Left Shift + Tilde by default).

	  The default rewind value is OFF (-norewind).

	  If debugger is in a 'break' state, a save state is  instead  created
	  every	 time  step  in, step over, or step out	occurs.	 In that mode,
	  rewind save states can be loaded by executing	 the  debugger	rewind
	  (or rw) command.

	  Example:

		     mame -norewind

       -rewind_capacity	<value>
	  Sets	the  rewind  capacity  value,  in  megabytes.  It is the total
	  amount of memory rewind savestates can  occupy.   When  capacity  is
	  hit,	old  savestates	 get erased as new ones	are captured.  Setting
	  capacity lower than the current savestate size disables rewind. Val-
	  ues below 0 are automatically	clamped	to 0.

	  Example:

		     mame -rewind_capacity 30

       -state <slot>
	  Immediately after starting the specified system, will	cause the save
	  state	in the specified <slot>	to be loaded.

	  Example:

		     mame -state 1

       -[no]autosave
	  When enabled,	automatically creates a	save state file	 when  exiting
	  MAME	and  automatically  attempts  to reload	it when	later starting
	  MAME with the	same system.  This only	works for  systems  that  have
	  explicitly enabled save state	support	in their driver.

	  The default is OFF (-noautosave).

	  Example:

		     mame -autosave

       -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.

	  The default is NULL (no playback).

	  Example:

		     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.

       -[no]exit_after_playback
	  When	used  in conjunction with the -playback	option,	MAME will exit
	  after	playing	back the input file.  By default,  MAME	 continues  to
	  run the emulated system after	playback completes.

	  The default is OFF (-noexit_after_playback).

	  Example:

		     mame pacman -playback worldrecord -exit_after_playback

       -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 record a session
	  from start to	finish.

	  The default is NULL (no recording).

	  Example:

		     mame pacman -record 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.

       -mngwrite <filename>
	  Writes each video frame to the given <filename> in MNG format,  pro-
	  ducing an animation of the session.  Note that -mngwrite only	writes
	  video	frames;	it does	not save any audio data.  Either use -wavwrite
	  to  record  audio and	combine	the audio and video tracks using video
	  editing software, or use -aviwrite to	record audio and  video	 to  a
	  single file.

	  The default is NULL (no recording).

	  Example:

		     mame pacman -mngwrite pacman-video

       -aviwrite <filename>
	  Stream  video	and sound data to the given <filename> in uncompressed
	  AVI format, producing	an animation  of  the  session	complete  with
	  sound.   Note	 that the AVI format does not changes to resolution or
	  frame	rate, uncompressed video consumes a lot	 of  disk  space,  and
	  recording  uncompressed  video in realtime requires a	fast disk.  It
	  may be more practical	to record an emulation session	using  -record
	  then make a video of it with -aviwrite in combination	with -playback
	  and -exit_after_playback options.

	  The default is NULL (no recording).

	  Example:

		     mame pacman -playback worldrecord -exit_after_playback -aviwrite worldrecord

       -wavwrite <filename>
	  Writes the final mixer output	to the given <filename>	in WAV format,
	  producing an audio recording of the session.

	  The default is NULL (no recording).

	  Example:

		     mame pacman -wavwrite pacsounds

       -snapname <name>
	  Describes  how  MAME	should	name files for snapshots.  <name> is a
	  string that provides a template that is used to generate a filename.

	  Three	simple substitutions are provided: the / character  represents
	  the path separator on	any target platform (even Windows); the	string
	  %g  represents the driver name of the	current	system;	and the	string
	  %i represents	an incrementing	index.	If %i is  omitted,  then  each
	  snapshot taken will overwrite	the previous one; otherwise, MAME will
	  find the next	empty value for	%i and use that	for a filename.

	  The  default is %g/%i, which creates a separate folder for each sys-
	  tem, and names the snapshots under it	starting  with	0000  and  in-
	  creasing from	there.

	  In  addition	to  the	above, for drivers using different media, like
	  carts	or floppy disks, you can also use  the	%d_[media]  indicator.
	  Replace [media] with the media switch	you want to use.

	  Example 1:

		     mame robby	-snapname foo\%g%i

		 Snapshots   will   be	 saved	 as   snaps\foo\robby0000.png,
		 snaps\foo\robby0001.png and so	on.

	  Example 2:

		     mame nes -cart robby -snapname %g\%d_cart

		 Snapshots will	be saved as snaps\nes\robby.png.

	  Example 3:

		     mame c64 -flop1 robby -snapname %g\%d_flop1/%i

		 Snapshots will	be saved as snaps\c64\robby\0000.png.

       -snapsize <width>x<height>
	  Hard-codes the size for snapshots and	movie recording.  By  default,
	  MAME 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.

	  The default is auto.

	  Example:

		     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.

       -snapview <viewname>
	  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  pre-
	  fix.	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.

	  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 art-
	  work elements	drawn or effects applied.

	  The default value is auto.

	  Example:

		     mame wrecking -snapview cocktail

       -[no]snapbilinear
	  Specify  if the snapshot or movie should have	bilinear filtering ap-
	  plied.  Disabling this off can improve performance  while  recording
	  video	to a file.

	  The default is ON (-snapbilinear).

	  Example:

		     mame pacman -nosnapbilinear

       -statename <name>
	  Describes  how  MAME	should store save state	files, relative	to the
	  state_directory path.	 <name>	is a string that provides  a  template
	  that is used to generate a relative path.

	  Two  simple  substitutions  are provided: the	/ character represents
	  the path separator on	any target platform (even Windows); the	string
	  %g represents	the driver name	of the current system.

	  The default is %g, which creates a separate folder for each system.

	  In addition to the above, for	drivers	using  different  media,  like
	  carts	 or  floppy  disks, you	can also use the %d_[media] indicator.
	  Replace [media] with the media switch	you want to use.

	  Example 1:

		     mame robby	-statename foo\%g
		     All save states will be stored inside sta\foo\robby\

	  Example 2:

		     mame nes -cart robby -statename %g/%d_cart
		     All save states will be stored inside sta\nes\robby\

	  Example 3:

		     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

       -[no]burnin
	  Tracks brightness of the screen during play and at the end of	emula-
	  tion generates a PNG that can	be used	to simulate burn-in effects on
	  other	 systems.   The	 resulting  PNG	is created such	that the least
	  used-areas of	the screen are fully white (since burned-in areas  are
	  darker, all other areas of the screen	must be	lightened a touch).

	  The  intention  is  that  this PNG can be loaded via an artwork file
	  with a low alpha (e.g, 0.1-0.2 seems to work well) and blended  over
	  the entire screen.

	  The  PNG  files  are	saved in the snap directory under the <system-
	  name>/burnin-<screen.name>.png.

	  The default is OFF (-noburnin).

	  Example:

		     mame neogeo -burnin

   Core	Performance Options
       -[no]autoframeskip / -[no]afs
	  Dynamically adjust the frameskip level while you're running the sys-
	  tem  to  maintain  full  speed.   Turning  this  on  overrides   the
	  -frameskip setting described below.

	  This is off by default (-noautoframeskip).

	  Example:

		     mame gradius4 -autoframeskip

       -frameskip / -fs	<level>
	  Specifies  the frameskip value.  This	is the number of frames	out of
	  every	12  to	drop  when  running.   For  example,  if  you  specify
	  -frameskip  2,  MAME will render and display 10 out of every 12 emu-
	  lated	frames.	 By skipping some frames, you may be able to get  full
	  speed	 emulation  for	a system that would otherwise be too demanding
	  for your computer.

	  The default value is -frameskip 0, which skips no frames.

	  Example:

		     mame gradius4 -frameskip 2

       -seconds_to_run / -str <seconds>
	  This option tells MAME to automatically stop emulation after a fixed
	  number of seconds of emulated	time have elapsed.  This may be	useful
	  for 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 addi-
	  tion,	upon exit, the -str option will	write a	screenshot to the sys-
	  tem's	snapshot directory with	the file name determined by the	-snap-
	  name option.

	  Example:

		     mame pacman -seconds_to_run 60

       -[no]throttle
	  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 dis-
	  abled, MAME runs the emulation as fast  as  possible.	 Depending  on
	  your	settings  and the characteristics of the emulated system, per-
	  formance may be limited by your CPU, graphics	card, or  even	memory
	  performance.

	  The default is to enable throttling (-throttle).

	      Example:

			mame pacman -nothrottle

       -[no]sleep
	  When enabled along with -throttle, MAME will yield the CPU when lim-
	  iting	 emulation speed.  This	allows other programs to use CPU time,
	  assuming the main emulation thread isn't completely utilising	a  CPU
	  core.	  This	option can potentially cause hiccups in	performance if
	  other	demanding programs are running.

	  The default is on (-sleep).

	  Example:

		     mame gradius 4 -nosleep

       -speed <factor>
	  Changes the way MAME throttles the emulation so that it runs at some
	  multiple of the system's original speed.  A <factor> of 1.0 means to
	  run the system at its	normal speed, a	<factor> of 0.5	means  run  at
	  half	speed,	and a <factor> of 2.0 means run	at double speed.  Note
	  that changing	this value affects sound playback as well, which  will
	  scale	 in pitch accordingly.	The internal precision of the fraction
	  is two decimal places, so a <factor> of 1.002	is rounded to 1.00.

	  The default is 1.0 (normal speed).

	  Example:

		     mame pacman -speed	1.25

       -[no]refreshspeed / -[no]rs
	  Allows MAME to adjust	the emulation speed so that the	 refresh  rate
	  of  the  first  emulated  screen does	not exceed the slowest refresh
	  rate for any targeted	monitors in your system.  Thus,	if you have  a
	  60Hz	monitor	 and  run  a system that is designed to	run at 60.6Hz,
	  MAME will reduce the emulation speed to  99%	in  order  to  prevent
	  sound	 hiccups  or  other  undesirable  side effects of running at a
	  slower refresh rate.

	  The default is off (-norefreshspeed).

	  Example:

		     mame pacman -refreshspeed

       -numprocessors /	-np auto|<value>
	  Specify the number of	threads	to use for  work  queues.   Specifying
	  auto	will use the value reported by the system or environment vari-
	  able OSDPROCESSORS.  This value is internally	limited	to four	 times
	  the number of	processors reported by the system.

	  The default is auto.

	  Example:

		     mame gradius4 -numprocessors 2

       -bench <n>
	  Benchmark  for <n> emulated seconds.	This is	equivalent to the fol-
	  lowing options:

	  -str <n> -video none -sound none -nothrottle

	  Example:

		     mame gradius4 -bench 300

       -[no]lowlatency
	  This tells MAME to draw a new	frame before throttling	to reduce  in-
	  put  latency.	 This is particularly effective	with VRR (Variable Re-
	  fresh	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 soft-
	  ware	akin to	an operating system), so the default is	off (-nolowla-
	  tency).

	  Example:

		     mame bgaregga -lowlatency

   Core	Rotation Options
       -[no]rotate
	  Rotate the system to match its normal	 state	(horizontal/vertical).
	  This	ensures	that both vertically and horizontally oriented systems
	  show up correctly without the	need to	rotate your monitor.   If  you
	  want	to  keep  the system displaying	'raw' on the screen the	way it
	  would	have in	the arcade, turn this option OFF.

	  The default is ON (-rotate).

	  Example:

		     mame pacman -norotate

       -[no]ror

       -[no]rol
	  Rotate  the  system  screen  to  the	right  (clockwise)   or	  left
	  (counter-clockwise)  relative	to either its normal state (if -rotate
	  is specified)	or its native state (if	-norotate is specified).

	  The default for both of these	options	is OFF (-noror -norol).

	  Example 1:

		     mame pacman -ror

	  Example 2:

		     mame pacman -rol

       -[no]autoror

       -[no]autorol
	  These	options	are designed for use with pivoting screens  that  only
	  pivot	 in a single direction.	 If your screen	only pivots clockwise,
	  use -autorol to ensure that the system will fill the	screen	either
	  horizontally	or vertically in one of	the directions you can handle.
	  If your screen only pivots counter-clockwise,	use -autoror.

	  Example 1:

		     mame pacman -autoror

	  Example 2:

		     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.

       -[no]flipx

       -[no]flipy
	  Flip (mirror)	the system screen either horizontally (-flipx) or ver-
	  tically  (-flipy).  The  flips  are  applied	after  the -rotate and
	  -ror/-rol options are	applied.

	  The default for both of these	options	is OFF (-noflipx -noflipy).

	  Example 1:

		     mame -flipx pacman

	  Example 2:

		     mame -flipy suprmrio

   Core	Video Options
       -video <bgfx|gdi|d3d|opengl|soft|accel|none>
	  Specifies which video	subsystem to use for drawing. Options here de-
	  pend on the operating	system and whether  this  is  an  SDL-compiled
	  version of MAME.

	  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 pri-
	    marily 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	 or  buggy  graphics  hardware
	    drivers.

	   Using  d3d	tells MAME to use Direct3D 9 for rendering.  This pro-
	    duces better quality output	than gdi and enables  additional  ren-
	    dering  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 SDLs 2D  acceleration
	    if possible.

	   Using soft uses software rendering for video output.  This isnt as
	    fast or as nice as OpenGL, but it will work	on any platform.

	  Defaults:

	   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:

		     mame gradius3 -video bgfx

       -numscreens <count>
	  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 ar-
	  cade machines).  Some	systems	with front panel controls and/or  sta-
	  tus  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:

		     mame darius -numscreens 3

	  Example 2:

		     mame pc_cntra -numscreens 2

       -[no]window / -[no]w
	  Run MAME in either a window or full screen.

	  The default is OFF (-nowindow).

	  Example:

		     mame coco3	-window

       -[no]maximize / -[no]max
	  Controls initial window size in windowed mode.  If it	is set on, the
	  window will initially	be set to the maximum supported	size when  you
	  start	 MAME.	 If it is turned off, the window will start out	at the
	  closest possible size	to the original	size of	the display;  it  will
	  scale	on only	one axis where non-square pixels are used. This	option
	  only has an effect when the -window option is	used.

	  The default is ON (-maximize).

	  Example:

		     mame apple2e -window -nomaximize

       -[no]keepaspect / -[no]ka
	  When	enabled,  MAME preserves the correct aspect ratio for the emu-
	  lated	system's screen(s).  This is most often	4:3  or	 3:4  for  CRT
	  monitors  (depending	on  the	orientation), though many other	aspect
	  ratios have been used, such as 3:2 (Nintendo Game  Boy),  5:4	 (some
	  workstations),  and  various	other  ratios.	If the emulated	screen
	  and/or artwork does not fill MAME's screen or	Window,	the image will
	  be centred and black bars will be added as necessary to fill	unused
	  space	(either	above/below or to the left and right).

	  When	this  option  is  disabled, the	emulated screen	and/or artwork
	  will be stretched to fill MAME's screen or window.  The  image  will
	  be  distorted	 by  non-proportional scaling if the aspect ratio does
	  not match.  This is very pronounced when the emulated	system uses  a
	  vertically-oriented  screen  and  MAME stretches the image to	fill a
	  horizontally-oriented	screen.

	  On Windows, when this	option is enabled and MAME  is	running	 in  a
	  window  (not	full screen), the aspect ratio will be maintained when
	  you resize the window	unless you hold	the Control (or	Ctrl)  key  on
	  your keyboard.  The window size will not be restricted when this op-
	  tion is disabled.

	  The default is ON (-keepaspect).

	  The  MAME  team  strongly  recommends	 leaving  this option enabled.
	  Stretching systems beyond their original aspect  ratio  will	mangle
	  the  appearance  of  the system in ways that no filtering or shaders
	  can repair.

	  Example:

		     mame sf2ua	-nokeepaspect

       -[no]waitvsync
	  Waits	for the	refresh	period on your computer's  monitor  to	finish
	  before  starting  to	draw  video to your screen.  If	this option is
	  off, MAME will just draw to the screen as a frame is ready, even  if
	  in  the  middle  of a	refresh	cycle.	This can cause "tearing" arti-
	  facts, where the top portion of the screen is	out of sync  with  the
	  bottom portion.

	  The  effect  of turning -waitvsync on	differs	a bit between combina-
	  tions	of different operating systems and video drivers.

	  On Windows, -waitvsync will block until video	blanking before	allow-
	  ing MAME to draw the next frame,  limiting  the  emulated  machine's
	  framerate  to	 that  of the host display. Note that this option does
	  not work with	-video gdi mode	in Windows.

	  On macOS, -waitvsync does not	block; instead the  most  recent  com-
	  pletely  drawn frame will be displayed at vblank. This means that if
	  an emulated system has a higher framerate than  your	host  display,
	  emulated  frames  will  be  dropped periodically resulting in	motion
	  judder.

	  On Windows, you should only need to turn this	on in  windowed	 mode.
	  In full screen mode, it is only needed if -triplebuffer does not re-
	  move	the  tearing,  in  which  case	you should use -notriplebuffer
	  -waitvsync.

	  Note that SDL-based MAME support for this option depends entirely on
	  your operating system	and video drivers; in general it will not work
	  in windowed mode so -video opengl and	fullscreen give	 the  greatest
	  chance of success with SDL builds of MAME.

	  The default is OFF (-nowaitvsync).

	  Example:

		     mame gradius2 -waitvsync

       -[no]syncrefresh
	  Enables  speed throttling only to the	refresh	of your	monitor.  This
	  means	that the system's actual refresh rate is ignored; however, the
	  sound	code still attempts to keep up with the	system's original  re-
	  fresh	rate, so you may encounter sound problems.

	  This	option	is  intended  mainly  for those	who have tweaked their
	  video	card's settings	to provide carefully matched refresh rate  op-
	  tions.  Note that this option	does not work with -video gdi mode.

	  The default is OFF (-nosyncrefresh).

	  Example:

		     mame mk -syncrefresh

       -prescale <amount>
	  Controls  the	 size of the screen images when	they are passed	off to
	  the graphics system for scaling.  At the minimum setting of  1,  the
	  screen  is  rendered at its original resolution before being scaled.
	  At higher settings, the screen is expanded in	both axes by a	factor
	  of  <amount> using nearest-neighbor sampling before applying filters
	  or shaders.  With -video d3d,	this produces a	less blurry  image  at
	  the expense of speed.

	  The default is 1.

	  This	is supported with all video output types ( bgfx, d3d, etc.) on
	  Windows and is supported with	BGFX and OpenGL	on other platforms.

	  Example:

		     mame pacman -video	d3d -prescale 3

       -[no]filter / -[no]d3dfilter / -[no]flt
	  Enable bilinear filtering on the system screen graphics.  When  dis-
	  abled,  point	 filtering  is	applied, which is crisper but leads to
	  scaling artifacts.  If you don't like	the  filtered  look,  you  are
	  probably better off increasing the -prescale value rather than turn-
	  ing off filtering altogether.

	  The default is ON (-filter).

	  This	is  supported with OpenGL and D3D video	on Windows and is ONLY
	  supported with OpenGL	on other platforms.

	  Use bgfx_screen_chains in your INI file(s) to	adjust filtering  with
	  the BGFX video system.

	  Example:

		     mame pacman -nofilter

       -[no]unevenstretch
	  Allow	 non-integer  scaling factors allowing for great window	sizing
	  flexibility.

	  The default is ON. (-unevenstretch)

	  Example:

		     mame dkong	-nounevenstretch

   Core	Full Screen Options
       -[no]switchres
	  Enables resolution switching.	This option is required	for the	-reso-
	  lution* options to switch resolutions	in full	screen mode.

	  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  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 and -video bgfx.

	  The default is OFF (-noswitchres).

	  Example:

		     mame kof97	-video d3d -switchres -resolution 1280x1024

   Core	Per-Window Options
       -screen <display>

       -screen0	<display>

       -screen1	<display>

       -screen2	<display>

       -screen3	<display>
	  Specifies  which  physical  monitor  on your system you wish to have
	  each window use by default.  In order	to use multiple	 windows,  you
	  must	have  increased	the value of the -numscreens option.  The name
	  of each display in your system can be	 determined  by	 running  MAME
	  with	the  -verbose  option.	The display names are typically	in the
	  format of: \\\\.\\DISPLAYn, where 'n'	is a number from 1 to the num-
	  ber of connected monitors.

	  The default value for	these options is auto, which  means  that  the
	  first	 window	 is  placed on the first display, the second window on
	  the second display, etc.

	  The -screen0,	-screen1, -screen2, -screen3 parameters	apply  to  the
	  specific  window. The	-screen	parameter applies to all windows.  The
	  window-specific options override values from the all window option.

	  Example 1:

		     mame pc_cntra -numscreens 2 -screen0 \\.\DISPLAY1 -screen1	\\.\DISPLAY2

	  Example 2:

		     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.

       -aspect <width:height> /	-screen_aspect <num:den>

       -aspect0	<width:height>

       -aspect1	<width:height>

       -aspect2	<width:height>

       -aspect3	<width:height>
	  Specifies the	physical aspect	ratio of the physical monitor for each
	  window.   In	order to use multiple windows, you must	have increased
	  the value of the -numscreens option.	The physical aspect ratio  can
	  be  determined  by  measuring	 the  width  and height	of the visible
	  screen image and specifying them separated by	a colon.

	  The default value for	these options is auto, which means  that  MAME
	  assumes  the aspect ratio is proportional to the number of pixels in
	  the desktop video mode for each monitor.

	  The -aspect0,	-aspect1, -aspect2, -aspect3 parameters	apply  to  the
	  specific window.  The	-aspect	parameter applies to all windows.  The
	  window-specific options override values from the all window option.

	  Example 1:

		     mame contra -aspect 16:9

	  Example 2:

		     mame pc_cntra -numscreens 2 -aspect0 16:9 -aspect1	5:4

       -resolution <widthxheight[@refresh]> / -r <widthxheight[@refresh]>

       -resolution0 <widthxheight[@refresh]> / -r0 <widthxheight[@refresh]>

       -resolution1 <widthxheight[@refresh]> / -r1 <widthxheight[@refresh]>

       -resolution2 <widthxheight[@refresh]> / -r2 <widthxheight[@refresh]>

       -resolution3 <widthxheight[@refresh]> / -r3 <widthxheight[@refresh]>
	  Specifies  an	exact resolution to run	in.  In	full screen mode, MAME
	  will try to use the specific resolution you request.	The width  and
	  height  are  required;  the refresh rate is optional.	 If omitted or
	  set to 0, MAME will determine	the mode automatically.	 For  example,
	  -resolution  640x480 will force 640x480 resolution, but MAME is free
	  to choose the	refresh	 rate.	 Similarly,  -resolution  0x0@60  will
	  force	a 60Hz refresh rate, but allows	MAME to	choose the resolution.
	  The string auto is also supported, and is equivalent to 0x0@0.

	  In  window  mode,  this resolution is	used as	a maximum size for the
	  window.  This	option requires	the -switchres option as well in order
	  to actually enable resolution	switching with -video d3d.

	  The default value for	these options is auto.

	  The -resolution0, -resolution1, -resolution2,	 -resolution3  parame-
	  ters apply to	the specific window. The -resolution parameter applies
	  to  all  windows.   The window-specific options override values from
	  the all window option.

	  Example:

		     mame pc_cntra -numscreens 2 -resolution0 1920x1080	-resolution1 1280x1024

       -view <viewname>

       -view0 <viewname>

       -view1 <viewname>

       -view2 <viewname>

       -view3 <viewname>
	  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  pre-
	  fix.	 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	inter-
	  nal 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  win-
	  dow-specific options override	values from the	all windows option.

	  Note	that view settings saved in the	configuration file for the ma-
	  chine	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:

		     mame contra -view native

   Core	Artwork	Options
       -[no]artwork_crop / -[no]artcrop
	  Enable cropping of artwork to	the system  screen  area  only.	  This
	  means	 that vertically oriented systems running full screen can dis-
	  play their artwork to	the left and right sides of the	screen.	  This
	  option can also be controlled	via the	Video Options menu in the user
	  interface.

	  The default is OFF -noartwork_crop.

	  Example:

		     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.

       -fallback_artwork
	  Specifies fallback artwork if	no external artwork or internal	driver
	  layout  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:

		     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 hori-
	  zontal and vertical systems.

       -override_artwork
	  Specifies override artwork for external artwork and internal	driver
	  layout.

	  Example:

		     mame galaga -override_artwork puckman

   Core	Screen Options
       -brightness <value>
	  Controls  the	 default  brightness,  or  black  level, of 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
	  brightness for each system screen; this option controls the  initial
	  value	for all	visible	system screens.	The standard and default value
	  is  1.0.   Selecting lower values (down to 0.1) will produce a dark-
	  ened display,	while selecting	higher values (up to 2.0) will give  a
	  brighter display.

	  Example:

		     mame pacman -brightness 0.5

       -contrast <value>
	  Controls  the	 contrast, or white level, of 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 contrast for each
	  system screen; this option controls the initial value	for all	 visi-
	  ble system screens.  The standard and	default	value is 1.0.  Select-
	  ing  lower values (down to 0.1) will produce a dimmer	display, while
	  selecting higher values (up to 2.0) will give	a more saturated  dis-
	  play.

	  Example:

		     mame pacman -contrast 0.5

       -gamma <value>
	  Controls  the	gamma, which produces a	potentially nonlinear black to
	  white	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 con-
	  trols	the initial value for all visible system screens.   The	 stan-
	  dard	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:

		     mame pacman -gamma	0.8

       -pause_brightness <value>
	  This controls	the brightness level when MAME is paused.

	  The default value is 0.65.

	  Example:

		     mame pacman -pause_brightness 0.33

       -effect <filename>
	  Specifies a single PNG file that is used as an overlay over any sys-
	  tem  screens in the video display.  This PNG file is assumed to live
	  in the root of one of	the artpath directories.  The pattern  in  the
	  PNG  file  is	repeated both horizontally and vertically to cover the
	  entire system	screen areas (but not any external  artwork),  and  is
	  rendered at the target resolution of the system image.

	  For  -video  gdi  and	-video d3d modes, this means that one pixel in
	  the PNG will map to one pixel	on your	output display.	 The RGB  val-
	  ues  of  each	pixel in the PNG are multiplied	against	the RGB	values
	  of the target	screen.

	  The default is none, meaning no effect.

	  Example:

		     mame pacman -effect scanlines

   Core	Vector Options
       -beam_width_min <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:

		     mame asteroid -beam_width_min 0.1

       -beam_width_max <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:

		     mame asteroid -beam_width_max 2

       -beam_intensity_weight <weight>
	  Sets the vector beam intensity weight. This value determines how the
	  intensity of the vector drawn	affects	the width. A value of  0  cre-
	  ates	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:

		     mame asteroid -beam_intensity_weight 0.5

       -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 dif-
	  ficult 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:

		     mame asteroid -beam_dot_size 2

       -flicker	<value>
	  Simulates  a	vector	"flicker"  effect, similar to a	vector monitor
	  that needs adjustment.  This option requires a float argument	in the
	  range	of 0.00	- 100.00 (0=none, 100=maximum).

	  The default is 0.

	  Example:

		     mame asteroid -flicker 0.15

   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
       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.

       -[no]gl_forcepow2texture
	  Always use only power-of-2 sized textures.

	  The default is OFF. (-nogl_forcepow2texture)

       -[no]gl_notexturerect
	  Don't	use OpenGL GL_ARB_texture_rectangle.

	  The default is ON. (-gl_notexturerect)

       -[no]gl_vbo
	  Enable OpenGL	VBO (Vertex Buffer Objects), if	available.

	  The default is ON. (-gl_vbo)

       -[no]gl_pbo
	  Enable OpenGL	PBO (Pixel Buffer Objects), if available (default on )

	  The default is ON. (-gl_pbo)

   Core	Video OpenGL GLSL Options
       -[no]gl_glsl
	  Enable OpenGL	GLSL, if available.

	  The default is OFF (-nogl_glsl).

	  Example:

		     mame galaxian -gl_glsl

       -gl_glsl_filter
	  Use OpenGL GLSL shader-based filtering  instead  of  fixed  function
	  pipeline-based filtering.

	  0-plain, 1-bilinear, 2-bicubic

	  The default is 1. (-gl_glsl_filter 1)

	  Example:

		     mame galaxian -gl_glsl -gl_glsl_filter 0

       -glsl_shader_mame0

       -glsl_shader_mame1

       ...

       -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.

	  Example:

		     mame suprmrio -gl_glsl -glsl_shader_mame0 NTSC/NTSC_chain -glsl_shader_mame1 CRT-geom/CRT-geom

       -glsl_shader_screen0

       -glsl_shader_screen1

       ...

       -glsl_shader_screen9
	  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.

	  Example:

		     mame suprmrio -gl_glsl -glsl_shader_screen0 gaussx	-glsl_shader_screen1 gaussy -glsl_shader_screen2 CRT-geom-halation

   Core	Sound Options
       -samplerate <value> / -sr <value>
	  Sets the audio sample	rate.  Smaller values (e.g. 11025) cause lower
	  audio	 quality  but  faster  emulation  speed.   Higher values (e.g.
	  48000) cause higher audio quality but	slower emulation speed.

	  The default is 48000.

	  Example:

		     mame galaga -samplerate 44100

       -[no]samples
	  Use samples if available.

	  The default is ON (-samples).

	  Example:

		     mame qbert	-nosamples

       -[no]compressor
	  Enable audio compressor. It temporarily reduces the  overall	volume
	  when the audio output	is overdriven.

	  The default is ON (-compressor).

	  Example:

		     mame popeye -nocompressor

       -volume / -vol <value>
	  Sets	the  initial  sound  volume.  It can be	changed	later with the
	  user interface (see Keys section).  The volume is an attenuation  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 (no attenuation, or full volume).

	  Example:

		     mame pacman -volume -30

       -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 and Linux,	portaudio is likely to give the	lowest	possi-
	  ble  latency,	 while Mac users will find coreaudio provides the best
	  results.

	  When using the sdl sound subsystem, the audio	API to use may be  se-
	  lected  by setting the SDL_AUDIODRIVER environment variable.	Avail-
	  able audio APIs 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:

		     mame pacman -sound	portaudio

   Supported sound subsystems per-platform
    +------------+--------+---------+-----------+-----------+-----------+------+
    | Microsoft	 | dsound | xaudio2 | portaudio	|	    | sdl [14].	| none |
    | Windows	 |	  |	    |		|	    |		|      |
    +------------+--------+---------+-----------+-----------+-----------+------+
    | macOS	 |	  |	    | portaudio	| coreaudio | sdl	| none |
    +------------+--------+---------+-----------+-----------+-----------+------+
    | Linux  and |	  |	    | portaudio	|	    | sdl	| none |
    | others	 |	  |	    |		|	    |		|      |
    +------------+--------+---------+-----------+-----------+-----------+------+

FOOTNOTES
       [14] While SDL is not a supported option	on official  builds  for  Win-
	    dows, you can compile MAME with SDL	support	on Windows.

	    -audio_latency <value>
	  The  exact  behavior	depends	 on  the selected audio	output module.
	  Smaller values provide less audio delay while	requiring better  sys-
	  tem  performance.   Higher  values increase audio delay but may help
	  avoid	buffer under-runs and audio interruptions.

	  The default is 1.

	   For	PortAudio, see the section on -pa_latency.

	   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:

		     mame galaga -audio_latency	1

   Core	Input Options
       -[no]coin_lockout / -[no]coinlock
	  Enables simulation of	the "coin lockout" feature that	is implemented
	  on a number of arcade	game PCBs.  It was up to the operator  whether
	  or  not the coin lockout outputs were	actually connected to the coin
	  mechanisms.  If this feature is enabled, then	attempts  to  enter  a
	  coin	while the lockout is active will fail and will display a popup
	  message in the user interface	(in debug mode).  If this  feature  is
	  disabled, the	coin lockout signal will be ignored.

	  The default is ON (-coin_lockout).

	  Example:

		     mame suprmrio -coin_lockout

       -ctrlr <controller>
	  Specifies  a	controller  configuration  file, typically used	to set
	  more suitable	default	input assignments for special controllers. Di-
	  rectories specified using the	ctrlrpath option are  searched.	  Con-
	  troller  configuration  files	 use  a	similar	format to .cfg used to
	  save system settings.	See Controller Configuration  Files  for  more
	  details.

	  The default is NULL (no controller configuration file).

	  Example:

		     mame dkong	-ctrlr xarcade

       -[no]mouse
	  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.  Supported mouse
	  controllers depend on	your mouseprovider setting.

	  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 automatic input enable settings.  In	 particular,  the  de-
	  fault	 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:

		     mame centiped -mouse

       -[no]joystick / -[no]joy
	  Controls whether or not MAME makes use  of  game  controllers	 (e.g.
	  joysticks,  gamepads	and simulation controls).  Supported game con-
	  trollers depend on your joystickprovider setting.

	  When this is enabled,	MAME will ask  the  system  about  which  con-
	  trollers 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 automatic input enable settings.

	  The default is OFF (-nojoystick).

	  Example:

		     mame mappy	-joystick

       -[no]lightgun / -[no]gun
	  Controls  whether  or	 not  MAME  makes use of lightgun controllers.
	  Note that most lightguns also	produce	mouse input, so	enabling mouse
	  and lightgun controllers simultaneously (using -lightgun and	-mouse
	  together)  may  produce  strange behaviour.  Supported lightgun con-
	  trollers depend on your lightgunprovider setting.

	  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 automatic input enable settings.

	  The default is OFF (-nolightgun).

	  Example:

		     mame lethalen -lightgun

       -[no]multikeyboard / -[no]multikey
	  Determines whether MAME differentiates between  multiple  keyboards.
	  Some systems may report more than one	keyboard; by default, the data
	  from all of these keyboards is combined so that it looks like	a sin-
	  gle keyboard.

	  Turning this option on will enable MAME to report keypresses on dif-
	  ferent keyboards independently.

	  The default is OFF (-nomultikeyboard).

	  Example:

		     mame sf2ceua -multikey

       -[no]multimouse
	  Determines  whether MAME differentiates between multiple mice.  Some
	  systems may report more than one mouse device; by default, the  data
	  from	all  of	 these mice is combined	so that	it looks like a	single
	  mouse.  Turning this option on will  enable  MAME  to	 report	 mouse
	  movement and button presses on different mice	independently.

	  The default is OFF (-nomultimouse).

	  Example:

		     mame warlords -multimouse

       -[no]steadykey /	-[no]steady
	  Some	systems	 require  two or more buttons to be pressed at exactly
	  the same time	to make	special	moves.	Due to limitations in the key-
	  board	hardware, it can be difficult or even impossible to accomplish
	  that using the standard keyboard handling.  This  option  selects  a
	  different  handling  that  makes  it easier to register simultaneous
	  button presses, but has the disadvantage of making controls less re-
	  sponsive.

	  The default is OFF (-nosteadykey)

	  Example:

		     mame sf2ua	-steadykey

       -[no]ui_active
	  Enable user interface	on top of emulated keyboard (if	present).

	  The default is OFF (-noui_active)

	  Example:

		     mame apple2e -ui_active

       -[no]offscreen_reload / -[no]reload
	  Controls whether or not MAME treats a	second	button	input  from  a
	  lightgun  as	a  reload  signal.  In this case, MAME will report the
	  gun's	position as (0,MAX) with the trigger held, which is equivalent
	  to an	offscreen reload.

	  This is only needed for games	that required you to  shoot  offscreen
	  to reload, and then only if your gun does not	support	off screen re-
	  loads.

	  The default is OFF (-nooffscreen_reload).

	  Example:

		     mame lethalen -offscreen_reload

       -joystick_map <map> / -joymap <map>
	  Controls  how	 analog	 joystick  values map to digital joystick con-
	  trols.

	  Systems such as Pac-Man use a	4-way digital joystick	and  will  ex-
	  hibit	 undesired  behavior when a diagonal is	triggered; in the case
	  of Pac-Man, movement will stop completely at intersections when  di-
	  agonals  are	triggered  and the game	will be	considerably harder to
	  play correctly.  Many	other arcade cabinets used 4-way or 8-way joy-
	  sticks (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  joy-
	  stick	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  joy-
	  stick	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  di-
	  rection  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
	  Multiple Configuration Files for further details on per-system  con-
	  figuration.

	  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 that
	  matches the picture shown above:
	 +-----------+-------------------------------------------------------+
	 | 777888999 | Note that the numeric digits correspond to the keys   |
	 | 777888999 | on a numeric keypad. So '7' maps	to up+left, '4'	maps |
	 | 777888999 | 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 |
	 | 444555666 | the output the same as the last non-sticky input	sent |
	 | 111222333 | to the system.					     |
	 | 111222333 |							     |
	 | 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:
+-------------------------------------------------------------------------------------------+
| -joymap										    |
| 777888999.777888999.777888999.444555666.444555666.444555666.111222333.111222333.111222333 |
+-------------------------------------------------------------------------------------------+

	  However,  this  can be reduced using several shorthands supported by
	  the <map> parameter.	If information about a row is missing, then it
	  is assumed that any missing data in columns 5-9 are left/right  sym-
	  metric with data in columns 0-4; and any missing data	in columns 0-4
	  is  assumed  to  be copies of	the previous data.  The	same logic ap-
	  plies	to missing rows, except	that up/down symmetry is assumed.

	  By using these shorthands, the 81 character map can be simply	speci-
	  fied by this 11 character string: 7778...4445	(which means  we  then
	  use -joymap 7778...4445)

	  Looking  at  the first row, 7778 is only 4 characters	long.  The 5th
	  entry	can't use symmetry, so it is assumed to	be equal to the	previ-
	  ous character	'8'.  The 6th character	is left/right  symmetric  with
	  the  4th  character, giving an '8'.  The 7th character is left/right
	  symmetric with the 3rd character, giving a '9' (which	 is  '7'  with
	  left/right  flipped).	  Eventually  this  gives  the	full 777888999
	  string of the	row.

	  The second and third rows are	missing, so they  are  assumed	to  be
	  identical to the first row.  The fourth row decodes similarly	to the
	  first	 row,  producing 444555666.  The fifth row is missing so it is
	  assumed to be	the same as the	fourth.

	  The remaining	three rows are also missing, so	they are assumed to be
	  the 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 | For this	mapping, we have a wide	range for the	      |
	 | 4s88888s6 | cardinal	directions on 8, 4, 6, and 2.  We have sticky |
	 | 44s888s66 | on the meeting points between those cardinal	      |
	 | 444555666 | directions where	the appropriate	direction isn't	      |
	 | 444555666 | going to	be completely obvious.			      |
	 | 444555666 |							      |
	 | 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	|
			     +--------------------------+

       -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.

	  The default is 0.15.

	  Example:

		     mame sinistar -joystick_deadzone 0.3

       -joystick_saturation <value> / joy_saturation <value> / -jsat <value>
	  If  you  play	 with an analog	joystick, the ends can drift a little,
	  and may not match in the +/- directions.  joystick_saturation	 tells
	  how  far  along  an  axis movement change will be accepted before it
	  reaches the maximum range.  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.85.

	  Example:

		     mame sinistar -joystick_saturation	1.0

       -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 joystick map is configured, that will take precedence
	  over	this  setting  when  a joysticks main X/Y axes are assigned to
	  digital inputs.

	  The default is 0.3.

	  Example:

		     mame raiden -joystick_threshold 0.2

       -[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, de-
	  pending on your  region,  allowing  compatibility  for  non-"QWERTY"
	  style	keyboards.

	  The default is OFF (-nonatural)

	  In  "emulated	 keyboard"  mode  (the	default	mode), MAME translates
	  pressing/releasing host keys/buttons to emulated  keystrokes.	  When
	  you  press/release  a	 key/button  mapped  to	 an emulated key, MAME
	  presses/releases the emulated	key.

	  In "natural keyboard"	mode, MAME attempts to translate characters to
	  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 has  to  support
	    it.

	   The	 selected  keyboard  layout must match the keyboard layout se-
	    lected in the emulated OS!

	   Keystrokes that dont produce characters cant 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 wont work at all	if IME edit is	involved  (e.g.	 for  Chinese,
	    Japanese or	Korean language	input).

	  Example:

		     mame coco2	-natural

       -[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:

		     mame pc_smb -joystick_contradictory

       -coin_impulse [n]
	  Set coin impulse time	based on n (n<0	 disable  impulse,  n==0  obey
	  driver, 0<n set time n).

	  Default is 0.

	  Example:

		     mame contra -coin_impulse 1

   Core	Input Automatic	Enable Options
       -paddle_device (	none | keyboard	| mouse	| lightgun | joystick )

       -adstick_device ( none |	keyboard | mouse | lightgun | joystick )

       -pedal_device ( none | keyboard | mouse | `lightgun | joystick )

       -dial_device ( none | keyboard |	mouse |	lightgun | joystick )

       -trackball_device ( none	| keyboard | mouse | lightgun |	joystick )

       -lightgun_device	( none | keyboard | mouse | lightgun | joystick	)

       -positional_device ( none | keyboard | mouse | lightgun | joystick )

       -mouse_device ( none | keyboard | mouse | lightgun | joystick )
	  Each	of these options sets whether mouse, joystick or lightgun con-
	  trollers should be enabled when running an emulated system that uses
	  a particular class of	analog inputs.	These options can  effectively
	  set  -mouse, -joystick and/or	-lightgun depending on the type	of in-
	  puts present on the emulated system.	Note that these	 options  will
	  not  override	explicit -nomouse, -nojoystick and/or -nolightgun set-
	  tings	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	speci-
	  fied -nomouse	.

	  The default is to automatically enable mouse controls	 when  running
	  emulated systems with	mouse inputs (-mouse_device mouse).

	  Example:

		     mame sbrkout -paddle_device mouse

       TIP:
	  Note	that  these settings can override -nomouse, -nojoystick	and/or
	  -nolightgun depending	on the inputs present on the emulated system.

   Debugging Options
       -[no]verbose / -[no]v
	  Displays internal diagnostic information. This information  is  very
	  useful for debugging problems	with your configuration.

	  The default is OFF (-noverbose).

	  Example:

		     mame polepos -verbose

       TIP:
	  IMPORTANT:  When reporting bugs to MAMEdev, please run with -verbose
	  and include the resulting information.

       -[no]oslog
	  Output error.log messages to the system diagnostic output, if	one is
	  present.

	  By default messages are sent to the standard error output  (this  is
	  typically  displayed	in  the	 terminal or command prompt window, or
	  saved	to a system log	file).	On Windows, if a debugger is  attached
	  (e.g.	 the  Visual Studio debugger or	WinDbg), messages will be sent
	  to the debugger instead.

	  The default is OFF (-nooslog).

	  Example:

		     mame mappy	-oslog

       -[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 -oslog to output  the	 log  data  to
	  both targets as well.

	  The default is OFF (-nolog).

	  Example 1:

		     mame qbert	-log

	  Example 2:

		     mame qbert	-oslog -log

       -[no]debug
	  Activates  the  integrated debugger.	By default, pressing the back-
	  tick/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 MAME Debugger	 for  informa-
	  tion on using	the debugger.

	  The default is OFF (-nodebug).

	  Example:

		     mame indy_4610 -debug

       -debugger <module>
	  Chooses  the	module to use for debugging the	target system when the
	  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 ma-
		 cOS.

	  imgui	 ImgUi	GUI debugger displayed in first	MAME window.  Requires
		 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 sup-
		 ported.  Use the debugger_port	option to  set	the  listening
		 port  and the debugger_host option to set the address to bind
		 to.  Supported	on all platforms with TCP socket support.

	  Example:

		     mame ambush -debug	-debugger qt

       -debugscript <filename>
	  Specifies a file that	contains a list	of debugger commands  to  exe-
	  cute immediately upon	startup.

	  The default is NULL (no commands).

	  Example:

		     mame galaga -debug	-debugscript testscript.txt

       -[no]update_in_pause
	  Enables  updating  of	 the  main  screen  bitmap while the system is
	  paused.  This	means that the video update callback  will  be	called
	  repeatedly  while  the  emulation is paused, which can be useful for
	  debugging.

	  The default is OFF (-noupdate_in_pause).

	  Example:

		     mame indy_4610 -update_in_pause

       -watchdog <duration> / -wdog <duration>
	  Enables an internal watchdog timer that will automatically kill  the
	  MAME	process	if more	than <duration>	seconds	passes without a frame
	  update.  Keep	in mind	that some systems sit for a while during  load
	  time	without	 updating  the	screen,	 so  <duration>	should be long
	  enough to cover that.

	  10-30	seconds	on a modern system should be plenty in general.

	  By default there is no watchdog.

	  Example:

		     mame ibm_5150 -watchdog 30

       -debugger_host <address>
	  Set the IP address to	listen on to accept GDB	connections when using
	  the GDB stub debugger	module (see the	debugger option).

	  The default is localhost.

	  Example:

		     mame rfjet	-debug -debugger gdbstub -debugger_host	0.0.0.0

       -debugger_port <port>
	  Set the TCP port number to accept GDB	connections on when using  the
	  GDB stub debugger module (see	the debugger option).

	  The default is 23946.

	  Example:

		     mame rfjet	-debug -debugger gdbstub -debugger_port	2159

       -debugger_font <fontname> / -dfont <fontname>
	  Specifies the	name of	the font to use	for debugger windows.
	  The Windows default font is Lucida Console.
	  The Mac (Cocoa) default font is system fixed-pitch font default (typically Monaco).
	  The Qt default font is Courier New.

	  Example:

		     mame marble -debug	-debugger_font "Comic Sans MS"

       -debugger_font_size <points> / -dfontsize <points>
	  Specifies  the  size	of  the	 font  to use for debugger windows, in
	  points.
	  The Windows default size is 9	points.
	  The Qt default size is 11 points.
	  The Mac (Cocoa) default size is the system default size.

	  Example:

		     mame marble -debug	-debugger_font "Comic Sans MS" -debugger_font_size 16

   Core	Communication Options
       -comm_localhost <string>
	  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 ad-
	  dresses).

	  Example:

		     mame arescue -comm_localhost 192.168.1.2

       -comm_localport <string>
	  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.

	  Example:

		     mame arescue -comm_localhost 192.168.1.2 -comm_localport 30100

       -comm_remotehost	<string>
	  Remote   address   to	  connect   to.	 This  can  be	a  traditional
	  xxx.xxx.xxx.xxx address or a string containing  a  resolvable	 host-
	  name.

	  The default is value is "0.0.0.0" (which binds to all	local IPv4 ad-
	  dresses).

	  Example:

		     mame arescue -comm_remotehost 192.168.1.2

       -comm_remoteport	<string>
	  Remote  port	to  connect to.	This can be any	traditional communica-
	  tions	port as	an unsigned 16-bit integer (0-65535).

	  The default value is "15122".

	  Example:

		     mame arescue -comm_remotehost 192.168.1.2 -comm_remoteport	30100

       -[no]comm_framesync
	  Synchronize frames between the communications	network.

	  The default is OFF (-nocomm_framesync).

	  Example:

		     mame arescue -comm_remotehost 192.168.1.3 -comm_remoteport	30100 -comm_framesync

   Core	Misc Options
       -[no]drc
	  Enable DRC (dynamic recompiler) CPU core if  available  for  maximum
	  speed.

	  The default is ON (-drc).

	  Example:

		     mame ironfort -nodrc

       -[no]drc_use_c
	  Force	DRC to use the C code backend.

	  The default is OFF (-nodrc_use_c).

	  Example:

		     mame ironfort -drc_use_c

       -[no]drc_log_uml
	  Write	DRC UML	disassembly log.

	  The default is OFF (-nodrc_log_uml).

	  Example:

		     mame ironfort -drc_log_uml

       -[no]drc_log_native
	  Write	DRC native disassembly log.

	  The default is OFF (-nodrc_log_native).

	  Example:

		     mame ironfort -drc_log_native

       -bios <biosname>
	  Specifies the	specific BIOS to use with the current system, for sys-
	  tems	that 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:

		     mame mslug	-bios unibios33

       -[no]cheat / -[no]c
	  Activates the	cheat menu with	autofire options and other tricks from
	  the cheat database, if present. This also activates  additional  op-
	  tions	on the slider menu for overclocking/underclocking.

	  Be  advised that savestates created with cheats on may not work cor-
	  rectly with this turned off and vice-versa.

	  The default is OFF (-nocheat).

	  Example:

		     mame dkong	-cheat

       -[no]skip_gameinfo
	  Forces MAME to skip displaying the system info screen.

	  The default is OFF (-noskip_gameinfo).

	  Example:

		     mame samsho5 -skip_gameinfo

       -uifont <fontname>
	  Specifies the	name of	a font file to use for the UI  font.  If  this
	  font	cannot be found	or cannot be loaded, the system	will fall back
	  to its built-in UI font. On some platforms fontname can be a	system
	  font name instead of a BDF font file.

	  The default is default (use the OSD-determined default font).

	  Example:

		     mame -uifont "Comic Sans MS"

       -ui <type>
	  Specifies the	type of	UI to use, either simple or cabinet.

	  The default is cabinet (-ui cabinet).

	  Example:

		     mame -ui simple

       -ramsize	[n]
	  Allows you to	change the default RAM size (if	supported by driver).

	  Example:

		     mame coco -ramsize	16K

       -[no]confirm_quit
	  Display a Confirm Quit dialog	to screen on exit, requiring one extra
	  step to exit MAME.

	  The default is OFF (-noconfirm_quit).

	  Example:

		     mame pacman -confirm_quit

       -[no]ui_mouse
	  Displays a mouse cursor when using the built-in MAME user interface.

	  The default is ON (-ui_mouse).

	  Example:

		     mame -ui_mouse

       -language <language>
	  Specify a localization language found	in the languagepath tree.

	  Example:

		     mame -language Japanese

       -[no]nvram_save
	  Save	the  NVRAM contents when exiting machine emulation. By turning
	  this off, you	can retain your	previous NVRAM contents	as any current
	  changes made will not	be saved. Turning this option  off  will  also
	  unconditionally  suppress  the  saving  of .nv files associated with
	  some types of	software cartridges.

	  The default is ON (-nvram_save).

	  Example:

		     mame galaga88 -nonvram_save

   Scripting Options
       -autoboot_command "<command>"
	  Command string to execute after machine boot (in quotes " ").	To is-
	  sue a	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:

		     mame c64 -autoboot_delay 5	-autoboot_command "load	"""$""",8,1\n"

       -autoboot_delay [n]
	  Timer	delay (in seconds) to trigger command execution	on autoboot.

	  Example:

		     mame c64 -autoboot_delay 5	-autoboot_command "load	"""$""",8,1\n"

       -autoboot_script	/ -script [filename.lua]
	  File containing scripting to execute after machine boot.

	  Example:

		     mame ibm5150 -autoboot_script myscript.lua

       -[no]console
	  Enables emulator Lua Console window.

	  The default of OFF (-noconsole).

	  Example:

		     mame ibm5150 -console

       -plugins
	  Enable the use of Lua	Plugins.

	  The default is ON (-plugins).

	  Example:

		     mame apple2e -plugins

       -plugin [plugin shortname]
	  A list of Lua	Plugins	to enable, comma separated.

	  Example:

		     mame alcon	-plugin	cheat,discord,autofire

       -noplugin [plugin shortname]
	  A list of Lua	Plugins	to disable, comma separated.

	  Example:

		     mame alcon	-noplugin cheat

   HTTP	Server Options
       -[no]http
	  Enable HTTP server.

	  The default is OFF (-nohttp).

	  Example:

		     mame -http

       -http_port <port>
	  Choose HTTP server port.

	  The default is 8080.

	  Example:

		     mame apple2 -http -http_port 6502

       -http_root <rootfolder>
	  Choose HTTP server document root.

	  The default is web.

	  Example:

		     mame apple2 -http -http_port 6502 -http_root C:\Users\me\appleweb\root

   PortAudio Options
       -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:

		     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:

		     mame suprmrio -sound portaudio -pa_api "Windows WASAPI"

       -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:

		     mame suprmrio -sound portaudio -pa_api "Windows WASAPI" -pa_device	"NX-EDG27 (NVIDIA High Definition Audio)"

       -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 hard-
	  ware and OS are capable of handling.

	  The default is 0.

	  Example:

		     mame suprmrio -sound portaudio -pa_api "Windows WASAPI" -pa_device	"NX-EDG27 (NVIDIA High Definition Audio)" -pa_latency 0.20

   Windows-Specific Command-line Options
       This section contains configuration options that	are  specific  to  the
       native (non-SDL)	Windows	version	of MAME.

   Performance options
       -priority <priority>
	  Sets the thread priority for the MAME	threads. By default the	prior-
	  ity  is left alone to	guarantee proper cooperation with other	appli-
	  cations. The valid range is -15 to 1,	with 1 being the highest  pri-
	  ority. The default is	0 (NORMAL priority).

       -profile	[n]
	  Enables profiling, specifying	the stack depth	of [n] to track.

   Full	screen options
       -[no]triplebuffer / -[no]tb
	  Enables or disables triple buffering.	 Normally, MAME	just draws di-
	  rectly  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).

       -full_screen_brightness <value> / -fsb <value>
	  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.

       -full_screen_contrast <value> / -fsc <value>
	  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.

       -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.  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.

   Input device	options
       -[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 lightgun	option
	  to be	on and the lightgunprovider option 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 lightgun option, use the default lightgunprovider
	  option of rawinput, and configure each lightgun individually.

	  The default is OFF (-nodual_lightgun).

   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).

   Performance Options
       -[no]sdlvideofps
	  Enable output	of benchmark data on the SDL video subsystem,  includ-
	  ing  your systems video driver, X server (if applicable), and	OpenGL
	  stack	in -video opengl mode.

   Video Options
       -[no]centerh
	  Center horizontally within the view area. Default is ON (-centerh).

       -[no]centerv
	  Center vertically within the view area. Default is ON	(-centerv).

   Video Soft-Specific Options
       -scalemode
	  Scale	mode: none, async, yv12, yuy2,	yv12x2,	 yuy2x2	 (-video  soft
	  only).  Default is none.

   SDL Keyboard	Mapping
       -keymap
	  Enable keymap.  Default is OFF (-nokeymap)

       -keymap_file <file>
	  Keymap file name.  Default is	keymap.dat.

   SDL Input Options
       -enable_touch
	  Enable  support  for	touch  input.  If this option is switched off,
	  mouse	input simulated	from touch devices will	be used	instead.   De-
	  fault	is OFF (-noenable_touch)

       -sixaxis
	  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)

       -[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 lightgun	option
	  to be	on and the lightgunprovider option 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	 acti-
	  vated.   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
       -lightgun_index1	<name>
       -lightgun_index2	<name>
       ...
       -lightgun_index8	<name>

       Device name or ID mapped	to a given lightgun slot.

   SDL Low-level Driver	Options
       -videodriver <driver>
	  SDL video driver to use ('x11', 'directfb', ... or  'auto'  for  SDL
	  default)

       -audiodriver <driver>
	  SDL  audio  driver to	use ('alsa', 'arts', ... or 'auto' for SDL de-
	  fault)

       -gl_lib <driver>
	  Alternative libGL.so to use; 'auto' for system default

   Command-line	Index
       This is a complete index	of all	command-line  options  and  verbs  for
       MAME, suitable for quickly finding a given option.

   Universal Command-line Options
       This  section contains configuration options that are applicable	to all
       MAME configurations (including both SDL and Windows native).

   Core	Verbs
       help
       validate

   Configuration Verbs
       createconfig
       showconfig
       showusage

   Frontend Verbs
       listxml
       listfull
       listsource
       listclones
       listbrothers
       listcrc
       listroms
       listbios
       listsamples
       verifyroms
       verifysamples
       romident
       listdevices
       listslots
       listmedia
       listsoftware
       verifysoftware
       getsoftlist
       verifysoftlist

   OSD-related Options
       uimodekey
       controller_map
       background_input
       uifontprovider
       keyboardprovider
       mouseprovider
       lightgunprovider
       joystickprovider
       midiprovider
       networkprovider

   OSD CLI Verbs
       listmidi
       listnetwork

   OSD Output Options
       output

   Configuration Options
       noreadconfig

   Core	Search Path Options
       homepath
       rompath
       hashpath
       samplepath
       artpath
       ctrlrpath
       inipath
       fontpath
       cheatpath
       crosshairpath
       pluginspath
       languagepath
       swpath

   Core	Output Directory Options
       cfg_directory
       nvram_directory
       input_directory
       state_directory
       snapshot_directory
       diff_directory
       comment_directory

   Core	State/Playback Options
       [no]rewind / rewind
       rewind_capacity
       state
       [no]autosave
       playback
       [no]exit_after_playback
       record
       mngwrite
       aviwrite
       wavwrite
       snapname
       snapsize
       snapview
       [no]snapbilinear
       statename
       [no]burnin

   Core	Performance Options
       [no]autoframeskip
       frameskip
       seconds_to_run
       [no]throttle
       [no]sleep
       speed
       [no]refreshspeed
       numprocessors
       bench
       [no]lowlatency

   Core	Rotation Options
       [no]rotate
       [no]ror
       [no]rol
       [no]autoror
       [no]autorol
       [no]flipx
       [no]flipy

   Core	Video Options
       video
       numscreens
       [no]window
       [no]maximize
       [no]keepaspect
       [no]waitvsync
       [no]syncrefresh
       prescale
       [no]filter
       [no]unevenstretch

   Core	Full Screen Options
       [no]switchres

   Core	Per-Window Video Options
       screen
       aspect
       resolution
       view

   Core	Artwork	Options
       [no]artwork_crop
       fallback_artwork
       override_artwork

   Core	Screen Options
       brightness
       contrast
       gamma
       pause_brightness
       effect

   Core	Vector Options
       beam_width_min
       beam_width_max
       beam_intensity_weight
       beam_dot_size
       flicker

   Core	Video OpenGL Debugging Options
       [no]gl_forcepow2texture
       [no]gl_notexturerect
       [no]gl_vbo
       [no]gl_pbo

   Core	Video OpenGL GLSL Options
       [no]gl_glsl
       gl_glsl_filter
       glsl_shader_mame[0-9]
       glsl_shader_screen[0-9]

   Core	Sound Options
       samplerate
       [no]samples
       [no]compressor
       volume
       sound
       audio_latency

   Core	Input Options
       [no]coin_lockout
       ctrlr
       [no]mouse
       [no]joystick
       [no]lightgun
       [no]multikeyboard
       [no]multimouse
       [no]steadykey
       [no]ui_active
       [no]offscreen_reload
       joystick_map
       joystick_deadzone
       joystick_saturation
       joystick_threshold
       [no]natural
       [no]joystick_contradictory
       coin_impulse

   Core	Input Automatic	Enable Options
       paddle_device
       adstick_device
       pedal_device
       dial_device
       trackball_device
       lightgun_device
       positional_device
       mouse_device

   Core	Debugging Options
       [no]verbose
       [no]oslog
       [no]log
       [no]debug
       debugger
       debugscript
       [no]update_in_pause
       watchdog
       debugger_host
       debugger_port
       debugger_font
       debugger_font_size

   Core	Communication Options
       comm_localhost
       comm_localport
       comm_remotehost
       comm_remoteport
       [no]comm_framesync

   Core	Misc Options
       [no]drc
       [no]drc_use_c
       [no]drc_log_uml
       [no]drc_log_native
       bios
       [no]cheat
       [no]skip_gameinfo
       uifont
       ui
       ramsize
       [no]confirm_quit
       [no]ui_mouse
       language
       [no]nvram_save

   Scripting Options
       autoboot_command
       autoboot_delay
       autoboot_script
       [no]console
       [no]plugins
       plugin
       noplugin

   HTTP	Server Options
       http
       http_port
       http_root

   PortAudio Options
       pa_api
       pa_device
       pa_latency

   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
       priority
       profile

   Windows Full	Screen Options
       [no]triplebuffer
       full_screen_brightness
       full_screen_contrast
       full_screen_gamma

   Windows Input Device	Options
       [no]dual_lightgun

   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
       [no]sdlvideofps

   SDL Video Options
       [no]centerh
       [no]centerv

   SDL Video Soft-Specific Options
       scalemode

   SDL Keyboard	Mapping
       keymap
       keymap_file

   SDL Input Options
       [no]enable_touch
       [no]sixaxis
       [no]dual_lightgun

   SDL Lightgun	Mapping
       lightgun_index

   SDL Low-level Driver	Options
       videodriver
       audiodriver
       gl_lib

PLUGINS
        Introduction

        Using plugins

        Included plugins

   Introduction
       MAME supports plugins that can provide additional functionality.	 Plug-
       ins 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  Lua
       Scripting Interface for more information	about MAMEs Lua	API.

   Using plugins
       To  enable  plugins,  you  need to turn on the plugins option, and make
       sure the	pluginspath option includes the	folder where your plugins  are
       stored.	 You  can set the plugins option in an INI file	or on the com-
       mand line.  You can set the pluginspath option by  selecting  Configure
       Options from the	system selection menu, then selecting Configure	Direc-
       tories,	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  homepath	option
       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 en-
       abled, 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 plugin	option on the command line, or change the set-
       tings 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).

   Included plugins
       MAME includes several plugins providing useful functionality, and serv-
       ing as sample code that you can use as a	starting  point	 when  writing
       your own	plugins.

   Autofire Plugin
        Introduction

        Autofire buttons settings

        Notes and potential pitfalls

   Introduction
       The  autofire plugin allows you to simulate repeatedly pressing an emu-
       lated 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 (ini-
       tially there will be no autofire	buttons	configured).  Select  an  aut-
       ofire  button  to change	settings, or choose Add	autofire button	to set
       up a new	autofire button.  See Autofire buttons 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  homepath option).  A file is created for each	system
       with autofire buttons configured, named according to the	systems	 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 aut-
       ofire folder in your plugin data	folder.	  The  autofire	 settings  are
       stored in JSON format.

   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 youll 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 Konamis Gradius games, P1	Button
       2 is the	primary	fire button.

       Select Hotkey to	set the	control	(or combination	of controls) youll 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,  respec-
       tively.	Adjust the value with the UI Left/Right	keys, or click the ar-
       rows.   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  se-
       lect  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 ef-
       fect immediately.

   Notes and potential pitfalls
       Autofire	buttons	act as if theyre wired in parallel with	MAMEs  regular
       controls.  This means that if you set the activation hotkey for an aut-
       ofire  button to	a button or key	thats also assigned to one of the emu-
       lated 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 aut-
	 ofire hotkey to button	1 as well.  Holding the	button down  to	 shoot
	 will  not  trigger  the autofire effect: the button will never	be re-
	 leased	as youre 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 sys-
       tem.

       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
       weapons effectiveness.  The fire	button must be held  down  to  produce
       all beams.  Some	shooting games (e.g. Raiden Fighters) require the pri-
       mary  fire  button  to be held down for a charged special attack.  This
       means its often necessary to have a non-autofire	input for the  primary
       fire button assigned to play effectively.

   Console Plugin
       The  console  plugin  provides  functionality for MAMEs interactive Lua
       console.	 It is not used	directly.  Use the console option to  activate
       the  interactive	Lua console.  See Lua Scripting	Interface for more in-
       formation about MAMEs Lua API.

   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 se-
       lection menus.  The info	viewer can be shown by	clicking  the  toolbar
       button  on  the system and software selection menus, or by choosing Ex-
       ternal 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 Con-
       figure Directories, and then choose DATs.  You can also set the	histo-
       rypath 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 MASHs MAMEINFO

       messinfo.dat
	      From progetto-SNAPS MESSINFO.dat

       gameinit.dat
	      From progetto-SNAPS GameInit.dat

       command.dat
	      from progetto-SNAPS Command.dat

       score3.htm
	      Top Scores from the MAME Action Replay Page

       Japanese	mameinfo.dat and command.dat
	      From MAME	E2J

       sysinfo.dat
	      From the defunct Progetto	EMMA site

       story.dat
	      From the defunct MAMESCORE site

       If  you	install	hi2txt,	the data plugin	can also show high scores from
       non-volatile memory or saved by the hiscore  support  plugin  for  sup-
       ported 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 homepath option).  This file	stores the in-
       formation from the support files	in a format suitable for  rapid	 load-
       ing.  It	uses the SQLite3 database format.

   Discord Presence Plugin
       The Discord presence plugin works with the Discord app for Windows, ma-
       cOS  or	Linux  to  set your activity to	show what youre	doing in MAME.
       The activity is set to In menu if youre 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.

   Dummy Test Plugin
       This is a sample	plugin that shows how to set  necessary	 plugin	 meta-
       data,  register callbacks, and display a	simple menu.  It prints	status
       messages, and it	adds a Dummy option to the Plugin Options menu.

   GDB Stub Plugin
       The GDB stub plugin acts	as a remote debugging server for the  GNU  de-
       bugger  (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 debugger	option for another GDB remote debugging	implementation
       with support for	more CPUs and configurable listening ports.

   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 coor-
       dination	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 theyre updated in memory.	To change the  setting,	 activate  the
       main  menu  (press  Tab during emulation	by default), select Plugin Op-
       tions, 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 homepath	option).  A file with a	name corresponding the
       system  short name (or ROM set name) with the extension .hi.  For exam-
       ple, 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 set-
       tings  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).

   Input Macro Plugin
        Introduction

        Editing input macros

        Example macros

	  Raiden autofire

	  Track & Field sprint	cheat

	  Street Fighter II Shoryuken

   Introduction
       The input macro plugin allows you to trigger a sequence of emulated in-
       put  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  se-
       quences	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 Editing input	macros for de-
       tails on	editing	input macros.  You can delete an input macro by	 high-
       lighting	 it in the menu	and pressing the UI Clear key (Del/Delete/For-
       ward Delete on the keyboard by default).

       Input macros are	saved in the inputmacro	 folder	 in  the  plugin  data
       folder  (see  the  homepath option).  A file is created for each	system
       with input macros configured, named according to	the systems 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.

   Editing input macros
       The  options for	editing	input macros are the same whether youre	creat-
       ing a new macro or editing an existing macro.  Input macros consist  of
       a sequence of steps.  Each step optionally waits	for a configurable de-
       lay,  then  activates one or more emulated inputs for a specified dura-
       tion.  You can choose what should happen	if the activation sequence  is
       still held when the final step of the macro completes: the emulated in-
       puts 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 isnt being used for any other	emulated input
	 in the	system.

        Set On	release	to specify what	should happen if  the  activation  se-
	 quence	 is released before the	macro completes.  When set to Stop im-
	 mediately, any	emulated inputs	activated by the  macro	 will  be  re-
	 leased	 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 se-
	 quence	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	 acti-
	 vated by the final step of the	macro will remain active until the ac-
	 tivation sequence is released;	when set to Loop to step <n> where <n>
	 is  a step number, macro processing will return to that step, includ-
	 ing 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 emu-
	 lated	inputs will be activated by the	macro.	You can	reset the set-
	 ting 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  in-
	 put  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 cant 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 youd 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  in-
       put 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.

   Example macros
   Raiden autofire
       This provides player 1 autofire functionality using the space bar.  The
       same thing could	be achieved using the Autofire Plugin, but this	demon-
       strates 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 sec-
       ond 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 but-
       ton.  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 re-
       quired to run in	the game.

   Street Fighter II Shoryuken
       This macro allows you to	perform	a right-facing Shryken (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 acti-
       vation sequence holds down the attack button.

   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 MAME Layout Scripting for	an introduction	to layout file
       scripting.

   Timecode Recorder Plugin
       The timecode recorder plugin logs time codes to a text file in conjunc-
       tion  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	record
       and  input_directory  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  plu-
       gin.cfg	in the timecode	folder inside your plugin data folder (see the
       homepath	option).

   Game	Play Timer Plugin
       The timer plugin	records	the total time spent emulating	each  combina-
       tion  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 emu-
       lated time.  The	elapsed	wall  clock  time  may	be  shorter  than  the
       elapsed emulated	time if	you turn off throttling	or use MAMEs fast for-
       ward 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 in-
       side your plugin	data folder (see the homepath option).	The file is  a
       SQLite3 database.

ADVANCED CONFIGURATION
   Multiple Configuration Files
       MAME  has  a very powerful configuration	file system that can allow you
       to tweak	settings on a per-game,	per-system, or even  per-monitor  type
       basis, but requires careful thought about how you arrange your configs.

   Order of Config Loading
       1. The  command	line is	parsed first, and any settings passed that way
	  will take precedence over anything in	an INI file.

       2. mame.ini (or other platform INI; e.g.	 mess.ini)  is	parsed	twice.
	  The  first pass may change various path settings, so the second pass
	  is done to see if there is a valid configuration file	 at  that  new
	  location (and	if so, change settings using that file).

       3. debug.ini  if	 the  debugger is enabled.  This is an advanced	config
	  file,	most people won't need to use it or be concerned by it.

       4. Screen orientation INI file (either horizont.ini  or	vertical.ini).
	  For example Pac-Man has a vertical screen, so	it loads vertical.ini,
	  while	 Street	 Fighter  Alpha	 uses a	horizontal screen, so it loads
	  horizont.ini.

	  Systems with no monitors, multiple monitors with different  orienta-
	  tions, or monitors connected to slot devices will usually load hori-
	  zont.ini.

       5. Monitor  type	 INI  file (vector.ini for vector monitors, raster.ini
	  for CRT raster monitors, or lcd.ini for LCD/EL/plasma	 matrix	 moni-
	  tors).   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.

	  For  systems	that  have  multiple monitor types, such as House Man-
	  nequin with its CRT raster monitor and dual LCD matrix monitors, the
	  INI file relevant to the first monitor is used (raster.ini  in  this
	  case).   Systems  without  monitors  or with other kinds of monitors
	  will not load	an INI file for	this step.

       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 line.

	  For instance,	Banpresto's Sailor Moon, Atlus's Dodonpachi, and Nihon
	  System's Dangun Feveron all run on similar hardware and are  defined
	  in  the  cave.cpp source file, so they will all load source/cave.ini
	  at this step.

       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.

       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.

       9. System INI file.  Using the previous example,	The Last Soldier  will
	  load lastsold.ini.

   Examples of Config Loading Order
        Brix, which is	a clone	of Zzyzzyxx. (mame brix)

	 1. Command line

	 2. mame.ini (global)

	 3. (debugger not enabled, no extra INI	file loaded)

	 4. vertical.ini (screen orientation)

	 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)

	 1. Command line

	 2. mame.ini (global)

	 3. (debugger not enabled, no extra INI	file loaded)

	 4. horizont.ini (screen orientation)

	 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)

	 1. Command line

	 2. mame.ini (global)

	 3. (debugger not enabled, no extra INI	file loaded)

	 4. horizont.ini (screen orientation)

	 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!

   Tricks to Make Life Easier
       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.

   MAME	Path Handling
       MAME  has a specific order it uses when checking	for user files such as
       ROM sets	and cheat files.

   Order of Path Loading
       Let's use an example of the cheat file for AfterBurner 2	for Sega Gene-
       sis/MegaDrive (aburner2 in the megadrive	softlist), and your  cheatpath
       is  set to "cheat" (as per the default) -- this is how MAME will	search
       for that	cheat file:

       1. cheat/megadriv/aburner2.xml

       2. cheat/megadriv.zip ->	aburner2.xml Notice that it checks for a  .ZIP
	  file first before a .7Z file.

       3. cheat/megadriv.zip ->	<arbitrary path>/aburner2.xml It will look for
	  the first (if	any) aburner2.xml file it can find inside that zip, no
	  matter what the path is.

       4. cheat.zip  ->	 megadriv/aburner2.xml	Now it is specifically looking
	  for the file and folder combination, but inside the cheat.zip	file.

       5. cheat.zip -> <arbitrary path>/megadriv/aburner2.xml Like before, ex-
	  cept looking for the first (if any) aburner2.xml inside  a  megadriv
	  folder inside	the zip.

       6. cheat/megadriv.7z -> aburner2.xml Now	we start checking 7ZIP files.

       7. cheat/megadriv.7z -> <arbitrary path>/aburner2.xml

       8. cheat.7z -> megadriv/aburner2.xml

       9. cheat.7z  ->	<arbitrary path>/megadriv/aburner2.xml Similar to zip,
	  except now 7ZIP files.

       [todo: ROM set loading is slightly more complicated,  adding  CRC.  Get
       that documented in the next day or two.]

   Shifter Toggle Disable
       This  is	 an advanced feature for alternative shifter handling for cer-
       tain older arcade machines such as Spy Hunter and Outrun	 that  used  a
       two-way	toggle	switch	for  the  shifter.  By default,	the shifter is
       treated as a toggle switch. One press of	the  mapped  control  for  the
       shifter	will  switch  it  from low to high, and	another	will switch it
       back. This may not be ideal if you have access to  a  physical  shifter
       that  works identically to how the original machines did. (The input is
       on when in one gear, the	input is off otherwise)

       Note that this feature will not help controller users and will not help
       with games that have more than two shifter states (e.g. five  gears  in
       modern racing games)

       This feature is not exposed through the graphical user interface	in any
       way,  as	it is an extremely advanced tweak intended explicitly for peo-
       ple who have this specific need,	have the hardware to take advantage of
       it, and the knowledge to	use it correctly.

   Disabling and Enabling Shifter Toggle
       This example will use the game Spy Hunter (set spyhunt) to  demonstrate
       the exact change	needed:

       You  will  need	to  manually edit the game .CFG	file in	the CFG	folder
       (e.g. spyhunt.cfg)

       Start by	loading	MAME with the game in question.	In our case, that will
       be mame spyhunt.

       Set up the controls as you would	please,	including mapping the shifter.
       Exit MAME, open the .cfg	file in	your text editor of choice.

       Inside the spyhunt.cfg file, you	will find the following	for the	input.
       The actual input	code in	the middle can and will	vary depending on  the
       controller number and what input	you have mapped.
       <port tag=":ssio:IP0" type="P1_BUTTON2" mask="16" defvalue="16">
	 <newseq type="standard">
	   JOYCODE_1_RYAXIS_NEG_SWITCH OR JOYCODE_1_RYAXIS_POS_SWITCH
	 </newseq>
       </port>

       The line	you need to edit will be the port line defining	the actual in-
       put.  For Spy Hunter, that's going to be	P1_BUTTON2. Add	toggle="no" to
       the end of the tag, like	follows:
       <port tag=":ssio:IP0" type="P1_BUTTON2" mask="16" defvalue="16" toggle="no">
	 <newseq type="standard">
	   JOYCODE_1_RYAXIS_NEG_SWITCH OR JOYCODE_1_RYAXIS_POS_SWITCH
	 </newseq>
       </port>

       Save and	exit. To disable this, simply remove the toggle="no" from each
       desired .CFG input.

   BGFX	Effects	for (nearly) Everyone
        Introduction

        Resolution and	Aspect Ratio

        Getting Started with BGFX

        Configuration Settings

        Tweaking BGFX HLSL Settings inside MAME

        Using the included pillarbox filters

   Introduction
       By default, MAME	outputs	an idealized version of	the video as it	 would
       be on the way to	the arcade cabinets 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.

       Thats 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 re-
       quires some effort on the users part: the settings you use are going to
       be tailored to your PCs system specs, and especially the	monitor	 youre
       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	guide-
       lines 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 caused by your monitor upscaling the dis-
       play image.

       While  most arcade machines used	a 4:3 ratio display (or	3:4 for	verti-
       cally oriented monitors like Pac-Man), its difficult to find a consumer
       display that is 4:3 at this point.  The good news is  that  that	 extra
       space  on  the sides isnt wasted.  Many arcade cabinets used bezel art-
       work 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 12801024 and	were a
       5:4 aspect ratio.  Theres not enough extra space	 to  display  artwork,
       and  youll  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 dont need to download any addi-
       tional files.

       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.

       As explained in Order of	Config Loading,	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 MAMEs configuration files, youll
       want to copy the	BGFX settings from mame.ini to one of the  other  con-
       figuration files	and make changes there.

       In  particular,	you will want the bgfx_screen_chains to	be specific to
       each game.

       Save your INI file(s) and youre 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 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 se-
	      lection 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 com-
		patible	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 ba-
	      sis.  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 well  call
	      a	screen)	and output windows or monitors (which well call	a win-
	      dow,  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	multi-
	      ple 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, well 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
       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  al-
       low  you	to change that setting.	 Results will be shown in real time as
       youre 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

       For systems using 3:4 vertical monitors,	use these options:

	  -override_artwork bgfx/border_blur -view Vertical -bgfx_screen_chains	crt-geom,pillarbox_left_vertical,pillarbox_right_vertical

        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 youve previously changed the view for the system in	MAME, the cor-
	 rect 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  cer-
	 tain systems automatically (e.g. horizont.ini or vertical.ini,	or the
	 INI file for a	specific system).

   HLSL	Effects	for Windows
       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  modifica-
       tion of the output (primarily to	stretch	the game image back to the as-
       pect  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 signifi-
       cantly.

       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 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 re-
       quires 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	 moni-
       tors  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	 addi-
       tional distortion and lag created by your monitor upscaling the display
       image.

       While  most arcade machines used	a 4:3 ratio display (or	3:4 for	verti-
       cally oriented monitors like Pac-Man), it's difficult to	 find  a  con-
       sumer display that is 4:3 at this point.	The good news is that that ex-
       tra  space  on  the sides isn't wasted. Many arcade cabinets used bezel
       artwork around the main display,	and should you have the	necessary art-
       work files, MAME	will display that artwork. Turn	the  artwork  view  to
       Cropped for best	results.

       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.

   Getting Started with	HLSL
       You will	need to	have followed  the  initial  MAME  setup  instructions
       elsewhere  in this manual before	beginning. Official MAME distributions
       include HLSL by default,	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:

        video d3d

        filter	0

       The former is required because HLSL requires Direct3D support. The lat-
       ter turns off extra filtering that interferes with HLSL output.

       Lastly, one more	edit will turn HLSL on:

        hlsl_enable 1

       Save the	.INI file and you're ready to begin.

       Several presets have been included in the INI folder with MAME,	allow-
       ing for good quick starting points for Nintendo Game Boy, Nintendo Game
       Boy Advance, Raster, and	Vector monitor settings.

   Tweaking HLSL Settings inside MAME
       For  multiple,  complicated  to	explain	 reasons, HLSL settings	are no
       longer saved when you exit MAME.	This means that	 while	tweaking  set-
       tings  is a little more work on your part, the results will always come
       out as expected.

       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 al-
       low you to change that setting. Results will be shown in	real  time  as
       you're changing these settings.

       Once  you've  found  settings  you  like,  write	 the numbers down on a
       notepad and exit	MAME.

   Configuration Editing
       As referenced in	Order of Config	Loading, MAME has a order in which  it
       processes  INI  files. The HLSL 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 HLSL	settings from mame.ini to  one	of  the	 other	config
       files and make changes there.

       For instance, once you've found HLSL settings you think are appropriate
       for  Neo	 Geo games, you	can put	those settings into neogeo.ini so that
       all Neo-Geo games will be able to  take	advantage  of  those  settings
       without needing to add it to every game INI manually.

   Configuration Settings
       hlslpath

	 This is where your HLSL files are stored. By default, this will be the	HLSL folder in your MAME installation.

       hlsl_snap_width
       hlsl_snap_height

	 Sets the resolution that Alt+F12 HLSL screenshots are output at.

       shadow_mask_alpha (Shadow Mask Amount)

	 This defines how strong the effect of the shadowmask is. Acceptable range is from 0 to	1, where 0 will	show no	shadowmask effect, 1 will be a completely opaque shadowmask, and 0.5 will be 50% transparent.

       shadow_mask_tile_mode (Shadow Mask Tile Mode)

	 This defines whether the shadowmask should be tiled based on the screen resolution of your monitor or based on	the source resolution of the emulated system. Valid values are 0 for Screen mode and 1 for Source mode.

       shadow_mask_texture
       shadow_mask_x_count (Shadow Mask	Pixel X	Count)
       shadow_mask_y_count (Shadow Mask	Pixel Y	Count)
       shadow_mask_usize (Shadow Mask U	Size)
       shadow_mask_vsize (Shadow Mask V	Size)
       shadow_mask_x_count (Shadow Mask	U Offset)
       shadow_mask_y_count (Shadow Mask	V Offset)

	 These settings	need to	be set in unison with one another. In particular, shadow_mask_texture sets rules for how you need to set the other options.

	 shadow_mask_texture sets the texture of the shadowmask	effect.	Three shadowmasks are included with MAME: aperture-grille.png, shadow-mask.png,	and slot-mask.png

	 shadow_mask_usize and shadow_mask_vsize define	the used size of the shadow_mask_texture in percentage,	staring	at the top-left	corner.	The means for a	texture	with the actual	size of	24x24 pixel and	an u/v size of 0.5,0.5 the top-left 12x12 pixel	will be	used. Keep in mind to define an	u/v size that makes is possible	to tile	the texture without gaps or glitches. 0.5,0.5 is fine for any shadowmask texture that is included with MAME.

	 shadow_mask_x_count and shadow_mask_y_count define how	many screen pixel should be used to display the	u/v sized texture. e.g.	if you use the example from above and define a x/y count of 12,12 every	pixel of the texture will be displayed 1:1 on the screen, if you define	a x/y count of 24,24 the texture will be displayed twice as large.

       example settings	for shadow_mask.png:

	 shadow_mask_texture shadow-mask.png
	 shadow_mask_x_count 12
	 shadow_mask_y_count 6 or 12
	 shadow_mask_usize 0.5
	 shadow_mask_vsize 0.5

       example settings	for slot-mask.png:

	 shadow_mask_texture slot-mask.png
	 shadow_mask_x_count 12
	 shadow_mask_y_count 8 or 16
	 shadow_mask_usize 0.5
	 shadow_mask_vsize 0.5

       example settings	for aperture-grille:

	 shadow_mask_texture aperture-grille.png
	 shadow_mask_x_count 12
	 shadow_mask_y_count 12	or any
	 shadow_mask_usize 0.5
	 shadow_mask_vsize 0.5

	 shadow_mask_uoffset and shadow_mask_voffset can be used to tweak the alignment	of the final shadowmask	in subpixel range. Range is from -1.00 to 1.00,	where 0.5 moves	the shadowmask by 50 percent of	the u/v	sized texture.

       distortion (Quadric Distortion Amount)

	 This setting determines strength of the quadric distortion of the screen image.

       cubic_distortion	(Cubic Distortion Amount)

	   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

       distort_corner (Distorted Corner	Amount)

	 This setting determines strength of distortion	of the screen corners, which does not affect the distortion of screen image itself.

       round_corner (Rounded Corner Amount)

	 The corners of	the display can	be rounded off through the use of this setting.

       smooth_border (Smooth Border Amount)

	 Sets a	smoothened/blurred border around the edges of the screen.

       reflection (Reflection Amount)

	 If set	above 0, this creates a	white reflective blotch	on the display.	By default, this is put	in the upper right corner of the display. By editing the POST.FX file's	GetSpotAddend section, you can change the location. Range is from 0.00 to 1.00.

       vignetting (Vignetting Amount)

	 When set above	0, will	increasingly darken the	outer edges of the display in a	pseudo-3D effect. Range	is from	0.00 to	1.00.

       scanline_alpha (Scanline	Amount)

	 This defines how strong the effect of the scanlines are. Acceptable range is from 0 to	1, where 0 will	show no	scanline effect, 1 will	be a completely	black line, and	0.5 will be 50%	transparent. Note that arcade monitors did not have completely black scanlines.

       scanline_size (Overall Scanline Scale)

	 The overall spacing of	the scanlines is set with this option. Setting it at 1 represents consistent alternating spacing between display lines and scanlines.

       scanline_height (Individual Scanline Scale)

	 This determines the overall size of each scanline. Setting lower than 1 makes them thinner, larger than 1 makes them thicker.

       scanline_variation (Scanline Variation)

	 This affects the size of each scanline	depending on its brightness. Brighter scanlines	will be	thicker	than darker scanline. Acceptable range is from 0 to 2.0, with the default being	1.0. At	0.0 all	scanlines will have the	same size independent of their brightness.

       scanline_bright_scale (Scanline Brightness Scale)

	 Specifies how bright the scanlines are. Larger	than 1 will make them brighter,	lower will make	them dimmer. Setting to	0 will make scanlines disappear	entirely.

       scanline_bright_offset (Scanline	Brightness Offset)

	 This will give	scanlines a glow/overdrive effect, softening and smoothing the top and bottom of each scanline.

       scanline_jitter (Scanline Jitter	Amount)

	 Specifies the wobble or jitter	of the scanlines, causing them to jitter on the	monitor. Warning: Higher settings may hurt your	eyes.

       hum_bar_alpha (Hum Bar Amount)

	 Defines the strength of the hum bar effect.

       defocus (Defocus)

	 This option will defocus the display, blurring	individual pixels like an extremely badly maintained monitor. Specify as X,Y values (e.g. defocus 1,1)

       converge_x (Linear Convergence X, RGB)
       converge_y (Linear Convergence Y, RGB)
       radial_converge_x (Radial Convergence X,	RGB)
       radial_converge_y (Radial Convergence Y,	RGB)

	 Adjust	the convergence	of the red, green, and blue channels in	a given	direction. Many	badly maintained monitors with bad convergence would bleed colored ghosting off-center of a sprite, and	this simulates that.

       red_ratio (Red Output from RGB)
       grn_ratio (Green	Output from RGB)
       blu_ratio (Blue Output from RGB)

	 Defines a 3x3 matrix that is multiplied with the RGB signals to simulate color	channel	interference. For instance, a green channel of (0.100, 1.000, 0.250) is	weakened 10% by	the red	channel	and strengthened 25% through the blue channel.

       offset (Signal Offset)

	 Strengthen or weakens the current color value of a given channel. For instance, a red signal of 0.5 with an offset of 0.2 will	be raised to 0.7

       scale (Signal Scale)

	 Applies scaling to the	current	color value of the channel. For	instance, a red	signal of 0.5 with a scale of 1.1 will result in a red signal of 0.55

       power (Signal Exponent, RGB)

	 Exponentiate the current color	value of the channel, also called gamma. For instance, a red signal of 0.5 with	red power of 2 will result in a	red signal of 0.25

	 This setting also can be used to adjust line thickness	in vector games.

       floor (Signal Floor, RGB)

	 Sets the absolute minimum color value of a channel. For instance, a red signal	of 0.0 (total absence of red) with a red floor of 0.2 will result in a red signal of 0.2

	 Typically used	in conjunction with artwork turned on to make the screen have a	dim raster glow.

       phosphor_life (Phosphor Persistence, RGB)

	 How long the color channel stays on the screen, also called phosphor ghosting.	0 gives	absolutely no ghost effect, and	1 will leave a contrail	behind that is only overwritten	by a higher color value.

	 This also affects vector games	quite a	bit.

       saturation (Color Saturation)

	 Color saturation can be adjusted here.

       bloom_blend_mode	(Bloom Blend Mode)

	 Determines the	mode of	the bloom effect. Valid	values are 0 for Brighten mode and 1 for Darken	mode, last is only useful for systems with STN LCD.

       bloom_scale (Bloom Scale)

	 Determines the	intensity of bloom effect. Arcade CRT displays had a tendency towards bloom, where bright colors could bleed out into neighboring pixels. This effect is extremely graphics card intensive, and	can be turned completely off to	save GPU power by setting it to	0

       bloom_overdrive (Bloom Overdrive, RGB)

	 Sets a	RGB color, separated by	commas,	that has reached the brightest possible	color and will be overdriven to	white. This is only useful on color raster, color LCD, or color	vector games.

       bloom_lvl0_weight (Bloom	Level 0	Scale)
       bloom_lvl1_weight (Bloom	Level 1	Scale)
	 .  .  .  .
       bloom_lvl7_weight (Bloom	Level 7	Scale)
       bloom_lvl8_weight (Bloom	Level 8	Scale)

	 These define the bloom	effect.	Range is from 0.00 to 1.00. If used carefully in conjunction with phosphor_life, glowing/ghosting for moving objects can be achieved.

       hlsl_write

	 Enables writing of an uncompressed AVI	video with the HLSL effects included with set to 1. This uses a	massive	amount of disk space very quickly, so a	large HD with fast write speeds	is highly recommended. Default is 0, which is off.

       Suggested defaults for raster-based games:

+----------------------------+----------------------+---------------------------------+
| bloom_lvl0_weight	1.00 | Bloom level 0 weight | Full-size	target.		      |
| bloom_lvl1_weight	0.64 | Bloom level 1 weight | 1/4 smaller that level 0 target |
| bloom_lvl2_weight	0.32 | Bloom level 2 weight | 1/4 smaller that level 1 target |
| bloom_lvl3_weight	0.16 | Bloom level 3 weight | 1/4 smaller that level 2 target |
| bloom_lvl4_weight	0.08 | Bloom level 4 weight | 1/4 smaller that level 3 target |
| bloom_lvl5_weight	0.06 | Bloom level 5 weight | 1/4 smaller that level 4 target |
| bloom_lvl6_weight	0.04 | Bloom level 6 weight | 1/4 smaller that level 5 target |
| bloom_lvl7_weight	0.02 | Bloom level 7 weight | 1/4 smaller that level 6 target |
| bloom_lvl8_weight	0.01 | Bloom level 8 weight | 1/4 smaller that level 7 target |
+----------------------------+----------------------+---------------------------------+

   Vector Games
       HLSL effects can	also be	used with vector games.	Due to a wide variance
       of  vector settings to optimize for each	individual game, it is heavily
       suggested you add these to per-game INI files (e.g. tempest.ini)

       Shadowmasks were	only present on	color vector games, and	should not  be
       used on monochrome vector games.	Additionally, vector games did not use
       scanlines, so that should also be turned	off.

       Open  your  INI	file in	your text editor of choice (e.g. Notepad), and
       make sure the following options are set correctly:

        video d3d

        filter	0

        hlsl_enable 1

       In the Core Vector Options section:

        beam_width_min	1.0 (Beam Width	Minimum)

        beam_width_max	1.0 (Beam Width	Maximum)

        beam_intensity_weight 0.0 (Beam Intensity Weight)

        flicker 0.0 (Vector Flicker)

       In the Vector Post-Processing Options section:

        vector_beam_smooth 0.0	(Vector	Beam Smooth Amount)

        vector_length_scale 0.5 (Vector Attenuation Maximum)

        vector_length_ratio 0.5 (Vector Attenuation Length Minimum)

       Suggested settings for vector games:

        bloom_scale should typically be set  higher  for  vector  games  than
	 raster	games. Try between 0.4 and 1.0 for best	effect.

        bloom_overdrive should	only be	used with color	vector games.

        bloom_lvl_weights should be set as follows:
+----------------------------+----------------------+---------------------------------+
| bloom_lvl0_weight	1.00 | Bloom level 0 weight | Full-size	target.		      |
| bloom_lvl1_weight	0.48 | Bloom level 1 weight | 1/4 smaller that level 0 target |
| bloom_lvl2_weight	0.32 | Bloom level 2 weight | 1/4 smaller that level 1 target |
| bloom_lvl3_weight	0.24 | Bloom level 3 weight | 1/4 smaller that level 2 target |
| bloom_lvl4_weight	0.16 | Bloom level 4 weight | 1/4 smaller that level 3 target |
| bloom_lvl5_weight	0.24 | Bloom level 5 weight | 1/4 smaller that level 4 target |
| bloom_lvl6_weight	0.32 | Bloom level 6 weight | 1/4 smaller that level 5 target |
| bloom_lvl7_weight	0.48 | Bloom level 7 weight | 1/4 smaller that level 6 target |
| bloom_lvl8_weight	0.64 | Bloom level 8 weight | 1/4 smaller that level 7 target |
+----------------------------+----------------------+---------------------------------+

   GLSL	Effects	for *nix, OS X,	and Windows
       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  modifica-
       tion of the output (primarily to	stretch	the game image back to the as-
       pect  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 signifi-
       cantly.

       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 GLSL comes into the	picture.

       GLSL simulates most of the effects that a CRT arcade monitor has	on the
       video,  making  the result look a lot more authentic. However, GLSL re-
       quires 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	 moni-
       tors  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 GLSL settings. You will want
       MAME to be using	the native resolution of your monitor to  avoid	 addi-
       tional distortion and lag created by your monitor upscaling the display
       image.

       While  most arcade machines used	a 4:3 ratio display (or	3:4 for	verti-
       cally oriented monitors like Pac-Man), it's difficult to	 find  a  con-
       sumer display that is 4:3 at this point.	The good news is that that ex-
       tra  space  on  the sides isn't wasted. Many arcade cabinets used bezel
       artwork around the main display,	and should you have the	necessary art-
       work files, MAME	will display that artwork. Turn	the  artwork  view  to
       Cropped for best	results.

       Some older LCD displays used a native resolution	of 1280x1024, which is
       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 on-par with a 4:3 monitor.

   Getting Started with	GLSL
       You  will  need	to  have  followed the initial MAME setup instructions
       elsewhere in this manual	before beginning. Official MAME	 distributions
       include	GLSL  support  by  default, but	do NOT include the GLSL	shader
       files. You will need to obtain the shader files from third party	online
       sources.

       Open your mame.ini in your text editor of choice	 (e.g.	Notepad),  and
       make sure the following options are set correctly:

        video opengl

        filter	0

       The former is required because GLSL requires OpenGL support. The	latter
       turns off extra filtering that interferes with GLSL output.

       Lastly, one more	edit will turn GLSL on:

        gl_glsl 1

       Save the	.INI file and you're ready to begin.

   Tweaking GLSL Settings inside MAME
       For  multiple,  complicated  to	explain	 reasons, GLSL settings	are no
       longer saved when you exit MAME.	This means that	 while	tweaking  set-
       tings  is a little more work on your part, the results will always come
       out as expected.

       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 al-
       low you to change that setting. Results will be shown in	real  time  as
       you're changing these settings.

       Once  you've  found  settings  you  like,  write	 the numbers down on a
       notepad and exit	MAME.

   Configuration Editing
       As referenced in	Order of Config	Loading, MAME has a order in which  it
       processes  INI  files. The GLSL 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 GLSL	settings from mame.ini to  one	of  the	 other	config
       files and make changes there.

       For instance, once you've found GLSL settings you think are appropriate
       for  Neo	 Geo games, you	can put	those settings into neogeo.ini so that
       all Neo-Geo games will be able to  take	advantage  of  those  settings
       without needing to add it to every game INI manually.

   Configuration Settings
       gl_glsl

	 Enables GLSL when set to 1, disabled if set to	0. Defaults to 0.

       gl_glsl_filter

	 Enables filtering to GLSL output. Reduces jagginess at	the cost of blurriness.

       glsl_shader_mame0
	 ...
       glsl_shader_mame9

	 Specifies the shaders to run, in the order from 0 to 9. See your shader pack author for details on which to run in which order	for best effect.

       glsl_shader_screen0
	 ...
       glsl_shader_screen9

	 Specifies screen to apply the shaders on.

   Controller Configuration Files
        Introduction

        Basic structure

        Substituting default controls

        Overriding defaults by	input type

        Overriding defaults for specific inputs

        Assigning input device	numbers

        Setting pointer input options

   Introduction
       Controller  configuration files can be used to modify MAMEs default in-
       put 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 ctrlrpath	option.	 A  controller
       configuration file is selected by setting the ctrlr option to its file-
       name,  excluding	the .cfg extension (e.g. set the ctrlr option to scor-
       pionxg to use scorpionxg.cfg).  It is an	error if  the  specified  con-
       troller	configuration  file  does not exist, or	if it contains no sec-
       tions applicable	to the emulated	system.

       Controller configuration	files use implementation-dependent  input  to-
       kens.   The  values  available and their	precise	meanings depend	on the
       exact version of	MAME used, the input devices connected,	 the  selected
       input  provider	modules	 (keyboardprovider,  mouseprovider,  lightgun-
       provider	and joystickprovider options), and possibly other settings.

   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
       cfg_directory  option).	 This example shows the	overall	structure of a
       controller configuration	file:

	  <?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  ele-
       ment, with a version attribute specifying the configuration format ver-
       sion  (currently	 10   MAME will	not load a file	using a	different ver-
       sion).  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  ap-
	 plied (including for the system/software selection menus).

        If  the  value	 of the	name attribute matches the systems 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 sys-
       tem 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.

   Substituting	default	controls
       You can use a remap element to substitute one host input	for another in
       MAMEs default input configuration.  For example,	this substitutes  keys
       on the numeric keypad for the cursor direction keys:

	  <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  re-
       placement  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 MAMEs default assignment	for the	input type.  That  is,
       they only apply to default assignments for control types	set in the In-
       put  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.

   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:

	  <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  MAMEs  default  as-
       signment	 for  the  input type.	That is, port elements without tag at-
       tributes	only override default assignments for control types set	in the
       Input Assignments (general) menus.  They	do not override	 default  con-
       trol  assignments  set in driver/device I/O port	definitions (using the
       PORT_CODE macro).

       MAME applies port elements without tag attributes found inside any  ap-
       plicable	system element.

   Overriding defaults for specific inputs
       Use port	elements with tag, type, mask and defvalue attributes to over-
       ride defaults for specific inputs.  These port elements should only oc-
       cur  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 in-
       put.  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 cfg_directory option).  Note	that these values are  not  guaranteed
       to be stable, and may change between MAME versions.

       Heres an	example	that overrides defaults	for 280-ZZZAP:

	  <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, re-
       spectively, and disables	the toggle setting for the gear	shift input.

   Assigning input device numbers
       Use  mapdevice elements with device and controller attributes to	assign
       stable numbers to input devices.	 Note that all devices explicitly con-
       figured 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).

       Heres  an  example  numbering  two  light guns and two XInput game con-
       trollers:

	  <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  sys-
       tem element only.  To avoid confusion, its 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.

   Setting pointer input options
       A pointer_input element may contain target elements to set pointer  in-
       put 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  sec-
       onds, 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 in-
       active  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.

       Heres an	example	demonstrating the use of this feature:

	  <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.

   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  num-
       bers can	be quite unpredictable.

       This  is	 where the mapdevice configuration setting comes into the pic-
       ture.  By adding	this setting to	a controller configuration  file,  you
       can ensure that a given input device is always assigned the same	number
       in MAME.

   Using mapdevice
       The mapdevice XML element is added to the input XML element in the con-
       troller configuration file. It requires two attributes, device and con-
       troller.	  Note	that  mapdevice	 elements only take effect in the con-
       troller configuration file (set using the -ctrlr	option)	 they are  ig-
       nored in	system configuration files and the default configuration 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 de-
       vice ID for an input device, select it in the Input Devices  menu,  and
       then  select Copy Device	ID.  The device	ID will	be copied to the clip-
       board.  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 de-
       vice, selected input provider module and	operating system.  Your	 input
       device IDs may look very	different to the examples here.

       The controller attribute	specifies the input token for the input	device
       type (i.e. JOYCODE, GUNCODE, MOUSECODE) and number to assign to the de-
       vice,  separated	by an underscore.  Numbering starts from 1.  For exam-
       ple the token for the first joystick device will	be JOYCODE_1, the sec-
       ond will	be JOYCODE_2, and so on.

   Example
       Heres an	example:
       <mameconfig version="10">
	 <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"	/>

	     <port type="P1_JOYSTICK_UP">
	       <newseq type="standard">
		 JOYCODE_1_YAXIS_UP_SWITCH OR KEYCODE_8PAD
	       </newseq>
	     </port>
	     ...

       In the above example, we	have four device mappings specified:

        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.

   Listing Available Devices
       There are two ways to obtain device IDs:	by copying them	from the Input
       Devices menu, or	by turning on verbose logging 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 de-
       vices menu from the main	menu, 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 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 joystick #1: ATRAK	Device #1 (device id: ATRAK Device #1)
       Skipping	DirectInput for	XInput compatible joystick Controller (XBOX 360	For Windows).
       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 reassigned	using  mapdevice  elements  in
       the  controller	configuration  file, youll see that in the verbose log
       output, too, such as:
       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 de-
       vices that are connected	may not	be numbered as expected.

   Linux Lightguns
       Many lightguns (especially the Ultimarc AimTrak)	 may  work  better  in
       MAME  under Linux when using a slightly more complicated	configuration.
       The instructions	here are for getting an	AimTrak	working	on Ubuntu  us-
       ing udev	and Xorg, but other Linux distributions	and lightguns may work
       with some changes to the	steps.

   Configure udev rules
       For  the	 AimTrak,  each	lightgun exposes several USB devices once con-
       nected: 2 mouse emulation devices, and 1	joystick emulation device.  We
       need  to	 instruct libinput via udev to ignore all but the correct emu-
       lated mouse device. This	prevents each lightgun from producing multiple
       mouse devices, which would result in  non-deterministic	selection  be-
       tween the "good"	and "bad" emulated mouse devices by Xorg.

       Create  a  new  file named /etc/udev/rules.d/65-aimtrak.rules and place
       the following contents into it:
       # Set mode (0666) & disable libinput handling to	avoid X11 picking up the wrong
       # interfaces/devices.
       SUBSYSTEMS=="usb", ATTRS{idVendor}=="d209", ATTRS{idProduct}=="160*",
	 MODE="0666", ENV{ID_INPUT}="",	ENV{LIBINPUT_IGNORE_DEVICE}="1"

       # For ID_USB_INTERFACE_NUM==2, re-enable	libinput handling.
       SUBSYSTEMS=="usb", ATTRS{idVendor}=="d209", ATTRS{idProduct}=="160*",
	 ENV{ID_USB_INTERFACE_NUM}=="02", ENV{ID_INPUT}="1",
	 ENV{LIBINPUT_IGNORE_DEVICE}="0"

       This configuration will be correct for the AimTrak  lightguns,  however
       each brand of lightgun will require their own settings.

   Configure Xorg inputs
       Next,  we'll  configure Xorg to treat the lightguns as a	"Floating" de-
       vice. This is important for multiple lightguns to  work	correctly  and
       ensures	each  gun's emulated mouse pointer is NOT merged with the main
       system mouse pointer.

       In /etc/X11/xorg.conf.d/60-aimtrak.conf we will need:
       Section "InputClass"
	 Identifier "AimTrak Guns"
	 MatchDevicePath "/dev/input/event*"
	 MatchUSBID "d209:160*"
	 Driver	"libinput"
	 Option	"Floating" "yes"
	 Option	"AutoServerLayout" "no"
       EndSection

   Configure MAME
       Next, we'll need	to configure MAME via mame.ini to use the new lightgun
       device(s).

        lightgun 1

        lightgun_device lightgun

        lightgunprovider x11

       These first three lines tell MAME to enable lightgun support,  to  tell
       MAME that we're using a lightgun	instead	of a mouse, and	to use the x11
       provider.

        lightgun_index1 "Ultimarc ATRAK Device	#1"

        lightgun_index2 "Ultimarc ATRAK Device	#2"

        lightgun_index3 "Ultimarc ATRAK Device	#3"

        lightgun_index4 "Ultimarc ATRAK Device	#4"

       These  next  lines  then	 tell MAME to keep lightguns consistent	across
       sessions.

        offscreen_reload 1

       Lastly, as most lightgun	games require offscreen	 reloading  and	 we're
       using  a	device that actually can point away from the screen, we	enable
       that functionality.

MAME DEBUGGER
        Introduction

        Debugger commands

        Specifying devices and	address	spaces

        Debugger expression syntax

	  Numbers

	  Boolean values

	  Memory accesses

	  Functions

   Introduction
       MAME includes an	interactive low-level debugger that targets  the  emu-
       lated  system.	This can be a useful tool for diagnosing emulation is-
       sues, 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 ac-
       tivated.	 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 pro-
       vide  a	multi-window  interface	for viewing the	contents of memory and
       disassembled code.

       The debugger console window is a	special	window that shows the contents
       of CPU registers	and  disassembled  code	 around	 the  current  program
       counter	address,  and provides a command-line interface	to most	of the
       debugging functionality.

   Debugger 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.

   General Debugger Commands
       help   displays built-in	help in	the console

       do     evaluates	the given expression

       symlist
	      lists registered symbols

       softreset
	      executes a soft reset

       hardreset
	      executes a hard reset

       print  prints one or more <item>s to the	console

       printf prints one or more <item>s to the	console	using <format>

       logerror
	      outputs one or more <item>s to the error.log

       tracelog
	      outputs one or more <item>s to the trace file using <format>

       tracesym
	      outputs one or more <item>s to the trace file

       history
	      displays recently	visited	PC addresses and opcodes

       trackpc
	      visually track visited opcodes

       trackmem
	      record which PC writes to	each memory address

       pcatmem
	      query which PC wrote to a	given memory address

       rewind go back in time by loading the most recent rewind	state

       statesave
	      save a state file	for the	emulated system

       stateload
	      load a state file	for the	emulated system

       snap   save a screen snapshot

       source read commands from file and executes them	one by one

       time   prints the current machine time to the console

       quit   exit the debugger	and end	the emulation session

   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:

       help   Lists top-level help topics.

       help expressions
	      Displays built-in	help for debugger expression syntax.

       help wpiset
	      Displays built-in	help for the wpiset command.

       Back to General Debugger	Commands

   do
       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 Debugger expression syntax for details about ex-
       pression	syntax.

       Examples:

       do pc = 0
	      Sets the register	pc to 0.

       Back to General Debugger	Commands

   symlist
       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	alpha-
       betically.   Read-only  symbols	are noted.  See	Specifying devices and
       address spaces 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 General Debugger	Commands

   softreset
       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 General Debugger	Commands

   hardreset
       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.

       Examples:

       hardreset
	      Executes a hard reset.

       Back to General Debugger	Commands

   print
       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 General Debugger	Commands

   printf
       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 op-
	      tional left justification, zero fill and minimum field width.

       %[-][0][<n>]o
	      Prints the corresponding argument	as an octal  number  with  op-
	      tional 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 ad-
	      dress  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  sec-
	      ond line.

       Back to General Debugger	Commands

   logerror
       logerror	<format>[,<argument>[,]]

       Prints  a  C-style  formatted message to	the error log.	See 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 General Debugger	Commands

   tracelog
       tracelog	<format>[,<argument>[,]]

       Prints  a  C-style  formatted  message to the currently open trace file
       (see trace for more information).  If no	trace file is open, this  com-
       mand  has  no  effect.  See 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 sec-
	      ond line if a trace log file is open.

       Back to General Debugger	Commands

   tracesym
       tracesym	<item>[,]

       Prints  the  specified  symbols	to  the	currently open trace file (see
       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 General Debugger	Commands

   history
       history [<CPU>[,<length>]]

       Displays	recently visited PC addresses, and disassembly of the instruc-
       tions  at  those	addresses.  If present,	the first argument selects the
       CPU (see	Specifying devices and address spaces 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:

       history ,5
	      Displays	up  to five most recently visited PC addresses and in-
	      structions 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.

   trackpc
       trackpc [<enable>[,<CPU>[,<clear>]]]

       Turns visited PC	address	tracking for disassembly views on or off.  In-
       structions 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 sec-
       ond argument specifies the CPU to enable	or disable tracking  for  (see
       Specifying devices and address spaces for details); if no CPU is	speci-
       fied,  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 CPUs 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 General Debugger	Commands

   trackmem
       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 sec-
       ond  argument  specifies	the CPU	to enable or disable tracking for (see
       Specifying devices and address spaces for details); if no CPU is	speci-
       fied, the visible CPU is	assumed.  The  third  argument	is  a  Boolean
       specifying whether existing data	should be cleared (defaults to false).

       Use  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 General Debugger	Commands

   pcatmem
       pcatmem[{d|i|o}]	<address>[:<space>]

       Returns the PC value at the time	the specified  address	was  most  re-
       cently  written	to.  The argument is the requested address, optionally
       followed	by a colon and a CPU and/or address space (see Specifying  de-
       vices  and  address spaces 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  trackmem).	  Right-clicking a debugger memory view	will also dis-
       play the	logged PC value	for the	given address in some configurations.

       Examples:

       pcatmem 400000
	      Print the	PC value when location 400000 in the visible CPUs pro-
	      gram space was most recently written.

       pcatmem 3bc:io
	      Print the	PC value when location 3bc  in	the  visible  CPUs  io
	      space was	most recently written.

       pcatmem 1400:audiocpu
	      Print the	PC value when location 1400 in the CPU :audiocpus pro-
	      gram space was most recently written.

       Back to General Debugger	Commands

   rewind
       rewind

       Loads  the  most	 recent	 RAM-based  saved state.  When enabled,	rewind
       states are saved	when step, over	and 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:

       rewind Load the previous	RAM-based save state.

       rw     Abbreviated form of the command.

       Back to General Debugger	Commands

   statesave
       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
       state_directory option),	and the	.sta extension	is  automatically  ap-
       pended to the specified file name.  May be abbreviates to ss.

       All  output  from this command is currently echoed into the running ma-
       chine window.

       Examples:

       statesave foo
	      Saves the	emulated machine state to the file foo.sta in the con-
	      figured save state directory.

       ss bar Abbreviated form of the  command	 saves	the  emulated  machine
	      state to bar.sta.

       Back to General Debugger	Commands

   stateload
       stateload <filename>

       Restores	 a  saved  state  file from disk.  The specified state file is
       read from the configured	save state directory (see the  state_directory
       option),	and the	.sta extension is automatically	appended to the	speci-
       fied file name.	May be abbreviated to sl.

       All  output  for	 this command is currently echoed into the running ma-
       chine window.  Previous memory and PC tracking statistics are cleared.

       Examples:

       stateload foo
	      Loads state from file foo.sta to the configured save  state  di-
	      rectory.

       sl bar Abbreviated form of the command  loads the file bar.sta.

       Back to General Debugger	Commands

   snap
       snap [<filename>[,<scrnum>]]

       Takes a snapshot	of the emulated	video display and saves	it to the con-
       figured	snapshot  directory (see the snapshot_directory	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
       snapview	and snapname options).

       If  a  file  name is specified, the .png	extension is automatically ap-
       pended.	The screen number is specified as a zero-based index, as  seen
       in  the	names  of automatically-generated single-screen	views in MAMEs
       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 General Debugger	Commands

   source
       source <filename>

       Reads  the  specified file in text mode and executes each line as a de-
       bugger command.	This is	similar	to running a  shell  script  or	 batch
       file.

       Examples:

       source break_and_trace.cmd
	      Reads and	executes debugger commands from	break_and_trace.cmd.

       Back to General Debugger	Commands

   time
       Prints the total	elapsed	emulated time to the debugger console.

       Examples:

       time   Prints the elapsed emulated time.

       Back to General Debugger	Commands

   quit
       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 General Debugger	Commands

   Memory Debugger Commands
       dasm   disassemble code to a file

       find   search emulated memory for data

       fill   fill emulated memory with	specified pattern

       dump   dump emulated memory to a	file as	text

       strdump
	      dump delimited strings from emulated memory to a file

       save   save binary data from emulated memory to a file

       saver  save binary data from a memory region to a file

       load   load binary data from a file to emulated memory

       loadr  load binary data from a file to a	memory region

       map    map  a logical address to	the corresponding physical address and
	      handler

       memdump
	      dump current memory maps to a file

   dasm
       dasm <filename>,<address>,<length>[,<opcodes>[,<CPU>]]

       Disassembles program memory to the file specified by the	<filename> pa-
       rameter.	 The <address> parameter specifies the address to start	disas-
       sembling	from, and the <length> parameter specifies how much memory  to
       disassemble.   The range	<address> through <address>+<length>-1,	inclu-
       sive, 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 dif-
       ferent  CPU,  specify  it  using	 the  optional	fifth  parameter  (see
       Specifying devices and address spaces for details).

       Examples:

       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 hard-
	      driv.asm.

       Back to Memory Debugger Commands

   find
       f[ind][{d|i|o}] <address>[:<space>],<length>[,<data>[,]]

       Search through memory for the specified sequence	 of  data.   The  <ad-
       dress> is the address to	begin searching	from, optionally followed by a
       device  and/or address space (see Specifying devices and	address	spaces
       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 expres-
       sion, or	the  wildcard  character  ?.   By  default,  strings  imply  a
       byte-sized search; by default non-string	data is	searched using the na-
       tive  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 dis-
       played.

       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 Memory Debugger Commands

   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 Specifying  devices  and
       address	spaces 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  de-
       fault  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 expres-
       sion.  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 oc-
       curs  or	 if  part  of  the  sequence  or string	would fall beyond <ad-
       dress>+<length>-1.

       Back to Memory Debugger Commands

   dump
       dump[{d|i|o}]					       <filename>,<ad-
       dress>[:<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	Specifying devices and
       address spaces 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 de-
       fault 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  na-
       tive word size of the address space.  You can override this by specify-
       ing  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 Memory Debugger Commands

   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	Specifying devices and
       address spaces 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), str-
       dumpi 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	print-
       able ASCII characters.  The optional <term> parameter can  be  used  to
       specify a different string terminator character.

       Back to Memory Debugger Commands

   save
       save[{d|i|o}] <filename>,<address>[:<space>],<length>

       Save  raw memory	to the binary file specified by	the <filename> parame-
       ter.  The <address> specifies the address to start saving from, option-
       ally followed by	a device and/or	address	space (see Specifying  devices
       and address spaces 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  de-
       fault  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 Memory Debugger Commands

   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 Specifying devices and ad-
       dress spaces).  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 Memory Debugger Commands

   load
       load[{d|i|o}] <filename>,<address>[:<space>][,<length>]

       Load  raw memory	from the binary	file specified by the <filename> para-
       meter.  The <address> specifies the address to start  loading  to,  op-
       tionally	 followed by a device and/or address space (see	Specifying de-
       vices and address spaces	for details); the <length> specifies how  much
       memory to load.	If an address space is not specified, the command suf-
       fix  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  val-
       ues.

       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 Memory Debugger Commands

   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.  Re-
       gions tags follow the same rules	as device tags (see Specifying devices
       and address spaces).  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 to-
       tal 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 Memory Debugger Commands

   map
       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	Specifying de-
       vices and address spaces	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 Memory Debugger Commands

   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  Specifying  de-
       vices  and address spaces), 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  my-
	      log.log.

       memdump
	      Dumps memory maps	for all	devices	in the system to the file mem-
	      dump.log.

       memdump audiomaps.log,audiopcb
	      Dumps memory maps	for the	device with the	absolute tag path :au-
	      diopcb 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  my-
	      log.log.

       Back to Memory Debugger Commands

   Execution Debugger Commands
       step   single step for <count> instructions (F11)

       over   single step over <count> instructions (F10)

       out    single  step  until the current subroutine/exception handler re-
	      turns (Shift-F11)

       go     resume execution (F5)

       gbt    resume execution until next true branch is executed

       gbf    resume execution until next false	branch is executed

       gex    resume execution until exception is raised

       gint   resume execution until interrupt is taken	(F7)

       gni    resume execution until next further instruction

       gtime  resume execution until the given delay has elapsed

       gvblank
	      resume execution until next vertical blanking interval (F8)

       next   resume execution until the next CPU switch (F6)

       focus  focus debugger only on <CPU>

       ignore stop debugging on	<CPU>

       observe
	      resume debugging on <CPU>

       trace  trace the	specified CPU to a file

       traceover
	      trace the	specified CPU to a file	skipping subroutines

       traceflush
	      flush all	open trace files.

   step
       s[tep] [<count>]

       Single steps one	or more	instructions on	the currently  executing  CPU.
       Executes	 one  instruction  if <count> is omitted, or steps <count> in-
       structions if it	is supplied.

       Examples:

       s      Steps forward one	instruction on the current CPU.

       step 4 Steps forward four instructions on the current CPU.

       Back to Execution Debugger Commands

   over
       o[ver] [<count>]

       The over	command	single steps over one or more instructions on the cur-
       rently executing	CPU, stepping over subroutine calls and	exception han-
       dler 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 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 Execution Debugger Commands

   out
       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
       step.

       Example:

       out    Steps until a subroutine or exception handler returns.

       Back to Execution Debugger Commands

   go
       g[o] [<address>]

       Resumes execution.  Control will	not be returned	to the debugger	 until
       a  breakpoint  or watchpoint is triggered, or a debugger	break is manu-
       ally requested.	If the optional	<address> is supplied, a temporary un-
       conditional 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 con-
	      dition causes execution to stop before then.

       Back to Execution Debugger Commands

   gbf
       gbf [<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 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.

       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 Execution Debugger Commands

   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 con-
       tinue 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 Execution Debugger Commands

   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	condi-
       tion is raised on the current CPU.  Use the optional <exception>	 para-
       meter  to  stop	execution only for a specific exception	condition.  If
       <exception> is omitted, execution will stop for	any  exception	condi-
       tion.

       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	excep-
       tion  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 Execution Debugger Commands

   gint
       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 as-
       serted 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 Execution Debugger Commands

   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 sequen-
       tially past the current one.  When this breakpoint is hit, it is	 auto-
       matically 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, in-
	      cluding the temporary breakpoint set at the address of the  fol-
	      lowing instruction.

       gni 2  Resume  execution	until a	breakpoint/watchpoint is triggered.  A
	      temporary	breakpoint is set two instructions  past  the  current
	      one.

       Back to Execution Debugger Commands

   gtime
       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 Execution Debugger Commands

   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 Execution Debugger Commands

   next
       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
       ignore or focus.

       Example:

       n      Resume execution,	stopping when a	different CPU that is not  ig-
	      nored is scheduled.

       Back to Execution Debugger Commands

   focus
       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
       Specifying devices and address spaces for details).  This is equivalent
       to  using  the  ignore command to ignore	all CPUs besides the specified
       CPU.

       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 :au-
	      diopcb:melodycpu.

       Back to Execution Debugger Commands

   ignore
       ignore [<CPU>[,<CPU>[,]]]

       Ignores the specified CPUs in the debugger.  CPUs can be	 specified  by
       tag  or	debugger CPU number (see Specifying devices and	address	spaces
       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 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 Execution Debugger Commands

   observe
       observe [<CPU>[,<CPU>[,]]]

       Allow interaction with the specified CPUs in the	debugger.  CPUs	can be
       specified by tag	or debugger CPU	number (see Specifying devices and ad-
       dress  spaces  for  details).  This command reverses the	effects	of the
       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 Execution Debugger Commands

   trace
       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, spec-
       ify  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 over-
       writing.

       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  tracelog
       or tracesym command to include additional information in	the trace log.
       Note  that you may need to surround the action within braces { }	to en-
       sure 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, log-
	      ging 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, log-
	      ging output to the file starswep.tr, with	 loop  detection  dis-
	      abled.

       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 in-
	      dex).

       trace asteroid.tr,,,{tracelog "A=%02X ",a}
	      Begin tracing the	execution of the currently visible  CPU,  log-
	      ging  output  to the file	asteroid.tr.  Before each line,	output
	      A=<aval> to the trace log.

       Back to Execution Debugger Commands

   traceover
       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	 algo-
       rithm  is  used	as is used in the step 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	trace command.	Please
       refer to	the corresponding section for a	detailed  description  of  op-
       tions and more examples.

       Examples:

       traceover joust.tr
	      Begin  tracing  the execution of the currently visible CPU, log-
	      ging 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, log-
	      ging output to the file starswep.tr, with	 loop  detection  dis-
	      abled.

       traceover off,0
	      Turn off tracing for the first CPU in the	system (zero-based in-
	      dex).

       traceover asteroid.tr,,,{tracelog "A=%02X ",a}
	      Begin  tracing  the execution of the currently visible CPU, log-
	      ging output to the file asteroid.tr.  Before each	 line,	output
	      A=<aval> to the trace log.

       Back to Execution Debugger Commands

   traceflush
       traceflush

       Flushes all open	trace log files	to disk.

       Example:

       traceflush
	      Flush trace log files.

       Back to Execution Debugger Commands

   Breakpoint Debugger Commands
       bpset  sets a breakpoint	at <address>

       bpclear
	      clears a specific	breakpoint or all breakpoints

       bpdisable
	      disables a specific breakpoint or	all breakpoints

       bpenable
	      enables a	specific breakpoint or all breakpoints

       bplist lists breakpoints

       Breakpoints  halt execution and activate	the debugger before a CPU exe-
       cutes an	instruction at a particular address.

   bpset
       bp[set] <address>[:<CPU>][,<condition>[,<action>]]

       Sets a new execution breakpoint at the specified	<address>.   The  <ad-
       dress>  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	debug-
       ger.

       The  optional <condition> parameter lets	you specify an expression that
       will be evaluated each time the breakpoint address is hit.  If the  re-
       sult of the expression is true (non-zero), the breakpoint will halt ex-
       ecution;	 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	 semi-
       colons  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 :au-
	      diocpu that will halt execution whenever	the  PC	 is  equal  to
	      3456.   When this	happens, print A0=<a0val> to the debugger con-
	      sole and resume execution.

       bp 45678:2,a0==100,{ a0 = ff ; g	}
	      Set a breakpoint on the third CPU	in the system (zero-based  in-
	      dex)  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 Breakpoint Debugger Commands

   bpclear
       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 Breakpoint Debugger Commands

   bpdisable
       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  temporar-
       ily  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 Breakpoint Debugger Commands

   bpenable
       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 Breakpoint Debugger Commands

   bplist
       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	break-
       points  for that	CPU will be listed.  The <CPU> can be specified	by tag
       or by debugger CPU number (see Specifying devices  and  address	spaces
       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 Breakpoint Debugger Commands

   Watchpoint Debugger Commands
       wpset  sets memory access watchpoints

       wpclear
	      clears watchpoints

       wpdisable
	      disables watchpoints

       wpenable
	      enables enables watchpoints

       wplist lists watchpoints

       Watchpoints halt	execution and activate the debugger  when  a  CPU  ac-
       cesses a	location in a particular memory	range.

   wpset
       wp[{d|i|o}][set]	<address>[:<space>],<length>,<type>[,<condition>[,<ac-
       tion>]]

       Sets a new watchpoint starting at the specified <address> and extending
       for  <length>.	The  range of the watchpoint is	<address> through <ad-
       dress>+<length>-1, inclusive.  The <address> may	optionally be followed
       by a CPU	and/or address	space  (see  Specifying	 devices  and  address
       spaces 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 de-
       faults to the space with	index 3	(opcodes).  The	<type> parameter spec-
       ifies 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 ac-
       cesses.

       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	execu-
       tion; otherwise,	execution will continue	with no	notification.  The op-
       tional <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	avail-
       able: for all watchpoints, the variable wpaddr is set to	the access ad-
       dress  that  triggered the watchpoint; for write	watchpoints, the vari-
       able 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	execu-
	      tion.

       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 Watchpoint Debugger Commands

   wpclear
       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 Watchpoint Debugger Commands

   wpdisable
       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 temporar-
       ily 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 Watchpoint Debugger Commands

   wpenable
       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 Watchpoint Debugger Commands

   wplist
       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	watch-
       points for that CPU will	be listed.  The	<CPU> can be specified by  tag
       or  by  debugger	 CPU number (see Specifying devices and	address	spaces
       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 Watchpoint Debugger Commands

   Registerpoint Debugger Commands
       rpset  sets a registerpoint to trigger on a condition

       rpclear
	      clears registerpoints

       rpdisable
	      disables a registerpoint

       rpenable
	      enables registerpoints

       rplist lists registerpoints

       Registerpoints  evaluate	 an expression each time a CPU executes	an in-
       struction and halt execution and	activate the debugger if the result is
       true (non-zero).

   rpset
       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> parame-
       ter  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	inter-
       preted 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 in-
       dices 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 when-
	      ever the PC register equals 150.

       rp {temp0==5}
	      Set a registerpoint that will halt execution whenever the	 temp0
	      variable equals 5.

       Back to Registerpoint Debugger Commands

   rpclear
       rpclear [<rpnum>,[,]]

       Clears registerpoints.  If <rpnum> is specified,	the registerpoints re-
       ferred  to will be cleared.  If <rpnum> is not specified, all register-
       points will be cleared.

       Examples:

       rpclear 3
	      Clear the	registerpoint with index 3.

       rpclear
	      Clear all	registerpoints.

       Back to Registerpoint Debugger Commands

   rpdisable
       rpdisable [<rpnum>[,]]

       Disables	registerpoints.	 If <rpnum> is specified,  the	registerpoints
       referred	 to will be disabled.  If <rpnum> is not specified, all	regis-
       terpoints will be disabled.

       Note that disabling a registerpoint does	not delete it,	it  just  tem-
       porarily	 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 Registerpoint Debugger Commands

   rpenable
       rpenable	[<rpnum>[,]]

       Enables	registerpoints.	  If  <rpnum> is specified, the	registerpoints
       referred	to will	be enabled.  If	<rpnum>	is not specified,  all	regis-
       terpoints will be enabled.

       Examples:

       rpenable	3
	      Enable the registerpoint with index 3.

       rpenable
	      Enable all registerpoints.

       Back to Registerpoint Debugger Commands

   rplist
       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	Specifying devices and
       address spaces 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 Registerpoint Debugger Commands

   Exception Point Debugger Commands
       epset  sets a new exception point

       epclear
	      clears a specific	exception point	or all exception points

       epdisable
	      disables a specific exception point or all exception points

       epenable
	      enables a	specific exception point or all	exception points

       eplist lists exception points

       Exception  points  halt	execution and activate the debugger when a CPU
       raises a	particular exception number.

   epset
       ep[set] <type>[,<condition>[,<action>]]

       Sets a new exception point for exceptions of type <type>.  The optional
       <condition> parameter lets you specify an expression that will be eval-
       uated each time the exception point is hit.  If the result of  the  ex-
       pression	is true	(non-zero), the	exception point	will actually halt ex-
       ecution	at  the	 start	of the exception handler; otherwise, execution
       will continue with no notification.  The	 optional  <action>  parameter
       provides	a command that is executed whenever the	exception point	is hit
       and  the	 <condition> is	true.  Note that you may need to embed the ac-
       tion 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 ex-
       ceptions	may include internally or externally vectored interrupts,  er-
       rors occurring within instructions and system calls.

       Each exception point that is set	is assigned an index which can be used
       in other	exception point	commands to reference this exception point.

       Examples:

       ep 2   Set  an  exception that will halt	execution whenever the visible
	      CPU raises exception number 2.

       Back to Exception Point Debugger	Commands

   epclear
       epclear [<epnum>[,]]

       The epclear command clears exception points.  If	<epnum>	is  specified,
       only  the  requested exception points are cleared, otherwise all	excep-
       tion points are cleared.

       Examples:

       epclear 3
	      Clear exception point index 3.

       epclear
	      Clear all	exception points.

       Back to Exception Point Debugger	Commands

   epdisable
       epdisable [<epnum>[,]]

       The epdisable command disables exception	points.	 If <epnum> is	speci-
       fied,  only  the	requested exception points are disabled, otherwise all
       exception points	are disabled.  Note that disabling an exception	 point
       does  not  delete  it, it just temporarily marks	the exception point as
       inactive.

       Examples:

       epdisable 3
	      Disable exception	point index 3.

       epdisable
	      Disable all exception points.

       Back to Exception Point Debugger	Commands

   epenable
       epenable	[<epnum>[,]]

       The epenable command enables exception points.  If  <epnum>  is	speci-
       fied,  only  the	 requested exception points are	enabled, otherwise all
       exception points	are enabled.

       Examples:

       epenable	3
	      Enable exception point index 3.

       epenable
	      Enable all exception points.

       Back to Exception Point Debugger	Commands

   eplist
       eplist

       The eplist command lists	all the	current	exception points,  along  with
       their index and any conditions or actions attached to them.

       Back to Exception Point Debugger	Commands

   Code	Annotation Debugger Commands
       comadd adds a comment to	the disassembled code at given address

       comdelete
	      removes a	comment	from the given address

       comsave
	      save the current comments	to file

       comlist
	      list comments stored in the comment file for the system

       commit combined comadd and comsave command

   comadd
       comadd <address>,<comment>

       Sets  the  specified comment for	the specified address in the disassem-
       bled 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.

   comdelete
       comdelete

       Deletes the comment at the specified address for	the visible CPU.

       Examples:

       comdelete 10
	      Deletes the comment at code address 10 for the visible CPU.

   comsave
       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 comment_directory	option.

       Examples:

       comsave
	      Saves the	current	comments to the	comment	file for the system.

   comlist
       comlist

       Reads the comments stored in the	XML comment file for the emulated sys-
       tem and prints them to the debugger console.  This command does not af-
       fect  the comments for the current session, it reads the	file directly.
       The directory for these files is	set using  the	comment_directory  op-
       tion.

       Examples:

       comlist
	      Shows comments stored in the comment file	for the	system.

   commit
       commit <address>,<comment>

       Sets  the  specified comment for	the specified address in the disassem-
       bled code for the visible CPU, and saves	comments to the	file  for  the
       current	emulated  system  (equivalent  to comadd followed by 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.

   Cheat Debugger Commands
       cheatinit
	      initialize the cheat search to the selected memory area

       cheatrange
	      add selected memory area to cheat	search

       cheatnext
	      filter cheat candidates by comparing to previous values

       cheatnextf
	      filter cheat candidates by comparing to initial value

       cheatlist
	      show the list of cheat search matches or save them to a file

       cheatundo
	      undo the last cheat search (state	only)

       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.

       Well demonstrate	use of the cheat search	functionality to make an infi-
       nite lives cheat	for Raiden (raiden):

        Start the game	with the debugger active.  Allow the game to run,  in-
	 sert 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 cheatinit command:

	    >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 cheatnext command 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 cheatlist command 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:

	    <cheat desc="Possibility 1:	00B85 (01)">
	      <script state="run">
		<action>:maincpu.pb@0x00B85=0x03</action>
	      </script>
	    </cheat>

   cheatinit
       cheatinit [[<sign>[<width>[<swap>]]],[<address>,<length>[,<space>]]]

       Initialize  the cheat search to writable	RAM areas in the specified ad-
       dress 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	previ-
       ous 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 Specifying devices and address spaces for details on	specifying ad-
       dress 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 ad-
	      dresses 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  ad-
	      dresses  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  re-
	      verse byte order in addresses 0x0000-0x0fff in the program space
	      of the visible CPU.

       Back to Cheat Debugger Commands

   cheatrange
       cheatrange <address>,<length>

       Add  writable RAM areas to the cheat search.  May be abbreviated	to cr.
       Before using this command, the cheatinit	command	must be	used  to  ini-
       tialize 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.

       Examples:

       cheatrange 0x1000,0x10
	      Add addresses 0x1000-0x100f to the areas to search for cheats.

       Back to Cheat Debugger Commands

   cheatnext
       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 val-
	      ues 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	previ-
	      ous search.

       Back to Cheat Debugger Commands

   cheatnextf
       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 Cheat Debugger Commands

   cheatlist
       cheatlist [<filename>]

       Without <filename>, show	the current cheat matches in the debugger con-
       sole; with <filename>, save the current cheat matches in	basic XML for-
       mat 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 Cheat Debugger Commands

   cheatundo
       cheatundo

       Undo filtering of cheat candidates by  the  most	 recent	 cheatnext  or
       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
	      cheatnext	or cheatnextf command.

       Back to Cheat Debugger Commands

   Media Image Debugger	Commands
       images lists all	image devices and mounted media	images

       mount  mounts a media image file	to an image device

       unmount
	      unmounts the media image from a device

   images
       images

       Lists the instance names	for media images devices in the	system and the
       currently mounted media images, if any.	Brief instance names,  as  al-
       lowed  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.

       Back to Media Image Debugger Commands

   mount
       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.

       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 Media Image Debugger Commands

   unmount
       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 al-
       lowed for command line media options.

       Examples:

       unmount cart
	      Unmounts any media image mounted on  the	device	with  instance
	      name cart.

       Back to Media Image Debugger Commands

   Specifying devices and address spaces
       Many debugger commands accept parameters	specifying which device	to op-
       erate  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 de-
	 vices,	in debugger disassembly	and memory viewer  source  lists,  and
	 various other places within MAMEs 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	inter-
       preted relative to the root machine device.  If a  device  argument  is
       ambiguously  valid  as  both  a tag and a CPU number, it	will be	inter-
       preted 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 ad-
       dress 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 visi-
	      ble 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 de-
       bugger should take the most likely meaning  for	a  device  or  address
       space specification.

   Debugger expression syntax
       Expressions  can	be used	anywhere a numeric or Boolean parameter	is ex-
       pected.	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  op-
       erator),	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 comple-
	      ment, 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 al-
	 ways evaluated.

   Numbers
       Literal numbers are prefixed according to their bases:

        Hexadecimal (base-16) with $ or 0x

        Decimal (base-10) with	#

        Octal (base-8)	with 0o

        Binary	(base-2) with 0b

        Unprefixed numbers are	hexadecimal (base-16).

       Examples:

        123 is	123 hexadecimal	(291 decimal)

        $123 is 123 hexadecimal (291 decimal)

        0x123 is 123 hexadecimal (291 decimal)

        #123 is 123 decimal

        0o123 is 123 octal (83	decimal)

        0b1001	is 1001	binary (9 decimal)

        0b123 is invalid

   Boolean values
       Any expression that evaluates to	a number can be	used where  a  Boolean
       value  is  required.  Zero is treated as	false, and all non-zero	values
       are treated as true.  Additionally, the string true is treated as true,
       and the string false is treated as false.

       An empty	string may be supplied as an argument for  Boolean  parameters
       to debugger commands to use the default value, even when	subsequent pa-
       rameters	are specified.

   Memory accesses
       The  memory  access  prefix operators allow reading from	and writing to
       emulated	address	spaces.	 The memory prefix operators specify  the  ac-
       cess  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 doesnt change behaviour in
       most cases  you want to see the effects of writing to a location.  How-
       ever, 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	condi-
	 tions.	 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 ma-
	 chines	point of view, the race	condition  is  not  usually  relevant.
	 Its  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	regis-
	 ter, and also clears the output compare flag (OCF) and	 enables  com-
	 pare  if  it was previously inhibited by writing to OCRH.  Writing to
	 OCRL with side	effects	disabled just changes the value	in the	regis-
	 ter  without  clearing	 OCF or	enabling compare, since	its 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 fol-
       lowed by	a dot (.).

       That may	seem like a lot	to digest, so lets look	at the simplest	 exam-
       ples:

       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,  re-
	      spectively.

       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 pro-
	      gram 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  cur-
       rent  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 ad-
       dresses are equivalent for some CPUs, and direct	read/write pointer ac-
       cesses 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.

   Functions
       The debugger supports a number of useful	utility	functions  in  expres-
       sions.

       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  <false-
	      val>  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,	count-
	      ing 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,	count-
	      ing from the least significant bit).

LUA SCRIPTING INTERFACE
        Introduction

        Features

        API reference

        Interactive Lua console tutorial

   Introduction
       MAME  provides Lua script bindings for a	useful set of core functional-
       ity.  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 MAMEs Lua scripting capabilities:

        Using the interactive Lua console, enabled by the console option.

        By providing a	script file to run using the -autoboot_script  option.
	 The  -autoboot_delay option controls how long MAME waits after	start-
	 ing the emulated system before	running	the script.

        By writing Lua	plugins.  Several plugins are included with MAME.

       Internally, MAME	makes extensive	use of Sol3 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.

   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 enu-
	 meration)

        Screen	introspection (screens listing,	screen details,	 frame	count-
	 ing)

        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)

   API reference
   Lua Common Types and	Globals
        Containers

        Emulator interface

   Containers
       Many properties yield container wrappers.  Container wrappers are cheap
       to  create, and provide an interface that is similar to a read-only ta-
       ble.  The complexity of operations may vary.  Container	wrappers  usu-
       ally 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  con-
	      tainer.  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.

   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 attotime or a	number in sec-
	      onds.  Any additional arguments are returned from	the coroutine.
	      Returns a	Boolean	indicating whether the duration	 expired  nor-
	      mally.

	      All  outstanding calls to	emu.wait will return false immediately
	      if a saved state is loaded or the	emulation session ends.	 Call-
	      ing 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 re-
	      turned 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 notifier subscription.

       emu.add_machine_stop_notifier(callback)
	      Add a callback to	receive	notifications when the emulated	system
	      is stopped.  Returns a notifier subscription.

       emu.add_machine_pause_notifier(callback)
	      Add a callback to	receive	notifications when the emulated	system
	      is paused.  Returns a notifier subscription.

       emu.add_machine_resume_notifier(callback)
	      Add a callback to	receive	notifications when the emulated	system
	      is resumed after being paused.  Returns a	notifier subscription.

       emu.add_machine_frame_notifier(callback)
	      Add a callback to	receive	notifications when an  emulated	 frame
	      completes.  Returns a notifier subscription.

       emu.add_machine_pre_save_notifier(callback)
	      Add  a callback to receive notification before the emulated sys-
	      tem state	is saved.  Returns a notifier subscription.

       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  notifier
	      subscription.

       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 de-
	      fault).

       emu.lang_translate([context], message)
	      Look up a	message	with optional context in the current localised
	      message catalog.	Returns	the message  unchanged	if  no	corre-
	      sponding localised message is found.

       emu.subst_env(string)
	      Substitute environment variables in a string.  The syntax	is de-
	      pendent on the host operating system.

   Lua Core Classes
       Many  of	 MAMEs core classes used to implement an emulation session are
       available to Lua	scripts.

        Notifier subscription

        Attotime

        MAME machine manager

        Running machine

        Video manager

        Sound manager

        Output	manager

        Parameters manager

        UI manager

        System	driver metadata

        Lua plugin

   Notifier subscription
       Wraps MAMEs util::notifier_subscription class,  which  manages  a  sub-
       scription 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 sub-
	      scription	becomes	inactive after explicitly unsubscribing	or  if
	      the underlying notifier is destroyed.

   Attotime
       Wraps  MAMEs attotime class, which represents a high-precision time in-
       terval.	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  num-
	      ber of seconds.

       emu.attotime.from_msec(milliseconds)
	      Creates  an attotime value representing the specified whole num-
	      ber of milliseconds.

       emu.attotime.from_usec(microseconds)
	      Creates an attotime value	representing the specified whole  num-
	      ber of microseconds.

       emu.attotime.from_nsec(nanoseconds)
	      Creates  an attotime value representing the specified whole num-
	      ber 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  correspond-
	      ing  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  correspond-
	      ing 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 correspond-
	      ing 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	speci-
	      fied 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 maxi-
	      mum 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 por-
	      tion of the interval.

       t.usec (read-only)
	      The number of whole microseconds in the fractional seconds  por-
	      tion of the interval.

       t.nsec (read-only)
	      The  number  of whole nanoseconds	in the fractional seconds por-
	      tion of the interval.

   MAME	machine	manager
       Wraps MAMEs mame_machine_manager	class, which  holds  the  running  ma-
       chine, 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 running machine for the current emulation session.

       manager.ui (read-only)
	      The UI manager for the current session.

       manager.options (read-only)
	      The emulation options for	the current session.

       manager.plugins[] (read-only)
	      Gets information about the Lua plugins that are present, indexed
	      by name.	The index get, at and index_of methods have O(n)  com-
	      plexity.

   Running machine
       Wraps  MAMEs  running_machine class, which represents an	emulation ses-
       sion.  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 ses-
	      sion.

   Methods
       machine:exit()
	      Schedules	an exit	from the current emulation session.  This will
	      either  return to	the system selection menu or exit the applica-
	      tion, depending on how it	was started.  This method returns  im-
	      mediately, 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	sched-
	      uled reset takes place.

       machine:soft_reset()
	      Schedules	 a soft	reset.	This is	implemented by calling the re-
	      set method of the	root device, which is propagated down the  de-
	      vice  tree.   This method	returns	immediately, before the	sched-
	      uled 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 directo-
	      ries 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	 pend-
	      ing 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 dis-
	      played 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
	      attotime.

       machine.system (read-only)
	      The driver metadata for the current system.

       machine.parameters (read-only)
	      The parameters manager for the current emulation session.

       machine.video (read-only)
	      The video	manager	for the	current	emulation session.

       machine.sound (read-only)
	      The sound	manager	for the	current	emulation session.

       machine.output (read-only)
	      The output manager for the current emulation session.

       machine.memory (read-only)
	      The emulated memory manager for the current session.

       machine.ioport (read-only)
	      The I/O port manager for the current emulation session.

       machine.input (read-only)
	      The input	manager	for the	current	emulation session.

       machine.natkeyboard (read-only)
	      Gets the natural keyboard	manager, used for controlling keyboard
	      and keypad input to the emulated system.

       machine.uiinput (read-only)
	      The UI input manager for the current emulation session.

       machine.render (read-only)
	      The render manager for the current emulation session.

       machine.debugger	(read-only)
	      The debugger manager for the current emulation session,  or  nil
	      if the debugger is not enabled.

       machine.options (read-only)
	      The user-specified options 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 sys-
	      tem 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	device enumerator that yields all devices in the emulated sys-
	      tem.

       machine.palettes	(read-only)
	      A	device enumerator that yields all palette devices in the  emu-
	      lated system.

       machine.screens (read-only)
	      A	 device	 enumerator that yields	all screen devices in the emu-
	      lated system.

       machine.cassettes (read-only)
	      A	device enumerator that yields all cassette  image  devices  in
	      the emulated system.

       machine.images (read-only)
	      A	 device	 enumerator that yields	all media image	devices	in the
	      emulated system.

       machine.slots (read-only)
	      A	device enumerator that yields all slot devices in the emulated
	      system.

   Video manager
       Wraps MAMEs 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 snap-
	      shots or if the system has no emulated screens, a	 single	 snap-
	      shot 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	inter-
	      preted  relative to the first configured snapshot	directory.  If
	      the format is supplied, it must be "avi" or "mng".  If the  for-
	      mat 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	calcu-
	      lated 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 snap-
	      shot  target  configuration as 32-bit integers packed into a bi-
	      nary 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 ra-
	      tio to normal speed multiplied by	1,000).

       video.throttled (read/write)
	      A	Boolean	indicating whether MAME	should wait before  video  up-
	      dates 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 ad-
	      justed 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 configu-
	      ration  setting, the emulated system must	have at	least one emu-
	      lated screen.

       video.is_recording (read-only)
	      A	Boolean	indicating whether any video recordings	are  currently
	      in progress.

       video.snapshot_target (read-only)
	      The  render  target  used	to produce snapshots and video record-
	      ings.

   Sound manager
       Wraps MAMEs 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  config-
	      ured  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 rea-
	      son.

       sound.ui_mute (read/write)
	      A	Boolean	indicating whether sound output	is muted  at  the  re-
	      quest of the user.

       sound.debugger_mute (read/write)
	      A	 Boolean  indicating  whether sound output is muted at the re-
	      quest of the debugger.

       sound.system_mute (read/write)
	      A	Boolean	indicating whether sound output	is muted  at  the  re-
	      quest of the emulated system.

       sound.attenuation (read/write)
	      The  output volume attenuation in	decibels.  Should generally be
	      a	negative integer or zero.

       sound.recording (read-only)
	      A	Boolean	indicating whether sound  output  is  currently	 being
	      recorded to a WAV	file.

   Output manager
       Wraps  MAMEs  output_manager  class, providing access to	system outputs
       that can	be used	for interactive	artwork	or consumed by	external  pro-
       grams.

   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 al-
	      ready exist.

       output:get_value(name)
	      Returns the value	of the specified output, or zero if it	doesnt
	      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
	      doesnt exist.

       output:name_to_id(name)
	      Gets the per-session unique integer ID for the specified output,
	      or zero if it doesnt exist.

       output:id_to_name(id)
	      Gets  the	 name  for  the	 output	with the specified per-session
	      unique ID, or nil	if it doesnt exist.  This method has O(n) com-
	      plexity, so avoid	calling	it when	performance is important.

   Parameters manager
       Wraps MAMEs 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.

   UI manager
       Wraps  MAMEs  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  in-
	      put  focus  in more situations than when its windows have	UI fo-
	      cus.

       ui:get_general_input_setting(type, [player])
	      Gets a description of the	 configured  input  sequence  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 options 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  cur-
	      rently active.  Examples include menus and slider	controls.

       ui.ui_active (read/write)
	      A	Boolean	indicating whether UI control inputs are currently en-
	      abled.

       ui.single_step (read/write)
	      A	 Boolean controlling whether the emulated system should	be au-
	      tomatically 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.

   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	 work-
	      ing.

       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  art-
	      work 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  in-
	      complete functionality.

   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 ac-
	      cessing 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	multi-
	      ple plugins.

       plugin.directory	(read-only)
	      The path to the directory	containing the plugins files.

       plugin.start (read-only)
	      A	Boolean	indicating whether the plugin enabled.

   Lua Device Classes
       Several	device	classes	and device mix-ins classes are exposed to Lua.
       Devices can be looked up	by tag or enumerated.

        Device	enumerators

        Device

        Palette device

        Screen	device

        Cassette image	device

        Image device interface

        Slot device interface

        Device	state entry

        Media image format

        Slot option

   Device enumerators
       Device enumerators are special containers that allow iterating over de-
       vices and looking up devices by tag.  A device enumerator can  be  cre-
       ated  to	find any kind of device, to find devices of a particular type,
       or to find devices that implement a particular interface.  When iterat-
       ing 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 spec-
       ified tag does not meet the type/interface requirements of  the	device
       enumerator.  The	complexity is O(1) if the result is cached, but	an un-
       cached 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 re-
       stricted	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  in-
       terface.	  For  example	this will test whether a device	implements the
       media image interface:

	  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  devices  in
	      the system.

       manager.machine.palettes
	      Returns  a  device enumerator that will iterate over palette de-
	      vices in the system.

       manager.machine.screens
	      Returns a	device enumerator that will iterate  over  screen  de-
	      vices in the system.

       manager.machine.cassettes
	      Returns  a device	enumerator that	will iterate over cassette im-
	      age devices in the system.

       manager.machine.images
	      Returns a	device enumerator that will iterate over  media	 image
	      devices in the system.

       manager.machine.slots
	      Returns  a device	enumerator that	will iterate over slot devices
	      in the system.

       emu.device_enumerator(device, [depth])
	      Returns a	device enumerator that will iterate  over  devices  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 palette de-
	      vices 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 max-
	      imum  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 screen de-
	      vices 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 max-
	      imum 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 cassette  im-
	      age  devices  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	speci-
	      fying the	maximum	number of levels to iterate below  the	speci-
	      fied  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  media	 image
	      devices  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 slot devices
	      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).

   Device
       Wraps MAMEs 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 devices parent device to  an  ab-
	      solute tag.

       device:memshare(tag)
	      Gets  a memory share by tag relative to the device, or nil if no
	      such memory share	exists.

       device:membank(tag)
	      Gets a memory bank by tag	relative to the	device,	or nil	if  no
	      such memory bank exists.

       device:memregion(tag)
	      Gets a memory region by tag relative to the device, or nil if no
	      such memory region exists.

       device:ioport(tag)
	      Gets  an	I/O  port  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 devices 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 devices absolute tag in canonical form.

       device.basetag (read-only)
	      The  last	component of the devices 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 devices 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 devices 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 configura-
	      tion.

       device.started (read-only)
	      A	Boolean	indicating whether the device has completed starting.

       device.debug (read-only)
	      The  debugger  interface 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 state	entries	for devices that expose	the register state in-
	      terface, 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	devices	address	spaces,	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 spe-
	      cial significance.

   Palette device
       Wraps MAMEs 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	inten-
       sity), inclusive.  Colour channel values	are not	pre-multiplied by  the
       alpha  value.   Channel	values are packed into the bytes of 32-bit un-
       signed integers,	in the order alpha, red, green,	blue from most-signif-
       icant to	least-significant byte.

   Instantiation
       manager.machine.palettes[tag]
	      Gets a palette device by tag relative to the  root  machine  de-
	      vice, or nil if no such device exists or it is not a palette de-
	      vice.

   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 con-
	      trast 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 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 device.

   Screen device
       Wraps MAMEs 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
        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  sec-
	      onds.

       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  sup-
	      plied,  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 in-
	      teger.  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 posi-
	      tions.

	      Coordinates are floating-point  numbers  in  units  of  emulated
	      screen  pixels,  with  the origin	at (0, 0).  Note that emulated
	      screen pixels often arent	square.	 The coordinate	system is  ro-
	      tated  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	 inte-
	      ger,  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 arent	square.	 The coordinate	system is  ro-
	      tated  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.	 Chan-
	      nel 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  cen-
	      tred  on	the  screen, or	right-aligned at the right edge	of the
	      screen, respectively.  The second	argument specifies the Y coor-
	      dinate 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 arent	square.	 The coordinate	system is  ro-
	      tated  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	   al-
	      pha/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  transpar-
	      ent.

   Properties
       screen.width (read-only)
	      The  width of the	bitmap produced	by the emulated	screen in pix-
	      els.

       screen.height (read-only)
	      The height of the	bitmap produced	by the emulated	screen in pix-
	      els.

       screen.refresh (read-only)
	      The screens configured refresh rate in Hertz (this may  not  re-
	      flect the	current	value).

       screen.refresh_attoseconds (read-only)
	      The screens configured refresh interval in attoseconds (this may
	      not reflect the current value).

       screen.xoffset (read-only)
	      The screens default X position offset.  This is a	floating-point
	      number  where  one  (1) corresponds to the X size	of the screens
	      container.  This may be useful for restoring the	default	 after
	      adjusting	the X offset via the screens container.

       screen.yoffset (read-only)
	      The screens default Y position offset.  This is a	floating-point
	      number  where  one  (1) corresponds to the Y size	of the screens
	      container.  This may be useful for restoring the	default	 after
	      adjusting	the Y offset via the screens container.

       screen.xscale (read-only)
	      The  screens default X scale factor, as a	floating-point number.
	      This may be useful for restoring the default after adjusting the
	      X	scale via the screens container.

       screen.yscale (read-only)
	      The screens default Y scale factor, as a floating-point  number.
	      This may be useful for restoring the default after adjusting the
	      Y	scale via the screens container.

       screen.pixel_period (read-only)
	      The  interval  taken  to	draw  a	 horizontal pixel, as a	float-
	      ing-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  sec-
	      onds.

       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	monot-
	      onically each frame interval.

       screen.container	(read-only)
	      The render container used	to draw	the screen.

       screen.palette (read-only)
	      The palette device used to translate pixel values	to colours, or
	      nil if the screen	uses a direct colour pixel format.

   Cassette image device
       Wraps MAMEs cassette_image_device class,	representing  a	 compact  cas-
       sette 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
        Device

        Image device interface

   Methods
       cassette:stop()
	      Disables playback.

       cassette:play()
	      Enables playback.	 The cassette will play	if the	motor  is  en-
	      abled.

       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,  respec-
	      tively.

   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  cas-
	      sette will play if the motor is enabled).

       cassette.is_recording (read-only)
	      A	Boolean	indicating whether recording is	enabled	(i.e. the cas-
	      sette 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 sec-
	      onds 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.

   Image device	interface
       Wraps MAMEs 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 de-
	      vice.

   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  oc-
	      curred.

       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 sup-
	      ported.  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 im-
	      age has been unloaded.  Returns a	notifier subscription.

   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 configura-
	      tion.  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  media  image	 formats  supported  by	the device, indexed by
	      name.  The index operator	and index_of methods  have  O(n)  com-
	      plexity; 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  me-
	      dia 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 device.

   Slot	device interface
       Wraps  MAMEs  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	speci-
	      fied 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  pro-
	      grammatically,  typically	 for  fixed slots or to	load media im-
	      ages).

       slot.options[] (read-only)
	      The slot options describing the child devices that  can  be  in-
	      stantiated by the	slot, indexed by option	value.	The at and in-
	      dex_of  methods have O(n)	complexity; all	other supported	opera-
	      tions have O(1) complexity.

       slot.device (read-only)
	      The underlying device.

   Device state	entry
       Wraps MAMEs device_state_entry class, which allows access to named reg-
       isters exposed by a 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	entrys 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
	      entrys value.

       entry.is_float (read-only)
	      A	 Boolean indicating whether the	state entrys value is a	float-
	      ing-point	number.

       entry.datamask (read-only)
	      A	bit mask of the	valid bits of the value	for integer state  en-
	      tries.

       entry.datasize (read-only)
	      The  size	of the underlying value	in bytes for integer state en-
	      tries.

       entry.max_length	(read-only)
	      The maximum display string length	for the	state entry.

   Media image format
       Wraps MAMEs image_device_format class, which  describes	a  media  file
       format supported	by a media image device.

   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  im-
	      age  using  this	format.	  The string is	not intended to	be hu-
	      man-readable.

   Slot	option
       Wraps MAMEs device_slot_interface::slot_option class, which  represents
       a child device that a slot device can be	configured to instantiate.

   Instantiation
       manager.machine.slots[tag].options[name]
	      Gets  a  slot  option  for a given slot device 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 devices 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
	      devices 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.

   Lua Memory System Classes
       MAMEs 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.

        Memory	manager

        Address space

        Pass-through handler

        Address map

        Address map entry

        Address map handler data

        Memory	share

        Memory	bank

        Memory	region

   Memory manager
       Wraps MAMEs 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 memory shares	in the system, indexed by absolute  tag.   The
	      at  and  index_of	 methods  have O(n) complexity;	all other sup-
	      ported operations	have O(1) complexity.

       memory.banks[]
	      The memory banks 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  memory regions in the system, indexed by absolute tag.  The
	      at and index_of methods have O(n)	 complexity;  all  other  sup-
	      ported operations	have O(1) complexity.

   Address space
       Wraps  MAMEs address_space class, which represents an address space be-
       longing to a device.

   Instantiation
       manager.machine.devices[tag].spaces[name]
	      Gets the address space with the specified	name for a  given  de-
	      vice.  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	speci-
	      fied 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	speci-
	      fied 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	speci-
	      fied 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	speci-
	      fied 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	speci-
	      fied 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	speci-
	      fied 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 ob-
	      tained  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	notifier subscription.

       space: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  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  be-
	      ing  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 pass-through handler 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 be-
	      ing written, return the modified value from the  callback	 func-
	      tion 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 address map for the space or nil.

   Pass-through	handler
       Tracks a	pass-through handler installed in an address space.  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 address
	      space.

       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 address
	      space.

   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 han-
	      dler 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.

   Address map
       Wraps MAMEs address_map class, used to configure	handlers  for  an  ad-
       dress 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 associ-
	      ated 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 entries in	the address map.  Uses 1-based integer
	      indices.	The index operator and the at method  have  O(n)  com-
	      plexity.

   Address map entry
       Wraps MAMEs address_map_entry class, representing an entry in a config-
       ured 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 entrys range.

       entry.address_end (read-only)
	      End address of the entrys	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 isnt	connected to  all  the
	      data lines.

       entry.read (read-only)
	      Additional data for the read handler.

       entry.write (read-only)
	      Additional data 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 en-
	      tries, nil infers	the region from	the device tag.

       entry.region_offset (read-only)
	      Starting offset in memory	region for ROM entries.

   Address map handler data
       Wraps  MAMEs  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",  "un-
	      map",  "delegate", "port", "bank", "submap", or "unknown".  Note
	      that multiple handler type values	can yield "delegate"  or  "un-
	      known".

       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.

   Memory share
       Wraps  MAMEs  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	speci-
	      fied 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	speci-
	      fied 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.

   Memory bank
       Wraps  MAMEs  memory_bank class,	representing a named memory zone indi-
       rection.

   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.

   Memory region
       Wraps MAMEs 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  re-
	      quested.	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	speci-
	      fied  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	speci-
	      fied  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 re-
	      gion 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.

   Lua Input System Classes
       Allows scripts to get input from	the user, and access I/O ports in  the
       emulated	system.

        I/O port manager

        Natural keyboard manager

        Keyboard input	device

        I/O port

        I/O port field

        Live I/O port field state

        Input type

        Input manager

        Input code poller

        Input sequence	poller

        Input sequence

        Host input device class

        Host input device

        Host input device item

        UI input manager

   I/O port manager
       Wraps MAMEs 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 ma-
	      chine.

   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 cur-
	      rently pressed.  The input type may be an	enumerated value or an
	      input type 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 num-
	      ber is a zero-based index.  If the player	 number	 is  not  sup-
	      plied, 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 num-
	      ber is a zero-based index.  Returns an integer giving the	group-
	      ing 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 input sequence	for the	specified input	 type,
	      player  number and sequence type.	 The input type	may be an enu-
	      merated value or an input	type 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  se-
	      quence  type  is supplied, it must be "standard",	"increment" or
	      "decrement"; if it is not	supplied, it is	assumed	to  be	"stan-
	      dard".

	      This provides access to general input assignments.

       ioport:set_type_seq(type, [player], seqtype, seq)
	      Set  the configured input	sequence for the specified input type,
	      player number and	sequence type.	The input type may be an  enu-
	      merated  value  or an input type 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 input types.	Keys  are  arbitrary  indices.
	      All supported operations have O(1) complexity.

       ioport.ports[]
	      Gets  the	 emulated  I/O ports 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.

   Natural keyboard manager
       Wraps MAMEs natural_keyboard class, which manages emulated keyboard and
       keypad inputs.

   Instantiation
       manager.machine.natkeyboard
	      Gets  the	 global	natural	keyboard manager instance for the emu-
	      lated 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 in-
	      terpreted	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  key-
	      board  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	managers input
	      buffer is	empty.

       natkeyboard.full	(read-only)
	      A	Boolean	indicating whether the natural keyboard	managers input
	      buffer is	full.

       natkeyboard.can_post (read-only)
	      A	Boolean	indicating whether the emulated	system supports	 post-
	      ing 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 man-
	      ager  translates	host  character	 input to emulated system key-
	      strokes.

       natkeyboard.keyboards[]
	      Gets the keyboard/keypad input devices in	the  emulated  system,
	      indexed  by absolute device tag.	Index get has O(n) complexity;
	      all other	supported operations have O(1) complexity.

   Keyboard input device
       Represents a keyboard or	keypad input device  managed  by  the  natural
       keyboard	manager.  Note that this is not	a 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 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 devices keyboard	and/or	keypad
	      inputs are enabled.

   I/O port
       Wraps MAMEs 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	speci-
	      fied  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 I/O	port field 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  ac-
	      tive 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 fields indexed by	name.

   I/O port field
       Wraps  MAMEs  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	fields
	      regular behaviour.

       field:set_input_seq(seqtype, seq)
	      Set the input sequence 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 input sequence	 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 input sequence for the specified sequence	 type.
	      This  overrides  the default input assignment for	a specific in-
	      put.  The	sequence  type	must  be  "standard",  "increment"  or
	      "decrement".

       field:default_input_seq(seq_type)
	      Gets the default input sequence for the specified	sequence type.
	      If  the  default	assignment is not overridden, this returns the
	      general input assignment for the fields  input  type.   The  se-
	      quence 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 I/O port that	the field belongs to.

       field.live (read-only)
	      The live state 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 systems 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 fields 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",	 "con-
	      troller",	"config", "dipswitch" or "misc".

       field.is_analog (read-only)
	      A	 Boolean indicating whether the	field is an analog axis	or po-
	      sitional 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 re-
	      quired 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 conven-
	      tion (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	incre-
	      mental 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 fields range	 to  crosshair
	      position.	  A  value of one (1) translates the fields full range
	      to the full width	or height the screen.

       field.crosshair_offset (read-only)
	      The offset for translating the fields range to  crosshair	 posi-
	      tion.

       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.

   Live	I/O port field state
       Wraps MAMEs 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.

   Input type
       Wraps MAMEs 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	 digi-
	      tal.   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.

   Input manager
       Wraps  MAMEs  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  correspond-
	      ing  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  correspond-
	      ing  to the specified code has moved away	from the neutral posi-
	      tion 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 de-
	      vice that	is not present.

       input:seq_pressed(seq)
	      Returns a	Boolean	indicating whether the supplied	input sequence
	      is currently pressed.

       input:seq_clean(seq)
	      Remove invalid elements from the supplied	input  sequence.   Re-
	      turns the	new, cleaned input sequence.

       input:seq_name(seq)
	      Get display text for an input sequence.

       input:seq_to_tokens(seq)
	      Convert  an  input  sequence  to a token string.	This should be
	      used when	saving configuration.

       input:seq_from_tokens(tokens)
	      Convert a	token string to	an input  sequence.   This  should  be
	      used when	loading	configuration.

       input:axis_code_poller()
	      Returns  an input	code poller for	obtaining an analog host input
	      code.

       input:switch_code_poller()
	      Returns an input code poller for obtaining a host	 switch	 input
	      code.

       input:keyboard_code_poller()
	      Returns  an  input code poller for obtaining a host switch input
	      code that	only considers keyboard	input devices.

       input:axis_sequence_poller()
	      Returns an input sequence	poller for obtaining an	input sequence
	      for configuring an analog	input assignment.

       input:axis_sequence_poller()
	      Returns an input sequence	poller for obtaining an	input sequence
	      for configuring a	digital	input assignment.

   Properties
       input.device_classes[] (read-only)
	      Gets a table of host input device	classes	indexed	by name.

   Input code poller
       Wraps MAMEs 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.

   Input sequence poller
       Wraps  MAMEs  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 input	sequence.  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.

   Input sequence
       Wraps  MAMEs 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 input manager  methods.   Use  an  input  sequence
       poller 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	 (con-
	      tains 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	 rela-
	      tive 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.

   Host	input device class
       Wraps MAMEs 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  host	input  devices in the class.  Keys are
	      one-based	indices.

   Host	input device
       Wraps MAMEs 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 hu-
	      man-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 input items, indexed by item ID.	The item ID is
	      an enumerated value.

   Host	input device item
       Wraps MAMEs 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 enumer-
	      ated 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 input	manager	with the items code.

       item.code (read-only)
	      The  input  items	 identification	code.  This is used by several
	      input manager methods.

       item.token (read-only)
	      The input	items token string.  Note that this is a  token	 frag-
	      ment  for	 the item itself, and does not include the device por-
	      tion.  The full token for	the item can be	 obtained  by  calling
	      the  code_to_token  method  on  the input	manager	with the items
	      code.

       item.current (read-only)
	      The items	current	value.	This is	a signed integer where zero is
	      the neutral position.

   UI input manager
       Wraps MAMEs 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 up-
	      dates.

   Lua Render System Classes
       The render system is responsible	for drawing what you see in MAMEs win-
       dows, including emulated	screens, artwork, and UI elements.

        Render	bounds

        Render	colour

        Palette

        Bitmap

        Render	texture

        Render	manager

        Render	target

        Render	container

        Container user	settings

        Layout	file

        Layout	view

        Layout	view item

        Layout	element

   Render bounds
       Wraps MAMEs 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 dont	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 rectangles 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	rectangles  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  coordi-
	      nate 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 dont  necessar-
	      ily  have	 equal	X  and	Y  scales.  A rectangle	representing a
	      square in	the final output doesnt	necessarily have an aspect ra-
	      tio of 1.

   Render colour
       Wraps MAMEs 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  multipli-
	      cation 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 objects alpha, red, green and blue channel val-
	      ues.

	      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).

   Palette
       Wraps MAMEs palette_t class, which represents a table of	 colours  that
       can  be	looked	up by zero-based index.	 Palettes always contain addi-
       tional special entries for black	and white.

       Each colour has an associated contrast adjustment value.	 Each  adjust-
       ment  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	inten-
       sity), inclusive.  Colour channel values	are not	pre-multiplied by  the
       alpha  value.   Channel	values are packed into the bytes of 32-bit un-
       signed integers,	in the order alpha, red, green,	blue from most-signif-
       icant 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  ini-
	      tialised	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 adjust-
	      ment 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 individ-
	      ual 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  in-
	      valid.

       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 in-
	      valid.

       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  in-
	      valid.

       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 in-
	      valid.

       palette:entry_set_contrast(index, level)
	      Sets the contrast	adjustment value for the colour	at the	speci-
	      fied 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  in-
	      valid.

       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	float-
	      ing-point	number.

   Bitmap
       Wraps implementations of	MAMEs 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 palette.

	      If no width and height are specified, they  are  assumed	to  be
	      zero.  If	the width is specified,	the height must	also be	speci-
	      fied.   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/bot-
	      tom  of each column, respectively.  If an	X slop value is	speci-
	      fied, 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 palette.

	      If  no  width  and  height are specified,	they are assumed to be
	      zero.  If	the width is specified,	the height must	also be	speci-
	      fied.  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/bot-
	      tom of each column, respectively.	 If an X slop value is	speci-
	      fied,  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 palette.

	      If no width and height are specified, they  are  assumed	to  be
	      zero.  If	the width is specified,	the height must	also be	speci-
	      fied.   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/bot-
	      tom  of each column, respectively.  If an	X slop value is	speci-
	      fied, 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 palette.

	      If  no  width  and  height are specified,	they are assumed to be
	      zero.  If	the width is specified,	the height must	also be	speci-
	      fied.  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/bot-
	      tom of each column, respectively.	 If an X slop value is	speci-
	      fied,  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 hori-
	      zontal 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	speci-
	      fied.   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/bot-
	      tom  of each column, respectively.  If an	X slop value is	speci-
	      fied, 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)	 chan-
	      nel.   Each pixel	is represented by a 32-bit integer value.  The
	      most significant byte of the pixel value is  ignored.   The  re-
	      maining three bytes, from	most significant to least significant,
	      are the unsigned 8-bit unsigned red, green and blue channel val-
	      ues (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	speci-
	      fied.  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/bot-
	      tom of each column, respectively.	 If an X slop value is	speci-
	      fied,  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 cor-
	      respond 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	speci-
	      fied.  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/bot-
	      tom of each column, respectively.	 If an X slop value is	speci-
	      fied,  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, pre-
	      venting resizing and reallocation.

	      If no coordinates	are specified, the new bitmap will represent a
	      view of the source bitmaps current clipping rectangle.  If coor-
	      dinates 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 bitmaps 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,  pre-
	      venting resizing and reallocation.

	      If no coordinates	are specified, the new bitmap will represent a
	      view of the source bitmaps current clipping rectangle.  If coor-
	      dinates  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 bitmaps 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, pre-
	      venting resizing and reallocation.

	      If no coordinates	are specified, the new bitmap will represent a
	      view of the source bitmaps current clipping rectangle.  If coor-
	      dinates 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 bitmaps 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,  pre-
	      venting resizing and reallocation.

	      If no coordinates	are specified, the new bitmap will represent a
	      view of the source bitmaps current clipping rectangle.  If coor-
	      dinates  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 bitmaps 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	 real-
	      location.

	      If no coordinates	are specified, the new bitmap will represent a
	      view of the source bitmaps current clipping rectangle.  If coor-
	      dinates  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
	      bitmaps 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, pre-
	      venting resizing and reallocation.

	      If no coordinates	are specified, the new bitmap will represent a
	      view of the source bitmaps current clipping rectangle.  If coor-
	      dinates 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
	      bitmaps 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, pre-
	      venting resizing and reallocation.

	      If no coordinates	are specified, the new bitmap will represent a
	      view of the source bitmaps current clipping rectangle.  If coor-
	      dinates 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
	      bitmaps 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  in-
	      valid or not a supported format.

   Methods
       bitmap:cliprect()
	      Returns  the  left,  top,	 right	and  bottom coordinates	of the
	      bitmaps 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  bitmaps  storage  is	 referenced  by	 another  bitmap  or a
	      texture.

       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 an-
	      other 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 pix-
	      els 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,	 irre-
	      spective 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 bitmaps  storage  is	referenced  by	another	 bitmap	 or  a
	      texture.

       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 pix-
	      els 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 bitmaps 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	exist-
	      ing storage is used, its contents	will not be changed).

	      Raises  an error if the bitmaps storage is referenced by another
	      bitmap or	a texture.

       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	repre-
	      sent  a  view  of	the source bitmaps 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  bot-
	      tom  right corner	at (x1,	y1) in the source bitmap.  Coordinates
	      are in units of pixels.  The bottom right	coordinates are	inclu-
	      sive.

	      The source bitmap	will be	locked,	preventing resizing and	 real-
	      location.	  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 bitmaps clipping rectangle;	if the
	      bitmaps storage is referenced by another bitmap or a texture; 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	speci-
	      fied, the	bitmaps	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 val-
	      ues depends on the format	of the bitmap.	Raises an error	if co-
	      ordinates	are specified representing a rectangle not fully  con-
	      tained within the	bitmaps	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.  Coordi-
	      nates  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 rectan-
	      gle 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 render colour.

   Properties
       bitmap.palette (read/write)
	      The palette used to translate pixel values to colours.  Only ap-
	      plicable 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	bitmaps	storage	in pixels.  That is, the  dif-
	      ference  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	bitmaps	storage	in bytes.  That	is,  the  dif-
	      ference  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 bitmaps storage	is  referenced
	      by another bitmap	or a texture.

   Render texture
       Wraps  MAMEs  render_texture  class, representing a texture that	cam be
       drawn in	a render container.  Render textures must be freed before  the
       emulation session ends.

   Instantiation
       manager.machine.render:texture_alloc(bitmap)
	      Creates  a render	texture	based on a bitmap.  The	bitmap must be
	      owned by the Lua script, and must	use the	Y'CbCr,	 RGB  or  ARGB
	      format.  The bitmaps 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).

   Render manager
       Wraps MAMEs render_manager class, responsible for managing render  tar-
       gets and	textures.

   Instantiation
       manager.machine.render
	      Gets  the	 global	render manager instance	for the	emulation ses-
	      sion.

   Methods
       render:texture_alloc(bitmap)
	      Creates a	render texture based on	a bitmap.  The bitmap must  be
	      owned  by	 the  Lua script, and must use the Y'CbCr, RGB or ARGB
	      pixel format.  The bitmaps 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 num-
	      ber.

       render.ui_target	(read-only)
	      The  render  target  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 render container 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.

   Render target
       Wraps  MAMEs render_target class, which represents a video output chan-
       nel.  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 (in-
	      cluding 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 render container 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)  complex-
	      ity.

       target.width (read-only)
	      The width	of the render target in	output pixels.	This is	an in-
	      teger.

       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  targets  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 tar-
	      get 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)  com-
	      plexity.

       target.current_view (read-only)
	      The  currently  selected	view for the render target.  This is a
	      layout view 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  cur-
	      rently 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.

   Render container
       Wraps MAMEs render_container class.

   Instantiation
       manager.machine.render.ui_container
	      Gets  the	 render	container used to draw the user	interface, in-
	      cluding 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 posi-
	      tions.

	      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	 inte-
	      ger,  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.	 Chan-
	      nel 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 textures 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  rec-
	      tangle extends beyond the	containers 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-signifi-
	      cant 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,  horizon-
	      tally  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   al-
	      pha/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 transpar-
	      ent.

   Properties
       container.user_settings (read/write)
	      The containers user settings.  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 containers X scale factor.  This is a	floating-point number.

       container.yscale	(read/write)
	      The containers Y scale factor.  This is a	floating-point number.

       container.xoffset (read/write)
	      The containers X offset.	This is	a floating-point number	 where
	      one (1) corresponds to the X size	of the container.

       container.yoffset (read/write)
	      The  containers 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.

   Container user settings
       Wraps MAMEs render_container::user_settings class,  representing	 image
       adjustments applied to a	render container.

   Instantiation
       manager.machine.screens[tag].container
	      Gets the current render container	user settings for a given emu-
	      lated 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	float-
	      ing-point	number.

       settings.xscale (read/write)
	      The containers X scale factor.  This is a	floating-point number.

       settings.yscale (read/write)
	      The containers Y scale factor.  This is a	floating-point number.

       settings.xoffset	(read/write)
	      The containers X offset.	This is	a floating-point number	 where
	      one (1) represents the X size of the container.

       settings.yoffset	(read/write)
	      The  containers Y	offset.	 This is a floating-point number where
	      one (1) represents the Y size of the container.

   Layout file
       Wraps MAMEs layout_file class, representing the	views  loaded  from  a
       layout  file  for  use by a render target.  Note	that layout file call-
       backs are not run as coroutines.

   Instantiation
       A layout	file object is supplied	to its layout script in	the file vari-
       able.  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 elements 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 views	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  de-
	      vices  will  not	be  created  if	said slot card devices are not
	      present in the emulated system.

   Layout view
       Wraps MAMEs layout_view class, representing a view  that	 can  be  dis-
       played  in  a  render target.  Views are	created	from XML layout	files,
       which may be loaded from	external artwork, internal to MAME,  or	 auto-
       matically  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 layout file.	  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 be-
	      long 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 vis-
	      ible  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  views  di-
	      mensions 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 ar-
	      guments.	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 items 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	 indi-
	      cate the device that caused the layout file to be	loaded when it
	      isnt 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	 render	bounds 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 ra-
	      tio.

       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.

   Layout view item
       Wraps MAMEs layout_view_item class, representing	an item	 in  a	layout
       view.  An item is drawn as a rectangular	textured surface.  The texture
       is  supplied by an emulated screen or a layout element.	Note that lay-
       out 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  items	 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 bind-
	      ings 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 inte-
	      ger.  Call with nil to restore the default animation state call-
	      back (based on bindings in the XML layout	file).

	      Note that	the function must not access the items 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 render bounds ob-
	      ject in render target coordinates.  Call with nil	to restore the
	      default bounds callback (based on	the items animation state  and
	      bounds child elements in the XML layout file).

	      Note  that  the  function	must not access	the items bounds prop-
	      erty, 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	render
	      colour  object.	Call  with  nil	 to restore the	default	colour
	      callback (based on the items animation state and color child el-
	      ements in	the XML	layout file).

	      Note that	the function must not access the items 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 elements	width.
	      The function must	 accept	 no  arguments	and  return  a	float-
	      ing-point	 value.	 Call with nil to restore the default horizon-
	      tal scroll window	size callback (based on	the xscroll child ele-
	      ment in the XML layout file).

	      Note that	the function must not access the  items	 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 elements 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 items 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 hori-
	      zontally,	 a value of 1.0	places the horizontal scroll window at
	      the right	edge of	the associated element;	if the item wraps hor-
	      izontally, 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  lay-
	      out file).

	      Note  that  the  function	must not access	the items 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  ver-
	      tically, a value of 1.0 places the vertical scroll window	at the
	      bottom  edge of the associated element; if the item wraps	verti-
	      cally, a value of	1.0 corresponds	to wrapping back to  the  left
	      edge of the associated element.  The function must accept	no ar-
	      guments and return a floating-point value.  Call with nil	to re-
	      store  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  items  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 element used to draw the item, or nil	for screen items.

       item.bounds_animated (read-only)
	      A	Boolean	indicating whether the items bounds depend on its ani-
	      mation state.

       item.color_animated (read-only)
	      A	Boolean	indicating whether the items colour depends on its an-
	      imation state.

       item.bounds (read-only)
	      The items	bounds for the current state.  This is a render	bounds
	      object in	render target coordinates.

       item.color (read-only)
	      The items	colour for the	current	 state.	  The  colour  of  the
	      screen or	element	texture	is multiplied by this colour.  This is
	      a	render colour 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	items  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 represent-
	      ing a proportion of the associated elements width.

       item.scroll_size_y (read/write)
	      Get the items 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 propor-
	      tion of the associated elements height.

       item.scroll_pos_x (read/write)
	      Get  the items 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 items vertical scroll position for the current state, or
	      set the vertical position	size to	use in the  absence  of	 bind-
	      ings.  This is a floating-point value.

       item.blend_mode (read-only)
	      Get  the	items  blend  mode.  This is an	integer	value, where 0
	      means no blending, 1 means alpha blending, 2 means RGB multipli-
	      cation, 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.

   Layout element
       Wraps  MAMEs  layout_element  class, representing a visual element that
       can be drawn in a layout	view.  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 view item.

   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
	      elements components have been drawn.  The	function is passed two
	      arguments:  the  element	state (an integer) and the 32-bit ARGB
	      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.

   Lua Debugger	Classes
       Some  of	 MAMEs	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).

        Symbol	table

        Parsed	expression

        Symbol	entry

        Debugger manager

        Device	debugger interface

        Breakpoint

        Watchpoint

        Expression error

   Symbol table
       Wraps  MAMEs  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 ma-
	      chine,

       emu.symbol_table(parent,	[device])
	      Creates a	new symbol table with the specified parent symbol  ta-
	      ble.   If	 a  device  is specified and it	implements device_mem-
	      ory_interface, it	will be	used as	the base for  looking  up  ad-
	      dress  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 de-
	      vice.  If	the device implements device_memory_interface, it will
	      be used as the base for looking up address spaces	and memory re-
	      gions.  Note that	if  a  device  that  does  not	implement  de-
	      vice_memory_interface  is	 supplied, it will only	be used	to de-
	      termine 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  sup-
	      plied,  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 symbol entry.

       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  sup-
	      plied, the setter	must be	a function that	accepts	a single inte-
	      ger  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 symbol entry.

       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 symbol entry.

       symbols:find(name)
	      Returns  the  symbol  entry  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 symbol entry 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 er-
	      ror 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 inte-
	      ger 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
	      memory accesses in debugger expressions for access type specifi-
	      cations that can be used for the	space  argument.   The	access
	      size  is specified in bytes, and must be 1, 2, 4 or 8.  The dis-
	      able_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
	      memory accesses in debugger expressions for access type specifi-
	      cations that can be used for the	space  argument.   The	access
	      size  is specified in bytes, and must be 1, 2, 4 or 8.  The dis-
	      able_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	speci-
	      fied in bytes, and must be 1, 2, 4, or 8.	 If the	apply_transla-
	      tion 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  tables memory modified function
	      will be called after the value is	written.  The value  will  not
	      be  written  and the symbol tables memory	modified function will
	      not be called if address translation fails.

   Properties
       symbols.entries[]
	      The symbol entries 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 par-
	      ent.

   Parsed expression
       Wraps MAMEs parsed_expression class, which represents a	tokenised  de-
       bugger  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	symbol
	      table 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	symbol table.  If the default base for
	      interpreting integer literals is not supplied, 16	is used	(hexa-
	      decimal).	 Raises	an expression error  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  con-
	      tents  of	 the  expression  if  it  is  not  empty.   Raises  an
	      expression error 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	expression error 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 symbol table used for	to look	up symbols in the expression.

   Symbol entry
       Wraps  MAMEs  symbol_entry class, which represents an entry in a	symbol
       table.  Note that symbol	entries	must not be used after the symbol  ta-
       ble they	belong to is destroyed.

   Instantiation
       symbols:add(name, [value])
	      Adds an integer symbol to	a symbol table,	returning the new sym-
	      bol entry.

       symbols:add(name, getter, [setter], [format])
	      Adds an integer symbol to	a symbol table,	returning the new sym-
	      bol entry.

       symbols:add(name, minparams, maxparams, execute)
	      Adds function symbol to a	symbol table, 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 sym-
	      bol  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.  At-
	      tempting to get or set the value of a function symbol raises  an
	      error.

   Debugger manager
       Wraps  MAMEs  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  de-
	      bugger 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.

   Device debugger interface
       Wraps MAMEs 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  instruc-
	      tion 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 con-
	      dition  and action.  If the action is not	specified, it defaults
	      to just breaking into the	debugger.  Returns the breakpoint num-
	      ber 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 de-
	      vice 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 de-
	      vice 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  de-
	      vice  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 breakpoint	objects.

       debug:wpset(space, type,	addr, len, [cond], [act])
	      Set  a  watchpoint over the specified address range, with	an op-
	      tional 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	 actu-
	      ally  triggered  the watchpoint, the variable 'wpdata' is	set to
	      the data that is being read or written, and  the	variable  'wp-
	      size' 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 de-
	      vice 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 de-
	      vice 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  de-
	      vice  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 watchpoint objects.

   Breakpoint
       Wraps  MAMEs  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 breakpoints index.  The can be used to  enable,  disable  or
	      clear the	breakpoint via the CPU debugger	interface.

       breakpoint.enabled (read/write)
	      A	 Boolean  indicating  whether  the breakpoint is currently en-
	      abled.

       breakpoint.address (read-only)
	      The breakpoints 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	speci-
	      fied.

       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.

   Watchpoint
       Wraps MAMEs 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 emu-
	      lated CPU	device,	or nil if no watchpoint	in the	address	 space
	      corresponds to the specified index.

   Properties
       watchpoint.index	(read-only)
	      The  watchpoints	index.	 The can be used to enable, disable or
	      clear the	watchpoint via the CPU debugger	interface.

       watchpoint.enabled (read/write)
	      A	Boolean	indicating whether the	watchpoint  is	currently  en-
	      abled.

       watchpoint.type (read-only)
	      Either  "r",  "w"	or "rw"	for a read, write or read/write	watch-
	      point.

       watchpoint.address (read-only)
	      The starting address of the watchpoints address range.

       watchpoint.length (read-only)
	      The length of the	watchpoints 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	speci-
	      fied.

       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.

   Expression error
       Wraps MAMEs expression_error class, describing an error occurring while
       parsing or executing a debugger expression.  Raised on errors when  us-
       ing  parsed expressions.	 Can be	converted to a string to provide a de-
       scription 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 en-
	      countered.

   Interactive Lua console tutorial
       First run an arcade game	in MAME	at the command prompt with  the	 -con-
       sole 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.  Lets
       pause it:

	  [MAME]> emu.pause()
	  [MAME]>

       Even without textual feedback on	the console, youll notice the game  is
       now  paused.   In general, commands are quiet and only print error mes-
       sages.

       You can check the version of MAME you are running with:

	  [MAME]> print(emu.app_name() .. " " .. emu.app_version())
	  mame 0.255

       Lets examine the	emulated screens.  First, enumerate the	screen devices
       in the system:

	  [MAME]> for tag, screen in pairs(manager.machine.screens) do print(tag) end
	  :screen

       manager.machine is the running machine object for the current emulation
       session.	 We will be using this frequently.  screens is a  device  enu-
       merator	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  us-
       ing 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 run-
       ning 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

MAME EXTERNAL TOOLS
       This  section  describes	 additional tools that are built alongside and
       typically distributed with MAME.

   chdman  CHD (Compressed Hunks of Data) File Manager
       chdman can be used to create, convert, check the	integrity of  and  ex-
       tract data from media images in CHD (Compressed Hunks of	Data) format.

       The basic usage is chdman <command> <option>...

        Common	options

        Commands

	  info

	  verify

	  createraw

	  createhd

	  createcd

	  createdvd

	  createld

	  extractraw

	  extracthd

	  extractcd

	  extractdvd

	  extractld

	  addmeta

	  delmeta

	  dumpmeta

	  listtemplates

        Compression algorithms

   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  com-
	      mands.  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 addi-
	      tional 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 com-
	      mands that produce output	files.	The output file	 formats  sup-
	      ported 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  compression  algorithms for sup-
	      ported 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 bet-
	      ter  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.

   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  me-
	      dia.   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 sup-
	      plied,  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>,<sec-
	 tors>

        --template <template> / -tp <template>

       Creates	a blank	(zero-filled) hard disk	image if no input file is sup-
       plied.	The  input   start/length   (--inputstartbyte/-isb,   --input-
       starthunk/-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 modi-
       fies 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.

   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 com-
	      pression 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 au-
	      dio 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 compres-
	      sion ratios than zlib deflate, but older software	may  not  sup-
	      port 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.

   Imgtool - A generic image manipulation tool for MAME
       Imgtool	is  a  tool  for  the maintenance and manipulation of disk and
       other types of images that MAME users need to deal with.	Functions  in-
       clude retrieving	and storing files and CRC checking/validation.

       Imgtool	is  part of the	MAME project. It shares	large portions of code
       with MAME, and its existence would not be if it were not	for  MAME.  As
       such, the distribution terms are	the same as MAME. Please read the MAME
       license thoroughly.

       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 man-
       ner along the lines of this:
	  imgtool <subcommand> <format>	<image>	...

        <subcommand> is the name of the subcommand

        <format> is the format	of the image

        <image> is the	filename of the	image

       Example usage:
	      imgtool dir coco_jvc_rsdos myimageinazip.zip

	      imgtool get coco_jvc_rsdos myimage.dsk myfile.bin	mynewfile.txt

	      imgtool getall coco_jvc_rsdos myimage.dsk

       Further details vary with each subcommand.  Also	note that not all sub-
       commands	are applicable or supported for	different image	formats.

   Imgtool Subcommands
       create
	  imgtool create <format> <imagename> [--(createoption)=value]

	   <format> is	the image format, e.g. coco_jvc_rsdos

	   <imagename>	is the image filename; can specify a ZIP file for  im-
	    age	name

	  Creates an image

       dir
	  imgtool dir <format> <imagename> [path]

	   <format> is	the image format, e.g. coco_jvc_rsdos

	   <imagename>	 is the	image filename;	can specify a ZIP file for im-
	    age	name

	  Lists	the contents of	an image

       get
	  imgtool get <format> <imagename> <filename> [newname]	[--filter=fil-
	  ter] [--fork=fork]

	   <format> is	the image format, e.g. coco_jvc_rsdos

	   <imagename>	is the image filename; can specify a ZIP file for  im-
	    age	name

	  Gets a single	file from an image

       put
	  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  im-
	    age	name

	  Puts a single	file on	an image (wildcards supported)

       getall
	  imgtool getall <format> <imagename> [path] [--filter=filter]

	   <format> is	the image format, e.g. coco_jvc_rsdos

	   <imagename>	 is the	image filename;	can specify a ZIP file for im-
	    age	name

	  Gets all files off an	image

       del
	  imgtool del <format> <imagename> <filename>...

	   <format> is	the image format, e.g. coco_jvc_rsdos

	   <imagename>	is the image filename; can specify a ZIP file for  im-
	    age	name

	  Deletes a file on an image

       mkdir
	  imgtool mkdir	<format> <imagename> <dirname>

	   <format> is	the image format, e.g. coco_jvc_rsdos

	   <imagename>	 is the	image filename;	can specify a ZIP file for im-
	    age	name

	  Creates a subdirectory on an image

       rmdir
	  imgtool rmdir	<format> <imagename> <dirname>...

	   <format> is	the image format, e.g. coco_jvc_rsdos

	   <imagename>	is the image filename; can specify a ZIP file for  im-
	    age	name

	  Deletes a subdirectory on an image

       readsector
	  imgtool  readsector  <format>	 <imagename>  <track>  <head> <sector>
	  <filename>

	   <format> is	the image format, e.g. coco_jvc_rsdos

	   <imagename>	is the image filename; can specify a ZIP file for  im-
	    age	name

	  Read a sector	on an image and	output it to specified <filename>

       writesector
	  imgtool  writesector	<format>  <imagename>  <track> <head> <sector>
	  <filename>

	   <format> is	the image format, e.g. coco_jvc_rsdos

	   <imagename>	is the image filename; can specify a ZIP file for  im-
	    age	name

	  Write	a sector to an image from specified <filename>

       identify

	   <format> is	the image format, e.g. coco_jvc_rsdos

	   <imagename>	 is the	image filename;	can specify a ZIP file for im-
	    age	name

	  imgtool identify <imagename>

       listformats
	  Lists	all image file formats supported by imgtool

       listfilters
	  Lists	all filters supported by imgtool

       listdriveroptions
	  imgtool listdriveroptions <format>

	   <format> is	the image format, e.g. coco_jvc_rsdos

	  Lists	all format-specific options for	the 'put'  and	'create'  com-
	  mands

   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:

       ascii
	  Translates end-of-lines to the appropriate format

       cocobas
	  Processes tokenized TRS-80 Color Computer (CoCo) BASIC programs

       dragonbas
	  Processes tokenized Tano/Dragon Data Dragon 32/64 BASIC programs

       macbinary
	  Processes Apple MacBinary-formatted (merged forks) files

       vzsnapshot
	  [todo: VZ Snapshot? Find out what this is...]

       vzbas
	  Processes Laser/VZ Tokenized Basic Files

       thombas5
	  Thomson MO5 w/ BASIC 1.0, Tokenized Files (read-only,	auto-decrypt)

       thombas7
	  Thomson TO7 w/ BASIC 1.0, Tokenized Files (read-only,	auto-decrypt)

       thombas128
	  Thomson w/ BASIC 128/512, Tokenized Files (read-only,	auto-decrypt)

       thomcrypt
	  Thomson BASIC, Protected file	encryption (no tokenization)

       bm13bas
	  Basic	Master Level 3 Tokenized Basic Files

   Imgtool Format Info
   Amiga floppy	disk image (OFS/FFS format) - (amiga_floppy)
       Driver specific options for module 'amiga_floppy':

       No image	specific file options

       Image specific creation options (usable on the 'create' command):
	      +--------------+----------------+---------------------+
	      |	Option	     | Allowed values |	Description	    |
	      +--------------+----------------+---------------------+
	      |	--density    | dd/hd	      |	Density		    |
	      +--------------+----------------+---------------------+
	      |	--filesystem | ofs/ffs	      |	File system	    |
	      +--------------+----------------+---------------------+
	      |	--mode	     | none/intl/dirc |	File system options |
	      +--------------+----------------+---------------------+

   Apple ][ DOS	order disk image (ProDOS format) - (apple2_do_prodos_525)
       Driver specific options for module 'apple2_do_prodos_525':

       No image	specific file options

       Image specific creation options (usable on the 'create' command):
		+-----------------+----------------+--------------+
		| Option	  | Allowed values | Description  |
		+-----------------+----------------+--------------+
		| --heads	  | 1		   | Heads	  |
		+-----------------+----------------+--------------+
		| --tracks	  | 35		   | Tracks	  |
		+-----------------+----------------+--------------+
		| --sectors	  | 16		   | Sectors	  |
		+-----------------+----------------+--------------+
		| --sectorlength  | 256		   | Sector Bytes |
		+-----------------+----------------+--------------+
		| --firstsectorid | 0		   | First Sector |
		+-----------------+----------------+--------------+

   Apple ][ Nibble order disk image (ProDOS format) - (apple2_nib_prodos_525)
       Driver specific options for module 'apple2_nib_prodos_525':

       No image	specific file options

       Image specific creation options (usable on the 'create' command):
		+-----------------+----------------+--------------+
		| Option	  | Allowed values | Description  |
		+-----------------+----------------+--------------+
		| --heads	  | 1		   | Heads	  |
		+-----------------+----------------+--------------+
		| --tracks	  | 35		   | Tracks	  |
		+-----------------+----------------+--------------+
		| --sectors	  | 16		   | Sectors	  |
		+-----------------+----------------+--------------+
		| --sectorlength  | 256		   | Sector Bytes |
		+-----------------+----------------+--------------+
		| --firstsectorid | 0		   | First Sector |
		+-----------------+----------------+--------------+

   Apple ][ ProDOS order disk image (ProDOS format) - (apple2_po_prodos_525)
       Driver specific options for module 'apple2_po_prodos_525':

       No image	specific file options

       Image specific creation options (usable on the 'create' command):
		+-----------------+----------------+--------------+
		| Option	  | Allowed values | Description  |
		+-----------------+----------------+--------------+
		| --heads	  | 1		   | Heads	  |
		+-----------------+----------------+--------------+
		| --tracks	  | 35		   | Tracks	  |
		+-----------------+----------------+--------------+
		| --sectors	  | 16		   | Sectors	  |
		+-----------------+----------------+--------------+
		| --sectorlength  | 256		   | Sector Bytes |
		+-----------------+----------------+--------------+
		| --firstsectorid | 0		   | First Sector |
		+-----------------+----------------+--------------+

   Apple ][gs 2IMG disk	image (ProDOS format) -	(apple35_2img_prodos_35)
       Driver specific options for module 'apple35_2img_prodos_35':

       No image	specific file options

       Image specific creation options (usable on the 'create' command):
		+-----------------+----------------+--------------+
		| Option	  | Allowed values | Description  |
		+-----------------+----------------+--------------+
		| --heads	  | 1-2		   | Heads	  |
		+-----------------+----------------+--------------+
		| --tracks	  | 80		   | Tracks	  |
		+-----------------+----------------+--------------+
		| --sectorlength  | 512		   | Sector Bytes |
		+-----------------+----------------+--------------+
		| --firstsectorid | 0		   | First Sector |
		+-----------------+----------------+--------------+

   Apple DiskCopy disk image (Mac HFS Floppy) -	(apple35_dc_mac_hfs)
       Driver specific options for module 'apple35_dc_mac_hfs':

       No image	specific file options

       Image specific creation options (usable on the 'create' command):
		+-----------------+----------------+--------------+
		| Option	  | Allowed values | Description  |
		+-----------------+----------------+--------------+
		| --heads	  | 1-2		   | Heads	  |
		+-----------------+----------------+--------------+
		| --tracks	  | 80		   | Tracks	  |
		+-----------------+----------------+--------------+
		| --sectorlength  | 512		   | Sector Bytes |
		+-----------------+----------------+--------------+
		| --firstsectorid | 0		   | First Sector |
		+-----------------+----------------+--------------+

   Apple DiskCopy disk image (Mac MFS Floppy) -	(apple35_dc_mac_mfs)
       Driver specific options for module 'apple35_dc_mac_mfs':

       No image	specific file options

       Image specific creation options (usable on the 'create' command):
		+-----------------+----------------+--------------+
		| Option	  | Allowed values | Description  |
		+-----------------+----------------+--------------+
		| --heads	  | 1-2		   | Heads	  |
		+-----------------+----------------+--------------+
		| --tracks	  | 80		   | Tracks	  |
		+-----------------+----------------+--------------+
		| --sectorlength  | 512		   | Sector Bytes |
		+-----------------+----------------+--------------+
		| --firstsectorid | 0		   | First Sector |
		+-----------------+----------------+--------------+

   Apple DiskCopy disk image (ProDOS format) - (apple35_dc_prodos_35)
       Driver specific options for module 'apple35_dc_prodos_35':

       No image	specific file options

       Image specific creation options (usable on the 'create' command):
		+-----------------+----------------+--------------+
		| Option	  | Allowed values | Description  |
		+-----------------+----------------+--------------+
		| --heads	  | 1-2		   | Heads	  |
		+-----------------+----------------+--------------+
		| --tracks	  | 80		   | Tracks	  |
		+-----------------+----------------+--------------+
		| --sectorlength  | 512		   | Sector Bytes |
		+-----------------+----------------+--------------+
		| --firstsectorid | 0		   | First Sector |
		+-----------------+----------------+--------------+

   Apple raw 3.5" disk image (Mac HFS Floppy) -	(apple35_raw_mac_hfs)
       Driver specific options for module 'apple35_raw_mac_hfs':

       No image	specific file options

       Image specific creation options (usable on the 'create' command):
		+-----------------+----------------+--------------+
		| Option	  | Allowed values | Description  |
		+-----------------+----------------+--------------+
		| --heads	  | 1-2		   | Heads	  |
		+-----------------+----------------+--------------+
		| --tracks	  | 80		   | Tracks	  |
		+-----------------+----------------+--------------+
		| --sectorlength  | 512		   | Sector Bytes |
		+-----------------+----------------+--------------+
		| --firstsectorid | 0		   | First Sector |
		+-----------------+----------------+--------------+

   Apple raw 3.5" disk image (Mac MFS Floppy) -	(apple35_raw_mac_mfs)
       Driver specific options for module 'apple35_raw_mac_mfs':

       No image	specific file options

       Image specific creation options (usable on the 'create' command):
		+-----------------+----------------+--------------+
		| Option	  | Allowed values | Description  |
		+-----------------+----------------+--------------+
		| --heads	  | 1-2		   | Heads	  |
		+-----------------+----------------+--------------+
		| --tracks	  | 80		   | Tracks	  |
		+-----------------+----------------+--------------+
		| --sectorlength  | 512		   | Sector Bytes |
		+-----------------+----------------+--------------+
		| --firstsectorid | 0		   | First Sector |
		+-----------------+----------------+--------------+

   Apple raw 3.5" disk image (ProDOS format) - (apple35_raw_prodos_35)
       Driver specific options for module 'apple35_raw_prodos_35':

       No image	specific file options

       Image specific creation options (usable on the 'create' command):
		+-----------------+----------------+--------------+
		| Option	  | Allowed values | Description  |
		+-----------------+----------------+--------------+
		| --heads	  | 1-2		   | Heads	  |
		+-----------------+----------------+--------------+
		| --tracks	  | 80		   | Tracks	  |
		+-----------------+----------------+--------------+
		| --sectorlength  | 512		   | Sector Bytes |
		+-----------------+----------------+--------------+
		| --firstsectorid | 0		   | First Sector |
		+-----------------+----------------+--------------+

   CoCo	DMK disk image (OS-9 format) - (coco_dmk_os9)
       Driver specific options for module 'coco_dmk_os9':

       No image	specific file options

       Image specific creation options (usable on the 'create' command):
	+-----------------+---------------------------------+--------------+
	| Option	  | Allowed values		    | Description  |
	+-----------------+---------------------------------+--------------+
	| --heads	  | 1-2				    | Heads	   |
	+-----------------+---------------------------------+--------------+
	| --tracks	  | 35-255			    | Tracks	   |
	+-----------------+---------------------------------+--------------+
	| --sectors	  | 1-18			    | Sectors	   |
	+-----------------+---------------------------------+--------------+
	| --sectorlength  | 128/256/512/1024/2048/4096/8192 | Sector Bytes |
	+-----------------+---------------------------------+--------------+
	| --interleave	  | 0-17			    | Interleave   |
	+-----------------+---------------------------------+--------------+
	| --firstsectorid | 0-1				    | First Sector |
	+-----------------+---------------------------------+--------------+

   CoCo	DMK disk image (RS-DOS format) - (coco_dmk_rsdos)
       Driver specific options for module 'coco_dmk_rsdos':

       Image specific file options (usable on the 'put'	command):
		     +---------+----------------+-------------+
		     | Option  | Allowed values	| Description |
		     +---------+----------------+-------------+
		     | --ftype | basic/data/bi-	| File type   |
		     |	       | nary/assembler	|	      |
		     +---------+----------------+-------------+
		     | --ascii | ascii/binary	| ASCII	flag  |
		     +---------+----------------+-------------+

       Image specific creation options (usable on the 'create' command):
	+-----------------+---------------------------------+--------------+
	| Option	  | Allowed values		    | Description  |
	+-----------------+---------------------------------+--------------+
	| --heads	  | 1-2				    | Heads	   |
	+-----------------+---------------------------------+--------------+
	| --tracks	  | 35-255			    | Tracks	   |
	+-----------------+---------------------------------+--------------+
	| --sectors	  | 1-18			    | Sectors	   |
	+-----------------+---------------------------------+--------------+
	| --sectorlength  | 128/256/512/1024/2048/4096/8192 | Sector Bytes |
	+-----------------+---------------------------------+--------------+
	| --interleave	  | 0-17			    | Interleave   |
	+-----------------+---------------------------------+--------------+
	| --firstsectorid | 0-1				    | First Sector |
	+-----------------+---------------------------------+--------------+

   CoCo	JVC disk image (OS-9 format) - (coco_jvc_os9)
       Driver specific options for module 'coco_jvc_os9':

       No image	specific file options

       Image specific creation options (usable on the 'create' command):
	       +-----------------+------------------+--------------+
	       | Option		 | Allowed values   | Description  |
	       +-----------------+------------------+--------------+
	       | --heads	 | 1-2		    | Heads	   |
	       +-----------------+------------------+--------------+
	       | --tracks	 | 35-255	    | Tracks	   |
	       +-----------------+------------------+--------------+
	       | --sectors	 | 1-255	    | Sectors	   |
	       +-----------------+------------------+--------------+
	       | --sectorlength	 | 128/256/512/1024 | Sector Bytes |
	       +-----------------+------------------+--------------+
	       | --firstsectorid | 0-1		    | First Sector |
	       +-----------------+------------------+--------------+

   CoCo	JVC disk image (RS-DOS format) - (coco_jvc_rsdos)
       Driver specific options for module 'coco_jvc_rsdos':

       Image specific file options (usable on the 'put'	command):
		     +---------+----------------+-------------+
		     | Option  | Allowed values	| Description |
		     +---------+----------------+-------------+
		     | --ftype | basic/data/bi-	| File type   |
		     |	       | nary/assembler	|	      |
		     +---------+----------------+-------------+
		     | --ascii | ascii/binary	| ASCII	flag  |
		     +---------+----------------+-------------+

       Image specific creation options (usable on the 'create' command):
	       +-----------------+------------------+--------------+
	       | Option		 | Allowed values   | Description  |
	       +-----------------+------------------+--------------+
	       | --heads	 | 1-2		    | Heads	   |
	       +-----------------+------------------+--------------+
	       | --tracks	 | 35-255	    | Tracks	   |
	       +-----------------+------------------+--------------+
	       | --sectors	 | 1-255	    | Sectors	   |
	       +-----------------+------------------+--------------+
	       | --sectorlength	 | 128/256/512/1024 | Sector Bytes |
	       +-----------------+------------------+--------------+
	       | --firstsectorid | 0-1		    | First Sector |
	       +-----------------+------------------+--------------+

   CoCo	OS-9 disk image	(OS-9 format) -	(coco_os9_os9)
       Driver specific options for module 'coco_os9_os9':

       No image	specific file options

       Image specific creation options (usable on the 'create' command):
	       +-----------------+------------------+--------------+
	       | Option		 | Allowed values   | Description  |
	       +-----------------+------------------+--------------+
	       | --heads	 | 1-2		    | Heads	   |
	       +-----------------+------------------+--------------+
	       | --tracks	 | 35-255	    | Tracks	   |
	       +-----------------+------------------+--------------+
	       | --sectors	 | 1-255	    | Sectors	   |
	       +-----------------+------------------+--------------+
	       | --sectorlength	 | 128/256/512/1024 | Sector Bytes |
	       +-----------------+------------------+--------------+
	       | --firstsectorid | 1		    | First Sector |
	       +-----------------+------------------+--------------+

   CoCo	VDK disk image (OS-9 format) - (coco_vdk_os9)
       Driver specific options for module 'coco_vdk_os9':

       No image	specific file options

       Image specific creation options (usable on the 'create' command):
		+-----------------+----------------+--------------+
		| Option	  | Allowed values | Description  |
		+-----------------+----------------+--------------+
		| --heads	  | 1-2		   | Heads	  |
		+-----------------+----------------+--------------+
		| --tracks	  | 35-255	   | Tracks	  |
		+-----------------+----------------+--------------+
		| --sectors	  | 18		   | Sectors	  |
		+-----------------+----------------+--------------+
		| --sectorlength  | 256		   | Sector Bytes |
		+-----------------+----------------+--------------+
		| --firstsectorid | 1		   | First Sector |
		+-----------------+----------------+--------------+

   CoCo	VDK disk image (RS-DOS format) - (coco_vdk_rsdos)
       Driver specific options for module 'coco_vdk_rsdos':

       Image specific file options (usable on the 'put'	command):
		     +---------+----------------+-------------+
		     | Option  | Allowed values	| Description |
		     +---------+----------------+-------------+
		     | --ftype | basic/data/bi-	| File type   |
		     |	       | nary/assembler	|	      |
		     +---------+----------------+-------------+
		     | --ascii | ascii/binary	| ASCII	flag  |
		     +---------+----------------+-------------+

       Image specific creation options (usable on the 'create' command):
		+-----------------+----------------+--------------+
		| Option	  | Allowed values | Description  |
		+-----------------+----------------+--------------+
		| --heads	  | 1-2		   | Heads	  |
		+-----------------+----------------+--------------+
		| --tracks	  | 35-255	   | Tracks	  |
		+-----------------+----------------+--------------+
		| --sectors	  | 18		   | Sectors	  |
		+-----------------+----------------+--------------+
		| --sectorlength  | 256		   | Sector Bytes |
		+-----------------+----------------+--------------+
		| --firstsectorid | 1		   | First Sector |
		+-----------------+----------------+--------------+

   Concept floppy disk image - (concept)
       Driver specific options for module 'concept':

       No image	specific file options

       No image	specific creation options

   CopyQM floppy disk image (Basic Master Level	3 format) - (cqm_bml3)
       Driver specific options for module 'cqm_bml3':

       Image specific file options (usable on the 'put'	command):
		     +---------+----------------+-------------+
		     | Option  | Allowed values	| Description |
		     +---------+----------------+-------------+
		     | --ftype | basic/data/bi-	| File type   |
		     |	       | nary/assembler	|	      |
		     +---------+----------------+-------------+
		     | --ascii | ascii/binary	| ASCII	flag  |
		     +---------+----------------+-------------+

       No image	specific creation options

   CopyQM floppy disk image (FAT format) - (cqm_fat)
       Driver specific options for module 'cqm_fat':

       No image	specific file options

       No image	specific creation options

   CopyQM floppy disk image (Mac HFS Floppy) - (cqm_mac_hfs)
       Driver specific options for module 'cqm_mac_hfs':

       No image	specific file options

       No image	specific creation options

   CopyQM floppy disk image (Mac MFS Floppy) - (cqm_mac_mfs)
       Driver specific options for module 'cqm_mac_mfs':

       No image	specific file options

       No image	specific creation options

   CopyQM floppy disk image (OS-9 format) - (cqm_os9)
       Driver specific options for module 'cqm_os9':

       No image	specific file options

       No image	specific creation options

   CopyQM floppy disk image (ProDOS format) - (cqm_prodos_35)
       Driver specific options for module 'cqm_prodos_35':

       No image	specific file options

       No image	specific creation options

   CopyQM floppy disk image (ProDOS format) - (cqm_prodos_525)
       Driver specific options for module 'cqm_prodos_525':

       No image	specific file options

       No image	specific creation options

   CopyQM floppy disk image (RS-DOS format) - (cqm_rsdos)
       Driver specific options for module 'cqm_rsdos':

       Image specific file options (usable on the 'put'	command):
		     +---------+----------------+-------------+
		     | Option  | Allowed values	| Description |
		     +---------+----------------+-------------+
		     | --ftype | basic/data/bi-	| File type   |
		     |	       | nary/assembler	|	      |
		     +---------+----------------+-------------+
		     | --ascii | ascii/binary	| ASCII	flag  |
		     +---------+----------------+-------------+

       No image	specific creation options

   CopyQM floppy disk image (VZ-DOS format) - (cqm_vzdos)
       Driver specific options for module 'cqm_vzdos':

       Image specific file options (usable on the 'put'	command):
		   +---------+-------------------+-------------+
		   | Option  | Allowed values	 | Description |
		   +---------+-------------------+-------------+
		   | --ftype | basic/binary/data | File	type   |
		   +---------+-------------------+-------------+
		   | --fname | intern/extern	 | Filename    |
		   +---------+-------------------+-------------+

       No image	specific creation options

   Cybiko Classic File System -	(cybiko)
       Driver specific options for module 'cybiko':

       No image	specific file options

       Image specific creation options (usable on the 'create' command):
	     +---------+-------------------------------+-------------+
	     | Option  | Allowed values		       | Description |
	     +---------+-------------------------------+-------------+
	     | --flash | AT45DB041/AT45DB081/AT45DB161 | Flash Type  |
	     +---------+-------------------------------+-------------+

   Cybiko Xtreme File System - (cybikoxt)
       Driver specific options for module 'cybikoxt':

       No image	specific file options

       No image	specific creation options

   D88 Floppy Disk image (Basic	Master Level 3 format) - (d88_bml3)
       Driver specific options for module 'd88_bml3':

       Image specific file options (usable on the 'put'	command):
		     +---------+----------------+-------------+
		     | Option  | Allowed values	| Description |
		     +---------+----------------+-------------+
		     | --ftype | basic/data/bi-	| File type   |
		     |	       | nary/assembler	|	      |
		     +---------+----------------+-------------+
		     | --ascii | ascii/binary	| ASCII	flag  |
		     +---------+----------------+-------------+

       No image	specific creation options

   D88 Floppy Disk image (FAT format) -	(d88_fat)
       Driver specific options for module 'd88_fat':

       No image	specific file options

       No image	specific creation options

   D88 Floppy Disk image (Mac HFS Floppy) - (d88_mac_hfs)
       Driver specific options for module 'd88_mac_hfs':

       No image	specific file options

       No image	specific creation options

   D88 Floppy Disk image (Mac MFS Floppy) - (d88_mac_mfs)
       Driver specific options for module 'd88_mac_mfs':

       No image	specific file options

       No image	specific creation options

   D88 Floppy Disk image (OS-9 format) - (d88_os9)
       Driver specific options for module 'd88_os9':

       No image	specific file options

       No image	specific creation options

   D88 Floppy Disk image (OS-9 format) - (d88_os9)
       Driver specific options for module 'd88_prodos_35':

       No image	specific file options

       No image	specific creation options

   D88 Floppy Disk image (ProDOS format) - (d88_prodos_525)
       Driver specific options for module 'd88_prodos_525':

       No image	specific file options

       No image	specific creation options

   D88 Floppy Disk image (RS-DOS format) - (d88_rsdos)
       Driver specific options for module 'd88_rsdos':

       Image specific file options (usable on the 'put'	command):
		     +---------+----------------+-------------+
		     | Option  | Allowed values	| Description |
		     +---------+----------------+-------------+
		     | --ftype | basic/data/bi-	| File type   |
		     |	       | nary/assembler	|	      |
		     +---------+----------------+-------------+
		     | --ascii | ascii/binary	| ASCII	flag  |
		     +---------+----------------+-------------+

       No image	specific creation options

   D88 Floppy Disk image (VZ-DOS format) - (d88_vzdos)
       Driver specific options for module 'd88_vzdos':

       Image specific file options (usable on the 'put'	command):
		   +---------+-------------------+-------------+
		   | Option  | Allowed values	 | Description |
		   +---------+-------------------+-------------+
		   | --ftype | basic/binary/data | File	type   |
		   +---------+-------------------+-------------+
		   | --fname | intern/extern	 | Filename    |
		   +---------+-------------------+-------------+

       No image	specific creation options

   DSK floppy disk image (Basic	Master Level 3 format) - (dsk_bml3)
       Driver specific options for module 'dsk_bml3':

       Image specific file options (usable on the 'put'	command):
		     +---------+----------------+-------------+
		     | Option  | Allowed values	| Description |
		     +---------+----------------+-------------+
		     | --ftype | basic/data/bi-	| File type   |
		     |	       | nary/assembler	|	      |
		     +---------+----------------+-------------+
		     | --ascii | ascii/binary	| ASCII	flag  |
		     +---------+----------------+-------------+

       No image	specific creation options

   DSK floppy disk image (FAT format) -	(dsk_fat)
       Driver specific options for module 'dsk_fat':

       No image	specific file options

       No image	specific creation options

   DSK floppy disk image (Mac HFS Floppy) - (dsk_mac_hfs)
       Driver specific options for module 'dsk_mac_hfs':

       No image	specific file options

       No image	specific creation options

   DSK floppy disk image (Mac MFS Floppy) - (dsk_mac_mfs)
       Driver specific options for module 'dsk_mac_mfs':

       No image	specific file options

       No image	specific creation options

   DSK floppy disk image (OS-9 format) - (dsk_os9)
       Driver specific options for module 'dsk_os9':

       No image	specific file options

       No image	specific creation options

   DSK floppy disk image (ProDOS format) - (dsk_prodos_35)
       Driver specific options for module 'dsk_prodos_35':

       No image	specific file options

       No image	specific creation options

   DSK floppy disk image (ProDOS format) - (dsk_prodos_525)
       Driver specific options for module 'dsk_prodos_525':

       No image	specific file options

       No image	specific creation options

   DSK floppy disk image (RS-DOS format) - (dsk_rsdos)
       Driver specific options for module 'dsk_rsdos':

       Image specific file options (usable on the 'put'	command):
		     +---------+----------------+-------------+
		     | Option  | Allowed values	| Description |
		     +---------+----------------+-------------+
		     | --ftype | basic/data/bi-	| File type   |
		     |	       | nary/assembler	|	      |
		     +---------+----------------+-------------+
		     | --ascii | ascii/binary	| ASCII	flag  |
		     +---------+----------------+-------------+

       No image	specific creation options

   DSK floppy disk image (VZ-DOS format) - (dsk_vzdos)
       Driver specific options for module 'dsk_vzdos':

       Image specific file options (usable on the 'put'	command):
		   +---------+-------------------+-------------+
		   | Option  | Allowed values	 | Description |
		   +---------+-------------------+-------------+
		   | --ftype | basic/binary/data | File	type   |
		   +---------+-------------------+-------------+
		   | --fname | intern/extern	 | Filename    |
		   +---------+-------------------+-------------+

       No image	specific creation options

   Formatted Disk Image	(Basic Master Level 3 format) -	(fdi_bml3)
       Driver specific options for module 'fdi_bml3':

       Image specific file options (usable on the 'put'	command):
		     +---------+----------------+-------------+
		     | Option  | Allowed values	| Description |
		     +---------+----------------+-------------+
		     | --ftype | basic/data/bi-	| File type   |
		     |	       | nary/assembler	|	      |
		     +---------+----------------+-------------+
		     | --ascii | ascii/binary	| ASCII	flag  |
		     +---------+----------------+-------------+

       No image	specific creation options

   Formatted Disk Image	(FAT format) - (fdi_fat)
       Driver specific options for module 'fdi_fat':

       No image	specific file options

       No image	specific creation options

   Formatted Disk Image	(Mac HFS Floppy) - (fdi_mac_hfs)
       Driver specific options for module 'fdi_mac_hfs':

       No image	specific file options

       No image	specific creation options

   Formatted Disk Image	(Mac MFS Floppy) - (fdi_mac_mfs)
       Driver specific options for module 'fdi_mac_mfs':

       No image	specific file options

       No image	specific creation options

   Formatted Disk Image	(OS-9 format) -	(fdi_os9)
       Driver specific options for module 'fdi_os9':

       No image	specific file options

       No image	specific creation options

   Formatted Disk Image	(ProDOS	format)	- (fdi_prodos_35)
       Driver specific options for module 'fdi_prodos_35':

       No image	specific file options

       No image	specific creation options

   Formatted Disk Image	(ProDOS	format)	- (fdi_prodos_525)
       Driver specific options for module 'fdi_prodos_525':

       No image	specific file options

       No image	specific creation options

   Formatted Disk Image	(RS-DOS	format)	- (fdi_rsdos)
       Driver specific options for module 'fdi_rsdos':

       Image specific file options (usable on the 'put'	command):
		     +---------+----------------+-------------+
		     | Option  | Allowed values	| Description |
		     +---------+----------------+-------------+
		     | --ftype | basic/data/bi-	| File type   |
		     |	       | nary/assembler	|	      |
		     +---------+----------------+-------------+
		     | --ascii | ascii/binary	| ASCII	flag  |
		     +---------+----------------+-------------+

       No image	specific creation options

   Formatted Disk Image	(VZ-DOS	format)	- (fdi_vzdos)
       Driver specific options for module 'fdi_vzdos':

       Image specific file options (usable on the 'put'	command):
		   +---------+-------------------+-------------+
		   | Option  | Allowed values	 | Description |
		   +---------+-------------------+-------------+
		   | --ftype | basic/binary/data | File	type   |
		   +---------+-------------------+-------------+
		   | --fname | intern/extern	 | Filename    |
		   +---------+-------------------+-------------+

       No image	specific creation options

   HP48	SX/GX memory card - (hp48)
       Driver specific options for module 'hp48':

       No image	specific file options

       Image specific creation options (usable on the 'create' command):
	    +--------+----------------------------------+-------------+
	    | Option | Allowed values			| Description |
	    +--------+----------------------------------+-------------+
	    | --size | 32/64/128/256/512/1024/2048/4096	| Size in KB  |
	    +--------+----------------------------------+-------------+

   IMD floppy disk image (Basic	Master Level 3 format) - (imd_bml3)
       Driver specific options for module 'imd_bml3':

       Image specific file options (usable on the 'put'	command):
		     +---------+----------------+-------------+
		     | Option  | Allowed values	| Description |
		     +---------+----------------+-------------+
		     | --ftype | basic/data/bi-	| File type   |
		     |	       | nary/assembler	|	      |
		     +---------+----------------+-------------+
		     | --ascii | ascii/binary	| ASCII	flag  |
		     +---------+----------------+-------------+

       No image	specific creation options

   IMD floppy disk image (FAT format) -	(imd_fat)
       Driver specific options for module 'imd_fat':

       No image	specific file options

       No image	specific creation options

   IMD floppy disk image (Mac HFS Floppy) - (imd_mac_hfs)
       Driver specific options for module 'imd_mac_hfs':

       No image	specific file options

       No image	specific creation options

   IMD floppy disk image (Mac MFS Floppy) - (imd_mac_mfs)
       Driver specific options for module 'imd_mac_mfs':

       No image	specific file options

       No image	specific creation options

   IMD floppy disk image (OS-9 format) - (imd_os9)
       Driver specific options for module 'imd_os9':

       No image	specific file options

       No image	specific creation options

   IMD floppy disk image (ProDOS format) - (imd_prodos_35)
       Driver specific options for module 'imd_prodos_35':

       No image	specific file options

       No image	specific creation options

   IMD floppy disk image (ProDOS format) - (imd_prodos_525)
       Driver specific options for module 'imd_prodos_525':

       No image	specific file options

       No image	specific creation options

   IMD floppy disk image (RS-DOS format) - (imd_rsdos)
       Driver specific options for module 'imd_rsdos':

       Image specific file options (usable on the 'put'	command):
		     +---------+----------------+-------------+
		     | Option  | Allowed values	| Description |
		     +---------+----------------+-------------+
		     | --ftype | basic/data/bi-	| File type   |
		     |	       | nary/assembler	|	      |
		     +---------+----------------+-------------+
		     | --ascii | ascii/binary	| ASCII	flag  |
		     +---------+----------------+-------------+

       No image	specific creation options

   IMD floppy disk image (VZ-DOS format) - (imd_vzdos)
       Driver specific options for module 'imd_vzdos':

       Image specific file options (usable on the 'put'	command):
		   +---------+-------------------+-------------+
		   | Option  | Allowed values	 | Description |
		   +---------+-------------------+-------------+
		   | --ftype | basic/binary/data | File	type   |
		   +---------+-------------------+-------------+
		   | --fname | intern/extern	 | Filename    |
		   +---------+-------------------+-------------+

       No image	specific creation options

   MESS	hard disk image	- (mess_hd)
       Driver specific options for module 'mess_hd':

       No image	specific file options

       Image specific creation options (usable on the 'create' command):
+-------------+---------------------------------------------------+-------------------+
| Option      |	Allowed	values					  | Description	      |
+-------------+---------------------------------------------------+-------------------+
| --blocksize |	1-2048						  | Sectors Per	Block |
+-------------+---------------------------------------------------+-------------------+
| --cylinders |	1-65536						  | Cylinders	      |
+-------------+---------------------------------------------------+-------------------+
| --heads     |	1-64						  | Heads	      |
+-------------+---------------------------------------------------+-------------------+
| --sectors   |	1-4096						  | Total Sectors     |
+-------------+---------------------------------------------------+-------------------+
| --seclen    |	128/256/512/1024/2048/4096/8192/16384/32768/65536 | Sector Bytes      |
+-------------+---------------------------------------------------+-------------------+

   TI99	Diskette (PC99 FM format) - (pc99fm)
       Driver specific options for module 'pc99fm':

       No image	specific file options

       No image	specific creation options

   TI99	Diskette (PC99 MFM format) - (pc99mfm)
       Driver specific options for module 'pc99mfm':

       No image	specific file options

       No image	specific creation options

   PC CHD disk image - (pc_chd)
       Driver specific options for module 'pc_chd':

       No image	specific file options

       Image specific creation options (usable on the 'create' command):
+-------------+------------------------------------------------------------------------+-------------+
| Option      |	Allowed	values							       | Description |
+-------------+------------------------------------------------------------------------+-------------+
| --cylinders |	10/20/30/40/50/60/70/80/90/100/110/120/130/140/150/160/170/180/190/200 | Cylinders   |
+-------------+------------------------------------------------------------------------+-------------+
| --heads     |	1-16								       | Heads	     |
+-------------+------------------------------------------------------------------------+-------------+
| --sectors   |	1-63								       | Sectors     |
+-------------+------------------------------------------------------------------------+-------------+

   PC floppy disk image	(FAT format) - (pc_dsk_fat)
       Driver specific options for module 'pc_dsk_fat':

       No image	specific file options

       Image specific creation options (usable on the 'create' command):
		   +-----------+-----------------+-------------+
		   | Option    | Allowed values	 | Description |
		   +-----------+-----------------+-------------+
		   | --heads   | 1-2		 | Heads       |
		   +-----------+-----------------+-------------+
		   | --tracks  | 40/80		 | Tracks      |
		   +-----------+-----------------+-------------+
		   | --sectors | 8/9/10/15/18/36 | Sectors     |
		   +-----------+-----------------+-------------+

   Psion Organiser II Datapack - (psionpack)
       Driver specific options for module 'psionpack':

       Image specific file options (usable on the 'put'	command):
		     +--------+----------------+-------------+
		     | Option |	Allowed	values | Description |
		     +--------+----------------+-------------+
		     | --type |	OB3/OPL/ODB    | file type   |
		     +--------+----------------+-------------+
		     | --id   |	0/145-255      | File ID     |
		     +--------+----------------+-------------+

       Image specific creation options (usable on the 'create' command):
	     +-----------+---------------------+---------------------+
	     | Option	 | Allowed values      | Description	     |
	     +-----------+---------------------+---------------------+
	     | --size	 | 8k/16k/32k/64k/128k | datapack size	     |
	     +-----------+---------------------+---------------------+
	     | --ram	 | 0/1		       | EPROM/RAM datapack  |
	     +-----------+---------------------+---------------------+
	     | --paged	 | 0/1		       | linear/paged  data- |
	     |		 |		       | pack		     |
	     +-----------+---------------------+---------------------+
	     | --protect | 0/1		       | write-protected     |
	     |		 |		       | datapack	     |
	     +-----------+---------------------+---------------------+
	     | --boot	 | 0/1		       | bootable datapack   |
	     +-----------+---------------------+---------------------+
	     | --copy	 | 0/1		       | copyable datapack   |
	     +-----------+---------------------+---------------------+

   Teledisk floppy disk	image (Basic Master Level 3 format) - (td0_bml3)
       Driver specific options for module 'td0_bml3':

       Image specific file options (usable on the 'put'	command):
		     +---------+----------------+-------------+
		     | Option  | Allowed values	| Description |
		     +---------+----------------+-------------+
		     | --ftype | basic/data/bi-	| File type   |
		     |	       | nary/assembler	|	      |
		     +---------+----------------+-------------+
		     | --ascii | ascii/binary	| ASCII	flag  |
		     +---------+----------------+-------------+

       No image	specific creation options

   Teledisk floppy disk	image (FAT format) - (td0_fat)
       Driver specific options for module 'td0_fat':

       No image	specific file options

       No image	specific creation options

   Teledisk floppy disk	image (Mac HFS Floppy) - (td0_mac_hfs)
       Driver specific options for module 'td0_mac_hfs':

       No image	specific file options

       No image	specific creation options

   Teledisk floppy disk	image (Mac MFS Floppy) - (td0_mac_mfs)
       Driver specific options for module 'td0_mac_mfs':

       No image	specific file options

       No image	specific creation options

   Teledisk floppy disk	image (OS-9 format) - (td0_os9)
       Driver specific options for module 'td0_os9':

       No image	specific file options

       No image	specific creation options

   Teledisk floppy disk	image (ProDOS format) -	(td0_prodos_35)
       Driver specific options for module 'td0_prodos_35':

       No image	specific file options

       No image	specific creation options

   Teledisk floppy disk	image (ProDOS format) -	(td0_prodos_525)
       Driver specific options for module 'td0_prodos_525':

       No image	specific file options

       No image	specific creation options

   Teledisk floppy disk	image (RS-DOS format) -	(td0_rsdos)
       Driver specific options for module 'td0_rsdos':

       Image specific file options (usable on the 'put'	command):
		     +---------+----------------+-------------+
		     | Option  | Allowed values	| Description |
		     +---------+----------------+-------------+
		     | --ftype | basic/data/bi-	| File type   |
		     |	       | nary/assembler	|	      |
		     +---------+----------------+-------------+
		     | --ascii | ascii/binary	| ASCII	flag  |
		     +---------+----------------+-------------+

       No image	specific creation options

   Teledisk floppy disk	image (VZ-DOS format) -	(td0_vzdos)
       Driver specific options for module 'td0_vzdos':

       Image specific file options (usable on the 'put'	command):
		   +---------+-------------------+-------------+
		   | Option  | Allowed values	 | Description |
		   +---------+-------------------+-------------+
		   | --ftype | basic/binary/data | File	type   |
		   +---------+-------------------+-------------+
		   | --fname | intern/extern	 | Filename    |
		   +---------+-------------------+-------------+

       No image	specific creation options

   Thomson .fd disk image, BASIC format	- (thom_fd)
       Driver specific options for module 'thom_fd':

       Image specific file options (usable on the 'put'	command):
		    +-----------+----------------+-------------+
		    | Option	| Allowed values | Description |
		    +-----------+----------------+-------------+
		    | --ftype	| auto/B/D/M/A	 | File	type   |
		    +-----------+----------------+-------------+
		    | --format	| auto/B/A	 | Format flag |
		    +-----------+----------------+-------------+
		    | --comment	| (string)	 | Comment     |
		    +-----------+----------------+-------------+

       Image specific creation options (usable on the 'create' command):
		    +-----------+----------------+-------------+
		    | Option	| Allowed values | Description |
		    +-----------+----------------+-------------+
		    | --heads	| 1-2		 | Heads       |
		    +-----------+----------------+-------------+
		    | --tracks	| 40/80		 | Tracks      |
		    +-----------+----------------+-------------+
		    | --density	| SD/DD		 | Density     |
		    +-----------+----------------+-------------+
		    | --name	| (string)	 | Floppy name |
		    +-----------+----------------+-------------+

   Thomson .qd disk image, BASIC format	- (thom_qd)
       Driver specific options for module 'thom_qd':

       Image specific file options (usable on the 'put'	command):
		    +-----------+----------------+-------------+
		    | Option	| Allowed values | Description |
		    +-----------+----------------+-------------+
		    | --ftype	| auto/B/D/M/A	 | File	type   |
		    +-----------+----------------+-------------+
		    | --format	| auto/B/A	 | Format flag |
		    +-----------+----------------+-------------+
		    | --comment	| (string)	 | Comment     |
		    +-----------+----------------+-------------+

       Image specific creation options (usable on the 'create' command):
		    +-----------+----------------+-------------+
		    | Option	| Allowed values | Description |
		    +-----------+----------------+-------------+
		    | --heads	| 1-2		 | Heads       |
		    +-----------+----------------+-------------+
		    | --tracks	| 25		 | Tracks      |
		    +-----------+----------------+-------------+
		    | --density	| SD/DD		 | Density     |
		    +-----------+----------------+-------------+
		    | --name	| (string)	 | Floppy name |
		    +-----------+----------------+-------------+

   Thomson .sap	disk image, BASIC format - (thom_sap)
       Driver specific options for module 'thom_sap':

       Image specific file options (usable on the 'put'	command):
		    +-----------+----------------+-------------+
		    | Option	| Allowed values | Description |
		    +-----------+----------------+-------------+
		    | --ftype	| auto/B/D/M/A	 | File	type   |
		    +-----------+----------------+-------------+
		    | --format	| auto/B/A	 | Format flag |
		    +-----------+----------------+-------------+
		    | --comment	| (string)	 | Comment     |
		    +-----------+----------------+-------------+

       Image specific creation options (usable on the 'create' command):
		    +-----------+----------------+-------------+
		    | Option	| Allowed values | Description |
		    +-----------+----------------+-------------+
		    | --heads	| 1		 | Heads       |
		    +-----------+----------------+-------------+
		    | --tracks	| 40/80		 | Tracks      |
		    +-----------+----------------+-------------+
		    | --density	| SD/DD		 | Density     |
		    +-----------+----------------+-------------+
		    | --name	| (string)	 | Floppy name |
		    +-----------+----------------+-------------+

   TI990 Hard Disk - (ti990hd)
       Driver specific options for module 'ti990hd':

       No image	specific file options

       Image specific creation options (usable on the 'create' command):
	  +--------------------+-------------------+---------------------+
	  | Option	       | Allowed values	   | Description	 |
	  +--------------------+-------------------+---------------------+
	  | --cylinders	       | 1-2047		   | Cylinders		 |
	  +--------------------+-------------------+---------------------+
	  | --heads	       | 1-31		   | Heads		 |
	  +--------------------+-------------------+---------------------+
	  | --sectors	       | 1-256		   | Sectors		 |
	  +--------------------+-------------------+---------------------+
	  | --bytes per	sector | (typically	   | Bytes   Per  Sector |
	  |		       | 25256-512 256-512 | [Todo: This section |
	  |		       |		   | is	glitched in img- |
	  |		       |		   | tool]		 |
	  +--------------------+-------------------+---------------------+

   TI99	Diskette (old MESS format) - (ti99_old)
       Driver specific options for module 'ti99_old':

       No image	specific file options

       Image specific creation options (usable on the 'create' command):
	      +--------------+----------------+---------------------+
	      |	Option	     | Allowed values |	Description	    |
	      +--------------+----------------+---------------------+
	      |	--sides	     | 1-2	      |	Sides		    |
	      +--------------+----------------+---------------------+
	      |	--tracks     | 1-80	      |	Tracks		    |
	      +--------------+----------------+---------------------+
	      |	--sectors    | 1-36	      |	Sectors	 (1->9	for |
	      |		     |		      |	SD,  1->18  for	DD, |
	      |		     |		      |	1->36 for HD)	    |
	      +--------------+----------------+---------------------+
	      |	--protection | 0-1	      |	Protection  (0	for |
	      |		     |		      |	normal,	 1 for pro- |
	      |		     |		      |	tected)		    |
	      +--------------+----------------+---------------------+
	      |	--density    | Auto/SD/DD/HD  |	Density		    |
	      +--------------+----------------+---------------------+

   TI99	Harddisk - (ti99hd)
       Driver specific options for module 'ti99hd':

       No image	specific file options

       No image	specific creation options

   TI99	Diskette (V9T9 format) - (v9t9)
       Driver specific options for module 'v9t9':

       No image	specific file options

       Image specific creation options (usable on the 'create' command):
	      +--------------+----------------+---------------------+
	      |	Option	     | Allowed values |	Description	    |
	      +--------------+----------------+---------------------+
	      |	--sides	     | 1-2	      |	Sides		    |
	      +--------------+----------------+---------------------+
	      |	--tracks     | 1-80	      |	Tracks		    |
	      +--------------+----------------+---------------------+
	      |	--sectors    | 1-36	      |	Sectors	 (1->9	for |
	      |		     |		      |	SD,  1->18  for	DD, |
	      |		     |		      |	1->36 for HD)	    |
	      +--------------+----------------+---------------------+
	      |	--protection | 0-1	      |	Protection  (0	for |
	      |		     |		      |	normal,	 1 for pro- |
	      |		     |		      |	tected)		    |
	      +--------------+----------------+---------------------+
	      |	--density    | Auto/SD/DD/HD  |	Density		    |
	      +--------------+----------------+---------------------+

   Laser/VZ disk image (VZ-DOS format) - (vtech1_vzdos)
       Driver specific options for module 'vtech1_vzdos':

       Image specific file options (usable on the 'put'	command):
		   +---------+-------------------+-------------+
		   | Option  | Allowed values	 | Description |
		   +---------+-------------------+-------------+
		   | --ftype | basic/binary/data | File	type   |
		   +---------+-------------------+-------------+
		   | --fname | intern/extern	 | Filename    |
		   +---------+-------------------+-------------+

       Image specific creation options (usable on the 'create' command):
		+-----------------+----------------+--------------+
		| Option	  | Allowed values | Description  |
		+-----------------+----------------+--------------+
		| --heads	  | 1		   | Heads	  |
		+-----------------+----------------+--------------+
		| --tracks	  | 40		   | Tracks	  |
		+-----------------+----------------+--------------+
		| --sectors	  | 16		   | Sectors	  |
		+-----------------+----------------+--------------+
		| --sectorlength  | 154		   | Sector Bytes |
		+-----------------+----------------+--------------+
		| --firstsectorid | 0		   | First Sector |
		+-----------------+----------------+--------------+

       [todo: fill out the command structures, describe	commands better. These
       descriptions came from the imgtool.txt file and are barebones]

   Castool - A generic cassette	image manipulation tool	for MAME
       Castool is a tool for the maintenance and manipulation of cassette  im-
       ages that MAME users need to deal with. MAME directly supports .WAV au-
       dio  formatted  images,	but  many of the existing images out there may
       come in forms such as .TAP for Commodore	64 tapes, .CAS for Tandy Color
       Computer	tapes, and so forth. Castool will convert these	other  formats
       to .WAV for use in MAME.

       Castool	is  part of the	MAME project. It shares	large portions of code
       with MAME, and its existence would not be if it were not	for MAME.   As
       such,  the  distribution	 terms	are the	same as	MAME.  Please read the
       MAME license thoroughly.

   Using Castool
       Castool is a command line program that contains a  simple  set  of  in-
       structions. Commands are	invoked	in a manner along the lines of this:
	  castool convert <format> <inputfile> <outputfile>

        <format> is the format	of the image

        <inputfile> is	the filename of	the image you're converting from

        <outputfile> is the filename of the output WAV	file

       Example usage:
	      castool convert coco zaxxon.cas zaxxon.wav

	      castool convert cbm arkanoid.tap arkanoid.wav

	      castool convert ddp mybasicprogram.ddp mybasicprogram.wav

   Castool Formats
       These  are  the	formats	 supported  by	Castool	for conversion to .WAV
       files.

       A26
	  Atari	2600 SuperCharger image

	  File extension: a26

       APF
	  APF Imagination Machine

	  File extensions: cas,	cpf, apt

       ATOM
	  Acorn	Atom

	  File extensions: tap,	csw, uef

       BBC
	  Acorn	BBC & Electron

	  File extensions: csw,	uef

       CBM
	  Commodore 8-bit series

	  File extensions: tap

       CDT
	  Amstrad CPC

	  File extensions: cdt

       CGENIE
	  EACA Colour Genie

	  File extensions: cas

       COCO
	  Tandy	Radio Shack Color Computer

	  File extensions: cas

       CSW
	  Compressed Square Wave

	  File extensions: csw

       DDP
	  Coleco ADAM

	  File extensions: ddp

       FM7
	  Fujitsu FM-7

	  File extensions: t77

       FMSX
	  MSX

	  File extensions: tap,	cas

       GTP
	  Elektronika inzenjering Galaksija

	  File extensions: gtp

       HECTOR
	  Micronique Hector & Interact Family Computer

	  File extensions: k7, cin, for

       JUPITER
	  Jupiter Cantab Jupiter Ace

	  File extensions: tap

       KC85
	  VEB Mikroelektronik KC 85

	  File extensions: kcc,	kcb, tap, 853, 854, 855, tp2, kcm, sss

       KIM1
	  MOS KIM-1

	  File extensions: kim,	kim1

       LVIV
	  PK-01	Lviv

	  File extensions: lvt,	lvr, lv0, lv1, lv2, lv3

       MO5
	  Thomson MO-series

	  File extensions: k5, k7

       MZ
	  Sharp	MZ-700

	  File extensions: m12,	mzf, mzt

       ORAO
	  PEL Varazdin Orao

	  File extensions: tap

       ORIC
	  Tangerine Oric

	  File extensions: tap

       PC6001
	  NEC PC-6001

	  File extensions: cas

       PHC25
	  Sanyo	PHC-25

	  File extensions: phc

       PMD85
	  Tesla	PMD-85

	  File extensions: pmd,	tap, ptp

       PRIMO
	  Microkey Primo

	  File extensions: ptp

       RKU
	  UT-88

	  File extensions: rku

       RK8
	  Mikro-80

	  File extensions: rk8

       RKS
	  Specialist

	  File extensions: rks

       RKO
	  Orion

	  File extensions: rko

       RKR
	  Radio-86RK

	  File extensions: rk, rkr, gam, g16, pki

       RKA
	  Zavod	BRA Apogee BK-01

	  File extensions: rka

       RKM
	  Mikrosha

	  File extensions: rkm

       RKP
	  SAM SKB VM Partner-01.01

	  File extensions: rkp

       SC3000
	  Sega SC-3000

	  File extensions: bit

       SOL20
	  PTC SOL-20

	  File extensions: svt

       SORCERER
	  Exidy	Sorcerer

	  File extensions: tape

       SORDM5
	  Sord M5

	  File extensions: cas

       SPC1000
	  Samsung SPC-1000

	  File extensions: tap,	cas

       SVI
	  Spectravideo SVI-318 & SVI-328

	  File extensions: cas

       TO7
	  Thomson TO-series

	  File extensions: k7

       TRS8012
	  TRS-80 Level 2

	  File extensions: cas

       TVC64
	  Videoton TVC 64

	  File extensions: cas

       TZX
	  Sinclair ZX Spectrum

	  File extensions: tzx,	tap, blk

       VG5K
	  Philips VG 5000

	  File extensions: k7

       VTECH1
	  Video	Technology Laser 110-310

	  File extensions: cas

       VTECH2
	  Video	Technology Laser 350-700

	  File extensions: cas

       X07
	  Canon	X-07

	  File extensions: k7, lst, cas

       X1
	  Sharp	X1

	  File extensions: tap

       ZX80_O
	  Sinclair ZX80

	  File extensions: o, 80

       ZX81_P
	  Sinclair ZX81

	  File extensions: p, 81

   Floptool - A	generic	floppy image manipulation tool for MAME
       Floptool	is a tool for the maintenance and manipulation of  floppy  im-
       ages that MAME users need to deal with. MAME directly supports .WAV au-
       dio  formatted  images,	but  many of the existing images out there may
       come in forms such as .TAP for Commodore	64 tapes, .CAS for Tandy Color
       Computer	tapes, and so forth. Castool will convert these	other  formats
       to .WAV for use in MAME.

       Floptool	 is part of the	MAME project. It shares	large portions of code
       with MAME, and its existence would not be if it were not	for MAME.   As
       such,  the  distribution	 terms	are the	same as	MAME.  Please read the
       MAME license thoroughly.

   Using Floptool
       Floptool	is a command line program that contains	a simple  set  of  in-
       structions. Commands are	invoked	in a manner along the lines of this:
	  floptool  identify  <inputfile>  [<inputfile>	...]  floptool convert
	  [input_format|auto] output_format <inputfile>	<outputile>

        <format> is the format	of the image

        <input_format>	is the format of the inputfile,	use auto if not	known

        <output_format> is the	format of the converted	file

        <inputfile> is	the filename of	the image you're  identifying/convert-
	 ing from

        <outputfile> is the filename of the converted file

       Example usage:
	      floptool convert coco zaxxon.cas zaxxon.wav

	      floptool convert cbm arkanoid.tap	arkanoid.wav

	      floptool convert ddp mybasicprogram.ddp mybasicprogram.wav

   Floptool Formats
       These  are  the	formats	 supported by Floptool for conversion to other
       formats.

       MFI
	  MAME floppy image

	  File extension: mfi

       DFI
	  DiscFerret flux dump format

	  File extensions: dfi

       IPF
	  SPS floppy disk image

	  File extensions: ipf

       MFM
	  HxC Floppy Emulator floppy disk image

	  File extensions: mfm

       ADF
	  Amiga	ADF floppy disk	image

	  File extensions: adf

       ST
	  Atari	ST floppy disk image

	  File extensions: st

       MSA
	  Atari	MSA floppy disk	image

	  File extensions: msa

       PASTI
	  Atari	PASTI floppy disk image

	  File extensions: stx

       DSK
	  CPC DSK format

	  File extensions: dsk

       D88
	  D88 disk image

	  File extensions: d77,	d88, 1dd

       IMD
	  IMD disk image

	  File extensions: imd

       TD0
	  Teledisk disk	image

	  File extensions: td0

       CQM
	  CopyQM disk image

	  File extensions: cqm,	cqi, dsk

       PC
	  PC floppy disk image

	  File extensions: dsk,	ima, img, ufi, 360

       NASLITE
	  NASLite disk image

	  File extensions: img

       DC42
	  DiskCopy 4.2 image

	  File extensions: dc42

       A2_16SECT
	  Apple	II 16-sector disk image

	  File extensions: dsk,	do, po

       A2_RWTS18
	  Apple	II RWTS18-type image

	  File extensions: rti

       A2_EDD
	  Apple	II EDD image

	  File extensions: edd

       ATOM
	  Acorn	Atom disk image

	  File extensions: 40t,	dsk

       SSD
	  Acorn	SSD disk image

	  File extensions: ssd,	bbc, img

       DSD
	  Acorn	DSD disk image

	  File extensions: dsd

       DOS
	  Acorn	DOS disk image

	  File extensions: img

       ADFS_O
	  Acorn	ADFS (OldMap) disk image

	  File extensions: adf,	ads, adm, adl

       ADFS_N
	  Acorn	ADFS (NewMap) disk image

	  File extensions: adf

       ORIC_DSK
	  Oric disk image

	  File extensions: dsk

       APPLIX
	  Applix disk image

	  File extensions: raw

       HPI
	  HP9845A floppy disk image

	  File extensions: hpi

   Other tools included	with MAME
   ledutil.exe/ledutil.sh
       On Microsoft Windows, ledutil.exe can take  control  of	your  keyboard
       LEDs to mirror those that were present on some early arcade games (e.g.
       Asteroids)

       Start  ledutil.exe  from	 the  command line to enable LED handling. Run
       ledutil.exe -kill to stop the handler.

       On SDLMAME platforms such as Mac	OS X  and  Linux,  ledutil.sh  can  be
       used.  Use  ledutil.sh  -a to have it automatically close when you exit
       SDLMAME.

   Developer-focused tools included with MAME
   pngcmp
       This tool is used in regression testing to compare PNG  screenshot  re-
       sults  with  the	 runtest.cmd  script found in the source archive. This
       script works only on Microsoft Windows.

   nltool
       Discrete	component conversion tool.

   nlwav
       Discrete	component conversion and testing tool.

   jedutil
       PAL/PLA/PLD/GAL dump handling tool. It can convert between  the	indus-
       try-standard JED	format and MAME's proprietary packed binary format and
       it  can	show logic equations for the types of devices it knows the in-
       ternal logic of.

   ldresample
       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.

   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 cal-
       culate hash functions.

   unidasm
       Universal disassembler for many of the architectures supported in MAME.

CONTRIBUTING TO	MAME
       So you want to contribute to MAME but arent sure	where to start?	  Well
       the great news is that theres always plenty to do for people with a va-
       riety of	skill sets.

   Testing and reporting bugs
       One  thing MAME can always do with is more testing and bug reports.  If
       youre familiar with a system that MAME emulates	and  notice  something
       wrong,  or if you find a	bug in MAMEs user interface, you can head over
       to MAME Testers and, assuming it	isnt already reported, register	an ac-
       count and open an issue.	 Be sure to read the FAQ and  rules  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.  Theres  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, its only for reporting reproducible issues.  Dont	open issues to
       ask  questions  or request support.  Also, keep in mind that the	master
       branch is unstable.  If the current revision doesnt compile at  all  or
       is  completely  broken, were probably already aware of it and dont need
       issues opened for that.	Wait a while and see if	theres an update.  You
       might want to comment on	the commit in question with the	compiler error
       message,	particularly if	youre compiling	in an unorthodox but supported
       configuration.

       When opening an issue, remember to provide as much information as  pos-
       sible  to  help	others	understand, reproduce, and diagnose the	issue.
       Things that are helpful to include:

        The incorrect behaviour, and expected or correct behaviour.  Be  spe-
	 cific:	just saying it doesnt work usually isnt	enough detail.

        Environment  details,	including your operating system, CPU architec-
	 ture, system locale, and display language, if applicable.  For	 video
	 output	 bugs, note your video hardware	(GPU), driver version, and the
	 MAME video output module youre	using.	For input handling  bugs,  in-
	 clude the input peripherals and MAME input modules youre using.

        The  exact version of MAME youre using, including a git commit	digest
	 if it isnt a tagged release version, and any non-standard  build  op-
	 tions.

        The  exact  system and	software being emulated	(may not be applicable
	 for issues with parts of MAMEs	UI, like the system  selection	menu).
	 Include  things  like the selected BIOS version, and emulated periph-
	 eral (slot device) configuration.

        Steps to reproduce the	issue.	Assume the person reading is  familiar
	 with MAME itself, but not necessarily familiar	with the emulated sys-
	 tem 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	to MAMEs source	code
       MAME  itself  is	 written  in  C++,  but	that isnt 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	markup.

        The supplied plugins, written in Lua 5.3.

        Internal layouts for emulated machines	that need to display more than
	 a simple video	screen.	 These are an XML application described	here.

        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.

       Our  primary  source code repository is hosted on GitHub.  We prefer to
       receive source code contributions in the	form of	pull requests.	 Youll
       need  to	learn the basics of git	distributed version control and	famil-
       iarise 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	 rele-
       vant to all kinds of changes):

        Make  your  commit  messages  descriptive.   Please  include what the
	 change	affects, and what its supposed to achieve.  A  person  reading
	 the commit log	shouldnt 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 dont 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.  Its a good	idea to	build with DE-
	 BUG=1 to check	that assertions	compile	and dont 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 its supposed to do.  The description should contain more detail.
	 Dont 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 isnt
	 clear when youre close	to  the	 limits,  and  weve  had  contributors
	 banned	from GitHub Actions for	violating the limits.  Even if you ap-
	 peal  the  ban,  they still wont 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 dont	need them to be	 automatically
	 built,	or cancelling workflow runs when you dont need the results.

        If  your  submission  is a computer or	other device such as a synthe-
	 sizer or sampler which	requires a disk, tape, cartridge, or other me-
	 dia 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 page of the MAME	Wiki.	Anyone
	 can  edit  the	wiki after creating an account,	and sub-pages for your
	 system	which discuss technical	details	of the system  are  also  wel-
	 come.

       We have guidelines for specific parts of	the source:

   C++ Coding Guidelines
        Introduction

        Definitions

        Source	file format

        Naming	conventions

        Variables and literals

        Bracing and indentation

        Spacing

        Scoping

        Const Correctness

        Comments

        MAME-Specific Helpers

        Logging

        Structural organization

   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  conven-
       tions  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,	defer-
       ence  can  be  given  to	a contributors 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 for-
       ward.

   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

   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 re-
       lease.  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.

   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 con-
	      stant  globals, constant data members, enumerators or preproces-
	      sor constants.

       Functions
	      Free functions names should use snake  case.   (There  are  some
	      utility  function	that were previously implemented as preproces-
	      sor 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  convention-
	      ally  end	in _state, while other concrete	device class names end
	      in _device.  Concrete device_interface names conventionally  be-
	      gin with device_ and end with _interface.

       Device types
	      Device types should use screaming	snake case.  Remember that de-
	      vice  types  are	names  in  the global namespace, so choose ex-
	      plicit, 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  re-
       served  according  to POSIX standards.  While MAME violates this	policy
       occasionally  most notably with device_t	 its considered	to be  an  un-
       fortunate legacy	decision that should be	avoided	in any new code.

   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  pol-
       icy 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	 inte-
       ger  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	situa-
       tions 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 MAMEs	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 pre-
       fixed with m_ for non-static instance members and s_  for  static  mem-
       bers.  This does	not apply to nested classes or structs.

   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:

	  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:

	  // 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  in-
       denting by one level appears to be used most often.

   Spacing
       Consistent single-spacing between binary	operators, variables, and lit-
       erals is	strongly preferred.  The following examples exhibit reasonably
       consistent spacing:

	  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:

	  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.:

	  switch (value) ...
	  if (a	!= b) ...
	  for (int i = 0; i < foo; i++)	...

   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 MAMEs  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:

	  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);
		  }
	      }
	  }

	  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  de-
       vice  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.

   Const Correctness
       Const-correctness  has  not  historically  been a strict	requirement of
       code that goes into MAME, but theres increasing	value  in  it  as  the
       amount of code refactoring increases and	technical debt decreases.

       When  writing new code, its worth taking	the time to determine if a lo-
       cal variable can	be declared const.  Similarly, it's encouraged to con-
       sider 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:

	  static const char *const EXAMPLE_NAMES[4] =
	  {
	      "1-bit",
	      "2-bit",
	      "4-bit",
	      "Invalid"
	  };

   Comments
       While  /* ANSI C	comments */ are	often found in the codebase, there has
       been a gradual shift towards // C++-style comments for single-line com-
       ments.  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 materi-
       als, comments should be in English so as	to match the predominant  lan-
       guage 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 MAMEs	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.

   MAME-Specific Helpers
       When at all possible, use helper	functions and macros for bit manipula-
       tion 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,	start-
       ing  at the specified bit position.  The	result will also be right-jus-
       tified 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 in-
       teger  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.

   Logging
       MAME  has multiple logging function for different purposes.  Two	of the
       most frequently used logging functions are logerror and osd_printf_ver-
       bose:

        Devices inherit a logerror member function.  This  automatically  in-
	 cludes	 the  fully-qualified  tag  of the invoking device in log mes-
	 sages.	 Output	is sent	to MAMEs debuggers rotating log	buffer if  the
	 debugger is enabled.  If the -log option is enabled, its also written
	 to the	file error.log in the working directory.  If the -oslog	option
	 is  enabled,  its  additionally sent to the OS	diagnostic output (the
	 host debugger diagnostic log on Windows if a  host  debugger  is  at-
	 tached, or standard error otherwise).

        The output of the osd_printf_verbose function is sent to standard er-
	 ror if	the -verbose option is enabled.

       The osd_printf_verbose function should be used for logging that is use-
       ful  for	diagnosing user	issues,	while logerror should be used for mes-
       sages more relevant to developers (either developing  MAME  itself,  or
       developing software for emulated	systems	using MAMEs 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	 chan-
       nels:

	  // 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	avail-
       able 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:

	  // 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:

	  #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.

   Structural organization
       All C++ source files must begin with a two comments listing the distri-
       bution  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:

	  // 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	trans-
	 lation	unit

        Local project headers (i.e. headers found in the same	source	direc-
	 tory)

        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  fol-
       lows:

	  #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 func-
       tion 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 delega-
       tion 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  declara-
       tion,  or  be relegated to #define macros within	the source file.  This
       helps avoid polluting the preprocessor.

   Guidelines for Software Lists
        Introduction

        Items and parts

        Metadata

   Introduction
       MAMEs 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/soft-
       warelist.dtd.

       Philosophically,	software list items should represent the original  me-
       dia,  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  im-
       age file.  Of course, this isnt always possible in practice  in partic-
       ular  its  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	match-
       ing  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.

   Items and parts
       A software list is a collection of items	and each item may have	multi-
       ple 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 rela-
	      tionships	spanning multiple software lists are not supported.

       supported (optional)
	      One  of  the values yes (fully usable in emulation), no (not us-
	      able in emulation), or partial (usable in	emulation with limita-
	      tions).  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 ele-
       ment 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  charac-
	      ters.

       interface (required)
	      This  attribute  is used to identify suitable emulated media de-
	      vices for	mounting the software part.  Applicable	values	depend
	      on the emulated system.

   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 re-
	      quired for  disambiguation,  use	lowercase  outside  of	proper
	      nouns, initialisms and verbatim quotes.

       year   The  year	of release or copyright	year for the software.	If un-
	      known, use an estimate with a question mark.  Items can be  fil-
	      tered by year in the software selection menu.

       publisher
	      The  publisher of	the software.  This may	be the same as the de-
	      veloper if the software was self-published.  Items can  be  fil-
	      tered by published in the	software selection menu.

       Most  user-visible  software  item metadata is provided using info ele-
       ments.  Each info element must have a name attribute and	 a  value  at-
       tribute.	  The  name attribute identifies the type of metadata, and the
       value attribute is the metadata value itself.  Note that	 name  attrib-
       utes  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-re-
	      leased by	a different publisher.

       partno Distributors 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.

TECHNICAL SPECIFICATIONS
       This  section  covers  technical	 specifications	 useful	to programmers
       working on MAMEs	source or working on scripts that run within the  MAME
       framework.

   MAME	Naming Conventions
        Introduction

        Transliteration

        Titles	and descriptions

        C++ naming conventions

   Introduction
       To  promote  consistency	 and  readability in MAME source code, we have
       some naming conventions for various elements.

   Transliteration
       For better or worse, the	most broadly recognised	script in the world is
       English Latin.  Conveniently, its 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  subjec-
       tive 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 nave	transliteration.  For titles  containing  for-
       eign  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 Can-
	      tonese-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 Eng-
	      lish spellings for Greek names (people or	places).

       Japanese
	      Modified Hepburn rules should generally be used.	Use  an	 apos-
	      trophe  between  syllabic	N and a	following vowel	(including io-
	      tised 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	cant  be  used,	omit the tones and replace the
	      vowels with single English vowels	 do not	use VIQR or TELEX con-
	      ventions (an chuot nuong rather than a(n chuo^.t nu*o*'ng	or awn
	      chuootj nuowngs).

   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  de-
       scription   element,   put   the	 title	in  an	info  element  with  a
       name="alt_title"	attribute.

       For software items that have multiple titles (for example different re-
       gional titles with the same installation	media),	 use  the  most	 wide-
       spread  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	manufacturers version number, regional licensees name,
       or terse	description of hardware	differences in preference to arbitrary
       set  numbers.   Surround	the disambiguation text	with parentheses, pre-
       serve original case for names and version text, but use	lowercase  for
       anything	else besides proper nouns and initialisms.

   C++ naming conventions
       For  C++	naming conventions, see	the relevant section in	the C++	Coding
       Guidelines: Naming conventions

   MAME	Layout Files
        Introduction

        Core concepts

	  Numbers

	  Coordinates

	  Colours

	  Parameters

	  Pre-defined parameters

        Parts of a layout

	  Elements

	  Views

	  Collections

	  Reusable groups

	  Repeating blocks

        Interactivity

	  Clickable items

	  Element state

	  View	item animation

        Error handling

        Automatically-generated views

        Using complay.py

        Example layout	files

   Introduction
       Layout files are	used to	tell MAME what to display when running an emu-
       lated system, and how to	arrange	it.  MAME can render emulated screens,
       images, text, shapes, and specialised objects  for  common  output  de-
       vices.	Elements  can  be static, or dynamically update	to reflect the
       state of	inputs and outputs.  Layouts may  be  automatically  generated
       based on	the number/type	of emulated screens, built and linked into the
       MAME  binary, or	provided externally.  MAME layout files	are an XML ap-
       plication, using	the .lay filename extension.

   Core	concepts
   Numbers
       There are two kinds of numbers in MAME  layouts:	 integers  and	float-
       ing-point numbers.

       Integers	may be supplied	in decimal or hexadecimal notation.  A decimal
       integer	consists of an optional	# (hash) prefix, an optional +/- (plus
       or minus) sign character, and a sequence	of digits 0-9.	A  hexadecimal
       number  consists	of one of the prefixes $ (dollar sign) or 0x (zero ex)
       followed	by a sequence of hexadecimal digits 0-9	and A-F.   Hexadecimal
       numbers are case-insensitive for	both the prefix	and digits.

       Floating-point numbers may be supplied in decimal fixed-point or	scien-
       tific  notation.	 Note that integer prefixes and	hexadecimal values are
       not accepted where a floating-point number is expected.

       For a few attributes, both integers and floating-point numbers are  al-
       lowed.	In these cases,	the presence of	a # (hash), $ (dollar sign) or
       0x (zero	ex) prefix causes the value to be interpreted as  an  integer.
       If no recognised	integer	prefix is found	and the	value contains a deci-
       mal point or the	letter E (uppercase or lowercase) introducing an expo-
       nent, it	is interpreted as a floating-point number.  If no integer pre-
       fix, decimal point or letter E is found,	the number will	be interpreted
       as an integer.

       Numbers are parsed using	the "C"	locale for portability.

   Coordinates
       Layout  coordinates are internally represented as IEEE754 32-bit	binary
       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 coordi-
       nates in	layouts.  Coordinates are supplied as floating-point numbers.

       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.

       Views, groups and elements all have their own internal coordinate  sys-
       tems.   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.	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 attrib-
       utes.  Similarly, the vertical position and size	may  be	 specified  in
       terms  of the top edge and height using y and height attributes,	verti-
       cal centre and height using yc and height attributes, or	top and	bottom
       edges using top and bottom attributes.

       These three bounds elements are equivalent:

	  <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"	/>

       Its possible to use different schemes in	the  horizontal	 and  vertical
       directions.   For  example,  these  equivalent bounds elements are also
       valid:

	  <bounds x="455" top="120" width="12" bottom="128" />
	  <bounds left="455" yc="124" right="467" height="8" />

       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.

   Colours
       Colours	are specified in RGBA space.  MAME is not aware	of colour pro-
       files and gamuts, so colours will typically be interpreted as sRGB with
       your systems 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 channel values are	not pre-multi-
       plied 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:

	  <color red="0.85" green="0.4"	blue="0.3" alpha="1.0" />

       Any  omitted  channel  attributes  default  to  1.0  (full intensity or
       opaque).	 It is an error	if any channel value falls outside  the	 range
       of 0.0 to 1.0 (inclusive).

   Parameters
       Parameters are named variables that can be used in most attributes.  To
       use a parameter in an attribute,	surround its name with tilde (~) char-
       acters.	 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~:

	  <element name="digit~digitno~" ref="digit">
	      <bounds x="~x~" y="80" width="25"	height="40" />
	  </element>

       A parameter name	is a sequence of uppercase English letters A-Z,	lower-
       case  English  letters  a-z,  decimal digits 0-9, and/or	underscore (_)
       characters.  Parameter names are	case-sensitive.	 When  looking	for  a
       parameter, the layout engine starts at the current, innermost scope and
       works outwards.	The outermost scope level corresponds to the top-level
       mamelayout  element.  Each repeat, group	or view	element	creates	a new,
       nested scope level.

       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 pre-
       cision).	 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 integer and	floating-point
       number parameters.

       There are two kinds of parameters: value	parameters and generator para-
       meters.	 Value	parameters keep	their assigned value until reassigned.
       Generator parameters have a starting  value  and	 an  increment	and/or
       shift to	be applied for each iteration.

       Value parameters	are assigned using a param element with	name and value
       attributes.   Value parameters may appear inside	the top-level mamelay-
       out element, inside repeat, and view elements, and inside group defini-
       tion elements (that is, group elements in the top-level mamelayout ele-
       ment, as	opposed	to group reference elements inside view	elements other
       group definition	elements).  A value parameter may be reassigned	at any
       point.

       Heres an	example	assigning the value 4 to the  value  parameter	first-
       digit:

	  <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.  Gen-
       erator parameters may only appear inside	repeat elements	(see Repeating
       blocks 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:

	  <param name="nybble" start="3" increment="-1"	/>
	  <param name="switchpos" start="74" increment="156" />
	  <param name="mask" start="0x0800" rshift="4" />

        The nybble parameter generates	values 3, 2, 1...

        The switchpos parameter generates values 74, 230, 386...

        The mask parameter generates values 2048, 128,	8...

       The increment attribute must be an integer or floating-point number  to
       be  added  to  the  parameters value.  The lshift and rshift attributes
       must be non-negative integers specifying	numbers	of bits	to  shift  the
       parameters value	to the left or right.  The increment and shift are ap-
       plied  at  the  end  of	the  repeating block before the	next iteration
       starts.	The parameters 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 parameters 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  parameters value is a	float-
       ing-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
       parameters value	will be	converted to  an  integer  if  necessary,  and
       shifted	accordingly.   Shifting	to the left is defined as shifting to-
       wards the most significant bit.	If both	lshift	and  rshift  are  sup-
       plied,  they  are netted	off before being applied.  This	means you can-
       not, for	example, use equal lshift and rshift attributes	to clear  bits
       at one end of a parameters value	after the first	iteration.

       It  is  an error	if a param element has neither value nor start attrib-
       utes, and it is an error	if a param element has both a value  attribute
       and any of the start, increment,	lshift,	or rshift attributes.

       A  param	element	defines	a parameter or reassigns its value in the cur-
       rent, innermost scope.  It is not possible to define or reassign	 para-
       meters in a containing scope.

   Pre-defined parameters
       A number	of pre-defined value parameters	are available providing	infor-
       mation about the	running	machine:

       devicetag
	      The  full	 tag  path  of the device that caused the layout to be
	      loaded, for example : for	the root driver	device,	 or  :tty:ie15
	      for  a terminal connected	to a port.  This parameter is a	string
	      defined at layout	(global) scope.

       devicebasetag
	      The base tag of the device that caused the layout	to be  loaded,
	      for  example root	for the	root driver device, or ie15 for	a ter-
	      minal connected to a port.  This parameter is a  string  defined
	      at layout	(global) scope.

       devicename
	      The full name (description) of the device	that caused the	layout
	      to  be loaded, for example AIM-65/40 or IE15 Terminal.  This pa-
	      rameter is a string defined at layout (global) scope.

       deviceshortname
	      The short	name of	the  device  that  caused  the	layout	to  be
	      loaded,  for  example aim65_40 or	ie15_terminal.	This parameter
	      is a string defined at layout (global) scope.

       scr0physicalxaspect
	      The horizontal part of the physical aspect ratio	of  the	 first
	      screen (if present).  The	physical aspect	ratio is provided as a
	      reduced  improper	 fraction.   Note  that	this is	the horizontal
	      component	before rotation	is applied.  This parameter is an  in-
	      teger defined at layout (global) scope.

       scr0physicalyaspect
	      The  vertical  part  of  the  physical aspect ratio of the first
	      screen (if present).  The	physical aspect	ratio is provided as a
	      reduced improper fraction.  Note that this is the	vertical  com-
	      ponent 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
	      screens 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 screens
	      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  in-
	      teger defined at layout (global) scope.

       scr0width
	      The width	of the first screens visible area (if present) in emu-
	      lated  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 screens visible area (if present)	in em-
	      ulated  pixels.  Note that this is the height before rotation is
	      applied.	 This  parameter  is  an  integer  defined  at	layout
	      (global) scope.

       scr1physicalxaspect
	      The  horizontal  part of the physical aspect ratio of the	second
	      screen (if present).  This parameter is an  integer  defined  at
	      layout (global) scope.

       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
	      screens 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
	      screens visible area (if present).  This parameter is an integer
	      defined at layout	(global) scope.

       scr1width
	      The width	of the second screens visible area (if present)	in em-
	      ulated  pixels.	This parameter is an integer defined at	layout
	      (global) scope.

       scr1height
	      The height of the	second screens visible area  (if  present)  in
	      emulated pixels.	This parameter is an integer defined at	layout
	      (global) scope.

       scrNphysicalxaspect
	      The  horizontal  part  of	 the  physical	aspect	ratio  of  the
	      (zero-based) Nth screen (if present).  This parameter is an  in-
	      teger defined at layout (global) scope.

       scrNphysicalyaspect
	      The   vertical   part  of	 the  physical	aspect	ratio  of  the
	      (zero-based) Nth screen (if present).  This parameter is an  in-
	      teger defined at layout (global) scope.

       scrNnativexaspect
	      The   horizontal	 part	of  the	 pixel	aspect	ratio  of  the
	      (zero-based) Nth screens visible area (if	present).  This	 para-
	      meter is an integer defined at layout (global) scope.

       scrNnativeyaspect
	      The  vertical part of the	pixel aspect ratio of the (zero-based)
	      Nth screens visible area (if present).  This parameter is	an in-
	      teger defined at layout (global) scope.

       scrNwidth
	      The width	of the	(zero-based)  Nth  screens  visible  area  (if
	      present)	in  emulated pixels.  This parameter is	an integer de-
	      fined at layout (global) scope.

       scrNheight
	      The height of the	(zero-based)  Nth  screens  visible  area  (if
	      present)	in  emulated pixels.  This parameter is	an integer de-
	      fined at layout (global) scope.

       viewname
	      The name of the current view.  This parameter is	a  string  de-
	      fined at view scope.  It is not defined outside a	view.

       For  screen-related  parameters,	 screens are numbered from zero	in the
       order they appear in machine configuration, and	all  screens  are  in-
       cluded  (not just subdevices of the device that caused the layout to be
       loaded).	 X/width and Y/height refer to the horizontal and vertical di-
       mensions	of the screen before rotation is applied.  Values based	on the
       visible area are	calculated at the end of  configuration.   Values  are
       not  updated  and layouts are not recomputed if the system reconfigures
       the screen while	running.

   Parts of a layout
       A view specifies	an arrangement graphical object	to  display.   A  MAME
       layout  file  can contain multiple views.  Views	are built up from ele-
       ments and screens.  To simplify complex layouts,	 reusable  groups  and
       repeating blocks	are supported.

       The  top-level  element of a MAME layout	file must be a mamelayout ele-
       ment with a version attribute.  The version attribute must be an	 inte-
       ger.   Currently	 MAME  only  supports version 2, and will not load any
       other version.  This is an example opening tag for a top-level mamelay-
       out element:

	  <mamelayout version="2">

       In general, children of the top-level mamelayout	element	are  processed
       in  reading  order from top to bottom.  The exception is	that, for his-
       torical reasons,	views are processed last.  This	means  views  see  the
       final  values  of  all parameters at the	end of the mamelayout element,
       and may refer to	elements and groups that appear	after them.

       The following elements are allowed inside the top-level mamelayout ele-
       ment:

       param  Defines or reassigns a value parameter.  See Parameters for  de-
	      tails.

       element
	      Defines  an  element   one  of  the  basic  objects  that	can be
	      arranged in a view.  See Elements	for details.

       group  Defines a	reusable group of elements/screens that	may be	refer-
	      enced  from  views or other groups.  See Reusable	groups for de-
	      tails.

       repeat A	repeating group	 of  elements	may  contain  param,  element,
	      group, and repeat	elements.  See Repeating blocks	for details.

       view   An  arrangement of elements and/or screens that can be displayed
	      on an output device (a host screen/window).  See Views  for  de-
	      tails.

       script Allows  Lua  script to be	supplied for enhanced interactive lay-
	      outs.  See MAME Layout Scripting for details.

   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	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 mul-
       tiple views, and	may be used multiple times within a view.

       An  elements  appearance	depends	on its state.  The state is an integer
       which usually comes from	an I/O port field or an	emulated  output  (see
       Element	state  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 elements state is	a particular value.  Some com-
       ponents (e.g.  multi-segment displays) use the state directly to	deter-
       mine their appearance.

       Each element has	its own	internal coordinate system.  The bounds	of the
       elements	coordinate system are computed as the union of the  bounds  of
       the individual components its 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  layout  file to contain multiple elements	with identical
       name attributes.	 Elements may optionally supply	a default state	 value
       with  a	defstate 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  into the element texture in reading order	from first to last us-
       ing 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	elements state
	 by  supplying	state  and/or statemask	attributes.  If	present, these
	 attributes must be non-negative integers.   If	 only  the  state  at-
	 tribute  is  present,	the component will only	be drawn when the ele-
	 ments 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 elements state.

	 If both the state and statemask attributes are	present, the component
	 will only be drawn when the bits in the elements state	 corresponding
	 to  the bits that are set in the statemask attributes value match the
	 value of the corresponding bits in the	state attributes value.

	 (The component	will always be drawn if	neither	 state	nor  statemask
	 attributes  are  present,  or	if  the	 statemask attributes value is
	 zero.)

        Each component	may have a bounds child	element	specifying  its	 posi-
	 tion  and size	(see 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  components	position  and/or size may be animated according	to the
	 elements 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  elements  state  is lower than the state value of any	bounds
	 child element,	the position/size specified by the bounds  child  ele-
	 ment with the lowest state value will be used.	 If the	elements state
	 is higher than	the state value	of any bounds child element, the posi-
	 tion/size  specified  by  the	bounds	child element with the highest
	 state value will be used.  If the elements state is between the state
	 values	of two bounds child elements, the position/size	will be	inter-
	 polated linearly.

        Each component	may have a color  child	 element  specifying  an  RGBA
	 colour	 (see  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 de-
	 faults	to opaque white.

	 A components color may	be animated according to the elements 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	elements 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 elements 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	elements state is between the state values of two color	 child
	 elements, the RGBA colour components will be interpolated linearly.

       The following components	are supported:

       rect   Draws a uniform colour rectangle filling its bounds.

       disk   Draws a uniform colour ellipse fitted to its bounds.

       image  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 ex-
	      tension) 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 it-
	      self using a data	child element.	This can be useful for supply-
	      ing  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  (bright-
	      ness) 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 con-
	      junction 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  examin-
	      ing 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  be	 supplied  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 the align attribute is	absent,	the text  will
	      be centred.

       led7seg
	      Draws  a	standard  seven-segment	 (plus	decimal	point) digital
	      LED/fluorescent display in the specified colour.	The low	 eight
	      bits  of	the  elements  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	clock-
	      wise  to the upper left segment, the middle bar, and the decimal
	      point.  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
	      elements state control which segments are	 lit.	Starting  from
	      the  least  significant bit, the bits correspond to the top seg-
	      ment, the	upper right-hand segment, continuing clockwise to  the
	      upper  left  segment, the	left-hand and right-hand halves	of the
	      horizontal middle	bar, the upper and lower halves	of the	verti-
	      cal  middle bar, and the diagonal	bars clockwise from lower left
	      to lower right.  Unlit  segments	are  drawn  at	low  intensity
	      (0x20/0xff).

       led14segsc
	      Draws  a	standard fourteen-segment alphanumeric LED/fluorescent
	      display with decimal point/comma in the specified	 colour.   The
	      low  sixteen  bits  of the elements 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
	      elements 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, contin-
	      uing clockwise to	the upper  left	 segment,  the	left-hand  and
	      right-hand  halves  of  the horizontal middle bar, the upper and
	      lower halves of the vertical middle bar, and the	diagonal  bars
	      clockwise	 from  lower  left to lower right.  Unlit segments are
	      drawn at low intensity (0x20/0xff).

       led16segsc
	      Draws a standard	sixteen-segment	 alphanumeric  LED/fluorescent
	      display  with  decimal point/comma in the	specified colour.  The
	      low eighteen bits	of the elements	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 elements state	using the sys-
	      tem 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 integer; if absent, a minimum of
	      two digits will be displayed.  A maxstate	attribute may be  sup-
	      plied  to	 specify  the  maximum	state  value  to  display.  If
	      present, the maxstate attribute must be a	 non-negative  number;
	      if  absent  it  defaults to 999.	An align attribute may be sup-
	      plied 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.

       An example element that draws a static left-aligned text	string:

	  <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 de-
       pends on	the state of an	active-high output:

	  <element name="led" defstate="0">
	      <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:

	  <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>
	      <rect state="1"><bounds x="0.0" y="0.0" width="1.0" height="1.0" /><color	red="0.1" green="0.1" blue="0.1" /></rect>
	      <rect state="0"><bounds x="0.1" y="0.1" width="0.9" height="0.9" /><color	red="0.1" green="0.1" blue="0.1" /></rect>
	      <rect state="1"><bounds x="0.1" y="0.1" width="0.9" height="0.9" /><color	red="0.2" green="0.2" blue="0.2" /></rect>
	      <rect><bounds x="0.1" y="0.1" width="0.8"	height="0.8" /><color red="0.15" green="0.15" blue="0.15" /></rect>
	      <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:

	  <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:

	  <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:

	  <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>

   Views
       A view defines an arrangement of	elements and/or	emulated screen	images
       that  can  be displayed in a window or on a screen.  Views also connect
       elements	to emulated I/O	ports and/or outputs.  A layout	file may  con-
       tain  multiple  views.	If a view references a non-existent screen, it
       will be considered unviable.  MAME will print a warning	message,  skip
       over  the  unviable  view,  and	continue to load views from the	layout
       file.  This is particularly useful for systems where a  screen  is  op-
       tional,	for  example computer systems with front panel controls	and an
       optional	serial terminal.

       Views are identified by name  in	 MAMEs	user  interface	 and  in  com-
       mand-line  options.   For  layouts  files associated with devices other
       than the	root driver device, view names are prefixed with  the  devices
       tag  (with  the	initial	colon omitted)	for example a view called Key-
       board LEDs loaded for the device	:tty:ie15 will be called tty:ie15 Key-
       board LEDs in MAMEs 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 op-
       tions.  This is an example of a valid opening tag for a view element:

	  <view	name="Control panel">

       A view creates a	nested parameter scope inside the parameter  scope  of
       the  top-level  mamelayout  element.  For historical reasons, view ele-
       ments are processed after all other child  elements  of	the  top-level
       mamelayout  element.   This  means  a  view  can	reference elements and
       groups that appear after	it in the file,	and parameters	from  the  en-
       closing scope will have their final values from the end of the mamelay-
       out 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 views internal coordinate	system
	      if present.  See 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 con-
	      tent outside the views 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 views scope.   See
	      Parameters for details.

       element
	      Adds an element to the view (see Elements).  The name of the el-
	      ement  to	add is specified using the required ref	attribute.  It
	      is an error if no	element	with this name is defined in the  lay-
	      out  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	input-
	      tag  and inputmask attributes, and/or an emulated	output using a
	      name attribute.  See Clickable items for details.	  See  Element
	      state 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 for a screen element to have both index and tag
	      attributes).  If present,	the index attribute must be a non-neg-
	      ative integer.  Screens are numbered by the order	they appear in
	      machine configuration, starting at 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	input-
	      tag and inputmask	attributes, and/or an emulated output using  a
	      name attribute.  See Clickable items for details.

       collection
	      Adds  screens  and/or items in a collection that can be shown or
	      hidden by	the user (see Collections).  The name of  the  collec-
	      tion 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 Reusable 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.

       repeat Repeats  its  contents  the number of times specified by the re-
	      quired count 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 Repeating
	      blocks 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  in-
       stantiated  via reusable	groups and repeating blocks.  Screens and lay-
       out elements with id attributes can be looked up	by  Lua	 scripts  (see
       MAME Layout Scripting).

       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 to  the  orientation	 modifiers  specified  on  the
       screen device and on the	machine.  The orientation element supports the
       following attributes, all of which are optional:

       rotate If  present,  applies clockwise rotation in ninety degree	incre-
	      ments.  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  forty-five  degrees  to  vertical  from  upper left to lower
	      right.  Must be either yes or no if present.  Mirroring  applies
	      logically	after rotation.

       flipx  Allows  the  screen,  element or group to	be mirrored around its
	      vertical axis, from left to right.  Must be either yes or	no  if
	      present.	Mirroring applies logically after rotation.

       flipy  Allows  the  screen,  element or group to	be mirrored around its
	      horizontal axis, from top	to bottom.  Must be either yes	or  no
	      if present.  Mirroring applies logically after rotation.

       Screens	(screen	 elements)  and	layout elements	(element elements) may
       have a blend attribute to set the blending mode.	 Supported values  are
       none  (no  blending), alpha (alpha blending), multiply (RGB multiplica-
       tion), and add (additive	blending).  The	default	for screens is to  al-
       low the driver to specify blending per layer; the default blending mode
       for 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  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 po-
       sitioning a screen, an  individual  layout  element,  and  two  element
       groups:

	  <view	name="LED Displays, Terminal and Keypad">
	      <screen index="0"><bounds	x="0" y="132" width="320" height="240" /></screen>
	      <element ref="beige"><bounds x="320" y="0" width="172" height="372" /></element>
	      <group ref="displays"><bounds x="0" y="0"	width="320" height="132" /></group>
	      <group ref="keypad"><bounds x="336" y="16" width="140" height="260" /></group>
	  </view>

       Screens	(screen	 elements),  layout  elements  (element	 elements) and
       groups (group elements) may have	a color	child  element	(see  Colours)
       specifying  a  modifier colour.	The component colours of the screen or
       layout element(s) are multiplied	by this	colour.

       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  View
       item animation for details.

       Layout  elements	(element elements) may be configured to	show only part
       of the elements width or	height using xscroll and/or yscroll child ele-
       ments.  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 pro-
	      portion of the elements 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	trail-
	      ing  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 val-
	      ues  (specified  with  the name attribute) as well as input port
	      values (specified	with the inputtag attribute).  Must be an  in-
	      teger 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.

   Collections
       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  col-
       lection 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 pro-
       viding 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:

	  <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>

       A collection creates a nested parameter scope.  Any param elements  in-
       side  the  collection element set parameters in the local scope for the
       collection.  See	Parameters for more detail on parameters.  (Note  that
       the  collections	 name  and default visibility are not part of its con-
       tent, and any parameter references in the name and  visible  attributes
       themselves  will	be substituted using parameter values from the collec-
       tions parents scope.)

   Reusable groups
       Groups allow an arrangement of screens and/or  layout  elements	to  be
       used multiple times in views or other groups.  Groups can be beneficial
       even  if	 you only use the arrangement once, as they can	be used	to en-
       capsulate part of a complex layout.  Groups are defined using group el-
       ements inside the top-level mamelayout element, and instantiated	 using
       group elements inside view and other group elements.

       Each  group  definition	element	must have a name attribute providing a
       unique 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  an-
       other group.  This is an	example	opening	tag for	a group	definition el-
       ement inside the	top-level mamelayout element:

	  <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 identi-
       fies  the group to instantiate  in this example,	destination bounds are
       supplied:

	  <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 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.

       Groups  have their own internal coordinate systems.  If a group defini-
       tion 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 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 posi-
       tion screens and/or elements outside its	bounds,	and they will  not  be
       cropped.

       To demonstrate how bounds calculation works, consider this example:

	  <group name="autobounds">
	      <!-- bounds automatically	calculated with	origin at (5,10), width	30, and	height 15 -->
	      <element ref="topleft"><bounds x="5" y="10" width="10" height="10" /></element>
	      <element ref="bottomright"><bounds x="25"	y="15" width="10" height="10" /></element>
	  </group>

	  <view	name="Test">
	      <!--
		  group	bounds translated and scaled to	fit - 2/3 scale	horizontally and double	vertically
		  element topleft positioned at	(0,0) with width 6.67 and height 20
		  element bottomright positioned at (13.33,10) with width 6.67 and height 20
		  view bounds calculated with origin at	(0,0), width 20, and height 30
	      -->
	      <group ref="autobounds"><bounds x="0" y="0" width="20" height="30" /></group>
	  </view>

       This  is	 relatively  straightforward,  as all elements inherently fall
       within the groups automatically computed	 bounds.   Now	consider  what
       happens if a group positions elements outside its explicit bounds:

	  <group name="periphery">
	      <!-- elements are	above the top edge and to the right of the right edge of the bounds -->
	      <bounds x="10" y="10" width="20" height="25" />
	      <element ref="topleft"><bounds x="10" y="0" width="10" height="10" /></element>
	      <element ref="bottomright"><bounds x="30"	y="20" width="10" height="10" /></element>
	  </group>

	  <view	name="Test">
	      <!--
		  group	bounds translated and scaled to	fit - 3/2 scale	horizontally and unity vertically
		  element topleft positioned at	(5,-5) with width 15 and height	10
		  element bottomright positioned at (35,15) with width 15 and height 10
		  view bounds calculated with origin at	(5,-5),	width 45, and height 30
	      -->
	      <group ref="periphery"><bounds x="5" y="5" width="30" height="25"	/></group>
	  </view>

       The  groups  elements are translated and	scaled as necessary to distort
       the groups internal bounds to the destination bounds in the view.   The
       groups 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.

       When a group is instantiated, it	creates	a nested parameter scope.  The
       logical	parent	scope is the parameter scope of	the view, group	or re-
       peating block where 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 in-
       stantiation.  Local parameters do not persist across multiple instanti-
       ations.	See Parameters for more	detail on parameters.  (Note that  the
       groups 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 elements scope.)

   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  Parameters).   Repeating
       blocks may be nested for	more complex arrangements.

       Repeating blocks	are created with repeat	elements.  Each	repeat element
       requires	 a count attribute specifying the number of iterations to gen-
       erate.  The count attribute must	 be  a	positive  integer.   Repeating
       blocks  are  allowed  inside  the  top-level mamelayout element,	inside
       group and view elements,	and insider other repeat elements.  The	 exact
       child  elements	allowed	inside a repeat	element	depend on where	it ap-
       pears:

        A repeating block inside the top-level	mamelayout element may contain
	 param,	element, group (definition), and repeat	elements.

        A repeating block inside a group or view element may  contain	param,
	 element (reference), screen, group (reference), and repeat elements.

       A  repeating block effectively repeats its contents the number of times
       specified by its	count attribute.  See the relevant  sections  for  de-
       tails  on  how the child	elements are used (Parts of a layout, Reusable
       groups, and 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,  la-
       bel_1, and so on	(inside	the top-level mamelayout element):

	  <repeat count="12">
	      <param name="labelnum" start="0" increment="1" />
	      <element name="label_~labelnum~">
		  <text	string="~labelnum~"><color red="1.0" green="1.0" blue="1.0" /></text>
	      </element>
	  </repeat>

       A  horizontal  row of forty digital displays, with five units space be-
       tween them, controlled by outputs digit0	to digit39 (inside a group  or
       view element):

	  <repeat count="40">
	      <param name="i" start="0"	increment="1" />
	      <param name="x" start="5"	increment="30" />
	      <element name="digit~i~" ref="digit">
		  <bounds x="~x~" y="5"	width="25" height="50" />
	      </element>
	  </repeat>

       Eight  five-by-seven  dot  matrix  displays  in a row, with pixels con-
       trolled by outputs Dot_000 to Dot_764 (inside a group or	view element):

	  <repeat count="8"> <!-- 8 digits -->
	      <param name="digitno" start="1" increment="1" />
	      <param name="digitx" start="0" increment="935" />	<!-- distance between digits ((111 * 5)	+ 380) -->
	      <repeat count="7"> <!-- 7	rows in	each digit -->
		  <param name="rowno" start="1"	increment="1" />
		  <param name="rowy" start="0" increment="114" /> <!-- vertical	distance between LEDs -->
		  <repeat count="5"> <!-- 5 columns in each digit -->
		      <param name="colno" start="1" increment="1" />
		      <param name="colx" start="~digitx~" increment="111" /> <!-- horizontal distance between LEDs -->
		      <element name="Dot_~digitno~~rowno~~colno~" ref="Pixel" state="0">
			  <bounds x="~colx~" y="~rowy~"	width="100" height="100" /> <!-- size of each LED -->
		      </element>
		  </repeat>
	      </repeat>
	  </repeat>

       Two horizontally	separated, clickable, four-by-four keypads  (inside  a
       group or	view element):

	  <repeat count="2">
	      <param name="group" start="0" increment="4" />
	      <param name="padx" start="10" increment="530" />
	      <param name="mask" start="0x01" lshift="4" />
	      <repeat count="4">
		  <param name="row" start="0" increment="1" />
		  <param name="y" start="100" increment="110" />
		  <repeat count="4">
		      <param name="col"	start="~group~"	increment="1" />
		      <param name="btnx" start="~padx~"	increment="110"	/>
		      <param name="mask" start="~mask~"	lshift="1" />
		      <element ref="btn~row~~col~" inputtag="row~row~" inputmask="~mask~">
			  <bounds x="~btnx~" y="~y~" width="80"	height="80" />
		      </element>
		  </repeat>
	      </repeat>
	  </repeat>

       The  buttons  are  drawn	using elements btn00 in	the top	left, bnt07 in
       the top right, btn30 in the bottom left,	and btn37 in the bottom	right,
       counting	in between.  The four rows are connected to  I/O  ports	 row0,
       row1, row2, and row3, from top to bottom.  The columns are connected to
       consecutive  I/O	 port bits, starting with the least significant	bit on
       the left.   Note	that the mask parameter	in the innermost  repeat  ele-
       ment  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):

	  <repeat count="4">
	      <param name="pairy" start="3" increment="20" />
	      <param name="pairno" start="7" increment="-2" />
	      <repeat count="2">
		  <param name="rowy" start="~pairy~" increment="10" />
		  <param name="rowno" start="~pairno~" increment="-1" />
		  <param name="lalpha" start="0.4" increment="-0.2" />
		  <param name="ralpha" start="0.2" increment="0.2" />
		  <repeat count="4">
		      <param name="lx" start="3" increment="20"	/>
		      <param name="rx" start="13" increment="20" />
		      <param name="lmask" start="0x01" lshift="2" />
		      <param name="rmask" start="0x02" lshift="2" />
		      <element ref="hl"	inputtag="board:IN.~rowno~" inputmask="~lmask~">
			  <bounds x="~lx~" y="~rowy~" width="10" height="10" />
			  <color alpha="~lalpha~" />
		      </element>
		      <element ref="hl"	inputtag="board:IN.~rowno~" inputmask="~rmask~">
			  <bounds x="~rx~" y="~rowy~" width="10" height="10" />
			  <color alpha="~ralpha~" />
		      </element>
		  </repeat>
	      </repeat>
	  </repeat>

       The outermost repeat element generates a	group of two rows on each  it-
       eration;	 the  next  repeat element generates an	individual row on each
       iteration; the innermost	repeat element produces	two horizontally adja-
       cent tiles  on  each  iteration.	  Rows	are  connected	to  I/O	 ports
       board:IN.7 at the top to	board.IN.0 at the bottom.

   Interactivity
       Interactive  views  are supported by allowing items to be bound to emu-
       lated outputs and I/O ports.  Five  kinds  of  interactivity  are  sup-
       ported:

       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  con-
	      taining	elements   state.    These  include  the  dot  matrix,
	      multi-segment LED	display	 and  simple  counter  elements.   See
	      Elements for details.

       Conditionally-drawn components
	      Components may be	conditionally drawn or hidden depending	on the
	      containing  elements  state  by supplying	state and/or statemask
	      attributes.  See Elements	for details.

       Component parameter animation
	      Components colour	and position/size within their containing ele-
	      ment may be animated according the elements state	 by  providing
	      multiple	color  and/or  bounds  elements	with state attributes.
	      See Elements for details.

       Item parameter animation
	      Items colour and position/size within their containing view  may
	      be animated according to their animation state.

   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  emu-
       lated  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 items current bounds.	(Note that the
       bounds may change depending on the items	animation state, see View item
       animation).

       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  at-
       tribute 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.

	  <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.

   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
       Elements	for details on how an elements 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 out-
       put.  Note that output names are	global,	which can become an issue when
       a machine uses multiple instances of the	same type of device.  This ex-
       ample shows how digital displays	may be connected to emulated outputs:

	  <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 at-
       tribute 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 ports 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 its 0.	  This
       is often	used or	provide	visual feedback	for clickable buttons, as val-
       ues 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 ports  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.

   View	item animation
       Items colour and	position/size within their containing view may be ani-
       mated.  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 items 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 items	anima-
       tion  state is higher than the state value of any bounds	child element,
       the position/size specified by the bounds child element with the	 high-
       est  state value	will be	used.  If the items animation state is between
       the state values	of two bounds child elements, the  position/size  will
       be interpolated linearly.

       If the items 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 items 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	items animation	state is between the state  values  of
       two  color  child elements, the RGBA colour components will be interpo-
       lated linearly.

       An items	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 items ani-
       mation state is the same	as its element state (see Element state).

       If the animate child element is present and has an inputtag  attribute,
       the  items  animation  state will be taken from the value of the	corre-
       sponding	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
       items  animation	 state will be taken from the value of the correspond-
       ingly 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 items  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	anima-
       tion  state,  using  the	animation state	taken from emulated outputs to
       control their position:

	  <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	anima-
       tion state, using the animation state taken from	an emulated positional
       input to	control	their positions:

	  <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>

   Error handling
        For  internal	(developer-supplied)  layout files, errors detected by
	 the complay.py	script result in a build failure.

        MAME will stop	loading	a layout file if a  syntax  error  is  encoun-
	 tered.	 No views from the layout will be available.  Examples of syn-
	 tax  errors  include  undefined  element or group references, invalid
	 bounds, invalid colours, recursively  nested  groups,	and  redefined
	 generator parameters.

        When  loading	a  layout  file,  if  a	view references	a non-existent
	 screen, MAME will print a warning message and continue.  Views	refer-
	 encing	non-existent screens are considered unviable and not available
	 to the	user.

   Automatically-generated views
       After loading internal  (developer-supplied)  and  external  (user-sup-
       plied) 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.

        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
	 doesnt	 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  dont	 automatically
	 rotate	 the  display  for the second player.  The screen will be dis-
	 played	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 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 in-
	 ternal	 or  external  layouts shows all screens, or if	the system has
	 more than two emulated	screens, MAME will  generate  views  with  the
	 screens  arranged horizontally	from left to right and vertically from
	 top to	bottom,	both with and without small gaps  between  them.   The
	 screens will be displayed at physical aspect ratio, with rotation ap-
	 plied.

        If  the system	has three or more emulated screens, MAME will generate
	 views	tiling	the  screens  in  grid	patterns,  in  both  row-major
	 (left-to-right	 then  top-to-bottom)  and column-major	(top-to-bottom
	 then left-to-right) order.  Views are generated with and without gaps
	 between the screens.  The screens will	be displayed at	 physical  as-
	 pect ratio, with rotation applied.

   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	 MAMEs
       build  process to reduce	the size of data for internal layouts and con-
       vert 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 doesnt actually run	the whole layout engine, so it
       cant detect errors like undefined element  references  when  parameters
       are  used, or recursively nested	groups.	 The complay.py	script is com-
       patible 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:
	  python scripts/build/complay.py <input> [<output> [<varname>]]

       The  input  file	name is	required.  If no output	file name is supplied,
       complay.py will parse and check the input, reporting any	errors	found,
       without	producing  output.  If no base variable	name is	provided, com-
       play.py will generate one based on the input file name.	 This  is  not
       guaranteed  to  produce valid identifiers.  The exit status is 0	(zero)
       on success, 1 on	an error in the	command	invocation,  2	if  error  are
       found  in  the  input file, or 3	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  to  check	and no output file name	or base	variable name.
       For example:
	  python scripts/build/complay.py artwork/dino/default.lay

   Example layout files
       These layout files demonstrate various artwork system  features.	  They
       are all internal	layouts	included in MAME.

       sstrangr.lay
	      A	 simple	 case of using translucent colour overlays to visually
	      separate and highlight elements on a black and white screen.

       seawolf.lay
	      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 dis-
	      abled selectively.

       armora.lay
	      This games monitor is  viewed  directly  through	a  translucent
	      colour overlay rather than being reflected from inside the cabi-
	      net.   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
	      A	 multi-segment	alphanumeric display and keypad.  The keys are
	      clickable, and provide visual feedback when pressed.

       esq2by16.lay
	      Builds up	a multi-line dot matrix	 character  display.   Repeats
	      are  used	to avoid repetition for	the rows in a character, char-
	      acters in	a line,	and lines in a page.   Group  colors  allow  a
	      single element to	be used	for all	four display colours.

       cgang.lay
	      Animates	the  position of element items to simulate an electro-
	      mechanical shooting gallery game.	 Also  demonstrates  effective
	      use of components	to build up complex graphics.

       minspace.lay
	      Shows the	position of a slider control with LEDs on it.

       md6802.lay
	      Effectively using	groups as a procedural programming language to
	      build up an image	of a trainer board.

       beena.lay
	      Using event-based	scripting to dynamically position elements and
	      draw elemnt content programmatically.

   MAME	Layout Scripting
        Introduction

        Practical examples

	  Espial: joystick split across ports

	  Star	Wars: animation	on two axes

        The layout script environment

        Layout	events

	  Layout file events

	  Layout view events

	  Layout view item events

	  Layout element events

   Introduction
       MAME  layout files can embed Lua	script to provide enhanced functional-
       ity.  Although theres a lot you can do with conditionally drawn	compo-
       nents  and  parameter  animation,  some	things	can  only be done with
       scripting.  MAME	uses an	event-based model.  Scripts can	 supply	 func-
       tions that will be called after certain events, or when certain data is
       required.

       Layout  scripting  requires the layout plugin to	be enabled.  For exam-
       ple, 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
       Plugins for more	information about using	plugins	with MAME.

   Practical examples
       Before  diving  into  the technical details of how it works, well start
       with some example layout	files using Lua	script for  enhancement.   Its
       assumed	that youre familiar with MAMEs artwork system and have a basic
       understanding of	Lua scripting.	For details on MAMEs layout file,  see
       MAME  Layout  Files;  for detailed descriptions of MAMEs	Lua interface,
       see Lua Scripting Interface.

   Espial: joystick split across ports
       Take a look at the player input definitions for Espial:

	  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	 cabi-
       net  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.

       Theres no layout	file syntax to build the element state using bits from
       multiple	I/O ports.  Its	also inconvenient if each joystick needs to be
       defined	as  a separate element because the bits	for the	switches arent
       arranged	the same way.

       We can overcome these limitations using a script	to read	the player in-
       puts and	set the	items element state:

	  <?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  emu-
       lated system has	not finished starting.	In particular, its 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 layout	file.

       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 I/O	ports 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 view items	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.

   Star	Wars: animation	on two axes
       Well make a layout that shows the position of the flight	yoke for Atari
       Star  Wars.  The	input ports are	straightforward	 each analog axis pro-
       duces a value in	the range from 0x00 (0)	to 0xff	(255), inclusive:

	  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)

       Heres our layout	file:

	  <?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 em-
       ulated  system  has  finished starting.	The layout file	object is sup-
       plied 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 inputs.

        Looks	up the view item 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 views dimensions have been
	 recomputed.

        Supplies a function to	be called before adding	view items to the ren-
	 der 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.	 Its 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 an-
       imated 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 were dis-
       playing the yoke	position.  We do this once each	 time  the  layout  is
       drawn  for  efficiency,	since we can use the values for	all three ani-
       mated 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
       formats	item  animation	features.  Only	the box	at the intersection of
       the line	actually requires scripting.  Its done entirely	using  script-
       ing here	for illustrative purposes.)

   The layout script environment
       The Lua environment is provided by the layout plugin.  Its fairly mini-
       mal, only providing whats needed:

        file  giving  the  scripts layout file	object.	 Has a device property
	 for obtaining the device that caused the layout file  to  be  loaded,
	 and  a	 views	property  for  obtaining the layouts views (indexed by
	 name).

        machine giving	MAMEs current running 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 attotime, bounds and colour 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	bitmaps.

        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, ta-
	 bles and other	containers.

        Standard Lua print function for text output to	the console.

   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.

   Layout file events
       Layout file events apply	to the file as a whole,	and not	to an individ-
       ual 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 parame-
	      ters.  Call with nil as the argument to remove  the  event  han-
	      dler.

   Layout view events
       Layout view events apply	to an individual view.

       Prepare items
	      view:set_prepare_items_callback(cb)

	      Called  before the views items are added to the render target in
	      preparation for drawing a	video frame.

	      The callback function has	no return value	and takes  no  parame-
	      ters.   Call  with  nil as the argument to remove	the event han-
	      dler.

       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  parame-
	      ters.   Call  with  nil as the argument to remove	the event han-
	      dler.

       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 collec-
	      tions,  and changes to the rotation and zoom to screen area set-
	      tings.  If youre 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  parame-
	      ters.   Call  with  nil as the argument to remove	the event han-
	      dler.

       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 ges-
		tures.

	      	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  ges-
		tures.

	      	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 receiv-
	      ing 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 ges-
		tures.

	      	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 parame-
	      ters.  Call with nil as the argument to remove  the  event  han-
	      dler.

   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 items element state.	 This controls
	      how the items element is drawn, for components that  change  ap-
	      pearance depending on state, conditionally-drawn components, and
	      component	bounds/colour animation.  Do not attempt to access the
	      items  element_state  property from the callback,	as it will re-
	      sult in infinite recursion.

	      The callback function must return	an integer, and	takes no para-
	      meters.  Call with nil as	the argument to	 restore  the  default
	      element state handler (based on the items	XML attributes).

       Get animation state
	      item:set_animation_state_callback(cb)

	      Set  callback  for  getting  the items animation state.  This is
	      used for item bounds/colour animation.  Do not attempt to	access
	      the items	animation_state	property from the callback, as it will
	      result in	infinite recursion.

	      The callback function must return	an integer, and	takes no para-
	      meters.  Call with nil as	the argument to	 restore  the  default
	      animation	 state	handler	(based on the items XML	attributes and
	      animate child element).

       Get item	bounds
	      item:set_bounds_callback(cb)

	      Set callback for getting the items bounds	(position  and	size).
	      Do  not  attempt	to  access  the	items bounds property from the
	      callback,	as it will result in infinite recursion.

	      The callback function must return	a render bounds	object	repre-
	      senting  the  items 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 han-
	      dler  (based  on the items animation state and bounds child ele-
	      ments).

       Get item	colour
	      item:set_color_callback(cb)

	      Set callback for getting the items colour	(the element  textures
	      colours  multiplied  by  this colour).  Do not attempt to	access
	      the items	color property from the	callback, as it	will result in
	      infinite recursion.

	      The callback function must return	a render colour	object	repre-
	      senting  the  ARGB  colour  (usually created by calling emu.ren-
	      der_color), and takes no parameters.  Call with nil as the argu-
	      ment to restore the default colour handler (based	on  the	 items
	      animation	state and color	child elements).

       Get item	horizontal scroll window size
	      item:set_scroll_size_x_callback(cb)

	      Set  callback  for  getting  the	items 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	 items
	      scroll_size_x  property  from the	callback, as it	will result in
	      infinite recursion.

	      The callback function must return	a floating-point number	repre-
	      senting the horizontal window size as a proportion of the	 asso-
	      ciated  elements 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 items 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 items
	      scroll_size_y property from the callback,	as it will  result  in
	      infinite recursion.

	      The callback function must return	a floating-point number	repre-
	      senting  the vertical window size	as a proportion	of the associ-
	      ated elements 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 items 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	 items
	      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 items 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 items
	      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 ele-
	      ment).

   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  elements	compo-
	      nents  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  in-
	      teger)  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.

   Object Finders
        Introduction

        Types of object finder

        Finding resources

        Connections between devices

        Object	finder arrays

        Optional object finders

	  Optional system components

	  Optional resources

        Object	finder types in	more detail

	  Device finders

	  Memory system object	finders

	  I/O port finders

	  Address space finders

	  Memory pointer finders

        Output	finders

   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 vali-
       dation.

       Object finders search for a target object by tag	relative to a base de-
       vice.  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  tar-
       get 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  doesnt exist.	 The target is the memory_bank object.
	      There is no optional version, because the	target object will al-
	      ways be found or created.

       required_ioport,	optional_ioport
	      Finds an I/O port	from a devices input  port  definitions.   The
	      target is	the ioport_port	object.

       required_address_space, optional_address_space
	      Finds  a devices 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 def-
	      initions.	 The template argument PointerType is the target  type
	      (usually an unsigned integer type).  The target is the first el-
	      ement in the memory region.

       required_shared_ptr<PointerType>, optional_shared_ptr<PointerType>
	      Finds  the base pointer of a memory share	instantiated in	an ad-
	      dress map.  The template argument	PointerType is the target type
	      (usually an unsigned integer type).  The target is the first el-
	      ement in the memory share.

       memory_share_creator<PointerType>
	      Finds the	base pointer of	a memory share instantiated in an  ad-
	      dress map, or creates it if it doesnt exist.  The	template argu-
	      ment 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 al-
	      ways be found or created.

   Finding resources
       Well start with a simple	example	of a device that uses  object  finders
       to  access its own child	devices, inputs	and ROM	region.	 The code sam-
       ples 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:

	  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:

	  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	 argu-
       ments.	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:

	  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  devices	machine	 configuration
       member function:

	  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 instan-
       tiating 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:

	  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.	 Heres
       how we declare the object finders in the	device class  (with  all  dis-
       tractions removed):

	  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 doesnt know how it	will fit into a	larger system, the ob-
	 ject 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 addi-
       tion to a tag-like object.

       So whats	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 configura-
	 tion.	Its most often used with *this.

       The additional constructor that sets initial configuration delegates to
       the standard constructor	and then calls the configuration member	 func-
       tions.  Its 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 de-
       vice, 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 addi-
       tional 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  re-
       sources 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_ar- |
	      |			       | ray			    |
	      +------------------------+----------------------------+
	      |	optional_memory_region | optional_memory_region_ar- |
	      |			       | ray			    |
	      +------------------------+----------------------------+
	      |	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_ar- |
	      |			       | ray			    |
	      +------------------------+----------------------------+
	      |	optional_address_space | optional_address_space_ar- |
	      |			       | ray			    |
	      +------------------------+----------------------------+
	      |	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:

	  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  ob-
       ject 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  dont	 need  to  use
       zero-based indices.  Its	common to use one-based	indexing like this:

	  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.

       Its also	possible to other format conversions, like hexadecimal (%x and
       %X) or character	(%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 dont follow a simple ascending sequence, you can supply a
       brace-enclosed initialiser list of tags:

	  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	 argu-
       ments, supply them after	the tag	format and index offset	(the same val-
       ues will	be used	for all	elements of the	array):

	  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 dont raise an error if the target  object  isnt
       found.  This is useful in two situations: driver_device implementations
       (state  classes)	representing a family of systems where some components
       arent 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  isnt	present	in all configurations, it may be convenient to
       use an optional object finder to	access it.  Well use the Sega  X-board
       device as an example:

	  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	 finders  found() member function to check whether its
       present in the system (the explicit  cast-to-Boolean  operator  can  be
       used for	the same purpose):

	  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:

	  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 it-
       self, and not a member  of  the	target	ioport_port  object  (the  op-
       tional_ioport is	not dereferenced when using it).

       There are some disadvantages to using optional object finders:

        Theres	 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 fre-
	 quently.

       Consider	whether	optional object	finders	 are  the  best	 solution,  or
       whether	creating a derived class for the system	with additional	compo-
       nents is	more appropriate.

   Optional resources
       Some devices can	optionally use certain resources.  If the host	system
       doesnt supply them, the device will still function, although some func-
       tionality 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 doesnt  need  to
       supply a	place for the cartridge	to install the corresponding handlers.
       (For example a copier may only use the ROM space.)

       Lets  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 in-
       line member functions for configuring them:

	  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):

	  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, well check for cases where address
       spaces have been	configured but arent present:

	  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:

	  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 callers 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:

	  ObjectClass *target()	const;
	  operator ObjectClass *() const;
	  ObjectClass *operator->() const;

       These members all provide access	to the target object.  The target mem-
       ber 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:

	  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:

	  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_mem-
       ory_region,   required_memory_bank,   optional_memory_bank   and	  mem-
       ory_bank_creator,  do not have any special functionality.  They are of-
       ten used	in place of literal tags when installing memory	 banks	in  an
       address space.

       Example using memory bank finders in an address map:

	  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 dynami-
       cally:

	  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:

	  ioport_value read_safe(ioport_value defval);

       This will read the ports	value if the target I/O	port was found,	or re-
       turn  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.

	  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 de-
       vice_memory_interface.  The address space number	is a zero-based	 index
       to one of the devices address spaces.

       If  the width is	non-zero, it must match	the target address spaces 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 spaces data width wont be checked.

       Member functions	are also provided to get the configured	address	 space
       number and set the required data	width:

	  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 doesnt 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 mem-
       bers for	accessing the size of the memory area:

	  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 mem-
       bers 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:

	  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 Endian-
       ness.

       The memory_share_creator	 provides  additional  members	for  accessing
       properties of the memory	share:

	  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 mem-
       ory 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 theyre	described here
       because	theyre 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 di-
	 mensions.

        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 correspond-
       ing to the number of array dimensions you want.	Lets look at an	 exam-
       ple that	uses zero-, one- and two-dimensional output finders:

	  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 find-
       ers.  They find a single	output each.  The m_digits member is a one-di-
       mensional  output  finder.   It	finds nine outputs organised as	a sin-
       gle-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:

	  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 outputs current
       value.

	  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:

	  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;
	  }

   Input System
        Introduction

        Components

	  Input device

	  Input device	item

	  I/O port field

	  Input manager

	  I/O port manager

        Structures and	data types

	  Input code

	  Input sequence

        Input provider	modules

        Player	positions

        Updating I/O port fields

	  Updating digital fields

	  Updating absolute analog fields

	  Updating relative analog fields

   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.

   Components
       From  the emulated systems point	of view, the input system has the fol-
       lowing conceptual components.

   Input device
       Input devices supply input values.  An input  device  typically	corre-
       sponds to a physical device in the host system, for example a keyboard,
       mouse or	game controller.  However, there isnt always a one-to-one cor-
       respondence  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 im-
       plementations) 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 rel-
       ative 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 approxi-
	 mately	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 dis-
       tinct 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	 infi-
       nite 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 devices 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 com-
       binations  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	direc-
	 tion  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, displace-
	 ment-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 MAMEs user interface.

        Additional  special field types are used to produce fixed or program-
	 matically 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	decre-
       ment 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  in-
       put  manager directly.  The most	common reason to access	the input man-
       ager is implementing special debug controls, which should  be  disabled
       in  release builds.  Plugins that respond to input need to call the in-
       put manager to read inputs.

   I/O port manager
       The I/O port managers primary responsibilities include:

        Managing assignments of controls to I/O port fields and  user	inter-
	 face 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.

   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  in-
       terpreted.   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 in-
	 put 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  op-
	 tions	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	speci-
	 fied.	 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 con-
	 trol 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 ap-
	 plicable to the primary X/Y axes of joystick devices.	The  user  can
	 specify  a joystick map to control how	these modifiers	interpret joy-
	 stick 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 posi-
	 tive/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 youll encounter input codes in device and	system
       driver code is when specifying initial assignments for I/O port	fields
       that dont 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/light-
       gun 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 mis-
       leading,	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 spe-
       cial  or	 and not codes.	 Its 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 re-
	 turned	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 ab-
	 solute	axes it	is clamped to the range	-65,536	to 65,536 (values pro-
	 duced from relative axes are not clamped).

       Emulation code rarely needs to deal with	input sequences	 directly,  as
       theyre  handled	internally between the I/O port	manager	and input man-
       ager.  The input	manager	also converts input sequences to and from  the
       token  strings stored in	configuration files and	produces text for dis-
       playing 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  se-
       quences.

   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 de-
       vices,  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 de-
       vices in	different ways.

   Player positions
       MAME uses a concept called player positions to help  manage  input  as-
       signments.  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 key-
	 board/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 de-
       fault.cfg.  These assignments are used for all systems unless  the  de-
       vice/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 managers current player po-
	 sition.

        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 cur-
	 rent 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 cur-
	 rent 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.

   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 fields assigned
	 input sequence	(via the input manager).

        If the	value is zero, the fields default value	is set.

        If the	value is non-zero, the binary complement of the	fields 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 fields assigned
	 axis input sequence (via the input manager).

        If the	current	value changed since the	last update and	the input  de-
	 vice  item  that produced the current value was an absolute axis, the
	 fields	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  pro-
	 duced	the  current  value  was a relative axis, the current value is
	 added to the fields value, scaled by the fields sensitivity setting.

        The I/O port manager reads the	current	value for the fields  assigned
	 increment  input  sequence  (via the input manager); if this value is
	 non-zero, the fields 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 fields  assigned
	 decrement  input  sequence  (via the input manager); if this value is
	 non-zero, the fields increment/decrement speed	setting	value is  sub-
	 tracted 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 fields value changed in
	 response to user input, the fields auto-centring speed	setting	 value
	 is  added  to	or subtracted from its value to	move it	toward its de-
	 fault value.

       Note that the sensitivity setting value for absolute analog fields  af-
       fects  the  response  to	 relative  axis	 input device items and	incre-
       ment/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 fields  assigned
	 axis input sequence (via the input manager).

        If  the current value is non-zero and the input device	item that pro-
	 duced the current value was an	absolute axis, the  current  value  is
	 added	to the fields value, scaled by the fields sensitivity setting,
	 and no	further	processing is performed.

        If the	current	value is non-zero and the input	device item that  pro-
	 duced	the  current  value  was a relative axis, the current value is
	 added to the fields value, scaled by the fields sensitivity setting.

        The I/O port manager reads the	current	value for the fields  assigned
	 increment  input  sequence  (via the input manager); if this value is
	 non-zero, the fields 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 fields  assigned
	 decrement  input  sequence  (via the input manager); if this value is
	 non-zero, the fields increment/decrement speed	setting	value is  sub-
	 tracted from its value, scaled	by its sensitivity setting.

       Note  that the sensitivity setting value	for relative analog fields af-
       fects the response to all user input.

   The device_memory_interface
        1. Capabilities

        2. Setup

        3. Associating	maps to	spaces

        4. Accessing the spaces

        5. MMU	support	for disassembler

   1. Capabilities
       The device memory interface provides devices  with  the	capability  of
       creating	 address spaces, to which address maps can be associated.  Its
       used for	any device that	provides a  (logical)  address/data  bus  that
       other devices can be connected to.  Thats mainly, but not solely, CPUs.

       The  interface  allows for an unlimited set of address spaces, numbered
       with small, non-negative	values.	 The IDs index vectors,	so they	should
       stay small to keep the lookup fast.  Spaces numbered 0-3	 have  associ-
       ated constant name:
				+----+------------+
				| ID | Name	  |
				+----+------------+
				| 0  | AS_PROGRAM |
				+----+------------+
				| 1  | AS_DATA	  |
				+----+------------+
				| 2  | AS_IO	  |
				+----+------------+
				| 3  | AS_OPCODES |
				+----+------------+

       Spaces 0	and 3, i.e. AS_PROGRAM and AS_OPCODES, are special for the de-
       bugger  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	disas-
       sembler.	  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  in-
       structions separately from data.

   2. Setup
	  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 com-
       prising of a space number and an	 associated  address_space_config  de-
       scribing	its configuration.  Some examples to look up when needed:

        Standard two-space vector: v60_device

        Conditional AS_OPCODES: z80_device

        Inherit configuration and add a space:	hd647180x_device

        Inherit configuration and modify a space: tmpz84c011_device

	  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_OP-
       CODES in	certain	CPU cores.

   3. Associating maps to spaces
       Associating  maps to spaces is done at the machine configuration	level,
       after the device	is instantiated.

	  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	 asso-
       ciated  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.

       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).

       As  an example, heres the address map configuration for the main	CPU in
       the Hana	Yayoi and Hana Fubuki machines,	with all distractions removed:

	  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(int index = 0) const;

       Returns the specified address space post-initialization.	 The specified
       address space must exist.

	  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, address_space *&target_space);

       Does a logical to physical address  translation	through	 the  device's
       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.

   The device_rom_interface
        1. Capabilities

        2. Setup

        3. ROM	access

        4. ROM	banking

        5. Caveats

   1. Capabilities
       This interface is designed for devices that expect to have a  ROM  con-
       nected  to  them	 on  a	dedicated  bus.	 Its mostly designed for sound
       chips.  Other devices types may be interested but other	considerations
       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<AddrWidth, DataWidth=0, AddrShift=0, Endian=ENDIANNESS_LITTLE>

       The interface is	a template that	takes the address width	of  the	 dedi-
       cated  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.

	  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.

	  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 devices tag.

	  ROM_REGION(length, tag, flags)

       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 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 override_address_width(u8 width);

       This method allows the address bus width	to be overridden. It  must  be
       called from within the device before config_complete time.

	  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
	  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.

   4. ROM banking
       If the ROM region or the	memory block in	set_rom	is larger than the ad-
       dress bus can access, banking is	automatically set up.

	  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_inter-
       face.  If the device wants to actually use the memory interface for it-
       self,  remember	that  space zero (0, or	AS_PROGRAM) is used by the ROM
       interface, and dont 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.

   The device_disasm_interface and the disassemblers
   1. Capabilities
       The  disassemblers  are	classes	 that  provide	disassembly and	opcode
       meta-information	for the	cpu cores and unidasm.	The  device_disasm_in-
       terface connects	a cpu core with	its disassembler.

   2. The disassemblers
   2.1.	Definition
       A disassembler is a class that derives from util::disasm_interface.  It
       then has	two required methods to	implement, opcode_alignment and	disas-
       semble,	and  6	optional,  interface_flags, page_address_bits, pc_lin-
       ear_to_real, pc_real_to_linear, and one with  four  possible  variants,
       decrypt8/16/32/64.

   2.2.	opcode_alignment
       u32 opcode_alignment() const

       Returns	the required alignment of opcodes by the cpu, in PC-units.  In
       other words, the	required alignment for the PC  register	 of  the  cpu.
       Tends  to  be  1	 (almost  everything), 2 (68000...), 4 (mips, ppc...),
       which an	exceptional 8 (tms 32082 parallel processor) and 16 (tms32010,
       instructions are	16-bits	aligned	and the	PC targets bits).  It must  be
       a power-of-two or things	will break.

       Note  that processors like the tms32031 which have 32-bits instructions
       but where the PC	targets	32-bits	values have an alignment of 1.

   2.3.	disassemble
       offs_t disassemble(std::ostream &stream,	offs_t pc, const data_buffer &opcodes, const data_buffer &params)

       This is the method where	the real work is done.	This method must  dis-
       assemble	 the instruction at address pc and write the result to stream.
       The  values  to	decode	are  retrieved	from  the  opcode  buffer.   A
       data_buffer object offers four accessor methods:
       u8  util::disasm_interface::data_buffer::r8 (offs_t pc) const
       u16 util::disasm_interface::data_buffer::r16(offs_t pc) const
       u32 util::disasm_interface::data_buffer::r32(offs_t pc) const
       u64 util::disasm_interface::data_buffer::r64(offs_t pc) const

       They read the data at a given address and take endianness and nonlinear
       PCs  for	 larger-than-bus-width	accesses.   The	 debugger variant also
       caches the read data in one block, so for that reason  one  should  not
       read data too far from the base pc (e.g.	stay within 16K	or so, careful
       when trying to follow indirect accesses).

       A  number  of  CPUs have	an external signal that	splits fetches into an
       opcode part and a parameter part.  This is for instance the  M1	signal
       of  the	z80 or the SYNC	signal of the 6502.  Some systems present dif-
       ferent values to	the cpu	depending on whether that  signal  is  active,
       usually	for protection purposes.  On these cpus	the opcode part	should
       be read from the	opcode buffer, and the parameter part from the	params
       buffer.	They will or will not be the same buffer depending on the sys-
       tem itself.

       The method returns the size of the instruction in PC units, with	a max-
       imum  of	65535.	In addition, if	possible, the disassembler should give
       some meta-information about the opcode by OR-ing	in into	the result:

        STEP_OVER for subroutine calls	or auto-decrementing loops.  If	 there
	 is  some  delay slots,	also OR	with step_over_extra(n)	where n	is the
	 number	of instruction slots.

        STEP_OUT for the return-from-subroutine instructions

       In addition, to indicated that these flags are supported, OR the	result
       with SUPPORTED.	An annoying number of disassemblers  lies  about  that
       support	(e.g.  they do a or with SUPPORTED without even	generating the
       STEP_OVER or STEP_OUT information).  Don't do that, it breaks the  step
       over/step out functionality of the debugger.

   2.4.	interface_flags
       u32 interface_flags() const

       That  optional method indicates specifics of the	disassembler.  Default
       of zero is correct most of the time.  Possible flags, which need	to  be
       OR-ed together, are:

        NONLINEAR_PC: stepping	to the next opcode or the next byte of the op-
	 code is not adding one	to pc.	Used for old LFSR-based	PCs.

        PAGED:	PC wraps at a page boundary

        PAGED2LEVEL:  not  only  PC  wraps at some kind of page boundary, but
	 there are two levels of paging

        INTERNAL_DECRYPTION: there is some decryption tucked between  reading
	 from AS_PROGRAM and the actual	disassembler

        SPLIT_DECRYPTION:  there  is  some  decryption	tucked between reading
	 from AS_PROGRAM and the actual	disassembler, and that	decryption  is
	 different for opcodes and parameters

       Note  that  in  practice	 non-linear  pc	 systems  are also paged, that
       PAGED2LEVEL implies PAGED, and that  SPLIT_DECRYPTION  implies  DECRYP-
       TION.

   2.5.	pc_linear_to_real and pc_real_to_linear
       offs_t pc_linear_to_real(offs_t pc) const
       offs_t pc_real_to_linear(offs_t pc) const

       These  methods  should  be present only when NONLINEAR_PC is set	in the
       interface flags.	 They must convert pc to and from a value to a	linear
       domain  where  the  instruction	parameters  and	 next  instruction are
       reached by incrementing the value.  pc_real_to_linear converts to  that
       domain, pc_linear_to_real converts back from that domain.

   2.6.	page_address_bits
       u32 page_address_bits() const

       Present	on  when  PAGED	or PAGED2LEVEL is set, gives the number	of ad-
       dress bits in the lowest	page.

   2.7.	page2_address_bits
       u32 page2_address_bits()	const

       Present on when PAGED2LEVEL is set, gives the number of address bits in
       the upper page.

   2.8.	decryptnn
       u8  decrypt8 (u8	 value,	offs_t pc, bool	opcode)	const
       u16 decrypt16(u16 value,	offs_t pc, bool	opcode)	const
       u32 decrypt32(u32 value,	offs_t pc, bool	opcode)	const
       u64 decrypt64(u64 value,	offs_t pc, bool	opcode)	const

       One of these must be defined when INTERNAL_DECRYPTION or	 SPLIT_DECRYP-
       TION  is	set.  The chosen one is	the one	which takes what opcode_align-
       ment represents in bytes.

       That method decrypts a given value read from address pc	(from  AS_PRO-
       GRAM)  and  gives  the result which will	be passed to the disassembler.
       In the split decryption case, opcode indicates whether we're in the op-
       code (true) or parameter	(false)	part of	the instruction.

   3. Disassembler interface, device_disasm_interface
   3.1.	Definition
       A CPU core derives  from	 device_disasm_interface  through  cpu_device.
       One method has to be implemented, create_disassembler.

   3.2.	create_disassembler
       util::disasm_interface *create_disassembler()

       That method must	return a pointer to a newly allocated disassembler ob-
       ject.  The caller takes ownership and handles the lifetime.

       This  method  will be called at most one	in the lifetime	of the cpu ob-
       ject.

   4. Disassembler configuration and communication
       Some disassemblers need to be configured.   Configuration  can  be  un-
       changing	 (static)  for the duration of the run (cpu model type for in-
       stance) or dynamic (state of a flag or a	user preference).  Static con-
       figuration can be done through either (a) parameter(s) to the disassem-
       bler constructor, or through deriving a main  disassembler  class.   If
       the information is short	and its	semantics obvious (like	a 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  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 implement
       the methods.  Unidasm will have to derive a small class from the	config
       class to	give the information.

   5. Missing stuff
       There currently is no way for the debugger GUI to add per-core configu-
       ration.	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 current
       list ("Configuration missing" comments).

   Emulated system memory and address spaces management
        1. Overview

        2. Basic concepts

	  2.1 Address spaces

	  2.2 Address maps

	  2.3 Shares, banks and regions

	  2.4 Views

        3. Memory objects

	  3.1 Shares -	memory_share

	  3.2 Banks - memory_bank

	  3.3 Regions - memory_region

	  3.4 Views - memory_view

	  3.5 Bus contention handling

        4. Address maps API

	  4.1 General API structure

	  4.2 Global configurations

	    4.2.1 Global masking

	    4.2.2 Returned value on unmapped/nop-ed read

	  4.3 Handler setting

	    4.3.1 Method on the current device

	    4.3.2 Method on a different device

	    4.3.3 Lambda function

	    4.3.4 Direct memory access

	    4.3.5 Bank	access

	    4.3.6 Port	access

	    4.3.7 Dropped access

	    4.3.8 Unmapped access

	    4.3.9 Subdevice mapping

	  4.4 Range qualifiers

	    4.4.1 Mirroring

	    4.4.2 Masking

	    4.4.3 Selection

	    4.4.4 Sub-unit selection

	    4.4.5 Chip	select handling	on sub-unit

	    4.4.6 User	flags

	  4.5 Contention

	  4.6 View setup

        5. Address space dynamic mapping API

	  5.1 General API structure

	  5.2 Handler mapping

	  5.3 Direct memory range mapping

	  5.4 Bank mapping

	  5.5 Port mapping

	  5.6 Dropped accesses

	  5.7 Unmapped	accesses

	  5.8 Device map installation

	  5.9 Contention

	  5.10	View installation

	  5.11	Taps

   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 de-
       vice_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 requir-
       ing 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 de-
       code.

   2.2 Address maps
       An address map is a static description of the decode expected when  us-
       ing  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  di-
       rectly accessed from devices.

       Memory  banks  are zones	that indirect memory access, giving the	possi-
       bility 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 in-
       ternal  indirection through a map ensures that any integer value	can be
       used.

   3. Memory objects
   3.1 Shares -	memory_share
	  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 ac-
       cess to its contents from the driver class.

	  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  re-
       trieved	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.

	  memory_share_creator<uNN> m_share;

	  [device constructor] m_share(*this, "name", size, endianness),

       A  memory  share	 can  be  created  if  it doesnt 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 in-
       formation.  The desired size is specified in bytes.

	  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
	  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.

	  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.

	  memory_bank_creator m_bank;

	  [device constructor] m_bank(*this, "name"),

       A memory	bank can be created if it doesnt exist in a memory map through
       that creator class.  If it already exists it is just retrieved.

	  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
	  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 dont	really
       have an intrinsic width (base() returns an u8 * always),	which is  his-
       torical	and pretty much	unfixable at this point.  The as_* methods al-
       low for accessing them at a given width.

	  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.

	  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
	  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 possibil-
       ities, or even disable it entirely to see what was there	before.	 It is
       created as an object of the device.

	  memory_view m_view;

	  [device constructor] m_view(*this, "name"),

       It is then setup	through	the address map	API or dynamically.   At  run-
       time,  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 Bus contention handling
       Some specific CPUs have been upgraded to	be interruptible which	allows
       to  add bus contention and wait states capabitilites.  Being interrupt-
       ible 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 instruc-
       tion 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 answer-
       ing 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 eventu-
       ally  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  re-
       quire  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  re-
       moves 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  hap-
       pen when	a specific range is accessed.

       The general syntax for entries uses method chaining:

	  map(start, end).handler(...).handler_qualifier(...).range_qualifier().contention();

       The  values  start and end define the range, the	handler() block	deter-
       mines how the access is handled,	the handler_qualifier()	 block	speci-
       fies  some aspects of the handler (memory sharing for instance) and the
       range_qualifier() block refines the range (mirroring, masking, lane se-
       lection,	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
	  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
	  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
	  (...).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.  Its 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
	  (...).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 (usu-
       ally required_device or optional_device)	or its tag, to read, write  or
       both for	the current entry.

   4.3.3 Lambda	function
	  (...).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
	  (...).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 loca-
       tion of this memory zone.  There	are two	cases when no qualifier	is ac-
       ceptable:

        ram()	gives  an anonymous RAM	zone not accessible outside of the ad-
	 dress 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.

	  (...).rom().region("name", offset)

       The region qualifier causes a read-only zone point to the contents of a
       given region at a given offset.

	  (...).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 Endi-
       anness must match.

   4.3.5 Bank access
	  (...).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
	  (...).portr("name")
	  (...).portw("name")
	  (...).portrw("name")

       Sets the	range to point at an I/O port.

   4.3.7 Dropped access
	  (...).nopr()
	  (...).nopw()
	  (...).noprw()

       Sets the	range to drop the access without logging.  When	 reading,  the
       unmap value is returned.

   4.3.8 Unmapped access
	  (...).unmapr()
	  (...).unmapw()
	  (...).unmaprw()

       Sets  the range to drop the access with logging.	 When reading, the un-
       map value is returned.

   4.3.9 Subdevice mapping
	  (...).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
	  (...).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
	  (...).mask(mask)

       Only valid with handlers, the address will be masked with the mask  be-
       fore being passed to the	handler.

   4.4.3 Selection
	  (...).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
	  (...).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
	  (...).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
	  (...).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
	  (...).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
	  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	quali-
       fier 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 addi-
       tional 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  set-
       ting 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 mem-
       ory_view	and an indexed entry (e.g. a variant to	setup) is of type mem-
       ory_view::memory_view_entry &.

       A  view	can  be	installed in another view, but dont 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.  Theyre 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, han-
       dler qualifier and range	qualifier, put them all	together as method pa-
       rameters.  To make things a little more readable, lots of them are  op-
       tional.

   5.2 Handler mapping
	  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.

	  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
	  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 allo-
       cate the	memory.

   5.4 Bank mapping
	  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  ad-
       dress space.

   5.5 Port mapping
	  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
	  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
	  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
	  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
	  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	 para-
       meter is	optional.

   5.10	View installation
	  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
	  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 al-
       low  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 pre-
       served, one should install a change notifier on the address space,  and
       remove +	reinstall the taps when	notified.

   CPU devices
        1. Overview

        2. DRC

        3. Interruptibility

	  3.1 Definition

	  3.2 Implementation requirements

	  3.3 Example implementation with generators

	  3.4 Bus contention cpu_device interface

	  3.5 Interaction with	DRC

   1. Overview
       CPU devices derivatives are used, unsurprisingly, to implement the emu-
       lation  of CPUs,	MCUs and SOCs.	A CPU device is	first a	combination of
       device_execute_interface, device_memory_interface,  device_state_inter-
       face  and  device_disasm_interface.  Refer to the associated documenta-
       tions 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_inter-
       ruptible	on a memory_access_specific or a memory_access_cache.  The ac-
       cess 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 ac-
       cess 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 ac-
       cess 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	clear-
       ing it use access_to_be_redone_noclear().

       The  core  needs	to do enough bookkeeping to eventually restart the in-
       struction execution just	before the access or just after	the test,  de-
       pending 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 instruc-
       tion 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):

	  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 fi-
       nal m_inst_substate clearing removed.

	  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:

	  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	inter-
       pretation  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.

	  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.	Other-
       wise  enough cycles are eaten to	reach the access time and false	is re-
       turned to tell to do the	access.

	  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 charac-
       terize the source of the	delay, so that the delay is not	applied	multi-
       ple times.  Similarly to	the previous method cycles are eaten and  true
       is returned to abort the	access,	false to execute it.

	  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.

	  void cpu_device::defer_access() noexcept;

       The method defer_access tells the cpu that we need to wait for  an  ex-
       ternal  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 syn-
       chronisation 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.

	  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 live-
       lock, 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 ac-
       cess.  It's theorically possible	but definitely non-trivial.

   The new floppy subsystem
   1. Introduction
       The new floppy subsystem	aims at	emulating the  behaviour  of  floppies
       and floppy controllers at a level low enough that protections work as a
       matter  of  course.  It reaches its goal	by following the real hardware
       configuration:

        a floppy image	class keeps in memory the magnetic state of the	floppy
	 surface and its physical characteristics

        an image handler class	talks with the floppy image class to  simulate
	 the  floppy  drive,  providing	 all  the signals you have on a	floppy
	 drive connector

        floppy	controller devices talk	with the image handler and provide the
	 register interfaces to	the host we all	know and love

        format	handling classes are given the task of statelessly  converting
	 to  and  from an on-disk image	format to the in-memory	magnetic state
	 format	the floppy image class manages

   2. Floppy storage 101
   2.1.	Floppy disk
       A floppy	disk is	a disc that stores magnetic orientations on their sur-
       face disposed in	a series on concentric circles called tracks or	cylin-
       ders [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 ei-
       ther be tangentially to the track, i.e. in the direction	of or opposite
       to the rotation,	or in the case of perpendicular	recording  the	direc-
       tion is perpendicular to	the disc surface (hence	the name). Perpendicu-
       lar recording allows for	closer orientation changes by writing the mag-
       netic information more deeply, but arrived late in the technology life-
       time.   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	demag-
       netized (no orientation)	or damaged (no orientation and can't be	 writ-
       ten 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 po-
       sitioned	 differently to	be recognized as the track start, and the oth-
       ers are at fixed	positions relative to the origin one.

   2.2.	Floppy drive
       A floppy	drive is what reads and	writes a floppy	disk.  It includes  an
       assembly	 capable  of rotating the disk at a fixed speed	and one	or two
       magnetic	heads tied to a	positioning motor to access the	tracks.

       The head	width and positioning motor step size decides how many	tracks
       are  written  on	the floppy.  Total number of tracks goes from 32 to 84
       depending on the	floppy and drive, with the track 0 being the most  ex-
       terior (longer) one of the concentric circles, and the highest numbered
       the  smallest  interior circle.	As a result the	tracks with the	lowest
       numbers have the	lowest physical	magnetic  orientation  density,	 hence
       the  best  reliability.	 Which	is  why	important and/or often changed
       structures like the boot	block or the fat allocation table are at track
       0.  That	is also	where the terminology "stepping	in"  to	 increase  the
       track  number and "stepping out"	to decrease it comes from.  The	number
       of tracks available is the second part of what is  usually  behind  the
       term "density".

       A  sensor detects when the head is on track 0 and the controller	is not
       supposed	to try to go past it.  In addition physical blocks prevent the
       head from going out of the correct track	range.	 Some  systems	(Apple
       II, some	C64) do	not take the track 0 sensor into account and just wham
       the  head against the track 0 physical block, giving a well-known crash
       noise and eventually damaging the head alignment.

       Also, some systems (Apple II and	C64 again) have	direct access  to  the
       phases  of  the head positioning	motor, allowing	to trick the head into
       going between tracks, in	middle or even quarter	positions.   That  was
       not  usable  to write more tracks, since	the head width did not change,
       but since reliable reading was only possible with the correct  position
       it was used for some copy protection systems.

       The  disk  rotates  at a	fixed speed for	a given	track.	The most usual
       speed is	300 rpm	for every track, with 360 rpm found for	HD 5.25" flop-
       pies and	most 8"	ones, and a number of different	values like 90 rpm for
       the earlier floppies or 150 rpm for an HD floppy	in an Amiga. Having  a
       fixed  rotational  speed	 for the whole disk is called Constant Angular
       Velocity	(CAV, almost everybody)	or  Zoned  Constant  Angular  Velocity
       (ZCAV,  C64) depending on whether the read/write	bitrate	is constant or
       track-dependant.	 Some systems (Apple  II,  Mac)	 vary  the  rotational
       speed  depending	on the track (something	like 394 rpm up	to 590 rpm) to
       end up with a Constant Linear Velocity (CLV).  The idea behind ZCAV/CLV
       is to get more bits out of the media by keeping the minimal spacing be-
       tween magnetic orientation transitions close to the  best  the  support
       can do.	It seems that the complexity was not deemed worth it since al-
       most no system does it.

       Finally,	 after	the disc rotates and the head is over the proper track
       reading happens.	 The reading is	done through an	inductive head,	 which
       gives  it  the  interesting  characteristic of not reading the magnetic
       orientation directly but	instead	of being sensitive to orientation  in-
       versions, called	flux transitions.  This	detection is weak and somewhat
       uncalibrated, so	an amplifier with Automatic Gain Calibration (AGC) and
       a  peak	detector are put behind	the head to deliver clean pulses.  The
       AGC slowly increases the	amplification level until a signal  goes  over
       the  threshold,	then  modulates	 its  gain so that said	signal is at a
       fixed position over the threshold.   Afterwards	the  increase  happens
       again.	This  makes the	amplifier calibrate itself to the signals read
       from the	floppy as long as flux transitions happen often	 enough.   Too
       long  and  the  amplification level will	reach a	point where the	random
       noise the head picks from the environment is amplified over the thresh-
       old, creating a pulse where none	should be. Too long in our  case  hap-
       pens to be around 16-20us with no transitions. That means a long	enough
       zone with a fixed magnetic orientation or no orientation	at all (demag-
       netized	or  damaged)  is going to be read as a series of random	pulses
       after a brief delay.  This is used by protections and is	known as "weak
       bits", which read differently each time they're accessed.

       A second	level of filtering happens after the peak detector.  When  two
       transitions  are	 a little close	(but still over	the media threshold) a
       bouncing	effect happens between them giving two very  close  pulses  in
       the  middle in addition to the two normal pulses.  The floppy drive de-
       tects when pulses are too close and filter them out, leaving the	normal
       ones.  As a result, if one writes a train of high-frequency  pulses  to
       the  floppy they	will be	read back as a train of	too close pulses (weak
       because they're over the	media tolerance, but picked up by the AGC any-
       way, only somewhat unreliably) they will	be all filtered	out, giving  a
       large  amount  of time without any pulse	in the output signal.  This is
       used by some protections	 since	it's  not  writable  with  a  normally
       clocked controller.

       Writing	is  symmetrical,  with	a series of pulses sent	which make the
       write head invert the magnetic field orientation	each time a  pulse  is
       received.

       So, in conclusion, the floppy drive provides inputs to control disk ro-
       tation  and  head position (and choice when double-sided), and the data
       goes both way as	a train	of pulses  representing	 magnetic  orientation
       inversions.   The  absolute  value  of  the orientation itself is never
       known.

   2.3.	Floppy controller
       The task	of the floppy controller is to turn the	 signals  to/from  the
       floppy drive into something the main CPU	can digest.  The level of sup-
       port actually done by the controller is extremely variable from one de-
       vice  to	 the  other,  from pretty much nothing (Apple II, C64) through
       minimal (Amiga) to complete (Western  Digital  chips,  uPD765  family).
       Usual  functions	 include drive selection, motor	control, track seeking
       and of course reading and writing data.	Of these  only	the  last  two
       need to be described, the rest is obvious.

       The  data is structured at two levels: how individual bits (or nibbles,
       or bytes) are encoded on	the surface, and how these are grouped in  in-
       dividually-addressable  sectors.	 Two standards exist for these,	called
       FM and MFM, and in addition a number of systems	use  their  home-grown
       variants.   Moreover,  some  systems  such  as the Amiga	use a standard
       bit-level encoding (MFM)	but a homegrown	sector-level organisation.

   2.3.1. Bit-level encodings
   2.3.1.1. Cell organization
       All floppy controllers, even the	wonkiest like the Apple	II one,	 start
       by dividing the track in	equally-sized cells.  They're angular sections
       in the middle of	which a	magnetic orientation inversion may be present.
       From  a	hardware  point	of view	the cells are seen as durations, which
       combined	with the floppy	rotation give the section.  For	 instance  the
       standard	 MFM  cell  size  for a	3" double-density floppy is 2us, which
       combined	with the also standard 300 rpm rotational speed	gives an angu-
       lar size	of 1/100000th of a turn.  Another way of  saying  it  is  that
       there are 100K cells in a 3" DD track.

       In  every  cell	there may or may not be	a magnetic orientation transi-
       tion, e.g. a pulse coming from (reading)	 or  going  to	(writing)  the
       floppy  drive.  A cell with a pulse is traditionally noted '1', and one
       without '0'.  Two constraints apply to the cell contents	though.	First,
       pulses must not be too close together or	they'll	blur each-other	and/or
       be filtered out.	 The limit is slightly better than 1/50000th of	a turn
       for single and double density floppies, half that for HD	 floppys,  and
       half  that again	for ED floppies	with perpendicular recording.  Second,
       they must not be	too away from each other or either the AGC is going to
       get wonky and introduce phantom pulses or the controller	 is  going  to
       lose sync and get a wrong timing	on the cells on	reading.  Conservative
       rule of thumb is	not to have more than three consecutive	'0' cells.

       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  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
       The very	first encoding method developed	for floppies  is  called  Fre-
       quency  Modulation,  or	FM.  The cell size is set at slightly over the
       physical	limit, e.g. 4us.  That means it	is possible to	reliably  have
       consecutive '1' cells.  Each bit	is encoded on two cells:

        the first cell, called	the clock bit, is '1'

        the second cell, called data bit, is the bit

       Since  every  other cell	at least is '1'	there is no risk of going over
       three zeroes.

       The name	Frequency Modulation simply derives from the fact that a 0  is
       encoded	with one period	of a 125Khz pulse train	while a	1 is two peri-
       ods of a	250Khz pulse train.

   2.3.1.3. MFM	encoding
       The FM encoding has been	superseded by the Modified  Frequency  Modula-
       tion  encoding,	which  can cram	exactly	twice as much data on the same
       surface,	hence its other	name of	"double	density".  The	cell  size  is
       set  at	slightly  over	half the physical limit, e.g. 2us usually. The
       constraint means	that two '1' cells must	be separated by	at  least  one
       '0' cell.  Each bit is once again encoded on two	cells:

        the first cell, called	the clock bit, is '1' if both the previous and
	 current data bits are 0, '0' otherwise

        the second cell, called data bit, is the bit

       The minimum space rule is respected since a '1' clock bit is by defini-
       tion  surrounded	by two '0' data	bits, and a '1'	data bit is surrounded
       by two '0' clock	bits.  The longest '0'-cell string  possible  is  when
       encoding	 101  which  gives x10001, respecting the maximum of three ze-
       roes.

   2.3.1.4. GCR	encodings
       Group Coded Recording, or GCR, encodings	are a class of encodings where
       strings of bits at least	nibble-size are	 encoded  into	a  given  cell
       stream  given  by a table.  It has been used in particular by the Apple
       II, the Mac and the C64,	and each system	has its	own table, or tables.

   2.3.1.5. Other encodings
       Other encodings exist, like M2FM, but they're very rare and system-spe-
       cific.

   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 instantaneous	speed very variable in general.	 So to
       extract the cell	values stream, the controller  must  dynamically  syn-
       chronize	with the pulse train that the floppy head picks	up.  The prin-
       ciple 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 ab-
       sence 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	encod-
       ing.  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
       Floppies	have been designed for read/write random access	to  reasonably
       sized blocks of data.  Track selection allows for a first level of ran-
       dom  access  and	sizing,	but the	~6K of a double	density	track would be
       too big a block to handle.  256/512 bytes are considered	a more	appro-
       priate  value.  To that end data	on a track is organized	as a series of
       (sector header, sector data) pairs where	the  sector  header  indicates
       important  information  like the	sector number and size,	and the	sector
       data contains the data.	Sectors	have to	be broken in two parts because
       while reading is	easy, read the header then read	the data if  you  want
       it,  writing requires reading the header	to find	the correct place then
       once that is done switching on the writing head for the data.  Starting
       writing is not instantaneous and	will not  be  perfectly	 phase-aligned
       with  the read header, so space for synchronization is required between
       header and data.

       In addition somewhere in	the sector header and in the sector  data  are
       pretty much always added	some kind of checksum allowing to know whether
       the data	was damaged or not.

       FM and MFM have (not always used) standard sector layout	methods.

   2.3.2.1. FM sector layout
       The standard "PC" track/sector layout for FM is as such:

        A number of FM-encoded	0xff (usually 40)

        6 FM-encoded 0x00 (giving a steady 125KHz pulse train)

        The 16-cell stream 1111011101111010 (f77a, clock 0xd7,	data 0xfc)

        A number of FM-encoded	0xff (usually 26, very variable)

       Then for	each sector: - 6 FM-encoded 0x00 (giving a steady 125KHz pulse
       train)

        The 16-cell stream 1111010101111110 (f57e, clock 0xc7,	data 0xfe)

        Sector	header,	e.g. FM	encoded	track, head, sector, size code and two
	 bytes of crc

        11 FM-encoded 0xff

        6 FM-encoded 0x00 (giving a steady 125KHz pulse train)

        The 16-cell stream 1111010101101111 (f56f, clock 0xc7,	data 0xfb)

        FM-encoded sector data	followed by two	bytes of crc

        A number of FM-encoded	0xff (usually 48, very variable)

       The track is finished with a stream of '1' cells.

       The  125KHz  pulse  trains  are used to lock the	PLL to the signal cor-
       rectly.	The specific 16-cells streams  allow  to  distinguish  between
       clock and data bits by providing	a pattern that is not supposed to hap-
       pen  in	normal	FM-encoded  data.   In the sector header track numbers
       start at	0, heads are 0/1 depending on the size,	sector numbers usually
       start at	1 and size code	is 0 for 128 bytes, 1 for 256, 2 for 512, etc.

       The CRC is a cyclic redundancy check of the data	bits starting with the
       mark just after the pulse train using polynom 0x11021.

       The Western Digital-based controllers usually get rid of	everything but
       some 0xff before	the first sector and allow a better use	of space as  a
       result.

   2.3.2.2. MFM	sector layout
       The standard "PC" track/sector layout for MFM is	as such:

        A number of MFM-encoded 0x4e (usually 80)

        12 FM-encoded 0x00 (giving a steady 250KHz pulse train)

        3  times  the 16-cell stream 0101001000100100 (5224, clock 0x14, data
	 0xc2)

        The MFM-encoded value 0xfc

        A number of MFM-encoded 0x4e (usually 50, very	variable)

       Then for	each sector:

        12 FM-encoded 0x00 (giving a steady 250KHz pulse train)

        3 times the 16-cell stream 0100010010001001 (4489, clock  0x0a,  data
	 0xa1)

        Sector	 header, e.g. MFM-encoded 0xfe,	track, head, sector, size code
	 and two bytes of crc

        22 MFM-encoded	0x4e

        12 MFM-encoded	0x00 (giving a steady 250KHz pulse train)

        3 times the 16-cell stream 0100010010001001 (4489, clock  0x0a,  data
	 0xa1)

        MFM-encoded 0xfb, sector data followed	by two bytes of	crc

        A number of MFM-encoded 0x4e (usually 84, very	variable)

       The track is finished with a stream of MFM-encoded 0x4e.

       The  250KHz  pulse  trains  are used to lock the	PLL to the signal cor-
       rectly.	The cell pattern 4489 does not appear  in  normal  MFM-encoded
       data and	is used	for clock/data separation.

       As  for	FM,  the  Western Digital-based	controllers usually get	rid of
       everything but some 0x4e	before the first sector	and allow a better use
       of space	as a result.

   2.3.2.3. Formatting and write splices
       To be usable, a floppy must have	the sector headers and default	sector
       data  written  on  every	 track before using it.	 The controller	starts
       writing at a given place, often the index pulse	but  on	 some  systems
       whenever	the command is sent, and writes	until a	complete turn is done.
       That's  called  formatting  the floppy.	At the point where the writing
       stops there is a	synchronization	loss since there is no chance the cell
       stream clock warps around  perfectly.   This  brutal  phase  change  is
       called  a  write	splice,	specifically the track write splice. It	is the
       point where writing should start	if one wants to	raw copy the track  to
       a new floppy.

       Similarly two write splices are created when a sector is	written	at the
       start  and  end of the data block part.	They're	not supposed to	happen
       on a mastered disk though, even if there	are some rare exceptions.

   3. The new implementation
   3.1.	Floppy disk representation
       The floppy disk contents	are represented	by the class floppy_image.  It
       contains	information of the media type and a representation of the mag-
       netic state of the surface.

       The media type is divided in two	parts.	The first half	indicates  the
       physical	 form  factor,	i.e.  all  medias with that form factor	can be
       physically inserted in a	reader that handles it.	 The second half indi-
       cates the variants which	are usually detectable by the reader, such  as
       density and number of sides.

       Track  data consists of a series	of 32-bits lsb-first values represent-
       ing magnetic cells.  Bits 0-27 indicate the absolute  position  of  the
       start  of  the  cell (not the size), and	bits 28-31 the type.  Type can
       be:

        0, MG_A -> Magnetic orientation A

        1, MG_B -> Magnetic orientation B

        2, MG_N -> Non-magnetized zone	(neutral)

        3, MG_D -> Damaged zone, reads	as neutral but cannot  be  changed  by
	 writing

       The position is in angular units	of 1/200,000,000th of a	turn.  It cor-
       responds	to one nanosecond when the drive rotates at 300	rpm.

       The last	cell implicit end position is of course	200,000,000.

       Unformatted tracks are encoded as zero-size.

       The  "track splice" information indicates where to start	writing	if you
       try to rewrite a	physical disk with the data.  Some  preservation  for-
       mats  encode  that  information,	 it  is	guessed	for others.  The write
       track function of fdcs should set it.  The representation is the	 angu-
       lar position relative to	the index.

   3.2.	Converting to and from the internal representation
   3.2.1. Class	and interface
       We need to be able to convert on-disk formats of	the floppy data	to and
       from the	internal representation.  This is done through classes derived
       from  floppy_image_format_t.  The interface to be implemented includes:
       - name()	gives the short	name of	the on-disk format

        description() gives a short description of the	format

        extensions() gives a comma-separated list  of	file  name  extensions
	 found for that	format

        supports_save() returns true is converting to that external format is
	 supported

        identify(file,	form factor) gives a 0-100 score for the file to be of
	 that format:

	  0 = not that	format

	  100 = certainly that	format

	  50 =	format identified from file size only

        load(file,  form factor, floppy_image)	loads an image and converts it
	 into the internal representation

        save(file, floppy_image) (if implemented) converts from the  internal
	 representation	and saves an image

       All of these methods are	supposed to be stateless.

   3.2.2. Conversion helper methods
       A  number  of  methods  are  provided to	simplify writing the converter
       classes.

   3.2.2.1. Load-oriented conversion methods
       generate_track_from_bitstream(track number,
	 head number,
	 UINT8 *cell stream,
	 int cell count,
	 floppy	image)

	  Takes	a stream of cell types (0/1), MSB-first, converts  it  to  the
	  internal  format  and	 stores	 it at the given track and head	in the
	  given	image.
       generate_track_from_levels(track	number,
	 head number,
	 UINT32	*cell levels,
	 int cell count,
	 splice	position,
	 floppy	image)

	  Takes	a variant of the internal format where each value represents a
	  cell,	the position part of the values	is the size of	the  cell  and
	  the  level  part is MG_0, MG_1 for normal cell types,	MG_N, MG_D for
	  unformatted/damaged cells, and MG_W for  Dungeon-Master  style  weak
	  bits.	  Converts it into the internal	format.	 The sizes are normal-
	  ized so that they total to a full turn.
       normalize_times(UINT32 *levels,
	 int level_count)

	  Takes	an internal-format buffer where	the position  part  represents
	  angle	 until	the  next change and turns it into a normal positional
	  stream, first	ensuring that the total	size is	normalized to  a  full
	  turn.

   3.2.2.2. Save-oriented conversion methods
       generate_bitstream_from_track(track number,
	 head number,
	 base cell size,
	 UINT8 *cell stream,
	 int &cell_stream_size,
	 floppy	image)

	  Extract a cell 0/1 stream from the internal format using a PLL setup
	  with an initial cell size set	to 'base cell size' and	a +/- 25% tol-
	  erance.
       struct desc_xs {	int track, head, size; const UINT8 *data }
       extract_sectors_from_bitstream_mfm_pc(...)
       extract_sectors_from_bitstream_fm_pc(const UINT8	*cell stream,
	 int cell_stream_size,
	 desc_xs *sectors,
	 UINT8 *sectdata,
	 int sectdata_size)

	  Extract  standard  mfm or fm sectors from a regenerated cell stream.
	  Sectors must point to	an array of 256	desc_xs.

	  An existing sector is	recognizable by	having ->data non-null.	Sector
	  data is written in sectdata up to sectdata_size bytes.
       get_geometry_mfm_pc(...)
       get_geometry_fm_pc(floppy image,
	 base cell size,
	 int &track_count,
	 int &head_count,
	 int &sector_count)

	  Extract the geometry (heads, tracks, sectors)	from a	pc-ish	floppy
	  image	by checking track 20.
       get_track_data_mfm_pc(...)
       get_track_data_fm_pc(track number,
	 head number,
	 floppy	image,
	 base cell size,
	 sector	size,
	 sector	count,
	 UINT8 *sector data)

	  Extract  what	you'd get by reading in	order 'sector size'-sized sec-
	  tors from number 1 to	sector count and  put  the  result  in	sector
	  data.

   3.3.	Floppy drive
	  The  class  floppy_image_interface simulates the floppy drive.  That
	  includes a number of control signals,	reading, and writing.  Control
	  signal changes must be synchronized, e.g. fired off a	timer  to  en-
	  sure the current time	is the same for	all devices.

   3.3.1. Control signals
	  Due  to  the way they're usually connected to	CPUs (e.g. directly on
	  an I/O port),	the control signals work with physical instead of log-
	  ical values.	Which means than in general 0 means  active,  1	 means
	  inactive.  Some  signals also	have a callback	associated called when
	  they change.

       mon_w(state) / mon_r()
	  Motor	on signal, rotates on 0.

       idx_r() / setup_index_pulse_cb(cb)
	  Index	signal,	goes 0 at start	of track for about 2ms.	  Callback  is
	  synchronized.	  Only happens when a disk is in and the motor is run-
	  ning.

       ready_r() / setup_ready_cb(cb)
	  Ready	signal,	goes to	1 when	the  disk  is  removed	or  the	 motor
	  stopped.  Goes to 0 after two	index pulses.

       wpt_r() / setup_wpt_cb(cb)
	  Write	protect	signal (1 = readonly).	Callback is unsynchronized.

       dskchg_r()
	  Disk	change	signal,	 goes to 1 when	a disk is change, goes to 0 on
	  track	change.

       dir_w(dir)
	  Selects track	stepping direction (1 =	out = decrease track number).

       stp_w(state)
	  Step signal, moves by	one track on 1->0 transition.

       trk00_r()
	  Track	0 sensor, returns 0 when on track 0.

       ss_w(ss)	/ ss_r()
	  Side select

   3.3.2. Read/write interface
       The read/write interface	is designed to work asynchronously, e.g. some-
       what independently of the current time.

       [1]  Cylinder is	a hard-drive term somewhat improperly used  for	 flop-
	    pies.   It	comes  from  the  fact that hard-drives	are similar to
	    floppies but include a series of stacked disks with	 a  read/write
	    head  on  each.   The heads	are physically linked and all point to
	    the	same circle on every disk at a given time, making the accessed
	    area look like a cylinder.	Hence the name.

   The new SCSI	subsystem
   Introduction
       The nscsi subsystem was created to allow	an implementation to be	closer
       to the physical reality,	making it easier (hopefully) to	implement  new
       controller chips	from the documentations.

   Global structure
       Parallel	 SCSI is built around a	symmetric bus to which a number	of de-
       vices are connected.  The bus is	composed of 9 control lines (for  now,
       later  SCSI  versions  may have more) and up to 32 data lines (but cur-
       rently implemented chips	only handle 8).	 All the lines are  open  col-
       lector,	which  means that either one or	multiple chip connect the line
       to ground and the line, of course, goes to ground, or  no  chip	drives
       anything	and the	line stays at Vcc.  Also, the bus uses inverted	logic,
       where ground means 1.  SCSI chips traditionally work in logical and not
       physical	 levels,  so  the nscsi	subsystem also works in	logical	levels
       and does	a logical-or of	all the	outputs	of the devices.

       Structurally, the implementation	 is  done  around  two	main  classes:
       nscsi_bus_devices  represents  the  bus,	and nscsi_device represents an
       individual device.  A device only communicate with the bus, and the bus
       takes care of transparently handling the	device discovery and  communi-
       cation.	In addition the	nscsi_full_device class	proposes a SCSI	device
       with the	SCSI protocol implemented making building generic SCSI devices
       like hard drives	or CD-ROM readers easier.

   Plugging in a SCSI bus in a driver
       The nscsi subsystem leverages the slot interfaces and the device	naming
       to allow	for a configurable yet simple bus implementation.

       First  you  need	 to create a list of acceptable	devices	to plug	on the
       bus.  This usually comprises of	cdrom,	harddisk  and  the  controller
       chip.  For instance:

       static SLOT_INTERFACE_START( next_scsi_devices )
	 SLOT_INTERFACE("cdrom", NSCSI_CDROM)
	 SLOT_INTERFACE("harddisk", NSCSI_HARDDISK)
	 SLOT_INTERFACE_INTERNAL("ncr5390", NCR5390)
       SLOT_INTERFACE_END

       The _INTERNAL interface indicates a device that is not user-selectable,
       which is	useful for the controller.

       Then  in	the machine config (or in a fragment config) you need to first
       add the bus, and	then the (potential) devices as	sub-devices of the bus
       with the	SCSI ID	as the name.  For instance you can use:

	 MCFG_NSCSI_BUS_ADD("scsibus")
	 MCFG_NSCSI_ADD("scsibus:0", next_scsi_devices,	"cdrom", 0, 0, 0, false)
	 MCFG_NSCSI_ADD("scsibus:1", next_scsi_devices,	"harddisk", 0, 0, 0, false)
	 MCFG_NSCSI_ADD("scsibus:2", next_scsi_devices,	0, 0, 0, 0, false)
	 MCFG_NSCSI_ADD("scsibus:3", next_scsi_devices,	0, 0, 0, 0, false)
	 MCFG_NSCSI_ADD("scsibus:4", next_scsi_devices,	0, 0, 0, 0, false)
	 MCFG_NSCSI_ADD("scsibus:5", next_scsi_devices,	0, 0, 0, 0, false)
	 MCFG_NSCSI_ADD("scsibus:6", next_scsi_devices,	0, 0, 0, 0, false)
	 MCFG_NSCSI_ADD("scsibus:7", next_scsi_devices,	"ncr5390", 0, &next_ncr5390_interface, 10000000, true)

       That configuration puts as default a CD-ROM reader on SCSI ID 0	and  a
       hard  drive on SCSI ID 1, and forces the	controller on ID 7.  The para-
       meters of add are:

        device	tag, comprised of bus-tag:scsi-id

        the list of acceptable	devices

        the device name as per	the list, if one is to be there	by default

        the device input config, if any (and there usually isn't one)

        the device configuration structure, usually for the controller	only

        the frequency,	usually	for the	controller only

        "false" for a user-modifiable slot, "true" for	a fixed	slot

       The full	device name, for mapping purposes, will	be bus-tag:scsi-id:de-
       vice-type, i.e. "scsibus:7:ncr5390" for our controller here.

   Creating a new SCSI device using nscsi_device
       The base	class "nscsi_device" is	to be used for	down-to-the-metal  de-
       vices,  i.e. SCSI controller chips.  The	class provides three variables
       and one method.	The first variable, scsi_bus,  is  a  pointer  to  the
       nscsi_bus_device.  The  second,	scsi_refid,  is	an opaque reference to
       pass to the bus on some operations. Finally, scsi_id gives the SCSI  ID
       as  per	the device tag.	It's written once at startup and never written
       or read afterwards, the device can do whatever it wants with the	 value
       or the variable.

       The virtual method scsi_ctrl_changed is called when watched-for control
       lines change. Which lines are watched is	defined	through	the bus.

       The  bus	 proposes  five	methods	to access the lines.  The read methods
       are ctrl_r() and	data_r().  The meaning of the control bits are defined
       in the S_* enum of nscsi_device.	The bottom three bits  (INP,  CTL  and
       MSG)  are  setup	so that	masking	with 7 (S_PHASE_MASK) gives the	tradi-
       tional numbers for the  phases,	which  are  also  available  with  the
       S_PHASE_* enum.

       Writing the data	lines is done with data_w(scsi_refid, value).

       Writing	the  control  lines  is	 done  with  ctrl_w(scsi_refid,	value,
       mask-of-lines-to-change). To change all control lines in	one  call  use
       S_ALL as	the mask.

       Of  course,  what is read is the	logical-or of all of what is driven by
       all devices.

       Finally,	      the	method	     ctrl_wait_w(scsi_id,	value,
       mask-of-wait-lines-to-change)  allows to	select which control lines are
       watched.	 The  watch  mask  is  per-device,  and	 the   device	method
       scsi_ctrl_changed is called whenever a control line in the mask changes
       due  to	an  action of another device (not itself, to avoid an annoying
       and somewhat useless recursion).

       Implementing the	controller is then just	 a  matter  of	following  the
       state  machines	descriptions, at least if they're available.  The only
       part often not described	is the arbitration/selection, which  is	 docu-
       mented  in  the	SCSI standard though.  For an initiator	(which is what
       the controller essentially always is), it goes like this:

        wait for the bus to be	idle

        assert	the data line which number is your scsi_id (1 << scsi_id)

        assert	the busy line

        wait the arbitration time

        check that the	of the active data lines the one with the highest num-
	 ber is	yours

	  if no, the arbitration was lost, stop driving anything and  restart
	   at the beginning

        assert	the select line	(at that point,	the bus	is yours)

        wait a	short while

        keep  your  data  line	asserted, assert the data line which number is
	 the SCSI ID of	the target

        wait a	short while

        assert	the atn	line if	needed,	de-assert busy

        wait for busy to be asserted or timeout

	  timeout means nobody	is answering at	that id, de-assert  everything
	   and stop

        wait a	short while for	de-skewing

        de-assert the data bus	and the	select line

        wait a	short while

       and then	you're done, you're connected with the target until the	target
       de-asserts the busy line, either	because	you asked it to	or just	to an-
       noy you.	The de-assert is called	a disconnect.

       The  ncr5390  is	 an example of how to use a two-level state machine to
       handle all the events.

   Creating a new SCSI device using nscsi_full_device
       The base	class "nscsi_full_device" is used to create HLE-d SCSI devices
       intended	for generic uses, like hard drives, CD-ROMs, perhaps scanners,
       etc.  The class provides	the SCSI protocol handling, leaving  only  the
       command handling	and (optionally) the message handling to the implemen-
       tation.

       The class currently only	support	target devices.

       The first method	to implement is	scsi_command().	 That method is	called
       when a command has fully	arrived. The command is	available in scsi_cmd-
       buf[],  and  its	length is in scsi_cmdsize (but the length is generally
       useless,	the command first byte giving it).  The	4096-bytes scsi_cmdbuf
       array is	then freely modifiable.

       In scsi_command(), the device can either	handle the command or pass  it
       up with nscsi_full_device::scsi_command().

       To handle the command, a	number of methods are available:

        get_lun(lua-set-in-command)  will  give  you  the LUN to work on (the
	 in-command one	can be overriden by a message-level one).

        bad_lun() replies to the host that the	specific LUN is	unsupported.

        scsi_data_in(buffer-id, size) sends size bytes	from buffer buffer-id

        scsi_data_out(buffer-id,  size)  receives  size  bytes	 into	buffer
	 buffer-id

        scsi_status_complete(status) ends the command with a given status.

        sense(deferred,  key)	prepares the sense buffer for a	subsequent re-
	 quest-sense command, which is useful when returning a check-condition
	 status.

       The scsi_data_* and scsi_status_complete	commands are queued, the  com-
       mand handler should call	them all without waiting.

       buffer-id identifies a buffer.  0, aka SBUF_MAIN, targets the scsi_cmd-
       buf  buffer.  Other acceptable values are 2 or more. 2+ ids are handled
       through the scsi_get_data method	for read and scsi_put_data for write.

       UINT8 device::scsi_get_data(int id, int pos) must return	 byte  pos  of
       buffer id, upcalling in nscsi_full_device for id	< 2.

       void device::scsi_put_data(int id, int pos, UINT8 data) must write byte
       pos in buffer id, upcalling in nscsi_full_device	for id < 2.

       scsi_get_data  and  scsi_put_data  should  do the external reads/writes
       when needed.

       The device can also override scsi_message to handle SCSI	messages other
       than the	ones generically handled, and it can also override some	of the
       timings (but a lot of them aren't used, beware).

       A number	of enums are defined to	make  things  easier.  The  SS_*  enum
       gives  status  returns  (with  SS_GOOD  for all's well).	 The SC_* enum
       gives the scsi commands.	 The SM_* enum gives the SCSI  messages,  with
       the  exception  of  identify  (which is 80-ff, doesn't really fit in an
       enum).

   What's missing in scsi_full_device
        Initiator support We have no initiator	device to HLE at that point.

        Delays	A scsi_delay command would help	giving more realistic  timings
	 to the	CD-ROM reader in particular.

        Disconnected  operation Would first require delays and	in addition an
	 emulated OS that can handle it.

        16-bits wide operation	needs an OS and	an initiator that  can	handle
	 it.

   What's missing in the ncr5390 (and probably future other controllers)
        Bus  free  detection Right now	the bus	is considered free if the con-
	 trollers isn't	using it, which	is true. This may change once  discon-
	 nected	operation is in.

        Target	commands We don't emulate (vs. HLE) any	target yet.

   The new 6502	family implementation
   Introduction
       The  new	 6502  family implementation has been created to reach sub-in-
       struction accuracy in observable	behaviour. It is designed with 3 goals
       in mind:

        every bus cycle must happen at	the exact time it would	 happen	 in  a
	 real CPU, and every access the	real CPU does is done

        instructions  can  be	interrupted  at	 any  time  in the middle then
	 restarted at that point transparently

        instructions can be interrupted even from within a memory handler for
	 bus contention/wait states emulation purposes

       Point 1 has been	ensured	through	bisimulation with the gate-level simu-
       lation perfect6502. Point 2 has been  ensured  structurally  through  a
       code  generator	which  will  be	explained in section 8.	Point 3	is not
       done yet	due to lack of support on the memory subsystem side, but  sec-
       tion 9 shows how	it will	be handled.

   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  off-
       shoots  (g65c816,  hu6280)  even	 exist that live elsewhere in the mame
       tree. The final class hierarchy is this:

				    6502
				     |
		  +------+--------+--+--+-------+-------+
		  |	 |	  |	|	|	|
		6510   deco16	6504   6509   rp2a03  65c02
		  |					|
	    +-----+-----+			     r65c02
	    |	  |	|				|
	  6510t	 7501  8502			    +---+---+
						    |	    |
						 65ce02	  65sc02
						    |
						  4510

       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	under-
       stood additional	instructions and some I/O.

       The 6504	is a pin and address-bus reduced version.

       The 6509	adds internal support for paging.

       The  rp2a03 is the NES variant with the D flag disabled and sound func-
       tionality integrated.

       The 65c02 is the	very first cmos	variant	with some additional  instruc-
       tions,  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.

       The  65ce02  is	the final evolution of the ISA in this hierarchy, with
       additional instructions,	registers, and removals	of a lot of dummy  ac-
       cesses  that slowed the original	6502 down by at	least 25%. The 4510 is
       a 65ce02	with integrated	MMU and	GPIO support.

   Usage of the	classes
       All the CPUs are	standard modern	CPU devices, with all the  normal  in-
       teraction  with the device infrastructure. To include one of these CPUs
       in your driver you need to include "CPU/m6502/<CPU>.h" and  then	 do  a
       MCFG_CPU_ADD("tag", <CPU>, clock).

       6510 variants port I/O callbacks	are setup through:
	      MCFG_<CPU>_PORT_CALLBACKS(READ8(type, read_method), WRITE8(type,
	      write_method))

       And the pullup and floating lines mask is given through:
	      MCFG_<CPU>_PORT_PULLS(pullups, floating)

       In order	to see all bus accesses	on the memory handlers it is possible
       to disable accesses through the direct map (at a	CPU cost, of course)
       with:
	      MCFG_M6502_DISABLE_DIRECT()

       In  that	 case, transparent decryption support is also disabled,	every-
       thing goes through normal memory-map read/write calls. The state	of the
       sync line is given by the CPU method  get_sync(),  making  implementing
       the decryption in the handler possible.

       Also,  as  for  every  executable device, the CPU method	total_cycles()
       gives the current time in cycles	since the start	of  the	 machine  from
       the  point  of  view  of	 the  CPU. Or, in other	words, what is usually
       called the cycle	number for the CPU when	somebody talks about bus  con-
       tention or wait states. The call	is designed to be fast (no system-wide
       sync, no	call to	machine.time())	and is precise.	Cycle number for every
       access is exact at the sub-instruction level.

       The 4510	special	nomap line is accessible through get_nomap().

       Other than these	specifics, these are perfectly normal CPU classes.

   General structure of	the emulations
       Each variant is emulated	through	up to 4	files:

        <CPU>.h    = header for the CPU class

        <CPU>.c    = implementation of	most of	the CPU	class

        d<CPU>.lst = dispatch table for the CPU

        o<CPU>.lst = opcode implementation code for the CPU

       The last	two are	optional. They're used to generate a <CPU>.inc file in
       the object directory which is included by the .c	file.

       At  a minimum, the class	must include a constructor and an enum picking
       up the correct input line ids. See m65sc02 for  a  minimalist  example.
       The  header  can	also include specific configuration macros (see	m8502)
       and also	the class can include specific memory accessors	(more on these
       later, simple example in	m6504).

       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_en-
       tries array) and	include	the .inc file (which provides the missing def-
       initions). 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.

   Dispatch tables
       Each d<CPU>.lst is the dispatch table for the CPU. Lines	starting  with
       '#'  are	comments. The file must	include	257 entries, the first 256 be-
       ing opcodes and the 257th what the CPU should do	on reset. In the  6502
       irq and nmi actually magically call the "brk" opcode, hence the lack of
       specific	description for	them.

       Entries	0  to 255, i.e.	the opcodes, must have one of these two	struc-
       tures:

        opcode_addressing-mode

        opcode_middle_addressing-mode

       Opcode is traditionally a three-character value.	Addressing  mode  must
       be  a  3-letter	value  corresponding  to  one  of the DASM_* macros in
       m6502.h.	Opcode and addressing mode are used to generate	the  disassem-
       bly  table.  The	full entry text	is used	in the opcode description file
       and the dispatching methods, allowing for per-CPU variants for  identi-
       cal-looking opcodes.

       An  entry of "."	was usable for unimplemented/unknown opcodes, generat-
       ing "???" in the	disassembly, but is not	a  good	 idea  at  this	 point
       since it	will infloop in	execute() if encountered.

   Opcode descriptions
       Each o<CPU>.lst file includes the CPU-specific opcodes descriptions. An
       opcode  description is a	series of lines	starting by an opcode entry by
       itself and followed by a	series of indented lines with  code  executing
       the opcode.

       For instance the	asl <absolute address> opcode looks like this:
       asl_aba
	 TMP = read_pc();
	 TMP = set_h(TMP, read_pc());
	 TMP2 =	read(TMP);
	 write(TMP, TMP2);
	 TMP2 =	do_asl(TMP2);
	 write(TMP, TMP2);
	 prefetch();

       First  the low part of the address is read, then	the high part (read_pc
       is auto-incrementing). Then, now	that  the  address  is	available  the
       value  to  shift	 is  read,  then re-written (yes, the 6502 does	that),
       shifted then the	final result is	written	 (do_asl  takes	 care  of  the
       flags).	The  instruction finishes with a prefetch of the next instruc-
       tion, as	all non-CPU-crashing instructions do.

       Available bus-accessing functions are:
		 +------------------+----------------------------+
		 | read(adr)	    | standard read		 |
		 +------------------+----------------------------+
		 | read_direct(adr) | read from	program	space	 |
		 +------------------+----------------------------+
		 | read_pc()	    | read at the PC address and |
		 |		    | increment	it		 |
		 +------------------+----------------------------+
		 | read_pc_noinc()  | read at the PC address	 |
		 +------------------+----------------------------+
		 | read_9()	    | 6509 indexed-y banked read |
		 +------------------+----------------------------+
		 | write(adr, val)  | standard write		 |
		 +------------------+----------------------------+
		 | prefetch()	    | instruction prefetch	 |
		 +------------------+----------------------------+
		 | prefetch_noirq() | instruction prefetch with- |
		 |		    | out irq check		 |
		 +------------------+----------------------------+

       Cycle counting is done by the code  generator  which  detects  (through
       string  matching)  the  accesses	and generates the appropriate code. In
       addition	to the bus-accessing functions a special line can be  used  to
       wait  for the next event	(irq or	whatever). "eat-all-cycles;" on	a line
       will do that wait then continue.	It is used by wai_imp and stp_imp  for
       the m65c02.

       Due  to	the  constraints of the	code generation, some rules have to be
       followed:

        in general, stay with one instruction/expression per line

        there must be no side effects in the parameters  of  a	 bus-accessing
	 function

        local	variables  lifetime must not go	past a bus access. In general,
	 it's better to	leave them to helper methods (like  do_asl)  which  do
	 not  do  bus accesses.	Note that "TMP"	and "TMP2" are not local vari-
	 ables,	they're	variables of the class.

        single-line then or else constructs must have braces around  them  if
	 they're calling a bus-accessing function

       The  per-opcode	generated  code	 are methods of	the CPU	class. As such
       they have complete access to other methods of the class,	 variables  of
       the class, everything.

   Memory interface
       For  better opcode reuse	with the MMU/banking variants, a memory	access
       subclass	has been created. It's called  memory_interface,  declared  in
       m6502_device, and provides the following	accessors:
	    +----------------------------+----------------------------+
	    | UINT8 read(UINT16	adr)	 | normal read		      |
	    +----------------------------+----------------------------+
	    | UINT8	read_sync(UINT16 | opcode read with sync  ac- |
	    | adr)			 | tive	 (first	 byte  of op- |
	    |				 | code)		      |
	    +----------------------------+----------------------------+
	    | UINT8 read_arg(UINT16 adr) | opcode read with sync  in- |
	    |				 | active (rest	of opcode)    |
	    +----------------------------+----------------------------+
	    | void   write(UINT16   adr, | normal write		      |
	    | UINT8 val)		 |			      |
	    +----------------------------+----------------------------+
	    +----------------------------+----------------------------+
	    | UINT8 read_9(UINT16 adr)	 | special   y-indexed	 6509 |
	    |				 | read, defaults to read()   |
	    +----------------------------+----------------------------+
	    | void  write_9(UINT16  adr, | special   y-indexed	 6509 |
	    | UINT8 val);		 | write, defaults to write() |
	    +----------------------------+----------------------------+

       Two implementations are given by	default, one usual, mi_default_normal,
       one  disabling  direct  access, mi_default_nd. A	CPU that wants its own
       interface (see 6504 or 6509 for instance) must  override	 device_start,
       intialize mintf there then call init().

   The generated code
       A  code generator is used to support interrupting and restarting	an in-
       struction in the	middle.	This is	done through a two-level state machine
       with updates only at the	boundaries. More precisely,  inst_state	 tells
       you  which  main	 state	you're	in. It's equal to the opcode byte when
       0-255, and 0xff00 means reset. It's always valid	and used  by  instruc-
       tions  like rmb.	inst_substate indicates	at which step we are in	an in-
       struction, but it set only when an instruction  has  been  interrupted.
       Let's go	back to	the asl	<abs> code:

       asl_aba
	 TMP = read_pc();
	 TMP = set_h(TMP, read_pc());
	 TMP2 =	read(TMP);
	 write(TMP, TMP2);
	 TMP2 =	do_asl(TMP2);
	 write(TMP, TMP2);
	 prefetch();

       The complete generated code is:
       void m6502_device::asl_aba_partial()
       {
       switch(inst_substate) {
       case 0:
	 if(icount == 0) { inst_substate = 1; return; }
       case 1:
	 TMP = read_pc();
	 icount--;
	 if(icount == 0) { inst_substate = 2; return; }
       case 2:
	 TMP = set_h(TMP, read_pc());
	 icount--;
	 if(icount == 0) { inst_substate = 3; return; }
       case 3:
	 TMP2 =	read(TMP);
	 icount--;
	 if(icount == 0) { inst_substate = 4; return; }
       case 4:
	 write(TMP, TMP2);
	 icount--;
	 TMP2 =	do_asl(TMP2);
	 if(icount == 0) { inst_substate = 5; return; }
       case 5:
	 write(TMP, TMP2);
	 icount--;
	 if(icount == 0) { inst_substate = 6; return; }
       case 6:
	 prefetch();
	 icount--;
       }
	 inst_substate = 0;
       }

       One  can	 see that the initial switch() restarts	the instruction	at the
       appropriate substate, that icount is updated  after  each  access,  and
       upon  reaching  0  the  instruction is interrupted and the substate up-
       dated. Since most instructions are started from the  beginning  a  spe-
       cific variant is	generated for when inst_substate is known to be	0:

       void m6502_device::asl_aba_full()
       {
	 if(icount == 0) { inst_substate = 1; return; }
	 TMP = read_pc();
	 icount--;
	 if(icount == 0) { inst_substate = 2; return; }
	 TMP = set_h(TMP, read_pc());
	 icount--;
	 if(icount == 0) { inst_substate = 3; return; }
	 TMP2 =	read(TMP);
	 icount--;
	 if(icount == 0) { inst_substate = 4; return; }
	 write(TMP, TMP2);
	 icount--;
	 TMP2 =	do_asl(TMP2);
	 if(icount == 0) { inst_substate = 5; return; }
	 write(TMP, TMP2);
	 icount--;
	 if(icount == 0) { inst_substate = 6; return; }
	 prefetch();
	 icount--;
       }

       That  variant removes the switch, avoiding a costly computed branch and
       also an inst_substate write. There is in	addition a  fair  chance  that
       the decrement-test with zero pair is compiled into something efficient.

       All  these  opcode  functions  are  called through two virtual methods,
       do_exec_full and	do_exec_partial, which are generated into a  257-entry
       switch  statement.  Pointers-to-methods being expensive to call,	a vir-
       tual function implementing a switch has a fair chance of	being better.

       The execute main	call ends up very simple:
       void m6502_device::execute_run()
       {
	 if(inst_substate)
	   do_exec_partial();

	 while(icount >	0) {
	   if(inst_state < 0x100) {
	     PPC = NPC;
	     inst_state	= IR;
	     if(machine().debug_flags &	DEBUG_FLAG_ENABLED)
	       debugger_instruction_hook(this, NPC);
	   }
	   do_exec_full();
	 }
       }

       If an instruction was partially executed	finish it (icount will then be
       zero if it still	doesn't	finish). Then try  to  run  complete  instruc-
       tions.  The NPC/IR dance	is due to the fact that	the 6502 does instruc-
       tion prefetching, so the	 instruction  PC  and  opcode  come  from  the
       prefetch	results.

   Future bus contention/delay slot support
       Supporting  bus	contention  and	delay slots in the context of the code
       generator only requires being able to  abort  a	bus  access  when  not
       enough  cycles  are  available  into icount, and	restart	it when	cycles
       have become available again. The	implementation plan is to:

        Have a	delay()	method on the CPU that removes cycles from icount.  If
	 icount	becomes	zero or	less, having it	throw a	suspend() exception.

        Change	the code generator to generate this:
       void m6502_device::asl_aba_partial()
       {
       switch(inst_substate) {
       case 0:
	 if(icount == 0) { inst_substate = 1; return; }
       case 1:
	 try {
	 TMP = read_pc();
	 } catch(suspend) { inst_substate = 1; return; }
	 icount--;
	 if(icount == 0) { inst_substate = 2; return; }
       case 2:
	 try {
	 TMP = set_h(TMP, read_pc());
	 } catch(suspend) { inst_substate = 2; return; }
	 icount--;
	 if(icount == 0) { inst_substate = 3; return; }
       case 3:
	 try {
	 TMP2 =	read(TMP);
	 } catch(suspend) { inst_substate = 3; return; }
	 icount--;
	 if(icount == 0) { inst_substate = 4; return; }
       case 4:
	 try {
	 write(TMP, TMP2);
	 } catch(suspend) { inst_substate = 4; return; }
	 icount--;
	 TMP2 =	do_asl(TMP2);
	 if(icount == 0) { inst_substate = 5; return; }
       case 5:
	 try {
	 write(TMP, TMP2);
	 } catch(suspend) { inst_substate = 5; return; }
	 icount--;
	 if(icount == 0) { inst_substate = 6; return; }
       case 6:
	 try {
	 prefetch();
	 } catch(suspend) { inst_substate = 6; return; }
	 icount--;
       }
	 inst_substate = 0;
       }

       A  modern  try/catch costs nothing if an	exception is not thrown. Using
       this the	control	will go	back to	the main loop, which  will  then  look
       like this:
       void m6502_device::execute_run()
       {
	 if(waiting_cycles) {
	   icount -= waiting_cycles;
	   waiting_cycles = 0;
	 }

	 if(icount > 0 && inst_substate)
	   do_exec_partial();

	 while(icount >	0) {
	   if(inst_state < 0x100) {
	     PPC = NPC;
	     inst_state	= IR;
	     if(machine().debug_flags &	DEBUG_FLAG_ENABLED)
	       debugger_instruction_hook(this, NPC);
	   }
	   do_exec_full();
	 }

	 waiting_cycles	= -icount;
	 icount	= 0;
       }

       A  negative  icount means that the CPU won't be able to do anything for
       some time in the	future,	because	it's either waiting for	the bus	to  be
       free  or	for a peripheral to answer. These cycles will be counted until
       elapsed and then	normal processing will go on. It's important  to  note
       that  the  exception  path  only	happens	when the contention/wait state
       goes further than the scheduling	slice of the CPU. That should not usu-
       ally be the case, so the	cost should be minimal.

   Multi-dispatch variants
       Some variants currently in the process of being	supported  change  in-
       struction  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).

   Current TO-DO:
        Implement the bus contention/wait states  stuff,  but	that  requires
	 support on the	memory map side	first.

        Integrate the I/O subsystems in the 4510

        Possibly integrate the	sound subsytem in the rp2a03

        Add decent hookups for	the Apple 3 madness

   Software 3D Rendering in MAME
        Background

        Concepts

	  ObjectType

	  Primitives

	  Synchronization

        The poly_manager class

	  Types & Constants

	    vertex_t

	    extent_t

	    render_delegate

	  Methods

	    poly_manager

	    wait

	    object_data

	    register_poly_array

	    render_tile

	    render_triangle

	    render_triangle_fan

	    render_triangle_strip

	    render_polygon

	    render_extents

	    zclip_if_less

        Example Renderer

	  Types

	  Constructor

	  swap_buffers

	  clear_buffers

	  draw_triangle

	  draw_triangle_flat

	  draw_triangle_gouraud

        Advanced Topic: the poly_array	class

	  Methods

	    poly_array

	    count

	    max

	    itemsize

	    allocated

	    byindex

	    contiguous

	    indexof

	    reset

	    next

	    last

   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 (usu-
       ally double- or triple-buffered), then  perhaps	combined  with	tradi-
       tional 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 emu-
       lator 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	 back-
       ground 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	situa-
       tions.

   Concepts
       At its core, poly_manager is a mechanism	to support multi-threaded ren-
       dering 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  or-
       der. Given a pool of threads and	a number of work items to complete, it
       is  important thatat least within a given scanlineall 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 proceedpoten-
       tially modifying	some of	 the  relevant	statewhile  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 re-
       cently allocated	ObjectType instance is implicitly  captured  and  pro-
       vided to	the render callbacks.

       For  more  complex  scenarios, where data might change even more	infre-
       quently,	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 bot-
	 tom-right vertex. Like	triangles, tiles have constant iterated	 para-
	 meter 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 be-
	 fore 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	frame-
	 buffer	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	primi-
	 tive  must  wait  until the first completes. poly_manager provides no
	 internal mechanism to help detect this, so it is on the caller	to de-
	 termine 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  mem-
       ory  allocated for its internal structures, as well as memory allocated
       for ObjectType structures. Thus it is important that you	dont 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 pa-
	 rameters, 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	primi-
	 tive  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 per-
	 mitted	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, youll find  a  vertex_t  type  that  de-
       scribes a single	vertex.	All primitive drawing methods accept 2 or more
       of  these  vertex_t  objects. The vertex_t includes the X and Y coordi-
       nates 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  Max-
       Params template values of the owning poly_manager class.

       All  of	poly_managers  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 in-
       clusive,	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 parame-
       ter values is specified as a template parameter to the primitive	 draw-
       ing 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 hori-
       zontal 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 ar-
       ray 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	 para-
       meters 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  ren-
	 dering.

        threadid is a unique ID indicating the	index of the thread youre run-
	 ning  on; this	value is useful	if you are keeping any kind of statis-
	 tics and dont want to add contention over shared values. In this sit-
	 uation, 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 its	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 render-
       ing 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 ob-
       ject 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 ob-
       jects it	knows about in order to	reclaim	all outstanding	allocated mem-
       ory.  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 ar-
	 ray 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 para-
	 meter	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 ren-
	 der 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 bot-
	 tom-right corner of the tile.

       Return value: the total number of clipped pixels	represented by the en-
       queued 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 ar-
	 ray 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 para-
	 meter	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 ren-
	 der 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 en-
       queued 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 ar-
	 ray 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 para-
	 meter	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 ren-
	 der 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 coordi-
	 nates	and  iterated  parameters for all the triangles, in fan	order.
	 This means that the first vertex is fixed.  So	if 5 vertices are pro-
	 vided,	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 en-
       queued 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 ar-
	 ray 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 para-
	 meter	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 ren-
	 der 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 coordi-
	 nates	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 en-
       queued 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 ar-
	 ray  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 para-
	 meter 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  ren-
	 der each extent.

        v is a	pointer	to an array of vertex_t	objects	containing the coordi-
	 nates	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 en-
       queued 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 ar-
	 ray 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 para-
	 meter	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 ren-
	 der 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 en-
       queued 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	repre-
       sents  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 ar-
	 ray 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 us-
       ing 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 for-
       mat,  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_managers 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 con-
       sumed 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  its	 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 weve 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 dis-
       play 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_managers
       wait(), which will block	the current thread until all rendering is com-
       plete. This is important	because	otherwise the  caller  may  receive  a
       bitmap  that  is	still being drawn to, leading to torn or corrupt visu-
       als.

   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 ver-
       tices.

       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 parame-
       ters 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 (pri-
       vately) 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 sepa-
       rate render callbacks that are optimized	for that special case.

   draw_triangle_flat
       Heres 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  per-
       spective	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 its 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_trian-
       gle() 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 val-
       ues 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 dynami-
       cally-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 allo-
       cated 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	dont 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  sys-
       tems.  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 construc-
       tion time, one chunks 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 re-
       allocate	all the	objects	into a contiguous vector once again.

       For the case where poly_array is	used to	manage a shared	 pool  of  ob-
       jects,  it can be configured to retain multiple most recently allocated
       items by	using a	TrackingCount greater than 1. For example, if poly_ar-
       ray is managing objects for two texture units, then it can  set	Track-
       ingCount	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 re-
       cently allocated	object for each	of the units independently.

   Methods
   poly_array
	  poly_array();

       The  poly_array constructor requires no parameters and simply pre-allo-
       cates 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 whats 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  re-
	 turned,  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 pre-
       vious allocations created a discontiguous array,	a fresh	vector is  al-
       located	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 ob-
	 ject independently for	each tracking_index.

       Return value: a reference to the	last allocated object.

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 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.

       Bug reports, however, are always	welcome.

THE MAME LICENSE
       The  MAME  project as a whole is	distributed under the terms of the GNU
       General Public License, version 2 or later (GPL-2.0+),  since  it  con-
       tains  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  and we would encourage new contributors to dis-
       tribute 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.
	  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
	  the  Free  Software  Foundation; either version 2 of the License, or
	  (at your option) any later version.

	  This program is distributed in the hope that it will be useful,  but
	  WITHOUT  ANY	WARRANTY;  without  even  the implied warranty of MER-
	  CHANTABILITY or FITNESS FOR A	PARTICULAR PURPOSE.  See the GNU  Gen-
	  eral Public License for more details.

	  You  should  have  received a	copy of	the GNU	General	Public License
	  along	with this program; if not, write to the	Free Software  Founda-
	  tion,	 Inc.,	51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
	  USA.

       Please see the license information for further details.

CONTRIBUTE
       The documentation on this site is the handiwork of our  many  contribu-
       tors.

AUTHOR
       MAMEdev Team

COPYRIGHT
       1997-2025, MAMEdev and contributors

0.274				 Apr 13, 2025			       MAME(1)

Want to link to this manual page? Use this URL:
<https://man.freebsd.org/cgi/man.cgi?query=MAME&sektion=1&manpath=FreeBSD+Ports+14.3.quarterly>

home | help