<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en-GB">
	<id>https://wiki.mamedev.org/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Madskunk</id>
	<title>MAMEDEV Wiki - User contributions [en-gb]</title>
	<link rel="self" type="application/atom+xml" href="https://wiki.mamedev.org/api.php?action=feedcontributions&amp;feedformat=atom&amp;user=Madskunk"/>
	<link rel="alternate" type="text/html" href="https://wiki.mamedev.org/index.php?title=Special:Contributions/Madskunk"/>
	<updated>2026-04-19T13:53:06Z</updated>
	<subtitle>User contributions</subtitle>
	<generator>MediaWiki 1.41.0</generator>
	<entry>
		<id>https://wiki.mamedev.org/index.php?title=MadSkunk&amp;diff=1964</id>
		<title>MadSkunk</title>
		<link rel="alternate" type="text/html" href="https://wiki.mamedev.org/index.php?title=MadSkunk&amp;diff=1964"/>
		<updated>2009-04-28T22:20:48Z</updated>

		<summary type="html">&lt;p&gt;Madskunk: New page: MadSkunk is the pseudonym of Matthew Taylor, a UK software and web site developer.&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;MadSkunk is the pseudonym of Matthew Taylor, a UK software and web site developer.&lt;/div&gt;</summary>
		<author><name>Madskunk</name></author>
	</entry>
	<entry>
		<id>https://wiki.mamedev.org/index.php?title=Programmable_Logic_Devices_in_MAME&amp;diff=1856</id>
		<title>Programmable Logic Devices in MAME</title>
		<link rel="alternate" type="text/html" href="https://wiki.mamedev.org/index.php?title=Programmable_Logic_Devices_in_MAME&amp;diff=1856"/>
		<updated>2008-07-17T13:26:10Z</updated>

		<summary type="html">&lt;p&gt;Madskunk: New page: One of the best uses of MAME is the identification of random video game parts. Thanks to the -romident feature, you can dump a ROM or PROM from a game and pretty quickly identify what game...&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;One of the best uses of MAME is the identification of random video game parts. Thanks to the -romident feature, you can dump a ROM or PROM from a game and pretty quickly identify what game you have. If you&#039;ve ever owned a giant pile of PCBs, you&#039;ll know it&#039;s not always easy to tell.&lt;br /&gt;
&lt;br /&gt;
In theory, MAME should catalog all the programmable parts on an arcade PCB. This is useful not only because of the -romident feature, but also because if a part fails due to bit rot or corrosion or some other kind of damage (or is just missing), you can identify it, track down the data, and program yourself a new one. Up until now, we have only been really cataloging ROM-based devices, in spite of the fact that another class of device -- the Programmable Logic Device (PLD) -- is often found on PCBs, especially those dating from the mid-80&#039;s onward. PLDs are a class of device that includes PALs, GALs, and other related devices, which are programmable in much the same way that ROMs and EPROMs are.&lt;br /&gt;
&lt;br /&gt;
One of the big reasons why we haven&#039;t been including PLDs is because they are generally not stored in raw binary format, like ROM data. Rather, they are stored in a format known as the JEDEC file format (.JED), which is basically a text file containing all the data, with lots of room for programmer-inserted comments and many optional fields.&lt;br /&gt;
&lt;br /&gt;
This is not really a big problem in and of itself, except for the fact that every single programmer out there, when reading a PLD, will produce slightly different output. This in turn makes tools such as the -romident feature useless for such devices because -romident works by comparing the CRCs and SHA1s of the files, which would be different even for the same PLD read by different programmers.&lt;br /&gt;
&lt;br /&gt;
== The solution ==&lt;br /&gt;
At the creamy center of a .JED file is what is known as the &amp;quot;fuse map&amp;quot;.&lt;br /&gt;
This is the raw set of binary 1s and 0s that get programmed into the PLD. In fact, the rest of the .JED file beyond that is mostly filler:&lt;br /&gt;
some checksums, default states for unspecified fuses, etc. The final fuse map is really the important data, along with the type of device that was used (was it a GAL16V8A or a PAL16L8?)&lt;br /&gt;
&lt;br /&gt;
So the basic premise for logic devices in MAME works like this: the fuse map is stored in raw binary form, preceded by a single 32-bit (big-endian) value that specifies the total number of fuses. Each bit of the fuse map is packed into a byte from LSB to MSB. This, it turns out, is the exact format that is used for the internal fuse map checksum, so it is a natural arrangement. I decided not to try and encode the device type into the file because (a) there are way too many devices to be concerned with, and (b) many devices with similar but not identical names are equivalent. Rather, PLDs that are added to MAME should specify the device type in the filename. (Also keep in mind that if the device type were encoded into the file itself, then if person A reads a GAL16V8 and person B reads a GAL16V8A that contain identical data, they would not match.)&lt;br /&gt;
&lt;br /&gt;
How do you get data in and out of this format? Since [[MAME 0.105u4|0.105u4]], the default build of MAME will build a new utility called jedutil, which can convert a .JED file into its binary form, and vice-versa. This means that you can find the binary form of a PLD, run jedutil on it, and extract a .JED which can be programmed into a real life PLD using any standard programmer.&lt;br /&gt;
&lt;br /&gt;
So how does this help -romident? Well, if you read a PLD from a board and want to see if it matches anything we&#039;ve cataloged, you can do one of two things. You can take the resulting .JED and run jedutil on it to convert it to binary form. Or, you can just point -romident to the .JED file directly, because code has been added to the romident feature that recognizes .JED files and automatically parses them into binary form on the fly.&lt;br /&gt;
&lt;br /&gt;
The first experiments in using this will be the mid-80&#039;s and later Atari games. There are several other games out there that we already have good PAL/GAL dumps from as well. Hopefully we can produce an even more complete catalog of arcade game devices as a result.&lt;/div&gt;</summary>
		<author><name>Madskunk</name></author>
	</entry>
	<entry>
		<id>https://wiki.mamedev.org/index.php?title=How_MAME_Works&amp;diff=1855</id>
		<title>How MAME Works</title>
		<link rel="alternate" type="text/html" href="https://wiki.mamedev.org/index.php?title=How_MAME_Works&amp;diff=1855"/>
		<updated>2008-07-17T13:15:48Z</updated>

		<summary type="html">&lt;p&gt;Madskunk: Updated &amp;#039;Programmable logic...&amp;#039; /* For Driver Writers */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The following is a list of documents describing the internal workings (core) of the MAME emulator.  Most are penned by Aaron Giles.&lt;br /&gt;
&lt;br /&gt;
== Building MAME ==&lt;br /&gt;
* [[Building MAME using Microsoft Visual Studio compilers]]&lt;br /&gt;
&lt;br /&gt;
== Writing for MAME ==&lt;br /&gt;
* [[MAME Coding Conventions]]&lt;br /&gt;
&lt;br /&gt;
== For Driver Writers ==&lt;br /&gt;
* [[Game Drivers]]&lt;br /&gt;
* [[Resource Management in MAME]]&lt;br /&gt;
* [[DIP Switches in MAME]]&lt;br /&gt;
* [[MAME Interrupt Function Review]]&lt;br /&gt;
* [[Using MAME&#039;s tilemap system]]&lt;br /&gt;
* [[Programmable Logic Devices in MAME]]&lt;br /&gt;
* [[CPUs and Address Spaces]]&lt;br /&gt;
* [[Address Maps]]&lt;br /&gt;
&lt;br /&gt;
== Core Internals ==&lt;br /&gt;
* [[Filters and streams in the MAME Sound System]]&lt;br /&gt;
* [[Save State Fundamentals]]&lt;br /&gt;
* [[Using the GFX/TileMap viewer (F4)]]&lt;br /&gt;
* [[How To Use the &#039;New&#039; Renderer]]&lt;br /&gt;
* [[Layouts and Rendering for MAME Artwork System]]&lt;br /&gt;
* [[LAY File Basics - Part I]]&lt;br /&gt;
&lt;br /&gt;
== CPU Emulation ==&lt;br /&gt;
* [[Virtual TLB]]&lt;br /&gt;
* [[CPU Scheduling in MAME]]&lt;br /&gt;
&lt;br /&gt;
== Universal Dynamic Recompiler ==&lt;br /&gt;
* [[Core Concepts]]&lt;br /&gt;
* [[UML Architecture]]&lt;br /&gt;
** [[UML Control Flow Opcodes]]&lt;br /&gt;
** [[UML Internal Register Opcodes]]&lt;br /&gt;
** [[UML Integer Opcodes]]&lt;br /&gt;
** [[UML Floating Point Opcodes]]&lt;br /&gt;
* [[Dynamic Recompiler Author&#039;s Guide]]&lt;br /&gt;
* [[Back-End Author&#039;s Guide]]&lt;br /&gt;
&lt;br /&gt;
== Tips &amp;amp; Tricks ==&lt;br /&gt;
* [[Executing Code Out of a Memory Region With a Read Handler]]&lt;br /&gt;
* [[Checklist for Cleaning Up Drivers]]&lt;br /&gt;
* [[Writing Messages to the Screen In a MAME Driver]]&lt;/div&gt;</summary>
		<author><name>Madskunk</name></author>
	</entry>
	<entry>
		<id>https://wiki.mamedev.org/index.php?title=Filters_and_streams_in_the_MAME_Sound_System&amp;diff=1854</id>
		<title>Filters and streams in the MAME Sound System</title>
		<link rel="alternate" type="text/html" href="https://wiki.mamedev.org/index.php?title=Filters_and_streams_in_the_MAME_Sound_System&amp;diff=1854"/>
		<updated>2008-07-17T13:14:40Z</updated>

		<summary type="html">&lt;p&gt;Madskunk: New page: The old MAME sound design came about as a result of an evolution from the original MAME code. The problem with evolutionary coding is that at some point it gets gross and unmanageable. Thi...&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The old MAME sound design came about as a result of an evolution from the original MAME code. The problem with evolutionary coding is that at some point it gets gross and unmanageable. This is exactly what happened with the existing sound core. The flow of sound is essentially:&lt;br /&gt;
&lt;br /&gt;
 sound core -&amp;amp;gt; stream -&amp;amp;gt; mixer -&amp;amp;gt; OSD&lt;br /&gt;
&lt;br /&gt;
This isn&#039;t really so bad, except that streams were something we added later, so a lot of old code is still left directly talking to the mixer. On top of that bit of fun, some basic RC filters were added to the streams engine, and some other filter types were added to the mixer engine.&lt;br /&gt;
&lt;br /&gt;
In the new order of things, as said before, there is no separate mixer engine. In addition, the functionality of a stream has been enhanced. Originally, a stream was a single output channel of audio. Chips that output stereo, for example, would end up allocating a special &amp;quot;joined stream&amp;quot;, which was really two streams, but which act kind of like a single stream. Confused yet?&lt;br /&gt;
&lt;br /&gt;
Anyway, the new streams are more flexible. Each stream can have multiple output channels, as well as multiple input channels. Each input channel can be connected to a single output from another stream. And each output channel can be connected to multiple input channels on other streams.&lt;br /&gt;
&lt;br /&gt;
Here are some examples.&lt;br /&gt;
&lt;br /&gt;
Two chips with a single output each, routed to a mono speaker. In this case the mixer is created with two inputs and one output:&lt;br /&gt;
&lt;br /&gt;
   chip #1 ---+&lt;br /&gt;
              +---&amp;amp;gt; mixer filter ---&amp;amp;gt; mono speaker&lt;br /&gt;
   chip #2 ---+&lt;br /&gt;
&lt;br /&gt;
One mono chip with a single output, routed to both the left and right speakers. In this case we have two speaker outputs, and two mixers, each with one input. The output from the mono chip is split to the input of two filters:&lt;br /&gt;
&lt;br /&gt;
           +---&amp;amp;gt; left mixer filter ---&amp;amp;gt; left speaker&lt;br /&gt;
   chip ---+&lt;br /&gt;
           +---&amp;amp;gt; right mixer filter ---&amp;amp;gt; right speaker&lt;br /&gt;
&lt;br /&gt;
Now the creation of filters becomes dead easy. The RC filter that is in the stream engine now just becomes another sound component that you need to wire up. Let&#039;s say you want an RC filter on the output of one of the chips in the first example. It&#039;s just:&lt;br /&gt;
&lt;br /&gt;
 chip #1 ---&amp;amp;gt; RC filter---+&lt;br /&gt;
                          +---&amp;amp;gt; mixer filter ---&amp;amp;gt; mono speaker&lt;br /&gt;
 chip #2 -----------------+&lt;br /&gt;
&lt;br /&gt;
And the one other nice thing is that with a few minor tweaks to the discrete sound engine, it can also make use of these input sound streams in order to do much more complex and accurate filtering than was possible with the hacked-in basic filters.&lt;/div&gt;</summary>
		<author><name>Madskunk</name></author>
	</entry>
	<entry>
		<id>https://wiki.mamedev.org/index.php?title=How_MAME_Works&amp;diff=1853</id>
		<title>How MAME Works</title>
		<link rel="alternate" type="text/html" href="https://wiki.mamedev.org/index.php?title=How_MAME_Works&amp;diff=1853"/>
		<updated>2008-07-17T13:08:36Z</updated>

		<summary type="html">&lt;p&gt;Madskunk: Updated &amp;#039;filters and streeams...&amp;#039; /* Core Internals */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The following is a list of documents describing the internal workings (core) of the MAME emulator.  Most are penned by Aaron Giles.&lt;br /&gt;
&lt;br /&gt;
== Building MAME ==&lt;br /&gt;
* [[Building MAME using Microsoft Visual Studio compilers]]&lt;br /&gt;
&lt;br /&gt;
== Writing for MAME ==&lt;br /&gt;
* [[MAME Coding Conventions]]&lt;br /&gt;
&lt;br /&gt;
== For Driver Writers ==&lt;br /&gt;
* [[Game Drivers]]&lt;br /&gt;
* [[Resource Management in MAME]]&lt;br /&gt;
* [[DIP Switches in MAME]]&lt;br /&gt;
* [[MAME Interrupt Function Review]]&lt;br /&gt;
* [[Using MAME&#039;s tilemap system]]&lt;br /&gt;
* [http://aarongiles.com/?p=159 Programmable Logic Devices in MAME]&lt;br /&gt;
* [[CPUs and Address Spaces]]&lt;br /&gt;
* [[Address Maps]]&lt;br /&gt;
&lt;br /&gt;
== Core Internals ==&lt;br /&gt;
* [[Filters and streams in the MAME Sound System]]&lt;br /&gt;
* [[Save State Fundamentals]]&lt;br /&gt;
* [[Using the GFX/TileMap viewer (F4)]]&lt;br /&gt;
* [[How To Use the &#039;New&#039; Renderer]]&lt;br /&gt;
* [[Layouts and Rendering for MAME Artwork System]]&lt;br /&gt;
* [[LAY File Basics - Part I]]&lt;br /&gt;
&lt;br /&gt;
== CPU Emulation ==&lt;br /&gt;
* [[Virtual TLB]]&lt;br /&gt;
* [[CPU Scheduling in MAME]]&lt;br /&gt;
&lt;br /&gt;
== Universal Dynamic Recompiler ==&lt;br /&gt;
* [[Core Concepts]]&lt;br /&gt;
* [[UML Architecture]]&lt;br /&gt;
** [[UML Control Flow Opcodes]]&lt;br /&gt;
** [[UML Internal Register Opcodes]]&lt;br /&gt;
** [[UML Integer Opcodes]]&lt;br /&gt;
** [[UML Floating Point Opcodes]]&lt;br /&gt;
* [[Dynamic Recompiler Author&#039;s Guide]]&lt;br /&gt;
* [[Back-End Author&#039;s Guide]]&lt;br /&gt;
&lt;br /&gt;
== Tips &amp;amp; Tricks ==&lt;br /&gt;
* [[Executing Code Out of a Memory Region With a Read Handler]]&lt;br /&gt;
* [[Checklist for Cleaning Up Drivers]]&lt;br /&gt;
* [[Writing Messages to the Screen In a MAME Driver]]&lt;/div&gt;</summary>
		<author><name>Madskunk</name></author>
	</entry>
	<entry>
		<id>https://wiki.mamedev.org/index.php?title=Save_State_Fundamentals&amp;diff=1831</id>
		<title>Save State Fundamentals</title>
		<link rel="alternate" type="text/html" href="https://wiki.mamedev.org/index.php?title=Save_State_Fundamentals&amp;diff=1831"/>
		<updated>2008-06-28T11:39:11Z</updated>

		<summary type="html">&lt;p&gt;Madskunk: Removed the unneeded &amp;lt;code&amp;gt; tags&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Before adding save state support to a driver in MAME, it&#039;s important to understand how the overall save state system works. But first, a word of warning: it&#039;s been said in the past that adding save state support to a driver is easy. Let&#039;s clarify that by saying: adding save state support a driver is relatively easy &#039;&#039;if you know C well&#039;&#039;. How do you know whether or not you know C well? Read on...&lt;br /&gt;
&lt;br /&gt;
The basic concept of saving the state of any emulator involves first identifying all the information that represents the current state of the system, and then writing that data out to disk in some fashion for later retrieval. There are many ways this can be done. Let&#039;s look at the first step: what comprises the set of data that needs to be saved in order to fully represent the state of an emulated system?&lt;br /&gt;
&lt;br /&gt;
Some obvious candidates are:&lt;br /&gt;
# the registers and internal state on each CPU&lt;br /&gt;
# information about what each sound chip is doing&lt;br /&gt;
# the contents of all RAM (including video, palette, sound RAM) in the system&lt;br /&gt;
# all timing information&lt;br /&gt;
# the state of any peripheral devices (EEPROMs, IDE controllers, etc.)&lt;br /&gt;
# the currently selected memory bank for banked RAM/ROM&lt;br /&gt;
# the state of any driver-specific devices&lt;br /&gt;
&lt;br /&gt;
Fortunately, due to MAME&#039;s modular design, a lot of this is taken care of centrally. For example, many common CPU cores already have built-in support for saving their registers and internal state, as do many common sound chip emulators. Similarly, the MAME core handles saving the contents of all RAM and timers. And many peripheral devices can save their state as well, as long as they have some sort of &amp;lt;code&amp;gt;init()&amp;lt;/code&amp;gt; function that is called to set them up. This leaves memory banks and driver-specific devices as the two main things that need to be managed manually for each driver.&lt;br /&gt;
&lt;br /&gt;
== Saving the Data ==&lt;br /&gt;
&lt;br /&gt;
In MAME, the save state system is designed as a primarily passive system. That is, MAME&#039;s save state code assumes that all the data you want to save lives in memory somewhere. It is the client&#039;s responsibility to inform the save state system where in memory that data lies, and in what format it exists. This is generally done at initialization time. The save state system manages the rest of the process from there.&lt;br /&gt;
&lt;br /&gt;
Each piece of data that is registered is required to have a unique signature. This signature is actually a combination of three pieces of data: the module name, the instance number, and the data name.&lt;br /&gt;
&lt;br /&gt;
The module name is a string that is intended to represent the name of the module that is saving the data; generally this is the name of the CPU (e.g., &amp;quot;Z80&amp;quot;) or driver (e.g., &amp;quot;pacman&amp;quot;), but really can be any unique identifier at all.&lt;br /&gt;
&lt;br /&gt;
The instance number specifies an index within the module; for example, the first Z80 in the system will use a module name &amp;quot;Z80&amp;quot; with an instance number of 0, while the second one will also use a module name &amp;quot;Z80&amp;quot; but with an instance number of 1.&lt;br /&gt;
&lt;br /&gt;
The data name is a string that represents the name of the specific piece of data. For example, the AF register on a Z80 might be registered with a data name of &amp;quot;AF&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Keep in mind that the combination of these three pieces of data must be 100% unique within the system. Any attempt to re-register an identical set of data will abort out of MAME with an error.&lt;br /&gt;
&lt;br /&gt;
So, how do you register this data? Well, you use one of the many different registration functions available in state.h:&lt;br /&gt;
 void state_save_register_UINT8&lt;br /&gt;
 void state_save_register_INT8&lt;br /&gt;
 void state_save_register_UINT16&lt;br /&gt;
 void state_save_register_INT16&lt;br /&gt;
 void state_save_register_UINT32&lt;br /&gt;
 void state_save_register_INT32&lt;br /&gt;
 void state_save_register_UINT64&lt;br /&gt;
 void state_save_register_INT64&lt;br /&gt;
 void state_save_register_double&lt;br /&gt;
 void state_save_register_float&lt;br /&gt;
Each of these functions takes a module name, an instance number, a data name, a pointer to the variable to be saved, and a count. The first three parameters I&#039;ve already explained above. The pointer is just that: the address of where the data currently lives in memory. And the count is there so that you can register a whole array of data in a single call.&lt;br /&gt;
&lt;br /&gt;
Let&#039;s look at an example. In this example, we have several global variables that need to be saved, one of which is an array, and one of which is dynamically allocated. For this example, we register in the MACHINE_INIT callback:&lt;br /&gt;
&lt;br /&gt;
 static UINT8 irq_state;&lt;br /&gt;
 static UINT8 irq_vector;&lt;br /&gt;
 static UINT16 irq_mask[16];&lt;br /&gt;
 static UINT32 *allocated_data;&lt;br /&gt;
 &lt;br /&gt;
 MACHINE_INIT( example1 )&lt;br /&gt;
 {&lt;br /&gt;
     state_save_register_UINT8(&amp;quot;example1&amp;quot;, 0, &amp;quot;irq_state&amp;quot;, &amp;amp;irq_state, 1);&lt;br /&gt;
     state_save_register_UINT8(&amp;quot;example1&amp;quot;, 0, &amp;quot;irq_vector&amp;quot;, &amp;amp;irq_vector, 1);&lt;br /&gt;
     state_save_register_UINT16(&amp;quot;example1&amp;quot;, 0, &amp;quot;irq_mask&amp;quot;, irq_mask, 16);&lt;br /&gt;
     &lt;br /&gt;
     allocated_data = auto_malloc(1000 * sizeof(*allocated_data));&lt;br /&gt;
     &lt;br /&gt;
     state_save_register_UINT32(&amp;quot;example1&amp;quot;, 0, &amp;quot;allocated_data&amp;quot;, allocated_data, 1000);&lt;br /&gt;
 }&lt;br /&gt;
A few observations here. First, you&#039;ll notice that we&#039;ve set the data name equal to the name of the variable we&#039;re saving. Since these are just global variables, they don&#039;t need special instance numbers (those are mainly useful if you have a peripheral device that could have multiple instances). &amp;quot;example1&amp;quot; was arbitrarily picked as the module name, though any name would have sufficed.&lt;br /&gt;
&lt;br /&gt;
The first two items are single variables, so we pass the address of the variable and a count of 1. The third item is an array, so we pass the address of the array and a count equal to the number of items in the array. The last item is similar, except that the data is allocated dynamically before passing the pointer and length into the registration function.&lt;br /&gt;
&lt;br /&gt;
You&#039;ll notice that writing that is kind of tedious, and there are some obvious patterns. For example, the module name for global variables is pretty much irrelevant, the instance number is always 0 here, and the data names are consistently related to the variable names. Furthermore, the compiler knows the type of each variable, so having to specify it explicitly is just extra work. Plus, the count for single variables is always 1, and the count for arrays can be determined at compile-time. To this end, there are some macros that simplify matters:&lt;br /&gt;
&lt;br /&gt;
 static UINT8 irq_state;&lt;br /&gt;
 static UINT8 irq_vector;&lt;br /&gt;
 static UINT16 irq_mask[16];&lt;br /&gt;
 static UINT32 *allocated_data;&lt;br /&gt;
 &lt;br /&gt;
 MACHINE_INIT( example1 )&lt;br /&gt;
 {    &lt;br /&gt;
     state_save_register_global(irq_state);&lt;br /&gt;
     state_save_register_global(irq_vector);&lt;br /&gt;
     state_save_register_global_array(irq_mask);&lt;br /&gt;
     &lt;br /&gt;
     allocated_data = auto_malloc(1000 * sizeof(*allocated_data));&lt;br /&gt;
     &lt;br /&gt;
     state_save_register_global_pointer(allocated_data, 1000);&lt;br /&gt;
 }&lt;br /&gt;
Ah, much simpler! All &amp;quot;global&amp;quot; items are registered with the &amp;quot;globals&amp;quot; module name and instance number 0. The &#039;&#039;&#039;state_save_register_global&#039;&#039;&#039; macro registers a single variable, while &#039;&#039;&#039;state_save_register_global_array&#039;&#039;&#039; registers an array, and &#039;&#039;&#039;state_save_register_global_pointer&#039;&#039;&#039; registers a dynamically allocated array.&lt;br /&gt;
&lt;br /&gt;
This is the part where it is crucial to have a good, basic understanding of C. You need to understand how pointers, arrays, and variables work in C, and how they differ. You also need to understand the answers to questions like: Why don&#039;t you need to save the pointers themselves? If you can&#039;t answer that last one, you&#039;ll probably be a bit out of your depth trying to add save state support to drivers in MAME.&lt;br /&gt;
&lt;br /&gt;
The final thing to mention about registering data for save states is that there is only a small window of time in which registrations are allowed, starting from early in initialization until just after the driver&#039;s MACHINE_INIT callback is called. This means that at init time, you need to register everything you might want to save up front. The reason for this will become clearer in a future article which explains how restore works.&lt;/div&gt;</summary>
		<author><name>Madskunk</name></author>
	</entry>
	<entry>
		<id>https://wiki.mamedev.org/index.php?title=Checklist_for_Cleaning_Up_Drivers&amp;diff=1830</id>
		<title>Checklist for Cleaning Up Drivers</title>
		<link rel="alternate" type="text/html" href="https://wiki.mamedev.org/index.php?title=Checklist_for_Cleaning_Up_Drivers&amp;diff=1830"/>
		<updated>2008-06-28T11:35:08Z</updated>

		<summary type="html">&lt;p&gt;Madskunk: Simple Wiki formatting changes&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Over the past year(s), Aaron has done some driver &amp;quot;cleanup&amp;quot; work. This generally involves picking apart a driver, revisiting all the assumptions using whatever information is available, and updating it to take advantage of newer features in MAME that have been introduced since it was first written. To do this work, Aaron keeps a checklist of things to do, just to make sure all bases are covered. This list is constantly updated, but since it is a good set of guidelines for updating a driver, or writing a new one from scratch, it is provided here.&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Timing/interrupts:&#039;&#039;&#039;&lt;br /&gt;
* all crystals on the PCB documented via #defines&lt;br /&gt;
* all CPU and sound clocks derived from #defined crystal values&lt;br /&gt;
* re-verify interrupt generation timing and sources&lt;br /&gt;
* implement interrupt acknowledges (many older drivers didn&#039;t bother)&lt;br /&gt;
*add accurate watchdog durations&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Memory:&#039;&#039;&#039;&lt;br /&gt;
* unified read/write memory maps (they used to be separate)&lt;br /&gt;
* map the entire address space fully, if possible from schematics&lt;br /&gt;
* use AM_SHARE where appropriate (better than sharedram read/write handlers)&lt;br /&gt;
* convert memory banking to the new system (memory_configure_bank)&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Graphics:&#039;&#039;&#039;&lt;br /&gt;
* gfx layouts should use RGN_FRAC wherever possible instead of hard-coded values&lt;br /&gt;
* gfx layouts that are common should be shared (vidhrdw/generic.c)&lt;br /&gt;
* accurate hblank/vblank/visible areas, derived from schematics if possible&lt;br /&gt;
* convert from old macros to new screen macros for display info&lt;br /&gt;
* use new more accurate screen timing routines for H/V positions&lt;br /&gt;
* convert to tilemaps, if applicable&lt;br /&gt;
* change to use resistors for palette generation&lt;br /&gt;
* add limits on sprite drawing (e.g., how many per scanline), if known&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;Inputs:&#039;&#039;&#039;&lt;br /&gt;
* tag all input ports&lt;br /&gt;
* change all port references in code to use tags&lt;br /&gt;
* convert non-DIP configurations to configs&lt;br /&gt;
* use PORT_CUSTOM where appropriate instead of memory overrides&lt;br /&gt;
* connect coin counters (often missing)&lt;br /&gt;
* connect PCB outputs via the new output system&lt;br /&gt;
* add DIPLOCATIONS&lt;br /&gt;
* verify DIPs and inputs&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;ROMs:&#039;&#039;&#039;&lt;br /&gt;
* memory regions reduced to minimum size (they don&#039;t have to cover the whole address space)&lt;br /&gt;
* make sure ROM names are good and accurate to what we know&lt;br /&gt;
* check for any unemulated clones&lt;br /&gt;
&lt;br /&gt;
&#039;&#039;&#039;General:&#039;&#039;&#039;&lt;br /&gt;
* update source files to be in order: header, includes, constants, typedefs, macros, globals, inlines, code&lt;br /&gt;
* update driver file to be in the same order, followed by: address maps, input ports, graphics definitions, sound configs, machine driver, ROMs, driver init code, drivers&lt;br /&gt;
* add save state support&lt;br /&gt;
* move all globals to hang off of driver_data&lt;br /&gt;
* de-obfuscate the code where it is confusing&lt;br /&gt;
&lt;br /&gt;
Some recent driver updates that are pretty up to date include: &amp;lt;code&amp;gt;ccastles.c, cloud9.c, missile.c, turbo.c, zaxxon.c.&amp;lt;/code&amp;gt;&lt;/div&gt;</summary>
		<author><name>Madskunk</name></author>
	</entry>
	<entry>
		<id>https://wiki.mamedev.org/index.php?title=Writing_Messages_to_the_Screen_in_a_MAME_Driver&amp;diff=1829</id>
		<title>Writing Messages to the Screen in a MAME Driver</title>
		<link rel="alternate" type="text/html" href="https://wiki.mamedev.org/index.php?title=Writing_Messages_to_the_Screen_in_a_MAME_Driver&amp;diff=1829"/>
		<updated>2008-06-28T11:27:01Z</updated>

		<summary type="html">&lt;p&gt;Madskunk: Corrected a missing &amp;#039;&amp;#039;&amp;#039;&amp;#039;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;One of the side-effects of the new video system is that drivers aren&#039;t allowed to write to the UI layer directly. They can call &amp;lt;code&amp;gt;popmessage()&amp;lt;/code&amp;gt; to display a popup at the bottom of the screen, but that&#039;s about it in the new system. The problem is that a few drivers were displaying important game-related information using the UI font. Specifically, &amp;lt;b&amp;gt;Atari Football&amp;lt;/b&amp;gt; was using it to show which plays had been selected, and the Exidy Max-a-Flex system was using it to draw the status of the lamps and timer. In retrospect, it is actually good that these cases broke because the way it was being done before was a big hack. For one thing, it meant that the game screen area was artificially increased to make room for the text. And second, the state of these lamps was not being properly exposed to the outside world (or in the case of Football, it was being changed via the rendering system in addition to being displayed on screen).&lt;br /&gt;
&lt;br /&gt;
Ideally, the state of these indicators should be made visible via the rendering system. This is great, except that in the absence of an external artwork file, there would be no visible indication at all. This is one of the reasons why it&#039;s good to have built-in layouts in the MAME code -- even if they are crude approximations of the original artwork, they at least can reflect important functional information. The problem is, built-in layouts can&#039;t really reference image files. All they can do is draw rectangles and disks, which is sufficient for basic overlays on top of old black &amp;amp; white games, but isn&#039;t really enough to provide textual information.&lt;br /&gt;
&lt;br /&gt;
In order to solve this problem, a couple of new primitives have been added to the layouts. In addition to rect and disk primitives, the two new primitives are: text and led7seg.&lt;br /&gt;
&lt;br /&gt;
The text primitive lets you add text anywhere within the artwork area. You can specify color and bounds just like the other primitives. The text is drawn using the built-in fixed-width MAME font (even if you have a different UI font), and is centered within the bounds. If there is too much text to fit in the area provided, the font will be squashed horizontally to fit. Here&#039;s an example that positions the text &amp;quot;GAME OVER&amp;quot; in red centered within the given rectangle:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;&amp;amp;lt;text string=&amp;quot;GAME OVER&amp;quot;&amp;amp;gt;&lt;br /&gt;
     &amp;amp;lt;bounds x=&amp;quot;0&amp;quot; y=&amp;quot;0&amp;quot; height=&amp;quot;10&amp;quot; width=&amp;quot;200&amp;quot; /&amp;amp;gt;&lt;br /&gt;
     &amp;amp;lt;color red=&amp;quot;1.0&amp;quot; green=&amp;quot;0.0&amp;quot; blue=&amp;quot;0.0&amp;quot; /&amp;amp;gt;&lt;br /&gt;
 &amp;amp;lt;/text&amp;amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The led7seg primitive lets you position a standard 7-segment LED somewhere in the artwork. The LEDs are drawn in a high resolution and oversampled down so they look nice. Typically these are used to specify a digit from 0-9, &amp;lt;b&amp;gt;Turbo&amp;lt;/b&amp;gt; is one example. To use this, you would typically create an element with multiple states, each state reflecting the corresponding digit. Here&#039;s an example that positions a red LED with the number &amp;quot;2&amp;quot; that is only visible with the containing element is in state &amp;quot;2&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;&amp;amp;lt;led7seg pattern=&amp;quot;10111010&amp;quot; state=&amp;quot;2&amp;quot;&amp;amp;gt;&lt;br /&gt;
     &amp;amp;lt;color red=&amp;quot;1.0&amp;quot; green=&amp;quot;0.0&amp;quot; blue=&amp;quot;0.0&amp;quot; /&amp;amp;gt;&lt;br /&gt;
 &amp;amp;lt;/led7seg&amp;amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The pattern attribute specifies which of the segments is visible. A 1 means &amp;quot;on&amp;quot;, and a 0 means &amp;quot;off&amp;quot;. They are specified in the following order:&lt;br /&gt;
&lt;br /&gt;
# Top horizontal segment&lt;br /&gt;
# Upper left vertical segment&lt;br /&gt;
# Upper right vertical segment&lt;br /&gt;
# Middle horizontal segment&lt;br /&gt;
# Lower left vertical segment&lt;br /&gt;
# Lower right vertical segment&lt;br /&gt;
# Bottom horizontal segment&lt;br /&gt;
# Decimal point&lt;br /&gt;
&lt;br /&gt;
Using these two new primitives, built-in layouts have been created for the Atari sports games (&#039;&#039;&#039;Football&#039;&#039;&#039; and &#039;&#039;&#039;Baseball&#039;&#039;&#039;), the Sega Z80 scaling games (&#039;&#039;&#039;Turbo&#039;&#039;&#039;, &#039;&#039;&#039;Subroc 3D&#039;&#039;&#039;, &#039;&#039;&#039;Buck Rogers&#039;&#039;&#039;), Taito&#039;s &#039;&#039;&#039;Super Speed Race&#039;&#039;&#039;, and the Exidy Max-a-Flex system that display all the essential lamps and score/timing information. Of course, you can continue to use the externally-provided artwork for a better visual appearance, but now it&#039;s possible to provide vital lamps and LEDs via the new built-in layouts without affecting the core game screen or abusing the UI system.&lt;/div&gt;</summary>
		<author><name>Madskunk</name></author>
	</entry>
	<entry>
		<id>https://wiki.mamedev.org/index.php?title=Writing_Messages_to_the_Screen_in_a_MAME_Driver&amp;diff=1828</id>
		<title>Writing Messages to the Screen in a MAME Driver</title>
		<link rel="alternate" type="text/html" href="https://wiki.mamedev.org/index.php?title=Writing_Messages_to_the_Screen_in_a_MAME_Driver&amp;diff=1828"/>
		<updated>2008-06-28T11:25:33Z</updated>

		<summary type="html">&lt;p&gt;Madskunk: A couple of Wiki style changes&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;One of the side-effects of the new video system is that drivers aren&#039;t allowed to write to the UI layer directly. They can call &amp;lt;code&amp;gt;popmessage()&amp;lt;/code&amp;gt; to display a popup at the bottom of the screen, but that&#039;s about it in the new system. The problem is that a few drivers were displaying important game-related information using the UI font. Specifically, &amp;lt;b&amp;gt;Atari Football&amp;lt;/b&amp;gt; was using it to show which plays had been selected, and the Exidy Max-a-Flex system was using it to draw the status of the lamps and timer. In retrospect, it is actually good that these cases broke because the way it was being done before was a big hack. For one thing, it meant that the game screen area was artificially increased to make room for the text. And second, the state of these lamps was not being properly exposed to the outside world (or in the case of Football, it was being changed via the rendering system in addition to being displayed on screen).&lt;br /&gt;
&lt;br /&gt;
Ideally, the state of these indicators should be made visible via the rendering system. This is great, except that in the absence of an external artwork file, there would be no visible indication at all. This is one of the reasons why it&#039;s good to have built-in layouts in the MAME code -- even if they are crude approximations of the original artwork, they at least can reflect important functional information. The problem is, built-in layouts can&#039;t really reference image files. All they can do is draw rectangles and disks, which is sufficient for basic overlays on top of old black &amp;amp; white games, but isn&#039;t really enough to provide textual information.&lt;br /&gt;
&lt;br /&gt;
In order to solve this problem, a couple of new primitives have been added to the layouts. In addition to rect and disk primitives, the two new primitives are: text and led7seg.&lt;br /&gt;
&lt;br /&gt;
The text primitive lets you add text anywhere within the artwork area. You can specify color and bounds just like the other primitives. The text is drawn using the built-in fixed-width MAME font (even if you have a different UI font), and is centered within the bounds. If there is too much text to fit in the area provided, the font will be squashed horizontally to fit. Here&#039;s an example that positions the text &amp;quot;GAME OVER&amp;quot; in red centered within the given rectangle:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;&amp;amp;lt;text string=&amp;quot;GAME OVER&amp;quot;&amp;amp;gt;&lt;br /&gt;
     &amp;amp;lt;bounds x=&amp;quot;0&amp;quot; y=&amp;quot;0&amp;quot; height=&amp;quot;10&amp;quot; width=&amp;quot;200&amp;quot; /&amp;amp;gt;&lt;br /&gt;
     &amp;amp;lt;color red=&amp;quot;1.0&amp;quot; green=&amp;quot;0.0&amp;quot; blue=&amp;quot;0.0&amp;quot; /&amp;amp;gt;&lt;br /&gt;
 &amp;amp;lt;/text&amp;amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The led7seg primitive lets you position a standard 7-segment LED somewhere in the artwork. The LEDs are drawn in a high resolution and oversampled down so they look nice. Typically these are used to specify a digit from 0-9, &amp;lt;b&amp;gt;Turbo&amp;lt;/b&amp;gt; is one example. To use this, you would typically create an element with multiple states, each state reflecting the corresponding digit. Here&#039;s an example that positions a red LED with the number &amp;quot;2&amp;quot; that is only visible with the containing element is in state &amp;quot;2&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;&amp;amp;lt;led7seg pattern=&amp;quot;10111010&amp;quot; state=&amp;quot;2&amp;quot;&amp;amp;gt;&lt;br /&gt;
     &amp;amp;lt;color red=&amp;quot;1.0&amp;quot; green=&amp;quot;0.0&amp;quot; blue=&amp;quot;0.0&amp;quot; /&amp;amp;gt;&lt;br /&gt;
 &amp;amp;lt;/led7seg&amp;amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The pattern attribute specifies which of the segments is visible. A 1 means &amp;quot;on&amp;quot;, and a 0 means &amp;quot;off&amp;quot;. They are specified in the following order:&lt;br /&gt;
&lt;br /&gt;
# Top horizontal segment&lt;br /&gt;
# Upper left vertical segment&lt;br /&gt;
# Upper right vertical segment&lt;br /&gt;
# Middle horizontal segment&lt;br /&gt;
# Lower left vertical segment&lt;br /&gt;
# Lower right vertical segment&lt;br /&gt;
# Bottom horizontal segment&lt;br /&gt;
# Decimal point&lt;br /&gt;
&lt;br /&gt;
Using these two new primitives, built-in layouts have been created for the Atari sports games (&#039;&#039;&#039;Football&#039;&#039;&#039; and &#039;&#039;&#039;Baseball&#039;&#039;&#039;), the Sega Z80 scaling games (&#039;&#039;&#039;Turbo&#039;&#039;&#039;, &#039;&#039;&#039;Subroc 3D&#039;&#039;&#039;, &#039;&#039;&#039;Buck Rogers), Taito&#039;s &#039;&#039;&#039;Super Speed Race&#039;&#039;&#039;, and the Exidy Max-a-Flex system that display all the essential lamps and score/timing information. Of course, you can continue to use the externally-provided artwork for a better visual appearance, but now it&#039;s possible to provide vital lamps and LEDs via the new built-in layouts without affecting the core game screen or abusing the UI system.&lt;/div&gt;</summary>
		<author><name>Madskunk</name></author>
	</entry>
	<entry>
		<id>https://wiki.mamedev.org/index.php?title=Save_State_Fundamentals&amp;diff=1827</id>
		<title>Save State Fundamentals</title>
		<link rel="alternate" type="text/html" href="https://wiki.mamedev.org/index.php?title=Save_State_Fundamentals&amp;diff=1827"/>
		<updated>2008-06-28T11:22:53Z</updated>

		<summary type="html">&lt;p&gt;Madskunk: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Before adding save state support to a driver in MAME, it&#039;s important to understand how the overall save state system works. But first, a word of warning: it&#039;s been said in the past that adding save state support to a driver is easy. Let&#039;s clarify that by saying: adding save state support a driver is relatively easy &#039;&#039;if you know C well&#039;&#039;. How do you know whether or not you know C well? Read on...&lt;br /&gt;
&lt;br /&gt;
The basic concept of saving the state of any emulator involves first identifying all the information that represents the current state of the system, and then writing that data out to disk in some fashion for later retrieval. There are many ways this can be done. Let&#039;s look at the first step: what comprises the set of data that needs to be saved in order to fully represent the state of an emulated system?&lt;br /&gt;
&lt;br /&gt;
Some obvious candidates are:&lt;br /&gt;
# the registers and internal state on each CPU&lt;br /&gt;
# information about what each sound chip is doing&lt;br /&gt;
# the contents of all RAM (including video, palette, sound RAM) in the system&lt;br /&gt;
# all timing information&lt;br /&gt;
# the state of any peripheral devices (EEPROMs, IDE controllers, etc.)&lt;br /&gt;
# the currently selected memory bank for banked RAM/ROM&lt;br /&gt;
# the state of any driver-specific devices&lt;br /&gt;
&lt;br /&gt;
Fortunately, due to MAME&#039;s modular design, a lot of this is taken care of centrally. For example, many common CPU cores already have built-in support for saving their registers and internal state, as do many common sound chip emulators. Similarly, the MAME core handles saving the contents of all RAM and timers. And many peripheral devices can save their state as well, as long as they have some sort of &amp;lt;code&amp;gt;init()&amp;lt;/code&amp;gt; function that is called to set them up. This leaves memory banks and driver-specific devices as the two main things that need to be managed manually for each driver.&lt;br /&gt;
&lt;br /&gt;
== Saving the Data ==&lt;br /&gt;
&lt;br /&gt;
In MAME, the save state system is designed as a primarily passive system. That is, MAME&#039;s save state code assumes that all the data you want to save lives in memory somewhere. It is the client&#039;s responsibility to inform the save state system where in memory that data lies, and in what format it exists. This is generally done at initialization time. The save state system manages the rest of the process from there.&lt;br /&gt;
&lt;br /&gt;
Each piece of data that is registered is required to have a unique signature. This signature is actually a combination of three pieces of data: the module name, the instance number, and the data name.&lt;br /&gt;
&lt;br /&gt;
The module name is a string that is intended to represent the name of the module that is saving the data; generally this is the name of the CPU (e.g., &amp;quot;Z80&amp;quot;) or driver (e.g., &amp;quot;pacman&amp;quot;), but really can be any unique identifier at all.&lt;br /&gt;
&lt;br /&gt;
The instance number specifies an index within the module; for example, the first Z80 in the system will use a module name &amp;quot;Z80&amp;quot; with an instance number of 0, while the second one will also use a module name &amp;quot;Z80&amp;quot; but with an instance number of 1.&lt;br /&gt;
&lt;br /&gt;
The data name is a string that represents the name of the specific piece of data. For example, the AF register on a Z80 might be registered with a data name of &amp;quot;AF&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Keep in mind that the combination of these three pieces of data must be 100% unique within the system. Any attempt to re-register an identical set of data will abort out of MAME with an error.&lt;br /&gt;
&lt;br /&gt;
So, how do you register this data? Well, you use one of the many different registration functions available in state.h:&lt;br /&gt;
 &amp;lt;code&amp;gt;void state_save_register_UINT8&lt;br /&gt;
 void state_save_register_INT8&lt;br /&gt;
 void state_save_register_UINT16&lt;br /&gt;
 void state_save_register_INT16&lt;br /&gt;
 void state_save_register_UINT32&lt;br /&gt;
 void state_save_register_INT32&lt;br /&gt;
 void state_save_register_UINT64&lt;br /&gt;
 void state_save_register_INT64&lt;br /&gt;
 void state_save_register_double&lt;br /&gt;
 void state_save_register_float&amp;lt;/code&amp;gt;&lt;br /&gt;
Each of these functions takes a module name, an instance number, a data name, a pointer to the variable to be saved, and a count. The first three parameters I&#039;ve already explained above. The pointer is just that: the address of where the data currently lives in memory. And the count is there so that you can register a whole array of data in a single call.&lt;br /&gt;
&lt;br /&gt;
Let&#039;s look at an example. In this example, we have several global variables that need to be saved, one of which is an array, and one of which is dynamically allocated. For this example, we register in the MACHINE_INIT callback:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;static UINT8 irq_state;&lt;br /&gt;
 static UINT8 irq_vector;&lt;br /&gt;
 static UINT16 irq_mask[16];&lt;br /&gt;
 static UINT32 *allocated_data;&lt;br /&gt;
 &lt;br /&gt;
 MACHINE_INIT( example1 )&lt;br /&gt;
 {&lt;br /&gt;
     state_save_register_UINT8(&amp;quot;example1&amp;quot;, 0, &amp;quot;irq_state&amp;quot;, &amp;amp;irq_state, 1);&lt;br /&gt;
     state_save_register_UINT8(&amp;quot;example1&amp;quot;, 0, &amp;quot;irq_vector&amp;quot;, &amp;amp;irq_vector, 1);&lt;br /&gt;
     state_save_register_UINT16(&amp;quot;example1&amp;quot;, 0, &amp;quot;irq_mask&amp;quot;, irq_mask, 16);&lt;br /&gt;
     &lt;br /&gt;
     allocated_data = auto_malloc(1000 * sizeof(*allocated_data));&lt;br /&gt;
     &lt;br /&gt;
     state_save_register_UINT32(&amp;quot;example1&amp;quot;, 0, &amp;quot;allocated_data&amp;quot;, allocated_data, 1000);&lt;br /&gt;
 }&amp;lt;/code&amp;gt;&lt;br /&gt;
A few observations here. First, you&#039;ll notice that we&#039;ve set the data name equal to the name of the variable we&#039;re saving. Since these are just global variables, they don&#039;t need special instance numbers (those are mainly useful if you have a peripheral device that could have multiple instances). &amp;quot;example1&amp;quot; was arbitrarily picked as the module name, though any name would have sufficed.&lt;br /&gt;
&lt;br /&gt;
The first two items are single variables, so we pass the address of the variable and a count of 1. The third item is an array, so we pass the address of the array and a count equal to the number of items in the array. The last item is similar, except that the data is allocated dynamically before passing the pointer and length into the registration function.&lt;br /&gt;
&lt;br /&gt;
You&#039;ll notice that writing that is kind of tedious, and there are some obvious patterns. For example, the module name for global variables is pretty much irrelevant, the instance number is always 0 here, and the data names are consistently related to the variable names. Furthermore, the compiler knows the type of each variable, so having to specify it explicitly is just extra work. Plus, the count for single variables is always 1, and the count for arrays can be determined at compile-time. To this end, there are some macros that simplify matters:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;static UINT8 irq_state;&lt;br /&gt;
 static UINT8 irq_vector;&lt;br /&gt;
 static UINT16 irq_mask[16];&lt;br /&gt;
 static UINT32 *allocated_data;&lt;br /&gt;
 &lt;br /&gt;
 MACHINE_INIT( example1 )&lt;br /&gt;
 {    &lt;br /&gt;
     state_save_register_global(irq_state);&lt;br /&gt;
     state_save_register_global(irq_vector);&lt;br /&gt;
     state_save_register_global_array(irq_mask);&lt;br /&gt;
     &lt;br /&gt;
     allocated_data = auto_malloc(1000 * sizeof(*allocated_data));&lt;br /&gt;
     &lt;br /&gt;
     state_save_register_global_pointer(allocated_data, 1000);&lt;br /&gt;
 }&amp;lt;/code&amp;gt;&lt;br /&gt;
Ah, much simpler! All &amp;quot;global&amp;quot; items are registered with the &amp;quot;globals&amp;quot; module name and instance number 0. The &#039;&#039;&#039;state_save_register_global&#039;&#039;&#039; macro registers a single variable, while &#039;&#039;&#039;state_save_register_global_array&#039;&#039;&#039; registers an array, and &#039;&#039;&#039;state_save_register_global_pointer&#039;&#039;&#039; registers a dynamically allocated array.&lt;br /&gt;
&lt;br /&gt;
This is the part where it is crucial to have a good, basic understanding of C. You need to understand how pointers, arrays, and variables work in C, and how they differ. You also need to understand the answers to questions like: Why don&#039;t you need to save the pointers themselves? If you can&#039;t answer that last one, you&#039;ll probably be a bit out of your depth trying to add save state support to drivers in MAME.&lt;br /&gt;
&lt;br /&gt;
The final thing to mention about registering data for save states is that there is only a small window of time in which registrations are allowed, starting from early in initialization until just after the driver&#039;s MACHINE_INIT callback is called. This means that at init time, you need to register everything you might want to save up front. The reason for this will become clearer in a future article which explains how restore works.&lt;/div&gt;</summary>
		<author><name>Madskunk</name></author>
	</entry>
	<entry>
		<id>https://wiki.mamedev.org/index.php?title=Save_State_Fundamentals&amp;diff=1826</id>
		<title>Save State Fundamentals</title>
		<link rel="alternate" type="text/html" href="https://wiki.mamedev.org/index.php?title=Save_State_Fundamentals&amp;diff=1826"/>
		<updated>2008-06-28T11:12:29Z</updated>

		<summary type="html">&lt;p&gt;Madskunk: New page: Before adding save state support to a driver in MAME, it&amp;#039;s important to understand how the overall save state system works. But first, a word of warning: it&amp;#039;s been said in the past that ad...&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Before adding save state support to a driver in MAME, it&#039;s important to understand how the overall save state system works. But first, a word of warning: it&#039;s been said in the past that adding save state support to a driver is easy. Let&#039;s clarify that by saying: adding save state support a driver is relatively easy &#039;&#039;if you know C well&#039;&#039;. How do you know whether or not you know C well? Read on...&lt;br /&gt;
&lt;br /&gt;
The basic concept of saving the state of any emulator involves first identifying all the information that represents the current state of the system, and then writing that data out to disk in some fashion for later retrieval. There are many ways this can be done. Let&#039;s look at the first step: what comprises the set of data that needs to be saved in order to fully represent the state of an emulated system?&lt;br /&gt;
&lt;br /&gt;
Some obvious candidates are:&lt;br /&gt;
# the registers and internal state on each CPU&lt;br /&gt;
# information about what each sound chip is doing&lt;br /&gt;
# the contents of all RAM (including video, palette, sound RAM) in the system&lt;br /&gt;
# all timing information&lt;br /&gt;
# the state of any peripheral devices (EEPROMs, IDE controllers, etc.)&lt;br /&gt;
# the currently selected memory bank for banked RAM/ROM&lt;br /&gt;
# the state of any driver-specific devices&lt;br /&gt;
&lt;br /&gt;
Fortunately, due to MAME&#039;s modular design, a lot of this is taken care of centrally. For example, many common CPU cores already have built-in support for saving their registers and internal state, as do many common sound chip emulators. Similarly, the MAME core handles saving the contents of all RAM and timers. And many peripheral devices can save their state as well, as long as they have some sort of &amp;lt;code&amp;gt;init()&amp;lt;/code&amp;gt; function that is called to set them up. This leaves memory banks and driver-specific devices as the two main things that need to be managed manually for each driver.&lt;br /&gt;
&lt;br /&gt;
== Saving the Data ==&lt;br /&gt;
&lt;br /&gt;
In MAME, the save state system is designed as a primarily passive system. That is, MAME&#039;s save state code assumes that all the data you want to save lives in memory somewhere. It is the client&#039;s responsibility to inform the save state system where in memory that data lies, and in what format it exists. This is generally done at initialization time. The save state system manages the rest of the process from there.&lt;br /&gt;
&lt;br /&gt;
Each piece of data that is registered is required to have a unique signature. This signature is actually a combination of three pieces of data: the module name, the instance number, and the data name.&lt;br /&gt;
&lt;br /&gt;
The module name is a string that is intended to represent the name of the module that is saving the data; generally this is the name of the CPU (e.g., &amp;quot;Z80&amp;quot;) or driver (e.g., &amp;quot;pacman&amp;quot;), but really can be any unique identifier at all.&lt;br /&gt;
&lt;br /&gt;
The instance number specifies an index within the module; for example, the first Z80 in the system will use a module name &amp;quot;Z80&amp;quot; with an instance number of 0, while the second one will also use a module name &amp;quot;Z80&amp;quot; but with an instance number of 1.&lt;br /&gt;
&lt;br /&gt;
The data name is a string that represents the name of the specific piece of data. For example, the AF register on a Z80 might be registered with a data name of &amp;quot;AF&amp;quot;.&lt;br /&gt;
&lt;br /&gt;
Keep in mind that the combination of these three pieces of data must be 100% unique within the system. Any attempt to re-register an identical set of data will abort out of MAME with an error.&lt;br /&gt;
&lt;br /&gt;
So, how do you register this data? Well, you use one of the many different registration functions available in state.h:&lt;br /&gt;
 &amp;lt;source lang=c&amp;gt;void state_save_register_UINT8&lt;br /&gt;
 void state_save_register_INT8&lt;br /&gt;
 void state_save_register_UINT16&lt;br /&gt;
 void state_save_register_INT16&lt;br /&gt;
 void state_save_register_UINT32&lt;br /&gt;
 void state_save_register_INT32&lt;br /&gt;
 void state_save_register_UINT64&lt;br /&gt;
 void state_save_register_INT64&lt;br /&gt;
 void state_save_register_double&lt;br /&gt;
 void state_save_register_float&amp;lt;/source&amp;gt;&lt;br /&gt;
Each of these functions takes a module name, an instance number, a data name, a pointer to the variable to be saved, and a count. The first three parameters I&#039;ve already explained above. The pointer is just that: the address of where the data currently lives in memory. And the count is there so that you can register a whole array of data in a single call.&lt;br /&gt;
&lt;br /&gt;
Let&#039;s look at an example. In this example, we have several global variables that need to be saved, one of which is an array, and one of which is dynamically allocated. For this example, we register in the MACHINE_INIT callback:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;static UINT8 irq_state;&lt;br /&gt;
 static UINT8 irq_vector;&lt;br /&gt;
 static UINT16 irq_mask[16];&lt;br /&gt;
 static UINT32 *allocated_data;&lt;br /&gt;
 &lt;br /&gt;
 MACHINE_INIT( example1 )&lt;br /&gt;
 {&lt;br /&gt;
     state_save_register_UINT8(&amp;quot;example1&amp;quot;, 0, &amp;quot;irq_state&amp;quot;, &amp;amp;irq_state, 1);&lt;br /&gt;
     state_save_register_UINT8(&amp;quot;example1&amp;quot;, 0, &amp;quot;irq_vector&amp;quot;, &amp;amp;irq_vector, 1);&lt;br /&gt;
     state_save_register_UINT16(&amp;quot;example1&amp;quot;, 0, &amp;quot;irq_mask&amp;quot;, irq_mask, 16);&lt;br /&gt;
     &lt;br /&gt;
     allocated_data = auto_malloc(1000 * sizeof(*allocated_data));&lt;br /&gt;
     &lt;br /&gt;
     state_save_register_UINT32(&amp;quot;example1&amp;quot;, 0, &amp;quot;allocated_data&amp;quot;, allocated_data, 1000);&lt;br /&gt;
 }&amp;lt;/code&amp;gt;&lt;br /&gt;
A few observations here. First, you&#039;ll notice that I tend to set the data name equal to the name of the variable I&#039;m saving. Since these are just global variables, they don&#039;t need special instance numbers (those are mainly useful if you have a peripheral device that could have multiple instances). I arbitrarily picked &amp;quot;example1&amp;quot; as my module name, though any name would have sufficed.&lt;br /&gt;
&lt;br /&gt;
The first two items are single variables, so we pass the address of the variable and a count of 1. The third item is an array, so we pass the address of the array and a count equal to the number of items in the array. The last item is similar, except that the data is allocated dynamically before passing the pointer and length into the registration function.&lt;br /&gt;
&lt;br /&gt;
You&#039;ll notice that writing that is kind of tedious, and there are some obvious patterns. For example, the module name for global variables is pretty much irrelevant, the instance number is always 0 here, and the data names are consistently related to the variable names. Furthermore, the compiler knows the type of each variable, so having to specify it explicitly is just extra work. Plus, the count for single variables is always 1, and the count for arrays can be determined at compile-time. To this end, there are some macros that simplify matters:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;static UINT8 irq_state;&lt;br /&gt;
 static UINT8 irq_vector;&lt;br /&gt;
 static UINT16 irq_mask[16];&lt;br /&gt;
 static UINT32 *allocated_data;&lt;br /&gt;
 &lt;br /&gt;
 MACHINE_INIT( example1 )&lt;br /&gt;
 {    &lt;br /&gt;
     state_save_register_global(irq_state);&lt;br /&gt;
     state_save_register_global(irq_vector);&lt;br /&gt;
     state_save_register_global_array(irq_mask);&lt;br /&gt;
     &lt;br /&gt;
     allocated_data = auto_malloc(1000 * sizeof(*allocated_data));&lt;br /&gt;
     &lt;br /&gt;
     state_save_register_global_pointer(allocated_data, 1000);&lt;br /&gt;
 }&amp;lt;/code&amp;gt;&lt;br /&gt;
Ah, much simpler! All &amp;quot;global&amp;quot; items are registered with the &amp;quot;globals&amp;quot; module name and instance number 0. The &amp;lt;strong&amp;gt;state_save_register_global&amp;lt;/strong&amp;gt; macro registers a single variable, while &amp;lt;strong&amp;gt;state_save_register_global_array&amp;lt;/strong&amp;gt; registers an array, and &amp;lt;strong&amp;gt;state_save_register_global_pointer&amp;lt;/strong&amp;gt; registers a dynamically allocated array.&lt;br /&gt;
&lt;br /&gt;
This is the part where it is crucial to have a good, basic understanding of C. You need to understand how pointers, arrays, and variables work in C, and how they differ. You also need to understand the answers to questions like: Why don&#039;t you need to save the pointers themselves? If you can&#039;t answer that last one, you&#039;ll probably be a bit out of your depth trying to add save state support to drivers in MAME.&lt;br /&gt;
&lt;br /&gt;
The final thing I will mention about registering data for save states is that there is only a small window of timeâ€”starting from early in initialization until just after the driver&#039;s MACHINE_INIT callback is calledâ€”during which registrations are allowed. This means that at init time, you need to register everything you might want to save up front. The reason for this will become clearer in a future article which explains how restore works.&lt;/div&gt;</summary>
		<author><name>Madskunk</name></author>
	</entry>
	<entry>
		<id>https://wiki.mamedev.org/index.php?title=How_MAME_Works&amp;diff=1825</id>
		<title>How MAME Works</title>
		<link rel="alternate" type="text/html" href="https://wiki.mamedev.org/index.php?title=How_MAME_Works&amp;diff=1825"/>
		<updated>2008-06-28T10:41:57Z</updated>

		<summary type="html">&lt;p&gt;Madskunk: /* Core Internals */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The following is a list of documents describing the internal workings (core) of the MAME emulator.  Most are penned by Aaron Giles.&lt;br /&gt;
&lt;br /&gt;
== Building MAME ==&lt;br /&gt;
* [[Building MAME using Microsoft Visual Studio compilers]]&lt;br /&gt;
&lt;br /&gt;
== Writing for MAME ==&lt;br /&gt;
* [[MAME Coding Conventions]]&lt;br /&gt;
&lt;br /&gt;
== For Driver Writers ==&lt;br /&gt;
* [[Resource Management in MAME]]&lt;br /&gt;
* [[DIP Switches in MAME]]&lt;br /&gt;
* [[MAME Interrupt Function Review]]&lt;br /&gt;
* [[Using MAME&#039;s tilemap system]]&lt;br /&gt;
* [http://aarongiles.com/?p=159 Programmable Logic Devices in MAME]&lt;br /&gt;
* [[CPUs and Address Spaces]]&lt;br /&gt;
* [[Address Maps]]&lt;br /&gt;
&lt;br /&gt;
== Core Internals ==&lt;br /&gt;
* [http://aarongiles.com/?p=74 Filters and streams in the MAME Sound System]&lt;br /&gt;
* [[Save State Fundamentals]]&lt;br /&gt;
* [[Using the GFX/TileMap viewer (F4)]]&lt;br /&gt;
* [[How To Use the &#039;New&#039; Renderer]]&lt;br /&gt;
* [[Layouts and Rendering for MAME Artwork System]]&lt;br /&gt;
* [[LAY File Basics - Part I]]&lt;br /&gt;
&lt;br /&gt;
== CPU Emulation ==&lt;br /&gt;
* [[Virtual TLB]]&lt;br /&gt;
* [[CPU Scheduling in MAME]]&lt;br /&gt;
&lt;br /&gt;
== Universal Dynamic Recompiler ==&lt;br /&gt;
* [[Core Concepts]]&lt;br /&gt;
* [[UML Architecture]]&lt;br /&gt;
** [[UML Control Flow Opcodes]]&lt;br /&gt;
** [[UML Internal Register Opcodes]]&lt;br /&gt;
** [[UML Integer Opcodes]]&lt;br /&gt;
** [[UML Floating Point Opcodes]]&lt;br /&gt;
* [[Dynamic Recompiler Author&#039;s Guide]]&lt;br /&gt;
* [[Back-End Author&#039;s Guide]]&lt;br /&gt;
&lt;br /&gt;
== Tips &amp;amp; Tricks ==&lt;br /&gt;
* [[Executing Code Out of a Memory Region With a Read Handler]]&lt;br /&gt;
* [[Checklist for Cleaning Up Drivers]]&lt;br /&gt;
* [[Writing Messages to the Screen In a MAME Driver]]&lt;/div&gt;</summary>
		<author><name>Madskunk</name></author>
	</entry>
	<entry>
		<id>https://wiki.mamedev.org/index.php?title=CPU_Scheduling_in_MAME&amp;diff=1824</id>
		<title>CPU Scheduling in MAME</title>
		<link rel="alternate" type="text/html" href="https://wiki.mamedev.org/index.php?title=CPU_Scheduling_in_MAME&amp;diff=1824"/>
		<updated>2008-06-28T10:39:20Z</updated>

		<summary type="html">&lt;p&gt;Madskunk: Slight grammatical change&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Multi-CPU games in MAME are scheduled in a round-robin fashion. The order of the round robin execution is strictly defined by the order of the CPUs in the machine driver. There is no way to alter this order; however, you can affect the scheduling by suspending CPUs or adjusting the granularity of the scheduling.&lt;br /&gt;
&lt;br /&gt;
The scheduler relies on the timer system, which knows when the next timer is scheduled. All scheduling happens between firings of timers, similarly, timers are never fired while a CPU is executing. This important to keep in mind.&lt;br /&gt;
&lt;br /&gt;
The scheduler queries the timer system to find out when the next timer is set to fire. It then loops over each CPU, computes how many cycles that CPU needs to execute to reach that time, and runs the CPU for that many cycles. When the CPU is finished executing, the CPU core returns how many cycles it actually executed. This information is accumulated and converted back into a &amp;quot;local CPU time&amp;quot;, in order to account for overshooting or early exiting from the CPU core.&lt;br /&gt;
&lt;br /&gt;
For example....&lt;br /&gt;
&lt;br /&gt;
Let&#039;s say that CPU #0 is running at 14MHz, and CPU #1 is running at 2MHz. Let&#039;s also say that we&#039;re starting at time 0 (local CPU time for both CPUs is 0), and a timer is scheduled to go off in 150 microseconds (time = 0.000150).&lt;br /&gt;
&lt;br /&gt;
The round robin logic will start with CPU #0 and compute how many cycles it needs to execute to reach 0.000150. Since we&#039;re starting from time 0, we need to execute for at least 150usec. 0.000150 * 14,000,000 = 2100 cycles. It then calls that CPU&#039;s execute function with 2100 cycles; when the execute function returns, it specifies how many cycles it actually ran. Let&#039;s say it returns saying that it ran 2112 cycles. (CPU cores generally overshoot because many instructions take more than 1 cycle each to execute.) 2112 cycles puts the local CPU time for CPU #0 at&lt;br /&gt;
0.000150857 (2112 / 14,000,000).&lt;br /&gt;
&lt;br /&gt;
Now it&#039;s time for CPU #1 to execute. 0.000150 * 2,000,000 = 300 cycles.&lt;br /&gt;
So we call execute(300), and get back 300 cycles. CPU #1 local time is now 0.000150.&lt;br /&gt;
&lt;br /&gt;
At this point, both CPUs have executed, and both their local times are greater than or equal to the target time 0.000150. So the scheduler calls the timer system to let it process the timers. When finished, it again asks when the next timer will fire. Let&#039;s say it&#039;s set to fire exactly 150usec later at time = 0.000300.&lt;br /&gt;
&lt;br /&gt;
Back to the scheduler, we start the round robin over again. CPU #0 needs to execute (0.000300 - 0.000150857) * 14,000,000 = 2088 cycles to reach a local time of 0.300. Note that we took into account the extra cycles that we executed last time. So we call execute(2088), and we get back, say, 2091. That puts our local time at 0.000150857 + 0.000149357 = 0.000300214.&lt;br /&gt;
&lt;br /&gt;
Now it&#039;s CPU #1&#039;s turn. (0.000300 - 0.000150) * 2,000,000 = 300 cycles again. Calling execute(300), we get back 302 cycles. This puts CPU #1&#039;s local time at 0.000150 + 0.000151 = 0.000301.&lt;br /&gt;
&lt;br /&gt;
Again, both CPUs have executed, both their local times are greater than or equal to 0.000300, so we contact the timer system to let it run its timers. This procedure continues throughout the execution of the system.&lt;br /&gt;
&lt;br /&gt;
Some things to note here, firstly, after the first round robin, CPU #0&#039;s local time was slightly ahead of CPU #1&#039;s local time. After the second pass, the opposite was true. Thus, you can&#039;t guarantee at any time that any given CPU is ahead of or behind the others.&lt;br /&gt;
&lt;br /&gt;
Also, be sure to keep in mind that each CPU has its own local time. The timer system also has a &amp;quot;global time&amp;quot;. The global time is generally the minimum of all the CPU local times. Which time is used when calling the timer system depends entirely upon which CPU context is currently active. If a CPU context is active (generally true only while a CPU is executing; for example, in read/write callbacks), then all timer operations treat the &amp;quot;current time&amp;quot; as the CPU local time, accounting for all cycles that have been executed on that CPU so far in the current timeslice. If a CPU context is not active (all other times; for example, in timer callbacks), then the &amp;quot;current time&amp;quot; is the global time.&lt;br /&gt;
&lt;br /&gt;
The global time is updated at the end of each timeslice before the scheduler calls into the timer system to let it run its timers, and that global time is used to dispatch the timers.&lt;/div&gt;</summary>
		<author><name>Madskunk</name></author>
	</entry>
	<entry>
		<id>https://wiki.mamedev.org/index.php?title=CPU_Scheduling_in_MAME&amp;diff=1823</id>
		<title>CPU Scheduling in MAME</title>
		<link rel="alternate" type="text/html" href="https://wiki.mamedev.org/index.php?title=CPU_Scheduling_in_MAME&amp;diff=1823"/>
		<updated>2008-06-28T00:13:53Z</updated>

		<summary type="html">&lt;p&gt;Madskunk: New page: Multi-CPU games in MAME are scheduled in a round-robin fashion. The order of the round robin execution is strictly defined by the order of the CPUs in the machine driver. There is no way t...&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Multi-CPU games in MAME are scheduled in a round-robin fashion. The order of the round robin execution is strictly defined by the order of the CPUs in the machine driver. There is no way to alter this order; however, you can affect the scheduling by suspending CPUs or adjusting the granularity of the scheduling.&lt;br /&gt;
&lt;br /&gt;
The scheduler relies on the timer system, which knows when the next timer is scheduled. All scheduling happens between firings of timers, similarly, timers are never fired while a CPU is executing. This important to keep in mind.&lt;br /&gt;
&lt;br /&gt;
The scheduler queries the timer system to find out when the next timer is set to fire. It then loops over each CPU, computes how many cycles that CPU needs to execute to reach that time, and runs the CPU for that many cycles. When the CPU is finished executing, the CPU core returns how many cycles it actually executed. This information is accumulated and converted back into a &amp;quot;local CPU time&amp;quot;, in order to account for overshooting or early exiting from the CPU core.&lt;br /&gt;
&lt;br /&gt;
For example....&lt;br /&gt;
&lt;br /&gt;
Let&#039;s say that CPU #0 is running at 14MHz, and CPU #1 is running at 2MHz. Let&#039;s also say that we&#039;re starting at time 0 (local CPU time for both CPUs is 0), and a timer is scheduled to go off in 150 microseconds (time = 0.000150).&lt;br /&gt;
&lt;br /&gt;
The round robin logic will start with CPU #0 and compute how many cycles it needs to execute to reach 0.000150. Since we&#039;re starting from time 0, we need to execute for at least 150usec. 0.000150 * 14,000,000 = 2100 cycles. It then calls that CPU&#039;s execute function with 2100 cycles; when the execute function returns, it specifies how many cycles it actually ran. Let&#039;s say it returns saying that it ran 2112 cycles. (CPU cores generally overshoot because many instructions take more than 1 cycle each to execute.) 2112 cycles puts the local CPU time for CPU #0 at&lt;br /&gt;
0.000150857 (2112 / 14,000,000).&lt;br /&gt;
&lt;br /&gt;
Now it&#039;s time for CPU #1 to execute. 0.000150 * 2,000,000 = 300 cycles.&lt;br /&gt;
So we call execute(300), and get back 300 cycles. CPU #1 local time is now 0.000150.&lt;br /&gt;
&lt;br /&gt;
At this point, both CPUs have executed, and both their local times are greater than or equal to the target time 0.000150. So the scheduler calls the timer system to let it process the timers. When finished, it again asks when the next timer will fire. Let&#039;s say it&#039;s set to fire exactly 150usec later at time = 0.000300.&lt;br /&gt;
&lt;br /&gt;
Back to the scheduler, we start the round robin over again. CPU #0 needs to execute (0.000300 - 0.000150857) * 14,000,000 = 2088 cycles to reach a local time of 0.300. Note that we took into account the extra cycles that we executed last time. So we call execute(2088), and we get back, say, 2091. That puts our local time at 0.000150857 + 0.000149357 = 0.000300214.&lt;br /&gt;
&lt;br /&gt;
Now it&#039;s CPU #1&#039;s turn. (0.000300 - 0.000150) * 2,000,000 = 300 cycles again. Calling execute(300), we get back 302 cycles. This puts CPU #1&#039;s local time at 0.000150 + 0.000151 = 0.000301.&lt;br /&gt;
&lt;br /&gt;
Again, both CPUs have executed, both their local times are greater than or equal to 0.000300, so we contact the timer system to let it run its timers. This procedure continues throughout the execution of the system.&lt;br /&gt;
&lt;br /&gt;
Some things to note here, firstly, after the first round robin, CPU #0&#039;s local time was slightly ahead of CPU #1&#039;s local time. After the second pass, the opposite was true. Thus, you can&#039;t be guaranteed at any time that any given CPU is ahead of or behind the others.&lt;br /&gt;
&lt;br /&gt;
Also, be sure to keep in mind that each CPU has its own local time. The timer system also has a &amp;quot;global time&amp;quot;. The global time is generally the minimum of all the CPU local times. Which time is used when calling the timer system depends entirely upon which CPU context is currently active. If a CPU context is active (generally true only while a CPU is executing; for example, in read/write callbacks), then all timer operations treat the &amp;quot;current time&amp;quot; as the CPU local time, accounting for all cycles that have been executed on that CPU so far in the current timeslice. If a CPU context is not active (all other times; for example, in timer callbacks), then the &amp;quot;current time&amp;quot; is the global time.&lt;br /&gt;
&lt;br /&gt;
The global time is updated at the end of each timeslice before the scheduler calls into the timer system to let it run its timers, and that global time is used to dispatch the timers.&lt;/div&gt;</summary>
		<author><name>Madskunk</name></author>
	</entry>
	<entry>
		<id>https://wiki.mamedev.org/index.php?title=How_MAME_Works&amp;diff=1822</id>
		<title>How MAME Works</title>
		<link rel="alternate" type="text/html" href="https://wiki.mamedev.org/index.php?title=How_MAME_Works&amp;diff=1822"/>
		<updated>2008-06-28T00:05:51Z</updated>

		<summary type="html">&lt;p&gt;Madskunk: /* CPU Emulation */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The following is a list of documents describing the internal workings (core) of the MAME emulator.  Most are penned by Aaron Giles.&lt;br /&gt;
&lt;br /&gt;
== Building MAME ==&lt;br /&gt;
* [[Building MAME using Microsoft Visual Studio compilers]]&lt;br /&gt;
&lt;br /&gt;
== Writing for MAME ==&lt;br /&gt;
* [[MAME Coding Conventions]]&lt;br /&gt;
&lt;br /&gt;
== For Driver Writers ==&lt;br /&gt;
* [[Resource Management in MAME]]&lt;br /&gt;
* [[DIP Switches in MAME]]&lt;br /&gt;
* [[MAME Interrupt Function Review]]&lt;br /&gt;
* [[Using MAME&#039;s tilemap system]]&lt;br /&gt;
* [http://aarongiles.com/?p=159 Programmable Logic Devices in MAME]&lt;br /&gt;
* [[CPUs and Address Spaces]]&lt;br /&gt;
* [[Address Maps]]&lt;br /&gt;
&lt;br /&gt;
== Core Internals ==&lt;br /&gt;
* [http://aarongiles.com/?p=74 Filters and streams in the MAME Sound System]&lt;br /&gt;
* [http://aarongiles.com/?p=149 Save State Fundamentals]&lt;br /&gt;
* [[Using the GFX/TileMap viewer (F4)]]&lt;br /&gt;
* [[How To Use the &#039;New&#039; Renderer]]&lt;br /&gt;
* [[Layouts and Rendering for MAME Artwork System]]&lt;br /&gt;
* [[LAY File Basics - Part I]]&lt;br /&gt;
&lt;br /&gt;
== CPU Emulation ==&lt;br /&gt;
* [[Virtual TLB]]&lt;br /&gt;
* [[CPU Scheduling in MAME]]&lt;br /&gt;
&lt;br /&gt;
== Universal Dynamic Recompiler ==&lt;br /&gt;
* [[Core Concepts]]&lt;br /&gt;
* [[UML Architecture]]&lt;br /&gt;
** [[UML Control Flow Opcodes]]&lt;br /&gt;
** [[UML Internal Register Opcodes]]&lt;br /&gt;
** [[UML Integer Opcodes]]&lt;br /&gt;
** [[UML Floating Point Opcodes]]&lt;br /&gt;
* [[Dynamic Recompiler Author&#039;s Guide]]&lt;br /&gt;
* [[Back-End Author&#039;s Guide]]&lt;br /&gt;
&lt;br /&gt;
== Tips &amp;amp; Tricks ==&lt;br /&gt;
* [[Executing Code Out of a Memory Region With a Read Handler]]&lt;br /&gt;
* [[Checklist for Cleaning Up Drivers]]&lt;br /&gt;
* [[Writing Messages to the Screen In a MAME Driver]]&lt;/div&gt;</summary>
		<author><name>Madskunk</name></author>
	</entry>
	<entry>
		<id>https://wiki.mamedev.org/index.php?title=How_To_Use_the_%27New%27_Renderer&amp;diff=1819</id>
		<title>How To Use the &#039;New&#039; Renderer</title>
		<link rel="alternate" type="text/html" href="https://wiki.mamedev.org/index.php?title=How_To_Use_the_%27New%27_Renderer&amp;diff=1819"/>
		<updated>2008-06-25T15:43:45Z</updated>

		<summary type="html">&lt;p&gt;Madskunk: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;There are really two ways to use the new renderer. (Well, there are really an infinite number, but these two ways were what motivated the feature set as it exists today.) Both ways will produce similar results, and both have their uses.&lt;br /&gt;
&lt;br /&gt;
The first thing to understand is the concept of a &amp;lt;b&amp;gt;render_target&amp;lt;/b&amp;gt;. A render_target is really a rendering context. It is an object that holds all the information about how you would like the renderer to assemble the primitives that make up the final result. From the OSD perspective, this is really the only object you need to talk to. You can allocate as many render_targets as you like; in the Windows OSD code, we allocate one per window. The MAME core also allocates one internally for taking snapshots.&lt;br /&gt;
&lt;br /&gt;
There are a number of knobs you can twiddle on each render_target. You can enumerate all of the views available for each target, find out which game screens are present on each view, and select which one to use. You can specify the orientation of the target, which rotates all of the primitives in the appropriate direction. You can specify flags that&lt;br /&gt;
control which types of artwork are visible. You can tell the renderer what the maximum texture size is. You can ask it to compute the smallest size that will ensure each game screen pixel maps to at least one output pixel. And most importantly, you can specify the size or bounds of the target.&lt;br /&gt;
&lt;br /&gt;
How you specify the bounds of a render_target fundamentally determines how you are using the renderer. And here is where the two approaches differ.&lt;br /&gt;
&lt;br /&gt;
The first approach is to tell the render_target the absolute truth about what it is drawing to. This entails calling &amp;lt;code&amp;gt;render_target_set_bounds&amp;lt;/code&amp;gt; with the actual width, height, and pixel aspect ratio of the screen you are drawing to. Thus, if the output is a 1600x1200 monitor with square pixels, you would call &amp;lt;code&amp;gt;render_target_set_bounds(1600, 1200, 1.0)&amp;lt;/code&amp;gt;. This works well if your final result will be hardware accelerated. Under the covers, the renderer will assemble all the pieces to be placed within the 1600x1200 area you specified, and -- here&#039;s the key -- it will perform a high-quality resampling of any artwork to the final output resolution. This is much better quality and much more efficient than simply uploading the entire artwork as a giant texture and letting your video card filter it. Because it&#039;s not expected that you will change this size too often, the expensive overhead of resampling the artwork is usually just taken once. In contrast, the game screen textures are not resampled in this way; rather, they are always uploaded at their native resolution and your video card is expected to do the resampling.&lt;br /&gt;
&lt;br /&gt;
This first approach is what you get when you run the Windows build with -video d3d or -video gdi. This is also why -video gdi is incredibly slow unless it&#039;s in a tiny window: all of that pixel pushing at full resolution is being done in software, and it ain&#039;t cheap.&lt;br /&gt;
&lt;br /&gt;
The second approach is to lie to the render_target about what it is drawing to. The usual way to do this is to compute the minimum size via the &amp;lt;code&amp;gt;render_target_get_minimum_size&amp;lt;/code&amp;gt; function, and then pass that width and height (or some integral multiple of such) into &amp;lt;code&amp;gt;render_target_set_bounds&amp;lt;/code&amp;gt; as the target size. What happens in this case is that, as far as the renderer knows, you are drawing to a low resolution output device. It will still do high quality artwork resampling, but just to a much lower resolution. Why would you do this? The main motivation is to support limited or non-existant hardware acceleration cases.&lt;br /&gt;
&lt;br /&gt;
Consider a situation where you can use your graphics hardware to accelerate only a final bitmap scaling operation, but none of the more advanced blending features required to assemble a full image. In this case, you could fall back to drawing everything in software at full resolution, but it is going to be very slow. The alternative is to lie&lt;br /&gt;
about the actual resolution. Instead, allocate a buffer at the render_target&#039;s minimum size, draw to that buffer, and then use the graphics hardware to scale that buffer to full screen.&lt;br /&gt;
&lt;br /&gt;
This second approach is what you get when you run with Windows build with -video ddraw. And in fact, the second approach produces output that is almost identical to what MAME produced before the new renderer went in, with the addition of more flexible features.&lt;br /&gt;
&lt;br /&gt;
One thing you&#039;ll notice if you look at the Windows code is that it ends up calling &amp;lt;code&amp;gt;render_target_set_bounds&amp;lt;/code&amp;gt; each frame, immediately before calling &amp;lt;code&amp;gt;render_target_get_primitives&amp;lt;/code&amp;gt;. The main reason for this is that the Windows system lives in a dynamic environment. We support live resizing of windows in windowed mode, which means the output resolution can change at any time when using the first method. Furthermore, games in MAME can dynamically change their resolution, and users are free to change the currently selected view, meaning that the minimum size can change from frame to frame within a game when we use the second method. For these reasons, it is just simpler to update the output size each frame before requesting the primitives so that we&lt;br /&gt;
ensure we&#039;re in sync.&lt;/div&gt;</summary>
		<author><name>Madskunk</name></author>
	</entry>
	<entry>
		<id>https://wiki.mamedev.org/index.php?title=How_To_Use_the_%27New%27_Renderer&amp;diff=1818</id>
		<title>How To Use the &#039;New&#039; Renderer</title>
		<link rel="alternate" type="text/html" href="https://wiki.mamedev.org/index.php?title=How_To_Use_the_%27New%27_Renderer&amp;diff=1818"/>
		<updated>2008-06-25T15:35:10Z</updated>

		<summary type="html">&lt;p&gt;Madskunk: New page: Since I&amp;#039;ve had a few questions asked recently about how the new renderer works from an OSD developer&amp;#039;s point of view, I figured this would be a good chance to kickstart things again.  Ther...&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Since I&#039;ve had a few questions asked recently about how the new renderer&lt;br /&gt;
works from an OSD developer&#039;s point of view, I figured this would be a&lt;br /&gt;
good chance to kickstart things again.&lt;br /&gt;
&lt;br /&gt;
There are really two ways to use the new renderer. (Well, there are&lt;br /&gt;
really an infinite number, but these two ways were what motivated the&lt;br /&gt;
feature set as it exists today.) Both ways will produce similar results,&lt;br /&gt;
and both have their uses.&lt;br /&gt;
&lt;br /&gt;
The first thing to understand is the concept of a &amp;lt;b&amp;gt;render_target&amp;lt;/b&amp;gt;.&lt;br /&gt;
A render_target is really a rendering context. It is an object that&lt;br /&gt;
holds all the information about how you would like the renderer to&lt;br /&gt;
assemble the primitives that make up the final result. From the OSD&lt;br /&gt;
perspective, this is really the only object you need to talk to. You can&lt;br /&gt;
allocate as many render_targets as you like; in the Windows OSD code, I&lt;br /&gt;
allocate one per window. The MAME core also allocates one internally for&lt;br /&gt;
taking snapshots.&lt;br /&gt;
&lt;br /&gt;
There are a number of knobs you can twiddle on each render_target. You&lt;br /&gt;
can enumerate all of the views available for each target, find out which&lt;br /&gt;
game screens are present on each view, and select which one to use. You&lt;br /&gt;
can specify the orientation of the target, which rotates all of the&lt;br /&gt;
primitives in the appropriate direction. You can specify flags that&lt;br /&gt;
control which types of artwork are visible. You can tell the renderer&lt;br /&gt;
what the maximum texture size is. You can ask it to compute the smallest&lt;br /&gt;
size that will ensure each game screen pixel maps to at least one output&lt;br /&gt;
pixel. And most importantly, you can specify the size or bounds of the&lt;br /&gt;
target.&lt;br /&gt;
&lt;br /&gt;
How you specify the bounds of a render_target fundamentally determines&lt;br /&gt;
how you are using the renderer. And here is where the two approaches&lt;br /&gt;
differ.&lt;br /&gt;
&amp;lt;!--more--&amp;gt;&lt;br /&gt;
The first approach is to tell the render_target the absolute truth about&lt;br /&gt;
what it is drawing to. This entails calling&lt;br /&gt;
&amp;lt;b&amp;gt;render_target_set_bounds&amp;lt;/b&amp;gt; with the actual width, height, and pixel&lt;br /&gt;
aspect ratio of the screen you are drawing to. Thus, if the output is a&lt;br /&gt;
1600x1200 monitor with square pixels, you would call&lt;br /&gt;
render_target_set_bounds(1600, 1200, 1.0). This works well if your final&lt;br /&gt;
result will be hardware accelerated. Under the covers, the renderer will&lt;br /&gt;
assemble all the pieces to be placed within the 1600x1200 area you&lt;br /&gt;
specified, and -- here&#039;s the key -- it will perform a high-quality&lt;br /&gt;
resampling of any artwork to the final output resolution. This is much&lt;br /&gt;
better quality and much more efficient than simply uploading the entire&lt;br /&gt;
artwork as a giant texture and letting your video card filter it.&lt;br /&gt;
Because it&#039;s not expected that you will change this size too often, the&lt;br /&gt;
expensive overhead of resampling the artwork is usually just taken once.&lt;br /&gt;
In contrast, the game screen textures are not resampled in this way;&lt;br /&gt;
rather, they are always uploaded at their native resolution and your&lt;br /&gt;
video card is expected to do the resampling.&lt;br /&gt;
&lt;br /&gt;
This first approach is what you get when you run the Windows build with&lt;br /&gt;
-video d3d or -video gdi. This is also why -video gdi is incredibly slow&lt;br /&gt;
unless it&#039;s in a tiny window: all of that pixel pushing at full&lt;br /&gt;
resolution is being done in software, and it ain&#039;t cheap.&lt;br /&gt;
&lt;br /&gt;
The second approach is to lie to the render_target about what it is&lt;br /&gt;
drawing to. The usual way to do this is to compute the minimum size via&lt;br /&gt;
the &amp;lt;b&amp;gt;render_target_get_minimum_size&amp;lt;/b&amp;gt; function, and then pass that&lt;br /&gt;
width and height (or some integral multiple of such) into&lt;br /&gt;
&amp;lt;b&amp;gt;render_target_set_bounds&amp;lt;/b&amp;gt; as the target size. What happens in this&lt;br /&gt;
case is that, as far as the renderer knows, you are drawing to a low&lt;br /&gt;
resolution output device. It will still do high quality artwork&lt;br /&gt;
resampling, but just to a much lower resolution. Why would you do this?&lt;br /&gt;
The main motivation is to support limited or non-existant hardware&lt;br /&gt;
acceleration cases.&lt;br /&gt;
&lt;br /&gt;
Consider a situation where you can use your graphics hardware to&lt;br /&gt;
accelerate only a final bitmap scaling operation, but none of the more&lt;br /&gt;
advanced blending features required to assemble a full image. In this&lt;br /&gt;
case, you could fall back to drawing everything in software at full&lt;br /&gt;
resolution, but it is going to be very slow. The alternative is to lie&lt;br /&gt;
about the actual resolution. Instead, allocate a buffer at the&lt;br /&gt;
render_target&#039;s minimum size, draw to that buffer, and then use the&lt;br /&gt;
graphics hardware to scale that buffer to full screen.&lt;br /&gt;
&lt;br /&gt;
This second approach is what you get when you run with Windows build&lt;br /&gt;
with -video ddraw. And in fact, the second approach produces output that&lt;br /&gt;
is almost identical to what MAME produced before the new renderer went&lt;br /&gt;
in, with the addition of more flexible features.&lt;br /&gt;
&lt;br /&gt;
One thing you&#039;ll notice if you look at the Windows code is that it ends&lt;br /&gt;
up calling &amp;lt;b&amp;gt;render_target_set_bounds&amp;lt;/b&amp;gt; each frame, immediately&lt;br /&gt;
before calling &amp;lt;b&amp;gt;render_target_get_primitives&amp;lt;/b&amp;gt;. The main reason for&lt;br /&gt;
this is that the Windows system lives in a dynamic environment. We&lt;br /&gt;
support live resizing of windows in windowed mode, which means the&lt;br /&gt;
output resolution can change at any time when using the first method.&lt;br /&gt;
Furthermore, games in MAME can dynamically change their resolution, and&lt;br /&gt;
users are free to change the currently selected view, meaning that the&lt;br /&gt;
minimum size can change from frame to frame within a game when we use&lt;br /&gt;
the second method. For these reasons, it is just simpler to update the&lt;br /&gt;
output size each frame before requesting the primitives so that we&lt;br /&gt;
ensure we&#039;re in sync.&lt;/div&gt;</summary>
		<author><name>Madskunk</name></author>
	</entry>
	<entry>
		<id>https://wiki.mamedev.org/index.php?title=How_MAME_Works&amp;diff=1816</id>
		<title>How MAME Works</title>
		<link rel="alternate" type="text/html" href="https://wiki.mamedev.org/index.php?title=How_MAME_Works&amp;diff=1816"/>
		<updated>2008-06-25T15:34:17Z</updated>

		<summary type="html">&lt;p&gt;Madskunk: /* Core Internals */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The following is a list of documents describing the internal workings (core) of the MAME emulator.  Most are penned by Aaron Giles.&lt;br /&gt;
&lt;br /&gt;
== Building MAME ==&lt;br /&gt;
* [[Building MAME using Microsoft Visual Studio compilers]]&lt;br /&gt;
&lt;br /&gt;
== Writing for MAME ==&lt;br /&gt;
* [[MAME Coding Conventions]]&lt;br /&gt;
&lt;br /&gt;
== For Driver Writers ==&lt;br /&gt;
* [[Resource Management in MAME]]&lt;br /&gt;
* [[DIP Switches in MAME]]&lt;br /&gt;
* [[MAME Interrupt Function Review]]&lt;br /&gt;
* [[Using MAME&#039;s tilemap system]]&lt;br /&gt;
* [http://aarongiles.com/?p=159 Programmable Logic Devices in MAME]&lt;br /&gt;
* [[CPUs and Address Spaces]]&lt;br /&gt;
* [[Address Maps]]&lt;br /&gt;
&lt;br /&gt;
== Core Internals ==&lt;br /&gt;
* [http://aarongiles.com/?p=137 CPU Scheduling in MAME]&lt;br /&gt;
* [http://aarongiles.com/?p=74 Filters and streams in the MAME Sound System]&lt;br /&gt;
* [http://aarongiles.com/?p=149 Save State Fundamentals]&lt;br /&gt;
* [[Using the GFX/TileMap viewer (F4)]]&lt;br /&gt;
* [[How To Use the &#039;New&#039; Renderer]]&lt;br /&gt;
* [[Layouts and Rendering for MAME Artwork System]]&lt;br /&gt;
* [[LAY File Basics - Part I]]&lt;br /&gt;
&lt;br /&gt;
== Universal Dynamic Recompiler ==&lt;br /&gt;
* [[Core Concepts]]&lt;br /&gt;
* [[UML Architecture]]&lt;br /&gt;
** [[UML Control Flow Opcodes]]&lt;br /&gt;
** [[UML Internal Register Opcodes]]&lt;br /&gt;
** [[UML Integer Opcodes]]&lt;br /&gt;
** [[UML Floating Point Opcodes]]&lt;br /&gt;
* [[Dynamic Recompiler Author&#039;s Guide]]&lt;br /&gt;
* [[Back-End Author&#039;s Guide]]&lt;br /&gt;
&lt;br /&gt;
== Tips &amp;amp; Tricks ==&lt;br /&gt;
* [[Executing Code Out of a Memory Region With a Read Handler]]&lt;br /&gt;
* [[Checklist for Cleaning Up Drivers]]&lt;br /&gt;
* [[Writing Messages to the Screen In a MAME Driver]]&lt;/div&gt;</summary>
		<author><name>Madskunk</name></author>
	</entry>
	<entry>
		<id>https://wiki.mamedev.org/index.php?title=Layouts_and_Rendering_for_MAME_Artwork_System&amp;diff=1813</id>
		<title>Layouts and Rendering for MAME Artwork System</title>
		<link rel="alternate" type="text/html" href="https://wiki.mamedev.org/index.php?title=Layouts_and_Rendering_for_MAME_Artwork_System&amp;diff=1813"/>
		<updated>2008-06-24T13:49:51Z</updated>

		<summary type="html">&lt;p&gt;Madskunk: Fixed typo&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;MAME 0.106u2 introduced a major change that needs a more detailed description, the concept of layouts and views.&lt;br /&gt;
&lt;br /&gt;
As a simplistic explanation, layouts are the replacement for the artwork description files (.art) that were previously used to describe artwork to be displayed with a game. However, layouts are much more flexible and much more deeply integrated into the rendering system than the artwork files ever were. You literally can&#039;t run the new renderer without a layout loaded.&lt;br /&gt;
&lt;br /&gt;
A layout consists of two parts: a list of zero or more elements, and a list of one or more views. The elements represent a sort of database of artwork pieces that can be assembled in various ways. The views represent the actual positioning of these elements relative to the game screens. The easiest way to understand this is to look at the simplest example, which is the default layout used for regular horizontal 4:3 games:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;&amp;amp;lt;?xml version=&amp;quot;1.0&amp;quot;?&amp;amp;gt;&lt;br /&gt;
 &amp;amp;lt;mamelayout version=&amp;quot;2&amp;quot;&amp;amp;gt;&lt;br /&gt;
     &amp;amp;lt;view name=&amp;quot;Standard&amp;quot;&amp;amp;gt;&lt;br /&gt;
         &amp;amp;lt;screen index=&amp;quot;0&amp;quot;&amp;amp;gt;&lt;br /&gt;
             &amp;amp;lt;bounds left=&amp;quot;0&amp;quot; top=&amp;quot;0&amp;quot; right=&amp;quot;4&amp;quot; bottom=&amp;quot;3&amp;quot; /&amp;amp;gt;  &lt;br /&gt;
         &amp;amp;lt;/screen&amp;amp;gt;&lt;br /&gt;
     &amp;amp;lt;/view&amp;amp;gt;&lt;br /&gt;
 &amp;amp;lt;/mamelayout&amp;amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This particular layout has no elements described, and only a single view. The name of the view is &amp;quot;Standard.&amp;quot; This is important because there is a new menu in the UI that lets you select on the fly which view to display, and this is the name that is displayed in that menu. Within the view, there can be a number of items:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;b&amp;gt;backdrops&amp;lt;/b&amp;gt; specify the attributes of elements that are drawn first and which cover the background of the screen areas; they are rendered against each other using regular alpha blending, so they can have cut-out areas and other effects&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;b&amp;gt;screens&amp;lt;/b&amp;gt; specify the attributes of the various screens that make up a game; they are referenced by index, and are rendered on top of the backdrop layer using additive blending (alpha values applied to the source but not the destination)&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;b&amp;gt;overlays&amp;lt;/b&amp;gt; specify the attributes of elements that are drawn over top of the screens and backdrops; they are rendered on top of the screens and backdrops using RGB multiplicative blending (the RGB values of the overlays are multiplied by the RGB values of the destination)&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;b&amp;gt;bezels&amp;lt;/b&amp;gt; specify the attributes of elements that are drawn last, over all the other elements; they are rendered using regular alpha blending, like the backdrops were&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Everything in the new system is rendered back-to-front, so first all backdrop items are drawn, then all screens, then all overlays, and finally all bezels. If more than one item of a given type is present, it is rendered in the order specified in the layout XML data.&lt;br /&gt;
&lt;br /&gt;
Looking back at the example, you can see that a single item has been specified for our view, which is screen index 0 (this will be the first screen in the system). Within the item are some parameters that describe the bounds of the screen within the view. You&#039;ll notice that the width of the screen is 4 and the height is 3, this is a fairly arbitrary coordinate system. The layout system will read all the items described, and compute the outer bounds of all of the rectangles specified. It will then scale that to fit whatever screen you have configured. Thus, you can specify your coordinates in pixels or whatever is most convenient. The key here is that the screen as described is a standard 4:3 aspect ratio screen oriented horizontally.&lt;br /&gt;
&lt;br /&gt;
Now, if you&#039;re familiar with the old artwork system, you may be scratching your head and thinking, why do we have to specify the aspect ratio of the screen? In the old system, the screen was always positioned from (0,0)-(1,1) and the aspect ratio of the screen (and the resulting artwork) was determined by flags in the game. This is true, and in retrospect, was a mistake. Not only did it make things confusing for positioning purposes, but it meant a lot of the artwork needed to be rotated and tweaked so that it stretched correctly. In addition, in the new world, there is nothing preventing you from having one screen rotated vertically and a second screen rotated horizontally, all within the same view (and yes, there is at least one dual monitor game that is set up that way).&lt;br /&gt;
&lt;br /&gt;
The next obvious question is, so are we going to need files for all these layouts, even the standard ones? The answer is no. The layout system will load a number of layouts from different sources, and offer you the option of switching between all of the views specified by all of the interesting layouts. The search order is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Explicitly specified files (on the command line)&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;i&amp;gt;gamename&amp;lt;/i&amp;gt;.lay&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Game-specific built-in layouts&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;i&amp;gt;parentname&amp;lt;/i&amp;gt;.lay&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Generic built-in layouts&amp;lt;/li&amp;gt; &amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The key are the built-in layouts. First, each game can specify a built-in layout as a parameter to the new GAMEL macro, which mimics the existing GAME macro but takes a final parameter which a pointer to an embedded XML string that holds the game-specific built-in layouts.&lt;br /&gt;
&lt;br /&gt;
Second, there are a number of built-in layouts. By default, each screen in the game gets a Standard layout, which is simply a single screen displayed at its appropriate aspect ratio. Each screen in the game also gets a Native layout, which is a single screen displayed 1:1 with the height/width ratio of the pixels. This produces, for example, widescreen Capcom games for those who still believe they should be widescreen.&lt;br /&gt;
Multi-screen games get a few additional options for displaying both screens at the same time, either on top of each other or side-by-side.&lt;br /&gt;
And finally, just for kicks, there is a &amp;quot;cocktail&amp;quot; layout that displays two copies of screen 0, one rotated 180 degrees for a pseudo-cocktail view. How is that done? With a layout something like this:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;&amp;amp;lt;?xml version=&amp;quot;1.0&amp;quot;?&amp;amp;gt;&lt;br /&gt;
 &amp;amp;lt;mamelayout version=&amp;quot;2&amp;quot;&amp;amp;gt;&lt;br /&gt;
     &amp;amp;lt;view name=&amp;quot;Cocktail&amp;quot;&amp;amp;gt;&lt;br /&gt;
         &amp;amp;lt;screen index=&amp;quot;0&amp;quot;&amp;amp;gt;&lt;br /&gt;
             &amp;amp;lt;bounds left=&amp;quot;-1.33333&amp;quot; top=&amp;quot;0.0&amp;quot; right=&amp;quot;0.0&amp;quot; bottom=&amp;quot;1.0&amp;quot; /&amp;amp;gt; &lt;br /&gt;
         &amp;amp;lt;/screen&amp;amp;gt;&lt;br /&gt;
         &amp;amp;lt;screen index=&amp;quot;0&amp;quot;&amp;amp;gt;&lt;br /&gt;
             &amp;amp;lt;bounds left=&amp;quot;0.01&amp;quot; top=&amp;quot;0.0&amp;quot; right=&amp;quot;1.34333&amp;quot; bottom=&amp;quot;1.0&amp;quot; /&amp;amp;gt;&lt;br /&gt;
             &amp;amp;lt;orientation rotate=&amp;quot;180&amp;quot; /&amp;amp;gt;&lt;br /&gt;
         &amp;amp;lt;/screen&amp;amp;gt;&lt;br /&gt;
     &amp;amp;lt;/view&amp;amp;gt;&lt;br /&gt;
 &amp;amp;lt;/mamelayout&amp;amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You&#039;ll notice a couple of interesting things here. The first is that you can repeat the same screen multiple times in a view. For fun, you could even create a &amp;quot;quad&amp;quot; view that displays the screen 4 times rotated in all four directions. The second is that you can specify an orientation for screens and actually for any item. This allows rotation and flipping of items, and even works with vector games or other special cases. Finally, you see how the coordinate system really is arbitrary. Here we&#039;re using 1.333 as the width of each screen and 1.0 as the height. This is the essentially the same as 4:3.&lt;br /&gt;
&lt;br /&gt;
For completeness sake, here are all the attributes you can specify for items:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;&amp;amp;lt;bounds left=&amp;quot;0&amp;quot; top=&amp;quot;0&amp;quot; right=&amp;quot;4&amp;quot; bottom=&amp;quot;3&amp;quot; /&amp;amp;gt;&lt;br /&gt;
 &amp;amp;lt;bounds x=&amp;quot;0&amp;quot; y=&amp;quot;0&amp;quot; width=&amp;quot;4&amp;quot; height=&amp;quot;3&amp;quot; /&amp;amp;gt;&lt;br /&gt;
 &amp;amp;lt;color red=&amp;quot;1.0&amp;quot; green=&amp;quot;1.0&amp;quot; blue=&amp;quot;1.0&amp;quot; alpha=&amp;quot;0.5&amp;quot; /&amp;amp;gt;&lt;br /&gt;
 &amp;amp;lt;orientation rotate=&amp;quot;90&amp;quot; swapxy=&amp;quot;yes&amp;quot; flipx=&amp;quot;yes&amp;quot; flipy=&amp;quot;no&amp;quot; /&amp;amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can control the bounds either by specifying left/top/right/bottom coordinates, or by specifying x/y/width/height coordinates. But only one or the other. The color tag lets you affect the overall color and alpha blending factors of the item. Each color value ranges from 0-1. And you can control orientation of the item via both a rotate parameter as well as through more primitive flipping and swapping controls.&lt;/div&gt;</summary>
		<author><name>Madskunk</name></author>
	</entry>
	<entry>
		<id>https://wiki.mamedev.org/index.php?title=Layouts_and_Rendering_for_MAME_Artwork_System&amp;diff=1812</id>
		<title>Layouts and Rendering for MAME Artwork System</title>
		<link rel="alternate" type="text/html" href="https://wiki.mamedev.org/index.php?title=Layouts_and_Rendering_for_MAME_Artwork_System&amp;diff=1812"/>
		<updated>2008-06-24T13:49:09Z</updated>

		<summary type="html">&lt;p&gt;Madskunk: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;MAME 0.106u2 introduced a major change that needs a more detailed description, the concept of layouts and views.&lt;br /&gt;
&lt;br /&gt;
As a simplistic explanation, layouts are the replacement for the artwork description files (.art) that were previously used to describe artwork to be displayed with a game. However, layouts are much more flexible and much more deeply integrated into the rendering system than the artwork files ever were. You literally can&#039;t run the new renderer without a layout loaded.&lt;br /&gt;
&lt;br /&gt;
A layout consists of two parts: a list of zero or more elements, and a list of one or more views. The elements represent a sort of database of artwork pieces that can be assembled in various ways. The views represent the actual positioning of these elements relative to the game screens. The easiest way to understand this is to look at the simplest example, which is the default layout used for regular horizontal 4:3 games:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;&amp;amp;lt;?xml version=&amp;quot;1.0&amp;quot;?&amp;amp;gt;&lt;br /&gt;
 &amp;amp;lt;mamelayout version=&amp;quot;2&amp;quot;&amp;amp;gt;&lt;br /&gt;
     &amp;amp;lt;view name=&amp;quot;Standard&amp;quot;&amp;amp;gt;&lt;br /&gt;
         &amp;amp;lt;screen index=&amp;quot;0&amp;quot;&amp;amp;gt;&lt;br /&gt;
             &amp;amp;lt;bounds left=&amp;quot;0&amp;quot; top=&amp;quot;0&amp;quot; right=&amp;quot;4&amp;quot; bottom=&amp;quot;3&amp;quot; /&amp;amp;gt;  &lt;br /&gt;
         &amp;amp;lt;/screen&amp;amp;gt;&lt;br /&gt;
     &amp;amp;lt;/view&amp;amp;gt;&lt;br /&gt;
 &amp;amp;lt;/mamelayout&amp;amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This particular layout has no elements described, and only a single view. The name of the view is &amp;quot;Standard.&amp;quot; This is important because there is a new menu in the UI that lets you select on the fly which view to display, and this is the name that is displayed in that menu. Within the view, there can be a number of items:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;b&amp;gt;backdrops&amp;lt;/b&amp;gt; specify the attributes of elements that are drawn first and which cover the background of the screen areas; they are rendered against each other using regular alpha blending, so they can have cut-out areas and other effects&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;b&amp;gt;screens&amp;lt;/b&amp;gt; specify the attributes of the various screens that make up a game; they are referenced by index, and are rendered on top of the backdrop layer using additive blending (alpha values applied to the source but not the destination)&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;b&amp;gt;overlays&amp;lt;/b&amp;gt; specify the attributes of elements that are drawn over top of the screens and backdrops; they are rendered on top of the screens and backdrops using RGB multiplicative blending (the RGB values of the overlays are multiplied by the RGB values of the destination)&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;b&amp;gt;bezels&amp;lt;/b&amp;gt; specify the attributes of elements that are drawn last, over all the other elements; they are rendered using regular alpha blending, like the backdrops were&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Everything in the new system is rendered back-to-front, so first all backdrop items are drawn, then all screens, then all overlays, and finally all bezels. If more than one item of a given type is present, it is rendered in the order specified in the layout XML data.&lt;br /&gt;
&lt;br /&gt;
Looking back at the example, you can see that a single item has been specified for our view, which is screen index 0 (this will be the first screen in the system). Within the item are some parameters that describe the bounds of the screen within the view. You&#039;ll notice that the width of the screen is 4 and the height is 3, this is a fairly arbitrary coordinate system. The layout system will read all the items described, and compute the outer bounds of all of the rectangles specified. It will then scale that to fit whatever screen you have configured. Thus, you can specify your coordinates in pixels or whatever is most convenient. The key here is that the screen as described is a standard 4:3 aspect ratio screen oriented horizontally.&lt;br /&gt;
&lt;br /&gt;
Now, if you&#039;re familiar with the old artwork system, you may be scratching your head and thinking, why do we have to specify the aspect ratio of the screen? In the old system, the screen was always positioned from (0,0)-(1,1) and the aspect ratio of the screen (and the resulting artwork) was determined by flags in the game. This is true, and in retrospect, was a mistake. Not only did it make things confusing for positioning purposes, but it meant a lot of the artwork needed to be rotated and tweaked so that it stretched correctly. In addition, in the new world, there is nothing preventing you from having one screen rotated vertically and a second screen rotated horizontally, all within the same view (and yes, there is at least one dual monitor game that is set up that way).&lt;br /&gt;
&lt;br /&gt;
The next obvious question is, so are we going to need files for all these layouts, even the standard ones? The answer is no. The layout system will load a number of layouts from different sources, and offer you the option of switching between all of the views specified by all of the interesting layouts. The search order is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Explicitly specified files (on the command line)&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;i&amp;gt;gamename&amp;lt;/i&amp;gt;.lay&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Game-specific built-in layouts&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;i&amp;gt;parentname&amp;lt;/i&amp;gt;.lay&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Generic built-in layouts&amp;lt;/li&amp;gt; &amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The key are the built-in layouts. First, each game can specify a built-in layout as a parameter to the new GAMEL macro, which mimics the existing GAME macro but takes a final parameter which a pointer to an embedded XML string that holds the game-specific built-in layouts.&lt;br /&gt;
&lt;br /&gt;
Second, there are a number of built-in layouts. By default, each screen in the game gets a Standard layout, which is simply a single screen displayed at its appropriate aspect ratio. Each screen in the game also gets a Native layout, which is a single screen displayed 1:1 with the height/width ratio of the pixels. This produces, for example, widescreen Capcom games for those who still believe they should be widescreen.&lt;br /&gt;
Multi-screen games get a few additional options for displaying both screens at the same time, either on top of each other or side-by-side.&lt;br /&gt;
And finally, just for kicks, there is a &amp;quot;cocktail&amp;quot; layout that displays two copies of screen 0, one rotated 180 degrees for a pseudo-cocktail view. How is that done? With a layout something like this:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;&amp;amp;lt;?xml version=&amp;quot;1.0&amp;quot;?&amp;amp;gt;&lt;br /&gt;
 &amp;amp;lt;mamelayout version=&amp;quot;2&amp;quot;&amp;amp;gt;&lt;br /&gt;
     &amp;amp;lt;view name=&amp;quot;Cocktail&amp;quot;&amp;amp;gt;&lt;br /&gt;
         &amp;amp;lt;screen index=&amp;quot;0&amp;quot;&amp;amp;gt;&lt;br /&gt;
             &amp;amp;lt;bounds left=&amp;quot;-1.33333&amp;quot; top=&amp;quot;0.0&amp;quot; right=&amp;quot;0.0&amp;quot; bottom=&amp;quot;1.0&amp;quot; /&amp;amp;gt; &lt;br /&gt;
         &amp;amp;lt;/screen&amp;amp;gt;&lt;br /&gt;
         &amp;amp;lt;screen index=&amp;quot;0&amp;quot;&amp;amp;gt;&lt;br /&gt;
             &amp;amp;lt;bounds left=&amp;quot;0.01&amp;quot; top=&amp;quot;0.0&amp;quot; right=&amp;quot;1.34333&amp;quot; bottom=&amp;quot;1.0&amp;quot; /&amp;amp;gt;&lt;br /&gt;
             &amp;amp;lt;orientation rotate=&amp;quot;180&amp;quot; /&amp;amp;gt;&lt;br /&gt;
         &amp;amp;lt;/screen&amp;amp;gt;&lt;br /&gt;
     &amp;amp;lt;/view&amp;amp;gt;&lt;br /&gt;
 &amp;amp;lt;/mamelayout&amp;amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You&#039;ll notice a couple of interesting things here. The first is that you can repeat the same screen multiple times in a view. For fun, you could even creat a &amp;quot;quad&amp;quot; view that displays the screen 4 times rotated in all four directions. The second is that you can specify an orientation for screens and actually for any item. This allows rotation and flipping of items, and even works with vector games or other special cases. Finally, you see how the coordinate system really is arbitrary. Here we&#039;re using 1.333 as the width of each screen and 1.0 as the height. This is the essentially the same as 4:3.&lt;br /&gt;
&lt;br /&gt;
For completeness sake, here are all the attributes you can specify for items:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;&amp;amp;lt;bounds left=&amp;quot;0&amp;quot; top=&amp;quot;0&amp;quot; right=&amp;quot;4&amp;quot; bottom=&amp;quot;3&amp;quot; /&amp;amp;gt;&lt;br /&gt;
 &amp;amp;lt;bounds x=&amp;quot;0&amp;quot; y=&amp;quot;0&amp;quot; width=&amp;quot;4&amp;quot; height=&amp;quot;3&amp;quot; /&amp;amp;gt;&lt;br /&gt;
 &amp;amp;lt;color red=&amp;quot;1.0&amp;quot; green=&amp;quot;1.0&amp;quot; blue=&amp;quot;1.0&amp;quot; alpha=&amp;quot;0.5&amp;quot; /&amp;amp;gt;&lt;br /&gt;
 &amp;amp;lt;orientation rotate=&amp;quot;90&amp;quot; swapxy=&amp;quot;yes&amp;quot; flipx=&amp;quot;yes&amp;quot; flipy=&amp;quot;no&amp;quot; /&amp;amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can control the bounds either by specifying left/top/right/bottom coordinates, or by specifying x/y/width/height coordinates. But only one or the other. The color tag lets you affect the overall color and alpha blending factors of the item. Each color value ranges from 0-1. And you can control orientation of the item via both a rotate parameter as well as through more primitive flipping and swapping controls.&lt;/div&gt;</summary>
		<author><name>Madskunk</name></author>
	</entry>
	<entry>
		<id>https://wiki.mamedev.org/index.php?title=Layouts_and_Rendering_for_MAME_Artwork_System&amp;diff=1811</id>
		<title>Layouts and Rendering for MAME Artwork System</title>
		<link rel="alternate" type="text/html" href="https://wiki.mamedev.org/index.php?title=Layouts_and_Rendering_for_MAME_Artwork_System&amp;diff=1811"/>
		<updated>2008-06-24T13:29:42Z</updated>

		<summary type="html">&lt;p&gt;Madskunk: New page: Today is when MAME 0.106u2 should &amp;lt;a href=&amp;quot;http://mamedev.org/release.html&amp;quot;&amp;gt;be available&amp;lt;/a&amp;gt;. I&amp;#039;m sure there will be lots of questions as a result, but the one major change that needs some...&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Today is when MAME 0.106u2 should &amp;lt;a&lt;br /&gt;
href=&amp;quot;http://mamedev.org/release.html&amp;quot;&amp;gt;be available&amp;lt;/a&amp;gt;. I&#039;m sure there will be lots of questions as a result, but the one major change that needs some more detailed description is the concept of layouts and views.&lt;br /&gt;
&lt;br /&gt;
As a simplistic explanation, layouts are the replacement for the artwork description files (.art) that were previously used to describe artwork to be displayed with a game. However, layouts are much more flexible and much more deeply integrated into the rendering system than the artwork files ever were. You literally can&#039;t run the new renderer without a layout loaded.&lt;br /&gt;
&lt;br /&gt;
A layout consists of two parts: a list of zero or more elements, and a list of one or more views. The elements represent a sort of database of artwork pieces that can be assembled in various ways. The views represent the actual positioning of these elements relative to the game screens. The easiest way to understand this is to look at the simplest example, which is the default layout used for regular horizontal 4:3&lt;br /&gt;
games:&lt;br /&gt;
&amp;lt;!--more--&amp;gt;&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;amp;lt;?xml version=&amp;quot;1.0&amp;quot;?&amp;amp;gt;&lt;br /&gt;
&amp;amp;lt;mamelayout version=&amp;quot;2&amp;quot;&amp;amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;lt;view name=&amp;quot;Standard&amp;quot;&amp;amp;gt; &amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;lt;screen index=&amp;quot;0&amp;quot;&amp;amp;gt; &amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
&amp;amp;lt;bounds left=&amp;quot;0&amp;quot; top=&amp;quot;0&amp;quot; right=&amp;quot;4&amp;quot; bottom=&amp;quot;3&amp;quot; /&amp;amp;gt; &amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;lt;/screen&amp;amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;lt;/view&amp;amp;gt;&lt;br /&gt;
&amp;amp;lt;/mamelayout&amp;amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
This particular layout has no elements described, and only a single view. The name of the view is &amp;quot;Standard.&amp;quot; This is important because there is a new menu in the UI that lets you select on the fly which view to display, and this is the name that is displayed in that menu. Within the view, there can be a number of items:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;&amp;lt;b&amp;gt;backdrops&amp;lt;/b&amp;gt; specify the attributes of elements that are drawn first and which cover the background of the screen areas; they are rendered against each other using regular alpha blending, so they can have cut-out areas and other effects&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;screens&amp;lt;/b&amp;gt; specify the attributes of the various screens that make up a game; they are referenced by index, and are rendered on top of the backdrop layer using additive blending (alpha values applied to the source but not the destination)&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;overlays&amp;lt;/b&amp;gt; specify the attributes of elements that are drawn over top of the screens and backdrops; they are rendered on top of the screens and backdrops using RGB multiplicative blending (the RGB values of the overlays are multiplied by the RGB values of the destination)&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;&amp;lt;b&amp;gt;bezels&amp;lt;/b&amp;gt; specify the attributes of elements that are drawn last, over all the other elements; they are rendered using regular alpha blending, like the backdrops were&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Everything in the new system is rendered back-to-front, so first all backdrop items are drawn, then all screens, then all overlays, and finally all bezels. If more than one item of a given type is present, it is rendered in the order specified in the layout XML data.&lt;br /&gt;
&lt;br /&gt;
So looking back at the example, you can see that we&#039;ve specified a single item for our view, which is screen index 0 (this will be the first screen in the system). Within the item are some parameters that describe the bounds of the screen within the view. You&#039;ll notice that the width of the screen is 4 and the height is 3. What kind of coordinate system is this? Well, it&#039;s an arbitrary system, really. The layout system will read all the items described, and compute the outer bounds of all of the rectangles specified. It will then scale that to fit whatever screen you have configured. Thus, you can specify your coordinates in pixels or whatever is most convenient. The key here is that the screen as described is a standard 4:3 aspect ratio screen oriented horizontally.&lt;br /&gt;
&lt;br /&gt;
Now, if you&#039;re familiar with the old artwork system, you may be scratching your head and thinking, why do we have to specify the aspect ratio of the screen? In the old system, the screen was always positioned from (0,0)-(1,1) and the aspect ratio of the screen (and the resulting&lt;br /&gt;
artwork) was determined by flags in the game. This is true. And in retrospect, it was a mistake. Not only did it make things confusing for positioning purposes, but it meant a lot of the artwork needed to be rotated and tweaked so that it stretched correctly. In addition, in the new world, there is nothing preventing you from having one screen rotated vertically and a second screen rotated horizontally, all within the same view (and yes, there is at least one dual monitor game that is set up that way).&lt;br /&gt;
&lt;br /&gt;
The next obvious question is, so are we going to need files for all these layouts, even the standard ones? The answer is no. The layout system will load a number of layouts from different sources, and offer you the option of switching between all of the views specified by all of the interesting layouts. The search order is:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Explicitly specified files (on the command line)&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;gamename&amp;lt;/i&amp;gt;.lay&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;Game-specific built-in layouts&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;&amp;lt;i&amp;gt;parentname&amp;lt;/i&amp;gt;.lay&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;Generic built-in layouts&amp;lt;/li&amp;gt; &amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The key are the built-in layouts. First, each game can specify a built-in layout as a parameter to the new GAMEL macro, which mimics the existing GAME macro but takes a final parameter which a pointer to an embedded XML string that holds the game-specific built-in layouts.&lt;br /&gt;
&lt;br /&gt;
Second, there are a number of built-in layouts. By default, each screen in the game gets a Standard layout, which is simply a single screen displayed at its appropriate aspect ratio. Each screen in the game also gets a Native layout, which is a single screen displayed 1:1 with the height/width ratio of the pixels. This produces, for example, widescreen Capcom games for those who still believe they should be widescreen.&lt;br /&gt;
Multi-screen games get a few additional options for displaying both screens at the same time, either on top of each other or side-by-side.&lt;br /&gt;
And finally, just for kicks, there is a &amp;quot;cocktail&amp;quot; layout that displays two copies of screen 0, one rotated 180 degrees for a pseudo-cocktail view. How is that done? With a layout something like this:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;amp;lt;?xml version=&amp;quot;1.0&amp;quot;?&amp;amp;gt;&lt;br /&gt;
&amp;amp;lt;mamelayout version=&amp;quot;2&amp;quot;&amp;amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;lt;view name=&amp;quot;Cocktail&amp;quot;&amp;amp;gt; &amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;lt;screen index=&amp;quot;0&amp;quot;&amp;amp;gt; &amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
&amp;amp;lt;bounds left=&amp;quot;-1.33333&amp;quot; top=&amp;quot;0.0&amp;quot; right=&amp;quot;0.0&amp;quot; bottom=&amp;quot;1.0&amp;quot; /&amp;amp;gt; &amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;lt;/screen&amp;amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;lt;screen index=&amp;quot;0&amp;quot;&amp;amp;gt; &amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
&amp;amp;lt;bounds left=&amp;quot;0.01&amp;quot; top=&amp;quot;0.0&amp;quot; right=&amp;quot;1.34333&amp;quot; bottom=&amp;quot;1.0&amp;quot; /&amp;amp;gt; &amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&lt;br /&gt;
&amp;amp;lt;orientation rotate=&amp;quot;180&amp;quot; /&amp;amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;lt;/screen&amp;amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;lt;/view&amp;amp;gt;&lt;br /&gt;
&amp;amp;lt;/mamelayout&amp;amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You&#039;ll notice a couple of interesting things here. First is, you can repeat the same screen multiple times in a view if you&#039;d like. For fun, I&#039;ve even created a &amp;quot;quad&amp;quot; view that displays the screen 4 times rotated all four directions. Second is that you can specify an orientation for screens and actually for any item. This allows rotation and flipping of items, and even works with vector games or other special cases. Finally, you see how the coordinate system really is arbitrary. Here I&#039;m using&lt;br /&gt;
1.333 as the width of each screen and 1.0 as the height. This is the same as 4:3. Really. :)&lt;br /&gt;
&lt;br /&gt;
For completeness sake, here are all the attributes you can specify for&lt;br /&gt;
items:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;code&amp;gt;&amp;amp;lt;bounds left=&amp;quot;0&amp;quot; top=&amp;quot;0&amp;quot; right=&amp;quot;4&amp;quot; bottom=&amp;quot;3&amp;quot; /&amp;amp;gt; &amp;amp;lt;bounds x=&amp;quot;0&amp;quot; y=&amp;quot;0&amp;quot; width=&amp;quot;4&amp;quot; height=&amp;quot;3&amp;quot; /&amp;amp;gt; &amp;amp;lt;color red=&amp;quot;1.0&amp;quot; green=&amp;quot;1.0&amp;quot; blue=&amp;quot;1.0&amp;quot; alpha=&amp;quot;0.5&amp;quot; /&amp;amp;gt; &amp;amp;lt;orientation rotate=&amp;quot;90&amp;quot; swapxy=&amp;quot;yes&amp;quot; flipx=&amp;quot;yes&amp;quot; flipy=&amp;quot;no&amp;quot;&lt;br /&gt;
/&amp;amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
You can control the bounds either by specifying left/top/right/bottom coordinates, or by specifying x/y/width/height coordinates. But only one or the other. The color tag lets you affect the overall color and alpha blending factors of the item. Each color value ranges from 0-1. And you can control orientation of the item via both a rotate parameter as well as through more primitive flipping and swapping controls.&lt;br /&gt;
&lt;br /&gt;
Well, that seems like enough for a single article. I&#039;ll talk about elements and artwork and how they work in the next article.&lt;/div&gt;</summary>
		<author><name>Madskunk</name></author>
	</entry>
	<entry>
		<id>https://wiki.mamedev.org/index.php?title=How_MAME_Works&amp;diff=1810</id>
		<title>How MAME Works</title>
		<link rel="alternate" type="text/html" href="https://wiki.mamedev.org/index.php?title=How_MAME_Works&amp;diff=1810"/>
		<updated>2008-06-24T13:29:24Z</updated>

		<summary type="html">&lt;p&gt;Madskunk: /* Core Internals */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The following is a list of documents describing the internal workings (core) of the MAME emulator.  Most are penned by Aaron Giles.&lt;br /&gt;
&lt;br /&gt;
== Building MAME ==&lt;br /&gt;
* [[Building MAME using Microsoft Visual Studio compilers]]&lt;br /&gt;
&lt;br /&gt;
== Writing for MAME ==&lt;br /&gt;
* [[MAME Coding Conventions]]&lt;br /&gt;
&lt;br /&gt;
== For Driver Writers ==&lt;br /&gt;
* [[Resource Management in MAME]]&lt;br /&gt;
* [[DIP Switches in MAME]]&lt;br /&gt;
* [[MAME Interrupt Function Review]]&lt;br /&gt;
* [[Using MAME&#039;s tilemap system]]&lt;br /&gt;
* [http://aarongiles.com/?p=159 Programmable Logic Devices in MAME]&lt;br /&gt;
* [[CPUs and Address Spaces]]&lt;br /&gt;
* [[Address Maps]]&lt;br /&gt;
&lt;br /&gt;
== Core Internals ==&lt;br /&gt;
* [http://aarongiles.com/?p=137 CPU Scheduling in MAME]&lt;br /&gt;
* [http://aarongiles.com/?p=74 Filters and streams in the MAME Sound System]&lt;br /&gt;
* [http://aarongiles.com/?p=149 Save State Fundamentals]&lt;br /&gt;
* [[Using the GFX/TileMap viewer (F4)]]&lt;br /&gt;
* [http://aarongiles.com/?p=182 How To Use the &#039;New&#039; Renderer]&lt;br /&gt;
* [[Layouts and Rendering for MAME Artwork System]]&lt;br /&gt;
* [[LAY File Basics - Part I]]&lt;br /&gt;
&lt;br /&gt;
== Universal Dynamic Recompiler ==&lt;br /&gt;
* [[Core Concepts]]&lt;br /&gt;
* [[UML Architecture]]&lt;br /&gt;
** [[UML Control Flow Opcodes]]&lt;br /&gt;
** [[UML Internal Register Opcodes]]&lt;br /&gt;
** [[UML Integer Opcodes]]&lt;br /&gt;
** [[UML Floating Point Opcodes]]&lt;br /&gt;
* [[Dynamic Recompiler Author&#039;s Guide]]&lt;br /&gt;
* [[Back-End Author&#039;s Guide]]&lt;br /&gt;
&lt;br /&gt;
== Tips &amp;amp; Tricks ==&lt;br /&gt;
* [[Executing Code Out of a Memory Region With a Read Handler]]&lt;br /&gt;
* [[Checklist for Cleaning Up Drivers]]&lt;br /&gt;
* [[Writing Messages to the Screen In a MAME Driver]]&lt;/div&gt;</summary>
		<author><name>Madskunk</name></author>
	</entry>
	<entry>
		<id>https://wiki.mamedev.org/index.php?title=Writing_Messages_to_the_Screen_in_a_MAME_Driver&amp;diff=1809</id>
		<title>Writing Messages to the Screen in a MAME Driver</title>
		<link rel="alternate" type="text/html" href="https://wiki.mamedev.org/index.php?title=Writing_Messages_to_the_Screen_in_a_MAME_Driver&amp;diff=1809"/>
		<updated>2008-06-24T13:27:15Z</updated>

		<summary type="html">&lt;p&gt;Madskunk: Changes to remove references to &amp;#039;I&amp;#039;&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;One of the side-effects of the new video system is that drivers aren&#039;t allowed to write to the UI layer directly. They can call &amp;lt;code&amp;gt;popmessage()&amp;lt;/code&amp;gt; to display a popup at the bottom of the screen, but that&#039;s about it in the new system. The problem is that a few drivers were displaying important game-related information using the UI font. Specifically, &amp;lt;b&amp;gt;Atari Football&amp;lt;/b&amp;gt; was using it to show which plays had been selected, and the Exidy Max-a-Flex system was using it to draw the status of the lamps and timer. In retrospect, it is actually good that these cases broke because the way it was being done before was a big hack. For one thing, it meant that the game screen area was artificially increased to make room for the text. And second, the state of these lamps was not being properly exposed to the outside world (or in the case of Football, it was being changed via the rendering system in addition to being displayed on screen).&lt;br /&gt;
&lt;br /&gt;
Ideally, the state of these indicators should be made visible via the rendering system. This is great, except that in the absence of an external artwork file, there would be no visible indication at all. This is one of the reasons why it&#039;s good to have built-in layouts in the MAME code -- even if they are crude approximations of the original artwork, they at least can reflect important functional information. The problem is, built-in layouts can&#039;t really reference image files. All they can do is draw rectangles and disks, which is sufficient for basic overlays on top of old black &amp;amp; white games, but isn&#039;t really enough to provide textual information.&lt;br /&gt;
&lt;br /&gt;
In order to solve this problem, a couple of new primitives have been added to the layouts. In addition to rect and disk primitives, the two new primitives are: text and led7seg.&lt;br /&gt;
&lt;br /&gt;
The text primitive lets you add text anywhere within the artwork area. You can specify color and bounds just like the other primitives. The text is drawn using the built-in fixed-width MAME font (even if you have a different UI font), and is centered within the bounds. If there is too much text to fit in the area provided, the font will be squashed horizontally to fit. Here&#039;s an example that positions the text &amp;quot;GAME OVER&amp;quot; in red centered within the given rectangle:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;&amp;amp;lt;text string=&amp;quot;GAME OVER&amp;quot;&amp;amp;gt;&lt;br /&gt;
     &amp;amp;lt;bounds x=&amp;quot;0&amp;quot; y=&amp;quot;0&amp;quot; height=&amp;quot;10&amp;quot; width=&amp;quot;200&amp;quot; /&amp;amp;gt;&lt;br /&gt;
     &amp;amp;lt;color red=&amp;quot;1.0&amp;quot; green=&amp;quot;0.0&amp;quot; blue=&amp;quot;0.0&amp;quot; /&amp;amp;gt;&lt;br /&gt;
 &amp;amp;lt;/text&amp;amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The led7seg primitive lets you position a standard 7-segment LED somewhere in the artwork. The LEDs are drawn in a high resolution and oversampled down so they look nice. Typically these are used to specify a digit from 0-9, &amp;lt;b&amp;gt;Turbo&amp;lt;/b&amp;gt; is one example. To use this, you would typically create an element with multiple states, each state reflecting the corresponding digit. Here&#039;s an example that positions a red LED with the number &amp;quot;2&amp;quot; that is only visible with the containing element is in state &amp;quot;2&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;&amp;amp;lt;led7seg pattern=&amp;quot;10111010&amp;quot; state=&amp;quot;2&amp;quot;&amp;amp;gt;&lt;br /&gt;
     &amp;amp;lt;color red=&amp;quot;1.0&amp;quot; green=&amp;quot;0.0&amp;quot; blue=&amp;quot;0.0&amp;quot; /&amp;amp;gt;&lt;br /&gt;
 &amp;amp;lt;/led7seg&amp;amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The pattern attribute specifies which of the segments is visible. A 1 means &amp;quot;on&amp;quot;, and a 0 means &amp;quot;off&amp;quot;. They are specified in the following order:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Top horizontal segment&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Upper left vertical segment&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Upper right vertical segment&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Middle horizontal segment&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Lower left vertical segment&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Lower right vertical segment&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Bottom horizontal segment&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Decimal point&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Using these two new primitives, built-in layouts have been created for the Atari sports games (&amp;lt;b&amp;gt;Football&amp;lt;/b&amp;gt; and &amp;lt;b&amp;gt;Baseball&amp;lt;/b&amp;gt;), the Sega Z80 scaling games (&amp;lt;b&amp;gt;Turbo&amp;lt;/b&amp;gt;, &amp;lt;b&amp;gt;Subroc 3D&amp;lt;/b&amp;gt;, &amp;lt;b&amp;gt;Buck Rogers&amp;lt;/b&amp;gt;), Taito&#039;s &amp;lt;b&amp;gt;Super Speed Race&amp;lt;/b&amp;gt;, and the Exidy Max-a-Flex system that display all the essential lamps and score/timing information. Of course, you can continue to use the externally-provided artwork for a better visual appearance, but now it&#039;s possible to provide vital lamps and LEDs via the new built-in layouts without affecting the core game screen or abusing the UI system.&lt;/div&gt;</summary>
		<author><name>Madskunk</name></author>
	</entry>
	<entry>
		<id>https://wiki.mamedev.org/index.php?title=Checklist_for_Cleaning_Up_Drivers&amp;diff=1808</id>
		<title>Checklist for Cleaning Up Drivers</title>
		<link rel="alternate" type="text/html" href="https://wiki.mamedev.org/index.php?title=Checklist_for_Cleaning_Up_Drivers&amp;diff=1808"/>
		<updated>2008-06-24T13:23:47Z</updated>

		<summary type="html">&lt;p&gt;Madskunk: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Over the past year(s), Aaron has done some driver &amp;quot;cleanup&amp;quot; work. This generally involves picking apart a driver, revisiting all the assumptions using whatever information is available, and updating it to take advantage of newer features in MAME that have been introduced since it was first written. To do this work, Aaron keeps a checklist of things to do, just to make sure all bases are covered. This list is constantly updated, but since it is a good set of guidelines for updating a driver, or writing a new one from scratch, it is provided here.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Timing/interrupts:&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;li&amp;gt;all crystals on the PCB documented via #defines&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;all CPU and sound clocks derived from #defined crystal values&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;re-verify interrupt generation timing and sources&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;implement interrupt acknowledges (many older drivers didn&#039;t bother)&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;add accurate watchdog durations&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Memory:&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;li&amp;gt;unified read/write memory maps (they used to be separate)&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;map the entire address space fully, if possible from schematics&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;use AM_SHARE where appropriate (better than sharedram read/write handlers)&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;convert memory banking to the new system (memory_configure_bank)&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Graphics:&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;li&amp;gt;gfx layouts should use RGN_FRAC wherever possible instead of hard-coded values&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;gfx layouts that are common should be shared (vidhrdw/generic.c)&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;accurate hblank/vblank/visible areas, derived from schematics if possible&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;convert from old macros to new screen macros for display info&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;use new more accurate screen timing routines for H/V positions&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;convert to tilemaps, if applicable&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;change to use resistors for palette generation&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;add limits on sprite drawing (e.g., how many per scanline), if known&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Inputs:&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;li&amp;gt;tag all input ports&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;change all port references in code to use tags&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;convert non-DIP configurations to configs&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;use PORT_CUSTOM where appropriate instead of memory overrides&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;connect coin counters (often missing)&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;connect PCB outputs via the new output system&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;add DIPLOCATIONS&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;verify DIPs and inputs&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;ROMs:&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;li&amp;gt;memory regions reduced to minimum size (they don&#039;t have to cover the whole address space)&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;make sure ROM names are good and accurate to what we know&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;check for any unemulated clones&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;General:&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&amp;lt;li&amp;gt;update source files to be in order: header, includes, constants, typedefs, macros, globals, inlines, code&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;update driver file to be in the same order, followed by: address maps, input ports, graphics definitions, sound configs, machine driver, ROMs, driver init code, drivers&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;add save state support&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;move all globals to hang off of driver_data&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;de-obfuscate the code where it is confusing&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Some recent driver updates that are pretty up to date include: &amp;lt;code&amp;gt;ccastles.c, cloud9.c, missile.c, turbo.c, zaxxon.c.&amp;lt;/code&amp;gt;&lt;/div&gt;</summary>
		<author><name>Madskunk</name></author>
	</entry>
	<entry>
		<id>https://wiki.mamedev.org/index.php?title=Checklist_for_Cleaning_Up_Drivers&amp;diff=1807</id>
		<title>Checklist for Cleaning Up Drivers</title>
		<link rel="alternate" type="text/html" href="https://wiki.mamedev.org/index.php?title=Checklist_for_Cleaning_Up_Drivers&amp;diff=1807"/>
		<updated>2008-06-24T13:15:34Z</updated>

		<summary type="html">&lt;p&gt;Madskunk: New page: Over the past year, I&amp;#039;ve done some driver &amp;quot;cleanup&amp;quot; work. This generally involves picking apart a driver, revisiting all the assumptions using whatever information is available, and updati...&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;Over the past year, I&#039;ve done some driver &amp;quot;cleanup&amp;quot; work. This generally involves picking apart a driver, revisiting all the assumptions using whatever information is available, and updating it to take advantage of newer features in MAME that have been introduced since it was first written. To do this work, I keep a checklist of things to do, just to make sure I&#039;ve covered all the bases. This list is constantly updated, but I figured I would share it, since it is a good set of guidelines when updating a driver or writing a new one from scratch.&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Timing/interrupts:&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;all crystals on the PCB documented via #defines&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;all CPU and sound clocks derived from #defined crystal values&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;re-verify interrupt generation timing and sources&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;implement interrupt acknowledges (many older drivers didn&#039;t bother)&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;add accurate watchdog durations&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Memory:&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;unified read/write memory maps (they used to be separate)&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;map the entire address space fully, if possible from schematics&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;use AM_SHARE where appropriate (better than sharedram read/write handlers)&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;convert memory banking to the new system (memory_configure_bank)&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Graphics:&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;gfx layouts should use RGN_FRAC wherever possible instead of hard-coded values&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;gfx layouts that are common should be shared (vidhrdw/generic.c)&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;accurate hblank/vblank/visible areas, derived from schematics if possible&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;convert from old macros to new screen macros for display info&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;use new more accurate screen timing routines for H/V positions&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;convert to tilemaps, if applicable&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;change to use resistors for palette generation&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;add limits on sprite drawing (i.e., how many per scanline) if known&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;Inputs:&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;tag all input ports&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;change all port references in code to use tags&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;convert non-DIP configurations to configs&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;use PORT_CUSTOM where appropriate instead of memory overrides&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;connect coin counters (often missing)&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;connect PCB outputs via the new output system&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;add DIPLOCATIONS&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;verify DIPs and inputs&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;ROMs:&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;memory regions reduced to minimum size (they don&#039;t have to cover the whole address space)&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;make sure ROM names are good and accurate to what we know&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;check for any unemulated clones&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&amp;lt;b&amp;gt;General:&amp;lt;/b&amp;gt;&lt;br /&gt;
&amp;lt;ul&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;update source files to be in order: header, includes, constants, typedefs, macros, globals, inlines, code&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;update driver file to be in the same order, followed by: address maps, input ports, graphics definitions, sound configs, machine driver, ROMs, driver init code, drivers&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;add save state support&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;move all globals to hang off of driver_data&amp;lt;/li&amp;gt; &amp;lt;li&amp;gt;de-obfuscate the code where it is confusing&amp;lt;/li&amp;gt; &amp;lt;/ul&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Actually, that&#039;s quite a lot of stuff. I&#039;m sure I&#039;ve missed a thing or two in some of my recent driver updates, but some examples that are pretty up to date include: ccastles.c, cloud9.c, missile.c, turbo.c, zaxxon.c.&lt;/div&gt;</summary>
		<author><name>Madskunk</name></author>
	</entry>
	<entry>
		<id>https://wiki.mamedev.org/index.php?title=How_MAME_Works&amp;diff=1806</id>
		<title>How MAME Works</title>
		<link rel="alternate" type="text/html" href="https://wiki.mamedev.org/index.php?title=How_MAME_Works&amp;diff=1806"/>
		<updated>2008-06-24T13:15:31Z</updated>

		<summary type="html">&lt;p&gt;Madskunk: /* Tips &amp;amp; Tricks */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The following is a list of documents describing the internal workings (core) of the MAME emulator.  Most are penned by Aaron Giles.&lt;br /&gt;
&lt;br /&gt;
== Building MAME ==&lt;br /&gt;
* [[Building MAME using Microsoft Visual Studio compilers]]&lt;br /&gt;
&lt;br /&gt;
== Writing for MAME ==&lt;br /&gt;
* [[MAME Coding Conventions]]&lt;br /&gt;
&lt;br /&gt;
== For Driver Writers ==&lt;br /&gt;
* [[Resource Management in MAME]]&lt;br /&gt;
* [[DIP Switches in MAME]]&lt;br /&gt;
* [[MAME Interrupt Function Review]]&lt;br /&gt;
* [[Using MAME&#039;s tilemap system]]&lt;br /&gt;
* [http://aarongiles.com/?p=159 Programmable Logic Devices in MAME]&lt;br /&gt;
* [[CPUs and Address Spaces]]&lt;br /&gt;
* [[Address Maps]]&lt;br /&gt;
&lt;br /&gt;
== Core Internals ==&lt;br /&gt;
* [http://aarongiles.com/?p=137 CPU Scheduling in MAME]&lt;br /&gt;
* [http://aarongiles.com/?p=74 Filters and streams in the MAME Sound System]&lt;br /&gt;
* [http://aarongiles.com/?p=149 Save State Fundamentals]&lt;br /&gt;
* [[Using the GFX/TileMap viewer (F4)]]&lt;br /&gt;
* [http://aarongiles.com/?p=182 How To Use the &#039;New&#039; Renderer]&lt;br /&gt;
* [http://aarongiles.com/?p=161 Layouts and Rendering for MAME Artwork System]&lt;br /&gt;
* [[LAY File Basics - Part I]]&lt;br /&gt;
&lt;br /&gt;
== Universal Dynamic Recompiler ==&lt;br /&gt;
* [[Core Concepts]]&lt;br /&gt;
* [[UML Architecture]]&lt;br /&gt;
** [[UML Control Flow Opcodes]]&lt;br /&gt;
** [[UML Internal Register Opcodes]]&lt;br /&gt;
** [[UML Integer Opcodes]]&lt;br /&gt;
** [[UML Floating Point Opcodes]]&lt;br /&gt;
* [[Dynamic Recompiler Author&#039;s Guide]]&lt;br /&gt;
* [[Back-End Author&#039;s Guide]]&lt;br /&gt;
&lt;br /&gt;
== Tips &amp;amp; Tricks ==&lt;br /&gt;
* [[Executing Code Out of a Memory Region With a Read Handler]]&lt;br /&gt;
* [[Checklist for Cleaning Up Drivers]]&lt;br /&gt;
* [[Writing Messages to the Screen In a MAME Driver]]&lt;/div&gt;</summary>
		<author><name>Madskunk</name></author>
	</entry>
	<entry>
		<id>https://wiki.mamedev.org/index.php?title=Writing_Messages_to_the_Screen_in_a_MAME_Driver&amp;diff=1804</id>
		<title>Writing Messages to the Screen in a MAME Driver</title>
		<link rel="alternate" type="text/html" href="https://wiki.mamedev.org/index.php?title=Writing_Messages_to_the_Screen_in_a_MAME_Driver&amp;diff=1804"/>
		<updated>2008-06-24T13:11:38Z</updated>

		<summary type="html">&lt;p&gt;Madskunk: Writing Messages to the Screen In a MAME Driver moved to Writing Messages to the Screen in a MAME Driver: Wrong capitalisation&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;One of the side-effects of the new video system is that drivers aren&#039;t allowed to write to the UI layer directly. They can call &amp;lt;code&amp;gt;popmessage()&amp;lt;/code&amp;gt; to display a popup at the bottom of the screen, but that&#039;s about it in the new system. The problem is that a few drivers were displaying important game-related information using the UI font. Specifically, &amp;lt;b&amp;gt;Atari Football&amp;lt;/b&amp;gt; was using it to show which plays had been selected, and the Exidy Max-a-Flex system was using it to draw the status of the lamps and timer. In retrospect, it is actually good that these cases broke because the way it was being done before was a big hack. For one thing, it meant that the game screen area was artificially increased to make room for the text. And second, the state of these lamps was not being properly exposed to the outside world (or in the case of Football, it was being changed via the rendering system in addition to being displayed on screen).&lt;br /&gt;
&lt;br /&gt;
Ideally, the state of these indicators should be made visible via the rendering system. This is great, except that in the absence of an external artwork file, there would be no visible indication at all. This is one of the reasons why it&#039;s good to have built-in layouts in the MAME code -- even if they are crude approximations of the original artwork, they at least can reflect important functional information. The problem is, built-in layouts can&#039;t really reference image files. All they can do is draw rectangles and disks, which is sufficient for basic overlays on top of old black &amp;amp; white games, but isn&#039;t really enough to provide textual information.&lt;br /&gt;
&lt;br /&gt;
In order to solve this problem, I&#039;ve added a couple of new primitives to the layouts. In addition to rect and disk primitives, there are two new primitives: text and led7seg.&lt;br /&gt;
&lt;br /&gt;
The text primitive lets you add text anywhere within the artwork area.&lt;br /&gt;
You can specify color and bounds just like the other primitives. The text is drawn using the built-in fixed-width MAME font (even if you have a different UI font), and is centered within the bounds. If there is too much text to fit in the area provided, the font will be squashed horizontally to fit. Here&#039;s an example that positions the text &amp;quot;GAME OVER&amp;quot; in red centered within the given rectangle:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;&amp;amp;lt;text string=&amp;quot;GAME OVER&amp;quot;&amp;amp;gt;&lt;br /&gt;
     &amp;amp;lt;bounds x=&amp;quot;0&amp;quot; y=&amp;quot;0&amp;quot; height=&amp;quot;10&amp;quot; width=&amp;quot;200&amp;quot; /&amp;amp;gt;&lt;br /&gt;
     &amp;amp;lt;color red=&amp;quot;1.0&amp;quot; green=&amp;quot;0.0&amp;quot; blue=&amp;quot;0.0&amp;quot; /&amp;amp;gt;&lt;br /&gt;
 &amp;amp;lt;/text&amp;amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The led7seg primitive lets you position a standard 7-segment LED somewhere in the artwork. The LEDs are drawn in a high resolution and oversampled down so they look nice. Typically these are used to specify a digit from 0-9, &amp;lt;b&amp;gt;Turbo&amp;lt;/b&amp;gt; is one example. To use this, you would typically create an element with multiple states, each state reflecting the corresponding digit. Here&#039;s an example that positions a red LED with the number &amp;quot;2&amp;quot; that is only visible with the containing element is in state &amp;quot;2&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;&amp;amp;lt;led7seg pattern=&amp;quot;10111010&amp;quot; state=&amp;quot;2&amp;quot;&amp;amp;gt;&lt;br /&gt;
     &amp;amp;lt;color red=&amp;quot;1.0&amp;quot; green=&amp;quot;0.0&amp;quot; blue=&amp;quot;0.0&amp;quot; /&amp;amp;gt;&lt;br /&gt;
 &amp;amp;lt;/led7seg&amp;amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The pattern attribute specifies which of the segments is visible. A 1 means &amp;quot;on&amp;quot;, and a 0 means &amp;quot;off&amp;quot;. They are specified in the following order:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Top horizontal segment&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Upper left vertical segment&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Upper right vertical segment&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Middle horizontal segment&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Lower left vertical segment&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Lower right vertical segment&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Bottom horizontal segment&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Decimal point&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Using these two new primitives, I&#039;ve created built-in layouts for the Atari sports games (&amp;lt;b&amp;gt;Football&amp;lt;/b&amp;gt; and &amp;lt;b&amp;gt;Baseball&amp;lt;/b&amp;gt;), the Sega Z80 scaling games (&amp;lt;b&amp;gt;Turbo&amp;lt;/b&amp;gt;, &amp;lt;b&amp;gt;Subroc 3D&amp;lt;/b&amp;gt;, &amp;lt;b&amp;gt;Buck Rogers&amp;lt;/b&amp;gt;), Taito&#039;s &amp;lt;b&amp;gt;Super Speed Race&amp;lt;/b&amp;gt;, and the Exidy Max-a-Flex system that display all the essential lamps and score/timing information. Of course, you can continue to use the externally-provided artwork for a better visual appearance, but now it&#039;s possible to provide vital lamps and LEDs via the new built-in layouts without affecting the core game screen or abusing the UI system.&lt;/div&gt;</summary>
		<author><name>Madskunk</name></author>
	</entry>
	<entry>
		<id>https://wiki.mamedev.org/index.php?title=Writing_Messages_to_the_Screen_in_a_MAME_Driver&amp;diff=1803</id>
		<title>Writing Messages to the Screen in a MAME Driver</title>
		<link rel="alternate" type="text/html" href="https://wiki.mamedev.org/index.php?title=Writing_Messages_to_the_Screen_in_a_MAME_Driver&amp;diff=1803"/>
		<updated>2008-06-24T13:10:32Z</updated>

		<summary type="html">&lt;p&gt;Madskunk: &lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;One of the side-effects of the new video system is that drivers aren&#039;t allowed to write to the UI layer directly. They can call &amp;lt;code&amp;gt;popmessage()&amp;lt;/code&amp;gt; to display a popup at the bottom of the screen, but that&#039;s about it in the new system. The problem is that a few drivers were displaying important game-related information using the UI font. Specifically, &amp;lt;b&amp;gt;Atari Football&amp;lt;/b&amp;gt; was using it to show which plays had been selected, and the Exidy Max-a-Flex system was using it to draw the status of the lamps and timer. In retrospect, it is actually good that these cases broke because the way it was being done before was a big hack. For one thing, it meant that the game screen area was artificially increased to make room for the text. And second, the state of these lamps was not being properly exposed to the outside world (or in the case of Football, it was being changed via the rendering system in addition to being displayed on screen).&lt;br /&gt;
&lt;br /&gt;
Ideally, the state of these indicators should be made visible via the rendering system. This is great, except that in the absence of an external artwork file, there would be no visible indication at all. This is one of the reasons why it&#039;s good to have built-in layouts in the MAME code -- even if they are crude approximations of the original artwork, they at least can reflect important functional information. The problem is, built-in layouts can&#039;t really reference image files. All they can do is draw rectangles and disks, which is sufficient for basic overlays on top of old black &amp;amp; white games, but isn&#039;t really enough to provide textual information.&lt;br /&gt;
&lt;br /&gt;
In order to solve this problem, I&#039;ve added a couple of new primitives to the layouts. In addition to rect and disk primitives, there are two new primitives: text and led7seg.&lt;br /&gt;
&lt;br /&gt;
The text primitive lets you add text anywhere within the artwork area.&lt;br /&gt;
You can specify color and bounds just like the other primitives. The text is drawn using the built-in fixed-width MAME font (even if you have a different UI font), and is centered within the bounds. If there is too much text to fit in the area provided, the font will be squashed horizontally to fit. Here&#039;s an example that positions the text &amp;quot;GAME OVER&amp;quot; in red centered within the given rectangle:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;&amp;amp;lt;text string=&amp;quot;GAME OVER&amp;quot;&amp;amp;gt;&lt;br /&gt;
     &amp;amp;lt;bounds x=&amp;quot;0&amp;quot; y=&amp;quot;0&amp;quot; height=&amp;quot;10&amp;quot; width=&amp;quot;200&amp;quot; /&amp;amp;gt;&lt;br /&gt;
     &amp;amp;lt;color red=&amp;quot;1.0&amp;quot; green=&amp;quot;0.0&amp;quot; blue=&amp;quot;0.0&amp;quot; /&amp;amp;gt;&lt;br /&gt;
 &amp;amp;lt;/text&amp;amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The led7seg primitive lets you position a standard 7-segment LED somewhere in the artwork. The LEDs are drawn in a high resolution and oversampled down so they look nice. Typically these are used to specify a digit from 0-9, &amp;lt;b&amp;gt;Turbo&amp;lt;/b&amp;gt; is one example. To use this, you would typically create an element with multiple states, each state reflecting the corresponding digit. Here&#039;s an example that positions a red LED with the number &amp;quot;2&amp;quot; that is only visible with the containing element is in state &amp;quot;2&amp;quot;:&lt;br /&gt;
&lt;br /&gt;
 &amp;lt;code&amp;gt;&amp;amp;lt;led7seg pattern=&amp;quot;10111010&amp;quot; state=&amp;quot;2&amp;quot;&amp;amp;gt;&lt;br /&gt;
     &amp;amp;lt;color red=&amp;quot;1.0&amp;quot; green=&amp;quot;0.0&amp;quot; blue=&amp;quot;0.0&amp;quot; /&amp;amp;gt;&lt;br /&gt;
 &amp;amp;lt;/led7seg&amp;amp;gt;&amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The pattern attribute specifies which of the segments is visible. A 1 means &amp;quot;on&amp;quot;, and a 0 means &amp;quot;off&amp;quot;. They are specified in the following order:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Top horizontal segment&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Upper left vertical segment&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Upper right vertical segment&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Middle horizontal segment&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Lower left vertical segment&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Lower right vertical segment&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Bottom horizontal segment&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Decimal point&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Using these two new primitives, I&#039;ve created built-in layouts for the Atari sports games (&amp;lt;b&amp;gt;Football&amp;lt;/b&amp;gt; and &amp;lt;b&amp;gt;Baseball&amp;lt;/b&amp;gt;), the Sega Z80 scaling games (&amp;lt;b&amp;gt;Turbo&amp;lt;/b&amp;gt;, &amp;lt;b&amp;gt;Subroc 3D&amp;lt;/b&amp;gt;, &amp;lt;b&amp;gt;Buck Rogers&amp;lt;/b&amp;gt;), Taito&#039;s &amp;lt;b&amp;gt;Super Speed Race&amp;lt;/b&amp;gt;, and the Exidy Max-a-Flex system that display all the essential lamps and score/timing information. Of course, you can continue to use the externally-provided artwork for a better visual appearance, but now it&#039;s possible to provide vital lamps and LEDs via the new built-in layouts without affecting the core game screen or abusing the UI system.&lt;/div&gt;</summary>
		<author><name>Madskunk</name></author>
	</entry>
	<entry>
		<id>https://wiki.mamedev.org/index.php?title=How_MAME_Works&amp;diff=1802</id>
		<title>How MAME Works</title>
		<link rel="alternate" type="text/html" href="https://wiki.mamedev.org/index.php?title=How_MAME_Works&amp;diff=1802"/>
		<updated>2008-06-24T12:52:39Z</updated>

		<summary type="html">&lt;p&gt;Madskunk: /* Tips &amp;amp; Tricks */&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;The following is a list of documents describing the internal workings (core) of the MAME emulator.  Most are penned by Aaron Giles.&lt;br /&gt;
&lt;br /&gt;
== Building MAME ==&lt;br /&gt;
* [[Building MAME using Microsoft Visual Studio compilers]]&lt;br /&gt;
&lt;br /&gt;
== Writing for MAME ==&lt;br /&gt;
* [[MAME Coding Conventions]]&lt;br /&gt;
&lt;br /&gt;
== For Driver Writers ==&lt;br /&gt;
* [[Resource Management in MAME]]&lt;br /&gt;
* [[DIP Switches in MAME]]&lt;br /&gt;
* [[MAME Interrupt Function Review]]&lt;br /&gt;
* [[Using MAME&#039;s tilemap system]]&lt;br /&gt;
* [http://aarongiles.com/?p=159 Programmable Logic Devices in MAME]&lt;br /&gt;
* [[CPUs and Address Spaces]]&lt;br /&gt;
* [[Address Maps]]&lt;br /&gt;
&lt;br /&gt;
== Core Internals ==&lt;br /&gt;
* [http://aarongiles.com/?p=137 CPU Scheduling in MAME]&lt;br /&gt;
* [http://aarongiles.com/?p=74 Filters and streams in the MAME Sound System]&lt;br /&gt;
* [http://aarongiles.com/?p=149 Save State Fundamentals]&lt;br /&gt;
* [[Using the GFX/TileMap viewer (F4)]]&lt;br /&gt;
* [http://aarongiles.com/?p=182 How To Use the &#039;New&#039; Renderer]&lt;br /&gt;
* [http://aarongiles.com/?p=161 Layouts and Rendering for MAME Artwork System]&lt;br /&gt;
* [[LAY File Basics - Part I]]&lt;br /&gt;
&lt;br /&gt;
== Universal Dynamic Recompiler ==&lt;br /&gt;
* [[Core Concepts]]&lt;br /&gt;
* [[UML Architecture]]&lt;br /&gt;
** [[UML Control Flow Opcodes]]&lt;br /&gt;
** [[UML Internal Register Opcodes]]&lt;br /&gt;
** [[UML Integer Opcodes]]&lt;br /&gt;
** [[UML Floating Point Opcodes]]&lt;br /&gt;
* [[Dynamic Recompiler Author&#039;s Guide]]&lt;br /&gt;
* [[Back-End Author&#039;s Guide]]&lt;br /&gt;
&lt;br /&gt;
== Tips &amp;amp; Tricks ==&lt;br /&gt;
* [[Executing Code Out of a Memory Region With a Read Handler]]&lt;br /&gt;
* [http://aarongiles.com/?p=195 Checklist for Cleaning Up Drivers]&lt;br /&gt;
* [[Writing Messages to the Screen In a MAME Driver]]&lt;/div&gt;</summary>
		<author><name>Madskunk</name></author>
	</entry>
	<entry>
		<id>https://wiki.mamedev.org/index.php?title=Writing_Messages_to_the_Screen_in_a_MAME_Driver&amp;diff=1801</id>
		<title>Writing Messages to the Screen in a MAME Driver</title>
		<link rel="alternate" type="text/html" href="https://wiki.mamedev.org/index.php?title=Writing_Messages_to_the_Screen_in_a_MAME_Driver&amp;diff=1801"/>
		<updated>2008-06-24T12:51:56Z</updated>

		<summary type="html">&lt;p&gt;Madskunk: New page: One of the side-effects of the new video system is that drivers aren&amp;#039;t allowed to write to the UI layer directly. They can call popmessage() to display a popup at the bottom of the screen,...&lt;/p&gt;
&lt;hr /&gt;
&lt;div&gt;One of the side-effects of the new video system is that drivers aren&#039;t allowed to write to the UI layer directly. They can call popmessage() to display a popup at the bottom of the screen, but that&#039;s about it in the new system. The problem is that a few drivers were displaying important game-related information using the UI font. Specifically, &amp;lt;b&amp;gt;Atari Football&amp;lt;/b&amp;gt; was using it to show which plays had been selected, and the Exidy Max-a-Flex system was using it to draw the status of the lamps and timer. It retrospect, it is actually good that these cases broke because the way it was being done before was a big hack. For one thing, it meant that the game screen area was artificially increased to make room for the text. And second, the state of these lamps was not being properly exposed to the outside world (or in the case of Football, it was being changed via the rendering system in addition to being displayed on screen).&lt;br /&gt;
&lt;br /&gt;
Ideally, the state of these indicators should be made visible via the rendering system. This is great, except that in the absence of an external artwork file, there would be no visible indication at all. This is one of the reasons why it&#039;s good to have built-in layouts in the MAME code -- even if they are crude approximations of the original artwork, they at least can reflect important functional information. The problem is, built-in layouts can&#039;t really reference image files. All they can do is draw rectangles and disks, which is sufficient for basic overlays on top of old black &amp;amp; white games, but isn&#039;t really enough to provide textual information.&lt;br /&gt;
&lt;br /&gt;
In order to solve this problem, I&#039;ve added a couple of new primitives to the layouts. In addition to rect and disk primitives, there are two new&lt;br /&gt;
primitives: text and led7seg.&lt;br /&gt;
&amp;lt;!--more--&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The text primitive lets you add text anywhere within the artwork area.&lt;br /&gt;
You can specify color and bounds just like the other primitives. The text is drawn using the built-in fixed-width MAME font (even if you have a different UI font), and is centered within the bounds. If there is too much text to fit in the area provided, the font will be squashed horizontally to fit. Here&#039;s an example that positions the text &amp;quot;GAME OVER&amp;quot; in red centered within the given rectangle:&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;amp;lt;text string=&amp;quot;GAME OVER&amp;quot;&amp;amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;lt;bounds x=&amp;quot;0&amp;quot; y=&amp;quot;0&amp;quot; height=&amp;quot;10&amp;quot; width=&amp;quot;200&amp;quot;&lt;br /&gt;
/&amp;amp;gt;&lt;br /&gt;
&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;lt;color red=&amp;quot;1.0&amp;quot; green=&amp;quot;0.0&amp;quot; blue=&amp;quot;0.0&amp;quot; /&amp;amp;gt; &amp;amp;lt;/text&amp;amp;gt; &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The led7seg primitive lets you position a standard 7-segment LED somewhere in the artwork. The LEDs are drawn a high resolution and oversampled down so they look nice. Typically these are used to specify a digit from 0-9. Turbo is one example. To use this, you would typically create an element with multiple states, each state reflecting the corresponding digit. Here&#039;s an example that positions a red LED with the number &amp;quot;2&amp;quot; that is only visible with the containing element is in state&lt;br /&gt;
&amp;quot;2&amp;quot;:&lt;br /&gt;
&amp;lt;code&amp;gt;&lt;br /&gt;
&amp;amp;lt;led7seg pattern=&amp;quot;10111010&amp;quot; state=&amp;quot;2&amp;quot;&amp;amp;gt; &amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;nbsp;&amp;amp;lt;color red=&amp;quot;1.0&amp;quot; green=&amp;quot;0.0&amp;quot; blue=&amp;quot;0.0&amp;quot; /&amp;amp;gt; &amp;amp;lt;/text&amp;amp;gt; &amp;lt;/code&amp;gt;&lt;br /&gt;
&lt;br /&gt;
The pattern attribute specifies which of the segments is visible. A 1 means &amp;quot;on&amp;quot;, and a 0 means &amp;quot;off&amp;quot;. They are specified in the following&lt;br /&gt;
order:&lt;br /&gt;
&lt;br /&gt;
&amp;lt;ol&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Top horizontal segment&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Upper left vertical segment&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Upper right vertical segment&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Middle horizontal segment&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Lower left vertical segment&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Lower right vertical segment&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Bottom horizontal segment&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;li&amp;gt;Decimal point&amp;lt;/li&amp;gt;&lt;br /&gt;
&amp;lt;/ol&amp;gt;&lt;br /&gt;
&lt;br /&gt;
Using these two new primitives, I&#039;ve created built-in layouts for the Atari sports games (&amp;lt;b&amp;gt;Football&amp;lt;/b&amp;gt; and &amp;lt;b&amp;gt;Baseball&amp;lt;/b&amp;gt;), the Sega Z80 scaling games (&amp;lt;b&amp;gt;Turbo&amp;lt;/b&amp;gt;, &amp;lt;b&amp;gt;Subroc 3D&amp;lt;/b&amp;gt;, &amp;lt;b&amp;gt;Buck Rogers&amp;lt;/b&amp;gt;), Taito&#039;s &amp;lt;b&amp;gt;Super Speed Race&amp;lt;/b&amp;gt;, and the Exidy Max-a-Flex system that display all the essential lamps and score/timing information. Of course, you can continue to use the externally-provided artwork for a better visual appearance, but now it&#039;s possible to provide vital lamps and LEDs via the new built-in layouts without affecting the core game screen or abusing the UI system.&lt;br /&gt;
&lt;br /&gt;
Tomorrow I&#039;ll write about the second big change coming, which is related to the issue of lamps and other signals output from the arcade PCBs.&lt;/div&gt;</summary>
		<author><name>Madskunk</name></author>
	</entry>
</feed>