#11548 - poslundc - Fri Oct 10, 2003 4:20 pm
Two questions relating to EWRAM:
1. If THUMB instructions load from the ROM and the compiler automatically puts local and global variables in IWRAM, is anything put into EWRAM at all?
2. Is there a method for putting C variables into EWRAM? I suppose if nothing gets put there by the compiler then I could just take a master pointer to 0x02000000 and dish it out myself, but it seems probable to me that there is some kind of compiler directive to use EWRAM instead of IWRAM, and I just can't find it.
Thanks,
Dan.
#11549 - DekuTree64 - Fri Oct 10, 2003 5:09 pm
EWram is completely empty by default. You can tell the compiler to put things there with
#define IN_EWRAM __attribute__ ((section (".ewram")))
and then in your header do like
extern u32 array[] IN_EWRAM;
And you can use the -Map name.map linker option to check and make sure where everything is.
And that will start at 0x2000000 and grow upward, so unless you have 256K of stuff to put there, you can use the upper part as a stack. Just set a global pointer to 0x2040000, and whenever you need to store something, subtract the size of it from your pointer and store it there. That's exactly how the main stack works too.
Oh, and if you have a non-speed-critical-but-often-called function, it's good to put it in EWram because it takes less battery power than reading from ROM. You can even copy it by hand to your EWram stack and call it from there with a function pointer so you can swap things in and out as needed. Or you could use overlays, but I never could get them to work right.
_________________
___________
The best optimization is to do nothing at all.
Therefore a fully optimized program doesn't exist.
-Deku
#11556 - tepples - Fri Oct 10, 2003 8:02 pm
However, if you make an uninitialized array and put it in EWRAM, GCC will convert it to an initialized array, wasting ROM space. This has something to do with the linker's support for only one BSS (uninitialized) section, which must be contiguous.
And there is one exception to the "nothing goes into EWRAM by default" rule: programs compiled to run from EWRAM, using less battery power and allowing multibooting. To trigger this behavior of the linker, insert the following line into one of your source code files: Code: |
int __gba_multiboot; |
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.
#11577 - Quirky - Sat Oct 11, 2003 5:56 pm
tepples wrote: |
However, if you make an uninitialized array and put it in EWRAM, GCC will convert it to an initialized array, wasting ROM space. |
Is there a work around for that which doesn't require pointer-to-ewram hacks? or, alternatively, a way to get data from a binary file in ewram? At the moment I use .all.rodata.o to add binary files in rom, but is there an equivalent something like .ewram.o?
#11579 - tepples - Sat Oct 11, 2003 6:43 pm
You could write an abstraction around the pointer-to-ewram hacks. In fact, DevKit Advance automates this using a facility called malloc().
WARNING: If you're using multiboot, DKA r4's malloc() will allocate addresses that overlap your program. It seems DKA r5b3 (which I use) has fixed this, but I'm not entirely sure.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.
#11595 - regularkid - Mon Oct 13, 2003 7:37 am
It doesn't sound like EWRAM is very useful except for what DekuTree64 said about saving some battery power. Also, according to the docs out there, it is slower to access than ROM in most cases because of wait states. Why did Nintendo include it? I'm sure there must be a good reason, I just can't seem to see what that is. Anyone have any ideas?
_________________
- RegularKid
#11596 - KashinKoji - Mon Oct 13, 2003 7:48 am
tepples wrote: |
However, if you make an uninitialized array and put it in EWRAM, GCC will convert it to an initialized array, wasting ROM space. This has something to do with the linker's support for only one BSS (uninitialized) section, which must be contiguous.
And there is one exception to the "nothing goes into EWRAM by default" rule: programs compiled to run from EWRAM, using less battery power and allowing multibooting. To trigger this behavior of the linker, insert the following line into one of your source code files: Code: | int __gba_multiboot; |
|
Forgive me if this is a stupid question, but how/why does this waste rom space? What if you make an initialized or const array and then force it into ewram using the macro someone posted above? My thinking is you will have faster and more battery efficient access to the data in that array, and you could even reload it (provided it is not declared const) at opportune times depending on the data you need.
I've been trying to tackle a way to efficiently access a lot of complicated sprite animation data (different sequence lists and delays, as well as different collision bounds per frame). Previously I always used a pointer to the data in ROM for animation sequences, but I was thinking I could load the data from ROM into variables declared in EWram for faster access when "initializing" a new object for the screen. Is this totally off base? I am admittedly not that familiar with the way the memory sections work, but I do know that I have too much info to declare it all in IWram, and that a pointer to the data in ROM will probably slow me down because of read times... doing a memcpy on a per frame basis into IWRam would also involve a ton of overhead.
I wish I could read the nintendo hardware spec. I'm sure many games have this kind of problem totally solved.
#11597 - KashinKoji - Mon Oct 13, 2003 7:50 am
regularkid wrote: |
It doesn't sound like EWRAM is very useful except for what DekuTree64 said about saving some battery power. Also, according to the docs out there, it is slower to access than ROM in most cases because of wait states. Why did Nintendo include it? I'm sure there must be a good reason, I just can't seem to see what that is. Anyone have any ideas? |
One good reason I can think of right away is head to head link up games that involve one cartridge. Is it really slower to access than ROM? I've never read that... Can you point me to the doc?
#11599 - torne - Mon Oct 13, 2003 8:36 am
EWRAM is not slower than ROM, unless you set your ROM wait states very very low. It takes 3 cycles to access a 16-bit word from EWRAM, 6 for a 32-bit word. Using default wait state settings in ROM it takes 5 and 8 respectively; using 3/1 wait states (normal for most commercial games) it takes 4 and 6. However, using 2/1, the fastest setting which may not work on flashcarts reliably takes 3 and 5, allowing you to shave one cycle from 32-bit reads (but 16-bit reads are still slower) - whether this is worthwhile depends on whether 2/1 is stable for you. =)
Of course, this is somewhat up in the air; the reason there is EWRAM (other than multiboot) is because you *can't write to ROM* so you can't keep variables there! =)
IWRAM will fill quickly in any large app, mostly with the stack (you can move the stack to EWRAM but push/pop will be much slower). There's just not enough space to put all your modifiable data in there after a point, so you have to use EWRAM. =)
#11600 - Paul Shirley - Mon Oct 13, 2003 1:12 pm
removed
Last edited by Paul Shirley on Sun Mar 28, 2004 10:11 pm; edited 1 time in total
#11606 - KashinKoji - Mon Oct 13, 2003 9:19 pm
I think I worded my question incorrectly, but that is OK, because that other thread you linked to answered my question exactly. I think for what I want to do the ewram static allocation tepples outlined is going to be just right, and it is ok if I have some redundancy between that and the data in ROM. What I really wanted to know was how to use all that ewram space for a ton of variables and avoid reading them all from ROM all the time. Thanks.
#11635 - regularkid - Tue Oct 14, 2003 11:29 pm
My mistake. I was looking at the CowBite hardware spec and was looking at the DMA cycle times, but was mistakingly comparing the times from EWRAM and ROM wait state 0. What is the default wait state for ROM? Also, how do you change the wait state. I'm not real clear on exactly what the wait state is. Can someone explain? Thanks!
_________________
- RegularKid
#11637 - DekuTree64 - Tue Oct 14, 2003 11:58 pm
Check this post: http://forum.gbadev.org/viewtopic.php?t=2211
I would explain it, but it'd just be the same things I said there^_^
_________________
___________
The best optimization is to do nothing at all.
Therefore a fully optimized program doesn't exist.
-Deku