Magic Disk 64

home to index to text: KURS-GRAFIKKURS.txt
          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.

MD8912/MD8912-KURSE-GRAFIKKURS_TEIL_1-2.koala.png
           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.

MD8912/MD8912-KURSE-GRAFIKKURS_TEIL_1-3.koala.png
           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 !

MD8912/MD8912-KURSE-GRAFIKKURS_TEIL_1-4.koala.png
           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 !

MD8912/MD8912-KURSE-GRAFIKKURS_TEIL_1-5.koala.png
           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:

MD9001/MD9001-KURSE-GRAFIKKURS_TEIL_2-2.koala.png

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. . .

MD9001/MD9001-KURSE-GRAFIKKURS_TEIL_2-3.koala.png

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:

MD9001/MD9001-KURSE-GRAFIKKURS_TEIL_2-4.koala.png

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!

MD9003/MD9003-KURSE-GRAFIKKURS_TEIL_4-2.koala.png

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!

MD9003/MD9003-KURSE-GRAFIKKURS_TEIL_4-3.koala.png

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.

MD9004/MD9004-KURSE-GRAFIKKURS_TEIL_5-2.koala.png
           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.

MD9004/MD9004-KURSE-GRAFIKKURS_TEIL_5-3.koala.png
           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. . .

MD9005/MD9005-KURSE-GRAFIKKURS_TEIL_6-2.koala.png

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. . .

MD9005/MD9005-KURSE-GRAFIKKURS_TEIL_6-3.koala.png

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. . .

MD9005/MD9005-KURSE-GRAFIKKURS_TEIL_6-4.koala.png

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

Valid HTML 4.0 Transitional Valid CSS!