音声合成の設計(4)のサンプルプログラムは、両方とも割り込み禁止をしていました。それは、音声データが0x0000からのRAM領域にあるために、切り替えるのが大変だったからです。
そこで、0x0000からの音声データを0xD000に転送させてから、割り込みを許可して音声(歌声)を鳴らすようにしました。
この方法だと、割り込みが有効なために、直前でPLAY文で音楽を鳴らすと、音声(歌声)と音楽が重ねられます。
songtest2.zip これがそのプログラムです。速度は2を指定すると何となくタイミングが合います。
しかし、タイミングがちゃんと合っていないと、歌声+伴奏には到底聞こえません。
uPD7752 の動作タイミングを把握して、それに合わせる必要があります。
外部データの音声再生時の入出力タイミングと入出力データの詳細を以下に示します。
まず、外部データの音声再生時の動作の詳細です。
1)CPU から、mode (速度)を書き込む。
2)CPU から、外部データコマンド(0xFE)を書き込む。
3−1)uPD7752 が BUSY=L→H、REQ=L→H にする。
3−2)CPU から、ホルマントデータの1組目の1バイト目を書き込む。
3−3)uPD7752 が REQ=H→L にする。
3−4)uPD7752 が REQ=L→H にする。
3−5)CPU から、ホルマントデータの1組目の2バイト目を書き込む。
3−6)uPD7752 が REQ=H→L にする。
3−7)uPD7752 が REQ=L→H にする。
3−8)CPU から、ホルマントデータの1組目の3バイト目を書き込む。
3−9)uPD7752 が REQ=H→L にする。
3−10)uPD7752 が REQ=L→H にする。
3−11)CPU から、ホルマントデータの1組目の4バイト目を書き込む。
3−12)uPD7752 が REQ=H→L にする。
3−13)uPD7752 が REQ=L→H にする。
3−14)CPU から、ホルマントデータの1組目の5バイト目を書き込む。
3−15)uPD7752 が REQ=H→L にする。
3−16)uPD7752 が REQ=L→H にする。
3−17)CPU から、ホルマントデータの1組目の6バイト目を書き込む。
3−18)uPD7752 が REQ=H→L にする。
3−19)uPD7752 が REQ=L→H にする。
3−20)CPU から、ホルマントデータの1組目の7バイト目を書き込む。
3−21)uPD7752 が REQ=H→L にする。
3−22)uPD7752 内の初期設定の処理が行われる(ちょっと時間がかかる)。
4−1)uPD7752 が REQ=L→H にする。
4−2)CPU から、ホルマントデータの2組目の1バイト目を書き込む。
4−3)uPD7752 が REQ=H→L にする。
4−4)uPD7752 が REQ=L→H にする。
4−5)CPU から、ホルマントデータの2組目の2バイト目を書き込む。
4−6)uPD7752 が REQ=H→L にする。
:
: 3−7)〜3−19)と同様
:
4−19)uPD7752 が REQ=L→H にする。
4−20)CPU から、ホルマントデータの2組目の7バイト目を書き込む。
4−21)uPD7752 が REQ=H→L にする。
4−22)uPD7752 内で1組目のホルマントデータの再生が完了するまで待つ。
4−1)〜4−22)の間に、3−1)〜3−21)で設定した1組目のデータが再生される。
5−1)uPD7752 が REQ=L→H にする。
5−2)CPU から、ホルマントデータの3組目の1バイト目を書き込む。
5−3)uPD7752 が REQ=H→L にする。
:
: 3−4)〜3−19)と同様
:
5−19)uPD7752 が REQ=L→H にする。
5−20)CPU から、ホルマントデータの3組目の7バイト目を書き込む。
5−21)uPD7752 が REQ=H→L にする。
5−22)uPD7752 内で2組目のホルマントデータの再生が完了するまで待つ。
5−1)〜5−22)の間に、4−1)〜4−21)で設定した2組目のデータが再生される。
以下、上記の内容が繰り返されます。
最終バイトは、送るデータが違うだけです。
?−1)uPD7752 が REQ=L→H にする。
?−2)CPU から、ホルマントデータの最終組の1バイト目(0x00)を書き込む。
?−3)uPD7752 が REQ=H→L にする。
?−4)uPD7752 が REQ=L→H にする。
?−5)CPU から、ホルマントデータの最終組の2バイト目(0x00:ダミー)を書き込む。
?−6)uPD7752 が REQ=H→L にする。
:
: 3−5)〜3−19)と同様。書き込むのは、(0x00:ダミー)のデータ
:
?−19)uPD7752 が REQ=L→H にする。
?−20)CPU から、ホルマントデータの最終組の2バイト目(0x00:ダミー)を書き込む。
?−21)uPD7752 が REQ=H→L にする。
?−22)uPD7752 内で(最終−1)組目のホルマントデータの再生が完了するまで待つ。
?−1)〜?−22)の間に、一つ前で設定したデータが再生される。
TIME に2以上を設定した場合は、以下のようになります。
例えばTIME=3 の場合、
a−1)uPD7752 が REQ=L→H にする。
a−2)CPU から、ホルマントデータのn組目の1バイト目を書き込む。
a−3)uPD7752 が REQ=H→L にする。
a−4)uPD7752 が REQ=L→H にする。
a−5)CPU から、ホルマントデータのn組目の2バイト目を書き込む。
a−6)uPD7752 が REQ=H→L にする。
:
: 3−7)〜3−19)と同様
:
a−19)uPD7752 が REQ=L→H にする。
a−20)CPU から、ホルマントデータのn組目の7バイト目を書き込む。
a−21)uPD7752 が REQ=H→L にする。
a−22)uPD7752 内で一つ前のホルマントデータの再生が完了するまで待つ。
a−1)〜a−22)の間、一つ前で設定したデータが再生される。
b−1)uPD7752 が REQ=L→H にする。
b−2)CPU から、ホルマントデータのn組目の8バイト目を書き込む。
b−3)uPD7752 が REQ=H→L にする。
b−4)uPD7752 内で一つ前のホルマントデータの再生が完了するまで待つ。
b−1)〜b−4)の間、a−1)〜a−22)で設定したデータが再生される。
c−1)uPD7752 が REQ=L→H にする。
c−2)CPU から、ホルマントデータのn組目の9バイト目を書き込む。
c−3)uPD7752 が REQ=H→L にする。
c−4)uPD7752 内で一つ前のホルマントデータの再生が完了するまで待つ。
c−1)〜c−4)の間、b−1)〜b−22)で設定したデータが再生される。
上記のタイミングチャートは以下の通りです。




それぞれのタイミングチャートの中での、フレームの長さや設定完了までの制限時間は、音声の再生速度に依存します。

制限時間までにホルマントデータを設定しないと、エラーになります。
uPD7752 の入出力タイミングが分かると、それに合わせてAY-3-8910を制御すれば、歌声に伴奏が出来る事になります。
実際に作ったのがこれです。
kohan.zip プログラムにデータを持たせましたので、mk2、66、のどちらでも動作可能です。
MODE=5、PAGE=2 で起動して下さい。
エミュレータと実機で音量が違うようなので、PSG の方の音量を変更可能にしました。
10ms/Normal の設定(速度2)の時は、一つのデータの処理が10ms なので、これに合わせて音を出しています。
そのため、音声の再生速度を変更すると、伴奏の速度も合わせて変わります。
実行結果〜♪ 実機(mk2)で、速度 = 1、VOL-A = 8、VOL-B = 8、として再生したものです。
音楽の才能がないので、イマイチですが...