slaanesh said:
So how do you easily detect this? Well the easiest and possibly quickest way is NOT to detect it; rather know where it occurs. This means that some one has to discover where they are and provide the necessary information. ie. game_config.txt
Other emulators have done this kind of thing in the past - PCEAdvance: the PC Engine emulator for the GBA is one that comes to mind.
Detecting these kind of loops on the fly could possibly also done. I think some of the MAME CPU emulators can do this.
There are probably other methods but I think having a database is a good way of doing this for now.
This works fine for games that match that list exactly. What to do about the ones that don't though? There are allot, and the ones I have seem to fall into that catagory unfortunatly
If the emu can't detect on the fly maybe there could be some kind of utility that does it once and then adds an entry into that list maybe? That does sound like work though. What do you think would be a good solution for these other ROMs?
What do you mean by games falling under that category? Do you mean different regions or versions of the games there, or different games altogether? Because if you mean different games then chances are good that they don't belong in that list. For alternate versions/regions of what's on there the best solution is to get someone to just find them and add them.
Detecting idle loops statically would be very difficult to flat out impossible a lot of the time. Dynamic analysis might give some good hints but if it messes up it could break the game.
It's true other emulators do automatic idle loop detection, but it's either because the games use very simple idle loops, or they use very standard ones (so there's a few specific patterns that all games use). A lot of the ones I've seen in GBA games are very complex, they'll make function calls inside them for instance. They're not usually like the vcount polling loops you see in demos.
EDIT: I looked at how PicoDrive does it (notaz, please tell me if I'm wrong), and I saw two methods employed:
One thing it does is checks to see if an I/O register is being polled a lot, and if it is, stops the CPU until an event occurs. This doesn't involve checking the code at all (which is expensive for an interpreter).
Unfortunately most GBA games seem to have their idle loops poll local memory that's modified due to interrupts, rather than by reading I/O registers. Another downside is that this would make reading I/O registers a lot slower (right now they get mapped straight to a memory region), but since they're only really read a lot when polling happens anyway that might not matter. Another issue with this is that far more GBA games need proper horizontal synchronization, for HIRQ, HDMA, polling, or vcount trigger, and GBA games also have fairly high resolution timers. This means that event periods can get pretty small, so there isn't a lot of room to check for things falling into loops.
Another thing it does is checks to see if it's in a two instruction loop where the registers don't change.
GBA idle loops just aren't this simple, most of the time. This kind of loop also can't be statically determined, it'd have to be checked in an interpreter. PicoDrive only seems to check if it fell into a loop like this at certain intervals (although I'm not sure how those two extra instructions are compensated for)..
I did encounter one idle loop in a GBA game once that can be easily detected at runtime, a branch to itself. I think this was the only game I saw that did this though. I might more closely look at some of the games to see if there are any simple patterns I can detect.