And it's yet another reason why databases are important for the time being. We're in a constant process of discovery and breakage, and until every single game is dumped and tested, there is nothing but the misery and confusion plaguing rom-side mapping. We've got standard boards and boards that deviate slightly. Who knows if the PCB on this board even has its own code. Plenty of NES games do this rewiring/substitution act with no serial distinguishment.
As I understand it, GB carts are much saner than NES or SNES when it comes to headers in a vast majority of cases. It's just a limited number of edge-cases that pop up. Still, I agree that databases are important. If there was a single place I could have looked up detailed info about MK 1&2, I probably wouldn't have made this thread. Instead, I've had to piece together bits of info from Google searches and advice from others familiar with these kinds of tricky games.
I'll just take this moment (yet again, for the Nth
time) to complain about how poor Game Boy documentation is, especially in regards to something like more exotic MBC variants. If you want to know more about the MBC7, for example, good luck. You'll need to pick apart mostly uncommented code (most of it tracing their origins to VBA-M) to figure out what's going on. I can't stress enough how many times I find things about the Game Boy that have only been documented as emulator source code with sparse comments. In my opinion, source code is only ever half of what proper documentation looks like. It's the implementation, which is helpful, but not the actual schematic. Things need to be written in Plain-Old-English so everyone can understand what's going on without having to dissect code.
It's a huge pet-peeve of mine. I hate it when emulators like MAME or Gambatte does something (in this case, support for MBC1 "multicarts") but fail to explicitly write out how it functions. I had to parse Gambatte (MAME's code was not helpful, or at least not as clear as it could have been) to figure out how MK 1&2 works. For the sake of others, I'm going to share the results here so no one has to scratch their heads anymore.
//MBC1 "multicart" writeable registers
0x2000 - 0x3FFF: Lower 5 bits of the ROM bank (Bits 0-4)
0x4000 - 0x5FFF: Upper 2 bits of the ROM bank (Bits 5-6)
0x6000 - 0x7FFF: "Multicart" mode select bit
As far as I can tell, MBC1 multicarts do not have cart RAM. What normally is the ROM/RAM banking mode bit at 0x6000 - 0x7FFF instead switches the MBC into a "multicart" mode. In this mode, half of the available banks (0x3F) can be accessed. Even though something like Mortal Kombat 1&2 appears to use 1MB of data, it only really has 512KB worth of data on its cart. A lot of those banks are blank data (0xFF). In "multicart" mode, unlike most MBCs, ROM0 can actually be replaced with another bank (0x0, 0x10, 0x20, or 0x30). As a result, unlike MBC1s, the multicart versions can access Bank 0x20 by setting ROM0 to it. ROM1 cannot access 0x20, however (or 0x40 or 0x60 for that matter).
When entering multicart mode, ROM0 gets switched with another bank using the following formula (assume ROM_BANK is the full ROM bank number using all 7 bits from 0x2000 through 0x5FFF)
ROM_BANK = ((ROM_BANK >> 1) & 0x30)
So essentially, in multicart mode, ROM0 banks translate as follows:
Banks 0x0 through 0x1F = 0x0
Banks 0x20 through 0x3F = 0x10
Banks 0x40 through 0x5F = 0x20
Banks 0x60 through 0x7F = 0x30
When entering multicart mode, ROM1 gets switched with another bank using the following forumla:
ROM_BANK = ((ROM_BANK >> 1) & 0x30) | (ROM_BANK & 0xF)
So essentially, in multicart mode, ROM1 banks translate as follows:
Banks 0x0 through 0x1F = 0x0 - 0xF, then 0x0 - 0xF again
Banks 0x20 through 0x3F = 0x10 - 0x1F, then 0x10 - 0x1F again
Banks 0x40 through 0x5F = 0x20 - 0x2F, then 0x20 - 0x2F again
Banks 0x60 through 0x7F = 0x30 - 0x3F, then 0x30 - 0x3F again
When multicart mode is disabled, ROM banking works just like a regular MBC1, as far as I can tell.
On a final side-note, when changing the ROM0 by writing a new ROM bank number or flipping the multicart mode bit in 0x6000 through 0x7FFF, most games jump to code in WRAM before doing so. This makes sense because switching out ROM0 means you get new interrupt handling code at 0x40, 0x48, etc... ROM1 also changes its bank, so the only "safe" spot to switch banks is in WRAM to avoid accidentally executed random code.
I haven't looked at the PCB (I can't read electronics or anything like that) but this gets MK 1&2 working. It would be best if someone verified that's how actual hardware works. But I'm sick of documentation not being written out explicitly.