Hello, Guest the thread was called461 times and contains 9 replays

last post from LilaQ at the

Unerklärlicher IRQ in Buggy Boy

  • Hallo zusammen,


    beim Basteln meines Emulators bin ich grade dabei "Buggy Boy" zum laufen zu bekommen, und gehe daher Traces durch und gucke nach unterschiedlichem Verhalten zwischen meinem Emulator und C64Debugger.


    Dabei bin ich bei Buggy Boy auf etwas gestoßen, was sich mir nicht erklärt (vielleicht bin ich auch einfach zu blind mittlerweile).


    Wenn man zu diesem Zeitpunkt einen Breakpoint setzt auf 0x0991 (Buggy Boy - REMEMBER release), kommt man in dieser Subroutine an:


    Es wird ein neuer IRQ Vektor gesetzt, die Rasterline Interrupts eingeschaltet, es wird jedoch keine tatsächliche Zeile gesetzt - das D012 Register ist die gesamte Zeit auf 0000!


    Der RTS springt dann zurück zu:



    Hier führt mein Emulator nun den JSR zu 0x0AB4 aus, der C64Debugger jedoch handelt stattdessen anscheinend einen Interrupt ab, und landet im neugesetzten IRQ-Vektor:



    Jetzt meine Frage: WIE UND WARUM?

    Zu diesem Zeitpunkt sind wir weit weg von Zeile 0, und auch der CIA1 counter is weit weg davon abzulaufen. Das D019 Register zeigt auch 0x00 an.


    Also, was genau passiert hier? Habe ich irgendwas offensichtliche übersehen? Oder gibt es besonderes Verhalten mit Rasterline IRQs wenn keine Zeile gesetzt wurde? Oder ist es etwas wirklich simples was ich nicht beachte?


    Wenn mir jemand dabei aushelfen könnte, wäre ich wirklich dankbar. Ich versuche schon seit letzter Nacht dahinter zu steigen, komme aber leider überhaupt nicht weiter.


    Vielen lieben Dank schon mal im Voraus!

    LilaQ

  • Ich rate mal ganz blöd ins Blaue hinein...

    1.) Es liegt noch ein Interrupt von früher an, der nun freigeschaltet wurde. ($d019 wurde nicht gelöscht, oder?)

    2.) Es mag sein, daß $d012 den Wert 0 hat, aber was ist mit $d011? Könnte es sein, daß der Rasterinterrupt bei Zeile 256 ausgelöst wird (Highbit in $d011 gesetzt)?

  • 0xD019 ist die ganze Zeit auf 0x00.


    Bezüglich 0xD011 und 0xD012 habe ich mich undeutlich ausgedrückt, die zusammengefasste Rasterzeile für den Rasterzeilen-IRQ ist permanent auf 0.


    Mag sein dass der Interrupt (auch) bei Zeile 256 ausgelöst wird, aber davon sind wir weit weg (Zeilen 0xB8 / 184, wenn man bei 0x0C91 ankommt)

  • 0xD019 ist die ganze Zeit auf 0x00.

    Ich habe es mal versucht nachzuvollziehen, doch VICE zeigt mir beim Interrupt für $d019 den Wert $f9 an. ($d01a = $f1) Da in der Initialisierungsroutine $d019 nicht gelöscht wird, würde ich vermuten, daß es sich hierbei um einen noch ausstehenden Interrupt handelt.

    Setzt man nämlich einen Breakpoint auf $d012, erkennt man, daß während der Phase des Entpackens eine Tabelle mit VIC-Werten ab $b290 in einer Schleife nach $d000 geschrieben wird. In dieser Tabelle enthält $d012 den Wert $b6, was zur ausgelösten Rasterzeile paßt. (Achtung: Bei der Benutzung des Breakpoints im VICE-Monitor muß unterschieden werden zwischen der VIC-Adresse und der Adresse für das darunterliegende Ram, da das Programm auch dorthin entpackt wird.)

  • Da in der Initialisierungsroutine $d019 nicht gelöscht wird, würde ich vermuten, daß es sich hierbei um einen noch ausstehenden Interrupt handelt.

    This.


    EDIT: Mir fiel gerade noch dieser alte Thread zum gleichen Thema ein.

  • könntest du mir sagen wie ich das mit dem VICE Monitor nachvollziehen kann?

    Kurz gesagt: Vergiß es. Lang gesagt: Ich hatte letzte Nacht (:sleeping:) übersehen, daß $1 den Wert $10 aufwies und damit auch an der genannten Stelle der Bereich $d000..$dfff auf Ram geschaltet war. Der dort geschriebene Wert war nur zufällig ähnlich der von Dir genannten Rasterzeile. Bei einem weiteren Test stellte sich heraus, daß bei Auftritt des IRQs die Rasterzeile bei 12 lag, woran man schon erkennt, daß es sich um einen willkürlichen Wert handelt. Mac Bacon hat hier - wie immer :thumbup:^^ - recht:

    Schreibzugriffe auf $d019 bestätigen aufgetretene Interrupts, so dass der VIC die IRQ-Leitung wieder loslässt. Wenn man das vergisst, springt die CPU direkt nach dem RTI (oder dem CLI, falls man verschachtelte Interrupts nutzt) also sofort wieder in den Interrupthandler. Je nachdem, was darin passiert, gibt das dann eine Endlosschleife oder wirre Effekte.

    Folgende Schritte führen zum gewünschten Ergebnis:

    1.) Wenn das Titelbild von "Buggy Boy" kommt, den Monitor aufrufen mit ALT-M.

    2.) Im Monitor einen Breakpoint setzen auf die IRQ-Routine mit "bk exec c91", d. h. aktiviere den Breakpoint, wenn von der Adresse c91 der Prozessor einen Befehl lädt.

    3.) Daraufhin den Monitor mit "x" verlassen und das Spiel weiter fortfahren lassen.

    4.) Nach reichlich Geflimmer und Drücken von 'H' oder 'U' wird der Breakpoint ausgelöst, weil der Interrupt aktiviert wurde.

    5.) Mit "r" kann man sich jetzt die aktuellen Registerwerte ausgeben lassen. Dabei sieht man, daß der Stapelzeiger auf $fa steht.

    6.) Mit "m 1fa" läßt sich der Inhalt des Speichers an dieser Stelle ausgeben.

    7.) Es erscheint "5a a1 d5 08". Die ersten beiden Werte sind irrelevant. Wichtig ist die Rücksprungadresse für den Interrupt: $08d5.

    8.) Mit "d 8d5" oder besser etwas früher "d 8d2" kann man sich das Programm dort angucken:

    .C:08d2 20 03 09 JSR $0903

    .C:08d5 20 B4 0A JSR $0AB4

    $903 entspricht dem Aufruf der Routine zur Initialisierung des Interrupts. $ab4 ist eine weitere Routine. Wichtig ist, daß der Interrupt ausgelöst wurde, bevor der JSR-Sprung nach $ab4 ausgeführt wurde. Schaut man sich das Ende der Routine von $903 an, steht dort bekanntlich

    .C:0930 58 CLI

    .C:0931 60 RTS

    Nach dem CLI wird der nachfolgende RTS-Befehl noch ausgeführt, d. h. der Prozessor springt an Adresse $8d5 zurück. Dann jedoch greift der Interrupt.

    Mit anderen Worten: Es ist genau so, wie Mac Bacon es beschreibt.