4) DIE PROBLEME BEI RASTER-IRQS
Wenn Sie unser eben beschriebenes Bei- spielprogramm einmal gestartet und ange- schaut 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 Bildschirmhinter- grund 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 hin- und her- springen. Zusätzlich kann es passieren, daß kurzfristig einer der drei Farb- bereiche nicht richtig eingeschaltet wird, und dann der ganze Balken flackert. Dieser Fall tritt dann ein, wenn Raster- und 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 VIC- und 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 Bei- spiels 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 $7F 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)