Erstellt: 27. April 2014 (zuletzt geändert: 1. November 2021)

Rasterbars

Stylische Balken anzeigen

C64 Studio, AMCE & TASM

Die Rasterbars (wer vom Amiga kommt kennt diesen Effekt evtl. als Copper-Bars) werden sehr häufig in Demos verwendet. Sie sind zunächst mal relativ einfach zu erzeugen und sehen bei entsprechender Farbgebung klasse aus.

Das Prinzip ist dabei sehr einfach. Man wartet bis zur gewünschten Rasterzeile und setzt dann für die folgenden Zeilen die Hintergrund- und / oder Rahmenfarbe auf die gewünschten Werte. Natürlich ist es in der Praxis wieder etwas hakeliger 😉 .

Da wir gleich einen stabilen Rasterzeileninterrupt verwenden, solltet ihr die unter Der Rasterzeileninterrupt zufindenden Beiträge gelesen haben.
Besonders das Wissen aus Raster-IRQ: Endlich stabil!!! wird vorausgesetzt!

Einen stabilen Rastzeileninterrupt einrichten

Ausgangspunkt für unser Programm ist also ein stabiler Rasterzeileninterrupt. Das folgende Programm sollte euch vor keine besonderen Probleme stellen, es richtet nur den Raster-IRQ (wie in den eben erwähnten Beiträgen beschrieben) ein.

Systemvoraussetzung: PAL mit 63TZ !

RASTER          = 47                ;Hier den 1. Raster-IRQ auslösen

;*** Startadresse 
*=$0801
;*** BASIC-Zeile: 2018 SYS 2062
 !word main-2, 2018 
 !byte $9e
 !text " 2062"
 !byte $00,$00,$00

main
 sei                                ;IRQs sperren
 lda #<myIRQ                        ;Adresse unserer Routine in
 sta $0314                          ;den RAM-Vektor
 lda #>myIRQ
 sta $0315
 lda #%00000001                     ;Raster-IRQs vom VIC-II aktivieren
 sta $d01a
 lda #RASTER                        ;Hier soll unsere Linie erscheinen
 sta $d012                      
 lda $d011                          ;Zur Sicherheit höchste BIT
 and #%01111111                     ;für die Rasterzeile löschen
 sta $d011
 lda #%01111111                     ;Timer-IRQs abschalten
 sta $dc0d
 lda $dc0d
 lda #%0000001                      ;evtl. aktiven Raster-IRQ bestätigen
 sta $d019
 cli                                ;Interrupts erlauben 
                          
 jmp *                              ;Endlosschleife



;*** an Pagegrenze ausrichten, damit die Sprünge passen
!align 255,0

myIRQ
;*** Wenn wir hier landen, sind bereits 38-45 Taktzyklen
;*** in der aktuellen Rasterzeile (RASTER) vergangen!

;*** Zweiten IRQ einrichten
;*** Da die Zeit bei aktivierten ROM nicht reicht,
;*** können wir den 2. Raster-IRQ erst in der übernächsten Zeile bekommen
 lda #<doubleIRQ                    ;(2 TZ) 2. Raster-IRQ einrichten
 sta $0314                          ;(4 TZ)
 lda #>doubleIRQ                    ;(2 TZ)
 sta $0315                          ;(4 TZ)
 tsx                                ;(2 TZ) Stackpointer im X-Reg. retten
 stx doubleIRQ+1                    ;(4 TZ) und fürs zurückholen sichern!
 nop                                ;(2 TZ)
 nop                                ;(2 TZ)
 nop                                ;(2 TZ)
 lda #%00000001                     ;(2 TZ) 1. Raster-IRQ später bestätigen
                                    ;------
                                    ;26 TZ

;*** Jetzt sind 64-71 Taktzyklen vergangen und wir sind
;*** aufjedenfall in nächsten Rasterzeile (RASTER+1)!
;*** Verbraucht wurden 1-8 TZ
 inc $d012                          ;(6 TZ) 2. IRQ in der übernächsten Zeile (RASTER+2)!!!
                                    ;       $d012 wurde bereits automatisch erhöht
 sta $d019                          ;(4 TZ) IRQ bestätigen
 cli                                ;(2 TZ) Interrupts für den 2. Raster-IRQ
                                    ;       wieder freigeben

;*** Wir befinden uns in Rasterzeile RASTER+1 und 
;*** haben bisher 13-20 Zyklen verbraucht

;*** etwas Zeit verschwenden...
 ldx #$08                           ;            2 TZ
 dex                                ;8 * 2 TZ = 16 TZ
 bne *-1                            ;7 * 3 TZ = 21 TZ
                                    ;1 * 2 TZ =  2 TZ
                                    ;          ------
                                    ;           41 TZ

;*** Bis hier sind 54-61 Taktzyklen vergannen, jetzt auf den IRQ warten...
;*** Der nächste Rasterinterrupt wird während dieser NOPs auftreten!
 nop                                ;2 TZ (55)
 nop                                ;2 TZ (57)
 nop                                ;2 TZ (59)
 nop                                ;2 TZ (51)
 nop                                ;2 TZ (63)
 nop                                ;2 TZ (65)

doubleIRQ
;*** Wir sind nun in Rasterzeile RASTER+2 und
;*** haben bisher genau 38 oder 39 Taktzyklen benötigt!!
;*** Wir können so sicher sein, da der IRQ während der NOPs auftrat.

;*** Jetzt exakt soviele Taktzyklen 'verschwenden', wie in 
;*** dieser Zeile noch zu verarbeiten sind (also 24 oder 25).
 ldx #$00                           ;(2 TZ) Platzhalter für 1. Stackpointer
 txs                                ;(2 TZ) Stackpointer vom 1. IRQ wiederherstellen
 nop                                ;(2 TZ)
 nop                                ;(2 TZ)
 nop                                ;(2 TZ)
 nop                                ;(2 TZ)
 bit $01                            ;(3 TZ)
 ldx $D012                          ;(4 TZ)
 lda #$01                           ;(2 TZ) weiß schonmal in den Akku
 cpx $D012                          ;(4 TZ) sind wir noch in Rasterzeile 22?
                                    ;------
                                    ;25 TZ = 63 oder 64 TZ!!!

 beq myIRQMain                      ;(3 TZ) wenn JA einen letzten Takt 'verschwenden'
                                    ;(2 TZ) sonst einfach weiterlaufen...

;*** Wir beginnen also immer exakt nach 3 TZ in der dritten Rasterzeile (RASTER+3)
;*** nach dem 1. Raster-IRQ (den hatten wir ja in für Zeile RASTER festgelegt)
myIRQMain
 lda #<myIRQ                        ;Original IRQ-Vektor setzen
 sta $0314
 lda #>myIRQ
 sta $0315

 lda #RASTER
 sta $d012

 lda #%00000001                     ;IRQ bestätigen
 sta $d019

 jmp $ea81                          ;zum Ende des 'Timer-Interrupts' springen

Das Programm zu starten macht aktuell noch keinen Sinn. Es richtet nur den Rasterzeileninterrupt so ein, dass wir stabil in der letzten Zeile vor dem Ausgabebereich beginnen (s. Konstante RASTER = 47). Das Hauptprogramm bleibt in einer Endlosschleife hängen JMP *. Erwähnen möchte ich noch den Sprung am Schluß des Raster-IRQs. Bisher sind wir fast immer nach $ea31 gesprungen, um den Systeminterrupt zu verarbeiten. Da wir den hier nicht benötigen springen wir einfach nach $ea81, dort werden die Register zurückgeholt und dann der Interrupt mit RTI verlassen. Schaut mit dem VICE-Monitor einfach mal nach.

Jetzt sorgen wir noch für einen sauberen Bildschirm und setzen die Rahmen- & Hintergrundfarbe auf schwarz. Fügt die folgenden gelb hervorgehobenen Zeilen einfach direkt zu Beginn hinter main ein.

main
 jsr $e544                          ;Bildschirm löschen
 lda #0                             ;schwarz
 sta $d020                          ;für Rahmen
 sta $d021                          ;und Hintergrund
 
 sei                                ;IRQs sperren

Das einzig Unbekannte ist evtl. das Löschen über die Kernal-Routine ab $e544. Die Funktion sollte euch aber nicht beunruhigen 😉 , sie löscht halt den Bildschirm für uns.

Farbe ins Spiel bringen

Nun ist es an der Zeit bei myIRQMain unseren Rasterbar zu erzeugen. Wir wollen jetzt also in jeder Zeile eine andere Hintergrundfarbe verwenden, um unseren Balken auf den Bildschirm zu bringen. Wer jetzt auf die Idee kommt einfach für jede Zeile einen eigenen Rasterinterrupt zu erzeugen, der sollte die oben im roten Block erwähnten Beiträge noch mal studieren. Spätestens bei den Bad-Lines werden wir Probleme bekommen. Wir können nun natürlich für jede Farbe einen eigenen Code-Block entwickeln, der die richtig Anzahl an Taktzyklen verwendet, aber das ist doch etwas aufwendig und unflexibel. Ich gehe hier den Weg über zwei Tabellen.

Die erste Tabelle

Die erste Tabelle rowcolortable bestimmt die Farbe der jeweiligen Zeile. Hier hinterlegen wir ein möglichst harmonisches Muster für einen stylischen Rasterbar. Das Ende kennzeichnen wir mit $f0. Fügt die Tabelle ganz am Schluß unseres Listings ein.

Folgende Farben des C64, können wir für die Rasterbars nutzen.
Die Farben des C64.

Dies ist noch kein Rasterbar 😉 .

rowcolortable
 !byte 6, 11, 11, 12, 12, 15, 1, 15, 12, 12, 11, 11, 6
 !byte $f0                          ;ENDE des Rasterbars

Wir können so eine Schleife bauen, die beendet wird, sobald die Tabelle einen negativen Wert enthält. Da für die 16 möglichen Farben nur 4-Bit benötigt werden, sorgt das untere Nibble unseres Schlußkennzeichen außerdem automatisch dafür, dass die Hintergrundfarbe (hier schwarz = 0) nach dem Rasterbar wieder korrekt gesetzt wird. Das $f0 kennzeichnet also nicht nur das Ende des Rasterbars, sondern sorgt auch wieder für einen schwarzen Hintergrund. Möchtet ihr lieber gelb als Hintergrundfarbe, dann könnt ihr einfach $f7 verwenden.

Die zweite Tabelle

In einer zweite Tabelle delaytable tragen wir die Wartezeit für die jeweilige Rasterzeile ein. Diese Zeiten müssen wir abhängig von unserer Hauptschleife berechnen / ermitteln. Wir wissen, dass wir bei einem PAL-System, 63 bzw. 20-23 Taktzyklen in einer Rasterzeile zur Verfügung haben und wieviele Zyklen die einzelnen Mnemonics benötigen. Nett, wie ich bin 😉 , habe ich euch die Arbeit abgenommen, fügt also die folgende Tabelle am Ende des Programms ein.

delaytable
 !byte 9                            ;1. Zeile nach dem Raster-IRQ
 !byte 2, 8, 8, 9, 9, 9, 9, 10
 !byte 2, 8, 8, 9, 9, 9, 9, 10

Da wir nur die Hintergrundfarbe ändern, kommt es hier nicht auf 100% Genauigkeit an. Wir stellen einfach nur sicher, dass im Ausgabebereich immer eine durchgängige Line zu sehen ist.

Jetzt brauchen wir natürlich auch noch eine Funktion, die auf die diese Tabellen zugreift. Fügt die markierten Zeilen einfach direkt hinter dem Label myIRQMain ein:

myIRQMain
 ldx #$ff                           ;X mit -1 initialisieren, da gleich INX folgt!
nextColor
 inx                                ;Schleifenzähler erhöhen
 ldy delaytable,X                   ;Wartezeit holen
 dey                                ;verringern
 bne *-1                            ;solange größer 0 zurück zum DEY
 lda rowcolortable,X                ;Farbe holen
 sta $d021                          ;und ins Register für die Hintergrundfarbe
 nop                                ;ahhhh einfach mal nichts 'tun'
 bpl nextColor                      ;solange die Farbe positiv ist -> @loop
 
 lda #<myIRQ                        ;Original IRQ-Vektor setzen

Das X-Register dient als Schleifenzähler. Da der Ausgabebereich max. 200 Zeilen hat, sollte das sogar für einen riesigen Rasterbar reichen. Da die erste Anweisung in der Schleife nextColor der Befehl INX ist, wurde das X-Register von uns mit $ff (also -1) initialisiert. In der Schleife erhöhen wir als erstes X und holen damit die Wartezeit für die aktuelle Zeile aus delaytable ins Y-Register. Wir zählen zum Warten einfach Y herunter, bis es null ist.
Eine Besonderheit stellt übrigens der erste Wartewert dar. Wir befinden uns in der letzten Rahmenzeile, wenn wir bei myIRQMain ankommen. Dort haben wir erst drei Zyklen verbraucht und nutzen die Zeit für unsere Vorbereitungen (hier nur die Initialisierung des X-Registers), den Rest müssen wir abbummeln.
Dann holen wir die Farbe für diese Rasterzeile aus der Tabelle rowcolortable und schreiben sie ins Register für die Hintergrundfarbe. Dies geschieht übrigens am Ende der aktuellen Rasterzeile. Das NOP dient nur dazu, etwas Zeit zu verbummeln. War die Farbe positiv, dann springen wir zurück an den Schleifenbeginn nach nextColor und fahren mit der nächsten Zeile fort.

Ein erster Rasterbar

Ein Start zeigt uns nun den erhofften Rasterbar.

Unsere Rasterbars nehmen Gestalt an, ein erster Rasterbar.
Unser erster Rasterbar.

Da man bekanntlich auf einem Bein nicht stehen kann, fügen wir doch noch einige Balken mehr hinzu. Niemand hindert uns daran, den ganzen Bildschirm mit Rasterbars zu füllen. Wir müssen dazu nur unsere beiden Tabellen erweitern.

rowcolortable
 !byte 6, 11, 11, 12, 12, 15, 1, 15, 12, 12, 11, 11, 6
 !byte 0,  0,  0,  0,  0,  0, 0,  0,  0,  0,  0,  0, 0
 !byte 6, 11, 11, 12, 12, 15, 1, 15, 12, 12, 11, 11, 6
 !byte 0,  0,  0,  0,  0,  0, 0,  0,  0,  0,  0,  0, 0
 !byte 6, 11, 11, 12, 12, 15, 1, 15, 12, 12, 11, 11, 6
 !byte 0,  0,  0,  0,  0,  0, 0,  0,  0,  0,  0,  0, 0
 !byte 6, 11, 11, 12, 12, 15, 1, 15, 12, 12, 11, 11, 6
 !byte 0,  0,  0,  0,  0,  0, 0,  0,  0,  0,  0,  0, 0
 !byte 6, 11, 11, 12, 12, 15, 1, 15, 12, 12, 11, 11, 6
 !byte 0,  0,  0,  0,  0,  0, 0,  0,  0,  0,  0,  0, 0
 !byte 6, 11, 11, 12, 12, 15, 1, 15, 12, 12, 11, 11, 6
 !byte 0,  0,  0,  0,  0,  0, 0,  0,  0,  0,  0,  0, 0
 !byte 6, 11, 11, 12, 12, 15, 1, 15, 12, 12, 11, 11, 6
 !byte 0,  0,  0,  0,  0,  0, 0,  0,  0,  0,  0,  0, 0
 !byte 6, 11, 11, 12, 12, 15, 1, 15, 12, 12, 11, 11, 6
 !byte 0,  0,  0,  0,  0,  0, 0,  0,  0,  0,  0,  0, 0
 !byte $f0


delaytable
 !byte 9                            ;letzte Zeile vor der Anzeige        
 !byte 2, 8, 8, 9, 9, 9, 9, 9       ; 1. Textzeile
 !byte 2, 8, 8, 9, 9, 9, 9, 10      ; 2. 
 !byte 2, 8, 8, 9, 9, 9, 9, 10      ; 3. 
 !byte 2, 8, 8, 9, 9, 9, 9, 9       ; 4. 
 !byte 2, 8, 8, 9, 9, 9, 9, 9       ; 5. 

 !byte 2, 8, 8, 9, 9, 9, 9, 9       ; 6. 
 !byte 2, 8, 8, 9, 9, 9, 9, 10      ; 7. 
 !byte 2, 8, 8, 9, 9, 9, 9, 10      ; 8. 
 !byte 2, 8, 8, 9, 9, 9, 9, 9       ; 9. 
 !byte 2, 8, 8, 9, 9, 9, 9, 9       ;10. Textzeile

 !byte 2, 8, 8, 9, 9, 9, 9, 9       ;11.
 !byte 2, 8, 8, 9, 9, 9, 9, 10      ;12.
 !byte 2, 8, 8, 9, 9, 9, 9, 10      ;13.
 !byte 2, 8, 8, 9, 9, 9, 9, 9       ;14.
 !byte 2, 8, 8, 9, 9, 9, 9, 9       ;15.

 !byte 2, 8, 8, 9, 9, 9, 9, 9       ;16.
 !byte 2, 8, 8, 9, 9, 9, 9, 10      ;17.
 !byte 2, 8, 8, 9, 9, 9, 9, 10      ;18.
 !byte 2, 8, 8, 9, 9, 9, 9, 9       ;19.
 !byte 2, 8, 8, 9, 9, 9, 9, 9       ;20. Textzeile

 !byte 2, 8, 8, 9, 9, 9, 9, 9       ;21.
 !byte 2, 8, 8, 9, 9, 9, 9, 10      ;22.
 !byte 2, 8, 8, 9, 9, 9, 9, 10      ;23.
 !byte 2, 8, 8, 9, 9, 9, 9, 9       ;24.
 !byte 2, 8, 8, 9, 9, 9, 9, 9       ;25. Textzeile

 !byte 2, 8, 8, 9, 9, 9, 9, 9       ;26. 'Sicherheitszeile'

Ich habe bei delaytable immer fünf Zeilen als Block abgesetzt. Wenn ihr die Werte später kontrolliert, werdet ihr feststellen, dass der Beginn eines jeden Blocks immer nach der gleiche Zahl Taktzyklen stattfindet. Übernehmt ihr die obigen Tabellen und startet das Programm, dann sieht fast alles gut aus. Aber leider kommt es zu einem Problem mit unseren Rasterbars.

Oops, ein kleines Problem
Am Ende kommt es zu einem Versatz bei den Rasterbars!
Am Ende kommt es zu einem Versatz!

Sind meine Werte doch falsch? Schaut euch die Daten und den Source (besonders die Befehle für den Zugriff auf die Tabellen) bevor ihr fortfahrt nochmal an und überlegt selbst einmal, wo das Problem liegt.

 

Nicht luschern… 😉

Geschafft!

Wie ein Blick auf die Mnemonics verrät, benötigt der LDY $$$$,X-Befehl einen weiteren Taktzyklus, wenn beim Zugriff die Pagegrenze überschritten wird. Genau dies verhagelt uns hier das Timing! Wir haben nun soviele Werte in den Tabellen, dass die Pagegrenze überschritten wird. Abhilfe schafft ein !align 255,0 vor jeder Tabelle. Sobald ihr die beiden Align-Anweisungen hinzugefügt habt, sollte die Anzeige wie erhofft sein.

Jetzt sehen die Rasterbars gut aus.
Jetzt sehen die Rasterbars gut aus.

Wie ihr am Quellcode erkennen könnt, händeln wir die ganze Geschichte, vom Prinzip her, wie den oben kurz erwähnten riesigen Rasterbar. Wir decken mit unserer Tabelle den gesamten sichtbaren Bereich (es ist sogar etwas mehr) ab.

RASTER          = 47                ;Hier den 1. Raster-IRQ auslösen

;*** Startadresse 
*=$0801
;*** BASIC-Zeile: 2018 SYS 2062
 !word main-2, 2018 
 !byte $9e
 !text " 2062"
 !byte $00,$00,$00

main
 jsr $e544                          ;Bildschirm löschen
 lda #0                             ;schwarz
 sta $d020                          ;für Rahmen
 sta $d021                          ;und Hintergrund
 
 sei                                ;IRQs sperren
 lda #<myIRQ                        ;Adresse unserer Routine in
 sta $0314                          ;den RAM-Vektor
 lda #>myIRQ
 sta $0315
 lda #%00000001                     ;Raster-IRQs vom VIC-II aktivieren
 sta $d01a
 lda #RASTER                        ;Hier soll unsere Linie erscheinen
 sta $d012                      
 lda $d011                          ;Zur Sicherheit höchste BIT
 and #%01111111                     ;für die Rasterzeile löschen
 sta $d011
 lda #%01111111                     ;Timer-IRQs abschalten
 sta $dc0d
 lda $dc0d
 lda #%0000001                      ;evtl. aktiven Raster-IRQ bestätigen
 sta $d019
 cli                                ;Interrupts erlauben 
                          
 jmp *                              ;Endlosschleife



;*** an Pagegrenze ausrichten, damit die Sprünge passen
!align 255,0

myIRQ
;*** Wenn wir hier landen, sind bereits 38-45 Taktzyklen
;*** in der aktuellen Rasterzeile (RASTER) vergangen!

;*** Zweiten IRQ einrichten
;*** Da die Zeit bei aktivierten ROM nicht reicht,
;*** können wir den 2. Raster-IRQ erst in der übernächsten Zeile bekommen
 lda #<doubleIRQ                    ;(2 TZ) 2. Raster-IRQ einrichten
 sta $0314                          ;(4 TZ)
 lda #>doubleIRQ                    ;(2 TZ)
 sta $0315                          ;(4 TZ)
 tsx                                ;(2 TZ) Stackpointer im X-Reg. retten
 stx doubleIRQ+1                    ;(4 TZ) und fürs zurückholen sichern!
 nop                                ;(2 TZ)
 nop                                ;(2 TZ)
 nop                                ;(2 TZ)
 lda #%00000001                     ;(2 TZ) 1. Raster-IRQ später bestätigen
                                    ;------
                                    ;26 TZ

;*** Jetzt sind 64-71 Taktzyklen vergangen und wir sind
;*** aufjedenfall in nächsten Rasterzeile (RASTER+1)!
;*** Verbraucht wurden 1-8 TZ
 inc $d012                          ;(6 TZ) 2. IRQ in der übernächsten Zeile (RASTER+2)!!!
                                    ;       $d012 wurde bereits automatisch erhöht
 sta $d019                          ;(4 TZ) IRQ bestätigen
 cli                                ;(2 TZ) Interrupts für den 2. Raster-IRQ
                                    ;       wieder freigeben

;*** Wir befinden uns in Rasterzeile RASTER+1 und 
;*** haben bisher 13-20 Zyklen verbraucht

;*** etwas Zeit verschwenden...
 ldx #$08                           ;            2 TZ
 dex                                ;8 * 2 TZ = 16 TZ
 bne *-1                            ;7 * 3 TZ = 21 TZ
                                    ;1 * 2 TZ =  2 TZ
                                    ;          ------
                                    ;           41 TZ

;*** Bis hier sind 54-61 Taktzyklen vergannen, jetzt auf den IRQ warten...
;*** Der nächste Rasterinterrupt wird während dieser NOPs auftreten!
 nop                                ;2 TZ (55)
 nop                                ;2 TZ (57)
 nop                                ;2 TZ (59)
 nop                                ;2 TZ (51)
 nop                                ;2 TZ (63)
 nop                                ;2 TZ (65)

doubleIRQ
;*** Wir sind nun in Rasterzeile RASTER+2 und
;*** haben bisher genau 38 oder 39 Taktzyklen benötigt!!
;*** Wir können so sicher sein, da der IRQ während der NOPs auftrat.

;*** Jetzt exakt soviele Taktzyklen 'verschwenden', wie in 
;*** dieser Zeile noch zu verarbeiten sind (also 24 oder 25).
 ldx #$00                           ;(2 TZ) Platzhalter für 1. Stackpointer
 txs                                ;(2 TZ) Stackpointer vom 1. IRQ wiederherstellen
 nop                                ;(2 TZ)
 nop                                ;(2 TZ)
 nop                                ;(2 TZ)
 nop                                ;(2 TZ)
 bit $01                            ;(3 TZ)
 ldx $D012                          ;(4 TZ)
 lda #$01                           ;(2 TZ) weiß schonmal in den Akku
 cpx $D012                          ;(4 TZ) sind wir noch in Rasterzeile 22?
                                    ;------
                                    ;25 TZ = 63 oder 64 TZ!!!

 beq myIRQMain                      ;(3 TZ) wenn JA einen letzten Takt 'verschwenden'
                                    ;(2 TZ) sonst einfach weiterlaufen...

;*** Wir beginnen also immer exakt nach 3 TZ in der dritten Rasterzeile (RASTER+3)
;*** nach dem 1. Raster-IRQ (den hatten wir ja in für Zeile RASTER festgelegt)
myIRQMain
 ldx #$ff                           ;X mit -1 initialisieren, da gleich INX folgt!
nextColor
 inx                                ;Schleifenzähler erhöhen
 ldy delaytable,X                   ;Wartezeit holen
 dey                                ;verringern
 bne *-1                            ;solange größer 0 zurück zum DEY
 lda rowcolortable,X                ;Farbe holen
 sta $d021                          ;und ins Register für die Hintergrundfarbe
 nop                                ;ahhhh einfach mal nichts 'tun'
 bpl nextColor                      ;solange die Farbe positiv ist -> @loop
 
 lda #<myIRQ                        ;Original IRQ-Vektor setzen
 sta $0314
 lda #>myIRQ
 sta $0315

 lda #RASTER
 sta $d012

 lda #%00000001                     ;IRQ bestätigen
 sta $d019

 jmp $ea81                          ;zum Ende des 'Timer-Interrupts' springen



!align 255,0
rowcolortable
 !byte 6, 11, 11, 12, 12, 15, 1, 15, 12, 12, 11, 11, 6
 !byte 0,  0,  0,  0,  0,  0, 0,  0,  0,  0,  0,  0, 0
 !byte 6, 11, 11, 12, 12, 15, 1, 15, 12, 12, 11, 11, 6
 !byte 0,  0,  0,  0,  0,  0, 0,  0,  0,  0,  0,  0, 0
 !byte 6, 11, 11, 12, 12, 15, 1, 15, 12, 12, 11, 11, 6
 !byte 0,  0,  0,  0,  0,  0, 0,  0,  0,  0,  0,  0, 0
 !byte 6, 11, 11, 12, 12, 15, 1, 15, 12, 12, 11, 11, 6
 !byte 0,  0,  0,  0,  0,  0, 0,  0,  0,  0,  0,  0, 0
 !byte 6, 11, 11, 12, 12, 15, 1, 15, 12, 12, 11, 11, 6
 !byte 0,  0,  0,  0,  0,  0, 0,  0,  0,  0,  0,  0, 0
 !byte 6, 11, 11, 12, 12, 15, 1, 15, 12, 12, 11, 11, 6
 !byte 0,  0,  0,  0,  0,  0, 0,  0,  0,  0,  0,  0, 0
 !byte 6, 11, 11, 12, 12, 15, 1, 15, 12, 12, 11, 11, 6
 !byte 0,  0,  0,  0,  0,  0, 0,  0,  0,  0,  0,  0, 0
 !byte 6, 11, 11, 12, 12, 15, 1, 15, 12, 12, 11, 11, 6
 !byte 0,  0,  0,  0,  0,  0, 0,  0,  0,  0,  0,  0, 0
 !byte $f0


!align 255,0
delaytable
 !byte 9                            ;letzte Zeile vor der Anzeige        
 !byte 2, 8, 8, 9, 9, 9, 9, 9       ; 1. Textzeile
 !byte 2, 8, 8, 9, 9, 9, 9, 10      ; 2. 
 !byte 2, 8, 8, 9, 9, 9, 9, 10      ; 3. 
 !byte 2, 8, 8, 9, 9, 9, 9, 9       ; 4. 
 !byte 2, 8, 8, 9, 9, 9, 9, 9       ; 5. 

 !byte 2, 8, 8, 9, 9, 9, 9, 9       ; 6. 
 !byte 2, 8, 8, 9, 9, 9, 9, 10      ; 7. 
 !byte 2, 8, 8, 9, 9, 9, 9, 10      ; 8. 
 !byte 2, 8, 8, 9, 9, 9, 9, 9       ; 9. 
 !byte 2, 8, 8, 9, 9, 9, 9, 9       ;10. Textzeile

 !byte 2, 8, 8, 9, 9, 9, 9, 9       ;11.
 !byte 2, 8, 8, 9, 9, 9, 9, 10      ;12.
 !byte 2, 8, 8, 9, 9, 9, 9, 10      ;13.
 !byte 2, 8, 8, 9, 9, 9, 9, 9       ;14.
 !byte 2, 8, 8, 9, 9, 9, 9, 9       ;15.

 !byte 2, 8, 8, 9, 9, 9, 9, 9       ;16.
 !byte 2, 8, 8, 9, 9, 9, 9, 10      ;17.
 !byte 2, 8, 8, 9, 9, 9, 9, 10      ;18.
 !byte 2, 8, 8, 9, 9, 9, 9, 9       ;19.
 !byte 2, 8, 8, 9, 9, 9, 9, 9       ;20. Textzeile

 !byte 2, 8, 8, 9, 9, 9, 9, 9       ;21.
 !byte 2, 8, 8, 9, 9, 9, 9, 10      ;22.
 !byte 2, 8, 8, 9, 9, 9, 9, 10      ;23.
 !byte 2, 8, 8, 9, 9, 9, 9, 9       ;24.
 !byte 2, 8, 8, 9, 9, 9, 9, 9       ;25. Textzeile

 !byte 2, 8, 8, 9, 9, 9, 9, 9       ;26. 'Sicherheitszeile'

Eigentlich habt ihr nun alles, was ihr als Ausgangsbasis für eigene Projekte benötigt. Spielt ein Wenig mit der Tabelle rowcolortable und variiert einfach die Farbe und Größe der Rasterbars oder fügt etwas Color-Cycling hinzu, damit es noch spektakulärer wird.

Wie so etwas aussehen kann, könnt ihr euch ansehen, wenn ihr das D64-Image herunterladet.

Die nächste Steigerung wäre es natürlich voneinander unabhängige Rasterbars frei zu bewegen oder diese vor und hinter einem Objekt entlangzuführen. Auch das Hinzufügen von Sprites wertet die ganze Sachen noch auf. Es gibt für euch also noch viel zu entdecken.


Schrott!!Naja...Geht so...Ganz gut...SUPER! (7 Bewertungen | Ø 4,57 von 5 | 91,43%)

Loading...


Zurück

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert

Protected by WP Anti Spam