Add support for 13-sector Apple DOS images. Fixes #551

This commit is contained in:
2021-06-08 03:10:42 +01:00
parent a3c498aa0f
commit 4957f37bec
4 changed files with 70 additions and 45 deletions

View File

@@ -41,6 +41,7 @@ namespace Aaru.DiscImages
public sealed partial class AppleDos : IWritableImage
{
byte[] _deinterleaved;
bool _dos32;
string _extension;
ImageInfo _imageInfo;
FileStream _writingStream;

View File

@@ -48,26 +48,35 @@ namespace Aaru.DiscImages
byte[] tmp = new byte[imageFilter.GetDataForkLength()];
stream.Read(tmp, 0, tmp.Length);
bool isDos = tmp[0x11001] == 17 && tmp[0x11002] < 16 && tmp[0x11027] <= 122 && tmp[0x11034] == 35 &&
tmp[0x11035] == 16 && tmp[0x11036] == 0 && tmp[0x11037] == 1;
_deinterleaved = new byte[tmp.Length];
_extension = Path.GetExtension(imageFilter.GetFilename())?.ToLower();
int[] offsets = _extension == ".do"
? isDos
? _deinterleave
: _interleave
: isDos
? _interleave
: _deinterleave;
for(int t = 0; t < 35; t++)
if((_extension == ".d13" || _extension == ".do") &&
tmp.Length == 116480)
{
for(int s = 0; s < 16; s++)
Array.Copy(tmp, (t * 16 * 256) + (s * 256), _deinterleaved, (t * 16 * 256) + (offsets[s] * 256),
256);
_dos32 = true;
_deinterleaved = tmp;
}
else
{
bool isDos = tmp[0x11001] == 17 && tmp[0x11002] < 16 && tmp[0x11027] <= 122 && tmp[0x11034] == 35 &&
tmp[0x11035] == 16 && tmp[0x11036] == 0 && tmp[0x11037] == 1;
_deinterleaved = new byte[tmp.Length];
int[] offsets = _extension == ".do"
? isDos
? _deinterleave
: _interleave
: isDos
? _interleave
: _deinterleave;
for(int t = 0; t < 35; t++)
{
for(int s = 0; s < 16; s++)
Array.Copy(tmp, (t * 16 * 256) + (s * 256), _deinterleaved, (t * 16 * 256) + (offsets[s] * 256),
256);
}
}
_imageInfo.SectorSize = 256;
@@ -75,12 +84,12 @@ namespace Aaru.DiscImages
_imageInfo.CreationTime = imageFilter.GetCreationTime();
_imageInfo.LastModificationTime = imageFilter.GetLastWriteTime();
_imageInfo.MediaTitle = Path.GetFileNameWithoutExtension(imageFilter.GetFilename());
_imageInfo.Sectors = 560;
_imageInfo.MediaType = MediaType.Apple33SS;
_imageInfo.Sectors = _dos32 ? 455u : 560u;
_imageInfo.MediaType = _dos32 ? MediaType.Apple32SS : MediaType.Apple33SS;
_imageInfo.XmlMediaType = XmlMediaType.BlockMedia;
_imageInfo.Cylinders = 35;
_imageInfo.Heads = 2;
_imageInfo.SectorsPerTrack = 16;
_imageInfo.Heads = 1;
_imageInfo.SectorsPerTrack = _dos32 ? 13u : 16u;
return true;
}

View File

@@ -52,16 +52,18 @@ namespace Aaru.DiscImages
return false;
}
if(mediaType != MediaType.Apple33SS)
if(mediaType != MediaType.Apple32SS &&
mediaType != MediaType.Apple33SS)
{
ErrorMessage = $"Unsupported media format {mediaType}";
return false;
}
if(sectors > uint.MaxValue)
if((mediaType == MediaType.Apple32SS && sectors != 455) ||
(mediaType == MediaType.Apple33SS && sectors != 560))
{
ErrorMessage = "Too many sectors";
ErrorMessage = "Incorrect number of sectors for media";
return false;
}
@@ -84,8 +86,15 @@ namespace Aaru.DiscImages
return false;
}
_deinterleaved = new byte[35 * 16 * 256];
_extension = Path.GetExtension(path);
_extension = Path.GetExtension(path);
if(mediaType == MediaType.Apple32SS)
{
_dos32 = true;
_extension = ".d13";
}
_deinterleaved = new byte[35 * (_dos32 ? 13 : 16) * 256];
IsWriting = true;
ErrorMessage = null;
@@ -155,25 +164,31 @@ namespace Aaru.DiscImages
return false;
}
bool isDos = _deinterleaved[0x11001] == 17 && _deinterleaved[0x11002] < 16 &&
_deinterleaved[0x11027] <= 122 && _deinterleaved[0x11034] == 35 &&
_deinterleaved[0x11035] == 16 && _deinterleaved[0x11036] == 0 && _deinterleaved[0x11037] == 1;
byte[] tmp;
byte[] tmp = new byte[_deinterleaved.Length];
int[] offsets = _extension == ".do"
? isDos
? _deinterleave
: _interleave
: isDos
? _interleave
: _deinterleave;
for(int t = 0; t < 35; t++)
if(_dos32)
tmp = _deinterleaved;
else
{
for(int s = 0; s < 16; s++)
Array.Copy(_deinterleaved, (t * 16 * 256) + (offsets[s] * 256), tmp, (t * 16 * 256) + (s * 256),
256);
bool isDos = _deinterleaved[0x11001] == 17 && _deinterleaved[0x11002] < 16 &&
_deinterleaved[0x11027] <= 122 && _deinterleaved[0x11034] == 35 &&
_deinterleaved[0x11035] == 16 && _deinterleaved[0x11036] == 0 &&
_deinterleaved[0x11037] == 1;
tmp = new byte[_deinterleaved.Length];
int[] offsets = _extension == ".do"
? isDos
? _deinterleave
: _interleave
: isDos
? _interleave
: _deinterleave;
for(int t = 0; t < 35; t++)
for(int s = 0; s < 16; s++)
Array.Copy(_deinterleaved, (t * 16 * 256) + (offsets[s] * 256), tmp, (t * 16 * 256) + (s * 256),
256);
}
_writingStream.Seek(0, SeekOrigin.Begin);

View File

@@ -47,9 +47,9 @@ namespace Aaru.Tests.Images.AppleDOS
{
TestFile = "alice.d13.lz",
MediaType = MediaType.Apple32SS,
Sectors = 560,
Sectors = 455,
SectorSize = 256,
MD5 = "UNKNOWN"
MD5 = "76f8fe4c5bc1976f99641ad7cdf53109"
}
};
}