/[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 1009 - (show annotations)
Wed Dec 11 20:11:41 2013 UTC (6 years, 3 months ago) by dbug
File size: 10653 byte(s)
More FloppyBuilder changes:
- Add 'OutputLayoutFile' and 'AddDefine' commands
- The generated file has been vastly improved
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_Offset(0),
98 m_TrackNumber(0),
99 m_SectorNumber(0)
100 {
101 fileCount=0;
102 }
103
104
105 Floppy::~Floppy()
106 {
107 delete m_Buffer;
108 }
109
110
111 bool Floppy::LoadDisk(const char* fileName)
112 {
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 bool Floppy::SaveDisk(const char* fileName) const
130 {
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 unsigned int Floppy::ComputeOffset(int track,int sector)
163 {
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 void Floppy::WriteSector(int track,int sector,const char *fileName)
173 {
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 printf("File for sector is too large. %d bytes (%d too many)",bufferSize,bufferSize-256);
184 exit(1);
185 }
186
187 unsigned int bootSectorOffset=ComputeOffset(track,sector);
188 if (m_BufferSize>bootSectorOffset+256)
189 {
190 memcpy((char*)m_Buffer+bootSectorOffset,buffer,bufferSize);
191 }
192 printf("Boot sector '%s' installed, %d free bytes remaining in this sector.\n",filteredFileName.c_str(),256-bufferSize);
193 }
194 else
195 {
196 printf("%s",filteredFileName.c_str());
197 ShowError("Boot Sector file not found");
198 }
199 }
200
201 int Floppy::WriteFile(const char *fileName,int& currentTrack,int& currentSector,int loadAddress)
202 {
203 FileEntry fileEntry;
204 fileEntry.m_FloppyNumber=0; // 0 for a single floppy program
205
206 if (fileCount)
207 {
208 code_adress_low << ",";
209 code_adress_high << ",";
210
211 code_sector << ",";
212 code_track << ",";
213 code_nombre_secteur << ",";
214 }
215 code_adress_low << "<" << loadAddress;
216 code_adress_high << ">" << loadAddress;
217
218 if (currentTrack>41) // face 2
219 {
220 fileEntry.m_StartSide=1;
221 code_track << currentTrack-42+128;
222 }
223 else
224 {
225 fileEntry.m_StartSide=0;
226 code_track << currentTrack;
227 }
228 code_sector << currentSector;
229
230 void* fileBuffer;
231 size_t fileSize;
232 if (!LoadFile(fileName,fileBuffer,fileSize))
233 {
234 printf("FloppyBuilder: Error can't open %s\n",fileName);
235 exit(1);
236 }
237
238 int nb_sectors_by_files=(fileSize+255)/256;
239
240 fileEntry.m_StartTrack =currentTrack; // 0 to 42 (80...)
241 fileEntry.m_StartSector=currentSector; // 1 to 17 (or 16 or 18...)
242 fileEntry.m_SectorCount=nb_sectors_by_files; // Should probably be the real length
243 fileEntry.m_LoadAddress=loadAddress;
244 fileEntry.m_TotalSize=fileSize;
245 fileEntry.m_FilePath =fileName;
246
247 unsigned char* fileData=(unsigned char*)fileBuffer;
248 while (fileSize)
249 {
250 SetOffset(currentTrack,currentSector);
251
252 int sizeToWrite=256;
253 if (fileSize<256)
254 {
255 sizeToWrite=fileSize;
256 }
257 fileSize-=sizeToWrite;
258
259 memset((char*)m_Buffer+m_Offset,0,256);
260 memcpy((char*)m_Buffer+m_Offset,fileData,sizeToWrite);
261 fileData+=sizeToWrite;
262
263 currentSector++;
264
265 if (currentSector==taille_piste+1) // We reached the end of the track!
266 {
267 currentSector=1;
268 currentTrack++;
269 if (currentTrack==m_TrackNumber)
270 {
271 // Next side is following on the floppy in the DSK format, so technically we should have nothing to do
272 // All the hard work is in the loader
273 }
274 }
275 }
276 free(fileBuffer);
277
278 code_nombre_secteur << nb_sectors_by_files;
279
280 ++fileCount;
281
282 m_FileEntries.push_back(fileEntry);
283
284 return nb_sectors_by_files;
285 }
286
287
288 bool Floppy::SaveDescription(const char* fileName) const
289 {
290 std::stringstream layoutInfo;
291 layoutInfo << "//\n";
292 layoutInfo << "// Floppy layout generated by FloppyBuilder " << TOOL_VERSION_MAJOR << "." << TOOL_VERSION_MINOR << "\n";
293 layoutInfo << "//\n";
294 layoutInfo << "\n";
295
296 layoutInfo << "#ifdef ASSEMBLER\n";
297 layoutInfo << "//\n";
298 layoutInfo << "// Information for the Assembler\n";
299 layoutInfo << "//\n";
300
301 layoutInfo << "FileStartSector .byt ";
302 layoutInfo << code_sector.str() << "\n";
303
304 layoutInfo << "FileStartTrack .byt ";
305 layoutInfo << code_track.str() << "\n";
306
307 layoutInfo << "FileSectorCount .byt ";
308 layoutInfo << code_nombre_secteur.str() << "\n";
309
310 layoutInfo << "FileLoadAdressLow .byt ";
311 layoutInfo << code_adress_low.str() << "\n";
312
313 layoutInfo << "FileLoadAdressHigh .byt ";
314 layoutInfo << code_adress_high.str() << "\n";
315
316 layoutInfo << "#else\n";
317 layoutInfo << "//\n";
318 layoutInfo << "// Information for the Compiler\n";
319 layoutInfo << "//\n";
320 layoutInfo << "#endif\n";
321
322 layoutInfo << "\n";
323 layoutInfo << "//\n";
324 layoutInfo << "// Summary for this floppy building session:\n";
325 layoutInfo << "#define FLOPPY_TRACK_NUMBER " << m_TrackNumber << " // Number of tracks\n";
326 layoutInfo << "#define FLOPPY_SECTOR_PER_TRACK " << m_SectorNumber << " // Number of sectors per track\n";
327 layoutInfo << "//\n";
328
329 layoutInfo << "// List of files written to the floppy\n";
330 int counter=0;
331 for (auto it(m_FileEntries.begin());it!=m_FileEntries.end();++it)
332 {
333 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";
334 ++counter;
335 }
336 layoutInfo << "//\n";
337
338 if (m_DefineList.empty())
339 {
340 layoutInfo << "// No defines set\n";
341 }
342 else
343 {
344 for (auto it(m_DefineList.begin());it!=m_DefineList.end();++it)
345 {
346 layoutInfo << "#define " << it->first << " " << it->second << "\n";
347 ++counter;
348 }
349 }
350
351 if (!SaveFile(fileName,layoutInfo.str().c_str(),layoutInfo.str().length()))
352 {
353 printf("FloppyBuilder: Can't save '%s'\n",fileName);
354 exit(1);
355 }
356
357 return true;
358 }
359
360
361 bool Floppy::AddDefine(std::string defineName,std::string defineValue)
362 {
363 // Ugly token replacement, can do more optimal but as long as it works...
364 {
365 std::stringstream tempValue;
366 tempValue << m_FileEntries.size();
367 StringReplace(defineName ,"{FileIndex}",tempValue.str());
368 StringReplace(defineValue,"{FileIndex}",tempValue.str());
369 }
370
371 m_DefineList.push_back(std::pair<std::string,std::string>(defineName,defineValue));
372 return true;
373 }

  ViewVC Help
Powered by ViewVC 1.1.26