* as/hc08/lkaomf51.c (OutputName): made name unsigned char,
[fw/sdcc] / as / mcs51 / lkarea.c
1 /* lkarea.c */
2
3 /*
4  * (C) Copyright 1989-1995
5  * All Rights Reserved
6  *
7  * Alan R. Baldwin
8  * 721 Berkeley St.
9  * Kent, Ohio  44240
10  *
11  *  3-Nov-97 JLH:
12  *           - change lkparea to use a_type == 0 as "virgin area" flag
13  * 02-Apr-98 JLH: add code to link 8051 data spaces
14  */
15
16 #include <stdio.h>
17 #include <string.h>
18 #include "aslink.h"
19
20 /*)Module   lkarea.c
21  *
22  *  The module lkarea.c contains the functions which
23  *  create and link together all area definitions read
24  *  from the .rel file(s).
25  *
26  *  lkarea.c contains the following functions:
27  *      VOID    lnkarea()
28  *      VOID    lnksect()
29  *      VOID    lkparea()
30  *      VOID    newarea()
31  *
32  *  lkarea.c contains no global variables.
33  */
34
35 /*)Function VOID    newarea()
36  *
37  *  The function newarea() creates and/or modifies area
38  *  and areax structures for each A directive read from
39  *  the .rel file(s).  The function lkparea() is called
40  *  to find tha area structure associated with this name.
41  *  If the area does not yet exist then a new area
42  *  structure is created and linked to any existing
43  *  linked area structures. The area flags are copied
44  *  into the area flag variable.  For each occurence of
45  *  an A directive an areax structure is created and
46  *  linked to the areax structures associated with this
47  *  area.  The size of this area section is placed into
48  *  the areax structure.  The flag value for all subsequent
49  *  area definitions for the same area are compared and
50  *  flagged as an error if they are not identical.
51  *  The areax structure created for every occurence of
52  *  an A directive is loaded with a pointer to the base
53  *  area structure and a pointer to the associated
54  *  head structure.  And finally, a pointer to this
55  *  areax structure is loaded into the list of areax
56  *  structures in the head structure.  Refer to lkdata.c
57  *  for details of the structures and their linkage.
58  *
59  *  local variables:
60  *      areax **halp        pointer to an array of pointers
61  *      int     i           counter, loop variable, value
62  *      char    id[]        id string
63  *      int     narea       number of areas in this head structure
64  *      areax * taxp        pointer to an areax structure
65  *                          to areax structures
66  *
67  *  global variables:
68  *      area    *ap         Pointer to the current
69  *                          area structure
70  *      areax   *axp        Pointer to the current
71  *                          areax structure
72  *      head    *hp         Pointer to the current
73  *                          head structure
74  *      int     lkerr       error flag
75  *
76  *  functions called:
77  *      Addr_T  eval()      lkeval.c
78  *      VOID    exit()      c_library
79  *      int     fprintf()   c_library
80  *      VOID    getid()     lklex.c
81  *      VOID    lkparea()   lkarea.c
82  *      VOID    skip()      lklex.c
83  *
84  *  side effects:
85  *      The area and areax structures are created and
86  *      linked with the appropriate head structures.
87  *      Failure to allocate area or areax structure
88  *      space will terminate the linker.  Other internal
89  *      errors most likely caused by corrupted .rel
90  *      files will also terminate the linker.
91  */
92
93 /*
94  * Create an area entry.
95  *
96  * A xxxxxx size nnnn flags mm
97  *   |           |          |
98  *   |           |          `--  ap->a_flag
99  *   |           `------------- axp->a_size
100  *   `-------------------------  ap->a_id
101  *
102  */
103 VOID
104 newarea()
105 {
106     register int i, narea;
107     struct areax *taxp;
108     struct areax **halp;
109     char id[NCPS];
110
111     /*
112      * Create Area entry
113      */
114     getid(id, -1);
115     lkparea(id);
116     /*
117      * Evaluate area size
118      */
119     skip(-1);
120     axp->a_size = eval();
121     /*
122      * Evaluate flags
123      */
124     skip(-1);
125     i = 0;
126     taxp = ap->a_axp;
127     while (taxp->a_axp) {
128         ++i;
129         taxp = taxp->a_axp;
130     }
131     if (i == 0) {
132         ap->a_flag = eval();
133     } else {
134         i = eval();
135 /*      if (i && (ap->a_flag != i)) { */
136 /*          fprintf(stderr, "Conflicting flags in area %8s\n", id); */
137 /*          lkerr++; */
138 /*      } */
139     }
140     /*
141      * Place pointer in header area list
142      */
143     if (headp == NULL) {
144         fprintf(stderr, "No header defined\n");
145         lkexit(1);
146     }
147     narea = hp->h_narea;
148     halp = hp->a_list;
149     for (i=0; i < narea ;++i) {
150         if (halp[i] == NULL) {
151             halp[i] = taxp;
152             return;
153         }
154     }
155     fprintf(stderr, "Header area list overflow\n");
156     lkexit(1);
157 }
158
159 /*)Function VOID    lkparea(id)
160  *
161  *      char *  id      pointer to the area name string
162  *
163  *  The function lkparea() searches the linked area structures
164  *  for a name match.  If the name is not found then an area
165  *  structure is created.  An areax structure is created and
166  *  appended to the areax structures linked to the area structure.
167  *  The associated base area and head structure pointers are
168  *  loaded into the areax structure.
169  *
170  *  local variables:
171  *      area *  tap         pointer to an area structure
172  *      areax * taxp        pointer to an areax structure
173  *
174  *  global variables:
175  *      area    *ap         Pointer to the current
176  *                          area structure
177  *      area    *areap      The pointer to the first
178  *                          area structure of a linked list
179  *      areax   *axp        Pointer to the current
180  *                          areax structure
181  *
182  *  functions called:
183  *      VOID *  new()       lksym()
184  *      char *  strcpy()    c_library
185  *      int     symeq()     lksym.c
186  *
187  *  side effects:
188  *      Area and/or areax structures are created.
189  *      Failure to allocate space for created structures
190  *      will terminate the linker.
191  */
192
193 VOID
194 lkparea(char *id)
195 {
196     register struct area *tap;
197     register struct areax *taxp;
198
199     ap = areap;
200     axp = (struct areax *) new (sizeof(struct areax));
201     axp->a_addr = -1; /* default: no address yet */
202     while (ap) {
203         if (symeq(id, ap->a_id)) {
204             taxp = ap->a_axp;
205             while (taxp->a_axp)
206                 taxp = taxp->a_axp;
207             taxp->a_axp = axp;
208             axp->a_bap = ap;
209             axp->a_bhp = hp;
210             return;
211         }
212         ap = ap->a_ap;
213     }
214     ap = (struct area *) new (sizeof(struct area));
215     if (areap == NULL) {
216         areap = ap;
217     } else {
218         tap = areap;
219         while (tap->a_ap)
220             tap = tap->a_ap;
221         tap->a_ap = ap;
222     }
223     ap->a_axp = axp;
224     axp->a_bap = ap;
225     axp->a_bhp = hp;
226     strncpy(ap->a_id, id, NCPS);
227     ap->a_addr = 0;
228 }
229
230 /*)Function VOID    lnkarea()
231  *
232  *  The function lnkarea() resolves all area addresses.
233  *  The function evaluates each area structure (and all
234  *  the associated areax structures) in sequence.  The
235  *  linking process supports four (4) possible area types:
236  *
237  *  ABS/OVR -   All sections (each individual areax
238  *          section) starts at the identical base
239  *          area address overlaying all other
240  *          areax sections for this area.  The
241  *          size of the area is largest of the area
242  *          sections.
243  *
244  *  ABS/CON -   All sections (each individual areax
245  *          section) are concatenated with the
246  *          first section starting at the base
247  *          area address.  The size of the area
248  *          is the sum of the section sizes.
249  *
250  *  NOTE:   Multiple absolute (ABS) areas are
251  *          never concatenated with each other,
252  *          thus absolute area A and absolute area
253  *          B will overlay each other if they begin
254  *          at the same location (the default is
255  *          always address 0 for absolute areas).
256  *
257  *  REL/OVR -   All sections (each individual areax
258  *          section) starts at the identical base
259  *          area address overlaying all other
260  *          areax sections for this area.  The
261  *          size of the area is largest of the area
262  *          sections.
263  *
264  *  REL/CON -   All sections (each individual areax
265  *          section) are concatenated with the
266  *          first section starting at the base
267  *          area address.  The size of the area
268  *          is the sum of the section sizes.
269  *
270  *  NOTE:   Relocatable (REL) areas are always concatenated
271  *          with each other, thus relocatable area B
272  *          (defined after area A) will follow
273  *          relocatable area A independent of the
274  *          starting address of area A.  Within a
275  *          specific area each areax section may be
276  *          overlayed or concatenated with other
277  *          areax sections.
278  *
279  *
280  *  If a base address for an area is specified then the
281  *  area will start at that address.  Any relocatable
282  *  areas defined subsequently will be concatenated to the
283  *  previous relocatable area if it does not have a base
284  *  address specified.
285  *
286  *  The names s_<areaname> and l_<areaname> are created to
287  *  define the starting address and length of each area.
288  *
289  *  local variables:
290  *      Addr_T  rloc        ;current relocation address
291  *      char    temp[]      ;temporary string
292  *      struct symbol   *sp ;symbol structure
293  *
294  *  global variables:
295  *      area    *ap         Pointer to the current
296  *                          area structure
297  *      area    *areap      The pointer to the first
298  *                          area structure of a linked list
299  *
300  *  functions called:
301  *      int     fprintf()   c_library
302  *      VOID    lnksect()   lkarea.c
303  *      symbol *lkpsym()    lksym.c
304  *      char *  strncpy()   c_library
305  *      int     symeq()     lksym.c
306  *
307  *  side effects:
308  *      All area and areax addresses and sizes are
309  *      determined and saved in their respective
310  *      structures.
311  */
312
313 /*
314  * Resolve all area addresses.
315  */
316 VOID
317 lnkarea()
318 {
319     Addr_T rloc[4];
320     int  locIndex;
321     char temp[NCPS];
322     struct sym *sp;
323     /*JCF: used to save the REG_BANK_[0-3] and SBIT_BYTES area pointers*/
324     struct area *ta[5];
325     int j;
326
327     rloc[0] = rloc[1] = rloc[2] = rloc[3] = 0;
328     ap = areap;
329     while (ap) {
330         if (ap->a_flag&A_ABS) {
331             /*
332              * Absolute sections
333              */
334             lnksect(ap);
335         } else {
336             /* Determine memory space */
337             locIndex = 0;
338             if (ap->a_flag & A_CODE) {
339                 locIndex = 1;
340             }
341             if (ap->a_flag & A_XDATA) {
342                 locIndex = 2;
343             }
344             if (ap->a_flag & A_BIT) {
345                 locIndex = 3;
346             }
347             /*
348              * Relocatable sections
349              */
350             if (ap->a_type == 0) {  /* JLH */
351                 ap->a_addr = rloc[ locIndex ];
352                 ap->a_type = 1;
353             }
354             lnksect(ap);
355             rloc[ locIndex ] = ap->a_addr + ap->a_size;
356         }
357
358         /*
359          * Create symbols called:
360          *  s_<areaname>    the start address of the area
361          *  l_<areaname>    the length of the area
362          */
363
364         if (! symeq(ap->a_id, _abs_)) {
365             strncpy(temp+2,ap->a_id,NCPS-2);
366             *(temp+1) = '_';
367
368             *temp = 's';
369             sp = lkpsym(temp, 1);
370             sp->s_addr = ap->a_addr ;
371             /* sp->s_axp = ap->a_axp;  JLH: was NULL; */
372             sp->s_type |= S_DEF;
373
374             *temp = 'l';
375             sp = lkpsym(temp, 1);
376             sp->s_addr = ap->a_size;
377             sp->s_axp = NULL;
378             sp->s_type |= S_DEF;
379
380         }
381
382         /*JCF: Since area BSEG is defined just before BSEG_BYTES, use the bit size of BSEG
383         to compute the byte size of BSEG_BYTES: */
384         if (!strcmp(ap->a_id, "BSEG")) {
385             ap->a_ap->a_axp->a_size += ((ap->a_addr + ap->a_size + 7)/8); /*Bits to bytes*/
386         }
387         else if (!strcmp(ap->a_id, "REG_BANK_0")) ta[0]=ap;
388         else if (!strcmp(ap->a_id, "REG_BANK_1")) ta[1]=ap;
389         else if (!strcmp(ap->a_id, "REG_BANK_2")) ta[2]=ap;
390         else if (!strcmp(ap->a_id, "REG_BANK_3")) ta[3]=ap;
391         else if (!strcmp(ap->a_id, "BSEG_BYTES"))
392         {
393             ta[4]=ap;
394             for(j=4; j>1; j--)
395             {
396                 /*If upper register banks are not used roll back the relocation counter*/
397                 if ( (ta[j]->a_size==0) && (ta[j-1]->a_size==0) )
398                 {
399                     rloc[0]-=8;
400                 }
401                 else break;
402             }
403         }
404         ap = ap->a_ap;
405     }
406 }
407
408 /*)Function VOID    lnksect()
409  *
410  *      area *  tap         pointer to an area structure
411  *
412  *  The function lnksect() is the function called by
413  *  lnkarea() to resolve the areax addresses.  Refer
414  *  to the function lnkarea() for more detail. Pageing
415  *  boundary and length errors will be reported by this
416  *  function.
417  *
418  *  local variables:
419  *      Addr_T  size        size of area
420  *      Addr_T  addr        address of area
421  *      areax * taxp        pointer to an areax structure
422  *
423  *  global variables:
424  *      int     lkerr       error flag
425  *
426  *  functions called:
427  *      none
428  *
429  *  side effects:
430  *      All area and areax addresses and sizes area determined
431  *      and linked into the structures.
432  */
433
434 VOID
435 lnksect(register struct area *tap)
436 {
437     register Addr_T size, addr;
438     register struct areax *taxp;
439
440     size = 0;
441     addr = tap->a_addr;
442 #if 0
443     if ((tap->a_flag&A_PAG) && (addr & 0xFF)) {
444         fprintf(stderr,
445         "\n?ASlink-Warning-Paged Area %8s Boundary Error\n", tap->a_id);
446         lkerr++;
447     }
448 #endif
449     taxp = tap->a_axp;
450     if (tap->a_flag&A_OVR) {
451         /*
452          * Overlayed sections
453          */
454         while (taxp) {
455             taxp->a_addr = addr;
456             if (taxp->a_size > size)
457                 size = taxp->a_size;
458             taxp = taxp->a_axp;
459         }
460     } else {
461         /*
462          * Concatenated sections
463          */
464         while (taxp) {
465             taxp->a_addr = addr;
466             addr += taxp->a_size;
467             size += taxp->a_size;
468             taxp = taxp->a_axp;
469         }
470     }
471     tap->a_size = size;
472     if ((tap->a_flag&A_PAG) && (size > 256)) {
473         fprintf(stderr,
474         "\n?ASlink-Warning-Paged Area %8s Length Error\n", tap->a_id);
475         lkerr++;
476     }
477     if ((tap->a_flag&A_PAG) && (tap->a_size) &&
478         ((tap->a_addr & 0xFFFFFF00) != ((addr-1) & 0xFFFFFF00)))
479     {
480         fprintf(stderr,
481         "\n?ASlink-Warning-Paged Area %8s Boundary Error\n", tap->a_id);
482         lkerr++;
483     }
484 }
485
486 void lnksect2 (struct area *tap, int rloc);
487 char idatamap[256];
488 long codemap[524288];
489
490 /*Modified version of the functions for packing variables in internal data memory*/
491 VOID lnkarea2 (void)
492 {
493     Addr_T rloc[4]={0, 0, 0, 0};
494     int  locIndex;
495     char temp[NCPS];
496     struct sym *sp;
497     int j;
498     struct area *dseg_ap = NULL;
499     struct area *abs_ap = NULL;
500     struct sym *sp_dseg_s=NULL, *sp_dseg_l=NULL;
501
502     for(j=0; j<256; j++) idatamap[j]=' ';
503     memset(codemap, 0, sizeof(codemap));
504
505     /* first sort all absolute areas to the front */
506     ap = areap;
507     /* no need to check first area, it's in front anyway */
508     while (ap && ap->a_ap)
509     {
510         if (ap->a_ap->a_flag & A_ABS)
511         {/* next area is absolute, move it to front,
512             reversed sequence is no problem for absolutes */
513             abs_ap = ap->a_ap;
514             ap->a_ap = abs_ap->a_ap;
515             abs_ap->a_ap = areap;
516             areap = abs_ap;
517         }
518         ap = ap->a_ap;
519     }
520
521     ap = areap;
522     while (ap)
523     {
524         /* Determine memory space */
525              if (ap->a_flag & A_CODE)  locIndex = 1;
526         else if (ap->a_flag & A_XDATA) locIndex = 2;
527         else if (ap->a_flag & A_BIT)   locIndex = 3;
528         else locIndex = 0;
529
530         if (ap->a_flag&A_ABS) /* Absolute sections */
531         {
532             lnksect2(ap, locIndex);
533         }
534         else /* Relocatable sections */
535         {
536             if (ap->a_type == 0)
537             {
538                 ap->a_addr=rloc[locIndex];
539                 ap->a_type=1;
540             }
541
542             lnksect2(ap, locIndex);
543             rloc[locIndex] = ap->a_addr + ap->a_size;
544         }
545
546         /*
547          * Create symbols called:
548          *  s_<areaname>    the start address of the area
549          *  l_<areaname>    the length of the area
550          */
551
552         if (! symeq(ap->a_id, _abs_))
553         {
554             strncpy(temp+2,ap->a_id,NCPS-2);
555             *(temp+1) = '_';
556
557             *temp = 's';
558             sp = lkpsym(temp, 1);
559             sp->s_addr = ap->a_addr ;
560             sp->s_type |= S_DEF;
561             if (!strcmp(ap->a_id, "DSEG")) sp_dseg_s=sp;
562
563             *temp = 'l';
564             sp = lkpsym(temp, 1);
565             sp->s_addr = ap->a_size;
566             sp->s_axp = NULL;
567             sp->s_type |= S_DEF;
568             if (!strcmp(ap->a_id, "DSEG")) sp_dseg_l=sp;
569         }
570
571         /*Since area BSEG is defined just before BSEG_BYTES, use the bit size of BSEG
572         to compute the byte size of BSEG_BYTES: */
573         if (!strcmp(ap->a_id, "BSEG"))
574         {
575             ap->a_ap->a_axp->a_size = ((ap->a_addr + ap->a_size + 7)/8); /*Bits to bytes*/
576         }
577         else if (!strcmp(ap->a_id, "DSEG"))
578         {
579             dseg_ap=ap; /*Need it later to set its correct size*/
580         }
581         ap = ap->a_ap;
582     }
583
584     /*Compute the size of DSEG*/
585     if(dseg_ap!=NULL)
586     {
587         dseg_ap->a_addr=0;
588         dseg_ap->a_size=0;
589         for(j=0; j<0x80; j++) if(idatamap[j]!=' ') dseg_ap->a_size++;
590     }
591     if(sp_dseg_s!=NULL) sp_dseg_s->s_addr=0;
592     if(sp_dseg_l!=NULL) sp_dseg_l->s_addr=dseg_ap->a_size;
593
594 #if 0
595     /*Print the memory map*/
596     fprintf(stderr, "Internal RAM layout:\n"
597            "      0 1 2 3 4 5 6 7 8 9 A B C D E F");
598     for(j=0; j<256; j++)
599     {
600         if(j%16==0) fprintf(stderr, "\n0x%02x:|", j);
601         fprintf(stderr, "%c|", idatamap[j]);
602     }
603     fprintf(stderr, "\n0-3:Reg Banks, a-z:Data, B:Bits, Q:Overlay, I:iData, S:Stack\n");
604 #endif
605 }
606
607 void lnksect2 (struct area *tap, int rloc)
608 {
609     register Addr_T size, addr;
610     register struct areax *taxp;
611     int j, k, ramlimit;
612     char fchar, dchar='a';
613     char ErrMsg[]="?ASlink-Error-Could not get %d consecutive byte%s"
614                   " in internal RAM for area %s.\n";
615
616     tap->a_unaloc=0;
617
618     /*Notice that only ISEG and SSEG can be in the indirectly addressable internal RAM*/
619     if( (!strcmp(tap->a_id, "ISEG")) || (!strcmp(tap->a_id, "SSEG")) )
620     {
621         if((iram_size<=0)||(iram_size>0x100))
622             ramlimit=0x100;
623         else
624             ramlimit=iram_size;
625     }
626     else
627     {
628         if((iram_size<=0)||(iram_size>0x80))
629             ramlimit=0x80;
630         else
631             ramlimit=iram_size;
632     }
633
634     size = 0;
635     addr = tap->a_addr;
636 #if 0
637     if ((tap->a_flag&A_PAG) && (addr & 0xFF))
638     {
639         fprintf(stderr,
640           "\n?ASlink-Warning-Paged Area %8s Boundary Error\n", tap->a_id);
641         lkerr++;
642     }
643 #endif
644     taxp = tap->a_axp;
645
646     /*Use a letter to identify each area in the internal RAM layout map*/
647     if(rloc==0)
648     {
649         /**/ if(!strcmp(tap->a_id, "DSEG"))
650             fchar='D'; /*It will be converted to letters 'a' to 'z' later for each areax*/
651         else if(!strcmp(tap->a_id, "ISEG"))
652             fchar='I';
653         else if(!strcmp(tap->a_id, "SSEG"))
654             fchar='S';
655         else if(!strcmp(tap->a_id, "OSEG"))
656             fchar='Q';
657         else if(!strcmp(tap->a_id, "REG_BANK_0"))
658             fchar='0';
659         else if(!strcmp(tap->a_id, "REG_BANK_1"))
660             fchar='1';
661         else if(!strcmp(tap->a_id, "REG_BANK_2"))
662             fchar='2';
663         else if(!strcmp(tap->a_id, "REG_BANK_3"))
664             fchar='3';
665         else if(!strcmp(tap->a_id, "BSEG_BYTES"))
666             fchar='B';
667         else if(!strcmp(tap->a_id, "BIT_BANK"))
668             fchar='T';
669         else
670             fchar=' ';/*???*/
671     }
672     else
673     {
674         fchar=' ';
675     }
676
677     if (tap->a_flag&A_OVR) /* Overlayed sections */
678     {
679         while (taxp)
680         {
681             if ( (fchar=='0')||(fchar=='1')||(fchar=='2')||(fchar=='3') ) /*Reg banks*/
682             {
683                 addr=(fchar-'0')*8;
684                 taxp->a_addr=addr;
685                 size=taxp->a_size;
686                 for(j=addr; (j<(int)(addr+taxp->a_size)) && (j<ramlimit); j++)
687                     idatamap[j]=fchar;
688             }
689             else if( (fchar=='S') || (fchar=='Q') ) /*Overlay and stack in internal RAM*/
690             {
691                 /*Find the size of the space currently used for this areax overlay*/
692                 for(j=0, size=0; j<ramlimit; j++)
693                     if(idatamap[j]==fchar) size++;
694
695                 if( (fchar=='S') && (stacksize==0) )
696                 {
697                    /*Search for the largest space available and use it for stack*/
698                     for(j=0, k=0, taxp->a_size=0; j<ramlimit; j++)
699                     {
700                         if(idatamap[j]==' ')
701                         {
702                             if((++k)>(int)taxp->a_size) taxp->a_size=k;
703                         }
704                         else
705                         {
706                             k=0;
707                         }
708                     }
709                     stacksize=taxp->a_size;
710                 }
711
712                 /*If more space required, release the previously allocated areax in
713                 internal RAM and search for a bigger one*/
714                 if((int)taxp->a_size>size)
715                 {
716                     size=(int)taxp->a_size;
717
718                     for(j=0; j<ramlimit; j++)
719                         if(idatamap[j]==fchar) idatamap[j]=' ';
720
721                     /*Search for a space large enough in data memory for this overlay areax*/
722                     for(j=0, k=0; j<ramlimit; j++)
723                     {
724                         if(idatamap[j]==' ')
725                             k++;
726                         else
727                             k=0;
728                         if(k==(int)taxp->a_size) break;
729                     }
730
731                     if(k==(int)taxp->a_size)
732                     {
733                         taxp->a_addr = j-k+1;
734                         if(addr<(unsigned int)ramlimit)
735                         {
736                             for(j=ramlimit-1; (j>=0)&&(idatamap[j]==' '); j--);
737                             if(j>=0) addr=j+1;
738                         }
739                     }
740
741                     /*Mark the memory used for overlay*/
742                     if(k==(int)taxp->a_size)
743                     {
744                         for(j=taxp->a_addr; (j<(int)(taxp->a_addr+taxp->a_size)) && (j<ramlimit); j++)
745                             idatamap[j]=fchar;
746
747                         /*Set the new size of the data memory area*/
748                         size=ramlimit-addr;
749                     }
750                     else /*Couldn't find a chunk big enough: report the problem.*/
751                     {
752                         tap->a_unaloc=taxp->a_size;
753                         fprintf(stderr, ErrMsg, taxp->a_size, taxp->a_size>1?"s":"", tap->a_id);
754                         lkerr++;
755                     }
756                 }
757
758                 for(j=0; j<ramlimit; j++)
759                 {
760                     if (idatamap[j]==fchar)
761                     {
762                         addr=j;
763                         tap->a_addr=addr;
764                         taxp->a_addr=addr;
765                         break;
766                     }
767                 }
768             }
769             else if (fchar=='T') /*Bit addressable bytes in internal RAM*/
770             {
771                 /*Find the size of the space currently used for this areax overlay*/
772                 for(j=0x20, size=0; j<0x30; j++)
773                     if(idatamap[j]==fchar) size++;
774
775                 /*If more space required, release the previously allocated areax in
776                 internal RAM and search for a bigger one*/
777                 if((int)taxp->a_size>size)
778                 {
779                     size=(int)taxp->a_size;
780
781                     for(j=0x20; j<0x30; j++)
782                         if(idatamap[j]==fchar) idatamap[j]=' ';
783
784                     /*Search for a space large enough in data memory for this overlay areax*/
785                     for(j=0x20, k=0; j<0x30; j++)
786                     {
787                         if(idatamap[j]==' ')
788                             k++;
789                         else
790                             k=0;
791                         if(k==(int)taxp->a_size) break;
792                     }
793
794                     if(k==(int)taxp->a_size)
795                     {
796                         taxp->a_addr = j-k+1;
797                         if(addr<(unsigned int)0x30)
798                         {
799                             for(j=0x2F; (j>=0x20)&&(idatamap[j]==' '); j--);
800                             if(j>=0x20) addr=j+1;
801                         }
802                     }
803
804                     /*Mark the memory used for overlay*/
805                     if(k==(int)taxp->a_size)
806                     {
807                         for(j=taxp->a_addr; (j<(int)(taxp->a_addr+taxp->a_size)) && (j<0x30); j++)
808                             idatamap[j]=fchar;
809
810                         /*Set the new size of the data memory area*/
811                         size=ramlimit-addr;
812                     }
813                     else /*Couldn't find a chunk big enough: report the problem.*/
814                     {
815                         tap->a_unaloc=taxp->a_size;
816                         fprintf(stderr, ErrMsg, taxp->a_size, taxp->a_size>1?"s":"", tap->a_id);
817                         lkerr++;
818                     }
819                 }
820
821                 for(j=0x20; j<0x30; j++)
822                 {
823                     if (idatamap[j]==fchar)
824                     {
825                         addr=j;
826                         tap->a_addr=addr;
827                         taxp->a_addr=addr;
828                         break;
829                     }
830                 }
831             }
832             else /*Overlay areas not in internal ram*/
833             {
834                 taxp->a_addr = addr;
835                 if (taxp->a_size > size) size = taxp->a_size;
836             }
837             taxp = taxp->a_axp;
838         }
839     }
840     else /* Concatenated sections */
841     {
842         while (taxp)
843         {
844             if( (fchar=='D') || (fchar=='I') )
845             {
846                 if(taxp->a_size)
847                 {
848                     /*Search for a space large enough in internal RAM for this areax*/
849                     for(j=0, k=0; j<ramlimit; j++)
850                     {
851                         if(idatamap[j]==' ')
852                             k++;
853                         else
854                             k=0;
855                         if(k==(int)taxp->a_size) break;
856                     }
857
858                     if(k==(int)taxp->a_size)
859                     {
860                         taxp->a_addr = j-k+1;
861                         if(addr<(unsigned int)ramlimit)
862                         {
863                             for(j=ramlimit-1; (j>=0)&&(idatamap[j]==' '); j--);
864                             if(j>=0) addr=j+1;
865                             size=ramlimit-addr;
866                         }
867
868                         for(j=taxp->a_addr; (j<(int)(taxp->a_addr+taxp->a_size)) && (j<ramlimit); j++)
869                             idatamap[j]=(fchar=='D')?dchar:fchar;
870                         if((taxp->a_size>0)&&(fchar=='D'))dchar++;
871                         if((dchar<'a')||(dchar>'z')) dchar='D'; /*Ran out of letters?*/
872                     }
873                     else /*We are in trouble, there is not enough memory for an areax chunk*/
874                     {
875                         taxp->a_addr = addr;
876                         addr += taxp->a_size;
877                         size += taxp->a_size;
878                         tap->a_unaloc+=taxp->a_size;
879                         fprintf(stderr, ErrMsg, taxp->a_size, taxp->a_size>1?"s":"", tap->a_id);
880                         lkerr++;
881                     }
882                }
883                taxp = taxp->a_axp;
884             }
885             else if(fchar=='B')
886             {
887                 if(taxp->a_size!=0)
888                 {
889                     for(j=addr; j<((int)(addr+taxp->a_size)); j++)
890                         idatamap[j]=fchar;
891                 }
892
893                 taxp->a_addr = addr;
894                 addr += taxp->a_size;
895                 size += taxp->a_size;
896                 taxp = taxp->a_axp;
897             }
898             else /*For concatenated BIT, CODE, and XRAM areax's*/
899             {
900                 if(!strcmp(tap->a_id, "XSTK") && (taxp->a_size == 1))
901                 {
902                     taxp->a_size = 256-(addr & 0xFF);
903                 }
904                 //should find next unused address now!!!
905                 //but let's first just warn for overlaps
906                 if (rloc == 1)
907                 {
908                     int a = addr;
909                     int i = addr >> 5;
910                     int j = (addr + taxp->a_size) >> 5;
911                     long mask = -(1 << (addr & 0x1F));
912
913                     while (i < j)
914                     {
915                         if (codemap[i] & mask)
916                         {
917                             fprintf(stderr, "memory overlap near 0x%X for %s\n", a, tap->a_id);
918                         }
919                         codemap[i++] |= mask;
920                         mask = 0xFFFFFFFF;
921                         a += 32;
922                     }
923                     mask &= (1 << ((addr + taxp->a_size) & 0x1F)) - 1;
924                     if (codemap[i] & mask)
925                     {
926                         fprintf(stderr, "memory overlap near 0x%X for %s\n", a, tap->a_id);
927                     }
928                     codemap[i] |= mask;
929                 }
930                 taxp->a_addr = addr;
931                 addr += taxp->a_size;
932                 size += taxp->a_size;
933                 taxp = taxp->a_axp;
934             }
935         }
936     }
937     tap->a_size = size;
938
939     if ((tap->a_flag&A_PAG) && (size > 256))
940     {
941         fprintf(stderr,
942         "\n?ASlink-Warning-Paged Area %8s Length Error\n", tap->a_id);
943         lkerr++;
944     }
945     if ((tap->a_flag&A_PAG) && (tap->a_size) &&
946         ((tap->a_addr & 0xFFFFFF00) != ((addr-1) & 0xFFFFFF00)))
947     {
948         fprintf(stderr,
949         "\n?ASlink-Warning-Paged Area %8s Boundary Error\n", tap->a_id);
950         lkerr++;
951     }
952 }