gbadev.org forum archive

This is a read-only mirror of the content originally found on forum.gbadev.org (now offline), salvaged from Wayback machine copies. A new forum can be found here.

DS development > libfat/dldi corrupting memory

#158487 - ingramb - Thu Jun 12, 2008 5:19 am

I have code (more or less) like this:

***
NeoSystem.h

typedef struct {
u32 val0;
u32 val1;
u32 val2;
...
} TNeoContext;

register TNeoContext* g_neo asm("r7");

***
NeoSystem.c

TNeoContext g_neoContext;

//call this at program start
void init() { g_neo = &g_neoContext; }

int systemOpen(const char* szFile)
{
u32 testVal = g_neo->val0;
int fd = open(szFile, O_RDONLY);
ASSERT(testVal == g_neo->val0); //!!!!!!! this fails!
return fd;
}


On my max media dock, everything is fine. On my ninjapass x9, the above ASSERT fails. Somewhere inside open, the value of g_neoContext is changing. I've moved g_neoContext back and forth between DTCM and main ram, and get the exact same behavior. So the value getting corrupted does not depend on a specific memory address. What else could be going wrong?

#158488 - eKid - Thu Jun 12, 2008 6:15 am

You're code confuses me. :\
Why are you using "r7" ?

#158489 - ingramb - Thu Jun 12, 2008 6:28 am

This is code from NeoDS which interfaces with the Cyclone cpu core. Cyclone uses r7 as a pointer to its context. In the actual NeoDS codebase, the first element of TNeoContext is the cyclone context. So memory handlers written in assembly called from cyclone can acces g_neo via r7 without having to grab the pointer from memory.

But none of this is important to the issue at hand =) The only thing that matters is that g_neo is a global register variable stored in r7.

#158490 - Dwedit - Thu Jun 12, 2008 6:54 am

r4-r7 are supposed to be preserved across function calls. If not, there's a broken function. Try saving and restoring r7.
_________________
"We are merely sprites that dance at the beck and call of our button pressing overlord."

#158491 - ingramb - Thu Jun 12, 2008 6:57 am

u32 testVal = g_neo->val0;
int fd = open(szFile, O_RDONLY);
g_neo = &g_neoContext; //this line doesn't help...
ASSERT(testVal == g_neo->val0); //!!!!!!! this fails!
return fd;

Resetting the value of r7 doesn't help. It seems that the actual memory is being changed. This is really confusing me =(

#158492 - Dwedit - Thu Jun 12, 2008 8:07 am

Is malloc destroying your global data? Maybe you need to use modified gba_nds_fat, which never calls malloc.
_________________
"We are merely sprites that dance at the beck and call of our button pressing overlord."

#158493 - ingramb - Thu Jun 12, 2008 8:15 am

Looks like it's interrupt related. Disabling interrupts around fat calls fixes things. Even though I don't have any interrupts that should be doing anything at that point...

Anyway, thanks for the suggestions guys.

#158494 - eKid - Thu Jun 12, 2008 9:43 am

You probably should be writing the functions in assembly (the ones that interface with the stuff), r7 may be getting overwritten somewhere.

An interrupt handler may overwrite r7 easily. r7 is an easily accessed register so the compiler may generate code that uses it too.