Assembler-Kurs #8 ------------------- von Tim-Philipp Müller Hallo, diesmal geht's hauptsächlich um das leidige Thema Feinscrolling, und zwar in alle Richtungen. Doch vorher noch die zwei bisher noch nicht behandelten Assembler-Befehle, nämlich SED - Set decimal mode CLD - clear decimal mode Nach einem SED 'tut' der Computer so, als ob er dezimal Rechnen könnte, mit CLD wird wieder in den normalen Modus geschaltet. Diese Befehle sind zum Beispiel beim Programmieren von Zählern wie Score- Anzeigen etc. sehr praktisch, denn der Computer setzt das Carryflag jetzt beim Überschreiten des Werts 99. Intern wird das so geregelt, daß 4 Bits nun anstatt 16 Ziffern (0-$F) nur noch 9 Ziffern darstellen. Somit lassen sich die Bytes auch sehr schön zur Anzeige bringen. Bevor wir ins Thema einsteigen, noch ein paar 'Tricks': 1. Man kann Sprünge natürlich nicht nur mit JMP,sondern auch mit den Branch- Befehlen ausführen. Der Vorteil des JMP ist, daß es jede mögliche Adresse erreichen kann. Der große Vorteil der Branches ist nun aber, daß sie Adressenunabhängig sind, allerdings kann man mit ihnen nur +-127 Bytes zurücklegen. Eine Routine, die nur Branch-Sprünge benutzt, ist also beliebig im Speicher positionierbar..! Erzwungener Branch:z.B. CLC SEC BCC .1 BCS .1 2. Oft kommt es vor, daß bestimmte Bits eines Registers einzelne Bedeutungen haben (z.B. Joystickreg.,CONSOL $D01F). Möchte man nun diese Bits abfragen,kann man dies natürlich mit CMP oder AND erledigen. Viel eleganter (und platz- sparender) ist es aber meist, die Bits ins Carryflag zu schieben (per LSR/ASL) und dann per Branch abzufragen. Beispiel: CONSOL $D01F Bit 0=0: START gedrückt Bit 1=0: SELECT Bit 2=0: OPTION LOOP LDA CONSOL LSR Bit 0=0 (Start)? BCC START LSR Select? BCC SELECT LSR Option? BCS LOOP OPTION ... START ... SELECT ... So, nun aber zu unserem heutigen Thema. Um das Prinzip von Finescrolling (engl. scroll: Schriftrolle) zu verdeutlichen, wollen wir erstmal 'Grobscrolling', also quasi 'Ruckeling' realisieren. Stellen Sie sich nun einfach vor, Sie haben vor sich die heutige Zeitung liegen, sagen wir mal mit 120 Zeichen pro Zeile und 240 Zeilen pro Seite. Nun können Sie mit ihrer eckigen Lupe allerdings immer nur 40*24 Zeichen überblicken. Jetzt übertragen wir das ganze auf den Computer und legen die Seite ab der linken, oberen Ecke im Speicher ab. Dann können wir also folgende Skizze aufstellen: Adr. 120 Zeichen ----+----+----+----+----+----+-- + 0 -................................ +120 -................................ +240 -................................ +360 -.............****............... +480 -.............****............... +600 -.............****............... +720 -................................ +840 -................................ usw. Wenn man mit der Lupe (bzw. dem Screen) nach oben möchte, muß man also eine Zeile (120 Bytes) zurück, um nach unten zu gelangen eine Zeile (120 Bytes) vor. Soll es aber nach rechts bzw. links gehen, rückt man nur um eine Stelle (Byte) vor bzw. zurück. In der Computerpraxis verändert man dann also den Bildschirmzeiger (Memory Scan Counter, MSC) entsprechend. Sie erinnern sich noch an die Display-List? Es wäre allerdings auch zu schön gewesen, wenn uns der ATARI jetzt nicht noch einen Strich durch die Rechnung machen würde. Der MSC zählt nämlich nur mit 4 Bits. Das heißt, wenn der interne MSC von $4FFF weiterspringt, nimmt er die nächsten Daten nicht aus $5000, sondern aus $4000, da er die oberen 4 Bits nicht miterhöht. Was machen? Ganz einfach, man setzt den MSC jede Zeile neu. Doch das Problem ist auch erst dann gelöst, wenn man dafür sorgt, daß INNERHALB einer Zeile nie ein 4-Bit Übertrag stattfindet. Und auch das ist nicht schwierig. In der Praxis erhöht man die Länge der Zeilen einfach auf einen Wert, durch den sich $1000 Teilen läßt, sprich z.B. $40,$80,$100,$200,$400,$800. In unserem Beispiel wären dann die ersten 120 Bytes der 1.Zeile belegt, die restlichen freigelassen, denn man achtet ja sowieso darauf, daß das Bild nicht über den 'Kartenrand' hinaus- scrollt. Die nächste Zeile beginnt dann natürlich an Adresse+128. Somit haben wir also das Prinzip des Grobscrollings begriffen. Jetzt fehlen uns nur noch ein paar Speicherstellen und Erinnerungen an die DL: (W)= nur schreiben HSCROL $D404 (W) Verschiebt nach rechts VSCROL $D405 (W) Verschiebt nach oben Es muß eigentlich nur noch geregelt werden, welche der dargestellten Zeilen gescrollt werden sollen (können). Dies geschieht anhand der DL. Ist Bit 4 ($10) gesetzt, ist Scrolling horizontal möglich, bei Bit 5 ($20) ist es vertikal möglich. Auch hier gibt es wieder ein paar Komplikationen: Da im 40-Zeichen Modus (einstellbar über SDMCTL $22F) manchmal 41 Zeichen (39+2 halbe) dargestellt werden müssen, holt sich der Computer automatisch immer 48 Zeichen (beim 32-Mode 40) und erhöht dann den MSC auch immer um 48 statt 40. Um dem abzuhelfen, müssen wir in jeder Zeile den MSC von neuem Setzen. Beim Vertikalscrolling darf Bit 4 in der letzten zu scrollenden Zeile nicht gesetzt sein, sonst erscheint diese auf einen Schlag! So, nun aber zur Feinverschiebung: Schreibe ich statt 0 den Wert 1 in HSCROL, bewegen sich alle Zeilen, die hor. verschoben werden dürfen (DL), um ein Pixel nach rechts, beim Wert 2 noch einmal. Nach 4 Verschiebungen (Wert springt von 3 auf 4) habe ich in Gr.0 das Zeichen um ein ganzes Zeichen nach rechts verschoben. Nun kann ich wie beim Grobscrolling den MSC erhöhen, und dann HSCROL wieder auf 0 setzen. Bei einer Linksbewegung durchläuft HSCROL die Werte 0,3,2,1(,0), bis es weitergesetzt wird. Leider wird die Zeile horizontal um eine Strecke von zwei Gr.8-Pixeln verschoben. Horizontal durchläuft VSCROL 0-7, bzw. 7-0, bis eine ganze Zeile verschoben ist. Am anschaulichsten ist das Ganze in den drei Beispiellistings dargestellt (Horizontal, Vertikal, kombiniert). Da in HSCROL und VSCROL nur geschrieben werden kann, muß man sich eigene Variablen schaffen, die man verändern kann, und die dann in die Register übertragen werden. In den Listings habe ich teilweise eine eigene Routine benutzt, die die Adressen der Zeilen nach den X- und Y-Position des Screens in der Karte in die DL einträgt. Scrollroutinen sind übrigens sinnvoll im VBI aufgehoben, da die Änderung außerhalb des Bildaufbaus erfolgt. Unabhängig scrollende Fenster und Zeilen sind natürlich per DLI zu erreichen. So, ich hoffe wieder einmal, alle haben meine Ausführungen verstanden. Wenn nicht, schreibt...!!! Bye, bis zum nächsten Mal.