Unterbrechungsroutinen C64

Es gibt 134 Antworten in diesem Thema, welches 16.938 mal aufgerufen wurde. Der letzte Beitrag (7. April 2013 um 15:24) ist von sauhund.

  • Hallo, ich möchte endlich ´mal kapieren, wie das mit Interrupt und C64 ist?

    Bisher dachte ich immer, daß wenn der Kernal an ist, man Tastaturinterrupt und 60x Superinterruot nenn ich das mal.
    Ohne Kernal 60x Superinterrupt verwiesen drauf über letzten Gesamtspeicherzeiger.

    Aber im Nachbarinterrupt habe ich jetzt verstanden, daß die 60x nicht fest sind, bzw. es weitere Interruptd gibt?

  • Es gibt verschiedene Bausteine im C64, die Interrupts auslösen können:

    CIAs, VIC, Restore-Taste

    Der normale Kernal-IRQ wird von einem CIA-Timer erzeugt, der eben so eingestellt ist, dass er 60 mal in der Sekunde abgelaufen ist und dann einen IRQ auslöst.

    Für die meisten anderen Sachen werden aber eher VIC-IRQs benötigt. Dafür muss man erstmal sämtliche CIA-IRQs abschalten:

    Code
    LDA #$7F
        STA $DC0D    ; Alle CIA 1 IRQs abschalten
        LDA $DC0D    ; Evtl noch wartende IRQs entfernen


    Und danach wird üblicherweise der VIC so eingestellt, dass er Raster-IRQs auslöst. Der VIC kann auch andere IRQs auslösen, z.B. Lightpen-IRQs, IRQs bei Sprite-Kollisionen usw. Aber das braucht man eigentlich nie.

    Raster IRQs stellt man meist so ein:

    Code
    LDA #<Rasterzeile>
        STA $D012    ; Bits 0-7 der Rasterzeile setzen
        LDA #$1B
        STA $D011    ; Bit 8 der Rasterzeile ist in Bit 7 von $D011
    
    
        LDA #$01
        STA $D01A    ; Raster IRQs einschalten
  • Zitat

    Der normale Kernal-IRQ wird von einem CIA-Timer erzeugt, der eben so eingestellt ist, dass er 60 mal in der Sekunde abgelaufen ist und dann einen IRQ auslöst.

    Kann man dem CIA direkt sagen, daß er doppelt so oft auslöst?

  • Kurz gesagt setzt du den Timer entsprechend, dann wird bei Unterlauf ein IRQ ausgelöst, sofern das eingestellt ist. Hier eine Bitte melde dich an, um diesen Link zu sehen. zu den CIA-Registern. Dort ist auch Bitte melde dich an, um diesen Link zu sehen. verlinkt, wo das an irgendeiner Stelle evtl. genauer erläutert wird.

  • Kann man dem CIA direkt sagen, daß er doppelt so oft auslöst?

    Klar, hiermit stellt man den Timer auf 8211 anstelle des Kernal Wertes von 16422 Taktzyklen ein:

    Code
    LDA #$12
        STA $DC04
        LDA #$20
        STA $DC05
  • Das macht Sinn.

    Grund: Wenn man 1234 gleichzeitig drückt, dann erfaßt die Hardwareinterrupttastaturroutine im Emulator machmal sogar nur 1 im Buffer. Es entfallen also 234.

    Darum werden 60x die Sekunde aktuell über Matriz eine Direktabfrage, die 1234 erfaßt. (Ich möchte nicht auf Probleme mit ab drei Tasten hier eingehen.)

    Da ein ganz schnelles gleichzeitiges Drücken von 1234 also nur über den Buffer manchmal erfasst wird, entfallen Tastendrücke.

    Und Dank Euch kann ich jetzt das Ding so verändern, daß es unmöglich wird, eine Taste zu versäumen.

    Ich hab´Euch lieb. :thnks:

  • Tasten gleichzeitig drücken sorgt meistens für Probleme. Da die Tasten als Matrix abgefragt werden, können viele Tastenkombinationen nicht eindeutig abgefragt werden:

    Bitte melde dich an, um diesen Link zu sehen.

    Da hilft auch eine häufigere Tastaturabfrage nichts.

  • Interrupte dürfen natürlich auch parallel von CIA und VIC kommen. Ganz nach Lehrbuch müsste die IRQ-Routine wissen, welche Chips für IRQs im System verbaut sind (hier CIA, VIC, manchmal REU oder anderes am Export).
    Dann diese Chips pollen, je nach Chip in ienem anderen Register nachsehen und feststellen, woher denn nun der Interrupt kam.
    Und dann auch noch, je nach Chip unterschiedlich, quittieren, daß der IRQ verarbeitet wurde.

    Strang nach Lehrbuch ist die Original-Routine nicht besonders gelungen, weil das lda$dc0d am Ende der Routine gleichzeitig für das Pollen und für das Quittieren zuständig ist.

  • Interrupte dürfen natürlich auch parallel von CIA und VIC kommen.


    In der Praxis aber selten zu gebrauchen. Meistens sind die Raster-IRQs so zeitkritisch, das kein anderer IRQ möglich ist.

  • Find ich nicht.

    pha
    lda $dc0d
    bpl rasterirq
    cli
    ...

    Jetzt nur so aus dem Kopf für eine Routine mit IRQ über $fffe. Die paar Extra-Takte+Extra-Verzögerung dürften eigentlich kein Hindernis sein, um über CIA-Timer noch bis zum Ende der Rasterzeile einen stabilen Raster zu haben. Müsste man aber ausprobieren, ich hab mir immer eine Extra-Rasterzeile gegönnt.

    Es wird sicher ein paar Spezialfälle geben, in denen man die Rasterzeile Zeit nicht hat, dann schaltet man CIA besser ab. Ninjas FLI-Aufruf z.B.

  • Oder es gibt Fälle, wo der Timer-IRQ auch wirklich zu dem Zeitpunkt kommen muss, und nicht nen halben Frame später.

  • ich fands bisher immer wesentlich praktischer gleich cia2 und timer-nmi zu benutzen - in den in 25 jahren bisher vielleicht 2 oder 3 fällen wo ich das mal brauchen konnte.

  • Das meinte ich mit "selten". Eigentlich nur zum Abspielen von Samples interessant, und da kann man nennenswerte Raster-IRQ Routinen vergessen.

  • Wie, erst hieß es, CIA+VIC-IRQ sind selten gemeinsam zu gebrauchen, weil Rasterinterrupte so zeitkritisch sind?
    Dann waren Rasterinterrupte doch nicht mehr so zeitkritisch, stattdessen sind nun CIA-Interrupte von höherer Priorität...

    OK, warum nicht, wenn Rasterroutine und Bildschirm entsprechend eingerichtet sind wird das gehen. NMI ist für diesen Zweck dann aber wirklich besser.
    Aber Digi+Rastereffekte würde ich jetzt mal als seltene Ausnahme bezeichnen, und nebenbei krepieren Digis auch nicht an 40 Takten Jitter durch eingeschalteten Bildschirm, die können sich auch hinter einer kurzen Rasterroutine anstellen.

    Normale Fälle für Interrupte aus 2 Quellen sind Basic-Direktmodus+Rastereffekte, oder die Möglichkeit, Musik in beliebiger Geschwindigkeit abzuspielen.

  • Nur sind viele Rasterroutinen nicht "kurz" und wenn man Timer-NMIs benutzt, müssen sich die Rasterroutinen hinten anstellen und nicht die Timer-NMIs.

  • Zitat

    Klar, hiermit stellt man den Timer auf 8211 anstelle des Kernal Wertes von 16422 Taktzyklen ein:


    Quellcode
    LDA #$12
    STA $DC04
    LDA #$20
    STA $DC05

    Was passiert, wenn ich den A-Timer auf 0 stelle, bzw. so klein, daß schon die nächste Unterbrechung kommen müßte, obwohl die eine Unterbrechung noch läuft?
    Wofür ist der B-Timer? :anonym

    Edit: Oh, oh: Ich sehe gerade, es gibt noch einen zweiten CIA2 Chip? Gleichzeitig?

  • Aus Sicht der CPU:
    IRQ-Leitung ist gesetzt, weil irgendein Chip an dem Bus einen IRQ meldet.
    I-Flag wird gesetzt, weitere IRQs sind unterdrückt
    IRQ-Routine läuft an
    Irgendwo darin wird der CIA-IRQ durch Auslesen des $Dc0d-Registers quittiert
    Am Ende der IRQ-Routine steht ein RTI, das I-Flag wird wieder gelöscht.
    ...und sofort fängt diese Schleife wieder von vorne an.

    Aus Sicht der CIA:
    IRQ wird gemeldet
    Irgendwann wird der IRQ durch Auslesen des $Dc0d-Registers quittiert
    Nächster Timer-Unterlauf steht direkt wieder vor der Tür
    ...Schleife fängt wieder von vorne an

    Timer B kann das Gleiche wie Timer A, dazu kann er noch ein paar andere Dinge zählen. Auch Timer A muß nicht unbedingt Taktzyklen zählen, aber ich habe keine Ahnung, was man mit der Alternative so anfangen kann.

    Die 2 CIA ist technisch das Gleiche wie die erste, klemmt aber an der NMI-Leitung statt der IRQ-Leitung und programmiert sich aus Prozessorsicht daher anders. Und die anderen Anschlüsse sind natürlich auch mit was anderem verbunden.

  • Äh, Vernunfti!

    Wenn du das mit dem Emu testest, denkst du auch daran, daß PC-Tastaturen auch schon das Problem haben? Es gibt kaum Tastaturen, wo man beliebige Tastenkombinationen drücken kann und alle Tastendrücke ankommen. Evtl. liegt es gar nicht am C64-Code.

    C64Studio: Bitte melde dich an, um diesen Link zu sehen. - Bitte melde dich an, um diesen Link zu sehen. --- C64Studio WIP: Bitte melde dich an, um diesen Link zu sehen. - Bitte melde dich an, um diesen Link zu sehen. --- Bitte melde dich an, um diesen Link zu sehen.

  • Problem mit der Multicolorfarbe 01 =>

    Ich möchte erstmal die Sternchensache professionell hinbekommen.

    Dazu habe ich ein paar Fragen:
    1. Kann man die Rasterzeile beim VIC2 anhalten?
    2. Wie verhalten sich die Interrupts, wenn ich einen habe, der 60x die Sekunde aufgerufen wird, und einen, der immer dann aufgerufen wird, wenn der VIC2 gerade den ohne Tricks sichtbaren Bereich durch hat?
    3. Was passiert, wenn ein neuer IRQ dran müßte, aber ein anderer noch arbeitet?