ファミコンエミュレータをつくろう(1)※まだ書きかけ

はじめに

令和の今、ファミコンエミュレータをつくろう、などと言うと、おいおいファミコン世代がとうとうご乱心かと世間では嘲笑されるに違いない。
しかしエミュレータを書くというのは今でもコンピュータを理解する意味で一定の意味を持つであろう。
例え単純であっても一つくらい自分で作り上げた経験があって損はないはずだ。
その点、ファミコンはちょうどいいのである。
難易度も、規模も、達成時のちょっと自慢できる感じも、全部ちょうどいい。
そしてなにより夏休みの自由研究あたりにちょうどいい。(嘘です)
ファミコンエミュレータをつくろう。
なんだかそう思えてきただろお?


あらすじ

初回の今回はまずファミコンがどういうものかざっと確認してエミュレータのイメージをつかむところまで見ていこうと思う。
エミュレータの書き方を早く知りたい人には退屈な内容ではあるが、当の私が色々と思い出すために必要なステップなので我慢されたし。

ファミコンを開けてみる

さて、小難しい話はさておき、まずはファミコンの中身を見てみることにしよう。
こちらにおわします我が愛機をとくとご覧あれ。
(しばらく無駄に写真が並びます)

我が愛機。一度レトロブライトしているのでわりかし奇麗なのではないか


裏側。消費電力4Wというのは今思えば何かの冗談かと思う数値だ


テレビが死にかけているのでボケボケだが一応こいつ動くぞ


開けてみたところ


基板の表側はこんな感じ

上側の赤枠部分がNTSC信号を生成しているRF基板で、下側の黄枠部分がファミコンのメイン基板である。

RF基板

RF基板はファミコンの映像と音声をテレビ信号であるNTSC信号に成形している部分である。(今ググってみたら実はなんちゃってNTSCであって厳密にはNTSCとは違うらしい。ちなみにRFは高周波の略だそうだ)
テレビ信号と聞いて、ん?と思ったかもしれない。少なくとも私は最初そうだった。
ゲーム機はゲーム機でなんかそれ専用のやつがあるんだろうなあと漠然と思っていたのだがそうではないのである。
雑に言い切ってしまえばファミコンは一種のテレビ番組を放送しているわけである。
これをテレビのアンテナ口に繋ぐとテレビはなんか知らんけど番組放送しとるなーとファミコン放送を受信するという仕掛けだ。
当然ながらこちらの操作にリアルタイム追従して生放送される。なんというクールな仕掛けか。
子供のころはテレビゲームと言えばRF接続が当たり前で気にもしなかったが大人になって改めて考えてみるとなかなか豪快なやり方だなと感心する。
ちなみに放送チャンネルは由緒正しい1CHか2CH(選択可)で、某公共放送と誤認して受信させる仕様である。
ファミコンとやらは教育上大変よろしいと国のお墨付きをいただいたからに違いないと私はふんでいるが、信じるか信じないかはあなた次第。
RF基板についてはエミュレートとは直接関係がないのでひとまずというかこのあとは永遠に忘れてしまおう。

ファミコンメイン基板

メイン基板だけ改めて眺めてみる。

基板の名前に「HVC-CPU-07」とある。
ググってみるとどうやらメジャーな基板のようだ。
見てのとおり部品がすごく少ない。
たったこれだけでよく動くものだとしばし感慨に耽ったところで、さて、もうちょっと詳しく見てみよう。

①CPU+APU

基板上に「U6 CPU 2A03」と刻印があることからも分かるように、「RP2A03G」と刻印されたこのICがファミコンの心臓部となるCPUである。
リコー製のカスタムICなのだが、CPUというかゲーム機向けの(今でいうところの)SoCのおもちゃみたいなものであり、CPUとAPU(Audio Processing Unit:ファミコンのサウンド機能)が合体したICになっている。
CPUの中身自体は6502という既存CPUをちょちょいと弄ったもので2A03というタイプのCPUがあるわけではない。
つまり今後我々は6502というCPUを理解する必要がある。

②RAM

CPUから上部へとなにやら線が伸びた先に「U1 S-RAM(2K×8)」(IC刻印「LH5116D-12」)と書かれているものが見える。
これがファミコンのRAM、つまりメモリである。
2K×8というのは2K*8(bit)の意味で要するに2KB(Byte)。
繰り返すが、2KBである。
そんな少ないはずないと思ったでしょ?俺も最初そう思ったよね。
でもそれ以外になんも載ってないんだから受け入れるしかしょうがない。

③PPU

CPUの上にある「U5 PPU2C02」(IC刻印「RP2C02G-0」)と書かれた大きめのICがPPU(Picture Processing Unit)と呼ばれるICで、これがファミコンの画面の全てを統べるものである。
CPUと情報の連携はもちろんするのだけども、PPUはCPUとは独立して動いていて、PPU管轄下にある画面構成用のデータを随時参照しながら画面の上から下まで延々と(CPUなんぞ無視して)生成しづづけている。
なのでCPUとPPUとの情報のやり取りを画面更新中などの変なタイミングでやってしまうと、画面も変な感じになってしまうので注意が必要である。
例えがあっているかはさておくが、自分の中では、大縄跳びをぐるぐる回しているのがPPUで、そこに飛び込もうとしているのがCPUという感じでイメージしている。飛び込むタイミングを失敗すると痛い目にあう。
なお、通常は画面が変にならないようにちゃんとするわけだが(そのためにVBLANK割り込みという仕掛けがある)、意図的に変にさせることでラスタスクロールさせるという使い方もある。
言っておくがこいつは強敵である。
昔のコンピュータは少ないコンピュータ資源で最大の成果を上げるために様々な工夫を凝らしているが、凝らしすぎにも程があり、何回見直しても頭が混乱する。
覚悟されたし。

④VRAM

PPUの上には「U4 S-RAM(2K×8)」(IC刻印「LH5116D-12」)が見つかる。
これはPPU用のRAMで通称VRAM(Video RAM)と呼ばれる。
ここに画面構成用のデータを転送しておくとPPUはそれを見ながら勝手に画面を作ってくれるという流れである。
もちろんこれも2KBである。
他にメモリは見当たらない。
つまりファミコンにはRAMとVRAMで合計4KBのメモリしかない。
正気ですか。

⑤カートリッジ

ここにカートリッジを差し込むよ。
気取ってないでカセットと言えとお叱りを受けそうだが、なんかエミュレータ界隈ではカートリッジと呼ぶのがデファクトみたいなので僕もそれにあやかります。

カートリッジにはプログラム(PRG-ROM)とキャラクタデータ(CHR-ROM)が書かれている。
重要な点は、CPUのアドレス線がPRG-ROMに、PPUのアドレス線がCHR-ROMに接続されているという点である。写真ではよく見えないが配線を辿るとちゃんとつながっている。
どういうことかと言うとCPUやPPUからすればメモリにアクセスするのもカートリッジにアクセスするのも特に区別がつかないという事だ。
言い換えればカートリッジを指した瞬間にカートリッジのROMはCPUやPPUのメモリの一部になる。
さきほどファミコンは2KB+2KBのメモリしか持たないと言ったがあれは嘘だ。
いや嘘と言うかRAMは確かにそうなのだが、別に書けないメモリだっていいじゃない、プログラムとかキャラだもの。
現代のOSだって山ほど積んでるメモリの相当部分をリードオンリーでしかつかっていなかったりするし、通常書き換えるはずのないものはカートリッジに全部放り込んでしまえばRAMが足りなくてもどうということはないというのはきわめて合理的な判断であろう。
さて、怪我の功名というか、ピンチをチャンスに変えるというか、この仕様を逆手にとってファミコンカートリッジは奇妙な発展を遂げる。
それを実現したのがマッパーと呼ばれる仕組みで、ざっくり言えば昔のコンピュータでよくあったバンク切り替えの事である(何枚ものメモリを隠し持っていて拳銃のリボルバーがくるくる回るみたいにメモリをすいすいと入れ替えるやり方)。
カートリッジにアクセスした後の挙動はカートリッジに丸投げなので、カートリッジに工夫さえこらせばバンク切り替えだろうが何だろうがやりたい放題なのだ。
メモリを何メガビット持とうが(ダイヨウリョウ二メガビット)勝手に一部をRAMにしようが(バッテリーバックアップとか)なんでもござれ。
しかもなぜかカートリッジから本体側に音声信号まで伸びている有様なので、カートリッジに超高性能音源を搭載してパソコン顔負けのサウンドを披露してしまうなんて芸当までやってのける。
案の定、巷には様々なマッパーが溢れかえるのであった。
そして後世でエミュレータ開発者はマッパー地獄に落ちるわよ、と相成るのである。
(※今回はちょっとしか対応しません。地獄には落ちたくないよね)

その他IC

他のICについてはエミュレータ的には特に気にしなくていいというか私もよく知らないのでググった情報をもとに簡単に紹介だけしておこう。

  • 「U2 74HC373」(SN74LS373L)
    PPUのメモリラッチ(読み出すデータを一時記憶しておく)に使われているらしい。詳細はPPUの時に書くけど読み出しが一回空振りするのがこれかな。

  • 「U3 74HC139」(SN74LS139N)
    デマルチプレクサ。アドレス信号を振り分けるのに使うのかな。(RAMかカートリッジか判定して信号出すとか)

  • 「U7 40H368」「U8 40H368」(TC40H368P)
    音声信号のアンプに使ってる?みたいなのだが具体的にどう使ってるかはよく知らない。

これらがどう動いているか

ブロック図とかメモリマップとか

エミュレートするとは

どういうことか

何をどこまでエミュレートするか

全部は無理なので対象を絞る

今後の流れ

昔やった流れを踏襲する予定

次回予告

たぶん王道を無視してPPUから

この記事が気に入ったらサポートをしてみませんか?