かつて、グラフィックがチープだったNEC PC-8001に美麗グラフィック風な機能を追加する(キャラジェネをRAMへ置き換え) ハル研究所のPCG8100というものがありました。その機器や互換ボードについていた音楽再生機能はi8253プログラマブルタイマーLSIを使っていました。後期には3声になったりしてました。
というわけで、今回のKZ80-IOB I/Oボード改良版も3チャンネル全部割り込み機能にしてもアレなのでチャンネル#2だけは外部出力してスピーカーでも鳴らしてみようかいと思ったわけであります。
音の周波数について
まずはドレミファ….という音の周波数を調べてみました。検索するといろいろと周波数を公開してくださっている方々がいらっしゃいまして参考にさせていただきます。
8254タイマーLSIで音程を…
まずは「音」の周波数を調べてみたい。先人の方々の情報をもとに周波数を表にしてみると以下のような感じであります。
音階 | 周波数(Hz) |
ド | 261.626 |
レ | 293.665 |
ミ | 329.628 |
ファ | 349.228 |
ソ | 391.995 |
ラ | 440.000 |
シ | 493.883 |
ド | 523.251 |
参考 : https://tomari.org/main/java/oto.html
前回の回路を見ていただけるとわかりますが、i8254プログラマブルタイマーに接続しているクロックは1228.8kHzであります。この周波数が最高値で16ビットカウンターでありますから2を指定すると1/2、3を指定すると1/3の周波数が出てきます。これを元に近い音階に周波数をテーブル化することとしました。Z80アセンブラで作成した音階テーブルは以下になります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | ;----- ; 音程データ ;----- SOUND_DATA: OCT4: ; ド DB "C" DW 1258h ; レ DB "D" DW 1058h ; ミ DB "E" DW 0E8Fh ; ファ DB "F" DW 0DBEh ; ソ DB "G" DW 0C3Eh ; ラ DB "A" DW 0AE8h ; シ DB "B" DW 9B8h OCT5: ; ド DB "C" DW 92Ch |
ソース:https://github.com/kuninet/Z80mon/blob/master/test/8254PLAY.asm
実際には1オクターブ分だと音楽を奏でるには足りなさそうだったので2オクターブ分のデータを準備しました。
演奏プログラムは簡易MMLで
上記のgithubのソースを読んでいただけるとわかりますが、演奏プログラムへの音楽データの引き渡しは簡易MMLで実装してみました。
C=ド、D=レ….という感じで、大昔のMSXやPC-8801SRなどのBASICで実装されていたPLAY文で使われたものと同じ英文字で音程を表す形式です。
自作Z80機械語モニターのG(プログラム実行)コマンドで引数をされるように改造しましてある程度の文字列を演奏プログラムに渡して「かえるの歌」ぐらいは演奏できたらなぁということで作ってみました。
上記は1石トランジスタアンプ経由で100円均一のスピーカーを鳴らしてみた感じです。(すでにだいぶ前のTweetですいません…^^);;)
i8254/i8253による1声の音楽演奏はPC-8001 PCGを始めかつての8bitマイコンでは定番だった気がします。私もマイコンも追いついたぜ!って感じで感動したのであります。
コメント