| 71 | */ |
| 72 | |
| 73 | void writeSector( |
| 74 | std::vector<bool>& bits, unsigned& cursor, const Sector& sector) const |
| 75 | { |
| 76 | if ((sector.status == Sector::OK) or |
| 77 | (sector.status == Sector::BAD_CHECKSUM)) |
| 78 | { |
| 79 | auto write_bit = [&](bool val) |
| 80 | { |
| 81 | if (cursor <= bits.size()) |
| 82 | { |
| 83 | bits[cursor] = val; |
| 84 | } |
| 85 | cursor++; |
| 86 | }; |
| 87 | |
| 88 | auto write_bits = [&](uint32_t bits, int width) |
| 89 | { |
| 90 | for (int i = width; i--;) |
| 91 | { |
| 92 | write_bit(bits & (1u << i)); |
| 93 | } |
| 94 | }; |
| 95 | |
| 96 | auto write_gcr44 = [&](uint8_t value) |
| 97 | { |
| 98 | write_bits((value << 7) | value | 0xaaaa, 16); |
| 99 | }; |
| 100 | |
| 101 | auto write_gcr6 = [&](uint8_t value) |
| 102 | { |
| 103 | write_bits(encode_data_gcr(value), 8); |
| 104 | }; |
| 105 | |
| 106 | // The special "FF40" sequence is used to synchronize the receiving |
| 107 | // shift register. It's written as "1111 1111 00"; FF indicates the |
| 108 | // 8 consecutive 1-bits, while "40" indicates the total number of |
| 109 | // microseconds. |
| 110 | auto write_ff40 = [&](int n = 1) |
| 111 | { |
| 112 | for (; n--;) |
| 113 | { |
| 114 | write_bits(0xff << 2, 10); |
| 115 | } |
| 116 | }; |
| 117 | |
| 118 | // There is data to encode to disk. |
| 119 | if ((sector.data.size() != APPLE2_SECTOR_LENGTH)) |
| 120 | error("unsupported sector size {} --- you must pick 256", |
| 121 | sector.data.size()); |
| 122 | |
| 123 | // Write address syncing leader : A sequence of "FF40"s; 5 of them |
| 124 | // are said to suffice to synchronize the decoder. |
| 125 | // "FF40" indicates that the actual data written is "1111 |
| 126 | // 1111 00" i.e., 8 1s and a total of 40 microseconds |
| 127 | // |
| 128 | // In standard formatting, the first logical sector apparently gets |
| 129 | // extra padding. |
| 130 | write_ff40(sector.logicalSector == 0 ? 32 : 8); |
nothing calls this directly
no test coverage detected