ピロ彦の何か置き場

【TAS】 スーパーマリオワールド "game end glitch" 41秒98 について。

またしてもMasterjun氏によってクレジット呼び出しバグによるクリアTASが制作されたので、解説を少しだけ書こうと思います。足りないところは http://tasvideos.org/4315S.html を読むべし。
※kentora12氏は全く無関係なのでコメントする際には注意しましょう。

・任意コード実行まで

炎で亀を燃やして発生したコインをヨッシーの舌で掴んでいる最中にマリオがそのコインを取ると、舌の上に無を取得し、そこでブルが画面内に現れると舌の上にワープしてそのまま食べてしまいます。
マリオの状態や食べるブルの種類によってストックアイテムに様々な変化をもたらします。
今回利用されたのは、ゴール玉をストックするのに使われたブルとは別の種類のブルです。

sm21390603 で出現したジュゲムの雲ストックについて Masterjun氏 が調査されてた時、"任意コード実行" = ACE(Arbitrary Code Execution) の可能性にたどり着いてしまったようです。
ちび状態でダッシュするブルを食べると、ジュゲムの雲ストックした後にマリオの状態が異常になり、本来は呼び出されることのないルーチンによってプログラムは$014A13へジャンプします。
これらは、あんた氏が以前に予見していたことでもあります。
そのジャンプ先は Open Bus とか SNES Bus とか呼ばれ不安定な部分なのでフリーズ待ったなしですが、なんとか$4218のコントローラレジスタ部へたどり着くことが出来たとのこと。

・任意コード実行

コードは4つのコントローラで5フレームの間実行されています。
これらのコードは65816というCPUのアセンブリ言語で書かれています。
  1. E0 0A FB 64 10 CB 00 00
  2. A9 18 D8 64 10 CB 80 F8
  3. 87 3D 0B 64 10 CB 80 F8
  4. A9 08 AB 64 10 CB 80 F8
  5. 8D C6 13 20 72 80 80 F8
上記の操作によって、$0100(ゲームモード)を 0x18(Load Credits/Cutscene?) にセットし、$13C6(カットシーン)を 0x08(エンディング) にセットした後、ゲームを正常にスタートさせています。

まずは共通して使用されているコードについて解説

 64 10 = STZ: $10
これはアドレス$10のメモリの値に0をセットするという意味になります。
このアドレスは1フレーム間に行われなければいけない処理が完了した時に0がセットされ、
0以外の場合は無限ループする処理が発生するのでそれを回避するために書き換えています。

 CB = WAI
これは1/60毎に発生するNMIという割り込み処理を待つという意味のコードです。
これによって複数フレームのコードを実行できるようにしています。

 80 F8 = BRA: -8
これは無条件分岐命令で、相対アドレスの F8(-8)先へジャンプするという意味です。
これによってコントローラ部の命令を何度も実行できるようにしています。

メモリの書き換え命令

 A9 18 = LDA: #$18
これはCPUのAレジスタに0x18という数値を読み込むという意味です。

 87 3D = STA: [$3D]=$000100
これはアドレス$3Dから3バイトのメモリ値をアドレスとして読み込んで、その先の$000100にAレジスタの値(0x18)を書き込むという意味です。
アドレスを直接指定しようとすると3バイトも使ってしまうので、たまたま 00 01 00 と並んでいた$3Dを利用してコードを2バイトに圧縮してるようです。

 A9 08 = LDA: #$08
同様にAレジスタに0x08を読み込み、

 8D C6 13 = STA: $13C6
$13C6にAレジスタの0x08を書き込んでいます。

その他の命令
 E0 0A = CPX: #$0A <- Xから0x0Aを減算して結果をN・Z・Cフラグへ返す
 0A = ASL <- Aレジスタを左にシフト($4218からじゃなくて$4219かもしれない?)
 FB = XCE <- CフラグとEフラグの値を入れ替え
 D8 = CLD <- Dフラグをクリア(D=0)
 0B = PHD <- DをSに格納
 AB = PLB <- DBをSから取出
 20 72 80 = JMP: $8072 <- バンク内のサブルーチン呼び出し
一連の操作で正常にゲームのメインプログラムへジャンプ出来るように、各種フラグやDB(データバンクレジスタ)を調整してるのだと思います。

多分こんな感じだと思います。