基礎知識
戦闘関係
コンピュータゲームでは、プレイヤーが何らかの操作をしなければゲームが進行しない。
スーパーファミコンのゲームでいえば、プレイヤーがコントローラのボタンを押さなければゲームは進行しない。
ここでは、ゲームにおける基本中の基本、コントローラのボタンを押したかどうか、ボタン判定について説明する。
本作におけるプログラムの紹介だが、おそらくスーパーファミコンのゲームならどれも似たような処理でボタン判定をしているはずである。
スーパーファミコンのコントローラ周りの説明は以下も参照にさせていただいた。
上サイトなどでも記述があるが、ゲームのコントローラをジョイパッド(Joypad)とも呼ぶ。意味は同じ。
ライブ・ア・ライブにおいて、ゲーム操作に必要なのはコントローラ1個(1P用のコネクタに接続)のみである。
コントローラのボタンは12個。
ボタン判定の仕組みだが、スーパーファミコン内部には、「Auto Joypad Read(自動ジョイパッド読み取り)」という機能があり、これを利用している。
$00:4200が、割り込み有効化レジスタというアドレスにあたり、8ビットの値の一番下のビットに1を入れると自動ジョイパッド読み取り機能をONにしてくれる。
アドレス$00:4212に入る値が、自動ジョイパッド読み取り機能のON・OFF状態を記録しており、8ビットの値の一番下に1の時、自動ジョイパッド読み取り機能がON、0ならOFFを表す。
自動ジョイパッド読み取り機能がONの間、$00:4218~$00:4219の2バイトの領域に、コントローラ1の何のボタンが押されているかを出力する仕組みである。
ちなみにコントローラ2の状態は$00:421A~$00:421Bの2バイトに出力されるそうだが、本作においては特に関係ない。
自動ジョイパッド読み取り機能はONにしてから一定時間有効で、その時間は4224マスターサイクルである。4224マスターサイクル経過後、自動的にOFFになる。
スーパーファミコンの中の水晶発振器という部品に電圧をかけると振動することを利用して電気信号を送信する仕組みがあるのだが、1秒間に2,100万回以上というとんでもない回数で振動している(21.4772700MHz)。この振動した回数4224回分の時間が4224マスターサイクルで、4224/21477270秒にあたる。
……数字だけ見てもよくわからないが、0.0002秒くらいであり、1/60秒を単位とするフレームで表すと0.01フレームくらいである。
とにかく、ほんの短時間しかボタンが押されているか判定しないことになるが、この判定を1フレーム毎に行えば、ボタンを押して1フレーム以内にボタンを押しているかどうか判断してくれることになる。
本作をプレイしていて、ボタンの反応が遅いと感じることはまずないだろう。
$00:4218~$00:4219の2バイトに出力される値は以下のようになっている。
$00:4218が下位バイト、$00:4219が上位バイト。
ボタンを同時押しした場合は合計値が出力される。
| ボタン | 16進数2バイト | 2進数16ビット |
|---|---|---|
| R | $0010 | %0000 0000 0001 0000 |
| L | $0020 | %0000 0000 0010 0000 |
| X | $0040 | %0000 0000 0100 0000 |
| A | $0080 | %0000 0000 1000 0000 |
| 右 | $0100 | %0000 0001 0000 0000 |
| 左 | $0200 | %0000 0010 0000 0000 |
| 下 | $0400 | %0000 0100 0000 0000 |
| 上 | $0800 | %0000 1000 0000 0000 |
| スタート | $1000 | %0001 0000 0000 0000 |
| セレクト | $2000 | %0010 0000 0000 0000 |
| Y | $4000 | %0100 0000 0000 0000 |
| B | $8000 | %1000 0000 0000 0000 |
例えば右ボタンを押した場合、$00:4218に$00、$00:4219に$01が出力される。
右方向にダッシュをする時は、Bボタンと右ボタンを同時押しするから、$0100と$8000を加算し、$00:4218に$00、$00:4219に$81が出力される。
といった仕組みである。
上の通りに$00:4218の下1桁にはボタンに対応した数値がない。
よって、ボタンの状態は、$00:4219・$00:4218の2バイト(16進数4桁)の中で上3桁で表されるということがわかる。
$00:4200について[$00:4200]が割り込み有効化レジスタである、と上で説明した通りだが、8ビットの値の一番下のビットに1を入れると自動ジョイパッド読み取り機能をONにする以外にも機能がある。
コントローラのボタン判定とは直接関係ないが、処理として重要なので、合わせて説明しておく。
[$00:4200]の下のビットから順に0~7と番号をふると、以下のように対応している。
| bit | 内容 |
|---|---|
| 0 | 自動Joypad読み出し有効化フラグ (0=無効, 1=有効) |
| 1~3 | 使用しない |
| 4~5 | IRQフラグ(2bit) |
| 6 | 使用しない |
| 7 | VBlank NMI 有効化フラグ (0=無効, 1=有効) |
IRQとNMIはどちらも処理の途中に割り込むための命令である。
IRQはとりあえず横に置いておくとして、7bit目、つまり一番上のビットの「VBlank NMI 有効化フラグ」が重要である。
VBlankとは、スーパーファミコンの画面1枚分を描画する処理の間の空白時間(Blank)のことである。1フレームに1回入る。
1枚分のグラフィック描画中に、グラフィック用メモリ(VRAM)に別のデータを転送すると画面描画がおかしくなるので、VBlank中に次の画像のデータをVRAMに送る。
VBlankのタイミングが来た時に、次のグラフィックの処理に移行するため、NMIという命令で現在の処理を一時中断するかどうかを、「VBlank NMI 有効化フラグ」で決めている。
本作のサブルーチンを見てみると、[$00:4200]で自動Joypad読み出し有効化フラグをONにする時、だいたい[$00:4200]に$01か$81を書き込むのだが、$01ならNMI割り込み無効、$81ならNMI割り込み有効ということである。
1フレーム後に、現在とは別のグラフィックを描画するなら[$00:4200]に$81を書き込み、NMI割り込みを有効化する必要がある。
ボタンの出力先は上の通り$00:4218~$00:4219なのだが、この値は他アドレスにもコピーされて各種判定に使われる。
| フィールド | $00:0000 | $00:0001$00:020A |
|---|---|---|
| 戦闘 | $00:0344$00:0348 | $00:0345$00:0349 |
| メニュー画面 | $00:057D | $00:057E |
| R | $10 | - |
| L | $20 | - |
| X | $40 | - |
| A | $80 | - |
| 右 | - | $01 |
| 左 | - | $02 |
| 下 | - | $04 |
| 上 | - | $08 |
| スタート | - | $10 |
| セレクト | - | $20 |
| Y | - | $40 |
| B | - | $80 |
つまり、[$00:4219][$00:4218]の2バイトは以下のようにコピーされる。
| 元アドレス | [$00:4219] | [$00:4218] |
|---|---|---|
| フィールド | [$00:0001]- | [$00:0000][$00:020A] |
| 戦闘 | [$00:0345][$00:0349] | [$00:0344][$00:0348] |
| メニュー画面 | [$00:057E] | [$00:057D] |
実際の判定のサブルーチンだが、フィールド・戦闘・メニュー画面でアドレスが異なる。
「自動ジョイパッド読み取り機能がONの間、$00:4218~$00:4219の値を読み取る」という処理自体は変わらない。
本作では、フィールドでのサブルーチンはバンク$C0、戦闘中のサブルーチンはバンク$C1、メニュー画面のサブルーチンはバンク$C2に収納されている。
アドレスの値が近い方が呼び出しに時間がかからないので、フィールド・戦闘・メニュー画面でそれぞれボタン判定サブルーチンを用意しているようだ。
基本の処理は以下の通り。
;ループ処理開始 LDA $4212 [$00:4212] ;Aに[$00:4212]をロード AND #$01 ;Aと$01で論理積 BNE (ループ頭) ;ゼロフラグが立っていないときループ頭に戻る ;ループ処理ここまで ;以降16bitモードのAレジスタか、 LDA $4218 [$00:4218] ;Aに[$00:4219][$00:4218]をロード ;または16bitモードのXレジスタで処理 LDX $4218 [$00:4218] ;Xに[$00:4219][$00:4218]をロード
[$00:4212]の一番下1ビットに1が入っている時は、[$00:4219][$00:4218]にボタンの押されている状態を出力し続けている。
上に記した通り、自動ジョイパッド読み取り機能は4224マスターサイクル経過すると自動終了だが、その時に[$00:4212]の一番下1ビットが0となって、自動ジョイパッド読み取り機能終了寸前のボタンの状態が[$00:4219][$00:4218]に残る。
自動ジョイパッド読み取り機能終了のタイミングのボタンの状況を読み出すのが上のサブルーチンになる。
ループ処理で、[$00:4212]と$01の論理積を取り、[$00:4212]の下1ビットが1ならゼロフラグが立たないのでループ頭に戻る。
このループは、[$00:4212]の下1ビットが0になるまで、つまり自動ジョイパッド読み取り機能がOFFになるまで続く。
自動ジョイパッド読み取り機能がOFFになると[$00:4219][$00:4218]をロードして、ボタン状況を読み出し、各種判定を行うことになる。
判定中、何のボタンも押されていないのなら、[$00:4219][$00:4218]には$0000が入るが、何かのボタンが押されていたら$0000以外が入る。
右ボタンを押せば、$00:4218に$00、$00:4219に$01が出力され、状況により右ボタンに対応した処理を行うことになる。
もし[$00:4219][$00:4218]が$0000、つまり何のボタンも押されなかったとしても、何もしないままということはない。
フィールドであったら何のボタンも押されていなくても、1フレームに1回、フィールド乱数を生成しているし、幕末編のフィールドなどだったらタイマーイベントがタイマー残り時間を-1して、鐘を鳴らしたりもする。ランダム移動する街の人の移動処理も行う。
以下、フィールド・戦闘・メニュー画面それぞれのサブルーチンをざっと紹介しておく。
フィールドにいる時のボタン判定用サブルーチンは以下の通り。
フィールド上でも、メニュー画面を開いている時とは別になる。
$C0/1051 LDA #$02 ;Aに$02をロード $C0/1053 STA $0104 [$00:0104] ;Aを[$00:0104]に書き込み $C0/1056 LDA #$5C ;Aに$5Cをロード $C0/1058 STA $F8 [$00:00F8] ;Aを[$00:00F8]に書き込み $C0/105A LDX #$01D1 ;Xに$01D1をロード $C0/105D STX $F9 [$00:00F9] ;Xを[$00:00F9]に書き込み $C0/105F LDA #$C0 ;Aに$C0をロード $C0/1061 STA $FB [$00:00FB] ;Aを[$00:00FB]に書き込み $C0/1063 LDA #$81 ;Aに$81をロード $C0/1065 STA $4200 [$00:4200] ;Aを[$00:4200]に書き込み $C0/1068 PLB ;DBレジスタに値をプル $C0/1069 RTS ;サブルーチン戻り
$C0/106A PHB ;DBレジスタをスタックにプッシュ $C0/106B LDA #$00 ;Aに$00をロード $C0/106D PHA ;Aをスタックにプッシュ $C0/106E PLB ;DBレジスタに値をプル $C0/106F LDA #$01 ;Aに$01をロード $C0/1071 STA $4200 [$00:4200] ;Aを[$00:4200]に書き込み $C0/1074 JSR $09F2 [$C0:09F2] ;[$C0:09F2]へジャンプ
[$00:4200]に$81または$01に書き込んで自動ジョイパッド読み取り機能をONにするサブルーチンは上の通り。
先に説明した通り、VBlankのタイミングで割り込みのNMIを入れるかどうか(現在の処理を中断しグラフィックの処理に移行するかどうか)でサブルーチンを変えるようにしている。
つまり、1フレーム後に、現在とは別のグラフィックを描画するなら[$00:4200]に$81を書き込み、NMI割り込みを有効化する必要がある。
$C0/B83E LDA #$01 ;Aに$01をロード ;ボタン判定ループ処理 $C0/B840 BIT $4212 [$00:4212] ;Aと[$00:4212]で論理積(ステータスフラグ変更のみ) $C0/B843 BNE $FB [$B840] ;ゼロフラグが立っていないとき[$B840]分岐 ;ボタン判定ループ処理ここまで $C0/B845 REP #$20 ;Aを16bit幅に変更、Mフラグをクリア $C0/B847 LDA $4218 [$00:4218] ;Aに[$00:4219][$00:4218]をロード $C0/B84A BIT #$000F ;Aと$000Fで論理積(ステータスフラグ変更のみ) $C0/B84D BEQ $03 [$B852] ;ゼロフラグが立っているとき[$B852]分岐 ;ゼロフラグOFF $C0/B84F LDA #$0000 ;Aに$0000をロード ;ゼロフラグON $C0/B852 TAX ;Aの値をXレジスタに転送 $C0/B853 EOR $00 [$00:0000] ;Aと[$00:0001][$00:0000]で排他的論理和XOR $C0/B855 STX $00 [$00:0000] ;Xを[$00:0001][$00:0000]に書き込み $C0/B857 AND $00 [$00:0000] ;Aと[$00:0001][$00:0000]で論理積 $C0/B859 STA $04 [$00:0004] ;Aを[$00:0005][$00:0004]に書き込み $C0/B85B STA $08 [$00:0008] ;Aを[$00:0009][$00:0008]に書き込み
まず$C0/B83Eで$01をロードし、[$00:4212]と論理積を取って、$C0/B843でゼロフラグ判定をし、ゼロフラグが立っていないなら$C0/B840にジャンプする。
つまり、ゼロフラグが立つまで、$C0/B840と$C0/B843をループすることになる。
$C0/B83Eで$01= %0000 0001 をロードしたから、$01と[$00:4212]の論理積でゼロフラグが立つのは、[$00:4212]の下1ビットが0の時。
先に説明したとおり、[$00:4212]の下1ビットは、自動ジョイパッド読み取り機能がONかOFFかの状態を示す。下1ビットが1ならON、0ならOFF。
ボタン判定ループ処理を抜けるのは、自動ジョイパッド読み取り機能がOFFになったタイミングになる。
自動ジョイパッド読み取り機能がONの間は[$00:4219][$00:4218]にボタンの状態を出力し続けるので、ループを抜けた$C0/B847でロードする[$00:4219][$00:4218]は、自動ジョイパッド読み取り機能がOFFになる直前のボタンの状態である。
$C0/B84A~では、[$00:4219][$00:4218]と$000Fで論理積を取ってゼロフラグ判定をしている。
ボタンの状況は、[$00:4219][$00:4218]の16進数4桁の値の中で、上3桁で表されるため、[$00:4219][$00:4218]と$000Fで論理積を取ると上3桁の値がすべて0となり、通常は$0000となってゼロフラグが立つはずである(おそらく)。
よって$C0/B84Dのゼロフラグ判定が立たないことは多分ない。次の$C0/B852へジャンプする。
ゼロフラグが立っている場合はAに$0000をロードして進む。
フィールドでは、[$00:4219][$00:4218]の値が[$00:0001][$00:0000]と同一なのだが、ここから[$00:0001][$00:0000]へのコピーが開始になっている。
Aに入っている[$00:4219][$00:4218]をXレジスタにコピーする。
このXは$C0/B855で[$00:0001][$00:0000]に書き込まれるので、[$00:4219][$00:4218]→Xレジスタ→[$00:0001][$00:0000]である。
これで入力されたボタンがほぼリアルタイムに[$00:0001][$00:0000]に反映されることになる。
$C0/B853~の処理は、ひとつ前のボタンの状況から、ボタンを押しっぱなしか、それとも新たに更新されたか、という判定用の計算である。
$C0/B853は、[$00:4219][$00:4218]と[$00:0001][$00:0000]の排他的論理和の計算になる。
排他的論理和は、2進数で各桁を比較した時、どちらかが1なら1を、それ以外は0を返す論理演算である。
この時点の[$00:0001][$00:0000]は、ひとつ前のボタンの状況が入っている。
たとえば、直前まで右ボタンを押していたら[$00:0001][$00:0000] = $0100 = %0000 0001 0000 0000である。
今回の判定では右ボタンを押すのを止めていれば、[$00:4219][$00:4218] = $0000 = %0000 0000 0000 0000である。
排他的論理和を取ると右ボタンの1だけ残り、%0000 0001 0000 0000 = $0100である。
一方、右ボタンを押しっぱなしだったとしたら、右ボタンの1と1で排他的論理和は0となり、%0000 0000 0000 0000 = $0000である。
要するに、直前までのボタンの状況と変化がない場合は排他的論理和が$0000、変化がある場合はそれ以外の値になる。
$C0/B857は、この排他的論理和の結果と、[$00:0001][$00:0000](現在のボタンの状況)の論理積をとって、[$00:0005][$00:0004]及び、[$00:0009][$00:0008]に書き込む。
直前までのボタンの状況と変化がない場合、$0000と[$00:0001][$00:0000](現在のボタンの状況)の論理積になるから、必ず$0000である。
それ以外なら新たに変化があったボタンの状態が[$00:0005][$00:0004]及び、[$00:0009][$00:0008]に入る。
ここまででとりあえず押したボタンの値の読み取りと保存は完了となる。
以降はどのボタンを押したか、またはボタンを離したか、という判定になる……と思いきや、実は次に以下のような処理がある。
$C0/B85D LDA $421A [$00:421A] ;Aに[$00:421B][$00:421A]をロード $C0/B860 BIT #$000F ;Aと$000Fで論理積(ステータスフラグ変更のみ) $C0/B863 BEQ $03 [$B868] ;ゼロフラグが立っているとき[$B868]分岐 ;ゼロフラグOFF $C0/B865 LDA #$0000 ;Aに$0000をロード ;ゼロフラグON $C0/B868 TAX ;Aの値をXレジスタに転送 $C0/B869 EOR $02 [$00:0002] ;Aと[$00:0003][$00:0002]で排他的論理和XOR $C0/B86B STX $02 [$00:0002] ;Xを[$00:0003][$00:0002]に書き込み $C0/B86D AND $02 [$00:0002] ;Aと[$00:0003][$00:0002]で論理積 $C0/B86F STA $06 [$00:0006] ;Aを[$00:0007][$00:0006]に書き込み $C0/B871 STA $0A [$00:000A] ;Aを[$00:000B][$00:000A]に書き込み
最初にも書いたが、コントローラ2の状態は$00:421A~$00:421Bの2バイトに入る。
上の通り、実はコントローラ2のボタンの状態を、コントローラ1のボタンの状況とほぼ同じ判定で各アドレスに書き込んでいるのだ。
つまり、[$00:0003][$00:0002]はコントローラ2のボタンの状態が常に反映されている。
といっても、本作でコントローラ2を使う場面はない。
[$00:0003][$00:0002]を何かの処理に使うかどうかも筆者にはわからない。
開発中はコントローラ2を何かに使う予定があったのか、それともスーパーファミコンのゲームの共通処理という意味で形式的に入れておいたのか、そこまではわからない。
(基本的に1人用のRPGでコントローラ2を使う作品はさほどないが、「ライブ・ア・ライブ」と同時期のスクウェアのゲームだと、「聖剣伝説2」や「ファイナルファンタジー4」で、戦闘時仲間キャラをコントローラ2で操作できるという仕組みがあった)
なお、コントローラ2の判定は、戦闘やメニュー画面のボタン判定用サブルーチンにも残されている。
[$00:0001]→[$00:020A]のコピーは上処理の直後に行われている。
$C0/0926 LDA $01 [$00:0001] ;Aに[$00:0001]をロード $C0/0928 STA $020A [$00:020A] ;Aを[$00:020A]に書き込み
戦闘中のボタン判定用サブルーチンは以下の通り。
戦闘開始時、$C1:0000~から処理が開始になるのだが、その中に以下の処理がある。
$C1/006E SEI ;インタラプトフラグON 割り込み不許可 $C1/006F LDA #$8F ;Aに$8Fをロード $C1/0071 STA $2100 [$00:2100] ;Aを[$00:2100]に書き込み $C1/0074 LDA #$01 ;Aに$01をロード $C1/0076 STA $4200 [$00:4200] ;Aを[$00:4200]に書き込み $C1/0079 JSR $F4A9 [$C1:F4A9] ;[$C1:F4A9]へジャンプ
戦闘開始時は、ここで[$00:4200]に$01がロードされて、自動ジョイパッド読み取り機能がONになる。
[$00:2100]はディスプレイ制御レジスタで、$8F = %1000 1111を書き込んでいるが、下4ビットが明るさ制御。
ただし一番上のビットに1を書き込むとForced blankフラグがONとなり画面が真っ暗になる仕様である。つまり戦闘突入時の暗転である。
$01を書き込むのでNMI割り込みは入らない。
$C1/0136 LDA $92 [$00:0392] ;Aに[$00:0392]をロード $C1/0138 STA $2100 [$00:2100] ;Aを[$00:2100]に書き込み $C1/013B LDA #$81 ;Aに$81をロード $C1/013D STA $4200 [$00:4200] ;Aを[$00:4200]に書き込み $C1/0140 JSR $0327 [$C1:0327] ;[$C1:0327]へジャンプ
$C1/835E LDA #$0F ;Aに$0Fをロード $C1/8360 STA $2100 [$00:2100] ;Aを[$00:2100]に書き込み $C1/8363 LDA #$81 ;Aに$81をロード $C1/8365 STA $4200 [$00:4200] ;Aを[$00:4200]に書き込み $C1/8368 JSR $6121 [$C1:6121] ;[$C1:6121]へジャンプ
上は戦闘中に[$00:4200]に$81を書き込む場合の処理。
;ボタン判定ループ処理 $C1/8AD8 LDA $4212 [$00:4212] ;Aに[$00:4212]をロード $C1/8ADB AND #$01 ;Aと$01で論理積 $C1/8ADD BNE $F9 [$8AD8] ;ゼロフラグが立っていないとき[$8AD8]分岐 ;ボタン判定ループ処理ここまで $C1/8ADF LDX #$0000 ;Xに$0000をロード $C1/8AE2 LDA $4218 [$00:4218] ;Aに[$00:4218]をロード $C1/8AE5 BIT #$0F ;Aと$0Fで論理積(ステータスフラグ変更のみ) $C1/8AE7 BNE $03 [$8AEC] ;ゼロフラグが立っていないとき[$8AEC]分岐 $C1/8AE9 LDX $4218 [$00:4218] ;Xに[$00:4219][$00:4218]をロード $C1/8AEC STX $44 [$00:0344] ;Xを[$00:0345][$00:0344]に書き込み $C1/8AEE LDX #$0000 ;Xに$0000をロード $C1/8AF1 LDA $421A [$00:421A] ;Aに[$00:421B][$00:421A]をロード $C1/8AF4 BIT #$0F ;Aと$0Fで論理積(ステータスフラグ変更のみ) $C1/8AF6 BNE $03 [$8AFB] ;ゼロフラグが立っていないとき[$8AFB]分岐 $C1/8AF8 LDX $421A [$00:421A] ;Xに[$00:421B][$00:421A]をロード $C1/8AFB STX $46 [$00:0346] ;Xを[$00:0347][$00:0346]に書き込み $C1/8AFD RTS ;サブルーチン戻り (中略) $C1/8B15 LDX $44 [$00:0344] ;Xに[$00:0344]をロード $C1/8B17 STX $48 [$00:0348] ;Xを[$00:0348]に書き込み $C1/8B19 LDX $46 [$00:0346] ;Xに[$00:0346]をロード $C1/8B1B STX $4A [$00:034A] ;Xを[$00:034A]に書き込み $C1/8B1D RTS ;サブルーチン戻り
$C1/8AD8~$C1/8ADDのループで、[$00:4212]の下1ビットが0になるまで(自動ジョイパッド読み取り機能がOFFになるまで)ループを行う。
後の判定の方法はフィールドとだいたい同じで、[$00:4218]のみで$0Fと論理積を取ってゼロフラグ判定してから、現在のボタンの状況[$00:4219][$00:4218]を[$00:0345][$00:0344]に書き込む。
[$00:0345][$00:0344]は更に、$C1/8B15~で[$00:0349][$00:0348]にもコピーされる。
なお$C1/8AF1~$C1/8AFBはコントローラ2の処理である。
メニュー画面でのボタン判定用サブルーチンは以下の通り。
$C2/4FE8 LDA $79 [$00:0579] ;Aに[$00:0579]をロード $C2/4FEA STA $4200 [$00:4200] ;Aを[$00:4200]に書き込み $C2/4FED STZ $76 [$00:0576] ;[$00:0576]に$00を書き込み $C2/4FEF JSR $5178 [$C2:5178] ;[$C2:5178]へジャンプ $C2/5178 PHP ;ステータスレジスタをスタックへプッシュ $C2/5179 SEP #$20 ;MフラグON Aレジスタは8bit幅 ;ボタン判定ループ処理 $C2/517B LDA #$01 ;Aに$01をロード $C2/517D AND $004212[$00:4212] ;Aと[$00:4212]で論理積 $C2/5181 BNE $F8 [$517B] ;ゼロフラグが立っていないとき[$517B]分岐 ;ボタン判定ループ処理ここまで $C2/5183 REP #$20 ;Aを16bit幅に変更、Mフラグをクリア $C2/5185 LDA $004218[$00:4218] ;Aに[$00:4219][$00:4218]をロード $C2/5189 STA $7D [$00:057D] ;Aを[$00:057E][$00:057D]に書き込み
判定方法はフィールドや戦闘時と同様である。
[$00:4200]に[$00:0579]を書き込むことで自動ジョイパッド読み取り機能をONにしているが、[$00:0579]は$81か$01である(筆者が確認した限りでは)。NMI割り込みが入るかどうかで[$00:0579]の値を書き換えているようだ。
[$00:4219][$00:4218]は[$00:057E][$00:057D]に書き込まれる。
ただし、メニュー画面の方ではコントローラ2判定はないようだ。