Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add basic support for Applesauce hardware. #773

Merged
merged 15 commits into from
Oct 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 10 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,8 @@ FluxEngine
(If you're reading this on GitHub, the formatting's a bit messed up. [Try the
version on cowlark.com instead.](http://cowlark.com/fluxengine/))

**Breaking news!** As of 2022-09-09, there's new [filesystem
support](doc/filesystem.md). Read (and sometimes write) files directly from
(and to) your disks, with eight different file systems! It works in the GUI,
too, which is available for Linux (and other Unix clones), Windows and OSX. See
the details below.
**Breaking news!** As of 2024-10-01, the FluxEngine client software works
(to a point) with [Applesauce](doc/applesauce.md) hardware.

<div style="text-align: center">
<a href="doc/screenshot.jpg"><img src="doc/screenshot.jpg" style="width:60%" alt="screenshot of the GUI in action"></a>
Expand All @@ -35,12 +32,14 @@ Don't believe me? Watch the demo reel!
</div>

**New!** The FluxEngine client software now works with
[Greaseweazle](https://github.com/keirf/Greaseweazle/wiki) hardware. So, if you
can't find a PSoC5 development kit, or don't want to use the Cypress Windows
tools for programming it, you can use one of these instead. Very nearly all
FluxEngine features are available with the Greaseweazle and it works out-of-the
box. See the [dedicated Greaseweazle documentation page](doc/greaseweazle.md)
for more information.
[Greaseweazle](https://github.com/keirf/Greaseweazle/wiki) and
[Applesauce](https://applesaucefdc.com/) hardware. So, if you can't find a PSoC5
development kit, or don't want to use the Cypress Windows tools for programming
it, you can use one of these instead. Very nearly all FluxEngine features are
available with the Greaseweazle and it works out-of-the box; the Applesauce is a
bit less supported but still works. See the [dedicated Greaseweazle
documentation page](doc/greaseweazle.md) or the [Applesauce
page](doc/applesauce.md) for more information.

Where?
------
Expand Down
3 changes: 3 additions & 0 deletions build.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,8 @@
"./lib/proto.cc",
"./lib/readerwriter.cc",
"./lib/sector.cc",
"./lib/usb/applesauce.cc",
"./lib/usb/applesauceusb.cc",
"./lib/usb/fluxengineusb.cc",
"./lib/usb/greaseweazle.cc",
"./lib/usb/greaseweazleusb.cc",
Expand Down Expand Up @@ -209,6 +211,7 @@
"lib/proto.h": "./lib/proto.h",
"lib/readerwriter.h": "./lib/readerwriter.h",
"lib/sector.h": "./lib/sector.h",
"lib/usb/applesauce.h": "./lib/usb/applesauce.h",
"lib/usb/greaseweazle.h": "./lib/usb/greaseweazle.h",
"lib/usb/usb.h": "./lib/usb/usb.h",
"lib/usb/usbfinder.h": "./lib/usb/usbfinder.h",
Expand Down
72 changes: 72 additions & 0 deletions doc/applesauce.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
Using the FluxEngine client software with Applesauce hardware
===============================================================

The FluxEngine isn't the only project which does this; another one is the
[Applesauce](https://applesaucefdc.com/), a proprietary but feature-rich
off-the-shelf imaging device. Its native client (which is a lot better than
FluxEngine) only works on OSX, so if you want to use it anywhere else,
the FluxEngine client works.

The Applesauce works rather differently to the FluxEngine hardware or the
[Greaseweazle](greaseweazle.md), so there are some caveats.

- Rather than streaming the flux data from the device to the PC, the Applesauce
has a fixed buffer in RAM used to capture a complete image of a track. This is
then downloaded later. The advantage is that USB bandwidth isn't an issue; the
downside is that the buffer can only hold so much data. In fact, the Applesauce
can only capture 1.25 revolutions or 2.25 revolutions, nothing else. When used
with the FluxEngine the capture time will be ignored apart from used to
determine whether you want a 'long' or 'short' capture.

- The current (v2) firmware only supports reading, not writing (via clients
other than the official one, of course). The new (v3) firmware will support
writing, but it's not out yet, so for the time being the FluxEngine client is
read only.

- You can only do synchronous reads, i.e., reads starting from the index mark.

Other than this, the FluxEngine software supports the Applesauce almost
out-of-the-box --- just plug it in and nearly everything should work. The
FluxEngine software will autodetect it. If you have more than one device plugged
in, use `--usb.serial=` to specify which one you want to use.

I am aware that having _software_ called FluxEngine and _hardware_ called
FluxEngine makes things complicated when you're not using the FluxEngine client
software with a FluxEngine board, but I'm afraid it's too late to change that
now. Sorry.

What works
----------

Supported features with the Greaseweazle include:

- simple reading of disks, seeking etc
- erasing disks
- hard sectored disks
- determining disk rotation speed
- normal IBM buses

I don't know what happens if you try to use an Apple Superdrive or a Apple II
disk with FluxEngine. If you've got one, [please get in
touch](https://github.com/davidgiven/fluxengine/issues/new)!

What doesn't work
-----------------

- voltage measurement
- writing

Who to contact
--------------

I want to make it clear that the FluxEngine code is _not_ supported by the
Applesauce team. If you have any problems, please [contact
me](https://github.com/davidgiven/fluxengine/issues/new) and not them.

In addition, the Applesauce release cycle is not synchronised to the
FluxEngine release cycle, so it's possible you'll have a version of the
Applesauce firmware which is not supported by FluxEngine. Hopefully, it'll
detect this and complain. Again, [file an
issue](https://github.com/davidgiven/fluxengine/issues/new) and I'll look into
it.

6 changes: 3 additions & 3 deletions doc/using.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,9 @@ file while changing the decoder options, to save disk wear. It's also much faste

### Connecting it up

To use, simply plug your FluxEngine (or [Greaseweazle](greaseweazle.md)) into
your computer and run the client. If a single device is plugged in, it will be
automatically detected and used.
To use, simply plug your FluxEngine (or [Greaseweazle](greaseweazle.md) or
[Applesauce](applesauce.md)) into your computer and run the client. If a single
device is plugged in, it will be automatically detected and used.

If _more_ than one device is plugged in, you need to specify which one to use
with the `--usb.serial` parameter, which takes the device serial number as a
Expand Down
6 changes: 3 additions & 3 deletions lib/decoders/fluxmapreader.cc
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ bool FluxmapReader::findEvent(int event, unsigned& ticks)
{
ticks = 0;

for (;;)
while (!eof())
{
unsigned thisTicks;
int thisEvent;
Expand All @@ -57,11 +57,11 @@ bool FluxmapReader::findEvent(int event, unsigned& ticks)
if (thisEvent == F_EOF)
return false;

if (eof())
return false;
if ((event == thisEvent) || (event & thisEvent))
return true;
}

return false;
}

unsigned FluxmapReader::readInterval(nanoseconds_t clock)
Expand Down
2 changes: 1 addition & 1 deletion lib/flags.cc
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ std::vector<std::string> FlagGroup::parseFlagsWithFilenames(int argc,
globalConfig().applyOption(path);
}
else
error("unrecognised flag; try --help");
error("unrecognised flag '-{}'; try --help", key);
}
else
{
Expand Down
2 changes: 1 addition & 1 deletion lib/fluxsource/fluxsource.proto
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ message HardwareFluxSourceProto {}

message TestPatternFluxSourceProto {
optional double interval_us = 1 [default = 4.0, (help) = "interval between pulses"];
optional double sequence_length_us = 2 [default = 200.0, (help) = "length of test sequence"];
optional double sequence_length_ms = 2 [default = 166.0, (help) = "length of test sequence"];
}

message EraseFluxSourceProto {}
Expand Down
4 changes: 2 additions & 2 deletions lib/fluxsource/testpatternfluxsource.cc
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ class TestPatternFluxSource : public TrivialFluxSource
{
auto fluxmap = std::make_unique<Fluxmap>();

while (fluxmap->duration() < (_config.sequence_length_us() * 1000000.0))
while (fluxmap->duration() < (_config.sequence_length_ms() * 1e6))
{
fluxmap->appendInterval(_config.interval_us());
fluxmap->appendInterval(_config.interval_us() * TICKS_PER_US);
fluxmap->appendPulse();
}

Expand Down
1 change: 0 additions & 1 deletion lib/globals.cc
Original file line number Diff line number Diff line change
Expand Up @@ -14,5 +14,4 @@ double getCurrentTime(void)
void warning(const std::string msg)
{
log(msg);
fmt::print("Warning: {}\n", msg);
}
64 changes: 64 additions & 0 deletions lib/usb/applesauce.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
#include "lib/globals.h"
#include "usb.h"
#include "protocol.h"
#include "lib/bytes.h"
#include "greaseweazle.h"
#include "lib/fluxmap.h"
#include "lib/decoders/fluxmapreader.h"
#include "lib/a2r.h"

static double a2r_to_ticks(double a2rticks)
{
return a2rticks * A2R_NS_PER_TICK / NS_PER_TICK;
}

static double ticks_to_a2r(double flticks)
{
return flticks * NS_PER_TICK / A2R_NS_PER_TICK;
}

Bytes fluxEngineToApplesauce(const Bytes& fldata)
{
Fluxmap fluxmap(fldata);
FluxmapReader fmr(fluxmap);
Bytes asdata;
ByteWriter bw(asdata);

while (!fmr.eof())
{
unsigned ticks;
if (!fmr.findEvent(F_BIT_PULSE, ticks))
break;

uint32_t applesauceTicks = ticks_to_a2r(ticks);
while (applesauceTicks >= 255)
{
bw.write_8(255);
applesauceTicks -= 255;
}
bw.write_8(applesauceTicks);
}

return asdata;
}

Bytes applesauceToFluxEngine(const Bytes& asdata)
{
ByteReader br(asdata);
Fluxmap fluxmap;

unsigned a2rTicksSinceLastPulse = 0;
while (!br.eof())
{
uint8_t b = br.read_8();
a2rTicksSinceLastPulse += b;
if (b != 255)
{
fluxmap.appendInterval(a2r_to_ticks(a2rTicksSinceLastPulse));
fluxmap.appendPulse();
a2rTicksSinceLastPulse = 0;
}
}

return fluxmap.rawBytes();
}
9 changes: 9 additions & 0 deletions lib/usb/applesauce.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#pragma once

#define APPLESAUCE_VID 0x16c0
#define APPLESAUCE_PID 0x0483

#define APPLESAUCE_ID ((APPLESAUCE_VID << 16) | APPLESAUCE_PID)

extern Bytes applesauceToFluxEngine(const Bytes& asdata);
extern Bytes fluxEngineToApplesauce(const Bytes& fldata);
Loading
Loading