ファミコンエミュレータ
ソースコードについて
一応コメントはつけてますが、どのファイルが何をしているのかわかりにくいと思うので
ちょっとずつファイルごとの役割を書いていこうと思います。
全てスタティックなクラスとして書いています。
2 個以上のインスタンスを作る必要がないと思ったのと、インスタンスの管理が面倒だったので
全部そのままアクセスしちゃえーという感じで書きました…
プログラムの流れは、
-------------------------------------------------------------------------------------------
・Program.cs の Main() から動作開始
・FormManager が メインフォームをロード
・メインフォームの Load イベントで、CPU と PPU と APU 初期化後、CPU の PowerON() 呼び出し
・PowerON() 中で、CPU 用のスレッド作成
・CPU のクロックが進むごとに、CPU から PPU と APU を呼び出す
- PPU は処理ごとに 1 フレーム分の画像を、オフスクリーンバッファに対して順番に、左上から組み立てて行く
- APU はサウンドレジスタの状態に合わせて、音量を 1 バイトずつメモリ上に組み立てて行く
・CPU 内で 16.6ms 分 (毎秒 60 フレームの内、 1 フレーム分) の処理を終えたら、実時間と合わせるためにウエイトを入れる
・PPU の現在描画中の画面をスクリーンに出力して見えるようにする
・APU のバッファがたまっていたらサウンドバッファに波形を書き込む
・さらに CPU の動作を継続…。CPU 停止フラグが立ったら、CPU のループを抜けてスレッド終了
-------------------------------------------------------------------------------------------
という感じです。
ファイルも少ないので、読んでいける量だと思いますが、
ファミコンの仕様についてはソースの中に書いていないので、ネットでドキュメントを探してみてください。
DirectX は、DirectSound のみ使用しています。
画像描画は、.NET の Graphics クラスを使っています。
速く描画するために若干ややこしいことをしていますが、
検索すると簡単に出てくるテクニックだと思います。
スクリーンのバッファに対して、メモリコピー命令で、色を1ピクセルずつ書き込んでいくような感じです。
バッファのポインタ操作の部分が、C# らしくない書き方になっています。
他のサイトのエミュレータのソースコードを拾うと、中にファミコンの仕様が書かれたファイルが含まれていることがあります。
Nestopia と、FCE Ultra と、nesterJ のソースは拾ったほうが良いと思います。
nesterJ は、若干ややこしいですが、読んでいけそうな感じです。FCE Ultra は すごく難解ですが、
仕様書から実際にどういう風に組み込んだか というのをチェックするには良いと思います。
Nestopia のソースはすごく読みやすいです。
一応コメントはつけてますが、どのファイルが何をしているのかわかりにくいと思うので
ちょっとずつファイルごとの役割を書いていこうと思います。
全てスタティックなクラスとして書いています。
2 個以上のインスタンスを作る必要がないと思ったのと、インスタンスの管理が面倒だったので
全部そのままアクセスしちゃえーという感じで書きました…
プログラムの流れは、
-------------------------------------------------------------------------------------------
・Program.cs の Main() から動作開始
・FormManager が メインフォームをロード
・メインフォームの Load イベントで、CPU と PPU と APU 初期化後、CPU の PowerON() 呼び出し
・PowerON() 中で、CPU 用のスレッド作成
・CPU のクロックが進むごとに、CPU から PPU と APU を呼び出す
- PPU は処理ごとに 1 フレーム分の画像を、オフスクリーンバッファに対して順番に、左上から組み立てて行く
- APU はサウンドレジスタの状態に合わせて、音量を 1 バイトずつメモリ上に組み立てて行く
・CPU 内で 16.6ms 分 (毎秒 60 フレームの内、 1 フレーム分) の処理を終えたら、実時間と合わせるためにウエイトを入れる
・PPU の現在描画中の画面をスクリーンに出力して見えるようにする
・APU のバッファがたまっていたらサウンドバッファに波形を書き込む
・さらに CPU の動作を継続…。CPU 停止フラグが立ったら、CPU のループを抜けてスレッド終了
-------------------------------------------------------------------------------------------
という感じです。
ファイルも少ないので、読んでいける量だと思いますが、
ファミコンの仕様についてはソースの中に書いていないので、ネットでドキュメントを探してみてください。
DirectX は、DirectSound のみ使用しています。
画像描画は、.NET の Graphics クラスを使っています。
速く描画するために若干ややこしいことをしていますが、
検索すると簡単に出てくるテクニックだと思います。
スクリーンのバッファに対して、メモリコピー命令で、色を1ピクセルずつ書き込んでいくような感じです。
バッファのポインタ操作の部分が、C# らしくない書き方になっています。
他のサイトのエミュレータのソースコードを拾うと、中にファミコンの仕様が書かれたファイルが含まれていることがあります。
Nestopia と、FCE Ultra と、nesterJ のソースは拾ったほうが良いと思います。
nesterJ は、若干ややこしいですが、読んでいけそうな感じです。FCE Ultra は すごく難解ですが、
仕様書から実際にどういう風に組み込んだか というのをチェックするには良いと思います。
Nestopia のソースはすごく読みやすいです。
ファイル一覧(フォーム以外)
- Program.cs
- FormManager.cs
- FileTool.cs
- Logger.cs
- NesHeader.cs
- NesStorage.cs
- NesJoystick.cs
- NesCpu.cs
- NesCpu_Operations.cs
- NesPpu.cs
- NesApu.cs
- NesAsm.cs
- NesDisasm.cs
ファイル一覧(フォーム)
- AboutBox.cs
- FormChrTable.cs
- FormDisasm.cs
- FormKeyConfig.cs
- FormMain.cs
- FormMemoryMap.cs
- FormPatcher.cs
- FormRegister.cs
- FormRomInfo.cs
雑談用のスレッドがあるので、そちらに書いてもらえるとうれしいです。