Main Menu
Main Page
Forums
Recent changes
Random page
Help

Databases
GlitchDex
AttackDex
ItemDex
StatDex
TrainerDex
TypeDex
UnownDex
More

Major Glitches
Trainer escape glitch
Old man trick
Celebi Egg trick
Select glitches (Japan)
SRAM glitch
CoolTrainer♀ corruption
LOL glitch
Rival LOL glitch
Super Glitch
ZZAZZ glitch
Pomeg data corruption glitch (Glitzer Popping)
Tweaking
Elite Four door glitch (Japan)
Pokémon merge glitch
Pokémon cloning
Time Capsule exploit
Arbitrary code execution
Coin Case glitches
More

Other Glitch Categories
Glitches by generation
Glitches between two generations
Japan-only/language specific glitches
Music glitches
Natural glitches
Non-core series glitches
Non-Pokémon glitches
Officially acknowledged glitches
Recurring glitches
Dead glitches

References
Pokémon GameShark codes
The Big HEX List
Glitch Pokémon cries
GB programming
Curiosities
Debugging features
Easter eggs
Error traps
Glitch areas
Glitch myths
Non-glitch exploits
Placeholder texts
Pokémon glitch terminology
Unused content and prerelease information

Useful Tools
8F Helper
GBz80 to Items
Old man trick name generator
PATH (Prama's Advanced Tweaking Heaven)
Save file editors
Special stat/Pokémon converter
Trainer escape Trainer Pokémon finder

Affiliates
Legendary Star Blob 2 (Hakuda)
Pokémon Speedruns wiki
PRAMA Initiative
Become an affiliate!

Technical
Site Source Code

Search Wiki

 

Search Forums

 

Author Topic: Downloading save files from another Gameboy with Pokemon Red/Blue  (Read 126 times)

0 Members and 1 Guest are viewing this topic.

Epsilon

  • Zeta
  • Member+
  • *
  • Offline Offline
  • The default personal text makes no sense
    • View Profile
Note: This only allows for Red -> Red or Blue -> Blue duplications. Attempting an R -> B or vice versa will result in a glitch Pokemon center that you cannot escape from

Hey all! Not sure how useful this might be, but I made a save file (well, "made", meaning I saved the game) that allows you to duplicate and play the save file of the person you are trading with in Pokemon Red/Blue! It uses the RCE method discovered by Vagiular and documented here.

To Use

1. Have a Pokemon Red/Blue cartridge with the save file you wish to duplicate (This file needs no special prerequisites, outside of being able to use Cable club, meaning oak's parcel has been delivered)
2. Have a copy of the same game (Red/Blue wise), with it's respective duplication save file loaded (I have attached both saves to this thread)
2. Connect the two via link cable (If you're on BGB, you can do this with Right Click>Link>Listen on one and Right Click>Link>Connect on the other)
3. Go to the Trade Colosseum
4. Start a trade
5. Wait for save file transfer to complete
Few things to note: This is different from Mr.Cheeze's virus in that this needs to transfer all three banks. As such, this is going to take a minute or two. Be patient.

During this time, you will notice both screens will become glitched. This is the save file data you are duplicating, being represented as tiles.

6. Once they are finished, both Gameboys will restart
7. You should now be able to play the save file you duplicated!

Technical

As i mentioned earlier, this uses the exploit vaguilar discovered and documented.

As you might have guessed, this was inspired by "Mr.Cheeze's virus"

Basically what vaguilar's exploit does is since the subroutine that draws Pokemon names to the screen doesn't end until it reaches the $FF terminator, you can change bytes in your party to force the subroutine to write names to the stack, forcing the game to jump to a certain address upon reaching "ret". In order to force the buffer to go that far, and to not damage any other important parts of RAM, we use glitch Pokemon $E3 (or $E4), as it's name begins with an end terminator $50. Because of this, we can safely move the buffer forward.

Our party looks like this: (note: Referring to the game gameboy you are duplicating the save file from as "victim", the other gameboy with my save file will be referred to as "master")
Code: [Select]
06 ; # of Pokemon, completely irrelevant
00 x6  ; These six pokemon are irrelevant also
e3 x346 ; Advance the buffer to the "victim"'s stack
ce ; Write $CE's name to the victim's stack (EE 21 96 D7 CB 86 21 A3 D7 CB), "A3 D7" is what the game will read from when returning, causing it to jump to $D7A3 (nop slide to master's name)
e3 x7 ; Advance the buffer to the "master"'s stack
f1 ; Write $F1's name to the stack (40 40 40 FF FA 30 D7 CB 47 C0) "30 D7" is what the game reads from when returning, forcing a jump to $D730 (event flags)
ff ; Cause aforementioned buffer to return, forcing the jumps

---
ld a,8 ; a = 8
ldh [rIE],a ; Only allow serial int
ld hl,$0316 ; Garbage to send master in exchange for payload (starts with $FD to allow for transfer)
ld de,$dc00 ; Location to store payload
ld bc,$0110 ; Bytes to send (sends way more than necessary to account for $fd bytes)
call $216f ; Exchange data
ld hl,$dc00
ld b,$fd
.loop: ; Check for FD bytes
ldi a,[hl] ; Grab byte at hl
cp b ; Is it $fd?
jr z,.loop ; If it is, keep looking
dec hl ; Undo the ldi
ld a,$0d ; a = $0D
ldh [rIE],a ; Enable vblank,timer,and serial ints
jp hl ; Jump to payload sent by master

At this point, the victim Gameboy is executing code from the master's name. The code we have written there causes the victim Gameboy to wait for synchronization with the master, and display the "Waiting!" text on the screen. The master gameboy is executing code in a section of RAM that is normally used for event flags. It nop slides to $D743, which there we have written a jump instructon to $DA80, our "PC pokemon" (there we have written another payload). Aforementioned payload causes master to synchronize with the slave gameboy.

Once both gameboys are synchronized (using a subroutine at $226E, or $227F if we do not want to display the "Waiting!" text), we call a subroutine to delay for a few frames, and then we begin the transfer.

The master gameboy first transmits the payload we want the victim to execute. The victim then (after jumping to a payload written at the end of master's party) executes the aforementioned payload, which causes the victim to write 03:A000 - 03:AFFF to the tilemap buffer. Then, both gameboys synchronize once more, and the victim gameboy sends over that portion of the save file (receives garbage in return). The master then copies what it receives into it's own save file in it's respective location. It does this for each 256-byte portion of that SRAM banks before switching banks. Once all 4 banks have been copied (0 - 3), the game locks SRAM and then restarts.

Code executed by master at $DA80:
Code: [Select]
transmitpayload:
call $226e
call $3dd7
ld a,8
ldh [$ff],a
ld hl,$d53a
ld de,$c3a0
ld bc,$110
call $216f
ld a,$0d
ldh [$ff],a
Start:
ld b,4
push bc
ld a,$0a
ld h,a
swap a
push af
ld [hl],h
ld h,$40
dec b
ld [hl],b
ld h,$60
ld l,$01
ld [hl],l
transmit:
call $227f
call $3dd7
ld a,8
ldh [$ff],a
ld hl,$0316
ld bc,$10b
ld de,$c3a0
call $216f
ld a,$0d
ldh [$ff],a
findhl:
ld hl,$c3a0
ld b,$fd
.loop:
ldi a,[hl]
cp b
jr z,.loop
dec hl
Init:
pop af
ld d,a
push af
ld e,0
ld bc,$100
memcpy:
ldi a,[hl]
ld [de],a
inc de
dec bc
ld a,b
or c
jr nz,memcpy
determine:
pop af
inc a
ld b,$c0
cp b
jr z,bankswap
push af
jr transmit
bankswap:
pop bc
dec b
push bc
jr z,end
ld h,$40
dec b
ld [hl],b
ld a,$a0
push af
jr transmit
end:
ld h,$00
ld [hl],h
jp $100

Code executed by victim (near $dc00)
Code: [Select]
Start:
ld b,4
push bc
ld a,$0a
ld h,a
swap a
push af
ld [hl],h
ld h,$40
dec b
ld [hl],b
ld h,$60
ld l,$01
ld [hl],l

Init:
pop af
ld h,a
ld l,$ff
ld de,$c507
ld bc,$100
push af
backwardsmemcpy:
ldd a,[hl]
ld [de],a
dec de
dec bc
ld a,b
or c
jr nz,backwardsmemcpy
ld a,$fd
ld [de],a
transmit:
push de
call $227f
call $3dd7
pop hl
ld a,8
ldh [$ff],a
ld de,$c200
ld bc,$10b
call $216f
ld a,$0d
ldh [$ff],a
determine:
pop af
inc a

Sorry if I over/under explained. Enjoy!
« Last Edit: January 09, 2018, 07:04:41 am by Epsilon »
"What's a stack? Can you eat that?"

"Sure, just POP it into your mouth!" (someoneplskillme)

Clash Royale profile: #LYQC9LLV. Join our clan because we're lonely.

Does anybody really know what time it is?

Does anybody really care?
- Chicago