Erstellt: 7. Juli 2013 (zuletzt geändert: 1. November 2021)

Oberen & unteren Rand öffnen

Den oberen und unteren Rand ausblenden

C64 Studio, AMCE & TASM

Ein häufig nachgefragter Effekt ist das Öffnen des Rahmens. Wie wir alle wissen, ist der Hauptanzeigebereich des C64 von einem relativ breiten und (in unseren Augen) meistens äußerst nutzlosen Rahmen umgeben.

Warum gibt es den Rahmen überhaupt?

Der Eine oder Andere wird sich nun fragen, was dieser Rahmen überhaupt soll, wieso haben uns die C64 Entwickler das angetan? Wie bei Der Rasterzeileninterrupt erwähnt, wurden die Heimcomputer Anfang der 80‘er Jahre fast ausschließlich an Röhrenfernsehern betrieben. Nun boten diese Fernseher aber bei weitem nicht die Einstellmöglichkeiten heutiger Geräte oder eines Monitors. Man konnte z. B. die Bildlage und -größe nicht ändern, besser gesagt, nur nach öffnen des Gerätes fand man auf der Platine die entsprechenden Potentiometer. Da die Fernseher auch noch große Fertigungstoleranzen aufwiesen und ein Teil der Röhre immer unter dem Gehäuse verschwand, mussten die C64 Entwickler sicherstellen, dass das Hauptbild immer sichtbar ist. Also spendierten Sie dem C64 einen breiten Rand.
Exkurs: Das gibt es übrigens auch heute noch.
Habt ihr euch z. B. mal mit der Entwicklung von Spielen für die Xbox 360 beschäftigt, dann wird euch bestimmt der Begriff „Title-Safe-Area“ bekannt sein. Da es bei der Xbox 360 noch immer die Möglichkeit gibt, diese an einen Röhrenfernseher anzuschließen, muss man, auch laut der Vorgabe von Microsoft, dafür sorgen, dass alles Wichtige immer sichtbar ist. Also ist ein Rahmen (ca. 5%-10% der Auflösung) notwendig, in dem keine Spiel relevanten Daten (z. B. die Punkteanzeige) erscheinen darf. Alternativ bieten viele Spiele die Möglichkeit den sichtbaren Bildschirmausschnitt selbst festzulegen, da wird das Bild dann per Software verkleinert.

Wie kann man den Rand nun verschwinden lassen?

Hier ist es wichtig zu unterscheiden, ob man den oberen und unteren oder die seitlichen Ränder verschwinden lassen will. Es ist jeweils ein ähnliches, aber vom Timing her doch sehr unterschiedliches Vorgehen notwendig. Wie der Titel es schon vorweggenommen hat, kümmern wir uns als Erstes um den oberen und unteren Rand, da sich dieser wirklich sehr einfach ausblenden lässt.

Technischer Hintergrund

Der VIC-II ist auch für das Zeichnen des Rahmens verantwortlich. Er erhält exakt einmal während des Bildaufbaus den Impuls, dass der Rahmen noch dargestellt werden muss. Dieser Impuls erfolgt direkt nach dem Ausgeben der letzten Textzeile, also normalerweise direkt nach Zeile 25. Unsere Aufgabe ist es nun, dem VIC-II vorzugaukeln, dass er den Rahmen bereits gezeichnet hat. Wer schon mal einen Blick auf sämtliche Register des VIC-II geworfen hat, dem ist evtl. Register 17 $d011 bekannt. Über das 3. Bit in $d011 kann man zwischen 25 und 24 Zeilen umschalten. Hier liegt nun der Schlüssel zum Erfolg. Im 24 Zeilen Modus würde der Rahmen direkt nach dem Schreiben der 24. Zeile dargestellt werden. Wenn wir nun, während die 25. Zeile gezeichnet wird, auf 24 Zeilen zurückschalten, dann „denkt“ der VIC-II, er hätte den Rahmen bereits gezeichnet. Nach dem Beenden der 25. Zeile können wir dann wieder auf diesen Modus zurückschalten und schon ist der Rahmen offen. Dieses Vorgehen muss bei jedem Bildaufbau wiederholt werden, das schreit geradezu nach einem Rasterzeileninterrupt.

Rahmen öffne dich…

Ein Beispielprogramm ist schnell entwickelt. Die erste Textzeile (im 25 Zeilenmodus) beginnt in der Rasterzeile 50. Wir müssen jetzt wissen, in welchen Rasterzeilen die 25. Textzeile geschrieben wird. Einfach 24 Zeilen * 8 Pixel (ein Zeichen ist bekanntlich 8×8 Pixel groß) zu 50 addieren und man landet bei Zeile 242. Dort beginnt das Zeichnen der 25. Zeile und endet bei Zeile 249. Also muss zwischen Zeile 242 und 249 auf 24 Zeilen umgeschaltet werden.

Damit haben wir alle Infos für das Beispielprogramm:

SET24ROWS      = $f8
SET25ROWS      = $fb

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

main
 sei                                ;IRQs sperren und
 lda #<irq                          ;Vektor umbiegen
 sta $0314
 lda #>irq
 sta $0315

 lda #%00000001                     ;Raster-IRQs erlauben
 sta $d01a

 lda $d011                          ;höchstes Bit löschen
 and #%01111111
 sta $d011

 lda #SET24ROWS                     ;gewünschte Rasterzeile für IRQ
 sta $d012
 cli                                ;IRQs erlauben

 rts                                ;und zurück zum BASIC



irq
 lda $d019                          ;ist es ein Raster-IRQ?
 bmi doRaster                       ;falls ja, zur Raster-Routine
 lda $dc0d                          ;sonst zur System-Routine
 cli                                ;...
 jmp $ea31                          ;springen

doRaster
 sta $d019                          ;Raster bestätigen
 lda $d012                          ;Zeile prüfen
 cmp #SET25ROWS                     ;zurück auf 25. Zeilen schalten?
 bne set24                          ;nein, dann -> irq_set_24:
 lda $d011                          ;sonst auf den
 ora #%00001000                     ;25 Zeilenmodus
 sta $d011                          ;zurückschalten
 lda #SET24ROWS                     ;nächste Zeile für IRQ
 sta $d012                          ;setzen
 jmp exit                           ;-> EXIT

set24
 cmp #SET24ROWS                     ;24 Zeilenmodus aktivieren?
 bne exit                           ;nein, dann -> EXIT
 lda $d011                          ;sonst den
 and #%11110111                     ;24 Zeilenmodus
 sta $d011                          ;aktivieren
 lda #SET25ROWS                     ;nächste Raster-IRQ Zeile
 sta $d012                          ;setzen

exit:
 pla                                ;Werte vom Stack holen
 tay
 pla
 tax
 pla
 rti                                ;und Interrupt beenden

Das Programm sollte kein Problem darstellen, über die Konstanten SET24ROWS und SET25ROWS wird festgelegt, in welchen Rasterzeilen die jeweilige Umschaltung erfolgt. Der Rest wurde bereits bei Der Rasterzeileninterrupt erklärt.

Was kann man nun damit anfangen?

Wenn ihr Glück habt sieht eure Ausgabe so aus wie hier:

Der obere und untere Rand ist offen.
Der obere und untere Rand ist offen.

Wie ihr seht, öffnen sich immer der obere und untere Rahmen, die Ecken müssen allerdings über die Seiten geöffnet werden. Im Rand lassen sich keine Zeichen darstellen, da der C64 keinen entsprechenden Speicherbereich aufweist, aus dem der VIC-II Daten lesen könnte. Das ist allerdings nicht ganz korrekt! Der VIC-II greift auf das letzte Byte des für ihn sichtbaren 16KB Speicherbereichs zu und gibt dieses im Rand wieder. Bei unserem Beispiel enden diese 16KB bei $3fff. Im obigen Bild steht dort $ff (bei euch kann an der Speicherstelle etwas ganz anderes stehen und euer Bild daher abweichen!). Da es auch kein Farb-RAM für den Rahmen gibt, wird jedes gesetzte Bit in $3fff schwarz dargestellt. Schreibt doch zu Beginn des Programms (z. B. direkt hinter sei) mal ein $f0 nach $3fff.

Rahmen offen und $f0 in $3fff.
Rahmen offen und $f0 in $3fff.

Nicht gesetzte Bits in $3fff werden (wie bei normalen Zeichen) in der Hintergrundfarbe eingefärbt. Hierüber lassen sich teilweise auch nette Effekte erzielen. Es ist aber immer eine gute Idee den gewünschten Wert nach $3fff zuschreiben, wenn man den Rahmen öffnet, um Müll auf dem Bildschirm zu vermeiden. Außerdem muss man natürlich darauf achten, dass in $3fff keine benötigten Befehle oder Daten stehen.
Am häufigsten wird der gewonnene Platz aber verwendet, um Sprites anzuzeigen. Auch hier greift übrigens die Einstellung, ob Sprites vor oder hinter den Zeichen darstellt werden sollen. Sprites im Rahmen findet man zwar meistens in Demos wieder, aber auch Spiele (z. B. Punkteanzeige im Rahmen) oder Anwendungen machen davon gebrauch.

AMICA Paint nutzt den Rahmen für Infos.
AMICA Paint nutzt den Rahmen für Infos.

Wie man an AMICA Paint sieht, lassen sich auch in anderen Grafikmodi die Rahmen entfernen. Das Vorgehen ist identisch, auch wenn ich oben von Textzeilen gesprochen habe. Wichtig sind nur die Rasterzeilen und das Umschalten zwischen 24/25 Zeilen.


Dann ist es jetzt wiedermal an euch, den Rahmen zu füllen. Laßt doch mal ein paar Sprites tanzen. Noch ein kleiner Hinweis: Sprites, die ihr im oberen Rahmen anzeigt, erscheinen je nach Y-Koordiante auch (evtl. nur teilweise) unten! Ihr könnt dies aber mittels Raster-IRQ beeinflussen.

Ein paar eigene Sprites im Rahmen.
Ein paar eigene Sprites im Rahmen.

Wie das in Bewegung aussieht, könnt ihr euch wieder mit dem D64-Image ansehen:

Wie die Seiten geöffnet werden erkläre ich in Linken & rechten Rahmen öffnen.


Schrott!!Naja...Geht so...Ganz gut...SUPER! (7 Bewertungen | Ø 5,00 von 5 | 100,00%)

Loading...


Zurück

13 Gedanken zu „Oberen & unteren Rand öffnen“

  1. “Im Rand lassen sich keine Zeichen darstellen, da der C64 keinen entsprechenden Speicherbereich aufweist, aus dem der VIC-II Daten lesen könnte.”
    Dazu wäre meine Frage, kann man über FLD den Bildschirm nach unten verschieben, und wenn das geht, kommt der Text dann wieder oben raus, wenn man ihn ganz weit nach unten verschiebt?

    Gruß
    Julian

    1. Schade …. ich habe jetzt mal schnell mein modifiziertes Rahmenprogramm (denn das hier angegebene sorgt hin und wieder für Flackern) mit dem FLD-Programm verwoben und leider funktioniert es nicht. Wäre aber auch zu schön gewesen.

  2. Hallo Jörn,

    gibt es eine Möglichkeit, den Rahmen oben und unten zu öffnen, während man gleichzeitig schon 24 Zeilen nutzt? Man könnte einfach 25 Zeilen normalerweise nehmen und dann Sprites nutzen, um die letzte Zeile zu überdecken (das sollte ja “einfach” durch Multiplexen gehen), aber geht das auch anders?

    Gruß
    Julian

    1. Moin Julian,

      ich bin zwar nicht ganz sicher, ob ich deine Frage richtig verstanden habe, aber..

      Da der C64 keinen echten 24-Zeilen Modus hat, ist die 25. Zeile immer vorhanden.
      Im 24 Zeilen Modus wird einfach nur der Rahmen etwas weiter ins Bild gezogen, daher sind beim Öffnen des oberen & unteren Rahmens auch immer alle 25 Zeilen sichtbar.

      Viele Möglichkeiten, die 25. Zeile in dem Fall auszublenden bleiben nicht.
      Am einfachsten wäre es, wenn die Zeile leer ist, dann könnte man zu Beginn der 25. Zeile einfach die Hintergrundfarbe ändern, sodass diese zum geöffneten Rahmen passt.
      Falls dort etwas steht, könnten auch einfach die Zeichenfarben so gesetzt werden, dass der Inhalt mit dem Umstellen der Hintergrundfarbe ebenfalls verschwindet.
      Oder man nimmt halt die von dir erwähnten Sprites.

      Gruß,
      Jörn

        1. Hätte ich gewußst, dass du scrollen möchtest, dann hätte ich die anderen Möglichkeiten überhaupt nicht erwähnt.
          Die Hauptaufgabe des 24-Zeilen Modus ist nämlich, dass man das Verschwinden (oben) bzw. plötzliche Auftauchen (unten) von Zeilen beim vertikalen Scrolling verstecken kann.
          In dem Fall bringt das Ändern der Farben natürlich überhaupt nichts.

  3. Hallo Jörn,
    ich versteh nicht warum die Umschaltung auf 24.Textzeilen erst ab Rasterzeile 248 und nicht schon ab R-Zeile 242 oder zumindestens ab R-Zeile 243 funktioniert. Da wäre es ja zum Zeichnen des 24er Rahmens eh schon zu spät.

    Gruß,
    Thomas

  4. Hi Jörn, Glückwunsch zu deiner Seite. Wie schon von anderen Leser bemerkt findet man hier Internetgold! Danke dafür.
    Ich programmiere an einem Textabenteuer (Olds school) benötige dafür viel Platz aber es ist eher Zeitunkritisch. Nun wollte ich den Rahmen öffnen und Sprites anzeigen und in Basic die Texte anzeigen lassen.
    Nun hab ich den Start auf $C000 verschoben und mit sys49152 gestartet.
    Der Basicspeicher steht mir aber irgentwie nicht zur Verfügung. Springt nach dem RasterIRQ das BS nicht wieder zurück ins Basic und wird beim erreichen der Zeile 24/25 erneut aufgerufen?
    Otto

    1. Hallo,
      ich habe mir erlaubt, das Björn in Jörn zu ändern. Der falsche Name ‘tut’ mir sonst echt weh! 😉
      Unabhängig davon freut es mich, dass du hier etwas Nützliches gefunden hast.

      Dein Problem wird wohl sein, dass du nach dem Laden des Programms einen “?OUT OF MEMORY FEHLER” bekommst, sobald du etwas mit BASIC machst.
      Dies liegt daran, dass durchs direkte Laden in den hohen Bereich, VARTAB (Zero-Page $2D/$2E) hinter das Ende des BASIC-Speichers zeigt.
      Du musst diesen wieder zurücksetzen. Das geht z. B. durch NEW. Da damit aber dein BASIC-Programm verschwindet, ist dies eher suboptimal.
      Du kannst z. B. das Programm als Data-Zeilen aufnehmen und an die richtige Stelle ‘POKEn’. Denkbar wäre es evtl. auch sich den Inhalt von VARTAB mit PEEK zu merken und mit POKE nach dem Laden zurückzuschreiben.

      Gruß,
      Jörn

  5. Hallo

    Sorry, ich wollte meinen Kommentar noch nicht absenden, der war noch nicht spruchreif. Da hat mich mein Browser verarscht…

    Ich wollte darauf hinweisen, dass die Adresse $3FFF von WinVICE und von CSS64 unterschiedlich initialisiert wird (zumindest gemäss meinen Beobachtungen). Darum gibt’s einmal blau und einmal schwarz. Sobald man selber etwas reinschreibt sieht’s dann auch bei beiden Emulatoren gleich aus.

    Gruss
    Thomas

  6. Hallo

    Im der Adresse $3FFF steht ein $00 drin und der Balken oben und unten erscheint schwarz (beim Einsatz von VICE).

    Beim Einsatz von CSS64 v3.9 (ein anderer Emulator) steht in der Adresse $3FFF $FF drin und der Balken erscheint blau.

    Sobald der Wert von $3FFF gesetzt wird, verhalten sich beide Emulatoren gleich.

    Gruss
    Thomas

    1. Sorry, aber diese Aussage scheint mir falsch zu sein.
      Ich kann sie jedenfalls in keinster Weise bestätigen.

      Bei $00 erscheint der Rahmen blau:
      VICE

      bei $FF schwarz:
      VICE
      wie man sieht, auch unter WinVICE und CCS64 (und ohne dass ich vorher etwas nach $3FFF geschrieben hätte).

      Ich möchte der Vollständigkeit noch darauf hinweisen, dass sich das Füllen des Speichers einstellen lässt.
      VICE und CCS64 bieten dazu verschiedene Konfigurationen an, sie können wie bei dir abweichen, müssen dies aber nicht.
      Ich habe normalerweise beide identisch konfiguriert.

      Auf einem echten C64 mit Turbo Chameleon 64 sieht es dann natürlich wieder ganz anders aus, da steht direkt nach dem Start ein $AA in $3FFF und wenn man direkt am C64 entwickelt kann etwas vollkommen unverhersehbares dort stehen. Da auch nach einem RESET der Speicher größtenteils unverändert bleibt, es werden nur wenige Bereiche von der ROM-Routine initialisiert, ist es reines Glück wenn der gewünschte Wert in $3FFF steht.

Schreibe einen Kommentar

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

Protected by WP Anti Spam