The level of effort put into reverse engineering for emulating classic hardware of all kinds is just remarkable. The Dolphin EMU team has a long history of these kind of blog posts for people looking for more of this kind of writing https://dolphin-emu.org/blog/
- Huh, getting USB disconnects randomly, need to fix this
- Hmm, device driver seems to be fine
- Hmm usbnet driver seems fine
- Hmm xhci driver seem fine
- $5000 and one USB 3.0 protocol analyzer later...
- What the heck is this host controller doing?
At this point it was looking like a hardware problem but seeing as I didn't have the schematics or verilog of the host controller I could go no further (nor did I want too... I never imagined USB could be such a deep rabbit hole).
Seems like "Holy grail" bugs like this happen to need a thorough understanding of complex systems (which I usually like to hide under layers of abstraction).
For example, a bug in the implementation of a virtualized device looks like a hardware bug to the client and like a software bug to the host.
According to the nesdev wiki, automation consists of playing back controller input, waiting for the tests to run, taking a screen shot of the results screen, hashing it and comparing the result to the hash of the expected results screen. This method also allows testing real games to check for reproducible bugs.
Pretty nice. I expected the test ROM to write the results to some special location in memory and have the emulator report those results.
Is it buggy code, or something intentional like anti-emulator sneakery?
Another example: there are several GBA games that dereference null pointers, but it works because there is no memory protection fault hardware in the GBA. Since the BIOS is mapped to address 0 and yet locked out from reading post-boot (in a failed anti-copying mechanism), you have to emulate the open bus behavior to run these games correctly as a result.
There are also several anti-emulator routines in the GBA library, such as lying about the type of save memory (flash, EEPROM, or SRAM) that a given game actually has (by including strings in the ROM from the Nintendo SDK used to access them.)
Maybe there was supposed to be music playing, this was for timing it, and it was removed, broken, or just forgotten about?
Did they have software emulation for that hardware at the time the game was written?
I understand it was less practical to do this for say, the NES or SNES. But it should have been done for the GBA. It's not just important for future hardware to be able to easily emulate GBA games, it also protects against product refreshes breaking games, something that plagued quite a few classic Game Boy games as newer models came out and fixed bugs in the older models.
Perhaps to "fix" some weird DMA related bug.
Had the GBA architects made the device halt on invalid memory rather than return the last thing on the bus and hope everything would be ok this entire class of bug wouldn't exist and the authors of that code likely would've found that bug during production.
Of course, would it matter if these bugs were found? The games ran fine on real hardware.
There’s no maintenance burden either, because updating a gba game is literally impossible.
Not quite. The Pokémon Ruby/Sapphire Berry Glitch bug was fixed by connecting to games that had a patch program, such as Pokémon Emerald, the 3rd in the Ruby/Sapphire/Emerald series.
Hey now, I'm sure it's not "impossible", you could probably overwrite specific sectors with laser or whatever, but probably had more to do with the distribution, where the economy and environment impact wouldn't make sense.
The graphics on Atari 2600 had to be fed line-by-line during the vertical blanking interval. Made for some really tricky assembly coding, trying to get enough done to make the interval without wasting VERY limited ROM resources (aka can't cheap with NOP instructions).