Hi
I would like to do an animation in a futur demo. I have 5 screens to switch speediest as possible.
I have a look on the gate array function 3. (ex: http://www.cpcwiki.eu/index.php/Gate_Array#Register_3_-_RAM_Banking)
is it the best strategy ?
Sid
Using RAM Banking 4 5 6 7 you can put 1st 2nd 3rd 4th image into RAM_4/RAM_5/RAM_6/RAM_7. And copy it (memcpy) into RAM_3 for show (RAM_3 is shown by default)
If you rewrite interrupt (killing firmware that is installed at RAM_2), RAM_2 can be used for 5th image (CRTC offset &8000 (always RAM_2 reading for display))
RAM_1 can be used as buffer of RAM_3 (offset of CRTC at &C000 (always RAM_3 reading for display) or else at &4000 (always RAM_1 reading for display))
while writing on RAM_3 (from RAM_5 for sample) you display RAM_1, while writing on RAM_1 from RAM_3 (using RAM Banking 0) you display RAM_3 (that's a buffer purpose, switching display (CRTC offset &C000 or else &4000) at each vsync() => then our animation is at 25Hz (each vsync() being at 50Hz)
RAM_0 has your program.
Note que le cpc ne peut adresser graphiquement que la RAM centrale. Donc si tes 5 ecrans font la taille d'un écran standard, tu peux directement oublier le flipping. Ta RAM centrale peut contenir seulement 4 ecrans de taille standard. Si t'as d'autres écran mais dans la ram supérieure, faudra alors passer par de la copie vers la RAM centrale. Autant te dire que même en faisant la copie à la pile ca va prendre du temps...
ok 4 images it's the best solution to flip in central memory.
With an ldir instruction I can flip the images. Is it speed enough ?
more important is to synchronize the flip (when changing CRTC offset) in order to get a full image displayed each vsync.
a ldir (==memcpy in SDCC) is quite long, but human eyes are quite slow to understand an animation.
sure you can change palette at 50Hz if you want to gain effects.
Just think about that, let's move a 10x10 pixels sprite from left to right of screen at 50Hz in mode 2, it does take 640 steps to do that.
50 images => 1 sec
640 images => ? sec
?=(640*1)/50=12.5 seconds : the sprite moving at max of speed for a human (let's say he saw 50Hz) without loosing any pixel step does take 12.5 seconds !
Now let's compare our animation speed to "a man walking speed", a man does take 0.5 seconds to do one step.
most of time animations are about actions, steps.
(drop me)
Quote from: Sid_ on 09:45, 27 April 18
Hi
I would like to do an animation in a futur demo. I have 5 screens to switch speediest as possible.
I have a look on the gate array function 3. (ex: http://www.cpcwiki.eu/index.php/Gate_Array#Register_3_-_RAM_Banking)
is it the best strategy ?
Sid
If you can live with 4 screen animation and small code space, load screens into memory at appropriate addresses (for example $50, $4050, $8050, $c050) and use these addresses to manipulate crtc's display start address - it will flip images instantly. If you use RAM banks, you'll need to copy each screen to video ram and it will take approx. 98300 microseconds per screen i.e. you'll get max 10 frames per second.
Btw: You'll need to kill system, take over the interrupts and change screen size a bit to hide your code, but the switching will be instant and you can even run it on cpc 464.
Hi
If you want to copy 16 kilobytes from extra-ram, you can reach 11.60 frame/sec with this code.
(you can go faster but you need to unroll the code)
copy
ld (updsporg+1),sp
di
xor a
ex af,af'
ld a,4
trall
ex af,af'
updspsrc ld sp,#4000
pop bc ; 4000/4001
pop de ; 4002/4003
pop hl ; 4004/4005
pop iy ; 4006/4007
pop ix ; 4008/4009
exx
pop bc ; 400A/400B
pop de ; 400C/400D
pop hl ; 400E/400F
ld (updspsrc+1),sp
updspdst ld sp,#0000
push hl ; FFFF/FFFE
push de ; FFFD/FFFC
push bc ; FFFB/FFFA
exx
push ix ; FFF9/FFF8
push iy ; FFF7/FFF6
push hl ; FFF5/FFF4
push de ; FFF3/FFF2
push bc ; FFF1/FFF0
ld (updspdst+1),sp
dec a
jr nz,updspsrc
ex af,af'
dec a
jr nz,trall
updsporg ld sp,0
ret
To use this code, you need to sort screen datas before:
org #A000
run $
ld a,1
call #bc0E
ld bc,1000
afftst
ld a,r
and 31
add a,65
call #bb5A
dec bc
ld a,b
or c
jr nz,afftst
;
ld hl,#C000+15
ld de,#7FFF
fmtscr
ld bc,16
lddr
ld bc,32
add hl,bc
ld a,h
or a
jr nz,fmtscr
;
call #bb06
ld hl,#C000
ld de,#C001
ld (hl),l
ld bc,#3FFF
ldir
call #bb06
call copy
moimeme
jr moimeme
If you need the system, the copy function need to save and restore the exx registers.
If you want to switch with the crtc (instantly) (if you do not need more than 4 pages in main-64kb-videoram)
You do not need to hide any code :P
You have just to run your code in extra-ram and switch the offset videoram through crtc offset registers.
And you do not need to kill the system. :-\
You can do that in basic.
You just need to switch the system on extra-ram with this little code
org #a000
Switch64k
di
ld bc,#7FC7 ; copy C000-FFFF to 1C000-1FFFF
out (c),c
ld hl,#C000
ld de,#4000
ld bc,#4000
ldir
ld bc,#7FC0 ; copy 4000-7FFF to C000-FFFF
out (c),c
ld hl,#4000
ld de,#C000
ld bc,#4000
ldir
ld bc,#7FC5 ; copy C000-FFFF (4000-7FFF) to 14000-17FFF
out (c),c
ld hl,#4000
ld de,#C000
ld bc,#4000
ldir
ld bc,#7FC3
out (c),C
ld hl,#C000 ; copy the original videoram
ld de,#4000
ld bc,#4000
ldir
ld bc,#7fc4 ; copy 0000-3FFF to 10000-13FFF
out (c),c
ld hl,#0000
ld de,#4000
ld bc,#4000
ldir
ld bc,#7fc6 ; copy 8000-BFFF to 18000-1BFFF
out (c),c
ld hl,#8000
ld de,#4000
ld bc,#4000
ldir
ld bc,#7fc2
out (c),c ; switch 64k
ei
ret
With this code in basic:
10 mode 1:load "switch64k",&A000:call &A000
20 for page=0 to 3
30 out &bc00,12:out &bd00,page*16
40 next:goto 20
memory &3fff: load "screen",&4000
you will not see anything because extra ram is not displayed
You just need a little extra code to copy the screen loaded in &4000 in the main ram.
To do that, the easier method is to use C1/C3 mode of RMR
Quote from: Longshot on 20:12, 28 April 18
If you want to switch with the crtc (instantly) (if you do not need more than 4 pages in main-64kb-videoram)
You do not need to hide any code :P
You have just to run your code in extra-ram and switch the offset videoram through crtc offset registers.
And you do not need to kill the system. :-\
You can do that in basic.
You just need to switch the system on extra-ram with this little code
org #a000
Switch64k
di
ld bc,#7FC7 ; copy C000-FFFF to 1C000-1FFFF
out (c),c
ld hl,#C000
ld de,#4000
ld bc,#4000
ldir
ld bc,#7FC0 ; copy 4000-7FFF to C000-FFFF
out (c),c
ld hl,#4000
ld de,#C000
ld bc,#4000
ldir
ld bc,#7FC5 ; copy C000-FFFF (4000-7FFF) to 14000-17FFF
out (c),c
ld hl,#4000
ld de,#C000
ld bc,#4000
ldir
ld bc,#7FC3
out (c),C
ld hl,#C000 ; copy the original videoram
ld de,#4000
ld bc,#4000
ldir
ld bc,#7fc4 ; copy 0000-3FFF to 10000-13FFF
out (c),c
ld hl,#0000
ld de,#4000
ld bc,#4000
ldir
ld bc,#7fc6 ; copy 8000-BFFF to 18000-1BFFF
out (c),c
ld hl,#8000
ld de,#4000
ld bc,#4000
ldir
ld bc,#7fc2
out (c),c ; switch 64k
ei
ret
Now try to run this code on 464 :)
btw: you do not need 6 ldirs to transfer base 64k memory to additional banks
Quote from: Longshot on 20:12, 28 April 18
To do that, the easier method is to use C1/C3 mode of RMR
MMR :)
QuoteMMR (http://www.cpcwiki.eu/forum/Smileys/SoLoSMiLeYS1/smiley.gif)
:doh: of course!
Quoteyou do not need 6 ldirs to transfer base 64k memory to additional banks
Old code. ;)
Indeed, 5 is the minimum (page 1 to 7, 7 to 5 instead of 1 to 3, 3 to 5, 7 to 3).
QuoteNow try to run this code on 464 (http://www.cpcwiki.eu/forum/Smileys/SoLoSMiLeYS1/smiley.gif)
Now try to load the 4 16kb files (screen pages) from disk (or tape) from a code fragmented in the dummies zones... :)
Thanks Longshot for this answer.
I'll try it.
I also think to compress the screens and try to uncompress in ram.
The performance is awful😖