---
name: vice-emulator
description: >
Use this skill when you need to run, autostart, debug, snapshot, or automate
Commodore 64 programs in the VICE emulator. Covers x64sc, command-line
autostart, warp mode, true drive emulation handling, the built-in monitor,
remote and binary monitor servers, and snapshot caveats.
Source: VICE 3.10 manual (C:\Program Files\GTK3VICE-3.10-win64\doc\vice.txt).
---
# VICE Emulator Workflow for the Commodore 64
This skill is primarily about **debugging programs with VICE**, not just launching them.
## When to Use This Skill
Use this skill when you need to:
- Launch a `.prg`, `.d64`, `.g64`, `.tap`, or cartridge image in VICE
- Choose the correct C64 emulator executable
- Autostart software for test runs
- Open the VICE monitor and set breakpoints or watchpoints
- Save or restore snapshots during debugging
- Automate VICE from an agent via the remote or binary monitor
If the user asks to "debug the assembly," "trace startup," "find where banking breaks," or "step through a PRG," this is the first skill to load.
---
## Preferred C64 Emulator
For C64 work, prefer:
- `x64sc` — accurate C64 emulator with cycle-based and pixel-accurate VIC-II emulation
The VICE manual notes that:
- `x64` was the older fast emulator
- `x64sc` is the accurate emulator and the default choice for serious debugging
Useful companion tools in the VICE package:
- `c1541` — disk image tool
- `petcat` — BASIC tokenization/detokenization tool
- `cartconv` — cartridge image conversion
- `vsid` — SID player
---
## Command-Line Autostart
The VICE manual documents two equivalent ways to autostart:
```text
x64sc mydisk.d64
x64sc -autostart myprog.prg
```
You can also select a named file inside an image:
```text
x64sc "demo.d64:loader"
x64sc -autostart "demo.d64:loader"
```
Helpful options for agent workflows:
```text
-autostart-warp
-autostart-handle-tde
-basicload
+basicload
```
Notes from the manual:
- `-autostart-warp` temporarily enables warp mode during autostart
- `-autostart-handle-tde` lets VICE temporarily manage True Drive Emulation during autostart
- For raw `.prg`/P00 files, VICE loads the file and then restores the previous autostart settings
- If the started program must access the host filesystem, enable virtual device traps
---
## Native, Remote, and Binary Monitor
VICE supports three monitor-related workflows that are useful for agents:
### Native Monitor
```text
-nativemonitor
+nativemonitor
```
When enabled, the monitor runs in the spawning terminal instead of only inside the emulator UI.
### Remote Monitor
```text
-remotemonitor
-remotemonitoraddress ip4://127.0.0.1:6510
```
This enables the text-based remote monitor server.
### Binary Monitor
```text
-binarymonitor
-binarymonitoraddress ip4://127.0.0.1:6502
```
This enables the binary monitor protocol used by automation tools and external debuggers.
### Recommended Debug Launch
For agent-driven debugging, prefer launching VICE with:
```text
x64sc -autostart c64os.prg -autostart-warp -nativemonitor -keepmonopen -refreshonbreak
```
Useful companion options from the manual:
```text
-monlog
-monlogname vice-monitor.log
```
These make the monitor visible in the terminal, keep it open after continuing, refresh screen state on breaks, and optionally log monitor output.
---
## Core Debugging Commands
These monitor commands are the most useful for day-to-day program debugging:
| Command | Meaning |
|---------|---------|
| `x` / `exit` | Leave the monitor and resume execution |
| `q` / `quit` | Exit VICE |
| `r` / `registers` | Show or modify registers |
| `reset [type]` | Reset the machine or drive |
| `goto
` | Set the program counter |
| `next [count]` | Step over instructions |
| `step [count]` | Step into instructions |
| `return` | Run until the next `RTS` or `RTI` |
| `until ` | Run until an address is reached, then break |
| `bt` / `backtrace` | Show the JSR call chain |
| `m ` | Show memory |
| `i ` | Show memory as PETSCII |
| `d ` | Disassemble |
| `io [address]` | Inspect I/O registers or a chip block |
| `break exec $addr` | Break on execution |
| `watch store $addr` | Break when an address is written |
| `trace exec $addr1 $addr2` | Trace execution without stopping |
| `bank` | Show/select banks |
| `device c:` / `8:` | Switch computer vs drive address space |
| `sidefx off` | Prevent monitor reads from causing hardware side effects |
| `keybuf "text\x0d"` | Feed characters into the keyboard buffer |
| `playback "file"` | Execute commands from a monitor script |
| `record "file"` | Record monitor commands for replay |
Examples:
```text
break exec $0810
watch store $0001
d $0810 $0840
m $0000 $0002
bt
return
```
Conditional checkpoints are supported. The manual documents register-based conditions and raster-aware conditions such as `RL` and `CY`.
---
## Breakpoints, Watchpoints, and Tracepoints
VICE supports several complementary debugging styles:
### 1. Breakpoints
Use when you care about **where execution reaches**:
```text
break exec $0810
until $0930
```
### 2. Watchpoints
Use when you care about **what wrote or read a memory location**:
```text
watch store $0001
watch load $dc0d
```
For C64 debugging, watchpoints are especially useful for:
- `$0001` — memory banking changes
- `$0314/$0315` — IRQ vector changes
- `$d020/$d021` — border/background color debugging
- `$0400-$07e7` — screen RAM writes
- `$d800-$dbe7` — color RAM writes
### 3. Tracepoints
Use when you need a non-stopping execution log:
```text
trace exec $0810 $08ff
```
### 4. Conditional Checkpoints
The VICE manual supports conditions using registers, arithmetic, boolean operators, raster line `RL`, cycle `CY`, and bank-qualified memory references.
Examples:
```text
break exec $0810 if A == $00
break load 0 $ffff if @cpu:(pc - $1) == $37
```
### 5. Checkpoint Automation
The monitor can attach commands to checkpoints:
```text
command 2 "m $0000 $0002"
ignore 2 1
disable 1
enable 1
```
This is useful when you want an automatic memory dump the first time a watchpoint hits.
---
## Stepping Strategy
Use these commands intentionally:
- `step` for stepping **into** a subroutine
- `next` for stepping **over** a subroutine
- `return` for stepping **out** of the current subroutine
- `until ` to run quickly to a known target
- `backtrace` to recover the call chain after a break
Recommended sequence for a new bug:
1. Break at the program entry or suspicious routine
2. `d` the nearby code
3. `r` to inspect registers
4. `step` or `next` depending on whether you need to enter subroutines
5. `backtrace` if you need to know how execution reached the current point
6. Add watchpoints once you identify suspicious state
---
## Safe Inspection Rules
The monitor manual explicitly documents side-effectful reads.
For C64 work:
- start with `sidefx off`
- use `device c:` for the main machine and `device 8:` when debugging a true-emulated drive CPU
- use `bank` if you need to inspect the CPU-visible versus I/O-visible memory view
- use `io $d000`, `io $d400`, `io $dc00`, or `io $dd00` when you want chip-level register context
---
## Monitor Script Files
VICE can execute a command file from inside the monitor, and can also record command sequences:
```text
playback "examples/vice-monitor-c64os.txt"
record "my-session.txt"
```
This is the easiest way for an agent to set up a repeatable debug session.
In this repository, prefer:
- `examples/vice-monitor-c64os.txt` for startup and banking inspection
- `examples/vice-monitor-c64os-debug.txt` for a fuller debugging session with labels, checkpoints, and keyboard injection
---
## Debugging Recipes
### Debugging PRG Startup
1. Launch with `-nativemonitor -keepmonopen -refreshonbreak`
2. `break exec $0810`
3. `d $0801 $0840`
4. `step` through startup or `next` over known KERNAL calls
### Debugging Banking Problems
1. `watch store $0001`
2. Add `command "m $0000 $0002"` to dump the port state when it hits
3. Use `bank` and `io` to inspect what memory view is active
### Debugging Command Input
1. Break at your parser or input loop
2. Use `keybuf "help\x0d"` to push test input into the keyboard buffer
3. Use `i` on the input buffer to inspect PETSCII text
### Debugging IRQ/Vector Corruption
1. `watch store $0314 $0315`
2. `watch store $0318 $0319`
3. Use `bt` and `d` when the watchpoint hits
4. If needed, inspect chip state with `io $dc00` and `io $d000`
---
## Snapshots
VICE snapshots save the complete emulator state, including memory configuration and optionally attached drives.
Use snapshots for:
- fast retry points during debugging
- preserving an emulator state mid-session
- short-lived reproduction cases
Do not use snapshots for:
- permanent archival storage
- cross-version compatibility guarantees
The VICE manual explicitly warns that snapshot compatibility is not reliable across versions.
---
## Recommended Repo Workflow
For this repository:
1. Build the program with `build.bat`
2. Launch `c64os.prg` with `x64sc -autostart c64os.prg -autostart-warp -nativemonitor -keepmonopen -refreshonbreak`
3. Run `playback "examples/vice-monitor-c64os-debug.txt"` for an immediate debug setup
4. Use `watch store $0001` to confirm banking writes
5. Use `step`, `next`, `return`, and `backtrace` to narrow the failing routine
6. Use snapshots for quick iteration, not long-term storage
---
## Common Pitfalls
1. `x64sc` is the preferred accurate emulator; do not default to the older `x64`
2. Autostart behavior changes depending on PRG vs image file
3. True Drive Emulation can affect autostart speed and compatibility
4. Monitor reads can have side effects unless you disable them with `sidefx off`
5. Stepping without choosing between `step`, `next`, and `return` can waste a lot of time in KERNAL code
6. Forgetting `device 8:` vs `device c:` can make you debug the wrong CPU when true drive emulation is involved
7. Snapshots are convenient, but the manual warns against treating them as stable long-term artifacts