The Monitor
Underneath BASIC there's a second program in the ROM that lets you look at the machine's memory directly, byte by byte, and run code that isn't BASIC at all.
You don't need it. You can write games for years without opening it. But it's where you go when you want to know what's really happening, and it's the door into machine code.
Getting in
Three ways, all landing in the same place:
From BASIC, type BRK:
BRK
6502 MONITOR v1.1
BRK AT $E9D1
PC=E9D3 A=00 X=FF Y=68 SP=FA ---B-IZC
.At startup, press Esc at the ENTER=BASIC ESC=MONITOR line instead of Enter.
From your own machine code, by executing a BRK instruction — which is how you use it as a debugger.
That single . is the Monitor's prompt, the way OK is BASIC's. The line above it is the state of the processor at the moment you arrived: where it was (PC), what was in its three registers (A, X, Y), and its flags. Don't worry about it yet.
X takes you back to BASIC, with your program intact:
X
OKLooking at memory
M for memory, with an address in hexadecimal:
M 0800
.:0800 00 00 00 00 00 00 00 00 ........
.:0808 00 00 00 00 00 00 00 00 ........
.:0810 00 00 00 00 00 00 00 00 ........Address on the left, eight bytes in hex, then the same bytes as characters on the right — which is how you spot text in among the numbers.
D disassembles instead, turning bytes back into 65C02 instructions:
D FF00
.,FF00 A9 1B LDA #$1B
.,FF02 C9 08 CMP #$08
.,FF04 F0 18 BEQ $FF1E
Everything it does
| Command | Type | What it does |
|---|---|---|
X | X | Exit to BASIC |
R | R | Display saved CPU registers: `PC=xxxx A=xx X=xx Y=xx SP=xx NV-BDIZC` |
M | M [addr] [addr] | Hex + ASCII memory dump (8 bytes/line); bare `M` continues from last address |
D | D [addr] [addr] | Disassemble 65C02 instructions (20 lines default); supports the full WDC 65C02 + Rockwell instruction set |
> | > ADDR XX [XX XX ...] | Deposit (write) bytes starting at address |
F | F ADDR1 ADDR2 XX | Fill memory range with a byte value |
T | T SRC_START SRC_END DEST | Transfer (copy) a memory block; handles overlapping regions |
H | H ADDR1 ADDR2 XX [XX XX ...] | Hunt (search) for a byte pattern in a range |
C | C ADDR1 ADDR2 ADDR3 | Compare two memory regions; prints differing addresses |
G | G [addr] | Go — JMP to address (or saved PC); restores all registers via RTI |
J | J [addr] | JSR — call a subroutine; RTS returns to the monitor with register display |
; | ; PC xxxx A xx X xx Y xx SP xx P xx | Modify saved registers (any subset, any order) |
L | L ["FILE"] [ADDR] | Load from CompactFlash (with filename) or XModem (without) to address (default `$0800`). Loading at the default address lets `X` hand the program straight to BASIC, ready to `RUN` |
S | S ["FILE"] ADDR1 ADDR2 | Save to CompactFlash (with filename) or XModem (without) |
@ | @ | List current disk's directory (prints `DISK n` header) |
N | N $XXXX or N +DDDDD or N %BBBBBBBBBBBBBBBB | Number conversion — hex (`$xx`), decimal (`+ddd`), or binary (`%bbbb`) input shown in all three bases |
# | # NN (hex disk 00-FF selects); # alone reports the current disk | Select CF disk bank `NN` (hex 00–FF); `#` alone reports the current disk |
The two you'll reach for besides M and D are R, which reprints that register line, and the two ways of running code:
J addrcalls the code at that address like a subroutine. When it finishes, you land back at the.prompt with the registers on show. This is the one to use.G addrjumps there and hands the machine over completely, interrupts and all. Nothing brings you back except aBRKin the code you jumped to — and because interrupts are off, the keyboard has stopped working, so if the code doesn't return you'll be reaching for the reset button.
Zeros disassemble as BRK
Point D at empty memory and you get page after page of BRK. Nothing is broken — the byte $00 is the BRK instruction, and unwritten memory is all zeros.
The easter egg
Type J FF00:
J FF00
\That backslash is the prompt of Wozmon — Steve Wozniak's monitor for the Apple I, written in 1976, kept here byte for byte because it deserves to survive. It's 256 bytes long and it does three things:
FF00.FF0F— show a range of memory0300: A9 01 60— put bytes into memory0300R— run from an address
It predates this machine by nearly fifty years and shares none of its commands. Press reset when you've had enough — your BASIC program will still be there.
Use J, not G
G FF00 prints the backslash and then ignores everything you type. Wozmon needs the keyboard, and G turns interrupts off on its way out — so the keystrokes never arrive. J leaves them on.

📄 Monitor Reference card — all seventeen commands, the register display and the G/J trap, on two printable pages.

