Mal wieder Raster-Interrupt

Es gibt 25 Antworten in diesem Thema, welches 2.575 mal aufgerufen wurde. Der letzte Beitrag (4. Mai 2024 um 19:55) ist von goloMAK.

  • 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:

    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.Bitte melde dich an, um diesen Link zu sehen.
  • Das mit dem "anderen Zeichensatz" verstehe ich nicht. Im Bitmap-Modus kannst du via $d018 lediglich mit Bit 3 umschalten, ob die Bitmap bei $0000 oder $2000 in der jeweiligen Bank liegen soll und mit Bit 4-7 das ScreenRAM. Schau z.B. hier mal: Bitte melde dich an, um diesen Link zu sehen.

  • Aber ich bin im Zeichenmodus - nicht im Bitmap-Modus. Und da sagen Bits 1-3, wo der in der Bank liegt. Oder irre ich mich? Ich befinde mich in der VIC-Bank 1 (also bei $4000).

    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.Bitte melde dich an, um diesen Link zu sehen.
  • lda $d018
    ora #TASKCHARSHI
    sta $d018

    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.

  • 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.

    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.Bitte melde dich an, um diesen Link zu sehen.
  • 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.

  • Ist das eine Badline?

    Ja.

    So ein Mist! Ich hab mal probiert: selbst wenn ich die 227 nehme, flackert es. Erst bei 228 wird er stabil. Aber egal, es muss ab 226 sein, sonst sieht's doof aus.

    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.Bitte melde dich an, um diesen Link zu sehen.
  • 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?

    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.Bitte melde dich an, um diesen Link zu sehen.
  • 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 persönlich würde es so machen:

    Allerdings würde dann L_ELSE nicht angesprungen. Aber ich denke, es ist ungünstig in andere Routinen zu springen, wenn man etwas recht genau timen will.

  • Ist das eine Badline?

    Nein. 227 ist eine.

    Aha! Deshalb Beitrag Bitte melde dich an, um diesen Link zu sehen..

    Ich hab's auch schon versucht mit 225 und vielen NOPs, aber das wird instabil, wenn ich mit dem Mauszeiger auf der Linie rumtanze.

    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.Bitte melde dich an, um diesen Link zu sehen.
  • 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:

    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.Bitte melde dich an, um diesen Link zu sehen.

    2 Mal editiert, zuletzt von WebFritzi (4. Mai 2024 um 06:33)

  • Ohne Code-Kontext keine Hilfe, geht nicht.

    Was aber sehr komisch ist: Du sagst Du hättest einen IRQ (welche Quelle?) und in diesem prüfst Du $d012 auf #226 und verzweigst bei kleiner nach L_ELSE was macht es das? Also entweder hast Du einen Raster IRQ, der bei #225 oder #226 auslöst und Du wartest ein wenig um Deine Dinge zu machen oder halt den Rest vom Code.

  • 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.

    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`.

    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).

    Ein paar Dinge, die du ausprobieren kannst:

    1. Die Werte, die du in die Register schreibst, vorher schon berechnen:

    ldy #CL_LIGHTGRAY
    lda $d016
    ora #%00010000
    tax
    lda $d018
    ora #TASKCHARSHI
    sty BKGCOLOR
    stx $d016
    sta $d018

    Dann sind die drei Schreibbefehle direkt hintereinander und die Änderungen passieren innerhalb von 9 Taktzyklen. Weniger geht nicht. (Du kannst allerdings möglicherweise noch die Reihenfolge der ST-Befehle ändern.

    2. Die einzelnen Register der VIC haben eine unterschiedliche Latenz, bis die Änderung wirksam wird.) lda $d012
    cmp #225
    bcc L_ELSE
    lda #226
    - cmp $d012
    bne -

    Damit hast du ein besseres Timing - maximal 7 Taktzyklen Unterschied pro Durchlauf (wobei da die Sprites noch reinspielen, dann kann es noch deutlich mehr werden).

    3. Den Rasterstrahl exakt mit dem Prozessor synchronisieren (siehe Bitte melde dich an, um diesen Link zu sehen.).Mit Sprites ist das allerdings sehr schwierig.

  • 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.

    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.

    Ich nehme jetzt mal an, dass die 227 die Badline ist. Dann ist 226 die letzte Zeile des Chars davor, dort soll dann der Rastercode laufen. Dort scrollst Du dann 1 Pixel nach unten. Dadurch wird 228 die Badline. Und die 227 bleibt leer, genug Rasterzeit, um alle Einstellungen trotz Sprites zu machen.

    Irgendwann musst Du aber auch wieder zurückscrollen. Da Du eh eine Zeile 0 hast, kannst Du das da machen.

  • 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.

    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.Bitte melde dich an, um diesen Link zu sehen.

    2 Mal editiert, zuletzt von WebFritzi (4. Mai 2024 um 15:19)