GP32 Gigadrive Hang


fdave

Final Dave
Joined
Apr 20, 2004
Messages
331
Website
www.finalburn.com
Okay think I may have figured out this GigaDrive hang....

It's got something weird to do with when the emu it running fast, like not much to draw on the screen. Shows up a lot in Ghouls 'N' Ghosts at the start of level 1. So I *think* it's to do with when the time gone is less than one frame...

This hangs:
Timer=Frames=0;
while (!quit)
{
int ticks=0,i=0;

now=Timer;
ticks=now-done; done=now;

if (ticks<1) continue; //test

if (ticks>10) ticks=10; // Limit frame-skipping

for (i=0; i<ticks-1; i++) quit|=InputFrame();

if (ticks>=1)
{
// Point to the top-left of the screen:
OutLine=(unsigned short *)DrawSurface[Flip].ptbuffer;
OutLine+=232;
PicoScan=EmulateScan;

quit|=InputFrame();

//GpSurfaceFlip(DrawSurface+Flip); Flip^=1;

Frames++;
}

PicoScan=NULL;
}



And this works (notice the difference in the way the done=now is only done if the time passed is >0).

Timer=Frames=0;
while (!quit)
{
int ticks=0,i=0;

now=Timer;
ticks=now-done;

if (ticks<1) continue; //test

if (ticks>10) ticks=10; // Limit frame-skipping

for (i=0; i<ticks-1; i++) quit|=InputFrame();

if (ticks>=1)
{
// Point to the top-left of the screen:
OutLine=(unsigned short *)DrawSurface[Flip].ptbuffer;
OutLine+=232;
PicoScan=EmulateScan;

quit|=InputFrame();

//GpSurfaceFlip(DrawSurface+Flip); Flip^=1;

Frames++;
}

PicoScan=NULL;

done=now;
}


Now can anyone think why? There is subtley there but I think in both it should work. Any ideas as to what I (originally) did wrong to cause these hangs is welcome! Either way, am going to do some extensive testing (i.e. playing my GP32 :) in the next few days to see if the GigaDrive hangs are *really* gone. It does look promising though...
 

Robster

Dodgy hardware mod maker
Joined
Jul 8, 2003
Messages
439
Location
New Zealand
Website
www.cobbleware.com
How is Timer updated? If it's updated in the InputFrame() function, then as soon as you have a short frame, ticks will be zero, and Timer will never be updated again.

If that is the case, your "fix" won't actually fix it :(.

If Timer is updated in a timer interrupt function or some such, make sure it's declared volatile so that its value will be checked every time it is referenced.

Nice work on cyclone btw, it's an impressive piece of work! I was thinking, would doing it in Thumb mode speed it up (because of less memory cycles fetching instructions)? It would require some changes to your arm9 register mapping, but might it be worth it?
 

gca

Still Fresh
Joined
Jan 2, 2004
Messages
2
Hello FDave,

Thanks for your great emu, COOOOOOOOOOOL!!!
And good luck with your work!!! (sorry for my bad english, im spanish!)

:lol: :lol:



DemoMan'04
 

fdave

Final Dave
Joined
Apr 20, 2004
Messages
331
Website
www.finalburn.com
Robster posted on May 17 2004 at 03:05 AM said:
How is Timer updated? If it's updated in the InputFrame() function, then as soon as you have a short frame, ticks will be zero, and Timer will never be updated again.

If that is the case, your "fix" won't actually fix it :(.

If Timer is updated in a timer interrupt function or some such, make sure it's declared volatile so that its value will be checked every time it is referenced.

Nice work on cyclone btw, it's an impressive piece of work! I was thinking, would doing it in Thumb mode speed it up (because of less memory cycles fetching instructions)? It would require some changes to your arm9 register mapping, but might it be worth it?

Source is on www.finalburn.com in the Cyclone source section.
Timer is updated in a function called by the GpTimer functions. It's declared volatile.

The only thing I could think of is maybe optmisation is so high that the compiler is ignoring the volatile keyword, or assigning 'done' directly from Timer, which it should not do of course, but who knows what craziness GCC could do.


About Cyclone - thanks! I did try, very early on, to include Thumb support, however it soon proved very difficult - even for the basic opcode dispatch you need to use many registers, one for the jump table, one for the opcode number, one for the cycle counter and one for the cpu context. That's 4 out of 8 lo-registers down the drain even before you've even emulated anything! The conditional execution is a speedup too which would be lost in Thumb.

I then realised that the GP32, Pocket PC and mobile phones I think have 32-bit memory anyway (perhaps you'd like to confirm this for me though, I am not sure) so the only gain would be for GBA in ROM. I eventually decided it probably wasn't worth compromising emulation speed for GP32, Pocket PC etc just for the sake for one 16-bit system, so took out the Thumb limitation. It was also a sanity-saver too :)
 
Last edited by a moderator:

Robster

Dodgy hardware mod maker
Joined
Jul 8, 2003
Messages
439
Location
New Zealand
Website
www.cobbleware.com
Oh yeah- I'd forgotten about the conditional execution thing :)

Memory in the GP32 is 16-bit though, that was why I wondered about Thumb mode in the first place. I think you've killed that idea now!
 

fdave

Final Dave
Joined
Apr 20, 2004
Messages
331
Website
www.finalburn.com
Robster posted on May 17 2004 at 10:47 AM said:
Oh yeah- I'd forgotten about the conditional execution thing :)

Memory in the GP32 is 16-bit though, that was why I wondered about Thumb mode in the first place. I think you've killed that idea now!


Is it??? What about on Pocket PC?

How on earth does Cyclone run so fast if it's 16-bit?
 
Last edited by a moderator:

Robster

Dodgy hardware mod maker
Joined
Jul 8, 2003
Messages
439
Location
New Zealand
Website
www.cobbleware.com
Well, by 16-bit I mean that there is one RAM chip and it has 16 data signals. The ARM chip still uses 32-bit words, so every instruction fetch involves two read cycles. Being SDRAM, the extra read cycle is pretty fast, but the effect is still very noticeable.

Other platforms probably have 32-bit wide access to the RAM. It kinda makes sense, really, to have a 32-bit data bus on a 32-bit machine :)
 
Top