MSXには次に示すような3系統の音声出力機能があります。ただし、3.はMSXに標準的に付属するものではないため、第7部で扱います。ここではそれ以外の1.と2.の機能について説明します。
- PSGによる音声出力(3チャンネル、8オクターブ)
- 1ビットI/Oポートによる音声出力
- MSX-AUDIOやMSX-MUSICによる音声出力(FM音源)
1.1 PSGの機能
MSXの音楽演奏機能およびBEEP音の発生には、AY-3-8910相当のLSIが使われています。このLSIはPSG(Programmable Sound Generator)とも呼ばれ、その名が示すとおり、プログラムにより複雑な音楽やさまざまな効果音を発生することがきます。その特徴をまとめると次のようになります。
- 3チャンネルのトーン発生器を持ち、各チャンネルには独立に、4096種の音階(8オクターブに相当)と16段階の音量を指定することができる。
- エンベロープパターンによって、ピアノやオルガンのような音色を出すことができる。ただし、エンベロープ発生器がひとつしか存在しないため、同時に使用できる音色は1種類だけである。
- 内蔵するノイズ発生器によって、風の音や波の音のような効果音も容易に得られる。ただし、ノイズ発生器がひとつしか存在しないため、同時に使用できるノイズは1種類だけである。
- 入力クロックfcを分周することで、トーンやエンベロープをはじめとする必要なすべての周波数を得ている(なおMSXでは、fc=1.7897725MHzと定められている)。このため音程やリズムのふらつきがまったくない。
上のブロックダイアグラムでは省略しましたが、PSGは音声発生の機能とは全く別に2つの入出力ポートを持っています。MSXではこれを汎用入出力ポートとして、ジョイスティック、タッチパッド、パドル、マウスなどの入出力装置との接続にも利用しています。なお、これらの汎用入出力ポートについては、5章で説明します。
1.1.1 PSGのレジスタ
PSGが音声出力の作業をすべて実行してくれるので、CPUの仕事は単に音が変化する時点でPSGにそれを教えることだけです。これは、図6.2に示したようなPSG内部の16個の8ビットレジスタに値を書き込むことによって行います。
以下に、これらのレジスタの役割とその使用法を説明します。
1.トーン周波数の設定(R0〜R5)
A、B、C各チャンネルのトーン周波数はR0〜R5によって設定します。まずPSG内で入力クロック(fc=1.7897725MHz)を16分周し、それを基準周波数とします。また各チャンネルは、この基準周波数をそれぞれに割り当てられた12ビットのデータで分周して最終的な音程を得ます。12ビットの分周データ(TP)と発生する音の周波数(ft)には次のような関係があります。
ft=fc/(16*TP)
=0.11186078125/TP[MHz]
=111860.78125/TP[Hz]
12ビットの分周データTPは、各チャンネルごとに上位4ビットの粗調整値CTと下位8ビットの微調整値FTによって、図6.3のように指定されます。また、音階を作るためのレジスタの設定を表6.1に示します。
表6.1 トーン周波数の設定(音階データ)
音程 | オクターブ | |||||||
1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | |
C | D5D | 6AF | 357 | 1AC | D6 | 6B | 35 | 1B |
C# | C9C | 64E | 327 | 194 | CA | 65 | 32 | 19 |
D | BE7 | 5F4 | 2FA | 17D | BE | 5F | 30 | 18 |
D# | B3C | 59E | 2CF | 168 | B4 | 5A | 2D | 16 |
E | A9B | 54E | 2A7 | 153 | AA | 55 | 2A | 15 |
F | A02 | 501 | 281 | 140 | A0 | 50 | 28 | 14 |
F# | 973 | 4BA | 25D | 12E | 97 | 4C | 26 | 13 |
G | 8EB | 476 | 23B | 11D | 8F | 47 | 24 | 12 |
G# | 86B | 436 | 21B | 10D | 87 | 43 | 22 | 11 |
A | 7F2 | 3F9 | 1FD | FE | 7F | 40 | 20 | 10 |
A# | 780 | 3C0 | 1E0 | F0 | 78 | 3C | 1E | F |
B | 714 | 38A | 1C5 | E3 | 71 | 39 | 1C | E |
2.ノイズ周波数の設定(R6)
爆発音や波の音などの合成にかかせないのがノイズ音です。PSGはノイズジェネレータによって発生させたノイズをA〜Cの各チャンネルに出力できます。ノイズジェネレータは1つしかないため、各チャンネル共通に同一のノイズが出力されます。ノイズは平均周波数を変えることによって様々な効果を出すことができ、R6レジスタがその設定を行います。このレジスタの下位5ビットのデータ(NP)で基準周波数(fc/16)を分周し、ノイズの平均周波数(fn)を決定します。
NPとfnの間には次のような関係があります。
fn=fc/(16*NP)
=0.11186078125/NP [MHz]
=111860.78125/NP [Hz]
NPは1〜31の値をとりますから、ノイズの平均周波数は3.6kHz〜111.9kHzの範囲で設定できます。
3.音のミキシング(R7)
R7は各チャンネルごとに、トーンジェネレータとノイズジェネレータの出力を選択するためのレジスタで、ノイズとトーンの両者を混合することもできます。図6.5に示したように、R7の下位3ビット(B0〜B2)はトーン出力、次の3ビット(B3〜B5)はノイズ出力の制御を行います。どちらも対応するビットが0のときに出力ON、1のときにOFFとなります。
R7の上位2ビットは音声出力とは関係ありません。これはPSGが持つ2本のI/Oポートのデータ方向を決定するもので、対応するビットが「0」のときに入力モード、「1」の時に出力モードが設定されます。MSXではポートAを入力、ポートBを出力として使用していますから、つねにビット6=「0」、ビット7=「1」と設定しておく必要があります。
4.音量の設定(R8〜R10)
R8〜R10は各チャンネルの音量を指定するレジスタです。4ビットのデータ(0〜15)で音量を固定的に指定する方法とエンベロープを用いてビブラートや減衰音などの効果音を発生させる方法の2通りが選べます。その選択もこのレジスタで行います。
なお、これらのレジスタのビット4が「0」の場合、エンベロープは使用されず、レジスタの下位4ビットの値L(0〜15)によって音量が指定されます。また、ビット4が「1」の場合はエンベロープ信号によって音量が変化し、Lの値は無視されます。
5.エンベロープ周期の設定(R11、R12)
R11、R12はエンベロープの周期を16ビットデータによって指定します。データの上位8ビットをR12で、下位8ビットをR11で設定します。
なお、エンベロープの周期Tと16ビットデータEPの間には、次のような関係があります。
T =(256*EP)/fc
=(256*EP)/1.7897725 [MHz]
=143.03493*EP [μs]
6.エンベロープパターンの設定(R13)
R13は、下位4ビットのデータによって図6.8のようにエンベロープパターンを設定します。同図に示したTの間隔がR11とR12で指定されたエンベロープ周期に相当します。
7.I/Oポート(R14、R15)
R14とR15は8ビットのデータをパラレルで入出力するポートです。MSXではここを汎用入出力インターフェイスとして使用しています。詳しくは5章を参照してください。
1.2 PSGのアクセス
マシン語プログラム中からPSGをアクセスするために、以下のようなBIOSルーチンが用意されています。
- GICINI (0090H/MAIN)
機能 |
PSGを初期化します。
コール手順 |
戻り値 |
解説 |
表6.2 PSGレジスタの初期値
レジスタ | ビット | ||||||||
7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | ||
R0 | チャンネルA | 0 | 1 | 0 | 1 | 0 | 1 | 0 | 1 |
R1 | 周波数 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
R2 | チャンネルB | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
R3 | 周波数 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
R4 | チャンネルC | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
R5 | 周波数 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
R6 | ノイズ周波数 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
R7 | チャンネル設定 | 1 | 0 | 1 | 1 | 1 | 0 | 0 | 0 |
R8 | チャンネルA音量 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
R9 | チャンネルB音量 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
R10 | チャンネルC音量 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
R11 | エンベロープ周期 | 0 | 0 | 0 | 0 | 1 | 0 | 1 | 1 |
R12 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | |
R13 | エンベロープパターン | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
R14 | I/OポートA | ||||||||
R15 | I/OポートB |
- WRTPSG (0093H/MAIN)
機能 |
PSGレジスタへデータを書き込みます。
コール手順 |
A | PSGのレジスタ番号 |
E | 書き込むデータ |
戻り値 |
なし
変更レジスタ |
解説 |
- RDPSG (0096H/MAIN)
機能 |
PSGレジスタのデータを読み出します。
コール手順 |
A | PSGのレジスタ番号 |
戻り値 |
A | 指定したレジスタの内容 |
変更レジスタ |
なし
解説 |
- STRTMS (0099H/MAIN)
機能 |
音楽の演奏を開始します。
コール手順 |
(QUEUE) 中間言語に変換されたMML
戻り値 |
なし
変更レジスタ |
解説 |
実際のアクセスについては、「第2部 6.1 PLAY文BIOS」を参照して下さい。
1.3 1ビットサウンドポートによる音声発生機能
MSXには、PSGのほかにもうひとつ音源が存在しています。これは1ビットのI/Oポートの出力をソフトで繰り返しON/OFFして音を出すというものです。
1.4 1ビットサウンドポートのアクセス
この1ビットサウンドポートをアクセスするために、以下のようなBIOSルーチンが用意されています。
- CHGSND (0135H/MAIN)
機能 |
1ビットサウンドポートをアクセスします。
コール手順 |
A | ON/OFF指定 | |
0 | OFF | |
1 | ON |
戻り値 |
なし
変更レジスタ |
解説 |