ドルアーガの塔(アーケード版)のサウンドドライバを調べてみました。
ドルアーガの塔の基板は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 | 面クリア |
02 | 60フロアクリア |
03 | ZAP |
04 | イシター面BGM |
05 | メインBGM |
06 | QOX面BGM |
07 | 59面 |
08 | チャイム |
09 | スライム移動 |
0A | スペル |
0B | スペル(炎) |
0C | 壁壊し |
0D | QOXの炎 |
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 | ||||
ループ1 | F4 | 回数 | アドレス上位バイト | アドレス下位バイト | アドレス〜コマンド間を回数だけループ |
ループ2 | F5 | 回数 | アドレス上位バイト | アドレス下位バイト | 指定回数通過した時だけループ |
ジャンプ | 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 | 終端処理:現在のボリュームを維持 | |
11 | n | 終端処理:ボリュームがnになるまで減衰 |
12 | 終端処理:音長に合わせて減衰 | |
13 | 先頭に戻り、ループする。 | |
14 | キーオンでエンベロープをリセットしない? |
まとめ
音程に不思議なところがあるものの、ループやエンベロープの機能など、時代を考えればかなり先進的なドライバと思いました。