Hallo Besucher, der Thread wurde 7,2k mal aufgerufen und enthält 40 Antworten

letzter Beitrag von Snoopy am

MEGA65 - Tipps und Tricks - Sammelthread

  • Weil ja doch immer wieder mal ein paar Tipps zum MEGA65 geschrieben werden, die Beiträge dann aber wild verstreut hier im Forum liegen, dachte ich mir, ich eröffne einfach mal einen Thread, in dem man kleine und große Tipps für den MEGA65 sammelt. :search:


    Also, wer mit dem MEGA65 (oder Emulator) rumspielt und dabei was rausfindet, was für andere hilfreich sein könnte, dann einfach hier in diesen Thread schreiben. :)



    Ich fange einfach mal an mit einer einfachen Möglichkeit, in DATA-Zeilen auch hexadezimale Zahlen angeben und diese dann mittels READ lesen und auswerten zu können. Ursprünglich stand dieser Tipp hier.


  • Also die Idee, was Snoopy vorschlägt finde ich gut.

    Das mit "Tip of the Day-Discord-Kanals" von diesen Kanal wusste ich bis dao überhaupt nicht, Da ich mich hier im Forum 64 aufhalte.

    Und wenn man Tante Google nach sowas fragt, ich meine nach Tipps für den Mega65, spukt sie nicht sonderlich viel aus, wenn über haupt gar nichts. Überwiegend Altes Material des Mega 65.


    Mir schweb sowas wie "codebase64.org" für den Mega65 vor. Das wäre eine Gute Anlaufstelle.

    Aber wir müssen halt mal Anfange und nicht immer alles zerreden. Lasst uns es einfach machen. Und wenn genügend Material da ist, könnte es ein Sonderausgabe geben für den Mega 65.

    Denn wenn er ausgeliefert wird, können sich alle darauf stürzen und loslegen zu proggen. :thumbsup:


    Im disen Sinne, hier mal ein kurzer Code um den Zeichensatz zu verschieben.

    (wohl gemerkt stammt nicht von mir sondern von SK/UBIK

    Gruss Drachen

  • Weil es gestern hier in dem "Boulder Dash"-Thread erwähnt worden ist, will ich mal was zum Thema "Integer-Variablen" beim BASIC 65 schreiben. :)


    BASIC 65 bietet neben den Standardvariablen (reelle Zahlen) und Strings ($), auch Variablen für Bytewerte (&) und Integerwerte(%):


    (Seite 6 vom Referenzhandbuch)


    Wie man in der Tabelle sehen kann, belegen die Standardvariablen jeweils 5 Bytes im Speicher, die Integervariablen 2 Bytes und die Bytevariablen nur 1 Byte. Das heißt, dass man hier - gerade bei Arrays - Speicherplatz sparen kann, wenn man nur die Form wählt, die man auch benötigt.


    Allerdings sind - im Gegensatz zu manch anderen BASIC-Varianten - beim BASIC 65 die Byte- und auch Integervariablen im Grunde eine "kleine Mogelpackung", wenn man die Verarbeitungszeiten betrachtet. Die ist nämlich beim BASIC 65 nicht schneller (wie bei vielen anderen BASICs), sondern langsamer als das Rechnen mit den Standardvariablen (Fließkommazahlen).


    Der Grund ist der, dass die Zahlen beim BASIC 65 (fast) immer erst in Fließkommazahlen umgerechnet werden, dann entsprechend die Operation ausgeführt wird und danach wieder in Byte- bzw. Integerwerte umgerechnet werden. Das fällt bei einzelnen Rechnungen bei einer Geschwindigkeit von 40 MHz nicht groß auf, bei längeren Schleifen macht es sich in der Summe dann schon bemerkbar.


    Hier mal das Grundgerüst für meine Tests:


    Zwei Schleifen, die jeweils 10*10000 mal durchlaufen werden und jeweils zwei Variablen (AA und BB) addieren und das Ergebnis der Variabeln CC zugeweisen. Eine Schleife mit Byte- oder Integervariabeln, die andere mit Standardvariablen. Es werden jeweils die Zeiten für die beiden Schleifen A1 und A2 ausgegeben, sowie die Differenz und der Prozentsatz, der A2 schneller im Vergleich zu A1 ist.




    Das heißt, dass mit zweistelligen Standardvariablen ca. 8,3% schneller gerechnet wird als mit den entsprechenden zweistelligen Integervariablen.



    Das Gleiche mit einstelligen Variablen:



    Hier ist der Unterschied sogar noch größer (18,5% schneller).


    Ganz allgemein auch der Hinweis, dass einstellige Variablennamen immer schneller sind als zweistellige, da diese eine feste Adresse im Speicher haben und BASIC 65 sich die Zeit beim Suchen der Adresse spart. :prof:


    Hier noch der Vergleich von einstelligen Bytevariablen zu einstelligen Standardvariabeln:



    Die Standardvariablen werden hier ca. 17,2% schneller ausgerechnet.



    Abschließend noch der Vergleich einstelliger Bytevariablen zu einstelligen Integervariablen:



    Hier ist kaum ein Unterschied (0,4%) in der Verarbeitungszeit festzustellen.



    Als Fazit also:


    Wenn es auf den Speicherplatzbedarf bei Variablen oder vor allem Arrays ankommt, dann sind Byte- oder Integervariablen beim BASIC 65 eine gute Wahl.


    Wenn es auf "jede Millisekunde" Rechenzeit ankommt, dann sind Standardvariabeln vorzuziehen, weil diese bei Berechnungen schneller verarbeitet werden.



    Eine Ausnahme sind FOR-Schleifen! Diese wurden auf Integervariablen optimiert und laufen damit schneller, also zum Beispiel FOR I%=1 TO 1000:NEXT I% wird schneller verarbeitet als FOR I=1 TO 1000:NEXT I.


    Wer das auch mal selbst ausprobieren will, kann sich das angehängte D81-Image mit den Testprogrammen runterladen. :)

  • Wenn wir schon beim "Millisekunden rausholen" sind, hier der Hinweis, dass Werte in der hexadezimalen Angabe schneller verarbeitet werden als in der dezimalen Angabe.


    Dazu dieses kurze Testprogramm, das jeweils 30000 Mal mittels POKE (in die Adresse 53280 bzw. $D020) den Rahmen auf Grün (5 bzw. $5) setzt.


    Diese Varianten werden geprüft:

    Code
    1. A: POKE 53280,5
    2. B: POKE 53280,$5
    3. C: POKE $D020,5
    4. D: POKE $D020,$5


    Und das kommt beim Test raus:



    Code
    1. A: POKE 53280,5 = 2,7732062 Sekunden
    2. B: POKE 53280,$5 = 2,7350758 Sekunden
    3. C: POKE $D020,5 = 2,5762992 Sekunden
    4. D: POKE $D020,$5 = 2,5363779 Sekunden


    So als Richtwert kann man sagen, dass Zahlen in hexadezimaler Angabe (mit vorangestelltem $) ca. 7% schneller verarbeitet werden als in der dezimalen Angabe.


    Wie Anfangs erwähnt, reden wir hier von zeitlichen Einsparungen im "Wimpernschlagbereich": Bei 30000 Durchgängen "spart" man ca. 0,2 Sekunden. Aber wer "maximal schnell" in BASIC 65 sein will ... ;)

  • Mit F9 und F11 kann man BASIC-Listings zeilenweise ausgeben, was bei der irrsinnigen Geschwindigkeit des MEGA65 zum Teil recht praktisch ist... steht bestimmt auch irgendwo im Handbuch, aber ich hab das eher durch Zufall rausgefunden

  • Mit F9 und F11 kann man BASIC-Listings zeilenweise ausgeben, ...

    Alternativ kann man dafür auch CTRL+V und CTRL+P verwenden. Die gehen auch im Emulator (da sind F9 und F11 für den Emulator reserviert) oder falls mal ein Programm die F9- und F11-Taste umbelegen sollte. Das geht auch von BASIC aus mit KEY 9,... oder KEY 11,...

  • Mit F9 und F11 kann man BASIC-Listings zeilenweise ausgeben, ...

    Alternativ kann man dafür auch CTRL+V und CTRL+P verwenden. Die gehen auch im Emulator (da sind F9 und F11 für den Emulator reserviert) oder falls mal ein Programm die F9- und F11-Taste umbelegen sollte. Das geht auch von BASIC aus mit KEY 9,... oder KEY 11,...

    Besten Dank! Das ist in der Tat bestens für BASIC-Listings geeignet und sehr nützlich.


    Gibt es aber auch eine Möglichkeit auf dem Bildschirm (bspw. mit F3 oder DIR Befehl) ausgegebene Disketten-Verzeichnisse zurückzuscrollen?

  • hexfile


    DLOAD"$$",U8


    Danach kannst du das Verzeichnis mit F9/F11 durchscrollen

    Danke sehr! Sehr nützlich.

    Nachteil ist leider, dass durch DLOAD ein sich bereits im BASIC-Speicher befindendes Programm gelöscht wird. Was bei Verwendung von DIR nicht der Fall ist - nur kann man dann offenbar nicht in der Directory-Auflistung scrollen (sondern im BASIC-Programm, falls vorhanden).

  • Nachteil ist leider, dass durch DLOAD ein sich bereits im BASIC-Speicher befindendes Programm gelöscht wird.

    Deswegen sah und sehe ich es sehr skeptisch, dass diese Variante mit ins ROM genommen worden ist.


    Mit dem MEGA65 ist man es einfach gewohnt, dass man sich das Directory anzeigen lassen kann, ohne dass dadurch das aktuelle BASIC-Programm gelöscht wird. Ein DLOAD"$$" löscht das jedoch ohne weiteres Nachfragen. Wer in dem Moment nicht daran denkt und ausnahmsweise mal den Befehl verwendet, der verliert deswegen sein BASIC-Programm, so es denn nicht vorher abgespeichert worden ist.


    Ich persönlich halte eine BASIC-Programm löschende Variante, sich das Directory anzeigen zu lassen, beim MEGA65 für einen nicht "ungefährlichen" Rückschritt zu C64-Zeiten. Aber der Befehl ist halt jetzt mit drin, wer ihn nutzen will, kann das tun. ;)

  • Mit F9 und F11 kann man BASIC-Listings zeilenweise ausgeben, ...

    Alternativ kann man dafür auch CTRL+V und CTRL+P verwenden. Die gehen auch im Emulator (da sind F9 und F11 für den Emulator reserviert) oder falls mal ein Programm die F9- und F11-Taste umbelegen sollte. Das geht auch von BASIC aus mit KEY 9,... oder KEY 11,...

    Besten Dank! Das ist in der Tat bestens für BASIC-Listings geeignet und sehr nützlich.


    Gibt es aber auch eine Möglichkeit auf dem Bildschirm (bspw. mit F3 oder DIR Befehl) ausgegebene Disketten-Verzeichnisse zurückzuscrollen?

    Es geht auch List p

    Dann wir das Listing Seitenweis angezeigt

  • Sprungtabellen mit FGOTO/FGOSUB


    Da hier im Boulder Dash-Thread die Diskussion aufkam, wie man längere ON GOSUB-Zeilen handhaben kann, will ich mal die Möglichkeit erläutern, mit FGOTO bzw. FGOSUB relative flexible Sprungtabellen zu verwenden.


    Für ein Beispiel mal angenommen, man hat in seinem BASIC-Programm eine Situation, in der man abhängig vom Wert einer Variablen W an bestimmte Zeilen im Programm springen will. Für unser Beispiel hier wäre das etwa:

    Die naheliegende Lösung hier wäre etwa:


    ON W GOSUB 200, 210, 220, 200, 210, 220, 200, 210, 220, 200, 210, 220


    Man könnte es in dem konkreten Fall sicherlich auch anders lösen, aber es geht ja jetzt nur mal um ein Beispiel. ;)


    Das funktioniert auch wie es soll und passt. :)



    Nur, dauert das "etwas", bis zum Beispiel für W = 12 der zwölfte Parameter bei ON GOSUB ermittelt wird.


    Etwas schneller geht es (je mehr Auswahlmöglichkeiten, desto mehr fällt das ins Gewicht) mit einer Sprungtabelle und FGOTO bzw. FGOSUB.


    Für das Beispiel werden in ein Array G() aufsteigend die Zieladressen eingespeichert, also G(1)=200, G(2)=210, G(3)=220, G(4)=200, ..., G(12) = 220.


    Die Anweisung für den Sprung ist dann angenehm kurz: FGOSUB G(W)


    Vorteile sind hier zum einen die schnellere Laufzeit, gerade wenn öfter höhere Werte von W auftreten und zum anderen eine gewissen Flexibilität in den Zieladressen. Zum Beispiel wäre denkbar, dass in einem zweiten Level bei W=1 nicht zur Zeile 200 gesprungen werden soll, sondern dann zur Zeile 300. Dafür müsste man nur vorm zweiten Level G(1)=300 setzen und gut ist.


    Nachteil von FGOTO und FGOSUB ist, dass prinzipiell die Zieladressen bei einem RENUMBER nicht berücksichtigt werden können. Nach einem RENUMBER müssen also die Zieladressen in der DATA-Zeile für die anzuspringenden Zeilernummern kontrolliert und eventuell angepasst werden. :prof:



    Aber nun genug "Theorie", hier nun die zwei Beispiele und die ermittelte Laufzeit in Sekunden für 20000 Schleifen, in den W von 1 bis 12 durchlaufen und jeweils ein Aufruf zum Sprung erfolgt.


    Bei ON GOSUB habe ich alle Zeilen des FGOSUB-Beispiels dringelassen (DATA, READ usw.), auch wenn man die hier nicht benötigt. Ich wollte allerdings das Programm aus Fairnessgründen möglichst gleich halten, damit ein kürzeres Programm keinen Einfluss auf die Laufzeit des GOSUB-Befehls hat. Also möglichst gleiche Bedingungen schaffen. :)


    ON GOSUB:




    mega65_on_gosub_b.png



    FGOSUB:




    mega65_fgosub_b.png




    ON GOSUB benötigt 49,625 Sekunden und FGOSUB benötigt 35,249 Sekunden (getestet mit ROM 920350).


    Die Lösung mit FGOSUB ist in diesem Beispiel also ca. 29% schneller als die Lösung mit ON GOSUB. :prof:



    Edit: Ich habe gerade Interesse halber beim ON GOSUB-Beispiel doch mal alle Zeilen entfernt, die man dafür nicht benötigt. Die Laufzeit bleibt trotzdem exakt gleich bei 49,625 Sekunden. Wenn die Zielzeilennummer eines GOTO/GOSUB-Befehls bei BASIC 65 höher ist als die aktuelle Zeilenummer, dann startet sie Suche nach dem Ziel immer bei der aktuellen Zeile. Insofern spielt es hier für die Laufzeit keine Rolle, ob niedrigere Zeilennummern vorhanden sind oder nicht.