Optimierungsgrad KERNAL /BASIC - fiktiver Talk

Es gibt 337 Antworten in diesem Thema, welches 62.640 mal aufgerufen wurde. Der letzte Beitrag (16. September 2017 um 00:34) ist von Boulderdash64.

  • Zur Erlernbarkeit und Verständlichkeit sage ich,

    daß es grundsätzlich durchaus verständlich ist, wenn beim print-Befehl ein Fehler auftritt,
    daß dann als Fehlermeldung print-error ausgegeben wird.

    Da ein direkter Zusammenhang von Fehler und Basic-Befehl besteht, was z.B. bei "undef. statement"-error nicht der Fall ist..

    Schönen Gruß.

  • Ich habe für meinen Bitte melde dich an, um diesen Link zu sehen. im Source Code alle Stellen im Kernal, die u.U. verzichtbar sind mit !if umgeben. Das schließt allerdings auch Tape- und RS232-Routinen mit ein. Aber falls Platzbedarf besteht, kann ein Blick in die Sourcen evtl. ein bisschen Arbeit sparen.

    ────────────────────────────────────────────────────────────
    Bitte melde dich an, um diesen Link zu sehen. - Bitte melde dich an, um diesen Link zu sehen.
    ────────────────────────────────────────────────────────────

  • Für kleinere MC-Programme nehme ich meistens den Bereich der Input-Fehlermeldungen.
    "Extra ignored" und so was vermisst bestimmt keiner .

    Ansonsten kann man natürlich auch statt der Fehlermeldung einfach die Fehlernummer ausgeben, damit hätte man dann wohl die einfachste Möglichkeit die Fehlermeldungen zu erstetzen.

    Für größere Projekt ist dann mit Sicherheit auch der Source-Code von Klaus interessant.


    Schönen Gruß.

  • Und hier ist es nun so, dass der original - C64 rein gar nichts, nüscht, nada, niente, zero an Grafikbefehlen in seinem Basic V2 hat. Kümmerlich! Ein schwaches Bild, wörtlich und übertragen.

    Deshalb ist ein im ROM verankerter Befehl entsprechend "GRAPHIC 1,1" und "... 0" zur Modusumschaltung,
    sowie ein Befehl zum Bildpunkt setzen und Löschen ein riesen Fortschritt (schon wegen der verschrobenen Speicheraufteilung.) Es braucht keine ELLIPSE, CIRCLE, BOX DRAWLINE und so weiter Instruktionen.

    Befehle, um die Grafik ein- und auszuschalten und um den Grafikschirm als ganzes zu löschen, sowie Punktsetz- und -löschbefehle sind sicher fundamental.

    Du willst aber sicher nicht auf einen halbwegs schnellen (und hoffentlich korrekten!) Linienziehbefehl verzichten - die Nachbildung über die vorhandenen Punktsetzbefehle+Bresenham/DDA bremst das ganze sonst soweit wieder aus, daß Du bei jeder nicht-trivialen Grafikanwendung keine Freude mehr hast: in purem BASIC+Punktsetz bekommst Du vielleicht 40 Punkte/Sekunde hin, ziehst Du den Linienzieh-Algorithmus in die Erweiterung mit rein, macht die Routine problemlos 4000 Punkte/Sekunde! *) Flaschenhals ist dann nur noch die Parameterübergabe an die Linienziehroutine.

    Der Geschwindigkeitsunterschied sorgt dann z.B. dafür, ob man mit der Erweiterung z.B. eine Uhr mit Stunden-, Minuten- und Sekundenzeigern darstellen kann - oder eben nicht.

    Auch eine Funktion um Punkte abzufragen (gelöscht/gesetzt) ist meines Erachtens unverzichtbar.

    Zuguterletzt gehören auch mindestens noch die zwei Befehle rein, um die Bitmap abzuspeichern und wieder zu laden. Dann hast Du genau den Befehlsumfang meiner Erweiterung Bitte melde dich an, um diesen Link zu sehen. auf dem VC-20. :D

    BOX läßt sich natürlich easy mit einer Unterroutine und vier DRAW-Befehlen nachbilden. Die Farbvergabe kann man über geeignete POKE-Befehle genauso einfach und schnell hinbekommen, einen dedizierten COLOR Befehl braucht's also nicht wirklich. CIRCLE/ELLIPSE hingegen ist mit nur mit jetzigem Umfang der Erweiterung aber eher wieder zäh, FILL und TEXT/CHAR ebenso. In der Praxis behelfe ich mich da ggfs. mit nachladbaren Maschinenroutinen. So wird nur dann extra Speicher belegt, wenn die etwas komplizierteren Grafikbefehle auch wirklich gebraucht werden. Der "Kern" der Erweiterung hingegen begnügt sich mit ziemlich genau 1 KB.

    Gruß,

    Michael


    *) 4000 Punkte/Sekunde kriegt man mit einem recht kurzen (~100 Byte) und nicht völlig verunfallten Bresenham problemlos hin. In meinem Tresor liegt auch eine Linienzieh-Routine, die durchgehend 30000 Punkte/Sekunde liefert - es bringt nur nichts, eine so schnelle Routine in eine BASIC-Erweiterung einzubauen, da bereits bei 4000 Punkten/Sekunde der umliegende BASIC-Overhead die Laufzeit dominiert, und damit keine merkbarer Geschwindigkeitsgewinn mehr rauskommt. Außerdem ist meine schnelle Routine mit ca. 800 Byte auch *etwas* größer.

  • Vielen Dank dass du es in Erinnerung rufst.

    Ich kann Deinen anklingenden Schmerz darüber, dass die "Gemeinde" Dein VC-20-Grafikpaket noch nicht ausreichend zur Kenntnis genommen hat, nachfühlen. Ich würde mich auch freuen , wenn der User, der den Wunsch in den Raum "geschmissen" hat, die ROM-Routinen für Clear Screen sollten doch auch die Grafik bedienen können, sich mit meinem Posting Nr. 196 befassen würde ...

    Bitte melde dich an, um diesen Link zu sehen.

    Immerhin kann ich aber sagen, dass ich daran arbeite, den Platz für solche Erweiterungen einschätzbar zu machen.

    Für den in Posting 196 eingeschlagenen Weg, Bytes "freizuklopfen" ergab sich folgende "Bilanz".
    Um 2 x 2 x PHA / PLA unterzubringen mussten insgesamt 106 Bytes betrachtet und tlw. umgeschichtet werden. Am Ende konnten 6 Bytes zusätzlich freigemacht werden wobei aber als "Kollateralschaden" 3 aus dem unbenutzten ROM Bereich genommen werden mussten

    Somit scheint es nicht zu hoch gegriffen, eine Quote von 3 % im jetzigen ROM (Basic V2 + Kernel) zu postulieren, um die extra Platz geschaffen werden kann.

    3% aus 16384 Bytes ROM ~= 3* 163.8 ~= 492

    also rund 500 Bytes "könnten" freigeschaufelt werden.

  • 4000 Punkte/Sekunde kriegt man mit einem recht kurzen (~100 Byte) und nicht völlig verunfallten Bresenham problemlos hin. In meinem Tresor liegt auch eine Linienzieh-Routine, die durchgehend 30000 Punkte/Sekunde liefert - es bringt nur nichts, eine so schnelle Routine in eine BASIC-Erweiterung einzubauen, da bereits bei 4000 Punkten/Sekunde der umliegende BASIC-Overhead die Laufzeit dominiert, und damit keine merkbarer Geschwindigkeitsgewinn mehr rauskommt. Außerdem ist meine schnelle Routine mit ca. 800 Byte auch *etwas* größer.

    in meinem Oberstübchen hab ich auch sowas - es läuft darauf hinaus, bei jedem Speicherzugriff auf ein Byte des Bildspeichers jeweils soviel Bits wie möglich gleichzeitig zu setzen, nicht wahr? - würde es aber wegen des Speicherbedarfs lieber als TTL-zusatzplatine realisiert sehen und damit fiele es aus der vorliegenden Competition raus ...

  • Ich kann Deinen anklingenden Schmerz darüber, dass die "Gemeinde" Dein VC-20-Grafikpaket noch nicht ausreichend zur Kenntnis genommen hat, nachfühlen.

    Oh, je! Sooo schlimm ist es jetzt auch wieder nicht. ;)

    Mit ging es im wesentlichen darum, bei dem Fall der Grafikanwendung die Grenzen zwischen sinnvollen und notwendigen Features einerseits und Feature-Creep andererseits etwas anders zu ziehen. Mit einem konkreten Beispiel einer durchaus nicht völlig unbekannten BASIC-Erweiterung für den VC. :)

    in meinem Oberstübchen hab ich auch sowas - es läuft darauf hinaus, bei jedem Speicherzugriff auf ein Byte des Bildspeichers jeweils soviel Bits wie möglich gleichzeitig zu setzen, nicht wahr?

    Nein, die Routine nutzt Einzelbit-Zugriffe, die aber 8-fach ausgerollt - für jede Bitposition in einem Byte. Mit ca. 32 Zyklen/Bildpunkt und konstantem Aufwand.

    Die Variante, die erst alle Bits "sammelt", bevor sie sie schreibt ist mir auch geläufig. Die übliche Implementierung in diesem Fall braucht 17 Zyklen/Bildpunkt während gesammelt wird - sie ist aber "teurer", wenn das aktuelle Byte verlassen wird und das Byte geschrieben wird (werden muß!) und braucht dann etwa 55..60 Zyklen/Punkt. Lohnt sich wirklich nur bei fast waagerechten Linien. Sobald die Steigung größer als 1 wird, bringt es gar nichts mehr. In der Summe kommt es bei gleicher Größe der Routine auf +/- 0 raus und ist komplizierter zu implementieren. Da lohnt sich eher noch die Abprüfung auf den Spezialfall exakt waagerechter und senkrechter Linien.

    würde es aber wegen des Speicherbedarfs lieber als TTL-zusatzplatine realisiert sehen

    Äh, wozu?

    Mir ging es nur darum, daß für diesen Anwendungsfall der Geschwindigkeitsvorteil sehr genau gegenüber der nötigen Programmgröße abgewogen werden muß. Für die Anwendung durch BASIC ist die kleine Routine mit 100 Byte völlig ausreichend.

    Ich habe mal woanders grob überschlagen, daß man durch Entfernen von Tape und RS232 (so wie JiffyDOS das macht), ohne weiteres das eine KB freischaufeln könnte, um die Grafikroutinen alle unterzubringen. Allerdings müßte dann jeder Anwender dieses ROM nachrüsten. Wäre nur einfacher für den Programmierer (Grafik-Kernel ist "sofort" da) aber ziemlich unmöglich für den Anwender. Ich würde mich "bedanken", wenn ich nur für irgendeine obskure Anwendung die Firmware austauschen müßte. Die jetzt implementierte Erweiterung ist ins RAM ladbar, und kann entweder für sich alleine zur Programmierung genutzt werden, oder durch einen Bootlader zusammen mit einem Nutzprogramm automatisch gestartet werden.

    Daher würde ich mich gar nicht so sehr darauf versteifen, *neue* Features in das BASIC einzubauen. Bestehende Routinen zu verbessern würde auch schon einiges bringen. Etwa eine schnellere GC (in linearer statt quadratischer Laufzeit), eine schnellere Quadratwurzel, dazu eben SWEET16 hernehmen um den dazu nötigen Platz zu realisieren und erst *dann*, als nette Dreingabe, SWEET16 auch noch nach draußen anbieten.

  • Hallo Leute,

    kann man in Eurer zukünftigen Version auch die Verwendung von CALL Subroutine-Name anstelle von Gosubs verwenden? Dass man anstelle von Zeilennummern aussagekräftige Namen verwenden kann?

  • Geht nicht bisher schon:

    120 GOSUB 30: REM FAKULTAET

    oder
    10 LET FAKULTAET% = 30
    ...
    ...
    ...
    120 GOSUB FAKULTAET%

    und das Basic-konform ohne das ROM auszutauschen? ich sehe keine Notwendigkeit... für die Garbage Collection in O(n) wie von Mike geschrieben durchaus ...

  • Geht nicht bisher schon:

    Hab grade geschaut wie ein Autobus. Doch, das geht! Und das lerne ich über 30 Jahre nach meinen ersten C64-Gehversuchen. HILFE! :cry:

    Wobei: Auch da wären bloß die ersten zwei Buchstaben ausschlaggebend, also limitierter Nutzen. Trotzdem: Danke für die Erleuchtung! :applaus:

    HAAAAAAAAALT! :abgelehnt

    Alles zurück! Nein, geht nicht! Habs falsch probiert. :schande:

    Hier könnte meine Signatur stehen, wenn ich eine hätte.

    Einmal editiert, zuletzt von BlondMammuth (29. Mai 2017 um 12:07)

  • Nein, das geht nicht. GOTO/GOSUB können nur Ziffern lesen.
    EDIT: BlondMammuth: Du hast das nicht zufällig mit Zeilennummer Null getestet? :D

    Yes, I'm the guy responsible for the Bitte melde dich an, um diesen Link zu sehen. cross assembler. And some Bitte melde dich an, um diesen Link zu sehen..

  • Ja, Asche auf mein Haupt, zumindest die 2. Variante geht nicht.

    Ich testete es nicht auf dem Original BASIC. Ich war voreingenommen von den Syntaxdiagrammen die ich z.Zt. wegen diesem Thread hier lese.

    Zu meiner Entschuldigung lest aber bitte dies:
    Bitte melde dich an, um diesen Link zu sehen.

    ... was leider eher die - zu Syntaxdiagrammen o.ä. geronnenen Wunschvorstellungen aus irgendwelchen Handbüchern sind. Da stand eben und ich hatte in Erinnerung:

    <Statement> ::=(...) | GOSUB <Expression> | GOTO <Expression> (..)und Expression ist halt sehr allgemein formuliert. Daher erklärt sich mein Faux-Pas...Halten wir fest: es ist keine Tatsache, es ist eine Wunschvorstellung. Es tut mir leid wenn ich überhöhte Erwartungen geweckt haben sollte.

    @Pentagon:
    Vielleicht mag Dein Emulator bloß keine falsch geschriebene "Fakultät"? ;)

  • Nun gut ... dann wird das möglichst frei parametrierbare GOTO / GOSUB ins inoffizielle Pflichtenheft mit aufgenommen.

    Zu dem anderen Punkt, dass bei Variablen nur die ersten zwei Stellen ausgewertet werden bzw. signifikant sind:

    Was haltet ihr von dem Vorschlag, dieses zu ändern z.B. folgendermaßen:

    Bei Namensbezeichnern für Variablen wird
    1. Der ASCII-Wert des 1. Zeichens
    2. eine Prüf-Summe über alle nachfolgenden Zeichen-ASCII-Werte (oder XOR oder CRC .. irgendwas möglichst einfaches) des Namens
    3. evtl. die Zeichenzahl des Namens
    .. zu einer internen Variablennummer zusammengefügt? Also eine Art Hash-Wert.
    Vorteil: Suchen gehen relativ schnell.
    Nachteil: Doppelbelegungen erfordern zusätzlichen Aufwand, weil sie für den Benutzer / Basic-Anwender nicht sofort erkennbar sind.

  • Nachteil: Doppelbelegungen erfordern zusätzlichen Aufwand, weil sie für den Benutzer / Basic-Anwender nicht sofort erkennbar sind.

    Oh weh, auch wenn das vielleicht selten passiert, wäre das ein Bug/Feature das einen mit Sicherheit in den Wahnsinn treiben würde bei der Fehlersuche... Da würde ich eher für eine volle Auswertung des Namens plädieren. Wenn man lange Namen benutzt, muss einem halt klar sein, dass es Speicher und Performance kostet.

    ────────────────────────────────────────────────────────────
    Bitte melde dich an, um diesen Link zu sehen. - Bitte melde dich an, um diesen Link zu sehen.
    ────────────────────────────────────────────────────────────

  • EDIT: BlondMammuth: Du hast das nicht zufällig mit Zeilennummer Null getestet?

    Nein, mit Zeile 100. Nur beim ersten Test habe ich Depp statt "gosub FAK" "gosub 100" hingeschrieben. :wink:

  • Oh weh, auch wenn das vielleicht selten passiert, wäre das ein Bug/Feature das einen mit Sicherheit in den Wahnsinn treiben würde bei der Fehlersuche...

    Auf den Sinclair-Rechnern ist das tadellos gegangen. Sogar auf dem ZX81. So hat man sowas wie "Case"-Anweisungen simulieren können.

  • Nun gut ... dann wird das möglichst frei parametrierbare GOTO / GOSUB ins inoffizielle Pflichtenheft mit aufgenommen.

    Damit die Spaghettiprogrammierer sich noch mehr in den Fuß schießen können? Richtige Labels bzw. Prozedur/Funktionsnamen sind ein Muss - wenn eine "neue" imperative Programmiersprache für den C64 die nicht hat, ist sie eh keinen zweiten Blick wert.

    [...] bei Variablen nur die ersten zwei Stellen [...] eine Prüf-Summe über alle nachfolgenden Zeichen-ASCII-Werte [...] Hash-Wert [...]

    Ein solcher Hash ist sehr nützlich für die Variablensuche, dann kann man nämlich die Variablen in einem (binären) Baum verwalten und hat statt linearer Zeitkomplexität nur noch eine logarithmische. Ist die vermeintlich richtige Variable gefunden, muss man aber natürlich trotzdem alle Zeichen überprüfen.

    Yes, I'm the guy responsible for the Bitte melde dich an, um diesen Link zu sehen. cross assembler. And some Bitte melde dich an, um diesen Link zu sehen..