cc65 Pointer Arithmetik

Es gibt 60 Antworten in diesem Thema, welches 13.182 mal aufgerufen wurde. Der letzte Beitrag (6. Januar 2012 um 19:16) ist von daybyter.

  • Hallo!

    Bin C-technisch ein wenig eingerostet, und versuche gerade eine kleine Sprite-Lade-Routine mit dem cc65 zu schreiben und er bringt mich gerade etwas zur Verzweiflung. Es geht um folgende, kleine, Funktion:

    , und nun scheitert es schon in der Zeile:
    unsigned char *bankStart = ((unsigned char *)CIA2.pra & 3) << 14;

    , wobei der Compiler meint:
    ====
    localhost shooter # make
    cl65 -t c64 shooter.c sprite.c -o shooter
    sprite.c(67): Error: Expression expected
    sprite.c(67): Warning: Statement has no effect
    sprite.c(67): Error: `;' expected
    sprite.c(67): Error: Expression expected
    sprite.c(67): Error: Undefined symbol: `bankStart'
    sprite.c(67): Error: Invalid lvalue in assignment
    sprite.c(67): Error: Integer expression expected
    sprite.c(70): Error: Expression expected
    sprite.c(70): Warning: Statement has no effect
    sprite.c(70): Error: `;' expected
    sprite.c(70): Error: Expression expected
    sprite.c(70): Error: Undefined symbol: `screenOffset'
    sprite.c(70): Error: Invalid lvalue in assignment
    sprite.c(70): Fatal: Too many errors
    make: *** [all] Fehler 1
    ====

    Sieht jemand auf die Schnelle, warum das kein Ausdruck sein soll? Irgendwie bin ich wohl gerade etwas blind...

    Vielen Dank im Voraus,
    Andreas

  • variablendeklarationen müssen immer am anfang eines blocks btw scopes stehen, das funktioniert mit cc65 sonst nicht.

  • Dicken Dank für den Tipp! Das war eines der Probleme. cc65 hat dann noch etwas über meine Integer-Rechnerei gemeckert, aber so compiliert der Code mal zumindest:

  • daybyter: Die Fehlerbehandlung bei der Datei ist nicht so gut. Wenn nicht 63 Bytes gelesen wurden, verlässt Du die Funktion ohne die Datei zu schliessen. Mit so etwas handelt man sich oft unter ”grossen” Betriebssystemen schon Probleme ein, aber beim C64 ist die Anzahl der Dateihandles doch *sehr* begrenzt.

  • Guter Tipp! Das hab ich übersehen. Vielen Dank! Ändere ich gleich.

    Ich gehe ehrlich gesagt davon aus, dass der User an dieser Stelle mal kurz zum Ein/Aus-Schalter greift, wenn das Spiel steht, so dass ein verlorenes Filehandle nicht so gross stören würde. :)

    Um richtig defensiv zu programmieren, wäre ja vor allen Dingen noch ein Test nötig, ob
    - die Speicheradresse im aktuellen 16k Block des VIC liegt, und
    - ein Vielfaches von 64 ist.

    Andererseits grüble ich halt wegen der Performance. D.h. wenn ich 8 Sprites lade, würde ja jedesmal getestet werden, was halt Zeit kostet.

    Vielleicht kann man es so machen, dass man diese Tests in ein ifdef legt, so dass sie z.B. fürs Debuggen aktiviert werden können und bei einer Release entfernt werden. Muss ich mal grübeln....

    Meinst Du, dass Interesse an so einer kleinen Sprite-Lib besteht?

    Danke nochmal für den Tipp,
    Andreas

  • Hier ein Tüpfelchen mit Datenübergabe.

    Es können alle Realberechnungen (Sin,Cos,Tan...MUl ,Dif , Potenz und...und ...) die Im Basic vorkommen mit ASM realisiert bzw berechnet werden. Mit eingabe der Realzahl als String, mit Integer, Ausgabe der Realzahl als String oder direkt auf dem Schirm, Ausgabe der Int zum verarbeiten in der Grafik, Kreisbewegubg usw. Der cc65 hat es geschafft, jedenfalls für den C64.
    Die Berechnungen sind ca 15-25x so schnell wie im Bremsklotz "C64-Basic".

    jup.....


    gruss

  • Zitat

    falsche Eingabe....


    damit meinst du aber jetzt deinen auf keine denkbare weise in diesen thread passenden vorherigen post, oder?

  • Hier ist eine kleine Laderoutine , womit ich ein Hiresbild einlade.
    Schau dir mal die letzten Zeilen an, da kannst du auch deine Adresse für die Sprite angeben, wo die Daten hin sollen.
    0x2000 ist die Hexadresse und 8000 die Anzahl.

    gruss


  • Zitat

    Schau dir mal die letzten Zeilen an, da kannst du auch deine Adresse für die Sprite angeben, wo die Daten hin sollen. 0x2000 ist die Hexadresse und 8000 die Anzahl.


    mal davon abgesehen das diese post auch nicht in diesen thread passt solltest du dir ernsthaft abgewöhnen leuten tips zu geben deren kenntnisse deine ein kleines bischen übertreffen. die loadtoram funktion zb funktioniert so zwar, aber nur aus zufall. fehlerfreier code sieht anders aus =)

  • Der Funktionsname ist cool `loadtoram()`. Ob's wohl auch eine `loadtorom()` gibt!? :wink:

  • Hallo plus4fan!

    Dicken Dank für Deinen Beitrag! Leider versteh ich Deine Funktion gerade nicht so ganz, weil es wohl 20 Jahre her ist, das ich ins Handbuch geguckt hab, und ich gerade nur einen winzigen Bildschirm auf dem Docs lesen nicht gut geht.

    Brauchst Du wirklich diese Poke-Befehle? Es gibt doch zumindest in _vic2.h eine Struktur, um auf die VIC Register per Namen zugreifen zu können. Such mal bei Dir nach dem File. Vielleicht hilft es Dir ja.

    Gute Nacht!

    Andreas

  • Zitat

    Brauchst Du wirklich diese Poke-Befehle?


    er will doch garkein C lernen sondern nur basic in C schreiben...

  • daybyter: Die `loadtoram()`-Funktion ist unsinnig. Die ``while``-Schleife ist unnötig, weil `cbm_read()` so viel wie möglich liest. Dass heisst es gibt nur einen Fall in dem weniger als `length` Bytes gelesen werden ohne das ein Fehler gemeldet wird: Die Datei ist am Ende angekommen (EOF). *Dann* hilft aber auch keine ``while``-Schleife in der immer wieder versucht wird aus einer Datei zu lesen aus der definitiv nichts mehr kommt. Ist die Datei also kleiner als erwartet, ist in dieser Funktion eine Endlosschleife. Und damit ist die IMHO für die Tonne.

    Zu den `POKE`\s: Neben den `VIC`- und `CIA`-Strukturen gibt es ja noch `memset()` in ``<string.h>`` um Speicherbereiche zu füllen und das aktuell beziehungsweise zuletzt benutzte Laufwerk steht unter dem Namen `_curunit` über ``<cbm.h>`` zur Verfügung. Damit sollte man das `POKE`-frei und etwas lesbarer hin bekommen.

    Was an dem Beispiel sonst noch gefährlich sein kann, ist natürlich einfach so mitten in den Speicher zu schreiben wo Programm, Variablen, Heap, oder Stack landen könnten wenn man die Speicherkonfiguration für den Linker nicht ändert. Das funktioniert dann auch nur mehr aus Glück und nicht wegen sauberer Programmierung.

    Zu Deinem Quelltext noch mal: Deine Funktion vermischt zwei Sachen, die eigentlich auch getrennt nützlich wären — Laden von Spritedaten und das setzen der Register für ein Sprite.

    Wenn das durch Sprites sowieso schon an den C64 gebunden ist, würde ich wahrscheinlich statt einer plattformunabhängigen Laderoutine einfach `cbm_load()` verwenden:

    Code
    if (cbm_load(filename, _curunit, address) != 63) return false;


    Gefahr dabei ist natürlich, dass hier auch Daten geladen werden können, die grösser als 63 Bytes sind und man das erst nach dem Laden feststellen kann.

  • Der Funktionsname ist cool `loadtoram()`. Ob's wohl auch eine `loadtorom()` gibt!? :wink:

    Ha....ha..., Bitte melde dich an, um dieses Bild zu sehen. die hat einer aus dem Forum bereitgestellt. Hatte mal um so eine Lösung gebeten.
    Ihr seid solche Nasen...ha..ha..

    Ihr grabt euch durch Lächerlichkeiten selber das Wasser ab. :gluck
    Merkt ihr nicht, das ihr euch hier im Forum gegenseitig verarscht.

    Ist schön anzusehen als aussenseiter , wie Fremde auf die lächerliche Bank geschoben werden.
    Ha...ha.... :P :P :P

    gruss

  • mal davon abgesehen das diese post auch nicht in diesen thread passt
    solltest du dir ernsthaft abgewöhnen leuten tips zu geben deren
    kenntnisse deine ein kleines bischen übertreffen. die loadtoram funktion
    zb funktioniert so zwar, aber nur aus zufall. fehlerfreier code sieht
    anders aus =)

    Merkt ihr garnicht das es nur ein Hobby ist , ihr könnt es auch nicht geniessen ... traurig, wie ernst die das hier alle sehen..ha..ha..ist schön das hiuer alles zu lesen, eine Freude. Traurig,....

    Man das ist nur ein Hobby....

    gruss

  • Was an dem Beispiel sonst noch gefährlich sein kann, ist natürlich
    einfach so mitten in den Speicher zu schreiben wo Programm, Variablen,
    Heap, oder Stack la....

    Man nehmt ihr so ein Hobby ernst....,..gefährlich ..., wenn ich das im Hobbybereich lese geht mit die Hutkrempe hoch...ha..ha..
    Ihr seid so Arm, kömmt ihr eigentlich noch fröhlich sein und lachen...ich glaube nicht.

    Also Locker vom Hocker..hä...ihr C64....

    gruss

  • Es ist so schön, wie ihr euch gegenseitig Kalt macht..., hier bleibe ich nicht lange, scheiss Klima hier.
    Man könnte auch sagen...bleibt unter Euch. Ihr seit zu Angespannt oder habt private Probleme die ihr in den C64 einfliessen lasst.
    Ist ein unfreundliches Forum, es gibt ein besseres.


    gruss

  • Laden und anzeigen einer Bitmap in C das nicht nach BASIC aussieht (ungetestet mangels Bitmap auf die Schnelle):


    Bei dem Code gibt es zwei Gefahrenquellen. Einmal dass die Bitmap-Datei grösser ist als erwartet. Die wird halt komplett geladen, egal wie gross sie ist. Und zweitens muss man natürlich noch eine eigene Linker-Konfiguration schreiben damit sichergestellt ist, dass der Speicherbereich ab $2000 nicht für etwas anderes verwendet wird. Beim Verwenden von `cbm_load()` hat man übrigens noch den Vorteil, dass Schnellader, zum Beispiel in Steckmodulen, die sich in den Load-Vektor einhängen, verwendet werden.

    Verbessert gegenüber dem Original ist auch, dass die Fehlermeldung ausgegeben wird während der Textbildschirm noch sichtbar ist. Textmodus-Ausgaben im Grafikmodus sind nicht so praktisch. :wink:

    Die VIC-Bank braucht man nicht über die CIA2 um zu schalten, da ist in der Ausgangskonfiguration schon die passende für eine Bitmap bei $2000 ausgewählt. Das zu ändern wäre nötig, wenn man die Bitmap beispielsweise nach $E000 legen möchte, was der HiRes-Grafiktreiber von cc65 macht. Der Bereich wird von der normalen Linker-Konfiguration nämlich nicht benutzt.

    @plus4fan: Könntest Du das mit diesen Mehrfachpostings mal sein lassen. Schreib *einen* Beitrag und schicke den erst ab, wenn er fertig ist.

    Hobby ist nicht gleichbedeutend mit schlampig. Im Gegenteil; die meisten Leute stecken viel Energie und Liebe zum Detail in ihre Hobbys. Sonst wäre es ja nicht ihr Hobby. Hobby ist Leidenschaft. Nicht diese lustlos hingerotzten Quelltexte voller Fehler. Jemand der sich tatsächlich für das Programmieren interessiert, und darum geht es in diesen Unterforen nun einmal, würde bei einem Hinweis darauf dass zum Beispiel ein ``asm("rts");`` am Ende einer C-Funktion überflüssig ist, diese entfernen und sich freuen, dass er etwas gelernt hat, und nicht sagen, ist doch egal, Hauptsache es funktioniert irgendwie. Gerade wenn es so eine total einfache Änderung ist, wo kaum Arbeit drin steckt, verstehe ich nicht, warum dass nicht einfach *machen* kann. Wo Du das Thema unfreundlich erwähnt hat: Dein Auftreten finde ich von Dir unfreundlich gegenüber Leuten, denen das Thema tatsächlich wichtig ist.