Grafikkurs: "Picasso und all die an- dern..." (Teil 3)
Willkommen zum dritten Teil des Grafikkurses. Nachdem wir ja nun die Sprites
abgehandelt hätten, können wir uns diesen Monat nun endlich an die oft begehrte Programmierung der HIRES-Grafik machen. Auch dies ist ein relativ komplexes Thema, obwohl wir diesmal nicht allzu vielen in Registern " herumpoken" müssen, als bei den Sprites. Das komplizierte hierbei ist mal wieder der Aufbau
einer HIRES-Grafik, doch das sollte nun
auch kein Problem mehr für Sie sein.
Außerdem werden Sie auch noch ein
anständiges Stück vom Binärsystem benötigen, beziehungsweise Sie sollten mittlerweile vielleicht etwas geübter in der
Benutzung der logischen Operatoren von
BASIC sein, das hatten wir ja aber auch
schon, und somit kann ja nichts mehr
schief gehen. . .
Klären wir doch zunächst einmal, was
" HIRES" überhaupt bedeutet. HIRES ist
schlichtweg die Abkürzung für " HIgh RE-Solution" und das heißt nichts anderes
als " hohe Auflösung" . Sie haben also bei
einer HIRES-Grafik eine hohe Auflösung
zur Verfügung - genauer gesagt erstreckt
sich diese auf eine Ausdehnung von
320 x200 Punkten, oder Pixels, wie man
sie auch oft nennt. Dieses Feld von
Punkten wird vom Bildschirmrand eingerahmt. Das heißt also, daß wir mit Hilfe
des HIRES-Modus des C64 jeden einzelnen
Punkt auf dem Bildschirm seperat ansteuern können.
Doch wie geht das nun vor sich? Zunächst
einmal sollte ich vielleicht erwähnen, daß eine solche Grafik, wie die Sprites
auch, natürlich Speicherplatz benötigt.
Und das in verhältnismäßig gewaltigem
Maße! Wie Sie sich bestimmt denken
repräsentiert ein Grafikpunkt hier
natürlich auch ein Bit im Speicher des
64 ers, das hatten wir ja bei den Sprites ja auch scon, nun können Sie sich das ja
mal ausrechnen. Wir haben da
320*200=64000 Pixel, das ganze dividieren wir durch 8, weil ja ein Byte 8 Bit
hat, und so kommen wir auf 8000 Bytes
pro Grafik! Das macht schon ein Achtel
des Gesamtspeichers des 64 ers aus - Sie
sehen, die hohe Auflösung hat ihren
Preis.
Doch da gibt es noch ein riesengroßes
Problem für uns. Für die paar kleinen
Sprites aus den letzten beiden Kursteilen haben wir ja noch Speicherplatz gefunden, aber 8000 Bytes sind nicht mehr
so einfach dazischenzumogeln. Der ganze
Speicher des 64 ers ist ja schon komplett
für andere spezifische Aufgaben reserviert. Woher also nehmen, wenn nicht
stehlen? Genau das werden wir jetzt aber
tun müssen! Wir werden uns etwas Speicher von unserem 64 er " klauen" müssen, sonst is nix drin mit HIRES. Und das
geht folgendermaßen:
Das Betriebssystem hat ganz am Anfang des Speichers eine ganze Menge Speicherstellen für sich reserviert, in dem es
sich einige Zwischenergebnisse und Hintergrundinformationen " merkt" . Dort befinden sich auch zwei kleine Speicherzellen, die ihm die Startadresse des
Basicspeichers angeben. In der Fachsprache nennt man so etwas " Pointer", oder
auch " Zeiger"( ähnlich wie die Spritezeiger bei Sprites) . Nomalerweise liegtder Basicspeicher, wie ich auch schon im
fünften Teil des Basickurses erwähnte, ab Adresse 2048 . Der Trick, den wir nun
anwenden werden, ist schlichtweg der, daß wir dem Betriebssystem vorgaukeln, der Basicspeicher beginne weiter hinten, und schon können wir uns einen passenden
Speicherbereich für unsere Grafik reservieren. Aber Vorsicht! Wie bei den Sprites auch können wir uns da nicht jeden
Xbeliebigen Speicherberech rausgreifen.
Hiresgrafiken dürfen nämlich grundsätzlich nur bei Speicherstellen beginnen, die durch 8192 teilbar sind ( bei Sprites war der Teiler ja 64 . . .) . Demnach gibt
es also insgesamt 8 Bereiche, die in
Frage kämen, nämlich:
Nr. Von Bis
0 0 7999 1 8192 16191 2 16192 24191 3 24192 32191 4 32192 40191 5 40192 48191 6 48192 56191 7 56192 64191
Wir werden uns Bereich 1 wählen, aus 2 ganz bestimmten Gründen, die ich Ihnen
jetzt noch näher erklären möchte. Bereich 0 können wir ja vergessen, hier
sind ja wieder vorreserviete Funktionen
angelegt, die man tunlichst in Ruhe lassen sollte. Soviel hierzu. Jetzt zu den
Bereichen 2 bis 7 . Diese sind ja eigentlich auch alle in reservierten Berei- chen, aber es wäre auch hier denkbar
( über viele Tricks) sie " bebaubar" zu
machen. Das ist sogar sehr gut möglich
und wird auch von sehr vielen Programmen
eifrig praktiziert. Doch damit das einfacher geht, ist es meist sinnvoller das
Ganze in Assembler zu versuchen ( zu diesem Zweck können Sie ja einmal in den
Assemblerkurs reinschauen, der seit Januar parallel zu meinem hier läuft - eine echte Gelegenheit für Basicprofis
noch tiefer in die Materie einzusteigen), und dann gibt es da auch noch ein
internes Problem, das mit dem VIC zu tun
hat, was jedoch zuviel wäre jetzt hier
erwähnt zu werden.
Bereich 1 ist einfach am Besten, da
pflegeleicht und für uns leicht erreichbar.
Also dann wollen wir einmal den Basicspeicheranfang etwas höher setzen. Die
beiden Speicherstellen die ich eben
erwähnte belegen die Adressen 43 und 44 .
Der 64 er hat ja insgesamt 65535 Speicherstellen, was der 16- Bit-Zahl
"1111111111111111"(16 mal " Bit gesetzt") entspricht. Um eine Adresse innerhalb des Speichers für den Computer
darstellen zu können, brauchen wir also
immer 16 Bit, gleich 2 Byte. So auch bei
der Adresse des Basicanfangs ( daher auch
2 Speicherstellen!) . Die beiden Bytes, die wir benötigen, teilen sich auf in
ein sogenanntes " niederwertiges-" oder
" LOW-Byte" und in ein " höherwertiges" oder auch " HIGH-Byte" . In Adresse 43 ist
nun das LOWund in Adresse 44 das
HIGH-Byte des Basicanfangs gespeichert.
Lesen wir doch einfach einmal diese beiden Bytes aus, also:
PRINT PEEK(43),PEEK(44)
Auf dem Bildschirm sollten jetzt die
beiden Zahlen:
18
stehen.1 wäre also dann der Wert des
LOW-Bytes und 8 der des HIGH-Bytes. Setzen wir uns also unsere 16- Bit-Zahl aus
diesen beiden Bytes zusammen. Das höherwertige Byte kommt beim Schreiben der
Binärzahl nach " oben" also nach links, das niederwertige nach " untern" beziehungsweise nach rechts:
--> 00001000 00000001 =8(HIGH) =1(LOW) --> in dezimaler Schreibweise: 2↑11+2↑1=2049
Huch, das ist ja 2049 und nicht 2048, wo
ja eigentlich der Basicspeicher normalerweise beginnen sollte! Doch keine
Angst, es stimmt schon so, denn das Betriebssystem möchte mämlich hier die
" wahre" Anfangsadresse des Basicspeichers plus 1 stehen haben. Das 0 . Byte
dieses Bereichs wird noch zu einem anderen Zweck benutzt, wie wir gleich noch sehen werden. Möchten wir also beispielsweise den Anfang des Basicspeichers nach Adresse 20000 verschieben, so
müßten wir hier die Adresse 20001 angeben! Ok?
Zugegeben, das Prozedere, eine Adresse
zuerst einmal als Binärzahl zu schreiben, um sie dann in zwei Bytewerte umzurechnen ist relativ umständlich, deshalb
möchte ich Ihnen hier noch einen einfacherern Weg zeigen, wie ein solcher 2- Byte-Wert umgerechnet werden kann:
Das erste Bit des höherwertigen Bytes
hat ja in der 16- Bit-Schreibweise den
Dezimalwert 2↑8=256, da es ja das 8 . Bit
der 16- Bit-Zahl ist ( das Zweite 2↑9=512 etc.) . Demnach wäre also die niedrigste
Zahl, die ( ausschließlich) mit dem
HIGH-Byte dargestellt werden kann ( das
LOW-Byte hat also den Wert 0) die Zahl
256 . Demnach genügt es schlichtweg, die
absolute 8- Bit-Zahl des HIGH-Bytes mit
dem Wert 256 zu multiplizieren. Der Wert des LOW-Bytes bleibt erhalten und wird
einfach zu dem 256 fachen Wert des HIGH-Bytes hinzuaddiert, also:
--> HI*256+ LO= absolute Adresse --> Oder in unserem Beispiel:
8*256+1=2048+1=2049
Genauso geht es auch umgekehrt. Um das
HIGH-Byte eines absoluten Wertes zu ermitteln dividieren wir diesen durch 256 und nehmen den ganzzahligen Anteil des
Ergebnisses als HIGH-Byte ( also OHNE
Nachkommastellen, falls die Division
nicht aufgehen sollte) . Das LOW-Byte
wird nun ermittelt, indem wir das HIGH-Byte mit 256 multiplizieren und das Ergebnis von dem absoluten ( Anfangs-) Wert
subtrahieren. Das hört sich vielleicht
komplizierter an als es ist, der Einfachheit halber hier die Umrechnung als
kleines BASIC-Programm:
10 INPUT"Absoluter Wert (max. 65535)";WE 20 HI=INT(WE/256) 30 LO=WE-256*HI 40 PRINT "LOW-Byte : "LO 50 PRINT "HIGH-Byte: "HI
Starten Sie doch einmal dieses Programm
( auf der Vorderseite der MD unter dem
Namen " LO-HI- UMRECHNUNG") und geben Sie
einmal den Wert 2049 ein. Das Ergebnis
ist, wie erwartet, eine 1 für das LOWund eine 8 für das HIGH-Byte.
Doch nun wollen wir endlich einmal den
Speicher für unsere Grafik verschieben.
Wir hatten uns ja darauf geeinigt, daß
wir Bereich 1 hierfür beanspruchen wollen, der sich ja von 8192 bis 16191 erstreckt. Lassen wir also den neuen Basicspeicher bei Adresse 16192 beginnen.
Sie sollten übrigens bedenken, daß bei
einer Verschiebung der Anfangsadresse
des Basicspeichers nach hinten, dieser
natürlich an Länge verliert! Vorher erstreckte er sich ja von 2048 bis 40959,
und wir hatten somit 38911" BASIC BYTES
FREE"(=40959-2048) . Bei 16192 sind das
jetzt nur noch 24767 Bytes (=40959-16192) ! Deshalb sollten wir auch kein
Byte zuviel wegnehmen, wenn dies nicht
unbedingt erforderlich ist!
Bei 16192 soll nun also die neue Startadresse liegen. Zuerst müssen noch eine 1 hinzuaddieren, bevor wir die Zahl in
HIGHund LOW umrechnen können ( Sie
erinnern sich - in 43/44 muß die gewollte Adresse plus 1 stehen) . Also:
16192+1=16193 HIGH=INT(16193/256)=63 LOW=16193-63*256=16193-16128=65
Das LOW-Byte hat also den Wert 65, das
HIGH-Byte den Wert 63 . Nun noch schnell
etwas über das 0 . Byte des Basicspeichers ( bei uns das Byte mit der Adresse
16192) . Dieses dient quasi als " Kennmarke" für unseren 64 er, daß hier der Basicspeicher beginnt und muß deshalb IM- MER den Wert 0 enthalten, andernfalls
erkennt BASIC nicht mehr die Befehle
NEW, CLR und RUN als Basicbefehle an und
bricht mit einem " SYNTAX ERROR" ab! Deshalb also immer auch eine 0 in das nullte Byte des neuen Basicanfangs schreiben, also:
POKE 16192,0 :REM 0.Byte POKE 43,65 :REM LOW-Byte POKE 44,63 :REM HIGH-Byte
Das wars. Der Basicanfang ist nun verschoben, und der Bereich von 2048 bis
16191 geschützt, er kann von nun an also
nicht mehr von BASIC-Programmen überschrieben werden. Öbrigens kann es sein, daß da hinten im Speicher noch irgenwo
Datenmüll rumsteht, der ja eigentlich
kein richtiges BASIC-Programm mehr
repräsentiert. Gibt man LIST ein, so
versucht der 64 er doch noch was daraus
zu machen, was natürlich in einem riesigen Chaos endet, deshalb sollten Sie auf alle Fälle den Basicspeicher noch
zusätzlich initialisiern, indem Sie Ihn
mit NEW löschen, also:
NEW
Jetzt können Sie Ihr HIRES-Basic- Programm schreiben. Achten Sie allerdings bitte darauf, daß Sie dieses unbedingt mit einem ",8" abspeichern und vor
allem laden und nicht etwa mit ",8,1", denn dann wird das Programm nämlich absolut geladen. Wenn Sie es also abgespeichert haben, als der Basicanfang
noch bei 2048 lag, dann wird es auch
dort hingeladen. Bei einem ",8" lädt der
C64 es jedoch an den aktuellen Basicspeicheranfang, in unserem Fall also
16192 !
Im Öbrigen können Sie sich möglicherweise noch erinnern, daß ich bei den Sprites erwähnte, daß es da auch noch andere
Möglichkeiten gibt, Speicherplatz für Sprites zu schaffen. Genau das was wir
eben praktizierten meinte ich damit.
Verschieben Sie sich einfach den Basicspeicher etwas nach vorne, um noch Platz
für Sprites zu bekommen. Wenn Sie auch
noch gleichzeitig eine Grafik benutzen, dann haben Sie sowieso den Speicher von
2048 bis 8192 frei, genügend also, für
eine ganze Menge Sprites. . .
Welche Register des VIC Sie jetzt ansprechen müssen, um endlich mit dem Grafikbildschirm arbeiten zu können, werde
ich Ihnen dann nächsten Monat erklären.
Bis dahin " Gut Hack" und Servus.
(ub)