ドルアーガの塔 サウンドドライバを調べてみました2

チャンネルの割り当て・優先制御

 ゲームはBGMだけでなく効果音も鳴ります。また複数の効果音が同時に発生することがあります。

 その場合のチャンネル割り当てや優先順位の制御について調べました。

各サウンドにはチャンネル割り当てがある

 前回の記事で32種類のサウンド(曲+効果音)があると書きましたが、それぞれに「開始チャンネル」が設定されています。

 原則的にBGM類は0ch、効果音は4ch以降が設定されています。

例)開始chが0で4和音の曲→0,1,2,3chを使用
  開始chが4で2和音の効果音→4,5chを使用

 BGMは4〜5和音で構成されており、BGMに5音、効果音に3音使うイメージです。ファミコンやPSG搭載PCに比べると余裕のある構成と言えます。

優先順位は曲番号に依存

 効果音が同時に鳴ったらどうなるか、ですがこちらは曲番号(前回記事参照)の高いものを優先する制御になっています。(曲番号順に処理を行ってワークエリアを上書きするので結果的に曲番号の高いものが残る)

 ちなみにクレジット投入音は31番ですので、最も優先順位が高い設定になっています。アーケードゲームならではですね。

 優先制御はチャンネル毎ですので、優先順位の低いSEも残ってるチャンネルがあれば鳴り続けます。可能な限り音を鳴らす設計です。(注)

 例えば歩行音は25番に割り当られており効果音の中では高い優先順位なのですが、ch7単独使用なので「歩いているので呪文の音が鳴らなかった」とならないようになっています。

 音源は8chですが論理chが45個用意されています。曲ごとに論理chが決められています。先述のチャンネル割り当ては論理chと物理chの関連付けの役割も持っている訳です。優先順位で鳴らないトラックも論理chでシーケンスは進むので、復帰しても音がズレることはありません。

 ただあまりに多くの効果音を同時に鳴らしたら処理落ちするんじゃないかと思います。

(注)チャンネルの割り当ては静的です。動的な割り当ては行っていません。例えば4chに割り当てられているトラックは他に空きがあっても4chが使用中なら鳴りません。開いてるチャンネルに移動、という機能はありません。

ドルアーガの塔 サウンドドライバを調べてみました

ドルアーガの塔(アーケード版)のサウンドドライバを調べてみました。

ドルアーガの塔の基板は6809CPUベースの基板で2つの6809が搭載されています。両者はメインとサブの役割を持ち、起動時はメインCPUから立ち上がります。メインCPUからの指令でサブCPUが動き出しゲーム機として稼働します。

サブCPUはサウンドの処理だけを行い、ゲームの進行そのものには影響しません。(サブCPUを止めてもゲームは動くはず…)

サブCPUでは常時共有RAMを監視しており、メインCPUからの演奏指令が書き込まれたら演奏を開始する仕組みです。

音源スペック

以下、独自の推定による音源のスペックです。

方式波形再生音源(通称ナムコPSG)
チャンネル数8音
波形数ROMプリセット8種類
波形スペック4bit×32サンプル
出力チャンネルモノラル
ドルアーガの塔の音源スペック

曲リスト

CPU間の通信は独特で、曲No.を指定するのではなく、共有RAMに1曲1バイトのテーブルが存在し鳴らしたい曲に対応する番地にフラグを書き込む仕組みです。音楽・効果音を区別せず管理されており、合計32種類のサウンドが存在します。具体的には共有RAM先頭から「下記の表の番号+0x40」バイト目の番地に0以外の値を書き込みます。

番号(16進数)
00面スタート
01面クリア
0260フロアクリア
03ZAP
04イシター面BGM
05メインBGM
06QOX面BGM
0759面
08チャイム
09スライム移動
0Aスペル
0Bスペル(炎)
0C壁壊し
0DQOXの炎
0E剣1
0F剣2
10剣交差
11剣3
12剣Hit
13未使用SE?
14呪文を盾で受ける
15ドアOPEN
16鍵取得
17宝箱取得
18ファンファーレ(未使用)
19ギル歩行
1Aクレジット(後半)
1Bギルやられる
1Cゲームオーバー
1Dネーム入れBGM
1Eエクステンド
1Fクレジット(前半)
サウンドリスト

曲データのフォーマット

曲データは複雑なテーブル構造になっていますが、曲本体のデータを調べた結果は以下のような感じでした。「音程+音長」が基本です。

命令+0 byte+1byte+2byte+3byte動作
発音音程(00-BF)音長指定した音程を音長×テンポ×1/60秒鳴らす
休符C0音長
波形選択F0波形No.(00-70)上位4bitで指定
エンベロープ指定F1エンベロープNo(00-19)26種類ある模様
テンポ指定F2テンポ音長の倍率になる
曲終了F3
ループ1F4回数アドレス上位バイトアドレス下位バイトアドレス〜コマンド間を回数だけループ
ループ2F5回数アドレス上位バイトアドレス下位バイト指定回数通過した時だけループ
ジャンプF6アドレス上位バイトアドレス下位バイト無条件ジャンプ
曲データ書式

テンポ指定は一般的な楽譜で言うテンポではなく曲データの音長に対する倍率です。つまり値が大きくなるほどゆっくりしたテンポになります。計算式にすると「テンポ×音長(単位1/60sec)」です。

ループのネストはできません。(ループ1と2のネストは可能。同種ループのネストが不可)

6809CPUなのでアドレスはビッグエンディアンで記載されています。アドレスは絶対番地です。

音程は

  • 上位4bit…音階(ドレミ…)
  • 下位4bit…オクターブ

ですが、MMLと違いオクターブが高いほど低い音になります。音階はC C# D E E# G G# A A# Bで0〜B、のはずなのですが実際は3音ほど高く発音されるようです。

(例:データ上のG#→実際はF)

エンベロープ

 エンベロープはソフトウェアで制御されています。曲データではエンベロープの番号を指定するのですが、エンベロープの中身は専用の領域に保存されています。

 エンベロープは1/60sec毎の音量(00〜0F)を並べた、単純なフォーマットです。終端の処理を10〜14の値で指定します。(13と14の動作はよく分かっていません…)

+0byte+1byte機能
00〜0F音量(長さ1/60sec固定)
10終端処理:現在のボリュームを維持
11n終端処理:ボリュームがnになるまで減衰
12終端処理:音長に合わせて減衰
13先頭に戻り、ループする。
14キーオンでエンベロープをリセットしない?
エンベロープのフォーマット

まとめ

 音程に不思議なところがあるものの、ループやエンベロープの機能など、時代を考えればかなり先進的なドライバと思いました。