Beiträge von WebFritzi im Thema „Mal wieder Raster-Interrupt“

    Mann, berni, du bist echt ne große Hilfe. Vielen Dank! Das Schema ist super. So versteht man gut, was abgeht. Mir scheint, durch Abschalten des Kernals könnte man nochmal ca. 15 Zyklen sparen. Aber ich hab's jetzt so gemacht, wie du vorgeschlagen hast: ne eigene Routine für die 226. Die sieht jetzt so aus:

    Das Ändern der Hintergrundfarbe ist eh unkritisch, da in 227 sowieso nur ein weißer Streifen erscheinen soll. Daher hab ich das ans Ende gesetzt. Es flickert noch manchmal ganz rechts, wenn ich einen Eintrag im Startmenu highlighte. Da ist er nicht schnell genug mit dem Zeichensatz und flackert, weil ich die 6 Zeichen aus dem anderen Zeichensatz wieder gelöscht habe.

    Ich verstehe aber noch nicht ganz, was das tax bringen soll. Warum nicht gleich sta $d016? Geht doch schneller. EDIT: Ich glaube, ich verstehe. So hat man mehr Kontrolle darüber, wann die echten Änderungen kommen. Die stx/sta's sollten genau zwischen den Zeitpunkten kommen, wo der Rasterstrahl das Innere von 226 verlässt und in das Innere von 227 eintritt. Wenn ich es richtig verstehe, wird das Badline-Verhalten so umgangen, weil ich schneller bin und das Fetchen erst nach den stx/sta's passiert.

    Ich mach's jetzt noch mit festen Werten für $d016 und $d018. Dann sollte es klappen. Melde mich wieder mit nem Edit.

    Edit: Puh, jetzt klappt es. Auch mit allen möglichen Sprites. Das ganze ist unheimlich zeitkritisch. Da kommt es auf jeden Zykel an. So sieht der Anfang er Routine jetzt aus:

    Wenn ich ne Zeropage-Adresse statt "byte" verwende, bin ich zu früh. Dann flackert er am Ende von 226 bereits.

    Ich habe hierbei eine Menge gelernt und danke dir nochmal dafür!

    Ich hab's mal ausprobiert, bei mir läuft es stabil (und ich verstehe den Code nicht ganz, heute Abend habe ich dafür mehr Zeit, dann schaue ich es mir nochmal genauer an). Ein paar Annahmen musste ich aber treffen: `std_irq` hatte ich durch $ea81 ersetzt und alle nicht vorhandenen Unterroutinen einfach als `RTS`.

    Ja, entschuldige. std_irq = ea31. Könnte ich auch ändern. Der Code macht folgendes: Er checkt zuerst, ob die Zeile kleiner als 226 ist. Wenn nicht, führt er den Code für 226 aus. Das mache ich, weil 226 zeitkritisch ist, die anderen nicht und weil nach 226 kein IRQ mehr kommt. Dann checkt er nacheinander $d012 nach den anderen Zeilen, an denen Benachrichtigungen stattfinden. Es ist aufgrund der Schachtelung etwas verwirrend - auch für mich immer wieder.

    Ich denke, deine Probleme kommen von den Sprites (die sind bei mir ja nicht da): Sprites machen ja auch so Mini-Badlines - da fallen dann pro Rasterzeile 5 bis 11 Zyklen aus, und zwar ausgerechnet in dem Bereich, in dem man gerne die Änderungen vornehmen würde (also im Rahmen links und rechts).

    Aha, das war mir nicht ganz klar. Kurz zur Erklärung: Ich schreibe eine GUI mit Taskleiste und die letzten drei Char-Zeilen sollen grau werden. Ich habe zwei Zustände: entweder ist das Startmenu geöffnet oder nicht. Darin wird ein Sprite-Balken für das Highlighting der Einträge benutzt. Aber wenn das Startmenu geschlossen ist oder nichts gehighlighted wird, gibt es nur zwei Sprites im Startbutton, die erst am Ende meines 226-Handlers definiert werden (DrawSpritesDown/DrawSpritesUp). Die können es also nicht sein. Viel weiter oben in 40 und 80 gibt es noch zwei Sprites, aber das war's dann auch. Die meisten Probleme habe ich natürlich, wenn der Mauszeiger (auch zwei Sprites) sich auf der Zeile befindet und/oder das Startmenu offen ist und ich einen Eintrag highlighte. Aber selbst mit dem Mauszeiger weit weg und geschlossenem Startmenu gab es Probleme.

    Ich habe das gestern Nacht noch mit einem reudigen Hack stabil bekommen. Der Hauptteil besteht darin, gewisse Chars im vorigen Zeichensatz so zu gestalten, dass ihre erste Zeile genauso aussieht wie die der entsprechenden Zeichen im neuen Satz. So macht es keinen Unterschied, ob der VIC es schon geschafft hat, den Zeichensatz zu wechseln oder nicht. Ist natürlich nicht ganz befriedigend, zumal ich damit insgesamt 6 Zeichen im vorigen Zeichensatz verschwende. Aber es läuft. Zusätzlich habe ich noch den Wert, der in $d016 geschrieben werden soll, im Handler für Zeile 0 in die Zeropage bei $06 geschrieben, so dass ich nur lda $06 / sta $d016 schreiben muss.

    Witzig nebenbei: wenn ich eine normale statt ner Zeropage-Speicherstelle verwende, habe ich noch Flicker, wenn gehighlighted wird. Da geht es also um einen einzigen Zykel, damit es stabil läuft.

    Deinen Tipp mit x, y und a habe ich aber nicht ganz verstanden. Das kostet doch genauso Zeit. Oder soll ich das in 225 machen, warten bis 226 kommt und dann ganz schnell die 3 Schreibzugriffe machen? Hört sich sinnvoll an. EDIT: Es hat sich aber herausgestellt, dass die eigentlliche Zeile, in der die Änderungen stattfinden sollen, die Badline 227 ist (s.u.). Das heißt, ich müsste eigentlich auf die 227 warten. EDIT: Aber das funktioniert auch nicht. Selbst wenn ich auf 226 warte nicht. Sehr merkwürdig.

    Danke für deine Zeit!

    Welche Rasterzeile Badline ist, hängt auch davon ab, wie der Schirm gescrollt ist. Badline ist, wo die Bits des Scrollregisters mit den Bits der Rasterzeile übereinstimmen.

    Ich benutze gar kein Scrolling. Ist also immer gleich.

    Frage: Müssen die beiden Bereiche nahtlos sein, oder wäre auch 1 leere Zeile zwischen den Chars OK? Dann könntest Du einen FLD einbauen.

    Ja, sollte nahtlos sein. Obwohl: die obere Rasterzeile der drittletzten Zeichenzeile sollte immer ein weißer Strich sein. Die kann also "leer" sein mit Hintergrundfarbe weiß. Was ein FLD ist, weiß ich nicht.

    Dann ist 226 die letzte Zeile des Chars davor

    Oh! Ich hätte gedacht, die 226 wäre die erste Zeile des drittletzten Chars von unten. Du hast aber recht. Ich habe meinen Code mal in inc $d020 / dec $d020 eingerahmt, und tatsächlich wird die Rahmenfarbe gaaanz am Ende der Zeile davor erhöht. Aber warum denn erst dort? Das sind dann ca. 55-60 Zykel, die in der Zeile 226 verbraucht werden, bis er endlich mal in meinen Code springt. Wieso das? Bin verwirrt.

    Danke auch für deine Zeit.

    Ich persönlich würde es so machen:

    Code
                    ...
                    lda #226 ;bei Bedarf 225 nehmen
    -
                    cmp $d012
                    bne -

    Verstehe ich jetzt nicht. Wieso sollte ich auf 226 warten? Ich bin doch im IRQ. Habe übrigens schon versucht, mich in 225 benachrichtigen zu lassen und dann

    Code
    -    lda $d012
         cmp #226
         bcc -

    Darin hat er sich allerdings aufgehängt. Keine Ahnung, warum. Du hast es andersherum gemacht. Hat das einen Grund?

    Das Problem liegt vermutlich nicht in dem geposteten Teilstück des Codes. Die Frage ist, wie du den IRQ auslösen lässt und ob andere IRQ-Auslöser noch aktiv sind. Zudem auch, was du sonst so noch (nach dem BCC-Sprung ans Ende des Listings) machst. Wenn du da mehr Details posten könntest, kann ich dir gerne weiterhelfen. So dürfte es nur stochern im Nebel sein.

    Ich kann dir gerne die gesamte Routine zeigen. Die anderen Handler (bei 150, 80, 40 und 0) sind allerdings eher zeitunkritisch. Deshalb wüsste ich nicht, wo da das Problem liegen soll, wenn nicht genau beim Handler von Zeile 226. Die Routine davor (bei 150) läuft im Extremfall über ca. 10 Rasterzeilen.

    IRQ-Auslöser:

    Aber bis zum Zeichensatz ändern kommt er in der Zeile gar nicht erst.

    Nochmal zu Verständnis: Schaltet er gar nicht um, oder nur nicht in Zeile 226 sondern erst in Zeile 227? Und was passiert alles bei L_ELSE...wenns doof läuft, weil da zu viel Rasterzeit verbraucht wird, triffst du nie rechtzeitig 226.

    Er schaltet alles wie gewünscht um. Nur zu spät. Danacha kommt nichts mehr. L_ELSE bezieht sich auf Zeilen weit darüber.

    Sehe ich es richtig, dass Zeile 226 diejenige ist, wo die dritte Zeile von unten beginnt?

    An welcher Adresse liegt der Zeichensatz denn?

    $4000 der eine, $4800 der andere. Den bei $4800 aktiviere ich im IRQ bei Zeile 226. Der andere wird bei Zeile 0 wieder aktiviert. Das klappt ja auch alles, nur eben nicht schnell genug. Erst eine Zeile später ist alles, wie es soll.

    Langt es denn, hier einfach nur Bits zu setzen? Muss nicht ggf. erst mit AND #%11110001 Bit 1-3 gelöscht werden...je nachdem was im Rest des Codes so passiert.

    Jepp. Das habe ich bei mir auskommentiert, damit er schneller geht. Bringt aber auch nix.

    Ich würde gerne ab Zeile 226 folgende drei Dinge ändern:

    1. Hintergrundfarbe grau
    2. Multicolor
    3. Anderer Zeichensatz

    Genau in der Reihenfolge habe ich das auch implementiert. Aber bis zum Zeichensatz ändern kommt er in der Zeile gar nicht erst. Er benutzt den alten Zeichensatz. Und selbst Multicolor wird nicht aktiviert, wenn ich mit dem Mauszeiger (Sprites 0 und 1) über der Zeile hänge. Ist das eine Badline? Ist es möglich, das trotzdem hinzukriegen? Hier mein Code: