1 /* lkaomf51.c - Create an absolute object memory format 51 file
3 Copyright (C) 2002 Jesus Calvino-Fraga, jesusc at ieee dot org
5 This program is free software; you can redistribute it and/or modify it
6 under the terms of the GNU General Public License as published by the
7 Free Software Foundation; either version 3, or (at your option) any
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>. */
24 #define EQ(A,B) !strcmp((A),(B))
25 #define MEMSIZE 0x1000000
32 char PathName
[PATH_MAX
];
33 char ModuleName
[PATH_MAX
];
43 int Procedure
;//If the symbol belongs to a function
44 int Static
; //If the symbol is only public on its file
50 _symbol
* symbol
=NULL
;
62 _procedure
* procedure
=NULL
;
73 _linenum
* linenum
=NULL
;
82 _UsageType UsageType
[]=
106 {"", 5} /*A typeless number?*/
109 char * UsageTypeName
[]={"CODE", "XDATA", "DATA", "IDATA", "BIT", "NUMBER"};
111 short * ihxBuff
=NULL
;
114 int HexSize
, HexBegin
=0x1000000;
117 int GetName(char * filepath
, char * name
)
120 for(j
=strlen(filepath
); j
>0; j
--)
121 if( (filepath
[j
-1]=='/')||(filepath
[j
-1]=='\\') ) break;
122 for(k
=0; (filepath
[j
]!=0)&&(filepath
[j
]!='.'); j
++, k
++)
128 void SaveLinkedFilePath(char * filepath
)
132 if((yflag
) && (!rflag
))
136 infn
= realloc(infn
, sizeof(_infn
)*(numin
+1));
138 /*Get the module name=filename, no drive, no dir, no ext*/
139 ext
= GetName(filepath
, infn
[numin
].ModuleName
);
140 //printf("%s, %s\n", infn[numin].PathName, infn[numin].ModuleName);
142 strcpy(infn
[numin
].PathName
, filepath
);
144 /*If there is an extension remove it*/
145 if (infn
[numin
].PathName
[ext
] == '.')
146 infn
[numin
].PathName
[ext
] = '\0';
148 /*Check if this filename is already in*/
149 for (j
=0; j
<numin
; j
++)
151 if (EQ(infn
[numin
].PathName
, infn
[j
].PathName
))
196 void OutputByte(unsigned char value
)
199 fwrite( &value
, 1, 1, aomf51out
);
202 void OutputWord(int value
)
204 OutputByte((unsigned char)(value
%0x100));
205 OutputByte((unsigned char)(value
/0x100));
208 void OutputName(char * name
)
211 OutputByte((unsigned char)strlen(name
));
212 for(k
=0; name
[k
]!=0; k
++)
216 OutputByte((unsigned char)toupper(name
[k
]));
220 OutputByte((unsigned char)name
[k
]);
225 void OutputChkSum(void)
227 OutputByte((unsigned char)(0x100-(GlobalChkSum
%0x100)));
231 void DumpForDebug (void)
233 char DumpFileName
[PATH_MAX
];
237 strcpy(DumpFileName
, infn
[0].PathName
);
238 strcat(DumpFileName
, ".d51");
240 DumpFile
=fopen(DumpFileName
, "wb");
243 printf("Couldn't create file %s\n", DumpFileName
);
247 fprintf(DumpFile
,"SYMBOLS:\n");
249 for(j
=0; j
<numsym
; j
++)
251 k
=symbol
[j
].UsageType
&0xf;
252 fprintf(DumpFile
, "%s, %s, %s, 0x%04x, %s\n",
254 infn
[symbol
[j
].FileNameNumber
].PathName
,
255 (symbol
[j
].Procedure
>=0)?procedure
[symbol
[j
].Procedure
].name
:"GLOBAL",
257 k
<6?UsageTypeName
[k
]:"???");
260 fprintf(DumpFile
,"\nPROCEDURES:\n");
261 for(j
=0; j
<numproc
; j
++)
263 fprintf(DumpFile
, "%s, %s, 0x%04x-0x%04x, %c\n",
265 infn
[procedure
[j
].FileNameNumber
].PathName
,
266 procedure
[j
].BeginAdd
,
268 procedure
[j
].RegBank
+ '0');
271 fprintf(DumpFile
,"\nLINE NUMBERS:\n");
272 for(j
=0; j
<numlinenum
; j
++)
274 fprintf(DumpFile
, "%d:0x%04x, %s -> %s\n",
277 infn
[linenum
[j
].FileNameNumber
].PathName
,
278 (linenum
[j
].Procedure
>=0)?procedure
[linenum
[j
].Procedure
].name
:"I don't know");
284 void ParseRegisters(_symbol
* symbol
, const char * Registers
)
290 int nRegs
= sscanf(Registers
, "[ %[^,] %c %[^,] %c %[^,] %c %[^,] ]",
291 regs
[0], &c
, regs
[1], &c
, regs
[2], &c
, regs
[3]);
292 nRegs
= (nRegs
+ 1) / 2;
293 for (i
=0; i
<nRegs
; i
++)
295 if ((regs
[i
][0] == 'r') && isdigit(regs
[i
][1]))
297 address
[i
] = regs
[i
][1] - '0';
300 for (i
=1; i
<nRegs
; i
++)
302 if (address
[i
] != address
[i
-1] + 1)
303 {// we need strict ascending registers
307 if (0 <= symbol
->Procedure
&& symbol
->Procedure
< numproc
)
308 symbol
->Address
= address
[0] + procedure
[symbol
->Procedure
].RegBank
* 8;
311 void OutputAOEMF51(void)
313 int i
, j
, k
, recsize
;
314 char MHRname
[0x100], Mname
[0x100];
315 char aomf51FileName
[PATH_MAX
];
317 strcpy(aomf51FileName
, infn
[0].PathName
);
318 strcat(aomf51FileName
, ".omf");
320 aomf51out
=fopen(aomf51FileName
, "wb");
323 printf("Couldn't create file %s\n", aomf51FileName
);
327 GetName(infn
[0].PathName
, MHRname
);
330 /*Module header record*/
331 OutputByte(0x02);/*REC TYPE*/
332 OutputWord((strlen(MHRname
)+1)+3);/*Record Length*/
333 OutputName(MHRname
);/*Module Name*/
334 OutputByte(0xff);/*TRN ID: RL51?*/
338 for(j
=0; j
<numin
; j
++)
340 GetName(infn
[j
].PathName
, Mname
);
342 /*Scope Definition record: begin module block*/
343 OutputByte(0x10);/*REC TYPE*/
344 OutputWord((strlen(Mname
)+1)+2);/*Record Length*/
345 OutputByte(0x00);/*BLK TYP: module block*/
346 OutputName(Mname
);/*Module Name*/
349 /*Public symbols defined in this module*/
351 for(k
=0; k
<numsym
; k
++)/*Compute the record length*/
353 if ( (symbol
[k
].FileNameNumber
==j
) &&
354 (symbol
[k
].Address
!=-1) &&
355 (symbol
[k
].Procedure
==-1) &&
356 (symbol
[k
].Static
==-1) )
358 recsize
+=((strlen(symbol
[k
].name
)+1)+5);
362 if(recsize
>2) /*If there are any symbols*/
364 OutputByte(0x12); /*REC TYPE*/
365 OutputWord(recsize
); /*Record Length*/
366 OutputByte(0x01); /*DEF TYPE: Public symbols*/
367 for(k
=0; k
<numsym
; k
++)
369 if ( (symbol
[k
].FileNameNumber
==j
) &&
370 (symbol
[k
].Address
!=-1) &&
371 (symbol
[k
].Procedure
==-1) &&
372 (symbol
[k
].Static
==-1) )
374 OutputByte(0x00);/*SEG ID*/
375 OutputByte((unsigned char)symbol
[k
].UsageType
);/*SYM INFO*/
376 OutputWord(symbol
[k
].Address
);/*Offset*/
378 OutputName(symbol
[k
].name
);/*Symbol name*/
384 /*Local symbols defined in this module*/
386 for(k
=0; k
<numsym
; k
++)/*Compute the record length*/
388 if ( (symbol
[k
].FileNameNumber
==j
) &&
389 (symbol
[k
].Address
!=-1) &&
390 (symbol
[k
].Procedure
==-1) &&
391 (symbol
[k
].Static
==j
) )
393 recsize
+=((strlen(symbol
[k
].name
)+1)+5);
397 if(recsize
>2) /*If there are any symbols*/
399 OutputByte(0x12); /*REC TYPE*/
400 OutputWord(recsize
); /*Record Length*/
401 OutputByte(0x00); /*DEF TYPE: Local symbols*/
402 for(k
=0; k
<numsym
; k
++)
404 if ( (symbol
[k
].FileNameNumber
==j
) &&
405 (symbol
[k
].Address
!=-1) &&
406 (symbol
[k
].Procedure
==-1) &&
407 (symbol
[k
].Static
==j
) )
409 OutputByte(0x00);/*SEG ID*/
410 OutputByte((unsigned char)symbol
[k
].UsageType
);/*SYM INFO*/
411 OutputWord(symbol
[k
].Address
);/*Offset*/
413 OutputName(symbol
[k
].name
);/*Symbol name*/
419 /*Output the procedures of this module*/
421 for(k
=0; k
<numproc
; k
++)
423 if(procedure
[k
].FileNameNumber
==j
)
425 /*Scope Definition record: begin PROCEDURE block*/
426 OutputByte(0x10);/*REC TYPE*/
427 OutputWord((strlen(procedure
[k
].name
)+1)+2);/*Record Length*/
428 OutputByte(0x02);/*BLK TYP: PROCEDURE block*/
429 OutputName(procedure
[k
].name
);/*Module Name*/
433 OutputByte(0x06);/*REC TYPE*/
434 if (procedure
[k
].EndAdd
==-1)
435 procedure
[k
].EndAdd
=HexSize
;
436 recsize
=procedure
[k
].EndAdd
-procedure
[k
].BeginAdd
+1+4;
437 OutputWord(recsize
);/*Record Length*/
438 OutputByte(0x00);/*SEG ID*/
439 OutputWord(procedure
[k
].BeginAdd
); /*Offset*/
440 for (i
=procedure
[k
].BeginAdd
; i
<=procedure
[k
].EndAdd
; i
++)
442 if (i
< 0 || MEMSIZE
<= i
)
444 OutputByte((unsigned char)ihxBuff
[i
]);
452 for(i
=0; i
<numsym
; i
++)/*Get the record length*/
454 if( (symbol
[i
].Procedure
==k
) &&
455 (symbol
[i
].Address
!=-1) )
457 recsize
+=((strlen(symbol
[i
].name
)+1)+5);
461 if(recsize
>2) /*If there are any symbols*/
463 OutputByte(0x12); /*REC TYPE*/
464 OutputWord(recsize
); /*Record Length*/
465 OutputByte(0x00); /*DEF TYPE: Local symbols*/
466 for(i
=0; i
<numsym
; i
++)
468 if ( (symbol
[i
].Procedure
==k
) &&
469 (symbol
[i
].Address
!=-1) )
471 OutputByte(0x00);/*SEG ID*/
472 OutputByte((unsigned char)symbol
[i
].UsageType
);/*SYM INFO*/
473 OutputWord(symbol
[i
].Address
);/*Offset*/
475 OutputName(symbol
[i
].name
);/*Symbol name*/
483 for(i
=0; i
<numlinenum
; i
++)/*Get the record length*/
484 if(linenum
[i
].Procedure
==k
)
487 if(recsize
>2) /*If there are any line numbers*/
489 OutputByte(0x12); /*REC TYPE*/
490 OutputWord(recsize
); /*Record Length*/
491 OutputByte(0x03); /*DEF TYPE: Line numbers*/
492 for(i
=0; i
<numlinenum
; i
++)
494 if ( (linenum
[i
].Procedure
==k
) )
496 OutputByte(0x00);/*SEG ID*/
497 OutputWord(linenum
[i
].Address
);/*Offset*/
498 OutputWord(linenum
[i
].Number
);/*Line Number*/
504 /*Scope Definition record: end PROCEDURE block*/
505 OutputByte(0x10);/*REC TYPE*/
506 OutputWord((strlen(procedure
[k
].name
)+1)+2);/*Record Length*/
507 OutputByte(0x05);/*BLK TYP: PROCEDURE end block*/
508 OutputName(procedure
[k
].name
);/*Module Name*/
513 /*Scope Definition record: end module block*/
514 OutputByte(0x10);/*REC TYPE*/
515 OutputWord((strlen(Mname
)+1)+2);/*Record Length*/
516 OutputByte(0x03);/*BLK TYP: module end*/
517 OutputName(Mname
);/*Module Name*/
521 /*Content records for everything that is not in the above procedures*/
522 strcpy(Mname
, "OTHER_SDCC_STUFF");
524 /*Scope Definition record: begin module block*/
525 OutputByte(0x10);/*REC TYPE*/
526 OutputWord((strlen(Mname
)+1)+2);/*Record Length*/
527 OutputByte(0x00);/*BLK TYP: module block*/
528 OutputName(Mname
);/*Module Name*/
531 for (i
=HexBegin
; i
<HexSize
; )
533 for (k
=i
; k
<HexSize
; k
++)
541 OutputByte(0x06);/*REC TYPE*/
542 OutputWord(k
-i
+4);/*Record Length*/
543 OutputByte(0x00);/*SEG ID*/
544 OutputWord(i
); /*Offset*/
547 OutputByte((unsigned char)ihxBuff
[i
]);
552 for ( ; i
<HexSize
; i
++)
559 /*Scope Definition record: end module block*/
560 OutputByte(0x10);/*REC TYPE*/
561 OutputWord((strlen(Mname
)+1)+2);/*Record Length*/
562 OutputByte(0x03);/*BLK TYP: module end*/
563 OutputName(Mname
);/*Module Name*/
566 /*Module end record*/
567 OutputByte(0x04);/*REC TYPE*/
568 OutputWord((strlen(MHRname
)+1)+5);/*Record Length*/
569 OutputName(MHRname
);/*Module Name*/
571 OutputByte(0x0f);/*REG MSK: All the register banks?*/
578 void CollectInfoFromCDB(void)
580 int i
, j
, k
, CurrentModule
;
583 char SourceName
[PATH_MAX
];
585 //"S:{G|F<filename>|L<filename>.<functionName>}$<name>$<level>$<block>(<type info>),<Address Space>,<on Stack?>,<stack offset>"
586 char Sfmt
[]="%[^$] %c %[^$] %c %[^$] %c %s";
593 char TypeInfo
[0x100];
600 char Registers
[0x100];
611 /*Build the source filename*/
612 strcpy(SourceName
, infn
[0].PathName
);
613 strcat(SourceName
, ".cdb");
614 CDBin
=fopen(SourceName
, "r");
617 printf("Couldn't open file '%s'\n", SourceName
);
621 CurrentModule
=0; /*Set the active module as the first one*/
624 if(NULL
==fgets(buff
, sizeof(buff
)-1, CDBin
))
628 perror("Can't read file");
631 else if(!feof(CDBin
))
633 fprintf(stderr
, "Unknown error while reading file '%s'\n", SourceName
);
638 if(!feof(CDBin
)) switch(buff
[0])
642 sscanf(&buff
[2], "%s", name
);
643 for(j
=0; j
<numin
; j
++)
644 if(EQ(infn
[j
].ModuleName
, name
)) break;
645 if(j
<numin
) CurrentModule
=j
;
649 "S:G$actual$0$0({7}ST__00010000:S),E,0,0"
650 "S:Lfile.main$j$1$1({2}SI:S),E,0,0"
651 "S:Lfile.main$k$1$1({2}DG,SI:S),R,0,0,[r2,r3]"
652 "S:G$DS1306_Reset_SPI$0$0({2}DF,SV:S),C,0,0"
653 "S:G$main$0$0({2}DF,SV:S),C,0,0"
663 /*<block>(<type info>),<Address Space>,<on Stack?>,<stack offset>*/
664 sscanf(block
, "%[^)] %c %c %c %c %d %c %d %c %s",
674 case 'G': /*Global symbol*/
676 case 'F': /*Local symbol to a module*/
677 for(j
=0; j
<numin
; j
++)
679 if (EQ(&scope
[3], infn
[j
].ModuleName
))
686 case 'L': /*Local symbol of a procedure*/
687 for(j
=0; j
<numproc
; j
++)
689 size_t mlen
= strlen(infn
[procedure
[j
].FileNameNumber
].ModuleName
);
690 if ((!strncmp (&scope
[3], infn
[procedure
[j
].FileNameNumber
].ModuleName
, mlen
)) &&
691 (scope
[mlen
+3] == '.') &&
692 (EQ(&scope
[mlen
+4], procedure
[j
].name
)))
694 k
= j
; /*Local symbol*/
701 /*This symbol may have been already defined*/
702 for (j
=0; j
<numsym
; j
++)
704 if (EQ(name
, symbol
[j
].name
) &&
705 (symbol
[j
].Procedure
== k
) &&
706 (symbol
[j
].Static
== i
) ) break;
708 if(j
==numsym
) /*New symbol*/
710 symbol
=realloc(symbol
, sizeof(_symbol
)*(numsym
+1));
711 symbol
[numsym
].FileNameNumber
=CurrentModule
;
712 strcpy(symbol
[numsym
].name
, name
);
713 symbol
[numsym
].Procedure
=k
;
714 symbol
[numsym
].Static
=i
;
715 symbol
[numsym
].Address
=-1;/*Collected later*/
720 case 'D': /*Code/static segment*/
721 case 'Z': /*Functions and undefined code space*/
722 symbol
[numsym
].UsageType
=0x40;
725 case 'F': /*External ram*/
726 case 'A': /*External stack*/
727 case 'P': /*External Pdata*/
728 symbol
[numsym
].UsageType
=0x41;
731 case 'E': /*Internal ram (lower 128) bytes*/
732 case 'I': /*SFR space*/
733 symbol
[numsym
].UsageType
=0x42;
736 case 'R': /*Register Space*/
737 ParseRegisters(&symbol
[numsym
], Registers
);
738 symbol
[numsym
].UsageType
=0x42;
741 case 'B': /*Internal stack*/
742 case 'G': /*Internal ram*/
743 symbol
[numsym
].UsageType
=0x43;
746 case 'H': /*Bit addressable*/
747 case 'J': /*SBIT space*/
748 symbol
[numsym
].UsageType
=0x44;
752 printf("Unknown scope information for: %s, AddressSpace:%c\n", symbol
[numsym
].name
, AddressSpace
);
760 F:G$AsciiToHex$0$0({2}DF,SC:U),C,0,0,0,0,0
761 F:G$main$0$0({2}DF,SV:S),C,0,0,0,0,0
762 F:Fbug1627975$f2$0$0({2}DF,DG,SI:U),C,0,0,0,0,0 */
765 sscanf(buff
, "%[^$] %c %[^$] %c %[^$] %c %s",
771 /*<block>(<type info>),<Address Space>,<on Stack?>,<stack offset>,<isr?>,<int nr>,<regbank> */
772 sscanf(block
, "%[^)] %c %c %c %c %d %c %d %c %d %c %d %c %d",
780 /*The same may have been already defined */
781 for(j
=0; j
<numproc
; j
++)
783 if (EQ(name
, procedure
[j
].name
) &&
784 (procedure
[j
].FileNameNumber
== CurrentModule
))
791 procedure
=realloc(procedure
, sizeof(_procedure
)*(numproc
+1));
792 strcpy(procedure
[numproc
].name
, name
);
793 procedure
[numproc
].FileNameNumber
=CurrentModule
;
794 procedure
[numproc
].BeginAdd
=-1;/*To be collected latter*/
795 procedure
[numproc
].EndAdd
=-1;/*To be collected latter*/
796 procedure
[numproc
].RegBank
=RegBank
;
800 /*This function name is also a global symbol*/
801 for(j
=0; j
<numsym
; j
++)/*A global symbol may have been already defined*/
803 if (EQ(name
, symbol
[j
].name
) &&
804 (symbol
[j
].Procedure
==-1) &&
805 (symbol
[j
].FileNameNumber
== CurrentModule
))
812 symbol
=realloc(symbol
, sizeof(_symbol
)*(numsym
+1));
813 symbol
[numsym
].FileNameNumber
=CurrentModule
;
814 strcpy(symbol
[numsym
].name
, name
);
815 symbol
[numsym
].UsageType
=0x00;/*A procedure name symbol*/
816 symbol
[numsym
].Procedure
=-1; /*Global symbol*/
817 symbol
[numsym
].Address
=-1;/*Collected later*/
818 symbol
[numsym
].Static
= buff
[2]=='F' ? CurrentModule
: -1; // o_gloom
826 case 'G': /*Example L:G$P0$0$0:80*/
827 sscanf(buff
, "%[^$] %c %[^$] %c %[^:] %c %x",
828 scope
, &c
, name
, &c
, level
, &c
, &Address
);
830 for(j
=0; j
<numsym
; j
++)
832 if(EQ(symbol
[j
].name
, name
))
834 if( (symbol
[j
].Address
==-1) && (symbol
[j
].Procedure
==-1) )
836 symbol
[j
].Address
=Address
;
839 /*If the symbol is the name of a procedure, the address is also
840 the begining of such procedure*/
841 if ((symbol
[j
].UsageType
& 0x0f) == 0x00)
843 for (k
=0; k
<numproc
; k
++)
845 if (EQ(symbol
[j
].name
, procedure
[k
].name
))
847 if (procedure
[k
].BeginAdd
== -1)
848 procedure
[k
].BeginAdd
= Address
;
859 case 'F': /*Example L:Fadq$_str_2$0$0:57A*/
860 sscanf(&buff
[3], "%[^$] %c %[^$] %c %[^:] %c %x",
861 scope
, &c
, name
, &c
, level
, &c
, &Address
);
863 for (j
=0; j
<numsym
; j
++)
865 if (EQ(symbol
[j
].name
, name
) &&
866 EQ(infn
[symbol
[j
].FileNameNumber
].ModuleName
, scope
))
868 if( (symbol
[j
].Address
== -1) )
870 symbol
[j
].Address
= Address
;
876 /*It could be also a static function*/
877 for (j
=0; j
<numproc
; j
++)
879 if (EQ(procedure
[j
].name
, name
) &&
880 EQ(infn
[procedure
[j
].FileNameNumber
].ModuleName
, scope
))
882 if( (procedure
[j
].BeginAdd
== -1) )
884 procedure
[j
].BeginAdd
= Address
;
892 case 'L': /*Example L:Lmain$j$1$1:29*/
895 L:Lds1306.DS1306_Write$Value$1$1:34
896 L:Lds1306.DS1306_Burst_Read$count$1$1:35
897 L:Lds1306.DS1306_Burst_Read$address$1$1:36
898 L:Lds1306.DS1306_Burst_Write$count$1$1:37
899 L:Lds1306.DS1306_Burst_Write$address$1$1:38
901 sscanf(&buff
[3], "%[^.] %c %[^$] %c %[^$] %c %[^:] %c %x",
902 module
, &c
, scope
, &c
, name
, &c
, level
, &c
, &Address
);
904 for (k
=0; k
<numproc
; k
++)
906 if (EQ(procedure
[k
].name
, scope
) &&
907 EQ(infn
[procedure
[k
].FileNameNumber
].ModuleName
, module
))
909 for (j
=0; j
<numsym
; j
++)
911 if ((symbol
[j
].FileNameNumber
== procedure
[k
].FileNameNumber
) &&
912 (symbol
[j
].Procedure
== k
) &&
913 (EQ(symbol
[j
].name
, name
)))
915 if (symbol
[j
].Address
== -1)
916 symbol
[j
].Address
= Address
;
927 case 'C': /*Example L:C$adq.c$38$1$1:3E*/ /*L:C$hwinit.c$29$1$1:7AD*/
928 sscanf(&buff
[4], "%[^.] %[^$] %c %d %[^:] %c %x",
929 name
, level
, &c
, &CLine
, level
, &c
, &Address
);
931 for(j
=0; j
<numin
; j
++)
932 if(EQ(infn
[j
].ModuleName
, name
)) break;
935 /*Check if this line is already defined*/
936 for(k
=0; k
<numlinenum
; k
++)
938 if( (linenum
[k
].Number
==CLine
) &&
939 (linenum
[k
].FileNameNumber
==j
) )break;
941 if(k
==numlinenum
) /*New line number*/
943 linenum
=realloc(linenum
, sizeof(_linenum
)*(numlinenum
+1));
944 linenum
[numlinenum
].Number
=CLine
;
945 linenum
[numlinenum
].FileNameNumber
=j
;
946 linenum
[numlinenum
].Procedure
=-1;/*To be asigned later*/
947 linenum
[numlinenum
].Address
=Address
;
953 case 'A': /*Example L:A$adq$424:40*/
954 /*No use for this one*/
957 /*The end of a procedure*/
958 case 'X': /*Example L:XG$AsciiToHex$0$0:88*/
959 sscanf(&buff
[3], "%[^$] %c %[^$] %c %[^:] %c %x",
960 scope
, &c
, name
, &c
, level
, &c
, &Address
);
962 for(k
=0; k
<numproc
; k
++)
964 if (EQ(procedure
[k
].name
, name
) &&
966 EQ(infn
[procedure
[k
].FileNameNumber
].ModuleName
, &scope
[1])))
968 if( (procedure
[k
].EndAdd
== -1) )
970 procedure
[k
].EndAdd
= Address
;
984 /*Make sure each procedure has an end*/
985 for(k
=0; k
<(numproc
-1); k
++)
987 if (procedure
[k
].EndAdd
==-1) procedure
[k
].EndAdd
=procedure
[k
+1].BeginAdd
-1;
989 /*Assign each line number to a procedure*/
990 for(j
=0; j
<numlinenum
; j
++)
992 for(k
=0; k
<numproc
; k
++)
994 if ( (linenum
[j
].Address
>=procedure
[k
].BeginAdd
) &&
995 (linenum
[j
].Address
<=procedure
[k
].EndAdd
) &&
996 (linenum
[j
].FileNameNumber
==procedure
[k
].FileNameNumber
) )
998 linenum
[j
].Procedure
=k
;
1006 int hex2dec (unsigned char hex_digit
)
1008 if (isdigit (hex_digit
))
1009 return hex_digit
-'0';
1011 return toupper (hex_digit
)-'A'+10;
1014 unsigned char GetByte(char * buffer
)
1016 return hex2dec(buffer
[0])*0x10+hex2dec(buffer
[1]);
1019 unsigned short GetWord(char * buffer
)
1021 return hex2dec(buffer
[0])*0x1000+
1022 hex2dec(buffer
[1])*0x100+
1023 hex2dec(buffer
[2])*0x10+
1027 int ReadHexFile(int * Begin
)
1029 char ihxFileName
[PATH_MAX
];
1033 unsigned char linesize
, recordtype
, rchksum
, value
;
1034 int address
, hi_addr
= 0;
1038 /*If the hexfile is already open, close it*/
1045 strcpy(ihxFileName
, infn
[0].PathName
);
1046 strcat(ihxFileName
, ".ihx");
1048 if ( (filein
=fopen(ihxFileName
, "r")) == NULL
)
1050 printf("Error: Can't open file `%s`.\r\n", ihxFileName
);
1054 ihxBuff
= calloc(MEMSIZE
, sizeof(short));
1057 printf("Insufficient memory\n");
1062 for (j
=0; j
<MEMSIZE
; j
++) ihxBuff
[j
]=-1;
1066 if(fgets(buffer
, sizeof(buffer
), filein
)==NULL
)
1068 printf("Error reading file '%s'\n", ihxFileName
);
1073 linesize
= GetByte(&buffer
[1]);
1074 address
= hi_addr
| GetWord(&buffer
[3]);
1075 recordtype
= GetByte(&buffer
[7]);
1076 rchksum
= GetByte(&buffer
[9]+(linesize
*2));
1077 chksum
=linesize
+(address
/0x100)+(address
%0x100)+recordtype
+rchksum
;
1082 for (j
=0; j
<linesize
; j
++)
1084 value
= GetByte(&buffer
[9]+(j
*2));
1086 ihxBuff
[address
+j
] = value
;
1088 if (MaxAddress
< (address
+linesize
-1))
1089 MaxAddress
= (address
+linesize
-1);
1090 if (address
< *Begin
)
1095 hi_addr
= (GetWord(&buffer
[9]) << 16) & 0x00FFFFFF; //upto 24 bit address space
1102 if ((chksum
% 0x100) != 0)
1104 printf("ERROR: Bad checksum in file %s\n", ihxFileName
);
1109 if (recordtype
==1) /*End of record*/
1118 void CreateAOMF51(void)
1120 if((yflag
) && (!rflag
))
1122 CollectInfoFromCDB();
1126 HexSize
=ReadHexFile(&HexBegin
)+1;