| 141 | } |
| 142 | |
| 143 | bool DiskTrack::Save(const string& path, uint64_t& cache_miss_write_count) |
| 144 | { |
| 145 | // Not needed if not initialized |
| 146 | if (!dt.init) { |
| 147 | return true; |
| 148 | } |
| 149 | |
| 150 | // Not needed unless changed |
| 151 | if (!dt.changed) { |
| 152 | return true; |
| 153 | } |
| 154 | |
| 155 | ++cache_miss_write_count; |
| 156 | |
| 157 | // Need to write |
| 158 | assert(dt.buffer); |
| 159 | assert((dt.sectors > 0) && (dt.sectors <= 0x100)); |
| 160 | |
| 161 | // Writing in RAW mode is not allowed |
| 162 | assert(!dt.raw); |
| 163 | |
| 164 | // Calculate offset (previous tracks are considered to hold 256 sectors) |
| 165 | off_t offset = ((off_t)dt.track << 8); |
| 166 | offset <<= dt.size; |
| 167 | |
| 168 | // Add offset to real image |
| 169 | offset += dt.imgoffset; |
| 170 | |
| 171 | // Calculate length per sector |
| 172 | const int length = 1 << dt.size; |
| 173 | |
| 174 | ofstream out(path, ios::in | ios::out | ios::binary); |
| 175 | if (out.fail()) { |
| 176 | return false; |
| 177 | } |
| 178 | |
| 179 | // Partial write loop |
| 180 | int total; |
| 181 | for (int i = 0; i < dt.sectors;) { |
| 182 | // If changed |
| 183 | if (dt.changemap[i]) { |
| 184 | // Initialize write size |
| 185 | total = 0; |
| 186 | |
| 187 | out.seekp(offset + ((off_t)i << dt.size)); |
| 188 | if (out.fail()) { |
| 189 | return false; |
| 190 | } |
| 191 | |
| 192 | // Consectutive sector length |
| 193 | int j; |
| 194 | for (j = i; j < dt.sectors; j++) { |
| 195 | // end when interrupted |
| 196 | if (!dt.changemap[j]) { |
| 197 | break; |
| 198 | } |
| 199 | |
| 200 | // Add one sector |