Hello, Guest the thread was called2.8k times and contains 64 replays

last post from ivettaB at the

BASIC-Programm überschreibt Zeichensatz

  • Hellö mal wieder,


    ich habe hier ein BASIC-Programm mit eigenem Zeichensatz. Dessen Definition startet bei 14336 = $3800. Dazu poke ich in 53272 den Wert 30 = $1E rein. Das klappt auch alles wunderbar, solange das BASIC-Programm klein ist. Nun habe ich aber eine Menge Zeilen hinzugefügt, so dass offenbar der Zeichensatz überschrieben wird. Sieht grauslich aus. Leider ist $1E der größte Wert, den ich in 53272 reinschreiben kann. Mich düngt, um mein Problem zu lösen muss ich den Grafikspeicher verschieben. Dazu folgende Fragen:


    1. Wie mache ich das und wohin schiebe ich den am besten?

    2. Wenn ich das gemacht habe, was poke ich dann in 53272?


    Vielen Dank im Voraus für eure Antworten.

  • Am Besten ist der letzte 16K-Block ab 49152, weil der hinter BASIC-Arbeitsspeicher und BASIC-ROM liegt und normalerweise in BASIC gar nicht benutzt wird.


    Den VIC auf den richtigen 16K-Speicher-Block zugreifen zu lassen ist Aufgabe der CIA 2, Adresse 56576. Dann müssen wir noch festlegen, wo in diesen 16K der Bildschirm liegt (muss in den ersten 4K sein, danach kommt ROM bzw. I/O) und wo der Zeichensatz liegt - das macht das VIC-Register 53272. Außerdem musst du dem Betriebssystem noch mitteilen, wo der Bildschirm liegt - schließlich sollen ja deine PRINT-Befehle den Text auch in den richtigen Speicherbereich schreiben.


    Code
    1. poke 56576,0: rem Speicherbank 3 ab 49152
    2. poke 53272,33: rem Zeichensatz ab 49152, Bildschirm ab 51200
    3. poke 648,200: rem dem System mitteilen, dass der Bildschirmspeicher bei 51200 liegt

    Alle drei POKEs natürlich gleichzeitig eingeben, sonst siehst du plötzlich nichts mehr ;)


    Vorher muss der Zeichensatz nach Adresse 49152 ($c000) geladen werden. Am einfachsten änderst du dazu die Startadresse der Zeichensatz-Datei mit einem entsprechenden Tool. Ich meine Dirmaster kann das.

  • Hallo Korodny. Danke für deine Antwort.

    Quote

    Am Besten ist der letzte 16K-Block ab 49152

    Na toll, da habe ich nun schon ein paar Maschinencode-Routinen abgelegt. Dann darf ich mir nochmal Gedanken machen, wo ich die danach hinpacken kann. Und ändern muss ich sie auch noch, weil darin auch explizite Adressen stehen. Grrrr. Ich denke, im vierten KB-Block ab $CC00 nach dem Bildschirmspeicher wäre dann ein guter Platz. (?) Oder kann ich Zeichensatz und Bildschirm auch um 1KB nach oben verschieben in der Angabe für 53272? Das wäre ideal. Dann müsste ich mich nicht mehr mit der Bedeutung der ganzen (Hex-)Zahlen der Routinen befassen.


    Quote

    Vorher muss der Zeichensatz nach Adresse 49152 ($c000) geladen werden. Am einfachsten änderst du dazu die Startadresse der Zeichensatz-Datei mit einem entsprechenden Tool. Ich meine Dirmaster kann das.

    Brauche ich gar nicht, weil ich meinen Zeichensatz selber definiert habe. ;-) Also erst den Standard-Zeichensatz ins RAM kopiert und dann geändert.


    Ok, dann werde ich mich morgen mal dran setzen. Die C64-Wiki finde ich dahingehend übrigens nicht sehr gut:

    Quote

    Aus https://www.c64-wiki.de/wiki/Zeichen#Zeichenprogrammierung:


    "Um die kompletten Zeichensätze 1 und 2 zu nutzen, werden 4 KByte (2×2048 Byte) benötigt. Der Speicherbereich 12288 bis 16383 ist hierfür ideal, zumal noch genügend Speicherplatz für BASIC-Programme zur Verfügung stehen."

    Das ist offensichtlich nicht so. Mein BASIC-Programm ist nicht sooo unglaublich groß und dennoch überschreibt es diesen Speicherbereich.

  • Leider kann ich den Beitrag oben nicht bearbeiten (warum nicht?)...


    Ich habe jetzt einiges ausprobiert und habe ein annehmbares Ergebnis erhalten. Ich lege jetzt den Bildschirm nach 50176 und ein KB später den Zeichensatz. Das geht. Ich bekomme zwar erstmal einen Bildschirm voller komischer Zeichen, aber nach einem CLRSCR ist alles weg, und es kann losgehen. Ich habe jedoch noch ein kleines Problemchen: STOP/RESTORE geht jetzt nicht mehr. Wenn ich diese Kombi drücke, hängt sich der C64 auf. Gibt es da Abhilfe?

  • Na toll, da habe ich nun schon ein paar Maschinencode-Routinen abgelegt.

    Dann leg den Screen zu $cc00 (die höchste Adresse, bei der man noch lesend darauf zugreifen kann) und den Zeichensatz zu $e000 oder höher (also unters ROM). Der Bereich $dxxx geht zwar auch, aber es ist dank der eingeblendeten I/O-Chips schwieriger, die Daten dort ins RAM zu bringen.

    Mein BASIC-Programm ist nicht sooo unglaublich groß und dennoch überschreibt es diesen Speicherbereich.

    Es liegt nicht einmal an der Größe des Programms. Auch bei einem sehr kleinen Programm hätten die "von oben kommenden" Strings irgendwann den Zeichensatz überschrieben. Was im Wiki an der Stelle fehlt, ist die Information, wie man - durch Setzen der Basic-Pointer - den Zeichensatz vor dem Überschreiben schützt. Aber die jetzige Lösung, einfach die oberste VIC-Bank zu benutzen, ist eh die bessere. ;)

    Ich habe jedoch noch ein kleines Problemchen: STOP/RESTORE geht jetzt nicht mehr. Wenn ich diese Kombi drücke, hängt sich der C64 auf. Gibt es da Abhilfe?

    Einfach die Standard Werte in die 3 Speicherstellen poken. Musst du in dem Fall blind eingeben.

    Oder man schreibt sich die POKEs in eine Programmzeile und gibt blind GOTO60000 ein.


    EDIT: Sind wirklich alle drei POKEs nötig? Evtl. reicht der 648er, die anderen beiden sollten von STOP+RESTORE erledigt werden.

  • Ich bekomme zwar erstmal einen Bildschirm voller komischer Zeichen

    Klar, der Speicherbereich enthält ja bereits Daten. Wenn alles korrekt läuft kannst du ja den Bildschirm vorher abschalten, Änderungen vornehmen, dann den Bildschirm wieder einschalten:

    Code
    1. poke 53265,11: rem Bildschirm abschalten
    2. poke 53265,27: rem einschalten

    Zeichensatz manipulieren würde ich in BASIC übrigens nicht machen, das ist viel zu langsam. Speicher das Ding auf Diskette und lade es von dort. Wenn das Programm fertig ist, kannst du den BASIC-Teil und den Zeichensatz dann zu einer Einheit verlinken, die nach dem Start an die richtigen Speicheradressen entpackt wird, dafür gibt es fertige Tools.

    Ich habe jedoch noch ein kleines Problemchen: STOP/RESTORE geht jetzt nicht mehr. Wenn ich diese Kombi drücke, hängt sich der C64 auf. Gibt es da Abhilfe?

    Soweit ich mich erinnern kann, ist das so wie @Mc Bacon sagt: RESTORE stellt den Wert der Adresse 648 nicht wieder her, also einfach blind "poke 648,4" eingeben.


    Aber wieso benutzt du STOP+RESTORE? STOP reicht doch völlig.

  • Aber wieso benutzt du STOP+RESTORE? STOP reicht doch völlig.

    Vielleicht gehört das "zum guten Ton", wenn der Warmstart durch STOP+RESTORE entweder (immer noch) sauber funktioniert oder ansonsten ignoriert wird, aber zu einem Absturz oder nicht mehr reagierenden Rechner sollte das nicht führen. Und STOP macht nun mal keinen Warmstart, sondern stoppt ein laufendes BASIC-Programm mit der "BREAK IN XXX"-Meldung.


    Hauptproblem wird wohl sein, daß die Warmstart-Routine die VIC-Bank im CIA wieder auf $0000..$3FFF stellt.


    Eine Alternative zur Änderung der VIC-Bank wäre, den BASIC-Start z.B. auf $3000 anzuheben. Dann paßt ein kompletter Zeichensatz von $2000..$2FFF rein (bei $1000 liegt für den VIC genau der Originalzeichensatz!), der Bildschirm kann an alter Stelle bleiben, zwischen $0800 (+ein paar gequetschte) und $1FFF hättest Du noch weiteren Platz für Maschinenroutinen, mußt ab $C000 nichts umschaufeln und der "Absturz" bei STOP+RESTORE passiert dann auch nicht.


    Geht relativ easy so - zuerst (bei leerem Speicher) folgenden BASIC-Stub eingeben:

    Code
    1. 2020 POKE44,48:RUN

    Dann mit:

    Code
    1. POKE44,48:POKE12288,0:NEW

    den BASIC-Start verschieben. Zuerst mit ",8,1" (Ladeadresse muß da stimmen!) den Zeichensatz nach $2000 laden, nochmal NEW um ein paar Pointer wieder gerade zu stellen, und dann mit ",8" (*nicht* ",8,1"!!!) das eigene BASIC-Programm an den neuen BASIC-Start laden. Der Zeichensatz wird mit POKE53272,24 aktiviert. BASIC-Stub, Zeichensatz und "Nutzlast" kannst Du zusammen abspeichern mit:

    Code
    1. POKE44,8:SAVE "...",8
  • Eine Alternative zur Änderung der VIC-Bank wäre, den BASIC-Start z.B. auf $3000 anzuheben.

    Wenn er nicht gerade zwei Zeichensätze verwenden will, um weiterhin ein Umschalten mit C=/Shift zu ermöglichen, braucht ein Zeichensatz nur 2 KB. Wenn der BASIC-Start erhöht werden soll, reicht also $1000 völlig, kein Grund 8 KB Speicher "wegzuwerfen".


    Ich halte das allerdings für den schlechteren Ansatz:


    1. Während man bei Nutzung des RAMs ab $C000 theoretisch sogar noch 1 KB Speicherplatz gewinnt - man könnte ja den BASIC-Start *nach unten* verschieben, verliert man mit deiner Methode 2 KB. In Commodore-BASIC immer schlecht, auch wenn es sich hier ausgehen sollte.


    2. Wenn man nicht auf Maschinensprache zurückgreifen will, lässt sich ein solches Programm m.W. nur noch durch einen Lader starten, der "Blindtext" auf den Bildschirm schreibt ("POKE X,Y:NEW", vier Zeilen darunter 'LOAD"HAUPTPROGRAMM",8' usw.), den Tastaturspeicher mit HOME und einer Reihe RETURNs füllt und sich dann beendet -> unschönes Gehacke.

  • Wenn er nicht gerade zwei Zeichensätze verwenden will, um weiterhin ein Umschalten mit C=/Shift zu ermöglichen, braucht ein Zeichensatz nur 2 KB.

    O.K. - dann nimmt man eben $2801 als BASIC-Start, mit POKE 44,40 (und POKE10240,0 für das Nullbyte vor dem BASIC-Start).

    Wenn der BASIC-Start erhöht werden soll, reicht also $1000 völlig,

    Bei $1000 blendet die PLA das Zeichensatz-ROM ein. Meine ich auch in meinem vorherigen Beitrag erwähnt zu haben.


    Wenn Du allerdings meintest, den Zeichensatz nach $0800 legen zu wollen, zerstört das natürlich den BASIC-Stub.

    Wenn man nicht auf Maschinensprache zurückgreifen will, lässt sich ein solches Programm m.W. [...]

    Das Ergebnis meiner Prozedur ist ein Onefiler mit BASIC-Stub, Zeichensatz und Nutzlast. Und etwas Platz zwischen $08xx und $1FFF für Code und Daten (z.B. Sprites bis $0FFF und vielleicht eine Musik-Abspielroutine ab $1000).

  • Bei $1000 blendet die PLA das Zeichensatz-ROM ein. Meine ich auch in meinem vorherigen Beitrag erwähnt zu haben.

    "Den BASIC-Start auf $1000 verschieben" bedeutet natürlich Zeichensatz bei $0800.

    Wenn Du allerdings meintest, den Zeichensatz nach $0800 legen zu wollen, zerstört das natürlich den BASIC-Stub.

    Was meinst du mit "BASIC-Stub"?

    Das Ergebnis meiner Prozedur ist ein Onefiler mit BASIC-Stub, Zeichensatz und Nutzlast. Und etwas Platz zwischen $08xx und $1FFF für Code und Daten (z.B. Sprites bis $0FFF und vielleicht eine Musik-Abspielroutine ab $1000).

    Eine "Prozedur" hattest du nicht gepostet. Wie mache ich aus deinen POKEs sowie geladenem BASIC-Programm und Zeichensatz und ML-Routine einen Onefiler, den ich per "Load,8" und "RUN" starten kann?

  • Eine "Prozedur" hattest du nicht gepostet. Wie mache ich aus deinen POKEs sowie geladenem BASIC-Programm und Zeichensatz und ML-Routine einen Onefiler, den ich per "Load,8" und "RUN" starten kann?

    Ach weißt Du, wenn Du mit der Anleitung in Beitrag #8 ab "zuerst (bei leerem Speicher) folgenden BASIC-Stub eingeben:" nicht zurechtkommst, dann kann dir mit dem Endergebnis in Beitrag #11 geholfen werden. Wenn Du dich bemüßigst, "beispiel.zip" herunterzuladen und auszuprobieren. :saint:

  • Danke, Leute!

    Hauptproblem wird wohl sein, daß die Warmstart-Routine die VIC-Bank im CIA wieder auf $0000..$3FFF stellt.

    Genau. Dass er sich nicht aufhängt, habe ich dann auch irgendwann kapiert. Ich bin dann auch selbst darauf gekommen, mir so ne Zeile ins Programm zu schreiben. Ist zwar bissl nervig, immer RUN20000 zu schreiben, aber was soll's.

    Was im Wiki an der Stelle fehlt, ist die Information, wie man - durch Setzen der Basic-Pointer - den Zeichensatz vor dem Überschreiben schützt.

    Wie macht man das denn? Würde mich interessieren. Ich kann ja nicht einfach so FRETOP runtersetzen, oder?

    Eine "Prozedur" hattest du nicht gepostet. Wie mache ich aus deinen POKEs sowie geladenem BASIC-Programm und Zeichensatz und ML-Routine einen Onefiler, den ich per "Load,8" und "RUN" starten kann?

    Würde mich auch interessieren, Mike.

  • Ach weißt Du, wenn Du mit der Anleitung in Beitrag #8 ab "zuerst (bei leerem Speicher) folgenden BASIC-Stub eingeben:" nicht zurechtkommst

    Ups, hatte ich glatt überlesen. Hab nur "POKE44,48" gesehen und dachte "jaja, kennen wir schon" ;) Geile Idee, wäre ich nicht drauf gekommen. Das führt allerdings dazu, dass Webfritzi vor jedem Speichervorgang erst mal "POKE 44,8" eingeben eingeben müsste - ist jetzt auch nicht viel eleganter.


    Deswegen noch mal meine Frage an WebFritzi: Wieso benutzt du RESTORE? Ich frage, weil ich den Verdacht habe dass du die STOP-Taste blockiert hast, um sie im Programm nutzen zu können - habe ich früher immer so gemacht. Während der Entwicklung kannst du STOP aber mit CONTROL-C simulieren, das bricht BASIC-Programme nicht ab. STOP-Taste blockierst du dann erst, wenn das Programm fertig ist.

  • Ich möchte auch mehr Basic Speicher für mein Adventure haben.

    Habe mir den Zeichensatz nach d000 verschoben damit E000-FFFF für Hires freibleibt.

    Leider platzt der List befehl sobald mein Basicprogramm über A000 hinausfährt...


    Habe auch schon die Routine 0073 geändert das immer das A000 ROM weg ist wenn das nächste Zeichen vom Interpreter geholt wird.

    Aber leider schon beim List Befehl kommt müll da er nicht über die $7a und 7b Zeiger das nächste Byte holt ....

    Das muss doch irgendwie gehen ?

  • Das muss doch irgendwie gehen ?

    Mit "Routine 0073" meinst du den Vektor bei $73?


    Bei A000 liegt das BASIC-ROM, das die BASIC-Befehle interpretiert - inklusive des von dir im Beispiel verwendeten LIST-Befehls. Natürlich kannst du BASIC nicht einfach abschalten, während du in BASIC programmierst - wie soll das denn gehen?


    Es gibt einen Trick, um den BASIC-Interpreter zu verschieben - nach $D000/53248 - und dann mittels einiger Anpassungen dafür zu sorgen dass, bei allen Sprüngen vom Interpreter ins Kernal ROM erst der (in dieser Konfiguration normalerweise ausgeblendete) Kernel eingeblendet wird. Paradoxon BASIC macht das so, und stellt auf diese Weise 50 KB Speicherplatz für BASIC zur Verfügung. Ganz nebenbei gibt es auch noch einige neue Befehle, die bei der Programmierung helfen.


    Unbedingt die Anleitung lesen (das Sonderheft wird im verlinkten Thread erwähnt), dort wird WIMRE auch erklärt, wie man Paradoxon so patcht, dass es mit den gewünschten Bildschirmfarben startet oder gleich nach dem Programmstart ein eigenes Programm lädt und startet.