Hallo Besucher, der Thread wurde 32k mal aufgerufen und enthält 170 Antworten

letzter Beitrag von EgonOlsen71 am

BASIC V2 Interpreter/Compiler in/für Java

  • So ein Textmodus passt zur normalen Konsolenausgabe von Java gar nicht

    Aber der Textmodus ist doch gerade das, was BASIC so einsteiger- und hacking-freundlich macht.


    Lanterna sieht in Sachen Terminal/Textmodus für Java ganz nett aus. Vielleicht gibt's da ja auch was für 40x25 und PETSCII...

  • Zum Eingeben gibt es ja eine Shell, die eine Art Textmodus darstellt. Die kümmert sich halt nur nicht um den Inhalt des simulierten RAMs oder so und kann kein PETSCII. Dafür ist sie als Editor leistungsfähiger.
    Aber ich verstehe den Wunsch nach was Authentischem, also baue ich eine zusätzliche PETSCII-Konsole. Die kümmert sich dann auch um Bildschirm- und Farbspeicher und um ein paar zusätzliche Speicherstellen wie 53281 und 646 usw.
    Sie ist noch nicht fertig, aber das hier geht schonmal:


  • Egon,


    das scheint ein wirklich heißes scharfes Spielzeug zu werden!
    Es nutzt die Flüssigkeit und Schnelligkeit eines heutigen Durchschnitts-PCs und ich kann nach C64 Konvention Sachen damit machen, die in realem Basic niemals gehen würden, auch kompiliert nicht.


    Das ist ein eigenes Feld für Wild Demos auf Demo Compos und man kann eigene Spiele machen, die nach C64 schmecken und doch anders sind.


    Wenn wir eh schon in einer "eigenen Welt" sind, kannst Du evtl. auch dafür sorgen, dass sich Grafikmodus und Textmodus überlagern können? Dann kann man Textzeichen neben mathematische Kurven plotten.


    Wichtig wäre aus meiner Sicht auch ein Dokument Restrictions.txt wo ganz klar abgegrenzt wird, was Dein Basic kann und was es niemals können wird. Ziel sollte sein, eigenwillige Demos und funktionierende Spiele machen (bewegliche Objekte, Input, Kollision) zu können. Es soll keine C64 Emulation sein sondern ein eigener Werkzeugsatz der vorgibt: das kannst du, das nicht, kombininer das frei und denk Dir als Entwickler etwas Kreatives damit aus!


    Wenn Du z.B. sagst, Grafikmodus und Textmodus sollen sich nicht überlagern weil es entweder technisch nicht geht oder andere Gründe hat, dann müssten das die Hobbyentwickler akzeptieren und damit umgehen.

  • Der PETSCII-Konsolen-Kram ist jetzt soweit fertig (denke ich). Er unterstützt:


    • Screen-RAM von 1024 bis 2023
    • Farb-RAM von 55296 bis 56295
    • Cursorfarbe in 646
    • Hintergrundfarbe in 53281
    • Zeichenmodus (21/32) in 53272
    • POKE, PEEK und WAIT von 198
    • C64-artiges Verhalten bei GET und INPUT
    • Kontrollzeichen in PRINT wie z.B. PRINT CHR$(147) usw.


    Der verwendete Zeichensatz bietet alle PETSCII-Zeichen, bis auf zwei. Das sind die inversen Varianten dieser vielen diagonalen Linien...die sind wohl aus Versehen nicht drin. Kann man nichts machen, fand ich jetzt aber auch nicht so wichtig.
    Das ganze ist als BASIC-Erweiterung implementiert, damit man es von BASIC aus an bzw. ausschalten kann. Der Befehl dazu ist CONSOLE 1/0, die Doku ist in "CONSOLE SUPPORT.txt"


    Mischen mit GRAPHICS BASIC ist möglich, indem man den Konsoleninhalt dort als Shape einbinden kann (siehe LINKSHAPE). Dazu kann man die eigentliche Konsole auch ausblenden. Das sieht dann so aus:



    Zusätzlich habe ich GRAPHICS BASIC noch um eine Funktion SPRITESHAPE(...) ergänzt. Diese holt sich Spritedaten aus dem simulierten RAM und macht daraus einen Shape. Damit kann man quasi alte Sprite-Definitionen "recyclen", wenn man dies denn will. z.B. so:


  • @ EgonOlsen


    Ich habe in Eclipse die Console-Tests laufen lassen.
    Ich habe auch bemerkt, dass die Console- und Graphics-Klassen automatisch statisch angemeldet werden.


    Ich selber bin Java Neuling und über ein paar einfache Console-Übungen noch nicht hinaus. Das Thema Methoden, Klassen, GUI etc. kommt erst jetzt bei mir dran weil die erste Hälfte von meinem Buch sich nur mit Grundlagen auf Console-Basis befasst hat (Variablentypen, Schleifen, Rechnen, mathematische Probleme und Reihen und so Zeugs). Ich werde Java aber weiter lernen, vor allem wenn es so tolle Werkzeuge wie Dein Basic gibt.


    Meine Frage jetzt ist:
    Wie kann ich direkt aus der Konsole heraus ein poke 1024,1 visualisieren?
    Bei Deinen Tests habe ich gesehen dass so etwas klappt und viel mehr. Bei grafischen Sachen geht einfach ein neues Fenster auf nachdem man den Quelltext aus der Konsole mit run startet.


    Aber wie bewirke ich, dass in einem Fenster mit sozusagen 1000 Chars der erste Char links oben gesetzt wird mit einem Zeichen?


    Mir ist da das Eintauchen in den C64 wichtig, ich möchte Java währenddessen vergessen und keinen Java Code schreiben müssen, sondern das über den emulierten C64 tun.


    Natürlich wird Dein Java Werk als solches für mich ein wichtiges Lernobjekt sein. Aber während des "Spielens" will ich im C64 sein und nicht in Eclipse.

  • Wie kann ich direkt aus der Konsole heraus ein poke 1024,1 visualisieren?


    Bei Deinen Tests habe ich gesehen dass so etwas klappt und viel mehr. Bei grafischen Sachen geht einfach ein neues Fenster auf nachdem man den Quelltext aus der Konsole mit run startet.

    Ich bin nicht sicher, ob die Frage bzw. den Kontext richtig verstanden habe. Im Prinzip schreibst du einfach ein kleines BASIC-Programm wie das hier:


    Code
    1. 10 CONSOLE1
    2. 20 POKE1024,1
    3. 30 GET A$:IFA$=""THEN30
    4. 40 CONSOLE0

    ...startest es und damit öffnet sich die PETSCII-Konsole mit Default-Einstellungen und links oben sollte ein A sichtbar sein.


    Oder meintest du was anderes?

  • ...startest es und damit öffnet sich die PETSCII-Konsole mit Default-Einstellungen und links oben sollte ein A sichtbar sein.


    Oder meintest du was anderes?

    Ich habe Bytebreaker Frage so verstanden, wie man sowas programmiertechnisch mit Java macht/umsetzt.
    Also so quasi einen 40 x 25 Zeichen Consolen-Textscreen öffnen und dann mit x/y Cursor Koordinaten ein Zeichen setzen.


    In .NET geht das z.B. mit SetCursorPosition.

  • @EgonOlsen71


    Ich meinte genau das! Der Console-Befehl war mir irgendwie nicht klar.
    Aber es ist logisch, so wie GRON/GROFF.


    Danke vielmals für die Info! Ich meine, der Console1 / Console0 Befehl steht nicht so explizit in Deiner aktuellsten Doku. Oder habe ich den einfach nur übersehen..


    @ syshack


    Ich muss an meiner präzisen Ausdrucksweise arbeiten. ;-)
    Mich interessiert die Java Mechanik im Hintergrund natürlich auch.
    Aber zuallererst will ich die Einbildung haben, eine Art Spezial-C64 zu bedienen ohne etwas von Java im Hintergrund zu merken.



    Edit:


    Es steht drin:


    Commands


    CONSOLE mode (,clear, width, height) - Opens or closes a console. If mode is 0, the console will be closed. If it's >0, a new console will be opened, PRINT output as well as GET and INPUT input will be redirected to it and the console will be shown in a window. If it's <0, the console will be "opened" as well, but not made visible. This is meant for consoles that are supposed to be used in combination with Graphics Basic but that shouldn't be visible. If clear is 0, the console's content (i.e. screen and color ram) won't be cleared. If it's anything else, they will, which is also the default. With width and height, you can specify the console's dimensions. Default is 800*500. The width is leading and the console will always show 40*25 characters. If the height doesn't match this ratio, the output will either be cut off early or won't reach the end of the console.



    Ich war zu schlampig beim Lesen, ich suche immer nach Code-Beispielen weil ich von formalisiertem Syntax-Muster lesen Augenkrebs kriege.

  • Zu den Console-Tests findest du im Projekt ja auch die BASIC-Beispiele in test/resources/ext. Das Lyrics-Beispiel habe ich auch so angepasst, dass es CONSOLE SUPPORT nutzt. Du findest es in LyricsTest.java


    Aber viel ist ja eigentlich nicht dabei. Mehr als CONSOLE 1 und 0 gibt ja schon fast nicht dazu zu wissen.

  • Ich habe eine weitere, momentan eher experimentelle, Absurdität ergänzt: Einen JIT-Compiler, der (wenn aktiviert), Teile des BASIC-Programms zur Laufzeit in Java-Bytecode compiliert. Das funktioniert leider nur, wenn man mit dem JDK arbeitet, weil das JRE keinen Compiler enthält. Solange man in einer IDE unterwegs ist, sollte das aber kein Problem sein.
    Was das bringt, das hängt stark vom Programm ab. Das Fraktal beschleunigt er gerade mal um etwa 15%, aber dieses sehr sinnvolle Programm...



    Code
    1. 10 A=1:B=2:C=3:F=4:R=5:R=12:F=4:G=5:Z=21:D=12:U=11:P=-3:O=3:I=22:Z=8
    2. 20 FOR A=0TO10000000
    3. 100 JJ=A * B * (-C*F+(T*R+-F*(G-Z)-F*G/Z^4)) + (-(D*U))*(P+(O*I*Z))*Z+U
    4. 110 NEXT
    5. 120 PRINT JJ

    ...läuft mit dem JIT 3,6mal so schnell.

  • Ich habe eine weitere, momentan eher experimentelle, Absurdität ergänzt: Einen JIT-Compiler,

    Auch wenn ich vermutlich nie eine Anwendung fuer Dein Meisterwerk habe (Hab nie BASIC gelernt): Ich lese hier mit Wonne mit. :thumbsup:


    Zum einen weil ich selber Java-Liebhaber bin und zum anderen weil mich Emulatoren, Compiler, etc schon immer fasziniert haben. Ich hoffe auf viele weitere solcher Innovationen von Dir...

  • Ich hoffe auf viele weitere solcher Innovationen von Dir...

    Also sowas wie das hier...? Ich habe eine (etwas versteckte) Hilfklasse ergänzt, mit der man BASIC-Code ohne Zeilennummern und stattdessen mit Labeln schreiben kann und die diesen dann in normales BASIC V2 übersetzt. Ist nichts großes, aber man kann dann halt sowas schreiben:


    Code
    1. A=3
    2. OUTPUT:
    3. PRINT"HALLO":A=A+1
    4. IF A<100 THEN OUTPUT
    5. GOTO TERMINATE
    6. PRINT "SHOULD NOT SEE THIS!"
    7. TERMINATE:END


    Und daraus wird dann:


    Code
    1. 100 A=3
    2. 110 REM JUMP TARGET
    3. 120 PRINT"HALLO":A=A+1
    4. 130 IF A<100 THEN 110
    5. 140 GOTO 160
    6. 150 PRINT "SHOULD NOT SEE THIS!"
    7. 160 END

    Das passiert momentan aber (noch?) nicht automatisch.

  • Einen JIT-Compiler, der (wenn aktiviert), Teile des BASIC-Programms zur Laufzeit in Java-Bytecode compiliert.

    Verzeih bitte, ich hätte mal eine kleine Frage in bezug auf Dein interessantes Projekt. Wie handhabst Du beim Kompilieren die FOR-Schleife, genauer gesagt die NEXT-Anweisung im Objektcode? Imitierst Du den Stack mitsamt Stackverhalten des C64-Basics oder erzeugst Du einen davon unabhängigen Code der Form: erhöhe Variable um X und spring zum fest definierten Schleifenanfang. Ich hatte früher mal darüber nachgedacht, einen Basic-Compiler zu schreiben, stolperte aber immer wieder über die NEXT-Anweisung, deren Semantik (welche Variable wird erhöht, wohin wird gesprungen) erst während der Laufzeit entschieden wird anhand des Stackinhalts, so daß eine feste Kompilierung ohne Laufzeitstack, wie man sie z. B. von C kennt, dadurch nicht möglich schien.

  • Wie handhabst Du beim Kompilieren die FOR-Schleife, genauer gesagt die NEXT-Anweisung im Objektcode? Imitierst Du den Stack mitsamt Stackverhalten des C64-Basics...

    ...ja, so mache ich das. Geht nicht anders, weil du beim BASIC V2 ja theoretisch ein Programm mit 20 FOR-Anweisungen aber nur einem NEXT haben kannst.

  • Verzeih bitte, ich hätte mal eine kleine Frage in bezug auf Dein interessantes Projekt. Wie handhabst Du beim Kompilieren die FOR-Schleife, genauer gesagt die NEXT-Anweisung im Objektcode? Imitierst Du den Stack mitsamt Stackverhalten des C64-Basics oder erzeugst Du einen davon unabhängigen Code der Form: erhöhe Variable um X und spring zum fest definierten Schleifenanfang. Ich hatte früher mal darüber nachgedacht, einen Basic-Compiler zu schreiben, stolperte aber immer wieder über die NEXT-Anweisung, deren Semantik (welche Variable wird erhöht, wohin wird gesprungen) erst während der Laufzeit entschieden wird anhand des Stackinhalts, so daß eine feste Kompilierung ohne Laufzeitstack, wie man sie z. B. von C kennt, dadurch nicht möglich schien.

    Das FOR-NEXT im BASIC gaukelt auch nur ein statische Konstrukt vor, ist aber in Wirklilchkeit mit for()-, oder while()-Konstrukten, wie man sie von sonst üblichen statischen Kontrukten anderer Compiler-Sprachen kennt, nicht vergleichbar. Es ist eigentlich mehr, als es gemeinhin den Anschein hat. Ich würde es eigentlich eher als primitiven Exception-Mechanismus mit Auto-inkrement/Dekrement-Funktion sehen, mit dem man halt zufällig auch auch Schleifen machen kann (was durch die Bezeichnung der Tokens auch so suggeriert wird), aber der für alles gut ist, wenn man an einen definierten Ausgangspunkt zurück will, und das in Verschachtelung. Die Abbildung in eine statische Struktur könnte dann nur durch eine aufwändigere semantische Analyse des Codes, wenn sozusagen, die Verhältnisse am Stack als nicht mehr von Laufzeit abhängig erkennbar wären. Sowas könnte man mit entsprechenden Compileroptionen für einen Compiler leichter machen, also wie genau der Compiler die Analyse betreiben soll. Die Verwendung von nichtanonymen NEXT-Aufrufen könnte einem Compiler da auch helfen.