Most information here is from PlutieDev! Thank you! Extra information was also provided by Devon (in a reply below), also thank you! Let's say that your ROM hack or homebrew has gone over 4 megabytes in file size and can't operate properly anymore on real hardware or accurate emulators. That's a real issue if you want to make sure RHS isn't at your door asking if it works on real hardware or not. However, there is a fix and this tutorial shows you how to use the Sega Mapper, a bank-switcher used to play games larger than 4MB in file size. The SM has only ever been used officially once (Super Street Fighter 2) and Sonic 3 & Knuckles uses a partial mapper with the lock-on technology to tie the two games together. The Mega Everdrive Pro also provides support for the Sega Mapper and Sonic Delta, created by Neto, uses mappers. This is why, on older flash carts, Sonic Delta doesn't work on real hardware, because it can't use the Sega Mapper, because the mapper isn't in the cartridge. Anyways, to use the Sega Mapper, first, you need to update your ROM header. For this tutorial, we're using Hivebrain's 2005 Sonic 1 disassembly. You can simply replace the "SEGA MEGA DRIVE" or "SEGA GENESIS" entry in your ROM header with "SEGA SSF" (make sure to pad the label with spaces!). This enables the mapper. Now, before we actually begin, let's get into the nitty-gritty of the Sega Mapper (a.k.a. the technical stuff and how it works): The Mega Drive is able to see only 4MB at once. The way this works is that the ROM is split into pages, or 512KB chunks. The console will then, still see only 4MB, but will also split into banks, which is similar to pages. Each bank is pointed to a page, letting us see up to 4MB at once. By switching the bank to another page, we can access other parts of the ROM as needed, bypassing the file limit. The first bank should always be pointed to the first page to allow for soft resetting, where as, the other banks can be pointed to any page we want at any moment. Each bank has its own register and to switch them we just write the page to the relevant register. Here's a list of the banks and their associated register: Default: $000000 - $07FFFF $A130F3: $080000 - $0FFFFF $A130F5: $100000 - $17FFFF $A130F7: $180000 - $1FFFFF $A130F9: $200000 - $27FFFF $A130FB: $280000 - $2FFFFF $A130FD: $300000 - $37FFFF $A130FF: $380000 - $3FFFFF Ok, now that that's over with, we can begin implementing the mapper. First, add this above the header (StartOfRom): Code: MB1: equ $A130F3 ;$080000-$0FFFFF MB2: equ $A130F5 ;$100000-$17FFFF MB3: equ $A130F7 ;$180000-$1FFFFF MB4: equ $A130F9 ;$200000-$27FFFF MB5: equ $A130FB ;$280000-$2FFFFF MB6: equ $A130FD ;$300000-$37FFFF MB7: equ $A130FF ;$380000-$3FFFFF You also need to set the RV flag to properly manage mapper bank switching. After you've finished that, place this below the label "GameInit": Code: move.b #1, (MB1) move.b #2, (MB2) move.b #3, (MB3) move.b #4, (MB4) move.b #5, (MB5) move.b #6, (MB6) move.b #7, (MB7) This will make the first 4MB of the ROM successfully boot. Now, for this example, let's say your ROM ends up being 5MB large. When your ROM needs to access the extra 1MB, you can call this: Code: move.b #8, (MB6) move.b #9, (MB7) This will let the console read that last extra MB. Now there is one precaution, and it's both the Z80 engine & the 32X. You NEED to make sure the Z80 and the 32X is aware of any bank and page switches when it happens as errors will occur after trying to access a bank that is not active. With the 32X, since the memory space on the 32X is so small, you will need to deal with 2 layers of bank switching. Congratulations, you can now continue working on your ROM hack just fine, without worrying about being below 4MB! You will have to worry about being below 32MB, as anything past 32MB, the console nor the mapper will just not read. Just, be aware that some emulators straight up just have a file size limit, such as Kega Fusion, having a 6MB file size limit. Happy hacking! Edit: Made some small changes and added some new bits based on Devon's reply below, with proper credits of course.
Same with the 32X. What's funny is that on the 68000 side, the 4 MiB address space is banked, because the 32X's memory space is small, so you have to deal with 2 layers of bank switching. The SH-2s do have the full 4 MiB address space accessible, but you still need to take the same precautions. You also need to set the RV flag in order to manage mapper bank switching.
Wow, you are right, the 32X memory space IS small! $800000-$9FFFFF is only $1FFFFF bytes of space. Never knew that. I also couldn't find anything about this RV flag. Mind telling me more about it? :b
So, the first 512 KiB of the address space is mapped to 0x880000-0x8FFFFF, and the 4 MiB space is split into 4 1 MiB banks that are chosen and mapped to 0x900000-0x9FFFFF. The 32X also effectively takes control over the cartridge, which the Genesis was not made to handle, and so, when doing a VDP DMA from ROM, the 32X can outright mess up the DMA. As a quick and dirty hack, the RV (ROM to VRAM) flag was created, which temporarily moves most of the cartridge mapping (first 0x100 bytes are still mapped to the internal 32X 68000 vector table) back into the regular 4 MiB space at the beginning of the 68000 address space. That way, stuff like a VDP DMA from ROM, or even things related to SRAM and the mapper, don't get screwed up by the 32X having priority over the 68000 in regards to cartridge access. And yes, this means that you pretty much have to load and execute code into RAM so that the memory mapping swapping can safely be done. Also, you may have to purge the cache on the SH-2s at the areas where you perform a mapper bank switch if you aren't accessing ROM via the "cache through" area (note: ROM access is slow on the SH-2s, and "cache through", while safer, would just make it worse), or else the SH-2s will read outdated data from the cache. Also, I thought the Sega Mapper supported up to 32 MiB? Where did you get 8 MiB from?
I'm pretty sure I read it somewhere that it was a 8 MB limit. I guess I didn't double check that. It's updated anyways.
Also worth noting is that Kega Fusion limits the ROM size to 6 MiB, while Regen limits it to 5 MiB. I know that BlastEm, PicoDrive (forgot if it works on the old BizHawk version or not), and ares allow at least 32 MiB. Only PicoDrive (not the version on BizHawk) and ares allow the mapper and 32X to be used at the same time, too.
About the 8MB limit, that likely derives from the everdrives. MegaSD has 8MB, everdrive md and x series can support 14MB but is usually equip with 5MB, the X7 and mega-ed pro has 15MB, the X3, X5 and recent mega-ed core has 7MB (all of krizz's ones allocate 1MB for BIOS tasks, so if it has 8MB of PSRAM, that's 7MB of "rom" for you) Sidenote about the sega mapper with sram: The everdrives map sram to a special bank that can be mapped to any range. Annoyingly that bank changed between the everdrive md and x series, being the first 32kb of bank 28 for the ed-md, and the upper 256kb of bank 31 for the x series; only the X7 allocates a full 256kb, the X5 has 128kb, and the X3 is the same but it shares SRAM with ROM The official sega mapper spec, however, has sram pretty much working as it does for any other game: Write 1 to $A130F1, $200000-$3FFFFF gets mapped to sram, or at least you should assume that whole range is mapped.