【MSX】MuSICAの仕様書とVCDファイルの構造解析メモ

2022/08/20 追記 詳細な仕様書の書き起こしを発掘したので追加しておきます。

MuSICAデータの内部形式についての資料が見つからなかったので、昔自分で解析したけど途中で止まっていたメモと、仕様書の書き起こしテキストを置いておきます。

 

VCDファイルの構造については、独自に調べただけで互換ドライバを作った訳でもないので、情報についての保証はございません。

もし、互換ドライバを作った方や内部データの資料をお持ちの方は教えていただけると嬉しいです。

 


MSDファイル概要

ヘッダ

 +0:モード指定(0=メロディー6音+リズム / 1=メロディー9音)
 +1:チャンネル1のブロックリストアドレス
 +3:チャンネル2のブロックリストアドレス
  ...
+33:チャンネル17(チャンネルH)のブロックリストアドレス

 

ブロックリスト(MuSICA仕様書ではシーケンスデータ)

+0:ブロックデータ1アドレス(2バイト)
+2:繰り返し回数(1バイト)
+3:ブロックデータ1アドレス(2バイト)
+5:繰り返し回数(1バイト)

  ...

+n:0000H(2バイト) 終端

 

ブロックデータ

ノート番号とか音長とかの各種制御命令を並べた部分。

詳細は後述のデータ仕様書で。

0FFHが終端。

 

相対指定にしたい場合(絶対アドレスの使用部分)

MSDファイルの中には絶対アドレスが使用されています。

使用されているのは、

  1. シーケンスデータアドレス(ヘッダ)
  2. ブロックデータアドレス(シーケンスデータ)
  3. 音声データアドレス(ブロックデータの83Hコマンド)

の3つです。

これらを変更すれば好きなアドレスに再配置できますが、3つ目の音声データアドレスを変更するためにはブロックデータのコマンド列を解析しながら変更する必要があります。

 


VCDファイル

音色数

OPLL音色数:100 (0~99)
PSG音色数:30 (0~29)
SCC音色数:50 (0~49)

(※OPLL=FM音源

構造

+000h:OPLL音色名 (8バイト×100個)
+320h:PSG音色名 (8バイト×30個)
+410h:SCC音色名 (8バイト×50個)
+5A0h:OPLL音色データ (8バイト×100個)
+8C0h:PSG音色データ(8バイト×30個)
+9B0h:SCC音色データ(36バイト×50個)
計10B8hバイト(4280バイト)

 

音色データ

  1. OPLL音色データ
    OPLL(YM2413)のレジスタ0~7の値
  2. PSG音色データ
    +0:ソフトウェアエンベロープのアタックタイム
    +1:ソフトウェアエンベロープのディケイタイム
    +2:ソフトウェアエンベロープのサスティンレベル
    +3:ソフトウェアエンベロープのリリースタイム
    +4:ノイズ周波数
    +5:トーン/ノイズ制御(1ならトーンOFF、8ならノイズOFF)
    ※ アタック、ディケイ、リリースは、
      上位4ビットがカウンタ。下位4ビットが音量の変化量。
  3. SCC音色データ
    +0:ソフトウェアエンベロープのアタックタイム
    +1:ソフトウェアエンベロープのディケイタイム
    +2:ソフトウェアエンベロープのサスティンレベル
    +3:ソフトウェアエンベロープのリリースタイム
    +4~+35:波形データ32バイト
    ※ 波形データは符号付8ビット値(80Hが-128で7FHが127)

 

VCDファイル解析メモ

github.com

-------------------------------------------------------------------------------
ASCII MuSICA VCD File format
-------------------------------------------------------------------------------

------------------------------------------------------
Voice Count:
------------------------------------------------------
* OPLL Voice Count: 0 - 99 (100)
* PSG  Voice Count: 0 - 29 (30)
* SCC  Voice Count: 0 - 49 (50)

------------------------------------------------------
Address Map
------------------------------------------------------
0000: 8byte*100 [OPLL Instrument Name]
0320: 8byte*30  [PSG  Instrument Name]
0410: 8byte*50  [SCC  Instrument Name]
05A0: 8byte*100 [OPLL Voice Data] 
08C0: 8byte*30  [PSG  Voice Data] 
09B0: 36byte*50 [SCC  Voice Data] 

------------------------------------------------------
[OPLL Voice Data] Format (8bytes)
------------------------------------------------------
* NAME(bits)

+0: M: AM(1) | VIB(1) | EG(1) | KSR(1) | MUL(4)
+1: C: AM(1) | VIB(1) | EG(1) | KSR(1) | MUL(4)
+2: M: KSL(2) | TL(6)
+3: C: KSL(2) | 0(1) | DC(1) | DM(1) | FB(3)
+4: M: AR(4) | DR(4)
+5: C: AR(4) | DR(4)
+6: M: SL(4) | RR(4)
+7: C: SL(4) | RR(4)


(detail word)
+0: M: Ampllitude_Modulation(1) Vibrato(1) EG_Type(1) Key_Scale_Rate(1) Multiple(4)
+1: C: Ampllitude_Modulation(1) Vibrato(1) EG_Type(1) Key_Scale_Rate(1) Multiple(4)
+2: M: Key_Scale_Level(2) Total_Level(6)
+3: C: Key_Scale_Level(2) 0(1) Distortion_Carrier(1) Distortion_Modulator(1) FeedBack(3)
+4: M: Attack_Rate(4) Decay_Rate(4)
+5: C: Attack_Rate(4) Decay_Rate(4)
+6: M: Sustain_Level(4) Release_Rate(4)
+7: C: Sustain_Level(4) Release_Rate(4)

(*) M: Modulator
(*) C: Carrier

(*) [BUG] DC and DM are reversed on Editor. DCとDMが入れ替わっているバグがあります。

------------------------------------------------------
[PSG Voice Data] Format (8bytes)
------------------------------------------------------
+0: Attack_Rate
+1: Decay_Rate
+2: Sustain_Level
+3: Release_Rate
+4: Noise Freqency
+5: $01=Tone off | $08=Noise off
+6: blank
+7: blank

Editor(Decimal)       : Dump($Hexadecimal)
AR DR SL RR NF T   N  : at dt sl rt nz sw xx xx
-----------------------------------------------
00 00 00 00 00 off off: F1 F1 00 F1 00 09 00 00
01 01 01 01 01 on  off: C1 C1 01 C1 01 08 00 00
02 02 02 02 02 on  off: A1 A1 02 A1 02 08 00 00
03 03 03 03 03 on  off: 91 91 03 91 03 08 00 00
04 04 04 04 04 on  off: 81 81 04 81 04 08 00 00
05 05 05 05 05 on  off: 71 71 05 71 05 08 00 00
06 06 06 06 06 on  off: 61 61 06 61 06 08 00 00
07 07 07 07 07 on  off: 51 51 07 51 07 08 00 00
08 08 08 08 08 on  off: 41 41 08 41 08 08 00 00
09 09 09 09 09 on  off: 72 72 09 72 09 08 00 00
00 00 00 00 00 on  off: 31 31 0A 31 0A 08 00 00
11 11 11 11 11 on  off: 52 52 0B 52 0B 08 00 00
12 12 12 12 12 on  off: 21 21 0C 21 0C 08 00 00
13 13 13 13 13 on  off: 53 53 0D 53 0D 08 00 00
14 14 14 14 14 on  off: 32 32 0E 32 0E 08 00 00
15 15 15 15 15 on  off: 43 43 0F 43 0F 08 00 00
16 16 15 16 16 on  off: 11 11 0F 11 10 08 00 00
17 17 15 17 17 on  off: 34 34 0F 34 11 08 00 00
18 18 15 18 18 on  off: 23 23 0F 23 12 08 00 00
19 19 15 19 19 on  off: 35 35 0F 35 13 08 00 00
20 20 15 20 20 on  off: 12 12 0F 12 14 08 00 00
21 21 15 21 21 on  off: 25 25 0F 25 15 08 00 00
22 22 15 22 22 on  off: 13 13 0F 13 16 08 00 00
23 23 15 23 23 on  off: 27 27 0F 27 17 08 00 00
24 24 15 24 24 on  off: 14 14 0F 14 18 08 00 00
25 25 15 25 25 on  off: 15 15 0F 15 19 08 00 00
26 26 15 26 26 on  off: 16 16 0F 16 1A 08 00 00
27 27 15 27 27 on  off: 17 17 0F 17 1B 08 00 00
28 28 15 28 28 on  off: 18 18 0F 18 1C 08 00 00
29 29 15 29 29 on  off: 19 19 0F 19 1D 08 00 00
30 30 15 30 30 on  off: 1A 1A 0F 1A 1E 08 00 00
31 31 15 31 31 on  off: 1C 1C 0F 1C 1F 08 00 00
32 32 15 32 31 on  on : 1F 1F 0F 1F 1F 00 00 00

*at/dt/rt: frame|value
 ... $1F -> add(or sub) 15 per 1 frame
 ... $11 -> add(or sub) 1 per 1 frame
 ... $F1 -> add(or sub) 1 per 15 frame

*AR: Attack Rate
*DR: Decay Rate
*SL: Sustain Level (Volume value)
*RR: Release Rate
*NF: Noise Freq. register value

------------------------------------------------------
[SCC Voice Data] Format (4+32=36bytes)
------------------------------------------------------
+00: Attack_Rate
+01: Decay_Rate
+02: Sustain_Level
+03: Release_Rate
+04: Wave Table (32bytes)
 ...
+35: (Wave Table end)

*AR,DR,SL,DR : see [PSG Voice Data]

*Wavetable (32Bytes) : Signed 8bit value
e.g.)
    $80: -127
    $81: -126
      (...)
    $FE:   -2
    $FF:   -1
    $00:    0
    $01:   +1
    $02:   +2
      (...)
    $7E: +126
    $7F: +127

データ仕様書

github.com

MSXマガジン標準ミュージックドライバー

[MuSICA]



-ドライバー部 音楽データ 仕様書 -



  MSXマガジン標準ミュージックドライバー「MuSICA」は、FM音源9音、PSG音源3音、SCC音源5音の全17音を同時に発声できるミュージックドライバーです。「MuSICA」のドライバー部で使用する音楽データ形式について説明します。

ミュージックデータ データ構造

  ミュージックデータは、ヘッダーデータ、シーケンスデータ、ブロックデータ、音色データの4つのデータから構成されます。ブロックデータは実際に演奏を行う音階、音調データなどで構成されており、シーケンスデータは、そのブロックデータをどのような順番で演奏するかを設定するためのデータです。さらに、そのシーケンスデータをどのチャンネルに振り分けるかを指定するのがヘッダーデータです。

(1) ヘッダーデータ データ構造

    ---------------------------------------------
      オフセット:内容
    ---------------------------------------------
              +0:モード指定
    ---------------------------------------------
              +1:1 CH シーケンスデータ先頭番地
              +3:2 CH シーケンスデータ先頭番地
              ・:・・・・・・・・・・・・・・
             +33:17CH シーケンスデータ先頭番地
    ---------------------------------------------

・モード指定
  FM音源部をメロディー6音+リズム、メロディー9音のどちらのモードを使用するかを指定します。0の時メロディー6音+リズム、1の時メロディー9音が選択されます。

・シーケンスデータ先頭番地
  各チャンネルのシーケンスデータの先頭番地を絶対番地で指定します。使用しないチャンネルは0000Hを設定します。

・各チャンネルのふりわけ方
  チャンネル1~9がFM音源に、チャンネル10~13がPSG音源に、チャンネル13~17がSCC音源に対応しています。FM音源部がメロディー6音+リズムのとき、チャンネル1~6がメロディーに、チャンネル7がリズムとなり、チャンネル8、9は0000Hを指定し、使用してはいけません。

(2) シーケンスデータ データ構造

  ブロックデータの演奏順番と演奏回数をチャンネル毎に設定します。最初の2バイトがブロックデータの先頭番地(絶対番地)、次の1バイトが演奏回数です。シーケンスデータを終了させたい場合はブロックデータのアドレスに0000Hを指定します。ミュージックドライバーはある任意のチャンネルの演奏が終了しても、他のチャンネルが演奏中であるときは、他のすべてのチャンネルの演奏が終了するまでなにもせずに待ちます。

(例)

DW BLOCK1 1番目に演奏するブロックデータのアドレス
DB 2      演奏回数
DW BLOCK2 2番目に演奏するブロックデータのアドレス
DB 2      演奏回数
DW 0000H  終了

  BLOCK1を2回、BLOCK2を1回演奏し、他のすべてのチャンネルの演奏が終了するまで待ちます。

(3) ブロックデータ データ構造

1.メロディー部

00H~5FH
  音程指定となります。続く1バイトが音長データです。音階データは00Hは休符、01HがO1Cとなり、以後半音毎に+1されます。このため8オクターブ目のシ(O8B)の音程は使用できません。
  音長データは1から255で指定します。0を指定した場合の動作の保証はありません。0FFHを指定した場合は、さらに次の1バイトも音長データとして加算されます。この音長データの読み出しは、0FFH以外になるまで繰り返されます。後記のウェイト指定、リズム音長データもこの形式と同様です。

60H~6FH
  音量指定です。この値から60Hを引いた値が実際にレジスタに設定されます。FM音源の場合60Hが、PSG音源、SCC音源の場合6FHが最大です。デフォルトは60Hです。

70H~7FH
  音色指定です。この値から70Hを引いた値が時差氏にレジスタに設定されます。この命令はFM音源のみの命令で、PSG音源、SCC音源でしようした場合はなにも起こりません。デフォルトは7AHです。

80H
  サスティンOFF指定OFFです。デフォルトはサスティンOFFです。PSG音源、SCC音源で使用した場合なにも起こりません。

81H
  サスティンON指定です。PSG音源、SCC音源で使用した場合なにも起こりません。

82H
  ミュージックドライバーではサポートしていません。このデータを使用しても何も起こりません。

83H
  ユーザー音色指定です。続く2バイトでユーザー音色データのある番地を絶対番地で指定します。FM音源の場合、ここで設定したユーザー音色を発声させるには音色指定で70Hを指定しなければなりません。
  音源によってデータ形式が異なるため、FMチャンネルにPSGデータを設定した場合などの動作の保証はありません。

84H
  レガートOFF指定です。この指定をした場合、音を音符毎に切って演奏します。デフォルトはレガートOFFです。

85H
  レガートON指定です。この指定をした場合、音を音符毎に切らずに演奏します。

86H
  Q指定です。続く1バイトのデータ(1~8または0)で指定します。Q指定が0の時だけは特別な意味を持ち、この値が指定された場合、必ず最後の1カウントは音を切って演奏します。データが1~8または0出ない場合の動作の保証はありません。また、レガートONの時はQ指定は実行されません。デフォルトは8です。

87H
  デチューン指定です。続く1バイトのデータ(0~255)がデチューン量です。0を設定した場合デチューンは行われません。デフォルトは0です。

88H
  ポルタメントを指定します。続く1バイトのデータ(0~255)で音程の変化量を指定します。0を設定した場合ポルタメントは行われません。デフォルトは0です。時間変化はLFOの速度に左右されます。

89H
  ビブラート指定です。続く1バイトのデータ(0~255)でビブラートの深さを設定します。0を設定した場合ビブラートは行われません。デフォルトは0です。

8AH
  ミュージックドライバーではサポートしていません。このデータを使用しても何も起こりません。

8BH
  LFOの速度を指定します。続く1バイトのデータ(1~255)で設定します。ポルタメント、ビブラート、トレモロなどはこの設定値で動作します。デフォルトは1です。

8CH
  レジスタ直接書き込み指定です。続く1バイトでレジスタ番号を、さらに続く1バイトで書き込むデータを指定します。FM音源、PSG音源、SCC音源のどれにでも使用できますが、レジ図た番号、データともに、それぞれの音源の有効範囲外の指定をした場合の動作の保証はありません。

8DH
  ウェイト指定です。続く1バイトで待ち時間を指定します。この待ち時間は音長データと同様の形式で読みだされますが、Q指定、レガート指定などの影響をまったく受けず、本当にただ待つだけです。主に、前記のレジスタ直接書き込み指定とともに使用します。

8EH~FEH
  未使用となります。このデータを実行した場合の動作の保証はありません。

FFH
  そのブロックデータ枚の終了コードです。このコードがはいると、シーケンスデータに設定されている次のブロックデータの演奏を開始します。

-注意-

  ポルタメント、ビブラートは同時に使用することはできません。同時に使用した場合は、後で設定されたほうが有効になります。

2. リズム部

  bit 76543210
      --------
      V01BSMCH

  BSMCHは1の時ONとなり、それに対応した音色のリズム発声指定、音量指定が可能になります。

  V=0:
    リズム発声指定です。続く1バイトのデータが音長データです。この音長データの読み出しはメロディー部の場合と同様です。

  V=1:
    音量指定です。続く1バイトのデータ(0~15)が音量データとなります。このデータは下位4ビットが有効です。

  0C0H:
    レジスタ直接書き込み指定です。使用方法はメロディー部と同様です。

  0FFH:
    そのブロックデータの演奏を終了します。

(4) 音色データ データ構造

・FM音源の場合

  OPLL-YM2413のレジスタ00H~07Hの順に設定されます。

・PSG音源の場合

  1音色のデータは6バイトで構成されます。

  +0:ソフトウェアエンベロープのアタックタイム
  +1:ソフトウェアエンベロープのディケイタイム
  +2:ソフトウェアエンベロープのサスティンレベル
  +3:ソフトウェアエンベロープのリリースタイム
  +4:ノイズの周波数
  +5:トーン及び、ノイズのオン・オフ制御

  アタック、ディケイ、リリースは上位4ビットでカウンター、下位4ビットで音量の変化量を指定します。それぞれ値のとる範囲は1~15です。たとえば、カウンターの値が1で変化量が2の場合、1カウント(60分の1秒)で音量が2ずつ変化していくことになるわけです。

  サスティンレベルは0~15で指定します。

  ノイズの周波数は0~31で指定します。

  トーンおよび、ノイズのオン・オフ制御は、ビット0でトーンを、ビット3でノイズを指定し、そのビットが0のときオン、1のときオフとなります。そのほかのビットは0を指定しなければなりません。

・SCC音源の場合

  1音色のデータは36バイトで構成されます。

  +0~+3 :ソフトウェアエンベロープ(PSGと同じ)
  +4~+35:波形データ

  ソフトウェアエンベロープはPSG音源と同様です。

  波形データは、符号付8ビットの振幅データが32個で1周期を構成します。チャンネル4、5はハードウェアの都合上同じデータを使用するため、後で設定された波形データが有効になります。


プログラム仕様書

github.com

MSXマガジン標準ミュージックドライバー

[MuSICA]

-ドライバー部 プログラム 仕様書 -

(1)ミュージックドライバーのエントリーについて説明します。

・BGMINI [CE00H]

  ミュージックドライバーを初期化します。このルーチンを実行するまでは、以後のすべてのミュージックドライバーのエントリールーチンを呼び出してはいけません。また、このルーチン実行後、ページ1のスロットを変更してはいけません。変更する必要が発生した場合は、いったん演奏を中断し、割り込み処理ルーチンからNGMDRVを切り離したあとスロットを変更し、再度このルーチンを呼び出してください。

    エントリー : なし
    リターン   : なし
    レジスタ   : すべて

・BGMON [CE03H]

  演奏を開始します。あらかじめBGMDRVを割り込み処理ルーチンに接続しておいてください。割り込み制御はしていません。必要に応じてDIおよびEIを行ってください。

    エントリー : HL=音楽データヘッダー部の先頭アドレス
                  A=繰り返し回数 0~255
                                 (0のとき無限ループ)
    リターン   : なし
    レジスタ   : すべて

・BGMOFF [CE06H]

  演奏を終了します。割り込み制御はしていません。

    エントリー : なし
    リターン   : なし
    レジスタ   : すべて

・BGMDRV [CE09H]

  60分の1のタイマー割り込みを使用して音楽の演奏を行います。ユーザーの割り込み処理ルーチンから呼び出してください。

・BGMTST [CE0CH]

  BGMONにより開始した音楽が演奏中かどうかを調べます。割り込み制御はしていません。

    エントリー : なし
    リターン   : Zフラグが立っていれば終了している
    レジスタ   : AF

・BGMVOL [CE0FH]

  マスターボリュームの書き込み、読み出し、演奏の一時中断、演奏の再開を制御します。マスターボリュームは0から15の16段階で指定でき、0のとき最大となります。特に必要のない場合は常に0で演奏するように心がけてください。割り込み制御はしていません


    エントリー : A=0~15 マスターボリューム書き込み
                 A=16    マスターボリューム読み出し
                 A=17    演奏の一時中断
                 A=18    演奏の再開
    リターン   : 読みだした場合、Aにマスターボリューム値0~15が入る
    レジスタ   : すべて

・BGMSW [CE12H]

  PSGの音楽データを実際にレジスタに書き込むかどうかをチャンネルごとに設定します。ある特定のPSGチャンネルを効果音で使用するとき、効果音の発生が終了するまで音楽演奏データをそのチャンネルのPSGレジスタに書き込まれては困る場合に使用します。割り込み制御はしていません。

    エントリー : A=00000PPP
                 bit0=PSG チャンネルA
                 bit1=PSG チャンネルB
                 bit2=PSG チャンネルC
                 対応するビットが0のときオン、1のときオフとなります。
                 上位5ビットは必ず0を設定してください。
    リターン   : なし
    レジスタ   : すべて

(2) ミュージックドライバーのワークエリアにすいて説明します。
[ ]内はそのアドレスとバイト数です。

  ワークエリアの読み出しは可能ですが、書き込んだ場合の動作の保証はありません。またミュージックドライバーの状態を知る必要はある場合は、直接ワークエリアを見ず、上記のエントリールーチンを使用することをおすすめします。

・FMSLOT [CE15H,1]

  BGMINIを呼び出した時のMSX-MUSICのスロット番号が入ります。MSX-MUSICがない場合0となります。

・SCSLOT [CE16H,1]

  BGMINIwo呼び出した時のSCCカートリッジのスロット番号がはいります。SCCカートリッジがない場合0となります。

・P1SLOT [CE17H,1]

  BGMINIを呼び出した時のページ1のメインRAMのスロット番号が入ります。

・MSTVOL [CE18H,1]

  マスターボリュームの値を示します。

・DRV.ON [CE19H,1]

  0なら演奏していない、1なら演奏中を示します。

・DATADD [CE1AH,2]

  現在演奏している音楽データのヘッダーデータ部の先頭番地を示します。

・PRTFLG [CE1CH,1]

  残りの演奏回数を示します。

(3) ミュージックドライバー使用上の注意事項

  BGMINIによりミュージックドライバーを初期化したあとは、ページ1のスロットを変更してはいけません。変更する必要が発生した場合、いったんドライバーを割り込み処理ルーチンより切り離し、スロットを変更後、再度BGMINIを呼び出してください。

  BGMINIをのぞくすべてのエントリールーチンでは、割り込み制御命令(DI、EI)を実行していません。エントリールーチンを呼び出す前後で、必要に応じてDI、EIを行ってください。

(例)

        DI                                      ;割り込み禁止
        LD HL,システムフック保存場所の先頭番地  ;フック切り離し
        LD DE,0FD9FH
        LD BC,5
        LDIR
        LD A,演奏回数                           ;エントリー呼び出し
        LD HL,ミュージックデータ先頭番地
        CALL BGMON
        LD A,0C3H
        LD HL,ユーザー割り込みルーチン
        LD (0FD9FH+0),A
        LD (0FD9FH+1),HL
        EI                                      ;割り込み許可