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

letzter Beitrag von ThomBraxton am

BASIC 7 - Shapes in SEQ-Datei speichern und wieder laden

  • Hallo Leute,


    ich bekomme gerade graue Haare, weil eine an für sich einfache Routine bei mir einfach nicht funktionieren will.


    Kurz zum Problem:
    Habe mir einen eingenen 5x5-Font für mein Programm konstruiert.
    Mac Bacon hat mir den Tipp gegeben, meinen Font als Shapes in Strings zu speichern.
    Habe mir eine Fortschrittsanzeige und meinen Font als Vertikal- und Horizontalfont auf den Monitor zeichnen lassen, die einzelnen Zeichen in Shape-Strings gespeichert und wollte diese auf Diskette in zwei sequentielle Dateien ablegen, was wohl auch ohne Probleme zu funktionieren scheint.
    Nur, wenn ich die Dateien wieder öffnen möche, um meine Shapes zu laden, dann blockiert VICE ohne Fehlermeldung schon beim Zugriff auf den ersten Datensatz.
    Wo habe ich meinen Fehler gemacht?


    Liebe Grüße!
    ThomBraxton

  • Zitat von ThomBraxton

    Wo habe ich meinen Fehler gemacht?


    Du hast INPUT# benutzt.


    Da in eine String-Variable eingelesen wird, gibt es kein ?FILE DATA ERROR gleich welcher Art, aber sobald in den Binärdaten der Shape-Strings irgendwie was in Richtung Anführungszeichen, Komma, Doppelpunkt, etc. auftaucht, war's das. INPUT# ist nicht für Binärdaten geeignet.


    In diesem Fall muß man sagen, leider. :(

  • EDIT: zu spät - aber das Schreiben hat etwas gedauert. :anonym

    Wo habe ich meinen Fehler gemacht?

    Du hast erwartet, dass INPUT (bzw. in diesem Fall INPUT#) sinnvoll funktioniert. :P
    Aber der Reihe nach:

    die einzelnen Zeichen in Shape-Strings gespeichert und wollte diese auf Diskette in zwei sequentielle Dateien ablegen, was wohl auch ohne Probleme zu funktionieren scheint.

    Theoretisch ja, denn PRINT# schreibt einfach nur die Strings in den logischen Kanal, somit landen die Bytesequenzen wie gewünscht in der Datei. Praktisch wurde allerdings an jeden String ein CR angefügt, da die PRINT#-Anweisungen hier nicht auf ";" enden. Wenn man nun beim Einlesen immer bis CR liest, was passiert dann, wenn ein Binärstring eh schon den CR-Code enthält? Aber das war hier gar nicht das Problem...
    Außerdem hat sich an dieser Stelle ein kleiner Fehler eingeschlichen, da die Zeile

    Code
    1. 4185 next

    fehlt. Daher stand in der einen Datei nur ein einzelner String statt neun. Aber das war hier auch nicht das Problem...

    Nur, wenn ich die Dateien wieder öffnen möche, um meine Shapes zu laden, dann blockiert VICE ohne Fehlermeldung schon beim Zugriff auf den ersten Datensatz.

    Der Vollständigkeit halber: Es liegt nicht an VICE, reale Hardware verhält sich genauso.
    Wenn man das vergessene NEXT hinzufügt, werden einige Datensätze gelesen. Dafür kommt die Blockade dann später. Das Problem ist - wie anfangs erwähnt - die INPUT-Anweisung:
    -Ausnahmsweise sind hier mal nicht Doppelpunkte das Problem.
    -Auch keine Kommata.
    -Es sind auch nicht die Anführungszeichen.
    -Es liegt auch nicht daran, dass der Eingabepuffer kürzer als die String-Maximallänge ist.
    -Nein, dieses Mal ist es die Tatsache, dass auch Nullbytes nicht eingelesen werden können.
    Genau die kommen in den Grafikdaten-Strings aber vor. Hier mal der Anfang der erzeugten Daten als Hexdump:

    Code
    1. 00000000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 |................|
    2. 00000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0e 00 |................|
    3. 00000020 0e 00 0d ff fe 81 02 83 82 81 02 81 02 81 02 83 |................|
    4. 00000030 82 83 82 83 82 80 02 80 02 80 02 80 02 80 02 ff |................|
    5. 00000040 fe 0e 00 0e 00 0d ff fe 80 02 80 3a 80 1a 80 2a |...........:...*|
    6. 00000050 80 42 83 82 83 82 83 82 80 02 80 02 80 02 80 02 |.B..............|
    7. 00000060 80 02 ff fe 0e 00 0e 00 0d ff fe 80 02 80 02 80 |................|

    Die Enden der Strings kann man an den angehängten CRs erkennen (Hexcode 0d). Wenn INPUT den ersten String zuzuweisen versucht, wird tatsächlich bis zum ersten CR gelesen, das wären 34 Bytes plus CR. Jetzt steht aber ein Nullbyte als erstes Byte im Eingabepuffer, und das steht für "keine Eingabe" (deshalb muss man ja bei GET# diesen blöden GET#1,A$:IFA$=""THENA$=CHR$(0)-Tanz aufführen). Da noch keine Eingabe erfolgt ist, wird weiter gelesen, so dass nun der nächste String (bis zum CR) im Eingabepuffer steht. Das sind wieder 34 Zeichen plus CR. An erster Stelle steht nun keine Null, so dass der Inhalt des Buffers zugewiesen wird. Dummerweise wird die Null als Terminator interpretiert, so dass nur 31 Zeichen zugewiesen werden und der Rest verfällt.
    Also ergeben sich zwei Probleme:
    1. In jedem String wird alles hinter dem ersten Nullbyte verworfen.
    2. Ist bereits das erste Byte Null, wird kein Leerstring zugewiesen, sondern einfach der nächste String aus der Datei geholt.
    Problem 2 sorgt dafür, dass am Ende weitere Leseversuche gemacht werden, obwohl keine Daten mehr vorliegen. An dieser Stelle scheinen Kernal und Diskettenlaufwerk in eine Endlosschleife zu gehen (liest man nach dem EOF noch weiter, so erfindet das Diskettenlaufwerk abwechselnd CR und Nullbytes, wenn ich mich recht erinnere). Man sollte eigentlich erwarten, dass das System an dieser Stelle mit einem Fehler abbricht, ja, aber... wenn man soviel erwartet, könnte man auch eine funktionierende INPUT-Anweisung erwarten. :bgdev


    Fazit: Vergiss INPUT. Es ist schon für Textstrings kaum brauchbar, aber bei Binärdaten hat man komplett verloren. Leider hat das CBM-Basic kein vernünftiges Interface, um Binärdaten aus einer Datei zu lesen, abgesehen von LOAD natürlich. Für das vorliegende Problem würde ich Dir empfehlen, statt SEQ-Dateien zu schreiben, einfach die erzeugte Grafik per BSAVE zu speichern.
    Um die Daten wieder zu lesen, lade die Grafik per BLOAD in den Speicher und lies die Strings wieder mit SSHAPE ein.


    EDIT: Probleme wie dieses sind übrigens perfekte Aufhänger, um mit eigenen Assembler-Hilfsroutinen anzufangen. ;)

  • Erst einmal vielen lieben Dank für die ausführlichen Antworten.


    Um Assembler zu lernen brauche ich viel mehr Freizeit, um mich in die Materie einarbeiten zu können. Ich werde aber demnächst einige Fragen posten, um Assembler-Teile aus alten Büchern in Cross-Compiler-Umgebungen wie CBM Prog Studio zum Laufen zu bringen. Einige Sachen verstehe ich schon, aber leider noch nicht ausreichend genug, um das, was ich in BASIC "kann" auch in Assembler umzusetzen. Da fehlt mir wirklich ein ausführliches Tutorial. Ich weiß, es gibt Seiten wie http://www.retro-programming.de, doch auch diese helfen mir bei meinen bisherigen Problemen nicht wirklich weiter.
    Gut, es gibt massig Routinen, die man im Kernal des C128 oder C64 aufrufen kann, aber auch da muss man sich intensiv einarbeiten und dafür brauche ich ebenfalls mehr Freizeit. Wird Zeit, dass ich Rentner werde. Aber das dauert noch gut 19 Jahre. Mist!


    Zu meinem Shape-Problem. Du, Mac Bacon, meinst bestimmt, das Speichern der Font-Bilder als Grafik, um sich beim eigentlchen Programm beim Start zu laden und die entsprechenden Shapes dann auszuschneiden, um sie im Programm benutzen zu können. Diese Lösung werde ich mir näher betrachten, doch möchte ich zuvor noch ein paar Test mit anderen "Möglichkeiten" machen. Obwohl, wenn alle benötigten Shapes in einer einzigen Grafik enthalten sind, dann ist Dein Lösungsvorschlag bestimmt der effektivste. Hmmmm...
    Mein Kopf raucht schon wieder! :zaunpfahl:


    Danke ebenfalls für den Hinweis mit dem DOPEN-Problem bei SD-Karten-Laufwerken. Werde wohl mein eigentliches Programm entsprechend anpassen. Machen BSAVE/BLOAD keine Probleme?
    :thnks:
    Liebe Grüße!
    ThomBraxton

  • [Ich hatte per PM angemerkt, dass DOPEN/DCLOSE keine Vorteile gegenüber OPEN/CLOSE bieten, dafür aber Nachteile haben]

    Danke ebenfalls für den Hinweis mit dem DOPEN-Problem bei SD-Karten-Laufwerken. Werde wohl mein eigentliches Programm entsprechend anpassen. Machen BSAVE/BLOAD keine Probleme?

    Doch, auch die beschränken den Dateinamensstring hart auf 16 Zeichen. Aber für diese Anweisungen gibt es keine Alternativen. ;)