Source: Compute's Mapping the Commodore 64; The Anatomy of the Commodore 64
| Range | Size | Description |
|---|---|---|
| $0000–$00FF | 256 B | Zero Page (fastest addressing) |
| $0100–$01FF | 256 B | CPU Stack |
| $0200–$03FF | 512 B | OS/BASIC work area (vectors, tables) |
| $0400–$07FF | 1 KB | Default screen text matrix (40×25) |
| $0800–$9FFF | 38 KB | BASIC program area (default) |
| $A000–$BFFF | 8 KB | BASIC ROM (or cartridge/RAM under) |
| $C000–$CFFF | 4 KB | Upper RAM (ML friendly) |
| $D000–$DFFF | 4 KB | I/O space (VIC-II/SID/CIA/Color RAM) |
| $E000–$FFFF | 8 KB | Kernal ROM (or RAM under) |
| Address | Label | Description |
|---|---|---|
| $00 | R6510 | 6510 I/O direction register |
| $01 | R6510+1 | 6510 I/O port (RAM/ROM banking + cassette) |
| $02 | UNUSED | Free zero-page byte |
| $03–$04 | ADRAY1 | Convert float→integer vector |
| $05–$06 | ADRAY2 | Convert integer→float vector |
| $07 | CHARAC | Search character for BASIC scanner |
| $08 | ENDCHR | Flag: scan to end of BASIC line |
| $09 | TRMPOS | Terminal position for tab |
| $0A | VERCKK | LOAD (0) or VERIFY (1) flag |
| $0B | COUNT | Input buffer character count |
| $0C | DIMFLG | Default (0) or DIM flag |
| $0D | VALTYP | Type flag: 0=float, $FF=string |
| $0E | INTFLG | Integer flag |
| $0F | GARBFL | DATA scan / LIST quote / garbage collect flag |
| $10 | SUBFLG | Subscript flag for FN |
| $11 | INPFLG | INPUT (0) or GET ($40) or READ ($98) |
| $12 | TANSGN | TAN sign / comparison flag |
| $13 | CHANNL | Current I/O channel (0=keyboard/screen) |
| $14–$15 | LINNUM | Integer line number |
| $16 | TEMPPT | Pointer: next temp string |
| $17–$18 | LASTPT | Pointer: last temp string |
| $19–$21 | TEMPST | Temp string descriptor stack |
| $22–$25 | INDEX1 | Utility pointer area |
| $26–$2A | FACEXP | Floating-point accumulator #1 |
| $2B–$2C | TXTTAB | Pointer: start of BASIC text ($0801 default) |
| $2D–$2E | VARTAB | Pointer: start of BASIC variables |
| $2F–$30 | ARYTAB | Pointer: start of BASIC arrays |
| $31–$32 | STREND | Pointer: end of arrays (+1) |
| $33–$34 | FRETOP | Pointer: bottom of string storage |
| $35–$36 | FRESPC | Utility pointer for strings |
| $37–$38 | MEMSIZ | Pointer: top of memory ($A000 default) |
| $39–$3A | CURLIN | Current BASIC line number |
| $3B–$3C | OLDLIN | Previous BASIC line number |
| $3D–$3E | OLDTXT | Pointer: previous BASIC statement |
| $3F–$40 | DATLIN | Line number of current DATA statement |
| $41–$42 | DATPTR | Pointer into current DATA statement |
| $43–$44 | INPPTR | Pointer: INPUT source |
| $45–$46 | VARNAM | Current variable name |
| $47–$48 | VARPNT | Pointer: current variable value |
| $49–$4A | FORPNT | Pointer: FOR/NEXT variable |
| $4B–$4E | OPPTR | Math operator work area |
| $52–$55 | FAC2 | Floating-point accumulator #2 |
| $56 | ARGSGN | Sign comparison, FAC1 vs FAC2 |
| $57–$58 | ARISGN | Sign of result |
| $59 | FACOV | FAC1 overflow byte |
| $5A–$5B | FBUFPT | Pointer: BASIC print buffer |
| $61–$66 | FAC | FAC1 (5 bytes) |
| $69–$6E | ARG | FAC2 (5 bytes) |
| $90 | STATUS | Kernal I/O status (ST) word |
| $91 | STKEY | STOP key flag ($7F = pressed) |
| $93 | VERCK | LOAD/VERIFY flag (Kernal) |
| $94 | C3PO | Cassette: 1=write leader sent |
| $95 | BSOUR | Cassette: byte to write |
| $9A | SXREG | Serial bus I/O address |
| $9B | RDFNM | Record/file number |
| $9C | RDEVNM | Record device |
| $9D | RDSEC | Record secondary address |
| $9E | RIRQSC | RS-232 recv IRQ state |
| $9F | STATUS2 | RS-232 status |
| $A0–$A2 | TIME | 60Hz jiffy clock (24-bit, MSB=$A0) |
| $A3–$A4 | PCTR | Cassette sync / block count |
| $B0–$B5 | EAL | Kernal: device address / sector pointers |
| $BA | DFLTN | Default input device (0=keyboard) |
| $BB | DFLTO | Default output device (3=screen) |
| $BC | PRTY | Cassette parity byte |
| $BD | DPSW | Cassette EOT flag |
| $BE | MYCH | Tape character in assembly |
| $BF | CAS1 | Cassette read error correction |
| $C0 | FSBLK | Cassette read: first block flag |
| $C1–$C2 | MXPNT | Pointer: maximum BASIC variable |
| $C3–$C4 | SXPTR | Pointer to tape buffer or screen for cassette |
| $C5 | LSTX | Matrix code of last key pressed |
| $C6 | NDX | Keyboard buffer index (# chars) |
| $C7 | RVS | Reverse mode flag (1=on) |
| $C8 | INDX | Pointer: end of logical input line |
| $C9–$CA | LXSP | Cursor column and row at I/O start |
| $CB | SFDX | Flag: shift/commodore key |
| $CC | BLNSW | Cursor blink enable (0=on) |
| $CD | BLNCT | Countdown to cursor blink |
| $CE | GDBLN | Character under cursor (saved) |
| $CF | BLNON | Last blink state (0=off) |
| $D0 | CRSW | INPUT/GET mode (0=INPUT) |
| $D1–$D2 | PNT | Pointer: current screen line address |
| $D3 | PNTR | Cursor column on current line |
| $D4 | QTSW | Quoted mode flag |
| $D5 | LNMX | Logical line length (39 or 79) |
| $D6 | TBLX | Current cursor row |
| $D7 | DATA | Last character output to screen |
| $D8 | INSRT | Insert mode count |
| $D9–$F2 | LDTB1 | Screen line link table (25 entries) |
| $F3–$F4 | USER | Pointer: base of color RAM ($D800) |
| $F5–$F6 | KEYD | Pointer: keyboard decode table |
| $F7–$F8 | RIBUF | RS-232 input buffer pointer |
| $F9–$FA | ROBUF | RS-232 output buffer pointer |
| $FB–$FE | FREKZP | Free zero-page bytes (user/ML) |
| $FF | BASZPT | BASIC: temp for float-to-string |
The 6510 stack grows downward from $01FF. SP register holds low byte of current top. Do not use this region for data storage in time-critical IRQs — pushes/pulls compete with JSR/RTS.
| Address | Label | Description |
|---|---|---|
| $0200–$0258 | BUF | BASIC/Kernal input buffer (89 bytes) |
| $0259–$0262 | LAT | Logical file number table (10 entries) |
| $0263–$026C | FAT | Device number table (10 entries) |
| $026D–$0276 | SAT | Secondary address table (10 entries) |
| $0277–$0280 | KEYD | Keyboard buffer (10 bytes) |
| $0281–$0282 | MEMSTR | Start of memory pointer ($0800 default) |
| $0283–$0284 | MEMSIZ | Top of memory ($A000 default) |
| $0285 | TIMOUT | Serial IEEE timeout flag |
| $0286 | COLOR | Current foreground color code |
| $0287 | BG COL | Color under cursor |
| $0288 | HIBASE | Screen RAM page ($04 = $0400) |
| $0289 | XMAX | Keyboard buffer max size (10 default) |
| $028A | RPTFLG | Key repeat flag ($40=repeat all) |
| $028B | KOUNT | Repeat delay counter |
| $028C | DELAY | Repeat speed counter |
| $028D | SHFLAG | Keyboard shift flags |
| $028E | LSTSHF | Previous shift state |
| $028F–$0290 | KEYLOG | Pointer: keyboard decode logic |
| $0291 | MODE | Shift+Commodore mode (0=switch, 128=lock) |
| $0292 | AUTODN | Screen scroll enable (0=on) |
| $0293–$0294 | M51CTR | RS-232 control register (fake 6551) |
| $0295–$0296 | M51CDR | RS-232 command register |
| $0297–$0298 | M51AJB | RS-232 baud rate (non-standard) |
| $0299–$029A | RIDBE | RS-232 buffer pointers |
| $029B–$02FF | Other RS-232/cassette work areas |
| Address | Default Points To | Description |
|---|---|---|
| $0300–$0301 | $E38B | IERROR — BASIC error message vector |
| $0302–$0303 | $A483 | IMAIN — BASIC main loop vector |
| $0304–$0305 | $A57C | ICRNCH — Tokenize input line vector |
| $0306–$0307 | $A71A | IQPLOP — List a token vector |
| $0308–$0309 | $A7E4 | IGONE — Execute a statement vector |
| $030A–$030B | $AE86 | IEVAL — Evaluate expression vector |
| $030C | $0 | SAREG — .A saved on IRQ |
| $030D | $00 | SXREG — .X saved on IRQ |
| $030E | $00 | SYREG — .Y saved on IRQ |
| $030F | $00 | SPREG — SP saved on IRQ |
| $0310–$0311 | $FE43/$8B | USRPOK — USR() vector (JMP + addr) |
| $0312–$0313 | $EA31 | IRQ vector (vectored from $FFFE) |
| $0314–$0315 | $EA31 | Hardware IRQ vector (CINV) |
| $0316–$0317 | $FE66 | BRK handler vector (CBINV) |
| $0318–$0319 | $FE47 | NMI vector (NMINV) |
| $031A–$031B | $F34A | IOPEN — OPEN routine vector |
| $031C–$031D | $F291 | ICLOSE — CLOSE routine vector |
| $031E–$031F | $F20E | ICHKIN — CHKIN routine vector |
| $0320–$0321 | $F250 | ICKOUT — CKOUT routine vector |
| $0322–$0323 | $F333 | ICLRCH — CLRCH routine vector |
| $0324–$0325 | $F157 | IBASIN — BASIN/CHRIN routine vector |
| $0326–$0327 | $F1CA | IBSOUT — BSOUT/CHROUT routine vector |
| $0328–$0329 | $F6ED | ISTOP — STOP key check vector |
| $032A–$032B | $F13E | IGETIN — GETIN routine vector |
| $032C–$032D | $F32F | ICLALL — CLALL routine vector |
| $032E–$032F | $FE66 | IUSRTO — User-defined load vector |
| $0330–$0331 | $F549 | ILOAD — LOAD routine vector |
| $0332–$0333 | $F685 | ISAVE — SAVE routine vector |
| Region | Address | Notes |
|---|---|---|
| Screen Matrix | $0400–$07E7 | 1000 bytes: 40 cols × 25 rows (default) |
| Unused | $07E8–$07FF | 24 bytes free |
| Color RAM | $D800–$DBE7 | 1000 bytes, nibble per cell (low 4 bits) |
| Color unused | $DBE8–$DBFF | 24 bytes |
Screen address formula: addr = $0400 + (row × 40) + col
POKE 43,1 : POKE 44,8 resets BASIC start pointer4 KB of RAM, never overlaid by ROM. Ideal location for:
| Range | Chip | Function |
|---|---|---|
| $D000–$D3FF | VIC-II | Video Interface Controller |
| $D400–$D7FF | SID | Sound Interface Device |
| $D800–$DBFF | Color | Color RAM (nibbles) |
| $DC00–$DCFF | CIA #1 | Keyboard, joysticks, IRQ timer |
| $DD00–$DDFF | CIA #2 | Serial bus, VIC bank, NMI timer |
| $DE00–$DEFF | I/O #1 | Cartridge expansion port I/O area 1 |
| $DF00–$DFFF | I/O #2 | Cartridge expansion port I/O area 2 |
When HIRAM=0 or banking overrides I/O region, character ROM or RAM appears instead.
| Bit | Name | 0 = … | 1 = … |
|---|---|---|---|
| 0 | LORAM | BASIC ROM disabled | BASIC ROM at $A000 enabled |
| 1 | HIRAM | Kernal ROM disabled | Kernal ROM at $E000 enabled |
| 2 | CHAREN | Char ROM at $D000 | I/O at $D000 enabled |
| 3 | CASS WR | Cassette write low | Cassette write high |
| 4 | CASS SW | (read only) | Cassette sense line |
| 5 | CASS MT | Cassette motor on | Cassette motor off |
Common values:
$37 (binary 00110111) — default: BASIC+Kernal+I/O visible$36 — Kernal+I/O visible, BASIC RAM underneath$35 — I/O visible, both ROMs as RAM$34 — all RAM, no I/O (character ROM at $D000)$33 — Kernal ROM, character ROM at $D000, no I/O| Address | Label | Function |
|---|---|---|
| $E003 | — | Kernal version/signature bytes |
| $EA31 | IRQRTL | Standard IRQ handler entry |
| $E544 | PLOT | Read/set cursor position |
| $E566 | IOBASE | Return CIA base address in .XY |
| $FF81 | SCINIT | Initialize VIC/screen editor |
| $FF84 | IOINIT | Initialize CIA chips |
| $FF87 | RAMTAS | RAM test and zero page init |
| $FF8A | RESTOR | Restore default vectors |
| $FF8D | VECTOR | Read/set system vectors |
| $FF90 | SETMSG | Set Kernal message flag |
| $FF93 | SECOND | Send secondary address after LISTEN |
| $FF96 | TKSA | Send secondary address after TALK |
| $FF99 | MEMTOP | Read/set top of memory |
| $FF9C | MEMBOT | Read/set bottom of memory |
| $FF9F | SCNKEY | Scan keyboard |
| $FFA2 | SETTMO | Set serial bus timeout |
| $FFA5 | ACPTR | Receive byte from serial bus |
| $FFA8 | CIOUT | Send byte to serial bus |
| $FFAB | UNTLK | Command device to UNTALK |
| $FFAE | UNLSN | Command device to UNLISTEN |
| $FFB1 | LISTEN | Command device to LISTEN |
| $FFB4 | TALK | Command device to TALK |
| $FFB7 | READST | Read I/O status word |
| $FFBA | SETLFS | Set logical/device/secondary address |
| $FFBD | SETNAM | Set filename address and length |
| $FFC0 | OPEN | Open logical file |
| $FFC3 | CLOSE | Close logical file |
| $FFC6 | CHKIN | Set input channel |
| $FFC9 | CKOUT | Set output channel |
| $FFCC | CLRCH | Restore default I/O channels |
| $FFCF | CHRIN | Input character from current channel |
| $FFD2 | CHROUT | Output character to current channel |
| $FFD5 | LOAD | Load file from device |
| $FFD8 | SAVE | Save file to device |
| $FFDB | SETTIM | Set jiffy clock |
| $FFDE | RDTIM | Read jiffy clock |
| $FFE1 | STOP | Check STOP key |
| $FFE4 | GETIN | Get character from keyboard buffer |
| $FFE7 | CLALL | Close all channels and files |
| $FFEA | UDTIM | Increment jiffy clock |
| $FFED | SCREEN | Return screen dimensions |
| $FFF0 | PLOT | Read/set cursor X/Y position |
| $FFF3 | IOBASE | Return I/O base address |
| $FFFA | — | NMI vector (points into Kernal) |
| $FFFC | — | RESET vector ($FCE2) |
| $FFFE | — | IRQ/BRK vector ($FF48) |
| Bits 0–1 | VIC Bank | Address Range |
|---|---|---|
| 11 | 0 | $0000–$3FFF |
| 10 | 1 | $4000–$7FFF |
| 01 | 2 | $8000–$BFFF |
| 00 | 3 | $C000–$FFFF |
Default: Bank 0 ($0000–$3FFF) — screen at $0400, charset at $1000 (ROM image).
Character ROM is mirrored into VIC banks 0 and 2 at offsets $1000 and $1800.
Each sprite = 64 bytes (63 data + 1 padding). Pointer bytes stored at screen RAM + $03F8 (8 bytes).
| Pointer Value | Sprite Data Address (Bank 0) |
|---|---|
| $0D | $0340 |
| $0E | $0380 |
| $0F | $03C0 |
| $80 | $2000 |
| $81 | $2040 |
| … | … |
sprite_addr = bank_base + (pointer_value × 64)
Powered by TurnKey Linux.