DMD

December 27, 2025 · View on GitHub

Emulating the DMD pursues the following purposes:

  • providing emulators (PinMame, VPX,...) with informations allowing rendering of a virtual DMD as accurately as possible,
  • driving modern DMD hardware boards which implement their own shading capabilities,
  • providing frames that can be uniquely identified to perform colorization or trigger events (f.e. PinUp display events).

These aims lead the DMD emulation to evaluate 2 different things:

  • luminance frames, which are suited for accurate rendering, but may vary as the luminance model improves,
  • raw frames, which can be used to uniquely identify frames for colorization, and can also be used for rendering but less accurately (mainly for backward compatibility, since this was the only thing available until PinMame 3.6).

All DMD control boards use Pulse Width Modulation (PWM) to create shades: they quickly toggle the dots on and off, and the observer eyes perceive a shade between fully off and fully on. The limit between perceiving flicker vs perceiving a stable shade is called the flicker/fusion threshold. It depends mainly on 2 factors:

  • the speed at which the dots switch on/off (do they ramp up/down quickly or do they fade more slowly),
  • the device luminance level, which impacts how the human eye perceive light (Ferry/Porter law).

For neon plasma DMDs, the flicker/fusion threshold is estimated to be around 25Hz, based on the analysis of existing hardware that feature PWM frequencies down to 30Hz, but avoid to get lower (See Phantom Haus). This means that the perceived luminance is influenced by what was displayed during the last 1/25 seconds (40ms). A consequence of this is that correct luminance may only be evaluated by considering the frames that makes up the PWM pattern as well as the ones displayed before.

The flicker/fusion limit for LED DMDs is unknown, perhaps higher as display is usually less bright which impacts the Ferry/Porter law, and LEDs have a faster on/off switching time.

State of DMD emulation

The table below gives the main information (PWM FPS / Display FPS / PWM pattern) for all emulated hardware, as well as the state of emulation as of writing (2024/09/18):

NamePWM FPS / Disp.FPSPWM patternEmulation comments
WPC122.1 / 61.1-40.72/3 frames
WPC Phantom Haus61.05 / 30.12 frames
Data East 128x16177.5 / 59.22u row
Data East 128x32234.2 / 78.12u rowSome machines exhibit slow startup
Sega 192x64224.2 / 74.732u rowTitle screen shows sometimes, likely due to timing issues
Gottlieb GTS3375.9 / 125.3-37.63/6/8/10 frames
Alvin G. 1293.7 / 73.44 row
Alvin G. 2298.6 / 74.64 row
Sega/Stern Whitestar233.3 / 77.82u row
Inder134.8 / ??Review in progress
Sleic244.1?Review in progress
Spinball132.9?Review in progress
Capcom508.7 / 127.2-42.43/6/9u frames
Stern SAM751.2 / 62.64u rowNeeds overall emulation timing fixes, interframe emulation, shade validation, back/front mix validation
Stern Spike 1952.4 / 63.54u framesUnsupported hardware
  • 'u' stands for 'unbalanced': each row/frame has a different display length.
  • All FPS are expressed in Hz (same as frame per second), the ones in bold have been verified on real hardware.
  • PWM can be performed per row or per frame (PWM FPS is computed considering equivalent per frame FPS). When done per frame, the game code may dynamically change the PWM pattern length.

WPC

WPC continuously renders frames at 122.1Hz. The game code uses this to render sequences of either 1 (0/100), 2 (0/50/100), or 3 (0/33/66/100) frames, expecting the viewer eye to merge these frames into shades. For example, Terminator 2 uses a 2 frame PWM pattern while Creature from the Black Lagoon uses a 3 frame PWM pattern.

Phantom Haus uses a double height DMD which is rasterized by the same hardware at half frequency: 61.5Hz. As a consequence, the game only uses a 2 frame PWM pattern, likely to avoid flicker.

Alvin G

This hardware is made of discrete circuits with available datasheets, allowing to directly read & perform digital simulation. There have been 2 different board revisions:

  • PCA020 for "Al's Garage Band Goes On a World Tour" which was modified after production by adding a clock divider to the rasterizer (existing schematics are incomplete),
  • PCA020A which integrates this clock divider as well as other slight improvments for later games.

Precise signal recordings are available from PPUC DMD reader project.

This is a simple rasterizer which rasterizes each row 4 times, either from the same data source (no shading) or from 4 contiguous RAM locations allowing 0 / 25 / 50 / 75 / 100 brightness levels.

Data East 128x16

The hardware uses a Z80 that performs frame preparation as well as direct rasterization to the DMD. It rasterizes each row twice with different lengths: 0.13ms and 0.37ms. This allows the hardware to render 0 / 33 / 66 / 100 brightness levels.

Data East 128x32 & Sega/Stern Whitestar

These systems share nearly identical hardware: board 520-5055-00 for Data East, 520-5055-01 to 520-5055-03 for Whitestar. These boards are built around a CRTC 6845 rasterizer, a 6809 CPU and 2 PAL chips in charge of address decoding (U16) and custom rasterization (U2).

Precise signal recordings are available from RGB DMD project. They show that each row is rasterized twice, once at 500kHz and then at 1MHz. They also show that the rasterizer setup changed between the initial revision of the board (Data East) and later ones (Sega/Stern). Since the wiring did not change and the software seems similar, this leads to the guess that the U2 chip setup was modified.

U16 is the main address decoder. It is a PAL16L8, which is a logic combiner (no flip flop). These are the guessed logics:

InputOutputTyGuessed output logic
BA15/RAMWROWrite (/BWR) & RAMCS
BA14/RAMCSIOBA = 0xxx | BA = 1xxx | BA = 2xxx
BA13/PORTIN => read latch from CPUIORead (/BWR) & BA = 3xxx & BA1
BA12/CRTCCSIOBA = 3xxx & not BA1
XA0CORE => Enable XA ROM/RAM bankingIOBA = 2xxx | BA = 4xxx
/BWR/BSE => latch XA0..7IOWrite (/BWR) & BA = 3xxx & BA1
BA1/ROMCS => Read ROM / Write StatusIOBA = 4xxx to Fxxx
XA5ZA0 => ROM A14 / RAM MA12OXA0 or XA5 depending on ROMCS/RAMCS and on BA12..15 for static ROM/RAM area
/E
/Q

U2 drives the rasterizer by toggling the 6845 clock signal divider. It is a PAL16R4, which is a logic combiner with additional flip flops. Its behavior is still largely unknown.

InputOutputTyGuessed output logic
CURSOR from 6845/FIRQIO
HSYNC from 6845/DEIO
DDATA/SDATAQ
RA0/RDATAQ
DE from 6845/DOTCLK to 6845QDerived from (RA0 ? Clock/2 : Clock/4)
/CRTCCSN.C.QInternal Clock/2
CA0 from 6845/PCLOCKIO
CA13 from 6845CLATCHIODerived from HSYNC

Capcom

Precise signal recordings are available from PPUC DMD reader project. They show that each row is rasterized once per frame, hence the PWM pattern is formed by a group of frames like WPC or GTS3. Unlike WPC or GTS3, the CPU is not the only one in charge of PWM pattern generation: a custom chip (U16) is in charge of the rasterization which is done by reading 2 bits per dot and generating 4 frames from these. These 4 frames are made up from the 2 bit image using the following patterns:

  • 0 -> 0000 -> 0% luminance
  • 1 -> 1000 -> 25% luminance
  • 2 -> 0101 -> 50% luminance
  • 3 -> 1111 -> 100% luminance

The emulation logs show that on some animations, the CPU may also dynamically toggle pages very quickly (2ms), leading to more complex PWM patterns and hence more perceived shades.

The U16 always rasterizes 256 dots per row, even if the DMD is only 128 dots wide. The extra dots are simply not processed by the display (actually the ignored dots are the first ones of the line as they are pushed outside of the 128 bit shift register by the other bits).

Stern SAM

Precise signal recordings are available from RGB DMD project. They show that on the SAM system, each row is rasterized 4 times with different lengths: 2 / 4 / 1 / 5 times 41.6µs. These timings lead to 12x41.6µs per row, and 32x12x41.6µs = 15.97ms per frame which match the 62.6 FPS measured on the real hardware.

This design allows the hardware to display 13 regularly spread shades from 0 to 100%, but when rasteriring, RAM only uses 12 of these. The mapping between these is guessed by the emulation and maybe incorrect.

Stern Spike 1

Precise signal recordings are available from RGB DMD project. They show that the Spike 1 system uses a PWM pattern made of 4 frames with different lengths: 1 / 2 / 4 / 8 times 1.05ms. These timings lead to 15.75ms for a complete PWM pattern, that is to say 63.5 FPS, and allows to create 16 regularly spread shades.