Skip to content

Commit f52967b

Browse files
committed
WIP: Add solved/reconstructed fluxmap support.
This proof of concept adds an optional encoder and fluxsink that runs after the image is written. This currently exposes the config of the solvedEncoder, though I think I ultimately don't want it to be exposed as part of the config proto. Another way to do this would be by extending the decoders and/or directly reading their records. That is actually closer to what I want in many ways, however those records would need to be deduplicated from multiple reads, etc. The ultimate goal is to exactly replicate the timing of the original sectors, but with a stable clock, sectors reread if a bad read happens, and garbage between sectors removed. This requires extending the sector struct to have more information than it currently holds.
1 parent e733dc9 commit f52967b

File tree

8 files changed

+76
-4
lines changed

8 files changed

+76
-4
lines changed

arch/ibm/encoder.cc

+29
Original file line numberDiff line numberDiff line change
@@ -315,3 +315,32 @@ std::unique_ptr<AbstractEncoder> createIbmEncoder(const EncoderProto& config)
315315
{
316316
return std::unique_ptr<AbstractEncoder>(new IbmEncoder(config));
317317
}
318+
319+
std::unique_ptr<AbstractEncoder> createIbmEncoderFromImage(EncoderProto& config, const Image& image)
320+
{
321+
IbmEncoderProto* ibm;
322+
Geometry geometry;
323+
ibm = config.mutable_ibm();
324+
geometry = image.getGeometry();
325+
std::map<int,std::map<int,std::vector<const Sector*>>> tracks_heads;
326+
for (const auto& sector : image) {
327+
tracks_heads[sector->logicalTrack][sector->logicalSide].push_back(sector.get());
328+
}
329+
for (const auto& track: tracks_heads) {
330+
for (const auto& head : track.second) {
331+
auto trackdata = ibm->mutable_trackdata()->Add();
332+
for (const auto& sector : head.second) {
333+
trackdata->mutable_sectors()->mutable_sector()->Add(sector->logicalSector);
334+
trackdata->set_sector_size(sector->data.size());
335+
}
336+
trackdata->set_track(track.first);
337+
trackdata->set_head(head.first);
338+
trackdata->set_gap0(0x1b);
339+
trackdata->set_gap2(0x09);
340+
trackdata->set_gap3(0x1b);
341+
trackdata->set_target_clock_period_us(1e3/250);
342+
trackdata->set_target_rotational_period_ms(200);
343+
}
344+
}
345+
return createIbmEncoder(config);
346+
}

arch/ibm/ibm.h

+1
Original file line numberDiff line numberDiff line change
@@ -33,5 +33,6 @@ class EncoderProto;
3333

3434
extern std::unique_ptr<AbstractDecoder> createIbmDecoder(const DecoderProto& config);
3535
extern std::unique_ptr<AbstractEncoder> createIbmEncoder(const EncoderProto& config);
36+
extern std::unique_ptr<AbstractEncoder> createIbmEncoderFromImage(EncoderProto& config, const Image& image);
3637

3738
#endif

lib/config.proto

+3-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import "lib/drive.proto";
1111
import "lib/mapper.proto";
1212
import "lib/common.proto";
1313

14-
// NEXT_TAG: 17
14+
// NEXT_TAG: 19
1515
message ConfigProto {
1616
optional string comment = 8;
1717
optional bool is_extension = 13;
@@ -21,9 +21,11 @@ message ConfigProto {
2121

2222
optional FluxSourceProto flux_source = 10;
2323
optional FluxSinkProto flux_sink = 11;
24+
optional FluxSinkProto solved_flux = 17;
2425
optional DriveProto drive = 15;
2526

2627
optional EncoderProto encoder = 3;
28+
optional EncoderProto solved_encoder = 18;
2729
optional DecoderProto decoder = 4;
2830
optional UsbProto usb = 5;
2931

lib/encoders/encoders.cc

+18
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
#include "arch/tids990/tids990.h"
1414
#include "arch/victor9k/victor9k.h"
1515
#include "lib/encoders/encoders.pb.h"
16+
#include "lib/decoders/decoders.pb.h"
17+
#include "lib/image.h"
1618
#include "protocol.h"
1719

1820
std::unique_ptr<AbstractEncoder> AbstractEncoder::create(
@@ -40,6 +42,22 @@ std::unique_ptr<AbstractEncoder> AbstractEncoder::create(
4042
return (encoder->second)(config);
4143
}
4244

45+
std::unique_ptr<AbstractEncoder> AbstractEncoder::createFromImage(EncoderProto& encoderConfig,
46+
const DecoderProto& decoderConfig, const Image& image)
47+
{
48+
static const std::map<int,
49+
std::function<std::unique_ptr<AbstractEncoder>(EncoderProto&, const Image&)>>
50+
encoders = {
51+
{DecoderProto::kIbm, createIbmEncoderFromImage},
52+
};
53+
54+
auto encoder = encoders.find(decoderConfig.format_case());
55+
if (encoder == encoders.end())
56+
Error() << "solved fluxmaps not supported for this format";
57+
58+
return (encoder->second)(encoderConfig, image);
59+
}
60+
4361
Fluxmap& Fluxmap::appendBits(const std::vector<bool>& bits, nanoseconds_t clock)
4462
{
4563
nanoseconds_t now = duration();

lib/encoders/encoders.h

+3
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
#define ENCODERS_H
33

44
class EncoderProto;
5+
class DecoderProto;
56
class Fluxmap;
67
class Image;
78
class Location;
@@ -14,6 +15,8 @@ class AbstractEncoder
1415
virtual ~AbstractEncoder() {}
1516

1617
static std::unique_ptr<AbstractEncoder> create(const EncoderProto& config);
18+
static std::unique_ptr<AbstractEncoder> createFromImage(EncoderProto& encoderConfig,
19+
const DecoderProto& decoderConfig, const Image& image);
1720

1821
public:
1922
virtual std::vector<std::shared_ptr<const Sector>> collectSectors(

lib/readerwriter.cc

+6-1
Original file line numberDiff line numberDiff line change
@@ -470,14 +470,19 @@ std::shared_ptr<const DiskFlux> readDiskCommand(
470470
}
471471

472472
void readDiskCommand(
473-
FluxSource& fluxsource, AbstractDecoder& decoder, ImageWriter& writer)
473+
FluxSource& fluxsource, AbstractDecoder& decoder, ImageWriter& writer,FluxSink* solvedFlux)
474474
{
475475
auto diskflux = readDiskCommand(fluxsource, decoder);
476476

477477
writer.printMap(*diskflux->image);
478478
if (config.decoder().has_write_csv_to())
479479
writer.writeCsv(*diskflux->image, config.decoder().write_csv_to());
480480
writer.writeImage(*diskflux->image);
481+
if (config.has_solved_flux()) {
482+
std::unique_ptr<AbstractEncoder> solvedEncoder = AbstractEncoder::createFromImage(*config.mutable_encoder(),
483+
config.decoder(), *diskflux->image);
484+
writeTracks(*solvedFlux, *solvedEncoder, *diskflux->image);
485+
}
481486
}
482487

483488
void rawReadDiskCommand(FluxSource& fluxsource, FluxSink& fluxsink)

lib/readerwriter.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ extern std::unique_ptr<TrackDataFlux> readAndDecodeTrack(
3434
FluxSource& source, AbstractDecoder& decoder, unsigned track, unsigned head);
3535

3636
extern std::shared_ptr<const DiskFlux> readDiskCommand(FluxSource& fluxsource, AbstractDecoder& decoder);
37-
extern void readDiskCommand(FluxSource& source, AbstractDecoder& decoder, ImageWriter& writer);
37+
extern void readDiskCommand(FluxSource& source, AbstractDecoder& decoder, ImageWriter& writer, FluxSink* solvedFlux);
3838
extern void rawReadDiskCommand(FluxSource& source, FluxSink& sink);
3939

4040
#endif

src/fe-read.cc

+15-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
#include "readerwriter.h"
44
#include "fluxmap.h"
55
#include "decoders/decoders.h"
6+
#include "encoders/encoders.h"
67
#include "macintosh/macintosh.h"
78
#include "sector.h"
89
#include "proto.h"
@@ -45,6 +46,15 @@ static StringFlag copyFluxTo(
4546
FluxSink::updateConfigForFilename(config.mutable_decoder()->mutable_copy_flux_to(), value);
4647
});
4748

49+
static StringFlag solvedFlux(
50+
{ "-r", "--solved" },
51+
"after reading, write a reconstructed/solved fluxmap to this file",
52+
"",
53+
[](const auto& value)
54+
{
55+
FluxSink::updateConfigForFilename(config.mutable_solved_flux(), value);
56+
});
57+
4858
static StringFlag srcTracks(
4959
{ "--cylinders", "-c" },
5060
"tracks to read from",
@@ -76,8 +86,12 @@ int mainRead(int argc, const char* argv[])
7686
std::unique_ptr<FluxSource> fluxSource(FluxSource::create(config.flux_source()));
7787
std::unique_ptr<AbstractDecoder> decoder(AbstractDecoder::create(config.decoder()));
7888
std::unique_ptr<ImageWriter> writer(ImageWriter::create(config.image_writer()));
89+
std::unique_ptr<FluxSink> solvedFlux;
90+
std::unique_ptr<AbstractEncoder> solvedEncoder;
91+
if (config.has_solved_flux()) {
92+
solvedFlux = FluxSink::create(config.solved_flux()); }
7993

80-
readDiskCommand(*fluxSource, *decoder, *writer);
94+
readDiskCommand(*fluxSource, *decoder, *writer, solvedFlux.get());
8195

8296
return 0;
8397
}

0 commit comments

Comments
 (0)