Added preliminary support for KryoFlux STREAM disk image format (only sidecar creation)

This commit is contained in:
2017-12-04 19:35:42 +00:00
parent d0462f61df
commit 824ac802b3
5 changed files with 771 additions and 70 deletions

View File

@@ -419,31 +419,24 @@ namespace DiscImageChef.Core
}
// TODO: This is more of a hack, redo it planned for >4.0
#region SuperCardPro
string scpFilePath = Path.Combine(Path.GetDirectoryName(imagePath),
Path.GetFileNameWithoutExtension(imagePath) + ".scp");
ImagePlugins.SuperCardPro scpImage = new SuperCardPro();
Filters.ZZZNoFilter scpFilter = new ZZZNoFilter();
scpFilter.Open(scpFilePath);
string scpFormat = null;
string trkFormat = null;
switch(image.ImageInfo.mediaType)
{
case MediaType.Apple32SS:
case MediaType.Apple32DS:
scpFormat = "Apple GCR (DOS 3.2)";
trkFormat = "Apple GCR (DOS 3.2)";
break;
case MediaType.Apple33SS:
case MediaType.Apple33DS:
scpFormat = "Apple GCR (DOS 3.3)";
trkFormat = "Apple GCR (DOS 3.3)";
break;
case MediaType.AppleSonySS:
case MediaType.AppleSonyDS:
scpFormat = "Apple GCR (Sony)";
trkFormat = "Apple GCR (Sony)";
break;
case MediaType.AppleFileWare:
scpFormat = "Apple GCR (Twiggy)";
trkFormat = "Apple GCR (Twiggy)";
break;
case MediaType.DOS_525_SS_DD_9:
case MediaType.DOS_525_DS_DD_8:
@@ -490,7 +483,7 @@ namespace DiscImageChef.Core
case MediaType.FDFORMAT_35_HD:
case MediaType.Apricot_35:
case MediaType.CompactFloppy:
scpFormat = "IBM MFM";
trkFormat = "IBM MFM";
break;
case MediaType.ATARI_525_SD:
case MediaType.NEC_8_SD:
@@ -503,19 +496,19 @@ namespace DiscImageChef.Core
case MediaType.IBM33FD_512:
case MediaType.IBM43FD_128:
case MediaType.IBM43FD_256:
scpFormat = "IBM FM";
trkFormat = "IBM FM";
break;
case MediaType.CBM_35_DD:
scpFormat = "Commodore MFM";
trkFormat = "Commodore MFM";
break;
case MediaType.CBM_AMIGA_35_HD:
case MediaType.CBM_AMIGA_35_DD:
scpFormat = "Amiga MFM";
trkFormat = "Amiga MFM";
break;
case MediaType.CBM_1540:
case MediaType.CBM_1540_Ext:
case MediaType.CBM_1571:
scpFormat = "Commodore GCR";
trkFormat = "Commodore GCR";
break;
case MediaType.SHARP_525:
case MediaType.SHARP_525_9:
@@ -529,7 +522,7 @@ namespace DiscImageChef.Core
case MediaType.ECMA_125:
case MediaType.ECMA_147:
case MediaType.ECMA_99_8:
scpFormat = "ISO MFM";
trkFormat = "ISO MFM";
break;
case MediaType.ECMA_54:
case MediaType.ECMA_59:
@@ -540,78 +533,186 @@ namespace DiscImageChef.Core
case MediaType.ECMA_70:
case MediaType.ECMA_78:
case MediaType.ECMA_78_2:
scpFormat = "ISO FM";
trkFormat = "ISO FM";
break;
default:
scpFormat = "Unknown";
trkFormat = "Unknown";
break;
}
if(image.ImageInfo.heads <= 2 && File.Exists(scpFilePath) && scpImage.IdentifyImage(scpFilter))
#region SuperCardPro
string scpFilePath = Path.Combine(Path.GetDirectoryName(imagePath),
Path.GetFileNameWithoutExtension(imagePath) + ".scp");
if(File.Exists(scpFilePath))
{
try
{
scpImage.OpenImage(scpFilter);
}
catch(NotImplementedException)
{
}
ImagePlugins.SuperCardPro scpImage = new SuperCardPro();
Filters.ZZZNoFilter scpFilter = new ZZZNoFilter();
scpFilter.Open(scpFilePath);
if((image.ImageInfo.heads == 2 && scpImage.header.heads == 0) ||
(image.ImageInfo.heads == 1 && (scpImage.header.heads == 1 || scpImage.header.heads == 2)))
if(image.ImageInfo.heads <= 2 && scpImage.IdentifyImage(scpFilter))
{
if(scpImage.header.end + 1 >= image.ImageInfo.cylinders)
try
{
ImageType scpImageType = new ImageType();
scpImageType.format = "SuperCardPro";
scpImageType.Value = Path.GetFileName(scpFilePath);
List<BlockTrackType> scpBlockTrackTypes = new List<BlockTrackType>();
long currentSector = 0;
Stream scpStream = scpFilter.GetDataForkStream();
scpImage.OpenImage(scpFilter);
}
catch(NotImplementedException)
{
}
for(byte t = scpImage.header.start; t <= scpImage.header.end; t++)
if((image.ImageInfo.heads == 2 && scpImage.header.heads == 0) ||
(image.ImageInfo.heads == 1 && (scpImage.header.heads == 1 || scpImage.header.heads == 2)))
{
if(scpImage.header.end + 1 >= image.ImageInfo.cylinders)
{
BlockTrackType scpBlockTrackType = new BlockTrackType();
scpBlockTrackType.Cylinder = t / image.ImageInfo.heads;
scpBlockTrackType.Head = t % image.ImageInfo.heads;
scpBlockTrackType.Image = scpImageType;
scpBlockTrackType.Image.offset = scpImage.header.offsets[t];
List<BlockTrackType> scpBlockTrackTypes = new List<BlockTrackType>();
long currentSector = 0;
Stream scpStream = scpFilter.GetDataForkStream();
if(scpBlockTrackType.Cylinder < image.ImageInfo.cylinders)
for(byte t = scpImage.header.start; t <= scpImage.header.end; t++)
{
scpBlockTrackType.StartSector = currentSector;
currentSector += image.ImageInfo.sectorsPerTrack;
scpBlockTrackType.EndSector = currentSector - 1;
scpBlockTrackType.Sectors = image.ImageInfo.sectorsPerTrack;
scpBlockTrackType.BytesPerSector = (int)image.ImageInfo.sectorSize;
scpBlockTrackType.Format = scpFormat;
BlockTrackType scpBlockTrackType = new BlockTrackType();
scpBlockTrackType.Cylinder = t / image.ImageInfo.heads;
scpBlockTrackType.Head = t % image.ImageInfo.heads;
scpBlockTrackType.Image = new ImageType();
scpBlockTrackType.Image.format = scpImage.GetImageFormat();
scpBlockTrackType.Image.Value = Path.GetFileName(scpFilePath);
scpBlockTrackType.Image.offset = scpImage.header.offsets[t];
if(scpBlockTrackType.Cylinder < image.ImageInfo.cylinders)
{
scpBlockTrackType.StartSector = currentSector;
currentSector += image.ImageInfo.sectorsPerTrack;
scpBlockTrackType.EndSector = currentSector - 1;
scpBlockTrackType.Sectors = image.ImageInfo.sectorsPerTrack;
scpBlockTrackType.BytesPerSector = (int)image.ImageInfo.sectorSize;
scpBlockTrackType.Format = trkFormat;
}
if(scpImage.tracks.TryGetValue(t, out SuperCardPro.TrackHeader scpTrack))
{
byte[] trackContents =
new byte[(scpTrack.entries.Last().dataOffset +
scpTrack.entries.Last().trackLength) - scpImage.header.offsets[t] +
1];
scpStream.Position = scpImage.header.offsets[t];
scpStream.Read(trackContents, 0, trackContents.Length);
scpBlockTrackType.Size = trackContents.Length;
scpBlockTrackType.Checksums = Checksum.GetChecksums(trackContents).ToArray();
}
scpBlockTrackTypes.Add(scpBlockTrackType);
}
if(scpImage.tracks.TryGetValue(t, out SuperCardPro.TrackHeader scpTrack))
{
byte[] trackContents =
new byte[(scpTrack.entries.Last().dataOffset +
scpTrack.entries.Last().trackLength) - scpImage.header.offsets[t] + 1];
scpStream.Position = scpImage.header.offsets[t];
scpStream.Read(trackContents, 0, trackContents.Length);
scpBlockTrackType.Size = trackContents.Length;
scpBlockTrackType.Checksums = Checksum.GetChecksums(trackContents).ToArray();
}
scpBlockTrackTypes.Add(scpBlockTrackType);
sidecar.BlockMedia[0].Track =
scpBlockTrackTypes.OrderBy(t => t.Cylinder).ThenBy(t => t.Head).ToArray();
}
sidecar.BlockMedia[0].Track =
scpBlockTrackTypes.OrderBy(t => t.Cylinder).ThenBy(t => t.Head).ToArray();
else
DicConsole.ErrorWriteLine(
"SuperCardPro image do not contain same number of tracks ({0}) than disk image ({1}), ignoring...",
scpImage.header.end + 1, image.ImageInfo.cylinders);
}
else
DicConsole.ErrorWriteLine("SuperCardPro image do not contain same number of tracks ({0}) than disk image ({1}), ignoring...", scpImage.header.end + 1, image.ImageInfo.cylinders);
DicConsole.ErrorWriteLine(
"SuperCardPro image do not contain same number of heads ({0}) than disk image ({1}), ignoring...",
2, image.ImageInfo.heads);
}
else
DicConsole.ErrorWriteLine("SuperCardPro image do not contain same number of heads ({0}) than disk image ({1}), ignoring...", 2, image.ImageInfo.heads);
}
#endregion
#region KryoFlux
string kfFile = null;
string basename = Path.Combine(Path.GetDirectoryName(imagePath),
Path.GetFileNameWithoutExtension(imagePath));
bool kfDir = false;
if(Directory.Exists(basename))
{
string[] possibleKfStarts = Directory.GetFiles(basename, "*.raw", SearchOption.TopDirectoryOnly);
if(possibleKfStarts.Length > 0)
{
kfFile = possibleKfStarts[0];
kfDir = true;
}
}
else if(File.Exists(basename + "00.0.raw"))
kfFile = basename + "00.0.raw";
else if(File.Exists(basename + "00.1.raw"))
kfFile = basename + "00.1.raw";
if(kfFile != null)
{
ImagePlugins.KryoFlux kfImage = new KryoFlux();
Filters.ZZZNoFilter kfFilter = new ZZZNoFilter();
kfFilter.Open(kfFile);
if(image.ImageInfo.heads <= 2 && kfImage.IdentifyImage(kfFilter))
{
try
{
kfImage.OpenImage(kfFilter);
}
catch(NotImplementedException)
{
}
if(kfImage.ImageInfo.heads == image.ImageInfo.heads)
{
if(kfImage.ImageInfo.cylinders >= image.ImageInfo.cylinders)
{
List<BlockTrackType> kfBlockTrackTypes = new List<BlockTrackType>();
long currentSector = 0;
foreach(KeyValuePair<byte, Filter> kvp in kfImage.tracks)
{
BlockTrackType kfBlockTrackType = new BlockTrackType();
kfBlockTrackType.Cylinder = kvp.Key / image.ImageInfo.heads;
kfBlockTrackType.Head = kvp.Key % image.ImageInfo.heads;
kfBlockTrackType.Image = new ImageType();
kfBlockTrackType.Image.format = kfImage.GetImageFormat();
kfBlockTrackType.Image.Value =
kfDir
? Path.Combine(Path.GetFileName(Path.GetDirectoryName(kvp.Value.GetBasePath())), kvp.Value.GetFilename())
: kvp.Value.GetFilename();
kfBlockTrackType.Image.offset = 0;
if(kfBlockTrackType.Cylinder < image.ImageInfo.cylinders)
{
kfBlockTrackType.StartSector = currentSector;
currentSector += image.ImageInfo.sectorsPerTrack;
kfBlockTrackType.EndSector = currentSector - 1;
kfBlockTrackType.Sectors = image.ImageInfo.sectorsPerTrack;
kfBlockTrackType.BytesPerSector = (int)image.ImageInfo.sectorSize;
kfBlockTrackType.Format = trkFormat;
}
Stream kfStream = kvp.Value.GetDataForkStream();
byte[] trackContents = new byte[kfStream.Length];
kfStream.Position = 0;
kfStream.Read(trackContents, 0, trackContents.Length);
kfBlockTrackType.Size = trackContents.Length;
kfBlockTrackType.Checksums = Checksum.GetChecksums(trackContents).ToArray();
kfBlockTrackTypes.Add(kfBlockTrackType);
}
sidecar.BlockMedia[0].Track =
kfBlockTrackTypes.OrderBy(t => t.Cylinder).ThenBy(t => t.Head).ToArray();
}
else
DicConsole.ErrorWriteLine(
"KryoFlux image do not contain same number of tracks ({0}) than disk image ({1}), ignoring...",
kfImage.ImageInfo.cylinders, image.ImageInfo.cylinders);
}
else
DicConsole.ErrorWriteLine(
"KryoFluximage do not contain same number of heads ({0}) than disk image ({1}), ignoring...",
kfImage.ImageInfo.heads, image.ImageInfo.heads);
}
}
#endregion
// TODO: Implement support for getting CHS from SCSI mode pages
}
}