mirror of
https://github.com/aaru-dps/Aaru.git
synced 2025-12-16 19:24:25 +00:00
REFACTOR: All refactor in DiscImageChef.Filesystems.
This commit is contained in:
@@ -113,16 +113,15 @@ namespace DiscImageChef.Filesystems.CPM
|
||||
public CPM()
|
||||
{
|
||||
Name = "CP/M File System";
|
||||
PluginUUID = new Guid("AA2B8585-41DF-4E3B-8A35-D1A935E2F8A1");
|
||||
PluginUuid = new Guid("AA2B8585-41DF-4E3B-8A35-D1A935E2F8A1");
|
||||
CurrentEncoding = Encoding.GetEncoding("IBM437");
|
||||
}
|
||||
|
||||
public CPM(Encoding encoding)
|
||||
{
|
||||
Name = "CP/M File System";
|
||||
PluginUUID = new Guid("AA2B8585-41DF-4E3B-8A35-D1A935E2F8A1");
|
||||
if(encoding == null) CurrentEncoding = Encoding.GetEncoding("IBM437");
|
||||
else CurrentEncoding = encoding;
|
||||
PluginUuid = new Guid("AA2B8585-41DF-4E3B-8A35-D1A935E2F8A1");
|
||||
CurrentEncoding = encoding ?? Encoding.GetEncoding("IBM437");
|
||||
}
|
||||
|
||||
public CPM(ImagePlugin imagePlugin, Partition partition, Encoding encoding)
|
||||
@@ -130,9 +129,8 @@ namespace DiscImageChef.Filesystems.CPM
|
||||
device = imagePlugin;
|
||||
this.partition = partition;
|
||||
Name = "CP/M File System";
|
||||
PluginUUID = new Guid("AA2B8585-41DF-4E3B-8A35-D1A935E2F8A1");
|
||||
if(encoding == null) CurrentEncoding = Encoding.GetEncoding("IBM437");
|
||||
else CurrentEncoding = encoding;
|
||||
PluginUuid = new Guid("AA2B8585-41DF-4E3B-8A35-D1A935E2F8A1");
|
||||
CurrentEncoding = encoding ?? Encoding.GetEncoding("IBM437");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -59,18 +59,14 @@ namespace DiscImageChef.Filesystems.CPM
|
||||
{
|
||||
if(def.side1 == null)
|
||||
{
|
||||
def.side1 = new Side();
|
||||
def.side1.sideId = 0;
|
||||
def.side1.sectorIds = new int[def.sectorsPerTrack];
|
||||
def.side1 = new Side {sideId = 0, sectorIds = new int[def.sectorsPerTrack]};
|
||||
for(int i = 0; i < def.sectorsPerTrack; i++) def.side1.sectorIds[i] = i + 1;
|
||||
}
|
||||
|
||||
if(def.sides != 2 || def.side2 != null) continue;
|
||||
|
||||
{
|
||||
def.side2 = new Side();
|
||||
def.side2.sideId = 1;
|
||||
def.side2.sectorIds = new int[def.sectorsPerTrack];
|
||||
def.side2 = new Side {sideId = 1, sectorIds = new int[def.sectorsPerTrack]};
|
||||
for(int i = 0; i < def.sectorsPerTrack; i++) def.side2.sectorIds[i] = i + 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -69,10 +69,9 @@ namespace DiscImageChef.Filesystems.CPM
|
||||
|
||||
for(int off = 0; off < directory.Length; off += 32)
|
||||
{
|
||||
DirectoryEntry entry;
|
||||
IntPtr dirPtr = Marshal.AllocHGlobal(32);
|
||||
Marshal.Copy(directory, off, dirPtr, 32);
|
||||
entry = (DirectoryEntry)Marshal.PtrToStructure(dirPtr, typeof(DirectoryEntry));
|
||||
DirectoryEntry entry = (DirectoryEntry)Marshal.PtrToStructure(dirPtr, typeof(DirectoryEntry));
|
||||
Marshal.FreeHGlobal(dirPtr);
|
||||
|
||||
if((entry.statusUser & 0x7F) < 0x20)
|
||||
|
||||
@@ -43,8 +43,6 @@ namespace DiscImageChef.Filesystems.CPM
|
||||
string[] pathElements = path.Split(new[] {'/'}, StringSplitOptions.RemoveEmptyEntries);
|
||||
if(pathElements.Length != 1) return Errno.NotSupported;
|
||||
|
||||
FileEntryInfo fInfo;
|
||||
|
||||
if(string.IsNullOrEmpty(pathElements[0]) ||
|
||||
string.Compare(pathElements[0], "/", StringComparison.OrdinalIgnoreCase) == 0)
|
||||
{
|
||||
@@ -53,18 +51,16 @@ namespace DiscImageChef.Filesystems.CPM
|
||||
return Errno.NoError;
|
||||
}
|
||||
|
||||
if(!statCache.TryGetValue(pathElements[0].ToUpperInvariant(), out fInfo)) return Errno.NoSuchFile;
|
||||
if(!statCache.TryGetValue(pathElements[0].ToUpperInvariant(), out FileEntryInfo fInfo)) return Errno.NoSuchFile;
|
||||
|
||||
attributes = fInfo.Attributes;
|
||||
return Errno.NoError;
|
||||
}
|
||||
|
||||
// TODO: Implementing this would require storing the interleaving
|
||||
public override Errno MapBlock(string path, long fileBlock, ref long deviceBlock)
|
||||
{
|
||||
if(!mounted) return Errno.AccessDenied;
|
||||
|
||||
// TODO: Implementing this would require storing the interleaving
|
||||
return Errno.NotImplemented;
|
||||
return !mounted ? Errno.AccessDenied : Errno.NotImplemented;
|
||||
}
|
||||
|
||||
public override Errno Read(string path, long offset, long size, ref byte[] buf)
|
||||
@@ -82,9 +78,7 @@ namespace DiscImageChef.Filesystems.CPM
|
||||
string[] pathElements = path.Split(new[] {'/'}, StringSplitOptions.RemoveEmptyEntries);
|
||||
if(pathElements.Length != 1) return Errno.NotSupported;
|
||||
|
||||
byte[] file;
|
||||
|
||||
if(!fileCache.TryGetValue(pathElements[0].ToUpperInvariant(), out file)) return Errno.NoSuchFile;
|
||||
if(!fileCache.TryGetValue(pathElements[0].ToUpperInvariant(), out byte[] file)) return Errno.NoSuchFile;
|
||||
|
||||
if(offset >= file.Length) return Errno.EINVAL;
|
||||
|
||||
@@ -114,7 +108,7 @@ namespace DiscImageChef.Filesystems.CPM
|
||||
if(labelCreationDate != null) stat.CreationTime = DateHandlers.CPMToDateTime(labelCreationDate);
|
||||
if(labelUpdateDate != null) stat.StatusChangeTime = DateHandlers.CPMToDateTime(labelUpdateDate);
|
||||
stat.Attributes = FileAttributes.Directory;
|
||||
stat.BlockSize = xmlFSType.ClusterSize;
|
||||
stat.BlockSize = XmlFsType.ClusterSize;
|
||||
return Errno.NoError;
|
||||
}
|
||||
|
||||
|
||||
@@ -164,9 +164,7 @@ namespace DiscImageChef.Filesystems.CPM
|
||||
try
|
||||
{
|
||||
byte[] sector;
|
||||
ulong sectorCount;
|
||||
ulong sectorSize;
|
||||
ulong sides;
|
||||
ulong firstDirectorySector;
|
||||
byte[] directory = null;
|
||||
workingDefinition = null;
|
||||
@@ -200,8 +198,8 @@ namespace DiscImageChef.Filesystems.CPM
|
||||
amsSb.format == 2 && (amsSb.sidedness & 0x02) == 2)
|
||||
{
|
||||
// Calculate device limits
|
||||
sides = (ulong)(amsSb.format == 0 ? 1 : 2);
|
||||
sectorCount = (ulong)(amsSb.tps * amsSb.spt * (byte)sides);
|
||||
ulong sides = (ulong)(amsSb.format == 0 ? 1 : 2);
|
||||
ulong sectorCount = (ulong)(amsSb.tps * amsSb.spt * (byte)sides);
|
||||
sectorSize = (ulong)(128 << amsSb.psh);
|
||||
|
||||
// Compare device limits from superblock to real limits
|
||||
@@ -211,10 +209,12 @@ namespace DiscImageChef.Filesystems.CPM
|
||||
firstDirectorySector = (ulong)(amsSb.off * amsSb.spt);
|
||||
|
||||
// Build a DiscParameterBlock
|
||||
dpb = new DiscParameterBlock();
|
||||
dpb.al0 = sectorCount == 1440 ? (byte)0xF0 : (byte)0xC0;
|
||||
dpb.spt = amsSb.spt;
|
||||
dpb.bsh = amsSb.bsh;
|
||||
dpb = new DiscParameterBlock
|
||||
{
|
||||
al0 = sectorCount == 1440 ? (byte)0xF0 : (byte)0xC0,
|
||||
spt = amsSb.spt,
|
||||
bsh = amsSb.bsh
|
||||
};
|
||||
for(int i = 0; i < dpb.bsh; i++) dpb.blm += (byte)Math.Pow(2, i);
|
||||
|
||||
if(sectorCount >= 1440)
|
||||
@@ -239,27 +239,27 @@ namespace DiscImageChef.Filesystems.CPM
|
||||
directoryLength);
|
||||
|
||||
// Build a CP/M disk definition
|
||||
workingDefinition = new CpmDefinition();
|
||||
workingDefinition.al0 = dpb.al0;
|
||||
workingDefinition.al1 = dpb.al1;
|
||||
workingDefinition.bitrate = "LOW";
|
||||
workingDefinition.blm = dpb.blm;
|
||||
workingDefinition.bsh = dpb.bsh;
|
||||
workingDefinition.bytesPerSector = 512;
|
||||
workingDefinition.cylinders = amsSb.tps;
|
||||
workingDefinition.drm = dpb.drm;
|
||||
workingDefinition.dsm = dpb.dsm;
|
||||
workingDefinition.encoding = "MFM";
|
||||
workingDefinition.evenOdd = false;
|
||||
workingDefinition.exm = dpb.exm;
|
||||
workingDefinition.label = null;
|
||||
workingDefinition.comment = "Amstrad PCW superblock";
|
||||
workingDefinition.ofs = dpb.off;
|
||||
workingDefinition.sectorsPerTrack = amsSb.spt;
|
||||
workingDefinition = new CpmDefinition
|
||||
{
|
||||
al0 = dpb.al0,
|
||||
al1 = dpb.al1,
|
||||
bitrate = "LOW",
|
||||
blm = dpb.blm,
|
||||
bsh = dpb.bsh,
|
||||
bytesPerSector = 512,
|
||||
cylinders = amsSb.tps,
|
||||
drm = dpb.drm,
|
||||
dsm = dpb.dsm,
|
||||
encoding = "MFM",
|
||||
evenOdd = false,
|
||||
exm = dpb.exm,
|
||||
label = null,
|
||||
comment = "Amstrad PCW superblock",
|
||||
ofs = dpb.off,
|
||||
sectorsPerTrack = amsSb.spt,
|
||||
side1 = new Side {sideId = 0, sectorIds = new int[amsSb.spt]}
|
||||
};
|
||||
|
||||
workingDefinition.side1 = new Side();
|
||||
workingDefinition.side1.sideId = 0;
|
||||
workingDefinition.side1.sectorIds = new int[amsSb.spt];
|
||||
for(int si = 0; si < amsSb.spt; si++) workingDefinition.side1.sectorIds[si] = si + 1;
|
||||
|
||||
if(amsSb.format == 2)
|
||||
@@ -273,9 +273,7 @@ namespace DiscImageChef.Filesystems.CPM
|
||||
break;
|
||||
}
|
||||
|
||||
workingDefinition.side2 = new Side();
|
||||
workingDefinition.side2.sideId = 1;
|
||||
workingDefinition.side2.sectorIds = new int[amsSb.spt];
|
||||
workingDefinition.side2 = new Side {sideId = 1, sectorIds = new int[amsSb.spt]};
|
||||
for(int si = 0; si < amsSb.spt; si++) workingDefinition.side2.sectorIds[si] = si + 1;
|
||||
}
|
||||
else workingDefinition.order = null;
|
||||
@@ -323,56 +321,59 @@ namespace DiscImageChef.Filesystems.CPM
|
||||
firstDirectorySector = (ulong)(hddSb.off * hddSb.sectorsPerTrack);
|
||||
|
||||
// Build a DiscParameterBlock
|
||||
dpb = new DiscParameterBlock();
|
||||
dpb.al0 = (byte)hddSb.al0;
|
||||
dpb.al1 = (byte)hddSb.al1;
|
||||
dpb.blm = hddSb.blm;
|
||||
dpb.bsh = hddSb.bsh;
|
||||
dpb.cks = hddSb.cks;
|
||||
dpb.drm = hddSb.drm;
|
||||
dpb.dsm = hddSb.dsm;
|
||||
dpb.exm = hddSb.exm;
|
||||
dpb.off = hddSb.off;
|
||||
dpb.phm = 0; // Needed?
|
||||
dpb.psh = 0; // Needed?
|
||||
dpb.spt = hddSb.spt;
|
||||
dpb = new DiscParameterBlock
|
||||
{
|
||||
al0 = (byte)hddSb.al0,
|
||||
al1 = (byte)hddSb.al1,
|
||||
blm = hddSb.blm,
|
||||
bsh = hddSb.bsh,
|
||||
cks = hddSb.cks,
|
||||
drm = hddSb.drm,
|
||||
dsm = hddSb.dsm,
|
||||
exm = hddSb.exm,
|
||||
off = hddSb.off,
|
||||
// Needed?
|
||||
phm = 0,
|
||||
// Needed?
|
||||
psh = 0,
|
||||
spt = hddSb.spt
|
||||
};
|
||||
|
||||
uint directoryLength = (uint)(((ulong)dpb.drm + 1) * 32 / sectorSize);
|
||||
directory = imagePlugin.ReadSectors(firstDirectorySector + partition.Start,
|
||||
directoryLength);
|
||||
DicConsole.DebugWriteLine("CP/M Plugin", "Found CP/M-86 hard disk superblock.");
|
||||
|
||||
// Build a CP/M disk definition
|
||||
workingDefinition = new CpmDefinition();
|
||||
workingDefinition.al0 = dpb.al0;
|
||||
workingDefinition.al1 = dpb.al1;
|
||||
workingDefinition.bitrate = "HIGH";
|
||||
workingDefinition.blm = dpb.blm;
|
||||
workingDefinition.bsh = dpb.bsh;
|
||||
workingDefinition.bytesPerSector = 512;
|
||||
workingDefinition.cylinders = hddSb.cylinders;
|
||||
workingDefinition.drm = dpb.drm;
|
||||
workingDefinition.dsm = dpb.dsm;
|
||||
workingDefinition.encoding = "MFM";
|
||||
workingDefinition.evenOdd = false;
|
||||
workingDefinition.exm = dpb.exm;
|
||||
workingDefinition.label = null;
|
||||
workingDefinition.comment = "CP/M-86 hard disk superblock";
|
||||
workingDefinition.ofs = dpb.off;
|
||||
workingDefinition.sectorsPerTrack = hddSb.sectorsPerTrack;
|
||||
workingDefinition.side1 = new Side();
|
||||
workingDefinition.side1.sideId = 0;
|
||||
workingDefinition.side1.sectorIds = new int[hddSb.sectorsPerTrack];
|
||||
workingDefinition = new CpmDefinition
|
||||
{
|
||||
al0 = dpb.al0,
|
||||
al1 = dpb.al1,
|
||||
bitrate = "HIGH",
|
||||
blm = dpb.blm,
|
||||
bsh = dpb.bsh,
|
||||
bytesPerSector = 512,
|
||||
cylinders = hddSb.cylinders,
|
||||
drm = dpb.drm,
|
||||
dsm = dpb.dsm,
|
||||
encoding = "MFM",
|
||||
evenOdd = false,
|
||||
exm = dpb.exm,
|
||||
label = null,
|
||||
comment = "CP/M-86 hard disk superblock",
|
||||
ofs = dpb.off,
|
||||
sectorsPerTrack = hddSb.sectorsPerTrack,
|
||||
side1 = new Side {sideId = 0, sectorIds = new int[hddSb.sectorsPerTrack]},
|
||||
order = "SIDES",
|
||||
side2 = new Side {sideId = 1, sectorIds = new int[hddSb.sectorsPerTrack]},
|
||||
skew = 0,
|
||||
sofs = 0
|
||||
};
|
||||
|
||||
for(int si = 0; si < hddSb.sectorsPerTrack; si++)
|
||||
workingDefinition.side1.sectorIds[si] = si + 1;
|
||||
|
||||
workingDefinition.order = "SIDES";
|
||||
workingDefinition.side2 = new Side();
|
||||
workingDefinition.side2.sideId = 1;
|
||||
workingDefinition.side2.sectorIds = new int[hddSb.sectorsPerTrack];
|
||||
for(int si = 0; si < hddSb.spt; si++) workingDefinition.side2.sectorIds[si] = si + 1;
|
||||
|
||||
workingDefinition.skew = 0;
|
||||
workingDefinition.sofs = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -404,44 +405,46 @@ namespace DiscImageChef.Filesystems.CPM
|
||||
{
|
||||
cpmFound = true;
|
||||
firstDirectorySector86 = 8;
|
||||
dpb = new DiscParameterBlock();
|
||||
dpb.al0 = 0xC0;
|
||||
dpb.al1 = 0;
|
||||
dpb.blm = 7;
|
||||
dpb.bsh = 3;
|
||||
dpb.cks = 0x10;
|
||||
dpb.drm = 0x3F;
|
||||
dpb.dsm = 0x9B;
|
||||
dpb.exm = 0;
|
||||
dpb.off = 1;
|
||||
dpb.phm = 3;
|
||||
dpb.psh = 2;
|
||||
dpb.spt = 8 * 4;
|
||||
dpb = new DiscParameterBlock
|
||||
{
|
||||
al0 = 0xC0,
|
||||
al1 = 0,
|
||||
blm = 7,
|
||||
bsh = 3,
|
||||
cks = 0x10,
|
||||
drm = 0x3F,
|
||||
dsm = 0x9B,
|
||||
exm = 0,
|
||||
off = 1,
|
||||
phm = 3,
|
||||
psh = 2,
|
||||
spt = 8 * 4
|
||||
};
|
||||
|
||||
workingDefinition = new CpmDefinition
|
||||
{
|
||||
al0 = dpb.al0,
|
||||
al1 = dpb.al1,
|
||||
bitrate = "LOW",
|
||||
blm = dpb.blm,
|
||||
bsh = dpb.bsh,
|
||||
bytesPerSector = 512,
|
||||
cylinders = 40,
|
||||
drm = dpb.drm,
|
||||
dsm = dpb.dsm,
|
||||
encoding = "MFM",
|
||||
evenOdd = false,
|
||||
exm = dpb.exm,
|
||||
label = null,
|
||||
comment = "CP/M-86 floppy identifier",
|
||||
ofs = dpb.off,
|
||||
sectorsPerTrack = 8,
|
||||
side1 = new Side {sideId = 0, sectorIds = new int[8]},
|
||||
skew = 0,
|
||||
sofs = 0
|
||||
};
|
||||
|
||||
workingDefinition = new CpmDefinition();
|
||||
workingDefinition.al0 = dpb.al0;
|
||||
workingDefinition.al1 = dpb.al1;
|
||||
workingDefinition.bitrate = "LOW";
|
||||
workingDefinition.blm = dpb.blm;
|
||||
workingDefinition.bsh = dpb.bsh;
|
||||
workingDefinition.bytesPerSector = 512;
|
||||
workingDefinition.cylinders = 40;
|
||||
workingDefinition.drm = dpb.drm;
|
||||
workingDefinition.dsm = dpb.dsm;
|
||||
workingDefinition.encoding = "MFM";
|
||||
workingDefinition.evenOdd = false;
|
||||
workingDefinition.exm = dpb.exm;
|
||||
workingDefinition.label = null;
|
||||
workingDefinition.comment = "CP/M-86 floppy identifier";
|
||||
workingDefinition.ofs = dpb.off;
|
||||
workingDefinition.sectorsPerTrack = 8;
|
||||
workingDefinition.side1 = new Side();
|
||||
workingDefinition.side1.sideId = 0;
|
||||
workingDefinition.side1.sectorIds = new int[8];
|
||||
for(int si = 0; si < 8; si++) workingDefinition.side1.sectorIds[si] = si + 1;
|
||||
|
||||
workingDefinition.skew = 0;
|
||||
workingDefinition.sofs = 0;
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -450,50 +453,49 @@ namespace DiscImageChef.Filesystems.CPM
|
||||
{
|
||||
cpmFound = true;
|
||||
firstDirectorySector86 = 16;
|
||||
dpb = new DiscParameterBlock();
|
||||
dpb.al0 = 0x80;
|
||||
dpb.al1 = 0;
|
||||
dpb.blm = 0x0F;
|
||||
dpb.bsh = 4;
|
||||
dpb.cks = 0x10;
|
||||
dpb.drm = 0x3F;
|
||||
dpb.dsm = 0x9D;
|
||||
dpb.exm = 1;
|
||||
dpb.off = 2;
|
||||
dpb.phm = 3;
|
||||
dpb.psh = 2;
|
||||
dpb.spt = 8 * 4;
|
||||
dpb = new DiscParameterBlock
|
||||
{
|
||||
al0 = 0x80,
|
||||
al1 = 0,
|
||||
blm = 0x0F,
|
||||
bsh = 4,
|
||||
cks = 0x10,
|
||||
drm = 0x3F,
|
||||
dsm = 0x9D,
|
||||
exm = 1,
|
||||
off = 2,
|
||||
phm = 3,
|
||||
psh = 2,
|
||||
spt = 8 * 4
|
||||
};
|
||||
|
||||
workingDefinition = new CpmDefinition
|
||||
{
|
||||
al0 = dpb.al0,
|
||||
al1 = dpb.al1,
|
||||
bitrate = "LOW",
|
||||
blm = dpb.blm,
|
||||
bsh = dpb.bsh,
|
||||
bytesPerSector = 512,
|
||||
cylinders = 40,
|
||||
drm = dpb.drm,
|
||||
dsm = dpb.dsm,
|
||||
encoding = "MFM",
|
||||
evenOdd = false,
|
||||
exm = dpb.exm,
|
||||
label = null,
|
||||
comment = "CP/M-86 floppy identifier",
|
||||
ofs = dpb.off,
|
||||
sectorsPerTrack = 8,
|
||||
side1 = new Side {sideId = 0, sectorIds = new int[8]},
|
||||
order = "SIDES",
|
||||
side2 = new Side {sideId = 1, sectorIds = new int[8]},
|
||||
skew = 0,
|
||||
sofs = 0
|
||||
};
|
||||
|
||||
workingDefinition = new CpmDefinition();
|
||||
workingDefinition.al0 = dpb.al0;
|
||||
workingDefinition.al1 = dpb.al1;
|
||||
workingDefinition.bitrate = "LOW";
|
||||
workingDefinition.blm = dpb.blm;
|
||||
workingDefinition.bsh = dpb.bsh;
|
||||
workingDefinition.bytesPerSector = 512;
|
||||
workingDefinition.cylinders = 40;
|
||||
workingDefinition.drm = dpb.drm;
|
||||
workingDefinition.dsm = dpb.dsm;
|
||||
workingDefinition.encoding = "MFM";
|
||||
workingDefinition.evenOdd = false;
|
||||
workingDefinition.exm = dpb.exm;
|
||||
workingDefinition.label = null;
|
||||
workingDefinition.comment = "CP/M-86 floppy identifier";
|
||||
workingDefinition.ofs = dpb.off;
|
||||
workingDefinition.sectorsPerTrack = 8;
|
||||
workingDefinition.side1 = new Side();
|
||||
workingDefinition.side1.sideId = 0;
|
||||
workingDefinition.side1.sectorIds = new int[8];
|
||||
for(int si = 0; si < 8; si++) workingDefinition.side1.sectorIds[si] = si + 1;
|
||||
|
||||
workingDefinition.order = "SIDES";
|
||||
workingDefinition.side2 = new Side();
|
||||
workingDefinition.side2.sideId = 1;
|
||||
workingDefinition.side2.sectorIds = new int[8];
|
||||
for(int si = 0; si < 8; si++) workingDefinition.side2.sectorIds[si] = si + 1;
|
||||
|
||||
workingDefinition.skew = 0;
|
||||
workingDefinition.sofs = 0;
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -504,50 +506,49 @@ namespace DiscImageChef.Filesystems.CPM
|
||||
{
|
||||
cpmFound = true;
|
||||
firstDirectorySector86 = 36;
|
||||
dpb = new DiscParameterBlock();
|
||||
dpb.al0 = 0x80;
|
||||
dpb.al1 = 0;
|
||||
dpb.blm = 0x0F;
|
||||
dpb.bsh = 4;
|
||||
dpb.cks = 0x10;
|
||||
dpb.drm = 0x3F;
|
||||
dpb.dsm = 0; // Unknown. Needed?
|
||||
dpb.exm = 1;
|
||||
dpb.off = 4;
|
||||
dpb.phm = 3;
|
||||
dpb.psh = 2;
|
||||
dpb.spt = 9 * 4;
|
||||
dpb = new DiscParameterBlock
|
||||
{
|
||||
al0 = 0x80,
|
||||
al1 = 0,
|
||||
blm = 0x0F,
|
||||
bsh = 4,
|
||||
cks = 0x10,
|
||||
drm = 0x3F,
|
||||
dsm = 0, // Unknown. Needed?
|
||||
exm = 1,
|
||||
off = 4,
|
||||
phm = 3,
|
||||
psh = 2,
|
||||
spt = 9 * 4
|
||||
};
|
||||
|
||||
workingDefinition = new CpmDefinition
|
||||
{
|
||||
al0 = dpb.al0,
|
||||
al1 = dpb.al1,
|
||||
bitrate = "LOW",
|
||||
blm = dpb.blm,
|
||||
bsh = dpb.bsh,
|
||||
bytesPerSector = 512,
|
||||
cylinders = 40,
|
||||
drm = dpb.drm,
|
||||
dsm = dpb.dsm,
|
||||
encoding = "MFM",
|
||||
evenOdd = false,
|
||||
exm = dpb.exm,
|
||||
label = null,
|
||||
comment = "CP/M-86 floppy identifier",
|
||||
ofs = dpb.off,
|
||||
sectorsPerTrack = 9,
|
||||
side1 = new Side {sideId = 0, sectorIds = new int[9]},
|
||||
order = "SIDES",
|
||||
side2 = new Side {sideId = 1, sectorIds = new int[9]},
|
||||
skew = 0,
|
||||
sofs = 0
|
||||
};
|
||||
|
||||
workingDefinition = new CpmDefinition();
|
||||
workingDefinition.al0 = dpb.al0;
|
||||
workingDefinition.al1 = dpb.al1;
|
||||
workingDefinition.bitrate = "LOW";
|
||||
workingDefinition.blm = dpb.blm;
|
||||
workingDefinition.bsh = dpb.bsh;
|
||||
workingDefinition.bytesPerSector = 512;
|
||||
workingDefinition.cylinders = 40;
|
||||
workingDefinition.drm = dpb.drm;
|
||||
workingDefinition.dsm = dpb.dsm;
|
||||
workingDefinition.encoding = "MFM";
|
||||
workingDefinition.evenOdd = false;
|
||||
workingDefinition.exm = dpb.exm;
|
||||
workingDefinition.label = null;
|
||||
workingDefinition.comment = "CP/M-86 floppy identifier";
|
||||
workingDefinition.ofs = dpb.off;
|
||||
workingDefinition.sectorsPerTrack = 9;
|
||||
workingDefinition.side1 = new Side();
|
||||
workingDefinition.side1.sideId = 0;
|
||||
workingDefinition.side1.sectorIds = new int[9];
|
||||
for(int si = 0; si < 9; si++) workingDefinition.side1.sectorIds[si] = si + 1;
|
||||
|
||||
workingDefinition.order = "SIDES";
|
||||
workingDefinition.side2 = new Side();
|
||||
workingDefinition.side2.sideId = 1;
|
||||
workingDefinition.side2.sectorIds = new int[9];
|
||||
for(int si = 0; si < 9; si++) workingDefinition.side2.sectorIds[si] = si + 1;
|
||||
|
||||
workingDefinition.skew = 0;
|
||||
workingDefinition.sofs = 0;
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -557,50 +558,49 @@ namespace DiscImageChef.Filesystems.CPM
|
||||
{
|
||||
cpmFound = true;
|
||||
firstDirectorySector86 = 36;
|
||||
dpb = new DiscParameterBlock();
|
||||
dpb.al0 = 0xF0;
|
||||
dpb.al1 = 0;
|
||||
dpb.blm = 0x0F;
|
||||
dpb.bsh = 4;
|
||||
dpb.cks = 0x40;
|
||||
dpb.drm = 0xFF;
|
||||
dpb.dsm = 0x15E;
|
||||
dpb.exm = 0;
|
||||
dpb.off = 4;
|
||||
dpb.phm = 3;
|
||||
dpb.psh = 2;
|
||||
dpb.spt = 9 * 4;
|
||||
dpb = new DiscParameterBlock
|
||||
{
|
||||
al0 = 0xF0,
|
||||
al1 = 0,
|
||||
blm = 0x0F,
|
||||
bsh = 4,
|
||||
cks = 0x40,
|
||||
drm = 0xFF,
|
||||
dsm = 0x15E,
|
||||
exm = 0,
|
||||
off = 4,
|
||||
phm = 3,
|
||||
psh = 2,
|
||||
spt = 9 * 4
|
||||
};
|
||||
|
||||
workingDefinition = new CpmDefinition
|
||||
{
|
||||
al0 = dpb.al0,
|
||||
al1 = dpb.al1,
|
||||
bitrate = "LOW",
|
||||
blm = dpb.blm,
|
||||
bsh = dpb.bsh,
|
||||
bytesPerSector = 512,
|
||||
cylinders = 80,
|
||||
drm = dpb.drm,
|
||||
dsm = dpb.dsm,
|
||||
encoding = "MFM",
|
||||
evenOdd = false,
|
||||
exm = dpb.exm,
|
||||
label = null,
|
||||
comment = "CP/M-86 floppy identifier",
|
||||
ofs = dpb.off,
|
||||
sectorsPerTrack = 9,
|
||||
side1 = new Side {sideId = 0, sectorIds = new int[9]},
|
||||
order = "SIDES",
|
||||
side2 = new Side {sideId = 1, sectorIds = new int[9]},
|
||||
skew = 0,
|
||||
sofs = 0
|
||||
};
|
||||
|
||||
workingDefinition = new CpmDefinition();
|
||||
workingDefinition.al0 = dpb.al0;
|
||||
workingDefinition.al1 = dpb.al1;
|
||||
workingDefinition.bitrate = "LOW";
|
||||
workingDefinition.blm = dpb.blm;
|
||||
workingDefinition.bsh = dpb.bsh;
|
||||
workingDefinition.bytesPerSector = 512;
|
||||
workingDefinition.cylinders = 80;
|
||||
workingDefinition.drm = dpb.drm;
|
||||
workingDefinition.dsm = dpb.dsm;
|
||||
workingDefinition.encoding = "MFM";
|
||||
workingDefinition.evenOdd = false;
|
||||
workingDefinition.exm = dpb.exm;
|
||||
workingDefinition.label = null;
|
||||
workingDefinition.comment = "CP/M-86 floppy identifier";
|
||||
workingDefinition.ofs = dpb.off;
|
||||
workingDefinition.sectorsPerTrack = 9;
|
||||
workingDefinition.side1 = new Side();
|
||||
workingDefinition.side1.sideId = 0;
|
||||
workingDefinition.side1.sectorIds = new int[9];
|
||||
for(int si = 0; si < 9; si++) workingDefinition.side1.sectorIds[si] = si + 1;
|
||||
|
||||
workingDefinition.order = "SIDES";
|
||||
workingDefinition.side2 = new Side();
|
||||
workingDefinition.side2.sideId = 1;
|
||||
workingDefinition.side2.sectorIds = new int[9];
|
||||
for(int si = 0; si < 9; si++) workingDefinition.side2.sectorIds[si] = si + 1;
|
||||
|
||||
workingDefinition.skew = 0;
|
||||
workingDefinition.sofs = 0;
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -609,50 +609,49 @@ namespace DiscImageChef.Filesystems.CPM
|
||||
{
|
||||
cpmFound = true;
|
||||
firstDirectorySector86 = 18;
|
||||
dpb = new DiscParameterBlock();
|
||||
dpb.al0 = 0xF0;
|
||||
dpb.al1 = 0;
|
||||
dpb.blm = 0x0F;
|
||||
dpb.bsh = 4;
|
||||
dpb.cks = 0x40;
|
||||
dpb.drm = 0xFF;
|
||||
dpb.dsm = 0x162;
|
||||
dpb.exm = 0;
|
||||
dpb.off = 2;
|
||||
dpb.phm = 3;
|
||||
dpb.psh = 2;
|
||||
dpb.spt = 9 * 4;
|
||||
dpb = new DiscParameterBlock
|
||||
{
|
||||
al0 = 0xF0,
|
||||
al1 = 0,
|
||||
blm = 0x0F,
|
||||
bsh = 4,
|
||||
cks = 0x40,
|
||||
drm = 0xFF,
|
||||
dsm = 0x162,
|
||||
exm = 0,
|
||||
off = 2,
|
||||
phm = 3,
|
||||
psh = 2,
|
||||
spt = 9 * 4
|
||||
};
|
||||
|
||||
workingDefinition = new CpmDefinition
|
||||
{
|
||||
al0 = dpb.al0,
|
||||
al1 = dpb.al1,
|
||||
bitrate = "LOW",
|
||||
blm = dpb.blm,
|
||||
bsh = dpb.bsh,
|
||||
bytesPerSector = 512,
|
||||
cylinders = 80,
|
||||
drm = dpb.drm,
|
||||
dsm = dpb.dsm,
|
||||
encoding = "MFM",
|
||||
evenOdd = false,
|
||||
exm = dpb.exm,
|
||||
label = null,
|
||||
comment = "CP/M-86 floppy identifier",
|
||||
ofs = dpb.off,
|
||||
sectorsPerTrack = 9,
|
||||
side1 = new Side {sideId = 0, sectorIds = new int[9]},
|
||||
order = "CYLINDERS",
|
||||
side2 = new Side {sideId = 1, sectorIds = new int[9]},
|
||||
skew = 0,
|
||||
sofs = 0
|
||||
};
|
||||
|
||||
workingDefinition = new CpmDefinition();
|
||||
workingDefinition.al0 = dpb.al0;
|
||||
workingDefinition.al1 = dpb.al1;
|
||||
workingDefinition.bitrate = "LOW";
|
||||
workingDefinition.blm = dpb.blm;
|
||||
workingDefinition.bsh = dpb.bsh;
|
||||
workingDefinition.bytesPerSector = 512;
|
||||
workingDefinition.cylinders = 80;
|
||||
workingDefinition.drm = dpb.drm;
|
||||
workingDefinition.dsm = dpb.dsm;
|
||||
workingDefinition.encoding = "MFM";
|
||||
workingDefinition.evenOdd = false;
|
||||
workingDefinition.exm = dpb.exm;
|
||||
workingDefinition.label = null;
|
||||
workingDefinition.comment = "CP/M-86 floppy identifier";
|
||||
workingDefinition.ofs = dpb.off;
|
||||
workingDefinition.sectorsPerTrack = 9;
|
||||
workingDefinition.side1 = new Side();
|
||||
workingDefinition.side1.sideId = 0;
|
||||
workingDefinition.side1.sectorIds = new int[9];
|
||||
for(int si = 0; si < 9; si++) workingDefinition.side1.sectorIds[si] = si + 1;
|
||||
|
||||
workingDefinition.order = "CYLINDERS";
|
||||
workingDefinition.side2 = new Side();
|
||||
workingDefinition.side2.sideId = 1;
|
||||
workingDefinition.side2.sectorIds = new int[9];
|
||||
for(int si = 0; si < 9; si++) workingDefinition.side2.sectorIds[si] = si + 1;
|
||||
|
||||
workingDefinition.skew = 0;
|
||||
workingDefinition.sofs = 0;
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -661,50 +660,49 @@ namespace DiscImageChef.Filesystems.CPM
|
||||
{
|
||||
cpmFound = true;
|
||||
firstDirectorySector86 = 30;
|
||||
dpb = new DiscParameterBlock();
|
||||
dpb.al0 = 0xC0;
|
||||
dpb.al1 = 0;
|
||||
dpb.blm = 0x1F;
|
||||
dpb.bsh = 5;
|
||||
dpb.cks = 0x40;
|
||||
dpb.drm = 0xFF;
|
||||
dpb.dsm = 0x127;
|
||||
dpb.exm = 1;
|
||||
dpb.off = 2;
|
||||
dpb.phm = 3;
|
||||
dpb.psh = 2;
|
||||
dpb.spt = 15 * 4;
|
||||
dpb = new DiscParameterBlock
|
||||
{
|
||||
al0 = 0xC0,
|
||||
al1 = 0,
|
||||
blm = 0x1F,
|
||||
bsh = 5,
|
||||
cks = 0x40,
|
||||
drm = 0xFF,
|
||||
dsm = 0x127,
|
||||
exm = 1,
|
||||
off = 2,
|
||||
phm = 3,
|
||||
psh = 2,
|
||||
spt = 15 * 4
|
||||
};
|
||||
|
||||
workingDefinition = new CpmDefinition
|
||||
{
|
||||
al0 = dpb.al0,
|
||||
al1 = dpb.al1,
|
||||
bitrate = "HIGH",
|
||||
blm = dpb.blm,
|
||||
bsh = dpb.bsh,
|
||||
bytesPerSector = 512,
|
||||
cylinders = 80,
|
||||
drm = dpb.drm,
|
||||
dsm = dpb.dsm,
|
||||
encoding = "MFM",
|
||||
evenOdd = false,
|
||||
exm = dpb.exm,
|
||||
label = null,
|
||||
comment = "CP/M-86 floppy identifier",
|
||||
ofs = dpb.off,
|
||||
sectorsPerTrack = 15,
|
||||
side1 = new Side {sideId = 0, sectorIds = new int[15]},
|
||||
order = "CYLINDERS",
|
||||
side2 = new Side {sideId = 1, sectorIds = new int[15]},
|
||||
skew = 0,
|
||||
sofs = 0
|
||||
};
|
||||
|
||||
workingDefinition = new CpmDefinition();
|
||||
workingDefinition.al0 = dpb.al0;
|
||||
workingDefinition.al1 = dpb.al1;
|
||||
workingDefinition.bitrate = "HIGH";
|
||||
workingDefinition.blm = dpb.blm;
|
||||
workingDefinition.bsh = dpb.bsh;
|
||||
workingDefinition.bytesPerSector = 512;
|
||||
workingDefinition.cylinders = 80;
|
||||
workingDefinition.drm = dpb.drm;
|
||||
workingDefinition.dsm = dpb.dsm;
|
||||
workingDefinition.encoding = "MFM";
|
||||
workingDefinition.evenOdd = false;
|
||||
workingDefinition.exm = dpb.exm;
|
||||
workingDefinition.label = null;
|
||||
workingDefinition.comment = "CP/M-86 floppy identifier";
|
||||
workingDefinition.ofs = dpb.off;
|
||||
workingDefinition.sectorsPerTrack = 15;
|
||||
workingDefinition.side1 = new Side();
|
||||
workingDefinition.side1.sideId = 0;
|
||||
workingDefinition.side1.sectorIds = new int[15];
|
||||
for(int si = 0; si < 15; si++) workingDefinition.side1.sectorIds[si] = si + 1;
|
||||
|
||||
workingDefinition.order = "CYLINDERS";
|
||||
workingDefinition.side2 = new Side();
|
||||
workingDefinition.side2.sideId = 1;
|
||||
workingDefinition.side2.sectorIds = new int[15];
|
||||
for(int si = 0; si < 15; si++) workingDefinition.side2.sectorIds[si] = si + 1;
|
||||
|
||||
workingDefinition.skew = 0;
|
||||
workingDefinition.sofs = 0;
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -713,50 +711,49 @@ namespace DiscImageChef.Filesystems.CPM
|
||||
{
|
||||
cpmFound = true;
|
||||
firstDirectorySector86 = 36;
|
||||
dpb = new DiscParameterBlock();
|
||||
dpb.al0 = 0xC0;
|
||||
dpb.al1 = 0;
|
||||
dpb.blm = 0x1F;
|
||||
dpb.bsh = 5;
|
||||
dpb.cks = 0x40;
|
||||
dpb.drm = 0xFF;
|
||||
dpb.dsm = 0x162;
|
||||
dpb.exm = 1;
|
||||
dpb.off = 2;
|
||||
dpb.phm = 3;
|
||||
dpb.psh = 2;
|
||||
dpb.spt = 18 * 4;
|
||||
dpb = new DiscParameterBlock
|
||||
{
|
||||
al0 = 0xC0,
|
||||
al1 = 0,
|
||||
blm = 0x1F,
|
||||
bsh = 5,
|
||||
cks = 0x40,
|
||||
drm = 0xFF,
|
||||
dsm = 0x162,
|
||||
exm = 1,
|
||||
off = 2,
|
||||
phm = 3,
|
||||
psh = 2,
|
||||
spt = 18 * 4
|
||||
};
|
||||
|
||||
workingDefinition = new CpmDefinition
|
||||
{
|
||||
al0 = dpb.al0,
|
||||
al1 = dpb.al1,
|
||||
bitrate = "LOW",
|
||||
blm = dpb.blm,
|
||||
bsh = dpb.bsh,
|
||||
bytesPerSector = 512,
|
||||
cylinders = 80,
|
||||
drm = dpb.drm,
|
||||
dsm = dpb.dsm,
|
||||
encoding = "MFM",
|
||||
evenOdd = false,
|
||||
exm = dpb.exm,
|
||||
label = null,
|
||||
comment = "CP/M-86 floppy identifier",
|
||||
ofs = dpb.off,
|
||||
sectorsPerTrack = 18,
|
||||
side1 = new Side {sideId = 0, sectorIds = new int[18]},
|
||||
order = "CYLINDERS",
|
||||
side2 = new Side {sideId = 1, sectorIds = new int[18]},
|
||||
skew = 0,
|
||||
sofs = 0
|
||||
};
|
||||
|
||||
workingDefinition = new CpmDefinition();
|
||||
workingDefinition.al0 = dpb.al0;
|
||||
workingDefinition.al1 = dpb.al1;
|
||||
workingDefinition.bitrate = "LOW";
|
||||
workingDefinition.blm = dpb.blm;
|
||||
workingDefinition.bsh = dpb.bsh;
|
||||
workingDefinition.bytesPerSector = 512;
|
||||
workingDefinition.cylinders = 80;
|
||||
workingDefinition.drm = dpb.drm;
|
||||
workingDefinition.dsm = dpb.dsm;
|
||||
workingDefinition.encoding = "MFM";
|
||||
workingDefinition.evenOdd = false;
|
||||
workingDefinition.exm = dpb.exm;
|
||||
workingDefinition.label = null;
|
||||
workingDefinition.comment = "CP/M-86 floppy identifier";
|
||||
workingDefinition.ofs = dpb.off;
|
||||
workingDefinition.sectorsPerTrack = 18;
|
||||
workingDefinition.side1 = new Side();
|
||||
workingDefinition.side1.sideId = 0;
|
||||
workingDefinition.side1.sectorIds = new int[18];
|
||||
for(int si = 0; si < 18; si++) workingDefinition.side1.sectorIds[si] = si + 1;
|
||||
|
||||
workingDefinition.order = "CYLINDERS";
|
||||
workingDefinition.side2 = new Side();
|
||||
workingDefinition.side2.sideId = 1;
|
||||
workingDefinition.side2.sectorIds = new int[18];
|
||||
for(int si = 0; si < 18; si++) workingDefinition.side2.sectorIds[si] = si + 1;
|
||||
|
||||
workingDefinition.skew = 0;
|
||||
workingDefinition.sofs = 0;
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -787,8 +784,7 @@ namespace DiscImageChef.Filesystems.CPM
|
||||
{
|
||||
// Load all definitions
|
||||
DicConsole.DebugWriteLine("CP/M Plugin", "Trying to load definitions.");
|
||||
if(LoadDefinitions() && definitions != null && definitions.definitions != null &&
|
||||
definitions.definitions.Count > 0)
|
||||
if(LoadDefinitions() && definitions?.definitions != null && definitions.definitions.Count > 0)
|
||||
{
|
||||
DicConsole.DebugWriteLine("CP/M Plugin", "Trying all known definitions.");
|
||||
foreach(CpmDefinition def in from def in definitions.definitions let sectors = (ulong)(def.cylinders * def.sides * def.sectorsPerTrack) where sectors == imagePlugin.GetSectors() && def.bytesPerSector == imagePlugin.GetSectorSize() select def) {
|
||||
@@ -889,16 +885,20 @@ namespace DiscImageChef.Filesystems.CPM
|
||||
|
||||
// Build a Disc Parameter Block
|
||||
workingDefinition = def;
|
||||
dpb = new DiscParameterBlock();
|
||||
dpb.al0 = (byte)def.al0;
|
||||
dpb.al1 = (byte)def.al1;
|
||||
dpb.blm = (byte)def.blm;
|
||||
dpb.bsh = (byte)def.bsh;
|
||||
dpb.cks = 0; // Needed?
|
||||
dpb.drm = (ushort)def.drm;
|
||||
dpb.dsm = (ushort)def.dsm;
|
||||
dpb.exm = (byte)def.exm;
|
||||
dpb.off = (ushort)def.ofs;
|
||||
dpb = new DiscParameterBlock
|
||||
{
|
||||
al0 = (byte)def.al0,
|
||||
al1 = (byte)def.al1,
|
||||
blm = (byte)def.blm,
|
||||
bsh = (byte)def.bsh,
|
||||
// Needed?
|
||||
cks = 0,
|
||||
drm = (ushort)def.drm,
|
||||
dsm = (ushort)def.dsm,
|
||||
exm = (byte)def.exm,
|
||||
off = (ushort)def.ofs,
|
||||
spt = (ushort)(def.sectorsPerTrack * def.bytesPerSector / 128)
|
||||
};
|
||||
switch(def.bytesPerSector)
|
||||
{
|
||||
case 128:
|
||||
@@ -939,7 +939,6 @@ namespace DiscImageChef.Filesystems.CPM
|
||||
break;
|
||||
}
|
||||
|
||||
dpb.spt = (ushort)(def.sectorsPerTrack * def.bytesPerSector / 128);
|
||||
cpmFound = true;
|
||||
workingDefinition = def;
|
||||
|
||||
@@ -991,12 +990,9 @@ namespace DiscImageChef.Filesystems.CPM
|
||||
workingDefinition.ofs * workingDefinition.sectorsPerTrack, workingDefinition.ofs)
|
||||
.AppendLine();
|
||||
|
||||
int interleaveSide1;
|
||||
int interleaveSide2;
|
||||
|
||||
if(workingDefinition.side1.sectorIds.Length >= 2)
|
||||
{
|
||||
interleaveSide1 = workingDefinition.side1.sectorIds[1] - workingDefinition.side1.sectorIds[0];
|
||||
int interleaveSide1 = workingDefinition.side1.sectorIds[1] - workingDefinition.side1.sectorIds[0];
|
||||
if(interleaveSide1 > 1)
|
||||
sb.AppendFormat("Side 0 uses {0}:1 software interleaving", interleaveSide1).AppendLine();
|
||||
}
|
||||
@@ -1005,7 +1001,7 @@ namespace DiscImageChef.Filesystems.CPM
|
||||
{
|
||||
if(workingDefinition.side2.sectorIds.Length >= 2)
|
||||
{
|
||||
interleaveSide2 = workingDefinition.side2.sectorIds[1] - workingDefinition.side2.sectorIds[0];
|
||||
int interleaveSide2 = workingDefinition.side2.sectorIds[1] - workingDefinition.side2.sectorIds[0];
|
||||
if(interleaveSide2 > 1)
|
||||
sb.AppendFormat("Side 1 uses {0}:1 software interleaving", interleaveSide2).AppendLine();
|
||||
}
|
||||
@@ -1046,23 +1042,23 @@ namespace DiscImageChef.Filesystems.CPM
|
||||
if(labelUpdateDate != null)
|
||||
sb.AppendFormat("Volume updated on {0}", DateHandlers.CPMToDateTime(labelUpdateDate)).AppendLine();
|
||||
|
||||
xmlFSType = new FileSystemType();
|
||||
xmlFSType.Bootable |= workingDefinition.sofs > 0 || workingDefinition.ofs > 0;
|
||||
xmlFSType.ClusterSize = 128 << dpb.bsh;
|
||||
if(dpb.dsm > 0) xmlFSType.Clusters = dpb.dsm;
|
||||
else xmlFSType.Clusters = (long)(partition.End - partition.Start);
|
||||
XmlFsType = new FileSystemType();
|
||||
XmlFsType.Bootable |= workingDefinition.sofs > 0 || workingDefinition.ofs > 0;
|
||||
XmlFsType.ClusterSize = 128 << dpb.bsh;
|
||||
if(dpb.dsm > 0) XmlFsType.Clusters = dpb.dsm;
|
||||
else XmlFsType.Clusters = (long)(partition.End - partition.Start);
|
||||
if(labelCreationDate != null)
|
||||
{
|
||||
xmlFSType.CreationDate = DateHandlers.CPMToDateTime(labelCreationDate);
|
||||
xmlFSType.CreationDateSpecified = true;
|
||||
XmlFsType.CreationDate = DateHandlers.CPMToDateTime(labelCreationDate);
|
||||
XmlFsType.CreationDateSpecified = true;
|
||||
}
|
||||
if(labelUpdateDate != null)
|
||||
{
|
||||
xmlFSType.ModificationDate = DateHandlers.CPMToDateTime(labelUpdateDate);
|
||||
xmlFSType.ModificationDateSpecified = true;
|
||||
XmlFsType.ModificationDate = DateHandlers.CPMToDateTime(labelUpdateDate);
|
||||
XmlFsType.ModificationDateSpecified = true;
|
||||
}
|
||||
xmlFSType.Type = "CP/M";
|
||||
xmlFSType.VolumeName = label;
|
||||
XmlFsType.Type = "CP/M";
|
||||
XmlFsType.VolumeName = label;
|
||||
|
||||
information = sb.ToString();
|
||||
}
|
||||
|
||||
@@ -149,8 +149,7 @@ namespace DiscImageChef.Filesystems.CPM
|
||||
// For each volume sector
|
||||
for(ulong a = 0; a < (ulong)deinterleavedSectors.Count; a++)
|
||||
{
|
||||
byte[] sector;
|
||||
deinterleavedSectors.TryGetValue(a, out sector);
|
||||
deinterleavedSectors.TryGetValue(a, out byte[] sector);
|
||||
|
||||
// May it happen? Just in case, CP/M blocks are smaller than physical sectors
|
||||
if(sector.Length > blockSize)
|
||||
@@ -187,8 +186,7 @@ namespace DiscImageChef.Filesystems.CPM
|
||||
MemoryStream dirMs = new MemoryStream();
|
||||
for(int d = 0; d < dirSectors; d++)
|
||||
{
|
||||
byte[] sector;
|
||||
deinterleavedSectors.TryGetValue((ulong)(d + dirOff), out sector);
|
||||
deinterleavedSectors.TryGetValue((ulong)(d + dirOff), out byte[] sector);
|
||||
dirMs.Write(sector, 0, sector.Length);
|
||||
}
|
||||
|
||||
@@ -219,10 +217,9 @@ namespace DiscImageChef.Filesystems.CPM
|
||||
if((directory[dOff] & 0x7F) < 0x10)
|
||||
if(allocationBlocks.Count > 256)
|
||||
{
|
||||
DirectoryEntry16 entry;
|
||||
dirPtr = Marshal.AllocHGlobal(32);
|
||||
Marshal.Copy(directory, dOff, dirPtr, 32);
|
||||
entry = (DirectoryEntry16)Marshal.PtrToStructure(dirPtr, typeof(DirectoryEntry16));
|
||||
DirectoryEntry16 entry = (DirectoryEntry16)Marshal.PtrToStructure(dirPtr, typeof(DirectoryEntry16));
|
||||
Marshal.FreeHGlobal(dirPtr);
|
||||
|
||||
bool hidden = (entry.statusUser & 0x80) == 0x80;
|
||||
@@ -254,24 +251,18 @@ namespace DiscImageChef.Filesystems.CPM
|
||||
if(!string.IsNullOrEmpty(extension)) filename = filename + "." + extension;
|
||||
|
||||
int entryNo = (32 * entry.extentCounter + entry.extentCounterHigh) / (dpb.exm + 1);
|
||||
List<ushort> blocks;
|
||||
Dictionary<int, List<ushort>> extentBlocks;
|
||||
FileEntryInfo fInfo;
|
||||
|
||||
// Do we have a stat for the file already?
|
||||
if(statCache.TryGetValue(filename, out fInfo)) statCache.Remove(filename);
|
||||
if(statCache.TryGetValue(filename, out FileEntryInfo fInfo)) statCache.Remove(filename);
|
||||
else
|
||||
{
|
||||
fInfo = new FileEntryInfo();
|
||||
fInfo.Attributes = new FileAttributes();
|
||||
}
|
||||
{ fInfo = new FileEntryInfo {Attributes = new FileAttributes()}; }
|
||||
|
||||
// And any extent?
|
||||
if(fileExtents.TryGetValue(filename, out extentBlocks)) fileExtents.Remove(filename);
|
||||
if(fileExtents.TryGetValue(filename, out Dictionary<int, List<ushort>> extentBlocks)) fileExtents.Remove(filename);
|
||||
else extentBlocks = new Dictionary<int, List<ushort>>();
|
||||
|
||||
// Do we already have this extent? Should never happen
|
||||
if(extentBlocks.TryGetValue(entryNo, out blocks)) extentBlocks.Remove(entryNo);
|
||||
if(extentBlocks.TryGetValue(entryNo, out List<ushort> blocks)) extentBlocks.Remove(entryNo);
|
||||
else blocks = new List<ushort>();
|
||||
|
||||
// Attributes
|
||||
@@ -313,10 +304,9 @@ namespace DiscImageChef.Filesystems.CPM
|
||||
}
|
||||
else
|
||||
{
|
||||
DirectoryEntry entry;
|
||||
dirPtr = Marshal.AllocHGlobal(32);
|
||||
Marshal.Copy(directory, dOff, dirPtr, 32);
|
||||
entry = (DirectoryEntry)Marshal.PtrToStructure(dirPtr, typeof(DirectoryEntry));
|
||||
DirectoryEntry entry = (DirectoryEntry)Marshal.PtrToStructure(dirPtr, typeof(DirectoryEntry));
|
||||
Marshal.FreeHGlobal(dirPtr);
|
||||
|
||||
bool hidden = (entry.statusUser & 0x80) == 0x80;
|
||||
@@ -348,24 +338,18 @@ namespace DiscImageChef.Filesystems.CPM
|
||||
if(!string.IsNullOrEmpty(extension)) filename = filename + "." + extension;
|
||||
|
||||
int entryNo = (32 * entry.extentCounterHigh + entry.extentCounter) / (dpb.exm + 1);
|
||||
List<ushort> blocks;
|
||||
Dictionary<int, List<ushort>> extentBlocks;
|
||||
FileEntryInfo fInfo;
|
||||
|
||||
// Do we have a stat for the file already?
|
||||
if(statCache.TryGetValue(filename, out fInfo)) statCache.Remove(filename);
|
||||
if(statCache.TryGetValue(filename, out FileEntryInfo fInfo)) statCache.Remove(filename);
|
||||
else
|
||||
{
|
||||
fInfo = new FileEntryInfo();
|
||||
fInfo.Attributes = new FileAttributes();
|
||||
}
|
||||
{ fInfo = new FileEntryInfo {Attributes = new FileAttributes()}; }
|
||||
|
||||
// And any extent?
|
||||
if(fileExtents.TryGetValue(filename, out extentBlocks)) fileExtents.Remove(filename);
|
||||
if(fileExtents.TryGetValue(filename, out Dictionary<int, List<ushort>> extentBlocks)) fileExtents.Remove(filename);
|
||||
else extentBlocks = new Dictionary<int, List<ushort>>();
|
||||
|
||||
// Do we already have this extent? Should never happen
|
||||
if(extentBlocks.TryGetValue(entryNo, out blocks)) extentBlocks.Remove(entryNo);
|
||||
if(extentBlocks.TryGetValue(entryNo, out List<ushort> blocks)) extentBlocks.Remove(entryNo);
|
||||
else blocks = new List<ushort>();
|
||||
|
||||
// Attributes
|
||||
@@ -408,10 +392,9 @@ namespace DiscImageChef.Filesystems.CPM
|
||||
// A password entry (or a file entry in PDOS, but this does not handle that case)
|
||||
else if((directory[dOff] & 0x7F) >= 0x10 && (directory[dOff] & 0x7F) < 0x20)
|
||||
{
|
||||
PasswordEntry entry;
|
||||
dirPtr = Marshal.AllocHGlobal(32);
|
||||
Marshal.Copy(directory, dOff, dirPtr, 32);
|
||||
entry = (PasswordEntry)Marshal.PtrToStructure(dirPtr, typeof(PasswordEntry));
|
||||
PasswordEntry entry = (PasswordEntry)Marshal.PtrToStructure(dirPtr, typeof(PasswordEntry));
|
||||
Marshal.FreeHGlobal(dirPtr);
|
||||
|
||||
int user = entry.userNumber & 0x0F;
|
||||
@@ -488,10 +471,9 @@ namespace DiscImageChef.Filesystems.CPM
|
||||
if(directory[dOff + 10] == 0x00 && directory[dOff + 20] == 0x00 && directory[dOff + 30] == 0x00 &&
|
||||
directory[dOff + 31] == 0x00)
|
||||
{
|
||||
DateEntry dateEntry;
|
||||
dirPtr = Marshal.AllocHGlobal(32);
|
||||
Marshal.Copy(directory, dOff, dirPtr, 32);
|
||||
dateEntry = (DateEntry)Marshal.PtrToStructure(dirPtr, typeof(DateEntry));
|
||||
DateEntry dateEntry = (DateEntry)Marshal.PtrToStructure(dirPtr, typeof(DateEntry));
|
||||
Marshal.FreeHGlobal(dirPtr);
|
||||
|
||||
FileEntryInfo fInfo;
|
||||
@@ -544,10 +526,9 @@ namespace DiscImageChef.Filesystems.CPM
|
||||
// However, if this byte is 0, timestamp is in Z80DOS or DOS+ format
|
||||
else if(directory[dOff + 1] == 0x00)
|
||||
{
|
||||
TrdPartyDateEntry trdPartyDateEntry;
|
||||
dirPtr = Marshal.AllocHGlobal(32);
|
||||
Marshal.Copy(directory, dOff, dirPtr, 32);
|
||||
trdPartyDateEntry = (TrdPartyDateEntry)Marshal.PtrToStructure(dirPtr, typeof(TrdPartyDateEntry));
|
||||
TrdPartyDateEntry trdPartyDateEntry = (TrdPartyDateEntry)Marshal.PtrToStructure(dirPtr, typeof(TrdPartyDateEntry));
|
||||
Marshal.FreeHGlobal(dirPtr);
|
||||
|
||||
FileEntryInfo fInfo;
|
||||
@@ -617,24 +598,19 @@ namespace DiscImageChef.Filesystems.CPM
|
||||
foreach(string filename in dirList)
|
||||
{
|
||||
MemoryStream fileMs = new MemoryStream();
|
||||
FileEntryInfo fInfo;
|
||||
|
||||
if(statCache.TryGetValue(filename, out fInfo)) statCache.Remove(filename);
|
||||
if(statCache.TryGetValue(filename, out FileEntryInfo fInfo)) statCache.Remove(filename);
|
||||
|
||||
fInfo.Blocks = 0;
|
||||
|
||||
Dictionary<int, List<ushort>> extents;
|
||||
if(fileExtents.TryGetValue(filename, out extents))
|
||||
if(fileExtents.TryGetValue(filename, out Dictionary<int, List<ushort>> extents))
|
||||
for(int ex = 0; ex < extents.Count; ex++)
|
||||
{
|
||||
List<ushort> alBlks;
|
||||
|
||||
if(!extents.TryGetValue(ex, out alBlks)) continue;
|
||||
if(!extents.TryGetValue(ex, out List<ushort> alBlks)) continue;
|
||||
|
||||
foreach(ushort alBlk in alBlks)
|
||||
{
|
||||
byte[] blk;
|
||||
allocationBlocks.TryGetValue(alBlk, out blk);
|
||||
allocationBlocks.TryGetValue(alBlk, out byte[] blk);
|
||||
fileMs.Write(blk, 0, blk.Length);
|
||||
fInfo.Blocks++;
|
||||
}
|
||||
@@ -668,29 +644,31 @@ namespace DiscImageChef.Filesystems.CPM
|
||||
cpmStat.FilenameLength = 11;
|
||||
cpmStat.Files = (ulong)fileCache.Count;
|
||||
cpmStat.FreeBlocks = cpmStat.Blocks - usedBlocks;
|
||||
cpmStat.PluginId = PluginUUID;
|
||||
cpmStat.PluginId = PluginUuid;
|
||||
cpmStat.Type = "CP/M filesystem";
|
||||
|
||||
// Generate XML info
|
||||
xmlFSType = new FileSystemType();
|
||||
xmlFSType.Clusters = cpmStat.Blocks;
|
||||
xmlFSType.ClusterSize = blockSize;
|
||||
XmlFsType = new FileSystemType
|
||||
{
|
||||
Clusters = cpmStat.Blocks,
|
||||
ClusterSize = blockSize,
|
||||
Files = fileCache.Count,
|
||||
FilesSpecified = true,
|
||||
FreeClusters = cpmStat.FreeBlocks,
|
||||
FreeClustersSpecified = true,
|
||||
Type = "CP/M filesystem"
|
||||
};
|
||||
if(labelCreationDate != null)
|
||||
{
|
||||
xmlFSType.CreationDate = DateHandlers.CPMToDateTime(labelCreationDate);
|
||||
xmlFSType.CreationDateSpecified = true;
|
||||
XmlFsType.CreationDate = DateHandlers.CPMToDateTime(labelCreationDate);
|
||||
XmlFsType.CreationDateSpecified = true;
|
||||
}
|
||||
if(labelUpdateDate != null)
|
||||
{
|
||||
xmlFSType.ModificationDate = DateHandlers.CPMToDateTime(labelUpdateDate);
|
||||
xmlFSType.ModificationDateSpecified = true;
|
||||
XmlFsType.ModificationDate = DateHandlers.CPMToDateTime(labelUpdateDate);
|
||||
XmlFsType.ModificationDateSpecified = true;
|
||||
}
|
||||
xmlFSType.Files = fileCache.Count;
|
||||
xmlFSType.FilesSpecified = true;
|
||||
xmlFSType.FreeClusters = cpmStat.FreeBlocks;
|
||||
xmlFSType.FreeClustersSpecified = true;
|
||||
xmlFSType.Type = "CP/M filesystem";
|
||||
if(!string.IsNullOrEmpty(label)) xmlFSType.VolumeName = label;
|
||||
if(!string.IsNullOrEmpty(label)) XmlFsType.VolumeName = label;
|
||||
|
||||
mounted = true;
|
||||
return Errno.NoError;
|
||||
|
||||
@@ -58,9 +58,7 @@ namespace DiscImageChef.Filesystems.CPM
|
||||
if(string.Compare(xattr, "com.caldera.cpm.password.text", StringComparison.InvariantCulture) != 0)
|
||||
return Errno.NoSuchExtendedAttribute;
|
||||
|
||||
if(!passwordCache.TryGetValue(pathElements[0].ToUpperInvariant(), out buf)) return Errno.NoError;
|
||||
|
||||
return Errno.NoSuchExtendedAttribute;
|
||||
return !passwordCache.TryGetValue(pathElements[0].ToUpperInvariant(), out buf) ? Errno.NoError : Errno.NoSuchExtendedAttribute;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
Reference in New Issue
Block a user