Merge from master.

This commit is contained in:
David Given
2021-12-08 19:39:59 +01:00
10 changed files with 55 additions and 25 deletions

View File

@@ -133,11 +133,17 @@ public:
encodeMfm(_bits, _cursor, bytes, _lastBit);
};
auto writeFillerRawBytes = [&](int count, uint16_t byte)
{
for (int i=0; i<count; i++)
writeRawBits(byte, 16);
};
auto writeFillerBytes = [&](int count, uint8_t byte)
{
Bytes bytes = { byte };
Bytes b { byte };
for (int i=0; i<count; i++)
writeBytes(bytes);
writeBytes(b);
};
double clockRateUs = 1e3 / trackdata.clock_rate_khz();
@@ -160,9 +166,9 @@ public:
}
}
uint8_t gapFill = trackdata.use_fm() ? 0x00 : 0x4e;
uint16_t gapFill = trackdata.gap_fill_byte();
writeFillerBytes(trackdata.gap0(), gapFill);
writeFillerRawBytes(trackdata.gap0(), gapFill);
if (trackdata.emit_iam())
{
writeFillerBytes(trackdata.use_fm() ? 6 : 12, 0x00);
@@ -172,7 +178,7 @@ public:
writeRawBits(MFM_IAM_SEPARATOR, 16);
}
writeRawBits(trackdata.use_fm() ? FM_IAM_RECORD : MFM_IAM_RECORD, 16);
writeFillerBytes(trackdata.gap1(), gapFill);
writeFillerRawBytes(trackdata.gap1(), gapFill);
}
int logicalSide = physicalSide ^ trackdata.swap_sides();
@@ -180,7 +186,7 @@ public:
for (int sectorId : trackdata.sectors().sector())
{
if (!first)
writeFillerBytes(trackdata.gap3(), gapFill);
writeFillerRawBytes(trackdata.gap3(), gapFill);
first = false;
const auto& sectorData = image.get(physicalTrack, logicalSide, sectorId);
@@ -227,7 +233,7 @@ public:
writeBytes(header.slice(conventionalHeaderStart));
}
writeFillerBytes(trackdata.gap2(), gapFill);
writeFillerRawBytes(trackdata.gap2(), gapFill);
{
Bytes data;
@@ -264,7 +270,7 @@ public:
if (_cursor >= _bits.size())
Error() << "track data overrun";
while (_cursor < _bits.size())
writeFillerBytes(1, gapFill);
writeFillerRawBytes(1, gapFill);
std::unique_ptr<Fluxmap> fluxmap(new Fluxmap);
fluxmap->appendBits(_bits, clockRateUs*1e3);

View File

@@ -15,7 +15,7 @@ message IbmDecoderProto {
}
message IbmEncoderProto {
// Next: 18
// Next: 19
message TrackdataProto {
message SectorsProto {
repeated int32 sector = 1 [(help) = "write these sectors (in order) on each track"];
@@ -37,6 +37,7 @@ message IbmEncoderProto {
optional int32 gap3 = 12 [default=80, (help) = "size of gap 4 (the post-data or format gap)"];
optional bool swap_sides = 14 [default=false, (help) = "swap side bytes when writing"];
optional SectorsProto sectors = 17 [(help) = "write these sectors (in order) on each track"];
optional int32 gap_fill_byte = 18 [default=0x9254, (help) = "16-bit raw bit pattern of gap fill byte"];
}
repeated TrackdataProto trackdata = 1;

View File

@@ -37,7 +37,6 @@ public:
const FluxMatcher* matcher = nullptr;
_sector->clock = _fmr->seekToPattern(SECTOR_SYNC_PATTERN, matcher);
if (matcher == &SECTOR_SYNC_PATTERN) {
readRawBits(16);
return SECTOR_RECORD;
}
return UNKNOWN_RECORD;
@@ -45,6 +44,7 @@ public:
void decodeSectorRecord()
{
readRawBits(16);
auto rawbits = readRawBits(MICROPOLIS_ENCODED_SECTOR_SIZE*16);
auto bytes = decodeFmMfm(rawbits).slice(0, MICROPOLIS_ENCODED_SECTOR_SIZE);
ByteReader br(bytes);

View File

@@ -127,13 +127,11 @@ public:
if (matcher == &MFM_PATTERN) {
_sectorType = SECTOR_TYPE_MFM;
readRawBits(48);
return SECTOR_RECORD;
}
if (matcher == &FM_PATTERN) {
_sectorType = SECTOR_TYPE_FM;
readRawBits(48);
return SECTOR_RECORD;
}
@@ -155,6 +153,8 @@ public:
headerSize = NORTHSTAR_HEADER_SIZE_SD;
}
readRawBits(48);
auto rawbits = readRawBits(recordSize * 16);
auto bytes = decodeFmMfm(rawbits).slice(0, recordSize);
ByteReader br(bytes);

View File

@@ -93,3 +93,18 @@ void Fluxmap::precompensate(int threshold_ticks, int amount_ticks)
}
}
}
std::vector<Fluxmap> Fluxmap::split() {
std::vector<Fluxmap> maps;
Fluxmap map;
for (unsigned i=0; i<_bytes.size(); i++) {
if (_bytes[i] == F_DESYNC) {
maps.push_back(map);
map = Fluxmap();
} else {
map.appendByte(_bytes[i]);
}
}
maps.push_back(map);
return maps;
}

View File

@@ -58,7 +58,8 @@ public:
Fluxmap& appendBits(const std::vector<bool>& bits, nanoseconds_t clock);
void precompensate(int threshold_ticks, int amount_ticks);
void precompensate(int threshold_ticks, int amount_ticks);
std::vector<Fluxmap> split();
private:
uint8_t& findLastByte();

View File

@@ -92,7 +92,9 @@ public:
trackheader.header.track_id[2] = 'K';
trackheader.header.strack = strack;
FluxmapReader fmr(fluxmap);
auto lastFluxmap = fluxmap.split().back();
FluxmapReader fmr(lastFluxmap);
Bytes fluxdata;
ByteWriter fluxdataWriter(fluxdata);

View File

@@ -40,7 +40,6 @@ public:
ByteReader headerReader(header);
// media flag indicates media density, currently unused
char mediaFlag = headerReader.seek(0x1b).read_8();
inputFile.seekg( 0, std::ios::end );
@@ -59,13 +58,22 @@ public:
inputFile.read((char*) trackTable.begin(), trackTable.size());
ByteReader trackTableReader(trackTable);
int diskSectorsPerTrack = -1;
if (config.encoder().format_case() != EncoderProto::FormatCase::FORMAT_NOT_SET)
std::cout << "D88: overriding configured format";
auto ibm = config.mutable_encoder()->mutable_ibm();
config.mutable_cylinders()->set_end(0);
if (mediaFlag == 0x20) {
std::cout << "D88: high density mode\n";
if (config.flux_sink().dest_case() == FluxSinkProto::DestCase::kDrive) {
config.mutable_flux_sink()->mutable_drive()->set_high_density(true);
}
} else {
std::cout << "D88: single/double density mode\n";
if (config.flux_sink().dest_case() == FluxSinkProto::DestCase::kDrive) {
config.mutable_flux_sink()->mutable_drive()->set_high_density(false);
}
}
std::unique_ptr<Image> image(new Image);
for (int track = 0; track < trackTableSize / 4; track++)
@@ -109,11 +117,6 @@ public:
} else if (currentSectorsInTrack != sectorsInTrack) {
Error() << "D88: mismatched number of sectors in track";
}
if (diskSectorsPerTrack < 0) {
diskSectorsPerTrack = sectorsInTrack;
} else if (diskSectorsPerTrack != sectorsInTrack) {
Error() << "D88: varying numbers of sectors per track is currently unsupported";
}
if (currentTrackCylinder < 0) {
currentTrackCylinder = cylinder;
} else if (currentTrackCylinder != cylinder) {
@@ -127,7 +130,7 @@ public:
trackdata->set_sector_size(sectorSize);
trackdata->set_use_fm(fm);
if (fm) {
//trackdata->set_clock_rate_khz(250*300/360);
trackdata->set_gap_fill_byte(0xffff);
trackdata->set_idam_byte(0xf57e);
trackdata->set_dam_byte(0xf56f);
}

View File

@@ -33,7 +33,7 @@ public:
std::cout << fmt::format("Writing {} cylinders, {} sides, {} sectors, {} ({} bytes/sector), {} kB total",
geometry.numTracks, geometry.numSides,
geometry.numSectors, geometry.sectorSize == 256 ? "SD" : "DD", geometry.sectorSize,
geometry.numTracks * geometry.sectorSize / 1024)
geometry.numTracks * geometry.numSides * geometry.numSectors * geometry.sectorSize / 1024)
<< std::endl;
std::ofstream outputFile(_config.filename(), std::ios::out | std::ios::binary);

View File

@@ -141,11 +141,13 @@ void setProtoFieldFromString(ProtoField& protoField, const std::string& value)
static const std::map<std::string, bool> boolvalues = {
{ "false", false },
{ "f", false },
{ "no", false },
{ "n", false },
{ "0", false },
{ "true", true },
{ "t", true },
{ "n", true },
{ "yes", true },
{ "y", true },
{ "1", true },
};