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 fprintf (afile, "\tglobal %s\n", sym->rname);
633 fprintf (afile, ";\tglobal %s\n", sym->rname);
637 /*-----------------------------------------------------------------*/
638 /* emitOverlay - will emit code for the overlay stuff */
639 /*-----------------------------------------------------------------*/
641 pic14emitOverlay (FILE * afile)
645 if (!elementsInSet (ovrSetSets))
646 fprintf (afile, "\t%s\n", port->mem.overlay_name);
648 /* for each of the sets in the overlay segment do */
649 for (ovrset = setFirstItem (ovrSetSets); ovrset;
650 ovrset = setNextItem (ovrSetSets))
655 if (elementsInSet (ovrset))
657 /* this dummy area is used to fool the assembler
658 otherwise the assembler will append each of these
659 declarations into one chunk and will not overlay
662 /* I don't think this applies to us. We are using gpasm. CRF */
664 fprintf (afile, ";\t.area _DUMMY\n");
665 /* output the area informtion */
666 fprintf (afile, ";\t.area\t%s\n", port->mem.overlay_name); /* MOF */
669 for (sym = setFirstItem (ovrset); sym;
670 sym = setNextItem (ovrset))
673 /* if extern then do nothing */
674 if (IS_EXTERN (sym->etype))
677 /* if allocation required check is needed
678 then check if the symbol really requires
679 allocation only for local variables */
680 if (!IS_AGGREGATE (sym->type) &&
681 !(sym->_isparm && !IS_REGPARM (sym->etype))
682 && !sym->allocreq && sym->level)
685 /* if global variable & not static or extern
686 and addPublics allowed then add it to the public set */
687 if ((sym->_isparm && !IS_REGPARM (sym->etype))
688 && !IS_STATIC (sym->etype))
689 addSetHead (&publics, sym);
691 /* if extern then do nothing or is a function
693 if (IS_FUNC (sym->type))
696 /* print extra debug info if required */
697 if (options.debug || sym->level == 0)
701 if (IS_STATIC (sym->etype))
702 fprintf (afile, "F%s_", moduleName); /* scope is file */
704 fprintf (afile, "G_"); /* scope is global */
707 /* symbol is local */
708 fprintf (afile, "L%s_",
709 (sym->localof ? sym->localof->name : "-null-"));
710 fprintf (afile, "%s_%d_%d", sym->name, sym->level, sym->block);
713 /* if is has an absolute address then generate
714 an equate for this no need to allocate space */
715 if (SPEC_ABSA (sym->etype))
718 if (options.debug || sym->level == 0)
719 fprintf (afile, " == 0x%04x\n", SPEC_ADDR (sym->etype));
721 fprintf (afile, "%s\t=\t0x%04x\n",
723 SPEC_ADDR (sym->etype));
727 if (options.debug || sym->level == 0)
728 fprintf (afile, "==.\n");
731 fprintf (afile, "%s:\n", sym->rname);
732 fprintf (afile, "\t.ds\t0x%04x\n", (unsigned int) getSize (sym->type) & 0xffff);
740 /*-----------------------------------------------------------------*/
741 /* glue - the final glue that hold the whole thing together */
742 /*-----------------------------------------------------------------*/
749 FILE *ovrFile = tempfile();
751 addSetHead(&tmpfileSet,ovrFile);
752 pCodeInitRegisters();
754 if (mainf && IFFUNC_HASBODY(mainf->type)) {
756 pBlock *pb = newpCodeChain(NULL,'X',newpCodeCharP("; Starting pCode block"));
759 /* entry point @ start of CSEG */
760 addpCode2pBlock(pb,newpCodeLabel("__sdcc_program_startup",-1));
761 /* put in the call to main */
762 addpCode2pBlock(pb,newpCode(POC_CALL,newpCodeOp("_main",PO_STR)));
764 if (options.mainreturn) {
766 addpCode2pBlock(pb,newpCodeCharP(";\treturn from main will return to caller\n"));
767 addpCode2pBlock(pb,newpCode(POC_RETURN,NULL));
771 addpCode2pBlock(pb,newpCodeCharP(";\treturn from main will lock up\n"));
772 addpCode2pBlock(pb,newpCode(POC_GOTO,newpCodeOp("$",PO_STR)));
778 /* At this point we've got all the code in the form of pCode structures */
779 /* Now it needs to be rearranged into the order it should be placed in the */
782 movepBlock2Head('P'); // Last
783 movepBlock2Head(code->dbName);
784 movepBlock2Head('X');
785 movepBlock2Head(statsg->dbName); // First
788 /* print the global struct definitions */
794 addSetHead(&tmpfileSet,vFile);
796 /* emit code for the all the variables declared */
798 /* do the overlay segments */
799 pic14emitOverlay(ovrFile);
801 /* PENDING: this isnt the best place but it will do */
802 if (port->general.glue_up_main) {
803 /* create the interrupt vector table */
804 pic14createInterruptVect (vFile);
810 //printCallTree(stderr);
820 /* now put it all together into the assembler file */
821 /* create the assembler file name */
823 if ((noAssemble || options.c1mode) && fullDstFileName)
825 sprintf (buffer, fullDstFileName);
829 sprintf (buffer, dstFileName);
830 strcat (buffer, ".asm");
833 if (!(asmFile = fopen (buffer, "w"))) {
834 werror (E_FILE_OPEN_ERR, buffer);
838 /* initial comments */
839 pic14initialComments (asmFile);
841 /* print module name */
842 fprintf (asmFile, ";\t.module %s\n", moduleName);
844 /* Let the port generate any global directives, etc. */
845 if (port->genAssemblerPreamble)
847 port->genAssemblerPreamble(asmFile);
850 /* print the extern variables in this module */
851 pic14printExterns (asmFile);
853 /* print the global variables in this module */
854 pic14printPublics (asmFile);
856 /* copy the sfr segment */
857 fprintf (asmFile, "%s", iComments2);
858 fprintf (asmFile, "; special function registers\n");
859 fprintf (asmFile, "%s", iComments2);
860 copyFile (asmFile, sfr->oFile);
862 fprintf (asmFile, "%s", iComments2);
863 fprintf (asmFile, "; udata\n");
864 fprintf (asmFile, "%s", iComments2);
865 fprintf (asmFile, "\tudata\n");
866 copyFile (asmFile, data->oFile);
868 /* Put all variables into a cblock */
870 writeUsedRegs(asmFile);
872 /* create the overlay segments */
873 fprintf (asmFile, "%s", iComments2);
874 fprintf (asmFile, "; overlayable items in internal ram \n");
875 fprintf (asmFile, "%s", iComments2);
876 copyFile (asmFile, ovrFile);
880 /* create the stack segment MOF */
881 if (mainf && IFFUNC_HASBODY(mainf->type)) {
882 fprintf (asmFile, "%s", iComments2);
883 fprintf (asmFile, "; Stack segment in internal ram \n");
884 fprintf (asmFile, "%s", iComments2);
885 fprintf (asmFile, ";\t.area\tSSEG\t(DATA)\n"
886 ";__start__stack:\n;\t.ds\t1\n\n");
889 /* create the idata segment */
890 fprintf (asmFile, "%s", iComments2);
891 fprintf (asmFile, "; indirectly addressable internal ram data\n");
892 fprintf (asmFile, "%s", iComments2);
893 copyFile (asmFile, idata->oFile);
895 /* if external stack then reserve space of it */
896 if (mainf && IFFUNC_HASBODY(mainf->type) && options.useXstack ) {
897 fprintf (asmFile, "%s", iComments2);
898 fprintf (asmFile, "; external stack \n");
899 fprintf (asmFile, "%s", iComments2);
900 fprintf (asmFile,";\t.area XSEG (XDATA)\n"); /* MOF */
901 fprintf (asmFile,";\t.ds 256\n");
904 /* copy xtern ram data */
905 fprintf (asmFile, "%s", iComments2);
906 fprintf (asmFile, "; external ram data\n");
907 fprintf (asmFile, "%s", iComments2);
908 copyFile (asmFile, xdata->oFile);
912 /* copy the bit segment */
913 fprintf (asmFile, "%s", iComments2);
914 fprintf (asmFile, "; bit data\n");
915 fprintf (asmFile, "%s", iComments2);
916 copyFile (asmFile, bit->oFile);
918 /* copy the interrupt vector table */
919 if (mainf && IFFUNC_HASBODY(mainf->type)) {
920 copyFile (asmFile, vFile);
922 fprintf (asmFile, "%s", iComments2);
923 fprintf (asmFile, "; interrupt and initialization code\n");
924 fprintf (asmFile, "%s", iComments2);
925 fprintf (asmFile, "code_init\t%s\t0x4\n", CODE_NAME);
927 /* interrupt service routine */
928 fprintf (asmFile, "__sdcc_interrupt:\n");
929 copypCode(asmFile, 'I');
931 /* initialize data memory */
932 fprintf (asmFile,"__sdcc_gsinit_startup:\n");
933 /* FIXME: This is temporary. The idata section should be used. If
934 not, we could add a special feature to the linker. This will
935 work in the mean time. Put all initalized data in main.c */
936 copypCode(asmFile, statsg->dbName);
937 fprintf (asmFile,"\tpagesel _main\n");
938 fprintf (asmFile,"\tgoto _main\n");
943 /* copy global & static initialisations */
944 fprintf (asmFile, "%s", iComments2);
945 fprintf (asmFile, "; global & static initialisations\n");
946 fprintf (asmFile, "%s", iComments2);
947 copypCode(asmFile, statsg->dbName);
952 fprintf (asmFile, "%s", iComments2);
953 fprintf (asmFile, "; code\n");
954 fprintf (asmFile, "%s", iComments2);
955 fprintf (asmFile, "code_%s\t%s\n", moduleName, port->mem.code_name);
958 copypCode(asmFile, 'X');
961 copypCode(asmFile, 'M');
963 /* other functions */
964 copypCode(asmFile, code->dbName);
967 copypCode(asmFile, 'P');
969 fprintf (asmFile,"\tend\n");