Manufaktur industri
Industri Internet of Things | bahan industri | Pemeliharaan dan Perbaikan Peralatan | Pemrograman industri |
home  MfgRobots >> Manufaktur industri >  >> Manufacturing Technology >> Proses manufaktur

Pembaca Floppy Disk Arduino Amiga (V1)

Komponen dan persediaan

Resistor 1k ohm
× 1
Breadboard (generik)
× 1
Kabel jumper (generik)
× 1
SparkFun Breadboard Power Supply 5V/3.3V
× 1
Arduino UNO
Atau Pro Mini
× 1

Aplikasi dan layanan online

Arduino IDE

Tentang proyek ini

  • Tujuan Saya: Untuk membuat cara sederhana, murah, dan open source untuk memulihkan data dari disket Amiga DD dari dalam Windows 10 dan sistem operasi lainnya.
  • Solusi Saya: Arduino + aplikasi Windows
  • Mengapa: Untuk menyimpan data dari disk ini untuk masa mendatang. Selain itu, PC biasa tidak dapat membaca disk Amiga karena cara penulisannya.

Situs Web Proyek:http://amiga.robsmithdev.co.uk/

Ini adalah V1 dari proyek. V2 berisi peningkatan membaca dan menulis!

Pengalaman Amiga

Saya berutang karir saya ke Amiga, khususnya A500+ yang dibelikan orang tua saya untuk saya saat Natal pada usia 10 tahun. Awalnya saya memainkan game tersebut, tetapi setelah beberapa saat saya mulai penasaran dengan apa lagi yang bisa dilakukannya. Saya bermain dengan Deluxe Paint III dan belajar tentang Workbench.

Amiga 500 Plus:

Setiap bulan saya membeli majalah Amiga Format yang populer. Satu bulan memiliki salinan AMOS gratis. Saya memasukkan Format Amiga Tulis Game Di AMOS kompetisi ketika AMOS Professional dimasukkan ke dalam coverdisk kemudian, dan merupakan salah satu dari 12 (menurut saya) pemenang dengan In The Pipe Line . Anda benar-benar harus mengejar mereka untuk mendapatkan hadiah!

AMOS - Sang Pencipta:

Latar belakang

Selanjutnya, saya menggunakannya sebagai bagian dari proyek GCSE dan A-Level saya (berkat Highspeed Pascal, yang kompatibel dengan Turbo Pascal di PC)

Bagaimanapun, itu sudah lama sekali, dan saya memiliki kotak disk, dan A500+ yang tidak berfungsi lagi, jadi saya berpikir untuk mencadangkan disk tersebut ke komputer saya, untuk pelestarian dan nostalgia.

Situs web Amiga Forever memiliki daftar pilihan yang sangat baik yang mencakup perangkat keras, dan menyalahgunakan dua floppy drive di PC - Sayangnya tidak satupun dari ini adalah pilihan dengan perangkat keras modern, dan pengontrol KryoFlux/Catweasel terlalu mahal. Saya sangat terkejut bahwa sebagian besar adalah sumber tertutup.

Sangat menyukai elektronik dan pernah bermain dengan perangkat Atmel (AT89C4051 ) sementara di Universitas saya memutuskan untuk melihat Arduino (kredit untuk GreatScott untuk inspirasi yang menunjukkan betapa mudahnya memulai) Saya bertanya-tanya apakah ini mungkin.

Jadi saya mencari di Google untuk membaca floppy drive Arduino kode, dan setelah melewatkan semua proyek yang menyalahgunakan dorongan untuk memutar musik, saya tidak benar-benar menemukan solusi apa pun. Saya menemukan beberapa diskusi dalam beberapa kelompok yang menyarankan itu tidak mungkin. Saya memang menemukan proyek berbasis FPGA yang merupakan bacaan yang sangat menarik, tetapi bukan arah yang ingin saya tuju, jadi satu-satunya pilihan adalah membangun solusi sendiri.

Riset

Ketika saya memulai proyek ini, saya tidak tahu bagaimana floppy drive bekerja, dan terlebih lagi bagaimana data dikodekan ke dalamnya. Situs web berikut sangat berharga dalam pemahaman saya tentang apa yang terjadi dan cara kerjanya:

  • techtravels.org (dan halaman ini)
  • FAQ format .ADF (Amiga Disk File) oleh Laurent Clévy
  • Amiga Selamanya
  • Wikipedia - File Disk Amiga
  • Papan Amiga Bahasa Inggris
  • QEEWiki - Penghitung pada ATmega168/328
  • Pinout drive floppy
  • Daftar format floppy disk

Asumsi

Berdasarkan penelitian saya sekarang tahu secara teoritis bagaimana data ditulis ke disk, dan bagaimana disk berputar.

Saya mulai mengerjakan beberapa angka. Berdasarkan kecepatan piringan berdensitas ganda yang diputar pada (300rpm) dan cara data disimpan (80 trek, 11 sektor per trek, dan 512 byte per sektor, dikodekan menggunakan MFM), untuk membaca data secara akurat saya harus dapat sampel data pada 500Khz; itu cukup cepat jika Anda menganggap Arduino hanya berjalan pada 16Mhz.

Dalam upaya berikutnya saya hanya berbicara tentang sisi Arduino. Langsung ke decoding.

Upaya 1:

Pertama saya perlu mengumpulkan perangkat keras dan antarmuka ke floppy drive. Floppy drive yang saya ambil dari PC lama di tempat kerja, dan mengambil kabel IDE-nya secara bersamaan.

Di bawah ini adalah foto dibebaskan floppy drive dari PC lama:

Mempelajari pinout drive, saya menyadari bahwa saya hanya membutuhkan beberapa kabel darinya, dan setelah melihat drive, saya menyadari bahwa itu juga tidak menggunakan input 12v.

Mendapatkan putaran drive dicapai dengan memilih drive dan mengaktifkan motor. Menggerakkan kepala itu sederhana. Anda mengatur /DIR pin tinggi atau rendah, lalu tekan /STEP pin. Anda dapat mengetahui apakah head telah mencapai track 0 (track pertama) dengan memantau /TRK00 pin.

Saya penasaran dengan /INDEX pin. Ini berdenyut sekali setiap rotasi. Karena Amiga tidak menggunakan ini untuk menemukan awal trek, saya tidak membutuhkannya dan dapat mengabaikannya. Setelah ini tinggal memilih sisi disk mana yang akan dibaca (/SIDE1 ) dan menghubungkan /RDATA .

Dengan persyaratan kecepatan data yang tinggi, pikiran pertama saya adalah menemukan cara untuk mengurangi masalah ini dengan mencoba mengurangi persyaratan pada kecepatan ini.

Rencananya adalah menggunakan dua register geser 8-bit (SN74HC594N ) untuk mengurangi frekuensi pengambilan sampel yang diperlukan dengan faktor 8. Saya menggunakan apa yang disebut Ebay Pro Mini atmega328 Board 5V 16M Arduino Kompatibel Nano (jadi saya tidak tahu apa itu secara resmi, tetapi ini berfungsi di Uno!) untuk menyangga paralel ini data dan mengirimkannya ke PC menggunakan antarmuka serial/USART. Saya tahu ini harus berjalan lebih cepat dari 500Kbaud (dengan semua overhead serial yang terlibat juga).

sn74hc594.pdf

Setelah membuang perpustakaan serial Arduino standar, saya sangat senang mengetahui bahwa saya dapat mengonfigurasi USART pada Arduino pada baud uptp 2M, dan dengan salah satu papan pemutus F2DI (eBay menyebutnya Basic Breakout Board For FTDI FT232RL USB ke IC Serial Untuk Arduino - lihat di bawah) Saya dapat dengan senang hati mengirim dan menerima data dengan kecepatan ini (62,5Khz) tetapi saya harus melakukannya dengan akurat.

Atmel-42735-8-bit-AVR-Mikrokontroler-ATmega328-328P_Datasheet.pdf

Papan breakout FTDI yang sangat cocok dengan antarmuka pada papan Arduino:

Pertama, saya menggunakan Arduino untuk mengatur register geser 8-bit hanya satu dari 8 bit yang memiliki clock tinggi. Yang lain menerima umpan langsung dari floppy drive (sehingga menyediakan konversi serial ke paralel).

Berikut ini adalah gambar gila dari papan tempat memotong roti yang saya buat pada saat itu:

Saya menggunakan salah satu pengatur waktu Arduino untuk menghasilkan sinyal 500Khz pada salah satu pin keluarannya dan karena perangkat keras mengelolanya, ini sangat akurat! - Yah, multimeter saya mengukurnya persis 500khz.

Kode berfungsi, saya mencatat 8-bit data penuh pada 62.5khz, meninggalkan CPU Arduino hampir tidak digunakan. Namun saya tidak menerima sesuatu yang berarti. Pada titik ini saya menyadari bahwa saya perlu melihat lebih dekat pada data aktual yang keluar dari floppy drive. Jadi saya membeli osiloskop tua yang murah dari eBay (Gould OS300 20Mhz Oscilloscope) untuk melihat apa yang terjadi.

Sambil menunggu osiloskop tiba, saya memutuskan untuk mencoba yang lain.

Fragmen kode yang digunakan untuk membaca data dari register geser:

void readTrackData() { byte op; for (int a=0; a<5632; a++) { // Kita akan menunggu penanda awal "byte" while (digitalRead(PIN_BYTE_READ_SIGNAL)==LOW) {}; // Baca byte op=0; if (Baca digital(DATA_LOWER_NIBBLE_PB0)==TINGGI) op|=1; if (DigitalBaca(DATA_LOWER_NIBBLE_PB1)==TINGGI) op|=2; if (DigitalBaca(DATA_LOWER_NIBBLE_PB2)==TINGGI) op|=4; if (digitalRead(DATA_LOWER_NIBBLE_PB3)==HIGH) op|=8; if (DigitalBaca(DATA_UPPER_NIBBLE_A0)==TINGGI) 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); // Tunggu hingga tinggi turun lagi saat (digitalRead(PIN_BYTE_READ_SIGNAL)==HIGH) {}; }} 

Upaya 2:

Saya memutuskan bahwa shift mendaftar, sementara ide bagus mungkin tidak membantu. Saya dapat dengan mudah membaca 8 bit sekaligus, tetapi terpikir oleh saya bahwa saya tidak dapat memastikan bahwa semua bit telah dimasukkan dengan benar sejak awal. Membaca dokumentasi itu menunjukkan bahwa data lebih merupakan pulsa pendek daripada tinggi dan rendah.

Saya menghapus register geser dan bertanya-tanya apa yang akan terjadi jika saya mencoba memeriksa pulsa dari drive dalam Interrupt (ISR) menggunakan sinyal 500Khz yang telah disiapkan sebelumnya. Saya mengonfigurasi ulang Arduino untuk menghasilkan ISR, dan setelah saya berhasil mengatasi masalah perpustakaan Arduino yang menghalangi (menggunakan ISR yang saya inginkan), saya pindah ke Timer 2.

Saya menulis ISR pendek yang akan menggeser ke kiri satu byte global satu bit dan kemudian jika pin yang terhubung ke jalur data floppy drive RENDAH (denyutnya rendah) Saya akan OR 1 ke atasnya. Setiap 8 kali saya melakukan ini, saya menulis byte lengkap ke USART.

Ini tidak berjalan seperti yang diharapkan! Arduino mulai berperilaku sangat tidak menentu dan aneh. Saya segera menyadari bahwa ISR membutuhkan lebih banyak waktu untuk dieksekusi daripada waktu antara panggilan ke sana. Saya dapat menerima pulsa setiap 2µDetik dan berdasarkan kecepatan Arduino, dan membuat asumsi liar bahwa setiap instruksi C diterjemahkan ke 1 siklus kode mesin jam, Saya menyadari bahwa saya paling banyak dapat memiliki 32 instruksi. Sayangnya sebagian besar akan lebih dari satu instruksi, dan setelah Googling saya menyadari biaya untuk memulai ISR ​​sangat besar; belum lagi fungsi digitalRead yang sangat lambat.

Saya membuang digitalRead berfungsi untuk mengakses pin port secara langsung! Ini masih tidak membantu dan tidak cukup cepat. Tidak siap untuk menyerah, saya mengesampingkan pendekatan ini dan memutuskan untuk melanjutkan dan mencoba sesuatu yang lain.

Pada titik ini osiloskop yang saya beli tiba, dan berhasil! Sebuah Oscilloscope tua berkerak yang mungkin lebih tua dari saya! Tapi tetap melakukan pekerjaan dengan sempurna. (Jika Anda tidak tahu apa itu Oscilloscope, lihat EEVblog #926 - Introduction To The Oscilloscope, dan jika Anda menyukai elektronik, saya sarankan untuk menonton beberapa lagi dan menjelajahi situs web EEVBlog.

Oscilloscope tua saya yang baru dibeli (Gould OS300 20Mhz):

Setelah menghubungkan sinyal 500Khz ke satu saluran dan output dari floppy drive ke yang lain, jelas ada sesuatu yang tidak beres. Sinyal 500Khz adalah gelombang persegi sempurna yang menggunakannya sebagai pemicu, data floppy ada di mana-mana. Saya bisa melihat pulsanya, tapi itu lebih kabur. Begitu pula jika saya dipicu dari sinyal floppy drive, sinyal gelombang persegi sinyal 500Khz ada di mana-mana dan tidak sinkron dengannya.

Foto jejak pada osiloskop yang dipicu dari dua saluran. Anda tidak dapat melihatnya dengan jelas, tetapi di saluran tidak dipicu adalah ribuan garis hantu samar:

Secara individual saya dapat mengukur pulsa dari kedua sinyal pada 500Khz, yang tidak masuk akal, seolah-olah keduanya berjalan pada kecepatan yang sama tetapi tidak memicu sehingga Anda dapat melihat kedua sinyal dengan benar, maka pasti ada sesuatu yang salah.

Setelah banyak bermain dengan level pemicu, saya berhasil mengetahui apa yang sedang terjadi. Sinyal saya adalah 500Khz yang sempurna, tetapi melihat sinyal floppy drive, mereka ditempatkan dengan benar, tetapi tidak setiap saat. Di antara kelompok pulsa ada penyimpangan kesalahan, dan juga celah dalam data yang membuat sinyal benar-benar tidak sinkron.

Mengingat penelitian sebelumnya, drive seharusnya berputar pada 300rpm, tetapi mungkin tidak benar-benar 300rpm, ditambah drive yang menulis data mungkin juga tidak tepat 300rpm. Kemudian ada jarak antar sektor dan kesenjangan sektor. Jelas ada masalah sinkronisasi, dan sinkronisasi sinyal 500Khz ke floppy drive di awal pembacaan tidak akan berhasil.

Saya juga menemukan bahwa pulsa dari floppy drive sangat pendek, meskipun Anda dapat memodifikasi ini dengan mengubah resistor pullup, dan jika waktunya tidak tepat maka Arduino mungkin kehilangan pulsa secara bersamaan.

Ketika saya masih di universitas (University of Leicester) saya mengambil modul yang disebut sistem tertanam. Kami mempelajari mikrokontroler Atmel 8051. Salah satu proyek yang terlibat menghitung pulsa dari stasiun cuaca simulasi (rotary encoder). Saat itu saya mengambil sampel pin secara berkala, tetapi ini tidak terlalu akurat.

Dosen modul, Prof Pont menyarankan agar saya menggunakan penghitung perangkat keras fitur perangkat (saya bahkan tidak tahu bahwa perangkat itu pernah memilikinya.)

Saya memeriksa lembar data untuk ATMega328 dan cukup yakin masing-masing dari tiga pengatur waktu dapat dikonfigurasi untuk menghitung pulsa yang dipicu dari input eksternal. Ini berarti kecepatan tidak lagi menjadi masalah. Yang benar-benar perlu saya ketahui adalah apakah denyut nadi telah terjadi dalam jangka waktu 2µdetik.

Upaya 3:

Saya menyesuaikan sketsa Arduino untuk mengatur ulang timer 500khz ketika pulsa pertama terdeteksi dan setiap kali timer 500khz meluap, saya memeriksa nilai penghitung untuk melihat apakah pulsa telah terdeteksi. Saya kemudian melakukan urutan bit-shifting yang sama dan setiap 8 bit menulis satu byte ke USART.

Data masuk dan saya mulai menganalisisnya di PC. Dalam data saya mulai melihat apa yang tampak seperti data yang valid. Kata sinkronisasi aneh akan muncul, atau kelompok urutan 0xAAAA, tetapi tidak ada yang dapat diandalkan. Saya tahu saya sedang mengerjakan sesuatu, tetapi masih melewatkan sesuatu.

Upaya 4:

Saya menyadari bahwa saat data sedang dibaca, data dari drive mungkin tidak sinkron/fase dengan sinyal 500khz saya. Saya mengkonfirmasi ini dengan hanya membaca 20 byte setiap kali saya mulai membaca.

Membaca tentang cara menangani masalah sinkronisasi ini, saya menemukan frasa Phase Locked Loop atau PLL. Dalam istilah yang sangat sederhana, untuk apa yang kita lakukan, loop fase terkunci akan secara dinamis menyesuaikan frekuensi clock (500khz) untuk mengkompensasi penyimpangan frekuensi dan varians dalam sinyal.

Resolusi pada pengatur waktu tidak cukup tinggi untuk memvariasikannya dengan jumlah yang cukup kecil (misalnya 444khz, 470khz, 500khz, 533khz, 571khz, dll.) dan untuk melakukan ini dengan benar, saya mungkin memerlukan kode untuk berjalan jauh lebih cepat.

Timer Arduino bekerja dengan menghitung hingga angka yang telah ditentukan (dalam hal ini 16 untuk 500khz ) kemudian mereka mengatur register luapan dan memulai lagi dari 0. Nilai penghitung yang sebenarnya dapat dibaca dan ditulis ke titik mana pun.

Saya menyesuaikan sketsa untuk menunggu dalam satu lingkaran sampai pengatur waktu meluap, dan ketika itu meluap saya memeriksa denyut nadi seperti sebelumnya. Perbedaan kali ini adalah kapan pulsa terdeteksi di dalam loop, saya mengatur ulang nilai penghitung waktu ke fase yang telah ditentukan sebelumnya posisi, secara efektif menyinkronkan ulang timer dengan setiap pulsa.

Saya memilih nilai yang saya tulis ke penghitung waktu sedemikian rupa sehingga akan meluap pada 1µDetik dari pulsa deteksi (setengah jalan) sehingga waktu berikutnya timer meluap, pulsa akan terpisah 2µDetik.

Ini berhasil! Saya sekarang membaca data yang hampir sempurna dari disk. Saya masih mendapatkan banyak kesalahan checksum yang mengganggu. Saya menyelesaikan sebagian besar dari ini dengan terus membaca ulang trek yang sama pada drive sampai saya memiliki semua 11 sektor dengan header dan checksum data yang valid.

Saya penasaran pada titik ini, jadi saya menghubungkan semuanya kembali ke osiloskop lagi untuk melihat apa yang terjadi sekarang, dan seperti yang saya duga, saya sekarang dapat melihat kedua jejak karena keduanya tetap sinkron satu sama lain:

Saya ingin melihat ini sedikit lebih jelas, jika ada yang ingin mendonasikan kepada saya osiloskop digital terbaik (misalnya salah satunya Keysight!) Saya akan sangat menghargainya!

Upaya 5:

Saya bertanya-tanya apakah saya bisa memperbaiki ini. Melihat kode, khususnya loop membaca bagian dalam (lihat di bawah) saya memiliki loop sementara menunggu overflow dan kemudian if bagian dalam mencari pulsa untuk disinkronkan.

Fragmen kode yang digunakan untuk membaca data dan menyinkronkannya:

register bool done =false;// Tunggu hingga 500khz overflow while (!(TIFR2&_BV(TOV2))) { // deteksi tepi jatuh saat menunggu pulsa 500khz. if ((TCNT0) &&(!selesai)) { // pulsa terdeteksi, reset penghitung waktu untuk menyinkronkan dengan pulsa TCNT2=fase; // Tunggu hingga pulsa kembali tinggi saat (!(PIN_RAW_FLOPPYDATA_PORT &PIN_RAW_FLOPPYDATA_MASK)) {}; selesai =benar; }}// Setel ulang flag yang melimpahTIFR2|=_BV(TOV2); // Apakah kita mendeteksi pulsa dari drive?if (TCNT0) { DataOutputByte|=1; TCNT0=0;} 

Saya menyadari bahwa tergantung pada instruksi mana yang dieksekusi dalam loop di atas, waktu antara deteksi pulsa dan penulisan TCNT2=phase; dapat berubah dengan waktu yang dibutuhkan untuk mengeksekusi beberapa instruksi.

Menyadari bahwa ini mungkin menyebabkan beberapa kesalahan/jitter pada data dan juga dengan loop di atas, saya mungkin benar-benar kehilangan pulsa dari drive (sehingga kehilangan bit sinkronisasi ulang) Saya memutuskan untuk mengambil trik dari salah satu dari saya sebelumnya upaya, ISR (interupsi).

Saya menghubungkan pulsa data ke pin kedua di Arduino. Data sekarang terhubung ke pemicu COUNTER0 dan sekarang juga pin INT0. INT0 adalah salah satu prioritas interupsi tertinggi sehingga harus meminimalkan penundaan antara pemicu dan ISR yang dipanggil, dan karena ini adalah satu-satunya interupsi yang sebenarnya saya minati, semua interupsi lainnya dinonaktifkan.

Semua interupsi yang perlu dilakukan adalah melakukan sinkronisasi ulang kode di atas, ini mengubah kode menjadi seperti ini:

// Tunggu hingga 500khz overflow while (!(TIFR2&_BV(TOV2))) {} // Reset flag overflowTIFR2|=_BV(TOV2); // Apakah kita mendeteksi pulsa dari drive?if (TCNT0) { DataOutputByte|=1; TCNT0=0;} 

ISR terlihat seperti ini:(perhatikan bahwa saya tidak menggunakan attachInterrupt karena ini juga menambahkan overhead ke panggilan).

byte targetPhase yang mudah menguap;ISR (INT0_vect) { TCNT2=targetPhase;} 

Kompilasi ini menghasilkan terlalu banyak kode untuk dieksekusi dengan cukup cepat. Bahkan pembongkaran di atas menghasilkan:

dorong 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 

Dengan menganalisis kode, saya menyadari bahwa hanya ada beberapa instruksi yang sebenarnya saya butuhkan. Memperhatikan bahwa kompiler akan melacak register apa pun yang saya pukul, saya mengubah ISR sebagai berikut:

 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)));} 

Yang dibongkar, menghasilkan instruksi berikut:

dorong r1push r0in r0, 0x3f; 63push r0eor r1, r1lds r0, 0x0102; 0x800102 sts 0x00B2, r0; 0x8000b2 pop r0out 0x3f, r0; 63pop r0pop r1reti 

Masih terlalu banyak instruksi. Saya perhatikan bahwa kompiler menambahkan banyak instruksi tambahan, yang untuk aplikasi saya sebenarnya tidak perlu ada di sana. Jadi saya mencari ISR() dan menemukan parameter kedua ISR_NAKED. Menambahkan ini akan mencegah kompiler menambahkan kode khusus apa pun, tetapi kemudian saya akan bertanggung jawab untuk memelihara register, tumpukan, dan kembali dari interupsi dengan benar. Saya juga perlu memelihara register SREG, tetapi karena tidak ada perintah yang perlu saya panggil untuk mengubahnya, saya tidak perlu mengkhawatirkannya.

Ini mengubah kode ISR menjadi:

ISR (INT0_vect, ISR_NAKED) { asm volatile("push __tmp_reg__"); // Pertahankan tmp_register asm volatile("lds __tmp_reg__, targetPhase"); // Salin nilai fase ke dalam tmp_register asm volatile("sts %0, __tmp_reg__" ::"M" (_SFR_MEM_ADDR(TCNT2))); // Salin tmp_register ke lokasi memori di mana TCNT2 asm volatile("pop __tmp_reg__"); // Kembalikan tmp_register asm volatile("reti"); // Dan keluar dari ISR} 

Yang diubah oleh kompiler menjadi:

tekan r0lds r0, 0x0102; 0x800102 sts 0x00B2, r0; 0x8000b2 pop r0reti 

Lima instruksi! Sempurna, atau setidaknya secepat yang diharapkan, secara teori membutuhkan waktu 0,3125µDetik untuk dieksekusi! Ini sekarang berarti sinkronisasi ulang harus terjadi pada periode waktu yang konsisten setelah pulsa. Di bawah ini adalah diagram waktu dari apa yang terjadi. Ini adalah bagaimana Anda memulihkan data dari umpan data serial yang tidak memiliki sinyal clock:

Ini meningkatkan hasil sedikit. Itu masih belum sempurna. Beberapa disk membaca dengan sempurna setiap saat, beberapa disk membutuhkan waktu lama dan harus terus mencoba lagi. Saya tidak yakin apakah ini karena beberapa disk telah duduk di sana begitu lama sehingga daya magnetnya telah menurun ke tingkat yang sangat rendah sehingga amplifier drive tidak dapat mengatasinya. Saya bertanya-tanya apakah ini ada hubungannya dengan floppy disk drive PC, jadi saya menghubungkan ini ke floppy disk drive Amiga eksternal yang saya miliki, tetapi hasilnya sama.

Upaya 6:

Saya bertanya-tanya apakah ada hal lain yang bisa dilakukan. Mungkin sinyal dari drive lebih berisik daripada yang saya kira. Setelah membaca informasi lebih lanjut, saya menemukan bahwa resistor pullup 1KOhm adalah norma, dimasukkan ke pemicu Schmitt.

Setelah menginstal Pemicu Hex Schmitt SN74HCT14N dan mengkonfigurasi ulang sketsa untuk memicu pada tepi yang naik alih-alih tepi yang turun, saya mencobanya, tetapi itu tidak benar-benar membuat perbedaan yang nyata. Saya kira ketika saya mencari satu atau lebih pulsa setiap kali ini mungkin diserap kebisingan apapun pula. Jadi kita akan tetap menggunakan metode Percobaan 5!

sn74hct14.pdf

Solusi papan tempat memotong roti terakhir saya tampak seperti ini:

Perhatikan pengkabelan di atas sedikit berbeda dengan sketsa langsung. Saya memesan ulang beberapa pin Arduino untuk membuat diagram sirkuit lebih mudah.

Percobaan 7

Saya sedikit tidak puas dengan beberapa disk yang belum saya baca. Beberapa kali disk tidak duduk dengan benar di floppy drive. Kurasa pegas di rana tidak membantu.

Saya mulai mencari untuk mendeteksi apakah ada kesalahan dalam data MFM yang sebenarnya diterima dari disk.

Dari aturan cara kerja encoding MFM, saya menyadari bahwa beberapa aturan sederhana dapat diterapkan sebagai berikut:

  • Tidak boleh ada dua bit '1' yang bersebelahan
  • Tidak boleh lebih dari tiga bit '0' bersebelahan

Pertama ketika mendekode data MFM saya melihat apakah ada dua '1 berturut-turut. Jika ya, saya berasumsi bahwa data menjadi sedikit kabur dari waktu ke waktu dan mengabaikan '1' kedua.

Dengan aturan ini diterapkan, secara harfiah ada tiga situasi 5 bit di mana kesalahan dibiarkan terjadi. Ini akan menjadi area baru tempat saya dapat meningkatkan data.

Namun sebagian besar, saya terkejut sebenarnya tidak banyak kesalahan MFM yang terdeteksi. Saya agak bingung mengapa beberapa disk tidak mau membaca ketika tidak ada kesalahan yang ditemukan.

Ini adalah area untuk penyelidikan lebih lanjut.

Penguraian kode

Setelah membaca cara kerja MFM, saya tidak sepenuhnya yakin bagaimana itu disejajarkan dengan benar.

Pada awalnya saya berpikir bahwa drive menghasilkan 1s dan 0s untuk bit on dan off. Ini bukan masalahnya. Drive mengeluarkan pulsa untuk setiap transisi fase, yaitu:setiap kali data berubah dari 0 ke 1, atau 1 ke 0.

Setelah membaca ini, saya bertanya-tanya apakah saya perlu mengubahnya kembali menjadi 1 dan 0 dengan memasukkannya ke sakelar flip-flop, atau membaca data, mencari sektor, dan jika tidak ada yang ditemukan, balikkan data dan coba lagi!

Ternyata ini bukan masalahnya dan jauh lebih sederhana. Pulsa sebenarnya adalah data RAW MFM dan dapat dimasukkan langsung ke dalam algoritma decoding. Sekarang saya mengerti ini, saya mulai menulis kode untuk memindai buffer dari drive dan mencari kata sinkronisasi 0x4489. Anehnya saya menemukannya!

Dari penelitian yang saya lakukan, saya menyadari bahwa saya harus benar-benar mencari 0xAAAAAAAAA44894489 (catatan dari penelitian juga menunjukkan bahwa ada beberapa bug dalam kode Amiga awal yang berarti bahwa urutan di atas tidak ditemukan. Jadi saya mencari 0x2AAAAAA44894489 setelah ANDing data dengan 0x7FFFFFFFFFFFFFF ).

Seperti yang diharapkan, saya menemukan hingga 11 di setiap trek yang sesuai dengan awal sebenarnya dari 11 sektor Amiga. Saya kemudian mulai membaca byte berikutnya untuk melihat apakah saya dapat memecahkan kode informasi sektor.

Saya mengambil cuplikan kode dari salah satu referensi di atas untuk membantu decoding MFM. Tidak ada gunanya menemukan kembali roda, kan?

Setelah membaca header dan data, saya mencoba menulisnya ke disk sebagai file ADF. Format file ADF standar sangat sederhana. Secara harfiah hanya 512 byte dari setiap sektor (dari kedua sisi disk) yang ditulis secara berurutan. Setelah ditulis dan dicoba dibuka dengan ADFOpus dan hasilnya campur aduk, kadang buka file kadang gagal. Jelas ada kesalahan dalam data. Saya mulai melihat bidang checksum di header, menolak sektor dengan checksum yang tidak valid dan mengulangi membaca sampai saya memiliki 11 yang valid.

Untuk beberapa disk, ini semua 11 pada pembacaan pertama, beberapa membutuhkan beberapa upaya dan nilai fase yang berbeda juga.

Akhirnya saya berhasil menulis file ADF yang valid. Beberapa disk akan memakan waktu lama, beberapa benar-benar kecepatan Amiga akan membacanya. Tidak memiliki Amiga yang berfungsi lagi Saya tidak dapat benar-benar memeriksa apakah disk ini terbaca dengan baik secara normal, mereka telah disimpan dalam kotak di loteng selama bertahun-tahun sehingga mungkin sudah rusak.

Jadi Apa Selanjutnya?

Berikutnya telah terjadi - V2 tersedia di sini dan telah meningkatkan dukungan membaca dan menulis!

Pertama, saya telah membuat seluruh proyek gratis dan open source di bawah GNU General Public License V3. Jika kita ingin memiliki harapan untuk melestarikan Amiga maka kita tidak boleh saling merobek untuk hak istimewa, dan selain itu, saya ingin memberikan kembali ke platform terbaik yang pernah saya kerjakan. Saya juga berharap orang-orang akan mengembangkan ini dan melangkah lebih jauh dan terus berbagi.

Saya selanjutnya ingin melihat format lain. File ADF bagus, tetapi hanya berfungsi untuk disk berformat AmigaDOS. Ada banyak judul dengan perlindungan salinan khusus dan format sektor non-standar yang tidak dapat didukung oleh format ini.

Menurut Wikipedia ada format file disk lain, format FDI. Format universal yang didokumentasikan dengan baik. Keuntungan dari format ini adalah mencoba menyimpan data trek sedekat mungkin dengan aslinya sehingga diharapkan dapat memperbaiki masalah di atas!

Saya juga menemukan Software Preservation Society, khususnya CAPS (secara resmi Classic Amiga Preservation Society ) dan format IPF-nya. Setelah sedikit membaca, saya sangat kecewa, semuanya ditutup, dan rasanya mereka hanya menggunakan format ini untuk menjual perangkat keras pembacaan disk mereka.

Jadi fokus saya adalah pada FDI! format. Satu-satunya perhatian saya di sini adalah dengan integritas data. Tidak akan ada checksum untuk saya periksa untuk melihat apakah pembacaan itu valid, tapi saya punya beberapa ide untuk menyelesaikannya!

Dan akhirnya saya juga akan mencarinya dengan menambahkan opsi disk tulis (mungkin mendukung FDI dan juga ADF), karena seharusnya tidak terlalu sulit untuk menambahkannya.

Kode

Repo GitHub
Sketsa Arduino dan kode sumber windowshttps://github.com/RobSmithDev/ArduinoFloppyDiskReader

Skema


Proses manufaktur

  1. Animasi
  2. Floppy Disk
  3. Arduino Spybot
  4. FlickMote
  5. TV Buatan Sendiri B-Gone
  6. Jam Master
  7. Temukan Saya
  8. Arduino Power
  9. Tech-TicTacToe
  10. Pembaca Floppy Disk Arduino Amiga (V1)