10

According to the GBdevwiki:

0000-1FFF - RAM Enable (Write Only)

Before external RAM can be read or written, it must be enabled by writing to this address space. It is recommended to disable external RAM after accessing it, in order to protect its contents from damage during power down of the gameboy.

What happens if you attempt to read/write while it's disabled? Does the CPU hang? The Gameboy crash? How should I implement this in an emulator? Just return a garbage value or crash the game?

18

Technically, the behaviour is what we call "undefined,"* meaning you can't know what will happen and the system is allowed to do anything it wants in response, up to and including launching a nuclear attack on another country.

That, of course, is highly unlikely (or you clearly got your hands on a Game Boy you should not have). The most likely scenario in this case is that writes would be ignored and reads would return unknown data. Exactly what would happen may vary with the particular cart and its specific memory controller; I can imagine perfectly plausible situations where on a read from one cart always returns 0, another returns random data, and a third returns exactly the contents of the RAM (i.e., "disabling" the RAM just write-protects it).

Less plausible, but still possible, would be a cart specifically designed to have "funny" behaviour when accessing the cartridge RAM addresses while disabled. It might, for example, have extra ROM that's mapped to that space when RAM is disabled, allowing for access to more ROM with less bank switching. Or there might be special hardware on the cartridge that's manipulated by writes to that area when RAM is disabled. This would also serve as a type of copy protection (intentional or not) by making the game more difficult to run on emulators: essentially the emulator would have to know about the game and emulate the cartridge's specific hardware as well as the Game Boy itself.

It may even vary as well with the particular model of Game Boy; it's not unusual for system designers explicitly to leave behaviour undefined so that they can take advantage of this to change how the hardware operates (usually to reduce costs) in later versions of the device.

For an emulator, I would start by generating an error and halting the emulation. This will help you find the cases where you need to deal with this and determine what the behaviour should be, which will hopefully be few and far between. (Nintendo puts all games through a farily detailed QA process, so they may well be checking the code to see game developers aren't doing this.)

Once you've found a game that triggers this, you need to figure out what to do about it, which will involve researching that particular game. There may be on-line resources for it where you can get advice from people who have already dealt with the issue. You can also reverse-engineer the game code to see what it might be trying to do (and whether it's a bug or the game is actually trying to use an undocumented feature) and change your emulator to try out different actions (returning random data, returning zeros, whatever) and test to see how that works.

Once you've figured out what to do, unless you can confirm that that particular behaviour is, even though undocumented, actually stable across all versions of the Game Boy and all cartridges and their memory management units, it's probably best to make the emulator detect that game and do your choosen behaviour only for it, continuing to abort the emulation for any other software that tries to do the same thing. This will let you continue to detect other games that are using undocumented and/or undefined behaviour and deal with their specific requirements when they come up.


*What is "undefined" is fairly clear when working with specifications from the original vendor: it's certainly whatever they tell you is not defined, and usually also what they omit to define in the documentation unless the behaviour is obvious by convention.

For reverse-engineered systems we're not working from original manufacturer documentation (detailed developer documentation for the GBA exists, but is proprietary) so the definition I'm using here for "defined behaviour" is "what extensive testing has shown to be consistently true for hardware considered to be working correctly."

So for example on cartridges where $0147 = $02 (thus claiming to adhere to MBC1+RAM behaviour) and $0149 = $03 (claiming 4 × 8KB RAM banks), I would call writing $02 to $4000-$5fff to switch RAM bank 2 to be "defined" behaviour, as per this widely confirmed document.

Conversely, since I've seen no widely confirmed evidence of consistent results from testing writes to disabled cartridge RAM, I call that "undefined" behaviour. This could change if sufficient testing is done to come to a fairly firm conclusion about what all correctly operating cartridge and main unit combinations do.

  • 5
    Did any of the models of the Game Boy cause demons to fly out of your nose? – Richard Ward Jul 22 at 14:33
  • 2
    Pretty sure some of the most powerful world leaders can, indeed, trigger a nuclear attack just from playing with a misprogrammed Game Boy. – dim Jul 22 at 15:07
  • 4
    "This is the worst Game Boy ever! It's the size of a football and no matter what I press it's not fun to play!" – Curt J. Sampson Jul 22 at 21:30
  • On the contrary, all behaviour of the original Gameboy is well defined by now. Your emulator should do whatever the original Gameboy did - that's what the hardware is defined to do. It's not a matter of "it's undefined behaviour therefore anything can happen" - you have to do what a Gameboy does. – immibis Jul 22 at 22:57
  • @immibis The Game Boy doesn't contain all the hardware that defines its behaviour, and in fact this question is specifically about hardware that's in the cartridge, not the Game Boy itself. Further, there are also many Game Boy clones (including from Nintendo itself! e.g. the pocket, light, GBA) that you may also want to emulate that may have different behaviour from the original GB. I don't know about Nindendo's GB compatibility on the GBA, but it's certain that some non-Nintendo clones have (subtly) different hardware behaviour. – Curt J. Sampson Jul 22 at 23:04
8

Generally, the RAM wouldn't respond to reads or writes (obviously). Writes would be discarded, the CPU moves on. Reads would return 0xFF if the cart leaves the lines floating, though 0x00 is a possibility. There's also the chance that a particular memory mapper that's actually its own processor could hang, with results similar to yanking out the cart. As far as I know, there are not mappers like that, so you don't need to consider it.

TL;DR: Writes do nothing, reads return 0xFF

6

The latest research shows that while writes are properly defined (ignored), reads are not. tl;dr: You will get a value with some bits reset.

Slightly more expanded: The behavior is open-bus with semi-weak pull-ups.

The long way around: The cartridge appears not to react at all, leaving the data bus (think of it as a temporary location for all bytes going in and out of the CPU) unchanged. The CPU normally has pull-up resistors which should set all the bits to 1, but it appears that they are a tad too weak to guarantee doing their job on time: some 0 bits might still be at 0. (gekkio even joked that this behavior can depend on room temperature) Note that the cartridge might have pull-ups of its own which would guarantee $FF to be read; however, RAM-less cartridges (Tetris...) have no circuitry to handle $A000-BFFF, and so the behavior ends up being as described above.

Note that the bus is also used for the instruction bytes the CPU reads, so the value read also depends on which instruction you used.

For an emulator implementation, returning $FF is "good enough", implementing the behavior described above might be better, but the best thing to do is to provide a toggleable warning for developers. (For example, BGB does this.)

  • 2
    This is great information; thank you! But would you mind linking to your sources for it? – Curt J. Sampson Sep 19 at 18:33
  • Was gekkio's joke really a joke? It sounds perfectly plausible to me. – Wilson Sep 19 at 21:01
  • @CurtJ.Sampson I believe there is no trace of this except in the Discord server, so I cannot link to sources. – Panda Habert Sep 21 at 18:23
  • @Wilson It's the case, but how it affects the behavior is unknown, and wouldn't matter much for a developer, unless you're planning on making your gameplay dependent on room temperature? :D – Panda Habert Sep 21 at 18:25
  • My takeaway from this: the Game Boy has a temperature sensor! – Curt J. Sampson Sep 21 at 19:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.