| 15 | NsiImageWriter(const ImageWriterProto& config): ImageWriter(config) {} |
| 16 | |
| 17 | void writeImage(const Image& image) override |
| 18 | { |
| 19 | const Geometry& geometry = image.getGeometry(); |
| 20 | bool mixedDensity = false; |
| 21 | |
| 22 | size_t trackSize = geometry.numSectors * geometry.sectorSize; |
| 23 | |
| 24 | if (geometry.numCylinders * trackSize == 0) |
| 25 | { |
| 26 | log("No sectors in output; skipping .nsi image file generation."); |
| 27 | return; |
| 28 | } |
| 29 | |
| 30 | log("Writing {} tracks, {} sides, {} sectors, {} ({} bytes/sector), {} " |
| 31 | "kB total", |
| 32 | geometry.numCylinders, |
| 33 | geometry.numHeads, |
| 34 | geometry.numSectors, |
| 35 | geometry.sectorSize == 256 ? "SD" : "DD", |
| 36 | geometry.sectorSize, |
| 37 | geometry.numCylinders * geometry.numHeads * geometry.numSectors * |
| 38 | geometry.sectorSize / 1024); |
| 39 | |
| 40 | std::ofstream outputFile( |
| 41 | _config.filename(), std::ios::out | std::ios::binary); |
| 42 | if (!outputFile.is_open()) |
| 43 | error("cannot open output file"); |
| 44 | |
| 45 | unsigned sectorFileOffset; |
| 46 | for (int track = 0; track < geometry.numCylinders * geometry.numHeads; |
| 47 | track++) |
| 48 | { |
| 49 | int side = (track < geometry.numCylinders) ? 0 : 1; |
| 50 | for (int sectorId = 0; sectorId < geometry.numSectors; sectorId++) |
| 51 | { |
| 52 | const auto& sector = |
| 53 | image.get(track % geometry.numCylinders, side, sectorId); |
| 54 | if (sector) |
| 55 | { |
| 56 | if (side == 0) |
| 57 | { /* Side 0 is from track 0-34 */ |
| 58 | sectorFileOffset = |
| 59 | track * trackSize + sectorId * geometry.sectorSize; |
| 60 | } |
| 61 | else |
| 62 | { /* Side 1 is from track 70-35 */ |
| 63 | sectorFileOffset = |
| 64 | (geometry.sectorSize * geometry.numSectors * |
| 65 | geometry.numCylinders) + /* Skip over side 0 */ |
| 66 | ((geometry.numCylinders - 1) - |
| 67 | (track % geometry.numCylinders)) * |
| 68 | (geometry.sectorSize * geometry.numSectors) + |
| 69 | (sectorId * |
| 70 | geometry.sectorSize); /* Sector offset from |
| 71 | beginning of track. */ |
| 72 | } |
| 73 | outputFile.seekp(sectorFileOffset, std::ios::beg); |
| 74 | if ((geometry.sectorSize == 512) && |