Beispiel #1
0
        public bool Identify(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);
            IntPtr headerPtr = Marshal.AllocHGlobal(256);

            Marshal.Copy(headerB, 0, headerPtr, 256);
            CpcDiskInfo header = (CpcDiskInfo)Marshal.PtrToStructure(headerPtr, typeof(CpcDiskInfo));

            Marshal.FreeHGlobal(headerPtr);

            DicConsole.DebugWriteLine("CPCDSK plugin", "header.magic = \"{0}\"",
                                      StringHandlers.CToString(header.magic));

            return(cpcdskId.SequenceEqual(header.magic) || edskId.SequenceEqual(header.magic) ||
                   du54Id.SequenceEqual(header.magic));
        }
Beispiel #2
0
        public bool Identify(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);

            AaruConsole.DebugWriteLine("CPCDSK plugin", "header.magic = \"{0}\"",
                                       StringHandlers.CToString(header.magic));

            return(cpcdskId.SequenceEqual(header.magic.Take(cpcdskId.Length)) || edskId.SequenceEqual(header.magic) ||
                   du54Id.SequenceEqual(header.magic));
        }
Beispiel #3
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.Take(_cpcdskId.Length)) &&
                !_edskId.SequenceEqual(header.magic) &&
                !_du54Id.SequenceEqual(header.magic))
            {
                return(false);
            }

            _extended = _edskId.SequenceEqual(header.magic);
            AaruConsole.DebugWriteLine("CPCDSK plugin", "Extended = {0}", _extended);

            AaruConsole.DebugWriteLine("CPCDSK plugin", "header.magic = \"{0}\"",
                                       StringHandlers.CToString(header.magic));

            AaruConsole.DebugWriteLine("CPCDSK plugin", "header.magic2 = \"{0}\"",
                                       StringHandlers.CToString(header.magic2));

            AaruConsole.DebugWriteLine("CPCDSK plugin", "header.creator = \"{0}\"",
                                       StringHandlers.CToString(header.creator));

            AaruConsole.DebugWriteLine("CPCDSK plugin", "header.tracks = {0}", header.tracks);
            AaruConsole.DebugWriteLine("CPCDSK plugin", "header.sides = {0}", header.sides);

            if (!_extended)
            {
                AaruConsole.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++)
                    {
                        AaruConsole.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))
                    {
                        AaruConsole.ErrorWriteLine("Not the expected track info.");

                        return(false);
                    }

                    AaruConsole.DebugWriteLine("CPCDSK plugin", "trackInfo[{1}:{2}].magic = \"{0}\"",
                                               StringHandlers.CToString(trackInfo.magic), i, j);

                    AaruConsole.DebugWriteLine("CPCDSK plugin", "trackInfo[{1}:{2}].bps = {0}",
                                               SizeCodeToBytes(trackInfo.bps), i, j);

                    AaruConsole.DebugWriteLine("CPCDSK plugin", "trackInfo[{1}:{2}].dataRate = {0}", trackInfo.dataRate,
                                               i, j);

                    AaruConsole.DebugWriteLine("CPCDSK plugin", "trackInfo[{1}:{2}].filler = 0x{0:X2}",
                                               trackInfo.filler, i, j);

                    AaruConsole.DebugWriteLine("CPCDSK plugin", "trackInfo[{1}:{2}].gap3 = 0x{0:X2}", trackInfo.gap3, i,
                                               j);

                    AaruConsole.DebugWriteLine("CPCDSK plugin", "trackInfo[{1}:{2}].padding = {0}", trackInfo.padding,
                                               i, j);

                    AaruConsole.DebugWriteLine("CPCDSK plugin", "trackInfo[{1}:{2}].recordingMode = {0}",
                                               trackInfo.recordingMode, i, j);

                    AaruConsole.DebugWriteLine("CPCDSK plugin", "trackInfo[{1}:{2}].sectors = {0}", trackInfo.sectors,
                                               i, j);

                    AaruConsole.DebugWriteLine("CPCDSK plugin", "trackInfo[{1}:{2}].side = {0}", trackInfo.side, i, j);

                    AaruConsole.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++)
                    {
                        AaruConsole.DebugWriteLine("CPCDSK plugin", "trackInfo[{1}:{2}].sector[{3}].id = 0x{0:X2}",
                                                   trackInfo.sectorsInfo[k - 1].id, i, j, k);

                        AaruConsole.DebugWriteLine("CPCDSK plugin", "trackInfo[{1}:{2}].sector[{3}].len = {0}",
                                                   trackInfo.sectorsInfo[k - 1].len, i, j, k);

                        AaruConsole.DebugWriteLine("CPCDSK plugin", "trackInfo[{1}:{2}].sector[{3}].side = {0}",
                                                   trackInfo.sectorsInfo[k - 1].side, i, j, k);

                        AaruConsole.DebugWriteLine("CPCDSK plugin", "trackInfo[{1}:{2}].sector[{3}].size = {0}",
                                                   SizeCodeToBytes(trackInfo.sectorsInfo[k - 1].size), i, j, k);

                        AaruConsole.DebugWriteLine("CPCDSK plugin", "trackInfo[{1}:{2}].sector[{3}].st1 = 0x{0:X2}",
                                                   trackInfo.sectorsInfo[k - 1].st1, i, j, k);

                        AaruConsole.DebugWriteLine("CPCDSK plugin", "trackInfo[{1}:{2}].sector[{3}].st2 = 0x{0:X2}",
                                                   trackInfo.sectorsInfo[k - 1].st2, i, j, k);

                        AaruConsole.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;

                        CRC16IBMContext.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++;
                }
            }

            AaruConsole.DebugWriteLine("CPCDSK plugin", "Read {0} sectors", _sectors.Count);
            AaruConsole.DebugWriteLine("CPCDSK plugin", "Read {0} tracks", readtracks);
            AaruConsole.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);
        }