GerbilSoft, on 23 September 2011 - 10:32 PM, said:
The 512 KB code limitation is actually due to an error in Gens, and isn't a limitation in hardware. The problem in this case is that Starscream (Gens' 68000 emulator) has two fetch functions: one for instruction fetch and one for data fetch. The data fetch function is properly managed by Gens' SSF2 mapper, but the instruction fetch function is not. Hence, if you have any banks swapped out, executing code there will act like the bank isn't swapped, which can cause weird issues. (I recommended the first 512 KB because that's guaranteed to not be swapped.)
I will eventually fix this limitation in Gens/GS II. I don't think Kega or Regen have this issue, and the real system obviously doesn't.
If you end up putting code in a swappable area, that's fine. It'll break on older Gens, but it'll give me a test case to fix the SSF2 instruction fetch mapping in Gens/GS II.
(tl;dr version; if you execute code in a ROM bank that's been swapped with another bank, it will break on Gens and most Gens derivatives, but should work on Kega, Regen, and actual hardware.)
Great, thanks for the explanation. Here's a memory map of Sonic VR, taken straight from my notes. As you can see, I didn't manage to fit all the code into the first 512KB (bank 0). However, my "music playing area" is in banks 1-3, so these are the ones that get swapped in and out. The rest of the game code comes after this in bank 4, so I don't think I'll actually hit this issue. Is that right?
;0 0x000000 - 0x07FFFF Sonic 2 code, Sonic VR sound driver, art & 01_mermaid
;1 0xA130F3: 0x080000 - 0x0FFFFF 01_mermaid
;2 0xA130F5: 0x100000 - 0x17FFFF 01_mermaid
;3 0xA130F7: 0x180000 - 0x1FFFFF 01_mermaid
;4 0xA130F9: 0x200000 - 0x27FFFF Sonic 1 objects, Sonic VR code, art & 03_mess
;5 0xA130FB: 0x280000 - 0x2FFFFF 03_mess
;6 0xA130FD: 0x300000 - 0x37FFFF 03_mess
;7 0xA130FF: 0x380000 - 0x3FFFFF 00_helix_nebula
;8 0x400000 - 0x47FFFF 00_helix_nebula
;9 0x480000 - 0x4FFFFF 00_helix_nebula & 02_blackout_city
;A 0x500000 - 0x57FFFF 02_blackout_city
;B 0x580000 - 0x5FFFFF 02_blackout_city
By the way, if anybody's considering using bankswitching in their own hack, it's really easy to do (although it doesn't seem to be well documented online for some reason, which is why I'm mentioning it here). The ROM is divided into 512KB banks, so a ROM with the maximum size of 4MB will have banks 0-7. These are represented by the odd numbered 0xA130F# registers you can see above. If I want to get to banks 8-$B (the remaining four banks between 4MB and 6MB), I just move the bank number that I want to access into the register that corresponds to the address range I want to use to access it. For example, to play track 0 - Helix Nebula, I just do this:
And then tell the sound driver to start playing from address 0x080000. Simple!
The register 0xA130F1 doesn't appear on the list above because the first bank can't be switched. However, if you've used SRAM in your hack you'll have seen it before. That's because it's used for a slightly different type of bankswitching - setting a 1 here will cause the address range 0x200000-0x3FFFFF to represent RAM instead of ROM, allowing you to write values here to be saved in SRAM. Set 0xA130F1 back to 0 to have this address range behave as normal again.