FM音源 OPPのレジスタ解析

はじめに

YM2164(OPP)はYM2151(OPM)の後継と言われているが、チップの詳細情報がメーカーから公開されていないため、どのような機能拡張がなされたか一般に明らかになっていない。
OPN系は主にFM以外の部分で機能追加されていったことに対し、OPM系はFMそのものの機能が向上している。そういった意味でOPM系の進化への関心は高い。

今回、OPPのレジスタマップを調べるために、OPPを搭載しているシンセサイザーFB-01の、システムROMの解析を行った。 FB-01の保守用マニュアルの回路図には、確かにYM2164・OPPと記載されていたので、OPP搭載で間違いないようである。 (2013.04.13; 2013.04.25修正)

FB-01のボイスパラメータ

取扱説明書を参照し、FB-01のボイスパラメータを眺めてみると、OPMと共通と考えられるパラメータが多い。 レジスタに書き込む生のデータがそのままの形で格納されているように見える。

以下、ボイスパラメータから、OPMからの機能拡張に関係しそうなパラメータに着目し、それぞれどのようにOPPへ出力しているか詳細を見ていく。
表の赤文字が着目するパラメータである。OPMのレジスタと対応するパラメータにはレジスタのアドレスを付けた。

アドレス$11,$12のデータに相当するレジスタを追加するとなると、これだけで64個のレジスタを消費するはずだが、 明らかにOPMの未使用レジスタが不足する。 また、アドレス$09,$0aのデータに関して、OPMのレジスタ$19の最上位ビットはAMDとPMDのフラグにすでに使用されている。 一体どうなっているのか??

(チャンネル単位のパラメータ)

アドレスビットパラメータOPM reg
00~06 VOICE NAME
07**** ****USER'S CODE
08**** ****LFO SPEED18
09E--- ----
-AAA AAAA
ENABLE TO LOAD LFO DATA
AMPLITUDE MODULATION DEPTH
19
0aS--- ----
-PPP PPPP
LFO SYNC
PITCH MODULATION DEPTH
19
0b-OOO O---ENABLE OPERATOR08
0cL--- ----
-R-- ----
--FF F---
---- -AAA
LEFT OUTPUT ENABLE
RIGHT OUTPUT ENABLE
FEEDBACK LEVEL
ALGORITHM
20-27
0d-PPP ----
---- --AA
PITCH MODULATION SENSITIVITY
AMPLITUDE MODULATION SENSITIVITY
38-3f
0e-WW- ----LFO WAVE FORM1b
0fTTTT TTTTTRANSPOSE

(オペレータ単位のパラメータ)
各オペレータのアドレス…Op1:10~17/Op2:18~1f/Op3:20-27/Op4:28-2f

アドレスビットパラメータOPM reg
10-LLL LLLLTOTAL LEVEL60-7f
11K--- ----
-VVV ----
KEYBOARD SCALING LEVEL TYPE BIT0
VELOCITY SENSITIVITY FOR TL
??
12LLLL ----
---- AAAA
KEYBOARD SCALING LEVEL DEPTH
ADJUST FOR TL
??
13K--- ----
-DDD ----
---- FFFF
KEYBOARD SCALING LEVEL TYPE BIT1
DETUNE
FREQUENCY
40-5f
14RR-- ----
---A AAAA
KEYBOARD SCALING RATE DEPTH
ATTACK RATE
80-9f
15F--- ----
-VV- ----
---D DDDD
MODULATOR/CARRIER FLAG
VELOCITY SENSITIVTY FOR AR
DECAY1 RATE
a0-bf
16II-- ----
---S SSSS
INHARMONIC FREQUENCY
DECAY2 RATE
c0-df
17LLLL ----
---- RRRR
SUSTAIN LEVEL
RELEASE RATE
e0-ff

各パラメータの値がどのように処理され、チップのレジスタに書き込まれるか、調べた結果は以下のとおり。

Enable to Load LFO Data

LFOを使用するかどうかを設定するパラメータ(0,1)。

値が0の場合は何もせず、値が1の場合に$18 LFRQ, $19 PMD/AMD, $1b CT/W のレジスタにデータを書き込んでいる。

LFO Sync

キーオン時にLFOの位相をリセットするかどうかを設定するパラメータ(0,1)。

このパラメータが1の場合、キーオン時、$08 KONのレジスタに書き込む直前に、 $09のレジスタに値$02, $00を続けて書き込んでいた。
OPMのレジスタ$01の機能がレジスタ$09に移動している。

$09: [---- --S-] LFO SYNC

Adjust for TL

TLを微調整するためのパラメータ(0〜15)。

TLのレジスタに値を書き込む際に、この値を加算している。
0〜$0fの4bitの値をTLに加算し、最大値$7fでクリップしている。

Velocity Sensitivity for TL

鍵盤を弾く強さ(ベロシティ)に応じてTLの値を増減する度合いを設定するパラメータ(0〜7)。

チップの機能ではなく、ソフトウェアにより実現されている。

次のようにしてキーオン時にTLの値を変更している。
ベロシティの入力7bitの値から、下位ビットを切り捨て、上位5bitを取り出す。
VELOCITY SENSITIVITY(0〜7)の設定値と、MODULATOR/CARRIER FLAGの設定値から、変換テーブルを選択する。
テーブルを参照して、ベロシティの上位5bitの値より、TLを増加する値(0〜$2d)を求める。

TL += TABLE[FLAG][SENS][VEL >> 2];
TL = MIN($7f, TL);

Velocity Sensitivity for AR

ベロシティに応じてARの値を増減する度合いを設定するパラメータ(0〜3)。

チップの機能ではなく、ソフトウェアにより実現されている。

次のようにしてキーオン時にARの値を変更している。
ベロシティの入力7bitの値から、下位ビットを切り捨て、上位4bitを取り出す。
テーブルを参照して、ベロシティの上位4bitからARを増減する値(-12~+12)に変換する。
元のATTACK RATEの設定値(0〜$1f)の値に対して、テーブルから求めたの値を加算し、 最大値$1f 最小値2でクリップする。

AR += TABLE[SENS][VEL >> 3];
AR = MIN($1f, AR);
AR = MAX($02, AR);

Keyboard Scaling Level

KEYBOARD SCALING LEVEL DEPTH (0~15)
KEYBOARD SCALING LEVEL TYPE BIT0 (0,1)
KEYBOARD SCALING LEVEL TYPE BIT1 (0,1)
キーコード(音程)に応じてオペレータの出力を増減するためのパラメータ。

チップの機能ではなく、ソフトウェアにより実現されている。

次のようにしてキーオン時にTLの値を変更している。
BIT0,BIT1の値によってテーブルを選択する。
キーコード7bitの上位6bitを使用する。この値(0~$3f)をテーブルによって8bitの値(0〜$ff)に変換する。
さらに、DEPTHの設定値(0〜$f)を掛けて得られた12bitの値から、下位ビットを切り捨て、上位6bitの値を取り出す。
この値をTLに加算する。

TL += (TABLE[BIT1][BIT0][KC >> 1] * DEPTH) >> 6;
TL = MIN($7f, TL);

その他

アドレス$0eのLFO WAVE FORMパラメータは、OPMのレジスタ$1bのWとビットの位置が異なっていることが気になったが、 同じビットの位置にシフトして書き込んでいた。

アドレス$15のMODULATOR/CARRIER FLAGパラメータは、OPMのレジスタ$a0のAMS-ENにそのまま書かれていた。 キャリアのオペレータがAMの対象に固定されている。

ボイスパラメータ以外に関して、 モジュレーションホイール、ブレスコントロール、フットコントローラ、アフタータッチでは、 コントロールチェンジのMIDIイベントの値(0~$7f)をPMDのレジスタに書き込んでいる。 ピッチモジュレーションの深さを変更している。

OPPで変更されたレジスタ

$09 LFO SYNCのレジスタが$01から移動されたのを確認できたのみで、 その他の機能差はソフトウェアによって実現されていることがわかった。

OPZのレジスタを解析した結果より、OPPの時点でレジスタ$00〜$07の役割を変更するためにレジスタ$01を$09へ移動したと推測する。FB-01ではレジスタ$00〜$07には初期化時に同じ値($10)を書き込むのみであるが、このことからも$00〜$07は同じ役割のレジスタであり、OPZと同じチャンネルボリュームのレジスタと見てよさそうである。

OPPで変更されたレジスタマップの差分を記述する。

$00-$07: [-VVV VVVV] Channel Volume
$09: [---- --S-] LFO SYNC