| 55 | } |
| 56 | |
| 57 | static void write_sector(std::vector<bool>& bits, |
| 58 | unsigned& cursor, |
| 59 | const std::shared_ptr<const Sector>& sector) |
| 60 | { |
| 61 | if ((sector->data.size() != 512) && (sector->data.size() != 528)) |
| 62 | error("unsupported sector size --- you must pick 512 or 528"); |
| 63 | |
| 64 | uint32_t checksum = 0; |
| 65 | |
| 66 | auto write_interleaved_bytes = [&](const Bytes& bytes) |
| 67 | { |
| 68 | Bytes interleaved = amigaInterleave(bytes); |
| 69 | Bytes mfm = encodeMfm(interleaved, lastBit); |
| 70 | checksum ^= amigaChecksum(mfm); |
| 71 | checksum &= 0x55555555; |
| 72 | write_bits(bits, cursor, mfm); |
| 73 | }; |
| 74 | |
| 75 | auto write_interleaved_word = [&](uint32_t word) |
| 76 | { |
| 77 | Bytes b(4); |
| 78 | b.writer().write_be32(word); |
| 79 | write_interleaved_bytes(b); |
| 80 | }; |
| 81 | |
| 82 | write_bits(bits, cursor, 0xaaaa, 2 * 8); |
| 83 | write_bits(bits, cursor, AMIGA_SECTOR_RECORD, 6 * 8); |
| 84 | |
| 85 | checksum = 0; |
| 86 | Bytes header = {0xff, /* Amiga 1.0 format byte */ |
| 87 | (uint8_t)((sector->logicalCylinder << 1) | sector->logicalHead), |
| 88 | (uint8_t)sector->logicalSector, |
| 89 | (uint8_t)(AMIGA_SECTORS_PER_TRACK - sector->logicalSector)}; |
| 90 | write_interleaved_bytes(header); |
| 91 | Bytes recoveryInfo(16); |
| 92 | if (sector->data.size() == 528) |
| 93 | recoveryInfo = sector->data.slice(512, 16); |
| 94 | write_interleaved_bytes(recoveryInfo); |
| 95 | write_interleaved_word(checksum); |
| 96 | |
| 97 | Bytes data = sector->data.slice(0, 512); |
| 98 | write_interleaved_word( |
| 99 | amigaChecksum(encodeMfm(amigaInterleave(data), lastBit))); |
| 100 | write_interleaved_bytes(data); |
| 101 | } |
| 102 | |
| 103 | class AmigaEncoder : public Encoder |
| 104 | { |
no test coverage detected