CODINGLISTINGS ★ Kleiner Punkt, großer Aufwand|CPC Amstrad International) ★

Fast-Plot (CPC Amstrad International)Coding Listings
★ Ce texte vous est présenté dans sa version originale ★ 
 ★ This text is presented to you in its original version ★ 
 ★ Este texto se presenta en su versión original ★ 
 ★ Dieser Text wird in seiner Originalfassung präsentiert ★ 

Wissen Sie, was ein Pixel ist? Na klar - ein Pünktchen auf dem Bildschirm. Wissen Sie aber auch, woher dieser Begriff stammt? Es handelt sich um eine Verunkürzung von 'Picture ElementProfis sprechen sogar mitunter nur noch von einem Pel, um keine wertvollen Mikrosekunden mit der Aussprache von 'ix ' zu vergeuden. Und noch eine dumme Frage: Wie erzeugt man ein Pel auf dem CPC-Monitor? Ganz einfach, mit einem PLOT-Befehl... und wenn das CPC-Betriebssystem sprechen könnte, würde es jetzt energisch Protest einlegen: Von wegen einfach!

Bereits in den letzten Folgen der As-semblerecke haben wir uns im Bildschirmspeicher herumgetrieben, dabei jedoch nur mit kompletten Bytes jongliert. Will man in Maschinensprache gezielt Punkte ansprechen, so müssen diese innerhalb eines Bytes lokalisiert werden, was neue Komplikationen mit sich bringt. Um der Sache näher zu kommen, schaut man sich am besten an, wie es das Betriebssystem macht. Damit Sie sich jedoch nicht mit ROM-Listings plagen müssen, finden Sie in dieser Folge ein Programm, das die Vorgehens weise in reinem Basic nachvollzieht.

Die Zeilen 10 bis 90 dienen nur Testzwecken: Hier können Sie zwei Grafikkoordinaten x,y eingeben, um an der entsprechenden Stelle einen Punkt zu erzeugen. Ernst wird es in der Subroutine PLOT, die ab Zeile 130 zunächst die Legalität Ihrer Eingaben prüft. Koordinaten außerhalb des Bildschirms könnten sonst Punkte an irgendeiner Undefinierten Position erscheinen lassen.

Physikalische Koordinaten und was davon zu halten ist

Ab Zeile 170 erfolgt die Umrechnung in physikalische Koordinaten, und dazu ist erst einmal eine Erklärung fällig: Die Grafikkoordinaten des CPC reichen vertikal von 0 bis 399 und horizontal von 0 bis 639, was jcdoch nicht dem tatsächlichen Auflösungsvermögen entspricht. In Y-Richtung lassen sich nur 200 Punkte darstellen; in X-Richtung sind es 640 (MODE 2), 320 (MODE 1) oder gar nur 160 (MODE 0). Was auf den ersten Blick wie Lug und Betrug aussieht, ist jedoch eine Wohltat für den Basic-Programmierer: Unabhängig vom MODE erzeugen gleiche Zahlenwerte geometrisch gesehen die gleichen Ergebnisse. Weiterhin sind die X-und Y-Skalierungen so aufeinander abgestimmt, daß ein mathematisch exakter Kreis wirklich als Kreis auf dem Bildschirm erscheint und nicht als Ellipse.

Natürlich muß sich das Betriebssystem an der physikalischen Realität orientieren und die Anwenderkoordinaten so umrechnen, daß sie der tatsächlichen Pixelanzahl entsprechen. Der Y-Wert wird deshalb durch 2 geteilt und der X-Wert in MODE 1 und MODE 0 durch 2 bzw. 4. Da es keine halben Pixel gibt, benutzt das Basic-Programm die Ganzzahl-Division ohne Rest (umgekehrter Schrägstrich). Der MODE wird einer Speicherstelle entnommen, die für den CPC 464 und CPC 664/6128 verschieden ist — hier bitte aufpassen!

Für weitere Berechnungen wird in Zeile 240 die Anzahl der Pixel innerhalb eines Bildschirm-Bytes bestimmt, die je nach MODE verschieden ist. Die MODE-spezifischen Bitmasken helfen bei der Lokalisierung eines Punktes innerhalb eines Bytes — dazu gleich mehr. Das Statement y = 199-y in Zeile 290 stellt die Y-Achse quasi auf den Kopf und verlegt den Punkt 0,0 in die linke obere Ecke. Das ist eine weitere Anpassung an die physikalische Realität: In einem mathematischen Koordinatensystem wachsen die Y-Werte von unten nach oben; die Bildschirmadressen nehmen jedoch in umgekehrter Richtung zu!

Adreßberechnungen

Die Umrechnung der X/Y-Koordina-ten in eine Bildschirmadresse erfolgt in Zeile 300. Das Adressenlabyrinth des Video-RAMs wurde bereits in Heft 3/89 ausführlich besprochen. Hier soll nur das Wichtigste in Kürze wiederholt werden: Wenn nach dem letzten MODE-Befehl oder Reset kein Hardware-Scrolling (Rollen des gesamten Bildschirms) stattgefunden hat, liegt die linke obere Bildschirmecke an der Adresse &C000. Wandert man von dort aus jeweils eine Textzeile (8 Pixelreihen) nach unten, so erhöht sich die Adresse immer um 80. Innerhalb einer Textzeile bewirkt der Sprung zur

nächsten Pixelreihe jedoch eine Erhöhung um 2048 (Hex &800).

Mit diesen Erkenntnissen läßt sich die in Zeile 300 benutzte Formel aufschlüsseln:

adr+&C000+(y \8)*80 ergibt die-Startadresse (links,oben) der Textzeile, in der sich der Punkt befindet. Die Ganzzahldivision ohne Rest rechnet hier die Y-Grafikkoordinate in die Textzeilen-Nummer um. adr=adr+(y MOD 8)*2048 rechnet die Adresse innerhalb der Textzeile mit Hilfe des Divisionsrestes nach unten weiter, um zu der korrekten Pixelreihe zu gelangen.

adr=adr + (x ^ pb) rechnet schließlich die Adresse nach rechts bis zum richtigen Byte weiter, indem die X-Koordinate addiert wird. Natürlich muß sie vorher durch die Pixel pro Byte dividiert werden, da jedes Byte gleich mehrere Punkte enthält!

Und damit befinden wir uns jetzt nahe genug an der Hardware, um uns wieder mit den Eigenarten des CPC-Video-chips herumärgern zu dürfen. Innerhalb eines Bytes sind bestimmte 'signifikante' Bits für unseren Punkt zuständig — aber welche? Wie Tabelle 1 zeigt, ist das in MODE 2 noch sehr einfach: Jedes Bit entspricht genau einem Bildpunkt. Steht das Bit auf 1, so wird der Punkt mit PEN 1 dargestellt, ansonsten mit PEN 0. Dabei muß man nur im Auge behalten, daß das höchstwertige Bit (Bit 7) für die Punktposition ganz links zuständig ist, Bit 6 für den nächsten Punkt usw.

In MODE 1 werden 2 Bits pro Punkt benötigt, um die vier Farben von PEN 0 bis PEN 3 unterscheiden zu können. Wer jetzt allerdings glaubt, daß die beiden Bits ordentlich sortiert nebeneinander liegen, kennt unseren Videochip noch nicht! Die Organisation des Bildschirmspeichers ist nämlich total auf seine Hardware-Logik zugeschnitten; der Programmierer muß sich gefälligst damit abfinden, daß die Bits für einen Pixel fein säuberlich im Byte verteilt liegen. Der Tabelle können Sie entnehmen, welche Bits für welche Punktposition zuständig sind, und sich gleichzeitig davon überzeugen, daß das Chaos in MODE 0 noch größer wird (4 Bit pro Punkt für 16 Farben).

Um die Bits gezielt anzusprechen, wurden bereits in den Basiczeilen 260-280 Bitmasken vorbereitet, die an den signifikanten Stellen eine 1 enthalten. In der vorliegenden Form gelten sie aller-
dings nur für die Punktposition 0 ganz links im Byte. Für die anderen Positionen müssen die Einsen noch etwas nach rechts geschoben werden; die X-Koor-dinate bestimmt, wie weit. Mit der Ganzzahl-Division x\pb hatten wir die Adresse des Bytes in horizontaler Richtung lokalisiert; der Rest (x MOD pb) gibt uns an, um wie viele Positionen die Bitmaske verschoben werden muß. Da uns in Basic keine Schiebeoperationen zur Verfügung stehen, benutzt die Schleife in den Zeilen 310..330 eine wiederholte Division durch 2, die bei Binärzahlen den gleichen Zweck erfüllt. (Siehe PC International 12/88, S. 42.)

Bits bekennen Farbe

Wenn man die Bitmaske per OR-Ver-knüpfung in das Bildschirmbyte hineinmurkst, erhält man allerdings immer nur einen Punkt in der höchstmöglichen Farbnummer (z.B. PEN 3 in MODE 1). Was uns noch fehlt, ist die Codierung der Farben in den signifikanten Bits. Hierbei hilft wieder die Tabelle 1, in der die Bitnummern gleich in einer passenden Reihenfolge stehen. Dazu ein Beispiel: In MODE 0 soll ein Byte mit PEN 12 eingefärbt werden. Da die Zahl 12 im Binärsystem durch I 100 dargestellt wird, müssen die Bits für die beiden Punktpositionen auf folgende Weise gesetzt werden: Bit 1 = 1, Bit 5 = 1, Bit 3 = 0, Bit 7=0, Bit 0 = 1, Bit 4 = 1, Bit 2 = 0, Bit 6=0

Bringt man die Bits in die richtige Reihenfolge, so erhält man den Wert &X00110011. Solch ein Bitmuster, das für alle Punktpositionen in einem Byte die Farbe angibt, nennt man 'Farbmas-ke'. Überzeugen Sie sich selbst: Schal-
ten Sie MODE 0 ein, und schreiben Sie den Wert mit POKE &C000 in den Bildschirmspeicher!

Punktposition
v. links nach
rechts
Signifikante Bits für
MODE 2MODE 1MODE 0
073 71 5 3 7
162 60 4 2 6
251 5
340 4
43
52
61
70
Tabelle 1: Signifikante Bits für die Punktpositionen in einem Bildschirm-Byte

Nach einer Farbwahl mit PEN, PAPER usw. legt das Betriebssystem die dazugehörigen Farbmasken in bestimmten Speicherstellen ab (siehe Tabelle 2), damit sie für nachfolgende Bildschirmausgaben sofort zur Verfügung stehen. Normalerweise enthalten diese Masken für alle Punktpositionen die gleiche Farbe... es sei denn, ein hinterlistiger Mensch verbiegt hier ein paar Bits! Lassen Sie das folgende Kabinettstück auf Ihrem Rechner laufen:

10 'Farbmaskendemo
20 MODE 1
30 INK 0,0: INK 1,6: INK 2,11: INK 3,21
40 POKE &B338,83: ' &B6A3 für 664/6128
50 F0R x=0 T0 640 STEP 10
60 MOVE 320,0:DRAW x,399:NEXT

Hübsch, nicht wahr? Nach dieser kleinen Erholungspause sind Sie sicherlich in der Lage, den Endspurt zu bewältigen. Um noch einmal zusammenzufassen: Wir haben die Adresse des Screen-bytes, eine Bitmaske für die Punktposition und wissen auch, wo wir eine Farbmaske herbekommen. Jetzt müssen nur noch bestimmte Bits im Screen-byte durch neue Bits aus der Farbmaske ersetzt werden, und das geht so (siehe Zeile 390):

serbyte AND NOT bitniask löscht die signifikanten Bits im Screenbyte,

colmask AND bitmask isoliert die Farbbits für die Punktposition,

... und die OR-Verknüpfung setzt sie in das Screenbyte ein. Das Ergebnis kommt zurück in den Bildschirmspeicher — fertig! Detaillierte Erläuterungen zu den logischen Verknüpfungen finden Sie übrigens in PC International 11/88, S. 20.

CPC 464664/6128
PEN Grafik
PAPER Grafik
&B338
&B339
&B6A3
&B6A4
PEN Text
PAPER Text
&B28F
&B290
&B72F
&B730
aktueller MODE&B1C8&B7C3
Tabelle 2: Speicherstellen für Farbmusken und den aktuellen MODE

FASTPLOT. ASM:
Ganz schön schnell...

Es ist in der Tat erstaunlich kompliziert, einen einzigen Punkt zu erzeugen, wenn man auf den PLOT-Befehl und die Mithilfe des Betriebssystems verzichtet. Wer jedoch superschnelle Grafik in Maschinensprache programmieren will, kommt um dieses Grundlagenwissen nicht herum. Als Beispiel möchte ich Ihnen die FASTPLOT-Routine aus dem Fraktal-Generator vorstellen, die dazu beiträgt, die anspruchsvolle 3D-Grafik in akzeptabler Rechenzeit zu erzeugen. Hier wurde nach Kräften optimiert, was leider nicht der Übersichtlichkeit zugute kommt.

Sie können die Routine als 'Black Box' in eigenen Programmen einsetzen; wer jedoch herausfinden möchte, wie und warum sie funktioniert, wird sich eventuell die Zähne daran ausbeißen, obwohl im Prinzip das Gleiche wie im Basic-Listing ab Zeile 300 passiert.

Hier noch ein kleiner Tip: Die Basic-zeile 390 läßt sich nach den Gesetzen der Logik in das Äquivalent scrbyte = ((colmask XOR scrbyte) AND bit-mask) XOR scrbyte umformen, was sich in Assembler mit weniger Befehlen erledigen läßt — siehe Zeile 470 bis 500.

Immerhin ist die FASTPLOT-Routine sechsmal so schnell wie die Betriebssystem-Routine GRA PLOT, da sie sich auf MODE 1 beschränkt, keine Abfrage auf legale Werte enthält und gleich mit physikalischen Koordinaten angesteuert wird. Falls Sie es genau wissen wollen: FASTPLOT schafft 10500 Pixel pro Sekunde!

Matthias Uphoff/cd , CPCAI

★ PUBLISHER: CPC Amstrad International
★ YEAR: 1989
★ CONFIG: 64K + AMSDOS
★ LANGUAGE:
★ LICENCE: LISTING
★ AUTHOR: Matthias Uphoff

★ AMSTRAD CPC ★ DOWNLOAD ★

Type-in/Listings:
  » Fast-Plot    (CPC  Amstrad  International)    GERMANDATE: 2020-06-23
DL: 3 fois
TYPE: ZIP
SIZE: 5Ko
NOTE: 40 Cyls
.HFE: NON

  » Fast-Plot    (CPC  Amstrad  International)    LISTING    GERMANDATE: 2020-06-23
DL: 3 fois
TYPE: text
SIZE: 2Ko

Je participe au site:
» Newfile(s) upload/Envoye de fichier(s)
★ AMSTRAD CPC ★ A voir aussi sur CPCrulez , les sujets suivants pourront vous intéresser...

Lien(s):
» Coding Src's » Graphic - Message Scroller (The Amstrad User)
» Coding Src's » Freeze
» Coding Src's » Relocating Z80 Code (The Amstrad User)
» Coding Src's » Curseur Clignotant
» Coding Src's » Netzgrafik (CPC Amstrad International)
» Coding Src's » Dump anything off the screen (Computing With the Amstrad)

CPCrulez[Content Management System] v8.7-desktop/cache
Page créée en 808 millisecondes et consultée 40 fois

L'Amstrad CPC est une machine 8 bits à base d'un Z80 à 4MHz. Le premier de la gamme fut le CPC 464 en 1984, équipé d'un lecteur de cassettes intégré il se plaçait en concurrent  du Commodore C64 beaucoup plus compliqué à utiliser et plus cher. Ce fut un réel succès et sorti cette même années le CPC 664 équipé d'un lecteur de disquettes trois pouces intégré. Sa vie fut de courte durée puisqu'en 1985 il fut remplacé par le CPC 6128 qui était plus compact, plus soigné et surtout qui avait 128Ko de RAM au lieu de 64Ko.