overdub

fm1-emulator

simonjohansson/fm1-emulator · ★ 22

Rust emulator that runs FM-1 firmware images (.fwsc, .elf, .bin) on your desktop with the screen, buttons and USB serial console, so you can test without flashing.

1 project builds on this: fm1-emulator

README from GitHub, GPL-2.0

FM-1 Emulator

Run FM-1 application firmware on macOS or Linux, with an FM-1 panel, mouse and keyboard controls, audio, and a USB console. Built on QEMU with a pi32v2 CPU and FM-1 board model.

Download

Prebuilt archives for macOS on Apple Silicon and Linux on x86-64 are attached to each release:

mkdir fm1-emulator && cd fm1-emulator
curl -fL https://github.com/simonjohansson/fm1-emulator/releases/latest/download/fm1-emulator-macos-arm64.tar.gz | tar -xz
# or fm1-emulator-linux-amd64.tar.gz

Each archive holds one self-contained emulator plus license notices. It links only libraries the OS ships: system frameworks on macOS, glibc on Linux, where SDL opens the desktop's X11 or Wayland and audio libraries at run time. The macOS binary is ad-hoc signed, not notarized: an archive downloaded with a browser needs xattr -dr com.apple.quarantine . first.

Run

./emulator path/to/firmware.bin

Close the window or press Ctrl-C in the terminal to quit. The executable needs no Python or third-party library installations to run. Firmware is not included. Pass a raw application .bin or an uncompressed .fwsc / .ufw update package; ELF files are unsupported.

Click and hold the piano keys or function buttons. Drag a knob up/down or scroll over it to turn it. MASTER controls the board’s volume input.

KeyAction
Z / CPlay notes
X / VOctave down / up
P / OENV / LFO
HReturn HOME

The firmware console appears in your terminal and accepts typed commands. For Felucca, try help or status. Use --no-audio for silence or --headless for a console-only session. See ./emulator --help for options.

Build

Install mise; on macOS also the Xcode Command Line Tools, for the SDK. Then:

mise install
mise run build

mise supplies everything else: clang, pkg-config, and static SDL2 from conda-forge. No Homebrew or apt packages are needed. The first build downloads pinned QEMU and GLib sources and Python build tools, and builds GLib statically. It produces ./emulator, which links only OS libraries, and a distribution archive in .cache/. Python is needed only to build and test.

Status

Firmware confirmed to work. CI boots each one on every push, drives the panel with random buttons and encoders for 60 guest seconds (mise run stress), then steps through 128 presets and every function button (mise run panel_smoke).

FirmwareVersionSourceHeadless, idleHeadless, input every 10 msWindowed with audio
Stock FM-1FM-1_015 (string in the image)FM-1.fwsc2.7x1.1xreal time, 53% of a core
Felucca1.5felucca-1.5.fwsc1.5x1.0xreal time, 68% of a core

Speeds are guest time divided by host time, measured on an Apple M3 Pro (macOS 27, both firmware cores emulated). Headless is unpaced, so it shows the most the emulator can do: "idle" is 50 guest seconds sitting at HOME, and "input every 10 ms" is the stress run, about 83 guest seconds of constant button presses and knob turns. Windowed sessions are paced to real time, so they cannot run faster than 1x; the last column is the host CPU the session used over 40 seconds, and no "guest is late" warnings appeared. A slower Mac has less headroom, and below 1x a windowed session falls behind.

The panel draws the button and key LEDs as the firmware drives them, including the dim glow, REC's red and PLAY's green. The stock FM-1 Wi-Fi radio is modeled as inert hardware. Other firmware compatibility is limited. Windows is deferred.

Browser (experimental)

A headless build runs in the browser: choose a firmware file, press Boot, and the page shows the display and the console, with its speed against real time. It is an interpreter: on an Apple M3 Pro it runs at roughly 0.05x real time, so Felucca reaches its home screen after about 30 seconds. There are no buttons, LEDs or sound yet. It runs in current Chrome, Firefox and Safari; the firmware never leaves your computer.

mise run build_wasm    # emsdk and clang come from mise
mise run serve_web     # http://localhost:8080

See development for tests and architecture for the model. Licensing and source provenance are described in LICENSES.md.