Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.

Topics - obskyr

Pages: [1]
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!


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!

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.



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.


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.



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.


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!

The game in question is Kotobattle for the Game Boy Color. The symptoms are bizarre: no matter how many times I dump it, between 60 and 110 half-random bytes are incorrect. The contacts are immaculate and shiny (I even gave 'em a peace-of-mind clean with the ol' IPA and cotton bud combo). I dumped it ten times, and the results are these:

Code: [Select]
$ md5sum Kotobattle-*.gb

None of these match the expected hash of 43351CD46357BD1615A713490401FDA8. Across these ten dumps, a total of 251 addresses were dumped incorrectly at least once. Most of these (86 addresses) were incorrect only once, but some were incorrect most every time, often in similar ways. For example, 0x1C9738 was 0x03 (which is incorrect) in eight dumps, and 0x00 (which is correct) in the other two. Most of the time, though, the errors are somewhat different – like 0x0785FC, for which 0x00 is correct, which dumped incorrectly seven times as 0xFB, 0x02, 0x93, 0x02, 0xFB, 0x02, and 0x02. Another interesting pattern is that most of these errors (206 out of 251 addresses) occurred with bytes that should've been 0x00, which may or may not mean something.

The extremely weird part is this: Kotobattle has the exact same MBC (MBC5) – and even PCB (DMG-A08-10; pictures of an identical board here) – as another game I tried dumping, and yet, Kotobattle has random incorrect bytes while the other consistently dumps well. Dumping SRAM also works totally fine every time.

That the MBC and PCB are the same as for a working game suggests that it's a software issue, but the fact that the faults are so intermittent suggests a hardware issue. I'm deeply perplexed. Does anyone have any idea what the problem could possibly be?

My Retrode is hardware version 2.2, firmware version .25a-beta, and I'm on Windows 10.

I've now tried reflowing the mask ROM and the MBC to no avail. The same mind-boggling symptoms persist. It's a bit hard to see any meaningful pattern (you can see the incorrect bytes from each dump collated here), but someone mentioned one thing: incorrectly dumped addresses with the same last three nibbles sometimes appear exactly twice. For example, 0x0907DC was incorrect 10/10 times, and 0x0AC7DC (also ends in 0x7DC) was incorrect 9/10 times – 0x5F0, 0xEBC, and 0x5C0 exhibit the same property.

At this point I'm almost considering a faulty ROM chip, but… I've never heard of mask ROM failing!

Pages: [1]