/[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 1018 - (show annotations)
Sat Dec 14 14:02:00 2013 UTC (5 years, 9 months ago) by dbug
File size: 17836 byte(s)
FloppyBuilder 0.6
- Added the 'LoadDiskTemplate' and 'DefineDisk' commands (and removed these parameters from the command line, define disk does not work at the moment)
- Added the 'AddTapFile' command, similar to 'AddFile' but automatically removes the header and extract the start address of the file
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 // BORN.DSK=537856 bytes
19 // 17*358=6086
20 // *2=12172
21 // *44=537856
22
23 // Boot sector at offset 793 (Confirmed)
24 // Loader at offset 0x734 (1844) - Confirmed
25
26 // 793-256-156=381
27 // 381-256=125
28
29 // offset=256+156; // on ajoute le header
30 // offset+=track*6400; // On avance à la bonne piste
31 // offset+=(taille_secteur+nb_oct_after_sector+nb_oct_before_sector)*(sector-1);
32 //
33 // So: Offset = 256+156 + (track*6400) + (taille_secteur+nb_oct_after_sector+nb_oct_before_sector)*(sector-1)
34 // = 256+156 + (track*6400) + (256+43+59)*(sector-1)
35 // = 412 + (track*6400) + (358)*(sector-1)
36
37
38 FloppyHeader::FloppyHeader()
39 {
40 assert(sizeof(*this)==256);
41 memset(this,0,sizeof(*this));
42 }
43
44 FloppyHeader::~FloppyHeader()
45 {
46 }
47
48 bool FloppyHeader::IsValidHeader() const
49 {
50 if (memcmp(m_Signature,"MFM_DISK",8)!=0) return false;
51
52 int sideNumber=GetSideNumber();
53 if ((sideNumber<1) || (sideNumber>2)) return false;
54
55 int trackNumber=GetTrackNumber();
56 if ((trackNumber<30) || (trackNumber>82)) return false;
57
58 return true;
59 }
60
61 int FloppyHeader::GetSideNumber() const
62 {
63 int sideNumber= ( ( ( ( (m_Sides[3]<<8) | m_Sides[2]) << 8 ) | m_Sides[1]) << 8 ) | m_Sides[0];
64 return sideNumber;
65 }
66
67 int FloppyHeader::GetTrackNumber() const
68 {
69 int trackNumber= ( ( ( ( (m_Tracks[3]<<8) | m_Tracks[2]) << 8 ) | m_Tracks[1]) << 8 ) | m_Tracks[0];
70 return trackNumber;
71 }
72
73
74
75
76 FileEntry::FileEntry() :
77 m_FloppyNumber(0),
78 m_StartSide(0),
79 m_StartTrack(0),
80 m_StartSector(1),
81 m_SectorCount(0),
82 m_LoadAddress(0),
83 m_TotalSize(0)
84 {
85 }
86
87 FileEntry::~FileEntry()
88 {
89 }
90
91
92
93
94 Floppy::Floppy() :
95 m_Buffer(0),
96 m_BufferSize(0),
97 m_TrackNumber(0),
98 m_SectorNumber(0),
99 m_CurrentTrack(0),
100 m_CurrentSector(1)
101 {
102 }
103
104
105 Floppy::~Floppy()
106 {
107 delete m_Buffer;
108 }
109
110
111 unsigned int crctab[256] =
112 {
113 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7,
114 0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF,
115 0x1231, 0x0210, 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6,
116 0x9339, 0x8318, 0xB37B, 0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE,
117 0x2462, 0x3443, 0x0420, 0x1401, 0x64E6, 0x74C7, 0x44A4, 0x5485,
118 0xA56A, 0xB54B, 0x8528, 0x9509, 0xE5EE, 0xF5CF, 0xC5AC, 0xD58D,
119 0x3653, 0x2672, 0x1611, 0x0630, 0x76D7, 0x66F6, 0x5695, 0x46B4,
120 0xB75B, 0xA77A, 0x9719, 0x8738, 0xF7DF, 0xE7FE, 0xD79D, 0xC7BC,
121 0x48C4, 0x58E5, 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823,
122 0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969, 0xA90A, 0xB92B,
123 0x5AF5, 0x4AD4, 0x7AB7, 0x6A96, 0x1A71, 0x0A50, 0x3A33, 0x2A12,
124 0xDBFD, 0xCBDC, 0xFBBF, 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A,
125 0x6CA6, 0x7C87, 0x4CE4, 0x5CC5, 0x2C22, 0x3C03, 0x0C60, 0x1C41,
126 0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD, 0xAD2A, 0xBD0B, 0x8D68, 0x9D49,
127 0x7E97, 0x6EB6, 0x5ED5, 0x4EF4, 0x3E13, 0x2E32, 0x1E51, 0x0E70,
128 0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A, 0x9F59, 0x8F78,
129 0x9188, 0x81A9, 0xB1CA, 0xA1EB, 0xD10C, 0xC12D, 0xF14E, 0xE16F,
130 0x1080, 0x00A1, 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046, 0x6067,
131 0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C, 0xE37F, 0xF35E,
132 0x02B1, 0x1290, 0x22F3, 0x32D2, 0x4235, 0x5214, 0x6277, 0x7256,
133 0xB5EA, 0xA5CB, 0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D,
134 0x34E2, 0x24C3, 0x14A0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
135 0xA7DB, 0xB7FA, 0x8799, 0x97B8, 0xE75F, 0xF77E, 0xC71D, 0xD73C,
136 0x26D3, 0x36F2, 0x0691, 0x16B0, 0x6657, 0x7676, 0x4615, 0x5634,
137 0xD94C, 0xC96D, 0xF90E, 0xE92F, 0x99C8, 0x89E9, 0xB98A, 0xA9AB,
138 0x5844, 0x4865, 0x7806, 0x6827, 0x18C0, 0x08E1, 0x3882, 0x28A3,
139 0xCB7D, 0xDB5C, 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A,
140 0x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1, 0x1AD0, 0x2AB3, 0x3A92,
141 0xFD2E, 0xED0F, 0xDD6C, 0xCD4D, 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9,
142 0x7C26, 0x6C07, 0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1,
143 0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8,
144 0x6E17, 0x7E36, 0x4E55, 0x5E74, 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0
145 };
146
147 void compute_crc(unsigned char *ptr,int count)
148 {
149 int i;
150 unsigned short crc=0xFFFF,byte;
151 for (i=0;i<count;i++) {
152 byte= *ptr++;
153 crc=(crc<<8)^crctab[(crc>>8)^byte];
154 }
155 *ptr++=crc>>8;
156 *ptr++=crc&0xFF;
157 }
158
159
160 struct DskHeader
161 {
162 char signature[8];
163 int sides;
164 int tracks;
165 int geometry;
166 };
167
168
169 bool Floppy::CreateDisk(int numberOfSides,int numberOfTracks,int numberOfSectors)
170 {
171 // Heavily based on MakeDisk and Tap2DSk
172 int gap1,gap2,gap3;
173
174 switch (numberOfSectors)
175 {
176 case 15: case 16: case 17:
177 gap1=72; gap2=34; gap3=50;
178 break;
179
180 case 18:
181 gap1=12; gap2=34; gap3=46;
182 break;
183
184 default:
185 ShowError("Unrealistic sectors per track number\n");
186 }
187
188 m_BufferSize=256+numberOfSides*numberOfTracks*6400;
189 m_Buffer=malloc(m_BufferSize);
190 if (m_Buffer)
191 {
192 m_TrackNumber =numberOfTracks; // 42
193 m_SectorNumber=numberOfSectors; // 17
194 m_SideNumber =numberOfSides; // 2
195
196 DskHeader* header=(DskHeader*)m_Buffer;
197 memcpy(header->signature,"MFM_DISK",8);
198 header->sides=numberOfSides;
199 header->tracks=numberOfTracks;
200 header->geometry=1;
201
202 unsigned char* trackbuf=(unsigned char*)m_Buffer+256;
203 for (int s=0;s<numberOfSides;s++)
204 {
205 for (int t=0;t<numberOfTracks;t++)
206 {
207 {
208 int i;
209 int offset=0;
210 for (i=0;i<gap1-12;i++)
211 {
212 trackbuf[offset++]=0x4E;
213 }
214 for (int j=0;j<numberOfSectors;j++)
215 {
216 for (i=0;i<12;i++) trackbuf[offset++]=0;
217 for (i=0;i<3;i++) trackbuf[offset++]=0xA1;
218 trackbuf[offset++]=0xFE;
219 for (i=0;i<6;i++) offset++;
220 for (i=0;i<gap2-12;i++) trackbuf[offset++]=0x22;
221 for (i=0;i<12;i++) trackbuf[offset++]=0;
222 for (i=0;i<3;i++) trackbuf[offset++]=0xA1;
223 trackbuf[offset++]=0xFB;
224 for (i=0;i<258;i++) offset++;
225 for (i=0;i<gap3-12;i++) trackbuf[offset++]=0x4E;
226 }
227
228 while (offset<6400)
229 {
230 trackbuf[offset++]=0x4E;
231 }
232 }
233 int offset=gap1;
234 for (int i=0;i<numberOfSectors;i++)
235 {
236 trackbuf[offset+4]=t;
237 trackbuf[offset+5]=s;
238 trackbuf[offset+6]=i+1;
239 trackbuf[offset+7]=1;
240 compute_crc(trackbuf+offset,4+4);
241 offset+=4+6;
242 offset+=gap2;
243 memset(trackbuf+offset+4,0,256);
244 compute_crc(trackbuf+offset,4+256);
245 offset+=256+6;
246 offset+=gap3;
247 }
248 trackbuf+=6400;
249 }
250 }
251 return true;
252 }
253
254 return false;
255 }
256
257
258 bool Floppy::LoadDisk(const char* fileName)
259 {
260 if (LoadFile(fileName,m_Buffer,m_BufferSize))
261 {
262 const FloppyHeader& header(*((FloppyHeader*)m_Buffer));
263 if (header.IsValidHeader())
264 {
265 m_TrackNumber =header.GetTrackNumber();
266 m_SideNumber =header.GetSideNumber();
267 m_SectorNumber=17; // Can't figure out that from the header Oo
268 return true;
269 }
270 }
271 return false;
272 }
273
274
275 bool Floppy::SaveDisk(const char* fileName) const
276 {
277 if (m_Buffer)
278 {
279 return SaveFile(fileName,m_Buffer,m_BufferSize);
280 }
281 return false;
282 }
283
284 /*
285 Début de la piste (facultatif): 80 [#4E], 12 [#00], [#C2 #C2 #C2 #FC] et 50 [#4E] (soit 146 octets selon
286 la norme IBM) ou 40 [#4E], 12 [#00], [#C2 #C2 #C2 #FC] et 40 [#4E] (soit 96 octets pour SEDORIC).
287
288 Pour chaque secteur: 12 [#00], 3 [#A1] [#FE #pp #ff #ss #tt CRC], 22 [#4E], 12 [#00], 3 [#A1], [#FB],
289 les 512 octets, [CRC CRC], 80 octets [#4E] (#tt = #02) (soit 141 + 512 = 653 octets selon la norme IBM)
290 ou 12 [#00], 3 [#A1] [#FE #pp #ff #ss #01 CRC CRC], 22 [#4E], 12 [#00], 3 [#A1], [#FB], les 256
291 octets, [CRC CRC], 12, 30 ou 40 octets [#4E] (selon le nombre de secteurs/piste). Soit environ 256 + (72
292 à 100) = 328 à 356 octets pour SEDORIC.
293
294 Fin de la piste (facultatif): un nombre variable d'octets [#4E
295
296 Selon NIBBLE,
297 une piste IBM compte 146 octets de début de piste + 9 secteurs de 653 octets + 257 octets de fin de piste = 6280 octets.
298 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.
299 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.
300 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).
301
302 Lors de l'élaboration du tampon de formatage SEDORIC, les octets #C2 sont remplacés par des octets
303 #F6, les octets #A1 sont remplacés par des octets #F5 et chaque paire de 2 octets [CRC CRC] et
304 remplacée par un octet #F7. Comme on le voit, nombre de variantes sont utilisées, sauf la zone 22 [#4E],
305 12 [#00], 3 [#A1] qui est strictement obligatoire.
306
307 // From DskTool:
308 15, 16 or 17 sectors: gap1=72; gap2=34; gap3=50;
309 18 sectors: gap1=12; gap2=34; gap3=46;
310 */
311 unsigned int Floppy::GetDskImageOffset()
312 {
313 unsigned int offset=256+156; // Add the header
314 offset+=m_CurrentTrack*6400; // And move to the correct track
315 offset+=(taille_secteur+nb_oct_after_sector+nb_oct_before_sector)*(m_CurrentSector-1);
316 return offset;
317 }
318
319
320 // 0x0319 -> 793
321 bool Floppy::WriteSector(const char *fileName)
322 {
323 if (!m_Buffer)
324 {
325 return false;
326 }
327
328 std::string filteredFileName(StringTrim(fileName," \t\f\v\n\r"));
329
330 void* buffer;
331 size_t bufferSize;
332
333 if (LoadFile(filteredFileName.c_str(),buffer,bufferSize))
334 {
335 if (bufferSize>256)
336 {
337 ShowError("File for sector is too large. %d bytes (%d too many)",bufferSize,bufferSize-256);
338 }
339
340 unsigned int sectorOffset=GetDskImageOffset();
341 if (m_BufferSize>sectorOffset+256)
342 {
343 memcpy((char*)m_Buffer+sectorOffset,buffer,bufferSize);
344 }
345 printf("Boot sector '%s' installed, %d free bytes remaining in this sector.\n",filteredFileName.c_str(),256-bufferSize);
346
347 MoveToNextSector();
348 }
349 else
350 {
351 ShowError("Boot Sector file '%s' not found",filteredFileName.c_str());
352 }
353 return true;
354 }
355
356
357 class TapeInfo
358 {
359 public:
360 TapeInfo()
361 : m_StartAddress(0)
362 , m_EndAddress(0)
363 , m_FileType(0)
364 , m_AutoStarts(false)
365 , m_PtrData(nullptr)
366 , m_DataSize(0)
367 {
368
369 }
370
371 bool ParseHeader(void* fileBuffer,size_t fileSize)
372 {
373 m_DataSize=fileSize;
374 m_PtrData =(unsigned char*)fileBuffer;
375 while (m_DataSize && (m_PtrData[0]==0x16))
376 {
377 m_DataSize--;
378 m_PtrData++;
379 }
380 if (m_DataSize>8 && (m_PtrData[0]==0x24) && (m_PtrData[1]==0x00) && (m_PtrData[2]==0x00) )
381 {
382 // At this point at least we have a valid synchro sequence and we know we have a usable header
383 m_FileType = m_PtrData[3];
384 m_AutoStarts =(m_PtrData[4]!=0);
385 m_EndAddress =(m_PtrData[5]<<8)|m_PtrData[6];
386 m_StartAddress=(m_PtrData[7]<<8)|m_PtrData[8];
387
388 m_DataSize-=9;
389 m_PtrData+=9;
390
391 if (m_DataSize && (m_PtrData[0]==0x00) )
392 {
393 // Skip the zero
394 m_DataSize--;
395 m_PtrData++;
396
397 // Now we read the name
398 while (m_DataSize && (m_PtrData[0]!=0x00))
399 {
400 m_FileName+=m_PtrData[0];
401 m_DataSize--;
402 m_PtrData++;
403 }
404 if (m_DataSize && (m_PtrData[0]==0x00) )
405 {
406 // Skip the zero
407 m_DataSize--;
408 m_PtrData++;
409
410 // Now ptr points on the actual data
411 return true;
412 }
413 }
414 }
415 // Not a valid tape file
416 return false;
417 }
418
419 public:
420 unsigned char* m_PtrData;
421 int m_DataSize;
422 int m_StartAddress;
423 int m_EndAddress;
424 int m_FileType;
425 bool m_AutoStarts;
426 std::string m_FileName;
427 };
428
429
430 bool Floppy::WriteFile(const char *fileName,int loadAddress,bool removeHeaderIfPresent)
431 {
432 if (!m_Buffer)
433 {
434 return false;
435 }
436
437 void* fileBuffer;
438 size_t fileSize;
439 if (!LoadFile(fileName,fileBuffer,fileSize))
440 {
441 ShowError("Error can't open file '%s'\n",fileName);
442 }
443
444 unsigned char* fileData=(unsigned char*)fileBuffer;
445
446 if (removeHeaderIfPresent)
447 {
448 TapeInfo tapeInfo;
449 if (!tapeInfo.ParseHeader(fileBuffer,fileSize))
450 {
451 ShowError("File '%s' is not a valid tape file\n",fileName);
452 }
453 // If the file was a valid tape header, then we use these new information
454 fileData=tapeInfo.m_PtrData;
455 fileSize=tapeInfo.m_DataSize;
456 loadAddress=tapeInfo.m_StartAddress;
457 }
458
459 FileEntry fileEntry;
460 fileEntry.m_FloppyNumber=0; // 0 for a single floppy program
461
462 if (!m_FileEntries.empty())
463 {
464 code_adress_low << ",";
465 code_adress_high << ",";
466
467 code_sector << ",";
468 code_track << ",";
469 code_nombre_secteur << ",";
470 }
471 code_adress_low << "<" << loadAddress;
472 code_adress_high << ">" << loadAddress;
473
474 if (m_CurrentTrack>41) // face 2
475 {
476 fileEntry.m_StartSide=1;
477 code_track << m_CurrentTrack-42+128;
478 }
479 else
480 {
481 fileEntry.m_StartSide=0;
482 code_track << m_CurrentTrack;
483 }
484 code_sector << m_CurrentSector;
485
486 int nb_sectors_by_files=(fileSize+255)/256;
487
488 fileEntry.m_StartTrack =m_CurrentTrack; // 0 to 42 (80...)
489 fileEntry.m_StartSector=m_CurrentSector; // 1 to 17 (or 16 or 18...)
490 fileEntry.m_SectorCount=nb_sectors_by_files; // Should probably be the real length
491 fileEntry.m_LoadAddress=loadAddress;
492 fileEntry.m_TotalSize =fileSize;
493 fileEntry.m_FilePath =fileName;
494
495 while (fileSize)
496 {
497 unsigned int offset=SetPosition(m_CurrentTrack,m_CurrentSector);
498
499 int sizeToWrite=256;
500 if (fileSize<256)
501 {
502 sizeToWrite=fileSize;
503 }
504 fileSize-=sizeToWrite;
505
506 memset((char*)m_Buffer+offset,0,256);
507 memcpy((char*)m_Buffer+offset,fileData,sizeToWrite);
508 fileData+=sizeToWrite;
509
510 MoveToNextSector();
511 }
512 free(fileBuffer);
513
514 code_nombre_secteur << nb_sectors_by_files;
515
516 m_FileEntries.push_back(fileEntry);
517
518 return true;
519 }
520
521
522 bool Floppy::SaveDescription(const char* fileName) const
523 {
524 std::stringstream layoutInfo;
525 layoutInfo << "//\n";
526 layoutInfo << "// Floppy layout generated by FloppyBuilder " << TOOL_VERSION_MAJOR << "." << TOOL_VERSION_MINOR << "\n";
527 layoutInfo << "//\n";
528 layoutInfo << "\n";
529
530 layoutInfo << "#ifdef ASSEMBLER\n";
531 layoutInfo << "//\n";
532 layoutInfo << "// Information for the Assembler\n";
533 layoutInfo << "//\n";
534
535 layoutInfo << "FileStartSector .byt ";
536 layoutInfo << code_sector.str() << "\n";
537
538 layoutInfo << "FileStartTrack .byt ";
539 layoutInfo << code_track.str() << "\n";
540
541 layoutInfo << "FileSectorCount .byt ";
542 layoutInfo << code_nombre_secteur.str() << "\n";
543
544 layoutInfo << "FileLoadAdressLow .byt ";
545 layoutInfo << code_adress_low.str() << "\n";
546
547 layoutInfo << "FileLoadAdressHigh .byt ";
548 layoutInfo << code_adress_high.str() << "\n";
549
550 layoutInfo << "#else\n";
551 layoutInfo << "//\n";
552 layoutInfo << "// Information for the Compiler\n";
553 layoutInfo << "//\n";
554 layoutInfo << "#endif\n";
555
556 layoutInfo << "\n";
557 layoutInfo << "//\n";
558 layoutInfo << "// Summary for this floppy building session:\n";
559 layoutInfo << "#define FLOPPY_TRACK_NUMBER " << m_TrackNumber << " // Number of tracks\n";
560 layoutInfo << "#define FLOPPY_SECTOR_PER_TRACK " << m_SectorNumber << " // Number of sectors per track\n";
561 layoutInfo << "//\n";
562
563 layoutInfo << "// List of files written to the floppy\n";
564 int counter=0;
565 for (auto it(m_FileEntries.begin());it!=m_FileEntries.end();++it)
566 {
567 if (it->m_StartTrack<m_TrackNumber)
568 {
569 // First side
570 layoutInfo << "// - Entry #" << counter << " '"<< it->m_FilePath << " ' loads at address " << it->m_LoadAddress << " starts on track " << it->m_StartTrack<< " sector "<< it->m_StartSector <<" and is " << it->m_SectorCount << " sectors long (" << it->m_TotalSize << " bytes).\n";
571 }
572 else
573 {
574 // Second side
575 layoutInfo << "// - Entry #" << counter << " '"<< it->m_FilePath << " ' loads at address " << it->m_LoadAddress << " starts on the second side on track " << (it->m_StartTrack-m_TrackNumber) << " sector "<< it->m_StartSector <<" and is " << it->m_SectorCount << " sectors long (" << it->m_TotalSize << " bytes).\n";
576 }
577 ++counter;
578 }
579 layoutInfo << "//\n";
580
581 if (m_DefineList.empty())
582 {
583 layoutInfo << "// No defines set\n";
584 }
585 else
586 {
587 for (auto it(m_DefineList.begin());it!=m_DefineList.end();++it)
588 {
589 layoutInfo << "#define " << it->first << " " << it->second << "\n";
590 ++counter;
591 }
592 }
593
594 if (!SaveFile(fileName,layoutInfo.str().c_str(),layoutInfo.str().length()))
595 {
596 ShowError("Can't save '%s'\n",fileName);
597 }
598
599 return true;
600 }
601
602
603 bool Floppy::AddDefine(std::string defineName,std::string defineValue)
604 {
605 // Ugly token replacement, can do more optimal but as long as it works...
606 {
607 std::stringstream tempValue;
608 tempValue << m_FileEntries.size();
609 StringReplace(defineName ,"{FileIndex}",tempValue.str());
610 StringReplace(defineValue,"{FileIndex}",tempValue.str());
611 }
612
613 m_DefineList.push_back(std::pair<std::string,std::string>(defineName,defineValue));
614 return true;
615 }

  ViewVC Help
Powered by ViewVC 1.1.26