mirror of
https://github.com/aaru-dps/Aaru.Server.git
synced 2025-12-16 19:24:27 +00:00
Added preliminary support for KryoFlux STREAM disk image format (only sidecar creation)
This commit is contained in:
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user