Hallo Besucher, der Thread wurde 11k mal aufgerufen und enthält 76 Antworten

letzter Beitrag von ThomBraxton am

Real-Zahlen und Funktionen im cc65 nutzen...zur Umsetzung

  • Hallo!


    xfMax = fsqr( _fsub( _fmul( yfMin, yfMin), _fmul( yf, yf)));


    Ich bin verblüfft...ich hab die Zeile jetzt minimal geändert:


    Code
    1. xfMax = _ftoi( _fadd( _strtof( "0.5"), fsqr( _fsub( _fmul( yfMin, yfMin), _fmul( yf, yf)))));


    , weil man doch eine Integer will. Also Deinen Ausdruck einfach gerundet, und er liefert immer 0. Läuft Deine Schleife jetzt mit floats?


    Ich bin jetzt dran, und versuch mal Teile von SoftFloat ans Laufen zu bekommen. Das sind single precision floats mit 32 bit. Wenn man es hinbekäme, dass man 2 Zahlen in den beiden long Akkus des cc65 addiert, _ohne_ dass man sie jn den Funktionen überschreibt, müsste der Einbau eigentlich machbar sein. Aber da muss ich noch ein bischen probieren.


    Ciao,
    Andreas

  • Hab jetzt mal als Ablenkung von den Floats ne Routine für verkale Linien angefangen. Ist noch ein Bug drin, aber die Idee ist hoffentlich erkennbar. Nach dem Setzen eines Bit soll die nächste, zu setzende, Adresse durch eine einfache Addition gefunden werden. Ich hoffe mal, in dieser Richtung noch ne Ecke Zeit sparen zu können...



    Ciao,
    Andreas

  • Hallo!


    Danke für Deinen Kommentar. Also es soll ja eine weisse Linie gezeichnet werden. Die Bits sollen also gelöscht werden. Insofern denke ich, dass das & schon richtig ist. Mit der Bitmaske hast Du völlig recht. Ich hab das jetzt mal auf


    unsigned char bitmask = ~( (unsigned char)0x80 >> (x & 7));


    geändert, so dass alle Bits, bis auf das bei (x mod 8 ) 1 sein sollten. Das muss doch 0 sein, damit es dann bei dem & gelöscht wird. Klappt aber immer noch nicht. Ich glaub, ich hab da auch einen Offset zu der Bildschirmspeicher-Adresse drin. Dann bin ich noch unsicher, ob die Schleife mit dem Mitführen von y so geschickt ist. Schöner wäre es eigentlich, wenn man gleich zu Anfang die letzte zu ändernde Adresse berechnet, und dann in der Schleife nur noch an die Adresse schreibt, sie erhöht und dann vergleicht, ob man schon die Endadresse erreicht hat. Ich bin mir da nur unsicher, weil es ja für einen 8-Bit-Prozessor ist, und der y-Vergleich in einem Byte zu machen ist. Der Adress-Pointer sind ja 2 Byte, die man vergleichen muss, was ja für nen 6510 mehr Aufwand ist.


    Ciao,
    Andreas

  • Ich bin so langsam am grübeln, ob der cc65 falschen Code erzeugt?


    Code
    1. *byteAddr &= bitmask;


    ist mein einziger Schreibbefehl, d.h. es dürften auf keinen Fall neue Bits gesetzt werden. Trotzdem passiert das...?


    Das macht der Compiler draus:



    Werden hier evtl. 16 bit, statt 8 geschrieben? Sind mir eigentlich nicht danach aus...*grübel*


    Ciao,
    Andreas

  • daybyter: Ich ging davon aus, dass eine Linien-Zeichnen-Routine Bits setzt und man das mit den Farben über das Video-RAM und nicht über das Bitmuster löst.


    Bezüglich `y` oder Endadresse berechnen müsstest Du halt einfach schauen was der Compiler an Code generiert. Und vielleicht noch mit der „static locals“-Einstellung und dem ``register``-Schlüsselwort experimentieren. Wobei es da dann eventuell auch einfacher sein kann es gleich in Assembler zu implementieren.

  • Diese Linienfunktion soll ja quasi den Hintergrund auslöschen, und schreibt daher in der Hintergrund-Farbe. Evtl. fass ich die plot und Line-Routine noch zusammen, damit die Adresse nur einmal berechnet werden muss. Würde nochmal bischen Zeit sparen.


    Den Code hab ich mir ja schon angesehen, steig aber noch nicht wirklich durch, weil halt soviele Unterroutinen aufgerufen werden, deren Code ich teilweise auch noch nicht ergoogeln konnte. Und auch ohne register-Schlüsselwort müsste der Code doch korrekt funktionieren, auch wenn er vielleicht langsamer ist?


    Muss ich nochmal suchen und evtl. paar Testpogramme schreiben.


    Ciao,
    Andreas

  • daybyter: Öhm, Du machst Dir ständig Gedanken was wohl für den 6510 zu schnellerem Code übersetzt wird, lässt den Compiler aber anscheinend nichts optimieren!? So sieht das mit Optimierungen aus:


    Und so wenn man dem Compiler sagt er soll lokale Variablen statisch machen:


    Dann ist die Funktion nicht „reentrant“, aber man hat für die lokalen Variablen (nicht die Argumente!) die Indirektion über den Softwarestack nicht mehr. (Man sieht das der Optimierer trotzdem noch Code erzeugt für den man einen menschlichen Programmierer hauen würde. :-))


    Beim optimierten Code musst Du auch nicht mehr so viele Unterroutinen nachschlagen. Die würde ich nicht bei Google suchen, sondern in den Quelltexten vom cc65.

  • Wenn man `byteAddr` und `bitmask` als ``register`` deklariert:

    Code
    1. 000098r 1 ;
    2. 000098r 1 ; *byteAddr &= bitmask;
    3. 000098r 1 ;
    4. 000098r 1 A0 00 L001C: ldy #$00
    5. 00009Ar 1 B1 rr lda (regbank+4),y
    6. 00009Cr 1 85 rr sta ptr1
    7. 00009Er 1 A2 00 ldx #$00
    8. 0000A0r 1 A5 rr lda regbank+3
    9. 0000A2r 1 25 rr and ptr1
    10. 0000A4r 1 91 rr sta (regbank+4),y


    Allderdings ist `register` kein Allheilmittel. Es stehen nicht unbegrenzt "Register" in der Zeropage zur Verfügung und es gibt den Mehraufwand die alten "Register"-Inhalte am Anfang der Funktion auf den Softwarestack zu sichern und am Ende der Funktion wieder herzustellen. Man sollte also nicht blindlings alles als ``register`` deklarieren, sondern auch darauf achten ob man dadurch wirklich etwas gewinnt und mit welchen Variablen der Gewinn am grössten ist.

  • Danke für den Tipp mit dem Optimieren! Da wird es schon ein ganzes Stück schneller. Funktionieren tut es dummerweise immer noch nicht. Ich schreib mal paar Testfunktionen...


    Ciao und Danke nochmal,
    Andreas


    Edit: das sta (regbank+4),y ist ja anscheinend das Speichern in den Bildschirmspeicher. Was 1 Byte wäre. Wo werden nur die schwarzen Pixel geschrieben? Ich versuch mal direkt in den Speicher zu schreiben, was dann passiert...


    Edit2: Interessant...mit folgender Schleife bekomm ich schon Müll in den Bildschirmspeicher geschrieben...das kann doch nur ein Compilterfehler sein, oder?

    Code
    1. /* Test screen writing. */
    2. for( screenPtr = (unsigned char *)0xe000; screenPtr < (unsigned char *)0xe100; screenPtr++) {
    3. *screenPtr &= ((unsigned char)0x01);
    4. }
  • Es ist wirklich viele Jahre her, dass ich ernsthaft C programmiert hab. Ich hab mich die letzten 10 Jahre fast nur um das Design von größeren Applikationen gekümmert und den ganzen Optimierungskram vergessen. Ausserdem bin ich eh ein furchtbarer Lehrer, weil ich nix erklären kann.