| 48 | Td0ImageReader(const ImageReaderProto& config): ImageReader(config) {} |
| 49 | |
| 50 | std::unique_ptr<Image> readImage() override |
| 51 | { |
| 52 | std::ifstream inputFile( |
| 53 | _config.filename(), std::ios::in | std::ios::binary); |
| 54 | if (!inputFile.is_open()) |
| 55 | error("cannot open input file"); |
| 56 | |
| 57 | Bytes input; |
| 58 | input.writer() += inputFile; |
| 59 | ByteReader br(input); |
| 60 | |
| 61 | uint16_t signature = br.read_be16(); |
| 62 | br.skip(2); /* sequence and checksequence */ |
| 63 | uint8_t version = br.read_8(); |
| 64 | br.skip(2); /* data rate, drive type */ |
| 65 | uint8_t stepping = br.read_8(); |
| 66 | br.skip(1); /* sparse flag */ |
| 67 | uint8_t sides = (br.read_8() == 1) ? 1 : 2; |
| 68 | uint16_t headerCrc = br.read_le16(); |
| 69 | |
| 70 | uint16_t gotCrc = crc16(0xa097, 0, input.slice(0, 10)); |
| 71 | if (gotCrc != headerCrc) |
| 72 | error("TD0: header checksum mismatch"); |
| 73 | if (signature != 0x5444) |
| 74 | error( |
| 75 | "TD0: unsupported file type (only uncompressed files " |
| 76 | "are supported for now)"); |
| 77 | |
| 78 | std::string comment = "(no comment)"; |
| 79 | if (stepping & 0x80) |
| 80 | { |
| 81 | /* Comment block */ |
| 82 | |
| 83 | br.skip(2); /* comment CRC */ |
| 84 | uint16_t length = br.read_le16(); |
| 85 | br.skip(6); /* timestamp */ |
| 86 | comment = br.read(length); |
| 87 | std::replace(comment.begin(), comment.end(), '\0', '\n'); |
| 88 | |
| 89 | /* Strip trailing newlines */ |
| 90 | |
| 91 | auto nl = std::find_if(comment.rbegin(), |
| 92 | comment.rend(), |
| 93 | [](unsigned char ch) |
| 94 | { |
| 95 | return !std::isspace(ch); |
| 96 | }); |
| 97 | comment.erase(nl.base(), comment.end()); |
| 98 | } |
| 99 | |
| 100 | log("TD0: TeleDisk {}.{}: {}", version / 10, version % 10, comment); |
| 101 | |
| 102 | unsigned totalSize = 0; |
| 103 | std::unique_ptr<Image> image(new Image); |
| 104 | for (;;) |
| 105 | { |
| 106 | /* Read track header */ |
| 107 |
nothing calls this directly
no test coverage detected