/// <summary> /// Write sector data, including the CRC, to the stream. The stream must be positioned at the first byte of the sector /// payload data. /// </summary> /// <param name="data">Sector data buffer.</param> /// <param name="offset">Offset of the first byte of sector data into the data buffer.</param> /// <param name="length">Size of the sector data.</param> private void WriteSectorData(byte[] data, int offset, int length) { Sync(); var blockId = trackStream.ReadByte(); if (blockId == -1) { throw new DiskImageFormatException("Sector data not found after sector address mark"); } if (blockId != DataAddressMark) { throw new DiskImageFormatException(String.Format("Unexpected block type {0}", blockId)); } var crc = new Crc16Ccitt(); crc.Add(0xa1); crc.Add(0xa1); crc.Add(0xa1); crc.Add(DataAddressMark); for (int i = 0; i < length; i++) { crc.Add(data[offset + i]); } trackStream.Write(data, offset, length); trackStream.WriteByte((byte)((crc.Crc >> 8) & 0xff)); trackStream.WriteByte((byte)(crc.Crc & 0xff)); }
/// <summary> /// Initialize (format) a track by writing headers and sectors to it. /// </summary> /// <param name="diskStream">Stream for writing the disk track.</param> /// <param name="trackOffset">Byte offset of the track data in the disk image.</param> /// <param name="headId">Side of disk for initializing the track.</param> /// <param name="sectors">Collection of sectors to be written to the track.</param> /// <returns>The track length in the disk image stream.</returns> static internal int InitializeTrack(Stream diskStream, int trackOffset, int headId, IEnumerable <HfeSector> sectors) { var rawStream = new HfeRawTrack(diskStream, trackOffset, headId); var trackStream = new MfmStream(rawStream); trackStream.WriteBytes(0x4e, PreableLength); foreach (var sector in sectors) { // Write gap preceeding sector ID record trackStream.WriteBytes(0x4e, 24); trackStream.WriteBytes(0x00, 12); trackStream.WriteSync(); trackStream.WriteSync(); trackStream.WriteSync(); // Write sector ID record var sectorInfo = sector.GetSectorInfo(); var encodedIdRecord = sectorInfo.Encode(); trackStream.Write(encodedIdRecord, 0, encodedIdRecord.Length); // Write gap preceeding sector data record trackStream.WriteBytes(0x4e, 22); trackStream.WriteBytes(0x00, 12); trackStream.WriteSync(); trackStream.WriteSync(); trackStream.WriteSync(); // Write sector data record var encodedDataRecord = sector.Encode(); trackStream.Write(encodedDataRecord, 0, encodedDataRecord.Length); } trackStream.WriteBytes(0x4e, PostambleLength); trackStream.Flush(); return(rawStream.TrackLength - trackOffset); }