+ 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"
+ " 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")) )
+ {
+ if((iram_size<=0)||(iram_size>0x100))
+ ramlimit=0x100;
+ else
+ ramlimit=iram_size;
+ }
+ else
+ {
+ if((iram_size<=0)||(iram_size>0x80))
+ ramlimit=0x80;
+ else
+ ramlimit=iram_size;
+ }
+
+ 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;
+
+ /*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' later for each areax*/
+ else if(!strcmp(tap->a_id, "ISEG"))
+ fchar='I';
+ else if(!strcmp(tap->a_id, "SSEG"))
+ fchar='S';
+ else if(!strcmp(tap->a_id, "OSEG"))
+ fchar='Q';
+ else if(!strcmp(tap->a_id, "REG_BANK_0"))
+ fchar='0';
+ else if(!strcmp(tap->a_id, "REG_BANK_1"))
+ fchar='1';
+ else if(!strcmp(tap->a_id, "REG_BANK_2"))
+ fchar='2';
+ else if(!strcmp(tap->a_id, "REG_BANK_3"))
+ fchar='3';
+ else if(!strcmp(tap->a_id, "BSEG_BYTES"))
+ fchar='B';
+ else if(!strcmp(tap->a_id, "BIT_BANK"))
+ fchar='T';
+ else
+ fchar=' ';/*???*/
+ }
+ else
+ {
+ fchar=' ';
+ }
+
+ if (tap->a_flag&A_OVR) /* Overlayed sections */
+ {
+ while (taxp)
+ {
+ 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)) && (j<ramlimit); j++)
+ idatamap[j]=fchar;
+ }
+ else if( (fchar=='S') || (fchar=='Q') ) /*Overlay and stack in internal RAM*/
+ {
+ /*Find the size of the space currently used for this areax overlay*/
+ for(j=0, size=0; j<ramlimit; j++)
+ if(idatamap[j]==fchar) size++;
+
+ if( (fchar=='S') && (stacksize==0) )
+ {
+ /*Search for the largest space available and use it for stack*/
+ for(j=0, k=0, taxp->a_size=0; j<ramlimit; j++)
+ {
+ if(idatamap[j]==' ')
+ {
+ if((++k)>(int)taxp->a_size) taxp->a_size=k;
+ }
+ else
+ {
+ k=0;
+ }
+ }
+ stacksize=taxp->a_size;
+ }
+
+ /*If more space required, release the previously allocated areax in
+ internal RAM and search for a bigger one*/
+ if((int)taxp->a_size>size)
+ {
+ size=(int)taxp->a_size;
+
+ for(j=0; j<ramlimit; j++)
+ if(idatamap[j]==fchar) idatamap[j]=' ';
+
+ /*Search for a space large enough in data memory for this overlay areax*/
+ for(j=0, k=0; j<ramlimit; j++)
+ {
+ if(idatamap[j]==' ')
+ 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)ramlimit)
+ {
+ for(j=ramlimit-1; (j>=0)&&(idatamap[j]==' '); j--);
+ if(j>=0) addr=j+1;
+ }
+ }
+
+ /*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)) && (j<ramlimit); 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.*/
+ {
+ tap->a_unaloc=taxp->a_size;
+ fprintf(stderr, ErrMsg, taxp->a_size, taxp->a_size>1?"s":"", tap->a_id);
+ lkerr++;
+ }
+ }
+
+ for(j=0; j<ramlimit; j++)
+ {
+ if (idatamap[j]==fchar)
+ {
+ addr=j;
+ tap->a_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++;
+
+ /*If more space required, release the previously allocated areax in
+ internal RAM and search for a bigger one*/
+ if((int)taxp->a_size>size)
+ {
+ size=(int)taxp->a_size;
+
+ for(j=0x20; j<0x30; j++)
+ if(idatamap[j]==fchar) idatamap[j]=' ';
+
+ /*Search for a space large enough in data memory for this overlay areax*/
+ for(j=0x20, k=0; j<0x30; j++)
+ {
+ if(idatamap[j]==' ')
+ 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;
+ }
+ }
+
+ /*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)) && (j<0x30); 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.*/
+ {
+ tap->a_unaloc=taxp->a_size;
+ fprintf(stderr, ErrMsg, taxp->a_size, taxp->a_size>1?"s":"", tap->a_id);
+ 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*/
+ {
+ taxp->a_addr = addr;
+ if (taxp->a_size > size) size = taxp->a_size;
+ }
+ taxp = taxp->a_axp;
+ }
+ }
+ else /* Concatenated sections */
+ {
+ while (taxp)
+ {
+ if( (fchar=='D') || (fchar=='I') )
+ {
+ if(taxp->a_size)
+ {
+ /*Search for a space large enough in internal RAM for this areax*/
+ for(j=0, k=0; j<ramlimit; j++)
+ {
+ if(idatamap[j]==' ')
+ 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)ramlimit)
+ {
+ for(j=ramlimit-1; (j>=0)&&(idatamap[j]==' '); j--);
+ if(j>=0) addr=j+1;
+ size=ramlimit-addr;
+ }
+
+ for(j=taxp->a_addr; (j<(int)(taxp->a_addr+taxp->a_size)) && (j<ramlimit); j++)
+ idatamap[j]=(fchar=='D')?dchar:fchar;
+ if((taxp->a_size>0)&&(fchar=='D'))dchar++;
+ if((dchar<'a')||(dchar>'z')) dchar='D'; /*Ran out of letters?*/
+ }
+ else /*We are in trouble, there is not enough memory for an areax chunk*/
+ {
+ taxp->a_addr = addr;
+ addr += 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;
+ }
+ else if(fchar=='B')
+ {
+ if(taxp->a_size!=0)
+ {
+ for(j=addr; j<((int)(addr+taxp->a_size)); j++)
+ idatamap[j]=fchar;
+ }
+
+ 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*/
+ {
+ if(!strcmp(tap->a_id, "XSTK") && (taxp->a_size == 1))
+ {
+ taxp->a_size = 256-(addr & 0xFF);
+ }
+ //should find next unused address now!!!
+ //but let's first just warn for overlaps
+ if (rloc == 1)
+ {
+ int a = addr;
+ int i = addr >> 5;
+ int j = (addr + taxp->a_size) >> 5;
+ long mask = -(1 << (addr & 0x1F));
+
+ while (i < j)
+ {
+ if (codemap[i] & mask)
+ {
+ fprintf(stderr, "memory overlap near 0x%X for %s\n", a, tap->a_id);
+ }
+ codemap[i++] |= mask;
+ mask = 0xFFFFFFFF;
+ a += 32;
+ }
+ mask &= (1 << ((addr + taxp->a_size) & 0x1F)) - 1;
+ if (codemap[i] & mask)
+ {
+ fprintf(stderr, "memory overlap near 0x%X for %s\n", a, tap->a_id);
+ }
+ codemap[i] |= mask;
+ }
+ 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++;
+ }