FPGAでファミコンエミュレータを動かした話

こんばんは、16のkura(@mochi_pako)です。

これは rogy Advent Calender 2017 の12日目の記事です。

今年の工大祭で、ファミコンエミュレータをFPGA上で動かしたものを展示していました。
そこで、どのようにしてエミュレータを作成していったかについて書こうと思います。
ファミコンのアーキテクチャに関しては色々なサイトで詳しく
解説されているので、ここでは細かくは触れません。

最初に大雑把にFPGAや、ファミコンの仕様について説明し、
次に、実際にどのようにエミュレータを作成していったかについて書こうと思います。

FPGAとは

Verilog HDLやVHDLといったハードウェア記述言語を用いて、
チップ上に任意の論理回路を構成できるものです。
FPGAを使えば自分の好きなCPUを作ることも可能です。

ファミコンについて

主要な部分として、CPU,PPU,APUがあります。
PPUはPicture Processing Unit、APUはAudio Processing Unitの略であり、それぞれ画面描写、サウンド生成に用いられています。
CPUは6502というものが使用されています。

6502 CPUについて

レジスタとして
・アキュムレータ
・インデックスレジスタ × 2
・スタックポインタ
・ステータスレジスタ
・プログラムカウンタ
が使われています。
プログラムカウンタのみ16bitで、それ以外は8bitです。
他に4種類の割り込みや、13種類のアドレッシングモードがあります。
あまり規模は大きくは無いので、初めて作るのに適しているかもしれません。
(他のCPUをHDLで記述したことが無いためわかりません)

実装

「CPUの創りかた」で紹介されている4bit CPUの作成以降、
他のCPUを作ってみたいと思っていたこともあり、
今年の夏休みに入り始めた頃からFPGAを触り始めました。
最初は適当なFPGAの入門書を読みながらLチカ等をやったりして基礎的なことができるようになった後、
どうせだったら後々ファミコンエミュレータにも応用できる6502を選んで作り始めました。

何回か書き直しながら1-2週間ほどですべての命令の実装が終わったと思います。
CPUの命令を1つ1つ実装していくという地味な作業が大半でしたが、
「CPUの創りかた」に載っている程度の事がわかっていればなんとかなりました。
PPUも試行錯誤しながら1-2週間ほどで完成しました。
多少デバッグ作業をした後、HELLO,WORLDや文字の回転などができるようになりました。

ここまでは順調に行きましたが、実際のROM(スーパーマリオブラザーズ)はこの時点では画面真っ暗のままで全く動きませんでした。
後述するデバッグ方法を使ってさらにデバッグ作業を行い、
結局さらに3週間程かかってようやくマリオが一応動くところまで行きました。

その後、PPUまわりのバグも取り除き、夏休みが終わる頃にはほぼ問題なく動くようになっていたと思います。
工大祭後になってしまいましたが、サウンドの方も実装し(まだおかしなところは多いが)、一応完成させました!

デバッグ作業

一番しんどかった…
今回のエミュレータ作成で一番印象的だったのはこの作業です。
あまり良いデバッグ方法がわからなかったため、
Model Simを用いてシミュレーションをしてみて、おかしなところを探すという方法でやりました。
具体的には、スーパーマリオブラザーズのROMを使い、
シミュレーション結果から、レジスタの値が不定値になっているところや意味不明なプログラム番地に行っているところを探す

その前後で実行されている機械語を読み、マリオのアセンブラから、場所を特定する
という作業を繰り返しました。
アセンブラはここで読むことができます。

HELLO,WORLDが動いたこともあり、せいぜい1-2個のバグだろうと予測してましたが結局10個ぐらい修正したような気がします。
バグとしては、ステータスレジスタのフラグの判定の誤りによる無限ループが起こったり、ブランチ命令の際のアドレスの繰り上がりができていなかったことが主な原因でした。

この方法でバグをほとんど取り除き、マリオも問題なく動くようになった頃、nestestというテスト用のROMを発見しました。

これを動かせば、どこの命令がおかしいかを判定してくれます。
もっと早く見つけていれば僕の夏休みが…

最後に

結局デバッグばかりやっていた夏休みになってしまいましたが、
得られたものも大きかったです。特にCPUやその辺りに関する知識が
多く得られたような気がします。
最初の頃に発売されたROMにしか対応していなかったりなど、まだまだ実装していない事が多くありますが、いつか気が向いたら実装しようかなという感じです。
とにかくもう疲れました…

明日のアドベントカレンダーは@manami1433さんの “双葉車の動作原理” です!お楽しみに!

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です