mirror of
https://github.com/davidgiven/fluxengine.git
synced 2025-10-31 11:17:01 -07:00
Convert the Macintosh decoder.
This commit is contained in:
@@ -184,5 +184,3 @@ std::unique_ptr<AbstractDecoder> createIbmDecoder(const DecoderProto& config)
|
||||
return std::unique_ptr<AbstractDecoder>(new IbmDecoder(config));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -124,85 +124,98 @@ uint8_t decode_side(uint8_t side)
|
||||
return !!(side & 0x20);
|
||||
}
|
||||
|
||||
AbstractDecoder::RecordType MacintoshDecoder::advanceToNextRecord()
|
||||
class MacintoshDecoder : public AbstractDecoder
|
||||
{
|
||||
const FluxMatcher* matcher = nullptr;
|
||||
_sector->clock = _fmr->seekToPattern(ANY_RECORD_PATTERN, matcher);
|
||||
if (matcher == &SECTOR_RECORD_PATTERN)
|
||||
return SECTOR_RECORD;
|
||||
if (matcher == &DATA_RECORD_PATTERN)
|
||||
return DATA_RECORD;
|
||||
return UNKNOWN_RECORD;
|
||||
}
|
||||
public:
|
||||
MacintoshDecoder(const DecoderProto& config):
|
||||
AbstractDecoder(config)
|
||||
{}
|
||||
|
||||
void MacintoshDecoder::decodeSectorRecord()
|
||||
RecordType advanceToNextRecord()
|
||||
{
|
||||
const FluxMatcher* matcher = nullptr;
|
||||
_sector->clock = _fmr->seekToPattern(ANY_RECORD_PATTERN, matcher);
|
||||
if (matcher == &SECTOR_RECORD_PATTERN)
|
||||
return SECTOR_RECORD;
|
||||
if (matcher == &DATA_RECORD_PATTERN)
|
||||
return DATA_RECORD;
|
||||
return UNKNOWN_RECORD;
|
||||
}
|
||||
|
||||
void decodeSectorRecord()
|
||||
{
|
||||
/* Skip ID (as we know it's a MAC_SECTOR_RECORD). */
|
||||
readRawBits(24);
|
||||
|
||||
/* Read header. */
|
||||
|
||||
auto header = toBytes(readRawBits(7*8)).slice(0, 7);
|
||||
|
||||
uint8_t encodedTrack = decode_data_gcr(header[0]);
|
||||
if (encodedTrack != (_track->physicalTrack & 0x3f))
|
||||
return;
|
||||
|
||||
uint8_t encodedSector = decode_data_gcr(header[1]);
|
||||
uint8_t encodedSide = decode_data_gcr(header[2]);
|
||||
uint8_t formatByte = decode_data_gcr(header[3]);
|
||||
uint8_t wantedsum = decode_data_gcr(header[4]);
|
||||
|
||||
if (encodedSector > 11)
|
||||
return;
|
||||
|
||||
_sector->logicalTrack = _track->physicalTrack;
|
||||
_sector->logicalSide = decode_side(encodedSide);
|
||||
_sector->logicalSector = encodedSector;
|
||||
uint8_t gotsum = (encodedTrack ^ encodedSector ^ encodedSide ^ formatByte) & 0x3f;
|
||||
if (wantedsum == gotsum)
|
||||
_sector->status = Sector::DATA_MISSING; /* unintuitive but correct */
|
||||
}
|
||||
|
||||
void decodeDataRecord()
|
||||
{
|
||||
auto id = toBytes(readRawBits(24)).reader().read_be24();
|
||||
if (id != MAC_DATA_RECORD)
|
||||
return;
|
||||
|
||||
/* Read data. */
|
||||
|
||||
readRawBits(8); /* skip spare byte */
|
||||
auto inputbuffer = toBytes(readRawBits(MAC_ENCODED_SECTOR_LENGTH*8))
|
||||
.slice(0, MAC_ENCODED_SECTOR_LENGTH);
|
||||
|
||||
for (unsigned i=0; i<inputbuffer.size(); i++)
|
||||
inputbuffer[i] = decode_data_gcr(inputbuffer[i]);
|
||||
|
||||
_sector->status = Sector::BAD_CHECKSUM;
|
||||
Bytes userData = decode_crazy_data(inputbuffer, _sector->status);
|
||||
_sector->data.clear();
|
||||
_sector->data.writer().append(userData.slice(12, 512)).append(userData.slice(0, 12));
|
||||
}
|
||||
|
||||
std::set<unsigned> requiredSectors(Track& track) const
|
||||
{
|
||||
int count;
|
||||
if (track.physicalTrack < 16)
|
||||
count = 12;
|
||||
else if (track.physicalTrack < 32)
|
||||
count = 11;
|
||||
else if (track.physicalTrack < 48)
|
||||
count = 10;
|
||||
else if (track.physicalTrack < 64)
|
||||
count = 9;
|
||||
else
|
||||
count = 8;
|
||||
|
||||
std::set<unsigned> sectors;
|
||||
while (count--)
|
||||
sectors.insert(count);
|
||||
return sectors;
|
||||
}
|
||||
};
|
||||
|
||||
std::unique_ptr<AbstractDecoder> createMacintoshDecoder(const DecoderProto& config)
|
||||
{
|
||||
/* Skip ID (as we know it's a MAC_SECTOR_RECORD). */
|
||||
readRawBits(24);
|
||||
|
||||
/* Read header. */
|
||||
|
||||
auto header = toBytes(readRawBits(7*8)).slice(0, 7);
|
||||
|
||||
uint8_t encodedTrack = decode_data_gcr(header[0]);
|
||||
if (encodedTrack != (_track->physicalTrack & 0x3f))
|
||||
return;
|
||||
|
||||
uint8_t encodedSector = decode_data_gcr(header[1]);
|
||||
uint8_t encodedSide = decode_data_gcr(header[2]);
|
||||
uint8_t formatByte = decode_data_gcr(header[3]);
|
||||
uint8_t wantedsum = decode_data_gcr(header[4]);
|
||||
|
||||
if (encodedSector > 11)
|
||||
return;
|
||||
|
||||
_sector->logicalTrack = _track->physicalTrack;
|
||||
_sector->logicalSide = decode_side(encodedSide);
|
||||
_sector->logicalSector = encodedSector;
|
||||
uint8_t gotsum = (encodedTrack ^ encodedSector ^ encodedSide ^ formatByte) & 0x3f;
|
||||
if (wantedsum == gotsum)
|
||||
_sector->status = Sector::DATA_MISSING; /* unintuitive but correct */
|
||||
}
|
||||
|
||||
void MacintoshDecoder::decodeDataRecord()
|
||||
{
|
||||
auto id = toBytes(readRawBits(24)).reader().read_be24();
|
||||
if (id != MAC_DATA_RECORD)
|
||||
return;
|
||||
|
||||
/* Read data. */
|
||||
|
||||
readRawBits(8); /* skip spare byte */
|
||||
auto inputbuffer = toBytes(readRawBits(MAC_ENCODED_SECTOR_LENGTH*8))
|
||||
.slice(0, MAC_ENCODED_SECTOR_LENGTH);
|
||||
|
||||
for (unsigned i=0; i<inputbuffer.size(); i++)
|
||||
inputbuffer[i] = decode_data_gcr(inputbuffer[i]);
|
||||
|
||||
_sector->status = Sector::BAD_CHECKSUM;
|
||||
Bytes userData = decode_crazy_data(inputbuffer, _sector->status);
|
||||
_sector->data.clear();
|
||||
_sector->data.writer().append(userData.slice(12, 512)).append(userData.slice(0, 12));
|
||||
}
|
||||
|
||||
std::set<unsigned> MacintoshDecoder::requiredSectors(Track& track) const
|
||||
{
|
||||
int count;
|
||||
if (track.physicalTrack < 16)
|
||||
count = 12;
|
||||
else if (track.physicalTrack < 32)
|
||||
count = 11;
|
||||
else if (track.physicalTrack < 48)
|
||||
count = 10;
|
||||
else if (track.physicalTrack < 64)
|
||||
count = 9;
|
||||
else
|
||||
count = 8;
|
||||
|
||||
std::set<unsigned> sectors;
|
||||
while (count--)
|
||||
sectors.insert(count);
|
||||
return sectors;
|
||||
return std::unique_ptr<AbstractDecoder>(new MacintoshDecoder(config));
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -18,19 +18,6 @@ class Fluxmap;
|
||||
class MacintoshDecoderProto;
|
||||
class MacintoshEncoderProto;
|
||||
|
||||
class MacintoshDecoder : public AbstractDecoder
|
||||
{
|
||||
public:
|
||||
MacintoshDecoder(const MacintoshDecoderProto&) {}
|
||||
virtual ~MacintoshDecoder() {}
|
||||
|
||||
RecordType advanceToNextRecord();
|
||||
void decodeSectorRecord();
|
||||
void decodeDataRecord();
|
||||
|
||||
std::set<unsigned> requiredSectors(Track& track) const;
|
||||
};
|
||||
|
||||
class MacintoshEncoder : public AbstractEncoder
|
||||
{
|
||||
public:
|
||||
|
||||
@@ -41,6 +41,7 @@ std::unique_ptr<AbstractDecoder> AbstractDecoder::create(const DecoderProto& con
|
||||
{ DecoderProto::kF85, createDurangoF85Decoder },
|
||||
{ DecoderProto::kFb100, createFb100Decoder },
|
||||
{ DecoderProto::kIbm, createIbmDecoder },
|
||||
{ DecoderProto::kMacintosh, createMacintoshDecoder },
|
||||
};
|
||||
|
||||
auto decoder = decoders.find(config.format_case());
|
||||
@@ -55,12 +56,6 @@ std::unique_ptr<AbstractDecoder> AbstractDecoder::create(const DecoderProto& con
|
||||
{
|
||||
switch (config.format_case())
|
||||
{
|
||||
case DecoderProto::kIbm:
|
||||
return std::unique_ptr<AbstractDecoder>(new IbmDecoder(config.ibm()));
|
||||
|
||||
case DecoderProto::kMacintosh:
|
||||
return std::unique_ptr<AbstractDecoder>(new MacintoshDecoder(config.macintosh()));
|
||||
|
||||
case DecoderProto::kMicropolis:
|
||||
return std::unique_ptr<AbstractDecoder>(new MicropolisDecoder(config.micropolis()));
|
||||
|
||||
|
||||
Reference in New Issue
Block a user