S1用の拡張PSGを作る
S1にはPSGが1個載っていますが、取扱説明書のI/Oアドレスには拡張PSGのポートが予約されている、との一文が記述されています。さらにS1 BASICは6重和音までの同時演奏ができるようなっています。このことからS1開発時にはPSGを2個載せるのを前提としていたのではないかと推測できます。せっかく用意されているのに使わないのはもったいない、ということで今回はその拡張PSGをFPGAで実装してみます。
まずは拡張PSGカードの回路がどのようになっていたかを推定します。
- PSGを制御するTMG2信号。これは標準PSGでも出力されるため、これ自身が拡張PSGのセレクト信号とはならずこれをもとに生成する必要がある。
- I/Oアドレスは$FFE6,$FFE7だが、$FFC0~$FFEFのセレクト信号IN I/Oが拡張端子に出力されていないためこの信号が使えない。 ($FF00~$FF7FならEX-I/O、$FF80~$FFBFならEX-I/O2信号が使用できる。)
基板からIN I/O信号を直接とりだすようなことはしていないと思うので、アドレスバス16本をすべて見てセレクト信号を生成していたのではないかと思われます。これらから以下のような回路を推定しました。なお、この回路、B(L3)モードでは使用できません。
上の回路をもとに、FPGA用の回路を設計します(回路図は後掲)。13ビットのNANDゲートはLCXやLSがなかったのでHC133にしました。完成したらこれをもとにブレッドボード上に配線します。
完成したら拡張ボードにある端子に接続します。今回はS1独自の端子は使用しないのでエッジコネクタを挿すピンの位置をまちがえないように注意します。挿したら拡張ボードをS1本体に接続して準備完了。あ、そうそう、ロジアナも接続しておきましょう。
(追記:S1用の拡張カードを全く挿していない場合は、68番目ピンのS1 IF SELをGNDに接続してください。)
ではS1の電源を入れてみます。1回目…BASICが起動しません。さっそくロジアナで信号を観測します。結果、ROMKIL信号が大量に出ています。これはHDLの記述バグでしたのでHDLを修正します。
2回目…BASICが起動しました。PLAYコマンドを入力してみます。…Address Error頻発で暴走。信号観測するとROMKIL信号のON/OFFが予想以上に遅すぎて次のサイクルと干渉しています。どうやらトランジスタのスイッチングの遅さに問題があるようです。トランジスタ廻りの抵抗値を10KΩからベースにつながる部分を4.7KΩ、ベースからGNDへ落とす部分を2.7KΩに下げてみました。
3回目…BASICが起動したのでPLAYコマンドを実行。…無事音がなりました。信号観測するとROMKIL信号が1サイクル内に収まっていることが確認できます。ただ、まだ遅い感じなのでコンデンサを挟んだほうがいいかもしれません、が今回は実装しませんでした。なお、標準搭載のPSGとくらべてFPGA側の音量が小さいので、音声出力部分の抵抗値を低くするように再度調整しました。
ひととおり調整が完了したので動作検証にいきます。まずはPLAYコマンドを実行。標準搭載PSGと遜色ない感じで音がなります。続いてメロディチャイムを演奏するプログラムをLOAD&RUN。こちらは拡張PSGの演奏が標準搭載のものと異なります。どうやらエンベロープ長さが拡張PSG側に設定されていないようです。エミュレータ上でこのプログラムを実行した時も同じ現象でしたので、おそらくS1 BASICのバグではないかと思います。ということで検証としてはOKとします。
まとめ
今回はトランジスタのスイッチング動作でつまづく結果となりましたが、この辺を解決するノウハウが勉強になりました。これ以外、アドレスバスのデコードやデータのラッチなど、この辺りの実装は大分こなれてきたような気がします。
さて今回でPSGシリーズは終わりとします。次は何をしようかな、MAX10-FB基板にはSDRAMが搭載されているので、これを使って拡張メモリカードなどを実装してもいいかもしれません。(おわり)
ソースコード・ダウンロード
s1expsg_010_source.zip (55KB)
[MD5:be1ea06e6b87f03f84f597e39446e893]
※試される方は自己責任でお願いします。
◆関連ページ◆