* YMF-262 [#top]
Sound Blaster Pro II 以降に搭載されているFM音源チップです。~
DOSや自作系OS用のアプリを作成するための資料として整理中(自分用)。~
#freeze
* YMF262 [#top]
Sound Blaster Pro II など に搭載されているFM音源ICです。~
たぶん互換性があるであろう Sound Blaster 16 やそのエミュレータなどでも使用できる可能性があります。~
残念ながらqemuでは4オペレータや18チャネルステレオ対応の音源としては使えないようです。~
DOSや自作系OS用のアプリを作成するための資料として自分用に整理中。~
~
''(以下書きかけです。間違っていたり誤記がある可能性があります)''
** 内部レジスタマップ [#registermap]
|アドレス&br;(hex)|>|>|>|>|>|>|>|1つ目||>|>|>|>|>|>|>|2つ目|
** スペック [#spec]
-同時発音数の例
--''2オペレータ18チャネル''&br;すべて2オペレータで使用する場合。
--''2オペレータ15チャネル+リズム5チャネル''&br;7~9チャネルをリズムで使用。
--''4オペレータ6チャネル+2オペレータ6チャネル''&br;7~9チャネルと16~18チャネルは4オペレータにできない。
--''4オペレータ6チャネル+2オペレータ3チャネル+リズム5チャネル''&br;7~9チャネルをリズムで利用。&br;16~18チャネルは4オペレータにできない。
--''4オペレータ2チャネル+2オペレータ14チャネル''&br;仕様を見る限りこういう利用も可能のようだ。しかし、対応したライブラリが無いとチャネルの管理が大変そう。
-[[wikipediaのFM音源ページのOPL3:http://ja.wikipedia.org/wiki/FM%E9%9F%B3%E6%BA%90#OPL.E7.B3.BB]]のところにはリズム10chとあるが、詳細不明。セカンダリの16~18チャネルも実はリズムとして利用できるのだろうか。
~
** I/Oアドレスマップ [#ioadddressmap]
|サウンドカード|ベースポート|
|LEFT:Sound Blaster Pro II   |LEFT:220h または 240h など(選択可)|
|LEFT:AdLib Gold             |LEFT:388h|
※Sound Blaster Pro I など は YMF262では無く FM1812 が2つ使用されているそうです。~
  その場合、ベース+0~+1とベース+2~+3は両方ともFM1812のレジスタマップとなり2オペレータ18チャネル(ステレオだが左右独立で左9チャネル+右9チャネル)のみ利用可能と思われます。~
~
|I/Oポート番号|アクセス|ポートの意味|
|ベース+0|R|LEFT:ステータスレジスタ|
|~|W|LEFT:プライマリ インデックスレジスタ|
|ベース+1|W|LEFT:プライマリ データレジスタ|
|ベース+2|W|LEFT:セカンダリ インデックスレジスタ|
|ベース+3|W|LEFT:セカンダリ データレジスタ|
※Sound Blaster では ベース+8~+9(228h~229hなど) でプライマリのレジスタがアクセスできるが、ベース+10~+11(22Ah~22Bh)からセカンダリのレジスタにはアクセスできない(らしい)。~
  その場合、ベース+8〜+9がモノラル出力用、ベース+0〜+1が左音声用、ベース+2〜+3が右音声用となるようです(なんでこんな仕様になっているんだろう)。~
~
** レジスタマップ [#registermap]
-ステータスレジスタ (ベース+0)
|b7|b6|b5|b4|b3|b2|b1|b0|
|IRQ|TF1|TF2|>|-|>|0|-|
~
-データレジスタ (プライマリはベース+1,セカンダリはベース+3)
|アドレス&br;(hex)|>|>|>|>|>|>|>|プライマリ||>|>|>|>|>|>|>|セカンダリ|
|~|b7|b6|b5|b4|b3|b2|b1|b0||b7|b6|b5|b4|b3|b2|b1|b0|
|01h|>|>|>|>|>|>|>|LSI TEST||>|-|>|>|>|>|>|LSI TEST|
|~|>|-|WM|>|>|>|>|-||>|~|>|>|>|>|>|~|
|02h|>|>|>|>|>|>|>|TIMER 1||>|>|>|>|>|>|>|-|
|03h|>|>|>|>|>|>|>|TIMER 2||>|>|>|>|>|>|>|-|
|04h|RST|MT1|MT2|>|>|-|ST2|ST1||>|-|>|>|>|>|>|4 OPERATOR MODE|
|~|~|~|~|~|~|~|~|~|~|~|~|12|11|10|3|2|1|
|05h|>|>|>|>|>|>|>|-||>|>|>|>|>|>|-|NEW|
|05h|>|>|>|>|>|>|>|-||>|>|>|>|>|>|-|OPL3|
|08h|-|NTS|>|>|>|>|>|-||>|>|>|>|>|>|>|-|
|20-35|AM|VB|EGT|KSR|>|>|>|MULTI||AM|VB|EGT|KSR|>|>|>|MULTI|
|40-55|>|KSL|>|>|>|>|>|TL||>|KSL|>|>|>|>|>|TL|
|60-75|>|>|>|AR|>|>|>|DR||>|>|>|AR|>|>|>|DR|
|80-95|>|>|>|SL|>|>|>|RR||>|>|>|SL|>|>|>|RR|
|A0-A8|>|>|>|>|>|>|>|Freq Number(L)||>|>|>|>|>|>|>|Freq Number(L)|
|B0-B8|>|-|KON|>|>|BLOCK|>|FNum(H)||>|-|KON|>|>|BLOCK|>|FNum(H)|
|BD|DAM|DVB|RYT|BD|SD|TOM|TC|HH||>|>|>|>|>|>|>|-|
|C0-C8|>|>|>|CH|>|>|FB|CNT||>|>|>|CH|>|>|FB|CNT|
|~|D|C|B|A|~|~|~|~||D|C|B|A|~|~|~|~|
|BD|TD|VD|PM|BD|SD|TOM|TC|HH||>|>|>|>|>|>|>|-|
|C0-C8|>|>|>|CH OUT|>|>|FeedBack|CNT||>|>|>|CH OUT|>|>|FeedBack|CNT|
|~|-|-|R|L|~|~|~|~||-|-|R|L|~|~|~|~|
|E0-F5|>|>|>|>|-|>|>|WS||>|>|>|>|-|>|>|WS|
|~|b7|b6|b5|b4|b3|b2|b1|b0||b7|b6|b5|b4|b3|b2|b1|b0|
|アドレス&br;(hex)|b7|b6|b5|b4|b3|b2|b1|b0||b7|b6|b5|b4|b3|b2|b1|b0|
|~|>|>|>|>|>|>|>|プライマリ||>|>|>|>|>|>|>|セカンダリ|
~
** スロットの配置 [#signalmap]
-2オペレータモード
|チャネル|コントロールポート|スロット|スロットポート|
|1|A0 B0 C0|1|20 40 60 80 E0|
|~|~|4|23 43 63 83 E3|
|2|A1 B1 C1|2|21 41 61 81 E1|
|~|~|5|24 44 64 84 E4|
|3|A2 B2 C2|3|22 42 62 82 E2|
|~|~|6|25 45 65 85 E5|
|4|A3 B3 C3|7|28 48 68 88 E8|
|~|~|10|2B 4B 6B 8B EB|
|5|A4 B4 C4|8|29 49 69 89 E9|
|~|~|11|2C 4C 6C 8C EC|
|6|A5 B5 C5|9|2A 4A 6A 8A EA|
|~|~|12|2D 4D 6D 8D ED|
|7|A6 B6 C6|13|30 50 70 90 F0|
|~|~|16|33 53 73 93 F3|
|8|A7 B7 C7|14|31 51 71 91 F1|
|~|~|17|34 54 74 94 F4|
|9|A8 B8 C8|15|32 52 72 92 F2|
|~|~|18|35 55 75 95 F5|
|1,10|A0 B0 C0|1,19|20 40 60 80 E0|
|~|~|4,22|23 43 63 83 E3|
|2,11|A1 B1 C1|2,20|21 41 61 81 E1|
|~|~|5,23|24 44 64 84 E4|
|3,12|A2 B2 C2|3,21|22 42 62 82 E2|
|~|~|6,24|25 45 65 85 E5|
|4,13|A3 B3 C3|7,25|28 48 68 88 E8|
|~|~|10,28|2B 4B 6B 8B EB|
|5,14|A4 B4 C4|8,26|29 49 69 89 E9|
|~|~|11,29|2C 4C 6C 8C EC|
|6,15|A5 B5 C5|9,27|2A 4A 6A 8A EA|
|~|~|12,30|2D 4D 6D 8D ED|
|7,16|A6 B6 C6|13,31|30 50 70 90 F0|
|~|~|16,34|33 53 73 93 F3|
|8,17|A7 B7 C7|14,32|31 51 71 91 F1|
|~|~|17,35|34 54 74 94 F4|
|9,18|A8 B8 C8|15,33|32 52 72 92 F2|
|~|~|18,36|35 55 75 95 F5|
~
-4オペレータモード
|チャネル|コントロールポート|スロット|スロットポート|
|1|A0 B0 C0 C3|1|20 40 60 80 E0|
|~|~|4|23 43 63 83 E3|
|~|~|7|28 48 68 88 E8|
|~|~|10|2B 4B 6B 8B EB|
|2|A1 B1 C1 C4|2|21 41 61 81 E1|
|~|~|5|24 44 64 84 E4|
|~|~|8|29 49 69 89 E9|
|~|~|11|2C 4C 6C 8C EC|
|3|A2 B2 C2 C5|3|22 42 62 82 E2|
|~|~|6|25 45 65 85 E5|
|~|~|9|2A 4A 6A 8A EA|
|~|~|12|2D 4D 6D 8D ED|
|1,10|A0 B0 C0 C3|1,19|20 40 60 80 E0|
|~|~|4,22|23 43 63 83 E3|
|~|~|7,25|28 48 68 88 E8|
|~|~|10,28|2B 4B 6B 8B EB|
|2,11|A1 B1 C1 C4|2,20|21 41 61 81 E1|
|~|~|5,23|24 44 64 84 E4|
|~|~|8,26|29 49 69 89 E9|
|~|~|11,29|2C 4C 6C 8C EC|
|3,12|A2 B2 C2 C5|3,21|22 42 62 82 E2|
|~|~|6,24|25 45 65 85 E5|
|~|~|9,27|2A 4A 6A 8A EA|
|~|~|12,30|2D 4D 6D 8D ED|
~
-パーカッションモード~
プライマリデータレジスタBDhのビット5を立てると7~9チャネル(13~18スロット)をパーカッションモードで使用する。~
パーカッションの発音はBDhを使用し、チャネル7~9には適切な音色データを書き込み常に消音状態にしておく。~
|チャネル|スロット|楽器|
|7|13|LEFT:バスドラム|
|~|16|~|
|8|14|LEFT:ハイハット|
|~|17|LEFT:スネアドラム|
|9|15|LEFT:タムタム|
|~|18|LEFT:シンバル|
~
※4オペレータモードと2オペレータモードとパーカッションモードは混在可~
~
** 値の意味
-ステータスレジスタ
|ビット|仮名称|仮名称|意味|
|b7|IRQ|割り込み要因フラグ|LEFT:割り込み要因が発生しているとフラグが立つ&br;レジスタ4に80hを書き込むとこのフラグがリセットされる&br;(PCの場合、割り込み要因が発生することがあっても実際の割り込みが発生することはない)|
|b6|TF1|タイマー1フラグ|LEFT:タイマーカウンタに書き込んだ時間が経つとこのフラグが毎回立つ&br;レジスタ4に0x40や0x20を書き込むとマスク(リセット?)できる|
|b5|TF2|タイマー2フラグ|~|

-データレジスタ
|アドレス&br;(hex)|>|>|>|LEFT:レジスタ名|
|~|ビット|仮名称|仮名称|LEFT:意味|
|01|>|>|>|LEFT:テストレジスタ/波形選択モード|
|~|b5|WM|波形選択モード|LEFT:フラグを立てるとスロット毎に波形を変更できる|
|02|>|>|>|LEFT:タイマー1カウントレジスタ|
|~|b7-0|TIMER1|タイマー1カウント|LEFT:80μ秒単位のカウント値|
|03|>|>|>|LEFT:タイマー2カウントレジスタ|
|~|b7-0|TIMER2|タイマー2カウント|LEFT:320μ秒単位のカウント値|
|04|>|>|>|LEFT:割り込み/タイマーマスクレジスタ(プライマリ)|
|~|b7|RST|IRQリセット|LEFT:フラグを立てて書き込むと割り込み要因をクリアする&br;※このフラグを立てると他のフラグは無効となる|
|~|b6|MT1|タイマー1マスク|LEFT:フラグを立てるとタイマー1をマスクする|
|~|b5|MT2|タイマー2マスク|LEFT:フラグを立てるとタイマー2をマスクする|
|~|b1|ST2|タイマー2スタート|LEFT:フラグを立てるとタイマー2がカウントする|
|~|b0|ST1|タイマー1スタート|LEFT:フラグを立てるとタイマー1がカウントする|
|04|>|>|>|LEFT:4オペレータモードチャネル設定(セカンダリ)|
|~|b5|>|4 OPERATOR MODE|LEFT:チャネル12を4オペレータモードにする|
|~|b4|~|~|LEFT:チャネル11を4オペレータモードにする|
|~|b3|~|~|LEFT:チャネル10を4オペレータモードにする|
|~|b2|~|~|LEFT:チャネル3を4オペレータモードにする|
|~|b1|~|~|LEFT:チャネル2を4オペレータモードにする|
|~|b0|~|~|LEFT:チャネル1を4オペレータモードにする|
|05|>|>|>|LEFT:OPL3モードフラグ(セカンダリ)|
|~|b0|OPL3|OPL3|LEFT:フラグを立てるとOPL3モードになり以下が有効になる&br;・10~18チャネル&br;・4オペレータモード&br;・波形選択のモード4~7&br;・各チャネル独立のステレオ出力設定|
|08|>|>|>|LEFT:音声合成モード/キーボードスプリットレジスタ|
|~|b7|CSW|-|LEFT:フラグを立てるとサイン波合成モードになる(詳細不明)|
|~|b6|NTS|セレクト|LEFT:キーボードスプリット選択ビットの設定&br;=0:Freq Number の ビット8&br;=1:Freq Number の ビット9(MSB)|
|20~35|>|>|>|LEFT:スロットレジスタ1|
|~|b7|>|AM|LEFT:トレモロのOn/Off|
|~|b6|>|VB|LEFT:ビブラートのOn/Off|
|~|b5|>|EGT|LEFT:発音モード&br;=0: 減退音&br;=1: 持続音|
|~|b4|>|KSR|LEFT:キースケールレート|
|~|b3-b0|>|MULTI|LEFT:マルチプル|
|40~55|>|>|>|LEFT:スロットレジスタ2|
|~|b7-b6|>|KSL|LEFT:キースケールレベル|
|~|b5-b0|>|TL|LEFT:トータルレベル(減衰量)|
|60~75|>|>|>|LEFT:スロットレジスタ3|
|~|b7-b4|>|AR|LEFT:アタックレート|
|~|b3-b0|>|DR|LEFT:デュケイレート|
|80~95|>|>|>|LEFT:スロットレジスタ4|
|~|b7-b4|>|SL|LEFT:サスティンレベル|
|~|b3-b0|>|RR|LEFT:リリースレート|
|A0-A8|>|>|>|LEFT:チャネルレジスタ1|
|~|b7-b0|>|F-Num|LEFT:Freq Numberの下位8ビット|
|B0-B8|>|>|>|LEFT:チャネルレジスタ2|
|~|b5|>|KON|LEFT:発音のOn/Off|
|~|b4-b2|>|BLOCK|LEFT:BLOCK(オクターブ指定)|
|~|b1-b0|>|F-Num|LEFT:Freq Numberの上位2ビット|
|BD|>|>|>|LEFT:変調度とパーカッション(プライマリ)|
|~|b7|>|TD|LEFT:トレモロの深さ&br;=0:1dB&br;=1:4.8dB|
|~|b6|>|VD|LEFT:ビブラートの深さ&br;=0:7セント&br;=1:14セント|
|~|b5|>|PM|LEFT:パーカッションモード|
|~|b4|>|BD|LEFT:バスドラム|
|~|b3|>|SD|LEFT:スネアドラム|
|~|b2|>|TOM|LEFT:タムタム|
|~|b1|>|TC|LEFT:トップシンバル|
|~|b0|>|HH|LEFT:ハイハット|
|C0-C8|>|>|>|LEFT:チャネルレジスタ3|
|~|b7-b4|>|CH OUT|LEFT:チャネル出力先の設定&br;b4=1:左音声に出力&br;b5=1:右音声に出力|
|~|b3-b1|>|FeedBack|LEFT:フィードバックの設定|
|~|b0|>|CNT|LEFT:コネクション(アルゴリズム)の設定|
|E0-F5|>|>|>|LEFT:スロットレジスタ5|
|~|b2-b0|>|WS|LEFT:波形番号|
~
--減衰音と持続音
|#ref(egtp0.png)|#ref(egtp1.png)|
|減衰音|持続音|
~
--マルチプルの変化
|MULTI|0|1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|
|実際の値|1/2|1|2|3|4|5|6|7|8|9|10|10|12|12|15|15|
~
--キースケールレートの変化
|KSR|>|>|>|>|>|>|>|>|>|>|>|>|>|>|>|キースケール番号|
|~|0|1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|
|0|0|1|2|3|4|5|6|7|8|9|10|11|12|13|14|15|
|1|0|0|0|0|1|1|1|1|2|2|2|2|3|3|3|3|
~
--フィードバックの変調度
|FeedBack|0|1|2|3|4|5|6|7|
|実際の値|0|1/16π|1/8π|1/4π|1/2π|π|2π|4π|
~
--標準的な Freq Number の値の例 (オクターブ4)
|音程|C#|D|D#|E|F|F#|G|G#|A|A#|B|C|
|周波数(Hz)|277.2|293.7|311.1|329.6|349.2|370.0|392.0|415.3|440.0|466.2|493.9|523.4|
|F-Num|363|385|408|432|458|485|514|544|577|611|647|686|
~
--パーカッションの推奨設定値
|チャネル|オペレータ|音色名|方式|>|>|>|>|>|>|>|>|>|>|>|>|>|設定値|
|~|~|~|~|AM|VB|EGT|KSR|MULTI|KSL|TL|AR|DR|SL|RR|WS|BLOCK|F-Num|
|7|1|バスドラム|FM|0|0|0|0|1|0|0|13|5|6|9|0|2|577|
|~|2|~|~|0|0|0|0|1|0|0|15|8|6|2|0|~|~|
|8|1|ハイハット|ノイズ|0|0|0|0|1|0|0|12|8|0|8|0|2|672|
|~|2|スネアドラム|ノイズ|0|0|0|0|1|0|0|13|8|4|8|0|~|~|
|9|1|タムタム|サイン波|0|0|0|0|5|0|0|15|8|5|7|0|0|896|
|~|2|トップシンバル|ノイズ|0|0|0|0|1|0|0|10|0|5|4|0|~|~|
~
** アルゴリズムの種類 [#connectmode]
-2オペレータモード
|CNT|アルゴリズム|図|
|0|RIGHT:Op.1 → Op.2 →||
|1|RIGHT:Op.1 →&br;Op.2 →||
|CNT|モード|アルゴリズム (→出力)|図|
|0|FM|RIGHT:Op.1 → Op.2 →||
|1|AM|RIGHT:Op.1 →&br;Op.2 →||
~
-4オペレータモード
|>|CNT|アルゴリズム|図|
|+0|+3|~|~|
|0|0|RIGHT:Op.1 → Op.2 → Op.3 → Op.4 →||
|0|1|RIGHT:Op.1 → Op.2 →&br;Op.3 → Op.4 →||
|1|0|RIGHT:Op.1 →&br;Op.2 → Op.3 → Op.4 →||
|1|1|RIGHT:Op.1 →&br;Op.2 → Op.3 →&br;Op.4 →||
|>|CNT|モード|アルゴリズム (→出力)|図|
|+0|+3|~|~|~|
|0|0|FM-FM|RIGHT:Op.1 → Op.2 → Op.3 → Op.4 →||
|1|0|AM-FM|RIGHT:Op.1 →&br;Op.2 → Op.3 → Op.4 →||
|0|1|FM-AM|RIGHT:Op.1 → Op.2 →&br;Op.3 → Op.4 →||
|1|1|AM-AM|RIGHT:Op.1 →&br;Op.2 → Op.3 →&br;Op.4 →||
~
※両モードともOp.1のみセルフフィードバック可~
~
** テストモードと波形 [#waveselect]
-2オペレータモード
|WS|波形|WS|波形|
|0|#ref(w0.png)|2|#ref(w2.png)|
|1|#ref(w1.png)|3|#ref(w3.png)|
WMに1を書き込むと使用可。

//|WS|波形|WS|波形|
//|0|#ref(w0.png)|4|#ref(w4.png)|
//|1|#ref(w1.png)|5|#ref(w5.png)|
//|2|#ref(w2.png)|6|#ref(w6.png)|
//|3|#ref(w3.png)|7|#ref(w7.png)|
|波&br;形|#ref(w0.png)|#ref(w1.png)|#ref(w2.png)|#ref(w3.png)|
|WS|0|1|2|3|
|波&br;形|#ref(w4.png)|#ref(w5.png)|#ref(w6.png)|#ref(w7.png)|
|WS|4|5|6|7|

~
-4オペレータモード
|WS|波形|WS|波形|
|0|#ref(w0.png)|4|#ref(w4.png)|
|1|#ref(w1.png)|5|#ref(w5.png)|
|2|#ref(w2.png)|6|#ref(w6.png)|
|3|#ref(w3.png)|7|#ref(w7.png)|
** FM1812の存在チェック方法
AdLib公式のOPL2存在チェック方法:
+''タイマ1とタイマ2をリセット''&br; レジスタ4に60hを書き込む
+''IRQをリセット''&br; レジスタ4に80hを書き込む&br; 注: IRQとタイマを同時にリセットすることは出来ない
+''ステータスレジスタを読む''&br; ベース+0のポートを読み込んでその値を取っておく
+''タイマ1をFFhにセット''&br; レジスタ2にFFhを書き込む
+''マスクを解除してタイマのカウントをスタート''&br; レジスタ4に21hを書き込む
+''ウェイト''&br; デュレイルーチンなどで最低でも80μ秒の間待機
+''ステータスレジスタを再度読む''&br; ベース+0のポートを読み込み、その値を取っておく
+''タイマ1とタイマ2、そしてIRQを1.や2.と同じようにリセット''
+''読み込んだ2つのステータスレジスタの値のテスト''&br; 1つ目の値は「0」で2つ目の値は「C0h」で無ければ、OPL2は存在しません。

※1: ステータスレジスタの値をE0hでANDして未使用のビットをマスクした方が良いかも知れません。~
※2: いくつかのSound Blaster互換のカードでは動作しないかも知れません。~
~
※WMに1を書き込んだ時のみ有効~
** YMF-262の存在チェック方法
-リザーブビット(?)で判別する方法
+''OPL2が存在することを確認''
+''ステータスレジスタを読む''&br; ベース+0のポートを読み込む。
+''その値を06hでマスク(AND)する''
+''マスクした値が「0」ならばOPL3、そうでなければOPL2です。''

~
** FM1812の存在チェック方法
** YMF-262の存在チェック方法
※Sound Blaster互換のカードでは動作しないかも知れません。

~
-セカンダリレジスタで判別する方法
+''プライマリレジスタが存在することを確認''
+''セカンダリレジスタにも同じチェックをする''&br; プライマリのステータスレジスタでは無くセカンダリのステータスレジスタを読み込んでみる
+''2つのセカンダリ ステータスレジスタの値をチェックする''&br; FM1812を2個搭載している場合、タイマーがプライマリとセカンダリの両方に存在するため、同じ結果に%%なります%%なるそうです。&br; 同じ結果になった場合、4オペレータでは使用できないことになります。


** 4オペレータモードへの切り替え方法
OPL3に1を書き込み4 OPERATER MODEに対応するチャネルのビットを立てて書き込みます。~
チャネル1~3,10~12を4オペレータモードにするとチャネル4~6,13~15がチャネル1~3,10~12のオペレータの一部になり、チャネル4~6,13~15は使用できなくなります。~

~

** コメント欄 [#commentarea]
ご意見やご批判などお待ちしております。~
また、スパムなどは無条件で対処させていただきます。
----
#comment


[リロード]   [トップ] [一覧] [単語検索] [最終更新]   [最終更新のRSS]