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 -------------------------------------------------------------------------*/
27 #include "SDCCglobl.h"
32 #include "SDCChasht.h"
34 #include "SDCCicode.h"
39 symbol *interrupts[256];
40 extern char *aopLiteral (value *, int);
41 void printIval (symbol *, link *, initList *, FILE *);
43 set *publics = NULL; /* public variables */
44 int maxInterrupts = 6;
45 extern int maxRegBank ;
47 extern char *VersionString;
48 extern FILE *codeOutFile;
49 set *tmpfileSet = NULL; /* set of tmp file created by the compiler */
50 /*-----------------------------------------------------------------*/
51 /* closeTmpFiles - closes all tmp files created by the compiler */
52 /* because of BRAIN DEAD MS/DOS & CYGNUS Libraries */
53 /*-----------------------------------------------------------------*/
54 DEFSETFUNC(closeTmpFiles)
64 /*-----------------------------------------------------------------*/
65 /* copyFile - copies source file to destination file */
66 /*-----------------------------------------------------------------*/
67 void copyFile (FILE * dest, FILE * src)
73 if ((ch = fgetc (src)) != EOF)
77 /*-----------------------------------------------------------------*/
78 /* emitRegularMap - emit code for maps with no special cases */
79 /*-----------------------------------------------------------------*/
80 static void emitRegularMap (memmap * map, bool addPublics, bool arFlag)
85 fprintf (map->oFile, "\t.area\t%s\n", map->sname);
87 /* print the area name */
88 for (sym = setFirstItem (map->syms); sym;
89 sym = setNextItem (map->syms)) {
91 /* if extern then do nothing */
92 if (IS_EXTERN (sym->etype))
95 /* if allocation required check is needed
96 then check if the symbol really requires
97 allocation only for local variables */
98 if (arFlag && !IS_AGGREGATE(sym->type) &&
99 !(sym->_isparm && !IS_REGPARM(sym->etype)) &&
100 !sym->allocreq && sym->level)
103 /* if global variable & not static or extern
104 and addPublics allowed then add it to the public set */
105 if ((sym->level == 0 ||
106 (sym->_isparm && !IS_REGPARM(sym->etype))) &&
108 !IS_STATIC (sym->etype))
109 addSetHead (&publics, sym);
111 /* if extern then do nothing or is a function
113 if (IS_FUNC (sym->type))
116 /* print extra debug info if required */
117 if (options.debug || sym->level == 0) {
119 cdbSymbol(sym,cdbFile,FALSE,FALSE);
121 if (!sym->level) /* global */
122 if (IS_STATIC(sym->etype))
123 fprintf(map->oFile,"F%s$",moduleName); /* scope is file */
125 fprintf(map->oFile,"G$"); /* scope is global */
127 /* symbol is local */
128 fprintf(map->oFile,"L%s$",(sym->localof ? sym->localof->name : "-null-"));
129 fprintf(map->oFile,"%s$%d$%d",sym->name,sym->level,sym->block);
132 /* if is has an absolute address then generate
133 an equate for this no need to allocate space */
134 if (SPEC_ABSA (sym->etype)) {
135 if (options.debug || sym->level == 0)
136 fprintf (map->oFile," == 0x%04x\n",SPEC_ADDR (sym->etype));
138 fprintf (map->oFile, "%s\t=\t0x%04x\n",
140 SPEC_ADDR (sym->etype));
144 if (options.debug || sym->level == 0)
145 fprintf(map->oFile,"==.\n");
146 fprintf (map->oFile, "%s:\n", sym->rname);
147 fprintf (map->oFile, "\t.ds\t0x%04x\n", (unsigned int)getSize (sym->type) & 0xffff);
150 /* if it has a initial value then do it only if
151 it is a global variable */
152 if (sym->ival && sym->level == 0) {
155 if (IS_AGGREGATE (sym->type))
156 ival = initAggregates (sym, sym->ival, NULL);
158 ival = newNode ('=', newAst (EX_VALUE, symbolVal (sym)),
159 decorateType (resolveSymbols (list2expr (sym->ival))));
160 codeOutFile = statsg->oFile;
161 eBBlockFromiCode (iCodeFromAst (ival));
168 /*-----------------------------------------------------------------*/
169 /* initPointer - pointer initialization code massaging */
170 /*-----------------------------------------------------------------*/
171 value *initPointer (initList *ilist)
174 ast *expr = list2expr(ilist);
179 /* try it the oldway first */
180 if ((val = constExprValue(expr,FALSE)))
183 /* no then we have to do these cludgy checks */
184 /* pointers can be initialized with address of
185 a variable or address of an array element */
186 if (IS_AST_OP(expr) && expr->opval.op == '&') {
187 /* address of symbol */
188 if (IS_AST_SYM_VALUE(expr->left)) {
189 val = copyValue(AST_VALUE(expr->left));
190 val->type = newLink();
191 if (SPEC_SCLS(expr->left->etype) == S_CODE) {
192 DCL_TYPE(val->type) = CPOINTER ;
193 DCL_PTR_CONST(val->type) = 1;
196 if (SPEC_SCLS(expr->left->etype) == S_XDATA)
197 DCL_TYPE(val->type) = FPOINTER;
199 if (SPEC_SCLS(expr->left->etype) == S_XSTACK )
200 DCL_TYPE(val->type) = PPOINTER ;
202 if (SPEC_SCLS(expr->left->etype) == S_IDATA)
203 DCL_TYPE(val->type) = IPOINTER ;
205 DCL_TYPE(val->type) = POINTER ;
206 val->type->next = expr->left->ftype;
207 val->etype = getSpec(val->type);
211 /* if address of indexed array */
212 if (IS_AST_OP(expr->left) && expr->left->opval.op == '[')
213 return valForArray(expr->left);
215 /* if address of structure element then
217 if (IS_AST_OP(expr->left) &&
218 expr->left->opval.op == '.' ) {
219 return valForStructElem(expr->left->left,
224 (&some_struct)->element */
225 if (IS_AST_OP(expr->left) &&
226 expr->left->opval.op == PTR_OP &&
227 IS_ADDRESS_OF_OP(expr->left->left))
228 return valForStructElem(expr->left->left->left,
233 werror(E_INIT_WRONG);
238 /*-----------------------------------------------------------------*/
239 /* printChar - formats and prints a characater string with DB */
240 /*-----------------------------------------------------------------*/
241 void printChar (FILE * ofile, char *s, int plen)
244 int len = strlen (s);
247 while (len && pplen < plen) {
249 fprintf (ofile, "\t.ascii /");
251 while (i && *s && pplen < plen) {
252 if (*s < ' ' || *s == '/') {
253 fprintf (ofile, "/\n\t.byte 0x%02x\n\t.ascii /", *s++);
256 fprintf (ofile, "%c", *s++);
260 fprintf (ofile, "/\n");
268 fprintf(ofile,"\t.byte\t0\n");
271 /*-----------------------------------------------------------------*/
272 /* printIvalType - generates ival for int/char */
273 /*-----------------------------------------------------------------*/
274 void printIvalType (link * type, initList * ilist, FILE * oFile)
278 /* if initList is deep */
279 if (ilist->type == INIT_DEEP)
280 ilist = ilist->init.deep;
282 val = list2val (ilist);
283 switch (getSize (type)) {
286 fprintf (oFile, "\t.byte 0\n");
288 fprintf (oFile, "\t.byte %s\n",
289 aopLiteral (val, 0));
294 fprintf (oFile, "\t.word 0\n");
296 fprintf (oFile, "\t.byte %s,%s\n",
297 aopLiteral (val, 0), aopLiteral (val, 1));
302 fprintf (oFile, "\t.word 0,0\n");
304 fprintf (oFile, "\t.byte %s,%s,%s,%s\n",
305 aopLiteral (val, 0), aopLiteral (val, 1),
306 aopLiteral (val, 2), aopLiteral (val, 3));
313 /*-----------------------------------------------------------------*/
314 /* printIvalStruct - generates initial value for structures */
315 /*-----------------------------------------------------------------*/
316 void printIvalStruct (symbol * sym,link * type,
317 initList * ilist, FILE * oFile)
322 sflds = SPEC_STRUCT (type)->fields;
323 if (ilist->type != INIT_DEEP) {
324 werror (E_INIT_STRUCT, sym->name);
328 iloop = ilist->init.deep;
330 for (; sflds; sflds = sflds->next, iloop = (iloop ? iloop->next : NULL))
331 printIval (sflds, sflds->type, iloop, oFile);
336 /*-----------------------------------------------------------------*/
337 /* printIvalChar - generates initital value for character array */
338 /*-----------------------------------------------------------------*/
339 int printIvalChar (link * type, initList * ilist, FILE * oFile, char *s)
346 val = list2val (ilist);
347 /* if the value is a character string */
348 if (IS_ARRAY (val->type) && IS_CHAR (val->etype)) {
349 if (!DCL_ELEM (type))
350 DCL_ELEM (type) = strlen (SPEC_CVAL (val->etype).v_char) + 1;
352 /* if size mismatch */
353 /* if (DCL_ELEM (type) < ((int) strlen (SPEC_CVAL (val->etype).v_char) + 1)) */
354 /* werror (E_ARRAY_BOUND); */
356 printChar (oFile, SPEC_CVAL (val->etype).v_char,DCL_ELEM(type));
358 if ((remain = (DCL_ELEM (type) - strlen (SPEC_CVAL (val->etype).v_char) -1))>0)
360 fprintf (oFile, "\t.byte 0\n");
368 printChar (oFile, s,strlen(s)+1);
372 /*-----------------------------------------------------------------*/
373 /* printIvalArray - generates code for array initialization */
374 /*-----------------------------------------------------------------*/
375 void printIvalArray (symbol * sym, link * type, initList * ilist,
379 int lcnt = 0, size = 0;
381 /* take care of the special case */
382 /* array of characters can be init */
384 if (IS_CHAR (type->next))
385 if (printIvalChar (type,
386 (ilist->type == INIT_DEEP ? ilist->init.deep : ilist),
387 oFile, SPEC_CVAL (sym->etype).v_char))
390 /* not the special case */
391 if (ilist->type != INIT_DEEP) {
392 werror (E_INIT_STRUCT, sym->name);
396 iloop = ilist->init.deep;
397 lcnt = DCL_ELEM (type);
401 printIval (sym, type->next, iloop, oFile);
402 iloop = (iloop ? iloop->next : NULL);
405 /* if not array limits given & we */
406 /* are out of initialisers then */
407 if (!DCL_ELEM (type) && !iloop)
410 /* no of elements given and we */
411 /* have generated for all of them */
416 /* if we have not been given a size */
417 if (!DCL_ELEM (type))
418 DCL_ELEM (type) = size;
423 /*-----------------------------------------------------------------*/
424 /* printIvalFuncPtr - generate initial value for function pointers */
425 /*-----------------------------------------------------------------*/
426 void printIvalFuncPtr (link * type, initList * ilist, FILE * oFile)
431 val = list2val (ilist);
432 /* check the types */
433 if ((dLvl = checkType (val->type, type->next)) <= 0) {
435 fprintf (oFile, "\t.word 0\n");
439 /* now generate the name */
441 if (IS_LITERAL (val->etype))
442 fprintf (oFile, "\t.byte %s,%s\n",
443 aopLiteral (val, 0), aopLiteral (val, 1));
445 fprintf (oFile, "\t.byte %s,(%s >> 8)\n",
446 val->name, val->name);
449 fprintf (oFile, "\t.byte %s,(%s >> 8)\n",
450 val->sym->rname, val->sym->rname);
455 /*-----------------------------------------------------------------*/
456 /* printIvalCharPtr - generates initial values for character pointers */
457 /*-----------------------------------------------------------------*/
458 int printIvalCharPtr (symbol * sym, link * type, value * val, FILE * oFile)
462 size = getSize (type);
466 "\t.byte %s", val->name) ;
469 "\t.byte %s,(%s >> 8)",
470 val->name, val->name);
473 fprintf (oFile, ",#0x02\n");
475 fprintf (oFile, "\n");
477 if (val->sym && val->sym->isstrlit)
478 addSet (&statsg->syms, val->sym);
483 /*-----------------------------------------------------------------*/
484 /* printIvalPtr - generates initial value for pointers */
485 /*-----------------------------------------------------------------*/
486 void printIvalPtr (symbol * sym, link * type, initList * ilist, FILE * oFile)
491 if (ilist->type == INIT_DEEP)
492 ilist = ilist->init.deep;
494 /* function pointer */
495 if (IS_FUNC (type->next)) {
496 printIvalFuncPtr (type, ilist, oFile);
500 if (!(val = initPointer (ilist)))
503 /* if character pointer */
504 if (IS_CHAR (type->next))
505 if (printIvalCharPtr (sym, type, val, oFile))
509 if (checkType (type, val->type) != 1)
510 werror (E_INIT_WRONG);
512 /* if val is literal */
513 if (IS_LITERAL (val->etype)) {
514 switch (getSize (type)) {
516 fprintf (oFile, "\t.byte 0x%02x\n", ((char) floatFromVal (val)) & 0xff);
519 fprintf (oFile, "\t.byte %s,%s\n",
520 aopLiteral (val, 0), aopLiteral (val, 1));
524 fprintf (oFile, "\t.byte %s,%s,0x%02x\n",
525 aopLiteral (val, 0), aopLiteral (val, 1), CPOINTER);
531 switch (getSize (type)) {
533 fprintf (oFile, "\t.byte %s\n", val->name);
536 fprintf (oFile, "\t.byte %s,(%s >> 8)\n", val->name, val->name);
540 fprintf (oFile, "\t.byte %s,(%s >> 8),0x%02x\n",
541 val->name, val->name, DCL_TYPE(val->type));
546 /*-----------------------------------------------------------------*/
547 /* printIval - generates code for initial value */
548 /*-----------------------------------------------------------------*/
549 void printIval (symbol * sym, link * type, initList * ilist, FILE * oFile)
554 /* if structure then */
555 if (IS_STRUCT (type)) {
556 printIvalStruct (sym, type, ilist, oFile);
560 /* if this is a pointer */
562 printIvalPtr (sym, type, ilist, oFile);
566 /* if this is an array */
567 if (IS_ARRAY (type)) {
568 printIvalArray (sym, type, ilist, oFile);
572 /* if type is SPECIFIER */
573 if (IS_SPEC (type)) {
574 printIvalType (type, ilist, oFile);
579 /*-----------------------------------------------------------------*/
580 /* emitStaticSeg - emitcode for the static segment */
581 /*-----------------------------------------------------------------*/
582 void emitStaticSeg (memmap * map)
586 /* fprintf(map->oFile,"\t.area\t%s\n",map->sname); */
589 /* for all variables in this segment do */
590 for (sym = setFirstItem (map->syms); sym;
591 sym = setNextItem (map->syms)) {
593 /* if it is "extern" then do nothing */
594 if (IS_EXTERN (sym->etype))
597 /* if it is not static add it to the public
599 if (!IS_STATIC (sym->etype))
600 addSetHead (&publics, sym);
602 /* print extra debug info if required */
603 if (options.debug || sym->level == 0) {
605 cdbSymbol(sym,cdbFile,FALSE,FALSE);
607 if (!sym->level) { /* global */
608 if (IS_STATIC(sym->etype))
609 fprintf(code->oFile,"F%s$",moduleName); /* scope is file */
611 fprintf(code->oFile,"G$"); /* scope is global */
614 /* symbol is local */
615 fprintf(code->oFile,"L%s$",
616 (sym->localof ? sym->localof->name : "-null-"));
617 fprintf(code->oFile,"%s$%d$%d",sym->name,sym->level,sym->block);
620 /* if it has an absolute address */
621 if (SPEC_ABSA (sym->etype)) {
622 if (options.debug || sym->level == 0)
623 fprintf(code->oFile," == 0x%04x\n", SPEC_ADDR (sym->etype));
625 fprintf (code->oFile, "%s\t=\t0x%04x\n",
627 SPEC_ADDR (sym->etype));
630 if (options.debug || sym->level == 0)
631 fprintf(code->oFile," == .\n");
633 /* if it has an initial value */
635 fprintf (code->oFile, "%s:\n", sym->rname);
637 resolveIvalSym (sym->ival);
638 printIval (sym, sym->type, sym->ival, code->oFile);
643 fprintf (code->oFile, "%s:\n", sym->rname);
644 /* special case for character strings */
645 if (IS_ARRAY (sym->type) && IS_CHAR (sym->type->next) &&
646 SPEC_CVAL (sym->etype).v_char)
647 printChar (code->oFile,
648 SPEC_CVAL (sym->etype).v_char,
649 strlen(SPEC_CVAL (sym->etype).v_char)+1);
651 fprintf (code->oFile, "\t.ds\t0x%04x\n", (unsigned int)getSize (sym->type)& 0xffff);
657 /*-----------------------------------------------------------------*/
658 /* emitMaps - emits the code for the data portion the code */
659 /*-----------------------------------------------------------------*/
662 /* no special considerations for the following
663 data, idata & bit & xdata */
664 emitRegularMap (data, TRUE, TRUE);
665 emitRegularMap (idata, TRUE,TRUE);
666 emitRegularMap (bit, TRUE,FALSE);
667 emitRegularMap (xdata, TRUE,TRUE);
668 emitRegularMap (sfr, FALSE,FALSE);
669 emitRegularMap (sfrbit, FALSE,FALSE);
670 emitRegularMap (code, TRUE,FALSE);
671 emitStaticSeg (statsg);
674 /*-----------------------------------------------------------------*/
675 /* createInterruptVect - creates the interrupt vector */
676 /*-----------------------------------------------------------------*/
677 void createInterruptVect (FILE * vFile)
680 mainf = newSymbol ("main", 0);
683 /* only if the main function exists */
684 if (!(mainf = findSymWithLevel (SymbolTab, mainf))) {
685 if (!options.cc_only)
690 /* if the main is only a prototype ie. no body then do nothing */
692 /* if ! compile only then main function should be present */
693 if (!options.cc_only)
698 fprintf (vFile, "\t.area\tCODE (CODE)\n");
699 fprintf (vFile, "__interrupt_vect:\n");
701 fprintf (vFile, "\tljmp\t__sdcc_gsinit_startup\n");
704 /* now for the other interrupts */
705 for (; i < maxInterrupts; i++) {
707 fprintf (vFile, "\tljmp\t%s\n\t.ds\t5\n", interrupts[i]->rname);
709 fprintf (vFile, "\treti\n\t.ds\t7\n");
715 ";--------------------------------------------------------\n"
716 "; File Created by SDCC : FreeWare ANSI-C Compiler\n"};
720 ";--------------------------------------------------------\n"};
723 /*-----------------------------------------------------------------*/
724 /* initialComments - puts in some initial comments */
725 /*-----------------------------------------------------------------*/
726 void initialComments (FILE * afile)
730 fprintf (afile, "%s", iComments1);
731 fprintf (afile, "; Version %s %s\n", VersionString,asctime(localtime(&t)));
732 fprintf (afile, "%s", iComments2);
735 /*-----------------------------------------------------------------*/
736 /* printPublics - generates .global for publics */
737 /*-----------------------------------------------------------------*/
738 void printPublics (FILE * afile)
742 fprintf (afile, "%s", iComments2);
743 fprintf (afile, "; publics variables in this module\n");
744 fprintf (afile, "%s", iComments2);
746 for (sym = setFirstItem (publics); sym;
747 sym = setNextItem (publics))
748 fprintf (afile, "\t.globl %s\n", sym->rname);
751 /*-----------------------------------------------------------------*/
752 /* emitOverlay - will emit code for the overlay stuff */
753 /*-----------------------------------------------------------------*/
754 static void emitOverlay(FILE *afile)
758 if (!elementsInSet(ovrSetSets))
759 fprintf(afile,"\t.area\tOSEG\t(OVR,DATA)\n");
761 /* for each of the sets in the overlay segment do */
762 for (ovrset = setFirstItem(ovrSetSets); ovrset;
763 ovrset = setNextItem(ovrSetSets)) {
767 if (elementsInSet(ovrset)) {
768 /* this dummy area is used to fool the assembler
769 otherwise the assembler will append each of these
770 declarations into one chunk and will not overlay
772 fprintf(afile,"\t.area _DUMMY\n");
773 /* output the area informtion */
774 fprintf(afile,"\t.area\tOSEG\t(OVR,DATA)\n"); /* MOF */
777 for (sym = setFirstItem(ovrset); sym;
778 sym = setNextItem(ovrset)) {
780 /* if extern then do nothing */
781 if (IS_EXTERN (sym->etype))
784 /* if allocation required check is needed
785 then check if the symbol really requires
786 allocation only for local variables */
787 if (!IS_AGGREGATE(sym->type) &&
788 !(sym->_isparm && !IS_REGPARM(sym->etype))
789 && !sym->allocreq && sym->level)
792 /* if global variable & not static or extern
793 and addPublics allowed then add it to the public set */
794 if ((sym->_isparm && !IS_REGPARM(sym->etype))
795 && !IS_STATIC (sym->etype))
796 addSetHead (&publics, sym);
798 /* if extern then do nothing or is a function
800 if (IS_FUNC (sym->type))
803 /* print extra debug info if required */
804 if (options.debug || sym->level == 0) {
806 cdbSymbol(sym,cdbFile,FALSE,FALSE);
808 if (!sym->level) { /* global */
809 if (IS_STATIC(sym->etype))
810 fprintf(afile,"F%s$",moduleName); /* scope is file */
812 fprintf(afile,"G$"); /* scope is global */
815 /* symbol is local */
816 fprintf(afile,"L%s$",
817 (sym->localof ? sym->localof->name : "-null-"));
818 fprintf(afile,"%s$%d$%d",sym->name,sym->level,sym->block);
821 /* if is has an absolute address then generate
822 an equate for this no need to allocate space */
823 if (SPEC_ABSA (sym->etype)) {
825 if (options.debug || sym->level == 0)
826 fprintf (afile," == 0x%04x\n",SPEC_ADDR (sym->etype));
828 fprintf (afile, "%s\t=\t0x%04x\n",
830 SPEC_ADDR (sym->etype));
833 if (options.debug || sym->level == 0)
834 fprintf(afile,"==.\n");
837 fprintf (afile, "%s:\n", sym->rname);
838 fprintf (afile, "\t.ds\t0x%04x\n", (unsigned int)getSize (sym->type) & 0xffff);
845 /*-----------------------------------------------------------------*/
846 /* glue - the final glue that hold the whole thing together */
847 /*-----------------------------------------------------------------*/
852 FILE *ovrFile = tmpfile();
854 addSetHead(&tmpfileSet,ovrFile);
855 /* print the global struct definitions */
857 cdbStructBlock (0,cdbFile);
859 /* create the interrupt vector table */
860 createInterruptVect ((vFile = tmpfile ()));
861 addSetHead(&tmpfileSet,vFile);
863 /* emit code for the all the variables declared */
865 /* do the overlay segments */
866 emitOverlay(ovrFile);
868 /* now put it all together into the assembler file */
869 /* create the assembler file name */
870 sprintf (buffer, srcFileName);
871 strcat (buffer, ".asm");
872 if (!(asmFile = fopen (buffer, "w"))) {
873 werror (E_FILE_OPEN_ERR, buffer);
877 /* initial comments */
878 initialComments (asmFile);
880 /* print module name */
881 fprintf (asmFile, "\t.module %s\n", moduleName);
883 /* print the global variables in this module */
884 printPublics (asmFile);
887 /* copy the sfr segment */
888 fprintf (asmFile, "%s", iComments2);
889 fprintf (asmFile, "; special function registers\n");
890 fprintf (asmFile, "%s", iComments2);
891 copyFile (asmFile, sfr->oFile);
893 /* copy the sbit segment */
894 fprintf (asmFile, "%s", iComments2);
895 fprintf (asmFile, "; special function bits \n");
896 fprintf (asmFile, "%s", iComments2);
897 copyFile (asmFile, sfrbit->oFile);
899 /* copy the data segment */
900 fprintf (asmFile, "%s", iComments2);
901 fprintf (asmFile, "; internal ram data\n");
902 fprintf (asmFile, "%s", iComments2);
903 copyFile (asmFile, data->oFile);
906 /* create the overlay segments */
907 fprintf (asmFile, "%s", iComments2);
908 fprintf (asmFile, "; overlayable items in internal ram \n");
909 fprintf (asmFile, "%s", iComments2);
910 copyFile (asmFile, ovrFile);
912 /* create the stack segment MOF */
913 if (mainf && mainf->fbody) {
914 fprintf (asmFile, "%s", iComments2);
915 fprintf (asmFile, "; Stack segment in internal ram \n");
916 fprintf (asmFile, "%s", iComments2);
917 fprintf (asmFile, "\t.area\tSSEG\t(DATA)\n"
918 "__start__stack:\n\t.ds\t1\n\n");
921 /* create the idata segment */
922 fprintf (asmFile, "%s", iComments2);
923 fprintf (asmFile, "; indirectly addressable internal ram data\n");
924 fprintf (asmFile, "%s", iComments2);
925 copyFile (asmFile, idata->oFile);
927 /* copy the bit segment */
928 fprintf (asmFile, "%s", iComments2);
929 fprintf (asmFile, "; bit data\n");
930 fprintf (asmFile, "%s", iComments2);
931 copyFile (asmFile, bit->oFile);
933 /* if external stack then reserve space of it */
934 if (mainf && mainf->fbody && options.useXstack ) {
935 fprintf (asmFile, "%s", iComments2);
936 fprintf (asmFile, "; external stack \n");
937 fprintf (asmFile, "%s", iComments2);
938 fprintf (asmFile,"\t.area XSEG (XDATA)\n"); /* MOF */
939 fprintf (asmFile,"\t.ds 256\n");
943 /* copy xtern ram data */
944 fprintf (asmFile, "%s", iComments2);
945 fprintf (asmFile, "; external ram data\n");
946 fprintf (asmFile, "%s", iComments2);
947 copyFile (asmFile, xdata->oFile);
949 /* copy the interrupt vector table */
950 if (mainf && mainf->fbody) {
951 fprintf (asmFile, "%s", iComments2);
952 fprintf (asmFile, "; interrupt vector \n");
953 fprintf (asmFile, "%s", iComments2);
954 copyFile (asmFile, vFile);
957 /* copy global & static initialisations */
958 fprintf (asmFile, "%s", iComments2);
959 fprintf (asmFile, "; global & static initialisations\n");
960 fprintf (asmFile, "%s", iComments2);
961 fprintf (asmFile, "\t.area GSINIT (CODE)\n"); /* MOF */
962 if (mainf && mainf->fbody) {
963 fprintf (asmFile,"__sdcc_gsinit_startup:\n");
964 /* if external stack is specified then the
965 higher order byte of the xdatalocation is
966 going into P2 and the lower order going into
968 if (options.useXstack) {
969 fprintf(asmFile,"\tmov\tP2,#0x%02x\n",
970 (((unsigned int)options.xdata_loc) >> 8) & 0xff);
971 fprintf(asmFile,"\tmov\t_spx,#0x%02x\n",
972 (unsigned int)options.xdata_loc & 0xff);
975 /* initialise the stack pointer */
976 /* if the user specified a value then use it */
977 if (options.stack_loc)
978 fprintf(asmFile,"\tmov\tsp,#%d\n",options.stack_loc);
980 /* no: we have to compute it */
981 if (!options.stackOnData && maxRegBank <= 3)
982 fprintf(asmFile,"\tmov\tsp,#%d\n",((maxRegBank + 1) * 8) -1);
984 fprintf(asmFile,"\tmov\tsp,#__start__stack\n"); /* MOF */
986 fprintf (asmFile,"\tlcall\t__sdcc_external_startup\n");
987 fprintf (asmFile,"\tmov\ta,dpl\n");
988 fprintf (asmFile,"\tjz\t__sdcc_init_data\n");
989 fprintf (asmFile,"\tljmp\t__sdcc_program_startup\n");
990 fprintf (asmFile,"__sdcc_init_data:\n");
993 copyFile (asmFile, statsg->oFile);
996 fprintf (asmFile, "%s", iComments2);
997 fprintf (asmFile, "; code\n");
998 fprintf (asmFile, "%s", iComments2);
999 fprintf (asmFile, "\t.area CSEG (CODE)\n");
1000 if (mainf && mainf->fbody) {
1002 /* entry point @ start of CSEG */
1003 fprintf (asmFile,"__sdcc_program_startup:\n");
1005 /* put in the call to main */
1006 fprintf(asmFile,"\tlcall\t_main\n");
1007 if (options.mainreturn) {
1009 fprintf(asmFile,";\treturn from main ; will return to caller\n");
1010 fprintf(asmFile,"\tret\n");
1014 fprintf(asmFile,";\treturn from main will lock up\n");
1015 fprintf(asmFile,"\tsjmp .\n");
1018 copyFile (asmFile, code->oFile);
1021 applyToSet(tmpfileSet,closeTmpFiles);