Arduino Amigaフロッピーディスクリーダー(V1)
コンポーネントと消耗品
> ![]() |
| × | 1 | |||
![]() |
| × | 1 | |||
![]() |
| × | 1 | |||
![]() |
| × | 1 | |||
![]() |
| × | 1 |
アプリとオンラインサービス
> ![]() |
|
このプロジェクトについて
- 私の目的: Windows10およびその他のオペレーティングシステム内からAmigaDDフロッピーディスクからデータを回復するためのシンプルで安価なオープンソースの方法を作成するため。
- 私の解決策: Arduino + Windowsアプリケーション
- 理由: これらのディスクからのデータを将来のために保存するため。また、通常のPCは、書き込み方法が原因でAmigaディスクを読み取ることができません。
プロジェクトのウェブサイト:http://amiga.robsmithdev.co.uk/
これはプロジェクトのV1です。 V2には、改善された読み取りと書き込みが含まれています!
Amiga Experiences
私のキャリアはAmiga、特に両親が10歳のときにクリスマスに購入してくれたA500 +のおかげです。最初はゲームをプレイしていましたが、しばらくすると他に何ができるのか知りたくなりました。 Deluxe Paint IIIで遊んで、Workbenchについて学びました。
Amiga 500 Plus:
<図>
毎月人気のAmigaFormatマガジンを購入しました。 1か月間、AMOSの無料コピーがありました。 Amiga形式を入力しました AMOSでゲームを書く 後でAMOSProfessionalがカバーディスクに載せられたときの競争であり、 In The Pipe Line で12人の(私が思うに)勝者の1人でした。 。しかし、あなたは本当に賞品を求めて彼らを追いかけなければなりませんでした!
AMOS-作成者:
<図>
背景
続いて、GCSEおよびAレベルプロジェクトの一部として使用しました(PC上のTurboPascalと互換性のあるHighspeedPascalのおかげで)
とにかく、それはずっと前のことで、ディスクの箱があり、A500 +が機能しなくなったので、保存と懐かしさの両方のために、それらのディスクをコンピューターにバックアップすることを考えました。
Amiga ForeverのWebサイトには、ハードウェアやPCで2つのフロッピードライブを悪用するなどの優れたオプションのリストがあります。残念ながら、これらはいずれも最新のハードウェアのオプションではなく、KryoFlux / Catweaselコントローラーは高すぎます。そのほとんどがクローズドソースであることに本当に驚きました。
電子機器に大いに興味を持ち、Atmelデバイス( AT89C4051 )大学にいる間、私はArduino( GreatScott のクレジット)を見てみることにしました。 始めるのがいかに簡単かを示すインスピレーションのために)これが可能かどうか疑問に思いました。
そこで、 Arduinoフロッピードライブの読み取りをグーグルで検索しました。 コード、および乱用したすべてのプロジェクトをスキップした後 音楽を再生するためのドライブ、私は本当に解決策を見つけられませんでした。いくつかのグループで、それが不可能であることを示唆するいくつかの議論を見つけました。 FPGAをベースにしたプロジェクトを見つけましたが、これは非常に興味深い読み物でしたが、行きたい方向性ではなかったため、唯一の選択肢は自分でソリューションを構築することでした。
調査
このプロジェクトを開始したとき、フロッピードライブがどのように機能するか、さらにはデータがどのようにそれらにエンコードされているかについての手がかりがありませんでした。次のWebサイトは、何が起こり、どのように機能するかを理解する上で非常に貴重でした。
- techtravels.org(およびこのページ)
- LaurentClévyによる.ADF(Amiga Disk File)形式のFAQ
- Amiga Forever
- ウィキペディア-Amigaディスクファイル
- 英語のAmigaボード
- QEEWiki-ATmega168 / 328のカウンター
- フロッピードライブのピン配列
- フロッピーディスクフォーマットのリスト
前提条件
調査に基づいて、データがどのようにディスクに書き込まれ、ディスクがどのように回転するかを理論的に理解しました。
私はいくつかの数字を考え始めました。倍密度ディスクが(300rpm)で回転する速度とデータの保存方法(80トラック、トラックあたり11セクター、セクターあたり512バイト、MFMを使用してエンコード)に基づいて、データを正確に読み取るには、次のことができる必要がありました。 500Khzでデータをサンプリングします。 Arduinoが16MHzでしか動作していないことを考えると、これは非常に高速です。
次の試みでは、Arduino側についてのみ話します。デコードにジャンプします。
試行1:
まず、ハードウェアとフロッピードライブへのインターフェイスを収集する必要がありました。職場の古いPCから取り出したフロッピードライブを、同時にIDEケーブルをつかみました。
以下は解放されたの写真です 古いPCのフロッピードライブ:
<図>
ドライブのピン配置を調べたところ、必要な配線はほんの数本でした。ドライブを見た後、12v入力も使用していないことに気付きました。
ドライブを回転させるには、ドライブを選択してモーターを有効にします。頭を動かすのは簡単でした。 / DIR を設定します ハイまたはローにピン留めしてから、 / STEP をパルスします。 ピン。 / TRK00 を監視することで、頭がトラック0(最初のトラック)に到達したかどうかを確認できます。 ピン。
/ INDEX に興味がありました ピン。これは、1回転ごとに1回パルスします。 Amigaはトラックの開始を見つけるためにこれを使用しないので、私はそれを必要とせず、無視することができました。この後、ディスクのどちら側を読み取るかを選択するだけです( / SIDE1 )そして / RDATA に接続します 。
データレートの要件が高いため、私の最初の考えは、このレートの要件を減らすことで、これを問題の少ないものにする方法を見つけることでした。
計画では、2つの8ビットシフトレジスタ( SN74HC594N )必要なサンプリング周波数を8分の1に減らすために使用しました。私が使用したのは、Ebayが Pro Miniatmega328ボード5V16MArduino互換ナノと呼んでいたものです。 (したがって、それが公式に何であるかはわかりませんが、これはUnoで機能します!)この並列をバッファリングします データを取得し、シリアル/ USARTインターフェースを使用してPCに送信します。これは500Kbaudよりも高速に実行する必要があることを私は知っていました(すべてのシリアルオーバーヘッドも含まれます)。
sn74hc594.pdf標準のArduinoシリアルライブラリを捨てた後、Arduinoで最大2MボーでUSARTを構成でき、それらのF2DIブレイクアウトボードの1つ(eBayではFTDIFT232RLの基本ブレイクアウトボードと呼ばれていました)を使用できることを本当に嬉しく思いました。 Arduino用のUSBからシリアルICへ -以下を参照)このレート(62.5Khz)でデータを楽しく送受信できましたが、これを正確に行う必要がありました。
Atmel-42735-8ビット-AVR-マイクロコントローラー-ATmega328-328P_Datasheet.pdfArduinoボードのインターフェースに完全に適合するFTDIブレークアウトボード:
<図>
まず、Arduinoを使用して8ビットシフトレジスタをセットアップし、8ビットのうち1つだけをHighにクロックしました。もう1つは、フロッピードライブから直接フィードを受信しました(したがって、シリアルからパラレルへの変換を提供します)。
以下は、当時私がこれを作成したブレッドボードのクレイジーな写真です。
<図>
Arduinosタイマーの1つを使用して、出力ピンの1つで500Khz信号を生成しました。ハードウェアがこれを管理するため、非常に正確です。 -まあ、私のマルチメータはとにかくそれを正確に500kHzと測定しました。
コードは機能し、62.5kHzで完全な8ビットのデータをクロックインしたため、ArduinoCPUはほとんど使用されませんでした。しかし、私は意味のあるものを何も受け取っていませんでした。この時点で、フロッピードライブから出力される実際のデータを詳しく調べる必要があることに気付きました。そこで、eBay(Gould OS300 20Mhz Oscilloscope)から安価な古いオシロスコープを購入して、何が起こっているのかを確認しました。
オシロスコープが到着するのを待っている間、私は別のことを試してみることにしました。
シフトレジスタからデータを読み取るために使用されるコードのフラグメント:
void readTrackData(){byte op; for(int a =0; a <5632; a ++){//「バイト」開始マーカーを待機しますwhile(digitalRead(PIN_BYTE_READ_SIGNAL)==LOW){}; //バイトを読み取りますop =0; if(digitalRead(DATA_LOWER_NIBBLE_PB0)==HIGH)op | =1; if(digitalRead(DATA_LOWER_NIBBLE_PB1)==HIGH)op | =2; if(digitalRead(DATA_LOWER_NIBBLE_PB2)==HIGH)op | =4; if(digitalRead(DATA_LOWER_NIBBLE_PB3)==HIGH)op | =8; if(digitalRead(DATA_UPPER_NIBBLE_A0)==HIGH)op | =16; if(digitalRead(DATA_UPPER_NIBBLE_A1)==HIGH)op | =32; if(digitalRead(DATA_UPPER_NIBBLE_A2)==HIGH)op | =64; if(digitalRead(DATA_UPPER_NIBBLE_A3)==HIGH)op | =128; writeByteToUART(op); //(digitalRead(PIN_BYTE_READ_SIGNAL)==HIGH){};の間、高値が再び下がるのを待ちます}}
試行2:
私はシフトレジスターを決定しましたが、良いアイデアはおそらく役に立たなかったでしょう。一度に8ビットを簡単に読み取ることができましたが、そもそもすべてのビットが正しくクロックインされているかどうか確信が持てないことに気づきました。ドキュメントを読むと、データは高低ではなく短いパルスであることがわかりました。
シフトレジスタを削除し、以前に設定した500Khz信号を使用して、割り込み(ISR)でドライブからのパルスをチェックしようとするとどうなるか疑問に思いました。 Arduinoを再構成してISRを生成し、Arduinoライブラリが邪魔になる問題を(必要なISRを使用して)通過した後、タイマー2に移動しました。
グローバルシングルバイトを1ビット左にシフトする短いISRを作成し、フロッピードライブのデータラインに接続されているピンが LOW の場合 (パルスは低調です)私はそれに1をORします。これを8回行うたびに、完成したバイトをUSARTに書き込みました。
これは期待どおりに進みませんでした! Arduinoは非常に不規則で奇妙な動作をし始めました。 ISRは、呼び出し間の時間よりも実行に時間がかかっていることにすぐに気付きました。 Arduinoの速度に基づいて、2µSecごとにパルスを受信でき、すべての C命令を大胆に想定しました。 1クロックマシンコードサイクルに変換 私はせいぜい32の命令を持つことができることに気づきました。悲しいことに、ほとんどは複数の命令であり、グーグルした後、ISRを開始する際のオーバーヘッドがとにかく大きいことに気づきました。 digitalRead関数が非常に遅いことは言うまでもありません。
digitalRead を捨てました ポートピンに直接アクセスするために機能します!これはまだ役に立たず、十分な速さではありませんでした。諦める準備ができていなかったので、私はこのアプローチを棚上げし、先に進んで別のことを試すことにしました。
この時点で、購入したオシロスコープが到着し、動作しました。おそらく私より古い、無愛想な古いオシロスコープ!しかし、それでも完璧に仕事をしました。 (オシロスコープが何であるかわからない場合は、EEVblog#926-オシロスコープの概要を確認してください。電子機器に興味がある場合は、もう少し見て、EEVBlogWebサイトを参照することをお勧めします。
新しく購入した無愛想な古いオシロスコープ(Gould OS300 20Mhz):
<図>
500Khz信号を1つのチャネルに接続し、フロッピードライブからの出力を別のチャネルに接続した後、何かが正しくないことが明らかになりました。 500Khz信号は、トリガーとして使用する完全な方形波であり、フロッピーデータはいたるところにありました。パルスは見えましたが、ぼやけていました。同様に、フロッピードライブ信号からトリガーした場合、500Khz信号の方形波信号がいたるところにあり、同期していませんでした。
2つのチャネルからトリガーされるオシロスコープのトレースの写真。あなたはそれを完全に見ることはできませんが、チャンネルでは トリガーされるのは、何千ものかすかな幽霊のような線です:
<図>
個別に、500Khzで両方の信号からのパルスを測定できましたが、両方が同じ速度で実行されているかのように意味がありませんでしたが、トリガーされないため、両方の信号を正しく表示できるので、何かが間違っている必要があります。
トリガーレベルでたくさん遊んだ後、私は何が起こっているのかを理解することができました。私の信号は完璧な500Khzでしたが、フロッピードライブの信号を見ると、正しく間隔が空けられていましたが、常にではありませんでした。パルスのグループ間にはエラードリフトがあり、データにギャップがあり、信号が完全に同期していませんでした。
以前の調査を思い出すと、ドライブは300rpmで回転するはずでしたが、実際には正確に300rpmではない可能性があり、さらにデータを書き込んだドライブも正確に300rpmではない可能性があります。次に、セクターとセクターギャップの間に間隔があります。明らかに同期の問題があり、読み取りの開始時に500Khz信号をフロッピードライブに同期することはできませんでした。
また、フロッピードライブからのパルスが非常に短いことも発見しましたが、プルアップ抵抗を変更することでこれを変更できます。タイミングが正確に正しくない場合、Arduinoはパルスをすべて見逃す可能性があります。
私が大学(レスター大学)にいたとき、私は組み込みシステムと呼ばれるモジュールを取りました。 Atmel8051マイクロコントローラーを研究しました。プロジェクトの1つは、シミュレートされた気象観測所(ロータリーエンコーダー)からのパルスをカウントすることでした。当時、私は定期的にピンをサンプリングしていましたが、これはあまり正確ではありませんでした。
モジュール講師、教授ポン ハードウェアカウンターを使用する必要があることを提案しました デバイスの機能(一度はあったことすら知りませんでした。)
ATMega328のデータシートを確認し、3つのタイマーのそれぞれが、外部入力からトリガーされたパルスをカウントするように構成できることを確認しました。これは、速度がもはや問題ではなくなったことを意味します。私が実際に知る必要があるのは、2µSecの時間枠内にパルスが発生したかどうかだけでした。
試行3:
Arduinoスケッチを調整して、最初のパルスが検出されたときに500khzタイマーをリセットし、500khzタイマーがオーバーフローしたときに、カウンター値をチェックして、パルスが検出されたかどうかを確認しました。次に、同じビットシフトシーケンスを実行し、8ビットごとに1バイトをUSARTに書き込みました。
データが入ってくると、PCで分析を始めました。データの中で、私は有効なデータのように見えるものを見始めました。奇妙な同期ワード、または0xAAAAシーケンスのグループが表示されますが、信頼できるものはありません。私は何かに取り組んでいることを知っていましたが、それでも何かが欠けていました。
試行4:
データが読み取られているときに、ドライブからのデータが500kHzの信号と同期/位相がずれている可能性があることに気付きました。読み始めるたびに20バイトを読むだけでこれを確認しました。
この同期の問題を処理する方法について読んで、私はフェーズロックループまたはPLLというフレーズに出くわしました。非常に簡単に言えば、私たちが行っていることでは、フェーズロックループはクロック周波数(500kHz)を動的に調整して、信号の周波数ドリフトと変動を補正します。
タイマーの解像度は、十分に小さい量(たとえば、444khz、470khz、500khz、533khz、571khzなど)で変化させるほど高くはなく、これを適切に実行するには、コードをはるかに高速に実行する必要があります。
Arduinoタイマーは、事前定義された数(この場合は500khzの場合は16 )までカウントすることで機能します。 )次に、オーバーフローレジスタを設定し、0から再開します。実際のカウンタ値は、いつでも読み取りおよび書き込みが可能です。
タイマーがオーバーフローするまでループで待機するようにスケッチを調整し、オーバーフローしたときに以前と同じようにパルスをチェックしました。今回の違いは、いつ ループ内でパルスが検出された場合、タイマーカウンター値を事前定義されたフェーズにリセットします。 位置、各パルスでタイマーを効果的に再同期します。
タイマーカウンターに書き込んだ値は、検出パルスから1µSecでオーバーフローするように(途中で)選択しました。これにより、次回タイマーがオーバーフローしたときに、パルスが2µSec離れていました。
これはうまくいきました!私は今、ディスクからほぼ完璧なデータを読み取っていました。私はまだ多くのチェックサムエラーを受け取っていましたが、それは迷惑でした。有効なヘッダーとデータのチェックサムを備えた11セクターすべてが揃うまで、ドライブ上の同じトラックを継続的に再読み取りすることで、これらのほとんどを解決しました。
この時点で興味があったので、すべてをオシロスコープに接続して、現在何が起こっているかを確認しました。推測したとおり、両方のトレースが互いに同期しているので、両方のトレースを確認できました。
<図>
誰かが私に最高級のデジタルオシロスコープ(たとえば、Keysightのものの1つ!)を寄付してくれたら、これをもう少し明確にしたいと思います。本当に感謝しています!
試行5:
これを改善できるかと思いました。コード、具体的には内部の読み取りループ(以下を参照)を見ると、オーバーフローを待機しているwhileループがあり、次に内部の if 同期するパルスを探しています。
データの読み取りと同期に使用されるコードのフラグメント:
register bool done =false; // 500khzオーバーフローを待機しますwhile(!(TIFR2&_BV(TOV2))){// 500khzパルスの待機中に立ち下がりエッジが検出されました。 if((TCNT0)&&(!done)){//パルスが検出されたら、タイマーカウンターをリセットしてパルスと同期させますTCNT2 =phase; //パルスが再びハイになるのを待ちます(!(PIN_RAW_FLOPPYDATA_PORT&PIN_RAW_FLOPPYDATA_MASK)){};完了=true; }} //オーバーフローフラグをリセットTIFR2 | =_BV(TOV2); //ドライブからのパルスを検出しましたか?if(TCNT0){DataOutputByte | =1; TCNT0 =0;}
上記のループで実行されている命令に応じて、パルス検出から TCNT2 =phase;
の書き込みまでの時間に気づきました。 いくつかの命令を実行するのにかかる時間によって変化する可能性があります。
これがデータにエラー/ジッターを引き起こしている可能性があり、上記のループでも実際にドライブからのパルスを見逃す可能性があることに気づきました(したがって再同期ビットが欠けています)以前の1つからトリックを取ることにしました試行、ISR(割り込み)。
データパルスをArduinoの2番目のピンに配線しました。これで、データはCOUNTER0トリガーに接続され、INT0ピンにも接続されました。 INT0は最も高い割り込み優先度の1つであるため、トリガーと呼び出されるISRの間の遅延を最小限に抑える必要があります。これは、私が実際に関心を持っている唯一の割り込みであるため、他のすべてが無効になっています。
必要な割り込みは、上記の再同期コードを実行することだけでした。これにより、コードが次のように変更されました。
// 500khzオーバーフローを待つwhile(!(TIFR2&_BV(TOV2))){} //オーバーフローフラグをリセットTIFR2 | =_BV(TOV2); //ドライブからのパルスを検出しましたか?if(TCNT0){DataOutputByte | =1; TCNT0 =0;}
ISRは次のようになりました:(これは呼び出しにオーバーヘッドを追加するため、attachInterruptを使用しなかったことに注意してください)。
volatile byte targetPhase; ISR(INT0_vect){TCNT2 =targetPhase;}
これをコンパイルすると、十分な速度で実行するにはコードが多すぎます。実際、上記を分解すると、次のようになります。
push r1push r0in r0、0x3f; 63push r0eor r1、r1push r24 lds r24、0x0102; 0x800102 sts 0x00B2、r24; 0x8000b2 pop r24pop r0out 0x3f、r0; 63pop r0pop r1reti
コードを分析することで、実際に必要な命令はほんのわずかしかないことに気づきました。コンパイラがバッシングしたレジスタを追跡することに注意して、ISRを次のように変更しました。
volatile byte targetPhase asm( "targetPhase"); ISR(INT0_vect){asm volatile( "lds __tmp_reg __、targetPhase"); asm volatile( "sts%0、__ tmp_reg__" :: "M"(_ SFR_MEM_ADDR(TCNT2)));}
分解すると、次の手順が生成されます。
push r1push r0in r0、0x3f; 63push r0eor r1、r1lds r0、0x0102; 0x800102 sts 0x00B2、r0; 0x8000b2 pop r0out 0x3f、r0; 63pop r0pop r1reti
まだ指示が多すぎます。コンパイラーが多くの追加の命令を追加していることに気づきました。私のアプリケーションでは、実際にそこにある必要はありませんでした。そこで、 ISR()を調べました。 そして、2番目のパラメータISR_NAKEDに出くわしました。これを追加すると、コンパイラが特別なコードを追加できなくなりますが、レジスタ、スタックを維持し、割り込みから正しく戻る責任があります。また、SREGレジスタを維持する必要がありますが、呼び出す必要のあるコマンドはどれも変更されていないため、心配する必要はありませんでした。
これにより、ISRコードが次のように変更されました。
ISR(INT0_vect、ISR_NAKED){asm volatile( "push __tmp_reg__"); // tmp_register asm volatile( "lds __tmp_reg __、targetPhase");を保持します//フェーズ値をtmp_registerにコピーしますasmvolatile( "sts%0、__ tmp_reg__" ::"M"(_ SFR_MEM_ADDR(TCNT2))); // tmp_registerを、TCNT2がasm volatile( "pop __tmp_reg__");であるメモリ位置にコピーします。 // tmp_register asm volatile( "reti");を復元します//そしてISRを終了します}
コンパイラが変換したもの:
push r0lds r0、0x0102; 0x800102 sts 0x00B2、r0; 0x8000b2 pop r0reti
5つの指示!理論的には、実行に0.3125µSecを要します。これは、パルス後の時間的に一定の期間に再同期が行われる必要があることを意味するはずです。以下は、何が起こっているかのタイミング図です。これは、クロック信号のないシリアルデータフィードからデータを回復する方法です。
<図>
これにより、結果が少し改善されました。まだ完璧ではありません。一部のディスクは毎回完全に読み取りますが、一部のディスクは古くなり、再試行を続ける必要があります。これは、一部のディスクが長時間そこに置かれているために、磁気が非常に低いレベルに低下してドライブアンプが対応できないためかどうかはわかりません。これはPCフロッピーディスクドライブと関係があるのだろうかと思ったので、これを持っていた外付けのAmigaフロッピーディスクドライブに接続しましたが、結果は同じでした。
試行6:
他にできることはないかと思いました。おそらく、ドライブからの信号は、私が思っていたよりもノイズが多かったのでしょう。さらに情報を読んだ後、1KOhmのプルアップ抵抗が標準であり、シュミットトリガーに供給されていることを発見しました。
SN74HCT14N Hex Schmittトリガーをインストールし、スケッチを再構成して、立ち下がりエッジではなく立ち上がりエッジでトリガーした後、試してみましたが、目立った違いはありませんでした。おそらく吸収された毎回1つ以上のパルスを探していたので、 とにかくノイズ。そこで、メソッドAttempt 5を使用します!
sn74hct14.pdf私の最終的なブレッドボードソリューションは次のようになりました:
<図>
上記の配線は、ライブスケッチとは少し異なることに注意してください。回路図を簡単にするために、いくつかのArduinoピンを並べ替えました。
試行7:
読んでいないディスクのいくつかに少し不満がありました。ディスクがフロッピードライブに正しく挿入されていない場合がありました。シャッターのバネが効かなかったと思います。
ディスクから実際に受信したMFMデータにエラーがあるかどうかを検出することを検討し始めました。
MFMエンコーディングがどのように機能するかのルールから、次のようにいくつかの簡単なルールを適用できることに気付きました。
- 2つの「1」ビットを隣り合わせにすることはできません
- 「0」ビットを3つ以上並べることはできません
まず、MFMデータをデコードするときに、2つの「1」が連続しているかどうかを確認しました。もしそうなら、データは時間の経過とともに少しぼやけていたと思い、2番目の「1」を無視しました。
このルールを適用すると、エラーが発生する5ビットの状況が文字通り3つあります。これは、データを改善するために検討できる新しい領域になります。
しかし、ほとんどの場合、MFMエラーがそれほど多く検出されなかったことに驚きました。エラーが見つからないのに一部のディスクが読み取れない理由が少しわかりません。
これはさらに調査するための領域です。
デコード
MFMがどのように機能するかを読んだ後、MFMがどのように正しく調整されているか完全にはわかりませんでした。
最初は、ドライブがオンビットとオフビットに対して1と0を出力すると思いました。そうではありませんでした。ドライブは、すべての相転移、つまりデータが0から1、または1から0になるたびにパルスを出力します。
これを読んだ後、フリップフロップのトグルにフィードしてこれを1と0に戻す必要があるのか、それともデータを読み取ってセクターを検索する必要があるのか疑問に思いました。見つからない場合は、データを反転して再試行してください。
これは事実ではなく、はるかに簡単であることがわかりました。パルスは実際にはRAWMFMデータであり、デコードアルゴリズムに直接供給することができます。これを理解したので、ドライブからバッファーをスキャンして同期ワード0x4489を検索するコードを書き始めました。驚いたことに見つけました!
私が行った調査から、実際に 0xAAAAAAAA44894489 を検索する必要があることに気付きました。 (調査のメモでは、初期のAmigaコードにいくつかのバグがあり、上記のシーケンスが見つからなかったことが示唆されました。そのため、代わりに 0x2AAAAAAA44894489 を検索しました。 データを 0x7FFFFFFFFFFFFFFF とAND演算した後 。
予想通り、11のAmigaセクターの実際の開始に対応する各トラックでこれらのうち最大11を見つけました。次に、後続のバイトを読み取り始めて、セクター情報をデコードできるかどうかを確認しました。
MFMデコードを支援するために、上記のリファレンスの1つからコードの一部を取り出しました。車輪の再発明に意味はありませんか?
ヘッダーとデータを読み取った後、ADFファイルとしてディスクに書き込んでみました。標準のADFファイル形式は非常に単純です。文字通り、順番に書き込まれる各セクター(ディスクの両側から)からの512バイトです。それを書き込んでADFOpusで開こうとしたところ、結果がまちまちでしたが、ファイルを開くこともあれば、失敗することもありました。明らかにデータにエラーがありました。ヘッダーのチェックサムフィールドを確認し始め、無効なチェックサムを持つセクターを拒否し、有効なチェックサムが11個になるまで読み取りを繰り返しました。
一部のディスクでは、これは最初の読み取りですべて11でしたが、いくつかの試行と異なる位相値も必要でした。
ついに私はなんとか有効なADFファイルを書くことができました。一部のディスクには時間がかかり、一部のディスクは文字通りAmigaがディスクを読み取る速度になります。動作するAmigaがなくなったため、これらのディスクが正常に読み取られるかどうかを実際に確認できませんでした。屋根裏部屋の箱に何年も保管されていたため、劣化している可能性があります。
では、次は何ですか?
次はすでに起こっています- V2はこちらから入手できます 読み取りと書き込みのサポートが改善されました!
まず、GNU General Public LicenseV3の下でプロジェクト全体を無料でオープンソースにしました。 Amigaを維持したいのであれば、特権のためにお互いを引き裂いてはいけません。さらに、これまでに取り組んだ最高のプラットフォームに還元したいと思います。また、人々がこれを開発し、さらに発展させ、共有し続けることを望んでいます。
次に、他の形式を見てみたいと思います。 ADFファイルは優れていますが、AmigaDOS形式のディスクでのみ機能します。カスタムコピー防止機能と非標準セクター形式のタイトルがたくさんありますが、この形式ではサポートできません。
ウィキペディアによると、別のディスクファイル形式であるFDI形式があります。十分に文書化されているユニバーサルフォーマット。この形式の利点は、トラックデータをできるだけ元のデータに近づけて保存しようとするため、上記の問題が修正されることを願っています。
また、Software Preservation Society、特にCAPS(正式には Classic Amiga Preservation Society )にも出くわしました。 )およびそれらのIPF形式。少し読んだ後、私は非常に失望し、すべてが閉じられ、ディスク読み取りハードウェアを販売するためにこの形式を使用しているように感じました。
だから私の焦点はFDIになります!フォーマット。ここでの私の唯一の懸念は、データの整合性です。読み取りが有効かどうかを確認するためのチェックサムはありませんが、それを解決するためのアイデアがいくつかあります。
そして最後に、書き込みディスクオプション(おそらくFDIとADFをサポートする)を追加することも検討します。追加するのはそれほど難しいことではないはずです。
コード
GitHubリポジトリ
Arduinoスケッチとウィンドウのソースコードhttps://github.com/RobSmithDev/ArduinoFloppyDiskReader 回路図


製造プロセス