This is a helper library to abstract away interfacing with floppy disk drives in a cross-platform and open source library.

Overview

Adafruit Floppy Build Status

Adafruit Floppy

This is a helper library to abstract away interfacing with floppy disk drives in a cross-platform and open source library.

Adafruit Floppy is a project to make a flexible, full-stack, open source hardware/software device for reading, archiving, accessing and duplicating floppy disk media. It joins a family of open source hardware and software such as greaseweazle and fluxengine, and will attempt to increase the availability and accessibility of floppy disk controllers by:

  1. porting the greaseweazle / fluxengine firmware to Arduino so that it is less tied to specific hardware. this is important as, during 2021 we learned that silicon shortages can make specific chips extremely difficult to find - having a cross-platform firmware alleviates dependancies on specific chips.

  2. adding firmware support for the RP2040 chip / pico. this is an ultra low cost dev board, at $4 each - and can make for an excellent alternative to higher cost atmel/stm chips. (of course, the firmware should be able to run on many chips, but we want to make sure this is one of them!)

  3. adding hardware support for reading apple ii disks. many flux readers focus on 34-pin disk drives but do not have interfacing for apple disk ii drives. the drives are available and could be used for archiving a vast number of floppies out there! this will require adding an index sensor so we can image disks into 'woz' formats. currently, applesauce hardware and software can do this for apple ii disks - applesauce is amazing and an excellent tool and we recommend it to folks! at this time, it appears to be closed source hardware, firmware and software, so we are not able to integrate their design into an open source design.

  4. adding woz/a2r support to greaseweazle / fluxengine. once hardware support is in place, we can then add woz/a2r file format support to the open source tools in existence, which will benefit the entire community

  5. as 'extra credit' we may look into analog flux data acquisition methods for repair of damaged disks.

Any hardware, firmware, or software we write is going to be fully open source under permissive licenses such as MIT, BSD or Unlicense. we will probably sell accessories, assembled PCBs, cables, etc in the Adafruit shop to help get hardware into folks hands but the designs will always be re-createable by others without any licensing agreements, NDAs, or discussion.

click_click_click.mp4
part6_flux.mp4

Latest video Jan 1, 2022 - 9pm EDT

Currently we are focusing on high-RAM (> 128KB SRAM) and high speed (> 100MHz) processors, so that we can buffer a full track of flux transitions at once, and not require the use of special peripherals such as timers. (Of course, those are welcome later!)

Tested working on:

  • SAMD51 chipset hardware - Please overclock to 180MHz, select Fastest optimization, and use TinyUSB stack for best performance
  • RP2040 chipset hardware - Please use philhower core, overclock to 200MHz, and select -O3 optimization for best performance Longer version!

Frequently Asked/Accused Questions

There's a LOT of preconceptions about floppy disks and how / why we have this library. Here are some answers!

  • How are you connecting a 3.3V logic microcontroller to a 5V Floppy Drive directly WITHOUT a level shifter, won't this destroy the board? Floppy drives are powered by 5V, and they use open drain outputs. That means that if the microcontroller pulls the index pin (for example) high to 3.3V, the logic level will be 3V. Is this out of spec? Maybe! But it does seem to work. Of course its always polite to use a level shifter, so if you can please add it to your hardware design. We do recommend a stronger external pullup on the READDATA line, 4.7K or so seems fine, other lines are fine with an internal pullup.
  • Did you know there are USB Floppy Drives for $10 on Amazon? Yes, we are aware. These are recycled laptop floppy drives with a controller chip that presents a mass storage interface to the sectors on disk. They are great for basic access to 1.44MB IBM PC MFM-formatted diskettes. They will not work for GCR formatted diskettes (we know because we tried) and may not work with non-FAT formatted diskettes (we don't have any but the controller chip is very specialized and may freak out). USB floppy drive controllers will not get you flux-level readings, and can't cope with damaged diskettes to read sector data that does not pass CRC to perform data recovery. They are also, of course, no good with 5.25" floppy diskettes.
  • Why do you need a flux level reading of disks??? Flux level readings are essential for data recovery, restoration, archiving of damaged or copy-protected floppies. You can read more about floppy disk preservation efforts here: https://wiki.archiveteam.org/index.php/Rescuing_Floppy_Disks

Adafruit invests time and resources providing this open source code, please support Adafruit and open-source hardware by purchasing products from Adafruit!

MIT license, all text above must be included in any redistribution.

Comments
  • Has gw been modified for this project ?

    Has gw been modified for this project ?

    When using your arduino pico code I get the following error. Arduino 1.8.16, macOS 10.15.7, Greaseweazle v0.31

    $ ./gw read --device /dev/cu.usbmodem14101 xxx ERROR: Greaseweazle firmware v1.0 is unsupported To perform an Update:

    • Run "gw update" to install firmware v0.31

    Brilliant piece of work (again).

    Thank you John Luke

    opened by jluke1 6
  • Add support for Apple II Floppy drives such as Disk ][

    Add support for Apple II Floppy drives such as Disk ][

    This adds support for the Apple II 5.25" floppy drives, as long as you've modified them to add a revolution sensor. Write protect is weird and untested. Writing is untested. Works with fluxengine pending a PR:

    • https://github.com/davidgiven/fluxengine/pull/492
    opened by jepler 3
  • capture_track waiting for index pulse

    capture_track waiting for index pulse

    Capturing a track from index pulse to next index pulse will run into trouble when reading disks that are not index aligned, e.g. Amiga Disks. A sector might start before an the index and end after the index, flux transitions might be lost when the capture does not overlap.

    opened by Niteto 2
  • Could I use this library with an ESP32?

    Could I use this library with an ESP32?

    Thank you for opening an issue on an Adafruit Arduino library repository. To improve the speed of resolution please review the following guidelines and common troubleshooting steps below before creating the issue:

    • Do not use GitHub issues for troubleshooting projects and issues. Instead use the forums at http://forums.adafruit.com to ask questions and troubleshoot why something isn't working as expected. In many cases the problem is a common issue that you will more quickly receive help from the forum community. GitHub issues are meant for known defects in the code. If you don't know if there is a defect in the code then start with troubleshooting on the forum first.

    • If following a tutorial or guide be sure you didn't miss a step. Carefully check all of the steps and commands to run have been followed. Consult the forum if you're unsure or have questions about steps in a guide/tutorial.

    • For Arduino projects check these very common issues to ensure they don't apply:

      • For uploading sketches or communicating with the board make sure you're using a USB data cable and not a USB charge-only cable. It is sometimes very hard to tell the difference between a data and charge cable! Try using the cable with other devices or swapping to another cable to confirm it is not the problem.

      • Be sure you are supplying adequate power to the board. Check the specs of your board and plug in an external power supply. In many cases just plugging a board into your computer is not enough to power it and other peripherals.

      • Double check all soldering joints and connections. Flakey connections cause many mysterious problems. See the guide to excellent soldering for examples of good solder joints.

      • Ensure you are using an official Arduino or Adafruit board. We can't guarantee a clone board will have the same functionality and work as expected with this code and don't support them.

    If you're sure this issue is a defect in the code and checked the steps above please fill in the following fields to provide enough troubleshooting information. You may delete the guideline and text above to just leave the following details:

    • Arduino board: INSERT ARDUINO BOARD NAME/TYPE HERE

    • Arduino IDE version (found in Arduino -> About Arduino menu): INSERT ARDUINO VERSION HERE

    • List the steps to reproduce the problem below (if possible attach a sketch or copy the sketch code in too): LIST REPRO STEPS BELOW

    opened by siriokds 1
  • Add Apple Disk ][ Flux Writing for rp2040

    Add Apple Disk ][ Flux Writing for rp2040

    The Apple Disk ][ produces a flux transition whenever the WRDATA signal has a transition, rather than on only one edge. This needs different low-level writing code than a PC drive.

    We can implement it later for samd51 or bitbang if needed.

    The original version was tested on HW but the compatible version hasn't been tested yet.

    image

    opened by jepler 1
  • Switch rp2040 to streaming flux capture

    Switch rp2040 to streaming flux capture

    This improves compatibility with genuine GW hardware, and improves (but doesn't fix; is it a g64conv track numbering bug?) decoding flippy disks with g64conv. It also provided an opportunity to learn how to use the 2nd core on RP2040, bonus for me!

    When adding internal debug prints to GW host software, a multi-track capture from genuine GW hardware consists of a partial revolution, followed by several full revolutions. These are sampled without gaps, so software like g64conv which likes to stitch 'index-hole insensitive' formats across the gap can do as it likes; it's advised of (but ignores) the locations where the index was seen:

     Total: 232202 samples, 594.17ms
     Revolution 0: 93.06ms
     Revolution 1: 166.87ms
     Revolution 2: 166.87ms
     Revolution 3: 166.87ms 
    

    Prior to this change, a capture from Adafruit_Floppy's GW-compatible firmware was shown as

     Total: 120485 samples, 652.35ms
     Revolution 0: 0.00ms
     Revolution 1: 162.34ms
     Revolution 2: 55.11ms
     Revolution 3: 162.17ms
     Revolution 4: 55.28ms
     Revolution 5: 162.12ms
    

    where there was an always-empty first revolution, then an alternation between a full and a partial revolution. (a 6th, partial revolution may have been discarded internally in GW before this message was printed)

    After this, a capture from an RP2040 with the GW-compatible firmware is shown essentially the same as genuine GW.

    However, there does seem to be a problem introduced here. With this firmware, GW will sometimes fail to decode any sector but the first, randomly on some tracks of a floppy. The problem moves around but occurs with probability >1/100, so most full disk captures are affected. The resulting sector map looks like:

    Cyl-> 0         1         2         3         4         5         6         7         
    H. S: 01234567890123456789012345678901234567890123456789012345678901234567890123456789
    0. 0: ................................................................................
    0. 1: ...............X............X...................................................
    0. 2: ...............X............X...................................................
    0. 3: ...............X............X...................................................
    0. 4: ...............X............X...................................................
    0. 5: ...............X............X...................................................
    0. 6: ...............X............X...................................................
    0. 7: ...............X............X...................................................
    0. 8: ...............X............X...................................................
    0. 9: ...............X............X...................................................
    0.10: ...............X............X...................................................
    0.11: ...............X............X...................................................
    0.12: ...............X............X...................................................
    0.13: ...............X............X...................................................
    0.14: ...............X............X...................................................
    

    Also, continuous capture would need to be implemented for samd51 before this PR should be accepted.

    opened by jepler 1
  • Allow an additional revolution to pick up straggling sectors

    Allow an additional revolution to pick up straggling sectors

    The performance on non-overclocked RP2040 from CircuitPython is marginal, but allowing an additional spindle revolution makes it >99.9% (now reads a 1.44MB commercial disk 100% full surface over multiple tests)

    Because the read_track loop usually terminates as soon as all sectors are successfully read, this doesn't decrease read speed unless a sector CRC was missed on the first read.

    opened by jepler 1
  • Add real-time MFM decoder

    Add real-time MFM decoder

    Typical output, on a Feather M4 with the Floppy Featherwing and a 5.25" 1.2MB floppy (which only has 15 sectors per track, not 18, so the partial track validity is expected):

    its time for a nice floppy transfer!
    Waiting for index pulse...Found!
    Seeking track...Going to track 0
    Going to track 0
    
    done!
    Captured 15 sectors
    Validity: VVVVVVVVVVVVVVV???
    0000 eb 3c 90 4d 53 44 4f 53 35 2e 30 00 02 01 01 00 02 e0 00 60 09 f9 07 00 0f 00 02 00 00 00 00 00
    0020 00 00 00 00 00 00 29 14 24 27 17 4e 4f 20 4e 41 4d 45 20 20 20 20 46 41 54 31 32 20 20 20 fa 33
    0040 c0 8e d0 bc 00 7c 16 07 bb 78 00 36 c5 37 1e 56 16 53 bf 3e 7c b9 0b 00 fc f3 a4 06 1f c6 45 fe
    0060 0f 8b 0e 18 7c 88 4d f9 89 47 02 c7 07 3e 7c fb cd 13 72 79 33 c0 39 06 13 7c 74 08 8b 0e 13 7c
    0080 89 0e 20 7c a0 10 7c f7 26 16 7c 03 06 1c 7c 13 16 1e 7c 03 06 0e 7c 83 d2 00 a3 50 7c 89 16 52
    00a0 7c a3 49 7c 89 16 4b 7c b8 20 00 f7 26 11 7c 8b 1e 0b 7c 03 c3 48 f7 f3 01 06 49 7c 83 16 4b 7c
    00c0 00 bb 00 05 8b 16 52 7c a1 50 7c e8 92 00 72 1d b0 01 e8 ac 00 72 16 8b fb b9 0b 00 be e6 7d f3
    00e0 a6 75 0a 8d 7f 20 b9 0b 00 f3 a6 74 18 be 9e 7d e8 5f 00 33 c0 cd 16 5e 1f 8f 04 8f 44 02 cd 19
    0100 58 58 58 eb e8 8b 47 1a 48 48 8a 1e 0d 7c 32 ff f7 e3 03 06 49 7c 13 16 4b 7c bb 00 07 b9 03 00
    0120 50 52 51 e8 3a 00 72 d8 b0 01 e8 54 00 59 5a 58 72 bb 05 01 00 83 d2 00 03 1e 0b 7c e2 e2 8a 2e
    0140 15 7c 8a 16 24 7c 8b 1e 49 7c a1 4b 7c ea 00 00 70 00 ac 0a c0 74 29 b4 0e bb 07 00 cd 10 eb f2
    0160 3b 16 18 7c 73 19 f7 36 18 7c fe c2 88 16 4f 7c 33 d2 f7 36 1a 7c 88 16 25 7c a3 4d 7c f8 c3 f9
    0180 c3 b4 02 8b 16 4d 7c b1 06 d2 e6 0a 36 4f 7c 8b ca 86 e9 8a 16 24 7c 8a 36 25 7c cd 13 c3 0d 0a
    01a0 4e 6f 6e 2d 53 79 73 74 65 6d 20 64 69 73 6b 20 6f 72 20 64 69 73 6b 20 65 72 72 6f 72 0d 0a 52
    01c0 65 70 6c 61 63 65 20 61 6e 64 20 70 72 65 73 73 20 61 6e 79 20 6b 65 79 20 77 68 65 6e 20 72 65
    01e0 61 64 79 0d 0a 00 49 4f 20 20 20 20 20 20 53 59 53 4d 53 44 4f 53 20 20 20 53 59 53 00 00 55 aa
    

    It's hoped that this code will also be used in CircuitPython via submodule; it's a lightly modified version of the code I was already using.

    I didn't use/test RP2040. Probably it'll need a little bit of work.

    opened by jepler 1
  • Drop the QUARTERTRACK type, APPLE2 is always quarter-track

    Drop the QUARTERTRACK type, APPLE2 is always quarter-track

    GW and FluxEngine folks agreed that it is better to just always use the drive's native step, and FluxEngine has started fixing things internally so that this works better than when I first implemented the "why not both" approach. Only the "3" bustype is allocated now in the GW protocol.

    We can decide if we want to keep the step_mode at all, since its only intended user was the GW-compatible firmware.

    opened by jepler 0
  • Speed up the inner loop (& grab bag)

    Speed up the inner loop (& grab bag)

    This series of changes speeds up the inner loop, ~~and also errors when greaseweazel is not compiled with overclocking on the M4 (SAMD51)~~. (doing that broke CI, because it doesn't turn on the overclock setting)

    It's tested with the adafruit "debugging" branch of gw and still reads the two test floppies I've been using. It is a bit surprising to me that no change in GW_SAMPLEFREQ was needed (since at least 2 instructions were knocked out of the inner loop), but there ya go..

    By accounting for the time needed to check for the index pulse, the timing is made more even and GW works even without overclocking.

    Minimal support for GW_CMD_GETPIN was added, so that the tip of their main branch works with this firmware.

    opened by jepler 0
  • multiple revolutions

    multiple revolutions

    It appears that specialty operations, such as using g64conv to convert the second side of a flippy disk from a two-sided .scp of the disk taken from the top side, may require operation similar to the genuine greaseweazel hardware: capture multiple revolutions without gaps.

    the current implementation in this repo simply captures 3 different copies of the same track, from one falling index pulse to the next.

    Making a change like this has a big impact on the structure of the code. A ping-pong buffer system could be adopted, so that flux is entering buffer A and then buffer B; once buffer A is filled, it can be transmitted over USB. Probably rp2040 is forced to go interrupt based to enable this, which we want to do anyway.

    I don't have any proof that this is why my flippy-floppy dump didn't work; there are also g64conv bugs—with the geniune greaseweazel scp file, the directory data which should be on track 18 is on track 14 of the resulting g64 file! but it is intact. (track 18 sectors 0 and 1). By contrast, my rips with feather rp2040 to scp do not have track 18 sector 0, but do have track 18 sector 1 (again, transposed incorrectly to track 14 by g64conv). I know the flip side reads correctly because it happens to have two index windows and can be flipped in a standard PC 5.25 drive (teac).

    opened by jepler 3
  • Feature suggestion: littleFS support?

    Feature suggestion: littleFS support?

    https://hackaday.com/2019/01/24/cool-tools-a-little-filesystem-that-keeps-your-bits-on-lock/ https://github.com/littlefs-project/littlefs

    On top of the basic drive I/O routines it might be useful to implement littlefs, a filesystem made for microcontrollers. AFAIK all you need to do to port it is to provide it with implementations of a few functions for reading/writing/syncing blocks.

    The filesystem is simple and light weight, far more robust than FAT, and every operation is atomic.

    opened by Matthew-Bradley 0
  • Drive emulation

    Drive emulation

    Thank you for making this.

    Will you emulate a floppy drive too?

    I have an old Korg N364 synthesizer with a broken drive. Would be nice to mount a Pico instead, perhaps with extra flash. or sdcard reader.

    It's a Matsushita EME-216 KR according to the service manual - but some have 34 pin floppy drives.

    image image

    https://en.wikipedia.org/wiki/Floppy_disk_hardware_emulator http://hxc2001.free.fr/floppy_drive_emulator/ https://github.com/keirf/FlashFloppy

    opened by jpnielsen 1
  • density pin

    density pin

    The density pin is used differently depending on the manufacturer, some use it as an output to signal the media type (mostly teac drives) some use it as an input to switch the rpm (300/360) when using HD media (e.g. Sony 920), and at some it is NC. Detecting the media type can only be done by counting the transitions when reading a track. Or when writing a track by firstly trying to write a HD track and reading it back while counting the transitions, a DD disk will return much less transitions than written. And another problem is that all HD drives change the sensitivity/write strength of the head depending on the sensor for the HD hole of a disk, so that a DD image written to a HD disk will fail. Covering the HD hole will circumvent this issue.

    opened by Niteto 1
Releases(0.2.0)
Owner
Adafruit Industries
Adafruit Industries
AVR (atmega328p) based floppy emulator for PC

fddEMU An AVR (atmega328p) based floppy drive emulator for PC fddEMU is a DIY floppy drive emulator. You can immediately begin testing fddEMU on seria

Acemi Elektronikci 93 Sep 29, 2022
ColecoAdam a boot menu and configurator for ADE virtual drives

VHS HEAD For Coleco Adam users with Adamnet Disk Emulator (ADE) devices. VHS Head is a boot menu and configuration program for ADE (Pro and Lite) user

Thomas Cherryhomes 3 Dec 24, 2021
PyAerotech: An Opensource Python Library or interfacing directly with the Aerotech A3200 Controlle

PyAerotech: An Opensource Python Library or interfacing directly with the Aerotech A3200 Controller pyAerotech is an additional Opensource Python libr

Dr Luke Parry 3 Aug 22, 2022
This is for interfacing rasberry-pi's (2 cards) with an arduino for sending raw data to form the close loop system to avoid motor heating by acting on a given temperature.

This is for interfacing rasberry-pi's (2 cards) with an arduino for sending raw data to form the close loop system to avoid motor heating by acting on a given temperature. Interface is explained through a master slave approach and client server approach. another camera is used with OPEN-CV platform to interface and collect data aswell.

Younes HAMZA 2 Oct 25, 2021
Step-by-step guide through the abstract and complex universe of Fragment Shaders.

The Book of Shaders by Patricio Gonzalez Vivo and Jen Lowe This is a gentle step-by-step guide through the abstract and complex universe of Fragment S

Patricio Gonzalez Vivo 4.7k Oct 1, 2022
Free,Open-Source,Cross-platform agent and Post-exploiton tool written in Golang and C++, the architecture and usage like Cobalt Strike

Khepri Free,Open-Source,Cross-platform agent and Post-exploiton tool written in Golang and C++ Description Khepri is a Cross-platform agent, the archi

Young 1.4k Sep 30, 2022
A Graphical Engine written in C++ for abstract OpenGL

Lukeda Graphical Engine (LGE) It's a simple graphical library, written in C++ with OpenGL(GLEW) and GLFW Start as a fork from my other project named "

Lucas Morais 2 Jul 13, 2022
Khepri is a Cross-platform agent, the architecture and usage like Coblat Strike but free and open-source.

Khepri Free,Open-Source,Cross-platform agent and Post-exploiton tool written in Golang and C++ Description Khepri is a Cross-platform agent, the archi

Young 1.4k Oct 3, 2022
SDR++ is a cross-platform and open source SDR software with the aim of being bloat free and simple to use.

SDR++ is a cross-platform and open source SDR software with the aim of being bloat free and simple to use.

AlexandreRouma 2k Oct 4, 2022
A free and open-source cross-platform application to control your Philips hue compatible lights💡

?? OpenHue ?? A cross platform application to control your Philips hue compatible lights. licensed under the gpl 3.0 license. Currently in super early

BOB450 3 Dec 19, 2021
SomeSmile - a free, open source and not yet cross-platform

SomeSmile - a free, open source and not yet cross-platform Table Of Contents For What? Structure Start Usage Guide How To Build Screenshots End For Wh

SonicTheHedgehog 3 Aug 3, 2022
Libguestfs is tools and a library for accessing and modifying guest disk images

Libguestfs is tools and a library for accessing and modifying guest disk images

null 506 Oct 1, 2022
A cross platform shader language with multi-threaded offline compilation or platform shader source code generation

A cross platform shader language with multi-threaded offline compilation or platform shader source code generation. Output json reflection info and c++ header with your shaders structs, fx-like techniques and compile time branch evaluation via (uber-shader) "permutations".

Alex Dixon 278 Sep 29, 2022
FireDog - Open source cross-platform lightweight virus signature detection engine.

FireDog 开源跨平台轻量级病毒特征检测引擎。Open source cross-platform lightweight virus signature detection engine. 语言 Language C++ 11 LICENSE 是你们喜欢的:MIT License. 让我们搞起

null 40 Aug 20, 2022
First open-source Geometry Dash cross-platform Modding SDK

BoolkaSDK First open-source Geometry Dash cross-platform Modding SDK Requirements CMake 3.21 Android NDK r23 LLVM x86 Java and ApkTool Building Open C

null 6 Jun 9, 2022
Creates a virtual disk in memory and provides the user a shell to interact with it

Tiny-File-System Creates a virtual disk in memory and provides the user a shell to interact with it Known bugs with Export missing chars at the end of

Alex Fuller 2 Nov 23, 2021
Comparing data of module exports from disk and memory, then caching any differences.

Inline-PatchFinder Need to see if the process you're reversing/analyzing is patching/hooking any loaded module's exports? Well, look no further. Inlin

null 12 Jun 20, 2022
Graphs the disk IO in a linux terminal.

diskgraph Monitor for disk IO Introduction The diskgraph tool will graph disk IO under linux, in a terminal. Examples: $ ./diskgraph /dev/nvme0n1 $ ./

Bram Stolk 178 Sep 13, 2022
Microcontroller based switchless ROM switcher for the Commodore 1541-II disk drive

Retroninja 1541-II Switchless Multi-ROM A microcontroller based switchless ROM switcher for the Commodore 1541-II disk drive. Switch between stock CBM

retroninja 5 Sep 3, 2022