Commodore 64
The Commodore 64 (1982) is the best-selling personal computer of all time, with an estimated 17 million units sold. It's powered by a 1 MHz MOS 6510 CPU (a variant of the 6502), paired with the VIC-II graphics chip and the legendary SID sound chip.
The C64 has an enormous community, decades of published tutorials, and more example code than any other 8-bit machine. It's an excellent starting platform.
Languages in the IDE
| Language | Preset name | Use for |
|---|---|---|
| Commodore BASIC V2 | C64 BASIC | Learning, quick experiments, small utilities |
| CC65 C | C64 C | Structured programs, games with logic-heavy code |
| KickAss (6502 asm) | C64 Assembly | Maximum performance, demos, low-level hardware |
| XC-BASIC 3 | C64 XC-BASIC | BASIC syntax, compiled speed |
Quick start
- Choose C64 in the platform dropdown.
- Select your preferred language.
- Load an example from the Examples menu — it gives you a known-good starting point.
- Build and run in the Vice emulator.
Click the emulator first
Before typing in the emulated C64, click the emulator window to give it keyboard focus. Some shortcut keys (like Ctrl) are intercepted by the browser otherwise.
Hardware overview
The CPU — MOS 6510
The 6510 is a 6502 with an extra 8-bit I/O port at address $0000/$0001. This port controls ROM banking — switching BASIC ROM, Kernal ROM, and I/O in and out of the address space.
Most programs leave the banking at the default (I/O visible, both ROMs present). If you need all 64 KB of RAM, you can bank out the ROMs — but then the Kernal routines are also gone.
VIC-II — Video
The VIC-II (Video Interface Chip II) handles all graphics on the C64:
- Text mode: 40×25 characters, 16 colours per cell (ink + paper)
- High-res bitmap: 320×200 pixels, 2 colours per 8×8 cell
- Multicolour bitmap: 160×200 pixels, 4 colours per 4×8 cell
- Sprites: 8 hardware sprites, each 24×21 pixels, can be multicolour
- Smooth scrolling in both X and Y
- Raster interrupts: trigger code at a specific scanline
VIC-II registers are at $D000–$D3FF. The most commonly used:
| Address | Register |
|---|---|
| $D020 | Border colour |
| $D021 | Background colour 0 |
| $D000/$D001 | Sprite 0 X/Y position |
| $D015 | Sprite enable bits |
| $D016 | Control register 2 (multicolour, X scroll) |
| $D011 | Control register 1 (Y scroll, bitmap mode) |
| $D018 | Memory pointers (screen RAM and charset bank) |
| $D012 | Raster line counter / IRQ trigger |
SID — Sound
The SID chip (6581/8580) is one of the most beloved sound chips ever made — three voices, each with their own waveform (triangle, sawtooth, square/pulse, noise), ADSR envelope, and a filter. Many people buy a C64 just to hear SID music.
SID registers start at $D400:
| Address | Register |
|---|---|
| $D400/$D401 | Voice 1 frequency (lo/hi) |
| $D404 | Voice 1 control (waveform, gate) |
| $D405/$D406 | Voice 1 attack/decay, sustain/release |
| $D418 | Filter cutoff frequency hi, volume |
A simple beep:
10 POKE 54296, 15 : REM MAX VOLUME
20 POKE 54272, 200 : REM VOICE 1 FREQ LOW
30 POKE 54273, 30 : REM VOICE 1 FREQ HIGH
40 POKE 54277, 9 : REM ATTACK=0, DECAY=9
50 POKE 54278, 240 : REM SUSTAIN=15, RELEASE=0
60 POKE 54276, 33 : REM SAWTOOTH WAVE + GATE ON
70 FOR I=1 TO 1000 : NEXT : REM WAIT
80 POKE 54276, 32 : REM GATE OFF (release)
CIA chips — I/O
Two CIA (Complex Interface Adapter) chips handle keyboard, joystick, timers, and serial I/O:
| Chip | Base | Handles |
|---|---|---|
| CIA 1 | $DC00 | Keyboard matrix, joystick ports, timer A/B |
| CIA 2 | $DD00 | Serial bus, user port, VIC bank select, timer A/B |
Memory map
| Range | Contents |
|---|---|
| $0000–$00FF | Zero page (fast variable storage) |
| $0100–$01FF | Hardware stack |
| $0200–$03FF | OS workspace and page 2 |
| $0400–$07FF | Screen character RAM (default, 40×25) |
| $0800–$9FFF | BASIC program area |
| $A000–$BFFF | BASIC ROM (or RAM if banked out) |
| $C000–$CFFF | RAM |
| $D000–$DFFF | I/O registers (VIC-II, SID, CIA, colour RAM) |
| $E000–$FFFF | Kernal ROM (or RAM if banked out) |
The colour RAM ($D800–$DBFF) is always RAM, even when I/O is mapped there — it can't be banked out.
Sprites
The C64 has 8 hardware sprites. Each is defined as a 64-byte bitmap (63 bytes of pixel data + 1 padding byte):
10 REM ENABLE SPRITE 0
20 POKE 53269, 1 : REM SPRITE 0 ENABLE BIT
30 POKE 2040, 13 : REM SPRITE 0 POINTER -> BLOCK 13 ($0340)
40 POKE 53248, 100 : REM SPRITE 0 X POSITION
50 POKE 53249, 100 : REM SPRITE 0 Y POSITION
60 POKE 53287, 7 : REM SPRITE 0 COLOUR = YELLOW
Sprite data lives in the VIC-II's video bank (default $0000–$3FFF). Sprite block 13 is at $0340 (13×64).
Useful Kernal routines (call via SYS or JSR)
| Address | Name | Action |
|---|---|---|
| $FFD2 | CHROUT | Print character in A |
| $FFE4 | GETIN | Get character from keyboard buffer |
| $FF81 | CINT | Initialise screen |
| $FF9C | CLALL | Close all files |
| $FFB4 | OPEN | Open a logical file |
| $FFC0 | CLOSE | Close a logical file |
Common patterns in cc65 C
#include <c64.h>
#include <conio.h>
int main(void) {
/* Hardware access via named structs */
VIC.bordercolor = COLOR_RED;
VIC.bgcolor0 = COLOR_BLACK;
/* Enable sprite 0 */
VIC.spr_ena = 0x01;
/* Screen operations */
clrscr();
gotoxy(10, 5);
cputs("Hello, C64!");
/* Joystick: CIA1 port A, active low */
while (1) {
unsigned char j = CIA1.pra;
if (!(j & 0x10)) {
/* fire button pressed */
}
}
return 0;
}