The new client can (lazily) read disks now, although nothing's actually done

with the result.
This commit is contained in:
David Given
2018-10-20 15:54:18 +02:00
parent 7efaae2f76
commit 7d765abb21
7 changed files with 154 additions and 31 deletions

View File

@@ -67,6 +67,7 @@ public:
_value(defaultValue)
{}
T value() const { return _value; }
operator T() const { return _value; }
bool hasArgument() const { return true; }

View File

@@ -1,12 +1,13 @@
#ifndef GLOBALS_H
#define GLOBALS_H
#include <vector>
#include <map>
#include <string>
#include <sstream>
#include <iostream>
#include <functional>
#include <iostream>
#include <map>
#include <memory>
#include <sstream>
#include <string>
#include <vector>
typedef int nanoseconds_t;

View File

@@ -1,6 +1,13 @@
#include "globals.h"
#include "flags.h"
#include "usb.h"
#include "reader.h"
#include "fluxmap.h"
#include <regex>
static const std::regex SOURCE_REGEX("([^:]*)"
"(?::t=([0-9]+)(?:-([0-9]+))?)?"
"(?::s=([0-9]+)(?:-([0-9]+))?)?");
static StringFlag source(
{ "--source", "-s" },
@@ -16,8 +23,81 @@ static SettableFlag justRead(
{ "--just-read", "-R" },
"just read the disk but do no further processing");
int allTracks()
static IntFlag revolutions(
{ "--revolutions" },
"read this many revolutions of the disk",
1);
static std::string basefilename;
static int starttrack = 0;
static int endtrack = 79;
static int startside = 0;
static int endside = 1;
Fluxmap& Track::read()
{
return 0;
if (!_read)
{
reallyRead();
_read = true;
}
return *_fluxmap.get();
}
void Track::forceReread()
{
_read = false;
}
void CapturedTrack::reallyRead()
{
std::cout << "read track " << track << " side " << side << ": " << std::flush;
usbSeek(track);
_fluxmap = usbRead(side, revolutions);
std::cout << int(_fluxmap->duration()/1e6) << "ms in " << _fluxmap->bytes() << " bytes" << std::endl;
}
void FileTrack::reallyRead()
{
Error() << "unsupported";
}
std::vector<std::unique_ptr<Track>> readTracks()
{
auto f = source.value();
std::smatch match;
if (!std::regex_match(f, match, SOURCE_REGEX))
Error() << "invalid source specifier '" << source.value() << "'";
basefilename = match[1];
if (match[2].length() != 0)
starttrack = endtrack = std::stoi(match[2]);
if (match[3].length() != 0)
endtrack = std::stoi(match[3]);
if (match[4].length() != 0)
startside = endside = std::stoi(match[4]);
if (match[5].length() != 0)
endside = std::stoi(match[5]);
std::cout << "Reading from: "
<< (basefilename.empty() ? "a real floppy disk" : basefilename) << std::endl
<< "Tracks: "
<< starttrack << " to " << endtrack << " inclusive" << std::endl
<< "Sides: "
<< startside << " to " << endside << " inclusive" << std::endl;
std::vector<std::unique_ptr<Track>> tracks;
for (int track=starttrack; track<=endtrack; track++)
{
for (int side=startside; side<=endside; side++)
{
std::unique_ptr<Track> t(
basefilename.empty() ? (Track*)new CapturedTrack() : (Track*)new FileTrack());
t->track = track;
t->side = side;
tracks.push_back(std::move(t));
}
}
return tracks;
}

View File

@@ -1,6 +1,37 @@
#ifndef READER_H
#define READER_H
extern int allTracks();
class Fluxmap;
class Track
{
public:
virtual ~Track() {}
int track;
int side;
Fluxmap& read();
void forceReread();
virtual void reallyRead() = 0;
protected:
bool _read = false;
std::unique_ptr<Fluxmap> _fluxmap;
};
class CapturedTrack : public Track
{
public:
void reallyRead();
};
class FileTrack : public Track
{
public:
void reallyRead();
};
extern std::vector<std::unique_ptr<Track>> readTracks();
#endif

View File

@@ -1,6 +1,7 @@
#include "globals.h"
#include "usb.h"
#include "protocol.h"
#include "fluxmap.h"
#include <libusb.h>
#define TIMEOUT 5000
@@ -66,7 +67,7 @@ static void bad_reply(void)
{
struct error_frame* f = (struct error_frame*) buffer;
if (f->f.type != F_FRAME_ERROR)
Error() << "bad USB reply %d" << f->f.type;
Error() << "bad USB reply " << f->f.type;
switch (f->error)
{
case F_ERROR_BAD_COMMAND:
@@ -100,13 +101,13 @@ int usbGetVersion(void)
return r->version;
}
void usbSeek(uint8_t track)
void usbSeek(int track)
{
usb_init();
struct seek_frame f = {
{ .type = F_FRAME_SEEK_CMD, .size = sizeof(f) },
.track = track
.track = (uint8_t) track
};
usb_cmd_send(&f, f.f.size);
await_reply<struct any_frame>(F_FRAME_SEEK_REPLY);
@@ -123,10 +124,10 @@ nanoseconds_t usbGetRotationalPeriod(void)
return r->period_ms * 1000;
}
static int large_bulk_transfer(int ep, void* buffer, int total_len)
static int large_bulk_transfer(int ep, std::vector<uint8_t>& buffer)
{
int len;
int i = libusb_bulk_transfer(device, ep, (uint8_t*) buffer, total_len, &len, TIMEOUT);
int i = libusb_bulk_transfer(device, ep, &buffer[0], buffer.size(), &len, TIMEOUT);
if (i < 0)
Error() << "data transfer failed: " << usberror(i);
return len;
@@ -144,18 +145,17 @@ void usbTestBulkTransport()
const int YSIZE = 256;
const int ZSIZE = 64;
uint8_t bulk_buffer[XSIZE*YSIZE*ZSIZE];
int total_len = sizeof(bulk_buffer);
std::vector<uint8_t> bulk_buffer(XSIZE*YSIZE*ZSIZE);
double start_time = getCurrentTime();
large_bulk_transfer(FLUXENGINE_DATA_IN_EP, bulk_buffer, total_len);
large_bulk_transfer(FLUXENGINE_DATA_IN_EP, bulk_buffer);
double elapsed_time = getCurrentTime() - start_time;
std::cout << "Transferred "
<< total_len
<< bulk_buffer.size()
<< " bytes in "
<< int(elapsed_time * 1000.0)
<< " ("
<< int((total_len / 1024.0) / elapsed_time)
<< int((bulk_buffer.size() / 1024.0) / elapsed_time)
<< " kB/s)"
<< std::endl;
@@ -164,7 +164,7 @@ void usbTestBulkTransport()
for (int z=0; z<ZSIZE; z++)
{
int offset = x*XSIZE*YSIZE + y*ZSIZE + z;
if (bulk_buffer[offset] != uint8_t(x+y+z))
if (bulk_buffer.at(offset) != uint8_t(x+y+z))
Error() << "data transfer corrupted at 0x"
<< std::hex << offset << std::dec
<< " "
@@ -174,27 +174,28 @@ void usbTestBulkTransport()
await_reply<struct any_frame>(F_FRAME_BULK_TEST_REPLY);
}
#if 0
struct fluxmap* usb_read(int side, int revolutions)
std::unique_ptr<Fluxmap> usbRead(int side, int revolutions)
{
struct read_frame f = {
.f = { .type = F_FRAME_READ_CMD, .size = sizeof(f) },
.side = side,
.revolutions = revolutions
.side = (uint8_t) side,
.revolutions = (uint8_t) revolutions
};
struct fluxmap* fluxmap = create_fluxmap();
usb_cmd_send(&f, f.f.size);
uint8_t buffer[1024*1024];
int len = large_bulk_transfer(FLUXENGINE_DATA_IN_EP, buffer, sizeof(buffer));
auto fluxmap = std::unique_ptr<Fluxmap>(new Fluxmap);
fluxmap_append_intervals(fluxmap, buffer, len);
std::vector<uint8_t> buffer(1024*1024);
int len = large_bulk_transfer(FLUXENGINE_DATA_IN_EP, buffer);
buffer.resize(len);
await_reply(F_FRAME_READ_REPLY);
fluxmap->appendIntervals(buffer);
await_reply<struct any_frame>(F_FRAME_READ_REPLY);
return fluxmap;
}
#if 0
/* Returns number of bytes actually written */
void usb_write(int side, struct fluxmap* fluxmap)
{

View File

@@ -1,9 +1,12 @@
#ifndef USB_H
#define USB_H
class Fluxmap;
extern int usbGetVersion();
extern void usbSeek(uint8_t track);
extern void usbSeek(int track);
extern nanoseconds_t usbGetRotationalPeriod();
extern void usbTestBulkTransport();
extern std::unique_ptr<Fluxmap> usbRead(int side, int revolutions);
#endif

View File

@@ -1,11 +1,17 @@
#include "globals.h"
#include "flags.h"
#include "reader.h"
#include "fluxmap.h"
int main(int argc, const char* argv[])
{
Flag::parseFlags(argc, argv);
allTracks();
for (auto& track : readTracks())
{
track->read();
std::cout << "track " << track->track << " " << track->side << std::endl;
}
return 0;
}