diff --git a/.idea/.idea.DiscImageChef/.idea/contentModel.xml b/.idea/.idea.DiscImageChef/.idea/contentModel.xml index ddb16a0c..32861038 100644 --- a/.idea/.idea.DiscImageChef/.idea/contentModel.xml +++ b/.idea/.idea.DiscImageChef/.idea/contentModel.xml @@ -72,6 +72,7 @@ + @@ -80,6 +81,7 @@ + diff --git a/DiscImageChef.CommonTypes/DiscImageChef.CommonTypes.csproj b/DiscImageChef.CommonTypes/DiscImageChef.CommonTypes.csproj index f50bbc03..4896d5f1 100644 --- a/DiscImageChef.CommonTypes/DiscImageChef.CommonTypes.csproj +++ b/DiscImageChef.CommonTypes/DiscImageChef.CommonTypes.csproj @@ -1,4 +1,4 @@ - + Debug @@ -32,8 +32,12 @@ + + ..\packages\System.ValueTuple.4.4.0\lib\portable-net40+sl4+win8+wp8\System.ValueTuple.dll + + @@ -44,6 +48,9 @@ LICENSE.LGPL + + + diff --git a/DiscImageChef.CommonTypes/Geometry.cs b/DiscImageChef.CommonTypes/Geometry.cs new file mode 100644 index 00000000..e88a2bdd --- /dev/null +++ b/DiscImageChef.CommonTypes/Geometry.cs @@ -0,0 +1,99 @@ +using System.Linq; + +namespace DiscImageChef.CommonTypes +{ + public static class Geometry + { + static readonly (ushort cylinders, byte heads, ushort sectorsPerTrack, uint bytesPerSector, MediaEncoding + encoding, bool variableSectorsPerTrack, MediaType type)[] KnownGeometries = + { + (32, 1, 8, 319, MediaEncoding.FM, false, MediaType.IBM23FD), + (35, 1, 9, 256, MediaEncoding.FM, false, MediaType.ECMA_66), + (35, 1, 13, 256, MediaEncoding.AppleGCR, false, MediaType.Apple32SS), + (35, 1, 16, 256, MediaEncoding.AppleGCR, false, MediaType.Apple33SS), + (35, 1, 19, 256, MediaEncoding.CommodoreGCR, false, MediaType.CBM_1540), + (35, 2, 13, 256, MediaEncoding.AppleGCR, false, MediaType.Apple32DS), + (35, 2, 16, 256, MediaEncoding.AppleGCR, false, MediaType.Apple33DS), + (35, 2, 19, 256, MediaEncoding.CommodoreGCR, false, MediaType.CBM_1571), + (40, 1, 8, 512, MediaEncoding.MFM, false, MediaType.DOS_525_SS_DD_8), + (40, 1, 9, 512, MediaEncoding.MFM, false, MediaType.DOS_525_SS_DD_9), + (40, 1, 10, 256, MediaEncoding.FM, false, MediaType.ACORN_525_SS_SD_40), + (40, 1, 16, 256, MediaEncoding.MFM, false, MediaType.ACORN_525_SS_DD_40), + (40, 1, 18, 128, MediaEncoding.FM, false, MediaType.ATARI_525_SD), + (40, 1, 18, 256, MediaEncoding.MFM, false, MediaType.ATARI_525_DD), + (40, 1, 19, 256, MediaEncoding.CommodoreGCR, false, MediaType.CBM_1540_Ext), + (40, 1, 26, 128, MediaEncoding.MFM, false, MediaType.ATARI_525_ED), + (40, 2, 8, 512, MediaEncoding.MFM, false, MediaType.DOS_525_DS_DD_8), + (40, 2, 9, 512, MediaEncoding.MFM, false, MediaType.DOS_525_DS_DD_9), + (40, 2, 16, 256, MediaEncoding.FM, false, MediaType.ECMA_70), + (70, 2, 9, 512, MediaEncoding.MFM, false, MediaType.Apricot_35), + (74, 1, 8, 512, MediaEncoding.FM, false, MediaType.IBM33FD_512), + (74, 1, 15, 256, MediaEncoding.FM, false, MediaType.IBM33FD_256), + (74, 1, 26, 128, MediaEncoding.FM, false, MediaType.IBM33FD_128), + (74, 2, 8, 1024, MediaEncoding.MFM, false, MediaType.IBM53FD_1024), + (74, 2, 15, 256, MediaEncoding.FM, false, MediaType.IBM43FD_256), + (74, 2, 15, 512, MediaEncoding.MFM, false, MediaType.IBM53FD_512), + (74, 2, 26, 128, MediaEncoding.FM, false, MediaType.IBM43FD_128), + (74, 2, 26, 256, MediaEncoding.MFM, false, MediaType.IBM53FD_256), + (77, 1, 26, 128, MediaEncoding.FM, false, MediaType.RX01), + (77, 1, 26, 256, MediaEncoding.MFM, false, MediaType.RX02), + (77, 2, 8, 1024, MediaEncoding.MFM, false, MediaType.NEC_525_HD), + (77, 2, 15, 512, MediaEncoding.MFM, false, MediaType.ECMA_99_15), + (77, 2, 26, 128, MediaEncoding.FM, false, MediaType.NEC_8_SD), + (77, 2, 26, 256, MediaEncoding.MFM, false, MediaType.RX03), + (80, 1, 8, 512, MediaEncoding.MFM, false, MediaType.DOS_35_SS_DD_8), + (80, 1, 9, 512, MediaEncoding.MFM, false, MediaType.DOS_35_SS_DD_9), + (80, 1, 10, 256, MediaEncoding.FM, false, MediaType.ACORN_525_SS_SD_80), + (80, 1, 10, 512, MediaEncoding.AppleGCR, true, MediaType.AppleSonySS), + (80, 1, 10, 512, MediaEncoding.MFM, false, MediaType.RX50), + (80, 1, 11, 512, MediaEncoding.MFM, false, MediaType.ATARI_35_SS_DD_11), + (80, 1, 16, 256, MediaEncoding.MFM, false, MediaType.ACORN_525_SS_DD_80), + (80, 2, 5, 1024, MediaEncoding.MFM, false, MediaType.ACORN_35_DS_DD), + (80, 2, 8, 512, MediaEncoding.MFM, false, MediaType.DOS_35_DS_DD_8), + (80, 2, 9, 512, MediaEncoding.MFM, false, MediaType.DOS_35_DS_DD_9), + (80, 2, 10, 512, MediaEncoding.AppleGCR, true, MediaType.AppleSonyDS), + (80, 2, 10, 512, MediaEncoding.MFM, false, MediaType.CBM_35_DD), + (80, 2, 10, 1024, MediaEncoding.MFM, false, MediaType.ACORN_35_DS_HD), + (80, 2, 11, 512, MediaEncoding.MFM, false, MediaType.CBM_AMIGA_35_DD), + (80, 2, 15, 512, MediaEncoding.MFM, false, MediaType.DOS_525_HD), + (80, 2, 16, 256, MediaEncoding.FM, false, MediaType.ECMA_78), + (80, 2, 16, 256, MediaEncoding.MFM, false, MediaType.ACORN_525_DS_DD), + (80, 2, 18, 512, MediaEncoding.MFM, false, MediaType.DOS_35_HD), + (80, 2, 19, 512, MediaEncoding.MFM, false, MediaType.XDF_525), + (80, 2, 21, 512, MediaEncoding.MFM, false, MediaType.DMF), + (80, 2, 22, 512, MediaEncoding.MFM, false, MediaType.CBM_AMIGA_35_HD), + (80, 2, 23, 512, MediaEncoding.MFM, false, MediaType.XDF_35), + (80, 2, 36, 512, MediaEncoding.MFM, false, MediaType.DOS_35_ED), + (82, 2, 10, 512, MediaEncoding.MFM, false, MediaType.FDFORMAT_35_DD), + (82, 2, 17, 512, MediaEncoding.MFM, false, MediaType.FDFORMAT_525_HD), + (82, 2, 21, 512, MediaEncoding.MFM, false, MediaType.FDFORMAT_35_HD), + (240, 2, 38, 512, MediaEncoding.MFM, false, MediaType.NEC_35_TD), + (652, 2, 0, 512, MediaEncoding.MFM, false, MediaType.Floptical), + // Following ones are what the device itself report, not the physical geometry + (154, 16, 32, 512, MediaEncoding.MFM, false, MediaType.PocketZip), + (262, 32, 56, 512, MediaEncoding.MFM, false, MediaType.LS240), + (963, 8, 32, 512, MediaEncoding.MFM, false, MediaType.LS120), + (1021, 64, 32, 512, MediaEncoding.MFM, false, MediaType.Jaz), + (1024, 2, 32, 512, MediaEncoding.MFM, false, MediaType.FD32MB) + }; + + public static MediaType GetMediaType( + (ushort cylinders, byte heads, ushort sectorsPerTrack, uint bytesPerSector, MediaEncoding encoding, bool + variableSectorsPerTrack) geometry) + { + return (from geom in KnownGeometries + where geom.cylinders == geometry.cylinders && geom.heads == geometry.heads && + geom.sectorsPerTrack == geometry.sectorsPerTrack && + geom.bytesPerSector == geometry.bytesPerSector && + geom.encoding == geometry.encoding && + geom.variableSectorsPerTrack == geometry.variableSectorsPerTrack + select geom.type).FirstOrDefault(); + } + + public static (ushort cylinders, byte heads, ushort sectorsPerTrack, uint bytesPerSector, MediaEncoding encoding + , bool variableSectorsPerTrack, MediaType type) GetGeometry(MediaType mediaType) + { + return (from geom in KnownGeometries where geom.type == mediaType select geom).FirstOrDefault(); + } + } +} \ No newline at end of file diff --git a/DiscImageChef.CommonTypes/MediaType.cs b/DiscImageChef.CommonTypes/MediaType.cs index cfbf0586..a7d8df5d 100644 --- a/DiscImageChef.CommonTypes/MediaType.cs +++ b/DiscImageChef.CommonTypes/MediaType.cs @@ -35,6 +35,16 @@ namespace DiscImageChef.CommonTypes { + public enum MediaEncoding + { + Unknown, + FM, + MFM, + M2FM, + AppleGCR, + CommodoreGCR + } + /// /// Contains an enumeration of all known types of media. /// @@ -293,9 +303,13 @@ namespace DiscImageChef.CommonTypes #endregion Microsoft non standard floppy formats #region IBM non standard floppy formats + /// + /// 5.25", DS, HD, 80 tracks, ? spt, ??? + ??? + ??? bytes/sector, MFM track 0 = ??15 sectors, 512 + /// bytes/sector, falsified to DOS as 19 spt, 512 bps + /// XDF_525, /// - /// 3.5", DS, HD, 80 tracks, 4 spt, 8192 + 2048 + 1024 + 512 bytes/sector, MFMm track 0 = 19 sectors, 512 + /// 3.5", DS, HD, 80 tracks, 4 spt, 8192 + 2048 + 1024 + 512 bytes/sector, MFM track 0 = 19 sectors, 512 /// bytes/sector, falsified to DOS as 23 spt, 512 bps /// XDF_35, diff --git a/DiscImageChef.CommonTypes/packages.config b/DiscImageChef.CommonTypes/packages.config new file mode 100644 index 00000000..57bc9eb2 --- /dev/null +++ b/DiscImageChef.CommonTypes/packages.config @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/DiscImageChef.DiscImages/Anex86.cs b/DiscImageChef.DiscImages/Anex86.cs index 103782fe..921dbf7e 100644 --- a/DiscImageChef.DiscImages/Anex86.cs +++ b/DiscImageChef.DiscImages/Anex86.cs @@ -42,33 +42,33 @@ namespace DiscImageChef.DiscImages { public class Anex86 : IMediaImage { - IFilter anexImageFilter; + IFilter anexImageFilter; Anex86Header fdihdr; - ImageInfo imageInfo; + ImageInfo imageInfo; public Anex86() { imageInfo = new ImageInfo { - ReadableSectorTags = new List(), - ReadableMediaTags = new List(), - HasPartitions = false, - HasSessions = false, - Version = null, - Application = null, - ApplicationVersion = null, - Creator = null, - Comments = null, - MediaManufacturer = null, - MediaModel = null, - MediaSerialNumber = null, - MediaBarcode = null, - MediaPartNumber = null, - MediaSequence = 0, - LastMediaSequence = 0, - DriveManufacturer = null, - DriveModel = null, - DriveSerialNumber = null, + ReadableSectorTags = new List(), + ReadableMediaTags = new List(), + HasPartitions = false, + HasSessions = false, + Version = null, + Application = null, + ApplicationVersion = null, + Creator = null, + Comments = null, + MediaManufacturer = null, + MediaModel = null, + MediaSerialNumber = null, + MediaBarcode = null, + MediaPartNumber = null, + MediaSequence = 0, + LastMediaSequence = 0, + DriveManufacturer = null, + DriveModel = null, + DriveSerialNumber = null, DriveFirmwareRevision = null }; } @@ -76,7 +76,7 @@ namespace DiscImageChef.DiscImages public ImageInfo Info => imageInfo; public string Name => "Anex86 Disk Image"; - public Guid Id => new Guid("0410003E-6E7B-40E6-9328-BA5651ADF6B7"); + public Guid Id => new Guid("0410003E-6E7B-40E6-9328-BA5651ADF6B7"); public string ImageFormat => "Anex86 disk image"; @@ -102,19 +102,19 @@ namespace DiscImageChef.DiscImages stream.Read(hdrB, 0, hdrB.Length); GCHandle handle = GCHandle.Alloc(hdrB, GCHandleType.Pinned); - fdihdr = (Anex86Header)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(Anex86Header)); + fdihdr = (Anex86Header)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(Anex86Header)); handle.Free(); - DicConsole.DebugWriteLine("Anex86 plugin", "fdihdr.unknown = {0}", fdihdr.unknown); - DicConsole.DebugWriteLine("Anex86 plugin", "fdihdr.hddtype = {0}", fdihdr.hddtype); - DicConsole.DebugWriteLine("Anex86 plugin", "fdihdr.hdrSize = {0}", fdihdr.hdrSize); - DicConsole.DebugWriteLine("Anex86 plugin", "fdihdr.dskSize = {0}", fdihdr.dskSize); - DicConsole.DebugWriteLine("Anex86 plugin", "fdihdr.bps = {0}", fdihdr.bps); - DicConsole.DebugWriteLine("Anex86 plugin", "fdihdr.spt = {0}", fdihdr.spt); - DicConsole.DebugWriteLine("Anex86 plugin", "fdihdr.heads = {0}", fdihdr.heads); + DicConsole.DebugWriteLine("Anex86 plugin", "fdihdr.unknown = {0}", fdihdr.unknown); + DicConsole.DebugWriteLine("Anex86 plugin", "fdihdr.hddtype = {0}", fdihdr.hddtype); + DicConsole.DebugWriteLine("Anex86 plugin", "fdihdr.hdrSize = {0}", fdihdr.hdrSize); + DicConsole.DebugWriteLine("Anex86 plugin", "fdihdr.dskSize = {0}", fdihdr.dskSize); + DicConsole.DebugWriteLine("Anex86 plugin", "fdihdr.bps = {0}", fdihdr.bps); + DicConsole.DebugWriteLine("Anex86 plugin", "fdihdr.spt = {0}", fdihdr.spt); + DicConsole.DebugWriteLine("Anex86 plugin", "fdihdr.heads = {0}", fdihdr.heads); DicConsole.DebugWriteLine("Anex86 plugin", "fdihdr.cylinders = {0}", fdihdr.cylinders); - return stream.Length == fdihdr.hdrSize + fdihdr.dskSize && + return stream.Length == fdihdr.hdrSize + fdihdr.dskSize && fdihdr.dskSize == fdihdr.bps * fdihdr.spt * fdihdr.heads * fdihdr.cylinders; } @@ -131,198 +131,26 @@ namespace DiscImageChef.DiscImages stream.Read(hdrB, 0, hdrB.Length); GCHandle handle = GCHandle.Alloc(hdrB, GCHandleType.Pinned); - fdihdr = (Anex86Header)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(Anex86Header)); + fdihdr = (Anex86Header)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(Anex86Header)); handle.Free(); - imageInfo.MediaType = MediaType.GENERIC_HDD; - - switch(fdihdr.cylinders) - { - case 40: - switch(fdihdr.bps) - { - case 512: - switch(fdihdr.spt) - { - case 8: - switch(fdihdr.heads) - { - case 1: - imageInfo.MediaType = MediaType.DOS_525_SS_DD_8; - break; - case 2: - imageInfo.MediaType = MediaType.DOS_525_DS_DD_8; - break; - } - - break; - case 9: - switch(fdihdr.heads) - { - case 1: - imageInfo.MediaType = MediaType.DOS_525_SS_DD_9; - break; - case 2: - imageInfo.MediaType = MediaType.DOS_525_DS_DD_9; - break; - } - - break; - } - - break; - } - - break; - case 70: - switch(fdihdr.bps) - { - case 512: - switch(fdihdr.spt) - { - case 9: - if(fdihdr.heads == 1) imageInfo.MediaType = MediaType.Apricot_35; - break; - } - - break; - } - - break; - case 77: - switch(fdihdr.bps) - { - case 128: - switch(fdihdr.spt) - { - case 26: - if(fdihdr.heads == 2) imageInfo.MediaType = MediaType.NEC_8_SD; - break; - } - - break; - case 256: - switch(fdihdr.spt) - { - case 26: - if(fdihdr.heads == 2) imageInfo.MediaType = MediaType.NEC_8_DD; - break; - } - - break; - case 512: - switch(fdihdr.spt) - { - case 8: - if(fdihdr.heads == 1) imageInfo.MediaType = MediaType.Apricot_35; - break; - } - - break; - case 1024: - switch(fdihdr.spt) - { - case 8: - if(fdihdr.heads == 2) imageInfo.MediaType = MediaType.NEC_525_HD; - break; - } - - break; - } - - break; - case 80: - switch(fdihdr.bps) - { - case 256: - switch(fdihdr.spt) - { - case 16: - switch(fdihdr.heads) - { - case 1: - imageInfo.MediaType = MediaType.NEC_525_SS; - break; - case 2: - imageInfo.MediaType = MediaType.NEC_525_DS; - break; - } - - break; - } - - break; - case 512: - switch(fdihdr.spt) - { - case 8: - switch(fdihdr.heads) - { - case 1: - imageInfo.MediaType = MediaType.DOS_35_SS_DD_8; - break; - case 2: - imageInfo.MediaType = MediaType.DOS_35_DS_DD_8; - break; - } - - break; - case 9: - switch(fdihdr.heads) - { - case 1: - imageInfo.MediaType = MediaType.DOS_35_SS_DD_9; - break; - case 2: - imageInfo.MediaType = MediaType.DOS_35_DS_DD_9; - break; - } - - break; - case 15: - if(fdihdr.heads == 2) imageInfo.MediaType = MediaType.NEC_35_HD_15; - break; - case 18: - if(fdihdr.heads == 2) imageInfo.MediaType = MediaType.DOS_35_HD; - break; - case 36: - if(fdihdr.heads == 2) imageInfo.MediaType = MediaType.DOS_35_ED; - break; - } - - break; - } - - break; - case 240: - switch(fdihdr.bps) - { - case 512: - switch(fdihdr.spt) - { - case 38: - if(fdihdr.heads == 2) imageInfo.MediaType = MediaType.NEC_35_TD; - break; - } - - break; - } - - break; - } + imageInfo.MediaType = + Geometry.GetMediaType(((ushort)fdihdr.cylinders, (byte)fdihdr.heads, (ushort)fdihdr.spt, + (uint)fdihdr.bps, MediaEncoding.MFM, false)); + if(imageInfo.MediaType == MediaType.Unknown) imageInfo.MediaType = MediaType.GENERIC_HDD; DicConsole.DebugWriteLine("Anex86 plugin", "MediaType: {0}", imageInfo.MediaType); - imageInfo.ImageSize = (ulong)fdihdr.dskSize; - imageInfo.CreationTime = imageFilter.GetCreationTime(); + imageInfo.ImageSize = (ulong)fdihdr.dskSize; + imageInfo.CreationTime = imageFilter.GetCreationTime(); imageInfo.LastModificationTime = imageFilter.GetLastWriteTime(); - imageInfo.MediaTitle = Path.GetFileNameWithoutExtension(imageFilter.GetFilename()); - imageInfo.Sectors = (ulong)(fdihdr.cylinders * fdihdr.heads * fdihdr.spt); - imageInfo.XmlMediaType = XmlMediaType.BlockMedia; - imageInfo.SectorSize = (uint)fdihdr.bps; - imageInfo.Cylinders = (uint)fdihdr.cylinders; - imageInfo.Heads = (uint)fdihdr.heads; - imageInfo.SectorsPerTrack = (uint)fdihdr.spt; + imageInfo.MediaTitle = Path.GetFileNameWithoutExtension(imageFilter.GetFilename()); + imageInfo.Sectors = (ulong)(fdihdr.cylinders * fdihdr.heads * fdihdr.spt); + imageInfo.XmlMediaType = XmlMediaType.BlockMedia; + imageInfo.SectorSize = (uint)fdihdr.bps; + imageInfo.Cylinders = (uint)fdihdr.cylinders; + imageInfo.Heads = (uint)fdihdr.heads; + imageInfo.SectorsPerTrack = (uint)fdihdr.spt; anexImageFilter = imageFilter; @@ -429,7 +257,7 @@ namespace DiscImageChef.DiscImages } public bool? VerifySectors(ulong sectorAddress, uint length, out List failingLbas, - out List unknownLbas) + out List unknownLbas) { failingLbas = new List(); unknownLbas = new List(); @@ -439,7 +267,7 @@ namespace DiscImageChef.DiscImages } public bool? VerifySectors(ulong sectorAddress, uint length, uint track, out List failingLbas, - out List unknownLbas) + out List unknownLbas) { throw new FeatureUnsupportedImageException("Feature not supported by image format"); } diff --git a/DiscImageChef.DiscImages/Apridisk.cs b/DiscImageChef.DiscImages/Apridisk.cs index b3c42911..bd0a12b3 100644 --- a/DiscImageChef.DiscImages/Apridisk.cs +++ b/DiscImageChef.DiscImages/Apridisk.cs @@ -63,25 +63,25 @@ namespace DiscImageChef.DiscImages { imageInfo = new ImageInfo { - ReadableSectorTags = new List(), - ReadableMediaTags = new List(), - HasPartitions = false, - HasSessions = false, - Version = null, - Application = null, - ApplicationVersion = null, - Creator = null, - Comments = null, - MediaManufacturer = null, - MediaModel = null, - MediaSerialNumber = null, - MediaBarcode = null, - MediaPartNumber = null, - MediaSequence = 0, - LastMediaSequence = 0, - DriveManufacturer = null, - DriveModel = null, - DriveSerialNumber = null, + ReadableSectorTags = new List(), + ReadableMediaTags = new List(), + HasPartitions = false, + HasSessions = false, + Version = null, + Application = null, + ApplicationVersion = null, + Creator = null, + Comments = null, + MediaManufacturer = null, + MediaModel = null, + MediaSerialNumber = null, + MediaBarcode = null, + MediaPartNumber = null, + MediaSequence = 0, + LastMediaSequence = 0, + DriveManufacturer = null, + DriveModel = null, + DriveSerialNumber = null, DriveFirmwareRevision = null }; } @@ -89,7 +89,7 @@ namespace DiscImageChef.DiscImages public ImageInfo Info => imageInfo; public string Name => "ACT Apricot Disk Image"; - public Guid Id => new Guid("43408CF3-6DB3-449F-A779-2B0E497C5B14"); + public Guid Id => new Guid("43408CF3-6DB3-449F-A779-2B0E497C5B14"); public string ImageFormat => "ACT Apricot disk image"; @@ -124,9 +124,9 @@ namespace DiscImageChef.DiscImages stream.Seek(signature.Length, SeekOrigin.Begin); int totalCylinders = -1; - int totalHeads = -1; - int maxSector = -1; - int recordSize = Marshal.SizeOf(typeof(ApridiskRecord)); + int totalHeads = -1; + int maxSector = -1; + int recordSize = Marshal.SizeOf(typeof(ApridiskRecord)); // Count cylinders while(stream.Position < stream.Length) @@ -134,7 +134,7 @@ namespace DiscImageChef.DiscImages byte[] recB = new byte[recordSize]; stream.Read(recB, 0, recordSize); - GCHandle handle = GCHandle.Alloc(recB, GCHandleType.Pinned); + GCHandle handle = GCHandle.Alloc(recB, GCHandleType.Pinned); ApridiskRecord record = (ApridiskRecord)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(ApridiskRecord)); handle.Free(); @@ -176,8 +176,8 @@ namespace DiscImageChef.DiscImages : "uncompressed"); if(record.cylinder > totalCylinders) totalCylinders = record.cylinder; - if(record.head > totalHeads) totalHeads = record.head; - if(record.sector > maxSector) maxSector = record.sector; + if(record.head > totalHeads) totalHeads = record.head; + if(record.sector > maxSector) maxSector = record.sector; stream.Seek(record.headerSize - recordSize + record.dataSize, SeekOrigin.Current); break; @@ -198,7 +198,7 @@ namespace DiscImageChef.DiscImages uint[][] spts = new uint[totalCylinders][]; imageInfo.Cylinders = (ushort)totalCylinders; - imageInfo.Heads = (byte)totalHeads; + imageInfo.Heads = (byte)totalHeads; DicConsole.DebugWriteLine("Apridisk plugin", "Found {0} cylinders and {1} heads with a maximum sector number of {2}", @@ -208,7 +208,7 @@ namespace DiscImageChef.DiscImages for(int i = 0; i < totalCylinders; i++) { sectorsData[i] = new byte[totalHeads][][]; - spts[i] = new uint[totalHeads]; + spts[i] = new uint[totalHeads]; for(int j = 0; j < totalHeads; j++) sectorsData[i][j] = new byte[maxSector + 1][]; } @@ -224,7 +224,7 @@ namespace DiscImageChef.DiscImages byte[] recB = new byte[recordSize]; stream.Read(recB, 0, recordSize); - GCHandle handle = GCHandle.Alloc(recB, GCHandleType.Pinned); + GCHandle handle = GCHandle.Alloc(recB, GCHandleType.Pinned); ApridiskRecord record = (ApridiskRecord)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(ApridiskRecord)); handle.Free(); @@ -235,7 +235,7 @@ namespace DiscImageChef.DiscImages case RecordType.Deleted: case RecordType.Comment: case RecordType.Creator: - stream.Seek(record.headerSize - recordSize + record.dataSize, SeekOrigin.Current); + stream.Seek(record.headerSize - recordSize + record.dataSize, SeekOrigin.Current); headersizes += record.headerSize + record.dataSize; break; case RecordType.Sector: @@ -248,7 +248,8 @@ namespace DiscImageChef.DiscImages uint realLength = record.dataSize; if(record.compression == CompressType.Compressed) - realLength = Decompress(data, out sectorsData[record.cylinder][record.head][record.sector]); + realLength = + Decompress(data, out sectorsData[record.cylinder][record.head][record.sector]); else sectorsData[record.cylinder][record.head][record.sector] = data; if(realLength < imageInfo.SectorSize) imageInfo.SectorSize = realLength; @@ -266,7 +267,9 @@ namespace DiscImageChef.DiscImages uint spt = uint.MaxValue; for(ushort cyl = 0; cyl < imageInfo.Cylinders; cyl++) { - for(ushort head = 0; head < imageInfo.Heads; head++) if(spts[cyl][head] < spt) spt = spts[cyl][head]; + for(ushort head = 0; head < imageInfo.Heads; head++) + if(spts[cyl][head] < spt) + spt = spts[cyl][head]; } imageInfo.SectorsPerTrack = spt; @@ -274,19 +277,16 @@ namespace DiscImageChef.DiscImages DicConsole.DebugWriteLine("Apridisk plugin", "Found a minimum of {0} sectors per track", imageInfo.SectorsPerTrack); - if(imageInfo.Cylinders == 70 && imageInfo.Heads == 1 && imageInfo.SectorsPerTrack == 9) - imageInfo.MediaType = MediaType.Apricot_35; - else if(imageInfo.Cylinders == 80 && imageInfo.Heads == 1 && imageInfo.SectorsPerTrack == 9) - imageInfo.MediaType = MediaType.DOS_35_SS_DD_9; - else if(imageInfo.Cylinders == 80 && imageInfo.Heads == 2 && imageInfo.SectorsPerTrack == 9) - imageInfo.MediaType = MediaType.DOS_35_DS_DD_9; + imageInfo.MediaType = + Geometry.GetMediaType(((ushort)imageInfo.Cylinders, (byte)imageInfo.Heads, + (ushort)imageInfo.SectorsPerTrack, 512, MediaEncoding.MFM, false)); - imageInfo.ImageSize = (ulong)stream.Length - headersizes; - imageInfo.CreationTime = imageFilter.GetCreationTime(); + imageInfo.ImageSize = (ulong)stream.Length - headersizes; + imageInfo.CreationTime = imageFilter.GetCreationTime(); imageInfo.LastModificationTime = imageFilter.GetLastWriteTime(); - imageInfo.MediaTitle = Path.GetFileNameWithoutExtension(imageFilter.GetFilename()); - imageInfo.Sectors = imageInfo.Cylinders * imageInfo.Heads * imageInfo.SectorsPerTrack; - imageInfo.XmlMediaType = XmlMediaType.BlockMedia; + imageInfo.MediaTitle = Path.GetFileNameWithoutExtension(imageFilter.GetFilename()); + imageInfo.Sectors = imageInfo.Cylinders * imageInfo.Heads * imageInfo.SectorsPerTrack; + imageInfo.XmlMediaType = XmlMediaType.BlockMedia; /* FileStream debugFs = new FileStream("debug.img", FileMode.CreateNew, FileAccess.Write); @@ -298,30 +298,6 @@ namespace DiscImageChef.DiscImages return true; } - static uint Decompress(byte[] compressed, out byte[] decompressed) - { - int readp = 0; - int cLen = compressed.Length; - MemoryStream buffer = new MemoryStream(); - - uint uLen = 0; - - while(cLen >= 3) - { - ushort blklen = BitConverter.ToUInt16(compressed, readp); - readp += 2; - - for(int i = 0; i < blklen; i++) buffer.WriteByte(compressed[readp]); - - uLen += blklen; - readp++; - cLen -= 3; - } - - decompressed = buffer.ToArray(); - return uLen; - } - public byte[] ReadSector(ulong sectorAddress) { (ushort cylinder, byte head, byte sector) = LbaToChs(sectorAddress); @@ -356,15 +332,6 @@ namespace DiscImageChef.DiscImages return buffer.ToArray(); } - (ushort cylinder, byte head, byte sector) LbaToChs(ulong lba) - { - ushort cylinder = (ushort)(lba / (imageInfo.Heads * imageInfo.SectorsPerTrack)); - byte head = (byte)(lba / imageInfo.SectorsPerTrack % imageInfo.Heads); - byte sector = (byte)(lba % imageInfo.SectorsPerTrack + 1); - - return (cylinder, head, sector); - } - public byte[] ReadDiskTag(MediaTagType tag) { throw new FeatureUnsupportedImageException("Feature not supported by image format"); @@ -441,7 +408,7 @@ namespace DiscImageChef.DiscImages } public bool? VerifySectors(ulong sectorAddress, uint length, out List failingLbas, - out List unknownLbas) + out List unknownLbas) { failingLbas = new List(); unknownLbas = new List(); @@ -451,7 +418,7 @@ namespace DiscImageChef.DiscImages } public bool? VerifySectors(ulong sectorAddress, uint length, uint track, out List failingLbas, - out List unknownLbas) + out List unknownLbas) { throw new FeatureUnsupportedImageException("Feature not supported by image format"); } @@ -461,10 +428,43 @@ namespace DiscImageChef.DiscImages return null; } + static uint Decompress(byte[] compressed, out byte[] decompressed) + { + int readp = 0; + int cLen = compressed.Length; + MemoryStream buffer = new MemoryStream(); + + uint uLen = 0; + + while(cLen >= 3) + { + ushort blklen = BitConverter.ToUInt16(compressed, readp); + readp += 2; + + for(int i = 0; i < blklen; i++) buffer.WriteByte(compressed[readp]); + + uLen += blklen; + readp++; + cLen -= 3; + } + + decompressed = buffer.ToArray(); + return uLen; + } + + (ushort cylinder, byte head, byte sector) LbaToChs(ulong lba) + { + ushort cylinder = (ushort)(lba / (imageInfo.Heads * imageInfo.SectorsPerTrack)); + byte head = (byte)(lba / imageInfo.SectorsPerTrack % imageInfo.Heads); + byte sector = (byte)(lba % imageInfo.SectorsPerTrack + 1); + + return (cylinder, head, sector); + } + enum RecordType : uint { Deleted = 0xE31D0000, - Sector = 0xE31D0001, + Sector = 0xE31D0001, Comment = 0xE31D0002, Creator = 0xE31D0003 } @@ -472,19 +472,19 @@ namespace DiscImageChef.DiscImages enum CompressType : ushort { Uncompresed = 0x9E90, - Compressed = 0x3E5A + Compressed = 0x3E5A } [StructLayout(LayoutKind.Sequential, Pack = 1)] struct ApridiskRecord { - public RecordType type; + public RecordType type; public CompressType compression; - public ushort headerSize; - public uint dataSize; - public byte head; - public byte sector; - public ushort cylinder; + public ushort headerSize; + public uint dataSize; + public byte head; + public byte sector; + public ushort cylinder; } } } \ No newline at end of file diff --git a/DiscImageChef.DiscImages/CopyQM.cs b/DiscImageChef.DiscImages/CopyQM.cs index 7d92e73c..bccec32e 100644 --- a/DiscImageChef.DiscImages/CopyQM.cs +++ b/DiscImageChef.DiscImages/CopyQM.cs @@ -43,17 +43,17 @@ namespace DiscImageChef.DiscImages public class CopyQm : IMediaImage { const ushort COPYQM_MAGIC = 0x5143; - const byte COPYQM_MARK = 0x14; + const byte COPYQM_MARK = 0x14; - const byte COPYQM_FAT = 0; + const byte COPYQM_FAT = 0; const byte COPYQM_BLIND = 1; - const byte COPYQM_HFS = 2; + const byte COPYQM_HFS = 2; const byte COPYQM_525_DD = 1; const byte COPYQM_525_HD = 2; - const byte COPYQM_35_DD = 3; - const byte COPYQM_35_HD = 4; - const byte COPYQM_35_ED = 6; + const byte COPYQM_35_DD = 3; + const byte COPYQM_35_HD = 4; + const byte COPYQM_35_ED = 6; readonly uint[] copyQmCrcTable = { @@ -87,38 +87,38 @@ namespace DiscImageChef.DiscImages 0x24B4A3A6, 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF, 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D }; - uint calculatedDataCrc; - byte[] decodedDisk; + uint calculatedDataCrc; + byte[] decodedDisk; MemoryStream decodedImage; CopyQmHeader header; - bool headerChecksumOk; + bool headerChecksumOk; ImageInfo imageInfo; public CopyQm() { imageInfo = new ImageInfo { - ReadableSectorTags = new List(), - ReadableMediaTags = new List(), - HasPartitions = false, - HasSessions = false, - Version = null, - Application = null, - ApplicationVersion = null, - Creator = null, - Comments = null, - MediaManufacturer = null, - MediaModel = null, - MediaSerialNumber = null, - MediaBarcode = null, - MediaPartNumber = null, - MediaSequence = 0, - LastMediaSequence = 0, - DriveManufacturer = null, - DriveModel = null, - DriveSerialNumber = null, + ReadableSectorTags = new List(), + ReadableMediaTags = new List(), + HasPartitions = false, + HasSessions = false, + Version = null, + Application = null, + ApplicationVersion = null, + Creator = null, + Comments = null, + MediaManufacturer = null, + MediaModel = null, + MediaSerialNumber = null, + MediaBarcode = null, + MediaPartNumber = null, + MediaSequence = 0, + LastMediaSequence = 0, + DriveManufacturer = null, + DriveModel = null, + DriveSerialNumber = null, DriveFirmwareRevision = null }; } @@ -126,7 +126,7 @@ namespace DiscImageChef.DiscImages public ImageInfo Info => imageInfo; public string Name => "Sydex CopyQM"; - public Guid Id => new Guid("147E927D-3A92-4E0C-82CD-142F5A4FA76D"); + public Guid Id => new Guid("147E927D-3A92-4E0C-82CD-142F5A4FA76D"); public string ImageFormat => "Sydex CopyQM"; @@ -161,46 +161,46 @@ namespace DiscImageChef.DiscImages byte[] hdr = new byte[133]; stream.Read(hdr, 0, 133); - header = new CopyQmHeader(); + header = new CopyQmHeader(); IntPtr hdrPtr = Marshal.AllocHGlobal(133); Marshal.Copy(hdr, 0, hdrPtr, 133); header = (CopyQmHeader)Marshal.PtrToStructure(hdrPtr, typeof(CopyQmHeader)); Marshal.FreeHGlobal(hdrPtr); - DicConsole.DebugWriteLine("CopyQM plugin", "header.magic = 0x{0:X4}", header.magic); - DicConsole.DebugWriteLine("CopyQM plugin", "header.mark = 0x{0:X2}", header.mark); - DicConsole.DebugWriteLine("CopyQM plugin", "header.sectorSize = {0}", header.sectorSize); + DicConsole.DebugWriteLine("CopyQM plugin", "header.magic = 0x{0:X4}", header.magic); + DicConsole.DebugWriteLine("CopyQM plugin", "header.mark = 0x{0:X2}", header.mark); + DicConsole.DebugWriteLine("CopyQM plugin", "header.sectorSize = {0}", header.sectorSize); DicConsole.DebugWriteLine("CopyQM plugin", "header.sectorPerCluster = {0}", header.sectorPerCluster); - DicConsole.DebugWriteLine("CopyQM plugin", "header.reservedSectors = {0}", header.reservedSectors); - DicConsole.DebugWriteLine("CopyQM plugin", "header.fatCopy = {0}", header.fatCopy); - DicConsole.DebugWriteLine("CopyQM plugin", "header.rootEntries = {0}", header.rootEntries); - DicConsole.DebugWriteLine("CopyQM plugin", "header.sectors = {0}", header.sectors); - DicConsole.DebugWriteLine("CopyQM plugin", "header.mediaType = 0x{0:X2}", header.mediaType); - DicConsole.DebugWriteLine("CopyQM plugin", "header.sectorsPerFat = {0}", header.sectorsPerFat); - DicConsole.DebugWriteLine("CopyQM plugin", "header.sectorsPerTrack = {0}", header.sectorsPerTrack); - DicConsole.DebugWriteLine("CopyQM plugin", "header.heads = {0}", header.heads); - DicConsole.DebugWriteLine("CopyQM plugin", "header.hidden = {0}", header.hidden); - DicConsole.DebugWriteLine("CopyQM plugin", "header.sectorsBig = {0}", header.sectorsBig); - DicConsole.DebugWriteLine("CopyQM plugin", "header.description = {0}", header.description); - DicConsole.DebugWriteLine("CopyQM plugin", "header.blind = {0}", header.blind); - DicConsole.DebugWriteLine("CopyQM plugin", "header.density = {0}", header.density); - DicConsole.DebugWriteLine("CopyQM plugin", "header.imageCylinders = {0}", header.imageCylinders); - DicConsole.DebugWriteLine("CopyQM plugin", "header.totalCylinders = {0}", header.totalCylinders); - DicConsole.DebugWriteLine("CopyQM plugin", "header.crc = 0x{0:X8}", header.crc); - DicConsole.DebugWriteLine("CopyQM plugin", "header.volumeLabel = {0}", header.volumeLabel); - DicConsole.DebugWriteLine("CopyQM plugin", "header.time = 0x{0:X4}", header.time); - DicConsole.DebugWriteLine("CopyQM plugin", "header.date = 0x{0:X4}", header.date); - DicConsole.DebugWriteLine("CopyQM plugin", "header.commentLength = {0}", header.commentLength); - DicConsole.DebugWriteLine("CopyQM plugin", "header.secbs = {0}", header.secbs); - DicConsole.DebugWriteLine("CopyQM plugin", "header.unknown = 0x{0:X4}", header.unknown); - DicConsole.DebugWriteLine("CopyQM plugin", "header.interleave = {0}", header.interleave); - DicConsole.DebugWriteLine("CopyQM plugin", "header.skew = {0}", header.skew); - DicConsole.DebugWriteLine("CopyQM plugin", "header.drive = {0}", header.drive); + DicConsole.DebugWriteLine("CopyQM plugin", "header.reservedSectors = {0}", header.reservedSectors); + DicConsole.DebugWriteLine("CopyQM plugin", "header.fatCopy = {0}", header.fatCopy); + DicConsole.DebugWriteLine("CopyQM plugin", "header.rootEntries = {0}", header.rootEntries); + DicConsole.DebugWriteLine("CopyQM plugin", "header.sectors = {0}", header.sectors); + DicConsole.DebugWriteLine("CopyQM plugin", "header.mediaType = 0x{0:X2}", header.mediaType); + DicConsole.DebugWriteLine("CopyQM plugin", "header.sectorsPerFat = {0}", header.sectorsPerFat); + DicConsole.DebugWriteLine("CopyQM plugin", "header.sectorsPerTrack = {0}", header.sectorsPerTrack); + DicConsole.DebugWriteLine("CopyQM plugin", "header.heads = {0}", header.heads); + DicConsole.DebugWriteLine("CopyQM plugin", "header.hidden = {0}", header.hidden); + DicConsole.DebugWriteLine("CopyQM plugin", "header.sectorsBig = {0}", header.sectorsBig); + DicConsole.DebugWriteLine("CopyQM plugin", "header.description = {0}", header.description); + DicConsole.DebugWriteLine("CopyQM plugin", "header.blind = {0}", header.blind); + DicConsole.DebugWriteLine("CopyQM plugin", "header.density = {0}", header.density); + DicConsole.DebugWriteLine("CopyQM plugin", "header.imageCylinders = {0}", header.imageCylinders); + DicConsole.DebugWriteLine("CopyQM plugin", "header.totalCylinders = {0}", header.totalCylinders); + DicConsole.DebugWriteLine("CopyQM plugin", "header.crc = 0x{0:X8}", header.crc); + DicConsole.DebugWriteLine("CopyQM plugin", "header.volumeLabel = {0}", header.volumeLabel); + DicConsole.DebugWriteLine("CopyQM plugin", "header.time = 0x{0:X4}", header.time); + DicConsole.DebugWriteLine("CopyQM plugin", "header.date = 0x{0:X4}", header.date); + DicConsole.DebugWriteLine("CopyQM plugin", "header.commentLength = {0}", header.commentLength); + DicConsole.DebugWriteLine("CopyQM plugin", "header.secbs = {0}", header.secbs); + DicConsole.DebugWriteLine("CopyQM plugin", "header.unknown = 0x{0:X4}", header.unknown); + DicConsole.DebugWriteLine("CopyQM plugin", "header.interleave = {0}", header.interleave); + DicConsole.DebugWriteLine("CopyQM plugin", "header.skew = {0}", header.skew); + DicConsole.DebugWriteLine("CopyQM plugin", "header.drive = {0}", header.drive); byte[] cmt = new byte[header.commentLength]; stream.Read(cmt, 0, header.commentLength); imageInfo.Comments = StringHandlers.CToString(cmt); - decodedImage = new MemoryStream(); + decodedImage = new MemoryStream(); calculatedDataCrc = 0; @@ -213,7 +213,7 @@ namespace DiscImageChef.DiscImages if(runLength < 0) { - byte repeatedByte = (byte)stream.ReadByte(); + byte repeatedByte = (byte)stream.ReadByte(); byte[] repeatedArray = new byte[runLength * -1]; ArrayHelpers.ArrayFill(repeatedArray, repeatedByte); @@ -253,7 +253,7 @@ namespace DiscImageChef.DiscImages debugStream.Close(); */ - int sum = 0; + int sum = 0; for(int i = 0; i < hdr.Length - 1; i++) sum += hdr[i]; headerChecksumOk = ((-1 * sum) & 0xFF) == header.headerChecksum; @@ -263,90 +263,33 @@ namespace DiscImageChef.DiscImages DicConsole.DebugWriteLine("CopyQM plugin", "Calculated data CRC = 0x{0:X8}, {1}", calculatedDataCrc, calculatedDataCrc == header.crc); - imageInfo.Application = "CopyQM"; - imageInfo.CreationTime = DateHandlers.DosToDateTime(header.date, header.time); + imageInfo.Application = "CopyQM"; + imageInfo.CreationTime = DateHandlers.DosToDateTime(header.date, header.time); imageInfo.LastModificationTime = imageInfo.CreationTime; - imageInfo.MediaTitle = header.volumeLabel; - imageInfo.ImageSize = (ulong)(stream.Length - 133 - header.commentLength); - imageInfo.Sectors = (ulong)sectors; - imageInfo.SectorSize = header.sectorSize; + imageInfo.MediaTitle = header.volumeLabel; + imageInfo.ImageSize = (ulong)(stream.Length - 133 - header.commentLength); + imageInfo.Sectors = (ulong)sectors; + imageInfo.SectorSize = header.sectorSize; - switch(header.drive) + imageInfo.MediaType = + Geometry.GetMediaType(((ushort)header.totalCylinders, (byte)header.heads, header.sectorsPerTrack, + (uint)header.sectorSize, MediaEncoding.MFM, false)); + + switch(imageInfo.MediaType) { - case COPYQM_525_HD: - if(header.heads == 2 && header.totalCylinders == 80 && header.sectorsPerTrack == 15 && - header.sectorSize == 512) imageInfo.MediaType = MediaType.DOS_525_HD; - else if(header.heads == 2 && header.totalCylinders == 80 && header.sectorsPerTrack == 16 && - header.sectorSize == 256) imageInfo.MediaType = MediaType.ACORN_525_DS_DD; - else if(header.heads == 1 && header.totalCylinders == 80 && header.sectorsPerTrack == 16 && - header.sectorSize == 256) imageInfo.MediaType = MediaType.ACORN_525_SS_DD_80; - else if(header.heads == 1 && header.totalCylinders == 80 && header.sectorsPerTrack == 10 && - header.sectorSize == 256) imageInfo.MediaType = MediaType.ACORN_525_SS_SD_80; - else if(header.heads == 2 && header.totalCylinders == 80 && header.sectorsPerTrack == 8 && - header.sectorSize == 1024) imageInfo.MediaType = MediaType.NEC_525_HD; - else if(header.heads == 2 && header.totalCylinders == 77 && header.sectorsPerTrack == 8 && - header.sectorSize == 1024) imageInfo.MediaType = MediaType.SHARP_525; - else goto case COPYQM_525_DD; + case MediaType.NEC_525_HD when header.drive == COPYQM_35_HD ||header.drive == COPYQM_35_ED: + imageInfo.MediaType = MediaType.NEC_35_HD_8; break; - case COPYQM_525_DD: - if(header.heads == 1 && header.totalCylinders == 40 && header.sectorsPerTrack == 8 && - header.sectorSize == 512) imageInfo.MediaType = MediaType.DOS_525_SS_DD_8; - else if(header.heads == 1 && header.totalCylinders == 40 && header.sectorsPerTrack == 9 && - header.sectorSize == 512) imageInfo.MediaType = MediaType.DOS_525_SS_DD_9; - else if(header.heads == 2 && header.totalCylinders == 40 && header.sectorsPerTrack == 8 && - header.sectorSize == 512) imageInfo.MediaType = MediaType.DOS_525_DS_DD_8; - else if(header.heads == 2 && header.totalCylinders == 40 && header.sectorsPerTrack == 9 && - header.sectorSize == 512) imageInfo.MediaType = MediaType.DOS_525_DS_DD_9; - else if(header.heads == 1 && header.totalCylinders == 40 && header.sectorsPerTrack == 18 && - header.sectorSize == 128) imageInfo.MediaType = MediaType.ATARI_525_SD; - else if(header.heads == 1 && header.totalCylinders == 40 && header.sectorsPerTrack == 26 && - header.sectorSize == 128) imageInfo.MediaType = MediaType.ATARI_525_ED; - else if(header.heads == 1 && header.totalCylinders == 40 && header.sectorsPerTrack == 18 && - header.sectorSize == 256) imageInfo.MediaType = MediaType.ATARI_525_DD; - else imageInfo.MediaType = MediaType.Unknown; + case MediaType.DOS_525_HD when header.drive == COPYQM_35_HD ||header.drive == COPYQM_35_ED: + imageInfo.MediaType = MediaType.NEC_35_HD_15; break; - case COPYQM_35_ED: - if(header.heads == 2 && header.totalCylinders == 80 && header.sectorsPerTrack == 36 && - header.sectorSize == 512) imageInfo.MediaType = MediaType.DOS_35_ED; - else goto case COPYQM_35_HD; - break; - case COPYQM_35_HD: - if(header.heads == 2 && header.totalCylinders == 80 && header.sectorsPerTrack == 18 && - header.sectorSize == 512) imageInfo.MediaType = MediaType.DOS_35_HD; - else if(header.heads == 2 && header.totalCylinders == 80 && header.sectorsPerTrack == 21 && - header.sectorSize == 512) imageInfo.MediaType = MediaType.DMF; - else if(header.heads == 2 && header.totalCylinders == 82 && header.sectorsPerTrack == 21 && - header.sectorSize == 512) imageInfo.MediaType = MediaType.DMF_82; - else if(header.heads == 2 && header.totalCylinders == 80 && header.sectorsPerTrack == 8 && - header.sectorSize == 1024) imageInfo.MediaType = MediaType.NEC_35_HD_8; - else if(header.heads == 2 && header.totalCylinders == 80 && header.sectorsPerTrack == 15 && - header.sectorSize == 512) imageInfo.MediaType = MediaType.NEC_35_HD_15; - else goto case COPYQM_35_DD; - break; - case COPYQM_35_DD: - if(header.heads == 2 && header.totalCylinders == 80 && header.sectorsPerTrack == 9 && - header.sectorSize == 512) imageInfo.MediaType = MediaType.DOS_35_DS_DD_9; - else if(header.heads == 2 && header.totalCylinders == 80 && header.sectorsPerTrack == 8 && - header.sectorSize == 512) imageInfo.MediaType = MediaType.DOS_35_DS_DD_8; - else if(header.heads == 1 && header.totalCylinders == 80 && header.sectorsPerTrack == 9 && - header.sectorSize == 512) imageInfo.MediaType = MediaType.DOS_35_SS_DD_9; - else if(header.heads == 1 && header.totalCylinders == 80 && header.sectorsPerTrack == 8 && - header.sectorSize == 512) imageInfo.MediaType = MediaType.DOS_35_SS_DD_8; - else if(header.heads == 2 && header.totalCylinders == 80 && header.sectorsPerTrack == 5 && - header.sectorSize == 1024) imageInfo.MediaType = MediaType.ACORN_35_DS_DD; - else if(header.heads == 2 && header.totalCylinders == 77 && header.sectorsPerTrack == 8 && - header.sectorSize == 1024) imageInfo.MediaType = MediaType.SHARP_35; - else if(header.heads == 1 && header.totalCylinders == 70 && header.sectorsPerTrack == 9 && - header.sectorSize == 512) imageInfo.MediaType = MediaType.Apricot_35; - else imageInfo.MediaType = MediaType.Unknown; - break; - default: - imageInfo.MediaType = MediaType.Unknown; + case MediaType.RX50 when header.drive == COPYQM_525_DD || header.drive == COPYQM_525_HD: + imageInfo.MediaType = MediaType.ATARI_35_SS_DD; break; } imageInfo.XmlMediaType = XmlMediaType.BlockMedia; - decodedDisk = decodedImage.ToArray(); + decodedDisk = decodedImage.ToArray(); decodedImage.Close(); @@ -354,8 +297,8 @@ namespace DiscImageChef.DiscImages if(!string.IsNullOrEmpty(imageInfo.Comments)) DicConsole.VerboseWriteLine("CopyQM comments: {0}", imageInfo.Comments); - imageInfo.Heads = header.heads; - imageInfo.Cylinders = header.imageCylinders; + imageInfo.Heads = header.heads; + imageInfo.Cylinders = header.totalCylinders; imageInfo.SectorsPerTrack = header.sectorsPerTrack; return true; @@ -372,7 +315,7 @@ namespace DiscImageChef.DiscImages } public bool? VerifySectors(ulong sectorAddress, uint length, out List failingLbas, - out List unknownLbas) + out List unknownLbas) { failingLbas = new List(); unknownLbas = new List(); @@ -383,7 +326,7 @@ namespace DiscImageChef.DiscImages } public bool? VerifySectors(ulong sectorAddress, uint length, uint track, out List failingLbas, - out List unknownLbas) + out List unknownLbas) { failingLbas = new List(); unknownLbas = new List(); @@ -414,7 +357,7 @@ namespace DiscImageChef.DiscImages byte[] buffer = new byte[length * imageInfo.SectorSize]; Array.Copy(decodedDisk, (int)sectorAddress * imageInfo.SectorSize, buffer, 0, - length * imageInfo.SectorSize); + length * imageInfo.SectorSize); return buffer; } @@ -516,7 +459,8 @@ namespace DiscImageChef.DiscImages /// 0x18 Sectors on disk (part of FAT's BPB) public uint sectorsBig; /// 0x1C Description - [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 60)] public string description; + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 60)] + public string description; /// 0x58 Blind mode. 0 = DOS, 1 = blind, 2 = HFS public byte blind; /// 0x59 Density. 0 = Double, 1 = High, 2 = Quad/Extra @@ -528,7 +472,8 @@ namespace DiscImageChef.DiscImages /// 0x5C CRC32 of data public uint crc; /// 0x60 DOS volume label - [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 11)] public string volumeLabel; + [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 11)] + public string volumeLabel; /// 0x6B Modification time public ushort time; /// 0x6D Modification date @@ -546,7 +491,8 @@ namespace DiscImageChef.DiscImages /// 0x76 Source drive type. 1 = 5.25" DD, 2 = 5.25" HD, 3 = 3.5" DD, 4 = 3.5" HD, 6 = 3.5" ED public byte drive; /// 0x77 Filling bytes - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 13)] public byte[] fill; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 13)] + public byte[] fill; /// 0x84 Header checksum public byte headerChecksum; } diff --git a/DiscImageChef.DiscImages/D88.cs b/DiscImageChef.DiscImages/D88.cs index 2f1e4986..60f06870 100644 --- a/DiscImageChef.DiscImages/D88.cs +++ b/DiscImageChef.DiscImages/D88.cs @@ -45,12 +45,13 @@ namespace DiscImageChef.DiscImages { // Information from Quasi88's FORMAT.TXT file // Japanese comments copied from there + // TODO: Solve media types public class D88 : IMediaImage { const byte READ_ONLY = 0x10; readonly byte[] reservedEmpty = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; - ImageInfo imageInfo; + ImageInfo imageInfo; List sectorsData; @@ -58,31 +59,31 @@ namespace DiscImageChef.DiscImages { imageInfo = new ImageInfo { - ReadableSectorTags = new List(), - ReadableMediaTags = new List(), - HasPartitions = false, - HasSessions = false, - Version = null, - Application = null, - ApplicationVersion = null, - Creator = null, - Comments = null, - MediaManufacturer = null, - MediaModel = null, - MediaSerialNumber = null, - MediaBarcode = null, - MediaPartNumber = null, - MediaSequence = 0, - LastMediaSequence = 0, - DriveManufacturer = null, - DriveModel = null, - DriveSerialNumber = null, + ReadableSectorTags = new List(), + ReadableMediaTags = new List(), + HasPartitions = false, + HasSessions = false, + Version = null, + Application = null, + ApplicationVersion = null, + Creator = null, + Comments = null, + MediaManufacturer = null, + MediaModel = null, + MediaSerialNumber = null, + MediaBarcode = null, + MediaPartNumber = null, + MediaSequence = 0, + LastMediaSequence = 0, + DriveManufacturer = null, + DriveModel = null, + DriveSerialNumber = null, DriveFirmwareRevision = null }; } - public string Name => "D88 Disk Image"; - public Guid Id => new Guid("669EDC77-EC41-4720-A88C-49C38CFFBAA0"); + public string Name => "D88 Disk Image"; + public Guid Id => new Guid("669EDC77-EC41-4720-A88C-49C38CFFBAA0"); public ImageInfo Info => imageInfo; public string ImageFormat => "D88 disk image"; @@ -111,7 +112,7 @@ namespace DiscImageChef.DiscImages stream.Read(hdrB, 0, hdrB.Length); GCHandle handle = GCHandle.Alloc(hdrB, GCHandleType.Pinned); - d88Hdr = (D88Header)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(D88Header)); + d88Hdr = (D88Header)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(D88Header)); handle.Free(); DicConsole.DebugWriteLine("D88 plugin", "d88hdr.name = \"{0}\"", @@ -158,7 +159,7 @@ namespace DiscImageChef.DiscImages stream.Read(hdrB, 0, hdrB.Length); GCHandle handle = GCHandle.Alloc(hdrB, GCHandleType.Pinned); - d88Hdr = (D88Header)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(D88Header)); + d88Hdr = (D88Header)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(D88Header)); handle.Free(); DicConsole.DebugWriteLine("D88 plugin", "d88hdr.name = \"{0}\"", @@ -190,7 +191,7 @@ namespace DiscImageChef.DiscImages if(trkCounter == 0) return false; SectorHeader sechdr = new SectorHeader(); - hdrB = new byte[Marshal.SizeOf(sechdr)]; + hdrB = new byte[Marshal.SizeOf(sechdr)]; stream.Seek(d88Hdr.track_table[0], SeekOrigin.Begin); stream.Read(hdrB, 0, hdrB.Length); @@ -198,20 +199,20 @@ namespace DiscImageChef.DiscImages sechdr = (SectorHeader)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(SectorHeader)); handle.Free(); - DicConsole.DebugWriteLine("D88 plugin", "sechdr.c = {0}", sechdr.c); - DicConsole.DebugWriteLine("D88 plugin", "sechdr.h = {0}", sechdr.h); - DicConsole.DebugWriteLine("D88 plugin", "sechdr.r = {0}", sechdr.r); - DicConsole.DebugWriteLine("D88 plugin", "sechdr.n = {0}", sechdr.n); - DicConsole.DebugWriteLine("D88 plugin", "sechdr.spt = {0}", sechdr.spt); - DicConsole.DebugWriteLine("D88 plugin", "sechdr.density = {0}", sechdr.density); + DicConsole.DebugWriteLine("D88 plugin", "sechdr.c = {0}", sechdr.c); + DicConsole.DebugWriteLine("D88 plugin", "sechdr.h = {0}", sechdr.h); + DicConsole.DebugWriteLine("D88 plugin", "sechdr.r = {0}", sechdr.r); + DicConsole.DebugWriteLine("D88 plugin", "sechdr.n = {0}", sechdr.n); + DicConsole.DebugWriteLine("D88 plugin", "sechdr.spt = {0}", sechdr.spt); + DicConsole.DebugWriteLine("D88 plugin", "sechdr.density = {0}", sechdr.density); DicConsole.DebugWriteLine("D88 plugin", "sechdr.deleted_mark = {0}", sechdr.deleted_mark); - DicConsole.DebugWriteLine("D88 plugin", "sechdr.status = {0}", sechdr.status); + DicConsole.DebugWriteLine("D88 plugin", "sechdr.status = {0}", sechdr.status); DicConsole.DebugWriteLine("D88 plugin", "sechdr.size_of_data = {0}", sechdr.size_of_data); - short spt = sechdr.spt; - IBMSectorSizeCode bps = sechdr.n; - bool allEqual = true; - sectorsData = new List(); + short spt = sechdr.spt; + IBMSectorSizeCode bps = sechdr.n; + bool allEqual = true; + sectorsData = new List(); for(int i = 0; i < trkCounter; i++) { @@ -231,7 +232,7 @@ namespace DiscImageChef.DiscImages allEqual = false; } - short maxJ = sechdr.spt; + short maxJ = sechdr.spt; byte[] secB; for(short j = 1; j < maxJ; j++) { @@ -345,81 +346,81 @@ namespace DiscImageChef.DiscImages DicConsole.DebugWriteLine("D88 plugin", "MediaType: {0}", imageInfo.MediaType); - imageInfo.ImageSize = (ulong)d88Hdr.disk_size; - imageInfo.CreationTime = imageFilter.GetCreationTime(); + imageInfo.ImageSize = (ulong)d88Hdr.disk_size; + imageInfo.CreationTime = imageFilter.GetCreationTime(); imageInfo.LastModificationTime = imageFilter.GetLastWriteTime(); - imageInfo.MediaTitle = Path.GetFileNameWithoutExtension(imageFilter.GetFilename()); - imageInfo.Sectors = (ulong)sectorsData.Count; - imageInfo.Comments = StringHandlers.CToString(d88Hdr.name, shiftjis); - imageInfo.XmlMediaType = XmlMediaType.BlockMedia; - imageInfo.SectorSize = (uint)(128 << (int)bps); + imageInfo.MediaTitle = Path.GetFileNameWithoutExtension(imageFilter.GetFilename()); + imageInfo.Sectors = (ulong)sectorsData.Count; + imageInfo.Comments = StringHandlers.CToString(d88Hdr.name, shiftjis); + imageInfo.XmlMediaType = XmlMediaType.BlockMedia; + imageInfo.SectorSize = (uint)(128 << (int)bps); switch(imageInfo.MediaType) { case MediaType.NEC_525_SS: - imageInfo.Cylinders = 80; - imageInfo.Heads = 1; + imageInfo.Cylinders = 80; + imageInfo.Heads = 1; imageInfo.SectorsPerTrack = 16; break; case MediaType.NEC_8_SD: case MediaType.NEC_8_DD: - imageInfo.Cylinders = 77; - imageInfo.Heads = 2; + imageInfo.Cylinders = 77; + imageInfo.Heads = 2; imageInfo.SectorsPerTrack = 26; break; case MediaType.NEC_525_DS: - imageInfo.Cylinders = 80; - imageInfo.Heads = 2; + imageInfo.Cylinders = 80; + imageInfo.Heads = 2; imageInfo.SectorsPerTrack = 16; break; case MediaType.NEC_525_HD: - imageInfo.Cylinders = 77; - imageInfo.Heads = 2; + imageInfo.Cylinders = 77; + imageInfo.Heads = 2; imageInfo.SectorsPerTrack = 8; break; case MediaType.DOS_525_SS_DD_8: - imageInfo.Cylinders = 40; - imageInfo.Heads = 1; + imageInfo.Cylinders = 40; + imageInfo.Heads = 1; imageInfo.SectorsPerTrack = 8; break; case MediaType.DOS_525_SS_DD_9: - imageInfo.Cylinders = 40; - imageInfo.Heads = 1; + imageInfo.Cylinders = 40; + imageInfo.Heads = 1; imageInfo.SectorsPerTrack = 9; break; case MediaType.DOS_525_DS_DD_8: - imageInfo.Cylinders = 40; - imageInfo.Heads = 2; + imageInfo.Cylinders = 40; + imageInfo.Heads = 2; imageInfo.SectorsPerTrack = 8; break; case MediaType.DOS_525_DS_DD_9: - imageInfo.Cylinders = 40; - imageInfo.Heads = 2; + imageInfo.Cylinders = 40; + imageInfo.Heads = 2; imageInfo.SectorsPerTrack = 9; break; case MediaType.NEC_35_HD_15: - imageInfo.Cylinders = 80; - imageInfo.Heads = 2; + imageInfo.Cylinders = 80; + imageInfo.Heads = 2; imageInfo.SectorsPerTrack = 15; break; case MediaType.DOS_35_DS_DD_9: - imageInfo.Cylinders = 80; - imageInfo.Heads = 2; + imageInfo.Cylinders = 80; + imageInfo.Heads = 2; imageInfo.SectorsPerTrack = 9; break; case MediaType.DOS_35_HD: - imageInfo.Cylinders = 80; - imageInfo.Heads = 2; + imageInfo.Cylinders = 80; + imageInfo.Heads = 2; imageInfo.SectorsPerTrack = 18; break; case MediaType.DOS_35_ED: - imageInfo.Cylinders = 80; - imageInfo.Heads = 2; + imageInfo.Cylinders = 80; + imageInfo.Heads = 2; imageInfo.SectorsPerTrack = 36; break; case MediaType.NEC_35_TD: - imageInfo.Cylinders = 240; - imageInfo.Heads = 2; + imageInfo.Cylinders = 240; + imageInfo.Heads = 2; imageInfo.SectorsPerTrack = 38; break; } @@ -523,7 +524,7 @@ namespace DiscImageChef.DiscImages } public bool? VerifySectors(ulong sectorAddress, uint length, out List failingLbas, - out List unknownLbas) + out List unknownLbas) { failingLbas = new List(); unknownLbas = new List(); @@ -533,7 +534,7 @@ namespace DiscImageChef.DiscImages } public bool? VerifySectors(ulong sectorAddress, uint length, uint track, out List failingLbas, - out List unknownLbas) + out List unknownLbas) { throw new FeatureUnsupportedImageException("Feature not supported by image format"); } @@ -545,7 +546,7 @@ namespace DiscImageChef.DiscImages enum DiskType : byte { - D2 = 0x00, + D2 = 0x00, Dd2 = 0x10, Hd2 = 0x20 } @@ -553,7 +554,7 @@ namespace DiscImageChef.DiscImages enum DensityType : byte { Mfm = 0x00, - Fm = 0x40 + Fm = 0x40 } /// @@ -601,12 +602,14 @@ namespace DiscImageChef.DiscImages /// Disk name, nul-terminated ASCII /// ディスクの名前(ASCII + '\0') /// - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 17)] public byte[] name; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 17)] + public byte[] name; /// /// Reserved /// ディスクの名前(ASCII + '\0') /// - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 9)] public byte[] reserved; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 9)] + public byte[] reserved; /// /// Write protect status /// ライトプロテクト: 0x00 なし、0x10 あり @@ -626,7 +629,8 @@ namespace DiscImageChef.DiscImages /// Track pointers /// トラック部のオフセットテーブル 0 Track ~ 163 Track /// - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 164)] public int[] track_table; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 164)] + public int[] track_table; } [StructLayout(LayoutKind.Sequential, Pack = 1)] @@ -676,7 +680,8 @@ namespace DiscImageChef.DiscImages /// Reserved /// リザーブ /// - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 5)] public byte[] reserved; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 5)] + public byte[] reserved; /// /// Size of data following this field /// このセクタ部のデータサイズ diff --git a/DiscImageChef.DiscImages/DriDiskCopy.cs b/DiscImageChef.DiscImages/DriDiskCopy.cs index 6b1c6c07..d812ae46 100644 --- a/DiscImageChef.DiscImages/DriDiskCopy.cs +++ b/DiscImageChef.DiscImages/DriDiskCopy.cs @@ -57,23 +57,23 @@ namespace DiscImageChef.DiscImages { imageInfo = new ImageInfo { - ReadableSectorTags = new List(), - ReadableMediaTags = new List(), - HasPartitions = false, - HasSessions = false, - Application = "DiskCopy", - Creator = null, - Comments = null, - MediaManufacturer = null, - MediaModel = null, - MediaSerialNumber = null, - MediaBarcode = null, - MediaPartNumber = null, - MediaSequence = 0, - LastMediaSequence = 0, - DriveManufacturer = null, - DriveModel = null, - DriveSerialNumber = null, + ReadableSectorTags = new List(), + ReadableMediaTags = new List(), + HasPartitions = false, + HasSessions = false, + Application = "DiskCopy", + Creator = null, + Comments = null, + MediaManufacturer = null, + MediaModel = null, + MediaSerialNumber = null, + MediaBarcode = null, + MediaPartNumber = null, + MediaSequence = 0, + LastMediaSequence = 0, + DriveManufacturer = null, + DriveModel = null, + DriveSerialNumber = null, DriveFirmwareRevision = null }; } @@ -81,7 +81,7 @@ namespace DiscImageChef.DiscImages public ImageInfo Info => imageInfo; public string Name => "Digital Research DiskCopy"; - public Guid Id => new Guid("9F0BE551-8BAB-4038-8B5A-691F1BF5FFF3"); + public Guid Id => new Guid("9F0BE551-8BAB-4038-8B5A-691F1BF5FFF3"); public string ImageFormat => "Digital Research DiskCopy"; @@ -112,21 +112,21 @@ namespace DiscImageChef.DiscImages string sig = StringHandlers.CToString(tmpFooter.signature); DicConsole.DebugWriteLine("DRI DiskCopy plugin", "tmp_footer.signature = \"{0}\"", sig); - DicConsole.DebugWriteLine("DRI DiskCopy plugin", "tmp_footer.bpb.five = {0}", tmpFooter.bpb.five); + DicConsole.DebugWriteLine("DRI DiskCopy plugin", "tmp_footer.bpb.five = {0}", tmpFooter.bpb.five); DicConsole.DebugWriteLine("DRI DiskCopy plugin", "tmp_footer.bpb.driveCode = {0}", tmpFooter.bpb.driveCode); - DicConsole.DebugWriteLine("DRI DiskCopy plugin", "tmp_footer.bpb.unknown = {0}", tmpFooter.bpb.unknown); + DicConsole.DebugWriteLine("DRI DiskCopy plugin", "tmp_footer.bpb.unknown = {0}", tmpFooter.bpb.unknown); DicConsole.DebugWriteLine("DRI DiskCopy plugin", "tmp_footer.bpb.cylinders = {0}", tmpFooter.bpb.cylinders); - DicConsole.DebugWriteLine("DRI DiskCopy plugin", "tmp_footer.bpb.unknown2 = {0}", tmpFooter.bpb.unknown2); - DicConsole.DebugWriteLine("DRI DiskCopy plugin", "tmp_footer.bpb.bps = {0}", tmpFooter.bpb.bps); - DicConsole.DebugWriteLine("DRI DiskCopy plugin", "tmp_footer.bpb.spc = {0}", tmpFooter.bpb.spc); - DicConsole.DebugWriteLine("DRI DiskCopy plugin", "tmp_footer.bpb.rsectors = {0}", tmpFooter.bpb.rsectors); - DicConsole.DebugWriteLine("DRI DiskCopy plugin", "tmp_footer.bpb.fats_no = {0}", tmpFooter.bpb.fats_no); - DicConsole.DebugWriteLine("DRI DiskCopy plugin", "tmp_footer.bpb.sectors = {0}", tmpFooter.bpb.sectors); + DicConsole.DebugWriteLine("DRI DiskCopy plugin", "tmp_footer.bpb.unknown2 = {0}", tmpFooter.bpb.unknown2); + DicConsole.DebugWriteLine("DRI DiskCopy plugin", "tmp_footer.bpb.bps = {0}", tmpFooter.bpb.bps); + DicConsole.DebugWriteLine("DRI DiskCopy plugin", "tmp_footer.bpb.spc = {0}", tmpFooter.bpb.spc); + DicConsole.DebugWriteLine("DRI DiskCopy plugin", "tmp_footer.bpb.rsectors = {0}", tmpFooter.bpb.rsectors); + DicConsole.DebugWriteLine("DRI DiskCopy plugin", "tmp_footer.bpb.fats_no = {0}", tmpFooter.bpb.fats_no); + DicConsole.DebugWriteLine("DRI DiskCopy plugin", "tmp_footer.bpb.sectors = {0}", tmpFooter.bpb.sectors); DicConsole.DebugWriteLine("DRI DiskCopy plugin", "tmp_footer.bpb.media_descriptor = {0}", tmpFooter.bpb.media_descriptor); - DicConsole.DebugWriteLine("DRI DiskCopy plugin", "tmp_footer.bpb.spfat = {0}", tmpFooter.bpb.spfat); - DicConsole.DebugWriteLine("DRI DiskCopy plugin", "tmp_footer.bpb.sptrack = {0}", tmpFooter.bpb.sptrack); - DicConsole.DebugWriteLine("DRI DiskCopy plugin", "tmp_footer.bpb.heads = {0}", tmpFooter.bpb.heads); + DicConsole.DebugWriteLine("DRI DiskCopy plugin", "tmp_footer.bpb.spfat = {0}", tmpFooter.bpb.spfat); + DicConsole.DebugWriteLine("DRI DiskCopy plugin", "tmp_footer.bpb.sptrack = {0}", tmpFooter.bpb.sptrack); + DicConsole.DebugWriteLine("DRI DiskCopy plugin", "tmp_footer.bpb.heads = {0}", tmpFooter.bpb.heads); DicConsole.DebugWriteLine("DRI DiskCopy plugin", "tmp_footer.bpb.hsectors = {0}", tmpFooter.bpb.hsectors); DicConsole.DebugWriteLine("DRI DiskCopy plugin", "tmp_footer.bpb.drive_no = {0}", tmpFooter.bpb.drive_no); DicConsole.DebugWriteLine("DRI DiskCopy plugin", "tmp_footer.bpb.unknown3 = {0}", tmpFooter.bpb.unknown3); @@ -159,7 +159,7 @@ namespace DiscImageChef.DiscImages stream.Seek(-buffer.Length, SeekOrigin.End); stream.Read(buffer, 0, buffer.Length); - footer = new DriFooter(); + footer = new DriFooter(); IntPtr ftrPtr = Marshal.AllocHGlobal(buffer.Length); Marshal.Copy(buffer, 0, ftrPtr, buffer.Length); footer = (DriFooter)Marshal.PtrToStructure(ftrPtr, typeof(DriFooter)); @@ -176,98 +176,51 @@ namespace DiscImageChef.DiscImages if(footer.bpb.sectors * footer.bpb.bps + Marshal.SizeOf(footer) != stream.Length) return false; - imageInfo.Cylinders = footer.bpb.cylinders; - imageInfo.Heads = footer.bpb.heads; - imageInfo.SectorsPerTrack = footer.bpb.sptrack; - imageInfo.Sectors = footer.bpb.sectors; - imageInfo.SectorSize = footer.bpb.bps; + imageInfo.Cylinders = footer.bpb.cylinders; + imageInfo.Heads = footer.bpb.heads; + imageInfo.SectorsPerTrack = footer.bpb.sptrack; + imageInfo.Sectors = footer.bpb.sectors; + imageInfo.SectorSize = footer.bpb.bps; imageInfo.ApplicationVersion = matchSignature.Groups["version"].Value; driImageFilter = imageFilter; - imageInfo.ImageSize = (ulong)(stream.Length - Marshal.SizeOf(footer)); - imageInfo.CreationTime = imageFilter.GetCreationTime(); + imageInfo.ImageSize = (ulong)(stream.Length - Marshal.SizeOf(footer)); + imageInfo.CreationTime = imageFilter.GetCreationTime(); imageInfo.LastModificationTime = imageFilter.GetLastWriteTime(); DicConsole.DebugWriteLine("DRI DiskCopy plugin", "Image application = {0} version {1}", imageInfo.Application, imageInfo.ApplicationVersion); // Correct some incorrect data in images of NEC 2HD disks - if(imageInfo.Cylinders == 77 && imageInfo.Heads == 2 && imageInfo.SectorsPerTrack == 16 && - imageInfo.SectorSize == 512 && - (footer.bpb.driveCode == DriDriveCodes.md2hd || footer.bpb.driveCode == DriDriveCodes.mf2hd)) + if(imageInfo.Cylinders == 77 && imageInfo.Heads == 2 && + imageInfo.SectorsPerTrack == 16 && + imageInfo.SectorSize == 512 && + (footer.bpb.driveCode == DriDriveCodes.md2hd || + footer.bpb.driveCode == DriDriveCodes.mf2hd)) { imageInfo.SectorsPerTrack = 8; - imageInfo.SectorSize = 1024; + imageInfo.SectorSize = 1024; } - switch(footer.bpb.driveCode) + imageInfo.MediaType = + Geometry.GetMediaType(((ushort)imageInfo.Cylinders, (byte)imageInfo.Heads, + (ushort)imageInfo.SectorsPerTrack, imageInfo.SectorSize, MediaEncoding.MFM, false + )); + + switch(imageInfo.MediaType) { - case DriDriveCodes.md2hd: - if(imageInfo.Heads == 2 && imageInfo.Cylinders == 80 && imageInfo.SectorsPerTrack == 15 && - imageInfo.SectorSize == 512) imageInfo.MediaType = MediaType.DOS_525_HD; - else if(imageInfo.Heads == 2 && imageInfo.Cylinders == 80 && imageInfo.SectorsPerTrack == 16 && - imageInfo.SectorSize == 256) imageInfo.MediaType = MediaType.ACORN_525_DS_DD; - else if(imageInfo.Heads == 1 && imageInfo.Cylinders == 80 && imageInfo.SectorsPerTrack == 16 && - imageInfo.SectorSize == 256) imageInfo.MediaType = MediaType.ACORN_525_SS_DD_80; - else if(imageInfo.Heads == 1 && imageInfo.Cylinders == 80 && imageInfo.SectorsPerTrack == 10 && - imageInfo.SectorSize == 256) imageInfo.MediaType = MediaType.ACORN_525_SS_SD_80; - else if(imageInfo.Heads == 2 && imageInfo.Cylinders == 77 && imageInfo.SectorsPerTrack == 8 && - imageInfo.SectorSize == 1024) imageInfo.MediaType = MediaType.NEC_525_HD; - else goto case DriDriveCodes.md2dd; + case MediaType.NEC_525_HD when footer.bpb.driveCode == DriDriveCodes.mf2hd || + footer.bpb.driveCode == DriDriveCodes.mf2ed: + imageInfo.MediaType = MediaType.NEC_35_HD_8; break; - case DriDriveCodes.md2dd: - if(imageInfo.Heads == 1 && imageInfo.Cylinders == 40 && imageInfo.SectorsPerTrack == 8 && - imageInfo.SectorSize == 512) imageInfo.MediaType = MediaType.DOS_525_SS_DD_8; - else if(imageInfo.Heads == 1 && imageInfo.Cylinders == 40 && imageInfo.SectorsPerTrack == 9 && - imageInfo.SectorSize == 512) imageInfo.MediaType = MediaType.DOS_525_SS_DD_9; - else if(imageInfo.Heads == 2 && imageInfo.Cylinders == 40 && imageInfo.SectorsPerTrack == 8 && - imageInfo.SectorSize == 512) imageInfo.MediaType = MediaType.DOS_525_DS_DD_8; - else if(imageInfo.Heads == 2 && imageInfo.Cylinders == 40 && imageInfo.SectorsPerTrack == 9 && - imageInfo.SectorSize == 512) imageInfo.MediaType = MediaType.DOS_525_DS_DD_9; - else if(imageInfo.Heads == 1 && imageInfo.Cylinders == 40 && imageInfo.SectorsPerTrack == 18 && - imageInfo.SectorSize == 128) imageInfo.MediaType = MediaType.ATARI_525_SD; - else if(imageInfo.Heads == 1 && imageInfo.Cylinders == 40 && imageInfo.SectorsPerTrack == 26 && - imageInfo.SectorSize == 128) imageInfo.MediaType = MediaType.ATARI_525_ED; - else if(imageInfo.Heads == 1 && imageInfo.Cylinders == 40 && imageInfo.SectorsPerTrack == 18 && - imageInfo.SectorSize == 256) imageInfo.MediaType = MediaType.ATARI_525_DD; - else imageInfo.MediaType = MediaType.Unknown; + case MediaType.DOS_525_HD when footer.bpb.driveCode == DriDriveCodes.mf2hd || + footer.bpb.driveCode == DriDriveCodes.mf2ed: + imageInfo.MediaType = MediaType.NEC_35_HD_15; break; - case DriDriveCodes.mf2ed: - if(imageInfo.Heads == 2 && imageInfo.Cylinders == 80 && imageInfo.SectorsPerTrack == 36 && - imageInfo.SectorSize == 512) imageInfo.MediaType = MediaType.DOS_35_ED; - else goto case DriDriveCodes.mf2hd; - break; - case DriDriveCodes.mf2hd: - if(imageInfo.Heads == 2 && imageInfo.Cylinders == 80 && imageInfo.SectorsPerTrack == 18 && - imageInfo.SectorSize == 512) imageInfo.MediaType = MediaType.DOS_35_HD; - else if(imageInfo.Heads == 2 && imageInfo.Cylinders == 80 && imageInfo.SectorsPerTrack == 21 && - imageInfo.SectorSize == 512) imageInfo.MediaType = MediaType.DMF; - else if(imageInfo.Heads == 2 && imageInfo.Cylinders == 82 && imageInfo.SectorsPerTrack == 21 && - imageInfo.SectorSize == 512) imageInfo.MediaType = MediaType.DMF_82; - else if(imageInfo.Heads == 2 && imageInfo.Cylinders == 77 && imageInfo.SectorsPerTrack == 8 && - imageInfo.SectorSize == 1024) imageInfo.MediaType = MediaType.NEC_35_HD_8; - else if(imageInfo.Heads == 2 && imageInfo.Cylinders == 80 && imageInfo.SectorsPerTrack == 15 && - imageInfo.SectorSize == 512) imageInfo.MediaType = MediaType.NEC_35_HD_15; - else goto case DriDriveCodes.mf2dd; - break; - case DriDriveCodes.mf2dd: - if(imageInfo.Heads == 2 && imageInfo.Cylinders == 80 && imageInfo.SectorsPerTrack == 9 && - imageInfo.SectorSize == 512) imageInfo.MediaType = MediaType.DOS_35_DS_DD_9; - else if(imageInfo.Heads == 2 && imageInfo.Cylinders == 80 && imageInfo.SectorsPerTrack == 8 && - imageInfo.SectorSize == 512) imageInfo.MediaType = MediaType.DOS_35_DS_DD_8; - else if(imageInfo.Heads == 1 && imageInfo.Cylinders == 80 && imageInfo.SectorsPerTrack == 9 && - imageInfo.SectorSize == 512) imageInfo.MediaType = MediaType.DOS_35_SS_DD_9; - else if(imageInfo.Heads == 1 && imageInfo.Cylinders == 80 && imageInfo.SectorsPerTrack == 8 && - imageInfo.SectorSize == 512) imageInfo.MediaType = MediaType.DOS_35_SS_DD_8; - else if(imageInfo.Heads == 2 && imageInfo.Cylinders == 80 && imageInfo.SectorsPerTrack == 5 && - imageInfo.SectorSize == 1024) imageInfo.MediaType = MediaType.ACORN_35_DS_DD; - else if(imageInfo.Heads == 1 && imageInfo.Cylinders == 70 && imageInfo.SectorsPerTrack == 9 && - imageInfo.SectorSize == 512) imageInfo.MediaType = MediaType.Apricot_35; - else imageInfo.MediaType = MediaType.Unknown; - break; - default: - imageInfo.MediaType = MediaType.Unknown; + case MediaType.RX50 when footer.bpb.driveCode == DriDriveCodes.md2dd || + footer.bpb.driveCode == DriDriveCodes.md2hd: + imageInfo.MediaType = MediaType.ATARI_35_SS_DD; break; } @@ -289,7 +242,7 @@ namespace DiscImageChef.DiscImages } public bool? VerifySectors(ulong sectorAddress, uint length, out List failingLbas, - out List unknownLbas) + out List unknownLbas) { failingLbas = new List(); unknownLbas = new List(); @@ -300,7 +253,7 @@ namespace DiscImageChef.DiscImages } public bool? VerifySectors(ulong sectorAddress, uint length, uint track, out List failingLbas, - out List unknownLbas) + out List unknownLbas) { failingLbas = new List(); unknownLbas = new List(); @@ -336,7 +289,7 @@ namespace DiscImageChef.DiscImages byte[] buffer = new byte[length * imageInfo.SectorSize]; Stream stream = driImageFilter.GetDataForkStream(); - stream.Seek((long)(sectorAddress * imageInfo.SectorSize), SeekOrigin.Begin); + stream.Seek((long)(sectorAddress * imageInfo.SectorSize), SeekOrigin.Begin); stream.Read(buffer, 0, (int)(length * imageInfo.SectorSize)); return buffer; @@ -406,7 +359,8 @@ namespace DiscImageChef.DiscImages struct DriFooter { /// Signature: "DiskImage 2.01 (C) 1990,1991 Digital Research Inc\0" - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 51)] public byte[] signature; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 51)] + public byte[] signature; /// Information about the disk image, mostly imitates FAT BPB public DriBpb bpb; /// Information about the disk image, mostly imitates FAT BPB, copy @@ -457,7 +411,8 @@ namespace DiscImageChef.DiscImages /// Sectors per track (again?) public ushort sptrack2; /// Seems to be 0 - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 144)] public byte[] unknown5; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 144)] + public byte[] unknown5; } /// diff --git a/DiscImageChef.DiscImages/HDCopy.cs b/DiscImageChef.DiscImages/HDCopy.cs index eb6c24ca..8184ace2 100644 --- a/DiscImageChef.DiscImages/HDCopy.cs +++ b/DiscImageChef.DiscImages/HDCopy.cs @@ -66,7 +66,6 @@ using System; using System.Collections.Generic; using System.IO; -using System.Linq; using System.Runtime.InteropServices; using DiscImageChef.CommonTypes; using DiscImageChef.Console; @@ -76,17 +75,6 @@ namespace DiscImageChef.DiscImages { public class HdCopy : IMediaImage { - readonly MediaTypeTableEntry[] mediaTypes = - { - new MediaTypeTableEntry {Tracks = 80, SectorsPerTrack = 8, MediaType = MediaType.DOS_35_DS_DD_8}, - new MediaTypeTableEntry {Tracks = 80, SectorsPerTrack = 9, MediaType = MediaType.DOS_35_DS_DD_9}, - new MediaTypeTableEntry {Tracks = 80, SectorsPerTrack = 18, MediaType = MediaType.DOS_35_HD}, - new MediaTypeTableEntry {Tracks = 80, SectorsPerTrack = 36, MediaType = MediaType.DOS_35_ED}, - new MediaTypeTableEntry {Tracks = 40, SectorsPerTrack = 8, MediaType = MediaType.DOS_525_DS_DD_8}, - new MediaTypeTableEntry {Tracks = 40, SectorsPerTrack = 9, MediaType = MediaType.DOS_525_DS_DD_9}, - new MediaTypeTableEntry {Tracks = 80, SectorsPerTrack = 15, MediaType = MediaType.DOS_525_HD} - }; - /// /// The HDCP file header after the image has been opened /// @@ -95,7 +83,7 @@ namespace DiscImageChef.DiscImages /// /// The ImageFilter we're reading from, after the file has been opened /// - IFilter hdcpImageFilter; + IFilter hdcpImageFilter; ImageInfo imageInfo; /// @@ -112,25 +100,25 @@ namespace DiscImageChef.DiscImages { imageInfo = new ImageInfo { - ReadableSectorTags = new List(), - ReadableMediaTags = new List(), - HasPartitions = false, - HasSessions = false, - Version = null, - Application = null, - ApplicationVersion = null, - Creator = null, - Comments = null, - MediaManufacturer = null, - MediaModel = null, - MediaSerialNumber = null, - MediaBarcode = null, - MediaPartNumber = null, - MediaSequence = 0, - LastMediaSequence = 0, - DriveManufacturer = null, - DriveModel = null, - DriveSerialNumber = null, + ReadableSectorTags = new List(), + ReadableMediaTags = new List(), + HasPartitions = false, + HasSessions = false, + Version = null, + Application = null, + ApplicationVersion = null, + Creator = null, + Comments = null, + MediaManufacturer = null, + MediaModel = null, + MediaSerialNumber = null, + MediaBarcode = null, + MediaPartNumber = null, + MediaSequence = 0, + LastMediaSequence = 0, + DriveManufacturer = null, + DriveModel = null, + DriveSerialNumber = null, DriveFirmwareRevision = null }; } @@ -138,10 +126,10 @@ namespace DiscImageChef.DiscImages public ImageInfo Info => imageInfo; public string Name => "HD-Copy disk image"; - public Guid Id => new Guid("8D57483F-71A5-42EC-9B87-66AEC439C792"); + public Guid Id => new Guid("8D57483F-71A5-42EC-9B87-66AEC439C792"); - public string ImageFormat => "HD-Copy image"; - public List Partitions => + public string ImageFormat => "HD-Copy image"; + public List Partitions => throw new FeatureUnsupportedImageException("Feature not supported by image format"); public List Tracks => @@ -158,10 +146,10 @@ namespace DiscImageChef.DiscImages if(stream.Length < 2 + 2 * 82) return false; byte[] header = new byte[2 + 2 * 82]; - stream.Read(header, 0, 2 + 2 * 82); + stream.Read(header, 0, 2 + 2 * 82); IntPtr hdrPtr = Marshal.AllocHGlobal(2 + 2 * 82); - Marshal.Copy(header, 0, hdrPtr, 2 + 2 * 82); + Marshal.Copy(header, 0, hdrPtr, 2 + 2 * 82); HdcpFileHeader fheader = (HdcpFileHeader)Marshal.PtrToStructure(hdrPtr, typeof(HdcpFileHeader)); Marshal.FreeHGlobal(hdrPtr); @@ -177,7 +165,9 @@ namespace DiscImageChef.DiscImages if(fheader.trackMap[0] != 1 || fheader.trackMap[1] != 1) return false; // all other tracks must be either present (=1) or absent (=0) - for(int i = 0; i < 2 * 82; i++) if(fheader.trackMap[i] > 1) return false; + for(int i = 0; i < 2 * 82; i++) + if(fheader.trackMap[i] > 1) + return false; // TODO: validate the tracks // For now, having a valid header should be sufficient. @@ -186,54 +176,51 @@ namespace DiscImageChef.DiscImages public bool OpenImage(IFilter imageFilter) { - long currentOffset; - Stream stream = imageFilter.GetDataForkStream(); stream.Seek(0, SeekOrigin.Begin); byte[] header = new byte[2 + 2 * 82]; - stream.Read(header, 0, 2 + 2 * 82); + stream.Read(header, 0, 2 + 2 * 82); IntPtr hdrPtr = Marshal.AllocHGlobal(2 + 2 * 82); - Marshal.Copy(header, 0, hdrPtr, 2 + 2 * 82); + Marshal.Copy(header, 0, hdrPtr, 2 + 2 * 82); HdcpFileHeader fheader = (HdcpFileHeader)Marshal.PtrToStructure(hdrPtr, typeof(HdcpFileHeader)); Marshal.FreeHGlobal(hdrPtr); DicConsole.DebugWriteLine("HDCP plugin", "Detected HD-Copy image with {0} tracks and {1} sectors per track.", fheader.lastCylinder + 1, fheader.sectorsPerTrack); - imageInfo.Cylinders = (uint)fheader.lastCylinder + 1; + imageInfo.Cylinders = (uint)fheader.lastCylinder + 1; imageInfo.SectorsPerTrack = fheader.sectorsPerTrack; - imageInfo.SectorSize = 512; // only 512 bytes per sector supported - imageInfo.Heads = 2; // only 2-sided floppies are supported - imageInfo.Sectors = 2 * imageInfo.Cylinders * imageInfo.SectorsPerTrack; - imageInfo.ImageSize = imageInfo.Sectors * imageInfo.SectorSize; + imageInfo.SectorSize = 512; // only 512 bytes per sector supported + imageInfo.Heads = 2; // only 2-sided floppies are supported + imageInfo.Sectors = 2 * imageInfo.Cylinders * imageInfo.SectorsPerTrack; + imageInfo.ImageSize = imageInfo.Sectors * imageInfo.SectorSize; imageInfo.XmlMediaType = XmlMediaType.BlockMedia; - imageInfo.CreationTime = imageFilter.GetCreationTime(); + imageInfo.CreationTime = imageFilter.GetCreationTime(); imageInfo.LastModificationTime = imageFilter.GetLastWriteTime(); - imageInfo.MediaTitle = Path.GetFileNameWithoutExtension(imageFilter.GetFilename()); - imageInfo.MediaType = - (from ent in mediaTypes - where ent.Tracks == imageInfo.Cylinders && ent.SectorsPerTrack == imageInfo.SectorsPerTrack - select ent.MediaType).FirstOrDefault(); + imageInfo.MediaTitle = Path.GetFileNameWithoutExtension(imageFilter.GetFilename()); + imageInfo.MediaType = + Geometry.GetMediaType(((ushort)imageInfo.Cylinders, 2, (ushort)imageInfo.SectorsPerTrack, 512, + MediaEncoding.MFM, false)); // the start offset of the track data - currentOffset = 2 + 2 * 82; + long currentOffset = 2 + 2 * 82; // build table of track offsets - for(int i = 0; i < imageInfo.Cylinders * 2; i++) - if(fheader.trackMap[i] == 0) trackOffset[i] = -1; + for(int i = 0; i < imageInfo.Cylinders * 2; i++) + if(fheader.trackMap[i] == 0) + trackOffset[i] = -1; else { // track is present, read the block header if(currentOffset + 3 >= stream.Length) return false; byte[] blkHeader = new byte[2]; - short blkLength; stream.Read(blkHeader, 0, 2); - blkLength = BitConverter.ToInt16(blkHeader, 0); + short blkLength = BitConverter.ToInt16(blkHeader, 0); // assume block sizes are positive if(blkLength < 0) return false; @@ -251,57 +238,14 @@ namespace DiscImageChef.DiscImages if(currentOffset > stream.Length) return false; // save some variables for later use - fileHeader = fheader; + fileHeader = fheader; hdcpImageFilter = imageFilter; return true; } - void ReadTrackIntoCache(Stream stream, int tracknum) - { - byte[] trackData = new byte[imageInfo.SectorSize * imageInfo.SectorsPerTrack]; - byte[] blkHeader = new byte[3]; - byte escapeByte; - short compressedLength; - - // check that track is present - if(trackOffset[tracknum] == -1) - throw new InvalidDataException("Tried reading a track that is not present in image"); - - stream.Seek(trackOffset[tracknum], SeekOrigin.Begin); - - // read the compressed track data - stream.Read(blkHeader, 0, 3); - compressedLength = (short)(BitConverter.ToInt16(blkHeader, 0) - 1); - escapeByte = blkHeader[2]; - - byte[] cBuffer = new byte[compressedLength]; - stream.Read(cBuffer, 0, compressedLength); - - // decompress the data - int sIndex = 0; // source buffer position - int dIndex = 0; // destination buffer position - while(sIndex < compressedLength) - if(cBuffer[sIndex] == escapeByte) - { - sIndex++; // skip over escape byte - byte fillByte = cBuffer[sIndex++]; - byte fillCount = cBuffer[sIndex++]; - // fill destination buffer - for(int i = 0; i < fillCount; i++) trackData[dIndex++] = fillByte; - } - else trackData[dIndex++] = cBuffer[sIndex++]; - - // check that the number of bytes decompressed matches a whole track - if(dIndex != imageInfo.SectorSize * imageInfo.SectorsPerTrack) - throw new InvalidDataException("Track decompression yielded incomplete data"); - - // store track in cache - trackCache[tracknum] = trackData; - } - public byte[] ReadSector(ulong sectorAddress) { - int trackNum = (int)(sectorAddress / imageInfo.SectorsPerTrack); + int trackNum = (int)(sectorAddress / imageInfo.SectorsPerTrack); int sectorOffset = (int)(sectorAddress % (imageInfo.SectorsPerTrack * imageInfo.SectorSize)); if(sectorAddress > imageInfo.Sectors - 1) @@ -412,7 +356,7 @@ namespace DiscImageChef.DiscImages } public bool? VerifySectors(ulong sectorAddress, uint length, out List failingLbas, - out List unknownLbas) + out List unknownLbas) { failingLbas = new List(); unknownLbas = new List(); @@ -422,7 +366,7 @@ namespace DiscImageChef.DiscImages } public bool? VerifySectors(ulong sectorAddress, uint length, uint track, out List failingLbas, - out List unknownLbas) + out List unknownLbas) { throw new FeatureUnsupportedImageException("Feature not supported by image format"); } @@ -432,6 +376,48 @@ namespace DiscImageChef.DiscImages return null; } + void ReadTrackIntoCache(Stream stream, int tracknum) + { + byte[] trackData = new byte[imageInfo.SectorSize * imageInfo.SectorsPerTrack]; + byte[] blkHeader = new byte[3]; + + // check that track is present + if(trackOffset[tracknum] == -1) + throw new InvalidDataException("Tried reading a track that is not present in image"); + + stream.Seek(trackOffset[tracknum], SeekOrigin.Begin); + + // read the compressed track data + stream.Read(blkHeader, 0, 3); + short compressedLength = (short)(BitConverter.ToInt16(blkHeader, 0) - 1); + byte escapeByte = blkHeader[2]; + + byte[] cBuffer = new byte[compressedLength]; + stream.Read(cBuffer, 0, compressedLength); + + // decompress the data + int sIndex = 0; // source buffer position + int dIndex = 0; // destination buffer position + while(sIndex < compressedLength) + if(cBuffer[sIndex] == escapeByte) + { + sIndex++; // skip over escape byte + byte fillByte = cBuffer[sIndex++]; + byte fillCount = cBuffer[sIndex++]; + // fill destination buffer + for(int i = 0; i < fillCount; i++) trackData[dIndex++] = fillByte; + } + else + trackData[dIndex++] = cBuffer[sIndex++]; + + // check that the number of bytes decompressed matches a whole track + if(dIndex != imageInfo.SectorSize * imageInfo.SectorsPerTrack) + throw new InvalidDataException("Track decompression yielded incomplete data"); + + // store track in cache + trackCache[tracknum] = trackData; + } + /// /// The global header of a HDCP image file /// @@ -454,7 +440,8 @@ namespace DiscImageChef.DiscImages /// 0 means track is not present, 1 means it is present. /// The first 2 tracks are always present. /// - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2 * 82)] public byte[] trackMap; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2 * 82)] + public byte[] trackMap; } /// @@ -473,12 +460,5 @@ namespace DiscImageChef.DiscImages /// public byte escape; } - - struct MediaTypeTableEntry - { - public byte Tracks; - public byte SectorsPerTrack; - public MediaType MediaType; - } } } \ No newline at end of file diff --git a/DiscImageChef.DiscImages/IMD.cs b/DiscImageChef.DiscImages/IMD.cs index 9c8f981a..19e7657c 100644 --- a/DiscImageChef.DiscImages/IMD.cs +++ b/DiscImageChef.DiscImages/IMD.cs @@ -43,12 +43,11 @@ namespace DiscImageChef.DiscImages { public class Imd : IMediaImage { - const byte SECTOR_CYLINDER_MAP_MASK = 0x80; - const byte SECTOR_HEAD_MAP_MASK = 0x40; - const byte COMMENT_END = 0x1A; - const string REGEX_HEADER = - @"IMD (?\d.\d+):\s+(?\d+)\/\s*(?\d+)\/(?\d+)\s+(?\d+):(?\d+):(?\d+)\r\n" - ; + const byte SECTOR_CYLINDER_MAP_MASK = 0x80; + const byte SECTOR_HEAD_MAP_MASK = 0x40; + const byte COMMENT_END = 0x1A; + const string REGEX_HEADER = + @"IMD (?\d.\d+):\s+(?\d+)\/\s*(?\d+)\/(?\d+)\s+(?\d+):(?\d+):(?\d+)\r\n"; ImageInfo imageInfo; List sectorsData; @@ -57,31 +56,31 @@ namespace DiscImageChef.DiscImages { imageInfo = new ImageInfo { - ReadableSectorTags = new List(), - ReadableMediaTags = new List(), - HasPartitions = false, - HasSessions = false, - Version = null, - Application = null, - ApplicationVersion = null, - Creator = null, - Comments = null, - MediaManufacturer = null, - MediaModel = null, - MediaSerialNumber = null, - MediaBarcode = null, - MediaPartNumber = null, - MediaSequence = 0, - LastMediaSequence = 0, - DriveManufacturer = null, - DriveModel = null, - DriveSerialNumber = null, + ReadableSectorTags = new List(), + ReadableMediaTags = new List(), + HasPartitions = false, + HasSessions = false, + Version = null, + Application = null, + ApplicationVersion = null, + Creator = null, + Comments = null, + MediaManufacturer = null, + MediaModel = null, + MediaSerialNumber = null, + MediaBarcode = null, + MediaPartNumber = null, + MediaSequence = 0, + LastMediaSequence = 0, + DriveManufacturer = null, + DriveModel = null, + DriveSerialNumber = null, DriveFirmwareRevision = null }; } - public string Name => "Dunfield's IMD"; - public Guid Id => new Guid("0D67162E-38A3-407D-9B1A-CF40080A48CB"); + public string Name => "Dunfield's IMD"; + public Guid Id => new Guid("0D67162E-38A3-407D-9B1A-CF40080A48CB"); public ImageInfo Info => imageInfo; public string ImageFormat => "IMageDisk"; @@ -126,26 +125,26 @@ namespace DiscImageChef.DiscImages } imageInfo.Comments = StringHandlers.CToString(cmt.ToArray()); - sectorsData = new List(); + sectorsData = new List(); byte currentCylinder = 0; - imageInfo.Cylinders = 1; - imageInfo.Heads = 1; - ulong currentLba = 0; + imageInfo.Cylinders = 1; + imageInfo.Heads = 1; + ulong currentLba = 0; TransferRate mode = TransferRate.TwoHundred; while(stream.Position + 5 < stream.Length) { - mode = (TransferRate)stream.ReadByte(); - byte cylinder = (byte)stream.ReadByte(); - byte head = (byte)stream.ReadByte(); - byte spt = (byte)stream.ReadByte(); - byte n = (byte)stream.ReadByte(); - byte[] idmap = new byte[spt]; - byte[] cylmap = new byte[spt]; - byte[] headmap = new byte[spt]; - ushort[] bps = new ushort[spt]; + mode = (TransferRate)stream.ReadByte(); + byte cylinder = (byte)stream.ReadByte(); + byte head = (byte)stream.ReadByte(); + byte spt = (byte)stream.ReadByte(); + byte n = (byte)stream.ReadByte(); + byte[] idmap = new byte[spt]; + byte[] cylmap = new byte[spt]; + byte[] headmap = new byte[spt]; + ushort[] bps = new ushort[spt]; if(cylinder != currentCylinder) { @@ -155,16 +154,19 @@ namespace DiscImageChef.DiscImages if((head & 1) == 1) imageInfo.Heads = 2; - stream.Read(idmap, 0, idmap.Length); + stream.Read(idmap, 0, idmap.Length); if((head & SECTOR_CYLINDER_MAP_MASK) == SECTOR_CYLINDER_MAP_MASK) stream.Read(cylmap, 0, cylmap.Length); - if((head & SECTOR_HEAD_MAP_MASK) == SECTOR_HEAD_MAP_MASK) stream.Read(headmap, 0, headmap.Length); + if((head & SECTOR_HEAD_MAP_MASK) == SECTOR_HEAD_MAP_MASK) + stream.Read(headmap, 0, headmap.Length); if(n == 0xFF) { byte[] bpsbytes = new byte[spt * 2]; stream.Read(bpsbytes, 0, bpsbytes.Length); for(int i = 0; i < spt; i++) bps[i] = BitConverter.ToUInt16(bpsbytes, i * 2); } - else for(int i = 0; i < spt; i++) bps[i] = (ushort)(128 << n); + else + for(int i = 0; i < spt; i++) + bps[i] = (ushort)(128 << n); if(spt > imageInfo.SectorsPerTrack) imageInfo.SectorsPerTrack = spt; @@ -173,7 +175,7 @@ namespace DiscImageChef.DiscImages for(int i = 0; i < spt; i++) { SectorType type = (SectorType)stream.ReadByte(); - byte[] data = new byte[bps[i]]; + byte[] data = new byte[bps[i]]; // TODO; Handle disks with different bps in track 0 if(bps[i] > imageInfo.SectorSize) imageInfo.SectorSize = bps[i]; @@ -212,99 +214,31 @@ namespace DiscImageChef.DiscImages imageInfo.Application = "IMD"; // TODO: The header is the date of dump or the date of the application compilation? - imageInfo.CreationTime = imageFilter.GetCreationTime(); + imageInfo.CreationTime = imageFilter.GetCreationTime(); imageInfo.LastModificationTime = imageFilter.GetLastWriteTime(); - imageInfo.MediaTitle = Path.GetFileNameWithoutExtension(imageFilter.GetFilename()); - imageInfo.Comments = StringHandlers.CToString(cmt.ToArray()); - imageInfo.Sectors = currentLba; - imageInfo.MediaType = MediaType.Unknown; + imageInfo.MediaTitle = Path.GetFileNameWithoutExtension(imageFilter.GetFilename()); + imageInfo.Comments = StringHandlers.CToString(cmt.ToArray()); + imageInfo.Sectors = currentLba; + imageInfo.MediaType = MediaType.Unknown; - switch(mode) + MediaEncoding mediaEncoding = MediaEncoding.MFM; + if(mode == TransferRate.TwoHundred || mode == TransferRate.ThreeHundred || mode == TransferRate.FiveHundred) + mediaEncoding = MediaEncoding.FM; + + imageInfo.MediaType = + Geometry.GetMediaType(((ushort)imageInfo.Cylinders, (byte)imageInfo.Heads, + (ushort)imageInfo.SectorsPerTrack, imageInfo.SectorSize, mediaEncoding, false)); + + switch(imageInfo.MediaType) { - case TransferRate.TwoHundred: - case TransferRate.ThreeHundred: - if(imageInfo.Heads == 1 && imageInfo.Cylinders == 40 && imageInfo.SectorsPerTrack == 10 && - imageInfo.SectorSize == 256) imageInfo.MediaType = MediaType.ACORN_525_SS_SD_40; - else if(imageInfo.Heads == 1 && imageInfo.Cylinders == 80 && imageInfo.SectorsPerTrack == 10 && - imageInfo.SectorSize == 256) imageInfo.MediaType = MediaType.ACORN_525_SS_SD_80; - else if(imageInfo.Heads == 1 && imageInfo.Cylinders == 40 && imageInfo.SectorsPerTrack == 18 && - imageInfo.SectorSize == 128) imageInfo.MediaType = MediaType.ATARI_525_SD; + case MediaType.NEC_525_HD when mode == TransferRate.FiveHundredMfm: + imageInfo.MediaType = MediaType.NEC_35_HD_8; break; - case TransferRate.FiveHundred: - if(imageInfo.Heads == 1 && imageInfo.Cylinders == 32 && imageInfo.SectorsPerTrack == 8 && - imageInfo.SectorSize == 319) imageInfo.MediaType = MediaType.IBM23FD; - else if(imageInfo.Heads == 1 && imageInfo.Cylinders == 73 && imageInfo.SectorsPerTrack == 26 && - imageInfo.SectorSize == 128) imageInfo.MediaType = MediaType.IBM23FD; - else if(imageInfo.Heads == 2 && imageInfo.Cylinders == 77 && imageInfo.SectorsPerTrack == 26 && - imageInfo.SectorSize == 128) imageInfo.MediaType = MediaType.NEC_8_SD; + case MediaType.DOS_525_HD when mode == TransferRate.FiveHundredMfm: + imageInfo.MediaType = MediaType.NEC_35_HD_15; break; - case TransferRate.TwoHundredMfm: - case TransferRate.ThreeHundredMfm: - if(imageInfo.Heads == 1 && imageInfo.Cylinders == 40 && imageInfo.SectorsPerTrack == 8 && - imageInfo.SectorSize == 512) imageInfo.MediaType = MediaType.DOS_525_SS_DD_8; - else if(imageInfo.Heads == 1 && imageInfo.Cylinders == 40 && imageInfo.SectorsPerTrack == 9 && - imageInfo.SectorSize == 512) imageInfo.MediaType = MediaType.DOS_525_SS_DD_9; - else if(imageInfo.Heads == 2 && imageInfo.Cylinders == 40 && imageInfo.SectorsPerTrack == 8 && - imageInfo.SectorSize == 512) imageInfo.MediaType = MediaType.DOS_525_DS_DD_8; - else if(imageInfo.Heads == 2 && imageInfo.Cylinders == 40 && imageInfo.SectorsPerTrack == 9 && - imageInfo.SectorSize == 512) imageInfo.MediaType = MediaType.DOS_525_DS_DD_9; - else if(imageInfo.Heads == 1 && imageInfo.Cylinders == 40 && imageInfo.SectorsPerTrack == 18 && - imageInfo.SectorSize == 128) imageInfo.MediaType = MediaType.ATARI_525_SD; - else if(imageInfo.Heads == 1 && imageInfo.Cylinders == 40 && imageInfo.SectorsPerTrack == 26 && - imageInfo.SectorSize == 128) imageInfo.MediaType = MediaType.ATARI_525_ED; - else if(imageInfo.Heads == 1 && imageInfo.Cylinders == 40 && imageInfo.SectorsPerTrack == 18 && - imageInfo.SectorSize == 256) imageInfo.MediaType = MediaType.ATARI_525_DD; - else if(imageInfo.Heads == 1 && imageInfo.Cylinders == 40 && imageInfo.SectorsPerTrack == 16 && - imageInfo.SectorSize == 256) imageInfo.MediaType = MediaType.ACORN_525_SS_DD_40; - else if(imageInfo.Heads == 1 && imageInfo.Cylinders == 80 && imageInfo.SectorsPerTrack == 16 && - imageInfo.SectorSize == 256) imageInfo.MediaType = MediaType.ACORN_525_SS_DD_80; - else if(imageInfo.Heads == 1 && imageInfo.Cylinders == 40 && imageInfo.SectorsPerTrack == 18 && - imageInfo.SectorSize == 256) imageInfo.MediaType = MediaType.ATARI_525_DD; - else if(imageInfo.Heads == 1 && imageInfo.Cylinders == 80 && imageInfo.SectorsPerTrack == 10 && - imageInfo.SectorSize == 512) imageInfo.MediaType = MediaType.RX50; - else if(imageInfo.Heads == 2 && imageInfo.Cylinders == 80 && imageInfo.SectorsPerTrack == 9 && - imageInfo.SectorSize == 512) imageInfo.MediaType = MediaType.DOS_35_DS_DD_9; - else if(imageInfo.Heads == 2 && imageInfo.Cylinders == 80 && imageInfo.SectorsPerTrack == 8 && - imageInfo.SectorSize == 512) imageInfo.MediaType = MediaType.DOS_35_DS_DD_8; - if(imageInfo.Heads == 1 && imageInfo.Cylinders == 80 && imageInfo.SectorsPerTrack == 9 && - imageInfo.SectorSize == 512) imageInfo.MediaType = MediaType.DOS_35_SS_DD_9; - else if(imageInfo.Heads == 1 && imageInfo.Cylinders == 80 && imageInfo.SectorsPerTrack == 8 && - imageInfo.SectorSize == 512) imageInfo.MediaType = MediaType.DOS_35_SS_DD_8; - else if(imageInfo.Heads == 2 && imageInfo.Cylinders == 80 && imageInfo.SectorsPerTrack == 5 && - imageInfo.SectorSize == 1024) imageInfo.MediaType = MediaType.ACORN_35_DS_DD; - else if(imageInfo.Heads == 2 && imageInfo.Cylinders == 82 && imageInfo.SectorsPerTrack == 10 && - imageInfo.SectorSize == 512) imageInfo.MediaType = MediaType.FDFORMAT_35_DD; - else if(imageInfo.Heads == 1 && imageInfo.Cylinders == 70 && imageInfo.SectorsPerTrack == 9 && - imageInfo.SectorSize == 512) imageInfo.MediaType = MediaType.Apricot_35; - break; - case TransferRate.FiveHundredMfm: - if(imageInfo.Heads == 2 && imageInfo.Cylinders == 80 && imageInfo.SectorsPerTrack == 18 && - imageInfo.SectorSize == 512) imageInfo.MediaType = MediaType.DOS_35_HD; - else if(imageInfo.Heads == 2 && imageInfo.Cylinders == 80 && imageInfo.SectorsPerTrack == 21 && - imageInfo.SectorSize == 512) imageInfo.MediaType = MediaType.DMF; - else if(imageInfo.Heads == 2 && imageInfo.Cylinders == 82 && imageInfo.SectorsPerTrack == 21 && - imageInfo.SectorSize == 512) imageInfo.MediaType = MediaType.DMF_82; - else if(imageInfo.Heads == 2 && imageInfo.Cylinders == 80 && imageInfo.SectorsPerTrack == 23 && - imageInfo.SectorSize == 512) imageInfo.MediaType = MediaType.XDF_35; - else if(imageInfo.Heads == 2 && imageInfo.Cylinders == 80 && imageInfo.SectorsPerTrack == 15 && - imageInfo.SectorSize == 512) imageInfo.MediaType = MediaType.DOS_525_HD; - else if(imageInfo.Heads == 2 && imageInfo.Cylinders == 80 && imageInfo.SectorsPerTrack == 10 && - imageInfo.SectorSize == 1024) imageInfo.MediaType = MediaType.ACORN_35_DS_HD; - else if(imageInfo.Heads == 2 && imageInfo.Cylinders == 77 && imageInfo.SectorsPerTrack == 8 && - imageInfo.SectorSize == 1024) imageInfo.MediaType = MediaType.NEC_525_HD; - else if(imageInfo.Heads == 2 && imageInfo.Cylinders == 80 && imageInfo.SectorsPerTrack == 9 && - imageInfo.SectorSize == 1024) imageInfo.MediaType = MediaType.SHARP_525_9; - else if(imageInfo.Heads == 1 && imageInfo.Cylinders == 80 && imageInfo.SectorsPerTrack == 10 && - imageInfo.SectorSize == 512) imageInfo.MediaType = MediaType.ATARI_35_SS_DD; - else if(imageInfo.Heads == 2 && imageInfo.Cylinders == 80 && imageInfo.SectorsPerTrack == 10 && - imageInfo.SectorSize == 512) imageInfo.MediaType = MediaType.ATARI_35_DS_DD; - else if(imageInfo.Heads == 1 && imageInfo.Cylinders == 80 && imageInfo.SectorsPerTrack == 11 && - imageInfo.SectorSize == 512) imageInfo.MediaType = MediaType.ATARI_35_SS_DD_11; - else if(imageInfo.Heads == 2 && imageInfo.Cylinders == 80 && imageInfo.SectorsPerTrack == 11 && - imageInfo.SectorSize == 512) imageInfo.MediaType = MediaType.ATARI_35_DS_DD_11; - break; - default: - imageInfo.MediaType = MediaType.Unknown; + case MediaType.RX50 when mode == TransferRate.FiveHundredMfm: + imageInfo.MediaType = MediaType.ATARI_35_SS_DD; break; } @@ -335,7 +269,7 @@ namespace DiscImageChef.DiscImages } public bool? VerifySectors(ulong sectorAddress, uint length, out List failingLbas, - out List unknownLbas) + out List unknownLbas) { failingLbas = new List(); unknownLbas = new List(); @@ -346,7 +280,7 @@ namespace DiscImageChef.DiscImages } public bool? VerifySectors(ulong sectorAddress, uint length, uint track, out List failingLbas, - out List unknownLbas) + out List unknownLbas) { failingLbas = new List(); unknownLbas = new List(); @@ -464,14 +398,14 @@ namespace DiscImageChef.DiscImages enum SectorType : byte { - Unavailable = 0, - Normal = 1, - Compressed = 2, - Deleted = 3, - CompressedDeleted = 4, - Error = 5, - CompressedError = 6, - DeletedError = 7, + Unavailable = 0, + Normal = 1, + Compressed = 2, + Deleted = 3, + CompressedDeleted = 4, + Error = 5, + CompressedError = 6, + DeletedError = 7, CompressedDeletedError = 8 } } diff --git a/DiscImageChef.DiscImages/MaxiDisk.cs b/DiscImageChef.DiscImages/MaxiDisk.cs index d8c7e0ba..4b36c2b7 100644 --- a/DiscImageChef.DiscImages/MaxiDisk.cs +++ b/DiscImageChef.DiscImages/MaxiDisk.cs @@ -43,30 +43,30 @@ namespace DiscImageChef.DiscImages public class MaxiDisk : IMediaImage { /// Disk image file - IFilter hdkImageFilter; + IFilter hdkImageFilter; ImageInfo imageInfo; public MaxiDisk() { imageInfo = new ImageInfo { - ReadableSectorTags = new List(), - ReadableMediaTags = new List(), - HasPartitions = false, - HasSessions = false, - Application = "MAXI Disk", - Creator = null, - Comments = null, - MediaManufacturer = null, - MediaModel = null, - MediaSerialNumber = null, - MediaBarcode = null, - MediaPartNumber = null, - MediaSequence = 0, - LastMediaSequence = 0, - DriveManufacturer = null, - DriveModel = null, - DriveSerialNumber = null, + ReadableSectorTags = new List(), + ReadableMediaTags = new List(), + HasPartitions = false, + HasSessions = false, + Application = "MAXI Disk", + Creator = null, + Comments = null, + MediaManufacturer = null, + MediaModel = null, + MediaSerialNumber = null, + MediaBarcode = null, + MediaPartNumber = null, + MediaSequence = 0, + LastMediaSequence = 0, + DriveManufacturer = null, + DriveModel = null, + DriveSerialNumber = null, DriveFirmwareRevision = null }; } @@ -74,7 +74,7 @@ namespace DiscImageChef.DiscImages public ImageInfo Info => imageInfo; public string Name => "MAXI Disk image"; - public Guid Id => new Guid("D27D924A-7034-466E-ADE1-B81EF37E469E"); + public Guid Id => new Guid("D27D924A-7034-466E-ADE1-B81EF37E469E"); public string ImageFormat => "MAXI Disk"; @@ -102,10 +102,10 @@ namespace DiscImageChef.DiscImages HdkHeader tmpHeader = (HdkHeader)Marshal.PtrToStructure(ftrPtr, typeof(HdkHeader)); Marshal.FreeHGlobal(ftrPtr); - DicConsole.DebugWriteLine("MAXI Disk plugin", "tmp_header.unknown = {0}", tmpHeader.unknown); - DicConsole.DebugWriteLine("MAXI Disk plugin", "tmp_header.diskType = {0}", tmpHeader.diskType); - DicConsole.DebugWriteLine("MAXI Disk plugin", "tmp_header.heads = {0}", tmpHeader.heads); - DicConsole.DebugWriteLine("MAXI Disk plugin", "tmp_header.cylinders = {0}", tmpHeader.cylinders); + DicConsole.DebugWriteLine("MAXI Disk plugin", "tmp_header.unknown = {0}", tmpHeader.unknown); + DicConsole.DebugWriteLine("MAXI Disk plugin", "tmp_header.diskType = {0}", tmpHeader.diskType); + DicConsole.DebugWriteLine("MAXI Disk plugin", "tmp_header.heads = {0}", tmpHeader.heads); + DicConsole.DebugWriteLine("MAXI Disk plugin", "tmp_header.cylinders = {0}", tmpHeader.cylinders); DicConsole.DebugWriteLine("MAXI Disk plugin", "tmp_header.bytesPerSector = {0}", tmpHeader.bytesPerSector); DicConsole.DebugWriteLine("MAXI Disk plugin", "tmp_header.sectorsPerTrack = {0}", tmpHeader.sectorsPerTrack); @@ -166,67 +166,22 @@ namespace DiscImageChef.DiscImages if(expectedFileSize != stream.Length) return false; - imageInfo.Cylinders = tmpHeader.cylinders; - imageInfo.Heads = tmpHeader.heads; + imageInfo.Cylinders = tmpHeader.cylinders; + imageInfo.Heads = tmpHeader.heads; imageInfo.SectorsPerTrack = tmpHeader.sectorsPerTrack; - imageInfo.Sectors = (ulong)(tmpHeader.heads * tmpHeader.cylinders * tmpHeader.sectorsPerTrack); - imageInfo.SectorSize = (uint)(128 << tmpHeader.bytesPerSector); + imageInfo.Sectors = (ulong)(tmpHeader.heads * tmpHeader.cylinders * tmpHeader.sectorsPerTrack); + imageInfo.SectorSize = (uint)(128 << tmpHeader.bytesPerSector); hdkImageFilter = imageFilter; - imageInfo.ImageSize = (ulong)(stream.Length - 8); - imageInfo.CreationTime = imageFilter.GetCreationTime(); + imageInfo.ImageSize = (ulong)(stream.Length - 8); + imageInfo.CreationTime = imageFilter.GetCreationTime(); imageInfo.LastModificationTime = imageFilter.GetLastWriteTime(); - if(imageInfo.Heads == 2 && imageInfo.Cylinders == 80 && imageInfo.SectorsPerTrack == 15 && - imageInfo.SectorSize == 512) imageInfo.MediaType = MediaType.DOS_525_HD; - else if(imageInfo.Heads == 2 && imageInfo.Cylinders == 80 && imageInfo.SectorsPerTrack == 16 && - imageInfo.SectorSize == 256) imageInfo.MediaType = MediaType.ACORN_525_DS_DD; - else if(imageInfo.Heads == 1 && imageInfo.Cylinders == 80 && imageInfo.SectorsPerTrack == 16 && - imageInfo.SectorSize == 256) imageInfo.MediaType = MediaType.ACORN_525_SS_DD_80; - else if(imageInfo.Heads == 1 && imageInfo.Cylinders == 80 && imageInfo.SectorsPerTrack == 10 && - imageInfo.SectorSize == 256) imageInfo.MediaType = MediaType.ACORN_525_SS_SD_80; - else if(imageInfo.Heads == 2 && imageInfo.Cylinders == 77 && imageInfo.SectorsPerTrack == 8 && - imageInfo.SectorSize == 1024) imageInfo.MediaType = MediaType.NEC_525_HD; - else if(imageInfo.Heads == 1 && imageInfo.Cylinders == 40 && imageInfo.SectorsPerTrack == 8 && - imageInfo.SectorSize == 512) imageInfo.MediaType = MediaType.DOS_525_SS_DD_8; - else if(imageInfo.Heads == 1 && imageInfo.Cylinders == 40 && imageInfo.SectorsPerTrack == 9 && - imageInfo.SectorSize == 512) imageInfo.MediaType = MediaType.DOS_525_SS_DD_9; - else if(imageInfo.Heads == 2 && imageInfo.Cylinders == 40 && imageInfo.SectorsPerTrack == 8 && - imageInfo.SectorSize == 512) imageInfo.MediaType = MediaType.DOS_525_DS_DD_8; - else if(imageInfo.Heads == 2 && imageInfo.Cylinders == 40 && imageInfo.SectorsPerTrack == 9 && - imageInfo.SectorSize == 512) imageInfo.MediaType = MediaType.DOS_525_DS_DD_9; - else if(imageInfo.Heads == 1 && imageInfo.Cylinders == 40 && imageInfo.SectorsPerTrack == 18 && - imageInfo.SectorSize == 128) imageInfo.MediaType = MediaType.ATARI_525_SD; - else if(imageInfo.Heads == 1 && imageInfo.Cylinders == 40 && imageInfo.SectorsPerTrack == 26 && - imageInfo.SectorSize == 128) imageInfo.MediaType = MediaType.ATARI_525_ED; - else if(imageInfo.Heads == 1 && imageInfo.Cylinders == 40 && imageInfo.SectorsPerTrack == 18 && - imageInfo.SectorSize == 256) imageInfo.MediaType = MediaType.ATARI_525_DD; - else if(imageInfo.Heads == 2 && imageInfo.Cylinders == 80 && imageInfo.SectorsPerTrack == 36 && - imageInfo.SectorSize == 512) imageInfo.MediaType = MediaType.DOS_35_ED; - else if(imageInfo.Heads == 2 && imageInfo.Cylinders == 80 && imageInfo.SectorsPerTrack == 18 && - imageInfo.SectorSize == 512) imageInfo.MediaType = MediaType.DOS_35_HD; - else if(imageInfo.Heads == 2 && imageInfo.Cylinders == 80 && imageInfo.SectorsPerTrack == 21 && - imageInfo.SectorSize == 512) imageInfo.MediaType = MediaType.DMF; - else if(imageInfo.Heads == 2 && imageInfo.Cylinders == 82 && imageInfo.SectorsPerTrack == 21 && - imageInfo.SectorSize == 512) imageInfo.MediaType = MediaType.DMF_82; - else if(imageInfo.Heads == 2 && imageInfo.Cylinders == 77 && imageInfo.SectorsPerTrack == 8 && - imageInfo.SectorSize == 1024) imageInfo.MediaType = MediaType.NEC_35_HD_8; - else if(imageInfo.Heads == 2 && imageInfo.Cylinders == 80 && imageInfo.SectorsPerTrack == 15 && - imageInfo.SectorSize == 512) imageInfo.MediaType = MediaType.NEC_35_HD_15; - else if(imageInfo.Heads == 2 && imageInfo.Cylinders == 80 && imageInfo.SectorsPerTrack == 9 && - imageInfo.SectorSize == 512) imageInfo.MediaType = MediaType.DOS_35_DS_DD_9; - else if(imageInfo.Heads == 2 && imageInfo.Cylinders == 80 && imageInfo.SectorsPerTrack == 8 && - imageInfo.SectorSize == 512) imageInfo.MediaType = MediaType.DOS_35_DS_DD_8; - else if(imageInfo.Heads == 1 && imageInfo.Cylinders == 80 && imageInfo.SectorsPerTrack == 9 && - imageInfo.SectorSize == 512) imageInfo.MediaType = MediaType.DOS_35_SS_DD_9; - else if(imageInfo.Heads == 1 && imageInfo.Cylinders == 80 && imageInfo.SectorsPerTrack == 8 && - imageInfo.SectorSize == 512) imageInfo.MediaType = MediaType.DOS_35_SS_DD_8; - else if(imageInfo.Heads == 2 && imageInfo.Cylinders == 80 && imageInfo.SectorsPerTrack == 5 && - imageInfo.SectorSize == 1024) imageInfo.MediaType = MediaType.ACORN_35_DS_DD; - else if(imageInfo.Heads == 1 && imageInfo.Cylinders == 70 && imageInfo.SectorsPerTrack == 9 && - imageInfo.SectorSize == 512) imageInfo.MediaType = MediaType.Apricot_35; - else imageInfo.MediaType = MediaType.Unknown; + imageInfo.MediaType = + Geometry.GetMediaType(((ushort)imageInfo.Cylinders, (byte)imageInfo.Heads, + (ushort)imageInfo.SectorsPerTrack, imageInfo.SectorSize, MediaEncoding.MFM, false + )); imageInfo.XmlMediaType = XmlMediaType.BlockMedia; @@ -244,7 +199,7 @@ namespace DiscImageChef.DiscImages } public bool? VerifySectors(ulong sectorAddress, uint length, out List failingLbas, - out List unknownLbas) + out List unknownLbas) { failingLbas = new List(); unknownLbas = new List(); @@ -255,7 +210,7 @@ namespace DiscImageChef.DiscImages } public bool? VerifySectors(ulong sectorAddress, uint length, uint track, out List failingLbas, - out List unknownLbas) + out List unknownLbas) { failingLbas = new List(); unknownLbas = new List(); @@ -292,7 +247,7 @@ namespace DiscImageChef.DiscImages Stream stream = hdkImageFilter.GetDataForkStream(); stream.Seek((long)(8 + sectorAddress * imageInfo.SectorSize), SeekOrigin.Begin); - stream.Read(buffer, 0, (int)(length * imageInfo.SectorSize)); + stream.Read(buffer, 0, (int)(length * imageInfo.SectorSize)); return buffer; } @@ -372,17 +327,17 @@ namespace DiscImageChef.DiscImages enum HdkDiskTypes : byte { - Dos360 = 0, - Maxi420 = 1, - Dos720 = 2, - Maxi800 = 3, - Dos1200 = 4, + Dos360 = 0, + Maxi420 = 1, + Dos720 = 2, + Maxi800 = 3, + Dos1200 = 4, Maxi1400 = 5, - Dos1440 = 6, - Mac1440 = 7, + Dos1440 = 6, + Mac1440 = 7, Maxi1600 = 8, - Dmf = 9, - Dos2880 = 10, + Dmf = 9, + Dos2880 = 10, Maxi3200 = 11 } } diff --git a/DiscImageChef.DiscImages/RayDIM.cs b/DiscImageChef.DiscImages/RayDIM.cs index 004d4eb9..c10edc2b 100644 --- a/DiscImageChef.DiscImages/RayDIM.cs +++ b/DiscImageChef.DiscImages/RayDIM.cs @@ -45,39 +45,38 @@ namespace DiscImageChef.DiscImages public class RayDim : IMediaImage { const string REGEX_SIGNATURE = - @"Disk IMage VER (?\d).(?\d) Copyright \(C\) (?\d{4}) Ray Arachelian, All Rights Reserved\." - ; + @"Disk IMage VER (?\d).(?\d) Copyright \(C\) (?\d{4}) Ray Arachelian, All Rights Reserved\."; MemoryStream disk; - ImageInfo imageInfo; + ImageInfo imageInfo; public RayDim() { imageInfo = new ImageInfo { - ReadableSectorTags = new List(), - ReadableMediaTags = new List(), - HasPartitions = false, - HasSessions = false, - Application = "Ray Arachelian's Disk IMage", - Creator = null, - Comments = null, - MediaManufacturer = null, - MediaModel = null, - MediaSerialNumber = null, - MediaBarcode = null, - MediaPartNumber = null, - MediaSequence = 0, - LastMediaSequence = 0, - DriveManufacturer = null, - DriveModel = null, - DriveSerialNumber = null, + ReadableSectorTags = new List(), + ReadableMediaTags = new List(), + HasPartitions = false, + HasSessions = false, + Application = "Ray Arachelian's Disk IMage", + Creator = null, + Comments = null, + MediaManufacturer = null, + MediaModel = null, + MediaSerialNumber = null, + MediaBarcode = null, + MediaPartNumber = null, + MediaSequence = 0, + LastMediaSequence = 0, + DriveManufacturer = null, + DriveModel = null, + DriveSerialNumber = null, DriveFirmwareRevision = null }; } - public string Name => "Ray Arachelian's Disk IMage"; - public Guid Id => new Guid("F541F4E7-C1E3-4A2D-B07F-D863E87AB961"); + public string Name => "Ray Arachelian's Disk IMage"; + public Guid Id => new Guid("F541F4E7-C1E3-4A2D-B07F-D863E87AB961"); public ImageInfo Info => imageInfo; public string ImageFormat => "Ray Arachelian's Disk IMage"; @@ -109,8 +108,8 @@ namespace DiscImageChef.DiscImages string signature = StringHandlers.CToString(header.signature); DicConsole.DebugWriteLine("Ray Arachelian's Disk IMage plugin", "header.signature = {0}", signature); - DicConsole.DebugWriteLine("Ray Arachelian's Disk IMage plugin", "header.diskType = {0}", header.diskType); - DicConsole.DebugWriteLine("Ray Arachelian's Disk IMage plugin", "header.heads = {0}", header.heads); + DicConsole.DebugWriteLine("Ray Arachelian's Disk IMage plugin", "header.diskType = {0}", header.diskType); + DicConsole.DebugWriteLine("Ray Arachelian's Disk IMage plugin", "header.heads = {0}", header.heads); DicConsole.DebugWriteLine("Ray Arachelian's Disk IMage plugin", "header.cylinders = {0}", header.cylinders); DicConsole.DebugWriteLine("Ray Arachelian's Disk IMage plugin", "header.sectorsPerTrack = {0}", header.sectorsPerTrack); @@ -148,14 +147,14 @@ namespace DiscImageChef.DiscImages imageInfo.ApplicationVersion = $"{sm.Groups["major"].Value}.{sm.Groups["minor"].Value}"; - imageInfo.Cylinders = (uint)(header.cylinders + 1); - imageInfo.Heads = (uint)(header.heads + 1); + imageInfo.Cylinders = (uint)(header.cylinders + 1); + imageInfo.Heads = (uint)(header.heads + 1); imageInfo.SectorsPerTrack = header.sectorsPerTrack; - imageInfo.Sectors = imageInfo.Cylinders * imageInfo.Heads * imageInfo.SectorsPerTrack; - imageInfo.SectorSize = 512; + imageInfo.Sectors = imageInfo.Cylinders * imageInfo.Heads * imageInfo.SectorsPerTrack; + imageInfo.SectorSize = 512; byte[] sectors = new byte[imageInfo.SectorsPerTrack * imageInfo.SectorSize]; - disk = new MemoryStream(); + disk = new MemoryStream(); for(int i = 0; i < imageInfo.SectorsPerTrack * imageInfo.SectorSize; i++) { @@ -164,55 +163,22 @@ namespace DiscImageChef.DiscImages disk.Write(sectors, 0, sectors.Length); } - switch(header.diskType) + imageInfo.MediaType = + Geometry.GetMediaType(((ushort)imageInfo.Cylinders, (byte)imageInfo.Heads, + (ushort)imageInfo.SectorsPerTrack, 512, MediaEncoding.MFM, false)); + + switch(imageInfo.MediaType) { - case RayDiskTypes.Md2hd: - if(imageInfo.Heads == 2 && imageInfo.Cylinders == 80 && imageInfo.SectorsPerTrack == 15) - imageInfo.MediaType = MediaType.DOS_525_HD; - else goto case RayDiskTypes.Md2dd; + case MediaType.NEC_525_HD when header.diskType == RayDiskTypes.Mf2hd || + header.diskType == RayDiskTypes.Mf2ed: + imageInfo.MediaType = MediaType.NEC_35_HD_8; break; - case RayDiskTypes.Md2dd: - if(imageInfo.Heads == 1 && imageInfo.Cylinders == 40 && imageInfo.SectorsPerTrack == 8) - imageInfo.MediaType = MediaType.DOS_525_SS_DD_8; - else if(imageInfo.Heads == 1 && imageInfo.Cylinders == 40 && imageInfo.SectorsPerTrack == 9) - imageInfo.MediaType = MediaType.DOS_525_SS_DD_9; - else if(imageInfo.Heads == 2 && imageInfo.Cylinders == 40 && imageInfo.SectorsPerTrack == 8) - imageInfo.MediaType = MediaType.DOS_525_DS_DD_8; - else if(imageInfo.Heads == 2 && imageInfo.Cylinders == 40 && imageInfo.SectorsPerTrack == 9) - imageInfo.MediaType = MediaType.DOS_525_DS_DD_9; - else imageInfo.MediaType = MediaType.Unknown; + case MediaType.DOS_525_HD when header.diskType == RayDiskTypes.Mf2hd || + header.diskType == RayDiskTypes.Mf2ed: + imageInfo.MediaType = MediaType.NEC_35_HD_15; break; - case RayDiskTypes.Mf2ed: - if(imageInfo.Heads == 2 && imageInfo.Cylinders == 80 && imageInfo.SectorsPerTrack == 36) - imageInfo.MediaType = MediaType.DOS_35_ED; - else goto case RayDiskTypes.Mf2hd; - break; - case RayDiskTypes.Mf2hd: - if(imageInfo.Heads == 2 && imageInfo.Cylinders == 80 && imageInfo.SectorsPerTrack == 18) - imageInfo.MediaType = MediaType.DOS_35_HD; - else if(imageInfo.Heads == 2 && imageInfo.Cylinders == 80 && imageInfo.SectorsPerTrack == 21) - imageInfo.MediaType = MediaType.DMF; - else if(imageInfo.Heads == 2 && imageInfo.Cylinders == 82 && imageInfo.SectorsPerTrack == 21) - imageInfo.MediaType = MediaType.DMF_82; - else if(imageInfo.Heads == 2 && imageInfo.Cylinders == 80 && imageInfo.SectorsPerTrack == 15) - imageInfo.MediaType = MediaType.NEC_35_HD_15; - else goto case RayDiskTypes.Mf2dd; - break; - case RayDiskTypes.Mf2dd: - if(imageInfo.Heads == 2 && imageInfo.Cylinders == 80 && imageInfo.SectorsPerTrack == 9) - imageInfo.MediaType = MediaType.DOS_35_DS_DD_9; - else if(imageInfo.Heads == 2 && imageInfo.Cylinders == 80 && imageInfo.SectorsPerTrack == 8) - imageInfo.MediaType = MediaType.DOS_35_DS_DD_8; - else if(imageInfo.Heads == 1 && imageInfo.Cylinders == 80 && imageInfo.SectorsPerTrack == 9) - imageInfo.MediaType = MediaType.DOS_35_SS_DD_9; - else if(imageInfo.Heads == 1 && imageInfo.Cylinders == 80 && imageInfo.SectorsPerTrack == 8) - imageInfo.MediaType = MediaType.DOS_35_SS_DD_8; - else if(imageInfo.Heads == 1 && imageInfo.Cylinders == 70 && imageInfo.SectorsPerTrack == 9) - imageInfo.MediaType = MediaType.Apricot_35; - else imageInfo.MediaType = MediaType.Unknown; - break; - default: - imageInfo.MediaType = MediaType.Unknown; + case MediaType.RX50 when header.diskType == RayDiskTypes.Md2dd || header.diskType == RayDiskTypes.Md2hd: + imageInfo.MediaType = MediaType.ATARI_35_SS_DD; break; } @@ -232,7 +198,7 @@ namespace DiscImageChef.DiscImages } public bool? VerifySectors(ulong sectorAddress, uint length, out List failingLbas, - out List unknownLbas) + out List unknownLbas) { failingLbas = new List(); unknownLbas = new List(); @@ -243,7 +209,7 @@ namespace DiscImageChef.DiscImages } public bool? VerifySectors(ulong sectorAddress, uint length, uint track, out List failingLbas, - out List unknownLbas) + out List unknownLbas) { failingLbas = new List(); unknownLbas = new List(); @@ -278,7 +244,7 @@ namespace DiscImageChef.DiscImages byte[] buffer = new byte[length * imageInfo.SectorSize]; - disk.Seek((long)(sectorAddress * imageInfo.SectorSize), SeekOrigin.Begin); + disk.Seek((long)(sectorAddress * imageInfo.SectorSize), SeekOrigin.Begin); disk.Read(buffer, 0, (int)(length * imageInfo.SectorSize)); return buffer; @@ -347,11 +313,12 @@ namespace DiscImageChef.DiscImages [StructLayout(LayoutKind.Sequential, Pack = 1)] struct RayHdr { - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 80)] public byte[] signature; + [MarshalAs(UnmanagedType.ByValArray, SizeConst = 80)] + public byte[] signature; public RayDiskTypes diskType; - public byte cylinders; - public byte sectorsPerTrack; - public byte heads; + public byte cylinders; + public byte sectorsPerTrack; + public byte heads; } [SuppressMessage("ReSharper", "InconsistentNaming")] diff --git a/DiscImageChef.DiscImages/SaveDskF.cs b/DiscImageChef.DiscImages/SaveDskF.cs index 4626e1c5..51226b9a 100644 --- a/DiscImageChef.DiscImages/SaveDskF.cs +++ b/DiscImageChef.DiscImages/SaveDskF.cs @@ -43,44 +43,44 @@ namespace DiscImageChef.DiscImages { public class SaveDskF : IMediaImage { - const ushort SDF_MAGIC_OLD = 0x58AA; - const ushort SDF_MAGIC = 0x59AA; + const ushort SDF_MAGIC_OLD = 0x58AA; + const ushort SDF_MAGIC = 0x59AA; const ushort SDF_MAGIC_COMPRESSED = 0x5AAA; - uint calculatedChk; - byte[] decodedDisk; + uint calculatedChk; + byte[] decodedDisk; SaveDskFHeader header; - ImageInfo imageInfo; + ImageInfo imageInfo; public SaveDskF() { imageInfo = new ImageInfo { - ReadableSectorTags = new List(), - ReadableMediaTags = new List(), - HasPartitions = false, - HasSessions = false, - Version = null, - Application = null, - ApplicationVersion = null, - Creator = null, - Comments = null, - MediaManufacturer = null, - MediaModel = null, - MediaSerialNumber = null, - MediaBarcode = null, - MediaPartNumber = null, - MediaSequence = 0, - LastMediaSequence = 0, - DriveManufacturer = null, - DriveModel = null, - DriveSerialNumber = null, + ReadableSectorTags = new List(), + ReadableMediaTags = new List(), + HasPartitions = false, + HasSessions = false, + Version = null, + Application = null, + ApplicationVersion = null, + Creator = null, + Comments = null, + MediaManufacturer = null, + MediaModel = null, + MediaSerialNumber = null, + MediaBarcode = null, + MediaPartNumber = null, + MediaSequence = 0, + LastMediaSequence = 0, + DriveManufacturer = null, + DriveModel = null, + DriveSerialNumber = null, DriveFirmwareRevision = null }; } - public string Name => "IBM SaveDskF"; - public Guid Id => new Guid("288CE058-1A51-4034-8C45-5A256CAE1461"); + public string Name => "IBM SaveDskF"; + public Guid Id => new Guid("288CE058-1A51-4034-8C45-5A256CAE1461"); public ImageInfo Info => imageInfo; public string ImageFormat => "IBM SaveDskF"; @@ -103,15 +103,15 @@ namespace DiscImageChef.DiscImages byte[] hdr = new byte[40]; stream.Read(hdr, 0, 40); - header = new SaveDskFHeader(); + header = new SaveDskFHeader(); IntPtr hdrPtr = Marshal.AllocHGlobal(40); Marshal.Copy(hdr, 0, hdrPtr, 40); header = (SaveDskFHeader)Marshal.PtrToStructure(hdrPtr, typeof(SaveDskFHeader)); Marshal.FreeHGlobal(hdrPtr); - return (header.magic == SDF_MAGIC || header.magic == SDF_MAGIC_COMPRESSED || - header.magic == SDF_MAGIC_OLD) && header.fatCopies <= 2 && header.padding == 0 && - header.commentOffset < stream.Length && header.dataOffset < stream.Length; + return (header.magic == SDF_MAGIC || header.magic == SDF_MAGIC_COMPRESSED || + header.magic == SDF_MAGIC_OLD) && header.fatCopies <= 2 && header.padding == 0 && + header.commentOffset < stream.Length && header.dataOffset < stream.Length; } public bool OpenImage(IFilter imageFilter) @@ -122,31 +122,31 @@ namespace DiscImageChef.DiscImages byte[] hdr = new byte[40]; stream.Read(hdr, 0, 40); - header = new SaveDskFHeader(); + header = new SaveDskFHeader(); IntPtr hdrPtr = Marshal.AllocHGlobal(40); Marshal.Copy(hdr, 0, hdrPtr, 40); header = (SaveDskFHeader)Marshal.PtrToStructure(hdrPtr, typeof(SaveDskFHeader)); Marshal.FreeHGlobal(hdrPtr); - DicConsole.DebugWriteLine("SaveDskF plugin", "header.magic = 0x{0:X4}", header.magic); - DicConsole.DebugWriteLine("SaveDskF plugin", "header.mediaType = 0x{0:X2}", header.mediaType); - DicConsole.DebugWriteLine("SaveDskF plugin", "header.sectorSize = {0}", header.sectorSize); - DicConsole.DebugWriteLine("SaveDskF plugin", "header.clusterMask = {0}", header.clusterMask); - DicConsole.DebugWriteLine("SaveDskF plugin", "header.clusterShift = {0}", header.clusterShift); + DicConsole.DebugWriteLine("SaveDskF plugin", "header.magic = 0x{0:X4}", header.magic); + DicConsole.DebugWriteLine("SaveDskF plugin", "header.mediaType = 0x{0:X2}", header.mediaType); + DicConsole.DebugWriteLine("SaveDskF plugin", "header.sectorSize = {0}", header.sectorSize); + DicConsole.DebugWriteLine("SaveDskF plugin", "header.clusterMask = {0}", header.clusterMask); + DicConsole.DebugWriteLine("SaveDskF plugin", "header.clusterShift = {0}", header.clusterShift); DicConsole.DebugWriteLine("SaveDskF plugin", "header.reservedSectors = {0}", header.reservedSectors); - DicConsole.DebugWriteLine("SaveDskF plugin", "header.fatCopies = {0}", header.fatCopies); - DicConsole.DebugWriteLine("SaveDskF plugin", "header.rootEntries = {0}", header.rootEntries); - DicConsole.DebugWriteLine("SaveDskF plugin", "header.firstCluster = {0}", header.firstCluster); - DicConsole.DebugWriteLine("SaveDskF plugin", "header.clustersCopied = {0}", header.clustersCopied); - DicConsole.DebugWriteLine("SaveDskF plugin", "header.sectorsPerFat = {0}", header.sectorsPerFat); - DicConsole.DebugWriteLine("SaveDskF plugin", "header.checksum = 0x{0:X8}", header.checksum); - DicConsole.DebugWriteLine("SaveDskF plugin", "header.cylinders = {0}", header.cylinders); - DicConsole.DebugWriteLine("SaveDskF plugin", "header.heads = {0}", header.heads); + DicConsole.DebugWriteLine("SaveDskF plugin", "header.fatCopies = {0}", header.fatCopies); + DicConsole.DebugWriteLine("SaveDskF plugin", "header.rootEntries = {0}", header.rootEntries); + DicConsole.DebugWriteLine("SaveDskF plugin", "header.firstCluster = {0}", header.firstCluster); + DicConsole.DebugWriteLine("SaveDskF plugin", "header.clustersCopied = {0}", header.clustersCopied); + DicConsole.DebugWriteLine("SaveDskF plugin", "header.sectorsPerFat = {0}", header.sectorsPerFat); + DicConsole.DebugWriteLine("SaveDskF plugin", "header.checksum = 0x{0:X8}", header.checksum); + DicConsole.DebugWriteLine("SaveDskF plugin", "header.cylinders = {0}", header.cylinders); + DicConsole.DebugWriteLine("SaveDskF plugin", "header.heads = {0}", header.heads); DicConsole.DebugWriteLine("SaveDskF plugin", "header.sectorsPerTrack = {0}", header.sectorsPerTrack); - DicConsole.DebugWriteLine("SaveDskF plugin", "header.padding = {0}", header.padding); - DicConsole.DebugWriteLine("SaveDskF plugin", "header.sectorsCopied = {0}", header.sectorsCopied); - DicConsole.DebugWriteLine("SaveDskF plugin", "header.commentOffset = {0}", header.commentOffset); - DicConsole.DebugWriteLine("SaveDskF plugin", "header.dataOffset = {0}", header.dataOffset); + DicConsole.DebugWriteLine("SaveDskF plugin", "header.padding = {0}", header.padding); + DicConsole.DebugWriteLine("SaveDskF plugin", "header.sectorsCopied = {0}", header.sectorsCopied); + DicConsole.DebugWriteLine("SaveDskF plugin", "header.commentOffset = {0}", header.commentOffset); + DicConsole.DebugWriteLine("SaveDskF plugin", "header.dataOffset = {0}", header.dataOffset); if(header.dataOffset == 0 && header.magic == SDF_MAGIC_OLD) header.dataOffset = 512; @@ -161,7 +161,7 @@ namespace DiscImageChef.DiscImages int b; do { - b = stream.ReadByte(); + b = stream.ReadByte(); if(b >= 0) calculatedChk += (uint)b; } while(b >= 0); @@ -169,108 +169,17 @@ namespace DiscImageChef.DiscImages DicConsole.DebugWriteLine("SaveDskF plugin", "Calculated checksum = 0x{0:X8}, {1}", calculatedChk, calculatedChk == header.checksum); - imageInfo.Application = "SaveDskF"; - imageInfo.CreationTime = imageFilter.GetCreationTime(); + imageInfo.Application = "SaveDskF"; + imageInfo.CreationTime = imageFilter.GetCreationTime(); imageInfo.LastModificationTime = imageFilter.GetLastWriteTime(); - imageInfo.MediaTitle = imageFilter.GetFilename(); - imageInfo.ImageSize = (ulong)(stream.Length - header.dataOffset); - imageInfo.Sectors = (ulong)(header.sectorsPerTrack * header.heads * header.cylinders); - imageInfo.SectorSize = header.sectorSize; + imageInfo.MediaTitle = imageFilter.GetFilename(); + imageInfo.ImageSize = (ulong)(stream.Length - header.dataOffset); + imageInfo.Sectors = (ulong)(header.sectorsPerTrack * header.heads * header.cylinders); + imageInfo.SectorSize = header.sectorSize; - imageInfo.MediaType = MediaType.Unknown; - switch(header.cylinders) - { - case 40: - switch(header.heads) - { - case 1: - switch(header.sectorsPerTrack) - { - case 8: - imageInfo.MediaType = MediaType.DOS_525_SS_DD_8; - break; - case 9: - imageInfo.MediaType = MediaType.DOS_525_SS_DD_9; - break; - } - - break; - case 2: - switch(header.sectorsPerTrack) - { - case 8: - imageInfo.MediaType = MediaType.DOS_525_DS_DD_8; - break; - case 9: - imageInfo.MediaType = MediaType.DOS_525_DS_DD_9; - break; - } - - break; - } - - break; - case 70: - switch(header.heads) - { - case 1: - switch(header.sectorsPerTrack) - { - case 9: - imageInfo.MediaType = MediaType.Apricot_35; - break; - } - - break; - } - - break; - case 80: - switch(header.heads) - { - case 1: - switch(header.sectorsPerTrack) - { - case 8: - imageInfo.MediaType = MediaType.DOS_35_SS_DD_8; - break; - case 9: - imageInfo.MediaType = MediaType.DOS_35_SS_DD_9; - break; - } - - break; - case 2: - switch(header.sectorsPerTrack) - { - case 8: - imageInfo.MediaType = MediaType.DOS_35_DS_DD_8; - break; - case 9: - imageInfo.MediaType = MediaType.DOS_35_DS_DD_9; - break; - case 15: - imageInfo.MediaType = MediaType.DOS_525_HD; - break; - case 18: - imageInfo.MediaType = MediaType.DOS_35_HD; - break; - case 23: - imageInfo.MediaType = MediaType.XDF_35; - break; - case 36: - imageInfo.MediaType = MediaType.DOS_35_ED; - break; - } - - break; - } - - break; - default: - imageInfo.MediaType = MediaType.Unknown; - break; - } + imageInfo.MediaType = + Geometry.GetMediaType((header.cylinders, (byte)header.heads, header.sectorsPerTrack, header.sectorSize, + MediaEncoding.MFM, false)); imageInfo.XmlMediaType = XmlMediaType.BlockMedia; @@ -288,8 +197,8 @@ namespace DiscImageChef.DiscImages decodedDisk = new byte[imageInfo.Sectors * imageInfo.SectorSize]; stream.Read(decodedDisk, 0, (int)(stream.Length - header.dataOffset)); - imageInfo.Cylinders = header.cylinders; - imageInfo.Heads = header.heads; + imageInfo.Cylinders = header.cylinders; + imageInfo.Heads = header.heads; imageInfo.SectorsPerTrack = header.sectorsPerTrack; return true; @@ -306,7 +215,7 @@ namespace DiscImageChef.DiscImages } public bool? VerifySectors(ulong sectorAddress, uint length, out List failingLbas, - out List unknownLbas) + out List unknownLbas) { failingLbas = new List(); unknownLbas = new List(); @@ -317,7 +226,7 @@ namespace DiscImageChef.DiscImages } public bool? VerifySectors(ulong sectorAddress, uint length, uint track, out List failingLbas, - out List unknownLbas) + out List unknownLbas) { failingLbas = new List(); unknownLbas = new List(); @@ -348,7 +257,7 @@ namespace DiscImageChef.DiscImages byte[] buffer = new byte[length * imageInfo.SectorSize]; Array.Copy(decodedDisk, (int)sectorAddress * imageInfo.SectorSize, buffer, 0, - length * imageInfo.SectorSize); + length * imageInfo.SectorSize); return buffer; } diff --git a/DiscImageChef.DiscImages/ZZZRawImage.cs b/DiscImageChef.DiscImages/ZZZRawImage.cs index 63732cff..eaf9af94 100644 --- a/DiscImageChef.DiscImages/ZZZRawImage.cs +++ b/DiscImageChef.DiscImages/ZZZRawImage.cs @@ -41,41 +41,41 @@ namespace DiscImageChef.DiscImages { public class ZZZRawImage : IMediaImage { - bool differentTrackZeroSize; - string extension; + bool differentTrackZeroSize; + string extension; ImageInfo imageInfo; - IFilter rawImageFilter; + IFilter rawImageFilter; public ZZZRawImage() { imageInfo = new ImageInfo { - ReadableSectorTags = new List(), - ReadableMediaTags = new List(), - HasPartitions = false, - HasSessions = false, - Version = null, - Application = null, - ApplicationVersion = null, - Creator = null, - Comments = null, - MediaManufacturer = null, - MediaModel = null, - MediaSerialNumber = null, - MediaBarcode = null, - MediaPartNumber = null, - MediaSequence = 0, - LastMediaSequence = 0, - DriveManufacturer = null, - DriveModel = null, - DriveSerialNumber = null, + ReadableSectorTags = new List(), + ReadableMediaTags = new List(), + HasPartitions = false, + HasSessions = false, + Version = null, + Application = null, + ApplicationVersion = null, + Creator = null, + Comments = null, + MediaManufacturer = null, + MediaModel = null, + MediaSerialNumber = null, + MediaBarcode = null, + MediaPartNumber = null, + MediaSequence = 0, + LastMediaSequence = 0, + DriveManufacturer = null, + DriveModel = null, + DriveSerialNumber = null, DriveFirmwareRevision = null }; } public string Name => "Raw Disk Image"; // Non-random UUID to recognize this specific plugin - public Guid Id => new Guid("12345678-AAAA-BBBB-CCCC-123456789000"); + public Guid Id => new Guid("12345678-AAAA-BBBB-CCCC-123456789000"); public ImageInfo Info => imageInfo; public string ImageFormat => "Raw disk image (sector by sector copy)"; @@ -89,17 +89,17 @@ namespace DiscImageChef.DiscImages Track trk = new Track { - TrackBytesPerSector = (int)imageInfo.SectorSize, - TrackEndSector = imageInfo.Sectors - 1, - TrackFile = rawImageFilter.GetFilename(), - TrackFileOffset = 0, - TrackFileType = "BINARY", + TrackBytesPerSector = (int)imageInfo.SectorSize, + TrackEndSector = imageInfo.Sectors - 1, + TrackFile = rawImageFilter.GetFilename(), + TrackFileOffset = 0, + TrackFileType = "BINARY", TrackRawBytesPerSector = (int)imageInfo.SectorSize, - TrackSequence = 1, - TrackStartSector = 0, - TrackSubchannelType = TrackSubchannelType.None, - TrackType = TrackType.Data, - TrackSession = 1 + TrackSequence = 1, + TrackStartSector = 0, + TrackSubchannelType = TrackSubchannelType.None, + TrackType = TrackType.Data, + TrackSession = 1 }; List lst = new List {trk}; return lst; @@ -115,11 +115,11 @@ namespace DiscImageChef.DiscImages Session sess = new Session { - EndSector = imageInfo.Sectors - 1, - EndTrack = 1, + EndSector = imageInfo.Sectors - 1, + EndTrack = 1, SessionSequence = 1, - StartSector = 0, - StartTrack = 1 + StartSector = 0, + StartTrack = 1 }; List lst = new List {sess}; return lst; @@ -134,14 +134,14 @@ namespace DiscImageChef.DiscImages throw new FeatureUnsupportedImageException("Feature not supported by image format"); List parts = new List(); - Partition part = new Partition + Partition part = new Partition { - Start = 0, - Length = imageInfo.Sectors, - Offset = 0, + Start = 0, + Length = imageInfo.Sectors, + Offset = 0, Sequence = 0, - Type = "MODE1/2048", - Size = imageInfo.Sectors * imageInfo.SectorSize + Type = "MODE1/2048", + Size = imageInfo.Sectors * imageInfo.SectorSize }; parts.Add(part); return parts; @@ -183,7 +183,7 @@ namespace DiscImageChef.DiscImages case 1222400: case 1304320: case 1255168: return true; - default: return false; + default: return false; } } @@ -202,10 +202,12 @@ namespace DiscImageChef.DiscImages imageInfo.SectorSize = 256; break; default: - if((extension == ".adf" || extension == ".adl" || extension == ".ssd" || extension == ".dsd") && - (imageFilter.GetDataForkLength() == 163840 || imageFilter.GetDataForkLength() == 327680 || - imageFilter.GetDataForkLength() == 655360)) imageInfo.SectorSize = 256; - else if((extension == ".adf" || extension == ".adl") && imageFilter.GetDataForkLength() == 819200) + if((extension == ".adf" || extension == ".adl" || + extension == ".ssd" || extension == ".dsd") && + (imageFilter.GetDataForkLength() == 163840 || imageFilter.GetDataForkLength() == 327680 || + imageFilter.GetDataForkLength() == 655360)) imageInfo.SectorSize = 256; + else if((extension == ".adf" || extension == ".adl") && + imageFilter.GetDataForkLength() == 819200) imageInfo.SectorSize = 1024; else switch(imageFilter.GetDataForkLength()) @@ -218,9 +220,9 @@ namespace DiscImageChef.DiscImages imageInfo.SectorSize = 128; break; case 116480: - case 287488: // T0S0 = 128bps - case 988416: // T0S0 = 128bps - case 995072: // T0S0 = 128bps, T0S1 = 256bps + case 287488: // T0S0 = 128bps + case 988416: // T0S0 = 128bps + case 995072: // T0S0 = 128bps, T0S1 = 256bps case 1021696: // T0S0 = 128bps, T0S1 = 256bps case 232960: case 143360: @@ -229,7 +231,7 @@ namespace DiscImageChef.DiscImages case 102400: case 204800: case 655360: - case 80384: // T0S0 = 128bps + case 80384: // T0S0 = 128bps case 325632: // T0S0 = 128bps, T0S1 = 256bps case 653312: // T0S0 = 128bps, T0S1 = 256bps @@ -248,7 +250,7 @@ namespace DiscImageChef.DiscImages case 81664: imageInfo.SectorSize = 319; break; - case 306432: // T0S0 = 128bps + case 306432: // T0S0 = 128bps case 1146624: // T0S0 = 128bps, T0S1 = 256bps case 1177344: // T0S0 = 128bps, T0S1 = 256bps imageInfo.SectorSize = 512; @@ -268,12 +270,12 @@ namespace DiscImageChef.DiscImages break; } - imageInfo.ImageSize = (ulong)imageFilter.GetDataForkLength(); - imageInfo.CreationTime = imageFilter.GetCreationTime(); + imageInfo.ImageSize = (ulong)imageFilter.GetDataForkLength(); + imageInfo.CreationTime = imageFilter.GetCreationTime(); imageInfo.LastModificationTime = imageFilter.GetLastWriteTime(); - imageInfo.MediaTitle = Path.GetFileNameWithoutExtension(imageFilter.GetFilename()); - differentTrackZeroSize = false; - rawImageFilter = imageFilter; + imageInfo.MediaTitle = Path.GetFileNameWithoutExtension(imageFilter.GetFilename()); + differentTrackZeroSize = false; + rawImageFilter = imageFilter; switch(imageFilter.GetDataForkLength()) { @@ -290,63 +292,63 @@ namespace DiscImageChef.DiscImages imageInfo.Sectors = 455; break; case 287488: // T0S0 = 128bps - imageInfo.Sectors = 1136; + imageInfo.Sectors = 1136; differentTrackZeroSize = true; break; case 988416: // T0S0 = 128bps - imageInfo.Sectors = 3874; + imageInfo.Sectors = 3874; differentTrackZeroSize = true; break; case 995072: // T0S0 = 128bps, T0S1 = 256bps - imageInfo.Sectors = 3900; + imageInfo.Sectors = 3900; differentTrackZeroSize = true; break; case 1021696: // T0S0 = 128bps, T0S1 = 256bps - imageInfo.Sectors = 4004; + imageInfo.Sectors = 4004; differentTrackZeroSize = true; break; case 81664: imageInfo.Sectors = 256; break; case 306432: // T0S0 = 128bps - imageInfo.Sectors = 618; + imageInfo.Sectors = 618; differentTrackZeroSize = true; break; case 1146624: // T0S0 = 128bps, T0S1 = 256bps - imageInfo.Sectors = 2272; + imageInfo.Sectors = 2272; differentTrackZeroSize = true; break; case 1177344: // T0S0 = 128bps, T0S1 = 256bps - imageInfo.Sectors = 2332; + imageInfo.Sectors = 2332; differentTrackZeroSize = true; break; case 1222400: // T0S0 = 128bps, T0S1 = 256bps - imageInfo.Sectors = 1236; + imageInfo.Sectors = 1236; differentTrackZeroSize = true; break; case 1304320: // T0S0 = 128bps, T0S1 = 256bps - imageInfo.Sectors = 1316; + imageInfo.Sectors = 1316; differentTrackZeroSize = true; break; case 1255168: // T0S0 = 128bps, T0S1 = 256bps - imageInfo.Sectors = 1268; + imageInfo.Sectors = 1268; differentTrackZeroSize = true; break; case 80384: // T0S0 = 128bps - imageInfo.Sectors = 322; + imageInfo.Sectors = 322; differentTrackZeroSize = true; break; case 325632: // T0S0 = 128bps, T0S1 = 256bps - imageInfo.Sectors = 1280; + imageInfo.Sectors = 1280; differentTrackZeroSize = true; break; case 653312: // T0S0 = 128bps, T0S1 = 256bps - imageInfo.Sectors = 2560; + imageInfo.Sectors = 2560; differentTrackZeroSize = true; break; case 1880064: // IBM XDF, 3,5", real number of sectors - imageInfo.Sectors = 670; - imageInfo.SectorSize = 8192; // Biggest sector size + imageInfo.Sectors = 670; + imageInfo.SectorSize = 8192; // Biggest sector size differentTrackZeroSize = true; break; case 175531: @@ -385,17 +387,17 @@ namespace DiscImageChef.DiscImages } // Sharp X68000 SASI hard disks - if(extension == ".hdf") + if(extension == ".hdf") if(imageInfo.ImageSize % 256 == 0) { imageInfo.SectorSize = 256; - imageInfo.Sectors = imageInfo.ImageSize / imageInfo.SectorSize; - imageInfo.MediaType = MediaType.GENERIC_HDD; + imageInfo.Sectors = imageInfo.ImageSize / imageInfo.SectorSize; + imageInfo.MediaType = MediaType.GENERIC_HDD; } if(imageInfo.XmlMediaType == XmlMediaType.OpticalDisc) { - imageInfo.HasSessions = true; + imageInfo.HasSessions = true; imageInfo.HasPartitions = true; } @@ -404,319 +406,319 @@ namespace DiscImageChef.DiscImages switch(imageInfo.MediaType) { case MediaType.ACORN_35_DS_DD: - imageInfo.Cylinders = 80; - imageInfo.Heads = 2; + imageInfo.Cylinders = 80; + imageInfo.Heads = 2; imageInfo.SectorsPerTrack = 5; break; case MediaType.ACORN_35_DS_HD: - imageInfo.Cylinders = 80; - imageInfo.Heads = 2; + imageInfo.Cylinders = 80; + imageInfo.Heads = 2; imageInfo.SectorsPerTrack = 10; break; case MediaType.ACORN_525_DS_DD: - imageInfo.Cylinders = 80; - imageInfo.Heads = 2; + imageInfo.Cylinders = 80; + imageInfo.Heads = 2; imageInfo.SectorsPerTrack = 16; break; case MediaType.ACORN_525_SS_DD_40: - imageInfo.Cylinders = 40; - imageInfo.Heads = 1; + imageInfo.Cylinders = 40; + imageInfo.Heads = 1; imageInfo.SectorsPerTrack = 16; break; case MediaType.ACORN_525_SS_DD_80: - imageInfo.Cylinders = 80; - imageInfo.Heads = 1; + imageInfo.Cylinders = 80; + imageInfo.Heads = 1; imageInfo.SectorsPerTrack = 16; break; case MediaType.ACORN_525_SS_SD_40: - imageInfo.Cylinders = 40; - imageInfo.Heads = 1; + imageInfo.Cylinders = 40; + imageInfo.Heads = 1; imageInfo.SectorsPerTrack = 10; break; case MediaType.ACORN_525_SS_SD_80: - imageInfo.Cylinders = 80; - imageInfo.Heads = 1; + imageInfo.Cylinders = 80; + imageInfo.Heads = 1; imageInfo.SectorsPerTrack = 10; break; case MediaType.Apple32DS: - imageInfo.Cylinders = 35; - imageInfo.Heads = 2; + imageInfo.Cylinders = 35; + imageInfo.Heads = 2; imageInfo.SectorsPerTrack = 13; break; case MediaType.Apple32SS: - imageInfo.Cylinders = 36; - imageInfo.Heads = 1; + imageInfo.Cylinders = 36; + imageInfo.Heads = 1; imageInfo.SectorsPerTrack = 13; break; case MediaType.Apple33DS: - imageInfo.Cylinders = 35; - imageInfo.Heads = 2; + imageInfo.Cylinders = 35; + imageInfo.Heads = 2; imageInfo.SectorsPerTrack = 16; break; case MediaType.Apple33SS: - imageInfo.Cylinders = 35; - imageInfo.Heads = 2; + imageInfo.Cylinders = 35; + imageInfo.Heads = 2; imageInfo.SectorsPerTrack = 16; break; case MediaType.AppleSonyDS: - imageInfo.Cylinders = 80; - imageInfo.Heads = 2; + imageInfo.Cylinders = 80; + imageInfo.Heads = 2; imageInfo.SectorsPerTrack = 10; break; case MediaType.AppleSonySS: - imageInfo.Cylinders = 80; - imageInfo.Heads = 1; + imageInfo.Cylinders = 80; + imageInfo.Heads = 1; imageInfo.SectorsPerTrack = 10; break; case MediaType.ATARI_35_DS_DD: - imageInfo.Cylinders = 80; - imageInfo.Heads = 2; + imageInfo.Cylinders = 80; + imageInfo.Heads = 2; imageInfo.SectorsPerTrack = 10; break; case MediaType.ATARI_35_DS_DD_11: - imageInfo.Cylinders = 80; - imageInfo.Heads = 2; + imageInfo.Cylinders = 80; + imageInfo.Heads = 2; imageInfo.SectorsPerTrack = 11; break; case MediaType.ATARI_35_SS_DD: - imageInfo.Cylinders = 80; - imageInfo.Heads = 1; + imageInfo.Cylinders = 80; + imageInfo.Heads = 1; imageInfo.SectorsPerTrack = 10; break; case MediaType.ATARI_35_SS_DD_11: - imageInfo.Cylinders = 80; - imageInfo.Heads = 1; + imageInfo.Cylinders = 80; + imageInfo.Heads = 1; imageInfo.SectorsPerTrack = 11; break; case MediaType.ATARI_525_ED: - imageInfo.Cylinders = 40; - imageInfo.Heads = 1; + imageInfo.Cylinders = 40; + imageInfo.Heads = 1; imageInfo.SectorsPerTrack = 26; break; case MediaType.ATARI_525_SD: - imageInfo.Cylinders = 40; - imageInfo.Heads = 1; + imageInfo.Cylinders = 40; + imageInfo.Heads = 1; imageInfo.SectorsPerTrack = 18; break; case MediaType.CBM_35_DD: - imageInfo.Cylinders = 80; - imageInfo.Heads = 2; + imageInfo.Cylinders = 80; + imageInfo.Heads = 2; imageInfo.SectorsPerTrack = 10; break; case MediaType.CBM_AMIGA_35_DD: - imageInfo.Cylinders = 80; - imageInfo.Heads = 2; + imageInfo.Cylinders = 80; + imageInfo.Heads = 2; imageInfo.SectorsPerTrack = 11; break; case MediaType.CBM_AMIGA_35_HD: - imageInfo.Cylinders = 80; - imageInfo.Heads = 2; + imageInfo.Cylinders = 80; + imageInfo.Heads = 2; imageInfo.SectorsPerTrack = 22; break; case MediaType.DMF: - imageInfo.Cylinders = 80; - imageInfo.Heads = 2; + imageInfo.Cylinders = 80; + imageInfo.Heads = 2; imageInfo.SectorsPerTrack = 21; break; case MediaType.DOS_35_DS_DD_9: - imageInfo.Cylinders = 80; - imageInfo.Heads = 2; + imageInfo.Cylinders = 80; + imageInfo.Heads = 2; imageInfo.SectorsPerTrack = 9; break; case MediaType.Apricot_35: - imageInfo.Cylinders = 70; - imageInfo.Heads = 1; + imageInfo.Cylinders = 70; + imageInfo.Heads = 2; imageInfo.SectorsPerTrack = 9; break; case MediaType.DOS_35_ED: - imageInfo.Cylinders = 80; - imageInfo.Heads = 2; + imageInfo.Cylinders = 80; + imageInfo.Heads = 2; imageInfo.SectorsPerTrack = 36; break; case MediaType.DOS_35_HD: - imageInfo.Cylinders = 80; - imageInfo.Heads = 2; + imageInfo.Cylinders = 80; + imageInfo.Heads = 2; imageInfo.SectorsPerTrack = 18; break; case MediaType.DOS_35_SS_DD_9: - imageInfo.Cylinders = 80; - imageInfo.Heads = 1; + imageInfo.Cylinders = 80; + imageInfo.Heads = 1; imageInfo.SectorsPerTrack = 9; break; case MediaType.DOS_525_DS_DD_8: - imageInfo.Cylinders = 40; - imageInfo.Heads = 2; + imageInfo.Cylinders = 40; + imageInfo.Heads = 2; imageInfo.SectorsPerTrack = 8; break; case MediaType.DOS_525_DS_DD_9: - imageInfo.Cylinders = 40; - imageInfo.Heads = 2; + imageInfo.Cylinders = 40; + imageInfo.Heads = 2; imageInfo.SectorsPerTrack = 9; break; case MediaType.DOS_525_HD: - imageInfo.Cylinders = 80; - imageInfo.Heads = 2; + imageInfo.Cylinders = 80; + imageInfo.Heads = 2; imageInfo.SectorsPerTrack = 15; break; case MediaType.DOS_525_SS_DD_8: - imageInfo.Cylinders = 40; - imageInfo.Heads = 1; + imageInfo.Cylinders = 40; + imageInfo.Heads = 1; imageInfo.SectorsPerTrack = 8; break; case MediaType.DOS_525_SS_DD_9: - imageInfo.Cylinders = 40; - imageInfo.Heads = 1; + imageInfo.Cylinders = 40; + imageInfo.Heads = 1; imageInfo.SectorsPerTrack = 9; break; case MediaType.ECMA_54: - imageInfo.Cylinders = 77; - imageInfo.Heads = 1; + imageInfo.Cylinders = 77; + imageInfo.Heads = 1; imageInfo.SectorsPerTrack = 26; break; case MediaType.ECMA_59: - imageInfo.Cylinders = 77; - imageInfo.Heads = 2; + imageInfo.Cylinders = 77; + imageInfo.Heads = 2; imageInfo.SectorsPerTrack = 26; break; case MediaType.ECMA_66: - imageInfo.Cylinders = 35; - imageInfo.Heads = 1; + imageInfo.Cylinders = 35; + imageInfo.Heads = 1; imageInfo.SectorsPerTrack = 9; break; case MediaType.ECMA_69_8: - imageInfo.Cylinders = 77; - imageInfo.Heads = 2; + imageInfo.Cylinders = 77; + imageInfo.Heads = 2; imageInfo.SectorsPerTrack = 8; break; case MediaType.ECMA_70: - imageInfo.Cylinders = 40; - imageInfo.Heads = 2; + imageInfo.Cylinders = 40; + imageInfo.Heads = 2; imageInfo.SectorsPerTrack = 16; break; case MediaType.ECMA_78: - imageInfo.Cylinders = 80; - imageInfo.Heads = 2; + imageInfo.Cylinders = 80; + imageInfo.Heads = 2; imageInfo.SectorsPerTrack = 16; break; case MediaType.ECMA_99_15: - imageInfo.Cylinders = 77; - imageInfo.Heads = 2; + imageInfo.Cylinders = 77; + imageInfo.Heads = 2; imageInfo.SectorsPerTrack = 15; break; case MediaType.ECMA_99_26: - imageInfo.Cylinders = 77; - imageInfo.Heads = 2; + imageInfo.Cylinders = 77; + imageInfo.Heads = 2; imageInfo.SectorsPerTrack = 26; break; case MediaType.ECMA_99_8: - imageInfo.Cylinders = 80; - imageInfo.Heads = 2; + imageInfo.Cylinders = 80; + imageInfo.Heads = 2; imageInfo.SectorsPerTrack = 8; break; case MediaType.FDFORMAT_35_DD: - imageInfo.Cylinders = 82; - imageInfo.Heads = 2; + imageInfo.Cylinders = 82; + imageInfo.Heads = 2; imageInfo.SectorsPerTrack = 10; break; case MediaType.FDFORMAT_35_HD: - imageInfo.Cylinders = 82; - imageInfo.Heads = 2; + imageInfo.Cylinders = 82; + imageInfo.Heads = 2; imageInfo.SectorsPerTrack = 21; break; case MediaType.FDFORMAT_525_HD: - imageInfo.Cylinders = 82; - imageInfo.Heads = 2; + imageInfo.Cylinders = 82; + imageInfo.Heads = 2; imageInfo.SectorsPerTrack = 17; break; case MediaType.IBM23FD: - imageInfo.Cylinders = 32; - imageInfo.Heads = 1; + imageInfo.Cylinders = 32; + imageInfo.Heads = 1; imageInfo.SectorsPerTrack = 8; break; case MediaType.IBM33FD_128: - imageInfo.Cylinders = 73; - imageInfo.Heads = 1; + imageInfo.Cylinders = 73; + imageInfo.Heads = 1; imageInfo.SectorsPerTrack = 26; break; case MediaType.IBM33FD_256: - imageInfo.Cylinders = 74; - imageInfo.Heads = 1; + imageInfo.Cylinders = 74; + imageInfo.Heads = 1; imageInfo.SectorsPerTrack = 15; break; case MediaType.IBM33FD_512: - imageInfo.Cylinders = 74; - imageInfo.Heads = 1; + imageInfo.Cylinders = 74; + imageInfo.Heads = 1; imageInfo.SectorsPerTrack = 8; break; case MediaType.IBM43FD_128: - imageInfo.Cylinders = 74; - imageInfo.Heads = 2; + imageInfo.Cylinders = 74; + imageInfo.Heads = 2; imageInfo.SectorsPerTrack = 26; break; case MediaType.IBM43FD_256: - imageInfo.Cylinders = 74; - imageInfo.Heads = 2; + imageInfo.Cylinders = 74; + imageInfo.Heads = 2; imageInfo.SectorsPerTrack = 15; break; case MediaType.IBM53FD_1024: - imageInfo.Cylinders = 74; - imageInfo.Heads = 2; + imageInfo.Cylinders = 74; + imageInfo.Heads = 2; imageInfo.SectorsPerTrack = 8; break; case MediaType.IBM53FD_256: - imageInfo.Cylinders = 74; - imageInfo.Heads = 2; + imageInfo.Cylinders = 74; + imageInfo.Heads = 2; imageInfo.SectorsPerTrack = 26; break; case MediaType.IBM53FD_512: - imageInfo.Cylinders = 74; - imageInfo.Heads = 2; + imageInfo.Cylinders = 74; + imageInfo.Heads = 2; imageInfo.SectorsPerTrack = 15; break; case MediaType.NEC_35_TD: - imageInfo.Cylinders = 240; - imageInfo.Heads = 2; + imageInfo.Cylinders = 240; + imageInfo.Heads = 2; imageInfo.SectorsPerTrack = 38; break; case MediaType.NEC_525_HD: - imageInfo.Cylinders = 77; - imageInfo.Heads = 2; + imageInfo.Cylinders = 77; + imageInfo.Heads = 2; imageInfo.SectorsPerTrack = 8; break; case MediaType.XDF_35: - imageInfo.Cylinders = 80; - imageInfo.Heads = 2; + imageInfo.Cylinders = 80; + imageInfo.Heads = 2; imageInfo.SectorsPerTrack = 23; break; // Following ones are what the device itself report, not the physical geometry case MediaType.Jaz: - imageInfo.Cylinders = 1021; - imageInfo.Heads = 64; + imageInfo.Cylinders = 1021; + imageInfo.Heads = 64; imageInfo.SectorsPerTrack = 32; break; case MediaType.PocketZip: - imageInfo.Cylinders = 154; - imageInfo.Heads = 16; + imageInfo.Cylinders = 154; + imageInfo.Heads = 16; imageInfo.SectorsPerTrack = 32; break; case MediaType.LS120: - imageInfo.Cylinders = 963; - imageInfo.Heads = 8; + imageInfo.Cylinders = 963; + imageInfo.Heads = 8; imageInfo.SectorsPerTrack = 32; break; case MediaType.LS240: - imageInfo.Cylinders = 262; - imageInfo.Heads = 32; + imageInfo.Cylinders = 262; + imageInfo.Heads = 32; imageInfo.SectorsPerTrack = 56; break; case MediaType.FD32MB: - imageInfo.Cylinders = 1024; - imageInfo.Heads = 2; + imageInfo.Cylinders = 1024; + imageInfo.Heads = 2; imageInfo.SectorsPerTrack = 32; break; default: - imageInfo.Cylinders = (uint)(imageInfo.Sectors / 16 / 63); - imageInfo.Heads = 16; + imageInfo.Cylinders = (uint)(imageInfo.Sectors / 16 / 63); + imageInfo.Heads = 16; imageInfo.SectorsPerTrack = 63; break; } @@ -761,7 +763,7 @@ namespace DiscImageChef.DiscImages } public bool? VerifySectors(ulong sectorAddress, uint length, out List failingLbas, - out List unknownLbas) + out List unknownLbas) { failingLbas = new List(); unknownLbas = new List(); @@ -772,7 +774,7 @@ namespace DiscImageChef.DiscImages } public bool? VerifySectors(ulong sectorAddress, uint length, uint track, out List failingLbas, - out List unknownLbas) + out List unknownLbas) { failingLbas = new List(); unknownLbas = new List(); @@ -797,18 +799,18 @@ namespace DiscImageChef.DiscImages Track trk = new Track { - TrackBytesPerSector = (int)imageInfo.SectorSize, - TrackEndSector = imageInfo.Sectors - 1, - TrackFilter = rawImageFilter, - TrackFile = rawImageFilter.GetFilename(), - TrackFileOffset = 0, - TrackFileType = "BINARY", + TrackBytesPerSector = (int)imageInfo.SectorSize, + TrackEndSector = imageInfo.Sectors - 1, + TrackFilter = rawImageFilter, + TrackFile = rawImageFilter.GetFilename(), + TrackFileOffset = 0, + TrackFileType = "BINARY", TrackRawBytesPerSector = (int)imageInfo.SectorSize, - TrackSequence = 1, - TrackStartSector = 0, - TrackSubchannelType = TrackSubchannelType.None, - TrackType = TrackType.Data, - TrackSession = 1 + TrackSequence = 1, + TrackStartSector = 0, + TrackSubchannelType = TrackSubchannelType.None, + TrackType = TrackType.Data, + TrackSession = 1 }; List lst = new List {trk}; return lst; @@ -824,18 +826,18 @@ namespace DiscImageChef.DiscImages Track trk = new Track { - TrackBytesPerSector = (int)imageInfo.SectorSize, - TrackEndSector = imageInfo.Sectors - 1, - TrackFilter = rawImageFilter, - TrackFile = rawImageFilter.GetFilename(), - TrackFileOffset = 0, - TrackFileType = "BINARY", + TrackBytesPerSector = (int)imageInfo.SectorSize, + TrackEndSector = imageInfo.Sectors - 1, + TrackFilter = rawImageFilter, + TrackFile = rawImageFilter.GetFilename(), + TrackFileOffset = 0, + TrackFileType = "BINARY", TrackRawBytesPerSector = (int)imageInfo.SectorSize, - TrackSequence = 1, - TrackStartSector = 0, - TrackSubchannelType = TrackSubchannelType.None, - TrackType = TrackType.Data, - TrackSession = 1 + TrackSequence = 1, + TrackStartSector = 0, + TrackSubchannelType = TrackSubchannelType.None, + TrackType = TrackType.Data, + TrackSession = 1 }; List lst = new List {trk}; return lst; @@ -881,6 +883,41 @@ namespace DiscImageChef.DiscImages return ReadSectors(sectorAddress, length); } + public byte[] ReadSectorTag(ulong sectorAddress, SectorTagType tag) + { + throw new FeatureUnsupportedImageException("Feature not supported by image format"); + } + + public byte[] ReadSectorsTag(ulong sectorAddress, uint length, SectorTagType tag) + { + throw new FeatureUnsupportedImageException("Feature not supported by image format"); + } + + public byte[] ReadSectorLong(ulong sectorAddress) + { + throw new FeatureUnsupportedImageException("Feature not supported by image format"); + } + + public byte[] ReadSectorsLong(ulong sectorAddress, uint length) + { + throw new FeatureUnsupportedImageException("Feature not supported by image format"); + } + + public byte[] ReadDiskTag(MediaTagType tag) + { + throw new FeatureUnsupportedImageException("Feature not supported by image format"); + } + + public byte[] ReadSectorTag(ulong sectorAddress, uint track, SectorTagType tag) + { + throw new FeatureUnsupportedImageException("Feature not supported by image format"); + } + + public byte[] ReadSectorsTag(ulong sectorAddress, uint length, uint track, SectorTagType tag) + { + throw new FeatureUnsupportedImageException("Feature not supported by image format"); + } + MediaType CalculateDiskType() { if(imageInfo.SectorSize == 2048) @@ -897,9 +934,9 @@ namespace DiscImageChef.DiscImages switch(imageInfo.ImageSize) { - case 80384: return MediaType.ECMA_66; - case 81664: return MediaType.IBM23FD; - case 92160: return MediaType.ATARI_525_SD; + case 80384: return MediaType.ECMA_66; + case 81664: return MediaType.IBM23FD; + case 92160: return MediaType.ATARI_525_SD; case 102400: return MediaType.ACORN_525_SS_SD_40; case 116480: return MediaType.Apple32SS; case 133120: return MediaType.ATARI_525_ED; @@ -938,7 +975,7 @@ namespace DiscImageChef.DiscImages case 737280: return MediaType.DOS_35_DS_DD_9; case 819200: if(imageInfo.SectorSize == 256) return MediaType.CBM_35_DD; - if((extension == ".adf" || extension == ".adl") && imageInfo.SectorSize == 1024) + if((extension == ".adf" || extension == ".adl") && imageInfo.SectorSize == 1024) return MediaType.ACORN_35_DS_DD; if(extension == ".st") return MediaType.ATARI_35_DS_DD; @@ -948,37 +985,37 @@ namespace DiscImageChef.DiscImages if(extension == ".st") return MediaType.ATARI_35_DS_DD_11; return MediaType.CBM_AMIGA_35_DD; - case 988416: return MediaType.IBM43FD_256; - case 995072: return MediaType.IBM53FD_256; - case 1021696: return MediaType.ECMA_99_26; - case 1146624: return MediaType.IBM53FD_512; - case 1177344: return MediaType.ECMA_99_15; - case 1222400: return MediaType.IBM53FD_1024; - case 1228800: return MediaType.DOS_525_HD; - case 1255168: return MediaType.ECMA_69_8; - case 1261568: return MediaType.NEC_525_HD; - case 1304320: return MediaType.ECMA_99_8; - case 1427456: return MediaType.FDFORMAT_525_HD; - case 1474560: return MediaType.DOS_35_HD; - case 1638400: return MediaType.ACORN_35_DS_HD; - case 1720320: return MediaType.DMF; - case 1763328: return MediaType.FDFORMAT_35_HD; - case 1802240: return MediaType.CBM_AMIGA_35_HD; - case 1880064: return MediaType.XDF_35; - case 1884160: return MediaType.XDF_35; - case 2949120: return MediaType.DOS_35_ED; - case 9338880: return MediaType.NEC_35_TD; - case 33554432: return MediaType.FD32MB; - case 40387584: return MediaType.PocketZip; - case 126222336: return MediaType.LS120; - case 127923200: return MediaType.ECMA_154; - case 201410560: return MediaType.HiFD; - case 229632000: return MediaType.ECMA_201; - case 240386048: return MediaType.LS240; - case 481520640: return MediaType.ECMA_183_512; - case 533403648: return MediaType.ECMA_183; - case 596787200: return MediaType.ECMA_184_512; - case 654540800: return MediaType.ECMA_184; + case 988416: return MediaType.IBM43FD_256; + case 995072: return MediaType.IBM53FD_256; + case 1021696: return MediaType.ECMA_99_26; + case 1146624: return MediaType.IBM53FD_512; + case 1177344: return MediaType.ECMA_99_15; + case 1222400: return MediaType.IBM53FD_1024; + case 1228800: return MediaType.DOS_525_HD; + case 1255168: return MediaType.ECMA_69_8; + case 1261568: return MediaType.NEC_525_HD; + case 1304320: return MediaType.ECMA_99_8; + case 1427456: return MediaType.FDFORMAT_525_HD; + case 1474560: return MediaType.DOS_35_HD; + case 1638400: return MediaType.ACORN_35_DS_HD; + case 1720320: return MediaType.DMF; + case 1763328: return MediaType.FDFORMAT_35_HD; + case 1802240: return MediaType.CBM_AMIGA_35_HD; + case 1880064: return MediaType.XDF_35; + case 1884160: return MediaType.XDF_35; + case 2949120: return MediaType.DOS_35_ED; + case 9338880: return MediaType.NEC_35_TD; + case 33554432: return MediaType.FD32MB; + case 40387584: return MediaType.PocketZip; + case 126222336: return MediaType.LS120; + case 127923200: return MediaType.ECMA_154; + case 201410560: return MediaType.HiFD; + case 229632000: return MediaType.ECMA_201; + case 240386048: return MediaType.LS240; + case 481520640: return MediaType.ECMA_183_512; + case 533403648: return MediaType.ECMA_183; + case 596787200: return MediaType.ECMA_184_512; + case 654540800: return MediaType.ECMA_184; case 1070617600: return MediaType.Jaz; #region Commodore @@ -993,40 +1030,5 @@ namespace DiscImageChef.DiscImages default: return MediaType.GENERIC_HDD; } } - - public byte[] ReadSectorTag(ulong sectorAddress, SectorTagType tag) - { - throw new FeatureUnsupportedImageException("Feature not supported by image format"); - } - - public byte[] ReadSectorsTag(ulong sectorAddress, uint length, SectorTagType tag) - { - throw new FeatureUnsupportedImageException("Feature not supported by image format"); - } - - public byte[] ReadSectorLong(ulong sectorAddress) - { - throw new FeatureUnsupportedImageException("Feature not supported by image format"); - } - - public byte[] ReadSectorsLong(ulong sectorAddress, uint length) - { - throw new FeatureUnsupportedImageException("Feature not supported by image format"); - } - - public byte[] ReadDiskTag(MediaTagType tag) - { - throw new FeatureUnsupportedImageException("Feature not supported by image format"); - } - - public byte[] ReadSectorTag(ulong sectorAddress, uint track, SectorTagType tag) - { - throw new FeatureUnsupportedImageException("Feature not supported by image format"); - } - - public byte[] ReadSectorsTag(ulong sectorAddress, uint length, uint track, SectorTagType tag) - { - throw new FeatureUnsupportedImageException("Feature not supported by image format"); - } } } \ No newline at end of file diff --git a/DiscImageChef.Tests/Images/CopyQM.cs b/DiscImageChef.Tests/Images/CopyQM.cs index 2aae199f..233f78fb 100644 --- a/DiscImageChef.Tests/Images/CopyQM.cs +++ b/DiscImageChef.Tests/Images/CopyQM.cs @@ -51,8 +51,8 @@ namespace DiscImageChef.Tests.Images // TODO: Add "unknown" media types readonly MediaType[] mediatypes = { - MediaType.DOS_35_DS_DD_9, MediaType.Unknown, MediaType.Unknown, MediaType.DOS_35_HD, MediaType.DOS_35_HD, - MediaType.DMF, MediaType.DMF + MediaType.DOS_35_DS_DD_9, MediaType.CBM_35_DD, MediaType.CBM_35_DD, MediaType.DOS_35_HD, + MediaType.DOS_35_HD, MediaType.DMF, MediaType.DMF }; readonly string[] md5S = @@ -67,18 +67,18 @@ namespace DiscImageChef.Tests.Images { for(int i = 0; i < testfiles.Length; i++) { - string location = Path.Combine(Consts.TestFilesRoot, "images", "copyqm", testfiles[i]); - IFilter filter = new LZip(); + string location = Path.Combine(Consts.TestFilesRoot, "images", "copyqm", testfiles[i]); + IFilter filter = new LZip(); filter.Open(location); IMediaImage image = new DiscImages.CopyQm(); - Assert.AreEqual(true, image.OpenImage(filter), testfiles[i]); - Assert.AreEqual(sectors[i], image.Info.Sectors, testfiles[i]); - Assert.AreEqual(sectorsize[i], image.Info.SectorSize, testfiles[i]); - Assert.AreEqual(mediatypes[i], image.Info.MediaType, testfiles[i]); + Assert.AreEqual(true, image.OpenImage(filter), testfiles[i]); + Assert.AreEqual(sectors[i], image.Info.Sectors, testfiles[i]); + Assert.AreEqual(sectorsize[i], image.Info.SectorSize, testfiles[i]); + Assert.AreEqual(mediatypes[i], image.Info.MediaType, testfiles[i]); // How many sectors to read at once const uint SECTORS_TO_READ = 256; - ulong doneSectors = 0; + ulong doneSectors = 0; Md5Context ctx = new Md5Context(); ctx.Init(); @@ -89,13 +89,13 @@ namespace DiscImageChef.Tests.Images if(image.Info.Sectors - doneSectors >= SECTORS_TO_READ) { - sector = image.ReadSectors(doneSectors, SECTORS_TO_READ); + sector = image.ReadSectors(doneSectors, SECTORS_TO_READ); doneSectors += SECTORS_TO_READ; } else { - sector = image.ReadSectors(doneSectors, (uint)(image.Info.Sectors - doneSectors)); - doneSectors += image.Info.Sectors - doneSectors; + sector = image.ReadSectors(doneSectors, (uint)(image.Info.Sectors - doneSectors)); + doneSectors += image.Info.Sectors - doneSectors; } ctx.Update(sector);