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 > Strange problem, game locks up.

#21841 - expos1994 - Mon Jun 07, 2004 3:53 pm

Hello,

I am having a weird problem with my code. It has held me up since yesterday afternoon. What happens is I write some text to background 2 (mode 0). Then I wait for the A or B button to be pressed. Then I clear the background and write some more text to the same background. Then again I wait for A or B.

After this happens, the code freezes. If I swap around a few lines here and there I can get it to basically do a restart of main(). I have no idea why this is happening. Logically it seems fine. I have tried so many different things and have gotten some interesting results. None are the ones I want however.

If I take out the code that waits for button presses and the code that writes the background text, and just put some simple assignments in the procedure, it will run through it without problems. So I'm guessing it is one of those things that is breaking my code.

Here's basically what I'm doing (I don't have the exact code since I'm at work. But maybe you guys won't need it. I can post it at another time.

Code:


void dolandmark()
{
            strcpy(message, "This is my message ... blah blah");
            DrawWindow(message, 0,5,20);
            waitforAB();
            while(!(KEYS & KEY_A); //I put this in to try and solve my problem.  It seems to help but it still freezes right below this.

            //I do a little bit here.  Some assignments

           strcpy(message, "The second message");
           DrawWindow(message, 0,5,20);
           waitforAB();
           while(!(KEYS & KEY_A);

}

//What I'm expecting now is that it would return to the calling function ... main(), but it freezes or in some cases restarts at the beginning of main.  In this state, it freezes.  This is very frustrating.  It is acting the same way on the hardware and VBA.


My waitforAB() basically is a loop that won't break; until A or B is pressed. And the while() I added under that is to wait until A (I'll add B later), is unpressed.

I use this combination in other spots in my code... DrawWindow()/waitforAB(), and it has no problem. It works fine. But in this particular function, called from main. It just won't allow it.

Can anyone provide insight into this? It's frustrating because it seems to have a mind of it's own, but I think I'm just not quite understanding something.

Thanks for any help. If you need more code, I'll post it.

--Chris

#21842 - tepples - Mon Jun 07, 2004 4:11 pm

You expect it to go back to main(). What are you doing in main() after that point? Remember that if main() returns, the init code will (not exactly predictably) freeze or reset the GBA.
_________________
-- Where is he?
-- Who?
-- You know, the human.
-- I think he moved to Tilwick.

#21843 - poslundc - Mon Jun 07, 2004 4:12 pm

expos1994 wrote:
If I take out the code that waits for button presses and the code that writes the background text, and just put some simple assignments in the procedure, it will run through it without problems. So I'm guessing it is one of those things that is breaking my code.


Well, then, post the code for those routines... :P

Also, post the main loop that calls dolandmark().

Dan.

#21844 - dagamer34 - Mon Jun 07, 2004 4:26 pm

Yeah, I can see a couple of potential problems with your code.

Is KEYS defined as a volatile u16? If not, then the code will definitely hang when you check for a key press.

I don't think we can really help you until we see more code.
_________________
Little kids and Playstation 2's don't mix. :(

#21846 - expos1994 - Mon Jun 07, 2004 4:49 pm

Hey thanks for the replies so far.

Here's how KEYS is defined. I think I got this from ThePernProject. Not sure it would have been awhile ago. I don't see an volatile keyword:

Code:

int* KEYS = (int*)0x04000130;


Waiting for the keypress does 'appear' to work in other areas of my code.

I will definitly post more code when I get home. The routine for DrawWindow() is a little lengthy and basically involves changing background tiles. It always worked for me before, and it still does. It displays the window, but it just crashes afterwards.

Sorry about not having the code. I was hoping that you guys would take a look at what I was doing and say "Yeah dumba**, here's your problem, you can't do this..." I've looked at it over and over, and can't figure out why it would go back to the top of main(). The call to the dolandmark() procedure is in a while(1) loop in main. Any ideas on what I could do to cause my code to break out of that loop.

I'll post the code later... thanks for the replies so far.

#21847 - niltsair - Mon Jun 07, 2004 4:57 pm

Declare keys as : volatile int* KEYS = (int*)0x04000130; instead.
Do the same for all variables that are pointing to registers. It prevent the compiler from doing some 'optimisation' that don't consider that thoses values can changes outside of your code (interupts, hardware).

Also make sure your main() is included in a loop from which you can never exit.
_________________
-Inside every large program is a small program struggling to get out. (Hoare's Law of Large Programs)
-The man who can smile when things go wrong has thought of someone he can blame it on. (Nixon's Theorem)

#21853 - expos1994 - Mon Jun 07, 2004 11:48 pm

Hi, first of all thanks for all the help.
To my surprise, my code executes the same with volatile or not on the KEYS definition. I changed it to volatile, because you make a good point. And I will remember that with future problems.

An update on my problem:

Well I struggled for a looooong time on this. Since yesterday afternoon. I have finally discovered the cause. The message I was passing in my sample code I posted was actually much larger. I guessed on the size when I defined it. As it turned out, my guess was a little short.

I have no idea why (I'd like to know, but I don't want to spend the time trying to figure it out.), but when I changed the char message[60]; to char message[65], the code executed as expected. And I'm very relieved.

Wow, what a mystery that was. I figured it out by passing little strings. They worked, so I knew it was a problem with the string I was passing.

Well anyways, thanks for the help. If you know why that happened, let me know.

#21856 - Foxy - Tue Jun 08, 2004 1:19 am

niltsair wrote:
Declare keys as : volatile int* KEYS = (int*)0x04000130; instead.


Keys should be declared as volatile unsigned short *

#21870 - johnny_north - Tue Jun 08, 2004 4:15 pm

expos1994-

One answer to your question is to examine the largest string you're trying to copy into

char message[60];

Obviously, if you write to memory off the end of this array you can expect undefined behavior. (If you're working with c style arrays don't forget to include the null character in your count of characters).

Less obvious is if your misusing memory somewhere else, expanding this array (even though you may or may not be using the extra 5 characters) may seem to correct the problem.

Take my advice - even though you may not want to spend the time pin pointing the problem - as your code base grows, finding the bug will become harder. Best to figure it out now.