| 15 | DiskCopyImageReader(const ImageReaderProto& config): ImageReader(config) {} |
| 16 | |
| 17 | std::unique_ptr<Image> readImage() override |
| 18 | { |
| 19 | std::ifstream inputFile( |
| 20 | _config.filename(), std::ios::in | std::ios::binary); |
| 21 | if (!inputFile.is_open()) |
| 22 | error("cannot open input file"); |
| 23 | |
| 24 | Bytes data; |
| 25 | data.writer() += inputFile; |
| 26 | ByteReader br(data); |
| 27 | |
| 28 | br.seek(1); |
| 29 | std::string label = br.read(data[0]); |
| 30 | |
| 31 | br.seek(0x40); |
| 32 | uint32_t dataSize = br.read_be32(); |
| 33 | |
| 34 | br.seek(0x50); |
| 35 | uint8_t encoding = br.read_8(); |
| 36 | uint8_t formatByte = br.read_8(); |
| 37 | |
| 38 | unsigned numCylinders = 80; |
| 39 | unsigned numHeads = 2; |
| 40 | unsigned numSectors = 0; |
| 41 | bool mfm = false; |
| 42 | |
| 43 | switch (encoding) |
| 44 | { |
| 45 | case 0: /* GCR CLV 400kB */ |
| 46 | numHeads = 1; |
| 47 | break; |
| 48 | |
| 49 | case 1: /* GCR CLV 800kB */ |
| 50 | break; |
| 51 | |
| 52 | case 2: /* MFM CAV 720kB */ |
| 53 | numSectors = 9; |
| 54 | mfm = true; |
| 55 | break; |
| 56 | |
| 57 | case 3: /* MFM CAV 1440kB */ |
| 58 | numSectors = 18; |
| 59 | mfm = true; |
| 60 | break; |
| 61 | |
| 62 | default: |
| 63 | error("don't understand DiskCopy disks of type {}", encoding); |
| 64 | } |
| 65 | |
| 66 | log("DC42: reading image with {} tracks, {} heads; {}; {}", |
| 67 | numCylinders, |
| 68 | numHeads, |
| 69 | mfm ? "MFM" : "GCR", |
| 70 | label); |
| 71 | |
| 72 | auto sectorsPerTrack = [&](int track) -> int |
| 73 | { |
| 74 | if (mfm) |