Page 2 of 3
Re: Scrolling Graphics Questions
Posted: Sat Oct 29, 2016 4:02 pm
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
Re: Scrolling Graphics Questions
Posted: Sat Oct 29, 2016 4:15 pm
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
Re: Scrolling Graphics Questions
Posted: Sat Oct 29, 2016 5:14 pm
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
Re: Scrolling Graphics Questions
Posted: Sat Oct 29, 2016 5:54 pm
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
Re: Scrolling Graphics Questions
Posted: Sat Oct 29, 2016 6:43 pm
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
Re: Scrolling Graphics Questions
Posted: Sat Oct 29, 2016 7:14 pm
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
Re: Scrolling Graphics Questions
Posted: Sat Oct 29, 2016 9:09 pm
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.
Re: Scrolling Graphics Questions
Posted: Sun Oct 30, 2016 12:08 am
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.
Re: Scrolling Graphics Questions
Posted: Sun Oct 30, 2016 8:41 am
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.
Re: Scrolling Graphics Questions
Posted: Sun Oct 30, 2016 1:06 pm
by pser1
Hi Stew,
thanks a bunch!
That's a lot of info to process
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