Example #1
0
 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);
 }
Example #2
0
        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);
        }