ROM Hack Pokémon Emerald Real 512Kb Flash Memory Patch

Pikachu025

Well-Known Member
OP
Member
Joined
May 3, 2006
Messages
972
Trophies
0
Age
33
Location
Austria
XP
396
Country
Australia
If your save is already corrupted there isn't much to be done. However, I'm curious how you got into this situation. Were you using a ROM with this patch applied? Cause if so that's a serious bug that somehow even bypassed the sanity bankswitch crash. Can you upload your 'corrupted' save file?
 

Synonyx

Member
Newcomer
Joined
May 16, 2018
Messages
6
Trophies
0
Age
24
XP
64
Country
United States
If your save is already corrupted there isn't much to be done. However, I'm curious how you got into this situation. Were you using a ROM with this patch applied? Cause if so that's a serious bug that somehow even bypassed the sanity bankswitch crash. Can you upload your 'corrupted' save file?

So what I did was using the Ultimate GBA tool mentioned above, I converted a Emerald ROM into a CIA using the 512kb/Flash save type. The first CIA didn't work. I then found out you had to hex edit the GBA in order for saving to work within the VC CIA. I did that, and the game worked fine with the second CIA; I was able to save normally and played through the majority of the game problem free.

It wasn't until I got to the Elite 4 that this problem arose. For reference, I have a tendency to save once right before the Champion fight just in case. So I beat the Champion, credits rolled, and then when it took me back to the title screen, it was then I was greeted with this corrupted/damaged save message. Thinking it was a one-time thing, I restored my save using GodMode9, and beat the Champion again.

Same result.

I then took my save and attempted to use your tool to fix it. I patched it up, but made a backup of the original just in case.

I restored the save I patched with your tool back into the VC title, beat the Champion, but same result yet again.

I come here, use the NSUI to create a new CIA from the GBA ROM, I make it with the 1mb/Flash save type. Install it, runs fine and saves fine.

I experimented with my save by using your tool to convert my old save into a 1mb version for this new CIA ROM.
Made a backup, restored it, but no luck there either.

And that's where I stand now.

But I've already figured to just play through the whole game again with this new ROM and its new save type to see if it really fixed my problem.

Save file attached below.
 

Attachments

  • Original Emerald VC Save.zip
    3.1 KB · Views: 199

Pikachu025

Well-Known Member
OP
Member
Joined
May 3, 2006
Messages
972
Trophies
0
Age
33
Location
Austria
XP
396
Country
Australia
Okay, I see what's happening. The save has a configuration of blocks that is only valid if you assume reads mirror across banks, which my tool is not equipped to handle.

Attached is a fixed save for both the original game and the patched (as in, with my patch) game. I'll expand my tool to detect and handle this use case.

EDIT: Tool has been updated, new version is in the OP, or here: https://filetrip.net/dl?c0A9uKM8rS
The patch itself has not changed, just the save conversion tool.
 

Attachments

  • fixed-emerald-save.zip
    8.7 KB · Views: 254
Last edited by Pikachu025,

Synonyx

Member
Newcomer
Joined
May 16, 2018
Messages
6
Trophies
0
Age
24
XP
64
Country
United States
Okay, I see what's happening. The save has a configuration of blocks that is only valid if you assume reads mirror across banks, which my tool is not equipped to handle.

Attached is a fixed save for both the original game and the patched (as in, with my patch) game. I'll expand my tool to detect and handle this use case.

EDIT: Tool has been updated, new version is in the OP, or here: https://filetrip.net/dl?c0A9uKM8rS
The patch itself has not changed, just the save conversion tool.

Thank you so, so much my dude. You don't know how much this game means to me.

The save works fine now, and I'm playing it as I type this. <3
 
  • Like
Reactions: AhsanMC

BastianMunoz

New Member
Newbie
Joined
Jul 30, 2018
Messages
1
Trophies
0
Age
36
XP
84
Country
Mexico
Thank you so, so much my dude. You don't know how much this game means to me.

The save works fine now, and I'm playing it as I type this. <3
so what did you do to solve it? you're using the 1mb/Flash save type cia you created right, did you lost your saved right before the champion?
 

t0w3l

Well-Known Member
Newcomer
Joined
Aug 15, 2018
Messages
82
Trophies
0
XP
97
Country
United States
Just tried to use a Hex Editor to find some of the functions in a Pokemon FireRed ROM, it didn't work as I expected when I copy/pasted the Emerald modifications onto FireRed, but maybe it can be useful if you ever do a FireRed version of the patch (which would be awesome, btw) I put all the adresses where they'd be in the readme file, except for the ones I wasn't able to find on the HexEditor, which you can find at the end
The game stores the current number of saves in 0x03006200 and does a mod 2 on it to figure out if the current save is in slot 0 or 1. I modified those calculations to always select slot 0, even though I'm not entirely sure what some of the functions are used for.

1x @ 0xD98B0 -> Always select the first save slot when determining the slot to write to.
1x @ 0xD9B90 -> Always select the first save slot in this undetermined function.
1x @ 0xD9D28 -> Always select the first save slot in this undetermined function.
1x @ 0xD9DC0 -> Always select the first save slot in this undetermined function.
1x @ 0xD9E76 -> Always select the first save slot in this undetermined function.

On game init, the game reads both save slots, determines which of them are valid and which one is newer then the other (via the save counter).

5x @ 0xD9FD4 -> The read of the second save slot has been replaced to always report that the second slot is the same validity as the first slot (so you still get correct system messages for corruption and stuff), and that the second slot is always one save older than the first slot, so the game will never pick it when deciding which slot to load.

2 * 48 bytes @ 0xD9FDB -> The second save slot read code that is now skipped over has been repurposed as storage for two extra flash chip identification structures.

After the Elite 4, the game calls a special function to save the game and record the current team in the Hall of Fame. Normally, the Hall of Fame occupies two sectors of flash memory, 0x1C and 0x1D, and stores a maximum of 50 teams. With a 512K flash, we only have two spare sectors for extra data, and we still need a place to hold the recorded battles from the Battle Frontier, so I've modified the Hall of Fame reads and writes to only store 32 teams and only use one flash sector, 0x0E.

1x @ 0xDA29C, 2x @ 0xDA2AE -> When Hall of Fame data has to be erased for whatever reason, only erase sector 0xE.
1x @ 0xDA2CA -> Save the first half of the Hall of Fame to sector 0xE instead of 0x1C.
2x @ 0xDA2D0 -> Remove the write to sector 0x1D. By limiting the Hall of Fame to 32 teams, the second half is always empty and doesn't need to be written.
1x @ 0xDA338, 2x @ 0xDA34A -> Again, when Hall of Fame data has to be erased for whatever reason, only erase sector 0xE.
1x @ 0xDA56E -> Load the first half of the Hall of Fame from sector 0xE instead of 0x1C.
7x @ 0xDA580 -> memset the second half of the Hall of Fame to 0 instead of reading it from sector 0x1D.

The Battle Frontier battle recording usually saves to sector 0x1F. I remapped it to sector 0xF.

2x @ 0xDA5AC -> This seems like a sanity check that determines if the requested sector is either 0x1E or 0x1F and returns from the function with failure if it's not. Since 0xF is outside that range, I modified the check to just check for sector 0xF.
2x @ 0xDA604 -> Same sanity check.

1x @ 0xF21F6 -> Change the maximum amount of saved hall of fame records from 50 to 32.
1x @ 0xF2204 -> Same as above.
1x @ 0xF2B84 -> Change the maximum amount of loaded hall of fame records from 50 to 32.
1x @ 0xF2B92 -> Same as above.
1x @ 0xF2BBC -> Same as above.

Functions that directly access Flash memory:

11x @ 0x1DE894 -> Completely rewrite SwitchFlashBank. It now does nothing if bank 0 is selected, but hangs the game when a higher bank is selected, so we can figure out if we missed a place where the save file is accessed. This also serves as a protection for writes that would hit flash bank 1, since on devices/emulators that don't understand flash banks they would hit bank 0 and corrupt the data in it.
1x @ 0x1DEB2C, 1x @ 0x1DEB30 -> ReadFlash checks for a 1M Flash size before calling SwitchFlashBank. This check has been modified so that SwitchFlashBank is called for effectively all flash sizes.
1x @ 0x1DEBF4, 1x @ 0x1DEBF8 -> Same as above for VerifyFlashSector.
1x @ 0x1DEC80, 1x @ 0x1DEC84 -> Same as above for VerifyFlashSectorNBytes.
Note that the Program and Erase functions always call SwitchFlashBank regardless of Flash size, probably because they're supposed to be flash type specific.

String @ 0x6FBF74 -> Change the Flash identification string to claim a 512K flash (I suspect these are unused on actual hardware, but some emulators use them to detect save type).


*Not Ported from Emerald Version*

-V1.0

1x @ 0x152E1E -> Always select the first save slot in this undetermined function.

1x @ 0x15359A -> Always select the first save slot in this undetermined function.

1x @ 0x1795D2 (Possibly 0xF55CE?) -> Modify function that (re?)initializes the entire save file to only write to 0x10 sectors we now have instead of the 0x20 sectors we had.
1x @ 0x18531C -> Write to sector 0xF instead of 0x1F for the Battle Frontier's battle recording.
1x @ 0x185A58 -> Read from sector 0xF instead of 0x1F for the Battle Frontier's battle recording.
2x @ 0x1D3A92 -> If, somehow, the Trainer Hill save write function is ever called, don't call the flash write function and just claim the write failed.
2x @ 0x1D3AE0 -> Likewise, if the Trainer Hill save read function is called, don't call the flash read and just claim the read failed. This function is actually still called when Trainer Hill starts in the English version, but doesn't seem to do anything.

-V1.1

32 bit pointer @ 0x2E1D84 -> Change pointer to the location of the array of flash chip identification structures in IdentifyFlash to a new, bigger one.
5x @ 0x2E1D8C -> Change the loop that identifies the flash chip the hardware reported so it reports failure once it encounters a nullptr, rather than reporting a failure once it finds a flash chip structure with an ID of zero.

32 bit pointer @ 0x9A30DC -> Change pointer to the location of the array of flash chip identification structures in IdentifyFlash to a new, bigger one.

1 byte @ 0x9A3166, 1 byte @ 0x9A316E, 2 bytes @ 0x9A3178 -> Modify the fallback flash chip identification structure to another valid one.

24 bytes @ 0x9A31A0 -> This space is now used as a bigger array of pointers to flash chip identification structures, as the original was just 3 entries large. The original array at 0x9A30D0 is still there unmodified, but now unused, and could be repurposed if the need arises for a little bit of extra memory.

The six entries are, in order:
- Pointer to 0x8152F88, data for the SST 512K flash chip. (was instructions for read of second save slot)
- Pointer to 0x8152FB8, data for the Macronix 512K flash chip. (was instructions for read of second save slot)
- Pointer to 0x89A314C, data for the Panasonic 512K flash chip. (was fallback structure)
- Pointer to 0x89A311C, data for the Macronix 1M flash chip. (unchanged from original game)
- Pointer to 0x89A31C8, data for the Sanyo 1M flash chip. (effectively unchanged from original game)
- Null pointer to indicate end of array.
 
Last edited by t0w3l,

t0w3l

Well-Known Member
Newcomer
Joined
Aug 15, 2018
Messages
82
Trophies
0
XP
97
Country
United States
it didn't work as I expected when I copy/pasted the Emerald modifications onto FireRed
I guess it worked partially, since I was actually able to load a converted save file, but the game crashed both when I tried looking at the Hall of Fame PC and defeating the Pokemon League itself...
 

bbsan2k

Well-Known Member
Newcomer
Joined
Jul 6, 2019
Messages
83
Trophies
0
Age
34
XP
1,452
Country
Germany
Do I have and chance applying this to a German Version without digging deeper into GBA debugging?
I tried to search for the replaced bytes using a Hex editor and was able to apply about 80%, but especially when setting the new pointers I failed because of different adress layout it seems...
 
Joined
Jan 1, 2018
Messages
7,292
Trophies
2
XP
5,947
Country
United States
Do I have and chance applying this to a German Version without digging deeper into GBA debugging?
I tried to search for the replaced bytes using a Hex editor and was able to apply about 80%, but especially when setting the new pointers I failed because of different adress layout it seems...
NSUI beta 27 - ROM save type: Flash 1Mbit (Macronix, ID: 0x09C2) + RTC
 
Joined
Jan 1, 2018
Messages
7,292
Trophies
2
XP
5,947
Country
United States

bbsan2k

Well-Known Member
Newcomer
Joined
Jul 6, 2019
Messages
83
Trophies
0
Age
34
XP
1,452
Country
Germany
Ok - let me be more precise about what I actually want to do
I want to patch a german FireRed/Emerald ROM to be able to save to 512K and then patch it to use SRAM.
The reason for this is, that I want to flash this ROM to a chinese GBA clone cartridge that only has SRAM, not FLASH.
SRAM patching for 512K is easy enough using GBATA, but as the savegame will still use 1M, it does not fit the SRAM and therefore will corrupt it.
Is there any way to make this work?
 
Joined
Jan 1, 2018
Messages
7,292
Trophies
2
XP
5,947
Country
United States
Ok - let me be more precise about what I actually want to do
I want to patch a german FireRed/Emerald ROM to be able to save to 512K and then patch it to use SRAM.
The reason for this is, that I want to flash this ROM to a chinese GBA clone cartridge that only has SRAM, not FLASH.
SRAM patching for 512K is easy enough using GBATA, but as the savegame will still use 1M, it does not fit the SRAM and therefore will corrupt it.
Is there any way to make this work?

[romhacking.net] Pokémon Emerald Real 512Kb Flash Memory Patch

I patched the German version of the game, 2185 - Pokemon - Smaragd-Edition (G).gba (Size: 16.0 MB - CRC32: 34C9DF89) with Floating IPS. The output rom had the hash (FB735997). The game seems to work fine with desktop mGBA despite patch being meant for the Pokemon - Emerald Version.gba (1F1C08FB).
 
  • Like
Reactions: bbsan2k
Joined
Jan 1, 2018
Messages
7,292
Trophies
2
XP
5,947
Country
United States
Will doing that fix the corrupt save file after completing the elite four?
It should? ¯\_(ツ)_/¯

Play the prepatched Emerald rom with the save on desktop mGBA emulator. Make a savestate of your progress. Switch over to a clean rom dump of Pokemon Emerald.
Load up the savestate and make an in-game save to create the 128 KB .sav file.

Inject the good .gba rom in NSUI, and restore the save with GodMode9.
 

Site & Scene News

Popular threads in this forum

General chit-chat
Help Users
  • Xdqwerty
    what are you looking at?
  • BakerMan
    I rather enjoy a life of taking it easy. I haven't reached that life yet though.
    SylverReZ @ SylverReZ: @AncientBoi, https://www.youtube.com/watch?v=7jUWpmU-X8k