ファミコンはいいぞ

# ファミコンとは？

ファミコンそれは君が見た光　　

僕が見た希望

正式名称はファミリーコンピュータといいます。  

日本では1983年7月15日に発売された家庭用ゲーム機です。この時代は「ゲーム=ゲームセンターでやるもの」といった感じであったため、それらアーケードゲームが家庭でできるといった感じで革新出来だったわけです。  

まぁ、もちろんファミコンが世界初のゲーム機というわけではなくその下にいくつもの屍があるわけですが...........

# ファミコンのスペック
ファミコンのスペックですが以下のようになります。

- CPU　リコー製 8bit 6502カスタム 1.79MHz
- ROM	PRG-ROM:32KB, CHR-ROM:8KB (マッパー未使用)
- RAM	WRAM:2KB, VRAM:2KB
- 解像度	NTSC:256x240ピクセル60Hz, PAL:256x240ピクセル50Hz
- 最大発色数	52色
- 画面	BG+スプライト同時表示可能
- サウンド	矩形波1, 矩形波2, 三角波, ノイズ, DPCMの5チャンネル
- コントローラ	上, 下, 左, 右, A, B, スタート, セレクト

こんな感じです。CPUで使われている6502カスタムなんか聞いたことないと思いますが、これはApple 2の互換CPUです。それをファミコンのためにカスタムしたものらしいです？　　

ROMが32KBと以上に少ないです。現代のCDの容量なんかと比較すると数秒ですね。（訂正します。数秒もないです。）でも、スーパーマリオブラザーズなんかはこの容量で作られています。すぎょい。　　

最大発色数52色と書いてありますが、一つのゲームで発色できる量は十数個です。それ以上内部のパレットに設定ができないんですね。　　

「これがファミコンなのかー。すげーなー。これでドラクエ３とかもできてるわけだしなー」と思った方。実はドラクエやほとんどのマリオ作品では実は純粋なファミコンの機能だけで成り立ちません。その純粋でない部分とはファミコンカセットに搭載されている機能のことです。これらの機能は「マッパー」などの類で呼ばれています。ファミコンのカセットがあんなにもでかいのはそのせいです。カセットによって中にいろいろ入ってたわけですね。　　

# ファミコンを動かそう

つらつらとファミコンのことを語っていってもいいのですが、それだと書いてる側はともかく読んでる側はとてもつまらないと思うので、ファミコンをぜひ動かしてみてください。　　

といっても持っていない人が大半だと思うのでエミュで動かしましょうおすすめはこちらです。
[ファミコンエミュレータ―　fecux](http://www.fceux.com/web/home.html)
[ウルトラ有名なコンパイラ](https://www.cc65.org/)
[私が作ったアセンブラ](https://github.com/jumdtw/6502assembler)

なんでお前の作ったアセンブラ入れてんだよって感じですが、実はウルトラ有名なコンパイラ(以下cc65とする)がいかんせん初心者に優しくないのです。ファミコンの構成がよくわかってないと使えないという設計になっています。なので、今回の記事を見てとりま動かしてみたいという方には向いていません。そのため、私がつくったやつならば解説もしやすいといった寸法です。　　

そして実際に何を動かすかですが、画像を動かすとなると実は意外と面倒臭いのです。設計上ただvramに書き込めばいいというわけではなくファミコン用の画像をつくって（この時点でかなりだるい）それをioポートを通してCPUとは別の装置を動かす必要があります。　　

なので、今回はファミコンから音を出していきたいと思います。なお、動作確認はwindows10 でしか行っていません。ご容赦ください。

# ファミコンの音～～～～～～～～～

## 環境構築
とりあえず今回は下記の二つを使って説明していきます。
[ファミコンエミュレータ―　fecux](http://www.fceux.com/web/home.html)
[私が作ったアセンブラ](https://github.com/jumdtw/6502assembler)

環境構築といっても fecux はダウンロード画面からmyアセンブラの方はcloneしてmakeしていただければオッケーです。

## 実行
というわけでさっそく鳴らしていきましょう。
各ニーモニック等は下記URLを参考にしてください。
[NES研究室](http://hp.vector.co.jp/authors/VA042397/nes/6502.html)

下記コードがドの音をファミコンから鳴らすコードです。

~~~
lda #%00000001
sta $4015
lda #%10111111
sta $4000
lda #$00
sta $4001
lda #%11010101
sta $4002
lda #$00
sta $4003
~~~

たったこれだけです。
まぁ、i/oメモリにちょっと書くだけなのでこんなもんです。
そんでもってこれを下記コマンドでファミコンエミュ用のバイナリ化します。

~~~
$ asm65 アセンブラファイル 保存先 
~~~

そして生成された .nesファイルをfecuxで起動するとめでたくファミコンを音が鳴ります(結構音量がでかいので注意)。

## コード解説
正直私が説明するより下記URL参考にして自分で読んだ方が早いかもです。
[Memory-Map of NES](http://img.atwikiimg.com/www34.atwiki.jp/cc65/pub/dsoft/mmap.html)

順々に説明していきます。まずこちら。

~~~
lda #%00000001
sta $4015
~~~

これはどの音源を使うのかを宣言しています。ファミコンは複数の音源をもっといるため使う音源と使わない音源をここでフラグ管理している感じですね。ちなみに、今回は短形波ch1を使用しています。　　

次に

~~~
lda #%10111111
sta $4000
lda #$00
sta $4001
~~~

これは短形波ch1の音階以外の設定をしています。各ビットがどの設定なのかは先ほどのURLから見てみてください。そして変更して音の違いを聞いてみてください。

最後に

~~~
lda #%11010101
sta $4002
lda #$00
sta $4003
~~~

ここでは短形波ch1が鳴らす音階を設定しています。
ファミコンにおける音階の周波数の計算式が少し特殊で
レジスタに設定する値 = CPUのクロック周波数 / (再生したい周波数 * 32) - 1
となっています。なんでこうなるのかの内部的構造の説明はだるいのでしませんが、軽い解説が下記URLから読むことができます。
[NES研究室-サウンド](http://hp.vector.co.jp/authors/VA042397/nes/apu.html)

雑な解説で申し訳ないですが、以上でファミコンから音を鳴らす解説を終了します。わからなかったらtwitterのDMなどで聞いてください。( @jumdtw )

# 最後に

ファミコンはいじってみると結構面白いです。
低レイヤが好きな人向けにいくつか利点をあげると
- 外部割込み機能付きCPUの仕組みがわかる
- メモリマップトioの理解が深まる

といったところでしょうか。まぁ、両方ともCPU関連なわけですが......(ファミコン自体でっかいマイコンみたいなものだからしかたないね☆)

割り込みやioのことが学べるのは意外とでかいです。CPUや低レイヤにおける名書と呼ばれるものであっても割り込みのことを解説している書籍はごくわずかで実装方法について解説している書物はさらに少ないです。低レイヤに興味があるかたはファミコンを触ってみることをおすすめします。面白いですよ～。