It is currently Tue Feb 19, 2019 3:24 am

All times are UTC - 7 hours





Post new topic Reply to topic  [ 21 posts ]  Go to page 1, 2  Next
Author Message
 Post subject: Switching ROM banks
PostPosted: Mon Feb 04, 2019 9:33 am 
Offline

Joined: Mon Feb 04, 2019 8:47 am
Posts: 8
So, I bought a cartridge slot for the Game Boy. I solder the wires to the cartridge pins and connected the pins to a GPIO board based on the pinout given here http://www.hardwarebook.info/Game_Pak (I didn't solder pin 2, 5, 30 or 31 since based on my understanding I don't need them).

I am able to read rom bank 0 and 1 by reading from address 0 to 0x7FFF (I have checked this results to be correct, so I am pretty sure all wires are connected correctly). Since I want to read the entire rom, the natural thing to do now is to switch rom bank. However, this is where I got a problem.

Based off http://gbdev.gg8.se/wiki/articles/Memor ... ontrollers and https://www.insidegadgets.com/2011/03/1 ... d-the-rom/ I try to first set pin WR low and RD high. Then I write the address 0x21 (in binary) to the "output" pins (AD0-15). Then I convert the pins A16-23 from input to output and then write a rom bank number to those pins in binary. Then I set RD low and WR high again and set A16-23 back to input and try to read the next rom bank in address space 0x4000-0x7FFF, however I still read rom bank 1 :cry:

Any idea on what I am missing?

BTW the game I have connected to the cartridge slot is "Spider-Man 2: The Sinister Six" for the GBC with a MBC5.


Top
 Profile  
 
 Post subject: Re: Switching ROM banks
PostPosted: Mon Feb 04, 2019 10:53 am 
Offline

Joined: Sun Apr 13, 2008 11:12 am
Posts: 8141
Location: Seattle
The pinout on that page tries to describe both the GBA and GBC usage of the same connector at the same time and is confusing as a result.

A better reference is the pandocs: http://problemkaputt.de/pandocs.htm#externalconnectors
or Frohwein's reverse-engineered schematics: http://gbdev.gg8.se/wiki/articles/DMG_Schematics

rombank wrote:
I try to first set pin WR low and RD high. Then I write the address 0x21 (in binary) to the "output" pins (AD0-15). Then I convert the pins A16-23 from input to output and then write a rom bank number to those pins in binary. Then I set RD low and WR high again and set A16-23 back to input and try to read the next rom bank in address space 0x4000-0x7FFF, however I still read rom bank 1 :cry:
1- /WR and /RD are the event. Everything else should be prepared before you drive exactly one of them low, and they should be both high before you change anything else. Do not change the contents of the address bus while they're asserted. If writing, also do not change the contents of the data bus while /WR is asserted.

Looking up the Z80 or 8080 datasheet and its external memory timings might be helpful.

2- The DMG/GBC doesn't have a 24-bit bus ever. It's always just a 8 bit data bus and a 15, 16, or 17 bit address bus (depending on just how pedantic you're being)


Top
 Profile  
 
 Post subject: Re: Switching ROM banks
PostPosted: Mon Feb 04, 2019 12:00 pm 
Offline

Joined: Mon Feb 04, 2019 8:47 am
Posts: 8
Thanks for the reply lidnariq :D

I am a bit new to doing hardware stuff so sorry for being a little slow.

Based on the references you sent it looks like I haven't made any errors regarding the pins (unless the same pin numbers as stated in the first post are needed).



1. I don't think I fully understand what you said, but I will try to explain what I understood. So both /WR and /RD should be set high before I try to change the rom bank. I should then do the necessary setup for changing the rom bank(writing to the address bus), before sending the signal to change the rom bank by
(the qoutes will be from https://www.insidegadgets.com/2011/03/1 ... d-the-rom/ )
Quote:
~WR – if low(grounded) and if RD is low, we can write to the SRAM and load a ROM or SRAM bank
and then switch back to pulling /WR and /RD high and then go back to reading the rom
Quote:
~RD – if low (grounded) and if WR is high, we can read the ROM and SRAM


2. Oh, well now i'm confused. If there is an 8 bit data bus and a 16 (because 2^4=16 and we love numbers with a base of 2 ;) ) bit address bus, how am I suppose to write the rom bank number if the 16 bit address bus is suppose to be used to write 0x21 ? If you open the link from insidegadgets and search "Read the next ROM bank (4000 – 7FFFh)", you will see he changes the 8 bit data bus from input to output is this because he is reading a gameboy game then(F1Race)?

Thanks for the help!


Top
 Profile  
 
 Post subject: Re: Switching ROM banks
PostPosted: Mon Feb 04, 2019 12:44 pm 
Offline

Joined: Sun Apr 13, 2008 11:12 am
Posts: 8141
Location: Seattle
insidegadgets wrote:
~WR – if low(grounded) and if RD is low, we can write to the SRAM and load a ROM or SRAM bank
That's a little misleading. It's not really "loading" anything.

Quote:
how am I suppose to write the rom bank number if the 16 bit address bus is suppose to be used to write 0x21 ?
because the address bus isn't used to write anything? Try to forget anything that you've read anywhere that had the "A23" signal on it. That entire diagram is exclusively for the GBA, and has little to do with how the DMG/GBC works, and it will just confuse you if you keep remembering it.


Let's talk about how old ROMs work.

There's a fixed number of pins that export data from the ROM. It's very often eight, almost always a power of two. This group of pins is usually connected to a data "bus", so that another device (like a CPU) can use its output.

There's some number of pins that can select what data to read from the ROM. There can be any number of them. These are called "address" pins because they let another device select what data to retrieve.

A closely related device is a RAM. It's almost the same, except that another part can put values into it as well as get values out of it. In order to specify which, the CPU (or other device, as appropriate) has a variety of "control" signals that specify what action should happen.

When the number on the address pins is the number X, and the control signals specify that it wants to read from ROM, the ROM will drive the number stored at address "X" onto the data bus.

So how does the CPU say that it wants to read a value from address X? By driving the address bus with X, leaving the data bus undriven, and driving the control signals to say it wants to read now. Different CPUs use different conventions for "I want to read now", but in the Game Boy, it does this by either driving A15 or /CS low and then driving /RD low. The CPU must stop asking the external part to drive the data bus before the CPU wants to drive it.

Similarly, the Game Boy says "I want to write now" by driving either A15 or /CS low, and then driving /WR low. The CPU must stop asking the external parts to listen to a write before the CPU changes the contents of the address or data bus.


But, you say, many Game Boy games are bigger than 32 KiB. How does this work? Well, the ROM works the exact same way as before. It still has a bunch of physical address pins, each of what doubling the amount of data that can be talked about. But the Game Boy CPU can't drive those higher address lines directly, so something else has to control them.


The final and most vital part to understand is that two different devices can be at the same address.

The Game Boy uses this extensively. The ROM can be read at one set of addresses – $0000 through $7FFF – but there are also control registers that do things when the CPU writes to the same addresses.

The "gbdev" wiki link explicitly calls this out, by specifying which addresses control the extra address lines to the ROM. So, for the MBC1, if the CPU writes to address $2000, it will change the address lines seen by the ROM. This allow the CPU to view a movable "window" out of the ROM.

Do you have a coherent image of how things work now?


Top
 Profile  
 
 Post subject: Re: Switching ROM banks
PostPosted: Mon Feb 04, 2019 5:43 pm 
Offline
User avatar

Joined: Fri Jan 04, 2019 5:31 pm
Posts: 27
Location: France, right of a pile of consoles
By the way, make sure you're driving A15 low last. It's used as a chip select signal.
Here's something that should work:
1. Drive WR and RD high
2. Put data on data bus
3. Put address on address bus, A15 last
4. Drive WR low
5. Wait for one 1 MHz cycle (that should be enough)
6. Drive WR high again
7. You should be done.

If you have a way to sniff pins while the game is running, you should use that to give yourself an idea of how things work on the actual hardware, and then try to replicate it.

_________________
The French Lord of Laziness (and a huge Legend of Zelda fan)
https://github.com/ISSOtm
ASMu is laifu <3


Top
 Profile  
 
 Post subject: Re: Switching ROM banks
PostPosted: Mon Feb 04, 2019 6:10 pm 
Offline

Joined: Sun Apr 13, 2008 11:12 am
Posts: 8141
Location: Seattle
ISSOtm wrote:
By the way, make sure you're driving A15 low last. It's used as a chip select signal.
The 8080-style bus used by the DMG/GBC should be safe to clock with /RD and/or /WR instead of A15. Different models, and different "bus controllers" on any given model, all have different timing between /RD/WR and A15/CS.

But yes, that's why I said the DMG has 15 to 17 bits of address bus. 15, if it's A0-A14 and two control lines ("/M0-7" and "/MA-E"). 16 if you pretend /CS is just /A15 (but it's not quite). 17 ... ok, I guess 17 is hard to justify.


Top
 Profile  
 
 Post subject: Re: Switching ROM banks
PostPosted: Tue Feb 05, 2019 1:32 am 
Offline
User avatar

Joined: Fri Jan 04, 2019 5:31 pm
Posts: 27
Location: France, right of a pile of consoles
I've heard gekkio say that A15 low meant ROM was selected, and /CS low meant SRAM selected. Here's the full message:
Quote:
gekkio 01/15/2019
> What's the behavior/role of the pins on the cart bus?

It's good to think about the behaviour and role a bit separately, for example we can study timing separately from how things are connected
the chip has two internal buses: a 16-bit bus ("address bus"), and a 8-bit bus ("data bus"). These aren't directly visible externally and there's some buffers/latches that separate them from the external pins
by looking at timing we can see that there's several "pin groups" where they have similar timing: A0-A7, A8-A14, D0-D7, CS/A15
A0-A7 seem to be buffered/possibly latched values directly from the corresponding signals of the 16-bit internal bus
latching in practice means that the buffer/latch can "lock down" the value that is presented to the external bus, so the internal bus can change freely without any effect on the external side
so external A0-A7 = internal A0-A7, but it's possible to "save" the value so the internal values can change without causing problems
A8-A14 are basically the same, but there's a minor difference in how they work between reads (in more technical terms, IIRC A0-A7 is put to high impedance between reads, but A8-A14 is not)
CS/A15 are completely different. They are deasserted at all times, except for a fairly short time during a memory access to the corresponding memory area. They are always asserted after the other address signals, so the address signals have stabilized at that point
a better naming would be RAM_CS/ROM_CS
so A15 is not really "address bit 15", but an external chip select signal

_________________
The French Lord of Laziness (and a huge Legend of Zelda fan)
https://github.com/ISSOtm
ASMu is laifu <3


Top
 Profile  
 
 Post subject: Re: Switching ROM banks
PostPosted: Tue Feb 05, 2019 10:15 am 
Offline

Joined: Sun Apr 13, 2008 11:12 am
Posts: 8141
Location: Seattle
Yes? I wasn't negating that. My point is in 8080-style buses like the DMG's, both /M0-7+/MA-E and also /WR+/RD are strobes and both have to be true, and saying that one or the other is the clock is wrong.

For example, in at least one Wisdom Tree unlicensed game uses a 74'377 where /WR is ↑clock and /M0-7 is the clock enable. Different bus controllers (the DMG's CPU, the DMG's DMA unit, the GBC's version of both) have subtly different timing on the relative phase of the two signals, and slavish devotion to one interpretation may well backfire.


Top
 Profile  
 
 Post subject: Re: Switching ROM banks
PostPosted: Wed Feb 06, 2019 10:44 am 
Offline
User avatar

Joined: Fri Jan 04, 2019 5:31 pm
Posts: 27
Location: France, right of a pile of consoles
lidnariq wrote:
Yes? I wasn't negating that.

Then I simply misunderstood you. :)

_________________
The French Lord of Laziness (and a huge Legend of Zelda fan)
https://github.com/ISSOtm
ASMu is laifu <3


Top
 Profile  
 
 Post subject: Re: Switching ROM banks
PostPosted: Wed Feb 06, 2019 3:10 pm 
Offline

Joined: Mon Feb 04, 2019 8:47 am
Posts: 8
Thank you lidnariq for your in-depth explanation!

I think my main point of confusion is how you can write the bank number to address $2000 . The way I understand it(I probably confused some, I'm sorry), I first have to read from address $2000 and then write to that address. So first I drive the address bus with $2000 and leave the data bus undriven, and
drive either A15 or /CS low and then drive /RD low. Then I drive the address bus with a bank number and leave the data bus undriven and then drive either A15 or /CS low, and then driving /WR low to do the write the data. How wrong was that guide?

Thank you ISSOtm for the step by step guide (it made things very clear). You wrote that
Quote:
Put data on data bus
, I guess by data you mean the bank number. However this seems to contradict what lidnariq wrote
Quote:
The DMG/GBC doesn't have a 24-bit bus ever. It's always just a 8 bit data bus and a 15, 16, or 17 bit address bus (depending on just how pedantic you're being)
or am I missing something?

I'm super thankful that both of you try to help me understand!


Top
 Profile  
 
 Post subject: Re: Switching ROM banks
PostPosted: Wed Feb 06, 2019 4:11 pm 
Offline

Joined: Sun Apr 13, 2008 11:12 am
Posts: 8141
Location: Seattle
rombank wrote:
I first have to read from address $2000 and then write to that address.
This is specifics of how bankswitching works on the Game Boy. It doesn't require that initial read.

Quote:
So first I drive the address bus with $2000 and leave the data bus undriven, and drive either A15 or /CS low and then drive /RD low.
That does describe how one reads from $2000, but that's not how one interacts with the MBC chip on the Game Boy.

Quote:
Then I drive the address bus with a bank number and leave the data bus undriven and then drive either A15 or /CS low, and then driving /WR low to do the write the data.
No, writes always happen via the data bus, not the address bus. What you're doing here is writing the value of the data bus—whatever it randomly happens to be—to the address on the address bus.

Here's another metaphor that might help.

Pretend you had two hallways. Each hallway has 32768 doors. (32768 = 215). Every door has a letter slot and a box.

The "A15" and "/CS" signals specify which hallway you're in. The address specifies the door. "/RD" and "/WR" specify whether you're putting something in the letter slot in the door, or taking something out of the box on the door.


In the Game Boy, sometimes there are different things controlling what's in the box, and what happens when you put something in the letter slot.

As an example, let's read a byte from and write a byte to $C000. $C000 means the address on A14 through A0 will be $4000, and that /CS will go low while A15 will stay high.

We write a value to this location: we put a number in the letter slot. (We drive the data bus with that number, drive /WR low then high). We then check the contents of the box (We leave the data bus floating, drive /RD low, check the contents of the data bus, then drive /RD high). Because there's RAM at this address, we find that the same number is in the box that we put in the letter slot.

In contrast, let's talk about reading and writing a byte from/to $0000. $0000 means the address on A14 through A0 will be $0000, and that A15 will go low while /CS will stay high. The process of reading and writing looks the same, but the behavior outside is different: regardless of what we write, we always get the same number out of this location, because there's ROM here.


Now, the MBC chips in the Game Boy do something funny with the value that you wrote to $2000. They change the contents of the boxes in the hallway when you read from $4000 through $7FFF. This is "bank switching"


Top
 Profile  
 
 Post subject: Re: Switching ROM banks
PostPosted: Fri Feb 08, 2019 6:47 am 
Offline

Joined: Mon Feb 04, 2019 8:47 am
Posts: 8
Thanks for the metaphor, lidnariq! It cleared up the misconception with the data lines from earlier, I think. We will soon find out, I still have problems switching ROM bank. I have reread all the post here a few times, and I am still stuck. So I will try to explain how to switch rom banks successfully.

First I will explain how to read the game title(located in address space 0x0134 to 0x0143) from ROM bank 0. I bolded out how to switch ROM banks longer down, but I thought giving the entire picture might make it clearer what I am misunderstanding.

1. Both RD and WR should be high
2. Set RD low and WR should be unchanged
3. The addresses we are reading will have the variable j. So, the first address will be 0x0134(j) and the value of 0x0134 should be written to the address lines (0000000100110100), since the Game Boy is little-endian the value should be written backwards.
The results are that 0010110010000000 is written from A0->A15. Here is the order to remove any confusion.
Code:
   A0=0
   A1=0
   A2=1
   A3=0
   A4=1
   A5=1
   A6=0
   A7=0
   A8=1
   A9=0
   A10=0
   A11=0
   A12=0
   A13=0
   A14=0
   A15=0

4. Now it's time to read the value from the data lines.
5. So, we check the data liens to see if they are high or not and this will depend on the value on the address we read from.
6. So what I do is reading the address lines backwards like D7-D0 and have a string we can call byte. As I read a new value from a data line I append 1 to the string if that particular data line is high and 0 if it were low. So, in this case we get the string 01010011 which is 83 in decimal or the letter "S" in ascii (I am reading the Spider-man 2 game)
7. Increment j and go back to step 2 untill you variable j is 0x0143 and you will have read the game title. (the results is SPIDERMAN2*NULL*2SE)

I have been able to read the first two ROM banks available by using the method described above.

Now I will explain how to switch ROM banks!
1. Both RD and WR should be high
2. Let's say we want to read ROM bank 60(I have a cartridge with 64 banks) which is 00111100 in binary. We put this value on the data lines:
Code:
   D0=0
   D1=0
   D2=1
   D3=1
   D4=1
   D5=1
   D6=0
   D7=0

3. Then we put the binary value of the address 0x2000 (0000000000100000) on the address lines, writing in the reverse the same way it was done when reading, so the address line will have these values :
Code:
   A0=0
   A1=0
   A2=0
   A3=0
   A4=0
   A5=1
   A6=0
   A7=0
   A8=0
   A9=0
   A10=0
   A11=0
   A12=0
   A13=0
   A14=0
   A15=0

4. Now set WR low
5. Wait 1 MHz cycle
6. Drive WR high again
7. Read rom bank 60


Top
 Profile  
 
 Post subject: Re: Switching ROM banks
PostPosted: Fri Feb 08, 2019 10:45 am 
Offline

Joined: Sun Apr 13, 2008 11:12 am
Posts: 8141
Location: Seattle
So close! But endian-ness confused you.

rombank wrote:
since the Game Boy is little-endian the value should be written backwards.
Address lines are always explicitly named, and buses are, by themselves, without end. "Endianness" has to do with how subunits are ordered within a thing when there isn't an explicit name.

For example, you're right that the game boy CPU is little-endian, but that means that an instruction referring to the address 0x1234 will appear as the two bytes, in order, of 0x34 0x12.

What's unfortunate is that you did the right thing here:
Quote:
A0=0
A1=0
A2=1
[...]
A13=0
A14=0
A15=0
in the sense that you had your "little end" at the top in both cases, but then you got confused down here:
Quote:
3. Then we put the binary value of the address 0x2000 (0000000000100000) on the address lines, writing in the reverse the same way it was done when reading, so the address line will have these values :
Code:
   A0=0
   A1=0
   A2=0
   A3=0
   A4=0
   A5=1
[...]
   A15=0
where you still but the "little end" on at the top on your labels, but you put the "big end" at the top on your values.


Top
 Profile  
 
 Post subject: Re: Switching ROM banks
PostPosted: Fri Feb 08, 2019 2:29 pm 
Offline

Joined: Mon Feb 04, 2019 8:47 am
Posts: 8
Ah! So I get that I have misunderstood the endian part. However, I don't understand why the reading worked with such a misconception :? (maybe luck with wire and code)

So would the rigth thing to do be to do this on step 3 ? (switch A5 with A10)
Code:
   
   A0=0
   A1=0
   A2=0
   A3=0
   A4=0
   A5=0
  [...]
   A10=1
   A11=0
   A12=0
   A13=0
   A14=0
   A15=0


Top
 Profile  
 
 Post subject: Re: Switching ROM banks
PostPosted: Fri Feb 08, 2019 2:52 pm 
Offline

Joined: Sun Apr 13, 2008 11:12 am
Posts: 8141
Location: Seattle
rombank wrote:
Ah! So I get that I have misunderstood the endian part. However, I don't understand why the reading worked with such a misconception :? (maybe luck with wire and code)
I'm not certain. If I had to guess, I suppose you reversed things twice there.

Or maybe you only paid attention to the signal names the first time around?

Quote:
So would the right thing to do be to do this on step 3 ? (switch A5 with A10)
Yeah.

Regardless of whether it's little-endian or big-endian, A10 always means the same thing. Even on the big-endian 68000 and little-endian 8086, both of which have 16-bit data buses, the 16-bit number 50000(decimal) is always represented D15=1 D14=1 D13=0 D12=0 D11=0 &c ...

The difference is when reading an 8-bit number from address 0, the 68000 fetches that value using D15 through D8, while the 8086 fetches that value using D7 through D0.


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 21 posts ]  Go to page 1, 2  Next

All times are UTC - 7 hours


Who is online

Users browsing this forum: No registered users and 2 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Group