世界を動かす技術を、日本語で。

「Bad Apple」を「スーパーマリオブラザーズ」の中で演奏する

2025年9月29日原文(tasvideos.org)

概要

  • Super Mario Bros. での 任意コード実行(ACE) を活用したTASの解説
  • RAM操作ワールドN 開始など、通常のプレイでは見られない挙動を利用
  • オブジェクトC9Open Bus現象 など、NESの内部動作を巧妙に利用
  • Bizhawk 2.9.1 を改造し、 カートリッジスワップ を再現
  • Bad Apple!!の再生、スコア最大化、最速クリアなど多様な目標達成

Super Mario Bros. TASによる任意コード実行の仕組み

  • 任意コード実行(ACE) とは、ゲーム機の プログラムカウンタ(PC)RAM領域 に誘導し、任意のバイト列を命令として実行させる技術
  • NESの命令は 6502アセンブリ で記述され、各命令が1バイトのオペコードとして格納される仕組み
  • JSRJMP 命令によりPCを任意のアドレスへジャンプ可能
  • RAMの操作PCの誘導 がACE実現の2大要素
  • ACEのために必要な条件
    • PCをRAMにジャンプさせる手段
    • RAMを任意に書き換える手段
    • 6502アセンブリの知識
    • 明確な実行目標

SMBにおける任意コード実行の実現方法

  • TASは ワールドN から開始
    • 通常プレイでは到達不可能な23番目のワールド
    • RAMアドレス$7FD を0x16に書き換え、Aボタンを押しながらスタートで到達
  • 本来は Super Mario Bros. 3 でRAMをセットアップし、カートリッジをSMBに交換する流れを再現
  • Bizhawk 2.9.1 を改造し、 カートリッジスワップ機能 を実装
  • この手法を「 Tomfoolery」と呼称し、TASの目的の一つを達成

ワールドN開始による副次的効果

  • ワールドNでは Bowser撃破時 の処理が異常動作
  • Bowserの正体を決定する ルックアップテーブル が範囲外アクセスし、 ID 0xC9 のオブジェクトが出現
  • ジャンプテーブル も範囲外を参照し、 アドレス$D007 にジャンプ
  • さらに処理が進むと、 状態遷移値 が4となり、 ジャンプ先$53AE は未割当アドレス
  • Open Bus現象 が発生し、データバス上の値(ここでは0x53)が命令として解釈される

Open Bus現象とコントローラ入力の活用

  • Open Bus では、バス上の値が命令として実行されるため、 コントローラ入力RAM値 を介して次の挙動を制御可能
  • 例えば、Aボタンのみ押下で アドレス$000A が0x80となり、以降の命令フローへ影響
  • この仕組みを利用し、 任意の6502コード をRAM上に配置して実行

TASの目標と工夫

  • 任意コード実行 による「Bad Apple!!」ミュージックビデオの再生
  • 最大スコア獲得4:53クリア など、複数の目標を同時達成
  • グラフィック最適化音声パケット化 など、NESの制約下での表現力向上
  • ASMコード によるパケット読み込み・描画・音声再生の工夫
  • エミュレータ特有の問題 (Open Busの再現性など)を回避し、 実機同期 を実現

技術的詳細と工夫点

  • グラフィック変換 :ビデオフレームをNESタイルに変換し、最適化レンダリングを実施
  • 音声再生 :コントローラ入力を音声データに変換し、DPCMや複数案で音質向上を追求
  • パケット化 :データを効率的にパケット化し、ASMで逐次処理
  • アドレス$2002 やコントローラ読み取りルーチンなど、NES特有のハードウェア挙動も活用
  • エミュレータ遅延問題 :なぜエミュレータ上で遅くなるかの分析

まとめ・特記事項

  • TAS作成手法RAM操作エミュレータ改造 など高度な技術の結集
  • Alyosha氏 による実機検証、コミュニティ協力への感謝
  • ASMコード や統計情報、TAS作成時の裏話も公開

参考・謝辞

  • ASMコード全文
  • 実行統計
  • 協力者への謝辞

(この内容は、元英文の技術解説を日本語に要約・再構成したものです。各項目は体言止めで簡潔にまとめています。ご要望に応じて、個別の技術詳細や特定セクションの深掘りも可能です。)

Hackerたちの意見

超クールだね。ペイロードの大きさってどこかに書いてある?ボタンの押し回数は?音声サンプルは「ストリーミング」なの、それとも全部NESのRAMに収まるの?

詳しい説明があるよ。音声はボタンの押しに合わせてストリーミングされてる。

TASファイル全体で約16MBかかるんだ。NESのRAMは4KBしかないのにね。音声と映像の再生中は、TASがコントローラーを通じて、1フレームあたり約500回入力してストリーミングしてる(15kHzで)。

こんにちは、これをまとめたTASerだよ。入力は580万回あったんだ。tasvideosの説明に全てのアセンブリコードを共有してるよ: https://tasvideos.org/8991S#HereSTheAsmCode 説明に書いたことをまとめると、7ビットPCM音声は約25kHzでストリーミングされてて(コントローラーから読み取って、アドレス$4011に71CPUサイクルごとに書き込んでる)、グラフィックデータをストリーミングする時は時々9kHzに落ちることもあったよ。

これって、改造したコントローラーを使って実機でもできるの?

https://www.youtube.com/watch?v=OJXxmD_Qk2o メモリの状態を設定するために改造したROMを使ってるけど、SMB3を手動でやってもできるみたいだよ。

https://www.youtube.com/watch?v=OJXxmD_Qk2o これはコンソールで動かしてる動画だけど、どうやって入力したのかはよくわからないな。

256個のセルをチェックした後、差が最も小さいセルが選ばれるんだ。これは基本的にベクトル量子化コーデックの基本的な操作で、初期のロスのある動画圧縮で人気があった理由は処理が軽いからなんだ。この用語が記事に出てこないってことは、著者が独自にこの理論を発見して再発明したってことだから、かなりすごいよね。

そういうことは直感でわかるし、オンラインで学術記事を探すよりもこっちの方が生産的だよ。

音声はただ重ねてあるだけだと思ってたけど、コントローラーを通じてストリーミングされてたんだ。めっちゃ素晴らしい音だよ、コンソールでも信じられないくらい!

同じく!「ああ、音が重なってるのか」と思ったけど、実際はそうじゃなかった。すごいね。

すごい!!!これでドゥーム動かせるかな?

Hacker Newsで議論の続きを見る