DEN C64'er AUSGEREIZT (Teil 2)
INTERRUPTKURS -------------
Lassen Sie uns das Wichtigste aus dem ersten Teil des Kurses zusammenfassen. a) Als erste Unterbrechungsanforderung ist der Assemblerbefehl BRK ganannt worden.Trifft der Prozessor auf solch einen Befehl, dann wird indirekt über die Adressen $0316 und $0317 ins Un- terbrechungsprogramm gesprungen. b) Als zweite Interrupt-Quelle wurden die beiden CIAs genannt. Ist IRQ-TIMER ($DC00) auf Interrupt programmiert, dann wird indirekt über die Adressen $0314/$0315 vezweigt. c) Der NMI-TIMER ($DD00) wird auch als Zwilling des IRQ-TIMERS bezeichnet und läßt sich auch auf die gleiche Weise programmieren. Der Unterschied besteht in der Art des Interrups.
IRQ und NMI -----------
Zu guter Letzt soll noch geklärt werden was hinter diesen unterschiedlichen Be- griffen steckt. IRQ (Interrupt ReQuest) Dies ist ein sogenannter maskierbarer Interrupt.Maskierbar heißt,daß per Soft- ware gesagt werden kann, ob er ausgelöst werden darf oder nicht. Das Abschalten erfogt durch den Assemblerbefehl SEI und das Einschalten durch CLI. NMI (Non Maskable Interrupt) Dieser Interrupt ist softwaremäßig nicht abschaltbar. Ein NMI-Interrupt wird aus- gelöst, durch Drücken der RESTORE-Taste oder durch den NMI-TIMER ($DD00). In beiden Fällen wird indirekt über die Adressen $0318 und $0319 gesprungen.
Der VIDEO-INTERRUPT -------------------
Ein Interrupt kann aber auch durch an- dere Ereignisse als durch den Ablauf eines Timers ausgelöst werden.
z.B. LIGHTPEN SPRITE-SPRITE-KOLLISION SPRITE-HINTERGUND KOLLISION RASTERZEILENINTERRUPT
Die ersten drei Interrupts sollen uns hier nicht weiter interessieren. Den RASTERINTERRUPT dagegen, könnte man ohne Übertreibung als ein Reservoir uner- schöpflicher Möglichkeiten bezeichnen. Wer die zahlreichen neuen Entwicklungen und Entdeckungen auf dem Softwaresektor seit 1985 mitverfolgt hat, der kann sich vorstellen wovon die Rede ist. Ich denke dabei besonders an die vielen Demos die seit Jahren den Public-Domain Markt unsicher machen. Einige dieser Werke sorgten sogar für weltweites Aufsehen. Man denke nur an das allgemeine Erstaunen, daß ein DEMO der 1001 CREW seinerzeit auslöste. Zum aller ersten Mal, seit der Herstellung des C64'er, hatte es jemand geschafft, den Bildschirmrand durch einen program- miertechnischen Trick auszuschalten und Graphiken auf der gesamten Bildschirm- fläche darzustellen. Diese Entdeckung löste eine einzigartige Experimentier- welle unter den Freaks aus, denn mit einem Schlag wurde klar, daß der C64'er doch etwas mehr zu bieten hatte, als aus dem mageren Handbuch ersichtlich war. Es gab zu der Zeit aber auch noch andere Programmierer(gruppen) wie die 1001CREW, die mit ihren Werken einen respektablen Bekanntheitsgrad erreichten. Hierzu ge- hörten schillernde Gestallten wie FLASH, S0DAN, THE JUDGES, THE CREAM CRACKERS, WOM, STAR FRONTIERS und MEANTEAM. Heutzutage sind es eher Gruppen wie HORIZON, UPFRONT und BEYOND FORCE, die versuchen durch eine immer raffinierter werdende Ausnutzung der Interrupttechnik an die Grenzen des guten alten C64'er zu stoßen. Und was da auf den Bildschirm gezaubert wird, stellt manchmal sogar AMIGA und ST in den Schatten. Einige der Routinen, die den erwähnten Gruppen zu Ruhm und Ehre verhalfen, werden in dieser und weiteren Ausgaben vorgestellt. Doch bevor wir uns auf die Programmierung von komplizierten Routinen stürzen,wollen wir anhand eines einfachen Beispiels die Funktionsweise der Raster-Unterbrechung erläutern.
DER RASTER-INTERRUPT --------------------
Wie Sie vieleicht wissen, wird das Bild auf dem Monitor oder dem Fernseher durch einen Elektronenstrahl erzeugt, der mit hoher Geschwindigkeit Rasterzeile für Rasterzeile abarbeitet. Ohne an dieser Stelle allzusehr in technische Einzel- heiten einzugehen, soll hier nur erwähnt werden, das sich der gesamte Bildschirm aus 312 Rasterzeilen zusammensetzt. Von disen 312 Rasterzeilen bilden 200 das Textfenster. Die restlichen 112 befinden sich im Rand oder unterhalb des Randes. Zwei Register des Video-Chips stehen mit dem Elektronenstrahl in direkter Verbin- dung: $D011 $D012 Es ist nun so, daß diese beiden Register eine DOPPELFUNKTION haben: a)Werden sie ausgelesen, dann erhällt man die aktuelle Rasterzeile, die ge- rade aufgebaut wird. b)Wird ein Wert hineingeschrieben, dann ist die so festgelegte Rasterzeile der Auslöser des IRQ. Bei $D011 ist nur Bit 7 von Bedeutung. Es stellt Hi-Byte des Rasterstrahls dar. In dem folgenden Programm, wird gleich an drei verschiedenen Stellen des Bild- schirms ein Rasterinterrupt ausgelöst.
;*** RASTER-DEMO 1 *** ;***** Initialisierung ***** 1000 SEI ;IRQ sperren 1001 LDA #$7F ;Timer-Interrupt 1003 STA $DC0D ;abschalten!!! 1006 LDA $DC0D ;ICR löschen 1009 LDA #$00 ;Rasterzeile $00 als 100B STA $d012 ;IRQ-Auslöser festlegen 100E LDA $D011 ;Bit 7 (Hi-Position) 1011 AND #$7F ;löschen 1013 STA $D011 1016 LDA #$01 ;Raster als IRQ-Quelle 1018 STA $D01A ;wählen 101B LDX #$27 ;IRQ-Vektor auf 101D LDY #$10 ;Interrupt Routine Nr.1 101F STX $0314 ;richten 1022 STY $0315 1025 CLI ;IRQ freigeben 1026 RTS ;***** ERSTER INTERRUPT ***** 1027 LDA #$70 ;RASTERZEILE $70 als 1029 STA $D012 ;IRQ-Auslöser festlegen 102c DEC $D019 ;IRR Register löschen 102F LDX #$44 ;IRQ-Vektor auf 1031 LDY #$10 ;RASTER-Routine Nr.2 1033 STX $0314 ;richten 1036 STY $0315 1039 LDA #$00 ;Rahmen- und 103B STA $D020 ;Hintergrundfarbe 103E STA $D021 ;auf schwarz setzen 1041 JMP $FEBC ;Return from Interrupt ;***** ZWEITER INTERRUPT ***** 1044 LDA #$C0 ;RASTERZELE $c0 als 1046 STA $D012 ;IRQ-Auslöser festlegen 1049 DEC $D019 ;IRR Register löschen 104C LDX #$61 ;IRQ-Vektor auf 104E LDY #$10 ;RASTER-Routine Nr.3 1050 STX $0314 ;richten 1053 STY $0315 1056 LDA #$02 ;Rahmen- und 1058 STA $D020 ;Hintergrundfarbe 105B STA $D021 ;auf rot setzen 105E JMP $FEBC ;Return from Interrupt ;***** DRITTER INTERRUPT ***** 1061 LDA #$00 ;RASTERZEILE $00 als 1063 STA $D012 ;IRQ-Auslöser festlegen 1066 DEC $D019 ;IRR Register löschen 1069 LDX #$27 ;IRQ-Vektor auf 106B LDY #$10 ;RASTER-Routine Nr.1 106D STX $0314 ;richten 1070 STY $0315 1073 LDA #$07 ;Rahmen- und 1075 STA $D020 ;Hintergrundfarbe 1078 STA $D021 ;auf gelb setzen 107B JMP $EA31 ;Return from Interrupt
Sobald Sie das Programm mit 'SYS 4096' starten, lösen die Rasterzeilen $00, $70 und $c0 fortlaufend Interrupte aus. Da jeder Interrupt dazu benutzt wird, Rahmen- und Hintergrundfarbe zu ändern, entsteht ein Effekt, der eine gewisse Ähnlichkeit mit der deutschen Fahne hat. Gleich zu Beginn der Initialisierung wird der Interrupt gesperrt(SEI) und der TIMER-IRQ abgeschaltet. Als nächstes müssen wir festlegen, daß RASTERZELE $00 Auslöser des erster Inte- rupts ist. Zu diesem Zweck schreibt man den Wert $0 in $d012 und löscht BIT 7 in $D011. Dieses BIT stellt die Hi-Position des Rasterstrahls dar und muß nur dann gesetzt werden, falls der IRQ irgendwo im untern Rand ausgelöst werden soll. Durch Löschen oder Setzen der BITS des Registers $D01A wird festgelegt, welches Ereignis IRQ-Auslöser sein soll.
BIT 0 ;RASTERINTERRUPT ($D012) BIT 1 ;SPRITE-HINTERGR.Koll. ($D01F) BIT 2 ;SPRITE-SPRITE Koll. ($D01E) BIT 3 ;LIGHTPEN sendet Impuls
Da wir uns für eine Unterbrechung durch den Rasterstrahl entschieden haben, muß der Wert $1 in $D01A geschrieben werden. Zu guter Letzt müssen wir wieder einmal den IRQ-Vektor $0314/0315 umstellen. Nun müssen wir aber aufpassen, denn die gleichen Adressen werden auch vom TIMER- IRQ als Sprungvektoren benutzt. Hätten wir den Timer-IRQ nicht abgestellt, so würden beide Interrupts abwechselnd und völlig unkontrolliert dieselbe Routine anspingen. Das Ergebnis wäre ein totales Durcheinander,gefolgt von einem Absturz. Damit wären fast alle Vorbereitungen getroffen. Der Rest liegt nun ganz bei unserer IRQ-Routine die an Adresse $1027 beginnt. Sobald der Elektronenstrahl mit Raster- zeile $00 in Berührung kommt, wird der erste Interrupt ausgelöst und die CPU führt das Programm an Adresse $1027 aus. Die folgende Beschreibung gilt für alle Routinen die durch einen RASTERINTERRUPT angesprungen werden: 1) Als erstes wird die neue Rasterzeile festgelegt, die als nächstes Interrupt auslösen soll. 2) IRQ-Request-Register ($D019) löschen. Falls der Interrupt durch den Raster ausgelöst wurde, ist BIT 7 gesetzt. Das Löschen erfolgt, indem man das Register ausliest und den selben Wert gleich wieder zurückschreibt. z.B. LDA $D019 STA $D019 oder einfacher: DEC $D019 3) Will man mehrere Interrupte der Reihe nach auslösen, dann muß der IRQ-Vektor erneut umgestellt werden. 4) Erst jetzt kommt die eigentliche Auf- gabe der Unterbrechung. In unserem Beispiel ändern wir nur die Farben. Sie können aber auch genau so gut eine Musik- oder eine Joystick-Routine an- springen. 5) Die Unterbrechung wird abgeschlossen durch einen Sprung zum Ende der nor- malen IRQ-Routine. Unser erstes Rasterdemo besteht aus 3 kurzen Routinen die der Reihe nach ange- sprungen werden und somit den Bildschirm in 3 Farbzonen einteilen. Theoretisch könnte man beliebig viele Routinen anei- nander reihen und so den Bildschirm in allen Farben schillern lassen. Die folgenden Befehle geben dem Benutzer die Möglichkeit die Routine wieder abzu- schalten. Start mit SYS4140
SEI ;IRQ sperren LDA #$81 ;Timer-IRQ STA $DC0D ;einschalten LDA #$00 ;Raster-IRQ STA $D01A ;abschlten LDX #$31 ;IRQ-Vektor LDY #$EA ;auf ursprünglichen STX $0314 ;Wert setzen STY $0315 CLI ;IRQ freigeben RTS
Der Rasterinterrupt erlaubt aber noch eine große Anzahl weiterer Effekte. Ver- suchen sie doch mal Text mit Hochauf- lösender Graphik zu mischen oder mehrere Zeichensätze auf einmal darzustellen. Selbst die Darstellung von mehr als acht Sprites gleichzeitig oder das Scrollen von einzelnen Bildschirmteilen lassen sich nun (fast) problemlos realisieren. Als nächstes wollen wir uns wieder ein- mal mit Farbeffekten befassen und auch eine Spezialroutine vorstellen. Wer sich unter 'RASTER-PROGRAMMIERUNG' nichts konkretes vorstellen kann, sollte sollte am besten gleich 'RASTER-DEMO 2' einladen und und mit SYS4096 starten. Diese interessanten Farbverläufe, wie sie in fast allen DEMOS der letzten Zeit geboten werden, nennt man RASTEREFFEKTE. Sie entstehen durch Ändern von Rahmen- und Hintergrundfarbe zu Beginn jeder Rasterzeile. Mit dem nun folgenden Source-Listing ist es möglich solche Rastereffekte auf ganz einfache Weise zu programmieren.
;*** RASTER-DEMO 2 *** 1000 SEI ;IRQ sperren 1001 LDA #$7F ;Timer-Interrupt 1003 STA $DC0D ;abschalten!!! 1006 LDA $DC0D ;ICR löschen 1009 LDA #$82 ;Rasterzeile $82 als 100B STA $d012 ;IRQ-Auslöser festlegen 100E LDA $D011 ;Bit 7 (Hi-Position) 1011 AND #$7F ;löschen 1013 STA $D011 1016 LDA #$01 ;Raster als IRQ-Quelle 1018 STA $D01A ;wählen 101B LDX #$27 ;IRQ-Vektor auf 101D LDY #$10 ;Interrupt Routine Nr.1 101F STX $0314 ;richten 1022 STY $0315 1025 CLI ;IRQ freigeben 1026 RTS ;--------------------------------------- 1027 LDA #$82 ;RASTERZEILE $82 als 1029 STA $D012 ;IRQ-Auslöser festlegen 102C LDA #$1B 102E STA $D011 1031 DEC $D019 ;IRR Register löschen 1034 LDX #$27 ;IRQ-Vektor 1036 LDY #$10 ;auf sich selbst 1038 STX $0314 ;richten 103B STY $0315 103E NOP 103F LDY #$00 ;ZEILENZÄHLER 1041 LDX #$08 ;CHARACTER-ZÄHLER 1043 LDA $1100,Y ;Farbwert aus Tabelle 1046 STA $D020 ;Rahmen- und 1049 STA $D021 ;Hintergrund ändern 104C INY ;ZEILENZÄHLER+1 104D DEX ;CHARACTER-ZEILE ? 104E BEQ 1041 ;JA? Dann neue Farbe 1050 LDA $1026 ;Sonst verzögern 1053 JSR $1026 1056 JSR $1026 1059 JSR $1026 105C CPY #$48 ;Routine beenden 105E BCC 1043 ;NEIN?? dann neue Farbe 1060 LDA #$0E ;Sonst IRQ beenden 1062 STA $D020 1065 LDA #$06 1067 STA $D021 106A JMP $EA31 ;Sprung zum IRQ-Ende
Um das obige Listing zu verstehen, ist es unbedingt notwendig, sich mit einigen technischen Besonderheiten des VIC-Chips und des CPU auseinander zu setzen. Um einen Assembler-Befehl auszuführen, braucht der Prozessor eine gewisse Zeit. Diese Zeit wird in TAKTZYKLEN gemessen. Ein Befehl benötigt in der Regel 2 bis 7 Taktzyklen. Einige 'Illegalen-Opcodes' benötigen sogar 8 Taktzyklen. Zuvor haben wir erfahren, daß das Bild auf dem Monitor oder Fernseher von einem Elektronenstrahl erstellt wird. Dies ge- schied mit großer Geschwindigkeit, denn immerhin wird das Bild 20mal pro Sekunde erneuert. Um eine einzige Rasterzeile zu zeichnen, "vergehen" im Normalfall genau 63 Takt- zyklen. Man müßte eigentlich nur eine Schleife in Maschinensprache schreiben, die alle 63 Taktzyklen die Bildfarben ändert.Das alles klingt schon wahnsinnig kompliziert, aber es wird gleich noch komplizierter.Der Haken ist nämlich der, daß der Prozessor in regelmäßigen Ab- ständen unterbrochen wird und deshalb ungleichmäßig läuft. Diese Unterbrechung erfolgt jedesmal durch den VIC-Chip,der eine gewisse Zeit benötigt, um die CHARACTER-ZEILEN zu re- generieren. Diese Unterbrechung erfolgt jede achte Rasterzeile und jedesmal am Anfang einer CHARACTER-ZEILE für genau 42 Taktzyklen. Mit diesen Informationen ist es uns nun möglich, den Ablauf des Source-Listings nachzuvollziehen. In der Initialisierung wird Rasterzeile $82 als IRQ-Auslöser festgelegt. Von nun an laufen alle IRQs über unsere eigene Routine die bei $1027 beginnt. Da es in diesem Beispiel nur eine ein- zige Routine gibt, die fortlaufend an- gesprungen wird, ist es erforderlich,die Vektoren jedesmal auf sich selbst zu richtenen. Da wir inzwischen wissen,daß jede achte Rasterzeile ein besonderes 'TIMING' er- fordert, haben wir einfach das Prinzip der GESCHACHTELTEN-SCHLEIFEN angewand. Das Y-Register ist der Zähler für die Anzahl der RASTERZEILEN die durchlaufen werden. Das X-Register ist eine Art Indikator für alle Rasterzeilen mit gesondertem Timing, daß in jeder Rasterzeile um den Wert 1 verringert wird. Ist der Wert 0 erreicht worden(ZERO-FLAG wird gesetzt), so erfolgt ein Rücksprung an die Adresse $1041. Die so entstandene Schleife hat genau 21 Taktzyklen. Sollte das X-Register den Wert 0 noch nicht erreicht haben, so wird die Lauf- zeit um 42 Taktzyklen verlängert. Bei Adresse $1000 wird das Y-Register mit der Anzahl der Rasterzeilen die dar- gestellt werden verglichen. Ist der Wert größer, dann erfolgt ein Sprung zum IRQ Ende. Die Routine erlaubt noch einige Experi- mente.Aus Adresse $1043 ist ersichtlich, daß sämtliche Farbwerte aus der Tabelle bei $105C geholt werden (LDA $1100,Y). Wollen sie andere Farben darstellen, dann müssen Sie mit einem Monitor die Zahlenwerte in dieser Tabelle ändern. Besonders gut -finde ich- sieht das Ganze aus, wenn man sehr weiche Farbver- läufe darstellt und diese zusätzlich noch bewegt werden. Sie sehen, der Raster-Interupt ist ein sehr interessantes Spielzeug, das eine Fülle von Varriationen zu bieten hat.
(IVO HERZEG)