Skip to content

namco/namcos23: emulate the C139 serial link - two-cabinet link play for Time Crisis II - #15777

Open
pocketjazzy wants to merge 4 commits into
mamedev:masterfrom
pocketjazzy:c139-linkplay
Open

namco/namcos23: emulate the C139 serial link - two-cabinet link play for Time Crisis II#15777
pocketjazzy wants to merge 4 commits into
mamedev:masterfrom
pocketjazzy:c139-linkplay

Conversation

@pocketjazzy

Copy link
Copy Markdown

What this is

This implements the Namco C139 serial link (previously a skeleton device) and wires it into the System 23 driver, giving timecrs2 (US, TSS3 Ver. B) working two-cabinet link play between two MAME instances over TCP — the same co-op mode the arcade hardware offered, using MAME's existing -comm_localhost/-comm_localport/-comm_remotehost/-comm_remoteport options. Works on one machine (loopback), across a LAN, and has survived an internet session.

  • src/mame/namco/namco_c139.cpp/.h: full device implementation — register interface, shared-RAM frame exchange, TCP transport (ASIO), receive reassembly, transmit pacing modeled on measured hardware behavior (transmit-complete gating, keepalive, vblank-coupled cadence). Protocol details are documented in the source.
  • src/mame/namco/namcos23.cpp: device instantiation and mapping for the S23 machines, link-synchronized vblank handling, the cabinet "Link ID" machine configuration, and a proper label for the link DIP switch (previously "Unknown"): DIP:5 = "Link Play Enabled".
  • timecrs2 flags: MACHINE_NODEVICE_LAN removed (the link is emulated now). This PR also proposes dropping MACHINE_NOT_WORKING for this set — see "Flags" below; happy to split that into its own commit/PR if preferred.

Not included, deliberately: an optional in-game UI menu for the comm settings exists in our fork and can be offered as a follow-up PR if there is interest; launcher tooling stays downstream.

How to test

Two instances, each from its own working directory (cfg/nvram = cabinet identity). Set DIP:5 "Link Play Enabled" ON in both, Machine Configuration "Link ID" = Left/Red on one and Right/Blue on the other. Then (note: pass the FULL option tuples — partially-specified -comm_* options leave MAME's non-empty defaults live on the unspecified side, which cross-connects the instances; on Windows PowerShell 5.x use --% so the empty strings survive):

instance A (red):  mame timecrs2 -comm_localport 9876 -comm_remotehost ""
instance B (blue): mame timecrs2 -comm_remotehost 127.0.0.1 -comm_remoteport 9876 -comm_localhost "" -rompath <shared roms>

Healthy link: both attracts synchronize within seconds (the NAMCO splash appears to pause while clocks align), and SOLO / LINK PLAY appears on the mode select. For two PCs, replace 127.0.0.1 with the red machine's address and allow inbound TCP on it.

Validation

Developed and tested since early July 2026: full campaigns completed in linked play on loopback and two-PC LAN (Ethernet and WiFi), plus a WAN session over port forwarding. Transport sustains ~55 state-corrections/s per direction in gameplay. The implementation went through a staged cleanup with linked-play regression sessions at every stage; the shipped code is the lean result (the reverse-engineering instrumentation lives in the fork's history).

Flags

  • MACHINE_NODEVICE_LAN: removed — the LAN device is emulated.
  • MACHINE_NOT_WORKING (proposed removal, kept as a separate commit for easy dropping): the US set boots reliably, completes full campaigns solo and linked, and saves state. MACHINE_IMPERFECT_GRAPHICS is retained (occasional cutscene flicker, see below). Practical note: NOT_WORKING places a machine in the severe-warning class for which the frontend deliberately never persists warning acknowledgements (src/frontend/mame/ui/ui.cpp), so the set cannot be launched unattended (front-ends, dedicated cabinets) regardless of skip_warnings; with the flag dropped, the standard skip_warnings flow works as designed (verified).

Known limitations

  • Occasional cutscene flicker (reason for keeping IMPERFECT_GRAPHICS); not yet bisected against stock — may predate this work.
  • Minor remote-entity micro-stutter in some scenes on the non-host cabinet; cosmetic.
  • Only the US TSS3 Ver. B set is validated; clone sets keep their current flags.

Credits & transparency

Device skeleton and System 23 driver by Angelo Salese and the MAME team — this work stands on the S23 emulation. The TCP transport approach follows SailorSat (Ariane Fugmann)'s pioneering C139 link work for the System 21 era. Link-play implementation and reverse engineering: pocketjazzy.

In the interest of full transparency: the protocol reverse engineering and this implementation were developed with substantial assistance from Anthropic's Claude (Fable 5 model), working under my direction. Every change was human-reviewed, and all behavior was validated in real linked-play sessions (loopback, LAN, and WAN) rather than taken on faith. The commits carry Co-Authored-By trailers accordingly; happy to discuss or adjust attribution however the team prefers.

Fork with history, launcher tooling, and prebuilt binaries: https://github.com/pocketjazzy/MAME-TC2-Public (gameplay video in the README).

@pocketjazzy

Copy link
Copy Markdown
Author

Heads-up for anyone reading early: runtime-testing a second System 23 title (Motocross Go!) surfaced a boot regression on this branch versus stock 0.288 - the game runs on stock but not here. Investigating now; the fix will likely scope the functional link behavior to the validated title (or make the device inert-by-default when unconfigured) so other S23/S2/S21 users see skeleton-equivalent behavior. Please hold off on review until this is resolved - I'll note here when it is.

pocketjazzy and others added 4 commits July 27, 2026 23:35
Register interface, shared-RAM frame exchange and interrupt behavior
modeled from Time Crisis II (System 23) hardware traces. The
cabinet-to-cabinet serial line is carried over TCP using the existing
-comm_* options; transmit pacing (transmit-complete gating, keepalive,
vblank-coupled cadence) follows measured behavior. Builds on SailorSat
(Ariane Fugmann)'s C139 link groundwork.

The device is inert without a configured transport: register behavior
matches the previous stub, so the other systems instantiating it
(System 2 / 21) are unaffected.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… switch.

Instantiates the link device for the System 23 machines with
link-synchronized vblank handling and the cabinet Link ID machine
configuration. DIP:5 is labeled "Link Play Enabled" (previously
"Unknown").

All link machinery lives in a timecrs2-scoped state class - other
System 23 machines run unchanged driver code - and crszone no longer
inherits the Link ID configuration field.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The cabinet link is emulated now.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Boots reliably, completes full campaigns solo and linked, and passes
save-state round trips. MACHINE_IMPERFECT_GRAPHICS is retained
(occasional cutscene flicker). Kept as a separate commit so it can be
dropped independently if preferred.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@pocketjazzy

Copy link
Copy Markdown
Author

All clear - the hold is lifted. The Motocross Go! boot hang turned out to be an unrelated upstream regression: it reproduces on unmodified master at this branch's base commit and bisects to d7e131c (F2MC-16 external-interrupt change; motoxgo emulates an F2MC I/O-board MCU, timecrs2 has none - hence the game specificity). Full bisection in #15778.

The branch has been updated (force-pushed) with hardening that came out of the investigation regardless: all link machinery now lives in a timecrs2-scoped state class, the device is inert (stub-equivalent register behavior) unless a transport is configured - so the other C139-instantiating systems (System 2 / 21) and other System 23 titles run unchanged code - and crszone no longer inherits the Link ID configuration field. Runtime-verified: timecrs2 links (loopback) and plays solo; motoxgo on this branch behaves identically to unmodified master. Review welcome.

@pocketjazzy
pocketjazzy marked this pull request as ready for review July 28, 2026 03:41
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