Convert the MX decoder.

This commit is contained in:
David Given
2021-07-11 16:02:41 +02:00
parent e9d80423ae
commit 1bf41cbfd7
3 changed files with 67 additions and 67 deletions

View File

@@ -23,53 +23,73 @@ const int SECTOR_SIZE = 256;
*/ */
const FluxPattern ID_PATTERN(32, 0xaaaaffaf); const FluxPattern ID_PATTERN(32, 0xaaaaffaf);
void MxDecoder::beginTrack() class MxDecoder : public AbstractDecoder
{ {
_currentSector = -1; public:
_clock = 0; MxDecoder(const DecoderProto& config):
AbstractDecoder(config)
{}
void beginTrack()
{
_currentSector = -1;
_clock = 0;
}
RecordType advanceToNextRecord()
{
if (_currentSector == -1)
{
/* First sector in the track: look for the sync marker. */
const FluxMatcher* matcher = nullptr;
_sector->clock = _clock = _fmr->seekToPattern(ID_PATTERN, matcher);
readRawBits(32); /* skip the ID mark */
_logicalTrack = decodeFmMfm(readRawBits(32)).slice(0, 32).reader().read_be16();
}
else if (_currentSector == 10)
{
/* That was the last sector on the disk. */
return UNKNOWN_RECORD;
}
else
{
/* Otherwise we assume the clock from the first sector is still valid.
* The decoder framwork will automatically stop when we hit the end of
* the track. */
_sector->clock = _clock;
}
_currentSector++;
return SECTOR_RECORD;
}
void decodeSectorRecord()
{
auto bits = readRawBits((SECTOR_SIZE+2)*16);
auto bytes = decodeFmMfm(bits).slice(0, SECTOR_SIZE+2).swab();
uint16_t gotChecksum = 0;
ByteReader br(bytes);
for (int i=0; i<(SECTOR_SIZE/2); i++)
gotChecksum += br.read_le16();
uint16_t wantChecksum = br.read_le16();
_sector->logicalTrack = _logicalTrack;
_sector->logicalSide = _track->physicalSide;
_sector->logicalSector = _currentSector;
_sector->data = bytes.slice(0, SECTOR_SIZE);
_sector->status = (gotChecksum == wantChecksum) ? Sector::OK : Sector::BAD_CHECKSUM;
}
private:
nanoseconds_t _clock;
int _currentSector;
int _logicalTrack;
};
std::unique_ptr<AbstractDecoder> createMxDecoder(const DecoderProto& config)
{
return std::unique_ptr<AbstractDecoder>(new MxDecoder(config));
} }
AbstractDecoder::RecordType MxDecoder::advanceToNextRecord()
{
if (_currentSector == -1)
{
/* First sector in the track: look for the sync marker. */
const FluxMatcher* matcher = nullptr;
_sector->clock = _clock = _fmr->seekToPattern(ID_PATTERN, matcher);
readRawBits(32); /* skip the ID mark */
_logicalTrack = decodeFmMfm(readRawBits(32)).slice(0, 32).reader().read_be16();
}
else if (_currentSector == 10)
{
/* That was the last sector on the disk. */
return UNKNOWN_RECORD;
}
else
{
/* Otherwise we assume the clock from the first sector is still valid.
* The decoder framwork will automatically stop when we hit the end of
* the track. */
_sector->clock = _clock;
}
_currentSector++;
return SECTOR_RECORD;
}
void MxDecoder::decodeSectorRecord()
{
auto bits = readRawBits((SECTOR_SIZE+2)*16);
auto bytes = decodeFmMfm(bits).slice(0, SECTOR_SIZE+2).swab();
uint16_t gotChecksum = 0;
ByteReader br(bytes);
for (int i=0; i<(SECTOR_SIZE/2); i++)
gotChecksum += br.read_le16();
uint16_t wantChecksum = br.read_le16();
_sector->logicalTrack = _logicalTrack;
_sector->logicalSide = _track->physicalSide;
_sector->logicalSector = _currentSector;
_sector->data = bytes.slice(0, SECTOR_SIZE);
_sector->status = (gotChecksum == wantChecksum) ? Sector::OK : Sector::BAD_CHECKSUM;
}

View File

@@ -3,24 +3,6 @@
#include "decoders/decoders.h" #include "decoders/decoders.h"
class MxDecoderProto;
class MxDecoder : public AbstractDecoder
{
public:
MxDecoder(const MxDecoderProto&) {}
virtual ~MxDecoder() {}
void beginTrack();
RecordType advanceToNextRecord();
void decodeSectorRecord();
private:
nanoseconds_t _clock;
int _currentSector;
int _logicalTrack;
};
extern std::unique_ptr<AbstractDecoder> createMxDecoder(const DecoderProto& config); extern std::unique_ptr<AbstractDecoder> createMxDecoder(const DecoderProto& config);
#endif #endif

View File

@@ -43,6 +43,7 @@ std::unique_ptr<AbstractDecoder> AbstractDecoder::create(const DecoderProto& con
{ DecoderProto::kIbm, createIbmDecoder }, { DecoderProto::kIbm, createIbmDecoder },
{ DecoderProto::kMacintosh, createMacintoshDecoder }, { DecoderProto::kMacintosh, createMacintoshDecoder },
{ DecoderProto::kMicropolis, createMicropolisDecoder }, { DecoderProto::kMicropolis, createMicropolisDecoder },
{ DecoderProto::kMx, createMxDecoder },
}; };
auto decoder = decoders.find(config.format_case()); auto decoder = decoders.find(config.format_case());
@@ -57,9 +58,6 @@ std::unique_ptr<AbstractDecoder> AbstractDecoder::create(const DecoderProto& con
{ {
switch (config.format_case()) switch (config.format_case())
{ {
case DecoderProto::kMx:
return std::unique_ptr<AbstractDecoder>(new MxDecoder(config.mx()));
case DecoderProto::kTids990: case DecoderProto::kTids990:
return std::unique_ptr<AbstractDecoder>(new Tids990Decoder(config.tids990())); return std::unique_ptr<AbstractDecoder>(new Tids990Decoder(config.tids990()));