public void Crc16RandomData() { byte[] data = new byte[1048576]; FileStream fs = new FileStream(Path.Combine(Consts.TestFilesRoot, "checksums", "random"), FileMode.Open, FileAccess.Read); fs.Read(data, 0, 1048576); fs.Close(); fs.Dispose(); Crc16Context.Data(data, out byte[] result); Assert.AreEqual(ExpectedRandom, result); }
public bool Open(IFilter imageFilter) { Stream stream = imageFilter.GetDataForkStream(); stream.Seek(0, SeekOrigin.Begin); if (stream.Length < 512) { return(false); } byte[] headerB = new byte[256]; stream.Read(headerB, 0, 256); CpcDiskInfo header = Marshal.ByteArrayToStructureLittleEndian <CpcDiskInfo>(headerB); if (!cpcdskId.SequenceEqual(header.magic) && !edskId.SequenceEqual(header.magic) && !du54Id.SequenceEqual(header.magic)) { return(false); } extended = edskId.SequenceEqual(header.magic); DicConsole.DebugWriteLine("CPCDSK plugin", "Extended = {0}", extended); DicConsole.DebugWriteLine("CPCDSK plugin", "header.magic = \"{0}\"", StringHandlers.CToString(header.magic)); DicConsole.DebugWriteLine("CPCDSK plugin", "header.magic2 = \"{0}\"", StringHandlers.CToString(header.magic2)); DicConsole.DebugWriteLine("CPCDSK plugin", "header.creator = \"{0}\"", StringHandlers.CToString(header.creator)); DicConsole.DebugWriteLine("CPCDSK plugin", "header.tracks = {0}", header.tracks); DicConsole.DebugWriteLine("CPCDSK plugin", "header.sides = {0}", header.sides); if (!extended) { DicConsole.DebugWriteLine("CPCDSK plugin", "header.tracksize = {0}", header.tracksize); } else { for (int i = 0; i < header.tracks; i++) { for (int j = 0; j < header.sides; j++) { DicConsole.DebugWriteLine("CPCDSK plugin", "Track {0} Side {1} size = {2}", i, j, header.tracksizeTable[i * header.sides + j] * 256); } } } ulong currentSector = 0; sectors = new Dictionary <ulong, byte[]>(); addressMarks = new Dictionary <ulong, byte[]>(); ulong readtracks = 0; bool allTracksSameSize = true; ulong sectorsPerTrack = 0; // Seek to first track descriptor stream.Seek(256, SeekOrigin.Begin); for (int i = 0; i < header.tracks; i++) { for (int j = 0; j < header.sides; j++) { // Track not stored in image if (extended && header.tracksizeTable[i * header.sides + j] == 0) { continue; } long trackPos = stream.Position; byte[] trackB = new byte[256]; stream.Read(trackB, 0, 256); CpcTrackInfo trackInfo = Marshal.ByteArrayToStructureLittleEndian <CpcTrackInfo>(trackB); if (!trackId.SequenceEqual(trackInfo.magic)) { DicConsole.ErrorWriteLine("Not the expected track info."); return(false); } DicConsole.DebugWriteLine("CPCDSK plugin", "trackInfo[{1}:{2}].magic = \"{0}\"", StringHandlers.CToString(trackInfo.magic), i, j); DicConsole.DebugWriteLine("CPCDSK plugin", "trackInfo[{1}:{2}].bps = {0}", SizeCodeToBytes(trackInfo.bps), i, j); DicConsole.DebugWriteLine("CPCDSK plugin", "trackInfo[{1}:{2}].dataRate = {0}", trackInfo.dataRate, i, j); DicConsole.DebugWriteLine("CPCDSK plugin", "trackInfo[{1}:{2}].filler = 0x{0:X2}", trackInfo.filler, i, j); DicConsole.DebugWriteLine("CPCDSK plugin", "trackInfo[{1}:{2}].gap3 = 0x{0:X2}", trackInfo.gap3, i, j); DicConsole.DebugWriteLine("CPCDSK plugin", "trackInfo[{1}:{2}].padding = {0}", trackInfo.padding, i, j); DicConsole.DebugWriteLine("CPCDSK plugin", "trackInfo[{1}:{2}].recordingMode = {0}", trackInfo.recordingMode, i, j); DicConsole.DebugWriteLine("CPCDSK plugin", "trackInfo[{1}:{2}].sectors = {0}", trackInfo.sectors, i, j); DicConsole.DebugWriteLine("CPCDSK plugin", "trackInfo[{1}:{2}].side = {0}", trackInfo.side, i, j); DicConsole.DebugWriteLine("CPCDSK plugin", "trackInfo[{1}:{2}].track = {0}", trackInfo.track, i, j); if (trackInfo.sectors != sectorsPerTrack) { if (sectorsPerTrack == 0) { sectorsPerTrack = trackInfo.sectors; } else { allTracksSameSize = false; } } byte[][] thisTrackSectors = new byte[trackInfo.sectors][]; byte[][] thisTrackAddressMarks = new byte[trackInfo.sectors][]; for (int k = 1; k <= trackInfo.sectors; k++) { DicConsole.DebugWriteLine("CPCDSK plugin", "trackInfo[{1}:{2}].sector[{3}].id = 0x{0:X2}", trackInfo.sectorsInfo[k - 1].id, i, j, k); DicConsole.DebugWriteLine("CPCDSK plugin", "trackInfo[{1}:{2}].sector[{3}].len = {0}", trackInfo.sectorsInfo[k - 1].len, i, j, k); DicConsole.DebugWriteLine("CPCDSK plugin", "trackInfo[{1}:{2}].sector[{3}].side = {0}", trackInfo.sectorsInfo[k - 1].side, i, j, k); DicConsole.DebugWriteLine("CPCDSK plugin", "trackInfo[{1}:{2}].sector[{3}].size = {0}", SizeCodeToBytes(trackInfo.sectorsInfo[k - 1].size), i, j, k); DicConsole.DebugWriteLine("CPCDSK plugin", "trackInfo[{1}:{2}].sector[{3}].st1 = 0x{0:X2}", trackInfo.sectorsInfo[k - 1].st1, i, j, k); DicConsole.DebugWriteLine("CPCDSK plugin", "trackInfo[{1}:{2}].sector[{3}].st2 = 0x{0:X2}", trackInfo.sectorsInfo[k - 1].st2, i, j, k); DicConsole.DebugWriteLine("CPCDSK plugin", "trackInfo[{1}:{2}].sector[{3}].track = {0}", trackInfo.sectorsInfo[k - 1].track, i, j, k); int sectLen = extended ? trackInfo.sectorsInfo[k - 1].len : SizeCodeToBytes(trackInfo.sectorsInfo[k - 1].size); byte[] sector = new byte[sectLen]; stream.Read(sector, 0, sectLen); if (sectLen < SizeCodeToBytes(trackInfo.sectorsInfo[k - 1].size)) { byte[] temp = new byte[SizeCodeToBytes(trackInfo.sectorsInfo[k - 1].size)]; Array.Copy(sector, 0, temp, 0, sector.Length); sector = temp; } else if (sectLen > SizeCodeToBytes(trackInfo.sectorsInfo[k - 1].size)) { byte[] temp = new byte[SizeCodeToBytes(trackInfo.sectorsInfo[k - 1].size)]; Array.Copy(sector, 0, temp, 0, temp.Length); sector = temp; } thisTrackSectors[(trackInfo.sectorsInfo[k - 1].id & 0x3F) - 1] = sector; byte[] amForCrc = new byte[8]; amForCrc[0] = 0xA1; amForCrc[1] = 0xA1; amForCrc[2] = 0xA1; amForCrc[3] = (byte)IBMIdType.AddressMark; amForCrc[4] = trackInfo.sectorsInfo[k - 1].track; amForCrc[5] = trackInfo.sectorsInfo[k - 1].side; amForCrc[6] = trackInfo.sectorsInfo[k - 1].id; amForCrc[7] = (byte)trackInfo.sectorsInfo[k - 1].size; Crc16Context.Data(amForCrc, 8, out byte[] amCrc); byte[] addressMark = new byte[22]; Array.Copy(amForCrc, 0, addressMark, 12, 8); Array.Copy(amCrc, 0, addressMark, 20, 2); thisTrackAddressMarks[(trackInfo.sectorsInfo[k - 1].id & 0x3F) - 1] = addressMark; } for (int s = 0; s < thisTrackSectors.Length; s++) { sectors.Add(currentSector, thisTrackSectors[s]); addressMarks.Add(currentSector, thisTrackAddressMarks[s]); currentSector++; if (thisTrackSectors[s].Length > imageInfo.SectorSize) { imageInfo.SectorSize = (uint)thisTrackSectors[s].Length; } } stream.Seek(trackPos, SeekOrigin.Begin); if (extended) { stream.Seek(header.tracksizeTable[i * header.sides + j] * 256, SeekOrigin.Current); imageInfo.ImageSize += (ulong)(header.tracksizeTable[i * header.sides + j] * 256) - 256; } else { stream.Seek(header.tracksize, SeekOrigin.Current); imageInfo.ImageSize += (ulong)header.tracksize - 256; } readtracks++; } } DicConsole.DebugWriteLine("CPCDSK plugin", "Read {0} sectors", sectors.Count); DicConsole.DebugWriteLine("CPCDSK plugin", "Read {0} tracks", readtracks); DicConsole.DebugWriteLine("CPCDSK plugin", "All tracks are same size? {0}", allTracksSameSize); imageInfo.Application = StringHandlers.CToString(header.creator); imageInfo.CreationTime = imageFilter.GetCreationTime(); imageInfo.LastModificationTime = imageFilter.GetLastWriteTime(); imageInfo.MediaTitle = Path.GetFileNameWithoutExtension(imageFilter.GetFilename()); imageInfo.Sectors = (ulong)sectors.Count; imageInfo.XmlMediaType = XmlMediaType.BlockMedia; imageInfo.MediaType = MediaType.CompactFloppy; imageInfo.ReadableSectorTags.Add(SectorTagType.FloppyAddressMark); // Debug writing full disk as raw /* * FileStream foo = new FileStream(Path.GetFileNameWithoutExtension(imageFilter.GetFilename()) + ".bin", FileMode.Create); * for(ulong i = 0; i < (ulong)sectors.Count; i++) * { * byte[] foob; * sectors.TryGetValue(i, out foob); * foo.Write(foob, 0, foob.Length); * } * foo.Close(); */ imageInfo.Cylinders = header.tracks; imageInfo.Heads = header.sides; imageInfo.SectorsPerTrack = (uint)(imageInfo.Sectors / (imageInfo.Cylinders * imageInfo.Heads)); return(true); }