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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1013 - (hide annotations)
Thu Dec 12 19:35:12 2013 UTC (6 years, 3 months ago) by dbug
File size: 10581 byte(s)
Modified the ShowError command to take optional parameters (makes it possible to display actual information in the error message)
FloppyBuilder 0.3: Fixed parsing of comments, added a 'OutputFloppyFile' command, validated that the number of sectors and tracks is correct in the 'SetPosition' command.
1 dbug 1002
2 dbug 1009 #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 dbug 1002 #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 dbug 1009 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 dbug 1002
87 dbug 1009 FileEntry::~FileEntry()
88     {
89     }
90    
91    
92    
93    
94 dbug 1002 Floppy::Floppy() :
95     m_Buffer(0),
96     m_BufferSize(0),
97     m_Offset(0),
98     m_TrackNumber(0),
99     m_SectorNumber(0)
100     {
101 dbug 1009 fileCount=0;
102 dbug 1002 }
103    
104    
105     Floppy::~Floppy()
106     {
107     delete m_Buffer;
108     }
109    
110    
111 dbug 1009 bool Floppy::LoadDisk(const char* fileName)
112 dbug 1002 {
113     m_Offset=0;
114     if (LoadFile(fileName,m_Buffer,m_BufferSize))
115     {
116     const FloppyHeader& header(*((FloppyHeader*)m_Buffer));
117     if (header.IsValidHeader())
118     {
119     m_TrackNumber =header.GetTrackNumber();
120     m_SideNumber =header.GetSideNumber();
121     m_SectorNumber=17; // Can't figure out that from the header Oo
122     return true;
123     }
124     }
125     return false;
126     }
127    
128    
129 dbug 1009 bool Floppy::SaveDisk(const char* fileName) const
130 dbug 1002 {
131     assert(m_Buffer);
132     return SaveFile(fileName,m_Buffer,m_BufferSize);
133     }
134    
135     /*
136     Début de la piste (facultatif): 80 [#4E], 12 [#00], [#C2 #C2 #C2 #FC] et 50 [#4E] (soit 146 octets selon
137     la norme IBM) ou 40 [#4E], 12 [#00], [#C2 #C2 #C2 #FC] et 40 [#4E] (soit 96 octets pour SEDORIC).
138    
139     Pour chaque secteur: 12 [#00], 3 [#A1] [#FE #pp #ff #ss #tt CRC], 22 [#4E], 12 [#00], 3 [#A1], [#FB],
140     les 512 octets, [CRC CRC], 80 octets [#4E] (#tt = #02) (soit 141 + 512 = 653 octets selon la norme IBM)
141     ou 12 [#00], 3 [#A1] [#FE #pp #ff #ss #01 CRC CRC], 22 [#4E], 12 [#00], 3 [#A1], [#FB], les 256
142     octets, [CRC CRC], 12, 30 ou 40 octets [#4E] (selon le nombre de secteurs/piste). Soit environ 256 + (72
143     à 100) = 328 à 356 octets pour SEDORIC.
144    
145     Fin de la piste (facultatif): un nombre variable d'octets [#4E
146    
147     Selon NIBBLE,
148     une piste IBM compte 146 octets de début de piste + 9 secteurs de 653 octets + 257 octets de fin de piste = 6280 octets.
149     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.
150     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.
151     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).
152    
153     Lors de l'élaboration du tampon de formatage SEDORIC, les octets #C2 sont remplacés par des octets
154     #F6, les octets #A1 sont remplacés par des octets #F5 et chaque paire de 2 octets [CRC CRC] et
155     remplacée par un octet #F7. Comme on le voit, nombre de variantes sont utilisées, sauf la zone 22 [#4E],
156     12 [#00], 3 [#A1] qui est strictement obligatoire.
157    
158     // From DskTool:
159     15, 16 or 17 sectors: gap1=72; gap2=34; gap3=50;
160     18 sectors: gap1=12; gap2=34; gap3=46;
161     */
162 dbug 1009 unsigned int Floppy::ComputeOffset(int track,int sector)
163 dbug 1002 {
164     unsigned int offset=256+156; // on ajoute le header
165     offset+=track*6400; // On avance à la bonne piste
166     offset+=(taille_secteur+nb_oct_after_sector+nb_oct_before_sector)*(sector-1);
167     return offset;
168     }
169    
170    
171     // 0x0319 -> 793
172 dbug 1009 void Floppy::WriteSector(int track,int sector,const char *fileName)
173 dbug 1002 {
174     std::string filteredFileName(StringTrim(fileName," \t\f\v\n\r"));
175    
176     void* buffer;
177     size_t bufferSize;
178    
179     if (LoadFile(filteredFileName.c_str(),buffer,bufferSize))
180     {
181     if (bufferSize>256)
182     {
183 dbug 1013 ShowError("File for sector is too large. %d bytes (%d too many)",bufferSize,bufferSize-256);
184 dbug 1002 }
185    
186 dbug 1009 unsigned int bootSectorOffset=ComputeOffset(track,sector);
187 dbug 1002 if (m_BufferSize>bootSectorOffset+256)
188     {
189     memcpy((char*)m_Buffer+bootSectorOffset,buffer,bufferSize);
190     }
191 dbug 1009 printf("Boot sector '%s' installed, %d free bytes remaining in this sector.\n",filteredFileName.c_str(),256-bufferSize);
192 dbug 1002 }
193     else
194     {
195 dbug 1013 ShowError("Boot Sector file '%s' not found",filteredFileName.c_str());
196 dbug 1002 }
197     }
198    
199 dbug 1009 int Floppy::WriteFile(const char *fileName,int& currentTrack,int& currentSector,int loadAddress)
200 dbug 1002 {
201 dbug 1009 FileEntry fileEntry;
202     fileEntry.m_FloppyNumber=0; // 0 for a single floppy program
203    
204     if (fileCount)
205     {
206     code_adress_low << ",";
207     code_adress_high << ",";
208    
209     code_sector << ",";
210     code_track << ",";
211     code_nombre_secteur << ",";
212     }
213     code_adress_low << "<" << loadAddress;
214     code_adress_high << ">" << loadAddress;
215    
216     if (currentTrack>41) // face 2
217     {
218     fileEntry.m_StartSide=1;
219     code_track << currentTrack-42+128;
220     }
221     else
222     {
223     fileEntry.m_StartSide=0;
224     code_track << currentTrack;
225     }
226     code_sector << currentSector;
227    
228 dbug 1002 void* fileBuffer;
229     size_t fileSize;
230     if (!LoadFile(fileName,fileBuffer,fileSize))
231     {
232 dbug 1013 ShowError("Error can't open file '%s'\n",fileName);
233 dbug 1002 }
234    
235     int nb_sectors_by_files=(fileSize+255)/256;
236    
237 dbug 1009 fileEntry.m_StartTrack =currentTrack; // 0 to 42 (80...)
238     fileEntry.m_StartSector=currentSector; // 1 to 17 (or 16 or 18...)
239     fileEntry.m_SectorCount=nb_sectors_by_files; // Should probably be the real length
240     fileEntry.m_LoadAddress=loadAddress;
241     fileEntry.m_TotalSize=fileSize;
242     fileEntry.m_FilePath =fileName;
243    
244 dbug 1002 unsigned char* fileData=(unsigned char*)fileBuffer;
245     while (fileSize)
246     {
247 dbug 1009 SetOffset(currentTrack,currentSector);
248 dbug 1002
249     int sizeToWrite=256;
250     if (fileSize<256)
251     {
252     sizeToWrite=fileSize;
253     }
254     fileSize-=sizeToWrite;
255    
256     memset((char*)m_Buffer+m_Offset,0,256);
257     memcpy((char*)m_Buffer+m_Offset,fileData,sizeToWrite);
258     fileData+=sizeToWrite;
259    
260 dbug 1009 currentSector++;
261 dbug 1002
262 dbug 1009 if (currentSector==taille_piste+1) // We reached the end of the track!
263 dbug 1002 {
264 dbug 1009 currentSector=1;
265     currentTrack++;
266     if (currentTrack==m_TrackNumber)
267     {
268     // Next side is following on the floppy in the DSK format, so technically we should have nothing to do
269     // All the hard work is in the loader
270     }
271 dbug 1002 }
272     }
273     free(fileBuffer);
274    
275 dbug 1009 code_nombre_secteur << nb_sectors_by_files;
276 dbug 1002
277 dbug 1009 ++fileCount;
278 dbug 1002
279 dbug 1009 m_FileEntries.push_back(fileEntry);
280 dbug 1002
281 dbug 1009 return nb_sectors_by_files;
282     }
283 dbug 1002
284    
285 dbug 1009 bool Floppy::SaveDescription(const char* fileName) const
286     {
287     std::stringstream layoutInfo;
288     layoutInfo << "//\n";
289     layoutInfo << "// Floppy layout generated by FloppyBuilder " << TOOL_VERSION_MAJOR << "." << TOOL_VERSION_MINOR << "\n";
290     layoutInfo << "//\n";
291     layoutInfo << "\n";
292 dbug 1002
293 dbug 1009 layoutInfo << "#ifdef ASSEMBLER\n";
294     layoutInfo << "//\n";
295     layoutInfo << "// Information for the Assembler\n";
296     layoutInfo << "//\n";
297 dbug 1002
298 dbug 1009 layoutInfo << "FileStartSector .byt ";
299     layoutInfo << code_sector.str() << "\n";
300 dbug 1002
301 dbug 1009 layoutInfo << "FileStartTrack .byt ";
302     layoutInfo << code_track.str() << "\n";
303 dbug 1002
304 dbug 1009 layoutInfo << "FileSectorCount .byt ";
305     layoutInfo << code_nombre_secteur.str() << "\n";
306 dbug 1002
307 dbug 1009 layoutInfo << "FileLoadAdressLow .byt ";
308     layoutInfo << code_adress_low.str() << "\n";
309 dbug 1002
310 dbug 1009 layoutInfo << "FileLoadAdressHigh .byt ";
311     layoutInfo << code_adress_high.str() << "\n";
312 dbug 1002
313 dbug 1009 layoutInfo << "#else\n";
314     layoutInfo << "//\n";
315     layoutInfo << "// Information for the Compiler\n";
316     layoutInfo << "//\n";
317     layoutInfo << "#endif\n";
318 dbug 1002
319 dbug 1009 layoutInfo << "\n";
320     layoutInfo << "//\n";
321     layoutInfo << "// Summary for this floppy building session:\n";
322     layoutInfo << "#define FLOPPY_TRACK_NUMBER " << m_TrackNumber << " // Number of tracks\n";
323     layoutInfo << "#define FLOPPY_SECTOR_PER_TRACK " << m_SectorNumber << " // Number of sectors per track\n";
324     layoutInfo << "//\n";
325 dbug 1002
326 dbug 1009 layoutInfo << "// List of files written to the floppy\n";
327     int counter=0;
328     for (auto it(m_FileEntries.begin());it!=m_FileEntries.end();++it)
329     {
330     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";
331     ++counter;
332     }
333     layoutInfo << "//\n";
334 dbug 1002
335 dbug 1009 if (m_DefineList.empty())
336     {
337     layoutInfo << "// No defines set\n";
338     }
339     else
340     {
341     for (auto it(m_DefineList.begin());it!=m_DefineList.end();++it)
342     {
343     layoutInfo << "#define " << it->first << " " << it->second << "\n";
344     ++counter;
345     }
346     }
347 dbug 1002
348 dbug 1009 if (!SaveFile(fileName,layoutInfo.str().c_str(),layoutInfo.str().length()))
349     {
350 dbug 1013 ShowError("Can't save '%s'\n",fileName);
351 dbug 1009 }
352 dbug 1002
353 dbug 1009 return true;
354     }
355 dbug 1002
356    
357 dbug 1009 bool Floppy::AddDefine(std::string defineName,std::string defineValue)
358 dbug 1002 {
359 dbug 1009 // Ugly token replacement, can do more optimal but as long as it works...
360 dbug 1002 {
361 dbug 1009 std::stringstream tempValue;
362     tempValue << m_FileEntries.size();
363     StringReplace(defineName ,"{FileIndex}",tempValue.str());
364     StringReplace(defineValue,"{FileIndex}",tempValue.str());
365 dbug 1002 }
366    
367 dbug 1009 m_DefineList.push_back(std::pair<std::string,std::string>(defineName,defineValue));
368     return true;
369     }

  ViewVC Help
Powered by ViewVC 1.1.26