APU (Audio Processing Unit)
_
|
エンベロープジェネレータは矩形波とノイズチャンネルで愛用し、一定のボリュームや、 ループするのこぎりエンベロープを生成します。これは分周器とカウンタから構成します。 エンベロープは各チャンネルの最初のレジスタで制御します。 ループフラグのビットは、長さカウンタのフラグビットとしても使用していることに注意してください。 1番目のレジスタ --ld nnnn 5 l ループフラグ 4 d エンベロープ無効フラグ 3-0 n エンベロープ周期分周器の周期は n+1 となります。 フレームシーケンサによって励起されるとき、 最後のクロック以降チャンネルの4番目のレジスタへの書き込みがあった場合、 カウンタへ$Fをセットし、分周器へエンベロープ周期をセットします。 そうでなければ、分周器を励起します。 分周器が励起されるとき、カウンタがゼロでなければデクリメントします。 カウンタがゼロで、ループフラグがセットされているならカウンタへ$Fをセットします。 チャンネルのボリューム出力として、 エンベロープ無効フラグがセットされているなら、 エンベロープ周期のnをそのまま出力します。 クリアされているならカウンタの値を出力します。 | ! | 分周器の+1は、セットされる周期に1を加算するわけではなく、 カウンタのリロードが含まれるため、セットされた値+1の周期となる。 |
タイマは全てのチャンネルで出力周波数を決定するために使用します。 タイマは分周器を持っており、約1.789MHzで励起されます。
矩形波と三角波では3番目と4番目のレジスタ、
$4002,$4006,$400A llll llll 7-0 l タイマ周期の下位8ビット $4003,$4007,$400B ---- -hhh 2-0 h タイマ周期の上位3ビットの11ビット値+1の値を分周器の周期とします。
ノイズとDMCはタイマの周期として波長コンバータからの値を使用します。
$400E,$4010 ---- iiii 3-0 i タイマ周期インデクスタイマ周期インデクスが波長コンバータに入力され、 その出力を分周器の周期とします。
長さカウンタによって音が鳴る時間を設定することができます。 これはカウンタと停止フラグを含みます。 カウント停止フラグビットはチャンネルの一番目のレジスタの、 矩形波とノイズについてはビット5、三角波についてはビット7が割り当てられています。 停止フラグビットはまた、長さカウンタ(ノイズと矩形波)もしくは線形カウンタ(三角波)における他のフラグにも割り当てられていることに注意してください。 $4000,$4004,$400C --h- ---- 5 halt (ノイズと矩形波チャンネル) $4008 h--- ---- 7 halt (三角波チャンネル) チャンネルの4番目のレジスタへの書き込みによって、 上位5ビットによるインデックスに基づいて、 ルックアップテーブルからの値をカウンタにロードします。 フレームシーケンサによって励起されるとき、 停止フラグがクリアかつカウンタがゼロでないなら、カウンタをデクリメントします。 bit 3 7-4 76543 カウント値 ------------------ 0 0 00000 $0A 1 00010 $14 2 00100 $28 3 00110 $50 4 01000 $A0 5 01010 $3C 6 01100 $0E 7 01110 $1A 8 10000 $0C 9 10010 $18 A 10100 $30 B 10110 $60 C 11000 $C0 D 11010 $48 E 11100 $10 F 11110 $20 1 0 00001 $FE 1 00011 $02 2 00101 $04 3 00111 $06 4 01001 $08 5 01011 $0A 6 01101 $0C 7 01111 $0E 8 10001 $10 9 10011 $12 A 10101 $14 B 10111 $16 C 11001 $18 D 11011 $1A E 11101 $1C F 11111 $1Eカウンタはリセットによって1をロードします。 ステータスレジスタ$4015の対応するビットがクリアされることで、 すぐにカウンタへ0をセットしチャンネルを無音化します。 またCPUがステータスレジスタを読むことで、カウンタの状態が分かります。 カウンタがゼロならチャンネルの対応するビットをクリアし、 そうでなければセットします。 チャンネルに対応するビットは次のようになっています。 $4015 ---d ntss 4 d DMC 3 n ノイズチャンネル 2 t 三角波 1 s 矩形波2 0 s 矩形波1 | ! | このユニットが60Hzで励起されるのは、 画面の描画タイミングに合わせるため? |
スイープユニットは矩形波チャンネルの周波数を変化させ、 しり上がり、もしくはしり下がりといった音の効果を提供します。 これはスイープユニットが停止させられるまで継続します。
スイープユニットは分周器とシフタから構成し、 チャンネルの2番目のレジスタによって設定されます。
$4001,$4005 eppp nsss 7 e スイープ有効フラグ 6-4 p スイープ周期 3 n スイープ方向 2-0 s スイープ量分周器の周期は p+1 となります。
チャンネルの4番目のレジスタへの書き込みによって、スイープユニットをリセットします。 次のクロックから分周器が励起され、分周器の出力クロックによってスイープを行います。
それぞれのスイープ更新クロックにおいて、
- スイープ有効フラグがセットされている - スイープ量が0ではない - チャンネルの長さカウンタがゼロではない以上の3つの条件がすべてそろえばチャンネルの周期を新しい値で更新します。
ビット3(スイープ方向) ---------------------- 0 しり下がりモード 新しい周期 = 周期 + (周期 >> N) 1 しり上がりモード 新しい周期 = 周期 - (周期 >> N)このNは0から7までのスイープ量です。
しり上がりモード(スイープ方向が1)ではチャンネルによって次の違いがあります。
- 矩形波チャンネル1では1の補数(NOT)を使用する。
- 矩形波チャンネル2では2の補数(NEG)を使用する。
これは、2つの矩形波チャンネルにおいて現在知られているだたひとつの違いらしいです。
もしチャンネルの周期が8未満か、$7FFより大きくなったなら、スイープを停止し、 チャンネルを無音化します。これはスイープユニットが無効であっても働きます。
矩形波チャンネルはエンベロープジェネレータ、スイープユニット、タイマ、
シーケンサ、長さカウンタで構成します。
$4000/$4004 ddld nnnn 7-6 d デューティ 5 l エンベロープループ 4 d エンベロープ無効 3-0 n ボリューム/エンベロープ周期 $4001/$4005 eppp nsss 7 e スイープ有効 6-4 p スイープ周期 3 n スイープ方向 2-0 s スイープ量 $4002/$4006 llll llll 7-0 l チャンネル周期下位 $4003/$4007 cccc chhh 7-3 c 長さカウンタインデクス 2-0 h チャンネル周期上位
1番目のレジスタによってデューディサイクルが設定されます。 シーケンサはタイマから励起され、次のような波形を出力します。
dd 波形 --------------------- _ 1 00 _ ______ 0 (12.5%) __ 1 01 _ _____ 0 (25%) ____ 1 10 _ ___ 0 (50%) ______ 1 11 _ _ 0 (75%)
4番目のレジスタへ書き込まれたとき、シーケンサをリセットします。 シーケンサの出力が0のとき、チャンネルの出力は0となります。
線形カウンタは、三角波チャンネルのための二つ目のより正確な音長コントロールとして動作します。 これはカウンタを含みます。 レジスタ$4008にコントロールフラグとリロード値が含まれます。 $4008 crrr rrrr 7 c コントロールフラグ 6-0 r 音の長さ コントロールフラグのビット位置はまた、長さカウンタ停止フラグに反映されることに注意してください。 レジスタ$400Bへの書き込みによって、線形カウンタを停止し、カウンタへ音の長さをロードします。 フレームシーケンサによって励起されるとき、 コントロールフラグがクリアかつカウンタがゼロでなければカウンタをデクリメントします。 | ! | 線形カウンタのみで使用することはできない。 |
三角波チャンネルは、タイマ、長さカウンタ、線形カウンタ、32ステップのシーケンサで構成します。
$4008 clll llll 7 c 長さカウンタ無効フラグ 6-0 l 線形カウンタ $400A llll llll 7-0 l チャンネル周期下位 $400B llll lhhh 7-3 l 長さカウンタインデクス 2-0 h チャンネル周期上位 タイマがクロックを生成し、長さカウンタ及び線形カウンタが両方ともゼロカウントでなければ、 シーケンサを励起します。 シーケンサは、下記の32ステップシーケンスを繰り返し出力します。 F E D C B A 9 8 7 6 5 4 3 2 1 0 0 1 2 3 4 5 6 7 8 9 A B C D E F シーケンサが励起されなければチャンネルの出力は一定値となるため、 音は聞こえません。 また周期が短い($400B=0と$400A=0か1)場合、 生じる周波数は非常に高いものとなりますが、 可聴領域を越えているため人間の耳には聞こえません。 | ! |
三角波はよくベースラインとして使用されます。
もちろんメロディーラインも。
音量の調節はできません。 高音域になるほど音痴になるらしい。 |
ノイズチャンネルは長さカウンタ、
エンベロープジェネレータ、タイマ、15ビットのリニアフィードバックシフトレジスタで構成します。
この15ビットシフトレジスタによって擬似乱数を生成、ノイズとなります。
$400C --le nnnn 5 l エンベロープループ、長さカウンタ無効 4 e エンベロープ無効フラグ 3-0 n ボリューム/エンベロープ周期 $400E s--- pppp 7 s ランダム生成モード 3-0 p タイマ周期インデクス $400F llll l--- 7-3 l 長さインデクス $400Eの周期インデックスによって、表の波長コンバータからタイマの周期を選択しセットします。 値 タイマ周期 オクターブ スケール ----------------------------------- $0 $004 15 A $1 $008 14 A $2 $010 13 A $3 $020 12 A $4 $040 11 A $5 $060 11 D $6 $080 10 A $7 $0A0 10 F $8 $0CA 10 C $9 $0FE 9 A $A $17C 9 D $B $1FC 8 A $C $2FA 8 D $D $3F8 7 A $E $7F2 6 A $F $FE4 5 A ランダム生成モードフラグがセットされていればショートモード、 クリアされていればロングモードとなります。 ショートモードの時のビットシーケンスは93ビット、 ロングモードの時は32767ビットです。 15ビットシフトレジスタにはリセット時に1をセットしておく必要があります。 タイマによってシフトレジスタが励起されるたびに1ビット右シフトし、 ビット14には、ショートモード時にはビット0とビット6のEORを、 ロングモード時にはビット0とビット1のEORを入れます。 シフトレジスタのビット0が1なら、チャンネルの出力は0となります。 | ! |
ノイズは主にパーカッションとして使用されます。
LFSR(Linear Feedback Shift Register):M系列のビットパターンを容易に生成する。 安価な擬似ランダム発生器としてよく使用される。 |
DMCは1ビットのDPCM(Differential Pulse Code Modulation)サンプルを出力します。
これはDMAリーダ、割り込みフラグ、サンプルバッファ、タイマ、
出力ユニット、7ビットのデルタカウンタによって構成します。
デルタカウンタの出力はDACへ接続します。
$4010 il-- ffff 7 i 割り込み有効フラグ 6 l ループフラグ 3-0 f 周期インデクス $4011 -ddd dddd 6-0 d デルタカウンタ初期値 $4012 aaaa aaaa 7-0 a サンプル開始アドレス $4013 llll llll 7-0 l サンプルバイト数 レジスタ$4010への書き込みによって、割り込み有効、ループ、タイマ周期をセットします。 もし新しい割り込み有効フラグがクリアなら、割り込みフラグをクリアします。 タイマ周期インデックスにより波長コンバータからタイマ周期をタイマへ入力します。 値 タイマ周期 オクターブ スケール ----------------------------------- $0 $1AC 5 C $1 $17C 5 D $2 $154 5 E $3 $140 5 F $4 $11E 5 G $5 $0FE 5 A $6 $0E2 5 B $7 $0D6 6 C $8 $0BE 6 D $9 $0A0 6 F $A $08E 6 G $B $080 6 A $C $06A 7 C $D $054 7 E $E $048 7 G $F $036 8 C デルタカウンタはパワーオン時に0をセットします。 $4011への書き込みによってデルタカウンタに新しい値をセットします。 $4011 -ddd dddd 新しいデルタカウンタ値 サンプルバッファは、 出力ユニットへ連続してサンプルを渡せるように1サンプルバイトを保持します。 DMAリーダによってフェッチされたサンプルが一時的にストアされ、 出力ユニットによって空にされます。 つまり一旦配置されたサンプルバイトはいずれ出力されることになります。
DMAリーダはサンプルバッファが空になったとき、次のサンプルバイトをストアします。
これは、アドレスカウンタと残りバイトカウンタを持っています。
DMCサンプリングを開始するとき、
アドレスカウンタにはレジスタ$4012 * $40 + $C000をセットし、
残りバイトカウンタにはレジスタ$4013 * $10 + 1をセットします。
出力ユニットは、連続するサンプルによるサウンドを出力します。
これは8ビット右シフトレジスタ、カウンタ、サイレンスフラグを含みます。
シフトレジスタのビット0 ----------------------- 0 デルタカウンタが 1 より大きいなら -2 1 デルタカウンタが 126 より小さいなら +2 またカウンタがゼロでなければシフトレジスタを1ビット右シフトし、カウンタをデクリメントします。 | ! | 適当なプログラム領域をサンプルとして指定して、 なんとなくバスドラっぽい音を出してるゲームもあるらしい。 |
出力としてDMCは7ビット、それ以外は4ビットとなります。 全てのチャンネルとマイクからの入力が加算され、本体から一旦カートリッジに出力されます。 カートリッジに拡張音源が存在するならその出力と加算され、また本体に入力されます。 この信号をオーディオとして出力します。