Grafikkurs : Teil 1 "Picasso und all die andern..." ---------------------------------------
Hallo Leute, hier bin ich wieder, diesen Monat jedoch mit einem NEUEN Kurs. Der Basickurs für Einsteiger ist jetzt abge- schlossen, nun geht es weiter mit einem Grafikkurs, der ebenfalls den Einstei- gern gewidmet sein soll. "Buuuh, Be- trug!" werden jetzt die Profis unter Ihnen jetzt schreien, "wir wollen end- lich mal was Richtiges !" - doch keine Panik. Dieser Kurs wird nur 3 Teile lang sein, und für danach halten wir dann einen Leckerbissen für Sie, den Profi bereit. Es geht anschließend nämlich ebenfalls mit Grafik weiter, doch dann wollen wir uns in die tiefen Abgründe der Raster-IRQ-Programmierung abseilen, die für manche von Ihnen bestimmt ein kleines Hindernis darstellen. Doch nun wollen wir erst einmal mit dem Einsteigerkurs loslegen, die Grafik kam in dem Basickurs ja entschieden zu kurz; was ich jetzt mit noch mehr Information über dieses Thema ausgleichen möchte. Wir werden uns in den nächsten Monaten um die wichtigsten Grafikarten des C64 kümmern, als da wären die Sprites, die HIRES- und MULTICOLOR-Grafiken und die Zeichensatzveränderung und -bedienung. In dieser Reihenfolge werden wir die einzelnen Themen dann auch abhandeln, und, wie Sie sich jetzt bestimmt denken können, werden in diesem ersten Teil gleich mit den Sprites beginnen. Zuerst jedoch eine kleine Einleitung in Sachen Grafik... Die komplette Bidschirmdarstellung, das heißt Zeichensätze, Grafik und Sprites, werden in unserem 64er von einem Grafik- chip verwaltet, der alle Informationen im Speicher des 64ers in ein Signal für einen Monitor umwandelt, damit wir die Bits und Bytes aus unserem Computer auch auf dem Bildschirm sehen können. Dieser Chip hat den Namen VIC, was für "Video Interface Controller" steht. Der VIC hat ebenso wie der Soundchip SID (den Sie ja noch aus dem sechsten Basickurs kennen sollten) ein paar Steuerregister im Ein-/Ausgabe-Bereich, den ich seiner- seits schon im fünften Basickurs erwähn- te. In jenem fünften Teil hatten wir ja auch gelernt, wie das Innere unseres 64ers aussieht, daß es dort Speicherbe- reiche gibt, die man mit sogenannten Speicheradressen anspricht, daß ein Byte aus acht Bit besteht, und wie man Binär- zahlen in Dezimalzahlen umrechnet. Alle diese Kenntnisse sind in der Grafik von großer Bedeutung, weshalb ich Ihnen emp- fehle, sollten Sie sich an die Gedan- kengänge von damals nicht mehr so ganz erinnern, sich doch noch einmal die Ma- gic Disk 64 Ausgabe 5/89 anzuschauen. Wie also schon gesagt, belegt der VIC einen Bereich von 46 Bytes im Ein- /Ausgabebereich unseres 64ers (von Adresse 53248 bis 57344). Der SID hatte seine erste Stelle, oder auch Basisa- dresse genannt, bei 54272. VICs Basisa- dresse liegt bei 53248, der ersten Spei- cherzelle des Ein-/Ausgabebereichs also. Diese Adresse wird nun also immer als relativer Bezug für die einzelnen Regi- ster herangezogen. Die Adresse 53248 ist also das Register mit der Nummer 0, 53249 (=53248+1) ist Register 1 des VICs und so fort... Die Register eines Chips in unserem 64er steuern also gewisse Funktionen des zu ihnen gehörendem Chips. Wie Sie ja wis- sen können Sie mit der Adresse 53280 die Hintergrundfarbe des Bildschirms verän- dern. Schreiben wir hier einen Wert hi- nein, so ändert sich die Farbe entspre- chend. Diese Adresse ist nun ebenfalls ein Register des VICs, da ja etwas, das mit der Bildschirmdarstellung zu tun hat, durch sie verändert wird. Demnach belegt diese Adresse ebenfalls ein Regi- ster im VIC, nämlich das Zweiunddreißig- ste. Ich gebe Ihnen am Besten einmal eine Übersicht über alle VIC-Register (Sie finden diese, etwas weniger kommen- tiert, übrigens auch im Anhang N Ihres Commodore-64 Benutzerhandbuchs) :
Adresse Register Funktion ----------------------------------------
53248 0 X-Position von Sprite 0 53249 1 Y-Position von Sprite 0 53250 2 X-Position von Sprite 1 53251 3 Y-Position von Sprite 1 53252 4 X-Position von Sprite 2 53253 5 Y-Position von Sprite 2 53254 6 X-Position von Sprite 3 53255 7 Y-Position von Sprite 3 53256 8 X-Position von Sprite 4 53257 9 Y-Position von Sprite 4 53258 10 X-Position von Sprite 5 53259 11 Y-Position von Sprite 5 53260 12 X-Position von Sprite 6 53261 13 Y-Position von Sprite 6 53262 14 X-Position von Sprite 7 53263 15 Y-Position von Sprite 7 53264 16 High-Bits Sprite-X-Pos. 53265 17 Steuerregister 1 53266 18 Rasterzeile für IRQ 53267 19 X-Anteil eines Strobes 53268 20 Y-Anteil eines Strobes 53269 21 Sprite ein-/ausschalten 53270 22 Steuerregister 2 53271 23 Spritevergrößerung in X-Richtung 53272 24 Basisadresse Video-RAM und Zeichensatz 53273 25 Interrupt-Request-Reg. 53274 26 Interrupt-Mask-Reg. 53275 27 Sprite im Vorder- oder Hintergrund 53276 28 Multicolorsprite-Reg. 53277 29 Spritevergrößerung in Y-Richtung 53278 30 Sprite-Sprite- Kollision 53279 31 Sprite-Hintergrund- Kollision 53280 32 Rahmenfarbe 53281 33 Hintergrundfarbe 0 53282 34 Hintergrundfarbe 1 53283 35 Hintergrundfarbe 2 53284 36 Hintergrundfarbe 3 53285 37 Multicolorfarbe 0 eines Sprites 53286 38 Multicolorfarbe 1 eines Sprites 53287 39 Farbe für Sprite 0 53288 40 Farbe für Sprite 1 53289 41 Farbe für Sprite 2 53290 42 Farbe für Sprite 3 53291 43 Farbe für Sprite 4 53292 44 Farbe für Sprite 5 53293 45 Farbe für Sprite 6 53294 46 Farbe für Sprite 7
Noch zwei kleine Bemerkungen zu der Ta- belle: ----------------------------------------
Die zwei Steuerregister (17 und 22) ha- ben mehrere Funktionen gleichzeitig, auf die wir später noch genauer eingehen werden. Mit den Registern 18,19,20,26 und 27 werden wir hier nichts zu tun haben. Sie haben etwas mit der Raster-Interrupt- Programmierung zu tun, die ja, wie oben schon erwähnt, in einem eigenen Kurs behandelt werden soll. Machen wir uns nun also an die Sprite- programmierung - wie Sie aus obiger Ta- belle ersehen können ein sehr komplexes Thema, da wir da eine Menge Register zur Beeinflussung von Sprites zur Verfügung haben. Zunächst einmal: Was ist ein Sprite? Nun, Sprites sind ganz einfach kleine Grafikobjekte, die man frei definieren kann und die, unabhängig von Grafiken oder Zeichen, über den ganzen Bildschirm verstreut sich befinden können. Ja es geht sogar so weit, daß man sie über selbigen ruckelfrei bewegen kann. Sie haben mit 100%-iger Sicherheit schon einmal Bekanntschaft mit einem Sprite gemacht, denn das kleine Raumschiff, daß sie bei Ihrem letzten Ballerspiel mit dem Joystick über den Bildschirm beweg- ten, oder das Männchen, mit dem sie die schöne Jungfrau neulich von dem bösen, bösen Gorilla gerettet hatten, waren nichts anderes als bewegte Sprites ! Der 64er stellt uns insegsamt 8 (Sprite 0-7) davon zur Verfügung, die wir unabhängig voneinander über den Bildschirm bewegen können. Doch nun zuerst einmal zum Aussehen ei- nes solchen Sprites. Ein Sprite muß näm- lich, bevor wir es auf den Bildschirm bringen können erst einmal "definiert" werden. Im Klartext heißt das, daß wir zunächst einmal festlegen müssen, wie unsere kleine Grafik da denn auszusehen hat. Täten wir das nicht, so erhielten wir nur ein paar wirre Punkte, die da irgendwo in der Gegend herumhingen... Ein Sprite setzt sich aus 24 mal 21 Punkten zusammen. Es kommt also zunächst einmal darauf an, daß wir uns einen Plan davon machen, welche Punkte in diesem Spritefeld erscheinen sollen, und welche nicht. Hierzu malen wir uns auf einem Stück Papier ein Gitter mit 24 mal 21 Kästchen auf. Unser kleines Bildchen, das wir darstellen wollen, können wir nun durch das Ausmalen der ensprechenden Kästchen auf Papier bringen. Sie können hierzu übrigens auch gerne einen der zahlreichen Spriteeditoren der Magic- Disk verwenden, damit lassen sich ein- zelne Korrekturen einfacher durchführen. Doch gibt es da dann meist Probleme, die Spritedaten in ein Programm einzubauen (meist benötigt man hierzu etwas mehr Verständnis der Materie). Sie sollten Ihr erstes Sprite jedoch ruhig einmal auf konventionelle Art und Weise, näm- lich auf Papier, konstruieren, damit Ihnen der Aufbau von Sprites etwas mehr einleuchtet.
Teil 2 Grafikkurs ----------------------------------------
Somit hätten wir nun also unser Sprite (hier eine kleine Untertasse) zu Papier gebracht. Doch wie bringen wir dem C64 jetzt bei, daß er genau das, was wir da auf dem Papier haben, auch auf dem Bild- schirm darstellt? Nunja, wie Sie be- stimmt schon erraten haben, haben die Zahlen neben der Grafik oben etwas damit zu tun. Ich habe da dann auch noch alle 8 Kästchen einen dickeren Strich gezo- gen, was natürlich auch seine Bedeutung hat. So stehen jetzt also immer acht Punkte nebeneinander. Wie wir ja bei der Betrachtung des Binärsystems gelernt hatten, bilden acht Bits ein Byte. Und ebenso paßt ein einziges Byte (also 8 Bits) in eine Speicherzelle unseres 64ers. Ich denke, daß es spätestens jetzt bei Ihnen klingelt. Jeder Punkt in unserem Spritegitter repräsentiert näm- lich 1 Byte. In X-Richtung, also in der Horizontalen, sind das genau drei Bytes, die hintereinander stehen. Es geht nun darum, die Binärzahlen, die wir uns an- hand der ausgefüllten (gleich Binär 1) und unausgefüllten (gleich Binär 0) Kästchen bilden, in Dezimalzahlen umzu- rechnen, um die Daten in BASIC auch ent- sprechend im Speicher des 64ers unter- bringen zu können, denn dieser verarbei- tet ja ausschließlich nur diese Zahlen. Nunja, nichts leichter als das, wie die- ses Umrechnungsverfahren funktioniert hatten wir uns ja im fünften Basickurs schon klargemacht:Jedes Bit hat einen bestimmten Wert. Ist es gesetzt (=1), dann wird dieser Wert einer Endsumme hinzuaddiert. So verfahren wir mit allen Bits, die in dem Byte vorkommen, und erhalten somit, nach Addition aller Summanden, eine Endsumme, die die ge- suchte Binärzahl in Dezimalschreibweise darstellt.
Teil 3 Grafikkurs ----------------------------------------
Ich habe Ihnen hier auch noch gerade (anhand des 8.Bytes des UFO-Sprites aus Grafik 1) ein kleines Beispiel gelie- fert, wie die umgerechenete Zahl für dieses Byte aussehen sollte. Nachdem wir nun alle Bytewerte (jeweils 3 Stück pro Zeile, mal 21 Zeilen, macht insgesamt 63 Bytes) unseres kleinen Sprites berechnet haben müssen wir diese Werte zeilenweise direkt in den Speicher unseres 64ers schreiben, also in der Reihenfolge :
1. Byte = 1. Zeile links 2. Byte = 1. Zeile mitte 3. Byte = 1. Zeile rechts 4. Byte = 2. Zeile links 5. Byte = 2. Zeile mitte
...und so fort... Hierbei stellt sich ein neues Problem. Nämlich das, daß BASIC V2.0 in keinster Weise die Spriteprogrammierung, bezie- hungsweise die Grafikprogrammierung im allgemeinen, unterstützt. Wir müssen uns die Speicherbereiche, in die wir die Bytewerte schreiben wollen, also selbst aussuchen. Doch das kann sich als äu- ßerst schwierig und aufwending erweisen, wie Sie im folgenden erkennen werden: Das Problem ist nämlich, daß prinzipiell ALLE Speicherbereiche in unserem 64er schon für bestimmte Aufgaben reserviert sind. Die Entwickler der 64ers haben uns da zwar doch noch ein wenig Handlungs- freiheit geschaffen, und haben da tatsächlich noch 4 Speicherbereiche für Sprites übriggelassen. Möchte man nun allerdings mehr als 4 verschiedene Spri- tes gleichzeitig auf den Bildschirm bringen, so kommt man da ganz schön in die Bredouille. Man scheitert nämlich ganz einfach an Speicherplatzmangel. Doch keine Panik - auch dieses Problem ist mit einigen Tricks zu lösen, die ich Ihnen später, wenn wir HIRES-Grafik und Zeichensätze behandeln, näher erläutern werde. Zunächst einmal wollen wir uns einmal um die eben genannten 4 Speicher- bereiche kümmern, da diese für unseren momentanen Wissensstand vollkommen aus- reichen. Diese 4 Bereiche liegen inner- halb der ersten 1024 Bytes unseres Com- puters. Wie ich im fünften Basickurs schon erwähnte, sind diese Speicherstel- len hauptsächlich für Computerinterne Funktionen reserviert, und durch uns nur begrenzt nutzbar. Diese Einschränkung gilt nun auch in unserem Fall. Die 4 Speicherbereiche von je 63 Bytes Länge existieren zwar, jedoch dürfen die letz- ten 3 davon (siehe Tabelle unten) von uns nur dann benutzt werden, wenn wir nicht mit der Datasette, einem Kasetten- laufwerk also, arbeiten. Da ich aller- dings davon ausgehen kann, daß Sie, als Magic Disk Leser bestimmt NICHT mit der Datasette arbeiten, sonst könnten Sie diesen Artikel hier nämlich gar nicht lesen, stellt dies also für uns nur ein geringes Problem dar. Doch nun endlich zur Lage dieser 4 Bereiche. Hier eine Öbersicht :
Von Bis Spriteblock Nr. -------------------------
704- 766 11 832- 894 13 896- 958 14 960-1022 15
Die letzte Angabe dieser Tabelle dürfte Sie vielleicht stutzig machen, da ich die Spriteblocks bisher noch nicht erwähnte. Eine Spriteblocknummer brau- chen wir, um dem VIC angeben zu können, aus welchem Speicherbereich er sich nun die 63 Datenbytes für das darzustellende Sprite holen soll. Die Blocks sind alle numerisch geordnet, gehen also von 0 bis 255. Geben wir dem VIC nun an, daß er sich die Spritedaten für ein Sprite aus dem Block Nummmer 11 holen soll, so be- rechnet er sich die "wahre" oder auch "absolute" Speicheradresse, in der das erste Datenbyte steht (bei Block 11 wäre das Speicherzelle 704, wie aus obiger Tabelle ersichtlich), indem er intern die Blocknummer mit 64 multipliziert. So wissen Sie also, daß Spritedaten nicht einfach wahllos im Speicher unseres 64ers abgelegt werden können, sondern IMMER bei einem Produkt von 64 beginnen sollten (11*64=704). Ein Spriteblock mit der Nummer 51 würde somit also bei Adresse 3264 beginnen, einer mit der Nummer 154 bei Adresse 9856 - dies nur einmal als Beispiel. Nun geht es uns darum, unsere Daten erst einmal in die entsprechenden Speicherbe- reiche zu schreiben. Wir hatten ja unser kleines UFO-Sprite in Dezimalwerte zer- legt, die wir nun irgendwo unterbringen müssen. Sie könnten sich nun hinsetzen und mit Hilfe des POKE-Befehls Byte für Byte in den Speicher schreiben. Einfa- cher geht es jedoch mit Hilfe von READ und DATA. Sie erinnern sich hoffentlich noch an diese beiden Befehle, aus dem BASIC-Kurs. Wir legen unsere Daten jetzt nämlich ganz einfach in ein paar DATA- Zeilen ab, lesen sie durch eine Schleife Byte für Byte ein und schreiben sie gleichzeitig in einen der 4 oben genann- ten Speicherbereiche. Wie wäre es denn mit Spriteblock 13 ! Er ersteckt sich von Byte 832 bis einschließlich Byte 894. Hier also unser kleines Programm :
10 FOR I=0 TO 62 :REM 63 DATENBYTES! 20 READ A 30 POKE 832+I,A 40 NEXT I 50 : 60 DATA 0,0,0,0,24,0,0,126,0 70 DATA 1,255,128,7,255,224,30,102,120 80 DATA 54,102,108,54,102,108,31,255,248 90 DATA 7,255,224,1,255,128,1,129,128 100 DATA 3,0,192,3,0,192,6,0,96 110 DATA 6,0,96,12,0,48,127,0,255 160 DATA 0,0,0,0,0,0,0,0,0
Wir zählen also mit der Laufvariablen I von 0 bis 62 (insgesamt 63 Durchgän- ge!). Es wird nun ein Datenbyte eingele- sen und gleich geschrieben, angefangen bei Adresse 832 (Basisadresse 832 plus 0) bis 894 (832 plus 62). Nachdem wir nun die Daten abgelegt hät- ten kommen wir zum zweiten Schritt : VIC muß ja noch wissen, aus welchem Sprite- block er sich die Spritedaten holen soll. Hierzu sind acht Speicherzellen zuständig, die sich im Bereich von 2040-2047 finden. Für jedes Byte haben wir eine Speicherzelle. 2040 für Spri- te 0, 2041 für Sprite 1, 2042 für Spri- te 2, und so fort, bis Byte 2047 für Sprite 7. Wir wollen einmal Sprite 0 auf den Bild- schirm bringen. Hierzu müssen wir die Blockadresse in Zelle 2040 schreiben. Unsere Daten liegen ja im Sprite- block 13, also: POKE 2040,13 Soweit - so gut. Trotzdem haben wir noch nicht alle Hindernisse hinter uns ge- bracht. Des Weiteren müssen wir nämlich, um das Sprite auf dem Bildschirm zu se- hen, dem VIC sagen, daß er es für uns dort anzeigen soll. Wir müssen es quasi "einschalten". Hierfür ist das VIC- Register 21 zuständig. Es steuert das Einschalten aller 8 Sprites. Dies wird folgendermaßen gehandhabt: Jedes der 8 Bits in diesem Register ist zuständig für ein Sprite. Ist es gesetzt (hat also den Wert 1), so ist sein zugehöriges Sprite eingeschaltet, ist es gelöscht (=Wert 0) so ist das Sprite ausgeschal- tet. Hier eine Tabelle der Zuständigkeit der Bits:
--------------------------------------- Bit 7 6 5 4 3 2 1 0 Sprite 7 6 5 4 3 2 1 0 Wert 128 64 32 16 8 4 2 1 ---------------------------------------
Möchte man also mehrere Sprites ein- schalten, so muß man die Werte ihrer zu- gehörigen Bits addieren und in Regi- ster 21 schreiben. Wollten wir also beispielsweise Sprite 6 und Sprite 2 einschalten, so wäre der Wert für Regi- ster 21 des VIC: 64+4=68. Da wir jedoch lediglich Sprite 0 auf den Bildschirm bringen wollen, genügt es, den Wert 1 in Register 21 zu schreiben. Damit wir übrigens keine Probleme mit der umständlchen Berechnung der Register bekommen, definieren wir ganz einfach eine Variable mit Namen V - für VIC - mit dessen Basisadresse (53248). Mit dieser Sequenz schalten wir also unser Sprite ein:
V=53248 POKE V+21,1
Natürlich hätten Sie im POKE-Befehl auch gleich eine absolute Adresse angeben können (für Register 21 nämlich 53269), die andere Schreibweise vereinfacht je- doch die Arbeit mit Registern und ist zudem auch noch viel übersichtlicher. Sicher ist Ihnen nun aufgefallen, daß unser Sprite immer noch nicht auf dem Bildschirm erschienen ist. Doch keine Panik, Sie haben hier nicht unbedingt etwas falsch gemacht - Sprite 0 ist näm- lich schon da, nur wir sehen es nicht, weil es sich noch versteckt hält ! Nor- malerweise sollte es sich nun, wenn Sie ihren 64er frisch eingeschaltet haben, an der Position 0/0 des Bildschirms be- finden. Womit wir schon gleich beim The- ma wären. Wie Sie aus der Register- Tabelle schon entnehmen konnten, können wir mit Hilfe der ersten 16 VIC-Register die Koordinaten für jedes der 8 Sprites angeben. Hierzu haben wir zwei Koordina- ten : Zum Einen die X-Koordinate, die angibt, um wieviele Bildschirmpunkte das Sprite vom linken Bildschirmrand vesetzt sich aufhält, und zum Anderen die Y- Koordinate, die angibt um wieviel Bild- schirmpunkte vom oberen Bildschirmrand versetzt, sich das Sprite befinden soll. Dies alles wird auf den ersten Punkt des Sprites (ganz links oben) bezogen. Der Grund, warum wir das Sprite nicht sehen können, liegt darin, daß der Bild- schirm, so wie wir ihn sehen, nicht etwa an der Nahtstelle Rahmen/Hintergrund beginnt, sondern daß eher ein Teil des Bildschirms, durch den Bildschirmrahmen überlagert, für uns nicht sichtbar ist. Somit befindet sich also unser kleiner Freund zwar auf dem Bildschirm, jedoch unter dem Rahmen versteckt !
Teil 4 Grafikkurs ----------------------------------------
Wie Sie erkennen können, liegt unser Sprite (wenn es die Koordinaten 0/0 hat) ganz genau in der linken oberen Ecke des Bildschirms, allerdings im unsichtbaren Breich. Erst ab den Koordinaten X=24 und Y=50 beginnt der sichtbare Bildschirmbe- reich. Da sich unser Sprite in einem Koordinatenbereich befindet der kleiner als die ersten sichtbaren Koordinaten ist, kann man es natürlich noch nicht sehen. Wozu dies alles gut sein kann, werden wir später noch sehen. Zunächst einmal wollen wir unser Sprite einmal auf den Bildschirm bringen. Hier- zu müssen wir lediglich die entsprechen- den Bildkoordinaten in die Koordinaten- register unseres Sprites schreiben. Das sind für Sprite 0 die Register 0 und 1 für die X- und Y-Koordinate. Positionie- ren wir unser Sprite doch einfach einmal in der Ecke links oben, diesmal jedoch die Sichtbare :
POKE V+0,24 :REM X-KOORDINATE POKE V+1,50 :REM Y-KOORDINATE
So. Nun müßten Sie endlich unser Sprite auf dem Bildschirm sehen. Da steht es nun und läßt sich durch nichts beein- drucken. Lassen Sie doch einmal den Bildschirm nach oben scrollen, indem Sie mit dem Cursor in die untere linke Ecke fahren und eventuell vorhandenen Text "nach oben rollen" lassen. Sie werden bemerken, daß unser Sprite kontinuier- lich auf seiner Stelle stehen bleibt und sich nicht von seiner links-oben- Position wegbewegen läßt. Sprites sind somit also tatsächlich unabhängige Gra- fikobjekte, mit denen man ganz eigene Dinge machen kann. Nun, man muß zugeben, daß ein unbewegli- ches Sprite auf die Dauer ziemlich lang- weilig werden kann. Wie wäre es denn, wenn wir unseren kleinen Freund zuerst einmal aus dem oberen Bildschirmrand runterlaufen ließen, und ihm dann einen Richtungswechsel nach rechts verpaßten ? Nichts einfacher als das ! Hierzu müssen wir einfach eine Schleife schreiben, die die X-, beziehungsweise Y-Position unse- res Sprites erhöht, oder erniedrigt. Hier ein Beispiel (wir setzen voraus, daß alle Daten schon im Speicher stehen, und das Sprite ordungsgemäß eingeschal- tet wurde) :
10 v=53248 20 POKE V+0,24 :REM SICHTBARE X-KOORDINATE. 30 FOR I=39 TO 150 :REM VON 39 BIS 150 ZÄHLEN... 40 FOR K=0 TO 10:NEXT K :REM VERZöGE- RUNGSSCHLEIFE, SONST GEHTS ZU SCHNELL 50 POKE V+1,I :REM Y-POS SETZEN 60 NEXT I 70 : 80 FOR I=24 TO 255 :REM JETZT VON 24 BIS 255 ZÄHLEN... 90 FOR K=0 TO 10:NEXT K: :REM WIEDER VERZöGE- RUNG, DAMITS FÖRS AUGE SICHTBAR WIRD. 100 POKE V+0,I 110 NEXT I
Wenn Ihnen das hier zu unübersichtlich ist, dann starten Sie doch einfach ein- mal das Programm "MOVESPRITE" auf der Rückseite der Magic Disk. Hieran sehen Sie dann auch wozu so ein "unsichtbarer" Bildschirmbereich nützlich ist. Man kann nämlich ein Sprite kurzerhand in den sichtbaren Bereich hineinbewegen, daß ist bestimmt ein besserer Auftritt für unseren kleinen Freund, als wenn er ein- fach - Zack - auf dem Bildschirm er- scheinen würde... Vielleicht ist Ihnen in diesem Beispiel hier ja aufgefallen, daß ich die X- Koordinate nur bis 255 gezählt habe, und wenn das nicht der Fall war, dann hat Sie aber ganz sicher der Ausdruck "Low- Grenze" in der letzten Grafik stutzig gemacht. 255 ist ja der höchste Wert den ein Byte annehmen kann. Für die X- Koordinate ist dies also der größtmö- glichste einsetzbare Wert. Wenn Sie jetzt einmal ein Sprite an die X- Position 255 setzen, dann werden Sie sehen, daß es noch mitten auf dem Bild- schirm steht. Was aber, wenn wir den Bereich ab 255 noch nutzen, unser Sprite also noch ein bisschen weiter bewegen möchten ? Hierfür ist, wie Sie es in der Liste der VIC-Register vielleicht schon gesehen haben, Register Nummer 16 ver- antwortlich. Das Hauptproblem, das wir nämlich haben, ist, daß das X-Register eines Sprites nur auf 8 Bit begrenzt ist. In Register 16 stellt uns der VIC nun ein weiteres, neuntes Bit zur Verfü- gung. Das Register 16 selbst hat ja ebenfalls 8 Bits, für jedes Sprite eins. Für Sprite 0 ist Bit 0 zuständig, für Sprite 1 gibt es das Bit Nummer 1 und so weiter... Doch wozu brauchen wir die ganzen neun- ten Bits ? Ganz einfach, dadurch erhöht sich der Wertebereich des Ganzen nämlich auf (dezimal) 512 X-Positionen (die 0. Position miteingerechnet) ! Sie müssen sich also für die X-Position eine 9- Bit-Binärzahl vorstellen. Wollenten wir unser Sprite beispielsweise an Position 256 setzen, so wäre die 9-Bit- Kombination "1 0000 0000" - das neute Bit wäre also gesetzt, alle acht anderen gelöscht. Die ersten acht Bits kommen immer in das "normale" X-Register eines Sprites. Das neunte nun schreiben wir in Register 16. Bei Sprite 0 wäre das ja das 0. Bit dieses Registers. Dieses hat den Dezimalwert 1, also schreiben wir in V+16 den Wert 1 und schon hätten wir unser Sprite ein Stückchen weiter über die Low-Grenze hinausgeschoben. Also : POKE V+0,0 POKE V+16,1 Wollten wir es jetzt weiterbewegen, so müßten wir einfach wieder das X-Register verändern, das neute Bit in Register 16 ist ja jetzt gesetzt. In unserem Bei- spielen vorhin, war es - wenn Sie Ihren 64er gerade frisch eingeschaltet hatten - schon von Haus aus auf 0, deshalb ist unser Sprite dann auch in der linken Bildschirmhälfte erschienen. Wird jedoch das neute Bit der X-Koordinate gesetzt, dann dient nun als relativer Anfang- spunkt die Bildschirmposition 256. Ach- ten Sie also immer darauf, daß Sie beim Positionieren von Sprites immer eine 9-Bit-Zahl verwenden, wobei das neute Bit immer in Register 16 wandert und die restlichen acht im entsprechenden X- Register des Sprites landen. Setzen wir doch einfach einmal Sprite 1 an die X- Koordinate 300. Binär gesehen hat 300 die folgende Kombination : 1 0010 1100 Demnach müssen wir also Bit 1 im Regi- ster 16 setzen. Dieses hat den Dezimal- wert 2. Die restlichen 8 Bits haben ins- gesamt den Dezimalwert 44. Also :
POKE V+16,2 :REM HI-BIT SPRITE 1 SETZEN POKE V+2,44 :REM X-POSITION SPRITE 1
Sehen Sie Register 16 also bitte als eigenständiges Register an. Auch hier müssen 8-Bit Werte hineingeschrieben werden ! Wollten Sie also beispielsweise Sprite 0, 2 und 5 in einen X-Bereich hinter 256 setzen, so müßten Sie den entsprechenden Dezimalwert, nämlich 37, ganz normal in dieses Register hinenPO- KEen !!! Eine andere Möglichkeit gibt es durch die logischen Operatoren, die ich im BASIC-Kurs bewußt NICHT behandelt habe, da sie wirklich nur eine wichtige Rolle in der Grafik spielen. Deshalb möchte ich dies hier noch nachholen. Die logischen Operatoren kann man wie die arithmetischen Operatoren (+,-,*,/) verwenden. BASIC stellt uns ihrer drei zur Verfügung, nämlich AND, OR und NOT. Man kann logische Operatoren hervorra- gend zur gezielten Manipulation von Bits benutzen, ohne voher irgendwelche Binär- zahlen in Dezimalzahlen umrechnen zu müssen und umgekehrt. Bei AND und OR werden ganz einfach zwei Binärzahlen und ihre Bits miteinander verglichen, und nach einer logischen Entscheidungstabel- le resultiert aus dem Zustand dieser Bits ein bestimmtes Ergebnis. Das hört sich vielleicht komplizierter an als es ist. Beginnen wir doch einfach einmal mit einem Beispiel. AND ist englisch und heißt UND. Ich möchte nun einmal ganz einfach mit dem AND-Operator verglei- chen, und Ihnen das Ergebnis erklären. Hier erst einmal das Beispiel :
0100 0010 (dez. 66) AND 0101 0000 (dez. 80) ----------------------- = 0100 0000 (dez. 64)
Der Computer hat hier zwei 8-Bit-Zahlen miteinander geUNDet. Hierbei hat er im- mer das n-te Bit der ersten Zahl mit dem n-ten Bit der zweiten Zahl verglichen und dann ein aus den beiden Bits resul- tierendes Bit ermittelt. Hierbei ging er nach dem Schema vor, daß nur, wenn das Bit der ersten Zahl UND (AND) das Bit der zweiten Zahl 1 oder 0 war, das re- sultierende Bit ebenfalls gleich 1 oder 0 war. In allen anderen Fällen, also wenn das Bit der ersten Zahl gleich 0 und das Bit der zweiten Zahl gleich 1 war (beziehungsweise umgekehrt), war das resultierende Bit gleich 0 ! Ebenso verhält sich das bei OR, was auf Deutsch ODER heißt. Hier ein Beispiel :
0100 0010 (dez. 66) OR 0101 0000 (dez. 80) ----------------------- = 0001 0010 (dez. 18)
Sie sehen, als Ursprungszahlen habe ich dieselben genommen wie eben, jedoch ist das Ergebnis nun ein anderes. Hierbei waren ja auch die Enscheidungskriterien nicht dieselben. Das resultierende Bit aus den zwei n-ten Bits einer Zahl war nämlich nur dann 1, wenn das Bit der ersten Zahl ODER (OR) das Bit der zwei- ten Zahl gesetzt war. ODER wenn beide Bits gesetzt waren. Nur wenn Beide 0 waren, war das resultierende Bit eben- falls gleich 0 !
Teil 5 Grafikkurs ----------------------------------------
Ich habe hier dann auch noch gleich eine Wertigkeitstabelle für NOT angegeben. Sie sehen, daß es sich hier etwas anders verhält, als bei den beiden ersten Ope- ratoren. NOT ist eigentlich auch gar kein Operator, man stellt es nämlich einfach nur einer Zahl voran. Was jetzt geschieht ist folgendes : alle Bits die- ser Zahl werden in ihr Gegenteil umge- wandelt (0 ist nämlich NICHT (NOT) 1 und somit das Gegenteil von 1 und umge- kehrt). Auch hier wieder ein Beispiel :
NOT 1001 0110 (dez. 150) ------------------------
= 0110 1001 (dez. 105)
Ist doch ganz einfach, oder ? Nun, wozu brauchen wir das denn, bei der Spriteprogrammierung. Ich möchte da noch einmal das Beispiel mit Register 16 strapazieren. Wir hatten ja gesagt, daß in diesem Register jedes Sprite ein ei- genes neutes Bit für die X-Position hat. Nun kann es sehr leicht vorkommen, daß wenn man in einem Programm mehrere Spri- tes über den Bildschirm bewegt, langsam aber sicher den Öberblick verliert, wel- ches Sprite nun das 9. Bit gesetzt haben muß und welches nicht. Würden wir jedes- mal, wenn ein neues Sprite in den X- Bereich über 256 rücken müßte einfach dessen neuntes Bit hineinPOKEn, so könn- te es gut sein, daß wir damit wiederum das neunte Bit eines andern Sprites lö- schen, was vielleicht nicht sein sollte, und zur Folge hätte, daß diese Sprites munter und lustig über den Bildschirm hüpfen, und sich nich fließend bewegen würden. Um diesem Problem entgegenzugehen, be- nutzen wir ganz einfach die logischen Operatoren, denn die wissen ja mit Bits umzugehen. Angenommen, Sprite 2 und 4 wären schon in einem X-Bereich über 256 und wir wollten nun auch noch Sprite Nummer 1 hinzuschalten. Register 16 sieht demnach also zuerst einmal folgen- dermaßen aus : 0001 0100 Um jetzt Sprite 1 hier auch noch bedie- nen zu können, müssen wir lediglich Bit 1 setzen. Hier hilft uns OR direkt wei- ter. Wir müssen nur den jetzigen Inhalt von Register 16 mit dem Binärwert "0000 0010" (dezimal 2) durch OR logisch verknüpfen. Nach der Entscheidungstabel- le von oben sieht das Ergebnis dann so aus :
0001 0100 OR 0000 0010 -------------
= 0001 0110 Es wäre geschafft ! Wir hätten nun Bit 1 gesetzt, ohne die anderen zu verändern, geschweige denn, die ganze Zahl ins De- zimalsystem oder umgekehrt umrechnen zu müssen. Programmatisch gesehen, sähe das dann so aus :
POKE V+16, PEEK(V+16) OR 2
Ähnlich verhält es sich umgekehrt. Ange- nommen, Sprite 2 sollte wieder herunter- geschaltet werden. Hierzu gibt es jetzt 2 Methoden. Zuerst einmal die Umständlichere von beiden, mit Hilfe von AND. Wir verknüp- fen hierzu den jetzigen Inhalt von Regi- ster 16 mit dem Binärwert "1111 1011" (dez. 251). Hier die Rechnung :
0001 0110 AND 1111 1011 -------------
= 0001 0010 Es waren also bei AND alle Bits gesetzt, bis auf das eine, daß gelöscht werden sollte. Sollte eins der ursprünglichen Bits 1 gewesen sein, so kam als Resultat ebenfalls 1 heraus - es wurde nichts verändert. Nur das eine Bit, daß bei AND gelöscht war, hat bewirkt, daß das ursprünglich Bit ebenfalls gelöscht wur- de (denn 1 AND 0 = 0). Andere Bits, die ursprünglich den Wert 0 aufwiesen, wur- den sowieso nicht verändert (denn 0 AND 1 = 0). Hier wieder ein Beispiel, wie das im Programm aussehen sollte :
POKE V+16, PEEK(V+16) AND 251
Also auch das gezielte Löschen von Bits ist möglich. Doch es geht, wie eben schon erwähnt, auch einfacher. Sie müs- sen doch zugeben, daß das Berechnen der sogenannten AND-Maske, der Zahl also, mit der man die ursprüngliche Zahl verknüpfen möchte, ziemlich zeitaufwen- dig und mühselig ist. Doch wozu gibt es denn NOT, nimmt uns dieser Operator doch alle Arbeit ab ! Wir müssen NOT einfach nur den Wert des zu löschenden Bits übergeben, es verwandelt diesen doch in sein Gegenteil, also das, was wir dann mit AND knüpfen müssen ! Hier ein Bei- spiel, bei dem ebenfalls das 2. Bit von Register 16 wieder gelöscht wird, dies- mal jedoch ohne umständliches Herumrech- nen :
NOT 0000 0100 = 1111 1011 --> 0001 0110 AND 1111 1011 (Ergebnis der NOT- Operation) ----------------------------------------
= 0001 0010 Im Prinzip haben wir also dasselbe getan wie im Beispiel mit AND, nur daß die Umrechnungsarbeit diesmal von NOT über- nommen wurde. Auch dieses Beispiel kann man in einer Programmzeile zusammenfas- sen :
POKE V+16, PEEK(V+16) AND NOT 4
Das wärs dann für heute. Sollten Sie das mit den logischen Operatoren nicht ganz verstanden haben, dann empfehle ich Ih- nen es sich noch einmal anzuschauen, denn nächsten Monat, wenn wir die HI- RES-Grafiken und den Rest, was es über Sprites noch zu sagen gibt, abhandeln, wird es in der Beziegung ganz schön rund gehen. Bis dahin wünsche ich Ihnen noch viel Erfolg bei der ersten Spriteprogrammie- rung und sage Tschüß,
Ihr Uli Basters.
"Picasso und all die andern..." Teil 2 ----------------------------------------
Ring frei zur zweiten Runde in Sachen Grafik. Diesmal wollen wir die Sprites zu Ende abhandeln. Sie hatten letzten Monat ja schon ge- lernt, was man alles machen muß, um ein Sprite auf den Bildschirm zu bringen und wie man es über den Bildschirm bewegt. Heute wollen wir nun noch ein paar Ein- zelheiten klären, mit denen man gezielt Sprites manipulieren kann. Und die sind sehr zahlreich, aber aufgrund der Infor- mationen des letzten Kurteils auch sehr einfach zu verstehen. Also los gehts...
a) Spriteexpansion: ---------------------
Wie Sie sicherlich noch wissen, war ein Sprite genau 24x21 Punkte groß. Wenn Sie sich dies einmal auf dem Bildschirm an- gesehen haben, so war zu erkennen, daß dies eigentlich ein relativ kleiner Be- reich ist. Was aber wenn wir jetzt ein Spiel schreiben wollten, in dem ein be- sonders großes Raumschiff in einer klei- nen Animation über den Bildschirm glei- tet? Da gibt es grundsätzlich 2 Möglich- keiten. Zum einen die, daß man einfach mehrere Sprites zusammenfaßt und diese dann nebeneinander darstellt. Das hat aber auch den Nachteil, daß nicht mehr viele weitere Sprites übrigbleiben wür- den, mit denen wir noch andere Dinge über den Bildschirm huschen lassen könn- ten, denn wir haben ja nur 8 von diesen kleinen und schnuckeligen Grafikobjek- ten. Deshalb können wir auch auf eine andere Methode zurückgreifen: die Spri- teexpansion. Was ist das, Expansion? Nun Expansion heißt nichts anderes als "Erweiterung" oder besser "Dehnung". Durch die Spri- teexpansion können wir also Sprites deh- nen. Hierbei wird der Bereich eines Sprites einfach um das doppelte erwei- tert. Im Klartext heißt das, daß wir auf diese Art und Weise die Größe von 24x21 auf 48x42 Punkte erhöhen. Das ist eine flächenmäßige Vergrößerung um den Faktor 4. Das Sprite ist jetzt also viermal größer als wenn es nicht-expandiert wäre! Die ganze Sache hat aber auch einen Nachteil. VIC benutzt zur Expansion näm- lich immer noch die alten 63 Bytes, wie Sie zur Darstellung von einem "normalen" Sprite nötig sind und nicht etwa das vierfache davon (=252 Bytes). Wir hatten ja gesagt, daß das Sprite "gedehnt" wird, und das ist auch genauso wörtlich aufzunehmen. VIC tut nichts anderes, als jeden Bildpunkt eines Sprites zu dehnen. Das heißt daß er da, wo vorher nur ein Punkt war zwei Punkte in X-Richtung und zwei Punkte in Y-Richtung darstellt. Hierbei hat die Grafikauflösung kräftig zu leiden, denn so haben wir nicht mehr einzelne feine Punkte, sondern dicke Klötze auf dem Bildschirm. Am besten ich zeige Ihnen einmal den Unterschied in Form einer Grafik:
Doch nun zum Praktischen. Um ein Sprite expandieren zu können stellt uns VIC 2 weitere Register zur Verfügung. Zum einen hätten wir da Register 29 für die Vergrößerung in X-, zum anderen Register 23 für Vergrößerung in Y-Richtung. Diese beiden Register sind ähnlich Register 16 aufgebaut, das wir ja für die neunten Bits der X-Position eines Sprites ver- wandten. Hier ist nämlich ebenfalls für jedes der acht Sprites ein Bit reser- viert. Möchten wir nun ein Sprite in X- oder Y-Position expandieren, so müssen wir lediglich dessen Bit in Register 23 und/oder 29 setzen, je nach dem in wel- che Richtung es vergrößert werden soll. Hier nochmal eine Öbersicht, welches Bit eines Registers für welches Sprite zuständig ist:
Bit : 7 6 5 4 3 2 1 0 Sprite: 7 6 5 4 3 2 1 0
Ist das Expansionsbit eines Sprites also gesetzt, so wird das Sprite vergrößert, ist es gelöscht, so wird es in der noma- len Auflösung dargestellt. Zur Demonsta- tion habe ich Ihnen auf der Rückseite dieser MagicDisk ein kleines Programm namens "SPRITE-EXP" gespeichert. Da kön- nen Sie sich unser UFO-Sprite nocheinmal ansehen.
2.) Farbige Sprites: --------------------
Wenn Sie letzten Monat einmal Sprite 0 auf dem Bildschirm hatten, dann hatte es -fast ganz selbstverständlich- die Farbe Weiß. Merkwürdigerweise war das Sprite 1 (wenn Sie dieses einmal eingeschaltet hatten) nicht der Fall. Dieses sollte nämlich direkt nach dem Einschalten des Rechners in sattem Rot geleuchtet haben. Sie merken schon worauf ich hinaus möch- te: man kann einem Sprite nämlich auch eine bestimmte Farbe zuordnen. Dies funktioniert genauso, als wollten Sie die Bildschirmfarbe ändern, nur müssen wir diesmal die Farbe nicht ins Hinter- grundregister schreiben, sondern in das dem Sprite zugehörige Farbregister. Die- se sind Ihnen bestimmt schon in der Re- gister-Tabelle aus dem letzten Kursteil aufgefallen. Es sind die Register 39 bis 46. Für jedes der 8 Sprites ein Regi- ster. Möchten wir also Sprite 0 nicht in Weiß, sondern beispielsweise in Schwarz auf dem Bildschirm sehen, so müssen wir schlichtweg eine 0 in Register 39 schreiben. Die Farbwerte sind dieselben wie bei der Hintergrundfarbgebung. Hier jedoch trotzdem nocheinmal eine Tabelle:
Wert Farbe Wert Farbe ----------------------------------------
0 Schwarz 8 Orange 1 Weiß 9 Braun 2 Rot 10 Hellrot 3 Türkis 11 Dunkelgrau 4 Violett 12 Mittelgrau 5 Grün 13 Hellgrün 6 Blau 14 Hellblau 7 Gelb 15 Hellgrau
Schreiben Sie nun einen dieser Werte in das Farbregister eines Sprites, so er- scheint dieses dann in der angegebenen Farbe (unter der Vorraussetzung, daß es natürlich auf dem Bildschirm sichtbar ist).
3.) Multicolorsprites: ----------------------
Nun können wir also auch einem Sprite eine Farbe zuweisen. Doch müssen Sie zugeben, daß dies auf die Dauer auch nicht die optimale Sache ist. Ein klei- nes Männchen, was da auf dem Bildschirm steht, würde sich doch viel besser ma- chen, wenn es nicht nur uni-Weiß wäre, sondern wenn es ein gesundes rosa Ge- sicht, einen gelben Pulli, und eine blaue Hose hätte. Sowas spricht doch bestimmt mehr an, als ein einfarbiger Klotz, bei dem man nicht Körper von Kopf unterscheiden kann. Nun, wie die Öber- schrift dieses Kapitels zeigt, gibt es auch die Möglichkeit, einem Sprite MEH- RERE Farben zuzuordnen (multi=viel; co- lor=Farbe; multicolor=vielfarbig). Um das "viel" gleich schon etwas genauer zu spezifizieren, kann ich Ihnen gleich verraten, daß ein Sprite maximal 4 von den 16 oben aufgelisteten Farben annhe- men kann. Die Sache mit der Vielfarbigkeit von Sprites hat aber wiederum einen kleinen Haken. Wir müssen nämlich, wie bei der Spriteexpansion auch, einen kleinen Auflösungsverlust hinnehmen. Diesmal wird sie halbiert, jedoch nur in X- Richtung. Das heißt, daß wir mit einem Multicolorsprite nur noch 12x21 Punkte darstellen können. Achtung, jetzt wirds kompliziert: Trotz- dem wir zwar nur noch 12 Punkte in X- Richtung darstellen können, ist das Sprite jedoch immer noch 24 Punkte breit! Deshalb schauen Sie sich am be- sten erst einmal die folgende Grafik an, bevor ich mich in umständlichen Erkl- ärungen verliere, die eh keiner ver- steht...
Die Grafik verrät es schon: bei Multico- lorsprites werden zwei Grafikpunkte zu einem zusammengefaßt. Doch wozu das Gan- ze? Nun ganz einfach - diese beiden Gra- fikpunkte die EINEN Multicolorpunkt er- geben können ja jeweils entweder gelöscht(=Binär 0), oder gesetzt(=Binär 1) sein. VIC betrachtet sich nun die Gesamtheit der beiden Punkte und ent- scheidet dann, welche Farbe diese zu- geordnet bekommen. Daraus ergeben sich insgesamt 4 mögliche Bitkombinationen, nämlich: 00 kein Punkt gesetzt 01 erster Punkt nicht, zweiter gesetzt 10 erster Punkt gesetzt, zweiter nicht 11 beide Punkte gesetzt Und schon haben wir unsere 4 maximal möglichen Farben eines Multicolorspri- tes. Die nun folgende Tabelle gibt an, aus welchen Registern sich VIC nun die Farben der einzelnen Kombinationen zu- sammensucht:
Komb. Reg. Bezeichnung -----------------------
00 32 Hintergrundregister 01 37 Sprite-Multicolor-Reg.0 10 39-46 Spritefarbregister 11 38 Sprite-Multicolor-Reg.1
Hier haben wir dann auch noch gleich die beiden Sprite-Multicolor-Register ken- nengelernt. In diese beiden Register können wir ebenfalls jeweils einen der 16 möglichen Farbwerte hineinschreiben. Somit haben alle Multicolorsprites 3 Farben immer gemeinsam. Die des Hinter- grundes (Kombination 00, der Hintergrund scheint durch), und die zwei Farben der Multicolorregister. Die vierte Farbe wird dann aus dem "normalen" Farbregi- ster des entsprechenden Sprites geholt, und die kann ja bei allen 8 Sprites ver- schieden sein. Beachten Sie also, daß Sie bei Multico- lorsprites immer nicht nur einen Punkt betrachten, sondern gleich die Bitkombi- nation für 2 Punkte in Ihr Sprite-Raster eintragen! Demnach sähe ein Multicolor- sprite in der "Roh-Darstellung" folgen- dermaßen aus:
Die blauen Kästchen in der Grafik stehen diesmal nicht für die Farbe des entspre- chenden Punktes, sondern nur dafür ob er gesetzt ist oder nicht. Doch kommen wir nun endlich zu der Pro- grammierung des Multicolormodes. Hierzu brauchen wir das Register 28 des VIC. In diesem Register steht ebenfalls jeweils ein Bit für ein Sprite zur Verfügung. Sie können sich also denken, wie wir den Modus einschalten. Einfach das Bit des entsprechenden Sprites setzen, und schon beachtet VIC zwei Bits als farbgebende Information. Zur Demonstration habe ich Ihnen auch diesmal ein Demoprogramm bereitgestellt. Es heißt "MC-SPRITE" und ist auf der Rückseite dieser MagicDisk zu finden.
4.) Sprites im Vorder- oder Hintergrund: ----------------------------------------
Wie Sie soeben richtig gelesen haben, können Sprites sowohl im Hinter- als auch im Vordergrund von Grafik- oder Text auf dem Bildschirm erscheinen. Nor- malerweise waren sie bis jetzt ja immer im Vordergrund. Wenn Sie schon ein wenig mit Sprites experimentiert haben, dann ist ihnen dies bestimmt aufgefallen. Ein Sprite hatte stets etwaige Zeichen auf dem Bildschirm verdeckt. Dies kann je- doch auch von Zeit zu Zeit hinderlich sein. Angenommen, ein von Ihnen program- miertes Männchen solte auf einmal HINTER einem Zaun laufen und nicht VOR ihm, oder das Raumschiff in Ihrem nächsten Spiel sollte eigentlich hinter edm Pla- neten verschwinden und nicht vor ihm herschwirren. Nun, für diesen Fall stellt uns VIC ebenfalls ein Register zur Verfügung. Es ist das Register Nummer 27. Jedes Bit dieses Registers repräsentiert wiederum ein Sprite. Setzen wir das Bit eines Sprites in ihm, so erscheint es ab so- fort HINTER einem Zeichen auf dem Bil- schirm (bzw. einer Grafik, das kommt dann später...); löschen wir es, so ist es wieder im Vordergrund und verdeckt Zeichen oder Grafik.
e) Sprite-Kollisionen: -----------------------
Wie Sie sehen, kann der VIC eine ganze Menge mit Sprites anfangen. Kommen wir nun zur letzten Möglichkeit, mit der er die komfortable Spriteprogrammierung unterstützt, der Sprite-Kollision. VIC steuert nämlich nicht nur seine acht "Schäfchen" über den Bildschirm, sondern er wacht auch über sie, wie ein Schäfer. Und er merkt sofort, wenn sie sich ge- genseitig anrempeln, oder etwa gegen eine Mauer laufen. Doch reden wir Klartext. VIC gibt uns durch Register 30 und 31 die Möglich- keit, zu Öberwachen, ob, und wann ein Sprite entweder mit einem anderen Sprite kollidiert (sprich: mit ihm zusammenge- troffen ist), oder an einem Zeichen des "Hintergrundes" angeeckt ist. Seit dem letzten Kapitel wissen wir ja, daß der Begriff "Hintergrund" für ein Sprite ja nur relativ ist. Es spielt keine Rolle, ob es nun im Hinter- oder Vordergrund steht, es werden die Berührungen mit entsprechenden Grafikobjektem immer re- gistriert. Dabei gibt Register 30 die Sprite-Sprite-Kollision an, und Register 31 die Sprite-Hintergrund-Kollision. Tritt einer der beiden Fälle ein, so setzt VIC das Bit des betroffenen Spri- tes in einem der beiden Register. Bei der Sprite-Sprite-Kollision, sogar immer mindestens zwei, da ja immer das eine Sprite mit dem anderen, und das andere Sprite mit dem einen kollidiert. Würden also beispielsweise Sprite 0 und Sprite 3 sich irgendwo bei ihrer Reise auf dem Bildschirm begegnen, so würde VIC in Register 30 die Bits 0 und 3 setzen, da diese beiden Sprites ja auch an der Kol- lision, oder sagen wir an dem "Unfall" beteiligt sind. Diese Funktion kann übrigens sehr hilfreich bei der Program- mierung von Spielen sein, wenn bei- spielsweise ein gegnerisches Raumschiff von dem Laser des Eigenen (alle Objekte sind natürlich als Sprites dargestellt) getroffen wurde. So kann man schnell feststellen, welche Sprites miteinander kollidierten und eine Entscheidung tref- fen, ob das Raumschiff nun sprchwörtlich explodieren soll, oder ob es doch eine andere Kollision war, bei der ein ande- res Ereignis eintritt. Eines müssen wir jedoch hierbei immer beachten. VIC löscht die Register die eine Kollision anzeigen nicht wieder von alleine. Diese Aufgabe bleibt uns über- lassen. Demnach sollte man nach dem obligatorischen Einlesen eines Kolli- sionsregisters mit:
A=PEEK(V+30) und/oder B=PEEK(V+31)
es wieder löschen, in dem man in diese Register wieder den Wert 0 hineinPOKEd, so daß alle Bits wieder gelöscht sind, und neue Kollisionen vernünftig festge- stellt werden können. Jedoch sollten Sie vorher sichergehen, daß Sie die beiden Sprites (oder Sprite und Hintergrund) wieder auseinander gebracht haben, denn solange sie noch in Kontakt miteinanan- der stehen, setzt VIC die Kollisionsre- gister immer wieder neu. Deshalb könnte er mehrmals ein- und dieselbe Kollision anzeigen! Auch hierzu ein Beispielpro- gramm auf der Rückseite dieser MD. Es heißt "SPR-KOLLISION". So, nun sind wir mit der Spriteprogram- mierung durch. Ich habe Ihnen jetzt al- les über Sprites erzählt, was es da zu erzählen gibt. Nächsten Monat wollen wir uns dann endlich um die geheimnisvolle Grafikprogrammierung kümmern. Bis dahin viel Spaß beim "spriten". (ub)
Grafikkurs: "Picasso und all die an- dern..." (Teil 3) ----------------------------------------
Willkommen zum dritten Teil des Grafik- kurses. Nachdem wir ja nun die Sprites abgehandelt hätten, können wir uns die- sen Monat nun endlich an die oft begehr- te Programmierung der HIRES-Grafik ma- chen. Auch dies ist ein relativ komple- xes Thema, obwohl wir diesmal nicht all- zu vielen in Registern "herumpoken" müs- sen, als bei den Sprites. Das kompli- zierte 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 mitt- lerweile 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 320x200 Punkten, oder Pixels, wie man sie auch oft nennt. Dieses Feld von Punkten wird vom Bildschirmrand einge- rahmt. Das heißt also, daß wir mit Hilfe des HIRES-Modus des C64 jeden einzelnen Punkt auf dem Bildschirm seperat ans- teuern 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 64ers, 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 dividie- ren 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 64ers 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 Kurstei- len haben wir ja noch Speicherplatz ge- funden, aber 8000 Bytes sind nicht mehr so einfach dazischenzumogeln. Der ganze Speicher des 64ers ist ja schon komplett für andere spezifische Aufgaben reser- viert. Woher also nehmen, wenn nicht stehlen? Genau das werden wir jetzt aber tun müssen! Wir werden uns etwas Spei- cher von unserem 64er "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 Speicher- stellen für sich reserviert, in dem es sich einige Zwischenergebnisse und Hin- tergrundinformationen "merkt". Dort be- finden sich auch zwei kleine Speicher- zellen, die ihm die Startadresse des Basicspeichers angeben. In der Fachspra- che nennt man so etwas "Pointer", oder auch "Zeiger" (ähnlich wie die Sprite- zeiger bei Sprites). Nomalerweise liegt- der 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 reser- vieren. Aber Vorsicht! Wie bei den Spri- tes auch können wir uns da nicht jeden X-beliebigen Speicherberech rausgreifen. Hiresgrafiken dürfen nämlich grundsätz- lich 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. Be- reich 0 können wir ja vergessen, hier sind ja wieder vorreserviete Funktionen angelegt, die man tunlichst in Ruhe las- sen sollte. Soviel hierzu. Jetzt zu den Bereichen 2 bis 7. Diese sind ja eigent- lich 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 ein- facher geht, ist es meist sinnvoller das Ganze in Assembler zu versuchen (zu die- sem Zweck können Sie ja einmal in den Assemblerkurs reinschauen, der seit Ja- nuar parallel zu meinem hier läuft - eine echte Gelegenheit für Basicprofis noch tiefer in die Materie einzustei- gen), 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 erreich- bar. Also dann wollen wir einmal den Basic- speicheranfang etwas höher setzen. Die beiden Speicherstellen die ich eben erwähnte belegen die Adressen 43 und 44. Der 64er hat ja insgesamt 65535 Spei- cherstellen, was der 16-Bit-Zahl "1111111111111111" (16 mal "Bit ge- setzt") entspricht. Um eine Adresse in- nerhalb 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 LOW- und in Adresse 44 das HIGH-Byte des Basicanfangs gespeichert. Lesen wir doch einfach einmal diese bei- den Bytes aus, also:
PRINT PEEK(43),PEEK(44)
Auf dem Bildschirm sollten jetzt die beiden Zahlen: 1 8 stehen. 1 wäre also dann der Wert des LOW-Bytes und 8 der des HIGH-Bytes. Set- zen wir uns also unsere 16-Bit-Zahl aus diesen beiden Bytes zusammen. Das höher- wertige Byte kommt beim Schreiben der Binärzahl nach "oben" also nach links, das niederwertige nach "untern" bezie- hungsweise 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 norma- lerweise beginnen sollte! Doch keine Angst, es stimmt schon so, denn das Be- triebssystem möchte mämlich hier die "wahre" Anfangsadresse des Basicspei- chers plus 1 stehen haben. Das 0. Byte dieses Bereichs wird noch zu einem ande- ren Zweck benutzt, wie wir gleich noch sehen werden. Möchten wir also bei- spielsweise den Anfang des Basicspei- chers nach Adresse 20000 verschieben, so müßten wir hier die Adresse 20001 ange- ben! Ok? Zugegeben, das Prozedere, eine Adresse zuerst einmal als Binärzahl zu schrei- ben, um sie dann in zwei Bytewerte umzu- rechnen ist relativ umständlich, deshalb möchte ich Ihnen hier noch einen einfa- cherern 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 256fachen 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 er- mitteln 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 Er- gebnis von dem absoluten (Anfangs-)Wert subtrahieren. Das hört sich vielleicht komplizierter an als es ist, der Ein- fachheit 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 LOW- und 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 wol- len, der sich ja von 8192 bis 16191 er- streckt. Lassen wir also den neuen Ba- sicspeicher 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 er- streckte 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 Starta- dresse liegen. Zuerst müssen noch eine 1 hinzuaddieren, bevor wir die Zahl in HIGH- und LOW umrechnen können (Sie erinnern sich - in 43/44 muß die gewoll- te 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 Basicspei- chers (bei uns das Byte mit der Adresse 16192). Dieses dient quasi als "Kennmar- ke" für unseren 64er, daß hier der Ba- sicspeicher 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! Des- halb also immer auch eine 0 in das null- te Byte des neuen Basicanfangs schrei- ben, 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 ver- schoben, und der Bereich von 2048 bis 16191 geschützt, er kann von nun an also nicht mehr von BASIC-Programmen über- schrieben 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 64er doch noch was daraus zu machen, was natürlich in einem riesi- gen 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 aller- dings bitte darauf, daß Sie dieses unbe- dingt mit einem ",8" abspeichern und vor allem laden und nicht etwa mit ",8,1", denn dann wird das Programm nämlich ab- solut geladen. Wenn Sie es also abge- speichert 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 Basic- speicheranfang, in unserem Fall also 16192! Im Öbrigen können Sie sich möglicherwei- se noch erinnern, daß ich bei den Spri- tes 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 Basic- speicher 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 ans- prechen müssen, um endlich mit dem Gra- fikbildschirm arbeiten zu können, werde ich Ihnen dann nächsten Monat erklären. Bis dahin "Gut Hack" und Servus.
(ub)
Grafikkurs : "Picasso und all die an- dern..."(Teil 4) ----------------------------------------
Hallo zusammen! Nach dem "Vorgeplänkel" von letzter Woche wollen wir uns jetzt an die "richtige" HIRES-Programmierung machen. Diesmal gehts also ums ganze, deshalb aufgepaßt - und los gehts... Sie erinnern sich: letzte Woche hatten wir uns den Speicherbereich von 2048 bis 16192 gesichert, um dort eine Grafik unterbringen zu können. Genauer gesagt, brauchen wir ja nur den Bereich von 8192 bis 16192 für die Grafik, aber wie ich ja schon das letzte Mal erwähnte, können wir den restlichen Bereich ja auch für andere Zwecke benutzen, zum Beispiel um dort Sprites unterzubringen... Doch nun zur HIRES-Grafik. Zunächst ein- mal grundlegendes zum Aufbau einer HI- RES-Grafik. Bei den Sprites haben Sie ja gelernt, wie der Aufbau einer solchen kleinen Grafik aussieht. Wir hatten da 21 Zeilen zu je 3*8 Bits, die wir ja zeilenweise ansprechen konnten (in der ersten Zeile waren die ersten 3 Bytes untergebracht, in der zweiten die näch- sten 3 und so weiter...). Leider kann man dieses Verfahren nicht mehr so ein- fach auf die HIRES-Grafik übertragen. Sie möchte anders behandelt werden, näm- lich nicht nur zeilen- sondern auch spaltenweise! Das hört sich ziemlich kompliziert an, ist es aber gar nicht, wenn man sich das einmal bildlich klar- gemacht hat. Deshalb erst einmal eine Grafik zur Erklärung. Bitte Teil 2 laden!
Grafik-Kurs Teil 4b Zunächst einmal können Sie erkennen, daß das erste Byte unserer Grafik für die ersten 8 Punkte in der linken oberen Ecke steht. Das zweite Byte ist nun aber nicht NEBEN dem ersten (so wie bei den Sprites), sondern UNTER ihm. Die ersten 8 Punkte der zweiten Zeile werden also vom zweiten Byte dargestellt. Ebenso mit dem dritten Byte, und so weiter. Bis zum Achten. Dieses ist das letzte Byte in diesem 8x8 Pixel-Stück, denn das neunte Byte steht nun nicht mehr UNTER sondern NEBEN den bisherigen, genauer gesagt neben dem ersten Byte. Es repräsentiert somit also die Punkte 9 bis 16 der er- sten Zeile... Auch in diesem 8x8-Pixel-Block sind die Bytes in ihrer Reihenfolge, so wie sie im Speicher hintereinander vorkommen untereinander angeordnet. Auch hier nur die nächsten 8 Bytes. Dann erfolgt wie- der ein Sprung in die erste Zeile - das nächste Byte stellt hier dann die Punkte 17 bis 24 im dritten 8x8-Pixel-Block dar und so fort. Bis wir dann am vierzigsten und letzten 8x8-Block angekommen sind. Die Bytes 8504 bis 8511 stellen hier die Punkte 313 bis 320 der ersten 8 Zeilen dar. Die erste Bildschirmzeile (8 einzelne Zeilen beinhaltend) hätten wir somit abgehandelt, und wie Sie sich jetzt den- ken können wird das nun folgende Byte 8512 das erste Byte in der zweiten Bild- schirmzeile sein. Es ist nun also für Zeile 9 zuständig; das nächste (8513) für die 10. Zeile und so weiter. Auch hier haben wir 8x8-Pixel-Blöcke, nur daß diese jetzt die Zeilen 9 bis 16 mit Bilddaten versorgen. Ebenso mit der nächsten Zeile und so fort. Demnach kann man einen Grafikbildschirm in 25 Zeilen mal 40 8x8-Pixel-Blöcke aufteilen! Zum Besseren Verständnis auch diesmal noch eine Grafik. Bitte Teil 3 laden!
Grafik-Kurs Teil 4c Sollten Sie jetzt immer noch nicht durch dieses recht komplizierte System des Grafikaufbaus durchgestiegen sein, so macht das auch nichts. Gleich werden wir lernen, wie der Grafikbildschirm ein- und ausgeschaltet wird. Wenn Sie das einmal können (und das ist sehr ein- fach), dann können Sie ja einmal ein wenig herumexperimentieren - nur Öbung macht halt den Meister... Doch nun zu den begehrten Befehlen, um den Grafikbildschirm einzuschalten. Wie- dereinmal handelt es sich hierbei um ein paar POKEs, mit denen wir einige Regi- ster im VIC verändern, so daß der uns die Grafik dann darstellt. Zum Einen brauchen wir hierfür das Steuerregister 1, in Register 17 des VIC. Neben einigen anderen Dingen (zu denen wir später, beim Zeichensatz kom- men) können wir hier nämlich den Grafik- modus einschalten. Bit 5 dieses Regi- sters ist hierfür zuständig. Ist es gelöscht (=Binär 0), so ist der Grafik- modus aus-, ist es gesetzt (=Binär 1) so ist er eingeschaltet. Demnach müssen wir es einfach mit Hilfe des OR-Operators setzen (sie erinnern sich an den Anfang dieses Kurses...) - Bit 5 hat den dezi- malwert 32, also:
POKE V+17,PEEK(V+17) OR 32
Analog müssen wir es zum Ausschalten wieder löschen. Dies geht entweder, in- dem man direkt das Komplement von 32 bildet (255-32=223) und es dann mit Hil- fe des AND-Operators mit Register 17 verknüpft; oder man kombiniert ganz ein- fach AND mit NOT (das hatten wir auch schon), was ja dasselbe ergibt, also: POKE V+17,PEEK(V+17) AND 223 oder auch:
POKE V+17,PEEK(V+17) AND NOT 32
Alle POKE-Befehle, die ich eben nannte müssen natürlich die Voraussetzung erfüllen, daß Sie vorher die Variable "V" mit der Basisadresse des VIC initia- lisiert (also: V=53248) haben - das hat- ten wir ja auch schon im ersten Teil des Grafikkurses. Soviel zum Einschalten des Grafikbild- schirms. Doch das ist leider noch nicht alles. Um nämlich wirklich den Speicher- bereich von 8192 bis 16191 auf dem Bild- schirm zu sehen, müssen wir dem VIC noch eine weitere Information geben. Diese ist in seinem 24. Register beinhaltet. Bit 3 in diesem Register gibt ihm unter anderem (nämlich dann, wenn der Grafik- modus eingeschaltet ist - im Normalmodus hat es wieder eine andere Funktion zu der wir ebenfalls später kommen werden) an, welcher Speicherbereich als HIRES- Grafik dargestellt werden soll. Ist es gelöscht (und das ist im normalerweise der Fall), so heißt das für den Grafik- chip unseres 64ers, daß er den Speicher- bereich von 0 bis 7999 als HIRES-Grafik darstellen soll. Damit wir aber auch den zweiten Grafikbereich von 8192 bis 16191 (denn diesen Bereich nutzen wir ja) se- hen können, müssen wir das 3. Bit im Register 24 setzen. Dann zeigt uns VIC nämlich diesen Bereich an. Auch dies geht mit dem OR-Operator, nämlich so:
POKE V+24,PEEK(V+24) OR 8
Beim Ausschalten des Grafikmodus müssen wir neben der Grafik-Ausschalt-Anweisung von oben ebenfalls dieses Bit wieder löschen, sonst zeigt VIC keine Buchsta- ben mehr auf dem Bildschirm an (das hat etwas mit der schon erwähnten zweiten Funktion des 3. Bits zu tun). Zum Aus- schalten schreiben wir also: POKE V+24,PEEK(V+24) AND 247 oder einfacher:
POKE V+24,PEEK(V+24) AND NOT 8
So. Nun können Sie endlich den Grafikmo- dus des VIC aktivieren. Sie sollten jetzt - bei frisch eingeschaltetem 64er - einen Haufen wirre Punkte auf dem Bildschirm sehen. Falls Sie übrigens vorher irgendein Spiel, oder Grafikpro- gramm geladen hatten (und mit einem RE- SET ausgestiegen sind - ohne den Rechner also abzuschalten), so kann es sein, daß sie sogar eine Titelgrafik oder ähnli- ches hier entdecken können. Das liegt dann einfach daran, daß das vorherige Programm seine Grafik auch hier abgelegt hatte. Wie dem auch sei, nun können Sie also DIREKT auf die Grafik zugreifen (geht vorher natürlich auch, nur daß Sie dann noch keine Veränderungen auf dem Bild- schirm sehen). Sie sehen nun die Bytes von 8192 bis 16191 auf dem Bildschirm grafisch dargestellt. Schreiben Sie doch einfach mal mittels POKE einen Wert in Byte 8192. Wenn Sie nicht zufällig den- selben Wert benutzten, der hier schon beinhaltet war, dann sollten Sie erken- nen, daß sich in der Ecke links oben, in der ersten Zeile etwas verändert hat, als Sie die RETURN-Taste zur Ausführung des POKE-Befehls drückten. Öbrigens: sollten Sie auf dem Bildschirm außer den Grafikpunkten auch noch dicke Farbige Quadrate sehen, oder sollten die einzelnen Punkte der Grafik verschiedene Farben aufweisen, so liegt das daran, daß der normale Bildschirmspeicher (hierzu später), in dem die ganzen Buch- staben gespeichert sind, die Sie im Nor- malmodus sehen, im Grafikmodus als Farb- speicher für die einzelnen Punkte fun- giert. Löschen Sie doch einfach einmal den Bildschirmspeicher mit SHIFT- CLR/HOME. Jetzt sollten Sie alle Grafik- punkte in der selben Farbe sehen. Wenn Sie jetzt einmal ein paar Worte einge- ben, so werden Sie einen Farbzug sehen, der sich mit dem Tippen eines Buchsta- bens um 8 Punkte verlängert - obwohl Sie die getippten Buchstaben nicht sehen... Zur Erklärung dieses Phenomens, muß ich etwas tiefer in die Kiste greifen, und möchte Sie bitten, den Grafikmodus no- cheinmal auszuschalten. Kommen wir zum Bildschirmspeicher. Ich hatte diesen ja schon unzählige Male bei Speicherbereichsauflistungen erwähnt. Dabei sagte ich, daß sich dieser ominöse Speicher von Adresse 1024 bis 2023 er- streckt. Das sind genau 1000 Bytes (zählt man von 0 an!). Wie Sie sicher wissen, oder auch leicht feststellen können, ist der Textbildschirm in 25 Zeilen zu je 40 Spalten aufgeteilt (huch! das war doch eben schon eimal der Fall... so ein Zufall aber auch). 25*40 ergibt genau 1000. Sie können auf dem Bildschirm also 1000 Zeichen gleichzei- tig darstellen. Klingelts bei Ihnen? Genau! Jede Speicherstelle des Bild- schirmspeichers repräsentiert eine ganz bestimmte Stelle (durch Zeile und Spalte definiert) des Bildschirms, in der ein Bytewert gespeichert ist, der den VIC dazu veranlasst ein ganz bestimmtes Zei- chen auf dem Bildschirm darzustellen. Er überprüft in regelmäßigen Abständen, was in diesem Speicherbereich an Daten abge- speichert ist und stellt diese auf dem Bildschirm in Form von Buchstaben (oder Grafikzeichen) dar. Schreiben Sie doch einmal den Wert 1 in die Speicherstelle 1024. Jetzt sollten Sie den Buchstaben "A" links oben auf dem Bildschirm sehen. Probieren Sie doch einmal verschiedene Werte durch, Sie werden dann die ver- schiedensten Zeichen auf dem Bildschirm sehen. Zur Demonstation habe ich Ihnen diesmal ein kleines Programm auf der Rückseite der MagicDisk abgespeichert, das Ihnen alle Zeichen des 64ers auf dem Bildschirm ausdruckt. Es heißt "SHOW- CHARS.GK und arbeitet nach der Methode, daß es nacheinander die Werte von 0 bis 255 in den Bildschirmspeicher schreibt. Zum Aufbau bleibt noch zu sagen, daß wir diesmal wieder zeilenweise arbeiten dür- fen (puuh - also nich son komplizierter Kram wie eben). Die ersten 40 Bytes des Bildschirmspeichers (1024-1064) sind also für die erste Zeile, die nächsten 40 (1064-1104) für die zweite Zeile (usw.) zuständig. Experimentieren Sie doch einfach einmal, indem Sie in die Speicherstellen von 1024 bis 2023 ver- schiedene Werte schreiben... Jetzt wissen Sie auch, wie die Buchsta- ben von den Tasten Ihrer Tastatur auf den Bildschirm kommen. Intern fragt das Betriebssystem nämlich ständig die Ta- statur ab, ob Sie nicht gerade eine Ta- ste gedrückt haben. Ist dies der Fall, so sucht es sich den entsprechenden "Bildschirmcode" (so heißen nämlich die Zahlen mit den dazugehörigen Zeichen - ähnlich wie beim ASCII-Code) der Taste aus einer Tabelle heraus und schreibt diesen in den Bildschirmspeicher, von wo aus ihn der VIC wieder in ein Videosig- nal für Fernseher oder Monitor umsetzt, so daß er schließlich und endlich auf selbigem erscheint... Doch kehren wir von den Interna des 64ers zurück zu unserer Grafik: Der Bildschirmspeicher dient also norma- lerweise zur Darstellung der Buchstaben auf dem Bildschirm. Im HIRES-Grafikmodus sehen wir diese jedoch eh nicht, die Grafik ist ja eingeschaltet. Bevor jetzt also ganze 1000 Bytes im Speicher des 64ers brach liegen benutzt VIC sie dazu, den Punkten im Grafikmodus eine Farbe zu geben (sieht doch viel besser aus!). Jede Speicherstelle des Bildschirmspei- chers kann nun genutzt werden, um einem 8x8-Pixel-Block gewisse Farbinformatio- nen zu geben (aha! also doch kein Zufall mit den 25x40 Zeichen...). Hierbei bleibt die Zeilen-Spalten-Struktur des Bildschirmspeichers voll und ganz erhal- ten! Die eigentliche Farbinformation in einem solchen 8x8-Pixel-Block teilt sich nun in 2 Komponenten, nämlich in Vorder- und Hintergrundfarbe, auf. Wie Sie ja wis- sen, kann der 64er insgesamt 16 ver- schiedene Farben darstellen. Demnach brauchen wir maximal 4 Bits (2↑4=16) um alle verschiedenen Farben darstellen zu können. Da uns in einem Byte allerdings 8 Bit zur Verfügung stehen, können wir also quasi 2 verschiedene Farbwerte in ein Byte "packen". Und genauso wird das gehandhabt. Der Farbwert für die Hinter- grundfarbe wird in den Bits 0-3 untege- bracht, der für die Vordergrundfarbe in den Bits 4-7. Zunächst jedoch noch ein- mal die Farbtabelle (ich hatte sie auch schon einmal bei den Sprites aufgeli- stet), damit Sie die Farbwerte auch wie- der im Kopf haben:
Wert Farbe Wert Farbe ----------------------------------------
0 Schwarz 8 Orange 1 Weiß 9 Braun 2 Rot 10 Hellrot 3 Türkis 11 Dunkelgrau 4 Violett 12 Mittelgrau 5 Grün 13 Hellgrün 6 Blau 14 Hellblau 7 Gelb 15 Hellgrau
Um nun beispielsweise die Hintergrund- farbe auf "Grün" und die Vordergrundfar- be auf "Braun" zu setzen, müssen wir die Farbwerte ins Binärsystem übersetzen, und sie in 8-Bit-Schreibweise aneinander hängen, also: Vordergrund = dez. 9 = bin. 1001 Hintergrund = dez. 5 = bin. 0101 --> (bin.) 10010101 = (dez.) 149 Oder Sie rechnen den Wert einfach so um, daß sie den Farbwert der Vordergrundfar- be (in den "höherwertigen" Bits 4-7) mit 16 multiplizieren und den Hintergrund- farbwert einfach hinzuaddieren (auch dies hatten wir schon an früherer Stel- le): 16*9+5=149 Schreiben Sie nun diesen Wert in die erste Speicherstelle des Bildschirmspei- chers (nämlich...na?...richtig! - 1024), so werden im ersten 8x8-Pixel-Block alle gesetzten Punkte in braun erscheinen, und alle nicht gesetzten in grün. Die Hintergrundfarbe aus Register 32 (aus dem ersten Teil des Grafikkurses) gilt hier nicht mehr! Alle Punkte, die also nicht gesetzt sind (=Binär 0) erhalten ihre Farbinformation jetzt aus den Bits 0-3 und alle gesetzten aus den Bits 4-7 der entsprechenden Bildschirmspeicher- zelle. Soviel zur Farbgebung der Grafik. Kommen wir nun noch einmal zurück zu den ein- zelnen Bildpunkten auf dem Bildschirm. Nachdem Sie jetzt ja wissen sollten, woher die dicken Farbkleckse herkommen, wollen wir uns noch einmal um den Aufbau des Bildschirms kümmern. Als letztes Beispiel, damit Sie diesen vielleicht etwas besser verstehen, möchte ich Ihnen jetzt zeigen, wie man den Grafikbild- schirm löscht, denn die wirren Punkte da kann man ja unmöglich als ansehliche Grafik bezeichnen. Um also Ordnung zu schaffen, müssen wir den Bildschirm erst einmal löschen. Dieser Vorgang ist denk- bar einfach: wir schreiben mit Hilfe einer FOR-NEXT-Schleife ganz einfach in die 8000 Datenbytes unserer Grafik (von 8192 bis 16191) den Wert 0 (das ist ja binär 0000 0000, wobei dann ja keine Punkte mehr auf der Grafikseite gesetzt sind!). Also:
FOR I=0 TO 7999:POKE 8192+I,0:NEXT
Das wärs schon. Natürlich wäre diese ganze Sache in Assembler besser geeig- net, zumal diese Schleife (in BASIC) schon eine geraume Zeit braucht, bis sie vollends abgelaufen ist. Doch das ist momentan gar nicht mal so schlimm, denn so können Sie bildlich sehr gut sehen, wie der Grafikbildschirm aufgebaut ist. Starten Sie doch einfach einmal das Pro- gramm "CLRGRAPH.BK" auf der Vorderseite dieser MD. Es tut nichts anderes, als den Grafikbildschirm einzuschalten und ihn dann zu löschen. Sie werden sehen, daß die Bytes nach und nach in den 0- Status springen. Hierbei "läuft" quasi ein unsichtbarer Radiergummi über den Bildschirm, und Sie werden sehen, daß alle 8x8-Pixel wieder die nächsten 8x8- Pixel gelöscht werden und so fort... Ich hoffe, daß Sie dieses Problem nun endlich abhaken können (sollten Sie es noch nicht verstanden haben). Deshalb kommen wir gleich noch zu einer weiteren Spezialität der Grafik. Man kann nämlich - genau wie bei den Sprites - auch hier den "Multicolormodus" einschalten. Auch hier funktioniert das etwa ähnlich wie bei den Sprites, zwei Bildpunkte werden nämlich zu EINEM zusammengefaßt, deren Gesamtinformation dann mit der Farbge- bung zusammenhängt. Sollten Sie nicht mehr so genau wissen, was ich damit mei- ne, dann sollten Sie noch einmal einen Blick in den zweiten Teil des Grafikkur- ses - MD64, Ausgabe 1/90 - werfen, dort steht alles noch einmal genau erklärt, nur halt im Rahmen der Spriteprogrammie- rung. Wie auch bei den Sprites geben hier die einzelnen Bitkombinationen dem VIC an, welche Farbe er einsetzen soll. Hier die vier möglichen Bitmuster und deren Farb- quellen:
Bitmuster Farbquelle ----------------------------------------
00 Hintergrundregister (53280) 01 Highnibble Bildschirmspeicher 10 Lownibble Bildschirmspeicher 11 Farbram Zunächst einmal zu den ersten 3 Einträ- gen dieser Liste. Im Multicolormodus ist, wie man sieht, das Hintergrundfar- bregister des VIC (Nr. 32 --> 53280) wieder von Bedeutung. Bei allen nicht- gesetzten Punkten "scheint" diese Farbe also durch. Nun zu dem Begriff "Nibble". Dies ist der Fachausdruck für ein halbes Byte, oder auch vier Bit. Mit "Lownibble" ist ganz einfach das "niederwertige" (Bits 0-3) Nibble und mit "Highnibble" das "höherwertige" (Bits 4-7) gemeint. Und zwar jeweils des Bytes der dazugehörigen Adresse des Bildschirmspeichers, also ähnlich wie bei der normalen 2-Farb- Grafikdarstellung. Jetzt zum vierten Eintrag der Bitmuster- liste. Wenn die beiden Informationsge- benden Bits in der Grafikseite auf "11" stehen (also beide gesetzt), dann wird die Farbinformation aus dem sogenannten Farbram (oder englisch auch "Colorram") geholt. Doch was heißt das eigentlich. Auch hier muß ich etwas weiter ausholen. Wie Sie ja wissen, kann jeder Buchstabe auf dem Bildschirm eine von 16 verschiedenen Farben annehmen. Drücken Sie doch einmal die Tastenkombination CTRL-1 - schon ist der Cursor schwarz und alle mit ihm ge- schriebenen Buchstaben ebenfalls. Schal- ten Sie jetzt eine andere Farbe ein (z.B. Weiß, mit CTRL-2), so wird alles was sie nun eingeben in der Farbe Weiß dargestellt. Sie haben jetzt also schon 2 verschiedenfarbige Buchstabengruppen auf dem Bildschirm. Das Spiel können Sie auch gerne weitertreiben, bis wir alle Regenbogenfarben da so rumschillern ha- ben. Klingelts bei Ihnen? Vorhin hatten wir doch gelernt, daß jeder Buchstabe, den wir auf dem Bildschirm sehen im Bildschirmspeicher untergebracht ist. Wenn jetzt aber jeder Buchstabe eine andere Farbe annehmen kann, so ist die logische Schlußfolgerung, daß es da noch irgendwo einen weiteren Speicher geben muß, in dem diese Farbinformation ge- speichert ist. Und genau das ist der Fall! Das Ganze nennt sich (wie oben schon erwähnt) Farbram, und besteht ebenfalls aus 1000 Bytes. Es erstreckt sich von Adresse 55296 bis 56319 und liegt somit im Ein-/Ausgabebereich des Speichers. Der Rest ist schnell gesagt, denn es ist vom Aufbau haargenau identisch mit dem Bildschirmspeicher nur daß es halt an einer anderen Adresse liegt als dieser, und daß es für die Farbgebung der Zei- chen auf dem Bildschirm zuständig ist. Wenn Sie also die (beispielsweise) 31. Stelle des Farbrams (55296+31=55327) mit einem Farbwert aus der, mittlerweile schon altbekannten, Farbtabelle von 16 Farbwerten beschreiben, so erscheint der 31. Buchstabe des Bildschirmspeichers (1024+31=1055) in eben dieser Farbe. Nun verstehen Sie also auch den Zusam- menhang mit der Multicolorgrafik. Der Farbwert, der im Farbram gespeichert ist, ist maßgebend für alle "11" kombi- nationen in dem 8x8-Pixel-Block, für den er zuständig ist (ebenso wie Low- und Highnibble des Bildschirmspeichers). Jetzt noch zum Einschalten des Multico- lor-Grafikbildschirms. Diesmal müssen wir ebenfalls lediglich ein Bit eines VIC-Registers setzen, um ihn zu veran- lassen, die Grafikinformationen in der Multicolorweise darzustellen. Genau ge- sagt handelt es sich um Bit 4 des Regi- sters 22 (Adresse 53270). Die enspre- chenden Befehle zum Ein- und Ausschalten lauten demnach: POKE V+22,PEEK(V+22) OR 16 (--> zum Einschalten)
POKE V+22,PEEK(V+22) AND NOT 16
(--> zum Ausschalten) Vorausgestzt natürlich, daß die Variable "V" die Basisadresse des VICs enthält (53248)! So. Das wärs dann für diesen Monat. Ex- perimentieren Sie doch einfach einmal ein wenig mit dem Grafikbildschirm des 64ers herum, denn nur so erhalten Sie die routinemäßige Erfahrung, wie man mit Ihm umgeht... Ich verabschiede mich dann bis nächsten Monat, wenn wir uns dann mit der Zei- chensatzprogrammierung auseinandersetzen wollen, bis dahin Servus,
Ihr Uli Basters (ub)
Grafikkurs: "Picasso und all die an- dern..." (Teil 5) ----------------------------------------
Grüetzi mitrnand (um an die DB anzuleh- nen) und herzlich willkommen zum fünften Teil unseres Grafikkurses. Nachdem wir die letzten Monate ja schon die Sprites und den Grafikbildschirm abgehandelt haben, werden wir uns nun dem dritten und letzen Teil der Grafikprogrammierung unseres 64ers widmen, der Zeichensatz- programmierung. Vielleicht werden Sie jetzt fragen: "Wieso Zeichensatzprogrammierung? Mit den schrägen Zeichen auf der Tastatur läßt sich doch eh nicht viel anfangen. Das kommt doch alles viel zu klotzig und plump!". Na da haben Sie sich aber ge- schnitten. Ich möchte mich hier ja auch nicht über die Blockgrafik durch die Sonderzeichen des C64 auslassen, sondern vielmehr darüber, wie man diese in eine ansehbare Form bringt. Man kann nämlich die Zeichen, die Sie sonst so auf dem Bildschirm rumfliegen auch beliebig verändern. Sie könnten zum Beispiel ganz "buchstäblich" aus einem "X" ein "U" machen! Die Veränderung des Zeichensat- zes ist sogar derart flexibel, daß man unter Umständen ganze HIRES- und Multi- colorgrafikbildschirme in einem Zeichen- satz unterbringen kann, um so eine Gra- fik zu "simulieren". Das hat manchmal so seine Vorteile. Beispielsweise der, daß ein Zeichensatz mit weniger Rechenauf- wand animiert werden kann, als eine Gra- fikseite. Als Beispiel ist hier vorzü- glich der große "MAGIC DISK 64"- Schriftzug in der Intro einer jeden MD geeignet. Das hoch- und runterwackeln dieses Grafikobjektes ist als Grafik- bildschirm nur schwer, wenn überhaupt gar nicht, so flüssig und schnell wie hier zu realisieren. 40 Zeichen umkopie- ren geht halt schneller, als 320 Da- tenbytes (soviele Bytes sind nämlich in 40 Zeichen untergebracht). Doch bevor ich Sie jetzt möglicherweise mit Dingen verwirre, von denen Sie noch nichts verstehen, möchte ich dieses The- ma etwas weiter nach Hinten verschieben. Zunächst einmal zu den "elementaren" Grundlagen der Zeichensatzprogrammie- rung. Zunächst einmal wollen wir die Frage klären, wo die Zeichen auf dem Bildschirm eigentlich herkommen. Letzten Monat hatte ich ja schon einmal vom Bildschirmspeicher gesprochen. Wir hat- ten damals geklärt, daß dieser Speicher- bereich von Adresse 1024 bis 2023 zuständig dafür ist, welches Zeichen wo auf dem Bildschirm zu stehen hat. Hier- bei gab es für jedes der 256 Zeichen des 64ers einen bestimmten Wert, der reprä- sentativ für ein Zeichen war. Dies war der sogenannte Bildschirmcode. Der Code 1 zum Beispiel stand für das "A". Ich hatte damals auch gesagt, daß der VIC bei der Zeichendarstellung jede Adresse des Bildschirmspeichers untersucht, wel- cher Code darin steht und dann das ent- sprechende Zeichen in ein Monitor- oder Fernsehsignal umwandelt, damit wir es auch auf dem Bildschirm sehen können. Doch woher soll er wissen wie denn nun das "A", oder die Buchstaben die Sie gerade lesen eigentlich aussehen sollen; daß ein "W" so aussieht wie ein umge- drehtes "M" und so weiter. Nun diese Informationen müssen natürlich wie al- les, was mit Grafik zu tun hat irgendwo in unserem 64er als Zeichendaten gespei- chert sein, und genau das ist auch der Fall. Doch wo im Speicher befinden sich denn nun die Zeichensatzdaten? Nun diese Frage ist nicht einfach zu erklären. Hierzu muß ich wieder einmal etwas wei- ter ausholen und Ihnen den genauen Spei- cheraufbau des 64ers erklären. Ich hatte ja schon einmal im Basickurs darüber gesprochen, wobei ich jedoch lediglich erwähnte, daß es insgesamt 65536 Spei- cherzellen innerhalb des C64 gibt, die alle mit einer entsprechenden Adresse angesprochen werden können. In Wirklich- keit gibt es aber weitaus mehr (nämlich so um die 90000!), nur sind diese nicht immer für den Prozessor, das Herzstück unserer Maschine, "zu sehen". Die ver- schiedenen Bereiche werden vielmehr in das "Sichtfeld" des Prozessors "einge- spiegelt", wenn sie benötigt werden. Man könnte sich den Speicher des 64er auch als ein Hochhaus mit mehreren Stockwer- ken vorstellen. Will der Prozessor ganz bestimmte Daten, so muß er in ein be- stimmtes Stockwerk gehen und sie sich dort abholen. Zur besseren Erläuterung hierzu einmal eine Grafik: Bitte laden Sie den 2. Teil des Kurses.
Grafikkurs Teil 2 ----------------------------------------
Sie sehen, es gibt da einen Bereich, der mit "Zeichensatz-ROM" bezeichnet ist. Und hier liegen auch unsere Zeichenda- ten. Zumindest die, wie wir sie sonst immer so auf dem Bildschirm sehen. Der VIC holt sie sich dirket von dort (der Microprozessor selbst hat also nichts mit dem Vorgang des "Zeichendaten- Holens" zu tun). Für VIC ist der Zei- chensatz also immer sichtbar. Dies auch nur über einen Trick, aber dazu später. Nun, wenn wir den Zeichensatz ändern wollen, dann müssen wir ganz einfach dem VIC andere Zeichendaten zur Verfügung stellen. Wie Sie jedoch wissen sollten, hat das Schreiben von Daten in ROM- Bereiche absolut keine Wirkung (ROM=- "Read Only Memory" zu deutsch "Nur- Lese-Speicher"). Wie können wir dieses Problem also lösen? Nun, der VIC gibt uns die Möglichkeit, in einem seiner Register anzugeben, aus welchem Spei- cherbereich er sich die Zeichendaten holen soll. Im Normalfall steht dieses Register auf "Zeichensatz-ROM", jedoch können wir uns auch einen Bereich im RAM aussuchen. Und genau das wollen wir tun. Bei der HIRES-Grakik-Programmierung hat- ten Sie ja gelernt, wie man sich Spei- cherplatz für große Datenmengen reser- viert (nämlich indem man den Basicanfang verschiebt). Für einen Zeichensatz benö- tigen wir ja 4 KiloByte, also 4096 Bytes (1KB=1024 Bytes!). Einigen wir uns doch auf den Bereich von 8192 bis 12288, dies ist ja ein Teilbereich, in dem wir sonst auch immer die Daten einer HIRES-Grafik abgelegt hatten. Wenn wir den ursprün- glichen Zeichensatz nun also ändern wol- len, müssen wir ihn zunächst aus dem Zeichensatz-ROM in den Bereich von 8192 bis 12288 umkopieren. Hier komme ich nun wieder auf den Spei- cheraufbau des 64ers zurück. Denn jetzt müssen wir ja auf das sonst unsichtbare Zeichensatz-ROM zugreifen können. Zu diesem Zweck möchte ich Sie mit einer der wichtigsten Speicherstellen inner- halb unseres kleinen Freundes bekannt machen, der Speicherstelle 1. Diese hat wegen ihrer Wichtigkeit sogar einen ei- genen Namen, nämlich "Prozessorport". Öber diese Speicherstelle haben wir die Kontrolle über bestimmte Funktionen und Modi des Prozessors des 64ers. Die Bits 0-2 der Speicherstelle 1 sind für die "Speicherkonfiguration" des Rechners verantwortlich. Sie geben an, welche der oben gezeigten Bereiche für den Prozes- sor erreichbar sind, und welche nicht. Zu diesem Zweck gleich nochmal eine Gra- fik: Bitte laden Sie den 3. Teil des Kurses.
Grafikkurs Teil 3 ----------------------------------------
Sie sehen in dieser Grafik, welche der Bitkombinationen welche Speicherauftei- lung bewirkt. Die 3 Zahlen jeweils unter einer Konfiguration geben die Stellung der Bits 0-2 an, die Zahl dahinter, den Dezimalwert, den man im Normalfall mit dieser Kombination in Adresse 1 schrei- ben sollte. Verändern Sie die Bits von 3-7 bitte nicht! Diese haben bestimmte Funktionen, die den Prozessor zu anderen Dingen veranlassen. Bei Veränderungen könnten Sie so den Rechner schnell zum Absturz bringen! Ebenso verhält es sich mit den Kombinationen, die ein Ausblen- den des Betriebssystems oder des BASIC- ROMs bewirken, da wir nämlich von BASIC aus programmieren, braucht der Rechner diese beiden Bereiche! Wenn Sie also verschwinden "verläuft" sich der Rechner im RAM darunter und stürzt ebenfalls ab! Diese Kombinationen werden erst für As- semblerprogrammier interessant, und selbst dann ist Vorsicht geboten beim Abschalten der ROMs. Für uns ist lediglich die Bitkombination "011" sinnvoll. Durch sie können wir nämlich einfach den I/O-Bereich ausblen- den, der dann durch das Zeichensatz-ROM ersetzt wird. Beim Zugriff auf die Adressen 53248-57344 bekommen wir nun also nicht mehr etwa die Werte von VIC, SID und den anderen Ein- /Ausgabebausteinen geliefert, sondern die des Zeichenssatz-ROMs. Wir können nun den gesamten Bereich mittels einer Schleife ins RAM kopieren, wo wir ihn dann verändern werden. Hierzu jedoch noch ein kleiner Hinweis, denn so einfach wird es uns leider doch nicht gemacht. Um wiederum einen mögli- chen Absturz des Rechners zu verhindern müssen wir auch noch den System- Interrupt abschalten. Dies ist eine Ein- richtung des Betriebssystems, die unter anderem macht, daß der Cursor auf dem Bildschirm rumblinkt. Das wiederum hat etwas mit der Bildschirmausgabe zu tun, und die ist ja nun nicht mehr gewährlei- stet, da der Ein-Ausgabebereich des Speichers ja abgeschaltet ist. Der In- terrupt (auch IRQ genannt) würde also versuchen auf die Register des VIC und vor allem auf Register der Ein- /Ausgabebausteine zuzugreifen, die natürlich nicht mehr da sind. Es gäbe ein großes Chaos mit einem Rechnerab- sturz zur Folge. Öber den Interrupt an- sich möchte ich mich hier allerdings nicht auslassen, das soll Aufgabe meines Assemblerkollegen Ralf Trabhardt sein (dessen Kurs Sie ja parallel zu diesem hier auch mitmachen können), ich werde mich darauf beschränken, Ihnen zu zei- gen, wie man den IRQ ein- und ausschal- tet. Dies geht wie immer über den POKE- Befehl. Die entsprechenden Befehle lau- ten:
POKE 56334,PEEK(56334) AND 254 zum einschalten, und POKE 56334,PEEK(56334) OR 1
Nun also zu dem Programm, daß den Zei- chensatz aus dem Zeichensatz-ROM ins RAM von 8192-12288 kopiert. Ich habe es Ih- nen auch als BASIC-Programm auf der Rückseite dieser MD unter dem Namen "COPYCHARSET" abgespeichert:
10 POKE 56334,PEEK(56334) AND 254:REM IRQ AUSSCHALTEN 20 POKE 1,51:REM ZEICHENSATZ EINBLENDEN 30 FOR I=0 4095 40 POKE 8192+I,PEEK(53248+I) 50 NEXT 60 POKE 1,55:REM I/O WIEDER EINBLENDEN 70 POKE 56334,PEEK(56334) OR 1:REM IRQ WIEDER EINSCHALTEN
Lassen Sie das Programm doch einmal lau- fen, nach einiger (sogar sehr langer) Zeit meldet sich der 64er wieder mit "READY." zurück, und der Zeichensatz steht im RAM. Damit Sie nicht solange warten müssen, bis die Kopierschleife durchlaufen ist, habe ich Ihnen auch noch die Assemblerversion von "COPYCHAR- SET" auf der Rückseite unter "COPYCHAR- SET.ASM" gespeichert. Öbrigens auch ein schöner Vergleich zwischen BASIC und Assembler - der Zeichensatz ist mit dem zweiten Programm nämlich in nur wenigen Sekundenbruchteilen umkopiert, anstatt in wenigen Minuten, mit der BASIC- Version! Haben Sie übrigens keine Angst, wenn Sie das BASIC-Programm nicht mit RUN-STOP abbrechen können. Der IRQ fragt nämlich auch ab, ob diese Taste gedrückt wurde und läßt in diesem Fall ein Pro- gramm abbrechen - so hat es den an- schein, als würde der Rechner "schla- fen". Da wir den IRQ jedoch abgeschaltet haben, kann das Programm folglich nicht mehr gestoppt werden, bis es abgelaufen ist. So. Kommen wir nun, nachdem der Zeichen- satz endlich im RAM liegt zu dessen Veränderung. Ein Zeichen, so wie Sie es auf dem Bild- schirm sehen können, ist aus einer Punktmatrix von 8x8-Pixeln aufgebaut. Diese werden durch 8 aufeinanderfolgende Bytes zu je 8 Bit repräsentiert (wie das vor sich geht sollten Sie nun ja mitt- lerweile wissen). In unserem Fall belegt das erste Zeichen des Zeichensatzes die Bytes 8192 bis 8199. Die Daten eines neuen Zeichens müssen also lediglich dort ins RAM geschrieben werden, und schon haben wir ein anderes Zeichen ans- telle des alten auf dem Bildschirm ste- hen. Das heißt noch nicht ganz, denn wir müssen dem VIC ja erst noch mitteilen, daß er sich die Zeichendaten jetzt aus einem anderen Speicherbereich holen soll, als aus dem Zeichensatz-ROM. Dies geht wieder über eines der VIC-Register, genauer gesagt über Register 24. Die Bits 0-3 dieses Registers steuern die Lage des Zeichensatzes, derer es 4 ver- schiedene Möglichkeiten gibt. Hier ein- mal eine Tabelle:
Adressbereich Bitmuster Wert(dez.) ----------------------------------
0- 4095 0001 01 4096- 8191 0101 05 8192-12287 1001 09 12288-16383 1101 13
Für uns ist also der dritte Eintrag die- ser Liste von Bedeutung, denn er adres- siert den Bereich, in dem wir unseren neuen Zeichensatz abgelegt haben. Setzen wir also die unteren vier Bits von Regi- ster 24 einmal auf "1001":
POKE V+24,PEEK(V+24) AND 240 OR 9
Somit wäre also der Zeichensatzgenerator des VIC auf den neuen Bereich einge- stellt. Ich werde Ihnen nachher noch einige Sonderheiten dieses Registers erklären, behalten Sie es also im Auge! Nun jedoch endlich zu der langersehnten Zeichenveränderung. Das erste Zeichen des neuen Zeichensatzes ist der Klamme- raffe " ". Schreiben Sie doch einmal ein solches Zeichen irgendwo auf den Bild- schirm. Jetzt fahren Sie mit dem Cursor an eine Stelle, die noch frei ist und schreiben mittels POKE den Wert 255 in Speicherzelle 8192, also:
POKE 8192,255
Sie werden jetzt sehen, daß unser Klam- meraffe oben deutlich abgeflacht wurde. Verändern Sie auch noch das nächste By- te, so wird er sich immer mehr entstel- len. Probieren Sie was sich so alles damit anstellen läßt. Sie wissen ja mittlerweile, daß jeweils ein Bit einer Speicherstelle einen Punkt in einer Zei- le des Zeichens darstellt. Pro Zeichen haben Sie acht Bytes zur Verfügung, die das Aussehen dieses Zeichens erheblich verändern können. Das zweite Zeichen des Zeichensatzes ist übrigens das "A", wenn Sie also die Speicherstellen von 8200 bis 8207 verändern, so werden Sie alle "A"s auf dem Bildschirm in ihrer Form verändern und so fort. Sie sehen, so ist es leicht möglich, andere Zeichen zu erzeugen, und so entstehen auch die Zei- chensätze, wie sie in manchen Spielen, oder in einem der zahlreichen Demo- Creator-Programme der MagicDisk vorhan- den sind. Nun noch ein wenig über den Aufbau eines Zeichensatzes. Die Zeichen ansich, 256 an der Zahl, sind 8-Byte-Weise hinterei- nander im Speicher abgelegt. Das wissen wir ja schon. Da ein Zeichen 8 Byte be- legt, müßte ein Zeichensatz also 8*256 Bytes lang sein, das sind insgesamt al- lerdings 2048 Bytes und nicht 4096, wie ich vorhin erwähnte (und soviele Daten haben wir ja auch umkopiert). Wie Sie merken ist 4096 genau das doppelte von 2048. Die Erklärung dafür, daß der Zei- chensatz länger ist als er eigentlich sein sollte, liegt darin, daß ein er in der Form, in der er auch im Zeichensatz- ROM vorliegt eigentlich aus ZWEI Zei- chensätzen besteht. Nämlich dem "Groß- schrift"-und dem "Kleinschrift"- Zeichensatz. Normalerweise schalten Sie zwischen diesen beiden Zeichensätzen mit der Tastenkombination "SHIFT-COMMODORE" hin und her. Hierbei können Sie entweder mit Großen Buchstaben und Grafikzeichen schreiben, oder mit kleinen und großen Buchstaben und dafür mit einigen Grafik- zeichen weniger. Probieren Sie es einmal aus: wenn Sie einige Grafikzeichen mit der SHIFT-Buchstabentaste-Kombination auf den Bildschirm bringen und dann auf Kleinschrift umschalten ("SHIFT/C="), dann verwandeln sich die Grafikzeichen in Großbuchstaben und umgekeht. Demnach reichen also 2096 Bytes für einen sicht- baren Zeichensatz aus! Soviel hierzu. Jetzt noch ein Wort zu der Lage von bestimmten Zeichen inner- halb eines Zeichensatzes. Zu diesem Zweck habe ich Ihnen ein weiteres Pro- gramm unter dem Namen "CHARLOC" auf der Rückseite der MD gespeichert. Es zeigt Ihnen an, wo ein Zeichen im Zeichensatz angesiedelt ist, und wie seine Punktma- trix aussieht. Die Zeichen von 0 bis 255 entsprechen hierbei dem "Groß/Grafik"- Zeichensatz, die von 256 bis 511 dem "Kleinschrift"-Zeichensatz. Die Reihen- folge entspricht übrigens der der Bild- schirmcodes, die wir ja schon im letzten Kursteil hatten. Nun möchte ich nocheinmal zu Register 24 des VIC kommen. In diesem kann ja die Lage des darzustellenden Zeichensatzes festgelegt werden. Wir hatten da ja auch den Bereich von 8192-12287 eingestellt, um unsere neuen Zeichen auf den Bild- schirm zu bringen. Was jedoch tun, wenn wir wieder den "alten" ROM-Zeichensatz auf dem Bildschirm haben wollen, der ROM-Bereich von 53248-57334 ist ja nicht dort aufgelistet? Nun, zur Erklärung dieser Frage muß ich wieder auf die Hardware-Grundlagen des 64ers zurück- greifen. Ich hatte Ihnen weiter oben ja schon erläutert, daß der VIC sich den Zeichensatz aus dem Zeichensatz-ROM holt. Der VIC kann nun aber nur einen Bereich von maximal 16 KiloByte adres- sieren (=auf ihn zugreifen) - das ist durch seinen hardwaremäßigen Aufbau so gegeben. Deshalb haben wir übrigens auch immer, wenn wir irgendwo Grafikdaten abgelegt haben, sei das jetzt eine HI- RES-Grafik, oder ein Sprite gewesen, im Bereich von 0 bis 16384 gearbeitet. Es gibt übrigens auch die Möglichkeit die- sen 16K-Bereich des VIC umzuschalten auf folgende 16K-Bereiche, doch hierzu an späterer Stelle mehr. Im Normalfall ar- beitet der VIC also in den ersten 16K des Speichers. Das Zeichensatz-ROM be- findet sich nun aber in den letzten 16K, womit sich ein Problem ergibt - denn wie soll der VIC den auf diesen Bereich zu- greifen können, wenn er nicht in seinem "Einzugsbereich" liegt. Hier wird mit einem kleinen Harwaretrick gearbeitet. Für den VIC wird der ROM-Zeichensatz nämlich immer in den zweiten Zeichen- satz-Bereich eines jeden 16K-Blocks ein- gespiegelt. Aber NUR für den VIC, der Prozessor hat darauf keinen Zugriff. Im Normalfall ist das also der Bereich von 4096 bis 8191. Wenn wir mit PEEK oder POKE an diesen Bereich gehen, erhalten oder verändern wir jedoch nur die Inhal- te der entsprechenden RAM-Adressen an dieser Stelle. Der VIC sieht hier jedoch den ROM-Zeichensatz, weshalb dieser Be- reich nicht dazu geeignet ist einen RAM-Zeichensatz aufzunehmen. VIC wird dann immer den Zeichensatz aus dem ROM holen und sich nicht darum kümmern, was dort im RAM steht. Deshalb ist auch der zweite Eintrag in der Zeichensatzbe- reichsliste von oben repräsentativ für das Zeichensatz-ROM. Schalten wir also diesen Bereich ein, so erhalten wir wie- der den alten ROM-Zeichensatz! Sie kön- nen ihn somit mit folgendem POKE wieder herholen:
POKE V+24,PEEK(V+24) AND 240 OR 5
Soviel also zu diesem Thema. Wenn Sie das mit den 16K nicht so recht verstan- den haben, dann macht das auch nichts. Hauptsache, Sie wissen, wie man den Zei- chensatz wieder in den Grundzustand bringt. Das Thema mit der Adressierung des VICs werden wir nächsten Monat so- wieso nocheinmal genauer behandeln. Befassen Sie sich jetzt erst einmal mit der Änderung des Zeichensatzes selbst, und experimentieren Sie ein wenig. Ich verabschiede mich nämlich jetzt wieder von Ihnen bis nächsten Monat, wenn wir den letzten Teil dieses Kurses durchge- hen möchten, in dem es dann um noch ei- nige Feinheiten der Grafikprogrammierung geht und um die Einzelheiten, was man mit einem gänderten Zeichensatz noch so anstellen kann. Bis dann also, Ihr Uli Basters (ub).
Grafikkurs Teil 6 "Picasso und all die andern..." ----------------------------------------
Hallo zur sechsten und letzten Runde des Grafikkurses. Heute wollen wir diesen Kurs abschließen, indem ich Ihnen zunächst noch ein wenig über die Zei- chensatzprogrammierung erzählen werde und dann noch ein paar kleine Grafiktips geben werde. Fangen wir also an: Letzten Monat hatten wir uns ja mit der Einrichtung eines neuen Zeichensatzes in unserem Rechner beschäftigt. Wo man die- sen im Speicher ablegt, wie man ihn ein- schaltet, und wie man ihn verändert, hatten wir ja schon geklärt. Nun gibt es aber auch bei der Zeichensatzdarstellung einige Sondermodi, ebenso wie bei der HIRES-Grafik, mit denen wir die Anzahl der Farben auf dem Bildschirm erhöhen können. Da haben wir zunächst einmal den Multi- color-Zeichensatz, der ähnlich wie die Multicolor-Grafik funktioniert. Sie kön- nen diesen Modus durch Setzen des 4. Bits in Register 22 des VIC einschalten. Wie Sie sehen ist dies übrigens das sel- be Bit, wie beim HIRES-Multicolormodus, woraus sich auch eine gewisse Verwand- schaft ergibt. Setzen Sie also dieses Bit mit:
POKE V+22,PEEK(V+22) OR 16
(wobei V=53248=Basisadresse VIC), so KÜNNEN Sie den momentanen Zeichensatz nun in Multicolor-Darstellung benutzen. Sie KÜNNEN, MÖSSEN aber nicht!!! Hierzu jedoch erst einmal die Erläuterung des Aufbaus eines Multicolorzeichens. Ebenso wie bei der Multicolorgrafik werden je 2 Bits von den 8 Bits eines Datenbytes zu einem Grafikpunkt zusammengenommen. Hierbei geben dann die vier möglichen Bitkombinationen an, welche Farbe an welcher Stelle dargestellt werden soll. Die Farbgebung selbst wird zum Einen durch die entsprechende Farbe im Color- RAM (von 55296 bis 56295), das Sie ja schon bei der HIRES-Multicolordarstel- lung kennengelernt haben (MagicDisk 3/90 - Grafikkurs Teil 4), zum Anderen kommen die Farben aus dreien der 4 Hintergrund- farbregister des VIC. Diese sind die Register 33, 34 und 35 (das vierte ist Register 36, wird jedoch hier nicht be- nutzt). Sehen Sie doch noch einmal in die Registertabelle aus dem ersten Teil des Grafikkurses (MD 12/89), damit sie die Lage dieser Register erkennen... Bei den verschiedenen Bitkombinationen eines Zeichens holt sich der VIC die entsprechende Farbe aus dem entsprechen- den Register. Hierzu eine Tabelle:
Bitmuster Farbregister -----------------------------
00 Register 33 (53281) 01 Register 34 (53282) 10 Register 35 (53283) 11 Farb-RAM, Bits 0-2
Als Erläuterung sehen Sie sich bitte die Grafik an, die vor dem 2.Teil zu sehen ist...
Grafikkurs Teil 6.2 Sie sehen hier wie die Grafikpunkte in- nerhalb der Zeichen gesetzt sein müssen, und wo sich der VIC nun die Farben für die Normaldarstellung herholt. Nun jedoch zum MÖSSEN und KÜNNEN. Wie Sie sehen, wird die vierte Farbe eines Zeichens ja durch die Bits 0 bis 2 der entsprechenden Farbramadresse eines Bildschirmzeichens dargestellt. Wir ha- ben hier also 3 Bits, in denen wir die Farbe für die "11"-Bitkombination ange- ben können. Somit haben wir die Möglich- keit nur schlappe 8 Farben für diese Multicolorfarbe festzulegen, anstelle der sonst 16 möglichen. Zugegeben - ein Nachteil, jedoch wird diese Einschrän- kung durch einen erheblichen Vorteil wieder von höchst positiv zu wertender Bedeutung. Das 3. Bit des Farbrams (in dem man sonst ja das vierte Bit für die Farbinformation ablegen könnte, so daß man 16 Farben zur Verfügung hätte) fun- giert im Multicolormodus für Zeichen nicht mehr als Farbinformationsträger, sondern es gibt dem VIC Auskunft darü- ber, ob das entsprechende Zeichen nun tatsächlich in Multicolordarstellung auf dem Bildschirm erscheinen soll, oder in normaler Auflösung! Somit bietet sich die Möglichkeit beide Zeichenmodi mitei- nander zu kombinieren, so daß sie im oberen Teil des Bildschirms beispiels- weise eine kleine Grafik darstellen kön- nen, zusammengesetzt aus Multicolorzei- chen, und im unteren Teil des Bild- schirms einen ganz normalen Text stehen haben, in normaler Zeichenauflösung natürlich. Ist das 3. Bit in der Farbramadresse eines Zeichens gesetzt, so wird die Mul- ticolordarstellung jenes Zeichens akti- viert, ist es jedoch gelöscht, so wird das Zeichen in ganz normaler Darstellung angezeigt. Experimentieren Sie doch ein- mal ein wenig mit dem Multicolorzeichen- satz; schreiben Sie einmal ein Zeichen in die Ecke links oben des Bildschirms und schalen Sie den Multicolormodus ein. Nun POKEen Sie den Wert 1 in die erste Farbramadresse (das Zeichen steht ja auch in der ersten Adresse des Bild- schirmspeichers), mit der Nummer 55296. Das Zeichen sollte nun in Weiß und nor- maler Auflösung dort erscheinen. Schrei- ben Sie jetzt eine 9 in die Farbadresse des Zeichens, so wird es in Multicolor- darstellung erscheinen, wobei die vierte Multicolorfarbe Weiß ist (9 enstpricht Binär 1001, wobei das 3. Bit ja wegfällt - die effektive Farbe ist also 001 was dezimal 1 und somit die Farbe Weiß ist - Sie erinnern sich ja noch an die Farbta- belle die ich schon häufiger zitierte). Mit dem Multicolorzeichensatz ergeben sich ja schon immense Möglichkeiten der Grafikdarstellung, kommen wir nun aber noch zu einem weiteren Modus, in dem wir einen Zeichensatz auf dem Bildschirm darstellen können, dem "Extended Back- ground Color Mode". Öbersetzt heißt das "Erweiterter Hinter- grundfarben Modus", und genau das ist es was dieser Modus bewirkt. Durch das Ein- schalten dieses Modus schrumpft der Dar- stellbare Zeichensatz von 256 Zeichen auf genau ein Viertel, nämlich 64 Zei- chen zusammen. Diese 64 Zeichen können nun jedoch in 4 verschiedenen Hinter- grundfarben dargestellt werden. Diese Farben werden wie beim Multicolormodus in den 4 Hintergrundfarbregistern (Regi- ster 33-36) des VIC festgelegt. Das dar- gestellte Zeichen selbst erscheint in der Farbe der entsprechenden Farbrama- dresse eines Zeichens. Zur besseren Erl- äuterung sollten Sie sich einmal das Programm "ZEICHENDEMO" auf der Rückseite dieser MD anschauen. Es sind dort auch noch eine Multicolordemo enthalten und eine Demo, die eine weiter unten be- schriebene Funktion des VIC erläutert. Jetzt jedoch noch zu weiteren Einzelhei- ten des "Extended Background Color Mode" (im weiteren EBC-Modus). Zunächst einmal die Befehle zum Ein- und Ausschalten desselben. Hierfür ist Register 17 des VIC (Adresse 53265) zuständig. Wird hier das 6. Bit gesetzt, so wird der EBC- Modus eingeschaltet. Somit ergeben sich die Befehle:
POKE V+17,PEEK(V+17) OR 64 zum Einschalten und POKE V+17,PEEK(V+17) AND NOT 64 zum Ausschalten.
Die 64 darstellbaren Zeichen des EBC- Modus enstprechen den 64 ersten Zeichen eines Zeichensatzes und somit den Bild- schirmcodes von 0 bis 63. Der Unter- schied, in welcher Hintergrundfarbe ein Zeichen nun dargestellt wird, besteht in den Bildschirmcodes im Bildschirmspei- cher. Die Codes 0-63 lassen die entspre- chenden Zeichen mit der Hintergrundfarbe aus Farbregister 0 (=VIC-Register 33) erscheinen. Die Codes 64-127 die zeigen DIESELBEN Zeichen, jedoch mit der Hin- tergrundfarbe aus dem Farbregister 1 (=VIC-Register 34) an, und so fort. Hierzu eine Tabelle:
Zeichen Farbreg. VIC-Reg. Adresse ---------------------------------
0-63 0 33 53281 64-127 1 34 53282 128-191 2 35 53283 192-255 3 36 53284
Ein Beispiel: Der Buchstabe "A" hat den Bildschirmcode 1. Im EBC-Modus entspre- chen die Bildschirmcodes 1+1*64=65, 1+2*64=129 und 1+3*64=193 jedoch eben- falls dem Buchstaben "A", allerdings mit dem Unterschied, daß der Buchstabe je- weils in verschiedenen Hintergrundfarben erscheint. Um also den enstprechenden EBC-Bildschirmcode eines Zeichens zu ermitteln, braucht man lediglich zu dem absoluten Bildschirmcodes dieses Zei- chens die Farbregisternummer multipli- ziert mit 64 zu addieren. Daraus ergibt sich die Formel: EBC-Code=Bildschirmcode+Farbregister*64 Auch dies ist in dem schon erwähnten Programm "ZEICHENDEMO" in einem Beispiel erläutert. Hiermit hätten wir das Thema "Grafik" im allgemeinen schon abgehandelt. Jedoch möchte ich Ihnen nun noch einige Fein- heiten des VIC erklären, mit denen sich schöne Effekte erzielen lassen. Im Ein- zelnen handelt es sich hierbei um die beiden Steuerregister des VIC Nummer 17 und 22. Diese hatten wir ja teilweise schon bei einzelnen Themen erwähnt, je- doch befinden sich in diesen beiden Re- gistern noch einige Bits, die wir noch nicht kennen, mit denen wir jedoch un- geanhte Möglichkeiten aus dem VIC raus- holen können. Mit diesen beiden Registern kann man nämlich den Bildschirm selbst und seine Lage steuern. In beiden stehen uns hierfür jeweils 4 Bit zur Verfügung, genauer gesagt die Bits 0-3. Das Bild vor dem nächsten Kursteil zeigt die Belegung der Bits...
Grafikkurs Teil 6.3 Wie Sie sehen haben wir die übrigen Bits (von 4 bis 7) ja auch schon alle abge- handelt, bis auf die Bits 4 und 7 aus Steuerregister 1. Letzteres Bit geht uns auch gar nichts an, da es etwas mit der Raster-IRQ-Programmierung zu tun hat, die in BASIC nicht zu realisieren ist (wie so oft auch hier ein Verweis auf den Assemblerkurs, der parallel zu die- sem hier läuft). Bit 4 hat eine ziemlich einfache Bedeu- tung, die ich am Besten gleich an den Mann bringe. Mit diesem Bit kann man, wie aus der Grafik eben schon ersicht- lich, der Bildschirm schlichtweg ein- und ausgeschaltet werden. Im Klartext heißt das, daß wenn Sie dieses Bit set- zen, der sichtbare Bildschirm einfach weggeblendet wird und in der Rahmenfarbe erscheint. Ich möchte darauf hinweisen, daß der Bildschirminhalt NICHT verloren geht, das ganze ist eher wie ein Vorhang zu vergleichen - hinter diesem "Vorhang" kann man immer noch den Bildschirmspei- cher verändern, nur wird das erst sicht- bar, wenn der Vorhang wieder zur Seite geschoben wird. Wir haben dem VIC also lediglich die Anweisung gegeben den Bildschirm nicht mehr darzustellen, was uns zwei Vorteile bringt. Der entscheidende Vorteil liegt wohl darin, daß der VIC den Prozessor des 64ers nun nicht mehr beim Zugriff auf den Speicher stört (hat was mit dem Auf- bau von Computern allgemeinhin zu tun. In aller Regel kann nämlich nicht mehr als EIN Chip gleichzitig auf den verfüg- baren Speicher zureifen). Da der VIC nun normalerweise aber sehr häufig auf den Speicher zugreifen muß um das Bild auch sauber und flimmerfrei darstellen zu können, und somit den Prozessor bremst, der dann nämlich ein paar Nanno bis Mi- crosekunden auf den Zugriff warten muß, erhalten wir mit dem Abschalten des Bildschirms einen Geschwindigkeitsvor- teil. Diesen kann ich Ihnen auch genau beziffern: bei Programmen die häufig auf Diskette zugreifen (z.B. Kopierprogram- me) wird etwa 15%(!) schneller gearbei- tet als sonst. Bei Programmen die im Speicher arbeiten sind es immerhin noch 5%, und die können sich ja häufig schon bemerkbar machen. Ich denke da zum Bei- spiel an komplizierte Grafikberechnun- gen, die unter Umständen einige Stunden dauern können... Zum Anderen haben wir BASIC-Programmier aber auch den Vorteil, daß wir so den Bildschirmaufbau eines Programms verbes- sern können. Angenommen Sie hätten ein Programm, das noch langwierig im Bild- schirmspeicher herumpoket, bis der endgültige Zustand erreicht ist. Es sieht einfach unsauber aus, wenn da noch lange rumgefriemelt wird bis man endlich was erkennen kann. Also schalten wir den Bildschirm in dieser Aufbauphase einfach ab und verdecken das vorläufige Chaos darunter unter dem "Vorhang der Liebe", wie man so schön sagt. Doch nun zurück zu den anfangs schon erwähnten Bits 0-3 der beiden Steuerre- gister. Mit Ihnen können wir, wie schon erwähnt, die Lage und das Aussehen des Bildschirms verändern. Zunächst zu den Bits 3 der beiden Regi- ster. Mit Ihnen können wir den Bild- schirm, relativ zu der Normalsarstel- lung, "verkleinern". Bit 3 aus Steuerre- gister 1 steuert hierbei die Anzahl der dargestellten Zeilen. Ist es gesetzt, so zeigt der VIC, wie gewohnt, 25 Zeilen an. Löschen wir es nun aber, so blendet VIC jeweils die Hälfte der obersten und der untersten Bildschirmzeile weg. ACH- TUNG: Auch diesmal geht der entsprechen- de Bildschirminhalt NICHT verloren, er wird lediglich nicht angezeigt! Ebenso verhält es sich mit Bit 4 von Steuerregister 2, nur daß letzteres für die Anzahl der Bildschirmspalten zustän- dig ist. Bei gesetztem Bit haben wir wie üblich 40 Spalten (=Zeichen) pro Zeile, bei gelöschtem Bit werden diese auf 38 reduziert, indem diesmal jeweils die Spalte ganz links und ganz rechts am Bildschirm verschwindet. Auch diesmal sind diese Spalten lediglich nicht sichtbar! Doch was für einen Vorteil bringt uns das nun. Das zeige ich Ihnen am Besten mit der Funktionsweise der Bits 0-2 der beiden Steuerregister. Diese 3 Bits steuern jeweils den Abstand des ersten sichtbaren Bildschirmpunktes von oben und von links, auch als Offset bezeich- net. Am besten erläutere ich Ihnen das anhand einer Grafik die vor dem nächsten Kursteil zu sehen ist...
Grafikkurs Teil 6.4 Wie Sie sehen, kann man den Bildschirm nun mit Hilfe dieser 3 Bits der beiden Steuerregister um jeweils 8 Pixel in der Vertikalen und in der Horizontalen ver- schieben. Probieren Sie doch einmal aus, was geschieht, wenn Sie verschiedene Werte in diese unteren 3 Bits hinein- schreiben. Der Rest des Registers sollte natürlich unverändert bleiben, um unan- genehme Nebenwirkungen auszuschließen. Diese Bits können ja dezimale Werte von 0 bis 7 annehmen. Bei jedem weiteren Wert, wird der Bildschirm um wiederum 4 Pixel verschoben. Wenn Sie hier also Werte hineinschreiben, so addieren Sie am Besten zu dem dezimalen Wert der 3 Bits den Wert der restlichen Bits, die gesetzt sein sollen direkt dazu (man nennt das auch absolutes POKEn). Und nun zur Anwendung des ganzen! Man kann nämlich mit Hilfe der nun kennenge- lernten Bits zur Bildschirmmanipulation einen sogenannten "SoftScroll" realisie- ren. Dies ist das weiche Schieben des Bildschirms nach links, rechts, oben oder unten, wie Sie es aus manchen Spie- len kennen (klassisches Beispiel ist wohl der schon uralte Megahit "Uri- dium"). Dies funktioniert denkbar ein- fach: zunächst wird der Bildschirm in der entsprechenden Scrollrichtung ver- kleinert. Als Beispiel nehme ich hier einmal einen Softscroll nach links. Dem- nach müssen wir die Spaltenzahl verkür- zen auf 38 Spalten pro Zeile. Nun sind die erste Spalte links und die erste Spalte rechts nicht mehr sichtbar. Wir schreiben nun eine 7 in Steuerregister 2, damit der linke Rand wieder sichtbar wird, jetzt jedoch 2 Spalten des rechten Randes verschwinden. Dort schreiben wir nun ein Zeichen hin und zählen den X- Offset von 7 auf 0 herunter. Somit wäre das nicht-sichtbare Zeichen in den Bild- schirm "hereingelaufen". Als nächstes wird es eine Spalte vorkopiert und das Steuerregister 2 wieder auf 7 gesetzt. Das Zeichen befindet sich nun in der letzten auf dem Bildschirm sichtbaren Spalte. Nun beginnt der nächste Durch- gang, das nächste Zeichen wird wieder in die erste unsichtbare Spalte geschrieben und durchgescrollt... Ein Softscrolling ist entstanden! Leider ist es jedoch in Basic nicht mö- glich einen solchen Scroll auch wirklich ruckelfrei zu realisieren. Das Umkopie- ren der Zeichen dauert zu lange, so daß der Scroll "zittert". So etwas ist wir- klich sauber nur in Maschinensprache zu machen, oder Sie versuchen einmal Ihr BASIC-Programm durch einen BASIC- Compiler zu beschleunigen, es kann gut sein, daß hierbei auch noch einigermaßen gute Ergebnisse zu erzielen sind. Eine in BASIC sicher realisierbare An- wendung, die einen guten Effekt liefert wäre ein sogenanntes Bildschirmwackeln. Angenommen, bei Ihrem nächsten Spiel explodiert ein Raumschiff, wenn es ge- troffen wird. Wie wäre es denn, wenn hierzu der Bildschirm so anständig wak- keln würde? Nichts einfacher als das, wir müssen lediglich ein paar Zufalls- werte in die Bildschirmoffsetbits schreiben, um ein chaotisches Wackeln zu erzeugen. Schauen Sie zu diesem Zweck einfach nocheinmal in das Programm "ZEI- CHENDEMO" der Rückseite dieser MD, auch zu diesem Thema gibt es da einige De- monstationen. Nun noch ein paar Worte zum Speicher- handling des VIC. Wie ich Ihnen ja schon im Grafikkurs Teil 5 erzählte kann der VIC lediglich 16 KByte Speicher adres- siere. Im Normalfall belegt er den Spei- cher von Adresse 0 bis 16383, was zur Folge hatte, daß wir Grafikdaten immer nur in diesem Bereich untergebracht ha- ben. Dies brachte jedoch häufig Schwie- rigkeiten mit sich, zumal wir manche Speicherbereiche nicht unbedingt direkt nutzen konnten und zunächst immer ir- gendwelche Vorsichtsmaßnahmen treffen mußten, bevor wir überhaupt Daten in einem Bereich ablegen konnten. Deshalb gibt es aber auch die Möglichkeit den Speicherbereich des VIC zu verschieben. Dies wird durch Adresse 56576 gesteuert. Diese Adresse liegt in dem Speicherbe- reich eines weiteren Bausteins des 64ers, dem CIA, mit dem wir uns jedoch nicht weiter befassen werden, da dieser nur in Maschinensprache von Nutzen ist. Die Bits 0 und 1 dieses Registers geben die möglichen Basisadressen des VIC an. Diese sind aufgeteilt in folgende Kombi- nationen:
Bitmuster Speicherbereich -------------------------
11 0-16383 10 16384-32767 01 32768-49151 00 49152-65535
Schreiben Sie also diese Bitkombinatio- nen in die Bits 0 und 1 der Adresse 56576, so wird der Speicherbereich des VIC verschoben. Wie Sie sehen geschieht dies in Abschnitten von 16 KB, wobei der ganze Speicher des VIC quasi "abgedeckt" werden kann. Doch Vorsicht! Die normalen Basisadressen von verschiedenen Grafik- funktionen verschieben sich somit näm- lich ebenfalls um 16 KB! Das heißt im Klartext, daß beispielsweise der Bild- schirmspeicher jetzt nicht mehr bei Adresse 1024 anfängt, sondern jeweils 16384 Bytes weiter! Ebenso ist es mit der Bitmap einer Grafikseite. Diese kann ja normalerweise bei Adresse 0, oder wahlweise bei Adresse 8192 des Speichers liegen. Schalten wir den Bildschirm auf den 2 Bereich der obigen Liste, so lie- gen die möglichen Grafikbereiche jetzt bei 0+16384=16384 und 8192+16384=24576! Nun noch zu einem Thema, das uns eben- falls aus Speicherplatzgründen sehr nützlich ist. Es gibt nämlich auch die Möglichkeit, die Basisadresse des Bild- schirmspeichers innerhalb des 16KB- Bereichs des VIC zu verschieben. Das hat den Vorteil, daß man sehr schnell zwi- schen 2 Bildschirmen hin- und herschal- ten kann, oder aber auch, daß man die Farbdaten einer Grafik an einer anderen Stelle ablegen kann, wenn man den norma- len Bildschirmspeicher für andere Dinge nutzen möchte. Dies ist ein denkbar ein- facher Vorgang. Die Bits 4-7 aus Regi- ster 24 sind dafür zuständig. Schreiben Sie die nun folgenden Bitkombinationen, so wird der Bildschirmspeicher an die angegeben Adresse verschoben:
0000 0-999 0001 1024-2023 0010 2048-3047 0011 3072-4071 0100 4096-5095 0101 5120-6119 0110 6144-7143 0111 7168-8167 1000 8192-9191 1001 9216-10215 1010 10240-11239 1011 11264-12263 1100 12288-13287 1101 13312-14311 1110 14336-15335 1111 15360-16359
Schreiben Sie also eines der angegeben Bitmuster in die Bits 4-7 des Registers 24 des VIC, so beginnt für den VIC der Bildschirmspeicher bei der angegebenen Adresse. Sie sehen nun den Inhalt dieses RAMs auf dem Monitor, jedoch ist der Cursor verschwunden! Das liegt daran, daß das Betriebssystem des 64ers eben- falls wissen muß, wo sich der neue Bild- schirmspeicher befindet, und jetzt den Cursor noch an der alten Adresse blinken läßt. Doch auch dies läßt sich beheben, nämlich indem Sie schlichtweg die neue Registeradresse dividiert durch 256 in die Adesse 648 schreiben. Dies ist ein Byte, das vom Betriebssystem benutzt wird, und wo es feststellt, wo sich der momentane Bildschirmspeicher befindet. Diese Adresse ist übrigens auch sehr wichtig, wenn Sie den VIC in einen ande- ren 16K-Bereich verschieben. Bedenken Sie, daß Sie ja auch den Bildschirmspei- cher absolut mitverschoben haben! Somit muß beim Verlegen des VIC-Bereichs auch die neue Bildschirmadresse in dieser Adresse mit angegeben werden. Desweiteren ist noch zu sagen, daß sich mit dem Bildschirmspeicher ebenfalls die Spriteblockregister mitverschieben. Spriteblockregister 0 liegt ja normaler- weise bei 2040. Verschieben Sie jetzt den Bildschirmspeicher beispielsweise nach 3072, so müssen Sie bedenken, daß das neue Spriteblockregister 0 jetzt bei 2040-1024=1016 liegt! So. Das wars dann endgültig in Sachen Grafik. Ich hoffe, es hat Ihnen ein we- nig Spaß gemacht und daß jetzt der VIC in Ihrem 64er heißlaufen wird. In näch- ster Zukunft ist für mich hier kein Kurs mehr geplant, deshalb verabschiede ich mich bis auf weiteres von Ihnen - Servus Ihr Uli Basters