/[projet1]/public/pc/tools/osdk/main/makedisk/Floppy.cpp
Defence Force logotype

Contents of /public/pc/tools/osdk/main/makedisk/Floppy.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1035 - (show annotations)
Sun Dec 15 15:35:39 2013 UTC (5 years, 11 months ago) by dbug
File size: 23307 byte(s)
FloppyBuilder 0.9
- Added the 'SetCompressionMode' command. Possible parameters are 'None' (default value) and 'FilePack'
The lzpack.cpp file moved out from FilePack and is now in Common, this means it will be usable in other projects (Like PictConv)
1
2 #include "infos.h"
3
4 #include <stdlib.h>
5 #include <stdio.h>
6 #include <sstream>
7 #include <iostream>
8 #include <string.h>
9
10 #include <assert.h>
11
12 #include "Floppy.h"
13
14 #include "common.h"
15
16
17
18
19 FloppyHeader::FloppyHeader()
20 {
21 assert(sizeof(*this)==256);
22 memset(this,0,sizeof(*this));
23 }
24
25 FloppyHeader::~FloppyHeader()
26 {
27 }
28
29 bool FloppyHeader::IsValidHeader() const
30 {
31 if (memcmp(m_Signature,"MFM_DISK",8)!=0) return false;
32
33 int sideNumber=GetSideNumber();
34 if ((sideNumber<1) || (sideNumber>2)) return false;
35
36 int trackNumber=GetTrackNumber();
37 if ((trackNumber<30) || (trackNumber>82)) return false;
38
39 return true;
40 }
41
42
43 void FloppyHeader::Clear()
44 {
45 memset(this,0,sizeof(FloppyHeader));
46 }
47
48 void FloppyHeader::SetSignature(char signature[8])
49 {
50 memcpy(m_Signature,signature,8);
51 }
52
53
54 void FloppyHeader::SetSideNumber(int sideNumber)
55 {
56 m_Sides[0]=(sideNumber>>0)&255;
57 m_Sides[1]=(sideNumber>>8)&255;
58 m_Sides[2]=(sideNumber>>16)&255;
59 m_Sides[3]=(sideNumber>>24)&255;
60 }
61
62 int FloppyHeader::GetSideNumber() const
63 {
64 int sideNumber= ( ( ( ( (m_Sides[3]<<8) | m_Sides[2]) << 8 ) | m_Sides[1]) << 8 ) | m_Sides[0];
65 return sideNumber;
66 }
67
68
69 void FloppyHeader::SetTrackNumber(int trackNumber)
70 {
71 m_Tracks[0]=(trackNumber>>0)&255;
72 m_Tracks[1]=(trackNumber>>8)&255;
73 m_Tracks[2]=(trackNumber>>16)&255;
74 m_Tracks[3]=(trackNumber>>24)&255;
75 }
76
77 int FloppyHeader::GetTrackNumber() const
78 {
79 int trackNumber= ( ( ( ( (m_Tracks[3]<<8) | m_Tracks[2]) << 8 ) | m_Tracks[1]) << 8 ) | m_Tracks[0];
80 return trackNumber;
81 }
82
83 void FloppyHeader::SetGeometry(int geometry)
84 {
85 m_Geometry[0]=(geometry>>0)&255;
86 m_Geometry[1]=(geometry>>8)&255;
87 m_Geometry[2]=(geometry>>16)&255;
88 m_Geometry[3]=(geometry>>24)&255;
89 }
90
91 int FloppyHeader::GetGeometry() const
92 {
93 int geometry= ( ( ( ( (m_Geometry[3]<<8) | m_Geometry[2]) << 8 ) | m_Geometry[1]) << 8 ) | m_Geometry[0];
94 return geometry;
95 }
96
97 int FloppyHeader::FindNumberOfSectors(int& firstSectorOffset,int& sectorInterleave) const
98 {
99 firstSectorOffset=0;
100 sectorInterleave=0;
101
102 /*
103 Format of a track:
104 6400 bytes in total
105 - gap1: 72/12 bytes at the start of the track (with zeroes)
106 Then for each sector:
107 - ?: 4 bytes (A1 A1 A1 FE)
108 - track number: 1 byte (0-40-80...)
109 - side number: 1 byte (0-1)
110 - sector number: 1 byte (1-18-19)
111 - one: 1 byte (1)
112 - crc: 2 bytes (crc of the 8 previous bytes)
113 - gap2: 34 bytes (22xAE , 12x00)
114 - ?: 4 bytes (A1 A1 A1 FB)
115 - data: 256 bytes
116 - crc: 2 bytes (crc of the 256+4 previous bytes)
117 - gap3: 50/46 bytes
118 */
119 unsigned char* trackDataStart=(unsigned char*)(this+1);
120 unsigned char* trackData =trackDataStart;
121 unsigned char* trackDataEnd=trackDataStart+6400;
122
123 int lastSectorFound=0;
124 while (trackData<(trackDataEnd-16))
125 {
126 if ( (trackData[0]==0xa1) && (trackData[1]==0xa1) && (trackData[2]==0xa1) && (trackData[3]==0xfe) )
127 {
128 // Found a marker for a synchronization sequence for a sector [#A1 #A1 #A1], [#FE Track Side Sector tt CRC CRC]
129 int sectorNumber=trackData[6];
130 if (sectorNumber==(lastSectorFound+1))
131 {
132 lastSectorFound=sectorNumber;
133 }
134 else
135 {
136 ShowError("There's something wrong in the track structure of the floppy, the sector id does not make sense.");
137 }
138 trackData+=10; // Skip synchronization sequence
139 trackData+=34; // - gap2: 34 bytes (22xAE , 12x00)
140 trackData+=4; // - ?: 4 bytes (A1 A1 A1 FB)
141
142 if (sectorNumber==1)
143 {
144 firstSectorOffset=trackData-trackDataStart;
145 }
146 else
147 if (sectorNumber==2)
148 {
149 sectorInterleave=trackData-trackDataStart-firstSectorOffset;
150 }
151 trackData+=256; // Sector data
152 }
153 else
154 {
155 trackData++;
156 }
157 }
158
159 return lastSectorFound;
160 }
161
162
163
164 FileEntry::FileEntry() :
165 m_FloppyNumber(0),
166 m_StartSide(0),
167 m_StartTrack(0),
168 m_StartSector(1),
169 m_SectorCount(0),
170 m_LoadAddress(0),
171 m_FileSize(0),
172 m_CompressionMode(e_CompressionNone),
173 m_CompressedFileSize(0)
174 {
175 }
176
177 FileEntry::~FileEntry()
178 {
179 }
180
181
182
183
184 Floppy::Floppy() :
185 m_Buffer(0),
186 m_BufferSize(0),
187 m_TrackNumber(0),
188 m_SectorNumber(0),
189 m_CurrentTrack(0),
190 m_CurrentSector(1),
191 m_CompressionMode(e_CompressionNone),
192 m_OffsetFirstSector(156), // 156 (Location of the first byte of data of the first sector)
193 m_InterSectorSpacing(358) // 358 (Number of bytes to skip to go to the next sector: 256+59+43)
194 {
195 }
196
197
198 Floppy::~Floppy()
199 {
200 delete m_Buffer;
201 }
202
203
204 unsigned int crctab[256] =
205 {
206 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7,
207 0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF,
208 0x1231, 0x0210, 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6,
209 0x9339, 0x8318, 0xB37B, 0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE,
210 0x2462, 0x3443, 0x0420, 0x1401, 0x64E6, 0x74C7, 0x44A4, 0x5485,
211 0xA56A, 0xB54B, 0x8528, 0x9509, 0xE5EE, 0xF5CF, 0xC5AC, 0xD58D,
212 0x3653, 0x2672, 0x1611, 0x0630, 0x76D7, 0x66F6, 0x5695, 0x46B4,
213 0xB75B, 0xA77A, 0x9719, 0x8738, 0xF7DF, 0xE7FE, 0xD79D, 0xC7BC,
214 0x48C4, 0x58E5, 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823,
215 0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969, 0xA90A, 0xB92B,
216 0x5AF5, 0x4AD4, 0x7AB7, 0x6A96, 0x1A71, 0x0A50, 0x3A33, 0x2A12,
217 0xDBFD, 0xCBDC, 0xFBBF, 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A,
218 0x6CA6, 0x7C87, 0x4CE4, 0x5CC5, 0x2C22, 0x3C03, 0x0C60, 0x1C41,
219 0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD, 0xAD2A, 0xBD0B, 0x8D68, 0x9D49,
220 0x7E97, 0x6EB6, 0x5ED5, 0x4EF4, 0x3E13, 0x2E32, 0x1E51, 0x0E70,
221 0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A, 0x9F59, 0x8F78,
222 0x9188, 0x81A9, 0xB1CA, 0xA1EB, 0xD10C, 0xC12D, 0xF14E, 0xE16F,
223 0x1080, 0x00A1, 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046, 0x6067,
224 0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C, 0xE37F, 0xF35E,
225 0x02B1, 0x1290, 0x22F3, 0x32D2, 0x4235, 0x5214, 0x6277, 0x7256,
226 0xB5EA, 0xA5CB, 0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D,
227 0x34E2, 0x24C3, 0x14A0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
228 0xA7DB, 0xB7FA, 0x8799, 0x97B8, 0xE75F, 0xF77E, 0xC71D, 0xD73C,
229 0x26D3, 0x36F2, 0x0691, 0x16B0, 0x6657, 0x7676, 0x4615, 0x5634,
230 0xD94C, 0xC96D, 0xF90E, 0xE92F, 0x99C8, 0x89E9, 0xB98A, 0xA9AB,
231 0x5844, 0x4865, 0x7806, 0x6827, 0x18C0, 0x08E1, 0x3882, 0x28A3,
232 0xCB7D, 0xDB5C, 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A,
233 0x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1, 0x1AD0, 0x2AB3, 0x3A92,
234 0xFD2E, 0xED0F, 0xDD6C, 0xCD4D, 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9,
235 0x7C26, 0x6C07, 0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1,
236 0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8,
237 0x6E17, 0x7E36, 0x4E55, 0x5E74, 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0
238 };
239
240 void compute_crc(unsigned char *ptr,int count)
241 {
242 int i;
243 unsigned short crc=0xFFFF,byte;
244 for (i=0;i<count;i++) {
245 byte= *ptr++;
246 crc=(crc<<8)^crctab[(crc>>8)^byte];
247 }
248 *ptr++=crc>>8;
249 *ptr++=crc&0xFF;
250 }
251
252
253 bool Floppy::CreateDisk(int numberOfSides,int numberOfTracks,int numberOfSectors)
254 {
255 // Heavily based on MakeDisk and Tap2DSk
256 int gap1,gap2,gap3;
257
258 switch (numberOfSectors)
259 {
260 case 15: case 16: case 17:
261 gap1=72; gap2=34; gap3=50;
262 break;
263
264 case 18:
265 gap1=12; gap2=34; gap3=46;
266 break;
267
268 default:
269 ShowError("Unrealistic sectors per track number\n");
270 }
271
272 m_BufferSize=256+numberOfSides*numberOfTracks*6400;
273 m_Buffer=malloc(m_BufferSize);
274 if (m_Buffer)
275 {
276 m_TrackNumber =numberOfTracks; // 42
277 m_SectorNumber=numberOfSectors; // 17
278 m_SideNumber =numberOfSides; // 2
279
280 FloppyHeader& header(*((FloppyHeader*)m_Buffer));
281 header.Clear();
282 header.SetSignature("MFM_DISK");
283 header.SetSideNumber(numberOfSides);
284 header.SetTrackNumber(numberOfTracks);
285 header.SetGeometry(1);
286
287 unsigned char* trackbuf=(unsigned char*)m_Buffer+256;
288 for (int s=0;s<numberOfSides;s++)
289 {
290 for (int t=0;t<numberOfTracks;t++)
291 {
292 {
293 int i;
294 int offset=0;
295 for (i=0;i<gap1-12;i++)
296 {
297 trackbuf[offset++]=0x4E;
298 }
299 for (int j=0;j<numberOfSectors;j++)
300 {
301 for (i=0;i<12;i++) trackbuf[offset++]=0;
302 for (i=0;i<3;i++) trackbuf[offset++]=0xA1;
303 trackbuf[offset++]=0xFE;
304 for (i=0;i<6;i++) offset++;
305 for (i=0;i<gap2-12;i++) trackbuf[offset++]=0x22;
306 for (i=0;i<12;i++) trackbuf[offset++]=0;
307 for (i=0;i<3;i++) trackbuf[offset++]=0xA1;
308 trackbuf[offset++]=0xFB;
309 for (i=0;i<258;i++) offset++;
310 for (i=0;i<gap3-12;i++) trackbuf[offset++]=0x4E;
311 }
312
313 while (offset<6400)
314 {
315 trackbuf[offset++]=0x4E;
316 }
317 }
318 int offset=gap1;
319 for (int i=0;i<numberOfSectors;i++)
320 {
321 trackbuf[offset+4]=t;
322 trackbuf[offset+5]=s;
323 trackbuf[offset+6]=i+1;
324 trackbuf[offset+7]=1;
325 compute_crc(trackbuf+offset,4+4);
326 offset+=4+6;
327 offset+=gap2;
328 memset(trackbuf+offset+4,0,256);
329 compute_crc(trackbuf+offset,4+256);
330 offset+=256+6;
331 offset+=gap3;
332 }
333 trackbuf+=6400;
334 }
335 }
336 if (header.IsValidHeader())
337 {
338 m_SectorNumber=header.FindNumberOfSectors(m_OffsetFirstSector,m_InterSectorSpacing); //17; // Can't figure out that from the header Oo
339 return true;
340 }
341 }
342
343 return false;
344 }
345
346
347 bool Floppy::LoadDisk(const char* fileName)
348 {
349 if (LoadFile(fileName,m_Buffer,m_BufferSize))
350 {
351 const FloppyHeader& header(*((FloppyHeader*)m_Buffer));
352 if (header.IsValidHeader())
353 {
354 m_TrackNumber =header.GetTrackNumber();
355 m_SideNumber =header.GetSideNumber();
356 m_SectorNumber=header.FindNumberOfSectors(m_OffsetFirstSector,m_InterSectorSpacing); //17; // Can't figure out that from the header Oo
357 return true;
358 }
359 }
360 return false;
361 }
362
363
364 bool Floppy::SaveDisk(const char* fileName) const
365 {
366 if (m_Buffer)
367 {
368 return SaveFile(fileName,m_Buffer,m_BufferSize);
369 }
370 return false;
371 }
372
373 /*
374 Début de la piste (facultatif): 80 [#4E], 12 [#00], [#C2 #C2 #C2 #FC] et 50 [#4E] (soit 146 octets selon
375 la norme IBM) ou 40 [#4E], 12 [#00], [#C2 #C2 #C2 #FC] et 40 [#4E] (soit 96 octets pour SEDORIC).
376
377 Pour chaque secteur: 12 [#00], 3 [#A1] [#FE #pp #ff #ss #tt CRC], 22 [#4E], 12 [#00], 3 [#A1], [#FB],
378 les 512 octets, [CRC CRC], 80 octets [#4E] (#tt = #02) (soit 141 + 512 = 653 octets selon la norme IBM)
379 ou 12 [#00], 3 [#A1] [#FE #pp #ff #ss #01 CRC CRC], 22 [#4E], 12 [#00], 3 [#A1], [#FB], les 256
380 octets, [CRC CRC], 12, 30 ou 40 octets [#4E] (selon le nombre de secteurs/piste). Soit environ 256 + (72
381 à 100) = 328 à 356 octets pour SEDORIC.
382
383 Fin de la piste (facultatif): un nombre variable d'octets [#4E
384
385 Selon NIBBLE,
386 une piste IBM compte 146 octets de début de piste + 9 secteurs de 653 octets + 257 octets de fin de piste = 6280 octets.
387 Une piste SEDORIC, formatée à 17 secteurs, compte 96 octets de début de piste + 17 secteurs de 358 octets + 98 octets de fin de piste = 6280 octets.
388 Une piste SEDORIC, formatée à 19 secteurs, compte 0 octet de début de piste + 19 secteurs de 328 octets + 48 octets de fin de piste = 6280 octets.
389 On comprend mieux le manque de fiabilité du formatage en 19 secteurs/piste dû à la faible largeur des zones de sécurité (12 [#4E] entre chaque secteur et 48 octets entre le dernier et le premier).
390
391 Lors de l'élaboration du tampon de formatage SEDORIC, les octets #C2 sont remplacés par des octets
392 #F6, les octets #A1 sont remplacés par des octets #F5 et chaque paire de 2 octets [CRC CRC] et
393 remplacée par un octet #F7. Comme on le voit, nombre de variantes sont utilisées, sauf la zone 22 [#4E],
394 12 [#00], 3 [#A1] qui est strictement obligatoire.
395
396 // From DskTool:
397 15, 16 or 17 sectors: gap1=72; gap2=34; gap3=50;
398 18 sectors: gap1=12; gap2=34; gap3=46;
399 */
400 // Header secteur
401 #define nb_oct_before_sector 59 // Cas de 17 secteurs/pistes !
402 #define nb_oct_after_sector 43 //#define nb_oct_after_sector 31
403
404 unsigned int Floppy::GetDskImageOffset()
405 {
406 unsigned int offset=256; // Add the DSK file header size
407 offset+=m_CurrentTrack*6400; // And move to the correct track
408 offset+=m_OffsetFirstSector; // Add the offset from the start of track to the data of the first sector
409 offset+=m_InterSectorSpacing*(m_CurrentSector-1);
410 return offset;
411 }
412
413
414 // 0x0319 -> 793
415 bool Floppy::WriteSector(const char *fileName)
416 {
417 if (!m_Buffer)
418 {
419 return false;
420 }
421
422 std::string filteredFileName(StringTrim(fileName," \t\f\v\n\r"));
423
424 void* buffer;
425 size_t bufferSize;
426
427 if (LoadFile(filteredFileName.c_str(),buffer,bufferSize))
428 {
429 if (bufferSize>256)
430 {
431 ShowError("File for sector is too large. %d bytes (%d too many)",bufferSize,bufferSize-256);
432 }
433
434 unsigned int sectorOffset=GetDskImageOffset();
435 if (m_BufferSize>sectorOffset+256)
436 {
437 memcpy((char*)m_Buffer+sectorOffset,buffer,bufferSize);
438 }
439 printf("Boot sector '%s' installed, %d free bytes remaining in this sector.\n",filteredFileName.c_str(),256-bufferSize);
440
441 MoveToNextSector();
442 }
443 else
444 {
445 ShowError("Boot Sector file '%s' not found",filteredFileName.c_str());
446 }
447 return true;
448 }
449
450
451 class TapeInfo
452 {
453 public:
454 TapeInfo()
455 : m_StartAddress(0)
456 , m_EndAddress(0)
457 , m_FileType(0)
458 , m_AutoStarts(false)
459 , m_PtrData(nullptr)
460 , m_DataSize(0)
461 {
462
463 }
464
465 bool ParseHeader(void* fileBuffer,size_t fileSize)
466 {
467 m_DataSize=fileSize;
468 m_PtrData =(unsigned char*)fileBuffer;
469 while (m_DataSize && (m_PtrData[0]==0x16))
470 {
471 m_DataSize--;
472 m_PtrData++;
473 }
474 if (m_DataSize>8 && (m_PtrData[0]==0x24) && (m_PtrData[1]==0x00) && (m_PtrData[2]==0x00) )
475 {
476 // At this point at least we have a valid synchro sequence and we know we have a usable header
477 m_FileType = m_PtrData[3];
478 m_AutoStarts =(m_PtrData[4]!=0);
479 m_EndAddress =(m_PtrData[5]<<8)|m_PtrData[6];
480 m_StartAddress=(m_PtrData[7]<<8)|m_PtrData[8];
481
482 m_DataSize-=9;
483 m_PtrData+=9;
484
485 if (m_DataSize && (m_PtrData[0]==0x00) )
486 {
487 // Skip the zero
488 m_DataSize--;
489 m_PtrData++;
490
491 // Now we read the name
492 while (m_DataSize && (m_PtrData[0]!=0x00))
493 {
494 m_FileName+=m_PtrData[0];
495 m_DataSize--;
496 m_PtrData++;
497 }
498 if (m_DataSize && (m_PtrData[0]==0x00) )
499 {
500 // Skip the zero
501 m_DataSize--;
502 m_PtrData++;
503
504 // Now ptr points on the actual data
505 return true;
506 }
507 }
508 }
509 // Not a valid tape file
510 return false;
511 }
512
513 public:
514 unsigned char* m_PtrData;
515 int m_DataSize;
516 int m_StartAddress;
517 int m_EndAddress;
518 int m_FileType;
519 bool m_AutoStarts;
520 std::string m_FileName;
521 };
522
523
524 bool Floppy::WriteFile(const char *fileName,int loadAddress,bool removeHeaderIfPresent)
525 {
526 if (!m_Buffer)
527 {
528 return false;
529 }
530
531 void* fileBuffer;
532 size_t fileSize;
533 if (!LoadFile(fileName,fileBuffer,fileSize))
534 {
535 ShowError("Error can't open file '%s'\n",fileName);
536 }
537
538 unsigned char* fileData=(unsigned char*)fileBuffer;
539
540 if (removeHeaderIfPresent)
541 {
542 TapeInfo tapeInfo;
543 if (!tapeInfo.ParseHeader(fileBuffer,fileSize))
544 {
545 ShowError("File '%s' is not a valid tape file\n",fileName);
546 }
547 // If the file was a valid tape header, then we use these new information
548 fileData=tapeInfo.m_PtrData;
549 fileSize=tapeInfo.m_DataSize;
550 loadAddress=tapeInfo.m_StartAddress;
551 }
552
553 FileEntry fileEntry;
554 fileEntry.m_FloppyNumber=0; // 0 for a single floppy program
555
556 if (m_CurrentTrack>41) // face 2
557 {
558 fileEntry.m_StartSide=1;
559 }
560 else
561 {
562 fileEntry.m_StartSide=0;
563 }
564
565 int nb_sectors_by_files=(fileSize+255)/256;
566
567 fileEntry.m_StartTrack =m_CurrentTrack; // 0 to 42 (80...)
568 fileEntry.m_StartSector=m_CurrentSector; // 1 to 17 (or 16 or 18...)
569 fileEntry.m_SectorCount=nb_sectors_by_files; // Should probably be the real length
570 fileEntry.m_LoadAddress=loadAddress;
571 fileEntry.m_FileSize =fileSize;
572 fileEntry.m_FilePath =fileName;
573 fileEntry.m_CompressionMode=e_CompressionNone;
574 fileEntry.m_CompressedFileSize=0;
575
576
577 std::vector<unsigned char> compressedBuffer;
578 if (m_CompressionMode==e_CompressionFilepack)
579 {
580 // So the user requested FilePack compression.
581 // Great, we can do that.
582 compressedBuffer.resize(fileSize);
583 size_t compressedFileSize=LZ77_Compress(fileData,compressedBuffer.data(),fileSize);
584 if (compressedFileSize<fileSize)
585 {
586 // We actually did manage to compress the data
587 fileData=compressedBuffer.data();
588 fileSize=compressedFileSize;
589
590 fileEntry.m_CompressionMode=e_CompressionFilepack;
591 fileEntry.m_CompressedFileSize=compressedFileSize;
592 }
593 }
594
595 //
596 // Finally write the data to the disk structure
597 //
598 while (fileSize)
599 {
600 unsigned int offset=SetPosition(m_CurrentTrack,m_CurrentSector);
601
602 int sizeToWrite=256;
603 if (fileSize<256)
604 {
605 sizeToWrite=fileSize;
606 }
607 fileSize-=sizeToWrite;
608
609 memset((char*)m_Buffer+offset,0,256);
610 memcpy((char*)m_Buffer+offset,fileData,sizeToWrite);
611 fileData+=sizeToWrite;
612
613 MoveToNextSector();
614 }
615 free(fileBuffer);
616
617 m_FileEntries.push_back(fileEntry);
618
619 return true;
620 }
621
622
623 bool Floppy::SaveDescription(const char* fileName) const
624 {
625 std::stringstream layoutInfo;
626 layoutInfo << "//\n";
627 layoutInfo << "// Floppy layout generated by FloppyBuilder " << TOOL_VERSION_MAJOR << "." << TOOL_VERSION_MINOR << "\n";
628 layoutInfo << "//\n";
629 layoutInfo << "\n";
630
631 layoutInfo << "#ifdef ASSEMBLER\n";
632 layoutInfo << "//\n";
633 layoutInfo << "// Information for the Assembler\n";
634 layoutInfo << "//\n";
635 layoutInfo << "#ifdef LOADER\n";
636
637 std::stringstream code_sector;
638 std::stringstream code_track;
639 std::stringstream code_compressed;
640 std::stringstream code_size_low;
641 std::stringstream code_size_high;
642 std::stringstream code_adress_low;
643 std::stringstream code_adress_high;
644
645 std::stringstream file_list_summary;
646
647 int counter=0;
648 for (auto it(m_FileEntries.begin());it!=m_FileEntries.end();++it)
649 {
650 const FileEntry& fileEntry(*it);
651
652 if (it!=m_FileEntries.begin())
653 {
654 code_adress_low << ",";
655 code_adress_high << ",";
656
657 code_size_low << ",";
658 code_size_high << ",";
659
660 code_sector << ",";
661 code_track << ",";
662
663 code_compressed << ",";
664 }
665 code_adress_low << "<" << fileEntry.m_LoadAddress;
666 code_adress_high << ">" << fileEntry.m_LoadAddress;
667
668
669 if (fileEntry.m_CompressionMode==e_CompressionNone)
670 {
671 // Uncompressed file
672 code_size_low << "<" << fileEntry.m_FileSize;
673 code_size_high << ">" << fileEntry.m_FileSize;
674
675 code_compressed << 0;
676 }
677 else
678 {
679 // Compressed file
680 code_size_low << "<" << fileEntry.m_CompressedFileSize;
681 code_size_high << ">" << fileEntry.m_CompressedFileSize;
682
683 code_compressed << 1;
684 }
685
686 code_sector << fileEntry.m_StartSector;
687
688 file_list_summary << "// - Entry #" << counter << " '"<< fileEntry.m_FilePath << " ' loads at address " << fileEntry.m_LoadAddress;
689 if (fileEntry.m_StartTrack<m_TrackNumber)
690 {
691 // First side
692 file_list_summary << " starts on track " << fileEntry.m_StartTrack;
693 code_track << fileEntry.m_StartTrack;
694 }
695 else
696 {
697 // Second side
698 file_list_summary << " starts on the second side on track " << (fileEntry.m_StartTrack-m_TrackNumber);
699 code_track << fileEntry.m_StartTrack-m_TrackNumber+128;
700 }
701 file_list_summary << " sector " << fileEntry.m_StartSector << " and is " << fileEntry.m_SectorCount << " sectors long ";
702
703 if (fileEntry.m_CompressionMode==e_CompressionNone)
704 {
705 // Uncompressed file
706 file_list_summary << "(" << fileEntry.m_FileSize << " bytes).\n";
707 }
708 else
709 {
710 // Compressed file
711 file_list_summary << "(" << fileEntry.m_CompressedFileSize << " compressed bytes: " << (fileEntry.m_CompressedFileSize*100)/fileEntry.m_FileSize << "% of " << fileEntry.m_FileSize << " bytes).\n";
712 }
713
714 ++counter;
715 }
716
717
718 layoutInfo << "FileStartSector .byt ";
719 layoutInfo << code_sector.str() << "\n";
720
721 layoutInfo << "FileStartTrack .byt ";
722 layoutInfo << code_track.str() << "\n";
723
724 layoutInfo << "FileSizeLow .byt ";
725 layoutInfo << code_size_low.str() << "\n";
726
727 layoutInfo << "FileSizeHigh .byt ";
728 layoutInfo << code_size_high.str() << "\n";
729
730 layoutInfo << "FileLoadAdressLow .byt ";
731 layoutInfo << code_adress_low.str() << "\n";
732
733 layoutInfo << "FileLoadAdressHigh .byt ";
734 layoutInfo << code_adress_high.str() << "\n";
735
736 layoutInfo << "FileCompression .byt ";
737 layoutInfo << code_compressed.str() << "\n";
738
739
740 layoutInfo << "#endif\n";
741
742 layoutInfo << "#else\n";
743 layoutInfo << "//\n";
744 layoutInfo << "// Information for the Compiler\n";
745 layoutInfo << "//\n";
746 layoutInfo << "#endif\n";
747
748 layoutInfo << "\n";
749 layoutInfo << "//\n";
750 layoutInfo << "// Summary for this floppy building session:\n";
751 layoutInfo << "#define FLOPPY_SIDE_NUMBER " << m_SideNumber << " // Number of sides\n";
752 layoutInfo << "#define FLOPPY_TRACK_NUMBER " << m_TrackNumber << " // Number of tracks\n";
753 layoutInfo << "#define FLOPPY_SECTOR_PER_TRACK " << m_SectorNumber << " // Number of sectors per track\n";
754 layoutInfo << "//\n";
755
756 layoutInfo << "// List of files written to the floppy\n";
757 layoutInfo << file_list_summary.str();
758 layoutInfo << "//\n";
759
760 if (m_DefineList.empty())
761 {
762 layoutInfo << "// No defines set\n";
763 }
764 else
765 {
766 for (auto it(m_DefineList.begin());it!=m_DefineList.end();++it)
767 {
768 layoutInfo << "#define " << it->first << " " << it->second << "\n";
769 ++counter;
770 }
771 }
772
773 if (!SaveFile(fileName,layoutInfo.str().c_str(),layoutInfo.str().length()))
774 {
775 ShowError("Can't save '%s'\n",fileName);
776 }
777
778 return true;
779 }
780
781
782 bool Floppy::AddDefine(std::string defineName,std::string defineValue)
783 {
784 // Ugly token replacement, can do more optimal but as long as it works...
785 {
786 std::stringstream tempValue;
787 tempValue << m_FileEntries.size();
788 StringReplace(defineName ,"{FileIndex}",tempValue.str());
789 StringReplace(defineValue,"{FileIndex}",tempValue.str());
790 }
791
792 m_DefineList.push_back(std::pair<std::string,std::string>(defineName,defineValue));
793 return true;
794 }

  ViewVC Help
Powered by ViewVC 1.1.26