トップ 一覧 検索 ヘルプ RSS ログイン

NRTDRV仕様

NRTDRV仕様

 メモリマップ

アドレス内容
0000-17FFHIPL起動用プログラム (IPLPATCH.BIN) / NRDSEL (NRDSEL2D.BIN) / OPM音色エディタ (IPLOPMED.BIN)
1800-3DFFHドライバ本体 (NRTDRV.BIN)
3E00-3EFFHOPM#1仮想レジスタ(NRDSELOPM音色エディタで使用)
3F00-3FFFHOPM#2仮想レジスタ(NRDSELOPM音色エディタで使用)
4000-FEFFH曲データ (*.NRD)
FF00-FFFFHIPL起動用ワークエリア / スタック領域

※NRTDRV内ではスタックポインタを設定していないため、呼び出すプログラム側でSPレジスタに適切な値を設定しておく必要がある(X1の場合は0000H)。

 エントリ

01800H (DRVINI)
ドライバ初期化。最初に実行する必要がある。
01803H (MPLAY)
再生。EI状態になり、任意のアドレスから演奏する。
01806H (MSTOP)
停止。EI状態になる。
01809H (MFADE)
フェードアウト。
0180FH (MTEST)
テスト音を発音。
01812H (MPLAYD)
デフォルトアドレス再生。EI状態になり、04000Hから演奏する。
01815H (VINIT)
簡易演奏モニタ用の画面初期化。PCGの定義などを行う。
01818H (VMAIN)
簡易演奏モニタを1フレーム描画する。
0181BH (INVREG)
NRDSEL/OPM音色エディタ用の仮想OPMレジスタを無効にします。

 外部参照用ワークエリア

01831H (VER)
内部バージョン番号
    • 0 : 2016/10/28版まで
    • 1 : 2016/11/01版から
    • 2 : 2017/03/03版から

この内部バージョン番号は、ユーザーアプリケーション側でドライバと曲データの不整合を防ぐために使う。

実際にバージョン番号が実装されているのは2016/12/03版からとなる。それ以前のバージョンで上記のワークエリアを読むと「0」が返る。

2016/12/03版以前では演奏開始した時点で値が変化してしまう(トラック1のワークエリアと重複している)ため、演奏開始前に値を取得しておく必要がある。

 データ

4000Hから配置。リロケータブルなので別の場所にも置けるが、その場合はドライバ側のBGMADRワークを書き換える(曲データを再アセンブルする必要はなく、再生エントリをコールする前にワークを書き換えるだけでOK)。

曲データ内で使用されるアドレスは、すべて曲データ開始アドレスからみたオフセット値。たとえば、曲データが04A00H〜で、トラックAの実際のアドレスが06809H〜なら、曲データ内に記録されているトラックAの開始アドレスは1E09Hとなる。

早送りの時は上記2バイトに早送り時の分周値が入る。

jコマンドの実体はtコマンドtコマンドで分周値を再設定することによって、本来のテンポに戻している。

上記2バイトは必ず確保されているので#TEMPOヘッダは曲データのサイズに影響しない。

#TEMPOヘッダを全く使わなくても上記にはBPM120相当の分周値が入る。

逆に、tコマンドjコマンドは使うたびに3バイト消費する。

よって、テンポの変わらない曲では#TEMPOヘッダだけを使うのがサイズ的に望ましい。

  • 3バイト目
    • ビット0:OPMにウェイトを掛けるかどうかのフラグ
    • ビット1:キーオンフラグ (このフラグを立てるとキーオンしない。テンポ再設定でキーオン復活)
    • ビット2:qコマンド未使用フラグ(このフラグを立てるとqコマンド関連の演算を一切行わなくなる)
    • ビット3〜6:予約
    • ビット7:内部バージョン番号が42バイト目に存在するかどうか
  • 4バイト目〜41バイト目
    • OPM#1の8チャンネル分の各トラック先頭アドレス(16バイト)
    • OPM#2の8チャンネル分の各トラック先頭アドレス(16バイト)
    • PSGの3チャンネル分の各トラック先頭アドレス(6バイト)
  • 42バイト目
    • 存在しない=2016/10/28版まで
    • 1=2016/11/01版から
    • 2=2017/03/03版から

3バイト目の最上位ビットが立っている場合は内部バージョン番号がここに入る。

3バイト目の最上位ビットが立っている場合は43バイト目から、立っていない42バイト目から、上記5項目の曲情報が入る。可変長で、各項目の終端は0。

  • それ以降

シーケンスデータ

 シーケンスデータ仕様

コマンド番号はすべて10進数で記載する。[????.w] の場合は2バイト値。

[00]+[count] (+[count]+[count]...)

休符。[count] はカウント数。もしカウント数が255なら、その次の1バイトもカウント数として扱う。

[01]+[times]+[register]+[data] (+[register]+[data]...)

zコマンド。一気に複数のレジスタへと書き込める。[times]は書き込むレジスタの個数。

[02]+[PAN/ALG/FB]+[voice_address+2.w]

軽量音色設定。PAN/ALG/FBをドライバ側で計算せずに決め打ちする。さらに、オペレータマスクは指定できない(前回の設定値を引き継ぐ)。[voice_address+2.w] は音色データが置かれているメモリの相対アドレス+2バイト。

[03]+[volume]

ボリューム値をワークエリアに書き込む。レジスタへの書き込みは行わない。音色切替と音量コマンドが連続したときにTLレジスタを2回叩くのを防ぐために使用。[volume]はボリューム値。

[04]+[OP1のDT2/MUL]+[OP1のTL]...[OP4のDT2/MUL]+[OP4のTL]

全オペレータのMUL、DT2、TLを一括で書き換える。CSM音声合成に使用可能。

[05]+[type/sync]

ソフトウェアPM-タイプ再設定(シンクフラグ設定用)

[06]+[OP/sync]

OPMトラックではソフトウェアAM-OP再設定(シンクフラグ設定用) / PSGトラックでは予約。

[07]〜[11]

予約。

[12]+[port]+[register]+[data]

ポート指定時のyコマンド。[port] はOPMのポートアドレスの下位バイト(0=PSG、1=0701H、9=0709H)。[register] はレジスタ番号、[data] は書き込む値。

[13]+[release_rate]+{release_level]

PSGリリース設定。PSGパートでキーオフした際のリリースレートとリリースレベルを設定する。

[14]+[voice_address.w]

音色設定。[voice_address.w] は音色データが置かれているメモリの相対アドレス。

[15]+[detune]

デチューン。[detune]はデチューン値。2の補数でマイナスを表現するので、値のもつ範囲は-128〜127となる。

[16]+[macro.address.w]

マクロ。[macro.address.w] はマクロデータの相対アドレス。

[17]

レガートON。

[18]

レガートOFF。

[19]+[volume]

ボリューム。[volume] はボリュームの値。PSGトラックでも0〜127となっているため、ドライバ側で3ビット右シフトし、0〜15に丸め込まれる。

[20]+[number]

OPMトラックではパン。[number] はパンの値。PSGトラックではトーン・ノイズ指定。[number] のビット0を立てるとトーン有効、ビット1を立てるとノイズ有効 (0=ミュート 1=トーン 2=ノイズ 3=両方)。

[21]+[times]

リピート開始。[times] はリピート回数。

[22]

リピート終了。

[23]

リピート脱出。

[24]+[register]+[data]

yコマンド。[register] はレジスタ番号、[data] は書き込む値。

[25]+[number]

qコマンド

[26]+[number]

Qコマンド

[27]+[number]

OPMトラックではハードウェアLFOリセット兼シンク。[number] は機能選択 (0=リセット 1=シンク解除 2=シンク)。PSGトラックではノイズ周波数。PSGレジスタ#6の値。

[28]+[key_shift]

移調。[key_shift] はキーシフト値。2の補数。

[29]+[pitch]/[pitch.d]+[pitch]

ポルタメント。[pitch] の値が割り込み1周期ごとにレジスタに加算される。

OPMトラックでは [pitch] は 0〜255で、この値がポルタメントON/OFFのフラグも兼ねる。

PSGトラックでは [pitch.d]+[pitch] の2バイトとなり、[pitch.d] は小数点以下2桁を100倍したものとなる。また、[pitch] は 0〜127で、最上位ビットはポルタメントON/OFFのフラグとして扱う(つまり、この2バイトで0.01〜127.99の精度となる)。

[30]+[CTC0]+[CTC3]

テンポ。[CTC0] と [CTC3] は各CTCチャンネルの分周値。

[31]+[delay]+[pitch]+[steps/flag]+[type/sync]

ソフトPM。[steps/flag] が動作フラグも兼ねている(0以外で動作)。[type/sync] のビット7はシンクフラグ。

[32]+( OPM=[delay]+[depth]+[steps/flag]+[OP/sync] / PSG=[shape] )

OPMトラックではソフトAM。[steps/flag] が動作フラグも兼ねている(0以外で動作)。[OP/sync] のビット7はシンクフラグ。PSGトラックではsコマンド(ハードウェアエンベロープ設定)。

[33]

強制キーオフ。

[34]+[number]

トラック再開。[number] はトラック番号(トラックA〜Pが1〜16、トラック1〜3が17〜19になる)。

[35]+[incliment]+[start_pitch.w]

グライド。[incliment] は増分兼フラグ(0でオフ)。[start_pitch] はグライド開始ピッチ。2の補数。

[36]+( OPM=[volume]+[OP] / PSG=[period.w] )

OPMトラックではOP指定型ボリューム。[volume] はボリュームの値。[OP] はオペレータ指定。PSGトラックではmコマンド(ハードウェアエンベロープ周期)。

[37]+[fade_speed]

フェードアウト。[fade_speed] はフェードアウトの速度。0〜15で、0が最速。

[38]〜[124]

予約。内部処理は [126] のトラック終了と同等。

[125]

トラック一時停止。トラック再開コマンドで再開できる。

[126]

トラック終了。トラック再開コマンドで再開できない。

[127] (+[loop_address.w])

トラック/マクロ終了。トラック終了の場合は [loop_address.w] がループ地点の相対アドレス。

[128〜247]+[count] (+[count]+[count]...)

音符。[128]=o0c、[247]=o9b。[count] はカウント数。もしカウント数が255なら、その次の1バイトもカウント数として扱う。

 割り込み仕様

2本の割り込みを駆動し、テンポとエフェクトに利用している。

CTC0+CTC3

この割り込みに演奏ルーチンを接続。割り込み周期自体を可変させてテンポを変更する。

周期 = 937500 / ( BPM * ( TimeBase / 4 ) )

X1のクロックは4MHzなので、1クロックあたりの時間は250ns。

しかし、プリスケーラを256倍にしているため、割り込み周期の最小単位は64ms(250ns*256)となる。

[例] BPM=120、TimeBase=192の場合

937500/(120*(192/4))*250ns*256=10.4166666…

つまり、BPM120の割り込み1周期あたりの時間は約10.42ミリ秒。

CTC1

この割り込みにエフェクトルーチンを接続。常に1周期16.384msで処理されるため、各種エフェクト(ポルタメント、グライド、ソフトウェアLFO)に関してはテンポの影響を受けない。タイマモードでタイムコンスタント値は0(256)、プリスケーラは1(256倍)。

周期 = 16.384ms = 16384000ns = 256(タイムコンスタント) * 256(プリスケーラ) * 250ns(4MHz)

音色データ仕様

OPM音色データ

下記の30バイトからなる。

PAN/FB/ALG,     OM,
DT1/ML, DT1/ML, DT1/ML, DT1/ML,
   VOL,    VOL,    VOL,    VOL,
KS /AR, KS /AR, KS /AR, KS /AR,
AM /DR, AM /DR, AM /DR, AM /DR,
DT2/SR, DT2/SR, DT2/SR, DT2/SR,
SL /RR, SL /RR, SL /RR, SL /RR,
    TL,     TL,     TL,     TL
;(OP1)   (OP3)   (OP2)   (OP4)

VOLはコンパイラ側で音量コマンドの値を反映するように加工したTL値。そのため、同じ音色で音量だけが違う場合、データ内には複数個の音色データが定義される(音色定義時にドライバ側でTLを再計算させるのを避けて負荷軽減するため)。

PSG音色

次の値が可変長で並ぶ。

[00]〜[15] 音量
[16]〜[47] ノイズ周波数指定
[48]〜[51] トーン/ノイズ指定
[255]+[loop_offset] 音色データ終了

発音が最後まで到達すると、発音位置からloop_offsetの値を引く。loop_offsetは1バイトなので、255バイト以上前にループさせることはできない。