Hello, Guest the thread was viewed1.1k times and contains 10 replies

last post from Acorn at the

Horizontales Scrolling: Flackern wenn mehrere Zeilen scrollen

  • Hi zusammen, nun muss ich doch mal die Profis fragen...


    Nach schmählich laaanger Zeit bin ich endlich mal wieder ein C64-"Problem" angegangen. Ich wollte das Scrolling in alle Richtungen testen, C64-Grundkenntnisse, auch über den internen Aufbau, sind noch - Grafikkenntnisse leidlich - und ASM Kenntnisse nur theoretisch vorhanden. Theoretisch insofern, wie wenn man bei Schach die Regeln kennt, aber damit noch lange kein Spiel gewinnt :-)


    Genug gequatscht, hier mein Problemchen und zwei Verständnisfragen:

    Die Herangehensweise war, mit dem ACME (geiles Ding - Danke!) unter Linux den Assembler-Einstieg aus der ct RETRO von 2018 nachzuvollziehen: ct.de/3yb8

    Der Artikel mach Lust auf mehr, ist aber für komplette Einsteiger zu grob. Das Programm habe ich abgetippt (das muss) und ergänzt, das Listing zum Download funktioniert sofort (1827-88.asm). Mein Problem ist, dass das Scrolling in den oberen Zeilen flackert, nachdem ich den Scrollbereich um weitere Zeilen vergrößert habe. Ich habe schon diverse Änderungen an den Registern des VIC ausprobiert, jedoch ohne eine Verbesserung erzielen zu können... nur der Bereich des Flackerns verschiebt sich natürlich wenn ich die Rasterzeilen für die IRQs verändere. Es kann doch nicht sein, dass das ein Zeitproblem ist, das PGM macht doch noch gar nichts :-)) Habe ich vielleicht einen Parameter vergessen anzupassen?


    Und ein kleines Verständnisproblem:

    Code
    1.   ldx #<irq1
    2.   ldy #>irq1

    Woher kommt der Wert irq1? Ist das eine Konstante, die ACME selbst vorbelegt? Ich finde keine Zuweisung.


    Und irritierend ist für mich Zeile 187:

    Code
    1. init_irq:
    2. ...
    3. lda $dc0d ; abschalten
    4. ...

    ist das an der Stelle nicht überflüssig..? Der Accu hat ja schon den Wert aus DC0D und wird danach sowieso mit 1 überschrieben.

    Auskommentiert ändert sich auch nichts...


    Die Dateien dazu:

  • Lesen von Register hat auch nebenwirkungen. Z.B. lesen von $dc0d bestätigt auch den IRQ damit diese nicht mehr auftritt.

    Also das ist nicht optional, weil es theoretisch ein CIA IRQ generiert sein könnte zwischen SEI und das abschalten von CIA IRQ. Wenn man dan vergisst $dc0d zu lesen wird das programm hängen bleiben in irq1.

  • irq1 ist ein Label, das 20 Zeilen weiter unten definiert wird. Und das Programm schiebt ja immerhin den ganzen Bildschirmspeicher herum (in update_screen), das muss es in einer 50tel Sekunde tun, was durchaus knapp werden kann.

  • Was Claus sagt. Das Kopieren dauert zu lange, und weil du das im Interrupt selber machst, springt der obere nicht an, und setzt das Scroll-Offset nicht.


    Murksaround:

    Du kannst das update_screen aufteilen, und die Scrollposition zwischen den beiden Kopier-Hälften setzen:


  • Vielen Dank. Sieht schon viel besser aus!

    Ich habe schon fast befürchtet, dass es die Datenschaufelei ist. Deswegen hat die c't nur so wenige Zeilen scrollen lassen....

    Bei meinem letzten Projekt bin ich aus Geschwindigkeitsgründen von Python auf C++ umgestiegen - aber was mache ich, wenn selbst Assembler nicht mehr ausreicht?


    Vielleicht mal an meiner Programmierlogik arbeiten... ;(

    Quote

    und weil du das im Interrupt selber machst...

    Gebt mir doch mal einen Tritt in die richtige Richtung - wo muss ich hinarbeiten, Bildschirmspeicher verschieben oder Gibt es da eine Routine im ROM? Ich muss noch mal in mich und vor allem in die Doku abtauchen, ich bin bestimmt nicht der erste mit dem Problem - aber Danke erstmal! Ihr habt mir sehr geholfen! :thumbsup:

  • Du könntest die Hauptschleife mit dem Kopieren in „normalem“ Code laufen lassen und den Interrupt nur für das Umschalten der Register verwenden. Dann würde das auch mit der einen Schleife da klappen.


    Da du von oben nach unten schiebst, bist du immer „vor“ dem Rasterstrahl.

  • Gebt mir doch mal einen Tritt in die richtige Richtung - wo muss ich hinarbeiten, Bildschirmspeicher verschieben oder Gibt es da eine Routine im ROM?

    Das ROM hat zwar was zum Kopieren, ist aber zu langsam. Nach dem Schema des Originals und wie Du es versucht hast, so ist es das Einfachste, Übersichtlichste und Verständlichste: Einfach alles im passenden IRQ machen. In irgendeiner Form selber kopieren ist korrekt.

    Mit den $d020 dabei wird hoffentlich sichtbarer, warum das Original klappt und Deine Version erstmal nicht funktionierte: IRQ2 ist mit Kopieren beschäftigt, Rasterzeile für IRQ1 wird erreicht,.. Aber IRQ1 kann nicht loslaufen, bevor IRQ2 nicht fertig ist. Vermute ich mal, ich hab nur den Quelltext gelesen.


    Endurion hat offenbar schon genauer hingeguckt und den simplen Workaround gefunden, mitten im Kopieren an ungefähr passender Stelle das Soft-Scrolling einzufügen.


    Und wenn Du noch mehr Zeit fürs Kopieren brauchst: Deine Hauptschleife ist das jmp * ganz am Anfang. Da könnte man stattdessen auch ein Kennzeichen prüfen, das der IRQ setzt, und das Hardscrollen in die Hauptschleife verschieben. Dann hättest Du reichlich Zeit, einen verdeckten Schirm vorzubereiten, ohne die IRQs zu blockieren.

  • Sobald die update_screen Routine einen Hardscroll ausführt, wird der erste Interrupt zu spät ausgeführt, so weit, so gut. Das Problem kann man sehr einfach lösen, man gibt den Interrupt einfach durch CLI bei u1: wieder frei. So kann der erste Interrupt rechtzeitig ausgeführt werden und springt nach beenden zurück zum Kopieren.