バーズテイル (FC) 未定義動作バグ
注意: 本記事で述べるバグは RAM の初期値に依存して未定義の動作を行うため、実機での実行は推奨しない (大抵はリセットまたはフリーズが発生すると思われるが、セーブデータ破壊の可能性も否定はできないため)。
FC版『バーズテイル』は、タイトル画面で入力 Up+Start によりゲームを開始すると未定義動作が発生するバグがあり、主要なエミュレーターではリセットが発生する (movie)。具体的にはバンク切り替えが壊れて RAM $00-
が実行されるのだが、本作は起動時にゼロページの初期化を行わないため、RAM $00-
の初期値がそのままコードとして実行されることになる。エミュレーターの場合、デフォルト設定では RAM $00
の値は 0 であることが多く、これは brk
命令として解釈され、結果としてリセットがかかる (本作では IRQ/BRK と RESET のハンドラが共通であるため)。
上記入力を行った際にバンク切り替えが壊れる原因は、ギルドへ遷移するより先に前進移動の処理が実行されてしまうことだと思われる。前進移動を行うとPT全員について毒ダメージの判定/処理が行われるが、この時点ではまだPT人数が 0 なので、毒ダメージ判定/処理のループが 256 回実行されてしまう (該当コード: $C80A
)。そして、PT 6 人目より後のメンバーについては冒険者構造体ポインタが不正な値になるため、それらのポインタを経由して MMC1 レジスタへの書き込みも行われ、結果として MMC1 の書き込みカウンタがずれてしまう。この状態でバンク切り替えルーチンを呼ぶと不正なバンクがロードされ、そのバンク内のポインタ経由で間接ジャンプを行った結果 RAM $00-
が実行されることになる。
このバグは制御の余地が少ないため、今のところ TAS には応用できていない (PTメンバーが毒ダメージで死ぬ寸前でリセットしてからバグを実行すると実行フローが変化するが、やはり結果はリセットになってしまうようである)。なお、本作は RAM $00-
付近はおそらく未使用なので、ソフトリセットを併用しても通常は brk
以外のコードを実行させることはできない (カートリッジ差し替えを許すなら初期値を自由に設定できるが)。また、仮に制御できるとしても、上記の不正なポインタにより open bus やミラー領域へのアクセスも大量に発生するので、実機での再現性は割と疑わしいところがある。
2025-06-29 追記:
本作ではイベントマスの処理を終える際にも前進移動を割り込ませることができる。たとえば、階段を上り下りする際の決定入力を Up+A にすると遷移先のマップで既に 1 歩前進した状態になる (「すすめない!」になることもある)。また、石の顔などのイベントから抜ける際の入力を Up+A にすると壁を抜けて本来進入できない領域を歩くこともできる。