FPGAでFDDコントローラを作る (2) リード処理

 前回ではモータとヘッドを制御する回路を実装して実際に動かすことができました。今回は、実際にFD内のデータを取り出すための実装を考えていきます。

データはもう出ている

 3.5インチFDDの場合ヘッドは常に磁気面に接触しているので、モータを回した時点ですでにREAD DATA信号からパルスが出ています。これを一定周期でサンプリングすれば生のデータが得られます。

 ここでは、まず16MHzの周期でデータをサンプリングすることにします。サンプリングの開始はINDEX信号がONになってから、1周して再びINDEX信号がONになった時点で終了にします。これだと1周分のデータサイズは16MHz*(60sec/300rpm)=3.2Mビットなので8で割ると約400Kバイトになります。

 データの流れを図にするとこんな感じでしょうか。


RAWデータ読み出し データの流れ

 16MHzの周期でREAD DATA信号をサンプリングしてこれをシフトレジスタに入れます。シフトレジスタは32ビットで左にシフトしていきます。これがいっぱいになったらSDRAMに書き込むようにします。図にすると単純ですが実装となると結構面倒…。

SDRAMに保存

 データは基本シーケンシャルに書き込んでいきますが、複数のトラックを一度に読んで書き込むような場合でも各トラックのデータであることが分かるように書き込みを開始したアドレスと書き込んだデータサイズを保持しておくようにします。SDRAMは32Mバイトなので32M/400K=最大80トラック分を一度に格納できます。


SDRAM書込みデータの流れ

 SDRAMには制御プログラムからもアクセスするため、データはNiosIIマイコン内にあるSDRAMコントローラに渡します。ちなみに、NiosIIマイコンはマルチレイヤバスなので制御プログラムがSDRAMにアクセスしていなければほぼウェイト無しで書き込めます。

 SDRAM R/Wモジュールは以下のように動作します。

(1) 最初に書込みを開始したアドレスを保存。
(2) データを書き込む。
(3) 書き込んだサイズを加算して保存。
(4) データ末尾まで(2),(3)を繰り返す。

 (1)(2)(3)は同時ではなく順序立てて動かす必要があるため、FPGAの実装ではステートマシンを使うことになりますね。

 これらハードウェア部分を実装したら、例によってシミュレーションを行います。毎度テストベンチやらテストデータやら作らなければならないのでこれがもう大変。

ソフトウェアも実装

 SDRAMに保持したデータをWindows PCにJTAG(USB)経由で送信するための機能を制御プログラムに実装します。PC側にもデータを受信するプログラムを作成します。これらは仮想FDDで作ったものがすでにあるのでこれを流用して実装します。


PCへデータ送信 データの流れ

 制御プログラムのデバッグをシミュレーションで行うと時間がかかってしょうがないのでそのまま実機に入れてテストすることにします。

実機で動かしてみる

 まずは、FDDからのデータをSDRAMに取り込んでみます。PCからFPGAに指示を出します。MAX10-JB基板に載っているJTAG通信中の黄色LEDが点灯してLCDに反応がありますがそこからダンマリ。

 こういう時はロジックアナライザで怪しい信号線を監視して不具合を特定していきます。結果、タイミングが合っていないようです。シフトレジスタからのデータをハザード中にラッチしていたりと、これらを考慮せずシミュレーションしていたため検証も甘かったようです。

 この辺りを直し、シミュレーションも一からやり直して、FPGAをコンフィグレーションして…フゥ…あ、動きました。


FDDからのデータをサンプリング

データサイズが表示される

 次は、サンプリングしたデータをPCに送信します。こちらもPCからFPGAに送信指示を出します。ん?動かないですねぇ。これらはソフトウェアで処理しているのでソースを修正して再トライ。こちらは少し直しただけで動きました。


PCに送信中

パルス波形を確認

 データが受信できたので中身を確認してみます。まずは、データがどういう波形になっているのか見てみます。


パルス波形(2HD)

 波形から、というより2HDだとわかっているので、記録方式はMFMであることがわかります。と、その前にFDにデータがどのように記録されるのか、を簡単に説明すると:

 次に、データパルスをビット0/1に置き換えたものを下図に示しました。
ん?ちょっとまった!クロックパルスとデータパルスはどのように見分けるのだ?しかもバイト境界はどうやって決めた?


データビットに変換(2HD)

 そう、ここからさらにフォーマットを調べる必要があるのです。ここでフォーマットについて、簡単に説明すると:

 データビット0/1を決定するには、まずGAPフィールドを、その後にSYNCフィールドがくるようなパターンを探すことになります。その結果、図中の上側のビット列&バイト列であることが決まります。

パルス間隔も確認

 パルス間の長さも確認してみます。


パルス間隔(2HD)

 図から、2,3,4マイクロ秒に集中していることが分かります。長さが3パターンあることからMFM方式、また最短が2マイクロ秒であることから高密度(HD)、これで2HDであることがわかります。


パルス間隔(2DD)

 こちらは2DDです。間隔は4,6,8マイクロ秒と2HDの2倍の長さになっています。

PC-98シリーズのFDは読めるか

 次に、NEC PC-98シリーズでフォーマットしたFDを読み出してみます。


パルス間隔(PC-98 2HD)

 データ自体は問題なく読み出せたようです。長さが3パターンあることからMFM方式ですが、長さが2.4, 3.6, 4.8マイクロ秒とPC/AT用より長くなっています。

 使用しているFDDは3モードなのでMODE SELECT信号を切り替えてもう一度読み出してみました。


パルス間隔(PC-98 2HD 1.6Mモードでリード)

 すこしばらついていますが、2,3,4マイクロ秒に集まっています。このことから、NEC PC-98シリーズのFDDはモータの回転数がPC/AT用のものより速かったことが分かりました。PC/AT用が300rpmなのでPC-98用は300*2.4/2=360rpmで動かしていたんですね。

FDDは何もしていない?

 結局、FDDは磁気の変化をパルスにして出力しているだけで、記録方式やフォーマットには全く関知してません。だからこそパソコン本体にFDCが必要になるわけですね。

 最後にもう1つ、3.5インチFDDは、2HDと2DDの区別は出来るのでパルス幅は変えているのかと思いましたが図を見る限り変わらないですね。やはりFDDは何もしていない?


2HDと2DDパルスの比較

 記録方式やフォーマットはユーザ側で解析していかないといけない、ということで、次回はデータセパレータを実装してハードウェアでフォーマットに即したデータを取り出すようにしていきたいと思います。(つづく)

参考文献

  1. FDアダプタ - http://ldlabo.hishaku.com/NO46/main.htm
  2. PC-9821/9801シリーズとFDD - http://www.geocities.jp/cpuparts98/FDD/FDD_0.htm
  3. マイクロコンピュータMC6809の考え方, オーム社
  4. TEAC FD-235HG-C304 MICRO FLOPPY DISK DRIVE SPECIFICATION
  5. FUJITSU MB8877A Datasheet

FPGAでFDDコントローラを作る (1) ←前 次→FPGAでFDDコントローラを作る (3)

 

TOP PAGE