AY-3-8910はPSGサウンドを再生するチップで比較的良く知られており、
数多くの機器に搭載されたサウンドデバイスである。
PSGはパルス波形を基本とした音で、同時発音数は3チャンネル、
このほかにノイズジェネレータ機能を含む。
単純なビープ音を発するのであれば最新のチップでは専用のLSIを用いずとも
可能だが、正確な音階やメロディー、和音を再現する場合は既存の機能では
不十分の場合があり、現在でもAY-3-8910などと互換性を持つ設計が用いられる事がある。
AY-3-8910I/Oアドレス
0xA0 |
Register number |
0xA1 |
Write |
0xA2 |
Read |
AY-3-8910のレジスタは16個。音を発生させる場合は、3つあるチャンネルから、
各チャンネルの周波数と音量を設定するだけ。
音量をセットすると即座に音が発音する。FM音源LSIのような鍵盤のON/OFF
といった制御は必要ではない。
音階は各チャンネルごとに用意されたレジスタにセットする。
ChannelAであればR0,R1。
このレジスタのパラメータは数値が小さくなるほど高音となる。
音階は二つのレジスタを組み合わせ12bitの長さを持つ。
この他に音量レジスタがある。ChannelA用のボリュームはR8。
音量は15段階が設定可能で、16を指定すると単調な音にくわえて振幅を変えるエンベロープ
と呼ばれる効果を指定可能。
音階は12bitで指定し、R0,R1の二つで一つのチャンネルの音階を指定する。
このレジスタセットはチャンネルAからチャンネルCの三つがある。
R7で各チャンネルやノイズ音源の有効、無効を指定する。
これはミキサー切り替え機能。
PSG音源のチップはFM音源LSIの打鍵ON/OFFという区別はなく、
直接ボリュームを指定するとダイレクトに音が再生される。
このほか一つだけエンベロープの振幅変化パターンを指定することが可能。
このエンベロープは振幅を一定のパターンと周期(周波数)によって変化
させるもの。
R11,12で周波数を指定し、R13でエンベロープのパターンを指定する。
有効化する場合は、ABC各チャンネルの音量指定レジスタの5bitを1として有効化する。
エンベロープ機能が有効の時は音量設定は意味を持たない。
AY-3-8910、PSGの基準クロックはCPUクロック(3.57Mhz)の1/2である、1.7897MhzをAY-3-8910に入力し、
内部で1/16した周波数、111.86khzがPSG音源の基準信号となる。
チャンネルの各周波数は基準信号、111.86Khzに対する分周(割り算)比で
指定する。
ChannelAの周波数レジスタにR0=255、R1=0を設定する場合は、111.86khz/255=438.667hzとなる。
この場合は438hzの音が鳴るという事。
音階を再生する場合は、ドレミの音階を周波数に変換するテーブルを
用意しておくと良いだろう。
一定の時間間隔で音をコントロールし、指定されたオクターブを演奏する
プログラムを書くと、それらはシーケンサと呼ばれる音楽演奏機となる。
AY-3-8910は汎用的な音源LSIで、多くの機械に搭載されている。音源LSIの詳細は以下の資料を参照。
- C言語によるAY-3-8910を直接操作しPSGサウンドを発生するサンプル。
extern unsigned char inp(unsigned char);
extern outp(unsigned char,unsigned char);
void psgsound(unsigned char reg, unsigned char parm);
void main(void){
volatile unsigned long i;
//CH-A Freq
psgsound(0,0x55);
psgsound(1,0);
//Mixer
psgsound(7,56);
//Vol
psgsound(8,15);
//Wait
for(i=0; i<30000; i++);
//Vol
psgsound(8,0);
}
void psgsound(unsigned char reg, unsigned char parm){
volatile int i;
outp(0xA0,reg);
//wait
for(i=0; i<1000; i++);
outp(0xA1,parm);
}
コンパイルは以下の通り
>sdcc -mz80 -c psg1.c
>sdld -b _CODE=0x100 -b _DATA=0x100 -i psg1.ihx psg1.rel iolib.rel
>makebin -s 4096 psg1.ihx > psg1.bin
>perl binout.pl > psg1.com
上記のコードは、以下のBASICと等しい。
10 sound 0,&h55
20 sound 1,0
30 '
40 sound 7,56
50 '
60 sound 8,15
70 '
80 for i=0 to 10000:next i
85 '
90 sound 8,0
以下の例は音階を変える例。
extern unsigned char inp(unsigned char);
extern outp(unsigned char,unsigned char);
void psgsound(unsigned char reg, unsigned char parm);
void main(void){
volatile unsigned int j;
unsigned int i;
unsigned int k;
//CH-A Freq
psgsound(0,0x55);
psgsound(1,0);
//Mixer
psgsound(7,56);
//Vol
psgsound(8,15);
for(k=0; k<5; k++){
for(i=0; i<80; i=i+5){
psgsound(0,0x55-i);
//Wait
for(j=0; j<10000; j++);
}
}
//Vol
psgsound(8,0);
}
最終更新:2012年05月03日 23:34