Stabile Rasterbars und Badlines - wieso funktioniert mein Code?

Es gibt 29 Antworten in diesem Thema, welches 5.341 mal aufgerufen wurde. Der letzte Beitrag (18. Dezember 2013 um 21:29) ist von flashback.

  • Hallo zusammen,

    mit Hilfe der Seite retro-programming.de habe ich endlich einen stabilen Raster-IRQ hinbekommen und tatsächlich einige schöne Bars auf den Bildschirm gebracht. Soweit so gut, aber wie kann der Code funktionieren? Ich habe alle Taktzyklen mitgezählt und komme in der Schleife, die für Badlines zuständig ist, nur auf 19 Taktzyklen. Trotzdem sind die Bars gerade? Hier mal der Code-Teil, man "startet" in der stabilen Rasterzeile mit 3 verbrauchten Taktzyklen:


    Abgesehen davon, daß die Schleife für eine normale Rasterzeile auch zu lang ist, sehen die Bars korrekt aus, alle gleich lang und die Umschaltstellen alle direkt untereinander. Liegt es irgendwie daran, daß der Sprung in der Schleife quasi über 2 Rasterzeilen geht?

    Ist ja schön und gut, wenn man mehr oder weniger durch ausprobieren was hinbekommen hat, aber man will ja auch wissen, WARUM! ;)

  • a) bitte ein startbares .prg anhängen, oft verrät einem schon ein kurzer blick auf das angezeigte was das problem sein wird :)
    b) wenn du dir bei sowas unsicher bist, lass dein programm im x64sc laufen. hier stellst du in den VIC optionen den border auf "debug". ausserdem das C64 modell auf "C64C". ersteres führt dazu das du den gesamten rahmenbereich angezeigt bekommst, inklusive overscan und dem normalerweise unsichtbaren bereich. letzteres dazu das bei jedem beschreiben eines farbregisters ein grauer punkt zu sehen ist. beides zusammen macht es recht einfach optisch zu kontrollieren ob das timing einer rasterroutine korrekt ist - irgendwo im normalerweise unsichtbaren bereich solltest du die stelle(n) sehen wo die farbe umgeschaltet wird, idealerweise liegen die alle unternander im gleichen cycle :)
    c) wenn ich cycles vermisse checke ich zuerst ob nicht ein branch oder indizierter zugriff irgendwo unvorhergesehenerweise eine pagegrenze überschreitet

    Zitat

    Ist ja schön und gut, wenn man mehr oder weniger durch ausprobieren was hinbekommen hat, aber man will ja auch wissen, WARUM!


    zum cycles zusammenzählen bin ich mitlerweile auch zu faul, bevor nicht b) und c) erledigt sind :=)

  • Vor allem würde ich nicht zu früh anfangen mit dem 100% perfekt anpassen

    Spätestens, wenn Du es auf NTSC anpassen willst, musst Du eh nochmal zählen ^^

  • Vielen Dank erstmal für die Tips, habe bisher zwar auch mit WinVice im Debug-Modus getestet, aber nur über die x64.exe. Habe jetzt mal das ganze Programm angehängt, es ist noch eine Menge mehr drin, aber die Rasterbars sehen meiner Meinung nach wirklich korrekt aus, die Schreibzugriffe untereinander ergeben eine graue Linie. Und bevor jemand meckert, die Farben für die Bars sind erstmal nur zum Testen.
    ;)

  • Sieht schon ganz gut aus! (damit meine ich die Stabilität, nicht die hübschen Coder Farben) ;)

    x64.exe


    Warum?

    Wobei man auch ohne X64sc erkennt, dass der allerletzte Split nicht ganz sauber ist. Im Border nicht schlimm, im Screen sollte man diese grünen Pixel noch wegkriegen.

  • Zur c64.exe: Keine Ahnung, ich kenne einfach den genauen Unterschied zwischen den Verschiedenen Versionen da gar nicht. Habe zwar gesehen, daß es im Programmverzeichnis verschiedene exe-Dateien gibt, aber mir keine Gedanken darüber gemacht. Also sollte man, um auf Nummer sicher zu gehen, am besten die x64sc benutzen?

    Der letzte grüne Balken ist im Moment noch länger, da vor dem Zurücksetzen auf die Original-Bildschirmfarben noch $d016 zurückgesetzt wird. Aber das kann ich sicher auch tauschen.

    Tja... aber wieso sehen die Bars denn nun sauber aus, wenn doch die Zyklen eigentlich falsch sind? :böse

  • deine zyklenberechnung ist an mehreren stellen falsch.
    dein beq charloop springt ja 2 zyklen weiter zurück

    deine badlines verbrauchen 21 zyklen.
    das ist ok, wenn der eine überzählige ein schreibzugriff ist der gerade am beginn der badline-sperre erfolgt(also z.b. ein sta)
    in deinem fall ist das der sta $d021.
    wenn du den durch ein lda $d021 ersetzt (der ja auch 4 zyklen braucht) verschiebt sich der sta $d020 alle 8 zeilen um einen zyklus - bis eben der sta $d020 den einen überzähligen zyklus benutzt.

  • ok, das timing ist offensichtlich korrekt. und du hast dich beim cycles zählen vertan, die äussere schleife sind durchaus 63 cycles =)

  • deine zyklenberechnung ist an mehreren stellen falsch.
    dein beq charloop springt ja 2 zyklen weiter zurück

    Hmm, und wieso? Ein beq verbraucht doch beim Sprung nur 3 TZ, wenn man innerhalb derselben Page bleibt? Dann müßten es ja 5 TZ sein, oder bin ich da jetzt komplett auf dem falschen Dampfer?

    deine badlines verbrauchen 21 zyklen.
    das ist ok, wenn der eine überzählige ein schreibzugriff ist der gerade am beginn der badline-sperre erfolgt(also z.b. ein sta)
    in deinem fall ist das der sta $d021.
    wenn du den durch ein lda $d021 ersetzt (der ja auch 4 zyklen braucht) verschiebt sich der sta $d020 alle 8 zeilen um einen zyklus - bis eben der sta $d020 den einen überzähligen zyklus benutzt.

    Ok, das habe ich soweit verstanden, Schreibzugriffe werden noch ausgeführt, daher also 20-23 TZ. Jetzt muß ich nur noch kapieren, wo die beiden TZ denn herkommen bei dem beq, habe momentan ein Brett vor'm Kopp...
    :thumbdown:

  • Code
    charloop:
    ldx #$08                         // 	2 	2
    
    
    lda rasters1cols,y     	 	// 	4 	6
    sta $d020			// 	4 	10
    sta $d021			// 	4 	14
    iny				// 	2	16
    dex				// 	2	18
    beq charloop		 	// 	3	21 ; bei Badline
  • Hmm, eigentlich sollte das "ldx #$08" als letzter Befehl in der Rasterzeile vorher ausgeführt werden, so daß man mit dem "lda rasters1cols,y" in der nächsten Rasterzeile startet. Oder habe ich mich da auch schon verzählt?

  • beachte die 2 unterschiedlichen sprungmarken:

    charloop und collloop

    bei der badline wird 2 zyklen weiter "nach hinten" gesprungen als bei der normalen loop

  • OK, das sehe ich, aber ist das nicht bei jedem Bildschirmaufbau identisch? Wird denn der Befehl beim Sprung zurück nicht mehr in der vorherigen Rasterzeile ausgeführt? Ich fange ja beim Label "colloop" in der neuen Rasterzeile an. Also muß ich beim Schleifendurchlauf bei einer Badline quasi alle Taktzyklen der Schleife innerhalb derselben Rasterzeile zählen? Die längere Schleife für die normalen Rasterzeilen läuft ja innerhalb einer Rasterzeile.

    Ach Mist, hätte ich nur nicht mit dem Programmieren angefangen... ?(

  • Vielleicht ist es für dich einfacher, wenn du die vergangenen Zyklen von einem STA $D020 bis zum nächsten STA $D020 zählst. (mit und ohne Badline).
    Dann wirst du sehen, dass du auf 21 bzw. 63 kommst.

  • Ah, jetzt hab ich's... der Befehl "ldx #$08", der ja nur innerhalb einer Badline ausgeführt wird, verbraucht natürlich innerhalb der Schleife 2 TZ mehr, deswegen auch die 21. Ich habe den Fehler gemacht, daß ich nur vom ersten Bildschirmaufbau aus gedacht habe, und da wird das "ldx #$08" ja auch tatsächlich das erste Mal VOR der Schleife auch in der vorherigen Rasterzeile ausgeführt, oder?

    Jedenfalls vielen Dank, Roland, ich hab das Gefühl, daß ich mich manchmal ziemlich blöd anstelle, aber ich will ja auch zu 100% kapieren, was ich da mache. Nur hinfrickeln bis es läuft reicht mir da nicht.

  • So, nachdem die Bars nun stabil sind, habe ich einen FLD-Effekt hinzugefügt, der die Bars und den Scroller darin hoch und runter hüpfen läßt. Allerdings stimmen nun die Abstände zwischen den Farben nicht mehr, bzw. einige Farbwerte werden "zu kurz" angezeigt. Woran liegt das? Bei einem FLD wird doch die Ausgabe der nächsten Badline unterdrückt. Meine FLD-Routine läuft in einer RZ direkt vor einer Badline und dauert genau 63 TZ. Danach sollte doch direkt die Badline ausgegeben werden, oder wird die "unterdrückt", und die nächste RZ hat ganz normal auch 63 TZ.

    Habe das Beispiel-PRG mal wieder angehängt.

  • die nächste badline kommt wenn die unteren 3 bits von d012 und d011 gleich sind (raster und yscroll). je nachdem wie die fld routine aufgebaut ist muss das nicht die rasterline sein die nach der fld routine drankommt :)

  • Hmm, wie gesagt, die FLD-Routine dauert genau 63 TZ und zählt den Wert in $d011 immer um 1 hoch:


    doFLD:
    lda $d011 // 4 4
    clc // 2 6
    adc #$01 // 2 8
    and #$07 // 2 10
    ora #$18 // 2 12
    jsr wait // 12 24
    jsr wait // 12 36
    jsr wait // 12 48
    nop // 2 50
    nop // 2 52
    nop // 2 54
    sta $d011 // 4 58
    dex // 2 60
    bne doFLD // 3 63