mirror of
https://github.com/aaru-dps/Aaru.git
synced 2025-12-16 19:24:25 +00:00
Added support for floppy leadout.
This commit is contained in:
@@ -693,7 +693,9 @@ namespace DiscImageChef.ImagePlugins
|
|||||||
/// <summary>MultiMediaCard Extended CSD</summary>
|
/// <summary>MultiMediaCard Extended CSD</summary>
|
||||||
MMC_ExtendedCSD,
|
MMC_ExtendedCSD,
|
||||||
/// <summary>Xbox Security Sector</summary>
|
/// <summary>Xbox Security Sector</summary>
|
||||||
Xbox_SecuritySector
|
Xbox_SecuritySector,
|
||||||
|
/// <summary>On floppy disks, data in last cylinder usually in a different format that contains duplication or manufacturing information</summary>
|
||||||
|
Floppy_LeadOut,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|||||||
@@ -202,6 +202,7 @@ namespace DiscImageChef.ImagePlugins
|
|||||||
// Cylinder by head, sector data matrix
|
// Cylinder by head, sector data matrix
|
||||||
byte[][][][] sectorsData;
|
byte[][][][] sectorsData;
|
||||||
Stream inStream;
|
Stream inStream;
|
||||||
|
byte[] leadOut;
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
@@ -479,16 +480,12 @@ namespace DiscImageChef.ImagePlugins
|
|||||||
if(TDTrack.sectors == 0xFF) // End of disk image
|
if(TDTrack.sectors == 0xFF) // End of disk image
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if(TDTrack.sectors < ImageInfo.sectorsPerTrack)
|
|
||||||
ImageInfo.sectorsPerTrack = TDTrack.sectors;
|
|
||||||
|
|
||||||
for(byte processedSectors = 0; processedSectors < TDTrack.sectors; processedSectors++)
|
for(byte processedSectors = 0; processedSectors < TDTrack.sectors; processedSectors++)
|
||||||
{
|
{
|
||||||
TDSectorHeader TDSector = new TDSectorHeader();
|
TDSectorHeader TDSector = new TDSectorHeader();
|
||||||
TDDataHeader TDData = new TDDataHeader();
|
TDDataHeader TDData = new TDDataHeader();
|
||||||
byte[] dataSizeBytes = new byte[2];
|
byte[] dataSizeBytes = new byte[2];
|
||||||
byte[] data;
|
byte[] data;
|
||||||
byte[] decodedData;
|
|
||||||
|
|
||||||
TDSector.cylinder = (byte)stream.ReadByte();
|
TDSector.cylinder = (byte)stream.ReadByte();
|
||||||
TDSector.head = (byte)stream.ReadByte();
|
TDSector.head = (byte)stream.ReadByte();
|
||||||
@@ -505,7 +502,6 @@ namespace DiscImageChef.ImagePlugins
|
|||||||
stream.Read(dataSizeBytes, 0, 2);
|
stream.Read(dataSizeBytes, 0, 2);
|
||||||
TDData.dataSize = BitConverter.ToUInt16(dataSizeBytes, 0);
|
TDData.dataSize = BitConverter.ToUInt16(dataSizeBytes, 0);
|
||||||
TDData.dataSize--; // Sydex decided to including dataEncoding byte as part of it
|
TDData.dataSize--; // Sydex decided to including dataEncoding byte as part of it
|
||||||
ImageInfo.imageSize += TDData.dataSize;
|
|
||||||
TDData.dataEncoding = (byte)stream.ReadByte();
|
TDData.dataEncoding = (byte)stream.ReadByte();
|
||||||
data = new byte[TDData.dataSize];
|
data = new byte[TDData.dataSize];
|
||||||
stream.Read(data, 0, TDData.dataSize);
|
stream.Read(data, 0, TDData.dataSize);
|
||||||
@@ -524,13 +520,67 @@ namespace DiscImageChef.ImagePlugins
|
|||||||
if(totalCylinders <= 0 || totalHeads <= 0)
|
if(totalCylinders <= 0 || totalHeads <= 0)
|
||||||
throw new ImageNotSupportedException("No cylinders or heads found");
|
throw new ImageNotSupportedException("No cylinders or heads found");
|
||||||
|
|
||||||
|
bool hasLeadOutOnHead0 = false;
|
||||||
|
bool hasLeadOutOnHead1 = false;
|
||||||
|
ImageInfo.cylinders = (ushort)totalCylinders;
|
||||||
|
ImageInfo.heads = (byte)totalHeads;
|
||||||
|
|
||||||
|
// Count sectors per track
|
||||||
|
stream.Seek(currentPos, SeekOrigin.Begin);
|
||||||
|
while(true)
|
||||||
|
{
|
||||||
|
TDTrackHeader TDTrack = new TDTrackHeader();
|
||||||
|
|
||||||
|
TDTrack.sectors = (byte)stream.ReadByte();
|
||||||
|
TDTrack.cylinder = (byte)stream.ReadByte();
|
||||||
|
TDTrack.head = (byte)stream.ReadByte();
|
||||||
|
TDTrack.crc = (byte)stream.ReadByte();
|
||||||
|
|
||||||
|
if(TDTrack.sectors == 0xFF) // End of disk image
|
||||||
|
break;
|
||||||
|
|
||||||
|
if(TDTrack.sectors < ImageInfo.sectorsPerTrack)
|
||||||
|
{
|
||||||
|
if(TDTrack.cylinder + 1 == totalCylinders)
|
||||||
|
{
|
||||||
|
hasLeadOutOnHead0 |= TDTrack.head == 0;
|
||||||
|
hasLeadOutOnHead1 |= TDTrack.head == 1;
|
||||||
|
if(ImageInfo.cylinders == totalCylinders)
|
||||||
|
ImageInfo.cylinders--;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
ImageInfo.sectorsPerTrack = TDTrack.sectors;
|
||||||
|
}
|
||||||
|
for(byte processedSectors = 0; processedSectors < TDTrack.sectors; processedSectors++)
|
||||||
|
{
|
||||||
|
TDSectorHeader TDSector = new TDSectorHeader();
|
||||||
|
TDDataHeader TDData = new TDDataHeader();
|
||||||
|
byte[] dataSizeBytes = new byte[2];
|
||||||
|
byte[] data;
|
||||||
|
|
||||||
|
TDSector.cylinder = (byte)stream.ReadByte();
|
||||||
|
TDSector.head = (byte)stream.ReadByte();
|
||||||
|
TDSector.sectorNumber = (byte)stream.ReadByte();
|
||||||
|
TDSector.sectorSize = (byte)stream.ReadByte();
|
||||||
|
TDSector.flags = (byte)stream.ReadByte();
|
||||||
|
TDSector.crc = (byte)stream.ReadByte();
|
||||||
|
|
||||||
|
if((TDSector.flags & FlagsSectorDataless) != FlagsSectorDataless && (TDSector.flags & FlagsSectorSkipped) != FlagsSectorSkipped)
|
||||||
|
{
|
||||||
|
stream.Read(dataSizeBytes, 0, 2);
|
||||||
|
TDData.dataSize = BitConverter.ToUInt16(dataSizeBytes, 0);
|
||||||
|
TDData.dataSize--; // Sydex decided to including dataEncoding byte as part of it
|
||||||
|
TDData.dataEncoding = (byte)stream.ReadByte();
|
||||||
|
data = new byte[TDData.dataSize];
|
||||||
|
stream.Read(data, 0, TDData.dataSize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
sectorsData = new byte[totalCylinders][][][];
|
sectorsData = new byte[totalCylinders][][][];
|
||||||
// Total sectors per track
|
// Total sectors per track
|
||||||
uint[][] spts = new uint[totalCylinders][];
|
uint[][] spts = new uint[totalCylinders][];
|
||||||
|
|
||||||
ImageInfo.cylinders = (ushort)totalCylinders;
|
|
||||||
ImageInfo.heads = (byte)totalHeads;
|
|
||||||
|
|
||||||
DicConsole.DebugWriteLine("TeleDisk plugin", "Found {0} cylinders and {1} heads with a maximum sector number of {2}", totalCylinders, totalHeads, maxSector);
|
DicConsole.DebugWriteLine("TeleDisk plugin", "Found {0} cylinders and {1} heads with a maximum sector number of {2}", totalCylinders, totalHeads, maxSector);
|
||||||
|
|
||||||
// Create heads
|
// Create heads
|
||||||
@@ -654,6 +704,29 @@ namespace DiscImageChef.ImagePlugins
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MemoryStream leadOutMs = new MemoryStream();
|
||||||
|
if(hasLeadOutOnHead0)
|
||||||
|
{
|
||||||
|
for(int i = 0; i < sectorsData[totalCylinders - 1][0].Length; i++)
|
||||||
|
{
|
||||||
|
if(sectorsData[totalCylinders - 1][0][i] != null)
|
||||||
|
leadOutMs.Write(sectorsData[totalCylinders - 1][0][i], 0, sectorsData[totalCylinders - 1][0][i].Length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(hasLeadOutOnHead1)
|
||||||
|
{
|
||||||
|
for(int i = 0; i < sectorsData[totalCylinders - 1][1].Length; i++)
|
||||||
|
{
|
||||||
|
if(sectorsData[totalCylinders - 1][1][i] != null)
|
||||||
|
leadOutMs.Write(sectorsData[totalCylinders - 1][1][i], 0, sectorsData[totalCylinders - 1][1][i].Length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(leadOutMs.Length != 0)
|
||||||
|
{
|
||||||
|
leadOut = leadOutMs.ToArray();
|
||||||
|
ImageInfo.readableMediaTags.Add(MediaTagType.Floppy_LeadOut);
|
||||||
|
}
|
||||||
|
|
||||||
ImageInfo.sectors = ImageInfo.cylinders * ImageInfo.heads * ImageInfo.sectorsPerTrack;
|
ImageInfo.sectors = ImageInfo.cylinders * ImageInfo.heads * ImageInfo.sectorsPerTrack;
|
||||||
ImageInfo.mediaType = DecodeTeleDiskDiskType();
|
ImageInfo.mediaType = DecodeTeleDiskDiskType();
|
||||||
|
|
||||||
@@ -666,6 +739,13 @@ namespace DiscImageChef.ImagePlugins
|
|||||||
inStream.Dispose();
|
inStream.Dispose();
|
||||||
stream.Dispose();
|
stream.Dispose();
|
||||||
|
|
||||||
|
/*
|
||||||
|
FileStream debugFs = new FileStream("debug.img", FileMode.CreateNew, FileAccess.Write);
|
||||||
|
for(ulong i = 0; i < ImageInfo.sectors; i++)
|
||||||
|
debugFs.Write(ReadSector(i), 0, (int)ImageInfo.sectorSize);
|
||||||
|
debugFs.Dispose();
|
||||||
|
*/
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -717,6 +797,8 @@ namespace DiscImageChef.ImagePlugins
|
|||||||
for(uint i = 0; i < length; i++)
|
for(uint i = 0; i < length; i++)
|
||||||
{
|
{
|
||||||
byte[] sector = ReadSector(sectorAddress + i);
|
byte[] sector = ReadSector(sectorAddress + i);
|
||||||
|
if(sector == null)
|
||||||
|
sector = new byte[ImageInfo.sectorSize];
|
||||||
buffer.Write(sector, 0, sector.Length);
|
buffer.Write(sector, 0, sector.Length);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1128,6 +1210,18 @@ namespace DiscImageChef.ImagePlugins
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override byte[] ReadDiskTag(MediaTagType tag)
|
||||||
|
{
|
||||||
|
if(tag == MediaTagType.Floppy_LeadOut)
|
||||||
|
{
|
||||||
|
if(leadOut != null)
|
||||||
|
return leadOut;
|
||||||
|
throw new FeatureNotPresentImageException("Lead-out not present in disk image");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
throw new FeatureUnsupportedImageException("Feature not supported by image format");
|
||||||
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
#region Unsupported features
|
#region Unsupported features
|
||||||
@@ -1142,11 +1236,6 @@ namespace DiscImageChef.ImagePlugins
|
|||||||
throw new FeatureUnsupportedImageException("Feature not supported by image format");
|
throw new FeatureUnsupportedImageException("Feature not supported by image format");
|
||||||
}
|
}
|
||||||
|
|
||||||
public override byte[] ReadDiskTag(MediaTagType tag)
|
|
||||||
{
|
|
||||||
throw new FeatureUnsupportedImageException("Feature not supported by image format");
|
|
||||||
}
|
|
||||||
|
|
||||||
public override string GetImageCreator()
|
public override string GetImageCreator()
|
||||||
{
|
{
|
||||||
return ImageInfo.imageCreator;
|
return ImageInfo.imageCreator;
|
||||||
|
|||||||
Reference in New Issue
Block a user