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

letzter Beitrag von cbmhardware am

ACME Zeropage Problem

  • Ich habe einen reassemblierten Code, den ich nun mit dem ACME ( ACME, release 0.96.2 ("Fenchurch"), 10 Mar 2017 ) wieder assemblieren möchte und hänge leider fest:




    Im originalen Source sind die Zeropage-Adressen mit z.B. $00AE und $00AF angegeben. Wenn ich das so mit dem ACME verwenden möchte, wird es umfangreich bemeckert. Wenn ich die Adressen auf z.B. $AE und $AF ändere, wird das erzeugte PRG entsprechend kürzer und kann natürlich nicht richtig funktionieren.


    Im Bild müsste bei C543: STX 00AE stehen ... aber wie ? - Könnte diese Stellen mit !by patchen, finde ich aber nicht wirklich schön.


    Kennt jemand eine besser Lösung ?

  • ZP addressen sind nunmal 1 byte lang wenn du die absolute adressierung moechtest probier mal zB.

    Code
    1. stx $00ae

    ich hab leider keine ahnung ob ACME das wegoptimiert.
    auf der anderen seite wuesste ich nicht warum das prg mit den ZP adressierung nicht correkt funzen sollte.

    Code
    1. lda $00ae ; laed akku mit inhalt von speicheradresse $00ae
    2. lda $ae ; laed akku mit inhalt von speicheradresse $00ae ist aber ein byte kuerzer und ein paar cyclen schneller.
  • in ACME you can specify the length of the address like that:


    "stx+1 $ae -> stx $ae"


    "stx+2 $ae -> stx $00ae"


    Yes, this works, but indirect addressing including x,y-indexing gives "Illegal combination of command and postfix" or "Number out of range" without +2.

  • Klar, indirekte Adressierung gibt es ja auch nicht für nicht-ZP-Adressen. Kannst Du da die beiden führenden Nullen nicht weglassen?

  • Bin dem Problem auf der Spur. Der DA65 baut sich Labels mit führenden Nullen aus den Zeropage-Adressen. Das ist manchmal richtig und manchmal auch falsch.
    Jetzt habe ich die Zeropage-Labelerzeugung im Infofile deaktiviert und es werden überall "kurze" Adressen eingebaut. Jetzt ist das daraus erzeugte Programm 11 Byte kürzer, es fehlt also etwas und hat sich entsprechend verschoben.


    Da werde ich dann nochmal suchen müssen. Der ACME machte es demnach wohl richtig, der DA65 hat eher das Problem.

  • Wenn man etwas reassembliert und danach daraus wieder ein Programm erzeugen möchte, müssen diese Nullen wieder am alten Platz stehen, ansonsten ist das Programm kaputt.
    Ich würde auch nie die führenden Nullen verwenden, wüsste auch nicht, wozu die gebraucht werden.

  • Yes, this works, but indirect addressing including x,y-indexing gives "Illegal combination of command and postfix" or "Number out of range" without +2.

    Da sag ich mal ganz hilfreich: Häh?


    Schritt 1: Definiere Zeropage-Symbole ohne führende Nullen, denn führende Nullen werden von ACME beachtet. Ganz frühe ACME-Versionen haben die ignoriert, aber dann haben $Leute gesagt: "Wenn ich schon führende Nullen schreibe, sollen die auch assembliert werden." (z.B. aus Timinggründen).
    Daher gilt: Wer ldx $ae schreibt, bekommt den Opcode mit Zeropage-Adressierung. Wer ldx $00ae schreibt, bekommt den Opcode mit absoluter Adressierung.
    Wenn man nun Symbole statt Literalen benutzt, passiert genau das Gleiche, denn bei der Definition ptr = $00ae wird an das Symbol die Information "der Coder will 16-Bit-Adressierung" angepappt. Ein lda (ptr),y erzeugt dann logischerweise die Fehlermeldung "Number out of range" - auch wenn das auf den ersten Blick bekloppt erscheint, ist es nur folgerichtig, denn der Coder hat den Wert nun mal mit der "Ich-will-aber-16-Bits-verdammt!"-Flagge deklariert.


    Schritt 2: An den paar Stellen im Code, wo man trotz 8-Bit-Argument unbedingt eine 16-Bit-Adressierungsart haben will, benutzt man die "+2"-Notation: stx+2 ptr erzeugt absolute Adressierung, auch wenn "ptr" eigentlich in 8 Bits passt. Das ist zwar nicht sehr schön, aber beim Disassemblieren unabdingbar, eben weil man ja nach jedem Fortschritt im Source immer noch das gleiche Binary erzeugen will.


    Schritt 3: Wenn das Programm fertig disassembliert ist (also alle internen Referenzen durch Symbole ersetzt) wurden, kann man sich überlegen, ob man Schritt 2 wieder rückgängig macht - denn erst dann kann man kompetent entscheiden, ob die 16-Bit-Adressierung an den Stellen wirklich gebraucht wird (wegen Selbstmodifikationen o. ä.) oder nur durch Schlampigkeit des ursprünglichen Programmierers bzw. seines Tools entstanden ist.

  • Hatte sich schon erledigt, war ein Problem mit dem Disassembler. Hatte die Problemstellen per Hand nachgebessert und danach neu assembliert. Da gab es keine Probleme mehr.