/[projet1]/public/pc/tools/osdk/main/MemMap/sources/memmap.cpp
Defence Force logotype

Contents of /public/pc/tools/osdk/main/MemMap/sources/memmap.cpp

Parent Directory Parent Directory | Revision Log Revision Log


Revision 898 - (show annotations)
Sat Sep 29 18:40:02 2012 UTC (7 years, 6 months ago) by dbug
File size: 12648 byte(s)
Fixed some issues on Visual Studio introduced by the posixification...
1 /*==============================================================================
2
3 MemMap
4
5 ==[Description]=================================================================
6
7 Generate an html file representing the memory map of provided files.
8
9 ==[History]=====================================================================
10
11 ==[ToDo]========================================================================
12
13 ==============================================================================*/
14
15 #pragma warning( disable : 4706)
16 #pragma warning( disable : 4786)
17
18
19 #include <stdio.h>
20 #include <stdlib.h>
21 #include <memory.h>
22 #include <io.h>
23 #include <fcntl.h>
24 #include <sys/stat.h>
25
26 #include <string>
27 #include <map>
28 #include <set>
29
30 #include "infos.h"
31
32 #include "common.h"
33
34
35 const char gHtmlHeader[]=
36 "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0//EN\">\r\n"
37 "<HTML lang=fr dir=ltr>\r\n"
38 " <HEAD>\r\n"
39 " <meta name=\"robots\" content=\"noindex\">\r\n"
40 " <meta http-equiv=\"Content-Type\" content=\"text/html;charset=iso-8859-1\">\r\n"
41 " <title>{PageTitle}</title>\r\n"
42 " <link href=\"{CssLink}\" rel=\"stylesheet\" type=\"text/css\">\r\n"
43 " </HEAD>\r\n"
44 " <BODY>\r\n"
45 "<hr>\r\n"
46 "<center>{PageTitle}</center>\r\n"
47 "<hr>\r\n";
48
49
50 //#define VERSION_STRING ##TOOL_VERSION_MAJOR":"##TOOL_VERSION_MINOR
51
52 #define STRINGIFY(x) #x
53 #define TOSTRING(x) STRINGIFY(x)
54
55 const char gHtmlFooter[]=
56 "<hr>\r\n"
57 "<center>Generated by MemMap version "TOSTRING(TOOL_VERSION_MAJOR)"."TOSTRING(TOOL_VERSION_MINOR)"</center>\r\n"
58 "<hr>\r\n"
59 " </BODY>\r\n"
60 "</HTML>\r\n";
61
62 class Block
63 {
64 public:
65 Block(int address) :
66 m_address(address),
67 m_block_size(0),
68 m_total_size(0),
69 m_sub_entries(0)
70 {
71 }
72
73 bool operator <(const Block& other) const
74 {
75 return m_address<other.m_address;
76 }
77
78 bool IsMasterBlock() const
79 {
80 std::set<std::string>::const_iterator it=m_labels.begin();
81 while (it!=m_labels.end())
82 {
83 const std::string& label=*it;
84 if (
85 ((label.size()>=1) && (label[0]=='_')) ||
86 ((label.size()>=4) && (label[0]=='o') && (label[1]=='s')&& (label[2]=='d') && (label[3]=='k'))
87 )
88 {
89 return true;
90 }
91 ++it;
92 }
93 return false;
94 }
95
96 //private:
97 int m_address;
98 int m_total_size;
99 int m_block_size;
100 int m_sub_entries;
101 std::set<std::string> m_labels;
102 };
103
104
105 class Section
106 {
107 public:
108 Section() :
109 m_adress_size(4),
110 m_begin_adress(0),
111 m_end_adress(65535)
112 {
113 }
114
115 bool HasData() const
116 {
117 return !m_map_data.empty();
118 }
119
120 void Generate(std::string &ref_html);
121
122 void AddSymbol(int address,const std::string label)
123 {
124 Block newBlock(address);
125 std::pair<std::set<Block>::iterator,bool> insertIt=m_map_data.insert(newBlock);
126 std::set<Block>::iterator it=insertIt.first;
127 Block& block=const_cast<Block&>(*it); // The C++ norm states that dereferencing a std::set returns a const reference, because modifying the key would require modifying the container itself
128 block.m_labels.insert(label);
129 }
130
131 std::set<Block> &GetMap()
132 {
133 return m_map_data;
134 }
135
136 public:
137 std::string m_anchor_name;
138 std::string m_section_name;
139 int m_adress_size;
140 int m_begin_adress;
141 int m_end_adress;
142
143 std::set<Block> m_map_data;
144 };
145
146
147 void Section::Generate(std::string &html)
148 {
149 html+="<a name=\""+m_anchor_name+"\"></a>\r\n";
150
151 html+="<h1>"+m_section_name+"</h1>\r\n";
152
153 html+="<table border>\r\n";
154 html+="<tr>\r\n";
155 html+="<th>Adress</th><th colspan=\"2\">Size</th><th>Name</th>\r\n";
156 html+="</tr>\r\n";
157
158 //
159 // First pass compute the size
160 //
161 {
162 Block* ptr_master_block=0;
163
164 std::set<Block>::iterator it=m_map_data.begin();
165 while (it!=m_map_data.end())
166 {
167 Block& block=const_cast<Block&>(*it);
168 if (block.IsMasterBlock())
169 {
170 ptr_master_block=&block;
171 }
172
173 int address =block.m_address;
174 ++it;
175
176 if (it!=m_map_data.end())
177 {
178 block.m_block_size=(*it).m_address-address;
179 }
180 else
181 {
182 block.m_block_size=m_end_adress-address;
183 }
184
185 if (ptr_master_block)
186 {
187 ptr_master_block->m_sub_entries++;
188 ptr_master_block->m_total_size+=block.m_block_size;
189 }
190
191 //Block& block=(*it);
192
193 }
194 }
195
196 //
197 // Second pass generates the html
198 //
199 {
200 std::set<Block>::iterator it=m_map_data.begin();
201 while (it!=m_map_data.end())
202 {
203 Block& block=const_cast<Block&>(*it);
204 int address =block.m_address;
205 const std::set<std::string>& labels=block.m_labels;
206 ++it;
207
208 char buffer_adress[512];
209 if (address&255)
210 {
211 sprintf(buffer_adress,"$%02x",address);
212 }
213 else
214 {
215 sprintf(buffer_adress,"<b>$%02x</b>",address);
216 }
217
218 char buffer_size[512];
219 /*
220 if (it!=m_map_data.end())
221 {
222 sprintf(buffer_size,"%d",(*it).m_address-address);
223 }
224 else
225 {
226 sprintf(buffer_size,"%d",m_end_adress-address);
227 //sprintf(buffer_size,"???");
228 }
229 */
230 html+="<tr>\r\n";
231 html+=(std::string)"<td>"+buffer_adress+"</td>";
232
233 if ( (block.m_total_size) ) // && (block.m_total_size!=block.m_block_size) )
234 {
235 // Master block
236 sprintf(buffer_size,"<td align=\"right\">%d</td><td align=\"right\">%d</td>",block.m_total_size,block.m_block_size);
237 }
238 else
239 {
240 // Normal block
241 sprintf(buffer_size,"<td colspan=\"2\" align=\"right\">%d</td>",block.m_block_size);
242 }
243 html+=buffer_size;
244
245 html+="<td>";
246 std::set<std::string>::const_iterator labelsIt=labels.begin();
247 while (labelsIt!=labels.end())
248 {
249 html+=*labelsIt ;
250 ++labelsIt;
251 if (labelsIt!=labels.end())
252 {
253 html+=", ";
254 }
255 }
256 html+=(std::string)"</td>";
257 html+="</tr>\r\n";
258 }
259 }
260
261 html+="</table>\r\n";
262 }
263
264
265
266 enum INPUT_FORMAT
267 {
268 INPUT_FORMAT_ORIC_XA,
269 INPUT_FORMAT_ATARI_DEVPAC,
270 };
271
272
273 #define NB_ARG 4
274
275 int main(int argc,char *argv[])
276 {
277 //
278 // Some initialization for the common library
279 //
280 SetApplicationParameters(
281 "MemMap",
282 TOOL_VERSION_MAJOR,
283 TOOL_VERSION_MINOR,
284 "{ApplicationName} - Version {ApplicationVersion} - This program is a part of the OSDK\r\n"
285 "\r\n"
286 "Author:\r\n"
287 " Pointier Mickael\r\n"
288 "\r\n"
289 "Switches:\r\n"
290 " -f Format\r\n"
291 " -f0 => XA (Oric) [default]\r\n"
292 " -f1 => Devpac (Atari ST)\r\n"
293 "\r\n"
294 );
295
296
297 INPUT_FORMAT inputFormat=INPUT_FORMAT_ORIC_XA; // 0=XA / 1=Devpac
298
299 ArgumentParser cArgumentParser(argc,argv);
300
301 while (cArgumentParser.ProcessNextArgument())
302 {
303 if (cArgumentParser.IsSwitch("-f"))
304 {
305 //format: [-f]
306 // 0 => XA (Oric)
307 // 1 => Devpac (Atari)
308 inputFormat=(INPUT_FORMAT)cArgumentParser.GetIntegerValue(INPUT_FORMAT_ORIC_XA);
309 }
310 }
311
312
313 if (cArgumentParser.GetParameterCount()!=NB_ARG)
314 {
315 ShowError(0);
316 }
317
318
319 //
320 // Copy last parameters
321 //
322 std::string source_name(cArgumentParser.GetParameter(0));
323 std::string dest_name(cArgumentParser.GetParameter(1));
324 std::string project_name(cArgumentParser.GetParameter(2));
325 std::string css_name(cArgumentParser.GetParameter(3));
326
327 /*
328 printf("\n0=%s\n",source_name.c_str());
329 printf("\n1=%s\n",dest_name.c_str());
330 printf("\n2=%s\n",project_name.c_str());
331 printf("\n3=%s\n",css_name.c_str());
332 */
333
334 void* ptr_buffer_void;
335 size_t size_buffer_src;
336
337 //
338 // Load the file
339 //
340 if (!LoadFile(source_name.c_str(),ptr_buffer_void,size_buffer_src))
341 {
342 printf("\nUnable to load file '%s'",source_name.c_str());
343 printf("\n");
344 exit(1);
345 }
346
347 unsigned char *ptr_buffer=(unsigned char*)ptr_buffer_void;
348
349 //
350 // Parse the file, and generate the list of values
351 //
352 std::map<std::string,Section> Sections;
353
354 switch (inputFormat)
355 {
356 case INPUT_FORMAT_ORIC_XA:
357 {
358 Section& section_zeropage=Sections["Zero"];
359 section_zeropage.m_anchor_name ="Zero";
360 section_zeropage.m_section_name ="Zero page";
361 section_zeropage.m_adress_size =2;
362 section_zeropage.m_begin_adress =0x0;
363 section_zeropage.m_end_adress =0xFF;
364
365 Section& section_normal=Sections["Normal"];
366 section_normal.m_anchor_name ="Normal";
367 section_normal.m_section_name ="Normal memory";
368 section_normal.m_adress_size =4;
369 section_normal.m_begin_adress =0x400;
370 section_normal.m_end_adress =0xBFFF;
371
372 Section& section_overlay=Sections["Overlay"];
373 section_overlay.m_anchor_name ="Overlay";
374 section_overlay.m_section_name ="Overlay memory";
375 section_overlay.m_adress_size =4;
376 section_overlay.m_begin_adress =0xC000;
377 section_overlay.m_end_adress =0xFFFF;
378 }
379 break;
380
381 case INPUT_FORMAT_ATARI_DEVPAC:
382 {
383 Section& section_zeropage=Sections["Text"];
384 section_zeropage.m_anchor_name ="Text";
385 section_zeropage.m_section_name ="Section TEXT";
386 section_zeropage.m_adress_size =4;
387 section_zeropage.m_begin_adress =0x00;
388 section_zeropage.m_end_adress =0xFFFFFF;
389
390 Section& section_normal=Sections["Data"];
391 section_normal.m_anchor_name ="Data";
392 section_normal.m_section_name ="Section DATA";
393 section_normal.m_adress_size =4;
394 section_normal.m_begin_adress =0x00;
395 section_normal.m_end_adress =0xFFFFFF;
396
397 Section& section_overlay=Sections["Bss"];
398 section_overlay.m_anchor_name ="Bss";
399 section_overlay.m_section_name ="Section BSS";
400 section_overlay.m_adress_size =4;
401 section_overlay.m_begin_adress =0x00;
402 section_overlay.m_end_adress =0xFFFFFF;
403
404 Section& section_rs=Sections["RS"];
405 section_rs.m_anchor_name ="RS";
406 section_rs.m_section_name ="RS offsets";
407 section_rs.m_adress_size =4;
408 section_rs.m_begin_adress =0x00;
409 section_rs.m_end_adress =0xFFFFFF;
410 }
411 break;
412 }
413
414
415 char *ptr_tok=strtok((char*)ptr_buffer," \r\n");
416 while (ptr_tok)
417 {
418 // Address
419 int value=strtol(ptr_tok,0,16);
420
421 switch (inputFormat)
422 {
423 case INPUT_FORMAT_ORIC_XA:
424 {
425 ptr_tok=strtok(0," \r\n");
426 // Name
427 if (value<256)
428 {
429 // Zero page
430 Sections["Zero"].AddSymbol(value,ptr_tok);
431 }
432 else
433 if (value>=0xc000)
434 {
435 // Overlay memory
436 Sections["Overlay"].AddSymbol(value,ptr_tok);
437 }
438 else
439 {
440 Sections["Normal"].AddSymbol(value,ptr_tok);
441 }
442 }
443 break;
444
445 case INPUT_FORMAT_ATARI_DEVPAC:
446 {
447 // ptr_tok:
448 // A=Absolute (rs/offsets/computations)
449 // R=Relocatable (addresses)
450 // T=TEXT
451 // D=DATA
452 // B=BSS
453 std::string section="Text";
454
455 std::string token;
456 do
457 {
458 ptr_tok=strtok(0," \r\n");
459 token=ptr_tok;
460 if (token=="A") section="RS";
461 else if (token=="B") section="Bss";
462 else if (token=="T") section="Text";
463 else if (token=="D") section="Data";
464 }
465 while (token.size()==1);
466
467 Sections[section].AddSymbol(value,token);
468 }
469 }
470 ptr_tok=strtok(0," \r\n");
471 }
472
473
474 //
475 // Generate the html file
476 //
477 std::string html(gHtmlHeader);
478
479 StringReplace(html,"{PageTitle}" ,project_name);
480 StringReplace(html,"{CssLink}" ,css_name);
481
482 html+="<table>\r\n";
483 html+="<tr>\r\n";
484
485 std::map<std::string,Section>::iterator it(Sections.begin());
486 while (it!=Sections.end())
487 {
488 Section& section=it->second;
489 if (section.HasData())
490 {
491 // We export the section data only if there is something
492 html+="<td valign=top>\r\n";
493 section.Generate(html);
494 html+="</td>\r\n";
495 }
496 ++it;
497 }
498
499 html+="</tr>\r\n";
500 html+="</table>\r\n";
501
502 html=html+gHtmlFooter;
503
504 if (!SaveFile(dest_name.c_str(),html.c_str(),html.size()))
505 {
506 printf("\nUnable to save file '%s'",source_name.c_str());
507 printf("\n");
508 exit(1);
509 }
510
511 //
512 // Make some cleaning
513 //
514 delete[] ptr_buffer;
515
516 return 0;
517 }
518
519

  ViewVC Help
Powered by ViewVC 1.1.26