BASICload -- MC loader für BASIC

There are 13 replies in this Thread which has previously been viewed 2,912 times. The latest Post (January 17, 2019 at 8:51 AM) was by Zirias/Excess.

  • So, dann möchte ich hier auch mal etwas vorstellen, was für meinen Beitrag zu "BASIC-Weihnachten" entstanden ist. Ich hatte ja früh die Idee, "nette" Musik einzubinden und dazu einen möglichst minimalen SID-Player für BASIC zu schreiben (der wird später auch noch separat veröffentlicht). Problem war dann, obwohl der nicht allzu viel kann, war der Code doch für ein abzutippendes BASIC-Programm recht groß -- 64 Zeilen DATA-Wüste nur für den Player waren es beim ersten Versuch. Außerdem dauerte da natürlich auch der Start recht lange .. DATA/READ und POKE sind nicht gerade flott.

    Also habe ich mir etwas überlegt, um das besser zu machen. Die Idee war schnell, dass in den BASIC Zeilen einfach direkt der MC-Code als hex steht. Leider pfuscht da der Tokenizer rein, die Sequenz "DEF" wird z.B. in ein Token übersetzt. Also mussten noch Anführungszeichen drumherum.

    Das Ergebnis ist ein kleines (PC) Tool, das ein PRG mit dem Maschinencode nimmt und passenden BASIC-Source ausgibt, inklusive einer kleinen Laderoutine, die "klassisch" per DATA/POKE in den Datasettenpuffer geschrieben wird. Diese Routine liest dann die Hex-Strings und springt am Ende direkt zu dem geladenen Maschinencode (es wird erwartet, dass die Ladeadresse auch die Einsprungadresse ist).

    Im Ergebnis wird das BASIC Programm ein gutes Stück kleiner als mit klassischem DATA/POKE und die Geschwindigkeit ist um ein Vielfaches besser. Falls man viele sich wiederholende Bytes hat wird das Abtippen schwieriger (Nullen zählen) -- das kann man dann aber elegant durch crunchen (z.B. mit exomizer) umgehen.

    Source: Please login to see this link.
    Da ist auch ein kleines README -- Aufruf z.B. mit basicload <mycode.prg >loader.bas.

    Einen win32 build hänge ich mal an ;)

    Hier noch der kommentierte Source der Laderoutine:

  • Örks! Ich habe aus Versehen einen Build von einem alten (nicht veröffentlichten) Stand hochgeladen, der noch keinen Parameter für die Startzeilennummer kann. Kann das leider nicht mehr löschen/editieren :(

    Der Anhang im Eingangspost ist Müll!

    Hier im Anhang kommt der Build, der auch wirklich zu der Version auf Github passt :) Jetzt auch "gestrippt" (also ohne Debugging-Symbole).

    Übrigens, der C-Code ist, mehr oder weniger bewusst, "gemurkst". Es ging darum, möglichst schnell ein funktionierendes Tool für meinen Beitrag zum Heftchen zu haben. Nichtsdestotrotz funktioniert's natürlich ;) Über den ASM Code des Loaders habe ich allerdings etwas länger nachgedacht, der sollte ja so kurz wie nur möglich werden. Wenn jemand noch eine Möglichkeit findet weiter zu kürzen, bitte posten ;)

  • ich wuerde evtl versuchen bei hexloop eine tabelle zu benutzen, das koennte ein paar bytes rausholen.
    leider hab ich noch nicht richtig verstanden was das prg machen soll.

    es laed eine "string" prg nach und springt dann in dieses?

    ich stelle mir das so vor

    ob das funktioniert hab ich jetzt nich getestet und wie die geschwindigkeit ist, ist auch fraglich.
    auch ob das kuerzer wird hab ich jetzt nicht nachgezaehlt.
    evtl kannst ja was draus machen.

    salute

  • leider hab ich noch nicht richtig verstanden was das prg machen soll.

    Also, am einfachsten sieht man das wohl an einem Beispiel: Wenn ich es auf Please login to see this link. (in der Version mit Systemzeichensatz) "loslasse" kommt folgendes "BASIC" heraus:

    Zum Vergleich der "klassische" Ansatz, der das gesamte Maschinenprogramm aus DATA-Zeilen lädt:

    Die Version mit meinem Tool ist hier gute 10 Zeilen kürzer und in einem Bruchteil der Zeit geladen und gestartet ;)

    Deine Idee mit Tabelle kann ich mir mal anschauen, denke aber das verkürzt den Code weniger als der zusätzliche Platz, den die Tabelle braucht?

  • ah alles klar jetzt leuchtet mir das ein.
    ja denke auch das die version mit der tabelle nicht die schlauste ist, sah ich aber auch erst jetzt beim nachzaehlen der
    bytes in deiner routine.

    was mir aber auffaellt ist der check auf alpha numeric und nummeric
    evtl ist das hier ja nicht :D kuerzer

    gut das prueft halt nich auf richtigkeit der eingabe ne

    Code
    HEXDIG CMP #'a'  (alphabetic digit?)
           BCC SKIP  (no, skip next part)
           SBC #6  (sub seven)
      SKIP SBC #'0' (convert to value)
  • gut das prueft halt nich auf richtigkeit der eingabe ne

    Das tut mein originaler Code auch nicht. Wozu auch, soll ja etwas parsen, was vom Tool generiert ist, und wenn es um abtippen geht, wie für das BASIC Magazin hier, hat man hoffentlich einen Checksummer ;)

    Ziel war wirklich nur so klein und schnell wie möglich ;)

    evtl ist das hier ja nicht :D kuerzer

    Hm, wenn ich jetzt nichts übersehe ist das genau gleich lang wie meine Variante:

    Code
    sbc	#$30
    		cmp	#$11
    		bcc	digit
    		sbc	#$7
    digit:          [...]

    Edited once, last by zrs1 (January 16, 2019 at 3:06 PM).

  • Wenn der Source explizit zum Abtippen vorgesehen ist, wäre noch ein Prüfsummenalgorithmus wichtig.
    Ich hab mal ein ähnliches Programm geschrieben (aber nie veröffentlicht), mit dem ich z.B. Please login to see this link. und Please login to see this link. erzeugt habe. Als "Kodierung" sind dabei sowohl Dezimalbytes als auch Strings möglich, da bei sehr kurzen zu bearbeitenden Programmen das längere Dekoderprogramm schwerer wiegt als die höhere Nutzdatendichte der Strings.

    Das Dekoderprogramm ist zwar nur Basic und damit langsam, aber da das Ergebnis in eine neue Datei geschrieben wird, finde ich das nicht schlimm: Das abgetippte Programm lässt man so eh nur ein einziges Mal laufen.

    Yes, I'm the guy responsible for the Please login to see this link. cross assembler. And some Please login to see this link..

  • Please login to see this link. -- das ist ein etwas anderer Anwendungsfall ;) Hier ging es ja grundsätzlich um BASIC-Programme, ich wollte aber Maschinencode mit einbinden. Das wird "klassisch" mit DATA/POKE gelöst, in der Regel auch ohne zusätzliche Prüfung. Das hier optimiert Platzbedarf und Geschwindigkeit. Für die Sicherheit beim Abtippen sollte IMHO lieber ein separater Checksummer sorgen, damit das abzutippende Programm nicht unnötig aufgebläht wird. (man tippt ja nur einmal ab, führt aber eventuell viele male aus ...)

    [...] da bei sehr kurzen zu bearbeitenden Programmen das längere Dekoderprogramm schwerer wiegt als die höhere Nutzdatendichte der Strings.

    Das hier ist ja genau für ein "etwas größeres" MC-Fragment entstanden, wo das eben nicht so ist. Bei kleineren Routinen lohnt sich das selbstverständlich nicht, auch nicht für die Ladegeschwindigkeit.

    (edit, OT -- verdammt lustiger Thread mit dem abtippbaren disk image ... :D )

    Edited once, last by zrs1 (January 16, 2019 at 3:41 PM).

  • hm ist das evtl 2 bytes kuerzer und erfuellt die selbe function?

    hab halt schon lange nix mehr am cevi gemacht, von daher is mein verstaendniss deiner routinen gerade nicht das beste ;D

  • Das ist doch gleich lang? ?( würde aber auch nicht funktionieren, weil so $fb ja nie gelöscht würde -- der gelesene wert würde also zu einem fixen #$ff "konvergieren" ;)

    Wenn noch mehr Leute so eifrig Kürzungsmöglichkeiten suchen könnte man glatt einen Wettbewerb draus machen :D

  • Vielleicht bin das ja nur ich, aber ich komme mit diesen langen Brocken von Zeilen wie in Beitrag 4 weniger klar als mit den typischen DATA-Zeilen mit den Ziffern mit Kommata getrennt. Da kann man so leicht den Überblick verlieren wenn man nicht 101%ig hochkonzentriert dabei ist. Da tippe ich lieber mehr Zeilen altmodisch ab.

  • hm okay war ja nur hn versuch ;D
    ansonsten finde ich nichts wo ich kuerzen koennte, evtl guggn ja die richtigen profis hier ma rein und finden was :)

  • Please login to see this link. ich habe es natürlich selbst getestet -- konnte bei mir keine Schwierigkeiten finden. Anders wäre es sicher bei "repetitivem" code, aber der verwirrt auch (wenn auch weniger) in DATA zeilen und das lässt sich wie gesagt durch crunchen umgehen.

    Kann schon gut sein, dass das individuell verschieden ist. Aber die Größenunterschiede allein sind schon sehr deutlich -- in DATA zeilen braucht ein Byte des Codes, bei Annahme einer Normalverteilung, im Schnitt 3,6 Zeichen -- gegenüber genau 2 Zeichen mit diesen Hex Strings. Wenn es um Startgeschwindigkeit geht reden wir sogar von Größenordnungen -- gemessen habe ich allerdings noch nicht :)

  • So, habe jetzt mal beide Varianten Please login to see this link. gemessen mit

    Code
    100 print ti
    ti$="000000":run

    Ergebnis ist

    Komplett aus DATA: 288 jiffies
    Mit meinem Loader: 56 jiffies

    Verhältnis ist hier also ca 5:1. Und die Uhr ist ja noch ein relativ kleines Progrämmchen, da hat das laden des Loaders selbst noch einen spürbaren Anteil ;)