#20312 - Johnny Watson - Thu May 06, 2004 10:42 pm
After reading through most of the GBA documentation on this website, I'm unsure of a couple of things. Where the game code on the cartridge is stored, and how the Gameboy Advance knows where to load and what code to load. Does it just load instructions and keep any static allocations on the cartridge? I'm not sure how it works, for example, if I have 16KB of instruction data, and 5MB of data implemented through static arrays. Would all the instruction data automatically go into work RAM, and the static array data stays memory mapped on the cartridge? I guess what I'm getting at is, I'm confused when it comes to managing memory on the GBA, and I'm not sure how instructions and literal data within code is placed in memory.
#20315 - dagamer34 - Thu May 06, 2004 11:13 pm
Code will always start at 0x8000000 (or 0x2000000 for multiboot). From there on, the program will execute code by jumping to it, and use arrays for whatever they are needed for.
Instruction data does not automatically go into work RAM unless it is told to do so at startup (by either having a multiboot program where everything is in RAM, or by declaring variables and functions in RAM). The same goes for data.
_________________
Little kids and Playstation 2's don't mix. :(
#20316 - poslundc - Thu May 06, 2004 11:15 pm
The linkscript used in devkitadvance (and probably just about any other system as well) treats your data as follows:
- Executable code and any variables declared as "const" go into ROM.
- Any other variables go into IWRAM.
- Usually if your devkit includes a malloc() routine it will put its heap in EWRAM.
Executable code that's in ROM stays in ROM, and is read into the GBA one instruction at a time.
The big exception to this is if your game is compiled to support multiboot, in which case all of the executable code and const data is copied into EWRAM when the program is loaded.
You can manually tell the compiler to put your executable code into EWRAM or IWRAM instead of the ROM by using section attributes, or a command-line switch for GCC. In this case, the code is stored in ROM but copied into EWRAM or IWRAM when the GBA is turned on.
Edit: You win this round, dagamer34...
Dan.
#20318 - Johnny Watson - Thu May 06, 2004 11:30 pm
Thanks.
So all non-const data exists in WRAM? Will I get a significant performance increase if program instructions exist in WRAM as opposed to cartridge ROM?
#20319 - sajiimori - Thu May 06, 2004 11:37 pm
Code in IWRAM, especially 32 bit ARM code, runs significantly faster than code run from ROM. It's typical to put a few speed-critical routines in IWRAM when performance starts to degrade.
#20323 - poslundc - Fri May 07, 2004 1:00 am
Code in EWRAM, however, will typically run somewhat slower than from the ROM (depending on how often the code branches).
There is a huge difference between the performance of the fast Internal WRAM (which you only have 32K of) and slower External WRAM (which you have 256K of).
As sajimori says, it's not something worth worrying about until it becomes necessary to optimize a few speed-critical routines. Until then, just compile all of your code as Thumb and leave it to run in ROM (unless it is a multiboot game, in which case it has to run from EWRAM).
Dan.
#20329 - Johnny Watson - Fri May 07, 2004 9:10 am
How would I tell certain instruction sections (ie: functions) to explicitly go to IWRAM for execution?
#20334 - Akolade - Fri May 07, 2004 5:53 pm
I found this page useful:
http://www.devrs.com/gba/files/gbadevfaqs.php#LongBranch
method 2 seems an easy way to do it. also, search around these forums for info about placing routines in IWRAM.[/url]
#20343 - Johnny Watson - Sat May 08, 2004 12:13 am
Thank you a lot. You were all very helpful, though I suppose I should have searched a bit harder.
#20358 - ScottLininger - Sat May 08, 2004 9:24 pm
Guys,
Is there any reason to put code in IWRAM besides performance? Here's a function from a library that's been causing me some compile headaches... And I'm trying to understand if the routine being in IWRAM is necessary.
From the Header:
Code: |
#define SER_SECTION __attribute__((section(".iwram"), long_call))
#ifndef REG_BASE // no mygba.h included
#define REG_BASE 0x4000000
#define REG_SIOCNT (REG_BASE+0x128)
#define REG_RCNT (REG_BASE+0x134)
#define REG_SIOMULTI0 (REG_BASE + 0x120)
#define REG_SIODATA32 REG_SIOMULTI0
#define REG_SIOMULTI1 (REG_BASE + 0x122)
#define REG_SIOMLT_SEND (REG_BASE + 0x12a)
#define XFER_ERROR_SUCCESS 0
#define XFER_ERROR_TIMEOUT 1
#define RW_ERROR_SUCCESS 0
#define RW_ERROR_XFER_ERROR 1
#define RW_ERROR_TIMEOUT 2
#define RW_ERROR_CMD_NAK 3
#define RW_ERROR_CHKSUM_ERROR 4
#endif
u32 SER_SECTION stick_xfer32(u32 send); |
The routine:
Code: |
u32 SER_SECTION stick_xfer32(u32 send)
{
int timeout=0x100000;
stick_xfer_error=XFER_ERROR_SUCCESS;
*(vu16*)REG_RCNT=0;
*(vu16*)REG_SIOCNT=0x1000;
*(vu32*)REG_SIODATA32=send;
*(vu16*)REG_SIOCNT=0x1080;
while(timeout--)
if(!((*(vu16*)REG_SIOCNT)&0x80)) break;
*(vu16*)REG_SIOCNT=0x1008;
if(!timeout) {
stick_xfer_error=XFER_ERROR_TIMEOUT; return 0;
}
return *(vu32*)REG_SIODATA32;
} |
Just curious...
:)
Scott