mirror of
https://github.com/davidgiven/fluxengine.git
synced 2025-10-24 11:11:02 -07:00
Fluxmaps can now be queried for a (cached) list of index marks. Tracks
now contain both the raw list of sectors and a deduplicated list, suitable for the visualiser.
This commit is contained in:
@@ -88,7 +88,7 @@ void renderLogMessage(
|
||||
std::set<std::shared_ptr<const Record>> rawRecords;
|
||||
for (const auto& track : m->tracks)
|
||||
{
|
||||
rawSectors.insert(track->sectors.begin(), track->sectors.end());
|
||||
rawSectors.insert(track->allSectors.begin(), track->allSectors.end());
|
||||
rawRecords.insert(track->records.begin(), track->records.end());
|
||||
}
|
||||
|
||||
@@ -113,7 +113,7 @@ void renderLogMessage(
|
||||
m->sectors.begin(), m->sectors.end());
|
||||
std::sort(sectors.begin(), sectors.end(), sectorPointerSortPredicate);
|
||||
|
||||
for (const auto& sector : sectors)
|
||||
for (const auto& sector : rawSectors)
|
||||
r.add(fmt::format("{}.{}.{}{}",
|
||||
sector->logicalCylinder,
|
||||
sector->logicalHead,
|
||||
@@ -180,7 +180,7 @@ private:
|
||||
_cache;
|
||||
};
|
||||
|
||||
void measureDiskRotation()
|
||||
static nanoseconds_t measureDiskRotation()
|
||||
{
|
||||
log(BeginSpeedOperationLogMessage());
|
||||
|
||||
@@ -220,6 +220,7 @@ void measureDiskRotation()
|
||||
error("Failed\nIs a disk in the drive?");
|
||||
|
||||
log(EndSpeedOperationLogMessage{oneRevolution});
|
||||
return oneRevolution;
|
||||
}
|
||||
|
||||
/* Given a set of sectors, deduplicates them sensibly (e.g. if there is a good
|
||||
@@ -298,7 +299,7 @@ static CombinationResult combineRecordAndSectors(
|
||||
/* Add the sectors which were there. */
|
||||
|
||||
for (auto& track : tracks)
|
||||
for (auto& sector : track->sectors)
|
||||
for (auto& sector : track->allSectors)
|
||||
track_sectors.push_back(sector);
|
||||
|
||||
/* Add the sectors which should be there. */
|
||||
@@ -399,6 +400,7 @@ static ReadGroupResult readGroup(const DiskLayout& diskLayout,
|
||||
fluxmap->bytes());
|
||||
|
||||
auto flux = decoder.decodeToSectors(std::move(fluxmap), ptl);
|
||||
flux->normalisedSectors = collectSectors(flux->allSectors);
|
||||
tracks.push_back(flux);
|
||||
|
||||
/* Decode what we've got so far. */
|
||||
@@ -707,6 +709,10 @@ void readDiskCommand(const DiskLayout& diskLayout,
|
||||
.push_back(track);
|
||||
|
||||
log(BeginOperationLogMessage{"Reading and decoding disk"});
|
||||
|
||||
if (fluxSource.isHardware())
|
||||
disk.rotationalPeriod = measureDiskRotation();
|
||||
|
||||
{
|
||||
std::unique_ptr<FluxSink> outputFluxSink;
|
||||
if (outputFluxSinkFactory)
|
||||
|
||||
@@ -76,8 +76,6 @@ struct OperationProgressLogMessage
|
||||
unsigned progress;
|
||||
};
|
||||
|
||||
extern void measureDiskRotation();
|
||||
|
||||
extern void writeTracks(const DiskLayout& diskLayout,
|
||||
FluxSinkFactory& fluxSinkFactory,
|
||||
const std::function<std::unique_ptr<const Fluxmap>(
|
||||
|
||||
@@ -47,7 +47,8 @@ Disk::Disk(
|
||||
for (auto& [ch, sector] :
|
||||
sectorsGroupedByTrack.equal_range(physicalLocation) | pair_to_range)
|
||||
{
|
||||
decodedTrack->sectors.push_back(sector);
|
||||
decodedTrack->allSectors.push_back(sector);
|
||||
decodedTrack->normalisedSectors.push_back(sector);
|
||||
sectorsByPhysicalLocation.insert(
|
||||
std::make_pair(physicalLocation, sector));
|
||||
}
|
||||
|
||||
@@ -26,7 +26,14 @@ struct Track
|
||||
std::shared_ptr<const PhysicalTrackLayout> ptl;
|
||||
std::shared_ptr<const Fluxmap> fluxmap;
|
||||
std::vector<std::shared_ptr<const Record>> records;
|
||||
std::vector<std::shared_ptr<const Sector>> sectors;
|
||||
|
||||
/* All sectors, valid or not, including duplicates. */
|
||||
|
||||
std::vector<std::shared_ptr<const Sector>> allSectors;
|
||||
|
||||
/* Zero or one sector for each ID, preferring good ones. */
|
||||
|
||||
std::vector<std::shared_ptr<const Sector>> normalisedSectors;
|
||||
};
|
||||
|
||||
struct Disk
|
||||
@@ -46,6 +53,10 @@ struct Disk
|
||||
std::multimap<CylinderHead, std::shared_ptr<const Sector>>
|
||||
sectorsByPhysicalLocation;
|
||||
std::shared_ptr<const Image> image;
|
||||
|
||||
/* 0 if the period is unknown (e.g. if this Disk was made from an image). */
|
||||
|
||||
nanoseconds_t rotationalPeriod = 0;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
#include "lib/core/globals.h"
|
||||
#include "lib/data/fluxmap.h"
|
||||
#include "lib/data/fluxmapreader.h"
|
||||
#include "protocol.h"
|
||||
#include <mutex>
|
||||
|
||||
Fluxmap& Fluxmap::appendBytes(const Bytes& bytes)
|
||||
{
|
||||
@@ -12,6 +14,8 @@ Fluxmap& Fluxmap::appendBytes(const Bytes& bytes)
|
||||
|
||||
Fluxmap& Fluxmap::appendBytes(const uint8_t* ptr, size_t len)
|
||||
{
|
||||
flushIndexMarks();
|
||||
|
||||
ByteWriter bw(_bytes);
|
||||
bw.seekToEnd();
|
||||
|
||||
@@ -52,6 +56,7 @@ Fluxmap& Fluxmap::appendPulse()
|
||||
|
||||
Fluxmap& Fluxmap::appendIndex()
|
||||
{
|
||||
flushIndexMarks();
|
||||
findLastByte() |= 0x40;
|
||||
return *this;
|
||||
}
|
||||
@@ -75,3 +80,27 @@ std::vector<std::unique_ptr<const Fluxmap>> Fluxmap::split() const
|
||||
|
||||
return maps;
|
||||
}
|
||||
|
||||
const std::vector<nanoseconds_t>& Fluxmap::getIndexMarks() const
|
||||
{
|
||||
std::scoped_lock lock(_mutationMutex);
|
||||
if (!_indexMarks.has_value())
|
||||
{
|
||||
_indexMarks = std::make_optional<std::vector<nanoseconds_t>>();
|
||||
FluxmapReader fmr(*this);
|
||||
for (;;)
|
||||
{
|
||||
unsigned ticks;
|
||||
if (!fmr.findEvent(F_BIT_INDEX, ticks))
|
||||
break;
|
||||
_indexMarks->push_back(fmr.tell().ns());
|
||||
}
|
||||
}
|
||||
return *_indexMarks;
|
||||
}
|
||||
|
||||
void Fluxmap::flushIndexMarks()
|
||||
{
|
||||
std::scoped_lock lock(_mutationMutex);
|
||||
_indexMarks = {};
|
||||
}
|
||||
|
||||
@@ -82,14 +82,18 @@ public:
|
||||
std::unique_ptr<const Fluxmap> precompensate(
|
||||
int threshold_ticks, int amount_ticks);
|
||||
std::vector<std::unique_ptr<const Fluxmap>> split() const;
|
||||
const std::vector<nanoseconds_t>& getIndexMarks() const;
|
||||
|
||||
private:
|
||||
uint8_t& findLastByte();
|
||||
void flushIndexMarks();
|
||||
|
||||
private:
|
||||
nanoseconds_t _duration = 0;
|
||||
int _ticks = 0;
|
||||
Bytes _bytes;
|
||||
mutable std::mutex _mutationMutex;
|
||||
mutable std::optional<std::vector<nanoseconds_t>> _indexMarks;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -44,6 +44,13 @@ void FluxmapReader::skipToEvent(int event)
|
||||
findEvent(event, ticks);
|
||||
}
|
||||
|
||||
int FluxmapReader::getCurrentEvent()
|
||||
{
|
||||
if (eof())
|
||||
return F_EOF;
|
||||
return _bytes[_pos.bytes] & 0xc0;
|
||||
}
|
||||
|
||||
bool FluxmapReader::findEvent(int event, unsigned& ticks)
|
||||
{
|
||||
ticks = 0;
|
||||
|
||||
@@ -42,6 +42,7 @@ public:
|
||||
return (_fluxmap.duration());
|
||||
}
|
||||
|
||||
int getCurrentEvent();
|
||||
void getNextEvent(int& event, unsigned& ticks);
|
||||
void skipToEvent(int event);
|
||||
bool findEvent(int event, unsigned& ticks);
|
||||
|
||||
@@ -90,7 +90,7 @@ std::shared_ptr<Track> Decoder::decodeToSectors(
|
||||
}
|
||||
|
||||
if (_sector->status != Sector::MISSING)
|
||||
_trackdata->sectors.push_back(_sector);
|
||||
_trackdata->allSectors.push_back(_sector);
|
||||
}
|
||||
|
||||
return _trackdata;
|
||||
|
||||
@@ -5,8 +5,11 @@
|
||||
#include "fmt/format.h"
|
||||
#include "tests.h"
|
||||
#include <sstream>
|
||||
#include "snowhouse/snowhouse.h"
|
||||
|
||||
static Fluxmap fluxmap(Bytes{F_DESYNC,
|
||||
using namespace snowhouse;
|
||||
|
||||
static const Fluxmap fluxmap(Bytes{F_DESYNC,
|
||||
F_BIT_PULSE | 0x30,
|
||||
F_BIT_INDEX | 0x30,
|
||||
F_BIT_PULSE | F_BIT_INDEX | 0x30,
|
||||
@@ -59,7 +62,7 @@ void test_read_pulses()
|
||||
ASSERT_READ_SPECIFIC_EVENT(F_BIT_PULSE, 0x60);
|
||||
ASSERT_READ_SPECIFIC_EVENT(F_BIT_PULSE, 0x60);
|
||||
ASSERT_READ_SPECIFIC_EVENT(F_BIT_PULSE, 0x30);
|
||||
ASSERT_READ_SPECIFIC_EVENT(F_BIT_PULSE, 0x90);
|
||||
ASSERT_READ_SPECIFIC_EVENT(F_BIT_PULSE, 0x90); /* EOF event */
|
||||
}
|
||||
|
||||
void test_read_indices()
|
||||
@@ -67,7 +70,7 @@ void test_read_indices()
|
||||
FluxmapReader fmr(fluxmap);
|
||||
ASSERT_READ_SPECIFIC_EVENT(F_BIT_INDEX, 0x60);
|
||||
ASSERT_READ_SPECIFIC_EVENT(F_BIT_INDEX, 0x30);
|
||||
ASSERT_READ_SPECIFIC_EVENT(F_BIT_INDEX, 6 * 0x30);
|
||||
ASSERT_READ_SPECIFIC_EVENT(F_BIT_INDEX, 6 * 0x30); /* EOF event */
|
||||
}
|
||||
|
||||
void test_read_desyncs()
|
||||
@@ -76,7 +79,13 @@ void test_read_desyncs()
|
||||
ASSERT_READ_SPECIFIC_EVENT(F_DESYNC, 0);
|
||||
ASSERT_READ_SPECIFIC_EVENT(F_DESYNC, 0xf0);
|
||||
ASSERT_READ_SPECIFIC_EVENT(F_DESYNC, 0x60);
|
||||
ASSERT_READ_SPECIFIC_EVENT(F_DESYNC, 0x60);
|
||||
ASSERT_READ_SPECIFIC_EVENT(F_DESYNC, 0x60); /* EOF event */
|
||||
}
|
||||
|
||||
void test_index_marks()
|
||||
{
|
||||
AssertThat(fluxmap.getIndexMarks(),
|
||||
Equals(std::vector<nanoseconds_t>{8000, 12000}));
|
||||
}
|
||||
|
||||
int main(int argc, const char* argv[])
|
||||
@@ -85,5 +94,6 @@ int main(int argc, const char* argv[])
|
||||
test_read_pulses();
|
||||
test_read_indices();
|
||||
test_read_desyncs();
|
||||
test_index_marks();
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user