mirror of
https://github.com/aaru-dps/Aaru.git
synced 2025-12-16 19:24:25 +00:00
🎨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:
2
.idea/.idea.DiscImageChef/.idea/contentModel.xml
generated
2
.idea/.idea.DiscImageChef/.idea/contentModel.xml
generated
@@ -72,6 +72,7 @@
|
||||
</e>
|
||||
<e p="DiscImageChef.CommonTypes" t="IncludeRecursive">
|
||||
<e p="DiscImageChef.CommonTypes.csproj" t="IncludeRecursive" />
|
||||
<e p="Geometry.cs" t="Include" />
|
||||
<e p="MediaType.cs" t="Include" />
|
||||
<e p="MediaTypeFromSCSI.cs" t="Include" />
|
||||
<e p="Partition.cs" t="Include" />
|
||||
@@ -80,6 +81,7 @@
|
||||
</e>
|
||||
<e p="bin" t="ExcludeRecursive" />
|
||||
<e p="obj" t="ExcludeRecursive" />
|
||||
<e p="packages.config" t="Include" />
|
||||
</e>
|
||||
<e p="DiscImageChef.Console" t="IncludeRecursive">
|
||||
<e p="DicConsole.cs" t="Include" />
|
||||
|
||||
@@ -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">
|
||||
<PropertyGroup>
|
||||
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||
@@ -32,8 +32,12 @@
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<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>
|
||||
<Compile Include="Geometry.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
<Compile Include="Partition.cs" />
|
||||
<Compile Include="MediaType.cs" />
|
||||
@@ -44,6 +48,9 @@
|
||||
<Link>LICENSE.LGPL</Link>
|
||||
</EmbeddedResource>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||
<ProjectExtensions>
|
||||
<MonoDevelop>
|
||||
|
||||
99
DiscImageChef.CommonTypes/Geometry.cs
Normal file
99
DiscImageChef.CommonTypes/Geometry.cs
Normal 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();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -35,6 +35,16 @@
|
||||
|
||||
namespace DiscImageChef.CommonTypes
|
||||
{
|
||||
public enum MediaEncoding
|
||||
{
|
||||
Unknown,
|
||||
FM,
|
||||
MFM,
|
||||
M2FM,
|
||||
AppleGCR,
|
||||
CommodoreGCR
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Contains an enumeration of all known types of media.
|
||||
/// </summary>
|
||||
@@ -293,9 +303,13 @@ namespace DiscImageChef.CommonTypes
|
||||
#endregion Microsoft 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,
|
||||
/// <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
|
||||
/// </summary>
|
||||
XDF_35,
|
||||
|
||||
4
DiscImageChef.CommonTypes/packages.config
Normal file
4
DiscImageChef.CommonTypes/packages.config
Normal file
@@ -0,0 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="System.ValueTuple" version="4.4.0" targetFramework="net40" />
|
||||
</packages>
|
||||
@@ -134,182 +134,10 @@ namespace DiscImageChef.DiscImages
|
||||
fdihdr = (Anex86Header)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(Anex86Header));
|
||||
handle.Free();
|
||||
|
||||
imageInfo.MediaType = MediaType.GENERIC_HDD;
|
||||
|
||||
switch(fdihdr.cylinders)
|
||||
{
|
||||
case 40:
|
||||
switch(fdihdr.bps)
|
||||
{
|
||||
case 512:
|
||||
switch(fdihdr.spt)
|
||||
{
|
||||
case 8:
|
||||
switch(fdihdr.heads)
|
||||
{
|
||||
case 1:
|
||||
imageInfo.MediaType = MediaType.DOS_525_SS_DD_8;
|
||||
break;
|
||||
case 2:
|
||||
imageInfo.MediaType = MediaType.DOS_525_DS_DD_8;
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
case 9:
|
||||
switch(fdihdr.heads)
|
||||
{
|
||||
case 1:
|
||||
imageInfo.MediaType = MediaType.DOS_525_SS_DD_9;
|
||||
break;
|
||||
case 2:
|
||||
imageInfo.MediaType = MediaType.DOS_525_DS_DD_9;
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
case 70:
|
||||
switch(fdihdr.bps)
|
||||
{
|
||||
case 512:
|
||||
switch(fdihdr.spt)
|
||||
{
|
||||
case 9:
|
||||
if(fdihdr.heads == 1) imageInfo.MediaType = MediaType.Apricot_35;
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
case 77:
|
||||
switch(fdihdr.bps)
|
||||
{
|
||||
case 128:
|
||||
switch(fdihdr.spt)
|
||||
{
|
||||
case 26:
|
||||
if(fdihdr.heads == 2) imageInfo.MediaType = MediaType.NEC_8_SD;
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
case 256:
|
||||
switch(fdihdr.spt)
|
||||
{
|
||||
case 26:
|
||||
if(fdihdr.heads == 2) imageInfo.MediaType = MediaType.NEC_8_DD;
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
case 512:
|
||||
switch(fdihdr.spt)
|
||||
{
|
||||
case 8:
|
||||
if(fdihdr.heads == 1) imageInfo.MediaType = MediaType.Apricot_35;
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
case 1024:
|
||||
switch(fdihdr.spt)
|
||||
{
|
||||
case 8:
|
||||
if(fdihdr.heads == 2) imageInfo.MediaType = MediaType.NEC_525_HD;
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
case 80:
|
||||
switch(fdihdr.bps)
|
||||
{
|
||||
case 256:
|
||||
switch(fdihdr.spt)
|
||||
{
|
||||
case 16:
|
||||
switch(fdihdr.heads)
|
||||
{
|
||||
case 1:
|
||||
imageInfo.MediaType = MediaType.NEC_525_SS;
|
||||
break;
|
||||
case 2:
|
||||
imageInfo.MediaType = MediaType.NEC_525_DS;
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
case 512:
|
||||
switch(fdihdr.spt)
|
||||
{
|
||||
case 8:
|
||||
switch(fdihdr.heads)
|
||||
{
|
||||
case 1:
|
||||
imageInfo.MediaType = MediaType.DOS_35_SS_DD_8;
|
||||
break;
|
||||
case 2:
|
||||
imageInfo.MediaType = MediaType.DOS_35_DS_DD_8;
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
case 9:
|
||||
switch(fdihdr.heads)
|
||||
{
|
||||
case 1:
|
||||
imageInfo.MediaType = MediaType.DOS_35_SS_DD_9;
|
||||
break;
|
||||
case 2:
|
||||
imageInfo.MediaType = MediaType.DOS_35_DS_DD_9;
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
case 15:
|
||||
if(fdihdr.heads == 2) imageInfo.MediaType = MediaType.NEC_35_HD_15;
|
||||
break;
|
||||
case 18:
|
||||
if(fdihdr.heads == 2) imageInfo.MediaType = MediaType.DOS_35_HD;
|
||||
break;
|
||||
case 36:
|
||||
if(fdihdr.heads == 2) imageInfo.MediaType = MediaType.DOS_35_ED;
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
case 240:
|
||||
switch(fdihdr.bps)
|
||||
{
|
||||
case 512:
|
||||
switch(fdihdr.spt)
|
||||
{
|
||||
case 38:
|
||||
if(fdihdr.heads == 2) imageInfo.MediaType = MediaType.NEC_35_TD;
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
imageInfo.MediaType =
|
||||
Geometry.GetMediaType(((ushort)fdihdr.cylinders, (byte)fdihdr.heads, (ushort)fdihdr.spt,
|
||||
(uint)fdihdr.bps, MediaEncoding.MFM, false));
|
||||
if(imageInfo.MediaType == MediaType.Unknown) imageInfo.MediaType = MediaType.GENERIC_HDD;
|
||||
|
||||
DicConsole.DebugWriteLine("Anex86 plugin", "MediaType: {0}", imageInfo.MediaType);
|
||||
|
||||
|
||||
@@ -248,7 +248,8 @@ namespace DiscImageChef.DiscImages
|
||||
uint realLength = record.dataSize;
|
||||
|
||||
if(record.compression == CompressType.Compressed)
|
||||
realLength = Decompress(data, out sectorsData[record.cylinder][record.head][record.sector]);
|
||||
realLength =
|
||||
Decompress(data, out sectorsData[record.cylinder][record.head][record.sector]);
|
||||
else sectorsData[record.cylinder][record.head][record.sector] = data;
|
||||
|
||||
if(realLength < imageInfo.SectorSize) imageInfo.SectorSize = realLength;
|
||||
@@ -266,7 +267,9 @@ namespace DiscImageChef.DiscImages
|
||||
uint spt = uint.MaxValue;
|
||||
for(ushort cyl = 0; cyl < imageInfo.Cylinders; cyl++)
|
||||
{
|
||||
for(ushort head = 0; head < imageInfo.Heads; head++) if(spts[cyl][head] < spt) spt = spts[cyl][head];
|
||||
for(ushort head = 0; head < imageInfo.Heads; head++)
|
||||
if(spts[cyl][head] < spt)
|
||||
spt = spts[cyl][head];
|
||||
}
|
||||
|
||||
imageInfo.SectorsPerTrack = spt;
|
||||
@@ -274,12 +277,9 @@ namespace DiscImageChef.DiscImages
|
||||
DicConsole.DebugWriteLine("Apridisk plugin", "Found a minimum of {0} sectors per track",
|
||||
imageInfo.SectorsPerTrack);
|
||||
|
||||
if(imageInfo.Cylinders == 70 && imageInfo.Heads == 1 && imageInfo.SectorsPerTrack == 9)
|
||||
imageInfo.MediaType = MediaType.Apricot_35;
|
||||
else if(imageInfo.Cylinders == 80 && imageInfo.Heads == 1 && imageInfo.SectorsPerTrack == 9)
|
||||
imageInfo.MediaType = MediaType.DOS_35_SS_DD_9;
|
||||
else if(imageInfo.Cylinders == 80 && imageInfo.Heads == 2 && imageInfo.SectorsPerTrack == 9)
|
||||
imageInfo.MediaType = MediaType.DOS_35_DS_DD_9;
|
||||
imageInfo.MediaType =
|
||||
Geometry.GetMediaType(((ushort)imageInfo.Cylinders, (byte)imageInfo.Heads,
|
||||
(ushort)imageInfo.SectorsPerTrack, 512, MediaEncoding.MFM, false));
|
||||
|
||||
imageInfo.ImageSize = (ulong)stream.Length - headersizes;
|
||||
imageInfo.CreationTime = imageFilter.GetCreationTime();
|
||||
@@ -298,30 +298,6 @@ namespace DiscImageChef.DiscImages
|
||||
return true;
|
||||
}
|
||||
|
||||
static uint Decompress(byte[] compressed, out byte[] decompressed)
|
||||
{
|
||||
int readp = 0;
|
||||
int cLen = compressed.Length;
|
||||
MemoryStream buffer = new MemoryStream();
|
||||
|
||||
uint uLen = 0;
|
||||
|
||||
while(cLen >= 3)
|
||||
{
|
||||
ushort blklen = BitConverter.ToUInt16(compressed, readp);
|
||||
readp += 2;
|
||||
|
||||
for(int i = 0; i < blklen; i++) buffer.WriteByte(compressed[readp]);
|
||||
|
||||
uLen += blklen;
|
||||
readp++;
|
||||
cLen -= 3;
|
||||
}
|
||||
|
||||
decompressed = buffer.ToArray();
|
||||
return uLen;
|
||||
}
|
||||
|
||||
public byte[] ReadSector(ulong sectorAddress)
|
||||
{
|
||||
(ushort cylinder, byte head, byte sector) = LbaToChs(sectorAddress);
|
||||
@@ -356,15 +332,6 @@ namespace DiscImageChef.DiscImages
|
||||
return buffer.ToArray();
|
||||
}
|
||||
|
||||
(ushort cylinder, byte head, byte sector) LbaToChs(ulong lba)
|
||||
{
|
||||
ushort cylinder = (ushort)(lba / (imageInfo.Heads * imageInfo.SectorsPerTrack));
|
||||
byte head = (byte)(lba / imageInfo.SectorsPerTrack % imageInfo.Heads);
|
||||
byte sector = (byte)(lba % imageInfo.SectorsPerTrack + 1);
|
||||
|
||||
return (cylinder, head, sector);
|
||||
}
|
||||
|
||||
public byte[] ReadDiskTag(MediaTagType tag)
|
||||
{
|
||||
throw new FeatureUnsupportedImageException("Feature not supported by image format");
|
||||
@@ -461,6 +428,39 @@ namespace DiscImageChef.DiscImages
|
||||
return null;
|
||||
}
|
||||
|
||||
static uint Decompress(byte[] compressed, out byte[] decompressed)
|
||||
{
|
||||
int readp = 0;
|
||||
int cLen = compressed.Length;
|
||||
MemoryStream buffer = new MemoryStream();
|
||||
|
||||
uint uLen = 0;
|
||||
|
||||
while(cLen >= 3)
|
||||
{
|
||||
ushort blklen = BitConverter.ToUInt16(compressed, readp);
|
||||
readp += 2;
|
||||
|
||||
for(int i = 0; i < blklen; i++) buffer.WriteByte(compressed[readp]);
|
||||
|
||||
uLen += blklen;
|
||||
readp++;
|
||||
cLen -= 3;
|
||||
}
|
||||
|
||||
decompressed = buffer.ToArray();
|
||||
return uLen;
|
||||
}
|
||||
|
||||
(ushort cylinder, byte head, byte sector) LbaToChs(ulong lba)
|
||||
{
|
||||
ushort cylinder = (ushort)(lba / (imageInfo.Heads * imageInfo.SectorsPerTrack));
|
||||
byte head = (byte)(lba / imageInfo.SectorsPerTrack % imageInfo.Heads);
|
||||
byte sector = (byte)(lba % imageInfo.SectorsPerTrack + 1);
|
||||
|
||||
return (cylinder, head, sector);
|
||||
}
|
||||
|
||||
enum RecordType : uint
|
||||
{
|
||||
Deleted = 0xE31D0000,
|
||||
|
||||
@@ -271,77 +271,20 @@ namespace DiscImageChef.DiscImages
|
||||
imageInfo.Sectors = (ulong)sectors;
|
||||
imageInfo.SectorSize = header.sectorSize;
|
||||
|
||||
switch(header.drive)
|
||||
imageInfo.MediaType =
|
||||
Geometry.GetMediaType(((ushort)header.totalCylinders, (byte)header.heads, header.sectorsPerTrack,
|
||||
(uint)header.sectorSize, MediaEncoding.MFM, false));
|
||||
|
||||
switch(imageInfo.MediaType)
|
||||
{
|
||||
case COPYQM_525_HD:
|
||||
if(header.heads == 2 && header.totalCylinders == 80 && header.sectorsPerTrack == 15 &&
|
||||
header.sectorSize == 512) imageInfo.MediaType = MediaType.DOS_525_HD;
|
||||
else if(header.heads == 2 && header.totalCylinders == 80 && header.sectorsPerTrack == 16 &&
|
||||
header.sectorSize == 256) imageInfo.MediaType = MediaType.ACORN_525_DS_DD;
|
||||
else if(header.heads == 1 && header.totalCylinders == 80 && header.sectorsPerTrack == 16 &&
|
||||
header.sectorSize == 256) imageInfo.MediaType = MediaType.ACORN_525_SS_DD_80;
|
||||
else if(header.heads == 1 && header.totalCylinders == 80 && header.sectorsPerTrack == 10 &&
|
||||
header.sectorSize == 256) imageInfo.MediaType = MediaType.ACORN_525_SS_SD_80;
|
||||
else if(header.heads == 2 && header.totalCylinders == 80 && header.sectorsPerTrack == 8 &&
|
||||
header.sectorSize == 1024) imageInfo.MediaType = MediaType.NEC_525_HD;
|
||||
else if(header.heads == 2 && header.totalCylinders == 77 && header.sectorsPerTrack == 8 &&
|
||||
header.sectorSize == 1024) imageInfo.MediaType = MediaType.SHARP_525;
|
||||
else goto case COPYQM_525_DD;
|
||||
case MediaType.NEC_525_HD when header.drive == COPYQM_35_HD ||header.drive == COPYQM_35_ED:
|
||||
imageInfo.MediaType = MediaType.NEC_35_HD_8;
|
||||
break;
|
||||
case COPYQM_525_DD:
|
||||
if(header.heads == 1 && header.totalCylinders == 40 && header.sectorsPerTrack == 8 &&
|
||||
header.sectorSize == 512) imageInfo.MediaType = MediaType.DOS_525_SS_DD_8;
|
||||
else if(header.heads == 1 && header.totalCylinders == 40 && header.sectorsPerTrack == 9 &&
|
||||
header.sectorSize == 512) imageInfo.MediaType = MediaType.DOS_525_SS_DD_9;
|
||||
else if(header.heads == 2 && header.totalCylinders == 40 && header.sectorsPerTrack == 8 &&
|
||||
header.sectorSize == 512) imageInfo.MediaType = MediaType.DOS_525_DS_DD_8;
|
||||
else if(header.heads == 2 && header.totalCylinders == 40 && header.sectorsPerTrack == 9 &&
|
||||
header.sectorSize == 512) imageInfo.MediaType = MediaType.DOS_525_DS_DD_9;
|
||||
else if(header.heads == 1 && header.totalCylinders == 40 && header.sectorsPerTrack == 18 &&
|
||||
header.sectorSize == 128) imageInfo.MediaType = MediaType.ATARI_525_SD;
|
||||
else if(header.heads == 1 && header.totalCylinders == 40 && header.sectorsPerTrack == 26 &&
|
||||
header.sectorSize == 128) imageInfo.MediaType = MediaType.ATARI_525_ED;
|
||||
else if(header.heads == 1 && header.totalCylinders == 40 && header.sectorsPerTrack == 18 &&
|
||||
header.sectorSize == 256) imageInfo.MediaType = MediaType.ATARI_525_DD;
|
||||
else imageInfo.MediaType = MediaType.Unknown;
|
||||
case MediaType.DOS_525_HD when header.drive == COPYQM_35_HD ||header.drive == COPYQM_35_ED:
|
||||
imageInfo.MediaType = MediaType.NEC_35_HD_15;
|
||||
break;
|
||||
case COPYQM_35_ED:
|
||||
if(header.heads == 2 && header.totalCylinders == 80 && header.sectorsPerTrack == 36 &&
|
||||
header.sectorSize == 512) imageInfo.MediaType = MediaType.DOS_35_ED;
|
||||
else goto case COPYQM_35_HD;
|
||||
break;
|
||||
case COPYQM_35_HD:
|
||||
if(header.heads == 2 && header.totalCylinders == 80 && header.sectorsPerTrack == 18 &&
|
||||
header.sectorSize == 512) imageInfo.MediaType = MediaType.DOS_35_HD;
|
||||
else if(header.heads == 2 && header.totalCylinders == 80 && header.sectorsPerTrack == 21 &&
|
||||
header.sectorSize == 512) imageInfo.MediaType = MediaType.DMF;
|
||||
else if(header.heads == 2 && header.totalCylinders == 82 && header.sectorsPerTrack == 21 &&
|
||||
header.sectorSize == 512) imageInfo.MediaType = MediaType.DMF_82;
|
||||
else if(header.heads == 2 && header.totalCylinders == 80 && header.sectorsPerTrack == 8 &&
|
||||
header.sectorSize == 1024) imageInfo.MediaType = MediaType.NEC_35_HD_8;
|
||||
else if(header.heads == 2 && header.totalCylinders == 80 && header.sectorsPerTrack == 15 &&
|
||||
header.sectorSize == 512) imageInfo.MediaType = MediaType.NEC_35_HD_15;
|
||||
else goto case COPYQM_35_DD;
|
||||
break;
|
||||
case COPYQM_35_DD:
|
||||
if(header.heads == 2 && header.totalCylinders == 80 && header.sectorsPerTrack == 9 &&
|
||||
header.sectorSize == 512) imageInfo.MediaType = MediaType.DOS_35_DS_DD_9;
|
||||
else if(header.heads == 2 && header.totalCylinders == 80 && header.sectorsPerTrack == 8 &&
|
||||
header.sectorSize == 512) imageInfo.MediaType = MediaType.DOS_35_DS_DD_8;
|
||||
else if(header.heads == 1 && header.totalCylinders == 80 && header.sectorsPerTrack == 9 &&
|
||||
header.sectorSize == 512) imageInfo.MediaType = MediaType.DOS_35_SS_DD_9;
|
||||
else if(header.heads == 1 && header.totalCylinders == 80 && header.sectorsPerTrack == 8 &&
|
||||
header.sectorSize == 512) imageInfo.MediaType = MediaType.DOS_35_SS_DD_8;
|
||||
else if(header.heads == 2 && header.totalCylinders == 80 && header.sectorsPerTrack == 5 &&
|
||||
header.sectorSize == 1024) imageInfo.MediaType = MediaType.ACORN_35_DS_DD;
|
||||
else if(header.heads == 2 && header.totalCylinders == 77 && header.sectorsPerTrack == 8 &&
|
||||
header.sectorSize == 1024) imageInfo.MediaType = MediaType.SHARP_35;
|
||||
else if(header.heads == 1 && header.totalCylinders == 70 && header.sectorsPerTrack == 9 &&
|
||||
header.sectorSize == 512) imageInfo.MediaType = MediaType.Apricot_35;
|
||||
else imageInfo.MediaType = MediaType.Unknown;
|
||||
break;
|
||||
default:
|
||||
imageInfo.MediaType = MediaType.Unknown;
|
||||
case MediaType.RX50 when header.drive == COPYQM_525_DD || header.drive == COPYQM_525_HD:
|
||||
imageInfo.MediaType = MediaType.ATARI_35_SS_DD;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -355,7 +298,7 @@ namespace DiscImageChef.DiscImages
|
||||
DicConsole.VerboseWriteLine("CopyQM comments: {0}", imageInfo.Comments);
|
||||
|
||||
imageInfo.Heads = header.heads;
|
||||
imageInfo.Cylinders = header.imageCylinders;
|
||||
imageInfo.Cylinders = header.totalCylinders;
|
||||
imageInfo.SectorsPerTrack = header.sectorsPerTrack;
|
||||
|
||||
return true;
|
||||
@@ -516,7 +459,8 @@ namespace DiscImageChef.DiscImages
|
||||
/// <summary>0x18 Sectors on disk (part of FAT's BPB)</summary>
|
||||
public uint sectorsBig;
|
||||
/// <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>
|
||||
public byte blind;
|
||||
/// <summary>0x59 Density. 0 = Double, 1 = High, 2 = Quad/Extra</summary>
|
||||
@@ -528,7 +472,8 @@ namespace DiscImageChef.DiscImages
|
||||
/// <summary>0x5C CRC32 of data</summary>
|
||||
public uint crc;
|
||||
/// <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>
|
||||
public ushort time;
|
||||
/// <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>
|
||||
public byte drive;
|
||||
/// <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>
|
||||
public byte headerChecksum;
|
||||
}
|
||||
|
||||
@@ -45,6 +45,7 @@ namespace DiscImageChef.DiscImages
|
||||
{
|
||||
// Information from Quasi88's FORMAT.TXT file
|
||||
// Japanese comments copied from there
|
||||
// TODO: Solve media types
|
||||
public class D88 : IMediaImage
|
||||
{
|
||||
const byte READ_ONLY = 0x10;
|
||||
@@ -601,12 +602,14 @@ namespace DiscImageChef.DiscImages
|
||||
/// Disk name, nul-terminated ASCII
|
||||
/// ディスクの名前(ASCII + '\0')
|
||||
/// </summary>
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 17)] public byte[] name;
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 17)]
|
||||
public byte[] name;
|
||||
/// <summary>
|
||||
/// Reserved
|
||||
/// ディスクの名前(ASCII + '\0')
|
||||
/// </summary>
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 9)] public byte[] reserved;
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 9)]
|
||||
public byte[] reserved;
|
||||
/// <summary>
|
||||
/// Write protect status
|
||||
/// ライトプロテクト: 0x00 なし、0x10 あり
|
||||
@@ -626,7 +629,8 @@ namespace DiscImageChef.DiscImages
|
||||
/// Track pointers
|
||||
/// トラック部のオフセットテーブル 0 Track ~ 163 Track
|
||||
/// </summary>
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 164)] public int[] track_table;
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 164)]
|
||||
public int[] track_table;
|
||||
}
|
||||
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
@@ -676,7 +680,8 @@ namespace DiscImageChef.DiscImages
|
||||
/// Reserved
|
||||
/// リザーブ
|
||||
/// </summary>
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 5)] public byte[] reserved;
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 5)]
|
||||
public byte[] reserved;
|
||||
/// <summary>
|
||||
/// Size of data following this field
|
||||
/// このセクタ部のデータサイズ
|
||||
|
||||
@@ -193,81 +193,34 @@ namespace DiscImageChef.DiscImages
|
||||
imageInfo.Application, imageInfo.ApplicationVersion);
|
||||
|
||||
// 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.SectorsPerTrack == 16 &&
|
||||
imageInfo.SectorSize == 512 &&
|
||||
(footer.bpb.driveCode == DriDriveCodes.md2hd || footer.bpb.driveCode == DriDriveCodes.mf2hd))
|
||||
(footer.bpb.driveCode == DriDriveCodes.md2hd ||
|
||||
footer.bpb.driveCode == DriDriveCodes.mf2hd))
|
||||
{
|
||||
imageInfo.SectorsPerTrack = 8;
|
||||
imageInfo.SectorSize = 1024;
|
||||
}
|
||||
|
||||
switch(footer.bpb.driveCode)
|
||||
imageInfo.MediaType =
|
||||
Geometry.GetMediaType(((ushort)imageInfo.Cylinders, (byte)imageInfo.Heads,
|
||||
(ushort)imageInfo.SectorsPerTrack, imageInfo.SectorSize, MediaEncoding.MFM, false
|
||||
));
|
||||
|
||||
switch(imageInfo.MediaType)
|
||||
{
|
||||
case DriDriveCodes.md2hd:
|
||||
if(imageInfo.Heads == 2 && imageInfo.Cylinders == 80 && imageInfo.SectorsPerTrack == 15 &&
|
||||
imageInfo.SectorSize == 512) imageInfo.MediaType = MediaType.DOS_525_HD;
|
||||
else if(imageInfo.Heads == 2 && imageInfo.Cylinders == 80 && imageInfo.SectorsPerTrack == 16 &&
|
||||
imageInfo.SectorSize == 256) imageInfo.MediaType = MediaType.ACORN_525_DS_DD;
|
||||
else if(imageInfo.Heads == 1 && imageInfo.Cylinders == 80 && imageInfo.SectorsPerTrack == 16 &&
|
||||
imageInfo.SectorSize == 256) imageInfo.MediaType = MediaType.ACORN_525_SS_DD_80;
|
||||
else if(imageInfo.Heads == 1 && imageInfo.Cylinders == 80 && imageInfo.SectorsPerTrack == 10 &&
|
||||
imageInfo.SectorSize == 256) imageInfo.MediaType = MediaType.ACORN_525_SS_SD_80;
|
||||
else if(imageInfo.Heads == 2 && imageInfo.Cylinders == 77 && imageInfo.SectorsPerTrack == 8 &&
|
||||
imageInfo.SectorSize == 1024) imageInfo.MediaType = MediaType.NEC_525_HD;
|
||||
else goto case DriDriveCodes.md2dd;
|
||||
case MediaType.NEC_525_HD when footer.bpb.driveCode == DriDriveCodes.mf2hd ||
|
||||
footer.bpb.driveCode == DriDriveCodes.mf2ed:
|
||||
imageInfo.MediaType = MediaType.NEC_35_HD_8;
|
||||
break;
|
||||
case DriDriveCodes.md2dd:
|
||||
if(imageInfo.Heads == 1 && imageInfo.Cylinders == 40 && imageInfo.SectorsPerTrack == 8 &&
|
||||
imageInfo.SectorSize == 512) imageInfo.MediaType = MediaType.DOS_525_SS_DD_8;
|
||||
else if(imageInfo.Heads == 1 && imageInfo.Cylinders == 40 && imageInfo.SectorsPerTrack == 9 &&
|
||||
imageInfo.SectorSize == 512) imageInfo.MediaType = MediaType.DOS_525_SS_DD_9;
|
||||
else if(imageInfo.Heads == 2 && imageInfo.Cylinders == 40 && imageInfo.SectorsPerTrack == 8 &&
|
||||
imageInfo.SectorSize == 512) imageInfo.MediaType = MediaType.DOS_525_DS_DD_8;
|
||||
else if(imageInfo.Heads == 2 && imageInfo.Cylinders == 40 && imageInfo.SectorsPerTrack == 9 &&
|
||||
imageInfo.SectorSize == 512) imageInfo.MediaType = MediaType.DOS_525_DS_DD_9;
|
||||
else if(imageInfo.Heads == 1 && imageInfo.Cylinders == 40 && imageInfo.SectorsPerTrack == 18 &&
|
||||
imageInfo.SectorSize == 128) imageInfo.MediaType = MediaType.ATARI_525_SD;
|
||||
else if(imageInfo.Heads == 1 && imageInfo.Cylinders == 40 && imageInfo.SectorsPerTrack == 26 &&
|
||||
imageInfo.SectorSize == 128) imageInfo.MediaType = MediaType.ATARI_525_ED;
|
||||
else if(imageInfo.Heads == 1 && imageInfo.Cylinders == 40 && imageInfo.SectorsPerTrack == 18 &&
|
||||
imageInfo.SectorSize == 256) imageInfo.MediaType = MediaType.ATARI_525_DD;
|
||||
else imageInfo.MediaType = MediaType.Unknown;
|
||||
case MediaType.DOS_525_HD when footer.bpb.driveCode == DriDriveCodes.mf2hd ||
|
||||
footer.bpb.driveCode == DriDriveCodes.mf2ed:
|
||||
imageInfo.MediaType = MediaType.NEC_35_HD_15;
|
||||
break;
|
||||
case DriDriveCodes.mf2ed:
|
||||
if(imageInfo.Heads == 2 && imageInfo.Cylinders == 80 && imageInfo.SectorsPerTrack == 36 &&
|
||||
imageInfo.SectorSize == 512) imageInfo.MediaType = MediaType.DOS_35_ED;
|
||||
else goto case DriDriveCodes.mf2hd;
|
||||
break;
|
||||
case DriDriveCodes.mf2hd:
|
||||
if(imageInfo.Heads == 2 && imageInfo.Cylinders == 80 && imageInfo.SectorsPerTrack == 18 &&
|
||||
imageInfo.SectorSize == 512) imageInfo.MediaType = MediaType.DOS_35_HD;
|
||||
else if(imageInfo.Heads == 2 && imageInfo.Cylinders == 80 && imageInfo.SectorsPerTrack == 21 &&
|
||||
imageInfo.SectorSize == 512) imageInfo.MediaType = MediaType.DMF;
|
||||
else if(imageInfo.Heads == 2 && imageInfo.Cylinders == 82 && imageInfo.SectorsPerTrack == 21 &&
|
||||
imageInfo.SectorSize == 512) imageInfo.MediaType = MediaType.DMF_82;
|
||||
else if(imageInfo.Heads == 2 && imageInfo.Cylinders == 77 && imageInfo.SectorsPerTrack == 8 &&
|
||||
imageInfo.SectorSize == 1024) imageInfo.MediaType = MediaType.NEC_35_HD_8;
|
||||
else if(imageInfo.Heads == 2 && imageInfo.Cylinders == 80 && imageInfo.SectorsPerTrack == 15 &&
|
||||
imageInfo.SectorSize == 512) imageInfo.MediaType = MediaType.NEC_35_HD_15;
|
||||
else goto case DriDriveCodes.mf2dd;
|
||||
break;
|
||||
case DriDriveCodes.mf2dd:
|
||||
if(imageInfo.Heads == 2 && imageInfo.Cylinders == 80 && imageInfo.SectorsPerTrack == 9 &&
|
||||
imageInfo.SectorSize == 512) imageInfo.MediaType = MediaType.DOS_35_DS_DD_9;
|
||||
else if(imageInfo.Heads == 2 && imageInfo.Cylinders == 80 && imageInfo.SectorsPerTrack == 8 &&
|
||||
imageInfo.SectorSize == 512) imageInfo.MediaType = MediaType.DOS_35_DS_DD_8;
|
||||
else if(imageInfo.Heads == 1 && imageInfo.Cylinders == 80 && imageInfo.SectorsPerTrack == 9 &&
|
||||
imageInfo.SectorSize == 512) imageInfo.MediaType = MediaType.DOS_35_SS_DD_9;
|
||||
else if(imageInfo.Heads == 1 && imageInfo.Cylinders == 80 && imageInfo.SectorsPerTrack == 8 &&
|
||||
imageInfo.SectorSize == 512) imageInfo.MediaType = MediaType.DOS_35_SS_DD_8;
|
||||
else if(imageInfo.Heads == 2 && imageInfo.Cylinders == 80 && imageInfo.SectorsPerTrack == 5 &&
|
||||
imageInfo.SectorSize == 1024) imageInfo.MediaType = MediaType.ACORN_35_DS_DD;
|
||||
else if(imageInfo.Heads == 1 && imageInfo.Cylinders == 70 && imageInfo.SectorsPerTrack == 9 &&
|
||||
imageInfo.SectorSize == 512) imageInfo.MediaType = MediaType.Apricot_35;
|
||||
else imageInfo.MediaType = MediaType.Unknown;
|
||||
break;
|
||||
default:
|
||||
imageInfo.MediaType = MediaType.Unknown;
|
||||
case MediaType.RX50 when footer.bpb.driveCode == DriDriveCodes.md2dd ||
|
||||
footer.bpb.driveCode == DriDriveCodes.md2hd:
|
||||
imageInfo.MediaType = MediaType.ATARI_35_SS_DD;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -406,7 +359,8 @@ namespace DiscImageChef.DiscImages
|
||||
struct DriFooter
|
||||
{
|
||||
/// <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>
|
||||
public DriBpb bpb;
|
||||
/// <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>
|
||||
public ushort sptrack2;
|
||||
/// <summary>Seems to be 0</summary>
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 144)] public byte[] unknown5;
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 144)]
|
||||
public byte[] unknown5;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -66,7 +66,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.InteropServices;
|
||||
using DiscImageChef.CommonTypes;
|
||||
using DiscImageChef.Console;
|
||||
@@ -76,17 +75,6 @@ namespace DiscImageChef.DiscImages
|
||||
{
|
||||
public class HdCopy : IMediaImage
|
||||
{
|
||||
readonly MediaTypeTableEntry[] mediaTypes =
|
||||
{
|
||||
new MediaTypeTableEntry {Tracks = 80, SectorsPerTrack = 8, MediaType = MediaType.DOS_35_DS_DD_8},
|
||||
new MediaTypeTableEntry {Tracks = 80, SectorsPerTrack = 9, MediaType = MediaType.DOS_35_DS_DD_9},
|
||||
new MediaTypeTableEntry {Tracks = 80, SectorsPerTrack = 18, MediaType = MediaType.DOS_35_HD},
|
||||
new MediaTypeTableEntry {Tracks = 80, SectorsPerTrack = 36, MediaType = MediaType.DOS_35_ED},
|
||||
new MediaTypeTableEntry {Tracks = 40, SectorsPerTrack = 8, MediaType = MediaType.DOS_525_DS_DD_8},
|
||||
new MediaTypeTableEntry {Tracks = 40, SectorsPerTrack = 9, MediaType = MediaType.DOS_525_DS_DD_9},
|
||||
new MediaTypeTableEntry {Tracks = 80, SectorsPerTrack = 15, MediaType = MediaType.DOS_525_HD}
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// The HDCP file header after the image has been opened
|
||||
/// </summary>
|
||||
@@ -177,7 +165,9 @@ namespace DiscImageChef.DiscImages
|
||||
if(fheader.trackMap[0] != 1 || fheader.trackMap[1] != 1) return false;
|
||||
|
||||
// all other tracks must be either present (=1) or absent (=0)
|
||||
for(int i = 0; i < 2 * 82; i++) if(fheader.trackMap[i] > 1) return false;
|
||||
for(int i = 0; i < 2 * 82; i++)
|
||||
if(fheader.trackMap[i] > 1)
|
||||
return false;
|
||||
|
||||
// TODO: validate the tracks
|
||||
// For now, having a valid header should be sufficient.
|
||||
@@ -186,8 +176,6 @@ namespace DiscImageChef.DiscImages
|
||||
|
||||
public bool OpenImage(IFilter imageFilter)
|
||||
{
|
||||
long currentOffset;
|
||||
|
||||
Stream stream = imageFilter.GetDataForkStream();
|
||||
stream.Seek(0, SeekOrigin.Begin);
|
||||
|
||||
@@ -215,25 +203,24 @@ namespace DiscImageChef.DiscImages
|
||||
imageInfo.LastModificationTime = imageFilter.GetLastWriteTime();
|
||||
imageInfo.MediaTitle = Path.GetFileNameWithoutExtension(imageFilter.GetFilename());
|
||||
imageInfo.MediaType =
|
||||
(from ent in mediaTypes
|
||||
where ent.Tracks == imageInfo.Cylinders && ent.SectorsPerTrack == imageInfo.SectorsPerTrack
|
||||
select ent.MediaType).FirstOrDefault();
|
||||
Geometry.GetMediaType(((ushort)imageInfo.Cylinders, 2, (ushort)imageInfo.SectorsPerTrack, 512,
|
||||
MediaEncoding.MFM, false));
|
||||
|
||||
// the start offset of the track data
|
||||
currentOffset = 2 + 2 * 82;
|
||||
long currentOffset = 2 + 2 * 82;
|
||||
|
||||
// build table of track offsets
|
||||
for(int i = 0; i < imageInfo.Cylinders * 2; i++)
|
||||
if(fheader.trackMap[i] == 0) trackOffset[i] = -1;
|
||||
if(fheader.trackMap[i] == 0)
|
||||
trackOffset[i] = -1;
|
||||
else
|
||||
{
|
||||
// track is present, read the block header
|
||||
if(currentOffset + 3 >= stream.Length) return false;
|
||||
|
||||
byte[] blkHeader = new byte[2];
|
||||
short blkLength;
|
||||
stream.Read(blkHeader, 0, 2);
|
||||
blkLength = BitConverter.ToInt16(blkHeader, 0);
|
||||
short blkLength = BitConverter.ToInt16(blkHeader, 0);
|
||||
|
||||
// assume block sizes are positive
|
||||
if(blkLength < 0) return false;
|
||||
@@ -256,49 +243,6 @@ namespace DiscImageChef.DiscImages
|
||||
return true;
|
||||
}
|
||||
|
||||
void ReadTrackIntoCache(Stream stream, int tracknum)
|
||||
{
|
||||
byte[] trackData = new byte[imageInfo.SectorSize * imageInfo.SectorsPerTrack];
|
||||
byte[] blkHeader = new byte[3];
|
||||
byte escapeByte;
|
||||
short compressedLength;
|
||||
|
||||
// check that track is present
|
||||
if(trackOffset[tracknum] == -1)
|
||||
throw new InvalidDataException("Tried reading a track that is not present in image");
|
||||
|
||||
stream.Seek(trackOffset[tracknum], SeekOrigin.Begin);
|
||||
|
||||
// read the compressed track data
|
||||
stream.Read(blkHeader, 0, 3);
|
||||
compressedLength = (short)(BitConverter.ToInt16(blkHeader, 0) - 1);
|
||||
escapeByte = blkHeader[2];
|
||||
|
||||
byte[] cBuffer = new byte[compressedLength];
|
||||
stream.Read(cBuffer, 0, compressedLength);
|
||||
|
||||
// decompress the data
|
||||
int sIndex = 0; // source buffer position
|
||||
int dIndex = 0; // destination buffer position
|
||||
while(sIndex < compressedLength)
|
||||
if(cBuffer[sIndex] == escapeByte)
|
||||
{
|
||||
sIndex++; // skip over escape byte
|
||||
byte fillByte = cBuffer[sIndex++];
|
||||
byte fillCount = cBuffer[sIndex++];
|
||||
// fill destination buffer
|
||||
for(int i = 0; i < fillCount; i++) trackData[dIndex++] = fillByte;
|
||||
}
|
||||
else trackData[dIndex++] = cBuffer[sIndex++];
|
||||
|
||||
// check that the number of bytes decompressed matches a whole track
|
||||
if(dIndex != imageInfo.SectorSize * imageInfo.SectorsPerTrack)
|
||||
throw new InvalidDataException("Track decompression yielded incomplete data");
|
||||
|
||||
// store track in cache
|
||||
trackCache[tracknum] = trackData;
|
||||
}
|
||||
|
||||
public byte[] ReadSector(ulong sectorAddress)
|
||||
{
|
||||
int trackNum = (int)(sectorAddress / imageInfo.SectorsPerTrack);
|
||||
@@ -432,6 +376,48 @@ namespace DiscImageChef.DiscImages
|
||||
return null;
|
||||
}
|
||||
|
||||
void ReadTrackIntoCache(Stream stream, int tracknum)
|
||||
{
|
||||
byte[] trackData = new byte[imageInfo.SectorSize * imageInfo.SectorsPerTrack];
|
||||
byte[] blkHeader = new byte[3];
|
||||
|
||||
// check that track is present
|
||||
if(trackOffset[tracknum] == -1)
|
||||
throw new InvalidDataException("Tried reading a track that is not present in image");
|
||||
|
||||
stream.Seek(trackOffset[tracknum], SeekOrigin.Begin);
|
||||
|
||||
// read the compressed track data
|
||||
stream.Read(blkHeader, 0, 3);
|
||||
short compressedLength = (short)(BitConverter.ToInt16(blkHeader, 0) - 1);
|
||||
byte escapeByte = blkHeader[2];
|
||||
|
||||
byte[] cBuffer = new byte[compressedLength];
|
||||
stream.Read(cBuffer, 0, compressedLength);
|
||||
|
||||
// decompress the data
|
||||
int sIndex = 0; // source buffer position
|
||||
int dIndex = 0; // destination buffer position
|
||||
while(sIndex < compressedLength)
|
||||
if(cBuffer[sIndex] == escapeByte)
|
||||
{
|
||||
sIndex++; // skip over escape byte
|
||||
byte fillByte = cBuffer[sIndex++];
|
||||
byte fillCount = cBuffer[sIndex++];
|
||||
// fill destination buffer
|
||||
for(int i = 0; i < fillCount; i++) trackData[dIndex++] = fillByte;
|
||||
}
|
||||
else
|
||||
trackData[dIndex++] = cBuffer[sIndex++];
|
||||
|
||||
// check that the number of bytes decompressed matches a whole track
|
||||
if(dIndex != imageInfo.SectorSize * imageInfo.SectorsPerTrack)
|
||||
throw new InvalidDataException("Track decompression yielded incomplete data");
|
||||
|
||||
// store track in cache
|
||||
trackCache[tracknum] = trackData;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The global header of a HDCP image file
|
||||
/// </summary>
|
||||
@@ -454,7 +440,8 @@ namespace DiscImageChef.DiscImages
|
||||
/// 0 means track is not present, 1 means it is present.
|
||||
/// The first 2 tracks are always present.
|
||||
/// </summary>
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2 * 82)] public byte[] trackMap;
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 2 * 82)]
|
||||
public byte[] trackMap;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -473,12 +460,5 @@ namespace DiscImageChef.DiscImages
|
||||
/// </summary>
|
||||
public byte escape;
|
||||
}
|
||||
|
||||
struct MediaTypeTableEntry
|
||||
{
|
||||
public byte Tracks;
|
||||
public byte SectorsPerTrack;
|
||||
public MediaType MediaType;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -47,8 +47,7 @@ namespace DiscImageChef.DiscImages
|
||||
const byte SECTOR_HEAD_MAP_MASK = 0x40;
|
||||
const byte COMMENT_END = 0x1A;
|
||||
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;
|
||||
|
||||
List<byte[]> sectorsData;
|
||||
@@ -157,14 +156,17 @@ namespace DiscImageChef.DiscImages
|
||||
|
||||
stream.Read(idmap, 0, idmap.Length);
|
||||
if((head & SECTOR_CYLINDER_MAP_MASK) == SECTOR_CYLINDER_MAP_MASK) stream.Read(cylmap, 0, cylmap.Length);
|
||||
if((head & SECTOR_HEAD_MAP_MASK) == SECTOR_HEAD_MAP_MASK) stream.Read(headmap, 0, headmap.Length);
|
||||
if((head & SECTOR_HEAD_MAP_MASK) == SECTOR_HEAD_MAP_MASK)
|
||||
stream.Read(headmap, 0, headmap.Length);
|
||||
if(n == 0xFF)
|
||||
{
|
||||
byte[] bpsbytes = new byte[spt * 2];
|
||||
stream.Read(bpsbytes, 0, bpsbytes.Length);
|
||||
for(int i = 0; i < spt; i++) bps[i] = BitConverter.ToUInt16(bpsbytes, i * 2);
|
||||
}
|
||||
else for(int i = 0; i < spt; i++) bps[i] = (ushort)(128 << n);
|
||||
else
|
||||
for(int i = 0; i < spt; i++)
|
||||
bps[i] = (ushort)(128 << n);
|
||||
|
||||
if(spt > imageInfo.SectorsPerTrack) imageInfo.SectorsPerTrack = spt;
|
||||
|
||||
@@ -219,92 +221,24 @@ namespace DiscImageChef.DiscImages
|
||||
imageInfo.Sectors = currentLba;
|
||||
imageInfo.MediaType = MediaType.Unknown;
|
||||
|
||||
switch(mode)
|
||||
MediaEncoding mediaEncoding = MediaEncoding.MFM;
|
||||
if(mode == TransferRate.TwoHundred || mode == TransferRate.ThreeHundred || mode == TransferRate.FiveHundred)
|
||||
mediaEncoding = MediaEncoding.FM;
|
||||
|
||||
imageInfo.MediaType =
|
||||
Geometry.GetMediaType(((ushort)imageInfo.Cylinders, (byte)imageInfo.Heads,
|
||||
(ushort)imageInfo.SectorsPerTrack, imageInfo.SectorSize, mediaEncoding, false));
|
||||
|
||||
switch(imageInfo.MediaType)
|
||||
{
|
||||
case TransferRate.TwoHundred:
|
||||
case TransferRate.ThreeHundred:
|
||||
if(imageInfo.Heads == 1 && imageInfo.Cylinders == 40 && imageInfo.SectorsPerTrack == 10 &&
|
||||
imageInfo.SectorSize == 256) imageInfo.MediaType = MediaType.ACORN_525_SS_SD_40;
|
||||
else if(imageInfo.Heads == 1 && imageInfo.Cylinders == 80 && imageInfo.SectorsPerTrack == 10 &&
|
||||
imageInfo.SectorSize == 256) imageInfo.MediaType = MediaType.ACORN_525_SS_SD_80;
|
||||
else if(imageInfo.Heads == 1 && imageInfo.Cylinders == 40 && imageInfo.SectorsPerTrack == 18 &&
|
||||
imageInfo.SectorSize == 128) imageInfo.MediaType = MediaType.ATARI_525_SD;
|
||||
case MediaType.NEC_525_HD when mode == TransferRate.FiveHundredMfm:
|
||||
imageInfo.MediaType = MediaType.NEC_35_HD_8;
|
||||
break;
|
||||
case TransferRate.FiveHundred:
|
||||
if(imageInfo.Heads == 1 && imageInfo.Cylinders == 32 && imageInfo.SectorsPerTrack == 8 &&
|
||||
imageInfo.SectorSize == 319) imageInfo.MediaType = MediaType.IBM23FD;
|
||||
else if(imageInfo.Heads == 1 && imageInfo.Cylinders == 73 && imageInfo.SectorsPerTrack == 26 &&
|
||||
imageInfo.SectorSize == 128) imageInfo.MediaType = MediaType.IBM23FD;
|
||||
else if(imageInfo.Heads == 2 && imageInfo.Cylinders == 77 && imageInfo.SectorsPerTrack == 26 &&
|
||||
imageInfo.SectorSize == 128) imageInfo.MediaType = MediaType.NEC_8_SD;
|
||||
case MediaType.DOS_525_HD when mode == TransferRate.FiveHundredMfm:
|
||||
imageInfo.MediaType = MediaType.NEC_35_HD_15;
|
||||
break;
|
||||
case TransferRate.TwoHundredMfm:
|
||||
case TransferRate.ThreeHundredMfm:
|
||||
if(imageInfo.Heads == 1 && imageInfo.Cylinders == 40 && imageInfo.SectorsPerTrack == 8 &&
|
||||
imageInfo.SectorSize == 512) imageInfo.MediaType = MediaType.DOS_525_SS_DD_8;
|
||||
else if(imageInfo.Heads == 1 && imageInfo.Cylinders == 40 && imageInfo.SectorsPerTrack == 9 &&
|
||||
imageInfo.SectorSize == 512) imageInfo.MediaType = MediaType.DOS_525_SS_DD_9;
|
||||
else if(imageInfo.Heads == 2 && imageInfo.Cylinders == 40 && imageInfo.SectorsPerTrack == 8 &&
|
||||
imageInfo.SectorSize == 512) imageInfo.MediaType = MediaType.DOS_525_DS_DD_8;
|
||||
else if(imageInfo.Heads == 2 && imageInfo.Cylinders == 40 && imageInfo.SectorsPerTrack == 9 &&
|
||||
imageInfo.SectorSize == 512) imageInfo.MediaType = MediaType.DOS_525_DS_DD_9;
|
||||
else if(imageInfo.Heads == 1 && imageInfo.Cylinders == 40 && imageInfo.SectorsPerTrack == 18 &&
|
||||
imageInfo.SectorSize == 128) imageInfo.MediaType = MediaType.ATARI_525_SD;
|
||||
else if(imageInfo.Heads == 1 && imageInfo.Cylinders == 40 && imageInfo.SectorsPerTrack == 26 &&
|
||||
imageInfo.SectorSize == 128) imageInfo.MediaType = MediaType.ATARI_525_ED;
|
||||
else if(imageInfo.Heads == 1 && imageInfo.Cylinders == 40 && imageInfo.SectorsPerTrack == 18 &&
|
||||
imageInfo.SectorSize == 256) imageInfo.MediaType = MediaType.ATARI_525_DD;
|
||||
else if(imageInfo.Heads == 1 && imageInfo.Cylinders == 40 && imageInfo.SectorsPerTrack == 16 &&
|
||||
imageInfo.SectorSize == 256) imageInfo.MediaType = MediaType.ACORN_525_SS_DD_40;
|
||||
else if(imageInfo.Heads == 1 && imageInfo.Cylinders == 80 && imageInfo.SectorsPerTrack == 16 &&
|
||||
imageInfo.SectorSize == 256) imageInfo.MediaType = MediaType.ACORN_525_SS_DD_80;
|
||||
else if(imageInfo.Heads == 1 && imageInfo.Cylinders == 40 && imageInfo.SectorsPerTrack == 18 &&
|
||||
imageInfo.SectorSize == 256) imageInfo.MediaType = MediaType.ATARI_525_DD;
|
||||
else if(imageInfo.Heads == 1 && imageInfo.Cylinders == 80 && imageInfo.SectorsPerTrack == 10 &&
|
||||
imageInfo.SectorSize == 512) imageInfo.MediaType = MediaType.RX50;
|
||||
else if(imageInfo.Heads == 2 && imageInfo.Cylinders == 80 && imageInfo.SectorsPerTrack == 9 &&
|
||||
imageInfo.SectorSize == 512) imageInfo.MediaType = MediaType.DOS_35_DS_DD_9;
|
||||
else if(imageInfo.Heads == 2 && imageInfo.Cylinders == 80 && imageInfo.SectorsPerTrack == 8 &&
|
||||
imageInfo.SectorSize == 512) imageInfo.MediaType = MediaType.DOS_35_DS_DD_8;
|
||||
if(imageInfo.Heads == 1 && imageInfo.Cylinders == 80 && imageInfo.SectorsPerTrack == 9 &&
|
||||
imageInfo.SectorSize == 512) imageInfo.MediaType = MediaType.DOS_35_SS_DD_9;
|
||||
else if(imageInfo.Heads == 1 && imageInfo.Cylinders == 80 && imageInfo.SectorsPerTrack == 8 &&
|
||||
imageInfo.SectorSize == 512) imageInfo.MediaType = MediaType.DOS_35_SS_DD_8;
|
||||
else if(imageInfo.Heads == 2 && imageInfo.Cylinders == 80 && imageInfo.SectorsPerTrack == 5 &&
|
||||
imageInfo.SectorSize == 1024) imageInfo.MediaType = MediaType.ACORN_35_DS_DD;
|
||||
else if(imageInfo.Heads == 2 && imageInfo.Cylinders == 82 && imageInfo.SectorsPerTrack == 10 &&
|
||||
imageInfo.SectorSize == 512) imageInfo.MediaType = MediaType.FDFORMAT_35_DD;
|
||||
else if(imageInfo.Heads == 1 && imageInfo.Cylinders == 70 && imageInfo.SectorsPerTrack == 9 &&
|
||||
imageInfo.SectorSize == 512) imageInfo.MediaType = MediaType.Apricot_35;
|
||||
break;
|
||||
case TransferRate.FiveHundredMfm:
|
||||
if(imageInfo.Heads == 2 && imageInfo.Cylinders == 80 && imageInfo.SectorsPerTrack == 18 &&
|
||||
imageInfo.SectorSize == 512) imageInfo.MediaType = MediaType.DOS_35_HD;
|
||||
else if(imageInfo.Heads == 2 && imageInfo.Cylinders == 80 && imageInfo.SectorsPerTrack == 21 &&
|
||||
imageInfo.SectorSize == 512) imageInfo.MediaType = MediaType.DMF;
|
||||
else if(imageInfo.Heads == 2 && imageInfo.Cylinders == 82 && imageInfo.SectorsPerTrack == 21 &&
|
||||
imageInfo.SectorSize == 512) imageInfo.MediaType = MediaType.DMF_82;
|
||||
else if(imageInfo.Heads == 2 && imageInfo.Cylinders == 80 && imageInfo.SectorsPerTrack == 23 &&
|
||||
imageInfo.SectorSize == 512) imageInfo.MediaType = MediaType.XDF_35;
|
||||
else if(imageInfo.Heads == 2 && imageInfo.Cylinders == 80 && imageInfo.SectorsPerTrack == 15 &&
|
||||
imageInfo.SectorSize == 512) imageInfo.MediaType = MediaType.DOS_525_HD;
|
||||
else if(imageInfo.Heads == 2 && imageInfo.Cylinders == 80 && imageInfo.SectorsPerTrack == 10 &&
|
||||
imageInfo.SectorSize == 1024) imageInfo.MediaType = MediaType.ACORN_35_DS_HD;
|
||||
else if(imageInfo.Heads == 2 && imageInfo.Cylinders == 77 && imageInfo.SectorsPerTrack == 8 &&
|
||||
imageInfo.SectorSize == 1024) imageInfo.MediaType = MediaType.NEC_525_HD;
|
||||
else if(imageInfo.Heads == 2 && imageInfo.Cylinders == 80 && imageInfo.SectorsPerTrack == 9 &&
|
||||
imageInfo.SectorSize == 1024) imageInfo.MediaType = MediaType.SHARP_525_9;
|
||||
else if(imageInfo.Heads == 1 && imageInfo.Cylinders == 80 && imageInfo.SectorsPerTrack == 10 &&
|
||||
imageInfo.SectorSize == 512) imageInfo.MediaType = MediaType.ATARI_35_SS_DD;
|
||||
else if(imageInfo.Heads == 2 && imageInfo.Cylinders == 80 && imageInfo.SectorsPerTrack == 10 &&
|
||||
imageInfo.SectorSize == 512) imageInfo.MediaType = MediaType.ATARI_35_DS_DD;
|
||||
else if(imageInfo.Heads == 1 && imageInfo.Cylinders == 80 && imageInfo.SectorsPerTrack == 11 &&
|
||||
imageInfo.SectorSize == 512) imageInfo.MediaType = MediaType.ATARI_35_SS_DD_11;
|
||||
else if(imageInfo.Heads == 2 && imageInfo.Cylinders == 80 && imageInfo.SectorsPerTrack == 11 &&
|
||||
imageInfo.SectorSize == 512) imageInfo.MediaType = MediaType.ATARI_35_DS_DD_11;
|
||||
break;
|
||||
default:
|
||||
imageInfo.MediaType = MediaType.Unknown;
|
||||
case MediaType.RX50 when mode == TransferRate.FiveHundredMfm:
|
||||
imageInfo.MediaType = MediaType.ATARI_35_SS_DD;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -178,55 +178,10 @@ namespace DiscImageChef.DiscImages
|
||||
imageInfo.CreationTime = imageFilter.GetCreationTime();
|
||||
imageInfo.LastModificationTime = imageFilter.GetLastWriteTime();
|
||||
|
||||
if(imageInfo.Heads == 2 && imageInfo.Cylinders == 80 && imageInfo.SectorsPerTrack == 15 &&
|
||||
imageInfo.SectorSize == 512) imageInfo.MediaType = MediaType.DOS_525_HD;
|
||||
else if(imageInfo.Heads == 2 && imageInfo.Cylinders == 80 && imageInfo.SectorsPerTrack == 16 &&
|
||||
imageInfo.SectorSize == 256) imageInfo.MediaType = MediaType.ACORN_525_DS_DD;
|
||||
else if(imageInfo.Heads == 1 && imageInfo.Cylinders == 80 && imageInfo.SectorsPerTrack == 16 &&
|
||||
imageInfo.SectorSize == 256) imageInfo.MediaType = MediaType.ACORN_525_SS_DD_80;
|
||||
else if(imageInfo.Heads == 1 && imageInfo.Cylinders == 80 && imageInfo.SectorsPerTrack == 10 &&
|
||||
imageInfo.SectorSize == 256) imageInfo.MediaType = MediaType.ACORN_525_SS_SD_80;
|
||||
else if(imageInfo.Heads == 2 && imageInfo.Cylinders == 77 && imageInfo.SectorsPerTrack == 8 &&
|
||||
imageInfo.SectorSize == 1024) imageInfo.MediaType = MediaType.NEC_525_HD;
|
||||
else if(imageInfo.Heads == 1 && imageInfo.Cylinders == 40 && imageInfo.SectorsPerTrack == 8 &&
|
||||
imageInfo.SectorSize == 512) imageInfo.MediaType = MediaType.DOS_525_SS_DD_8;
|
||||
else if(imageInfo.Heads == 1 && imageInfo.Cylinders == 40 && imageInfo.SectorsPerTrack == 9 &&
|
||||
imageInfo.SectorSize == 512) imageInfo.MediaType = MediaType.DOS_525_SS_DD_9;
|
||||
else if(imageInfo.Heads == 2 && imageInfo.Cylinders == 40 && imageInfo.SectorsPerTrack == 8 &&
|
||||
imageInfo.SectorSize == 512) imageInfo.MediaType = MediaType.DOS_525_DS_DD_8;
|
||||
else if(imageInfo.Heads == 2 && imageInfo.Cylinders == 40 && imageInfo.SectorsPerTrack == 9 &&
|
||||
imageInfo.SectorSize == 512) imageInfo.MediaType = MediaType.DOS_525_DS_DD_9;
|
||||
else if(imageInfo.Heads == 1 && imageInfo.Cylinders == 40 && imageInfo.SectorsPerTrack == 18 &&
|
||||
imageInfo.SectorSize == 128) imageInfo.MediaType = MediaType.ATARI_525_SD;
|
||||
else if(imageInfo.Heads == 1 && imageInfo.Cylinders == 40 && imageInfo.SectorsPerTrack == 26 &&
|
||||
imageInfo.SectorSize == 128) imageInfo.MediaType = MediaType.ATARI_525_ED;
|
||||
else if(imageInfo.Heads == 1 && imageInfo.Cylinders == 40 && imageInfo.SectorsPerTrack == 18 &&
|
||||
imageInfo.SectorSize == 256) imageInfo.MediaType = MediaType.ATARI_525_DD;
|
||||
else if(imageInfo.Heads == 2 && imageInfo.Cylinders == 80 && imageInfo.SectorsPerTrack == 36 &&
|
||||
imageInfo.SectorSize == 512) imageInfo.MediaType = MediaType.DOS_35_ED;
|
||||
else if(imageInfo.Heads == 2 && imageInfo.Cylinders == 80 && imageInfo.SectorsPerTrack == 18 &&
|
||||
imageInfo.SectorSize == 512) imageInfo.MediaType = MediaType.DOS_35_HD;
|
||||
else if(imageInfo.Heads == 2 && imageInfo.Cylinders == 80 && imageInfo.SectorsPerTrack == 21 &&
|
||||
imageInfo.SectorSize == 512) imageInfo.MediaType = MediaType.DMF;
|
||||
else if(imageInfo.Heads == 2 && imageInfo.Cylinders == 82 && imageInfo.SectorsPerTrack == 21 &&
|
||||
imageInfo.SectorSize == 512) imageInfo.MediaType = MediaType.DMF_82;
|
||||
else if(imageInfo.Heads == 2 && imageInfo.Cylinders == 77 && imageInfo.SectorsPerTrack == 8 &&
|
||||
imageInfo.SectorSize == 1024) imageInfo.MediaType = MediaType.NEC_35_HD_8;
|
||||
else if(imageInfo.Heads == 2 && imageInfo.Cylinders == 80 && imageInfo.SectorsPerTrack == 15 &&
|
||||
imageInfo.SectorSize == 512) imageInfo.MediaType = MediaType.NEC_35_HD_15;
|
||||
else if(imageInfo.Heads == 2 && imageInfo.Cylinders == 80 && imageInfo.SectorsPerTrack == 9 &&
|
||||
imageInfo.SectorSize == 512) imageInfo.MediaType = MediaType.DOS_35_DS_DD_9;
|
||||
else if(imageInfo.Heads == 2 && imageInfo.Cylinders == 80 && imageInfo.SectorsPerTrack == 8 &&
|
||||
imageInfo.SectorSize == 512) imageInfo.MediaType = MediaType.DOS_35_DS_DD_8;
|
||||
else if(imageInfo.Heads == 1 && imageInfo.Cylinders == 80 && imageInfo.SectorsPerTrack == 9 &&
|
||||
imageInfo.SectorSize == 512) imageInfo.MediaType = MediaType.DOS_35_SS_DD_9;
|
||||
else if(imageInfo.Heads == 1 && imageInfo.Cylinders == 80 && imageInfo.SectorsPerTrack == 8 &&
|
||||
imageInfo.SectorSize == 512) imageInfo.MediaType = MediaType.DOS_35_SS_DD_8;
|
||||
else if(imageInfo.Heads == 2 && imageInfo.Cylinders == 80 && imageInfo.SectorsPerTrack == 5 &&
|
||||
imageInfo.SectorSize == 1024) imageInfo.MediaType = MediaType.ACORN_35_DS_DD;
|
||||
else if(imageInfo.Heads == 1 && imageInfo.Cylinders == 70 && imageInfo.SectorsPerTrack == 9 &&
|
||||
imageInfo.SectorSize == 512) imageInfo.MediaType = MediaType.Apricot_35;
|
||||
else imageInfo.MediaType = MediaType.Unknown;
|
||||
imageInfo.MediaType =
|
||||
Geometry.GetMediaType(((ushort)imageInfo.Cylinders, (byte)imageInfo.Heads,
|
||||
(ushort)imageInfo.SectorsPerTrack, imageInfo.SectorSize, MediaEncoding.MFM, false
|
||||
));
|
||||
|
||||
imageInfo.XmlMediaType = XmlMediaType.BlockMedia;
|
||||
|
||||
|
||||
@@ -45,8 +45,7 @@ namespace DiscImageChef.DiscImages
|
||||
public class RayDim : IMediaImage
|
||||
{
|
||||
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;
|
||||
ImageInfo imageInfo;
|
||||
@@ -164,55 +163,22 @@ namespace DiscImageChef.DiscImages
|
||||
disk.Write(sectors, 0, sectors.Length);
|
||||
}
|
||||
|
||||
switch(header.diskType)
|
||||
imageInfo.MediaType =
|
||||
Geometry.GetMediaType(((ushort)imageInfo.Cylinders, (byte)imageInfo.Heads,
|
||||
(ushort)imageInfo.SectorsPerTrack, 512, MediaEncoding.MFM, false));
|
||||
|
||||
switch(imageInfo.MediaType)
|
||||
{
|
||||
case RayDiskTypes.Md2hd:
|
||||
if(imageInfo.Heads == 2 && imageInfo.Cylinders == 80 && imageInfo.SectorsPerTrack == 15)
|
||||
imageInfo.MediaType = MediaType.DOS_525_HD;
|
||||
else goto case RayDiskTypes.Md2dd;
|
||||
case MediaType.NEC_525_HD when header.diskType == RayDiskTypes.Mf2hd ||
|
||||
header.diskType == RayDiskTypes.Mf2ed:
|
||||
imageInfo.MediaType = MediaType.NEC_35_HD_8;
|
||||
break;
|
||||
case RayDiskTypes.Md2dd:
|
||||
if(imageInfo.Heads == 1 && imageInfo.Cylinders == 40 && imageInfo.SectorsPerTrack == 8)
|
||||
imageInfo.MediaType = MediaType.DOS_525_SS_DD_8;
|
||||
else if(imageInfo.Heads == 1 && imageInfo.Cylinders == 40 && imageInfo.SectorsPerTrack == 9)
|
||||
imageInfo.MediaType = MediaType.DOS_525_SS_DD_9;
|
||||
else if(imageInfo.Heads == 2 && imageInfo.Cylinders == 40 && imageInfo.SectorsPerTrack == 8)
|
||||
imageInfo.MediaType = MediaType.DOS_525_DS_DD_8;
|
||||
else if(imageInfo.Heads == 2 && imageInfo.Cylinders == 40 && imageInfo.SectorsPerTrack == 9)
|
||||
imageInfo.MediaType = MediaType.DOS_525_DS_DD_9;
|
||||
else imageInfo.MediaType = MediaType.Unknown;
|
||||
break;
|
||||
case RayDiskTypes.Mf2ed:
|
||||
if(imageInfo.Heads == 2 && imageInfo.Cylinders == 80 && imageInfo.SectorsPerTrack == 36)
|
||||
imageInfo.MediaType = MediaType.DOS_35_ED;
|
||||
else goto case RayDiskTypes.Mf2hd;
|
||||
break;
|
||||
case RayDiskTypes.Mf2hd:
|
||||
if(imageInfo.Heads == 2 && imageInfo.Cylinders == 80 && imageInfo.SectorsPerTrack == 18)
|
||||
imageInfo.MediaType = MediaType.DOS_35_HD;
|
||||
else if(imageInfo.Heads == 2 && imageInfo.Cylinders == 80 && imageInfo.SectorsPerTrack == 21)
|
||||
imageInfo.MediaType = MediaType.DMF;
|
||||
else if(imageInfo.Heads == 2 && imageInfo.Cylinders == 82 && imageInfo.SectorsPerTrack == 21)
|
||||
imageInfo.MediaType = MediaType.DMF_82;
|
||||
else if(imageInfo.Heads == 2 && imageInfo.Cylinders == 80 && imageInfo.SectorsPerTrack == 15)
|
||||
case MediaType.DOS_525_HD when header.diskType == RayDiskTypes.Mf2hd ||
|
||||
header.diskType == RayDiskTypes.Mf2ed:
|
||||
imageInfo.MediaType = MediaType.NEC_35_HD_15;
|
||||
else goto case RayDiskTypes.Mf2dd;
|
||||
break;
|
||||
case RayDiskTypes.Mf2dd:
|
||||
if(imageInfo.Heads == 2 && imageInfo.Cylinders == 80 && imageInfo.SectorsPerTrack == 9)
|
||||
imageInfo.MediaType = MediaType.DOS_35_DS_DD_9;
|
||||
else if(imageInfo.Heads == 2 && imageInfo.Cylinders == 80 && imageInfo.SectorsPerTrack == 8)
|
||||
imageInfo.MediaType = MediaType.DOS_35_DS_DD_8;
|
||||
else if(imageInfo.Heads == 1 && imageInfo.Cylinders == 80 && imageInfo.SectorsPerTrack == 9)
|
||||
imageInfo.MediaType = MediaType.DOS_35_SS_DD_9;
|
||||
else if(imageInfo.Heads == 1 && imageInfo.Cylinders == 80 && imageInfo.SectorsPerTrack == 8)
|
||||
imageInfo.MediaType = MediaType.DOS_35_SS_DD_8;
|
||||
else if(imageInfo.Heads == 1 && imageInfo.Cylinders == 70 && imageInfo.SectorsPerTrack == 9)
|
||||
imageInfo.MediaType = MediaType.Apricot_35;
|
||||
else imageInfo.MediaType = MediaType.Unknown;
|
||||
break;
|
||||
default:
|
||||
imageInfo.MediaType = MediaType.Unknown;
|
||||
case MediaType.RX50 when header.diskType == RayDiskTypes.Md2dd || header.diskType == RayDiskTypes.Md2hd:
|
||||
imageInfo.MediaType = MediaType.ATARI_35_SS_DD;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -347,7 +313,8 @@ namespace DiscImageChef.DiscImages
|
||||
[StructLayout(LayoutKind.Sequential, Pack = 1)]
|
||||
struct RayHdr
|
||||
{
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 80)] public byte[] signature;
|
||||
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 80)]
|
||||
public byte[] signature;
|
||||
public RayDiskTypes diskType;
|
||||
public byte cylinders;
|
||||
public byte sectorsPerTrack;
|
||||
|
||||
@@ -177,100 +177,9 @@ namespace DiscImageChef.DiscImages
|
||||
imageInfo.Sectors = (ulong)(header.sectorsPerTrack * header.heads * header.cylinders);
|
||||
imageInfo.SectorSize = header.sectorSize;
|
||||
|
||||
imageInfo.MediaType = MediaType.Unknown;
|
||||
switch(header.cylinders)
|
||||
{
|
||||
case 40:
|
||||
switch(header.heads)
|
||||
{
|
||||
case 1:
|
||||
switch(header.sectorsPerTrack)
|
||||
{
|
||||
case 8:
|
||||
imageInfo.MediaType = MediaType.DOS_525_SS_DD_8;
|
||||
break;
|
||||
case 9:
|
||||
imageInfo.MediaType = MediaType.DOS_525_SS_DD_9;
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
case 2:
|
||||
switch(header.sectorsPerTrack)
|
||||
{
|
||||
case 8:
|
||||
imageInfo.MediaType = MediaType.DOS_525_DS_DD_8;
|
||||
break;
|
||||
case 9:
|
||||
imageInfo.MediaType = MediaType.DOS_525_DS_DD_9;
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
case 70:
|
||||
switch(header.heads)
|
||||
{
|
||||
case 1:
|
||||
switch(header.sectorsPerTrack)
|
||||
{
|
||||
case 9:
|
||||
imageInfo.MediaType = MediaType.Apricot_35;
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
case 80:
|
||||
switch(header.heads)
|
||||
{
|
||||
case 1:
|
||||
switch(header.sectorsPerTrack)
|
||||
{
|
||||
case 8:
|
||||
imageInfo.MediaType = MediaType.DOS_35_SS_DD_8;
|
||||
break;
|
||||
case 9:
|
||||
imageInfo.MediaType = MediaType.DOS_35_SS_DD_9;
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
case 2:
|
||||
switch(header.sectorsPerTrack)
|
||||
{
|
||||
case 8:
|
||||
imageInfo.MediaType = MediaType.DOS_35_DS_DD_8;
|
||||
break;
|
||||
case 9:
|
||||
imageInfo.MediaType = MediaType.DOS_35_DS_DD_9;
|
||||
break;
|
||||
case 15:
|
||||
imageInfo.MediaType = MediaType.DOS_525_HD;
|
||||
break;
|
||||
case 18:
|
||||
imageInfo.MediaType = MediaType.DOS_35_HD;
|
||||
break;
|
||||
case 23:
|
||||
imageInfo.MediaType = MediaType.XDF_35;
|
||||
break;
|
||||
case 36:
|
||||
imageInfo.MediaType = MediaType.DOS_35_ED;
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
imageInfo.MediaType = MediaType.Unknown;
|
||||
break;
|
||||
}
|
||||
imageInfo.MediaType =
|
||||
Geometry.GetMediaType((header.cylinders, (byte)header.heads, header.sectorsPerTrack, header.sectorSize,
|
||||
MediaEncoding.MFM, false));
|
||||
|
||||
imageInfo.XmlMediaType = XmlMediaType.BlockMedia;
|
||||
|
||||
|
||||
@@ -202,10 +202,12 @@ namespace DiscImageChef.DiscImages
|
||||
imageInfo.SectorSize = 256;
|
||||
break;
|
||||
default:
|
||||
if((extension == ".adf" || extension == ".adl" || extension == ".ssd" || extension == ".dsd") &&
|
||||
if((extension == ".adf" || extension == ".adl" ||
|
||||
extension == ".ssd" || extension == ".dsd") &&
|
||||
(imageFilter.GetDataForkLength() == 163840 || imageFilter.GetDataForkLength() == 327680 ||
|
||||
imageFilter.GetDataForkLength() == 655360)) imageInfo.SectorSize = 256;
|
||||
else if((extension == ".adf" || extension == ".adl") && imageFilter.GetDataForkLength() == 819200)
|
||||
else if((extension == ".adf" || extension == ".adl") &&
|
||||
imageFilter.GetDataForkLength() == 819200)
|
||||
imageInfo.SectorSize = 1024;
|
||||
else
|
||||
switch(imageFilter.GetDataForkLength())
|
||||
@@ -525,7 +527,7 @@ namespace DiscImageChef.DiscImages
|
||||
break;
|
||||
case MediaType.Apricot_35:
|
||||
imageInfo.Cylinders = 70;
|
||||
imageInfo.Heads = 1;
|
||||
imageInfo.Heads = 2;
|
||||
imageInfo.SectorsPerTrack = 9;
|
||||
break;
|
||||
case MediaType.DOS_35_ED:
|
||||
@@ -881,6 +883,41 @@ namespace DiscImageChef.DiscImages
|
||||
return ReadSectors(sectorAddress, length);
|
||||
}
|
||||
|
||||
public byte[] ReadSectorTag(ulong sectorAddress, SectorTagType tag)
|
||||
{
|
||||
throw new FeatureUnsupportedImageException("Feature not supported by image format");
|
||||
}
|
||||
|
||||
public byte[] ReadSectorsTag(ulong sectorAddress, uint length, SectorTagType tag)
|
||||
{
|
||||
throw new FeatureUnsupportedImageException("Feature not supported by image format");
|
||||
}
|
||||
|
||||
public byte[] ReadSectorLong(ulong sectorAddress)
|
||||
{
|
||||
throw new FeatureUnsupportedImageException("Feature not supported by image format");
|
||||
}
|
||||
|
||||
public byte[] ReadSectorsLong(ulong sectorAddress, uint length)
|
||||
{
|
||||
throw new FeatureUnsupportedImageException("Feature not supported by image format");
|
||||
}
|
||||
|
||||
public byte[] ReadDiskTag(MediaTagType tag)
|
||||
{
|
||||
throw new FeatureUnsupportedImageException("Feature not supported by image format");
|
||||
}
|
||||
|
||||
public byte[] ReadSectorTag(ulong sectorAddress, uint track, SectorTagType tag)
|
||||
{
|
||||
throw new FeatureUnsupportedImageException("Feature not supported by image format");
|
||||
}
|
||||
|
||||
public byte[] ReadSectorsTag(ulong sectorAddress, uint length, uint track, SectorTagType tag)
|
||||
{
|
||||
throw new FeatureUnsupportedImageException("Feature not supported by image format");
|
||||
}
|
||||
|
||||
MediaType CalculateDiskType()
|
||||
{
|
||||
if(imageInfo.SectorSize == 2048)
|
||||
@@ -993,40 +1030,5 @@ namespace DiscImageChef.DiscImages
|
||||
default: return MediaType.GENERIC_HDD;
|
||||
}
|
||||
}
|
||||
|
||||
public byte[] ReadSectorTag(ulong sectorAddress, SectorTagType tag)
|
||||
{
|
||||
throw new FeatureUnsupportedImageException("Feature not supported by image format");
|
||||
}
|
||||
|
||||
public byte[] ReadSectorsTag(ulong sectorAddress, uint length, SectorTagType tag)
|
||||
{
|
||||
throw new FeatureUnsupportedImageException("Feature not supported by image format");
|
||||
}
|
||||
|
||||
public byte[] ReadSectorLong(ulong sectorAddress)
|
||||
{
|
||||
throw new FeatureUnsupportedImageException("Feature not supported by image format");
|
||||
}
|
||||
|
||||
public byte[] ReadSectorsLong(ulong sectorAddress, uint length)
|
||||
{
|
||||
throw new FeatureUnsupportedImageException("Feature not supported by image format");
|
||||
}
|
||||
|
||||
public byte[] ReadDiskTag(MediaTagType tag)
|
||||
{
|
||||
throw new FeatureUnsupportedImageException("Feature not supported by image format");
|
||||
}
|
||||
|
||||
public byte[] ReadSectorTag(ulong sectorAddress, uint track, SectorTagType tag)
|
||||
{
|
||||
throw new FeatureUnsupportedImageException("Feature not supported by image format");
|
||||
}
|
||||
|
||||
public byte[] ReadSectorsTag(ulong sectorAddress, uint length, uint track, SectorTagType tag)
|
||||
{
|
||||
throw new FeatureUnsupportedImageException("Feature not supported by image format");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -51,8 +51,8 @@ namespace DiscImageChef.Tests.Images
|
||||
// TODO: Add "unknown" media types
|
||||
readonly MediaType[] mediatypes =
|
||||
{
|
||||
MediaType.DOS_35_DS_DD_9, MediaType.Unknown, MediaType.Unknown, MediaType.DOS_35_HD, MediaType.DOS_35_HD,
|
||||
MediaType.DMF, MediaType.DMF
|
||||
MediaType.DOS_35_DS_DD_9, MediaType.CBM_35_DD, MediaType.CBM_35_DD, MediaType.DOS_35_HD,
|
||||
MediaType.DOS_35_HD, MediaType.DMF, MediaType.DMF
|
||||
};
|
||||
|
||||
readonly string[] md5S =
|
||||
|
||||
Reference in New Issue
Block a user