🎨Remove chains of if-else to get media type from it's geometry, plus add

a geometry class with a list of known geometries and ❤️LINQ❤️ queries.
This commit is contained in:
2017-12-28 04:57:26 +00:00
parent 6aba6d36e8
commit 741a3289a2
17 changed files with 1136 additions and 1529 deletions

View File

@@ -72,6 +72,7 @@
</e> </e>
<e p="DiscImageChef.CommonTypes" t="IncludeRecursive"> <e p="DiscImageChef.CommonTypes" t="IncludeRecursive">
<e p="DiscImageChef.CommonTypes.csproj" t="IncludeRecursive" /> <e p="DiscImageChef.CommonTypes.csproj" t="IncludeRecursive" />
<e p="Geometry.cs" t="Include" />
<e p="MediaType.cs" t="Include" /> <e p="MediaType.cs" t="Include" />
<e p="MediaTypeFromSCSI.cs" t="Include" /> <e p="MediaTypeFromSCSI.cs" t="Include" />
<e p="Partition.cs" t="Include" /> <e p="Partition.cs" t="Include" />
@@ -80,6 +81,7 @@
</e> </e>
<e p="bin" t="ExcludeRecursive" /> <e p="bin" t="ExcludeRecursive" />
<e p="obj" t="ExcludeRecursive" /> <e p="obj" t="ExcludeRecursive" />
<e p="packages.config" t="Include" />
</e> </e>
<e p="DiscImageChef.Console" t="IncludeRecursive"> <e p="DiscImageChef.Console" t="IncludeRecursive">
<e p="DicConsole.cs" t="Include" /> <e p="DicConsole.cs" t="Include" />

View File

@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup> <PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
@@ -32,8 +32,12 @@
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Reference Include="System" /> <Reference Include="System" />
<Reference Include="System.ValueTuple, Version=4.0.2.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51">
<HintPath>..\packages\System.ValueTuple.4.4.0\lib\portable-net40+sl4+win8+wp8\System.ValueTuple.dll</HintPath>
</Reference>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="Geometry.cs" />
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Partition.cs" /> <Compile Include="Partition.cs" />
<Compile Include="MediaType.cs" /> <Compile Include="MediaType.cs" />
@@ -44,6 +48,9 @@
<Link>LICENSE.LGPL</Link> <Link>LICENSE.LGPL</Link>
</EmbeddedResource> </EmbeddedResource>
</ItemGroup> </ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" /> <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<ProjectExtensions> <ProjectExtensions>
<MonoDevelop> <MonoDevelop>

View File

@@ -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();
}
}
}

View File

@@ -35,6 +35,16 @@
namespace DiscImageChef.CommonTypes namespace DiscImageChef.CommonTypes
{ {
public enum MediaEncoding
{
Unknown,
FM,
MFM,
M2FM,
AppleGCR,
CommodoreGCR
}
/// <summary> /// <summary>
/// Contains an enumeration of all known types of media. /// Contains an enumeration of all known types of media.
/// </summary> /// </summary>
@@ -293,9 +303,13 @@ namespace DiscImageChef.CommonTypes
#endregion Microsoft non standard floppy formats #endregion Microsoft non standard floppy formats
#region IBM non standard floppy formats #region IBM non standard floppy formats
/// <summary>
/// 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
/// </summary>
XDF_525, XDF_525,
/// <summary> /// <summary>
/// 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 /// bytes/sector, falsified to DOS as 23 spt, 512 bps
/// </summary> /// </summary>
XDF_35, XDF_35,

View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="System.ValueTuple" version="4.4.0" targetFramework="net40" />
</packages>

View File

@@ -42,33 +42,33 @@ namespace DiscImageChef.DiscImages
{ {
public class Anex86 : IMediaImage public class Anex86 : IMediaImage
{ {
IFilter anexImageFilter; IFilter anexImageFilter;
Anex86Header fdihdr; Anex86Header fdihdr;
ImageInfo imageInfo; ImageInfo imageInfo;
public Anex86() public Anex86()
{ {
imageInfo = new ImageInfo imageInfo = new ImageInfo
{ {
ReadableSectorTags = new List<SectorTagType>(), ReadableSectorTags = new List<SectorTagType>(),
ReadableMediaTags = new List<MediaTagType>(), ReadableMediaTags = new List<MediaTagType>(),
HasPartitions = false, HasPartitions = false,
HasSessions = false, HasSessions = false,
Version = null, Version = null,
Application = null, Application = null,
ApplicationVersion = null, ApplicationVersion = null,
Creator = null, Creator = null,
Comments = null, Comments = null,
MediaManufacturer = null, MediaManufacturer = null,
MediaModel = null, MediaModel = null,
MediaSerialNumber = null, MediaSerialNumber = null,
MediaBarcode = null, MediaBarcode = null,
MediaPartNumber = null, MediaPartNumber = null,
MediaSequence = 0, MediaSequence = 0,
LastMediaSequence = 0, LastMediaSequence = 0,
DriveManufacturer = null, DriveManufacturer = null,
DriveModel = null, DriveModel = null,
DriveSerialNumber = null, DriveSerialNumber = null,
DriveFirmwareRevision = null DriveFirmwareRevision = null
}; };
} }
@@ -76,7 +76,7 @@ namespace DiscImageChef.DiscImages
public ImageInfo Info => imageInfo; public ImageInfo Info => imageInfo;
public string Name => "Anex86 Disk Image"; 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"; public string ImageFormat => "Anex86 disk image";
@@ -102,19 +102,19 @@ namespace DiscImageChef.DiscImages
stream.Read(hdrB, 0, hdrB.Length); stream.Read(hdrB, 0, hdrB.Length);
GCHandle handle = GCHandle.Alloc(hdrB, GCHandleType.Pinned); 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(); handle.Free();
DicConsole.DebugWriteLine("Anex86 plugin", "fdihdr.unknown = {0}", fdihdr.unknown); DicConsole.DebugWriteLine("Anex86 plugin", "fdihdr.unknown = {0}", fdihdr.unknown);
DicConsole.DebugWriteLine("Anex86 plugin", "fdihdr.hddtype = {0}", fdihdr.hddtype); DicConsole.DebugWriteLine("Anex86 plugin", "fdihdr.hddtype = {0}", fdihdr.hddtype);
DicConsole.DebugWriteLine("Anex86 plugin", "fdihdr.hdrSize = {0}", fdihdr.hdrSize); DicConsole.DebugWriteLine("Anex86 plugin", "fdihdr.hdrSize = {0}", fdihdr.hdrSize);
DicConsole.DebugWriteLine("Anex86 plugin", "fdihdr.dskSize = {0}", fdihdr.dskSize); DicConsole.DebugWriteLine("Anex86 plugin", "fdihdr.dskSize = {0}", fdihdr.dskSize);
DicConsole.DebugWriteLine("Anex86 plugin", "fdihdr.bps = {0}", fdihdr.bps); DicConsole.DebugWriteLine("Anex86 plugin", "fdihdr.bps = {0}", fdihdr.bps);
DicConsole.DebugWriteLine("Anex86 plugin", "fdihdr.spt = {0}", fdihdr.spt); DicConsole.DebugWriteLine("Anex86 plugin", "fdihdr.spt = {0}", fdihdr.spt);
DicConsole.DebugWriteLine("Anex86 plugin", "fdihdr.heads = {0}", fdihdr.heads); DicConsole.DebugWriteLine("Anex86 plugin", "fdihdr.heads = {0}", fdihdr.heads);
DicConsole.DebugWriteLine("Anex86 plugin", "fdihdr.cylinders = {0}", fdihdr.cylinders); 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; fdihdr.dskSize == fdihdr.bps * fdihdr.spt * fdihdr.heads * fdihdr.cylinders;
} }
@@ -131,198 +131,26 @@ namespace DiscImageChef.DiscImages
stream.Read(hdrB, 0, hdrB.Length); stream.Read(hdrB, 0, hdrB.Length);
GCHandle handle = GCHandle.Alloc(hdrB, GCHandleType.Pinned); 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(); handle.Free();
imageInfo.MediaType = MediaType.GENERIC_HDD; imageInfo.MediaType =
Geometry.GetMediaType(((ushort)fdihdr.cylinders, (byte)fdihdr.heads, (ushort)fdihdr.spt,
switch(fdihdr.cylinders) (uint)fdihdr.bps, MediaEncoding.MFM, false));
{ if(imageInfo.MediaType == MediaType.Unknown) imageInfo.MediaType = MediaType.GENERIC_HDD;
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;
}
DicConsole.DebugWriteLine("Anex86 plugin", "MediaType: {0}", imageInfo.MediaType); DicConsole.DebugWriteLine("Anex86 plugin", "MediaType: {0}", imageInfo.MediaType);
imageInfo.ImageSize = (ulong)fdihdr.dskSize; imageInfo.ImageSize = (ulong)fdihdr.dskSize;
imageInfo.CreationTime = imageFilter.GetCreationTime(); imageInfo.CreationTime = imageFilter.GetCreationTime();
imageInfo.LastModificationTime = imageFilter.GetLastWriteTime(); imageInfo.LastModificationTime = imageFilter.GetLastWriteTime();
imageInfo.MediaTitle = Path.GetFileNameWithoutExtension(imageFilter.GetFilename()); imageInfo.MediaTitle = Path.GetFileNameWithoutExtension(imageFilter.GetFilename());
imageInfo.Sectors = (ulong)(fdihdr.cylinders * fdihdr.heads * fdihdr.spt); imageInfo.Sectors = (ulong)(fdihdr.cylinders * fdihdr.heads * fdihdr.spt);
imageInfo.XmlMediaType = XmlMediaType.BlockMedia; imageInfo.XmlMediaType = XmlMediaType.BlockMedia;
imageInfo.SectorSize = (uint)fdihdr.bps; imageInfo.SectorSize = (uint)fdihdr.bps;
imageInfo.Cylinders = (uint)fdihdr.cylinders; imageInfo.Cylinders = (uint)fdihdr.cylinders;
imageInfo.Heads = (uint)fdihdr.heads; imageInfo.Heads = (uint)fdihdr.heads;
imageInfo.SectorsPerTrack = (uint)fdihdr.spt; imageInfo.SectorsPerTrack = (uint)fdihdr.spt;
anexImageFilter = imageFilter; anexImageFilter = imageFilter;
@@ -429,7 +257,7 @@ namespace DiscImageChef.DiscImages
} }
public bool? VerifySectors(ulong sectorAddress, uint length, out List<ulong> failingLbas, public bool? VerifySectors(ulong sectorAddress, uint length, out List<ulong> failingLbas,
out List<ulong> unknownLbas) out List<ulong> unknownLbas)
{ {
failingLbas = new List<ulong>(); failingLbas = new List<ulong>();
unknownLbas = new List<ulong>(); unknownLbas = new List<ulong>();
@@ -439,7 +267,7 @@ namespace DiscImageChef.DiscImages
} }
public bool? VerifySectors(ulong sectorAddress, uint length, uint track, out List<ulong> failingLbas, public bool? VerifySectors(ulong sectorAddress, uint length, uint track, out List<ulong> failingLbas,
out List<ulong> unknownLbas) out List<ulong> unknownLbas)
{ {
throw new FeatureUnsupportedImageException("Feature not supported by image format"); throw new FeatureUnsupportedImageException("Feature not supported by image format");
} }

View File

@@ -63,25 +63,25 @@ namespace DiscImageChef.DiscImages
{ {
imageInfo = new ImageInfo imageInfo = new ImageInfo
{ {
ReadableSectorTags = new List<SectorTagType>(), ReadableSectorTags = new List<SectorTagType>(),
ReadableMediaTags = new List<MediaTagType>(), ReadableMediaTags = new List<MediaTagType>(),
HasPartitions = false, HasPartitions = false,
HasSessions = false, HasSessions = false,
Version = null, Version = null,
Application = null, Application = null,
ApplicationVersion = null, ApplicationVersion = null,
Creator = null, Creator = null,
Comments = null, Comments = null,
MediaManufacturer = null, MediaManufacturer = null,
MediaModel = null, MediaModel = null,
MediaSerialNumber = null, MediaSerialNumber = null,
MediaBarcode = null, MediaBarcode = null,
MediaPartNumber = null, MediaPartNumber = null,
MediaSequence = 0, MediaSequence = 0,
LastMediaSequence = 0, LastMediaSequence = 0,
DriveManufacturer = null, DriveManufacturer = null,
DriveModel = null, DriveModel = null,
DriveSerialNumber = null, DriveSerialNumber = null,
DriveFirmwareRevision = null DriveFirmwareRevision = null
}; };
} }
@@ -89,7 +89,7 @@ namespace DiscImageChef.DiscImages
public ImageInfo Info => imageInfo; public ImageInfo Info => imageInfo;
public string Name => "ACT Apricot Disk Image"; 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"; public string ImageFormat => "ACT Apricot disk image";
@@ -124,9 +124,9 @@ namespace DiscImageChef.DiscImages
stream.Seek(signature.Length, SeekOrigin.Begin); stream.Seek(signature.Length, SeekOrigin.Begin);
int totalCylinders = -1; int totalCylinders = -1;
int totalHeads = -1; int totalHeads = -1;
int maxSector = -1; int maxSector = -1;
int recordSize = Marshal.SizeOf(typeof(ApridiskRecord)); int recordSize = Marshal.SizeOf(typeof(ApridiskRecord));
// Count cylinders // Count cylinders
while(stream.Position < stream.Length) while(stream.Position < stream.Length)
@@ -134,7 +134,7 @@ namespace DiscImageChef.DiscImages
byte[] recB = new byte[recordSize]; byte[] recB = new byte[recordSize];
stream.Read(recB, 0, recordSize); stream.Read(recB, 0, recordSize);
GCHandle handle = GCHandle.Alloc(recB, GCHandleType.Pinned); GCHandle handle = GCHandle.Alloc(recB, GCHandleType.Pinned);
ApridiskRecord record = ApridiskRecord record =
(ApridiskRecord)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(ApridiskRecord)); (ApridiskRecord)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(ApridiskRecord));
handle.Free(); handle.Free();
@@ -176,8 +176,8 @@ namespace DiscImageChef.DiscImages
: "uncompressed"); : "uncompressed");
if(record.cylinder > totalCylinders) totalCylinders = record.cylinder; if(record.cylinder > totalCylinders) totalCylinders = record.cylinder;
if(record.head > totalHeads) totalHeads = record.head; if(record.head > totalHeads) totalHeads = record.head;
if(record.sector > maxSector) maxSector = record.sector; if(record.sector > maxSector) maxSector = record.sector;
stream.Seek(record.headerSize - recordSize + record.dataSize, SeekOrigin.Current); stream.Seek(record.headerSize - recordSize + record.dataSize, SeekOrigin.Current);
break; break;
@@ -198,7 +198,7 @@ namespace DiscImageChef.DiscImages
uint[][] spts = new uint[totalCylinders][]; uint[][] spts = new uint[totalCylinders][];
imageInfo.Cylinders = (ushort)totalCylinders; imageInfo.Cylinders = (ushort)totalCylinders;
imageInfo.Heads = (byte)totalHeads; imageInfo.Heads = (byte)totalHeads;
DicConsole.DebugWriteLine("Apridisk plugin", DicConsole.DebugWriteLine("Apridisk plugin",
"Found {0} cylinders and {1} heads with a maximum sector number of {2}", "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++) for(int i = 0; i < totalCylinders; i++)
{ {
sectorsData[i] = new byte[totalHeads][][]; 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][]; 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]; byte[] recB = new byte[recordSize];
stream.Read(recB, 0, recordSize); stream.Read(recB, 0, recordSize);
GCHandle handle = GCHandle.Alloc(recB, GCHandleType.Pinned); GCHandle handle = GCHandle.Alloc(recB, GCHandleType.Pinned);
ApridiskRecord record = ApridiskRecord record =
(ApridiskRecord)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(ApridiskRecord)); (ApridiskRecord)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(ApridiskRecord));
handle.Free(); handle.Free();
@@ -235,7 +235,7 @@ namespace DiscImageChef.DiscImages
case RecordType.Deleted: case RecordType.Deleted:
case RecordType.Comment: case RecordType.Comment:
case RecordType.Creator: 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; headersizes += record.headerSize + record.dataSize;
break; break;
case RecordType.Sector: case RecordType.Sector:
@@ -248,7 +248,8 @@ namespace DiscImageChef.DiscImages
uint realLength = record.dataSize; uint realLength = record.dataSize;
if(record.compression == CompressType.Compressed) 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; else sectorsData[record.cylinder][record.head][record.sector] = data;
if(realLength < imageInfo.SectorSize) imageInfo.SectorSize = realLength; if(realLength < imageInfo.SectorSize) imageInfo.SectorSize = realLength;
@@ -266,7 +267,9 @@ namespace DiscImageChef.DiscImages
uint spt = uint.MaxValue; uint spt = uint.MaxValue;
for(ushort cyl = 0; cyl < imageInfo.Cylinders; cyl++) 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; imageInfo.SectorsPerTrack = spt;
@@ -274,19 +277,16 @@ namespace DiscImageChef.DiscImages
DicConsole.DebugWriteLine("Apridisk plugin", "Found a minimum of {0} sectors per track", DicConsole.DebugWriteLine("Apridisk plugin", "Found a minimum of {0} sectors per track",
imageInfo.SectorsPerTrack); imageInfo.SectorsPerTrack);
if(imageInfo.Cylinders == 70 && imageInfo.Heads == 1 && imageInfo.SectorsPerTrack == 9) imageInfo.MediaType =
imageInfo.MediaType = MediaType.Apricot_35; Geometry.GetMediaType(((ushort)imageInfo.Cylinders, (byte)imageInfo.Heads,
else if(imageInfo.Cylinders == 80 && imageInfo.Heads == 1 && imageInfo.SectorsPerTrack == 9) (ushort)imageInfo.SectorsPerTrack, 512, MediaEncoding.MFM, false));
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.ImageSize = (ulong)stream.Length - headersizes; imageInfo.ImageSize = (ulong)stream.Length - headersizes;
imageInfo.CreationTime = imageFilter.GetCreationTime(); imageInfo.CreationTime = imageFilter.GetCreationTime();
imageInfo.LastModificationTime = imageFilter.GetLastWriteTime(); imageInfo.LastModificationTime = imageFilter.GetLastWriteTime();
imageInfo.MediaTitle = Path.GetFileNameWithoutExtension(imageFilter.GetFilename()); imageInfo.MediaTitle = Path.GetFileNameWithoutExtension(imageFilter.GetFilename());
imageInfo.Sectors = imageInfo.Cylinders * imageInfo.Heads * imageInfo.SectorsPerTrack; imageInfo.Sectors = imageInfo.Cylinders * imageInfo.Heads * imageInfo.SectorsPerTrack;
imageInfo.XmlMediaType = XmlMediaType.BlockMedia; imageInfo.XmlMediaType = XmlMediaType.BlockMedia;
/* /*
FileStream debugFs = new FileStream("debug.img", FileMode.CreateNew, FileAccess.Write); FileStream debugFs = new FileStream("debug.img", FileMode.CreateNew, FileAccess.Write);
@@ -298,30 +298,6 @@ namespace DiscImageChef.DiscImages
return true; 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) public byte[] ReadSector(ulong sectorAddress)
{ {
(ushort cylinder, byte head, byte sector) = LbaToChs(sectorAddress); (ushort cylinder, byte head, byte sector) = LbaToChs(sectorAddress);
@@ -356,15 +332,6 @@ namespace DiscImageChef.DiscImages
return buffer.ToArray(); 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) public byte[] ReadDiskTag(MediaTagType tag)
{ {
throw new FeatureUnsupportedImageException("Feature not supported by image format"); 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<ulong> failingLbas, public bool? VerifySectors(ulong sectorAddress, uint length, out List<ulong> failingLbas,
out List<ulong> unknownLbas) out List<ulong> unknownLbas)
{ {
failingLbas = new List<ulong>(); failingLbas = new List<ulong>();
unknownLbas = new List<ulong>(); unknownLbas = new List<ulong>();
@@ -451,7 +418,7 @@ namespace DiscImageChef.DiscImages
} }
public bool? VerifySectors(ulong sectorAddress, uint length, uint track, out List<ulong> failingLbas, public bool? VerifySectors(ulong sectorAddress, uint length, uint track, out List<ulong> failingLbas,
out List<ulong> unknownLbas) out List<ulong> unknownLbas)
{ {
throw new FeatureUnsupportedImageException("Feature not supported by image format"); throw new FeatureUnsupportedImageException("Feature not supported by image format");
} }
@@ -461,10 +428,43 @@ namespace DiscImageChef.DiscImages
return null; 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 enum RecordType : uint
{ {
Deleted = 0xE31D0000, Deleted = 0xE31D0000,
Sector = 0xE31D0001, Sector = 0xE31D0001,
Comment = 0xE31D0002, Comment = 0xE31D0002,
Creator = 0xE31D0003 Creator = 0xE31D0003
} }
@@ -472,19 +472,19 @@ namespace DiscImageChef.DiscImages
enum CompressType : ushort enum CompressType : ushort
{ {
Uncompresed = 0x9E90, Uncompresed = 0x9E90,
Compressed = 0x3E5A Compressed = 0x3E5A
} }
[StructLayout(LayoutKind.Sequential, Pack = 1)] [StructLayout(LayoutKind.Sequential, Pack = 1)]
struct ApridiskRecord struct ApridiskRecord
{ {
public RecordType type; public RecordType type;
public CompressType compression; public CompressType compression;
public ushort headerSize; public ushort headerSize;
public uint dataSize; public uint dataSize;
public byte head; public byte head;
public byte sector; public byte sector;
public ushort cylinder; public ushort cylinder;
} }
} }
} }

View File

@@ -43,17 +43,17 @@ namespace DiscImageChef.DiscImages
public class CopyQm : IMediaImage public class CopyQm : IMediaImage
{ {
const ushort COPYQM_MAGIC = 0x5143; 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_BLIND = 1;
const byte COPYQM_HFS = 2; const byte COPYQM_HFS = 2;
const byte COPYQM_525_DD = 1; const byte COPYQM_525_DD = 1;
const byte COPYQM_525_HD = 2; const byte COPYQM_525_HD = 2;
const byte COPYQM_35_DD = 3; const byte COPYQM_35_DD = 3;
const byte COPYQM_35_HD = 4; const byte COPYQM_35_HD = 4;
const byte COPYQM_35_ED = 6; const byte COPYQM_35_ED = 6;
readonly uint[] copyQmCrcTable = readonly uint[] copyQmCrcTable =
{ {
@@ -87,38 +87,38 @@ namespace DiscImageChef.DiscImages
0x24B4A3A6, 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF, 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 0x24B4A3A6, 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF, 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94,
0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D
}; };
uint calculatedDataCrc; uint calculatedDataCrc;
byte[] decodedDisk; byte[] decodedDisk;
MemoryStream decodedImage; MemoryStream decodedImage;
CopyQmHeader header; CopyQmHeader header;
bool headerChecksumOk; bool headerChecksumOk;
ImageInfo imageInfo; ImageInfo imageInfo;
public CopyQm() public CopyQm()
{ {
imageInfo = new ImageInfo imageInfo = new ImageInfo
{ {
ReadableSectorTags = new List<SectorTagType>(), ReadableSectorTags = new List<SectorTagType>(),
ReadableMediaTags = new List<MediaTagType>(), ReadableMediaTags = new List<MediaTagType>(),
HasPartitions = false, HasPartitions = false,
HasSessions = false, HasSessions = false,
Version = null, Version = null,
Application = null, Application = null,
ApplicationVersion = null, ApplicationVersion = null,
Creator = null, Creator = null,
Comments = null, Comments = null,
MediaManufacturer = null, MediaManufacturer = null,
MediaModel = null, MediaModel = null,
MediaSerialNumber = null, MediaSerialNumber = null,
MediaBarcode = null, MediaBarcode = null,
MediaPartNumber = null, MediaPartNumber = null,
MediaSequence = 0, MediaSequence = 0,
LastMediaSequence = 0, LastMediaSequence = 0,
DriveManufacturer = null, DriveManufacturer = null,
DriveModel = null, DriveModel = null,
DriveSerialNumber = null, DriveSerialNumber = null,
DriveFirmwareRevision = null DriveFirmwareRevision = null
}; };
} }
@@ -126,7 +126,7 @@ namespace DiscImageChef.DiscImages
public ImageInfo Info => imageInfo; public ImageInfo Info => imageInfo;
public string Name => "Sydex CopyQM"; 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"; public string ImageFormat => "Sydex CopyQM";
@@ -161,46 +161,46 @@ namespace DiscImageChef.DiscImages
byte[] hdr = new byte[133]; byte[] hdr = new byte[133];
stream.Read(hdr, 0, 133); stream.Read(hdr, 0, 133);
header = new CopyQmHeader(); header = new CopyQmHeader();
IntPtr hdrPtr = Marshal.AllocHGlobal(133); IntPtr hdrPtr = Marshal.AllocHGlobal(133);
Marshal.Copy(hdr, 0, hdrPtr, 133); Marshal.Copy(hdr, 0, hdrPtr, 133);
header = (CopyQmHeader)Marshal.PtrToStructure(hdrPtr, typeof(CopyQmHeader)); header = (CopyQmHeader)Marshal.PtrToStructure(hdrPtr, typeof(CopyQmHeader));
Marshal.FreeHGlobal(hdrPtr); Marshal.FreeHGlobal(hdrPtr);
DicConsole.DebugWriteLine("CopyQM plugin", "header.magic = 0x{0:X4}", header.magic); 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.mark = 0x{0:X2}", header.mark);
DicConsole.DebugWriteLine("CopyQM plugin", "header.sectorSize = {0}", header.sectorSize); DicConsole.DebugWriteLine("CopyQM plugin", "header.sectorSize = {0}", header.sectorSize);
DicConsole.DebugWriteLine("CopyQM plugin", "header.sectorPerCluster = {0}", header.sectorPerCluster); DicConsole.DebugWriteLine("CopyQM plugin", "header.sectorPerCluster = {0}", header.sectorPerCluster);
DicConsole.DebugWriteLine("CopyQM plugin", "header.reservedSectors = {0}", header.reservedSectors); DicConsole.DebugWriteLine("CopyQM plugin", "header.reservedSectors = {0}", header.reservedSectors);
DicConsole.DebugWriteLine("CopyQM plugin", "header.fatCopy = {0}", header.fatCopy); DicConsole.DebugWriteLine("CopyQM plugin", "header.fatCopy = {0}", header.fatCopy);
DicConsole.DebugWriteLine("CopyQM plugin", "header.rootEntries = {0}", header.rootEntries); DicConsole.DebugWriteLine("CopyQM plugin", "header.rootEntries = {0}", header.rootEntries);
DicConsole.DebugWriteLine("CopyQM plugin", "header.sectors = {0}", header.sectors); 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.mediaType = 0x{0:X2}", header.mediaType);
DicConsole.DebugWriteLine("CopyQM plugin", "header.sectorsPerFat = {0}", header.sectorsPerFat); DicConsole.DebugWriteLine("CopyQM plugin", "header.sectorsPerFat = {0}", header.sectorsPerFat);
DicConsole.DebugWriteLine("CopyQM plugin", "header.sectorsPerTrack = {0}", header.sectorsPerTrack); DicConsole.DebugWriteLine("CopyQM plugin", "header.sectorsPerTrack = {0}", header.sectorsPerTrack);
DicConsole.DebugWriteLine("CopyQM plugin", "header.heads = {0}", header.heads); DicConsole.DebugWriteLine("CopyQM plugin", "header.heads = {0}", header.heads);
DicConsole.DebugWriteLine("CopyQM plugin", "header.hidden = {0}", header.hidden); DicConsole.DebugWriteLine("CopyQM plugin", "header.hidden = {0}", header.hidden);
DicConsole.DebugWriteLine("CopyQM plugin", "header.sectorsBig = {0}", header.sectorsBig); DicConsole.DebugWriteLine("CopyQM plugin", "header.sectorsBig = {0}", header.sectorsBig);
DicConsole.DebugWriteLine("CopyQM plugin", "header.description = {0}", header.description); DicConsole.DebugWriteLine("CopyQM plugin", "header.description = {0}", header.description);
DicConsole.DebugWriteLine("CopyQM plugin", "header.blind = {0}", header.blind); DicConsole.DebugWriteLine("CopyQM plugin", "header.blind = {0}", header.blind);
DicConsole.DebugWriteLine("CopyQM plugin", "header.density = {0}", header.density); DicConsole.DebugWriteLine("CopyQM plugin", "header.density = {0}", header.density);
DicConsole.DebugWriteLine("CopyQM plugin", "header.imageCylinders = {0}", header.imageCylinders); DicConsole.DebugWriteLine("CopyQM plugin", "header.imageCylinders = {0}", header.imageCylinders);
DicConsole.DebugWriteLine("CopyQM plugin", "header.totalCylinders = {0}", header.totalCylinders); 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.crc = 0x{0:X8}", header.crc);
DicConsole.DebugWriteLine("CopyQM plugin", "header.volumeLabel = {0}", header.volumeLabel); 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.time = 0x{0:X4}", header.time);
DicConsole.DebugWriteLine("CopyQM plugin", "header.date = 0x{0:X4}", header.date); 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.commentLength = {0}", header.commentLength);
DicConsole.DebugWriteLine("CopyQM plugin", "header.secbs = {0}", header.secbs); 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.unknown = 0x{0:X4}", header.unknown);
DicConsole.DebugWriteLine("CopyQM plugin", "header.interleave = {0}", header.interleave); DicConsole.DebugWriteLine("CopyQM plugin", "header.interleave = {0}", header.interleave);
DicConsole.DebugWriteLine("CopyQM plugin", "header.skew = {0}", header.skew); DicConsole.DebugWriteLine("CopyQM plugin", "header.skew = {0}", header.skew);
DicConsole.DebugWriteLine("CopyQM plugin", "header.drive = {0}", header.drive); DicConsole.DebugWriteLine("CopyQM plugin", "header.drive = {0}", header.drive);
byte[] cmt = new byte[header.commentLength]; byte[] cmt = new byte[header.commentLength];
stream.Read(cmt, 0, header.commentLength); stream.Read(cmt, 0, header.commentLength);
imageInfo.Comments = StringHandlers.CToString(cmt); imageInfo.Comments = StringHandlers.CToString(cmt);
decodedImage = new MemoryStream(); decodedImage = new MemoryStream();
calculatedDataCrc = 0; calculatedDataCrc = 0;
@@ -213,7 +213,7 @@ namespace DiscImageChef.DiscImages
if(runLength < 0) if(runLength < 0)
{ {
byte repeatedByte = (byte)stream.ReadByte(); byte repeatedByte = (byte)stream.ReadByte();
byte[] repeatedArray = new byte[runLength * -1]; byte[] repeatedArray = new byte[runLength * -1];
ArrayHelpers.ArrayFill(repeatedArray, repeatedByte); ArrayHelpers.ArrayFill(repeatedArray, repeatedByte);
@@ -253,7 +253,7 @@ namespace DiscImageChef.DiscImages
debugStream.Close(); debugStream.Close();
*/ */
int sum = 0; int sum = 0;
for(int i = 0; i < hdr.Length - 1; i++) sum += hdr[i]; for(int i = 0; i < hdr.Length - 1; i++) sum += hdr[i];
headerChecksumOk = ((-1 * sum) & 0xFF) == header.headerChecksum; 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, DicConsole.DebugWriteLine("CopyQM plugin", "Calculated data CRC = 0x{0:X8}, {1}", calculatedDataCrc,
calculatedDataCrc == header.crc); calculatedDataCrc == header.crc);
imageInfo.Application = "CopyQM"; imageInfo.Application = "CopyQM";
imageInfo.CreationTime = DateHandlers.DosToDateTime(header.date, header.time); imageInfo.CreationTime = DateHandlers.DosToDateTime(header.date, header.time);
imageInfo.LastModificationTime = imageInfo.CreationTime; imageInfo.LastModificationTime = imageInfo.CreationTime;
imageInfo.MediaTitle = header.volumeLabel; imageInfo.MediaTitle = header.volumeLabel;
imageInfo.ImageSize = (ulong)(stream.Length - 133 - header.commentLength); imageInfo.ImageSize = (ulong)(stream.Length - 133 - header.commentLength);
imageInfo.Sectors = (ulong)sectors; imageInfo.Sectors = (ulong)sectors;
imageInfo.SectorSize = header.sectorSize; 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: case MediaType.NEC_525_HD when header.drive == COPYQM_35_HD ||header.drive == COPYQM_35_ED:
if(header.heads == 2 && header.totalCylinders == 80 && header.sectorsPerTrack == 15 && imageInfo.MediaType = MediaType.NEC_35_HD_8;
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;
break; break;
case COPYQM_525_DD: case MediaType.DOS_525_HD when header.drive == COPYQM_35_HD ||header.drive == COPYQM_35_ED:
if(header.heads == 1 && header.totalCylinders == 40 && header.sectorsPerTrack == 8 && imageInfo.MediaType = MediaType.NEC_35_HD_15;
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;
break; break;
case COPYQM_35_ED: case MediaType.RX50 when header.drive == COPYQM_525_DD || header.drive == COPYQM_525_HD:
if(header.heads == 2 && header.totalCylinders == 80 && header.sectorsPerTrack == 36 && imageInfo.MediaType = MediaType.ATARI_35_SS_DD;
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;
break; break;
} }
imageInfo.XmlMediaType = XmlMediaType.BlockMedia; imageInfo.XmlMediaType = XmlMediaType.BlockMedia;
decodedDisk = decodedImage.ToArray(); decodedDisk = decodedImage.ToArray();
decodedImage.Close(); decodedImage.Close();
@@ -354,8 +297,8 @@ namespace DiscImageChef.DiscImages
if(!string.IsNullOrEmpty(imageInfo.Comments)) if(!string.IsNullOrEmpty(imageInfo.Comments))
DicConsole.VerboseWriteLine("CopyQM comments: {0}", imageInfo.Comments); DicConsole.VerboseWriteLine("CopyQM comments: {0}", imageInfo.Comments);
imageInfo.Heads = header.heads; imageInfo.Heads = header.heads;
imageInfo.Cylinders = header.imageCylinders; imageInfo.Cylinders = header.totalCylinders;
imageInfo.SectorsPerTrack = header.sectorsPerTrack; imageInfo.SectorsPerTrack = header.sectorsPerTrack;
return true; return true;
@@ -372,7 +315,7 @@ namespace DiscImageChef.DiscImages
} }
public bool? VerifySectors(ulong sectorAddress, uint length, out List<ulong> failingLbas, public bool? VerifySectors(ulong sectorAddress, uint length, out List<ulong> failingLbas,
out List<ulong> unknownLbas) out List<ulong> unknownLbas)
{ {
failingLbas = new List<ulong>(); failingLbas = new List<ulong>();
unknownLbas = new List<ulong>(); unknownLbas = new List<ulong>();
@@ -383,7 +326,7 @@ namespace DiscImageChef.DiscImages
} }
public bool? VerifySectors(ulong sectorAddress, uint length, uint track, out List<ulong> failingLbas, public bool? VerifySectors(ulong sectorAddress, uint length, uint track, out List<ulong> failingLbas,
out List<ulong> unknownLbas) out List<ulong> unknownLbas)
{ {
failingLbas = new List<ulong>(); failingLbas = new List<ulong>();
unknownLbas = new List<ulong>(); unknownLbas = new List<ulong>();
@@ -414,7 +357,7 @@ namespace DiscImageChef.DiscImages
byte[] buffer = new byte[length * imageInfo.SectorSize]; byte[] buffer = new byte[length * imageInfo.SectorSize];
Array.Copy(decodedDisk, (int)sectorAddress * imageInfo.SectorSize, buffer, 0, Array.Copy(decodedDisk, (int)sectorAddress * imageInfo.SectorSize, buffer, 0,
length * imageInfo.SectorSize); length * imageInfo.SectorSize);
return buffer; return buffer;
} }
@@ -516,7 +459,8 @@ namespace DiscImageChef.DiscImages
/// <summary>0x18 Sectors on disk (part of FAT's BPB)</summary> /// <summary>0x18 Sectors on disk (part of FAT's BPB)</summary>
public uint sectorsBig; public uint sectorsBig;
/// <summary>0x1C Description</summary> /// <summary>0x1C Description</summary>
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 60)] public string description; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 60)]
public string description;
/// <summary>0x58 Blind mode. 0 = DOS, 1 = blind, 2 = HFS</summary> /// <summary>0x58 Blind mode. 0 = DOS, 1 = blind, 2 = HFS</summary>
public byte blind; public byte blind;
/// <summary>0x59 Density. 0 = Double, 1 = High, 2 = Quad/Extra</summary> /// <summary>0x59 Density. 0 = Double, 1 = High, 2 = Quad/Extra</summary>
@@ -528,7 +472,8 @@ namespace DiscImageChef.DiscImages
/// <summary>0x5C CRC32 of data</summary> /// <summary>0x5C CRC32 of data</summary>
public uint crc; public uint crc;
/// <summary>0x60 DOS volume label</summary> /// <summary>0x60 DOS volume label</summary>
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 11)] public string volumeLabel; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 11)]
public string volumeLabel;
/// <summary>0x6B Modification time</summary> /// <summary>0x6B Modification time</summary>
public ushort time; public ushort time;
/// <summary>0x6D Modification date</summary> /// <summary>0x6D Modification date</summary>
@@ -546,7 +491,8 @@ namespace DiscImageChef.DiscImages
/// <summary>0x76 Source drive type. 1 = 5.25" DD, 2 = 5.25" HD, 3 = 3.5" DD, 4 = 3.5" HD, 6 = 3.5" ED</summary> /// <summary>0x76 Source drive type. 1 = 5.25" DD, 2 = 5.25" HD, 3 = 3.5" DD, 4 = 3.5" HD, 6 = 3.5" ED</summary>
public byte drive; public byte drive;
/// <summary>0x77 Filling bytes</summary> /// <summary>0x77 Filling bytes</summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 13)] public byte[] fill; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 13)]
public byte[] fill;
/// <summary>0x84 Header checksum</summary> /// <summary>0x84 Header checksum</summary>
public byte headerChecksum; public byte headerChecksum;
} }

View File

@@ -45,12 +45,13 @@ namespace DiscImageChef.DiscImages
{ {
// Information from Quasi88's FORMAT.TXT file // Information from Quasi88's FORMAT.TXT file
// Japanese comments copied from there // Japanese comments copied from there
// TODO: Solve media types
public class D88 : IMediaImage public class D88 : IMediaImage
{ {
const byte READ_ONLY = 0x10; const byte READ_ONLY = 0x10;
readonly byte[] reservedEmpty = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; readonly byte[] reservedEmpty = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
ImageInfo imageInfo; ImageInfo imageInfo;
List<byte[]> sectorsData; List<byte[]> sectorsData;
@@ -58,31 +59,31 @@ namespace DiscImageChef.DiscImages
{ {
imageInfo = new ImageInfo imageInfo = new ImageInfo
{ {
ReadableSectorTags = new List<SectorTagType>(), ReadableSectorTags = new List<SectorTagType>(),
ReadableMediaTags = new List<MediaTagType>(), ReadableMediaTags = new List<MediaTagType>(),
HasPartitions = false, HasPartitions = false,
HasSessions = false, HasSessions = false,
Version = null, Version = null,
Application = null, Application = null,
ApplicationVersion = null, ApplicationVersion = null,
Creator = null, Creator = null,
Comments = null, Comments = null,
MediaManufacturer = null, MediaManufacturer = null,
MediaModel = null, MediaModel = null,
MediaSerialNumber = null, MediaSerialNumber = null,
MediaBarcode = null, MediaBarcode = null,
MediaPartNumber = null, MediaPartNumber = null,
MediaSequence = 0, MediaSequence = 0,
LastMediaSequence = 0, LastMediaSequence = 0,
DriveManufacturer = null, DriveManufacturer = null,
DriveModel = null, DriveModel = null,
DriveSerialNumber = null, DriveSerialNumber = null,
DriveFirmwareRevision = null DriveFirmwareRevision = null
}; };
} }
public string Name => "D88 Disk Image"; public string Name => "D88 Disk Image";
public Guid Id => new Guid("669EDC77-EC41-4720-A88C-49C38CFFBAA0"); public Guid Id => new Guid("669EDC77-EC41-4720-A88C-49C38CFFBAA0");
public ImageInfo Info => imageInfo; public ImageInfo Info => imageInfo;
public string ImageFormat => "D88 disk image"; public string ImageFormat => "D88 disk image";
@@ -111,7 +112,7 @@ namespace DiscImageChef.DiscImages
stream.Read(hdrB, 0, hdrB.Length); stream.Read(hdrB, 0, hdrB.Length);
GCHandle handle = GCHandle.Alloc(hdrB, GCHandleType.Pinned); 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(); handle.Free();
DicConsole.DebugWriteLine("D88 plugin", "d88hdr.name = \"{0}\"", DicConsole.DebugWriteLine("D88 plugin", "d88hdr.name = \"{0}\"",
@@ -158,7 +159,7 @@ namespace DiscImageChef.DiscImages
stream.Read(hdrB, 0, hdrB.Length); stream.Read(hdrB, 0, hdrB.Length);
GCHandle handle = GCHandle.Alloc(hdrB, GCHandleType.Pinned); 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(); handle.Free();
DicConsole.DebugWriteLine("D88 plugin", "d88hdr.name = \"{0}\"", DicConsole.DebugWriteLine("D88 plugin", "d88hdr.name = \"{0}\"",
@@ -190,7 +191,7 @@ namespace DiscImageChef.DiscImages
if(trkCounter == 0) return false; if(trkCounter == 0) return false;
SectorHeader sechdr = new SectorHeader(); 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.Seek(d88Hdr.track_table[0], SeekOrigin.Begin);
stream.Read(hdrB, 0, hdrB.Length); stream.Read(hdrB, 0, hdrB.Length);
@@ -198,20 +199,20 @@ namespace DiscImageChef.DiscImages
sechdr = (SectorHeader)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(SectorHeader)); sechdr = (SectorHeader)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(SectorHeader));
handle.Free(); handle.Free();
DicConsole.DebugWriteLine("D88 plugin", "sechdr.c = {0}", sechdr.c); DicConsole.DebugWriteLine("D88 plugin", "sechdr.c = {0}", sechdr.c);
DicConsole.DebugWriteLine("D88 plugin", "sechdr.h = {0}", sechdr.h); DicConsole.DebugWriteLine("D88 plugin", "sechdr.h = {0}", sechdr.h);
DicConsole.DebugWriteLine("D88 plugin", "sechdr.r = {0}", sechdr.r); DicConsole.DebugWriteLine("D88 plugin", "sechdr.r = {0}", sechdr.r);
DicConsole.DebugWriteLine("D88 plugin", "sechdr.n = {0}", sechdr.n); DicConsole.DebugWriteLine("D88 plugin", "sechdr.n = {0}", sechdr.n);
DicConsole.DebugWriteLine("D88 plugin", "sechdr.spt = {0}", sechdr.spt); DicConsole.DebugWriteLine("D88 plugin", "sechdr.spt = {0}", sechdr.spt);
DicConsole.DebugWriteLine("D88 plugin", "sechdr.density = {0}", sechdr.density); 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.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); DicConsole.DebugWriteLine("D88 plugin", "sechdr.size_of_data = {0}", sechdr.size_of_data);
short spt = sechdr.spt; short spt = sechdr.spt;
IBMSectorSizeCode bps = sechdr.n; IBMSectorSizeCode bps = sechdr.n;
bool allEqual = true; bool allEqual = true;
sectorsData = new List<byte[]>(); sectorsData = new List<byte[]>();
for(int i = 0; i < trkCounter; i++) for(int i = 0; i < trkCounter; i++)
{ {
@@ -231,7 +232,7 @@ namespace DiscImageChef.DiscImages
allEqual = false; allEqual = false;
} }
short maxJ = sechdr.spt; short maxJ = sechdr.spt;
byte[] secB; byte[] secB;
for(short j = 1; j < maxJ; j++) for(short j = 1; j < maxJ; j++)
{ {
@@ -345,81 +346,81 @@ namespace DiscImageChef.DiscImages
DicConsole.DebugWriteLine("D88 plugin", "MediaType: {0}", imageInfo.MediaType); DicConsole.DebugWriteLine("D88 plugin", "MediaType: {0}", imageInfo.MediaType);
imageInfo.ImageSize = (ulong)d88Hdr.disk_size; imageInfo.ImageSize = (ulong)d88Hdr.disk_size;
imageInfo.CreationTime = imageFilter.GetCreationTime(); imageInfo.CreationTime = imageFilter.GetCreationTime();
imageInfo.LastModificationTime = imageFilter.GetLastWriteTime(); imageInfo.LastModificationTime = imageFilter.GetLastWriteTime();
imageInfo.MediaTitle = Path.GetFileNameWithoutExtension(imageFilter.GetFilename()); imageInfo.MediaTitle = Path.GetFileNameWithoutExtension(imageFilter.GetFilename());
imageInfo.Sectors = (ulong)sectorsData.Count; imageInfo.Sectors = (ulong)sectorsData.Count;
imageInfo.Comments = StringHandlers.CToString(d88Hdr.name, shiftjis); imageInfo.Comments = StringHandlers.CToString(d88Hdr.name, shiftjis);
imageInfo.XmlMediaType = XmlMediaType.BlockMedia; imageInfo.XmlMediaType = XmlMediaType.BlockMedia;
imageInfo.SectorSize = (uint)(128 << (int)bps); imageInfo.SectorSize = (uint)(128 << (int)bps);
switch(imageInfo.MediaType) switch(imageInfo.MediaType)
{ {
case MediaType.NEC_525_SS: case MediaType.NEC_525_SS:
imageInfo.Cylinders = 80; imageInfo.Cylinders = 80;
imageInfo.Heads = 1; imageInfo.Heads = 1;
imageInfo.SectorsPerTrack = 16; imageInfo.SectorsPerTrack = 16;
break; break;
case MediaType.NEC_8_SD: case MediaType.NEC_8_SD:
case MediaType.NEC_8_DD: case MediaType.NEC_8_DD:
imageInfo.Cylinders = 77; imageInfo.Cylinders = 77;
imageInfo.Heads = 2; imageInfo.Heads = 2;
imageInfo.SectorsPerTrack = 26; imageInfo.SectorsPerTrack = 26;
break; break;
case MediaType.NEC_525_DS: case MediaType.NEC_525_DS:
imageInfo.Cylinders = 80; imageInfo.Cylinders = 80;
imageInfo.Heads = 2; imageInfo.Heads = 2;
imageInfo.SectorsPerTrack = 16; imageInfo.SectorsPerTrack = 16;
break; break;
case MediaType.NEC_525_HD: case MediaType.NEC_525_HD:
imageInfo.Cylinders = 77; imageInfo.Cylinders = 77;
imageInfo.Heads = 2; imageInfo.Heads = 2;
imageInfo.SectorsPerTrack = 8; imageInfo.SectorsPerTrack = 8;
break; break;
case MediaType.DOS_525_SS_DD_8: case MediaType.DOS_525_SS_DD_8:
imageInfo.Cylinders = 40; imageInfo.Cylinders = 40;
imageInfo.Heads = 1; imageInfo.Heads = 1;
imageInfo.SectorsPerTrack = 8; imageInfo.SectorsPerTrack = 8;
break; break;
case MediaType.DOS_525_SS_DD_9: case MediaType.DOS_525_SS_DD_9:
imageInfo.Cylinders = 40; imageInfo.Cylinders = 40;
imageInfo.Heads = 1; imageInfo.Heads = 1;
imageInfo.SectorsPerTrack = 9; imageInfo.SectorsPerTrack = 9;
break; break;
case MediaType.DOS_525_DS_DD_8: case MediaType.DOS_525_DS_DD_8:
imageInfo.Cylinders = 40; imageInfo.Cylinders = 40;
imageInfo.Heads = 2; imageInfo.Heads = 2;
imageInfo.SectorsPerTrack = 8; imageInfo.SectorsPerTrack = 8;
break; break;
case MediaType.DOS_525_DS_DD_9: case MediaType.DOS_525_DS_DD_9:
imageInfo.Cylinders = 40; imageInfo.Cylinders = 40;
imageInfo.Heads = 2; imageInfo.Heads = 2;
imageInfo.SectorsPerTrack = 9; imageInfo.SectorsPerTrack = 9;
break; break;
case MediaType.NEC_35_HD_15: case MediaType.NEC_35_HD_15:
imageInfo.Cylinders = 80; imageInfo.Cylinders = 80;
imageInfo.Heads = 2; imageInfo.Heads = 2;
imageInfo.SectorsPerTrack = 15; imageInfo.SectorsPerTrack = 15;
break; break;
case MediaType.DOS_35_DS_DD_9: case MediaType.DOS_35_DS_DD_9:
imageInfo.Cylinders = 80; imageInfo.Cylinders = 80;
imageInfo.Heads = 2; imageInfo.Heads = 2;
imageInfo.SectorsPerTrack = 9; imageInfo.SectorsPerTrack = 9;
break; break;
case MediaType.DOS_35_HD: case MediaType.DOS_35_HD:
imageInfo.Cylinders = 80; imageInfo.Cylinders = 80;
imageInfo.Heads = 2; imageInfo.Heads = 2;
imageInfo.SectorsPerTrack = 18; imageInfo.SectorsPerTrack = 18;
break; break;
case MediaType.DOS_35_ED: case MediaType.DOS_35_ED:
imageInfo.Cylinders = 80; imageInfo.Cylinders = 80;
imageInfo.Heads = 2; imageInfo.Heads = 2;
imageInfo.SectorsPerTrack = 36; imageInfo.SectorsPerTrack = 36;
break; break;
case MediaType.NEC_35_TD: case MediaType.NEC_35_TD:
imageInfo.Cylinders = 240; imageInfo.Cylinders = 240;
imageInfo.Heads = 2; imageInfo.Heads = 2;
imageInfo.SectorsPerTrack = 38; imageInfo.SectorsPerTrack = 38;
break; break;
} }
@@ -523,7 +524,7 @@ namespace DiscImageChef.DiscImages
} }
public bool? VerifySectors(ulong sectorAddress, uint length, out List<ulong> failingLbas, public bool? VerifySectors(ulong sectorAddress, uint length, out List<ulong> failingLbas,
out List<ulong> unknownLbas) out List<ulong> unknownLbas)
{ {
failingLbas = new List<ulong>(); failingLbas = new List<ulong>();
unknownLbas = new List<ulong>(); unknownLbas = new List<ulong>();
@@ -533,7 +534,7 @@ namespace DiscImageChef.DiscImages
} }
public bool? VerifySectors(ulong sectorAddress, uint length, uint track, out List<ulong> failingLbas, public bool? VerifySectors(ulong sectorAddress, uint length, uint track, out List<ulong> failingLbas,
out List<ulong> unknownLbas) out List<ulong> unknownLbas)
{ {
throw new FeatureUnsupportedImageException("Feature not supported by image format"); throw new FeatureUnsupportedImageException("Feature not supported by image format");
} }
@@ -545,7 +546,7 @@ namespace DiscImageChef.DiscImages
enum DiskType : byte enum DiskType : byte
{ {
D2 = 0x00, D2 = 0x00,
Dd2 = 0x10, Dd2 = 0x10,
Hd2 = 0x20 Hd2 = 0x20
} }
@@ -553,7 +554,7 @@ namespace DiscImageChef.DiscImages
enum DensityType : byte enum DensityType : byte
{ {
Mfm = 0x00, Mfm = 0x00,
Fm = 0x40 Fm = 0x40
} }
/// <summary> /// <summary>
@@ -601,12 +602,14 @@ namespace DiscImageChef.DiscImages
/// Disk name, nul-terminated ASCII /// Disk name, nul-terminated ASCII
/// ディスクの名前(ASCII + '\0') /// ディスクの名前(ASCII + '\0')
/// </summary> /// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 17)] public byte[] name; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 17)]
public byte[] name;
/// <summary> /// <summary>
/// Reserved /// Reserved
/// ディスクの名前(ASCII + '\0') /// ディスクの名前(ASCII + '\0')
/// </summary> /// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 9)] public byte[] reserved; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 9)]
public byte[] reserved;
/// <summary> /// <summary>
/// Write protect status /// Write protect status
/// ライトプロテクト: 0x00 なし、0x10 あり /// ライトプロテクト: 0x00 なし、0x10 あり
@@ -626,7 +629,8 @@ namespace DiscImageChef.DiscImages
/// Track pointers /// Track pointers
/// トラック部のオフセットテーブル 0 Track 163 Track /// トラック部のオフセットテーブル 0 Track 163 Track
/// </summary> /// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 164)] public int[] track_table; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 164)]
public int[] track_table;
} }
[StructLayout(LayoutKind.Sequential, Pack = 1)] [StructLayout(LayoutKind.Sequential, Pack = 1)]
@@ -676,7 +680,8 @@ namespace DiscImageChef.DiscImages
/// Reserved /// Reserved
/// リザーブ /// リザーブ
/// </summary> /// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 5)] public byte[] reserved; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 5)]
public byte[] reserved;
/// <summary> /// <summary>
/// Size of data following this field /// Size of data following this field
/// このセクタ部のデータサイズ /// このセクタ部のデータサイズ

View File

@@ -57,23 +57,23 @@ namespace DiscImageChef.DiscImages
{ {
imageInfo = new ImageInfo imageInfo = new ImageInfo
{ {
ReadableSectorTags = new List<SectorTagType>(), ReadableSectorTags = new List<SectorTagType>(),
ReadableMediaTags = new List<MediaTagType>(), ReadableMediaTags = new List<MediaTagType>(),
HasPartitions = false, HasPartitions = false,
HasSessions = false, HasSessions = false,
Application = "DiskCopy", Application = "DiskCopy",
Creator = null, Creator = null,
Comments = null, Comments = null,
MediaManufacturer = null, MediaManufacturer = null,
MediaModel = null, MediaModel = null,
MediaSerialNumber = null, MediaSerialNumber = null,
MediaBarcode = null, MediaBarcode = null,
MediaPartNumber = null, MediaPartNumber = null,
MediaSequence = 0, MediaSequence = 0,
LastMediaSequence = 0, LastMediaSequence = 0,
DriveManufacturer = null, DriveManufacturer = null,
DriveModel = null, DriveModel = null,
DriveSerialNumber = null, DriveSerialNumber = null,
DriveFirmwareRevision = null DriveFirmwareRevision = null
}; };
} }
@@ -81,7 +81,7 @@ namespace DiscImageChef.DiscImages
public ImageInfo Info => imageInfo; public ImageInfo Info => imageInfo;
public string Name => "Digital Research DiskCopy"; 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"; public string ImageFormat => "Digital Research DiskCopy";
@@ -112,21 +112,21 @@ namespace DiscImageChef.DiscImages
string sig = StringHandlers.CToString(tmpFooter.signature); string sig = StringHandlers.CToString(tmpFooter.signature);
DicConsole.DebugWriteLine("DRI DiskCopy plugin", "tmp_footer.signature = \"{0}\"", sig); 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.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.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.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.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.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.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.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.sectors = {0}", tmpFooter.bpb.sectors);
DicConsole.DebugWriteLine("DRI DiskCopy plugin", "tmp_footer.bpb.media_descriptor = {0}", DicConsole.DebugWriteLine("DRI DiskCopy plugin", "tmp_footer.bpb.media_descriptor = {0}",
tmpFooter.bpb.media_descriptor); 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.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.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.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.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.drive_no = {0}", tmpFooter.bpb.drive_no);
DicConsole.DebugWriteLine("DRI DiskCopy plugin", "tmp_footer.bpb.unknown3 = {0}", tmpFooter.bpb.unknown3); 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.Seek(-buffer.Length, SeekOrigin.End);
stream.Read(buffer, 0, buffer.Length); stream.Read(buffer, 0, buffer.Length);
footer = new DriFooter(); footer = new DriFooter();
IntPtr ftrPtr = Marshal.AllocHGlobal(buffer.Length); IntPtr ftrPtr = Marshal.AllocHGlobal(buffer.Length);
Marshal.Copy(buffer, 0, ftrPtr, buffer.Length); Marshal.Copy(buffer, 0, ftrPtr, buffer.Length);
footer = (DriFooter)Marshal.PtrToStructure(ftrPtr, typeof(DriFooter)); 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; if(footer.bpb.sectors * footer.bpb.bps + Marshal.SizeOf(footer) != stream.Length) return false;
imageInfo.Cylinders = footer.bpb.cylinders; imageInfo.Cylinders = footer.bpb.cylinders;
imageInfo.Heads = footer.bpb.heads; imageInfo.Heads = footer.bpb.heads;
imageInfo.SectorsPerTrack = footer.bpb.sptrack; imageInfo.SectorsPerTrack = footer.bpb.sptrack;
imageInfo.Sectors = footer.bpb.sectors; imageInfo.Sectors = footer.bpb.sectors;
imageInfo.SectorSize = footer.bpb.bps; imageInfo.SectorSize = footer.bpb.bps;
imageInfo.ApplicationVersion = matchSignature.Groups["version"].Value; imageInfo.ApplicationVersion = matchSignature.Groups["version"].Value;
driImageFilter = imageFilter; driImageFilter = imageFilter;
imageInfo.ImageSize = (ulong)(stream.Length - Marshal.SizeOf(footer)); imageInfo.ImageSize = (ulong)(stream.Length - Marshal.SizeOf(footer));
imageInfo.CreationTime = imageFilter.GetCreationTime(); imageInfo.CreationTime = imageFilter.GetCreationTime();
imageInfo.LastModificationTime = imageFilter.GetLastWriteTime(); imageInfo.LastModificationTime = imageFilter.GetLastWriteTime();
DicConsole.DebugWriteLine("DRI DiskCopy plugin", "Image application = {0} version {1}", DicConsole.DebugWriteLine("DRI DiskCopy plugin", "Image application = {0} version {1}",
imageInfo.Application, imageInfo.ApplicationVersion); imageInfo.Application, imageInfo.ApplicationVersion);
// Correct some incorrect data in images of NEC 2HD disks // Correct some incorrect data in images of NEC 2HD disks
if(imageInfo.Cylinders == 77 && imageInfo.Heads == 2 && imageInfo.SectorsPerTrack == 16 && if(imageInfo.Cylinders == 77 && imageInfo.Heads == 2 &&
imageInfo.SectorSize == 512 && imageInfo.SectorsPerTrack == 16 &&
(footer.bpb.driveCode == DriDriveCodes.md2hd || footer.bpb.driveCode == DriDriveCodes.mf2hd)) imageInfo.SectorSize == 512 &&
(footer.bpb.driveCode == DriDriveCodes.md2hd ||
footer.bpb.driveCode == DriDriveCodes.mf2hd))
{ {
imageInfo.SectorsPerTrack = 8; 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: case MediaType.NEC_525_HD when footer.bpb.driveCode == DriDriveCodes.mf2hd ||
if(imageInfo.Heads == 2 && imageInfo.Cylinders == 80 && imageInfo.SectorsPerTrack == 15 && footer.bpb.driveCode == DriDriveCodes.mf2ed:
imageInfo.SectorSize == 512) imageInfo.MediaType = MediaType.DOS_525_HD; imageInfo.MediaType = MediaType.NEC_35_HD_8;
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;
break; break;
case DriDriveCodes.md2dd: case MediaType.DOS_525_HD when footer.bpb.driveCode == DriDriveCodes.mf2hd ||
if(imageInfo.Heads == 1 && imageInfo.Cylinders == 40 && imageInfo.SectorsPerTrack == 8 && footer.bpb.driveCode == DriDriveCodes.mf2ed:
imageInfo.SectorSize == 512) imageInfo.MediaType = MediaType.DOS_525_SS_DD_8; imageInfo.MediaType = MediaType.NEC_35_HD_15;
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;
break; break;
case DriDriveCodes.mf2ed: case MediaType.RX50 when footer.bpb.driveCode == DriDriveCodes.md2dd ||
if(imageInfo.Heads == 2 && imageInfo.Cylinders == 80 && imageInfo.SectorsPerTrack == 36 && footer.bpb.driveCode == DriDriveCodes.md2hd:
imageInfo.SectorSize == 512) imageInfo.MediaType = MediaType.DOS_35_ED; imageInfo.MediaType = MediaType.ATARI_35_SS_DD;
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;
break; break;
} }
@@ -289,7 +242,7 @@ namespace DiscImageChef.DiscImages
} }
public bool? VerifySectors(ulong sectorAddress, uint length, out List<ulong> failingLbas, public bool? VerifySectors(ulong sectorAddress, uint length, out List<ulong> failingLbas,
out List<ulong> unknownLbas) out List<ulong> unknownLbas)
{ {
failingLbas = new List<ulong>(); failingLbas = new List<ulong>();
unknownLbas = new List<ulong>(); unknownLbas = new List<ulong>();
@@ -300,7 +253,7 @@ namespace DiscImageChef.DiscImages
} }
public bool? VerifySectors(ulong sectorAddress, uint length, uint track, out List<ulong> failingLbas, public bool? VerifySectors(ulong sectorAddress, uint length, uint track, out List<ulong> failingLbas,
out List<ulong> unknownLbas) out List<ulong> unknownLbas)
{ {
failingLbas = new List<ulong>(); failingLbas = new List<ulong>();
unknownLbas = new List<ulong>(); unknownLbas = new List<ulong>();
@@ -336,7 +289,7 @@ namespace DiscImageChef.DiscImages
byte[] buffer = new byte[length * imageInfo.SectorSize]; byte[] buffer = new byte[length * imageInfo.SectorSize];
Stream stream = driImageFilter.GetDataForkStream(); 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)); stream.Read(buffer, 0, (int)(length * imageInfo.SectorSize));
return buffer; return buffer;
@@ -406,7 +359,8 @@ namespace DiscImageChef.DiscImages
struct DriFooter struct DriFooter
{ {
/// <summary>Signature: "DiskImage 2.01 (C) 1990,1991 Digital Research Inc\0"</summary> /// <summary>Signature: "DiskImage 2.01 (C) 1990,1991 Digital Research Inc\0"</summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 51)] public byte[] signature; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 51)]
public byte[] signature;
/// <summary>Information about the disk image, mostly imitates FAT BPB</summary> /// <summary>Information about the disk image, mostly imitates FAT BPB</summary>
public DriBpb bpb; public DriBpb bpb;
/// <summary>Information about the disk image, mostly imitates FAT BPB, copy</summary> /// <summary>Information about the disk image, mostly imitates FAT BPB, copy</summary>
@@ -457,7 +411,8 @@ namespace DiscImageChef.DiscImages
/// <summary>Sectors per track (again?)</summary> /// <summary>Sectors per track (again?)</summary>
public ushort sptrack2; public ushort sptrack2;
/// <summary>Seems to be 0</summary> /// <summary>Seems to be 0</summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 144)] public byte[] unknown5; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 144)]
public byte[] unknown5;
} }
/// <summary> /// <summary>

View File

@@ -66,7 +66,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using DiscImageChef.CommonTypes; using DiscImageChef.CommonTypes;
using DiscImageChef.Console; using DiscImageChef.Console;
@@ -76,17 +75,6 @@ namespace DiscImageChef.DiscImages
{ {
public class HdCopy : IMediaImage 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}
};
/// <summary> /// <summary>
/// The HDCP file header after the image has been opened /// The HDCP file header after the image has been opened
/// </summary> /// </summary>
@@ -95,7 +83,7 @@ namespace DiscImageChef.DiscImages
/// <summary> /// <summary>
/// The ImageFilter we're reading from, after the file has been opened /// The ImageFilter we're reading from, after the file has been opened
/// </summary> /// </summary>
IFilter hdcpImageFilter; IFilter hdcpImageFilter;
ImageInfo imageInfo; ImageInfo imageInfo;
/// <summary> /// <summary>
@@ -112,25 +100,25 @@ namespace DiscImageChef.DiscImages
{ {
imageInfo = new ImageInfo imageInfo = new ImageInfo
{ {
ReadableSectorTags = new List<SectorTagType>(), ReadableSectorTags = new List<SectorTagType>(),
ReadableMediaTags = new List<MediaTagType>(), ReadableMediaTags = new List<MediaTagType>(),
HasPartitions = false, HasPartitions = false,
HasSessions = false, HasSessions = false,
Version = null, Version = null,
Application = null, Application = null,
ApplicationVersion = null, ApplicationVersion = null,
Creator = null, Creator = null,
Comments = null, Comments = null,
MediaManufacturer = null, MediaManufacturer = null,
MediaModel = null, MediaModel = null,
MediaSerialNumber = null, MediaSerialNumber = null,
MediaBarcode = null, MediaBarcode = null,
MediaPartNumber = null, MediaPartNumber = null,
MediaSequence = 0, MediaSequence = 0,
LastMediaSequence = 0, LastMediaSequence = 0,
DriveManufacturer = null, DriveManufacturer = null,
DriveModel = null, DriveModel = null,
DriveSerialNumber = null, DriveSerialNumber = null,
DriveFirmwareRevision = null DriveFirmwareRevision = null
}; };
} }
@@ -138,10 +126,10 @@ namespace DiscImageChef.DiscImages
public ImageInfo Info => imageInfo; public ImageInfo Info => imageInfo;
public string Name => "HD-Copy disk image"; 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 string ImageFormat => "HD-Copy image";
public List<Partition> Partitions => public List<Partition> Partitions =>
throw new FeatureUnsupportedImageException("Feature not supported by image format"); throw new FeatureUnsupportedImageException("Feature not supported by image format");
public List<Track> Tracks => public List<Track> Tracks =>
@@ -158,10 +146,10 @@ namespace DiscImageChef.DiscImages
if(stream.Length < 2 + 2 * 82) return false; if(stream.Length < 2 + 2 * 82) return false;
byte[] header = new byte[2 + 2 * 82]; 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); 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)); HdcpFileHeader fheader = (HdcpFileHeader)Marshal.PtrToStructure(hdrPtr, typeof(HdcpFileHeader));
Marshal.FreeHGlobal(hdrPtr); Marshal.FreeHGlobal(hdrPtr);
@@ -177,7 +165,9 @@ namespace DiscImageChef.DiscImages
if(fheader.trackMap[0] != 1 || fheader.trackMap[1] != 1) return false; if(fheader.trackMap[0] != 1 || fheader.trackMap[1] != 1) return false;
// all other tracks must be either present (=1) or absent (=0) // 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 // TODO: validate the tracks
// For now, having a valid header should be sufficient. // For now, having a valid header should be sufficient.
@@ -186,54 +176,51 @@ namespace DiscImageChef.DiscImages
public bool OpenImage(IFilter imageFilter) public bool OpenImage(IFilter imageFilter)
{ {
long currentOffset;
Stream stream = imageFilter.GetDataForkStream(); Stream stream = imageFilter.GetDataForkStream();
stream.Seek(0, SeekOrigin.Begin); stream.Seek(0, SeekOrigin.Begin);
byte[] header = new byte[2 + 2 * 82]; 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); 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)); HdcpFileHeader fheader = (HdcpFileHeader)Marshal.PtrToStructure(hdrPtr, typeof(HdcpFileHeader));
Marshal.FreeHGlobal(hdrPtr); Marshal.FreeHGlobal(hdrPtr);
DicConsole.DebugWriteLine("HDCP plugin", DicConsole.DebugWriteLine("HDCP plugin",
"Detected HD-Copy image with {0} tracks and {1} sectors per track.", "Detected HD-Copy image with {0} tracks and {1} sectors per track.",
fheader.lastCylinder + 1, fheader.sectorsPerTrack); fheader.lastCylinder + 1, fheader.sectorsPerTrack);
imageInfo.Cylinders = (uint)fheader.lastCylinder + 1; imageInfo.Cylinders = (uint)fheader.lastCylinder + 1;
imageInfo.SectorsPerTrack = fheader.sectorsPerTrack; imageInfo.SectorsPerTrack = fheader.sectorsPerTrack;
imageInfo.SectorSize = 512; // only 512 bytes per sector supported imageInfo.SectorSize = 512; // only 512 bytes per sector supported
imageInfo.Heads = 2; // only 2-sided floppies are supported imageInfo.Heads = 2; // only 2-sided floppies are supported
imageInfo.Sectors = 2 * imageInfo.Cylinders * imageInfo.SectorsPerTrack; imageInfo.Sectors = 2 * imageInfo.Cylinders * imageInfo.SectorsPerTrack;
imageInfo.ImageSize = imageInfo.Sectors * imageInfo.SectorSize; imageInfo.ImageSize = imageInfo.Sectors * imageInfo.SectorSize;
imageInfo.XmlMediaType = XmlMediaType.BlockMedia; imageInfo.XmlMediaType = XmlMediaType.BlockMedia;
imageInfo.CreationTime = imageFilter.GetCreationTime(); imageInfo.CreationTime = imageFilter.GetCreationTime();
imageInfo.LastModificationTime = imageFilter.GetLastWriteTime(); imageInfo.LastModificationTime = imageFilter.GetLastWriteTime();
imageInfo.MediaTitle = Path.GetFileNameWithoutExtension(imageFilter.GetFilename()); imageInfo.MediaTitle = Path.GetFileNameWithoutExtension(imageFilter.GetFilename());
imageInfo.MediaType = imageInfo.MediaType =
(from ent in mediaTypes Geometry.GetMediaType(((ushort)imageInfo.Cylinders, 2, (ushort)imageInfo.SectorsPerTrack, 512,
where ent.Tracks == imageInfo.Cylinders && ent.SectorsPerTrack == imageInfo.SectorsPerTrack MediaEncoding.MFM, false));
select ent.MediaType).FirstOrDefault();
// the start offset of the track data // the start offset of the track data
currentOffset = 2 + 2 * 82; long currentOffset = 2 + 2 * 82;
// build table of track offsets // build table of track offsets
for(int i = 0; i < imageInfo.Cylinders * 2; i++) for(int i = 0; i < imageInfo.Cylinders * 2; i++)
if(fheader.trackMap[i] == 0) trackOffset[i] = -1; if(fheader.trackMap[i] == 0)
trackOffset[i] = -1;
else else
{ {
// track is present, read the block header // track is present, read the block header
if(currentOffset + 3 >= stream.Length) return false; if(currentOffset + 3 >= stream.Length) return false;
byte[] blkHeader = new byte[2]; byte[] blkHeader = new byte[2];
short blkLength;
stream.Read(blkHeader, 0, 2); stream.Read(blkHeader, 0, 2);
blkLength = BitConverter.ToInt16(blkHeader, 0); short blkLength = BitConverter.ToInt16(blkHeader, 0);
// assume block sizes are positive // assume block sizes are positive
if(blkLength < 0) return false; if(blkLength < 0) return false;
@@ -251,57 +238,14 @@ namespace DiscImageChef.DiscImages
if(currentOffset > stream.Length) return false; if(currentOffset > stream.Length) return false;
// save some variables for later use // save some variables for later use
fileHeader = fheader; fileHeader = fheader;
hdcpImageFilter = imageFilter; hdcpImageFilter = imageFilter;
return true; 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) 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)); int sectorOffset = (int)(sectorAddress % (imageInfo.SectorsPerTrack * imageInfo.SectorSize));
if(sectorAddress > imageInfo.Sectors - 1) if(sectorAddress > imageInfo.Sectors - 1)
@@ -412,7 +356,7 @@ namespace DiscImageChef.DiscImages
} }
public bool? VerifySectors(ulong sectorAddress, uint length, out List<ulong> failingLbas, public bool? VerifySectors(ulong sectorAddress, uint length, out List<ulong> failingLbas,
out List<ulong> unknownLbas) out List<ulong> unknownLbas)
{ {
failingLbas = new List<ulong>(); failingLbas = new List<ulong>();
unknownLbas = new List<ulong>(); unknownLbas = new List<ulong>();
@@ -422,7 +366,7 @@ namespace DiscImageChef.DiscImages
} }
public bool? VerifySectors(ulong sectorAddress, uint length, uint track, out List<ulong> failingLbas, public bool? VerifySectors(ulong sectorAddress, uint length, uint track, out List<ulong> failingLbas,
out List<ulong> unknownLbas) out List<ulong> unknownLbas)
{ {
throw new FeatureUnsupportedImageException("Feature not supported by image format"); throw new FeatureUnsupportedImageException("Feature not supported by image format");
} }
@@ -432,6 +376,48 @@ namespace DiscImageChef.DiscImages
return null; 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;
}
/// <summary> /// <summary>
/// The global header of a HDCP image file /// The global header of a HDCP image file
/// </summary> /// </summary>
@@ -454,7 +440,8 @@ namespace DiscImageChef.DiscImages
/// 0 means track is not present, 1 means it is present. /// 0 means track is not present, 1 means it is present.
/// The first 2 tracks are always present. /// The first 2 tracks are always present.
/// </summary> /// </summary>
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2 * 82)] public byte[] trackMap; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 2 * 82)]
public byte[] trackMap;
} }
/// <summary> /// <summary>
@@ -473,12 +460,5 @@ namespace DiscImageChef.DiscImages
/// </summary> /// </summary>
public byte escape; public byte escape;
} }
struct MediaTypeTableEntry
{
public byte Tracks;
public byte SectorsPerTrack;
public MediaType MediaType;
}
} }
} }

View File

@@ -43,12 +43,11 @@ namespace DiscImageChef.DiscImages
{ {
public class Imd : IMediaImage public class Imd : IMediaImage
{ {
const byte SECTOR_CYLINDER_MAP_MASK = 0x80; const byte SECTOR_CYLINDER_MAP_MASK = 0x80;
const byte SECTOR_HEAD_MAP_MASK = 0x40; const byte SECTOR_HEAD_MAP_MASK = 0x40;
const byte COMMENT_END = 0x1A; const byte COMMENT_END = 0x1A;
const string REGEX_HEADER = const string REGEX_HEADER =
@"IMD (?<version>\d.\d+):\s+(?<day>\d+)\/\s*(?<month>\d+)\/(?<year>\d+)\s+(?<hour>\d+):(?<minute>\d+):(?<second>\d+)\r\n" @"IMD (?<version>\d.\d+):\s+(?<day>\d+)\/\s*(?<month>\d+)\/(?<year>\d+)\s+(?<hour>\d+):(?<minute>\d+):(?<second>\d+)\r\n";
;
ImageInfo imageInfo; ImageInfo imageInfo;
List<byte[]> sectorsData; List<byte[]> sectorsData;
@@ -57,31 +56,31 @@ namespace DiscImageChef.DiscImages
{ {
imageInfo = new ImageInfo imageInfo = new ImageInfo
{ {
ReadableSectorTags = new List<SectorTagType>(), ReadableSectorTags = new List<SectorTagType>(),
ReadableMediaTags = new List<MediaTagType>(), ReadableMediaTags = new List<MediaTagType>(),
HasPartitions = false, HasPartitions = false,
HasSessions = false, HasSessions = false,
Version = null, Version = null,
Application = null, Application = null,
ApplicationVersion = null, ApplicationVersion = null,
Creator = null, Creator = null,
Comments = null, Comments = null,
MediaManufacturer = null, MediaManufacturer = null,
MediaModel = null, MediaModel = null,
MediaSerialNumber = null, MediaSerialNumber = null,
MediaBarcode = null, MediaBarcode = null,
MediaPartNumber = null, MediaPartNumber = null,
MediaSequence = 0, MediaSequence = 0,
LastMediaSequence = 0, LastMediaSequence = 0,
DriveManufacturer = null, DriveManufacturer = null,
DriveModel = null, DriveModel = null,
DriveSerialNumber = null, DriveSerialNumber = null,
DriveFirmwareRevision = null DriveFirmwareRevision = null
}; };
} }
public string Name => "Dunfield's IMD"; public string Name => "Dunfield's IMD";
public Guid Id => new Guid("0D67162E-38A3-407D-9B1A-CF40080A48CB"); public Guid Id => new Guid("0D67162E-38A3-407D-9B1A-CF40080A48CB");
public ImageInfo Info => imageInfo; public ImageInfo Info => imageInfo;
public string ImageFormat => "IMageDisk"; public string ImageFormat => "IMageDisk";
@@ -126,26 +125,26 @@ namespace DiscImageChef.DiscImages
} }
imageInfo.Comments = StringHandlers.CToString(cmt.ToArray()); imageInfo.Comments = StringHandlers.CToString(cmt.ToArray());
sectorsData = new List<byte[]>(); sectorsData = new List<byte[]>();
byte currentCylinder = 0; byte currentCylinder = 0;
imageInfo.Cylinders = 1; imageInfo.Cylinders = 1;
imageInfo.Heads = 1; imageInfo.Heads = 1;
ulong currentLba = 0; ulong currentLba = 0;
TransferRate mode = TransferRate.TwoHundred; TransferRate mode = TransferRate.TwoHundred;
while(stream.Position + 5 < stream.Length) while(stream.Position + 5 < stream.Length)
{ {
mode = (TransferRate)stream.ReadByte(); mode = (TransferRate)stream.ReadByte();
byte cylinder = (byte)stream.ReadByte(); byte cylinder = (byte)stream.ReadByte();
byte head = (byte)stream.ReadByte(); byte head = (byte)stream.ReadByte();
byte spt = (byte)stream.ReadByte(); byte spt = (byte)stream.ReadByte();
byte n = (byte)stream.ReadByte(); byte n = (byte)stream.ReadByte();
byte[] idmap = new byte[spt]; byte[] idmap = new byte[spt];
byte[] cylmap = new byte[spt]; byte[] cylmap = new byte[spt];
byte[] headmap = new byte[spt]; byte[] headmap = new byte[spt];
ushort[] bps = new ushort[spt]; ushort[] bps = new ushort[spt];
if(cylinder != currentCylinder) if(cylinder != currentCylinder)
{ {
@@ -155,16 +154,19 @@ namespace DiscImageChef.DiscImages
if((head & 1) == 1) imageInfo.Heads = 2; 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_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) if(n == 0xFF)
{ {
byte[] bpsbytes = new byte[spt * 2]; byte[] bpsbytes = new byte[spt * 2];
stream.Read(bpsbytes, 0, bpsbytes.Length); stream.Read(bpsbytes, 0, bpsbytes.Length);
for(int i = 0; i < spt; i++) bps[i] = BitConverter.ToUInt16(bpsbytes, i * 2); 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; if(spt > imageInfo.SectorsPerTrack) imageInfo.SectorsPerTrack = spt;
@@ -173,7 +175,7 @@ namespace DiscImageChef.DiscImages
for(int i = 0; i < spt; i++) for(int i = 0; i < spt; i++)
{ {
SectorType type = (SectorType)stream.ReadByte(); 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 // TODO; Handle disks with different bps in track 0
if(bps[i] > imageInfo.SectorSize) imageInfo.SectorSize = bps[i]; if(bps[i] > imageInfo.SectorSize) imageInfo.SectorSize = bps[i];
@@ -212,99 +214,31 @@ namespace DiscImageChef.DiscImages
imageInfo.Application = "IMD"; imageInfo.Application = "IMD";
// TODO: The header is the date of dump or the date of the application compilation? // 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.LastModificationTime = imageFilter.GetLastWriteTime();
imageInfo.MediaTitle = Path.GetFileNameWithoutExtension(imageFilter.GetFilename()); imageInfo.MediaTitle = Path.GetFileNameWithoutExtension(imageFilter.GetFilename());
imageInfo.Comments = StringHandlers.CToString(cmt.ToArray()); imageInfo.Comments = StringHandlers.CToString(cmt.ToArray());
imageInfo.Sectors = currentLba; imageInfo.Sectors = currentLba;
imageInfo.MediaType = MediaType.Unknown; 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 MediaType.NEC_525_HD when mode == TransferRate.FiveHundredMfm:
case TransferRate.ThreeHundred: imageInfo.MediaType = MediaType.NEC_35_HD_8;
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;
break; break;
case TransferRate.FiveHundred: case MediaType.DOS_525_HD when mode == TransferRate.FiveHundredMfm:
if(imageInfo.Heads == 1 && imageInfo.Cylinders == 32 && imageInfo.SectorsPerTrack == 8 && imageInfo.MediaType = MediaType.NEC_35_HD_15;
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;
break; break;
case TransferRate.TwoHundredMfm: case MediaType.RX50 when mode == TransferRate.FiveHundredMfm:
case TransferRate.ThreeHundredMfm: imageInfo.MediaType = MediaType.ATARI_35_SS_DD;
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;
break; break;
} }
@@ -335,7 +269,7 @@ namespace DiscImageChef.DiscImages
} }
public bool? VerifySectors(ulong sectorAddress, uint length, out List<ulong> failingLbas, public bool? VerifySectors(ulong sectorAddress, uint length, out List<ulong> failingLbas,
out List<ulong> unknownLbas) out List<ulong> unknownLbas)
{ {
failingLbas = new List<ulong>(); failingLbas = new List<ulong>();
unknownLbas = new List<ulong>(); unknownLbas = new List<ulong>();
@@ -346,7 +280,7 @@ namespace DiscImageChef.DiscImages
} }
public bool? VerifySectors(ulong sectorAddress, uint length, uint track, out List<ulong> failingLbas, public bool? VerifySectors(ulong sectorAddress, uint length, uint track, out List<ulong> failingLbas,
out List<ulong> unknownLbas) out List<ulong> unknownLbas)
{ {
failingLbas = new List<ulong>(); failingLbas = new List<ulong>();
unknownLbas = new List<ulong>(); unknownLbas = new List<ulong>();
@@ -464,14 +398,14 @@ namespace DiscImageChef.DiscImages
enum SectorType : byte enum SectorType : byte
{ {
Unavailable = 0, Unavailable = 0,
Normal = 1, Normal = 1,
Compressed = 2, Compressed = 2,
Deleted = 3, Deleted = 3,
CompressedDeleted = 4, CompressedDeleted = 4,
Error = 5, Error = 5,
CompressedError = 6, CompressedError = 6,
DeletedError = 7, DeletedError = 7,
CompressedDeletedError = 8 CompressedDeletedError = 8
} }
} }

View File

@@ -43,30 +43,30 @@ namespace DiscImageChef.DiscImages
public class MaxiDisk : IMediaImage public class MaxiDisk : IMediaImage
{ {
/// <summary>Disk image file</summary> /// <summary>Disk image file</summary>
IFilter hdkImageFilter; IFilter hdkImageFilter;
ImageInfo imageInfo; ImageInfo imageInfo;
public MaxiDisk() public MaxiDisk()
{ {
imageInfo = new ImageInfo imageInfo = new ImageInfo
{ {
ReadableSectorTags = new List<SectorTagType>(), ReadableSectorTags = new List<SectorTagType>(),
ReadableMediaTags = new List<MediaTagType>(), ReadableMediaTags = new List<MediaTagType>(),
HasPartitions = false, HasPartitions = false,
HasSessions = false, HasSessions = false,
Application = "MAXI Disk", Application = "MAXI Disk",
Creator = null, Creator = null,
Comments = null, Comments = null,
MediaManufacturer = null, MediaManufacturer = null,
MediaModel = null, MediaModel = null,
MediaSerialNumber = null, MediaSerialNumber = null,
MediaBarcode = null, MediaBarcode = null,
MediaPartNumber = null, MediaPartNumber = null,
MediaSequence = 0, MediaSequence = 0,
LastMediaSequence = 0, LastMediaSequence = 0,
DriveManufacturer = null, DriveManufacturer = null,
DriveModel = null, DriveModel = null,
DriveSerialNumber = null, DriveSerialNumber = null,
DriveFirmwareRevision = null DriveFirmwareRevision = null
}; };
} }
@@ -74,7 +74,7 @@ namespace DiscImageChef.DiscImages
public ImageInfo Info => imageInfo; public ImageInfo Info => imageInfo;
public string Name => "MAXI Disk image"; 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"; public string ImageFormat => "MAXI Disk";
@@ -102,10 +102,10 @@ namespace DiscImageChef.DiscImages
HdkHeader tmpHeader = (HdkHeader)Marshal.PtrToStructure(ftrPtr, typeof(HdkHeader)); HdkHeader tmpHeader = (HdkHeader)Marshal.PtrToStructure(ftrPtr, typeof(HdkHeader));
Marshal.FreeHGlobal(ftrPtr); Marshal.FreeHGlobal(ftrPtr);
DicConsole.DebugWriteLine("MAXI Disk plugin", "tmp_header.unknown = {0}", tmpHeader.unknown); 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.diskType = {0}", tmpHeader.diskType);
DicConsole.DebugWriteLine("MAXI Disk plugin", "tmp_header.heads = {0}", tmpHeader.heads); 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.cylinders = {0}", tmpHeader.cylinders);
DicConsole.DebugWriteLine("MAXI Disk plugin", "tmp_header.bytesPerSector = {0}", tmpHeader.bytesPerSector); DicConsole.DebugWriteLine("MAXI Disk plugin", "tmp_header.bytesPerSector = {0}", tmpHeader.bytesPerSector);
DicConsole.DebugWriteLine("MAXI Disk plugin", "tmp_header.sectorsPerTrack = {0}", DicConsole.DebugWriteLine("MAXI Disk plugin", "tmp_header.sectorsPerTrack = {0}",
tmpHeader.sectorsPerTrack); tmpHeader.sectorsPerTrack);
@@ -166,67 +166,22 @@ namespace DiscImageChef.DiscImages
if(expectedFileSize != stream.Length) return false; if(expectedFileSize != stream.Length) return false;
imageInfo.Cylinders = tmpHeader.cylinders; imageInfo.Cylinders = tmpHeader.cylinders;
imageInfo.Heads = tmpHeader.heads; imageInfo.Heads = tmpHeader.heads;
imageInfo.SectorsPerTrack = tmpHeader.sectorsPerTrack; imageInfo.SectorsPerTrack = tmpHeader.sectorsPerTrack;
imageInfo.Sectors = (ulong)(tmpHeader.heads * tmpHeader.cylinders * tmpHeader.sectorsPerTrack); imageInfo.Sectors = (ulong)(tmpHeader.heads * tmpHeader.cylinders * tmpHeader.sectorsPerTrack);
imageInfo.SectorSize = (uint)(128 << tmpHeader.bytesPerSector); imageInfo.SectorSize = (uint)(128 << tmpHeader.bytesPerSector);
hdkImageFilter = imageFilter; hdkImageFilter = imageFilter;
imageInfo.ImageSize = (ulong)(stream.Length - 8); imageInfo.ImageSize = (ulong)(stream.Length - 8);
imageInfo.CreationTime = imageFilter.GetCreationTime(); imageInfo.CreationTime = imageFilter.GetCreationTime();
imageInfo.LastModificationTime = imageFilter.GetLastWriteTime(); imageInfo.LastModificationTime = imageFilter.GetLastWriteTime();
if(imageInfo.Heads == 2 && imageInfo.Cylinders == 80 && imageInfo.SectorsPerTrack == 15 && imageInfo.MediaType =
imageInfo.SectorSize == 512) imageInfo.MediaType = MediaType.DOS_525_HD; Geometry.GetMediaType(((ushort)imageInfo.Cylinders, (byte)imageInfo.Heads,
else if(imageInfo.Heads == 2 && imageInfo.Cylinders == 80 && imageInfo.SectorsPerTrack == 16 && (ushort)imageInfo.SectorsPerTrack, imageInfo.SectorSize, MediaEncoding.MFM, false
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.XmlMediaType = XmlMediaType.BlockMedia; imageInfo.XmlMediaType = XmlMediaType.BlockMedia;
@@ -244,7 +199,7 @@ namespace DiscImageChef.DiscImages
} }
public bool? VerifySectors(ulong sectorAddress, uint length, out List<ulong> failingLbas, public bool? VerifySectors(ulong sectorAddress, uint length, out List<ulong> failingLbas,
out List<ulong> unknownLbas) out List<ulong> unknownLbas)
{ {
failingLbas = new List<ulong>(); failingLbas = new List<ulong>();
unknownLbas = new List<ulong>(); unknownLbas = new List<ulong>();
@@ -255,7 +210,7 @@ namespace DiscImageChef.DiscImages
} }
public bool? VerifySectors(ulong sectorAddress, uint length, uint track, out List<ulong> failingLbas, public bool? VerifySectors(ulong sectorAddress, uint length, uint track, out List<ulong> failingLbas,
out List<ulong> unknownLbas) out List<ulong> unknownLbas)
{ {
failingLbas = new List<ulong>(); failingLbas = new List<ulong>();
unknownLbas = new List<ulong>(); unknownLbas = new List<ulong>();
@@ -292,7 +247,7 @@ namespace DiscImageChef.DiscImages
Stream stream = hdkImageFilter.GetDataForkStream(); Stream stream = hdkImageFilter.GetDataForkStream();
stream.Seek((long)(8 + sectorAddress * imageInfo.SectorSize), SeekOrigin.Begin); 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; return buffer;
} }
@@ -372,17 +327,17 @@ namespace DiscImageChef.DiscImages
enum HdkDiskTypes : byte enum HdkDiskTypes : byte
{ {
Dos360 = 0, Dos360 = 0,
Maxi420 = 1, Maxi420 = 1,
Dos720 = 2, Dos720 = 2,
Maxi800 = 3, Maxi800 = 3,
Dos1200 = 4, Dos1200 = 4,
Maxi1400 = 5, Maxi1400 = 5,
Dos1440 = 6, Dos1440 = 6,
Mac1440 = 7, Mac1440 = 7,
Maxi1600 = 8, Maxi1600 = 8,
Dmf = 9, Dmf = 9,
Dos2880 = 10, Dos2880 = 10,
Maxi3200 = 11 Maxi3200 = 11
} }
} }

View File

@@ -45,39 +45,38 @@ namespace DiscImageChef.DiscImages
public class RayDim : IMediaImage public class RayDim : IMediaImage
{ {
const string REGEX_SIGNATURE = const string REGEX_SIGNATURE =
@"Disk IMage VER (?<major>\d).(?<minor>\d) Copyright \(C\) (?<year>\d{4}) Ray Arachelian, All Rights Reserved\." @"Disk IMage VER (?<major>\d).(?<minor>\d) Copyright \(C\) (?<year>\d{4}) Ray Arachelian, All Rights Reserved\.";
;
MemoryStream disk; MemoryStream disk;
ImageInfo imageInfo; ImageInfo imageInfo;
public RayDim() public RayDim()
{ {
imageInfo = new ImageInfo imageInfo = new ImageInfo
{ {
ReadableSectorTags = new List<SectorTagType>(), ReadableSectorTags = new List<SectorTagType>(),
ReadableMediaTags = new List<MediaTagType>(), ReadableMediaTags = new List<MediaTagType>(),
HasPartitions = false, HasPartitions = false,
HasSessions = false, HasSessions = false,
Application = "Ray Arachelian's Disk IMage", Application = "Ray Arachelian's Disk IMage",
Creator = null, Creator = null,
Comments = null, Comments = null,
MediaManufacturer = null, MediaManufacturer = null,
MediaModel = null, MediaModel = null,
MediaSerialNumber = null, MediaSerialNumber = null,
MediaBarcode = null, MediaBarcode = null,
MediaPartNumber = null, MediaPartNumber = null,
MediaSequence = 0, MediaSequence = 0,
LastMediaSequence = 0, LastMediaSequence = 0,
DriveManufacturer = null, DriveManufacturer = null,
DriveModel = null, DriveModel = null,
DriveSerialNumber = null, DriveSerialNumber = null,
DriveFirmwareRevision = null DriveFirmwareRevision = null
}; };
} }
public string Name => "Ray Arachelian's Disk IMage"; public string Name => "Ray Arachelian's Disk IMage";
public Guid Id => new Guid("F541F4E7-C1E3-4A2D-B07F-D863E87AB961"); public Guid Id => new Guid("F541F4E7-C1E3-4A2D-B07F-D863E87AB961");
public ImageInfo Info => imageInfo; public ImageInfo Info => imageInfo;
public string ImageFormat => "Ray Arachelian's Disk IMage"; public string ImageFormat => "Ray Arachelian's Disk IMage";
@@ -109,8 +108,8 @@ namespace DiscImageChef.DiscImages
string signature = StringHandlers.CToString(header.signature); 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.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.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.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.cylinders = {0}", header.cylinders);
DicConsole.DebugWriteLine("Ray Arachelian's Disk IMage plugin", "header.sectorsPerTrack = {0}", DicConsole.DebugWriteLine("Ray Arachelian's Disk IMage plugin", "header.sectorsPerTrack = {0}",
header.sectorsPerTrack); header.sectorsPerTrack);
@@ -148,14 +147,14 @@ namespace DiscImageChef.DiscImages
imageInfo.ApplicationVersion = $"{sm.Groups["major"].Value}.{sm.Groups["minor"].Value}"; imageInfo.ApplicationVersion = $"{sm.Groups["major"].Value}.{sm.Groups["minor"].Value}";
imageInfo.Cylinders = (uint)(header.cylinders + 1); imageInfo.Cylinders = (uint)(header.cylinders + 1);
imageInfo.Heads = (uint)(header.heads + 1); imageInfo.Heads = (uint)(header.heads + 1);
imageInfo.SectorsPerTrack = header.sectorsPerTrack; imageInfo.SectorsPerTrack = header.sectorsPerTrack;
imageInfo.Sectors = imageInfo.Cylinders * imageInfo.Heads * imageInfo.SectorsPerTrack; imageInfo.Sectors = imageInfo.Cylinders * imageInfo.Heads * imageInfo.SectorsPerTrack;
imageInfo.SectorSize = 512; imageInfo.SectorSize = 512;
byte[] sectors = new byte[imageInfo.SectorsPerTrack * imageInfo.SectorSize]; byte[] sectors = new byte[imageInfo.SectorsPerTrack * imageInfo.SectorSize];
disk = new MemoryStream(); disk = new MemoryStream();
for(int i = 0; i < imageInfo.SectorsPerTrack * imageInfo.SectorSize; i++) for(int i = 0; i < imageInfo.SectorsPerTrack * imageInfo.SectorSize; i++)
{ {
@@ -164,55 +163,22 @@ namespace DiscImageChef.DiscImages
disk.Write(sectors, 0, sectors.Length); 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: case MediaType.NEC_525_HD when header.diskType == RayDiskTypes.Mf2hd ||
if(imageInfo.Heads == 2 && imageInfo.Cylinders == 80 && imageInfo.SectorsPerTrack == 15) header.diskType == RayDiskTypes.Mf2ed:
imageInfo.MediaType = MediaType.DOS_525_HD; imageInfo.MediaType = MediaType.NEC_35_HD_8;
else goto case RayDiskTypes.Md2dd;
break; break;
case RayDiskTypes.Md2dd: case MediaType.DOS_525_HD when header.diskType == RayDiskTypes.Mf2hd ||
if(imageInfo.Heads == 1 && imageInfo.Cylinders == 40 && imageInfo.SectorsPerTrack == 8) header.diskType == RayDiskTypes.Mf2ed:
imageInfo.MediaType = MediaType.DOS_525_SS_DD_8; imageInfo.MediaType = MediaType.NEC_35_HD_15;
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;
break; break;
case RayDiskTypes.Mf2ed: case MediaType.RX50 when header.diskType == RayDiskTypes.Md2dd || header.diskType == RayDiskTypes.Md2hd:
if(imageInfo.Heads == 2 && imageInfo.Cylinders == 80 && imageInfo.SectorsPerTrack == 36) imageInfo.MediaType = MediaType.ATARI_35_SS_DD;
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;
break; break;
} }
@@ -232,7 +198,7 @@ namespace DiscImageChef.DiscImages
} }
public bool? VerifySectors(ulong sectorAddress, uint length, out List<ulong> failingLbas, public bool? VerifySectors(ulong sectorAddress, uint length, out List<ulong> failingLbas,
out List<ulong> unknownLbas) out List<ulong> unknownLbas)
{ {
failingLbas = new List<ulong>(); failingLbas = new List<ulong>();
unknownLbas = new List<ulong>(); unknownLbas = new List<ulong>();
@@ -243,7 +209,7 @@ namespace DiscImageChef.DiscImages
} }
public bool? VerifySectors(ulong sectorAddress, uint length, uint track, out List<ulong> failingLbas, public bool? VerifySectors(ulong sectorAddress, uint length, uint track, out List<ulong> failingLbas,
out List<ulong> unknownLbas) out List<ulong> unknownLbas)
{ {
failingLbas = new List<ulong>(); failingLbas = new List<ulong>();
unknownLbas = new List<ulong>(); unknownLbas = new List<ulong>();
@@ -278,7 +244,7 @@ namespace DiscImageChef.DiscImages
byte[] buffer = new byte[length * imageInfo.SectorSize]; 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)); disk.Read(buffer, 0, (int)(length * imageInfo.SectorSize));
return buffer; return buffer;
@@ -347,11 +313,12 @@ namespace DiscImageChef.DiscImages
[StructLayout(LayoutKind.Sequential, Pack = 1)] [StructLayout(LayoutKind.Sequential, Pack = 1)]
struct RayHdr struct RayHdr
{ {
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 80)] public byte[] signature; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 80)]
public byte[] signature;
public RayDiskTypes diskType; public RayDiskTypes diskType;
public byte cylinders; public byte cylinders;
public byte sectorsPerTrack; public byte sectorsPerTrack;
public byte heads; public byte heads;
} }
[SuppressMessage("ReSharper", "InconsistentNaming")] [SuppressMessage("ReSharper", "InconsistentNaming")]

View File

@@ -43,44 +43,44 @@ namespace DiscImageChef.DiscImages
{ {
public class SaveDskF : IMediaImage public class SaveDskF : IMediaImage
{ {
const ushort SDF_MAGIC_OLD = 0x58AA; const ushort SDF_MAGIC_OLD = 0x58AA;
const ushort SDF_MAGIC = 0x59AA; const ushort SDF_MAGIC = 0x59AA;
const ushort SDF_MAGIC_COMPRESSED = 0x5AAA; const ushort SDF_MAGIC_COMPRESSED = 0x5AAA;
uint calculatedChk; uint calculatedChk;
byte[] decodedDisk; byte[] decodedDisk;
SaveDskFHeader header; SaveDskFHeader header;
ImageInfo imageInfo; ImageInfo imageInfo;
public SaveDskF() public SaveDskF()
{ {
imageInfo = new ImageInfo imageInfo = new ImageInfo
{ {
ReadableSectorTags = new List<SectorTagType>(), ReadableSectorTags = new List<SectorTagType>(),
ReadableMediaTags = new List<MediaTagType>(), ReadableMediaTags = new List<MediaTagType>(),
HasPartitions = false, HasPartitions = false,
HasSessions = false, HasSessions = false,
Version = null, Version = null,
Application = null, Application = null,
ApplicationVersion = null, ApplicationVersion = null,
Creator = null, Creator = null,
Comments = null, Comments = null,
MediaManufacturer = null, MediaManufacturer = null,
MediaModel = null, MediaModel = null,
MediaSerialNumber = null, MediaSerialNumber = null,
MediaBarcode = null, MediaBarcode = null,
MediaPartNumber = null, MediaPartNumber = null,
MediaSequence = 0, MediaSequence = 0,
LastMediaSequence = 0, LastMediaSequence = 0,
DriveManufacturer = null, DriveManufacturer = null,
DriveModel = null, DriveModel = null,
DriveSerialNumber = null, DriveSerialNumber = null,
DriveFirmwareRevision = null DriveFirmwareRevision = null
}; };
} }
public string Name => "IBM SaveDskF"; public string Name => "IBM SaveDskF";
public Guid Id => new Guid("288CE058-1A51-4034-8C45-5A256CAE1461"); public Guid Id => new Guid("288CE058-1A51-4034-8C45-5A256CAE1461");
public ImageInfo Info => imageInfo; public ImageInfo Info => imageInfo;
public string ImageFormat => "IBM SaveDskF"; public string ImageFormat => "IBM SaveDskF";
@@ -103,15 +103,15 @@ namespace DiscImageChef.DiscImages
byte[] hdr = new byte[40]; byte[] hdr = new byte[40];
stream.Read(hdr, 0, 40); stream.Read(hdr, 0, 40);
header = new SaveDskFHeader(); header = new SaveDskFHeader();
IntPtr hdrPtr = Marshal.AllocHGlobal(40); IntPtr hdrPtr = Marshal.AllocHGlobal(40);
Marshal.Copy(hdr, 0, hdrPtr, 40); Marshal.Copy(hdr, 0, hdrPtr, 40);
header = (SaveDskFHeader)Marshal.PtrToStructure(hdrPtr, typeof(SaveDskFHeader)); header = (SaveDskFHeader)Marshal.PtrToStructure(hdrPtr, typeof(SaveDskFHeader));
Marshal.FreeHGlobal(hdrPtr); Marshal.FreeHGlobal(hdrPtr);
return (header.magic == SDF_MAGIC || header.magic == SDF_MAGIC_COMPRESSED || return (header.magic == SDF_MAGIC || header.magic == SDF_MAGIC_COMPRESSED ||
header.magic == SDF_MAGIC_OLD) && header.fatCopies <= 2 && header.padding == 0 && header.magic == SDF_MAGIC_OLD) && header.fatCopies <= 2 && header.padding == 0 &&
header.commentOffset < stream.Length && header.dataOffset < stream.Length; header.commentOffset < stream.Length && header.dataOffset < stream.Length;
} }
public bool OpenImage(IFilter imageFilter) public bool OpenImage(IFilter imageFilter)
@@ -122,31 +122,31 @@ namespace DiscImageChef.DiscImages
byte[] hdr = new byte[40]; byte[] hdr = new byte[40];
stream.Read(hdr, 0, 40); stream.Read(hdr, 0, 40);
header = new SaveDskFHeader(); header = new SaveDskFHeader();
IntPtr hdrPtr = Marshal.AllocHGlobal(40); IntPtr hdrPtr = Marshal.AllocHGlobal(40);
Marshal.Copy(hdr, 0, hdrPtr, 40); Marshal.Copy(hdr, 0, hdrPtr, 40);
header = (SaveDskFHeader)Marshal.PtrToStructure(hdrPtr, typeof(SaveDskFHeader)); header = (SaveDskFHeader)Marshal.PtrToStructure(hdrPtr, typeof(SaveDskFHeader));
Marshal.FreeHGlobal(hdrPtr); Marshal.FreeHGlobal(hdrPtr);
DicConsole.DebugWriteLine("SaveDskF plugin", "header.magic = 0x{0:X4}", header.magic); 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.mediaType = 0x{0:X2}", header.mediaType);
DicConsole.DebugWriteLine("SaveDskF plugin", "header.sectorSize = {0}", header.sectorSize); DicConsole.DebugWriteLine("SaveDskF plugin", "header.sectorSize = {0}", header.sectorSize);
DicConsole.DebugWriteLine("SaveDskF plugin", "header.clusterMask = {0}", header.clusterMask); DicConsole.DebugWriteLine("SaveDskF plugin", "header.clusterMask = {0}", header.clusterMask);
DicConsole.DebugWriteLine("SaveDskF plugin", "header.clusterShift = {0}", header.clusterShift); DicConsole.DebugWriteLine("SaveDskF plugin", "header.clusterShift = {0}", header.clusterShift);
DicConsole.DebugWriteLine("SaveDskF plugin", "header.reservedSectors = {0}", header.reservedSectors); DicConsole.DebugWriteLine("SaveDskF plugin", "header.reservedSectors = {0}", header.reservedSectors);
DicConsole.DebugWriteLine("SaveDskF plugin", "header.fatCopies = {0}", header.fatCopies); DicConsole.DebugWriteLine("SaveDskF plugin", "header.fatCopies = {0}", header.fatCopies);
DicConsole.DebugWriteLine("SaveDskF plugin", "header.rootEntries = {0}", header.rootEntries); DicConsole.DebugWriteLine("SaveDskF plugin", "header.rootEntries = {0}", header.rootEntries);
DicConsole.DebugWriteLine("SaveDskF plugin", "header.firstCluster = {0}", header.firstCluster); DicConsole.DebugWriteLine("SaveDskF plugin", "header.firstCluster = {0}", header.firstCluster);
DicConsole.DebugWriteLine("SaveDskF plugin", "header.clustersCopied = {0}", header.clustersCopied); DicConsole.DebugWriteLine("SaveDskF plugin", "header.clustersCopied = {0}", header.clustersCopied);
DicConsole.DebugWriteLine("SaveDskF plugin", "header.sectorsPerFat = {0}", header.sectorsPerFat); 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.checksum = 0x{0:X8}", header.checksum);
DicConsole.DebugWriteLine("SaveDskF plugin", "header.cylinders = {0}", header.cylinders); DicConsole.DebugWriteLine("SaveDskF plugin", "header.cylinders = {0}", header.cylinders);
DicConsole.DebugWriteLine("SaveDskF plugin", "header.heads = {0}", header.heads); DicConsole.DebugWriteLine("SaveDskF plugin", "header.heads = {0}", header.heads);
DicConsole.DebugWriteLine("SaveDskF plugin", "header.sectorsPerTrack = {0}", header.sectorsPerTrack); DicConsole.DebugWriteLine("SaveDskF plugin", "header.sectorsPerTrack = {0}", header.sectorsPerTrack);
DicConsole.DebugWriteLine("SaveDskF plugin", "header.padding = {0}", header.padding); DicConsole.DebugWriteLine("SaveDskF plugin", "header.padding = {0}", header.padding);
DicConsole.DebugWriteLine("SaveDskF plugin", "header.sectorsCopied = {0}", header.sectorsCopied); DicConsole.DebugWriteLine("SaveDskF plugin", "header.sectorsCopied = {0}", header.sectorsCopied);
DicConsole.DebugWriteLine("SaveDskF plugin", "header.commentOffset = {0}", header.commentOffset); DicConsole.DebugWriteLine("SaveDskF plugin", "header.commentOffset = {0}", header.commentOffset);
DicConsole.DebugWriteLine("SaveDskF plugin", "header.dataOffset = {0}", header.dataOffset); DicConsole.DebugWriteLine("SaveDskF plugin", "header.dataOffset = {0}", header.dataOffset);
if(header.dataOffset == 0 && header.magic == SDF_MAGIC_OLD) header.dataOffset = 512; if(header.dataOffset == 0 && header.magic == SDF_MAGIC_OLD) header.dataOffset = 512;
@@ -161,7 +161,7 @@ namespace DiscImageChef.DiscImages
int b; int b;
do do
{ {
b = stream.ReadByte(); b = stream.ReadByte();
if(b >= 0) calculatedChk += (uint)b; if(b >= 0) calculatedChk += (uint)b;
} }
while(b >= 0); while(b >= 0);
@@ -169,108 +169,17 @@ namespace DiscImageChef.DiscImages
DicConsole.DebugWriteLine("SaveDskF plugin", "Calculated checksum = 0x{0:X8}, {1}", calculatedChk, DicConsole.DebugWriteLine("SaveDskF plugin", "Calculated checksum = 0x{0:X8}, {1}", calculatedChk,
calculatedChk == header.checksum); calculatedChk == header.checksum);
imageInfo.Application = "SaveDskF"; imageInfo.Application = "SaveDskF";
imageInfo.CreationTime = imageFilter.GetCreationTime(); imageInfo.CreationTime = imageFilter.GetCreationTime();
imageInfo.LastModificationTime = imageFilter.GetLastWriteTime(); imageInfo.LastModificationTime = imageFilter.GetLastWriteTime();
imageInfo.MediaTitle = imageFilter.GetFilename(); imageInfo.MediaTitle = imageFilter.GetFilename();
imageInfo.ImageSize = (ulong)(stream.Length - header.dataOffset); imageInfo.ImageSize = (ulong)(stream.Length - header.dataOffset);
imageInfo.Sectors = (ulong)(header.sectorsPerTrack * header.heads * header.cylinders); imageInfo.Sectors = (ulong)(header.sectorsPerTrack * header.heads * header.cylinders);
imageInfo.SectorSize = header.sectorSize; imageInfo.SectorSize = header.sectorSize;
imageInfo.MediaType = MediaType.Unknown; imageInfo.MediaType =
switch(header.cylinders) Geometry.GetMediaType((header.cylinders, (byte)header.heads, header.sectorsPerTrack, header.sectorSize,
{ MediaEncoding.MFM, false));
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.XmlMediaType = XmlMediaType.BlockMedia; imageInfo.XmlMediaType = XmlMediaType.BlockMedia;
@@ -288,8 +197,8 @@ namespace DiscImageChef.DiscImages
decodedDisk = new byte[imageInfo.Sectors * imageInfo.SectorSize]; decodedDisk = new byte[imageInfo.Sectors * imageInfo.SectorSize];
stream.Read(decodedDisk, 0, (int)(stream.Length - header.dataOffset)); stream.Read(decodedDisk, 0, (int)(stream.Length - header.dataOffset));
imageInfo.Cylinders = header.cylinders; imageInfo.Cylinders = header.cylinders;
imageInfo.Heads = header.heads; imageInfo.Heads = header.heads;
imageInfo.SectorsPerTrack = header.sectorsPerTrack; imageInfo.SectorsPerTrack = header.sectorsPerTrack;
return true; return true;
@@ -306,7 +215,7 @@ namespace DiscImageChef.DiscImages
} }
public bool? VerifySectors(ulong sectorAddress, uint length, out List<ulong> failingLbas, public bool? VerifySectors(ulong sectorAddress, uint length, out List<ulong> failingLbas,
out List<ulong> unknownLbas) out List<ulong> unknownLbas)
{ {
failingLbas = new List<ulong>(); failingLbas = new List<ulong>();
unknownLbas = new List<ulong>(); unknownLbas = new List<ulong>();
@@ -317,7 +226,7 @@ namespace DiscImageChef.DiscImages
} }
public bool? VerifySectors(ulong sectorAddress, uint length, uint track, out List<ulong> failingLbas, public bool? VerifySectors(ulong sectorAddress, uint length, uint track, out List<ulong> failingLbas,
out List<ulong> unknownLbas) out List<ulong> unknownLbas)
{ {
failingLbas = new List<ulong>(); failingLbas = new List<ulong>();
unknownLbas = new List<ulong>(); unknownLbas = new List<ulong>();
@@ -348,7 +257,7 @@ namespace DiscImageChef.DiscImages
byte[] buffer = new byte[length * imageInfo.SectorSize]; byte[] buffer = new byte[length * imageInfo.SectorSize];
Array.Copy(decodedDisk, (int)sectorAddress * imageInfo.SectorSize, buffer, 0, Array.Copy(decodedDisk, (int)sectorAddress * imageInfo.SectorSize, buffer, 0,
length * imageInfo.SectorSize); length * imageInfo.SectorSize);
return buffer; return buffer;
} }

View File

@@ -41,41 +41,41 @@ namespace DiscImageChef.DiscImages
{ {
public class ZZZRawImage : IMediaImage public class ZZZRawImage : IMediaImage
{ {
bool differentTrackZeroSize; bool differentTrackZeroSize;
string extension; string extension;
ImageInfo imageInfo; ImageInfo imageInfo;
IFilter rawImageFilter; IFilter rawImageFilter;
public ZZZRawImage() public ZZZRawImage()
{ {
imageInfo = new ImageInfo imageInfo = new ImageInfo
{ {
ReadableSectorTags = new List<SectorTagType>(), ReadableSectorTags = new List<SectorTagType>(),
ReadableMediaTags = new List<MediaTagType>(), ReadableMediaTags = new List<MediaTagType>(),
HasPartitions = false, HasPartitions = false,
HasSessions = false, HasSessions = false,
Version = null, Version = null,
Application = null, Application = null,
ApplicationVersion = null, ApplicationVersion = null,
Creator = null, Creator = null,
Comments = null, Comments = null,
MediaManufacturer = null, MediaManufacturer = null,
MediaModel = null, MediaModel = null,
MediaSerialNumber = null, MediaSerialNumber = null,
MediaBarcode = null, MediaBarcode = null,
MediaPartNumber = null, MediaPartNumber = null,
MediaSequence = 0, MediaSequence = 0,
LastMediaSequence = 0, LastMediaSequence = 0,
DriveManufacturer = null, DriveManufacturer = null,
DriveModel = null, DriveModel = null,
DriveSerialNumber = null, DriveSerialNumber = null,
DriveFirmwareRevision = null DriveFirmwareRevision = null
}; };
} }
public string Name => "Raw Disk Image"; public string Name => "Raw Disk Image";
// Non-random UUID to recognize this specific plugin // 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 ImageInfo Info => imageInfo;
public string ImageFormat => "Raw disk image (sector by sector copy)"; public string ImageFormat => "Raw disk image (sector by sector copy)";
@@ -89,17 +89,17 @@ namespace DiscImageChef.DiscImages
Track trk = new Track Track trk = new Track
{ {
TrackBytesPerSector = (int)imageInfo.SectorSize, TrackBytesPerSector = (int)imageInfo.SectorSize,
TrackEndSector = imageInfo.Sectors - 1, TrackEndSector = imageInfo.Sectors - 1,
TrackFile = rawImageFilter.GetFilename(), TrackFile = rawImageFilter.GetFilename(),
TrackFileOffset = 0, TrackFileOffset = 0,
TrackFileType = "BINARY", TrackFileType = "BINARY",
TrackRawBytesPerSector = (int)imageInfo.SectorSize, TrackRawBytesPerSector = (int)imageInfo.SectorSize,
TrackSequence = 1, TrackSequence = 1,
TrackStartSector = 0, TrackStartSector = 0,
TrackSubchannelType = TrackSubchannelType.None, TrackSubchannelType = TrackSubchannelType.None,
TrackType = TrackType.Data, TrackType = TrackType.Data,
TrackSession = 1 TrackSession = 1
}; };
List<Track> lst = new List<Track> {trk}; List<Track> lst = new List<Track> {trk};
return lst; return lst;
@@ -115,11 +115,11 @@ namespace DiscImageChef.DiscImages
Session sess = new Session Session sess = new Session
{ {
EndSector = imageInfo.Sectors - 1, EndSector = imageInfo.Sectors - 1,
EndTrack = 1, EndTrack = 1,
SessionSequence = 1, SessionSequence = 1,
StartSector = 0, StartSector = 0,
StartTrack = 1 StartTrack = 1
}; };
List<Session> lst = new List<Session> {sess}; List<Session> lst = new List<Session> {sess};
return lst; return lst;
@@ -134,14 +134,14 @@ namespace DiscImageChef.DiscImages
throw new FeatureUnsupportedImageException("Feature not supported by image format"); throw new FeatureUnsupportedImageException("Feature not supported by image format");
List<Partition> parts = new List<Partition>(); List<Partition> parts = new List<Partition>();
Partition part = new Partition Partition part = new Partition
{ {
Start = 0, Start = 0,
Length = imageInfo.Sectors, Length = imageInfo.Sectors,
Offset = 0, Offset = 0,
Sequence = 0, Sequence = 0,
Type = "MODE1/2048", Type = "MODE1/2048",
Size = imageInfo.Sectors * imageInfo.SectorSize Size = imageInfo.Sectors * imageInfo.SectorSize
}; };
parts.Add(part); parts.Add(part);
return parts; return parts;
@@ -183,7 +183,7 @@ namespace DiscImageChef.DiscImages
case 1222400: case 1222400:
case 1304320: case 1304320:
case 1255168: return true; case 1255168: return true;
default: return false; default: return false;
} }
} }
@@ -202,10 +202,12 @@ namespace DiscImageChef.DiscImages
imageInfo.SectorSize = 256; imageInfo.SectorSize = 256;
break; break;
default: default:
if((extension == ".adf" || extension == ".adl" || extension == ".ssd" || extension == ".dsd") && if((extension == ".adf" || extension == ".adl" ||
(imageFilter.GetDataForkLength() == 163840 || imageFilter.GetDataForkLength() == 327680 || extension == ".ssd" || extension == ".dsd") &&
imageFilter.GetDataForkLength() == 655360)) imageInfo.SectorSize = 256; (imageFilter.GetDataForkLength() == 163840 || imageFilter.GetDataForkLength() == 327680 ||
else if((extension == ".adf" || extension == ".adl") && imageFilter.GetDataForkLength() == 819200) imageFilter.GetDataForkLength() == 655360)) imageInfo.SectorSize = 256;
else if((extension == ".adf" || extension == ".adl") &&
imageFilter.GetDataForkLength() == 819200)
imageInfo.SectorSize = 1024; imageInfo.SectorSize = 1024;
else else
switch(imageFilter.GetDataForkLength()) switch(imageFilter.GetDataForkLength())
@@ -218,9 +220,9 @@ namespace DiscImageChef.DiscImages
imageInfo.SectorSize = 128; imageInfo.SectorSize = 128;
break; break;
case 116480: case 116480:
case 287488: // T0S0 = 128bps case 287488: // T0S0 = 128bps
case 988416: // T0S0 = 128bps case 988416: // T0S0 = 128bps
case 995072: // T0S0 = 128bps, T0S1 = 256bps case 995072: // T0S0 = 128bps, T0S1 = 256bps
case 1021696: // T0S0 = 128bps, T0S1 = 256bps case 1021696: // T0S0 = 128bps, T0S1 = 256bps
case 232960: case 232960:
case 143360: case 143360:
@@ -229,7 +231,7 @@ namespace DiscImageChef.DiscImages
case 102400: case 102400:
case 204800: case 204800:
case 655360: case 655360:
case 80384: // T0S0 = 128bps case 80384: // T0S0 = 128bps
case 325632: // T0S0 = 128bps, T0S1 = 256bps case 325632: // T0S0 = 128bps, T0S1 = 256bps
case 653312: // T0S0 = 128bps, T0S1 = 256bps case 653312: // T0S0 = 128bps, T0S1 = 256bps
@@ -248,7 +250,7 @@ namespace DiscImageChef.DiscImages
case 81664: case 81664:
imageInfo.SectorSize = 319; imageInfo.SectorSize = 319;
break; break;
case 306432: // T0S0 = 128bps case 306432: // T0S0 = 128bps
case 1146624: // T0S0 = 128bps, T0S1 = 256bps case 1146624: // T0S0 = 128bps, T0S1 = 256bps
case 1177344: // T0S0 = 128bps, T0S1 = 256bps case 1177344: // T0S0 = 128bps, T0S1 = 256bps
imageInfo.SectorSize = 512; imageInfo.SectorSize = 512;
@@ -268,12 +270,12 @@ namespace DiscImageChef.DiscImages
break; break;
} }
imageInfo.ImageSize = (ulong)imageFilter.GetDataForkLength(); imageInfo.ImageSize = (ulong)imageFilter.GetDataForkLength();
imageInfo.CreationTime = imageFilter.GetCreationTime(); imageInfo.CreationTime = imageFilter.GetCreationTime();
imageInfo.LastModificationTime = imageFilter.GetLastWriteTime(); imageInfo.LastModificationTime = imageFilter.GetLastWriteTime();
imageInfo.MediaTitle = Path.GetFileNameWithoutExtension(imageFilter.GetFilename()); imageInfo.MediaTitle = Path.GetFileNameWithoutExtension(imageFilter.GetFilename());
differentTrackZeroSize = false; differentTrackZeroSize = false;
rawImageFilter = imageFilter; rawImageFilter = imageFilter;
switch(imageFilter.GetDataForkLength()) switch(imageFilter.GetDataForkLength())
{ {
@@ -290,63 +292,63 @@ namespace DiscImageChef.DiscImages
imageInfo.Sectors = 455; imageInfo.Sectors = 455;
break; break;
case 287488: // T0S0 = 128bps case 287488: // T0S0 = 128bps
imageInfo.Sectors = 1136; imageInfo.Sectors = 1136;
differentTrackZeroSize = true; differentTrackZeroSize = true;
break; break;
case 988416: // T0S0 = 128bps case 988416: // T0S0 = 128bps
imageInfo.Sectors = 3874; imageInfo.Sectors = 3874;
differentTrackZeroSize = true; differentTrackZeroSize = true;
break; break;
case 995072: // T0S0 = 128bps, T0S1 = 256bps case 995072: // T0S0 = 128bps, T0S1 = 256bps
imageInfo.Sectors = 3900; imageInfo.Sectors = 3900;
differentTrackZeroSize = true; differentTrackZeroSize = true;
break; break;
case 1021696: // T0S0 = 128bps, T0S1 = 256bps case 1021696: // T0S0 = 128bps, T0S1 = 256bps
imageInfo.Sectors = 4004; imageInfo.Sectors = 4004;
differentTrackZeroSize = true; differentTrackZeroSize = true;
break; break;
case 81664: case 81664:
imageInfo.Sectors = 256; imageInfo.Sectors = 256;
break; break;
case 306432: // T0S0 = 128bps case 306432: // T0S0 = 128bps
imageInfo.Sectors = 618; imageInfo.Sectors = 618;
differentTrackZeroSize = true; differentTrackZeroSize = true;
break; break;
case 1146624: // T0S0 = 128bps, T0S1 = 256bps case 1146624: // T0S0 = 128bps, T0S1 = 256bps
imageInfo.Sectors = 2272; imageInfo.Sectors = 2272;
differentTrackZeroSize = true; differentTrackZeroSize = true;
break; break;
case 1177344: // T0S0 = 128bps, T0S1 = 256bps case 1177344: // T0S0 = 128bps, T0S1 = 256bps
imageInfo.Sectors = 2332; imageInfo.Sectors = 2332;
differentTrackZeroSize = true; differentTrackZeroSize = true;
break; break;
case 1222400: // T0S0 = 128bps, T0S1 = 256bps case 1222400: // T0S0 = 128bps, T0S1 = 256bps
imageInfo.Sectors = 1236; imageInfo.Sectors = 1236;
differentTrackZeroSize = true; differentTrackZeroSize = true;
break; break;
case 1304320: // T0S0 = 128bps, T0S1 = 256bps case 1304320: // T0S0 = 128bps, T0S1 = 256bps
imageInfo.Sectors = 1316; imageInfo.Sectors = 1316;
differentTrackZeroSize = true; differentTrackZeroSize = true;
break; break;
case 1255168: // T0S0 = 128bps, T0S1 = 256bps case 1255168: // T0S0 = 128bps, T0S1 = 256bps
imageInfo.Sectors = 1268; imageInfo.Sectors = 1268;
differentTrackZeroSize = true; differentTrackZeroSize = true;
break; break;
case 80384: // T0S0 = 128bps case 80384: // T0S0 = 128bps
imageInfo.Sectors = 322; imageInfo.Sectors = 322;
differentTrackZeroSize = true; differentTrackZeroSize = true;
break; break;
case 325632: // T0S0 = 128bps, T0S1 = 256bps case 325632: // T0S0 = 128bps, T0S1 = 256bps
imageInfo.Sectors = 1280; imageInfo.Sectors = 1280;
differentTrackZeroSize = true; differentTrackZeroSize = true;
break; break;
case 653312: // T0S0 = 128bps, T0S1 = 256bps case 653312: // T0S0 = 128bps, T0S1 = 256bps
imageInfo.Sectors = 2560; imageInfo.Sectors = 2560;
differentTrackZeroSize = true; differentTrackZeroSize = true;
break; break;
case 1880064: // IBM XDF, 3,5", real number of sectors case 1880064: // IBM XDF, 3,5", real number of sectors
imageInfo.Sectors = 670; imageInfo.Sectors = 670;
imageInfo.SectorSize = 8192; // Biggest sector size imageInfo.SectorSize = 8192; // Biggest sector size
differentTrackZeroSize = true; differentTrackZeroSize = true;
break; break;
case 175531: case 175531:
@@ -385,17 +387,17 @@ namespace DiscImageChef.DiscImages
} }
// Sharp X68000 SASI hard disks // Sharp X68000 SASI hard disks
if(extension == ".hdf") if(extension == ".hdf")
if(imageInfo.ImageSize % 256 == 0) if(imageInfo.ImageSize % 256 == 0)
{ {
imageInfo.SectorSize = 256; imageInfo.SectorSize = 256;
imageInfo.Sectors = imageInfo.ImageSize / imageInfo.SectorSize; imageInfo.Sectors = imageInfo.ImageSize / imageInfo.SectorSize;
imageInfo.MediaType = MediaType.GENERIC_HDD; imageInfo.MediaType = MediaType.GENERIC_HDD;
} }
if(imageInfo.XmlMediaType == XmlMediaType.OpticalDisc) if(imageInfo.XmlMediaType == XmlMediaType.OpticalDisc)
{ {
imageInfo.HasSessions = true; imageInfo.HasSessions = true;
imageInfo.HasPartitions = true; imageInfo.HasPartitions = true;
} }
@@ -404,319 +406,319 @@ namespace DiscImageChef.DiscImages
switch(imageInfo.MediaType) switch(imageInfo.MediaType)
{ {
case MediaType.ACORN_35_DS_DD: case MediaType.ACORN_35_DS_DD:
imageInfo.Cylinders = 80; imageInfo.Cylinders = 80;
imageInfo.Heads = 2; imageInfo.Heads = 2;
imageInfo.SectorsPerTrack = 5; imageInfo.SectorsPerTrack = 5;
break; break;
case MediaType.ACORN_35_DS_HD: case MediaType.ACORN_35_DS_HD:
imageInfo.Cylinders = 80; imageInfo.Cylinders = 80;
imageInfo.Heads = 2; imageInfo.Heads = 2;
imageInfo.SectorsPerTrack = 10; imageInfo.SectorsPerTrack = 10;
break; break;
case MediaType.ACORN_525_DS_DD: case MediaType.ACORN_525_DS_DD:
imageInfo.Cylinders = 80; imageInfo.Cylinders = 80;
imageInfo.Heads = 2; imageInfo.Heads = 2;
imageInfo.SectorsPerTrack = 16; imageInfo.SectorsPerTrack = 16;
break; break;
case MediaType.ACORN_525_SS_DD_40: case MediaType.ACORN_525_SS_DD_40:
imageInfo.Cylinders = 40; imageInfo.Cylinders = 40;
imageInfo.Heads = 1; imageInfo.Heads = 1;
imageInfo.SectorsPerTrack = 16; imageInfo.SectorsPerTrack = 16;
break; break;
case MediaType.ACORN_525_SS_DD_80: case MediaType.ACORN_525_SS_DD_80:
imageInfo.Cylinders = 80; imageInfo.Cylinders = 80;
imageInfo.Heads = 1; imageInfo.Heads = 1;
imageInfo.SectorsPerTrack = 16; imageInfo.SectorsPerTrack = 16;
break; break;
case MediaType.ACORN_525_SS_SD_40: case MediaType.ACORN_525_SS_SD_40:
imageInfo.Cylinders = 40; imageInfo.Cylinders = 40;
imageInfo.Heads = 1; imageInfo.Heads = 1;
imageInfo.SectorsPerTrack = 10; imageInfo.SectorsPerTrack = 10;
break; break;
case MediaType.ACORN_525_SS_SD_80: case MediaType.ACORN_525_SS_SD_80:
imageInfo.Cylinders = 80; imageInfo.Cylinders = 80;
imageInfo.Heads = 1; imageInfo.Heads = 1;
imageInfo.SectorsPerTrack = 10; imageInfo.SectorsPerTrack = 10;
break; break;
case MediaType.Apple32DS: case MediaType.Apple32DS:
imageInfo.Cylinders = 35; imageInfo.Cylinders = 35;
imageInfo.Heads = 2; imageInfo.Heads = 2;
imageInfo.SectorsPerTrack = 13; imageInfo.SectorsPerTrack = 13;
break; break;
case MediaType.Apple32SS: case MediaType.Apple32SS:
imageInfo.Cylinders = 36; imageInfo.Cylinders = 36;
imageInfo.Heads = 1; imageInfo.Heads = 1;
imageInfo.SectorsPerTrack = 13; imageInfo.SectorsPerTrack = 13;
break; break;
case MediaType.Apple33DS: case MediaType.Apple33DS:
imageInfo.Cylinders = 35; imageInfo.Cylinders = 35;
imageInfo.Heads = 2; imageInfo.Heads = 2;
imageInfo.SectorsPerTrack = 16; imageInfo.SectorsPerTrack = 16;
break; break;
case MediaType.Apple33SS: case MediaType.Apple33SS:
imageInfo.Cylinders = 35; imageInfo.Cylinders = 35;
imageInfo.Heads = 2; imageInfo.Heads = 2;
imageInfo.SectorsPerTrack = 16; imageInfo.SectorsPerTrack = 16;
break; break;
case MediaType.AppleSonyDS: case MediaType.AppleSonyDS:
imageInfo.Cylinders = 80; imageInfo.Cylinders = 80;
imageInfo.Heads = 2; imageInfo.Heads = 2;
imageInfo.SectorsPerTrack = 10; imageInfo.SectorsPerTrack = 10;
break; break;
case MediaType.AppleSonySS: case MediaType.AppleSonySS:
imageInfo.Cylinders = 80; imageInfo.Cylinders = 80;
imageInfo.Heads = 1; imageInfo.Heads = 1;
imageInfo.SectorsPerTrack = 10; imageInfo.SectorsPerTrack = 10;
break; break;
case MediaType.ATARI_35_DS_DD: case MediaType.ATARI_35_DS_DD:
imageInfo.Cylinders = 80; imageInfo.Cylinders = 80;
imageInfo.Heads = 2; imageInfo.Heads = 2;
imageInfo.SectorsPerTrack = 10; imageInfo.SectorsPerTrack = 10;
break; break;
case MediaType.ATARI_35_DS_DD_11: case MediaType.ATARI_35_DS_DD_11:
imageInfo.Cylinders = 80; imageInfo.Cylinders = 80;
imageInfo.Heads = 2; imageInfo.Heads = 2;
imageInfo.SectorsPerTrack = 11; imageInfo.SectorsPerTrack = 11;
break; break;
case MediaType.ATARI_35_SS_DD: case MediaType.ATARI_35_SS_DD:
imageInfo.Cylinders = 80; imageInfo.Cylinders = 80;
imageInfo.Heads = 1; imageInfo.Heads = 1;
imageInfo.SectorsPerTrack = 10; imageInfo.SectorsPerTrack = 10;
break; break;
case MediaType.ATARI_35_SS_DD_11: case MediaType.ATARI_35_SS_DD_11:
imageInfo.Cylinders = 80; imageInfo.Cylinders = 80;
imageInfo.Heads = 1; imageInfo.Heads = 1;
imageInfo.SectorsPerTrack = 11; imageInfo.SectorsPerTrack = 11;
break; break;
case MediaType.ATARI_525_ED: case MediaType.ATARI_525_ED:
imageInfo.Cylinders = 40; imageInfo.Cylinders = 40;
imageInfo.Heads = 1; imageInfo.Heads = 1;
imageInfo.SectorsPerTrack = 26; imageInfo.SectorsPerTrack = 26;
break; break;
case MediaType.ATARI_525_SD: case MediaType.ATARI_525_SD:
imageInfo.Cylinders = 40; imageInfo.Cylinders = 40;
imageInfo.Heads = 1; imageInfo.Heads = 1;
imageInfo.SectorsPerTrack = 18; imageInfo.SectorsPerTrack = 18;
break; break;
case MediaType.CBM_35_DD: case MediaType.CBM_35_DD:
imageInfo.Cylinders = 80; imageInfo.Cylinders = 80;
imageInfo.Heads = 2; imageInfo.Heads = 2;
imageInfo.SectorsPerTrack = 10; imageInfo.SectorsPerTrack = 10;
break; break;
case MediaType.CBM_AMIGA_35_DD: case MediaType.CBM_AMIGA_35_DD:
imageInfo.Cylinders = 80; imageInfo.Cylinders = 80;
imageInfo.Heads = 2; imageInfo.Heads = 2;
imageInfo.SectorsPerTrack = 11; imageInfo.SectorsPerTrack = 11;
break; break;
case MediaType.CBM_AMIGA_35_HD: case MediaType.CBM_AMIGA_35_HD:
imageInfo.Cylinders = 80; imageInfo.Cylinders = 80;
imageInfo.Heads = 2; imageInfo.Heads = 2;
imageInfo.SectorsPerTrack = 22; imageInfo.SectorsPerTrack = 22;
break; break;
case MediaType.DMF: case MediaType.DMF:
imageInfo.Cylinders = 80; imageInfo.Cylinders = 80;
imageInfo.Heads = 2; imageInfo.Heads = 2;
imageInfo.SectorsPerTrack = 21; imageInfo.SectorsPerTrack = 21;
break; break;
case MediaType.DOS_35_DS_DD_9: case MediaType.DOS_35_DS_DD_9:
imageInfo.Cylinders = 80; imageInfo.Cylinders = 80;
imageInfo.Heads = 2; imageInfo.Heads = 2;
imageInfo.SectorsPerTrack = 9; imageInfo.SectorsPerTrack = 9;
break; break;
case MediaType.Apricot_35: case MediaType.Apricot_35:
imageInfo.Cylinders = 70; imageInfo.Cylinders = 70;
imageInfo.Heads = 1; imageInfo.Heads = 2;
imageInfo.SectorsPerTrack = 9; imageInfo.SectorsPerTrack = 9;
break; break;
case MediaType.DOS_35_ED: case MediaType.DOS_35_ED:
imageInfo.Cylinders = 80; imageInfo.Cylinders = 80;
imageInfo.Heads = 2; imageInfo.Heads = 2;
imageInfo.SectorsPerTrack = 36; imageInfo.SectorsPerTrack = 36;
break; break;
case MediaType.DOS_35_HD: case MediaType.DOS_35_HD:
imageInfo.Cylinders = 80; imageInfo.Cylinders = 80;
imageInfo.Heads = 2; imageInfo.Heads = 2;
imageInfo.SectorsPerTrack = 18; imageInfo.SectorsPerTrack = 18;
break; break;
case MediaType.DOS_35_SS_DD_9: case MediaType.DOS_35_SS_DD_9:
imageInfo.Cylinders = 80; imageInfo.Cylinders = 80;
imageInfo.Heads = 1; imageInfo.Heads = 1;
imageInfo.SectorsPerTrack = 9; imageInfo.SectorsPerTrack = 9;
break; break;
case MediaType.DOS_525_DS_DD_8: case MediaType.DOS_525_DS_DD_8:
imageInfo.Cylinders = 40; imageInfo.Cylinders = 40;
imageInfo.Heads = 2; imageInfo.Heads = 2;
imageInfo.SectorsPerTrack = 8; imageInfo.SectorsPerTrack = 8;
break; break;
case MediaType.DOS_525_DS_DD_9: case MediaType.DOS_525_DS_DD_9:
imageInfo.Cylinders = 40; imageInfo.Cylinders = 40;
imageInfo.Heads = 2; imageInfo.Heads = 2;
imageInfo.SectorsPerTrack = 9; imageInfo.SectorsPerTrack = 9;
break; break;
case MediaType.DOS_525_HD: case MediaType.DOS_525_HD:
imageInfo.Cylinders = 80; imageInfo.Cylinders = 80;
imageInfo.Heads = 2; imageInfo.Heads = 2;
imageInfo.SectorsPerTrack = 15; imageInfo.SectorsPerTrack = 15;
break; break;
case MediaType.DOS_525_SS_DD_8: case MediaType.DOS_525_SS_DD_8:
imageInfo.Cylinders = 40; imageInfo.Cylinders = 40;
imageInfo.Heads = 1; imageInfo.Heads = 1;
imageInfo.SectorsPerTrack = 8; imageInfo.SectorsPerTrack = 8;
break; break;
case MediaType.DOS_525_SS_DD_9: case MediaType.DOS_525_SS_DD_9:
imageInfo.Cylinders = 40; imageInfo.Cylinders = 40;
imageInfo.Heads = 1; imageInfo.Heads = 1;
imageInfo.SectorsPerTrack = 9; imageInfo.SectorsPerTrack = 9;
break; break;
case MediaType.ECMA_54: case MediaType.ECMA_54:
imageInfo.Cylinders = 77; imageInfo.Cylinders = 77;
imageInfo.Heads = 1; imageInfo.Heads = 1;
imageInfo.SectorsPerTrack = 26; imageInfo.SectorsPerTrack = 26;
break; break;
case MediaType.ECMA_59: case MediaType.ECMA_59:
imageInfo.Cylinders = 77; imageInfo.Cylinders = 77;
imageInfo.Heads = 2; imageInfo.Heads = 2;
imageInfo.SectorsPerTrack = 26; imageInfo.SectorsPerTrack = 26;
break; break;
case MediaType.ECMA_66: case MediaType.ECMA_66:
imageInfo.Cylinders = 35; imageInfo.Cylinders = 35;
imageInfo.Heads = 1; imageInfo.Heads = 1;
imageInfo.SectorsPerTrack = 9; imageInfo.SectorsPerTrack = 9;
break; break;
case MediaType.ECMA_69_8: case MediaType.ECMA_69_8:
imageInfo.Cylinders = 77; imageInfo.Cylinders = 77;
imageInfo.Heads = 2; imageInfo.Heads = 2;
imageInfo.SectorsPerTrack = 8; imageInfo.SectorsPerTrack = 8;
break; break;
case MediaType.ECMA_70: case MediaType.ECMA_70:
imageInfo.Cylinders = 40; imageInfo.Cylinders = 40;
imageInfo.Heads = 2; imageInfo.Heads = 2;
imageInfo.SectorsPerTrack = 16; imageInfo.SectorsPerTrack = 16;
break; break;
case MediaType.ECMA_78: case MediaType.ECMA_78:
imageInfo.Cylinders = 80; imageInfo.Cylinders = 80;
imageInfo.Heads = 2; imageInfo.Heads = 2;
imageInfo.SectorsPerTrack = 16; imageInfo.SectorsPerTrack = 16;
break; break;
case MediaType.ECMA_99_15: case MediaType.ECMA_99_15:
imageInfo.Cylinders = 77; imageInfo.Cylinders = 77;
imageInfo.Heads = 2; imageInfo.Heads = 2;
imageInfo.SectorsPerTrack = 15; imageInfo.SectorsPerTrack = 15;
break; break;
case MediaType.ECMA_99_26: case MediaType.ECMA_99_26:
imageInfo.Cylinders = 77; imageInfo.Cylinders = 77;
imageInfo.Heads = 2; imageInfo.Heads = 2;
imageInfo.SectorsPerTrack = 26; imageInfo.SectorsPerTrack = 26;
break; break;
case MediaType.ECMA_99_8: case MediaType.ECMA_99_8:
imageInfo.Cylinders = 80; imageInfo.Cylinders = 80;
imageInfo.Heads = 2; imageInfo.Heads = 2;
imageInfo.SectorsPerTrack = 8; imageInfo.SectorsPerTrack = 8;
break; break;
case MediaType.FDFORMAT_35_DD: case MediaType.FDFORMAT_35_DD:
imageInfo.Cylinders = 82; imageInfo.Cylinders = 82;
imageInfo.Heads = 2; imageInfo.Heads = 2;
imageInfo.SectorsPerTrack = 10; imageInfo.SectorsPerTrack = 10;
break; break;
case MediaType.FDFORMAT_35_HD: case MediaType.FDFORMAT_35_HD:
imageInfo.Cylinders = 82; imageInfo.Cylinders = 82;
imageInfo.Heads = 2; imageInfo.Heads = 2;
imageInfo.SectorsPerTrack = 21; imageInfo.SectorsPerTrack = 21;
break; break;
case MediaType.FDFORMAT_525_HD: case MediaType.FDFORMAT_525_HD:
imageInfo.Cylinders = 82; imageInfo.Cylinders = 82;
imageInfo.Heads = 2; imageInfo.Heads = 2;
imageInfo.SectorsPerTrack = 17; imageInfo.SectorsPerTrack = 17;
break; break;
case MediaType.IBM23FD: case MediaType.IBM23FD:
imageInfo.Cylinders = 32; imageInfo.Cylinders = 32;
imageInfo.Heads = 1; imageInfo.Heads = 1;
imageInfo.SectorsPerTrack = 8; imageInfo.SectorsPerTrack = 8;
break; break;
case MediaType.IBM33FD_128: case MediaType.IBM33FD_128:
imageInfo.Cylinders = 73; imageInfo.Cylinders = 73;
imageInfo.Heads = 1; imageInfo.Heads = 1;
imageInfo.SectorsPerTrack = 26; imageInfo.SectorsPerTrack = 26;
break; break;
case MediaType.IBM33FD_256: case MediaType.IBM33FD_256:
imageInfo.Cylinders = 74; imageInfo.Cylinders = 74;
imageInfo.Heads = 1; imageInfo.Heads = 1;
imageInfo.SectorsPerTrack = 15; imageInfo.SectorsPerTrack = 15;
break; break;
case MediaType.IBM33FD_512: case MediaType.IBM33FD_512:
imageInfo.Cylinders = 74; imageInfo.Cylinders = 74;
imageInfo.Heads = 1; imageInfo.Heads = 1;
imageInfo.SectorsPerTrack = 8; imageInfo.SectorsPerTrack = 8;
break; break;
case MediaType.IBM43FD_128: case MediaType.IBM43FD_128:
imageInfo.Cylinders = 74; imageInfo.Cylinders = 74;
imageInfo.Heads = 2; imageInfo.Heads = 2;
imageInfo.SectorsPerTrack = 26; imageInfo.SectorsPerTrack = 26;
break; break;
case MediaType.IBM43FD_256: case MediaType.IBM43FD_256:
imageInfo.Cylinders = 74; imageInfo.Cylinders = 74;
imageInfo.Heads = 2; imageInfo.Heads = 2;
imageInfo.SectorsPerTrack = 15; imageInfo.SectorsPerTrack = 15;
break; break;
case MediaType.IBM53FD_1024: case MediaType.IBM53FD_1024:
imageInfo.Cylinders = 74; imageInfo.Cylinders = 74;
imageInfo.Heads = 2; imageInfo.Heads = 2;
imageInfo.SectorsPerTrack = 8; imageInfo.SectorsPerTrack = 8;
break; break;
case MediaType.IBM53FD_256: case MediaType.IBM53FD_256:
imageInfo.Cylinders = 74; imageInfo.Cylinders = 74;
imageInfo.Heads = 2; imageInfo.Heads = 2;
imageInfo.SectorsPerTrack = 26; imageInfo.SectorsPerTrack = 26;
break; break;
case MediaType.IBM53FD_512: case MediaType.IBM53FD_512:
imageInfo.Cylinders = 74; imageInfo.Cylinders = 74;
imageInfo.Heads = 2; imageInfo.Heads = 2;
imageInfo.SectorsPerTrack = 15; imageInfo.SectorsPerTrack = 15;
break; break;
case MediaType.NEC_35_TD: case MediaType.NEC_35_TD:
imageInfo.Cylinders = 240; imageInfo.Cylinders = 240;
imageInfo.Heads = 2; imageInfo.Heads = 2;
imageInfo.SectorsPerTrack = 38; imageInfo.SectorsPerTrack = 38;
break; break;
case MediaType.NEC_525_HD: case MediaType.NEC_525_HD:
imageInfo.Cylinders = 77; imageInfo.Cylinders = 77;
imageInfo.Heads = 2; imageInfo.Heads = 2;
imageInfo.SectorsPerTrack = 8; imageInfo.SectorsPerTrack = 8;
break; break;
case MediaType.XDF_35: case MediaType.XDF_35:
imageInfo.Cylinders = 80; imageInfo.Cylinders = 80;
imageInfo.Heads = 2; imageInfo.Heads = 2;
imageInfo.SectorsPerTrack = 23; imageInfo.SectorsPerTrack = 23;
break; break;
// Following ones are what the device itself report, not the physical geometry // Following ones are what the device itself report, not the physical geometry
case MediaType.Jaz: case MediaType.Jaz:
imageInfo.Cylinders = 1021; imageInfo.Cylinders = 1021;
imageInfo.Heads = 64; imageInfo.Heads = 64;
imageInfo.SectorsPerTrack = 32; imageInfo.SectorsPerTrack = 32;
break; break;
case MediaType.PocketZip: case MediaType.PocketZip:
imageInfo.Cylinders = 154; imageInfo.Cylinders = 154;
imageInfo.Heads = 16; imageInfo.Heads = 16;
imageInfo.SectorsPerTrack = 32; imageInfo.SectorsPerTrack = 32;
break; break;
case MediaType.LS120: case MediaType.LS120:
imageInfo.Cylinders = 963; imageInfo.Cylinders = 963;
imageInfo.Heads = 8; imageInfo.Heads = 8;
imageInfo.SectorsPerTrack = 32; imageInfo.SectorsPerTrack = 32;
break; break;
case MediaType.LS240: case MediaType.LS240:
imageInfo.Cylinders = 262; imageInfo.Cylinders = 262;
imageInfo.Heads = 32; imageInfo.Heads = 32;
imageInfo.SectorsPerTrack = 56; imageInfo.SectorsPerTrack = 56;
break; break;
case MediaType.FD32MB: case MediaType.FD32MB:
imageInfo.Cylinders = 1024; imageInfo.Cylinders = 1024;
imageInfo.Heads = 2; imageInfo.Heads = 2;
imageInfo.SectorsPerTrack = 32; imageInfo.SectorsPerTrack = 32;
break; break;
default: default:
imageInfo.Cylinders = (uint)(imageInfo.Sectors / 16 / 63); imageInfo.Cylinders = (uint)(imageInfo.Sectors / 16 / 63);
imageInfo.Heads = 16; imageInfo.Heads = 16;
imageInfo.SectorsPerTrack = 63; imageInfo.SectorsPerTrack = 63;
break; break;
} }
@@ -761,7 +763,7 @@ namespace DiscImageChef.DiscImages
} }
public bool? VerifySectors(ulong sectorAddress, uint length, out List<ulong> failingLbas, public bool? VerifySectors(ulong sectorAddress, uint length, out List<ulong> failingLbas,
out List<ulong> unknownLbas) out List<ulong> unknownLbas)
{ {
failingLbas = new List<ulong>(); failingLbas = new List<ulong>();
unknownLbas = new List<ulong>(); unknownLbas = new List<ulong>();
@@ -772,7 +774,7 @@ namespace DiscImageChef.DiscImages
} }
public bool? VerifySectors(ulong sectorAddress, uint length, uint track, out List<ulong> failingLbas, public bool? VerifySectors(ulong sectorAddress, uint length, uint track, out List<ulong> failingLbas,
out List<ulong> unknownLbas) out List<ulong> unknownLbas)
{ {
failingLbas = new List<ulong>(); failingLbas = new List<ulong>();
unknownLbas = new List<ulong>(); unknownLbas = new List<ulong>();
@@ -797,18 +799,18 @@ namespace DiscImageChef.DiscImages
Track trk = new Track Track trk = new Track
{ {
TrackBytesPerSector = (int)imageInfo.SectorSize, TrackBytesPerSector = (int)imageInfo.SectorSize,
TrackEndSector = imageInfo.Sectors - 1, TrackEndSector = imageInfo.Sectors - 1,
TrackFilter = rawImageFilter, TrackFilter = rawImageFilter,
TrackFile = rawImageFilter.GetFilename(), TrackFile = rawImageFilter.GetFilename(),
TrackFileOffset = 0, TrackFileOffset = 0,
TrackFileType = "BINARY", TrackFileType = "BINARY",
TrackRawBytesPerSector = (int)imageInfo.SectorSize, TrackRawBytesPerSector = (int)imageInfo.SectorSize,
TrackSequence = 1, TrackSequence = 1,
TrackStartSector = 0, TrackStartSector = 0,
TrackSubchannelType = TrackSubchannelType.None, TrackSubchannelType = TrackSubchannelType.None,
TrackType = TrackType.Data, TrackType = TrackType.Data,
TrackSession = 1 TrackSession = 1
}; };
List<Track> lst = new List<Track> {trk}; List<Track> lst = new List<Track> {trk};
return lst; return lst;
@@ -824,18 +826,18 @@ namespace DiscImageChef.DiscImages
Track trk = new Track Track trk = new Track
{ {
TrackBytesPerSector = (int)imageInfo.SectorSize, TrackBytesPerSector = (int)imageInfo.SectorSize,
TrackEndSector = imageInfo.Sectors - 1, TrackEndSector = imageInfo.Sectors - 1,
TrackFilter = rawImageFilter, TrackFilter = rawImageFilter,
TrackFile = rawImageFilter.GetFilename(), TrackFile = rawImageFilter.GetFilename(),
TrackFileOffset = 0, TrackFileOffset = 0,
TrackFileType = "BINARY", TrackFileType = "BINARY",
TrackRawBytesPerSector = (int)imageInfo.SectorSize, TrackRawBytesPerSector = (int)imageInfo.SectorSize,
TrackSequence = 1, TrackSequence = 1,
TrackStartSector = 0, TrackStartSector = 0,
TrackSubchannelType = TrackSubchannelType.None, TrackSubchannelType = TrackSubchannelType.None,
TrackType = TrackType.Data, TrackType = TrackType.Data,
TrackSession = 1 TrackSession = 1
}; };
List<Track> lst = new List<Track> {trk}; List<Track> lst = new List<Track> {trk};
return lst; return lst;
@@ -881,6 +883,41 @@ namespace DiscImageChef.DiscImages
return ReadSectors(sectorAddress, length); 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() MediaType CalculateDiskType()
{ {
if(imageInfo.SectorSize == 2048) if(imageInfo.SectorSize == 2048)
@@ -897,9 +934,9 @@ namespace DiscImageChef.DiscImages
switch(imageInfo.ImageSize) switch(imageInfo.ImageSize)
{ {
case 80384: return MediaType.ECMA_66; case 80384: return MediaType.ECMA_66;
case 81664: return MediaType.IBM23FD; case 81664: return MediaType.IBM23FD;
case 92160: return MediaType.ATARI_525_SD; case 92160: return MediaType.ATARI_525_SD;
case 102400: return MediaType.ACORN_525_SS_SD_40; case 102400: return MediaType.ACORN_525_SS_SD_40;
case 116480: return MediaType.Apple32SS; case 116480: return MediaType.Apple32SS;
case 133120: return MediaType.ATARI_525_ED; case 133120: return MediaType.ATARI_525_ED;
@@ -938,7 +975,7 @@ namespace DiscImageChef.DiscImages
case 737280: return MediaType.DOS_35_DS_DD_9; case 737280: return MediaType.DOS_35_DS_DD_9;
case 819200: case 819200:
if(imageInfo.SectorSize == 256) return MediaType.CBM_35_DD; 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; return MediaType.ACORN_35_DS_DD;
if(extension == ".st") return MediaType.ATARI_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; if(extension == ".st") return MediaType.ATARI_35_DS_DD_11;
return MediaType.CBM_AMIGA_35_DD; return MediaType.CBM_AMIGA_35_DD;
case 988416: return MediaType.IBM43FD_256; case 988416: return MediaType.IBM43FD_256;
case 995072: return MediaType.IBM53FD_256; case 995072: return MediaType.IBM53FD_256;
case 1021696: return MediaType.ECMA_99_26; case 1021696: return MediaType.ECMA_99_26;
case 1146624: return MediaType.IBM53FD_512; case 1146624: return MediaType.IBM53FD_512;
case 1177344: return MediaType.ECMA_99_15; case 1177344: return MediaType.ECMA_99_15;
case 1222400: return MediaType.IBM53FD_1024; case 1222400: return MediaType.IBM53FD_1024;
case 1228800: return MediaType.DOS_525_HD; case 1228800: return MediaType.DOS_525_HD;
case 1255168: return MediaType.ECMA_69_8; case 1255168: return MediaType.ECMA_69_8;
case 1261568: return MediaType.NEC_525_HD; case 1261568: return MediaType.NEC_525_HD;
case 1304320: return MediaType.ECMA_99_8; case 1304320: return MediaType.ECMA_99_8;
case 1427456: return MediaType.FDFORMAT_525_HD; case 1427456: return MediaType.FDFORMAT_525_HD;
case 1474560: return MediaType.DOS_35_HD; case 1474560: return MediaType.DOS_35_HD;
case 1638400: return MediaType.ACORN_35_DS_HD; case 1638400: return MediaType.ACORN_35_DS_HD;
case 1720320: return MediaType.DMF; case 1720320: return MediaType.DMF;
case 1763328: return MediaType.FDFORMAT_35_HD; case 1763328: return MediaType.FDFORMAT_35_HD;
case 1802240: return MediaType.CBM_AMIGA_35_HD; case 1802240: return MediaType.CBM_AMIGA_35_HD;
case 1880064: return MediaType.XDF_35; case 1880064: return MediaType.XDF_35;
case 1884160: return MediaType.XDF_35; case 1884160: return MediaType.XDF_35;
case 2949120: return MediaType.DOS_35_ED; case 2949120: return MediaType.DOS_35_ED;
case 9338880: return MediaType.NEC_35_TD; case 9338880: return MediaType.NEC_35_TD;
case 33554432: return MediaType.FD32MB; case 33554432: return MediaType.FD32MB;
case 40387584: return MediaType.PocketZip; case 40387584: return MediaType.PocketZip;
case 126222336: return MediaType.LS120; case 126222336: return MediaType.LS120;
case 127923200: return MediaType.ECMA_154; case 127923200: return MediaType.ECMA_154;
case 201410560: return MediaType.HiFD; case 201410560: return MediaType.HiFD;
case 229632000: return MediaType.ECMA_201; case 229632000: return MediaType.ECMA_201;
case 240386048: return MediaType.LS240; case 240386048: return MediaType.LS240;
case 481520640: return MediaType.ECMA_183_512; case 481520640: return MediaType.ECMA_183_512;
case 533403648: return MediaType.ECMA_183; case 533403648: return MediaType.ECMA_183;
case 596787200: return MediaType.ECMA_184_512; case 596787200: return MediaType.ECMA_184_512;
case 654540800: return MediaType.ECMA_184; case 654540800: return MediaType.ECMA_184;
case 1070617600: return MediaType.Jaz; case 1070617600: return MediaType.Jaz;
#region Commodore #region Commodore
@@ -993,40 +1030,5 @@ namespace DiscImageChef.DiscImages
default: return MediaType.GENERIC_HDD; 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");
}
} }
} }

View File

@@ -51,8 +51,8 @@ namespace DiscImageChef.Tests.Images
// TODO: Add "unknown" media types // TODO: Add "unknown" media types
readonly MediaType[] mediatypes = readonly MediaType[] mediatypes =
{ {
MediaType.DOS_35_DS_DD_9, MediaType.Unknown, MediaType.Unknown, MediaType.DOS_35_HD, MediaType.DOS_35_HD, MediaType.DOS_35_DS_DD_9, MediaType.CBM_35_DD, MediaType.CBM_35_DD, MediaType.DOS_35_HD,
MediaType.DMF, MediaType.DMF MediaType.DOS_35_HD, MediaType.DMF, MediaType.DMF
}; };
readonly string[] md5S = readonly string[] md5S =
@@ -67,18 +67,18 @@ namespace DiscImageChef.Tests.Images
{ {
for(int i = 0; i < testfiles.Length; i++) for(int i = 0; i < testfiles.Length; i++)
{ {
string location = Path.Combine(Consts.TestFilesRoot, "images", "copyqm", testfiles[i]); string location = Path.Combine(Consts.TestFilesRoot, "images", "copyqm", testfiles[i]);
IFilter filter = new LZip(); IFilter filter = new LZip();
filter.Open(location); filter.Open(location);
IMediaImage image = new DiscImages.CopyQm(); IMediaImage image = new DiscImages.CopyQm();
Assert.AreEqual(true, image.OpenImage(filter), testfiles[i]); Assert.AreEqual(true, image.OpenImage(filter), testfiles[i]);
Assert.AreEqual(sectors[i], image.Info.Sectors, testfiles[i]); Assert.AreEqual(sectors[i], image.Info.Sectors, testfiles[i]);
Assert.AreEqual(sectorsize[i], image.Info.SectorSize, testfiles[i]); Assert.AreEqual(sectorsize[i], image.Info.SectorSize, testfiles[i]);
Assert.AreEqual(mediatypes[i], image.Info.MediaType, testfiles[i]); Assert.AreEqual(mediatypes[i], image.Info.MediaType, testfiles[i]);
// How many sectors to read at once // How many sectors to read at once
const uint SECTORS_TO_READ = 256; const uint SECTORS_TO_READ = 256;
ulong doneSectors = 0; ulong doneSectors = 0;
Md5Context ctx = new Md5Context(); Md5Context ctx = new Md5Context();
ctx.Init(); ctx.Init();
@@ -89,13 +89,13 @@ namespace DiscImageChef.Tests.Images
if(image.Info.Sectors - doneSectors >= SECTORS_TO_READ) 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; doneSectors += SECTORS_TO_READ;
} }
else else
{ {
sector = image.ReadSectors(doneSectors, (uint)(image.Info.Sectors - doneSectors)); sector = image.ReadSectors(doneSectors, (uint)(image.Info.Sectors - doneSectors));
doneSectors += image.Info.Sectors - doneSectors; doneSectors += image.Info.Sectors - doneSectors;
} }
ctx.Update(sector); ctx.Update(sector);