2018年5月24日木曜日

沙羅曼蛇2を2周目BGMでスタートするパッチ

なんとなく沙羅曼蛇2のサウンドCPU側のコードを眺めてました。ホストからのコマンド、初期化の手順、全体的なデータのレイアウトくらいはわかったので少しメモ。たぶん他のSystem GXも同じ系譜なんじゃないかと(ヤッホー!軽く見てみたけど、ほぼほぼ同じだった。未使用曲は等に目新しいモノはなくMagical Melodyだけだった)

ホストからのコマンド

K056800を経由して8-bits x 4のデータを受け取ります。割り込みあがったらデータを呼んでコマンドを解釈。最初のバイトが0xF0以上の時は初期化やメモリチェック、サウンドチェック用の曲の再生など、特殊な要求がアサインされてます。それ以外の場合、最初のバイトに曲番号、2バイト目にバンク番号を指定して演奏開始。BGMはバンク1に、SEはバンク2から6にアサインされてました(ただし沙羅曼蛇2だと4〜6は同一)。

特殊コマンドはディスパッチするとこまでは追いかけたけど個別の処理は全部は追ってませんが、わかりやすいのだと0xF0が基板のテストモードから入れるSOUND SCALE CHECK。内部的に[0x0E, 0x01, 0x00, 0x00]のコマンドに置き換えられてテスト用のシーケンスが再生されます。0xF9はワークエリアの初期化、0xFEは起動時のROM RAM CHECKで7C/S、9C/S(沙羅曼蛇2の場合)のチェックの実体です。本格的にサウンドプログラムにパッチあてる場合には、このコマンドが成功するように修正する必要がある。

データ構造

0x000067e4 から 4Bytes x 8 x 2のアドレステーブルがあります。前半の4Bytes x 8が1周目、後半の4Bytes x 8が2周目のBGM/SE情報で、それぞれがバンク0〜7に対応する情報を格納する構造体のアドレスです。

各バンクの情報を格納する構造体は、単純に楽曲情報ヘッダのアドレスの配列です。1周目のBGM用バンク1の場合

.dc.b $00,$00,$6a,$fc ; SILVER WINGS AGAIN (STAGE 1)
.dc.b $00,$00,$6b,$08 ; SENSATION (STAGE 2)
.dc.b $00,$00,$6b,$14 ; ALL IS VANITY (STAGE 3)
.dc.b $00,$00,$6b,$20 ; SERIOUS! SERIOUS! SERIOUS (STAGE 4)
.dc.b $00,$00,$6b,$2c ; SPEED (STAGE 5)
.dc.b $00,$00,$6b,$38 ; DEAR BLUE (STAGE 6)
.dc.b $00,$00,$6b,$44 ; DEAR BLUE (STAGE 6)
.dc.b $00,$00,$6c,$16 ; DEAR BLUE (STAGE 6)
.dc.b $00,$00,$6c,$28 ; THEME OF THE LIVING BODY BOSS (3, 5 STAGE BOSS)
.dc.b $00,$00,$6b,$c8 ; WHAT'S YOUR NAME (NAMING)
.dc.b $00,$00,$6b,$98 ; AND THEN ...... (GAME OVER)
.dc.b $00,$00,$6b,$a4 ; A THEME OF THE SALAMANDER2 (TITLE)
.dc.b $00,$00,$6b,$b0 ; BEGINING FROM THE ENDLESS (ENDING)
.dc.b $00,$00,$6b,$f8 ; SOUND SCALE CHECK
.dc.b $00,$00,$6b,$5c ; THEME OF THE MECHANICAL BOSS (2, 4, 6 STAGE BOSS)
.dc.b $00,$00,$6b,$68 ; THEME OF THE LIVING BODY BOSS (3, 5 STAGE BOSS)
.dc.b $00,$00,$6b,$c8 ; WHAT'S YOUR NAME (NAMING)
.dc.b $00,$00,$6b,$50 ; NO FUTURE
.dc.b $00,$00,$6b,$74 ; PRELUDE OF THE LAST BATTLE (LAST STAGE)
.dc.b $00,$00,$6c,$04 ; THEME OF THE GOREM (STAGE 1 BOSS)
.dc.b $00,$00,$6b,$d4 ; THEME OF THE GOREM (STAGE 1 BOSS)
.dc.b $00,$00,$6b,$80 ; GIGA'S RAGE (LAST BOSS)
.dc.b $00,$00,$6b,$bc ; ENDING - AM SHOW VER.
.dc.b $00,$00,$6b,$e0 ; NERVOUS BREAKDOWN
.dc.b $00,$00,$6b,$ec ; FIRE TRIPPER
.dc.b $ff,$ff,$ff,$ff ; [n/a]
.dc.b $ff,$ff,$ff,$ff ; [n/a]
.dc.b $00,$00,$00,$00 ; [null]

こんな順に並んでました。ホストからのコマンドで最初のバイトで指定する順です。CD等に収録されてる未収録曲もばっちりアサインされてます(が、YOU TAKAMINE版のThunderboltは見つからず)。2周目用テーブルでは1面、4面、5面の箇所に別アドレスが入っており、POWER OF ANGER、LAST EXIT、PLANET PATISを指してます。同じ曲が複数入っているのは使い分けよくわかってないんだけど、曲番号に応じて特殊な初期化が走るコードを見かけたので、たぶん状況によって曲がうまく切り替わらない時があって、その時はワークアラウンド的に強制初期化+再生が無理やり走るような仕組みになってる気がする。

各楽曲情報を示すアドレスは、12Bytesだったかの構造体になっていて、なんらかのフラグ情報とシーケンスデータのアドレスを含んでる模様。この先はまだ調べてないけど、シーケンスデータもそのうち調べたい、というか沙羅曼蛇2音源で好き勝手演奏させたい(その後の調査でだいたい理解できた。基本演奏と音色、LFO、パンくらいは好き勝手できるようになったので簡単な曲くらいは作れそう)

ワークエリア

RAMの先頭(0x00100000)からいきなりチャンネルごとのワークが並んでいるっぽい。各チャンネル512Bytesで16チャンネル分。詳細はシーケンスフォーマットの調査と合わせていずれ。

1周目と2周目のBGMを入れ替えるパッチ

一番最初のテーブルで入れ替えちゃうのが楽です。7CのROMに対して以下の2Bytesを書き換えればOK。

0x000033f5 : 0xc4 => 0x54
0x00003405 : 0x54 => 0xc4

この入れ替えだったら起動時のチェックも素通りできます。

一応、mame用のcheatも紹介しておくとこんな感じ。
<mamecheat version="1">
  <cheat desc="Loop 1 BGM">
    <parameter>
      <item value="0xc4">Loop 1</item>
      <item value="0x54">Loop 2</item>
    </parameter>
    <script state="run">
      <action>soundcpu.rb@67EB=param</action>
    </script>
  </cheat>
</mamecheat>

0 件のコメント: