MAME Manual
MAME Manual
MAME Manual
Release 0.174
MAMEdev Team
1 What is MAME 3
1.1 I. Purpose . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.2 II. Cost . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3
1.3 III. Software Image Files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
1.4 IV. Derivative Works . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
1.5 V. Official Contact Information . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4
5 Advanced configuration 55
5.1 Multiple Configuration Files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
5.2 MAME Path Handling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
5.3 Shifter Toggle Disable . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
5.4 BGFX Effects for (nearly) Everyone . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57
5.5 HLSL Effects for Windows . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
5.6 GLSL Effects for *nix, OS X, and Windows . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68
5.7 Stable Controller IDs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 70
i
6.3 Imgtool Subcommands . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73
6.4 Imgtool Filters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75
6.5 Imgtool Format Info . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76
6.6 Castool - A generic casette image manipulation tool for MAME . . . . . . . . . . . . . . . . . . . . 95
6.7 Using Castool . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95
6.8 Castool Formats . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 95
6.9 Other tools included with MAME . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101
6.10 Developer-focused tools included with MAME . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101
10 Contribute 135
ii
MAME Documentation, Release 0.174
Note: This documentation is a work in progress. You can track the status of these topics through our public docu-
mentation issue tracker. Learn how you can contribute on GitHub.
CONTENTS 1
MAME Documentation, Release 0.174
2 CONTENTS
CHAPTER
ONE
WHAT IS MAME
I. Purpose
MAME 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
emulated behavior matches the original, one must also be able to actually use the software. This is considered a nice
side effect, and is not MAMEs primary focus.
It is not our intention to infringe on any copyrights or patents on the original games. 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 game code are
included in the executable.
II. Cost
MAME is free. Its source code is free. The project as whole is distributed under the GNU General Public License,
version 2 or later (GPL-2.0+), but most of code (including core functionality) is also available under the 3-clause BSD
license (BSD-3-clause).
3
MAME Documentation, Release 0.174
ROM, CD, hard disk and other media images are all copyrighted material. They cannot be distributed without the
explicit permission of the copyright holder(s). They are not abandonware, nor has any of the software supported by
MAME passed out of copyright.
MAME is not intended to be used as a tool for mass copyright infringement. Therefore, it is strongly against the
authors wishes to sell, advertise, or link to resources that provide illegal copies of ROM, CD, hard disk or other media
images.
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 permission, which
requires that you follow the guidelines above.
The version number of any derivative work should reflect the version number of the MAME release from which it was
was derived.
For questions regarding the MAME license, trademark, or other usage, go to http://www.mamedev.org/
TWO
This section covers initial preparation work needed to use MAME, including downloading and compiling MAME.
An Introduction to MAME
MAME, formerly was an acronym which stood for Multi Arcade Machine Emulator, documents and reproduces
through emulation the inner components of arcade machines, computers, consoles, chess computers, calculators, and
many other types of electronic amusement machines. As a nice side-effect, MAME allows to use on a modern PC
those programs and games which were originally developed for the emulated machines.
At one point there were actually two separate projects, MAME and MESS. MAME covered arcade machines, while
MESS covered everything else. They are now merged into the one MAME.
MAME is mostly programmed in C with some core components in C++. MAME can currently emulate over 32000
individual systems from the last 5 decades.
Purpose of MAME
The primary purpose of MAME is to preserve decades of arcade, computer, and console history. As technology
continues to rush forward, MAME prevents these important vintage systems from being lost and forgotten.
ProjectMESS contains a complete list of the systems currently emulated. As you will notice, being supported does not
always mean that the status of the emulation is perfect. You may want
1. to check the status of the emulation in the wiki pages of each system, accessible from the drivers page (e.g. for
Apple Macintosh, from the page for the mac.c driver you can reach the pages for both macplus and macse),
2. to read the corresponding sysinfo.dat entry in order to better understand which issues you may encounter while
running a system in MAME (again, for Apple Macintosh Plus you have to check this entry).
Alternatively, you can simply see the status by yourself, launching the system emulation and taking a look to the
red or yellow warning screen which appears before the emulation starts, if any. Notice that if you have informa-
tion which can help to improve the emulation of a supported system, or if you can directly contribute fixes and/or
addition to the current source, you can follow the instructions at the contact page or post to the MAME Forums at
http://forum.mamedev.org/
5
MAME Documentation, Release 0.174
Supported OS
The current source code can be directly compiled under all the main OSes: Microsoft Windows (both with Di-
rectX/BGFX native support or with SDL support), Linux, FreeBSD, and Mac OS X. Also, both 32-bit and 64-bit
are supported, but be aware 64-bit often shows significant speed increases.
System Requirements
MAME is written in fairly generic C/C++, and has been ported to numerous platforms. Over time, as computer
hardware has evolved, the MAME code has evolved as well to take advantage of the greater processing power and
hardware capabilities offered.
The official MAME binaries are compiled and designed to run on a standard Windows-based system. The minimum
requirements are:
Intel Core series CPU or equivalent, at least 2.0 GHz
32-bit OS (Vista SP1 or later on Windows, 10.9 or later on Mac)
4 GB RAM
DirectX 9.0c for Windows
A Direct3D, or OpenGL capable graphics card
Any DirectSound capable sound card/onboard audio
Of course, the minimum requirements are just that: minimal. You may not get optimal performance from such a
system, but MAME should run. Modern versions of MAME require more power than older versions, so if you have a
less-capable PC, you may find that using an older version of MAME may get you better performance, at the cost of
greatly lowered accuracy and fewer supported systems.
MAME will take advantage of 3D hardware for compositing artwork and scaling the games to full screen. To make
use of this, you should have a modern Direct3D 8-capable video card with at least 16MB of video RAM.
HLSL or GLSL special effects such as CRT simulation will put a very heavy load on your video card, especially
at higher resolutions. You will need a fairly powerful modern video card, and the load on your video card goes up
exponentially as your resolution increases. If HLSL or GLSL are too intensive, try dropping your output resolution.
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.
Most of the systems emulated by MAME requires a dump of the internal chips of the original system. These can be
obtained by extracting the data from an original unit, or finding them (at your own risk) in the WorldWideWeb. Being
copyrighted material, MAME does not come with any of these.
Also, you may want to find some software to be run on the emulated machine. Again, Google and other search engines
are your best friends. MAME does not provide any software to be run on the emulated machines because it is very
often (almost always, in the case of console software) copyrighted material.
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?
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 All Platforms.
Compiling MAME
All Platforms
Whenever you are changing build parameters, (such as switching between a SDL-based build and a native
Windows renderer one, or adding tools to the compile list) you need to run a make REGENIE=1 to allow the
settings to be regenerated. Failure to do this will cause you very difficult to troubleshoot problems.
If you want to add various additional tools to the compile, such as CHDMAN, add a TOOLS=1 to your make
statement, like make REGENIE=1 TOOLS=1
You can do driver specific builds by using SOURCES=<driver> in your make statement. For instance, building
Pac-Man by itself would be make SOURCES=src/mame/drivers/pacman.cpp REGENIE=1 including the
necessary REGENIE for rebuilding the settings.
Speeding up the compilation can be done by using more cores from your CPU. This is done with the -j parameter.
Note: the maximum number you should use is the number of cores your CPU has, plus one. No higher than that
will speed up the compilation, and may in fact slow it down. For instance, make -j5 on a quad-core CPU will
provide optimal speed.
Debugging information can be added to a compile using SYMBOLS=1 though most users will not want or need
to use this.
Putting all of these together, we get a couple of examples:
Rebuilding MAME for just the Pac-Man driver, with tools, on a quad-core (e.g. i5 or i7) machine:
make -j3
Microsoft Windows
Here are specific notes about compiling MAME for Microsoft Windows.
Refer to the MAME tools site for the latest toolkit for getting MAME compiled on Windows.
You will need to download the toolset from that link to begin. Periodically, these tools are updated and newer
versions of MAME from that point on will require updated tools to compile.
You can do compilation on Visual Studio 2015 (if installed on your PC) by using make vs2015. This will always
regenerate the settings, so REGENIE=1 is not needed.
Make sure you get SDL 2 2.0.3 or 2.0.4 as earlier versions are buggy.
Fedora Linux
Youll need a few prerequisites from your distro. Make sure you get SDL2 2.0.3 or 2.0.4 as earlier versions are buggy.
sudo yum install gcc gcc-c++ SDL2-devel SDL2_ttf-devel libXinerama-devel qt5-qtbase-devel qt5-qttools expat-
devel fontconfig-devel
Compilation is exactly as described above in All Platforms.
Youll need a few prerequisites from your distro. Make sure you get SDL2 2.0.3 or 2.0.4 as earlier versions are buggy.
sudo apt-get install git build-essential libsdl2-dev libsdl2-ttf-dev libfontconfig-dev qt5-default
Compilation is exactly as described above in All Platforms.
Arch Linux
Apple Mac OS X
Youll need a few prerequisites to get started. Make sure youre on OS X 10.9 Mavericks or later. You will NEED
SDL2 2.0.4 for OS X.
Install Xcode from the Mac App Store
Launch Xcode. It will download a few additional prerequisites. Let this run through before proceeding.
Once thats done, quit Xcode and open a Terminal window
Type xcode-select install to install additional tools necessary for MAME
Next youll need to get SDL2 installed.
Go to this site and download the Mac OS X .dmg file
If the .dmg doesnt auto-open, 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
Lastly to begin compiling, use Terminal to navigate to where you have the MAME source tree (cd command) and
follow the normal compilation instructions from above in All Platforms.
Its possible to get MAME working from 10.6, but a bit more complicated:
Youll need to install clang-3.7, ld64, libcxx and python27 from MacPorts
Then add these options to your make command or useroptions.mak:
OVERRIDE_CC=/opt/local/bin/clang-mp-3.7
OVERRIDE_CXX=/opt/local/bin/clang++-mp-3.7
PYTHON_EXECUTABLE=/opt/local/bin/python2.7
ARCHOPTS=-stdlib=libc++
First, download and install Emscripten 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/drivers/pacman.cpp
The SOURCES parameter should have the path to at least one driver .cpp file. The make process will attempt to
locate and include all dependencies necessary to produce a complete build including the specified driver(s). However,
sometimes it is necessary to manually specify additional files (using commas) if this process misses something. E.g.:
emmake make SUBTARGET=apple2e SOURCES=src/mame/drivers/apple2e.cpp,src/mame/machine/applefdc.cpp
The value of the SUBTARGET parameter serves only to differentiate multiple builds and need not be set to any specific
value.
Other make parameters can also be used, e.g. -j for multithreaded compilation as described earlier.
When the compilation reaches the emcc phase, you may see a number of unresolved symbol warnings. At the
moment, this is expected for OpenGL-related functions such as glPointSize. Any others may indicate that an additional
dependency file needs to be specified in the SOURCES list. Unfortunately this process is not automated and you will
need to search the source tree to locate the files supplying the missing symbols. You may also be able to get away with
ignoring the warnings if the code path referencing them is not used at run-time.
If all goes well, a .js file will be output to the current directory. This file cannot be run by itself, but requires an HTML
loader to provide it with a canvas to output to and pass in command-line parameters. 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 filename
and pass in whatever parameters you desire. You will then need to place all of the following on a web server:
The compiled MAME .js file
The .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 directly 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.
THREE
This section describes general usage information about MAME. It is intended to cover aspects of using and configuring
MAME that are common across all operating systems. For additional OS-specific options, please see the separate
documentation for your platform of choice.
Using MAME
If you want to dive right in and skip the command line, theres a nice graphical way to use MAME without the need
to download and set up a front end. Simply start MAME with no parameters, by doubleclicking the mame.exe file or
running it directly from the command line. If youre looking to harness the full power of MAME, keep reading further.
On Macintosh OS X and *nix-based platforms, please be sure to set your font up to match your locale before starting,
otherwise you may not be able to read the text due to missing glyphs.
If you are a new MAME user, you could find this emulator a bit complex at first. Lets take a moment to talk about
softlists, as they can simplify matters quite a bit. If the content you are trying to play is a documented entry on one of
the MAME softlists, starting the content is as easy as
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 softlist-compatible software you
have in your roms folders. Please note that many older dumps of cartridges and discs may either be bad or require
renaming to match up to the softlist in order to work in this way.
If you are loading an arcade board or other non-softlist 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 shortname of the system you want to emulate (e.g. nes, c64, etc.)
<media> is the switch for the media you want to load (if its a cartridge, try -cart or -cart1; if its a floppy disk,
try -flop or -flop1; if its a CD-ROM, try -cdrom)
11
MAME Documentation, Release 0.174
<software> is the program / game you want to load (and it can be given either as the fullpath to the file to load,
or as the shortname of the file in our software lists)
<options> is any additional command line option for controllers, video, sound, etc.
Remember that if you type a <system> name which does not correspond to any emulated system, MAME will suggest
you some possible choices which are close to what you typed; and if you dont know which <media> switch are
available, you can always launch
mame.exe <system> -listmedia
If you dont know what <options> are available, there are a few things you can do. First of all, you can check the
command line options section of this manual. You can also try one of the many Frontends available for MAME.
Alternatively, you should keep in mind the following command line options, which might be very useful on occasion:
mame.exe -help
tells what MAME is the basic structure of MAME launching options, i.e. 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 Commandline Options section of this manual.
mame.exe -showconfig
gives you a (quite long) list of available configuration options for MAME. These configuration can always be modified
at command line, or by editing them in mame.ini which is the main configuration file for MAME. You can find a
description of some configuration options in the Universal Commandline 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, hence you can open it with any text editor (e.g. Notepad, Emacs or TextEdit) and configure every option you need.
However, no particular tweaks are needed to start, so you can basically leave most of the options unaltered.
Once you are more confident with MAME options, you may want to configure a bit more your setup. In this case,
keep in mind the order in which options are read; see Order of Config Loading for details.
Default Keys
All the keys below are fully configurable in the user interface. This list shows the standard keyboard configuration.
Key
Action
Tab
Toggles the configuration menu.
P
Pauses the game.
Shift+P
While paused, advances to next frame.
F2
Service Mode for games that support it.
F3
Resets the game.
Shift+F3
Performs a hard reset, which tears everything down
and re-creates it
from scratch. This is a more thorough and complete
reset than the reset
you get from hitting F3.
LCtrl+F3
[SDL ONLY] - Toggle uneven stretch.
Palette/colortable mode:
* [ ] - switch between palette and colortable
modes
* Up/Down - scroll up/down one line at a time
* Page Up/Page Down - scroll up/down one
page at a time
* Home/End - move to top/bottom of list
* -/+ - increase/decrease the number of colors per
row
* Enter - switch to graphics viewer
Graphics mode:
* [ ] - switch between different graphics sets
* Up/Down - scroll up/down one line at a time
* Page Up/Page Down - scroll up/down one
page at a time
* Home/End - move to top/bottom of list
* Left/Right - change color displayed
* R - rotate tiles 90 degrees clockwise
* -/+ - increase/decrease the number of tiles per
row
* Enter - switch to tilemap viewer
Tilemap mode:
* [ ] - switch between different tilemaps
* Up/Down/Left/Right - scroll 8 pixels at a time
* Shift+Up/Down/Left/Right - scroll 1 pixel at a
time
* Control+Up/Down/Left/Right - scroll 64
pixels at a time
* R - rotate tilemap view 90 degrees clockwise
* -/+ - increase/decrease the zoom factor
* Enter - switch to palette/colortable mode
LCtrl+F5
[SDL ONLY] - Toggle Filter.
Alt+Ctrl+F5
[NON SDL MS WINDOWS ONLY] - Toggle HLSL
Post-Processing.
F6
Toggle cheat mode (if started with -cheat).
LCtrl+F6
Decrease Prescaling.
F7
Load a save state. You will be requested to press a key
to determine which
save state you wish to load.
LCtrl+F7
Increase Prescaling.
Shift+F7
Create a save state. Requires an additional keypress to
identify the state,
similar to the load option above.
F8
Decrease frame skip on the fly.
F9
Increase frame skip on the fly.
F10
Toggle speed throttling.
F11
Toggles speed display.
Shift+F11
Toggles internal profiler display (if compiled in).
F12
Saves a screen snapshot.
Alt+F12
Take HLSL Rendered Snapshot.
Insert
[WINDOW ONLY, NON-SDL] Fast forward. While
held, runs game with
throttling disabled and with the maximum frameskip.
Page DN
[SDL ONLY] Fast forward. While held, runs the game
with throttling
disabled and with the maximum frameskip.
Alt+ENTER
Toggles between full-screen and windowed mode.
Scroll Lock
Default mapping for the uimodekey.
Escape
Exits emulator.
MAME Menus
If you started MAME without any command line parameters, youll be shown the game selection menu immediately.
While the keys listed above will let you navigate the menus, you can also use a mouse.
[todo: This needs SERIOUS expansion. Waiting on answer to a few questions..]
Frontends
There are a number of third party tools for MAME to make system and software selection simpler. These tools are
called Frontends, and there are far too many to list conclusively here. Some are free, some are commercial caveat
emptor. Some older frontends predate the merging of MAME and MESS and do not support the additional console,
handheld, etc functionality that MAME inherited from MESS.
This following list is not an endorsement of any of these frontends by the MAME team, but simply showing a number
of commonly used free frontends as a good starting point to begin from.
The MAME team will not provide support for issues with frontends. For support, we suggest contacting the frontend
author or trying any of the popular MAME-friendly forums on the internet.
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 youll need to know to use MAME effectively.
Lets start with a simple definition of what a ROM is.
For arcade games, a ROM image or file is a copy of all of the data inside 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, youll 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 Puckman ROM set.
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 wasnt damaged 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.
3.4. Frontends 17
MAME Documentation, Release 0.174
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 parent 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 isnt quite as efficient as
A merged set takes the parent set and one or more clone sets and puts them all inside the parent sets storage. To use
the existing Pac-Man example, combining the Puckman, Midway Pac-Man (USA) sets, along with various bootleg
versions and combining it all into ((PUCKMAN.ZIP**, would be making a merged set. A complete merged set with
the parent and all clones is the most common format MAME sets are stored in as it saves the most space.
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 hard-
ware. As the main board had data necessary to start up and self-test the hardware before passing it off to the game
cartridge, its not really appropriate to store that data as part of the game ROM sets. Instead, it is stored as a BIOS
image 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 couldnt just have them share the circuit/ROM
data through a normal parent/clone relationship. Instead, these re-used designs 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 youll also need the NAMCO51.ZIP device set as
well as any needed for the game.
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 broken boards by replacing damaged chips. Unfortunately, these sets eventually 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 wouldnt 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 documented. 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 multiple 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 determine which set(s) may be missing files.
ROM chip data tends to be relatively small and gets loaded to system memory outright. Some games also used
additional storage mediums such as hard drives, CD-ROMs, DVDs, and Laserdiscs. Those storage mediums are, for
multiple technical reasons, not well-suited to being stored the same way as ROM data and wont fit completely in
memory in some cases.
Thus, a new format was created for these in the CHD file. Compressed Hunks of Data, or CHD for short, are designed
very specifically around the needs of mass storage media. Some arcade games, consoles, and PCs will require a CHD
to run. As CHDs are already compressed, they should NOT be stored in a ZIP or 7Z file as you would for ROM
images.
Disclaimer: The following information is not legal advice and was not written by a lawyer.
This is not a bug in MAME. On original arcade hardware, you simply could not insert coins as fast as you can mashing
the button. The only ways you could get credit feeding at that kind of pace was if the coin mech hardware was defective
or if you were physically trying to cheat the coin mech.
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 youll not trigger this.
In many cases, updates to various subsystems such as HLSL, BGFX, or Lua plugins come as updates to the external
shader files as well as to the core MAME code. Unfortunately, builds that come from third parties may come as just
a main MAME executable or with outdated external files, which can break the coupling between these external files
and MAME core code. Despite repeated attempts at contacting some of these third parties to warn them, they persist
in distributing broken MAME updates.
As we have no control over how third parties distribute these, all we really can do is disclaim the use of sites like
EmuCR and say that we cannot provide support for packages we didnt build. Compile your own MAME or use one
of the official packages provided by us.
Why does MAME support console games and dumb terminals? Wouldnt it be faster
if MAME had just the arcade games? Wouldnt it take less RAM? Wouldnt
MAME be faster if you just X?
This is a common misconception. The actual size of the MAME file doesnt 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 dont 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.
Theres still room for improvements in MAMEs speed, but chances are that if youre not already a skilled programmer
any ideas you have will have already been covered. Dont 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 Universal BIOS. This was done between 0.171
and 0.172, and results in an error trying to load Neo Geo games with an un-updated neogeo.zip set.
This also affects the Humble Bundle set: the games themselves are correct and up to date as of MAME 0.173 (and
most likely will remain so) though youll 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 theyll 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 Clas-
sics\uncompressed 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?
You may find that some games require CHD files. A CHD file is a compressed representation of a games hard
disk, CD-ROM, or laserdisc, and is generally not included as part of a games 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 version of the same game. Common alternate versions of games include versions
with text in other languages, versions with different copyright dates, later versions or updates, bootlegs, etc.
Cloned games often overlap some of the ROM code as the original or parent version of the game. To see if
you have any clones type MAME -listclones. To run a cloned game you simply need to place its parent
ROM file in your ROMs folder (leave it zipped).
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 compatible with the current version of MAME, you can
use the -verifyroms parameter. 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?
While this rule isnt always true, there is typically a method to how sets are arranged. The usual priority is to go with
the World set if its available, US if no World English set exists, and Japanese or other origin region if no World or
US English set.
Exceptions arise where the US or World sets have significant censorship/changes from the original version. For
instance, Gals Panic (set galsnew) uses the US version as parent because it has additional features compared to the
world export version (set galsnewa). These features are optional censorship, an additional control layout option (stick
with no button use), and English-language voice clips.
Another exception comes for games where it was licensed to a third party for export release. Pac-Man, for instance,
was published by Midway in the US though it was created by Namco. As a result, the parent set is the Japanese
puckman set, which retains the Namco copyright.
Lastly, a developer adding a new set can choose to use whatever naming and parent scheme they wish and are not
restricted to the above rules. Most follow these guidelines, however.
You can obtain a license to them by purchasing one via a distributor or vendor who has proper authority to do
so.
You can download one of the ROM sets that have been released for free to the public for non-commerical use.
You can purchase an actual arcade PCB, read the ROMs or disks yourself, and let MAME use that data.
Beyond these options, you are on your own.
No, its not. You are not permitted to make copies of software without the copyright owners permission. This is a
black & white issue.
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 dont. What
happened?
As time passes, MAME is perfecting the emulation of older games, even when the results arent immediately obvious
to the user. Often times the better emulation requires more data from the original game to operate. Sometimes the
data was overlooked, sometimes it simply wasnt feasible 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 its 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 his system, he is not allowed to legally include
any ROMs with his system. If he has purchased a license to the ROMs in your name from a distributor or vendor with
legitimate licenses, then he is okay to include them with the cabinet. After signing an agreement, cabinet owners that
include legitimate licensed ROMs may be permitted to include a version of MAME that runs those ROMs and nothing
more.
What about those guys who burn DVDs of ROMs for the price of the media?
What they are doing is just as illegal as selling the ROMs outright. As long as somebody owns the copyright, making
illegal copies is illegal, period. If someone went on the internet and started a business of selling cheap copies of the
latest U2 album for the price of media, do you think they would get away with it?
Even worse, a lot of these folks like to claim that they are helping the project. In fact, they only create more problems
for the MAME team. We are not associated with these people in any way regardless of how official they may attempt
to appear. You are only helping criminals make a profit through selling software they have no right to sell. Anybody
using the MAME name and/or logo to sell such products is also in violation of the MAME trademark.
But isnt 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 en-
cryption in computer programs that are obsolete. The exemption simply means that figuring out how these obsolete
programs worked is not illegal according to the DMCA. It does not have any effect on the legality of violating the
copyright on computer programs, which is what you are doing if you make copies of ROMs.
This is an urban legend that was made up by people who put ROMs up for download on their sites, in order to justify
the fact that they were breaking the law. There is nothing like this in any copyright law.
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-commercial purposes.
But Ive 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 commercial 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.
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 Microsofts website at https://support.microsoft.com/en-
us/kb/179113
I have a controller that doesnt want to work with the standard Microsoft Windows
version of MAME, what can I do?
By default, MAME on Microsoft Windows tries to do raw reads of the joystick(s), mouse/mice, and keyboard(s). This
works with most devices and provides the most stable results. However, some devices need special drivers to translate
their output and these drivers may not work with raw input.
One thing you can try is setting the keyboardprovider, mouseprovider, or joystickprovider setting (depending on which
kind of device your input device acts as) from rawinput to one of the other options such as dinput or win32. See OSD
related options for details on supported providers.
FOUR
This section contains configuration options that are applicable to all MAME sub-builds (both SDL and Windows
native).
Core commands
-help / -h / -?
Displays current MAME version and copyright notice.
-validate / -valid
Performs internal validation on every driver in the system. Run this before submitting changes to ensure
that you havent violated any of the core system rules.
Configuration commands
-createconfig / -cc
Creates the default mame.ini file. All the configuration options (not commands) described below can be
permanently changed by editing this configuration file.
-showconfig / -sc
Displays the current configuration settings. If you route this to a file, you can use it as an INI file. For
example, the command:
mame -showconfig >mame.ini
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 sufficient.
Frontend commands
Note: By default, all the -list commands below write info to the screen. If you wish to write the info to a textfile
instead, add this to the end of your command:
> filename
25
MAME Documentation, Release 0.174
-uimodekey [keystring]
Key used to toggle emulated keyboard on and off. Default setting is SCRLOCK.
-uifontprovider
Chooses provider for UI font: win, none or auto. Default setting is AUTO.
-menu
Enables menu bar at the top of the MAME window, if available by UI implementation. Default is OFF
-keyboardprovider
Chooses how MAME will get keyboard input.
On Windows, you can choose from: auto, rawinput, dinput, win32, or none On SDL, you can choose
from: auto, sdl, none
The default is auto. On Windows, auto will try rawinput with fallback to dinput. On SDL, auto will
default to sdl.
-mouseprovider
-listmidi
Create a list of available MIDI I/O devices for use with emulation.
-listnetwork
Create a list of available Network Adapters for use with emulation.
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 order:
mame.ini
<mymame>.ini (i.e. if MAME was renamed mame060.exe, MAME parses mame060.ini here)
debug.ini (if the debugger is enabled)
<driver>.ini (based on the source filename of the driver)
vertical.ini (for games with vertical monitor orientation)
horizont.ini (for games with horizontal monitor orientation)
arcade.ini (for games in source added with GAME() macro)
console.ini (for games in source added with CONS() macro)
-crosshairpath <path>
Specifies a list of paths within which to find crosshair files. Multiple paths can be specified by separat-
ing them with semicolons. The default is crsshair (that is, a directory crsshair in the same directory
as the MAME executable). If the Crosshair is set to default in the menu, MAME will look for game-
name\cross#.png and then cross#.png in the specified crsshairpath, where # is the player number. Failing
that, MAME will use built-in default crosshairs.
-pluginspath <path>
Specifies a list of paths within which to find Lua plugins for MAME.
-languagepath <path>
Specifies a list of paths within which to find language files for localized UI text.
-cfg_directory <path>
Specifies a single directory where configuration files are stored. Configuration files store user config-
urable settings that are read at startup and written when MAME exits. The default is cfg (that is, a
directory cfg in the same directory as the MAME executable). If this directory does not exist, it will be
automatically created.
-nvram_directory <path>
Specifies a single directory where NVRAM files are stored. NVRAM files store the contents of EEPROM
and non-volatile RAM (NVRAM) for games which used this type of hardware. This data is read at startup
and written when MAME exits. The default is nvram (that is, a directory nvram in the same directory
as the MAME executable). If this directory does not exist, it will be automatically created.
-input_directory <path>
Specifies a single directory where input recording files are stored. Input recordings are created via the
-record option and played back via the -playback option. The default is inp (that is, a directory inp
in the same directory as the MAME executable). If this directory does not exist, it will be automatically
created.
-state_directory <path>
Specifies a single 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
same directory as the MAME executable). If this directory does not exist, it will be automatically created.
-snapshot_directory <path>
Specifies a single directory where screen snapshots are stored, when requested by the user. The default is
snap (that is, a directory snap in the same directory as the MAME executable). If this directory does
not exist, it will be automatically created.
-diff_directory <path>
Specifies a single directory where hard drive differencing files are stored. Hard drive differencing files
store any data that is written back to a hard disk image, in order to preserve the original image. The
differencing files are created at startup when a game with a hard disk image. The default is diff (that is,
a directory diff in the same directory as the MAME executable). If this directory does not exist, it will
be automatically created.
-comment_directory <path>
Specifies a single directory where debugger comment files are stored. Debugger comment files are written
by the debugger when comments are added to the disassembly for a game. The default is comments (that
is, a directory comments in the same directory as the MAME executable). If this directory does not exist,
it will be automatically created.
-state <slot>
Immediately after starting the specified game, will cause the save state in the specified <slot> to be loaded.
-[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 game. This only works for games that have explicitly
enabled save state support in their driver. The default is OFF (-noautosave).
-playback / -pb <filename>
Specifies a file from which to play back a series of game inputs. Thisfeature does not work reliably for all
games, but can be used to watch a previously recorded game session from start to finish. In order to make
things consistent, you should only record and playback with all configuration (.cfg), NVRAM (.nv), and
memory card files deleted. The default is NULL (no playback).
-exit_after_playback
Tells MAME to exit after finishing playback of the input file.
-record / -rec <filename>
Specifies a file to record all input from a game session. This can be used to record a game session for
later playback. This feature does not work reliably for all games, but can be used to watch a previously
recorded game session from start to finish. In order to make things consistent, you should only record
and playback with all configuration (.cfg), NVRAM (.nv), and memory card files deleted. The default is
NULL (no recording).
-record_timecode
Tells MAME to create a timecode file. It contains a line with elapsed times on each press of timecode
shortcut key (default is F12). This option works only when recording mode is enabled (-record option).
The file is saved in the inp folder. By default, no timecode file is saved.
-mngwrite <filename>
Writes each video frame to the given <filename> in MNG format, producing an animation of the game
session. Note that -mngwrite only writes video frames; it does not save any audio data. Use -wavwrite for
that, and reassemble the audio/video using offline tools. The default is NULL (no recording).
-aviwrite <filename>
Stream video and sound data to the given <filename> in AVI format, producing an animation of the game
session complete with sound. The default is NULL (no recording).
-wavwrite <filename>
Writes the final mixer output to the given <filename> in WAV format, producing an audio recording of
the game session. The default is NULL (no recording).
-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 plat-
form (even Windows); the string %g represents the driver name of the current game; 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 game, and names the snapshots under it
starting with 0000 and increasing 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.
A few examples: if you use mame robby -snapname foo/%g%i snapshots will be saved as
snaps\foo\robby0000.png , snaps\foo\robby0001.png and so on; if you use mame nes -cart robby -
snapname %g/%d_cart snapshots will be saved as snaps\nes\robby.png ; if you use 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
games current resolution in raw pixels, and will create movies at the games starting resolution in raw
pixels. If you specify this option, then MAME will create both snapshots and movies at the size specified,
and will bilinear filter the result. Note that this size does not automatically rotate if the game is vertically
oriented. The default is auto.
-snapview <viewname>
Specifies the view to use when rendering snapshots and movies. By default, both use a special internal
view, which renders a separate snapshot per screen or renders movies only of the first screen. By spec-
ifying this option, you can override this default behavior and select a single view that will apply to all
snapshots and movies. Note that <viewname> does not need to be a perfect match; rather, it will select
the first view whose name matches all the characters specified by <viewname>.
For example, -snapview native will match the Native (15:14) view even though it is not a perfect match.
<viewname> can also be auto, which selects the first view with all screens present. The default value is
internal.
-[no]snapbilinear
Specify if the snapshot or movie should have bilinear filtering applied. Shutting this off can make a
difference in some performance while recording video to a file. The default is ON (-snapbilinear).
-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 game.
The default is %g, which creates a separate folder for each game.
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.
A few examples: if you use mame robby -statename foo/%g save states will be stored inside
sta\foo\robby\ ; if you use mame nes -cart robby -statename %g/%d_cart save states will be stored
inside sta\nes\robby\ ; if you use mame c64 -flop1 robby -statename %g/%d_flop1 save states will be
stored inside sta\c64\robby\.
-[no]burnin
Tracks brightness of the screen during play and at the end of emulation generates a PNG that can be used
to simulate burn-in effects on other games. 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
gamename/burnin-<screen.name>.png. The default is OFF (-noburnin).
-[no]autoframeskip / -[no]afs
Automatically determines the frameskip level while youre playing the game, adjusting it constantly in a
frantic attempt to keep the game running at full speed. Turning this on overrides the value you have set
for -frameskip below. The default is OFF (-noautoframeskip).
-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 say -frameskip 2, then MAME will display 10 out of every 12 frames. By skipping those
frames, you may be able to get full speed in a game that requires more horsepower than your computer
has. The default value is -frameskip 0, which skips no frames.
-seconds_to_run / -str <seconds>
This option can be used for benchmarking and automated testing. It tells MAME to stop execution after
a fixed number of seconds. By combining this with a fixed set of other command line options, you can
set up a consistent environment for benchmarking MAME performance. In addition, upon exit, the -str
option will write a screenshot called final.png to the games snapshot directory.
-[no]throttle
Configures the default thottling setting. When throttling is on, MAME attempts to keep the game running
at the games intended speed. When throttling is off, MAME runs the game as fast as it can. Note that the
fastest speed is more often than not limited by your graphics card, especially for older games. The default
is ON (-throttle).
-[no]sleep
Allows MAME to give time back to the system when running with -throttle. This allows other programs
to have some CPU time, assuming that the game isnt taxing 100% of your CPU resources. This option
can potentially cause hiccups in performance if other demanding programs are running. The default is
ON (-sleep).
-speed <factor>
Changes the way MAME throttles gameplay such that the game runs at some multiplier of the original
speed. A <factor> of 1.0 means to run the game at its normal speed. A <factor> of 0.5 means run at half
speed, and a <factor> of 2.0 means run at 2x speed. Note that changing this value affects sound playback
as well, which will scale in pitch accordingly. The internal resolution of the fraction is two decimalplaces,
so a value of 1.002 is the same as 1.0. The default is 1.0.
-[no]refreshspeed / -[no]rs
Allows MAME to dynamically adjust the gameplay speed such that it does not exceed the slowest refresh
rate for any targeted monitors in your system. Thus, if you have a 60Hz monitor and run a game that is
actually designed to run at 60.6Hz, MAME will dynamically change the speed down 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).
-[no]rotate
Rotate the game to match its normal state (horizontal/vertical). This ensures that both vertically and
horizontally oriented games show up correctly without the need to rotate your monitor. If you want to keep the
game displaying raw on the screen the way it would have in the arcade, turn this option OFF. The default is
ON (-rotate).
-[no]ror
-[no]rol
Rotate the game 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).
-[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 game 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.
-[no]flipx
-[no]flipy
Flip (mirror) the game screen either horizontally (-flipx) or vertically (-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).
-[no]artwork_crop / -[no]artcrop
Enable cropping of artwork to the game screen area only. This works best with -video gdi or -video d3d,
and means that vertically oriented games running full screen can display 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).
-[no]use_backdrops / -[no]backdrop
Enables/disables the display of backdrops. The default is ON (-use_backdrops).
-[no]use_overlays / -[no]overlay
Enables/disables the display of overlays. The default is ON (-use_overlays).
-[no]use_bezels / -[no]bezels
Enables/disables the display of bezels. The default is ON (-use_bezels).
-[no]use_cpanels / -[no]cpanels
Enables/disables the display of control panels. The default is ON (-use_cpanels).
-[no]use_marquees / -[no]marquees
Enables/disables the display of marquees. The default is ON (-use_marquees).
-brightness <value>
Controls the default brightness, or black level, of the game 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 game screen; this option controls the initial value for all visible game screens. The standard value is
1.0. Selecting lower values (down to 0.1) will produce a darkened display, while selecting higher values
(up to 2.0) will give a brighter display. The default is 1.0.
-contrast <value>
Controls the contrast, or white level, of the game 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 game screen; this
option controls the initial value for all visible game screens. The standard value is 1.0. Selecting lower
values (down to 0.1) will produce a dimmer display, while selecting higher values (up to 2.0) will give a
more saturated display. The default is 1.0.
-gamma <value>
Controls the gamma, which produces a potentially nonlinear black to white ramp, for the game 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 game screen; this option controls the initial value for all visible game
screens. The standard value is 1.0, which gives a linear ramp from black to white. Selecting lower values
(down to 0.1) will increase the nonlinearity toward black, while selecting higher values (up to 3.0) will
push the nonlinearity toward white. The default is 1.0.
-pause_brightness <value>
This controls the brightness level when MAME is paused. The default value is 0.65.
-effect <filename>
Specifies a single PNG file that is used as an overlay over any game 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 game screen areas (but not any external artwork), and
is rendered at the target resolution of the game 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 values of each pixel in
the PNG are multiplied against the RGB values of the target screen. The default is none, meaning no
effect.
-[no]antialias / -[no]aa
Enables antialiased line rendering for vector games. The default is ON (-antialias).
-beam <width>
Sets the width of the vectors. This is a scaling factor against the standard vector width. A value of 1.0 will
keep the default vector line width. Smaller values will reduce the width, and larger values will increase
the width. The default is 1.0.
-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.
-[no]coin_lockout / -[no]coinlock
Enables simulation of the coin lockout feature that is implemented on a number of 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).
-ctrlr <controller>
Enables support for special controllers. Configuration files are loaded from the ctrlrpath. They are in the
same format as the .cfg files that are saved, but only control configuration data is read from the file. The
default is NULL (no controller file).
-[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 game. The default is OFF
(-nomouse).
-[no]joystick / -[no]joy
Controls whether or not MAME makes use of joystick/gamepad controllers. When this is enabled, MAME
will ask DirectInput about which controllers are connected. The default is OFF (-nojoystick).
-[no]lightgun / -[no]gun
Controls whether or not MAME makes use of lightgun controllers. Note that most lightguns map to
the mouse, so using -lightgun and -mouse together may produce strange results. The default is OFF
(-nolightgun).
-[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
single keyboard. Turning this option on will enable MAME to report keypresses on different keyboards
independently. The default is OFF (-nomultikeyboard).
-[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).
-[no]steadykey / -[no]steady
Some games require two or more buttons to be pressed at exactly the same time to make special moves.
Due to limitations in the keyboard 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 responsive. The default is
OFF (-nosteadykey)
-[no]ui_active
Enable user interface on top of emulated keyboard (if present). The default is OFF (-noui_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 guns 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 reloads. The default is OFF (-nooffscreen_reload).
-joystick_map <map> / -joymap <map>
Controls how joystick values map to digital joystick controls. MAME accepts all joystick input
from the system as analog data. For true analog joysticks, this needs to be mapped down to the
usual 4-way or 8-way digital joystick values. To do this, MAME divides the analog range into
a 9x9 grid. It then takes the joystick axis position (for X and Y axes only), maps it to this grid,
and then looks up a translation from a joystick map. This parameter allows you to specify the
map. 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 game.
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:
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:
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 symmetric with data in columns 0-4; and any missing data in colums 0-4 is assumed
to be copies of the previous data. The same logic applies to missing rows, except that up/down
symmetry is assumed.
By using these shorthands, the 81 character map can be simply specified by this 11 character
string: 7778...4445
Looking at the first row, 7778 is only 4 characters long. The 5th entry cant use symmetry, so it
is assumed to be equal to the previous 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.
-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.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.
-natural
Allows user to specify whether or not to use a natural keyboard or not. This allows you to start your game
or system in a native mode, depending on your region, allowing compatability for non-QWERTY
style keyboards. The default is OFF (-nonatural)
-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)
-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.
Debugging options
-[no]verbose / -[no]v
Displays internal diagnostic information. This information is very useful for debugging problems with
your configuration. IMPORTANT: when reporting bugs, please run with mame -verbose and include the
resulting information. The default is OFF (-noverbose).
-[no]oslog
Output error.log data to the system debugger. The default is OFF (-nooslog).
-[no]log
Creates a file called error.log which contains all of the internal log messages generated by the MAME
core and game drivers. The default is OFF (-nolog).
-[no]debug
Activates the integrated debugger. By default, the debugger is entered by pressing the tilde (~) key during
emulation. It is also entered immediately at startup. The default is OFF (-nodebug).
-debugscript <filename>
Specifies a file that contains a list of debugger commands to execute immediately upon startup. The
default is NULL (no commands).
-[no]update_in_pause
Enables updating of the main screen bitmap while the game is paused. This means that the
VIDEO_UPDATE callback will be called repeatedly during pause, which can be useful for debugging.
The default is OFF (-noupdate_in_pause).
-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
-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.
-comm_remotehost <string>
Remote address to connect 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
-comm_remoteport <string>
Remote port to connect to. This can be any traditional communications port as an unsigned 16-bit integer
(0-65535). The default value is 15122.
-ramsize [n]
Allows you to change the default RAM size (if supported by driver).
-confirm_quit
Display a Confirm Quit dialong to screen on exit, requiring one extra step to exit MAME. The default is
OFF (-noconfirm_quit).
-ui_mouse
Displays a mouse cursor when using the built-in UI for MAME. The default is (-noui_mouse).
-autoboot_command <command>
Command string to execute after machine boot (in quotes ). To issue a quote to the emulation, use
in the string. Using \n will issue a create a new line, issuing what was typed prior as a command.
Example: -autoboot_command load $,8,1\n
-autoboot_delay [n]
Timer delay (in seconds) to trigger command execution on autoboot.
-autoboot_script / -script [filename.lua]
File containing scripting to execute after machine boot.
-language <language>
Specify a localization language found in the languagepath tree.
This section contains configuration options that are specific to the native (non-SDL) Windows version of MAME.
Debugging options
-[no]oslog
Outputs the error.log data to the Windows debugger. This can be used at the same time as -log to output
the log data to both targets as well. Default is OFF (-nooslog).
-watchdog <duration> / -wdog <duration>
Enables an internal watchdog timer that will automatically kill the MAME process if more than <dura-
tion> seconds passes without a frame update. Keep in mind that some games 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.
-debugger_font <fontname> / -dfont <fontname>
Specifies the name of the font to use for debugger windows. By default, the font is Lucida Console.
-debugger_font_size <points> / -dfontsize <points>
Specifies the size of the font to use for debugger windows, in points. By default, this is set to 9pt.
Performance options
-priority <priority>
Sets the thread priority for the MAME threads. By default the priority is left alone to guarantee proper
cooperation with other applications. The valid range is -15 to 1, with 1 being the highest priority. The
default is 0 (NORMAL priority).
-numprocessors <auto|value> / -np <auto|value>
Specify the number of processors to use for work queues. Specifying auto will use the value reported by
the system or environment variable OSDPROCESSORS. To avoid abuse, this value is internally limited
to 4 times the number of processors reported by the system. The default is auto.
-profile [n]
Enables profiling, specifying the stack depth of [n] to track.
-bench [n]
Benchmark for [n] number of emulated seconds; implies the command string:
-str [n] -video none -sound none -nothrottle
Video options
-video <bgfx|gdi|d3d|none>
Specifies which video subsystem to use for drawing. Using bgfx specifies the new hardware accelerated
renderer. By specifying gdi here, you tell MAME to render video using older standard Windows graphics
drawing calls. This is the slowest but most compatible option on older versions of Windows. Specifying
d3d tells MAME to use Direct3D for rendering. This produces the highest quality output and enables all
rendering options. It is recommended if you have a semi-recent (2002+) video card or onboard Intel video
of the HD3000 line or better. The final option none displays no windows and does no drawing. This
is primarily present for doing CPU benchmarks without the overhead of the video system. The default is
d3d.
-numscreens <count>
Tells MAME how many output windows to create. For most games, a single output window is all you
need, but some games originally used multiple screens (e.g. Darius, PlayChoice-10). 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.
-[no]window / -[no]w
Run MAME in either a window or full screen. The default is OFF (-nowindow).
-[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
smallest supported size. This option only has an effect when the -window option is used. The default is
ON (-maximize).
-[no]keepaspect / -[no]ka
Enables aspect ratio enforcement. When this option is on, the games proper aspect ratio (generally 4:3
or 3:4) is enforced, so you get the game looking like it should. When running in a window with this
option on, you can only resize the window to the proper aspect ratio, unless you are holding down the
CONTROL key. By turning the option off, the aspect ratio is allowed to float. In full screen mode, this
means that all games will stretch to the full screen size (even vertical games). In window mode, it means
that you can freely resize the window without any constraints. The default is ON (-keepaspect).
The MAME team heavily suggests you leave this at default. Stretching games beyond their original aspect
ratio will mangle the appearance of the game in ways that no filtering or HLSL can repair.
-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 by a factor of <amount> before being scaled. With -video d3d, this
produces a less blurry image at the expense of some speed. The default is 1.
-[no]waitvsync
Waits for the refresh period on your computers monitor to finish before starting to draw video to your
screen. If this option is off, MAME will just draw to the screen at any old time, even in the middle of a
refresh cycle. This can cause tearing artifacts, where the top portion of the screen is out of sync with
the bottom portion. Tearing is not noticeable on all games, and some people hate it more than others.
However, if you turn this option on, you will waste more of your CPU cycles waiting for the proper time
to draw, so you will see a performance hit. You should only need to turn this on in windowed mode. In
full screen mode, it is only needed if -triplebuffer does not remove the tearing, in which case you should
use -notriplebuffer -waitvsync. Note that this option does not work with -video gdi mode. The default
is OFF (-nowaitvsync).
-[no]syncrefresh
Enables speed throttling only to the refresh of your monitor. This means that the games actual refresh rate
is ignored; however, the sound code still attempts to keep up with the games original refresh rate, so you
may encounter sound problems. This option is intended mainly for those who have tweaked their video
cards settings to provide carefully matched refresh rate options. Note that this option does not work with
-video gdi mode. The default is OFF (-nosyncrefresh).
Direct3D-specific options
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 number 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.
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.
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 parameters apply to the specific window. The
-resolution parameter applies to all windows. The window-specific options override values from the all
window option.
-view <viewname>
-view0 <viewname>
-view1 <viewname>
-view2 <viewname>
-view3 <viewname>
Specifies the initial view setting for each window. The <viewname> does not need to be a perfect match;
rather, it will select the first view whose name matches all the characters specified by <viewname>. For
example, -view native will match the Native (15:14) view even though it is not a perfect match. The value
auto is also supported, and requests that MAME perform a default selection. The default value for these
options is auto.
The -view0, -view1, -view2, -view3 parameters apply to the specific window. The -view parameter applies to
all windows. The window-specific options override values from the all window option.
-[no]triplebuffer / -[no]tb
Enables or disables triple buffering. Normally, MAME just draws directly to the screen, without any
fancy buffering. But with this option enabled, MAME creates three buffers to draw to, and cycles between
them in order. It attempts to keep things flowing such that one buffer is currently displayed, the second
buffer is waiting to be displayed, and the third buffer is being drawn to. -triplebuffer will override -
waitvsync, if the buffer is successfully created. This option does not work with -video gdi. The default
is OFF (-notriplebuffer).
-[no]switchres
Enables resolution switching. This option is required for the -resolution* 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 games, which requires significant tweaking. This
option is also useful 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. The default is OFF (-noswitchres).
-full_screen_brightness <value> / -fsb <value>
Controls the brightness, or black level, of the entire display. The standard value is 1.0. Selecting lower
values (down to 0.1) will produce a darkened display, while selecting higher values (up to 2.0) will give a
brighter display. Note that not all video cards have hardware to support this option. This option does not
work with -video gdi. The default is 1.0.
-full_screen_contrast <value> / -fsc <value>
Controls the contrast, or white level, of the entire display. The standard value is 1.0. Selecting lower
values (down to 0.1) will produce a dimmer display, while selecting higher values (up to 2.0) will give a
more saturated display. Note that not all video cards have hardware to support this option. This option
does not work with -video gdi. The default is 1.0.
-full_screen_gamma <value> / -fsg <value>
Controls the gamma, which produces a potentially nonlinear black to white ramp, for the entire display.
The standard value is 1.0, which gives a linear ramp from black to white. Selecting lower values (down
to 0.1) will increase the nonlinearity toward black, while selecting higher values (up to 3.0) will push the
nonlinearity toward white. Note that not all video cards have hardware to support this option. This option
does not work with -video gdi. The default is 1.0.
Sound options
-sound <dsound|sdl|none>
Specifies which sound subsystem to use. none disables sound altogether. The default is dsound.
-audio_latency <value>
This controls the amount of latency built into the audio streaming. By default MAME tries to keep the
DirectSound audio buffer between 1/5 and 2/5 full. On some systems, this is pushing it too close to the
edge, and you get poor sound sometimes. The latency parameter controls the lower threshold. The default
is 1 (meaning lower=1/5 and upper=2/5). Set it to 2 (-audio_latency 2) to keep the sound buffer between
2/5 and 3/5 full. If you crank it up to 4, you can definitely notice audio lag.
-[no]dual_lightgun / -[no]dual
Controls whether or not MAME attempts to track two lightguns connected at the same time. This option
requires -lightgun. This option is a hack for supporting certain older dual lightgun setups. If you have
multiple lightguns connected, you will probably just need to enable -mouse and configure each lightgun
independently. The default is OFF (-nodual_lightgun).
This section contains configuration options that are specific to any build supported by SDL (including Windows where
compiled as SDL instead of native).
In addition to the keys described in config.txt, the following additional keys are defined for SDL-specific versions of
MAME:
Debugging options
-[no]oslog
Outputs the error.log data to the stderr TTY channel (usually the command line window MAME was
started in). This can be used at the same time as -log to output the log data to both targets as well. Default
is OFF (-nooslog).
-watchdog <duration> / -wdog <duration>
Enables an internal watchdog timer that will automatically kill the MAME process if more than <dura-
tion> seconds passes without a frame update. Keep in mind that some games 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.
Performance options
Enable output of benchmark data on the SDL video subsystem, including your systems video driver, X
server (if applicable), and OpenGL stack in -video opengl mode.
-bench [n]
Benchmark for [n] number of emulated seconds; implies the command string: -str [n] -video none -sound
none -nothrottle. Default is OFF (-nobench)
Video options
-video <soft|opengl|none>
Specifies which video subsystem to use for drawing. The default for Mac OS X is opengl because OS
X is guaranteed to have a compliant OpenGL stack. The default on all other systems is soft.
-numscreens <count>
Tells MAME how many output windows to create. For most games, a single output window is all you
need, but some games originally used multiple 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.
-[no]window / -[no]w
Run MAME in either a window or full screen. The default is OFF (-nowindow).
-[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
smallest supported size. This option only has an effect when the -window option is used. The default is
ON (-maximize).
-[no]keepaspect / -[no]ka
Enables aspect ratio enforcement. When this option is on, the games proper aspect ratio (generally 4:3
or 3:4) is enforced, so you get the game looking like it should. When running in a window with this
option on, you can only resize the window to the proper aspect ratio, unless you are holding down the
CONTROL key. By turning the option off, the aspect ratio is allowed to float. In full screen mode, this
means that all games will stretch to the full screen size (even vertical games). In window mode, it means
that you can freely resize the window without any constraints. The default is ON (-keepaspect).
-[no]unevenstretch
Allow non-integer stretch factors allowing for great window sizing flexability. The default is ON. (-
unevenstretch)
-[no]centerh
Center horizontally within the view area. Default is ON (-centerh).
-[no]centerv
Center vertically within the view area. Default is ON (-centerv).
-[no]waitvsync
Waits for the refresh period on your computers monitor to finish before starting to draw video to your
screen. If this option is off, MAME will just draw to the screen at any old time, even in the middle of a
refresh cycle. This can cause tearing artifacts, where the top portion of the screen is out of sync with
the bottom portion. Tearing is not noticeable on all games, and some people hate it more than others.
However, if you turn this option on, you will waste more of your CPU cycles waiting for the proper time
to draw, so you will see a performance hit. You should only need to turn this on in windowed mode. In full
screen mode, it is only needed if -triplebuffer does not remove the tearing, in which case you should use
-notriplebuffer -waitvsync. Note that 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. The default is OFF (-nowaitvsync).
-[no]syncrefresh
Enables speed throttling only to the refresh of your monitor. This means that the games actual refresh rate
is ignored; however, the sound code still attempts to keep up with the games original refresh rate, so you
may encounter sound problems. This option is intended mainly for those who have tweaked their video
cards settings to provide carefully matched refresh rate options. The default is OFF (-nosyncrefresh).
-scalemode
Scale mode: none, async, yv12, yuy2, yv12x2, yuy2x2 (-video soft only). Default is none.
-[no]filter / -[no]flt
Enable bilinear filtering on the game screen graphics. When disabled, point filtering is applied, which
is crisper but leads to scaling artifacts. If you dont like the filtered look, you are probably better off
increasing the -prescale value rather than turning off filtering altogether. The default is ON (-filter).
-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 by a factor of <amount> before being scaled. This produces a less blurry
image at the expense of some speed and also increases the effective resolution of non-screen elements
such as artwork and fonts. The default is 1.
These 4 options are for compatibility in -video opengl. If you report rendering artifacts you may be asked to try
messing with them by the devs, but normally they should be left at their defaults which results in the best possible
video performance.
-[no]gl_forcepow2texture
Always use only power-of-2 sized textures (default off )
-[no]gl_notexturerect
Dont use OpenGL GL_ARB_texture_rectangle (default on)
-[no]gl_vbo
Enable OpenGL VBO, if available (default on)
-[no]gl_pbo
Enable OpenGL PBO, if available (default on)
-gl_glsl
Enable OpenGL GLSL, if available (default off )
-gl_glsl_filter
Enable OpenGL GLSL filtering instead of FF filtering 0-plain, 1-bilinear (default is 1)
-glsl_shader_mame0
Custom OpenGL GLSL shader set MAME bitmap 0 [todo: better details on usage at some point. See
http://forums.bannister.org/ubbthreads.php?ubb=showflat&Number=100988#Post100988 ]
-glsl_shader_mame1
Custom OpenGL GLSL shader set MAME bitmap 1
-glsl_shader_mame2
Custom OpenGL GLSL shader set MAME bitmap 2
-glsl_shader_mame3
Custom OpenGL GLSL shader set MAME bitmap 3
-glsl_shader_mame4
Custom OpenGL GLSL shader set MAME bitmap 4
-glsl_shader_mame5
Custom OpenGL GLSL shader set MAME bitmap 5
-glsl_shader_mame6
Custom OpenGL GLSL shader set MAME bitmap 6
-glsl_shader_mame7
Custom OpenGL GLSL shader set MAME bitmap 7
-glsl_shader_mame8
Custom OpenGL GLSL shader set MAME bitmap 8
-glsl_shader_mame9
Custom OpenGL GLSL shader set MAME bitmap 9
-glsl_shader_screen0
Custom OpenGL GLSL shader screen bitmap 0
-glsl_shader_screen1
Custom OpenGL GLSL shader screen bitmap 1
-glsl_shader_screen2
Custom OpenGL GLSL shader screen bitmap 2
-glsl_shader_screen3
Custom OpenGL GLSL shader screen bitmap 3
-glsl_shader_screen4
Custom OpenGL GLSL shader screen bitmap 4
-glsl_shader_screen5
Custom OpenGL GLSL shader screen bitmap 5
-glsl_shader_screen6
Custom OpenGL GLSL shader screen bitmap 6
-glsl_shader_screen7
Custom OpenGL GLSL shader screen bitmap 7
-glsl_shader_screen8
Custom OpenGL GLSL shader screen bitmap 8
-glsl_shader_screen9
Custom OpenGL GLSL shader screen bitmap 9
-gl_glsl_vid_attr
Enable OpenGL GLSL handling of brightness and contrast. Better RGB game performance. Default is
on.
Per-window options
NOTE: Multiple Screens may fail to work correctly on some Macintosh machines as of right now.
-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 a number from 1 to the number 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.
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.
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. The default value for these options is auto.
The -resolution0, -resolution1, -resolution2, -resolution3 parameters apply to the specific window. The
-resolution parameter applies to all windows. The window-specific options override values from the all
window option.
-view <viewname>
-view0 <viewname>
-view1 <viewname>
-view2 <viewname>
-view3 <viewname>
Specifies the initial view setting for each window. The <viewname> does not need to be a perfect match;
rather, it will select the first view whose name matches all the characters specified by <viewname>. For
example, -view native will match the Native (15:14) view even though it is not a perfect match. The value
auto is also supported, and requests that MAME perform a default selection. The default value for these
options is auto.
The -view0, -view1, -view2, -view3 parameters apply to the specific window. The -view parameter applies to
all windows. The window-specific options override values from the all window option.
-[no]switchres
Enables resolution switching. This option is required for the -resolution* 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 games, which requires significant tweaking. This
option is also useful on LCD displays, since they run with a fixed resolution and switching resolutions on
them is just silly. The default is OFF (-noswitchres).
Sound options
-sound <sdl|none>
Specifies which sound subsystem to use. none disables sound altogether. The default is sdl.
-audio_latency <value>
This controls the amount of latency built into the audio streaming. By default MAME tries to keep the
audio buffer between 1/5 and 2/5 full. On some systems, this is pushing it too close to the edge, and you
get poor sound sometimes. The latency parameter controls the lower threshold. The default is 1 (meaning
lower=1/5 and upper=2/5). Set it to 2 (-audio_latency 2) to keep the sound buffer between 2/5 and 3/5
full. If you crank it up to 4, you can definitely notice audio lag.
-keymap
Enable keymap. Default is OFF (-nokeymap)
-keymap_file <file>
Keymap Filename. Default is keymap.dat.
-uimodekey <key>
Key to toggle keyboard mode. Default is SCRLOCK
-joy_idx1 <name>
Name of joystick mapped to joystick #1, default is auto.
-joy_idx2 <name>
Name of joystick mapped to joystick #2, default is auto.
-joy_idx3 <name>
Name of joystick mapped to joystick #3, default is auto.
-joy_idx4 <name>
Name of joystick mapped to joystick #4, default is auto.
-joy_idx5 <name>
Name of joystick mapped to joystick #5, default is auto.
-joy_idx6 <name>
-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 default)
-gl_lib <driver>
Alternative libGL.so to use; auto for system default
FIVE
ADVANCED CONFIGURATION
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.
1. The command line is parsed first, and any settings passed that way will take priority 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 config file at that new location (and if so, change
settings using that file)
3. DEBUG.INI if in debug mode. This is an advanced config file, most people wont need to use it or be con-
cerned by it.
4. System-specific INI files where appropriate (e.g. NEOGEO_NOSLOT.INI or CPS2.INI) As an example,
Street Fighter Alpha is a CPS2 game, and so CPS2.INI would be loaded here.
5. Monitor orientation INI file (either HORIZONT.INI or VERTICAL.INI) Pac-Man, for one example, is a
vertical monitor setup, so it would load VERTICAL.INI. Street Fighter Alpha is a horizontal game, so it
loads HORIZONT.INI.
6. System-type INI files (ARCADE.INI, CONSOLE.INI, COMPUTER.INI, or OTHERSYS.INI) Both Pac-
Man and Street Fighter Alpha are arcade games, so ARCADE.INI would be loaded here. Atari 2600
would load CONSOLE.INI.
7. Screen-type INI file (VECTOR.INI for vector games, RASTER.INI for raster games, LCD.INI for LCD games)
Pac-Man and Street Fighter Alpha are raster, so RASTER.INI gets loaded here. Tempest is a vector
monitor game, and VECTOR.INI would be loaded here.
8. Source INI files. This is an advanced config file, most people wont need to use it and it can be safely ignored.
MAME will attempt to load SOURCE/SOURCEFILE.INI and SOURCEFILE.INI, where sourcefile is
the actual filename of the source code file. mame -listsource <game> will show the source file for a given
game.
For instance, Banprestos Sailor Moon, Atluss Dodonpachi, and Nihon Systems Dangun Feveron all share
a large amount of hardware and are grouped into the CAVE.C file, meaning they all parse source/cave.ini
9. Parent INI file. For example, if running Pac-Man, which is a clone of Puck-Man, itd be PUCKMAN.INI
10. Driver INI file. Using our previous example of Pac-Man, this would be PACMAN.INI.
55
MAME Documentation, Release 0.174
1. Alcon, which is the US clone of Slap Fight. (mame alcon) Command line, MAME.INI, VERTICAL.INI,
ARCADE.INI, RASTER.INI, SLAPFGHT.INI, and lastly ALCON.INI (remember command line param-
eters take precedence over all else!)
2. Super Street Fighter 2 Turbo (mame ssf2t) Command line, MAME.INI, HORIZONT.INI, ARCADE.INI,
RASTER.INI, CPS2.INI, and lastly SSF2T.INI (remember command line parameters take precedence
over all else!)
Some users may have a wall-mounted or otherwise rotatable monitor, and may wish to actually play vertical games
with the rotated display. The easiest way to accomplish this is to put your rotation modifiers into VERTICAL.INI,
where they will only affect vertical games.
[todo: more practical examples]
MAME has a specific order it uses when checking for user files such as ROM sets and cheat files.
Lets use an example of the cheat file for AfterBurner 2 for Sega Genesis/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, except 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.]
This is an advanced feature for alternative shifter handling for certain 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 people who have this specific need, have the hardware to take advantage of it, and the knowledge
to use it correctly.
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 mame64 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.
The line you need to edit will be the port line defining the actual input. For Spy Hunter, thats going to be
P1_BUTTON2. Add toggle=no to the end of the tag, like follows:
Save and exit. To disable this, simply remove the toggle=no from each desired .CFG input.
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 requires 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 guidelines will be provided here to help you, but you may also wish to ask for opinions on
popular MAME-centric forums.
Resolution is a very important subject for HLSL settings. You will want MAME to be using the native resolution of
your monitor to avoid additional distortion and lag created by your monitor upscaling the display image.
While most arcade machines used a 4:3 ratio display (or 3:4 for vertically 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 artwork around the main display, and should you have the necessary artwork files,
MAME will display that artwork. Turn the artwork view to Cropped for best results.
Some older LCD displays used a native resolution of 1280x1024 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.
You will need to have followed the initial MAME setup instructions elsewhere in this manual before beginning. Official
MAME distributions include BGFX as of 172, so you dont 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 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 referenced 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 config files, youll want to copy the
BGFX settings from MAME.INI to one of the other config 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.
bgfx_backend
Selects a rendering backend for BGFX to use. Possible choices include d3d9, d3d11, opengl, and metal. The
default is auto, which will let MAME choose the best selection for you.
bgfx_debug
Enables BGFX debugging features. Most users will not need to use this.
bgfx_screen_chains
This dictates how to handle BGFX rendering on a per-display basis. Possible choices include hlsl, unfiltered,
and default.
We make a distinction between emulated device screens (which well call a screen) and physical displays
(which well call a window, set by -numscreens) here. We use colons (:) to seperate windows, and commas (,)
to seperate screens. Commas always go on the outside of the chain (see House Mannequin example)
On a combination of a single window, single screen case, such as Pac-Man on one physical PC monitor, you
can specify one entry like:
bgfx_screen_chains hlsl
Things get only slightly more complicated when we get to multiple windows and multiple screens.
On a single window, multiple screen game, such as Darius on one physical PC monitor, specify multiple entries
(one per window) like:
bgfx_screen_chains hlsl,hlsl,hlsl
This also works with single screen games where you are mirroring the output to more than one physical
display. For instance, you could set up Pac-Man to have one unfiltered output for use with video broadcasting
while a second display is set up HLSL for playing on.
On a mulitple window, multiple screen game, such as Darius on three physical PC monitors, specify multiple
entries (one per window) like:
bgfx_screen_chains hlsl:hlsl:hlsl
Another example game would be Taisen Hot Gimmick, which used two CRTs to show individual player hands
to just that player. If using two windows (two physical displays):
bgfx_screen_chains hlsl:hlsl
One more special case is that Nichibutsu had a special cocktail mahjongg cabinet that used a CRT in the middle
along with two LCD displays to show each player their hand. We would want the LCDs to be unfiltered and
untouched as they were, while the CRT would be improved through HLSL. Since we want to give each player
their own full screen display (two physical monitors) along with the LCD, well go with:
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.
Warning: Currently BGFX HLSL settings are not saved or loaded from any configuration files. This is expected to
change in the future.
Start by loading MAME with the game of your choice (e.g. mame pacman)
The tilde key (~) brings up the on-screen display options. Use up and down to go through the various settings, while
left and right will allow you to change that setting. Results will be shown in real time as youre changing these settings.
Note that settings are individually changable on a per-screen basis.
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 HLSL comes into the picture.
HLSL simulates most of the effects that a CRT arcade monitor has on the video, making the result look a lot more
authentic. However, HLSL requires some effort on the 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 guidelines will be provided here to help you, but you may also wish to ask for opinions on
popular MAME-centric forums.
Resolution is a very important subject for HLSL settings. You will want MAME to be using the native resolution of
your monitor to avoid additional distortion and lag created by your monitor upscaling the display image.
While most arcade machines used a 4:3 ratio display (or 3:4 for vertically 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 artwork around the main display, and should you have the necessary artwork files,
MAME will display that artwork. Turn the artwork view to Cropped for best results.
Some older LCD displays used a native resolution of 1280x1024 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.
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 dont 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 latter 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 youre ready to begin.
Several presets have been included in the INI folder with MAME, allowing for good quick starting points for Nintendo
Game Boy, Nintendo Game Boy Advance, Raster, and Vector monitor settings.
For multiple, complicated to explain reasons, HLSL settings are no longer saved when you exit MAME. This means
that while tweaking settings 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 allow you to change that setting. Results will be shown in real time as youre changing these settings.
Once youve 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 MAMEs config files, youll want to copy the
HLSL settings from MAME.INI to one of the other config files and make changes there.
For instance, once youve 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.
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.
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_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.
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
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
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.
This setting determines strength of the quadric distortion of the screen image.
This setting determines strength of the qubic 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
This setting determines strength of distortion of the screen corners, which does not affect the distortion of
screen image itself.
The corners of the display can be rounded off through the use of this setting.
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 files GetSpotAddend section, you can change the location.
Range is from 0.00 to 1.00.
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.
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.
The overall spacing of the scanlines is set with this option. Setting it at 1 represents consistent alternating
spacing between display lines and scanlines.
This determines the overall size of each scanline. Setting lower than 1 makes them thinner, larger than 1 makes
them thicker.
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
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.
This will give scanlines a glow/overdrive effect, softening and smoothing the top and bottom of each scanline.
Specifies the wobble or jitter of the scanlines, causing them to jitter on the monitor. Warning: Higher settings
may hurt your eyes.
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)
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.
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.
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
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
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.
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.
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.
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.
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
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.
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.
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. Addi-
tionally, 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:
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 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 requires 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 guidelines will be provided here to help you, but you may also wish to ask for opinions on
popular MAME-centric forums.
Resolution is a very important subject for GLSL settings. You will want MAME to be using the native resolution of
your monitor to avoid additional distortion and lag created by your monitor upscaling the display image.
While most arcade machines used a 4:3 ratio display (or 3:4 for vertically 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 artwork around the main display, and should you have the necessary artwork files,
MAME will display that artwork. Turn the artwork view to Cropped for best results.
Some older LCD displays used a native resolution of 1280x1024, which is 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 on-par with a
4:3 monitor.
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 youre ready to begin.
For multiple, complicated to explain reasons, GLSL settings are no longer saved when you exit MAME. This means
that while tweaking settings 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 allow you to change that setting. Results will be shown in real time as youre changing these settings.
Once youve 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 MAMEs config files, youll want to copy the
GLSL settings from MAME.INI to one of the other config files and make changes there.
For instance, once youve 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
gl_glsl_filter
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
By default, the mapping between devices and controller IDs is not stable. For instance, a gamepad controller may be
assigned to Joy 1 initially, but after a reboot, it may get re-assigned to Joy 3.
The reason is that MAME enumerates attached devices and assigns controller IDs based on the enumeration order.
Factors that can cause controller IDs to change include plugging / unplugging USB devices, changing ports / hubs and
even system reboots.
It is quite cumbersome to ensure that controller IDs are always correct.
Thats where the mapdevice configuration setting comes into the picture. This setting allows you to map a device id
to a controller ID, ensuring that the specified device always maps to the same controller ID in MAME.
Usage of mapdevice
The mapdevice xml element is specified under the input xml element in the controller configuration file. It requires
two attributes, device and controller. NOTE: This setting only take effect when added to the ctrlr config file.
The device attribute specifies the id of the device to match. It may also be a substring of the id. To see the list of
available devices, enable verbose output and available devices will then be listed to the console at startup (more on
this below).
The controller attribute specifies the MAME controller ID. It is made up of a controller class (i.e. JOYCODE,
GUNCODE, MOUSECODE) and controller index. For example: JOYCODE_1.
Example
Heres an example:
<mameconfig version=10>
<system name=default>
<input>
<mapdevice device=VID_D209&PID_1601 controller=GUNCODE_1 />
<mapdevice device=VID_D209&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>
...
How did we obtain the device ids in the above example? Easy!
Run MAME with -v parameter to enable verbose output. It will then list available devices include the corresponding
device id to the console.
Here an example:
Input: Adding Joy #1: ATRAK Device #2 (device id: ATRAK Device #2)
Input: Adding Joy #2: XInput Player 1 (device id: XInput Player 1)
Input: Adding Joy #3: XInput Player 2 (device id: XInput Player 2)
Furthermore, when devices are mapped using mapdevice, youll see that in the verbose logging too, such as:
SIX
This section covers various extra tools that come with your MAME distribution (e.g. imgtool)
Imgtool is a tool for the maintenance and manipulation of disk and other types of images that MAME users need to
deal with. Functions include 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 manner 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 subcommands are applicable or supported for
different image formats.
Imgtool Subcommands
create
imgtool create <format> <imagename> [(createoption)=value]
73
MAME Documentation, Release 0.174
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
Castool is a tool for the maintenance and manipulation of cassette images that MAME users need to deal with. MAME
directly supports .WAV audio 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 instructions. Commands are invoked in a manner
along the lines of this:
castool convert <format> <image> <output>
<format> is the format of the image
<image> is the filename of the image youre converting from
<output> 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
BBC
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 automat-
ically close when you exit SDLMAME.
pngcmp
This tool is used in regression testing to compare PNG screenshot results with the runtest.cmd script found in the
source archive. This script works only on Microsoft Windows.
nltool
Discrete component conversion tool. Most users will not need to work with this.
nlwav
Discrete component conversion and testing tool. Most users will not need to work with this.
jedutil
PAL/PLA/PLD/GAL dump handling tool. It can convert between the industry-standard JED format and MAMEs
proprietary packed binary format and it can show logic equations for the types of devices it knows the internal logic
of. Most users will not need to work with this.
ldresample
This tool recompresses video data for laserdisc and VHS dumps. Most users will not need to work with this.
ldverify
This tool is used for comparing laserdisc or VHS CHD images with the source AVI. Most users will not need to work
with this.
unidasm
Universal disassembler for many of the architectures supported in MAME. Most users will not need to work with this.
SEVEN
TECHNICAL SPECIFICATIONS
This section covers technical specifications useful to programmers working on MAMEs source or working on LUA
scripts that run within the MAME framework.
The device_memory_interface
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 (logically) address/data bus other devices can be connected
to. Its mainly, but not only, cpus.
The interface allows for up to four address spaces, numbered 0-3, with symbolic names associated to them in
emumem.h for historical reasons.
Numeric ID Symbolic ID Symbolic name
0 AS_0 AS_PROGRAM
1 AS_1 AS_DATA
2 AS_2 AS_IO
3 AS_3 AS_DECRYPTED_OPCODES
2. Setup
The device must override that method to provide, for each of the four address spaces, either an address_space_config
describing the spaces configucation or nullptr if the space is not to be created.
The has_configured_map method allows to test in the memory_space_config method whether an address_map
has been associated with a given space. That allows to implement optional memory spaces, such as
AS_DECRYPTED_OPCODES in certain cpu cores. The parameterless version tests for AS_PROGRAM/AS_0.
103
MAME Documentation, Release 0.174
Associating maps to spaces is done at the machine config level, after the device declaration.
MCFG_DEVICE_ADDRESS_MAP(_space, _map)
MCFG_DEVICE_PROGRAM_MAP(_map)
MCFG_DEVICE_DATA_MAP(_map)
MCFG_DEVICE_IO_MAP(_map)
MCFG_DEVICE_DECRYPTED_OPCODES_MAP(_map)
The generic macro and the four specific ones associate a map to a given space. Address maps associated to non-existing
spaces are ignored (no warning given). devcpu.h defines MCFG_CPU_*_MAP aliases to the specific macros.
MCFG_DEVICE_REMOVE_ADDRESS_MAP(_space)
That macro removes a memory map associated to a given space. Useful when removing a map for an optional space
in a machine config derivative.
Returns a given address space post-initialization. The parameterless version tests for AS_PROGRAM/AS_0. Aborts
if the space doesnt exist.
Indicates whether a given space actually exists. The parameterless version tests for AS_PROGRAM/AS_0.
These methods override how the debugger accesses memory for a cpu. Avoid them if you can. Otherwise, prepare for
heavy-duty spelunking in complicated code.
The device_rom_interface
1. Capabilities
This interface is designed for devices which expect to have a rom connected to them on a dedicated bus. Its mostly
designed for sound chips. Other devices types may be interested but other considerations may make it impratical
(graphics decode caching for instance). The interface provides the capability of either connecting a ROM_REGION,
connecting an ADDRESS_MAP or dynamically setting up a block of memory as rom. In the region/block cases,
banking is automatically handled.
2. Setup
The constructor of the interface wants, in addition to the standard parameters, the address bus width of the dedicated
bus. In addition the endianness (if not little endian or byte-sized bus) and data bus width (if not byte) can be provided.
MCFG_DEVICE_ADDRESS_MAP(AS_0, map)
Use that method at machine config time to provide an address map for the bus to connect to. It has priority over a rom
region if one is also present.
MCFG_DEVICE_ROM(tag)
Used to select a rom region to use if a device address map is not given. Defaults to DEVICE_SELF, e.g. the device
tag.
If a rom region with a tag as given with MCFG_DEVICE_ROM if present, or identical to the device tag otherwise,
is provided in the rom description for the system, it will be automatically picked up as the connected rom. An address
map has priority over the region if present in the machine config.
At any time post- interface_pre_start, a memory block can be setup 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
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 address bus, banking is automatically setup.
5. Caveats
Using that interface makes the device derive from device_memory_interface. If the device wants to actually use the
memory interface for itself, remember that AS_0/AS_PROGRAM is used by the rom interface, and dont forget to
upcall memory_space_config.
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
A floppy disk is a disc that stores magnetic orientations on their surface disposed in a series on concentric circles called
tracks or cylinders 1 . Its main characteristics are its size (goes from a diameter of around 2.8 to 8) , its number of
writable sides (1 or 2) and its magnetic resistivity. The magnetic resistivity indicates how close magnetic orientation
changes can happen and the information kept. Thats 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. theyre one way or the opposite, theres no intermediate state. Their
direction can either be tengentially to the track, e.g in the direction or opposite to the rotation, or in the case of perpen-
dicular recording the direction is perpendicular to the disc surface (hence the name). Perpendicular recording allows
for closer orientation changes by writing the magnetic information more deeply, but arrived late in the technology
lifetime. 2.88Mb disks and the floppy children (Zip drives, etc) used perpendicular recording. For simulation purposes
the direction is not important, only the fact that only two orientations are possible is. Two more states are possible
though: a portion of a track can be demagnetized (no orientation) or damaged (no orientation and cant be written to).
A specific position in the disk rotation triggers an index pulse. That position can be detected through a hole in the
surface (very visible in 5.25 and 3 floppies for instance) or through a specific position of the rotating center (3.5
floppies, perhaps others). This index pulse is used to designate the beginning of the track, but is not used by every
system. Older 8 floppies have multiple index holes used to mark the beginning of sectors (called hard sectoring) but
one of them is positioned differently to be recognized as the track start, and the others are at fixed positions relative to
the origin one.
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 exterior (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 floppies 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
1 Cylinder is a hard-drive term somewhat improperly used for floppies. 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.
is to get more bits out of the media by keeping the minimal spacing between magnetic orientation transitions close to
the best the support can do. It seems that the complexity was not deemed worth it since almost 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 inversions, 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 threshold, creating a pulse where none should be. Too long in our case happens to be around 16-20us with no
transitions. That means a long enough zone with a fixed magnetic orientation or no orientation at all (demagnetized 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 theyre 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 detects 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 theyre over the media tolerance, but picked up by the AGC anyway, 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 its 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 rotation 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.
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 support actually done by the controller is extremely variable from one device 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 individually-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.1. Cell organization All floppy controllers, even the wonkiest like the Apple II one, start by dividing the
track in equally-sized cells. Theyre 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 angular 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 transition, 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 theyll 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 endocing 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 Frequency Modulation, or
FM. The cell size is set at slighly 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 periods of a 250Khz pulse train.
2.3.1.3. MFM encoding The FM encoding has been superseded by the Modified Frequency Modulation 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 definition 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 zeroes.
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 theyre very rare and system-specific.
2.3.1.6. Reading back encoded data Writing encoded data is easy, you only need a clock at the appropriate fre-
quency and send or not a pulse on the clock edges. Reading back the data is where the fun is. Cells are a logical
construct and not a physical measurable entity. Rotational speeds very around the defined one (+/- 2% is not rare)
and local perturbations (air turbulence, surface distance...) make the instant speed very variable in general. So to
extract the cell values stream the controller must dynamically synchronize with the pulse train that the floppy head
picks up. The principle is simple: a cell-sized duration window is build within which the presence of at least one
pulse indicates the cell is a 1, and the absence of any a 0. After reaching the end of the window the starting time
is moved appropriately to try to keep the observed pulse at the exact middle of the window. This allows to correct the
phase on every 1 cell, making the synchronization work if the rotational speed is not too off. Subsequent generations
of controllers used a Phase-Locked Loop (PLL) which vary both phase and window duration to adapt better to wrong
rotational speeds, with usually a tolerance of +/- 15%.
Once the cell data stream is extracted decoding depends on the encoding. In the FM and MFM case the only question
is to recognize data bits from clock bits, while in GCR the start position of the first group should be found. That second
level of synchronization is handled at a higher level using patterns not found in a normal stream.
Floppies have been designed for read/write random access to reasonably sized blocks of data. Track selection allows
for a first level of random 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 appropriate 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.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 correctly. 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. Thats 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. Theyre not
supposed to happen on a mastered disk though, even if there are some rare exceptions.
The floppy disk contents are represented by the class floppy_image. It contains information of the media type and a
representation of the magnetic 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 indicates 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 representing 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
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.
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 unformat-
ted/damaged cells, and MG_W for Dungeon-Master style weak bits. Converts it into the internal format.
The sizes are normalized 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.
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 §or_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 youd get by reading in order sector size-sized sectors from number 1 to sector count and
put the result in sector data.
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 ensure the
current time is the same for all devices.
Due to the way theyre usually connected to CPUs (e.g. directly on an I/O port), the control signals work
with physical instead of logical 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 running.
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 transistion.
trk00_r()
Track 0 sensor, returns 0 when on track 0.
ss_w(ss) / ss_r()
Side select
The read/write interface is designed to work asynchronously, e.g. somewhat independently of the current time.
1. 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.
2. Global structure
Parallel SCSI is built around a symmetric bus to which a number of devices 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 currently implemented chips
only handle 8). All the lines are open collector, 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 communication. 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.
3. 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:
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 parameters 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 isnt 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:device-type, i.e. scsibus:7:ncr5390 for our
controller here.
4. Creating a new SCSI device using nscsi_device
The base class nscsi_device is to be used for down-to-the-metal devices, 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. Its 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 traditional 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 theyre avail-
able. The only part often not described is the arbitration/selection, which is documented 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 number 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 youre done, youre connected with the target until the target de-asserts the busy line, either because you
asked it to or just to annoy 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.
5. 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 implementation.
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_cmdbuf[], 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.
Introduction
It is now possible to externally drive MAME via LUA scripts. This feature initially appeared in version 0.148, when a
minimal luaengine was implemented. Nowadays, the LUA interface is rich enough to let you inspect and manipu-
late devices state, access CPU registers, read and write memory, and draw a custom HUD on screen.
Internally, MAME makes extensive use of luabridge to implement this feature: the idea is to transparently expose
as many of the useful internals as possible.
Finally, a warning: The LUA API is not yet declared stable and may suddenly change without prior notice. However,
we expose methods to let you know at runtime which API version you are running against, and you can introspect
most of the objects at runtime.
Features
The API is not yet complete, but this is a partial list of capabilities currently available to LUA scripts:
machine metadata (app version, current rom, rom details)
machine control (starting, pausing, resetting, stopping)
machine hooks (on frame painting and on user events)
devices introspection (device tree listing, memory and register enumeration)
screens introspection (screens listing, screen details, frames counting)
screen HUD drawing (text, lines, boxes on multiple screens)
memory read/write (8/16/32/64 bits, signed and unsigned)
registers and states control (states enumeration, get and set)
Usage
MAME supports external scripting via LUA (>= 5.3) scripts, either written on the interactive console or loaded as a
file. To reach the console, just run MAME with -console and you will be greeted by a naked > prompt where you can
input your script.
To load a whole script at once, store it in a plain text file and pass it via -autoboot_script. Please note that script loading
may be delayed (few seconds by default), but you can override the default with the -autoboot_delay argument.
To control the execution of your code, you can use a loop-based or an event-based approach. The former is not
encouraged as it is resource-intensive and makes control flow unnecessarily complex. Instead, we suggest to register
custom hooks to be invoked on specific events (eg. at each frame rendering).
Walkthrough
>
At this point, your game is probably running in demo mode, lets pause it:
> emu.pause()
>
Even without textual feedback on the console, youll notice the game is now paused. In general, commands are quiet
and only print back error messages.
You can check at runtime which version of MAME you are running, with:
> print(emu.app_name() .. " " .. emu.app_version())
mame 0.158
We now start exploring screen related methods. First, lets enumerate available screens:
manager:machine() is the root object of your currently running machine: we will be using this often. screens is a
table with all available screens; most machines only have one main screen. In our case, the main and only screen is
tagged as :screen, and we can further inspect it:
> -- let's define a shorthand for the main screen
> s = manager:machine().screens[":screen"]
> print(s:width() .. "x" .. s:height())
320x224
We have several methods to draw on the screen a HUD composed of lines, boxes and text:
> -- we define a HUD-drawing function, and then call it
> function draw_hud()
>> s:draw_text(40, 40, "foo"); -- (x0, y0, msg)
>> s:draw_box(20, 20, 80, 80, 0, 0xff00ffff); -- (x0, y0, x1, y1, fill-color, line-color)
>> s:draw_line(20, 20, 80, 80, 0xff00ffff); -- (x0, y0, x1, y1, line-color)
>> end
> draw_hud();
This will draw some useless art on the screen. However, when unpausing the game, your HUD needs to be refreshed
otherwise it will just disappear. In order to do this, you have to register your hook to be called on every frame repaint:
> emu.sethook(draw_hud, "frame")
All colors are expected in ARGB format (32b unsigned), while screen origin (0,0) normally corresponds to the top-left
corner.
Similarly to screens, you can inspect all the devices attached to a machine:
> for k,v in pairs(manager:machine().devices) do print(k) end
:audiocpu
:maincpu
:saveram
:screen
:palette
[...]
On some of them, you can also inspect and manipulate memory and state:
> cpu = manager:machine().devices[":maincpu"]
> -- enumerate, read and write state registers
> for k,v in pairs(cpu.state) do print(k) end
D5
SP
A4
A3
D0
PC
[...]
> print(cpu.state["D0"].value)
303
> cpu.state["D0"].value = 255
> print(cpu.state["D0"].value)
255
program
> mem = cpu.spaces["program"]
> print(mem:read_i8(0xC000))
41
Introduction
The new 6502 family implementation has been created to reach sub-instruction 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 simulation 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 section 9 shows how it will be handled.
The MOS 6502 family has been large and productive. A large number of variants exist, varying on bus sizes, I/O,
and even opcodes. Some offshots (g65c816, hu6280) even exist that live elsewhere in the mame tree. The final class
hierarchy is this:
6502
|
+------+--------+--+--+-------+-------+
| | | | | |
6510 deco16 6504 6509 n2a03 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 understood additional instructions and some I/O.
The 6504 is a pin and address-bus reduced version.
The 6509 adds internal support for paging.
The n2a03 is the NES variant with the D flag disabled and sound functionality integrated.
The 65c02 is the very first cmos variant with some additional instructions, some fixes, and most of the undocumented
instructions turned into nops. The R (Rockwell, but eventually produced by WDC too among others) variant adds a
number of bitwise instructions and also stp and wai. The SC variant, used by the Lynx portable console, looks identical
to the R variant. The S probably indicates a static-ram-cell process allowing full DC-to-max clock control.
The 65ce02 is the final evolution of the ISA in this hierarchy, with additional instructions, registers, and removals of
a lot of dummy accesses that slowed the original 6502 down by at least 25%. The 4510 is a 65ce02 with integrated
MMU and GPIO support.
All the CPUs are standard modern CPU devices, with all the normal interaction with the device infrastruc-
ture. 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, o
MCFG_M6502_DISABLE_DIRECT()
In that case, transparent decryption support is also disabled, everything 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 contention 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.
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 being 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 structures:
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 disassembly table. The
full entry text is used in the opcode description file and the dispatching methods, allowing for per-CPU variants for
identical-looking opcodes.
An entry of . was usable for unimplemented/unknown opcodes, generating ??? 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 instruction, 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 without 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, its better to leave them to helper methods (like
do_asl) which do not do bus accesses. Note that TMP and TMP2 are not local variables, theyre variables
of the class.
single-line then or else constructs must have braces around them if theyre 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. Its called
memory_interface, declared in m6502_device, and provides the following accessors:
UINT8 read(UINT16 adr) normal read
UINT8 read_sync(UINT16 adr) opcode read with sync active (first byte of opcode)
UINT8 read_arg(UINT16 adr) opcode read with sync inactive (rest of opcode)
void write(UINT16 adr, UINT8 val) normal write
UINT8 read_9(UINT16 adr) special y-indexed 6509 read, defaults to read()
void write_9(UINT16 adr, UINT8 val); special y-indexed 6509 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().
A code generator is used to support interrupting and restarting an instruction 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
youre in. Its equal to the opcode byte when 0-255, and 0xff00 means reset. Its always valid and used by instructions
like rmb. inst_substate indicates at which step we are in an instruction, but it set only when an instruction has been
interrupted. Lets 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();
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 updated. Since most instructions are started
from the beginning a specific 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 gen-
erated into a 257-entry switch statement. Pointers-to-methods being expensive to call, a virtual 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 doesnt finish). Then try to run
complete instructions. The NPC/IR dance is due to the fact that the 6502 does instruction prefetching, so the instruction
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;
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;
}
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 wont be able to do anything for some time in the future, because its 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. Its 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 usually be the case, so the cost should be minimal.
Multi-dispatch variants
Some variants currently in the process of being supported change instruction set depending on an internal flag, either
switching to a 16-bits mode or changing some register accesses to memory accesses. This is handled by having
multiple dispatch tables for the CPU, the d<CPU>.lst not being 257 entries anymore but 256*n+1. The variable
inst_state_base must select which instruction table to use at a given time. It must be a multiple of 256, and is in fact
simply OR-ed to the first instruction byte to get the dispatch table index (aka inst_state).
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 n2a03
Add decent hookups for the Apple 3 madness
EIGHT
MAME is not intended or designed to run in secure sites. It has not been security audited for such types of usage, and
has been known in the past to have flaws that could be used for malicious intent if run as administator or root.
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.
131
MAME Documentation, Release 0.174
NINE
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 contains code made available under multiple GPL-compatible licenses. A great majority of files
(over 90% including core files) are under the BSD-3-Clause License and we would encourage new contributors to
distribute files under this license.
Please note that MAME is a registered trademark of Nicola Salmoria, and permission is required to use the MAME
name, logo, or wordmark.
Copyright (C) 1997-2017 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 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General 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 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
Please see LICENSE.md for further details.
133
MAME Documentation, Release 0.174
TEN
CONTRIBUTE
135