mirror of
https://github.com/davidgiven/fluxengine.git
synced 2025-10-31 11:17:01 -07:00
The new client can (lazily) read disks now, although nothing's actually done
with the result.
This commit is contained in:
@@ -67,6 +67,7 @@ public:
|
||||
_value(defaultValue)
|
||||
{}
|
||||
|
||||
T value() const { return _value; }
|
||||
operator T() const { return _value; }
|
||||
|
||||
bool hasArgument() const { return true; }
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
33
lib/reader.h
33
lib/reader.h
@@ -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
|
||||
|
||||
43
lib/usb.cc
43
lib/usb.cc
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user