+
+// fprintf(stderr, "Initializing stack pointer at 0x%x len 0x%x\n", stackPos, stackLen);
+
+ /* check sanity of stack */
+ if ((stackPos >> 8) != ((stackPos+stackLen) >> 8)) {
+ fprintf (stderr, "%s:%u: warning: stack [0x%03X,0x%03X] crosses memory bank boundaries (not fully tested)\n",
+ filename,lineno-1, stackPos, stackPos+stackLen-1);
+ }
+
+ if (pic16) {
+ if (stackPos < pic16->acsSplitOfs) {
+ fprintf (stderr, "%s:%u: warning: stack [0x%03X, 0x%03X] intersects with the access bank [0x000,0x%03x] -- this is highly discouraged!\n",
+ filename, lineno-1, stackPos, stackPos+stackLen-1, pic16->acsSplitOfs);
+ }
+
+ if (stackPos+stackLen > 0xF00 + pic16->acsSplitOfs) {
+ fprintf (stderr, "%s:%u: warning: stack [0x%03X,0x%03X] intersects with special function registers [0x%03X,0xFFF]-- this is highly discouraged!\n",
+ filename, lineno-1, stackPos, stackPos+stackLen-1, 0xF00 + pic16->acsSplitOfs);
+ }
+
+ if (stackPos+stackLen > pic16->RAMsize) {
+ fprintf (stderr, "%s:%u: error: stack [0x%03X,0x%03X] is placed outside available memory [0x000,0x%03X]!\n",
+ filename, lineno-1, stackPos, stackPos+stackLen-1, pic16->RAMsize-1);
+ exit(-1);
+ return 1; /* considered an error, but this reports "invalid pragma stack"... */
+ }
+ }
+
+ reg=newReg(REG_SFR, PO_SFR_REGISTER, stackPos, "_stack", stackLen-1, 0, NULL);
+ addSet(&pic16_fix_udata, reg);
+
+ reg = newReg(REG_SFR, PO_SFR_REGISTER, stackPos + stackLen-1, "_stack_end", 1, 0, NULL);
+ addSet(&pic16_fix_udata, reg);
+
+ sym = newSymbol("stack", 0);
+ sprintf(sym->rname, "_%s", sym->name);
+ addSet(&publics, sym);
+
+ sym = newSymbol("stack_end", 0);
+ sprintf(sym->rname, "_%s", sym->name);
+ addSet(&publics, sym);
+
+ initsfpnt = 1; // force glue() to initialize stack/frame pointers */
+
+ return 0;
+ }
+
+ /* #pragma code [symbol] [location] */
+ if(startsWith(ptr, "code")) {
+ char *symname = strtok((char *)NULL, WHITE);
+ char *location = strtok((char *)NULL, WHITE);
+ absSym *absS;
+ value *addr;
+
+ if (!symname || !location) {
+ fprintf (stderr, "%s:%d: #pragma code [symbol] [location] -- symbol or location missing\n", filename, lineno-1);
+ exit (-1);
+ return 1; /* considered an error, but this reports "invalid pragma code"... */
+ }
+
+ absS = Safe_calloc(1, sizeof(absSym));
+ sprintf(absS->name, "_%s", symname);
+
+ addr = constVal( location );
+ absS->address = (unsigned int)floatFromVal( addr );
+
+ if((absS->address % 2) != 0) {
+ absS->address--;
+ fprintf(stderr, "%s:%d: warning: code memory locations should be word aligned, will locate to 0x%06x instead\n",
+ filename, lineno-1, absS->address);
+ }
+
+ addSet(&absSymSet, absS);
+// fprintf(stderr, "%s:%d symbol %s will be placed in location 0x%06x in code memory\n",
+// __FILE__, __LINE__, symname, absS->address);
+
+ return 0;
+ }
+
+ /* #pragma udata [section-name] [symbol] */
+ if(startsWith(ptr, "udata")) {
+ char *sectname = strtok((char *)NULL, WHITE);
+ char *symname = strtok((char *)NULL, WHITE);
+ symbol *nsym;
+ sectSym *ssym;
+ sectName *snam;
+ int found=0;
+
+ if (!symname || !sectname) {
+ fprintf (stderr, "%s:%d: #pragma udata [section-name] [symbol] -- section-name or symbol missing!\n", filename, lineno-1);
+ exit (-1);
+ return 1; /* considered an error, but this reports "invalid pragma code"... */
+ }
+
+ while(symname) {
+ ssym = Safe_calloc(1, sizeof(sectSym));
+ ssym->name = Safe_calloc(1, strlen(symname)+2);
+ sprintf(ssym->name, "%s%s", port->fun_prefix, symname);
+ ssym->reg = NULL;
+
+ addSet(§Syms, ssym);
+
+ nsym = newSymbol(symname, 0);
+ strcpy(nsym->rname, ssym->name);
+
+#if 0
+ checkAddSym(&publics, nsym);
+#endif
+
+ found = 0;
+ for(snam=setFirstItem(sectNames);snam;snam=setNextItem(sectNames)) {
+ if(!strcmp(sectname, snam->name)){ found=1; break; }
+ }
+
+ if(!found) {
+ snam = Safe_calloc(1, sizeof(sectName));
+ snam->name = Safe_strdup( sectname );
+ snam->regsSet = NULL;
+
+ addSet(§Names, snam);
+ }
+
+ ssym->section = snam;
+
+#if 0
+ fprintf(stderr, "%s:%d placing symbol %s at section %s (%p)\n", __FILE__, __LINE__,
+ ssym->name, snam->name, snam);
+#endif
+
+ symname = strtok((char *)NULL, WHITE);
+ }
+
+ return 0;
+ }
+
+ /* #pragma wparam function1[, function2[,...]] */
+ if(startsWith(ptr, "wparam")) {
+ char *fname = strtok((char *)NULL, WHITECOMMA);
+
+
+ while(fname) {
+ fprintf(stderr, "PIC16 Warning: `%s' wparam pragma is obsolete. use function attribute `wparam' instead.\n", fname);
+ addSet(&wparamList, Safe_strdup(fname));
+
+// debugf("passing with WREG to %s\n", fname);
+ fname = strtok((char *)NULL, WHITECOMMA);
+ }
+