The Special Defense badge boost glitch is a glitch in Pokémon Gold, Silver and Crystal that causes the Glacier Badge's boost to the Special Defense stat of a Pokémon to not apply if the Special Attack stat of that Pokémon is in certain ranges.
Specifically, if the unboosted Special Attack stat (which may include the Special Attack stage modifier) is either 0 ~ 205, or 433 ~ 660, then the glitch will cause the player to lose the Special Defense boost.
After giving the player the Glacier Badge, Pryce mentions that "That BADGE will raise the SPECIAL stats of POKéMON." Presumably, the developer's intention is for the Glacier Badge to boost both the Special Attack and the Special Defence unconditionally. However, the code to apply the Special Defense boost uses register
a to determine whether the boost should be applied, but the value in register
a is overwritten while applying the Special Attack boost. This results in an unintended extra condition for the boost to apply.
The piece of code to apply the badge stat boosts is as follows: (external link)
; The value in register b has been initialized to a bitmask for Johto badges,
; in the following order, starting from the least significant bit:
; ZEPHYR, HIVE, MINERAL, FOG, PLAIN, STORM, GLACIER, RISING.
; The order of the stats are:
; Attack, Defense, Speed, SpAtk, SpDef.
ld hl, wBattleMonAttack
ld c, 4 ; The number of times the below loop should execute
ld a, b ; Save the value of b, specifically for use after the loop
srl b ; Shift b to the right, removing the least significant bit
call c, BoostStat ; Apply the boost if the bit just removed is 1
inc hl ; Move to the next stat (stats are 2-byte integers)
srl b ; Throw away a bit from b (only check every other badge)
jr nz, .CheckBadge
srl a ; Check Glacier Badge again for Special Defense
call c, BoostStat
The last check assumes that the value in register
a comes from the
ld a, b instruction from the last iteration of the loop. Since the
srl b immediately after is a check for the Glacier Badge, the final
srl a should be a check for the Glacier Badge, too.
However, this does not take into account that the function BoostStat actually overwrites register
a. The code for that function is as follows: (external link)
; Raise stat at hl by 1/8.
ld a, [hli]
ld d, a ; High byte of the stat
ld e, [hl] ; Low byte of the stat
rr e ; Shift the 16-bit integer de to the right...
rr e ; ...
rr e ; ... three times (i.e. divide by 8)
ld a, [hl]
ld [hld], a
ld a, [hl]
ld [hli], a ; Add de back into the stat at hl
; Cap at 999.
ld a, [hld] ; Low byte of boosted stat
ld a, [hl] ; High byte of boosted stat
ret c ; If boosted stat is less than 999, return
ld a, HIGH(MAX_STAT_VALUE)
ld [hli], a
ld a, LOW(MAX_STAT_VALUE)
ld [hld], a ; Otherwise, set boosted stat to 999
Here, the value of MAX_STAT_VALUE is 999 = 0x03E7.
There are therefore three cases for the
srl a check:
- If the player does not have the Glacier Badge, then the function BoostStat is not called, and the check works as intended. The Special Defense boost will not be applied.
- If the player has the Glacier Badge, and the unboosted Special Attack is at least 888, then the boosted Special Attack would be at least 999, and the last few instructions in BoostStat will cap it at 999, setting register
a to LOW(MAX_STAT_VALUE) = 0xE7 in the process. The
srl a check will see that the least significant bit of 0xE7 is 1, so the Special Defense boost will be applied.
- If the player has the Glacier Badge, and the unboosted Special Attack is less than 888, then the value left in register
a will be the result of
sbc HIGH(MAX_STAT_VALUE), i.e. the high byte of (boosted Special Attack - 999). The table below shows the possible values for that high byte:
||Boosted SpAtk - 999
||Value left in
|0 ~ 205
||0 ~ 230
||-999 ~ -769 (0xFC19 ~ 0xFCFF)
|206 ~ 432
||231 ~ 486
||-768 ~ -513 (0xFD00 ~ 0xFDFF)
|433 ~ 660
||487 ~ 742
||-512 ~ -257 (0xFE00 ~ 0xFEFF)
|661 ~ 887
||743 ~ 997
||-256 ~ -2 (0xFF00 ~ 0xFFFE)
In conclusion, this glitch causes an unintended behavior only when the player has the Glacier Badge, and the unboosted Special Attack of the Pokémon in question is either 0 ~ 205, or 433 ~ 660. In those cases, the glitch causes the Special Defense boost to not apply.