PICでチップチューンプレイヤーを作った

あまり暇ではないのですが、PICを使ったチップチューンプレイヤーを作りました。

ハードウェア

klovnin.netはSDGsを応援しています

近年あらゆるところで重要視されているSDGsですが、その中に「ゴミの量を減らし、リサイクルする」(目標12-5)が存在します。この目標達成に向けて、以下のICを選びました。

AY-3-8910

音源ICにはAY-3-8910を使いました。この音源ICは3和音1ノイズでファミコンみたいな音を出す事ができる音源で、昔のいろいろなパソコンやゲーム機に採用されていたようです。インターネット上で中古品が安く(100円/個以下)手に入るのですが、その理由として昔のいらなくなったパソコンから取り出したものであることが推測できます。つまり廃棄物の活用となり、SDGsですね。また先例が豊富にあることを基準としました。特にロシアではコミュニティが盛んで、AY-3-8910用の作曲ソフトや曲データが多く開発されています。

接続方法としてはマルチプレクスバス方式で、8ビットのバスと2つのコントロールピンでデータとアドレスの通信を行います。具体的には、コントロールピンでアドレス書き込み状態にしてから8ビットのバスを設定し、一旦バスを無効化してからコントロールピンをデータ書き込み状態にして8ビットのバスを設定するとアドレスにデータが書き込めます。

今回はAY-3-8910への書き込みルーチンはYMZ294で楽しむPSG音源のサイトのサンプルコードを流用しました。YMZ294はAY-3-8910の互換品で、制御方法もとても似ています。

PIC16F57

Arduinoなどで採用されていて先例もたくさんあるAVRではなく、なぜ今更PICなのかと言うと、秋月でPIC16F57が安くなっていたためです。十年ほど前から同じような価格で売られているようなのですが、使い道がなければリユースされにくそうです。それに、数年前に3000円で秋月で買ったPICライター(LEAP PSTART)を結局一度も使っておらず、もったいない気がしたためです。

危ないベースライン

1995年に発売されたPIC16F57は、1987年ごろに発売された16C57のフラッシュメモリ版なので、設計の古さから使いにくいです。有名な16F84と比べると色々なところが異なりますが、特に重要なのは16F84がミッドレンジなのに対し16F57はベースラインである事でしょう。詳しくはいかづちSqueakさんのベースラインPICの注意点が分かりやすいのですが、要約するとこんな感じです。

・プログラムメモリは1kワードごとにバンク切り替えが必要
・ファイルレジスタ(データメモリ)は16バイトごとに切り替えが必要
・CALL命令のサブルーチンはバンクの始めから512ワードにしか配置できない
CALL命令は2回までしかネスト出来ない

この中で特にヤバいのはサブルーチン関係ですね。後ろのネストが2回まで制限はビルド時にエラーが出ないので悩みました。
一応C言語も使えるようですが今回はメモリサイズと書き込みハードの関係上MPASMで書きました。

他にもPIC16F57の特徴として、

・周辺機器は8bitタイマーとWDTのみ
・割り込みなし
・内蔵クロックなし

などがありますが今回はタイミング用のタイマーがあれば十分でした。

ちなみに、PSTARTやPICSTARTで書き込む際にはCLKOUTを浮かせておかないと書き込みができません。何度も曲げると折れてしまうので、ソケットのピンを切ってそれに乗せて書き込みましょう。

EEPROM

PIC自身の曲データを入れる領域は少ないので、外付けのメモリが必要になります。今回はI2C EEPROMの24FC512を使います。こちらは普通に利便性から選びました。16F57はハードウェアでI2CやSPIの通信機能を持っていないので、ソフトウェアでI2C通信を行います。しかし、自力で仕様を読み解いてコーディングするのは大変なのでインターネット上のI2C EEPROMルーチン(nagoyacoderさん電子マスカットさん)を流用しました。

その他

AY-3-8910は1MHzから2MHzまでの外部クロックが必要です。作曲ソフトで使われるZX SpectrumはCPUが3.5MHz、AY-3-8910がその半分の1.75MHzなのでそれに最も近く手に入れやすい3.58MHzの発信器を使います。これ単体ではクロックの出力はできないので、データシートにあるようなクロック回路を作る必要があります。その際に使うICは、基本的に74HCU04(か74AHCU04)もしくは4069UBである必要があります。それ以外の74HC04などは機能が似ていても正常に発振しない可能性があります。
生成した3.58MHzはPICのCLKINに供給してシステムクロックとすると同時に、74HC74を利用した分周器を通して1.79MHzをAY-3-8910に供給します。

AY-3-8910からのオーディオの出力回路は、avray.ruにある簡易RCフィルターを使用します。チャンネルごとに別れているので、Aを左、Bを右、Cは10kΩを左右両方につないで中心とします。

その他、状態確認用のLEDと曲選択用のスイッチ、電源コネクタを取り付けます。

ソフトウェア

ソフトウェア面では前述のYMZ294ルーチンとI2C EEPROMルーチンをベースに、RSFファイルのプレイヤーを作りました。
RSFファイルはavray.ruで公開されている形式で、AY-3-8910のアドレスとデータの列で構成されています。公式サイトの説明は分かりにくいのですが、まず2バイトのアドレス情報があり、その1ビットずつで書き込むかどうかを判別します。その後に値が1バイトずつあるので、小さいアドレスから順に書き込み処理を行います。全て終わったら20msの待機を行います。

RSFファイルの作成方法は、Vortex Tracker IIなどの作曲ソフトから書き出したファイルをAVR-AY Playerで変換することで得る事ができます。それからヘッダを削除し、EEPROMに複数曲を入れられるように独自のヘッダを加えて書き込みます。

また、起動時にスイッチを押しっぱなしにする事でArduinoなどの外部機器からAY-3-8910を使えるようにPICを無効化するモードと、起動時に互換品のYM2149かAY-3-8910かをチェックし、YM2149の場合はLEDをオフにする機能を実装しました。おまけとして、AY-3-8910のIOポートの簡易的なテスト機能もあります。(詳しくはソースを見てください)

今回のソフトウェアは色々なところからサブルーチンを借りてきているので、ライセンス的には微妙ですが、全てサンプルソースなのでこのコードもサンプルソースとします。

リンク

ソース、HEXファイル、接続の説明はgithubにあります。再生例はこちら

コメントを残す