Magic Disk 64

home to index
          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 beeindruckend wurde es durch die Vertikal-Bewegung, durch das sog.' Linecrunching' was soviel wie ' Zeilen-Komprimierung' bedeutet.
In Spielen setzte sich der Trick nur sehr träge durch. In den beiden " Stormlord"- 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" verwendet 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 erwähnt wurde, wollen wir nun zum Theoretischen 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 umfangreiche 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 lediglich 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 1 Mhz 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 dargestellt; 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 Textund 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( Rasterzeilen- 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 " abgezwickt" 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 arbeitet 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 abgeschlossen 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 Platzieren", denn es ist bei Tricks mit dem $ d011- Register viel Erfahrung, Geduld und vielleicht auch ein wenig Glück notwendig, doch ist dieses Grundschema der getimtem Zeilen-Initialisierng der ( !) Baustein beim Bitmap-Scrollen und Linecrunchen.
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 aufzubauen 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 " versetzte" Darstellung des gesamten Screen-Inhaltes, ab der Rasterzeile, in der wir den VIC überlisten.
Wie weit der Inhalt nun nach rechts verschoben 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 (1 Mhz) genau der Zeit entspricht, die der Strahl für die Darstellung von 8 Hires-Pixel braucht, kann man also mit geschicktem Austimen des Opcodes den Bildschirm-Inhalt cursorschrittweise 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 Bildschirm, 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 diesmal anhand eines Source-Codes, welchen ich ausführlich dokumentieren und erklä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, obwohl 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 richtiggesetzt ( muß jeden Rasterdurchlauf reinitialisiert werden!) und auf die entsprechende Raster-Y- Position gewartet ( 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. geschrieben wird, erniedrigen wir das Register $ d02 f, 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 $ d02 f! 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 #$5 f. 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,$ d02 f reinitialisiert ( 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 durchfü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 nachdem, 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 " Bitmap- 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 2 x2 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 erstellen. Beim anwählen der Pages ändert sich die Rahmenfarbe mit, das heißt, daß jede Page seine bestimmte Farbe anzeigt. Somit ist das Arbeiten im Field-Editor leichter, da in diesem das vollstä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 40 x20 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," redefined" Format gebracht wird ( der Bildschirmrand 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 entsteht.
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 verwenden, dann ist folgende Schrittfolge anzuwenden:
Zuerst speichern wir die Grafik( Squares) als " redefined Grafics" ab ( Bereich von $2000 bis $3 f3 f) . 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 beeinflussen. . .
. . . 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 ( linecrunching) werden 7 Sprites ( Xund Yexpanded) dargestellt. Die Koordinaten, Blöcke und Farben werden im Programm initialisiert. Durch gezieltes Ändern ist diese Gestaltung selbst frei einzurichten ( die Y- Koordinaten müssen allerdings gleichbleiben; Timing!) .
2 . Das Programm arbeitet in einem Hauptund einem Interrupt-Teil. Der Hauptteil wartet immer wieder darauf, ob neue Zeilen aufgebaut werden müssen.
Im Interrupt werden die Tasten abgefragt, 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 Hauptoder 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 verankert wurde ( in die Area wird das Square also auf jeden Fall geschrieben) .
4 . Gescrollt wird, indem man die gewü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 werden 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 einund 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 $47 f8 . Gewöhnlich ist dieser Bereich frei verfügbar, da der Text-Bildschirm nur einen Bereich von 1000 Bytes braucht ( also bis $47 d7) .
Doch durch das Linecrunching kommt dieser sonst unsichtbare Bereich auch zum Vorschein, da der VIC bei der Darstellung des Screens dort fortsetzt, wo er aufgehört hat ( also bei $47 d8, und erst nach $47 ff springt er zu $4400 zurü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)