(2013.8.24追記:マイコン用プログラムとそのビルド手順が間違っていたので修正しました。試された方がいましたらすみません。)
昔のパソコンをいじっていると、現代のPCとのデータの受け渡しにフロッピーディスクを利用できると便利な場合があります。しかし、倍密度フロッピーが読み書きできる環境というのは段々少なくなってきました。フロッピーインターフェースを内蔵しているPCならばやりようがあるのですが、USB接続用のFDDは2HDにしか対応していないことが多く、最近のPCだとお手上げです。
そこで、市販のマイコンボードをPCにUSB接続し、USB接続でないFDDとの中継役をやらせることで、USBコネクタ経由で倍密度ディスクを読み書きしてみる実験を行いました。原理的にはシンプルなことしかやっていないのですが、個人でやってみた情報が見つからなかったので作業メモを公開してみます。PC-6601の1Dディスクでしか試していませんが、2DDなど他の倍密度ディスクでも基本的には大丈夫なはずです。また、マイコン用のプログラムのコンパイル・書き込みはWindowsXP (32bit) 上で、ディスクの吸い出しや書き込みはWindowsXP (32bit)、Linux 2.6.32、Windows7x64 on VMware Player 4.0.4 on Linux 2.6.32上でテストしました。何かの参考になれば幸いです。
ちなみに、同様のコンセプトのKryoFluxという専用ハードが既に存在しているようです。その廉価版・簡易版ということになるでしょうか。
ノートPC-マイコンボード-FDDと接続したところ
使用したマイコンボード。ピンヘッダ (使用するのは奥の方のみ。手前のはテスト用) と足だけ追加した
この手のマイコンボードを買うのは初めてでよくわからなかったので、以下の条件でえいやと選びました。
結局、秋月で売っていたAKI-RX62というボードにしました。開発セットが3800円、本体のみが2700円。開発セットの方は本体に加えて、開発ソフトやドキュメント、簡単な解説文書やサンプルプログラムなどを収録したCD-Rが付属しています。自分はこちらを購入しましたが、ソフトやドキュメントはルネサスのサイトからもダウンロードできるので (会員登録が必要)、慣れた人なら本体のみでも十分かもしれません。主なスペックは以下の通りです。
FDDはY-E DATA社のYD-702D-6238D (玄人志向 FDD-YE/S) を用いました。信号の電気的特性やタイミングはたぶん一般的な3.5インチ2HDドライブで共通ではないかと思います。FDDとマイコンボードの接続については、工作を最小限にしたかったので、マイコンボードの汎用I/O端子に2列のピンヘッダを立て、そこにFDDケーブルのコネクタを直接挿すようにしました。ケーブルは、10〜16番をひねってあるタイプのもの。ピンアサインは以下のようにしました。
マイコン | ボード | FDD | 信号名 | IN/OUT (FDDから見て) | 説明 |
---|---|---|---|---|---|
未接続 | 未接続 | 2 | MODE SELECT | IN | 2HDモード時に回転数を360rpmにする |
PA1 | CN2.ch2 | 8 | INDEX | OUT | トラックの開始位置信号 |
PA3 | CN2.ch4 | 16 | MOTOR ON | IN | ディスクを回転させるモーターをON |
PA7 | CN2.ch8 | 12 | DRIVE SELECT | IN | ドライブ使用時ONにする |
PB3 | CN2.ch12 | 18 | DIRECTION SELECT | IN | シーク方向を決める。ON時内側 |
PB5 | CN2.ch14 | 20 | STEP | IN | 1ステップ分シークする |
PB7 | CN2.ch16 | 22 | WRITE DATA | IN | データ書き込み信号 |
PC1 | CN2.ch18 | 24 | WRITE GATE | IN | データ書き込み時ONにする。OFF時リード・シーク可 |
PC3 | CN2.ch20 | 26 | TRACK 00 | OUT | ヘッドが最外周にあればON |
PC5 | CN2.ch22 | 28 | WRITE PROTECT | OUT | ライトプロテクトがかかったディスクならON |
PC7 | CN2.ch24 | 30 | READ DATA | OUT | データ読み取り信号 |
P21 | CN2.ch26 | 32 | SIDE ONE SELECT | IN | OFF時サイド0、ON時サイド1選択 |
未接続 | 未接続 | 34 | DISK CHANGE | OUT | 電源投入後もしくはディスクが抜かれるとON |
信号はすべて負論理で、ON=Low、OFF=High (3.3V) です。他に、奇数番はすべてリターンとなっています。Lowレベル出力としたのですが、本当ならGNDにしっかり落とした方がいいかもしれません。また、FDDが出力する信号を読むためにはプルアップの必要があります。マイコン内蔵のプルアップ機能を使用しましたが、すべてのI/Oポートにこの機能があるわけではなく、プルアップ可能なポートを最低限必要な信号線に割り当てるため、MODE SELECT信号とDISK CHANGE信号は使用しないことにしました。プルアップ抵抗を別途用意するなり離れたポートまで線を引くなりすれば済む話ではあるので、これは純然たる手抜きです。
PC-マイコン間のデータ転送は、1トラック分をまとめて行うようにしました。読み込み時ならば、1トラック読んでマイコンのRAMに貯める→PCに転送する→次のトラックを読む→……という繰り返しです。
FDDから出力されるデータリード信号は1ビットのON/OFFで、そのエッジを見ることになっています。3.5インチ倍密度ディスクでは、信号間の間隔は4μs/6μs/8μsの3種類 (上書きによるビットずれを除く) で、その時間がそのままONになるビット間の間隔に対応します。よって、読み取り時には信号のエッジから次の信号のエッジまでの時間を測り、2μsの分解能でその長さを分類して、どのビットをONにするかを判定するようにしました。いわゆるハーフビットという単位に相当します。以下にマイコン用プログラムのメイン部分を抜粋します。
index_old = ON;
while (INDEX == ON) ;
while (INDEX == OFF) ;
TMR01.TCNT = 0;
while (index_old == ON || INDEX == OFF){
if (INDEX == OFF){
index_old = OFF;
}
while (READ == ON) ;
while (READ == OFF) ;
time = TMR01.TCNT;
TMR01.TCNT = 0;
size += (time + freq) / (freq * 2);
data[size / 8] |= (0x80 >> (size % 8));
}
まずインデックス信号を空読みして、ONになるエッジを捉えたらメインループの開始です。メインループはインデックス信号が再びONになるエッジまで続きます。TMR01.TCNTはマイコン内蔵のタイマで、データリード信号の空読みを繰り返してONエッジを待ち、前のONエッジからの経過時間を測定するのに使います。タイマの周波数 (MHz) をfreqに入れておいて、時間が1〜3μsなら次のビットがON (これは本来なら現れない)、3〜5μsなら次の次のビットがON、5〜7μsならそのまた次のビットが……という具合にして配列に格納しています。
ただし、こうして得られたデータは、データビット以外にクロックビットも含んでおり、そのままでは使えません。一般的な環境ではFDCがデータビットとクロックビットの分離をやってくれるのですが、この実装では両者を区別せずにまとめて格納し、PCに取り込んだ後でソフトウェア的に分離するという方法をとることにしました。即ち、マイコンはデータ解釈を行わず、セクタの判別などもできません。とにかくトラック全体のデータを丸ごと取り込む機能しか持っておらず、PCに転送してから別途解析プログラムでセクタごとのデータを切り分ける (D88形式に変換する)、という方針です。
書き込み時はこの逆で、あらかじめ用意したD88形式のディスクイメージを変換プログラムにかけ、トラックごとの (クロックビットも含めた) ビットパターンを生成し、それをマイコンにコピーします。マイコンは2μsごとにビットパターンを見て、ONならばWRITE信号のONパルスを出力する、というのをトラック1周分繰り返します。こちらも特定のセクタにだけ書き込む機能は持っておらず、あらかじめ施されている物理フォーマットは無視してすべて上書きするようにしました。機能が低い代わりに、ビットパターンさえ用意すれば特殊な物理フォーマットも書くことが可能なので、まあ一長一短でしょうか。また、すべてのビットがゼロのデータを渡すか、サイズ1以上のファイルが無い状態で書き込むと、アンフォーマット動作になります。ちなみに書き込みの方は、時間精度向上のためプログラムを機械語で書いてみました。そう大きくは違わないでしょうが、恐らく0.1μs程度の精度で書き込めていると思われます。
動作テストの結果を見ると、読み込みはやや精度が悪いようで、FDD内蔵PCでFDC経由で読み出した場合に比べCRCエラーの確率が若干高まるようです。とは言え、大抵のディスクでは悪くても二三度読み込み直せば正しく読み取ることができました。ただディスクによって違うようで、稀にどうしても駄目なものもあります。この辺どうもよくわかりません。アルゴリズムを変更する、電気的にノイズ対策を講じるなど、もうひと工夫必要かも。機械語で書いてみたり、簡単なVFOやピークシフト補正も試みたのですが、改善は見られませんでした。
コピープロテクトのかかったディスクは完全には読み取れない可能性があります。例えばクォータービットに関する情報はこのプログラムでは欠落するため、そういったものを利用するディスクを読み出すには修正が必要でしょう。手持ちのPC-6601用ディスクにはそういった種類のものが無いため、深追いはしませんでした。D88形式で表現できる範囲の情報についてはほぼ取得できていると思うのですが。また書き込みについても、書き継ぎ点 (インデックス信号のONエッジ) 付近の情報を利用したい場合や、書き込み周波数を変更してデータを詰め込みたい場合などには、プログラム修正が必要になると思われます。
PC-マイコン間のUSB通信については、自分で一から書くのは大変そうなので、ルネサスが公開しているプログラムを利用することにしました。マイコンのRAMの一部をPCからUSBメモリとして使えるというもので、基本的な通信部分は変更せずにそのまま使い、そこにFDDコントロール部分を追加するような形で使っています。
追加した部分では、PCによってマイコンのRAM上にファイルが作成されると、そのファイル名をコマンド文字列として解釈し、規定の動作を行う、ということをやっています。例えばmtonという名前のファイルを作成するとモーターがONになり、次いでseek40という名前のファイルを作成するとシリンダ番号40までシークする、という具合です。読み書き用データのやりとりも、トラックごとのデータをUSBメモリ上のファイルとしてコピーするようにしました。
このページの終わりの方で紹介しますが、ディスク1枚分のデータを読んだり書いたりするには、こうした手続きをバッチファイルやシェルスクリプトにまとめたものを実行します。ただPC側のドライバの動作によって、思うように動かないケースがあり、対症療法としていくつか小細工が必要でした。例えば、コマンドやデータを書き込む際には、PC側の遅延書き込み機能をOFFにする必要がありますし、LinuxではOFFのやり方がわからなかったので、書き込む度にいちいちsyncコマンドを実行したりしています。
また、フロッピーを読む場合には、PCからすると新しいトラックを読む度にUSBメモリ上のデータが勝手に更新されることになるわけですが、PCのドライバは普通そんなことを想定していないので、キャッシュされた古いデータがいつまでも見えたままです。データを同期させる正式な方法というのがよくわからないため、今はとりあえず、Windowsならばchkdsk /f、Linuxならばumount/mountを実行して再認識を行うようにしています。
以下のようなコマンドを用意しました。
コマンド名 | 動作 |
---|---|
seek | 指定したシリンダまでヘッドを移動する。後ろに0〜81までの数字を付けて、seek5とかseek80などと指定する。 |
side | サイドを切り替える。side0もしくはside1として指定する。 |
read | 1トラック読む。 |
write | 1トラック書く。 |
recalib | 最外周までシークし、サイド0側を選択する。 |
mton | モーターをONする。 |
mtoff | モーターをOFFする。 |
手順としては以下のようになります。1〜4が事前準備です。
まず、マイコンのCN2のch1〜ch26に13×2のピンヘッダをハンダ付けします。14×2でもいいのですが、それより多いとケーブルが挿せなくなります。FDDケーブルは、10〜16番をひねってあるタイプのもの。接続の際は、1ピン側は3×2空けて、マイコンボードのch1がFDDのch7になるようにします。次は電源。マイコンの電源はUSBで与えられますが、FDDの電源は別途用意する必要があります。自分は手軽に使いたくてDCアダプタを接続できるようにしていますが、電圧の安定やノイズ抑制を考えると、ちゃんとしたPC用電源を使った方が良いかも。
フラットケーブルを接続したところ。ピンアサインの都合で左右が空いている
gccなどでもプログラム開発は可能らしいのですが、ここではルネサスが配布している標準的な環境を用いたWindowsXP上でのやり方についてメモ。
開発環境としては「HEW (High-performance Embedded Workshop) 無償評価版」、マイコンへのプログラム書き込みとしては「FDT (Flash Development Toolkit) 無償評価版」を用いました。どちらもAKI-RX62開発セット同梱のCD-Rに収録されていますが、ルネサスのサイトより最新版のダウンロードも可能です (会員登録が必要)。開発環境にはCubeSuite+というのもあって、今後はそちらにシフトしていくっぽい?
PC側のプログラムとして、以下のものを作成しました。バッチファイルとシェルスクリプトについては、USB通信の項に書いたように少々小細工を弄しているので、他の環境で動くかどうか少し自信がありません。手元の環境では、Linuxの場合はroot権限が必要でした。
トップ > 雑多なもの > マイコンボードを用いた3.5インチ倍密度フロッピーのUSBリード/ライト実験