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)
110 fprintf (map->oFile, ";\t.area\t%s\n", map->sname);
112 /* print the area name */
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<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 and interrupt vectors \n");
576 fprintf (vFile, "%s", iComments2);
577 fprintf (vFile, "STARTUP\t%s\n", CODE_NAME);
578 fprintf (vFile, "\tgoto\t__sdcc_gsinit_startup\n");
579 fprintf (vFile, "\tnop\n");
580 fprintf (vFile, "\tnop\n");
581 fprintf (vFile, "\tgoto\t__sdcc_interrupt\n");
586 /*-----------------------------------------------------------------*/
587 /* initialComments - puts in some initial comments */
588 /*-----------------------------------------------------------------*/
590 pic14initialComments (FILE * afile)
592 initialComments (afile);
593 fprintf (afile, "; PIC port for the 14-bit core\n");
594 fprintf (afile, iComments2);
598 /*-----------------------------------------------------------------*/
599 /* printExterns - generates extern for external variables */
600 /*-----------------------------------------------------------------*/
602 pic14printExterns (FILE * afile)
606 fprintf (afile, "%s", iComments2);
607 fprintf (afile, "; extern variables in this module\n");
608 fprintf (afile, "%s", iComments2);
610 for (sym = setFirstItem (externs); sym;
611 sym = setNextItem (externs))
612 fprintf (afile, "\textern %s\n", sym->rname);
615 /*-----------------------------------------------------------------*/
616 /* printPublics - generates .global for publics */
617 /*-----------------------------------------------------------------*/
619 pic14printPublics (FILE * afile)
623 fprintf (afile, "%s", iComments2);
624 fprintf (afile, "; publics variables in this module\n");
625 fprintf (afile, "%s", iComments2);
627 for (sym = setFirstItem (publics); sym;
628 sym = setNextItem (publics)) {
629 if(!IS_BITFIELD(sym->type) && ((IS_FUNC(sym->type) || sym->allocreq)))
630 fprintf (afile, "\tglobal %s\n", sym->rname);
632 fprintf (afile, ";\tglobal %s\n", sym->rname);
636 /*-----------------------------------------------------------------*/
637 /* emitOverlay - will emit code for the overlay stuff */
638 /*-----------------------------------------------------------------*/
640 pic14emitOverlay (FILE * afile)
644 if (!elementsInSet (ovrSetSets))
645 fprintf (afile, "\t%s\n", port->mem.overlay_name);
647 /* for each of the sets in the overlay segment do */
648 for (ovrset = setFirstItem (ovrSetSets); ovrset;
649 ovrset = setNextItem (ovrSetSets))
654 if (elementsInSet (ovrset))
656 /* this dummy area is used to fool the assembler
657 otherwise the assembler will append each of these
658 declarations into one chunk and will not overlay
661 /* I don't think this applies to us. We are using gpasm. CRF */
663 fprintf (afile, ";\t.area _DUMMY\n");
664 /* output the area informtion */
665 fprintf (afile, ";\t.area\t%s\n", port->mem.overlay_name); /* MOF */
668 for (sym = setFirstItem (ovrset); sym;
669 sym = setNextItem (ovrset))
672 /* if extern then do nothing */
673 if (IS_EXTERN (sym->etype))
676 /* if allocation required check is needed
677 then check if the symbol really requires
678 allocation only for local variables */
679 if (!IS_AGGREGATE (sym->type) &&
680 !(sym->_isparm && !IS_REGPARM (sym->etype))
681 && !sym->allocreq && sym->level)
684 /* if global variable & not static or extern
685 and addPublics allowed then add it to the public set */
686 if ((sym->_isparm && !IS_REGPARM (sym->etype))
687 && !IS_STATIC (sym->etype))
688 addSetHead (&publics, sym);
690 /* if extern then do nothing or is a function
692 if (IS_FUNC (sym->type))
695 /* print extra debug info if required */
696 if (options.debug || sym->level == 0)
700 if (IS_STATIC (sym->etype))
701 fprintf (afile, "F%s_", moduleName); /* scope is file */
703 fprintf (afile, "G_"); /* scope is global */
706 /* symbol is local */
707 fprintf (afile, "L%s_",
708 (sym->localof ? sym->localof->name : "-null-"));
709 fprintf (afile, "%s_%d_%d", sym->name, sym->level, sym->block);
712 /* if is has an absolute address then generate
713 an equate for this no need to allocate space */
714 if (SPEC_ABSA (sym->etype))
717 if (options.debug || sym->level == 0)
718 fprintf (afile, " == 0x%04x\n", SPEC_ADDR (sym->etype));
720 fprintf (afile, "%s\t=\t0x%04x\n",
722 SPEC_ADDR (sym->etype));
726 if (options.debug || sym->level == 0)
727 fprintf (afile, "==.\n");
730 fprintf (afile, "%s:\n", sym->rname);
731 fprintf (afile, "\t.ds\t0x%04x\n", (unsigned int) getSize (sym->type) & 0xffff);
739 /*-----------------------------------------------------------------*/
740 /* glue - the final glue that hold the whole thing together */
741 /*-----------------------------------------------------------------*/
748 FILE *ovrFile = tempfile();
750 addSetHead(&tmpfileSet,ovrFile);
751 pCodeInitRegisters();
753 if (mainf && IFFUNC_HASBODY(mainf->type)) {
755 pBlock *pb = newpCodeChain(NULL,'X',newpCodeCharP("; Starting pCode block"));
758 /* entry point @ start of CSEG */
759 addpCode2pBlock(pb,newpCodeLabel("__sdcc_program_startup",-1));
760 /* put in the call to main */
761 addpCode2pBlock(pb,newpCode(POC_CALL,newpCodeOp("_main",PO_STR)));
763 if (options.mainreturn) {
765 addpCode2pBlock(pb,newpCodeCharP(";\treturn from main will return to caller\n"));
766 addpCode2pBlock(pb,newpCode(POC_RETURN,NULL));
770 addpCode2pBlock(pb,newpCodeCharP(";\treturn from main will lock up\n"));
771 addpCode2pBlock(pb,newpCode(POC_GOTO,newpCodeOp("$",PO_STR)));
777 /* At this point we've got all the code in the form of pCode structures */
778 /* Now it needs to be rearranged into the order it should be placed in the */
781 movepBlock2Head('P'); // Last
782 movepBlock2Head(code->dbName);
783 movepBlock2Head('X');
784 movepBlock2Head(statsg->dbName); // First
787 /* print the global struct definitions */
793 addSetHead(&tmpfileSet,vFile);
795 /* emit code for the all the variables declared */
797 /* do the overlay segments */
798 pic14emitOverlay(ovrFile);
800 /* PENDING: this isnt the best place but it will do */
801 if (port->general.glue_up_main) {
802 /* create the interrupt vector table */
803 pic14createInterruptVect (vFile);
809 //printCallTree(stderr);
819 /* now put it all together into the assembler file */
820 /* create the assembler file name */
822 if ((noAssemble || options.c1mode) && fullDstFileName)
824 sprintf (buffer, fullDstFileName);
828 sprintf (buffer, dstFileName);
829 strcat (buffer, ".asm");
832 if (!(asmFile = fopen (buffer, "w"))) {
833 werror (E_FILE_OPEN_ERR, buffer);
837 /* initial comments */
838 pic14initialComments (asmFile);
840 /* print module name */
841 fprintf (asmFile, ";\t.module %s\n", moduleName);
843 /* Let the port generate any global directives, etc. */
844 if (port->genAssemblerPreamble)
846 port->genAssemblerPreamble(asmFile);
849 /* print the extern variables in this module */
850 pic14printExterns (asmFile);
852 /* print the global variables in this module */
853 pic14printPublics (asmFile);
855 /* copy the sfr segment */
856 fprintf (asmFile, "%s", iComments2);
857 fprintf (asmFile, "; special function registers\n");
858 fprintf (asmFile, "%s", iComments2);
859 copyFile (asmFile, sfr->oFile);
861 fprintf (asmFile, "%s", iComments2);
862 fprintf (asmFile, "; udata\n");
863 fprintf (asmFile, "%s", iComments2);
864 fprintf (asmFile, "\tudata\n");
865 copyFile (asmFile, data->oFile);
867 /* Put all variables into a cblock */
869 writeUsedRegs(asmFile);
871 /* create the overlay segments */
872 fprintf (asmFile, "%s", iComments2);
873 fprintf (asmFile, "; overlayable items in internal ram \n");
874 fprintf (asmFile, "%s", iComments2);
875 copyFile (asmFile, ovrFile);
879 /* create the stack segment MOF */
880 if (mainf && IFFUNC_HASBODY(mainf->type)) {
881 fprintf (asmFile, "%s", iComments2);
882 fprintf (asmFile, "; Stack segment in internal ram \n");
883 fprintf (asmFile, "%s", iComments2);
884 fprintf (asmFile, ";\t.area\tSSEG\t(DATA)\n"
885 ";__start__stack:\n;\t.ds\t1\n\n");
888 /* create the idata segment */
889 fprintf (asmFile, "%s", iComments2);
890 fprintf (asmFile, "; indirectly addressable internal ram data\n");
891 fprintf (asmFile, "%s", iComments2);
892 copyFile (asmFile, idata->oFile);
894 /* if external stack then reserve space of it */
895 if (mainf && IFFUNC_HASBODY(mainf->type) && options.useXstack ) {
896 fprintf (asmFile, "%s", iComments2);
897 fprintf (asmFile, "; external stack \n");
898 fprintf (asmFile, "%s", iComments2);
899 fprintf (asmFile,";\t.area XSEG (XDATA)\n"); /* MOF */
900 fprintf (asmFile,";\t.ds 256\n");
903 /* copy xtern ram data */
904 fprintf (asmFile, "%s", iComments2);
905 fprintf (asmFile, "; external ram data\n");
906 fprintf (asmFile, "%s", iComments2);
907 copyFile (asmFile, xdata->oFile);
911 /* copy the bit segment */
912 fprintf (asmFile, "%s", iComments2);
913 fprintf (asmFile, "; bit data\n");
914 fprintf (asmFile, "%s", iComments2);
915 copyFile (asmFile, bit->oFile);
917 /* copy the interrupt vector table */
918 if (mainf && IFFUNC_HASBODY(mainf->type)) {
919 copyFile (asmFile, vFile);
921 fprintf (asmFile, "%s", iComments2);
922 fprintf (asmFile, "; initialization and interrupt code \n");
923 fprintf (asmFile, "%s", iComments2);
925 /* initialize data memory */
926 fprintf (asmFile, "code_init\t%s\t0x10\n", CODE_NAME);
927 fprintf (asmFile,"__sdcc_gsinit_startup:\n");
928 /* FIXME: This is temporary. The idata section should be used. If
929 not, we could add a special feature to the linker. This will
930 work in the mean time. Put all initalized data in main.c */
931 copypCode(asmFile, statsg->dbName);
932 fprintf (asmFile,"\tpagesel _main\n");
933 fprintf (asmFile,"\tgoto _main\n");
935 /* interrupt service routine */
936 fprintf (asmFile, "__sdcc_interrupt:\n");
937 copypCode(asmFile, 'I');
938 fprintf (asmFile,"\tgoto $\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");