本音源ドライバーは、cc65(6502用クロス開発環境)のオブジェクトライブラリ`*.lib'として開発しています。
ユーザーアプリケーションからは、ライブラリ中の関数を呼ぶことにより、本音源ドライバーを制御することが可能です。
本音源ドライバーは、cc65の付属のNES用ライブラリ`nes.lib'内の関数を一切呼び出していません。
(つまり、C言語の機能(標準関数など)を一切、使っていません。)
従って、アセンブリ言語のみで開発されたアプリケーションからでも使用する事が可能です。
cc65以外の開発環境で記述されたコードから呼び出しても動作するとは思いますが、
ライブラリはcc65の形式ですので、その開発環境のライブラリ形式に変換するか、
もしくは、cc65のライブラリ形式と互換性を持っている必要があります。
6502シリーズのCPUをターゲットとした、C言語・アセンブリ言語によるクロス開発を可能にしたソフトウェア開発環境です。
多くのプラットフォーム(システム)に対応しており、NES(ファミコン)もその中の1つとなっています。
フリーの6502開発環境としては非常に優れており、本格的なクロス開発によるソフトウェア開発ができます。
cc65は、http://cc65.github.io/cc65/からダウンロードできます。
(※cc65のホームページ、マニュアルは、全て英文です。)
リンカー"ld65.exe"でリンクする時に、"nsd.lib"(音源ドライバー本体)をリンクして下さい。
各インクルードファイル(C言語用は"nsd.h"、アセンブリ言語用は"nsd.inc")には、
nsd.libを制御するライブラリ関数の外部宣言等が記述されていますので、
ユーザーアプリケーションのソースからリンクすると便利です。
以下のセグメントを使っています。
リンカーのコンフィグファイルで、かならず本セグメント領域を作ってください。
※C言語からコンパイルされるアセンブリ言語ソースで用いられるセグメント名に合わせてあります。
セグメント名 | 内容 |
---|---|
CODE | 音源ドライバのプログラム本体です |
RODATA | 固定データです。 音程テーブルや、オペコード毎のジャンプテーブル等のデータがあります。 |
BSS | 制御用のワークエリア(非ゼロページ)です。 |
ZEROPAGE | 制御用のワークエリア(ゼロページ)です。 ※リンカーの"-t nes"オプションでは容量が足りない旨、注意してください。 |
外部宣言されるラベルには、ラベル名の先頭に"_nsd_"の5文字を付加しています。
C言語から参照する場合は、先頭の`_'を抜き、"nsd_"の4文字で参照可能です。
付属のMMLコンパイラを用いて楽曲制作する場合、
MMLソースにて、曲データを配置するセグメント、用いるラベル名を設定することが可能です。
(従い、1つのプロジェクトに、複数のMMLから作ったオブジェクトをリンク可能です。)
また、付属のMMLコンパイラで作られたアセンブリ言語ソースは、ソースの編集無しにそのままアセンブル・リンクする事が可能です。
別途、nsc.exeが出力するアセンブリ言語ソースについてを参照して下さい。
C言語で曲データを再生するサンプルソースですが、アセンブリ言語でも方法は同じです。
本音源ドライバーは、6502の"Zeropage"領域(メモリ空間0x0000~0x00FF)をいくらか使用します。
(使用する量は、対応する拡張音源の種類によって異なります。)
従いまして、別途リンカー用の config ファイルを作成し、 -t none オプションでビルドして下さい。
これは、 -t nes オプションでは、C言語のランタイムが使う分のサイズしか、 zeropage のセグメント設定をしていないためです。
そのため、 -t nes オプションを使用すると、音源ドライバ用の Zeropage を確保できず、ビルドに失敗します。
cc65に付属のNES用ライブラリ"nes.lib"内のコードは、configファイルのセグメント設定と関係無しに、
Zeropageを絶対アドレス(つまり、番地を直接指定)で読み書きしている領域があります。
そのため、configファイルのセグメントの設定次第では、nes.libがアクセスする領域とバッティングします。
リンカー用の config ファイルの作成に際しては、
cc65に付属のドキュメント及び、"nes.inc"及び、"nes.lib"のソースファイルを良く参照してください。
以下に記載のライブラリ関数について、関数呼出規約は全て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. |
関数の一番右の引数はレジスターで渡されます。
cc65では、一番右の引数以外は、ソフトウェアスタック(zeropage内の変数spによりC言語で制御される)に格納されますが、
本音源ドライバーではライブラリ関数の引数は必ず1つ以内とし、ソフトウェアスタックの使用を避けております。
これにより、cc65に付属のランタイムライブラリ`nes.lib'をリンクしないでも、動作する設計となっています。
戻り値はレジスターに格納されます。
戻り値がない場合は、レジスターの値は不定となります。
yレジスターの値は常に不定です。
アセンブリ言語から呼び出す場合は、シンボル名にアンダーバー('_')を追加して下さい。
たとえば、アセンブリ言語からnsd_main(void)
を呼び出す場合は、jsr _nsd_main
と記述します。