Path: chuka.playstation.co.uk!news From: "Peter Armstrong" Newsgroups: scee.yaroze.freetalk.english Subject: Re: weird behaviour in vsync callback Date: Wed, 20 Feb 2002 18:21:03 -0000 Organization: PlayStation Net Yaroze (SCEE) Lines: 78 Message-ID: References: <01c1ba1d$77e99820$57a1933e@pal-s-omnibook> NNTP-Posting-Host: modem-35.angband.dialup.pol.co.uk X-Priority: 3 X-MSMail-Priority: Normal X-Newsreader: Microsoft Outlook Express 5.50.4133.2400 X-MimeOLE: Produced By Microsoft MimeOLE V5.50.4133.2400 The problem is due to the global pointer register, which is used to access x, being invalid inside a callback routine. Below is a snippet from the CW docs on the subject. Writing Interrupt Routines Many PlayStation programs install interrupt tasks. When writing an interrupt task in CodeWarrior, you consider how to deal with global variables in interrupt routines. Global Variables in Interrupt Routines The CodeWarrior C compiler assigns globals into program sections based upon size. If a variable is of a size equal to or less than the size threshold specified in the MIPS Target settings panel, it will be placed in the .sdata (for preinitialized global data) or .sbss (for uninitialized global data) section. Otherwise, the global variable will be placed into the .data or .bss section. If a global variable is placed into the .sbss or .sdata sections, it is accessed using an offset from the gp register. The compiler assumes that the gp register is always valid. In interrupt task code, this is not correct. There are two ways to solve this problem. 1. Make sure that all global variables accessed in an interrupt rou- tine are in the .data or .bss sections. 2. Save or restore the GP register in your interrupt routine. The linker variable _gp contains the value that the compiler expects to be in the gp register at all times. Thus, using ASM{} statements, you can save and restore the gp register in your code. ------- I'm not sure how you'd go about the first method in GCC, but for the second, if you add the line __asm__ volatile ("la $28, _gp"); at the start of your callback function you'll be able to access global variables. HTH, Peter "pal" wrote in message news:01c1ba1d$77e99820$57a1933e@pal-s-omnibook... > In the following code x never gets set to 2. I can't understand why. Any > idea? > Note: the commented out "puts" is here to check that f actually gets > executed: if you uncomment it, something gets printed (although not the > specified string). I wouldn't expect it to work properly under the > constraints of a vsync callback, it's just a test. > Oddly, I have some more complex code that does exactly the same thing, but > included in my game, and it happens to work properly! > > pal > > #include > #include > > int x = 0; > > void f() { > x = 2; > //puts("x"); > } > > main() { > static int i; > > printf("%d\n", x); > VSyncCallback(f); > for (i = 0; i < 3*50; i++) VSync(0); // could be just one time but you're > never sure ;) > printf("%d\n", x); > > x = 1; > printf("%d\n", x); > } >