Hallo Besucher, der Thread wurde 44k mal aufgerufen und enthält 337 Antworten

letzter Beitrag von Boulderdash64 am

Optimierungsgrad KERNAL /BASIC - fiktiver Talk

  • Danke für die erhellenden Anregungen!


    Wenn ich eh dabei bin wir eh dabei sind*, den C64 gedanklich neu zu erfinden, und du von den Seriellen-Bus-Routinen sprichst (EOI = End or identify, eine Folge der IEEE488-Logik), da möchte ich den Gedankenfaden fortspinnen:


    - eine nennenswerte EInsparung bei höherer Effizienz ergäbe sich, wenn der "neuen" C64-Firmware auch ein neues Floppy-ROM sowie runderneuerte Peripherie zur Seite gestellt wird.
    Anknüpfungspunkt VC20: der hatte noch im Schaltplan klar erkennbar die Bedienung des seriellen BUS mit dem VIA-Schieberegister! und zwar ohne Daten-Puffer 7404 oder 7406 im Signalpfad.. sodass über CB1 sowohl Takteingang als auch Taktausgang bedient werden kann.
    Im Gegensatz zum C128, der hier einen "Riesen-Sums" an Umschaltpuffern je nach Datenrichtung sowie zur Abwärtskompatibilität zum vermurksten C64-Software-Protokoll aufweist, könnte ich mir gut vorstellen, das "ursprünglich" beim VC20 geplante serielle Bus-Protokoll (MIT schieberegister) neu zu implementieren und in der Floppy dann konsequent CIAs statt VIAs zu verwenden.


    Kennt jemand eine Prototyp-Version des VC20-ROM, wo die ursprünglich geplanten Schieberegister-Routinen drin waren? Die müssten viel simpler sein, als die im C128 (Edit: oder im historischen C64) !


    Denkbar wäre, ausnahmsweise hier auch die Hardware zu verändern: entweder käme in der Floppy dann ein CIA oder ein VIA 65C22 von CMD in Betracht... nur mal so ins unreine gedacht.


    MacBacon, die komische Programmierung im Bereich der Jobschleife könnte ich mir so erklären, dass Siracusa sich nicht getraut hat, den Stack stark zu belasten und daher etwas spitzfingrig zu Werke gegangen ist: der Coprozessor für Laufwerk-Lesen/Schreiben ist ja (Edit: ursprünglich; SFD 1001 oder 2031 o.ä.) ein 6504 oder 6507 mit ganz wenig Speicher und Adressraum; vermutlich hat der nur 16 Bytes für Unterprogrammverschachtelung, weil Stack und Zeropage und Jobspeicher eng miteinander verschachtelt /gespiegelt sind. Nur so eine Idee... sinnlose Rücksichtnahme freilich, da in der 1541 ja genug Stack vorhanden ist.


    _____
    * Edit: MacBacon hat einen dicken Hals vom Commodore-ROM-Listing-Lesen und hat sich ausgeklinkt.

  • In einem C-F von 1999 hab' ich zu dem Thema mal ein Manifest verfaßt. ^^


    Einfach mal so zum Genießen:


  • :)


    Ist es möglich, die von dir erwähnten Zusatzinformationen (Adressen von Variablen, Adressen von GOTO , GOSUB Sprungzielen... umgewandelte Zahlkonstanten in Real/Integerbinärformat..) statt direkt hinter der jeweiligen Verwendungsstelle stattdessen nach dem Nullbyte am Zeilenende, aber vor Beginn der nächsten Zeile zu "verstecken"?
    Soviel ich weiß, müssen Linkzeiger zur Folgezeile und Nullbyte am Ende der aktuellen (oder war das nur am Ende des Programms ein Nullbyte?) nicht genau zueinander passen... es geht um eine "abwärtskompatible" Art, die Zusatzinfos unter zubringen.


    Ein lesenswertes Manifest! Besonders das mit den fixen 1-Zeichen-Variablen ist eigentlich überfällig:
    LDA Variablenname; AND #$1F ; ASL ; STA adresse_low und fertig ist die Adresse der (INTEGER-)Variablen... keine nervige Sucherei.


    Was haltet ihr dann davon, (EDIT: )die Variablen mit 2 oder mehr Zeichen langem Variablennamen so zu ändern, dass nicht die ersten beiden Zeichen, sondern das erste und das letzte Zeichen signifikant sind?


    so könnten
    BAUM
    und BAUM1
    unterschieden werden,
    während bei Basic V2 beide dieselbe Variable bezeichnen ..

  • Am wichtigsten [...]

    +

    Generell [...]

    +

    Da sitzt bereits mein Patch für die fehlerhafte Multiplikation drin.

    Frechheit :böse . Ist da nicht noch ein kuscheliger Platz von 26 Bytes frei? Ach, dann geh ich halt in die Einschaltmeldung :D .

    hexworx, hoffentlich machst du nicht wieder einen Rückzieher und schreibst wieder "Grütze" hinter deinen Code

    Kann jederzeit wieder vorkommen *²


    werden da so gefühlt vielleicht doch rund 50 Einsprungpunkte zu berücksichtigen sein.

    Denke ich auch.


    Wenn ich diese Tabelle der Bildschirmzeilen richtig verstehe, dann hat die Sache mit den Fortsetzungszeilen im Verhältnis zum Aufwand eh sehr selten Nutzen.

    Das täuscht man sich leider oft voreilig *²


    Was am Basic so furchtbar schlecht ist [...]

    +

    In einem C-F von 1999 hab' ich zu dem Thema mal ein Manifest verfaßt.


    Einfach mal so zum Genießen:

    Sehr geil :ilikeit: !

    so könnten
    BAUM
    und BAUM1
    unterschieden werden,
    während bei Basic V2 beide dieselbe Variable bezeichnen ..

    Und wenn dann "BUSCH" & "BUSCH1" kommen? Da beißt sich die Katze dann leider in den Schwanz.



    Man muss sich die Routinen wirklich 10x angucken, um sie wirklich zu durchblicken. Zuerst dachte ich hier auch, dass das zum Teil Quatsch ist oder Teile noch aus dem VC20 stammen...


    Z. B. wenn die RETURN-Taste gedrückt wird, dann muss jedesmal erstmal nachgeguckt werden, ob sich der Cursor in einer Einzelzeile oder ggf. in der 1. oder 2. Zeile einer Doppelzeile befindet etc.


    Oder woher rührt die Sache, dass bei $0288 immer nur Bit 0-1 berücksichtigt wird, obwohl dort eigentlich nur Vielfache von #04 Sinn machen? Das dürfte doch auch noch aus irgendeinem anderen/falschen System stammen :gruebel .


    Meine Idee mit der anderen Verknüpfungstabelle finde ich immer noch recht witzig und teste das gerade etwas. Das zieht aber auch einen Rattenschwanz nach sich. Manchmal gibt es auch ziemlich wilde Sprünge 'mitten rein', wie z. B. 2x nach $E6ED, was damit indirekt zusammenhängt. Das macht nicht wirklich Spaß. Es gibt scheinbar auch keine richtig guten ROM-Listings. Ich hatte mich jetzt mal mit der Version auf Github, die von dem Michael Steil dort auf Basis vom DATA-Becker intern gemacht wurde, auseinander gesetzt, und das ist leider wirklich grottig. Ich hatte jetzt auch schon ein paar Sachen bei Github verbessert, aber das ist auch eine kleine Lebensaufgabe und vom Format her auch nicht wirklich weiter zu verwenden. Da bastel/disassemblier ich mir das lieber mit dem Studio selbst.


  • Z. B. wenn die RETURN-Taste gedrückt wird, dann muss jedesmal erstmal nachgeguckt werden, ob sich der Cursor in einer Einzelzeile oder ggf. in der 1. oder 2. Zeile einer Doppelzeile befindet etc.

    Kannst du mir denn bitte in möglichst kurzen eigenen Worten erklären was denn "gemacht" wird wenn die Return-Taste gedrückt wird? Du schriebst dass "geschaut" wird... dabei wirds aber nicht bleiben, das dient ja einem Zweck ...
    Eingabezeile aus dem Bildschirmspeicher in den zugehörigen 88-Zeichen-Buffer in der (erweiterten) Zeropage kopieren? Parsen? Ausführen?


    Zitat von hexworx

    Und wenn dann "BUSCH" & "BUSCH1" kommen? Da beißt sich die Katze dann leider in den Schwanz.

    Aua, hoffentlich nicht...
    die Idee, nach dem ersten Byte das letzte statt das zweite zur Unterscheidung von Variablennamen heranzuziehen, kam mir nach dem Lesen des Buchs "Künstliche Intelligenz auf dem Commodore 116" aus der Commodore-Sachbuchreihe (iirc). Dort ging es allerdings nicht um Variablennamen, sondern um ein Übersetzungsprogramm Englisch-Deutsch. Der Clou war, dass nur Vokabeln EINER Sprache abgespeichert werden mussten (=Speicher sparen). Die Benutzereingabe wurde eben nach einem Algorithmus verkürzt, wobei nur 2 Zeichen vom eingegebenen englischen Wort sowie die Länge des Wortes zu einem Selektor zusammengefasst wurden. Wenn ich mich recht erinnere, waren das das erste, das letzte Zeichen und die Länge. (oder die Quersumme / Prüfsumme?)
    Diesen Gedanken hab ich versucht auf das Commodore-Basic insgesamt zu übertragen, aber das war wohl Grütze ..... :)
    (gestrichener Abschnitt über den Tokenizer - noch nicht durchdacht genug)


    Manifest (..)

    Hier schlägt Mike jede Menge Erweiterungen vor, die mit viel Zusatzaufwand einhergehen; wenn man sich vergegenwärtigt dass z.b. bei Zahlen (Sprungziel-Zeilennummern z.b.) sowohl die Klartextversion als auch die binäre Form sowohl behandelt als auch abgelegt werden müssen, wird sonnenklar dass die (auch versteckte) "Redundanz" zunimmt. Ich sehe das Problem darin, dass das "Kürzen" derselben Funktionalität und das Erweitern von Funktionalität in einem starken Zielkonflikt stehen, bzw. um dieselben geistigen Resourcen wetteifern. Wahrscheinlich ist es zielführender, erst eine Neuimplementierung des Bestehenden zu versuchen und dabei nur im Hinterkopf zu behalten dass man es besser machen will; und dann später in einem eigenständigen Schritt versuchen extra Befehle unterzubringen. Anders vielleicht bei der Garbage-Collection, da würde man wohl von anfang an die Version mit den Backlinks nehmen. (Der Speichermehraufwand liegt da mehr im Wirkbetrieb im Stringspeicher, als im ROM).

  • Woah, jetzt, wo ich es lese, kommt mir das Manifest sogar wieder bekannt vor! Müsste man glatt die alten CFs noch mal raussuchen :)


    Zu den 80 Zeichen/Zeile:
    Klar, kann immer sein, dass da noch irgendwelche Features drin stecken, die ich nicht erkannt habe und die mir erst beim auseinanderpflücken auffallen würden. Es ist echt Mörder-lange her, dass ich mir das angesehen habe, und ich hab glaub ich nie die Stelle gefunden, an der der Screencode einer Bildschirmzeile in Ascii gewandelt und in den Eingabepuffer übertragen wird.


    Das sehe ich aber zumindest zum Teil als "Optimierungspotential", wenn man from scratch loslegt ;) Definieren, was sich auf logische und was sich auf echte Bildschirmzeilen beziehen soll, und gucken, ob Abweichungen vom Original schlechter oder gar besser sind. Braucht man den Insert-Mode wirklich, der fast, aber nicht ganz, wie der Quote-Mode ist? Wären nicht auch 120 Zeichen oder mehr schön?
    Was wäre günstiger: Cursorposition X/Y rein auf logische Zeilen bezogen führen? Rein auf echte Zeilen bezogen? Oder beides? Ich würde zum ersten plus Zeiger auf Adresse tendieren... Ein Unterprogramm, das dazu die passende Adresse berechnet, würde selten benutzt und dürfte langsam sein, wohl eine Schleife mit Additionen. Sicher wird auch eine Tabelle gebraucht, die die Zeilenlängen speichert, die wird aber sicher anders aussehen als die vorhandene.


    Ob das Ergebnis dann tatsächlich optimaler wäre müsste man sehen... Kann ja durchaus sein, dass das Hi-Byte eine Art praktisches Abfallprodukt ist, das an anderen Stellen gespart hat.


    By the way: Müsste der Editor nicht komisch werden, wenn der Screen nach 49152 verschoben wurde?

  • Hm, BASIC ging es aber nie darum schnell zu sein, oder?
    Mit Abstand das schlechteste Platz-Nutzen-Verhaeltnis haben meiner Meinung nach die RS232-Routinen und der Tape-Loader.
    Den zu nem TurboTape oder wenigstens Kansas City standard und man haette massig an Platz UND Komfort gewonnen.
    Dass RS232 _SO_ niemand benutzen wuerde (zumal die Kernalroutinen ja ohnehin nicht die 'volle' Geschwindigkeit schaffen, vom Pegel mal ganz abgesehen) haette man sich auch seiner Zeit schon denken koennen vermute ich.
    Der ROM tape load hat coole Features aber (fast) alle im Zweifel nicht praxistauglich...

  • In diesem Zusammenhang ist vielleicht das "Schwesterprojekt" BSOS interessant: zwar ist das für den CBM 8296 und nicht für den C64, aber BlackSmurf hat genau das dort gemacht: das Betriebssystem des CBM 8296 ordentlich entrümpelt und optimiert um Platz für zahlreiche Verbesserungen und Erweiterungen zu schaffen. Im github-log kann man sehen, wie er es immer wieder mal schafft, hier und dort die eine oder andere Routine zu kürzen oder zu vereinfachen. Vielleicht ist das eine oder andere davon auf den C64 übertragbar.

  • Kannst du mir denn bitte in möglichst kurzen eigenen Worten erklären was denn "gemacht" wird wenn die Return-Taste gedrückt wird? Du schriebst dass "geschaut" wird... dabei wirds aber nicht bleiben, das dient ja einem Zweck ...

    Es wird halt anhand von der Tabelle $d9,x (x=Cursorzeile) geschaut, ob sich der Cursor in der 2. Zeile einer Doppelzeile (=Bit 7 gelöscht) befindet , wenn ja, wird ab Zeile-1 eingelesen.

    By the way: Müsste der Editor nicht komisch werden, wenn der Screen nach 49152 verschoben wurde?

    Hatte ich auch schon gedacht, passiert aber nicht, da ständig wieder $0288 (per ORA) hinzugezogen wird und das ggf. fehlende Bit 7 dadurch wieder gesetzt wird.

  • Wären nicht auch 120 Zeichen oder mehr schön?

    Da sind die Routinen teils sogar schon bzw. noch für ausgelegt (kommt vermutlich noch vom VC20 mit seinen 4x22=88 Zeichen); siehe Quellcode in #66 ("BPL" in Zeile 32 nach Zeile 24). Beschränkung wären hier wohl 6 Zeilen (#$F0) damit sie noch in $D3 passen.

  • Hexworx: Danke für die Erläuterung mit den Doppelzeilen, jetzt kann ich was damit anfangen!

    ordentlich entrümpelt und optimiert

    Einerseits: beeindruckende Feature-Fülle, vor allem Monitorprogramm mit Assembler; und das bei max. 18 KB bzw. 20 KB Programmgröße.


    "Entrümpeln" ist aber entschieden das falsche Wort! Denn, andererseits:


    DELETED FEATURES All tape related code is removed in order to make room for improvements The entry of diacritic characters is removed (accented letters etc.)

    Oh, oh... wenn dafür die Tape-Routinen ins Gras beißen müssen, ist die Sache höchstens halb so genial. ;(
    Schade! - eine in meinen Augen verträglichere Lösung wäre, einen simplen aber effektiven TurboTape-Verschnitt zu integrieren, der beim Lesen auch das klassische CBM-Format verkraftet und beim Schreiben Nur Turbo erzeugt.


    Die in Mikes Manifest erwähnten Sachen waren hier wohl nicht im Ansatz angegangen.

  • kommt vermutlich noch vom VC20 mit seinen 4x22=88 Zeichen

    Das ist tatsächlich so!


    Siehe hier:

    Code
    1. .C:a569 9D 00 02 STA $0200,X ; Eingabepuffer
    2. .C:a56c E8 INX
    3. .C:a56d E0 59 CPX #$59 !!! ; 89. Zeichen erreicht?
    4. .C:a56f 90 F1 BCC $A562 ; nein, weiter
    5. .C:a571 A2 17 LDX #$17 ; Fehler-# STRING-TOO-LONG
    6. .C:a573 4C 37 A4 JMP $A437 ; Fehler ausgeben


    Und das funktioniert (mit einem Trick) tatsächlich:



    Hier wird durch den POKE 219,4 die 3. Zeile mit übernommen. Bei einem Zeichen mehr gibt es den "STRING TOO LONG ERROR".


    Problem ist halt, dass der Eingabepuffer nur für 88(89) Zeichen Platz hat ($0200-$0258). Es sei denn, man könnte auf den Kassettenpuffer ausweichen. Ich wüsste nicht, dass sich beiden im Normalfall in die Quere kommen können (oder?). Problem ist natürlich, dass der Kassettenpuffer gern schon für andere Sachen missbraucht wird, aber solang man im BASIC rumeditiert ist sollte das nicht unbedingt weiter stören. Durch den Kassettenpuffer hätte man 192 Zeichen Platz, also Platz für vier Zeilen (160 Z.).

  • Ich chabe jetzt nicht alle 4 Threadseiten gelesen, arbeite aber seit rund 20 Jahren sehr eng mit beiden ROMs zusammen. Was BladeRunners Frage nach der Effizienz betrifft, würde ich daher vereinfacht Folgendes sagen:


    - Die ROM Routinen sind sehr flexibel und universell gehalten


    - Viele ROM Routinen bestehen aus mehreren kleinen Subroutinchen, die wiederum von anderen Routinen verwendet werden


    - Insgsamt musste alles in 2 x 8 KB reinpassen


    - Zwangsläufig geht die Flexibilität und dieses Sammelsurium von kleinklein auf Kosten der Geschwindigkeit


    - Ich persönlich versuche zwar immer einen Kompromiss zu finden, aber nur wenn ich mit der Geschwindigkeit zufrieden bin. Bei schnellen Schleifen bpsw. verwende ich ausschl. 16-Bit Adressbefehle, anstelle der inidiz. 8-Bitter, was teilweise richtig Platz kostet, dafür aber giftig schnell ist


    - In allen Produkten der TMF werden viele ROM Routinen verwendet. Läuft sehr stabil und harmonisch Hand in Hand, wenn man sich an die Standards hält. Abstürze oder Ungereimtheiten durch die Verwendung mit den ROM Routinen sind mir nicht bekannt! Hier noch 2 Anwendungen, die sehr viel ROM nutzen und trotzdem angenehm flüssig laufen:
    http://csdb.dk/release/?id=94188
    http://csdb.dk/release/?id=97928 (Der Editor!)


    - Alles in allem würde ich sagen das BASIC und auch das Kernal ROM sind in punkto Funktion, Flexibilität/Universalität und Speicherbedarf (2 x 8 KB) eingermaßen effizient, aber dafür halt langsam(er)


    - Bedauerlicherweise gibt es für das BASIC ROM keine Sprungtabelle, was den Platz natürlich noch mehr reduziert hätte


    - Was die Ausgangsfragen betraf:
    a) Viel schneller wird's schon aufgrund der Struktur kaum gehen
    b) Evtl. hätte man ein bißchen Platz sparen können


    Ich würde sagen CBM und MS haben keinen schlechten Job gemacht.


    BladeRunner: War diese Art der Antwort für dich hilfreich?

  • Die Antworten insgesamt waren hilfreich - in dem Sinne dass ich mich in meiner Grundposition bestätigt sehe (für ein Produkt dass noch nicht lange am Markt war wurde ein schon sehr durchdachter /tricky Code entwickelt, Einsparungen wären kaum möglich, auch Effizienzsteigerung wohl nur sehr bedingt).
    Meine Überlegung für die Grage war: als der C64 rauskam war die CPU noch nicht ewig alt, und daher hatte ich mich gefragt ob eineige der Tricks die zum beschleunigen / verkürzen von Code benutzt werden können einfach noch nicht bekannt waren. Es scheint ja aber in der Tat so dass da Leute am Werk waren die ihr Handwerk beherrschten.
    Die aufgekommene Frage nach einem Rewrite sehe ich zweischneidig - es wäre zum einen wirklich interessant ob man durch eine komplett neue Implementierung deutlich mehr reinpacken könnte, auf der anderen Seite frag ich mich auch wie kompatibel dass dann noch wäre.

  • ... die "neue" Firmware würde also beim Befehl "SYS" einen Hash-Wert über das Adreß-Argument bilden müssen und falls es einer jener 50 Einsprungpunkte ist, eine 'Adapter-Schicht' bzw. eine "Konverter-Stufe" aufrufen (alt/neu) :D

    Ja, bestimmt ;-)


    Aber mal im ernst: entweder ein paar wenige änderungen auf kosten von anderen (z.B. tape) routinen und dabei komplett kompatibel oder alles von grund auf neu: viel schneller und kleiner aber halt inkompatibel zu allem.
    Zudem nutzt ja eh jeder den speed loader kernal seiner wahl und quasi keiner das original.
    Und wenn jemand komplett aufruaumt, dann bitte auch die benuztung der ZP: schön getrennt von ein ander: kernal-disk, kernal-tape, kernal-x und zum schluss basic. Dann ist es ganz einfach sich zu entscheiden was man überschreiben kann (wobei ich bis jetzt immer einfach alles platt gemacht habe)

  • BladeRunner: Ja, wir liegen hier sehr nah beieinander. Natürlich kann man viele Jahre danach aufgrund von Erfahrungen und Versuchen immer noch was verbessern. Aber ich denke auch für die Zeit war die Firmware okay - also kein Grund unseren CeVi umzutauschen! ^^ Crossbow von Crest bspw. ist so'n "Käpsele", der mit einer Handvoll Bytes komplexe Funktionen hinkriegt. Er wäre einer von denen, die in Sachen Effizienz die ROMs wohl noch entschlacken könnten ohne eine Inkompatibilität in Kauf nehmen zu müssen, wenn man von der fehlenden Sprungtabelle des BASIC ROMs absieht. Ich hingegen habe mich auf schnelle Kodes spezialisiert und brauche dementsprechend Platz... ;)