So. I wrote a "smooth" scroller using colour bitmap mode.
The flickering experienced when the smooth scroll register resets is horrible. It doesn't look as bad on VICE but it's terrible on real hardware. I am using a double buffered screen for scrolling with the new data being rendered into the second screen so the process of scrolling the 9th pixel is very fast, reset the smooth scroll register and then update the screen address registers. I've made wild guesses at why it flickers so much but it looks to be timing related as on VICE I get the odd smooth scroll where I presume I hit the right time "by accident". This is taken from my real flat 128 (64k upgraded) not vice.
Hmm, watching this in slow-motion it looks like the picture pops down and up at the reset of the scroll register. Maybe you need to wait for vblank (bit 5 of $d600) before you switch to the other bitmap?
Can you try it the other way around? So that the change occurs while in VBLANK, not while outside is? So BEQ instead of BNE? Do you check the status-register-ready-bit when writing to VDC? Do you take into account the character-height set in register 9? Did you check the scrolling on its own without dual bitmap? Maybe the scroll-register itself produces those crazy results on the real thing. Never trust VICE when coding VDC. The emulation is pretty good considering it can run Risen from Oblivion, but a lot of quirks are still missing, the least of which is interlace-mode, which would be pretty hard to adapt for VICE.
BEQ seems to just lock it up. Which is odd. It freezes and doesn't scroll. I will play with that. I check the status reg in a lot of places but mostly you don't actually need to. You can fill the registers without much trouble, it's only when you start writing byte after byte of data to the thing that it needs status checking. I tested that quite heavily in Boulder Dash when speeding it up. Default character height is set, so 8 pixels. The smooth scroll register seems to know about that, if you try moving extra pixels it doesn't work and just wraps back to the first. Yeah, I did basic scrolling up the screen first (which doesn't require double buffering, down does). I did it pixel smooth at first without the hardware register and it worked fine. Then I added the hardware register for pixel offset and scrolled a whole 8 pixels at a time and it jumped just like in this video. I DON'T trust VICE. I found that out with Boulder Dash. I use a real flat 64k upgraded 128 to test on (which caused ALL sorts of problems before I found out that I had to set the bit to tell it there was 64k of vram!) Does pretty much the same on real hardware as emulator for this bug. I am pretty sure VICE is representing the problem correctly and I just need to work out how to get around it. It looks to be the same issue the other guy doing a simple text scroller came accross, but in the other axis for me. (btw, for that many pixels I could smooth scroll the shit out of that text without jitter).
The BASIC-program just shows the routine. You can adjust the scroll-speed in line 20.
The assembler-routine (softscroll.prg) @ $1300 is where the work is done. I did this "by the book":
lda #$18 sta lines lda #$07 sta soft sta videoaddress lda #$0f sta attributeaddress lda #$80 sta videoaddress+1 sta attributeaddress+1 sei flag0 lda #$20 flag1 bit $d600 beq flag1 ; wait until inside vblank flag2 bit $d600 bne flag2 ; wait until outside vblank
lda videoaddress ldx #$0c ; register 12 stx $d600 flag3 bit $d600 bpl flag3 sta $d601 lda videoaddress+1 ldx #$0d ; register 13 stx $d600 flag4 bit $d600 bpl flag4 sta $d601 lda attributeaddress ldx #$14 ; register 20 stx $d600 flag5 bit $d600 bpl flag5 sta $d601 lda attributeaddress+1 ldx #$15 ; register 21 stx $d600 flag6 bit $d600 bpl flag6 sta $d601 lda soft ldx #$18 ; register 24 stx $d600 flag7 bit $d600 bpl flag7 sta $d601 dec soft bpl flag9 lda #$07 sta soft lda videoaddress+1 sec sbc #$50 ; subtract 80 from videoaddress / attributeaddress sta videoaddress+1 sta attributeaddress+1 bcs flag8 dec videoaddress dec attributeaddress flag8 dec lines bmi flag11 flag9 ldy #$f0 ldx #$00 flag10 inx bne flag10 iny bne flag10 jmp flag0 flag11 cli rts
Ok, so you are scrolling by changing the display start address, where I am actually using block copy to shift the entire contents of the visible screen instead! I will try this method and adapt my scroll routine. It would be cool if I could get this working
Ok, so I can confirm that it IS possible to scroll smoothly in both up and down directions.
As for side to side? I don't think so!
I tried everything I can think of. I have perfect smooth scrolling in both vertical directions but I just can't get Horizontal smooth scrolling to work without a flicker when you reset the pixel register.
for the 30 year old record ... storing a 7 into the register does not produce smooth scrolling. I can only test this on vice128 at this time, until I find a true 80 column monitor, but, here is how you smooth scroll in the horizontal, that works for me. There is no need to turn off the interrupts.
screen_update_display ; ====================== main screen write/scroll except at very beginning ===========test-backwards====== ; ; added smooth scroll because of customer request ; I don't think it makes much of a difference and just ; greatly slows the game down - VDC just can't keep up without ; flashing - maybe move routine here once game is set ; ; instead of jsr vdcwrite 13 times in this short section ; replaced by inline code ! Makes it much longer. ; maybe replace bit command with a NOP and then ; just write smooth_scroll_screen ; jsr screen_update_attr ; ldy #01 smooth_scroll_start lda smooth_scroll_data,y ldx #25 ; jsr vdcwrite stx $d600 smooth_scroll_screen_loop01 bit $d600 wait for bit 7 to turn to a binary one bpl smooth_scroll_screen_loop01 sta $d601 ; iny cpy #8 bne smooth_scroll_start ; smooth_scroll_screen_move ; lda screen_attr_low ldx #21 ; jsr vdcwrite stx $d600 smooth_scroll_screen_loop02 bit $d600 wait for bit 7 to turn to a binary one bpl smooth_scroll_screen_loop02 sta $d601 ; lda screen_attr_high ldx #20 ; jsr vdcwrite stx $d600 smooth_scroll_screen_loop03 bit $d600 wait for bit 7 to turn to a binary one bpl smooth_scroll_screen_loop03 sta $d601 ; lda screen_loc_low ldx #13 ; jsr vdcwrite stx $d600 smooth_scroll_screen_loop04 bit $d600 wait for bit 7 to turn to a binary one bpl smooth_scroll_screen_loop04 sta $d601 ; lda screen_loc_high ldx #12 ; jsr vdcwrite stx $d600 smooth_scroll_screen_loop05 bit $d600 wait for bit 7 to turn to a binary one bpl smooth_scroll_screen_loop05 sta $d601 ; smoothscroll_reset ; lda #%01000111 ldx #25 ; jsr vdcwrite stx $d600 smooth_scroll_screen_loop06 bit $d600 wait for bit 7 to turn to a binary one bpl smooth_scroll_screen_loop06 sta $d601 ; rts ; smooth_scroll_data .db %01000111,%01000110,%01000101,%01000100,%01000011,%01000010,%01000001,%01000000 smooth_scroll_screen_temp .db 00