Hallo Besucher, der Thread wurde 1,5k mal aufgerufen und enthält 9 Antworten

letzter Beitrag von BIF am

Grafikzeichen in BASIC umdefinieren (Beispielprogramm)

  • Servus,


    ausgehend von einer Frage in einer C64-Facebook-Gruppe habe ich dieses kleine Programm hier gebastelt, welches demonstriert, wie sich in BASIC Grafikzeichen umdefinieren lassen. Da hier vielleicht auch einige anwesend sind, die das interessieren koennte, habe ich mich dazu entschieden das ganze hier auch mal vorzustellen.


    Das Programm koennt ihr einfach kopieren und in VICE einfuegen, VICE bietet naemlich eine sehr tolle Einfuege-Option an, was ich selbst auch erst seit geraumer Zeit kenne aber inzwischen sehr zu schaetzen weiss :) also fuer den Anfang am besten einfach mal alles markieren, kopieren, und in VICE einfuegen und anschliessend "RUN" eingeben und ihr solltet nach einigen Sekunden (dauert schon ein bisschen) ein kleines Gesicht auf einer Mauer sehen koennen.


    Nun zur Erklaerung, was in diesem Programm vor sich geht. Generell erstmal zum Thema "Zeichen umdefinieren": So einfach ist das naemlich gar nicht moeglich, da sich die Zeichendefinitionen im sog. "Character ROM" befinden, wo wir leider nicht hineinschreiben koennen (ROM = read only memory). Was wir jedoch machen koennen, ist, dass wir dem C64 sagen, er soll die Zeichendefinition von einem anderen Ort lesen, naemlich von einer Stelle im RAM (= random access memory, hier kann auch geschrieben werden).


    Wenn wir dies jedoch tun, haben wir das Problem, dass wir es an dieser Stelle zunaechst mit einem leeren Speicherbereich zu tun haben, d.h. dort sind ja von Beginn an gar keine Zeichen hinterlegt. Daher muessen wir als allererstes alle vorhandenen Zeichen dort hineinkopieren. Anschliessend beginnen wir damit, ein paar dieser Zeichen zu ueberschreiben.


    Mit dem folgenden simplen Programm koennen wir auf sehr einfache Weise einmal alle vorhandenen Zeichen auf dem Bildschirm ausgeben, dies dient nur dem besseren Verstaendnis:


    Code
    1. 10 for i=0 to 255
    2. 20 poke 1024+i, i
    3. 30 next i


    Wenn wir dies ausfuehren, sehen wir auf dem Bildschirm alle moeglichen Zeichen des Character ROM. Hier sieht man auch, dass die invertierten Zeichen ebenfalls gespeichert sind, diese werden also nicht vom C64 selbst invertiert sondern sind tatsaechlich im Character ROM hinterlegt.


    Nun zurueck zu unserem eigentlichen Vorhaben. Wir muessen also wie gesagt alle diese Zeichen (bzw. das Aussehen dieser Zeichen) in einen anderen Speicherbereich kopieren. Dazu muessen wir zunaechst das Character ROM sichtbar machen (denn normalerweise koennen wir da nicht mal lesend hineinschauen) und wir muessen die Interrupts ausschalten. Darauf gehe ich jetzt nicht naeher ein, wir machen es einfach. Das Abschalten des Interrupts geschieht in Zeile 30, das Sichtbarmachen des Character ROM in Zeile 40. Nun muessen wir 256 Zeichen kopieren, wobei jedes Zeichen aus 8 Byte besteht, daher 256*8 Byte. Diese kopieren wir vom Character ROM, welches bei 53248 liegt ($D000 hexadezimal), in unseren neuen Zielbereich, welcher bei 14336 beginnt ($3800 hexadezimal). Als moegliche Zielbereiche gibt es nur eine handvoll an Auswahl, aber wir wollen hier jetzt nicht zu sehr ins Detail gehen und waehlen daher $3800. Das Kopieren der 256*8 Byte passiert in den Zeilen 60-80. Anschliessend wir das Character ROM wieder unsichtbar gemacht (Zeile 90) und die Interrupts werden wieder eingeschaltet (Zeile 100). Zu guter Letzt wird nun dem C64 gesagt, dass er von jetzt an nicht mehr die Zeichen aus dem Character ROM verwenden soll, sondern die kopierten ab $3800. Dies passiert in Zeile 110. Auch hier werde ich nicht naeher drauf eingehen, wer es genau wissen will, sollte sich einmal den folgenden Speicherbelegungsplan ansehen: http://sta.c64.org/cbm64mem.html


    Nun haben wir also das Basis-Setup. Fuer den Nutzer aendert sich scheinbar nichts, denn wir haben die Zeichen ja kopiert und somit sieht unser C64-Bildschirm nach wie vor gleich aus. Im Inneren werden die Zeichen nun aber wie gesagt von einer anderen Stelle gelesen, und dort koennen wir jetzt auch eigene Zeichen definieren.


    Es gibt von dem Programm 2 Varianten, die erste ist die kompaktere (und schnellere), hier muessen die Zeichendefinitionen jedoch in Form von fertig umgerechneten Werten bereits vorliegen. Wer nicht weiss, wie das geht, kann sich auch die Variante 2 anschauen, dort sind die beiden Zeichen, die wir umdefinieren, im Code "lesbar" und koennen beliebig gestaltet werden (siehe Zeilen 140 und 160).


    Wir definieren nun zwei neue Zeichen, ein Gesicht und eine Mauer. Das Gesicht legen wir auf das grosse "F" (F wie Face), und die Mauer auf das grosse "W" (W wie Wall). Da wir ja auf dem C64 ueblicherweise sowieso nur Grossbuchstaben verwenden, sind auf dem grossen F und grossen W ja vorher bereits schon Grafikzeichen abgelegt (wenn man Shift+F und Shift+W drueckt, sieht man das). Wir ueberschreiben also nun nicht die Buchstaben sondern diese beiden Grafikzeichen.


    Die Routine, die diese Zeichen ueberschreibt, befindet sich in beiden Varianten des Programms ab Zeile 400. In der zweiten Variante ist diese natuerlich etwas komplexer, da sie die Byte-Werte fuer die Zeichen erst noch umrechnen muss. Die Routine wird in den Zeilen ab 200 aufgerufen. Hier wird der Zeichencode, welches ueberschrieben werden soll, in der Variablen "c" abgelegt (70 steht fuer das grosse F, 87 fuer das grosse W) und dann per GOSUB die Zeichen-Ueberschreib-Routine aufgerufen.


    Zu guter Letzt werden unsere neuen Zeichen dann auch auf dem Bildschirm ausgegeben (ab Zeile 300). Wenn das Programm durchgelaufen ist, koennt ihr auch direkt auf dem C64-Bildschirm mithilfe von Shift+F und Shift+W diese neuen Zeichen setzen, als waeren diese fest im C64 vorhanden. Ihr koennt auch verschieden Farben verwenden usw, alles wie mit den gewoehnlichen Grafikzeichen auch. Und wenn ihr nun LIST eingebt, seht ihr sogar im Code ab Zeile 300 diese Zeichen, anstelle der vorherigen C64-Grafikzeichen :)


    Ich hoffe ihr habt ein bisschen Spass mit diesem Programm und koennt ein bisschen was lernen. Klar, auf alles bin ich jetzt nicht im Detail eingegangen, aber vielleicht hilft es ja ein wenig als Grundgeruest.


    Und denkt dran, ihr koennt die Programme so wie sie sind einfach in VICE rein-pasten :)


    Viel Spass damit!


    Variante 1:


    Variante 2:

  • Wichtiger Hinweis noch: Wenn ihr den Code in VICE einfuegt, muesst ihr in der letzten Zeile noch RETURN druecken, sonst ist diese nicht Teil des Programms :) und dann einfach RUN eingeben...

  • Und noch eine kleine Preisfrage: Wenn ihr den Cursor auf eines unserer Zeichen bewegt, welches sich nun auf dem Bildschirm befindet, dann werdet ihr sehen, dass es beim blinkenden Cursor anders aussieht. Wer kann mir korrekt beantworten, warum das so ist :)

  • Und noch eine kleine Preisfrage: Wenn ihr den Cursor auf eines unserer Zeichen bewegt, welches sich nun auf dem Bildschirm befindet, dann werdet ihr sehen, dass es beim blinkenden Cursor anders aussieht. Wer kann mir korrekt beantworten, warum das so ist :)

    Soll ich antworten? ^^
    Du hast das invertierte Zeichen nicht verändert. Daher ist dort immer noch das Original nur invertiert. :D


    Im übrigen Empfehle ich für das Kopieren der Zeichen aus dem ROM ins RAM eine kleine Assemblerroutine zu verwenden. Ich kann sie hier ja gern posten, wenn gewünscht.

  • Hab den Code glaube vom C64 Wiki oder so:


    Code
    1. 1 fora=0to57:readb:poke828+a,b:next:sys828:poke53272,peek(53272)and240or12
    2. 2 data120,173,14,220,41,254,141,14,220,165,1,41,251,133,1,169,0,160,208,133
    3. 3 data95,132,96,169,0,160,224,133,90,132,91,169,0,160,64,133,88,132,89
    4. 4 data32,191,163,165,1,9,4,133,1,173,14,220,9,1,141,14,220,88,96

    Hier kopiert die Routine den Zeichensatz aus dem ROM nach $3000 bzw. 12288 und aktiviert diesen.

  • Hier noch eine Variante wo man beim Kopieren der Zeichen (und auch beim Erstellen der neuen Zeichen) zugucken kann:


  • nochmal etwas verfeinert:


  • Hallo, hier ein Programm, mit dem man schnell Zeichen ändern kann.
    Das Basic-,Zeichen- und Kernal-Rom wird hierbei mit nur einer Kopieraktion ins RAM kopiert.




    QUELLCODE:

    • 150 :rem--rom/ram,bild:52224,satz:53248
    • 151 poke56334,0:poke1,51:fori=88to91:pokei,0:next:poke781,97:poke782,.:sys41971
    • 152 :poke53248+32*8+6,16
    • 153 poke1,53:poke56334,1:poke648,204:sys58692:poke53272,52:poke56576,196:return


    Schönen Gruß.