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 abgeschlossen, nun geht es weiter mit einem
Grafikkurs, der ebenfalls den Einsteigern gewidmet sein soll." Buuuh, Betrug!" werden jetzt die Profis unter
Ihnen jetzt schreien," wir wollen endlich 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
HIRESund 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 64 er von einem Grafikchip verwaltet, der alle Informationen
im Speicher des 64 ers 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 seinerseits schon im fünften Basickurs erwähnte. In jenem fünften Teil hatten wir ja auch gelernt, wie das Innere unseres
64 ers aussieht, daß es dort Speicherbereiche gibt, die man mit sogenannten
Speicheradressen anspricht, daß ein Byte
aus acht Bit besteht, und wie man Binärzahlen in Dezimalzahlen umrechnet. Alle
diese Kenntnisse sind in der Grafik von
großer Bedeutung, weshalb ich Ihnen empfehle, sollten Sie sich an die Gedankengänge von damals nicht mehr so ganz
erinnern, sich doch noch einmal die Magic Disk 64 Ausgabe 5/89 anzuschauen.
Wie also schon gesagt, belegt der VIC
einen Bereich von 46 Bytes im Ein-/ Ausgabebereich unseres 64 ers ( von Adresse 53248 bis 57344) . Der SID hatte
seine erste Stelle, oder auch Basisadresse genannt, bei 54272 . VICs Basisadresse liegt bei 53248, der ersten Speicherzelle des Ein-/ Ausgabebereichs also.
Diese Adresse wird nun also immer als
relativer Bezug für die einzelnen Register 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 64 er
steuern also gewisse Funktionen des zu
ihnen gehörendem Chips. Wie Sie ja wissen können Sie mit der Adresse 53280 die
Hintergrundfarbe des Bildschirms verändern. Schreiben wir hier einen Wert hinein, so ändert sich die Farbe entsprechend. 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 Register 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 kommentiert, ü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) haben 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 Spriteprogrammierung - wie Sie aus obiger Tabelle 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 bewegten, 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
64 er 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 eines solchen Sprites. Ein Sprite muß nämlich, 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 einzelne 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ämlich 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 Bildschirm darstellt? Nunja, wie Sie bestimmt 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 gezogen, 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
64 ers. Ich denke, daß es spätestens
jetzt bei Ihnen klingelt. Jeder Punkt in
unserem Spritegitter repräsentiert nämlich 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 anhand der ausgefüllten ( gleich Binär 1) und unausgefüllten ( gleich Binär 0) Kästchen bilden, in Dezimalzahlen umzurechnen, um die Daten in BASIC auch entsprechend im Speicher des 64 ers unterbringen zu können, denn dieser verarbeitet ja ausschließlich nur diese Zahlen.
Nunja, nichts leichter als das, wie dieses 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 gesuchte 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 geliefert, 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 64 ers
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 64 er
schon für bestimmte Aufgaben reserviert
sind. Die Entwickler der 64 ers haben uns
da zwar doch noch ein wenig Handlungsfreiheit geschaffen, und haben da
tatsächlich noch 4 Speicherbereiche für
Sprites übriggelassen. Möchte man nun
allerdings mehr als 4 verschiedene Sprites 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 Speicherbereiche kümmern, da diese für unseren
momentanen Wissensstand vollkommen ausreichen. Diese 4 Bereiche liegen innerhalb der ersten 1024 Bytes unseres Computers. Wie ich im fünften Basickurs
schon erwähnte, sind diese Speicherstellen 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 letzten 3 davon ( siehe Tabelle unten) von
uns nur dann benutzt werden, wenn wir
nicht mit der Datasette, einem Kasettenlaufwerk also, arbeiten. Da ich allerdings 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 brauchen 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 berechnet 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
64 ers 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 Speicherbereiche zu schreiben. Wir hatten ja unser
kleines UFO-Sprite in Dezimalwerte zerlegt, 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. Einfacher 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 genannten 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änge!) . Es wird nun ein Datenbyte eingelesen und gleich geschrieben, angefangen
bei Adresse 832( Basisadresse 832 plus
0) bis 894(832 plus 62) .
Nachdem wir nun die Daten abgelegt hätten kommen wir zum zweiten Schritt : VIC
muß ja noch wissen, aus welchem Spriteblock 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 Sprite 0,2041 für Sprite 1,2042 für Sprite 2, und so fort, bis Byte 2047 für
Sprite 7 .
Wir wollen einmal Sprite 0 auf den Bildschirm bringen. Hierzu müssen wir die
Blockadresse in Zelle 2040 schreiben.
Unsere Daten liegen ja im Spriteblock 13, also:
POKE 2040,13
Soweit - so gut. Trotzdem haben wir noch
nicht alle Hindernisse hinter uns gebracht. Des Weiteren müssen wir nämlich, um das Sprite auf dem Bildschirm zu sehen, 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 ausgeschaltet. 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 einschalten, so muß man die Werte ihrer zugehörigen Bits addieren und in Register 21 schreiben. Wollten wir also
beispielsweise Sprite 6 und Sprite 2 einschalten, so wäre der Wert für Register 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 jedoch 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ämlich schon da, nur wir sehen es nicht, weil es sich noch versteckt hält ! Normalerweise sollte es sich nun, wenn Sie
ihren 64 er frisch eingeschaltet haben, an der Position 0/0 des Bildschirms befinden. Womit wir schon gleich beim Thema 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 Koordinaten : 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 Bildschirmpunkte 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 Bildschirm, 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 Bildschirmbereich. 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. Hierzu müssen wir lediglich die entsprechenden Bildkoordinaten in die Koordinatenregister unseres Sprites schreiben. Das
sind für Sprite 0 die Register 0 und 1 für die Xund Y-Koordinate. Positionieren 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 beeindrucken. 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 kontinuierlich auf seiner Stelle stehen bleibt und
sich nicht von seiner linksoben- Position wegbewegen läßt. Sprites sind
somit also tatsächlich unabhängige Grafikobjekte, mit denen man ganz eigene
Dinge machen kann.
Nun, man muß zugeben, daß ein unbewegliches Sprite auf die Dauer ziemlich langweilig 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 unseres Sprites erhöht, oder erniedrigt.
Hier ein Beispiel ( wir setzen voraus, daß alle Daten schon im Speicher stehen, und das Sprite ordungsgemäß eingeschaltet 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 einmal 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 einfach - Zack - auf dem Bildschirm erscheinen 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 Bildschirm 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 verantwortlich. 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 neunten 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 "100000000"- 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 Beispielen vorhin, war es - wenn Sie Ihren
64 er 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 Anfangspunkt die Bildschirmposition 256 . Achten 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 :
100101100
Demnach müssen wir also Bit 1 im Register 16 setzen. Dieses hat den Dezimalwert 2 . Die restlichen 8 Bits haben insgesamt 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 hervorragend zur gezielten Manipulation von Bits
benutzen, ohne voher irgendwelche Binärzahlen 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 Entscheidungstabelle 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 vergleichen, 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 immer das nte Bit der ersten Zahl mit dem
nten Bit der zweiten Zahl verglichen
und dann ein aus den beiden Bits resultierendes 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 resultierende 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 nten Bits einer Zahl war
nämlich nur dann 1, wenn das Bit der
ersten Zahl ODER ( OR) das Bit der zweiten Zahl gesetzt war. ODER wenn beide
Bits gesetzt waren. Nur wenn Beide 0 waren, war das resultierende Bit ebenfalls 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 Operatoren. NOT ist eigentlich auch gar
kein Operator, man stellt es nämlich
einfach nur einer Zahl voran. Was jetzt
geschieht ist folgendes : alle Bits dieser Zahl werden in ihr Gegenteil umgewandelt (0 ist nämlich NICHT ( NOT)1 und
somit das Gegenteil von 1 und umgekehrt) . 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 eigenes neutes Bit für die X-Position hat.
Nun kann es sehr leicht vorkommen, daß
wenn man in einem Programm mehrere Sprites über den Bildschirm bewegt, langsam
aber sicher den Öberblick verliert, welches Sprite nun das 9 . Bit gesetzt haben
muß und welches nicht. Würden wir jedesmal, wenn ein neues Sprite in den X-Bereich über 256 rücken müßte einfach
dessen neuntes Bit hineinPOKEn, so könnte 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, benutzen 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 folgendermaßen aus :
00010100
Um jetzt Sprite 1 hier auch noch bedienen zu können, müssen wir lediglich Bit
1 setzen. Hier hilft uns OR direkt weiter. Wir müssen nur den jetzigen Inhalt
von Register 16 mit dem Binärwert
"00000010"( dezimal 2) durch OR logisch
verknüpfen. Nach der Entscheidungstabelle von oben sieht das Ergebnis dann so
aus :
0001 0100 OR 0000 0010 -------------
=00010110
Es wäre geschafft ! Wir hätten nun Bit 1 gesetzt, ohne die anderen zu verändern,
geschweige denn, die ganze Zahl ins Dezimalsystem 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. Angenommen, Sprite 2 sollte wieder heruntergeschaltet werden. Hierzu gibt es jetzt
2 Methoden.
Zuerst einmal die Umständlichere von
beiden, mit Hilfe von AND. Wir verknüpfen hierzu den jetzigen Inhalt von Register 16 mit dem Binärwert "11111011"( dez.251) . Hier die Rechnung :
0001 0110 AND 1111 1011 -------------
=00010010
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 wurde ( denn 1 AND 0=0) . Andere Bits, die
ursprünglich den Wert 0 aufwiesen, wurden 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üssen doch zugeben, daß das Berechnen der
sogenannten AND-Maske, der Zahl also, mit der man die ursprüngliche Zahl
verknüpfen möchte, ziemlich zeitaufwendig 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 Beispiel, bei dem ebenfalls das 2 . Bit von
Register 16 wieder gelöscht wird, diesmal jedoch ohne umständliches Herumrechnen :
NOT 0000 0100 = 1111 1011 --> 0001 0110 AND 1111 1011 (Ergebnis der NOT- Operation) ----------------------------------------
=00010010
Im Prinzip haben wir also dasselbe getan
wie im Beispiel mit AND, nur daß die
Umrechnungsarbeit diesmal von NOT übernommen wurde. Auch dieses Beispiel kann
man in einer Programmzeile zusammenfassen :
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 Ihnen 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 Spriteprogrammierung 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 gelernt, 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 Einzelheiten klären, mit denen man gezielt
Sprites manipulieren kann. Und die sind
sehr zahlreich, aber aufgrund der Informationen des letzten Kurteils auch sehr
einfach zu verstehen. Also los gehts. . .
a) Spriteexpansion:
Wie Sie sicherlich noch wissen, war ein
Sprite genau 24 x21 Punkte groß. Wenn Sie
sich dies einmal auf dem Bildschirm angesehen haben, so war zu erkennen, daß dies eigentlich ein relativ kleiner Bereich ist. Was aber wenn wir jetzt ein
Spiel schreiben wollten, in dem ein besonders großes Raumschiff in einer kleinen Animation über den Bildschirm gleitet? Da gibt es grundsätzlich 2 Möglichkeiten. 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ürden, mit denen wir noch andere Dinge
über den Bildschirm huschen lassen könnten, denn wir haben ja nur 8 von diesen
kleinen und schnuckeligen Grafikobjekten. Deshalb können wir auch auf eine
andere Methode zurückgreifen: die Spriteexpansion.
Was ist das, Expansion? Nun Expansion
heißt nichts anderes als " Erweiterung" oder besser " Dehnung" . Durch die Spriteexpansion können wir also Sprites dehnen. 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 24 x21 auf 48 x42 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 nichtexpandiert
wäre!
Die ganze Sache hat aber auch einen
Nachteil. VIC benutzt zur Expansion nämlich 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 verwandten. Hier ist nämlich ebenfalls für
jedes der acht Sprites ein Bit reserviert. Möchten wir nun ein Sprite in Xoder Y-Position expandieren, so müssen
wir lediglich dessen Bit in Register 23 und/ oder 29 setzen, je nach dem in welche 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 nomalen Auflösung dargestellt. Zur Demonstation habe ich Ihnen auf der Rückseite
dieser MagicDisk ein kleines Programm
namens " SPRITE-EXP" gespeichert. Da können 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ändlichdie 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öchte: 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 Hintergrundregister schreiben, sondern in das
dem Sprite zugehörige Farbregister. Diese sind Ihnen bestimmt schon in der Register- Tabelle aus dem letzten Kursteil
aufgefallen. Es sind die Register 39 bis
46 . Für jedes der 8 Sprites ein Register. 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 erscheint 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 kleines Männchen, was da auf dem Bildschirm
steht, würde sich doch viel besser machen, wenn es nicht nur uni-Weiß wäre, sondern wenn es ein gesundes rosa Gesicht, 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 Öberschrift dieses Kapitels zeigt, gibt es
auch die Möglichkeit, einem Sprite MEH-RERE Farben zuzuordnen ( multi= viel; color= 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 annhemen 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 12 x21 Punkte
darstellen können.
Achtung, jetzt wirds kompliziert: Trotzdem 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 besten erst einmal die folgende Grafik an, bevor ich mich in umständlichen Erklärungen verliere, die eh keiner versteht. . .
Die Grafik verrät es schon: bei Multicolorsprites werden zwei Grafikpunkte zu
einem zusammengefaßt. Doch wozu das Ganze? Nun ganz einfach - diese beiden Grafikpunkte die EINEN Multicolorpunkt ergeben 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 entscheidet dann, welche Farbe diese zugeordnet 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 Multicolorsprites. Die nun folgende Tabelle gibt an, aus welchen Registern sich VIC nun die Farben der einzelnen Kombinationen zusammensucht:
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 kennengelernt. 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 Hintergrundes ( Kombination 00, der Hintergrund
scheint durch), und die zwei Farben der
Multicolorregister. Die vierte Farbe
wird dann aus dem " normalen" Farbregister des entsprechenden Sprites geholt, und die kann ja bei allen 8 Sprites verschieden sein.
Beachten Sie also, daß Sie bei Multicolorsprites immer nicht nur einen Punkt
betrachten, sondern gleich die Bitkombination für 2 Punkte in Ihr Sprite-Raster
eintragen! Demnach sähe ein Multicolorsprite in der " Roh-Darstellung" folgendermaßen aus:
Die blauen Kästchen in der Grafik stehen
diesmal nicht für die Farbe des entsprechenden Punktes, sondern nur dafür ob er
gesetzt ist oder nicht.
Doch kommen wir nun endlich zu der Programmierung 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 Hinterals
auch im Vordergrund von Grafikoder
Text auf dem Bildschirm erscheinen. Normalerweise 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 jedoch auch von Zeit zu Zeit hinderlich
sein. Angenommen, ein von Ihnen programmiertes 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 Planeten 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 sofort 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 gegenseitig anrempeln, oder etwa gegen
eine Mauer laufen.
Doch reden wir Klartext. VIC gibt uns
durch Register 30 und 31 die Möglichkeit, 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 Hinteroder Vordergrund
steht, es werden die Berührungen mit
entsprechenden Grafikobjektem immer registriert. 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 Sprites 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 Kollision, oder sagen wir an dem " Unfall"
beteiligt sind. Diese Funktion kann
übrigens sehr hilfreich bei der Programmierung von Spielen sein, wenn beispielsweise 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 treffen, ob das Raumschiff nun sprchwörtlich
explodieren soll, oder ob es doch eine
andere Kollision war, bei der ein anderes 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 überlassen. Demnach sollte man nach dem
obligatorischen Einlesen eines Kollisionsregisters 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 festgestellt 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 miteinanander stehen, setzt VIC die Kollisionsregister immer wieder neu. Deshalb könnte
er mehrmals einund dieselbe Kollision
anzeigen! Auch hierzu ein Beispielprogramm auf der Rückseite dieser MD. Es
heißt " SPR-KOLLISION" .
So, nun sind wir mit der Spriteprogrammierung durch. Ich habe Ihnen jetzt alles ü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 Grafikkurses. Nachdem wir ja nun die Sprites
abgehandelt hätten, können wir uns diesen Monat nun endlich an die oft begehrte Programmierung der HIRES-Grafik machen. Auch dies ist ein relativ komplexes Thema, obwohl wir diesmal nicht allzu vielen in Registern " herumpoken" müssen, als bei den Sprites. Das komplizierte hierbei ist mal wieder der Aufbau
einer HIRES-Grafik, doch das sollte nun
auch kein Problem mehr für Sie sein.
Außerdem werden Sie auch noch ein
anständiges Stück vom Binärsystem benötigen, beziehungsweise Sie sollten mittlerweile vielleicht etwas geübter in der
Benutzung der logischen Operatoren von
BASIC sein, das hatten wir ja aber auch
schon, und somit kann ja nichts mehr
schief gehen. . .
Klären wir doch zunächst einmal, was
" HIRES" überhaupt bedeutet. HIRES ist
schlichtweg die Abkürzung für " HIgh RE-Solution" und das heißt nichts anderes
als " hohe Auflösung" . Sie haben also bei
einer HIRES-Grafik eine hohe Auflösung
zur Verfügung - genauer gesagt erstreckt
sich diese auf eine Ausdehnung von
320 x200 Punkten, oder Pixels, wie man
sie auch oft nennt. Dieses Feld von
Punkten wird vom Bildschirmrand eingerahmt. Das heißt also, daß wir mit Hilfe
des HIRES-Modus des C64 jeden einzelnen
Punkt auf dem Bildschirm seperat ansteuern können.
Doch wie geht das nun vor sich? Zunächst
einmal sollte ich vielleicht erwähnen, daß eine solche Grafik, wie die Sprites
auch, natürlich Speicherplatz benötigt.
Und das in verhältnismäßig gewaltigem
Maße! Wie Sie sich bestimmt denken
repräsentiert ein Grafikpunkt hier
natürlich auch ein Bit im Speicher des
64 ers, das hatten wir ja bei den Sprites ja auch scon, nun können Sie sich das ja
mal ausrechnen. Wir haben da
320*200=64000 Pixel, das ganze dividieren wir durch 8, weil ja ein Byte 8 Bit
hat, und so kommen wir auf 8000 Bytes
pro Grafik! Das macht schon ein Achtel
des Gesamtspeichers des 64 ers aus - Sie
sehen, die hohe Auflösung hat ihren
Preis.
Doch da gibt es noch ein riesengroßes
Problem für uns. Für die paar kleinen
Sprites aus den letzten beiden Kursteilen haben wir ja noch Speicherplatz gefunden, aber 8000 Bytes sind nicht mehr
so einfach dazischenzumogeln. Der ganze
Speicher des 64 ers ist ja schon komplett
für andere spezifische Aufgaben reserviert. Woher also nehmen, wenn nicht
stehlen? Genau das werden wir jetzt aber
tun müssen! Wir werden uns etwas Speicher von unserem 64 er " klauen" müssen, sonst is nix drin mit HIRES. Und das
geht folgendermaßen:
Das Betriebssystem hat ganz am Anfang des Speichers eine ganze Menge Speicherstellen für sich reserviert, in dem es
sich einige Zwischenergebnisse und Hintergrundinformationen " merkt" . Dort befinden sich auch zwei kleine Speicherzellen, die ihm die Startadresse des
Basicspeichers angeben. In der Fachsprache nennt man so etwas " Pointer", oder
auch " Zeiger"( ähnlich wie die Spritezeiger bei Sprites) . Nomalerweise liegtder Basicspeicher, wie ich auch schon im
fünften Teil des Basickurses erwähnte, ab Adresse 2048 . Der Trick, den wir nun
anwenden werden, ist schlichtweg der, daß wir dem Betriebssystem vorgaukeln, der Basicspeicher beginne weiter hinten, und schon können wir uns einen passenden
Speicherbereich für unsere Grafik reservieren. Aber Vorsicht! Wie bei den Sprites auch können wir uns da nicht jeden
Xbeliebigen Speicherberech rausgreifen.
Hiresgrafiken dürfen nämlich grundsätzlich nur bei Speicherstellen beginnen, die durch 8192 teilbar sind ( bei Sprites war der Teiler ja 64 . . .) . Demnach gibt
es also insgesamt 8 Bereiche, die in
Frage kämen, nämlich:
Nr. Von Bis
0 0 7999 1 8192 16191 2 16192 24191 3 24192 32191 4 32192 40191 5 40192 48191 6 48192 56191 7 56192 64191
Wir werden uns Bereich 1 wählen, aus 2 ganz bestimmten Gründen, die ich Ihnen
jetzt noch näher erklären möchte. Bereich 0 können wir ja vergessen, hier
sind ja wieder vorreserviete Funktionen
angelegt, die man tunlichst in Ruhe lassen sollte. Soviel hierzu. Jetzt zu den
Bereichen 2 bis 7 . Diese sind ja eigentlich auch alle in reservierten Berei- chen, aber es wäre auch hier denkbar
( über viele Tricks) sie " bebaubar" zu
machen. Das ist sogar sehr gut möglich
und wird auch von sehr vielen Programmen
eifrig praktiziert. Doch damit das einfacher geht, ist es meist sinnvoller das
Ganze in Assembler zu versuchen ( zu diesem Zweck können Sie ja einmal in den
Assemblerkurs reinschauen, der seit Januar parallel zu meinem hier läuft - eine echte Gelegenheit für Basicprofis
noch tiefer in die Materie einzusteigen), und dann gibt es da auch noch ein
internes Problem, das mit dem VIC zu tun
hat, was jedoch zuviel wäre jetzt hier
erwähnt zu werden.
Bereich 1 ist einfach am Besten, da
pflegeleicht und für uns leicht erreichbar.
Also dann wollen wir einmal den Basicspeicheranfang etwas höher setzen. Die
beiden Speicherstellen die ich eben
erwähnte belegen die Adressen 43 und 44 .
Der 64 er hat ja insgesamt 65535 Speicherstellen, was der 16- Bit-Zahl
"1111111111111111"(16 mal " Bit gesetzt") entspricht. Um eine Adresse innerhalb des Speichers für den Computer
darstellen zu können, brauchen wir also
immer 16 Bit, gleich 2 Byte. So auch bei
der Adresse des Basicanfangs ( daher auch
2 Speicherstellen!) . Die beiden Bytes, die wir benötigen, teilen sich auf in
ein sogenanntes " niederwertiges-" oder
" LOW-Byte" und in ein " höherwertiges" oder auch " HIGH-Byte" . In Adresse 43 ist
nun das LOWund in Adresse 44 das
HIGH-Byte des Basicanfangs gespeichert.
Lesen wir doch einfach einmal diese beiden Bytes aus, also:
PRINT PEEK(43),PEEK(44)
Auf dem Bildschirm sollten jetzt die
beiden Zahlen:
18
stehen.1 wäre also dann der Wert des
LOW-Bytes und 8 der des HIGH-Bytes. Setzen wir uns also unsere 16- Bit-Zahl aus
diesen beiden Bytes zusammen. Das höherwertige Byte kommt beim Schreiben der
Binärzahl nach " oben" also nach links, das niederwertige nach " untern" beziehungsweise nach rechts:
--> 00001000 00000001 =8(HIGH) =1(LOW) --> in dezimaler Schreibweise: 2↑11+2↑1=2049
Huch, das ist ja 2049 und nicht 2048, wo
ja eigentlich der Basicspeicher normalerweise beginnen sollte! Doch keine
Angst, es stimmt schon so, denn das Betriebssystem möchte mämlich hier die
" wahre" Anfangsadresse des Basicspeichers plus 1 stehen haben. Das 0 . Byte
dieses Bereichs wird noch zu einem anderen Zweck benutzt, wie wir gleich noch sehen werden. Möchten wir also beispielsweise den Anfang des Basicspeichers nach Adresse 20000 verschieben, so
müßten wir hier die Adresse 20001 angeben! Ok?
Zugegeben, das Prozedere, eine Adresse
zuerst einmal als Binärzahl zu schreiben, um sie dann in zwei Bytewerte umzurechnen ist relativ umständlich, deshalb
möchte ich Ihnen hier noch einen einfacherern Weg zeigen, wie ein solcher 2- Byte-Wert umgerechnet werden kann:
Das erste Bit des höherwertigen Bytes
hat ja in der 16- Bit-Schreibweise den
Dezimalwert 2↑8=256, da es ja das 8 . Bit
der 16- Bit-Zahl ist ( das Zweite 2↑9=512 etc.) . Demnach wäre also die niedrigste
Zahl, die ( ausschließlich) mit dem
HIGH-Byte dargestellt werden kann ( das
LOW-Byte hat also den Wert 0) die Zahl
256 . Demnach genügt es schlichtweg, die
absolute 8- Bit-Zahl des HIGH-Bytes mit
dem Wert 256 zu multiplizieren. Der Wert des LOW-Bytes bleibt erhalten und wird
einfach zu dem 256 fachen Wert des HIGH-Bytes hinzuaddiert, also:
--> HI*256+ LO= absolute Adresse --> Oder in unserem Beispiel:
8*256+1=2048+1=2049
Genauso geht es auch umgekehrt. Um das
HIGH-Byte eines absoluten Wertes zu ermitteln dividieren wir diesen durch 256 und nehmen den ganzzahligen Anteil des
Ergebnisses als HIGH-Byte ( also OHNE
Nachkommastellen, falls die Division
nicht aufgehen sollte) . Das LOW-Byte
wird nun ermittelt, indem wir das HIGH-Byte mit 256 multiplizieren und das Ergebnis von dem absoluten ( Anfangs-) Wert
subtrahieren. Das hört sich vielleicht
komplizierter an als es ist, der Einfachheit halber hier die Umrechnung als
kleines BASIC-Programm:
10 INPUT"Absoluter Wert (max. 65535)";WE 20 HI=INT(WE/256) 30 LO=WE-256*HI 40 PRINT "LOW-Byte : "LO 50 PRINT "HIGH-Byte: "HI
Starten Sie doch einmal dieses Programm
( auf der Vorderseite der MD unter dem
Namen " LO-HI- UMRECHNUNG") und geben Sie
einmal den Wert 2049 ein. Das Ergebnis
ist, wie erwartet, eine 1 für das LOWund eine 8 für das HIGH-Byte.
Doch nun wollen wir endlich einmal den
Speicher für unsere Grafik verschieben.
Wir hatten uns ja darauf geeinigt, daß
wir Bereich 1 hierfür beanspruchen wollen, der sich ja von 8192 bis 16191 erstreckt. Lassen wir also den neuen Basicspeicher bei Adresse 16192 beginnen.
Sie sollten übrigens bedenken, daß bei
einer Verschiebung der Anfangsadresse
des Basicspeichers nach hinten, dieser
natürlich an Länge verliert! Vorher erstreckte er sich ja von 2048 bis 40959,
und wir hatten somit 38911" BASIC BYTES
FREE"(=40959-2048) . Bei 16192 sind das
jetzt nur noch 24767 Bytes (=40959-16192) ! Deshalb sollten wir auch kein
Byte zuviel wegnehmen, wenn dies nicht
unbedingt erforderlich ist!
Bei 16192 soll nun also die neue Startadresse liegen. Zuerst müssen noch eine 1 hinzuaddieren, bevor wir die Zahl in
HIGHund LOW umrechnen können ( Sie
erinnern sich - in 43/44 muß die gewollte Adresse plus 1 stehen) . Also:
16192+1=16193 HIGH=INT(16193/256)=63 LOW=16193-63*256=16193-16128=65
Das LOW-Byte hat also den Wert 65, das
HIGH-Byte den Wert 63 . Nun noch schnell
etwas über das 0 . Byte des Basicspeichers ( bei uns das Byte mit der Adresse
16192) . Dieses dient quasi als " Kennmarke" für unseren 64 er, daß hier der Basicspeicher beginnt und muß deshalb IM- MER den Wert 0 enthalten, andernfalls
erkennt BASIC nicht mehr die Befehle
NEW, CLR und RUN als Basicbefehle an und
bricht mit einem " SYNTAX ERROR" ab! Deshalb also immer auch eine 0 in das nullte Byte des neuen Basicanfangs schreiben, also:
POKE 16192,0 :REM 0.Byte POKE 43,65 :REM LOW-Byte POKE 44,63 :REM HIGH-Byte
Das wars. Der Basicanfang ist nun verschoben, und der Bereich von 2048 bis
16191 geschützt, er kann von nun an also
nicht mehr von BASIC-Programmen überschrieben werden. Öbrigens kann es sein, daß da hinten im Speicher noch irgenwo
Datenmüll rumsteht, der ja eigentlich
kein richtiges BASIC-Programm mehr
repräsentiert. Gibt man LIST ein, so
versucht der 64 er doch noch was daraus
zu machen, was natürlich in einem riesigen Chaos endet, deshalb sollten Sie auf alle Fälle den Basicspeicher noch
zusätzlich initialisiern, indem Sie Ihn
mit NEW löschen, also:
NEW
Jetzt können Sie Ihr HIRES-Basic- Programm schreiben. Achten Sie allerdings bitte darauf, daß Sie dieses unbedingt mit einem ",8" abspeichern und vor
allem laden und nicht etwa mit ",8,1", denn dann wird das Programm nämlich absolut geladen. Wenn Sie es also abgespeichert haben, als der Basicanfang
noch bei 2048 lag, dann wird es auch
dort hingeladen. Bei einem ",8" lädt der
C64 es jedoch an den aktuellen Basicspeicheranfang, in unserem Fall also
16192 !
Im Öbrigen können Sie sich möglicherweise noch erinnern, daß ich bei den Sprites erwähnte, daß es da auch noch andere
Möglichkeiten gibt, Speicherplatz für Sprites zu schaffen. Genau das was wir
eben praktizierten meinte ich damit.
Verschieben Sie sich einfach den Basicspeicher etwas nach vorne, um noch Platz
für Sprites zu bekommen. Wenn Sie auch
noch gleichzeitig eine Grafik benutzen, dann haben Sie sowieso den Speicher von
2048 bis 8192 frei, genügend also, für
eine ganze Menge Sprites. . .
Welche Register des VIC Sie jetzt ansprechen müssen, um endlich mit dem Grafikbildschirm arbeiten zu können, werde
ich Ihnen dann nächsten Monat erklären.
Bis dahin " Gut Hack" und Servus.
(ub)
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 einmal 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ächsten 3 und so weiter. . .) . Leider kann
man dieses Verfahren nicht mehr so einfach auf die HIRES-Grafik übertragen.
Sie möchte anders behandelt werden, nämlich nicht nur zeilensondern auch
spaltenweise! Das hört sich ziemlich
kompliziert an, ist es aber gar nicht, wenn man sich das einmal bildlich klargemacht hat. Deshalb erst einmal eine
Grafik zur Erklärung.
Bitte Teil 2 laden!
Grafik-Kurs Teil 4 b
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 8 x8 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 ersten Zeile. . .
Auch in diesem 8 x8- 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 wieder ein Sprung in die erste Zeile - das nächste Byte stellt hier dann die Punkte
17 bis 24 im dritten 8 x8- Pixel-Block dar
und so fort. Bis wir dann am vierzigsten
und letzten 8 x8- 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 denken können wird das nun folgende Byte
8512 das erste Byte in der zweiten Bildschirmzeile 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 8 x8- 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 408 x8- Pixel-Blöcke
aufteilen! Zum Besseren Verständnis auch
diesmal noch eine Grafik.
Bitte Teil 3 laden!
Grafik-Kurs Teil 4 c
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 einund ausgeschaltet wird. Wenn Sie das
einmal können ( und das ist sehr einfach), 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. Wiedereinmal handelt es sich hierbei um ein
paar POKEs, mit denen wir einige Register 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 kommen) können wir hier nämlich den Grafik- modus einschalten. Bit 5 dieses Registers ist hierfür zuständig. Ist es
gelöscht (= Binär 0), so ist der Grafikmodus 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 dezimalwert 32, also:
POKE V+17,PEEK(V+17) OR 32
Analog müssen wir es zum Ausschalten
wieder löschen. Dies geht entweder, indem man direkt das Komplement von 32 bildet (255-32=223) und es dann mit Hilfe des AND-Operators mit Register 17 verknüpft; oder man kombiniert ganz einfach 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 initialisiert ( also: V=53248) haben - das hatten wir ja auch schon im ersten Teil des
Grafikkurses.
Soviel zum Einschalten des Grafikbildschirms. Doch das ist leider noch nicht
alles. Um nämlich wirklich den Speicherbereich von 8192 bis 16191 auf dem Bildschirm 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 Grafikmodus 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 Grafikchip unseres 64 ers, daß er den Speicherbereich 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) sehen 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 Buchstaben mehr auf dem Bildschirm an ( das hat
etwas mit der schon erwähnten zweiten
Funktion des 3 . Bits zu tun) . Zum Ausschalten 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 Grafikmodus des VIC aktivieren. Sie sollten
jetzt - bei frisch eingeschaltetem 64 er
- einen Haufen wirre Punkte auf dem
Bildschirm sehen. Falls Sie übrigens
vorher irgendein Spiel, oder Grafikprogramm geladen hatten ( und mit einem RE-SET ausgestiegen sind - ohne den Rechner
also abzuschalten), so kann es sein, daß
sie sogar eine Titelgrafik oder ähnliches 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 Bildschirm 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 denselben Wert benutzten, der hier schon
beinhaltet war, dann sollten Sie erkennen, 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 Buchstaben gespeichert sind, die Sie im Normalmodus sehen, im Grafikmodus als Farbspeicher für die einzelnen Punkte fungiert. Löschen Sie doch einfach einmal
den Bildschirmspeicher mit SHIFT-CLR/ HOME. Jetzt sollten Sie alle Grafikpunkte in der selben Farbe sehen. Wenn
Sie jetzt einmal ein paar Worte eingeben, 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 nocheinmal 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 erstreckt. 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 gleichzeitig darstellen. Klingelts bei Ihnen?
Genau! Jede Speicherstelle des Bildschirmspeichers 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 Zeichen auf dem Bildschirm darzustellen. Er
überprüft in regelmäßigen Abständen, was
in diesem Speicherbereich an Daten abgespeichert 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 verschiedensten 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 64 ers 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ürfen ( 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 verschiedene Werte schreiben. . .
Jetzt wissen Sie auch, wie die Buchstaben von den Tasten Ihrer Tastatur auf
den Bildschirm kommen. Intern fragt das
Betriebssystem nämlich ständig die Tastatur ab, ob Sie nicht gerade eine Taste 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 Videosignal für Fernseher oder Monitor umsetzt, so daß er schließlich und endlich auf
selbigem erscheint. . .
Doch kehren wir von den Interna des
64 ers zurück zu unserer Grafik:
Der Bildschirmspeicher dient also normalerweise 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
64 ers brach liegen benutzt VIC sie dazu, den Punkten im Grafikmodus eine Farbe zu
geben ( sieht doch viel besser aus!) .
Jede Speicherstelle des Bildschirmspeichers kann nun genutzt werden, um einem
8 x8- Pixel-Block gewisse Farbinformationen zu geben ( aha! also doch kein Zufall
mit den 25 x40 Zeichen. . .) . Hierbei
bleibt die Zeilen-Spalten- Struktur des
Bildschirmspeichers voll und ganz erhal- ten!
Die eigentliche Farbinformation in einem
solchen 8 x8- Pixel-Block teilt sich nun
in 2 Komponenten, nämlich in Vorderund
Hintergrundfarbe, auf. Wie Sie ja wissen, kann der 64 er insgesamt 16 verschiedene 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 Hintergrundfarbe wird in den Bits 0-3 untegebracht, der für die Vordergrundfarbe in
den Bits 4-7 . Zunächst jedoch noch einmal die Farbtabelle ( ich hatte sie auch
schon einmal bei den Sprites aufgelistet), damit Sie die Farbwerte auch wieder 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 Hintergrundfarbe auf " Grün" und die Vordergrundfarbe 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 Vordergrundfarbe ( in den " höherwertigen" Bits 4-7) mit
16 multiplizieren und den Hintergrund- farbwert einfach hinzuaddieren ( auch
dies hatten wir schon an früherer Stelle) :
16*9+5=149
Schreiben Sie nun diesen Wert in die
erste Speicherstelle des Bildschirmspeichers ( nämlich. . . na? . . . richtig!-1024), so werden im ersten 8 x8- 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 Bildschirmspeicherzelle.
Soviel zur Farbgebung der Grafik. Kommen
wir nun noch einmal zurück zu den einzelnen 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 Grafikbildschirm 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 denkbar 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 00000000, 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 Programm " 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 8 x8- Pixel wieder die nächsten 8 x8- 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 Farbgebung zusammenhängt. Sollten Sie nicht
mehr so genau wissen, was ich damit meine, dann sollten Sie noch einmal einen
Blick in den zweiten Teil des Grafikkurses - MD64, Ausgabe 1/90- werfen, dort
steht alles noch einmal genau erklärt, nur halt im Rahmen der Spriteprogrammierung.
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 Farbquellen:
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 Hintergrundfarbregister des VIC ( Nr.32-->53280) wieder von Bedeutung. Bei allen nichtgesetzten 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 Bitmusterliste. Wenn die beiden Informationsgebenden 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 geschriebenen Buchstaben ebenfalls. Schalten 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 haben. 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 gespeichert 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 Zeichen 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 Zusammenhang mit der Multicolorgrafik. Der
Farbwert, der im Farbram gespeichert
ist, ist maßgebend für alle "11" kombinationen in dem 8 x8- Pixel-Block, für den
er zuständig ist ( ebenso wie Lowund
Highnibble des Bildschirmspeichers) .
Jetzt noch zum Einschalten des Multicolor- Grafikbildschirms. Diesmal müssen
wir ebenfalls lediglich ein Bit eines
VIC-Registers setzen, um ihn zu veranlassen, die Grafikinformationen in der
Multicolorweise darzustellen. Genau gesagt handelt es sich um Bit 4 des Registers 22( Adresse 53270) . Die ensprechenden Befehle zum Einund 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. Experimentieren Sie doch einfach einmal
ein wenig mit dem Grafikbildschirm des
64 ers 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 Zeichensatzprogrammierung 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 anzulehnen) 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 64 ers widmen, der Zeichensatzprogrammierung.
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 geschnitten. 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 Zeichensatzes ist sogar derart flexibel, daß man
unter Umständen ganze HIRESund Multicolorgrafikbildschirme in einem Zeichensatz unterbringen kann, um so eine Grafik zu " simulieren" . Das hat manchmal so
seine Vorteile. Beispielsweise der, daß
ein Zeichensatz mit weniger Rechenaufwand animiert werden kann, als eine Grafikseite. Als Beispiel ist hier vorzüglich der große " MAGIC DISK 64"- Schriftzug in der Intro einer jeden MD
geeignet. Das hochund runterwackeln
dieses Grafikobjektes ist als Grafikbildschirm nur schwer, wenn überhaupt
gar nicht, so flüssig und schnell wie
hier zu realisieren.40 Zeichen umkopieren geht halt schneller, als 320 Datenbytes ( 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 Thema etwas weiter nach Hinten verschieben.
Zunächst einmal zu den " elementaren" Grundlagen der Zeichensatzprogrammierung. 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 hatten damals geklärt, daß dieser Speicherbereich von Adresse 1024 bis 2023 zuständig dafür ist, welches Zeichen wo
auf dem Bildschirm zu stehen hat. Hierbei gab es für jedes der 256 Zeichen des
64 ers 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, welcher Code darin steht und dann das ent- sprechende Zeichen in ein Monitoroder
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 umgedrehtes " M" und so weiter. Nun diese
Informationen müssen natürlich wie alles, was mit Grafik zu tun hat irgendwo
in unserem 64 er als Zeichendaten gespeichert 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 weiter ausholen und Ihnen den genauen Speicheraufbau des 64 ers erklären. Ich hatte
ja schon einmal im Basickurs darüber
gesprochen, wobei ich jedoch lediglich
erwähnte, daß es insgesamt 65536 Speicherzellen 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 verschiedenen Bereiche werden vielmehr in
das " Sichtfeld" des Prozessors " eingespiegelt", wenn sie benötigt werden. Man
könnte sich den Speicher des 64 er auch
als ein Hochhaus mit mehreren Stockwerken vorstellen. Will der Prozessor ganz
bestimmte Daten, so muß er in ein bestimmtes 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 Zeichendaten. 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 Zeichensatz 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 hatten Sie ja gelernt, wie man sich Speicherplatz für große Datenmengen reserviert ( nämlich indem man den Basicanfang
verschiebt) . Für einen Zeichensatz benötigen wir ja 4 KiloByte, also 4096 Bytes
(1 KB=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ünglichen Zeichensatz nun also ändern wollen, 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 Speicheraufbau des 64 ers 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 innerhalb unseres kleinen Freundes bekannt
machen, der Speicherstelle 1 . Diese hat
wegen ihrer Wichtigkeit sogar einen eigenen Namen, nämlich " Prozessorport" .
Öber diese Speicherstelle haben wir die
Kontrolle über bestimmte Funktionen und
Modi des Prozessors des 64 ers. 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 Prozessor erreichbar sind, und welche nicht.
Zu diesem Zweck gleich nochmal eine Grafik:
Bitte laden Sie den 3 . Teil des Kurses.
Grafikkurs Teil 3
Sie sehen in dieser Grafik, welche der
Bitkombinationen welche Speicheraufteilung 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 schreiben 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 Ausblenden 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 Assemblerprogrammier 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 ausblenden, 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öglichen Absturz des Rechners zu verhindern
müssen wir auch noch den System-Interrupt abschalten. Dies ist eine Einrichtung 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ährleistet, da der Ein-Ausgabebereich des
Speichers ja abgeschaltet ist. Der Interrupt ( 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 Rechnerabsturz zur Folge. Öber den Interrupt ansich 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 zeigen, wie man den IRQ einund ausschaltet. Dies geht wie immer über den POKE-Befehl. Die entsprechenden Befehle lauten:
POKE 56334,PEEK(56334) AND 254 zum einschalten, und POKE 56334,PEEK(56334) OR 1
Nun also zu dem Programm, daß den Zeichensatz aus dem Zeichensatz-ROM ins RAM
von 8192-12288 kopiert. Ich habe es Ihnen 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 laufen, nach einiger ( sogar sehr langer) Zeit meldet sich der 64 er 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 Programm abbrechen - so hat es den anschein, als würde der Rechner " schlafen" . 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 Zeichensatz endlich im RAM liegt zu dessen
Veränderung.
Ein Zeichen, so wie Sie es auf dem Bildschirm sehen können, ist aus einer
Punktmatrix von 8 x8- Pixeln aufgebaut.
Diese werden durch 8 aufeinanderfolgende
Bytes zu je 8 Bit repräsentiert ( wie das
vor sich geht sollten Sie nun ja mittlerweile 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 anstelle des alten auf dem Bildschirm stehen. 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 verschiedene Möglichkeiten gibt. Hier einmal 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 dieser Liste von Bedeutung, denn er adressiert den Bereich, in dem wir unseren
neuen Zeichensatz abgelegt haben. Setzen
wir also die unteren vier Bits von Register 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 eingestellt. 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 Klammeraffe "" . Schreiben Sie doch einmal ein
solches Zeichen irgendwo auf den Bildschirm. 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 Klammeraffe oben deutlich abgeflacht wurde.
Verändern Sie auch noch das nächste Byte, so wird er sich immer mehr entstellen. Probieren Sie was sich so alles
damit anstellen läßt. Sie wissen ja
mittlerweile, daß jeweils ein Bit einer
Speicherstelle einen Punkt in einer Zeile 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 Zeichensätze, wie sie in manchen Spielen, oder in einem der zahlreichen Demo-Creator- Programme der MagicDisk vorhanden sind.
Nun noch ein wenig über den Aufbau eines
Zeichensatzes. Die Zeichen ansich,256 an der Zahl, sind 8- Byte-Weise hintereinander im Speicher abgelegt. Das wissen
wir ja schon. Da ein Zeichen 8 Byte belegt, müßte ein Zeichensatz also 8*256 Bytes lang sein, das sind insgesamt allerdings 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 Zeichensatz 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 Zeichensä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 Grafikzeichen 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 sichtbaren Zeichensatz aus!
Soviel hierzu. Jetzt noch ein Wort zu
der Lage von bestimmten Zeichen innerhalb eines Zeichensatzes. Zu diesem Zweck habe ich Ihnen ein weiteres Programm 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 Punktmatrix aussieht. Die Zeichen von 0 bis 255 entsprechen hierbei dem " Groß/ Grafik"- Zeichensatz, die von 256 bis 511 dem
" Kleinschrift"- Zeichensatz. Die Reihenfolge entspricht übrigens der der Bildschirmcodes, 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 Bildschirm 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 64 ers zurückgreifen. 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 adressieren (= 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 diesen 16 K-Bereich des VIC umzuschalten auf
folgende 16 K-Bereiche, doch hierzu an
späterer Stelle mehr. Im Normalfall arbeitet der VIC also in den ersten 16 K
des Speichers. Das Zeichensatz-ROM befindet sich nun aber in den letzten 16 K, womit sich ein Problem ergibt - denn wie
soll der VIC den auf diesen Bereich zugreifen 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 Zeichensatz- Bereich eines jeden 16 K-Blocks eingespiegelt. 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 Inhalte der entsprechenden RAM-Adressen an
dieser Stelle. Der VIC sieht hier jedoch
den ROM-Zeichensatz, weshalb dieser Bereich 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 Zeichensatzbereichsliste von oben repräsentativ für
das Zeichensatz-ROM. Schalten wir also
diesen Bereich ein, so erhalten wir wieder 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 16 K nicht so recht verstanden haben, dann macht das auch nichts.
Hauptsache, Sie wissen, wie man den Zeichensatz wieder in den Grundzustand
bringt. Das Thema mit der Adressierung
des VICs werden wir nächsten Monat sowieso 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 durchgehen möchten, in dem es dann um noch einige 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 Zeichensatzprogrammierung 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 diesen im Speicher ablegt, wie man ihn einschaltet, 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 Multicolor- Zeichensatz, der ähnlich wie die Multicolor-Grafik funktioniert. Sie können diesen Modus durch Setzen des 4 .
Bits in Register 22 des VIC einschalten.
Wie Sie sehen ist dies übrigens das selbe Bit, wie beim HIRES-Multicolormodus, woraus sich auch eine gewisse Verwandschaft 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 Hintergrundfarbregister des VIC. Diese sind die
Register 33,34 und 35( das vierte ist
Register 36, wird jedoch hier nicht benutzt) . 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 entsprechenden 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 innerhalb 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 haben hier also 3 Bits, in denen wir die
Farbe für die "11"- Bitkombination angeben können. Somit haben wir die Möglichkeit nur schlappe 8 Farben für diese
Multicolorfarbe festzulegen, anstelle
der sonst 16 möglichen. Zugegeben - ein
Nachteil, jedoch wird diese Einschränkung 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 miteinander zu kombinieren, so daß sie im
oberen Teil des Bildschirms beispielsweise eine kleine Grafik darstellen können, zusammengesetzt aus Multicolorzeichen, und im unteren Teil des Bildschirms 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 Multicolordarstellung jenes Zeichens aktiviert, ist es jedoch gelöscht, so wird
das Zeichen in ganz normaler Darstellung
angezeigt. Experimentieren Sie doch einmal ein wenig mit dem Multicolorzeichensatz; 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 Bildschirmspeichers), mit der Nummer 55296 .
Das Zeichen sollte nun in Weiß und normaler Auflösung dort erscheinen. Schreiben Sie jetzt eine 9 in die Farbadresse
des Zeichens, so wird es in Multicolordarstellung 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 Farbtabelle 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 Hintergrundfarben Modus", und genau das ist es
was dieser Modus bewirkt. Durch das Einschalten dieses Modus schrumpft der Darstellbare Zeichensatz von 256 Zeichen
auf genau ein Viertel, nämlich 64 Zeichen zusammen. Diese 64 Zeichen können
nun jedoch in 4 verschiedenen Hintergrundfarben dargestellt werden. Diese
Farben werden wie beim Multicolormodus
in den 4 Hintergrundfarbregistern ( Register 33-36) des VIC festgelegt. Das dargestellte Zeichen selbst erscheint in
der Farbe der entsprechenden Farbramadresse 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 beschriebene Funktion des VIC erläutert.
Jetzt jedoch noch zu weiteren Einzelheiten des " Extended Background Color Mode"
( im weiteren EBC-Modus) . Zunächst einmal
die Befehle zum Einund 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 Bildschirmcodes von 0 bis 63 . Der Unterschied, in welcher Hintergrundfarbe ein
Zeichen nun dargestellt wird, besteht in
den Bildschirmcodes im Bildschirmspeicher. Die Codes 0-63 lassen die entsprechenden Zeichen mit der Hintergrundfarbe
aus Farbregister 0(= VIC-Register 33) erscheinen. Die Codes 64-127 die zeigen DIESELBEN Zeichen, jedoch mit der Hintergrundfarbe 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 entsprechen die Bildschirmcodes 1+1*64=65,1+2*64=129 und 1+3*64=193 jedoch ebenfalls dem Buchstaben " A", allerdings mit
dem Unterschied, daß der Buchstabe jeweils in verschiedenen Hintergrundfarben
erscheint. Um also den enstprechenden
EBC-Bildschirmcode eines Zeichens zu
ermitteln, braucht man lediglich zu dem
absoluten Bildschirmcodes dieses Zeichens 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 Feinheiten des VIC erklären, mit denen sich
schöne Effekte erzielen lassen. Im Einzelnen 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, jedoch befinden sich in diesen beiden Registern noch einige Bits, die wir noch
nicht kennen, mit denen wir jedoch ungeanhte Möglichkeiten aus dem VIC rausholen 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 abgehandelt, 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 diesem hier läuft) .
Bit 4 hat eine ziemlich einfache Bedeutung, die ich am Besten gleich an den
Mann bringe. Mit diesem Bit kann man, wie aus der Grafik eben schon ersichtlich, der Bildschirm schlichtweg einund ausgeschaltet werden. Im Klartext
heißt das, daß wenn Sie dieses Bit setzen, 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 Bildschirmspeicher verändern, nur wird das erst sichtbar, 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
64 ers nun nicht mehr beim Zugriff auf
den Speicher stört ( hat was mit dem Aufbau von Computern allgemeinhin zu tun.
In aller Regel kann nämlich nicht mehr
als EIN Chip gleichzitig auf den verfügbaren 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 Microsekunden 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. Kopierprogramme) wird etwa 15%( !) schneller gearbeitet 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 Beispiel an komplizierte Grafikberechnungen, 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 verbessern können. Angenommen Sie hätten ein
Programm, das noch langwierig im Bildschirmspeicher 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 Steuerregister. 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 Register. Mit Ihnen können wir den Bildschirm, relativ zu der Normalsarstellung," verkleinern" . Bit 3 aus Steuerregister 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 entsprechende 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ändig 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 bezeichnet. 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 verschieben. Probieren Sie doch einmal aus, was geschieht, wenn Sie verschiedene
Werte in diese unteren 3 Bits hineinschreiben. Der Rest des Registers sollte
natürlich unverändert bleiben, um unangenehme 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 kennengelernten Bits zur Bildschirmmanipulation einen sogenannten " SoftScroll" realisieren. Dies ist das weiche Schieben des
Bildschirms nach links, rechts, oben
oder unten, wie Sie es aus manchen Spielen kennen ( klassisches Beispiel ist
wohl der schon uralte Megahit " Uridium") . Dies funktioniert denkbar einfach: zunächst wird der Bildschirm in
der entsprechenden Scrollrichtung verkleinert. Als Beispiel nehme ich hier
einmal einen Softscroll nach links. Demnach müssen wir die Spaltenzahl verkürzen 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 nichtsichtbare Zeichen in den Bildschirm " 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 Durchgang, 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 Umkopieren der Zeichen dauert zu lange, so daß
der Scroll " zittert" . So etwas ist wirklich 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 Anwendung, 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 wakkeln würde? Nichts einfacher als das, wir müssen lediglich ein paar Zufallswerte 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 Demonstationen.
Nun noch ein paar Worte zum Speicherhandling des VIC. Wie ich Ihnen ja schon
im Grafikkurs Teil 5 erzählte kann der
VIC lediglich 16 KByte Speicher adressiere. Im Normalfall belegt er den Speicher von Adresse 0 bis 16383, was zur
Folge hatte, daß wir Grafikdaten immer
nur in diesem Bereich untergebracht haben. Dies brachte jedoch häufig Schwierigkeiten 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 Speicherbereich eines weiteren Bausteins des
64 ers, 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 Kombinationen:
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 Grafikfunktionen verschieben sich somit nämlich ebenfalls um 16 KB! Das heißt im
Klartext, daß beispielsweise der Bildschirmspeicher 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 liegen die möglichen Grafikbereiche jetzt
bei 0+16384=16384 und 8192+16384=24576 !
Nun noch zu einem Thema, das uns ebenfalls aus Speicherplatzgründen sehr
nützlich ist. Es gibt nämlich auch die Möglichkeit, die Basisadresse des Bildschirmspeichers innerhalb des 16 KB-Bereichs des VIC zu verschieben. Das hat
den Vorteil, daß man sehr schnell zwischen 2 Bildschirmen hinund herschalten kann, oder aber auch, daß man die
Farbdaten einer Grafik an einer anderen
Stelle ablegen kann, wenn man den normalen Bildschirmspeicher für andere Dinge
nutzen möchte. Dies ist ein denkbar einfacher Vorgang. Die Bits 4-7 aus Register 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 64 ers ebenfalls wissen muß, wo sich der neue Bildschirmspeicher 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 anderen 16 K-Bereich verschieben. Bedenken
Sie, daß Sie ja auch den Bildschirmspeicher 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 normalerweise 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 wenig Spaß gemacht und daß jetzt der VIC
in Ihrem 64 er heißlaufen wird. In nächster Zukunft ist für mich hier kein Kurs
mehr geplant, deshalb verabschiede ich
mich bis auf weiteres von Ihnen - Servus Ihr Uli Basters