diff --git a/lib/decoders/fluxmapreader.cc b/lib/decoders/fluxmapreader.cc index 09b512ec..5767b1e8 100644 --- a/lib/decoders/fluxmapreader.cc +++ b/lib/decoders/fluxmapreader.cc @@ -76,6 +76,8 @@ bool FluxPattern::matches(const unsigned* end, double& clock) const { const unsigned* start = end - intervals.size(); unsigned candidatelength = std::accumulate(start, end, 0); + if (!candidatelength) + return false; clock = (double)candidatelength / (double)length; for (unsigned i=0; i #include +const FluxPattern SECTOR_ID_PATTERN(16, 0xd5aa); + static int decode_data_gcr(uint8_t gcr) { switch (gcr) @@ -118,36 +122,41 @@ uint8_t decode_side(uint8_t side) return !!(side & 0x40); } -SectorVector MacintoshDecoder::decodeToSectors( - const RawRecordVector& rawRecords, unsigned physicalTrack, unsigned physicalSide) +void MacintoshDecoder::decodeToSectors(Track& track) { - std::vector> sectors; + if (track.rawrecords || track.sectors) + Error() << "cannot decode track twice"; + track.rawrecords = std::make_unique(); + track.sectors = std::make_unique(); + + FluxmapReader fmr(*track.fluxmap); + int nextSector; int nextSide; bool headerIsValid = false; - - for (auto& rawrecord : rawRecords) + for (;;) { - const std::vector& rawdata = rawrecord->data; - const auto& rawbytes = toBytes(rawdata); + nanoseconds_t clockPeriod = fmr.seekToPattern(SECTOR_ID_PATTERN); + if (fmr.eof() || !clockPeriod) + break; - if (rawbytes.size() < 8) - continue; - - uint32_t signature = rawbytes.reader().read_be24(); - switch (signature) + auto idfield = toBytes(fmr.readRawBits(24, clockPeriod)).slice(0, 3).reader().read_be24(); + switch (idfield) { case MAC_SECTOR_RECORD: { - unsigned track = decode_data_gcr(rawbytes[3]); - if (track != (physicalTrack & 0x3f)) + auto header = toBytes(fmr.readRawBits(7*8, clockPeriod)) + .slice(0, 7); + + unsigned trackid = decode_data_gcr(header[0]); + if (trackid != (track.physicalTrack & 0x3f)) break; - nextSector = decode_data_gcr(rawbytes[4]); - nextSide = decode_data_gcr(rawbytes[5]); - uint8_t formatByte = decode_data_gcr(rawbytes[6]); - uint8_t wantedsum = decode_data_gcr(rawbytes[7]); + nextSector = decode_data_gcr(header[1]); + nextSide = decode_data_gcr(header[2]); + uint8_t formatByte = decode_data_gcr(header[3]); + uint8_t wantedsum = decode_data_gcr(header[4]); - uint8_t gotsum = (track ^ nextSector ^ nextSide ^ formatByte) & 0x3f; + uint8_t gotsum = (trackid ^ nextSector ^ nextSide ^ formatByte) & 0x3f; headerIsValid = (wantedsum == gotsum); break; } @@ -158,34 +167,22 @@ SectorVector MacintoshDecoder::decodeToSectors( break; headerIsValid = false; - Bytes inputbuffer(MAC_ENCODED_SECTOR_LENGTH + 4); + fmr.readRawBits(8, clockPeriod); /* skip spare byte */ + auto inputbuffer = toBytes(fmr.readRawBits(MAC_ENCODED_SECTOR_LENGTH*8, clockPeriod)) + .slice(0, MAC_ENCODED_SECTOR_LENGTH); + for (unsigned i=0; i rawbytes.end()) - break; - - inputbuffer[i] = decode_data_gcr(*p); - } + inputbuffer[i] = decode_data_gcr(inputbuffer[i]); int status = Sector::BAD_CHECKSUM; auto data = decode_crazy_data(inputbuffer, status); auto sector = std::unique_ptr( - new Sector(status, physicalTrack, decode_side(nextSide), nextSector, data)); - sectors.push_back(std::move(sector)); + new Sector(status, track.physicalTrack, decode_side(nextSide), nextSector, data)); + sector->clock = clockPeriod; + track.sectors->push_back(std::move(sector)); break; } } - } - - return sectors; -} - -int MacintoshDecoder::recordMatcher(uint64_t fifo) const -{ - uint32_t masked = fifo & 0xffffff; - if ((masked == MAC_SECTOR_RECORD) || (masked == MAC_DATA_RECORD)) - return 24; - return 0; + } } diff --git a/lib/macintosh/macintosh.h b/lib/macintosh/macintosh.h index 57ccc033..61920de2 100644 --- a/lib/macintosh/macintosh.h +++ b/lib/macintosh/macintosh.h @@ -5,18 +5,17 @@ #define MAC_DATA_RECORD 0xd5aaad #define MAC_SECTOR_LENGTH 524 /* yes, really */ -#define MAC_ENCODED_SECTOR_LENGTH 700 +#define MAC_ENCODED_SECTOR_LENGTH 703 class Sector; class Fluxmap; -class MacintoshDecoder : public AbstractSoftSectorDecoder +class MacintoshDecoder : public AbstractStatefulDecoder { public: virtual ~MacintoshDecoder() {} - SectorVector decodeToSectors(const RawRecordVector& rawRecords, unsigned physicalTrack, unsigned physicalSide); - int recordMatcher(uint64_t fifo) const; + void decodeToSectors(Track& track) override; }; #endif diff --git a/lib/reader.cc b/lib/reader.cc index 6d540b53..172964b4 100644 --- a/lib/reader.cc +++ b/lib/reader.cc @@ -159,7 +159,7 @@ void readDiskCommand(AbstractDecoder& decoder, const std::string& outputFilename track->rawrecords->size(), track->sectors->size()); if (track->sectors->size() > 0) - std::cout << fmt::format("{:.2}us clock; ", + std::cout << fmt::format("{:.2f}us clock; ", track->sectors->begin()->get()->clock / 1000.0); for (auto& sector : *track->sectors)