| |
johncl
Registered: Aug 2007 Posts: 37 |
Screen copy CPU intensive
I am working on a little game for the C64 and have stumbled upon a slight problem. A smooth scroller is darn CPU intensive! Its a simple sidescroller where I want to scroll the upper 18 lines. The copy required to move the character and color ram is very expensive! I use kickassembler and at first I tried this:
.macro ScrollLines(screen,from,to) {
.var half = round([to-from]/2)
ldx #0
jmp !loop+
.align $100
!loop:
.for (var i=from;i<from+half;i++) {
lda screen+1+[i*40],x
sta screen+[i*40],x
lda SCREEN_COLOR+1+[i*40],x
sta SCREEN_COLOR+[i*40],x
}
inx
cpx #39
bne !loop-
ldx #0
jmp !loop+
.align $100
!loop:
.for (var i=from+half;i<=to;i++) {
lda screen+1+[i*40],x
sta screen+[i*40],x
lda SCREEN_COLOR+1+[i*40],x
sta SCREEN_COLOR+[i*40],x
}
inx
cpx #39
bne !loop-
}
So here I unroll a full column copy in two parts (because bne wont work if I unroll whole column). This even aligns the two loops so that the bne doesnt cross any page boundaries and end up costing another cycle. But still, this routine eats up my CPU big time.
I then tried a complete unroll of a pure copy:
.macro ScrollLines2(screen,from,to) {
.for (var i=from*40;i<=to*40;i++) {
lda screen+1+i
sta screen+i
lda SCREEN_COLOR+1+i
sta SCREEN_COLOR+i
}
}
This also copies the unecessary column too that I need to copy from my map data. But this complete unroll uses almost 2/3 of the screen raster time! Even with this I have to split up my copy so the top part is copied at the bottom redraw of the refresh and the bottom part on start of next screen refresh.
Am I doing something wrong here? |
|
... 25 posts hidden. Click here to view all posts.... |
| |
Radiant
Registered: Sep 2004 Posts: 639 |
johncl: Put $35 in memory location $01 to swap out both the BASIC and KERNAL ROM areas. You'll have to use the $FFFE/$FFFF etc interrupt vectors.
Put $34 there to also swap out the IO registers at $D000-$E000. You have to enable them again once you are going to do any SID, VIC or CIA operations, of course. |
| |
Steppe
Registered: Jan 2002 Posts: 1510 |
Johncl, I think a very useful site for you is here:
http://www.the-dreams.de/aay.html
At least the zero page issue is answered there. |
| |
Radiant
Registered: Sep 2004 Posts: 639 |
Have to commend doynax on the EXCELLENT technique as well! Well done indeed! |
| |
Stainless Steel
Registered: Mar 2003 Posts: 966 |
Looks great, except for the gfx. |
| |
Oswald
Registered: Apr 2002 Posts: 5094 |
$01 usage for beginners:
http://codebase64.org/doku.php?id=base:memory_management&s=memo..
raster irq with kernal & basic off:
http://codebase64.org/doku.php?id=base:introduction_to_raster_i..
if you still want to use kernal you can do turn it back on IN the irq, and turn it off(or restore state) before exiting. If you use the kernal for reading the keys make sure to call SCNKEY once every screen refresh since this routine scans the keyboard and fills the keyboard buffer for GETIN which you call normall from the main loop to read the keys.
Make sure that your irq saves the state of $01 before changing it, and restores it before exiting. This assures that your code outside the irq can aswell safely turn the roms on and off.
This way you can turn off even the $d000 area, but that will cost you time since in all irqs you will have to turn it back on and off again. |
| |
johncl
Registered: Aug 2007 Posts: 37 |
Quote: johncl: Put $35 in memory location $01 to swap out both the BASIC and KERNAL ROM areas. You'll have to use the $FFFE/$FFFF etc interrupt vectors.
Put $34 there to also swap out the IO registers at $D000-$E000. You have to enable them again once you are going to do any SID, VIC or CIA operations, of course.
Thanks for the tips. Oswald also posted some good links that explains it all. It is nice to be able to use as much memory as possible. That kernal keyboard scan is really only needed during the non-game screens so I can swap in the kernal again for those screens. The game would benefit from the extra memory so that I can store some compressed level data there. The big challenge at the end here is to see how many levels I can squeeze into the game without any loading. :) |
| |
Radiant
Registered: Sep 2004 Posts: 639 |
johncl: And don't forget loading isn't a big deal nowadays, with several very fast and easy to use IRQ loaders around. Almost like already having the data in RAM. ;-) |
| |
Oswald
Registered: Apr 2002 Posts: 5094 |
yeah, you should rather ask for a loader source here instead of squeezing the memory and limiting the game code. |
| |
johncl
Registered: Aug 2007 Posts: 37 |
Yeah, I might try out a loader too if the game cant pack enough levels into memory. For this game project I really wanted to make a tape version and all. Its like an advanced joke where I am making a brand new version of a game I did in basic back in the 80s (which was in a terrible state). :)
Maybe the disk version will have lots of extra levels. :) |
| |
cbmeeks
Registered: Oct 2005 Posts: 78 |
@johncl
I think you and I are in the same boat. I am also working on developing a simple scroller/platformer (Metroid clone).
Last night, I was able to get one column drawn from map data. Big freaking deal...lol
Well, it has been a LONG time since I was a 6502 coder.
Anyway, my email is cbmeeks AT gmail DOT com
if you want to share ideas or whatever. Of course since you are ahead of me I will probably just be an anchor stealing ideas from you. hahaha
Seriously, I am finding the KickAssembler a real joy to use. I think that is how I was able to do it in about 20 minutes last night! But, I did unroll everything. So, I am going to figure out a cleaner/better way soon.
METROID
http://www.metroidclassic.com |
Previous - 1 | 2 | 3 | 4 - Next |