* structures.
*/
+VOID lnksect(register struct area *tap);
/*
* Resolve all area addresses.
*/
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)
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;
/* 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)
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)
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_<areaname> the start address of the area
*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;
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;
}
{
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";
/*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;
{
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)) && (j<ramlimit); j++)
+ for(j=addr; (j<(int)(addr+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++)
+ for(j=ramstart, 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++)
+ for(j=ramstart, k=0, taxp->a_size=0; j<ramlimit; j++)
{
if(idatamap[j]==' ')
{
- if((++k)>(int)taxp->a_size) taxp->a_size=k;
+ if((++k)>(int)taxp->a_size)
+ taxp->a_size=k;
}
else
{
{
size=(int)taxp->a_size;
- for(j=0; j<ramlimit; j++)
+ for(j=ramstart; 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++)
+ for(j=ramstart, 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;
- }
+ 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)) && (j<ramlimit); 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.*/
{
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++;
+// 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*/
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.*/
{
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 = 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 */
{
{
if (locIndex == 0)
{
- for (j=taxp->a_addr; (j<(int)(taxp->a_addr+taxp->a_size)) && (j<ramlimit); j++)
- idatamap[j] = 'A';
+ for (j=taxp->a_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);
}
if(taxp->a_size)
{
/*Search for a space large enough in internal RAM for this areax*/
- for(j=0, k=0; j<ramlimit; j++)
+ for(j=ramstart, 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)
+ 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)) && (j<ramlimit); j++)
idatamap[j]=(fchar=='D')?dchar:fchar;
{
if(taxp->a_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;
}
}
}
tap->a_size = size;
+ tap->a_addr = tap->a_axp->a_addr;
if ((tap->a_flag&A_PAG) && (size > 256))
{