Game & Watch LCD Emulation: Mapping SM510 Outputs to Custom Segment Artwork
Trace MAME's SM510-family LCD outputs into per-title SVG artwork, input matrices, persistence state, and reproducible display tests.
For the SM510 Game & Watch titles modeled here, MAME maps MCU segment/common outputs rather than maintaining a conventional framebuffer. The controller selects groups of segments and common lines; MAME’s handheld driver translates that state through an X/Y/Z map and combines it with title-specific SVG artwork. That architecture is useful both for understanding the emulator and for debugging a display that looks wrong even when the game logic is running.
This guide follows the pinned MAME source revision listed below. It describes MAME’s model, not a verified electrical reconstruction of every original panel. In particular, MAME’s own comments distinguish its periodic output model from the higher-frequency scan that occurs in the physical device.
Follow segment state instead of assuming pixels
The SM510 core’s lcd_update() iterates four LCD scan columns. For each column it emits A, B, and C segment rows through the write_segs callback, plus a separate blink/status output derived from the L, X, and Y registers and gated by BP/BC state. MAME schedules this operation periodically. The source comments that the physical controller strobes a segment at high frequency, while the emulator’s default timer is approximately one kilohertz. Treat that as the emulator’s update cadence, not as a measurement of the original LCD waveform.
The handheld driver receives those writes and records segment bits. Its SM510 path sets the display dimensions to two group bits, sixteen segments, and two common bits. The output mapper then interprets each state as x.y.z: the group selects A/B/BS/C, the segment selects one of sixteen positions, and the common selects H1 through H4. The related SM5A/SM500/SM530 setup uses a different group/segment/common shape, so an emulator developer should not apply the SM510 dimensions to every calculator or handheld that happens to have an LCD.
The core-to-driver boundary is visible in a small source excerpt:
void hh_sm510_state::sm510_lcd_segment_w(offs_t offset, u16 data)
{
set_display_size(2, 16, 2);
m_display_state[offset] = data;
}
The important work is not merely storing data. The chosen model dimensions tell the later display update how to expand the compact segment state into output coordinates. MAME’s SVG screen device indexes artwork shapes by their SVG title and changes shape visibility when an output with the matching name changes. When a title shows the wrong icon or a whole row appears shifted, check the CPU callback, output name, and artwork title before adjusting the artwork’s scale or the host window size.
Separate the controller map from the title’s drawing
MAME’s handheld driver declares the display artwork as title-specific ROM regions. Donkey Kong model DK-52 is a useful example: its driver configures two vertically arranged screens and declares separate top and bottom SVG regions with their own byte lengths, CRCs, and SHA-1 values. The panel drawing is therefore data associated with a driver, while the SM510 state determines which mapped segments are active.
ROM_REGION( 176843, "screen_top", 0 )
ROM_LOAD( "gnw_dkong_top.svg", 0, 176843,
CRC(16c16b84) SHA1(fa2e54c04366a30b51de024296b9f94c1cb76d68) )
ROM_REGION( 145516, "screen_bottom", 0 )
ROM_LOAD( "gnw_dkong_bottom.svg", 0, 145516,
CRC(2b711e9d) SHA1(0e263020cbe0e8b88bb68e3176630639b518935e) )
These declarations let a reviewer reproduce which asset bytes the pinned driver expects. A matching checksum verifies the file contents against that source declaration; it does not independently establish who scanned or reconstructed the original panel. MAME’s driver specifically notes that some SM511/SM512 melody ROM data was reconstructed from playback; for the listed titles it still requests decap/visual verification or a re-dump. Preserve that provenance distinction when documenting a dump or a replacement asset.
This split is operationally helpful. If the game logic toggles a segment but the rendered panel does not, inspect the chain in order: the CPU’s RAM and blink state, the write_segs callback, the handheld’s X/Y/Z index mapping, and finally the SVG element associated with that output. A single screenshot cannot identify which layer failed. A trace or minimal test that activates one group and one segment at a time can.
Understand MAME’s persistence approximation
Physical LCDs do not switch from dark to fully visible instantaneously. MAME models a delayed on/off response with per-segment decay counters. The handheld state schedules decay updates at 1,024 Hz; its source describes the timing in approximate one-kilohertz ticks. The default pivot and decay length are emulator parameters, and the display code converts the counter into an on/off output state. It does not turn that state into per-segment analog brightness in the SVG renderer.
That limit is explicit in the driver: its TODO notes that SVG cannot set brightness for each segment, so adding another PWM display device would not currently improve the model. Therefore, describe the implementation as a useful anti-flicker/persistence approximation, not a physically exact LCD simulation. If you are comparing MAME with a camera recording, remember that the real device’s scanning, optical response, camera exposure, and the emulator’s update loop are different parts of the measurement.
MAME registers the segment state, decay counters, dimension fields, and decay parameters for save states. This is the right kind of state to preserve: a restore should not rebuild the display from a guessed screenshot when the emulator already tracks which segments are active and how far each has progressed through the persistence model. A focused regression test should save during a changing animation, restore, and compare subsequent segment outputs, not only the final composed picture.
Treat buttons as a multiplexed input circuit
The same driver also models button reads as selected input rows. Its S-output handler updates an input multiplexer; read_inputs() combines only the rows selected by that multiplexer, plus any fixed row for the specific model. When input changes, the driver updates the SM510 external wake-up input based on whether the emulated K-port read is active. This explains why a button that appears in a frontend menu can still fail inside a game: the title’s row/bit mapping and wake behavior are separate from the host’s keyboard or gamepad binding.
DK-52’s input map puts Jump on IN.0, the four directions on IN.1, Time, Game B, Game A, and Alarm on IN.2, and ACL on its own port. Validate each control against the named port and bit, then test both the normal game loop and any wake-from-idle path. Do not “fix” an input issue by changing LCD geometry; that crosses subsystem boundaries and can hide the actual fault.
A reproducible review sequence
- Pin the exact MAME revision and inspect the title driver, CPU-family setup, ROM declarations, input ports, and display callback together. A title name alone does not prove that two revisions use identical artwork or segment wiring.
- Verify each ROM or SVG against the CRC/SHA values where that revision declares them. Keep local preservation files unchanged; use copies for experiments and record their source and hash.
- Test one input row and one segment group at a time. Capture the emulated register/output state and the rendered display so a mapping error is distinguishable from an asset error.
- Exercise separate screens on dual-display titles. Confirm top and bottom artwork are both loaded and that activating one game’s segment does not appear on the other screen.
- Save and restore while segment states are changing. Compare the next several output updates after restore, not merely the first static frame.
- Document fidelity limits. MAME source is excellent evidence for MAME’s implementation, but a source comment or checksum is not a hardware measurement or a complete provenance chain.
The practical lesson is that retro LCD emulation has a real data path: controller RAM, a periodic core callback, a family-specific segment matrix, a persistence filter, and model-specific artwork. Following those boundaries makes a broken icon, flickering segment, or unresponsive button diagnosable without mistaking a vector drawing for the original electrical display.
Related:
- MAME Driver Save States: Register Runtime Data and Rebuild Derived State
- MAME NVRAM Preservation: Separating Persistent Cabinet State from Save States
Sources:
- MAME SM510 core: LCD RAM groups, blink/status output, and emulated scan cadence at the reviewed revision
- MAME handheld driver: segment mapping, decay state, input matrix, and wake line at the reviewed revision
- MAME handheld driver: CPU-family callbacks route SM5A, SM500-style, and SM510 devices to their display mappings
- MAME handheld driver: DK-52 dual-screen configuration and expected SVG hashes at the reviewed revision
- MAME handheld driver: reconstructed melody-ROM data and remaining verification notes at the reviewed revision
- MAME SVG screen device: map output names to SVG titles and toggle matching shapes at the reviewed revision
- MAME SM510 core: external wake-up line semantics at the reviewed revision
- MAME handheld state definition: default segment persistence parameters at the reviewed revision