Remote Client console app¶
dotnet-6502-remote is a thin CLI wrapper that hides the JSON framing, handles connection setup, and formats output for human or pipeline consumption.
Pre-built binaries are available for Windows, Linux, and macOS. The remote client connects to a running Avalonia Desktop or Headless emulator via its TCP remote control endpoint. See TCP protocol for the protocol, available commands, and full reference.
Global options¶
| Option | Default | Description |
|---|---|---|
--host <host> |
127.0.0.1 |
Server hostname or IP |
--port <port> |
6510 |
TCP port |
--help |
Print usage and exit | |
--version |
Print the client version and exit | |
--check-update |
Check for a newer release of dotnet-6502-remote and print the result (no automatic check otherwise). Package-manager installs only. |
|
--update |
Check and, if a newer release is available on a package-manager install, run the brew/scoop upgrade, then exit. |
|
--check-server-version |
Connect to the server, read its app version, and warn if it differs from this client's version (see Server version preflight). |
Exit codes: 0 = success, 1 = server returned an error or connection failed, 2 = bad arguments, 3 = server/client version mismatch (from --check-server-version).
The Remote Client never checks for updates automatically (its stdout stays script-friendly); the flags above are the only update surface. See Staying up to date.
Server version preflight¶
--check-server-version is a recommended preflight before a scripted control session: it makes sure the dotnet-6502-remote client and the emulator it is about to drive are the same release. It sends one cheap, read-only server.info command (host app name + release-stamped version), compares that version with the client's own, and reports the result — it does not run any other command.
- Match → prints an
OK: …line to stdout and exits0. - Mismatch → prints a warning plus the
brew/scoopcommands to update both sides to stderr, and exits3. (Warnings go to stderr so normal command stdout stays script-friendly.) - Can't verify (either side is an unversioned development build, or the server is too old to answer
server.info) → prints a note to stderr; a development build exits0, a too-old server is treated as a mismatch (3).
# Preflight: bail out of a script if the endpoint version doesn't match this client
dotnet-6502-remote --port 6510 --check-server-version || exit 1
This is a version-mismatch warning only — it is not TCP protocol negotiation or full compatibility handling. Because the Homebrew tap and Scoop bucket normally track only the latest release, the fix for a mismatch is to bring both the client and the server app forward to the latest package-manager version rather than trying to install an older matching pair.
You can also query the server directly:
# Print the server host app name and its release-stamped version
dotnet-6502-remote --port 6510 server.info
Usage examples¶
# Check emulator state
dotnet-6502-remote emu.state
# Start the emulator (also resumes from paused)
dotnet-6502-remote --port 6510 emu.start
# List available systems and variants
dotnet-6502-remote emu.systems
dotnet-6502-remote emu.variants
# Show storage paths used by the running emulator host
dotnet-6502-remote emu.storagepaths
# Switch system (requires emulator to be stopped first)
dotnet-6502-remote emu.stop
dotnet-6502-remote emu.selectsystem --name C64
dotnet-6502-remote emu.selectvariant --name C64NTSC
dotnet-6502-remote emu.start
# Read 16 bytes from $C000
dotnet-6502-remote mem.read --addr C000 --len 16
# Write bytes to $C000
dotnet-6502-remote mem.write --addr C000 --data 169,42,133,254
# Get CPU registers
dotnet-6502-remote cpu.get
# Set CPU registers (set A and force InterruptDisable flag)
dotnet-6502-remote cpu.set --a 42 --flags "----I---"
# Jump to a specific address
dotnet-6502-remote cpu.set --pc C000
# Load a PRG file into C64 memory
dotnet-6502-remote c64.loadprg --file /path/to/program.prg
# Set joystick port 1: up + fire
dotnet-6502-remote joystick.set --port 1 --up --fire
# Hold joystick port 1 up + fire until release
dotnet-6502-remote joystick.press --port 1 --up --fire
# Release held joystick up on port 1
dotnet-6502-remote joystick.release --port 1 --up
# Release all held joystick actions on port 1
dotnet-6502-remote joystick.releaseall --port 1
# Clear joystick port 1 up + fire explicitly for the next frame only
dotnet-6502-remote joystick.set --port 1 --no-up --fire false
# Press and release the Return key
dotnet-6502-remote keyboard.press --key return
dotnet-6502-remote keyboard.release --key return
# Paste text into the C64 keyboard buffer (C64 only; use lowercase — see c64.type section in TCP protocol)
dotnet-6502-remote c64.type --text "load\"*\",8,1"
# Type text into the Apple II via the keyboard latch (Apple II only; typed as uppercase)
dotnet-6502-remote apple2.type --text "PRINT 123"
# Get the current Applesoft BASIC program as text (Apple II only)
dotnet-6502-remote apple2.getbasicsource
# Load a tokenized Applesoft program at $0801 with pointer init (Apple II only)
dotnet-6502-remote apple2.loadbasic --file /path/to/program.bas
# Put a disk image in drive 1 without rebooting, then boot from it (Apple II only)
dotnet-6502-remote apple2.insertdisk --file /path/to/game.dsk
dotnet-6502-remote apple2.bootdisk
# Check the drive: a climbing read counter means software is reading the disk (Apple II only)
dotnet-6502-remote apple2.diskstatus
# Eject the disk (Apple II only)
dotnet-6502-remote apple2.ejectdisk
# Type text and read the current BASIC program (Oric only; use uppercase BASIC keywords)
dotnet-6502-remote oric.type --text $'10 PRINT "HELLO"\n'
dotnet-6502-remote oric.getbasicsource
# Fast direct-load of the first file in an Oric TAP image, honoring its autorun flag
dotnet-6502-remote oric.loadtap --file /path/to/program.tap
# Or insert a multi-file tape and load it through the Atmos ROM
dotnet-6502-remote oric.inserttape --file /path/to/game.tap
dotnet-6502-remote oric.tapestatus
dotnet-6502-remote oric.type --text $'CLOAD""\n'
dotnet-6502-remote oric.rewindtape
dotnet-6502-remote oric.ejecttape
# Save / restore a full emulator-state snapshot (relative paths use the emulator host's snapshot directory)
dotnet-6502-remote emu.savesnapshot --path state.d6502snap
dotnet-6502-remote emu.loadsnapshot --path state.d6502snap
# Step the (paused) emulator a fixed number of frames, then screenshot the result
dotnet-6502-remote emu.runframes --count 1
# Take a screenshot and save to a file
dotnet-6502-remote screenshot --output /tmp/screen.png
# Display a message in the Log tab
dotnet-6502-remote ui.message --text "Checkpoint reached" --level info
# Quit the headless emulator (requires --allow-remote-quit on server)
dotnet-6502-remote emu.quit
For end-to-end automation patterns, see Examples.
Run from source (development)¶
# Run directly from source
dotnet run --project src/apps/Highbyte.DotNet6502.App.RemoteClient -- --help
# Or build and add to PATH
dotnet build src/apps/Highbyte.DotNet6502.App.RemoteClient -c Release
# binary: src/apps/Highbyte.DotNet6502.App.RemoteClient/bin/Release/net10.0/Highbyte.DotNet6502.App.RemoteClient
Installation¶
Pre-built binaries (dotnet-6502-remote) are available via Homebrew (macOS/Linux), Scoop (Windows), or manual download. See Desktop apps installation for the install / update / remove commands and manual-download details.
After installing, start an emulator with remote control enabled (see Remote control overview), then run the client from any terminal:
Run dotnet-6502-remote --help for the full command list.