Fixing ROMs for EMS 64 GB Smart Card USB
-
- Posts: 780
- Joined: Tue Nov 23, 2004 9:35 pm
Fixing ROMs for EMS 64 GB Smart Card USB
I have an EMS 64 GB Smart Card USB, and while almost all Gameboy & Gameboy Color games work in it, there are a few that do not. The list is here:
Super Mario Land 2 (see BF)
Megaman V (blank screen)
Who Framed Roger Rabbit (garbled copyright screen, resets)
Gargoyle's Quest (see BF)
Donkey Kong Land 3 (blank screen)
Game & Watch Gallery (wrong music, graphical garbage, resetting)
Asteroids & Missile Command (mostly blank screen, random lines)
Kung Fu Master
Pyrmaids of Ra
RoboCop v. the Terminator (see BF)
SeaQuest DSV (see BF)
Spiderman and the X-Men: Arcade's Revenge (see BF)
Gauntlet II (garbled initial screen)
Pokemon Red/Blue (garbled "Ed" tile in name select screen)
I can only think of three reasons why these games would not work:
1. Improper Bankswitch Emulation in the cart
2. Flash is too slow
3. Cart's setup conflicts with Game code
The Bung Fixes solve the Super Mario Land 2 problem (garbled map screen) and makes Gargoyle's Quest, (blank screen), SeaQuest (garbled screen) Spider-Man & X-Men (ditto) & RoboCop v. Terminator (ditto). It improves Who Framed Roger Rabbit (first copyright screen visible, will go no further) but not Pyramids or Kung Fu Master. However, the Fixes only change one string starting with EA 00 (other than the global checksum). What does this do and how can I improve and fix the other ROMs?
Super Mario Land 2 (see BF)
Megaman V (blank screen)
Who Framed Roger Rabbit (garbled copyright screen, resets)
Gargoyle's Quest (see BF)
Donkey Kong Land 3 (blank screen)
Game & Watch Gallery (wrong music, graphical garbage, resetting)
Asteroids & Missile Command (mostly blank screen, random lines)
Kung Fu Master
Pyrmaids of Ra
RoboCop v. the Terminator (see BF)
SeaQuest DSV (see BF)
Spiderman and the X-Men: Arcade's Revenge (see BF)
Gauntlet II (garbled initial screen)
Pokemon Red/Blue (garbled "Ed" tile in name select screen)
I can only think of three reasons why these games would not work:
1. Improper Bankswitch Emulation in the cart
2. Flash is too slow
3. Cart's setup conflicts with Game code
The Bung Fixes solve the Super Mario Land 2 problem (garbled map screen) and makes Gargoyle's Quest, (blank screen), SeaQuest (garbled screen) Spider-Man & X-Men (ditto) & RoboCop v. Terminator (ditto). It improves Who Framed Roger Rabbit (first copyright screen visible, will go no further) but not Pyramids or Kung Fu Master. However, the Fixes only change one string starting with EA 00 (other than the global checksum). What does this do and how can I improve and fix the other ROMs?
Last edited by Great Hierophant on Sun Dec 06, 2009 9:50 am, edited 3 times in total.
-
- Posts: 780
- Joined: Tue Nov 23, 2004 9:35 pm
That would make sense. I would suggest that the Card is emulating an MCB5, which can cause some difficulty for older games. If an MCB1-3 game writes to somewhere in the 3000-3FFF range to switch banks, it may likely end up with something very different that what it expects. How does one figure out which bytes are used for bankswitching?kyuusaku wrote:1.
-
- Posts: 780
- Joined: Tue Nov 23, 2004 9:35 pm
-
- Posts: 780
- Joined: Tue Nov 23, 2004 9:35 pm
I can confirm that it is the MBC that is causing the trouble here. In every case, if you switch the 0x147 from an MBC1/2/3 type to an MCB5 type and play them in an emulator like bgb, you will encounter the exact same problems with each ROM as on the Gameboy.
Now on MBC5, there are three instances where the problem can occur:
1. Game writes to 3000-3FFF to perform a bankswitch
2. Game writes a 00 value to perform a bankswitch, seeking to select bank 1 on an MBC1/2/3, but selects bank 0 on an MBC5.
3. Game writes a value greater than 1F (MBC1), F (MBC2), 7F (MBC3) to switch a bank on MBC5, the upper bits selecting some random bank.
In many cases, it seems like number #2 is occuring. The Bung Fixes are supposed to address #1, and if they cannot do so alone, then one must adjust for #2.
Now on MBC5, there are three instances where the problem can occur:
1. Game writes to 3000-3FFF to perform a bankswitch
2. Game writes a 00 value to perform a bankswitch, seeking to select bank 1 on an MBC1/2/3, but selects bank 0 on an MBC5.
3. Game writes a value greater than 1F (MBC1), F (MBC2), 7F (MBC3) to switch a bank on MBC5, the upper bits selecting some random bank.
In many cases, it seems like number #2 is occuring. The Bung Fixes are supposed to address #1, and if they cannot do so alone, then one must adjust for #2.
-
- Posts: 780
- Joined: Tue Nov 23, 2004 9:35 pm
This is where I need help. A typical bankswitch command is sometimes as simple as
where register a contains the number of the bank to which the program wants to access. In these cases, a contains 00 and the MBC1/2/3 understands that to switch to bank 1 while the MCB5 will switch to bank 0.
My trouble is trying to figure out where previously in the code the program set register a to 00 and how to tell it to write a 01 without breaking anything else. Also, I would need to figure out all instances where this would occur.
Code: Select all
ld (2100), a
My trouble is trying to figure out where previously in the code the program set register a to 00 and how to tell it to write a 01 without breaking anything else. Also, I would need to figure out all instances where this would occur.
Instead of worrying about what happened before, it would be much easier to replace the actual write by a call to a subroutine, which you'll place wherever you can. In this routine you can modify the value as desired and then write it. Just save and restore whatever flags or registers you mess with and you should be OK.Great Hierophant wrote:My trouble is trying to figure out where previously in the code the program set register a to 00 and how to tell it to write a 01 without breaking anything else.
I don't know much about the GB scene, but there's an emulator with good debugging capabilities you can just trap all writes to the registers in question so you know where they happen. You can also search the ROM for the 2 bytes that represent the address of the register and check if each instance of it is actually a bankswitch command, and replace by the call to the subroutine.Also, I would need to figure out all instances where this would occur.
This is exactly what you want to do. I'm not particularly good with Z80 type ASM since I have rarely been involved with it but you should be able to replace the actual write opcode to the register with a JSR type command to some free space in the Fixed ROM bank. All you need here is to check the contents of the value to be written for being 0 which should probably be easily determined by a CMP or perhaps just a BNE type command so that you can load the value with 1 if it was 0 and do nothing if it was not 0 and then do the write you replaced with the JSR followed by a RTS.
Again I'm not experienced with Z80 type ASM so I can't really be specific. But it really should't be that hard to do. Not unless the fixed bank is jam packed and you have no free rom space.
Again I'm not experienced with Z80 type ASM so I can't really be specific. But it really should't be that hard to do. Not unless the fixed bank is jam packed and you have no free rom space.
I don't know much Z80 either, but from what I've read "ld (2100), a" can easily be replaced by "call XXXX" (XXXX is the location you found to place your subroutine), because both instructions occupy the same amount of bytes (3).
Then, if all you need is turn 0's into 1's, the routine can be something like this (note that I never coded Z80 before, so I don't know if this is the best way to do it or if it works at all):
Then, if all you need is turn 0's into 1's, the routine can be something like this (note that I never coded Z80 before, so I don't know if this is the best way to do it or if it works at all):
Code: Select all
push af ;save the flags and a
cp 0 ;compare a to 0
jr nz, skip ;skip if not equal
inc a ;correct the value
skip:
ld (2100), a ;switch the bank
pop af ;restore the flags and a
ret ;return
-
- Posts: 780
- Joined: Tue Nov 23, 2004 9:35 pm
This code will fix the problems in:tokumaru wrote:I don't know much Z80 either, but from what I've read "ld (2100), a" can easily be replaced by "call XXXX" (XXXX is the location you found to place your subroutine), because both instructions occupy the same amount of bytes (3).
Then, if all you need is turn 0's into 1's, the routine can be something like this (note that I never coded Z80 before, so I don't know if this is the best way to do it or if it works at all):
Code: Select all
push af ;save the flags and a cp 0 ;compare a to 0 jr nz, skip ;skip if not equal inc a ;correct the value skip: ld (2100), a ;switch the bank pop af ;restore the flags and a ret ;return
Megaman V
Game & Watch Gallery
Pokemon Red/Blue
Kung Fu Master
Pyrmaids of Ra
Asteroids & Missile Command
Last edited by Great Hierophant on Tue Dec 08, 2009 9:30 pm, edited 3 times in total.