VICE TCP Monitor - cressie176/Load64 GitHub Wiki
Reference guide for using VICE's binary monitor protocol in LoadC64.
Launch VICE with both binary and text monitors:
x64sc -binarymonitor -binarymonitoraddress ip4://127.0.0.1:6502 \
-remotemonitor -remotemonitoraddress ip4://127.0.0.1:6510- Binary monitor (port 6502): Structured protocol for most operations
- Text monitor (port 6510): Text-based commands for disk attach/detach
Connection timing: Use a retry loop rather than fixed delays:
- Attempt TCP connection
- Send Ping (0x81) command
- Wait for successful response
- Retry after brief delay if connection fails
| Offset | Size | Field | Description |
|---|---|---|---|
| 0 | 1 | STX | Start of command (0x02) |
| 1 | 1 | API Version | Currently 0x02 |
| 2-5 | 4 | Length | Command body length (little endian) |
| 6-9 | 4 | Request ID | For matching responses (little endian) |
| 10 | 1 | Command Type | Numeric command identifier |
| 11+ | var | Body | Command-specific data |
Note: Length does NOT include the header (bytes 0-10), only the body.
| Offset | Size | Field | Description |
|---|---|---|---|
| 0 | 1 | STX | Start of response (0x02) |
| 1 | 1 | API Version | Currently 0x02 |
| 2-5 | 4 | Length | Response body length (little endian) |
| 6 | 1 | Response Type | Usually matches command ID |
| 7 | 1 | Error Code | 0x00 = success |
| 8-11 | 4 | Request ID | Matches request, or 0xffffffff for events |
| 12+ | var | Body | Response-specific data |
| Code | Meaning |
|---|---|
| 0x00 | Success |
| 0x01 | Object doesn't exist |
| 0x02 | Invalid memspace |
| 0x80 | Incorrect command length |
| 0x81 | Invalid parameter value |
| 0x82 | API version not understood |
| 0x83 | Command type not understood |
| 0x8f | General failure |
All multi-byte values use little endian byte order.
Verify VICE is responsive.
Command: 02 02 00 00 00 00 [request_id] 81
Response: Empty body, error code 0x00 indicates success.
Minimum VICE version: 3.5
Get version information.
Command: 02 02 00 00 00 00 [request_id] 85
Response body:
ML | MV[0..ML-1] | SL | SV[0..SL-1]
| Field | Description |
|---|---|
| ML | Main version length (typically 4) |
| MV | Main version bytes (e.g., 0x03 0x05 0x00 0x00 = 3.5.0.0) |
| SL | SVN revision length |
| SV | SVN revision (little endian, 0 if not SVN build) |
Minimum VICE version: 3.6
Command: Quit (0xbb)
Binary format: 02 02 00 00 00 00 [request_id] bb
Response: Empty body.
Effect: VICE terminates and TCP connection closes.
Minimum VICE version: 3.5
Monitor TCP connection status:
- Read returning 0 bytes = connection closed
- Write failures = connection lost
- Distinguish
WouldBlock(no data) from actual errors
Command: Registers Get (0x31)
Binary format: 02 02 01 00 00 00 [request_id] 31 [memspace]
- Memspace: 0x00 (main CPU)
Response body:
RC RC [ IS { RI | RV RV } ... ]
| Field | Description |
|---|---|
| RC | Register count (2 bytes) |
| IS | Item size (1 byte, always 3) |
| RI | Register ID (1 byte) |
| RV | Register value (2 bytes) |
Effect: Any binary monitor command causes the emulator to stop and enter monitor mode. Registers Get is a convenient no-side-effects command for this purpose. The emulator remains stopped until you send Exit (0xaa).
Important:
- When paused, stop autosave timers to prevent unwanted snapshots
- While paused, you will continue to receive asynchronous event responses (Request ID 0xffffffff)
- The client must keep reading and demultiplexing responses even when paused
Minimum VICE version: 3.5
Command: Exit (0xaa)
Binary format: 02 02 00 00 00 00 [request_id] aa
Response: Empty body.
Effect: Exits monitor mode, continues emulation.
Important: Restart autosave timers when resuming.
Minimum VICE version: 3.5
Goal: Swap which host controller feeds each C64 control port.
Resources to swap:
-
JoyDevice1(integer) - Host controller for joystick emulation 1 -
JoyDevice2(integer) - Host controller for joystick emulation 2
Important: Keep JoyPort1Device and JoyPort2Device set to joystick (value 1). You are not changing device types, you are swapping which host controller feeds each port.
Method: Use text monitor (port 6510) for simplicity, especially if already using it for disk operations.
A. Pause emulation (via binary monitor):
- Send Registers Get (0x31) via binary monitor
- Read events until you receive STOPPED event (Request ID 0xffffffff)
B. Read current mappings (via text monitor):
resourceget "JoyDevice1"\n
resourceget "JoyDevice2"\n
Parse the returned integer values (typically 0, 1, or sentinel values for "none").
C. Write swapped values (via text monitor):
resourceset "JoyDevice1" "<old JoyDevice2 value>"\n
resourceset "JoyDevice2" "<old JoyDevice1 value>"\n
D. Optional verification (via text monitor):
resourceget "JoyDevice1"\n
resourceget "JoyDevice2"\n
E. Resume emulation (via binary monitor):
02 02 00 00 00 00 [request_id] aa
Get Resource (0x51):
Command body:
NL | RN[0..NL-1]
Example - Get JoyDevice1:
02 02 0b 00 00 00 [request_id] 51 0a 4a 6f 79 44 65 76 69 63 65 31
- NL: 0x0a (10 bytes)
- RN: "JoyDevice1"
Response body:
RT | VL | RV[0..VL-1]
| Field | Description |
|---|---|
| RT | Resource type (0x00=String, 0x01=Integer) |
| VL | Value length |
| RV | Resource value |
Set Resource (0x52):
Command body:
RT | NL | RN[0..NL-1] | VL | RV[0..VL-1]
Example - Set JoyDevice1 to value 1:
02 02 0c 00 00 00 [request_id] 52 01 0a 4a 6f 79 44 65 76 69 63 65 31 01 01
- RT: 0x01 (Integer)
- NL: 0x0a (10 bytes)
- RN: "JoyDevice1"
- VL: 0x01 (1 byte)
- RV: 0x01
Response: Empty body.
Minimum VICE version: 3.5
Command: Dump (0x41)
Command body:
SR | SD | FL | FN[0..FL-1]
| Field | Description |
|---|---|
| SR | Save ROMs? (0x00=false, >=0x01=true) |
| SD | Save disks? (0x00=false, >=0x01=true) |
| FL | Filename length (1 byte) |
| FN | Filename (ASCII, not null-terminated) |
Example - Save /path/to/snapshot.vsf with ROMs and disks:
02 02 [length] [request_id] 41 01 01 [FL] [filename bytes...]
Response: Empty body.
Important:
- Filename must be absolute path or relative to VICE working directory
- Parent directory must exist
- After saving, do NOT send Exit (0xaa) if you want to remain paused
- Recommended: SR=1, SD=1 for complete state
Minimum VICE version: 3.5
Command: Undump (0x42)
Command body:
FL | FN[0..FL-1]
| Field | Description |
|---|---|
| FL | Filename length (1 byte) |
| FN | Filename (ASCII, not null-terminated) |
Example - Load /path/to/quickstart.vsf:
02 02 [length] [request_id] 42 [FL] [filename bytes...]
Response body:
PC PC
| Field | Description |
|---|---|
| PC | Current program counter (2 bytes) |
Effect: Restores complete system state, emulator paused in monitor mode. Use Exit (0xaa) to resume.
Minimum VICE version: 3.5
Method: Use text monitor (port 6510) for attach/detach operations.
Text monitor protocol: Line-based text commands, newline-terminated.
detach 8\n
attach 8 "/full/absolute/path/to/disk.d64"\n
Workflow:
- Connect to text monitor (port 6510)
- Optionally pause emulation first (Registers Get 0x31 via binary monitor) to avoid racing drive emulation
- Send
detach 8\n - Send
attach 8 "/path/to/new-disk.d64"\n - Read responses until prompt appears to avoid buffer buildup
- If paused, send Exit (0xaa) via binary monitor to resume
Important: Must use absolute paths.
Minimum VICE version: 3.5
Method: Use text monitor (port 6510) screenshot command.
Text monitor protocol:
screenshot "/full/absolute/path/to/screenshot.png"\n
Supported formats: PNG, BMP, PCX, IFF, PPM, DOODLE (format auto-detected from extension)
Important: Read responses until prompt appears to avoid buffer buildup, even if you ignore the text content.
Naming convention: Save alongside snapshots with matching base names:
-
autosave-10s-001.vsf→autosave-10s-001.png -
quickstart.vsf→quickstart.png
Workflow for autosaves:
- Pause emulation (Registers Get 0x31 via binary monitor)
- Stop autosave timers
- Capture screenshot (text monitor:
screenshot "/path/to/file.png"\n, then read until prompt) - Save snapshot (Dump 0x41 via binary monitor)
- Resume emulation (Exit 0xaa via binary monitor)
- Restart autosave timers
Minimum VICE version: 3.5
VICE sends unsolicited responses with Request ID 0xffffffff:
| Response | Code | When |
|---|---|---|
| Register Info | 0x31 | Emulator stops (entering monitor) |
| Stopped | 0x62 | Checkpoint hit, step complete |
| Resumed | 0x63 | After Exit command |
| JAM | 0x61 | CPU executes illegal instruction |
Response body: PC PC (program counter where jam occurred)
Meaning: CPU crash/illegal instruction. Emulator stopped, user intervention required (reset or restore snapshot).
Command body: RS (1 byte)
Reset types:
- 0x00 = Reset system (soft)
- 0x01 = Power cycle (hard)
- 0x08-0x0b = Reset drives 8-11
Minimum VICE version: 3.5
| ID | Memspace |
|---|---|
| 0x00 | Main memory |
| 0x01 | Drive 8 |
| 0x02 | Drive 9 |
| 0x03 | Drive 10 |
| 0x04 | Drive 11 |
- VICE Manual - Binary Monitor: https://vice-emu.sourceforge.io/vice_13.html
- VICE Manual - Monitor Commands: https://vice-emu.sourceforge.io/vice_12.html
- VICE Manual - Resources: https://vice-emu.sourceforge.io/vice_6.html