1 /*-------------------------------------------------------------------------
3 glue.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);
44 extern unsigned maxInterrupts;
45 extern int maxRegBank;
47 extern char *VersionString;
48 extern FILE *codeOutFile;
49 extern set *tmpfileSet;
50 extern set *tmpfileNameSet;
51 extern char *iComments1;
52 extern char *iComments2;
53 //extern void emitStaticSeg (memmap * map);
55 extern DEFSETFUNC (closeTmpFiles);
56 extern DEFSETFUNC (rmTmpFiles);
58 extern void pic16_AnalyzeBanking (void);
59 extern void copyFile (FILE * dest, FILE * src);
60 extern void pic16_InlinepCode(void);
61 extern void pic16_writeUsedRegs(FILE *);
63 extern void initialComments (FILE * afile);
64 extern void printPublics (FILE * afile);
66 extern void printChar (FILE * ofile, char *s, int plen);
67 void pic16_pCodeInitRegisters(void);
69 /*-----------------------------------------------------------------*/
70 /* aopLiteral - string from a literal value */
71 /*-----------------------------------------------------------------*/
72 int pic16aopLiteral (value *val, int offset)
79 /* if it is a float then it gets tricky */
80 /* otherwise it is fairly simple */
81 if (!IS_FLOAT(val->type)) {
82 unsigned long v = (unsigned long) floatFromVal(val);
84 return ( (v >> (offset * 8)) & 0xff);
87 /* it is type float */
88 fl.f = (float) floatFromVal(val);
89 #ifdef WORDS_BIGENDIAN
90 return fl.c[3-offset];
98 /*-----------------------------------------------------------------*/
99 /* emitRegularMap - emit code for maps with no special cases */
100 /*-----------------------------------------------------------------*/
102 pic16emitRegularMap (memmap * map, bool addPublics, bool arFlag)
105 int i, size, bitvars = 0;;
108 fprintf (map->oFile, ";\t.area\t%s\n", map->sname);
110 /* print the area name */
111 for (sym = setFirstItem (map->syms); sym;
112 sym = setNextItem (map->syms))
115 /* if extern then do nothing */
116 if (IS_EXTERN (sym->etype))
119 /* if allocation required check is needed
120 then check if the symbol really requires
121 allocation only for local variables */
122 if (arFlag && !IS_AGGREGATE (sym->type) &&
123 !(sym->_isparm && !IS_REGPARM (sym->etype)) &&
124 !sym->allocreq && sym->level)
127 /* if global variable & not static or extern
128 and addPublics allowed then add it to the public set */
129 if ((sym->level == 0 ||
130 (sym->_isparm && !IS_REGPARM (sym->etype))) &&
132 !IS_STATIC (sym->etype))
133 addSetHead (&publics, sym);
135 /* if extern then do nothing or is a function
137 if (IS_FUNC (sym->type))
140 /* print extra debug info if required */
141 if (options.debug || sym->level == 0)
144 cdbSymbol (sym, cdbFile, FALSE, FALSE);
146 if (!sym->level) /* global */
147 if (IS_STATIC (sym->etype))
148 fprintf (map->oFile, "F%s_", moduleName); /* scope is file */
150 fprintf (map->oFile, "G_"); /* scope is global */
152 /* symbol is local */
153 fprintf (map->oFile, "L%s_", (sym->localof ? sym->localof->name : "-null-"));
154 fprintf (map->oFile, "%s_%d_%d", sym->name, sym->level, sym->block);
158 /* if is has an absolute address then generate
159 an equate for this no need to allocate space */
160 if (SPEC_ABSA (sym->etype))
162 //if (options.debug || sym->level == 0)
163 //fprintf (map->oFile,"; == 0x%04x\n",SPEC_ADDR (sym->etype));
165 fprintf (map->oFile, "%s\tEQU\t0x%04x\n",
167 SPEC_ADDR (sym->etype));
173 /* If this is a bit variable, then allocate storage after 8 bits have been declared */
174 /* unlike the 8051, the pic does not have a separate bit area. So we emulate bit ram */
175 /* by grouping the bits together into groups of 8 and storing them in the normal ram. */
176 if (IS_BITVAR (sym->etype))
182 fprintf (map->oFile, "\t%s\n", sym->rname);
183 if ((size = (unsigned int) getSize (sym->type) & 0xffff) > 1)
185 for (i = 1; i < size; i++)
186 fprintf (map->oFile, "\t%s_%d\n", sym->rname, i);
189 //fprintf (map->oFile, "\t.ds\t0x%04x\n", (unsigned int)getSize (sym->type) & 0xffff);
192 /* if it has a initial value then do it only if
193 it is a global variable */
194 if (sym->ival && sym->level == 0) {
197 if (IS_AGGREGATE (sym->type))
198 ival = initAggregates (sym, sym->ival, NULL);
200 ival = newNode ('=', newAst_VALUE(symbolVal (sym)),
201 decorateType (resolveSymbols (list2expr (sym->ival))));
202 codeOutFile = statsg->oFile;
204 eBBlockFromiCode (iCodeFromAst (ival));
211 /*-----------------------------------------------------------------*/
212 /* printIvalType - generates ival for int/char */
213 /*-----------------------------------------------------------------*/
215 printIvalType (symbol *sym, sym_link * type, initList * ilist, pBlock *pb)
220 //fprintf(stderr, "%s\n",__FUNCTION__);
222 /* if initList is deep */
223 if (ilist->type == INIT_DEEP)
224 ilist = ilist->init.deep;
226 if (!IS_AGGREGATE(sym->type) && getNelements(type, ilist)>1) {
227 werror (W_EXCESS_INITIALIZERS, "scalar", sym->name, sym->lineDef);
230 if (!(val = list2val (ilist))) {
231 // assuming a warning has been thrown
235 if (val->type != type) {
236 val = valCastLiteral(type, floatFromVal(val));
240 ulval = (unsigned long) floatFromVal (val);
244 switch (getSize (type)) {
246 pic16_addpCode2pBlock(pb,pic16_newpCode(POC_RETLW,pic16_newpCodeOpLit(BYTE_IN_LONG(ulval,0))));
250 pic16_addpCode2pBlock(pb,pic16_newpCode(POC_RETLW,pic16_newpCodeOpLit(BYTE_IN_LONG(ulval,0))));
251 pic16_addpCode2pBlock(pb,pic16_newpCode(POC_RETLW,pic16_newpCodeOpLit(BYTE_IN_LONG(ulval,1))));
255 pic16_addpCode2pBlock(pb,pic16_newpCode(POC_RETLW,pic16_newpCodeOpLit(BYTE_IN_LONG(ulval,0))));
256 pic16_addpCode2pBlock(pb,pic16_newpCode(POC_RETLW,pic16_newpCodeOpLit(BYTE_IN_LONG(ulval,1))));
257 pic16_addpCode2pBlock(pb,pic16_newpCode(POC_RETLW,pic16_newpCodeOpLit(BYTE_IN_LONG(ulval,2))));
258 pic16_addpCode2pBlock(pb,pic16_newpCode(POC_RETLW,pic16_newpCodeOpLit(BYTE_IN_LONG(ulval,3))));
263 /*-----------------------------------------------------------------*/
264 /* printIvalChar - generates initital value for character array */
265 /*-----------------------------------------------------------------*/
267 printIvalChar (sym_link * type, initList * ilist, pBlock *pb, char *s)
275 fprintf(stderr, "%s\n",__FUNCTION__);
279 val = list2val (ilist);
280 /* if the value is a character string */
281 if (IS_ARRAY (val->type) && IS_CHAR (val->etype))
283 if (!DCL_ELEM (type))
284 DCL_ELEM (type) = strlen (SPEC_CVAL (val->etype).v_char) + 1;
286 //printChar (oFile, SPEC_CVAL (val->etype).v_char, DCL_ELEM (type));
287 //fprintf(stderr, "%s omitting call to printChar\n",__FUNCTION__);
288 pic16_addpCode2pBlock(pb,pic16_newpCodeCharP(";omitting call to printChar"));
290 if ((remain = (DCL_ELEM (type) - strlen (SPEC_CVAL (val->etype).v_char) - 1)) > 0)
292 //tfprintf (oFile, "\t!db !constbyte\n", 0);
293 pic16_addpCode2pBlock(pb,pic16_newpCode(POC_RETLW,pic16_newpCodeOpLit(0)));
300 //printChar (oFile, s, strlen (s) + 1);
302 for(remain=0; remain<strlen(s); remain++) {
303 pic16_addpCode2pBlock(pb,pic16_newpCode(POC_RETLW,pic16_newpCodeOpLit(s[remain])));
304 //fprintf(stderr,"0x%02x ",s[remain]);
306 //fprintf(stderr,"\n");
311 /*-----------------------------------------------------------------*/
312 /* printIvalArray - generates code for array initialization */
313 /*-----------------------------------------------------------------*/
315 printIvalArray (symbol * sym, sym_link * type, initList * ilist,
319 int lcnt = 0, size = 0;
324 /* take care of the special case */
325 /* array of characters can be init */
327 if (IS_CHAR (type->next)) {
328 //fprintf(stderr,"%s:%d - is_char\n",__FUNCTION__,__LINE__);
329 if (!IS_LITERAL(list2val(ilist)->etype)) {
330 werror (W_INIT_WRONG);
333 if (printIvalChar (type,
334 (ilist->type == INIT_DEEP ? ilist->init.deep : ilist),
335 pb, SPEC_CVAL (sym->etype).v_char))
338 /* not the special case */
339 if (ilist->type != INIT_DEEP)
341 werror (E_INIT_STRUCT, sym->name);
345 iloop = ilist->init.deep;
346 lcnt = DCL_ELEM (type);
350 //fprintf(stderr,"%s:%d - is_char\n",__FUNCTION__,__LINE__);
352 printIval (sym, type->next, iloop, pb);
353 iloop = (iloop ? iloop->next : NULL);
356 /* if not array limits given & we */
357 /* are out of initialisers then */
358 if (!DCL_ELEM (type) && !iloop)
361 /* no of elements given and we */
362 /* have generated for all of them */
364 /* if initializers left */
366 werror (W_EXCESS_INITIALIZERS, "array", sym->name, sym->lineDef);
372 /* if we have not been given a size */
373 if (!DCL_ELEM (type))
374 DCL_ELEM (type) = size;
379 /*-----------------------------------------------------------------*/
380 /* printIval - generates code for initial value */
381 /*-----------------------------------------------------------------*/
383 printIval (symbol * sym, sym_link * type, initList * ilist, pBlock *pb)
388 /* if structure then */
389 if (IS_STRUCT (type))
391 //fprintf(stderr,"%s struct\n",__FUNCTION__);
392 //printIvalStruct (sym, type, ilist, oFile);
396 /* if this is a pointer */
399 //fprintf(stderr,"%s pointer\n",__FUNCTION__);
400 //printIvalPtr (sym, type, ilist, oFile);
404 /* if this is an array */
407 //fprintf(stderr,"%s array\n",__FUNCTION__);
408 printIvalArray (sym, type, ilist, pb);
412 /* if type is SPECIFIER */
415 //fprintf(stderr,"%s spec\n",__FUNCTION__);
416 printIvalType (sym, type, ilist, pb);
421 extern void pic16_pCodeConstString(char *name, char *value);
422 /*-----------------------------------------------------------------*/
423 /* emitStaticSeg - emitcode for the static segment */
424 /*-----------------------------------------------------------------*/
426 pic16emitStaticSeg (memmap * map)
430 fprintf (map->oFile, ";\t.area\t%s\n", map->sname);
432 //fprintf(stderr, "%s\n",__FUNCTION__);
434 /* for all variables in this segment do */
435 for (sym = setFirstItem (map->syms); sym;
436 sym = setNextItem (map->syms))
438 /* if it is "extern" then do nothing */
439 if (IS_EXTERN (sym->etype))
442 /* if it is not static add it to the public
444 if (!IS_STATIC (sym->etype))
445 addSetHead (&publics, sym);
448 /* print extra debug info if required */
449 if (options.debug || sym->level == 0)
451 /* NOTE to me - cdbFile may be null in which case,
452 * the sym name will be printed to stdout. oh well */
454 cdbSymbol (sym, cdbFile, FALSE, FALSE);
458 if (IS_STATIC (sym->etype))
459 fprintf (code->oFile, "F%s_", moduleName); /* scope is file */
461 fprintf (code->oFile, "G_"); /* scope is global */
464 /* symbol is local */
465 fprintf (code->oFile, "L%s_",
466 (sym->localof ? sym->localof->name : "-null-"));
467 fprintf (code->oFile, "%s_%d_%d", sym->name, sym->level, sym->block);
472 /* if it has an absolute address */
473 if (SPEC_ABSA (sym->etype))
475 if (options.debug || sym->level == 0)
476 fprintf (code->oFile, " == 0x%04x\n", SPEC_ADDR (sym->etype));
478 fprintf (code->oFile, "%s\t=\t0x%04x\n",
480 SPEC_ADDR (sym->etype));
484 if (options.debug || sym->level == 0)
485 fprintf (code->oFile, " == .\n");
487 /* if it has an initial value */
492 fprintf (code->oFile, "%s:\n", sym->rname);
494 resolveIvalSym (sym->ival);
495 //printIval (sym, sym->type, sym->ival, code->oFile);
496 pb = pic16_newpCodeChain(NULL, 'P',pic16_newpCodeCharP("; Starting pCode block for Ival"));
498 pic16_addpCode2pBlock(pb,pic16_newpCodeLabel(sym->rname,-1));
500 printIval (sym, sym->type, sym->ival, pb);
507 fprintf (code->oFile, "%s:\n", sym->rname);
508 /* special case for character strings */
509 if (IS_ARRAY (sym->type) && IS_CHAR (sym->type->next) &&
510 SPEC_CVAL (sym->etype).v_char)
511 pic16_pCodeConstString(sym->rname , SPEC_CVAL (sym->etype).v_char);
512 /*printChar (code->oFile,
513 SPEC_CVAL (sym->etype).v_char,
514 strlen (SPEC_CVAL (sym->etype).v_char) + 1);*/
516 fprintf (code->oFile, "\t.ds\t0x%04x\n", (unsigned int) getSize (sym->type) & 0xffff);
524 /*-----------------------------------------------------------------*/
525 /* emitMaps - emits the code for the data portion the code */
526 /*-----------------------------------------------------------------*/
530 /* no special considerations for the following
531 data, idata & bit & xdata */
532 pic16emitRegularMap (data, TRUE, TRUE);
533 pic16emitRegularMap (idata, TRUE, TRUE);
534 pic16emitRegularMap (bit, TRUE, FALSE);
535 pic16emitRegularMap (xdata, TRUE, TRUE);
536 pic16emitRegularMap (sfr, FALSE, FALSE);
537 pic16emitRegularMap (sfrbit, FALSE, FALSE);
538 pic16emitRegularMap (code, TRUE, FALSE);
539 pic16emitStaticSeg (statsg);
542 /*-----------------------------------------------------------------*/
543 /* createInterruptVect - creates the interrupt vector */
544 /*-----------------------------------------------------------------*/
546 pic16createInterruptVect (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)
570 * update started by Vangelis Rokas on 19-Jun-2003
571 * all fprintf() calls are prefixed with ';' so they seem
572 * as comments to the assembler. I (VR) removed them */
574 // fprintf (vFile, "\t.area\t%s\n", CODE_NAME);
575 fprintf(vFile, "\tcode\t0x0000\n");
576 fprintf (vFile, "__interrupt_vect:\n");
579 if (!port->genIVT || !(port->genIVT (vFile, interrupts, maxInterrupts)))
581 /* "generic" interrupt table header (if port doesn't specify one).
583 * Look suspiciously like 8051 code to me...
586 fprintf (vFile, ";\tljmp\t__sdcc_gsinit_startup\n");
589 /* now for the other interrupts */
590 for (; i < maxInterrupts; i++)
593 fprintf (vFile, ";\tljmp\t%s\n;\t.ds\t5\n", interrupts[i]->rname);
595 fprintf (vFile, ";\treti\n;\t.ds\t7\n");
601 /*-----------------------------------------------------------------*/
602 /* initialComments - puts in some initial comments */
603 /*-----------------------------------------------------------------*/
605 pic16initialComments (FILE * afile)
607 initialComments (afile);
608 fprintf (afile, "; PIC port for the 16-bit core\n");
609 fprintf (afile, iComments2);
613 /*-----------------------------------------------------------------*/
614 /* printPublics - generates .global for publics */
615 /*-----------------------------------------------------------------*/
617 pic16printPublics (FILE * afile)
621 fprintf (afile, "%s", iComments2);
622 fprintf (afile, "; publics variables in this module\n");
623 fprintf (afile, "%s", iComments2);
625 for (sym = setFirstItem (publics); sym;
626 sym = setNextItem (publics))
627 fprintf (afile, ";\t.globl %s\n", sym->rname);
632 /*-----------------------------------------------------------------*/
633 /* emitOverlay - will emit code for the overlay stuff */
634 /*-----------------------------------------------------------------*/
636 pic16emitOverlay (FILE * afile)
640 if (!elementsInSet (ovrSetSets))
641 fprintf (afile, ";\t.area\t%s\n", port->mem.overlay_name);
643 /* for each of the sets in the overlay segment do */
644 for (ovrset = setFirstItem (ovrSetSets); ovrset;
645 ovrset = setNextItem (ovrSetSets))
650 if (elementsInSet (ovrset))
652 /* this dummy area is used to fool the assembler
653 otherwise the assembler will append each of these
654 declarations into one chunk and will not overlay
656 fprintf (afile, ";\t.area _DUMMY\n");
657 /* output the area informtion */
658 fprintf (afile, ";\t.area\t%s\n", port->mem.overlay_name); /* MOF */
661 for (sym = setFirstItem (ovrset); sym;
662 sym = setNextItem (ovrset))
665 /* if extern then do nothing */
666 if (IS_EXTERN (sym->etype))
669 /* if allocation required check is needed
670 then check if the symbol really requires
671 allocation only for local variables */
672 if (!IS_AGGREGATE (sym->type) &&
673 !(sym->_isparm && !IS_REGPARM (sym->etype))
674 && !sym->allocreq && sym->level)
677 /* if global variable & not static or extern
678 and addPublics allowed then add it to the public set */
679 if ((sym->_isparm && !IS_REGPARM (sym->etype))
680 && !IS_STATIC (sym->etype))
681 addSetHead (&publics, sym);
683 /* if extern then do nothing or is a function
685 if (IS_FUNC (sym->type))
689 /* print extra debug info if required */
690 if (options.debug || sym->level == 0)
693 cdbSymbol (sym, cdbFile, FALSE, FALSE);
697 if (IS_STATIC (sym->etype))
698 fprintf (afile, "F%s_", moduleName); /* scope is file */
700 fprintf (afile, "G_"); /* scope is global */
703 /* symbol is local */
704 fprintf (afile, "L%s_",
705 (sym->localof ? sym->localof->name : "-null-"));
706 fprintf (afile, "%s_%d_%d", sym->name, sym->level, sym->block);
710 /* if is has an absolute address then generate
711 an equate for this no need to allocate space */
712 if (SPEC_ABSA (sym->etype))
715 if (options.debug || sym->level == 0)
716 fprintf (afile, " == 0x%04x\n", SPEC_ADDR (sym->etype));
718 fprintf (afile, "%s\t=\t0x%04x\n",
720 SPEC_ADDR (sym->etype));
724 if (options.debug || sym->level == 0)
725 fprintf (afile, "==.\n");
728 fprintf (afile, "%s:\n", sym->rname);
729 fprintf (afile, "\t.ds\t0x%04x\n", (unsigned int) getSize (sym->type) & 0xffff);
737 /*-----------------------------------------------------------------*/
738 /* glue - the final glue that hold the whole thing together */
739 /*-----------------------------------------------------------------*/
746 FILE *ovrFile = tempfile();
748 addSetHead(&tmpfileSet,ovrFile);
749 pic16_pCodeInitRegisters();
751 if (mainf && IFFUNC_HASBODY(mainf->type)) {
753 pBlock *pb = pic16_newpCodeChain(NULL,'X',pic16_newpCodeCharP("; Starting pCode block"));
756 /* entry point @ start of CSEG */
757 pic16_addpCode2pBlock(pb,pic16_newpCodeLabel("__sdcc_program_startup",-1));
758 /* put in the call to main */
759 pic16_addpCode2pBlock(pb,pic16_newpCode(POC_CALL,pic16_newpCodeOp("_main",PO_STR)));
761 if (options.mainreturn) {
763 pic16_addpCode2pBlock(pb,pic16_newpCodeCharP(";\treturn from main will return to caller\n"));
764 pic16_addpCode2pBlock(pb,pic16_newpCode(POC_RETURN,NULL));
768 pic16_addpCode2pBlock(pb,pic16_newpCodeCharP(";\treturn from main will lock up\n"));
769 pic16_addpCode2pBlock(pb,pic16_newpCode(POC_GOTO,pic16_newpCodeOp("$",PO_STR)));
775 /* At this point we've got all the code in the form of pCode structures */
776 /* Now it needs to be rearranged into the order it should be placed in the */
779 pic16_movepBlock2Head('P'); // Last
780 pic16_movepBlock2Head(code->dbName);
781 pic16_movepBlock2Head('X');
782 pic16_movepBlock2Head(statsg->dbName); // First
785 /* print the global struct definitions */
787 cdbStructBlock (0); //,cdbFile);
790 /* PENDING: this isnt the best place but it will do */
791 if (port->general.glue_up_main) {
792 /* create the interrupt vector table */
793 pic16createInterruptVect (vFile);
796 addSetHead(&tmpfileSet,vFile);
798 /* emit code for the all the variables declared */
800 /* do the overlay segments */
801 pic16emitOverlay(ovrFile);
804 pic16_AnalyzepCode('*');
807 //pic16_printCallTree(stderr);
812 pic16_AnalyzepCode('*');
817 /* now put it all together into the assembler file */
818 /* create the assembler file name */
820 if ((noAssemble || options.c1mode) && fullDstFileName)
822 sprintf (buffer, fullDstFileName);
826 sprintf (buffer, dstFileName);
827 strcat (buffer, ".asm");
830 if (!(asmFile = fopen (buffer, "w"))) {
831 werror (E_FILE_OPEN_ERR, buffer);
835 /* initial comments */
836 pic16initialComments (asmFile);
838 /* print module name */
839 fprintf (asmFile, ";\t.module %s\n", moduleName);
841 /* Let the port generate any global directives, etc. */
842 if (port->genAssemblerPreamble)
844 port->genAssemblerPreamble(asmFile);
847 /* print the global variables in this module */
848 pic16printPublics (asmFile);
851 /* copy the sfr segment */
852 fprintf (asmFile, "%s", iComments2);
853 fprintf (asmFile, "; special function registers\n");
854 fprintf (asmFile, "%s", iComments2);
855 copyFile (asmFile, sfr->oFile);
858 /* Put all variables into a cblock */
859 pic16_AnalyzeBanking();
860 pic16_writeUsedRegs(asmFile);
862 /* create the overlay segments */
863 fprintf (asmFile, "%s", iComments2);
864 fprintf (asmFile, "; overlayable items in internal ram \n");
865 fprintf (asmFile, "%s", iComments2);
866 copyFile (asmFile, ovrFile);
868 /* create the stack segment MOF */
869 if (mainf && IFFUNC_HASBODY(mainf->type)) {
870 fprintf (asmFile, "%s", iComments2);
871 fprintf (asmFile, "; Stack segment in internal ram \n");
872 fprintf (asmFile, "%s", iComments2);
873 fprintf (asmFile, ";\t.area\tSSEG\t(DATA)\n"
874 ";__start__stack:\n;\t.ds\t1\n\n");
877 /* create the idata segment */
878 fprintf (asmFile, "%s", iComments2);
879 fprintf (asmFile, "; indirectly addressable internal ram data\n");
880 fprintf (asmFile, "%s", iComments2);
881 copyFile (asmFile, idata->oFile);
883 /* if external stack then reserve space of it */
884 if (mainf && IFFUNC_HASBODY(mainf->type) && options.useXstack ) {
885 fprintf (asmFile, "%s", iComments2);
886 fprintf (asmFile, "; external stack \n");
887 fprintf (asmFile, "%s", iComments2);
888 fprintf (asmFile,";\t.area XSEG (XDATA)\n"); /* MOF */
889 fprintf (asmFile,";\t.ds 256\n");
893 /* copy xtern ram data */
894 fprintf (asmFile, "%s", iComments2);
895 fprintf (asmFile, "; external ram data\n");
896 fprintf (asmFile, "%s", iComments2);
897 copyFile (asmFile, xdata->oFile);
900 /* copy the bit segment */
901 fprintf (asmFile, "%s", iComments2);
902 fprintf (asmFile, "; bit data\n");
903 fprintf (asmFile, "%s", iComments2);
904 copyFile (asmFile, bit->oFile);
907 /* the following is commented out. the CODE directive will be
908 used instead before code */
910 // fprintf (asmFile, "\tORG 0\n");
912 /* copy the interrupt vector table */
913 if (mainf && IFFUNC_HASBODY(mainf->type)) {
914 fprintf (asmFile, "%s", iComments2);
915 fprintf (asmFile, "; interrupt vector \n");
916 fprintf (asmFile, "%s", iComments2);
917 copyFile (asmFile, vFile);
920 /* copy global & static initialisations */
921 fprintf (asmFile, "%s", iComments2);
922 fprintf (asmFile, "; global & static initialisations\n");
923 fprintf (asmFile, "%s", iComments2);
925 /* Everywhere we generate a reference to the static_name area,
926 * (which is currently only here), we immediately follow it with a
927 * definition of the post_static_name area. This guarantees that
928 * the post_static_name area will immediately follow the static_name
931 fprintf (asmFile, ";\t.area %s\n", port->mem.static_name); /* MOF */
932 fprintf (asmFile, ";\t.area %s\n", port->mem.post_static_name);
933 fprintf (asmFile, ";\t.area %s\n", port->mem.static_name);
935 if (mainf && IFFUNC_HASBODY(mainf->type)) {
936 fprintf (asmFile,"__sdcc_gsinit_startup:\n");
939 /* 8051 legacy (?!) - VR 20-Jun-2003 */
940 /* if external stack is specified then the
941 higher order byte of the xdatalocation is
942 going into P2 and the lower order going into
944 if (options.useXstack) {
945 fprintf(asmFile,";\tmov\tP2,#0x%02x\n",
946 (((unsigned int)options.xdata_loc) >> 8) & 0xff);
947 fprintf(asmFile,";\tmov\t_spx,#0x%02x\n",
948 (unsigned int)options.xdata_loc & 0xff);
954 if (port->general.glue_up_main && mainf && IFFUNC_HASBODY(mainf->type))
956 /* This code is generated in the post-static area.
957 * This area is guaranteed to follow the static area
958 * by the ugly shucking and jiving about 20 lines ago.
960 fprintf(asmFile, ";\t.area %s\n", port->mem.post_static_name);
961 fprintf (asmFile,"\tgoto\t__sdcc_program_startup\n");
965 fprintf (asmFile, "%s", iComments2);
966 fprintf (asmFile, "; code\n");
967 fprintf (asmFile, "%s", iComments2);
968 fprintf (asmFile, ";\t.area %s\n", port->mem.code_name);
970 //copyFile (stderr, code->oFile);
972 // fprintf(asmFile, "; I code from now on!\n");
973 pic16_copypCode(asmFile, 'I');
976 // fprintf(asmFile, "; dbName from now on!\n");
977 fprintf(asmFile, "__sdcc_program_startup:\n");
978 pic16_copypCode(asmFile, statsg->dbName);
980 fprintf(asmFile, "; X code from now on!\n");
981 pic16_copypCode(asmFile, 'X');
982 fprintf(asmFile, "; M code from now on!\n");
983 pic16_copypCode(asmFile, 'M');
984 pic16_copypCode(asmFile, code->dbName);
985 pic16_copypCode(asmFile, 'P');
987 fprintf (asmFile,"\tend\n");