Hallo Besucher, der Thread wurde 2,1k mal aufgerufen und enthält 11 Antworten

letzter Beitrag von mrsid am

Verstehe nicht warum Rasterzeilen-Interrupt Beispiel nur auf NTSC 64er funktioniert

  • Hallo,


    ich lerne gerade Assembler am C64 und verstehe nicht warum ein Rasterzeilen-Interrupt Beispielprogramm aus dem Buch Compute's Machine Language Routines for the Commodore 64/128 in VICE nur im NTSC-Modus funktioniert. Im PAL-Modus und an meinem echten PAL 64er bekomme ich nur einen schwarzen Bildschirm zu sehen.


    Der Code ist hier zu finden, und im Anhang ist ein D64-Image mit dem Programm. Wenn mir jemand erklären könnte was an dem Code für PAL geändert werden muss wäre ich sehr dankbar.


    Gruß,

    Ralph

  • Der verlinkte Code ist ... suboptimal. Eine vollständige Initialisierung des Interrupts findet nicht statt. Ein NTSC-C64 zeigt weniger Linien an pro Bild als ein PAL-C64. Aus diesem Grund kommt es vor, daß das Highbit (Bit 8 ) des Rasterzählers beim PAL-C64 länger auf 1 gesetzt wird als beim NTSC-C64. Dieses 9. Bit des Rasterzählers findet sich in Bit 7 von Register $d011, und es wird bei der Initialisierung nicht gelöscht. Außerdem merkt sich das Programm stupide den aktuellen Zustand des VIC und kopiert diesen später gnadenlos komplett zurück. Ist zufällig das Bit 7 in Register $d011 gesetzt, wird es beim späteren Zurückschreiben ebenfalls gesetzt. Damit wird die IRQ-Rasterwert auf einen unmöglichen, weil zu hohen Wert gesetzt, und der IRQ wird nie ausgelöst.

    Gegenmaßnahme:

    1.) Korrekte Initialisierung des Interrupts. Hierzu gehört wenigstens, daß man Bit 7 in $d011 löscht:

    LDA $d011

    AND #$7f

    STA $d011

    2.) Nach dem Auslesen der Registerwerte in beiden VIC-Kopien das Register ebenfalls löschen.

    LDA newvic + $11

    AND #$7f

    STA newvic + $11

    STA newvic + 47 + $11

    Schau mal, ob es so funktioniert. Das Programmprinzip sollte eigentlich auch auf einem PAL-C64 laufen, jedoch scheint mir der Code einfach buggy zu sein.

  • Danke für die ausführliche Erklärung, wenigstens glaube ich jetzt die Ursachen des Problems etwas besser zu verstehen.

    Mit diesen Änderungen funktioniert das Programm im NTSC-Modus zwar immer noch, aber leider bekomme ich im PAL-Modus weiterhin nur einen schwarzen Bildschirm zu sehen :(. Ich habe den verlinkten Code mit deinen Änderungen upgedatet - schau doch bitte mal ob ich es evtl. an der falschen Stelle angepasst habe.

  • die Codebase64 ist eine gute Quelle von div. Codeschnipseln und Tutorials.


    u.a. gibt es da den einfachen Source für Rasterbars vom Graham/Oxyron, der simple aber funktionell und gut ist. Funzt aufgrund des Timings aber nur auf PAL sauber.



  • copybk lda newvic,y

    sollte das nicht eher lda newvic,x sein?

    Nein, y hat entweder den Wert 46 (falls die Rasterzeile <= 147) oder 46+47=93. Somit wird eine der beiden Bildschirmkopien zurück in die VIC-Register geschrieben. So jedenfalls mein (zugegebenermaßen unvollständiges!) Verständnis. :)


    Übrigens, ab und zu bekomme ich im PAL-Modus von VICE ab und zu "Artefakte" zu sehen anstatt eines leeren Bildschirms. Vgl. die Screenshots im PAL vs. NTSC-Modus. Vielleicht werden die VIC-Register doch irgendwie falsch gesetzt?


  • die Codebase64 ist eine gute Quelle von div. Codeschnipseln und Tutorials.


    u.a. gibt es da den einfachen Source für Rasterbars vom Graham/Oxyron, der simple aber funktionell und gut ist. Funzt aufgrund des Timings aber nur auf PAL sauber.

    Danke, ich werde mir das Rasterbars-Beispiel von Oxyron mal näher ansehen. Was müsste man denn machen um die Timings anzupassen damit es auch auf NTSC sauber funktioniert?

  • Genau sowas passierte bei dem Game Space Rogue.

    Daran kann ich mich noch gut erinnern. Habe damals[tm] das Original gekauft. An sich ein tolles Spiel (absolut lohnenswert), aber leider fiel mir auf, daß beim Vorspann manchmal Sound zu hören war und manchmal nicht. Und wenn er nicht zu hören war, funktionierte auch die Tastatur nicht. Der Zusammenhang war schnell klar: nicht ausgelöster Interrupt. Die einzige Lösung: Programm patchen.

    schau doch bitte mal ob ich es evtl. an der falschen Stelle angepasst habe.

    Ich habe das Programm noch ein wenig ergänzt:

    Um deutlich erkennbar zu machen, wo genau die Trennlinie zwischen den beiden VICs verläuft, lasse ich im Programm noch die Rahmenfarbe umsetzen. Dieser Code zusammen mit dem Basic-Testprogramm und den Sprites laufen bei mir im Emulator.

  • schau doch bitte mal ob ich es evtl. an der falschen Stelle angepasst habe.

    Ich habe das Programm noch ein wenig ergänzt:

    Super! Vielen, vielen herzlichen Dank :thumbsup:! Ich werde deinen Code sorgfältig studieren und verinnerlichen. Wer hätte gedacht dass die alten Lehrbücher von damals solch verbuggten Code beinhalten würden! Und ich hielt dieses Buch immer für die "Bibel" unter den ASM-Büchern.

  • Es fängt ja schon damt an, dass beim Initialisieren des Interrupts auf ein SEI (und später CLI) komplett verzichtet wird - selbst dies kann schon zu Fehlern führen.

    Mann muss schon wissen was man tut.

    Aber sollte das der Fall sein dann sind SEI und CLI völlig überflüssig. Die braucht man nicht zum intialisieren von Interrupts, ist nur ein gängiger Cargo Cult...