最近、趣味でファミコンエミュレータをGo言語で実装しています。
世の中にはたくさんのファミコンエミュレータ実装があり、golangだけでもいくつもあるため何で同じ言語で実装するのかと言われると、楽しそうだからとしか言いようがありませんが、趣味の話なので気にしないようにしましょう :)
私は下記のPHP実装のファミコンエミュレータを読んで、PHPなら読める・・読めるぞ!と思って写経しています。せっかくなので勉強し始めたgolangで実装をしています。
ここ1ヶ月ぐらい、毎朝20分ほどファミコンの仕様を読みつつPHPのコードを読みつつgolangに移植しているのですが、まだHello Worldが出力できていませんw
そんな時間のかかるHello Worldですが、そこにたどり着くまでにファミコンのROMデータのロード、CPU命令の実装、PPU命令の実装までをやる必要があります。気の遠くなる話ですね・・だが楽しい! プラモデルを毎日コツコツ作っている感覚です。
今はPHP実装をgolangに移植してるのですが、PHPの場合は8bit intでも16bit intでもすべてint型になっています。そのため細かい型のところや、書いている内容がわからない場合は他の言語実装も読みます。一番読んでるのはRust実装のこれです。
Rustの文法は知らないし、コードも読んだことなかったのですが、問題なく読めました。ファミコンエミュレータに使われるコードはビットの演算やデータの管理(クラス・構造体)、バイト列の操作、条件分岐がメインになるため基本的な言語文法のみが使われているためです。
ちなみに、ファミコンは海外ではNESと呼ばれていますので、検索する場合はNES Emulator というキーワードを組み合わせると便利です。
golangで書いてても使っているのは、構造体、レシーバ、ビット演算、条件分岐、byte操作ぐらいです。ですので、新しいプログラミング言語を覚えるのにファミコンエミュレータを実装するのは良い練習になります。
CPUやメモリのこと、アセンブラのこと、写経しながらこれらも学んでいけますので、ハードに近い場所での操作がどうなっているか体験できるのは面白いですね。いままでアセンブラとか避けてきていたので・・
Hello Worldを出力するまでは、まずはこの記事を読むべしという感じです。
私はもう何回も読んで、毎回、なるほどわからん!って感じを繰り返してます。 今はプリンタで印刷してカバンにいれて暇な時に読んでます。
それでもわからないまま写経しながら実装してると、だんだんとわからん!の範囲が小さくなっていきます。この感覚は楽しいですね。
1ヶ月以上も実装しつつ、わからないことが多いですが、最近このように分からないものに長い時間をかけて挑戦することがしたくて、ファミコンエミュレータは良い題材となってます。