16-FARBEN-SCROLLING
"Wow! - So bunt und'n irrer Speed!"; so in etwa lauteten die Reaktionen auf die ersten 16-Farben-Bitmaps, die vom VIC gesteuert über den Bildschirm des C64 rasten. Natürlich, wie so oft, waren die ersten Programmierer, die den Brotkasten einmal mehr austricksten, Coder aus der Demo- Szene. Zuerst sah man die Bitmaps nur horizontal "tanzen", doch richtig beein- druckend wurde es durch die Vertikal- Bewegung, durch das sog.'Line-crunching' was soviel wie 'Zeilen-Komprimierung' bedeutet. In Spielen setzte sich der Trick nur sehr träge durch. In den beiden "Storm- lord"-Games waren zwar bunte Pixels am Scrollen, doch war dies durch gesamtes Neuaufbauen und Umschalten zwischen zwei Screens realisiert worden. "Phobia",ein altes Baller-Spektakel bediente sich des Horizontal-Tricks, um beim Scrollen (ein Charakter+$d800-Farbram-Scroller) Prozessor-Zeit zu sparen. Selbiger Trick, allerdings schon für bunte Bitmaps, wurde in "Eskimo Games" ver- wendet und "Another World" lief sogar mit Linecrunching-Scrolling, allerdings nur horizontal. Sogar "Creatures" wartete mit Bitmap-Scrolling auf, doch nur im Miniatur-Format um die Level- Übersich darzustellen. Das Spiel selbst scrollte wieder in normalen Character- Modus... Wir sehen, daß sich der Trick mit dem bunten 8-Wege-Scrolling in Spielen noch nicht manifestieren konnte. Warum, wo die Schwierigkeiten und Hindernisse liegen, welche Möglichkeiten es gibt, sie zu überwinden und wo letztendlich die Grenzen des C64 in diesem Bereich liegen, das versuche ich in diesem Kurs zu übermitteln. Folgender ist in 3 Teile unterteilt: Teil I: Einführung, Theoretisches Teil II: Beispiel und Dokumentation anhand des Source-Codes Teil III: Praxis, Einbinden des Codes in eigene Programme, Arbeiten mit dem "Bitmap-Manager". Da zur Einleitung eigentlich alles er- wähnt wurde, wollen wir nun zum Theore- tischen kommen. Um diesen Kurs mehr oder weniger erfolgreich zu absolvieren sind als Vorraussetzung recht gute Assembler- Kenntnisse sowie Erfahrung mit dem VIC des C64 mitzubringen. Ich werde mich aber bemühen, dieses doch recht umfang- reiche Thema so einfach wie möglich, und vor Allem für jeden verständlich zu erläutern. Beim Thema Bitmap-Grafik-Scrolling ist immer die Rede von einem Trick. Ja logisch, oder ? Beim 'normalen' Scrollen im Character-3-Farben-Modus ist ledig- lich beim Überlauf eines der beiden Scroll-Register der Screen-Inhalt um ein Zeichen zu verschieben. Im Grafik- Modus sieht's da ganz anders aus: Zu verschieben sind die gesamte Bitmap, der Screen und das Farbram, also insg. knapp 10 KB. Kurz gesagt für einen C64 mit einer Taktfrequenz von 1Mhz ist das flüssige Scrolling einer solchen Daten-Menge schier unmöglich... ...doch - da war doch dieses eine Demo, mit dem großen bunten Logo, das da in alle Richtungen flog, so schnell und flüssig, Sprites wurden auch noch dar- gestellt; als ob Bitmap-Scrolling noch weniger Prozessor-Zeit schlucken würde, als übliches Scrolling.
UND GENAU DAS (!) IST ES.
Am C64 gibt es eine Möglichkeit, den Bildschirm ohne enormen Rasterzeit- Verlust in alle Richtungen zu bewegen, als ob man die Start-Werte links oben für Text-und Grafik-RAM selbst wählen kann. Wer sich am Amiga auskennt, der weiß, daß es dort durch Register ganz einfach ist, die Start-Werte links oben für die Grafiken zu bestimmen; ab jetzt auch für den C64 !!! Gut, Haupt-Register der Scroll-Routine ist das Register $d011 (wer öfter mit dem VIC herumexperimentiert, weiß, daß jenes Register bei den meisten Tricks und Effekten (FLI,FLD,...) die Haupt- Regie führt). Grundlegend ist das $d011-Register wie folgt belegt: Bit 0-2...Softscrolling (Werte 0-7) Bit 3.....1=24 Zeilen,0=25 Zeilen Bit 4.....0=Screen off,1=Screen on Bit 5.....0=Charmode,1=Bitmapmode Bit 6.....1=Extended Colourmode Bit 7.....8.Bit von Reg.$d012 (Raster) Wichtig ist es zu wissen, daß der VIC sich jede 8.Rasterzeile (im Bereich des Textes/der Grafik), und zwar zu Beginn jeder Cursor-Zeile, Informationen aus dem Bildschirm-Inhalt holt um die Cursor Zeile korrekt darzustellen. In welchen Raster-Zeilen dies geschieht,hängt davon ab, welche Werte das Reg.$d011 in den ersten 3 Bits aufweist. Und genau diese Abhängigkeit von Scroll-Register $d011 zum Neu-Initialisiern jeder neuen Cursor Zeile des VIC macht die Sache so enorm interessant... Durch genaues Timing ist es nämlich möglich, das Neu-Initialisieren einer Zeile durch den VIC zu verzögern, indem man den $d011-Scrollwert gerade dann verändert, wenn eine Cursor-Zeile z.B. erst halb aufgebaut ist und im selben Frame (Rahmen = 1 Rasterdurchlauf) wieder auf den ursprünglichen Wert von zuvor zurücksetzt. Der VIC baut nämlich eine neue Zeile immer erst dann auf, wenn die ersten 3 Bits aus Reg.$d011 mit den ersten 3 Bits von Reg.$d012 (Raster- zeilen-Y-Position) übereinstimmen. So ist die Y-Position der Cursor-Zeilen- Initialisierung linear zum $d011-Scroll- Register auf 8 (0-7) Werte flexibel. Nebenbei sei erwähnt, daß der Prozessor dadurch in jeder 8. (eben in dieser!) Rasterzeile um einige Taktzyklen weniger Rechenzeit hat, da diese vom VIC "abge- zwickt" werden um Werte für die Cursor- Zeilen Initialisierung und Darstellung aus dem Bildschirm-Inhalt zu holen. Dies berührt uns im Moment zwar wenig, ist aber für das spätere 'Linecrunchen' von großer Bedeutung da dort Timing auf Zyklen genau verlangt wird. Gut, da wir nun wissen, wie der VIC ar- beitet und auf welche Weise er vorgeht, um Cursor-Zeilen (egal ob Grafik oder Text) darzustellen, könnte man auf die sinnlose Idee kommen, durch Austimen mit dem $d012-Register ganze Cursor-Zeilen bereits darzustellen, obwohl die Zeile zuvor in ihrer Darstellung nicht abge- schlossen war. Das hieße, eine Zeile sozusagen "künstlich" zu platzieren. Es ist zwar nicht ganz so einfach,wie es klingt, das mit dem "künstlichen Plat- zieren", denn es ist bei Tricks mit dem $d011-Register viel Erfahrung, Geduld und vielleicht auch ein wenig Glück not- wendig, doch ist dieses Grundschema der getimtem Zeilen-Initialisierng der (!) Baustein beim Bitmap-Scrollen und Line- crunchen. Zuerst möchte ich das Scrolling in der Horizontalen erklären: Wir wissen: Der Bildschirm wird 50 mal pro Sekunde neu aufgebaut. Ein Ganzbild besteht aus 312 Rasterzeilen. Dabei jagt der Elektronenstrahl jede Zeile von links nach rechts, um die Partikel zum Leuchten zu bringen. Nach der 312. Zeile wird der Strahl wieder nach links oben gesetzt, dadurch entsteht die sog. vertikale Austastlücke (es gibt auch eine horiz.Austastlücke, bedingt durch das Zurücksetzen des Elektronenstrahls nach links, wenn er den rechten Rand erreicht hat). Um nun den VIC zu überlisten, müssen wir einfach einen Zustand produzieren, in welchem er eine neue Cursor-Zeile auf- zubauen beginnt. Diesen Moment wählen wir so, daß der Elektronenstrahl gerade über den sichtbaren Bereich rast. Wenn er nun das Kommando für den Aufbau einer neuen Cursor-Zeile erhält, stellt er diese sofort dar, auch wenn der Strahl sich gerade z.B. in der Bildschirm-Mitte befindet. So produzieren wir eine "ver- setzte" Darstellung des gesamten Screen- Inhaltes, ab der Rasterzeile, in der wir den VIC überlisten. Wie weit der Inhalt nun nach rechts ver- schoben wird (der Bereich, der rechts hinausgeschoben wurde, wird übrigens und logischerweise links, eine Zeile tiefer, wieder sichtbar), hängt von der horiz. Position des Elektronenstrahls ab. Da ein Prozessor-Takt (1Mhz) genau der Zeit entspricht, die der Strahl für die Dar- stellung von 8 Hires-Pixel braucht, kann man also mit geschicktem Austimen des Opcodes den Bildschirm-Inhalt cursor- schrittweise verschieben. Das X-Soft- Scrolling erledigt ohnehin Reg. $d016, und schon funktioniert der Trick mit dem Horizontalen Bildschirm-"Wanken"! Das Vertikalscrolling oder Linecrunching funktioniert ein wenig(!) komplizierter. Gesagt sei nur kurz, daß dabei beliebig viele Cursor-Zeilen nach oben unsichtbar "zusammengestaucht" werden, um den Bild- schirm, wie zuvor nach rechts, diesmal nach oben zu versetzen... Programmierer, für welche dieses Gebiet absolut Neuland ist, sollten sich durch das viele Theoretische nicht verwirren lassen. Im Teil 2 wird der dokumentierte Source-Code für Klarheit sorgen...
(hs) 16-FARBEN-SCROLLING Teil II
Im ersten Teil dieses Kurses wurde viel Theoretisches gesagt. Um nun langsam (!) zur Praxis zu kommen, wollen wird dies- mal anhand eines Source-Codes, welchen ich ausführlich dokumentieren und er- klären werde, einen Schritt in Richtung "Linecrunching", so wie's wirklich funktioniert, machen. Der "Linecrunching-Sourcecode" als sequentielles File, wurde nur wenig dokumentiert. Doch sollte er für jeden, der folgendes Kapitel "durchackert" hat, leicht verständlich sein. Um kurz zu wiederholen: Horizontale Bildverschiebung erreichen wir, indem wir den VIC dazu bringen, eine neue Cursor-Zeile aufzubauen, ob- wohl die alte noch nicht abgeschlossen wurde und der darstellende Elektronen- Strahl gerade am sichtbaren Bereich unterwegs ist. So läßt sich durch Timing eine X-Versetzung auf Cursor-Positionen genau erreichen. Vertikal dupliziert sich die Trickserei! Und zwar simuliert man für den oberen Screen-Bereich beliebig viel Cursor- Zeilen, dir nur eine Rasterzeile hoch sich (Verhältnis 1:8). So werden die Zeilen "geschrumpft" und der Bildscirm- Inhalt nach oben gezogen. Was oben fehlt kommt (so wie beim Horizontalen Versetzen rechts) unten wieder rein. Gut, nun wird's ernst. Sehn' wir uns die Sache mit dem $d011-Register genauer an:
lda #$1b ;Register sta $d011 ;reinitialisieren lda #$2c fl1 cmp $d012 ;auf Rasterzeile #$2c bne fl1 ldx #4
fl2 dex ;extaktes Timing bne fl2 Bis jetzt wurde nur $d011 richtig- gesetzt (muß jeden Rasterdurchlauf re- initialisiert werden!) und auf die entsprechende Raster-Y-Position ge- wartet (hängt ja bekanntlich vom 3-Bit-Wert im $d011-Register ab. Die Schleife danach bringt nur genaueres Timing, damit der Rasterstrahl in etwa dort ist, wo wir ihn brauchen (dieses Timing ist noch nicht auf Zyklen ganau; die Schwankungen liegen von 1-4 Taktzyklen).
fl4 lda dtab,x ;$d011-Wert-Tabelle dec $d02f ;$d02f(?) erniedrigen sta $d011 ;Wert schreiben inc $d02f ;(?) wieder erhöhen nop ;Timing-nops! . . u.s.w. .
Zuerst wird der entsprechende $d011-Wert aus einer angelegten Tabelle (kommt noch!) ausgelesen. Danach folgt wieder was typisch "C64-Mäßiges": Bevor nun der ausgelesene Wert ins $d011-Reg. ge- schrieben wird, erniedrigen wir das Register $d02f, um es danach wieder zu erhöhen. Rein sinnlos, oder ? Doch wer die beiden "Sinnlosigkeiten" aus dem Code entfernt, wird sich wundern: Kein Linecrunching ohne $d02f! Warum ? Wer den C64 so lange und gut kennt wie ich, fragt so was nicht. Er wundert sich gar nicht mal. Danach kommt wieder Rasterzeitfüllendes Timen. Erwähnt sei, daß ein NOP-Befehl genau 2 Taktzyklen benötigt, wohingegen ein BIT $XX-Befehl 3 braucht. So läßt sich auf Zyklen genau verzögern. Ein entsprechendes Beispiel finden wir später beim X-Scrollen, da wir dort den Rasterstrahl ja an jeder möglichen X-Position austricksen werden. .
. ...und weiter: . inx ;Pointer erhöhen up cpx #2 ;fertig ? bne fl4 fll4 lda dtab+1,x ;aus Tabelle+#1 dec $d02f ;wie gehabt sta $d011 inc $d02f nop . . .
Ab "fll4" passiert anscheinend ganau dasselbe wie zuvor, doch: Wir lesen den $d011-Wert aus der Tabelle+1. Warum ? Folgende Rasterzeilen wird sozusagen nur Zeit verbraucht, um die Lücke zu füllen. Die Lückenspanne ist linear zur Y-Versetzung. Wenn viele Zeilen "ge- staucht" werden, ist die Spanne klein - und umgekehrt. Und dadurch, daß wir aus der Tabelle+1 lesen, passiert gar nichts. Allerdings müssen wir in $d011 etwas schreiben, da wir sonst mit dem Soft-Scrolling in Y-Richtung nicht zurechtkommen. .
. ...und weiter: . inx ;Pointer erhöhen cpx #28 ;Zeilen-Limit ? bne fll4 ;zurück! ldx #1 fl5 dex ;wieder timen... bne fl5 lda #$59 ;Neuer Fix-Wert für sta $d011 ;$d011 ldx #$4f ;x-Reg.für Raster-Check lda #$5f ;$d011-Wert in Akku fl6 cpx $d012 ;Rasterzeile schon bne fl6 ;erreicht ? ldx #3 fl7 dex ;und wieder timen... bne fl7 sta $d011 ;jetzt in $d011!
Linecrunching ist abgeschlossen (max. 28 Rasters!) und zwischen den gewohnten "Austimereien" wurde der Fixwert #$59 in $d011 geschrieben und anschließend nochmal #$5f. Das war die Vorbereitung für das X-Scrolling, dem jetzt nichts mehr im Wege steht...
lda #208 ;Border eng ora xsoft ;mit Xsoft verknüpft sta 53270 ;ins X-Scroll-Register lda #$0f sta $d02f ;$d02f zurücksetzen ldx #3 jumpi dex ;zum Xten mal Timen bne jumpi
Alles ist nun vorbereitet: "Softscroll- 3-Bit-Byte" (0-7) verknüpft, $d02f re-initialisiert (für nächsten Durchlauf notwendig!) und wieder Verzögerung. Warum zwei mal ins $d011-Reg.geschrieben wird, ist auch ganz einfach: Durch diese besondere Zusammensetzung der beiden Werte und auch dem Zeitraum zwischen den beiden, erreichen wir, daß der Prozessor nun den nächsten Befehl auf einer fixen Raster-X-Position durch- führt. D.h. das relativ ungenaue (auf 1-4 Zyklen genaue) Timing ist jetzt auf 1 Taktzyklus genau. Und genau das ist absolut notwendig für den X-Trick, für das sog. Hard-Scrolling...
lda #$59 ;Wert für $d011 xhard bne jumpl+0 ;variabler jump jumpl cmp #$c9 ;22 x "cmp #$c9" cmp #$c9 . . cmp #$c9 bit $ea ;versteckter "NOP" sta $d011
Im Grunde genommen sind diese 22 platz- füllend wirkenden "cmp #$c9" wieder Timer-Elemente. Und zwar ist der Jump- BNE-Befehl ausschlaggebend: Gesprungen wird immer (da #$59 ja unequal 0 ist!), und zwar soweit, wie wir in xhard+1 schreiben. Logische Werte wären 0-39, da wir eine Cursor-Auflösung von 40 Zeichen haben. Wir wissen, daß wir eine Verzögerung von 0-39 Taktzyklen brauchen, um den Screen an alle möglichen Position versetzen zu können. Genau das erledigen die "CMP #$c9" Befehle. Wenn wir uns den Opcode dieses Befehls in einem Monitor ansehen, merken wir, daß der Opcode des Befehls "CMP" den Wert #$c9 besitzt. Das heißt, wir können den BNE-Jump irgendwo in die Liste steuern, und der Prozessor wird immer "CMP #$c9" entdecken, egal ob der Wert nach dem "BNE" (xhard+1) gerade oder ungerade ist. Schließlich wird die "CMP #$c9"-Liste noch mit einem "BIT #$ea" abgeschlossen. Erraten! #$ea ist der Opcode-Wert für "NOP". Nun liest der Prozessor je nach- dem, ob es eine gerade oder ungerade Sprungadresse ist, folgende Befehls- Serien... gerade: ungerade:
... ... cmp #$c9 cmp #$c9 cmp #$c9 cmp #$c9 cmp #$c9 cmp #$24 ;#$24 = Opcode bit #$ea nop für BIT
Diese Lösung scheint auf den ersten Blick vielleicht ein wenig aufwendig und kompliziert, doch wenn man das Prinzip und die Problemstellung richtig verstanden hat, so entdeckt man einen kleinen Touch von Genialität dahinter. Gut, auch diesmal war wieder 'ne Menge "Stuff" dabei, der Köpfe zum Rauchen bringen kann. Doch Assembler-Tüftler werden mit Hilfe des Source-Files bald den Durchblick haben.
Der HAMMER und die KRONE im Teil 3: Scroll-Action pur für eigene Projekte und ein super Editor für bunte, riesengroße Scrollfields... (hs/wk) 16-FARBEN-SCROLLING Teil III
Endlich! Diesmal wollen wir das Ding mit der $d011-Trickserei hinter uns bringen. Als Krönung dazu befindet sich der "Bit- map-Manager" auf der Diskette. Dieser Editor verwaltet Grafik-Areas für die Routine des dok.Scroll-Source-Codes der vorigen Ausgabe. Zu Beginn eine kurze Einführung in das Arbeiten mit diesem Editor... Mit dem "Bitmap-Manager" lassen sich Grafik-Backgrounds in einem Format von 100 x 40 Squares gestalten. Ein Square ist ein Feld der Größe von 2x2 Cursors. Insgesamt also eine Area von rund 5 x 4 Screens. Die Squares werden von einem Grafik-Bild von 40 x 20 Chars ausgelesen (z.B.ein normales Koala-Pic in der Höhe von 20 Chars), womit wir bei 200 verschiedenen Squares wären. Zu Beginn befindet man sich im Haupt- Menu, in welchem man mit den Cursor- Tasten und Return bestimmte Funktionen startet. Wenn wir in den Field-Editor gelangen, gelten folgende Tasten als funktionstüchtig:
Return,Pfeil links........ins Haupt-Menu Cursor oder Joystick.....Pointer bewegen 1-8........................Square setzen Space oder Feuer........Square #0 setzen F1/F2...................Hintergrundfarbe F7....................in den Page-Editor +,-...................Page 0-31 anwählen shift+clr home...........Area löschen(!) *...................Sprite-Block-pointer (die '*'-Funktion wird später noch genauer erläutert werden...)
Die Squares lassen sich also mit den Tasten 1-8 setzen, abhängig von der aktuellen Page. Um nun die Pages zu editieren, gelangen wir mit 'F7' in den Page-Editor, welcher mit folgenden Tasten bedient wird:
F7...................in den Field-Editor Cursor oder Joystick.....Pointer bewegen 1-8.............Square in Page schreiben +,-........................Page anwählen
So lassen sich 32 verschiedene Pages er- stellen. Beim anwählen der Pages ändert sich die Rahmen-farbe mit, das heißt, daß jede Page seine bestimmte Farbe an- zeigt. Somit ist das Arbeiten im Field- Editor leichter, da in diesem das voll- ständige Darstellen der 8 Squares einer Page aus technischen Gründen nicht möglich ist. Orientierung schafft nur die Page-Nummer rechts oben und eben die entsprechende Rahmenfarbe.
NUN GANZ PRAKTISCH:
Wie gestalte ich mein eigenes Demo/Game? Zuerst mal wird gemalt. Ein Picture in der Größe 40x20 Cursors, welches alle 200 Squares repräsentiert. Abgespeichert wird im Koala-Format. Nun läßt sich dieses Bild mit dem "Bitmap-Manager" laden, wonach es in das richtige, "re- defined" Format gebracht wird (der Bild- schirmrand flackert kurz). So, nun kann's schon mit der Field- Gestaltung losgehen. Zuerst mal die Pages zusammenstellen. Am Besten die Squares, die in Verbindung miteinander stehen (ganze Grafik-Elemente), in die gleiche Page bringen. Jetzt zurück in den Field-Editor und den Background designen... Hat man sich einmal an das Prinzip mit den Pages und dem 1-8-Modus gewöhnt, läuft das Gestalten so richtig schnell und macht Spaß. Vor Allem dann, wenn man schon weiß, wo bestimmte Squares sind, die man z.B. öfter braucht, was nach einer gewissen Zeit sowieso ent- steht. Gut, die Area ist abgeschlossen und wir begeben uns wieder ins Hauptmenu. Dort speichern wir vorsorgend gleich die Pages und die gesamte Area ($c000- $cfa0). Beim Wiederbearbeiten einfach die Grafik, Area und Pages reinladen, und losgeht'S (die Pages haben also nur für den Editor Bedeutung)! Wollen wir ernst machen und den gesamten Background für ein eigenes Projekt ver- wenden, dann ist folgende Schrittfolge anzuwenden: Zuerst speichern wir die Grafik(Squares) als "redefined Grafics" ab (Bereich von $2000 bis $3f3f). Bevor wir nun die Routine starten (ich rede vom Sourcecode der letzten Ausgabe von Kurs Teil 2), laden wir die Area ($c000) normal und die "redefined Grafic" (gespeichert ab $2000) nach $e000 in den Speicher. Wenn wir jetzt die Routine starten, haben wir nicht viel Unterschied zum Editor, da die Routine (vom Sourcecode) dem Editor ähnlich ist. Aber wir befinden uns schon mal im Assembler und können die ganze Sache entscheidend beeinflus- sen... ...ab hier ist jeder Programmierer auf sich selbst angewiesen. Man sollte sich ein wenig in den Code einarbeiten und herumexperimentieren. Ein wenig Tips und Hilfe möchte ich hier aber noch auflisten: 1.Im schwarzen, oberen Bereich (line- crunching) werden 7 Sprites (X-und Y-expanded) dargestellt. Die Koordi- naten,Blöcke und Farben werden im Programm initialisiert. Durch ge- zieltes Ändern ist diese Gestaltung selbst frei einzurichten (die Y- Koordinaten müssen allerdings gleich- bleiben; Timing!). 2.Das Programm arbeitet in einem Haupt- und einem Interrupt-Teil. Der Haupt- teil wartet immer wieder darauf, ob neue Zeilen aufgebaut werden müssen. Im Interrupt werden die Tasten abge- fragt, die Softscreenmoving-Routine aufgerufen sowie ins Linecrunching verzeigt. Wird nun im Hauptprogramm gerade eine Cursor-Zeile aufgebaut, wird der Vorgang meist,denn er dauert eine gewisse Zeit, vom Interrupt unterbrochen. Also: Routinen,die alle 1/50 Sekunde stattfinden müssen, werden einfach in den Interrupt eingabaut. Dabei ist zu beachten, daß nicht zuviel Rasterzeit verbraucht wird, da das Linecrunching zur bestimmten Rasterzeile unbedingt stattfinden muß. Wenn die freie Zeit zuwenig ist, einfach den Raster-IRQ- Einsatz um ein paar Zeilen verfrühen, und sozusagen vom Haupt-oder Aufbau- Programm etwas abzwicken. 3.Im Sourcecode befindet sich eine Routine mit dem Namen "SET PIECE". Wenn ein Square auf den Bildschirm gestzt wird, muß sie aufgerufen werden. Die "set piece"-Routine ist sehr praktisch: Sie prüft, ob das Square, welches gesetzt wird, im sichtbaren Bereich liegt oder nicht. Wenn ja, wird es in die angezeigte, aktuelle Bitmap geschrieben. Wenn nicht, dann nur als Byte in der Area festgehalten, d.h. wenn dorthin gescrollt wird, wird jenes Square angezeigt, da's ja in der Area ver- ankert wurde (in die Area wird das Square also auf jeden Fall geschrie- ben). 4.Gescrollt wird, indem man die ge- wünschten Werte direkt in den Opcode der Screenmoving-Routine schreibt. Die Labels heißen "mo1"-"mo4". Also um nach oben zu scrollen, den Soft- Wert nach "mo1+1" schreiben und die Routine Screenmoving aufrufen. Die Werte können von 0-8 liegen und wer- den nach jedem Aufruf automatisch gelöscht. Zum Schluß möchte ich noch auf einen kleinen "Hindernis"-Umstand eingehen, welchen ich oben zu Beginn dieses Kurs-Teiles angesprochen habe. Es geht um den Sprite-Blockpointer-Bereich, welcher sich im Editor durch die "*"- Taste und im Sourcecode mit der Return- Taste ein-und ausschalten läßt (diese 8 nebeneinanderliegenden (phew!) Cursor- Bytes "flashen" dann). Bekanntlich belegen die Blockpointer für die Sprites die letzten 8 Bytes des aktuellen Text-Bildschirms. In unserem Beispiel liegt dieser ab $4400, die Blockpointer also ab $47f8. Gewöhnlich ist dieser Bereich frei verfügbar, da der Text-Bildschirm nur einen Bereich von 1000 Bytes braucht (also bis $47d7). Doch durch das Linecrunching kommt dieser sonst unsichtbare Bereich auch zum Vorschein, da der VIC bei der Dar- stellung des Screens dort fortsetzt, wo er aufgehört hat (also bei $47d8, und erst nach $47ff springt er zu $4400 zu- rück). Dies ist auch der Grund, warum beim Linecrunchen der Bereich auch in X- Richtung versetzt auftaucht, nämlich genau um diese 24 Bytes/Cursors! Um mit diesem Umstand keine "Troubles" zu bekommen, läßt man jene Cursors einfach leer oder vom Screen-Colour-RAM unbeeinflußt (nur $d800-Farb-RAM!). Wenn man auf Sprites über der Scroll- Area verzichtet, stellt sich selbiges Problem ohnehin nicht. Mein letzter und vielleicht wichtigster Tip lautet:
Durchbeißen! Durchbeißen! Durchbeißen!
...und NIIIIIEEMALS aufgeben!
(Hannes Sommer,'93)