| 169 | } |
| 170 | |
| 171 | void decodeDataRecord() override |
| 172 | { |
| 173 | /* This is the same deal as the sector record. */ |
| 174 | |
| 175 | Bytes bytes; |
| 176 | ByteWriter bw(bytes); |
| 177 | |
| 178 | auto readByte = [&]() |
| 179 | { |
| 180 | auto bits = readRawBits(16); |
| 181 | auto bytes = decodeFmMfm(bits).slice(0, 1); |
| 182 | uint8_t byte = bytes[0]; |
| 183 | bw.write_8(byte); |
| 184 | return byte; |
| 185 | }; |
| 186 | |
| 187 | uint8_t id = readByte(); |
| 188 | if (id == 0xa1) |
| 189 | { |
| 190 | readByte(); |
| 191 | readByte(); |
| 192 | id = readByte(); |
| 193 | } |
| 194 | if ((id != IBM_DAM1) && (id != IBM_DAM2) && (id != IBM_TRS80DAM1) && |
| 195 | (id != IBM_TRS80DAM2)) |
| 196 | return; |
| 197 | |
| 198 | ByteReader br(bytes); |
| 199 | br.seek(bw.pos); |
| 200 | |
| 201 | auto bits = readRawBits((_currentSectorSize + 2) * 16); |
| 202 | bw += decodeFmMfm(bits).slice(0, _currentSectorSize + 2); |
| 203 | |
| 204 | _sector->data = br.read(_currentSectorSize); |
| 205 | uint16_t gotCrc = crc16(CCITT_POLY, bytes.slice(0, br.pos)); |
| 206 | uint16_t wantCrc = br.read_be16(); |
| 207 | _sector->status = |
| 208 | (wantCrc == gotCrc) ? Sector::OK : Sector::BAD_CHECKSUM; |
| 209 | |
| 210 | if (_currentSectorSize != _ltl->sectorSize) |
| 211 | std::cerr << fmt::format( |
| 212 | "Warning: configured sector size for t{}.h{}.s{} is {} bytes " |
| 213 | "but that seen on disk is {} bytes\n", |
| 214 | _sector->logicalCylinder, |
| 215 | _sector->logicalHead, |
| 216 | _sector->logicalSector, |
| 217 | _ltl->sectorSize, |
| 218 | _currentSectorSize); |
| 219 | } |
| 220 | |
| 221 | private: |
| 222 | void getTrackFormat(IbmDecoderProto::TrackdataProto& trackdata, |