Commodore 64 (C64)

C64 Specifications

Lifespan

1982-1994

Media

Floppy disk, cassette tape, ROM cartridge

CPU 8-bit

MOS Technology 6510 (6502-compatible) @ 1.023 MHz (NTSC) / 0.985 MHz (PAL)

Memory

64 KB dynamic RAM, 1024 x 4 static color RAM

Controllers

Joystick, mouse, paddles

Best-selling games

The Last Ninja, Ghostbusters

Commodore 64

History

In 1981, MOS Technology (Commodore’s integrated circuit design subsidiary) designed graphic and audio chips for a next-generation video game console called the Ultimax, destined for release in Japan. Commodore engineers pitched Commodore CEO Jack Tramiel on a new home computer using the new chips.

Tramiel dictated that the machine should have 64 KB of random-access memory. Although 64-Kbit dynamic random-access memory chips cost over US$100 at the time, he knew that 64K DRAM prices were falling and would drop to an acceptable level before full production was reached. The product was code named the VIC-40 as the successor to the popular VIC-20. The machine used the same case, same-sized motherboard, and same Commodore BASIC 2.0 in ROM as the VIC-20.

With the help of Commodore’s underutilized chip fab, the chips were completed by the end of the year. The VIC-40 product was renamed C64, and it debuted at the 1982 CES at $595. Thanks to aggressive pricing and wide distribution, it went on to sell more than 12 million units through its lifespan.

It was primarily known as a game machine, since the 1541 disk drive’s slow performance limited its use in business and productivity applications. Few cartridge-based games were released, but low-priced cassette games were popular in Europe.

The C64 had a Microsoft-licensed BASIC built-in, but any graphics or sound operations required unfriendly PEEK and POKE commands. Commodore offered developers an SDK consisting of an assembler/monitor, sound editor (SIDMON), sprite editor (SPED), and character graphics editor (CHRED) as well as programming documentation. A market quickly developed for third-party tools such as BASIC compilers, assemblers/linkers, and programming languages.

Nowadays, homebrew C64 developers usually write games in either assembler or C, the latter using the cc65 compiler toolchain. Writing in C gives you more functionality per line of code. While it has lower performance and greater code size than a well-written assembly program, you can still write a pretty good game in C.

Memory Map

Start

End

Description

Alternate Use

$0000

$00FF

RAM, zero-page

$0100

$01FF

RAM, CPU stack

$0200

$7FFF

RAM

$8000

$9FFF

RAM

Cartridge ROM

$A000

$BFFF

RAM

BASIC ROM

$C000

$CFFF

RAM

$D000

$D3FF

RAM

VIC-II

$D400

$D7FF

RAM

SID

$D800

$DBFF

RAM

Color RAM

$DC00

$DCFF

RAM

CIA 1

$DD00

$DDFF

RAM

CIA 2

$DE00

$DEFF

RAM

I/O 1

$DF00

$DFFF

RAM

I/O 2

$E000

$FFFF

RAM

Kernal ROM

CC65 Header Files

C64

/* Color defines */
#define COLOR_BLACK             0x00
#define COLOR_WHITE             0x01
#define COLOR_RED               0x02
#define COLOR_CYAN              0x03
#define COLOR_PURPLE            0x04
#define COLOR_GREEN             0x05
#define COLOR_BLUE              0x06
#define COLOR_YELLOW            0x07
#define COLOR_ORANGE            0x08
#define COLOR_BROWN             0x09
#define COLOR_LIGHTRED          0x0A
#define COLOR_GRAY1             0x0B
#define COLOR_GRAY2             0x0C
#define COLOR_LIGHTGREEN        0x0D
#define COLOR_LIGHTBLUE         0x0E
#define COLOR_GRAY3             0x0F

/* Masks for joy_read */
#define JOY_UP_MASK             0x01
#define JOY_DOWN_MASK           0x02
#define JOY_LEFT_MASK           0x04
#define JOY_RIGHT_MASK          0x08
#define JOY_BTN_1_MASK          0x10

/* Define hardware */
#include <_vic2.h>
#define VIC     (*(struct __vic2*)0xD000)

#include <_sid.h>
#define SID     (*(struct __sid*)0xD400)

#include <_6526.h>
#define CIA1    (*(struct __6526*)0xDC00)
#define CIA2    (*(struct __6526*)0xDD00)

/* Define special memory areas */
#define COLOR_RAM       ((unsigned char*)0xD800)

VIC-II

/* 6567/8562/8564 (NTSC) 6569/8565/8566 (PAL) */
struct __vic2 {
    union {
        struct {
            unsigned char   spr0_x;         /* Sprite 0, X coordinate */
            unsigned char   spr0_y;         /* Sprite 0, Y coordinate */
            unsigned char   spr1_x;         /* Sprite 1, X coordinate */
            unsigned char   spr1_y;         /* Sprite 1, Y coordinate */
            unsigned char   spr2_x;         /* Sprite 2, X coordinate */
            unsigned char   spr2_y;         /* Sprite 2, Y coordinate */
            unsigned char   spr3_x;         /* Sprite 3, X coordinate */
            unsigned char   spr3_y;         /* Sprite 3, Y coordinate */
            unsigned char   spr4_x;         /* Sprite 4, X coordinate */
            unsigned char   spr4_y;         /* Sprite 4, Y coordinate */
            unsigned char   spr5_x;         /* Sprite 5, X coordinate */
            unsigned char   spr5_y;         /* Sprite 5, Y coordinate */
            unsigned char   spr6_x;         /* Sprite 6, X coordinate */
            unsigned char   spr6_y;         /* Sprite 6, Y coordinate */
            unsigned char   spr7_x;         /* Sprite 7, X coordinate */
            unsigned char   spr7_y;         /* Sprite 7, Y coordinate */
        };
        struct {
            unsigned char   x;              /* X coordinate */
            unsigned char   y;              /* Y coordinate */
        } spr_pos[8];
    };
    unsigned char           spr_hi_x;       /* High bits of X coordinate */
    unsigned char           ctrl1;          /* Control register 1 */
    unsigned char           rasterline;     /* Current raster line */
    union {
        struct {
            unsigned char   strobe_x;       /* Light pen, X position */
            unsigned char   strobe_y;       /* Light pen, Y position */
        };
        struct {
            unsigned char   x;              /* Light pen, X position */
            unsigned char   y;              /* Light pen, Y position */
        } strobe;
    };
    unsigned char           spr_ena;        /* Enable sprites */
    unsigned char           ctrl2;          /* Control register 2 */
    unsigned char           spr_exp_y;      /* Expand sprites in Y dir */
    unsigned char           addr;           /* Address of chargen and video ram */
    unsigned char           irr;            /* Interrupt request register */
    unsigned char           imr;            /* Interrupt mask register */
    unsigned char           spr_bg_prio;    /* Priority to background */
    unsigned char           spr_mcolor;     /* Sprite multicolor bits */
    unsigned char           spr_exp_x;      /* Expand sprites in X dir */
    unsigned char           spr_coll;       /* Sprite/sprite collision reg */
    unsigned char           spr_bg_coll;    /* Sprite/background collision reg */
    unsigned char           bordercolor;    /* Border color */
    union {
        struct {
            unsigned char   bgcolor0;       /* Background color 0 */
            unsigned char   bgcolor1;       /* Background color 1 */
            unsigned char   bgcolor2;       /* Background color 2 */
            unsigned char   bgcolor3;       /* Background color 3 */
        };
        unsigned char       bgcolor[4];     /* Background colors */
    };
    union {
        struct {
            unsigned char   spr_mcolor0;    /* Color 0 for multicolor sprites */
            unsigned char   spr_mcolor1;    /* Color 1 for multicolor sprites */
        };
        /* spr_color is already used ... */
        unsigned char       spr_mcolors[2]; /* Color for multicolor sprites */
    };
    union {
        struct {
            unsigned char   spr0_color;     /* Color sprite 0 */
            unsigned char   spr1_color;     /* Color sprite 1 */
            unsigned char   spr2_color;     /* Color sprite 2 */
            unsigned char   spr3_color;     /* Color sprite 3 */
            unsigned char   spr4_color;     /* Color sprite 4 */
            unsigned char   spr5_color;     /* Color sprite 5 */
            unsigned char   spr6_color;     /* Color sprite 6 */
            unsigned char   spr7_color;     /* Color sprite 7 */
        };
        unsigned char       spr_color[8];   /* Colors for the sprites */
    };

    /* The following ones are only valid in the C128: */
    unsigned char           x_kbd;          /* Additional keyboard lines */
    unsigned char           clock;          /* Clock switch bit */
};

SID

/* 6581/8580 SID chip */
struct __sid_voice {
    unsigned            freq;           /* Frequency */
    unsigned            pw;             /* Pulse width */
    unsigned char       ctrl;           /* Control register */
    unsigned char       ad;             /* Attack/decay */
    unsigned char       sr;             /* Sustain/release */
};
struct __sid {
    struct __sid_voice  v1;             /* Voice 1 */
    struct __sid_voice  v2;             /* Voice 2 */
    struct __sid_voice  v3;             /* Voice 3 */
    unsigned            flt_freq;       /* Filter frequency */
    unsigned char       flt_ctrl;       /* Filter control register */
    unsigned char       amp;            /* Amplitude */
    unsigned char       ad1;            /* A/D converter 1 */
    unsigned char       ad2;            /* A/D converter 2 */
    unsigned char       noise;          /* Noise generator */
    unsigned char       read3;          /* Value of voice 3 */
};

CIA

/* 6526 CIA chip */
struct __6526 {
    unsigned char       pra;            /* Port register A */
    unsigned char       prb;            /* Port register B */
    unsigned char       ddra;           /* Data direction register A */
    unsigned char       ddrb;           /* Data direction register B */
    unsigned char       ta_lo;          /* Timer A, low byte */
    unsigned char       ta_hi;          /* Timer A, high byte */
    unsigned char       tb_lo;          /* Timer B, low byte */
    unsigned char       tb_hi;          /* Timer B, high byte */
    unsigned char       tod_10;         /* TOD, 1/10 sec. */
    unsigned char       tod_sec;        /* TOD, seconds */
    unsigned char       tod_min;        /* TOD, minutes */
    unsigned char       tod_hour;       /* TOD, hours */
    unsigned char       sdr;            /* Serial data register */
    unsigned char       icr;            /* Interrupt control register */
    unsigned char       cra;            /* Control register A */
    unsigned char       crb;            /* Control register B */
};

Comments