nesdev.com
http://forums.nesdev.com/

Fixing ROMs for EMS 64 GB Smart Card USB
http://forums.nesdev.com/viewtopic.php?f=20&t=5804
Page 1 of 22

Author:  Great Hierophant [ Sat Dec 05, 2009 3:03 pm ]
Post subject:  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?

Author:  kyuusaku [ Sat Dec 05, 2009 3:45 pm ]
Post subject: 

1.

Author:  Great Hierophant [ Sat Dec 05, 2009 9:25 pm ]
Post subject: 

kyuusaku wrote:
1.


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?

Author:  kyuusaku [ Sat Dec 05, 2009 9:50 pm ]
Post subject: 

You'd have to put breakpoints on MBC writes, determine what write breaks what, then fix it.

Author:  Great Hierophant [ Sun Dec 06, 2009 9:53 am ]
Post subject: 

Or if the Game uses a value greater than what the MBC originally would have expected, then it may change to a random bank.

Author:  Great Hierophant [ Mon Dec 07, 2009 8:15 pm ]
Post subject: 

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.

Author:  Dwedit [ Mon Dec 07, 2009 8:49 pm ]
Post subject: 

Zelda Oracles uses mirrored banks, so I doubt it's number 3.

Author:  MottZilla [ Mon Dec 07, 2009 11:58 pm ]
Post subject: 

If it's the bank switching numbering you should be able to do a minor ASM hack to fix the number on the fly. You just need to find the mapper writes and patch them so if the write is going to be zero to write 1 instead. Shouldn't be hard at all.

Author:  Great Hierophant [ Tue Dec 08, 2009 9:52 am ]
Post subject: 

This is where I need help. A typical bankswitch command is sometimes as simple as

Code:
ld (2100), a


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.

Author:  tokumaru [ Tue Dec 08, 2009 10:30 am ]
Post subject: 

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.

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.

Quote:
Also, I would need to figure out all instances where this would occur.

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.

Author:  MottZilla [ Tue Dec 08, 2009 12:56 pm ]
Post subject: 

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.

Author:  tokumaru [ Tue Dec 08, 2009 4:35 pm ]
Post subject: 

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:
   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

Author:  Dwedit [ Tue Dec 08, 2009 4:59 pm ]
Post subject: 

Pretty much correct, except people would usually use a one byte flag update instruction (like OR A or AND A) instead of CP 0.

Author:  Great Hierophant [ Tue Dec 08, 2009 7:58 pm ]
Post subject: 

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:
   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


This code will fix the problems in:
Megaman V
Game & Watch Gallery
Pokemon Red/Blue
Kung Fu Master
Pyrmaids of Ra
Asteroids & Missile Command

Author:  MottZilla [ Tue Dec 08, 2009 9:05 pm ]
Post subject: 

So are you asking a question or telling us you did that and it fixed those? I'm not sure what you are saying exactly.

Page 1 of 22 All times are UTC - 7 hours
Powered by phpBB® Forum Software © phpBB Group
http://www.phpbb.com/