ZZAZZ glitch
はじめに
初代ポケモンで20番目セレクトバグ[1][2]やfifth法[3]を利用してバグトレーナーと戦うと、手持ちポケモンの情報が破壊されることがあります[4]。これはZZAZZ glitch[5]と呼ばれているバグによるもので、トレーナーに勝ったときにもらえる賞金の計算処理に起因します。以下、このバグについて解説します。
トレーナーからもらえる賞金
※これ以降に出てくるROMアドレスは、緑後期版のものです。他のバージョンでは異なる場合があります。
トレーナーに勝ったときにもらえる賞金は、アドレスD057h~D058hにBCD・ビッグエンディアンで書き込まれます*1。このアドレスは、0E:6074からの処理によって書き込まれます。以下にその処理内容を示します。
- 前処理によって、アドレスD025h~D026hに賞金の倍率(BCD・ビッグエンディアン)、アドレスD0EChに手持ち最後のポケモンのレベルが入っている。
- アドレスD056h~D058hを00hで初期化する。
- deレジスタ = D058hとする。
- アドレスD0EChに入っている値の回数分、以下の処理を繰り返し行う。ただしD0EChの値が00hの場合、以下の処理は256回繰り返す。
従って、賞金は「倍率*手持ち最後のレベル」となります(ただし、レベル0は256扱いとする)。ただし、後述の仕様により賞金が9999円を超える場合は、9999円となります。
BCDの足し算を行うサブルーチンの仕様
このルーチンは、メモリ上のBCDで表されている値同士の足し算を行います。パラメーターとしてdeレジスタに被加算BCDが格納されているアドレス、hlレジスタに加算BCDが格納されているアドレス、cレジスタにそれぞれのBCDのバイト数を指定します。従って、このルーチンは(de) = (de) + (hl)という計算を行います。
計算後に上限を超えた場合は、上限値に補正します。例えば、2バイトのBCDに対して計算を行って9999hを超えた場合は、9999hに補正します(以下、この補正を上限補正という。)。
バグ解説
ZZAZZ glitchは、BCDの足し算を行うサブルーチンによって上限補正が行われると引き起こされます。
賞金を求める処理の手順4-3は上限に到達することを想定していないため、上限補正が発生するとこの処理により賞金を書き込むアドレスが3バイト上位アドレス側にズレます。このズレは上限補正が発生するたびに起こります。
従って、このバグが発生すると、アドレスD059h~D355hまでの3の倍数以外のアドレスが99hで書き換えられます。ただし、書き換えられるアドレスの範囲は戦うトレーナーの種類や手持ちによって変化します。特に、バグトレーナーは賞金の倍率が通常のトレーナーよりも高いため、上限補正が起こりやすくなります。
書き換えられる範囲が十分に広い場合は、主人公の名前・手持ちポケモンの情報・手持ち道具などが書き換えられます。これらの情報に対して99hが何に対応しているかについては、表1を参照してください。
種類 | 99hに対応するもの |
---|---|
文字 | カタカナの「ハ」 |
ポケモン(内部番号) | フシギダネ |
わざ | だいばくはつ |
PP | ポイントアップ2回使用・残りPP25 |
状態異常 | ねむり残り1ターン・どく・やけど・(bit7)*2 |
道具 | 使うとオーキドの言葉が表示されるバグ道具 緑後期以外は名前が長い |
参考文献
[1] yue@・ゴーマもどき、オーキド"せんせい"とは何ぞやと | ネオ・グリーン、http://g-modoki.s59.xrea.com/x/Pokemon/okido/000.html、2023年9月12日閲覧。
[2] 20番目バグ - pokemonbug @ ウィキ - atwiki(アットウィキ)、https://w.atwiki.jp/pokemonbug/pages/16.html、2023年9月12日閲覧。
[3] fifth法 - pokemonbug @ ウィキ - atwiki(アットウィキ)、https://w.atwiki.jp/pokemonbug/pages/10.html、2023年9月12日閲覧。
[4] yue@・ゴーマもどき、不可思議現象、20番目の怪 | ネオ・グリーン、http://g-modoki.s59.xrea.com/x/Pokemon/okido/100.html、2023年9月12日閲覧。
[5] ZZAZZ glitch - Glitch City Wiki、https://glitchcity.wiki/wiki/ZZAZZ_glitch、、2023年9月12日閲覧。