Double buffering ist hier m.E. nicht nötig. Als erstes würde ich den gewaltig großen Kopierloop, der screen+CRAM gleichzeitig bearbeitet, in kleinere Häppchen aufteilen. Bspw. 3 loops die jeweils nur sechs bis acht Zeilen verschieben. Das sollte vielleicht schon reichen.
Hallo Besucher, der Thread wurde 9,2k mal aufgerufen und enthält 71 Antworten
letzter Beitrag von ThomBraxton am
Fullscreen Smooth Scroll zuckt
- Haubitze
- Erledigt
-
-
Naja, das kommt drauf an was noch alles so in dem Frame passieren soll. Vielleicht kriegt man es so wie es jetzt ist irgendwie reingequetscht, aber selbst wenn sonst nichts weiter geplant wäre: wieso sollte man die Last so ungleich auf die Frames verteilen?
-
Die Last ist auch beim regulären double buffering nicht immer gleich verteilt.
Außerdem sind hier ja nicht so viele Zeilen betroffen. Ohne double buffering geht einiges.
Man schaue sich mal Green Beret an: 16 Zeilen mit CRAM-Verschiebung, sprite multiplexer, recht anspruchsvolle AI, Musik etc....auch wenn ich persönlich fast immer mit zwei screens arbeite, aber nur weil ich zu faul bin, timing Stress auszubügeln
-
Die Last ist auch beim regulären double buffering nicht immer gleich verteilt.
Ja, sie ist sogar immer noch total ungleich verteilt, nämlich in diesem Fall auf nur zwei von 8 Frames. Aber immerhin viel besser als alles in einem Frame
-
Also das ist alles so spannend hier zu lesen, da würde ich ja fast schon eine Compo ausrufen wollen:
Wer schafft die meisten Zeilen Scrolling screen + color in einem Frame (bzw mit der wenigsten Rasterzeit)?
Da können sicher noch viele außer mir eine Menge lernen.
Was denkt Ihr? -
50 framegenauer per second muss zuckeln wenn der Monitor 60 nur kann
-
Wer schafft die meisten Zeilen Scrolling screen + color in einem Frame (bzw mit der wenigsten Rasterzeit)?
Ich weiß nicht. Die schnellste Lösung ist wohl, alles komplett zu unrollen. Am Ende gäbe es m.E. vermutlich lauter identische Beiträge auf Platz 1.
-
Dann mit Begrenzung des zur Verfügung stehenden RAM's
-
Uff... Also Softscrolling mit Double Buffering läuft...
Alles noch total unoptimiert, aber die größten brainfucks habe ich wohl umschifft.Jetzt kommt aber das nächste Fragezeichen auf mich zu: wenn ich ständig zwischen screen und buffer switche, dann muss ich ja auch ständig zwei Screens updaten, ebenso Sprite Pointer etc, oder?
Sieht man im angehängten File ganz gut, wo der Text blinkt, weil er immer nur auf einen der beiden Screens geschrieben wird. Ebenso auch beim Sprite, wenn man nach oben läuft.Also wenn ich z.B. bisher das Sprite so geändert habe:
Muss ich jetzt entweder eine Abfrage machen, ob ich mich im screen oder buffer befinde, oder einfach alles doppelt schreiben, wenn ich keinen Denkfehler habe? -
ständig zwei Screens updaten, ebenso Sprite Pointer etc,
Die Sprite Pointer sind das einzige, was außer dem Screen selber behandelt werden muss. Ich setze immer einfach beide Pointer, das ist glaube ich schneller und kleiner als eine Abfrage. Für den Teil des Screens, der nicht gescrollt wird, kannst Du entweder beide Screens identisch beschreiben, oder Du benutzt einen Raster-IRQ und schaltest nur für den scrollenden Teil den Screenbuffer um.
-
So langsam wird's - tausend Dank für Eure tolle Hilfe!
Jetzt kopiere ich nur noch das color ram in einem Rutsch.
Dennoch benötigt das ganze knapp zuviel Zeit und bringt die erste Zeile noch zum flackern.Dabei ist mir aufgefallen, dass der IRQ Trigger nur funktioniert, wenn ich einen Wert zwischen 0 und 38 eintrage. Alle Werte darüber führen aus dem IRQ nicht mehr zurück. Kann ich den IRQ nicht auch bei z.B. $F8 anspringen?
Code- main
- sei ; set interrupt disable flag
- jsr clear ; clear the screen
- jsr init_sprites
- ;lda #%10000100 ; SCRRAM 2000
- lda #%00010100 ; SCRRAM 0400
- sta $d018 ; switch screen
- jsr petscii_init
- jsr scroll_init
- lda #$00
- jsr init_joystick ; $00 = joy2, $01 = joy1
- lda #$7f ; $7f = %01111111
- sta $dc0d ; Turn off CIAs Timer interrupts ($7f = %01111111)
- sta $dd0d ; Turn off CIAs Timer interrupts ($7f = %01111111)
- lda $dc0d ; by reading $dc0d and $dd0d we cancel all CIA-IRQs in queue/unprocessed
- lda $dd0d ; by reading $dc0d and $dd0d we cancel all CIA-IRQs in queue/unprocessed
- lda #<irq ; point IRQ Vector to our custom irq routine
- ldx #>irq
- sta $0314 ; store in $314/$315
- stx $0315
- lda #$00 ; trigger interrupt at row zero
- sta RASTERLINE
- cli ; clear interrupt disable flag
- loop
- jmp loop ; infinite loop
- ;================================
- ; Our custom interrupt routines
- ;================================
- irq
- lda #$3
- sta $d019 ; acknowledge IRQ / clear register for next interrupt
- jmp $ea31 ; return to Kernel routine
Oder lässt sich bei der col ram Routine noch was rausholen?
Code- ;==========================================================
- ; move color ram
- ;==========================================================
- move_color_ram
- inc BORDERCOLOR
- ldx #$0
- -
- lda COLRAM+1 + 0*40,x
- sta COLRAM + 0*40,x
- lda COLRAM+1 + 1*40,x
- sta COLRAM + 1*40,x
- lda COLRAM+1 + 2*40,x
- sta COLRAM + 2*40,x
- lda COLRAM+1 + 3*40,x
- sta COLRAM + 3*40,x
- lda COLRAM+1 + 4*40,x
- sta COLRAM + 4*40,x
- lda COLRAM+1 + 5*40,x
- sta COLRAM + 5*40,x
- lda COLRAM+1 + 6*40,x
- sta COLRAM + 6*40,x
- lda COLRAM+1 + 7*40,x
- sta COLRAM + 7*40,x
- lda COLRAM+1 + 8*40,x
- sta COLRAM + 8*40,x
- lda COLRAM+1 + 9*40,x
- sta COLRAM + 9*40,x
- lda COLRAM+1 + 10*40,x
- sta COLRAM + 10*40,x
- lda COLRAM+1 + 11*40,x
- sta COLRAM + 11*40,x
- lda COLRAM+1 + 12*40,x
- sta COLRAM + 12*40,x
- lda COLRAM+1 + 13*40,x
- sta COLRAM + 13*40,x
- lda COLRAM+1 + 14*40,x
- sta COLRAM + 14*40,x
- lda COLRAM+1 + 15*40,x
- sta COLRAM + 15*40,x
- lda COLRAM+1 + 16*40,x
- sta COLRAM + 16*40,x
- lda COLRAM+1 + 17*40,x
- sta COLRAM + 17*40,x
- lda COLRAM+1 + 18*40,x
- sta COLRAM + 18*40,x
- inx
- cpx #39
- beq +
- jmp -
- +
- dec BORDERCOLOR
- rts
-
Versuche doch mal move_color_ram in zwei Schleifen zu machen, zuerst die oberen ~7 Zeilen, dann den Rest.
Mit ein wenig Glück reicht das schon. -
Dabei ist mir aufgefallen, dass der IRQ Trigger nur funktioniert, wenn ich einen Wert zwischen 0 und 38 eintrage.
Ein beliebter Fehler (ich spreche aus Erfahrung ) ist es, Bit 8 der Rasterzeile zu ignorieren (ist in $d011). Wenn das gesetzt ist, wird auf die Rasterzeile in $d012 immer 256 aufaddiert. Setz Bit 8 mal explizit auf 0, das könnte es sein.
-
Versuche doch mal move_color_ram in zwei Schleifen zu machen, zuerst die oberen ~7 Zeilen, dann den Rest.
Mit ein wenig Glück reicht das schon.Leider nein, im Endeffekt verbrauche ich dadurch noch mehr Rasterzeit.
-
Leider nein, im Endeffekt verbrauche ich dadurch noch mehr Rasterzeit.
Das stimmt zwar, aber Du gewinnst trotzdem Zeit: dadurch dass Du die obersten 7*8=56 Rasterzeilen schon erledigt hast, darf der Rasterstrahl bis zur 56.sichtbaren Zeile laufen bevor es flackert. Diese Zeit gewinnst Du, um den unteren Teil zu scrollen. Da Dein Loop im Moment auch in der letzten Iteration die allererste Zeile anfasst, musst Du im Moment schon fertig sein, bevor der Rasterstrahl diese erste Zeile erreicht.
-
Hmm. Es klingt logisch, nur will mein Gehirn dieser Reise nicht folgen
Hier mal der aktuelle Codes des Grauens (es gibt vermutlich viel schlauere Ansätze, zwischen screen und screen_buffer zu wechseln, aber dieser hier ist zumindest simpel)Code- xscroll !byte $07 ; position of the soft scrolling (0-7)
- xscroll_counter !byte $0f ; counts from 15 to 0
- ; so we can check if we need to copy the screen or the buffer
- ; e.g. if 0-7 then copy buffer, if 8-15 then copy screen
- ; can be done much more elegant I guess, but this is my way
- xscroll_wait !byte $00 ; a wait byte to slow the scrolling down
- map_copy_pos !byte $00
- ;==========================================================
- ; init
- ;==========================================================
- scroll_init
- lda #$07
- sta $d016 ; set 38 colums
- rts
- ;==========================================================
- ; entry point for scrolling routine
- ; loop to slow down execution of the scrolling
- ;==========================================================
- scroll_screen
- ldy xscroll_wait ; a timing loop to slow down the scrolling
- cpy #$00
- bne +
- ldy #$3 ; defines the slowdown. 0 = fastest
- sty xscroll_wait
- jmp start_scroll
- +
- dey
- sty xscroll_wait
- rts
- ;==========================================================
- ; scroll routine
- ;==========================================================
- start_scroll
- ldx xscroll_counter
- cpx #12
- bne +
- jsr move_lower_buffer
- +
- ldx xscroll_counter
- cpx #10
- bne +
- jsr move_upper_buffer
- +
- ldx xscroll_counter
- cpx #7
- bne +
- lda #%10000100 ; SCRRAM 2000
- sta $d018 ; switch screen
- +
- ldx xscroll_counter
- cpx #4
- bne +
- jsr move_lower_screen
- +
- ldx xscroll_counter
- cpx #2
- bne +
- jsr move_upper_screen
- +
- ldx xscroll_counter
- cpx #$ff
- bne +
- ldx #15
- lda #%00010100 ; SCRRAM 0400
- sta $d018 ; switch screen
- +
- dex
- stx xscroll_counter
- ldy xscroll
- cpy #$ff
- bne +
- ldy #$07 ; one soft scrolling cycle complete, now copy scrram
- jsr move_upper_color_ram
- jsr move_lower_color_ram
- +
- sty $d016 ; soft scroll
- dey
- sty xscroll
- rts
- ;==========================================================
- ; move upper screen
- ;==========================================================
- move_upper_screen
- ldx #$0
- -
- lda SCRRAM_BUFFER+1 + 0*40,x
- sta SCRRAM + 0*40,x
- lda SCRRAM_BUFFER+1 + 1*40,x
- sta SCRRAM + 1*40,x
- lda SCRRAM_BUFFER+1 + 2*40,x
- sta SCRRAM + 2*40,x
- lda SCRRAM_BUFFER+1 + 3*40,x
- sta SCRRAM + 3*40,x
- lda SCRRAM_BUFFER+1 + 4*40,x
- sta SCRRAM + 4*40,x
- lda SCRRAM_BUFFER+1 + 5*40,x
- sta SCRRAM + 5*40,x
- lda SCRRAM_BUFFER+1 + 6*40,x
- sta SCRRAM + 6*40,x
- lda SCRRAM_BUFFER+1 + 7*40,x
- sta SCRRAM + 7*40,x
- lda SCRRAM_BUFFER+1 + 8*40,x
- sta SCRRAM + 8*40,x
- lda SCRRAM_BUFFER+1 + 9*40,x
- sta SCRRAM + 9*40,x
- inx
- cpx #39
- beq +
- jmp -
- +
- rts
- ;==========================================================
- ; move lower screen
- ;==========================================================
- move_lower_screen
- ldx #$0
- -
- lda SCRRAM_BUFFER+1 + 10*40,x
- sta SCRRAM + 10*40,x
- lda SCRRAM_BUFFER+1 + 11*40,x
- sta SCRRAM + 11*40,x
- lda SCRRAM_BUFFER+1 + 12*40,x
- sta SCRRAM + 12*40,x
- lda SCRRAM_BUFFER+1 + 13*40,x
- sta SCRRAM + 13*40,x
- lda SCRRAM_BUFFER+1 + 14*40,x
- sta SCRRAM + 14*40,x
- lda SCRRAM_BUFFER+1 + 15*40,x
- sta SCRRAM + 15*40,x
- lda SCRRAM_BUFFER+1 + 16*40,x
- sta SCRRAM + 16*40,x
- lda SCRRAM_BUFFER+1 + 17*40,x
- sta SCRRAM + 17*40,x
- lda SCRRAM_BUFFER+1 + 18*40,x
- sta SCRRAM + 18*40,x
- inx
- cpx #39
- beq +
- jmp -
- +
- rts
- ;==========================================================
- ; move upper buffer
- ;==========================================================
- move_upper_buffer
- ldx #$0
- -
- lda SCRRAM+1 + 0*40,x
- sta SCRRAM_BUFFER + 0*40,x
- lda SCRRAM+1 + 1*40,x
- sta SCRRAM_BUFFER + 1*40,x
- lda SCRRAM+1 + 2*40,x
- sta SCRRAM_BUFFER + 2*40,x
- lda SCRRAM+1 + 3*40,x
- sta SCRRAM_BUFFER + 3*40,x
- lda SCRRAM+1 + 4*40,x
- sta SCRRAM_BUFFER + 4*40,x
- lda SCRRAM+1 + 5*40,x
- sta SCRRAM_BUFFER + 5*40,x
- lda SCRRAM+1 + 6*40,x
- sta SCRRAM_BUFFER + 6*40,x
- lda SCRRAM+1 + 7*40,x
- sta SCRRAM_BUFFER + 7*40,x
- lda SCRRAM+1 + 8*40,x
- sta SCRRAM_BUFFER + 8*40,x
- lda SCRRAM+1 + 9*40,x
- sta SCRRAM_BUFFER + 9*40,x
- inx
- cpx #39
- beq +
- jmp -
- +
- rts
- ;==========================================================
- ; move lower buffer
- ;==========================================================
- move_lower_buffer
- ldx #$0
- -
- lda SCRRAM+1 + 10*40,x
- sta SCRRAM_BUFFER + 10*40,x
- lda SCRRAM+1 + 11*40,x
- sta SCRRAM_BUFFER + 11*40,x
- lda SCRRAM+1 + 12*40,x
- sta SCRRAM_BUFFER + 12*40,x
- lda SCRRAM+1 + 13*40,x
- sta SCRRAM_BUFFER + 13*40,x
- lda SCRRAM+1 + 14*40,x
- sta SCRRAM_BUFFER + 14*40,x
- lda SCRRAM+1 + 15*40,x
- sta SCRRAM_BUFFER + 15*40,x
- lda SCRRAM+1 + 16*40,x
- sta SCRRAM_BUFFER + 16*40,x
- lda SCRRAM+1 + 17*40,x
- sta SCRRAM_BUFFER + 17*40,x
- lda SCRRAM+1 + 18*40,x
- sta SCRRAM_BUFFER + 18*40,x
- inx
- cpx #39
- beq +
- jmp -
- +
- rts
- ;==========================================================
- ; move upper color ram
- ;==========================================================
- move_upper_color_ram
- inc BORDERCOLOR
- ldx #$0
- -
- lda COLRAM+1 + 0*40,x
- sta COLRAM + 0*40,x
- lda COLRAM+1 + 1*40,x
- sta COLRAM + 1*40,x
- lda COLRAM+1 + 2*40,x
- sta COLRAM + 2*40,x
- lda COLRAM+1 + 3*40,x
- sta COLRAM + 3*40,x
- lda COLRAM+1 + 4*40,x
- sta COLRAM + 4*40,x
- lda COLRAM+1 + 5*40,x
- sta COLRAM + 5*40,x
- lda COLRAM+1 + 6*40,x
- sta COLRAM + 6*40,x
- lda COLRAM+1 + 7*40,x
- sta COLRAM + 7*40,x
- lda COLRAM+1 + 8*40,x
- sta COLRAM + 8*40,x
- lda COLRAM+1 + 9*40,x
- sta COLRAM + 9*40,x
- inx
- cpx #39
- beq +
- jmp -
- +
- dec BORDERCOLOR
- rts
- ;==========================================================
- ; move color ram
- ;==========================================================
- move_lower_color_ram
- inc BORDERCOLOR
- ldx #$0
- -
- lda COLRAM+1 + 10*40,x
- sta COLRAM + 10*40,x
- lda COLRAM+1 + 11*40,x
- sta COLRAM + 11*40,x
- lda COLRAM+1 + 12*40,x
- sta COLRAM + 12*40,x
- lda COLRAM+1 + 13*40,x
- sta COLRAM + 13*40,x
- lda COLRAM+1 + 14*40,x
- sta COLRAM + 14*40,x
- lda COLRAM+1 + 15*40,x
- sta COLRAM + 15*40,x
- lda COLRAM+1 + 16*40,x
- sta COLRAM + 16*40,x
- lda COLRAM+1 + 17*40,x
- sta COLRAM + 17*40,x
- lda COLRAM+1 + 18*40,x
- sta COLRAM + 18*40,x
- inx
- cpx #39
- beq +
- jmp -
- +
- dec BORDERCOLOR
- rts
-
Ein beliebter Fehler (ich spreche aus Erfahrung ) ist es, Bit 8 der Rasterzeile zu ignorieren (ist in $d011). Wenn das gesetzt ist, wird auf die Rasterzeile in $d012 immer 256 aufaddiert. Setz Bit 8 mal explizit auf 0, das könnte es sein.
Danke für den Reminder - hat immerhin drei Rasterzeilen eingebracht (bis $fb geht das Interface)
-
Ich würde die Schleifen anders machen:
ldx #38
[...]
dex
bpl -Spart dir das "cpx" und dessen Takte.
-
-
Oh, stimmt!