Hallo Besucher, der Thread wurde 10k mal aufgerufen und enthält 29 Antworten

letzter Beitrag von Hexworx am

TASS will kein jsr machen ??

  • Ich versuche gerade mit dem Assembler TASS was ganz simples zu machen aber des assembler scheint das jsr zu ignorieren.
    Ich habe diesen Code hier für den C65 erstellt:


    Irgendwie springt er vom makro (segment) nicht nach accu_to_hex (in ziele 20). Zum einen wird das sta 2070 nicht ausgeführt (ich sehe nichts auf dem Bildschirm) und zum anderen werden die Ausgaben in Zeile6 und Zeile14 so ausgegeben wie wenn die Sprünge nicht ausgeführt werden. ?(
    Die Ausgaben auf dem Bildschirm sind genau die, die den Werten des accus in Zeile 12 bzw. in Zeile 4 entsprechen.


    Ich hab schon nachgeschaut ob beim C65 jsr die register konserviert - aber das mache es dort auch nicht - und das würde auch nicht so viel Sinn machen.


    Ich vermute mir fehlt ein compilleparameter oder etwas in der Art.
    Kann mir da jemand weiterhelfen?

  • OK, ich habe das die Ursache für das Problem gefunden ... nur wie behebe ich es jetzt. ?(


    Hier erst mal die Ursache:

    Der Übertäte sind die beiden Byte in Rosa.
    Das programm sollte eigentlich bei 2100 anfangen.
    Dadurch gibt es überall eine verschiebung von 2 Byte.
    In blau die 20 ist der Jump befehl. Er spring nach 2125 (orange) sollte aber eigentlich nach rosa springen.


    Vielleicht hat das ganze mit einem Header zu tun. Der ist nämlich nicht wiegewohnt:


    Nehben dem SYS, brauche ich noch den BASIC-Befehl "BANK 0", weil ich sonst in die Datenbank (also die Bank, wo die Daten abgelegt sind) springe und ich in die ProgrammBank.


    Hat jemand ne Idee was für das Offset verantwortlich sein könnte?

  • "Verschiebung um zwei Byte" riecht immer ganz stark nach fehlender/zusätzlicher Ladeadresse. Aber um brauchbare Tipps zu bekommen, solltest Du den Code auf ein minimales Beispiel reduzieren. Das da oben ist ziemlich Kraut und Rüben: Ein Monitordump ab Adresse "0100" (?), mit NOP:LDA#:LDX#:LDA# vorweg (?), dann ein Basic-Header ab $2000 (?).
    Also: Minimales Beispiel mit komplettem Source und komplettem Binary, dann sehen wir weiter.

  • hallo hallo


    wenn ich das richtig interpretiere, gibt deine subroutine 'accu_2_hex' immer ein $3 aus.
    das wird kein lesbares zeichen auf dem bildschirm sein.


    ich will damit sagen, deine subroutine 'accu_2_hex' überschreibt jedesmal den aktuellen inhalt
    des ACCUS mit $3. dieser wert wird dann an stelle 2070, 2049 und 2048 ausgegeben.


    just my 2 cents rijo...

  • So, hier nochmal alles in Minimal Form.
    Das Programm lautet komplett wie folgt:

    Der Header am Anfang bewirkt das ich nach dem Laden des Programmes und LIST follgendes sehe:


    2005 BANK0
    2006 SYS8449


    Das benötige ich damit das Programm auf den C65 mit RUN startet.


    Das Programm führt zu follgender Ausgabe:
    srceen_top_left.jpg


    Der Hexdunm dazu ist:

    Man sieht wieder den offset von 2.


    Ausserdem kann ich mit auch nicht die 00 20 am Anfang erklähren. Vielleicht gibts ja da nen Zusammenhang.
    Und der Sprung unten in Zeile 30 würde ja nach 203e gehen .. das mach jetzt ja noch weniger sinn. ?(?(

  • Ist die $00 $20 am Anfang nicht die Ladeadresse $2000?


    Edit: Habe mal den Sourcecode verglichen mit dem Objektcode. Sieht soweit korrekt aus mit Ausnahme des fehlenden RTS ($60) am Ende. Was genau ist eigentlich das Problem? Am Anfang des Programms packt der Assembler die Ladeadresse mit hinzu. Mehr nicht. Wird das Programm denn überhaupt richtig geladen, d. h. wird die Ladeadresse vom Kernal richtig interpretiert?

  • Ist die $00 $20 am Anfang nicht die Ladeadresse $2000?


    Edit: Habe mal den Sourcecode verglichen mit dem Objektcode. Sieht soweit korrekt aus mit Ausnahme des fehlenden RTS ($60) am Ende. Was genau ist eigentlich das Problem? Am Anfang des Programms packt der Assembler die Ladeadresse mit hinzu. Mehr nicht. Wird das Programm denn überhaupt richtig geladen, d. h. wird die Ladeadresse vom Kernal richtig interpretiert?

    Hi M.J.,


    gut erkannt. Dann stimmt das Programm so ... warum springt er dann nicht.
    Wie Du richtig erkannt hat, hbe ich in der ersten Variante das rts am ende vergessen.
    Selbst da ist er sauber ausgesdtiegen.
    Und auch jetzt, mit dem rts. Das Zeichen aus der subroutine kommt nicht. Es sieht so aus als würde er einfach jrs ignorieren.

  • Noch ein test - zum ganz sicher gehen:



    gibt nur ein C aus. Aber mit


    Code
    1. start:
    2. lda #$00
    3. jsr onemore
    4. lda #3
    5. sta 2068
    6. sta 2069
    7. rts

    werden zewi C's ausgegeben.

  • ???? :gruebel

    Ich glaube das stimmt, Das Handbuch sagt:


    --m4510
    CSG 4510. Enables extra opcodes and addressing modes specific to this CPU. Useful
    for C65 projects.


    und dann (für inline statt commandline):
    .cpu "4510" ;CSG 4510


    und ein
    .cpu "m4510"


    führt auch zu nem compilerfehler (unknown processor).


    Vielleicht hat ja auch der Emulator nen fehler - aber so nen ellementaren? Das kann ich mir nicht vorstellen.

  • Meine Fragen wären folgende:
    1.) Befindet sich das Programm nach dem Laden tatsächlich an der Adresse, für die es assembliert wurde?
    2.) Ist TASS ein 2-Pass oder Mehrpass-Assembler? Von 2-Pass-Assemblern kenne ich das Problem, daß es beim zweiten Pass (Codeerzeugung) dazu kommen kann, daß sich Adressen verschieben, z. B. wenn man folgendes schreibt:

    Code
    1. lda label
    2. ...
    3. label: .equ $12 ; Zeropageadresse!

    In diesem Fall "denkt" der Assembler im ersten Durchlauf, daß an der Stelle "lda label" ein 3-Byte-Befehl stehen muß für "Lade von absoluter Adresse". Das Label wird dabei mit einem 2-Byte-Integerwert (z. B. $8000) vordefiniert. Später erhält jedoch das Label den Wert $12, woraufhin im nächsten Durchlauf ein 2-Byte-Befehl erzeugt wird und dadurch alle Adressen um ein Byte verschoben werden.
    3.) Hast Du mal ACME probiert anstelle von TASS? IIRC soll laut Mac Bacon der neue ACME auch 4510-Code erzeugen können. Erscheint da dergleiche Fehler?

  • 4510 ist die C65-CPU.


    Aaalso:


    Der Offset im Hexdump ist wie schon gesagt die Ladeadresse. Da Du das Programm bei $2000 anfangen lässt, hängt der Assembler diese zwei Bytes davor. Beim Laden werden die dann wieder entfernt, landen also nicht im Speicher (überprüfe es mit dem eingebauten Speichermonitor!). Ist also ok.


    Aber wieso eigentlich $2000? Ich hab vom C65 keine Ahnung, vielleicht ist die Adresse korrekt, aber traditionellerweise beginnt der Basicbereich bei den CBM-Acht-Bittern immer bei $xxx1. Überprüf das mal.


    Dann ist der erste Zeilenlink falsch, der zeigt nicht auf die zweite, sondern auf die dritte Zeile. Das macht zwar gar keinen Unterschied, da Basic automatisch neu verlinkt, aber wenn ich eh schon beim Erbsenzählen bin...


    Dann kommt das SYS: Im Source steht "^start+1" (?), im Kommentar steht 4096, im Binary steht 8241 (das wäre $2031), laut Source wäre aber $2030 korrekt, also 8140. Da müsste ins Argument gesprungen werden, was aber einen BRK ausführen müsste, und der passiert ja scheinbar auch nicht. Überpüf das mal. :D


    EDIT: Falls der C65-Kernal das Folgebyte zu BRK irgendwie interpretiert und dann dahinter weitermacht, wäre klar, warum JSR nicht ausgeführt wird. Stattdessen würde "3e 20" als Opcodes interpretiert, was man jetzt erstmal in der 4510-Tabelle nachschlagen müsste...

  • Hallo Zusammen,


    nachdem ich nochmals das Programm in den C65 geladen habe konnte ich per Print Peek feststellen, dass das Programm korrekt im Speicher lag.


    Ich habe dann das Programm minimal umgeschrieben und in den C64 geladen.


    Dort musst ich es zwar dann per Sys starten, aber es hat tadellos funktioniert.


    Es liegt also am Emulator. Damit stelle ich erst mal meine Vorentwicklung von SW für den C65 ein :cry: .
    Und fange wieder damit an wenn ich einen Mega in echt hab.
    Immerhin ein weiteres pro-Argument für das Teil :thumbsup: .


    Ich danke Euch allen für die Unterstützung und hoffe nicht zu sehr genervt zu haben.
    Immerhin enthält der treat ein paar Infos, die ganz nützlich sein können, wenn wir dann mal mit der C65-Programmierung anfangen.


    Gruß,
    Zaadii.


    P.S.: Hier das entsprechende Programm dass ohne problene drei C's auf dem Bildschirm ausgibt:

  • 4510 ist die C65-CPU.


    Aaalso:


    Dann kommt das SYS: Im Source steht "^start+1" (?), im Kommentar steht 4096, im Binary steht 8241 (das wäre $2031), laut Source wäre aber $2030 korrekt, also 8140. Da müsste ins Argument gesprungen werden, was aber einen BRK ausführen müsste, und der passiert ja scheinbar auch nicht. Überpüf das mal. :D

    Hi Mac Bacon,


    Dein Tipp hat mich echt nochmal ins Grübeln gebracht - aber es scheint alles an der richtige stelle zu liegen (oder auch alles falsch und um eines verschoben - aber es passt zusammen.) Schwer zu erklähren, aber der Screenshot sollte es erklähren. Es liegt wohl echt am Emulator:


    Trotzdem danke für die Tipps.
    Gruß,
    Zaadii.

  • Gerafft hab ich's auch noch nicht, aber ersetz doch mal den (komischen) ".null" durch was 'normales' (.byte .text o. ä.). Vielleicht hat der damit zu tun.

  • Verzeih, aber so ganz habe ich das noch nicht verstanden. Wenn der Code lautet

    Code
    1. * = $2030
    2. start:
    3. lda #$00

    dann sollte der Speicher so aussehen:
    $2030 / 8240: $a9 / 169
    $2031 / 8241: $00 / 0
    Das paßt aber nicht zu den Ergebnissen der Peekanweisungen. :gruebel
    Irgendwie will mir nicht in den Kopf, daß ein Emulator den Befehl JSR nicht korrekt ausführen soll. Wenn dem so wäre, dürfte eigentlich gar nichts funktionieren.
    Mich irritiert hierbei auch die Verwendung des ".null"-Pseudoopcodes zur Erzeugung des Strings "SYS <Adresse>", 0. Zwar habe ich es auf die Schnelle in der Kurzbeschreibung des TASS nicht gefunden, aber ich gehe mal davon aus, daß der Operator "^" einen String aus dem Wert start+1 erzeugt. Hier wäre dann die Frage, woher der Assembler beim ersten Durchlauf weiß, wie lang dieser String sein muß, da ja "start" erst nachfolgend definiert wird. Hast Du mal versucht, den String per Hand einzutragen?
    Apropos per Hand: Man könnte noch versuchen, das Testprogramm per Hand direkt in den Speicher zu poken um zu schauen, was dann passiert. Sollte das dann immer noch nicht funktionieren, liegt es in der Tat am Emulator. Aber so recht glauben tue ich das nicht.

  • Es liegt nicht am Emulator.


    Die Ladeadresse ist falsch, damit wird das Argument von JSR falsch assembliert und springt direkt zum RTS vor der eigentlichen Subroutine, denn der LOAD"dings",8 lädt das Programm an den korrekten Basicstart $2001.


    Ich zitier mich mal selbst:

    Sieh Dir das Programm doch mal mit dem integrierten Speichermonitor an, ob auch wirklich an die richtige Stelle gesprungen wird.

    überprüfe es mit dem eingebauten Speichermonitor!


    EDIT: Die Anweisung lautet übrigens "MONITOR".

  • Es liegt also am Emulator. Damit stelle ich erst mal meine Vorentwicklung von SW für den C65 ein .

    4510 ist die C65-CPU.

    @MacBacon:
    Kannst Du in acme nicht auch die 4510-CPU mit einbauen ? Dann muss Zaadii sich auch nicht mehr mit TASS rumärgern.


    Zaadii: crossdev ist doch eh viel praktischer !!