【MSX】MuSICAの仕様書とVCDファイルの構造解析メモ(2025/03/03更新)

 

MuSICA関連のドキュメント置き場:
https://uniskie.github.io/msx_music_data/

 

2025/03/03 githubに置いてあるドキュメント類をマークダウンテキストとして整備し、HTML変換して見やすくしたものからこの記事にフィードバック(githubのドキュメント置き場所も移動されています)

2025/02/08 プログラム仕様書が間違っているのにも関わらず、当時、BASICから演奏できた理由は、「Mマガの記事に乗っていたBASICサンプルが実装と合っているものだったから。」でした。

2025/02/07 プログラム仕様書が実装と大きく異なる為に実用にならない問題について、実際に使用できるように独自調査したときの内容を反映しました。

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)

 


MuSICA VCD File Format 解析情報

https://uniskie.github.io/msx_music_data/html/MuSICA%20VCD%20File%20Format.html

独自の解析情報に、「MuSICA ドライバー部 音楽データ 仕様書」からの引用を加えた非公式文書です。

 

音色の数

音源 番号範囲 個数
OPLL 0 ~ 99 100個
PSG 0 ~ 29 30個
SCC 0 ~ 49 50個
 

VCDファイルの全体アドレスマップ

offset size 内容
+0000H 8 * 100 = 800 bytes OPLL 音色名 テーブル
+0320H 8 * 30 = 240 bytes PSG 音色名 テーブル
+0410H 8 * 50 = 400 bytes SCC 音色名 テーブル
+05A0H 8 * 100 = 800 bytes OPLL 音色データ テーブル
+08C0H 8 * 30 = 240 bytes PSG 音色データ テーブル
+09B0H 36 * 50 = 1800 bytes SCC 音色データ テーブル

合計 10B8H = 4280バイト

 

OPLL 音色データ Format (8 bytes)

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

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

ofs. C/M bit7 6 5 4 3 2 1 0
+0 (M) AM VIB EG KSR MULtiple
+1 (C) AM VIB EG KSR MULtiple
+2 (M) KSL Total Level
+3 (C) KSL 0 DC DM FeedBack(M)
+4 (M) Attack Rate Decay Rate
+5 (C) Attack Rate Decay Rate
+6 (M) Sustain Level Release Rate
+7 (C) Sustain Level Release Rate
 
  • (M): Modulator

  • (C): Carrier

  • Multiple値と周波数倍率の関係について、
    特殊なものは、0(半分)、10と11(10倍)、12と13(12倍)、14と15(15倍)。
    それ以外は指定値通りの倍率。

  • [BUG] MuSICAの音色エディタではDCとDMが入れ替わっているバグあり

 

PSG 音色データ Format (8 bytes)

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

VCDファイルでは切りの良いように8バイト単位で配置されます。
(2バイトは余白になります)

オフセット 内容
+0 ソフトウェアエンベロープのアタックタイム
+1 ソフトウェアエンベロープのディケイタイム
+2 ソフトウェアエンベロープのサスティンレベル
+3 ソフトウェアエンベロープのリリースタイム
+4 ノイズの周波数
+5 トーン及び、ノイズのオン・オフ制御
  (01H = Tone off
+6 空き
+7 空き
  • アタック、ディケイ、リリースは上位4ビットでカウンター、下位4ビットで音量の変化量を指定します。
    それぞれ値のとる範囲は1~15です。

    たとえば、カウンターの値が1で変化量が2の場合、
    1カウント(60分の1秒)で音量が2ずつ変化していく。

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

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

  • トーンおよび、ノイズのオン・オフ制御は、

    ビット0でトーンを指定。
    ビット3でノイズを指定。

    ビットが0のときオン。
    ビットが1のときオフ。

  • その他のビットは0を指定しなければなりません。

 
参考: テストデータ
Editor(Decimal)       : Dump(0xHexadecimal)  
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  
 ... 1FH -> add(or sub) 15 per 1 frame  
 ... 11H -> add(or sub) 1 per 1 frame  
 ... F1H -> 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 音色データ Format (4 + 32 = 36 bytes)

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

オフセット 内容
+0 ソフトウェアエンベロープのアタックタイム
+1 ソフトウェアエンベロープのディケイタイム
+2 ソフトウェアエンベロープのサスティンレベル
+3 ソフトウェアエンベロープのリリースタイム
+4~+35 波形データ
  • ソフトウェアエンベロープはPSG音源と同様です。

  • 波形データは、符号付8ビットの振幅データが32個で1周期を構成します。

  • チャンネル4、5はハードウェアの都合上同じデータを使用するため、後で設定された波形データが有効になります。

 
波形データテーブル例
+4:  80H = -127  
     81H = -126  
     ...  
     FEH =   -2  
     FFH =   -1  
     00H =    0  
     01H =   +1  
     02H =   +2  
     ...  
     7EH = +126  
+35: 7FH = +127  

MuSICA ドライバー部 データ 仕様書

https://uniskie.github.io/msx_music_data/html/MuSICA_Driver_Data_manual.html

MSXマガジン標準ミュージックドライバー[MuSICA]
(C) Ascii corporation / 1990

MSXディスク通信創刊号(1990年10月)付属の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を引いた値が実際にレジスタに設定されます。
デフォルトは60Hです。

FM音源の場合60Hが、PSG音源、SCC音源の場合6FHが最大です。

 
70H~7FH

音色指定です。この値から70Hを引いた値が実際にレジスタに設定されます。
デフォルトは7AHです。

この命令はFM音源のみの命令で、PSG音源、SCC音源で使用した場合は何も起こりません。

 
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)で指定します。
デフォルトは8です。

Q指定が0の時だけは特別な意味を持ち、この値が指定された場合、必ず最後の1カウントは音を切って演奏します。

データが1~8または0出ない場合の動作の保証はありません。
また、レガートONの時はQ指定は実行されません。

 
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. リズム部
 
リズム音操作
ビット 7 6 5 4 3 2 1 0
意味 V 0 1 B S M C H
ビット 意味
V このビットが1なら次の1バイトで音量指定
  0なら指定されたリズム楽器を発音
B バスドラムを指定
S スネアドラムを指定
M タムタムを指定
C シンバルを指定
H ハイハットを指定
 
(bit7) V=0 (001?????b)

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

 
(bit7) V=1 (101?????b)

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

 
0C0H (11000000b)

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

 
0FFH (11111111b)

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

 
(4) 音色データ データ構造
 
FM音源の場合

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

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

ofs. C/M bit7 6 5 4 3 2 1 0
+0 (M) AM VIB EG KSR MULtiple
+1 (C) AM VIB EG KSR MULtiple
+2 (M) KSL Total Level
+3 (C) KSL 0 DC DM FeedBack(M)
+4 (M) Attack Rate Decay Rate
+5 (C) Attack Rate Decay Rate
+6 (M) Sustain Level Release Rate
+7 (C) Sustain Level Release Rate
 
  • (M): Modulator

  • (C): Carrier

  • Multiple値と周波数倍率の関係について、
    特殊なものは、0(半分)、10と11(10倍)、12と13(12倍)、14と15(15倍)。
    それ以外は指定値通りの倍率。

  • [BUG] MuSICAの音色エディタではDCとDMが入れ替わっているバグあり

PSG音源の場合

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

VCDファイルでは切りの良いように8バイト単位で配置されます。
(2バイトは余白になります)

オフセット 内容
+0 ソフトウェアエンベロープのアタックタイム
+1 ソフトウェアエンベロープのディケイタイム
+2 ソフトウェアエンベロープのサスティンレベル
+3 ソフトウェアエンベロープのリリースタイム
+4 ノイズの周波数
+5 トーン及び、ノイズのオン・オフ制御
  (0x01 = Tone off
+6 空き
+7 空き
  • アタック、ディケイ、リリースは上位4ビットでカウンター、下位4ビットで音量の変化量を指定します。
    それぞれ値のとる範囲は1~15です。

    たとえば、カウンターの値が1で変化量が2の場合、
    1カウント(60分の1秒)で音量が2ずつ変化していく。

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

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

  • トーンおよび、ノイズのオン・オフ制御は、

    ビット0でトーンを指定。
    ビット3でノイズを指定。

    ビットが0のときオン。
    ビットが1のときオフ。

  • その他のビットは0を指定しなければなりません。

SCC音源の場合

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

オフセット 内容
+0 ソフトウェアエンベロープのアタックタイム
+1 ソフトウェアエンベロープのディケイタイム
+2 ソフトウェアエンベロープのサスティンレベル
+3 ソフトウェアエンベロープのリリースタイム
+4~+35 波形データ
  • ソフトウェアエンベロープはPSG音源と同様です。

  • 波形データは、符号付8ビットの振幅データが32個で1周期を構成します。

  • チャンネル4、5はハードウェアの都合上同じデータを使用するため、後で設定された波形データが有効になります。

 
波形データテーブル例
+4:  0x80 = -127  
     0x81 = -126  
     ...  
     0xFE =   -2  
     0xFF =   -1  
     0x00 =    0  
     0x01 =   +1  
     0x02 =   +2  
     ...  
     0x7E = +126  
+35: 0x7F = +127  

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

https://uniskie.github.io/msx_music_data/html/MuSICA_Driver_Program_manual.html

MSXマガジン標準ミュージックドライバー[MuSICA]
(C) Ascii corporation / 1990

このドキュメントは特集記事のサンプルプログラムと
自分で解析した情報を元に実際に使えるように修正した非公式版です。

注意事項:

MSXディスク通信創刊号(1990年10月)付属のMuSICA仕様書は、
実際に配布されているBGM.BINとは仕様が異なっているため、
仕様書の情報では演奏制御が出来ません。

実際にリリースされたBGM.BINはBASICからの呼び出し向けに実装されており、
一部エントリが呼び出し型の変更や廃止があり、ワークエリアも大きく移動しています。

  • MSXマガジン1990年10月号のMuSICA特集記事に掲載されている
    BASIC用サンプルプログラムが正しい使い方です。

(1)ミュージックドライバーのエントリー

[ ]内はそのアドレスです。

BGMINI [CE00H]

ミュージックドライバーを初期化します。

このルーチンを実行するまでは、以後のすべてのミュージックドライバーのエントリールーチンを呼び出してはいけません。

エントリー BGMINI [CE00H]
入力 なし
出力 なし
レジスタ すべて

[補足] オリジナル版マニュアルと実装の異なる部分:

このルーチン実行後にページ1のスロットを変更しても問題ありません。
ただし、演奏中に変更してはいけません。
(演奏終了していれば問題ありません。)

BGMON [CE03H]

演奏を開始します。

[補足] オリジナル版マニュアルと実装の異なる部分:

  1. 呼び出し方法が異なります。
  2. タイマー割り込み周りが異なります。
  • 演奏中にディスクアクセスをすると暴走しますので、ディスク操作前にBGMOFFを呼び出してください。

  •  

    演奏開始時にタイマー割り込みフックを書き換えます。
    (BGMOFFでタイマー割り込みフックを元に戻します。)

    • その際、内部で割り込み禁止した後に、割り込み許可状態に変更して戻ります。
      ※ 割り込み禁止が必要な状態での呼び出しは避けてください。
  • 【制限事項】
    演奏中にページ1のスロットを変更してはいけません。

    MuSICAはタイマー割り込み中に強制的にMAIN ROMへ切り替えて戻ります。
    (変更前のスロット選択状態に戻すわけではありません。)

    暴走を避けたい場合、スロット変更中は割り込みを禁止してください。

    ※ ディスクアクセスはスロット切り替えと割り込みを使用するので暴走します。

BASICから扱う場合 :

DEFUSR=&HCE03:U=USR(VARPTR(P(0)))
(※変数は整数型であること)

エントリー BGMON [CE03H]
入力 P(1)=音楽データヘッダー部の先頭アドレス
  P(0)=繰り返し回数 0~255 (0のとき無限ループ)
出力 なし

利用例 :

  • BGM.BGM
    MuSICA の Disk menu5.save BGMStart address=A600
    で保存したもの

  • 配列変数を使用する場合

    100 CLEAR 200,&HA000:DEFINT A-Z  '変数は整数とする  
    110 BLOAD"BGM.BIN"               'ドライバロード  
    120 DEFUSR=&HCE00:U=USR(0)       'BGMINI:ドライバ初期化  
    130 BLOAD"BGM.BGM"               'BGMデータロード  
    140 P(0)=0                       'P(0) = ループ回数 0=無限  
    150 P(1)=&HA600                  'P(1) = BGMアドレス=&HA600  
    190 DEFUSR1=&HCE03:U=USR1(VARPTR(P(0))) 'BGMON:演奏開始  
    200 I$=INPUT$(1)  
    210 DEFUSR2=&HCE06:U=USR2(0)     'BGMOFF:演奏終了  
    
  • 配列変数を使用しない場合

    100 CLEAR 200,&HA000:DEFINT A-Z  '変数は整数とする  
    110 BLOAD"BGM.BIN"               'ドライバロード  
    120 DEFUSR=&HCE00:U=USR(0)       'BGMINI:ドライバ初期化  
    130 BLOAD"BGM.BGM"               'BGMデータロード  
    140 BA=&HA600                    'BA = BGMアドレス=&HA600  
    150 PA=&HA000                    'PA = パラメータワークアドレス  
    160 POKE PA,0                    'ループ回数 0=無限ループ  
    170 POKE PA+2,PEEK(VARPTR(BA)+0) 'BGMアドレス(下位8ビット)  
    180 POKE PA+3,PEEK(VARPTR(BA)+1) 'BGMアドレス(上位8ビット)  
    190 DEFUSR1=&HCE03:U=USR1(PA)    'BGMON:演奏開始  
    200 I$=INPUT$(1)  
    210 DEFUSR2=&HCE06:U=USR2(0)     'BGMOFF:演奏終了  
    
機械語から扱う場合 :
エントリー BGMON [CE03H]
入力 HL=F7F6H(ワークエリア:DAC)
  [F7F6H+2,2]=F7FAH (パラメータワークにF6F7H+4を利用)
  [F6FAH+2,2]=音楽データヘッダー部の先頭アドレス
  [F7FAH+0,1]=繰り返し回数 0~255 (0のとき無限ループ)
出力 なし
レジスタ すべて

ワークバッファを用意して、ワークバッファのアドレスを指定する形になります。
基本的にDACをワークバッファとして使用してしまうのが楽だと思います。

※ BASICと併用する場合は他のアドレスを使用してください。

機械語からの呼び出し簡略化
エントリー BGMON_2 [CE15H]
入力 HL=音楽データヘッダー部の先頭アドレス
  A=繰り返し回数 0~255 (0のとき無限ループ)
出力 なし
レジスタ すべて

[CE15H]を呼び出すとUSR関数向けの処理を飛ばしてHLAレジスタで直接指定できます。
今後のバージョンアップは無いと思うので、機械語から使用する場合はこちらの方が楽です。

解説 : エントリ呼び出し~USR引数処理
  1. BASIC USR関数で呼び出した場合、HLにはDACアドレスF7F6Hが入っている。
  2. 整数型の場合、DAC+2に引数の値が入っている。

「USR引数を受け取る処理」は以下の通り。

ce03:  jp $ce12  
...  
ce12:  call $ce1e     ; USR引数からパラメータを受け取る処理  
ce15:  jp $ce34       ; BGMON処理の本体  
...  
ce1e:  ; USR引数からパラメータを受け取る処理  
	push hl  
	pop  ix  
	ld   l,(ix+2)  
	ld   h,(ix+3) ; hl=USR引数  
	push hl  
	pop  ix  
	ld   a,(ix+0) ;  a=peek(USR引数+0)  
	ld   l,(ix+2) ; hl=peek(USR引数+2)+peek(USR引数+3)*256  
	ld   h,(ix+3)  
BGMOFF [CE06H]

演奏を終了します。

エントリー BGMOFF [CE06H]
入力 なし
出力 なし
レジスタ すべて

[補足] オリジナル版マニュアルに書かれていない注意点:

  • BGMONで書き換えたタイマー割り込みフックを元の状態に戻します。
    その際、内部で割り込み禁止した後に、割り込み許可状態に変更して戻ります。

  • 演奏中でなければBGMOFFを呼び出しても何もしません。(問題も起きません。)

  • 演奏中にディスクアクセス等をすると暴走しますので、ディスク操作前にBGMOFFを呼び出してください。

BGMDRV [CE09H] → 廃止

廃止されています。

実体はCE62Hにありますが、
BGMONを呼び出した時に自動的にタイマーフックから呼び出すように設定されますので、自分で呼び出す必要はありません。

BGMTST [CE0CH] → 廃止

廃止されています。

ワークエリア DRV.ON [CE9BH,1] を調べれば演奏中かどうか判定は可能です。

BGMVOL [CE09H] ← [CE0FH]

マスターボリュームの書き込み、読み出し、演奏の一時中断、演奏の再開を制御します。

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

注意事項

演奏中にマスターボリュームを変更すると発音に問題が発生します。
急に大きな音が鳴るなどの現象が発生するので、フェードアウト・フェードインには使用できません。
マスターボリュームの操作は演奏開始前に使用してください。

[補足] オリジナル版マニュアルと実装の異なる部分:

  1. エントリアドレスが異なります。
  2. 呼び出し方が異なります。
BASICから扱う場合 :

DEFUSR=&HCE09:U=USR(VARPTR(A))
(※変数は整数型であること)

エントリー BGMVOL [CE09H]
入力 A=0~15 マスターボリューム書き込み
  A=16 マスターボリューム読み出し
  A=17 演奏の一時中断
  A=18 演奏の再開
出力 読みだした場合、Aレジスタにマスターボリューム値0~15が入るのでBASICからは取得できません。
  (どうしても必要であればワークエリア MSTVOL [CE9AH,1] を直接読みだしてください。)

利用例 :

DEFINT A-Z '整数変数とする  
(中略)  
V=15 ' マスターボリューム=最低音量  
DEFUSR=&HCE09:U=USR(VARPTR(V))  
機械語から扱う場合 :

ワークバッファを用意して、ワークバッファのアドレスを指定する形になります。
基本的にDACをワークバッファとして使用してしまうのが楽だと思います。

※ BASICと併用する場合は他のアドレスを使用してください。

エントリー BGMVOL [CE09H]
入力 HL=F7F6H(ワークエリア:DAC)
  [F7F6H+2,2]=F7F6H (パラメータワークにF6F7Hを利用)
  [F7F6H,1]=0~15 マスターボリューム書き込み
  [F7F6H,1]=16 マスターボリューム読み出し
  [F7F6H,1]=17 演奏の一時中断
  [F7F6H,1]=18 演奏の再開
出力 読みだした場合、Aにマスターボリューム値0~15が入る
レジスタ すべて
機械語からの呼び出し簡略化

[CE1BH]を呼び出すとUSR関数向けの処理を飛ばしてAレジスタで直接指定できます。
今後のバージョンアップは無いと思うので、機械語から使用する場合はこちらの方が楽です。

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

PSGの音楽データを実際にレジスタに書き込むかどうかをチャンネルごとに設定します。
(チャンネルマスク)

ある特定のPSGチャンネルを効果音で使用するとき、 効果音の発生が終了するまで音楽演奏データをそのチャンネルのPSGレジスタに書き込まれては困る場合に使用します。

割り込み制御はしていません。

[補足] オリジナル版マニュアルと実装の異なる部分:

  1. エントリアドレスが異なります。
  2. 呼び出し方が異なります。
補足:
  1. 曲がループするとチャンネルマスクが勝手にクリアされます。
    毎フレーム呼せば良さそうですが、次項(補足2)の問題がありますので、注意が必要です。

  2. BGMSWでは瞬間的にPSGミキサーを全ミュート→再設定を行うので
    連続して呼び出していると発音に僅かに影響が出ます。

    そのため、SEを再生する場合、BGMSWを実行したあとに毎回ミキサーの設定から行う必要があるかもしれません。(未検証)

効果音対策:
  1. ループを検出したら、再度BGMSWを実行し、効果音を途中再生(ミキサーも再設定)。
  2. または、少々処理は増えますが、毎フレームミキサー設定→音量や音程書き込み。

などの対応が考えられます。

(Dante2や吉田STGシリーズで効果音がおかしくなる事があるのはコレのせい?)

BASICから扱う場合 :

DEFUSR=&HCE0C:U=USR(VARPTR(A))
(※変数は整数型であること)

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

利用例 :

M=&B111 ' PSG全チャンネルOFF  
DEFUSR=&HCE0C:U=USR(VARPTR(M))  
機械語から扱う場合 :

ワークバッファを用意して、ワークバッファのアドレスを指定する形になります。
基本的にDACをワークバッファとして使用してしまうのが楽だと思います。

※ BASICと併用する場合は他のアドレスを使用してください。

エントリー BGMSW [CE0CH]
入力 HL=F7F6H(ワークエリア:DAC)
  [F7F6H+2,2]=F7F6H (パラメータワークにF6F7Hを利用)
  [F7F6H,1]=00000PPP
  bit0=1 : PSG チャンネルAを発声しない。
  bit1=1 : PSG チャンネルBを発声しない。
  bit2=1 : PSG チャンネルCを発声しない。
  対応するビットが0のときオン、1のときオフとなります。
  上位5ビットは必ず0を設定してください。
出力 なし
レジスタ すべて
機械語からの呼び出し簡略化

[CE0FH]を呼び出すとUSR関数向けの処理を飛ばしてAレジスタで直接指定できます。
今後のバージョンアップは無いと思うので、機械語から使用する場合はこちらの方が楽です。

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

(2)ミュージックドライバーのワークエリア

[ ]内はそのアドレスとバイト数です。

ワークエリアの読み出しは可能ですが、書き込んだ場合の動作の保証はありません。

またミュージックドライバーの状態を知る必要はある場合は、直接ワークエリアを見ず、上記のエントリールーチンを使用することをおすすめします。

FMSLOT [CE97H,1] ← [CE15H,1]

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

SCSLOT [CE98H,1] ← [CE16H,1]

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

P1SLOT [CE99H,1] ← [CE17H,1]

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

MSTVOL [CE9AH,1] ← [CE18H,1]

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

DRV.ON [CE9BH,1] ← [CE19H,1]

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

DATADD [CE9CH,2] ← [CE1AH,2]

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

※ 演奏開始後にこのアドレスを書き換えると、
イントロ→メインループのようなことが出来ます。

PRTFLG [CE9EH,1] ← [CE1CH,1]

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

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

[補足] オリジナル版マニュアルと実装の異なる部分:

割り込み周りの制御が異なり、必要な場面でドライバーが割り込みを制御します。

  • 演奏中にページ1のスロットを切り替えないでください。

    ディスクアクセスなどはページ1のスロット切替と割り込みを使用するので、演奏中は暴走します。

  • 内部でフック書き換え状態を管理しているので、BGMONやNGMOFFを多重に呼び出しても安全です。

  • タイマー割り込みフック(H.TIMI)の操作はBGMONとNGMOFF内部で行っています。
    演奏中にタイマー割り込みフックを読み書きしないようにしてください。

  • BGMONやBGMOFFは割り込み許可状態に変更して帰ります。
    割り込み禁止が必要な状態からは呼び出さないようにしてください。

非公式ワークエリア

[CE67H,1]

演奏のためにH.TIMIを書き換えていれば1、書き換えていなければ0

[dcd1,1]

bit2 - PSG ch.Aのマスク

[dceb,1]

bit2 - PSG ch.Bのマスク

[dd05,1]

bit2 - PSG ch.Aのマスク

[dd99,1]

bit0 - PSG ch.Aのトーンを演奏に使用している
bit3 - PSG ch.Aのノイズを演奏に使用している

[dda2,1]

bit0 - PSG ch.Bのトーンを演奏に使用している
bit3 - PSG ch.Bのノイズを演奏に使用している

[ddab,1]

bit0 - PSG ch.Cのトーンを演奏に使用している
bit3 - PSG ch.Cのノイズを演奏に使用している

ループ検出(演奏済みループ回数など)の方法・ワークエリアは残念ながら見つかっていません。

おまけ情報:

  • SCCスロットを強制指定したい場合

    プログラムを書き換えてSCC走査結果を上書き固定するパッチ

    A=SCCカートリッジのSLOT番号  
    POKE&HD053,&H3E:POKE&HD054,A:POKE&HD055,&H32:POKE&HD056,&H98:POKE&HD057,&HCE:POKE&HD058,0