Skip to content

osd: add serial output provider#15256

Open
KoalaBear wants to merge 2 commits into
mamedev:masterfrom
KoalaBear:feature/serial_io
Open

osd: add serial output provider#15256
KoalaBear wants to merge 2 commits into
mamedev:masterfrom
KoalaBear:feature/serial_io

Conversation

@KoalaBear
Copy link
Copy Markdown

osd: add serial output provider

Adds a new OSD output module that streams MAME output notifications over a serial port, with the same neutral one-way semantics as the existing network provider. Every notify(name, value) becomes one name = value\n line on the wire.

Motivation

MAME's existing output providers (console, network, windows) are software notification channels. Real arcade hardware that implements core arcade behaviour - ticket dispensers, coin hoppers, coin acceptors, lamp boards - talks serial natively. Today the only way to bridge MAME to that hardware is to take -output network, write a userspace TCP-to-serial process, and ship/maintain it alongside MAME.

For the common "MAME -> COM port -> I/O board" topology a built-in module is simpler, has fewer moving parts, and matches user expectations. Operators running games on a real cabinet (ddboy, shuriboy, fuusenpn, tsupenta, mariorou, tsukande, and similar ticket/medal games) get a drop-in path to drive their hardware.

Design

Architecturally identical to src/osd/modules/output/network.cpp:

  • Implements osd_module + output_module, registers under the output provider type as serial.
  • notify() formats "%s = %d\n" and writes synchronously to the port. Writes are non-blocking (WriteTotalTimeoutConstant = 0 on Windows, O_NONBLOCK on POSIX) so a stuck or disconnected host can never stall the emulation thread.
  • Cross-platform via straight Win32 (CreateFileA + SetCommState) and POSIX termios. No third-party deps; no changes to anything outside src/osd/modules/output/ and the small option/registration edits below.

Two new CLI options:

  • -output_serial_port <name>: port name, e.g. COM4 or /dev/ttyUSB0. Empty by default; if no port is set when -output serial is selected, init logs a clear error and MAME falls back to -output none (same fallback flow as any other failed module).
  • -output_serial_baud <rate>: defaults to 9600.

Testing

  • Built and ran against ddboy (Konami medal, src/mame/konami/konmedal.cpp).
  • Verified ROM via mame -verifyroms ddboy (good).
  • Played the game end-to-end with a real serial listener attached:
    • lamp activity (lamp0 = 1 / lamp0 = 0) appears during attract mode at the expected ~130 ms cadence
    • inserting a coin stops the lamp blink (game leaves attract)
    • on a 4-ticket payout, the wire shows exactly four hopper = 0 -> 1 rising edges at the 100 ms period the driver configures via HOPPER(config, "hopper", attotime::from_msec(100))
    • all lines newline-terminated, no truncation, no out-of-order interleaving with other outputs (lamp + hopper coexist correctly)
  • srcclean run against the new file and the touched files; zero changes.

Scope / non-goals

Intentionally one-way (MAME -> wire only). Adding an input/feedback path (e.g. external sensor pulses driving the ticket dispenser device) is a much bigger design conversation. There is no clean MAME-core API today for OSD modules to inject data into a specific emulated device, and the right answer probably lives at the device or input layer rather than the output layer. Out of scope for this PR.

Where this fits in practice

This module is the upstream-side counterpart to Arcadeify, a plug-and-play PCB that sits between a PC running MAME and physical arcade hardware (ticket dispenser, coin hopper, coin acceptor, panel buttons). Arcadeify already speaks serial; with this module MAME can drive it directly without any user-side bridge process. The same module is equally usable by anyone with a different serial-attached I/O board.

Inputs (coin pulses, button presses) reach MAME through a separate HID-keyboard path on the controller side, which is why this module is deliberately output-only.

Files

  • new: src/osd/modules/output/serial.cpp
  • modified: scripts/src/osd/modules.lua (one line, register file)
  • modified: src/osd/modules/lib/osdobj_common.{h,cpp} (option defines, option entries, REGISTER_MODULE line)
  • modified: docs/source/commandline/commandline-{all,index}.rst (document the provider and its two options)

New output module that forwards MAME output notifications as
"name = value\n" lines over a configured serial port.  Mirrors
the existing network output provider, intended for external
arcade I/O boards driving ticket dispensers, coin hoppers, and
lamps.

Options:
  -output serial                select the provider
  -output_serial_port <port>    e.g. COM4, /dev/ttyUSB0
  -output_serial_baud <rate>    default 9600
Adds documentation for the new 'serial' output provider:
- mention 'serial' in the -output choices listing with a brief
  description of its intended use (driving external arcade I/O
  hardware: ticket dispensers, coin hoppers, lamp boards)
- new -output_serial_port option
- new -output_serial_baud option

Also references both new options from commandline-index.rst.
@KoalaBear
Copy link
Copy Markdown
Author

Bumping with some context.

Since opening this PR I've shipped the hardware side: custom board, firmware, and Unity SDK, all working in a real cabinet. Wrote up the full build here.

The MAME gateway in this PR is what closes the loop. With it, any preserved ROM can drive real coin acceptors, hoppers, and ticket dispensers through MAME's existing IO layer. Without it, the rest of the stack is emulating in a vacuum.

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant