nba-emu / NanoBoyAdvance

A cycle-accurate Nintendo Game Boy Advance emulator.
GNU General Public License v3.0
955 stars 53 forks source link

[Feature Request] Frame Pausing/Frame Stepping #303

Open 0Slashking0 opened 1 year ago

0Slashking0 commented 1 year ago

Hi, I'm currently trying to essentially dump a bunch of "initial seeds" generated by the german version of the Fire Red and Leaf Green Pokemon Games. The games use the timer functionality (specifically the timer 1 register, set to increment every single CPU cycle, timer setting is 0x0080 to be precise) to generate this seed and other emulators simply aren't very accurate in this regard, aka they generate "emulator seeds" that real hardware doesn't generate (I have researched how the seed is computed heavily already, just incase more information on this is needed). Seeing that this emulator seems to be very accurate I would love to try to use it to generate some seeds, maybe I can generate some hardware accurate seeds with it (or atleast seeds that are very close!), I already tried with mgba, vba-rr and also BizHawk (BizHawk was the only emulator that had some seeds that were close-ish to some of my "real seeds", might just be coincidental though), the seeds generated by those weren't accurate at all though. Considering this emulator seems to pass most timer related tests, I have (some) hope it might generate accurate initial seeds. In a way this would also make for a good "emulator accuracy test" of sorts I suppose.

To do so, ideally I'd need to be able to pause the emulator on a certain frame and step forwards by a frame. I'd imagine pausing on/after a vblank could achieve this. Even more ideally I could then extract the seed from memory, however this isnt necessary as there is other ways of figuring out which seed I'm on (the same ways I would use on real hardware).

I can imagine frame stepping and pausing would be useful for other purposes aswell.

fleroviux commented 1 year ago

I have tested this with an English version of Pokémon Fire Red before and haven't had much luck getting any matching seeds :/

Unfortunately the situation is much more complicated than "it needs accurate timer emulation". The hardware timer runs over many frames until its value is finally read to generate a seed. This makes for a lot of opportunities for small off-by-one inaccuracies to accumulate over time and cause error in the final seed. NanoBoyAdvance's timing emulation, even though very very close, is still not 100% accurate sadly and again, small errors accumulate quickly over hundreds of frames.

That being said debugging tools are on my list and frame stepping should be implemented at some point.

0Slashking0 commented 1 year ago

Hm, I see, that's rather unfortunate. To my understanding the timer overflows multiple times between frames, as it is incremented 280,896 times (+-1 or 2 "slip" cycles, atleast that's how it behaves in vba-rr, I believe also on the real hardware, it has something to do with buttons pressed maybe). The real issue I'm having is the "final frame" so to speak, as the cycles needed to get to the actual final timer value seem to differ from frame to frame, Manually adding a final timer value to 280896 tends to under or overshoot by somewhere between 5-8 cycles at the least, but sometimes even up to 150 cycles or something. Curiously enough on Bizhawk as mentioned earlier I got a bunch of seeds/final timer values that very closely match my actual real seed values, they were all roughly off by I think (in decimal) 30-50, for some seeds anyways, after that either the rest of my calibrated real seeds come up way earlier or later, or by chance I calibrated the exact couple of seeds that happen to come out similiarly. Oh well, I suppose we're still atleast a bunch of years away from getting "perfect" emulation in that regard (if it can ever be achieved ever at all, some finicky stuff). There is a way to generate/dump the seeds on real hardware, but it abuses an arbitrary code execution glitch comboed with some "Tasbot"-style script or hardware, not sure, but I dont feel comfortable risking my cartridge if that goes wrong, so oh well, but thanks for telling me dumping won't work!