| 205 | |
| 206 | private: |
| 207 | void writeSector(std::vector<bool>& bits, |
| 208 | unsigned& cursor, |
| 209 | std::shared_ptr<const Sector> sector) const |
| 210 | { |
| 211 | /* Source: http://www.unusedino.de/ec64/technical/formats/g64.html |
| 212 | * 1. Header sync FF FF FF FF FF (40 'on' bits, not GCR) |
| 213 | * 2. Header info 52 54 B5 29 4B 7A 5E 95 55 55 (10 GCR bytes) |
| 214 | * 3. Header gap 55 55 55 55 55 55 55 55 55 (9 bytes, never read) |
| 215 | * 4. Data sync FF FF FF FF FF (40 'on' bits, not GCR) |
| 216 | * 5. Data block 55...4A (325 GCR bytes) |
| 217 | * 6. Inter-sector gap 55 55 55 55...55 55 (4 to 12 bytes, never read) |
| 218 | * 1. Header sync (SYNC for the next sector) |
| 219 | */ |
| 220 | if ((sector->status == Sector::OK) or |
| 221 | (sector->status == Sector::BAD_CHECKSUM)) |
| 222 | { |
| 223 | // There is data to encode to disk. |
| 224 | if ((sector->data.size() != C64_SECTOR_LENGTH)) |
| 225 | error("unsupported sector size {} --- you must pick 256", |
| 226 | sector->data.size()); |
| 227 | |
| 228 | // 1. Write header Sync (not GCR) |
| 229 | for (int i = 0; i < 6; i++) |
| 230 | write_bits( |
| 231 | bits, cursor, C64_HEADER_DATA_SYNC, 1 * 8); /* sync */ |
| 232 | |
| 233 | // 2. Write Header info 10 GCR bytes |
| 234 | /* |
| 235 | * The 10 byte header info (#2) is GCR encoded and must be decoded |
| 236 | * to it's normal 8 bytes to be understood. Once decoded, its |
| 237 | * breakdown is as follows: |
| 238 | * |
| 239 | * Byte $00 - header block ID ($08) |
| 240 | * 01 - header block checksum 16 (EOR of $02-$05) |
| 241 | * 02 - Sector |
| 242 | * 03 - Track |
| 243 | * 04 - Format ID byte #2 |
| 244 | * 05 - Format ID byte #1 |
| 245 | * 06-07 - $0F ("off" bytes) |
| 246 | */ |
| 247 | uint8_t encodedTrack = |
| 248 | ((sector->logicalCylinder) + |
| 249 | 1); // C64 track numbering starts with 1. Fluxengine with 0. |
| 250 | uint8_t encodedSector = sector->logicalSector; |
| 251 | // uint8_t formatByte1 = C64_FORMAT_ID_BYTE1; |
| 252 | // uint8_t formatByte2 = C64_FORMAT_ID_BYTE2; |
| 253 | uint8_t headerChecksum = |
| 254 | (encodedTrack ^ encodedSector ^ _formatByte1 ^ _formatByte2); |
| 255 | write_bits(bits, cursor, encode_data(C64_HEADER_BLOCK_ID)); |
| 256 | write_bits(bits, cursor, encode_data(headerChecksum)); |
| 257 | write_bits(bits, cursor, encode_data(encodedSector)); |
| 258 | write_bits(bits, cursor, encode_data(encodedTrack)); |
| 259 | write_bits(bits, cursor, encode_data(_formatByte2)); |
| 260 | write_bits(bits, cursor, encode_data(_formatByte1)); |
| 261 | write_bits(bits, cursor, encode_data(C64_PADDING)); |
| 262 | write_bits(bits, cursor, encode_data(C64_PADDING)); |
| 263 | |
| 264 | // 3. Write header GAP not GCR |
nothing calls this directly
no test coverage detected