音源ドライバー(nsd.lib)

本音源ドライバーは、cc65(6502用クロス開発環境)のオブジェクトライブラリ`*.lib'として開発しています。
ユーザーアプリケーションからは、ライブラリ中の関数を呼ぶことにより、本音源ドライバーを制御することが可能です。

本音源ドライバーは、cc65の付属のNES用ライブラリ`nes.lib'内の関数を一切呼び出していません。
(つまり、C言語の機能(標準関数など)を一切、使っていません。)
従って、アセンブリ言語のみで開発されたアプリケーションからでも使用する事が可能です。
cc65以外の開発環境で記述されたコードから呼び出しても動作するとは思いますが、 ライブラリはcc65の形式ですので、その開発環境のライブラリ形式に変換するか、 もしくは、cc65のライブラリ形式と互換性を持っている必要があります。

クロス開発環境"cc65"での使用方法

cc65とは

6502シリーズのCPUをターゲットとした、C言語・アセンブリ言語によるクロス開発を可能にしたソフトウェア開発環境です。
多くのプラットフォーム(システム)に対応しており、NES(ファミコン)もその中の1つとなっています。
フリーの6502開発環境としては非常に優れており、本格的なクロス開発によるソフトウェア開発ができます。

cc65は、http://cc65.github.io/cc65/からダウンロードできます。
(※cc65のホームページ、マニュアルは、全て英文です。)

nsd.libをユーザーアプリケーションに組み込む

リンカー"ld65.exe"でリンクする時に、"nsd.lib"(音源ドライバー本体)をリンクして下さい。
各インクルードファイル(C言語用は"nsd.h"、アセンブリ言語用は"nsd.inc")には、 nsd.libを制御するライブラリ関数の外部宣言等が記述されていますので、 ユーザーアプリケーションのソースからリンクすると便利です。

ライブラリ"nsd.lib"が用いるセグメント・ラベル

セグメントについて

以下のセグメントを使っています。
リンカーのコンフィグファイルで、かならず本セグメント領域を作ってください。
※C言語からコンパイルされるアセンブリ言語ソースで用いられるセグメント名に合わせてあります。

セグメント名内容
CODE 音源ドライバのプログラム本体です
RODATA 固定データです。
音程テーブルや、オペコード毎のジャンプテーブル等のデータがあります。
BSS 制御用のワークエリア(非ゼロページ)です。
ZEROPAGE 制御用のワークエリア(ゼロページ)です。
※リンカーの"-t nes"オプションでは容量が足りない旨、注意してください。

ラベルについて

外部宣言されるラベルには、ラベル名の先頭に"_nsd_"の5文字を付加しています。
C言語から参照する場合は、先頭の`_'を抜き、"nsd_"の4文字で参照可能です。

曲データが用いるセグメント・ラベル

付属のMMLコンパイラを用いて楽曲制作する場合、 MMLソースにて、曲データを配置するセグメント、用いるラベル名を設定することが可能です。
(従い、1つのプロジェクトに、複数のMMLから作ったオブジェクトをリンク可能です。)
また、付属のMMLコンパイラで作られたアセンブリ言語ソースは、ソースの編集無しにそのままアセンブル・リンクする事が可能です。
別途、nsc.exeが出力するアセンブリ言語ソースについてを参照して下さい。
C言語で曲データを再生するサンプルソースですが、アセンブリ言語でも方法は同じです。

C言語でアプリケーションを開発する場合の注意

本音源ドライバーは、6502の"Zeropage"領域(メモリ空間0x0000〜0x00FF)をいくらか使用します。
(使用する量は、対応する拡張音源の種類によって異なります。)
従いまして、別途リンカー用の config ファイルを作成し、 -t none オプションでビルドして下さい。

これは、 -t nes オプションでは、C言語のランタイムが使う分のサイズしか、 zeropage のセグメント設定をしていないためです。
そのため、 -t nes オプションを使用すると、音源ドライバ用の Zeropage を確保できず、ビルドに失敗します。

NES用ライブラリ"nes.lib"を使用する場合の注意

cc65に付属のNES用ライブラリ"nes.lib"内のコードは、configファイルのセグメント設定と関係無しに、 Zeropageを絶対アドレス(つまり、番地を直接指定)で読み書きしている領域があります。
そのため、configファイルのセグメントの設定次第では、nes.libがアクセスする領域とバッティングします。
リンカー用の config ファイルの作成に際しては、 cc65に付属のドキュメント及び、"nes.inc"及び、"nes.lib"のソースファイルを良く参照してください。

関数リファレンス(Function reference)

以下に記載のライブラリ関数について、関数呼出規約は全てcc65の __fastcall__ となります。

ライブラリ関数一覧

return value Function name Contents
void nsd_init(void) Initraize the driver.
void nsd_set_dpcm(nsd_dpcm* dpcm)Set the dpcm information.
void nsd_main(void) Driver main routine. Please call by one V-blank.
void nsd_main_bgm(void) Driver main routine(BGM). Please call by one V-blank.
void nsd_main_se(void) Driver main routine(SE). Please call by one V-blank.
void nsd_play_bgm(void *bgm) Start the BGM.
void nsd_stop_bgm(void) Stop the BGM.
void nsd_play_se(void *se) Start the SE.
void nsd_stop_se(void) Stop the SE.
void nsd_pause_bgm(void) Pause the BGM.
void nsd_resume_bgm(void) Resume the BGM.
void nsd_save(void *buff) Save the control work.
void nsd_load(void *buff) Load the control work.

関数呼出規約 __fastcall__ について(About the calling conversion __fastcall__ )

引数(Inputs)

関数の一番右の引数はレジスターで渡されます。

1 byte value
a register
2 byte value
a (LSB) and x (MSB) register

cc65では、一番右の引数以外は、ソフトウェアスタック(zeropage内の変数spによりC言語で制御される)に格納されますが、 本音源ドライバーではライブラリ関数の引数は必ず1つ以内とし、ソフトウェアスタックの使用を避けております。
これにより、cc65に付属のランタイムライブラリ`nes.lib'をリンクしないでも、動作する設計となっています。

戻り値(Outputs)

戻り値はレジスターに格納されます。
戻り値がない場合は、レジスターの値は不定となります。
yレジスターの値は常に不定です。

1 byte value
a register
2 byte value
a (LSB) and x (MSB) register

関数のシンボル名(Function symbol name)

アセンブリ言語から呼び出す場合は、シンボル名にアンダーバー('_')を追加して下さい。
たとえば、アセンブリ言語からnsd_main(void)を呼び出す場合は、jsr _nsd_mainと記述します。