<< Back to contents.

CharPad 2.3 User Manual - Subchrist Software, 2019.

VIC-II Register Map.

The VIC-II graphics chip has 47 (8-bit) registers that can be collectively switched in or out of the Commodore 64's address space but they will always appear between addresses $d000 and $d02e when switched in, these addresses are included in the register map below.

Reg# |Addr Hex |Addr Dec |Description...
0 $d000 53248 Sprite 0 X-position.
1 $d001 53249 Sprite 0 Y-position.
2 $d002 53250 Sprite 1 X-position.
3 $d003 53251 Sprite 1 Y-position.
4 $d004 53252 Sprite 2 X-position.
5 $d005 53253 Sprite 2 Y-position.
6 $d006 53254 Sprite 3 X-position.
7 $d007 53255 Sprite 3 Y-position.
8 $d008 53256 Sprite 4 X-position.
9 $d009 53257 Sprite 4 Y-position.
10 $d00a 53258 Sprite 5 X-position.
11 $d00b 53259 Sprite 5 Y-position.
12 $d00c 53260 Sprite 6 X-position.
13 $d00d 53261 Sprite 6 Y-position.
14 $d00e 53262 Sprite 7 X-position.
15 $d00f 53263 Sprite 7 Y-position.
16 $d010 53264 Sprites 0-7 X-position MSb's, one bit per sprite.
 
17 $d011 53265 Control register 1 (default = X0011011)...
  Bit 7 - Raster line (Bit 8), read current, write for IRQ.
  Bit 6 - Extended colour text mode (1 = Enabled).
  Bit 5 - Bitmap mode (1 = Enabled).
  Bit 4 - Blank screen to border colour (0 = Blank).
  Bit 3 - Select 24/25 row text display (1 = 25 Rows).
  Bit 2 - Screen scroll Y-offset (Bit 2).
  Bit 1 - Screen scroll Y-offset (Bit 1).
  Bit 0 - Screen scroll Y-offset (Bit 0).
 
18 $d012 53266 Raster line (Bits 0-7), read current, write for IRQ.
19 $d013 53267 Light-pen latch X-position.
20 $d014 53268 Light-pen latch Y-position.
21 $d015 53269 Sprite display enable (one bit per sprite, 1 = Enabled).
 
22 $d016 53270 Control register 2 (default = 11001000)...
  Bit 7 - NC
  Bit 6 - NC
  Bit 5 - RES: ALWAYS SET THIS BIT TO 0!.
  Bit 4 - Screen multi-colour mode. (1 = Enabled).
  Bit 3 - Select 38/40 column text display (1 = 40 columns).
  Bit 2 - Screen scroll X-offset (Bit 2).
  Bit 1 - Screen scroll X-offset (Bit 1).
  Bit 0 - Screen scroll X-offset (Bit 0).
 
23 $d017 53271 Sprites 0-7 expand 2x vertical (one bit per sprite, 1 = Enabled).
 
24 $d018 53272 Memory pointer register (default = 00010101)...
  Bit 7 - Video matrix (1KB) base address (Bit 3).
  Bit 6 - Video matrix (1KB) base address (Bit 2).
  Bit 5 - Video matrix (1KB) base address (Bit 1).
  Bit 4 - Video matrix (1KB) base address (Bit 0).
  Bit 3 - Character set (2KB) base address (Bit 2).
  Bit 2 - Character set (2KB) base address (Bit 1).
  Bit 1 - Character set (2KB) base address (Bit 0).
  Bit 0 - NC
 
  nb. In bitmap mode, bit 3 selects the upper or lower 8KB for use, bits 1 and 2 are ignored).
 
25 $d019 53273 Interrupt flag register (1 = IRQ occurred)...
  Bit 7 - Set on any enabled VIC IRQ condition.
  Bit 6 - NC
  Bit 5 - NC
  Bit 4 - NC
  Bit 3 - IRQ: Light-pen.
  Bit 2 - IRQ: Sprite-to-sprite collision.
  Bit 1 - IRQ: Sprite-to-character collision.
  Bit 0 - IRQ: Raster beam reached written line.
 
  nb. Read to determine IRQ status/sources, write (1's) to acknowledge IRQ(s).
 
26 $d01a 53274 Interrupt mask register. (1 = IRQ enabled)...
  Bit 7 - NC
  Bit 6 - NC
  Bit 5 - NC
  Bit 4 - NC
  Bit 3 - IRQ: Light-pen.
  Bit 2 - IRQ: Sprite-to-sprite collision.
  Bit 1 - IRQ: Sprite-to-character collision.
  Bit 0 - IRQ: Raster line comparison.
 
  nb. Write (1's) to enable IRQ source(s).
 
27 $d01b 53275 Sprite to background display priority (one bit per sprite, 0 = Sprite has priority).
28 $d01c 53276 Sprites 0-7 multi-colour mode select (one bit per sprite, 1 = Multi-colour).
29 $d01d 53277 Sprites 0-7 expand 2x horizontal (one bit per sprite, 1 = Expand).
30 $d01e 53278 Sprite-to-sprite collision detection (one bit per sprite, cleared on reading).
31 $d01f 53279 Sprite-to-character collision detection (one bit per sprite, cleared on reading).
32 $d020 53280 Screen border colour (0-15).
33 $d021 53281 Background colour 0 (0-15, Screen colour).
34 $d022 53282 Background colour 1 (0-15, Character multi-colour 1).
35 $d023 53283 Background colour 2 (0-15, Character multi-colour 2).
36 $d024 53284 Background colour 3 (Only used in 'Extended-colour' text mode).
37 $d025 53285 Sprite multi-colour 1 (0-15).
38 $d026 53286 Sprite multi-colour 2 (0-15).
39 $d027 53287 Sprite 0 colour (0-15).
40 $d028 53288 Sprite 1 colour (0-15).
41 $d029 53289 Sprite 2 colour (0-15).
42 $d02a 53290 Sprite 3 colour (0-15).
43 $d02b 53291 Sprite 4 colour (0-15).
44 $d02c 53292 Sprite 5 colour (0-15).
45 $d02d 53293 Sprite 6 colour (0-15).
46 $d02e 53294 Sprite 7 colour (0-15).

Notes...

Bits marked NC are not connected and will always read as set (1).

All colour registers only have their low nybbles (4 bits) connected, the bits of their upper nybbles will always read as set (1).

The 24/25 row mode switch ($d011, bit 3) is something of a misnomer, there are always 25 rows in the video matrix, this switch just toggles the visual expansion of the top and bottom borders, "24 row mode" is usually used to conceal the sudden appearance of fresh data when scrolling the screen vertically.

The 38/40 column mode switch ($d016, bit 3) is something of a misnomer, there are always 40 columns in the video matrix, this switch just toggles the visual expansion of the left and right borders, "38 column mode" is usually used to conceal the sudden appearance of fresh data when scrolling the screen horizontally.

The VIC-II can only access 16KB of memory (it only has 14 address lines), this can be deduced by examining the memory pointer register (reg #24, $d018) which only provides a 4-bit pointer (values 0-15) to specify a 1KB video matrix, a 3-bit pointer (values 0-7) to specify a 2KB character set and a 1-bit pointer (0 or 1) to specify an 8KB bitmap image.

The Commodore 64 (with it's 64KB memory) solves the above issue by providing two additional address bits in CIA chip #2, using these, the VIC-II can be made to "see" any one (but only one) of the four possible 16KB quarters ("video banks") of the available 64KB RAM.

Sprite images (63 bytes each) are selected using the Sprite Pointers, these are not available as on-chip registers, instead they are always located in the last 8 bytes of the active 1024 byte video matrix (which itself requires only 1000 bytes, 40x25 cells).

ie. If the VIC-II is using video bank 0 ($0000-$3fff, 16KB) and the video matrix pointer ($d018, upper nybble) is also set to 0 ($0000-$03ff, 1KB) then the 8 Sprite Pointers will be available at addresses $03f8-$03ff.

Although each sprite image requires only 63 bytes, each image's data should always be aligned on a 64 byte boundary, as each Sprite Pointer stores an 8-bit value (0-255) then we have space for a possible 256 sprite images in a 16KB video bank (256 * 64).

When the VIC-II is switched in to the Commodore 64's address space (as is normal) it's 47 registers appear from $d000 to $d02e but they are also mirrored every 64 bytes up to $d3ff, a total of 16 times across this 1024 byte (1KB) memory area as listed below.

nb. After each range of 47 addresses follows 17 disconnected addresses (64 total) that will always read $ff (ie. $d02f-$d03f).

$d000 - $d02e (the VIC-II registers are normally accessed using this address range).
$d040 - $d06e
$d080 - $d0ae
$d0c0 - $d0ee
$d100 - $d12e
$d140 - $d16e
$d180 - $d1ae
$d1c0 - $d1ee
$d200 - $d22e
$d240 - $d26e
$d280 - $d2ae
$d2c0 - $d2ee
$d300 - $d32e
$d340 - $d36e
$d380 - $d3ae
$d3c0 - $d3ee

We can say then that the chip has a 1KB (1024 byte) footprint despite only having 47 registers.