Use a floppy-disk as a multi-frame-buffer, store audio-samples, and increase capacity to boot!

Similar projects worth following
Using PWM, rather than MFM, to store data on magnetic media, I believe it possible to increase the storage capacity dramatically without compromising data-integrity. With a simple 8-bit uC at 16MHz, 8 bits could be stored in 5 bits' space!

A single track, then, contains enough data to be used as a frame-buffer for a small LCD. 160 tracks makes for a digital-picture-frame, something like HyperCard, or even short videos.

But first, I'll store audio-samples, 80 tracks per side is perfect for a MIDI controlled synth-patch, etc. Yep, it's a bit crazy.

that name... just now imagined, might just do the trick... (was trying to figure out what to demo with this thing)

Herein, I plan to document plausibly the most ridiculous of my endeavors, to date...

Wherein there are planned two subprojects to demonstrate a technique I've come up with for increasing the amount of data that can be stored on media such as floppy disks, and maybe extendable to similar media still in use today, such as hard-disks.

(It's plausible this technique already exists, but I have not read of it previously).

The first subproject will use this technique to store and play-back audio directly on a diskette using an unmodified drive and a handful of discrete components (comparators, mostly). No microcontroller is necessary for concept-demonstration, though may be added later for increased functionality.

The second subproject, and likely my most-ridiculous, ever, will use this new storage technique to use a floppy diskette as a framebuffer for an LCD.

Briefly: each track will contain an entire frame, refreshing the LCD once with each revolution, at 5Hz.

(160 images! Think: HyperCard, or maybe a digital picture frame).


A standard 3.5in 1.44MB diskette is recorded at 500kb/s, and spins at 300RPM, or 5 rotations per second, 100,000 bits per rotation... left spinning on a single track, those 100,000 bits repeat...

A 240x160 LCD has 115,200 pixels... it's like a sign or something.

(Actually, it has 38,400 three-color pixels)

A) the 500kbps data rate is a guarantee by design, and can likely be bumped up a bit, especially on outer tracks... so a 15.2% increase should be doable. That doesn't include invisible pixel-clocks, used by the "porches", but... worst-case we lose some pixels at the right or bottom... definitely feasible.

But That's Irrelevent because:

B) a different, and possibly new, technique of magnetic data-storage is proposed:

North...  _____________
South... /       \_\_\_\_______/

Floppies store data as magnetic flux transitions. The 500kbps limitation is due, largely, as I understand, to the minimum distance at which two "magnets" can be placed on the innermost track without repelling or attracting each other too dramatically as to affect the stored data.

The typical approach is to store these flux transitions at one of two locations, depending on whether the bit is a one or zero. Thus, data is stored such that each data bit occupies essentially the minimum amount of space which can accomodate *either* flux-transition mapping without affecting the next bit. 

What I'm trying to say is that every bit contains (or at least is big enough to contain) a flux transition in either of two locations, one of which always goes unused...

But it needn't be that way...

Imagine a digital oscilloscope... Say it samples at 100MS/s. Analog-to-digital converters that fast are typically quite expensive. So a trick often used is to have, say, two 50MS/s ADCs which are offset by 1/2 of their sample-period. Bam... 100MS/s.

Now look at it the other way... the ADCs aren't restricted to 50MS/s... they could just as easily be bumped down to 49.9999MS/s. It's not a factor of sample-rates divisible by 50, it's a matter of the resolution of the sample-clock. And the limitation of 50MS/s is merely a matter of the maximum number of samples that can be crammed into a second, put more clearly, a matter of how fast a single sample can be processed.

But those samples don't have to be evenly spaced throughout a second! One could just as well sample one sample at 1/50millionth of a second, and sample the next at 1/49.999 sec, thereafter (being nowhere near some multiple of 1/50mil).

Oy... bad explanation. Let's think about synchronous logic... say...

Read more »

  • 'duh' moment...

    esot.eric4 days ago 2 comments

    OK, but there's really no [easy] way to determine whether we're looking at the *start* of a PWM cycle, or the falling-edge of the duty-cycle, itself... because: every edge is stored as a falling-edge.

    This doesn't matter for *audio*, because an inversion in the PWM output-signal results in an inversion in duty-cycle, around 50%... and *that* is nothing more than an inversion in polarity on the speaker-cone, which doesn't matter when only dealing with mono.

    But for *data* (e.g. the image-frames), we definitely need to keep track of which falling-edge corresponds to the beginning of a PWM pulse, and which corresponds to the duty-cycle's edge.

    I feel like I must've figured this out once before...

    Best I can come up with is to align the PWM with the "Index" output (which occurs once every rotation). But, that may be iffy, as well... E.G. the Write-head and Read-head may not be perfectly aligned... in which case, writing at the start of an index-pulse may be read-back after! Oy! Then, of course, the odds of the "index" outputs on differing drives being perfectly-timed with the read/write-heads... Even less likely.

    Some amount of reconstruction should be possible... e.g. let it run for several pulses, then figure out which edge occurs at the same period, then that's the PWM-start edge. But... well, anyways, it's getting a little more complicated.

    An interesting artifact will occur when switching tracks... (e.g. data will be garbled while the head races to the next track, *but* the screen will most-likely continue to refresh with that garbled data since the uC will be regenerating the pixel-clock... but hsyncs will be missed, or even randomly-injected...) I've looked forward to seeing that. And with this new dilemma, it could be even more interesting (e.g. colors may be inverted for one frame, even after the read-head has stopped seeking).

    Frankly, I consider these things to be one of the major driving-factors for this project... I already know the project should work as-planned, with maybe a few unexpecteds which can likely be worked-out... But these other things, probably not *useful* per-se, but hard to predict, so akin, maybe, to the draw to watching a flame. And sometimes these sortsa things wind-up being *very* useful... Moldy bread, yahknow? Moldy-milk, Moldy grapes, Moldy oats-grains-and-hops... Post-its! (oh, wait...) Once it's running, I'll probably spend more time looking into that stuff than actually making it useful (turning it into a game, etc.) If nothing else, maybe I could use it as a random-number-generator...


    Another idea, (I feel like I'm reinventing the standard method) is to have a "header" at the start of each track, immediately after the index-pulse. This'd contain a string of PWM-values with the same (not 50%) duty-cycle. Oh No! Wait a minute... It'd have to be *vastly-differing* duty-cycles, from one to the next. Then, use this time to look for the edges which are periodic, as described earlier.

    The original plan was to use the "index" pulse *as* the Vsync pulse... Doing-so, here, wouldn't be so useful... Unless, maybe, I choose to use the trailing-edge for Vsync, and the leading-edge for beginning the header. Hmmm.

    If that *doesn't* work, then we'd have a string of data that can't be used immediately after the vsync, which'd leave garbled pixels on the first row of the screen. (Which could be interesting, anyhow).

    But, it could be that we're back to having a specific nibble-value to indicate Vsync. Not so bad, really. Better, probably, what with the alignment concerns.

    And, again, I'm planning on storing 4-bits per PWM-value, that's 16 different duty-cycles within a 1us time-frame, which corresponds to our 16MHz processing-speed. (Or, plausibly, 16 values in 2us, allowing for some lee-way, in case the disk decides to spin at a slightly different rate from time-to-time; due to temperature, maybe, etc. Or different drives...). But, with these processing-speeds, it might be difficult...

    Read more »

  • Audio preparations

    esot.eric5 days ago 0 comments

    Before I actually start writing audio (and images!) to disk, I need to make sure my write/read technique/circuitry is "sound"...

    I've implemented the test-circuitry via comparators, just for the heck of it. And to (later) demonstrate how easy it is to make use of floppy-data... no microcontroller necessary! But, we're still a ways off from that.

    First, the audio is converted to PWM.

    Then both PWM edges are converted to falling-edge pulses.

    This, then, could be fed directly into a floppy drive's "write data" input, storing the PWM on-disk.

    When read-back from the disk, the floppy drive will give these same falling-edge pulses to indicate each edge of the recorded PWM.

    That, then, gets fed into my single-comparator T-Flip-Flop, to convert those falling-edges back into PWM, then directly drives a speaker.

  • WIP: MFM (normal diskette) data-storage

    esot.eric04/13/2018 at 04:04 0 comments

    Most floppy drives use a method called Modified Frequency Modulation (MFM) to store binary data-bits on the magnetic media.

    This method encodes each data-bit into two MFM 'bits'. E.G. the data-bit '1' is always encoded in MFM as "01", the data-bit '0' is either stored as MFM "00" or "10", depending on whether this follows a '0' or a '1' in the previous bit.

    This seemingly over-complicated scheme serves several purposes. First and foremost, it assures somewhat regularly-spaced transitions/alternating between North and South polarity on the media, regardless of the binary data stored. Thus, the floppy disk controller is able to keep its serial-data clock synchronized with the data-bits on-disk. Essentially, MFM encodes both the data-bit *and* the serial clock into each MFM bit-pair. This alternating polarity is also essential for the inductive read-head/pickup, which can only detect *changes* in magnetism. 

    Thus, MFM assures that even 1KB of consecutive 0x00's (e.g. after a format) will be stored on-disk as alternating between North and South, once for every 0-valued data-bit.


    But, note, again, that data-bit '0' has two separate encodings "00" and "10". If MFM "0110" were written to disk (binary data "10"), we'd have a problem... and this is where things get a bit more detailed, and we need to take a step back and analyze what's actually being stored on the disk.

    Each MFM bit represents a potential for transition in magnetic flux. Wow that's badly-worded. Let's try again.

    Most any position on the disk surface can either be North-polarized or South-polarized. MFM assures that North and South alternate somewhat regularly. Great!

    BUT, placing these opposing polarities too close together can cause problems. Maybe the read-head is too large, picking up two (or three?) polarities at the same time, unable to discern which it's reading. Maybe there's some inherent granularity* in the media? There could be many factors, but as I understand, it boils down to these "magnets," each one MFM-bit wide, attracting and repelling each other.

    Here's how I understand it: If you place two magnets on a table, so their North polarities face each other, then those two magnets will repel each other, up to a certain distance, at which point friction prevents further repulsion. 

    Placing a weaker magnet's South pole between the two would probably reduce the effect, but not eliminate it. The two stronger magnets still repel, and placing a compass above the weaker magnet's south pole will still show a net North polarity.

    (*Note that 'precompensation' is another topic entirely, but if granularity was a concern, precompensation wouldn't be possible)

    Thus, there is a minimum space which can reliably contain two flux-transitions (three polarities alternating, NSN or SNS). That minimum space is two MFM-bits long, on the innermost track, where the bits are most-densely packed.

    (binary values: High and Low. MFM values: Change and No-Change. Read/Write values: Hi-Z/floating and Low. Polarity values: North and South)

    Anyhow, an MFM '1' bit does not correspond to a polarity on the disk, it corresponds to a *change* in polarity on the disk. A "change in flux".

    And two changes in flux can only occur at greater than some minimum distance (2us on the smallest/inner track on a spinning disk). Thus, MFM encoding does not allow for a "11" pattern. The first data-bit '0' after a data-bit '1' is, therefore, encoded as "00" rather than "10", giving data="10" mfm="0100", rather than mfm="0110"; no consecutive '1's in the MFM encoding.

    All That To Say: diskettes guarantee proper data-retention when each singular magetic polarity is at least 2us long, but also alternates regularly. And, MFM assures that.


    So, the shortest single-polarity...

    Read more »

  • PWMing 2

    esot.eric04/12/2018 at 01:29 0 comments

    Again, we cannot send our PWM *data* directly to the floppy-drive's /Write-data pin. Instead we need to send two falling-edge pulses for each PWM-nibble. Confusingly, I plan to use a PWM-output from the microcontroller to create those *two* precisely-timed falling-edges. Thus requiring *two* uC-PWM cycles to write *one* PWM-nibble to disk.

    In order to write the PWM-data, I've come up with a couple possibilities: 

    In both cases, the negative-going /WR pulses will vary in duration depending on the value of the PWM-nibble to be written. This shouldn't matter, as the flux-transition is triggered by the falling-edge.

    The second case is a little less-intuitive, as the PWM-output cycle starts midway through the PWM-data signal.

    Importantly: the PWM-signal will have a constant period, possibly saving several instruction-cycles, which may be near the limit.

    These cases both assume a PWM-output that starts high and goes low after a set duration... AVRs allow for the opposite, or it could easily be done with an inverter, but I've yet to analyze whether that could be helpful (e.g. in aligning a *data* start with a *signal* start?). My intuition is that doing-so would require both PWM-output cycles to vary in period, e.g. duration1=value, duration2=2us-value, eating into our valuable instruction-cycles.

  • PWMing

    esot.eric11/26/2017 at 09:07 0 comments

    The read/write data pins on a floppy drive do not correspond to flux-value (e.g. 1 for North, 0 for South). Instead these signals supply a falling-edge at each flux transition... and the duration of the low pulse is somewhat arbitrary. Thus, I don't think it's possible to know the polarity on the disk. Though that doesn't matter. What does matter is that we can't just drive the /WD pin with our PWM signal, as will be stored on the media...

View all 5 project logs

Enjoy this project?



zakqwy wrote 04/12/2018 at 13:35 point

man I miss hypercard.

  Are you sure? yes | no

esot.eric wrote 04/13/2018 at 05:39 point

Those were The Dayz!

  Are you sure? yes | no

Similar Projects

Does this project spark your interest?

Become a member to follow this project and never miss any updates