vertical scrolling

Basic and Machine Language

Moderator: Moderators

Post Reply
User avatar
aitsch
Vic 20 Amateur
Posts: 51
Joined: Sun Mar 08, 2020 12:54 pm
Location: Germany NS

vertical scrolling

Post by aitsch »

hi,

the last two days i've played around with vertical scrolling.
it was relative easy to write the character copy code for the "scroll down" part (means, characters rising up, decreasing $9001).
after a beamline sync i got a very smooth scolling animation.

but:
the "scroll up" part was not successfull. ( characters falling down, increasing $9001)
I've tried two different concepts.
1. the copy process works bottom-up, what means oncoming to the beamline (yes, bad idea! :evil: ).
line 22 is copied to 23, 21 to 22, and so on. the routine is slim but not fast enough.

2. the copy process works top-down, what means in beamline direction (yes, good idea! but not good enough :| ).
here i buffer the top line in the zero page and copy it to the old line 1 and - in the same run - the old line 1 fills the buffer.
like this:

Code: Select all

			     
			... 
			ldx #0		; 
			ldy #0		; 0 to 21 (for 22 columns)
loop
			.adrReadDown  
			lda $1000,x	; read character
			sta tmp2		; temp backup character                                     
			lda tmp_line,y 	; read new character for line ...
			.adrWriteDown  
			sta $1016		; store new character - selfmod. code increases by 1 (initvalue $1016 )
			lda tmp2		; restore temp character
			sta tmp_line,y	; store in tmp line
			...
i do this 22 times (value of columns), set y=0 and repeat that 23 times (value of rows)

for both solutions i got a flickering scroll animation.
it was not possible for me to find a proper beamline position for a stable screen.

for this experiment i use the standard screen configuration (23 rows / 22 columns).
the copy routines will be called after 4 times dec / inc $9001.

how can this be solved better? has someone an code snippet for scrolling in this direction?

aitsch
User avatar
beamrider
Vic 20 Scientist
Posts: 1452
Joined: Sun Oct 17, 2010 2:28 pm
Location: UK

Re: vertical scrolling

Post by beamrider »

haven't time to look into your routine, but...

bear in mind that you need to do the block copy and the adjustment of $9001 during a VBI (Vertical Blank Interrupt) if you want perfectly smooth scrolling. Also the block copy needs to complete before the raster starts drawing the next frame (or at least have completed the rows faster than the raster gets to them).

Also, be sure to test it on a real vic with a CRT as other combinations can give false flickering.

Edit: Actually just remembered that $9001 is latched and read before each frame, so in-frame adjustment has no effect unlike the horizontal register.

p.s. You can see how long your copy routine is taking by changing the border colour at the start/end to something different. If you see flickering the raster is likely over-taking your drawing of the screen.
nippur72
de Lagash
Posts: 574
Joined: Thu Sep 07, 2006 8:35 am

Re: vertical scrolling

Post by nippur72 »

I think you can get a faster scroll-copy routine if you work in blocks rather than lines, e.g. 2 blocks of 253 bytes

Code: Select all

   ldx #253
loop:
   lda 7680-1+22*1,x
   sta 7680-1+22*0,x
   lda 7680-1+253+22*1,x
   sta 7680-1+253+22*0,x
   dex
   bne loop
(I haven't checked it, the actual numbers need to be verified)
User avatar
Mike
Herr VC
Posts: 4841
Joined: Wed Dec 01, 2004 1:57 pm
Location: Munich, Germany
Occupation: electrical engineer

Re: vertical scrolling

Post by Mike »

@nippur72: I think aitsch already arrived at an unrolled loop ... ;)
aitsch wrote:I've tried two different concepts.

1. the copy process works bottom-up, what means oncoming to the beamline (yes, bad idea! :evil: ).
line 22 is copied to 23, 21 to 22, and so on. the routine is slim but not fast enough.
Copying "against the grain" is not a bad idea, per se. If any tearing occurs, it happens at 'singular' lines/positions - any (unsynced!) copy action "with the grain" could suffer from a race condition with the electron beam, resulting in much more severe tearing artifacts when CPU and VIC overtake each other multiple times within a few rasters.

That being said, I don't see any speed problem with a fully unrolled loop: you have 22 pairs of LDA ABS,X|STA ABS,X in the loop body, each which take 9 cycles. Add to that 1x DEX (2 cycles) and 1x BPL (taken, 3 cycles) per iteration, over 22 columns and you get 2 + 22 x (22 x 9 + 2 + 3) - 1 = 4467 cycles - the "2 +" accounts for LDX #21 and the "-1" accounts for the single not taken branch at the end.

From the bottom of the display window to the top of the display window of the next frame you have 312 - 184 = 128 raster lines in PAL, 261 - 184 = 77 in NTSC. In PAL, 4467 cycles correspond to ~63 rasters, 63 < 128 => works. In NTSC, 4467 cycles correspond to ~69 rasters, 69 < 77 => works - albeit barely. Not much more time for further screen updates before the electron beam hits the top edge of the display window.

Any issues with using two screen pages (one on display, one hidden and for update) other than "it has to run on an unexpanded VIC-20"? That's a standard technique and you can use a full frame time for the screen update. If you have constant speed scrolling, you can even "distribute" the load of the full copy across several frames.
srowe wrote:Also, be sure to test it on a real vic with a CRT as other combinations can give false flickering.
And this. Yes.
Post Reply