Add ClusterM Famicom Dumper/Writer NES driver over Web Serial#29
Merged
Conversation
A new Web Serial dumper at USB 1209:baba — an STM32F103 + CPLD Famicom-bus simulator whose M2 clock free-runs from power-on, so the full shared NES mapper catalog is available, including the CPLD multicart boards (mappers 268/470) that idle-M2 dumpers must pre-flight-reject. The frame format, CRC-8, command set, and init handshake are ported from the GPL-3.0 famicom-dumper-client (attributed in THIRD-PARTY-LICENSES); the handshake and version report are validated against real hardware (firmware 3.4.0 / protocol 5). The firmware holds a single command slot, so frames are issued one at a time rather than pipelined. SerialTransport now takes its Web Serial chooser filters from the connection entry rather than hardcoding them (the GBxCart's CH340 filter moves into its own command module). Mapper 413 (BATMAP) is refused on this device: its 8 MiB serial sample flash can't be paced through the stock firmware's CDC staging buffer, so the cartridge can't be fully dumped here — the mapper is greyed out and rejected up front rather than producing a partial file. A field note documents the @hualazimo7 compatible board this driver was developed against (an open-hardware build, firmware byte-verified against ClusterM's reference); the README credits it as well.
There was a problem hiding this comment.
Pull request overview
This PR adds first-class support for the ClusterM Famicom Dumper/Writer (USB 1209:baba) as a new NES/Famicom Web Serial driver, and refactors Web Serial port-chooser filtering so each device supplies its own chooser filters rather than SerialTransport hardcoding them.
Changes:
- Added a new ClusterM driver stack (
ClusterMProtocol+ClusterMNesBus+ClusterMDriver) with comprehensive Vitest coverage and a scripted fake device for wire-level tests. - Refactored
SerialTransportto accept per-device Web Serial chooser filters; moved the GBxCart RW CH340 filter into its command module and added a new ClusterM filter/baud config. - Registered the new device in the connection registry/device catalog and updated attribution/docs + Linux udev rules.
Reviewed changes
Copilot reviewed 14 out of 14 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
THIRD-PARTY-LICENSES |
Adds GPL attribution for the ClusterM serial protocol port. |
src/lib/transport/serial-transport.ts |
Makes Web Serial chooser filters configurable per transport instance. |
src/lib/drivers/gbxcart/gbxcart-commands.ts |
Defines GBxCart RW Web Serial chooser filters (CH340). |
src/lib/drivers/clusterm/clusterm-test-utils.ts |
Adds a frame-parsing fake ClusterM device for protocol/driver tests. |
src/lib/drivers/clusterm/clusterm-protocol.ts |
Implements ClusterM request/response framing, handshake, and ops. |
src/lib/drivers/clusterm/clusterm-protocol.test.ts |
Adds wire-protocol tests (CRC, framing, resync, error cases). |
src/lib/drivers/clusterm/clusterm-driver.ts |
Adds the ClusterM NES/Famicom driver with mapper 413 refusal logic. |
src/lib/drivers/clusterm/clusterm-driver.test.ts |
Adds driver/bus behavior tests (dump ordering, abort/reset invariants). |
src/lib/drivers/clusterm/clusterm-commands.ts |
Defines ClusterM command IDs, CRC-8, framing, filters, baud rate. |
src/lib/drivers/clusterm/clusterm-bus.ts |
Implements an NES bus adapter with chunking + abort granularity. |
src/lib/core/devices.ts |
Registers the ClusterM device metadata (VID/PID, systems, description). |
src/lib/core/connection-registry.ts |
Adds CLUSTERM connection entry; wires serial filters + baud. |
README.md |
Documents the new supported device and compatible third-party build note. |
linux/99-nabu.rules |
Adds udev rule for ClusterM VID/PID to enable Web Serial access on Linux. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Per PR review: buildFrame() and the protocol's addrLen() encode lengths (and addresses) into LE16 wire fields without checking the value fits. An out-of-range value would wrap silently while the frame still carries every byte, desyncing the device's byte stream — host and device then disagree about the request. Throw a descriptive error up front instead, matching the response-side length check in expectBlock(). Current callers stay well within 16 bits (NES addresses are 16-bit, reads chunk to 8 KiB), so these are fail-fast guards at the wire boundary rather than a fix for an observed bug.
Per PR review: rather than a runtime guard for an unreachable case (writeCpu/writePpu carry byte-sized mapper-register payloads, never within kilobytes of the 0xFFFF - 4 per-frame data ceiling), note the bound in the method docs. buildFrame still throws loudly if it is ever somehow exceeded.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
A new Web Serial dumper (USB
1209:baba) — an STM32F103 + CPLD Famicom-bus simulator whose M2 clock free-runs from power-on, so the full shared NES mapper catalog is available, including the CPLD multicart boards (mappers 268/470) that idle-M2 dumpers have to pre-flight-reject.famicom-dumper-client(attributed inTHIRD-PARTY-LICENSES); handshake + version report validated against real hardware (firmware 3.4.0 / protocol 5). The firmware holds a single command slot, so frames go out one at a time, not pipelined.SerialTransportnow takes its Web Serial chooser filters from the connection entry instead of hardcoding them (the GBxCart's CH340 filter moves into its own command module).