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)