| 105 | } |
| 106 | |
| 107 | void decodeSectorRecord() override |
| 108 | { |
| 109 | /* This is really annoying because the IBM record scheme has a |
| 110 | * variable-sized header _and_ the checksum covers this header too. So |
| 111 | * we have to read and decode a byte at a time until we know where the |
| 112 | * record itself starts, saving the bytes for the checksumming later. |
| 113 | */ |
| 114 | |
| 115 | Bytes bytes; |
| 116 | ByteWriter bw(bytes); |
| 117 | |
| 118 | auto readByte = [&]() |
| 119 | { |
| 120 | auto bits = readRawBits(16); |
| 121 | auto bytes = decodeFmMfm(bits).slice(0, 1); |
| 122 | uint8_t byte = bytes[0]; |
| 123 | bw.write_8(byte); |
| 124 | return byte; |
| 125 | }; |
| 126 | |
| 127 | uint8_t id = readByte(); |
| 128 | if (id == 0xa1) |
| 129 | { |
| 130 | readByte(); |
| 131 | readByte(); |
| 132 | id = readByte(); |
| 133 | } |
| 134 | if (id != IBM_IDAM) |
| 135 | return; |
| 136 | |
| 137 | ByteReader br(bytes); |
| 138 | br.seek(bw.pos); |
| 139 | |
| 140 | auto bits = readRawBits(IBM_IDAM_LEN * 16); |
| 141 | bw += decodeFmMfm(bits).slice(0, IBM_IDAM_LEN); |
| 142 | |
| 143 | IbmDecoderProto::TrackdataProto trackdata; |
| 144 | getTrackFormat(trackdata, _ltl->logicalCylinder, _ltl->logicalHead); |
| 145 | |
| 146 | _sector->logicalCylinder = br.read_8(); |
| 147 | _sector->logicalHead = br.read_8(); |
| 148 | _sector->logicalSector = br.read_8(); |
| 149 | _currentSectorSize = 1 << (br.read_8() + 7); |
| 150 | |
| 151 | uint16_t gotCrc = crc16(CCITT_POLY, bytes.slice(0, br.pos)); |
| 152 | uint16_t wantCrc = br.read_be16(); |
| 153 | if (wantCrc == gotCrc) |
| 154 | _sector->status = |
| 155 | Sector::DATA_MISSING; /* correct but unintuitive */ |
| 156 | |
| 157 | if (trackdata.ignore_side_byte()) |
| 158 | _sector->logicalHead = _ltl->logicalHead; |
| 159 | _sector->logicalHead ^= trackdata.invert_side_byte(); |
| 160 | if (trackdata.ignore_track_byte()) |
| 161 | _sector->logicalCylinder = _ltl->logicalCylinder; |
| 162 | |
| 163 | for (int sector : trackdata.ignore_sector()) |
| 164 | if (_sector->logicalSector == sector) |