Magic Disk 64

home to index to text: MD9002-KURSE-GRAFIKKURS:_PICASSO_UND_ALL_DIE_ANDERN..._TEIL_3.txt
  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)

Valid HTML 4.0 Transitional Valid CSS!