Hallo Besucher, der Thread wurde 2,7k mal aufgerufen und enthält 11 Antworten

letzter Beitrag von Hamrath am

Längeren Text von Disk einlesen

  • Moin,


    ich möchte (möglichst schnell) einen längeren Text (520 Bytes) von Disk einlesen und auf dem Bildschirm anzeigen. Diesen Text habe ich vorher als PRG mit c1541.exe auf ein .d64-Image geschrieben. Mit einem kleinen BASIC-Programm kann ich den Text auch auslesen, allerdings nur die ersten 254 Zeichen via GET#. Außerdem dauert das Einlesen mit 3 Sekunden viel zu lange.



    Via INPUT# scheint das Ganze gar nicht zu funktionieren.


    Ich würde gerne aber die ganzen 520 Byte auslesen. GIbt es eine Lösung dafür in BASIC? Ist der Ansatz, die Textdatei als PRG zu speichern falsch?


    Vielen Dank für Eure Hilfe.

  • ich möchte (möglichst schnell) einen längeren Text (520 Bytes) von Disk einlesen und auf dem Bildschirm anzeigen.

    Der schnellste Weg dürfte ein LOAD direkt in den Bildschirmspeicher sein. Dafür muss der Text in der Datei allerdings in Screencodes vorliegen (also nicht ASCII und nicht PetSCII).

    Mit einem kleinen BASIC-Programm kann ich den Text auch auslesen, allerdings nur die ersten 254

    Die Schleife geht von 0 bis 254, das sind 255 Zeichen. Und dieses Limit hat nichts mit der Datei-I/O zu tun, sondern liegt an der Maximallänge eines Basic-Strings. Würdest Du die Zeichen in zwei Strings lesen, gingen auch mehr als 255 Zeichen. Alternativ gibt man jedes Zeichen direkt nach dem Einlesen gleich wieder auf dem Bildschirm aus, ohne erst längere Strings zusammenzubasteln.

    Via INPUT# scheint das Ganze gar nicht zu funktionieren.

    INPUT funktioniert nur, wenn spätestens nach 88 Zeichen ein Zeilenumbruch kommt (aber CR, nicht LF!), außerdem dürfen keine Kommata und keine Doppelpunkte benutzt werden. Und Anführungszeichen sind auch problematisch.


    Bessere Lösungsvorschläge wirst Du erst bekommen können, wenn Du das eigentliche Ziel der Übung verrätst: Einfach nur einen Text von 520 Zeichen auszugeben, geht ja auch direkt per PRINT - also warum willst Du das unbedingt per Datei machen?


  • Bessere Lösungsvorschläge wirst Du erst bekommen können, wenn Du das eigentliche Ziel der Übung verrätst: Einfach nur einen Text von 520 Zeichen auszugeben, geht ja auch direkt per PRINT - also warum willst Du das unbedingt per Datei machen?

    Ich schreibe zum "Wiedereinstieg" ein Textadventure und möchte die Raum und Objektbeschreibungen in Dateien auslagern, damit ich mehr Platz im RAM habe. Ggf. sollen auch PETSCII-Bilder dort ausgelagert werden. Meine Idee war, nur Raum- und Objekt-IDs und Namen in meinem Programm zu haben, aber längere Beschreibungen von Diskette nachzuladen. Dass bspw. die Beschreibung des Raum 13 in der PRG-Datei "R013", Objekt 25 in "O025", etc. liegt.


    Ich dachte an PRG, damit ich Inhalte unabhängig von der Textlänge speichern kann.


    Und ja, ich weiß, dass es da Editoren wie D42 gibt (die Diskussion gab es ja an anderer Stelle vor kurzem schon einmal. ;) ). Für mich ist das eine Übung, um wieder in die C64-Programmierung zu kommen.

  • Ich schreibe zum "Wiedereinstieg" ein Textadventure und möchte die Raum und Objektbeschreibungen in Dateien auslagern, damit ich mehr Platz im RAM habe.

    Das dürfte auf die Dauer lästig werden, selbst mit einem Fastloader. Oberhalb Adresse 40960 gibt es 24 KB Speicher, der von BASIC überhaupt nicht benutzt wird. (Mindestens) 20 KB davon kannst du problemlos zum Ablegen von Zeichenketten benutzen. Dann bräuchtest du nur ein mal zu laden - oder zwei, drei mal pro Spiel, wenn der Speicher nicht fürs ganze Spiel reicht - und könntest danach blitzschnell beliebige Texte anzeigen.


    Du müsstest eben selbst irgendwo eine Art Inhaltsverzeichnis anlegen (String A beginnt an Adresse X, String B an Adresse Y...), außerdem bräuchte es zum Hervorholen der Strings unter den ROMs wohl eine (sehr) kleine Assemblerroutine.


    Ich dachte an PRG, damit ich Inhalte unabhängig von der Textlänge speichern kann.

    Anstatt die Datei Byteweise per BASIC-Schleife einzulesen, solltest du sie direkt am Stück von den Betriebssystemroutinen laden lassen. Das ist schneller, und wird von jedem Fastloader nochmal deutlich beschleunigt. Der Text liegt dann halt irgendwo im Speicher herum statt in einem BASIC-String, d.h. die Ausgabe wird etwas komplizierter (s.u.).


    So kannst du eine Datei von Disk an eine beliebige Stelle im Speicher laden (LO und HI sind Low- und High-Byte der gewünschten Zieladresse):

    Code
    1. SYS 57812 "dateiname",8,0:POKE780,0:POKE781,LO:POKE782,HI:SYS 65493

    Wichtig: damit das funktioniert, muss die PRG-Datei eine (beliebige) Startadresse haben - also mit zwei (beliebigen) Bytes beginnen, die nicht zum String gehören.


    Dann gibt es zwei Möglichkeiten:


    1. Den Text wie von Mac Bacon erwähnt als Screencodes speichern, nicht als PETSCII. Dann kannst du ihn direkt in den Bildschirmspeicher laden. Ausknobeln in welcher Zeile er erscheinen soll, daraus folgt dann die Ladeadresse: 1024+40xZEILE (wobei 1. Zeile = 0). Allerdings funktioniert das nur für monochrome Texte (es werden ja keine Farbinformationen mitgespeichert) und es wird nicht gescrollt, das müsste man selbst erledigen (X mal CURSOR DOWN, dann Text in den entstandenen Freiraum laden).


    2. Den Text in einen Zwischenspeicher laden, und von dort ausgeben lassen. Ich meine, es gab eine KERNAL- oder BASIC-Routine die man auch von BASIC aus anspringen konnte und die Zeichenketten im Speicher ausgibt, die mit einem Nullbyte enden müssen - komme aber gerade nicht drauf. Ansonsten wäre wieder eine winzige Maschinensprache-Routine fällig.

  • Eine Lösung, die ich gefunden habe: Ich ändere meine Text-Datei so um, dass jedes Wort in einer einzelnen Zeile steht (oder die Sätze nicht länger als 88 Zeichen sind). Dann speichere ich sie mit c1541.exe als SEQ. Entweder speichere ich jetzt in meinem DIM die Anzahl der Zeilen ab, oder beende die Text-Datei mit einem Schlüsselwort (bspw. #END) und gebe den Text so lange aus, bis ich am Ende angekommen bin.


    Das funktioniert auf jeden Fall schneller als mein erster Gedanke, 2520 Zeichen werden in knapp 7 Sekunden ausgegeben.


    Sonder- bzw. nicht darstellbare Zeichen (Komma, etc.) schreibe ich in meinem Text mit anderen Zeichen und könnte sie später während der Ausgabe ersetzen.


    Aber ich bin für andere Vorschläge offen. :)

  • Hi


    Code
    1. 10 OPEN 1,8,2,"Datei,S,R"
    2. 20 INPUT#1,D$
    3. 30 IF ST<>64 THEN 20

    Damit list du solange den Text ein, bis die Variabel ST 64 erreicht hat. Die Sendet das Floppy sobald das Dateiende erreicht wurde.


    Habe erst neulich ein Basicprogramm geschrieben wo man SEQ-Files einlist damit man den Text wieder bearbeiten kann. Und natürlich den Text wieder abspeichern kann.


    Schönen Vatertag noch euch allen :winke:

  • Sonder- bzw. nicht darstellbare Zeichen (Komma, etc.) schreibe ich in meinem Text mit anderen Zeichen

    Kommas und Doppelpunkte kann man durchaus benutzen, wenn die Zeile mit einem Anführungszeichen beginnt. Das Anführungszeichen wird dann auch automatisch entfernt.

    und könnte sie später während der Ausgabe ersetzen.

    Und damit wären wir beim Thema "wie man in Basic V2 Probleme löst, die man in brauchbaren Programmiersprachen gar nicht hätte" :D

  • Kommas und Doppelpunkte kann man durchaus benutzen, wenn die Zeile mit einem Anführungszeichen beginnt. Das Anführungszeichen wird dann auch automatisch entfernt.

    Und damit wären wir beim Thema "wie man in Basic V2 Probleme löst, die man in brauchbaren Programmiersprachen gar nicht hätte" :D

    Ah, danke für den Tipp mit den Anführungszeichen!


    Und: Jaja, ich weiß. :P Es gibt halt Gründe (die nicht sind: Ich habe keine Lust, mich mit Assembler oder C auseinanderzusetzen.)

  • Da zitiere ich gerne den Code, der im Beispiel des C64-Wiki-STATUS-Beitrags erwähnt wird, in einer Abwandlung für zeilenweises Einlesen. Abgesehen davon, erfolgt in der obigen Variante kein Abbruch bei einem Fehler, sondern nur, wenn das EOF auftritt. Ein etwaiger Fehler sollte schon behandelt werden und zu einem Abbruch der Schleife führen. Abgesehen davon ist das eine GOTO-lose Variante, die somit nicht von der Zeilenposition abhängt und auch die GOTO-Laufzeitschwankungen nicht auftreten. Hier also die abgewandelte Version:

    Code
    1. 10 REM SEQ. DATEI FUER EINGABE OEFFNEN:
    2. 20 OPEN 1,8,2,"Datei,S,R"
    3. 30 FOR S=0 TO 1 : REM ENDLOSSCHLEIFE, SOLANGE S = 0 IST
    4. 40 INPUT#1,D$ : REM STRING EINLESEN
    5. 50 PRINT D$; : REM DAS BYTE AUF DEM BILDSCHIRM AUSGEBEN
    6. 60 S=ABS(ST) : REM S ist >0 WENN DATEIENDE ODER FEHLER
    7. 70 NEXT S : REM ABBRUCH, WENN ST <> 0 WAR
    8. 80 CLOSE 1 : REM DATEI WIEDER SCHLIESSEN
    9. 90 IF ST=64 THEN PRINT "OK"
    10. 91 PRINT "STATUS:" 255 AND ST
  • Hi Jeek


    Der Code ist klasse, den werde ich mir merken. Den kann ich dann in meinen Programm einbinden. Ich habe meinen Code, den ich hier zitiert habe, zu stark gekürzt. Den habe ich als einen alten Floppybuch ^^
    Wieder was gelernt. Denn ich habe in meinen Programm habe ich keine richtige Fehlerbehandlung eingebaut.