YM2203のレジスタ設定(FM音源編)

前回に続き、今回はFM音源の設定についてまとめます。


※ まだ実機検証してないので、内容の正確性は一切保証いたしません。

レジスタマップ概要

レジスタマップ

表記について

表記を簡単にするため、レジスタ値については、@アドレス でそのアドレスの値とします。またレジスタ値の表記では、[ビット番号]で特定の1ビットを表し、[MSB:LSB] の形でビットの範囲を表すことにします。たとえば、 @06h[4:0] は06h番地のビット0〜ビット4の5ビット値を示します。

タイマ周期と制御

プロセッサへの割り込みを生成するタイマの設定です。タイマAは短い周期の割り込みに、タイマBは長い周期の割り込みに適しています。

タイマAの周期


TA = 72 * (1024 - NA) / φM
 TA: タイマAの周期
 φM: マスタークロック
 NA = (@24h[7:0] << 2) + @25h[1:0]

タイマBの周期


TB = 1152 * (256 - NB) / φM
 TB: タイマBの周期
 φM: マスタークロック
 NB = @26h[7:0]

タイマの制御


@27h[0]: タイマAのスタート(1) / ストップ(0)
@27h[1]: タイマBのスタート(1) / ストップ(0)
@27h[2]: タイマAのオーバーフローでの割り込みを 有効(1) / 無効(0) にする。
@27h[3]: タイマBのオーバーフローでの割り込みを 有効(1) / 無効(0) にする。
@27h[4]: 1を書くとタイマAの割り込みフラグがクリアされる。(このビットは即座に0に戻る。)
@27h[5]: 1を書くとタイマBの割り込みフラグがクリアされる。(このビットは即座に0に戻る。)

チャンネル3のモード

チャンネル3のみ、特別なモードを持ちます。そのモードを設定します。

@27h[7:6] モード 動作
00 通常モード 他のチャンネルと同様の発声。
01 音声合成モード CSM音声合成のモード。
4個のオペレータの周波数を独立に設定できる。
また、キーオン/キーオフはタイマAを用いておこなう。
1X 効果音モード 4個のオペレータの周波数を独立に設定できる。

キーオン/キーオフ

指定したチャンネルのキーオン/キーオフ、つまり発声のオン/オフをおこないます。またこのとき、4つのオペレータを独立にオン/オフできます。

チャンネルの指定


@28h[1:0] == 00: チャンネル1
@28h[1:0] == 01: チャンネル2
@28h[1:0] == 10: チャンネル3

オペレータごとのオン/オフ


@28h[4]: オペレータ1の オン(1) / オフ(0)
@28h[5]: オペレータ2の オン(1) / オフ(0)
@28h[6]: オペレータ3の オン(1) / オフ(0)
@28h[7]: オペレータ4の オン(1) / オフ(0)

マスタークロックのプリスケーラ

マスタークロックのプリスケーラの分周比を設定します。ここに関してだけは、特定のアドレス値を書き込むだけで設定されます。したがってデータの書き込みはありません。リセット時はFM音源の分周比は1/6、PSG音源の分周比は1/4です。

アドレス FM音源の分周比 PSG音源の分周比
2Dh
1/6
1/4
2Dh, 2Eh
1/3
1/2
2Fh
1/2
1/1
※ ただし、一度FM音源の分周比を1/3に設定すると、リセットしない限り1/6には戻せないようです。(未検証)

チャンネル・オペレータごとの設定

以下に述べる、Detune, Multiple, Total Level, Attack Rate, Decay Rate, Sustain Rate, Sustain Level, Release Rate, Key Scale, SSG Envelope の各パラメータは、各チャンネル・各オペレータごとに独立して設定できます。チャンネルは3個、オペレータは各チャンネルに4個ずつあるので、各パラメータには3×4=12個の設定値があり、それぞれに別個のアドレスのレジスタに置かれています。
各設定値のベースアドレスと、各チャンネル・各オペレータのオフセットアドレスは次の通りです。この記事の最初に載せたレジスタマップも合わせて参照してください。
レジスタアドレス表

Detune(周波数のデチューン)

後述する周波数設定からのわずかなズレを設定します。


Detune = @(30h+オフセット)[6:4]
Detune
※1 音階のオクターブに相当します。(後述)
※2 オクターブ内の音程の上位2ビットに相当します。

Multiple(周波数の倍率)

後述する周波数設定からの倍率を設定します。


Multiple = @(30h+オフセット)[3:0]
Multiple

Total Level(音量)

出力レベルすなわち音量を設定します。音量は、7ビットの設定値に比例した減衰量(デシベル表記)で設定されます。つまり、設定値=0のとき音量は最大値の0dBとなり、設定値=127のとき音量は最小の-95.25dBとなります。


TL = @(40h+オフセット)[6:0]
Total level

Attack Rate

エンベロープパラメータのAttack Rate(AR)を設定します。ARは5ビットの値でキーオンからの立ち上がりの傾きを表します。AR=31のとき傾きは最大となり、AR=0のとき傾きは0となってエンベロープは立ち上がりません。


AR = @(50h+オフセット)[4:0]

Decay Rate

エンベロープパラメータのDecay Rate(DR)を設定します。DRは5ビットの値で最大音量からの減衰の傾きを表します。DR=31のとき傾きは最大となり、DR=0のとき傾きは0(水平)となります。


Decay Rate = @(60h+オフセット)[4:0]

Sustain Rate

エンベロープパラメータのSustainRate(SR)を設定します。SRは5ビットの値で持続音の減衰の傾きを表します。SR=31のとき傾きは最大となり、SR=0のとき傾きは0(水平)となって持続音を減衰させずに維持します。


Sustain Rate = @(70h+オフセット)[4:0]

Sustain Level

エンベロープパラメータのSustain Level(SL)を設定します。SLは持続音のレベルを表します。持続音のレベルは、Total Levelからの減衰量で設定されます。設定値=0のとき持続音のレベルは最大値のTotal Level - 0dBとなり、設定値=15のとき音量は最小値のTotal Level - 93dBとなります。


Sustain Level = @(80h+オフセット)[7:4]
Sustain Level

Release Rate

エンベロープパラメータのRelease Rate(RR)を設定します。RRは5ビットの値でキーオフ後の立ち下がりの傾きを表します。RR=31のとき傾きは最大となり、RR=1のとき傾きは最小となります。下の式のように、レジスタ設定じたいは4ビット値であることに注意してください。RR=0だと音が永遠に消えないので、そうならない仕様になっています。


Release Rate = (@(80h+オフセット)[3:0] << 1) + 1

Key Scale

現実の楽器では、高音ほどエンベロープが短くなります。(たとえばピアノの「キンッ」という高音と「ダ〜ン」という低音みたいな?) これを再現するパラメータがKey Scaleです。Key Scaleは2ビットの値で、音程に応じて下の表のようにAR, DR, SR, RRに対する補正値が決まります。


Key Scale = @(50h+オフセット)[7:6]
Key Scale
※1 音階のオクターブに相当します。(後述)
※2 オクターブ内の音程の上位2ビットに相当します。

Rate' = 2 * Rate + Rks
 Rate: AR, DR, SR, RR の各設定値(0〜31)
 Rate': 補正後のAR, DR, SR, RR (0〜63, 63で飽和)
 Rks: Key Scaleによる補正値

SSG Envelope

FM音源のエンペロープ発生器は、これまで述べたようなARSR式のエンベロープ以外に、SSG音源(PSG音源)相当のエンベロープを発生することもできます。このとき、ARSRパラメータは次のような振る舞いになります。

  1. AR: かならず最大値の31に設定してください。
  2. DR, SR, SL: キーオン中のSSG型エンベロープのレベルと傾きを決定します。←?
  3. RR: 通常の場合と同じように、キーオフ後の立ち下がりの傾きを決定します。


SSG Envelope = @(90h+オフセット)[3:0]
SSG Envelope

周波数(音程)

周波数すなわち音程を設定します。設定値BlockおよびF-Numberは、発声したい周波数から次の式で求めます。F-Numberの計算で、f_noteを 2^Block で割っていることに注目してください。1オクターブ上がると周波数は2倍になりますので、同じ音名の音(たとえばC)であればオクターブが異なってもF-Numberは同じになります。つまり、オクターブ内に12の音がある通常の音階であれば、F-Numberは12個の値をテーブルで持てばよいことになります。


F-Number = 144 * f_note * 2^(21-Block) / φM
 f_note: 発声したい周波数
 φM: マスタークロック
 Block: オクターブ指定
 Block[チャンネル1] = @A4h[5:3] >> 3
 Block[チャンネル2] = @A5h[5:3] >> 3
 Block[チャンネル3] = @A6h[5:3] >> 3
 F-Number[チャンネル1] = (@A4h[2:0] << 8) + @A0h[7:0]
 F-Number[チャンネル2] = (@A5h[2:0] << 8) + @A1h[7:0]
 F-Number[チャンネル3] = (@A6h[2:0] << 8) + @A2h[7:0]

音声合成/効果音モード時のチャンネル3の周波数

チャンネル3を音声合成モードまたは効果音モードに設定した場合、4個のオペレータに独立した周波数を設定できます。このとき前項の周波数設定はオペレータ4に適用され、オペレータ1〜3の周波数は本項で設定します。設定値BlockおよびF-Numberの意味は前項の周波数設定と同じです。


Block[オペレータ3] = @ACh[5:3] >> 3
Block[オペレータ1] = @ADh[5:3] >> 3
Block[オペレータ2] = @AEh[5:3] >> 3
F-Number[オペレータ3] = (@ACh[2:0] << 8) + @A8h[7:0]
F-Number[オペレータ1] = (@ADh[2:0] << 8) + @A9h[7:0]
F-Number[オペレータ2] = (@AEh[2:0] << 8) + @AAh[7:0]

フィードバック量

オペレータ1のセルフ・フィードバック量を設定します。各チャンネルでセルフ・フィードバックができるのはオペレータ1のみです。


Feedback[チャンネル1] = @B0h[5:3] >> 3
Feedback[チャンネル2] = @B1h[5:3] >> 3
Feedback[チャンネル3] = @B2h[5:3] >> 3
フィードバック

アルゴリズム

アルゴリズムを設定します。ここでいうアルゴリズムとは4個のオペレータの接続パターンのことです。


Algorithm[チャンネル1] = @B0h[2:0]
Algorithm[チャンネル2] = @B1h[2:0]
Algorithm[チャンネル3] = @B2h[2:0]
Algorithmの値とオペレータの接続パターンの対応は下図のようになります。
アルゴリズム

参考文献