/// <summary> /// Reads a HFE disk image from a given stream. /// </summary> /// <param name="image">Stream containing the HFE disk image.</param> /// <param name="isWriteable">Allow write operations to this disk.</param> /// <returns>A disk object.</returns> public static HfeDisk Open(Stream image, bool isWriteable) { if (image == null) { throw new ArgumentNullException("image"); } if (!image.CanRead) { throw new NotSupportedException("Disk image stream does not support reading"); } if (!image.CanSeek) { throw new NotSupportedException("Disk image stream does not support seeking"); } if (isWriteable && !image.CanWrite) { throw new NotSupportedException("Disk image stream does not support writing"); } var diskHeader = new HfeDiskHeader(image); if (diskHeader.FloppyInterface != HfeDiskHeader.FloppyInterfaceMode.GENERIC_SHUGART_DD) { throw new DiskImageFormatException(String.Format("Unsupported floppy interface mode {0}", diskHeader.FloppyInterface)); } if (diskHeader.TrackEncoding != HfeDiskHeader.TrackEncodingMode.ISOIBM_MFM) { throw new DiskImageFormatException(String.Format("Unsupported track encoding mode {0}", diskHeader.TrackEncoding)); } if (diskHeader.TrackEncoding0 != HfeDiskHeader.TrackEncodingMode.ISOIBM_MFM) { throw new DiskImageFormatException( String.Format("Unsupported track encoding mode {0} for track 0 head 0", diskHeader.TrackEncoding0)); } if (diskHeader.Sides > 1 && diskHeader.TrackEncoding1 != HfeDiskHeader.TrackEncodingMode.ISOIBM_MFM) { throw new DiskImageFormatException( String.Format("Unsupported track encoding mode {0} for track 0 head 1", diskHeader.TrackEncoding1)); } var disk = new HfeDisk { DiskHeader = diskHeader, IsWriteable = isWriteable, diskImageStream = image }; disk.ReadTrackList(); return(disk); }
/// <summary> /// Create a new HFE disk associated with the given stream. /// </summary> /// <param name="image">Stream for storing the disk image.</param> /// <param name="heads">Number of disk heads.</param> /// <param name="tracks">Number of tracks per head.</param> /// <param name="sectors">Number of sectors per track.</param> /// <param name="sectorsize">Sector size in bytes</param> /// <returns>A disk object</returns> public static HfeDisk Create(Stream image, int heads, int tracks, int sectors, int sectorsize) { if (image == null) { throw new ArgumentNullException("image"); } if (!image.CanRead) { throw new NotSupportedException("Disk image stream does not support reading"); } if (!image.CanSeek) { throw new NotSupportedException("Disk image stream does not support seeking"); } if (!image.CanWrite) { throw new NotSupportedException("Disk image stream does not support writing"); } if (heads < 1 || heads > 2) { throw new NotSupportedException("HFE disk images only support 1 or 2 disk heads"); } var disk = new HfeDisk { IsWriteable = true, diskImageStream = image }; disk.DiskHeader = new HfeDiskHeader(heads, tracks, DefaultTrackListBlock); disk.trackBlock = new int[tracks]; disk.trackLength = new int[tracks]; int trackBlock = DefaultTrackListBlock + 1; for (var t = 0; t < tracks; t++) { var trackLength = disk.CreateTrack(heads, t, sectors, sectorsize, trackBlock); disk.trackBlock[t] = trackBlock; disk.trackLength[t] = trackLength; trackBlock += (trackLength + BlockSize - 1) / BlockSize; } var encodedHeader = disk.DiskHeader.Encode(); image.Seek(0, SeekOrigin.Begin); image.Write(encodedHeader, 0, encodedHeader.Length); disk.WriteTrackList(); return(disk); }
/// <summary> /// Creates a new virtual disk image file and returns a Disk object associated with it. The file name extension determines the /// type of Disk object actually returned. /// </summary> /// <param name="filename">File name of virtual disk image.</param> /// <param name="heads">Number of disk heads.</param> /// <param name="tracks">Number of disk tracks per head.</param> /// <param name="sectors">Number of disk sectors per track and per head.</param> /// <param name="sectorsize">The size of each sector measured in bytes.</param> /// <returns>A Disk object associated with the given file.</returns> public static IDisk CreateDisk(string filename, int heads, int tracks, int sectors, int sectorsize) { filename = filename.ToLowerInvariant(); if (filename.EndsWith(".vdk")) { return(VdkDisk.Create(new FileStream(filename, FileMode.Create), heads, tracks, sectors)); } if (filename.EndsWith(".dsk")) { return(JvcDisk.Create(new FileStream(filename, FileMode.Create), heads, tracks, sectors, sectorsize)); } if (filename.EndsWith(".hfe")) { return(HfeDisk.Create(new FileStream(filename, FileMode.Create), heads, tracks, sectors, sectorsize)); } if (filename.EndsWith(".dmk")) { return(DmkDisk.Create(new FileStream(filename, FileMode.Create), heads, tracks, sectors, sectorsize)); } return(null); }
/// <summary> /// Returns a Disk object associated with an existing virtual disk image file. The name (extension) of the file name determines the /// type of Disk object actually returned. /// </summary> /// <param name="filename">File name of virtual disk image.</param> /// <param name="iswriteable">Returns a writeable Disk object if this is <value>true</value>.</param> /// <returns>A Disk object associated with the given file.</returns> public static IDisk OpenDisk(string filename, bool iswriteable) { filename = filename.ToLowerInvariant(); var access = iswriteable ? FileAccess.ReadWrite : FileAccess.Read; if (filename.EndsWith(".vdk")) { return(VdkDisk.Open(new FileStream(filename, FileMode.Open, access), iswriteable)); } if (filename.EndsWith(".dsk")) { return(JvcDisk.Open(new FileStream(filename, FileMode.Open, access), iswriteable)); } if (filename.EndsWith(".hfe")) { return(HfeDisk.Open(new FileStream(filename, FileMode.Open, access), iswriteable)); } if (filename.EndsWith(".dmk")) { return(DmkDisk.Open(new FileStream(filename, FileMode.Open, access), iswriteable)); } return(null); }
/// <summary> /// Dump raw track data after MFM encoding. /// </summary> /// <param name="diskStream">Stream for reading the disk image data.</param> /// <param name="disk">Disk.</param> /// <param name="headId">Head.</param> /// <param name="trackId">Track.</param> void DumpTrackData(Stream diskStream, HfeDisk disk, int headId, int trackId) { Console.WriteLine(); Console.Write("Track data for track {0} side {1}", trackId, headId); Console.WriteLine(); var t = disk.GetTrack(trackId, headId); var trackStream = new MfmStream(new HfeRawTrack(diskStream, t.TrackOffset, t.TrackLength, headId)); var offset = 0; var done = false; var buffer = new byte[16]; while (!done) { Console.Write(String.Format("{0:x4} : ", offset)); var len = trackStream.Read(buffer, 0, buffer.Length); for (var i = 0; i < Math.Min(buffer.Length, len); i++) { Console.Write(String.Format("{0:x2} ", buffer[i])); } Console.WriteLine(); done = (len < buffer.Length); offset += len; } trackStream.Dispose(); }
/// <summary> /// Reads a HFE disk image from a given stream. /// </summary> /// <param name="image">Stream containing the HFE disk image.</param> /// <param name="isWriteable">Allow write operations to this disk.</param> /// <returns>A disk object.</returns> public static HfeDisk Open(Stream image, bool isWriteable) { if (image == null) throw new ArgumentNullException("image"); if (!image.CanRead) throw new NotSupportedException("Disk image stream does not support reading"); if (!image.CanSeek) throw new NotSupportedException("Disk image stream does not support seeking"); if (isWriteable && !image.CanWrite) throw new NotSupportedException("Disk image stream does not support writing"); var diskHeader = new HfeDiskHeader(image); if (diskHeader.FloppyInterface != HfeDiskHeader.FloppyInterfaceMode.GENERIC_SHUGART_DD) throw new DiskImageFormatException(String.Format("Unsupported floppy interface mode {0}", diskHeader.FloppyInterface)); if (diskHeader.TrackEncoding != HfeDiskHeader.TrackEncodingMode.ISOIBM_MFM) throw new DiskImageFormatException(String.Format("Unsupported track encoding mode {0}", diskHeader.TrackEncoding)); if (diskHeader.TrackEncoding0 != HfeDiskHeader.TrackEncodingMode.ISOIBM_MFM) throw new DiskImageFormatException( String.Format("Unsupported track encoding mode {0} for track 0 head 0", diskHeader.TrackEncoding0)); if (diskHeader.Sides > 1 && diskHeader.TrackEncoding1 != HfeDiskHeader.TrackEncodingMode.ISOIBM_MFM) throw new DiskImageFormatException( String.Format("Unsupported track encoding mode {0} for track 0 head 1", diskHeader.TrackEncoding1)); var disk = new HfeDisk {DiskHeader = diskHeader, IsWriteable = isWriteable, diskImageStream = image}; disk.ReadTrackList(); return disk; }
/// <summary> /// Create a new HFE disk associated with the given stream. /// </summary> /// <param name="image">Stream for storing the disk image.</param> /// <param name="heads">Number of disk heads.</param> /// <param name="tracks">Number of tracks per head.</param> /// <param name="sectors">Number of sectors per track.</param> /// <param name="sectorsize">Sector size in bytes</param> /// <returns>A disk object</returns> public static HfeDisk Create(Stream image, int heads, int tracks, int sectors, int sectorsize) { if (image == null) throw new ArgumentNullException("image"); if (!image.CanRead) throw new NotSupportedException("Disk image stream does not support reading"); if (!image.CanSeek) throw new NotSupportedException("Disk image stream does not support seeking"); if (!image.CanWrite) throw new NotSupportedException("Disk image stream does not support writing"); if (heads < 1 || heads > 2) throw new NotSupportedException("HFE disk images only support 1 or 2 disk heads"); var disk = new HfeDisk {IsWriteable = true, diskImageStream = image}; disk.DiskHeader = new HfeDiskHeader(heads, tracks, DefaultTrackListBlock); disk.trackBlock = new int[tracks]; disk.trackLength = new int[tracks]; int trackBlock = DefaultTrackListBlock + 1; for (var t = 0; t < tracks; t++) { var trackLength = disk.CreateTrack(heads, t, sectors, sectorsize, trackBlock); disk.trackBlock[t] = trackBlock; disk.trackLength[t] = trackLength; trackBlock += (trackLength + BlockSize - 1)/BlockSize; } var encodedHeader = disk.DiskHeader.Encode(); image.Seek(0, SeekOrigin.Begin); image.Write(encodedHeader, 0, encodedHeader.Length); disk.WriteTrackList(); return disk; }