From: maartenbrock Date: Tue, 19 Oct 2004 11:10:37 +0000 (+0000) Subject: * as/mcs51/lkarea.c: removed old K&R style, X-Git-Url: https://git.gag.com/?a=commitdiff_plain;h=d2da99feec099aa224e1db53bc5a1ed42ed51ec9;p=fw%2Fsdcc * as/mcs51/lkarea.c: removed old K&R style, (lnksect): changed check on boundary error, (lnksect2): changed check on boundary error, (lnksect2): extend XSTK to end of page if size = 1 * as/mcs51/lkmain.c: removed old K&R style, (Areas51): create l_IRAM symbol * as/mcs51/lkmem.c (summary2): added report on PSEG and XSTK * device/lib/Makefile.in: renamed model-mcs51-reentrant to model-mcs51-stack-auto, added model-mcs51-xstack-auto * device/lib/_mullong.c: added version to be compiled with xstack * device/lib/mcs51/crtclear.asm: clear only upto --iram-size * device/lib/mcs51/crtxclear.asm: clear pdata as well * device/lib/mcs51/crtxstack.asm: fixed comment * src/SDCCglue.c: maxInterrupts defaults to 0, (emitMaps): added pdata, (createInterruptVect): (re)moved default, (glue): added pdata, (glue): moved __start__xstack to XSTK with default size 1 * src/SDCCmain.c (parseCmdLine): automatically set options.intlong_rent and options.float_rent when options.stackAuto is set, (linkEdit): only write XDATA_NAME if provided on command line * src/SDCCmem.h, * src/SDCCmem.c: added pdata * src/port.h: added pdata_name to PORT * src/mcs51/gen.c (toBoolean): fixed for Acc use of aopGet, (saveRegisters, unsaveRegisters): removed usage of B, (genMinus): fixed accumulator clash, (genJumpTab): added comment, this needs another look * src/mcs51/gen.c: added check for "B in use" paranoia, added pushB() and popB() * src/mcs51/peeph.def: restart after 177.c so 177.a can get a second chance * src/avr/main.c, * src/ds390/main.c, * src/hc08/main.c, * src/mcs51/main.c, * src/pic/main.c, * src/pic16/main.c, * src/xa51/main.c, * src/z80/main.c: (reset_regparms) made void parameter explicit and added PSEG (PAG,XDATA) or NULL to port specifier * src/ds390/main.c (_ds390_genIVT): moved implemented default in here * src/mcs51/main.c (_mcs51_genIVT): moved implemented default in here, (_mcs51_genInitStartup): removed __start__xstack equ, (mcs51_port): moved xstack from XSEG (XDATA) to XSTK (PAG,XDATA) * src/pic16/device.c (pic16_dump_usection, pic16_dump_isection), * src/z80/gen.c (_rleAppend): fixed warnings * support/regression/tests/zeropad.c: added pdata test * .version: bumped to 2.4.6 git-svn-id: https://sdcc.svn.sourceforge.net/svnroot/sdcc/trunk/sdcc@3544 4a8a32a2-be11-0410-ad9d-d568d2c75423 --- diff --git a/.version b/.version index 59aa62c1..7bf4b6a8 100644 --- a/.version +++ b/.version @@ -1 +1 @@ -2.4.5 +2.4.6 diff --git a/ChangeLog b/ChangeLog index 80928845..4e524e21 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,55 @@ +2004-10-17 Maarten Brock + + * as/mcs51/lkarea.c: removed old K&R style, + (lnksect): changed check on boundary error, + (lnksect2): changed check on boundary error, + (lnksect2): extend XSTK to end of page if size = 1 + * as/mcs51/lkmain.c: removed old K&R style, + (Areas51): create l_IRAM symbol + * as/mcs51/lkmem.c (summary2): added report on PSEG and XSTK + * device/lib/Makefile.in: renamed model-mcs51-reentrant to + model-mcs51-stack-auto, added model-mcs51-xstack-auto + * device/lib/_mullong.c: added version to be compiled with xstack + * device/lib/mcs51/crtclear.asm: clear only upto --iram-size + * device/lib/mcs51/crtxclear.asm: clear pdata as well + * device/lib/mcs51/crtxstack.asm: fixed comment + * src/SDCCglue.c: maxInterrupts defaults to 0, + (emitMaps): added pdata, + (createInterruptVect): (re)moved default, + (glue): added pdata, + (glue): moved __start__xstack to XSTK with default size 1 + * src/SDCCmain.c (parseCmdLine): automatically set options.intlong_rent + and options.float_rent when options.stackAuto is set, + (linkEdit): only write XDATA_NAME if provided on command line + * src/SDCCmem.h, + * src/SDCCmem.c: added pdata + * src/port.h: added pdata_name to PORT + * src/mcs51/gen.c (toBoolean): fixed for Acc use of aopGet, + (saveRegisters, unsaveRegisters): removed usage of B, + (genMinus): fixed accumulator clash, + (genJumpTab): added comment, this needs another look + * src/mcs51/gen.c: added check for "B in use" paranoia, + added pushB() and popB() + * src/mcs51/peeph.def: restart after 177.c so 177.a can get a second + chance + * src/avr/main.c, + * src/ds390/main.c, + * src/hc08/main.c, + * src/mcs51/main.c, + * src/pic/main.c, + * src/pic16/main.c, + * src/xa51/main.c, + * src/z80/main.c: (reset_regparms) made void parameter explicit and + added PSEG (PAG,XDATA) or NULL to port specifier + * src/ds390/main.c (_ds390_genIVT): moved implemented default in here + * src/mcs51/main.c (_mcs51_genIVT): moved implemented default in here, + (_mcs51_genInitStartup): removed __start__xstack equ, + (mcs51_port): moved xstack from XSEG (XDATA) to XSTK (PAG,XDATA) + * src/pic16/device.c (pic16_dump_usection, pic16_dump_isection), + * src/z80/gen.c (_rleAppend): fixed warnings + * support/regression/tests/zeropad.c: added pdata test + * .version: bumped to 2.4.6 + 2004-10-17 Borut Razem * support/scripts/sdcc.nsi: cross compiling of WIN32 setup.exe on Linux diff --git a/as/mcs51/lkarea.c b/as/mcs51/lkarea.c index 693b5d49..07b29fc1 100644 --- a/as/mcs51/lkarea.c +++ b/as/mcs51/lkarea.c @@ -8,7 +8,7 @@ * 721 Berkeley St. * Kent, Ohio 44240 * - * 3-Nov-97 JLH: + * 3-Nov-97 JLH: * - change lkparea to use a_type == 0 as "virgin area" flag * 02-Apr-98 JLH: add code to link 8051 data spaces */ @@ -17,77 +17,77 @@ #include #include "aslink.h" -/*)Module lkarea.c +/*)Module lkarea.c * - * The module lkarea.c contains the functions which - * create and link together all area definitions read - * from the .rel file(s). + * The module lkarea.c contains the functions which + * create and link together all area definitions read + * from the .rel file(s). * - * lkarea.c contains the following functions: - * VOID lnkarea() - * VOID lnksect() - * VOID lkparea() - * VOID newarea() + * lkarea.c contains the following functions: + * VOID lnkarea() + * VOID lnksect() + * VOID lkparea() + * VOID newarea() * - * lkarea.c contains no global variables. + * lkarea.c contains no global variables. */ -/*)Function VOID newarea() - * - * The function newarea() creates and/or modifies area - * and areax structures for each A directive read from - * the .rel file(s). The function lkparea() is called - * to find tha area structure associated with this name. - * If the area does not yet exist then a new area - * structure is created and linked to any existing - * linked area structures. The area flags are copied - * into the area flag variable. For each occurence of - * an A directive an areax structure is created and - * linked to the areax structures associated with this - * area. The size of this area section is placed into - * the areax structure. The flag value for all subsequent - * area definitions for the same area are compared and - * flagged as an error if they are not identical. - * The areax structure created for every occurence of - * an A directive is loaded with a pointer to the base - * area structure and a pointer to the associated - * head structure. And finally, a pointer to this - * areax structure is loaded into the list of areax - * structures in the head structure. Refer to lkdata.c - * for details of the structures and their linkage. - * - * local variables: - * areax **halp pointer to an array of pointers - * int i counter, loop variable, value - * char id[] id string - * int narea number of areas in this head structure - * areax * taxp pointer to an areax structure - * to areax structures - * - * global variables: - * area *ap Pointer to the current - * area structure - * areax *axp Pointer to the current - * areax structure - * head *hp Pointer to the current - * head structure - * int lkerr error flag - * - * functions called: - * Addr_T eval() lkeval.c - * VOID exit() c_library - * int fprintf() c_library - * VOID getid() lklex.c - * VOID lkparea() lkarea.c - * VOID skip() lklex.c - * - * side effects: - * The area and areax structures are created and - * linked with the appropriate head structures. - * Failure to allocate area or areax structure - * space will terminate the linker. Other internal - * errors most likely caused by corrupted .rel - * files will also terminate the linker. +/*)Function VOID newarea() + * + * The function newarea() creates and/or modifies area + * and areax structures for each A directive read from + * the .rel file(s). The function lkparea() is called + * to find tha area structure associated with this name. + * If the area does not yet exist then a new area + * structure is created and linked to any existing + * linked area structures. The area flags are copied + * into the area flag variable. For each occurence of + * an A directive an areax structure is created and + * linked to the areax structures associated with this + * area. The size of this area section is placed into + * the areax structure. The flag value for all subsequent + * area definitions for the same area are compared and + * flagged as an error if they are not identical. + * The areax structure created for every occurence of + * an A directive is loaded with a pointer to the base + * area structure and a pointer to the associated + * head structure. And finally, a pointer to this + * areax structure is loaded into the list of areax + * structures in the head structure. Refer to lkdata.c + * for details of the structures and their linkage. + * + * local variables: + * areax **halp pointer to an array of pointers + * int i counter, loop variable, value + * char id[] id string + * int narea number of areas in this head structure + * areax * taxp pointer to an areax structure + * to areax structures + * + * global variables: + * area *ap Pointer to the current + * area structure + * areax *axp Pointer to the current + * areax structure + * head *hp Pointer to the current + * head structure + * int lkerr error flag + * + * functions called: + * Addr_T eval() lkeval.c + * VOID exit() c_library + * int fprintf() c_library + * VOID getid() lklex.c + * VOID lkparea() lkarea.c + * VOID skip() lklex.c + * + * side effects: + * The area and areax structures are created and + * linked with the appropriate head structures. + * Failure to allocate area or areax structure + * space will terminate the linker. Other internal + * errors most likely caused by corrupted .rel + * files will also terminate the linker. */ /* @@ -103,211 +103,210 @@ VOID newarea() { - register int i, narea; - struct areax *taxp; - struct areax **halp; - char id[NCPS]; - - /* - * Create Area entry - */ - getid(id, -1); - lkparea(id); - /* - * Evaluate area size - */ - skip(-1); - axp->a_size = eval(); - /* - * Evaluate flags - */ - skip(-1); - i = 0; - taxp = ap->a_axp; - while (taxp->a_axp) { - ++i; - taxp = taxp->a_axp; - } - if (i == 0) { - ap->a_flag = eval(); - } else { - i = eval(); -/* if (i && (ap->a_flag != i)) { */ -/* fprintf(stderr, "Conflicting flags in area %8s\n", id); */ -/* lkerr++; */ -/* } */ - } - /* - * Place pointer in header area list - */ - if (headp == NULL) { - fprintf(stderr, "No header defined\n"); - lkexit(1); - } - narea = hp->h_narea; - halp = hp->a_list; - for (i=0; i < narea ;++i) { - if (halp[i] == NULL) { - halp[i] = taxp; - return; - } - } - fprintf(stderr, "Header area list overflow\n"); - lkexit(1); + register int i, narea; + struct areax *taxp; + struct areax **halp; + char id[NCPS]; + + /* + * Create Area entry + */ + getid(id, -1); + lkparea(id); + /* + * Evaluate area size + */ + skip(-1); + axp->a_size = eval(); + /* + * Evaluate flags + */ + skip(-1); + i = 0; + taxp = ap->a_axp; + while (taxp->a_axp) { + ++i; + taxp = taxp->a_axp; + } + if (i == 0) { + ap->a_flag = eval(); + } else { + i = eval(); +/* if (i && (ap->a_flag != i)) { */ +/* fprintf(stderr, "Conflicting flags in area %8s\n", id); */ +/* lkerr++; */ +/* } */ + } + /* + * Place pointer in header area list + */ + if (headp == NULL) { + fprintf(stderr, "No header defined\n"); + lkexit(1); + } + narea = hp->h_narea; + halp = hp->a_list; + for (i=0; i < narea ;++i) { + if (halp[i] == NULL) { + halp[i] = taxp; + return; + } + } + fprintf(stderr, "Header area list overflow\n"); + lkexit(1); } -/*)Function VOID lkparea(id) - * - * char * id pointer to the area name string - * - * The function lkparea() searches the linked area structures - * for a name match. If the name is not found then an area - * structure is created. An areax structure is created and - * appended to the areax structures linked to the area structure. - * The associated base area and head structure pointers are - * loaded into the areax structure. - * - * local variables: - * area * tap pointer to an area structure - * areax * taxp pointer to an areax structure - * - * global variables: - * area *ap Pointer to the current - * area structure - * area *areap The pointer to the first - * area structure of a linked list - * areax *axp Pointer to the current - * areax structure - * - * functions called: - * VOID * new() lksym() - * char * strcpy() c_library - * int symeq() lksym.c - * - * side effects: - * Area and/or areax structures are created. - * Failure to allocate space for created structures - * will terminate the linker. +/*)Function VOID lkparea(id) + * + * char * id pointer to the area name string + * + * The function lkparea() searches the linked area structures + * for a name match. If the name is not found then an area + * structure is created. An areax structure is created and + * appended to the areax structures linked to the area structure. + * The associated base area and head structure pointers are + * loaded into the areax structure. + * + * local variables: + * area * tap pointer to an area structure + * areax * taxp pointer to an areax structure + * + * global variables: + * area *ap Pointer to the current + * area structure + * area *areap The pointer to the first + * area structure of a linked list + * areax *axp Pointer to the current + * areax structure + * + * functions called: + * VOID * new() lksym() + * char * strcpy() c_library + * int symeq() lksym.c + * + * side effects: + * Area and/or areax structures are created. + * Failure to allocate space for created structures + * will terminate the linker. */ VOID -lkparea(id) -char *id; +lkparea(char *id) { - register struct area *tap; - register struct areax *taxp; - - ap = areap; - axp = (struct areax *) new (sizeof(struct areax)); - while (ap) { - if (symeq(id, ap->a_id)) { - taxp = ap->a_axp; - while (taxp->a_axp) - taxp = taxp->a_axp; - taxp->a_axp = axp; - axp->a_bap = ap; - axp->a_bhp = hp; - return; - } - ap = ap->a_ap; - } - ap = (struct area *) new (sizeof(struct area)); - if (areap == NULL) { - areap = ap; - } else { - tap = areap; - while (tap->a_ap) - tap = tap->a_ap; - tap->a_ap = ap; - } - ap->a_axp = axp; - axp->a_bap = ap; - axp->a_bhp = hp; - strncpy(ap->a_id, id, NCPS); - ap->a_addr = 0; + register struct area *tap; + register struct areax *taxp; + + ap = areap; + axp = (struct areax *) new (sizeof(struct areax)); + while (ap) { + if (symeq(id, ap->a_id)) { + taxp = ap->a_axp; + while (taxp->a_axp) + taxp = taxp->a_axp; + taxp->a_axp = axp; + axp->a_bap = ap; + axp->a_bhp = hp; + return; + } + ap = ap->a_ap; + } + ap = (struct area *) new (sizeof(struct area)); + if (areap == NULL) { + areap = ap; + } else { + tap = areap; + while (tap->a_ap) + tap = tap->a_ap; + tap->a_ap = ap; + } + ap->a_axp = axp; + axp->a_bap = ap; + axp->a_bhp = hp; + strncpy(ap->a_id, id, NCPS); + ap->a_addr = 0; } -/*)Function VOID lnkarea() - * - * The function lnkarea() resolves all area addresses. - * The function evaluates each area structure (and all - * the associated areax structures) in sequence. The - * linking process supports four (4) possible area types: - * - * ABS/OVR - All sections (each individual areax - * section) starts at the identical base - * area address overlaying all other - * areax sections for this area. The - * size of the area is largest of the area - * sections. - * - * ABS/CON - All sections (each individual areax - * section) are concatenated with the - * first section starting at the base - * area address. The size of the area - * is the sum of the section sizes. - * - * NOTE: Multiple absolute (ABS) areas are - * never concatenated with each other, - * thus absolute area A and absolute area - * B will overlay each other if they begin - * at the same location (the default is - * always address 0 for absolute areas). - * - * REL/OVR - All sections (each individual areax - * section) starts at the identical base - * area address overlaying all other - * areax sections for this area. The - * size of the area is largest of the area - * sections. - * - * REL/CON - All sections (each individual areax - * section) are concatenated with the - * first section starting at the base - * area address. The size of the area - * is the sum of the section sizes. - * - * NOTE: Relocatable (REL) areas ae always concatenated - * with each other, thus relocatable area B - * (defined after area A) will follow - * relocatable area A independent of the - * starting address of area A. Within a - * specific area each areax section may be - * overlayed or concatenated with other - * areax sections. - * - * - * If a base address for an area is specified then the - * area will start at that address. Any relocatable - * areas defined subsequently will be concatenated to the - * previous relocatable area if it does not have a base - * address specified. - * - * The names s_ and l_ are created to - * define the starting address and length of each area. - * - * local variables: - * Addr_T rloc ;current relocation address - * char temp[] ;temporary string - * struct symbol *sp ;symbol structure - * - * global variables: - * area *ap Pointer to the current - * area structure - * area *areap The pointer to the first - * area structure of a linked list - * - * functions called: - * int fprintf() c_library - * VOID lnksect() lkarea.c - * symbol *lkpsym() lksysm.c - * char * strncpy() c_library - * int symeq() lksysm.c - * - * side effects: - * All area and areax addresses and sizes are - * determined and saved in their respective - * structures. +/*)Function VOID lnkarea() + * + * The function lnkarea() resolves all area addresses. + * The function evaluates each area structure (and all + * the associated areax structures) in sequence. The + * linking process supports four (4) possible area types: + * + * ABS/OVR - All sections (each individual areax + * section) starts at the identical base + * area address overlaying all other + * areax sections for this area. The + * size of the area is largest of the area + * sections. + * + * ABS/CON - All sections (each individual areax + * section) are concatenated with the + * first section starting at the base + * area address. The size of the area + * is the sum of the section sizes. + * + * NOTE: Multiple absolute (ABS) areas are + * never concatenated with each other, + * thus absolute area A and absolute area + * B will overlay each other if they begin + * at the same location (the default is + * always address 0 for absolute areas). + * + * REL/OVR - All sections (each individual areax + * section) starts at the identical base + * area address overlaying all other + * areax sections for this area. The + * size of the area is largest of the area + * sections. + * + * REL/CON - All sections (each individual areax + * section) are concatenated with the + * first section starting at the base + * area address. The size of the area + * is the sum of the section sizes. + * + * NOTE: Relocatable (REL) areas are always concatenated + * with each other, thus relocatable area B + * (defined after area A) will follow + * relocatable area A independent of the + * starting address of area A. Within a + * specific area each areax section may be + * overlayed or concatenated with other + * areax sections. + * + * + * If a base address for an area is specified then the + * area will start at that address. Any relocatable + * areas defined subsequently will be concatenated to the + * previous relocatable area if it does not have a base + * address specified. + * + * The names s_ and l_ are created to + * define the starting address and length of each area. + * + * local variables: + * Addr_T rloc ;current relocation address + * char temp[] ;temporary string + * struct symbol *sp ;symbol structure + * + * global variables: + * area *ap Pointer to the current + * area structure + * area *areap The pointer to the first + * area structure of a linked list + * + * functions called: + * int fprintf() c_library + * VOID lnksect() lkarea.c + * symbol *lkpsym() lksym.c + * char * strncpy() c_library + * int symeq() lksym.c + * + * side effects: + * All area and areax addresses and sizes are + * determined and saved in their respective + * structures. */ /* @@ -316,24 +315,24 @@ char *id; VOID lnkarea() { - Addr_T rloc[4]; - int locIndex; - char temp[NCPS]; - struct sym *sp; - /*JCF: used to save the REG_BANK_[0-3] and SBIT_BYTES area pointers*/ - struct area *ta[5]; - int j; - - rloc[0] = rloc[1] = rloc[2] = rloc[3] = 0; - ap = areap; - while (ap) { - if (ap->a_flag&A_ABS) { - /* - * Absolute sections - */ - lnksect(ap); - } else { - /* Determine memory space */ + Addr_T rloc[4]; + int locIndex; + char temp[NCPS]; + struct sym *sp; + /*JCF: used to save the REG_BANK_[0-3] and SBIT_BYTES area pointers*/ + struct area *ta[5]; + int j; + + rloc[0] = rloc[1] = rloc[2] = rloc[3] = 0; + ap = areap; + while (ap) { + if (ap->a_flag&A_ABS) { + /* + * Absolute sections + */ + lnksect(ap); + } else { + /* Determine memory space */ locIndex = 0; if (ap->a_flag & A_CODE) { locIndex = 1; @@ -344,135 +343,143 @@ lnkarea() if (ap->a_flag & A_BIT) { locIndex = 3; } - /* - * Relocatable sections - */ - if (ap->a_type == 0) { /* JLH */ - ap->a_addr = rloc[ locIndex ]; - ap->a_type = 1; - } - lnksect(ap); - rloc[ locIndex ] = ap->a_addr + ap->a_size; - } - - /* - * Create symbols called: - * s_ the start address of the area - * l_ the length of the area - */ - - if (! symeq(ap->a_id, _abs_)) { - strncpy(temp+2,ap->a_id,NCPS-2); - *(temp+1) = '_'; - - *temp = 's'; - sp = lkpsym(temp, 1); - sp->s_addr = ap->a_addr ; - /* sp->s_axp = ap->a_axp; JLH: was NULL; */ - sp->s_type |= S_DEF; - - *temp = 'l'; - sp = lkpsym(temp, 1); - sp->s_addr = ap->a_size; - sp->s_axp = NULL; - sp->s_type |= S_DEF; - - } - - /*JCF: Since area BSEG is defined just before BSEG_BYTES, use the bit size of BSEG - to compute the byte size of BSEG_BYTES: */ - if (!strcmp(ap->a_id, "BSEG")) { - ap->a_ap->a_axp->a_size=(ap->a_addr/8)+((ap->a_size+7)/8); /*Bits to bytes*/ - } - else if (!strcmp(ap->a_id, "REG_BANK_0")) ta[0]=ap; - else if (!strcmp(ap->a_id, "REG_BANK_1")) ta[1]=ap; - else if (!strcmp(ap->a_id, "REG_BANK_2")) ta[2]=ap; - else if (!strcmp(ap->a_id, "REG_BANK_3")) ta[3]=ap; - else if (!strcmp(ap->a_id, "BSEG_BYTES")) - { - ta[4]=ap; - for(j=4; j>1; j--) - { - /*If upper register banks are not used roll back the rellocation counter*/ - if ( (ta[j]->a_size==0) && (ta[j-1]->a_size==0) ) - { - rloc[0]-=8; - } - else break; - } - } - ap = ap->a_ap; - } + /* + * Relocatable sections + */ + if (ap->a_type == 0) { /* JLH */ + ap->a_addr = rloc[ locIndex ]; + ap->a_type = 1; + } + lnksect(ap); + rloc[ locIndex ] = ap->a_addr + ap->a_size; + } + + /* + * Create symbols called: + * s_ the start address of the area + * l_ the length of the area + */ + + if (! symeq(ap->a_id, _abs_)) { + strncpy(temp+2,ap->a_id,NCPS-2); + *(temp+1) = '_'; + + *temp = 's'; + sp = lkpsym(temp, 1); + sp->s_addr = ap->a_addr ; + /* sp->s_axp = ap->a_axp; JLH: was NULL; */ + sp->s_type |= S_DEF; + + *temp = 'l'; + sp = lkpsym(temp, 1); + sp->s_addr = ap->a_size; + sp->s_axp = NULL; + sp->s_type |= S_DEF; + + } + + /*JCF: Since area BSEG is defined just before BSEG_BYTES, use the bit size of BSEG + to compute the byte size of BSEG_BYTES: */ + if (!strcmp(ap->a_id, "BSEG")) { + ap->a_ap->a_axp->a_size=(ap->a_addr/8)+((ap->a_size+7)/8); /*Bits to bytes*/ + } + else if (!strcmp(ap->a_id, "REG_BANK_0")) ta[0]=ap; + else if (!strcmp(ap->a_id, "REG_BANK_1")) ta[1]=ap; + else if (!strcmp(ap->a_id, "REG_BANK_2")) ta[2]=ap; + else if (!strcmp(ap->a_id, "REG_BANK_3")) ta[3]=ap; + else if (!strcmp(ap->a_id, "BSEG_BYTES")) + { + ta[4]=ap; + for(j=4; j>1; j--) + { + /*If upper register banks are not used roll back the relocation counter*/ + if ( (ta[j]->a_size==0) && (ta[j-1]->a_size==0) ) + { + rloc[0]-=8; + } + else break; + } + } + ap = ap->a_ap; + } } -/*)Function VOID lnksect() +/*)Function VOID lnksect() * - * area * tap pointer to an area structure + * area * tap pointer to an area structure * - * The function lnksect() is the function called by - * lnkarea() to resolve the areax addresses. Refer - * to the function lnkarea() for more detail. Pageing - * boundary and length errors will be reported by this - * function. + * The function lnksect() is the function called by + * lnkarea() to resolve the areax addresses. Refer + * to the function lnkarea() for more detail. Pageing + * boundary and length errors will be reported by this + * function. * - * local variables: - * Addr_T size size of area - * Addr_T addr address of area - * areax * taxp pointer to an areax structure + * local variables: + * Addr_T size size of area + * Addr_T addr address of area + * areax * taxp pointer to an areax structure * - * global variables: - * int lkerr error flag + * global variables: + * int lkerr error flag * - * functions called: - * none + * functions called: + * none * - * side effects: - * All area and areax addresses and sizes area determined - * and linked into the structures. + * side effects: + * All area and areax addresses and sizes area determined + * and linked into the structures. */ VOID -lnksect(tap) -register struct area *tap; +lnksect(register struct area *tap) { - register Addr_T size, addr; - register struct areax *taxp; - - size = 0; - addr = tap->a_addr; - if ((tap->a_flag&A_PAG) && (addr & 0xFF)) { - fprintf(stderr, - "\n?ASlink-Warning-Paged Area %8s Boundary Error\n", tap->a_id); - lkerr++; - } - taxp = tap->a_axp; - if (tap->a_flag&A_OVR) { - /* - * Overlayed sections - */ - while (taxp) { - taxp->a_addr = addr; - if (taxp->a_size > size) - size = taxp->a_size; - taxp = taxp->a_axp; - } - } else { - /* - * Concatenated sections - */ - while (taxp) { - taxp->a_addr = addr; - addr += taxp->a_size; - size += taxp->a_size; - taxp = taxp->a_axp; - } - } - tap->a_size = size; - if ((tap->a_flag&A_PAG) && (size > 256)) { - fprintf(stderr, - "\n?ASlink-Warning-Paged Area %8s Length Error\n", tap->a_id); - lkerr++; - } + register Addr_T size, addr; + register struct areax *taxp; + + size = 0; + addr = tap->a_addr; +#if 0 + if ((tap->a_flag&A_PAG) && (addr & 0xFF)) { + fprintf(stderr, + "\n?ASlink-Warning-Paged Area %8s Boundary Error\n", tap->a_id); + lkerr++; + } +#endif + taxp = tap->a_axp; + if (tap->a_flag&A_OVR) { + /* + * Overlayed sections + */ + while (taxp) { + taxp->a_addr = addr; + if (taxp->a_size > size) + size = taxp->a_size; + taxp = taxp->a_axp; + } + } else { + /* + * Concatenated sections + */ + while (taxp) { + taxp->a_addr = addr; + addr += taxp->a_size; + size += taxp->a_size; + taxp = taxp->a_axp; + } + } + tap->a_size = size; + if ((tap->a_flag&A_PAG) && (size > 256)) { + fprintf(stderr, + "\n?ASlink-Warning-Paged Area %8s Length Error\n", tap->a_id); + lkerr++; + } + if ((tap->a_flag&A_PAG) && (tap->a_size) && + ((tap->a_addr & 0xFFFFFF00) != ((addr-1) & 0xFFFFFF00))) + { + fprintf(stderr, + "\n?ASlink-Warning-Paged Area %8s Boundary Error\n", tap->a_id); + lkerr++; + } } void lnksect2 (struct area *tap, int rloc); @@ -482,112 +489,112 @@ char idatamap[256]; VOID lnkarea2 (void) { Addr_T rloc[4]={0, 0, 0, 0}; - int locIndex; - char temp[NCPS]; - struct sym *sp; - int j; + int locIndex; + char temp[NCPS]; + struct sym *sp; + int j; struct area *dseg_ap=NULL; - struct sym *sp_dseg_s=NULL, *sp_dseg_l=NULL; + struct sym *sp_dseg_s=NULL, *sp_dseg_l=NULL; - for(j=0; j<256; j++) idatamap[j]=' '; + for(j=0; j<256; j++) idatamap[j]=' '; - ap = areap; - while (ap) - { - /* Determine memory space */ + ap = areap; + while (ap) + { + /* Determine memory space */ if (ap->a_flag & A_CODE) locIndex = 1; else if (ap->a_flag & A_XDATA) locIndex = 2; else if (ap->a_flag & A_BIT) locIndex = 3; else locIndex = 0; if (ap->a_flag&A_ABS) /* Absolute sections */ - { - lnksect2(ap, locIndex); - } - else /* Relocatable sections */ - { - if (ap->a_type == 0) + { + lnksect2(ap, locIndex); + } + else /* Relocatable sections */ + { + if (ap->a_type == 0) { - ap->a_addr=rloc[locIndex]; - ap->a_type=1; - } - - lnksect2(ap, locIndex); - rloc[locIndex] = ap->a_addr + ap->a_size; - } - - /* - * Create symbols called: - * s_ the start address of the area - * l_ the length of the area - */ - - if (! symeq(ap->a_id, _abs_)) - { - strncpy(temp+2,ap->a_id,NCPS-2); - *(temp+1) = '_'; - - *temp = 's'; - sp = lkpsym(temp, 1); - sp->s_addr = ap->a_addr ; - sp->s_type |= S_DEF; + ap->a_addr=rloc[locIndex]; + ap->a_type=1; + } + + lnksect2(ap, locIndex); + rloc[locIndex] = ap->a_addr + ap->a_size; + } + + /* + * Create symbols called: + * s_ the start address of the area + * l_ the length of the area + */ + + if (! symeq(ap->a_id, _abs_)) + { + strncpy(temp+2,ap->a_id,NCPS-2); + *(temp+1) = '_'; + + *temp = 's'; + sp = lkpsym(temp, 1); + sp->s_addr = ap->a_addr ; + sp->s_type |= S_DEF; if (!strcmp(ap->a_id, "DSEG")) sp_dseg_s=sp; - *temp = 'l'; - sp = lkpsym(temp, 1); - sp->s_addr = ap->a_size; - sp->s_axp = NULL; - sp->s_type |= S_DEF; + *temp = 'l'; + sp = lkpsym(temp, 1); + sp->s_addr = ap->a_size; + sp->s_axp = NULL; + sp->s_type |= S_DEF; if (!strcmp(ap->a_id, "DSEG")) sp_dseg_l=sp; - } - - /*Since area BSEG is defined just before BSEG_BYTES, use the bit size of BSEG - to compute the byte size of BSEG_BYTES: */ - if (!strcmp(ap->a_id, "BSEG")) + } + + /*Since area BSEG is defined just before BSEG_BYTES, use the bit size of BSEG + to compute the byte size of BSEG_BYTES: */ + if (!strcmp(ap->a_id, "BSEG")) { - ap->a_ap->a_axp->a_size=(ap->a_addr/8)+((ap->a_size+7)/8); /*Bits to bytes*/ - } + ap->a_ap->a_axp->a_size=(ap->a_addr/8)+((ap->a_size+7)/8); /*Bits to bytes*/ + } else if (!strcmp(ap->a_id, "DSEG")) { dseg_ap=ap; /*Need it later to set its correct size*/ } - ap = ap->a_ap; - } + ap = ap->a_ap; + } /*Compute the size of DSEG*/ - if(dseg_ap!=NULL) - { - dseg_ap->a_addr=0; - dseg_ap->a_size=0; - for(j=0; j<0x80; j++) if(idatamap[j]!=' ') dseg_ap->a_size++; - } + if(dseg_ap!=NULL) + { + dseg_ap->a_addr=0; + dseg_ap->a_size=0; + for(j=0; j<0x80; j++) if(idatamap[j]!=' ') dseg_ap->a_size++; + } if(sp_dseg_s!=NULL) sp_dseg_s->s_addr=0; if(sp_dseg_l!=NULL) sp_dseg_l->s_addr=dseg_ap->a_size; #if 0 /*Print the memory map*/ - fprintf(stderr, "Internal RAM layout:\n" + fprintf(stderr, "Internal RAM layout:\n" " 0 1 2 3 4 5 6 7 8 9 A B C D E F"); for(j=0; j<256; j++) - { - if(j%16==0) fprintf(stderr, "\n0x%02x:|", j); - fprintf(stderr, "%c|", idatamap[j]); - } - fprintf(stderr, "\n0-3:Reg Banks, a-z:Data, B:Bits, Q:Overlay, I:iData, S:Stack\n"); + { + if(j%16==0) fprintf(stderr, "\n0x%02x:|", j); + fprintf(stderr, "%c|", idatamap[j]); + } + fprintf(stderr, "\n0-3:Reg Banks, a-z:Data, B:Bits, Q:Overlay, I:iData, S:Stack\n"); #endif } void lnksect2 (struct area *tap, int rloc) { - register Addr_T size, addr; - register struct areax *taxp; - int j, k, ramlimit; + register Addr_T size, addr; + register struct areax *taxp; + int j, k, ramlimit; char fchar, dchar='a'; - char ErrMsg[]="?ASlink-Error-Could not get %d consecutive byte%s" + char ErrMsg[]="?ASlink-Error-Could not get %d consecutive byte%s" " in internal RAM for area %s.\n"; tap->a_unaloc=0; - + /*Notice that only ISEG and SSEG can be in the indirectly addressable internal RAM*/ if( (!strcmp(tap->a_id, "ISEG")) || (!strcmp(tap->a_id, "SSEG")) ) { @@ -598,24 +605,29 @@ void lnksect2 (struct area *tap, int rloc) } else { - ramlimit=0x80; + if((iram_size<=0)||(iram_size>0x80)) + ramlimit=0x80; + else + ramlimit=iram_size; } - size = 0; - addr = tap->a_addr; - if ((tap->a_flag&A_PAG) && (addr & 0xFF)) + size = 0; + addr = tap->a_addr; +#if 0 + if ((tap->a_flag&A_PAG) && (addr & 0xFF)) { - fprintf(stderr, - "\n?ASlink-Warning-Paged Area %8s Boundary Error\n", tap->a_id); - lkerr++; - } - taxp = tap->a_axp; + fprintf(stderr, + "\n?ASlink-Warning-Paged Area %8s Boundary Error\n", tap->a_id); + lkerr++; + } +#endif + taxp = tap->a_axp; /*Use a letter to identify each area in the internal RAM layout map*/ if(rloc==0) { /**/ if(!strcmp(tap->a_id, "DSEG")) - fchar='D'; /*It will be converted to letters 'a' to 'z' latter for each areax*/ + fchar='D'; /*It will be converted to letters 'a' to 'z' later for each areax*/ else if(!strcmp(tap->a_id, "ISEG")) fchar='I'; else if(!strcmp(tap->a_id, "SSEG")) @@ -640,7 +652,7 @@ void lnksect2 (struct area *tap, int rloc) fchar=' '; } - if (tap->a_flag&A_OVR) /* Overlayed sections */ + if (tap->a_flag&A_OVR) /* Overlayed sections */ { while (taxp) { @@ -675,7 +687,7 @@ void lnksect2 (struct area *tap, int rloc) stacksize=taxp->a_size; } - /*If more space required, release the previously allocated areax in + /*If more space required, release the previously allocated areax in internal RAM and search for a bigger one*/ if((int)taxp->a_size>size) { @@ -683,7 +695,7 @@ void lnksect2 (struct area *tap, int rloc) for(j=0; j=0) addr=j+1; } } - + /*Mark the memory used for overlay*/ if(k==(int)taxp->a_size) { @@ -720,32 +732,32 @@ void lnksect2 (struct area *tap, int rloc) lkerr++; } } - + for(j=0; ja_addr=addr; - taxp->a_addr=addr; + taxp->a_addr=addr; break; } } } else /*Overlay areas not in internal ram*/ { - taxp->a_addr = addr; - if (taxp->a_size > size) size = taxp->a_size; + taxp->a_addr = addr; + if (taxp->a_size > size) size = taxp->a_size; } taxp = taxp->a_axp; - } - } + } + } else /* Concatenated sections */ { - while (taxp) + while (taxp) { - if( (fchar=='D') || (fchar=='I') ) - { + if( (fchar=='D') || (fchar=='I') ) + { if(taxp->a_size) { /*Search for a space large enough in internal RAM for this areax*/ @@ -767,7 +779,7 @@ void lnksect2 (struct area *tap, int rloc) if(j>=0) addr=j+1; size=ramlimit-addr; } - + for(j=taxp->a_addr; (j<(int)(taxp->a_addr+taxp->a_size)) && (ja_size>0)&&(fchar=='D'))dchar++; @@ -777,14 +789,14 @@ void lnksect2 (struct area *tap, int rloc) { taxp->a_addr = addr; addr += taxp->a_size; - size += taxp->a_size; + size += taxp->a_size; tap->a_unaloc+=taxp->a_size; fprintf(stderr, ErrMsg, taxp->a_size, taxp->a_size>1?"s":"", tap->a_id); lkerr++; } } - taxp = taxp->a_axp; - } + taxp = taxp->a_axp; + } else if(fchar=='B') { if(taxp->a_size!=0) @@ -793,26 +805,37 @@ void lnksect2 (struct area *tap, int rloc) idatamap[j]=fchar; } - taxp->a_addr = addr; - addr += taxp->a_size; - size += taxp->a_size; - taxp = taxp->a_axp; + taxp->a_addr = addr; + addr += taxp->a_size; + size += taxp->a_size; + taxp = taxp->a_axp; } else /*For concatenated BIT, CODE, and XRAM areax's*/ { - taxp->a_addr = addr; - addr += taxp->a_size; - size += taxp->a_size; - taxp = taxp->a_axp; + if(!strcmp(tap->a_id, "XSTK") && (taxp->a_size == 1)) + { + taxp->a_size = 256-(addr & 0xFF); + } + taxp->a_addr = addr; + addr += taxp->a_size; + size += taxp->a_size; + taxp = taxp->a_axp; } - } - } - tap->a_size = size; - - if ((tap->a_flag&A_PAG) && (size > 256)) - { - fprintf(stderr, - "\n?ASlink-Warning-Paged Area %8s Length Error\n", tap->a_id); - lkerr++; - } + } + } + tap->a_size = size; + + if ((tap->a_flag&A_PAG) && (size > 256)) + { + fprintf(stderr, + "\n?ASlink-Warning-Paged Area %8s Length Error\n", tap->a_id); + lkerr++; + } + if ((tap->a_flag&A_PAG) && (tap->a_size) && + ((tap->a_addr & 0xFFFFFF00) != ((addr-1) & 0xFFFFFF00))) + { + fprintf(stderr, + "\n?ASlink-Warning-Paged Area %8s Boundary Error\n", tap->a_id); + lkerr++; + } } diff --git a/as/mcs51/lkmain.c b/as/mcs51/lkmain.c index 1ee7f26b..843f707c 100644 --- a/as/mcs51/lkmain.c +++ b/as/mcs51/lkmain.c @@ -10,7 +10,7 @@ * * 31-Oct-97 JLH: * - add jflag and jfp to control NoICE output file genration - * 3-Nov-97 JLH: + * 3-Nov-97 JLH: * - use a_type == 0 as "virgin area" flag: set == 1 if -b */ @@ -24,20 +24,20 @@ void Timer(int action, char * message) { - static double start, end, total=0.0; + static double start, end, total=0.0; static const double secs_per_tick = 1.0 / CLOCKS_PER_SEC; if(action==0) start=clock()*secs_per_tick; else if(action==1) { - end=clock() * secs_per_tick; - printf("%s \t%f seconds.\n", message, (end-start)); - total+=end-start; + end=clock() * secs_per_tick; + printf("%s \t%f seconds.\n", message, (end-start)); + total+=end-start; } else { - printf("Total time: \t%f seconds.\n", total); - total=0.0; + printf("Total time: \t%f seconds.\n", total); + total=0.0; } } #endif @@ -47,467 +47,471 @@ void Timer(int action, char * message) */ extern int unlink(const char *); -/*)Module lkmain.c - * - * The module lkmain.c contains the functions which - * (1) input the linker options, parameters, and specifications - * (2) perform a two pass link - * (3) produce the appropriate linked data output and/or - * link map file and/or relocated listing files. - * - * lkmain.c contains the following functions: - * FILE * afile(fn,ft,wf) - * VOID bassav() - * VOID gblsav() - * VOID link_main() - * VOID lkexit() - * VOID main(argc,argv) - * VOID map() - * int parse() - * VOID setbas() - * VOID setgbl() - * VOID usage() - * - * lkmain.c contains the following local variables: - * char * usetext[] array of pointers to the - * command option tect lines +/*)Module lkmain.c + * + * The module lkmain.c contains the functions which + * (1) input the linker options, parameters, and specifications + * (2) perform a two pass link + * (3) produce the appropriate linked data output and/or + * link map file and/or relocated listing files. + * + * lkmain.c contains the following functions: + * FILE * afile(fn,ft,wf) + * VOID bassav() + * VOID gblsav() + * VOID link_main() + * VOID lkexit() + * VOID main(argc,argv) + * VOID map() + * int parse() + * VOID setbas() + * VOID setgbl() + * VOID usage() + * + * lkmain.c contains the following local variables: + * char * usetext[] array of pointers to the + * command option tect lines * */ -/*JCF: Creates some of the default areas so they are allocated in the right order.*/ +/*JCF: Creates some of the default areas so they are allocated in the right order.*/ void Areas51 (void) { - char * rel[]={ - "XH", - "H 7 areas 0 global symbols", - "A _CODE size 0 flags 0", /*Each .rel has one, so...*/ - "A REG_BANK_0 size 0 flags 4", /*Register banks are overlayable*/ - "A REG_BANK_1 size 0 flags 4", - "A REG_BANK_2 size 0 flags 4", - "A REG_BANK_3 size 0 flags 4", - "A BSEG size 0 flags 80", /*BSEG must be just before BITS*/ - "A BSEG_BYTES size 0 flags 0", /*Size will be obtained from BSEG in lnkarea()*/ - "" - }; - + char * rel[]={ + "XH", + "H 7 areas 0 global symbols", + "A _CODE size 0 flags 0", /*Each .rel has one, so...*/ + "A REG_BANK_0 size 0 flags 4", /*Register banks are overlayable*/ + "A REG_BANK_1 size 0 flags 4", + "A REG_BANK_2 size 0 flags 4", + "A REG_BANK_3 size 0 flags 4", + "A BSEG size 0 flags 80", /*BSEG must be just before BITS*/ + "A BSEG_BYTES size 0 flags 0", /*Size will be obtained from BSEG in lnkarea()*/ + "" + }; + char * rel2[]={ - "XH", - "H B areas 0 global symbols", - "A _CODE size 0 flags 0", /*Each .rel has one, so...*/ - "A REG_BANK_0 size 0 flags 4", /*Register banks are overlayable*/ - "A REG_BANK_1 size 0 flags 4", - "A REG_BANK_2 size 0 flags 4", - "A REG_BANK_3 size 0 flags 4", - "A BSEG size 0 flags 80", /*BSEG must be just before BITS*/ - "A BSEG_BYTES size 0 flags 0", /*Size will be obtained from BSEG in lnkarea()*/ - "A DSEG size 0 flags 0", - "A OSEG size 0 flags 4", - "A ISEG size 0 flags 0", - "A SSEG size 0 flags 4", - "" - }; - int j; + "XH", + "H B areas 0 global symbols", + "A _CODE size 0 flags 0", /*Each .rel has one, so...*/ + "A REG_BANK_0 size 0 flags 4", /*Register banks are overlayable*/ + "A REG_BANK_1 size 0 flags 4", + "A REG_BANK_2 size 0 flags 4", + "A REG_BANK_3 size 0 flags 4", + "A BSEG size 0 flags 80", /*BSEG must be just before BITS*/ + "A BSEG_BYTES size 0 flags 0", /*Size will be obtained from BSEG in lnkarea()*/ + "A DSEG size 0 flags 0", + "A OSEG size 0 flags 4", + "A ISEG size 0 flags 0", + "A SSEG size 0 flags 4", + "" + }; + int j; + struct sym * sp; if(packflag) { - for (j=0; rel2[j][0]!=0; j++) - { - ip=rel2[j]; - link_main(); - } + for (j=0; rel2[j][0]!=0; j++) + { + ip=rel2[j]; + link_main(); + } } else { - for (j=0; rel[j][0]!=0; j++) - { - ip=rel[j]; - link_main(); - } + for (j=0; rel[j][0]!=0; j++) + { + ip=rel[j]; + link_main(); + } } - - /*Set the start address of the default areas:*/ - for(ap=areap; ap; ap=ap->a_ap) - { - /**/ if (!strcmp(ap->a_id, "REG_BANK_0")) { ap->a_addr=0x00; ap->a_type=1; } - else if (!strcmp(ap->a_id, "REG_BANK_1")) { ap->a_addr=0x08; ap->a_type=1; } - else if (!strcmp(ap->a_id, "REG_BANK_2")) { ap->a_addr=0x10; ap->a_type=1; } - else if (!strcmp(ap->a_id, "REG_BANK_3")) { ap->a_addr=0x18; ap->a_type=1; } - else if (!strcmp(ap->a_id, "BSEG_BYTES")) { ap->a_addr=0x20; ap->a_type=1; } - else if (!strcmp(ap->a_id, "SSEG")) + + /*Set the start address of the default areas:*/ + for(ap=areap; ap; ap=ap->a_ap) + { + /**/ if (!strcmp(ap->a_id, "REG_BANK_0")) { ap->a_addr=0x00; ap->a_type=1; } + else if (!strcmp(ap->a_id, "REG_BANK_1")) { ap->a_addr=0x08; ap->a_type=1; } + else if (!strcmp(ap->a_id, "REG_BANK_2")) { ap->a_addr=0x10; ap->a_type=1; } + else if (!strcmp(ap->a_id, "REG_BANK_3")) { ap->a_addr=0x18; ap->a_type=1; } + else if (!strcmp(ap->a_id, "BSEG_BYTES")) { ap->a_addr=0x20; ap->a_type=1; } + else if (!strcmp(ap->a_id, "SSEG")) { if(stacksize) ap->a_axp->a_size=stacksize; } - } + } + + sp = lkpsym("l_IRAM", 1); + sp->s_addr = ((iram_size>0) && (iram_size<=0x100)) ? iram_size : 0x0100; + sp->s_axp = NULL; + sp->s_type |= S_DEF; } -/*)Function VOID main(argc,argv) - * - * int argc number of command line arguments + 1 - * char * argv[] array of pointers to the command line - * arguments - * - * The function main() evaluates the command line arguments to - * determine if the linker parameters are to input through 'stdin' - * or read from a command file. The functiond getline() and parse() - * are to input and evaluate the linker parameters. The linking process - * proceeds by making the first pass through each .rel file in the order - * presented to the linker. At the end of the first pass the setbase(), - * lnkarea(), setgbl(), and symdef() functions are called to evaluate - * the base address terms, link all areas, define global variables, - * and look for undefined symbols. Following these routines a linker - * map file may be produced and the linker output files may be opened. - * The second pass through the .rel files will output the linked data - * in one of the four supported formats. - * - * local variables: - * char * p pointer to an argument string - * int c character from argument string - * int i loop counter - * - * global variables: - * text line in ib[] - * lfile *cfp The pointer *cfp points to the - * current lfile structure - * char ctype[] array of character types, one per - * ASCII character - * lfile *filep The pointer *filep points to the - * beginning of a linked list of - * lfile structures. - * head *hp Pointer to the current - * head structure - * char ib[NINPUT] .rel file text line - * char *ip pointer into the .rel file - * lfile *linkp pointer to first lfile structure - * containing an input .rel file - * specification - * int lkerr error flag - * int mflag Map output flag - * int oflag Output file type flag - * FILE *ofp Output file handle - * for word formats - * FILE *ofph Output file handle - * for high byte format - * FILE *ofpl Output file handle - * for low byte format - * int pass linker pass number - * int pflag print linker command file flag - * int radix current number conversion radix - * FILE *sfp The file handle sfp points to the - * currently open file - * lfile *startp asmlnk startup file structure - * FILE * stdin c_library - * FILE * stdout c_library - * - * functions called: - * FILE * afile() lkmain.c - * int fclose() c_library - * int fprintf() c_library - * int getline() lklex.c - * VOID library() lklibr.c - * VOID link_main() lkmain.c - * VOID lkexit() lkmain.c - * VOID lnkarea() lkarea.c - * VOID map() lkmain.c - * VOID new() lksym.c - * int parse() lkmain.c - * VOID reloc() lkreloc.c - * VOID search() lklibr.c - * VOID setbas() lkmain.c - * VOID setgbl() lkmain.c - * VOID symdef() lksym.c - * VOID usage() lkmain.c - * - * side effects: - * Completion of main() completes the linking process - * and may produce a map file (.map) and/or a linked - * data files (.ihx or .s19) and/or one or more - * relocated listing files (.rst). +/*)Function VOID main(argc,argv) + * + * int argc number of command line arguments + 1 + * char * argv[] array of pointers to the command line + * arguments + * + * The function main() evaluates the command line arguments to + * determine if the linker parameters are to input through 'stdin' + * or read from a command file. The functiond getline() and parse() + * are to input and evaluate the linker parameters. The linking process + * proceeds by making the first pass through each .rel file in the order + * presented to the linker. At the end of the first pass the setbase(), + * lnkarea(), setgbl(), and symdef() functions are called to evaluate + * the base address terms, link all areas, define global variables, + * and look for undefined symbols. Following these routines a linker + * map file may be produced and the linker output files may be opened. + * The second pass through the .rel files will output the linked data + * in one of the four supported formats. + * + * local variables: + * char * p pointer to an argument string + * int c character from argument string + * int i loop counter + * + * global variables: + * text line in ib[] + * lfile *cfp The pointer *cfp points to the + * current lfile structure + * char ctype[] array of character types, one per + * ASCII character + * lfile *filep The pointer *filep points to the + * beginning of a linked list of + * lfile structures. + * head *hp Pointer to the current + * head structure + * char ib[NINPUT] .rel file text line + * char *ip pointer into the .rel file + * lfile *linkp pointer to first lfile structure + * containing an input .rel file + * specification + * int lkerr error flag + * int mflag Map output flag + * int oflag Output file type flag + * FILE *ofp Output file handle + * for word formats + * FILE *ofph Output file handle + * for high byte format + * FILE *ofpl Output file handle + * for low byte format + * int pass linker pass number + * int pflag print linker command file flag + * int radix current number conversion radix + * FILE *sfp The file handle sfp points to the + * currently open file + * lfile *startp asmlnk startup file structure + * FILE * stdin c_library + * FILE * stdout c_library + * + * functions called: + * FILE * afile() lkmain.c + * int fclose() c_library + * int fprintf() c_library + * int getline() lklex.c + * VOID library() lklibr.c + * VOID link_main() lkmain.c + * VOID lkexit() lkmain.c + * VOID lnkarea() lkarea.c + * VOID map() lkmain.c + * VOID new() lksym.c + * int parse() lkmain.c + * VOID reloc() lkreloc.c + * VOID search() lklibr.c + * VOID setbas() lkmain.c + * VOID setgbl() lkmain.c + * VOID symdef() lksym.c + * VOID usage() lkmain.c + * + * side effects: + * Completion of main() completes the linking process + * and may produce a map file (.map) and/or a linked + * data files (.ihx or .s19) and/or one or more + * relocated listing files (.rst). */ int -main(argc, argv) -char *argv[]; +main(int argc, char *argv[]) { - register char *p; - register int c, i; + register char *p; + register int c, i; #ifdef WIN32T Timer(0, ""); #endif - startp = (struct lfile *) new (sizeof (struct lfile)); - - pflag = 1; - for (i=1; if_type = F_STD; - break; - - case 'f': - case 'F': - startp->f_type = F_LNK; - break; - - case 'n': - case 'N': - pflag = 0; - break; - - case 'p': - case 'P': - pflag = 1; - break; - - default: - usage(); - } - } - } else { - if (startp->f_type == F_LNK) { - startp->f_idp = p; - } - } - } - if (startp->f_type == 0) - usage(); - if (startp->f_type == F_LNK && startp->f_idp == NULL) - usage(); - - cfp = NULL; - sfp = NULL; - filep = startp; - while (1) { - ip = ib; - if (getline() == 0) - break; - if (pflag && sfp != stdin) - fprintf(stdout, "%s\n", ip); + startp = (struct lfile *) new (sizeof (struct lfile)); + + pflag = 1; + for (i=1; if_type = F_STD; + break; + + case 'f': + case 'F': + startp->f_type = F_LNK; + break; + + case 'n': + case 'N': + pflag = 0; + break; + + case 'p': + case 'P': + pflag = 1; + break; + + default: + usage(); + } + } + } else { + if (startp->f_type == F_LNK) { + startp->f_idp = p; + } + } + } + if (startp->f_type == 0) + usage(); + if (startp->f_type == F_LNK && startp->f_idp == NULL) + usage(); + + cfp = NULL; + sfp = NULL; + filep = startp; + while (1) { + ip = ib; + if (getline() == 0) + break; + if (pflag && sfp != stdin) + fprintf(stdout, "%s\n", ip); if (*ip == '\0' || parse()) - break; - } - - if (sfp) { - fclose(sfp); - sfp = NULL; - } - - if (linkp == NULL) - usage(); - - syminit(); - - if (dflag){ - //dfp = afile("temp", "cdb", 1); - SaveLinkedFilePath(linkp->f_idp); //Must be the first one... - dfp = afile(linkp->f_idp,"cdb",1); //JCF: Nov 30, 2002 - if (dfp == NULL) - lkexit(1); - } - - for (pass=0; pass<2; ++pass) { - cfp = NULL; - sfp = NULL; - filep = linkp; - hp = NULL; - radix = 10; - - Areas51(); /*JCF: Create the default 8051 areas in the right order*/ - - while (getline()) { - ip = ib; - - /* pass any "magic comments" to NoICE output */ - if ((ip[0] == ';') && (ip[1] == '!') && jfp) { - fprintf( jfp, "%s\n", &ip[2] ); - } - link_main(); - } - if (pass == 0) { - /* - * Search libraries for global symbols - */ - search(); - /* - * Set area base addresses. - */ - setbas(); - /* - * Link all area addresses. - */ - if(!packflag) + break; + } + + if (sfp) { + fclose(sfp); + sfp = NULL; + } + + if (linkp == NULL) + usage(); + + syminit(); + + if (dflag){ + //dfp = afile("temp", "cdb", 1); + SaveLinkedFilePath(linkp->f_idp); //Must be the first one... + dfp = afile(linkp->f_idp,"cdb",1); //JCF: Nov 30, 2002 + if (dfp == NULL) + lkexit(1); + } + + for (pass=0; pass<2; ++pass) { + cfp = NULL; + sfp = NULL; + filep = linkp; + hp = NULL; + radix = 10; + + Areas51(); /*JCF: Create the default 8051 areas in the right order*/ + + while (getline()) { + ip = ib; + + /* pass any "magic comments" to NoICE output */ + if ((ip[0] == ';') && (ip[1] == '!') && jfp) { + fprintf( jfp, "%s\n", &ip[2] ); + } + link_main(); + } + if (pass == 0) { + /* + * Search libraries for global symbols + */ + search(); + /* + * Set area base addresses. + */ + setbas(); + /* + * Link all area addresses. + */ + if(!packflag) lnkarea(); else lnkarea2(); - /* - * Process global definitions. - */ - setgbl(); - /* - * Check for undefined globals. - */ - symdef(stderr); - - /* Open NoICE output file if requested */ - if (jflag) { - jfp = afile(linkp->f_idp, "NOI", 1); - if (jfp == NULL) { - lkexit(1); - } - } - - /* - * Output Link Map if requested, - * or if NoICE output requested (since NoICE - * file is generated in part by map() processing) - */ - if (mflag || jflag) - map(); - - if (sflag) /*JCF: memory usage summary output*/ + /* + * Process global definitions. + */ + setgbl(); + /* + * Check for undefined globals. + */ + symdef(stderr); + + /* Open NoICE output file if requested */ + if (jflag) { + jfp = afile(linkp->f_idp, "NOI", 1); + if (jfp == NULL) { + lkexit(1); + } + } + + /* + * Output Link Map if requested, + * or if NoICE output requested (since NoICE + * file is generated in part by map() processing) + */ + if (mflag || jflag) + map(); + + if (sflag) /*JCF: memory usage summary output*/ { if(!packflag) { - if(summary(areap)) lkexit(1); + if(summary(areap)) lkexit(1); } else { - if(summary2(areap)) lkexit(1); + if(summary2(areap)) lkexit(1); } } - if ((iram_size) && (!packflag)) - iramcheck(); - - /* - * Open output file - */ - if (oflag == 1) { - ofp = afile(linkp->f_idp, "ihx", 1); - if (ofp == NULL) { - lkexit(1); - } - /* include NoICE command to load hex file */ - if (jfp) fprintf( jfp, "LOAD %s.IHX\n", linkp->f_idp ); - - } else - if (oflag == 2) { - ofp = afile(linkp->f_idp, "S19", 1); - if (ofp == NULL) { - lkexit(1); - } - /* include NoICE command to load hex file */ - if (jfp) fprintf( jfp, "LOAD %s.S19\n", linkp->f_idp ); - } - } else { - /* - * Link in library files - */ - library(); - reloc('E'); - } - } - //JCF: - CreateAOMF51(); + if ((iram_size) && (!packflag)) + iramcheck(); + + /* + * Open output file + */ + if (oflag == 1) { + ofp = afile(linkp->f_idp, "ihx", 1); + if (ofp == NULL) { + lkexit(1); + } + /* include NoICE command to load hex file */ + if (jfp) fprintf( jfp, "LOAD %s.IHX\n", linkp->f_idp ); + + } else + if (oflag == 2) { + ofp = afile(linkp->f_idp, "S19", 1); + if (ofp == NULL) { + lkexit(1); + } + /* include NoICE command to load hex file */ + if (jfp) fprintf( jfp, "LOAD %s.S19\n", linkp->f_idp ); + } + } else { + /* + * Link in library files + */ + library(); + reloc('E'); + } + } + //JCF: + CreateAOMF51(); #ifdef WIN32T Timer(1, "Linker execution time"); #endif - lkexit(lkerr); - return 0; + lkexit(lkerr); + return 0; } -/*)Function VOID lkexit(i) +/*)Function VOID lkexit(i) * - * int i exit code + * int i exit code * - * The function lkexit() explicitly closes all open - * files and then terminates the program. + * The function lkexit() explicitly closes all open + * files and then terminates the program. * - * local variables: - * none + * local variables: + * none * - * global variables: - * FILE * mfp file handle for .map - * FILE * ofp file handle for .ihx/.s19 - * FILE * rfp file hanlde for .rst - * FILE * sfp file handle for .rel - * FILE * tfp file handle for .lst + * global variables: + * FILE * mfp file handle for .map + * FILE * ofp file handle for .ihx/.s19 + * FILE * rfp file hanlde for .rst + * FILE * sfp file handle for .rel + * FILE * tfp file handle for .lst * - * functions called: - * int fclose() c_library - * VOID exit() c_library + * functions called: + * int fclose() c_library + * VOID exit() c_library * - * side effects: - * All files closed. Program terminates. + * side effects: + * All files closed. Program terminates. */ VOID -lkexit(i) -int i; +lkexit(int i) { - if (mfp != NULL) fclose(mfp); - if (jfp != NULL) fclose(jfp); - if (ofp != NULL) fclose(ofp); - if (rfp != NULL) fclose(rfp); - if (sfp != NULL) fclose(sfp); - if (tfp != NULL) fclose(tfp); - if (dfp != NULL) fclose(dfp); - /*if (dfp != NULL) - FILE *xfp = afile(linkp->f_idp,"cdb",1); - dfp = freopen("temp.cdb","r",dfp); - copyfile(xfp,dfp); - fclose(xfp); - fclose(dfp); - unlink("temp.cdb"); - }*/ - exit(i); + if (mfp != NULL) fclose(mfp); + if (jfp != NULL) fclose(jfp); + if (ofp != NULL) fclose(ofp); + if (rfp != NULL) fclose(rfp); + if (sfp != NULL) fclose(sfp); + if (tfp != NULL) fclose(tfp); + if (dfp != NULL) fclose(dfp); + /*if (dfp != NULL) + FILE *xfp = afile(linkp->f_idp,"cdb",1); + dfp = freopen("temp.cdb","r",dfp); + copyfile(xfp,dfp); + fclose(xfp); + fclose(dfp); + unlink("temp.cdb"); + }*/ + exit(i); } -/*)Function link_main() - * - * The function link_main() evaluates the directives for each line of - * text read from the .rel file(s). The valid directives processed - * are: - * X, D, Q, H, M, A, S, T, R, and P. - * - * local variables: - * int c first non blank character of a line - * - * global variables: - * head *headp The pointer to the first - * head structure of a linked list - * head *hp Pointer to the current - * head structure - * int pass linker pass number - * int radix current number conversion radix - * - * functions called: - * char endline() lklex.c - * VOID module() lkhead.c - * VOID newarea() lkarea.c - * VOID newhead() lkhead.c - * sym * newsym() lksym.c - * VOID reloc() lkreloc.c - * - * side effects: - * Head, area, and symbol structures are created and - * the radix is set as the .rel file(s) are read. +/*)Function link_main() + * + * The function link_main() evaluates the directives for each line of + * text read from the .rel file(s). The valid directives processed + * are: + * X, D, Q, H, M, A, S, T, R, and P. + * + * local variables: + * int c first non blank character of a line + * + * global variables: + * head *headp The pointer to the first + * head structure of a linked list + * head *hp Pointer to the current + * head structure + * int pass linker pass number + * int radix current number conversion radix + * + * functions called: + * char endline() lklex.c + * VOID module() lkhead.c + * VOID newarea() lkarea.c + * VOID newhead() lkhead.c + * sym * newsym() lksym.c + * VOID reloc() lkreloc.c + * + * side effects: + * Head, area, and symbol structures are created and + * the radix is set as the .rel file(s) are read. */ VOID link_main() { - register int c; + register int c; - if ((c=endline()) == 0) { return; } - switch (c) { + if ((c=endline()) == 0) { return; } + switch (c) { case 'O': /*For some important sdcc options*/ if (pass == 0) @@ -521,309 +525,309 @@ link_main() { if(strcmp(sdccopt, &ip[1])!=0) { - fprintf(stderr, - "?ASlink-Warning-Conflicting sdcc options:\n" + fprintf(stderr, + "?ASlink-Warning-Conflicting sdcc options:\n" " \"%s\" in module \"%s\" and\n" " \"%s\" in module \"%s\".\n", sdccopt, sdccopt_module, &ip[1], curr_module); - lkerr++; + lkerr++; } } } - break; - - case 'X': - radix = 16; - break; - - case 'D': - radix = 10; - break; - - case 'Q': - radix = 8; - break; - - case 'H': - if (pass == 0) { - newhead(); - } else { - if (hp == 0) { - hp = headp; - } else { - hp = hp->h_hp; - } - } - sdp.s_area = NULL; - sdp.s_areax = NULL; - sdp.s_addr = 0; - break; - - case 'M': - if (pass == 0) + break; + + case 'X': + radix = 16; + break; + + case 'D': + radix = 10; + break; + + case 'Q': + radix = 8; + break; + + case 'H': + if (pass == 0) { + newhead(); + } else { + if (hp == 0) { + hp = headp; + } else { + hp = hp->h_hp; + } + } + sdp.s_area = NULL; + sdp.s_areax = NULL; + sdp.s_addr = 0; + break; + + case 'M': + if (pass == 0) { strcpy(curr_module, &ip[1]); - module(); + module(); + } + break; + + case 'A': + if (pass == 0) + newarea(); + if (sdp.s_area == NULL) { + sdp.s_area = areap; + sdp.s_areax = areap->a_axp; + sdp.s_addr = 0; + } + break; + + case 'S': + if (pass == 0) + newsym(); + break; + + case 'T': + case 'R': + case 'P': + if (pass == 0) + break; + reloc(c); + break; + + default: + break; + } + if (c == 'X' || c == 'D' || c == 'Q') { + if ((c = get()) == 'H') { + hilo = 1; + } else + if (c == 'L') { + hilo = 0; } - break; - - case 'A': - if (pass == 0) - newarea(); - if (sdp.s_area == NULL) { - sdp.s_area = areap; - sdp.s_areax = areap->a_axp; - sdp.s_addr = 0; - } - break; - - case 'S': - if (pass == 0) - newsym(); - break; - - case 'T': - case 'R': - case 'P': - if (pass == 0) - break; - reloc(c); - break; - - default: - break; - } - if (c == 'X' || c == 'D' || c == 'Q') { - if ((c = get()) == 'H') { - hilo = 1; - } else - if (c == 'L') { - hilo = 0; - } - } + } } -/*)Function VOID map() - * - * The function map() opens the output map file and calls the various - * routines to - * (1) output the variables in each area, - * (2) list the files processed with module names, - * (3) list the libraries file processed, - * (4) list base address definitions, - * (5) list global variable definitions, and - * (6) list any undefined variables. - * - * local variables: - * int i counter - * head * hdp pointer to head structure - * lbfile *lbfh pointer to library file structure - * - * global variables: - * area *ap Pointer to the current - * area structure - * area *areap The pointer to the first - * area structure of a linked list - * base *basep The pointer to the first - * base structure - * base *bsp Pointer to the current - * base structure - * lfile *filep The pointer *filep points to the - * beginning of a linked list of - * lfile structures. - * globl *globlp The pointer to the first - * globl structure - * globl *gsp Pointer to the current - * globl structure - * head *headp The pointer to the first - * head structure of a linked list - * lbfile *lbfhead The pointer to the first - * lbfile structure of a linked list - * lfile *linkp pointer to first lfile structure - * containing an input REL file - * specification - * int lop current line number on page - * FILE *mfp Map output file handle - * int page current page number - * - * functions called: - * FILE * afile() lkmain.c - * int fprintf() c_library - * VOID lkexit() lkmain.c - * VOID lstarea() lklist.c - * VOID newpag() lklist.c - * VOID symdef() lksym.c - * - * side effects: - * The map file is created. +/*)Function VOID map() + * + * The function map() opens the output map file and calls the various + * routines to + * (1) output the variables in each area, + * (2) list the files processed with module names, + * (3) list the libraries file processed, + * (4) list base address definitions, + * (5) list global variable definitions, and + * (6) list any undefined variables. + * + * local variables: + * int i counter + * head * hdp pointer to head structure + * lbfile *lbfh pointer to library file structure + * + * global variables: + * area *ap Pointer to the current + * area structure + * area *areap The pointer to the first + * area structure of a linked list + * base *basep The pointer to the first + * base structure + * base *bsp Pointer to the current + * base structure + * lfile *filep The pointer *filep points to the + * beginning of a linked list of + * lfile structures. + * globl *globlp The pointer to the first + * globl structure + * globl *gsp Pointer to the current + * globl structure + * head *headp The pointer to the first + * head structure of a linked list + * lbfile *lbfhead The pointer to the first + * lbfile structure of a linked list + * lfile *linkp pointer to first lfile structure + * containing an input REL file + * specification + * int lop current line number on page + * FILE *mfp Map output file handle + * int page current page number + * + * functions called: + * FILE * afile() lkmain.c + * int fprintf() c_library + * VOID lkexit() lkmain.c + * VOID lstarea() lklist.c + * VOID newpag() lklist.c + * VOID symdef() lksym.c + * + * side effects: + * The map file is created. */ VOID map() { - register int i; - register struct head *hdp; - register struct lbfile *lbfh; - - /* - * Open Map File - */ - mfp = afile(linkp->f_idp, "map", 1); - if (mfp == NULL) { - lkexit(1); - } - - /* - * Output Map Area Lists - */ - page = 0; - lop = NLPP; - ap = areap; - while (ap) { - lstarea(ap); - ap = ap->a_ap; - } - /* - * List Linked Files - */ - newpag(mfp); - fprintf(mfp, "\nFiles Linked [ module(s) ]\n\n"); - hdp = headp; - filep = linkp; - while (filep) { - fprintf(mfp, "%-16s", filep->f_idp); - i = 0; - while ((hdp != NULL) && (hdp->h_lfile == filep)) { - if (i % 5) { - fprintf(mfp, ", %8.8s", hdp->m_id); - } else { - if (i) { - fprintf(mfp, ",\n%20s%8.8s", "", hdp->m_id); - } else { - fprintf(mfp, " [ %8.8s", hdp->m_id); - } - } - hdp = hdp->h_hp; - i++; - } - if (i) - fprintf(mfp, " ]"); - fprintf(mfp, "\n"); - filep = filep->f_flp; - } - /* - * List Linked Libraries - */ - if (lbfhead != NULL) { - fprintf(mfp, - "\nLibraries Linked [ object file ]\n\n"); - for (lbfh=lbfhead; lbfh; lbfh=lbfh->next) { - fprintf(mfp, "%-32s [ %16.16s ]\n", - lbfh->libspc, lbfh->relfil); - } - fprintf(mfp, "\n"); - } - /* - * List Base Address Definitions - */ - if (basep) { - newpag(mfp); - fprintf(mfp, "\nUser Base Address Definitions\n\n"); - bsp = basep; - while (bsp) { - fprintf(mfp, "%s\n", bsp->b_strp); - bsp = bsp->b_base; - } - } - /* - * List Global Definitions - */ - if (globlp) { - newpag(mfp); - fprintf(mfp, "\nUser Global Definitions\n\n"); - gsp = globlp; - while (gsp) { - fprintf(mfp, "%s\n", gsp->g_strp); - gsp = gsp->g_globl; - } - } - fprintf(mfp, "\n\f"); - symdef(mfp); + register int i; + register struct head *hdp; + register struct lbfile *lbfh; + + /* + * Open Map File + */ + mfp = afile(linkp->f_idp, "map", 1); + if (mfp == NULL) { + lkexit(1); + } + + /* + * Output Map Area Lists + */ + page = 0; + lop = NLPP; + ap = areap; + while (ap) { + lstarea(ap); + ap = ap->a_ap; + } + /* + * List Linked Files + */ + newpag(mfp); + fprintf(mfp, "\nFiles Linked [ module(s) ]\n\n"); + hdp = headp; + filep = linkp; + while (filep) { + fprintf(mfp, "%-16s", filep->f_idp); + i = 0; + while ((hdp != NULL) && (hdp->h_lfile == filep)) { + if (i % 5) { + fprintf(mfp, ", %8.8s", hdp->m_id); + } else { + if (i) { + fprintf(mfp, ",\n%20s%8.8s", "", hdp->m_id); + } else { + fprintf(mfp, " [ %8.8s", hdp->m_id); + } + } + hdp = hdp->h_hp; + i++; + } + if (i) + fprintf(mfp, " ]"); + fprintf(mfp, "\n"); + filep = filep->f_flp; + } + /* + * List Linked Libraries + */ + if (lbfhead != NULL) { + fprintf(mfp, + "\nLibraries Linked [ object file ]\n\n"); + for (lbfh=lbfhead; lbfh; lbfh=lbfh->next) { + fprintf(mfp, "%-32s [ %16.16s ]\n", + lbfh->libspc, lbfh->relfil); + } + fprintf(mfp, "\n"); + } + /* + * List Base Address Definitions + */ + if (basep) { + newpag(mfp); + fprintf(mfp, "\nUser Base Address Definitions\n\n"); + bsp = basep; + while (bsp) { + fprintf(mfp, "%s\n", bsp->b_strp); + bsp = bsp->b_base; + } + } + /* + * List Global Definitions + */ + if (globlp) { + newpag(mfp); + fprintf(mfp, "\nUser Global Definitions\n\n"); + gsp = globlp; + while (gsp) { + fprintf(mfp, "%s\n", gsp->g_strp); + gsp = gsp->g_globl; + } + } + fprintf(mfp, "\n\f"); + symdef(mfp); } -/*)Function int parse() - * - * The function parse() evaluates all command line or file input - * linker directives and updates the appropriate variables. - * - * local variables: - * int c character value - * char fid[] file id string - * - * global variables: - * char ctype[] array of character types, one per - * ASCII character - * lfile *lfp pointer to current lfile structure - * being processed by parse() - * lfile *linkp pointer to first lfile structure - * containing an input REL file - * specification - * int mflag Map output flag - * int oflag Output file type flag - * int pflag print linker command file flag - * FILE * stderr c_library - * int uflag Relocated listing flag - * int xflag Map file radix type flag - * - * Functions called: - * VOID addlib() lklibr.c - * VOID addpath() lklibr.c - * VOID bassav() lkmain.c - * int fprintf() c_library - * VOID gblsav() lkmain.c - * VOID getfid() lklex.c - * char getnb() lklex.c - * VOID lkexit() lkmain.c - * char * strcpy() c_library - * int strlen() c_library - * - * side effects: - * Various linker flags are updated and the linked - * structure lfile is created. +/*)Function int parse() + * + * The function parse() evaluates all command line or file input + * linker directives and updates the appropriate variables. + * + * local variables: + * int c character value + * char fid[] file id string + * + * global variables: + * char ctype[] array of character types, one per + * ASCII character + * lfile *lfp pointer to current lfile structure + * being processed by parse() + * lfile *linkp pointer to first lfile structure + * containing an input REL file + * specification + * int mflag Map output flag + * int oflag Output file type flag + * int pflag print linker command file flag + * FILE * stderr c_library + * int uflag Relocated listing flag + * int xflag Map file radix type flag + * + * Functions called: + * VOID addlib() lklibr.c + * VOID addpath() lklibr.c + * VOID bassav() lkmain.c + * int fprintf() c_library + * VOID gblsav() lkmain.c + * VOID getfid() lklex.c + * char getnb() lklex.c + * VOID lkexit() lkmain.c + * char * strcpy() c_library + * int strlen() c_library + * + * side effects: + * Various linker flags are updated and the linked + * structure lfile is created. */ int parse() { - register int c; - char fid[NINPUT]; - - while ((c = getnb()) != 0) { - if ( c == ';') - return(0); - if ( c == '-') { - while (ctype[c=get()] & LETTER) { - switch(c) { - - case 'i': - case 'I': - oflag = 1; - break; - - case 's': - case 'S': - oflag = 2; - break; - - case 'm': - case 'M': - ++mflag; - break; - - case 'y': /*JCF: memory usage summary output*/ - ++sflag; - break; + register int c; + char fid[NINPUT]; + + while ((c = getnb()) != 0) { + if ( c == ';') + return(0); + if ( c == '-') { + while (ctype[c=get()] & LETTER) { + switch(c) { + + case 'i': + case 'I': + oflag = 1; + break; + + case 's': + case 'S': + oflag = 2; + break; + + case 'm': + case 'M': + ++mflag; + break; + + case 'y': /*JCF: memory usage summary output*/ + ++sflag; + break; case 'Y': unget(getnb()); @@ -838,441 +842,439 @@ parse() if(stacksize>256) stacksize=256; else if(stacksize<0) stacksize=0; } - return(0); - - case 'j': - case 'J': - jflag = 1; - break; - - case 'u': - case 'U': - uflag = 1; - break; - case 'r': - case 'R': - rflag = 1; - break; - case 'x': - case 'X': - xflag = 0; - break; - - case 'q': - case 'Q': - xflag = 1; - break; - - case 'd': - case 'D': - xflag = 2; - break; - - case 'e': - case 'E': - return(1); - - case 'n': - case 'N': - pflag = 0; - break; - - case 'p': - case 'P': - pflag = 1; - break; - - case 'b': - case 'B': - bassav(); - return(0); - - case 'g': - case 'G': - gblsav(); - return(0); - - case 'k': - case 'K': - addpath(); - return(0); - - case 'l': - case 'L': - addlib(); - return(0); - - case 'a': - iramsav(); - return(0); - - case 'v': - case 'V': - xramsav(); - return(0); - - case 'w': - case 'W': - codesav(); - return(0); - - case 'z': + return(0); + + case 'j': + case 'J': + jflag = 1; + break; + + case 'u': + case 'U': + uflag = 1; + break; + case 'r': + case 'R': + rflag = 1; + break; + case 'x': + case 'X': + xflag = 0; + break; + + case 'q': + case 'Q': + xflag = 1; + break; + + case 'd': + case 'D': + xflag = 2; + break; + + case 'e': + case 'E': + return(1); + + case 'n': + case 'N': + pflag = 0; + break; + + case 'p': + case 'P': + pflag = 1; + break; + + case 'b': + case 'B': + bassav(); + return(0); + + case 'g': + case 'G': + gblsav(); + return(0); + + case 'k': + case 'K': + addpath(); + return(0); + + case 'l': + case 'L': + addlib(); + return(0); + + case 'a': + iramsav(); + return(0); + + case 'v': + case 'V': + xramsav(); + return(0); + + case 'w': + case 'W': + codesav(); + return(0); + + case 'z': case 'Z': - dflag = 1; - return(0); - default: - fprintf(stderr, "Invalid option\n"); - lkexit(1); - } - } - if ( c == ';') - return(0); - } else + dflag = 1; + return(0); + default: + fprintf(stderr, "Invalid option\n"); + lkexit(1); + } + } + if ( c == ';') + return(0); + } else if (ctype[c] & ILL) { fprintf(stderr, "Invalid input"); lkexit(1); } else { - if (linkp == NULL) { - linkp = (struct lfile *) - new (sizeof (struct lfile)); - lfp = linkp; - } else { - lfp->f_flp = (struct lfile *) - new (sizeof (struct lfile)); - lfp = lfp->f_flp; - } - getfid(fid, c); - lfp->f_idp = (char *) new (strlen(fid)+1); - strcpy(lfp->f_idp, fid); - lfp->f_type = F_REL; - } - } - return(0); + if (linkp == NULL) { + linkp = (struct lfile *) + new (sizeof (struct lfile)); + lfp = linkp; + } else { + lfp->f_flp = (struct lfile *) + new (sizeof (struct lfile)); + lfp = lfp->f_flp; + } + getfid(fid, c); + lfp->f_idp = (char *) new (strlen(fid)+1); + strcpy(lfp->f_idp, fid); + lfp->f_type = F_REL; + } + } + return(0); } -/*)Function VOID bassav() +/*)Function VOID bassav() * - * The function bassav() creates a linked structure containing - * the base address strings input to the linker. + * The function bassav() creates a linked structure containing + * the base address strings input to the linker. * - * local variables: - * none + * local variables: + * none * - * global variables: - * base *basep The pointer to the first - * base structure - * base *bsp Pointer to the current - * base structure - * char *ip pointer into the REL file - * text line in ib[] + * global variables: + * base *basep The pointer to the first + * base structure + * base *bsp Pointer to the current + * base structure + * char *ip pointer into the REL file + * text line in ib[] * - * functions called: - * char getnb() lklex.c - * VOID * new() lksym.c - * int strlen() c_library - * char * strcpy() c_library - * VOID unget() lklex.c + * functions called: + * char getnb() lklex.c + * VOID * new() lksym.c + * int strlen() c_library + * char * strcpy() c_library + * VOID unget() lklex.c * - * side effects: - * The basep structure is created. + * side effects: + * The basep structure is created. */ VOID bassav() { - if (basep == NULL) { - basep = (struct base *) - new (sizeof (struct base)); - bsp = basep; - } else { - bsp->b_base = (struct base *) - new (sizeof (struct base)); - bsp = bsp->b_base; - } - unget(getnb()); - bsp->b_strp = (char *) new (strlen(ip)+1); - strcpy(bsp->b_strp, ip); + if (basep == NULL) { + basep = (struct base *) + new (sizeof (struct base)); + bsp = basep; + } else { + bsp->b_base = (struct base *) + new (sizeof (struct base)); + bsp = bsp->b_base; + } + unget(getnb()); + bsp->b_strp = (char *) new (strlen(ip)+1); + strcpy(bsp->b_strp, ip); } -/*)Function VOID setbas() - * - * The function setbas() scans the base address lines in hte - * basep structure, evaluates the arguments, and sets beginning - * address of the specified areas. - * - * local variables: - * int v expression value - * char id[] base id string - * - * global variables: - * area *ap Pointer to the current - * area structure - * area *areap The pointer to the first - * area structure of a linked list - * base *basep The pointer to the first - * base structure - * base *bsp Pointer to the current - * base structure - * char *ip pointer into the REL file - * text line in ib[] - * int lkerr error flag - * - * functions called: - * Addr_T expr() lkeval.c - * int fprintf() c_library - * VOID getid() lklex.c - * char getnb() lklex.c - * int symeq() lksym.c - * - * side effects: - * The base address of an area is set. +/*)Function VOID setbas() + * + * The function setbas() scans the base address lines in the + * basep structure, evaluates the arguments, and sets beginning + * address of the specified areas. + * + * local variables: + * int v expression value + * char id[] base id string + * + * global variables: + * area *ap Pointer to the current + * area structure + * area *areap The pointer to the first + * area structure of a linked list + * base *basep The pointer to the first + * base structure + * base *bsp Pointer to the current + * base structure + * char *ip pointer into the REL file + * text line in ib[] + * int lkerr error flag + * + * functions called: + * Addr_T expr() lkeval.c + * int fprintf() c_library + * VOID getid() lklex.c + * char getnb() lklex.c + * int symeq() lksym.c + * + * side effects: + * The base address of an area is set. */ VOID setbas() { - register int v; - char id[NCPS]; - - bsp = basep; - while (bsp) { - ip = bsp->b_strp; - getid(id, -1); - if (getnb() == '=') { - v = expr(0); - for (ap = areap; ap != NULL; ap = ap->a_ap) { - if (symeq(id, ap->a_id)) - break; - } - if (ap == NULL) { - fprintf(stderr, - "ASlink-Warning-No definition of area %s\n", id); - lkerr++; - } else { - ap->a_addr = v; - ap->a_type = 1; /* JLH: value set */ - } - } else { - fprintf(stderr, "ASlink-Warning-No '=' in base expression"); - lkerr++; - } - bsp = bsp->b_base; - } + register int v; + char id[NCPS]; + + bsp = basep; + while (bsp) { + ip = bsp->b_strp; + getid(id, -1); + if (getnb() == '=') { + v = expr(0); + for (ap = areap; ap != NULL; ap = ap->a_ap) { + if (symeq(id, ap->a_id)) + break; + } + if (ap == NULL) { + fprintf(stderr, + "ASlink-Warning-No definition of area %s\n", id); + lkerr++; + } else { + ap->a_addr = v; + ap->a_type = 1; /* JLH: value set */ + } + } else { + fprintf(stderr, "ASlink-Warning-No '=' in base expression"); + lkerr++; + } + bsp = bsp->b_base; + } } -/*)Function VOID gblsav() +/*)Function VOID gblsav() * - * The function gblsav() creates a linked structure containing - * the global variable strings input to the linker. + * The function gblsav() creates a linked structure containing + * the global variable strings input to the linker. * - * local variable: - * none + * local variable: + * none * - * global variables: - * globl *globlp The pointer to the first - * globl structure - * globl *gsp Pointer to the current - * globl structure - * char *ip pointer into the REL file - * text line in ib[] - * int lkerr error flag + * global variables: + * globl *globlp The pointer to the first + * globl structure + * globl *gsp Pointer to the current + * globl structure + * char *ip pointer into the REL file + * text line in ib[] + * int lkerr error flag * - * functions called: - * char getnb() lklex.c - * VOID * new() lksym.c - * int strlen() c_library - * char * strcpy() c_library - * VOID unget() lklex.c + * functions called: + * char getnb() lklex.c + * VOID * new() lksym.c + * int strlen() c_library + * char * strcpy() c_library + * VOID unget() lklex.c * - * side effects: - * The globlp structure is created. + * side effects: + * The globlp structure is created. */ VOID gblsav() { - if (globlp == NULL) { - globlp = (struct globl *) - new (sizeof (struct globl)); - gsp = globlp; - } else { - gsp->g_globl = (struct globl *) - new (sizeof (struct globl)); - gsp = gsp->g_globl; - } - unget(getnb()); - gsp->g_strp = (char *) new (strlen(ip)+1); - strcpy(gsp->g_strp, ip); + if (globlp == NULL) { + globlp = (struct globl *) + new (sizeof (struct globl)); + gsp = globlp; + } else { + gsp->g_globl = (struct globl *) + new (sizeof (struct globl)); + gsp = gsp->g_globl; + } + unget(getnb()); + gsp->g_strp = (char *) new (strlen(ip)+1); + strcpy(gsp->g_strp, ip); } - -/*)Function VOID setgbl() - * - * The function setgbl() scans the global variable lines in hte - * globlp structure, evaluates the arguments, and sets a variable - * to this value. - * - * local variables: - * int v expression value - * char id[] base id string - * sym * sp pointer to a symbol structure - * - * global variables: - * char *ip pointer into the REL file - * text line in ib[] - * globl *globlp The pointer to the first - * globl structure - * globl *gsp Pointer to the current - * globl structure - * FILE * stderr c_library - * int lkerr error flag - * - * functions called: - * Addr_T expr() lkeval.c - * int fprintf() c_library - * VOID getid() lklex.c - * char getnb() lklex.c - * sym * lkpsym() lksym.c - * - * side effects: - * The value of a variable is set. + +/*)Function VOID setgbl() + * + * The function setgbl() scans the global variable lines in the + * globlp structure, evaluates the arguments, and sets a variable + * to this value. + * + * local variables: + * int v expression value + * char id[] base id string + * sym * sp pointer to a symbol structure + * + * global variables: + * char *ip pointer into the REL file + * text line in ib[] + * globl *globlp The pointer to the first + * globl structure + * globl *gsp Pointer to the current + * globl structure + * FILE * stderr c_library + * int lkerr error flag + * + * functions called: + * Addr_T expr() lkeval.c + * int fprintf() c_library + * VOID getid() lklex.c + * char getnb() lklex.c + * sym * lkpsym() lksym.c + * + * side effects: + * The value of a variable is set. */ VOID setgbl() { - register int v; - register struct sym *sp; - char id[NCPS]; - - gsp = globlp; - while (gsp) { - ip = gsp->g_strp; - getid(id, -1); - if (getnb() == '=') { - v = expr(0); - sp = lkpsym(id, 0); - if (sp == NULL) { - fprintf(stderr, - "No definition of symbol %s\n", id); - lkerr++; - } else { - if (sp->s_flag & S_DEF) { - fprintf(stderr, - "Redefinition of symbol %s\n", id); - lkerr++; - sp->s_axp = NULL; - } - sp->s_addr = v; - sp->s_type |= S_DEF; - } - } else { - fprintf(stderr, "No '=' in global expression"); - lkerr++; - } - gsp = gsp->g_globl; - } + register int v; + register struct sym *sp; + char id[NCPS]; + + gsp = globlp; + while (gsp) { + ip = gsp->g_strp; + getid(id, -1); + if (getnb() == '=') { + v = expr(0); + sp = lkpsym(id, 0); + if (sp == NULL) { + fprintf(stderr, + "No definition of symbol %s\n", id); + lkerr++; + } else { + if (sp->s_flag & S_DEF) { + fprintf(stderr, + "Redefinition of symbol %s\n", id); + lkerr++; + sp->s_axp = NULL; + } + sp->s_addr = v; + sp->s_type |= S_DEF; + } + } else { + fprintf(stderr, "No '=' in global expression"); + lkerr++; + } + gsp = gsp->g_globl; + } } -/*)Function FILE * afile(fn,, ft, wf) +/*)Function FILE * afile(fn,, ft, wf) * - * char * fn file specification string - * char * ft file type string - * int wf read(0)/write(1) flag + * char * fn file specification string + * char * ft file type string + * int wf read(0)/write(1) flag * - * The function afile() opens a file for reading or writing. - * (1) If the file type specification string ft - * is not NULL then a file specification is - * constructed with the file path\name in fn - * and the extension in ft. - * (2) If the file type specification string ft - * is NULL then the file specification is - * constructed from fn. If fn does not have - * a file type then the default .rel file - * type is appended to the file specification. + * The function afile() opens a file for reading or writing. + * (1) If the file type specification string ft + * is not NULL then a file specification is + * constructed with the file path\name in fn + * and the extension in ft. + * (2) If the file type specification string ft + * is NULL then the file specification is + * constructed from fn. If fn does not have + * a file type then the default .rel file + * type is appended to the file specification. * - * afile() returns a file handle for the opened file or aborts - * the assembler on an open error. + * afile() returns a file handle for the opened file or aborts + * the assembler on an open error. * - * local variables: - * char fb[] constructed file specification string - * FILE * fp filehandle for opened file + * local variables: + * char fb[] constructed file specification string + * FILE * fp filehandle for opened file * - * global variables: - * int lkerr error flag + * global variables: + * int lkerr error flag * - * functions called: - * FILE * fopen() c_library - * int fprintf() c_library + * functions called: + * FILE * fopen() c_library + * int fprintf() c_library * - * side effects: - * File is opened for read or write. + * side effects: + * File is opened for read or write. */ FILE * -afile(fn, ft, wf) -char *fn; -char *ft; +afile(char *fn, char *ft, int wf) { - FILE *fp; - char fb[PATH_MAX]; - char *omode = (wf ? (wf == 2 ? "a" : "w") : "r"); - int i; - - /*Look backward the name path and get rid of the extension, if any*/ - i=strlen(fn); - for(; (fn[i]!='.')&&(fn[i]!='\\')&&(fn[i]!='/')&&(i>0); i--); - if( (fn[i]=='.') && strcmp(ft, "lnk") ) - { - strncpy(fb, fn, i); - fb[i]=0; - } - else - { - strcpy(fb, fn); - } - - /*Add the extension*/ - if (fb[i] != '.') - { - strcat(fb, "."); - strcat(fb, strlen(ft)?ft:"rel"); - } - - fp = fopen(fb, omode); - if (fp==NULL) - { - if (strcmp(ft,"adb"))/*Do not complaint for optional adb files*/ - { - fprintf(stderr, "%s: cannot %s.\n", fb, wf?"create":"open"); - lkerr++; - } - } - return (fp); + FILE *fp; + char fb[PATH_MAX]; + char *omode = (wf ? (wf == 2 ? "a" : "w") : "r"); + int i; + + /*Look backward the name path and get rid of the extension, if any*/ + i=strlen(fn); + for(; (fn[i]!='.')&&(fn[i]!='\\')&&(fn[i]!='/')&&(i>0); i--); + if( (fn[i]=='.') && strcmp(ft, "lnk") ) + { + strncpy(fb, fn, i); + fb[i]=0; + } + else + { + strcpy(fb, fn); + } + + /*Add the extension*/ + if (fb[i] != '.') + { + strcat(fb, "."); + strcat(fb, strlen(ft)?ft:"rel"); + } + + fp = fopen(fb, omode); + if (fp==NULL) + { + if (strcmp(ft,"adb"))/*Do not complaint for optional adb files*/ + { + fprintf(stderr, "%s: cannot %s.\n", fb, wf?"create":"open"); + lkerr++; + } + } + return (fp); } -/*)Function VOID iramsav() +/*)Function VOID iramsav() * - * The function iramsav() stores the size of the chip's internal RAM. - * This is used after linking to check that variable assignment to this - * dataspace didn't overflow into adjoining segments. Variables in the - * DSEG, OSEG, and ISEG are assigned to this dataspace. + * The function iramsav() stores the size of the chip's internal RAM. + * This is used after linking to check that variable assignment to this + * dataspace didn't overflow into adjoining segments. Variables in the + * DSEG, OSEG, and ISEG are assigned to this dataspace. * - * local variables: - * none + * local variables: + * none * - * global variables: - * char *ip pointer into the REL file - * text line in ib[] - * unsigned int size of chip's internal - * iram_size RAM segment + * global variables: + * char *ip pointer into the REL file + * text line in ib[] + * unsigned int size of chip's internal + * iram_size RAM segment * - * functions called: - * char getnb() lklex.c - * VOID unget() lklex.c - * Addr_T expr() lkeval.c + * functions called: + * char getnb() lklex.c + * VOID unget() lklex.c + * Addr_T expr() lkeval.c * - * side effects: - * The iram_size may be modified. + * side effects: + * The iram_size may be modified. */ VOID @@ -1280,10 +1282,11 @@ iramsav() { unget(getnb()); if (ip && *ip) - //iram_size = atoi(ip); - iram_size = expr(0); /* evaluate size expression */ + iram_size = expr(0); /* evaluate size expression */ else - iram_size = 128; /* Default is 128 (0x80) bytes */ + iram_size = 128; /* Default is 128 (0x80) bytes */ + if ((iram_size<=0) || (iram_size>256)) + iram_size = 128; /* Default is 128 (0x80) bytes */ } /*Similar to iramsav but for xram memory*/ @@ -1292,9 +1295,9 @@ xramsav() { unget(getnb()); if (ip && *ip) - xram_size = expr(0); /* evaluate size expression */ + xram_size = expr(0); /* evaluate size expression */ else - xram_size = rflag?0x1000000:0x10000; + xram_size = rflag?0x1000000:0x10000; } /*Similar to iramsav but for code memory*/ @@ -1303,31 +1306,31 @@ codesav() { unget(getnb()); if (ip && *ip) - code_size = expr(0); /* evaluate size expression */ + code_size = expr(0); /* evaluate size expression */ else - code_size = rflag?0x1000000:0x10000; + code_size = rflag?0x1000000:0x10000; } -/*)Function VOID iramcheck() +/*)Function VOID iramcheck() * - * The function iramcheck() is used at the end of linking to check that - * the internal RAM area wasn't overflowed by too many variable - * assignments. Variables in the DSEG, ISEG, and OSEG are assigned to - * the chip's internal RAM. + * The function iramcheck() is used at the end of linking to check that + * the internal RAM area wasn't overflowed by too many variable + * assignments. Variables in the DSEG, ISEG, and OSEG are assigned to + * the chip's internal RAM. * - * local variables: - * none + * local variables: + * none * - * global variables: - * unsigned int size of chip's internal - * iram_size RAM segment - * struct area linked list of memory - * *areap areas + * global variables: + * unsigned int size of chip's internal + * iram_size RAM segment + * struct area linked list of memory + * *areap areas * - * functions called: + * functions called: * - * side effects: + * side effects: */ VOID @@ -1346,100 +1349,100 @@ iramcheck() { last_addr = ap->a_addr + ap->a_size - 1; if (last_addr >= iram_size) - fprintf(stderr, - "\nWARNING! Segment %s extends past the end\n" - " of internal RAM. Check map file.\n", - ap->a_id); + fprintf(stderr, + "\nWARNING! Segment %s extends past the end\n" + " of internal RAM. Check map file.\n", + ap->a_id); } } } char *usetxt[] = { - "Startup:", - " -c Command line input", - " -f file[LNK] File input", - " -p Prompt and echo of file[LNK] to stdout (default)", - " -n No echo of file[LNK] to stdout", -/* "Usage: [-Options] file [file ...]", */ - "Libraries:", - " -k Library path specification, one per -k", - " -l Library file specification, one per -l", - "Relocation:", - " -b area base address = expression", - " -g global symbol = expression", - "Map format:", - " -m Map output generated as file[MAP]", - " -x Hexadecimal (default), -d Decimal, -q Octal", - "Output:", - " -i Intel Hex as file[IHX]", - " -s Motorola S19 as file[S19]", - " -j Produce NoICE debug as file[NOI]", - " -z Produce SDCdb debug as file[cdb]", -/* "List:", */ - " -u Update listing file(s) with link data as file(s)[.RST]", - "Miscellaneous:\n" - " -a [iram-size] Check for internal RAM overflow", - " -v [xram-size] Check for external RAM overflow", - " -w [code-size] Check for code overflow", - " -y Generate memory usage summary file[mem]", - " -Y Pack internal ram", - " -A [stack-size] Allocate space for stack", - "End:", - " -e or null line terminates input", - 0 + "Startup:", + " -c Command line input", + " -f file[LNK] File input", + " -p Prompt and echo of file[LNK] to stdout (default)", + " -n No echo of file[LNK] to stdout", +/* "Usage: [-Options] file [file ...]", */ + "Libraries:", + " -k Library path specification, one per -k", + " -l Library file specification, one per -l", + "Relocation:", + " -b area base address = expression", + " -g global symbol = expression", + "Map format:", + " -m Map output generated as file[MAP]", + " -x Hexadecimal (default), -d Decimal, -q Octal", + "Output:", + " -i Intel Hex as file[IHX]", + " -s Motorola S19 as file[S19]", + " -j Produce NoICE debug as file[NOI]", + " -z Produce SDCdb debug as file[cdb]", +/* "List:", */ + " -u Update listing file(s) with link data as file(s)[.RST]", + "Miscellaneous:\n" + " -a [iram-size] Check for internal RAM overflow", + " -v [xram-size] Check for external RAM overflow", + " -w [code-size] Check for code overflow", + " -y Generate memory usage summary file[mem]", + " -Y Pack internal ram", + " -A [stack-size] Allocate space for stack", + "End:", + " -e or null line terminates input", + 0 }; -/*)Function VOID usage() +/*)Function VOID usage() * - * The function usage() outputs to the stderr device the - * assembler name and version and a list of valid assembler options. + * The function usage() outputs to the stderr device the + * assembler name and version and a list of valid assembler options. * - * local variables: - * char ** dp pointer to an array of - * text string pointers. + * local variables: + * char ** dp pointer to an array of + * text string pointers. * - * global variables: - * FILE * stderr c_library + * global variables: + * FILE * stderr c_library * - * functions called: - * int fprintf() c_library + * functions called: + * int fprintf() c_library * - * side effects: - * none + * side effects: + * none */ VOID usage() { - register char **dp; + register char **dp; - fprintf(stderr, "\nASxxxx Linker %s\n\n", VERSION); - for (dp = usetxt; *dp; dp++) - fprintf(stderr, "%s\n", *dp); - lkexit(1); + fprintf(stderr, "\nASxxxx Linker %s\n\n", VERSION); + for (dp = usetxt; *dp; dp++) + fprintf(stderr, "%s\n", *dp); + lkexit(1); } -/*)Function VOID copyfile() - * - * FILE *dest destination file - * FILE *src source file +/*)Function VOID copyfile() + * + * FILE *dest destination file + * FILE *src source file * * function will copy source file to destination file * * - * functions called: - * int fgetc() c_library - * int fputc() c_library + * functions called: + * int fgetc() c_library + * int fputc() c_library * - * side effects: - * none + * side effects: + * none */ VOID copyfile (dest,src) FILE *src,*dest ; -{ +{ int ch; while ((ch = fgetc(src)) != EOF) { - fputc(ch,dest); + fputc(ch,dest); } } diff --git a/as/mcs51/lkmem.c b/as/mcs51/lkmem.c index 4e452f2e..d330f055 100644 --- a/as/mcs51/lkmem.c +++ b/as/mcs51/lkmem.c @@ -24,446 +24,462 @@ #include "aslink.h" #include "strcmpi.h" -int summary(struct area * areap) +int summary(struct area * areap) { - #define EQ(A,B) !as_strcmpi((A),(B)) - #define MIN_STACK 16 - #define REPORT_ERROR(A, H) \ - {\ - fprintf(of, "%s%s", (H)?"*** ERROR: ":"", (A)); \ - fprintf(stderr, "%s%s", (H)?"\n?ASlink-Error-":"",(A)); \ - toreturn=1; \ - } - - #define REPORT_WARNING(A, H) \ - { \ - fprintf(of, "%s%s", (H)?"*** WARNING: ":"", (A)); \ - fprintf(stderr, "%s%s",(H)?"\n?ASlink-Warning-":"", (A)); \ - } - - char buff[128]; - int j, toreturn=0; - unsigned int Total_Last=0, k; - - struct area * xp; - FILE * of; - - /*Artifacts used for printing*/ - char start[15], end[15], size[15], max[15]; - char format[]=" %-16.16s %-8.8s %-8.8s %-8.8s %-8.8s\n"; - char line[]="---------------------"; - - typedef struct - { - unsigned long Start; - unsigned long Size; - unsigned long Max; - char Name[NCPS]; - unsigned long flag; - } _Mem; - - unsigned int dram[0x100]; - _Mem Ram[]={ - {0, 8, 8, "REG_BANK_0", 0x0001}, - {0x8, 8, 8, "REG_BANK_1", 0x0002}, - {0x10, 8, 8, "REG_BANK_2", 0x0004}, - {0x18, 8, 8, "REG_BANK_3", 0x0008}, - {0x20, 0, 16, "BSEG_BYTES", 0x0010}, - {0, 0, 128, "UNUSED", 0x0000}, - {0x7f, 0, 128, "DATA", 0x0020}, - {0, 0, 128, "TOTAL:", 0x0000} - }; - - _Mem IRam= {0xff, 0, 128, "INDIRECT RAM", 0x0080}; - _Mem Stack={0xff, 0, 1, "STACK", 0x0000}; - _Mem XRam= {0xffff, 0, 65536, "EXTERNAL RAM", 0x0100}; - _Mem Rom= {0xffff, 0, 65536, "ROM/EPROM/FLASH", 0x0200}; - - if(stacksize==0) stacksize=MIN_STACK; - - if(rflag) /*For the DS390*/ - { - XRam.Max=0x1000000; /*24 bits*/ - XRam.Start=0xffffff; - Rom.Max=0x1000000; - Rom.Start=0xffffff; - } - - if((iram_size<=0)||(iram_size>0x100)) /*Default: 8052 like memory*/ - { - Ram[5].Max=0x80; - Ram[6].Max=0x80; - Ram[7].Max=0x80; - IRam.Max=0x80; - iram_size=0x100; - } - else if(iram_size<0x80) - { - Ram[5].Max=iram_size; - Ram[6].Max=iram_size; - Ram[7].Max=iram_size; - IRam.Max=0; - } - else - { - Ram[5].Max=0x80; - Ram[6].Max=0x80; - Ram[7].Max=0x80; - IRam.Max=iram_size-0x80; - } - - for(j=0; j<(int)iram_size; j++) dram[j]=0; - for(; j<0x100; j++) dram[j]=0x8000; /*Memory not available*/ - - /* Open Memory Summary File*/ - of = afile(linkp->f_idp, "mem", 1); - if (of == NULL) - { - lkexit(1); - } - - xp=areap; - while (xp) - { - /**/ if (EQ(xp->a_id, "REG_BANK_0")) - { - Ram[0].Size=xp->a_size; - } - else if (EQ(xp->a_id, "REG_BANK_1")) - { - Ram[1].Size=xp->a_size; - } - else if (EQ(xp->a_id, "REG_BANK_2")) - { - Ram[2].Size=xp->a_size; - } - else if (EQ(xp->a_id, "REG_BANK_3")) - { - Ram[3].Size=xp->a_size; - } - else if (EQ(xp->a_id, "BSEG_BYTES")) - { - Ram[4].Size=xp->a_size; - } + #define EQ(A,B) !as_strcmpi((A),(B)) + #define MIN_STACK 16 + #define REPORT_ERROR(A, H) \ + {\ + fprintf(of, "%s%s", (H)?"*** ERROR: ":"", (A)); \ + fprintf(stderr, "%s%s", (H)?"\n?ASlink-Error-":"",(A)); \ + toreturn=1; \ + } + + #define REPORT_WARNING(A, H) \ + { \ + fprintf(of, "%s%s", (H)?"*** WARNING: ":"", (A)); \ + fprintf(stderr, "%s%s",(H)?"\n?ASlink-Warning-":"", (A)); \ + } + + char buff[128]; + int j, toreturn=0; + unsigned int Total_Last=0, k; + + struct area * xp; + FILE * of; + + /*Artifacts used for printing*/ + char start[15], end[15], size[15], max[15]; + char format[]=" %-16.16s %-8.8s %-8.8s %-8.8s %-8.8s\n"; + char line[]="---------------------"; + + typedef struct + { + unsigned long Start; + unsigned long Size; + unsigned long Max; + char Name[NCPS]; + unsigned long flag; + } _Mem; + + unsigned int dram[0x100]; + _Mem Ram[]={ + {0, 8, 8, "REG_BANK_0", 0x0001}, + {0x8, 8, 8, "REG_BANK_1", 0x0002}, + {0x10, 8, 8, "REG_BANK_2", 0x0004}, + {0x18, 8, 8, "REG_BANK_3", 0x0008}, + {0x20, 0, 16, "BSEG_BYTES", 0x0010}, + {0, 0, 128, "UNUSED", 0x0000}, + {0x7f, 0, 128, "DATA", 0x0020}, + {0, 0, 128, "TOTAL:", 0x0000} + }; + + _Mem IRam= {0xff, 0, 128, "INDIRECT RAM", 0x0080}; + _Mem Stack={0xff, 0, 1, "STACK", 0x0000}; + _Mem XRam= {0xffff, 0, 65536, "EXTERNAL RAM", 0x0100}; + _Mem Rom= {0xffff, 0, 65536, "ROM/EPROM/FLASH", 0x0200}; + + if(stacksize==0) stacksize=MIN_STACK; + + if(rflag) /*For the DS390*/ + { + XRam.Max=0x1000000; /*24 bits*/ + XRam.Start=0xffffff; + Rom.Max=0x1000000; + Rom.Start=0xffffff; + } + + if((iram_size<=0)||(iram_size>0x100)) /*Default: 8052 like memory*/ + { + Ram[5].Max=0x80; + Ram[6].Max=0x80; + Ram[7].Max=0x80; + IRam.Max=0x80; + iram_size=0x100; + } + else if(iram_size<0x80) + { + Ram[5].Max=iram_size; + Ram[6].Max=iram_size; + Ram[7].Max=iram_size; + IRam.Max=0; + } + else + { + Ram[5].Max=0x80; + Ram[6].Max=0x80; + Ram[7].Max=0x80; + IRam.Max=iram_size-0x80; + } + + for(j=0; j<(int)iram_size; j++) dram[j]=0; + for(; j<0x100; j++) dram[j]=0x8000; /*Memory not available*/ + + /* Open Memory Summary File*/ + of = afile(linkp->f_idp, "mem", 1); + if (of == NULL) + { + lkexit(1); + } + + xp=areap; + while (xp) + { + /**/ if (EQ(xp->a_id, "REG_BANK_0")) + { + Ram[0].Size=xp->a_size; + } + else if (EQ(xp->a_id, "REG_BANK_1")) + { + Ram[1].Size=xp->a_size; + } + else if (EQ(xp->a_id, "REG_BANK_2")) + { + Ram[2].Size=xp->a_size; + } + else if (EQ(xp->a_id, "REG_BANK_3")) + { + Ram[3].Size=xp->a_size; + } + else if (EQ(xp->a_id, "BSEG_BYTES")) + { + Ram[4].Size=xp->a_size; + } else if(xp->a_flag & A_CODE) - { + { if(xp->a_size>0) { - Rom.Size+=xp->a_size; - if(xp->a_addra_addr; + Rom.Size+=xp->a_size; + if(xp->a_addra_addr; } - } - - else if (EQ(xp->a_id, "SSEG")) - { - Stack.Size+=xp->a_size; - if(xp->a_addra_addr; - } + } + + else if (EQ(xp->a_id, "SSEG")) + { + Stack.Size+=xp->a_size; + if(xp->a_addra_addr; + } else if(xp->a_flag & A_XDATA) - { + { if(xp->a_size>0) { - XRam.Size+=xp->a_size; - if(xp->a_addra_addr; + XRam.Size+=xp->a_size; + if(xp->a_addra_addr; } - } + } - else if (EQ(xp->a_id, "ISEG")) - { - IRam.Size+=xp->a_size; - if(xp->a_addra_addr; - } + else if (EQ(xp->a_id, "ISEG")) + { + IRam.Size+=xp->a_size; + if(xp->a_addra_addr; + } /*If is not a register bank, bit, stack, or idata, then it should be data*/ else if((xp->a_flag & (A_CODE|A_BIT|A_XDATA))==0) - { + { if(xp->a_size) { - Ram[6].Size+=xp->a_size; - if(xp->a_addra_addr; + Ram[6].Size+=xp->a_size; + if(xp->a_addra_addr; } - } + } xp=xp->a_ap; - } - - for(j=0; j<7; j++) - for(k=Ram[j].Start; (k<(Ram[j].Start+Ram[j].Size))&&(k<0x100); k++) - dram[k]|=Ram[j].flag; /*Mark as used*/ - - for(k=IRam.Start; (k<(IRam.Start+IRam.Size))&&(k<0x100); k++) - dram[k]|=IRam.flag; /*Mark as used*/ - - /*Compute the amount of unused memory in direct data Ram. This is the - gap between the last register bank or bit segment and the data segment.*/ - for(k=Ram[6].Start-1; (dram[k]==0) && (k>0); k--); - Ram[5].Start=k+1; - Ram[5].Size=Ram[6].Start-Ram[5].Start; /*It may be zero (which is good!)*/ - - /*Compute the data Ram totals*/ - for(j=0; j<7; j++) - { - if(Ram[7].Start>Ram[j].Start) Ram[7].Start=Ram[j].Start; - Ram[7].Size+=Ram[j].Size; - } - Total_Last=Ram[6].Size+Ram[6].Start-1; - - /*Report the Ram totals*/ - fprintf(of, "Direct Internal RAM:\n"); - fprintf(of, format, "Name", "Start", "End", "Size", "Max"); - - for(j=0; j<8; j++) - { - if((j==0) || (j==7)) fprintf(of, format, line, line, line, line, line); - if((j!=5) || (Ram[j].Size>0)) - { - sprintf(start, "0x%02lx", Ram[j].Start); - if(Ram[j].Size==0) - end[0]=0;/*Empty string*/ - else - sprintf(end, "0x%02lx", j==7?Total_Last:Ram[j].Size+Ram[j].Start-1); - sprintf(size, "%5lu", Ram[j].Size); - sprintf(max, "%5lu", Ram[j].Max); - fprintf(of, format, Ram[j].Name, start, end, size, max); - } - } - - for(k=Ram[6].Start; (k<(Ram[6].Start+Ram[6].Size))&&(k<0x100); k++) - { - if(dram[k]!=Ram[6].flag) - { - sprintf(buff, "Internal memory overlap starting at 0x%02x.\n", k); - REPORT_ERROR(buff, 1); - break; - } - } - - if(Ram[4].Size>Ram[4].Max) - { - k=Ram[4].Size-Ram[4].Max; - sprintf(buff, "Insufficient bit addressable memory. " - "%d byte%s short.\n", k, (k==1)?"":"s"); - REPORT_ERROR(buff, 1); - } - - if(Ram[5].Size!=0) - { - sprintf(buff, "%ld bytes in data memory wasted. " - "SDCC link could use: --data-loc 0x%02lx\n", - Ram[5].Size, Ram[6].Start-Ram[5].Size); - REPORT_WARNING(buff, 1); - } - - if((Ram[6].Start+Ram[6].Size)>Ram[6].Max) - { - k=(Ram[6].Start+Ram[6].Size)-Ram[6].Max; - sprintf(buff, "Insufficient space in data memory. " - "%d byte%s short.\n", k, (k==1)?"":"s"); - REPORT_ERROR(buff, 1); - } - - /*Report the position of the begining of the stack*/ - fprintf(of, "\n%stack starts at: 0x%02lx (sp set to 0x%02lx)", - rflag ? "16 bit mode initial s" : "S", Stack.Start, Stack.Start-1); - - /*Check that the stack pointer is landing in a safe place:*/ - if( (dram[Stack.Start] & 0x8000) == 0x8000 ) - { - fprintf(of, ".\n"); - sprintf(buff, "Stack set to unavailable memory.\n"); - REPORT_ERROR(buff, 1); - } - else if(dram[Stack.Start]) - { - fprintf(of, ".\n"); - sprintf(buff, "Stack overlaps area "); - REPORT_ERROR(buff, 1); - for(j=0; j<7; j++) - { - if(dram[Stack.Start]&Ram[j].flag) - { - sprintf(buff, "'%s'\n", Ram[j].Name); - break; - } - } - if(dram[Stack.Start]&IRam.flag) - { - sprintf(buff, "'%s'\n", IRam.Name); - } - REPORT_ERROR(buff, 0); - } - else - { - for(j=Stack.Start, k=0; (j<(int)iram_size)&&(dram[j]==0); j++, k++); - fprintf(of, " with %d bytes available\n", k); - if ((int)k(IRam.Max+0x80)) - { - sprintf(buff, "Insufficient INDIRECT RAM memory.\n"); - REPORT_ERROR(buff, 1); - } - if( ((XRam.Start+XRam.Size)>XRam.Max) || - (((int)XRam.Size>xram_size)&&(xram_size>=0)) ) - { - sprintf(buff, "Insufficient EXTERNAL RAM memory.\n"); - REPORT_ERROR(buff, 1); - } - if( ((Rom.Start+Rom.Size)>Rom.Max) || - (((int)Rom.Size>code_size)&&(code_size>=0)) ) - { - sprintf(buff, "Insufficient ROM/EPROM/FLASH memory.\n"); - REPORT_ERROR(buff, 1); - } - - fclose(of); - return toreturn; + } + + for(j=0; j<7; j++) + for(k=Ram[j].Start; (k<(Ram[j].Start+Ram[j].Size))&&(k<0x100); k++) + dram[k]|=Ram[j].flag; /*Mark as used*/ + + for(k=IRam.Start; (k<(IRam.Start+IRam.Size))&&(k<0x100); k++) + dram[k]|=IRam.flag; /*Mark as used*/ + + /*Compute the amount of unused memory in direct data Ram. This is the + gap between the last register bank or bit segment and the data segment.*/ + for(k=Ram[6].Start-1; (dram[k]==0) && (k>0); k--); + Ram[5].Start=k+1; + Ram[5].Size=Ram[6].Start-Ram[5].Start; /*It may be zero (which is good!)*/ + + /*Compute the data Ram totals*/ + for(j=0; j<7; j++) + { + if(Ram[7].Start>Ram[j].Start) Ram[7].Start=Ram[j].Start; + Ram[7].Size+=Ram[j].Size; + } + Total_Last=Ram[6].Size+Ram[6].Start-1; + + /*Report the Ram totals*/ + fprintf(of, "Direct Internal RAM:\n"); + fprintf(of, format, "Name", "Start", "End", "Size", "Max"); + + for(j=0; j<8; j++) + { + if((j==0) || (j==7)) fprintf(of, format, line, line, line, line, line); + if((j!=5) || (Ram[j].Size>0)) + { + sprintf(start, "0x%02lx", Ram[j].Start); + if(Ram[j].Size==0) + end[0]=0;/*Empty string*/ + else + sprintf(end, "0x%02lx", j==7?Total_Last:Ram[j].Size+Ram[j].Start-1); + sprintf(size, "%5lu", Ram[j].Size); + sprintf(max, "%5lu", Ram[j].Max); + fprintf(of, format, Ram[j].Name, start, end, size, max); + } + } + + for(k=Ram[6].Start; (k<(Ram[6].Start+Ram[6].Size))&&(k<0x100); k++) + { + if(dram[k]!=Ram[6].flag) + { + sprintf(buff, "Internal memory overlap starting at 0x%02x.\n", k); + REPORT_ERROR(buff, 1); + break; + } + } + + if(Ram[4].Size>Ram[4].Max) + { + k=Ram[4].Size-Ram[4].Max; + sprintf(buff, "Insufficient bit addressable memory. " + "%d byte%s short.\n", k, (k==1)?"":"s"); + REPORT_ERROR(buff, 1); + } + + if(Ram[5].Size!=0) + { + sprintf(buff, "%ld bytes in data memory wasted. " + "SDCC link could use: --data-loc 0x%02lx\n", + Ram[5].Size, Ram[6].Start-Ram[5].Size); + REPORT_WARNING(buff, 1); + } + + if((Ram[6].Start+Ram[6].Size)>Ram[6].Max) + { + k=(Ram[6].Start+Ram[6].Size)-Ram[6].Max; + sprintf(buff, "Insufficient space in data memory. " + "%d byte%s short.\n", k, (k==1)?"":"s"); + REPORT_ERROR(buff, 1); + } + + /*Report the position of the beginning of the stack*/ + fprintf(of, "\n%stack starts at: 0x%02lx (sp set to 0x%02lx)", + rflag ? "16 bit mode initial s" : "S", Stack.Start, Stack.Start-1); + + /*Check that the stack pointer is landing in a safe place:*/ + if( (dram[Stack.Start] & 0x8000) == 0x8000 ) + { + fprintf(of, ".\n"); + sprintf(buff, "Stack set to unavailable memory.\n"); + REPORT_ERROR(buff, 1); + } + else if(dram[Stack.Start]) + { + fprintf(of, ".\n"); + sprintf(buff, "Stack overlaps area "); + REPORT_ERROR(buff, 1); + for(j=0; j<7; j++) + { + if(dram[Stack.Start]&Ram[j].flag) + { + sprintf(buff, "'%s'\n", Ram[j].Name); + break; + } + } + if(dram[Stack.Start]&IRam.flag) + { + sprintf(buff, "'%s'\n", IRam.Name); + } + REPORT_ERROR(buff, 0); + } + else + { + for(j=Stack.Start, k=0; (j<(int)iram_size)&&(dram[j]==0); j++, k++); + fprintf(of, " with %d bytes available\n", k); + if ((int)k(IRam.Max+0x80)) + { + sprintf(buff, "Insufficient INDIRECT RAM memory.\n"); + REPORT_ERROR(buff, 1); + } + if( ((XRam.Start+XRam.Size)>XRam.Max) || + (((int)XRam.Size>xram_size)&&(xram_size>=0)) ) + { + sprintf(buff, "Insufficient EXTERNAL RAM memory.\n"); + REPORT_ERROR(buff, 1); + } + if( ((Rom.Start+Rom.Size)>Rom.Max) || + (((int)Rom.Size>code_size)&&(code_size>=0)) ) + { + sprintf(buff, "Insufficient ROM/EPROM/FLASH memory.\n"); + REPORT_ERROR(buff, 1); + } + + fclose(of); + return toreturn; } extern char idatamap[]; //0:not used, 1:used -int summary2(struct area * areap) +int summary2(struct area * areap) { - #define EQ(A,B) !as_strcmpi((A),(B)) - - char buff[128]; - int j, toreturn=0; - long int Stack_Start=0, Stack_size; - - struct area * xp; - FILE * of; - - /*Artifacts used for printing*/ - char start[15], end[15], size[15], max[15]; - char format[]=" %-16.16s %-8.8s %-8.8s %-8.8s %-8.8s\n"; - char line[]="---------------------"; - - typedef struct - { - unsigned long Start; - unsigned long Size; - unsigned long Max; - char Name[NCPS]; - unsigned long flag; - } _Mem; - - _Mem Stack={0xff, 0, 1, "STACK", 0x0000}; - _Mem XRam= {0xffff, 0, 65536, "EXTERNAL RAM", 0x0100}; - _Mem Rom= {0xffff, 0, 65536, "ROM/EPROM/FLASH", 0x0200}; - - if(rflag) /*For the DS390*/ - { - XRam.Max=0x1000000; /*24 bits*/ - XRam.Start=0xffffff; - Rom.Max=0x1000000; - Rom.Start=0xffffff; - } - - /* Open Memory Summary File*/ - of = afile(linkp->f_idp, "mem", 1); - if (of == NULL) - { - lkexit(1); - } - - xp=areap; - while (xp) - { + #define EQ(A,B) !as_strcmpi((A),(B)) + + char buff[128]; + int toreturn = 0; + unsigned int j; + unsigned long int Stack_Start=0, Stack_Size; + + struct area * xp; + struct area * xstack_xp = NULL; + FILE * of; + + /*Artifacts used for printing*/ + char start[15], end[15], size[15], max[15]; + char format[]=" %-16.16s %-8.8s %-8.8s %-8.8s %-8.8s\n"; + char line[]="---------------------"; + + typedef struct + { + unsigned long Start; + unsigned long Size; + unsigned long Max; + char Name[NCPS]; + unsigned long flag; + } _Mem; + + _Mem Stack={0xff, 0, 1, "STACK", 0x0000}; + _Mem Paged={0xff, 0, 256, "PAGED EXT. RAM", A_PAG}; + _Mem XRam= {0xffff, 0, 65536, "EXTERNAL RAM", 0x0100}; + _Mem Rom= {0xffff, 0, 65536, "ROM/EPROM/FLASH", 0x0200}; + + if(rflag) /*For the DS390*/ + { + XRam.Max=0x1000000; /*24 bits*/ + XRam.Start=0xffffff; + Rom.Max=0x1000000; + Rom.Start=0xffffff; + } + + /* Open Memory Summary File*/ + of = afile(linkp->f_idp, "mem", 1); + if (of == NULL) + { + lkexit(1); + } + + xp=areap; + while (xp) + { if(xp->a_flag & A_CODE) - { + { if(xp->a_size) { - Rom.Size+=xp->a_size; - if(xp->a_addra_addr; + Rom.Size+=xp->a_size; + if(xp->a_addra_addr; } - } - - else if (EQ(xp->a_id, "SSEG")) - { - Stack.Size+=xp->a_size; - if(xp->a_addra_addr; - } + } + + else if (EQ(xp->a_id, "SSEG")) + { + Stack.Size+=xp->a_size; + if(xp->a_addra_addr; + } + + else if (EQ(xp->a_id, "PSEG")) + { + Paged.Size+=xp->a_size; + if(xp->a_addra_addr; + } + + else if (EQ(xp->a_id, "XSTK")) + { + xstack_xp = xp; + Paged.Size+=xp->a_size; + if(xp->a_addra_addr; + } else if(xp->a_flag & A_XDATA) - { + { if(xp->a_size) { - XRam.Size+=xp->a_size; - if(xp->a_addra_addr; + XRam.Size+=xp->a_size; + if(xp->a_addra_addr; } - } + } - xp=xp->a_ap; - } + xp=xp->a_ap; + } - /*Report the Ram totals*/ - fprintf(of, "Internal RAM layout:\n"); - fprintf(of, " 0 1 2 3 4 5 6 7 8 9 A B C D E F"); + /*Report the Ram totals*/ + fprintf(of, "Internal RAM layout:\n"); + fprintf(of, " 0 1 2 3 4 5 6 7 8 9 A B C D E F"); for(j=0; j<256; j++) - { - if(j%16==0) fprintf(of, "\n0x%02x:|", j); - fprintf(of, "%c|", idatamap[j]); - } - fprintf(of, "\n0-3:Reg Banks, a-z:Data, B:Bits, Q:Overlay, I:iData, S:Stack\n"); + { + if(j%16==0) fprintf(of, "\n0x%02x:|", j); + fprintf(of, "%c|", idatamap[j]); + } + fprintf(of, "\n0-3:Reg Banks, a-z:Data, B:Bits, Q:Overlay, I:iData, S:Stack\n"); for(j=0; j<256; j++) { @@ -474,80 +490,104 @@ int summary2(struct area * areap) } } - for(j=Stack_Start, Stack_size=0; j<256; j++) + for(j=Stack_Start, Stack_Size=0; j<((iram_size)?iram_size:256); j++) { - if((idatamap[j]=='S')||(idatamap[j]==' ')) Stack_size++; + if((idatamap[j]=='S')||(idatamap[j]==' ')) Stack_Size++; else break; } - - xp=areap; - while (xp) + + xp=areap; + while (xp) { if(xp->a_unaloc>0) { - fprintf(of, "\nERROR: Couldn't get %d byte%s allocated" + fprintf(of, "\nERROR: Couldn't get %d byte%s allocated" " in internal RAM for area %s.", xp->a_unaloc, xp->a_unaloc>1?"s":"", xp->a_id); toreturn=1; } - xp=xp->a_ap; + xp=xp->a_ap; } - /*Report the position of the begining of the stack*/ + /*Report the position of the begining of the stack*/ if(Stack_Start!=256) - fprintf(of, "\n%stack starts at: 0x%02lx (sp set to 0x%02lx) with %ld bytes available.", - rflag ? "16 bit mode initial s" : "S", Stack_Start, Stack_Start-1, Stack_size); + fprintf(of, "\n%stack starts at: 0x%02lx (sp set to 0x%02lx) with %ld bytes available.", + rflag ? "16 bit mode initial s" : "S", Stack_Start, Stack_Start-1, Stack_Size); else fprintf(of, "\nI don't have a clue where the stack ended up! Sorry..."); - fprintf(of, "\n\nOther memory:\n"); - fprintf(of, format, "Name", "Start", "End", "Size", "Max"); - fprintf(of, format, line, line, line, line, line); + /*Report about xstack*/ + if (xstack_xp) + { + Stack_Start = xstack_xp->a_addr; + Stack_Size = xstack_xp->a_size; + fprintf(of, "\nXstack starts at: 0x%04lx with %ld bytes available.", + Stack_Start, Stack_Size); + } + + fprintf(of, "\n\nOther memory:\n"); + fprintf(of, format, "Name", "Start", "End", "Size", "Max"); + fprintf(of, format, line, line, line, line, line); - /*Report XRam totals:*/ - if(XRam.Size==0) + /*Report Paged XRam totals:*/ + if(Paged.Size==0) { start[0]=0;/*Empty string*/ - end[0]=0;/*Empty string*/ + end[0]=0;/*Empty string*/ + } + else + { + sprintf(start, "0x%04lx", Paged.Start); + sprintf(end, "0x%04lx", Paged.Size+Paged.Start-1); } - else + sprintf(size, "%5lu", Paged.Size); + sprintf(max, "%5lu", xram_size<0 ? Paged.Max : xram_size<256 ? xram_size : 256); + fprintf(of, format, Paged.Name, start, end, size, max); + + /*Report XRam totals:*/ + if(XRam.Size==0) + { + start[0]=0;/*Empty string*/ + end[0]=0;/*Empty string*/ + } + else { - sprintf(start, "0x%04lx", XRam.Start); - sprintf(end, "0x%04lx", XRam.Size+XRam.Start-1); + sprintf(start, "0x%04lx", XRam.Start); + sprintf(end, "0x%04lx", XRam.Size+XRam.Start-1); } - sprintf(size, "%5lu", XRam.Size); - sprintf(max, "%5lu", xram_size<0?XRam.Max:xram_size); - fprintf(of, format, XRam.Name, start, end, size, max); + sprintf(size, "%5lu", XRam.Size); + sprintf(max, "%5lu", xram_size<0?XRam.Max:xram_size); + fprintf(of, format, XRam.Name, start, end, size, max); - /*Report Rom/Flash totals:*/ - if(Rom.Size==0) + /*Report Rom/Flash totals:*/ + if(Rom.Size==0) { start[0]=0;/*Empty string*/ - end[0]=0;/*Empty string*/ - } - else - { - sprintf(start, "0x%04lx", Rom.Start); - sprintf(end, "0x%04lx", Rom.Size+Rom.Start-1); - } - sprintf(size, "%5lu", Rom.Size); - sprintf(max, "%5lu", code_size<0?Rom.Max:code_size); - fprintf(of, format, Rom.Name, start, end, size, max); - - /*Report any excess:*/ - if( ((XRam.Start+XRam.Size)>XRam.Max) || - (((int)XRam.Size>xram_size)&&(xram_size>=0)) ) - { - sprintf(buff, "Insufficient EXTERNAL RAM memory.\n"); - REPORT_ERROR(buff, 1); - } - if( ((Rom.Start+Rom.Size)>Rom.Max) || - (((int)Rom.Size>code_size)&&(code_size>=0)) ) - { - sprintf(buff, "Insufficient ROM/EPROM/FLASH memory.\n"); - REPORT_ERROR(buff, 1); - } - - fclose(of); - return toreturn; + end[0]=0;/*Empty string*/ + } + else + { + sprintf(start, "0x%04lx", Rom.Start); + sprintf(end, "0x%04lx", Rom.Size+Rom.Start-1); + } + sprintf(size, "%5lu", Rom.Size); + sprintf(max, "%5lu", code_size<0?Rom.Max:code_size); + fprintf(of, format, Rom.Name, start, end, size, max); + + /*Report any excess:*/ + if( ((XRam.Start+XRam.Size)>XRam.Max) || + (((int)XRam.Size>xram_size)&&(xram_size>=0)) ) + { + sprintf(buff, "Insufficient EXTERNAL RAM memory.\n"); + REPORT_ERROR(buff, 1); + } + if( ((Rom.Start+Rom.Size)>Rom.Max) || + (((int)Rom.Size>code_size)&&(code_size>=0)) ) + { + sprintf(buff, "Insufficient ROM/EPROM/FLASH memory.\n"); + REPORT_ERROR(buff, 1); + } + + fclose(of); + return toreturn; } diff --git a/device/lib/Makefile.in b/device/lib/Makefile.in index e8e33845..447ef06b 100644 --- a/device/lib/Makefile.in +++ b/device/lib/Makefile.in @@ -173,10 +173,17 @@ models: done \ fi -model-mcs51-reentrant: +model-mcs51-stack-auto: if [ "`grep mcs51 ../../ports.build`" = mcs51 ]; then \ for model in $(MODELS); do \ - $(MAKE) MODELFLAGS="--model-$$model --stack-auto --int-long-reent --float-reent" PORT=reent-$$model objects; \ + $(MAKE) MODELFLAGS="--model-$$model --stack-auto" PORT=$$model-stack-auto objects; \ + done \ + fi + +model-mcs51-xstack-auto: + if [ "`grep mcs51 ../../ports.build`" = mcs51 ]; then \ + for model in $(MODELS); do \ + $(MAKE) MODELFLAGS="--model-$$model --stack-auto --xstack" PORT=$$model-xstack-auto objects; \ done \ fi diff --git a/device/lib/_mullong.c b/device/lib/_mullong.c index 1a37ce25..6a0669ff 100644 --- a/device/lib/_mullong.c +++ b/device/lib/_mullong.c @@ -542,6 +542,34 @@ union bil { |3.0| G |-------> only this side 32 x 32 -> 32 */ +#if defined(SDCC_USE_XSTACK) +// currently the original code without u fails with --xstack +// it runs out of pointer registers +long +_mullong (long a, long b) +{ + union bil t, u; + + t.i.hi = bcast(a)->b.b0 * bcast(b)->b.b2; // A + t.i.lo = bcast(a)->b.b0 * bcast(b)->b.b0; // A + u.bi.b3 = bcast(a)->b.b0 * bcast(b)->b.b3; // B + u.bi.i12 = bcast(a)->b.b0 * bcast(b)->b.b1; // B + u.bi.b0 = 0; // B + t.l += u.l; + + t.b.b3 += bcast(a)->b.b3 * bcast(b)->b.b0; // G + t.b.b3 += bcast(a)->b.b2 * bcast(b)->b.b1; // F + t.i.hi += bcast(a)->b.b2 * bcast(b)->b.b0; // E + t.i.hi += bcast(a)->b.b1 * bcast(b)->b.b1; // D + + u.bi.b3 = bcast(a)->b.b1 * bcast(b)->b.b2; // C + u.bi.i12 = bcast(a)->b.b1 * bcast(b)->b.b0; // C + u.bi.b0 = 0; // C + t.l += u.l; + + return t.l; +} +#else long _mullong (long a, long b) { @@ -572,5 +600,6 @@ _mullong (long a, long b) return t.l + b; } +#endif #endif // _MULLONG_ASM diff --git a/device/lib/mcs51/crtclear.asm b/device/lib/mcs51/crtclear.asm index 3ccaca84..672ec1dc 100644 --- a/device/lib/mcs51/crtclear.asm +++ b/device/lib/mcs51/crtclear.asm @@ -1,24 +1,24 @@ ; /*------------------------------------------------------------------------- -; +; ; crtclear.asm :- C run-time: clear DATA/IDATA -; +; ; This library is free software; you can redistribute it and/or modify it ; under the terms of the GNU Library General Public License as published by the ; Free Software Foundation; either version 2, or (at your option) any ; later version. -; +; ; This library is distributed in the hope that it will be useful, ; but WITHOUT ANY WARRANTY; without even the implied warranty of ; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ; GNU Library General Public License for more details. -; +; ; You should have received a copy of the GNU Library General Public License ; along with this program; if not, write to the Free Software ; Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -; +; ; In other words, you are welcome to use, share and improve this program. ; You are forbidden to forbid anyone else to use, share and improve -; what you give them. Help stamp out software-hoarding! +; what you give them. Help stamp out software-hoarding! ; -------------------------------------------------------------------------*/ .area CSEG (CODE) @@ -30,12 +30,12 @@ .area GSINIT5 (CODE) .area GSINIT (CODE) .area GSFINAL (CODE) - + .area GSINIT4 (CODE) __mcs51_genRAMCLEAR:: clr a - mov r0,a -00005$: mov @r0,a + mov r0,#(l_IRAM-1) +00005$: mov @r0,a djnz r0,00005$ ; _mcs51_genRAMCLEAR() end diff --git a/device/lib/mcs51/crtxclear.asm b/device/lib/mcs51/crtxclear.asm index 819c111b..f7db6a88 100644 --- a/device/lib/mcs51/crtxclear.asm +++ b/device/lib/mcs51/crtxclear.asm @@ -34,16 +34,27 @@ .area GSINIT4 (CODE) __mcs51_genXRAMCLEAR:: + mov r0,#l_PSEG + mov a,r0 + orl a,#(l_PSEG >> 8) + jz 00005$ + mov r1,#s_PSEG + mov __XPAGE,#(s_PSEG >> 8) + clr a +00004$: movx @r1,a + inc r1 + djnz r0,00004$ +00005$: mov r0,#l_XSEG mov a,r0 orl a,#(l_XSEG >> 8) - jz 00005$ + jz 00007$ mov r1,#((l_XSEG + 255) >> 8) mov dptr,#s_XSEG clr a -00004$: movx @dptr,a +00006$: movx @dptr,a inc dptr - djnz r0,00004$ - djnz r1,00004$ -00005$: + djnz r0,00006$ + djnz r1,00006$ +00007$: diff --git a/device/lib/mcs51/crtxstack.asm b/device/lib/mcs51/crtxstack.asm index 38e6d135..9fbf66d2 100644 --- a/device/lib/mcs51/crtxstack.asm +++ b/device/lib/mcs51/crtxstack.asm @@ -46,7 +46,7 @@ __sdcc_init_xstack:: .area GSINIT5 (CODE) -; Need to initialize in GSINIT5 because __mcs51_genXINIT modifies __PAGESFR +; Need to initialize in GSINIT5 because __mcs51_genXINIT modifies __XPAGE ; and __mcs51_genRAMCLEAR modifies _spx. mov __XPAGE,#(__start__xstack >> 8) diff --git a/src/SDCCglue.c b/src/SDCCglue.c index 8f5510b4..acb2d342 100644 --- a/src/SDCCglue.c +++ b/src/SDCCglue.c @@ -39,10 +39,9 @@ symbol *interrupts[INTNO_MAX+1]; void printIval (symbol *, sym_link *, initList *, FILE *); set *publics = NULL; /* public variables */ -set *externs = NULL; /* Varibles that are declared as extern */ +set *externs = NULL; /* Variables that are declared as extern */ -/* TODO: this should be configurable (DS803C90 uses more than 6) */ -unsigned maxInterrupts = 6; +unsigned maxInterrupts = 0; int allocInfo = 1; symbol *mainf; set *pipeSet = NULL; /* set of pipes */ @@ -1321,6 +1320,7 @@ emitMaps (void) emitRegularMap (data, TRUE, TRUE); emitRegularMap (idata, TRUE, TRUE); emitRegularMap (bit, TRUE, FALSE); + emitRegularMap (pdata, TRUE, TRUE); emitRegularMap (xdata, TRUE, TRUE); if (port->genXINIT) { emitRegularMap (xidata, TRUE, TRUE); @@ -1355,7 +1355,6 @@ flushStatics (void) void createInterruptVect (FILE * vFile) { - unsigned i = 0; mainf = newSymbol ("main", 0); mainf->block = 0; @@ -1382,28 +1381,8 @@ createInterruptVect (FILE * vFile) if (!port->genIVT || !(port->genIVT (vFile, interrupts, maxInterrupts))) { - /* "generic" interrupt table header (if port doesn't specify one). - * Look suspiciously like 8051 code to me... - */ - - fprintf (vFile, "\tljmp\t__sdcc_gsinit_startup\n"); - - /* now for the other interrupts */ - for (; i < maxInterrupts; i++) - { - if (interrupts[i]) - { - fprintf (vFile, "\tljmp\t%s\n", interrupts[i]->rname); - if ( i != maxInterrupts - 1 ) - fprintf (vFile, "\t.ds\t5\n"); - } - else - { - fprintf (vFile, "\treti\n"); - if ( i != maxInterrupts - 1 ) - fprintf (vFile, "\t.ds\t7\n"); - } - } + /* There's no such thing as a "generic" interrupt table header. */ + wassert(0); } } @@ -1774,18 +1753,26 @@ glue (void) copyFile (asmFile, bit->oFile); } - /* if external stack then reserve space of it */ + /* copy paged external ram data */ + if (mcs51_like) + { + fprintf (asmFile, "%s", iComments2); + fprintf (asmFile, "; paged external ram data\n"); + fprintf (asmFile, "%s", iComments2); + copyFile (asmFile, pdata->oFile); + } + + /* if external stack then reserve space for it */ if (mainf && IFFUNC_HASBODY(mainf->type) && options.useXstack) { fprintf (asmFile, "%s", iComments2); fprintf (asmFile, "; external stack \n"); fprintf (asmFile, "%s", iComments2); - fprintf (asmFile, "\t.area XSEG (XDATA)\n"); /* MOF */ - fprintf (asmFile, "\t.ds 256\n"); + fprintf (asmFile, "\t.area XSTK (PAG,XDATA)\n" + "__start__xstack:\n\t.ds\t1\n\n"); } - - /* copy xtern ram data */ + /* copy external ram data */ if (mcs51_like) { fprintf (asmFile, "%s", iComments2); fprintf (asmFile, "; external ram data\n"); @@ -1793,7 +1780,7 @@ glue (void) copyFile (asmFile, xdata->oFile); } - /* copy xternal initialized ram data */ + /* copy external initialized ram data */ fprintf (asmFile, "%s", iComments2); fprintf (asmFile, "; external initialized ram data\n"); fprintf (asmFile, "%s", iComments2); @@ -1930,9 +1917,9 @@ glue (void) /** Creates a temporary file with unique file name Scans, in order: - - TMP, TEMP, TMPDIR env. varibles + - TMP, TEMP, TMPDIR env. variables - if Un*x system: /usr/tmp and /tmp - - root directory using mkstemp() if avaliable + - root directory using mkstemp() if available - default location using tempnam() */ static int diff --git a/src/SDCCmain.c b/src/SDCCmain.c index c9668217..9ffc2f04 100644 --- a/src/SDCCmain.c +++ b/src/SDCCmain.c @@ -103,15 +103,18 @@ char buffer[PATH_MAX * 2]; #define OPTION_DUMP_ALL "--dumpall" #define OPTION_PEEP_FILE "--peep-file" #define OPTION_LIB_PATH "--lib-path" -#define OPTION_XSTACK_LOC "--xstack-loc" #define OPTION_CALLEE_SAVES "--callee-saves" #define OPTION_STACK_LOC "--stack-loc" +#define OPTION_XSTACK_LOC "--xstack-loc" +#define OPTION_DATA_LOC "--data-loc" +#define OPTION_IDATA_LOC "--idata-loc" #define OPTION_XRAM_LOC "--xram-loc" +#define OPTION_CODE_LOC "--code-loc" +#define OPTION_STACK_SIZE "--stack-size" #define OPTION_IRAM_SIZE "--iram-size" +#define OPTION_XRAM_SIZE "--xram-size" +#define OPTION_CODE_SIZE "--code-size" #define OPTION_VERSION "--version" -#define OPTION_DATA_LOC "--data-loc" -#define OPTION_CODE_LOC "--code-loc" -#define OPTION_IDATA_LOC "--idata-loc" #define OPTION_NO_LABEL_OPT "--nolabelopt" #define OPTION_NO_LOOP_INV "--noinvariant" #define OPTION_NO_LOOP_IND "--noinduction" @@ -121,14 +124,11 @@ char buffer[PATH_MAX * 2]; #define OPTION_SHORT_IS_8BITS "--short-is-8bits" #define OPTION_TINI_LIBID "--tini-libid" #define OPTION_NO_XINIT_OPT "--no-xinit-opt" -#define OPTION_XRAM_SIZE "--xram-size" -#define OPTION_CODE_SIZE "--code-size" #define OPTION_NO_CCODE_IN_ASM "--no-c-code-in-asm" #define OPTION_ICODE_IN_ASM "--i-code-in-asm" #define OPTION_PRINT_SEARCH_DIRS "--print-search-dirs" #define OPTION_MSVC_ERROR_STYLE "--vc" #define OPTION_USE_STDOUT "--use-stdout" -#define OPTION_STACK_SIZE "--stack-size" #define OPTION_PACK_IRAM "--pack-iram" #define OPTION_NO_PEEP_COMMENTS "--no-peep-comments" #define OPTION_OPT_CODE_SPEED "--opt-code-speed" @@ -172,12 +172,10 @@ optionsTable[] = { { 0, OPTION_SMALL_MODEL, NULL, "internal data space is used (default)" }, #if !OPT_DISABLE_DS390 { 0, OPTION_FLAT24_MODEL, NULL, "use the flat24 model for the ds390 (default)" }, -#endif - { 0, "--stack-auto", &options.stackAuto, "Stack automatic variables" }, -#if !OPT_DISABLE_DS390 { 0, OPTION_STACK_8BIT, NULL, "use the 8bit stack for the ds390 (not supported yet)" }, { 0, "--stack-10bit", &options.stack10bit, "use the 10bit stack for ds390 (default)" }, #endif + { 0, "--stack-auto", &options.stackAuto, "Stack automatic variables" }, { 0, "--xstack", &options.useXstack, "Use external stack" }, { 0, "--int-long-reent", &options.intlong_rent, "Use reenterant calls on the int and long support functions" }, { 0, "--float-reent", &options.float_rent, "Use reenterant calls on the float support functions" }, @@ -1337,6 +1335,13 @@ parseCmdLine (int argc, char **argv) /* else no module given: help text is displayed */ } + /* set int, long and float reentrancy based on stack-auto */ + if (options.stackAuto) + { + options.intlong_rent++; + options.float_rent++; + } + /* set up external stack location if not explicitly specified */ if (!options.xstack_loc) options.xstack_loc = options.xdata_loc; @@ -1450,8 +1455,12 @@ linkEdit (char **envp) WRITE_SEG_LOC (DATA_NAME, options.data_loc); } - /* xdata start */ - WRITE_SEG_LOC (XDATA_NAME, options.xdata_loc); + /* xdata segment start. If zero, the linker chooses + the best place for xdata */ + if(options.xdata_loc) + { + WRITE_SEG_LOC (XDATA_NAME, options.xdata_loc); + } /* indirect data */ if (IDATA_NAME) @@ -1459,14 +1468,14 @@ linkEdit (char **envp) WRITE_SEG_LOC (IDATA_NAME, options.idata_loc); } - /* bit segment start */ - WRITE_SEG_LOC (BIT_NAME, 0); + /* bit segment start */ + WRITE_SEG_LOC (BIT_NAME, 0); - /* stack start */ - if ( (options.stack_loc) && (options.stack_loc<0x100) ) - { - WRITE_SEG_LOC ("SSEG", options.stack_loc); - } + /* stack start */ + if ( (options.stack_loc) && (options.stack_loc<0x100) ) + { + WRITE_SEG_LOC ("SSEG", options.stack_loc); + } } else /*For the z80, gbz80*/ { @@ -1494,7 +1503,7 @@ linkEdit (char **envp) { switch (options.model) { - case MODEL_SMALL: + case MODEL_SMALL: c = "small"; break; case MODEL_LARGE: diff --git a/src/SDCCmem.c b/src/SDCCmem.c index b2a8c7b5..1e062c54 100644 --- a/src/SDCCmem.c +++ b/src/SDCCmem.c @@ -9,6 +9,7 @@ memmap *xstack = NULL; /* xternal stack data */ memmap *istack = NULL; /* internal stack */ memmap *code = NULL; /* code segment */ memmap *data = NULL; /* internal data upto 128 */ +memmap *pdata = NULL; /* paged external data */ memmap *xdata = NULL; /* external data */ memmap *xidata = NULL; /* the initialized xdata */ memmap *xinit = NULL; /* the initializers for xidata */ @@ -175,6 +176,22 @@ initMem () overlay = NULL; } + /* Xternal paged segment ; + SFRSPACE - NO + FAR-SPACE - YES + PAGED - YES + DIRECT-ACCESS - NO + BIT-ACCESS - NO + CODE-ACESS - NO + DEBUG-NAME - 'P' + POINTER-TYPE - PPOINTER + */ + if (PDATA_NAME) { + pdata = allocMap (0, 1, 1, 0, 0, 0, options.xstack_loc, PDATA_NAME, 'P', PPOINTER); + } else { + pdata = NULL; + } + /* Xternal Data segment - SFRSPACE - NO FAR-SPACE - YES @@ -189,7 +206,7 @@ initMem () xidata = allocMap (0, 1, 0, 0, 0, 0, 0, XIDATA_NAME, 'F', FPOINTER); xinit = allocMap (0, 1, 0, 0, 0, 1, 0, XINIT_NAME, 'C', CPOINTER); - /* Inderectly addressed internal data segment + /* Indirectly addressed internal data segment SFRSPACE - NO FAR-SPACE - NO PAGED - NO @@ -203,7 +220,7 @@ initMem () idata = allocMap (0, 0, 0, 0, 0, 0, options.idata_loc, IDATA_NAME, 'G', IPOINTER); } else { - idata=NULL; + idata = NULL; } /* Static segment (code for variables ); @@ -327,21 +344,21 @@ allocGlobal (symbol * sym) then put it in the interrupt service array */ if (FUNC_ISISR (sym->type) && !options.noiv && (FUNC_INTNO (sym->type) != INTNO_UNSPEC)) - { - if (interrupts[FUNC_INTNO (sym->type)]) - werror (E_INT_DEFINED, - FUNC_INTNO (sym->type), - interrupts[FUNC_INTNO (sym->type)]->name); - else - interrupts[FUNC_INTNO (sym->type)] = sym; - - /* automagically extend the maximum interrupts */ - if (FUNC_INTNO (sym->type) >= maxInterrupts) - maxInterrupts = FUNC_INTNO (sym->type) + 1; - } + { + if (interrupts[FUNC_INTNO (sym->type)]) + werror (E_INT_DEFINED, + FUNC_INTNO (sym->type), + interrupts[FUNC_INTNO (sym->type)]->name); + else + interrupts[FUNC_INTNO (sym->type)] = sym; + + /* automagically extend the maximum interrupts */ + if (FUNC_INTNO (sym->type) >= maxInterrupts) + maxInterrupts = FUNC_INTNO (sym->type) + 1; + } /* if it is not compiler defined */ if (!sym->cdef) - allocIntoSeg (sym); + allocIntoSeg (sym); return; } @@ -377,8 +394,8 @@ allocGlobal (symbol * sym) if(!TARGET_IS_PIC16 || (TARGET_IS_PIC16 && sym->level)) /* register storage class ignored changed to FIXED */ - if (SPEC_SCLS (sym->etype) == S_REGISTER) - SPEC_SCLS (sym->etype) = S_FIXED; + if (SPEC_SCLS (sym->etype) == S_REGISTER) + SPEC_SCLS (sym->etype) = S_FIXED; /* if data specified then */ if (SPEC_SCLS (sym->etype) == S_DATA) @@ -418,9 +435,9 @@ allocGlobal (symbol * sym) // should we move this to the initialized data segment? if (port->genXINIT && sym->ival && (sym->level==0) && !SPEC_ABSA(sym->etype)) { - SPEC_OCLS(sym->etype)=xidata; + SPEC_OCLS(sym->etype)=xidata; } else { - SPEC_OCLS (sym->etype) = xdata; + SPEC_OCLS (sym->etype) = xdata; } allocIntoSeg (sym); return; @@ -434,6 +451,14 @@ allocGlobal (symbol * sym) return; } + if (SPEC_SCLS (sym->etype) == S_PDATA) + { + SPEC_OCLS (sym->etype) = pdata; + sym->iaccess = 1; + allocIntoSeg (sym); + return; + } + if (SPEC_SCLS (sym->etype) == S_EEPROM) { SPEC_OCLS (sym->etype) = eeprom; @@ -463,7 +488,7 @@ allocParms (value * val) it as a local variable by adding it to the first block we see in the body */ if (IS_REGPARM (lval->etype)) - continue; + continue; /* mark it as my parameter */ lval->sym->ismyparm = 1; @@ -472,20 +497,20 @@ allocParms (value * val) /* if automatic variables r 2b stacked */ if (options.stackAuto || IFFUNC_ISREENT (currFunc->type)) - { + { - if (lval->sym) - lval->sym->onStack = 1; + if (lval->sym) + lval->sym->onStack = 1; /* choose which stack 2 use */ /* use xternal stack */ if (options.useXstack) { - /* PENDING: stack direction support */ - SPEC_OCLS (lval->etype) = SPEC_OCLS (lval->sym->etype) = xstack; - SPEC_STAK (lval->etype) = SPEC_STAK (lval->sym->etype) = lval->sym->stack = - xstackPtr - getSize (lval->type); - xstackPtr -= getSize (lval->type); + /* PENDING: stack direction support */ + SPEC_OCLS (lval->etype) = SPEC_OCLS (lval->sym->etype) = xstack; + SPEC_STAK (lval->etype) = SPEC_STAK (lval->sym->etype) = lval->sym->stack = + xstackPtr - getSize (lval->type); + xstackPtr -= getSize (lval->type); } else { /* use internal stack */ @@ -623,7 +648,7 @@ allocLocal (symbol * sym) /* this is automatic */ - /* if it to be placed on the stack */ + /* if it's to be placed on the stack */ if (options.stackAuto || reentrant) { sym->onStack = 1; if (options.useXstack) { @@ -833,15 +858,15 @@ allocVariables (symbol * symChain) /* if this is a function or a pointer to function */ /* then args processing */ if (funcInChain (csym->type)) - { - processFuncArgs (csym); - - /* if register bank specified then update maxRegBank */ - if (maxRegBank < FUNC_REGBANK (csym->type)) - maxRegBank = FUNC_REGBANK (csym->type); - /*JCF: Mark the register bank as used*/ - RegBankUsed[FUNC_REGBANK(csym->type)]=1; - } + { + processFuncArgs (csym); + + /* if register bank specified then update maxRegBank */ + if (maxRegBank < FUNC_REGBANK (csym->type)) + maxRegBank = FUNC_REGBANK (csym->type); + /*JCF: Mark the register bank as used*/ + RegBankUsed[FUNC_REGBANK(csym->type)]=1; + } /* if this is a extern variable then change the */ /* level to zero temporarily */ diff --git a/src/SDCCmem.h b/src/SDCCmem.h index 505d5ecb..6b9dcfcc 100644 --- a/src/SDCCmem.h +++ b/src/SDCCmem.h @@ -36,6 +36,7 @@ extern FILE *junkFile; #define CODE_NAME port->mem.code_name #define DATA_NAME port->mem.data_name #define IDATA_NAME port->mem.idata_name +#define PDATA_NAME port->mem.pdata_name #define XDATA_NAME port->mem.xdata_name #define XIDATA_NAME port->mem.xidata_name #define XINIT_NAME port->mem.xinit_name @@ -46,24 +47,25 @@ extern FILE *junkFile; #define OVERLAY_NAME port->mem.overlay_name /* forward definition for variables */ -extern memmap *xstack; /* xternal stack data */ -extern memmap *istack; /* internal stack */ -extern memmap *code; /* code segment */ -extern memmap *data; /* internal data upto 128 */ -extern memmap *xdata; /* external data */ -extern memmap *xidata; /* the initialized xdata */ -extern memmap *xinit; /* the initializers for xidata */ -extern memmap *idata; /* internal data upto 256 */ -extern memmap *bit; /* bit addressable space */ -extern memmap *statsg; /* static code segment */ -extern memmap *sfr; /* register space */ -extern memmap *sfrbit; /* sfr bit space */ -extern memmap *reg; /* register space */ -extern memmap *generic; /* unknown */ -extern memmap *overlay; /* the overlay segment */ -extern memmap *eeprom; /* eepromp space */ -extern memmap *eeprom; /* eepromp space */ -extern memmap *home; /* Non-banked home space */ +extern memmap *xstack; /* xternal stack data */ +extern memmap *istack; /* internal stack */ +extern memmap *code; /* code segment */ +extern memmap *data; /* internal data upto 128 */ +extern memmap *pdata; /* paged external data upto 256 */ +extern memmap *xdata; /* external data */ +extern memmap *xidata; /* the initialized xdata */ +extern memmap *xinit; /* the initializers for xidata */ +extern memmap *idata; /* internal data upto 256 */ +extern memmap *bit; /* bit addressable space */ +extern memmap *statsg; /* static code segment */ +extern memmap *sfr; /* register space */ +extern memmap *sfrbit; /* sfr bit space */ +extern memmap *reg; /* register space */ +extern memmap *generic; /* unknown */ +extern memmap *overlay; /* the overlay segment */ +extern memmap *eeprom; /* eepromp space */ +extern memmap *eeprom; /* eepromp space */ +extern memmap *home; /* Non-banked home space */ extern int fatalError; diff --git a/src/avr/main.c b/src/avr/main.c index e09ba53a..c5ff3622 100644 --- a/src/avr/main.c +++ b/src/avr/main.c @@ -42,7 +42,7 @@ _avr_init (void) } static void -_avr_reset_regparm () +_avr_reset_regparm (void) { regParmFlg = 0; } @@ -207,6 +207,7 @@ PORT avr_port = { "CSEG", "DSEG", "ISEG", + NULL, //PSEG "XSEG", "BSEG", "RSEG", diff --git a/src/ds390/main.c b/src/ds390/main.c index a1ff41aa..27a64e8d 100644 --- a/src/ds390/main.c +++ b/src/ds390/main.c @@ -70,7 +70,7 @@ _ds390_init (void) } static void -_ds390_reset_regparm () +_ds390_reset_regparm (void) { regParmFlg = 0; } @@ -235,8 +235,25 @@ _ds390_genIVT (FILE * of, symbol ** interrupts, int maxInterrupts) if (options.model != MODEL_FLAT24) { - /* Let the default code handle it. */ - return FALSE; + fprintf (of, "\tljmp\t__sdcc_gsinit_startup\n"); + + /* now for the other interrupts */ + for (i = 0; i < maxInterrupts; i++) + { + if (interrupts[i]) + { + fprintf (of, "\tljmp\t%s\n", interrupts[i]->rname); + if ( i != maxInterrupts - 1 ) + fprintf (of, "\t.ds\t5\n"); + } + else + { + fprintf (of, "\treti\n"); + if ( i != maxInterrupts - 1 ) + fprintf (of, "\t.ds\t7\n"); + } + } + return TRUE; } fprintf (of, "\tajmp\t__reset_vect\n"); @@ -846,6 +863,7 @@ PORT ds390_port = "CSEG (CODE)", "DSEG (DATA)", "ISEG (DATA)", + "PSEG (PAG,XDATA)", "XSEG (XDATA)", "BSEG (BIT)", "RSEG (DATA)", @@ -983,7 +1001,7 @@ static void _tininative_finaliseOptions (void) static int _tininative_genIVT (FILE * of, symbol ** interrupts, int maxInterrupts) { - return 1; + return TRUE; } static void _tininative_genAssemblerPreamble (FILE * of) { @@ -1157,13 +1175,14 @@ PORT tininative_port = "CSEG (CODE)", "DSEG (DATA)", "ISEG (DATA)", + "PSEG (PAG,XDATA)", "XSEG (XDATA)", "BSEG (BIT)", "RSEG (DATA)", "GSINIT (CODE)", "OSEG (OVR,DATA)", "GSFINAL (CODE)", - "HOME (CODE)", + "HOME (CODE)", NULL, NULL, NULL, @@ -1383,6 +1402,7 @@ PORT ds400_port = "CSEG (CODE)", "DSEG (DATA)", "ISEG (DATA)", + "PSEG (PAG,XDATA)", "XSEG (XDATA)", "BSEG (BIT)", "RSEG (DATA)", diff --git a/src/hc08/main.c b/src/hc08/main.c index f5efd860..5e8555c9 100644 --- a/src/hc08/main.c +++ b/src/hc08/main.c @@ -62,7 +62,7 @@ _hc08_init (void) } static void -_hc08_reset_regparm () +_hc08_reset_regparm (void) { regParmFlg = 0; } @@ -423,6 +423,7 @@ PORT hc08_port = "CSEG (CODE)", "DSEG", NULL, /* "ISEG" */ + NULL, /* "PSEG" */ "XSEG", "BSEG", "RSEG", diff --git a/src/mcs51/gen.c b/src/mcs51/gen.c index a19a133b..5cea9722 100644 --- a/src/mcs51/gen.c +++ b/src/mcs51/gen.c @@ -68,8 +68,16 @@ static struct { short r0Pushed; short r1Pushed; - short r0InB; - short r1InB; + union + { + struct + { + short r0InB : 2;//2 so we can see it overflow + short r1InB : 2;//2 so we can see it overflow + short OpInB : 2;//2 so we can see it overflow + } ; + short BInUse; + } ; short accInUse; short inLine; short debugLine; @@ -88,13 +96,14 @@ extern int mcs51_ptrRegReq; extern int mcs51_nRegs; extern FILE *codeOutFile; static void saveRBank (int, iCode *, bool); + #define RESULTONSTACK(x) \ (IC_RESULT(x) && IC_RESULT(x)->aop && \ IC_RESULT(x)->aop->type == AOP_STK ) -#define MOVA(x) mova(x) /* use function to avoid multiple eval */ -#define CLRC emitcode("clr","c") -#define SETC emitcode("setb","c") +#define MOVA(x) mova(x) /* use function to avoid multiple eval */ +#define CLRC emitcode("clr","c") +#define SETC emitcode("setb","c") static lineNode *lineHead = NULL; static lineNode *lineCurr = NULL; @@ -126,21 +135,21 @@ emitcode (char *inst, const char *fmt,...) if (inst && *inst) { if (fmt && *fmt) - SNPRINTF (lb, sizeof(lb), "%s\t", inst); + SNPRINTF (lb, sizeof(lb), "%s\t", inst); else - SNPRINTF (lb, sizeof(lb), "%s", inst); + SNPRINTF (lb, sizeof(lb), "%s", inst); tvsprintf (lb + strlen(lb), sizeof(lb) - strlen(lb), fmt, ap); } else - tvsprintf (lb, sizeof(lb), fmt, ap); + tvsprintf (lb, sizeof(lb), fmt, ap); while (isspace (*lbp)) - lbp++; + lbp++; if (lbp && *lbp) - lineCurr = (lineCurr ? - connectLine (lineCurr, newLineNode (lb)) : - (lineHead = newLineNode (lb))); + lineCurr = (lineCurr ? + connectLine (lineCurr, newLineNode (lb)) : + (lineHead = newLineNode (lb))); lineCurr->isInline = _G.inLine; lineCurr->isDebug = _G.debugLine; lineCurr->ic = _G.current_iCode; @@ -167,12 +176,49 @@ static void mova (const char *x) { /* do some early peephole optimization */ - if (!strcmp(x, "a") || !strcmp(x, "acc")) + if (!strncmp(x, "a", 2) || !strncmp(x, "acc", 4)) return; emitcode("mov","a,%s", x); } +/*-----------------------------------------------------------------*/ +/* pushB - saves register B if necessary */ +/*-----------------------------------------------------------------*/ +static bool +pushB (void) +{ + bool pushedB = FALSE; + + if (_G.BInUse) + { + emitcode ("push", "b"); +// printf("B was in use !\n"); + pushedB = TRUE; + } + else + { + _G.OpInB++; + } + return pushedB; +} + +/*-----------------------------------------------------------------*/ +/* popB - restores value of register B if necessary */ +/*-----------------------------------------------------------------*/ +static void +popB (bool pushedB) +{ + if (pushedB) + { + emitcode ("pop", "b"); + } + else + { + _G.OpInB--; + } +} + /*-----------------------------------------------------------------*/ /* getFreePtr - returns r0 or r1 whichever is free or can be pushed */ /*-----------------------------------------------------------------*/ @@ -363,7 +409,6 @@ pointerCode (sym_link * etype) } - /*-----------------------------------------------------------------*/ /* leftRightUseAcc - returns size of accumulator use by operands */ /*-----------------------------------------------------------------*/ @@ -430,7 +475,6 @@ leftRightUseAcc(iCode *ic) return accuse; } - /*-----------------------------------------------------------------*/ /* aopForSym - for a true symbol */ /*-----------------------------------------------------------------*/ @@ -541,7 +585,7 @@ aopForRemat (symbol * sym) { iCode *ic = sym->rematiCode; asmop *aop = newAsmop (AOP_IMMD); - int ptr_type=0; + int ptr_type = 0; int val = 0; for (;;) @@ -1227,7 +1271,7 @@ aopPut (asmop * aop, const char *s, int offset, bool bvolatile) if (strcmp (d, s) || bvolatile) - emitcode ("mov", "%s,%s", d, s); + emitcode ("mov", "%s,%s", d, s); break; @@ -1546,9 +1590,33 @@ toBoolean (operand * oper) { int size = AOP_SIZE (oper) - 1; int offset = 1; - MOVA (aopGet (AOP (oper), 0, FALSE, FALSE)); - while (size--) - emitcode ("orl", "a,%s", aopGet (AOP (oper), offset++, FALSE, FALSE)); + char *l = aopGet (AOP (oper), 0, FALSE, FALSE); + bool pushedB; + + if (!strncmp (l, "a", 2) || !strncmp (l, "acc", 4)) + { + if (size--) + { + pushedB = pushB (); + emitcode("mov", "b,a"); + while (size--) + { + MOVA (aopGet (AOP (oper), offset++, FALSE, FALSE)); + emitcode ("orl", "b,a"); + } + MOVA (aopGet (AOP (oper), offset, FALSE, FALSE)); + emitcode ("orl", "a,b"); + popB (pushedB); + } + } + else + { + MOVA (l); + while (size--) + { + emitcode ("orl", "a,%s", aopGet (AOP (oper), offset++, FALSE, FALSE)); + } + } } @@ -1791,7 +1859,7 @@ saveRegisters (iCode * lic) IFFUNC_ISNAKED(OP_SYM_TYPE(IC_LEFT (ic))))) return; - /* safe the registers in use at this time but skip the + /* save the registers in use at this time but skip the ones for the result */ rsave = bitVectCplAnd (bitVectCopy (ic->rMask), mcs51_rUmaskForOp (IC_RESULT(ic))); @@ -1800,15 +1868,16 @@ saveRegisters (iCode * lic) if (options.useXstack) { if (bitVectBitValue (rsave, R0_IDX)) - emitcode ("mov", "b,r0"); + { + emitcode ("mov", "a,r0"); + emitcode ("push", "%s", mcs51_regWithIdx (R0_IDX)->dname); + } emitcode ("mov", "r0,%s", spname); for (i = 0; i < mcs51_nRegs; i++) { if (bitVectBitValue (rsave, i)) { - if (i == R0_IDX) - emitcode ("mov", "a,b"); - else + if (i != R0_IDX) emitcode ("mov", "a,%s", mcs51_regWithIdx (i)->name); emitcode ("movx", "@r0,a"); emitcode ("inc", "r0"); @@ -1816,7 +1885,9 @@ saveRegisters (iCode * lic) } emitcode ("mov", "%s,r0", spname); if (bitVectBitValue (rsave, R0_IDX)) - emitcode ("mov", "r0,b"); + { + emitcode ("pop", "%s", mcs51_regWithIdx (R0_IDX)->dname); + } } else for (i = 0; i < mcs51_nRegs; i++) @@ -1849,16 +1920,16 @@ unsaveRegisters (iCode * ic) { emitcode ("dec", "r0"); emitcode ("movx", "a,@r0"); - if (i == R0_IDX) - emitcode ("mov", "b,a"); - else + if (i != R0_IDX) emitcode ("mov", "%s,a", mcs51_regWithIdx (i)->name); } } emitcode ("mov", "%s,r0", spname); if (bitVectBitValue (rsave, R0_IDX)) - emitcode ("mov", "r0,b"); + { + emitcode ("mov", "r0,a"); + } } else for (i = mcs51_nRegs; i >= 0; i--) @@ -1888,9 +1959,9 @@ pushSide (operand * oper, int size) emitcode ("push", "acc"); } else - emitcode ("push", "%s", l); + emitcode ("push", "%s", l); + } } -} /*-----------------------------------------------------------------*/ /* assignResultValue - */ @@ -2012,8 +2083,8 @@ genIpush (iCode * ic) emitcode ("push", "acc"); } else - emitcode ("push", "%s", l); - } + emitcode ("push", "%s", l); + } freeAsmop (IC_LEFT (ic), NULL, ic, TRUE); } @@ -2164,14 +2235,14 @@ saveRBank (int bank, iCode * ic, bool pushPsw) emitcode ("mov", "psw,#0x%02x", (bank << 3) & 0x00ff); } - if (aop) + if (aop) { - freeAsmop (NULL, aop, ic, TRUE); + freeAsmop (NULL, aop, ic, TRUE); } if (ic) { - ic->bankSaved = 1; + ic->bankSaved = 1; } } @@ -3643,11 +3714,13 @@ genPlus (iCode * ic) { if (aopGetUsesAcc (leftOp, offset) && aopGetUsesAcc (rightOp, offset)) { - emitcode("mov", "b,a"); + bool pushedB; MOVA (aopGet (leftOp, offset, FALSE, TRUE)); + pushedB = pushB (); emitcode("xch", "a,b"); MOVA (aopGet (rightOp, offset, FALSE, TRUE)); emitcode (add, "a,b"); + popB (pushedB); } else if (aopGetUsesAcc (leftOp, offset)) { @@ -3924,13 +3997,26 @@ genMinus (iCode * ic) while (size--) { if (aopGetUsesAcc(rightOp, offset)) { - wassertl(!aopGetUsesAcc(leftOp, offset), "accumulator clash"); - MOVA (aopGet(rightOp, offset, FALSE, TRUE)); - if (offset == 0) { - emitcode( "setb", "c"); + if (aopGetUsesAcc(leftOp, offset)) { + bool pushedB; + + MOVA (aopGet (rightOp, offset, FALSE, FALSE)); + pushedB = pushB (); + emitcode ("mov", "b,a"); + if (offset == 0) + CLRC; + MOVA (aopGet (leftOp, offset, FALSE, FALSE)); + emitcode ("subb", "a,b"); + popB (pushedB); + } else { + wassertl(!aopGetUsesAcc(leftOp, offset), "accumulator clash"); + MOVA (aopGet(rightOp, offset, FALSE, TRUE)); + if (offset == 0) { + emitcode( "setb", "c"); + } + emitcode("subb", "a,%s", aopGet(leftOp, offset, FALSE, TRUE)); + emitcode("cpl", "a"); } - emitcode("subb", "a,%s", aopGet(leftOp, offset, FALSE, TRUE)); - emitcode("cpl", "a"); } else { MOVA (aopGet (leftOp, offset, FALSE, FALSE)); if (offset == 0) @@ -3979,7 +4065,7 @@ genMultOneByte (operand * left, symbol *lbl; int size = AOP_SIZE (result); bool runtimeSign, compiletimeSign; - bool lUnsigned, rUnsigned; + bool lUnsigned, rUnsigned, pushedB; D(emitcode ("; genMultOneByte","")); @@ -4012,6 +4098,8 @@ genMultOneByte (operand * left, lUnsigned = SPEC_USIGN (getSpec (operandType (left))); rUnsigned = SPEC_USIGN (getSpec (operandType (right))); + pushedB = pushB (); + if (size == 1 /* no, this is not a bug; with a 1 byte result there's no need to take care about the signedness! */ || (lUnsigned && rUnsigned)) @@ -4037,6 +4125,8 @@ genMultOneByte (operand * left, aopPut (AOP (result), "a", 0, isOperandVolatile (result, FALSE)); if (size == 2) aopPut (AOP (result), "b", 1, isOperandVolatile (result, FALSE)); + + popB (pushedB); return; } @@ -4163,6 +4253,8 @@ genMultOneByte (operand * left, aopPut (AOP (result), "a", 0, isOperandVolatile (result, FALSE)); if (size == 2) aopPut (AOP (result), "b", 1, isOperandVolatile (result, FALSE)); + + popB (pushedB); } /*-----------------------------------------------------------------*/ @@ -4222,11 +4314,13 @@ genDivbits (operand * left, operand * right, operand * result) { - char *l; + bool pushedB; D(emitcode ("; genDivbits","")); + pushedB = pushB (); + /* the result must be bit */ emitcode ("mov", "b,%s", aopGet (AOP (right), 0, FALSE, FALSE)); l = aopGet (AOP (left), 0, FALSE, FALSE); @@ -4235,6 +4329,9 @@ genDivbits (operand * left, emitcode ("div", "ab"); emitcode ("rrc", "a"); + + popB (pushedB); + aopPut (AOP (result), "c", 0, isOperandVolatile (result, FALSE)); } @@ -4246,7 +4343,7 @@ genDivOneByte (operand * left, operand * right, operand * result) { - bool lUnsigned, rUnsigned; + bool lUnsigned, rUnsigned, pushedB; bool runtimeSign, compiletimeSign; symbol *lbl; int size, offset; @@ -4284,6 +4381,8 @@ genDivOneByte (operand * left, lUnsigned = SPEC_USIGN (getSpec (operandType (left))); rUnsigned = SPEC_USIGN (getSpec (operandType (right))); + pushedB = pushB (); + /* signed or unsigned */ if (lUnsigned && rUnsigned) { @@ -4294,6 +4393,8 @@ genDivOneByte (operand * left, aopPut (AOP (result), "a", 0, isOperandVolatile (result, FALSE)); while (size--) aopPut (AOP (result), zero, offset++, isOperandVolatile (result, FALSE)); + + popB (pushedB); return; } @@ -4429,6 +4530,8 @@ genDivOneByte (operand * left, while (size--) aopPut (AOP (result), zero, offset++, isOperandVolatile (result, FALSE)); } + + popB (pushedB); } /*-----------------------------------------------------------------*/ @@ -4481,11 +4584,13 @@ genModbits (operand * left, operand * right, operand * result) { - char *l; + bool pushedB; D(emitcode ("; genModbits","")); + pushedB = pushB (); + /* the result must be bit */ emitcode ("mov", "b,%s", aopGet (AOP (right), 0, FALSE, FALSE)); l = aopGet (AOP (left), 0, FALSE, FALSE); @@ -4495,6 +4600,9 @@ genModbits (operand * left, emitcode ("div", "ab"); emitcode ("mov", "a,b"); emitcode ("rrc", "a"); + + popB (pushedB); + aopPut (AOP (result), "c", 0, isOperandVolatile (result, FALSE)); } @@ -4506,7 +4614,7 @@ genModOneByte (operand * left, operand * right, operand * result) { - bool lUnsigned, rUnsigned; + bool lUnsigned, rUnsigned, pushedB; bool runtimeSign, compiletimeSign; symbol *lbl; int size, offset; @@ -4518,6 +4626,8 @@ genModOneByte (operand * left, lUnsigned = SPEC_USIGN (getSpec (operandType (left))); rUnsigned = SPEC_USIGN (getSpec (operandType (right))); + pushedB = pushB (); + /* signed or unsigned */ if (lUnsigned && rUnsigned) { @@ -4528,6 +4638,8 @@ genModOneByte (operand * left, aopPut (AOP (result), "b", 0, isOperandVolatile (result, FALSE)); while (size--) aopPut (AOP (result), zero, offset++, isOperandVolatile (result, FALSE)); + + popB (pushedB); return; } @@ -4633,6 +4745,8 @@ genModOneByte (operand * left, while (size--) aopPut (AOP (result), zero, offset++, isOperandVolatile (result, FALSE)); } + + popB (pushedB); } /*-----------------------------------------------------------------*/ @@ -4789,9 +4903,13 @@ genCmp (operand * left, operand * right, CLRC; while (size--) { + bool pushedB = FALSE; rightInB = aopGetUsesAcc(AOP (right), offset); if (rightInB) - emitcode ("mov", "b,%s", aopGet (AOP (right), offset, FALSE, FALSE)); + { + pushedB = pushB (); + emitcode ("mov", "b,%s", aopGet (AOP (right), offset, FALSE, FALSE)); + } MOVA (aopGet (AOP (left), offset, FALSE, FALSE)); if (sign && size == 0) { @@ -4806,7 +4924,11 @@ genCmp (operand * left, operand * right, else { if (!rightInB) - emitcode ("mov", "b,%s", aopGet (AOP (right), offset, FALSE, FALSE)); + { + pushedB = pushB (); + rightInB++; + emitcode ("mov", "b,%s", aopGet (AOP (right), offset, FALSE, FALSE)); + } emitcode ("xrl", "b,#0x80"); emitcode ("subb", "a,b"); } @@ -4818,6 +4940,8 @@ genCmp (operand * left, operand * right, else emitcode ("subb", "a,%s", aopGet (AOP (right), offset, FALSE, FALSE)); } + if (rightInB) + popB (pushedB); offset++; } } @@ -4970,7 +5094,10 @@ gencjneshort (operand * left, operand * right, symbol * lbl) /* right is a pointer reg need both a & b */ while (size--) { - char *l = aopGet (AOP (left), offset, FALSE, FALSE); + char *l; + //if B in use: push B; mov B,left; mov A,right; clrc; subb A,B; pop B; jnz + wassertl(!_G.BInUse, "B was in use"); + l = aopGet (AOP (left), offset, FALSE, FALSE); if (strcmp (l, "b")) emitcode ("mov", "b,%s", l); MOVA (aopGet (AOP (right), offset, FALSE, FALSE)); @@ -5529,7 +5656,7 @@ genAnd (iCode * ic, iCode * ifx) "acc.%d", posbit & 0x07); genIfxJump (ifx, buffer, left, right, result); } - else + else {// what is this case? just found it in ds390/gen.c emitcode ("anl","a,#!constbyte",1 << (posbit & 0x07)); } @@ -5594,7 +5721,7 @@ genAnd (iCode * ic, iCode * ifx) if (isOperandVolatile (left, FALSE)) MOVA (aopGet (AOP (left), offset, FALSE, FALSE)); else - continue; + continue; } else if (bytelit == 0) { @@ -5649,9 +5776,11 @@ genAnd (iCode * ic, iCode * ifx) aopGet (AOP (right), offset, FALSE, FALSE)); } else { if (AOP_TYPE(left)==AOP_ACC) { + bool pushedB = pushB (); emitcode("mov", "b,a"); MOVA (aopGet (AOP (right), offset, FALSE, FALSE)); emitcode("anl", "a,b"); + popB (pushedB); }else { MOVA (aopGet (AOP (right), offset, FALSE, FALSE)); emitcode ("anl", "a,%s", @@ -6177,7 +6306,7 @@ genXor (iCode * ic, iCode * ifx) if (isOperandVolatile (left, FALSE)) MOVA (aopGet (AOP (left), offset, FALSE, FALSE)); else - continue; + continue; } else if (IS_AOP_PREG (left)) { @@ -6509,15 +6638,22 @@ genSwap (iCode * ic) else if (operandsEqu (left, result)) { char * reg = "a"; + bool pushedB = FALSE, leftInB = FALSE; + MOVA (aopGet (AOP (left), 0, FALSE, FALSE)); if (aopGetUsesAcc(AOP (left), 1) || aopGetUsesAcc(AOP (result), 0)) { + pushedB = pushB (); emitcode ("mov", "b,a"); reg = "b"; + leftInB = TRUE; } aopPut (AOP (result), aopGet (AOP (left), 1, FALSE, FALSE), 0, isOperandVolatile (result, FALSE)); aopPut (AOP (result), reg, 1, isOperandVolatile (result, FALSE)); + + if (leftInB) + popB (pushedB); } else { @@ -7397,6 +7533,7 @@ genLeftShift (iCode * ic) int size, offset; char *l; symbol *tlbl, *tlbl1; + bool pushedB; D(emitcode ("; genLeftShift","")); @@ -7420,14 +7557,14 @@ genLeftShift (iCode * ic) more that 32 bits make no sense anyway, ( the largest size of an object can be only 32 bits ) */ + pushedB = pushB (); emitcode ("mov", "b,%s", aopGet (AOP (right), 0, FALSE, FALSE)); emitcode ("inc", "b"); freeAsmop (right, NULL, ic, TRUE); aopOp (left, ic, FALSE); aopOp (result, ic, FALSE); - /* now move the left to the result if they are not the - same */ + /* now move the left to the result if they are not the same */ if (!sameRegs (AOP (left), AOP (result)) && AOP_SIZE (result) > 1) { @@ -7466,6 +7603,7 @@ genLeftShift (iCode * ic) emitcode ("add", "a,acc"); emitcode ("", "%05d$:", tlbl1->key + 100); emitcode ("djnz", "b,%05d$", tlbl->key + 100); + popB (pushedB); aopPut (AOP (result), "a", 0, isOperandVolatile (result, FALSE)); goto release; } @@ -7489,6 +7627,7 @@ genLeftShift (iCode * ic) emitcode ("", "%05d$:", tlbl1->key + 100); emitcode ("djnz", "b,%05d$", tlbl->key + 100); + popB (pushedB); release: freeAsmop (left, NULL, ic, TRUE); freeAsmop (result, NULL, ic, TRUE); @@ -7744,6 +7883,7 @@ genSignedRightShift (iCode * ic) int size, offset; char *l; symbol *tlbl, *tlbl1; + bool pushedB; D(emitcode ("; genSignedRightShift","")); @@ -7768,6 +7908,7 @@ genSignedRightShift (iCode * ic) more that 32 bits make no sense anyway, ( the largest size of an object can be only 32 bits ) */ + pushedB = pushB (); emitcode ("mov", "b,%s", aopGet (AOP (right), 0, FALSE, FALSE)); emitcode ("inc", "b"); freeAsmop (right, NULL, ic, TRUE); @@ -7817,6 +7958,7 @@ genSignedRightShift (iCode * ic) emitcode ("rrc", "a"); emitcode ("", "%05d$:", tlbl1->key + 100); emitcode ("djnz", "b,%05d$", tlbl->key + 100); + popB (pushedB); aopPut (AOP (result), "a", 0, isOperandVolatile (result, FALSE)); goto release; } @@ -7835,6 +7977,7 @@ genSignedRightShift (iCode * ic) reAdjustPreg (AOP (result)); emitcode ("", "%05d$:", tlbl1->key + 100); emitcode ("djnz", "b,%05d$", tlbl->key + 100); + popB (pushedB); release: freeAsmop (left, NULL, ic, TRUE); @@ -7852,6 +7995,7 @@ genRightShift (iCode * ic) int size, offset; char *l; symbol *tlbl, *tlbl1; + bool pushedB; D(emitcode ("; genRightShift","")); @@ -7892,6 +8036,7 @@ genRightShift (iCode * ic) more that 32 bits make no sense anyway, ( the largest size of an object can be only 32 bits ) */ + pushedB = pushB (); emitcode ("mov", "b,%s", aopGet (AOP (right), 0, FALSE, FALSE)); emitcode ("inc", "b"); freeAsmop (right, NULL, ic, TRUE); @@ -7937,6 +8082,7 @@ genRightShift (iCode * ic) emitcode ("rrc", "a"); emitcode ("", "%05d$:", tlbl1->key + 100); emitcode ("djnz", "b,%05d$", tlbl->key + 100); + popB (pushedB); aopPut (AOP (result), "a", 0, isOperandVolatile (result, FALSE)); goto release; } @@ -7956,6 +8102,7 @@ genRightShift (iCode * ic) emitcode ("", "%05d$:", tlbl1->key + 100); emitcode ("djnz", "b,%05d$", tlbl->key + 100); + popB (pushedB); release: freeAsmop (left, NULL, ic, TRUE); @@ -8077,18 +8224,18 @@ genUnpackBits (operand * result, char *rname, int ptype, iCode *ifx) SNPRINTF (buffer, sizeof(buffer), "acc.%d", bstr); genIfxJump (ifx, buffer, NULL, NULL, NULL); - } + } else { if (blen < 8) emitcode ("anl", "a,#0x%02x", - (((unsigned char) -1) >> (8 - blen)) << bstr); + (((unsigned char) -1) >> (8 - blen)) << bstr); genIfxJump (ifx, "a", NULL, NULL, NULL); - } + } return; } wassert (!ifx); - + /* If the bitfield length is less than a byte */ if (blen < 8) { @@ -8167,7 +8314,7 @@ genNearPointerGet (operand * left, operand * result, iCode * ic, iCode * pi, - iCode * ifx) + iCode * ifx) { asmop *aop = NULL; regs *preg = NULL; @@ -8248,7 +8395,7 @@ genNearPointerGet (operand * left, emitcode ("mov", "a,@%s", rname); if (!ifx) - aopPut (AOP (result), "a", offset, isOperandVolatile (result, FALSE)); + aopPut (AOP (result), "a", offset, isOperandVolatile (result, FALSE)); } else { @@ -8287,7 +8434,7 @@ genNearPointerGet (operand * left, emitcode ("dec", "%s", rname); } } - + if (ifx && !ifx->generated) { genIfxJump (ifx, "a", left, NULL, result); @@ -8307,7 +8454,7 @@ genPagedPointerGet (operand * left, operand * result, iCode * ic, iCode *pi, - iCode *ifx) + iCode *ifx) { asmop *aop = NULL; regs *preg = NULL; @@ -8352,7 +8499,7 @@ genPagedPointerGet (operand * left, emitcode ("movx", "a,@%s", rname); if (!ifx) - aopPut (AOP (result), "a", offset, isOperandVolatile (result, FALSE)); + aopPut (AOP (result), "a", offset, isOperandVolatile (result, FALSE)); offset++; @@ -8406,7 +8553,7 @@ loadDptrFromOperand (operand *op, bool loadBToo) { if (AOP_TYPE (op) != AOP_STR) { - /* if this is remateriazable */ + /* if this is rematerializable */ if (AOP_TYPE (op) == AOP_IMMD) { emitcode ("mov", "dptr,%s", aopGet (AOP (op), 0, TRUE, FALSE)); @@ -8487,20 +8634,19 @@ genFarPointerGet (operand * left, while (size--) { emitcode ("movx", "a,@dptr"); - if (!ifx) + if (!ifx) aopPut (AOP (result), "a", offset++, isOperandVolatile (result, FALSE)); if (size || pi) emitcode ("inc", "dptr"); } - } - + if (pi && AOP_TYPE (left) != AOP_IMMD && AOP_TYPE (left) != AOP_STR) { - aopPut ( AOP (left), "dpl", 0, isOperandVolatile (left, FALSE)); - aopPut ( AOP (left), "dph", 1, isOperandVolatile (left, FALSE)); - pi->generated = 1; - } + aopPut ( AOP (left), "dpl", 0, isOperandVolatile (left, FALSE)); + aopPut ( AOP (left), "dph", 1, isOperandVolatile (left, FALSE)); + pi->generated = 1; + } if (ifx && !ifx->generated) { @@ -8544,7 +8690,7 @@ genCodePointerGet (operand * left, emitcode ("clr", "a"); emitcode ("movc", "a,@a+dptr"); if (!ifx) - aopPut (AOP (result), "a", offset++, isOperandVolatile (result, FALSE)); + aopPut (AOP (result), "a", offset++, isOperandVolatile (result, FALSE)); emitcode ("inc", "dptr"); } else @@ -8552,17 +8698,17 @@ genCodePointerGet (operand * left, emitcode ("mov", "a,#0x%02x", offset); emitcode ("movc", "a,@a+dptr"); if (!ifx) - aopPut (AOP (result), "a", offset++, isOperandVolatile (result, FALSE)); + aopPut (AOP (result), "a", offset++, isOperandVolatile (result, FALSE)); } } } if (pi && AOP_TYPE (left) != AOP_IMMD && AOP_TYPE (left) != AOP_STR) { - aopPut ( AOP (left), "dpl", 0, isOperandVolatile (left, FALSE)); - aopPut ( AOP (left), "dph", 1, isOperandVolatile (left, FALSE)); - pi->generated = 1; - } + aopPut ( AOP (left), "dpl", 0, isOperandVolatile (left, FALSE)); + aopPut ( AOP (left), "dph", 1, isOperandVolatile (left, FALSE)); + pi->generated = 1; + } if (ifx && !ifx->generated) { @@ -8603,7 +8749,7 @@ genGenPointerGet (operand * left, { emitcode ("lcall", "__gptrget"); if (!ifx) - aopPut (AOP (result), "a", offset++, isOperandVolatile (result, FALSE)); + aopPut (AOP (result), "a", offset++, isOperandVolatile (result, FALSE)); if (size || pi) emitcode ("inc", "dptr"); } @@ -8611,17 +8757,17 @@ genGenPointerGet (operand * left, if (pi && AOP_TYPE (left) != AOP_IMMD && AOP_TYPE (left) != AOP_STR) { - aopPut ( AOP (left), "dpl", 0, isOperandVolatile (left, FALSE)); - aopPut ( AOP (left), "dph", 1, isOperandVolatile (left, FALSE)); - pi->generated = 1; - } + aopPut ( AOP (left), "dpl", 0, isOperandVolatile (left, FALSE)); + aopPut ( AOP (left), "dph", 1, isOperandVolatile (left, FALSE)); + pi->generated = 1; + } if (ifx && !ifx->generated) { genIfxJump (ifx, "a", left, NULL, result); } - + freeAsmop (left, NULL, ic, TRUE); freeAsmop (result, NULL, ic, TRUE); } @@ -8640,7 +8786,7 @@ genPointerGet (iCode * ic, iCode *pi, iCode *ifx) left = IC_LEFT (ic); result = IC_RESULT (ic); - + if (getSize (operandType (result))>1) ifx = NULL; @@ -8752,6 +8898,7 @@ genPackBits (sym_link * etype, } else { + bool pushedB; /* Case with a bitfield length < 8 and arbitrary source */ MOVA (aopGet (AOP (right), 0, FALSE, FALSE)); @@ -8759,6 +8906,7 @@ genPackBits (sym_link * etype, AccLsh (bstr); emitcode ("anl", "a,#0x%02x", (~mask) & 0xff); + pushedB = pushB (); /* transfer A to B and get next byte */ emitPtrByteGet (rname, p_type, TRUE); @@ -8766,6 +8914,8 @@ genPackBits (sym_link * etype, emitcode ("orl", "a,b"); if (p_type == GPOINTER) emitcode ("pop", "b"); + + popB (pushedB); } } @@ -8803,11 +8953,13 @@ genPackBits (sym_link * etype, } else { + bool pushedB; /* Case with partial byte and arbitrary source */ MOVA (aopGet (AOP (right), offset++, FALSE, FALSE)); emitcode ("anl", "a,#0x%02x", (~mask) & 0xff); + pushedB = pushB (); /* transfer A to B and get next byte */ emitPtrByteGet (rname, p_type, TRUE); @@ -8815,6 +8967,8 @@ genPackBits (sym_link * etype, emitcode ("orl", "a,b"); if (p_type == GPOINTER) emitcode ("pop", "b"); + + popB (pushedB); } emitPtrByteSet (rname, p_type, "a"); } @@ -9259,7 +9413,7 @@ genIfx (iCode * ic, iCode * popIc) if (popIc) genIpop (popIc); - /* if the condition is a bit variable */ + /* if the condition is a bit variable */ if (isbit && IS_ITEMP (cond) && SPIL_LOC (cond)) genIfxJump (ic, SPIL_LOC (cond)->rname, NULL, NULL, NULL); @@ -9497,9 +9651,11 @@ genJumpTab (iCode * ic) if( count <= 16 ) { - /* this algorithm needs 9 cycles and 7 + 3*n bytes - if the switch argument is in an register. - (8 cycles and 6+2*n bytes if peepholes can change ljmp to sjmp) */ + /* this algorithm needs 9 cycles and 7 + 3*n bytes + if the switch argument is in a register. + (8 cycles and 6+2*n bytes if peepholes can change ljmp to sjmp) */ + /* (MB) What if peephole converts ljmp to sjmp or ret ??? + How will multiply by three be updated ???*/ aopOp (IC_JTCOND (ic), ic, FALSE); /* get the condition into accumulator */ l = aopGet (AOP (IC_JTCOND (ic)), 0, FALSE, FALSE); @@ -9520,24 +9676,26 @@ genJumpTab (iCode * ic) } else { - /* this algorithm needs 14 cycles and 13 + 2*n bytes - if the switch argument is in an register. - For n>6 this algorithm may be more compact */ + /* this algorithm needs 14 cycles and 13 + 2*n bytes + if the switch argument is in a register. + For n>6 this algorithm may be more compact */ jtablo = newiTempLabel (NULL); jtabhi = newiTempLabel (NULL); /* get the condition into accumulator. - Using b as temporary storage, if register push/pop is needed */ + Using b as temporary storage, if register push/pop is needed */ aopOp (IC_JTCOND (ic), ic, FALSE); l = aopGet (AOP (IC_JTCOND (ic)), 0, FALSE, FALSE); if ((AOP_TYPE (IC_JTCOND (ic)) == AOP_R0 && _G.r0Pushed) || (AOP_TYPE (IC_JTCOND (ic)) == AOP_R1 && _G.r1Pushed)) { + // (MB) what if B is in use??? + wassertl(!_G.BInUse, "B was in use"); emitcode ("mov", "b,%s", l); l = "b"; } - freeAsmop (IC_JTCOND (ic), NULL, ic, TRUE); - MOVA (l); + freeAsmop (IC_JTCOND (ic), NULL, ic, TRUE); + MOVA (l); if( count <= 112 ) { emitcode ("add", "a,#(%05d$-3-.)", jtablo->key + 100); @@ -9549,7 +9707,7 @@ genJumpTab (iCode * ic) emitcode ("movc", "a,@a+pc"); emitcode ("push", "acc"); } - else + else { /* this scales up to n<=255, but needs two more bytes and changes dptr */ @@ -9576,9 +9734,7 @@ genJumpTab (iCode * ic) for (jtab = setFirstItem (IC_JTLABELS (ic)); jtab; jtab = setNextItem (IC_JTLABELS (ic))) emitcode (".db", "%05d$>>8", jtab->key + 100); - - } - + } } /*-----------------------------------------------------------------*/ @@ -10089,7 +10245,7 @@ gen51Code (iCode * lic) { if (options.debug) { - debugFile->writeCLine(ic); + debugFile->writeCLine (ic); } if (!options.noCcodeInAsm) { emitcode ("", ";%s:%d: %s", ic->filename, ic->lineno, @@ -10274,7 +10430,7 @@ gen51Code (iCode * lic) case GET_VALUE_AT_ADDRESS: genPointerGet (ic, hasInc (IC_LEFT (ic), ic, - getSize (operandType (IC_RESULT (ic)))), + getSize (operandType (IC_RESULT (ic)))), ifxForOp (IC_RESULT (ic), ic) ); break; diff --git a/src/mcs51/main.c b/src/mcs51/main.c index f43f4174..f84acfb8 100644 --- a/src/mcs51/main.c +++ b/src/mcs51/main.c @@ -58,7 +58,7 @@ _mcs51_init (void) } static void -_mcs51_reset_regparm () +_mcs51_reset_regparm (void) { regParmFlg = 0; } @@ -152,7 +152,27 @@ _mcs51_genAssemblerPreamble (FILE * of) static int _mcs51_genIVT (FILE * of, symbol ** interrupts, int maxInterrupts) { - return FALSE; + int i; + + fprintf (of, "\tljmp\t__sdcc_gsinit_startup\n"); + + /* now for the other interrupts */ + for (i = 0; i < maxInterrupts; i++) + { + if (interrupts[i]) + { + fprintf (of, "\tljmp\t%s\n", interrupts[i]->rname); + if ( i != maxInterrupts - 1 ) + fprintf (of, "\t.ds\t5\n"); + } + else + { + fprintf (of, "\treti\n"); + if ( i != maxInterrupts - 1 ) + fprintf (of, "\t.ds\t7\n"); + } + } + return TRUE; } static void @@ -178,7 +198,6 @@ _mcs51_genInitStartup (FILE *of) { tfprintf (of, "\t!global\n", "__sdcc_init_xstack"); tfprintf (of, "\t!global\n", "__start__xstack"); - fprintf (of, "__start__xstack = 0x%04x", options.xdata_loc); } // if the port can copy the XINIT segment to XISEG @@ -686,11 +705,12 @@ PORT mcs51_port = 1, 2, 2, 4, 1, 2, 3, 1, 4, 4 }, { - "XSEG (XDATA)", + "XSTK (PAG,XDATA)", "STACK (DATA)", "CSEG (CODE)", "DSEG (DATA)", "ISEG (DATA)", + "PSEG (PAG,XDATA)", "XSEG (XDATA)", "BSEG (BIT)", "RSEG (DATA)", diff --git a/src/mcs51/peeph.def b/src/mcs51/peeph.def index 8eb9dd35..ba0c1dbb 100644 --- a/src/mcs51/peeph.def +++ b/src/mcs51/peeph.def @@ -1022,7 +1022,7 @@ replace { // applies to f.e. bug-408972.c // not before peephole 177.c -replace { +replace restart { mov %1,%2 mov %3,%4 mov %2,%1 diff --git a/src/pic/main.c b/src/pic/main.c index 14aeeb51..e8eaaacb 100644 --- a/src/pic/main.c +++ b/src/pic/main.c @@ -436,6 +436,7 @@ PORT pic_port = "code", "DSEG (DATA)", "ISEG (DATA)", + NULL, /* pdata */ "XSEG (XDATA)", "BSEG (BIT)", "RSEG (DATA)", diff --git a/src/pic16/device.c b/src/pic16/device.c index 904e5f65..737336e8 100644 --- a/src/pic16/device.c +++ b/src/pic16/device.c @@ -562,7 +562,7 @@ void pic16_dump_usection(FILE *of, set *section, int fix) { static int abs_usection_no=0; regs *r, *rprev; - int init_addr, i; + unsigned int init_addr, i; regs **rlist; regs *r1; @@ -587,7 +587,7 @@ void pic16_dump_usection(FILE *of, set *section, int fix) fprintf(of, "%s\tres\t%d\n", r->name, r->size); } } else { - int j=0; + unsigned int j=0; int deb_addr=0; rprev = NULL; @@ -647,7 +647,7 @@ void pic16_dump_isection(FILE *of, set *section, int fix) { static int abs_isection_no=0; symbol *s, *sprev; - int init_addr, i; + unsigned int init_addr, i; symbol **slist; /* put all symbols in an array */ @@ -688,7 +688,7 @@ void pic16_dump_isection(FILE *of, set *section, int fix) } } else { - int j=0; + unsigned int j=0; symbol *s1; sprev = NULL; diff --git a/src/pic16/main.c b/src/pic16/main.c index ab2748f0..f298a0ea 100644 --- a/src/pic16/main.c +++ b/src/pic16/main.c @@ -857,6 +857,7 @@ PORT pic16_port = "CSEG (CODE)", // code "DSEG (DATA)", // data "ISEG (DATA)", // idata + NULL, // pdata "XSEG (XDATA)", // xdata "BSEG (BIT)", // bit "RSEG (DATA)", // reg diff --git a/src/port.h b/src/port.h index 58cb554f..a93a2edb 100644 --- a/src/port.h +++ b/src/port.h @@ -144,6 +144,7 @@ typedef struct const char *code_name; const char *data_name; const char *idata_name; + const char *pdata_name; const char *xdata_name; const char *bit_name; const char *reg_name; diff --git a/src/xa51/main.c b/src/xa51/main.c index 26b52112..3c1d73fb 100755 --- a/src/xa51/main.c +++ b/src/xa51/main.c @@ -64,7 +64,7 @@ _xa51_init (void) } static void -_xa51_reset_regparm () +_xa51_reset_regparm (void) { regParmFlg = 0; } @@ -275,6 +275,7 @@ PORT xa51_port = "CSEG (CODE)", "DSEG (DATA)", NULL, //"ISEG (DATA)", + NULL, //"PSEG (PAG,XDATA)", "XSEG (XDATA)", "BSEG (BIT)", NULL, //"RSEG (DATA)", diff --git a/src/z80/gen.c b/src/z80/gen.c index 2818150f..8562c69a 100644 --- a/src/z80/gen.c +++ b/src/z80/gen.c @@ -2397,7 +2397,7 @@ genUminusFloat (operand * op, operand * result) emitDebug("; genUminusFloat"); /* for this we just need to flip the - first it then copy the rest in place */ + first bit then copy the rest in place */ size = AOP_SIZE (op) - 1; _moveA(aopGet (AOP (op), MSB32, FALSE)); @@ -7431,7 +7431,7 @@ _rleCommit(RLECTX *self) chunks. */ static void -_rleAppend(RLECTX *self, int c) +_rleAppend(RLECTX *self, unsigned c) { int i; diff --git a/src/z80/main.c b/src/z80/main.c index 057d01d5..8fb6b0a2 100644 --- a/src/z80/main.c +++ b/src/z80/main.c @@ -112,7 +112,7 @@ _gbz80_init (void) } static void -_reset_regparm () +_reset_regparm (void) { _G.regParams = 0; } @@ -603,6 +603,7 @@ PORT z80_port = "CODE", "DATA", "ISEG", + NULL, /* pdata */ "XSEG", "BSEG", "RSEG", @@ -718,6 +719,7 @@ PORT gbz80_port = "CODE", "DATA", "ISEG", + NULL, /* pdata */ "XSEG", "BSEG", "RSEG", diff --git a/support/regression/tests/zeropad.c b/support/regression/tests/zeropad.c index 05069b46..f8f759da 100644 --- a/support/regression/tests/zeropad.c +++ b/support/regression/tests/zeropad.c @@ -1,6 +1,6 @@ /** Zeropad tests. - storage: idata, xdata, code, + storage: idata, pdata, xdata, code, */ #ifndef STORAGE #define STORAGE {storage} @@ -22,12 +22,14 @@ typedef unsigned int size_t; #if defined(PORT_HOST) || defined(SDCC_z80) || defined(SDCC_gbz80) # define idata +# define pdata # define xdata # define code #endif #if defined(SDCC_hc08) # define idata data +# define pdata data #endif const char *string1 = "\x00\x01";