エミュレータを作ってみたいなぁという漠然とした思いがずっとあったので、ファミコンのエミュレータを書いている。スクリーンショットにあるような表示はできる。
ファミコンにした理由
エミュレータは作りたいが、よく知らない機械のエミュレータを作ってもつまらないので、多少は親しんだファミコンにした。
一番印象深いゲーム機はスーパーファミコンだが、スーパーがついてないほうが簡単かな、と思ってファミコンにした。
買ったもの
カートリッジからROMイメージを吸い出すために、吸い出し機をAmazonで購入した。
![GAMEBANK-web.comオリジナル「FCダンパー」 / ファミコン ファミリーコンピュータ Famicom Kazzo DUMPER レトロゲーム 吸い出しツール [0217] GAMEBANK-web.comオリジナル「FCダンパー」 / ファミコン ファミリーコンピュータ Famicom Kazzo DUMPER レトロゲーム 吸い出しツール [0217]](http://ecx.images-amazon.com/images/I/51L8UZk4xEL._SL160_.jpg)
GAMEBANK-web.comオリジナル「FCダンパー」 / ファミコン ファミリーコンピュータ Famicom Kazzo DUMPER レトロゲーム 吸い出しツール [0217]
- 出版社/メーカー: GAMEBANK-web.com
- メディア: エレクトロニクス
- この商品を含むブログを見る
ゲーム自体は大須のレトロゲームを取り扱ってる店に行って買った。1200円くらいした。
進捗の様子
Hello world
NES研究所にあるサンプル。
最初はこれを動かすのを目標にしていた。作ろうと思ってから、これを動かすまで2週間ほどかかっている。
ギコ猫
ギコ猫でもわかるファミコンプログラミングにあるサンプルを一個づつ動かしていった。ギコ猫なつかしい。
スーパーマリオブラザーズ
一番最初にスーパーマリオブラザーズを動かしたときの様子。 空の色がおかしい。
だいたいの背景色が正しくなったが、一部おかしい。
空の表示はできるようになった。
Sprite 0の当り判定(ヒットフラグ)を実装したら、タイトルがでるようになった。
VRAMの読み込みがおかしかったので修正した。
スプライトの表示をちゃんとしたらマリオっぽいのが表示された。 が体がバラバラになっている。
スプライトの反転処理を実装したら、体がくっついた。
スプライトの背景処理をちゃんとした。
他の画面もそこそこ動く。
実装してないこと
実装してない部分を列挙すると以下のようになる。ゲームとして遊ぶのは無理だと思う。
- mapper 0以外のカートリッジの対応
- タイミング制御。普通に画面がチラつく。
- サウンド
つらさ
うまく動作しないときの原因の特定が、本当に大変だった。
エミュレータは任意のプログラムを入力とするので、許容する入力が圧倒的に多い。さらに、その内容は機械語で書かれているので意図を理解するのが難しい。 だいたいは、以下のような手順でデバッグしていた。
- ディスアセンブルしたコードを読んでなんとなくの動きを把握する。
- そして、その通りに動いてるかどうかをメモリを監視しながら確認する。
- 変な動きをしてるところがあったら命令のログもとって重点的に動きを追っていく。
Rubyで書かれたNESエミュレータであるoptcarrotと動きを比較してみることも多かった。
逆アセンブルしたコードを読んでたら、ジャンプ先がアドレスじゅなくて名前の世界、マジ最高、って気分になってきた
— mzp (@mzp) August 14, 2016
現状
さぼっていた部分がだんだんと致命的になってきてウワーとなっている。
- 上から順に1ラインづつ画面を更新していく、
- CPUとPPUのタイミング動機
がっつり直さないといけないけど、どうしようかな…。
レポジトリ
https://github.com/mzp/famicom/
そろそろGo言語を勉強するか、という気分だったのでGo言語で書いている。深い意図はない。