Beiträge von Hoogo im Thema „Unterbrechungsroutinen C64“

    @Sauhund: Erinnere Dich mal ans Konzept für die Newspress:
    Wenn ein Block des Textes im Speicher ist, sollte mit der Textausgabe angefangen werden. Bei sowas macht es einen großen Unterschied, ob man die Ladepausen zwischen den Sektoren mit Textausgabe verbringen kann oder nicht.

    Mir fehlt da zwar inzwischen ein bisschen das Gefühl für die Rechenzeit, ich schätze mal, daß die Textausgabe einer Seite so fertig wäre, bevor 20 Sektoren geladen sind.

    Und ähnliche Konzepte könnte man sich auch für Scroller in Spielen denken.

    Also ich finde es jetzt nicht soo exotisch, auch mal Dinge zu tun, die länger als 1 Frame brauchen. Entpacken, nachladen wie Peiselulli sagt, oder Hardscrollen, Level generieren, Grafiken malen... Was halt mehr nach Anwendung oder Spiel und weniger nach Demo mit Rastereffekten riecht.
    Und ich mag es auch sehr, Musik im CIA-IRQ laufen zu lassen und noch am Tempo zu tweaken.

    C. Kann man es einrichten, daß bei ausgeschalteten Kernal unterschiedliche Sprungadressen angesprungen werden, je nachdem, ob VIC oder CIA der Interrupt auslöst?

    1) Der Prozessor hat 1 IRQ-Leitung. Mehr also die Information "IRQ liegt an" bekommt man nicht über diese eine Leitung!
    2) Interrupt passiert, wenn diese Leitung von irgendeinem Chip oder sonswie von der Hardware gesetzt und das I-Flag von der Software nicht gesetzt ist.
    3) Bei IRQ werden eine Rücksprungadresse und das Flag-Register auf den Stapel gelegt, das I-Flag wird gesetzt und indirekt über den Vektor $fffe gesprungen.
    4) Das Programm regelt alles weitere. Da wäre das Erkennen der IRQ-Quelle, dem Chip seinen IRQ bestätigen, und halt das eigentliche Programm.
    5) Ob Kernal ein oder aus ist, ob I/O ein oder aus ist - ganz egal, der beschriebene Ablauf ist der Gleiche. Man darf an $01 herumspielen, wenn an 4) beachtet, man darf am I-Flag herumspielen, wenn man 2) und 4) beachtet.

    Alles weitere sind logische Konsequenzen daraus.

    Und meist reicht es auch, gar nicht so extrem tief einzusteigen, sondern einfach das Kernal eingeschaltet zu lassen, es erledigt dann das Retten der Register und sowas. Dazu den Vektor $0314 verwenden und am Ende nach $ea31 (normaler IRQ mit allem Tastaturabgefrage usw.), $ea81 (nur Register wiederherstellen) oder $ea7e (CIA confirmen) zu springen.

    Lass Dich NICHT von MS-DOS und 8086 in die Irre führen! Wenn man dort von Interrupt und Interrupt-Tabelle gesprochen hat, dann meinte man tatsächlich das Äquivalent zum BRK-Befehl und eine Sprungtabelle voller Vektoren zum Kernal-Aufruf. Diese Begriffe waren imho extrem ungeschickt und haben beim C64 nichts verloren.

    CIA ist ziemlich unabhängig vom VIC. Aber: Der Systemtakt, der die CIA versorgt, ist mit dem Pixeltakt verbunden, den der VIC zur Bilddarstellung braucht. Und dieser Pixeltakt hängt wieder von der Fernsehnorm ab. Die NTSCs haben glaub ich 1,02 MHz, der Pal-C64 0,9825 MHz. Und entsprechend schnell zählen auch die Timer der CIA.

    Und von NTSC mal ganz abgesehen: Die Rasterzeile ist ja variabel, wenn man die mittendrin noch umprogrammiert kriegt man auch 5000 Rasterirqs je Sekunde hin. Auslöser für den IRQ ist ja, das eine eingestellte, beliebig wählbare Rasterzeile erreicht wurde, und nicht eine bestimmte wie z.B. der Anfang des Bildschirms.

    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.

    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.

    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.

    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.