private byte[][] generateTrackImage(List <FdiSectorHeader> sectorHeaderList) { var trackImage = new byte[2][]; // Вычисляем необходимое число байт под данные: var imageSize = 6250; var secCount = sectorHeaderList.Count; var trkdatalen = 0; for (var ilsec = 0; ilsec < secCount; ilsec++) { var hdr = sectorHeaderList[ilsec]; trkdatalen += 2 + 6; // for marks: 0xA1, 0xFE, 6bytes var slen = 128 << hdr.N; if ((hdr.Flags & 0x40) != 0) // заголовок без массива данных { slen = 0; } else { trkdatalen += 4; // for data header/crc: 0xA1, 0xFB, ...,2bytes } trkdatalen += slen; } var freeSpace = imageSize - (trkdatalen + secCount * (3 + 2)); // 3x4E & 2x00 per sector var synchroPulseLen = 1; // 1 уже учтен в trkdatalen... var firstSpaceLen = 1; var secondSpaceLen = 1; var thirdSpaceLen = 1; var synchroSpaceLen = 1; freeSpace -= firstSpaceLen + secondSpaceLen + thirdSpaceLen + synchroSpaceLen; if (freeSpace < 0) { imageSize += -freeSpace; freeSpace = 0; } // Распределяем длины пробелов и синхропромежутка: while (freeSpace > 0) { if (freeSpace >= (secCount * 2)) // Synchro for ADMARK & DATA { if (synchroSpaceLen < 12) { synchroSpaceLen++; freeSpace -= secCount * 2; } } if (freeSpace < secCount) { break; } if (firstSpaceLen < 10) { firstSpaceLen++; freeSpace -= secCount; } if (freeSpace < secCount) { break; } if (secondSpaceLen < 22) { secondSpaceLen++; freeSpace -= secCount; } if (freeSpace < secCount) { break; } if (thirdSpaceLen < 60) { thirdSpaceLen++; freeSpace -= secCount; } if (freeSpace < secCount) { break; } if ((synchroSpaceLen >= 12) && (firstSpaceLen >= 10) && (secondSpaceLen >= 22) && (thirdSpaceLen >= 60)) { break; } } // по возможности делаем три синхроимпульса... if (freeSpace > (secCount * 2) + 10) { synchroPulseLen++; freeSpace -= secCount; } if (freeSpace > (secCount * 2) + 9) { synchroPulseLen++; } if (freeSpace < 0) { imageSize += -freeSpace; freeSpace = 0; } // Форматируем дорожку... trackImage[0] = new byte[imageSize]; trackImage[1] = new byte[trackImage[0].Length / 8 + (((trackImage[0].Length & 7) != 0) ? 1 : 0)]; var tptr = 0; for (var sec = 0; sec < secCount; sec++) { var hdr = sectorHeaderList[sec]; for (var r = 0; r < firstSpaceLen; r++) // Первый пробел { trackImage[0][tptr] = 0x4E; trackImage[1][tptr / 8] &= (byte)~(1 << (tptr & 7)); tptr++; } for (var r = 0; r < synchroSpaceLen; r++) // Синхропромежуток { trackImage[0][tptr] = 0x00; trackImage[1][tptr / 8] &= (byte)~(1 << (tptr & 7)); tptr++; } var ptrcrc = tptr; for (var r = 0; r < synchroPulseLen; r++) // Синхроимпульс { trackImage[0][tptr] = 0xA1; trackImage[1][tptr / 8] |= (byte)(1 << (tptr & 7)); tptr++; } trackImage[0][tptr] = 0xFE; // Метка "Адрес" trackImage[1][tptr / 8] &= (byte)~(1 << (tptr & 7)); tptr++; trackImage[0][tptr] = hdr.C; // cyl trackImage[1][tptr / 8] &= (byte)~(1 << (tptr & 7)); tptr++; trackImage[0][tptr] = hdr.H; // head trackImage[1][tptr / 8] &= (byte)~(1 << (tptr & 7)); tptr++; trackImage[0][tptr] = hdr.R; // sector # trackImage[1][tptr / 8] &= (byte)~(1 << (tptr & 7)); tptr++; trackImage[0][tptr] = hdr.N; // len code trackImage[1][tptr / 8] &= (byte)~(1 << (tptr & 7)); tptr++; ushort vgcrc = CrcVg93.Calculate(trackImage[0], ptrcrc, tptr - ptrcrc); trackImage[0][tptr] = (byte)vgcrc; // crc trackImage[1][tptr / 8] &= (byte)~(1 << (tptr & 7)); tptr++; trackImage[0][tptr] = (byte)(vgcrc >> 8); // crc trackImage[1][tptr / 8] &= (byte)~(1 << (tptr & 7)); tptr++; for (var r = 0; r < secondSpaceLen; r++) // Второй пробел { trackImage[0][tptr] = 0x4E; trackImage[1][tptr / 8] &= (byte)~(1 << (tptr & 7)); tptr++; } for (var r = 0; r < synchroSpaceLen; r++) // Синхропромежуток { trackImage[0][tptr] = 0x00; trackImage[1][tptr / 8] &= (byte)~(1 << (tptr & 7)); tptr++; } byte fdiSectorFlags = hdr.Flags; // !!!!!!!!! // !WARNING! this feature of FDI format is NOT FULL DOCUMENTED!!! // !!!!!!!!! // // Flags::bit6 - Возможно, 1 в данном разряде // будет обозначать адресный маркер без области данных. // if ((fdiSectorFlags & 0x40) == 0) // oh-oh, data area can be not present... ;-) { ptrcrc = tptr; for (var r = 0; r < synchroPulseLen; r++) // Синхроимпульс { trackImage[0][tptr] = 0xA1; trackImage[1][tptr / 8] |= (byte)(1 << (tptr & 7)); tptr++; } if ((fdiSectorFlags & 0x80) != 0) { trackImage[0][tptr] = 0xF8; // Метка "Удаленные данные" } else { trackImage[0][tptr] = 0xFB; // Метка "Данные" } trackImage[1][tptr / 8] &= (byte)~(1 << (tptr & 7)); tptr++; //TODO: sector len from crc flags? var SL = 128 << hdr.N; for (var r = 0; r < SL; r++) // сектор SL байт { trackImage[0][tptr] = hdr.DataArray[r]; trackImage[1][tptr / 8] &= (byte)~(1 << (tptr & 7)); tptr++; } vgcrc = CrcVg93.Calculate(trackImage[0], ptrcrc, tptr - ptrcrc); if ((fdiSectorFlags & 0x3F) == 0) // CRC not correct? { vgcrc ^= (ushort)0xFFFF; // oh-oh, high technology... CRC bad... ;-) } trackImage[0][tptr] = (byte)vgcrc; // crc trackImage[1][tptr / 8] &= (byte)~(1 << (tptr & 7)); tptr++; trackImage[0][tptr] = (byte)(vgcrc >> 8); // crc trackImage[1][tptr / 8] &= (byte)~(1 << (tptr & 7)); tptr++; } for (var r = 0; r < thirdSpaceLen; r++) // Третий пробел { trackImage[0][tptr] = 0x4E; trackImage[1][tptr / 8] &= (byte)~(1 << (tptr & 7)); tptr++; } } for (var eoftrk = tptr; eoftrk < trackImage[0].Length; eoftrk++) { trackImage[0][tptr] = 0x4E; trackImage[1][tptr / 8] &= (byte)~(1 << (tptr & 7)); tptr++; } return(trackImage); }