Skip to content

About

Remap keys on an IBM Model M through a Soarer's Converter - press a key, pick its target (Command/Option on macOS).

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

15 Commits

Folders and files

Repository files navigation

modelm-remap

Remap keys on an IBM Model M that is connected through a Soarer's Converter adapter — press a key, pick what it should become, and the tool rewrites the converter's EEPROM so the change survives unplugging and works on any computer.

Built for the common Mac case: the Model M has no Command key, so people remap RALT/RCTRL/CAPS_LOCK to Command. On macOS, Command is the USB "GUI" key, so the target token is LGUI (left ⌘) or RGUI (right ⌘).

modelm-remap  ·  Soarer's Converter
  adapter  Soarer's Keyboard Converter  (USB 16c0:047d)
  firmware v1.12   EEPROM 1024 bytes (990 bytes free)

STEP 1 — Press the key you want to remap.
  Press it on the IBM Model M now (Ctrl-C to abort)…
  ✔ Detected: RALT  (Option (right) ⌥, code 0x40)

STEP 2 — What should RALT do?
    Command / Mac modifiers
      1  LGUI   Command (left)   ⌘
      2  RGUI   Command (right)  ⌘
      ...

Install

The low-level tools are vendored under vendor/bin and built once:

./build.sh          # clones thentenaar/sctools and compiles scas/scdis/sctool

build.sh needs only Xcode command-line tools (clang) — no Homebrew, no autotools. sctool is compiled against the bundled hidapi macOS backend.

Put the CLI on your PATH (optional):

ln -sf "$PWD/modelm-remap" ~/.local/bin/modelm-remap

Usage

modelm-remap                          # interactive wizard (the main flow)
modelm-remap --from RALT --to LGUI --dry-run   # preview, write nothing
modelm-remap set RALT LGUI            # non-interactive, with confirmation
modelm-remap set RCTRL RGUI -y        # no confirmation prompt
modelm-remap screenshot               # press a key -> Cmd+Shift+4 (region screenshot)
modelm-remap copy                     # press a key -> Cmd+C
modelm-remap paste                    # press a key -> Cmd+V
modelm-remap select-all               # press a key -> Cmd+A
modelm-remap copy --from F10          # same, trigger key given up front
modelm-remap macro                    # press a key -> choose a shortcut to send
modelm-remap shortcut F10 CMD+SHIFT+4 # non-interactive shortcut macro
modelm-remap shortcuts                # list the named shortcuts
modelm-remap remove EXTRA_F2          # drop a key's remap and/or shortcut (backs up first)
modelm-remap remove F3 --only macro   # just the shortcut, keep a plain remap
modelm-remap listen                   # print keys as you press them
modelm-remap ls                       # list the keys already configured
modelm-remap ls --json                # ... machine-readable
modelm-remap show                     # raw config currently stored in the converter
modelm-remap keys CMD                 # list/search valid key names
modelm-remap info                     # firmware + EEPROM info
modelm-remap read backup.scb          # save the whole config
modelm-remap restore backup.scb       # write a saved config back

Options: --dry-run (show the result, don't write), --yes/-y (skip the confirm prompt), --timeout N (key-capture timeout), --bin-dir DIR.

How it works

A Soarer's Converter exposes three HID interfaces:

Interface Usage page Used for
keyboard 0x0001 normal typing
diagnostic 0xff31 / 0x0074 key events (+XX = press)
config 0xff99 / 0x2468 read/write the EEPROM config

modelm-remap uses the diagnostic interface to see the physical key you press (before remapping), then:

  1. reads the current config out of EEPROM,
  2. disassembles it to Soarer's text (scdis),
  3. merges your remap into the first remapblock,
  4. assembles it (scas), writes it back (sctool),
  5. reads it back and verifies the bytes match.

Existing remaps are preserved. Every write is preceded by a backup in ~/.config/modelm-remap/backups/ (both .scb and a readable .sc).

The resulting source is a normal Soarer's config you can also edit by hand:

ifkeyboard any
ifselect any
remapblock
layer 0
    EXTRA_F10 LGUI
    RALT LGUI
endblock

Shortcuts (macros)

A plain remap turns one key into one key. A shortcut is several keys at once — a chord like ⌘⇧4 — so it is stored as a Soarer's Converter macro that the converter synthesises from a single press:

modelm-remap screenshot               # the built-in one: Cmd+Shift+4
modelm-remap copy                     # Cmd+C
modelm-remap paste                    # Cmd+V
modelm-remap select-all               # Cmd+A
modelm-remap macro                    # pick any shortcut interactively
modelm-remap shortcut F10 CMD+SHIFT+4 # or name the chord yourself

modelm-remap shortcut accepts any trigger key and a chord built from modifiers (CMD, SHIFT, CTRL, OPT, and their R…/right-hand forms) plus one ordinary key. Run modelm-remap shortcuts to list the built-in names; each is just an alias for its chord, so shortcut F10 COPY and macro --to UNDO work too.

Editing Text navigation Screenshots System
CUT ⌘X HOME ⌘← SCREENSHOT ⌘⇧4 SPOTLIGHT ⌘␣
COPY ⌘C END ⌘→ SCREENSHOT_FULL ⌘⇧3 EMOJI ⌃⌘␣
PASTE ⌘V WORD_LEFT ⌥← SCREENSHOT_CLIPBOARD ⌃⌘⇧4 LOCK_SCREEN ⌃⌘Q
UNDO ⌘Z WORD_RIGHT ⌥→ SCREENSHOT_OPTIONS ⌘⇧5 FORCE_QUIT ⌥⌘⎋
REDO ⌘⇧Z DELETE_WORD ⌥⌫ MISSION_CONTROL ⌃↑
SELECT_ALL ⌘A DELETE_LINE_START ⌘⌫
FIND ⌘F
SAVE ⌘S

The resulting config is a normal macro you can also edit by hand:

macroblock
	macro EXTRA_F10
		PUSH_META ASSIGN_META LGUI LSHIFT
		PRESS 4
		POP_META
	endmacro
endblock

Adding a shortcut for a key that already has a remap replaces that remap, and adding one for a key that already has a macro replaces that macro.

To delete a rule instead of replacing it, use modelm-remap remove KEY (both the remap and the shortcut), or --only remap / --only macro for one of them. A block that ends up empty is removed from the config, and the previous config is backed up first.

My layout

configured shortcuts

tools/keymap-final.swift redraws this from the photo (swift tools/keymap-final.swift docs/model-m.jpg docs/keymap-final.png). F1/F2 send ⌃⌥⌘T / ⌃⌥⌘F, which two macOS Quick Actions (~/Library/Services/New Terminal.workflow, Open Finder.workflow, shortcuts set under System Settings → Keyboard → Shortcuts → Services) turn into "open a new Terminal" and "open Finder" — a converter can only send keys, not launch apps.

Menubar app (app/)

Model M Remap icon

Model M Remap is a native macOS app that shows every rule on a keyboard map and lets you add, edit and delete them with the mouse. It is a thin GUI over the CLI (ls --json, shortcut, set, remove, capture, restore), so the two never disagree. The CLI and the Soarer tools are bundled inside the app, so it runs from /Applications with nothing else installed (it uses the system python3 from the Xcode Command Line Tools).

Keyboard map

Edit a key All rules Profiles and backups
editor rules keyboard

Install. Download ModelMRemap-<version>.dmg from the Releases page, drag the app to Applications. It is not notarized yet: the first time, open System Settings → Privacy & Security → Open Anyway.

Build it yourself (Xcode Command Line Tools only, no Xcode project, no Homebrew):

./app/build-app.sh      # -> app/build/Model M Remap.app (icon, bundled CLI, ad-hoc signed)
./app/build-dmg.sh      # -> app/dist/ModelMRemap-<version>.dmg (arrow background, Applications link)
open "app/build/Model M Remap.app"        # keyboard icon in the menubar -> "Open Keyboard Map…"
"app/build/Model M Remap.app/Contents/MacOS/ModelMBar" --screenshots out/   # photograph the real window
  • Map — orange = shortcut, blue = remap, red = conflict, grey = free. Click a key to edit.
  • Rules — every rule, including keys the map does not draw. New rule can capture a physical key (“Press a key…”), so any key can be added without being in the profile.
  • Keyboard — pick the keyboard profile, see converter/EEPROM info, restore a backup.
  • Labels you type (e.g. “New Terminal”) live in ~/.config/modelm-remap/labels.json.
  • app/make-icon.swift draws the app icon and the DMG background.

Keyboard detection. A Soarer's Converter cannot report the keyboard's make or model. It auto-detects the protocol (XT, AT, PS/2, 122-key terminal, IBM RT) and, for terminal keyboards, reads a 16-bit ID from DIP switches (default BFBF, shared by many boards). So the map comes from a profile: app/Profiles/*.json (bundled) or ~/.config/modelm-remap/profiles/*.json (yours), each a list of {key, x, y, w?, label?} in key units using Soarer key names. Bundled (generated by app/gen-profiles.py, edit it and re-run to change or add layouts): IBM Model M 122-key (terminal), 101-key (US ANSI), 102-key (ISO), Space Saving (tenkeyless), IBM PC/AT 84-key, IBM PC/XT 83-key, and generic 104-key ANSI / 105-key ISO with Windows keys. Only keys whose position is known are drawn; the 84/83-key profiles skip Ctrl, Caps Lock, ` and . IBM RT keyboards are supported by the converter but have no profile yet.

macOS may ask for Input Monitoring for the app (the converter is read over HID); the app opens the right Settings pane from its banner if access is missing.

Mac key reference

macOS Soarer token Notes
⌘ Command (left) LGUI most common target
⌘ Command (right) RGUI
⌥ Option (left) LALT
⌥ Option (right) RALT
⌃ Control (left/right) LCTRL / RCTRL
⇧ Shift LSHIFT / RSHIFT

Aliases accepted by the tool: CMD, COMMAND, SUPER, WIN → LGUI; OPT/OPTION → LALT; CONTROL → LCTRL; RETURN → ENTER.

Troubleshooting

  • Config wiped after a failed write — fixed upstream of you: sctool write used to abort on the last chunk when the config length was 2 more than a multiple of 60 (patched, see vendor/patches/), and the tool now retries writes, restores the previous config if one still fails, and refuses to overwrite when it merely failed to read the config. A macro block holds ~255 bytes, so shortcuts spill into extra macro blocks automatically. Backups of every write are in ~/.config/modelm-remap/backups/; modelm-remap restore <file.scb>.

  • "no Soarer's Converter found" — check the adapter is plugged in and the keyboard cable is seated. system_profiler SPUSBDataType | grep -i soarer should list it; the USB id is 16c0:047d.

  • Nothing detected when pressing a key — run modelm-remap listen and watch the output. The tool watches for the +XX press event; if your key is unusual, pass --from NAME explicitly (see modelm-remap keys).

  • Writing fails — the converter may be busy; unplug/replug it and retry. Your previous config is always backed up first, and restore can put it back.

  • Keys also type into the terminal while capturing — that's normal (the standard keyboard interface still delivers to macOS); the input is drained afterwards.

Credits

scas / scdis / sctool come from thentenaar/sctools (BSD-2-Clause), a maintained replacement for Soarer's original converter tools. Soarer's Converter firmware itself is by Soarer.

Launching apps (New Terminal, Finder)

A converter can only send keys, so "open a new Terminal" is a two-part setup: a macOS Quick Action (a Service) runs open -n -a Terminal, and gets a global shortcut; the Model M key then sends that chord.

Key Chord Quick Action (~/Library/Services)
F1 CTRL+OPT+CMD+T New Terminal — open -n -a Terminal
F2 CTRL+OPT+CMD+F Open Finder — activates Finder, makes a window if none

The shortcut is stored in the pbs defaults (defaults write pbs NSServicesStatus -dict-add "'(null) - <Service name> - runWorkflowAsService'" "{ key_equivalent = \"@~^t\"; … }", then /System/Library/CoreServices/pbs -flush; pbs -update). Modifier letters: @ ⌘, ~ ⌥, ^ ⌃, $ ⇧.

License

MIT © Eko S. Wibowo. The Soarer's Converter tools (scas, scdis, sctool) are built from thentenaar/sctools (BSD-2-Clause) with the small fixes in vendor/patches/; the converter firmware is by Soarer.

About

Remap keys on an IBM Model M through a Soarer's Converter - press a key, pick its target (Command/Option on macOS).

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages