1 /*-------------------------------------------------------------------------
3 SDCCglue.c - glues everything we have done together into one file.
4 Written By - Sandeep Dutta . sandeep.dutta@usa.net (1998)
6 This program is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 In other words, you are welcome to use, share and improve this program.
21 You are forbidden to forbid anyone else to use, share and improve
22 what you give them. Help stamp out software-hoarding!
23 -------------------------------------------------------------------------*/
25 #include "../common.h"
32 #ifdef WORDS_BIGENDIAN
33 #define _ENDIAN(x) (3-x)
35 #define _ENDIAN(x) (x)
38 #define BYTE_IN_LONG(x,b) ((x>>(8*_ENDIAN(b)))&0xff)
40 extern symbol *interrupts[256];
41 static void printIval (symbol * sym, sym_link * type, initList * ilist, pBlock *pb);
45 extern unsigned maxInterrupts;
46 extern int maxRegBank;
48 extern char *VersionString;
49 extern FILE *codeOutFile;
50 extern set *tmpfileSet;
51 extern set *tmpfileNameSet;
52 extern char *iComments1;
53 extern char *iComments2;
54 //extern void emitStaticSeg (memmap * map);
56 extern DEFSETFUNC (closeTmpFiles);
57 extern DEFSETFUNC (rmTmpFiles);
59 extern void AnalyzeBanking (void);
60 extern void copyFile (FILE * dest, FILE * src);
61 extern void InlinepCode(void);
62 extern void writeUsedRegs(FILE *);
64 extern void initialComments (FILE * afile);
65 extern void printPublics (FILE * afile);
67 extern void printChar (FILE * ofile, char *s, int plen);
68 void pCodeInitRegisters(void);
69 int getConfigWord(int address);
71 /*-----------------------------------------------------------------*/
72 /* aopLiteral - string from a literal value */
73 /*-----------------------------------------------------------------*/
74 int pic14aopLiteral (value *val, int offset)
81 /* if it is a float then it gets tricky */
82 /* otherwise it is fairly simple */
83 if (!IS_FLOAT(val->type)) {
84 unsigned long v = (unsigned long) floatFromVal(val);
86 return ( (v >> (offset * 8)) & 0xff);
89 /* it is type float */
90 fl.f = (float) floatFromVal(val);
91 #ifdef WORDS_BIGENDIAN
92 return fl.c[3-offset];
100 /*-----------------------------------------------------------------*/
101 /* emitRegularMap - emit code for maps with no special cases */
102 /*-----------------------------------------------------------------*/
104 pic14emitRegularMap (memmap * map, bool addPublics, bool arFlag)
109 /* print the area name */
111 fprintf (map->oFile, ";\t.area\t%s\n", map->sname);
113 for (sym = setFirstItem (map->syms); sym;
114 sym = setNextItem (map->syms)) {
116 //printf("%s\n",sym->name);
118 /* if extern then add it into the extern list */
119 if (IS_EXTERN (sym->etype)) {
120 addSetHead (&externs, sym);
124 /* if allocation required check is needed
125 then check if the symbol really requires
126 allocation only for local variables */
127 if (arFlag && !IS_AGGREGATE (sym->type) &&
128 !(sym->_isparm && !IS_REGPARM (sym->etype)) &&
129 !sym->allocreq && sym->level)
132 /* if global variable & not static or extern
133 and addPublics allowed then add it to the public set */
134 if ((sym->level == 0 ||
135 (sym->_isparm && !IS_REGPARM (sym->etype))) &&
137 !IS_STATIC (sym->etype))
138 addSetHead (&publics, sym);
140 /* if extern then do nothing or is a function
142 if (IS_FUNC (sym->type))
145 /* print extra debug info if required */
146 if (options.debug || sym->level == 0)
148 if (!sym->level) /* global */
149 if (IS_STATIC (sym->etype))
150 fprintf (map->oFile, "F%s_", moduleName); /* scope is file */
152 fprintf (map->oFile, "G_"); /* scope is global */
154 /* symbol is local */
155 fprintf (map->oFile, "L%s_", (sym->localof ? sym->localof->name : "-null-"));
156 fprintf (map->oFile, "%s_%d_%d", sym->name, sym->level, sym->block);
160 /* if it has an absolute address then generate
161 an equate for this no need to allocate space */
162 if (SPEC_ABSA (sym->etype))
164 //if (options.debug || sym->level == 0)
165 //fprintf (map->oFile,"; == 0x%04x\n",SPEC_ADDR (sym->etype));
167 fprintf (map->oFile, "%s\tEQU\t0x%04x\n",
169 SPEC_ADDR (sym->etype));
175 /* If this is a bit variable, then allocate storage after 8 bits have been declared */
176 /* unlike the 8051, the pic does not have a separate bit area. So we emulate bit ram */
177 /* by grouping the bits together into groups of 8 and storing them in the normal ram. */
178 if (IS_BITVAR (sym->etype))
184 fprintf (map->oFile, "%s\tres\t%d\n", sym->rname,getSize (sym->type) & 0xffff);
189 if ((size = (unsigned int) getSize (sym->type) & 0xffff) > 1)
191 for (i = 1; i < size; i++)
192 fprintf (map->oFile, "\t%s_%d\n", sym->rname, i);
197 //fprintf (map->oFile, "\t.ds\t0x%04x\n", (unsigned int)getSize (sym->type) & 0xffff);
200 /* if it has a initial value then do it only if
201 it is a global variable */
202 if (sym->ival && sym->level == 0) {
205 if (IS_AGGREGATE (sym->type))
206 ival = initAggregates (sym, sym->ival, NULL);
208 ival = newNode ('=', newAst_VALUE(symbolVal (sym)),
209 decorateType (resolveSymbols (list2expr (sym->ival))));
210 codeOutFile = statsg->oFile;
212 eBBlockFromiCode (iCodeFromAst (ival));
219 /*-----------------------------------------------------------------*/
220 /* printIvalType - generates ival for int/char */
221 /*-----------------------------------------------------------------*/
223 printIvalType (symbol *sym, sym_link * type, initList * ilist, pBlock *pb)
228 //fprintf(stderr, "%s\n",__FUNCTION__);
230 /* if initList is deep */
231 if (ilist->type == INIT_DEEP)
232 ilist = ilist->init.deep;
234 if (!IS_AGGREGATE(sym->type) && getNelements(type, ilist)>1) {
235 werror (W_EXCESS_INITIALIZERS, "scalar", sym->name, sym->lineDef);
238 if (!(val = list2val (ilist))) {
239 // assuming a warning has been thrown
243 if (val->type != type) {
244 val = valCastLiteral(type, floatFromVal(val));
248 ulval = (unsigned long) floatFromVal (val);
252 switch (getSize (type)) {
254 addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(BYTE_IN_LONG(ulval,0))));
258 addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(BYTE_IN_LONG(ulval,0))));
259 addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(BYTE_IN_LONG(ulval,1))));
263 addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(BYTE_IN_LONG(ulval,0))));
264 addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(BYTE_IN_LONG(ulval,1))));
265 addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(BYTE_IN_LONG(ulval,2))));
266 addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(BYTE_IN_LONG(ulval,3))));
271 /*-----------------------------------------------------------------*/
272 /* printIvalChar - generates initital value for character array */
273 /*-----------------------------------------------------------------*/
275 printIvalChar (sym_link * type, initList * ilist, pBlock *pb, char *s)
283 //fprintf(stderr, "%s\n",__FUNCTION__);
287 val = list2val (ilist);
288 /* if the value is a character string */
289 if (IS_ARRAY (val->type) && IS_CHAR (val->etype))
291 if (!DCL_ELEM (type))
292 DCL_ELEM (type) = strlen (SPEC_CVAL (val->etype).v_char) + 1;
294 //printChar (oFile, SPEC_CVAL (val->etype).v_char, DCL_ELEM (type));
295 //fprintf(stderr, "%s omitting call to printChar\n",__FUNCTION__);
296 addpCode2pBlock(pb,newpCodeCharP(";omitting call to printChar"));
298 if ((remain = (DCL_ELEM (type) - strlen (SPEC_CVAL (val->etype).v_char) - 1)) > 0)
300 //tfprintf (oFile, "\t!db !constbyte\n", 0);
301 addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(0)));
308 //printChar (oFile, s, strlen (s) + 1);
310 for(remain=0; remain<(int)strlen(s); remain++) {
311 addpCode2pBlock(pb,newpCode(POC_RETLW,newpCodeOpLit(s[remain])));
312 //fprintf(stderr,"0x%02x ",s[remain]);
314 //fprintf(stderr,"\n");
319 /*-----------------------------------------------------------------*/
320 /* printIvalArray - generates code for array initialization */
321 /*-----------------------------------------------------------------*/
323 printIvalArray (symbol * sym, sym_link * type, initList * ilist,
327 int lcnt = 0, size = 0;
332 /* take care of the special case */
333 /* array of characters can be init */
335 if (IS_CHAR (type->next)) {
336 //fprintf(stderr,"%s:%d - is_char\n",__FUNCTION__,__LINE__);
337 if (!IS_LITERAL(list2val(ilist)->etype)) {
338 werror (W_INIT_WRONG);
341 if (printIvalChar (type,
342 (ilist->type == INIT_DEEP ? ilist->init.deep : ilist),
343 pb, SPEC_CVAL (sym->etype).v_char))
346 /* not the special case */
347 if (ilist->type != INIT_DEEP)
349 werror (E_INIT_STRUCT, sym->name);
353 iloop = ilist->init.deep;
354 lcnt = DCL_ELEM (type);
358 //fprintf(stderr,"%s:%d - is_char\n",__FUNCTION__,__LINE__);
360 printIval (sym, type->next, iloop, pb);
361 iloop = (iloop ? iloop->next : NULL);
364 /* if not array limits given & we */
365 /* are out of initialisers then */
366 if (!DCL_ELEM (type) && !iloop)
369 /* no of elements given and we */
370 /* have generated for all of them */
372 /* if initializers left */
374 werror (W_EXCESS_INITIALIZERS, "array", sym->name, sym->lineDef);
380 /* if we have not been given a size */
381 if (!DCL_ELEM (type))
382 DCL_ELEM (type) = size;
387 /*-----------------------------------------------------------------*/
388 /* printIval - generates code for initial value */
389 /*-----------------------------------------------------------------*/
391 printIval (symbol * sym, sym_link * type, initList * ilist, pBlock *pb)
396 /* if structure then */
397 if (IS_STRUCT (type))
399 //fprintf(stderr,"%s struct\n",__FUNCTION__);
400 //printIvalStruct (sym, type, ilist, oFile);
404 /* if this is a pointer */
407 //fprintf(stderr,"%s pointer\n",__FUNCTION__);
408 //printIvalPtr (sym, type, ilist, oFile);
412 /* if this is an array */
415 //fprintf(stderr,"%s array\n",__FUNCTION__);
416 printIvalArray (sym, type, ilist, pb);
420 /* if type is SPECIFIER */
423 //fprintf(stderr,"%s spec\n",__FUNCTION__);
424 printIvalType (sym, type, ilist, pb);
429 extern void pCodeConstString(char *name, char *value);
430 /*-----------------------------------------------------------------*/
431 /* emitStaticSeg - emitcode for the static segment */
432 /*-----------------------------------------------------------------*/
434 pic14emitStaticSeg (memmap * map)
438 fprintf (map->oFile, ";\t.area\t%s\n", map->sname);
440 //fprintf(stderr, "%s\n",__FUNCTION__);
442 /* for all variables in this segment do */
443 for (sym = setFirstItem (map->syms); sym;
444 sym = setNextItem (map->syms))
446 /* if it is "extern" then do nothing */
447 if (IS_EXTERN (sym->etype))
450 /* if it is not static add it to the public
452 if (!IS_STATIC (sym->etype))
453 addSetHead (&publics, sym);
455 /* print extra debug info if required */
456 if (options.debug || sym->level == 0)
460 if (IS_STATIC (sym->etype))
461 fprintf (code->oFile, "F%s_", moduleName); /* scope is file */
463 fprintf (code->oFile, "G_"); /* scope is global */
466 /* symbol is local */
467 fprintf (code->oFile, "L%s_",
468 (sym->localof ? sym->localof->name : "-null-"));
469 fprintf (code->oFile, "%s_%d_%d", sym->name, sym->level, sym->block);
473 /* if it has an absolute address */
474 if (SPEC_ABSA (sym->etype))
476 if (options.debug || sym->level == 0)
477 fprintf (code->oFile, " == 0x%04x\n", SPEC_ADDR (sym->etype));
479 fprintf (code->oFile, "%s\t=\t0x%04x\n",
481 SPEC_ADDR (sym->etype));
485 if (options.debug || sym->level == 0)
486 fprintf (code->oFile, " == .\n");
488 /* if it has an initial value */
493 fprintf (code->oFile, "%s:\n", sym->rname);
495 resolveIvalSym (sym->ival);
496 //printIval (sym, sym->type, sym->ival, code->oFile);
497 pb = newpCodeChain(NULL, 'P',newpCodeCharP("; Starting pCode block for Ival"));
499 addpCode2pBlock(pb,newpCodeLabel(sym->rname,-1));
501 printIval (sym, sym->type, sym->ival, pb);
508 fprintf (code->oFile, "%s:\n", sym->rname);
509 /* special case for character strings */
510 if (IS_ARRAY (sym->type) && IS_CHAR (sym->type->next) &&
511 SPEC_CVAL (sym->etype).v_char)
512 pCodeConstString(sym->rname , SPEC_CVAL (sym->etype).v_char);
513 /*printChar (code->oFile,
514 SPEC_CVAL (sym->etype).v_char,
515 strlen (SPEC_CVAL (sym->etype).v_char) + 1);*/
517 fprintf (code->oFile, "\t.ds\t0x%04x\n", (unsigned int) getSize (sym->type) & 0xffff);
525 /*-----------------------------------------------------------------*/
526 /* emitMaps - emits the code for the data portion the code */
527 /*-----------------------------------------------------------------*/
531 /* no special considerations for the following
532 data, idata & bit & xdata */
533 pic14emitRegularMap (data, TRUE, TRUE);
534 pic14emitRegularMap (idata, TRUE, TRUE);
535 pic14emitRegularMap (bit, TRUE, FALSE);
536 pic14emitRegularMap (xdata, TRUE, TRUE);
537 pic14emitRegularMap (sfr, FALSE, FALSE);
538 pic14emitRegularMap (sfrbit, FALSE, FALSE);
539 pic14emitRegularMap (code, TRUE, FALSE);
540 pic14emitStaticSeg (statsg);
543 /*-----------------------------------------------------------------*/
544 /* createInterruptVect - creates the interrupt vector */
545 /*-----------------------------------------------------------------*/
547 pic14createInterruptVect (FILE * vFile)
549 mainf = newSymbol ("main", 0);
552 /* only if the main function exists */
553 if (!(mainf = findSymWithLevel (SymbolTab, mainf)))
555 if (!options.cc_only)
560 /* if the main is only a prototype ie. no body then do nothing */
561 if (!IFFUNC_HASBODY(mainf->type))
563 /* if ! compile only then main function should be present */
564 if (!options.cc_only)
569 fprintf (vFile, "%s", iComments2);
570 fprintf (vFile, "; config word \n");
571 fprintf (vFile, "%s", iComments2);
572 fprintf (vFile, "\t__config 0x%x\n", getConfigWord(0x2007));
574 fprintf (vFile, "%s", iComments2);
575 fprintf (vFile, "; reset vector \n");
576 fprintf (vFile, "%s", iComments2);
577 fprintf (vFile, "STARTUP\t%s\n", CODE_NAME);
578 fprintf (vFile, "\tnop\n"); /* first location used by incircuit debugger */
579 fprintf (vFile, "\tgoto\t__sdcc_gsinit_startup\n");
580 /* during an interrupt PCLATH must be cleared before a goto - delete me
581 fprintf (vFile, "\tnop\n");
582 fprintf (vFile, "\tgoto\t__sdcc_interrupt\n");
587 /*-----------------------------------------------------------------*/
588 /* initialComments - puts in some initial comments */
589 /*-----------------------------------------------------------------*/
591 pic14initialComments (FILE * afile)
593 initialComments (afile);
594 fprintf (afile, "; PIC port for the 14-bit core\n");
595 fprintf (afile, iComments2);
599 /*-----------------------------------------------------------------*/
600 /* printExterns - generates extern for external variables */
601 /*-----------------------------------------------------------------*/
603 pic14printExterns (FILE * afile)
607 fprintf (afile, "%s", iComments2);
608 fprintf (afile, "; extern variables in this module\n");
609 fprintf (afile, "%s", iComments2);
611 for (sym = setFirstItem (externs); sym;
612 sym = setNextItem (externs))
613 fprintf (afile, "\textern %s\n", sym->rname);
616 /*-----------------------------------------------------------------*/
617 /* printPublics - generates .global for publics */
618 /*-----------------------------------------------------------------*/
620 pic14printPublics (FILE * afile)
624 fprintf (afile, "%s", iComments2);
625 fprintf (afile, "; publics variables in this module\n");
626 fprintf (afile, "%s", iComments2);
628 for (sym = setFirstItem (publics); sym;
629 sym = setNextItem (publics)) {
630 if(!IS_BITFIELD(sym->type) && ((IS_FUNC(sym->type) || sym->allocreq))) {
631 if (!IS_BITVAR(sym->type))
632 fprintf (afile, "\tglobal %s\n", sym->rname);
634 fprintf (afile, ";\tglobal %s\n", sym->rname);
638 /*-----------------------------------------------------------------*/
639 /* emitOverlay - will emit code for the overlay stuff */
640 /*-----------------------------------------------------------------*/
642 pic14emitOverlay (FILE * afile)
646 if (!elementsInSet (ovrSetSets))
647 fprintf (afile, "\t%s\n", port->mem.overlay_name);
649 /* for each of the sets in the overlay segment do */
650 for (ovrset = setFirstItem (ovrSetSets); ovrset;
651 ovrset = setNextItem (ovrSetSets))
656 if (elementsInSet (ovrset))
658 /* this dummy area is used to fool the assembler
659 otherwise the assembler will append each of these
660 declarations into one chunk and will not overlay
663 /* I don't think this applies to us. We are using gpasm. CRF */
665 fprintf (afile, ";\t.area _DUMMY\n");
666 /* output the area informtion */
667 fprintf (afile, ";\t.area\t%s\n", port->mem.overlay_name); /* MOF */
670 for (sym = setFirstItem (ovrset); sym;
671 sym = setNextItem (ovrset))
674 /* if extern then do nothing */
675 if (IS_EXTERN (sym->etype))
678 /* if allocation required check is needed
679 then check if the symbol really requires
680 allocation only for local variables */
681 if (!IS_AGGREGATE (sym->type) &&
682 !(sym->_isparm && !IS_REGPARM (sym->etype))
683 && !sym->allocreq && sym->level)
686 /* if global variable & not static or extern
687 and addPublics allowed then add it to the public set */
688 if ((sym->_isparm && !IS_REGPARM (sym->etype))
689 && !IS_STATIC (sym->etype))
690 addSetHead (&publics, sym);
692 /* if extern then do nothing or is a function
694 if (IS_FUNC (sym->type))
697 /* print extra debug info if required */
698 if (options.debug || sym->level == 0)
702 if (IS_STATIC (sym->etype))
703 fprintf (afile, "F%s_", moduleName); /* scope is file */
705 fprintf (afile, "G_"); /* scope is global */
708 /* symbol is local */
709 fprintf (afile, "L%s_",
710 (sym->localof ? sym->localof->name : "-null-"));
711 fprintf (afile, "%s_%d_%d", sym->name, sym->level, sym->block);
714 /* if is has an absolute address then generate
715 an equate for this no need to allocate space */
716 if (SPEC_ABSA (sym->etype))
719 if (options.debug || sym->level == 0)
720 fprintf (afile, " == 0x%04x\n", SPEC_ADDR (sym->etype));
722 fprintf (afile, "%s\t=\t0x%04x\n",
724 SPEC_ADDR (sym->etype));
728 if (options.debug || sym->level == 0)
729 fprintf (afile, "==.\n");
732 fprintf (afile, "%s:\n", sym->rname);
733 fprintf (afile, "\t.ds\t0x%04x\n", (unsigned int) getSize (sym->type) & 0xffff);
741 /*-----------------------------------------------------------------*/
742 /* glue - the final glue that hold the whole thing together */
743 /*-----------------------------------------------------------------*/
750 FILE *ovrFile = tempfile();
752 addSetHead(&tmpfileSet,ovrFile);
753 pCodeInitRegisters();
755 if (mainf && IFFUNC_HASBODY(mainf->type)) {
757 pBlock *pb = newpCodeChain(NULL,'X',newpCodeCharP("; Starting pCode block"));
760 /* entry point @ start of CSEG */
761 addpCode2pBlock(pb,newpCodeLabel("__sdcc_program_startup",-1));
762 /* put in the call to main */
763 addpCode2pBlock(pb,newpCode(POC_CALL,newpCodeOp("_main",PO_STR)));
765 if (options.mainreturn) {
767 addpCode2pBlock(pb,newpCodeCharP(";\treturn from main will return to caller\n"));
768 addpCode2pBlock(pb,newpCode(POC_RETURN,NULL));
772 addpCode2pBlock(pb,newpCodeCharP(";\treturn from main will lock up\n"));
773 addpCode2pBlock(pb,newpCode(POC_GOTO,newpCodeOp("$",PO_STR)));
779 /* At this point we've got all the code in the form of pCode structures */
780 /* Now it needs to be rearranged into the order it should be placed in the */
783 movepBlock2Head('P'); // Last
784 movepBlock2Head(code->dbName);
785 movepBlock2Head('X');
786 movepBlock2Head(statsg->dbName); // First
789 /* print the global struct definitions */
795 addSetHead(&tmpfileSet,vFile);
797 /* emit code for the all the variables declared */
799 /* do the overlay segments */
800 pic14emitOverlay(ovrFile);
802 /* PENDING: this isnt the best place but it will do */
803 if (port->general.glue_up_main) {
804 /* create the interrupt vector table */
805 pic14createInterruptVect (vFile);
811 //printCallTree(stderr);
821 /* now put it all together into the assembler file */
822 /* create the assembler file name */
824 if ((noAssemble || options.c1mode) && fullDstFileName)
826 sprintf (buffer, fullDstFileName);
830 sprintf (buffer, dstFileName);
831 strcat (buffer, ".asm");
834 if (!(asmFile = fopen (buffer, "w"))) {
835 werror (E_FILE_OPEN_ERR, buffer);
839 /* initial comments */
840 pic14initialComments (asmFile);
842 /* print module name */
843 fprintf (asmFile, ";\t.module %s\n", moduleName);
845 /* Let the port generate any global directives, etc. */
846 if (port->genAssemblerPreamble)
848 port->genAssemblerPreamble(asmFile);
851 /* print the extern variables in this module */
852 pic14printExterns (asmFile);
854 /* print the global variables in this module */
855 pic14printPublics (asmFile);
857 /* copy the sfr segment */
858 fprintf (asmFile, "%s", iComments2);
859 fprintf (asmFile, "; special function registers\n");
860 fprintf (asmFile, "%s", iComments2);
861 copyFile (asmFile, sfr->oFile);
863 fprintf (asmFile, "%s", iComments2);
864 fprintf (asmFile, "; udata\n");
865 fprintf (asmFile, "%s", iComments2);
866 fprintf (asmFile, "\tudata\n");
867 copyFile (asmFile, data->oFile);
869 /* Put all variables into a cblock */
871 writeUsedRegs(asmFile);
873 /* create the overlay segments */
874 fprintf (asmFile, "%s", iComments2);
875 fprintf (asmFile, "; overlayable items in internal ram \n");
876 fprintf (asmFile, "%s", iComments2);
877 copyFile (asmFile, ovrFile);
881 /* create the stack segment MOF */
882 if (mainf && IFFUNC_HASBODY(mainf->type)) {
883 fprintf (asmFile, "%s", iComments2);
884 fprintf (asmFile, "; Stack segment in internal ram \n");
885 fprintf (asmFile, "%s", iComments2);
886 fprintf (asmFile, ";\t.area\tSSEG\t(DATA)\n"
887 ";__start__stack:\n;\t.ds\t1\n\n");
890 /* create the idata segment */
891 fprintf (asmFile, "%s", iComments2);
892 fprintf (asmFile, "; indirectly addressable internal ram data\n");
893 fprintf (asmFile, "%s", iComments2);
894 copyFile (asmFile, idata->oFile);
896 /* if external stack then reserve space of it */
897 if (mainf && IFFUNC_HASBODY(mainf->type) && options.useXstack ) {
898 fprintf (asmFile, "%s", iComments2);
899 fprintf (asmFile, "; external stack \n");
900 fprintf (asmFile, "%s", iComments2);
901 fprintf (asmFile,";\t.area XSEG (XDATA)\n"); /* MOF */
902 fprintf (asmFile,";\t.ds 256\n");
905 /* copy xtern ram data */
906 fprintf (asmFile, "%s", iComments2);
907 fprintf (asmFile, "; external ram data\n");
908 fprintf (asmFile, "%s", iComments2);
909 copyFile (asmFile, xdata->oFile);
913 /* copy the bit segment */
914 fprintf (asmFile, "%s", iComments2);
915 fprintf (asmFile, "; bit data\n");
916 fprintf (asmFile, "%s", iComments2);
917 copyFile (asmFile, bit->oFile);
919 /* copy the interrupt vector table */
920 if (mainf && IFFUNC_HASBODY(mainf->type)) {
921 copyFile (asmFile, vFile);
923 fprintf (asmFile, "%s", iComments2);
924 fprintf (asmFile, "; interrupt and initialization code\n");
925 fprintf (asmFile, "%s", iComments2);
926 fprintf (asmFile, "code_init\t%s\t0x4\n", CODE_NAME);
928 /* interrupt service routine */
929 fprintf (asmFile, "__sdcc_interrupt:\n");
930 copypCode(asmFile, 'I');
932 /* initialize data memory */
933 fprintf (asmFile,"__sdcc_gsinit_startup:\n");
934 /* FIXME: This is temporary. The idata section should be used. If
935 not, we could add a special feature to the linker. This will
936 work in the mean time. Put all initalized data in main.c */
937 copypCode(asmFile, statsg->dbName);
938 fprintf (asmFile,"\tpagesel _main\n");
939 fprintf (asmFile,"\tgoto _main\n");
944 /* copy global & static initialisations */
945 fprintf (asmFile, "%s", iComments2);
946 fprintf (asmFile, "; global & static initialisations\n");
947 fprintf (asmFile, "%s", iComments2);
948 copypCode(asmFile, statsg->dbName);
953 fprintf (asmFile, "%s", iComments2);
954 fprintf (asmFile, "; code\n");
955 fprintf (asmFile, "%s", iComments2);
956 fprintf (asmFile, "code_%s\t%s\n", moduleName, port->mem.code_name);
959 copypCode(asmFile, 'X');
962 copypCode(asmFile, 'M');
964 /* other functions */
965 copypCode(asmFile, code->dbName);
968 copypCode(asmFile, 'P');
970 fprintf (asmFile,"\tend\n");