マイコンボードを用いた3.5インチ倍密度フロッピーのUSBリード/ライト実験

(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という専用ハードが既に存在しているようです。その廉価版・簡易版ということになるでしょうか。

RXマイコン
ノートPC-マイコンボード-FDDと接続したところ


目次


マイコン選び

RXマイコン
使用したマイコンボード。ピンヘッダ (使用するのは奥の方のみ。手前のはテスト用) と足だけ追加した

この手のマイコンボードを買うのは初めてでよくわからなかったので、以下の条件でえいやと選びました。

結局、秋月で売っていたAKI-RX62というボードにしました。開発セットが3800円本体のみが2700円。開発セットの方は本体に加えて、開発ソフトやドキュメント、簡単な解説文書やサンプルプログラムなどを収録したCD-Rが付属しています。自分はこちらを購入しましたが、ソフトやドキュメントはルネサスのサイトからもダウンロードできるので (会員登録が必要)、慣れた人なら本体のみでも十分かもしれません。主なスペックは以下の通りです。


FDDの接続とI/O制御

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エッジ) 付近の情報を利用したい場合や、書き込み周波数を変更してデータを詰め込みたい場合などには、プログラム修正が必要になると思われます。


USB通信

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が事前準備です。


1.マイコンやFDDの配線・接続

まず、マイコンのCN2のch1〜ch26に13×2のピンヘッダをハンダ付けします。14×2でもいいのですが、それより多いとケーブルが挿せなくなります。FDDケーブルは、10〜16番をひねってあるタイプのもの。接続の際は、1ピン側は3×2空けて、マイコンボードのch1がFDDのch7になるようにします。次は電源。マイコンの電源はUSBで与えられますが、FDDの電源は別途用意する必要があります。自分は手軽に使いたくてDCアダプタを接続できるようにしていますが、電圧の安定やノイズ抑制を考えると、ちゃんとしたPC用電源を使った方が良いかも。

RXマイコン
フラットケーブルを接続したところ。ピンアサインの都合で左右が空いている


2.開発環境のダウンロード・インストール

gccなどでもプログラム開発は可能らしいのですが、ここではルネサスが配布している標準的な環境を用いたWindowsXP上でのやり方についてメモ。

開発環境としては「HEW (High-performance Embedded Workshop) 無償評価版」、マイコンへのプログラム書き込みとしては「FDT (Flash Development Toolkit) 無償評価版」を用いました。どちらもAKI-RX62開発セット同梱のCD-Rに収録されていますが、ルネサスのサイトより最新版のダウンロードも可能です (会員登録が必要)。開発環境にはCubeSuite+というのもあって、今後はそちらにシフトしていくっぽい?

  1. ルネサスのサイトより、http://japan.renesas.com/products/tools/evaluation_software/index.jsp から「RXファミリ用C/C++コンパイラパッケージ」「SuperH RISC Engine, RX, H8SX, H8S, H8, M16C, R8C, 740ファミリ 用 フラッシュ 開発 ツールキット(Flash Development Toolkit)」をダウンロードできます。
    (※FDTインストール中はマイコンを接続しないこと)
  2. ルネサスのサイト より、「Renesas USB MCU and USB ASSP USB Peripheral Mass Storage Class Driver Rev.2.10 C Source」(以下、PMSC) をダウンロードし、展開します。このソースを一部置き換えてビルドすることになります。(現在最新のバージョンは2.20となっているため、2.10はいつまでダウンロードできるかわからない状況です)

3.マイコンプログラムのビルド

  1. まず、ダウンロードしたPMSCソースのうち、マイコンの機種に依存する部分をコピーしてやる必要があります。PMSCを展開した下の、「an_r01an0514jj0210_usb\workspace\RX600_USB_PmscFW_nonOS_Rev210_BasicRev210\WorkSpace\HwResourceForUSB_RX62N」以下にあるファイル一式を、「an_r01an0514jj0210_usb\workspace\RX600_USB_PmscFW_nonOS_Rev210_BasicRev210\WorkSpace\HwResourceForUSB」以下にコピーします。
  2. サンプルアプリケーションを置き換えます。PMSCを展開した下にある、「an_r01an0514jj0210_usb\workspace\RX600_USB_PmscFW_nonOS_Rev210_BasicRev210\WorkSpace\SmplMain\APL\r_usb_pmsc_apl.c」が本来のファイルです。これを、FDDコントロール用のプログラムファイル(2013.8.24修正) で置き換えます。
  3. HEWを起動します。デフォルトインストールの場合、スタートメニューから「Renesas > High-performance Embedded Workshop > High-performance Embedded Workshop」で。
  4. 「別のプロジェクトワークスペースを参照する」を選択して、PMSCを展開した下にある、「an_r01an0514jj0210_usb\workspace\RX600_USB_PmscFW_nonOS_Rev210_BasicRev210\Fw.hws」を指定します。
  5. 左側のペインで、「Fw > NonOS_MscFw > Dependencies > r_usb_usrconfig.h」を選択し、#define USB_SDRAM_USE_PP という行を、削除ないしコメントアウトします。

    HEW

  6. ビルドします。メニューから「ビルド > すべてをビルド」

4.マイコンへのプログラム書き込み

  1. 付属のUSBケーブルでマイコンボードとPCを接続します。
  2. マイコンボードのスイッチを以下の設定にします。
  3. FDTを起動します。デフォルトインストールの場合、スタートメニューから Renesas > Flash Development Toolkit 4.08 > Flash Development Toolkit 4.08 Basic で。
  4. 初回は「デバイスとカーネルの選択」「通信ポート」というウィンドウが開くので、それぞれ「Generic BOOT Device」「USB Direct」を選択します。

    FDT

    FDT

  5. 「Select USB Device」というウィンドウで「1 USB device located」と表示されたら、表示されたデバイスを選択します。「汎用デバイスの確認」ウィンドウですべての項目にチェックが入ったらOK。うまくいかない場合は、ドライバのインストールに失敗している可能性があります。一旦アンインストールして、「マイコンボードを接続せずに」FDTをインストールし直すと直るかも。

    FDT

    FDT

  6. 「デバイス設定」ウィンドウが開いたら、以下のように設定します。

    FDT

  7. 「接続完了しました」と表示されたら、File SelectionのUser/Data Areaに、PMSCを展開した下にある「an_r01an0514jj0210_usb\workspace\RX600_USB_PmscFW_nonOS_Rev210_BasicRev210\WorkSpace\SmplMain\Project\Project_NonOs_MscFw\PERI\NonOS_MscFw.mot」を指定します。2回目以降はここで「Select USB Device」ウィンドウが開きます。
  8. 「書き込みが完了しました」と表示されたら「デバイスとの切断」を押して、「ブロックのロック」ウィンドウでそのまま「OK」。「Disconnected」と表示されたら終了です。

    FDT

    FDT

  9. POWER SW (S1) を一旦OFFにし、CN4-1をOFF (Singleモード) にしておきます。

5.フロッピーの読み書き

PC側のプログラムとして、以下のものを作成しました。バッチファイルとシェルスクリプトについては、USB通信の項に書いたように少々小細工を弄しているので、他の環境で動くかどうか少し自信がありません。手元の環境では、Linuxの場合はroot権限が必要でした。


5-1.FDを読む場合

  1. マイコンボードとFDDを接続した後、POWER SW (S1) をONにします。
  2. Windowsの場合、「新しいハードウェアが見つかりました」と表示されてドライバがインストールされる場合があります。一般的なUSBメモリが読める環境ならば、少し待てば完了するはずです。
  3. 読み取り用のバッチファイル (Windows用) もしくはシェルスクリプト (Linux用) を実行します。Windowsの場合、遅延書き込みはOFFにしておいてください。
  4. 1D用で、Windows用バッチファイルはドライブGを、Linux用スクリプトはデバイス/dev/sdcとマウントポイント/mnt を前提としているので、それ以外の場合はファイル中のcylstep, sidemax, drv, dev, mountを適宜変更してください。
  5. うまく読めれば、c**h*.datという名前のファイルがたくさん作成されます。*の部分はシリンダ番号とヘッド番号です。
  6. 同じディレクトリで、D88への変換プログラム (Windows用実行ファイル / ソース) を実行すると、fd.d88というファイルが作成されます。引数を与えて実行すればファイル名は変更可能です。1D以外を変換する場合は、ソースのNSIDE, NCYLINDER, TRACK_DENSITYあたりを書き換えてコンパイルすれば可能だと思います。
  7. 変換時にエラーが表示される場合は、読み取りに失敗しているかもしれません。何度かやり直してみてください。
  8. Windowsで「ボリュームが別のプロセスによって使用されているため、Chkdskを実行できません。」と表示される場合は、エクスプローラをすべて閉じてみてください。

5-2.FDに書く場合

  1. マイコンボードとFDDを接続した後、POWER SW (S1) をONにします。
  2. Windowsの場合、「新しいハードウェアが見つかりました」と表示されてドライバがインストールされる場合があります。一般的なUSBメモリが読める環境ならば、少し待てば完了するはずです。
  3. 書きたいディスクイメージをD88形式で用意します。
  4. D88からの変換プログラム (Windows用実行ファイル / ソース) を実行します。入力ファイル名のデフォルトはfd.d88ですが、引数を与えて実行すれば変更できます。
  5. c**h*.datという名前のファイルがたくさん作成されます。*の部分はシリンダ番号とヘッド番号。
  6. 同じディレクトリで、書き込み用のバッチファイル (Windows用) もしくはシェルスクリプト (Linux用) を実行します。Windowsの場合、遅延書き込みはOFFにしておいてください。
  7. Windows用バッチファイルはドライブGを、Linux用スクリプトはデバイス/dev/sdcとマウントポイント/mntを前提としているので、それ以外の場合はファイル中のdrv, dev, mountを適宜変更してください。

トップ > 雑多なもの > マイコンボードを用いた3.5インチ倍密度フロッピーのUSBリード/ライト実験