Added the SectorSet class for holding collections of Sector objects --- much

easier to deal with than ad-hoc maps.
This commit is contained in:
David Given
2018-12-28 00:43:47 +01:00
parent 3e60d37c44
commit 490e649942
7 changed files with 109 additions and 43 deletions

View File

@@ -1,46 +1,33 @@
#include "globals.h"
#include "image.h"
#include "sectorset.h"
#include "fmt/format.h"
#include <algorithm>
#include <iostream>
#include <fstream>
void writeSectorsToFile(const std::vector<std::unique_ptr<Sector>>& sectors, const std::string& filename)
void writeSectorsToFile(const SectorSet& sectors, const std::string& filename)
{
/* Count the tracks, sides and sectors. */
int trackCount = 0;
int sideCount = 0;
int sectorCount = 0;
size_t sectorSize = 0;
for (auto& sector : sectors)
{
trackCount = std::max(sector->track+1, trackCount);
sideCount = std::max(sector->side+1, sideCount);
sectorCount = std::max(sector->sector+1, sectorCount);
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 numTracks;
int numHeads;
int numSectors;
int sectorSize;
sectors.calculateSize(numTracks, numHeads, numSectors, sectorSize);
int badSectors = 0;
int missingSectors = 0;
int totalSectors = 0;
std::cout << "H.SS Tracks --->" << std::endl;
for (int side = 0; side < sideCount; side++)
for (int head = 0; head < numHeads; head++)
{
for (int sectorId = 0; sectorId < sectorCount; sectorId++)
for (int sectorId = 0; sectorId < numSectors; sectorId++)
{
std::cout << fmt::format("{}.{:2} ", side, sectorId);
for (int track = 0; track < trackCount; track++)
std::cout << fmt::format("{}.{:2} ", head, sectorId);
for (int track = 0; track < numTracks; track++)
{
Sector* sector = index[track][side][sectorId];
auto sector = sectors[{track, head, sectorId}];
if (!sector)
{
std::cout << '.';
@@ -74,21 +61,31 @@ void writeSectorsToFile(const std::vector<std::unique_ptr<Sector>>& sectors, con
<< std::endl;
}
size_t sideSize = sectorCount * sectorSize;
size_t trackSize = sideSize * sideCount;
size_t headSize = numSectors * sectorSize;
size_t trackSize = headSize * numHeads;
std::cout << fmt::format("{} tracks, {} sides, {} sectors, {} bytes per sector, {} kB total",
trackCount, sideCount, sectorCount, sectorSize,
trackCount * sideCount * sectorCount * sectorSize / 1024)
std::cout << fmt::format("{} tracks, {} heads, {} sectors, {} bytes per sector, {} kB total",
numTracks, numHeads, numSectors, sectorSize,
numTracks * trackSize / 1024)
<< std::endl;
std::ofstream outputFile(filename, std::ios::out | std::ios::binary);
if (!outputFile.is_open())
Error() << "cannot open output file";
Error() << "cannot open output file";
for (auto& sector : sectors)
{
outputFile.seekp(sector->track*trackSize + sector->side*sideSize + sector->sector*sectorSize, std::ios::beg);
outputFile.write((const char*) &sector->data[0], sector->data.size());
}
for (int track = 0; track < numTracks; track++)
{
for (int head = 0; head < numHeads; head++)
{
for (int sectorId = 0; sectorId < numSectors; sectorId++)
{
auto sector = sectors[{track, head, sectorId}];
if (sector)
{
outputFile.seekp(sector->track*trackSize + sector->side*headSize + sector->sector*sectorSize, std::ios::beg);
outputFile.write((const char*) &sector->data[0], sector->data.size());
}
}
}
}
}

View File

@@ -30,8 +30,10 @@ public:
const std::vector<uint8_t> data;
};
class SectorSet;
extern void writeSectorsToFile(
const std::vector<std::unique_ptr<Sector>>& sectors,
const SectorSet& sectors,
const std::string& filename);
#endif

36
lib/sectorset.cc Normal file
View File

@@ -0,0 +1,36 @@
#include "globals.h"
#include "image.h"
#include "sectorset.h"
std::unique_ptr<Sector>& SectorSet::operator[](const key_t& key)
{
return _data[key];
}
Sector* SectorSet::operator[](const key_t& key) const
{
auto i = _data.find(key);
if (i == _data.end())
return NULL;
return i->second.get();
}
void SectorSet::calculateSize(int& numTracks, int& numHeads, int& numSectors,
int& sectorSize) const
{
numTracks = numHeads = numSectors = sectorSize = 0;
for (auto& i : _data)
{
auto& sector = i.second;
if (sector)
{
numTracks = std::max(numTracks, sector->track+1);
numHeads = std::max(numHeads, sector->side+1);
numSectors = std::max(numSectors, sector->sector+1);
sectorSize = std::max(sectorSize, (int)sector->data.size());
}
}
}

27
lib/sectorset.h Normal file
View File

@@ -0,0 +1,27 @@
#ifndef SECTORSET_H
#define SECTORSET_H
class Sector;
class SectorSet
{
private:
typedef std::tuple<int, int, int> key_t;
public:
static key_t keyof(int track, int head, int sector)
{ return std::tuple<int, int, int>(track, head, sector); }
SectorSet() {};
std::unique_ptr<Sector>& operator[](const key_t& key);
Sector* operator[](const key_t& key) const;
void calculateSize(int& numTracks, int& numHeads, int& numSectors,
int& sectorSize) const;
private:
std::map<const key_t, std::unique_ptr<Sector>> _data;
};
#endif

View File

@@ -40,6 +40,7 @@ felib = shared_library('felib',
'lib/image.cc',
'lib/crc.cc',
'lib/hexdump.cc',
'lib/sectorset.cc',
],
include_directories: [fmtinc],
link_with: [fmtlib],

View File

@@ -4,6 +4,7 @@
#include "fluxmap.h"
#include "decoders.h"
#include "brother.h"
#include "sectorset.h"
#include "image.h"
#include <fmt/format.h>
#include <fstream>
@@ -31,7 +32,7 @@ int main(int argc, const char* argv[])
Flag::parseFlags(argc, argv);
bool failures = false;
std::vector<std::unique_ptr<Sector>> allSectors;
SectorSet allSectors;
for (auto& track : readTracks())
{
std::map<int, std::unique_ptr<Sector>> readSectors;
@@ -108,12 +109,12 @@ int main(int argc, const char* argv[])
{
if (!printedTrack)
{
std::cout << " logical track " << sector->track << "; ";
std::cout << "logical track " << sector->track << "; ";
printedTrack = true;
}
size += sector->data.size();
allSectors.push_back(std::move(sector));
allSectors[{sector->track, 0, sector->sector}] = std::move(sector);
}
}
std::cout << size << " bytes decoded." << std::endl;

View File

@@ -4,6 +4,7 @@
#include "fluxmap.h"
#include "decoders.h"
#include "image.h"
#include "sectorset.h"
#include <fmt/format.h>
static StringFlag outputFilename(
@@ -20,7 +21,7 @@ int main(int argc, const char* argv[])
Flag::parseFlags(argc, argv);
bool failures = false;
std::vector<std::unique_ptr<Sector>> allSectors;
SectorSet allSectors;
for (auto& track : readTracks())
{
int retries = 5;
@@ -67,7 +68,8 @@ int main(int argc, const char* argv[])
for (auto& sector : sectors)
{
size += sector->data.size();
allSectors.push_back(std::move(sector));
allSectors[{sector->track, sector->side, sector->sector}] =
std::move(sector);
}
std::cout << size << " bytes decoded." << std::endl;