X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=src%2Fpic16%2Fdevice.c;h=589b89da7070060c3375001ed8a94a1ef1500cf7;hb=eae1bd2f705a2c61e143c539f8c4d1e9c2b4efe6;hp=c22d8e78cae0c9cf63f89233729e6a5f67f79998;hpb=35abef5d818f86c51e157fd340f2252f588a49f5;p=fw%2Fsdcc diff --git a/src/pic16/device.c b/src/pic16/device.c index c22d8e78..589b89da 100644 --- a/src/pic16/device.c +++ b/src/pic16/device.c @@ -20,50 +20,44 @@ Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -------------------------------------------------------------------------*/ - -/* - VR - Began writing code to make PIC16 C source files independent from - the header file (created by the inc2h.pl) - - - adding maximum RAM memory into PIC_Device structure - -*/ - #include #include "common.h" // Include everything in the SDCC src directory #include "newalloc.h" - +#include "dbuf_string.h" #include "main.h" #include "pcode.h" #include "ralloc.h" #include "device.h" +void pic16_printIval (symbol * sym, sym_link * type, initList * ilist, char ptype, void *p); +extern void pic16_pCodeConstString (char *name, char *value, unsigned length); + stats_t statistics = { 0, 0, 0, 0 }; #define DEVICE_FILE_NAME "pic16devices.txt" static PIC16_device default_device = { - { "p18f452", "18f452", "pic18f452", "f452" }, - 0x600, - 0x80, - { /* configuration words */ - 0x300001, 0x30000d, - { { 0x27, 0, 0xff } /* 1 */ , { 0x0f, 0, 0xff } /* 2 */ , - { 0x0f, 0, 0xff } /* 3 */ , { -1 , 0, 0xff } /* 4 */ , - { 0x01, 0, 0xff } /* 5 */ , { 0x85, 0, 0xff } /* 6 */ , - { -1 , 0, 0xff } /* 7 */ , { 0x0f, 0, 0xff } /* 8 */ , - { 0xc0, 0, 0xff } /* 9 */ , { 0x0f, 0, 0xff } /* a */ , - { 0xe0, 0, 0xff } /* b */ , { 0x0f, 0, 0xff } /* c */ , - { 0x40, 0, 0xff } /* d */ } - }, - { /* ID locations */ - 0x200000, 0x200007, - { { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, - { 0, 0 }, { 0, 0 }, { 0, 0 } } - }, - NULL + { "p18f452", "18f452", "pic18f452", "f452" }, + 0x600, + 0x80, + { /* configuration words */ + 0x300001, 0x30000d, + { { 0x27, 0, 0xff } /* 1 */ , { 0x0f, 0, 0xff } /* 2 */ , + { 0x0f, 0, 0xff } /* 3 */ , { -1 , 0, 0xff } /* 4 */ , + { 0x01, 0, 0xff } /* 5 */ , { 0x85, 0, 0xff } /* 6 */ , + { -1 , 0, 0xff } /* 7 */ , { 0x0f, 0, 0xff } /* 8 */ , + { 0xc0, 0, 0xff } /* 9 */ , { 0x0f, 0, 0xff } /* a */ , + { 0xe0, 0, 0xff } /* b */ , { 0x0f, 0, 0xff } /* c */ , + { 0x40, 0, 0xff } /* d */ } + }, + { /* ID locations */ + 0x200000, 0x200007, + { { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 }, + { 0, 0 }, { 0, 0 }, { 0, 0 } } + }, + NULL }; PIC16_device *pic16 = &default_device; @@ -74,300 +68,371 @@ extern set *userIncDirsSet; extern char *iComments2; -void pic16_dump_equates(FILE *of, set *equs) +void +pic16_dump_equates (FILE *of, set *equs) { regs *r; - r = setFirstItem(equs); - if(!r)return; + r = setFirstItem (equs); + if (!r) + return; - fprintf(of, "%s", iComments2); - fprintf(of, ";\tEquates to used internal registers\n"); - fprintf(of, "%s", iComments2); + fprintf (of, "%s", iComments2); + fprintf (of, ";\tEquates to used internal registers\n"); + fprintf (of, "%s", iComments2); - for(; r; r = setNextItem(equs)) { - fprintf(of, "%s\tequ\t0x%02x\n", r->name, r->address); - } + for (; r; r = setNextItem (equs)) + { + fprintf (of, "%s\tequ\t0x%02x\n", r->name, r->address); + } // for } -void pic16_dump_access(FILE *of, set *section) +void +pic16_dump_access (FILE *of, set *section) { regs *r; - r = setFirstItem(section); - if(!r)return; + r = setFirstItem (section); + if (!r) + return; - fprintf(of, "%s", iComments2); - fprintf(of, ";\tAccess bank symbols\n"); - fprintf(of, "%s", iComments2); + fprintf (of, "%s", iComments2); + fprintf (of, ";\tAccess bank symbols\n"); + fprintf (of, "%s", iComments2); - fprintf(of, "\tudata_acs\n"); - for(; r; r = setNextItem(section)) { - fprintf(of, "%s\tres\t%d\n", r->name, r->size); - statistics.adsize += r->size; - } + fprintf (of, "\tudata_acs\n"); + for (; r; r = setNextItem (section)) + { + fprintf (of, "%s\tres\t%d\n", r->name, r->size); + statistics.adsize += r->size; + } // for } - -int regCompare(const void *a, const void *b) +int +regCompare (const void *a, const void *b) { const regs *const *i = a; const regs *const *j = b; - /* sort primarily by the address */ - if( (*i)->address > (*j)->address)return 1; - if( (*i)->address < (*j)->address)return -1; + /* Sort primarily by the address ... */ + if ((*i)->address > (*j)->address) + return (1); - /* and secondarily by size */ - /* register size sorting may have strange results use with care */ - if( (*i)->size > (*j)->size)return 1; - if( (*i)->size < (*j)->size)return -1; + if ((*i)->address < (*j)->address) + return (-1); - /* finally if in same address and same size sort by name */ - return (strcmp( (*i)->name, (*j)->name)); + /* ... and secondarily by size. */ + /* Register size sorting may have strange results, use with care! */ + if ((*i)->size > (*j)->size) + return (1); - return 0; + if ((*i)->size < (*j)->size) + return (-1); + + /* Finally, if in same address and same size, sort by name. */ + return (strcmp ((*i)->name, (*j)->name)); } -int symCompare(const void *a, const void *b) +int +symCompare (const void *a, const void *b) { const symbol *const *i = a; const symbol *const *j = b; - /* sort primarily by the address */ - if( SPEC_ADDR((*i)->etype) > SPEC_ADDR((*j)->etype))return 1; - if( SPEC_ADDR((*i)->etype) < SPEC_ADDR((*j)->etype))return -1; + /* Sort primarily by the address ... */ + if (SPEC_ADDR ((*i)->etype) > SPEC_ADDR ((*j)->etype)) + return (1); - /* and secondarily by size */ - /* register size sorting may have strange results use with care */ - if( getSize((*i)->etype) > getSize((*j)->etype))return 1; - if( getSize((*i)->etype) < getSize((*j)->etype))return -1; + if (SPEC_ADDR ((*i)->etype) < SPEC_ADDR ((*j)->etype)) + return (-1); - /* finally if in same address and same size sort by name */ - return (strcmp( (*i)->rname, (*j)->rname)); + /* ... and secondarily by size. */ + /* Register size sorting may have strange results, use with care! */ + if (getSize ((*i)->etype) > getSize ((*j)->etype)) + return (1); - return 0; + if (getSize ((*i)->etype) < getSize ((*j)->etype)) + return (-1); + + /* Finally, if in same address and same size, sort by name. */ + return (strcmp ((*i)->rname, (*j)->rname)); } -void pic16_dump_usection(FILE *of, set *section, int fix) +void +pic16_dump_usection (FILE *of, set *section, int fix) { - static int abs_usection_no=0; - static unsigned int usection_no=0; + static int abs_usection_no = 0; + static unsigned int usection_no = 0; regs *r, *rprev; unsigned int init_addr, i; regs **rlist; regs *r1; - /* put all symbols in an array */ - if (!elementsInSet(section)) return; - rlist = Safe_calloc(elementsInSet(section), sizeof(regs *)); - r = rlist[0]; i = 0; - for(rprev = setFirstItem(section); rprev; rprev = setNextItem(section)) { - rlist[i] = rprev; i++; - } + /* put all symbols in an array */ + if (!elementsInSet (section)) + return; - if(!i) { - if(rlist)Safe_free(rlist); - return; - } + rlist = Safe_calloc (elementsInSet (section), sizeof (regs *)); + r = rlist[0]; + i = 0; + for (rprev = setFirstItem (section); rprev; rprev = setNextItem (section)) + { + rlist[i] = rprev; + i++; + } // for - /* sort symbols according to their address */ - qsort(rlist, i /*elementsInSet(section)*/, sizeof(regs *), regCompare); + if (!i) + { + if (rlist) + Safe_free (rlist); - if(!fix) { + return; + } // if + /* sort symbols according to their address */ + qsort (rlist, i, sizeof (regs *), regCompare); + + if (!fix) + { #define EMIT_SINGLE_UDATA_SECTION 0 #if EMIT_SINGLE_UDATA_SECTION - fprintf(of, "\n\n\tudata\n"); - for(r = setFirstItem(section); r; r = setNextItem(section)) { - fprintf(of, "%s\tres\t%d\n", r->name, r->size); - statistics.udsize += r->size; - } + fprintf (of, "\n\n\tudata\n"); + for (r = setFirstItem (section); r; r = setNextItem (section)) + { + fprintf (of, "%s\tres\t%d\n", r->name, r->size); + statistics.udsize += r->size; + } // for #else - for(r = setFirstItem(section); r; r = setNextItem(section)) { - //fprintf(of, "\nudata_%s_%s\tudata\n", moduleName, r->name); - fprintf(of, "\nudata_%s_%u\tudata\n", moduleName, usection_no++); - fprintf(of, "%s\tres\t%d\n", r->name, r->size); - statistics.udsize += r->size; - } + for (r = setFirstItem (section); r; r = setNextItem (section)) + { + //fprintf (of, "\nudata_%s_%s\tudata\n", moduleName, r->name); + fprintf (of, "\nudata_%s_%u\tudata\n", moduleName, usection_no++); + fprintf (of, "%s\tres\t%d\n", r->name, r->size); + statistics.udsize += r->size; + } // for #endif - } else { - unsigned int j=0; - int deb_addr=0; - - rprev = NULL; - init_addr = rlist[j]->address; - deb_addr = init_addr; - fprintf(of, "\n\nustat_%s_%02d\tudata\t0X%04X\n", moduleName, abs_usection_no++, init_addr); - - for(j=0;jaddress & 0x0FFF); // warning(s) emitted below + fprintf (of, "\n\nustat_%s_%02d\tudata\t0X%04X\n", moduleName, abs_usection_no++, (init_addr & 0x0FFF)); + + for (j = 0; j < i; j++) + { + r = rlist[j]; + r1 = NULL; + if (j < i - 1) + r1 = rlist[j + 1]; + + init_addr = (r->address & 0x0FFF); + if (init_addr != r->address) + { + fprintf (stderr, "%s: WARNING: Changed address of pinned variable %s from 0x%x to 0x%x\n", + moduleName, r->name, r->address, init_addr); + } // if - init_addr = r->address; - deb_addr = init_addr; + if ((rprev && (init_addr != ((rprev->address & 0x0FFF) + prev_size)))) + fprintf (of, "\n\nustat_%s_%02d\tudata\t0X%04X\n", moduleName, abs_usection_no++, init_addr); - if((rprev && (init_addr > (rprev->address + rprev->size)))) { - fprintf(of, "\n\nustat_%s_%02d\tudata\t0X%04X\n", moduleName, abs_usection_no++, init_addr); - } + /* XXX: Does not handle partial overlap correctly. */ + if (r1 && (init_addr == (r1->address & 0x0FFF))) + { + prev_size = 0; + fprintf (of, "%-15s\n", r->name); + } + else + { + prev_size = r->size; + fprintf (of, "%-15s\tres\t%d\n", r->name, prev_size); + statistics.udsize += prev_size; + } - if(r1 && (init_addr == r1->address)) { - fprintf(of, "\n%s\tres\t0\n", r->name); - } else { - fprintf(of, "%s\tres\t%d\n", r->name, r->size); - deb_addr += r->size; - statistics.udsize += r->size; - } + rprev = r; + } // for + } // if - rprev = r; - } - } - Safe_free(rlist); + Safe_free (rlist); } -void pic16_dump_gsection(FILE *of, set *sections) +void +pic16_dump_gsection (FILE *of, set *sections) { regs *r; sectName *sname; - for(sname = setFirstItem(sections); sname; sname = setNextItem(sections)) { - if(!strcmp(sname->name, "access"))continue; - fprintf(of, "\n\n%s\tudata\n", sname->name); + for (sname = setFirstItem (sections); sname; sname = setNextItem (sections)) + { + if (!strcmp (sname->name, "access")) + continue; + + fprintf (of, "\n\n%s\tudata\n", sname->name); - for(r=setFirstItem(sname->regsSet); r; r=setNextItem(sname->regsSet)) { + for (r = setFirstItem (sname->regsSet); r; r = setNextItem (sname->regsSet)) + { #if 0 - fprintf(stderr, "%s:%d emitting variable %s for section %s (%p)\n", __FILE__, __LINE__, - r->name, sname->name, sname); + fprintf (stderr, "%s:%d emitting variable %s for section %s (%p)\n", + __FILE__, __LINE__, r->name, sname->name, sname); #endif - fprintf(of, "%s\tres\t%d\n", r->name, r->size); - statistics.udsize += r->size; - } - } + fprintf (of, "%s\tres\t%d\n", r->name, r->size); + statistics.udsize += r->size; + } // for + } // for } - -/* forward declaration */ -void pic16_printIval(symbol * sym, sym_link * type, initList * ilist, char ptype, void *p); -extern void pic16_pCodeConstString(char *name, char *value); - -void pic16_dump_isection(FILE *of, set *section, int fix) +void +pic16_dump_isection (FILE *of, set *section, int fix) { - static int abs_isection_no=0; + static int abs_isection_no = 0; symbol *s, *sprev; unsigned int init_addr, i; symbol **slist; - /* put all symbols in an array */ - if (!elementsInSet(section)) return; - slist = Safe_calloc(elementsInSet(section), sizeof(symbol *)); - s = slist[0]; i = 0; - for(sprev = setFirstItem(section); sprev; sprev = setNextItem(section)) { - slist[i] = sprev; i++; - } - - if(!i) { - if(slist)Safe_free(slist); - return; - } + /* put all symbols in an array */ + if (!elementsInSet (section)) + return; - /* sort symbols according to their address */ - qsort(slist, i, sizeof(symbol *), symCompare); + slist = Safe_calloc (elementsInSet (section), sizeof (symbol *)); + s = slist[0]; + i = 0; + for (sprev = setFirstItem (section); sprev; sprev = setNextItem (section)) + { + slist[i] = sprev; + i++; + } // for - pic16_initDB(); + if (!i) + { + if (slist) + Safe_free (slist); - if(!fix) { - fprintf(of, "\n\n\tidata\n"); - for(s = setFirstItem(section); s; s = setNextItem(section)) { + return; + } // if - if(s->ival) { - fprintf(of, "%s", s->rname); - pic16_printIval(s, s->type, s->ival, 'f', (void *)of); - pic16_flushDB('f', (void *)of); - } else { - if (IS_ARRAY (s->type) && IS_CHAR (s->type->next) - && SPEC_CVAL (s->etype).v_char) { + /* sort symbols according to their address */ + qsort (slist, i, sizeof (symbol *), symCompare); -// fprintf(stderr, "%s:%d printing code string from %s\n", __FILE__, __LINE__, s->rname); - pic16_pCodeConstString(s->rname , SPEC_CVAL (s->etype).v_char); - } else { - assert(0); - } - } + pic16_initDB (); + if (!fix) + { + fprintf (of, "\n\n\tidata\n"); + for (s = setFirstItem (section); s; s = setNextItem (section)) + { + if (s->ival) + { + fprintf (of, "%s", s->rname); + pic16_printIval (s, s->type, s->ival, 'f', (void *)of); + pic16_flushDB ('f', (void *)of); + } + else + { + if (IS_ARRAY (s->type) && IS_CHAR (s->type->next) + && SPEC_CVAL (s->etype).v_char) + { + //fprintf (stderr, "%s:%d printing code string from %s\n", __FILE__, __LINE__, s->rname); + pic16_pCodeConstString (s->rname , SPEC_CVAL (s->etype).v_char, getSize (s->type)); } - } else { - unsigned int j=0; - symbol *s1; + else + { + assert (0); + } // if + } // if + } // for + } + else + { + unsigned int j = 0; + symbol *s1; - sprev = NULL; - init_addr = SPEC_ADDR(slist[j]->etype); - fprintf(of, "\n\nistat_%s_%02d\tidata\t0X%04X\n", moduleName, abs_isection_no++, init_addr); + sprev = NULL; + init_addr = SPEC_ADDR (slist[j]->etype); + fprintf (of, "\n\nistat_%s_%02d\tidata\t0X%04X\n", moduleName, abs_isection_no++, init_addr); - for(j=0;jetype); + init_addr = SPEC_ADDR (s->etype); - if(sprev && (init_addr > (SPEC_ADDR(sprev->etype) + getSize(sprev->etype)))) { - fprintf(of, "\nistat_%s_%02d\tidata\t0X%04X\n", moduleName, abs_isection_no++, init_addr); - } + if (sprev && (init_addr > (SPEC_ADDR (sprev->etype) + getSize (sprev->etype)))) + fprintf(of, "\nistat_%s_%02d\tidata\t0X%04X\n", moduleName, abs_isection_no++, init_addr); - if(s->ival) { - fprintf(of, "%s", s->rname); - pic16_printIval(s, s->type, s->ival, 'f', (void *)of); - pic16_flushDB('f', (void *)of); - } else { - if (IS_ARRAY (s->type) && IS_CHAR (s->type->next) - && SPEC_CVAL (s->etype).v_char) { - -// fprintf(stderr, "%s:%d printing code string from %s\n", __FILE__, __LINE__, s->rname); - pic16_pCodeConstString(s->rname , SPEC_CVAL (s->etype).v_char); - } else { - assert(0); - } - } + if (s->ival) + { + fprintf (of, "%s", s->rname); + pic16_printIval (s, s->type, s->ival, 'f', (void *)of); + pic16_flushDB ('f', (void *)of); + } + else + { + if (IS_ARRAY (s->type) && IS_CHAR (s->type->next) + && SPEC_CVAL (s->etype).v_char) + { + //fprintf (stderr, "%s:%d printing code string from %s\n", __FILE__, __LINE__, s->rname); + pic16_pCodeConstString (s->rname , SPEC_CVAL (s->etype).v_char, getSize (s->type)); + } + else + { + assert (0); + } // if + } // if + sprev = s; + } // for + } // if - sprev = s; - } - } - Safe_free(slist); + Safe_free (slist); } - -void pic16_dump_int_registers(FILE *of, set *section) +void +pic16_dump_int_registers (FILE *of, set *section) { regs *r, *rprev; int i; regs **rlist; - /* put all symbols in an array */ - if (!elementsInSet(section)) return; - rlist = Safe_calloc(elementsInSet(section), sizeof(regs *)); - r = rlist[0]; i = 0; - for(rprev = setFirstItem(section); rprev; rprev = setNextItem(section)) { - rlist[i] = rprev; i++; - } + /* put all symbols in an array */ + if (!elementsInSet (section)) + return; - /* sort symbols according to their address */ - qsort(rlist, elementsInSet(section), sizeof(regs *), regCompare); + rlist = Safe_calloc (elementsInSet (section), sizeof (regs *)); + r = rlist[0]; + i = 0; + for (rprev = setFirstItem (section); rprev; rprev = setNextItem (section)) + { + rlist[i] = rprev; + i++; + } // for - if(!i) { - if(rlist)Safe_free(rlist); - return; - } + if (!i) + { + if (rlist) + Safe_free (rlist); - fprintf(of, "\n\n; Internal registers\n"); + return; + } // if - fprintf(of, "%s\tudata_ovr\t0x0000\n", ".registers"); - for(r = setFirstItem(section); r; r = setNextItem(section)) { - fprintf(of, "%s\tres\t%d\n", r->name, r->size); - statistics.intsize += r->size; - } + /* sort symbols according to their address */ + qsort (rlist, i, sizeof (regs *), regCompare); - Safe_free(rlist); + fprintf (of, "\n\n; Internal registers\n"); + + fprintf (of, "%s\tudata_ovr\t0x0000\n", ".registers"); + for (r = setFirstItem (section); r; r = setNextItem (section)) + { + fprintf (of, "%s\tres\t%d\n", r->name, r->size); + statistics.intsize += r->size; + } // for + + Safe_free (rlist); } /** @@ -483,22 +548,25 @@ get_line (FILE *file) static char * strip_comment (char *line) { - char *l = line; - char c; + char *l = line; + char c; - if (!line) { - return (line); + if (!line) + { + return (line); } // if - while (0 != (c = *l)) { - if ('#' == c) { - *l = 0; - return (line); + while (0 != (c = *l)) + { + if ('#' == c) + { + *l = 0; + return (line); } // if - l++; + l++; } // while - return (line); + return (line); } /** @@ -524,192 +592,266 @@ strip_comment (char *line) static PIC16_device * pic16_find_device(const char *name) { - const char *path; - char buffer[PATH_MAX]; - char *line, *key; - const char *sep = " \t\n\r"; - FILE *f = NULL; - PIC16_device *d = NULL, *template; - PIC16_device *head = NULL, *tail = NULL; - set *_sets[] = { userIncDirsSet, includeDirsSet }; - set **sets = &_sets[0]; - int lineno = 0; - int res, i; - int val[3]; - - if (!devices) { - //printf("%s: searching %s\n", __func__, DEVICE_FILE_NAME); - - // locate the specification file in the include search paths - for (i = 0; (NULL == f) && (i < 2); i++) { - for (path = setFirstItem(sets[i]); - (NULL == f) && path; - path = setNextItem(sets[i])) + const char *path; + char buffer[PATH_MAX]; + char *line, *key; + const char *sep = " \t\n\r"; + FILE *f = NULL; + PIC16_device *d = NULL, *template; + PIC16_device *head = NULL, *tail = NULL; + set *_sets[] = { userIncDirsSet, includeDirsSet }; + set **sets = &_sets[0]; + int lineno = 0; + int res, i; + int val[4]; + + if (!devices) + { + //printf("%s: searching %s\n", __func__, DEVICE_FILE_NAME); + + // locate the specification file in the include search paths + for (i = 0; (NULL == f) && (i < 2); i++) + { + for (path = setFirstItem(sets[i]); + (NULL == f) && path; + path = setNextItem(sets[i])) { - SNPRINTF(&buffer[0], PATH_MAX, "%s%s%s", - path, DIR_SEPARATOR_STRING, DEVICE_FILE_NAME); - //printf("%s: checking %s\n", __func__, &buffer[0]); - f = fopen(&buffer[0], "r"); + SNPRINTF(&buffer[0], PATH_MAX, "%s%s%s", + path, DIR_SEPARATOR_STRING, DEVICE_FILE_NAME); + //printf("%s: checking %s\n", __func__, &buffer[0]); + f = fopen(&buffer[0], "r"); } // for - } // while + } // for } // if - if (devices) { - // list already set up, nothing to do - } else if (NULL == f) { - fprintf(stderr, "ERROR: device list %s not found, specify its path via -I\n", DEVICE_FILE_NAME); - d = &default_device; - } else { - // parse the specification file and construct a linked list of - // supported devices - d = NULL; - while (NULL != (line = get_line(f))) { - strip_comment(line); - //printf("%s: read %s\n", __func__, line); - lineno++; - key = strtok(line, sep); - if (!key) { - // empty line---ignore - } else if (0 == strcmp(key, "name")) { - // name %s - if (d) { - if (tail) { - tail->next = d; - } else { - head = d; + if (devices) + { + // list already set up, nothing to do + } + else if (NULL == f) + { + fprintf(stderr, "ERROR: device list %s not found, specify its path via -I\n", + DEVICE_FILE_NAME); + d = &default_device; + } + else + { + // parse the specification file and construct a linked list of + // supported devices + d = NULL; + while (NULL != (line = get_line(f))) + { + strip_comment(line); + //printf("%s: read %s\n", __func__, line); + lineno++; + key = strtok(line, sep); + if (!key) + { + // empty line---ignore + } + else if (0 == strcmp(key, "name")) + { + // name %s + if (d) + { + if (tail) + { + tail->next = d; + } + else + { + head = d; } // if - tail = d; - d = NULL; + tail = d; + d = NULL; } // if - res = sscanf(&line[1+strlen(key)], " %16s", &buffer[3]); - if ((1 < res) || (3 > strlen(&buffer[3]))) { - SYNTAX(" (e.g., 18f452) expected."); - } else { - d = Safe_calloc(1, sizeof(PIC16_device)); - - // { "p18f452", "18f452", "pic18f452", "f452" } - buffer[0] = 'p'; - buffer[1] = 'i'; - buffer[2] = 'c'; - d->name[3] = Safe_strdup(&buffer[5]); - d->name[2] = Safe_strdup(&buffer[0]); - d->name[1] = Safe_strdup(&buffer[3]); - buffer[2] = 'p'; - d->name[0] = Safe_strdup(&buffer[2]); + res = sscanf(&line[1 + strlen(key)], " %16s", &buffer[3]); + if ((1 < res) || (3 > strlen(&buffer[3]))) + { + SYNTAX(" (e.g., 18f452) expected."); + } + else + { + d = Safe_calloc(1, sizeof(PIC16_device)); + + // { "p18f452", "18f452", "pic18f452", "f452" } + buffer[0] = 'p'; + buffer[1] = 'i'; + buffer[2] = 'c'; + d->name[3] = Safe_strdup(&buffer[5]); + d->name[2] = Safe_strdup(&buffer[0]); + d->name[1] = Safe_strdup(&buffer[3]); + buffer[2] = 'p'; + d->name[0] = Safe_strdup(&buffer[2]); } // if - } else if (0 == strcmp(key, "using")) { - // using %s - res = sscanf(&line[1+strlen(key)], " %16s", &buffer[0]); - if ((1 < res) || (3 > strlen(&buffer[3]))) { - SYNTAX(" (e.g., 18f452) expected."); - } else { - template = find_in_list(&buffer[0], head); - if (!template) { - SYNTAX(" (e.g., 18f452) expected."); - } else { - memcpy(&d->RAMsize, &template->RAMsize, - ((char *)&d->next) - ((char *)&d->RAMsize)); + } + else if (0 == strcmp(key, "using")) + { + // using %s + res = sscanf(&line[1 + strlen(key)], " %16s", &buffer[0]); + if ((1 < res) || (3 > strlen(&buffer[3]))) + { + SYNTAX(" (e.g., 18f452) expected."); + } + else + { + template = find_in_list(&buffer[0], head); + if (!template) + { + SYNTAX(" (e.g., 18f452) expected."); + } + else + { + memcpy(&d->RAMsize, &template->RAMsize, + ((char *)&d->next) - ((char *)&d->RAMsize)); } // if } // if - } else if (0 == strcmp(key, "ramsize")) { - // ramsize %i - res = sscanf(&line[1+strlen(key)], " %i", &val[0]); - if (res < 1) { - SYNTAX(" (e.g., 256) expected."); - } else { - d->RAMsize = val[0]; + } + else if (0 == strcmp(key, "ramsize")) + { + // ramsize %i + res = sscanf(&line[1 + strlen(key)], " %i", &val[0]); + if (res < 1) + { + SYNTAX(" (e.g., 256) expected."); + } + else + { + d->RAMsize = val[0]; } // if - } else if (0 == strcmp(key, "split")) { - // split %i - res = sscanf(&line[1+strlen(key)], " %i", &val[0]); - if (res < 1) { - SYNTAX(" (e.g., 0x80) expected."); - } else { - d->acsSplitOfs = val[0]; + } + else if (0 == strcmp(key, "split")) + { + // split %i + res = sscanf(&line[1 + strlen(key)], " %i", &val[0]); + if (res < 1) + { + SYNTAX(" (e.g., 0x80) expected."); + } + else + { + d->acsSplitOfs = val[0]; } // if - } else if (0 == strcmp(key, "configrange")) { - // configrange %i %i - res = sscanf(&line[1+strlen(key)], " %i %i", - &val[0], &val[1]); - if (res < 2) { - SYNTAX(" (e.g., 0xf60 0xfff) expected."); - } else { - d->cwInfo.confAddrStart = val[0]; - d->cwInfo.confAddrEnd = val[1]; + } + else if (0 == strcmp(key, "configrange")) + { + // configrange %i %i + res = sscanf(&line[1 + strlen(key)], " %i %i", + &val[0], &val[1]); + if (res < 2) + { + SYNTAX(" (e.g., 0xf60 0xfff) expected."); + } + else + { + d->cwInfo.confAddrStart = val[0]; + d->cwInfo.confAddrEnd = val[1]; } // if - } else if (0 == strcmp(key, "configword")) { - // configword %
i %i %i - res = sscanf(&line[1+strlen(key)], " %i %i %i", - &val[0], &val[1], &val[2]); - if (res < 3) { - SYNTAX("
(e.g., 0x200001 0x0f 0x07) expected."); - } else { - val[0] -= d->cwInfo.confAddrStart; - if ((val[0] < 0) - || (val[0] > (d->cwInfo.confAddrEnd - d->cwInfo.confAddrStart)) - || (val[0] >= CONFIGURATION_WORDS)) + } + else if (0 == strcmp(key, "configword")) + { + // configword %
i %i %i [%i] + res = sscanf(&line[1 + strlen(key)], " %i %i %i %i", + &val[0], &val[1], &val[2], &val[3]); + if (res < 3) + { + SYNTAX("
[] (e.g., 0x200001 0x0f 0x07) expected."); + } + else + { + val[0] -= d->cwInfo.confAddrStart; + if ((val[0] < 0) + || (val[0] > (d->cwInfo.confAddrEnd - d->cwInfo.confAddrStart)) + || (val[0] >= CONFIGURATION_WORDS)) + { + SYNTAX("address out of bounds."); + } + else { - SYNTAX("address out of bounds."); - } else { - d->cwInfo.crInfo[val[0]].mask = val[1]; - d->cwInfo.crInfo[val[0]].value = val[2]; + d->cwInfo.crInfo[val[0]].mask = val[1]; + d->cwInfo.crInfo[val[0]].value = val[2]; + d->cwInfo.crInfo[val[0]].andmask = 0; + if (res >= 4) + { + // apply extra mask (e.g., to disable XINST) + d->cwInfo.crInfo[val[0]].andmask = val[3]; + } // if } // if } // if - } else if (0 == strcmp(key, "idlocrange")) { - // idlocrange %i %i - res = sscanf(&line[1+strlen(key)], " %i %i", - &val[0], &val[1]); - if (res < 2) { - SYNTAX(" (e.g., 0xf60 0xfff) expected."); - } else { - d->idInfo.idAddrStart = val[0]; - d->idInfo.idAddrEnd = val[1]; + } + else if (0 == strcmp(key, "idlocrange")) + { + // idlocrange %i %i + res = sscanf(&line[1 + strlen(key)], " %i %i", + &val[0], &val[1]); + if (res < 2) + { + SYNTAX(" (e.g., 0xf60 0xfff) expected."); + } + else + { + d->idInfo.idAddrStart = val[0]; + d->idInfo.idAddrEnd = val[1]; } // if - } else if (0 == strcmp(key, "idword")) { - // idword %
i %i - res = sscanf(&line[1+strlen(key)], " %i %i", - &val[0], &val[1]); - if (res < 2) { - SYNTAX("
(e.g., 0x3fffff 0x00) expected."); - } else { - val[0] -= d->idInfo.idAddrStart; - if ((val[0] < 0) - || (val[0] > (d->idInfo.idAddrEnd - d->idInfo.idAddrStart)) - || (val[0] >= IDLOCATION_BYTES)) + } + else if (0 == strcmp(key, "idword")) + { + // idword %
i %i + res = sscanf(&line[1 + strlen(key)], " %i %i", + &val[0], &val[1]); + if (res < 2) + { + SYNTAX("
(e.g., 0x3fffff 0x00) expected."); + } + else + { + val[0] -= d->idInfo.idAddrStart; + if ((val[0] < 0) + || (val[0] > (d->idInfo.idAddrEnd - d->idInfo.idAddrStart)) + || (val[0] >= IDLOCATION_BYTES)) { - SYNTAX("address out of bounds."); - } else { - d->idInfo.irInfo[val[0]].value = val[1]; + SYNTAX("address out of bounds."); + } + else + { + d->idInfo.irInfo[val[0]].value = val[1]; } // if } // if - } else { - printf("%s: Invalid keyword in %s ignored: %s\n", - __func__, DEVICE_FILE_NAME, key); + } + else + { + printf("%s: Invalid keyword in %s ignored: %s\n", + __func__, DEVICE_FILE_NAME, key); } // if } // while - if (d) { - if (tail) { - tail->next = d; - } else { - head = d; + if (d) + { + if (tail) + { + tail->next = d; + } + else + { + head = d; } // if - tail = d; - d = NULL; + tail = d; + d = NULL; } // if - devices = head; + devices = head; - fclose(f); + fclose(f); } // if - d = find_in_list(name, devices); - if (!d) { - d = &default_device; + d = find_in_list(name, devices); + if (!d) + { + d = &default_device; } // if - return (d); + return (d); } /*-----------------------------------------------------------------* @@ -922,45 +1064,65 @@ void pic16_groupRegistersInSection(set *regset) * This routine will assign a value to that address. * *-----------------------------------------------------------------*/ -void pic16_assignConfigWordValue(int address, unsigned int value) +void +pic16_assignConfigWordValue(int address, unsigned int value) { int i; - for(i=0;icwInfo.confAddrEnd-pic16->cwInfo.confAddrStart+1;i++) { - if((address == pic16->cwInfo.confAddrStart+i) - && (pic16->cwInfo.crInfo[i].mask != -1) - && (pic16->cwInfo.crInfo[i].mask != 0)) { + for (i = 0; i < pic16->cwInfo.confAddrEnd - pic16->cwInfo.confAddrStart + 1; i++) + { + if ((address == pic16->cwInfo.confAddrStart + i) + && (pic16->cwInfo.crInfo[i].mask != -1) + && (pic16->cwInfo.crInfo[i].mask != 0)) + { #if 0 - fprintf(stderr, "setting location 0x%X to value 0x%x\tmask: 0x%x\ttest: 0x%x\n", - /*address*/ pic16->cwInfo.confAddrStart+i, (~value)&0xff, - pic16->cwInfo.crInfo[i].mask, - (pic16->cwInfo.crInfo[i].mask) & (~value)); + fprintf(stderr, "setting location 0x%x to value 0x%x, mask: 0x%x, test: 0x%x\n", + pic16->cwInfo.confAddrStart + i, + (~value) & 0xff, + pic16->cwInfo.crInfo[i].mask, + (pic16->cwInfo.crInfo[i].mask) & (~value)); #endif #if 0 - if((((pic16->cwInfo.crInfo[i].mask) & (~value))&0xff) != ((~value)&0xff)) { - fprintf(stderr, "%s:%d a wrong value has been given for configuration register 0x%x\n", - __FILE__, __LINE__, address); - return; - } + if ((((pic16->cwInfo.crInfo[i].mask) & (~value)) & 0xff) != ((~value) & 0xff)) + { + fprintf(stderr, "%s:%d a wrong value has been given for configuration register 0x%x\n", + __FILE__, __LINE__, address); + return; + } // if #endif - pic16->cwInfo.crInfo[i].value = value; - pic16->cwInfo.crInfo[i].emit = 1; - return; - } - } + pic16->cwInfo.crInfo[i].value = (value & 0xff); + if (pic16->cwInfo.crInfo[i].andmask + && ((value & 0xff) != (value & 0xff & pic16->cwInfo.crInfo[i].andmask))) + { + // apply andmask if effective + printf ("INFO: changing configuration word at 0x%x from 0x%x to 0x%x due to %s\n", + address, + (value & 0xff), + (value & 0xff & pic16->cwInfo.crInfo[i].andmask), + DEVICE_FILE_NAME); + pic16->cwInfo.crInfo[i].value &= pic16->cwInfo.crInfo[i].andmask; + } // if + pic16->cwInfo.crInfo[i].emit = 1; + return; + } // if + } // for } -void pic16_assignIdByteValue(int address, char value) +void +pic16_assignIdByteValue(int address, char value) { int i; - for(i=0;iidInfo.idAddrEnd-pic16->idInfo.idAddrStart+1;i++) { - if(address == pic16->idInfo.idAddrStart+i) { - pic16->idInfo.irInfo[i].value = value; - pic16->idInfo.irInfo[i].emit = 1; - } - } + for (i = 0; i < pic16->idInfo.idAddrEnd - pic16->idInfo.idAddrStart + 1; i++) + { + if (address == pic16->idInfo.idAddrStart + i) + { + pic16->idInfo.irInfo[i].value = value; + pic16->idInfo.irInfo[i].emit = 1; + } // if + } // for } +