Der MOS 6567/6569 Videocontroller (VIC-II) und seine Anwendung im Commodore 64
Inhalt 3. Funktionsweise des VIC 3.14. Effekte/Anwendungen
3.14.6. DMA-Delay |
Die trickreichste Bad-Line-Manupulation besteht darin, innerhalb von Zyklus 15-53 einer Rasterzeile des Anzeigefensters, innerhalb der der Grafikdatensequenzer im Idle-Zustand ist, einen Bad-Line-Zustand zu erzeugen, z.B. durch Ändern von Register $d011 derart, daß YSCROLL gleich den unteren drei Bit von RASTER ist. Der VIC setzt dann sofort im nächsten Zyklus BA nach Low, geht in den Display-Zustand und beginnt mit dem Lesen aus der Videomatrix (der Prozessor ist nun angehalten, denn BA ist Low und er will den nächsten Opcode lesen). Allerdings schwingt AEC erst noch drei Zyklen lang mit ø2 mit, bevor es ebenfalls auf Low bleibt. Dieses Verhalten (AEC erst drei Zyklen nach BA) ist im VIC festverdrahtet und läßt sich nicht umgehen. Trotzdem greift der VIC auf die Videomatrix zu, oder versucht es zumindest, denn solange AEC in der zweiten Taktphase noch High ist, sind die Adreßbustreiber und Datenbustreiber D0-D7 des VIC im Tri-State und der VIC liest statt der Daten aus der Videomatrix in den ersten drei Zyklen den Wert $ff an D0-D7. Die Datenleitungen D8-D13 des VIC haben allerdings keinen Tri-State-Treiber und sind immer auf Eingang geschaltet. Allerdings bekommt der VIC auch dort keine gültigen Farb-RAM-Daten, denn da AEC High ist, kontrolliert offiziell der 6510 noch den Bus und sofern dieser nicht zufällig gerade den nächsten Opcode vom Farb-RAM lesen will, ist der Chip-Select-Eingang des Farb-RAMs nicht aktiv. Stattdessen stellt ein 4-Bit Analogschalter (!), U16, eine Verbindung zwischen den Datenbits D0-D3 des Prozessors und den Datenbits D8-D13 des VIC her. Diese Verbindung besteht immer bei AEC High und soll dem Prozessor ggf. den Zugriff auf das Farb-RAM ermöglichen. Lange Rede, kurzer Sinn: Der VIC liest in den ersten drei Zyklen, nachdem BA auf Low gegangen ist als Zeichenzeiger $ff und als Farbinformation die untersten 4 Bit des Opcodes nach dem Zugriff auf $d011. Erst danach werden wieder reguläre Videomatrixdaten gelesen. Diese Daten werden ganz normal ab dem Anfang der internen Videomatrix-/Farbzeile abgelegt und nach jedem nachfolgenden g-Zugriff (mit dem Erzeugen der Bad Line wurde auch der Sequenzer in den Display-Zustand geschaltet) wird VC erhöht. Die c- und g-Zugriffe werden bis Zyklus 54 fortgesetzt. Dadurch, daß mit den Zugriffen aber erst mitten in der Zeile begonnen wurde, fanden weniger als 40 Zugriffe statt, also wurde auch VC insgesamt um weniger als 40 in dieser Rasterzeile erhöht und hat keinen durch 40 teilbaren Wert mehr, wie dies normalerweise am Ende einer Rasterzeile immer der Fall ist. Aufgrund der Arbeitsweise des VC (siehe Abschnitt 3.7.2.) setzt sich diese "Verstimmung" in allen folgenden Zeilen fort. Der ganze Bildinhalt erscheint dadurch nach rechts gerollt, und zwar um soviele Zeichen, wieviele Zyklen der $d011-Zugriff nach Zyklus 14 gemacht wurde. Da die c-Zugriffe innerhalb der Zeile erst später als in einer normalen Bad Line einsetzen, wird dieses Verfahren als "DMA-Delay" bezeichnet. Damit ist es möglich, den kompletten Bildschirm um große Distanzen seitlich zu verschieben (dies funktioniert mit Bitmap-Grafiken genauso wie mit Textschirmen, denn der VC wird auch zum Zugriff auf die Bitmap-Daten benutzt), ohne den Grafikspeicher mit dem Prozessor umkopieren zu müssen. Kombiniert man den DMA-Delay mit FLD und Linecrunch, ist es möglich, bildschirmfüllende Grafiken ohne nennenswerten Rechenzeitverbrauch um fast beliebig große Distanzen in alle Richtungen zu scrollen. Das Experimentieren mit dem DMA-Delay (und mit Bad-Line-Effekten generell) ist auch die beste Methode, die interne Funktionsweise des VIC, insbesondere von RC und VC, zu ergründen und zu bestimmen, in welchen Taktzyklen bestimmte Vorgänge im VIC ablaufen. Es sollte noch erwähnt werden, daß DMA-Delay nicht nur durch Manipulation von YSCROLL, sondern auch mit dem DEN-Bit aus Register $d011 erzielt werden kann. Dazu muß man YSCROLL auf Null setzen, damit Rasterzeile $30 zur ersten Bad Line wird und DEN mitten in Zeile $30 von gelöscht auf gesetzt schalten. Bad Lines können nämlich nur auftreten, wenn in Zeile $30 das DEN-Bit mindestens einen Zyklus lang gesetzt war, und wenn YSCROLL Null ist, tritt in Zeile $30 der Bad-Line-Zustand ein, sobald DEN gesetzt ist.