Hacking Hardware GBA Project Reading data from the Gameboy DMG/Color/Advance cartridge. Help needed

dev4hire

Member
OP
Newcomer
Joined
Jul 9, 2022
Messages
10
Trophies
0
Age
34
Location
SC
XP
68
Country
United States
I'm posting this in hopes that someone else knows how the protocol works. Currently my pseudo-code protocol looks like the following:

Default CS, CS2, RD, WR, IRQ, CLK to HIGH
Set the 24-bit address
Latch:
- setting the RD pin to HIGH for 10ms and then LOW
- setting the CS pin to LOW for 10ms then HIGH
Read the 16bit data lines

However, this is causing consistent garbage data, meaning I get the same results most of the time that do not match the ROM data. Any help via resources know of would be most helpful. I'll leave the resources I used to get to this point below.

Pinouts:
- (GB/C) https://allpinouts.org/pinouts/connectors/cartridges_expansions/gameboy-cartridge/
- (GBA) https://electronics.stackexchange.com/questions/635733/address-data-on-a-diy-gba-cartridge
- (GBA) https://web.archive.org/web/20230601081530/https://www.hardwarebook.info/Game_Pak
Reading:
- https://douevenknow.us/post/68126856498/arduino-based-gba-rom-dumper-part-1
 

merlish

New Member
Newbie
Joined
Jun 26, 2022
Messages
3
Trophies
0
Age
32
Location
Elsewhere
XP
51
Country
United Kingdom
I'm a little confused by what you mean, but maybe I can help anyway?

Note: This is based on the GBA, which I had a partially complete project making a cartridge for. So I'm reading my C and flipping it around to think of being the 'system', not being the 'cartridge'...


More importantly:

1. Default /CS, /CS2, /RD, /WR, /IRQ etc. all high
2. Put the address on the bus.
3. Send /CS low. The cart must now latch the lower 16 bits of the address, and must wake up. (Need to wait ??ns; can't remember, but it's fairly short)
4. Keeping /CS low, stop asserting those low 16 address lines that will become data lines (make microcontroller switch 'em to input pins), and send /RD low. This starts a non-sequential read.
5. After N cycles (cart-dependent) (90ns?), the data will be available on the data pins.
6. To continue with sequential reads, keep toggling /RD up and down. Cart will loop at a certain block boundary.

Important: When you put /RD up, the data may no longer be valid. Do not put /CS up until you are completely done with the transaction & you want the cart to stop listening to everything you're doing.

Things to watch out for:
- Converting address to the format the GBA protocol uses -- i.e., if you're used to byte-wise addressing, you need to rotate everything to the right 1 bit, because you're going to get 16 bits at a time
- Are your bits flipped somehow? Wrong way round? It's easy to flip a game boy cart PCB and forget that now all your pins are the wrong way around.
- Is there a space where there's all 1s in the ROM, or all 0s, and can you do a test read to that address & compare to what you expect?
- My crap soldering let me down when I was trying, but I was able to eventually diagnose my broken wires & fix
- You're sending 3.3V to your GBA cartridge, and you have GND hooked up, right? It would be good if both are connected to your respective microcontroller 3.3V power & ground.
- Try doing a full non-sequential read, put all pins high, wait a bit, do it again in a few loops. Do you get the same garbage data each time? Are there patterns?
- If you have some kind of probe or oscilloscope, check that you are really putting out the signals you think your code is putting out.
- Consider reading all pins on your microcontroller every substep of the read process, so you can see if and how things change. Even if the results are wrong, it may give you a hint.

Misc thoughts, maybe irrelevant:

- Doing stuff for "10ms": Just to check, you know this is way too slow for normal speed comms, right? Normal GBA stuff is 10s of nanoseconds as a 'cycle' of communication. I have no idea if you can drive carts that slowly. If you have some docs that says you can, fine.
- Also, do any cartridges need you to drive /CLK to push the cart forward? Is it optional for real carts? I don't know & can't remember
^^^^ both of these should be fines if cart mask roms are actually async
Post automatically merged:

Couple more things actually:

Correction: Don't drive /IRQ at all. It's a signal from the cartridge, not the system. On my test board (where I was making a pseudo-cartridge), I left that pin is disconnected, but my DS could read from my GBA cart.

Protocol reference: Use GBATEK's section on it. I'm not allowed to link, because my account is too young, but search "GBATEK AUX GBA Game Pak Bus". It's very brief, but it's actually correct, if you can puzzle it out. I puzzled out the read procedure I laid out above from that page.

For the GBC/GB connector, look up "GBDev PanDocs" ' External Connectors section. Like GBA but no latching, no /CS2, +5V.
 
Last edited by merlish,

dev4hire

Member
OP
Newcomer
Joined
Jul 9, 2022
Messages
10
Trophies
0
Age
34
Location
SC
XP
68
Country
United States
I'm a little confused by what you mean, but maybe I can help anyway?

Note: This is based on the GBA, which I had a partially complete project making a cartridge for. So I'm reading my C and flipping it around to think of being the 'system', not being the 'cartridge'...


More importantly:

1. Default /CS, /CS2, /RD, /WR, /IRQ etc. all high
2. Put the address on the bus.
3. Send /CS low. The cart must now latch the lower 16 bits of the address, and must wake up. (Need to wait ??ns; can't remember, but it's fairly short)
4. Keeping /CS low, stop asserting those low 16 address lines that will become data lines (make microcontroller switch 'em to input pins), and send /RD low. This starts a non-sequential read.
5. After N cycles (cart-dependent) (90ns?), the data will be available on the data pins.
6. To continue with sequential reads, keep toggling /RD up and down. Cart will loop at a certain block boundary.

Important: When you put /RD up, the data may no longer be valid. Do not put /CS up until you are completely done with the transaction & you want the cart to stop listening to everything you're doing.

Things to watch out for:
- Converting address to the format the GBA protocol uses -- i.e., if you're used to byte-wise addressing, you need to rotate everything to the right 1 bit, because you're going to get 16 bits at a time
- Are your bits flipped somehow? Wrong way round? It's easy to flip a game boy cart PCB and forget that now all your pins are the wrong way around.
- Is there a space where there's all 1s in the ROM, or all 0s, and can you do a test read to that address & compare to what you expect?
- My crap soldering let me down when I was trying, but I was able to eventually diagnose my broken wires & fix
- You're sending 3.3V to your GBA cartridge, and you have GND hooked up, right? It would be good if both are connected to your respective microcontroller 3.3V power & ground.
- Try doing a full non-sequential read, put all pins high, wait a bit, do it again in a few loops. Do you get the same garbage data each time? Are there patterns?
- If you have some kind of probe or oscilloscope, check that you are really putting out the signals you think your code is putting out.
- Consider reading all pins on your microcontroller every substep of the read process, so you can see if and how things change. Even if the results are wrong, it may give you a hint.

Misc thoughts, maybe irrelevant:

- Doing stuff for "10ms": Just to check, you know this is way too slow for normal speed comms, right? Normal GBA stuff is 10s of nanoseconds as a 'cycle' of communication. I have no idea if you can drive carts that slowly. If you have some docs that says you can, fine.
- Also, do any cartridges need you to drive /CLK to push the cart forward? Is it optional for real carts? I don't know & can't remember
^^^^ both of these should be fines if cart mask roms are actually async

Sorry I made the original post while very tired in the middle of a workday. This was exactly what I was looking for. I had a couple things wrong from what you described. I did mean microseconds, not milliseconds, but even then that is too long for nanoseconds timing. I was latching in a weird order and found some older documentation on archive.org that supports your order of doing it. I found that I had an issue with the 3 74HC595s I was using for the address bus, the pins were floating because I had too high resistance pulldowns when I disabled output. I also disconnected /IRQ.

Now the problem is the cartridge is always returning zeros

I spent some time and fully tested everything about the board. Firstly, the cartridge breakout is in the correct orientation (facing the label: 3.3v left, GND right). The address bus puts out the address I expect. The data bus reads data correctly when I apply voltage to them. The data bus can read the lower 2 bytes of the address if I don't disable output. The control pins (/RD, /WR, /CS, /CS2, /CLK) all confirmed to be outputting to the cartridge slot on my breakout board. All address and data pins shows voltage being applied (or continuity with the data lines) to the cartridge slot with no bridging or weak solder. To be safe, I remade the cartridge slot breakout board and tested that as well.

Any idea why the cartridge would be outputting only zeros? I don't believe they are /CLK dependent cartridge because I am using several cheap Barbie and other bargain bin games to test.
 
Last edited by dev4hire,

merlish

New Member
Newbie
Joined
Jun 26, 2022
Messages
3
Trophies
0
Age
32
Location
Elsewhere
XP
51
Country
United Kingdom
Hey! I didn't know the answer, but I might do, now.

Per (FFS links....... google "reinerziegler mirrors gba.htm" - yes, the rainbow wonderland webpage):

"GBA ROMs are special chips that contain a standard ROM, address latches, and address counters all on onechip. Cart accesses can be either sequential or non-sequential. The first access to a random cart ROMlocation must be non-sequential. This type of access is done by putting the lower 16 bits of the ROM addresson cart lines AD0-AD15 and setting /CS low to latch address lines A0-A15. Then /RD is strobed low to read 16bits of data from that ROM location. (Data is valid on the rising edge of /RD.) The following sequential ROMlocation(s) can be read by again strobing /RD low. Sequential ROM access does not require doing another /CS high-to-low transitions because there are count up registers in the cart ROM chip that keep track of the next ROM location toread. Address increment occurs on the low-to-high edge of all /RD. In theory, you can read an entire GBA ROM with just one non-sequential read(address 0) and all of the other reads as sequential so address counters must be used on most address lines to exactly emulate a GBA ROM."

(^ my addendum to the last bit: IIRC no you can't read the whole cart in one sequential read; there's looping at some kinda "block" boundary. I guess when the non-latched high address bits would change.)

Also, unrelated, been doing some reading, and my god the GB/GBC cart usage of pins is surprisingly different in practice. On GB, the /CS pin is used exclusively for RAM, and A15 going low is recommended as the practical way of seeing if a read is directed to you, the cartridge (whole system bus comes out the cartridge slot)... And reading on the GB looks more like "/RD is held low all the time, and when the game boy sets an address pointing at the cartridge then the cart just needs to set data in 150ns; /CS high the whole time..". gbdev.gg8.se forums has some info, as does Appendix C of gekkio.fi's "Game Boy: Complete Technical Reference" pdf. All very obscure.
 

Site & Scene News

Popular threads in this forum

General chit-chat
Help Users
    Psionic Roshambo @ Psionic Roshambo: 24,000 hmmmm lol