Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

10KB


name: graphics-vic2 description: > Use this skill for all VIC-II graphics programming on the C64. Covers text modes, bitmap modes, multicolor modes, sprites, raster interrupts, smooth scrolling, color RAM, and the VIC-II register set. Sources: The Anatomy of the C64, COMPUTE!‘s Mapping the C64, The Advanced ML Book.

VIC-II Graphics Programming

VIC-II Chip Overview

The MOS 6567 (NTSC) / MOS 6569 (PAL) Video Interface Chip II is the C64's graphics processor. It resides at addresses $D000–$D3FF (53248–54271) when I/O is banked in.

Key capabilities:

  • 40×25 character text display (standard or multicolor)
  • 320×200 high-resolution bitmap (or 160×200 multicolor bitmap)
  • 8 independent hardware sprites (24×21 each, or 12×21 multicolor)
  • 16 colors
  • Programmable raster interrupt
  • Horizontal and vertical fine scrolling (8 pixels each)
  • Background color in multiple modes (up to 4 simultaneously)

VIC-II Register Map ($D000–$D02E)

Sprite Position Registers

Address Decimal Register Description
$D000 53248 SP0X Sprite 0 X position
$D001 53249 SP0Y Sprite 0 Y position
$D002 53250 SP1X Sprite 1 X position
$D003 53251 SP1Y Sprite 1 Y position
$D004 53252 SP2X Sprite 2 X position
$D005 53253 SP2Y Sprite 2 Y position
$D006 53254 SP3X Sprite 3 X position
$D007 53255 SP3Y Sprite 3 Y position
$D008 53256 SP4X Sprite 4 X position
$D009 53257 SP4Y Sprite 4 Y position
$D00A 53258 SP5X Sprite 5 X position
$D00B 53259 SP5Y Sprite 5 Y position
$D00C 53260 SP6X Sprite 6 X position
$D00D 53261 SP6Y Sprite 6 Y position
$D00E 53262 SP7X Sprite 7 X position
$D00F 53263 SP7Y Sprite 7 Y position
$D010 53264 MSIGX Most significant bits of sprites’ X positions (bit N = sprite N)

Control Registers

Address Decimal Register Description
$D011 53265 SCROLY Vertical control register
$D012 53266 RASTER Raster counter / raster IRQ compare
$D013 53267 LPENX Light pen X (read-only)
$D014 53268 LPENY Light pen Y (read-only)
$D015 53269 SPENA Sprite enable (bit N = sprite N)
$D016 53270 SCROLX Horizontal control register
$D017 53271 YXPAND Sprite Y-expansion (bit N = sprite N)
$D018 53272 VMCSB VIC-II memory control
$D019 53273 VICIRQ Interrupt register (read/clear)
$D01A 53274 IRQMSK Interrupt enable mask
$D01B 53275 SPBGPR Sprite-background priority
$D01C 53276 SPMC Sprite multicolor enable
$D01D 53277 XXPAND Sprite X-expansion
$D01E 53278 SPSPCL Sprite-sprite collision (clears on read)
$D01F 53279 SPBGCL Sprite-background collision (clears on read)
$D020 53280 EXTCOL Border color
$D021 53281 BGCOL0 Background color 0
$D022 53282 BGCOL1 Background color 1 (extended/multicolor)
$D023 53283 BGCOL2 Background color 2 (extended/multicolor)
$D024 53284 BGCOL3 Background color 3 (extended color text only)
$D025 53285 SPMC0 Sprite multicolor register 0
$D026 53286 SPMC1 Sprite multicolor register 1
$D027 53287 SP0COL Sprite 0 color
$D028 53288 SP1COL Sprite 1 color
$D029 53289 SP2COL Sprite 2 color
$D02A 53290 SP3COL Sprite 3 color
$D02B 53291 SP4COL Sprite 4 color
$D02C 53292 SP5COL Sprite 5 color
$D02D 53293 SP6COL Sprite 6 color
$D02E 53294 SP7COL Sprite 7 color

$D011 — SCROLY: Vertical Control Register

Bit 7  RST8  — Bit 8 of raster compare (use with $D012 for lines > 255)
Bit 6  ECM   — Extended Color Mode (1=on)
Bit 5  BMM   — Bitmap Mode (1=on, 0=text mode)
Bit 4  DEN   — Display Enable (1=display on)
Bit 3  RSEL  — Row Select: 1=25 rows, 0=24 rows (borders shown)
Bit 2-0 YSCL — Fine vertical scroll (0-7)

Default value: $1B = %00011011 (display on, 25 rows, scroll=3)

$D016 — SCROLX: Horizontal Control Register

Bit 7  (unused)
Bit 6  (unused)  
Bit 5  RES   — Always set to 1 for normal operation
Bit 4  MCM   — Multicolor Mode (1=on)
Bit 3  CSEL  — Column Select: 1=40 columns, 0=38 columns
Bit 2-0 XSCL — Fine horizontal scroll (0-7)

Default value: $C8 = %11001000 (40 cols, scroll=0)

$D018 — VMCSB: VIC-II Memory Control

Bits 7-4  VM   — Video matrix base address (within current VIC-II bank)
Bits 3-1  CB   — Character base address (within current VIC-II bank)
Bit 0     (unused)

Video matrix address = bits[7:4] × $0400 within the VIC-II bank Character base = bits[3:1] × $0800 within the VIC-II bank

$D018 Value Screen RAM Character Set
$10 (default) $0400 $1000 (ROM chars via mirror)
$14 $0400 $1800 (ROM chars, inverted)
$18 $0400 $2000 (user char at $2000)
$15 $0400 $1400 (user chars at $1400 in Bank 0)

Display Modes

1. Standard Text Mode (default)

  • 40×25 characters, 8×8 pixels each = 320×200 pixels
  • Screen RAM at $0400: each byte = character code (0-255)
  • Color RAM at $D800: each byte = foreground color (bits 0-3)
  • Character set at $D000 (character ROM, 256 chars × 8 bytes = 2KB)

2. Multicolor Text Mode ($D016 bit 4 = 1)

  • Characters with color RAM value ≥ 8 use 4 colors, 2 pixels per bit
  • Characters with color RAM value 0-7 use standard 2-color mode
  • Colors: BG0 ($D021), BG1 ($D022), BG2 ($D023), color RAM value AND 7

3. Extended Background Color Mode ($D011 bit 6 = 1)

  • Only 64 character codes available (bits 6-7 select BG color)
  • Four background colors: $D021–$D024
  • Cannot be combined with bitmap or multicolor modes

4. Standard Bitmap Mode ($D011 bit 5 = 1)

  • 320×200 pixels, 8000 bytes of bitmap data
  • Each 8×8 cell has its own 2-color pair stored in screen RAM
  • Bitmap data location: bit 3 of $D018 × $2000 within VIC-II bank
    • $D018 = $18 → bitmap at $2000 (if screen at $0400)
    • $D018 = $1A → bitmap at $4000 in Bank 0? No — bitmap bit is bit3 of high nybble
  • Screen RAM holds color pairs: high nybble = “0” pixel color, low nybble = “1” pixel color

5. Multicolor Bitmap Mode ($D011 bit 5 = 1, $D016 bit 4 = 1)

  • 160×200 pixels, 4 colors per 4×8 cell
  • Colors: $D021 (global), $D022 (global), $D023 (global), color RAM per cell

Sprite Programming

Sprite Specifications

  • Size: 24×21 pixels (hi-res) or 12×21 pixels (multicolor)
  • Data: 63 bytes per sprite (3 bytes × 21 rows), stored in 64-byte blocks
  • Maximum 8 sprites on screen simultaneously
  • Hardware X expansion (2× wide) and Y expansion (2× tall) per sprite

Setting Up a Sprite

Step 1 — Define sprite shape data (63 bytes in a 64-byte block):

' Write sprite data to block 13 ($0340-$037F)
FOR B = 0 TO 62 : POKE 832+B, 0 : NEXT  ' clear first
' Each row is 3 bytes (24 bits = 24 horizontal pixels)
POKE 832, 255 : POKE 833, 255 : POKE 834, 255   ' row 0: solid line

Step 2 — Point sprite pointer to the block:

POKE 2040, 13    ' sprite 0 → block 13 ($0340)
' Sprite pointer addresses: 2040-2047 = sprites 0-7
' (at default screen RAM $0400 + $03F8-$03FF = $07F8-$07FF)

Step 3 — Set sprite position:

POKE 53248, 160   ' sprite 0 X position
POKE 53249, 100   ' sprite 0 Y position

Step 4 — Set color and enable:

POKE 53287, 1    ' sprite 0 color = white (1)
POKE 53269, PEEK(53269) OR 1   ' enable sprite 0 (bit 0)

Sprite Screen Coordinates

  • Valid X range: 0-335 (use $D010 for X > 255)
  • Valid Y range: 0-247
  • Sprite appears at top-left of screen when X≈24, Y≈50 (NTSC)
  • Top-left of visible area: approximately X=24, Y=50

Sprite X > 255 (using $D010)

' Set sprite 0 X to 300 (= 256 + 44)
POKE 53248, 44     ' low 8 bits
POKE 53264, PEEK(53264) OR 1   ' set MSB for sprite 0

Sprite Priority ($D01B)

POKE 53275, 1   ' sprite 0 behind background characters
POKE 53275, 0   ' sprite 0 in front of background (default)

Collision Detection

' Read and clear sprite-sprite collisions
C = PEEK(53278)   ' bit N set if sprite N collided with another sprite
' Read and clear sprite-background collisions
C = PEEK(53279)   ' bit N set if sprite N hit a background pixel

Colors

Code Color Code Color
0 Black 8 Orange
1 White 9 Brown
2 Red 10 Light Red
3 Cyan 11 Dark Grey
4 Purple 12 Grey
5 Green 13 Light Green
6 Blue 14 Light Blue
7 Yellow 15 Light Grey

Raster Interrupts

The VIC-II generates an interrupt when the raster beam reaches the line stored in $D012 (plus bit 8 in $D011 bit 7).

NTSC: 262 lines (0-261), PAL: 312 lines (0-311). Visible screen starts around line 50.

Setting Up a Raster IRQ

        SEI
        LDA #<RasterIRQ
        STA $0314           ; IRQ vector low
        LDA #>RasterIRQ
        STA $0315           ; IRQ vector high
        LDA #50             ; trigger at line 50
        STA $D012
        LDA $D011
        AND #$7F            ; clear bit 8 of raster
        STA $D011
        LDA #$01            ; enable raster IRQ
        STA $D01A
        CLI

RasterIRQ:
        LDA $D019           ; read IRQ status
        STA $D019           ; acknowledge (write-back clears)
        ; ... your raster effect code ...
        JMP $EA31           ; chain to normal IRQ handler

Double-Buffer Raster Trick (for stable raster)

; After acknowledging the interrupt, wait for the specific raster line
WAIT    LDA $D012
        CMP #100            ; target line
        BNE WAIT
        ; Now change colors etc.

Smooth Scrolling

Vertical Scroll (software scroll)

  1. Change $D011 bits 0-2 (YSCL) from 7 down to 0 each frame
  2. When YSCL reaches 0, physically shift screen RAM up one row, reset YSCL=7

Horizontal Scroll (software scroll)

  1. Change $D016 bits 0-2 (XSCL) from 7 down to 0 each frame
  2. When XSCL reaches 0, shift all characters in each screen row left one, reset XSCL=7
' Smooth vertical scroll - change scroll register each frame
FOR S = 7 TO 0 STEP -1
    POKE 53265, (PEEK(53265) AND 248) OR S
    FOR W = 1 TO 100 : NEXT  ' wait
NEXT S
' Then scroll screen RAM and reset to 7

Powered by TurnKey Linux.