RunCPM Speed-Vergleich auf verschiedenen Plattformen

  • Wegen BREAKCHAR: das geht leider auf Windows bzw. POSIX nicht. Der Mechanismus setzt voraus, dass I/O non blocking ist, was getchar auf POSIX Platformen nicht tut. Bei Arduino kann ich Zeichen aus dem Serial Stream abfangen.


    Ich habe eben mal einen Signalhandler implementiert und auf Windows und Mac getestet. Windows mit MINGW64 (siehe unten). Wenn ihr die neue Version von basic.c und hardware-posix.h runterladet und compiliert, müsste jetzt Ctrl-C ein Program unterbrechen können. Das ist nur wenig getestet. Feedback ist willkommen.


    Man kann jetzt aber den Interpreter nicht mehr mit Ctrl-C verlassen. Das geht aber immer mit CALL 0.


    Wegen Compilerproblemen: ich habe dazu eben auch eine neue Version von basic.c und hardware-posix.c eingecheckt. Diese Version kann mit MINGW64 compiliert werden. Die bisherige Version war nur MINGW32 getestet. Das "alte" sprich originale MINGW von mingw.org hat Standard POSIX Filehandling. Die Header von MINGW64 sehen eher wir Windows/MSDOS aus. Setzt bitte die Flag MINGW64 in basic.c vor dem Compilieren.

    Edited once, last by slenz ().

  • Habs noch nicht probiert, aber mal in die Anleitung geschaut bzw. diese gelesen. Sieht interessant aus und könnte auch auf anderen Plattformen evtl. interessant sein. Insbesondere natürlich, wenn es schnell ist.


    Hätte mal ein paar Anregungen, was mir so aufgefallen/eingefallen ist.


    Zunächst aber mal - das mit den REM Zeilen (was ja hier der Diskussionsauslöser war) geht so wahrscheinlich wirklich nicht. Es verhindert vor allem GANZ wirksam, daß Leute sowas benutzen, wenn sie einfach mal Sachen probeiren wollen, die sie im Netz gefunden haben und die REM Zeilen haben. Niemand fängt heute an per Hand REM Zeilen zu entfernen oder gar Anführungszeichen drumherum zu setzen. Kurz für wirklich Benutzer, die selbst Programme damit schreiben ist das so OK und zumutbar (zumal es ja dann woanders auch mit den Anführungszeichen läuft), aber es schränkt wahrscheinlich den Kreis potentieller "Probierer" ziemlich ein.


    Na ja, egal. Wichtiger sind evtl. diese Sachen hier:


    Es gibt anscheinend nur eine Schleifenform: FOR NEXT STEP. Ganz klassisch. Gehört sich auch so. Aus dem Handbuch ist nicht ersichtlich, ob man auch abwärts zählen kann.


    Es wäre evtl. gut noch eine paar andere Varianten zu haben. Also sowas wie WHILE. Mir haben ja immer die späteren Commodore Schleifen Konstrukte in BASIC >= 3.5 gefallen, diese sind DO ... LOOP mit den Zusätzen WHILE und UNTIL , https://www.c64-wiki.de/wiki/LOOP_(BASIC_3.5)


    Ansonsten ist eine Mehrfachauswahl schön. Gerade in BASIC wird sowas sonst ganz schnell zu einem IF Desaster. Also sowas wie SWITCH(variable) - CASE 1 ; CASE 2 ; CASE 3 etc. ; In BCC Basic ließt sich das schöner, da wird benutzt CASE variable OF - WHEN 1 ; WHEN 2 ; ... ENDCASE.

    Evtl. lassen sich da ja auch zwei Varianten zumindest intern anlegen, die für Strings und Zahlen und Ints/Bytes unterschiedlichen Code verwenden.


    Da du ja die Variablen alle letztlich als Byteblocks ablegst inkl. Strings, kann man da evtl. schön solche Byteweisen Zugriff erlauben, wie das BBC sie hat. Dort kann man mit Variable!4 auf das 4te Byte/Word der Variablen direkt zugreifen. Da das auch mit Strings und Arrays geht, wird das eine schöne Form von PEEK/POKE und es ist relativ flexibel nutzbar, weil man statt der !4 auch eine Variable nehmen kann.

    In den deutschen Handbücher nennen sie das so schön "Byte Indirektionsparameter" ... http://www.riscos.com/support/…/part2/accessmemlocs.html

    Ist ein mächtiges Tool und würde hier auch schon zum Einsatzzweck passen.


    Außerdem sind so ein paar Sachen aus C sicherlich auch eine Überlegung wert. Insbesonder dieses Variable++ bzw. Variable-- ist was sehr Nettes. Man kann ja ein Space dazwischen lassen. Und für Variable += 4 hätten sicher auch einige Leute was übrig.



    So, ab hier wird "spinnig"


    Was mir immer schon gefallen hätte, wäre sowas wie ein impliziter Counter in Schleifen. Insbesondere aber sowas wie ein Zusatzcounter, der in einer Schleife einfach mit hochgezählt werden kann. Also ungefähr sowas in der Art hier

    FOR I = 0 TO 100 [ STEP 1 [ WITH C1, Z, X ] ] : ... : NEXT I

    wobei C1, Z, X jeweils genauso wie I mitverändert werden.


    Schöne wäre auch sowas wie

    FOR I = 0 TO 100 [ STEP 1 [ WITH COPY C1, Z, X ] ] : ... : NEXT I

    was das gleiche macht, aber C1, Z, X werden nach Ablauf der Schleife wieder auf ihren Ursprungswert zurückgesetzt.

    Könnte auch heißen

    FOR I = 0 TO 100 [ STEP 1 [ WITH C1, Z, X [ USECOPY ] ] ] : ... : NEXT I

    auch wenn das ein schwieriges Konstrukt ist, weil sehr BASIC untypisch.


    Die Grafikbefehle sind ein wenig ... wenig. Vielleicht kann man die prinzipiell auch komplett weglassen und das wie eine Bibliothek behandeln und einen Befehl einführen, der abgfragt, ob Grafikbefehle überhaupt "einkompiliert" sind. Die meisten Leute auf den Mikrocontrollern werden sie eh nicht verwenden (können/wollen).

    Wenn sie aber dabei sind, dürfen es wirklich ein paar mehr sein. Insbesondere aber sollte man sich evtl überlegen, wie man die Koordinaten benutzt. Es hat nämlich gerade bei heute möglichen Auflösungen durchaus seinen Charme, wenn man die z.B. auch generell als Bildschirm-relativ angeben kann. Also etwa als PLOT ( X R, Y R ) bzw. PLOTR( X, Y ), wobei in dem Fall 100% die Maximalauflösung ist. Möglicherweise macht es auch Sinn statt 100% eine interne 255 zu nehmen oder eine 65536 oder mehr und Kommawerte (oder gefakte Kommawerte) zuzulassen. Der Charme bei sowas ist, daß man z.B. Diagramme o.ä. überall dann ähnlich anzeigen kann. Für präzise Sachen und Games taugt es eher bedingt (bzw. nur bei hohen realen Auflösungen).

    Außerdem ist ein TRIANGLE Befehl was sehr hübsches. Zumindest wenn man heute Spielkinder auf die "Plattform" holen will.


    So und jetzt ist erstmal gut ... ;)

  • Ich habe eben mal einen Signalhandler implementiert und auf Windows und Mac getestet.
    Windows mit MINGW64 (siehe unten). Wenn ihr die neue Version von basic.c und hardware-posix.h runterladet und compiliert, müsste jetzt Ctrl-C ein Program unterbrechen können.
    Das ist nur wenig getestet. Feedback ist willkommen.


    Man kann jetzt aber den Interpreter nicht mehr mit Ctrl-C verlassen. Das geht aber immer mit CALL 0.


    Wegen Compilerproblemen: ich habe dazu eben auch eine neue Version von basic.c und hardware-posix.c eingecheckt. Diese Version kann mit MINGW64 compiliert werden. Die bisherige Version war nur MINGW32 getestet.
    Das "alte" sprich originale MINGW von mingw.org hat Standard POSIX Filehandling. Die Header von MINGW64 sehen eher wir Windows/MSDOS aus. Setzt bitte die Flag MINGW64 in basic.c vor dem Compilieren.

    slenz Ich habe es eben mal mit dem WinLibs MinGW32 und MinGW64 compiliert und getestet.

    (GCC 12.2.0 + LLVM/Clang/LLD/LLDB 15.0.7 + MinGW-w64 10.0.0 (MSVCRT) - release 4)


    Bei beiden Versionen klappte es mit dem Flag MINGW64 (bei MinGW32 mit originaler dirent.h).


    Ctrl-C klappt nun einwandfrei wie auch die Ausgabe von CATALOG ;)

    Das Ctrl-C hatte ich bei den 1000 Stellen von Pi getestet und die Ausfuehrung wurde sauber abgebrochen, aber man ist noch im Interpreter. CALL 0 brachte mich auch einwandfrei zureuck zum Prompt.


    Ein Zeilenumbruch nach dem Ctrl-C waer schoen (hatte hier 2mal ENTER gedrueckt) und eine Meldung wie "BREAK in 150" noch erste Sahne :)

    Peter z80.eu Gegen einen Alias von SYSTEM zu CALL 0 haette ich auch nichts ;)

    Einen Geschwindigkeitsvorteil bringt die 64Bit Version nicht gegenueber der 32Bit Version,
    dafuer laeuft die 32Bit Version auch unter Windows 64Bit ;)


    Compiliert hatte ich je nach Bit mit folgendem Befehl:


    Code
    gcc -m32 basic.c -o basic-win-32bit.exe -O3 -mconsole -lm
    gcc -m64 basic.c -o basic-win-64bit.exe -O3 -mconsole -lm
  • Jetzt nur noch wie vorgeschlagen SYSTEM als zusätzlichen Befehl implementieren, und die Welt ist fast in Ordnung.

    Das mit den Anführungsstrichen für die Zeichenketten nach dem REM Befehl finde ich zwar immer noch gewöhnungsbedürftig, aber wenn man es weiß kann man damit leben 8o

    "The biggest communication problem is we do not listen to understand. We listen to reply." - Stephen Covey


    Webseite und Blog ist immer noch - seit fast 20 Jahren - online.

  • Das mit dem SYSTEM ginge schnell zu machen. Warum ist es nicht drin? Weil Tokens knapp sind. Der Interpreter ist so gebaut, dass er strikt 1 byte Tokens verwendet im Bereich von -1 bis -127. Momentan sind nur noch 20 Tokens frei. Deswegen spare ich.


    Die alten BASIC hatten das gleich Problem und haben irgendwann 2 byte Tokens eingeführt. Man sieht das schön, wenn man sich das Amstrad BASIC anschaut, dass sehr viele Keywords hatte.


    Ich zögere gerade, 2byte Tokens einzuführen, weil ich will, dass das BASIC auf Arduino 8 bit noch läuft. Ich werde in den nächsten Tagen 1.4 final releasen, danach schaue ich mir den Lexer nochmal an. Stichwort, dynamischer Namespace, also echte Aliases.

  • Zunächst aber mal - das mit den REM Zeilen (was ja hier der Diskussionsauslöser war) geht so wahrscheinlich wirklich nicht. Es verhindert vor allem GANZ wirksam, daß Leute sowas benutzen, wenn sie einfach mal Sachen probeiren wollen, die sie im Netz gefunden haben und die REM Zeilen haben. Niemand fängt heute an per Hand REM Zeilen zu entfernen oder gar Anführungszeichen drumherum zu setzen. Kurz für wirklich Benutzer, die selbst Programme damit schreiben ist das so OK und zumutbar (zumal es ja dann woanders auch mit den Anführungszeichen läuft), aber es schränkt wahrscheinlich den Kreis potentieller "Probierer" ziemlich ein


    Das mit dem REM ist tatsächlich eigenartig. Es ist eine direkte Konsequenz der Tokenisierung. Wenn man vollständige(!) Tokenisierung macht, muss jedes Objekt im Programspeicher einen Typ haben. Man könnte theoretisch einen Typ LITERAL einführen und dann würde man folgenderweise tokenisieren


    10 REM Das ist ein Text

    20 PRINT


    als

    LINENUMBER 10

    Token REM

    LITERAL 16 Das ist ein Text

    LINENUMBER 20


    Dann kann man bei LIST wieder eindeutig detokenisieren. Das Problem ist ja, dass man LIST machen will, d.h. den Code wieder zurück in Text verwandeln will.


    Warum verwende ich Strings? Weil


    10 REM "Das ist ein Text"


    einfach so tokensiert wird


    LINENUMBER 10

    Token REM

    STRING 16 Das ist ein Text


    MS BASIC hat das Problem gelöst, indem es nur die Zeilennummern und die Kommandos tokenisiert und sonst alle Objekte als Zeichenketten speichert. Das heisst dann aber auch, dass in Schleifen immer wieder die gleiche Zahl geparst werden muss. Der Grund warum die das so machen ist aber genau das Problem, das man hier bei REM hat.


    Quote

    Es gibt anscheinend nur eine Schleifenform: FOR NEXT STEP. Ganz klassisch. Gehört sich auch so. Aus dem Handbuch ist nicht ersichtlich, ob man auch abwärts zählen kann.

    Es wäre evtl. gut noch eine paar andere Varianten zu haben. Also sowas wie WHILE. Mir haben ja immer die späteren Commodore Schleifen Konstrukte in BASIC >= 3.5 gefallen, diese sind DO ... LOOP mit den Zusätzen WHILE und UNTIL , https://www.c64-wiki.de/wiki/LOOP_(BASIC_3.5)


    Ja und nein. Es gibt ein paar Tricks, folgendes ist legal


    FOR I

    ....

    IF some condition THEN BREAK

    NEXT


    FOR I

    IF some condition THEN BREAK

    ....

    NEXT


    Ersteres ist DO ... UNTIL

    Zweiteres ist WHILE .... WEND


    Außerdem geht noch


    FOR I

    ... block A ...

    IF some condition THEN CONT

    ... block B ...

    NEXT


    CONT zählt in der Schleife die Variable weiter und überspringt block B


    Ich wollte mir Tokens sparsam sein, deswegen ist FOR eine Schleife für alle Fälle.


    Quote

    Ansonsten ist eine Mehrfachauswahl schön. Gerade in BASIC wird sowas sonst ganz schnell zu einem IF Desaster. Also sowas wie SWITCH(variable) - CASE 1 ; CASE 2 ; CASE 3 etc. ; In BCC Basic ließt sich das schöner, da wird benutzt CASE variable OF - WHEN 1 ; WHEN 2 ; ... ENDCASE.


    Das ist syntaktisch recht kniffelig, ich hatte darüber nachgedacht aber keine einfache Syntax gefunden. Es müsste in etwa so sein:


    10 SWITCH <expression>

    20 CASE <expression>

    .... block A ...

    30 CASE <expression>

    .... block B ....

    ....

    90 END SWITCH


    Das ganze hat nur einen wirklichen Nutzen, wenn man das als Block Struktur aufbaut. Man muss dann aber SWITCHES in CASES parsen, was ein relativer Aufwand ist. Und dann wie macht man Dinge mit : eindeutig.


    Ist

    10 SWITCH <expression> : CASE <expression>: .... block A ...: CASE <expression>.... block B ....: END SWITCH

    was man will?


    Quote

    Die Grafikbefehle sind ein wenig ... wenig. Vielleicht kann man die prinzipiell auch komplett weglassen und das wie eine Bibliothek behandeln und einen Befehl einführen, der abgfragt, ob Grafikbefehle überhaupt "einkompiliert" sind. Die meisten Leute auf den Mikrocontrollern werden sie eh nicht verwenden (können/wollen).

    Das ist tatsächlich so. Auf den MCUs ist das hardware-arduino.h File sehr komplex. Im Grunde ist es ein Mini OS. Die Grafikbefehle werden nur einkompiliert wenn die MCU eine Graphikhardware hat und HASGRAPH gesetzt ist. Generell werden viele Kommandosets nur angezogen, wenn die Platform das kann. Beispiel ist File I/O. Eine Platform ohne Filesystem hat kein OPEN und CLOSE.


    Generell sind die Graphikbefehle nur eine Skizze. Ich muss mir noch genauer einfallen lassen, wie man das macht.

  • Dies ist in MMBasic beim Color Maximite 2 anders gelöst. Die Firmware entfernt alle Kommentare und unnötige Leerzeichen, wenn das Programm in den Programmspeicher geladen wird. Infolgedessen können so viele Kommentare verwendet werden, wie nötig oder gewünscht. Nur im edit-Mode und auf dem Massenspeicher wird dafür Platz benötigt. Zur Laufzeit gibt es dadurch weder Speichermangel noch Geschwindigkeitseinbußen.

    Das ist eine gute Sache, weil ein Programm mit vielen Kommentaren viel einfacher zu verstehen ist.

  • Also sowas mag ich z.B. gar nicht, wenn das Programm anfängt selbsttätig Spaces oder anderes dazuzusetzen oder zu entfernen. Was anderes ist, wenn man sowas selbst als Macro o.ä. eingestellt hat. Aber z.B. der Editor von QBasic oder QuickB ist diesbezüglich sehr häßlich. Der einzige Vorteil den sowas hat ist, daß Programme dann immer gleich ordentlich aussehen - aber das ist ja genau der Kritikpunkt. :)


    Das eigentliche Problem an den REM Zeilen entsteht m.E. dann, wenn man echten Code "kommentiert" also z.B. mit REM ausmarkiert. In dem Moment ändert sich das dann hier von Token zu String bzw geht ohne Anführungsstriche nicht. Und noch schlimmer wird dann die entgegengesetzte Operation. Da muß ja i.P. der String wieder in Token gewandelt werden. So gesehen ist das eigentlich rein prinzipiell schon erstmal eine gute Lösung mit dem String für reine Kommentare.

    Vielleicht wäre ja eine Option, daß man hinter REM einfach immer und per Definition einen String erwartet, der dann auch bis zum Zeilenende reicht und folglich gar nicht besonders markiert werden muß (also ohne Anführungszeichen). Damit man aber trotzdem noch Programmzeilen mit Code ausmarkieren kann, macht man einfach ein Zuatzkommando auf: sowas wie "RMK" (remark) oder "CRM" (code rem) oder ":RM".



    Ich wollte mir Tokens sparsam sein, deswegen ist FOR eine Schleife für alle Fälle.


    OK. Scheint ja eng im Speicher zu sein.


    Der C nahe Ansatz wäre dann aber gewesen, eine While Schleife zu benutzen. ;)




    Na ja, je nachdem, wie komplex man das zulassen will. Für die reine Benutzung und das, was man oft mit sowas macht, würde es wohl völlig gausreichen, wenn nach einem CASE gar kein Block kommt, sondern das CASE einfach nur bis Zeilenende wirkt. Wer dann unbedingt mehr braucht, muß halt erstmal Gosubs bemühen, also


    Code
    10 SWITCH <expr/var> 
    20 CASE <expr> anweisung1 [ : anweisung2 [ : anweisung3 [ ... ] ] ]
    30 CASE <expr> anweisung1 [ : anweisung2 [ : anweisung3 [ ... ] ] ]
    40 CASE <expr> anweisung1 [ : anweisung2 [ : anweisung3 [ ... ] ] ]
    50 END SWITCH



    Generell sind die Graphikbefehle nur eine Skizze. Ich muss mir noch genauer einfallen lassen, wie man das macht.


    Klingt gut.


    Meine Ideen, wo man dafür Anregungen holen kann, wären die Löve Bibliothek und die Allegrobibliothek und da v.a. der 2D Teil. Außerdem kannst Du hier mal nach tomtom suchen. Da gibt es auch was. Siehe Double LORES Bibliothek für AppleSoft

  • MS BASIC hat das Problem gelöst, indem es nur die Zeilennummern und die Kommandos tokenisiert und sonst alle Objekte als Zeichenketten speichert. Das heisst dann aber auch, dass in Schleifen immer wieder die gleiche Zahl geparst werden muss. Der Grund warum die das so machen ist aber genau das Problem, das man hier bei REM hat.


    Gerade noch aufgefallen ... DAS macht aber auch alles richtig wunderbar langsam. Will man wohl eher nicht.

  • Es paßt schon. Aber es ist eben wohl nicht das, was so ein üblicher Basic Interpreter macht. Der hat doch eigentlich die Kommentare etc. eben immer mit im Speicher - deshalb tritt ja diese Art Problem überhaupt erst auf. Einen Compiler stört sowas gar nicht, v.a. deshalb, weil er ja genau das, was Du da vorschlägst, als allererstes macht.


    Der macht auch aus Funktionsnamen oder Befehlen keine Tokens - zumindest keine in der Art, daß er sie auch in normalen Text rückübersetzen können soll.


    So gesehen: der Vorschlag ist gut und würde helfen, aber eben nicht, wenn die Kommentare beim Ausführen immer mit im Speicher stehen sollen.

  • Es ist halt kein Vorschlag, sondern Realität.

    Der CMM2 ist die schnellste BASIC-Maschine, die ich habe.

    Das Text-Apfelmännchen braucht etwa eine Drittel Sekunde.



    … und mit 121 Zeilen zu je 255 Zeichen braucht es etwas mehr als 5 Sekunden.


    Das ist ohne Compilieren schon ziemlich schnell. Und ob da Kommentar Befehle genutzt werden oder mit Leerzeichen der Listing besser lesbar gemacht wird ist egal.

  • Code
    10 SWITCH <expr/var> 
    20 CASE <expr> anweisung1 [ : anweisung2 [ : anweisung3 [ ... ] ] ]
    30 CASE <expr> anweisung1 [ : anweisung2 [ : anweisung3 [ ... ] ] ]
    40 CASE <expr> anweisung1 [ : anweisung2 [ : anweisung3 [ ... ] ] ]
    50 END SWITCH

    Das gibt es schon, uns zwar geht das so:


    Code
    10 INPUT A
    20 IF A=1 THEN PRINT "EINS"
    30 ELSE IF A=2 THEN PRINT "ZWEI"
    40 ELSE IF A=3 THEN PRINT "DREI"
    50 ELSE PRINT "Unbekannt"
    60 GOTO 10

    ELSE kann bei IoT BASIC auf der nächsten Zeile nach IF kommen. Damit kann man genau solche Kettenabfragen bauen. Deswegen habe ich das so implementiert. Das ist ein Trick. ELSE wird vom Parser als "terminal symbol" gesehen, also einfach ein Zeilenanfang oder ":" . IF sucht das ELSE bis zum Anfang der Folgezeile es checkt dann, ob das ELSE vielleicht nach der Zeilennummer kommt. Das kann man mit minimalen Aufwand einbauen und kriegt eine Menge Nutzen für ein paar Bytes mehr Programmcode.

  • Vielleicht wäre ja eine Option, daß man hinter REM einfach immer und per Definition einen String erwartet, der dann auch bis zum Zeilenende reicht und folglich gar nicht besonders markiert werden muß (also ohne Anführungszeichen).

    Wenn man es beim REM immer als String nehmen wuerde, muesste man nur schauen ob man evtl. vorne und hinten ein " einfuegt oder ob diese schon vorhanden sind.

    So koennte man beider Versionen nutzen.


    Oder man strippt diese wenn vorhanden und nimmt alles nach dem "REM " (also ohne das eine Leerzeichen) als String - somit koennten andere Source-Quellen einfach eingefuegt/pasted werden ;)

  • Quote

    Vielleicht wäre ja eine Option, daß man hinter REM einfach immer und per Definition einen String erwartet, der dann auch bis zum Zeilenende reicht und folglich gar nicht besonders markiert werden muß (also ohne Anführungszeichen). Damit man aber trotzdem noch Programmzeilen mit Code ausmarkieren kann, macht man einfach ein Zuatzkommando auf: sowas wie "RMK" (remark) oder "CRM" (code rem) oder ":RM".

    Ich hab das mal so ähnlich versucht. Scheint zu gehen. Ist bisher nur kurz getestet. Danke für den Gedanken!

  • Die Berechnung der 1000 Stellen - in Windows - geht in ca. 10 Sekunden durch ;)
    (der TTGO VGA32 brauchte 281.68301 Sekunden fuer die 1000 Stellen)

    Ich hatte das MMBASIC auf einem Picomite immer als schnell im Kopf, deshalb machte ich heute (nachdem die Grippe hier wieder bei mir abebt) den Gegenvergleich - und muss dabei bleiben, dass IoTBASIC/TinyBASIC von slenz ist echt schnell(er) ;)


    Wobei MMBASIC hier zu Gute zu halten ist, dass es sich nicht gross mit den REMs bremsen laesst.

    Allerdings ist es ca. 4x so langsam, wie das IoTBASIC/TinyBasic auf dem TTGO VGA32
    (wobei ich nicht weiss, ob MMBASIC auf dem Pico auch mit 250Mhz compiliert wurde, da es nur ein .UF2 Binary gibt)



  • Die Berechnung der 1000 Stellen - in Windows - geht in ca. 10 Sekunden durch ;)
    (der TTGO VGA32 brauchte 281.68301 Sekunden fuer die 1000 Stellen)

    Ich hatte das MMBASIC auf einem Picomite immer als schnell im Kopf, deshalb machte ich heute (nachdem die Grippe hier wieder bei mir abebt) den Gegenvergleich - und muss dabei bleiben, dass IoTBASIC/TinyBASIC von slenz ist echt schnell(er) ;)

    Freut mich! Ich mache übrigens gerade speziell für Raspberry PI ein paar neue Dinge. Graphik läuft schon, VT52 Terminalemulation auch. Bin grad dabei eine gute GPIO Library einzubinden und MQTT. Damit kann man dan einen Raspberry PI Homecomputer bauen.

  • Freut mich! Ich mache übrigens gerade speziell für Raspberry PI ein paar neue Dinge. Graphik läuft schon, VT52 Terminalemulation auch. Bin grad dabei eine gute GPIO Library einzubinden und MQTT. Damit kann man dan einen Raspberry PI Homecomputer bauen.

    slenz Wie siehst Du die Chance eine Version zu definieren, die auf dem RPi Pico laeuft und den USB-Port als serielle Aussgabe nutzt und die SPI-Pins (zusaetzlich zu SS/CS - also auc MISO, MOSI, SCLK) selbst definieren kann?

    Bis jetzt sah es fuer mich in Deinem Source so aus, als ob Du Dich auf die Standard-Pindefinition der Boards verlaesst (bis auf SS/CS). Oder welche Pinnummerm waren bei Dir die Standard-Pinnummern dafuer?


    Beim Pico gibt es da ja selbst fuer SPI0/SPI1 mehrere Moeglichkeiten.

    So nutze ich fuer RunCPM schon solch ein Board mit SPI-SDCard-Adapter:


  • Müsste gehen. Sogar eher einfach. Es ist allerdings bei jedem Board anders. Ich schaue das mal an.

  • Bis jetzt sah es fuer mich in Deinem Source so aus, als ob Du Dich auf die Standard-Pindefinition der Boards verlaesst (bis auf SS/CS). Oder welche Pinnummerm waren bei Dir die Standard-Pinnummern dafuer?


    Beim Pico gibt es da ja selbst fuer SPI0/SPI1 mehrere Moeglichkeiten.

    So nutze ich fuer RunCPM schon solch ein Board mit SPI-SDCard-Adapter:

    Also, das geht so:


    Die Standard SP bus pins sind

    #define PIN_SPI_MISO (16u)

    #define PIN_SPI_MOSI (19u)

    #define PIN_SPI_SCK (18u)

    #define PIN_SPI_SS (17u)


    Wenn ich das auf Deinem Bild sehe, hast Du das genauso schon angeschlossen.


    Dann musst du in die Hardware Definition gehen in hardware-arduino.h und folgendes setzen


    #undef USESPICOSERIAL

    #undef ARDUINOPS2

    #undef ARDUINOUSBKBD

    #undef ARDUINOZX81KBD

    #undef ARDUINOPRT

    #undef DISPLAYCANSCROLL

    #undef ARDUINOLCDI2C

    #undef ARDUINONOKIA51

    #undef ARDUINOILI9488

    #undef ARDUINOSSD1306

    #undef ARDUINOMCUFRIEND

    #undef ARDUINOEDP47

    #undef ARDUINOGRAPHDUMMY

    #undef LCDSHIELD

    #undef ARDUINOTFT

    #undef ARDUINOVGA

    #undef ARDUINOEEPROM

    #undef ARDUINOI2CEEPROM

    #undef ARDUINOEFS

    #define ARDUINOSD

    #undef ESPSPIFFS

    #undef RP2040LITTLEFS

    #undef STM32SDIO

    #undef ARDUINORTC

    #undef ARDUINORTCEMULATION

    #undef ARDUINOTONEEMULATION

    #undef ARDUINOWIRE

    #undef ARDUINOWIRESLAVE

    #undef ARDUINORF24

    #undef ARDUINOETH

    #undef ARDUINOMQTT

    #undef ARDUINOSENSORS

    #undef ARDUINOSPIRAM

    #undef STANDALONE

    #undef STANDALONESECONDSERIAL


    es sind also alle undef außer ARDUINOSD


    Es gibt aber noch eine weitere Einstellung. Du musst darauf achten, dass in basic.c das Flag HASEVENTS nicht gesetzt ist. Grund dafür ist, dass attachInterrupt in den core files vom Raspberry Pi Pico anders funktioniert. Ich muss mir das nochmal genauer ansehen.

  • slenz Danke, leider komme ich wohl erst in ca. 1 Woche wieder an meinen Rechner. Bis dahin nur uebers Smartphone von unterwegs.

    Dann werde ich dies sicher testen.


    Mein Versuch mit TurboC 2.x und 3.0 brachte leider keinen Erfolg.

    Bei 2.x (2.01?) war TurboC das basic.c zu lang und er wollte nach ca. 2700 Zeilen von 7700 das File truncaten (trotz dosify der Sourcefiles)

    Wann hattest Du zuletzt den DOS - Compile getestet? ;)

  • Letzte Woche ;-). Du musst unbedingt mit dem Kommandozeilencompiler übersetzen, also


    TCC basic.c


    dann wichtig, das File hardware-posix.h muss hardware.h heissen im DOS Kontext, weil ja nur 8 Zeichen erlaubt. Ich teste nur mit TCC 2, den 3.0 habe ich nicht.


    TC basic.c geht nicht, weil der Editor nur 64 kB Filelänge verkraftet.


    Es ist übrigens ein fertiges DOS Binary im Repository für das Release 1.4.

  • Man kann jetzt aber den Interpreter nicht mehr mit Ctrl-C verlassen. Das geht aber immer mit CALL 0.

    CALL 0 ist sehr ungewöhnlich, jeder wird es mit SYSTEM versuchen...

    Auch lustig, besoders wenn Zuschauer dabei sind, ist der Ausstieg mit call bratkartoffel :)

    Mir ist echt nichts besseres einfallen, als Call zu verwenden. CALL 1 gibt es übrigens auch. Das started den Filesystem Code auf Arduino neu. Ich nehme CALL meistens her, um irgendwas zu Laufzeit zu testen. SET und CALL sind ein bisschen Allheilmittel, wenn ich keine Lust habe, ein neues Token in den Code einzuführen.

  • Letzte Woche ;-). Du musst unbedingt mit dem Kommandozeilencompiler übersetzen, also

    TCC basic.c

    dann wichtig, das File hardware-posix.h muss hardware.h heissen im DOS Kontext, weil ja nur 8 Zeichen erlaubt. Ich teste nur mit TCC 2, den 3.0 habe ich nicht.

    Ahh - TCC war der Trick - ich wollte es mal selbst kompilieren ;)
    Das mit der Datei hatte ich bemerlt und diese einfach hwp.h genannt :)
    Der TCC von v2.x macht mir dann auch ein .EXE - im Gegensatz zum v3.x der mir 8 Fehler schmeisst.

    Ist aber nicht wild, wenn der v2.x laeuft.

    Eine v3.x findet man ueber folgenden Thread