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.

Coding > [bonk] Gamepak mem, pointers and my fried brain..[/bonk]

#35000 - wbochar - Sat Jan 29, 2005 5:27 am

Ok. Before the pointers guide's, the rtfm's and reading xyz. I looked and I have a headache and I have done soo many spins that I am not sure what is right or wrong.. Here is the deal..

Saving to gamepak memory.. I can save, but when I try to verfiy the data programattically it never works.. though after looking at the emu sav file its does save the header.. I know this is a pointer problem.. but I am not sure how to go about fixing it..
Code:

   u8 *pSaveMemory = GAMEPAK_RAM;
   char *SaveHeader="KHSAVE";
   int SaveHeaderGood;

   SaveHeaderGood=1;

   int i;

   // If there is no Save Game header Data create a high score table

   for (i=0;i<strlen(SaveHeader);i++)
   {
   if ((u8)*pSaveMemory+i != *SaveHeader+i)
   {
      SaveHeaderGood=0;
   }
   }


this always returns false. I have tried what feels like everything, including the 1000's of monkeys tapping keys in case I get either the right combonation or the next great novel.

Head hurts.. please help..

#35001 - DekuTree64 - Sat Jan 29, 2005 5:51 am

Hmm, I'm not positive, but that string may not actually be claiming stack space, and is overlapping with the SaveHeaderGood variable and getting overwritten. Try this:
Code:
char SaveHeader[7]="KHSAVE";

And if that doesn't help, try printing the data yoyu're checking on the screen so you can look at it, or just store them out in memory at some specific address so you can look at the values in VBA's memory viewer. Like,
Code:
   for (i=0;i<strlen(SaveHeader);i++)
   {
      // Save the values we're about to compare out in the middle of EWRAM
   ((u8*)0x2010000)[i] = (u8)*pSaveMemory+i;
   ((u8*)0x2010010)[i] = *SaveHeader+i;

   if ((u8)*pSaveMemory+i != *SaveHeader+i)
   {
      SaveHeaderGood=0;
   }
   }

_________________
___________
The best optimization is to do nothing at all.
Therefore a fully optimized program doesn't exist.
-Deku

#35004 - sajiimori - Sat Jan 29, 2005 7:19 am

The pointer occupies the appropriate amount of stack space.

Unary * binds more tightly than +, so you are repeatedly reading the first char of each string. If you mean array access, just use [].

#35025 - wbochar - Sat Jan 29, 2005 3:27 pm

Code:

u8 *pSaveMemory = GAMEPAK_RAM;
   char SaveHeader[]="KHSAVE";
   int SaveHeaderGood;
   SaveHeaderGood=1;
   int i;

   // If there is no Save Game Data create a high score table
   for (i=0;i<strlen(SaveHeader);i++)
   {
   if (pSaveMemory[i] != SaveHeader[i])
   {
      SaveHeaderGood=0;
   }
   }
   
   if(SaveHeaderGood==0)
   {
      //create a header (KHSAVE)
      for (i=0;i<strlen(SaveHeader);i++)
      {
         pSaveMemory[i]=SaveHeader[i];
      }
      //Load in bogus top 5 default highscores

   }
   else
   {
   
   pSaveMemory[0]=0x00;
      
   }



this is the code from the suggestions.. it compiles but doesnt work. to see if the 'KHSAVE' is successfully found, I write a 0x00 to the start of mem (where the K is). So If I run the program without a save or proper header it will create a new header -- if it is there, it will make it invalid with a 0x00 at the begining. I run the game, check to see that the sav file has the right text, then run it again to see if the code alters the header to show that it found the header.

#35047 - denopqrihg - Sat Jan 29, 2005 9:03 pm

I don't know if this is the case, but gbatek says that code in ROM can't read from SRAM. So if your code is in ROM (which probably isn't), move it to IWRAM or somewhere.

#35107 - gb_feedback - Sun Jan 30, 2005 3:03 pm

Strange, the code looks ok to me. Whenever this kind of thing happens I resort to desperate casting methods, like:

Code:
   if ( (u8)pSaveMemory[i] != (u8)SaveHeader[i] )
   {
      SaveHeaderGood=0;
   }


Always worth a try.
_________________
http://www.bookreader.co.uk/

#35651 - Morloth - Tue Feb 08, 2005 11:57 pm

Hi there,

I wrote a simple program to demonstrate what is going wrong, the problem is basically that you are dereferincing the pointer and than add i to the value it is refering to rather than the move the pointer and than dereference. Let me explain:

Code:

*SaveHeader+i


What this does is this (*SaveHeader) + i; So it takes the first character the pointer points to "K", and add i to this character. Obviously this is not prefered. So you should use parantes like this:

Code:

*(SaveHeader + i)


To let he pointer point to the next character and dereference this character. Take a look at the following application and try it for yourself :).

Code:

#include <iostream.h>
#include <string.h>
#include <stddef.h>

int main(void) {

   typedef unsigned char u8;

   char *niceChar = "testing";

   size_t i;

   // Display the values
   for (i = 0; i < strlen(niceChar); i++)
   {
      cout << *niceChar + i <<                  // Not good :x
            ' ' << *(niceChar + i) << endl;         // Good :)
   }

   return 0;
}


So basically I think your code should look something like this:

Code:

...

for (i=0; i<strlen(SaveHeader); i++)
{
   if (*(pSaveMemory+i) != *(SaveHeader+i))
   {
      SaveHeaderGood=0;
   }
}


You may even want to use arrays, if you find it prettier:

Code:

for (i=0; i<strlen(SaveHeader); i++)
{
   if (*(u8*)pSaveMemory[i] != *(u8*)SaveHeader[i])
   {
      SaveHeaderGood=0;
   }
}


In the last block of code I casted both points to a u8*, just to make sure C doesn't get confused with 2 different data types. I'm not sure if it's necessary, but you can't be to sure =).

Hope it helps!

#35653 - sajiimori - Wed Feb 09, 2005 12:24 am

Morloth, his revised code already used proper array indexing.

wbochar, your code looks fine to me too. You're comparing u8s with chars, but that shouldn't cause a problem here.

Misc stuff: indent things that are inside braces, and use strcmp and strcpy instead of writing them inline.
Code:
if(strcmp(pSaveMemory, SaveHeader))
{
  strcpy(pSaveMemory, SaveHeader);
}
else
{
  pSaveMemory[0] = 0;
}

#35675 - Morloth - Wed Feb 09, 2005 10:57 am

sajiimori, you are right. I'm sorry, I obviously misread your post...

#36809 - wbochar - Wed Mar 02, 2005 1:28 am

This is really getting on my nerves..

I can write data to the gamepak memory, but when I try to read back to verify I get completely different information. Its really annoying.

Sajiimori -- the strcopy is not 8bit compatible (i think) it will screwup copying to gamepak mem.

I am stuck -- maybe this is an issue with emulation -- but how many other people have done gamepak read/write? Someone has to have gotten this work.. what am I doing wrong?

wbochar

#36812 - tepples - Wed Mar 02, 2005 1:39 am

For one thing, code that directly accesses SRAM should be in EWRAM, not in ROM. There's probably something to do with the address decoding that's unreliable on real carts.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.

#36817 - wbochar - Wed Mar 02, 2005 2:41 am

The code i've written can write to the sram, just cant seem to reliably read from it. This is all of course done in emulation -- I havent tried to run this on my ez-cart II..yet..

I am going to look into the ewram method but I am not sure how to begin :).. Time for some more reading..

wbochar

#36839 - sasq - Wed Mar 02, 2005 9:04 am

I've read/written to SRAM without problems - you just have to remember to not use libc-functions for anything - strlen, strcpy, memcpy etc may all be optimized to read or write more than 8-bits at a time.

#36852 - tepples - Wed Mar 02, 2005 2:34 pm

Search this forum for bytecpy(), a memcpy() replacement , and stick the code in EWRAM using a section attribute.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.