6502 CPUの実装

| No Comments | No TrackBacks

最近までいろいろ調べたりしていたことを全く書いていなかったので備忘録代わりに。

NESというものがある。nintendo entertainment system、ファミコンで使われているOSのことだ。最近であればたいていの環境向けに存在しているFCエミュレータの類は、このNESというものを実装していることになる。FCはハードウェアとしては6502というCPUに独自の音源(audio processing unit, APU)を搭載した2A03というチップを使用している。

ファミコンはゲーム機なので当然ながらROMはゲームのものが多いが、音楽データとしてはNSFという形式のデータが出回っていて、この実体は2A03に対する機械語命令であり、ゲームのROMと何ら変わらない。NSFのプレイヤーは、NESのエミュレータを搭載している(はずだ)。

NSFを演奏できるようになるためには、6502の仮想ハードウェアを作って、そのI/Oポート(実際にはメモリアドレスに対する読み書き)に対応するAPUの仮想ハードウェアを作って、さらにAPUのレジスタ値から音声を合成するシンセサイザを作って、その上でCPU上にNSFをプログラムとしてロードし実行し、かつAPUのシンセサイザも制御しながら、処理系ネイティブで音声を再生するプレイヤーが必要になる。

FC音源の音は率直に言えばゴミなので、そこまでやる意味は自分を含む一般人にはほとんど無い。ノスタルジーで生きていたり、機構に関心があれば、眺める価値があるかもしれない。

さて、今回は無駄にその一部をC#で実装することになってしまったので、そこだけ何とかしようと思っている。実のところゲーム類を実行する気はさらさらないので、音楽ファイルを処理するためにAPUの一部も必要だろうとは思っている。完成させるところまではしない予定だけど。

CPUを実装するためには、計算機工学の基礎的な理解があると有用だろう。CASL/Cometがわかれば十分だと思う。6502のCPU命令に相当するロジックを書けば良い、ということになる。実のところ、6502 CPUの実装は様々な言語で存在しているので、それらを引っ張ってくれば通常は十分だ。

CPUが出来たら、APUを作って繋ぎ込む必要がある。APUへはメモリアドレス4000h-4017hでCPUからアクセスできる。APUのレジスタ側の論理構造を用意するのは簡単だ。一方、APUは実機では独自にループを回して発振器から音声を出力しているので、エミュレータでもこれを実現してやる必要がある。これをやるためには基礎的な音声合成の知識が必要だ。実のところまだ無いので、ある程度分かってきたら書こうと思う。

さて、6502の実装は大抵のプラットフォームではあると書いたけど、MIT/X11レベルで自由に使えるエミュレータは見つからなかった。そこで今回は既存の他言語の実装を探してきて、それをC#に移植することにした。

今回最終的に決めたターゲットはlib6502というCの実装だ。これがどこまでFCに忠実なのかは分からないが、コードは綺麗に1000行ちょっとでまとめられている。中身はマクロの嵐だが、これはコードを最適化してメインループから関数呼び出しを排斥してIRQ/BRK以外でのレジスタコピーを抑えたからだ、と思われる。アカデミックなコードとしての完成度は高そうだ。いずれにせよ、これを1日かけて移植した(選ぶのには時間をかけたけど、着手したら1日でできるレベルだった)。

全くといって良いほど動作を確認していないので、実際に動かし始めたらバグフィクスをはじめることになるのだろうけど、CPUはこれで出来たことにしたので、次は他の部分の話を書こうと思う。

No TrackBacks

TrackBack URL: http://veritas-vos-liberabit.com/noteon/mt-tb.cgi/169

Leave a comment