Den seitlichen Rahmen ausblenden
In Oberen & unteren Rand öffnen wurde ja bereits erklärt, wie einfach sich der Rahmen über und unter dem Ausgabebereich entfernen lässt. Nach dem Beitrag Raster-IRQ: Bad Lines ist es uns nun auch möglich den seitlichen Rahmen zu entfernen.
Die Theorie
Für den oberen & unteren Rahmen mussten wir ja nur zur richtigen Zeit die Anzeige von 25 Zeilen auf 24 und dann wieder zurück ändern. Wie ihr evtl. bei VIC-II: Die Register gesehen habt, kann man neben der Zeilenanzahl auch die der Spalten einstellen. Dazu dient das Bit 3 im Register 22 $d016, hiermit kann zwischen 40 (Standard) und 38 Spalten umgeschaltet werden. Ändern wir nun zum passenden Zeitpunkt die Breite von 40 auf 38 Spalten, dann denkt der VIC-II wieder (wie beim oberen & unteren Rahmen) der Rahmen sei bereits gezeichnet worden und er wird ausgeblendet. Anschließend müssen wir den Wert wieder auf 40 zurückstellen und das Spiel beginnt von neuem.
Leider ist die Umsetzung nicht ganz so einfach. Wir müssen dieses Mal in jeder Rasterzeile dafür sorgen, dass die Spaltenanzahl geändert und zurückgestellt wird. Dabei bereiten uns die Bad Lines natürlich zusätzliches Kopfzerbrechen. Aber fangen wir doch einfach mal an.
Ein erster Versuch
Lasst uns zunächst mal einen stabilen Raster-IRQ so einrichten, dass wir in der letzen Zeile vor dem Ausgabebereich mit unserer Routine beginnen.
RASTER = $2f ;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 Interrupt auftreten sta $d012 lda $d011 ;Zur Sicherheit höchstes BIT and #%01111111 ;für die Rasterzeile löschen sta $d011 lda #%00001000 ;Ausgabe nicht verschieben und 40-Spalten sta $d016 lda #%0111111 ;Timer-IRQs abschalten sta $dc0d lda $dc0d ;zur Sicherheit bestätigen lda #%00000001 ;Sicherheitshalber auch den sta $d019 ;Raster-IRQ bestätigen cli ;Interrupts erlauben rts ;zurück zum BASIC ;*** Selbst gebautes align... *=((*-1)/1024)*1024+1024 ;etwas Platz lassen & Pagegrenze 'vermeiden' myIRQ ;*** Wenn wir hier landen, sind bereits 38-45 Taktzyklen in der ;*** aktuellen Rasterzeile (ab jetzt als STARTROW bezeichnet) 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 (STARTROW+2) 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 ;*** auf jeden Fall in nächsten Rasterzeile (STARTROW+1)! ;*** Verbraucht wurden dort 1-8 TZ inc $d012 ;(6 TZ) 2. IRQ in der übernächsten Zeile STARTROW+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 STARTROW+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 vergangen, jetzt auf den IRQ warten... ;*** Der nächste Rasterinterrupt wird während dieser NOPs auftreten! nop ;2 TZ (56) nop ;2 TZ (58) nop ;2 TZ (60) nop ;2 TZ (62) nop ;2 TZ (64) nop ;2 TZ (66) doubleIRQ: ;*** Wir sind nun in Rasterzeile STARTROW+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) lda #$00 ;(2 TZ) Farbe in den Akku ldx $d012 ;(4 TZ) cpx $d012 ;(4 TZ) sind wir noch in Rasterzeile STARTROW+2? ;====== ;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 (STARTROW+3) ;*** nach dem 1. Raster-IRQ (den hatten wir ja für Zeile STARTROW festgelegt)
Dies sollte jetzt keinen mehr vor Probleme stellen, es wird ein Raster-IRQ für Zeile 47 $2f eingerichtet. Da unsere bekannte Routine für den stabilen Raster-IRQ drei Zeilen benötigt, landen wir somit nach 3TZ in Zeile 50. Dies ist bekanntlich die letzte Zeile vor dem Ausgabebereich und somit die letzte vor der 1. Bad Line. Einzige Änderung zum bekannten Vorgehen ist, dass wir #%00001000 nach $d016 schreiben. Wir verhindern damit, dass die Ausgabe seitlich verschoben ist und aktivieren zur Sicherheit die 40-Spalten.
Die eigentliche Arbeit wird jetzt wieder ab myIRQMain erledigt.
myIRQMain ;*** Die restliche Zeit in dieser Zeile abwarten... ;*** Dies ist auch die letzte Zeile vor der 1. Bad Line!! ;s. oben 3TZ nop ; 2TZ nop ; 2TZ ldx #$0b ; 2TZ dex bne *-1 ;X*5TZ-1TZ= 54TZ ;=============== ; 63TZ ;*** Bad Line nop ; 2TZ nop ; 2TZ nop ; 2TZ nop ; 2TZ nop ; 2TZ nop ; 2TZ nop ; 2TZ nop ; 2TZ nop ; 2TZ nop ; 2TZ ;=============== ; 20TZ
Hier lassen wir erstmal die letzte Zeile vor der ersten Bad Line und die folgende Bad Line einfach verstreichen. Wir warten also 63TZ und 20TZ.
;*** 1. Zeile nach Bad Line nop ; 2TZ nop ; 2TZ ldx #$09 ; 2TZ dex bne *-1 ;X*5TZ-1TZ= 44TZ ;=============== ; 50TZ dec $d016 ; 6TZ nach 56TZ 38-Spalten inc $d016 ; 6TZ dann zurück auf 40 Spalten
Der richtige Zeitpunkt, um die Anzeige von 40 auf 38 Spalten zu ändern, ist nach 56TZ in der Rasterzeile. Dort wird das letzte Zeichen der aktuellen Zeile ausgegeben. Also warten wir erstmal 50 Taktzyklen um dann mit einem dec $d016 auf 38 Spalten um zuschalten. Das klappt hier so, da wir dort am Programmbeginn #%00001000 hinterlegt haben. Nach dem dec $d016 geht das Bit 3 also auf 0. Dass sich die Werte fürs Scrolling ändern, ist nicht weiter wild, wir machen dies ja direkt mit dem folgenden inc $d016 wieder Rückgängig.
Nun folgt wieder das bekannte Ende des Interrupts:
lda #<myIRQ ;Original IRQ-Vektor setzen sta $0314 lda #>myIRQ sta $0315 lda #RASTER ;ursprüngliche Rasterzeile zurücksetzen sta $d012 lda #%00000001 ;IRQ bestätigen sta $d019 jmp $ea31 ;zur System-Routine
Vektoren zurücksetzen, Zeile für den 1. Raster-IRQ eintragen, Interrupt bestätigen und zur System-Routine.
Ein Start sollte jetzt folgende Ausgabe erzeugen. Mit einem POKE 53281,1 könnt ihr die Hintergrundfarbe ändern und so feststellen, dass diese auch durch den offenen Rahmen sichtbar ist.
Außerdem fällt euch bestimmt auf, dass der Rahmen rechts beim Ausgabebereich geöffnet wird und dieses bis in die nächste Zeile links anhält.
Weitere Zeilen öffnen
Um jetzt einen größeren Bereich zu öffen, müssen wir das Vorgehen, wie bereits angekündigt, in jeder Zeile wiederholen. Ersetzt also alles ab myIRQMain mit den folgenden Programmzeilen:
myIRQMain ;*** Die restliche Zeit in dieser Zeile abwarten... ;*** Dies ist auch die letzte Zeile vor der 1. Bad Line!! ;s. oben 3TZ nop ; 2TZ nop ; 2TZ ldx #$0b ; 2TZ dex bne *-1 ;X*5TZ-1TZ= 54TZ ;=============== ; 63TZ ;*** Bad Line nop ; 2TZ nop ; 2TZ nop ; 2TZ nop ; 2TZ nop ; 2TZ nop ; 2TZ nop ; 2TZ nop ; 2TZ nop ; 2TZ nop ; 2TZ ;=============== ; 20TZ ;*** 1. Zeile nach Bad Line nop ; 2TZ nop ; 2TZ ldx #$09 ; 2TZ dex bne *-1 ;X*5TZ-1TZ= 44TZ ;=============== ; 50TZ dec $d016 ; 6TZ nach 56TZ 38-Spalten inc $d016 ; 6TZ dann zurück auf 40 Spalten ;=============== ; 62TZ ;*** 2. Zeile nach Bad Line bit $01 ; 3TZ inkl. 1TZ für letzte Zeile nop ; 2TZ ldx #$09 ; 2TZ dex bne *-1 ;X*5TZ-1TZ= 44TZ ;=============== ; 50TZ dec $d016 ; 6TZ nach 56TZ 38-Spalten inc $d016 ; 6TZ dann zurück auf 40 Spalten ;=============== ; 62TZ ;*** 3. Zeile nach Bad Line bit $01 ; 3TZ inkl. 1TZ für letzte Zeile nop ; 2TZ ldx #$09 ; 2TZ dex bne *-1 ;X*5TZ-1TZ= 44TZ ;=============== ; 50TZ dec $d016 ; 6TZ nach 56TZ 38-Spalten inc $d016 ; 6TZ dann zurück auf 40 Spalten ;=============== ; 62TZ ;*** 4. Zeile nach Bad Line bit $01 ; 3TZ inkl. 1TZ für letzte Zeile nop ; 2TZ ldx #$09 ; 2TZ dex bne *-1 ;X*5TZ-1TZ= 44TZ ;=============== ; 50TZ dec $d016 ; 6TZ nach 56TZ 38-Spalten inc $d016 ; 6TZ dann zurück auf 40 Spalten ;=============== ; 62TZ ;*** 5. Zeile nach Bad Line bit $01 ; 3TZ inkl. 1TZ für letzte Zeile nop ; 2TZ ldx #$09 ; 2TZ dex bne *-1 ;X*5TZ-1TZ= 44TZ ;=============== ; 50TZ dec $d016 ; 6TZ nach 56TZ 38-Spalten inc $d016 ; 6TZ dann zurück auf 40 Spalten ;=============== ; 62TZ ;*** 6. Zeile nach Bad Line bit $01 ; 3TZ inkl. 1TZ für letzte Zeile nop ; 2TZ ldx #$09 ; 2TZ dex bne *-1 ;X*5TZ-1TZ= 44TZ ;=============== ; 50TZ dec $d016 ; 6TZ nach 56TZ 38-Spalten inc $d016 ; 6TZ dann zurück auf 40 Spalten ;=============== ; 62TZ ;*** 7. Zeile nach Bad Line bit $01 ; 3TZ inkl. 1TZ für letzte Zeile nop ; 2TZ ldx #$09 ; 2TZ dex bne *-1 ;X*5TZ-1TZ= 44TZ ;=============== ; 50TZ dec $d016 ; 6TZ nach 56TZ 38-Spalten inc $d016 ; 6TZ dann zurück auf 40 Spalten ;=============== ; 62TZ ;*** Bad Line bit $01 ; 3TZ nop ; 2TZ nop ; 2TZ nop ; 2TZ nop ; 2TZ nop ; 2TZ nop ; 2TZ nop ; 2TZ nop ; 2TZ nop ; 2TZ ;=============== ; 20TZ ;*** 1. Zeile nach Bad Line nop ; 2TZ nop ; 2TZ ldx #$09 ; 2TZ dex bne *-1 ;X*5TZ-1TZ= 44TZ ;=============== ; 50TZ dec $d016 ; 6TZ nach 56TZ 38-Spalten inc $d016 ; 6TZ dann zurück auf 40 Spalten ;=============== ; 62TZ ;*** 2. Zeile nach Bad Line bit $01 ; 3TZ inkl. 1TZ für letzte Zeile nop ; 2TZ ldx #$09 ; 2TZ dex bne *-1 ;X*5TZ-1TZ= 44TZ ;=============== ; 50TZ dec $d016 ; 6TZ nach 56TZ 38-Spalten inc $d016 ; 6TZ dann zurück auf 40 Spalten ;=============== ; 62TZ lda #<myIRQ ;Original IRQ-Vektor setzen sta $0314 lda #>myIRQ sta $0315 lda #RASTER ;ursprüngliche Rasterzeile zurücksetzen sta $d012 lda #%00000001 ;IRQ bestätigen sta $d019 jmp $ea31 ;zur System-Routine
Hier haben wir nun den Rahmen für mehrere Zeilen geöffnet. Die Bad Lines lassen wir erstmal wieder aus.
Die nächste (ausgelassene) Bad Line erkennt ihr an der hellblauen Linie, die unseren Rahmen durchkreuzt. Der Source wird durch das Kopieren der einzelnen Codeblöcke für jede Rasterzeile auch immer unübersichtlicher, daher laßt uns abschließend ein paar Funktionen basteln, um für etwas Ordnung zu sorgen. Außerdem wollen wir die Bad Lines mit dem bekannten Scrolling überspringen, damit der Rahmen endlich durchgängig geöffnet wird. Dass wir dann aber keinen Ausgabebereich mehr haben ist wohl klar.
Durchgängigen Block öffnen
Also fügen wir erstmal an den Programmbeginn, vor das cli folgende beiden Zeilen hinzu:
main lda #$00 ;Bitmuster für den VIC-II sta $3fff ;falls er nicht weiß, was angezeigt werden soll sei ;IRQs sperren
Da der VIC-II durch unser Scrollen keine gültigen Daten für den Ausgabebereich mehr bekommt, greift er (wie bereits bei Oberen & unteren Rand öffnen erklärt) auf das Byte bei $3fff zurück. Damit wir einen definierten Zustand erhalten, füllen wir es zur Sicherheit mit $00.
Nun bauen wir uns drei kleine Sub-Routinen. Zum besseren Verständnis möchte ich euch jetzt noch darauf hinweisen, dass wir immer so zu den Routinen springen, dass die jeweilige Funktion mit dem 50 Taktzyklus beginnt. Der erste Befehl ist stets ein dec $d016.
Die erste Routine kümmert sich um die letzte Zeile vor einer Bad Line.
;*** Kümmert sich um die letzte Zeile vor einer BadLine beforeBadLine dec $d016 ; 6TZ: nach 50 TZ dec $d011 ; 6TZ inc $d016 ; 6TZ ldx #$06 ; 2TZ dex bne *-1 ;X*5TZ-1TZ= 29TZ nop ; 2TZ rts ; 6TZ ;=============== ; 57TZ + nächstes JSR = 63TZ
Wir öffnen mit dem ersten Befehl den Rahmen (OK eigentlich ändern wir die Spaltenanzahl auf 38). Da gleich eine unerwünschte Bad Line folgt, scrollen wir den Ausgabebereich um eine Zeile. Dann stellen wir zurück auf 40 Spalten und verbummeln den Rest der Zeile.
Diese Funktion müssen wir also immer direkt vor einer Bad Line aufrufen!
Nach einer Bad Line wollen wir wieder zurückscrollen, also:
;*** Kümmert sich um die erste Zeile nach einer BadLine afterBadLine dec $d016 ; 6TZ: nach 50 TZ inc $d011 ; 6TZ inc $d016 ; 6TZ ldx #$06 ; 2TZ dex bne *-1 ;X*5TZ-1TZ= 26TZ nop ; 2TZ rts ; 6TZ ;=============== ; 57TZ + nächstes JSR = 63TZ
Diese Routine ist bis auf einen Befehl mit beforeBadLine identisch. Nur dass wir hier mit inc $d011 wieder zurückscrollen.
Diese Funktion muss also immer direkt nach einer Bad Line ausgeführt werden!
Da es nun keine Bad Lines mehr gibt, brauchen wir nur noch eine Funktion, die sich um alle anderen Zeilen kümmert:
;*** Kümmert sich um 'normale' Zeilen normalLine dec $d016 ; 6TZ: nach 50 TZ inc $d016 ; 6TZ ldx #$07 ; 2TZ dex bne *-1 ;X*5TZ-1TZ= 34TZ bit $01 ; 3TZ rts ; 6TZ ;=============== ; 57TZ + nächstes JSR = 63TZ
Hier öffnen wir einfach nur den seitlichen Rahmen und warten, bis die Zeit für diese Zeile rum ist.
Diese Routine also einfach für alle anderen Rasterzeilen aufrufen.
Jetzt noch unser Programm ab myIRQMain anpassen:
myIRQMain ;*** abwarten, bis der 44TZ erreicht wird (s. JSR) ;s. oben 3TZ ldx #$08 ; 2TZ dex bne *-1 ;X*5TZ-1TZ= 39TZ ;=============== ;1. Block ; 44TZ! jsr beforeBadLine ; 6TZ -> immer nach 50TZ springen jsr normalLine jsr afterBadLine jsr normalLine jsr normalLine jsr normalLine jsr normalLine jsr normalLine
Wie ihr seht, lassen wir 44TZ in der ersten Zeile verstreichen, da diese auch die letzte Zeile vor einer Bad Line ist, springen wir dann zu beforeBadLine. Anschließend geht es zu normalLine, da es durch das Scrolling keine Bad Line gibt und zu guter Letzt wird mit afterBadLine das Scrolling zurückgesetzt. Nun folgen fünf normale Zeilen und wir haben einen 8 Zeilen Block geschafft (OK eigentlich gehört ein kommendes beforeBadLine noch dazu). Aber wir können nun durch einfaches Kopieren dieser acht Zeilen unseren Rahmen durchgängig öffnen.
Fügen wir also noch ein paar Blöcke hinzu und schließen die Funktion dann auch ab. Ich zeige hier den kompletten Bereich ab myIRQMain, also vorsicht, falls ihr die Abschnitte von oben bereits in den Source aufgenommen habt.
myIRQMain ;*** abwarten, bis der 44TZ erreicht wird (s. JSR) ;s. oben 3TZ ldx #$08 ; 2TZ dex bne *-1 ;X*5TZ-1TZ= 39TZ ;=============== ;1. Block ; 44TZ! jsr beforeBadLine ; 6TZ -> immer nach 50TZ springen jsr normalLine jsr afterBadLine jsr normalLine jsr normalLine jsr normalLine jsr normalLine jsr normalLine ;2. Block jsr beforeBadLine jsr normalLine jsr afterBadLine jsr normalLine jsr normalLine jsr normalLine jsr normalLine jsr normalLine ;3. Block jsr beforeBadLine jsr normalLine jsr afterBadLine jsr normalLine jsr normalLine jsr normalLine jsr normalLine jsr normalLine ;4. Block jsr beforeBadLine jsr normalLine jsr afterBadLine jsr normalLine jsr normalLine jsr normalLine jsr normalLine jsr normalLine ;5. Block jsr beforeBadLine jsr normalLine jsr afterBadLine jsr normalLine jsr normalLine jsr normalLine jsr normalLine jsr normalLine lda #<myIRQ ;Original IRQ-Vektor setzen sta $0314 lda #>myIRQ sta $0315 lda #RASTER ;ursprüngliche Rasterzeile zurücksetzen sta $d012 lda #%00000001 ;IRQ bestätigen sta $d019 jmp $ea31 ;zum Schluß zum 'Timer-Interrupt' springen ;*** Kümmert sich um die letzte Zeile vor einer BadLine beforeBadLine dec $d016 ; 6TZ: nach 50 TZ dec $d011 ; 6TZ inc $d016 ; 6TZ ldx #$06 ; 2TZ dex bne *-1 ;X*5TZ-1TZ= 29TZ nop ; 2TZ rts ; 6TZ ;=============== ; 57TZ + nächstes JSR = 63TZ ;*** Kümmert sich um die erste Zeile nach einer BadLine afterBadLine dec $d016 ; 6TZ: nach 50 TZ inc $d011 ; 6TZ inc $d016 ; 6TZ ldx #$06 ; 2TZ dex bne *-1 ;X*5TZ-1TZ= 26TZ nop ; 2TZ rts ; 6TZ ;=============== ; 57TZ + nächstes JSR = 63TZ ;*** Kümmert sich um 'normale' Zeilen normalLine dec $d016 ; 6TZ: nach 50 TZ inc $d016 ; 6TZ ldx #$07 ; 2TZ dex bne *-1 ;X*5TZ-1TZ= 34TZ bit $01 ; 3TZ rts ; 6TZ ;=============== ; 57TZ + nächstes JSR = 63TZ
Hier gibt es einfach nur den 2. bis 5. Block, dann wird der Raster-IRQ verlassen. Ganz zum Schluß findet ihr die drei neuen Routinen.
Jetzt haben wir endlich einen durchgängig geöffneten Rahmen. Bei uns zur Zeit zwar nur in den ersten fünf Textzeilen, aber wie ihr den Rest öffnet, wisst ihr nun auch.
Oben, unten, links & rechts öffnen
Um den seitlichen Rahmen auch ober- und unterhalb des Ausgabebereichs zu öffnen, müssen, wie bereits bei Oberen & unteren Rand öffnen erwähnt, beide Rahmen entfernt werden. Da bereits beides beschrieben wurde, braucht ihr diese beiden Vorgehensweisen nur kombinieren.
Ändert doch mal die Konstante RASTER am Programmbeginn in RASTER = $20 und ersetzt dann alles ab myIRQMain mit dem folgenden Block.
myIRQMain ;*** abwarten, bis der 44TZ erreicht wird (s. JSR) ;s. oben 3TZ lda $d011 ; 4TZ auf 25 Zeilen umstellen ora #%00001000 ; 2TZ sta $d011 ; 4TZ ldx #$06 ; 2TZ dex bne *-1 ;X*5TZ-1TZ= 29TZ ;=============== ;Rahmen ; 44TZ! jsr normalLine ; 6TZ -> immer nach 50TZ springen jsr normalLine jsr normalLine jsr normalLine jsr normalLine jsr normalLine jsr normalLine jsr normalLine jsr normalLine jsr normalLine jsr normalLine jsr normalLine jsr normalLine jsr normalLine jsr normalLine ;1. Block jsr beforeBadLine jsr normalLine jsr afterBadLine jsr normalLine jsr normalLine jsr normalLine jsr normalLine jsr normalLine ;2. Block jsr beforeBadLine jsr normalLine jsr afterBadLine jsr normalLine jsr normalLine jsr normalLine jsr normalLine jsr normalLine ;3. Block jsr beforeBadLine jsr normalLine jsr afterBadLine jsr normalLine jsr normalLine jsr normalLine jsr normalLine jsr normalLine ;4. Block jsr beforeBadLine jsr normalLine jsr afterBadLine jsr normalLine jsr normalLine jsr normalLine jsr normalLine jsr normalLine ;5. Block jsr beforeBadLine jsr normalLine jsr afterBadLine jsr normalLine jsr normalLine jsr normalLine jsr normalLine jsr normalLine lda #<myIRQ2 ;IRQ-Vektor oberen & unteren Rahmen öffnen sta $0314 lda #>myIRQ2 sta $0315 lda #$fa ;passende Zeile zum Rahmen öffnen sta $d012 lda #%00000001 ;IRQ bestätigen sta $d019 jmp $ea31 ;zum Schluß zum 'Timer-Interrupt' springen myIRQ2 lda $d011 ;auf 24 Zeilen umschalten and #%11110111 sta $d011 lda #<myIRQ ;Original IRQ-Vektor setzen sta $0314 lda #>myIRQ sta $0315 lda #RASTER ;ursprüngliche Rasterzeile zurücksetzen sta $d012 lda #%00000001 ;IRQ bestätigen sta $d019 pla ;Register zurückholen tay pla tax pla rti ;IRQ-Verlassen beforeBadLine dec $d016 ; 6TZ: nach 50 TZ dec $d011 ; 6TZ inc $d016 ; 6TZ ldx #$06 ; 2TZ dex bne *-1 ;X*5TZ-1TZ= 29TZ nop ; 2TZ rts ; 6TZ ;=============== ; 57TZ + nächstes JSR = 63TZ normalLine dec $d016 ; 6TZ: nach 50 TZ inc $d016 ; 6TZ ldx #$07 ; 2TZ dex bne *-1 ;X*5TZ-1TZ= 34TZ bit $01 ; 3TZ rts ; 6TZ ;=============== ; 57TZ + nächstes JSR = 63TZ afterBadLine dec $d016 ; 6TZ: nach 50 TZ inc $d011 ; 6TZ inc $d016 ; 6TZ ldx #$06 ; 2TZ dex bne *-1 ;X*5TZ-1TZ= 26TZ nop ; 2TZ rts ; 6TZ ;=============== ; 57TZ + nächstes JSR = 63TZ
Hier beginnt das Öffnen des seitlichen Randes schon in Zeile 32. Da sich dort der obere Rahmen befindet, öffnen wir mit einem weiteren IRQ myIRQ2 auch den oberen & unteren Rand.
Hinter myIRQMain setzen wir die Anzeige zunächst auf 25 Zeilen. Dann verbummeln wir wieder den Rest der Zeile, bis wir im 44TZ angekommen sind. Anschließend rufen wir 15 mal normalLine auf. Dies sind die Zeilen im Rahmen. Danach geht es mit den eben entwickelten Blöcken weiter. Zum Schluß setzen wir den RAM-Vektor aber auf einen weiteren Raster-IRQ myIRQ2, den wir in Zeile $fa auftreten lassen.
Bei myIRQ2 wird nur auf 24 Zeilen umgeschaltet, dann der Hauptinterrupt myIRQ in den Vektor geschrieben und schließlich der Interrupt bestätigt und verlassen.
Wie man den gesamten Rahmen öffnet, sollte jetzt kein Problem mehr sein, dass könnt ihr ja mal selbst in Angriff nehmen. Ihr dürft euch nur nicht bei den Taktzyklen verzählen. Da wir durchs Scrollen dann aber keine Ausgabe mehr haben, könnt ihr aktuell wenig damit anfangen. Solltet ihr auf die Idee kommen Sprites zu verwenden, dann werdet ihr euer „blaues Wunder“ erleben. Es klappt dann nichts mehr, dass Thema wird im Beitrag Raster-IRQ: Sprites & Timing behandelt.
Vorsicht, evtl. gibt es Darstellungsprobleme!
Bedenkt auch, dass der Rahmen nicht aus Spass vorhanden ist. Unter VICE ist es kein Problem den vollen Rahmen auszunutzen. Läuft euer Programm aber auf einem echten C64, der evtl. auch noch an einem Röhrenmonitor angeschlossen ist, dann sieht die Sache schon anders aus. Das Problem könnt ihr auf den beiden folgenden Bildern sehen.
Ein Vergleich mit WinVICE und einem SX-64 ist zwar nicht ganz fair (beim SX-64 ist der Rahmen sehr dünn) aber er illustiert das Problem sehr gut.
Abschließend noch ein kleines Beispielprogramm, dass ich zum Testen geschrieben habe. Es öffnet im oberen Bereich komplett den Rahmen, zeigt alle 8 Sprites an und bewegt diese von links nach rechts über die gesamte Breite. Das BASIC bleibt verfügbar.
Wer es in Bewegung sehen möchte, kann sich das Beispiel als D64-Image herunterladen:
Rahmen an den Seiten öffnen