Announce SDCC 4.5.0 RC3.
[sdcc.git] / sdcc / sdas / linksrc / lkmem.c
bloba4bb3b91babd09852242165e8d1cde8f9bbb3300
1 /* lkmem.c - Create a memory summary file with extension .mem
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
8 later version.
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/>. */
18 #include <stdio.h>
19 #include <string.h>
20 #include <stdlib.h>
21 #include <assert.h>
22 #include "sdld.h"
23 #include "aslink.h"
25 int summary(struct area * areap)
27 if (TARGET_IS_8051 || TARGET_IS_6808) {
28 /* only for 8051 and 6808 targets */
30 #define EQ(A,B) !as_strcmpi((A),(B))
31 #define MIN_STACK 16
32 #define REPORT_ERROR(A, H) \
34 fprintf(of, "%s%s", (H)?"*** ERROR: ":"", (A)); \
35 fprintf(stderr, "%s%s", (H)?"\n?ASlink-Error-":"",(A)); \
36 toreturn=1; \
39 #define REPORT_WARNING(A, H) \
40 { \
41 fprintf(of, "%s%s", (H)?"*** WARNING: ":"", (A)); \
42 fprintf(stderr, "%s%s",(H)?"\n?ASlink-Warning-":"", (A)); \
45 char buff[128];
46 int j, toreturn=0;
47 unsigned int Total_Last=0, k;
49 struct area * xp;
50 FILE * of;
52 /*Artifacts used for printing*/
53 char start[15], end[15], size[15], max[15];
54 char format[]=" %-16.16s %-8.8s %-8.8s %-8.8s %-8.8s\n";
55 char line[]="---------------------";
57 typedef struct
59 unsigned long Start;
60 unsigned long Size;
61 unsigned long Max;
62 char Name[NCPS];
63 unsigned long flag;
64 } _Mem;
66 unsigned int dram[0x100];
67 _Mem Ram8051[] = {
68 {0, 8, 8, "REG_BANK_0", 0x0001},
69 {0x8, 8, 8, "REG_BANK_1", 0x0002},
70 {0x10, 8, 8, "REG_BANK_2", 0x0004},
71 {0x18, 8, 8, "REG_BANK_3", 0x0008},
72 {0x20, 0, 16, "BSEG_BYTES", 0x0010},
73 {0, 0, 128, "UNUSED", 0x0000},
74 {0x7f, 0, 128, "DATA", 0x0020},
75 {0, 0, 128, "TOTAL:", 0x0000}
78 _Mem IRam8051 = {0xff, 0, 128, "INDIRECT RAM", 0x0080};
79 _Mem Stack8051 = {0xff, 0, 1, "STACK", 0x0000};
80 _Mem XRam8051 = {0xffff, 0, 65536, "EXTERNAL RAM", 0x0100};
81 _Mem Rom8051 = {0xffff, 0, 65536, "ROM/EPROM/FLASH", 0x0200};
83 _Mem Ram6808[] = {
84 {0, 0, 0, "REG_BANK_0", 0x0001},
85 {0x0, 0, 0, "REG_BANK_1", 0x0002},
86 {0x0, 0, 0, "REG_BANK_2", 0x0004},
87 {0x0, 0, 0, "REG_BANK_3", 0x0008},
88 {0x0, 0, 0, "BSEG_BYTES", 0x0010},
89 {0, 0, 256, "UNUSED", 0x0000},
90 {0xff, 0, 256, "DATA", 0x0020},
91 {0, 0, 256, "TOTAL:", 0x0000}
94 _Mem IRam6808 = {0xff, 0, 0, "INDIRECT RAM", 0x0080};
95 _Mem Stack6808 = {0xff, 0, 1, "STACK", 0x0000};
96 _Mem XRam6808 = {0xffff, 0, 65536, "EXTERNAL RAM", 0x0100};
97 _Mem Rom6808 = {0xffff, 0, 65536, "ROM/EPROM/FLASH", 0x0200};
99 _Mem *Ram = NULL;
101 _Mem IRam = {0, 0, 0, "", 0};
102 _Mem Stack = {0, 0, 0, "", 0};
103 _Mem XRam = {0, 0, 0, "", 0};
104 _Mem Rom = {0, 0, 0, "", 0};
106 if (TARGET_IS_8051) {
107 Ram = Ram8051;
108 memcpy(&IRam, &IRam8051, sizeof (_Mem));
109 memcpy(&Stack, &Stack8051, sizeof (_Mem));
110 memcpy(&XRam, &XRam8051, sizeof (_Mem));
111 memcpy(&Rom, &Rom8051, sizeof (_Mem));
113 else {
114 Ram = Ram6808;
115 memcpy(&IRam, &IRam6808, sizeof (_Mem));
116 memcpy(&Stack, &Stack6808, sizeof (_Mem));
117 memcpy(&XRam, &XRam6808, sizeof (_Mem));
118 memcpy(&Rom, &Rom6808, sizeof (_Mem));
121 if (stacksize == 0) stacksize = MIN_STACK;
123 if (TARGET_IS_8051) {
124 if(rflag) /*For the DS390*/
126 XRam.Max=0x1000000; /*24 bits*/
127 XRam.Start=0xffffff;
128 Rom.Max=0x1000000;
129 Rom.Start=0xffffff;
132 if((iram_size<=0)||(iram_size>0x100)) /*Default: 8052 like memory*/
134 Ram[5].Max=0x80;
135 Ram[6].Max=0x80;
136 Ram[7].Max=0x80;
137 IRam.Max=0x80;
138 iram_size=0x100;
140 else if(iram_size<0x80)
142 Ram[5].Max=iram_size;
143 Ram[6].Max=iram_size;
144 Ram[7].Max=iram_size;
145 IRam.Max=0;
147 else
149 Ram[5].Max=0x80;
150 Ram[6].Max=0x80;
151 Ram[7].Max=0x80;
152 IRam.Max=iram_size-0x80;
156 for(j=0; j<(int)iram_size; j++) dram[j]=0;
157 for(; j<0x100; j++) dram[j]=0x8000; /*Memory not available*/
159 /* Open Memory Summary File*/
160 of = afile(linkp->f_idp, "mem", 1);
161 if (of == NULL)
163 lkexit(1);
166 xp=areap;
167 while (xp)
169 /**/ if (EQ(xp->a_id, "REG_BANK_0"))
171 Ram[0].Size=xp->a_size;
173 else if (EQ(xp->a_id, "REG_BANK_1"))
175 Ram[1].Size=xp->a_size;
177 else if (EQ(xp->a_id, "REG_BANK_2"))
179 Ram[2].Size=xp->a_size;
181 else if (EQ(xp->a_id, "REG_BANK_3"))
183 Ram[3].Size=xp->a_size;
185 else if (EQ(xp->a_id, "BSEG_BYTES"))
187 if (TARGET_IS_8051)
188 Ram[4].Size+=xp->a_size;
189 else
190 Ram[4].Size=xp->a_size;
193 else if (EQ(xp->a_id, "SSEG"))
195 Stack.Size+=xp->a_size;
196 if(xp->a_addr<Stack.Start) Stack.Start=xp->a_addr;
199 else if (EQ(xp->a_id, "ISEG"))
201 IRam.Size+=xp->a_size;
202 if(xp->a_addr<IRam.Start) IRam.Start=xp->a_addr;
205 else if (TARGET_IS_8051)
207 if(xp->a_flag & A_XDATA)
209 if(xp->a_size>0)
211 XRam.Size+=xp->a_size;
212 if(xp->a_addr<XRam.Start) XRam.Start=xp->a_addr;
216 else if (EQ(xp->a_id, "BIT_BANK"))
218 Ram[4].Size+=xp->a_size;
221 else if(xp->a_flag & A_CODE)
223 if(xp->a_size>0)
225 Rom.Size+=xp->a_size;
226 if(xp->a_addr<Rom.Start) Rom.Start=xp->a_addr;
231 else if(TARGET_IS_6808)
233 if ( EQ(xp->a_id, "DSEG") || EQ(xp->a_id, "OSEG") )
235 Ram[6].Size+=xp->a_size;
236 if(xp->a_addr<Ram[6].Start) Ram[6].Start=xp->a_addr;
239 else if( EQ(xp->a_id, "CSEG") || EQ(xp->a_id, "GSINIT") ||
240 EQ(xp->a_id, "GSFINAL") || EQ(xp->a_id, "HOME") )
242 Rom.Size+=xp->a_size;
243 if(xp->a_addr<Rom.Start) Rom.Start=xp->a_addr;
246 else if (EQ(xp->a_id, "XSEG") || EQ(xp->a_id, "XISEG"))
248 XRam.Size+=xp->a_size;
249 if(xp->a_addr<XRam.Start) XRam.Start=xp->a_addr;
253 /*If is not a register bank, bit, stack, or idata, then it should be data*/
254 else if((TARGET_IS_8051 && xp->a_flag & (A_CODE|A_BIT|A_XDATA))==0)
256 if(xp->a_size)
258 Ram[6].Size+=xp->a_size;
259 if(xp->a_addr<Ram[6].Start) Ram[6].Start=xp->a_addr;
263 xp=xp->a_ap;
266 for(j=0; j<7; j++)
267 for(k=Ram[j].Start; (k<(Ram[j].Start+Ram[j].Size))&&(k<0x100); k++)
268 dram[k]|=Ram[j].flag; /*Mark as used*/
270 if (TARGET_IS_8051) {
271 for(k=IRam.Start; (k<(IRam.Start+IRam.Size))&&(k<0x100); k++)
272 dram[k]|=IRam.flag; /*Mark as used*/
275 /*Compute the amount of unused memory in direct data Ram. This is the
276 gap between the last register bank or bit segment and the data segment.*/
277 for(k=Ram[6].Start-1; (dram[k]==0) && (k>0); k--);
278 Ram[5].Start=k+1;
279 Ram[5].Size=Ram[6].Start-Ram[5].Start; /*It may be zero (which is good!)*/
281 /*Compute the data Ram totals*/
282 for(j=0; j<7; j++)
284 if(Ram[7].Start>Ram[j].Start) Ram[7].Start=Ram[j].Start;
285 Ram[7].Size+=Ram[j].Size;
287 Total_Last=Ram[6].Size+Ram[6].Start-1;
289 /*Report the Ram totals*/
290 fprintf(of, "Direct Internal RAM:\n");
291 fprintf(of, format, "Name", "Start", "End", "Size", "Max");
293 for(j=0; j<8; j++)
295 if((j==0) || (j==7)) fprintf(of, format, line, line, line, line, line);
296 if((j!=5) || (Ram[j].Size>0))
298 sprintf(start, "0x%02lx", Ram[j].Start);
299 if(Ram[j].Size==0)
300 end[0]=0;/*Empty string*/
301 else
302 sprintf(end, "0x%02lx", j==7?Total_Last:Ram[j].Size+Ram[j].Start-1);
303 sprintf(size, "%5lu", Ram[j].Size);
304 sprintf(max, "%5lu", Ram[j].Max);
305 fprintf(of, format, Ram[j].Name, start, end, size, max);
309 if (TARGET_IS_8051) {
310 for(k=Ram[6].Start; (k<(Ram[6].Start+Ram[6].Size))&&(k<0x100); k++)
312 if(dram[k]!=Ram[6].flag)
314 sprintf(buff, "Internal memory overlap starting at 0x%02x.\n", k);
315 REPORT_ERROR(buff, 1);
316 break;
320 if(Ram[4].Size>Ram[4].Max)
322 k=Ram[4].Size-Ram[4].Max;
323 sprintf(buff, "Insufficient bit addressable memory. "
324 "%d byte%s short.\n", k, (k==1)?"":"s");
325 REPORT_ERROR(buff, 1);
328 if(Ram[5].Size!=0)
330 sprintf(buff, "%ld bytes in data memory wasted. "
331 "SDCC link could use: --data-loc 0x%02lx\n",
332 Ram[5].Size, Ram[6].Start-Ram[5].Size);
333 REPORT_WARNING(buff, 1);
336 if((Ram[6].Start+Ram[6].Size)>Ram[6].Max)
338 k=(Ram[6].Start+Ram[6].Size)-Ram[6].Max;
339 sprintf(buff, "Insufficient space in data memory. "
340 "%d byte%s short.\n", k, (k==1)?"":"s");
341 REPORT_ERROR(buff, 1);
345 /*Report the position of the beginning of the stack*/
346 fprintf(of, "\n%stack starts at: 0x%02lx (sp set to 0x%02lx)",
347 rflag ? "16 bit mode initial s" : "S", Stack.Start, Stack.Start-1);
349 if (TARGET_IS_8051) {
350 /*Check that the stack pointer is landing in a safe place:*/
351 if( (dram[Stack.Start] & 0x8000) == 0x8000 )
353 fprintf(of, ".\n");
354 sprintf(buff, "Stack set to unavailable memory.\n");
355 REPORT_ERROR(buff, 1);
357 else if(dram[Stack.Start])
359 fprintf(of, ".\n");
360 sprintf(buff, "Stack overlaps area ");
361 REPORT_ERROR(buff, 1);
362 for(j=0; j<7; j++)
364 if(dram[Stack.Start]&Ram[j].flag)
366 sprintf(buff, "'%s'\n", Ram[j].Name);
367 break;
370 if(dram[Stack.Start]&IRam.flag)
372 sprintf(buff, "'%s'\n", IRam.Name);
374 REPORT_ERROR(buff, 0);
376 else
378 for(j=Stack.Start, k=0; (j<(int)iram_size)&&(dram[j]==0); j++, k++);
379 fprintf(of, " with %d bytes available\n", k);
380 if ((int)k<stacksize)
382 sprintf(buff, "Only %d byte%s available for stack.\n",
383 k, (k==1)?"":"s");
384 REPORT_WARNING(buff, 1);
389 fprintf(of, "\nOther memory:\n");
390 fprintf(of, format, "Name", "Start", "End", "Size", "Max");
391 fprintf(of, format, line, line, line, line, line);
393 /*Report IRam totals:*/
394 if(IRam.Size==0)
396 start[0]=0;/*Empty string*/
397 end[0]=0;/*Empty string*/
399 else
401 sprintf(start, "0x%02lx", IRam.Start);
402 sprintf(end, "0x%02lx", IRam.Size+IRam.Start-1);
404 sprintf(size, "%5lu", IRam.Size);
405 sprintf(max, "%5lu", IRam.Max);
406 fprintf(of, format, IRam.Name, start, end, size, max);
408 /*Report XRam totals:*/
409 if(XRam.Size==0)
411 start[0]=0;/*Empty string*/
412 end[0]=0;/*Empty string*/
414 else
416 sprintf(start, "0x%04lx", XRam.Start);
417 sprintf(end, "0x%04lx", XRam.Size+XRam.Start-1);
419 sprintf(size, "%5lu", XRam.Size);
420 sprintf(max, "%5lu", xram_size<0?XRam.Max:xram_size);
421 fprintf(of, format, XRam.Name, start, end, size, max);
423 /*Report Rom/Flash totals:*/
424 if(Rom.Size==0)
426 start[0]=0;/*Empty string*/
427 end[0]=0;/*Empty string*/
429 else
431 sprintf(start, "0x%04lx", Rom.Start);
432 sprintf(end, "0x%04lx", Rom.Size+Rom.Start-1);
434 sprintf(size, "%5lu", Rom.Size);
435 sprintf(max, "%5lu", code_size<0?Rom.Max:code_size);
436 fprintf(of, format, Rom.Name, start, end, size, max);
438 /*Report any excess:*/
439 if (TARGET_IS_8051) {
440 if((IRam.Start+IRam.Size)>(IRam.Max+0x80))
442 sprintf(buff, "Insufficient INDIRECT RAM memory.\n");
443 REPORT_ERROR(buff, 1);
446 if( ((XRam.Start+XRam.Size)>XRam.Max) ||
447 (((int)XRam.Size>xram_size)&&(xram_size>=0)) )
449 sprintf(buff, "Insufficient EXTERNAL RAM memory.\n");
450 REPORT_ERROR(buff, 1);
452 if( ((Rom.Start+Rom.Size)>Rom.Max) ||
453 (((int)Rom.Size>code_size)&&(code_size>=0)) )
455 sprintf(buff, "Insufficient ROM/EPROM/FLASH memory.\n");
456 REPORT_ERROR(buff, 1);
459 fclose(of);
460 return toreturn;
462 else {
463 assert (0);
464 return 0;
468 int summary2(struct area * areap)
470 if (TARGET_IS_8051) {
471 /* only for 8051 target */
473 #define EQ(A,B) !as_strcmpi((A),(B))
475 char buff[128];
476 int toreturn = 0;
477 unsigned int i, j;
478 unsigned long int Stack_Start=0, Stack_Size;
479 unsigned int spare_begin = 0, spare_size = 0;
481 struct area * xp;
482 struct area * xstack_xp = NULL;
483 FILE * of;
485 /*Artifacts used for printing*/
486 char start[15], end[15], size[15], max[15];
487 char format[]=" %-16.16s %-8.8s %-8.8s %-8.8s %-8.8s\n";
488 char line[]="---------------------";
490 typedef struct
492 unsigned long Start;
493 unsigned long End;
494 unsigned long Size;
495 unsigned long Max;
496 char Name[NCPS];
497 unsigned long flag;
498 } _Mem;
500 _Mem Stack={0xff, 0, 0, 1, "STACK", 0x0000};
501 _Mem Paged={0xffff, 0, 0, 256, "PAGED EXT. RAM", A3_PAG};
502 _Mem XRam= {0xffff, 0, 0, 65536, "EXTERNAL RAM", 0x0100};
503 _Mem Rom= {0xffff, 0, 0, 65536, "ROM/EPROM/FLASH", 0x0200};
505 if(rflag) /*For the DS390*/
507 XRam.Max=0x1000000; /*24 bits*/
508 XRam.Start=0xffffff;
509 Rom.Max=0x1000000;
510 Rom.Start=0xffffff;
513 /* Open Memory Summary File*/
514 of = afile(linkp->f_idp, "mem", 1);
515 if (of == NULL)
517 lkexit(1);
520 xp=areap;
521 while (xp)
523 if (xp->a_flag & A_CODE)
525 if(xp->a_size)
527 Rom.Size += xp->a_size;
528 if(xp->a_addr < Rom.Start)
529 Rom.Start = xp->a_addr;
530 if(xp->a_addr + xp->a_size > Rom.End)
531 Rom.End = xp->a_addr + xp->a_size;
535 else if (EQ(xp->a_id, "SSEG"))
537 Stack.Size += xp->a_size;
538 if(xp->a_addr < Stack.Start)
539 Stack.Start = xp->a_addr;
540 if(xp->a_addr + xp->a_size > Stack.End)
541 Stack.End = xp->a_addr + xp->a_size;
544 else if (EQ(xp->a_id, "PSEG"))
546 Paged.Size += xp->a_size;
547 if(xp->a_addr < Paged.Start)
548 Paged.Start = xp->a_addr;
549 if(xp->a_addr + xp->a_size > Paged.End)
550 Paged.End = xp->a_addr + xp->a_size;
553 else if (EQ(xp->a_id, "XSTK"))
555 xstack_xp = xp;
556 Paged.Size += xp->a_size;
557 if(xp->a_addr < Paged.Start)
558 Paged.Start = xp->a_addr;
559 if(xp->a_addr + xp->a_size > Paged.End)
560 Paged.End = xp->a_addr + xp->a_size;
563 else if (xp->a_flag & A_XDATA)
565 if(xp->a_size)
567 XRam.Size += xp->a_size;
568 if(xp->a_addr < XRam.Start)
569 XRam.Start = xp->a_addr;
570 if(xp->a_addr + xp->a_size > XRam.End)
571 XRam.End = xp->a_addr + xp->a_size;
575 xp = xp->a_ap;
578 /*Report the Ram totals*/
579 fprintf(of, "Internal RAM layout:\n");
580 fprintf(of, " 0 1 2 3 4 5 6 7 8 9 A B C D E F");
581 for(j=0; j<256; j++)
583 if(j%16==0) fprintf(of, "\n0x%02x:|", j);
584 fprintf(of, "%c|", idatamap[j]);
586 fprintf(of, "\n0-3:Reg Banks, T:Bit regs, a-z:Data, B:Bits, Q:Overlay, I:iData, S:Stack, A:Absolute\n");
588 for(j=0; j<256; j++)
590 if(idatamap[j]=='S')
592 Stack_Start=j;
593 break;
597 for(j=Stack_Start, Stack_Size=0; j<((iram_size)?iram_size:256); j++)
599 if(idatamap[j]=='S') Stack_Size++;
600 else break;
603 xp=areap;
604 while (xp)
606 if(xp->a_unaloc>0)
608 fprintf(of, "\nERROR: Couldn't get %d byte%s allocated"
609 " in internal RAM for area %s.",
610 xp->a_unaloc, xp->a_unaloc>1?"s":"", xp->a_id);
611 toreturn=1;
613 xp=xp->a_ap;
616 /*Report the position of the begining of the stack*/
617 if(Stack_Start!=256 && Stack_Size > 0)
618 fprintf(of, "\n%s starts at: 0x%02lx (sp set to 0x%02lx) with %ld bytes available.",
619 rflag ? "16 bit mode initial stack" : "Stack", Stack_Start, Stack_Start-1, Stack_Size);
620 else
621 fprintf(of, "\nNo clue at where the stack begins and ends!");
623 /* Report the spare space left in the IRAM */
624 for (j = 0; j < (iram_size ? iram_size : 256); )
626 for (i = j; i < (iram_size ? iram_size : 256) && idatamap[i] == ' '; i++);
627 if (i - j > spare_size)
629 spare_size = i - j;
630 spare_begin = j;
632 j = i + 1;
634 if (spare_size > 0)
635 fprintf(of, "\nThe largest spare internal RAM space starts at 0x%x with %d byte%s available.", spare_begin, spare_size, spare_size > 1 ? "s" : "");
636 else
637 fprintf(of, "\nNo spare internal RAM space left.");
639 /*Report about xstack*/
640 if (xstack_xp)
642 Stack_Start = xstack_xp->a_addr;
643 Stack_Size = xstack_xp->a_size;
644 fprintf(of, "\nXstack starts at: 0x%04lx with %ld bytes available.",
645 Stack_Start, Stack_Size);
648 fprintf(of, "\n\nOther memory:\n");
649 fprintf(of, format, "Name", "Start", "End", "Size", "Max");
650 fprintf(of, format, line, line, line, line, line);
652 /*Report Paged XRam totals:*/
653 if(Paged.Size==0)
655 start[0]=0;/*Empty string*/
656 end[0]=0;/*Empty string*/
658 else
660 sprintf(start, "0x%04lx", Paged.Start);
661 sprintf(end, "0x%04lx", Paged.End-1);
663 sprintf(size, "%5lu", Paged.Size);
664 sprintf(max, "%5lu", xram_size<0 ? Paged.Max : xram_size<256 ? xram_size : 256);
665 fprintf(of, format, Paged.Name, start, end, size, max);
667 /*Report XRam totals:*/
668 if(XRam.Size==0)
670 start[0]=0;/*Empty string*/
671 end[0]=0;/*Empty string*/
673 else
675 sprintf(start, "0x%04lx", XRam.Start);
676 sprintf(end, "0x%04lx", XRam.End-1);
678 sprintf(size, "%5lu", XRam.Size);
679 sprintf(max, "%5lu", xram_size<0?XRam.Max:xram_size);
680 fprintf(of, format, XRam.Name, start, end, size, max);
682 /*Report Rom/Flash totals:*/
683 if(Rom.Size==0)
685 start[0]=0;/*Empty string*/
686 end[0]=0;/*Empty string*/
688 else
690 sprintf(start, "0x%04lx", Rom.Start);
691 sprintf(end, "0x%04lx", Rom.End-1);
693 sprintf(size, "%5lu", Rom.Size);
694 sprintf(max, "%5lu", code_size<0?Rom.Max:code_size);
695 fprintf(of, format, Rom.Name, start, end, size, max);
697 /*Report any excess:*/
698 if( ((XRam.End) > XRam.Max) ||
699 ((((int)XRam.Size+(int)Paged.Size)>xram_size)&&(xram_size>=0)) )
701 sprintf(buff, "Insufficient EXTERNAL RAM memory.\n");
702 REPORT_ERROR(buff, 1);
704 if( ((Rom.End) > Rom.Max) ||
705 (((int)Rom.Size>code_size)&&(code_size>=0)) )
707 sprintf(buff, "Insufficient ROM/EPROM/FLASH memory.\n");
708 REPORT_ERROR(buff, 1);
711 fclose(of);
712 return toreturn;
714 else {
715 assert (0);
716 return 0;