レベル3/S1用の仮想FDDを作る
1980年代前半、8ビットパソコンの記憶装置と言えばカセットテープかフロッピーディスクでした。 ただフロッピーディスクは非常に高価でドライブ+インターフェースカード+DISK BASICなどのOS、これら一式の値段が本体の2倍近くになることもありました。 それでも、広く普及したこともあって後年は価格もかなり下がりました。 今回は、そんなフロッピーディスクドライブ(FDD)機能をFPGAに実装して仮想FDDとしてアクセスできるようにしたいと思います。
まずは、フロッピーディスクまわりがどうなっているかをおさらいします。
以下にレベル3用5インチ両面倍密度(2D)フロッピーディスクのブロック図を示しました。
データの読み書き、ドライブヘッドの移動はフロッピーディスクコントローラ(FDC)に指示を出して行い、ドライブのモータON/OFFやドライブの選択はUNIT SELに書き込んで制御します。
ちなみに5インチ版のFDCは富士通のMB8866やMB8876を、3インチ版はモトローラのMC6843を採用していました。
これをもとにFPGAに実装する機能を考えていきます。今回は、FDCとディスクドライブ(FDD)の機能をすべてFPGA側に実装するので、
- FDCやUNIT SELはハードウェアで実装する。FDD部分は、ディスクイメージをSDRAMに置き、FDCからのデータ読み書きをするためのモジュール(FDD UNIT)を実装する。
- SDRAMのディスクイメージは、PCからJTAG(USB)経由で送信することにする。PCとSDRAM間の送受信はNIOS IIマイコン機能を実装しこのマイコン用のソフトウェアで行う。PC側にも送受信するためのソフトウェアを新規開発する。
- ディスクブート用のROMイメージをNIOS IIマイコン用のソフトウェアに組み込む。これをL3側から読むことができるようにモジュール(ROM)を実装する。
上記FDDの機能以外に、ディスクイメージの状態表示用にI2Cで動かせるLCDと、FPGAに指示をするためのボタンを接続します。以上の機能をブロック図にすると以下のようになります。
さらに、各モジュールについて細かい機能を設計していきます。
- FDC:今回はDISK BASICが使用している機能のみ実装する。具体的にはRESTORE(SEEK TRACK 0), SEEK, READ SECTOR, WRITE SECTORの各コマンド。また、ステップレートなどの細かいオプションは無視する。
- FDD: ドライブは1つ(DRIVE 0のみ)とする。HEAD LOADやINDEXなどの信号は省略する。モータON/OFF信号はそのままREADY信号ON/OFFとなる。
- ディスクイメージとFDC間はパラレルデータをそのまま読み書きするので補正回路は不要。
- ディスクイメージのフォーマットはエミュレータでも採用しているd88形式にする。
- ディスクイメージの送受信はPC側のソフトで制御する。送受信用に簡単なプロトコルを定義してネゴシエーションを行う。
と挙げ出したらきりがないのでこれぐらいにして、あとはFPGA周りの回路も設計します。今回は、ボタンやらLCDやらで使用するIOピンも多くなっています。ROMKIL信号を作るためにNANDゲートである74HC00が増えてロジックICが5つになりました。NMIとROMKIL信号はあいかわらずトランジスタで実装していますがスイッチングが速くなるようにコンデンサを入れています。
一通り設計が完了したら実装していきます。FDCは5インチ用と3インチ用のものをVerilog HDLで実装していきます。 一方、PCとの送受信する部分はソフトウェアなのでC言語で記述します。 さらに、PC側のソフトウェアをVC++で作っていきます。今回は、作らなければならないものが多いし、FDCや各モジュールの状態遷移がややこしい!
それぞれの機能ごとに実装が終わったら単体テストを行っていきます。FDCなどのハードウェア部分はシミュレーションで想定通り動いているかをテストします。また、ディスクイメージの送受信はFPGAだけで実際に動かせるようにしデバッグ&テストを行いました。
デバッグ&テストでいろいろ試行錯誤した結果なんとか動く形になったのでいよいよ実機と接続します。 今回は、ロジックICが5つもあるのでブレッドボード1枚では足らず小さいブレッドボードを追加しました。配線が終わったらマーク5の拡張端子に接続します。 まずはFPGA側を通電し、5インチ2DのディスクイメージをFPGAに送り込みます。これは単体テストをしたこともあって問題なく動きました。
ではマーク5の電源を入れてみます。はたしてDISK BASICは起動するでしょうか…やっぱりNG。 ROM BASICさえ起動しない状態に。 今回もFPGA内のロジックアナライザで信号を観測します。その結果いろいろ不具合箇所が見えてきました。
- ROMKIL信号がまだ遅い感じがするのでFPGA内で早めに切り替えるように調整した。
- 5インチ版FDCのデータ入出力が負論理になっていなかった。これは、単純にFDCの仕様をド忘れしていた。
- FPGAから出力するCS信号の立上りをE信号の立下りより遅くした。6809のデータシートにはそのように書いてある。仕様書はよく見直しましょう。
- READ後のNMI割り込みの発生タイミングを遅らせた。早すぎるとDISK BASIC内でREAD終了を検知できないようです。
- E信号のノイズ対策でコンデンサを追加した。たまにノイズがのっているような感じがするのですが…。
- レベル3のリセット信号にチャタリング対策を施した。チャタリングしているとFPGA内の初期化がうまくいかない。
と、他にもいろいろと不具合が見つかり、これらを修正した結果、やーっとDISK BASICが起動しました!
NEWONコマンドでの再起動、プログラムのLOADやSAVEも問題ないようです。 いや、SAVEはちょっと遅いのでもしかしたら問題あるのかも。 確認のためPCにディスクイメージを送って中身を見てみるとSAVEは正しく行われているようなので問題なしかな?
5インチ2D版が成功したので、次は3インチ版のDISK BASICも試してみます。 前述の不具合を修正した後に3インチ版のディスクイメージを送り電源ON。おっ!こちらは、すんなりと起動した模様です。
次は、S1に接続して動作確認してみます。まずは、Aモードで5インチ2D版のS1 DISK BASICの起動させます。 実機はS1/40で2HDのFDがついているため、IOアドレスがFPGA側と重複しないようにします。 ABモード切替スイッチにつながっている白いコネクタをはずし、このコネクタのピンをショートさせて、2HD FDのIOアドレスを切り替えます。
まずは、Aモードで5インチ2D版のS1 DISK BASICをFPGAに送り、S1の電源を入れます。おおっ!こちらも、あっさりと起動してしまいました。
次はBモードでLEVEL-3 DISK BASICを試してみます。マーク5と同様に5インチ版と3インチ版で動作確認を行います。結果は、あれ起動しない。 どうやら、BモードではCPUがアドレスを変更してからアドレスバスに出力されるまでにタイムラグがあるため、ラッチするタイミングを遅くしなければいけないようです。 これを変更したところ、無事起動するようになりました。
まとめ
今回は全体のシステムの規模がいままでのより大きくなり、準備段階からここまで到達するのに約3カ月かかりました。 いまだ実機の信号遷移を理解していないということで、この状態でシミュレーションやらでテストOKとなっても実機では動かないわけでして。 これは今回かなり理解が進んだので、今後は実機での検証もスムーズにいくのではないかと(期待を込めて)思います。(おわり)