Register im IRQ per selbstmodifizierendem Code sichern

Es gibt 10 Antworten in diesem Thema, welches 1.283 mal aufgerufen wurde. Der letzte Beitrag (8. Mai 2014 um 20:54) ist von hoogo.

  • Bei der IRQ-Programmierung gibt es ja die Möglichkeit, den Akku sowie das X- und Y-Register per selbstmodifizierendem Code zu sichern und am Ende der Routine wieder zurückzuholen:


    Wenn ich mehrere IRQ-Routinen habe, die nacheinander abgearbeitet werden, muß ich das ja für jeden IRQ einzeln machen. Kann man nicht einfach 3 Adressen aus der Zeropage belegen, die man dann für jeden IRQ nutzt? Ungefähr so:

    So würde man sich die Mühe sparen, für jeden IRQ die Label anpassen zu müssen. Oder kann man nicht für jeden IRQ dieselben Speicheradressen für Akku, X und Y nehmen, weil sich das ins Gehege kommt?

  • Wenn die verschiedenen Interrupts tatsächlich nacheinander abgearbeitet werden, kann sich da auch nichts ins Gehege kommen. Können sie jedoch verschachtelt auftreten, wäre das ein Problem. Solange es sich nur um IRQs handelt und keine NMIs dabei sind, müsste man das "Verschachteln" aber eh erst per CLI erlauben - wenn Du das im Augenblick nicht tust, sollte das gehen.
    Ob es sinnvoll und/oder nötig ist, steht auf einem anderen Blatt. Du schaltest das ROM aus, nehme ich an? Denn falls nicht, sichert letzteres die Register ja schon selbst.

    Yes, I'm the guy responsible for the Bitte melde dich an, um diesen Link zu sehen. cross assembler. And some Bitte melde dich an, um diesen Link zu sehen..

  • Wenn bei dir nie mehrere IRQ's gleichzeitig auftreten kannst du ein und die selbe speicherstellen nutzen. Aber wenn nun eine zweite irq-routine aufgerufen wird noch waehrend die erste abgearbeitet wird wuerde ja der 2. irq die register speichern und damit die werte die der 1. irq zurueck lesen sollte ueberschreiben... das problem kannst du mit selbstmodifizierendem code aber genau so haben! kann nur vorkommen wenn du entweder NMI's benutzt oder innerhalb einer irq-routine interrupts wieder freigibst.

  • Im Normalfall nimmt man ja eher den Stack:

  • Mehrere IRQ-Routinen ist ein flexibler Begriff...

    Das kann meinen, daß Du z.B. einen IRQ ab Rasterzeile 50, einen weiteren ab Zeile 100, einen ab Zeile 200 hast. In dem Fall dürfte sicher sein, daß die IRQs wirklich nacheinander kommen. Dann läuft das, wie Du schreibst. Könnte aber auch nützlich sein, zum Umschalten zwischen diesen IRQ-Routinen nicht $FFFF, sondern einen eigenen keinen Jmp nach dem Retten der Register zu modifizieren.

    Das kann aber auch meinen, daß Du CIA-Timer mit Rastern kombinierst und per CLI im CIA-IRQ dem Raster höhere Prio gibst. Das ist jetzt nicht unbedingt "nacheinander", aber falls Du sowas meinst, dann könnte es ohne Stack ein bisschen gefährlich werden.

  • Zitat

    Aber wenn nun eine zweite irq-routine aufgerufen wird noch waehrend die erste abgearbeitet wird wuerde ja der 2. irq die register speichern und damit die werte die der 1. irq zurueck lesen sollte ueberschreiben...

    Wird nicht ggf. der aktuelle IRQ erstmal komplett abgearbeitet bis der NMI-Irq abgearbeitet wird?

  • Mehrere IRQ-Routinen ist ein flexibler Begriff...
    Das kann meinen, daß Du z.B. einen IRQ ab Rasterzeile 50, einen weiteren ab Zeile 100, einen ab Zeile 200 hast. In dem Fall dürfte sicher sein, daß die IRQs wirklich nacheinander kommen. Dann läuft das, wie Du schreibst. Könnte aber auch nützlich sein, zum Umschalten zwischen diesen IRQ-Routinen nicht $FFFF, sondern einen eigenen keinen Jmp nach dem Retten der Register zu modifizieren.

    So ist es im Moment aufgebaut, es werden die IRQs in verschiedenen Rasterzeilen nacheinander ausgelöst. Gut zu wissen, daß es in dem Fall funktionieren würde.

    Was genau meinst du mit deinem letzten Satz mit dem JMP? Momentan setze ich am Ende meiner jeweiligen IRQs immer den Vektor direkt auf den nächsten IRQ und sichere dann die Register zurück:

  • Code
    $FFFE: 00 10
    *=$1000 
    sta $fa
    stx $fb
    sty $fc
    +vector jmp $4711
    ...
    +ende
    lda $fa...

    War also was ganz popliges gemeint, spart Speicher, aber verzögert 3 Takte. Und am Ende hab ich gerne einen Zeiger in Tabellen mit Low, High, Rasterzeile gehabt, statt alle Werte direkt zu poken. War langsamer, aber einfacher zu pflegen, sofern das immer die gleichen Routinen waren.

  • Wird nicht ggf. der aktuelle IRQ erstmal komplett abgearbeitet bis der NMI-Irq abgearbeitet wird?


    nein, ein nmi kann den irq unterbrechen

  • Code
    $FFFE: 00 10
    *=$1000 
    sta $fa
    stx $fb
    sty $fc
    +vector jmp $4711
    ...
    +ende
    lda $fa...

    War also was ganz popliges gemeint, spart Speicher, aber verzögert 3 Takte. Und am Ende hab ich gerne einen Zeiger in Tabellen mit Low, High, Rasterzeile gehabt, statt alle Werte direkt zu poken. War langsamer, aber einfacher zu pflegen, sofern das immer die gleichen Routinen waren.

    Hmm, da steig ich jetzt nicht ganz durch. Der Start der Routine liegt bei $1000, dann sicherst du die Register, die du am Ende wieder zurückholst, soweit klar. Aber was bedeutet "$FFFE: 00 10"? Kann man so auch direkt den IRQ-Vektor setzen?

    Und "+vector jmp $4711"? +vector ist sicher das Label, was soll dann der JMP an der Stelle? Oder liegen da deine Tabellen für Low, High und Rasterzeile?

  • Hmm, da steig ich jetzt nicht ganz durch. Der Start der Routine liegt bei $1000, dann sicherst du die Register, die du am Ende wieder zurückholst, soweit klar. Aber was bedeutet "$FFFE: 00 10"? Kann man so auch direkt den IRQ-Vektor setzen?

    Damit wollte ich nur darstellen, daß der IRQ-Vektor bei $FFFE auf $1000 zeigt. Jetzt, wo ich es sehe, da hätt ich es auch in verständlicher Sprache sagen können... :drunk:

    Und "+vector jmp $4711"? +vector ist sicher das Label, was soll dann der JMP an der Stelle? Oder liegen da deine Tabellen für Low, High und Rasterzeile?

    Anstatt nach jedem Abschnitt von Rastereffekten die Adresse der nächste Routine nach $FFFE zu schreiben, schreibst Du sie an diese Stelle. Von den Tabellen und dem Kram drumrum hab ich nichts hingeschrieben, halt das übliche Pointerzählen und Tabellen lesen, das in den speziellen Fällen dann eh nicht taugt.