Author Topic: Bug report: Game Boy timings are off, causing some saves to be undumpable!  (Read 94 times)

Offline obskyr

  • Baby Retrode
  • *
  • Posts: 5
  • Karma: +0/-0
    • View Profile
    • My Twitter!
The problem

Lately, I've been researching an as of yet obscure Game Boy cartridge mod, where you switch out the SRAM chip for a non-volatile FRAM chip, effectively making the cartridge's saves immortal. Long story short, to make this mod compatible with some of the more obscure features of the Game Boy, the memory's chip enable pin has to be connected to an OR of the normal signal (the MBC's ¬RAMCS) and the cartridge bus's clock signal (CLK), meaning that the RAM chip (¬CE) is only active when both of those are low. This works A-OK on console – both saving and loading work perfectly! However, the Retrode (firmware version 0.25) can neither read nor write successfully to the saves of these modded cartridges.

The symptoms are awfully strange: writing overwrites every byte with 0xFF, and reading turns all 0x00s (and only 0x00s!) into 0x02! This screamed "timing issue" to me, so I checked out the signals, and indeed – the Retrode pulses the signals completely unlike the Game Boy does!



Analysis

I connected up an oscilloscope up to both a Game Boy Advance and to the Retrode to compare how they pulse the signals when reading and writing SRAM. Check out the results!

Legend:
ColorNameFunction
YellowCLKThe console's generated clock signal. Constantly pulses on console. Pin 2 of the cartridge connector.
Pink¬RAMCSThe MBC's "activate SRAM" signal. Active low. A pin on the MBC (which one depends on the MBC).
Blue¬RDPuts the save memory into read mode (or not, depending on MBC). Active low. Pin 4 of the cartridge connector.
Green¬WRPuts the save memory into write mode (or not, depending on MBC). Active low. Pin 3 of the cartridge connector.

Reading

Console

A one-byte read from an MBC5 game on console running in double-speed mode:



¬WR is constantly inactive, ¬RD is constantly active, and CLK pulses at a constant rate of ~2.1 MHz (as it always does). ¬RAMCS goes active for ~400 ns. Not pictured is that the Game Boy samples the data lines at the midpoint of CLK being low while ¬RAMCS is active.

Retrode

In comparison, two bytes (I think?) read from an MBC5 game on a Retrode:



As you can see, it looks quite different. For starters, ¬WR is constantly asserted active alongside ¬RD, which is a bit befuddling – ¬WR shouldn't be active when reading. ¬RAMCS goes active for ~9 µs, during which CLK pulses 10 times. CLK doesn't pulse outside of ¬RAMCS being active. When the Retrode samples the data lines I don't know, but given that CLK pulses ten times, I wouldn't think it's in the middle of any specific one of those.

Writing

Console

A one-byte write to an MBC5 game on console running in double-speed mode:



CLK pulses at a constant rate of ~2.1 MHz (as usual). ¬RD goes inactive at the same time ¬RAMCS goes active. The next time CLK goes low, ¬WR goes active with it. ¬WR goes inactive a little bit later, after which ¬CLK goes high and brings ¬RAMCS to inactive and ¬RD active with it. Not pictured is that the Game Boy makes data available on the data lines at the same time as ¬WR goes active.

Retrode

A one-byte (I think?) write to an MBC5 game on a Retrode:



I don't quite know what's going on here. At the beginning of the entire length of bytes written, ¬RD briefly goes active (probably just incidentally), after which it goes inactive again and stays that way for the rest of the write. ¬WR is constantly active. ¬RAMCS goes active for ~10 µs, during which CLK pulses 10 times. ¬RAMCS then goes inactive again, and… CLK pulses 10 more times? When the Retrode makes the data available I haven't checked.

For a more formal reference for the console timings, see appendix C of GB-CTR. To note is that GB-CTR uses the name "PHI" for the signal called "CLK" above, and that it documents normal-speed mode – multiply the frequencies by 2 to get the timings for double-speed mode.



The fix

The technically correct fix for this is, of course, to rewrite a bunch of code and make the Retrode's timings more or less match those of the Game Boy. The specific lengths of the pulses aren't immensely important – after all, the Game Boy Color can run at twice the speed of the Game Boy – but the order of rises and falls is. This way, the Retrode is guaranteed to be timing-compatible with anything that works on console. However, the particular case I mentioned can be solved with smaller modifications.

The reason reading doesn't work is probably because the data lines are sampled either while CLK is high or hasn't been low for very long (thus trying to read while the chip is disabled or not ready) – so moving that sampling to a time when CLK is low (and has been low for at least 100 ns) would fix reading.

As for writing, I'm not sure what exactly the issue is! It may be the same thing there – the Retrode could be making data available while CLK is high or similar.

I'd also recommend only one CLK pulse per byte read/write – it's not strictly necessary for this case, but… the current 10× pulse behavior is weird, and might waste memory write cycles when that's wired up to CLK.

I hope that this can be fixed soon! As the batteries of MBC5 games run out in greater and greater numbers, and word of this mod gets out, I expect mods like these to become more pervasive. It'd be nice if the Retrode could handle it correctly!
« Last Edit: 05/Apr/2019 05:36:26 PM by obskyr »

Offline MasterOfPuppets

  • Sgt. Retrode
  • ***
  • Posts: 109
  • Karma: +2/-0
    • View Profile
You may want to reach out to Matthias to see if you can get the Retrode's source code to implement the fix. That is, of course, if you have the time/desire to do so.

Offline obskyr

  • Baby Retrode
  • *
  • Posts: 5
  • Karma: +0/-0
    • View Profile
    • My Twitter!
I suppose… In a way, I don't want to implement the fix myself, since I'd be tempted to make it properly correct and not just put a band-aid on it – which might take a lot of time and work. But… on the other hand, I guess I wouldn't be opposed to making sure it gets done right, and I do know the ins and outs of the issue.

Where can I get in contact with Matthias?
« Last Edit: 06/Apr/2019 12:40:02 AM by obskyr »

Offline skaman

  • Global Moderator
  • Sgt. Retrode
  • *****
  • Posts: 177
  • Karma: +40/-0
    • View Profile
Nice work documenting the issues.  I haven't worked on any of the GB/GBC/GBA code.  There are a lot of things that could be improved.  If you're up to fixing the code, then definitely contact Matthias.

If you start working on those consoles, then you'll see the missing support for the various mappers and save types.  The small project can become a large one very quickly.