vdcmaniac: Reviving the Commodore 128 VDC's Rarest Bitmap Modes
vdcmaniac title screen, raster bar underneath

vdcmaniac: Reviving the Commodore 128 VDC's Rarest Bitmap Modes

August 22, 2026
C128VDCdemoretroOscar646502

vdcmaniac is a Commodore 128 demo built entirely around the VDC -- the 8563/8568 80-column video chip most C128 owners only ever saw render text. Underneath its familiar 80x25 display sits up to 64 KB of dedicated video RAM and a set of bitmap modes far beyond what the chip is normally asked to do: colour resolutions up to 800x600, interlaced modes doubling vertical detail, and addressing tricks the chip's own documentation barely touches. This project is a from-scratch C rewrite of a 2012 demo that first put those modes on screen, plus one real hardware mystery that took a purpose-built diagnostic test to solve.

The VDC and VDC Mode Mania

VDC Mode Mania, released in 2012 by Tokra and Mike of Akronyme Analogiker, was a BASIC-driven slideshow showing off the VDC's rare 64KB-VDC-RAM graphics modes -- interlaced and non-interlaced, colour and monochrome, at resolutions far beyond the VIC-II's usual 320x200. It was extended twice since, up to a 960x540 monochrome mode in 2023. The original demo, its BASIC source and its own PC-side image converters are still available on CSDb.

vdcmaniac is not a port of that codebase. It targets the same family of modes -- the set VDC Mode Mania first demonstrated -- but everything driving them is new: the Oscar64 C cross-compiler in place of interpreted BASIC, Krill's fastloader with on-the-fly TSCrunch decompression for every asset, a from-scratch VDC mode/register library, and its own Python-based picture converter. Every showcase picture is freshly sourced too -- public-domain paintings and CC-licensed photographs, each credited individually, none of the original's own converted images.

Eight Modes, One Chip

The Great Wave off Kanagawa, rendered in VDC-HFLI colour-cell mode

The showcase runs through the VDC's full rare-mode roster: VDC-FLI and VDC-HFLI (480x252 and 640x400, non-interlaced colour), VDC-IHFLI and VDC-ITFLI (640x480 and 640x576, interlaced colour), VDC-IMONO and VDC-IM800 (720x700 and 800x600, interlaced monochrome), and a VDC Spectrum mode decoding real ZX Spectrum .scr screen dumps into the VDC's own 8x8 flat colour-attribute cells. Each colour mode has its own colour-cell granularity -- from FLI's coarse 8x1 cells up to ITFLI's 8x3 -- and its own dithering strategy in the picture converter to make the most of it.

Passiflora caerulea, rendered in VDC-IHFLI interlaced colour mode

Two procedural effects round out the picture showcases: a sine-table plasma and a colour-cycling bitmap, both direct C translations of the same technique described in a Turbo Rascal Syntax Error demo-coding writeup, re-targeted to the VDC's own palette and bitmap layout.

A Register That Lied

The most demanding section to build was VDC-SCROLL -- three scripted auto-play sections panning through bitmaps larger than the 640x200 display window. A vertical pan turned out to be simple: the stored bitmap's row stride already matches the display's, so stepping through it is just a sequence of DISP_ADDR writes. A horizontal pan through a bitmap wider than the display is a different problem, and it took three attempts to solve properly.

The first attempt reused VDC-FLI's own raster-synced CSIZE toggle trick to fake per-scanline addressing. It rendered correctly in short bursts but never stabilised -- intermittent garbling with no isolable root cause. The second dropped hardware addressing tricks entirely in favour of a CPU-driven shift-and-refill scheme, redesigned twice to eliminate real corruption bugs, and ended up correct but too slow to ship: every crossing needed a full 80-byte-per-row rewrite to VDC memory, and the VDC's own ready-poll timing put a hard floor under that no amount of software optimisation could clear.

The third attempt used VDC register 27 (ROWINC) directly. The C128 Programmer's Reference Guide is explicit that R27 increments the bitmap address on every scanline, not once per character row -- exactly the per-scanline granularity the first two attempts had worked around rather than used. A small diagnostic test confirmed it worked in VICE and in z64k, an independent second VDC emulator. On real Commodore 128D hardware, the same test produced a diagonally sheared, unusable pattern.

Nine Dragons, the artwork used for the VDC-PANORAMA horizontal pan

That discrepancy led to a genuine rabbit hole: a community forum thread describing an undocumented VDC silicon quirk where R27 values above zero drift into the attribute plane's own address generator partway through the second bitmap row, plus a z64k changelog entry citing the same thread and adding a partial emulation fix for it. It read like a promising match. It also turned out to be the wrong answer.

A wider diagnostic -- sweeping nine different R27 values against a barcode test pattern, with a same-mode control run at R27=0 -- isolated the actual cause: this project's own mode-switching code wrote R27 as part of a mode's register table, applied before DISP_ADDR was set to its real value rather than after. The VDC briefly saw a non-zero row increment layered on top of a throwaway zero address, and that transient state corrupted internal addressing that stayed wrong even once both registers were later set correctly. Moving the R27 write to strictly after the real DISP_ADDR fixed every case immediately -- no silicon quirk, no emulator gap, a self-inflicted ordering bug in code that had never actually exercised R27 correctly to begin with. The VDC-SCROLL family shipped shortly after: a vertical pan, a horizontal pan using the now-understood R27 mechanism, and a combined diagonal pan touring a bitmap both wider and taller than the display.

Fastloading and Raster Timing

Every asset -- pictures, the SID tune, the demo's own code overlays -- loads through Krill's fastloader with TSCrunch decompression baked in, rather than shipping raw files on disk. Raster-bar effects and the menu's own highlight sweep run on a custom raster-IRQ trampoline installed directly on the CPU's hardware interrupt vector, built on a CIA-timer VDC raster-sync routine from Peter Hulstede's VDC-Intromaker: Perfektes Rasterzeilen-Timing, published in 64'er Sonderheft 95 -- a C translation of a technique originally written for exactly this chip, decades before this project existed.

That calibration routine holds interrupts off for roughly 1.3 seconds to measure real VDC timing against the CIA -- audible as a short music pause wherever it ran. Early on it ran once per mode transition, recalibrating on every return to the main menu. Reducing it to a single call, at hardware-detection time, removed the audible pause entirely and, measured over extended real-hardware sessions, held up more reliably than the more frequent recalibration it replaced.

Credits

  • Code: Xander Mol
  • Original inspiration: VDC Mode Mania by Tokra and Mike, Akronyme Analogiker (2012)
  • Raster-sync technique: Peter Hulstede, VDC-Intromaker: Perfektes Rasterzeilen-Timing, 64'er Sonderheft 95
  • Fastloader: Krill's Loader, with TSCrunch compression
  • Compiler: Oscar64 by drmortalwombat
  • Pictures: public-domain paintings/prints and CC-licensed photographs, individually credited in the repository; three ZX Spectrum demoscene graphics credited to their own sceners

Licensed under the GNU General Public License v3.0. Full picture and asset attributions are in the repository's own credit block.

Sources and More Information

vdcmaniac repository -- source code, VDC register/mode reference, raster library and fastloader documentation, and the v1.0.0 release: github.com/xahmol/vdcmaniac

VDC Mode Mania -- the original 2012 BASIC demo this project draws its mode set from, on CSDb: csdb.dk/release/?id=234174

Krill's Loader -- the fastloader used for every asset load in this project, on CSDb: csdb.dk/release/?id=226124

Oscar64 compiler -- C99/C++ cross-compiler for 6502, by drmortalwombat: github.com/drmortalwombat/oscar64

z64k -- an independent C128/VDC emulator used as a second data point during hardware debugging: z64k.com

C128 Programmer's Reference Guide -- the official hardware and BASIC reference, including the VDC register set: zimmers.net/anonftp/pub/cbm/manuals/c128

Share:
Facebook X Bluesky WhatsApp