Published on

Cold Storage for Warm Samplers, Part 2: Nix-Caging EMXP

Authors
  • avatar
    Name
    Johanness Nilsson
    Mastodon

Five hours

A customer came to collect a sampler I had been working on for him, but his demeanor was quite defeated. He recounted to me how he'd spent an entire evening, five precious hours gone, trying to get EMXP running on macOS so he could open his sampler banks. Wine version roulette. Prefixes. A tool that launches but eats the ESC key. No manuals or documentation with the exact winning incantation. Five hours, and at the end of it, nothing that worked twice.

In Part 1 I reverse-engineered the EMAX II floppy format while working on this guys sampler so a Greaseweazle could write physical disks the sampler actually boots. But moving images on and off disks is only half the battle when an image is just a brick of bytes until something can read the filesystem inside it: the banks, the presets, the samples an E-mu machine actually understands. Exactly one tool does that job across the whole E-mu lineage, and it is a crusty, brilliant, keyboard-driven Windows program from 2006. This post is about making it work in 2026.

What EMXP is

EMXP is by E-Synthesist and is not to be confused with any of the other E-mu utilities floating around. It is the closest thing the vintage E-mu sampler world has to a Rosetta Stone. It reads and writes the disk and image formats for:

E-mu. EMAX I/II. Emulator II/III/IIIX. ESI. SP-12/1200.

It handles ISO/IMG hard-disk images and IMG/HFE floppy images directly, converts between bank formats, and lets you surgically edit what's on a sampler's disk. It is also, unapologetically, a keyboard-only console application /w no mouse. Oh it's big fun.

Why it hurts

The reflex, when you see a decades-old executable, is "DOSBox." Wrong. emxpn.exe isn't DOS. It's a PE32, i386 Windows console program. It wants a Windows console, not a DOS one, and the difference is exactly where a lot of time get's wasted before people give up.

Another very quirky jerky fact about EMXP's lack luster interface is that navigating it's menues hing hevily on the ESC key. Run it hanging off a Linux (or macOS) terminal through Wine and the terminal steals its keys. Press ESC and it arrives as an escape sequence = mangled, late, interpreted by the shell before the program ever sees it. EMXP leans on ESC and the arrow keys for its entire UI, so this makes it feel b0rk3d and there is never any error message explaing WTF. Add Wine-version drift, a prefix that collides with whatever else you run under Wine, and per-machine setup that never survives a reinstall, and you've reconstructed the customer's lost evening.

The correct tool is for sure Wine, but Wine set up precisely: 32-bit prefix, the right WoW64, and the program launched so it gets its own console window. The whole trick, distilled, is one line:

wine start /wait /unix emxpn.exe

start /wait /unix makes Wine spin up its own graphical conhost`` window and run the binary inside _that_. Now ESC is a realVK_ESCAPE` key event, exactly like the Windows XP box EMXP was written for. The keys work. The screen refreshes. It behaves like the good litle program it is.

Knowing the trick and reproducing it reliably on every machine, offline, in 2029, are different problems. That second one is Nix's whole reason to exist.

Nix-caging it

emxp-nix is a flake that builds the cage and nothing else. The binary lives outside it; the flake supplies a pinned, wrapped, disposable Wine environment tuned for this one stubborn program:

  • Pinned Wine. wineWowPackages.stable, win32 prefix (the binary is 32-bit), locked to nixos-25.05. Upstream Wine is retiring classic WoW64 and nixpkgs follows — so the lockfile is the headstone. Nothing moves unless I move it.
  • The console trick, baked in. The launcher always uses wine start /wait /unix, so you get real key events, every time, without knowing why.
  • Zero profile collision. The wrapped Wine never touches the Wine you already have. State lives in a dedicated prefix at ~/.local/share/emxp/prefix; delete ~/.local/share/emxp and it's factory-fresh.
  • Binary stays yours. emxpn.exe is found at runtime (from $EMXP_EXE, the current dir, or a known spot) and copied once into the prefix. Never fetched, never stored in the Nix store, never redistributed.

The flake exposes more than the launcher:

OutputWhat it does
emxpthe program itself, in its own Wine console window
emxp-imageimage real media to/from a file with ddrescue (read-only on source; write makes you re-type the device path)
emxp-mapexperimental raw-device passthrough into the prefix (Linux-only, here be dragons)
emxp-suitethe default — all of the above plus a desktop launcher

Plus an overlay, a home-manager module, and a NixOS module, so it drops into a system config as cleanly as any other package.

One command

That's the payoff. The five-hour yak-shave collapses to:

nix run github:Synthesizer-repair/emxp-nix                # transient
nix profile install github:Synthesizer-repair/emxp-nix    # resident

Point it at your emxpn.exe, and EMXP comes up in its own console window with working keys, an isolated prefix, and a Wine that will still be byte-identical the next time you need it. Your host filesystem shows up inside EMXP as drive Z:, so the .img you captured in Part 1 is right there.

About "any modern OS"

I will be straight-up about the cross-platform claim, I'm not overselling it. This flake is Linux-only (x86_64-linux). It does not magically run EMXP natively on macOS. Wine on Apple Silicon is its own tar pit, and I'm not going to pretend a nix run on a Mac Just Works when it doesn't.

What Nix does deliver is this: the setup that eats five hours becomes one reproducible command on any Linux you can point at be that a spare box, a live NixOS installer, a VM on that same Mac, WSL2 on a Windows machine. Look John, I'll lay it out simple. You've got options.

The full loop

Part 1 and Part 2 are two ends of one pipeline. Greaseweazle handles the physical layer, getting raw flux off disks a normal drive can't even read, where EMXP handles the logical layers like the sampler's filesystem and banks. They meet at the image file:

  physical E-mu floppy
        │  gw read   (flux, format-agnostic)
   emax2_boot.img
        │  EMXP      (edit banks / convert patches, via drive Z:)
   emax2_boot.img
        │  gw write  (flux; tape the HD hole — the format is DD)
  a working E-mu floppy

It works

This isn't theory. With the two halves together I've imaged, edited, and re-created working disks across EMAX I/II and the Emulator III, converted patches, and watched them load on real hardware exactly as they should. The samplers are warm again, and the bits behind them are in cold storage. All reproducible, pinned, and no longer one dying floppy or one lost evening away from gone.

Get the tool from emxp.net. Get the cage from emxp-nix. And back up your disks!

Backups are not optional!