What it is
The VIC (Video Interface Controller) is the system's graphics block. It reads character, color and bitmap data from video RAM and turns it into a complete video signal with its own horizontal and vertical sync — HDMI/DVI on the Tang Primer 20K, VGA on the PIX16.
What it does
Text mode
40×25 characters, each 2× scaled (16×16 screen pixels). Character patterns live in the
char_rom (8×8 pixels, bit 7 = reverse video). Each cell has its own
foreground and background color from color RAM at $8400, packed as
bg[7:4] | fg[3:0]. The 16-color palette is a Pepto-style C64 RGB565
lookup.
Bitmap modes
- 320×200 1-bpp — legacy bitmap, 2× scaled to 640×400, 16 colors per 8×8 cell.
- 160×100 RGB332 — 256 colors, one byte per pixel, 4× scaled to 640×400.
- 180×120 RGB222 — 64 colors packed (4 pixels in 3 bytes), 3× scaled to 540×360.
The 16 KB framebuffer is exposed through an 8 KB CPU window at $6000–$7FFF;
a MODE bit selects the bank. The control register $9000 switches
between modes.
Bus stealing — the shared bus
VIC and CPU share a single-port video memory. During each horizontal blanking interval the
VIC prefetches the next display line and holds the CPU via the RDY pin.
The overhead is small: ~4.8 % in text mode, with a worst case of
9.4 % for RGB332. CPU writes to video RAM are never lost — a pending write is
buffered and committed on the first free clock.
Color registers
| Address | Register | Function |
|---|---|---|
| $9000 | MODE | bit 0 bitmap, bit 1 RGB332, bit 2 bank, bit 3 RGB222 |
| $9003 | TEXT_COLOR | foreground color 0–15 |
| $9004 | BG_COLOR | background color 0–15 |
From BASIC
REM bitmap mode on, set a pixel POKE 36864, 1 A=24576+Y*40+INT(X/8) POKE A, PEEK(A) OR 2^(7-(X AND 7)) POKE 36864, 0 : REM back to text