Segmentgrößenbestimmung

Es gibt 41 Antworten in diesem Thema, welches 7.084 mal aufgerufen wurde. Der letzte Beitrag (20. Dezember 2011 um 23:28) ist von Lysosom.

  • Probieren ist Kacke. Also deshalb meine Frage: Kann man sich die Größen der Segmente ausgeben lassen beim Compelieren?

  • einfach ein mapfile mit ausgeben lassen, da stehen die drin

  • Segment list:
    -------------
    Name Start End Size
    --------------------------------------------
    ZEROPAGE 000002 00001B 00001A
    BSS 0007FF 002484 001C86
    SIDSEGM 001079 001079 000001
    STARTUP 001305 001398 000094
    INIT 001399 00140E 000076
    CODE 00140F 00ADEC 0099DE
    RODATA 00ADED 00B288 00049C
    DATA 00B289 00B371 0000E9
    ZPSAVE 00B372 00B38B 00001A

    Danköö

  • Code
    MEMORY {
        ZP:   start = $0002,                size = $001A,                      type = rw, define = yes;
        LOWRAM:  start = $07FF,             size = $1000-$07ff,                define = yes, fill = yes;
        SIDRAM:  start = $1000,             size = $1f3a-$1000,		   define = yes, fill = yes;
        RAM:  start = $1f3a,		size=  $c801-$1f3a,	    	   define = yes;
    }

    BSS und CODE sind bei mir zu groß. Insgesamt um 3092 Bytes.

    Was muß ich ändern?

    $c801, kann ich Speicher oberhalb nutzen?
    $07ff, kann ich Speicher unterhalb nutzen?

    (CODE und LOWCODE habe ich schon getrennt und in Benutzung.)

  • in BSS legt der compiler nicht-initialisierte variablen ab. in CODE landet wie der name schon sagt der code.

    wenn das nicht passt bleibt nur den code entsprechend zu optimieren =P

    mit dem speicherende bei $c800 kannst du ein *bischen* hoch gehen. hinter c800 liegt der stack für den c-compiler, dh für den sind 2kb reserviert. je nachdem was dein program macht braucht es aber viel weniger, ich dreh das oft auf 1kb oder gar 512bytes runter, bzw das speicherende nach cc00 bzw ce00.

    den rest vom speicher kannst du auch nutzen, dann musst du allerdings auf grosse teile der mitgeliefierten libraries verzichten, weil die halt den kernal brauchen.

  • Ich komme jetzt gerade so hin mit meinem Speicher.

    Frage: Wird der Stack "von hinten nach vorne" beschrieben?

    Auf wlche der obigen *.h müßte man verzichten und wieviel Extra-Speicher bringt sowas und wo?

  • Zitat

    Frage: Wird der Stack "von hinten nach vorne" beschrieben?


    ja genau. idr startet er bei $cfff und wandert nach vorne

    Zitat

    Auf wlche der obigen *.h müßte man verzichten und wieviel Extra-Speicher bringt sowas und wo?


    guck doch mal in das mapfile, da werden am anfang alle eingelinkten funktionen und ihr jeweiliger speicherverbauch gelistet. "pintf" wäre zb etwas das ich versuchen würde loszuwerden, sowie die funktionen für file io (fopen usw).

  • "in BSS legt der compiler nicht-initialisierte variablen ab."

    Warum ist BSS dann so groß?
    Sind das Variablen, die in Funktionen eigentlich neu initialisiert werden? (ich dachte die sind im Stack)

  • Da liegen alle Variblen drin, die beim Starten auf 0 gesetzt werden.
    Bitte melde dich an, um diesen Link zu sehen.
    Ob das beim CC65 genauso ist, weiß ich allerdings nicht ...

  • da musst du schon ein bischen mehr kontext liefern, so ist da nix dran auszusetzen :)

  • ok, [...][...] zu verwenden, wenn man nur den Zeiger übergibt, kann nicht funktionieren, ok.

    Aber ich bekomme den Zeiger auf array char name [y][x] einfach nicht übergeben??

  • Prima, da habe ich nett meinen eigenen Code überschrieben.

    Meine erste Version, den Zeiger zu übergeben, klappt jetzt. SORRY FÜR DIE VERWIRRUNG.

    ALSO WIEDER EINE FRAGE, DIE HIER HER GEHÖRT:

    Welche Programme gibt es zu cc65 ??? , denn

    A Mich interessiert, welche Funktionen genau wieviel Zeit kosten.
    B Welche Funktionen welchen Codeumfang in Byte haben.
    C Die Größen der festen Variablen gelistet.
    D Für welche Befehle benötige ich die Bibliotheken, die ich los werden will um mehr Speichermöglichkeiten mir zu eröffnen ohn Kernal?

  • Wieder zu Segmentgrößenbestimmung:

    Ich hatte immer Angst, wichtige Teile des Kernals zu löschen, weil sich das hier immer gefährlich anhörte. Wie damals meine Sorge, das Internett zu löschen.

    Jetzt greife ich aber prima schon ab 0xE400 zu, indem ich den Romsteim ausblende beim Lesen und das andere Ding ein. Beim Schreiben gibt es garkeine Probleme.

    Meine Fragen also:

    1. Wie benutzt cc65 den Speicher "hinterm" Rom?
    2. Kann es Probleme geben, wenn ich alle Daten darein haue, selbst die einzelnen Datengrößen bestimmend?
    3. Benutzt cc65 den Teil des Speichers garnicht?
    4. Hilft cc65 dabei, schlimmstenfalls auch Code darein zu stopfen, wenn der dazu gedachte Speicher überläuft`?

  • Also zumindest wenn Du den Hires-Mode benutzt, wird dazu Speicher unter dem Rom benutzt. Im Moment probiere ich gerade die Roms komplett abgeschaltet zu lassen, weil ich aktuell wohl eh keine Routinen davon nutze (für Textausgabe o.ä.).

    Ich gehe mal nach diesem Beispiel vor

    Bitte melde dich an, um diesen Link zu sehen.

    , wo ja der IRQ-Pointer in 0xfffe umgesetzt wird, was ja bei eingeschaltetem Rom wohl nicht geht. Ich hab vorher auch versucht den Pointer in 0x314 zu nutzen hab aber nur nen Reboot hinbekommen.

    Aktuell läuft der RasterIRQ anscheinend, nur die Hauptroutine steht nun. Muss ich mal weitersuchen.

    Ciao,
    Andreas

  • Den IRQ muss man im RAM nicht unbedingt setzen, wenn man allen Code mit gesetzem I Flag ausführt (SEI).

    Den Reset Vektor so und so nicht, weil ein Reset ja automatisch den ROM einblendet.

    Der NMI ist das Problem. der ist nicht maskierbar und die RESTORE Taste liegt auch offen rum ...

    ------------

    Die beste Lösung ist es: den RAM-IRQ und RAM-NMI auf eine eigene Routine zu setzen, die NICHT im ROM überlagerten Bereich liegt. Also $C oder unterhalb von $8.

    Die beiden Routinen blenden den ROM ein, führen die alte ROM Routine aus, blenden wieder RAM ein und kehren zurück.

    Sowas nennt man Wrapper, kann man auch für Kernelroutinen machen, wenn man zb. 64K RAM will und trotzdem auf die Floppy zugreifen.

    -----

    Die Alternative ist, man klaut sich den Kernel Code soweit man ihn braucht und baut ihn ein ins eigene Programm. Dann spart man sich die Wrapper ganz.

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

  • Vernunftmensch: Ad 1) Die Laufzeitbibliothek benutzt den Speicher unter dem Kernal-ROM nicht. „Unter“ ist gebräuchlicher als „hinter“ weil „hinter“ missverständlich sein kann wenn der Kontext nicht klar ist, denn damit werden ja auch höhere Adressbereiche beschrieben. Es wäre zum Beispiel bei der Beschreibung „Die Daten liegen hinter dem BASIC-ROM“ sonst nicht klar ob damit nun im RAM ab $A000 oder im RAM ab $C000 gemeint ist.

    Es gibt allerdings zwei Erweiterungen die den Speicher nutzen: Der Grafiktreiber und für das Speichererweiterungs-Modul gibt es auch eine Implementierung, die den Speicher dort anbietet. Die beiden APIs schliessen sich gegenseitig aus, und natürlich auch anderen Code der auf den Speicher dort zugreift.

    Ad 2) Was sind für Dich „alle Daten“, und was hast Du mit den Daten vor? Grundsätzlich kannst Du natürlich nicht alles mit den Daten dort machen was die Standardbibliothek an Funktionalität bietet. Wenn da zum Beispiel ein Dateiname liegt, dann bekommst Du den nicht an die Kernal-Routinen zum Öffnen von Dateien übergeben, denn wie das ROM eingeblendet ist, dann ist der Name nicht sichtbar und wenn der Name nicht sichtbar ist, kann man die Kernal-Routine nicht aufrufen.

    Ad 3) Siehe Ad 1.

    Ad 4) Nicht automatisch. Man kann aber beim Compiler angeben welche Namen für die Standardsegmente verwendet werden sollen. Wenn Code aus einer Übersetzungseinheit also nicht im `code`-Segment landen soll, kann man mit der ``--code-name``-Option ein anderes Segment vorgeben. Mittels ``pragma`` kann man das im Quelltext selbst noch etwas feiner steuern und auch den Code aus einer Übersetzungseinheit auf mehrere Segmente verteilen.

  • Dicken Dank für diese Beschreibung. Gibt es irgendwo eine Liste, für welche Funktionen man die Roms braucht, so dass man z.B. solche Funktionen dann aufruft, _bevor_ man die Roms abschaltet? Also z.B. erst alle benötigten Dateien laden und erst später die Roms ausblenden?

  • Es gibt ROM-Listings, in denen alle Funktionen des ROMs beschrieben sind. Wenn Du die haben willst, dann ROM ein, sonst ROM aus.

    Ein paar Dinge fallen mir ein, die man gerne dem ROM überlässt:

    Für das initialisieren eines Fastloaders wird man 99,99%ig das ROM benutzen, zu viel Aufwand, kompatible serielle Routinen zu schreiben, nur, um sie dann nicht zu benutzen . Für Fließkomma und Tastaturabfragen wird man wohl auch gerne das ROM benutzen, wobei ein einfacher Ersatz für Tastaturabfragen auch schonmal von Hand programmiert wird.