Retro-Notizen — die C64-Wissensbasis im Überblick
Dies ist der öffentliche Spaziergang durch die kuratierte Wissensbasis des wintermute-c64-Projekts — das Wissen, mit dem der Agent Dope arbeitet, kondensiert für Menschen. Alles hier ist in VICE verifiziert oder an dokumentierte Quellen rückgebunden; wo öffentliche Referenzen existieren, sind sie verlinkt.
Prozessor: 6510 & Opcodes
Adressierungsarten und Opcodes
Der 6510 im C64 ist für alle dokumentierten Opcodes 6502-kompatibel und ergänzt den CPU-I/O-Port bei $00/$01. Seine 13 Adressierungsarten unterscheiden sich vor allem in einem: was sie kosten.
An den Lücken der Befehlsmatrix verhebt sich generierter wie handgeschriebener Code gleichermaßen gern:
STAkennt kein Immediate,STXkeinabsolute,Y,STYkeinabsolute,XBITgibt es nur Zero Page und Absolute- Read-Modify-Write-Befehle (
INC,ASL, …) haben kein Immediate
Dazu zwei NMOS-Fallen mit Tradition: Zero-Page-Indizierung wickelt modulo 256 (lda $80,x mit X=$FF liest $007F, nicht $017F) — und jmp ($xxFF) holt das High-Byte fälschlich von $xx00. Indirekte Vektoren also nie auf ein Seitenende legen.
Quellen: Oxyron-Opcode-Matrix · c64os.com · pagetable c64ref
Speicher & Banking
Memory Map und Zero Page
Der 6510 sieht 64 KB — aber ROM und I/O liegen als schaltbare Schichten über dem RAM. Die goldene Regel: Schreibzugriffe treffen immer das RAM darunter, nur Lesezugriffe sehen das eingeblendete Gerät.
Wer unter laufendem BASIC/KERNAL eigene Routinen schreibt, hat erstaunlich wenig garantiert freien Platz:
- Zero Page: offiziell nur
$FB–$FE(vier Bytes!) $0334–$033Bund der 192-Byte-Kassettenpuffer$033C–$03FB(solange kein Tape-I/O läuft)- der klassische 4-KB-Block
$C000–$CFFF
Quelle: pagetable.com/c64ref/c64mem
VIC-II: der Grafikchip
Die Register-Referenz
Die 47 VIC-II-Register liegen bei $D000–$D02E. Das Steuerzentrum bilden zwei Register, deren Bits man irgendwann auswendig kennt:
Dazu die Eckdaten, auf denen alles Weitere aufbaut:
$D018wählt Video-Matrix (1-KB-Schritte) und Zeichensatz (2-KB-Schritte) innerhalb der aktiven 16-KB-VIC-Bank; die Bank selbst schaltet CIA 2 ($DD00)- Raster-IRQs: aktivieren über
$D01ABit 0, quittieren durch Schreiben von$01nach$D019 - PAL: 312 Rasterzeilen à 63 Zyklen
- Badline: wenn im sichtbaren Bereich
(Rasterzeile & 7) == YSCROLLgilt, stoppt der VIC die CPU für rund 40 Zyklen, um Zeichendaten zu holen
Sprites
Acht Hardware-Sprites à 24×21 Pixel. Ihre Daten (63 Bytes + 1 Füllbyte) liegen auf 64-Byte-Grenzen, adressiert über Pointer, die keine Register sind, sondern die letzten 8 Bytes der Video-Matrix:
Die drei Regeln, die man nicht in Registerlisten findet:
- Die Kollisionslatches
$D01E(Sprite–Sprite) und$D01F(Sprite–Grafik) löschen sich beim Lesen — einmal lesen, Ergebnis speichern - Multicolor (
$D01C) halbiert die Auflösung auf 12 Doppelpixel: 00 = transparent, 01/11 = gemeinsame Farben$D025/$D026, 10 = Einzelfarbe - Multiplexing geht vertikal (Sprite nach Displayende wiederverwenden), aber nie horizontal in derselben Rasterzeile — das Schieberegister wird nicht neu gefüllt
Bitmap-Modi
Hires-Bitmap ($D011 Bit 5) liefert 320×200 Pixel in 8.000 Bytes; Multicolor (zusätzlich $D016 Bit 4) tauscht die halbe horizontale Auflösung gegen vier Farbquellen pro Zelle:
Das Referenz-Layout des Projekts: VIC-Bank 0, Screen $0400, Bitmap $2000, $D018 = $18.
Visuelle Grundlagen
Ein „A", vier Welten
Die häufigste Fehlerquelle bei C64-Textausgabe ist keine Technik, sondern eine Verwechslung — dasselbe Zeichen existiert in vier Kodierungen:
Dazu das Drumherum:
- Der Textbildschirm ist 40×25, Offset = Zeile × 40 + Spalte
- Das parallele Farb-RAM
$D800speichert nur das Low-Nibble — niemals Flags im High-Nibble ablegen - Eigene Zeichensätze gehören auf 2-KB-Grenzen der VIC-Bank (Screen
$0400+ Charset$3000→$D018 = $1C) - Die 16 VIC-Farben haben keine lineare Helligkeitsordnung — Farbrampen (Feuer:
$00 $09 $02 $08 $0A $07 $01) lebt man als Tabellen aus
Quellen: c64ref/charset · c64ref/colors
SID: der Soundchip
Die SID-Referenz
Drei Stimmen, ein Filter, ein Lautstärkeregler — der ganze Chip in einem Bild:
Die Regeln, die beim ersten eigenen Player Nerven sparen:
- ADSR und Frequenz vor dem GATE-Bit setzen; GATE löschen startet die Release-Phase
- Fast alles ist write-only — lesbar sind nur Paddles, OSC3 und ENV3 (
$D419–$D41C) - Musik-Player folgen der Konvention init =
$1000, play =$1003, einmal pro Frame aus dem IRQ - 6581 und 8580 klingen beim Filter und bei
$D418-Volume-Digis deutlich verschieden
Quellen: Oxyron SID-Register · C64-Wiki · Codebase64
Von der Note zum Registerwert
In der Praxis lebt das als vorberechnete Lo/Hi-Tabelle im Quelltext, indiziert über die Notennummer. Unterhalb von C-1 werden die Registerschritte hörbar grob; oben deckelt $FFFF bei B-7.
Demo-Techniken
Das Herzstück der Wissensbasis — hier steckt das meiste gemessene Wissen.
IRQ-Grundlagen
Der C64 kennt zwei IRQ-Routing-Modelle, und sie zu mischen ist der Klassiker unter den Anfängerfehlern:
Für Demo-Code ist der direkte Vektor mit Banking $01 = $35 die erste Wahl — das Timing bleibt explizit. Und nicht vergessen: sei maskiert nur IRQs, keine NMIs. Die RESTORE-Taste läuft über $FFFA/$FFFB und muss in timing-kritischen Produktionen separat gezähmt werden.
Stabile Raster-IRQs
Jeder naive Raster-IRQ jittert um einige Zyklen, weil die CPU ihre laufende Instruktion erst beendet — sichtbar als zitternde Balkenkante. Die Demoszene-Antwort ist der Double-IRQ-Stabilizer:
Einmal pro IRQ-Kette stabilisieren genügt, solange danach jeder Pfad feste Zyklenzahl hat. Und ein hübsch obskures Messergebnis aus dem Projekt: Ein $D021-Write auf einer Badline erzeugt ein Ein-Pixel-Artefakt — die Rasterbar-Farbtabelle dupliziert dort schlicht die Vorzeile.
CIA-Timer-IRQs
Die zweite Interrupt-Quelle des C64 — mit einer Quittierungs-Asymmetrie, die immer wieder Bugs produziert:
Cycle-Budget-Planung
Timing plant man rückwärts: Ziel-Rasterzeile → Fixpunkte → Overhead → Trigger-Zeile. Das Budget dafür ist endlich, und der VIC nimmt sich seinen Teil zuerst:
Die Fixpunkte im Kopf:
- IRQ-Latenz des 6510: 7–14 Zyklen
- Ein stabilisierter Handler verbraucht mit Save/Restore schnell eine ganze Rasterzeile
sta abs,xkostet immer 5 Zyklen (kein Page-Cross-Rabatt), Branches über Seitengrenzen +1 — zeitkritische Tabellen deshalb per!alignauf Seitenanfänge legen
Effekte kombinieren
Rasterbar, Scroller, Musik und Logo teilen sich einen Frame über eine kaskadierende IRQ-Kette — nicht über je einen eigenen Interrupt:
Stabilisiert wird nur einmal oben im Frame; die Folge-Splits erben das Timing. Musik gehört als fester Posten in einen unkritischen Split — nicht in einen freilaufenden CIA-IRQ, der den Stabilizer mitten in der Korrektur unterbrechen kann.
Scroller
Ein pixelglatter Textscroller ist ein Zwei-Phasen-Uhrwerk:
Wer eigene Zeichensätze will, kopiert das ROM-Charset mit dem Banking-Trick $01 = $33 (Zeichen-ROM sichtbar, I/O weg) nach RAM. Und der Klassiker unter den Fehlbildern: lda #$08 / sta $D016 jeden Frame ist kein Scrolling — das ist nur der 40-Spalten-Modus mit X-Scroll 0.
Sprite-Multiplexing
Mehr als acht Sprites heißt: Hardware-Sprites nach ihrem Displayende im selben Frame wiederverwenden — mit Y-Sortierung und einem IRQ-Fahrplan:
Ein gemessenes Detail mit Praxiswert: Rasterzeile 251 ist kein sicherer VBlank-Punkt für die Plan-Übergabe — ein Sprite bei Y = $EA wird dort noch angezeigt. Sicher ist Zeile 0.
FLD & FLI
Beide Techniken manipulieren den Zeichenzeilen-Zyklus des VIC-II — die eine dehnt das Bild, die andere vervielfacht die Farben:
Der Preis von FLI ist die berüchtigte Bug-Spalte am linken Rand, die man mit Sprites oder Artwork versteckt. Die maschinensensitiven Verwandten VSP/AGSP bleiben im Projekt bewusst außen vor — Kompatibilitätsrisiko auf echter Hardware.
Die Systematik der Visual-Math-Effekte
Vor jedem Effekt stehen dieselben vier Fragen:
- Wohin schreiben? Screen-RAM, Farb-RAM, Bitmap oder Sprites
- Welche Tabelle treibt? Farbrampe, Sinustabelle, LFSR, Heat-Buffer
- Was taktet? VBlank-Poll, Raster-IRQ oder CIA-Timer
- PAL oder NTSC?
Das kleinste Beispiel ist Color-Cycling (Phasenzähler plus Farbtabelle auf $D020/$D021); das größte sind volle 40×25-Updates mit 1.000 Stores pro Frame, die ohne Speedcode kein Frame-Budget der Welt hergibt.
Plasma & Speedcode
Plasma ist Tabellen-Mixing — und das beste Anschauungsbeispiel dafür, warum Speedcode existiert:
Die Speedcode-Variante cached 16 Achsenwerte pro Frame und lässt den Assembler feste STA abs-Ketten generieren: ~3,7 KB Code statt einer Schleife, dafür viermal schneller. Dazu die eisernen Regeln für selbstmodifizierenden Code: nur Operanden patchen, nie Opcodes — und nie patchen, während ein IRQ die Routine ausführen könnte.
Starfields
Sternenhimmel gibt es in drei Preisklassen:
- Screen-RAM-Sterne — Dutzende Punkte in Zeichenauflösung, fast gratis
- Sprite-Sterne — pixelgenau, aber maximal acht (und Sprite-DMA stiehlt Buszyklen)
- Bitmap-Sterne — radiale Perspektive à la C=Hacking #16:
x' = x + dx/Tiefein Fixed-Point
Der schönste Trick der Notiz: Ein animiertes Charset-Sternfeld rotiert einfach vier Zeichensatz-Pages per $D018 durch ($18/$1A/$1C/$1E) — kostet 8 KB RAM und fast keine CPU. Als Zufallsquelle dient ein 8-Bit-LFSR mit XOR-Maske $B8, und die Tiefen-Helligkeit wählt man explizit ($0B $0C $0F $01), denn VIC-Farbnummern sind keine Helligkeitsskala.
Feuer & Farbrampen
Das klassische Feuer ist ein Heat-Buffer mit Faltung — die Update-Reihenfolge ist dabei Teil der Physik:
Die Projekt-Messung: 220 Zellen Simulation plus 960 Farb-RAM-Stores ≈ 12.500–13.000 Zyklen — passt in einen PAL-Frame. Die Abkühlung läuft über eine branchlose Cooling-Tabelle, die den Underflow $00 → $FF verhindert.
Sinus-Tabellen
Der 6510 rechnet nie zur Laufzeit sin() — der Assembler tut es zur Assemblierzeit:
Geschwindigkeit ist schlicht das Phaseninkrement (+1 sanft, +3 flott), und zwei Zähler mit verschiedenen Inkrementen ergeben die typischen gekoppelten Pendelbewegungen.
Twister, Rotatoren, Waving Carpets
Deformationen rotieren nichts zur Laufzeit — sie mappen jede Zeile durch vorberechnete Tabellen:
Rasterline-Deformationen schreiben stattdessen getimte VIC-Register ($D016 für horizontale Wellen, $D011 vertikal, $D020/$D021 für reine Farbtiefe) — und brauchen dann die volle Stabilizer-Disziplin. Beim X-Rotator gilt: vorgeschobene Glyphs im Zeichensatz sind billiger als Pixelrotation.
Vektor-Grundlagen
Das Fundament aller Vektor-Effekte ist die Pixel-Adressrechnung im Hires-Bitmap:
Darauf bauen die Klassiker auf: Bresenham-Linien ohne Multiplikation (Fehlerterm halbieren, pro Schritt addieren/subtrahieren), der Midpoint-Kreis mit einem Oktanten achtfach gespiegelt, und die 3D-Pipeline mit signiertem Fixed-Point, Sinustabellen und der Projektion screen_x = cx + x·scale/z. Die Grundhaltung überall: RAM gegen Rechenzeit tauschen, wo immer eine Tabelle passt.
Das C=Hacking-Archiv
Die Effekt-Notizen sind systematisch im C=Hacking-Magazin geerdet — dem technischen Fachblatt der Szene (1992–2002). Die Landkarte für Einsteiger:
- Timing: Issue 3 „Missing Cycles", Issue 10 „Making stable raster routines"
- Ränder öffnen: Issue 6 „Opening the Borders"
- Display-Tricks: Issues 4/9/10 zu FLI, AFLI und BFLI
- 3D: Issues 8–12, die Serie „A Different Perspective"
- Sound: Issue 20 „The C64 Digi" über
$D418-Sample-Playback
Diskette & Speicherung
1541 & D64
Ein D64 ist das sektorweise Abbild einer 1541-Diskette — und Track 18 ist ihr Nervensystem:
Dateien sind Track/Sektor-Ketten: Die ersten zwei Bytes jedes Sektors zeigen auf den nächsten, 254 Nutzbytes bleiben. Und die 1541 selbst ist ein vollwertiger Computer mit eigener 6502-CPU und 2 KB RAM — die Grundlage aller Fastloader, die das lahme serielle IEC-Protokoll durch eigenen Code im Laufwerk ersetzen. Praktisch baut man D64s heute mit c1541 aus dem VICE-Paket.
Toolchain
Packing & Crunching
Auf dem C64 wird fast nichts unkomprimiert ausgeliefert. Die goldene Reihenfolge dabei:
Exomizer erzeugt mit sfx sys selbststartende PRGs (-n schaltet den Decrunch-Effekt ab — gut für deterministische Tests); Pucrunch ist der LZ77/RLE-Klassiker mit eingebettetem Entpacker.
Der kanonische BASIC-Start
Jedes ACME-Projekt beginnt mit demselben Ritual bei * = $0801 — einem BASIC-Einzeiler als Bytes:
Der häufigste Stolperstein steckt mittendrin: Das SYS-Argument ist Dezimaltext, kein Binärwert. Die PRG-Ladeadresse selbst steht nie im Quelltext — sie kommt von -f cbm beim Assemblieren.
Alle Angaben stammen aus der kuratierten, quellen-rückgebundenen Wissensbasis von wintermute-c64 — jede Notiz dort dokumentiert Herkunft, Lizenz und Vertrauensstufe ihrer Quellen, und die Timing-Aussagen sind in VICE (x64sc) gemessen. Wie diese Wissensbasis entstand, steht im Projektartikel; die übergreifende Methodik — jede Behauptung hat eine Fundstelle — kennt ihr aus der Denkmaschinen-Serie.