Apple II System Monitor

Apple II System Monitor Commands

Entering the Monitor

MethodCommandDescription
From BASICCALL -151Enter monitor from Applesoft or Integer BASIC
From DOSCALL -151Same as BASIC
Reset + KeyRESET then CTRL+BOn older Apple IIs
From AssemblyJMP $FF69Jump to monitor entry point
BreakBRKExecute BRK instruction (if vector set)
Power On*Some Apple II models boot to monitor
The monitor prompt is an asterisk (*)

Basic Commands

CommandSyntaxDescriptionExample
Exit MonitorCTRL+C or CTRL+BReturn to BASIC^C
Exit to Integer BASICE000GCold start Integer BASIC*E000G
Exit to ApplesoftE003GCold start Applesoft*E003G
Warm Start DOS3D0GReturn to DOS without destroying program*3D0G
Cold Start DOS3D3GRestart DOS (clears program)*3D3G
ResetCTRL+RESETHardware reset-

Memory Examination Commands

CommandSyntaxDescriptionExample
Display ByteaddrDisplay single byte*300
0300- A9
Display Rangeaddr.addrDisplay memory range*300.31F
0300- A9 00 85...
Display Next(just press Return)Display next 8 bytes*
0308- 00 00 00...
Display Pageaddr.addrDisplay full page*300.3FF
ASCII Display(automatic)Shows ASCII on right side*300.30F
0300- C1 D0 D0 CC C5 APPLE

Display Format

*800.807 0800- A9 00 AA 20 EF FF E8 60 .. ....` ↑ ↑ ↑ Address Hex bytes ASCII

Memory Modification Commands

CommandSyntaxDescriptionExample
Store Byteaddr:byteStore single byte*300:A9
Store Multipleaddr:b1 b2 b3...Store multiple bytes*300:A9 00 85 06
Modify Modeaddr:byteReturnEnter modify mode*300:A9
*301:_
Previous in Modify or -Go back one byte*301:
*300:A9
Next in Modify or SpaceGo forward one byte*300:A9 Space
*301:_
Exit ModifyReturnExit modify mode*301:Return
*
ASCII Entryaddr:"text"Enter ASCII text (with high bit set)*300:"HELLO"
Use period (.) to separate addresses in ranges, colon (:) to store data

Execution Commands

CommandSyntaxDescriptionExample
Go/RunaddrGExecute from address*300G
JumpaddrJJMP to address*300J
TraceaddrTSingle-step execution*300T
StepaddrSStep over subroutine*300S
ContinueCTRL+YContinue from breakpoint^Y
Call SubroutineaddrCTRL+EJSR to address*FD8E^E

Execution Notes

  • G - Starts execution and doesn't return unless program does RTS to monitor
  • J - Same as G but displays registers first
  • T - Executes one instruction and shows registers (trace mode)
  • S - Steps over JSR calls (executes whole subroutine)

Arithmetic Operations

CommandSyntaxDescriptionExample
Addaddr+addrAdd two addresses*1000+80
1080
Subtractaddr-addrSubtract addresses*1000-80
0F80
Hex to Dec=addrConvert hex to decimal*=FF
255
Dec to Hex=+decimalConvert decimal to hex*=+255
00FF
Two's Complement=-addrCalculate two's complement*=-1
FFFF
The monitor uses 16-bit arithmetic for all calculations

Move & Verify Commands

CommandSyntaxDescriptionExample
Move Memorydest<start.endMMove/copy memory block*4000<300.3FFM
Verifydest<start.endVCompare memory blocks*4000<300.3FFV
Fill Memorystart.end:byteFill range with byte*300.3FF:00
Search Memorystart<byte byte...SSearch for byte pattern*300<A9 00S

Move Command Details

*4000<300.3FFM ; Copy $300-$3FF to $4000-$40FF *800<300.3FFM ; Copy $300-$3FF to $800-$8FF Note: Source and destination can overlap

Register Display & Modification

CommandSyntaxDescriptionExample
Display AllCTRL+EDisplay all registers*^E
A=00 X=00 Y=00 P=30 S=F8
Set AccumulatorA:valueSet A register*A:FF
Set X RegisterX:valueSet X register*X:01
Set Y RegisterY:valueSet Y register*Y:80
Set StatusP:valueSet processor status*P:30
Set Stack PtrS:valueSet stack pointer*S:FF

Status Register Flags

Bit 7
N - Negative
Bit 6
V - Overflow
Bit 5
- - Unused (always 1)
Bit 4
B - Break
Bit 3
D - Decimal
Bit 2
I - Interrupt Disable
Bit 1
Z - Zero
Bit 0
C - Carry

Input/Output Commands

CommandSyntaxDescriptionExample
Input from KeyboardIInput hex byte from keyboard*300:I
(type two hex digits)
Output to ScreenOOutput ASCII character*300:41 O
A
Control OutputCTRL+KSet output hook*^K
Normal OutputNReset to normal I/O*N
User VectoraddrUSet user command vector*300U

Mini-Assembler (! Command)

CommandDescriptionExample
!Enter mini-assembler*!
!_
addr:opcodeAssemble instruction!300:LDA #$00
ReturnNext address!302:_
$Exit assembler!$
*

Mini-Assembler Examples

*! ; Enter mini-assembler !300:LDA #$00 ; A9 00 !STA $06 ; 85 06 (auto-increments) !INX ; E8 !RTS ; 60 !$ ; Exit to monitor *300L ; Disassemble to verify 0300- A9 00 LDA #$00 0302- 85 06 STA $06 0304- E8 INX 0305- 60 RTS
The mini-assembler supports standard 6502 mnemonics and addressing modes

SWEET16 Commands

SWEET16 is a 16-bit virtual machine interpreter built into Apple II ROM

To Use SWEET16Description
300:20 00 F8JSR $F800 - Enter SWEET16
303:(SWEET16 code)Place SWEET16 opcodes
xxx:00RTN - Return to 6502

SWEET16 Registers

  • R0-R15: Sixteen 16-bit registers
  • R0: Accumulator
  • R12: Subroutine stack
  • R13: Comparison results
  • R14: Status register
  • R15: Program counter

Useful ROM Monitor Routines

AddressNameFunctionRegisters Used
$F800SWEET16Enter SWEET16 interpreterAll
$F819SETSet SWEET16 register-
$F831LDLoad SWEET16 register-
$F941PRNTAXPrint A and X in hexA, X
$F944PRBLNKPrint 3 spacesX=3
$F948PRBL2Print X spacesX
$FA62RTS1Do RTS-
$FAA6OLDRSTOld reset entryAll
$FB1EPREADRead paddleX
$FB2FINITInitialize text screenA
$FB39SETTXTSet text mode-
$FB40SETGRSet graphics mode-
$FB60SCRNRead text screenA, X, Y
$FBC1BASCALCCalculate text base addressA
$FBD9BELL1Ring bellA
$FBE4BELL2Ring bell twiceA
$FC22VTABVertical tab to AA
$FC24VTABZVertical tab to CV-
$FC42CLREOPClear to end of pageY
$FC58HOMEClear screenA, Y
$FC62CRCarriage returnA
$FC66LFLine feedA
$FC9CCLREOLClear to end of lineY
$FCA8WAITDelay 1/2(26+27A+5A²) μsA
$FD0CRDKEYRead keyboardA
$FD1BKEYINRead keyboard (no cursor)A
$FD35RDCHARRead char with cursorA
$FD6AGETLNGet line of inputA, X
$FD6FGETLNZGet line (use prompt)A, X
$FD8ECROUTOutput carriage returnA
$FDA3PRBYTEPrint byte in hexA
$FDDAPRHEXPrint nibble in hexA
$FDE3PRNTYXPrint Y and X in hexY, X
$FDEDCOUTOutput characterA
$FDF0COUT1Output to screenA
$FE2CMOVEMove memoryA, Y
$FE5ELISTDisassemblerA, X, Y
$FE80SETINVSet inverse text-
$FE84SETNORMSet normal text-
$FEB0SETVIDSet video mode-
$FEC5WRITEWrite cassette tapeA, Y
$FECCREADRead cassette tapeA, Y
$FF3ABELLRing bell-
$FF59BRKVECBRK vector location-
$FF65MONEnter monitorAll
$FF69MONZEnter monitor quietlyAll
$FF70TRACETrace one instructionAll

Important Memory Locations & Vectors

AddressNameDescription
$0020-$002FWNDLFT/TOP/WIDTH/BTMText window parameters
$0024CHHorizontal cursor position
$0025CVVertical cursor position
$0026-$0027GBASL/HGraphics base address
$0028-$0029BASL/HText base address
$0033PROMPTMonitor prompt character
$0036-$0037CSWCharacter output hook
$0038-$0039KSWKeyboard input hook
$003A-$003BPCL/HProgram counter storage
$003C-$003DA1L/HMonitor work area
$003E-$003FA2L/HMonitor work area
$0040-$0041A3L/HMonitor work area
$0042-$0043A4L/HMonitor work area
$0045ACCAccumulator storage
$0046XREGX register storage
$0047YREGY register storage
$0048STATUSStatus register storage
$0049SPNTStack pointer storage
$0050-$00FFSTACK6502 stack area (grows down from $01FF)
$0200-$02FFINBUFInput buffer
$03F0-$03F1BRKVBRK vector (normally $FA59)
$03F2-$03F3SOFTEVSoft entry vector (normally $FF59)
$03F4PWREDUPPower-up byte
$03F5-$03F7USRVUser command vector (JMP)
$03F8-$03FANMINMI vector (JMP)
$03FB-$03FDIRQVIRQ vector (JMP)
$FFFA-$FFFBNMIVECNMI hardware vector
$FFFC-$FFFDRESETVRESET hardware vector
$FFFE-$FFFFIRQVECIRQ hardware vector

Monitor Tips & Tricks

Quick Disassembly: Use addrL to disassemble 20 instructions starting at addr
Memory Search: To find a byte sequence, use the Search command: *800<A9 00 85S
Breakpoints: Replace an instruction with BRK ($00) to create a breakpoint. Original byte saved at $49
Quick Fill: Fill memory with zeros: *300.3FF:0
Save Typing: After entering an address once, subsequent commands use it as default
ASCII Text: View memory as ASCII by looking at the right side of the display
Register Shortcut: Just press ^E to see all registers quickly
Modify Memory: Use Space to advance, minus to go back while modifying
Hex Math: Monitor supports 16-bit addition and subtraction directly
Call ROM: Many ROM routines can be called directly, e.g., *FC58G to clear screen

Common Monitor Workflows

1. Write and test a small routine: *300:A9 00 ; LDA #$00 *302:85 06 ; STA $06 *304:60 ; RTS *300L ; Disassemble to verify *300G ; Run it 2. Save memory to cassette (old school!): *800.8FFW ; Write $800-$8FF to tape *800.8FFR ; Read it back 3. Examine and modify a BASIC program: *67.68 ; See program start pointer *800.9FF ; View program area 4. Debug with breakpoints: *305 ; See what's at $305 *305:00 ; Replace with BRK *300G ; Run until breakpoint *^E ; Check registers *305:XX ; Restore original byte *^Y ; Continue execution
Historical Note: The Apple II System Monitor, written by Steve Wozniak, fit in just 2KB of ROM and provided a complete development environment. Its compact design and powerful features made it legendary among early microcomputer monitors.