
2022/12/31 冬コミC101のお品書きです!
スペースは土曜日 西2 す-08b 流線堂です。
新刊「CPUの訳しかた」は6809からZ80へのコード翻訳の研究と実践を本にしたものです。
アクワリオのギネス話&攻略の記事もあります。
取り急ぎですが、このような感じです。
「CPUの訳しかた」は書店委託も検討中です。
2022/12/31 冬コミC101のお品書きです!
スペースは土曜日 西2 す-08b 流線堂です。
新刊「CPUの訳しかた」は6809からZ80へのコード翻訳の研究と実践を本にしたものです。
アクワリオのギネス話&攻略の記事もあります。
取り急ぎですが、このような感じです。
「CPUの訳しかた」は書店委託も検討中です。
ゲームは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 | 面クリア |
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なのでアドレスはビッグエンディアンで記載されています。アドレスは絶対番地です。
音程は
ですが、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 | キーオンでエンベロープをリセットしない? |
音程に不思議なところがあるものの、ループやエンベロープの機能など、時代を考えればかなり先進的なドライバと思いました。