4) DIE PROBLEME BEI RASTER-IRQS
Wenn Sie unser eben beschriebenes Beispielprogramm einmal gestartet und angeschaut haben, so wird Ihnen sicher
aufgefallen sein, daß die Farbbalken
nicht ganz sauber auf dem Bildschirm zu
sehen waren. Bei jedem Farbübergang
flackerte der Bildschirm am linken Rand.
Dies ist eines der größten Probleme bei
der Raster-Interrupt- Programmierung.
Dadurch nämlich, daß der Rasterstrahl
mit einer Wahnsinnsgeschwindigkeit über
den Bildschirm huscht können minimale
Verzögerungen im Programm, wie zum
Beispiel ein weiterer Befehl, bevor die
Farbänderung geschrieben wird, verheerende Folgen haben. In unserem
Beispiel werden die beiden Farben
nämlich genau dann geändert, wenn sich
der Rasterstrahl gerade am Übergang vom
Bildschirmrahmen zum Bildschirmhintergrund befindet. Dadurch entstehen die
kleinen Farbsteifen am linken Rand, wo die Rahmenfarbe schon auf den neuen
Wert, die Hintergrundfarbe jedoch noch
auf dem alten Wert steht. Erst wenn
letztere ebenfalls geändert wurde, ist
das Bild so wie gewünscht. Zusätzlich
benötigt unsere Routine immer
Unterschiedlich viel Rechenzeit, da sie
einige Branch-Befehle enthält, die je
nach Zutreffen der abgefragten Bedingung
2 oder 3 Taktzyklen dauern, weswegen die
Farbstreifen unruhig hinund herspringen. Zusätzlich kann es passieren, daß kurzfristig einer der drei Farbbereiche nicht richtig eingeschaltet
wird, und dann der ganze Balken
flackert. Dieser Fall tritt dann ein, wenn Rasterund CIA-Interrupt kurz
hintereinander auftreten und ein gerade
bearbeiteter Raster-IRQ durch den
CIA-IRQ nochmals unterbrochen wird. Die
Routine kann also noch erheblich
verbessert werden! Stellen Sie doch
einmal die Farbänderung jeweils an den
Anfang der entsprechenden Unterroutine,
und sperren Sie gleichzeitig mittels
" SEI" das Auftreten weiterer IRQs. Die
Flackereffekte sollten sich dadurch
schon um einiges vermindern, aber
dennoch werden Sie nicht ganz
verschwinden. Das liegt hauptsächlich an
unserer Verzweigungsroutine, die
zwischen VICund CIA-IRQ unterscheidet.
Da sie für den Rasterstrahl nicht
unerheblich Zeit verbraucht wird immer
irgendwo eine Assynchronität
festzustellen sein.
Sauberer soll das nun mit unserem
nächsten Programmbeispiel gelöst werden.
Hier wollen wir ganz einfach den
Betriebssystems-IRQ von CIA1 ganz
unterbinden, und ihn quasi über den
Raster-IRQ ' simulieren' . Zusätzlich soll
die Abfrage nach der Rasterzeile, die
den Interrupt auslöste wegfallen, so daß
wenn unsere Routine angesprungen wird, immer gleich die gewünschte Farbe
eingestellt werden kann. Da wir daraufhin auch keine Abfragen mittels
Branch-Befehlen in unserem
Interrupt-Programm haben, wird die
Routine immer mit der gleichen Laufzeit
ablaufen, weswegen unruhiges Zittern
wegfallen wird. Hier nun zunächst das
Beispielprogramm. Sie finden es auf
dieser MD als ausführbaren Code unter
dem Namen " RASTERDEMO2" . Es wird ebenso
geladen und gestartet wie unser erstes
Beispiel:
;*** Initialisierung Init: sei ;IRQs sperren lda #$7f ;Alle Bits im CIA-ICR sta $dc0d ;löschen (CIA-IRQs) lda $dc0d ;CIA-ICR löschen lda #$00 ;Rasterzeile 0 als Inter- sta $d012 ; ruptauslöser festlegen lda $d011 ;Bit 7 in $D011 and #$7f ; löschen. sta $d011 lda #$01 ;Rasterstrahl als Inter- sta $d01a ; rupt-quelle definieren ldx #<(irq1) ;IRQ-Vektor bei $0314/ ldy #>(irq1) ; $0315 auf erste stx $0314 ; Interrupt- sty $0315 ; Routine verbiegen cli ;IRQs wieder freigeben rts ;ENDE!
;*** Erster Interrupt
irq1: lda #$70 ;Zeile $70 als Auslöser sta $d012 ; für nächsten IRQ festl. dec $d019 ;VIC-IRR löschen ldx #<(irq2) ;IRQ-Vektor auf ldy #>(irq2) ; zweite Interrupt- stx $0314 ; Routine sty $0315 ; verbiegen lda #$00 ;Rahmen u. Hintergrund sta $d020 ; auf 'schwarz' sta $d021 ; setzen jmp $febc ;IRQ beenden ;*** Zweiter Interrupt irq2: lda #$C0 ;Zeile $C0 als Auslöser sta $d012 ; für nächsten IRQ festl. dec $d019 ;VIC-IRR löschen ldx #<(irq3) ;IRQ-Vektor auf ldy #>(irq3) ; dritte Interrupt- stx $0314 ; Routine sty $0315 ; verbiegen lda #$00 ;Rahmen u. Hintergrund sta $d020 ; auf 'rot' sta $d021 ; setzen jmp $febc ;IRQ beenden ;*** Dritter Interrupt irq2: lda #$C0 ;Wieder Zeile 0 als Aus- sta $d012 ; löser für IRQ festl. dec $d019 ;VIC-IRR löschen ldx #<(irq1) ;IRQ-Vektor wieder auf ldy #>(irq) ; erste Interrupt- stx $0314 ; Routine sty $0315 ; verbiegen lda #$00 ;Rahmen u. Hintergrund sta $d020 ; auf 'gelb' sta $d021 ; setzen jmp $ea31 ;Betr.sys.-IRQ anspringen
Die Initialisierungsroutine dieses Beispiels unterscheidet sich kaum von dem
des ersten Programms. Wir setzen auch
hier Zeile 0 als Auslöser für den ersten
IRQ und verbiegen den IRQ-Vektor auf die
erste IRQ-Routine mit dem Namen " IRQ1" .
Ganz am Anfang jedoch unterbinden wir
alle CIA1- IRQs, indem wir durch
Schreiben des Wertes $7 F alle Bits des
CIA-ICRs löschen, womit wir alle von
CIA1 auslösbaren IRQs sperren. Das
anschließende Auslesen des ICRs dient
dem ' freimachen' der CIA, falls dort
noch eine Interruptanforderung vorliegen
sollte, die nach Freigeben der IRQs ja
sofort ausgeführt und so in unsere
Raster-IRQ- Routine1 springen würde.
Die Interrupt-Routine selbst wird nun
wirklich nur dann aufgerufen, wenn sich
der Rasterstrahl in Zeile 0 befindet.
Deshalb können wir hier gleich, ohne
große Abfragen durchführen zu müssen, Zeile $70 als nächsten Interruptauslöser
festlegen und die Bildschirmfarben
ändern. Damit hier nun ebenfalls die
richtige Routine angesprungen wird, verbiegen wir den IRQ-Vektor noch auf
die Routine " IRQ2", die speziell den
Interrupt bei Zeile $70 behandeln soll.
Sie verfährt genauso mit dem dritten
Interruptauslöser, Rasterzeile $ C0, für
die die Routine " IRQ3" zuständig ist.
Sie biegt den IRQ-Vektor nun wieder
zurück auf " IRQ1", womit das ganze von
vorne beginnt. Eine Neuheit ist hier
übrigens das Löschen des VIC-IRRs. Um
selbiges zu tun, hatten wir in letztem
Beispiel ja einen Schreibzuriff auf das
Register durchführen müssen. Dies tun
wir hier mit dem Befehl " DEC $ D019" . Er
hat den Vorteil daß er kürzer und schneller ist als einzelnes ein Lesen
und Schreiben des Registers und zudem
kein Prozessorregister in Anspruch
nimmt, in das wir lesen müssen.
Wie Sie nun sehen werden ist unsere
Flagge nun nicht mehr von
Flackererffekten gebeutelt. Die
Farbbalken sind sauber durch horizontale
Linien voneinander getrennt. Versuchen
Sie jetzt doch einmal ein paar andere
Farbkombinationen, oder vielleicht auch
mehr Rasterbalken zu erzeugen. Oder
kombinieren Sie doch einmal Hiresgrafik
mit Text. Die Möglichkeiten solch recht
einfacherer Raster-IRQs sind sehr
vielseitig, und warten Sie erst einmal
ab, wenn wir zu komplizierteren Routinen
kommen. Dies wird im nächsten Monat dann
schon der Fall sein, wenn wir per
Rasterstrahl die Bildschirmränder
abschalten werden. Bis dahin viel Spaß
beim Rasterprogrammieren!
( ub)