X-Git-Url: https://git.gag.com/?a=blobdiff_plain;f=as%2Flink%2Fmcs51%2Flkarea.c;h=58f96c1d71dd81c418f7ea992b4099d7ceac39fe;hb=392dfbbb29fe895cf309075c115a6d7a9cad74d7;hp=96a91307beec5863a725115295c67055014202bd;hpb=e5eda9d6a5ea34e83b0b1fdcf05db3b04b7aaac8;p=fw%2Fsdcc diff --git a/as/link/mcs51/lkarea.c b/as/link/mcs51/lkarea.c index 96a91307..58f96c1d 100644 --- a/as/link/mcs51/lkarea.c +++ b/as/link/mcs51/lkarea.c @@ -315,6 +315,7 @@ lkparea(char *id) * structures. */ +VOID lnksect(register struct area *tap); /* * Resolve all area addresses. */ @@ -492,6 +493,9 @@ Addr_T lnksect2 (struct area *tap, int locIndex); char idatamap[256]; unsigned long codemap[524288]; unsigned long xdatamap[131072]; +struct area *dseg_ap = NULL; +Addr_T dram_start = 0; +Addr_T iram_start = 0; /*Modified version of the functions for packing variables in internal data memory*/ VOID lnkarea2 (void) @@ -502,7 +506,7 @@ VOID lnkarea2 (void) char temp[NCPS]; struct sym *sp; int j; - struct area *dseg_ap = NULL; + struct area *bseg_ap = NULL; struct area *abs_ap = NULL; struct area *gs0_ap = NULL; struct sym *sp_dseg_s=NULL, *sp_dseg_l=NULL; @@ -533,8 +537,13 @@ VOID lnkarea2 (void) /* next accumulate all GSINITx/GSFINAL area sizes into GSINIT so they stay together */ ap = areap; + abs_ap = areap; while (ap) { + if (ap->a_flag & A_ABS) + { + abs_ap = ap; /* Remember the last abs area */ + } if (!strncmp(ap->a_id, "GS", 2)) {/* GSxxxxx area */ if (ap->a_size == 0) @@ -552,6 +561,28 @@ VOID lnkarea2 (void) gs0_ap = ap; } } + /*Since area BSEG is defined just before BSEG_BYTES, use the bit size of BSEG + to compute the byte size of BSEG_BYTES: */ + else if (!strcmp(ap->a_id, "BSEG")) + { + bseg_ap = ap->a_ap; //BSEG_BYTES + for (axp=ap->a_axp; axp; axp=axp->a_axp) + ap->a_size += axp->a_size; + bseg_ap->a_axp->a_size = ((ap->a_addr + ap->a_size + 7)/8); /*Bits to bytes*/ + ap->a_ap = bseg_ap->a_ap; //removed BSEG_BYTES from list + bseg_ap->a_ap = abs_ap->a_ap; + abs_ap->a_ap = bseg_ap; //inserted BSEG_BYTES after abs + bseg_ap = ap; //BSEG + } + else if (!strcmp(ap->a_id, "DSEG")) + { + dseg_ap = ap; /*Need it later*/ + dram_start = ap->a_addr; + } + else if (!strcmp(ap->a_id, "ISEG")) + { + iram_start = ap->a_addr; + } ap = ap->a_ap; } if (gs0_ap) @@ -581,6 +612,10 @@ VOID lnkarea2 (void) rloc[locIndex] = lnksect2(ap, locIndex); } + if (!strcmp(ap->a_id, "BSEG_BYTES")) + { + bseg_ap->a_addr = (ap->a_axp->a_addr - 0x20) * 8; /*Bytes to bits*/ + } /* * Create symbols called: * s_ the start address of the area @@ -594,7 +629,7 @@ VOID lnkarea2 (void) *temp = 's'; sp = lkpsym(temp, 1); - sp->s_addr = ap->a_addr ; + sp->s_addr = ap->a_addr; sp->s_type |= S_DEF; if (!strcmp(ap->a_id, "DSEG")) sp_dseg_s=sp; @@ -606,16 +641,6 @@ VOID lnkarea2 (void) 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")) - { - ap->a_ap->a_axp->a_size = ((ap->a_addr + 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; } @@ -713,7 +738,7 @@ Addr_T lnksect2 (struct area *tap, int locIndex) { register Addr_T size, addr; register struct areax *taxp; - int j, k, ramlimit; + int j, k, ramlimit, ramstart; char fchar=' ', dchar='a'; char ErrMsg[]="?ASlink-Error-Could not get %d consecutive byte%s" " in internal RAM for area %s.\n"; @@ -723,17 +748,21 @@ Addr_T lnksect2 (struct area *tap, int locIndex) /*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")) ) { - if((iram_size<=0)||(iram_size>0x100)) - ramlimit=0x100; + ramstart = iram_start; + + if ((iram_size <= 0) || (ramstart + iram_size > 0x100)) + ramlimit = 0x100; else - ramlimit=iram_size; + ramlimit = ramstart + iram_size; } else { - if((iram_size<=0)||(iram_size>0x80)) - ramlimit=0x80; + ramstart = dram_start; + + if ((iram_size <= 0) || (ramstart + iram_size > 0x80)) + ramlimit = 0x80; else - ramlimit=iram_size; + ramlimit = ramstart + iram_size; } size = 0; @@ -789,28 +818,35 @@ Addr_T lnksect2 (struct area *tap, int locIndex) { while (taxp) { + if(taxp->a_size == 0) + { + taxp = taxp->a_axp; + continue; + } + if ( (fchar=='0')||(fchar=='1')||(fchar=='2')||(fchar=='3') ) /*Reg banks*/ { addr=(fchar-'0')*8; taxp->a_addr=addr; size=taxp->a_size; - for(j=addr; (j<(int)(addr+taxp->a_size)) && (ja_size=0; ja_size=0; j(int)taxp->a_size) taxp->a_size=k; + if((++k)>(int)taxp->a_size) + taxp->a_size=k; } else { @@ -826,37 +862,26 @@ Addr_T lnksect2 (struct area *tap, int locIndex) { size=(int)taxp->a_size; - for(j=0; ja_size) break; - } - if(k==(int)taxp->a_size) - { - taxp->a_addr = j-k+1; - if(addr<(unsigned int)ramlimit) - { - for(j=ramlimit-1; (j>=0)&&(idatamap[j]==' '); j--); - if(j>=0) addr=j+1; - } + break; } /*Mark the memory used for overlay*/ if(k==(int)taxp->a_size) { - for(j=taxp->a_addr; (j<(int)(taxp->a_addr+taxp->a_size)) && (ja_addr=addr; - taxp->a_addr=addr; - break; - } - } } else if (fchar=='T') /*Bit addressable bytes in internal RAM*/ { /*Find the size of the space currently used for this areax overlay*/ - for(j=0x20, size=0; j<0x30; j++) - if(idatamap[j]==fchar) size++; +// for(j=0x20, size=0; j<0x30; j++) +// if(idatamap[j]==fchar) size++; /*If more space required, release the previously allocated areax in internal RAM and search for a bigger one*/ @@ -899,27 +913,16 @@ Addr_T lnksect2 (struct area *tap, int locIndex) k++; else k=0; - if(k==(int)taxp->a_size) break; - } - - if(k==(int)taxp->a_size) - { - taxp->a_addr = j-k+1; - if(addr<(unsigned int)0x30) - { - for(j=0x2F; (j>=0x20)&&(idatamap[j]==' '); j--); - if(j>=0x20) addr=j+1; - } + if(k==(int)taxp->a_size) + break; } /*Mark the memory used for overlay*/ - if(k==(int)taxp->a_size) + if(k==(int)size) { - for(j=taxp->a_addr; (j<(int)(taxp->a_addr+taxp->a_size)) && (j<0x30); j++) + addr = j-k+1; + for(j=addr; (j<(int)(addr+size)); j++) idatamap[j]=fchar; - - /*Set the new size of the data memory area*/ - size=ramlimit-addr; } else /*Couldn't find a chunk big enough: report the problem.*/ { @@ -928,17 +931,6 @@ Addr_T lnksect2 (struct area *tap, int locIndex) lkerr++; } } - - for(j=0x20; j<0x30; j++) - { - if (idatamap[j]==fchar) - { - addr=j; - tap->a_addr=addr; - taxp->a_addr=addr; - break; - } - } } else /*Overlay areas not in internal ram*/ { @@ -947,6 +939,13 @@ Addr_T lnksect2 (struct area *tap, int locIndex) } taxp = taxp->a_axp; } + /*Now set all overlayed areax to the same start address*/ + taxp = tap->a_axp; + while (taxp) + { + taxp->a_addr = addr; + taxp = taxp->a_axp; + } } else if (tap->a_flag & A_ABS) /* Absolute sections */ { @@ -954,14 +953,19 @@ Addr_T lnksect2 (struct area *tap, int locIndex) { if (locIndex == 0) { - for (j=taxp->a_addr; (j<(int)(taxp->a_addr+taxp->a_size)) && (ja_addr; (j<(int)(taxp->a_addr+taxp->a_size)) && (j<256); j++) + { + if (idatamap[j] == ' ') + idatamap[j] = 'A'; + else + fprintf(stderr, "memory overlap at 0x%X for %s\n", j, tap->a_id); + } } - if (locIndex == 1) + else if (locIndex == 1) { allocate_space(taxp->a_addr, taxp->a_size, tap->a_id, codemap); } - if (locIndex == 2) + else if (locIndex == 2) { allocate_space(taxp->a_addr, taxp->a_size, tap->a_id, xdatamap); } @@ -987,24 +991,21 @@ Addr_T lnksect2 (struct area *tap, int locIndex) if(taxp->a_size) { /*Search for a space large enough in internal RAM for this areax*/ - for(j=0, k=0; ja_size) break; + if(k==(int)taxp->a_size) + break; } if(k==(int)taxp->a_size) { taxp->a_addr = j-k+1; - if(addr<(unsigned int)ramlimit) - { - for(j=ramlimit-1; (j>=0)&&(idatamap[j]==' '); j--); - if(j>=0) addr=j+1; - size=ramlimit-addr; - } + + size += taxp->a_size; for(j=taxp->a_addr; (j<(int)(taxp->a_addr+taxp->a_size)) && (ja_size!=0) { - for(j=addr; j<((int)(addr+taxp->a_size)); j++) + /*Search for a space large enough in data memory for this areax*/ + for(j=0x20, k=0; j<0x30; j++) + { + if(idatamap[j]==' ') + k++; + else + k=0; + if(k==(int)taxp->a_size) break; + } + + /*Mark the memory used*/ + if(k==(int)taxp->a_size) + { + taxp->a_addr = j-k+1; + for(j=taxp->a_addr; (j<(int)(taxp->a_addr+taxp->a_size)) && (j<0x30); j++) idatamap[j]=fchar; + } + else /*Couldn't find a chunk big enough: report the problem.*/ + { + tap->a_unaloc=taxp->a_size; + fprintf(stderr, ErrMsg, taxp->a_size, taxp->a_size>1?"s":"", tap->a_id); + lkerr++; + } } - - taxp->a_addr = addr; - addr += taxp->a_size; size += taxp->a_size; taxp = taxp->a_axp; }