Spiele-Kurs für Assemblerprogrammierer
(Teil 4)

64'er, Ausgabe 9/September 1989

Sprites sind die wichtigsten Elemente eines Spiels. Ohne sie wäre der Bildschirm »leblos«. Lernen Sie, mit Sprites Bewegung ins Computerbild zu bringen.

Wer schon mit Sprites gearbeitet hat, denkt vielleicht, die Programmierung sei ganz einfach, weil der VIC alle Funktionen zur Verfügung stellt. Dem ist nicht ganz so, denn es wird reger Gebrauch von Rasterzeilen-IRQs gemacht. Wer Teil 2 und 3 dieses Kurses studiert hat, kann hier sein Wissen voll anwenden. Grundlegende Kenntnisse der Spriteprogrammierung werden vorausgesetzt. Sie sollen also zumindest in Basic einmal ausprobiert haben, Sprites zu definieren und auf dem Bildschirm darzustellen. Verfügen Sie nicht über diese Kenntnisse, empfiehlt sich das 64'er-Sonderheft Nr. 20. Dort wird genau auf die Programmierung von Sprites eingegangen.

Sehen wir uns zunächst die einfache Bewegung eines Sprites näher an. Sie ist die Grundlage jedes Spiels und zum Beispiel dafür verantwortlich, daß ein Raumschiff über den Bildschirm gleitet. Sprites bewegt man, indem man die Register der X-/Y-Koordinate (Gültigkeitsbereiche siehe Bild 1) kontinuierlich hoch- oder herunterzählt. (inkrementiert bzw. dekrementiert). Es stellt sich allerdings ein Problem: Bewegt man Sprites in Maschinensprache vom Hauptprogramm aus, so sind unbedingt Warteschleifen erforderlich. Der Computer wäre dann aber vorwiegend damit beschäftigt, nichts zu tun, und für das Spiel hätte er keine Zeit mehr. Aus diesem Grunde programmiert man Spritebewegungen im IRQ. Probieren wir es zunächst im System-IRQ aus. Tippen Sie hierfür Listing 1 ein und starten Sie es mit SYS 49152.

Bild 1. Die Spritekoordinaten der Grenzpositionen. Wird ein Sprite auf X = 0 und Y = 0 gesetzt, liegt es außerhalb des sichtbaren Bereiches. Mit den Koordinaten X = 24 und Y= 50 erscheint es in der linken oberen Ecke des Bildschirms.

Es bewegt sich nun ein Sprite von links nach rechts, dessen Geschwindigkeit Sie durch POKE 56325,Wert beeinflussen können. Sie verändern mit diesem POKE-Befehl die Häufigkeit der IRQs, die durch den CIA 1 ausgelöst werden.

Spritebewegungen

Das Programm selber ist ohne weitere Erklärungen verständlich, da alle Befehle in diesem Kursteil bzw. in Teil 2 behandelt wurden.

Wie Sie sehen, erzielt man mit dieser Methode keine besonders guten Ergebnisse. Zum einen ist die Bewegung nicht fließend, zum anderen wird das Sprite »zerrissen«, wenn Sie den IRQ schnell einstellen (kleine Wert in die Speicherzelle 56325 schreiben).

Dies kommt durch das schlechte Timing zustande. Es kann passieren, daß der Rasterstrahl zweimal über das Sprite läuft, obwohl nur einmal die Position geändert wurde. Es kann aber auch geschehen, daß der Rasterstrahl nur einmal über das Sprite läuft, obwohl schon mehrmals die Position geändert wurde. Dadurch kommt die unruhige Bewegung zustande. Ferner ist es möglich, daß die Koordinaten gerade in dem Moment verändert werden, wenn der Rasterstrahl dabei ist, das Sprite darzustellen. Die erste Hälfte wird mit der alten, die zweite mit der neuen Position dargestellt. Man erhält den Eindruck eines »zerrissenen« Sprites (Bild 2).

Bild 2. Ein Sprite wird bewegt, während der Rasterstrahl es darstellt. Es wird dadurch scheinbar »zerrissen«.

Rasterstrahlen-IRQs lösen dieses Problem.

Löst man immer bei Rasterzeile 0 einen IRQ aus, in dessen IRQ-Routine die Sprite-Koordinaten verändert werden, ist zum einen sichergestellt, daß pro Bildschirmaufbau genau einmal die Position verändert wird, und zum anderen, daß das Sprite erst nach der erneuten Positionierung vom Rasterstrahl dargestellt wird. Natürlich muß der System-IRQ inaktiviert und vom Raster-IRQ abgewickelt werden (vlg. Teil 2).

In Listing 2 wird von der hier beschriebenen Methode Gebrauch gemacht. Wie Sie sehen, ist die Bewegung nun fließend und flimmerfrei.

Man ist jetzt auch in der Lage, mehrere Sprites gleichzeitig zu bewegen, was in Basic aufgrund der geringen Laufgeschwindigkeit nicht möglich ist.

Auch kann man durch Überlagern von mehreren Single-Color-Sprites ein Multicolor-Sprite mit hoher Auflösung simulieren und dieses dann bewegen. Positioniert man mehrere Sprites nebeneinander, erhält man ein »Compound-Sprite« (ein aus mehreren Sprites zusammengesetzes Objekt).

Schießlich ist es nun auch möglich, ein oder mehrere Sprites mit dem Joystick zu »koppeln«. Man liest in der IRQ-Routine das Joystickregister aus und legt dann die Richtung fest, in die sich das Sprite bewegen soll. Dies wurde im Programm »SPRITE-CONNECT« (Listing 3) getan. Tippen Sie es mit dem MSE ein. Starten Sie es mit SYS 49152, so wird Sprite 0, das vorher bereits aktiviert sein muß, mit dem Joystick in Port 2 »verbunden«. Durch eingebaute Legalitätskontrollen wird sichergestellt, daß das Sprite nicht über die Grenzen des darstellbaren Bildschirmes hinausläuft. Durch POKE 49393,Wert können Sie die Geschwindigkeit variieren, genauer gesagt, die Schrittweite, mit der sich das Sprite über den Bildschirm bewegt.

WICHTIG: Sie können das Programm auch downloaden

Sprite-Animation

Eine Animation entspricht von der Programmstruktur her einer Spritebewegung. Nur wird hier nicht die Position des Sprites, sondern der Wert des Spritepointers, also sein Inhalt, verändert. Hierdurch bekommt das Sprite ständig ein anderes Aussehen. Stehen zum Beispiel im Block 128 bis 130 die Spritedaten einer Animationssequenz und zählt man den Spritepointer ständig zwischen den Werten 128 und 130 herauf und herunter, so entsteht der Eindruck einer fließenden Formveränderung. Auch hier erhält man eine fließende und flimmerfreie Bewegung nur dann, wenn die IRQ-Routine vom Rasterzeilen-IRQ gesteuert wird.

Tippen Sie Listing 4 ein und starten es mit SYS 49152. Das Programm belegt acht Spriteblocks mit Bitmustern. Anschließend wird regelmäßig zwischen diesen Spriteblocks umgeschaltet.

Wie Sie sehen, hat sich Listing 4 gegenüber Listing 2 nicht wesentlich verändert. Lediglich die Routine, die die Spritedaten generiert, wurde modifiziert. Ferner wird anstelle der Spriteposition der Spritepointer inkrementiert bzw. dekrementiert. Verändern Sie den Wert in Zeile 790, so läßt sich die Animationsgeschwindigkeit variieren. Setzen Sie zum Beispiel eine 2 ein, so wird nur bei jedem zweiten IRQ der Spritepointer verändert.

Mit den Kenntnissen über Spritebewegung und -animation sollte es Ihnen nun möglich sein, Ihre ersten Spieleversionen in Basic von Maschinensprache aus zu unterstützen. Selbstverständlich lassen sich Animation und Bewegung auch gleichzeitig abwickeln. Versuchen Sie doch einmal durch Ergänzung des Listings 4 mit der IRQ-Routine aus Listing 2 ein animiertes und bewegtes Sprite zu zaubern.

Der VIC bietet die Möglichkeit, bei Kollisionen zwischen zwei Sprites oder zwischen Sprite und Hintergrund einen IRQ auszulösen. Sehen Sie sich Listing 5 an. Dieses Programm gibt einen VIC-IRQ für Sprite/Hintergrund-Kollisionen frei. Starten Sie das Programm mit SYS 49152, erscheint ein Sprite in der Mitte des Bildschirms. Schreiben Sie nun per Tastatur ein Zeichen unter das Sprite, so verändert sich das linke obere Zeichen des Bildschirms so lange, bis das Zeichen wieder gelöscht wurde. Zu beachten ist hierbei, daß nicht nur das IRQ-Requestregister (sowohl bei der Initialisierung als auch in der IRQ-Routine) durch Auslesen und Rückschreiben gelöscht werden muß, sodern auch das Sprite-Hintergrund-Kollisionsregister VIC+31. Dies geschieht durch einfaches Auslesen. Eine Programmierung von Sprite-Sprite-Kollisionen erfolgt analog, mit der einzigen Ausnahme, daß Sie in das IRQ-Maskenregister den Wert 132 (128+4) schreiben und statt der Sprite-Hintergrund-Kollisionsregister das Sprite-Sprite-Kollisionsregister VIC+30 auslesen müssen.

Sprite-Kollisionen

Leider läßt sich diese Kollisionserkennung nicht für anspruchsvolle Spiele nutzen, aus folgendem Grund:

Wie Sie sehen, wird so lange ein IRQ ausgelöst, bis die Kollision aufgehoben wurde, entweder duch Abschalten des Sprites oder durch Löschen des beziehungsweise der Zeichen, mit denen das Sprite kollidiert. Das ist in den meisten Spielen unerwünscht, da nur einmal pro Kollision eine Reaktion ausgelöst werden soll. Eine naheliegende Lösung wäre:

Man speichert immer den alten Wert des Kolllisionsregisters zwischen, und wenn ein Kollisions-IRQ auftritt, wird der aktuelle Wert des Kollisionsregister mit dem zwischengespeicherten Wert verglichen. Sind die beide Werte verschieden, so hat sich irgendetwas getan, und es wird eine Reaktion ausgeführt. Beim Initialisieren wird der Zwischenspeicher mit einer 0 belegt. Was passiert nun, wenn ein Sprite mit einem Zeichen kollidiert und einen Kollisions-IRQ ausgelöst hat? Jetzt wird nur einmal eine Reaktion ausgeführt, weil alle folgenden IRQs durch den Vergleich abgefangen werden, da sich der Inhalt des Kollisionsregister nach der Kollision nicht verändert hat. Nun ist das Sprite über das Zeichen hinweg gelaufen. Im Zwischenspeicher steht jetzt der Wert, den das Kollisionsregister zum Zeitpunkt der Kollision enthielt. Kollidiert das Sprite erneut, wird das Kollisionsregister mit dessen altem Wert verglichen und da beide identisch sind, wird nun keine Reaktion mehr ausgelöst!

Wenn der VIC auch beim Verschwinden einer Kollision einen spezifischen IRQ auslösen würde, könnte man den Zwischenspeicher per IRQ wieder auf Null setzen, und alles wäre in bester Ordnung. Leider kann der VIC dies nicht, und man muß sich daher per Programm durch Vergleichen der Sprite- und Zeichenkoordinaten um die Reinitialisierung des Zwischenspeichers kümmern. Damit geht aber der Vorteil der IRQ-Ausnutzung leider gänzlich verloren.

Da es meistens erwünscht ist, daß die kollidierten Sprites auch nach der Kollision noch eingeschaltet bleiben, ist der oben beschriebene Weg der Kollisionserkennung nicht zufriedenstellend.

Es bietet sich jedoch eine ähnliche Methode an, die allerdings keinen Gebrauch von Kollisions-IRQ macht: Da bei Spielen fast immer irgendeine IRQ-Quelle eingeschaltet ist, kann man in die zugehörige IRQ-Routine eine permanente Abfrage der Kollisionsregister einhängen. Man läßt nur dann eine Reaktion zu, wenn ein Bit in diesem Register zusätzlich gesetzt wurde. Wenn das Register erst eine 0 enthielt, dannach eine 1, da Sprite 0 kollidiert ist, wird eine Reaktion ausgelöst. Verändert sich das Register wieder, es wird zum Beispiel aus der 1 wieder eine 0, so erfolgt keine Reaktion.

Nun haben wir umfassende Kenntnisse zum Thema Spritebewegung, -animation und -kollision. Im nächsten Teil lesen Sie, wie Sie sich eigene Zeichensätze erstellen und diese in eigenen Spielen verwenden können.

(H. Rosenfeld/mf)

  Listing 1 zeigt eine Spritebewegung ohne Berücksichtigung des Rasterstrahls
(download Quellcode in Hypra-Ass Format)
 
10   -.BA 49152                ;START = 49152
20   -.GL VIC    = $D000       ;VIC BASISADRESSE
30   -.GL IRQVEC = $0314       ;IRQ-VEKTOR
40   -.GL IRQALT = $EA31       ;ALTE IRQ-ROUTINE
200  -INIT       JSR MAKESPR   ;SPRITE GENERIEREN
210  -           SEI           ;IRQ SPERREN
220  -           LDA #<(IRQNEU);IRQ-VEKTOR AUF IRQNEU STELLEN
230  -           LDX #>(IRQNEU)
240  -           STA IRQVEC
250  -           STX IRQVEC+1
260  -           CLI           ;IRQ ZULASSEN
270  -           RTS           ;UND ZURUECK...
280  -;
290  -MAKESPR    LDX #62       ;SPRITE-DATEN NACH BLOCK 32
300  -           LDA #255      ;(2048-2110)
310  -MAKELOOP   STA 2048,X
320  -           DEX
330  -           BPL MAKELOOP
340  -           LDA #32       ;BLOCK 32 FESTLEGEN
350  -           STA 2040
360  -           LDA #0        ;SINGLECOLOR-MODUS
370  -           STA VIC+28
380  -           LDA #1        ;SPRITE 0 = WEISS
390  -           STA VIC+39
400  -           LDA #0
410  -           STA VIC+29    ;KEINE X-VERGROESSERUNG
420  -           STA VIC+23    ;KEINE Y-VERGROESSERUNG
430  -           STA VIC       ;X-KOORDINATE = 0
440  -           STA VIC+16
450  -           LDA #140      ;Y-KOORDINATE = 140
460  -           STA VIC+1
470  -           LDA #1        ;SPRITE 0 EINSCHALTEN
480  -           STA VIC+21
490  -           RTS           ;UND ZURUECK...
500  -;
510  -IRQNEU     INC VIC       ;LO-BYTE DER X-KOORDINATE
520  -           BEQ INCHI     ;ERHOEHEN- IST ES 0, DANN INCHHI
530  -           LDA VIC       ;LO-BYTE GROESSER ALS 120 ?
540  -           CMP #120
550  -           BCC IRQRET    ;NEIN, DANN IRQ BEENDEN
560  -           LDA VIC+16    ;JA, DANN HI-BYTE = 1 ?
570  -           AND #1
580  -           BEQ IRQRET    ;NEIN, DANN IRQ BEENDEN
590  -           LDA #0        ;JA, DANN X-KOORDINATE = 0
600  -           STA VIC
610  -           STA VIC+16
620  -IRQRET     JMP IRQALT    ;ZUR ALTEN IRQ-ROUTINE
630  -INCHI      INC VIC+16    ;HI-BYTE ERHOEHEN
640  -           JMP IRQRET    ;IRQ BEENDEN

READY.
 
  Listing 2 erzeugt eine flimmerfreie Spritebewegung durch Berücksichtigung des Rasterstrahls
(download Quellcode in Hypra-Ass Format)
 
10   -.BA 49152                ;START = 49152
20   -.GL VIC    = $D000       ;VIC BASISADRESSE
30   -.GL IRQVEC = $0314       ;IRQ-VEKTOR
40   -.GL IRQALT = $EA31       ;ALTE IRQ-ROUTINE
50   -.GL RASTER = VIC+18      ;RASTERZEILEN-REGISTER
60   -.GL IRQMASK= VIC+26      ;IRQ-MASKENREGISTER
70   -.GL IRQFLAG= VIC+25      ;IRQ-REQUESTREGISTER
80   -.GL HIBIT  = VIC+17      ;HI-BIT VOM RASTERREGISTER
90   -.GL CIATIME= $DC0E       ;CIA-TIMER-STEUERREGISTER
200  -INIT       JSR MAKESPR   ;SPRITE GENERIEREN
210  -           SEI           ;IRQ SPERREN
220  -           LDA #0        ;RASTER-IRQ BEI ZEILE 0
230  -           STA RASTER
240  -           LDA HIBIT
250  -           AND #127
260  -           STA HIBIT
270  -           LDA #129      ;RASTER-IRQ MASKIEREN
280  -           STA IRQMASK
290  -           LDA CIATIME   ;CIA-TIMER AUSSCHALTEN
300  -           AND #254
310  -           STA CIATIME
320  -           LDA #<(IRQNEU);IRQ-VEKTOR AUF IRQNEU STELLEN
330  -           LDX #>(IRQNEU)
340  -           STA IRQVEC
350  -           STX IRQVEC+1
360  -           LDA IRQFLAG   ;IRQ-REQUESTREGISTER
370  -           STA IRQFLAG   ;LOESCHEN
380  -           CLI           ;IRQ ZULASSEN
390  -           RTS           ;UND ZURUECK...
400  -;
410  -MAKESPR    LDX #62       ;SPRITE-DATEN NACH BLOCK 32
420  -           LDA #255      ;(2048-2110)
430  -MAKELOOP   STA 2048,X
440  -           DEX
450  -           BPL MAKELOOP
460  -           LDA #32       ;BLOCK 32 FESTLEGEN
470  -           STA 2040
480  -           LDA #0        ;SINGLECOLOR-MODUS
490  -           STA VIC+28
500  -           LDA #1        ;SPRITE 0 = WEISS
510  -           STA VIC+39
520  -           LDA #0
530  -           STA VIC+29    ;KEINE X-VERGROESSERUNG
540  -           STA VIC+23    ;KEINE Y-VERGROESSERUNG
550  -           STA VIC       ;X-KOORDINATE = 0
560  -           STA VIC+16
570  -           LDA #140      ;Y-KOORDINATE = 140
580  -           STA VIC+1
590  -           LDA #1        ;SPRITE 0 EINSCHALTEN
600  -           STA VIC+21
610  -           RTS           ;UND ZURUECK...
620  -;
630  -IRQNEU     LDA IRQFLAG   ;IRQ-RASTERREGISTER
640  -           STA IRQFLAG   ;LOESCHEN
650  -           INC VIC       ;LO-BYTE DER X-KOORDINATE
660  -           BEQ INCHI     ;ERHOEHEN- IST ES 0, DANN INCHHI
670  -           LDA VIC       ;LO-BYTE GROESSER ALS 120 ?
680  -           CMP #120
690  -           BCC IRQRET    ;NEIN, DANN IRQ BEENDEN
700  -           LDA VIC+16    ;JA, DANN HI-BYTE = 1 ?
710  -           AND #1
720  -           BEQ IRQRET    ;NEIN, DANN IRQ BEENDEN
730  -           LDA #0        ;JA, DANN X-KOORDINATE = 0
740  -           STA VIC
750  -           STA VIC+16
760  -IRQRET     JMP IRQALT    ;ZUR ALTEN IRQ-ROUTINE
770  -INCHI      INC VIC+16    ;HI-BYTE ERHOEHEN
780  -           JMP IRQRET    ;IRQ BEENDEN

READY.
 
  Listing 3 koppelt Sprite 0 mit dem Joystick an Port 2
(Sie können dieses File auch downloaden)
 
Name : sprite-connect    c000 c0f2
----------------------------------
c000 : 78 a9 00 8d 12 d0 ad 11  7f
c008 : d0 29 7f 8d 11 d0 a9 81  40
c010 : 8d 1a d0 ad 0e dc 29 fe  ff
c018 : 8d 0e dc a9 2d a2 c0 8d  1f
c020 : 14 03 8e 15 03 ad 19 d0  a0
c028 : 8d 19 d0 58 60 ad 19 d0  fa
c030 : 8d 19 d0 ad 00 dc 29 0f  dd
c038 : aa bd cf c0 8d ef c0 bd  a4
c040 : df c0 8d f0 c0 ad ef c0  bb
c048 : 30 4d d0 27 ad 00 d0 c9  ea
c050 : 19 b0 07 ad 10 d0 29 01  67
c058 : f0 3d ad 10 d0 29 01 aa  04
c060 : 38 ad 00 d0 ed f1 c0 8d  15
c068 : 00 d0 8a e9 00 20 be c0  2e
c070 : 4c 97 c0 ad 00 d0 c9 41  9e
c078 : 90 07 ad 10 d0 29 01 d0  f5
c080 : 16 ad 10 d0 29 01 aa 18  00
c088 : ad 00 d0 6d f1 c0 8d 00  72
c090 : d0 8a 69 00 20 be c0 ad  56
c098 : f0 c0 30 1f d0 10 ad 01  1f
c0a0 : d0 c9 32 90 16 ed f1 c0  0e
c0a8 : 8d 01 d0 4c bb c0 ad 01  ee
c0b0 : d0 c9 e6 b0 06 6d f1 c0  4a
c0b8 : 8d 01 d0 4c 31 ea 48 ad  6a
c0c0 : 10 d0 29 fe 8d 10 d0 68  d0
c0c8 : 0d 10 d0 8d 10 d0 60 80  cd
c0d0 : 80 80 80 80 01 01 01 80  de
c0d8 : 00 00 00 80 80 80 80 80  f8
c0e0 : 80 80 80 80 01 00 80 80  e4
c0e8 : 01 00 80 80 01 00 80 00  2c
c0f0 : 00 04 00 00 ff ff 00 00  f2
 
  Listing 4 zeigt eine Sprite-Animation, die durch Umschalten des Spritepointers erzeugt wird. Probieren Sie, es mit Listing 2 zu kombinieren!
(download Quellcode in Hypra-Ass Format)
 
10   -.BA 49152                ;START = 49152
20   -.GL VIC    = $D000       ;VIC BASISADRESSE
30   -.GL IRQVEC = $0314       ;IRQ-VEKTOR
40   -.GL IRQALT = $EA31       ;ALTE IRQ-ROUTINE
50   -.GL RASTER = VIC+18      ;RASTERZEILEN-REGISTER
60   -.GL IRQMASK= VIC+26      ;IRQ-MASKENREGISTER
70   -.GL IRQFLAG= VIC+25      ;IRQ-REQUESTREGISTER
80   -.GL HIBIT  = VIC+17      ;HI-BIT VOM RASTERREGISTER
90   -.GL CIATIME= $DC0E       ;CIA-TIMER-STEUERREGISTER
100  -.GL JOYSTICK=56320       ;JOYSTICK PORT 2
200  -INIT       SEI           ;IRQ SPERREN
210  -           JSR MAKESPR   ;SPRITES GENERIEREN
220  -           LDA #0        ;RASTER-IRQ BEI ZEILE 0
230  -           STA RASTER
240  -           LDA HIBIT
250  -           AND #127
260  -           STA HIBIT
270  -           LDA #129      ;RASTER-IRQ MASKIEREN
280  -           STA IRQMASK
290  -           LDA CIATIME   ;CIA-TIMER AUSSCHALTEN
300  -           AND #254
310  -           STA CIATIME
320  -           LDA #<(IRQNEU);IRQ-VEKTOR AUF IRQNEU STELLEN
330  -           LDX #>(IRQNEU)
340  -           STA IRQVEC
350  -           STX IRQVEC+1
360  -           LDA IRQFLAG   ;IRQ-REQUESTREGISTER
370  -           STA IRQFLAG   ;LOESCHEN
380  -           CLI           ;IRQ ZULASSEN
390  -           RTS           ;UND ZURUECK...
400  -;
410  -MAKESPR    LDA #<(2048)  ;POINTER AUF 2048
420  -           LDX #>(2048)
430  -           STA LOOP+1
440  -           STX LOOP+2
450  -           LDX #62       ;62 INS X-REGISTER
460  -           LDY #8        ;8 EINZEL-SPRITES
470  -           LDA #254      ;SPRITE 1 BITMUSTER %11111110
480  -LOOP       STA 65535,X   ;SPRITE X MIT BITMUSTER
490  -           DEX           ;BELEGEN
500  -           BPL LOOP
510  -           PHA           ;AKKU MERKEN
520  -           CLC           ;POINTER UM 64 AUFADDIEREN
530  -           LDA LOOP+1
540  -           ADC #64
550  -           STA LOOP+1
560  -           LDA LOOP+2
570  -           ADC #0
580  -           STA LOOP+2
590  -           LDX #62       ;ERNEUT 62 INS X-REGISTER
600  -           PLA           ;AKKU ZURUECKHOLEN
610  -           SEC           ;CARRY SETZEN
620  -           ROL           ;UND 'HINEINROTIEREN'
630  -           DEY           ;Y-DEKREMENTIEREN
640  -           BNE LOOP      ;UNGLEICH NULL, DANN WEITER
650  -           LDA #32       ;SONST SPRITE-POINTER
660  -           STA 2040      ;BELEGEN
670  -           LDA #1        ;SPRITE 0 = WEISS
680  -           STA VIC+39
690  -           LDA #100      ;SPRITE 0 KOORDINATEN 100:100
700  -           STA VIC
710  -           STA VIC+1
720  -           LDA #1        ;SPRITE 0 EINSCHALTEN
730  -           STA VIC+21
740  -           RTS           ;UND ZURUECK...
750  -IRQNEU     LDA IRQFLAG   ;IRQ-STEUERREGISTER LOESCHEN
760  -           STA IRQFLAG
770  -           DEC WART      ;WARTE-SCHLEIFE ERNIEDRIGEN
780  -           BNE IRQRET    ;UNGLEICH 0, DANN IRQ BEENDEN
790  -           LDA #5        ;SONST WARTESCHLEIFE NEU
800  -           STA WART      ;BELEGEN
810  -           LDA DIRECT    ;WENN ZAEHLRICHTING = 0,
820  -           BEQ UP        ;DANN NACH 'UP'
830  -DOWN       DEC 2040      ;SONST SPRITE-POINTER
840  -           LDA 2040      ;HERUNTERZAEHLEN UND MIT
850  -           CMP #31       ;31 VERGLEICHEN
860  -           BNE IRQRET    ;UNGLEICH, DANN ENDE
870  -           LDA #0        ;SONST ZAEHLRICHTUNG = UP
880  -           STA DIRECT
890  -UP         INC 2040      ;SPRITE-POINTER ERHOEHEN
900  -           LDA 2040      ;MIT 40 VERGLEICHEN
910  -           CMP #40
920  -           BNE IRQRET    ;UNGLEICH, DANN ENDE
930  -           LDA #1        ;ZAEHLRICHTING = DOWN
940  -           STA DIRECT
950  -           JMP DOWN      ;NACH 'DOWN'
960  -IRQRET     JMP IRQALT    ;IRQ-ROUTINE BEENDEN
970  -WART       .BY 1
980  -DIRECT     .BY 0

READY.
 
  Listing 5 demonstriert einen VIC-Interrupt für Sprite/Hintergrund-Kollisionen
(download Quellcode in Hypra-Ass Format)
 
10   -.BA 49152                ;START = 49152
20   -.GL VIC    = $D000       ;VIC BASISADRESSE
30   -.GL IRQVEC = $0314       ;IRQ-VEKTOR
40   -.GL IRQALT = $EA31       ;ALTE IRQ-ROUTINE
50   -.GL IRQEND = $FEBC       ;IRQ BEENDEN
60   -.GL RASTER = VIC+18      ;RASTERZEILEN-REGISTER
70   -.GL IRQMASK= VIC+26      ;IRQ-MASKENREGISTER
80   -.GL IRQFLAG= VIC+25      ;IRQ-REQUESTREGISTER
90   -.GL HIBIT  = VIC+17      ;HI-BIT VOM RASTERREGISTER
100  -.GL SPRKOL = VIC+30      ;SPRITE-SPRITE-KOLL.
110  -.GL SCRKOL = VIC+31      ;SPRITE-HINTERGRUND-KOLL.
999  -;
1000 -INIT       JSR MAKESPR   ;SPRITE-GENERIEREN
1010 -           SEI           ;IRQ SPERREN
1020 -           LDA #130      ;SPRITE-HINTERGRUND-KOLL.
1030 -           STA IRQMASK   ;MASKIEREN
1040 -           LDA #<(IRQNEU);IRQ-VEKTOR
1050 -           LDX #>(IRQNEU);VERBIEGEN
1060 -           STA IRQVEC
1070 -           STX IRQVEC+1
1080 -           LDA SCRKOL    ;KOLL.-REGISTER LOESCHEN
1090 -           LDA IRQFLAG   ;IRQ-REQUESTREGISTER
1100 -           STA IRQFLAG   ;LOESCHEN
1110 -           CLI           ;IRQ ZULASSEN
1120 -           RTS           ;UND ZURUECK...
1130 -;
1140 -MAKESPR    LDX #62       ;BLOCK 32 MIT 255 BELEGEN
1150 -           LDA #255
1160 -LOOP       STA 2048,X
1170 -           DEX
1180 -           BPL LOOP
1190 -           LDA #32       ;BLOCK 32 FUER SPRITE 0
1200 -           STA 2040      ;FESTLEGEN
1210 -           LDA #1        ;SPRITE 0 = WEISS
1220 -           STA VIC+39
1230 -           LDA #160      ;X-KOORDINATE = 160
1240 -           STA VIC
1250 -           LDA #130      ;Y-KOORDINATE = 130
1260 -           STA VIC+1
1270 -           LDA #0        ;HILFSBIT LOESCHEN
1280 -           STA VIC+16
1290 -           LDA #1        ;SPRITE 0 EINSCHALTEN
1300 -           STA VIC+21
1310 -           RTS           ;UND ZURUECK...
1320 -;
1330 -IRQNEU     LDA IRQFLAG   ;IRQ-REQUESTREGISTER
1340 -           STA IRQFLAG   ;LOESCHEN
1350 -           BMI VICIRQ    ;BIT 7 GESETZT, DANN VICIRQ
1360 -           JMP IRQALT    ;SONST ALTE IRQ-ROUTINE
1370 -VICIRQ     LDA SCRKOL    ;KOLL-REGISTER LOESCHEN
1380 -           INC 1024      ;1024 INKREMENTIEREN
1390 -           JMP IRQEND    ;IRQ BEENDEN

READY.