sslxy

gfx-techniken

VIC-II – was das Datenblatt beschreibt, und was Programmierer trotzdem herausgeholt haben.

Der VIC-II wurde 1982 entworfen. Er kann 16 Farben darstellen, acht Hardware-Sprites rendern, mehrere Grafikmodi bedienen und einen Bildschirm mit 40×25 Zeichen aufbauen. Das ist die offizielle Version. Die inoffizielle Version ist erheblich länger: Rasterstrahl-Manipulation, aufgebrochene Rahmen, pro-Zeilen-Farbänderungen, Sprite-Multiplex, FLI, FLD, DYCP, VSP, AGSP, Hardware-Scrolling in acht Richtungen, doppelt gepufferte Grafik – alles auf Hardware, die vieles davon nicht ausdrücklich vorgesehen hat.

Diese Seite geht nicht den einfachen Weg. Sie beginnt mit dem Timing des VIC-II, weil ohne dieses Fundament keine der fortgeschrittenen Techniken wirklich verständlich ist. Dann folgen die Techniken in aufsteigender Komplexität – von stabilem Raster-IRQ bis zu FLI, VSP und komplexeren Bildverschiebungen. Alles mit dem Ziel: nicht nur zu wissen, dass ein Trick funktioniert, sondern zu verstehen, warum.

System Diagnostic

> VIC-II GFX ANALYSIS
CHIP MOS 6569 (PAL) / MOS 6567 (NTSC) – Video Interface Controller II RASTER PAL: 312 Zeilen / 63 Zyklen pro Zeile – NTSC: 263 Zeilen / 65 Zyklen SICHTBAR 320×200 Pixel / 40×25 Zeichen – plus Rahmen oben, unten, links, rechts FARBEN 16 Festfarben – keine frei definierbare Palette im Standard SPRITES 8 Hardware-Sprites / 24×21 Pixel je – erweiterbar per Multiplex REGISTER $D000–$D02E: Sprite- und VIC-II-Register / $D011–$D012: Raster und Y-Scroll / $D016: X-Scroll / $D018: Screen-/Charset-/Bitmap-Pointer innerhalb der aktiven VIC-Bank / $DD00: VIC-Bank TRICKS FLI / FLD / DYCP / Open Border / Sprite-Multiplex / VSP / AGSP / Dithering / Splits
Ein Chip, der 1982 definiert wurde – und dessen Grenzen bis heute verschoben werden.
[hardware/vic_timing]

VIC-II Timing: die Grundlage von allem

Wer den VIC-II verstehen will, muss mit seinem Timing beginnen. Nicht mit den Grafikmodi, nicht mit den Sprites – mit dem Timing. Denn das Timing des VIC-II ist der Mechanismus, der alle fortgeschrittenen Techniken erst möglich macht. Und es ist derselbe Mechanismus, der die CPU regelmäßig bremst und damit den Charakter des gesamten Systems prägt.

Der VIC-II erzeugt sein Bild, indem er Zeile für Zeile einen virtuellen Rasterstrahl durch das Bild bewegt – analog zum physischen Elektronenstrahl einer Bildröhre. Auf einem PAL-C64 gibt es 312 Rasterzeilen pro Vollbild, von denen 200 den sichtbaren Text- beziehungsweise Grafikbereich ausmachen. Jede Rasterzeile hat 63 Taktzyklen Dauer. Auf NTSC sind es 263 Zeilen mit je 65 Zyklen.

Parameter PAL (6569) NTSC (6567)
Gesamte Rasterzeilen312263
Sichtbare Zeilen200200
Taktzyklen pro Zeile6365
Systemtakt985.248 Hz1.022.727 Hz
Frames pro Sekundeca. 50,12 Hzca. 59,83 Hz
Taktzyklen pro Frame19.65617.095
Badlines pro Frame2525

Während der VIC-II eine Zeile aufbaut, teilen sich CPU und VIC-II den Speicherbus. Das ist die zentrale Tatsache hinter fast allen Tricks. Der 6510 ist nicht frei, wann immer er möchte auf RAM zuzugreifen. Er bekommt nur die Busphasen, die der VIC-II gerade nicht selbst beansprucht.

In normalen Zeilen ist das noch relativ harmlos. In Badlines und bei aktivem Sprite-DMA sieht die Lage deutlich enger aus. Deshalb ist auf dem C64 jede ernsthafte Grafiktechnik zugleich immer auch eine Timing-Technik.

[hardware/badlines]

Badlines im Detail

Eine Badline entsteht, wenn der VIC-II neue Zeichenkodierungen für die nächste Textzeile lesen muss. Das passiert genau dann, wenn die aktuelle Rasterzeile innerhalb des sichtbaren Bereichs liegt und die unteren drei Bits der Rasterzeile mit den unteren drei Bits des Y-Scroll-Werts in $D011 übereinstimmen.

In einer PAL-Badline stiehlt der VIC-II der CPU 40 Zyklen. Für die CPU bleiben in dieser Zeile also nur 23 Zyklen übrig. Das ist die saubere Grundregel. Zusätzliche Verluste entstehen dann separat, wenn in derselben Zeile Sprites aktiv sind und ihr DMA ebenfalls Buszeit braucht.

Diese 40 gestohlenen Zyklen sind kein theoretisches Detail. Sie sind der Grund, warum zeitkritischer Code ohne Berücksichtigung von Badlines unzuverlässig wird. Eine Routine, die auf einer normalen Zeile funktioniert, kann in einer Badline plötzlich um dutzende Zyklen verrutschen.

Badlines manipulieren

Die entscheidende Einsicht ist: Weil die Badline-Erkennung an den Y-Scroll-Wert gekoppelt ist, kann man beeinflussen, ob eine bestimmte Zeile zur Badline wird. Wer $D011 im richtigen Moment verändert, kann den Vergleich verhindern – und damit die Badline unterdrücken. Genau darauf bauen FLD und mehrere vertikale Feinverschiebungstricks auf.

Sprite-DMA als zweiter Engpass

Zusätzlich zu Badlines kostet auch Sprite-DMA Buszeit. Sobald der Rasterstrahl den sichtbaren Bereich eines Sprites erreicht, liest der VIC-II dessen Daten. Bei mehreren gleichzeitig aktiven Sprites summieren sich diese Zugriffe. Deshalb werden eng getaktete Rasterroutinen oft nicht nur gegen Badlines, sondern auch gegen Sprite-DMA kalibriert.

[hardware/graphics_modes]

Alle Grafikmodi vollständig

Der VIC-II kennt mehrere dokumentierte Grafikmodi, die sich aus den Bits in $D011 und $D016 ergeben. Entscheidend sind vor allem Bitmap-Bit, Multicolor-Bit und der Modus für erweiterten Hintergrund. Aus diesen Kombinationen entstehen die klassischen Betriebsarten des C64.

Modus Auflösung Farblogik RAM-Bedarf
Standard-Zeichenmodus 320×200 1 Vordergrundfarbe pro Zeichen aus Color-RAM, 1 globaler Hintergrund 1 KB Screen + 2 KB Charset
Multicolor-Zeichenmodus 160×200 effektiv 4 Farben pro Zeichenfeld nach Multicolor-Logik 1 KB Screen + 2 KB Charset
Erweiterter Hintergrund 320×200 4 globale Hintergrundfarben, reduzierter Zeichenvorrat 1 KB Screen + 2 KB Charset
Hires-Bitmap 320×200 2 Farben pro 8×8-Zelle 8 KB Bitmap + 1 KB Screen
Multicolor-Bitmap 160×200 effektiv 4 Farben pro 4×8-Zelle 8 KB Bitmap + 1 KB Screen + 1 KB Color-RAM

Standard-Zeichenmodus

Der Standard-Zeichenmodus ist der sparsamste und praktischste Modus des C64. Der Bildschirm besteht aus 1000 Zeichenpositionen, und jede davon verweist auf ein 8×8-Muster im Zeichensatz. Für Spiele war das ideal: wenig RAM-Bedarf, hohe Geschwindigkeit und sehr gute Eignung für Tile-basierte Welten.

Multicolor-Bitmap

Der Multicolor-Bitmap-Modus ist der klassische Modus für aufwendigere Bilder. Er liefert vier Farben pro 4×8-Zelle und ist die Grundlage des Koala-Formats. Die horizontale Auflösung sinkt dabei effektiv, dafür steigt die Farbdichte deutlich.

Erweiterter Hintergrund

Der ECM-Modus wird seltener erwähnt, ist aber nützlich. Er erlaubt mehrere globale Hintergrundfarben auf Kosten eines Teils des Zeichensatzes. Für strukturierte Hintergründe, Menüs und bestimmte Spieloberflächen ist das durchaus brauchbar.

Undokumentierte Kombinationen

Bestimmte Bitkombinationen, die offiziell keinen regulären Grafikmodus darstellen, führen zu leerem oder instabilem Bildaufbau. Diese Zustände sind nicht als normaler Arbeitsmodus gedacht, werden aber in Spezialfällen als Zwischenzustände in Rasterroutinen genutzt.

[hardware/colors]

Die 16 Farben und Color-RAM

Der C64 hat eine feste 16-Farben-Palette. Es gibt keine frei programmierbaren RGB-Werte. Diese starre Palette ist ein Teil seiner visuellen Identität und zugleich eine harte Grenze für alle Grafiktechniken.

Color-RAM ist dabei ein Sonderfall: Es liegt bei $D800–$DBFF und ist kein normales 8-Bit-RAM, sondern 4-Bit-Farbspeicher. Jeder Bildschirmposition ist genau ein Farbwert zugeordnet. Das macht Farblogik im Zeichenmodus einfach – und Farbumschaltungen bei Scrolling oder Animationen aufwendiger, weil Screen-RAM und Color-RAM gemeinsam gepflegt werden müssen.

Im Multicolor-Zeichenmodus kommt eine weitere Besonderheit hinzu: Ein gesetztes Bit 3 im Farbnybble signalisiert, dass das Zeichen im Multicolor-Zeichenmodus interpretiert wird. Damit kann man auf demselben Bildschirm gewissermaßen zwischen scharfen und breiteren Pixeln mischen.

[programming/raster_irq]

Raster-IRQ: Theorie und Praxis

Der Raster-IRQ ist die Grundtechnik fast aller dynamischen VIC-II-Effekte. Der VIC-II kann einen Interrupt auslösen, wenn der Rasterstrahl eine bestimmte Zeile erreicht. In dieser IRQ-Routine lassen sich Register umschalten, Farben ändern, Modi wechseln oder der nächste IRQ vorbereiten.

Das Grundprinzip ist einfach: Zielzeile in $D012 eintragen, Raster-IRQ in $D01A aktivieren, IRQ-Flag in $D019 sauber quittieren. Die Komplexität kommt erst später – wenn das Timing innerhalb der Zeile pixelgenau werden soll.

; Raster-IRQ einrichten: Grundkonfiguration
;
SEI
LDA #<my_irq : STA $0314
LDA #>my_irq : STA $0315
LDA #TARGET_LINE : STA $D012
LDA $D011 : AND #$7F : STA $D011
LDA #$01 : STA $D01A
CLI
;
my_irq:
LDA #NEW_COLOR : STA $D020
LDA #$01 : STA $D019
JMP $EA31

Für einen einfachen Split-Screen reicht das oft schon. Für exakte Effekte innerhalb einer Zeile nicht. Dort beginnt dann der Bereich stabiler Raster-IRQs.

[programming/stable_raster]

Stabiler Raster-IRQ (Double-IRQ)

Ein normaler Raster-IRQ hat Jitter. Der Grund ist schlicht: Der 6510 beendet den gerade laufenden Befehl, bevor er in die IRQ-Routine springt. Je nach aktuellem Befehl verschiebt sich der Einsprungzeitpunkt um mehrere Zyklen. Für grobe Effekte ist das belanglos. Für pixelgenaue Umschaltungen nicht.

Der Double-IRQ-Trick löst dieses Problem, indem der erste IRQ nur dazu dient, den zweiten sauber einzufangen. Man wartet auf eine exakt definierte Situation in der nächsten Zeile und hat ab dort einen stabilen Einstiegspunkt.

; Double-IRQ: stabilisierter Raster-Handler
;
stable_irq_1:
LDA #$01 : STA $D019
LDA #TARGET+1 : STA $D012
NOP : NOP : NOP : NOP
wait_line: BIT $D012 : BPL wait_line
; ab hier definierter Einstiegspunkt
LDA #NEW_COL : STA $D021
JMP $EA31

Das eigentliche Handwerk liegt dann im Kalibrieren. NOPs und andere feste Zyklusblöcke verschieben den Schreibzeitpunkt in präzisen Schritten. Wer stabile horizontale Kanten will, kommt um dieses Zählen nicht herum.

[technique/color_split]

Farb-Split und Farbbalken

Der einfachste Rastereffekt ist der Farb-Split: In einem Raster-IRQ wird $D020 oder $D021 umgeschaltet. Damit entstehen horizontale Farbzonen. Mehrere IRQs pro Frame ergeben mehrere Zonen. Wird das in dichter Folge gemacht, entstehen Farbbalken und Farbverläufe.

Regenbogen-Raster

Ein IRQ pro Zeile oder pro wenige Zeilen verändert die Hintergrund- oder Rahmenfarbe entlang einer Tabelle. Das Ergebnis ist der klassische Regenbogenbalken-Effekt. Einfach in der Idee, aber timing-empfindlich, wenn die Kanten sauber bleiben sollen.

Split-Screen

Hier wird nicht nur Farbe gewechselt, sondern auch Modus, Screen-Pointer oder Zeichensatzbasis. So entstehen Spieloberflächen mit Grafik oben und Statusbereich unten oder umgekehrt. Der Raster-Split ist eines der nützlichsten Werkzeuge der praktischen C64-Grafikprogrammierung.

Horizontale Balken innerhalb einer Zeile

Wer Farben mehrfach innerhalb derselben Zeile umschaltet, erzeugt vertikale oder feingliedrige Balkenmuster. Dafür braucht man stabile IRQs und sauberes Cycle-Counting. Der Effekt ist klassisch, aber technisch kein Zufallsprodukt.

[technique/scrolling]

Hardware-Scrolling: X und Y

Der VIC-II besitzt eingebaute Feinscroll-Register: $D016 für horizontales Scrolling um 0–7 Pixel, $D011 für vertikales Scrolling um 0–7 Pixel. Das spart Kopierarbeit, weil der Bildschirm zunächst nur optisch verschoben wird.

Sobald der Feinscroll-Bereich ausgeschöpft ist, muss der logische Bildinhalt nachgezogen werden: Bei horizontalem Scrollen wird eine Zeichenspalte umkopiert, bei vertikalem Scrollen eine ganze Zeichenzeile. Das ist die Kombination aus Hardware- und Softscrolling, wie sie fast jedes größere Scrollspiel verwendet.

Vertikales Softscrolling

Der Y-Scroll-Wert läuft von 0 bis 7. Beim Übergang muss der sichtbare Inhalt um genau eine Textzeile reorganisiert werden. Das ist vergleichsweise günstig, weil Zeilen im Screen-RAM als zusammenhängende 40-Byte-Blöcke vorliegen.

Horizontales Softscrolling

Hier ist der Aufwand größer. Eine Verschiebung um eine Zeichenspalte betrifft alle 25 Bildschirmzeilen plus das Color-RAM. Gerade deshalb sind horizontale Scroller auf dem C64 immer auch ein Thema sauberer Speicherorganisation.

38-Spalten-Modus als Hilfsmittel

Das Umschalten zwischen 38- und 40-Spalten-Modus wird häufig genutzt, um kritische Übergänge beim horizontalen Scrollen optisch zu verbergen. Das ist kein Nebentrick, sondern in vielen Routinen Bestandteil des eigentlichen Scroll-Designs.

[technique/open_border]

Open Border: vertikal und horizontal

Der Rahmen des C64 ist nicht einfach nur Farbe außen herum. Er wird vom VIC-II über interne Zustände ein- und ausgeschaltet. Genau dort setzt Open Border an: Wer im richtigen Moment Register umschaltet, kann verhindern, dass der VIC-II den Rahmen wieder schließt.

Vertikales Open Border

Durch gezielte Manipulation von $D011 rund um die kritischen Rasterzeilen lässt sich der obere oder untere Rahmen offenhalten. Das schafft zusätzliche sichtbare Zeilen, in denen Sprites oder andere Effekte weiterlaufen können.

; Vertikales Open Border (schematisch)
;
LDA $D011
AND #$EF
STA $D011
ORA #$10
STA $D011

Horizontales Open Border

Der seitliche Rahmen ist noch heikler. Hier wird mit $D016 und dem Zeitpunkt des Umschaltens gearbeitet. Das Fenster ist klein, der Effekt aber sehr wirkungsvoll: Sprites und Grafik reichen scheinbar in den Rahmen hinein oder über ihn hinaus.

[technique/fld]

FLD – Flexible Line Distance

FLD ist ein Trick zur vertikalen Dehnung oder Verschiebung von Bildinhalt, ohne RAM-Daten wirklich zu verschieben. Die Technik basiert darauf, dass Badlines gezielt unterdrückt werden können. Dadurch bleibt der VIC-II länger auf derselben Zeichenzeile stehen, als er es eigentlich tun sollte.

Das Ergebnis ist eine vertikal gestreckte oder scheinbar verschobene Darstellung. In der Praxis wird FLD oft mit vorberechneten Tabellen kombiniert, um sanfte Wellen- oder Gleitbewegungen im Bild zu erzeugen.

; FLD: schematische Badline-Unterdrückung
;
LDA yscroll_val
EOR #$07
AND #$07
ORA d011_base
STA $D011

Wer FLD sauber einsetzt, arbeitet letztlich nicht mit „Grafik“, sondern mit dem Zeilenfortschritt des Chips. Genau deshalb gehört FLD zu den Techniken, die erst dann wirklich verständlich werden, wenn man Badlines nicht mehr nur als Theorie kennt.

[technique/fli]

FLI – Flexible Line Interpretation

FLI ist eine der wichtigsten C64-Bildtechniken überhaupt. Sie löst das grundlegende Problem des Multicolor-Bitmap-Modus: Normalerweise gilt eine Farbkombination für eine ganze 4×8-Zelle. FLI zwingt den VIC-II dazu, pro Rasterzeile andere Farbinformationen zu verwenden. Damit steigt die vertikale Farbauflösung drastisch.

Das Prinzip

Der Trick besteht darin, den Screen-RAM-Bezug innerhalb des Bildaufbaus laufend umzuschalten. Der VIC-II liest dadurch in verschiedenen Rasterzeilen unterschiedliche Farbquellen, obwohl der Bitmap-Inhalt selbst stehenbleibt. Genau diese Trennung zwischen Bitmap-Daten und Farbquelle macht FLI möglich.

; FLI: schematisches Umschalten der Farbquelle
;
fli_irq:
LDA fli_screen_ptr,X
STA $D018
INX
; Timing muss innerhalb derselben Rasterzeile sitzen

Der FLI-Bug

FLI hat einen unvermeidlichen Nebeneffekt: Am linken Bildrand entsteht ein fehlerhafter Bereich. In der Praxis betrifft das nicht nur eine einzelne „normale“ Zeichenspalte, sondern einen breiteren linken Teil des Bildes, der in klassischen FLI-Bildern oft bewusst verdeckt oder schwarz gehalten wird. Das ist kein Umsetzungsfehler des Programmierers, sondern eine direkte Folge der Technik.

Kosten der Technik

FLI kostet Speicher und CPU-Zeit. Mehrere Screen-RAM-Varianten, exakte Rastersteuerung und sauberes IRQ-Management machen die Technik teuer. Gerade deshalb wird FLI in der Regel für statische oder nur gering animierte Bilder eingesetzt – nicht für allgemeine Spielegrafik.

[technique/ifli]

IFLI – Interlaced FLI

IFLI treibt das FLI-Prinzip weiter, indem zwei zueinander versetzte Bildzustände in aufeinanderfolgenden Frames abwechselnd dargestellt werden. Das Auge mischt diese beiden Halbbilder zu einem feineren Gesamteindruck. Dadurch steigt die subjektive Detailwirkung sichtbar an.

Der Preis dafür ist Flickern. Auf manchen Displays und für manche Betrachter ist das noch akzeptabel, auf anderen deutlich sichtbar. IFLI ist deshalb eine Technik mit beeindruckender Wirkung, aber klarer Nebenwirkung.

[technique/dycp]

DYCP – Different Y Character Positions

DYCP ist der klassische Sinus-Text-Effekt. Jede Spalte eines Textes bekommt eine eigene vertikale Position, sodass der Text wie ein schwingendes Band wirkt. Technisch geschieht das über fein abgestimmte Änderungen des Y-Scroll-Werts und gegebenenfalls über zusätzliche Tricks, wenn die Auslenkung größer werden soll.

Entscheidend ist, dass nicht der Text als Datenblock bewegt wird, sondern seine Darstellung entlang des Rasterstrahls moduliert wird. Auch hier gilt: Der eigentliche Effekt ist letztlich ein Timing-Effekt.

; DYCP: schematischer Ablauf
;
dycp_irq:
LDX column_counter
LDA y_table,X
AND #$07
ORA d011_base
STA $D011
INC column_counter

Gute DYCP-Routinen arbeiten mit vorberechneten Tabellen und sehr straffer Taktung. Schlechte wirken grob. Gute wirken ruhig, obwohl sie technisch hektisch sind.

[hardware/sprites]

Sprites: vollständige Technik

Der VIC-II bietet acht Hardware-Sprites. Jedes Sprite ist 24×21 Pixel groß und wird über 64 Byte Daten beschrieben. Die X-Position ist 9 Bit breit, die Y-Position 8 Bit. Farben, Multicolor-Modus, Priorität und Dehnung werden über eigene Register gesteuert.

Adresse Register Funktion
$D000/$D001SP0X / SP0YSprite 0 Position
$D002–$D00FSP1–SP7Sprites 1–7 Positionen
$D010MSBXNeuntes Bit der X-Positionen
$D015SPENASprites aktivieren
$D017SPEXPYVertikale Dehnung
$D01CSPMCSprite-Multicolor
$D01DSPEXPXHorizontale Dehnung
$D01BSPBGPRPriorität vor/hinter Hintergrund
$D01ECLXSPSSprite/Sprite-Kollision
$D01FCLXSPBSprite/Hintergrund-Kollision
$D025/$D026SPMC0/SPMC1Globale Multicolor-Farben
$D027–$D02ESP0C–SP7CEinzelfarben der Sprites

Sprite-Pointer

Die Sprite-Daten selbst werden über acht Pointer am Ende des Screen-RAM adressiert. Jeder Pointer verweist in 64-Byte-Schritten auf den Beginn der Sprite-Daten innerhalb der aktiven VIC-Bank. Genau deshalb hängen Sprite-Datenorganisation und VIC-Bank immer zusammen.

Multicolor und Dehnung

Im Multicolor-Sprite-Modus sinkt die effektive horizontale Detailauflösung, dafür steigt die Farbfähigkeit des Sprites. Dehnung verdoppelt Breite oder Höhe, ohne den Datenumfang zu erhöhen. Das ist praktisch, aber sichtbar grob. Gute Routinen setzen diese Hilfsmittel bewusst ein, nicht aus Verlegenheit.

[technique/sprite_multiplex]

Sprite-Multiplex

Acht Hardware-Sprites genügen für viele Spiele und Demo-Effekte nicht. Sprite-Multiplex löst das, indem Sprites nach ihrem sichtbaren Einsatz im Bild neu positioniert und mit neuen Daten versehen werden. Derselbe Hardwarekanal erscheint damit mehrfach im selben Frame an verschiedenen Stellen.

Die harte Grenze bleibt: Pro Rasterzeile sind physisch nur acht Spritekanäle vorhanden. Multiplex erhöht also nicht die Zahl gleichzeitig in derselben Zeile sichtbarer Sprites, sondern die Zahl aller Sprites im ganzen Bild.

Einfaches Multiplex

Ein Sprite wird nach Verlassen seines oberen Einsatzbereichs weiter unten neu gesetzt. Zwei sichtbare Positionen mit demselben Kanal – technisch simpel, praktisch sehr wirksam.

Sortierte Multiplex-Systeme

Fortgeschrittene Routinen führen eine nach Y-Position sortierte Liste und belegen die acht Hardwarekanäle dynamisch mit den jeweils nächsten sichtbaren Sprites. Das ist aufwendig, aber der Standardweg für spriteintensive Spiele.

Der eigentliche Preis

Multiplex kostet IRQ-Zeit, Sortierzeit und Registerschreibzeit. Gute Multiplexer sparen an jeder Stelle Zyklen, weil die Bildlogik sonst an ihrer eigenen Verwaltung erstickt.

[technique/vsp_agsp]

VSP und AGSP

Hier lohnt Präzision. AGSP ist im C64-Kontext nicht „All Graphics Sprite Plane“. Gemeint ist in der Regel die Familie der VSP-/AGSP-Techniken, also Bildpositions- und Bildverschiebungstricks auf Basis des VIC-II-Speicherzugriffs und der Scroll-/Badline-Logik. Der Kern ist nicht eine Sprite-Vollfläche, sondern die Verschiebung des angezeigten Bildinhalts an Positionen, die so offiziell nicht vorgesehen sind.

VSP – Variable Screen Position

VSP verschiebt den logischen Bildschirmbezug des VIC-II, ohne den Bildinhalt selbst umzukopieren. Das geschieht durch sehr genaues Umschalten von Scroll- und Bildparametern in Kombination mit dem Zeitpunkt, zu dem der VIC-II seine Zeilen- und Screen-Referenzen holt. Das Ergebnis ist ein scheinbar frei verschiebbarer Bildausschnitt.

Diese Technik ist mächtig, aber nicht harmlos. Auf manchen Maschinen kann fehlerhaftes oder aggressives VSP zu Speicherbeschädigungen führen. Genau deshalb ist VSP historisch bekannt, aber auch berüchtigt.

AGSP – Any Given Screen Position

AGSP geht einen Schritt weiter und zielt darauf, den Bildschirminhalt an beliebigen Positionen innerhalb des darstellbaren Bereichs zu verankern. Praktisch ist das eine Verallgemeinerung der VSP-Idee: nicht nur weiche Verschiebung, sondern freie Platzierung des sichtbaren Screen-Fensters innerhalb der technischen Grenzen des VIC-II.

AGSP ist damit kein Sprite-Trick, sondern ein Screen-Positioning-Trick. Wer hier sauber formuliert, vermeidet Missverständnisse. Es geht um den Bildschirminhalt als solchen, nicht um eine aus Sprites aufgebaute Ersatzebene.

[technique/custom_charset]

Char-ROM und Custom-Zeichensätze

Der Zeichensatz des C64 ist kein starres Schicksal. Man kann das Zeichen-ROM ins RAM kopieren, eigene Muster anlegen und den VIC-II per $D018 auf diesen RAM-Zeichensatz zeigen lassen. Das ist die Grundlage fast aller tilebasierten Spielwelten, vieler Schrifttricks und zahlreicher Pseudo-Grafiksysteme.

; Zeichen-ROM nach $3000 ins RAM kopieren
;
SEI
LDA $01 : AND #$FB : STA $01
LDX #$00
copy_loop:
LDA $D000,X : STA $3000,X
LDA $D100,X : STA $3100,X
LDA $D200,X : STA $3200,X
INX : BNE copy_loop
LDA $01 : ORA #$04 : STA $01
CLI

Der eigentliche Wert liegt nicht nur in „anderen Zeichen“, sondern darin, dass ein Zeichenmodus-Bildschirm mit eigenem Zeichensatz sehr viel billiger und oft schneller ist als ein Bitmap-Bildschirm. Genau deshalb ist der Charaktermodus auf dem C64 kein Rückstand, sondern in vielen Fällen die bessere Entscheidung.

Animated Tiles und Charset-Umschaltung

Wer mehrere Zeichensätze vorbereitet und zwischen ihnen umschaltet, bekommt Animation fast ohne Schreibaufwand ins eigentliche Screen-RAM. Wasser, Feuer, blinkende Anzeigen – vieles lässt sich so wesentlich eleganter lösen als mit direkter Pixelmanipulation.

[technique/double_buffering]

Double-Buffering

Double-Buffering ist die saubere Methode gegen sichtbare Abrisslinien. Während ein Buffer angezeigt wird, wird der andere aufgebaut. Zum richtigen Zeitpunkt wird umgeschaltet. Erst danach wird der alte sichtbare Buffer wieder zum Arbeitsbereich.

Im C64-Kontext ist das je nach Modus teuer oder günstig. Zwei komplette Bitmap-Buffer kosten viel RAM. Zwei Screen-RAM-Buffer sind deutlich leichter zu stemmen. Deshalb wird in der Praxis oft selektiv gepuffert: Dort, wo es nötig ist – nicht überall.

; Double-Buffer: Screen-RAM wechseln
;
LDA active_buffer
EOR #$01
STA active_buffer
BEQ use_buffer_a
use_buffer_b:
LDA #$18 : STA $D018
JMP buffer_done
use_buffer_a:
LDA #$58 : STA $D018
buffer_done:

Das Entscheidende ist nicht der Umschaltbefehl selbst, sondern der Zeitpunkt. Wer mitten im sichtbaren Aufbau umschaltet, bekommt genau den Fehler, den er eigentlich vermeiden wollte.

[technique/dithering]

Dithering auf dem C64

Mit 16 festen Farben und harten Zellgrenzen reicht rohe Farbauswahl allein oft nicht. Dithering simuliert zusätzliche Farbstufen durch räumliche Verteilung vorhandener Farben. Das ist auf dem C64 keine Nebensache, sondern oft der Unterschied zwischen grob und überzeugend.

Schachbrett-Dithering

Zwei Farben wechseln sich pixelweise ab. Aus der Entfernung mischt das Auge sie zu einer scheinbaren Zwischenfarbe. Einfach, sichtbar, wirkungsvoll – und in vielen C64-Bildern klar zu erkennen.

Ordered Dithering

Hier wird ein geordnetes Muster verwendet, meist eine kleine Matrix. Das Ergebnis wirkt kontrollierter als ein bloßes Schachbrett und ist für vorberechnete Grafikdaten oft sinnvoller.

Error-Diffusion

Für echte Bildkonvertierung ist Error-Diffusion qualitativ stärker. Auf dem C64 selbst wird das praktisch nicht in Echtzeit gerechnet. Die Technik gehört in den Vorbereitungsprozess, nicht in den laufenden Bildaufbau.

[technique/plasma]

Plasma-Effekte

Plasma ist die Kunst, aus vorberechneten oder laufend kombinierten Wellenmustern eine fließende Farbbewegung zu erzeugen. Technisch steckt meist nichts Mystisches dahinter: Sinustabellen, Additionen, Phasenverschiebungen, Farbnachschlagetabellen.

Die Herausforderung auf dem C64 ist wie immer die Rechenzeit. Echte Pixelplasma-Effekte sind teuer. Deshalb wird häufig auf Zeichenebene oder mit vorberechneten Tabellen gearbeitet. Die Wirkung kann trotzdem ausgesprochen weich erscheinen.

; Plasma: Grundprinzip mit Tabellen
;
LDX x_pos
LDA sin_x,X
LDY y_pos
CLC
ADC sin_y,Y
ADC time_offset
AND #$0F
STA $D800,X
[technique/starfield]

Starfield und Parallax-Scrolling

Ein Sternfeld ist technisch simpel und visuell effektiv. Wenige Pixel mit unterschiedlichen Geschwindigkeiten reichen aus, um Tiefe zu suggerieren. Gerade weil der Effekt sparsam ist, gehört er zu den langlebigsten Mitteln des C64.

Parallax-Scrolling erweitert diese Idee: Mehrere Ebenen bewegen sich mit verschiedenen Geschwindigkeiten. Auf dem C64 geschieht das meist durch Kombination von Zeichenmodus-Hintergründen, Sprites und Raster-Splits. Der Effekt ist umso überzeugender, je disziplinierter die Routinen organisiert sind.

[hardware/vic_bank]

VIC-II Bank-Switching

Der VIC-II sieht nie den kompletten 64-KB-Adressraum gleichzeitig. Er arbeitet mit vier möglichen 16-KB-Bänken. Welche davon aktiv ist, wird über CIA2 beziehungsweise $DD00 gewählt. Innerhalb dieser aktiven Bank bestimmt dann $D018, wo Screen-RAM, Charset oder Bitmap liegen.

$DD00 Bits 0–1 VIC-II Bank Adressbereich Besonderheit
%11Bank 0$0000–$3FFFChar-ROM-Fenster vorhanden
%10Bank 1$4000–$7FFFfrei nutzbar
%01Bank 2$8000–$BFFFChar-ROM-Fenster vorhanden
%00Bank 3$C000–$FFFFfrei nutzbar

Char-ROM-Fenster

In Bank 0 und 2 gibt es Bereiche, in denen der VIC-II statt des darunterliegenden RAM das Zeichen-ROM sieht. Wer eigene Zeichensatzdaten dort platziert, wundert sich später zurecht, warum der Bildschirm nicht zeigt, was im RAM steht. Das ist kein Fehler im Code, sondern feste Verdrahtung des Chips.

Genau deshalb liegen viele eigene Grafiksysteme bevorzugt in Bank 1 oder 3. Dort gibt es diese Falle nicht.

[meaning/legacy]

Was die Grafiktechniken über Systemprogrammierung sagen

Alle Techniken auf dieser Seite haben eines gemeinsam: Sie entstanden nicht, weil der VIC-II sie ausdrücklich vorgesehen hatte. Sie entstanden, weil Programmierer das System vollständig verstanden hatten – bis auf die Ebene einzelner Taktzyklen – und dann Eigenschaften der Hardware ausnutzten, die im Datenblatt gar nicht oder nur indirekt auftauchten.

FLI funktioniert nur, wenn man weiß, wann der VIC-II seine Farbquelle liest. Open Border funktioniert nur, wenn man weiß, wann interne Rahmenzustände umschalten. Stabile Raster-IRQs funktionieren nur, wenn man die Längen des 6510-Befehlssatzes und deren Verhältnis zum Bildtakt im Griff hat.

Das ist keine nostalgische Beobachtung, sondern eine strukturelle. Wer den Unterschied kennt zwischen dem, was ein System tun soll, und dem, was es tatsächlich tut, findet Möglichkeiten, die andere übersehen. Der VIC-II ist dafür nur ein besonders gutes Beispiel.

[Lesson] VIC-II → Systemprogrammierung allgemein
> Datenblatt = Mindestbeschreibung, nicht vollständige Realität
> Timing-Diagramme sind keine Dekoration, sondern Arbeitsmaterial
> Cycle-Counting ist Grundlage, nicht Marotte
> Grenzen sind präzise Zustände, keine metaphysischen Wände
> Verstehen entsteht durch Messen, Testen, Wiederholen

„Wer nur liest, was der VIC-II tun soll, weiß weniger als wer gemessen hat, was er tut.“

↑ Nach oben