ROM Hack Reverse engineering GBA patching

FAST6191

Techromancer
OP
Editorial Team
Joined
Nov 21, 2005
Messages
36,798
Trophies
3
XP
28,321
Country
United Kingdom
First things first this is just an idea I have been toying with for a while and I have way to many projects on the go to devote much time to this right now. I just thought I might start some discussion and write up what I know/think.

Background/introduction.

The GBA is near enough dead and despite the greatness that is the DS the GBA library is not to be overlooked. Unknown 1.1 versions and 2 in 1 packs aside I doubt we will ever see another good game released and the rom hacking community has taken to the GBA is quite a big way too.

Now GBA roms most people use either their own client (EZ4Client/M3/G6 stuff) or GBATA to patch roms, the main problem with some of these is the limited scope/ability (despite having stuff for RTC in the DLL responsible (which contains vast tracts of code seemingly copied and pasted from EZ1/2/3 patching routines for the curious) the EZ4 Client app does not touch it). Others advocate the use of stuff like GBATA in place of the "official" apps.

From conversations with moleDJ (creator of the now defunct EZ4 Client plus: a .net rom manager with EZ4 patching capabilities) way back as well as my own testing I recall 90% of patching (as far as the EZ4 and now 3 in 1 is concerned) is merely a couple of bytes changed in the header and later in the binary (the stuff concerning the save). Rather than implement EZ4 Client's/GBATA's functions moleDJ remade them into what was essentially his own app. Sadly though the source was never obtained for this.

the "tech" stuff.

Not so much detail here right now as that is one of the things required.

Some more detail the GBA uses 4 saving types: SRAM, Flash, EEPROM and, whilst not technically a save type, none/password. The changes made to roms being patched broadly fall into those 4 categories (the exceptions being stuff like EEPROM detection (examples: classic nes and dragon ball games), motion/light sensor (warioware and boktai, and RTC (pokemon)) with it being relatively simple stuff. The few minor variations that have an effect like EEPROM v124 (mainly 256Mbit titles) should not be difficult to take of.

The project is probably easier to pull off in a "clean room" style reverse engineering project (patch files and binary compare) rather than busting out the disassemblers/emulators/bus monitors/memory viewers (save perhaps for the rom that has been patched and some confirmation is desired).

As usual GBAtek is possibly the most useful document in existence (at least until this project is written up).
http://nocash.emubase.de/gbatek.htm

Some potential problems/points for discussion:
should "odd" rom support be added (personally I favour "odd" patches being integrated into a DLL or similar) how might they be detected:
hashing works but rom hacks and trimming screw that one up not to mention hashes probably need a separate list (which from experience I can tell you will get large especially as something better than CRC32 is needed: and will have to be generated (unless no-intro have a full md5 library). The GBA is effectively defunct though so a list could conceivably be a one time thing.

Header detection: a suitable amount of header data will have to be used (the name/serial alone can mess up in the case of v1.1 titles (which a good number of popular games got)) and once again a list may be needed.

Naming: input=output or similar is OK but potentially undesirable, the header does not contain anything good like it does on the DS and we are left with the list option again.

What to code it in: I will not hide the fact that a cross platform (i.e. non windows) GBA patcher is sorely needed (WINE just about cuts it for some) and is one of the main reasons for suggesting this project. Performance is not really an issue (any language that takes more than 10 seconds to do a very minor bit of file i/o (not all can bear in mind) like this does not warrant my attention), the question then is do many binaries exist or are the users to be restricted to/bound by a framework (both have their merits and disadvantages: I feel a simple project like this could quite easily do both however). I would love a GBA/DS code patcher a la the recently released/ported DS code DLDI patcher (DLDI is for both GBA and DS remember) but that is getting well ahead of the game (the ultimate goal could even be GBA autopatching which some, perhaps unjustifiably, desire).

GUI/input issues are somewhat of a when all is said and done thing: whatever happens command line parsing/input is a real must for me (I do more and more at batch file/command line level, it is also far easier to chain apps together (decompression mainly) this way and make a batch file). I however would like to consider myself a somewhat advanced computer user, others really prefer a GUI.
Documentation: I tend to document all that I do and would like that to continue here, both the effects and any "lists" that are used. I doubt very much any potential contributors will have a problem with this but I am putting it up anyway (I would personally go for a public domain release of the source as well but we shall see there)
Other patches/support: comes under my command line request but do PAR2 files get supported (I have been using a few of these lately rather than messing with "clean rom patches"), do IPS, BSdiff and XDelta get a look in as well? (all 4 items are extensively documented and/or have ports/source to most major operating systems). Are these DLL/external app based or built in?

Maybe a subject for later releases but should in game reset be added (there are several tools and apps that be used to check), should sleep be added (Dwedit recently released an app for it) or even cheats (I dare say they are very much desired and mondayz created a nice base in GABSharky).



It is now two in the morning so I am out. I may think of some more stuff and realise what a mess of typos this is in the morning but this is just to get it out there.
 

Azimuth

Chicken Teriyaki Boy!
Member
Joined
Feb 23, 2006
Messages
637
Trophies
0
Website
Visit site
XP
110
Country
Canada
Just what I needed, I am trying to code a g6 patcher(CLI first then maybe GUI) for *nix since the current Windows version is really unstable in WINE.

I tried the whole reverse engineering through binary/hex comparison, it takes too damn long to find a relevant pattern and gets really boring but I suppose it is possible.

A low level language will be needed, maybe for the GUI elements we could use higher level languages and embed the file manipulation functions?

I have one concern though, aren't gba roms patched according to the flashcart?

Count me in, time to learn some C and Gtk programming
smile.gif
 

chuckstudios

Putting the pro in procrastination
Member
Joined
Jul 19, 2006
Messages
890
Trophies
0
Age
124
Location
North Carolina, USA
Website
www.schlarp.com
XP
275
Country
United States
They aren't usually patched by flashcart except for some specific functions such as the Realtime Saving on the M3 Perfect brand. Mostly they are just patched to work with SRAM.


(also, I would love to use this tool when it's finished... unfortunately, I probably lack the skills to help make it)
 

FAST6191

Techromancer
OP
Editorial Team
Joined
Nov 21, 2005
Messages
36,798
Trophies
3
XP
28,321
Country
United Kingdom
Despite having more pressing concerns I found myself doing some work on the subject (VBA sourcecode is not half bad for a push in the right direction (it is very simplistic), as an aside with the initial work I have done I could probably cure a lot of ills with the autodetection as well). I think I missed a few of my results out as well.

All work done using GBATA at this stage.

Save type detection
It is known what types there are (FLASH, EEPROM and SRAM) and they are nicely labelled in ASCII in the ROM (a cursory examination of the saveless titles suggests there is nothing in there).
The subtypes are in the same ASCII as well.

As for changes I have not done much but I tested some EEPROM v126 and V120 titles (to my knowledge there are only V111, v120, v121, v122, v124 and v126 with the version numbers getting higher the later in the GBA life).
In EEPROM 2 main sections are changed (I have yet to determine how to locate via opcodes/header (and I doubt it can easily be done) but a binary search should yield a result).
The both sections are changed in the same manner and seem to be to be common between v120 and v126. The difference is in the distance between patching:

I also checked 2 32 Mbyte EEPROM v126 titles (yggdra union and shamu's deep sea adventures)

SRAM: not much work done yet. Something that move prove valuable is that the Mr Driller 2 titles vary in save type between the EU and U versions (v103 and v100 respectively).

Flash. Nothing yet.

Edit: if this pans out like I think it will (same patching needed for different but detectable save types but at different offsets) I suggest an app to search for the save type and then the save location followed by a final patch from a "library".

I have messed around with some ASM but nothing definitive yet, it will perhaps make more sense if I throw some of the different flash cart patching in there.
 

TrolleyDave

Philosolosophising
Former Staff
Joined
Jan 1, 2007
Messages
7,761
Trophies
1
Age
52
Location
Wales, UK
XP
933
Country
edit : Fixes (03/12/08)
Shortened the unpatched length for most save types.

I've managed to write succesful patching routines for save types Flash_V12X and Eeprom_V12X. The procedure is pretty straightforward for these save types which is why I tackled it first.

The following are the byte patterns to search for and what to replace them with :

Save Pattern Blocks for Flash1M_V102
Unpatched block 1 (48 Bytes)
($aa,$21,$19,$70,$05,$4a,$55,$21,$11,$70,$b0,$21,$19,$70,
$e0,$21,$09,$05,$08,$70,$70,$47,$55,$55,$00,$0e,$aa,$2a,$00,$0e,
$30,$b5,$91,$b0,$68,$46,$00,$f0,$f3,$f8,$6d,$46,$01,$35,$06,$4a,
$aa,$20)

Patch with (136 Bytes)
($80,$21,$09,$02,$09,$22,$12,$06,$9f,$44,$11,$80,$03,$49,
$c3,$02,$c9,$18,$11,$80,$70,$47,$fe,$ff,$ff,$01,$00,$00,$00,$00,
$30,$b5,$91,$b0,$68,$46,$00,$f0,$f3,$f8,$6d,$46,$01,$35,$06,$4a,
$aa,$20,$00,$00,$05,$49,$55,$20,$00,$00,$90,$20,$00,$00,$10,$a9,
$03,$4a,$10,$1c,$08,$e0,$00,$00,$55,$55,$00,$0e,$aa,$2a,$00,$0e,
$20,$4e,$00,$00,$08,$88,$01,$38,$08,$80,$08,$88,$00,$28,$f9,$d1,
$0c,$48,$13,$20,$13,$20,$00,$06,$04,$0c,$e0,$20,$00,$05,$62,$20,
$62,$20,$00,$06,$00,$0e,$04,$43,$07,$49,$aa,$20,$00,$00,$07,$4a,
$55,$20,$00,$00,$f0,$20,$00,$00,$00,$00)

Unpatched Block 2 (24 Bytes)
($14,$49,$aa,$24,$0c,$70,$13,$4b,$55,$22,$1a,$70,$80,$20,$08,$70,
$0c,$70,$1a,$70,$10,$20,$08,$70)
Patch with
($0e,$21,$09,$06,$ff,$24,$80,$22,$13,$4b,$52,$02,$01,$3a,$8c,$54,
$fc,$d1,$00,$00,$00,$00,$00,$00)

Unpatched Block 3 (22 Bytes)
($aa,$25,$0d,$70,$13,$4b,$55,$22,$1a,$70,$80,$20,$08,$70,$0d,$70,
$1a,$70,$30,$20,$20,$70)
Patch with
($ff,$25,$08,$22,$00,$00,$52,$02,$01,$3a,$a5,$54,$fc,$d1,$00,$00,
$00,$00,$00,$00,$00,$00)

Unpatched Block 4 (12 Bytes)
($22,$70,$09,$4b,$55,$22,$1a,$70,$a0,$22,$22,$70)
Patch with
($00,$00,$09,$4b,$55,$22,$00,$00,$a0,$22,$00,$00)

Save Pattern Blocks for Flash1M_V103
Unpatched Block 1 (98 Bytes)
($05,$4b,$aa,$21,$19,$70,$05,$4a,$55,$21,$11,$70,$b0,$21,$19,$70,
$e0,$21,$09,$05,$08,$70,$70,$47,$55,$55,$00,$0e,$aa,$2a,$00,$0e,
$30,$b5,$91,$b0,$68,$46,$00,$f0,$f3,$f8,$6d,$46,$01,$35,$06,$4a,
$aa,$20,$10,$70,$05,$49,$55,$20,$08,$70,$90,$20,$10,$70,$10,$a9,
$03,$4a,$10,$1c,$08,$e0,$00,$00,$55,$55,$00,$0e,$aa,$2a,$00,$0e,
$20,$4e,$00,$00,$08,$88,$01,$38,$08,$80,$08,$88,$00,$28,$f9,$d1,
$0c,$48)
Patch with (138 Bytes)
($05,$4b,$80,$21,$09,$02,$09,$22,$12,$06,$9f,$44,$11,$80,$03,$49,
$c3,$02,$c9,$18,$11,$80,$70,$47,$fe,$ff,$ff,$01,$00,$00,$00,$00,
$30,$b5,$91,$b0,$68,$46,$00,$f0,$f3,$f8,$6d,$46,$01,$35,$06,$4a,
$aa,$20,$00,$00,$05,$49,$55,$20,$00,$00,$90,$20,$00,$00,$10,$a9,
$03,$4a,$10,$1c,$08,$e0,$00,$00,$55,$55,$00,$0e,$aa,$2a,$00,$0e,
$20,$4e,$00,$00,$08,$88,$01,$38,$08,$80,$08,$88,$00,$28,$f9,$d1,
$0c,$48,$13,$20,$13,$20,$00,$06,$04,$0c,$e0,$20,$00,$05,$62,$20,
$62,$20,$00,$06,$00,$0e,$04,$43,$07,$49,$aa,$20,$00,$00,$07,$4a,
$55,$20,$00,$00,$f0,$20,$00,$00,$00,$00)

Unpatched block 2 (24 bytes)
($14,$49,$aa,$24,$0c,$70,$13,$4b,$55,$22,$1a,$70,$80,$20,$08,$70,
$0c,$70,$1a,$70,$10,$20,$08,$70)
Patch with
($0e,$21,$09,$06,$ff,$24,$80,$22,$13,$4b,$52,$02,$01,$3a,$8c,$54,
$fc,$d1,$00,$00,$00,$00,$00,$00)

Unpatched block 3 (22 Bytes)

($aa,$25,$0d,$70,$14,$4b,$55,$22,$1a,$70,$80,$20,$08,$70,$0d,$70,
$1a,$70,$30,$20,$20,$70)
Patch with
($ff,$25,$08,$22,$00,$00,$52,$02,$01,$3a,$a5,$54,$fc,$d1,$00,$00,
$00,$00,$00,$00,$00,$00)

Unpatched block 4 (12 Bytes)
($10,$70,$0b,$49,$55,$20,$08,$70,$a0,$20,$10,$70)
Patch with
($00,$00,$0b,$49,$55,$20,$00,$00,$a0,$20,$00,$00)

Unpatched block 5 (12 bytes)
($22,$70,$09,$4b,$55,$22,$1a,$70,$a0,$22,$22,$70)
Patch with
($00,$00,$09,$4b,$55,$22,$00,$00,$a0,$22,$00,$00)


Save Pattern Blocks for Flash512_V130, V131, V133
Unpatched block 1 (38 Bytes)
($f0,$b5,$a0,$b0,$0d,$1c,$16,$1c,$1f,$1c,$03,$04,$1c,$0c,$0f,$4a,
$10,$88,$0f,$49,$08,$40,$03,$21,$08,$43,$10,$80,$0d,$48,$00,$68,
$01,$68,$80,$20,$80,$02)
Patch with
($70,$b5,$a0,$b0,$00,$03,$40,$18,$e0,$21,$09,$05,$09,$18,$08,$78,
$10,$70,$01,$3b,$01,$32,$01,$31,$00,$2b,$f8,$d1,$00,$20,$20,$b0,
$70,$bc,$02,$bc,$08,$47);

Unpatched block 2 (8 Bytes)
($ff,$f7,$88,$fd,$00,$04,$03,$0c)
Patch with
($1b,$23,$1b,$02,$32,$20,$03,$43)

Unpatched block 3 (8 Bytes)
($70,$b5,$90,$b0,$15,$4d,$29,$88)
Patch with
($00,$b5,$00,$20,$02,$bc,$08,$47)

Unpatched block 4 (8 Bytes)
($70,$b5,$46,$46,$40,$b4,$90,$b0)
Patch with
($00,$b5,$00,$20,$02,$bc,$08,$47)

Unpatched block 5 (24 Bytes)
($f0,$b5,$90,$b0,$0f,$1c,$00,$04,$04,$0c,$03,$48,
$00,$68,$40,$89,$84,$42,$05,$d3,$01,$48,$41,$e0)
Patch with (42 Bytes)
($7c,$b5,$90,$b0,$00,$03,$0a,$1c,$e0,$21,$09,$05,
$09,$18,$01,$23,$1b,$03,$10,$78,$08,$70,$01,$3b,
$01,$32,$01,$31,$00,$2b,$f8,$d1,$00,$20,$10,$b0,
$7c,$bc,$02,$bc,$08,$47);

Save Pattern Block for Eeprom_V120-V122
Unpatched Block 1 (20 Bytes)
($a2,$b0,$0d,$1c,$00,$04,$03,$0c,$03,$48,$00,$68,$80,$88,$83,$42,$05,$d3,$01,$48,$48,$e0)
Patch with (38 Bytes)
($00,$04,$0a,$1c,$40,$0b,$e0,$21,$09,$05,$41,$18,$07,$31,$00,$23,$08,$78,$10,$70,$01,$33,
$01,$32,$01,$39,$07,$2b,$f8,$d9,$00,$20,$70,$bc,$02,$bc,$08,$47)

Unpatched Block 2 (22 Bytes)
($30,$b5,$a9,$b0,$0d,$1c,$00,$04,$04,$0c,$03,$48,$00,$68,$80,$88,$84,$42,$05,$d3,$01,$48,
$59,$e0)
Patch with (40 Bytes)
($70,$b5,$00,$04,$0a,$1c,$40,$0b,$e0,$21,$09,$05,$41,$18,$07,$31,$00,$23,$10,$78,$08,$70,
$01,$33,$01,$32,$01,$39,$07,$2b,$f8,$d9,$00,$20,$70,$bc,$02,$bc,$08,$47)

Save Pattern Block for Eeprom_V124
Unpatched Block 1 (20 Bytes)
($a2,$b0,$0d,$1c,$00,$04,$03,$0c,$03,$48,$00,$68,$80,$88,$83,$42,$05,$d3,$01,$48,$48,$e0)
Patch with (38 Bytes)
($00,$04,$0a,$1c,$40,$0b,$e0,$21,$09,$05,$41,$18,$07,$31,$00,$23,$08,$78,$10,$70,$01,$33,
$01,$32,$01,$39,$07,$2b,$f8,$d9,$00,$20,$70,$bc,$02,$bc,$08,$47)

Unpatched Block 2 (22 Bytes)
($f0,$b5,$ac,$b0,$0d,$1c,$00,$04,$01,$0c,$12,$06,$17,$0e,$03,$48,$00,$68,$80,$88,$81,$42,
$05,$d3)
Patch with (40 Bytes)
($70,$b5,$00,$04,$0a,$1c,$40,$0b,$e0,$21,$09,$05,$41,$18,$07,$31,$00,$23,$10,$78,$08,$70,
$01,$33,$01,$32,$01,$39,$07,$2b,$f8,$d9,$00,$20,$70,$bc,$02,$bc,$08,$47)

Save Pattern Blocks for Eeprom_V126
Unpatched Block 1 (20 Bytes)
($a2,$b0,$0d,$1c,$00,$04,$03,$0c,$03,$48,$00,$68,$80,$88,$83,$42,$05,$d3,$01,$48,$48,$e0)
Patch with (38 Bytes)
($00,$04,$0a,$1c,$40,$0b,$e0,$21,$09,$05,$41,$18,$07,$31,$00,$23,$08,$78,$10,$70,$01,$33,
$01,$32,$01,$39,$07,$2b,$f8,$d9,$00,$20,$70,$bc,$02,$bc,$08,$47)

Unpatched Block 2 (22 Bytes)
($f0,$b5,$47,$46,$80,$b4,$ac,$b0,$0e,$1c,$00,$04,$05,$0c,$12,$06,$12,$0e,$90,$46,$03,$48,
$00,$68)
Patch with (40 Bytes)
($70,$b5,$00,$04,$0a,$1c,$40,$0b,$e0,$21,$09,$05,$41,$18,$07,$31,$00,$23,$10,$78,$08,$70,
$01,$33,$01,$32,$01,$39,$07,$2b,$f8,$d9,$00,$20,$70,$bc,$02,$bc,$08,$47)

Save Pattern Block for Flash_v120 + Flash_v121
Unpatched Block 1 (12 Bytes)
($90,$b5,$93,$b0,$6f,$46,$39,$1d,$08,$1c,$00,$f0);
Patch with (14 Bytes)
($00,$b5,$3d,$20,$00,$02,$1f,$21,$08,$43,$02,$bc,$08,$47);

Unpatched Block 2 (35 Bytes)
($80,$b5,$94,$b0,$6f,$46,$39,$1c,$08,$80,$38,$1c,$01,$88,$0f,$29,$04,$d9,$01,$48,$56,$e0,$00,
$00,$ff,$80,$00,$00,$23,$48,$23,$49,$0a,$88,$23)
Patch with (36 bytes)
($7c,$b5,$00,$07,$00,$0c,$e0,$21,$09,$05,$09,$18,$01,$23,$1b,$03,$ff,$20,$08,$70,$01,$3b,$01, $31,$00,$2b,$fa,$d1,$00,$20,$7c,$bc,$02,$bc,$08,$47)

Unpatched Block 3 (42 Bytes)
($80,$b5,$94,$b0,$6f,$46,$79,$60,$39,$1c,$08,$80,$38,$1c,$01,$88,$0f,$29,$03,$d9,$00,$48,$73,
$e0,$ff,$80,$00,$00,$38,$1c,$01,$88,$08,$1c,$ff,$f7,$21,$fe,$39,$1c,$0c,$31)
Patch with
($7c,$b5,$90,$b0,$00,$03,$0a,$1c,$e0,$21,$09,$05,$09,$18,$01,$23,$1b,$03,$10,$78,$08,$70,$01,
$3b,$01,$32,$01,$31,$00,$2b,$f8,$d1,$00,$20,$10,$b0,$7c,$bc,$08,$bc,$08,$47)

Save Pattern Block for Flash_v123 + Flash_v124
Unpatched block 1 (8 Bytes)
($ff,$f7,$aa,$ff,$00,$04,$03,$0c)
Patch with
($1b,$23,$1b,$02,$32,$20,$03,$43)

Unpatched block 2 (6 Bytes)
($70,$b5,$90,$b0,$15,$4d)
Patch with
($00,$20,$70,$47,$15,$4d)

Unpatched block 3 (6 Bytes)
($70,$b5,$46,$46,$40,$b4)
Patch with
($00,$20,$70,$47,$40,$b4)

Unpatched block 4 (38 Bytes)
($f0,$b5,$90,$b0,$0f,$1c,$00,$04,$04,$0c,$0f,$2c,$04,$d9,$01,$48,$40,$e0,$00,$00,$ff,
$80,$00,$00,$20,$1c,$ff,$f7,$d7,$fe,$00,$04,$05,$0c,$00,$2d,$35,$d1)
Patch with
($70,$b5,$00,$03,$0a,$1c,$e0,$21,$09,$05,$41,$18,$01,$23,$1b,$03,$10,$78,$08,$70,$01,
$3b,$01,$32,$01,$31,$00,$2b,$f8,$d1,$00,$20,$70,$bc,$02,$bc,$08,$47)

Save Pattern Block for Flash_v125 + Flash_v126
Unpatched block 1 (8 Bytes)
($ff,$f7,$aa,$ff,$00,$04,$03,$0c)
Patch with
($1b,$23,$1b,$02,$32,$20,$03,$43);

Unpatched block 2 (6 Bytes)
($00,$03,$70,$b5,$90,$b0,$15,$4d)
Patch with
($00,$03,$00,$20,$70,$47,$15,$4d)

Unpatched block 3 (6 Bytes)
($00,$03,$70,$b5,$46,$46,$40,$b4)
Patch with
($00,$03,$00,$20,$70,$47,$40,$b4)

Unpatched block 4 (38 Bytes)
($f0,$b5,$90,$b0,$0f,$1c,$00,$04,$04,$0c,$0f,$2c,$04,$d9,$01,$48,$40,$e0,$00,$00,$ff,
$80,$00,$00,$20,$1c,$ff,$f7,$d7,$fe,$00,$04,$05,$0c,$00,$2d,$35,$d1)
Patch with
($70,$b5,$00,$03,$0a,$1c,$e0,$21,$09,$05,$41,$18,$01,$23,$1b,$03,$10,$78,$08,$70,$01,
$3b,$01,$32,$01,$31,$00,$2b,$f8,$d1,$00,$20,$70,$bc,$02,$bc,$08,$47)

Each byte pattern for each save is exactly the same in every rom.

If you want to have a look at the code (it's in Pascal) then just send me a PM. Remember I'm not a great coder so the code is probably pretty messy compared to a seasoned programmer, but it works and should give you an idea of how to implement it.

edit : These are the optimized arrays, these are all the correct size with any unnecessary data taken it. I'll tidy it up at some point and replace the above with them

Code:
{**** Flash_v1XX Unpatched/Patched blocks for SRAM patching ****}
ÂÂFlashv121NoPatchBlock1 : Array[1..12] Of Byte = ($90,$b5,$93,$b0,$6f,$46,$39,$1d,$08,$1c,$00,$f0);
ÂÂFlashv121PatchBlock1ÂÂ : Array[1..14] Of Byte = ($00,$b5,$3d,$20,$00,$02,$1f,$21,$08,$43,$02,$bc,$08,$47);
ÂÂFlashv121NoPatchBlock2 : Array[1..35] Of Byte = ($80,$b5,$94,$b0,$6f,$46,$39,$1c,$08,$80,$38,$1c,$01,$88,$0f,$29,$04,$d9,$01,$48,$56,$e0,$00,
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ $00,$ff,$80,$00,$00,$23,$48,$23,$49,$0a,$88,$23);
ÂÂFlashv121PatchBlock2ÂÂ : Array[1..36] Of Byte = ($7c,$b5,$00,$07,$00,$0c,$e0,$21,$09,$05,$09,$18,$01,$23,$1b,$03,$ff,$20,$08,$70,$01,$3b,$01,
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ $31,$00,$2b,$fa,$d1,$00,$20,$7c,$bc,$02,$bc,$08,$47);
ÂÂFlashv121NoPatchBlock3 : Array[1..42] Of Byte = ($80,$b5,$94,$b0,$6f,$46,$79,$60,$39,$1c,$08,$80,$38,$1c,$01,$88,$0f,$29,$03,$d9,$00,$48,$73,
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ $e0,$ff,$80,$00,$00,$38,$1c,$01,$88,$08,$1c,$ff,$f7,$21,$fe,$39,$1c,$0c,$31);
ÂÂFlashv121PatchBlock3ÂÂ : Array[1..42] Of Byte = ($7c,$b5,$90,$b0,$00,$03,$0a,$1c,$e0,$21,$09,$05,$09,$18,$01,$23,$1b,$03,$10,$78,$08,$70,$01,
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ $3b,$01,$32,$01,$31,$00,$2b,$f8,$d1,$00,$20,$10,$b0,$7c,$bc,$08,$bc,$08,$47);

ÂÂFlashv123NoPatchBlock1 : Array[1..8] Of Byte = ($ff,$f7,$aa,$ff,$00,$04,$03,$0c);
ÂÂFlashv123PatchBlock1ÂÂ : Array[1..8] Of Byte = ($1b,$23,$1b,$02,$32,$20,$03,$43);
ÂÂFlashv123NoPatchBlock2 : Array[1..6] Of Byte = ($70,$b5,$90,$b0,$15,$4d);
ÂÂFlashv123PatchBlock2ÂÂ : Array[1..6] Of Byte = ($00,$20,$70,$47,$15,$4d);
ÂÂFlashv123NoPatchBlock3 : Array[1..6] Of Byte = ($70,$b5,$46,$46,$40,$b4);
ÂÂFlashv123PatchBlock3ÂÂ : Array[1..6] Of Byte = ($00,$20,$70,$47,$40,$b4);
ÂÂFlashv123NoPatchBlock4 : Array[1..38] Of Byte = ($f0,$b5,$90,$b0,$0f,$1c,$00,$04,$04,$0c,$0f,$2c,$04,$d9,$01,$48,$40,$e0,$00,$00,$ff,
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ $80,$00,$00,$20,$1c,$ff,$f7,$d7,$fe,$00,$04,$05,$0c,$00,$2d,$35,$d1);
ÂÂFlashv123PatchBlock4ÂÂ : Array[1..38] Of Byte = ($70,$b5,$00,$03,$0a,$1c,$e0,$21,$09,$05,$41,$18,$01,$23,$1b,$03,$10,$78,$08,$70,$01,
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ $3b,$01,$32,$01,$31,$00,$2b,$f8,$d1,$00,$20,$70,$bc,$02,$bc,$08,$47);

ÂÂFlashv125NoPatchBlock1 : Array[1..8] Of Byte = ($ff,$f7,$aa,$ff,$00,$04,$03,$0c);
ÂÂFlashv125PatchBlock1ÂÂ : Array[1..8] Of Byte = ($1b,$23,$1b,$02,$32,$20,$03,$43);
ÂÂFlashv125NoPatchBlock2 : Array[1..6] Of Byte = ($70,$b5,$90,$b0,$15,$4d);
ÂÂFlashv125PatchBlock2ÂÂ : Array[1..6] Of Byte = ($00,$20,$70,$47,$15,$4d);
ÂÂFlashv125NoPatchBlock3 : Array[1..6] Of Byte = ($70,$b5,$46,$46,$40,$b4);
ÂÂFlashv125PatchBlock3ÂÂ : Array[1..6] Of Byte = ($00,$20,$70,$47,$40,$b4);
ÂÂFlashv125NoPatchBlock4 : Array[1..38] Of Byte = ($f0,$b5,$90,$b0,$0f,$1c,$00,$04,$04,$0c,$0f,$2c,$04,$d9,$01,$48,$40,$e0,$00,$00,$ff,
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ $80,$00,$00,$20,$1c,$ff,$f7,$d7,$fe,$00,$04,$05,$0c,$00,$2d,$35,$d1);
ÂÂFlashv125PatchBlock4ÂÂ : Array[1..38] Of Byte = ($70,$b5,$00,$03,$0a,$1c,$e0,$21,$09,$05,$41,$18,$01,$23,$1b,$03,$10,$78,$08,$70,$01,
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ $3b,$01,$32,$01,$31,$00,$2b,$f8,$d1,$00,$20,$70,$bc,$02,$bc,$08,$47);
{**** Eeprom_v1XX Unpatched/Patched blocks for SRAM patching ****}
ÂÂEepromV12XNoPatchBlock1 : Array[1..20] Of Byte = ($a2,$b0,$0d,$1c,$00,$04,$03,$0c,$03,$48,$00,$68,$80,$88,$83,$42,$05,$d3,$01,$48);
ÂÂEepromV12XPatchBlock1ÂÂ : Array[1..38] Of Byte = ($00,$04,$0a,$1c,$40,$0b,$e0,$21,$09,$05,$41,$18,$07,$31,$00,$23,$08,$78,$10,$70,$01,$33,
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ$01,$32,$01,$39,$07,$2b,$f8,$d9,$00,$20,$70,$bc,$02,$bc,$08,$47);
ÂÂEepromV12XNoPatchBlock2 : Array[1..22] Of Byte = ($30,$b5,$a9,$b0,$0d,$1c,$00,$04,$04,$0c,$03,$48,$00,$68,$80,$88,$84,$42,$05,$d3,$01,$48);
ÂÂEepromV12XPatchBlock2ÂÂ : Array[1..40] of Byte = ($70,$b5,$00,$04,$0a,$1c,$40,$0b,$e0,$21,$09,$05,$41,$18,$07,$31,$00,$23,$10,$78,$08,$70,
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ$01,$33,$01,$32,$01,$39,$07,$2b,$f8,$d9,$00,$20,$70,$bc,$02,$bc,$08,$47);

ÂÂEepromV124NoPatchBlock1 : Array[1..20] Of Byte = ($a2,$b0,$0d,$1c,$00,$04,$03,$0c,$03,$48,$00,$68,$80,$88,$83,$42,$05,$d3,$01,$48);
ÂÂEepromV124PatchBlock1ÂÂ : Array[1..38] Of Byte = ($00,$04,$0a,$1c,$40,$0b,$e0,$21,$09,$05,$41,$18,$07,$31,$00,$23,$08,$78,$10,$70,$01,$33,
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ$01,$32,$01,$39,$07,$2b,$f8,$d9,$00,$20,$70,$bc,$02,$bc,$08,$47);
ÂÂEepromV124NoPatchBlock2 : Array[1..22] Of Byte = ($f0,$b5,$ac,$b0,$0d,$1c,$00,$04,$01,$0c,$12,$06,$17,$0e,$03,$48,$00,$68,$80,$88,$81,$42);
ÂÂEepromV124PatchBlock2ÂÂ : Array[1..40] of Byte = ($70,$b5,$00,$04,$0a,$1c,$40,$0b,$e0,$21,$09,$05,$41,$18,$07,$31,$00,$23,$10,$78,$08,$70,
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ$01,$33,$01,$32,$01,$39,$07,$2b,$f8,$d9,$00,$20,$70,$bc,$02,$bc,$08,$47);


ÂÂEepromV126NoPatchBlock1 : Array[1..20] Of Byte = ($a2,$b0,$0d,$1c,$00,$04,$03,$0c,$03,$48,$00,$68,$80,$88,$83,$42,$05,$d3,$01,$48);
ÂÂEepromV126PatchBlock1ÂÂ : Array[1..38] Of Byte = ($00,$04,$0a,$1c,$40,$0b,$e0,$21,$09,$05,$41,$18,$07,$31,$00,$23,$08,$78,$10,$70,$01,$33,
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ$01,$32,$01,$39,$07,$2b,$f8,$d9,$00,$20,$70,$bc,$02,$bc,$08,$47);
ÂÂEepromV126NoPatchBlock2 : Array[1..22] Of Byte = ($f0,$b5,$47,$46,$80,$b4,$ac,$b0,$0e,$1c,$00,$04,$05,$0c,$12,$06,$12,$0e,$90,$46,$03,$48);
ÂÂEepromV126PatchBlock2ÂÂ : Array[1..40] of Byte = ($70,$b5,$00,$04,$0a,$1c,$40,$0b,$e0,$21,$09,$05,$41,$18,$07,$31,$00,$23,$10,$78,$08,$70,
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ$01,$33,$01,$32,$01,$39,$07,$2b,$f8,$d9,$00,$20,$70,$bc,$02,$bc,$08,$47);

{**** Eeprom_V111 Unpatched/Patched blocks for SRAM patching ****}
ÂÂEepromV111NoPatchBlock1 : Array[1..8] of ByteÂÂ= ($0e,$48,$39,$68,$01,$60,$0e,$48);
ÂÂEepromV111PatchBlock1ÂÂ : Array[1..8] of ByteÂÂ= ($00,$48,$00,$47,$71,$ba,$3e,$08);
ÂÂEepromV111NoPatchBlock2 : Array[1..8] of ByteÂÂ= ($27,$e0,$d0,$20,$00,$05,$01,$88);
ÂÂEepromV111PatchBlock2ÂÂ : Array[1..8] of ByteÂÂ= ($27,$e0,$e0,$20,$00,$05,$01,$88);
ÂÂEepromV111PatchBlock3ÂÂ : Array[1..188] of Byte = ($39,$68,$27,$48,$81,$42,$23,$d0,$89,$1c,$08,$88,$01,$28,$02,$d1,
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ $24,$48,$78,$60,$33,$e0,$00,$23,$00,$22,$89,$1c,$10,$b4,$01,$24,
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ $08,$68,$20,$40,$5b,$00,$03,$43,$89,$1c,$52,$1c,$06,$2a,$f7,$d1,
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ $10,$bc,$39,$60,$db,$01,$02,$20,$00,$02,$1b,$18,$0e,$20,$00,$06,
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ $1b,$18,$7b,$60,$39,$1c,$08,$31,$08,$88,$09,$38,$08,$80,$16,$e0,
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ $15,$49,$00,$23,$00,$22,$10,$b4,$01,$24,$08,$68,$20,$40,$5b,$00,
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ $03,$43,$89,$1c,$52,$1c,$06,$2a,$f7,$d1,$10,$bc,$db,$01,$02,$20,
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ $00,$02,$1b,$18,$0e,$20,$00,$06,$1b,$18,$08,$3b,$3b,$60,$0b,$48,
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ $39,$68,$01,$60,$0a,$48,$79,$68,$01,$60,$0a,$48,$39,$1c,$08,$31,
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ $0a,$88,$80,$21,$09,$06,$0a,$43,$02,$60,$07,$48,$00,$47,$00,$00,
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ $00,$00,$00,$0d,$00,$00,$00,$0e,$04,$00,$00,$0e,$d4,$00,$00,$04,
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ $d8,$00,$00,$04,$dc,$00,$00,$04,$8d,$66,$0b,$08);

{**** Flash512_V130 Unpatched/Patched blocks for SRAM patching ****}
ÂÂFlash512V130NoPatchBlock1 : Array[1..38] Of Byte = ($f0,$b5,$a0,$b0,$0d,$1c,$16,$1c,$1f,$1c,$03,$04,$1c,$0c,$0f,$4a,
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ$10,$88,$0f,$49,$08,$40,$03,$21,$08,$43,$10,$80,$0d,$48,$00,$68,
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ$01,$68,$80,$20,$80,$02);
ÂÂFlash512V130PatchBlock1ÂÂ : Array[1..38] Of Byte = ($70,$b5,$a0,$b0,$00,$03,$40,$18,$e0,$21,$09,$05,$09,$18,$08,$78,
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ$10,$70,$01,$3b,$01,$32,$01,$31,$00,$2b,$f8,$d1,$00,$20,$20,$b0,
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ$70,$bc,$02,$bc,$08,$47);
ÂÂFlash512V130NoPatchBlock2 : Array[1..8] of ByteÂÂ= ($ff,$f7,$88,$fd,$00,$04,$03,$0c);
ÂÂFlash512V130PatchBlock2ÂÂ : Array[1..8] of ByteÂÂ= ($1b,$23,$1b,$02,$32,$20,$03,$43);
ÂÂFlash512V130NoPatchBlock3 : Array[1..8] of ByteÂÂ= ($70,$b5,$90,$b0,$15,$4d,$29,$88);
ÂÂFlash512V130PatchBlock3ÂÂ : Array[1..8] of ByteÂÂ= ($00,$b5,$00,$20,$02,$bc,$08,$47);
ÂÂFlash512V130NoPatchBlock4 : Array[1..8] of ByteÂÂ= ($70,$b5,$46,$46,$40,$b4,$90,$b0);
ÂÂFlash512V130PatchBlock4ÂÂ : Array[1..8] of ByteÂÂ= ($00,$b5,$00,$20,$02,$bc,$08,$47);
ÂÂFlash512V130NoPatchBlock5 : Array[1..24] of Byte = ($f0,$b5,$90,$b0,$0f,$1c,$00,$04,$04,$0c,$03,$48,
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ$00,$68,$40,$89,$84,$42,$05,$d3,$01,$48,$41,$e0);
ÂÂFlash512V130PatchBlock5ÂÂ : Array[1..42] of Byte = ($7c,$b5,$90,$b0,$00,$03,$0a,$1c,$e0,$21,$09,$05,
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ$09,$18,$01,$23,$1b,$03,$10,$78,$08,$70,$01,$3b,
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ$01,$32,$01,$31,$00,$2b,$f8,$d1,$00,$20,$10,$b0,
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ$7c,$bc,$02,$bc,$08,$47);

{**** Flash1M_V102, V103 Unpatched/Patched block for SRAM patching ****}
ÂÂFlash1MV102NoPatchBlock1ÂÂ: Array[1..48] of ByteÂÂ= ($aa,$21,$19,$70,$05,$4a,$55,$21,$11,$70,$b0,$21,$19,$70,
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ $e0,$21,$09,$05,$08,$70,$70,$47,$55,$55,$00,$0e,$aa,$2a,$00,$0e,
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ $30,$b5,$91,$b0,$68,$46,$00,$f0,$f3,$f8,$6d,$46,$01,$35,$06,$4a,
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ $aa,$20);
ÂÂFlash1MV102PatchBlock1ÂÂÂÂ: Array[1..136] of Byte = ($80,$21,$09,$02,$09,$22,$12,$06,$9f,$44,$11,$80,$03,$49,
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ $c3,$02,$c9,$18,$11,$80,$70,$47,$fe,$ff,$ff,$01,$00,$00,$00,$00,
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ $30,$b5,$91,$b0,$68,$46,$00,$f0,$f3,$f8,$6d,$46,$01,$35,$06,$4a,
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ $aa,$20,$00,$00,$05,$49,$55,$20,$00,$00,$90,$20,$00,$00,$10,$a9,
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ $03,$4a,$10,$1c,$08,$e0,$00,$00,$55,$55,$00,$0e,$aa,$2a,$00,$0e,
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ $20,$4e,$00,$00,$08,$88,$01,$38,$08,$80,$08,$88,$00,$28,$f9,$d1,
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ $0c,$48,$13,$20,$13,$20,$00,$06,$04,$0c,$e0,$20,$00,$05,$62,$20,
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ $62,$20,$00,$06,$00,$0e,$04,$43,$07,$49,$aa,$20,$00,$00,$07,$4a,
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ $55,$20,$00,$00,$f0,$20,$00,$00,$00,$00);
ÂÂFlash1MV102NoPatchBlock2ÂÂ: Array[1..24] of ByteÂÂ= ($14,$49,$aa,$24,$0c,$70,$13,$4b,$55,$22,$1a,$70,$80,$20,$08,$70,
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ $0c,$70,$1a,$70,$10,$20,$08,$70);
ÂÂFlash1MV102PatchBlock2ÂÂÂÂ: Array[1..24] of ByteÂÂ= ($0e,$21,$09,$06,$ff,$24,$80,$22,$13,$4b,$52,$02,$01,$3a,$8c,$54,
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ $fc,$d1,$00,$00,$00,$00,$00,$00);
ÂÂFlash1MV102NoPatchBlock3ÂÂ: Array[1..22] of ByteÂÂ= ($aa,$25,$0d,$70,$13,$4b,$55,$22,$1a,$70,$80,$20,$08,$70,$0d,$70,
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ $1a,$70,$30,$20,$20,$70);
ÂÂFlash1MV102PatchBlock3ÂÂÂÂ: Array[1..22] of ByteÂÂ= ($ff,$25,$08,$22,$00,$00,$52,$02,$01,$3a,$a5,$54,$fc,$d1,$00,$00,
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ $00,$00,$00,$00,$00,$00);
ÂÂFlash1MV102NoPatchBlock4ÂÂ: Array[1..12] of ByteÂÂ= ($22,$70,$09,$4b,$55,$22,$1a,$70,$a0,$22,$22,$70);
ÂÂFlash1MV102PatchBlock4ÂÂÂÂ: Array[1..12] of ByteÂÂ= ($00,$00,$09,$4b,$55,$22,$00,$00,$a0,$22,$00,$00);

ÂÂFlash1MV103NoPatchBlock1ÂÂ: Array[1..98] of ByteÂÂ= ($05,$4b,$aa,$21,$19,$70,$05,$4a,$55,$21,$11,$70,$b0,$21,$19,$70,
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ $e0,$21,$09,$05,$08,$70,$70,$47,$55,$55,$00,$0e,$aa,$2a,$00,$0e,
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ $30,$b5,$91,$b0,$68,$46,$00,$f0,$f3,$f8,$6d,$46,$01,$35,$06,$4a,
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ $aa,$20,$10,$70,$05,$49,$55,$20,$08,$70,$90,$20,$10,$70,$10,$a9,
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ $03,$4a,$10,$1c,$08,$e0,$00,$00,$55,$55,$00,$0e,$aa,$2a,$00,$0e,
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ $20,$4e,$00,$00,$08,$88,$01,$38,$08,$80,$08,$88,$00,$28,$f9,$d1,
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ $0c,$48);
ÂÂFlash1MV103PatchBlock1ÂÂÂÂ: Array[1..138] of Byte = ($05,$4b,$80,$21,$09,$02,$09,$22,$12,$06,$9f,$44,$11,$80,$03,$49,
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ $c3,$02,$c9,$18,$11,$80,$70,$47,$fe,$ff,$ff,$01,$00,$00,$00,$00,
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ $30,$b5,$91,$b0,$68,$46,$00,$f0,$f3,$f8,$6d,$46,$01,$35,$06,$4a,
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ $aa,$20,$00,$00,$05,$49,$55,$20,$00,$00,$90,$20,$00,$00,$10,$a9,
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ $03,$4a,$10,$1c,$08,$e0,$00,$00,$55,$55,$00,$0e,$aa,$2a,$00,$0e,
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ $20,$4e,$00,$00,$08,$88,$01,$38,$08,$80,$08,$88,$00,$28,$f9,$d1,
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ $0c,$48,$13,$20,$13,$20,$00,$06,$04,$0c,$e0,$20,$00,$05,$62,$20,
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ $62,$20,$00,$06,$00,$0e,$04,$43,$07,$49,$aa,$20,$00,$00,$07,$4a,
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ $55,$20,$00,$00,$f0,$20,$00,$00,$00,$00);
ÂÂFlash1MV103NoPatchBlock2ÂÂ: Array[1..24] of ByteÂÂ= ($14,$49,$aa,$24,$0c,$70,$13,$4b,$55,$22,$1a,$70,$80,$20,$08,$70,
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ $0c,$70,$1a,$70,$10,$20,$08,$70);
ÂÂFlash1MV103PatchBlock2ÂÂÂÂ: Array[1..24] of ByteÂÂ= ($0e,$21,$09,$06,$ff,$24,$80,$22,$13,$4b,$52,$02,$01,$3a,$8c,$54,
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ $fc,$d1,$00,$00,$00,$00,$00,$00);
ÂÂFlash1MV103NoPatchBlock3ÂÂ: Array[1..22] of ByteÂÂ= ($aa,$25,$0d,$70,$14,$4b,$55,$22,$1a,$70,$80,$20,$08,$70,$0d,$70,
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ $1a,$70,$30,$20,$20,$70);
ÂÂFlash1MV103PatchBlock3ÂÂÂÂ: Array[1..22] of ByteÂÂ= ($ff,$25,$08,$22,$00,$00,$52,$02,$01,$3a,$a5,$54,$fc,$d1,$00,$00,
ÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂ $00,$00,$00,$00,$00,$00);
ÂÂFlash1MV103NoPatchBlock4ÂÂ: Array[1..12] of ByteÂÂ= ($10,$70,$0b,$49,$55,$20,$08,$70,$a0,$20,$10,$70);
ÂÂFlash1MV103PatchBlock4ÂÂÂÂ: Array[1..12] of ByteÂÂ= ($00,$00,$0b,$49,$55,$20,$00,$00,$a0,$20,$00,$00);
ÂÂFlash1MV103NoPatchBlock5ÂÂ: Array[1..12] of ByteÂÂ= ($22,$70,$09,$4b,$55,$22,$1a,$70,$a0,$22,$22,$70);
ÂÂFlash1MV103PatchBlock5ÂÂÂÂ: Array[1..12] of ByteÂÂ= ($00,$00,$09,$4b,$55,$22,$00,$00,$a0,$22,$00,$00);
 

TrolleyDave

Philosolosophising
Former Staff
Joined
Jan 1, 2007
Messages
7,761
Trophies
1
Age
52
Location
Wales, UK
XP
933
Country
I remember reading something about GBATA not handling 512k/1024k Flash save types. Can anyone give more any more info on this? I've based all the other patching routines on GBATAs output, should I be using another app for these save types?
 

Destructobot

Crave the Hammer
Member
Joined
Oct 15, 2006
Messages
5,002
Trophies
0
Age
45
Location
Portland, OR
Website
Visit site
XP
321
Country
United States
GBATA works just fine with 512kbit Flash save types.

It works with 1024kbit save types as well, but it converts them to 512kbit saves. The save still works properly for nearly all games, but they usually complain about corrupted data when they start up.
 

TrolleyDave

Philosolosophising
Former Staff
Joined
Jan 1, 2007
Messages
7,761
Trophies
1
Age
52
Location
Wales, UK
XP
933
Country
GBATA works just fine with 512kbit Flash save types.

It works with 1024kbit save types as well, but it converts them to 512kbit saves. The save still works properly for nearly all games, but they usually complain about corrupted data when they start up.

So it would still be safe to use the GBATA patching style on all Flash1M save types? Should be easy enough then as it's the same patch for all the Flash1M roms that I've done so far. Now if only I could crack the Eeprom_V111 save type!
 

Destructobot

Crave the Hammer
Member
Joined
Oct 15, 2006
Messages
5,002
Trophies
0
Age
45
Location
Portland, OR
Website
Visit site
XP
321
Country
United States
So it would still be safe to use the GBATA patching style on all Flash1M save types?
This is probably your only choice, unless you get into cart-specific save patches. I'm not too clear on the inner workings, but the GBA can apparently only access 64 kilobytes of SRAM at a time; to write a larger save than that requires bank switching, and that works differently on different flashcarts.

I haven't had a problem yet with GBATA's method of patching the Flash_1M save types, but I've only done basic testing with most of the games that use it.
 

TrolleyDave

Philosolosophising
Former Staff
Joined
Jan 1, 2007
Messages
7,761
Trophies
1
Age
52
Location
Wales, UK
XP
933
Country
Ok so I've cracked SRAM patching for V111. This one was a little trickier to crack as it's the only one where you need to do some calculations and it's the only one where it isn't just a straight patch of data.

Save Pattern Block for Eeprom_V111
Unpatched block 1 (8 Bytes)
($0e,$48,$39,$68,$01,$60,$0e,$48)
Patch with
($00,$48,$00,$47,$XX,$XX,$XX,$08) (See below for what to fill the XXs with)

Unpatched block 2 (8 Bytes)
($27,$e0,$d0,$20,$00,$05,$01,$88)
Patch with
($27,$e0,$e0,$20,$00,$05,$01,$88)

Patch block 3 (188 Bytes) (goes at the end of the rom data, see notes below)
($39,$68,$27,$48,$81,$42,$23,$d0,$89,$1c,$08,$88,$01,$28,$02,$d1,
$24,$48,$78,$60,$33,$e0,$00,$23,$00,$22,$89,$1c,$10,$b4,$01,$24,
$08,$68,$20,$40,$5b,$00,$03,$43,$89,$1c,$52,$1c,$06,$2a,$f7,$d1,
$10,$bc,$39,$60,$db,$01,$02,$20,$00,$02,$1b,$18,$0e,$20,$00,$06,
$1b,$18,$7b,$60,$39,$1c,$08,$31,$08,$88,$09,$38,$08,$80,$16,$e0,
$15,$49,$00,$23,$00,$22,$10,$b4,$01,$24,$08,$68,$20,$40,$5b,$00,
$03,$43,$89,$1c,$52,$1c,$06,$2a,$f7,$d1,$10,$bc,$db,$01,$02,$20,
$00,$02,$1b,$18,$0e,$20,$00,$06,$1b,$18,$08,$3b,$3b,$60,$0b,$48,
$39,$68,$01,$60,$0a,$48,$79,$68,$01,$60,$0a,$48,$39,$1c,$08,$31,
$0a,$88,$80,$21,$09,$06,$0a,$43,$02,$60,$07,$48,$00,$47,$00,$00,
$00,$00,$00,$0d,$00,$00,$00,$0e,$04,$00,$00,$0e,$d4,$00,$00,$04,
$d8,$00,$00,$04,$dc,$00,$00,$04,$XX,$XX,$XX,$08)

Notes
This ones a little trickier than the rest of them. I've managed to compact all the other save types into one patching routine but for this I've had to use a completely different patching routine. As you can see from the patch blocks there's a couple of non-standard bytes in Patch block 1 and Patch block 3. Patch block 2 is a simple search and patch routine, I'll explain about blocks 1 and 2 below. Before you begin your patching for this save type you have to calculate where the end of the actual rom data is as Patch block 3 needs to bea appended to the empty space after. Unfortunately though it's not as simple as jus fnding the first free byte, the patch has to begin in the first empty byte divisible by 16 (no remainder, in Pascal it's EOFMarker MOD 16 = 0). Make sure that this number is kept in a 32-bit number as your going to need the first 3 bytes of it!
wink.gif


Patch block 1
The unpatched search block 1 is standard between all roms so the same kind of search routines you used for all the others will do. Before patching the data though you need to fill in bytes 5,6 and 7 of the patch block. This data needs to be the first 3 bytes of the 32 bit number that you stored the EOF position in. The number that you should be patching in is the EOF marker position you stored earlier plus 1. So if the patch starts at file position 3000000 you need to apply the number 300001.

The way I did it in Pascal (there's probably an easier way) is to move the Integer into an 4 byte array (call it TmpArray for ease) and then copy the relevant bytes from that array into the patch data. So if the patch data is stored as an 8 byte array called PatchArray the code would simply be PatchArray[5] := TmpArray[1] and PatchArray[6] := TmpArray[2] and so on. Then it's just a simple matter of pasting the modified patch data in there. Keep a marker of the byte position of the start of this data as you'll need it to fill in the relevant data in patch block 3.

Patch block 3
Patch block 3 is actually pretty easy as there's no data to search for to overwrite with the patch, it's simply added in the empty space at the end of the rom. It has to be placed in the first position after the end of the rom data that's divisible by 16 (it has to be 16 byte aligned) or the rom won't be able to access the save data.

You need to modify bytes 185, 186 and 187 in the patch block. Again it's another offset and it's a 3 byte length number (a 24-bit number) the same as in patch block 1. Alter the data in this patch block exactly the same way that you altered the data in patch block 1. The number you need to fill bytes 185-187 with is the offset of patch 1 + 32 bytes. So if patch 1 is store at file offset 30000 the number you need to fill bytes 185-187 with would be 30032. Again the way I did it was just to move the 32 bit number I had the file offset + 32 stored in into an array of bytes and then copied the relevant bytes into the patch data. Once you've filled bytes 185-187 with the correct data you can just patch the data directly into the file.

Just as a side note, if the file is already trimmed by a trimmer the easiest thing to do would be to append 512 bytes of blank data to the end of the rom and then run your patching routine like normal.

And that folks is Eeprom_V111 patching! I know I probably haven't explained it too well but if you need any clarification on anything or you want to have a look at my patching routines then just PM me.

I'll do Flash1M and Flash512 tomorrow.
 

TrolleyDave

Philosolosophising
Former Staff
Joined
Jan 1, 2007
Messages
7,761
Trophies
1
Age
52
Location
Wales, UK
XP
933
Country
Here's the app I've written to test my patching routines, it's not very nice looking as it's just for making sure the routines work. To use it pick a GBA file from the file browser and hit the patch button, it'll output a patched file wth the same name as the original except with the extension .sram.gba instead of just .gba

I've done some testing but haven't tested the patching routines on more that a handful of roms for each save type so if any one wants to test them on a few more roms for me I'd be most grateful. Flash1M and Flash512 save types not supported yet.


http://tinyurl.com/3xer2l

EDIT : Oh yeah, if you run a file compare on a game patched using my app and GBATA the data should be exactly the same.
 

dexmix

Well-Known Member
Member
Joined
Apr 13, 2007
Messages
266
Trophies
0
XP
56
Country
United States
super appreciated! i would love to see this program replace all others for gba save patching.

i would like to see this patch rebel star tactical command and sigma star saga properly because later versions of EZ Client don't seem to work.
 

TrolleyDave

Philosolosophising
Former Staff
Joined
Jan 1, 2007
Messages
7,761
Trophies
1
Age
52
Location
Wales, UK
XP
933
Country
Yeah that would be great if you could. All the ones I've tested seem to work but it's just handful of each type on 1 cart so it'd be nice to see if it works for others as well. There's no Flash512 or Flash1M at the mo but I'll be working on it shortly (just been marathon watching up on S2 of The Wire, lazy ass that I am
wink.gif
) but it shouldn't take too long to add in.

If it works fine for more than me then I'll slap together a batch SRAM patcher later for people. GBATA is a terrific app but doing 1 game at a time is a bit much!

EDIT : I've added in SRAM patching for Flash512 and Flash1M now. If people wouldn't mind testing this out on their carts I'd be most grateful!
smile.gif
 

TrolleyDave

Philosolosophising
Former Staff
Joined
Jan 1, 2007
Messages
7,761
Trophies
1
Age
52
Location
Wales, UK
XP
933
Country
I've just had a look on PocketHeaven and found that there's still a few more save types I haven't done. I'll try and get it done tomorrow.
 

Destructobot

Crave the Hammer
Member
Joined
Oct 15, 2006
Messages
5,002
Trophies
0
Age
45
Location
Portland, OR
Website
Visit site
XP
321
Country
United States
You should take a look at some of the 2in1 game packs; "Dr. Mario & Puzzle League" and "Dragon Ball Z - Buu's Fury & Dragon Ball GT - Transformation" are both known to be unpatchable by GBATA. I've tested Dr. Mario & Puzzle League with every SRAM patcher I could find (including yours), and none of them worked.

I'll do some more testing in a while when I have more free time.
 

TrolleyDave

Philosolosophising
Former Staff
Joined
Jan 1, 2007
Messages
7,761
Trophies
1
Age
52
Location
Wales, UK
XP
933
Country
If GBATA can't patch a game then mine definitely won't be able to eithe as my output is based solely on changes made by GBATA. I can't find any tech docs on it so basically all the info I've posted is just stuff I've worked out by comparing clean roms and roms patched by GBATA.

I'm wondering if the double packs need to be patched twice or something similar. Chances are they haven't reprogrammed anything, they've just dumped two roms and there and put a loader on it (it's an official cart but it probably uses a similar scheme to HK multi-carts).

I'll have to grab the roms so I can check them out. What are the release numbers?
 

Site & Scene News

Popular threads in this forum

General chit-chat
Help Users
    Maximumbeans @ Maximumbeans: butte