commodore 64 smooth scroller on line 1 - is jumping around on the screen if interrupt set on line #0

567 Views Asked by At

I have this horizontal smooth scrolling text on line 1 on the screen. the smooth scrolling effect is made using the $d016 hardware scrolling effect by iterating on the 7 lowest bits of $d016). The scroller runs on line 1 of the screen. I have set up two raster interrupts.

The "noScroller" interrupt is the part of the screen that should not be scrolled - which is whole screen except line 1.

The "scroller" is the interrupt that happens on line 1. I have set this interrupt to #50 even though I think it would make sense to set it to #0 since the scroll should only happen on line 1, but if I do set it to #0 then the scrolling text jumps around.

The "noscroller" interrupt is set to happen on line #66 - if I set it to #58 which seems to be the place where line 1 happens then the scrolling text starts to jump around strangely.

My problem is that I don't know what is wrong with my 2 interrupts. I would like to have the $d016 smooth scrolling only happen on line 1 but I have to make a larger area of the screen scroll than just line 1 otherwise the text will jump around. Here is my working code (with a too large scrolling screen area):

            *=$c000
            sei
            lda #$7f
            sta $dc0d
            sta $dd0d
            and $d011
            sta $d011                  
            ldy #50
            sty $d012
            lda #<scroller
            ldx #>scroller
            sta $0314
            stx $0315
            lda #$01
            sta $d01a
            cli
            rts

 noScroller      lda $d016
            and #$f8
            sta $d016
            ldy #50
            sty $d012
            lda #<scroller
            ldx #>scroller
            sta $0314
            stx $0315
            inc $d019
            jmp $ea31        


scroller        lda $d016
            and #$f8
            adc offset
            sta $d016
            dec offset
            bpl continue
            lda #07
            sta offset

 shiftrow        ldx #$00
            lda $0401,x
            sta $0400,x
            inx
            cpx #39
            bne shiftrow+2

 fetchnewchar    ldx nextchar                
            lda message,x
            sta $0427
            inx
            lda message,x
            cmp #255
            bne continue-3
            ldx #00
            stx nextchar

 continue       ldx #66
           stx $d012
           lda #<noScroller
           ldy #>noScroller
           sta $0314
           sty $0315
           inc $d019
           jmp $ea31



 offset          byte 07  
 nextchar        byte 00
 message         byte 011, 009, 012, 018, 015, 025, 032, 023, 001, 019, 032, 006, 009, 014, 001, 012, 012, 025, 032, 008, 005, 018, 005, 032, 032, 032, 032, 032, 032, 255
1

There are 1 best solutions below

0
On BEST ANSWER

It has been a long time ;-) I remember that doing real work in interrupts is sometimes problematic because the computer is busy and you will not get the next interrupt in time. You do update the $0400 area while you are in that area, that will flicker. Maybe that is the reason you need to increase the window of scan lines.

I recommend you try separating the change of register $d016 from storing the text at $0400. Move the copying of text into the second interrupt noScroller after resetting $d016 because there you have all the time you need. The change will not be visible until you hit the top scan line again. Then experiment with the scan lines $d012 again if you can make the area exactly as small as needed.

During debugging you can change the background colour of the screen at the begin of your interrupt and reset it at the end. You should get a short coloured line on your screen that is wobbling a bit around. That will show you "where" your interrupt is happening. If you see that every 8th interrupt is taking too long, try unrolling the loop shiftrow with 39 times LDA/STA, which is faster.