Smooth vertical scrolling problem...

Basic and Machine Language

Moderator: Moderators

Post Reply
andym00
Vic 20 Newbie
Posts: 16
Joined: Sun Jan 30, 2011 10:50 am

Smooth vertical scrolling problem...

Post by andym00 »

I'm trying to setup a vertical scrolling screen, but smoothly using HPOS==0 to delay the screen by the extra line to get single line position..

This works fine, and very well..

On top of that, I also want to blank the top of the display to hide the offscreen region so it scroll on smoothly without having to have the top of the display off the screen..

This doesn't work so smoothly :(

I found that setting Width to 0 hides the display, but when combined with the other effects I'm unable to move the screen down by more than 8 pixels in 8x8 mode, 16 in 8x16 mode.. Removing the code that sets width to 0 indicates the logic is all cool, and the screen is moving the desired amount, but with it in it doesn't..

Logic follows like this:
Raster Line 0: Set HPOS to 0
On the first (off screen line) Set HPOS to 12
On the first displayed line: Set WIDTH to 22

That works fine, and I see the screen moving as it should, but obviously the top is visibly moving up and down..

Now if on Raster line 0 I set WIDTH to 0 in addition to HPOS something very weird happens and I appear to lose one of the zero width lines..

I also noticed that I'm getting one link of junk at the bottom of the screen, which I expect using the HPOS method, but sometimes it's also going to 2 lines depending upon the Y value I use..

I suspect I'm just missing something in how the VIC uses the Width value when it's zero.. Or maybe the point in the raster line where I'm changing HPOS or WIDTH..

Code: Select all


Raster1	= 25	;	First distance..
Raster2	= 8
Raster3	= 16
Raster4	= 42
Raster0	= 52+169	;	Last distance..

			!to "main.prg", cbm
			!cpu 6510
			!ct pet

			;	VIC20 BASIC stub 
			;	* = $401	;3k 
				* = $1001	;Unexpanded 
			;	* = $1201	;8k+ 
BASICstub	!word next_line		; Calculate pointer to next BASIC line 
			!word 2012			; BASIC Line# (change this to any # you want) 
			!byte $9e			; BASIC token for SYS 
			!byte <(Initialise / 1000 % 10) + $30
			!byte <(Initialise / 100 % 10) + $30
			!byte <(Initialise / 10 % 10) + $30
			!byte <(Initialise / 1 % 10) + $30
			!byte 0				; End of BASIC line 
next_line	!byte 0,0			; The next BASIC line would start here 


Main:
			cli

			lda #0
MainLoop:
			jmp MainLoop


SCREENY		!byte 0
YSCROLL		!byte 0


IRQ:
			dec $900F
			lda $9124
			lda #0
			sta CurrentRaster

			lda #<NMI0
			sta $0318
			lda #>NMI0
			sta $0319

			lda SCREENY
			clc
			adc #1
			sta SCREENY

			and #15
			sta YSCROLL
			lsr
			clc
			adc #17
			sta $9001

			ldy YSCROLL
			lda LineTime_lo,y
			clc
			adc #<((71*Raster2)-2)
			sta RasterTimes_lo+0
			lda LineTime_hi,y
			adc #>((71*Raster2)-2)
			sta RasterTimes_hi+0

			lda #<((71*Raster3)-2)
			sec
			sbc LineTime_lo,y
			sta RasterTimes_lo+1
			lda #>((71*Raster3)-2)
			sbc LineTime_hi,y
			sta RasterTimes_hi+1

			lda #50
			sta $9003

			inc $900f
			jmp	$eb18
			

			!align 255,0
			;	Line #0 of the frame..
NMI0:
			inc $900F
			sta .save_a
			lda #$0			;	Set HPOS and WIDTH to 0..
			sta $9000
			sta $9002
			lda #<NMI1
			jmp NMI_Exit

			;	This NMI is just a dummy since we need 2 timer latches to occur, and whilst it could work without
			;	it's easier since the scroll will work as long as the new scroll value is set by line #0 of the new frame..
NMI1:
			inc $900F
			sta .save_a
			lda #<NMI2
			jmp NMI_Exit

			;	Variable by +15 lines to control HPOS setting to move screen by one line..
NMI2:
			inc $900F
			sta .save_a
			lda #$0C		;	Restore the correct HPOS on the exact scanline to undelay scanline..
			sta $9000
			lda #<NMI3
			jmp NMI_Exit

			;	Fixed at the display start to reset screen from 0 width back to normal width, unblanking it essentially..
NMI3:
			inc $900F
			sta .save_a
			lda #$80+22		;	Restore correct width now..
			sta $9002
			lda #<NMI4
			jmp NMI_Exit

NMI4:
			inc $900F
			sta .save_a
			lda #<NMI0
			jmp NMI_Exit

NMI_Exit:
			sta $0318
			stx .save_x
CurrentRaster = * + 1
			ldx #0
			lda RasterTimes_lo,x
			sta $9116
			lda RasterTimes_hi,x
			sta $9117
			inx
			stx CurrentRaster

.save_x		=  * + 1
			ldx #0
.save_a		=  * + 1
			lda #0
			dec $900F
			rti

NMI_JUMP	!word NMI0

RasterTimes_lo
			!byte <((71*Raster2)-2)
			!byte <((71*Raster3)-2)
			!byte <((71*Raster4)-2)
			!byte <((71*Raster0)-2)
			!byte <((71*Raster1)-2)
RasterTimes_hi
			!byte >((71*Raster2)-2)
			!byte >((71*Raster3)-2)
			!byte >((71*Raster4)-2)
			!byte >((71*Raster0)-2)
			!byte >((71*Raster1)-2)

LineTime_lo	!for .i, 0, 16 { !byte <(.i*71) }
LineTime_hi	!for .i, 0, 16 { !byte >(.i*71) }

Initialise:
			sei

			;	Disable all interrupt sources, and stop the timers..
			lda #$7F
			sta $911E
			sta $912D
			sta $912E

			;	Enable Timer #1 on both VIAs..
			lda #$40
			sta $911B
			lda #$40
			sta $912B

			; Set our NMI & IRQ vectors up..
			lda #<IRQ
			sta $0314
			lda #>IRQ
			sta $0315	

			lda #<NMI0
			sta $0318
			lda #>NMI0
			sta $0319	

			;	Load the low bytes of Timer #1 on both VIAs..
			lda #<((312*71)-2)
			sta $9116
			sta $9126
			ldx #>((312*71)-2)

			;	Sync the IRQ to raster line 260..
			lda #134
-			cmp $9004
			bne -
			stx $9125

			;	Sync the NMI up to line 0..
			lda #0
-			cmp $9004
			bne -
			stx $9115

			;	Enable IRQs and NMIs for Timer #1 on both VIAs..
			lda #$c0
			sta $911E
			sta $912E

			;	Set the next timer value for the NMI into the latches.. So, on raster line 0..
			lda #<((Raster1*71)-2)
			sta $9116
			lda #>((Raster1*71)-2)
			sta $9117

			jmp Main
Anyone got any clues at all what I'm doing wrong here ?
TBCVIC
Vic 20 Hobbyist
Posts: 127
Joined: Thu Mar 05, 2009 3:38 am

Post by TBCVIC »

I can't say why it doesn't work, but I've done vertical scrolling myself. I didn't use your method though. My method only works on a monochrome screen though (well atleast the top and bottom character row). What I did was changing the color instead of setting the width to zero. I used inverted character graphics and just set the border and background color to the same color as the character color to effectively hide everything and then just change the background color to any other color you want at the first displayed line.

This is what I use here:
http://sleepingelephant.com/ipw-web/bul ... php?t=4825
Ola Andersson
Image
PhilRanger
Vic 20 Hobbyist
Posts: 143
Joined: Thu Aug 25, 2011 10:04 am

Re: Smooth vertical scrolling problem...

Post by PhilRanger »

andym00 wrote:'m trying to setup a vertical scrolling screen, but smoothly using HPOS==0 to delay the screen by the extra line to get single line position..

This works fine, and very well..
I didn't know this was possible. Could you please let me know where I could find more info on this?

Also, is it also possible for horizontal scrolling?

Thanks :D
Phil Ranger
-------------
"Don't eat the trees 2" for the VIC 20 : http://www.box.net/shared/u398kj0nr0lkauzm1k67
on line: http://www.mdawson.net/vic20chrome/vic2 ... otrees.prg
andym00
Vic 20 Newbie
Posts: 16
Joined: Sun Jan 30, 2011 10:50 am

Post by andym00 »

I stumbled across it just by playing with a program to test screen sizes, allowing me to control width, height, x position, y position..

I simply noticed that when HPOS was 0 the screen moved by one single raster line from the set VPOS value of 2 line resolution, and a spark ignited :)

I haven't found anything that shifts the screen anything other than 4 pixels horizontally though, and I'm not hopeful that it exists..

That said, I have stumbled into several manners of VIC video madness in my attempts to somehow get to the root of where one of my 0 width lines vanishes to, and also resetting the screen position to allow a second window with a different line offset.. Most of which it seems Viznut found out ages ago :)
User avatar
pixel
Vic 20 Scientist
Posts: 1329
Joined: Fri Feb 28, 2014 3:56 am
Website: http://hugbox.org/
Location: Berlin, Germany
Occupation: Pan–galactic shaman

Re: Smooth vertical scrolling problem...

Post by pixel »

andym00 wrote:Anyone got any clues at all what I'm doing wrong here ?
Absolutely nothing! This is beautiful and exactly what I just need. Very impressive how little CPU time this requires.
I'm thinking "double buffering" and copying just an 8th of the screen per frame before switching to the other screen. That's just about 64 bytes per frame as you sure know. Thanks a lot! :D
A man without talent or ambition is most easily pleased. Others set his path and he is content.
https://github.com/SvenMichaelKlose
Post Reply