// JV1 private static FloppyData FromJV1(byte[] DiskData) { const byte SECTORS_PER_TRACK = 10; const int SECTOR_LENGTH = 0x100; if (DiskData.Length % (SECTOR_LENGTH * SECTORS_PER_TRACK) != 0) { throw new Exception("Invalid JV1 Format"); } var sectors = new List <SectorDescriptor>(); byte numTracks = (byte)(DiskData.Length / 0x100 / 0x0A); // Sectors not interleaved for (byte i = 0; i < numTracks; i++) { for (byte j = 0; j < SECTORS_PER_TRACK; j++) { var sd = new SectorDescriptor(i, j, false, false, (i == 17) ? DAM_DELETED : DAM_NORMAL, new byte[SECTOR_LENGTH], true, false, false); Array.Copy(DiskData, (i * SECTORS_PER_TRACK + j) * SECTOR_LENGTH, sd.SectorData, 0, SECTOR_LENGTH); sectors.Add(sd); } } return(new FloppyData(sectors, false)); }
private const byte JV3_SECTOR_FREE_FLAGS = 0xFC; // in flags field, OR'd with size code // JV3 private static FloppyData FromJV3(byte[] DiskData) { var sectors = new List <SectorDescriptor>(); int diskCursor = 0; bool?writeProt = null; while (diskCursor < DiskData.Length - JV3_HEADER_SIZE - 1) { // Read sector Headers for (int i = diskCursor; i < diskCursor + JV3_HEADER_SIZE; i += 3) { if (DiskData[i] != JV3_SECTOR_FREE && DiskData[i + 1] != JV3_SECTOR_FREE) // 0xFF for unused header entries { byte flags = DiskData[i + 2]; bool dd = (flags & JV3_DOUBLE_DENSITY) == JV3_DOUBLE_DENSITY; var inUse = (flags & JV3_SECTOR_FREE_FLAGS) != JV3_SECTOR_FREE_FLAGS; // Sector Size Codes // Size IBM size SECTOR_SIZE field SECTOR_SIZE field // code if in use if free // 0x080 00 1 2 // 0x100 01 0 3 // 0x200 02 3 0 // 0x400 03 2 1 // JV3 sector size code is stored in a weird way var sectorSizeCode = (byte)((flags & JV3_SECTOR_SIZE_MASK) ^ (inUse ? 1 : 2)); var sectorSize = GetDataLengthFromCode(sectorSizeCode); var sd = new SectorDescriptor(DiskData[i], DiskData[i + 1], (flags & JV3_SIDE_ONE) == JV3_SIDE_ONE, dd, GetDamFromJV3Flags(flags, dd), new byte[sectorSize], inUse, (flags & JV3_CRC_ERROR) == JV3_CRC_ERROR, (flags & JV3_NON_IBM) == JV3_NON_IBM); sectors.Add(sd); } } diskCursor += JV3_HEADER_SIZE; if (writeProt.HasValue) { diskCursor++; } else { writeProt = (DiskData[diskCursor++] != 0xFF); } foreach (var sd in sectors) { if (sd.InUse) { if (DiskData.Length - diskCursor < sd.SectorSize) // not enough data for sector { if (DiskData.Length > diskCursor) // try to get some data { Array.Copy(DiskData, diskCursor, sd.SectorData, 0, DiskData.Length - diskCursor); } diskCursor = DiskData.Length; // push cursor past end; we're done } else { Array.Copy(DiskData, diskCursor, sd.SectorData, 0, sd.SectorSize); } } diskCursor += sd.SectorSize; } } return(new FloppyData(sectors, writeProt.Value)); }