Hello, Guest the thread was called14k times and contains 236 replays

last post from dg5kr at the

BASIC 4.5 für den C64 (BASIC 3.5 + EIGENE BEFEHLE)

  • Es wird aber definitiv anders gehandhabt. REM und ' (als Alternative) zeigen nach einem LIST verschiedene Kommentare. Beim REM bleibt das ? stehen, beim ' wird es in PRINT als Klartext umgewandelt.

    Stimmt. Der Tokenizer geht, sobald er ein REM erkannt hat und das Token dazu hat in den String-Modus und ignoriert damit etwaige implizite Umwandlungen wie $3f (?) -> $99 (PRINT-Token).


    Siehe http://unusedino.de/ec64/technical/aay/c64/roma579.htm an der Stelle $A5DF (zeigt sich nicht in den Kommentare, die sind auf dieser Site eher schwach), wo in einer Kettensubtraktion ($3A und $55 = $8F -> REM Token) vom ermittelten Token abgezogen wird.


    Daher müsste man den Tokenizer also auch dahingehend abändern, dass er das beim Zeichen (') macht ...

    Aber das Tokenizer-Thema hatten wir da ja schon öfter, etwa um Funktionen in Ausdrücken erkennen zu können, müsste man da ohnehin Hand anlegen. ;)

  • (zeigt sich nicht in den Kommentare, die sind auf dieser Site eher schwach)

    OT-Hinweis: Die Kommentare hier sind recht ausführlich: Fully Commented Commodore 64 ROM Disassembly (English)

    Danke, ja, das ist ordentlich dokumentiert, aber rein als Text mühsam. Hab's als HMTL-Dokument unter

    https://klasek.at/c64/c64-rom-listing.html#A579

    bereitgestellt. ;)

  • Hallo zusammen,

    erstmal einn riesen Dank für alle hier im Forum für die echt konstruktiven Hinweise und einer sehr sehr fachlichen Diskussion.
    Es macht wirklich Spass hier :thumbsup:


    Ich versuche die beiden Themen -> ' als REM-Ersatz und -> TI$ via RTC etwas zu trennen.

    Daher werde ich mich als aller erstes um das ' - Problem kümmern und TI$ solange bei Seite stellen (zumindest hier).

    Wenn das gefixt ist, greife ich die RTC-Geschichte wieder auf. Ich hoffe das ist für alle OK.
    Ich muss erstmal die vielen Beiträge lesen und auswerten ?(. Da benötige ich ein Stündchen....:rolleyes:

    Bei dem Apostrophe werde ich als erstes das Tokenizer Problem lösen und dann sehen warum "Drachen" einen Syntax Error erhält.
    Jeek hat mich da auf die Spur gebracht :thumbup:. Alles nach dem Apostrophe darf bis zum Ende der Zeile nicht mehr tokenisiert werden. Den werde ich wohl nochmal anpacken müssen.

    So, nun ziehe ich mich ins Kämmerlein zurück und muss nachdenken :honk:

    Übrigens Danke an Snoopy und Jeek für den Link. Ein wirklich ausgezeichnet dokumentiertes ROM - Listing.

  • Hier ist eine neue Version meines BASIC 4.5 inklusive aktualisierter Dokumentation.

    Das sind die Fixes/Ändeungen/Erweiterungen:


    Zur Erklärung.

    Die Unzulänglichkeiten beim "REM-Ersatz" wurden abgestellt. Ich habe den Tokenizer dahingehend überarbeitet, das er genauso wie REM alle Zeichen bis zum Zeilen Ende nicht tokenisiert. REM und ' sollten sich nun exakt gleich verhalten. Das berifft auch die REM-Bugs. Die hat nun auch das ' ^^


    Sobald ein RTC Baustein DS12C887 RTC Baustein vorhanden ist, so wird Systemvariable TI$ wird beim Einschalten automatisch mit der Uhrzeit versehen. Achtung! Der DS12C887 MUSS als Basis Adresse $DE00 haben. Wo möglich werde ich eine Konfigurationsmöglichkeit in der nächsten Version einbauen. Selbstverständlich kann TI$ weiterhin per Hand geändert werden. Wenn kein RTC in $DE00 zu finden ist, dann startet wie üblich der Timer bei 0.


    Ich freue mich auf euer Feedback.

  • Hier die Liste der Token für den Einbau ins C64Sudio:

    #Es wird mit zwei Tokens gearbeitet. 7F ist das Master Token.

    #Die Befehlstoken beginnen bei 01 fortlaufend.

    #============================================================

    #Befehl Token

    #------------------------------------------------------------

    AT;7F01;

    CLS;7F02;

    INFO;7F03;

    VER;7F04;

    FRAME;7F05;

    CATALOG;7F06;

    MEMORY;7F07;

    STOP;7F08;#*

    WINDOW;7F09;

    DLRUN;7F0A;

    FIND;7F0B;

    FILES;7F0C;

    BEGINBLOCK;7F0D;

    ENDBLOCK;7F0E;

    RESTORE;7F0F;#*

    RTRIM;7F10;

    LTRIM;7F11;

    XOR;7F12;

    ';7F13;APOSTROHPE(ALTERNATIVE ZU REM)

    DELAY;7F14;

    BEEP;7F15;

    #* BASIC V2.0 Befehl, wurde aber erweitert wodurch sich das Token geändert hat.

    #==============================================================================

    Gruß Robert (DG5KR)

  • Leider hat sich in der CRT Datei ein Fehler eingeschlichen was einen JAM zur Folge hat ?(. Die PRG Datei ist ok.

    Ich werde mal auf BUG Suche gehen.

    Das CRT - Problem ist (zunächst) gelöst. Ich habe einen reproduzierbaren Fehler im Code. Sobald ich für den RTC $DE00 als Basis Adresse nehme gibt es Probleme mit dem erzeugten CRT. Bei $DF00 nicht. Denn Grund habe ich noch nicht raus gefunden. Daher habe ich hier eine Version mit funktionierender RTC DS12C887 und Basis Adresse $DF00 als PRG und CRT.


    Zur Eklärung: Mein Programm liegt wenn es gestartet wurde ab Adresse $8400. Warum $8400? Ganz einfach ich möchte den Bereich $9FFF nicht durch die Größe überschreiten weil im RAM ab $A000 die BASIC 3.5 Erweiterungen liegen. Das heißt jeder Befehls-Erweiterung läßt den Anfang weiter in Richtung $8000 wachsen.


    Das gesamte PRG-Programm (BASIC 4.5 + BASIC 3.5) liegt wenn es von Disk geladen und noch nicht gestartet wurde wird direkt hinter dem kleinen BASIC Loader. Beim Aufruf kopiert es sich selbst in den gewünschten Speicherbreich und startet sich.


    Die CRT Erstellung mache ich mit einem Python Tool von Frank Buß (https://frank-buss.de/c64/prg2crt/index.html). Dieses macht mir aus der PRG ein CRT, welches dann im CRT ab $8000 korrekt läuft. Nun scheine ich aber an dessen Grenze zu stoßen.


    Um mit dem Tool CARTCONV eine CRT zu erstellen muss ich mich an die Spielregeln von CRTs halten (siehe http://blog.worldofjani.com/?p=879). Ein BASIC45 als PRG mit Basic Loader und Basic45 als CRT auszuliefern wird im Assembler Code sehr komplex und unübersichtlich (Stichwort Compilerschalter, bedingt Compilierung).


    Ich möchte meine knappe Zeit lieber in der Pflege und Weiterentwicklung von BASIC 4.5 stecken und nicht so sehr in der Generierung eines 16K CRT Images. Deshalb habe ich mich entschlossen in der nächsten Version kein CRT mehr auszuliefern. Ich hoffe ihr versteht das.

    Super gerne nehme ich aber einen "Mitstreiter" in meiner Entwicklung auf der sich dann um die CRT Geschichte kümmern möchte. Also, ich bitte um Handzeichen ;)

  • ; 11.01.2021:
    ; New: Neuer Befehl: DELAY N -> Wartet 1/50Sekunde * N (1/60Sek * N bei NTSC)

    Uhi, das ist gar nicht gut, dass das vom der Bildwiederholfrequenz abhängt. Damit bürdet man einem Programmierer auf, sich um den Unterschied zu kümmern bzw. man neigt dazu, diesen überhaupt nicht zu berücksichtigen. Das ist natürlich keine Tragödie, aber aus dem Standpunkt der Portabilität sollte man so etwas erst gar nicht erst einreißen lassen.


    Verwendet die Funktion tatsächlich das Raster-Interrupt-Timing?

    Warum orientiert sich die Routine nicht am schon vorhandenen 1/60 s IRQ? Der ist doch schon "hardware-unabhängig". Ich hab mir die Implementierung jetzt nicht angesehen, aber dort im IRQ noch einen Countdown-Zähler zu bedienen, sobald ein Wert >0 vorhanden ist und im DELAY-Befehl dann auf das Herabzählen auf 0 zu warten, ist kaum ein Aufwand. ;)

  • ; 11.01.2021:
    ; New: Neuer Befehl: DELAY N -> Wartet 1/50Sekunde * N (1/60Sek * N bei NTSC)

    Uhi, das ist gar nicht gut, dass das vom der Bildwiederholfrequenz abhängt. Damit bürdet man einem Programmierer auf, sich um den Unterschied zu kümmern bzw. man neigt dazu, diesen überhaupt nicht zu berücksichtigen. Das ist natürlich keine Tragödie, aber aus dem Standpunkt der Portabilität sollte man so etwas erst gar nicht erst einreißen lassen.


    Verwendet die Funktion tatsächlich das Raster-Interrupt-Timing?

    Warum orientiert sich die Routine nicht am schon vorhandenen 1/60 s IRQ? Der ist doch schon "hardware-unabhängig". Ich hab mir die Implementierung jetzt nicht angesehen, aber dort im IRQ noch einen Countdown-Zähler zu bedienen, sobald ein Wert >0 vorhanden ist und im DELAY-Befehl dann auf das Herabzählen auf 0 zu warten, ist kaum ein Aufwand. ;)

    Hmm, ich habe den Raster interrupt genommen damit der Programmierer genau diese Auswahl hat. Abgesehen davon finde ich 1/50 Sekunde deutlich besser auf die volle Sekunde umzurechnen als 1/60. Im Basiccode will man i.R. auf Basis von Sekunden was tun oder eben warten. Ob es aber genau 1 Sekunde ist, oder eben 0,83 Sekunde merkt der anwender wo möglich gar nicht.

    Dem Argument der portabilität kann ich nur zustimmen. Das abzuändern ist recht einfach. Welcher vorhandene, stets 1/60 Sekunde Interrupt meinst du denn?

  • Uhi, das ist gar nicht gut, dass das vom der Bildwiederholfrequenz abhängt. Damit bürdet man einem Programmierer auf, sich um den Unterschied zu kümmern bzw. man neigt dazu, diesen überhaupt nicht zu berücksichtigen. Das ist natürlich keine Tragödie, aber aus dem Standpunkt der Portabilität sollte man so etwas erst gar nicht erst einreißen lassen.

    Bei "mca2" habe ich deshalb als Zeiteinheit einfach Zehntelsekunden genommen. Das Laufzeitsystem multipliziert diese Zeitangabe dann - je nach Zustand des PAL/NTSC-Flags - mit fünf oder sechs und benutzt das Ergebnis, um Frames abzuzählen.

    Zehntelsekunden sind zwar relativ grob, aber in BASIC ist das eh egal.

  • Uhi, das ist gar nicht gut, dass das vom der Bildwiederholfrequenz abhängt. Damit bürdet man einem Programmierer auf, sich um den Unterschied zu kümmern bzw. man neigt dazu, diesen überhaupt nicht zu berücksichtigen. Das ist natürlich keine Tragödie, aber aus dem Standpunkt der Portabilität sollte man so etwas erst gar nicht erst einreißen lassen.

    Bei "mca2" habe ich deshalb als Zeiteinheit einfach Zehntelsekunden genommen. Das Laufzeitsystem multipliziert diese Zeitangabe dann - je nach Zustand des PAL/NTSC-Flags - mit fünf oder sechs und benutzt das Ergebnis, um Frames abzuzählen.

    Zehntelsekunden sind zwar relativ grob, aber in BASIC ist das eh egal.

    Die Idee ist gar nicht mal schlecht. Danke für den Hinweis. :thumbsup:

  • Hmm, ich habe den Raster interrupt genommen damit der Programmierer genau diese Auswahl hat. Abgesehen davon finde ich 1/50 Sekunde deutlich besser auf die volle Sekunde umzurechnen als 1/60.

    Ja, diesen Vorteil hat aber nur ein PAL-System. Es ist besser, wenn PAL und NTSC-System beide die gleiche Zeitbasis haben, statt es für nur PAL-Benutzer "komfortabel" zu machen.

    Dann kommt so ein Blödsinn wie bei BASIC 7.0 raus, siehe https://www.c64-wiki.de/wiki/TEMPO

    Im Basiccode will man i.R. auf Basis von Sekunden was tun oder eben warten. Ob es aber genau 1 Sekunde ist, oder eben 0,83 Sekunde merkt der anwender wo möglich gar nicht.

    Wenn man vielleicht Musik macht oder Spiele mit einem gewissen Timing macht, dann ist es zumindest unschön und ärgerlich, wenn dann bei der jeweils anderen Platzform etwas durchaus fühlbar schneller oder langsamer ist.

    Dem Argument der portabilität kann ich nur zustimmen. Das abzuändern ist recht einfach. Welcher vorhandene, stets 1/60 Sekunde Interrupt meinst du denn?

    Naja, der IRQ beim C64 wird immer immer 1/60-Takt aufgerufen, der über den Vektor $0314 ($EA31). Da wird ja auch

    mit jedem Interrupt der Timer-Wert für TI hochgezählt (siehe dazu eines meiner vorigen Postings bezüglich RTC).

  • Naja, der IRQ beim C64 wird immer immer 1/60-Takt aufgerufen, der über den Vektor $0314 ($EA31). Da wird ja auch

    mit jedem Interrupt der Timer-Wert für TI hochgezählt (siehe dazu eines meiner vorigen Postings bezüglich RTC).

    Yepp, das wars was ich hören wollte. $314, bzw den Einsprung. Dann weiß ich was gemeint ist. Werde ich sofort in Angriff nehmen. Vielen Dank für die Unterstützung.

  • Läuft mit C64 Studio großartig. Super Arbeit dg5kr :thumbsup:

  • Auf Anregung vom User JeeK und Mac Bacon habe ich die Delay Routine angepasst. Diese verzögert nun ohne Parameter immer um 0,1 Sekunde, unabhängig ob PAL oder NTSC. Als Parameter kann eine Zahl von 0 bis 255 angegeben werden. Das heißt ein Delay wartet maximal 25,5 Sekunden bei DELAY 255. Ein DELAY 0 verzögert halt gar nicht.