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

  ViewVC Help
Powered by ViewVC 1.1.26