- static const char *WHITE = " \t\n";
- static const char *WHITECOMMA = " \t\n,";
-
- char *ptr = strtok((char *)sz, WHITE);
-
- /* #pragma maxram [maxram] */
- if (startsWith (ptr, "maxram")) {
- char *maxRAM = strtok((char *)NULL, WHITE);
-
- if (maxRAM != (char *)NULL) {
- int maxRAMaddress;
- value *maxRAMVal;
-
- maxRAMVal = constVal(maxRAM);
- maxRAMaddress = (int)floatFromVal(maxRAMVal);
- pic16_setMaxRAM(maxRAMaddress);
- }
-
- return 0;
- }
-
- /* #pragma stack [stack-position] [stack-len] */
- if(startsWith(ptr, "stack")) {
- char *stackPosS = strtok((char *)NULL, WHITE);
- char *stackLenS = strtok((char *)NULL, WHITE);
- value *stackPosVal;
- value *stackLenVal;
- regs *reg;
- symbol *sym;
-
- stackPosVal = constVal( stackPosS );
- stackPos = (unsigned int)floatFromVal( stackPosVal );
-
-
- if(stackLenS) {
- stackLenVal = constVal( stackLenS );
- stackLen = (unsigned int)floatFromVal( stackLenVal );
- }
-
- if(stackLen < 1) {
- stackLen = 64;
- fprintf(stderr, "%s:%d: warning: setting stack to default size %d (0x%04x)\n",
- filename, lineno-1, stackLen, stackLen);
-
-// fprintf(stderr, "%s:%d setting stack to default size %d\n", __FILE__, __LINE__, stackLen);
- }
-
-// fprintf(stderr, "Initializing stack pointer at 0x%x len 0x%x\n", stackPos, stackLen);
-
- 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;
-
- 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;
-
- while(symname) {
- ssym = Safe_calloc(1, sizeof(sectSyms));
- ssym->name = Safe_calloc(1, strlen(symname)+2);
- sprintf(ssym->name, "_%s", symname);
- ssym->reg = NULL;
-
- addSet(§Syms, ssym);
-
- nsym = newSymbol(symname, 0);
- strcpy(nsym->rname, ssym->name);
+ struct pragma_token_s token;
+ int err = 0;
+ int processed = 1;
+
+ init_pragma_token(&token);
+
+ switch (id)
+ {
+ /* #pragma stack [stack-position] [stack-len] */
+ case P_STACK:
+ {
+ unsigned int stackPos, stackLen;
+ regs *reg;
+ symbol *sym;
+
+ cp = get_pragma_token(cp, &token);
+ if (TOKEN_INT != token.type)
+ {
+ err = 1;
+ break;
+ }
+ stackPos = token.val.int_val;
+
+ cp = get_pragma_token(cp, &token);
+ if (TOKEN_INT != token.type)
+ {
+ err = 1;
+ break;
+ }
+ stackLen = token.val.int_val;
+
+ cp = get_pragma_token(cp, &token);
+ if (TOKEN_EOL != token.type)
+ {
+ err = 1;
+ break;
+ }
+
+ if (stackLen < 1) {
+ stackLen = 64;
+ fprintf(stderr, "%s:%d: warning: setting stack to default size %d (0x%04x)\n",
+ filename, lineno, stackLen, stackLen);
+ }
+
+ /* check sanity of stack */
+ if ((stackPos >> 8) != ((stackPos + stackLen - 1) >> 8)) {
+ fprintf (stderr, "%s:%u: warning: stack [0x%03X,0x%03X] crosses memory bank boundaries (not fully tested)\n",
+ filename, lineno, 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, 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, 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, stackPos, stackPos + stackLen - 1, pic16->RAMsize-1);
+ err = 1;
+ break;
+ }
+ }
+
+ 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 */
+ }
+ break;
+
+ /* #pragma code [symbol] [location] */
+ case P_CODE:
+ {
+ absSym *absS;
+
+ cp = get_pragma_token(cp, &token);
+ if (TOKEN_STR != token.type)
+ goto code_err;
+
+ absS = Safe_calloc(1, sizeof(absSym));
+ sprintf(absS->name, "_%s", get_pragma_string(&token));
+
+ cp = get_pragma_token(cp, &token);
+ if (TOKEN_INT != token.type)
+ {
+ code_err:
+ //fprintf (stderr, "%s:%d: #pragma code [symbol] [location] -- symbol or location missing\n", filename, lineno);
+ err = 1;
+ break;
+ }
+ absS->address = token.val.int_val;
+
+ cp = get_pragma_token(cp, &token);
+ if (TOKEN_EOL != token.type)
+ {
+ err = 1;
+ break;
+ }
+
+ 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, 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);
+ }
+ break;
+
+ /* #pragma udata [section-name] [symbol] */
+ case P_UDATA:
+ {
+ char *sectname;
+ const char *symname;
+ symbol *nsym;
+ sectSym *ssym;
+ sectName *snam;
+ int found = 0;
+
+ cp = get_pragma_token(cp, &token);
+ if (TOKEN_STR == token.type)
+ sectname = Safe_strdup(get_pragma_string(&token));
+ else
+ {
+ err = 1;
+ break;
+ }
+
+ cp = get_pragma_token(cp, &token);
+ if (TOKEN_STR == token.type)
+ symname = get_pragma_string(&token);
+ else
+ {
+ //fprintf (stderr, "%s:%d: #pragma udata [section-name] [symbol] -- section-name or symbol missing!\n", filename, lineno);
+ err = 1;
+ symname = NULL;
+ }
+
+ 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((char *)symname, 0);
+ strcpy(nsym->rname, ssym->name);
+