public bool Identify(IFilter imageFilter) { Stream stream = imageFilter.GetDataForkStream(); stream.Seek(0, SeekOrigin.Begin); // Even if disk name is supposedly ASCII, I'm pretty sure most emulators allow Shift-JIS to be used :p Encoding shiftjis = Encoding.GetEncoding("shift_jis"); D88Header d88Hdr = new D88Header(); if (stream.Length < Marshal.SizeOf(d88Hdr)) { return(false); } byte[] hdrB = new byte[Marshal.SizeOf(d88Hdr)]; stream.Read(hdrB, 0, hdrB.Length); GCHandle handle = GCHandle.Alloc(hdrB, GCHandleType.Pinned); d88Hdr = (D88Header)Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(D88Header)); handle.Free(); DicConsole.DebugWriteLine("D88 plugin", "d88hdr.name = \"{0}\"", StringHandlers.CToString(d88Hdr.name, shiftjis)); DicConsole.DebugWriteLine("D88 plugin", "d88hdr.reserved is empty? = {0}", d88Hdr.reserved.SequenceEqual(reservedEmpty)); DicConsole.DebugWriteLine("D88 plugin", "d88hdr.write_protect = 0x{0:X2}", d88Hdr.write_protect); DicConsole.DebugWriteLine("D88 plugin", "d88hdr.disk_type = {0} ({1})", d88Hdr.disk_type, (byte)d88Hdr.disk_type); DicConsole.DebugWriteLine("D88 plugin", "d88hdr.disk_size = {0}", d88Hdr.disk_size); if (d88Hdr.disk_size != stream.Length) { return(false); } if (d88Hdr.disk_type != DiskType.D2 && d88Hdr.disk_type != DiskType.Dd2 && d88Hdr.disk_type != DiskType.Hd2) { return(false); } if (!d88Hdr.reserved.SequenceEqual(reservedEmpty)) { return(false); } int counter = 0; foreach (int t in d88Hdr.track_table) { if (t > 0) { counter++; } if (t < 0 || t > stream.Length) { return(false); } } DicConsole.DebugWriteLine("D88 plugin", "{0} tracks", counter); return(counter > 0); }
public bool Open(IFilter imageFilter) { Stream stream = imageFilter.GetDataForkStream(); stream.Seek(0, SeekOrigin.Begin); // Even if disk name is supposedly ASCII, I'm pretty sure most emulators allow Shift-JIS to be used :p var shiftjis = Encoding.GetEncoding("shift_jis"); if (stream.Length < Marshal.SizeOf <D88Header>()) { return(false); } byte[] hdrB = new byte[Marshal.SizeOf <D88Header>()]; stream.Read(hdrB, 0, hdrB.Length); D88Header d88Hdr = Marshal.ByteArrayToStructureLittleEndian <D88Header>(hdrB); AaruConsole.DebugWriteLine("D88 plugin", "d88hdr.name = \"{0}\"", StringHandlers.CToString(d88Hdr.name, shiftjis)); AaruConsole.DebugWriteLine("D88 plugin", "d88hdr.reserved is empty? = {0}", d88Hdr.reserved.SequenceEqual(_reservedEmpty)); AaruConsole.DebugWriteLine("D88 plugin", "d88hdr.write_protect = 0x{0:X2}", d88Hdr.write_protect); AaruConsole.DebugWriteLine("D88 plugin", "d88hdr.disk_type = {0} ({1})", d88Hdr.disk_type, (byte)d88Hdr.disk_type); AaruConsole.DebugWriteLine("D88 plugin", "d88hdr.disk_size = {0}", d88Hdr.disk_size); if (d88Hdr.disk_size != stream.Length) { return(false); } if (d88Hdr.disk_type != DiskType.D2 && d88Hdr.disk_type != DiskType.Dd2 && d88Hdr.disk_type != DiskType.Hd2) { return(false); } if (!d88Hdr.reserved.SequenceEqual(_reservedEmpty)) { return(false); } int trkCounter = 0; foreach (int t in d88Hdr.track_table) { if (t > 0) { trkCounter++; } if (t < 0 || t > stream.Length) { return(false); } } AaruConsole.DebugWriteLine("D88 plugin", "{0} tracks", trkCounter); if (trkCounter == 0) { return(false); } hdrB = new byte[Marshal.SizeOf <SectorHeader>()]; stream.Seek(d88Hdr.track_table[0], SeekOrigin.Begin); stream.Read(hdrB, 0, hdrB.Length); SectorHeader sechdr = Marshal.ByteArrayToStructureLittleEndian <SectorHeader>(hdrB); AaruConsole.DebugWriteLine("D88 plugin", "sechdr.c = {0}", sechdr.c); AaruConsole.DebugWriteLine("D88 plugin", "sechdr.h = {0}", sechdr.h); AaruConsole.DebugWriteLine("D88 plugin", "sechdr.r = {0}", sechdr.r); AaruConsole.DebugWriteLine("D88 plugin", "sechdr.n = {0}", sechdr.n); AaruConsole.DebugWriteLine("D88 plugin", "sechdr.spt = {0}", sechdr.spt); AaruConsole.DebugWriteLine("D88 plugin", "sechdr.density = {0}", sechdr.density); AaruConsole.DebugWriteLine("D88 plugin", "sechdr.deleted_mark = {0}", sechdr.deleted_mark); AaruConsole.DebugWriteLine("D88 plugin", "sechdr.status = {0}", sechdr.status); AaruConsole.DebugWriteLine("D88 plugin", "sechdr.size_of_data = {0}", sechdr.size_of_data); short spt = sechdr.spt; IBMSectorSizeCode bps = sechdr.n; bool allEqual = true; _sectorsData = new List <byte[]>(); for (int i = 0; i < trkCounter; i++) { stream.Seek(d88Hdr.track_table[i], SeekOrigin.Begin); stream.Read(hdrB, 0, hdrB.Length); SortedDictionary <byte, byte[]> sectors = new SortedDictionary <byte, byte[]>(); sechdr = Marshal.ByteArrayToStructureLittleEndian <SectorHeader>(hdrB); if (sechdr.spt != spt || sechdr.n != bps) { AaruConsole.DebugWriteLine("D88 plugin", "Disk tracks are not same size. spt = {0} (expected {1}), bps = {2} (expected {3}) at track {4} sector {5}", sechdr.spt, spt, sechdr.n, bps, i, 0); allEqual = false; } short maxJ = sechdr.spt; byte[] secB; for (short j = 1; j < maxJ; j++) { secB = new byte[sechdr.size_of_data]; stream.Read(secB, 0, secB.Length); sectors.Add(sechdr.r, secB); stream.Read(hdrB, 0, hdrB.Length); sechdr = Marshal.ByteArrayToStructureLittleEndian <SectorHeader>(hdrB); if (sechdr.spt == spt && sechdr.n == bps) { continue; } AaruConsole.DebugWriteLine("D88 plugin", "Disk tracks are not same size. spt = {0} (expected {1}), bps = {2} (expected {3}) at track {4} sector {5}", sechdr.spt, spt, sechdr.n, bps, i, j, sechdr.deleted_mark); allEqual = false; } secB = new byte[sechdr.size_of_data]; stream.Read(secB, 0, secB.Length); sectors.Add(sechdr.r, secB); foreach (KeyValuePair <byte, byte[]> kvp in sectors) { _sectorsData.Add(kvp.Value); } } AaruConsole.DebugWriteLine("D88 plugin", "{0} sectors", _sectorsData.Count); _imageInfo.MediaType = MediaType.Unknown; if (allEqual) { if (trkCounter == 154 && spt == 26 && bps == IBMSectorSizeCode.EighthKilo) { _imageInfo.MediaType = MediaType.NEC_8_SD; } else if (bps == IBMSectorSizeCode.QuarterKilo) { switch (trkCounter) { case 80 when spt == 16: _imageInfo.MediaType = MediaType.NEC_525_SS; break; case 154 when spt == 26: _imageInfo.MediaType = MediaType.NEC_8_DD; break; case 160 when spt == 16: _imageInfo.MediaType = MediaType.NEC_525_DS; break; } } else if (trkCounter == 154 && spt == 8 && bps == IBMSectorSizeCode.Kilo) { _imageInfo.MediaType = MediaType.NEC_525_HD; } else if (bps == IBMSectorSizeCode.HalfKilo) { switch (d88Hdr.track_table.Length) { case 40: { switch (spt) { case 8: _imageInfo.MediaType = MediaType.DOS_525_SS_DD_8; break; case 9: _imageInfo.MediaType = MediaType.DOS_525_SS_DD_9; break; } } break; case 80: { switch (spt) { case 8: _imageInfo.MediaType = MediaType.DOS_525_DS_DD_8; break; case 9: _imageInfo.MediaType = MediaType.DOS_525_DS_DD_9; break; } } break; case 160: { switch (spt) { case 15: _imageInfo.MediaType = MediaType.NEC_35_HD_15; break; case 9: _imageInfo.MediaType = MediaType.DOS_35_DS_DD_9; break; case 18: _imageInfo.MediaType = MediaType.DOS_35_HD; break; case 36: _imageInfo.MediaType = MediaType.DOS_35_ED; break; } } break; case 480: if (spt == 38) { _imageInfo.MediaType = MediaType.NEC_35_TD; } break; } } } AaruConsole.DebugWriteLine("D88 plugin", "MediaType: {0}", _imageInfo.MediaType); _imageInfo.ImageSize = (ulong)d88Hdr.disk_size; _imageInfo.CreationTime = imageFilter.GetCreationTime(); _imageInfo.LastModificationTime = imageFilter.GetLastWriteTime(); _imageInfo.MediaTitle = Path.GetFileNameWithoutExtension(imageFilter.GetFilename()); _imageInfo.Sectors = (ulong)_sectorsData.Count; _imageInfo.Comments = StringHandlers.CToString(d88Hdr.name, shiftjis); _imageInfo.XmlMediaType = XmlMediaType.BlockMedia; _imageInfo.SectorSize = (uint)(128 << (int)bps); switch (_imageInfo.MediaType) { case MediaType.NEC_525_SS: _imageInfo.Cylinders = 80; _imageInfo.Heads = 1; _imageInfo.SectorsPerTrack = 16; break; case MediaType.NEC_8_SD: case MediaType.NEC_8_DD: _imageInfo.Cylinders = 77; _imageInfo.Heads = 2; _imageInfo.SectorsPerTrack = 26; break; case MediaType.NEC_525_DS: _imageInfo.Cylinders = 80; _imageInfo.Heads = 2; _imageInfo.SectorsPerTrack = 16; break; case MediaType.NEC_525_HD: _imageInfo.Cylinders = 77; _imageInfo.Heads = 2; _imageInfo.SectorsPerTrack = 8; break; case MediaType.DOS_525_SS_DD_8: _imageInfo.Cylinders = 40; _imageInfo.Heads = 1; _imageInfo.SectorsPerTrack = 8; break; case MediaType.DOS_525_SS_DD_9: _imageInfo.Cylinders = 40; _imageInfo.Heads = 1; _imageInfo.SectorsPerTrack = 9; break; case MediaType.DOS_525_DS_DD_8: _imageInfo.Cylinders = 40; _imageInfo.Heads = 2; _imageInfo.SectorsPerTrack = 8; break; case MediaType.DOS_525_DS_DD_9: _imageInfo.Cylinders = 40; _imageInfo.Heads = 2; _imageInfo.SectorsPerTrack = 9; break; case MediaType.NEC_35_HD_15: _imageInfo.Cylinders = 80; _imageInfo.Heads = 2; _imageInfo.SectorsPerTrack = 15; break; case MediaType.DOS_35_DS_DD_9: _imageInfo.Cylinders = 80; _imageInfo.Heads = 2; _imageInfo.SectorsPerTrack = 9; break; case MediaType.DOS_35_HD: _imageInfo.Cylinders = 80; _imageInfo.Heads = 2; _imageInfo.SectorsPerTrack = 18; break; case MediaType.DOS_35_ED: _imageInfo.Cylinders = 80; _imageInfo.Heads = 2; _imageInfo.SectorsPerTrack = 36; break; case MediaType.NEC_35_TD: _imageInfo.Cylinders = 240; _imageInfo.Heads = 2; _imageInfo.SectorsPerTrack = 38; break; } return(true); }
public bool Identify(IFilter imageFilter) { Stream stream = imageFilter.GetDataForkStream(); stream.Seek(0, SeekOrigin.Begin); // Even if disk name is supposedly ASCII, I'm pretty sure most emulators allow Shift-JIS to be used :p var shiftjis = Encoding.GetEncoding("shift_jis"); if (stream.Length < Marshal.SizeOf <D88Header>()) { return(false); } byte[] hdrB = new byte[Marshal.SizeOf <D88Header>()]; stream.Read(hdrB, 0, hdrB.Length); D88Header d88Hdr = Marshal.ByteArrayToStructureLittleEndian <D88Header>(hdrB); AaruConsole.DebugWriteLine("D88 plugin", "d88hdr.name = \"{0}\"", StringHandlers.CToString(d88Hdr.name, shiftjis)); AaruConsole.DebugWriteLine("D88 plugin", "d88hdr.reserved is empty? = {0}", d88Hdr.reserved.SequenceEqual(_reservedEmpty)); AaruConsole.DebugWriteLine("D88 plugin", "d88hdr.write_protect = 0x{0:X2}", d88Hdr.write_protect); AaruConsole.DebugWriteLine("D88 plugin", "d88hdr.disk_type = {0} ({1})", d88Hdr.disk_type, (byte)d88Hdr.disk_type); AaruConsole.DebugWriteLine("D88 plugin", "d88hdr.disk_size = {0}", d88Hdr.disk_size); if (d88Hdr.disk_size != stream.Length) { return(false); } if (d88Hdr.disk_type != DiskType.D2 && d88Hdr.disk_type != DiskType.Dd2 && d88Hdr.disk_type != DiskType.Hd2) { return(false); } if (!d88Hdr.reserved.SequenceEqual(_reservedEmpty)) { return(false); } int counter = 0; foreach (int t in d88Hdr.track_table) { if (t > 0) { counter++; } if (t < 0 || t > stream.Length) { return(false); } } AaruConsole.DebugWriteLine("D88 plugin", "{0} tracks", counter); return(counter > 0); }