Remote Mouse & Keyboard Gateway for AmigaOS 3.x
Bifrost enables seamless mouse and keyboard forwarding from a PC to a AmigaOs 3.x over TCP/IP. Control your Amiga remotely with smooth, low-latency input using a piecewise-linear acceleration curve and sub-pixel precision. Includes toggle switching to alternate between PC and Amiga input control.
✅ Remote Input Forwarding - Real-time mouse and keyboard events from PC to Amiga
✅ Smooth Mouse Movement - Piecewise-linear acceleration curve (sub-pixel accumulation)
✅ Low-Latency Streaming - TCP_NODELAY for immediate packet delivery
✅ Keyboard Support - Full keyboard forwarding with toggle capability
✅ Input Toggle - Scroll Lock or screen edge trigger to switch PC ↔ Amiga control
✅ Edge Detection - Screen edge/corner switching for focus control
✅ Auto-Discovery - UDP broadcast — no IP configuration needed
✅ Configurable - Mouse tuning via Amiga CLI args, everything else via bifrost_config.json — no code edits
✅ Systray Status Icon - Green icon when Amiga connected, grey when disconnected
✅ Python Server - Cross-platform PC side daemon (Windows/Linux/macOS)
cd server
./setup_venv.sh # Windows: pwsh .\setup_venv.ps1
python main.py # Windows: .venv\Scripts\python main.pyBifrostDone! Server auto-discovers and connects. Toggle focus with Scroll Lock.
- Python 3.8+
- Network connectivity to Amiga (Ethernet or USB FTDI)
- Any Amiga with a TCP/IP stack (AmiTCP, Roadshow, or ApolloOS networking) — no specific accelerator or chipset required
- AmigaOS 3.x
- Network connectivity to PC
1. Set up the Python environment (creates .venv, installs dependencies):
cd server
./setup_venv.sh # Windows: pwsh .\setup_venv.ps12. Start server:
python main.py # Default port 7890 (Windows: .venv\Scripts\python main.py)
python main.py --port 9999 # Custom port2b. (optional) Auto-start at login:
-
Windows:
cd server pwsh .\install_startup.ps1
Adds a shortcut to your Startup folder so Bifrost launches automatically at every login, with no console window (status is shown in the systray). Logs go to
server\bifrost.log. Rununinstall_startup.ps1to remove it.(macOS/Linux: the zip doesn't preserve the executable bit - run
chmod +x server/start_bifrost.shonce after extracting.) -
macOS:
start_bifrost.shis a plain launch script - it doesn't register itself anywhere. Open System Settings → General → Login Items, click +, and addserver/start_bifrost.sh. -
Linux: Same idea - most desktop environments have their own "Startup Applications" setting (e.g. GNOME: Settings → Apps → Startup Applications; KDE: System Settings → Autostart). Point it at
server/start_bifrost.sh.
3. Copy Bifrost to Amiga:
Copy Bifrost to SYS:4. Launch from CLI:
Bifrost [port] [edge]Auto-discovery: Server is found via UDP broadcast on port 7891 (TCP 7890 + 1). No IP needed.
Bifrost # Auto-discover, default port (7890)
Bifrost 9999 # Custom TCP port (PC must also use 9999)
Bifrost 9999 TOPRIGHT # + Edge trigger (top-right corner)
Bifrost NOCAPSLOCK # Disable PC Capslock -> Amiga sync (default: enabled)
Bifrost HZ=75 SPEED=1.5 # Mouse tuning args (see below), any order
Bifrost STATUS # Query the running daemon's connection status
Bifrost STOP # Disconnect and quit the running daemon
Bifrost ? # Print full usage/helpEdge Options: TOP, BOTTOM, LEFT, RIGHT, TOPLEFT, TOPRIGHT, BOTTOMLEFT, BOTTOMRIGHT
Mouse Tuning (KEY=VALUE): HZ=n poll rate in Hz (default 50) · HZDRAG=n poll rate while dragging (default 15, clamped ≤ HZ) · SPEED=n speed multiplier, 0.2-3.0 (default 1.0) · DELTAMAX=n startup glitch filter in pixels (default 80) · CURVELINEAR=n acceleration curve linear threshold (default 2.0) · CURVERATIO=n acceleration curve compression ratio (default 0.5). Running Bifrost again while an instance is already running live-pushes any edge/tuning args to it instead of launching a duplicate.
STATUS / STOP: Talk to the already-running daemon over a public message port (Bifrost_Port) instead of launching a new one - useful for scripts. Running Bifrost again while an instance is already active applies any new edge/tuning args live (use STOP first to actually stop it, or STATUS to check).
UDP port - 1. This will be fixed in Phase 2 (auto-negotiation).
Mouse tuning is Amiga-side (see HZ=/SPEED=/etc. above) - it's sent to the PC automatically over the wire, no PC-side setup needed.
PC-side config is everything else: edit server/bifrost_config.json:
{
"network": {
"port": 7890
},
"keys": {
"toggle": "scroll_lock",
"emergency": "pause",
"kill_modifier": "ctrl"
},
"debug": {
"enabled": true
}
}For detailed parameter explanations, profiles, and troubleshooting: See docs/CONFIGURATION.md
- Scroll Lock key - Toggle between PC and Amiga input
- Screen corner - Top-right click also triggers toggle (if enabled via edge config)
When the server runs, a systray icon shows the Amiga connection state:
- 🟢 Green circle - Amiga is connected and ready to receive input
- ⚫ Grey circle - Amiga is disconnected (waiting for Amiga to connect)
The systray menu displays:
- Current connection status: "Amiga Connected" or "Amiga Disconnected"
- Quit button to exit the server gracefully
Updates every 0.5 seconds to reflect connection state changes in real-time.
Note: Systray support requires pystray (installed via pip install -r requirements.txt). If not installed, the server runs normally without systray.
Ctrl+Alt+Del cannot be captured. While in Amiga focus mode, pressing Ctrl+Alt+Del on the PC keyboard still brings up Windows' secure screen (lock/task manager/sign out). This is Windows' Secure Attention Sequence (SAS): it is intercepted by the OS below any user-mode hook (including the WH_KEYBOARD_LL hook the PC server uses) specifically so that no application - malicious or not - can intercept credential entry. There is no supported way to suppress it from a user-mode process; only a signed kernel-mode keyboard filter driver could, which is out of scope for Bifrost's current architecture.
- Python daemon captures mouse/keyboard
- Applies acceleration curve
- Sends 8-byte packets via TCP/IP (50 Hz default)
- Receives packets over TCP
- Injects into
input.devicestream - Supports edge-triggered focus switching
-
Discovery: UDP broadcast (port 7891 default)
- PC broadcasts
Bifrost_DISCOVER - Amiga replies
Bifrost_HEREand connects via TCP - No pre-configured IP needed
- PC broadcasts
-
Data: TCP/IP with TCP_NODELAY enabled
- Fixed 8-byte packets with big-endian encoding
- Packet types:
PKT_MOUSE_MOVE,PKT_MOUSE_BTN,PKT_KEY,PKT_WHEEL,PKT_HELLO,PKT_EDGE_TRIGGER,PKT_FOCUS_ENTER,PKT_CLIENT_STATE,PKT_HEARTBEAT - Default send rate: 50 Hz (~20ms per event)
|d| ≤ CURVE_LINEAR → output = |d| (1:1 precision)
|d| > CURVE_LINEAR → output = CL + (|d|-CL) × CURVE_RATIO
Example (default: linear=2.0, ratio=0.5):
- 1px → 1px, 2px → 2px, 3px → 2.5px, 4px → 3px, 10px → 6px
Only relevant for apps using opaque drag (MCP — Move/Copy/Paste window).
If an app uses opaque drag (Workbench, file managers), each mouse event forces a full-screen redraw. Lower send rate during drag prevents overwhelming the Amiga.
If an app uses transparent drag or no drag visual, set hz_drag = hz — no lag, no benefit to lowering.
All tests on:
- Apollo Computer Vampire V4 (A6000, 68080 SAGA)
- A1200 Pistorm
- UAE A1200
- Configuration: 50 Hz polling, CURVE_LINEAR=2.0, CURVE_RATIO=0.5
Validated:
- ✅ Smooth mouse movement with sub-pixel accumulation
- ✅ Keyboard input forwarding
- ✅ Edge-triggered focus switching
- ✅ Low-latency auto-discovery
- ✅ Acceleration curve responsiveness
Note: Other Vampire versions or non-accelerated Amigas may need parameter adjustments. See docs/CONFIGURATION.md for hardware-specific profiles.
# Build for 68020+ (SAGA-compatible)
make CPU=68020 build
# Release build
make MODE=release build
# Clean
make clean
# Upload to Vampire V4
make upload- ✅ Mouse-tuning config (
HZ/HZDRAG/SPEED/DELTAMAX/CURVELINEAR/CURVERATIO) moved from PC config file to Amiga-side CLI args - ✅ Live config push to an already-running daemon (edge + mouse-tuning) via a second
Bifrostinvocation - ✅ Fixed several CLI live-update merge bugs
- ✅
PKT_HEARTBEATreplacesPKT_PING- liveness independent of packet backlog, carries Amiga cursor position - ✅ PC Capslock state sync to Amiga,
NOCAPSLOCKCLI toggle - ✅ Fixed Left/Right Amiga key qualifiers to track per-side state instead of always setting both
- ✅ Improved logging and connection status reporting
-
✅ Refactor source codes
-
✅ split the commodity part to another project
-
Many other things to release the
first fonctionnal Beta release
- ✅ Introduce commodity
- ✅ Piecewise-linear acceleration curve
- ✅ Sub-pixel float accumulation
- ✅ TCP_NODELAY for low-latency delivery
- ✅ Edge detection and boundary handling
- ✅ UDP auto-discovery
- ✅ JSON configuration file
- ✅ Smooth mouse movement
- ✅ Keyboard forwarding
- ✅ Toggle switching
- ✅ Initial client-server architecture
- ✅ TCP/IP mouse forwarding
- ✅ Basic acceleration curve
| Document | Purpose |
|---|---|
| ROADMAP.md | Development roadmap (Phases 2-6) |
| docs/CONFIGURATION.md | Full configuration guide — parameter details, profiles, troubleshooting |
| MILESTONES.txt | Release history and validation points |
Copyright (c) 2025 Vincent Buzzano (ReddoC)
See LICENSE file for details.
Status: Ready for production.
Next: Per-app profiles, Amiga→PC reverse control, GUI preferences editor — see ROADMAP.md
