| 17 | NsiImageReader(const ImageReaderProto& config): ImageReader(config) {} |
| 18 | |
| 19 | std::unique_ptr<Image> readImage() override |
| 20 | { |
| 21 | std::ifstream inputFile( |
| 22 | _config.filename(), std::ios::in | std::ios::binary); |
| 23 | if (!inputFile.is_open()) |
| 24 | error("cannot open input file"); |
| 25 | |
| 26 | const auto begin = inputFile.tellg(); |
| 27 | inputFile.seekg(0, std::ios::end); |
| 28 | const auto end = inputFile.tellg(); |
| 29 | const auto fsize = (end - begin); |
| 30 | |
| 31 | log("NSI: Autodetecting geometry based on file size: {}", fsize); |
| 32 | |
| 33 | unsigned numCylinders = 35; |
| 34 | unsigned numSectors = 10; |
| 35 | unsigned numHeads = 2; |
| 36 | unsigned sectorSize = 512; |
| 37 | |
| 38 | switch (fsize) |
| 39 | { |
| 40 | case 358400: |
| 41 | numHeads = 2; |
| 42 | sectorSize = 512; |
| 43 | break; |
| 44 | |
| 45 | case 179200: |
| 46 | numHeads = 1; |
| 47 | sectorSize = 512; |
| 48 | break; |
| 49 | |
| 50 | case 89600: |
| 51 | numHeads = 1; |
| 52 | sectorSize = 256; |
| 53 | break; |
| 54 | |
| 55 | default: |
| 56 | error("NSI: unknown file size"); |
| 57 | } |
| 58 | |
| 59 | size_t trackSize = numSectors * sectorSize; |
| 60 | |
| 61 | log("reading {} tracks, {} heads, {} sectors, {} bytes per sector, {} " |
| 62 | "kB total", |
| 63 | numCylinders, |
| 64 | numHeads, |
| 65 | numSectors, |
| 66 | sectorSize, |
| 67 | numCylinders * numHeads * trackSize / 1024); |
| 68 | |
| 69 | std::unique_ptr<Image> image(new Image); |
| 70 | unsigned sectorFileOffset; |
| 71 | |
| 72 | for (unsigned head = 0; head < numHeads; head++) |
| 73 | { |
| 74 | for (unsigned track = 0; track < numCylinders; track++) |
| 75 | { |
| 76 | for (unsigned sectorId = 0; sectorId < numSectors; sectorId++) |