| 60 | |
| 61 | public: |
| 62 | std::unique_ptr<Fluxmap> encode(const LogicalTrackLayout& ltl, |
| 63 | const std::vector<std::shared_ptr<const Sector>>& sectors, |
| 64 | const Image& image) override |
| 65 | { |
| 66 | double clockRateUs = _config.clock_period_us() / 2.0; |
| 67 | int bitsPerRevolution = |
| 68 | (_config.rotational_period_ms() * 1000.0) / clockRateUs; |
| 69 | _bits.resize(bitsPerRevolution); |
| 70 | _cursor = 0; |
| 71 | |
| 72 | uint8_t am1Unencoded = decodeUint16(_config.am1_byte()); |
| 73 | uint8_t am2Unencoded = decodeUint16(_config.am2_byte()); |
| 74 | |
| 75 | writeBytes(_config.gap1_bytes(), 0x55); |
| 76 | |
| 77 | bool first = true; |
| 78 | for (const auto& sectorData : sectors) |
| 79 | { |
| 80 | if (!first) |
| 81 | writeBytes(_config.gap3_bytes(), 0x55); |
| 82 | first = false; |
| 83 | |
| 84 | /* Writing the sector and data records are fantastically annoying. |
| 85 | * The CRC is calculated from the *very start* of the record, and |
| 86 | * include the malformed marker bytes. Our encoder doesn't know |
| 87 | * about this, of course, with the result that we have to construct |
| 88 | * the unencoded header, calculate the checksum, and then use the |
| 89 | * same logic to emit the bytes which require special encoding |
| 90 | * before encoding the rest of the header normally. */ |
| 91 | |
| 92 | { |
| 93 | Bytes header; |
| 94 | ByteWriter bw(header); |
| 95 | |
| 96 | writeBytes(12, 0x55); |
| 97 | bw.write_8(am1Unencoded); |
| 98 | bw.write_8(sectorData->logicalHead << 3); |
| 99 | bw.write_8(sectorData->logicalCylinder); |
| 100 | bw.write_8(_config.sector_count()); |
| 101 | bw.write_8(sectorData->logicalSector); |
| 102 | bw.write_be16(sectorData->data.size()); |
| 103 | uint16_t crc = crc16(CCITT_POLY, header); |
| 104 | bw.write_be16(crc); |
| 105 | |
| 106 | writeRawBits(_config.am1_byte(), 16); |
| 107 | writeBytes(header.slice(1)); |
| 108 | } |
| 109 | |
| 110 | writeBytes(_config.gap2_bytes(), 0x55); |
| 111 | |
| 112 | { |
| 113 | Bytes data; |
| 114 | ByteWriter bw(data); |
| 115 | |
| 116 | writeBytes(12, 0x55); |
| 117 | bw.write_8(am2Unencoded); |
| 118 | |
| 119 | bw += sectorData->data; |