mirror of
https://github.com/davidgiven/fluxengine.git
synced 2025-10-31 11:17:01 -07:00
Improve handling of Brother bad sectors. Add the sector visualisation.
This commit is contained in:
43
lib/image.cc
43
lib/image.cc
@@ -21,6 +21,49 @@ void writeSectorsToFile(const std::vector<std::unique_ptr<Sector>>& sectors, con
|
||||
sectorSize = std::max(sector->data.size(), sectorSize);
|
||||
}
|
||||
|
||||
/* Create the index. */
|
||||
|
||||
Sector* index[trackCount][sideCount][sectorCount] = {};
|
||||
for (auto& sector : sectors)
|
||||
index[sector->track][sector->side][sector->sector] = sector.get();
|
||||
|
||||
/* Emit the map. */
|
||||
|
||||
int badSectors = 0;
|
||||
int missingSectors = 0;
|
||||
int totalSectors = 0;
|
||||
for (int side = 0; side < sideCount; side++)
|
||||
{
|
||||
for (int sectorId = 0; sectorId < sectorCount; sectorId++)
|
||||
{
|
||||
std::cout <<
|
||||
for (int track = 0; track < trackCount; track++)
|
||||
{
|
||||
Sector* sector = index[track][side][sectorId];
|
||||
if (!sector)
|
||||
{
|
||||
std::cout << '.';
|
||||
missingSectors++;
|
||||
}
|
||||
else if (sector->status == Sector::OK)
|
||||
std::cout << 'G';
|
||||
else
|
||||
{
|
||||
badSectors++;
|
||||
std::cout << 'B';
|
||||
}
|
||||
totalSectors++;
|
||||
}
|
||||
std::cout << std::endl;
|
||||
}
|
||||
}
|
||||
std::cout << "Missing sectors: " << missingSectors << "/" << totalSectors
|
||||
<< " (" << (100*missingSectors/totalSectors) << "%)"
|
||||
<< std::endl;
|
||||
std::cout << "Bad sectors: " << badSectors << "/" << totalSectors
|
||||
<< " (" << (100*badSectors/totalSectors) << "%)"
|
||||
<< std::endl;
|
||||
|
||||
size_t sideSize = sectorCount * sectorSize;
|
||||
size_t trackSize = sideSize * sideCount;
|
||||
|
||||
|
||||
@@ -30,6 +30,8 @@ public:
|
||||
const std::vector<uint8_t> data;
|
||||
};
|
||||
|
||||
extern void writeSectorsToFile(const std::vector<std::unique_ptr<Sector>>& sectors, const std::string& filename);
|
||||
extern void writeSectorsToFile(
|
||||
const std::vector<std::unique_ptr<Sector>>& sectors,
|
||||
const std::string& filename);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -16,7 +16,13 @@ static SettableFlag dumpRecords(
|
||||
{ "--dump-records" },
|
||||
"Dump the parsed records.");
|
||||
|
||||
static IntFlag retries(
|
||||
{ "--retries" },
|
||||
"How many times to retry each track in the event of a read failure.",
|
||||
5);
|
||||
|
||||
#define SECTOR_COUNT 12
|
||||
#define TRACK_COUNT 78
|
||||
|
||||
int main(int argc, const char* argv[])
|
||||
{
|
||||
@@ -27,56 +33,75 @@ int main(int argc, const char* argv[])
|
||||
std::vector<std::unique_ptr<Sector>> allSectors;
|
||||
for (auto& track : readTracks())
|
||||
{
|
||||
int retries = 5;
|
||||
retry:
|
||||
Fluxmap& fluxmap = track->read();
|
||||
|
||||
nanoseconds_t clockPeriod = fluxmap.guessClock();
|
||||
std::cout << fmt::format(" {:.1f} us clock; ", (double)clockPeriod/1000.0) << std::flush;
|
||||
|
||||
auto bitmap = decodeFluxmapToBits(fluxmap, clockPeriod);
|
||||
std::cout << fmt::format("{} bytes encoded; ", bitmap.size()/8) << std::flush;
|
||||
|
||||
auto records = decodeBitsToRecordsBrother(bitmap);
|
||||
std::cout << records.size() << " records." << std::endl;
|
||||
|
||||
auto sectors = parseRecordsToSectorsBrother(records);
|
||||
std::cout << " " << sectors.size() << " sectors; ";
|
||||
|
||||
std::vector<std::unique_ptr<Sector>> goodSectors(SECTOR_COUNT);
|
||||
for (auto& sector : sectors)
|
||||
std::map<int, std::unique_ptr<Sector>> readSectors;
|
||||
for (int retry = ::retries; retry >= 0; retry--)
|
||||
{
|
||||
if (sector->status == Sector::OK)
|
||||
goodSectors.at(sector->sector) = std::move(sector);
|
||||
}
|
||||
Fluxmap& fluxmap = track->read();
|
||||
|
||||
bool hasBadSectors = false;
|
||||
for (int i=0; i<SECTOR_COUNT; i++)
|
||||
{
|
||||
if (!goodSectors.at(i))
|
||||
nanoseconds_t clockPeriod = fluxmap.guessClock();
|
||||
std::cout << fmt::format(" {:.1f} us clock; ", (double)clockPeriod/1000.0) << std::flush;
|
||||
|
||||
auto bitmap = decodeFluxmapToBits(fluxmap, clockPeriod);
|
||||
std::cout << fmt::format("{} bytes encoded; ", bitmap.size()/8) << std::flush;
|
||||
|
||||
auto records = decodeBitsToRecordsBrother(bitmap);
|
||||
std::cout << records.size() << " records." << std::endl;
|
||||
|
||||
auto sectors = parseRecordsToSectorsBrother(records);
|
||||
std::cout << " " << sectors.size() << " sectors; ";
|
||||
|
||||
for (auto& sector : sectors)
|
||||
{
|
||||
std::cout << std::endl
|
||||
<< " Failed to read sector " << i << "; ";
|
||||
hasBadSectors = true;
|
||||
if ((sector->sector < SECTOR_COUNT) && (sector->track < TRACK_COUNT))
|
||||
{
|
||||
auto& replacing = readSectors[sector->sector];
|
||||
if (sector->status == Sector::OK)
|
||||
replacing = std::move(sector);
|
||||
else
|
||||
{
|
||||
if (!replacing || (replacing->status == Sector::OK))
|
||||
replacing = std::move(sector);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (hasBadSectors)
|
||||
{
|
||||
if (retries == 0)
|
||||
failures = true;
|
||||
else
|
||||
|
||||
bool hasBadSectors = false;
|
||||
for (int i=0; i<SECTOR_COUNT; i++)
|
||||
{
|
||||
std::cout << std::endl
|
||||
<< " " << retries << " retries remaining" << std::endl;
|
||||
retries--;
|
||||
track->forceReread();
|
||||
goto retry;
|
||||
auto& sector = readSectors[i];
|
||||
if (!sector || (sector->status != Sector::OK))
|
||||
{
|
||||
std::cout << std::endl
|
||||
<< " Failed to read sector " << i << "; ";
|
||||
hasBadSectors = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (hasBadSectors)
|
||||
failures = false;
|
||||
|
||||
if (dumpRecords && (!hasBadSectors || (retry == 0)))
|
||||
{
|
||||
std::cout << "\nRaw records follow:\n\n";
|
||||
for (auto& record : records)
|
||||
{
|
||||
hexdump(std::cout, record);
|
||||
std::cout << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
if (!hasBadSectors)
|
||||
break;
|
||||
|
||||
std::cout << std::endl
|
||||
<< " " << retry << " retries remaining" << std::endl;
|
||||
track->forceReread();
|
||||
}
|
||||
|
||||
int size = 0;
|
||||
for (auto& sector : goodSectors)
|
||||
{
|
||||
for (int sectorId = 0; sectorId < SECTOR_COUNT; sectorId++)
|
||||
{
|
||||
auto& sector = readSectors[sectorId];
|
||||
if (sector)
|
||||
{
|
||||
size += sector->data.size();
|
||||
@@ -85,15 +110,6 @@ int main(int argc, const char* argv[])
|
||||
}
|
||||
std::cout << size << " bytes decoded." << std::endl;
|
||||
|
||||
if (dumpRecords)
|
||||
{
|
||||
std::cout << "\nRaw records follow:\n\n";
|
||||
for (auto& record : records)
|
||||
{
|
||||
hexdump(std::cout, record);
|
||||
std::cout << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
writeSectorsToFile(allSectors, outputFilename);
|
||||
|
||||
Reference in New Issue
Block a user