----------------------------------------------------

Kapitel 6

Scrolling

----------------------------------------------------

 

Sehr oft übersteigt der Informationsbetrag, den ein Programmierer anzeigen möchte, dem, der auf den Bildschirm paßt. Eine Möglichkeit, um dieses Problem zu lösen, besteht im "Scrollen" (= Rollen) der Information über den Schirm. So scrollen BASIC-Programm Listings z.B. über die Mattscheibe. Alle Personal Computer besitzen diesen Typ des Scrollens. Zusätzlich besitzt der ATARI-Personal Computer aber noch zwei weitere Scroll-Möglichkeiten. Es sind grobes Scrolling (über die LMS-Anweisung) und feines Scrolling.

 

Andere Computer benutzen außchließlich grobes Scrolling. Bei dieser Art sind allerdings die Pixel, welche die Zeichen beinhalten, auf der Bildschirmposition fixiert. Der Text wird dabei gescrollt, indem die Bytes durch den Bildschirmspeicher bewegt werden. Die Auflösung bei dieser Methode beträgt ein Zeichen, das sehr grob ist, wie man sicherlich zugeben muß. Das erzeugte Scrolling ist springend und nicht sehr augenfreundlich. Außerdem kann es nur dadurch erreicht werden, daß jeweils bis zu tausend Bytes im RAM herumgeschoben werden. Dieses ist auch für einen Computer eine sehr mühselige Arbeit. Das System muß also die Daten bewegen, um ein Scrollen der Information zu erzeugen.

 

Einige Personal Computer produzieren ein etwas feineres Scrolling, indem die Bilder in einem Graphik-Modus mit höherer Auflösung gezeichnet und dann erst gescrollt werden. Obwohl hierbei eine bessere Auflösung beim Scrolling erreicht wird, müßen noch mehr Daten als beim groben Scrolling bewegt werden, wodurch das Programm natürlich sehr stark verlangsamt wird. Das grundsätzliche Problem ist also, daß Daten durch den Bildschirmbereich des Speichers bewegt werden müßen, damit ein Scrollen erreicht wird.

 

Auf dem ATARI Computer gibt es eine bessere Möglichkeit, um ein grobes Scrolling zu erreichen: der Bildschirmbereich wird über den anzuzeigenden Datenbereich bewegt, was mit Hilfe der LMS-Anweisung geschieht. Der Load-Memory-Scan-Befehl wurde zum ersten Mal in Kapitel 2 behandelt. Er teilt dem ANTIC-Prozessor mit, wo sich das Bildschirm-RAM befindet. Eine normale Display List besitzt nur eine LMS-Anweisung am Anfang; der angewählte RAM-Bereich enthält die anzuzeigenden Daten in linearer Reihenfolge. Durch Manipulation der Bytes des LMS-Operanden kann ein einfaches Scrolling erreicht werden; das Playfield-Fenster wird über die Daten bewegt. Das heißt durch Ändern von lediglich zwei Adress-Bytes kann ein Effekt erzielt werden, der dem Bewegen der gesamten Bildschirmdaten gleichkommt. Das folgende Programm realisiert die oben beschriebene Methode:

 

 

 

10  DLIST=PEEK(560)+256*PEEK(561):REM Display-List finden

20  LMSLOW=DLIST+4:REM Adresse des niederwertigen Operanden

30  LMSHIGH=DLIST+5:REM Adresse des höherwertigen Operanden

40  FOR I=0 TO 255:REM Äußere Schleife

50  POKE LMSHIGH,I

60  FOR J=0 TO 255:REM Innere Schleife

70  POKE LMSLOW,J

80  FOR Y=l TO 50:NEXT Y:REM Verzögerungs-Schleife

90  NEXT J

100 NEXT I

 

 

Dieses Programm bewegt das Display-List über den gesamten Adressbereich des Computers. Die Inhalte aller Speicherstellen werden auf dem Bildschirm ausgegeben. Das Scrolling ist ein einfaches serielles Scrolling, das durch Kombination von waagerechtem und senkrechtem Scrolling erreicht wird. Ein reines senkrechtes Scrolling kann erzielt werden, indem ein festgelegter Betrag (die Zeilenlänge in Bytes) zum LMS-Operanden addiert oder subtrahiert wird. Das folgende Programm tut dies:

 

 

10  GRAPHICS 0

20  DLIST=PEEK(560)+256*PEEK(561)

30  LMSLOW=DLIST+4

40  LMSHIGH=DLIST+5

50  SCREENLOW=0

60  SCREENHIGH=0

70  SCREENLOW=SCREENLOW+40:REM Nächste Zeile

80  IF SCREENLOW<256 THEN GOTO 120:REM übertrag?

90  SCREENLOW=SCREENLOW-256:REM Ja, Zeiger korrigieren

100 SCREENHIGH=SCREENHIGH+l

110 IF SCREENHIGH=256 THEN END

120 POKE LMSLOW,SCREENLOW

130 POKE LMSHIGH,SCREENHIGH

140 GOTO 70

 

 

Ein reines waagerechtes Scrolling ist nicht ganz so leicht zu erreichen wie ein reines senkrechtes. Das Problem hierbei ist, daß das Bildschirm-RAM für eine einfache Display-List sequentiell organisiert ist. Die Bildschirm-Bytes für die einzelnen Zeilen folgen direkt aufeinander, wobei das erste Byte einer Zeile genau dem letzten der vorangehenden folgt. Es könnte gescrollt werden, indem alle Bytes nach links oder rechts geschoben werden; dieses kann durch de- bzw. inkrementieren des LMS-Operanden geschehen. Bei dieser Methode wird aber das Byte am Rand einer Zeile eine Zeile höher bzw. tiefer an den linken bzw. rechten Rand gebracht. Das erste Beispielprogramm zeigte dieses.

 

Die Lösung ist, den Bereich der Bildschirmdaten zu erweitern und in eine Folge von unabhängigen waagerechten Datenzeilen aufzuspalten. Abbildung 6.1 illustriert diese Idee schematisch:

 

     Normale Datenanordnung    Datenanordnung für

                               waagerechtes Scrolling

 

Abbildung 6.1.

Anordnung der Daten im Bildschirmspeicher

 

 

Die in obiger Abbildung auf der linken Seite befindliche Anordnung stellt die normale Aufteilung der Bildschirmdaten dar. Das eindimensionale, serielle RAM wird zu einer linearen Folge gestapelt. Das rechte Bild zeigt die Datenanordnung für ein wagerechtes Scrolling. Das RAM ist hierbei natürlich immer noch eindimensional und seriell, wird aber jetzt anders benutzt. Das RAM für jede einzelne Zeile ist größer als eine Bildschirmbreite. Dieses ist kein Fehler; die grundliegende Absicht beim Scrolling ist ja, mehr Information anzuzeigen, als auf den Bildschirm paßt. Ist kein RAM-Bereich vorhanden, der diese zusätzliche Information fassen kann, wird sie auch nicht angezeigt. Mit dieser Datenanordnung kann ein echtes waagerechtes Scrolling erreicht werden. Das Bildschirmfenster kann über den gesamten Datenbereich bewegt werden, ohne daß ein senkrechtes Rollen wie bei den früheren Versuchen auftritt.

 

Der erste Schritt bei der Erzeugung waagerechten Scrollings ist die Festlegung der Länge einer Zeile, wobei der zugehörige RAM-Bereich entsprechend angelegt werden muß. Als nächstes muß eine neue Display-List geschrieben werden, die für jede Mode-Line eine LMS-Anweisung besitzt. Hierdurch wird die Display-List natürlich länger als gewöhnlich (wofür es allerdings auch keinen Hinderungsgrund gibt). Welche Werte sollen nun für die LMS-Operanden verwendet werden? Es könnten z.B. die Adressen der ersten Bytes jeder Datenzeile sein. Für jede Mode-Line, d.h. LMS-Operanden, gibt es dann eine solche Adresse.

 

Sobald die neue Display-List geschrieben und im Speicher plaziert wurde, muß der ANTIC-Prozessor auf sie umgeschaltet werden. Ebenso müßen die Bildschirmdaten in den entsprechenden RAM-Bereich geschrieben werden, damit der Schirm gefüllt wird. Soll nun ein Scrolling durchgeführt werden, müßen die LMS-Operanden de- bzw. inkrementiert werden, wodurch ein Scrolling nach links bzw. nach rechts erfolgt. Das Programm für diese Aktion muß darauf achten, daß nicht über die Ränder des angelegten Bildschirm-RAMs hinaus gescrollt wird. Andernfalls erscheint ein falsches Bild auf der Mattscheibe. Der LMS-Operand muß beim Aufbau des Programms auf das linksseitigste Byte der angezeigten Zeile deuten. Das Maximum für den Wert dieses LMS-Operanden ist die Adresse des letzten Bytes der Speicherzeile minus der Anzahl der Bytes, die in einer Bildschirmzeile angezeigt werden.

 

Da waagerechtes Scrolling ein etwas komplizierter Prozeß ist, soll es hier an einem Beispiel verdeutlicht werden. Als erstes muß die Länge der Speicherzeilen bestimmt werden. Im Beispiel werden Zeilen mit einer Länge von 256 Bytes verwendet, weil dadurch die Berechnungen vereinfacht werden. Jede Zeile verbraucht hierdurch eine Page des Speichers. Im Beispiel wird der BASIC-Modus 2 verwendet, d.h. der Bildschirm besteht aus 12 Zeilen. Dieses wiederum bedeutet einen Speicherbereich von 12 Pages, was 3K-RAM entspricht. Der Einfachheit halber (und um zu garantieren, daß der Bildschirm nicht leer ist) werden die untersten 3K des Speichers benutzt. Dieser Bereich wird vom OS und vom DOS belegt und ist daher mit interessanten Daten gefüllt. Damit das Ganze noch interessanter wird, wird die Display-List auf Page 6 abgelegt. So erscheint sie mit auf dem Schirm, wenn gescrollt wird.

 

Die Anfangswerte der LMS-Operanden sind leicht zu berechnen; die niederwertigen Bytes haben alle den Wart 0, wogegen die höherwertigen Bytes die Werte 0, 1, 2, 3 usw. annehmen. Das folgende Programm führt alle oben genannten Aktionen aus und scrollt dann den Bildschirm horizontal.

 

10   REM  Als erstes wird die Display-List aufgebaut

20   POKE 1536,112:REM    Blank-8-Line

30   POKE 1537,112:REM    Blank-8-Line

40   POKE 1539,112:REM    Blamk-8-Line

50   FOR I=1 TO 12:REM    Schleife zum Einlesen der DL

60   POKE 1536+3*I,71:REM BASIC-Modus 2 mit gesetztem LMS

70   POKE 1536+3*I+1,0:REM Niederwertiges LMS-Operanden Byte

80   POKE 1536+3*I+2,I:REM Höherwertiges LMS-Oparanden Byte

90   NEXT I

100  POKE 1575,65:REM JVB-Anweisung für ANTIC

110  POKE 1576,0:REM DL fängt bei $600 an

120  POKE 1577,6

130  REM  ANTIC wird mitgeteilt, wo sich die DL befindet

140  POKE 560,0

150  POKE 561,6

160  REM  Nun wird waagerecht gescrollt

170  FOR I=l TO 235:REM   Schleife für niederwertige LMS-Bytes

180 REM 235 anstatt 256, da eine Zeile aus 20 Zeichen besteht

190  FOR J=l TO 12:REM Für jede Mode-Line

200  POKE 1536+3*J+1,I:REM Niederwertiges LMS-Byte

210  NEXT J                 neuschreiben

220  NEXT I

230  GOTO 170:REM Endlos-Schleife

 

 

Dieses Programm scrollt die Daten von rechts nach links. Wird das Ende einer Page erreicht, beginnt einfach wieder alles von vorn. Die Display-List kann in der 6. Reihe von oben gefunden werden (Page 6). Sie erscheint als eine Folge von Anführungszeichen.

 

 

Der nächste Schritt wäre das Mischen von senkrechtem und waagerechtem Scrolling. Senkrechtes Scrolling wird durch Addition oder Subtraktion einer 1 am LMS-Operanden erzielt; senkrechtes entsprechend durch Addition bzw. Subtraktion der Zeilenlänge. Diagonales Scrolling kann demnach erreicht werden, wenn diese beiden gemischt werden, d.h. gleichzeitig ausgeführt werden.

 

Es gibt 4 mögliche Richtungen des diagonalen Scrollings. Beträgt die Zeilenlänge z.B. 256 Bytes und es soll nach rechts unten gescrollt werden, so muß ein Wert von 256+(-1)=255 zum LMS-Operanden addiert werden. Dieses ist eine 2-Byte Addition; das obere Programm umgeht die Schwierigkeiten bei der Manipulation von 2-Byte Adressen, was bei den meisten Programmen aber nicht möglich ist. Für schnelles Scrollen in 2 Richtungen ist ein Maschinensprachen-Programm erforderlich.

 

Alle Anordnungen sind möglich, wenn die LMS-Bytes unterschiedlich manipuliert werden. Die Zeilen können gleichmäßig scrollen oder sich gegenseitig überholen. Vieles könnte natürlich mit einem normalen Display gemacht werden, wobei allerdings mehr Daten zur Durchführung notwendig wären. Der wirkliche Vorteil des LMS-Scrollings ist die Geschwindigkeit. Anstatt einen gesamten Bildschirm mit Daten zu bewegen, werden vom Programm nur 2 bzw. etwas mehr Bytes manipuliert.

 

 

FEINES SCROLLING

 

Die zweite wichtige Möglichkeit auf dem ATARI 400/800 "TM" ist die des Fein-Scrollings. Feines Scrolling bedeutet, daß die Zeichen in Schritten, die der Größe eines Bildschirmpixels entsprechen, gescrollt werden. Beim groben Scrolling beträgt diese Größe jeweils nur ein Zeichen; das waagerechte Scrolling hat eine waagerechte Auflösung von einem Color Clock, sowie eine senkrechte von einer Scan-Line. Das feine Scrolling kann allerdings nicht über diese Werte hinaus kleiner werden. Soll feines Scrolling über eine längere Strecke durchgeführt werden, so müßen grobes und feines Scrolling kombiniert werden.

 

Zum Durchführen des feinen Scrollings sind lediglich zwei Schritte erforderlich. Als erstes muß das entsprechende Bit der Mode-Line-Anweisung, die zu der zu scrollenden Zeile gehört, gesetzt werden (in den meisten Fällen gilt dieses für den gesamten Bildschirm, d.h. in sämtlichen Mode-Line-Anweisungen werden die "Fein-Scrolling"-Bits gesetzt). Bit D5 der DL-Anweisung ist das Einschalt-Bit für feines Scrolling in senkrechter Richtung, Bit D4 für das in waagerechter Richtung. Die Werte für die senkrechte und waagerechte Verschiebung werden in zwei Registern gespeichert. Das Register für feines Scrolling in waagerechter Richtung (HSCROL) liegt bei $D404, das für feines senkrechtes Scrolling (VSCROL) liegt bei $D405.

 

Für feines horizontales Scrolling wird die Anzahl der Color Clocks, um die gescrollt werden soll, in HSCROL gespeichert. Beim feinen senkrechten Scrolling wird die Anzahl der Scan-Lines, um die gescrollt werden soll, nach VSCROL gebracht. Die in diesen Registern gespeicherten Werte gelten dann für alle Mode-Lines, deren entsprechende Bits gesetzt sind.

 

Es gibt zwei Faktoren, durch die der Einsatz von feinem Scrolling verkompliziert wird. Beide liegen in der Tatsache begründet, daß ein gescrolltes Display mehr Information als ein nicht gescrolltes anzeigt. Was geschieht z.B., wenn eine Zeile waagerecht um ein halbes Zeichen nach links gescrollt wird? Die Hälfte des ersten Zeichens befindet sich außerhalb des linken Bildschirmrandes und das 40. Zeichen der Zeile wird ebenfalls nach links verschoben. Was nimmt nun diesen rechts freigewordenen ein? Das entsprechende Zeichen wäre das 41. Es gibt aber nur 40 Zeichen in einer Zeile; was geschieht also? Wird grobes Scrolling verwendet, dann erscheint das 41. Zeichen plötzlich auf dem Schirm, sobald das erste Zeichen am linken Rand aus dem Bild verschwunden ist. Dieses plötzliche Erscheinen irritiert das Auge sehr, aber es wurde bereits eine hardwaremäßige Lösung in das Gerät eingebaut: es gibt drei Anzeige-Optionen, welche die Zeilenbreite bestimmen. Es sind folgende: das "Narrow-Playfield" (narrow = eng) mit einer Breite von 128 Color Clocks, das "Normal-Playfield" mit einer Breite von 160 Color Clocks, und das "Wide-Playfield" (wide = ausgedehnt), welches eine Breite von 192 Color Clock besitzt. Diese Optionen werden durch Setzen des zugehörigen Bits im DMACTL-Register ausgewählt.

 

Wird feines waagerechtes Srolling benutzt, dann holt ANTIC mehr Daten aus dem RAM, als vom Display angezeigt werden. Wird DMACTL z.B. auf ein normales Playfield eingestellt, das im BASIC-Modus 0 vierzig Bytes pro Zeile besitzt, dann holt ANTIC in Wirklichkeit Daten, die denen eines Wide-Playfield entsprechen. (In diesem Falle wären es 49 Bytes pro Zeile.) Hierdurch werden die Zeilen waagerecht verschoben, sofern diese Länge nicht berücksichtigt wird. Dieses Problem taucht allerdings nicht auf, wenn das RAM vom Programmierer bereits in lange waagerechte Zeilen aufgeteilt wurde, wie in Abbildung 6.1 dargestellt.

 

Das entsprechende Problem beim senkrechten Scrolling kann auf zwei Arten gelöst werden. Die erste Möglichkeit wäre, es einfach zu ignorieren. In diesem Fall ergeben sich an den Bildschirmrändern keine Halbbilder. Statt dessen werden die Bilder am unteren bzw. am oberen Rand nicht sauber gescrollt; sie springen plötzlich ins Bild. Der richtige Weg erfordert wenig Arbeit. Um ordentliches feines Scrolling zu erhalten (in und aus dem Bildschirm), muß eine Mode-Line als Buffer eingesetzt werden. Dieses geschieht, indem bei dieser (der letzten Mode-Line des zu scrollenden Bereiches) das Bit für horizontales Scrolling nicht gesetzt wird. Das Fenster wird zwar um eine Mode-Line gekürzt, scrollt dann aber ohne das irritierende Springen.

 

Es ist möglich, Bilder für den Schirm zu entwerfen, die eine Höhe von mehr als 192 Scan-Lines besitzen. Bei "festen" Displays würde dies störend wirken. Mit scrollenden Displays aber können Bilder, die sich ober- oder unterhalb der angezeigten Region befinden, immer in den sichtbaren Bereich gescrollt werden.

 

Feines Scrolling besitzt eine senkrechte Begrenzung von 16 Scan-Lines; das waagerechte Limit beträgt 16 Color Clocks. Wird versucht, über diese Begrenzungen hinauszugehen, ignoriert ANTIC einfach die höherwertigen Bits der Scrolling-Register. Um den gesamten Bildschirm fein zu scrollen (und zwar über eine beliebige Entfernung), muß feines mit grobem Scrolling gekoppelt werden. Als erstes wird das Bild fein gescrollt, wobei auf die gescrollte Entfernung geachtet wird. Entspricht der Betrag des feinen Scrollings der Größe eines Zeichens, wird das Feinscrolling-Register auf Null gesetzt und eine grobes Scrolling durchgeführt. Abbildung 6.2 veranschaulicht diesen Vorgang:

 

 

                                                  

Abbildung 6.2.

Verbinden von feinem und grobem Scrolling

 

 

Das folgende Programm ist ein Beispiel für einfaches feines Scrolling:

 

1    HSCROL=54276

2    VSCROL=54277

10   GRAPHICS 0:LIST

20   DLIST=PEEK(560)+256*PEEK(561)

30   POKE DLIST+10,50:REM Für zwei Mode-Lines werden beide

40   POKE DLIST+11,50:REM Scrolling-Möglichkeiten

50   FOR Y=0 TO 7:REM eingeschaltet

60   POKE VSCROL,Y:REM Senkrecht scrollen

70   GOSUB 200:REM Verzögerung

80   NEXT Y

90   FOR X=0 TO 3

100  POKE HSCROL,X:REM Waagerecht scrollen

110  GOSUB 200:REM Verzögerung

120  NEXT X

130  GOTO 40

200  FOR J=l TO 200

210  NEXT J:RETURN

 

Dieses Programm zeigt feines Scrolling in sehr langsamem Tempo und demonstriert einige Probleme, die beim Benutzen dieser Möglichkeit auftreten. Als erstes sind die Zeilen unter dem gescrollten nach rechts verschoben. Grund hierfür ist ANTIC, der sich mehr Daten holt (48 statt 40 Bytes pro Zeile). Dieses Problem taucht allerdings nur in unrealistischen Programmen auf; bei richtiger Verwendung des feinen Scrollings schließt eine ordnungsgemäße Aufteilung der Daten (wie in Abbildung 6.1. gezeigt) dieses aus. Das zweite und ernstzunehmendere Problem taucht auf, wenn ein Scrolling-Register geändert wird, während ANTIC sich in der Mitte seines Anzeigeprozesses befindet. Diese Änderung "verwirrt" den ANTIC-Prozessor, und hat zur Folge, daß der Schirm zittert. Die Scrolling-Register sollten also nur während des Vertical-Blanks geändert werden. Dieses kann allerdings nur mit Assembler-Routinen geschehen. Folglich kann feines Scrolling nur mit Programmen in Maschinensprache erreicht werden.

 

 ANWENDUNGEN

 

Die Anwendungen für feines Scrolling mit Graphiken sind zahllos. Die offensichtlichste Anwendung ist bei großen Karten gegeben, die mit Zeichensatzgraphiken aufgebaut wurden. Im Programm "Eastern Front" wurde mit dem BASIC-Modus 2 eine Karte von Rußland aufgebaut, die sich über 10 Bildschirme erstreckt. Der Fernsehschirm ist ein Ausschnitt dieser Karte. Der Benutzer ist durch Betätigen des Steuerknüppels in der Lage, über die gesamte Fläche zu scrollen. Dieses System ist sehr effizient: das gesamte Kartenprogramm mit Daten, Display-List und Zeichensatz-Definition benötigt einen Speicherbereich von ca. 4K-RAM.

 

Es gibt viele Verwendungen für diese Technik. Jedes mit Zeichensatz erstellte Bild kann mit diesem System verwendet werden. (Scrolling benötigt nicht unbedingt Zeichensatz-Graphiken. Map-Modi-Graphiken sind allerdings ungünstiger, da sie sehr viel Speicherplatz benötigen.) Auf diese Weise könnten große Schaltpläne gezeigt werden, wobei der Joystick zum Scrollen und zum Anzeigen spezieller Dinge auf dem Schirm benutzt werden könnte. Mit dieser Technik kann jedes Bild dargestellt werden, daß nicht ganz auf den Schirm paßt (Z.B. Baupläne).

 

Auch für große Textblöcke könnte dieses System verwendet werden. Da es aber nicht sehr praktisch ist, fortgesetzte Textteile durch Scrolling über das Display zu bewegen und dann zu lesen, ist es für unabhängige Textpassagen besser geeignet.

 

Eine andere Verwendung dieser Technik besteht im Anzeigen spezieller Menüs. Der Benutzer arbeitet mit dem Menü, indem er den Joystick zum Angeben der Operation verwendet. Hat er sich für etwas entschieden, plaziert er einfach über den Steuerknüppel ein Fadenkreuz an der zugehörigen Stelle und drückt den Feuerknopf. Obwohl dieses System nicht für alle Programme verwertbar ist, mag es für einige von um so größerem Nutzen sein.

 

Es gibt noch zwei weitere Anwendungen für das feine Scrolling. Die erste ist das selektive Feinscrolling. Hierbei werden verschiedene Scrolling-Bits unterschiedlicher Mode-Lines eingeschaltet. Normalerweise wird der gesamte Schirm gescrollt, dieses ist aber nicht unbedingt erforderlich. Ein Beispiel hierfür ist das ATARI™ DOS 2.0S.

 

Die zweite Möglichkeit ist, die Scrolling-Register mit Hilfe von Display-List-Interrupts zu ändern. Die Änderung des VSCROL-Registers ist ein schwieriges Unterfangen; ANTIC könnte durch diese verwirrt werden und unerwünschte Resultate anzeigen. Das Ändern des HSCROL-Registers mit dieser Methode ist zwar auch nicht ganz leicht, aber einfacher als das des VSCROL-Registers.