TASVideos

Tool-assisted game movies
When human skills are just not enough

Submission #7097: CasualPokePlayer's GBC Pokémon: Gold Version "save glitch" in 03:14.16

Console: Game Boy Color
Game name: Pokémon: Gold Version
Game version: USA/Europe
ROM filename: pokegold.gbc
Branch: save glitch
Emulator: Bizhawk 2.5.2
Movie length: 03:14.16
FrameCount: 11599
Re-record count: 5474
Author's real name: Wesley B.
Author's nickname: CasualPokePlayer
Submitter: CasualPokePlayer
Submitted at: 2021-04-13 13:05:26
Text last edited at: 2021-06-24 02:42:54
Text last edited by: CasualPokePlayer
Download: Download (4542 bytes)
Status: published
Click to view the actual publication
Submission instructions
Discuss this submission (also rating / voting)
List all submissions by this submitter
List pages on this site that refer to this submission
View submission text history
Back to the submission list
Author's comments and explanations:

(Link to video)

See http://tasvideos.org/7090S.html for the branch name change; this movie, while doing save corruption, ultimately just does a game end glitch, so I'm marking the branch as such.

Emulator used: Bizhawk 2.5.2

  • SubGBHawk is used due to the use of a sub-frame reset.
  • CGB in GBA is enabled for potential console verification which I mean no chance in heck this thing is getting console verified anyways lmao.

Categories

  • Corrupts save data
  • Executes arbitrary code
  • No luck manipulation (lmao)

About the run

Version Choice

Gold is used over Silver due to better default names.

Route

  • Save data is cleared this time due to the ACE payload requiring cleared save data.
  • A default name (GOLD) is chosen as the name doesn't appear enough to warrant a custom name.
  • Cyndaquil's Berry is taken off, then the game is saved.
  • The Berry is tossed, then a checksum collision is done to save the 0 items count while keeping the berry in my pack.
  • The Berry is tossed again, but this time since there was "0 items" in the pack, the item pocket underflows to 255 items.
  • Items are created in the Balls pocket to setup ACE.
    • Mail is created first to create a payload. The payload is largely identical to the previous submission's, just accounting for it using Mail instead of box names, along with storing a bootstrap to jump from the mail buffer to the actual mail data in SRAM.
    • TM22 is created, then swapped down to slot 0x25, then 0xE9 is put into the tossed buffer by faking a toss, then TM22 is used. This executes a small bootstrap, which jumps to the actual bootstrap in the mail buffer, which unlocks SRAM then jumps to a little before the Mail data in SRAM. Note this SRAM area jumped to is never initialized by the game, so it will be filled with 0xFF (crashes) unless save data is explicitly cleared as was done in the beginning of the movie.
  • Auto-input takes over once the payload is finished, then Red is "defeated".

Bootstrap & Payload

Here is a tracelog of the relevant parts of the bootstrap and payload:

  D002:  D5        push de                 AF:0200 BC:0007 DE:CF70 HL:D002 SP:DFC9 ; TM22 jumps here
  D003:  25        dec h                   AF:0200 BC:0007 DE:CF70 HL:D002 SP:DFC7 ; D003 holds the current item slot, this is why TM22 is swapped
  D004:  9B        sbc a, e                AF:0260 BC:0007 DE:CF70 HL:CF02 SP:DFC7 ; D004 holds the last Pokemon species interacted with (Cyndaquil)
  D009:  E9        jp hl                   AF:9250 BC:0007 DE:CF70 HL:CF02 SP:DFC7 ; D009 holds the tossed item buffer, this is why a fake toss is done
  CF02:  D6 88     sub a, $88              AF:9250 BC:0007 DE:CF70 HL:CF02 SP:DFC7 ; CF02 is in the middle of the mail buffer, a bit after the actual payload
  CF04:  F5        push af                 AF:0A60 BC:0007 DE:CF70 HL:CF02 SP:DFC7
  CF05:  F5        push af                 AF:0A60 BC:0007 DE:CF70 HL:CF02 SP:DFC5
  CF06:  E1        pop hl                  AF:0A60 BC:0007 DE:CF70 HL:CF02 SP:DFC3 ; address $0000-$1FFF needs to be written to to unlock SRAM
  CF07:  D1        pop de                  AF:0A60 BC:0007 DE:CF70 HL:0A60 SP:DFC5 ; value $xA needs to be written to unlock SRAM
  CF08:  72        ld [hl], d              AF:0A60 BC:0007 DE:0A60 HL:0A60 SP:DFC7 ; unlock SRAM
  CF09:  D2 FB A5  jp nc, $A5FB            AF:0A60 BC:0007 DE:0A60 HL:0A60 SP:DFC7 ; jump a little before Mail data in SRAM, also where Joypad->Opcode byte is written
  A5FB:  27        daa                     AF:0A00 BC:0007 DE:2D00 HL:0A60 SP:DFC7
  A5FB:  BD        cp a, l                 AF:1000 BC:0007 DE:9000 HL:0A60 SP:DFC7
  A5FB:  62        ld h, d                 AF:1000 BC:0007 DE:F200 HL:0A60 SP:DFC7
  A5FB:  6F        ld l, a                 AF:1000 BC:0007 DE:9D00 HL:F260 SP:DFC7
  A5FB:  3D        dec a                   AF:1000 BC:0007 DE:A000 HL:F210 SP:DFC7
  A5FB:  32        ld [hl-], a             AF:0F00 BC:0007 DE:9200 HL:F210 SP:DFC7 ; wPlayerLastMapY = $0F
  A5FB:  7E        ld a, [hl]              AF:0F00 BC:0007 DE:EC00 HL:F20F SP:DFC7
  A5FB:  25        dec h                   AF:0900 BC:0007 DE:C900 HL:F20F SP:DFC7
  A5FB:  6A        ld l, d                 AF:0900 BC:0007 DE:A300 HL:F10F SP:DFC7
  A5FB:  19        add hl, de              AF:0900 BC:0007 DE:BA00 HL:F1A3 SP:DFC7
  A5FB:  62        ld h, d                 AF:0900 BC:0007 DE:D800 HL:ABA3 SP:DFC7
  A5FB:  22        ld [hl+], a             AF:0900 BC:0007 DE:FA00 HL:D8A3 SP:DFC7 ; EVENT_RED_IN_MT_SILVER = clear bit 2
  A5FB:  66        ld h, [hl]              AF:0900 BC:0007 DE:9C00 HL:D8A4 SP:DFC7
  A5FB:  50        ld d, b                 AF:0900 BC:0007 DE:CC00 HL:F0A4 SP:DFC7
  A5FB:  CC 00 00  call z, $0000           AF:0900 BC:0007 DE:CC00 HL:F0A4 SP:DFC7
  A5FB:  6A        ld l, d                 AF:0900 BC:0007 DE:A600 HL:F0A4 SP:DFC7
  A5FB:  22        ld [hl+], a             AF:0900 BC:0007 DE:8400 HL:F0A6 SP:DFC7 ; wSouthConnectionStripYOffset = $09
  A5FB:  1F        rra                     AF:0900 BC:0007 DE:9B00 HL:F0A7 SP:DFC7
  A5FB:  77        ld [hl], a              AF:0400 BC:0007 DE:EC00 HL:F0A7 SP:DFC7 ; wSouthConnectionStripXOffset = $04
  A5FB:  18 00     jr $A5FD                AF:0400 BC:0007 DE:F400 HL:F0A7 SP:DFC7
  A5FB:  6A        ld l, d                 AF:0400 BC:0007 DE:9E00 HL:F0A7 SP:DFC7
  A5FB:  3D        dec a                   AF:0400 BC:0007 DE:A300 HL:F09E SP:DFC7
  A5FB:  22        ld [hl+], a             AF:0300 BC:0007 DE:8100 HL:F09E SP:DFC7 ; wSouthConnectedMapGroup = $03
  A5FB:  BF        cp a, a                 AF:0300 BC:0007 DE:3E00 HL:F09F SP:DFC7
  A5FB:  7A        ld a, d                 AF:0300 BC:0007 DE:4400 HL:F09F SP:DFC7
  A5FB:  77        ld [hl], a              AF:4400 BC:0007 DE:3300 HL:F09F SP:DFC7 ; wSouthConnectedMapNumber = $44
  A5FB:  29        add hl, hl              AF:4400 BC:0007 DE:1A00 HL:F09F SP:DFC7
  A5FB:  44        ld b, h                 AF:4400 BC:0007 DE:5E00 HL:E13E SP:DFC7
  A5FB:  0F        rrca                    AF:4400 BC:E107 DE:5100 HL:E13E SP:DFC7
  A5FB:  F8 00     ld hl, sp + $00         AF:2200 BC:E107 DE:A900 HL:E13E SP:DFC7
  A5FB:  60        ld h, b                 AF:2200 BC:E107 DE:C900 HL:DFC7 SP:DFC7
  A5FB:  2D        dec l                   AF:2200 BC:E107 DE:E400 HL:E1C7 SP:DFC7
  A5FB:  35        dec [hl]                AF:2200 BC:E107 DE:D100 HL:E1C6 SP:DFC7 ; wInputType = $FF
  A5FB:  49        ld c, c                 AF:2200 BC:E107 DE:9800 HL:E1C6 SP:DFC7
  A5FB:  62        ld h, d                 AF:2200 BC:E107 DE:FA00 HL:E1C6 SP:DFC7
  A5FB:  6F        ld l, a                 AF:2200 BC:E107 DE:9500 HL:FAC6 SP:DFC7
  A5FB:  35        dec [hl]                AF:2200 BC:E107 DE:A000 HL:FA22 SP:DFC7 ; wPartyCount = $00
  A5FB:  F8 00     ld hl, sp + $00         AF:2200 BC:E107 DE:5800 HL:FA22 SP:DFC7
  A5FB:  68        ld l, b                 AF:2200 BC:E107 DE:3000 HL:DFC7 SP:DFC7
  A5FB:  F9        ld sp, hl               AF:2200 BC:E107 DE:C900 HL:DFE1 SP:DFC7 ; SP = $DFE1 (return to overworld)
  A5FB:  C9        ret                     AF:2200 BC:E107 DE:0080 HL:DFE1 SP:DFE1

Samsara: File replaced with a 13 second improvement on Gold, and judging.

Samsara: The palindrome of Gen2 glitched is finally complete. Gold is obsoleted by Silver is obsoleted by Crystal is obsoleted by Crystal is obsoleted by Silver and is now obsoleted by Gold once more. I do hope that future TASes will continue to uphold this tradition. Accepting as an improvement to the published run.

Spikestuff: Agumon is my favourite Pokémon.


Similar submissions (by title and categories where applicable):