Scrolling Graphics Questions

Hardware Hacking, Programming and Game Solutions/Cheats
pser1
Posts: 1655
Joined: Sun Mar 25, 2012 7:32 pm
Location: Barcelona (SPAIN)

Re: Scrolling Graphics Questions

Post by pser1 »

@Ciaran and Stew
Now I remember the reason why I forgot about the stack ...
a) working right on the visible screen produces noticiable glitches
b) using double buffer, screens have their beginning at $c00 and $2400 and the data is copied once forwards, next backwards and so on.
The stack has to be changed using 16 bit offsets before every PULS and PUSH, and these offsets are different in both 'copy' directions, making
things a bit tangled ... not impossible at all, of course!

cheers
pere
pser1
Posts: 1655
Joined: Sun Mar 25, 2012 7:32 pm
Location: Barcelona (SPAIN)

Re: Scrolling Graphics Questions

Post by pser1 »

sorchard wrote:Hi Pere,
You can make it go even faster if you use both stacks. Sixxie's suggestion was to disable interrupts in the pias and make use of cc & dp as well, i.e. something like this to move the screen up one line:
ldu #copy_from_address
lds #copy_to_address+8
; repeat these 3 instructions many times
pulu cc,dp,d,x,y
pshs cc,dp,d,x,y
leas 16,s
Even the leas 16,s can be removed if the source data is arranged in the right way. (Though not much use if the screen is being scrolled onto itself)
If interrupts are disabled you can use your extra 32K in MAP1 for anything you like. You just need to switch back to MAP0 when you want to use disks & basic again.
Hi Stew,
you are right, but if I disable interrupts
ORCC #$50 ; disables IRQ and FIRQ
I assume that the FS will still be generated and received, right?
Using that code, the U stack will be going for free from say $c00 till $23ff
But S stack goes backwards, so I will need to add 16 after every copy, I don't see how to get rid of the leas 16,s
Keeping into acount that we have a 'real' image so not pre-arranged in any way.

Right, a simple routine near $7fff could be called with x=ROM address and after switching to map0 and do the task
it will return to map1. Of course, I see that the Data to be saved must be in the low 32k

This thread is becoming very, very interesting. I am learning quite a lot about graphics and programming tricks!
Maybe I should think about creating a game in the near future ;-)

cheers
pere
pser1
Posts: 1655
Joined: Sun Mar 25, 2012 7:32 pm
Location: Barcelona (SPAIN)

Re: Scrolling Graphics Questions

Post by pser1 »

Hi Stew,
I think that I answered too fast!
I need to synchronize the changes of images exactly when an FS arrives (end of screen)
That interrupt will occur even with IRQ and FIRQ disabled, but you talk about disabling them in the PIAs.
If I do this:
lda #$04 ; reset bits 0 and 1
sta $ff03 ; FS IRQ to CPU disabled
Then how could I detect the FS interrupt?
Will the flag at bit7 still be set every FS?
Last point, if I mess up the CC in the PULS, aren't there chances for other interrupts to occur?
I was thinking in the timer that acts every 20ms ...
You know that hardware is a great unknow to me, sorry :(

regards
pere
pser1
Posts: 1655
Joined: Sun Mar 25, 2012 7:32 pm
Location: Barcelona (SPAIN)

Re: Scrolling Graphics Questions

Post by pser1 »

for sure this will not be the last version, but works faster than previous ones
Thanks a lot, Ciaran and Stew

Code: Select all

			opt	cd
			opt	ct
			org	$4500					; donde ubicar el programa
inicio	sts	$0114
			tfr	cc,a
			tfr	dp,b
			std	CcDp
			orcc	#$50					; deshabilita interrupciones
			lda	#$4					; poner a uno los bits 0 y 2
			sta	$ff03					; para detectar FS al final de pantalla

			ldx	#$0c00				; origen de pantalla (inicial donde está imagen a mover)
			stx	origen				; guardar puntero
			ldx	#$2400				; destino sin desplazar
			stx	destino				; guardar puntero
			ldb	#192					; filas a desplazar para mover toda la pantalla
			stb	>$0076				; guardar en variable pagina 0

			opt 	cc
S1			lda	#191					; numero de lineas a hacer scroll (la última NO)
			sta	>$0077				; guardar en variable pagina 0
			ldu	>$008a				; tomar doble cero
			stu	,x++					; 2
			stu	,x++					; 4
			stu	,x++					; 6
			stu	,x++					; 8 
			stu	,x++					;10
			stu	,x++					;12
			stu	,x++					;14
			stu	,x++					;16
			stu	,x++					;18
			stu	,x++					;20
			stu	,x++					;22
			stu	,x++					;24
			stu	,x++					;26
			stu	,x++					;28
			stu	,x++					;30
			stu	,x++					; limpiar los 32 bytes de la primera linea

			lds	origen				; points to beginning of ORIGIN line
			ldu	destino				; points to 8th byte next DESTination line
			leau	40,u
Cpy1L		puls  cc,dp,x,y,d			; copies 8 bytes ($c00-$c07)
			pshu  cc,dp,x,y,d			; puts in buffer these 8 bytes
			leau  16,u					; to point to next 8 bytes
			puls  cc,dp,x,y,d			; copies 8 bytes ($c00-$c07)
			pshu  cc,dp,x,y,d			; puts in buffer these 8 bytes
			leau  16,u					; to point to next 8 bytes
			puls  cc,dp,x,y,d			; copies 8 bytes ($c00-$c07)
			pshu  cc,dp,x,y,d			; puts in buffer these 8 bytes
			leau  16,u					; to point to next 8 bytes
			puls  cc,dp,x,y,d			; copies 8 bytes ($c00-$c07)
			pshu  cc,dp,x,y,d			; puts in buffer these 8 bytes. ONE line copied
			leau  16,u					; to point to next 8 bytes
			dec	>$0077					; decrement counter
			bne	Cpy1L					; not yet done, loop
			
			opt 	cc
			lda	$ff02					; limpiar indicador de interrupción
eHs		lda	$ff03					; llegó interrupción HSYNC? (la de final de pantalla!)
			bpl	eHs					; esperar
											; cambiar inicio de pantalla en SAM
cambio	lda	>$0076				; lee contador numero de scrolls a realizar (+1)
			anda	#1						; usa bit cero
			beq	par					; si es par mostrar buffer
											; si es impar mostrar 'std'
impar		sta	$ffcb					; 1
			sta	$ffce					; 0 = #%0000110 = 6 (valor x defecto)
			bra	actPun				; salta codigo para Pares
par		sta	$ffca					; 0
			sta	$ffcf					; 1 = #%0010010 = 18 (valor x buffer)
											; cambiar punteros
actPun	ldx	destino				; toma destino (nuevo origen)
			ldy	origen				; toma origen (nuevo destino)
			sty	destino				; actualiza destino actual
			stx	origen				; actualiza origen actual
			dec	>$0076				; movida la imagen completa?
			lbne	S1						; no, siguiente pixel abajo
			lds	$0114
			ldd	CcDp
			tfr	a,cc
			tfr	b,dp
			rts							; retorna
****************************************************************************************************
origen	fdb	$0000
destino	fdb	$0000
CcDp		fdb	$0000
			end 	inicio
I should assume that having disabled the FS interrupt to CPU implies that no more TIMER
is available. And there are no other interrupts disturbing the program.
It runs faster but I have not yet calculated the difference becuase the way I clean the first
line is very slow ... so it needs doing it better.

cheers
pere
pser1
Posts: 1655
Joined: Sun Mar 25, 2012 7:32 pm
Location: Barcelona (SPAIN)

Re: Scrolling Graphics Questions

Post by pser1 »

I have modified the 'cleaning method' for the first line
Not that important because it is one over 192 processed lines, so just a very little speed gain
The cycle-count for 1st version was:
60 (Intro) + 156 (1st Line) + 134 * 191 Lines + 84 (change of buffer) = 25.894 cycles
For this last version, it's the same with 1st Line = 97 cycles that gives a total of 25.835 cycles
So the gain is almost negligible, just a 0,23%
I attach here an VDK disk image to test it, just
RUN"TEST"

Any idea / advice on how to do that faster will be highly welcome :)

cheers
pere
Scroll with STACK.zip
(4.06 KiB) Downloaded 305 times
VSCROLDMix2.zip
Source file
(1.25 KiB) Downloaded 296 times
pser1
Posts: 1655
Joined: Sun Mar 25, 2012 7:32 pm
Location: Barcelona (SPAIN)

Re: Scrolling Graphics Questions

Post by pser1 »

I have tried to unroll the loop that does the 191 'normal' lines and that way
I can gain a 7,4% (only) at the cost of having an executable that is 5.500 bytes
instead of the just 185 bytes of previous version :(
Here you can found the source file ... not many changes, just macros

cheers
pere
VSCROLDMix3.zip
Source file
(1.29 KiB) Downloaded 300 times
sorchard
Posts: 530
Joined: Sat Jun 07, 2014 9:43 pm
Location: Norwich UK

Re: Scrolling Graphics Questions

Post by sorchard »

Hi Pere,

You've pretty much maxed it out already which I would say is a good day's work :) I think you can get most of the 7% improvement without having a huge program, if you copied for example 128 or 256 bytes per loop.

The only way I know to get an improvement after that is to take out the leas 16,s. For that you will need to have a background buffer to copy from, and you will need to draw each new line into the background buffer in a sequence that appears correctly on screen after copying. Simply put the whole image is pretty much stored in reverse order, but each group of 8 bytes runs forwards.

There is the additional complication of having to wrap the buffer, because the scrolling effect is achieved by moving the start position of the copy. This could be handled by doing two separate copies for the two parts of the buffer that are divided by the copy source pointer.
Stew
sorchard
Posts: 530
Joined: Sat Jun 07, 2014 9:43 pm
Location: Norwich UK

Re: Scrolling Graphics Questions

Post by sorchard »

Hi Pere,

I've attached a vertical scroll demo that uses the background buffer idea where the data is specially arranged to allow the fastest possible stack copy. Sorry if the code looks a bit messy, it's been hacked together from various bits and pieces.

I haven't actually done anything in the code to specially arrange the buffer, it's been done in the map data by swapping the tiles around. The resulting image is still upside down, but that can be fixed by further changes to the map and tile data.
Attachments
vsdemo_src.zip
(5.61 KiB) Downloaded 308 times
vsdemo.zip
(16.32 KiB) Downloaded 307 times
Stew
sorchard
Posts: 530
Joined: Sat Jun 07, 2014 9:43 pm
Location: Norwich UK

Re: Scrolling Graphics Questions

Post by sorchard »

Hi Pere,

I forgot to mention that the copy routine was designed for something else and copies n bytes, so is a bit more complicated than it needs to be for vertical scrolling.

It would be better to determine the number of lines that need copying and design the copy routine around that. That would remove the first 5 counter checks and save a few cycles and bytes of code.
Stew
pser1
Posts: 1655
Joined: Sun Mar 25, 2012 7:32 pm
Location: Barcelona (SPAIN)

Re: Scrolling Graphics Questions

Post by pser1 »

Hi Stew,
thanks a bunch!
That's a lot of info to process 8-)
I have downloaded the files but I have not yet looked at them.
I assume the code could be a 'special' routine you uploaded many time ago
that copied any number of bytes from a pointer to another ...

cheers
pere
Post Reply