Assembler für Einsteiger - Teil 6 ----------------------------------- von Tim-Philipp Müller Diemal geht's um die Display-List, kurz DL, die vor allem dem Assembler- Freak umfangreiche Möglichkeiten bietet, sein neuestes Programm graphisch ein wenig aufzubereiten. Die Display-List ist quasi ein eigenes Programm für den Graphik-Chip im XL/XE, das diesem angibt, wo auf dem Screen jeweils Zeilen eines bestimmten Grafik- oder Text-Modus zu sehen sind. Die Display-List wird durch eine Reihe von Bytes dargestellt, die jeweils verschiedene Bedeutungen haben (Besprechung später). Auf die DL zeigt der Vektor $230,$231 SDLSTL als Schattenregister oder $D402,$D403 DLIST als Hardwareregister Nun zur Bedeutung der Bytes. Zuerst: ----- DIE AUSNAHMEN, nämlich: $00 1 leer-Scanline $10 2 leer-Scanlines $20 3 leer-Scanlines $30 4 leer-Scanlines $40 5 leer-Scanlines $50 6 leer-Scanlines $60 7 leer-Scanlines $70 8 leer-Scanlines $41 DL zuende. VBI auslösen. Zwei folgende Bytes zeigen wieder auf den Anfang der DL... Eine Scanline ist eine Zeile von der Höhe einer Graphics-8 Zeile, und wird in Rahmenfarbe dargestellt. Am Anfang jedes Bildschirms sollten 24 leere Scanlines stehen. ----- NICHT-AUSNAHMEN... Bits 0-3 : ANTIC Graphic-Modus siehe Tabelle unten Bit 4 $10 =1: Horizontal-Finescrolling bei Text ermöglichen. (Register: $D404 HSCROL) Bit 5 $20 =1: Vertikales Finescrolling bei Text ermöglichen. (Register: $D405 VSCROL) Bit 6 $40 =1: Memory Scan Counter neu setzen. Es folgen zwei weitere Bytes, die die Adresse angeben, aus denen die weiteren Bild- daten genommen werden sollen. (siehe unten) Bit 7 $80 =1: DLI auslösen (->Kurs 5) (Display-List-Interrupt) Die ANTIC-Modi entsprechen leider nicht den Werten der Graphics- Befehle in BASIC. Deshalb hier eine 'Übersicht': -------------------------------------- Text-Modi: Die beiden letzten Zahlen bedeuten: Zeichen pro Zeile Scanlines pro Zeile (Bildschimzeilen) -------------------------------------- --- ANTIC Mode 2 --- GR.0 -----40--8--- Entspricht einer Zeile in Graphics 0. --- ANTIC 3 -------- GR.- -----40-10--- Ist in der Auflösung der Zeichen gleich mit Graphics 0, nur daß er pro Zeichen zwei Bildschirmzeilen mehr hat. Dies erlaubt die Darstellung von Zeichen mit Unterlängen (Speedscipt 3.0 nutzt das). Bei Zeichen aus den ersten Vierteln des Zeichensatzes werden unten einfach zwei Zeilen angefügt, bei Zeichen aus dem letzten Viertel (Kleinbuchstaben) werden die Zeilen oben angefügt, und wie folgt verschoben: Die oberen zwei Zeilen des Zeichensatz-Zeichens werden unter die sechs übrigen Zeilen des Zeichensatz-Zeichens angehängt, die wiederum an die zwei oben angefügten Bildschimzeichen angehängt werden. (!!) --- ANTIC 4 -------- GR.12 ----40--8--- Hier stehen für jedes Zeichen 2 Pixel zur Verfügung. Damit kann das Zeichen zwar nur 4 Pixel breit sein, dafür aber in 4 Farben! Ist solch ein Zeichen invertiert (also Bit 7=1), wird bei einem für Farbe 2 deklariertem Pixel (%11) die Farbe aus COLOR3($2C7) genommen. Da damit ohne DLI 5 Farben dargestellt werden können, eignet dieser Modus sich hervorragend zur Darstellung von Karten, Landschaften, etc. --- ANTIC 5 -------- GR.13 ----40-16--- Wie ANTIC-Modus 4, nur daß die Zeichen doppelt so hoch sind. --- ANTIC 6 -------- GR.1 -----20--8--- Jedes Zeichen ist hier doppelt so breit wie in Gr.0, läßt sich aber in 4 Farben darstellen, da die ersten 6 Bits das Zeichen anwählen, die letzten 2 Bits die Farbe. Deshalb lassen sich auch nur 64 verschiedene Zeichen darstellen.... --- ANTIC 7 -------- GR.2 -----20-16--- Wie ANTIC-Modus 6, nur daß die Zeichen doppelt so hoch sind. --------------------------------------- Grafik-Modi: Die letzten drei Zahlen bedeuten: Pixel pro Zeile Bytes pro Zeile Scanlines pro Zeile Zahl der Farben --------------------------------------- --- ANTIC 8 ---- GR.3 ----40--10--8--4- Klötzchen von der Größe eines Gr.0- Cursors in 4 Farben. --- ANTIC 9 ---- GR.4 ----80--10--4--2- Halb so breit und halb so hoch wie bei ANTIC Modus 8 ist ein Pixel. --- ANTIC $A --- GR.5 ----80--20--4--4- Wie Antic-Mode 9, nur doppelt soviele Farben. --- ANTIC $B --- GR.6 ---160--20--2--2- Ein Pixel ist halb so hoch und halb so breit wie in Antic Mode $A, dafür aber auch nur in 2 Farben. --- ANTIC $C --- GR.14 --160--20--1--2- Wie Graphics 8, nur daß die Punkte doppelt so breit sind, dafür aber eine von zwei Farben annehmen können. --- ANTIC $D --- GR.7 ---160--40--2--4- Wie Antic-Modus $C, nur daß vier Farben zur Auswahl stehen und die Pixel zwei Scanlines hoch sind. --- ANTIC $E --- GR.15 --160--40--1--4- Wie Gr.8, nur daß die Punkte doppelt so breit sind, dafür aber eine von vier Farben annehmen können. --- ANTIC $F --- GR.8 ---320--40--1--1- Die bekannte HiRes- Grafikstufe. (von GPRIOR Bits 6+7 gelöscht!) --- ANTIC $F --- GR.9 ---192--40--1-16- Dafür muß von GPRIOR $26F (PRIOR $D01B) Bit 6 gesetzt und Bit 7 gelöscht sein. --- ANTIC $F --- GR.10 --192--40--1--9- Von GPRIOR muß Bit 7 gesetzt, Bit 6 gelöscht sein. --- ANTIC $F --- GR.11 --192--40--1-16- Von GPRIOR müssen Bit 6+7 gesetzt sein. So, ich hoffe, das war klar genug. Zum Thema Feinscrolling schreibe ich noch einen ausführlichen(!) Extra-Artikel. Den DLI hatten wir ja u.a. bereits im letzten Kurs behandelt. Nun noch ein paar Worte zum s.g. 'Memory-Scan-Counter' (MSC): Er enthält die Adresse, an dem der Bildschirmspeicher beginnt, in dem angegeben wird, welches Zeichen oder Pixel gesetzt werden soll. Also muß in jeder DL der MSC mindestens einmal gesetzt werden. Der MSC hat aber noch eine weitere (schlechte) Eigenschaft: Er ist nämlich nur 12 Bits breit. Die oberen 4 Bits werden nur durch den entsprechenden Befehl geändert, nicht aber beim Weiterzählen. Deshalb kann der Screenspeicher auch ohne den LMS (Load Memory Scan)-Befehl keine 4kB-Grenze überschreiten. Wenn doch, müssen eben zwei LMS verwendet werden. Ein gutes Beispiel dazu gibt z.B. eine Gr.15-DL, die man sich vom BASIC aus mal ansehen sollte. Ebenso wie mit dem MSC verhält es sich auch mit dem Display-List Counter. Der ist nämlich auch nur 12 Bytes breit. Es ist also 'ziemlich ungünstig', eine DL bei z.B. $4FFF anfangen zu lassen. (Da wäre dann nur Schrott auf dem Screen.) Zur Verdeutlichung die Analysis einer Graphics-0 DL (ohne BASIC bei $BC20): $70,$70,$70 3*8=24 Leerzeilen (Rand) $42,$40,$BC 1 Graphics-0 Zeile und den Memory Scan Counter auf $BC40 setzen. 2,2,2,2,2,2 2,2,2,2,2,2 23 Graphics-0 Zeilen 2,2,2,2,2,2 2,2,2,2,2 $41,$20,$BC Ende. Und von vorn.... (weiter bei $BC20) Da gäbe es noch ein Problemchen: Der ANTIC verlangt im Bildspeicher keine ATASCII- Zeichen, sondern so genannten Internen Code. Zwei Umrechnungsroutinen lagen dem ersten Kurs bei. Rechnung: Atascii -> Intern: 0- 31 Atascii+64 32- 95 Atascii-32 96-127 identisch 128-159 Atascii+64 160-223 Atascii-32 224-255 identisch Intern -> Atascii: 0- 63 Intern+32 64- 9 Intern-64 96-127 identisch 128-191 Intern+32 192-223 Intern-64 224-255 identisch Damit ist also die Darstellung der Buchstaben geklärt (hoffe ich). Bleiben nur noch die Pixel. Nehmen wir an, wir haben einen Grafik- Modus mit 4 Farben und 160 Pixel pro Zeile. Mit 2 Bits lassen sich 4 verschiedene Zustände (hier: Farben) schalten. Also benötigt jeder Pixel 2 Bits. Das 160mal ergibt 320 Bits. In jedes Byte passen acht Bits, also braucht die Grafikstufe pro Zeile 40 (320/8) Bytes. Das erste Byte lautet z.B. wie folgt: Bit 76543210 %01001010 Auf dem Bildschirm kommt also erst ein Pixel in Farbe eins (%01), dann in Farbe null (%00). Nun noch zwei Pixel in Farbe zwei (%10). Und so geht's weiter.... In Graphics 8 gibt dann jedes gesetzte Bit einen Punkt auf dem Bildschirm an, jedes gelöschte das Gegenteil. Zum Schluß noch ein Hinweis: Die beiden Assembler bieten die geniale Möglichkeit, ATASCII-Strings schon beim Assemblieren in den Internen Code umzurechnen: Graphics-0 mit Titelzeile: 00010 .LI OFF 00020 00030 DL .HX 7042 00040 .DA TITELZ 00050 .HX 7042 00070 DLSC .DA $FFFF 00080 .BL 23,$2 00090 .HX $41 00100 .DA DL 00110 00120 INIT LDA #DL 00130 STA 560 00140 LDA /DL 00150 STA 561 00160 LDA $58 00170 STA DLSC 00180 LDA $59 00190 STA DLSC+1 00200 RTS 00210 00220 TITELZ .AT " TITEL (C) 1002 vor " 00230 .AT " Christus by FROGGY " 00240 So, probieren Sie das Ganze doch einmal mit zwei Graphics-1 Zeilen statt einer langen Grapgics-0 Zeile....... Ansonsten wieder viel Freude mit meinen Beispielen (angucken kostet nichts!). Good Byte