2 using System.Collections.Generic;
7 using System.Threading.Tasks;
8 using System.Windows.Controls;
12 private TextBox _infoBox;
33 List<byte> buffer =
new List<byte>();
34 bool status = encodeIPF(buffer, fd);
37 fs =
new FileStream(fileName, FileMode.Create, FileAccess.Write, FileShare.Read);
39 catch (Exception exc) {
40 Console.WriteLine(
"Error: {0}", exc.Message);
43 fs.Write(buffer.ToArray(), 0, buffer.Count);
50 private bool encodeIPF(List<byte> buffer,
Floppy fd) {
57 writeByte(buffer, (byte)
'C');
58 writeByte(buffer, (byte)
'A');
59 writeByte(buffer, (byte)
'P');
60 writeByte(buffer, (byte)
'S');
61 writeInt32(buffer, 12);
62 crc_pos = buffer.Count;
63 writeInt32(buffer, 0);
65 crc =
Utilities.crc32Buffer(buffer, 0, 12);
66 writeInt32(buffer, crc_pos, crc);
98 writeByte(buffer, (byte)
'I');
99 writeByte(buffer, (byte)
'N');
100 writeByte(buffer, (byte)
'F');
101 writeByte(buffer, (byte)
'O');
102 writeInt32(buffer, 96);
103 crc_pos = buffer.Count;
104 writeInt32(buffer, 0);
106 writeInt32(buffer, (uint)info.
mediaType);
109 writeInt32(buffer, info.
fileKey);
110 writeInt32(buffer, info.
fileRev);
111 writeInt32(buffer, info.
origin);
114 writeInt32(buffer, info.
minSide);
115 writeInt32(buffer, info.
maxSide);
118 for (
int i = 0; i < 4; i++)
119 writeInt32(buffer, (uint)info.
platforms[i]);
122 for (
int i = 0; i < 3; i++)
123 writeInt32(buffer, info.
reserved[i]);
125 crc =
Utilities.crc32Buffer(buffer, start, 96);
126 writeInt32(buffer, crc_pos, crc);
130 for (uint track = 0; track < 84; track++) {
131 for (uint side = 0; side < 2; side++) {
132 Track t = fd.tracks[track, side];
137 image.density = t.density;
139 image.trackBytes = t.trackBytes;
140 image.startBytePos = t.startBitPos / 8;
141 image.startBitPos = t.startBitPos;
142 image.dataBits = t.dataBits;
143 image.gapBits = t.gapBits;
144 image.trackBits = t.dataBits + t.gapBits;
145 image.blockCount = t.blockCount;
147 image.trackFlags = t.trackFlags;
148 image.dataKey = dataKey++;
152 start = buffer.Count;
153 writeByte(buffer, (byte)
'I');
154 writeByte(buffer, (byte)
'M');
155 writeByte(buffer, (byte)
'G');
156 writeByte(buffer, (byte)
'E');
157 writeInt32(buffer, 80);
158 crc_pos = buffer.Count;
159 writeInt32(buffer, 0);
161 writeInt32(buffer, image.track);
162 writeInt32(buffer, image.side);
163 writeInt32(buffer, (uint)image.density);
164 writeInt32(buffer, (uint)image.signalType);
165 writeInt32(buffer, image.trackBytes);
166 writeInt32(buffer, image.startBytePos);
167 writeInt32(buffer, image.startBitPos);
168 writeInt32(buffer, image.dataBits);
169 writeInt32(buffer, image.gapBits);
170 writeInt32(buffer, image.trackBits);
171 writeInt32(buffer, image.blockCount);
172 writeInt32(buffer, image.encoder);
173 writeInt32(buffer, (uint)image.trackFlags);
174 writeInt32(buffer, image.dataKey);
175 for (
int i = 0; i < 3; i++)
176 writeInt32(buffer, image.
reserved[i]);
178 crc =
Utilities.crc32Buffer(buffer, start, 80);
179 writeInt32(buffer, crc_pos, crc);
184 for (uint track = 0; track < 84; track++) {
185 for (uint side = 0; side < 2; side++) {
186 Track t = fd.tracks[track, side];
188 start = buffer.Count;
189 writeByte(buffer, (byte)
'D');
190 writeByte(buffer, (byte)
'A');
191 writeByte(buffer, (byte)
'T');
192 writeByte(buffer, (byte)
'A');
193 writeInt32(buffer, 28);
194 crc_pos = buffer.Count;
195 writeInt32(buffer, 0);
198 List<byte> extraDataBlock =
new List<byte>();
201 foreach (Sector sector
in t.sectors) {
202 BlockDescriptor bd =
new BlockDescriptor();
203 bd.dataBits = sector.dataBits;
204 bd.gapBits = sector.gapBits;
208 bd.blockFlags = sector.flags;
209 bd.gapDefaultValue = 0;
212 writeInt32(extraDataBlock, bd.dataBits);
213 writeInt32(extraDataBlock, bd.gapBits);
214 writeInt32(extraDataBlock, bd.gapOffset);
215 writeInt32(extraDataBlock, (uint)bd.cellType);
216 writeInt32(extraDataBlock, (uint)bd.encoderType);
217 writeInt32(extraDataBlock, (uint)bd.blockFlags);
218 writeInt32(extraDataBlock, bd.gapDefaultValue);
219 writeInt32(extraDataBlock, bd.dataOffset);
223 int gapOffset = t.sectors.Count * 32;
225 foreach (Sector sector
in t.sectors) {
229 writeInt32(extraDataBlock, (secNum * 32) + 8, (uint)gapOffset);
232 foreach (GapElement ge
in sector.gapElems) {
233 if (ge.type !=
GapType.Forward)
continue;
234 writeGapElem(extraDataBlock, ge.gapBytes, ge.value);
235 gapOffset += (ge.gapBytes == 0) ? 3 : ((ge.gapBytes * 8) < 256) ? 5 : 6;
237 writeByte(extraDataBlock, 0);
242 foreach (GapElement ge
in sector.gapElems) {
243 if (ge.type !=
GapType.Backward)
continue;
244 writeGapElem(extraDataBlock, ge.gapBytes, ge.value);
245 gapOffset += (ge.gapBytes == 0) ? 3 : ((ge.gapBytes * 8) < 256) ? 5 : 6;
247 writeByte(extraDataBlock, 0);
256 int dataOffset = gapOffset;
258 foreach (Sector sector
in t.sectors) {
260 writeInt32(extraDataBlock, (secNum * 32) + 28, (uint)dataOffset);
262 foreach (DataElem de
in sector.dataElems) {
263 writeDataElem(extraDataBlock, de.type, de.dataBytes, de.value);
264 dataOffset += ((de.dataBytes < 255) ? 2 : 3) + (int)de.dataBytes;
266 writeByte(extraDataBlock, 0);
273 DataRecord data =
new DataRecord();
274 data.length = (uint)extraDataBlock.Count;
275 data.bitSize = data.length * 8;
276 data.crc = Utilities.crc32Buffer(extraDataBlock, 0, (
int)data.length);
277 data.key = dataKey++;
279 writeInt32(buffer, data.length);
280 writeInt32(buffer, data.bitSize);
281 writeInt32(buffer, data.crc);
282 writeInt32(buffer, data.key);
284 crc = Utilities.crc32Buffer(buffer, start, 28);
285 writeInt32(buffer, crc_pos, crc);
288 foreach (byte b
in extraDataBlock)
298 private void writeGapElem(List<byte> buffer, uint byteCount, byte value) {
299 uint bitCount = byteCount * 8;
302 if (bitCount < 256) {
303 writeByte(buffer, 0x21);
304 writeByte(buffer, (byte)bitCount);
307 writeByte(buffer, 0x41);
308 writeByte(buffer, (byte)(bitCount / 256));
309 writeByte(buffer, (byte)(bitCount & 0xFF));
313 writeByte(buffer, 0x22);
314 writeByte(buffer, 8);
315 writeByte(buffer, value);
319 private void writeDataElem(List<byte> buffer,
DataType type, uint byteCount, List<byte> value) {
320 byte dataHead = (byte)((
int)type + ((byteCount < 256) ? 0x20 : 0x40));
321 writeByte(buffer, dataHead);
322 if (byteCount < 256) {
323 writeByte(buffer, (byte)byteCount);
326 writeByte(buffer, (byte)(byteCount / 256));
327 writeByte(buffer, (byte)(byteCount & 0xFF));
330 Debug.Assert(byteCount == value.Count,
"Lenght error in dataElem");
331 for (
int i = 0; i < byteCount; i++) {
332 writeByte(buffer, value[i]);
337 private static void writeInt32(List<byte> buffer,
int buf_position, uint value) {
338 buffer[buf_position] = (byte)((value >> 24) & 0xFF);
339 buffer[buf_position + 1] = (byte)((value >> 16) & 0xFF);
340 buffer[buf_position + 2] = (byte)((value >> 8) & 0xFF);
341 buffer[buf_position + 3] = (byte)(value & 0xFF);
345 private static void writeInt32(List<byte> buffer, uint val) {
346 buffer.Add((byte)((val >> 24) & 0xFF));
347 buffer.Add((byte)((val >> 16) & 0xFF));
348 buffer.Add((byte)((val >> 8) & 0xFF));
349 buffer.Add((byte)(val & 0xFF));
353 private static void writeByte(List<byte> buffer, byte val) {
uint diskNumber
Number of the disk in a multi-disc release otherwise 0
uint creatorId
A unique user ID of the disk image creator
BlockFlags
Flags for a block descriptor
bool writeIPF(string fileName, Floppy fd)
Write an IPF file from the Floppy structure
uint fileRev
Revision of the file.
uint creationTime
The image creation time: Specify the hour, the minute, the second, and the tick
DataType
Type of Data in data element
Store information about all tracks of a FD
uint origin
Reference to original source
uint[] reserved
reserved for future
uint[] reserved
reserved for future
uint creationDate
The image creation date: Specify the year, the month, the day
GapType
Type of a gap element
MediaType mediaType
Type of media imaged
The image record definition
uint minTrack
The first track number of the floppy image.
uint encoderRev
Image encoder revision
SignalType
Signal Processing Type
uint minSide
The lowest head (side) number of the floppy image.
uint maxTrack
The last track number of the floppy image.
IPFWriter(TextBox tb)
The IPF Writer Constructor
uint fileKey
Each IPF file has a unique ID that can be used as a unique key for database
The info record definition
EncoderType encoderType
image encoder type
Store information about one track
BlockEncoderType
Block Encoder Type
Platform[] platforms
Array of four possible platforms
uint maxSide
The highest head (side) number of the floppy image. Usually 1