VIC-II Bank Reference & Memory Map
Even though RIFT64 frees you from writing raw assembly, your backend program still needs to understand the structure and constraints of the C64's VIC-II (Video Interface Chip). Use this memory map reference to design graphics offsets, custom character sets, bitmaps, and sprites inside the four 16KB hardware chunks.
1. Visual 64KB System Memory Map
This visual representation illustrates the entire 64KB RAM layout of the Commodore 64, ordered from high-memory (top) to low-memory (bottom), color-coded by architecture layers:
2. Active 16KB VIC-II Banks
The VIC-II chip can only access 16KB of RAM at once. The active bank is chosen using CIA 2 Register `$DD00` (bits 0 and 1):
| Bank ID | Memory Range | `$DD00` Bit Layout | Hex Value | Default Usage & Layout Constraints |
|---|---|---|---|---|
| Bank 0 | `$0000 - $3FFF` | `%xxxxxx11` | `$03` | System default on boot. Contains default character ROM mapping. |
| Bank 1 | `$4000 - $7FFF` | `%xxxxxx10` | `$02` | Completely free RAM block. Excellent for custom graphics & bitmapped screens. |
| Bank 2 | `$8000 - $BFFF` | `%xxxxxx01` | `$01` | Contains character generator ROM mirror ($9000-$9FFF). |
| Bank 3 | `$C000 - $FFFF` | `%xxxxxx00` | `$00` | Free RAM block. Common destination for assembly programs and graphics. |
3. Internal Offset Pointers (`$D018`)
VIC-II Register `$D018` defines where Screen Character RAM and Character Graphics RAM reside *within* the currently active 16KB bank:
- High 4 Bits (7-4): Selects Screen Character RAM location (in steps of 1KB relative to the bank's base address).
- Low 4 Bits (3-1): Selects custom Character Graphics/Font RAM location (in steps of 2KB relative to the bank's base address).
4. Visual 16KB Bank Memory Allocations
Below is a comprehensive textual breakdown of how the memory layout is segmented inside the four physical 16KB VIC-II banks:
Bank 0 ($0000 - $3FFF) - System Default Bank
Bank 1 ($4000 - $7FFF) - High-Performance Free RAM
Bank 2 ($8000 - $BFFF) - System ROM Bank
Bank 3 ($C000 - $FFFF) - Code & Sprite Space
- From the CPU's perspective, this space contains active hardware I/O registers (VIC-II, SID, CIAs) and Color RAM ($D800-$DBE7).
- From the VIC-II's perspective, it sees raw RAM instead of registers, but reads Color RAM in a parallel dedicated data path to assign individual character colors!
5. VIC-II Hardware Graphics Modes
- Standard Character Mode: Set `$D011` to `$1B` (BMM=0) and `$D016` to `$08` (MCM=0). Provides 40x25 character grid, 2 colors per cell (Bg & Fg).
- Multicolor Character Mode: Set `$D011` to `$1B` and `$D016` to `$18` (MCM=1). Character cells now use multicolor decoding, providing 4 colors per cell (fat pixels).
- Standard Bitmap Mode: Set `$D011` to `$3B` (BMM=1) and `$D016` to `$08`. High resolution 320x200 canvas, with 2 colors per 8x8 block.
- Multicolor Bitmap Mode: Set `$D011` to `$3B` (BMM=1) and `$D016` to `$18` (MCM=1). Multicolor 160x200 resolution, allowing up to 4 colors per 8x8 block.
6. Sprite Memory Structure (64-Byte Grid)
Each C64 hardware sprite is represented in memory as exactly 64 bytes. The pixel layout is 24 pixels wide by 21 pixels high, which translates to 3 bytes per horizontal line over 21 lines:
Line 0: [Byte 0: %00111100] [Byte 1: %01111110] [Byte 2: %00111100] (24 Pixels)
Line 1: [Byte 3: %01111110] [Byte 4: %11111111] [Byte 5: %01111110] (24 Pixels)
Line 2: [Byte 6: %11111111] [Byte 7: %11111111] [Byte 8: %11111111] (24 Pixels)
...
Line 20: [Byte 60] [Byte 61] [Byte 62] (24 Pixels)
Padding: [Byte 63: Unused / Stardust Padding Byte]
When in Standard High-Resolution mode (1 color), each active bit (1) represents a pixel drawn in the sprite's individual color register. In Multicolor mode (lower resolution), bits are parsed in pairs (00=Bg, 01=Sprite Multicolor 1, 10=Sprite Color, 11=Sprite Multicolor 2), doubling the pixel width.
7. Custom Character Set (8-Byte Font Grid)
The C64's custom character set glyphs are stored in memory as a series of 8-byte blocks. Each character in an 8x8 font grid is represented by exactly 8 consecutive bytes, where each byte dictates one horizontal pixel row:
Row 0: . . X X X . . . Binary: %00111000 → Hex: $38 (Row Value)
Row 1: . X . . . X . . Binary: %01000100 → Hex: $44 (Row Value)
Row 2: X . . . . . X . Binary: %10000010 → Hex: $82 (Row Value)
Row 3: X X X X X X X . Binary: %11111110 → Hex: $FE (Row Value)
Row 4: X . . . . . X . Binary: %10000010 → Hex: $82 (Row Value)
Row 5: X . . . . . X . Binary: %10000010 → Hex: $82 (Row Value)
Row 6: X . . . . . X . Binary: %10000010 → Hex: $82 (Row Value)
Row 7: . . . . . . . . Binary: %00000000 → Hex: $00 (Row Value)
To draw the letter "A" shown above, you stream the 8 hex bytes ($38, $44, $82, $FE, $82, $82, $82, $00) directly into your C64's Character Generator offset (at any 2KB boundary relative to your selected VIC bank) using client.StoreMemoryAsync()!
8. Official Commodore 64 Color Palette
Use these official C64 palette color codes (0-15 / $00-$0F) when sending color commands (like `K` and `Q` or sprite register values `CC`).