NES Music Format 仕様書 ----------------------- By: Kevin Horton khorton@iquest.net ノート: ------- 私はこの仕様書を更新していきたいと思っています。 もし、新しい音源チップやその他の変更を見つけたら私に知らせてください。 メールは上記アドレスへ。 V1.61 - 06/27/2000 ビットの仕様を更新。 V1.60 - 06/01/2000 Sunsoft、MMC5、Namcoのチップ情報を更新。 V1.50 - 05/28/2000 FDSを更新。SunsoftとNamcoのチップを追加。 V1.32 - 11/27/1999 MMC5のレジスタアドレスを追加。 V1.30 - 11/14/1999 MMC5のオーディオビットを追加。いくつかのレジスタ情報を追加。 V1.20 - 09/12/1999 VRCとFDSの情報を追加。 V1.00 - 05/11/1999 公式NSF仕様ファイル初版。 このファイルではNESの音楽データを小さく、簡単に扱えるフォーマットにすることができ ます。 基本的な考え方として、NESゲームから吸い出した音楽/効果音の再生コードとデータをまと め、データへのヘッダを先頭に付けます。 6502で動作する音源エミュレータはデータを取り出し、適切なアドレスへ読み込み、初期化 をした後に再生を行います。 ヘッダの構成: オフセット バイト数 内容 --------------------------- 0000 5 STRING "NESM",01Ah ; NESサウンドフォーマットファイルを示します。 0005 1 BYTE バージョン番号 (現在 01h) 0006 1 BYTE 曲数 (1 = 1曲、2 = 2曲...) 0007 1 BYTE 開始曲 (1 = 最初の曲、2 = 次の曲...) 0008 2 WORD (LO/HI) 読み込むデータのアドレス (8000-FFFF) 000A 2 WORD (LO/HI) 初期化するデータのアドレス (8000-FFFF) 000C 2 WORD (LO/HI) 再生するデータのアドレス (8000-FFFF) 000E 32 STRING 曲名(NULL終端) 002E 32 STRING 作曲者(NULL終端) 004E 32 STRING 著作権所有者(NULL終端) 006E 2 WORD (LO/HI) 1/1000000秒単位の速さ NTSC (テキスト参照) 0070 8 BYTE バンクスイッチ初期化値 (テキスト及びFDSの項を参照) 0078 2 WORD (LO/HI) 1/1000000秒単位の速さ PAL (テキスト参照) 007A 1 BYTE PAL/NTSC ビット: bit 0: クリアされていれば NTSC bit 0: セットされていれば PAL bit 1: セットされていれば PAL/NTSC両方 bits 2-7: 未使用。必ず 0 にすること。 007B 1 BYTE 拡張音源チップサポート bit 0: セットされていれば VRC6 が使用されています。 bit 1: セットされていれば VRC7 が使用されています。 bit 2: セットされていれば FDS音源が使用されています。 bit 3: セットされていれば MMC5 audio が使用されています。 bit 4: セットされていれば Namco 106 が使用されています。 bit 5: セットされていれば Sunsoft FME-07 が使用されています。 bits 6,7: 今後の拡張用。必ず 0 にすること。 007C 4 ---- 4 今後の拡張用。必ず 0 にすること。 0080 nnn ---- 再生プログラムとデータが続きます。 これには見覚えを感じる人がいるかもしれません。もしそうなら、コモドール64音源の為の PSIDファイルフォーマットを少し参考にしているからでしょう。 RAMへの曲の読み込み ------------------- オフセットアドレス0070h〜0077hが0だったら、バンクスイッチは使用しません。 いずれかが0以外であれば使用します。 バンクスイッチが使用されるなら読み込むデータのアドレスは使用されますが 最初のバンクを読み込む為に(アドレス & 0FFFh)したものを使います。 各バンクのサイズは4KByteです。それは、6502のアドレス空間全体の8000h〜FFFFhの範囲 に8つあるということになります。ファイルの70h〜77hの設定データがメモリ上のどこに あるか決定します。これらはバンクの初期化値として使われ、メモリ空間へ読み込まれます。 例: METROID.NSFを使って説明します。 ファイルのセットアップ: (70hから) 0070: 05 05 05 05 05 05 05 05 - 00 00 00 00 00 00 00 00 0080: ... ここから音楽データ... 0070h〜0077hが0以外になっています。ですので、バンクスイッチを使って演奏するという ことになります。データ用の読み込みアドレスは8000hに指定されます。これに0FFFhをAND した値は0000hなのでバンク0の0バイトを読み込むことになり、音楽データまでを連続して 読み込みます。 メトロイドは4KByteのバンクを6つ持っています。番号は0〜5番です。 6502のアドレス空間は4KByteのバンク切り替え用のブロックが8つあります。8000h〜8FFFhで 始まり、9000h〜9FFFh、A000h〜AFFFh...F000〜FFFFhとなります。これらのサイズは4KByte ずつです。カレントバンクは5FF8h〜5FFFhに書かれて操作されます。1バンクに1バイトです。 ですので、5FF8hは8000h〜8FFFhの範囲を操作し、5FF9hは9000h〜9FFFhと続き、F000h〜FFFFh の範囲を操作する5FFFhまで上がっていきます。曲がRAMに読み込まれる時、6502のアドレス空間 ではなくバンクへ読み込まれます。これは一度だけ行われ、バンクコントロールレジスタは設定 のために初期値を書き込みます。 このため、ファイルの0070hの値は5FF8hに、0071hは5FF9hに書かれます。以下0077hが5FFFhに 書かれるまで続きます。 これは、初期化処理が呼ばれる前にされることになります。 もしバンク切り替え時に調整されなかった場合は、ファイル終端までが決められたアドレスとし て読み込まれます。 曲の初期化 ------------------ これはかなり単純です。曲をアキュムレーターに読み込み、-1してXレジスタをPALなら1、NTSCな ら0に指定してください。 これがPALかNTSCのどちらか(両方ではない)の場合、Xレジスタの値は使われません。 曲の読み込みとPAL/NTSCの指定が行われると、初期化アドレスが呼ばれます。 初期化が終わるとRTSが実行されます。 曲の再生 -------- 曲の初期化が終わると再生できます。 再生するには、毎秒再生するアドレスを呼ぶだけです。 曲が何秒あるかは、ファイルのオフセットアドレス006Ehと006Fhでわかります。 これらは100万分の1秒で再生速度を示しています。 通常の再生レート60Hzにするには、411Ahに設定します。 その他の再生レートにするには、次の式を使います: 1000000 再生レート = --------- 速 度 ファイルの006Ehと006Fhに設定した値が再生レートとなります。速度はヘルツで指定してください。 曲を読み込むための適切な方法 ---------------------------- 1) バンクスイッチを使用するなら手順3へ。 2) 指定されたアドレスから6502のアドレス空間にデータをロードします。手順4へ。 3) RAMエリアへデータをロードして開始します(開始アドレスに0FFFhをANDします)。 4) 曲の読み込み完了です。 演奏の初期化のための適切な方法 ------------------------------ 1) RAMの0000h〜07FFhをクリアします。 2) RAMの6000h〜7FFFhをクリアします。 3) サウンドレジスタの4000h〜400Fhへ00hを、4010hへ10hを、4011h〜4013hへ00hを書き込んで初期化します。 4) ボリュームレジスタの4015hを0Fhにします。 5) バンク切り替えする曲であれば、ヘッダの5FF8h〜5FFFhをバンクボリュームとしてロードします。 6) アキュムレータとXレジスタを曲のために設定します。 7) 曲の初期化処理を呼び出します。 再生のための適切な方法 ---------------------- 1) 曲の再生アドレスを呼ぶことで再生速度が決定されます。 どのデータが使われるかはPALかNTSCのモードによって決まります。 サウンドチップサポート ---------------------- ファイルの007Bhにはサウンドチップフラグが設定されます。 特定のフラグがセットされている場合はサウンドレジスタが許可され、 セットされていなかった場合は無効となります。 * VRC6はレジスタの9000h〜9002h、A000h〜A002h、B000h〜B002hを書き込み専用として使います。 警告: 1) 上記レジスタは「書き込み専用」です。 ここにコードを保存して曲を壊さないようにしてください。 2) 重要な警告: A0、A1行はいくつかのゲームでフリップされます。 そうしなければ曲と音が全ておかしくなります。 フリップされるのはxxx1とxxx2の組となります(例:9001hと9002h) 9002hと9003hのような場合はそのままでいいです。これを決めてから 全体的に簡単になりました。これは、再生コードのほんのわずかな 場所(6つ)の変更だけすればよいことを意味します。 エスパードリーム2とマダラはこの変更が必要です。 キャッスルバニア3には不要です。 3) 完全なレジスタの説明書としてVRCVI.TXTを参照ください。 * VRC7はレジスタの9010hと9030hを書き込み専用として使います。 警告: 1) 上記内容と同様。 2) 完全なレジスタの説明書としてVRCVII.TXTを参照ください。 * FDS音源は4040h〜4092hのレジスタを使用します。 警告: 1) 6000h〜DFFFhはRAMとなります。 6000h〜DFFFhはFDS上のRAMとなります。 E000h〜FFFFhはBIOSのROM領域となる為、FDSのゲームには通常含まれません。 しかし、FDSから吸い出す為に使用されます(再生・初期化アドレス変更の為)。 2) バンクスイッチはFDSの再生において少し異なった動作をします。 5FF6hと5FF7hはそれぞれ6000h〜6FFFhと7000〜7FFFhのバンクを操作します。 NSFヘッダのオフセット76hと77hは6000h〜7FFFhとE000h〜FFFFhの両方に相当し ています。このことを覚えておいてください。 * MMC5音源は5000h〜5015hのレジスタを使用します。5205hと5206h、5C00h〜5FF5hを書き 込み専用とします。 警告: 1) 正しいドキュメントができるまでお待ちください。 2) 5205hと5206hはハードウェアの8*8乗数です。 アイデアとして、5205hと5206hに掛けられる2バイトを書き込み、その後結果を 読み込みます。 今そのトリガに取り掛かっています(5205hか5206hのどちらかを掛け算のトリガ にして書き込めばいいかと思います)。 3) 5C00h〜5FF5hは拡張RAMのエミュレート用に使われます。 ノート: 拡張RAM情報を提供してくれたMamiya氏に感謝します。 * Namco106音源は4800hとF800hのレジスタを使用します。 この動作はVRC7と同じです。 4800hはデータの読み込みか書き込みポートとして、 F800hはアドレスの書き込みポートとして使用されます。 アドレスは7ビットとモード用ビットで構成されます。 ビット7はアドレスの自動増加の判定です。セットされていた場合は4800hのデータが 読み書きされた時に自動的にアドレスが増加されます。 $40 ffffffff f:頻度 L $42 ffffffff f:頻度 M $44 ---sssff f:頻度 H s:トーン長 (8-s) * 4 4ビットサンプル $46 tttttttt t:トーンアドレス (4ビットアドレス $41は$20の上位4ビットを意味する) $47 -cccvvvv v:ラインボリューム 1+c:使用中のチャンネル($7Fのみ) $40-47:チャンネル1 $48-4F:チャンネル2 ... $78-7F:チャンネル8 チャンネル2から8はチャンネル1と同様。 $00-3F(8チャンネル)...77(1チャンネル) hhhhllll トーンデータ h:奇数アドレスデータ(符号付き4ビット) l:偶数アドレスデータ(符号付き4ビット) 正確な頻度 = (f * NES_BASECYCLES) / (40000h * (c + 1) * (8 - s) * 4 * 45) NES_BASECYCLES 21477270(Hz) ノート: 情報を提供してくれたMamiya氏に大感謝! * Sunsoft FME-07音源はC000hとE000hのレジスタを使用します。 これは、インテリビジョンやアーケードマシンの音色に使われる AY 3-8910 サウ ンドチップと同じです。 C000hはアドレスポート E000hはデータポート 両方書き込み専用で、AY 3-8910と同じように動作します。 ノート: またしても情報を提供してくれたMamiya氏に大感謝! 警告 ---- 1) 開始曲番号と最大曲番号は1から数え、開始曲のアドレスの初期値は0です。 これを明確にするため、初期化ルーチンへは単に曲番号から1引いた数を渡します。 2) NTSCの速度データはNTSCの曲、またはPAL/NTSC共通の曲にのみ使用されます。 PALの速度データはPALの曲、またはPAL/NTSC共通の曲にのみ使用されます。 3) 曲名、作曲者、著作権者の長さは31バイト以内で! 各フィールド間には少なくともNULL文字が1つになるようにしてください。 4) もし各フィールド(曲名、作曲者、著作権者)がわからない場合は内容に""を含む ようにしてください(引用文無しで)。 5) RAMは6000h〜7FFFhの8KByteあります。 MMC5の曲には5C00h〜5FF7hの拡張RAMが必要です。 8000h〜FFFFhは、曲をロードした後は読み込み専用(書き込み不可)となります。 FDSの曲で再生が始まった時のみ、ここは書き込めるようになります。 6) 初期化処理時は、AとXを除いて不定値となります。 Yはフラグとして使用できます。 7) 再生処理に入るときは、どちらになるかを仮定しないようにしてください。 フラグ、X、A、Yはどのような状態になるかわかりません。 この問題と上の問題で10曲に関して修正しました。 8) スタックは1FFh以降となります。 変数が1F0h〜1FFhを使わないようにしてください(甲竜伝説ヴィルガストがその状態 だった為2xxhへ移動させました)。 9) 変数は0000h〜07FFh内に収まるようにしてください。 もし、曲が1400h等この範囲外へ書き込む場合は移動させてください(ターミネーター3 がその状態だった為04xxhへ移動させました)。 おしまい! 日本語訳: 年がら年中春うらら URL: http://uraran.jp/ MAIL: RXP10430@nifty.ne.jp