* as/asx8051.dsp: added mcs51/strcmpi.h
[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      * Evaluate area address
142      */
143     skip(-1);
144     axp->a_addr = eval();
145     /*
146      * Place pointer in header area list
147      */
148     if (headp == NULL) {
149         fprintf(stderr, "No header defined\n");
150         lkexit(1);
151     }
152     narea = hp->h_narea;
153     halp = hp->a_list;
154     for (i=0; i < narea ;++i) {
155         if (halp[i] == NULL) {
156             halp[i] = taxp;
157             return;
158         }
159     }
160     fprintf(stderr, "Header area list overflow\n");
161     lkexit(1);
162 }
163
164 /*)Function VOID    lkparea(id)
165  *
166  *      char *  id      pointer to the area name string
167  *
168  *  The function lkparea() searches the linked area structures
169  *  for a name match.  If the name is not found then an area
170  *  structure is created.  An areax structure is created and
171  *  appended to the areax structures linked to the area structure.
172  *  The associated base area and head structure pointers are
173  *  loaded into the areax structure.
174  *
175  *  local variables:
176  *      area *  tap         pointer to an area structure
177  *      areax * taxp        pointer to an areax structure
178  *
179  *  global variables:
180  *      area    *ap         Pointer to the current
181  *                          area structure
182  *      area    *areap      The pointer to the first
183  *                          area structure of a linked list
184  *      areax   *axp        Pointer to the current
185  *                          areax structure
186  *
187  *  functions called:
188  *      VOID *  new()       lksym()
189  *      char *  strcpy()    c_library
190  *      int     symeq()     lksym.c
191  *
192  *  side effects:
193  *      Area and/or areax structures are created.
194  *      Failure to allocate space for created structures
195  *      will terminate the linker.
196  */
197
198 VOID
199 lkparea(char *id)
200 {
201     register struct area *tap;
202     register struct areax *taxp;
203
204     ap = areap;
205     axp = (struct areax *) new (sizeof(struct areax));
206     axp->a_addr = -1; /* default: no address yet */
207     while (ap) {
208         if (symeq(id, ap->a_id)) {
209             taxp = ap->a_axp;
210             while (taxp->a_axp)
211                 taxp = taxp->a_axp;
212             taxp->a_axp = axp;
213             axp->a_bap = ap;
214             axp->a_bhp = hp;
215             return;
216         }
217         ap = ap->a_ap;
218     }
219     ap = (struct area *) new (sizeof(struct area));
220     if (areap == NULL) {
221         areap = ap;
222     } else {
223         tap = areap;
224         while (tap->a_ap)
225             tap = tap->a_ap;
226         tap->a_ap = ap;
227     }
228     ap->a_axp = axp;
229     axp->a_bap = ap;
230     axp->a_bhp = hp;
231     strncpy(ap->a_id, id, NCPS);
232     ap->a_addr = 0;
233 }
234
235 /*)Function VOID    lnkarea()
236  *
237  *  The function lnkarea() resolves all area addresses.
238  *  The function evaluates each area structure (and all
239  *  the associated areax structures) in sequence.  The
240  *  linking process supports four (4) possible area types:
241  *
242  *  ABS/OVR -   All sections (each individual areax
243  *          section) starts at the identical base
244  *          area address overlaying all other
245  *          areax sections for this area.  The
246  *          size of the area is largest of the area
247  *          sections.
248  *
249  *  ABS/CON -   All sections (each individual areax
250  *          section) are concatenated with the
251  *          first section starting at the base
252  *          area address.  The size of the area
253  *          is the sum of the section sizes.
254  *
255  *  NOTE:   Multiple absolute (ABS) areas are
256  *          never concatenated with each other,
257  *          thus absolute area A and absolute area
258  *          B will overlay each other if they begin
259  *          at the same location (the default is
260  *          always address 0 for absolute areas).
261  *
262  *  REL/OVR -   All sections (each individual areax
263  *          section) starts at the identical base
264  *          area address overlaying all other
265  *          areax sections for this area.  The
266  *          size of the area is largest of the area
267  *          sections.
268  *
269  *  REL/CON -   All sections (each individual areax
270  *          section) are concatenated with the
271  *          first section starting at the base
272  *          area address.  The size of the area
273  *          is the sum of the section sizes.
274  *
275  *  NOTE:   Relocatable (REL) areas are always concatenated
276  *          with each other, thus relocatable area B
277  *          (defined after area A) will follow
278  *          relocatable area A independent of the
279  *          starting address of area A.  Within a
280  *          specific area each areax section may be
281  *          overlayed or concatenated with other
282  *          areax sections.
283  *
284  *
285  *  If a base address for an area is specified then the
286  *  area will start at that address.  Any relocatable
287  *  areas defined subsequently will be concatenated to the
288  *  previous relocatable area if it does not have a base
289  *  address specified.
290  *
291  *  The names s_<areaname> and l_<areaname> are created to
292  *  define the starting address and length of each area.
293  *
294  *  local variables:
295  *      Addr_T  rloc        ;current relocation address
296  *      char    temp[]      ;temporary string
297  *      struct symbol   *sp ;symbol structure
298  *
299  *  global variables:
300  *      area    *ap         Pointer to the current
301  *                          area structure
302  *      area    *areap      The pointer to the first
303  *                          area structure of a linked list
304  *
305  *  functions called:
306  *      int     fprintf()   c_library
307  *      VOID    lnksect()   lkarea.c
308  *      symbol *lkpsym()    lksym.c
309  *      char *  strncpy()   c_library
310  *      int     symeq()     lksym.c
311  *
312  *  side effects:
313  *      All area and areax addresses and sizes are
314  *      determined and saved in their respective
315  *      structures.
316  */
317
318 /*
319  * Resolve all area addresses.
320  */
321 VOID
322 lnkarea()
323 {
324     Addr_T rloc[4];
325     int  locIndex;
326     char temp[NCPS];
327     struct sym *sp;
328     /*JCF: used to save the REG_BANK_[0-3] and SBIT_BYTES area pointers*/
329     struct area *ta[5];
330     int j;
331
332     rloc[0] = rloc[1] = rloc[2] = rloc[3] = 0;
333     ap = areap;
334     while (ap) {
335         if (ap->a_flag&A_ABS) {
336             /*
337              * Absolute sections
338              */
339             lnksect(ap);
340         } else {
341             /* Determine memory space */
342             locIndex = 0;
343             if (ap->a_flag & A_CODE) {
344                 locIndex = 1;
345             }
346             if (ap->a_flag & A_XDATA) {
347                 locIndex = 2;
348             }
349             if (ap->a_flag & A_BIT) {
350                 locIndex = 3;
351             }
352             /*
353              * Relocatable sections
354              */
355             if (ap->a_type == 0) {  /* JLH */
356                 ap->a_addr = rloc[ locIndex ];
357                 ap->a_type = 1;
358             }
359             lnksect(ap);
360             rloc[ locIndex ] = ap->a_addr + ap->a_size;
361         }
362
363         /*
364          * Create symbols called:
365          *  s_<areaname>    the start address of the area
366          *  l_<areaname>    the length of the area
367          */
368
369         if (! symeq(ap->a_id, _abs_)) {
370             strncpy(temp+2,ap->a_id,NCPS-2);
371             *(temp+1) = '_';
372
373             *temp = 's';
374             sp = lkpsym(temp, 1);
375             sp->s_addr = ap->a_addr ;
376             /* sp->s_axp = ap->a_axp;  JLH: was NULL; */
377             sp->s_type |= S_DEF;
378
379             *temp = 'l';
380             sp = lkpsym(temp, 1);
381             sp->s_addr = ap->a_size;
382             sp->s_axp = NULL;
383             sp->s_type |= S_DEF;
384
385         }
386
387         /*JCF: Since area BSEG is defined just before BSEG_BYTES, use the bit size of BSEG
388         to compute the byte size of BSEG_BYTES: */
389         if (!strcmp(ap->a_id, "BSEG")) {
390             ap->a_ap->a_axp->a_size += ((ap->a_addr + ap->a_size + 7)/8); /*Bits to bytes*/
391         }
392         else if (!strcmp(ap->a_id, "REG_BANK_0")) ta[0]=ap;
393         else if (!strcmp(ap->a_id, "REG_BANK_1")) ta[1]=ap;
394         else if (!strcmp(ap->a_id, "REG_BANK_2")) ta[2]=ap;
395         else if (!strcmp(ap->a_id, "REG_BANK_3")) ta[3]=ap;
396         else if (!strcmp(ap->a_id, "BSEG_BYTES"))
397         {
398             ta[4]=ap;
399             for(j=4; j>1; j--)
400             {
401                 /*If upper register banks are not used roll back the relocation counter*/
402                 if ( (ta[j]->a_size==0) && (ta[j-1]->a_size==0) )
403                 {
404                     rloc[0]-=8;
405                 }
406                 else break;
407             }
408         }
409         ap = ap->a_ap;
410     }
411 }
412
413 /*)Function VOID    lnksect()
414  *
415  *      area *  tap         pointer to an area structure
416  *
417  *  The function lnksect() is the function called by
418  *  lnkarea() to resolve the areax addresses.  Refer
419  *  to the function lnkarea() for more detail. Pageing
420  *  boundary and length errors will be reported by this
421  *  function.
422  *
423  *  local variables:
424  *      Addr_T  size        size of area
425  *      Addr_T  addr        address of area
426  *      areax * taxp        pointer to an areax structure
427  *
428  *  global variables:
429  *      int     lkerr       error flag
430  *
431  *  functions called:
432  *      none
433  *
434  *  side effects:
435  *      All area and areax addresses and sizes area determined
436  *      and linked into the structures.
437  */
438
439 VOID
440 lnksect(register struct area *tap)
441 {
442     register Addr_T size, addr;
443     register struct areax *taxp;
444
445     size = 0;
446     addr = tap->a_addr;
447 #if 0
448     if ((tap->a_flag&A_PAG) && (addr & 0xFF)) {
449         fprintf(stderr,
450         "\n?ASlink-Warning-Paged Area %8s Boundary Error\n", tap->a_id);
451         lkerr++;
452     }
453 #endif
454     taxp = tap->a_axp;
455     if (tap->a_flag&A_OVR) {
456         /*
457          * Overlayed sections
458          */
459         while (taxp) {
460             taxp->a_addr = addr;
461             if (taxp->a_size > size)
462                 size = taxp->a_size;
463             taxp = taxp->a_axp;
464         }
465     } else {
466         /*
467          * Concatenated sections
468          */
469         while (taxp) {
470             taxp->a_addr = addr;
471             addr += taxp->a_size;
472             size += taxp->a_size;
473             taxp = taxp->a_axp;
474         }
475     }
476     tap->a_size = size;
477     if ((tap->a_flag&A_PAG) && (size > 256)) {
478         fprintf(stderr,
479         "\n?ASlink-Warning-Paged Area %8s Length Error\n", tap->a_id);
480         lkerr++;
481     }
482     if ((tap->a_flag&A_PAG) && (tap->a_size) &&
483         ((tap->a_addr & 0xFFFFFF00) != ((addr-1) & 0xFFFFFF00)))
484     {
485         fprintf(stderr,
486         "\n?ASlink-Warning-Paged Area %8s Boundary Error\n", tap->a_id);
487         lkerr++;
488     }
489 }
490
491 Addr_T lnksect2 (struct area *tap, int rloc);
492 char idatamap[256];
493 unsigned long codemap[524288];
494
495 /*Modified version of the functions for packing variables in internal data memory*/
496 VOID lnkarea2 (void)
497 {
498     Addr_T rloc[4]={0, 0, 0, 0};
499     Addr_T gs_size = 0;
500     int  locIndex;
501     char temp[NCPS];
502     struct sym *sp;
503     int j;
504     struct area *dseg_ap = NULL;
505     struct area *abs_ap = NULL;
506     struct area *gs0_ap = NULL;
507     struct sym *sp_dseg_s=NULL, *sp_dseg_l=NULL;
508
509     for(j=0; j<256; j++) idatamap[j]=' ';
510     memset(codemap, 0, sizeof(codemap));
511
512     /* first sort all absolute areas to the front */
513     ap = areap;
514     /* no need to check first area, it's in front anyway */
515     while (ap && ap->a_ap)
516     {
517         if (ap->a_ap->a_flag & A_ABS)
518         {/* next area is absolute, move it to front,
519             reversed sequence is no problem for absolutes */
520             abs_ap = ap->a_ap;
521             ap->a_ap = abs_ap->a_ap;
522             abs_ap->a_ap = areap;
523             areap = abs_ap;
524         }
525         ap = ap->a_ap;
526     }
527
528     /* next accumulate all GSINITx/GSFINAL area sizes
529        into GSINIT so they stay together */
530     ap = areap;
531     while (ap)
532     {
533         if (!strncmp(ap->a_id, "GS", 2))
534         {/* GSxxxxx area */
535             if (ap->a_size == 0)
536             {
537                 axp = ap->a_axp;
538                 while (axp)
539                 {
540                     ap->a_size += axp->a_size;
541                     axp = axp->a_axp;
542                 }
543             }
544             gs_size += ap->a_size;
545             if (!strcmp(ap->a_id, "GSINIT0"))
546             {/* GSINIT0 area */
547                 gs0_ap = ap;
548             }
549         }
550         ap = ap->a_ap;
551     }
552     if (gs0_ap)
553         gs0_ap->a_size = gs_size;
554
555     ap = areap;
556     while (ap)
557     {
558         /* Determine memory space */
559              if (ap->a_flag & A_CODE)  locIndex = 1;
560         else if (ap->a_flag & A_XDATA) locIndex = 2;
561         else if (ap->a_flag & A_BIT)   locIndex = 3;
562         else locIndex = 0;
563
564         if (ap->a_flag & A_ABS) /* Absolute sections */
565         {
566             lnksect2(ap, locIndex);
567         }
568         else /* Relocatable sections */
569         {
570             if (ap->a_type == 0)
571             {
572                 ap->a_addr = rloc[locIndex];
573                 ap->a_type = 1;
574             }
575
576             rloc[locIndex] = lnksect2(ap, locIndex);
577         }
578
579         /*
580          * Create symbols called:
581          *  s_<areaname>    the start address of the area
582          *  l_<areaname>    the length of the area
583          */
584
585         if (! symeq(ap->a_id, _abs_))
586         {
587             strncpy(temp+2,ap->a_id,NCPS-2);
588             *(temp+1) = '_';
589
590             *temp = 's';
591             sp = lkpsym(temp, 1);
592             sp->s_addr = ap->a_addr ;
593             sp->s_type |= S_DEF;
594             if (!strcmp(ap->a_id, "DSEG")) sp_dseg_s=sp;
595
596             *temp = 'l';
597             sp = lkpsym(temp, 1);
598             sp->s_addr = ap->a_size;
599             sp->s_axp = NULL;
600             sp->s_type |= S_DEF;
601             if (!strcmp(ap->a_id, "DSEG")) sp_dseg_l=sp;
602         }
603
604         /*Since area BSEG is defined just before BSEG_BYTES, use the bit size of BSEG
605         to compute the byte size of BSEG_BYTES: */
606         if (!strcmp(ap->a_id, "BSEG"))
607         {
608             ap->a_ap->a_axp->a_size = ((ap->a_addr + ap->a_size + 7)/8); /*Bits to bytes*/
609         }
610         else if (!strcmp(ap->a_id, "DSEG"))
611         {
612             dseg_ap=ap; /*Need it later to set its correct size*/
613         }
614         ap = ap->a_ap;
615     }
616
617     /*Compute the size of DSEG*/
618     if(dseg_ap!=NULL)
619     {
620         dseg_ap->a_addr=0;
621         dseg_ap->a_size=0;
622         for(j=0; j<0x80; j++) if(idatamap[j]!=' ') dseg_ap->a_size++;
623     }
624     if(sp_dseg_s!=NULL) sp_dseg_s->s_addr=0;
625     if(sp_dseg_l!=NULL) sp_dseg_l->s_addr=dseg_ap->a_size;
626
627 #if 0
628     /*Print the memory map*/
629     fprintf(stderr, "Internal RAM layout:\n"
630            "      0 1 2 3 4 5 6 7 8 9 A B C D E F");
631     for(j=0; j<256; j++)
632     {
633         if(j%16==0) fprintf(stderr, "\n0x%02x:|", j);
634         fprintf(stderr, "%c|", idatamap[j]);
635     }
636     fprintf(stderr, "\n0-3:Reg Banks, a-z:Data, B:Bits, Q:Overlay, I:iData, S:Stack\n");
637 #endif
638 }
639
640 static
641 Addr_T find_empty_space(Addr_T start, Addr_T size)
642 {
643     int i, j, k;
644     unsigned long mask, b;
645
646     while (1)
647     {
648         Addr_T a = start;
649         i = start >> 5;
650         j = (start + size) >> 5;
651         mask = -(1 << (start & 0x1F));
652
653         while (i < j)
654         {
655             if (codemap[i] & mask)
656             {
657                 k = 32;
658                 for (b=0x80000000; b!=0; b>>=1, k--)
659                 {
660                     if (codemap[i] & b)
661                       break;
662                 }
663                 start = a + k;
664                 break;
665             }
666             i++;
667             mask = 0xFFFFFFFF;
668             a += 32;
669         }
670         if (start > a)
671           continue;
672
673         mask &= (1 << ((start + size) & 0x1F)) - 1;
674         if (codemap[i] & mask)
675         {
676             k = 32;
677             for (b=0x80000000; b!=0; b>>=1, k--)
678             {
679                 if (codemap[i] & b)
680                   break;
681             }
682             start = (a & ~0x1F) + k;
683         }
684         if (start <= a)
685           break;
686     }
687     return start;
688 }
689
690 static
691 Addr_T allocate_space(Addr_T start, Addr_T size, char* id)
692 {
693     int i, j;
694     unsigned long mask;
695     Addr_T a = start;
696     i = start >> 5;
697     j = (start + size) >> 5;
698     mask = -(1 << (start & 0x1F));
699
700     while (i < j)
701     {
702         if (codemap[i] & mask)
703         {
704             fprintf(stderr, "memory overlap near 0x%X for %s\n", a, id);
705         }
706         codemap[i++] |= mask;
707         mask = 0xFFFFFFFF;
708         a += 32;
709     }
710     mask &= (1 << ((start + size) & 0x1F)) - 1;
711     if (codemap[i] & mask)
712     {
713         fprintf(stderr, "memory overlap near 0x%X for %s\n", a, id);
714     }
715     codemap[i] |= mask;
716     return start;
717 }
718
719 Addr_T lnksect2 (struct area *tap, int rloc)
720 {
721     register Addr_T size, addr;
722     register struct areax *taxp;
723     int j, k, ramlimit;
724     char fchar=' ', dchar='a';
725     char ErrMsg[]="?ASlink-Error-Could not get %d consecutive byte%s"
726                   " in internal RAM for area %s.\n";
727
728     tap->a_unaloc=0;
729
730     /*Notice that only ISEG and SSEG can be in the indirectly addressable internal RAM*/
731     if( (!strcmp(tap->a_id, "ISEG")) || (!strcmp(tap->a_id, "SSEG")) )
732     {
733         if((iram_size<=0)||(iram_size>0x100))
734             ramlimit=0x100;
735         else
736             ramlimit=iram_size;
737     }
738     else
739     {
740         if((iram_size<=0)||(iram_size>0x80))
741             ramlimit=0x80;
742         else
743             ramlimit=iram_size;
744     }
745
746     size = 0;
747     addr = tap->a_addr;
748 #if 0
749     if ((tap->a_flag&A_PAG) && (addr & 0xFF))
750     {
751         fprintf(stderr,
752           "\n?ASlink-Warning-Paged Area %8s Boundary Error\n", tap->a_id);
753         lkerr++;
754     }
755 #endif
756     taxp = tap->a_axp;
757
758     /*Use a letter to identify each area in the internal RAM layout map*/
759     if (rloc==0)
760     {
761         /**/ if(!strcmp(tap->a_id, "DSEG"))
762             fchar='D'; /*It will be converted to letters 'a' to 'z' later for each areax*/
763         else if(!strcmp(tap->a_id, "ISEG"))
764             fchar='I';
765         else if(!strcmp(tap->a_id, "SSEG"))
766             fchar='S';
767         else if(!strcmp(tap->a_id, "OSEG"))
768             fchar='Q';
769         else if(!strcmp(tap->a_id, "REG_BANK_0"))
770             fchar='0';
771         else if(!strcmp(tap->a_id, "REG_BANK_1"))
772             fchar='1';
773         else if(!strcmp(tap->a_id, "REG_BANK_2"))
774             fchar='2';
775         else if(!strcmp(tap->a_id, "REG_BANK_3"))
776             fchar='3';
777         else if(!strcmp(tap->a_id, "BSEG_BYTES"))
778             fchar='B';
779         else if(!strcmp(tap->a_id, "BIT_BANK"))
780             fchar='T';
781         else
782             fchar=' ';/*???*/
783     }
784     else if (rloc==1)
785     {
786         /**/ if(!strcmp(tap->a_id, "GSINIT"))
787             fchar='G';
788     }
789     else if (rloc==2)
790     {
791         /**/ if(!strcmp(tap->a_id, "XSTK"))
792             fchar='K';
793     }
794
795     if (tap->a_flag&A_OVR) /* Overlayed sections */
796     {
797         while (taxp)
798         {
799             if ( (fchar=='0')||(fchar=='1')||(fchar=='2')||(fchar=='3') ) /*Reg banks*/
800             {
801                 addr=(fchar-'0')*8;
802                 taxp->a_addr=addr;
803                 size=taxp->a_size;
804                 for(j=addr; (j<(int)(addr+taxp->a_size)) && (j<ramlimit); j++)
805                     idatamap[j]=fchar;
806             }
807             else if( (fchar=='S') || (fchar=='Q') ) /*Overlay and stack in internal RAM*/
808             {
809                 /*Find the size of the space currently used for this areax overlay*/
810                 for(j=0, size=0; j<ramlimit; j++)
811                     if(idatamap[j]==fchar) size++;
812
813                 if( (fchar=='S') && (stacksize==0) )
814                 {
815                    /*Search for the largest space available and use it for stack*/
816                     for(j=0, k=0, taxp->a_size=0; j<ramlimit; j++)
817                     {
818                         if(idatamap[j]==' ')
819                         {
820                             if((++k)>(int)taxp->a_size) taxp->a_size=k;
821                         }
822                         else
823                         {
824                             k=0;
825                         }
826                     }
827                     stacksize=taxp->a_size;
828                 }
829
830                 /*If more space required, release the previously allocated areax in
831                 internal RAM and search for a bigger one*/
832                 if((int)taxp->a_size>size)
833                 {
834                     size=(int)taxp->a_size;
835
836                     for(j=0; j<ramlimit; j++)
837                         if(idatamap[j]==fchar) idatamap[j]=' ';
838
839                     /*Search for a space large enough in data memory for this overlay areax*/
840                     for(j=0, k=0; j<ramlimit; j++)
841                     {
842                         if(idatamap[j]==' ')
843                             k++;
844                         else
845                             k=0;
846                         if(k==(int)taxp->a_size) break;
847                     }
848
849                     if(k==(int)taxp->a_size)
850                     {
851                         taxp->a_addr = j-k+1;
852                         if(addr<(unsigned int)ramlimit)
853                         {
854                             for(j=ramlimit-1; (j>=0)&&(idatamap[j]==' '); j--);
855                             if(j>=0) addr=j+1;
856                         }
857                     }
858
859                     /*Mark the memory used for overlay*/
860                     if(k==(int)taxp->a_size)
861                     {
862                         for(j=taxp->a_addr; (j<(int)(taxp->a_addr+taxp->a_size)) && (j<ramlimit); j++)
863                             idatamap[j]=fchar;
864
865                         /*Set the new size of the data memory area*/
866                         size=ramlimit-addr;
867                     }
868                     else /*Couldn't find a chunk big enough: report the problem.*/
869                     {
870                         tap->a_unaloc=taxp->a_size;
871                         fprintf(stderr, ErrMsg, taxp->a_size, taxp->a_size>1?"s":"", tap->a_id);
872                         lkerr++;
873                     }
874                 }
875
876                 for(j=0; j<ramlimit; j++)
877                 {
878                     if (idatamap[j]==fchar)
879                     {
880                         addr=j;
881                         tap->a_addr=addr;
882                         taxp->a_addr=addr;
883                         break;
884                     }
885                 }
886             }
887             else if (fchar=='T') /*Bit addressable bytes in internal RAM*/
888             {
889                 /*Find the size of the space currently used for this areax overlay*/
890                 for(j=0x20, size=0; j<0x30; j++)
891                     if(idatamap[j]==fchar) size++;
892
893                 /*If more space required, release the previously allocated areax in
894                 internal RAM and search for a bigger one*/
895                 if((int)taxp->a_size>size)
896                 {
897                     size=(int)taxp->a_size;
898
899                     for(j=0x20; j<0x30; j++)
900                         if(idatamap[j]==fchar) idatamap[j]=' ';
901
902                     /*Search for a space large enough in data memory for this overlay areax*/
903                     for(j=0x20, k=0; j<0x30; j++)
904                     {
905                         if(idatamap[j]==' ')
906                             k++;
907                         else
908                             k=0;
909                         if(k==(int)taxp->a_size) break;
910                     }
911
912                     if(k==(int)taxp->a_size)
913                     {
914                         taxp->a_addr = j-k+1;
915                         if(addr<(unsigned int)0x30)
916                         {
917                             for(j=0x2F; (j>=0x20)&&(idatamap[j]==' '); j--);
918                             if(j>=0x20) addr=j+1;
919                         }
920                     }
921
922                     /*Mark the memory used for overlay*/
923                     if(k==(int)taxp->a_size)
924                     {
925                         for(j=taxp->a_addr; (j<(int)(taxp->a_addr+taxp->a_size)) && (j<0x30); j++)
926                             idatamap[j]=fchar;
927
928                         /*Set the new size of the data memory area*/
929                         size=ramlimit-addr;
930                     }
931                     else /*Couldn't find a chunk big enough: report the problem.*/
932                     {
933                         tap->a_unaloc=taxp->a_size;
934                         fprintf(stderr, ErrMsg, taxp->a_size, taxp->a_size>1?"s":"", tap->a_id);
935                         lkerr++;
936                     }
937                 }
938
939                 for(j=0x20; j<0x30; j++)
940                 {
941                     if (idatamap[j]==fchar)
942                     {
943                         addr=j;
944                         tap->a_addr=addr;
945                         taxp->a_addr=addr;
946                         break;
947                     }
948                 }
949             }
950             else /*Overlay areas not in internal ram*/
951             {
952                 taxp->a_addr = addr;
953                 if (taxp->a_size > size) size = taxp->a_size;
954             }
955             taxp = taxp->a_axp;
956         }
957     }
958     else if (tap->a_flag & A_ABS) /* Absolute sections */
959     {
960         while (taxp)
961         {
962             if (rloc == 1)
963             {
964                 allocate_space(taxp->a_addr, taxp->a_size, tap->a_id);
965             }
966             taxp->a_addr = 0; /* reset to zero so relative addresses become absolute */
967             size += taxp->a_size;
968             taxp = taxp->a_axp;
969         }
970     }
971     else /* Concatenated sections */
972     {
973         if ((rloc == 1) && tap->a_size)
974         {
975             addr = find_empty_space(addr, tap->a_size);
976         }
977         while (taxp)
978         {
979             if( (fchar=='D') || (fchar=='I') )
980             {
981                 if(taxp->a_size)
982                 {
983                     /*Search for a space large enough in internal RAM for this areax*/
984                     for(j=0, k=0; j<ramlimit; j++)
985                     {
986                         if(idatamap[j]==' ')
987                             k++;
988                         else
989                             k=0;
990                         if(k==(int)taxp->a_size) break;
991                     }
992
993                     if(k==(int)taxp->a_size)
994                     {
995                         taxp->a_addr = j-k+1;
996                         if(addr<(unsigned int)ramlimit)
997                         {
998                             for(j=ramlimit-1; (j>=0)&&(idatamap[j]==' '); j--);
999                             if(j>=0) addr=j+1;
1000                             size=ramlimit-addr;
1001                         }
1002
1003                         for(j=taxp->a_addr; (j<(int)(taxp->a_addr+taxp->a_size)) && (j<ramlimit); j++)
1004                             idatamap[j]=(fchar=='D')?dchar:fchar;
1005                         if((taxp->a_size>0)&&(fchar=='D'))dchar++;
1006                         if((dchar<'a')||(dchar>'z')) dchar='D'; /*Ran out of letters?*/
1007                     }
1008                     else /*We are in trouble, there is not enough memory for an areax chunk*/
1009                     {
1010                         taxp->a_addr = addr;
1011                         addr += taxp->a_size;
1012                         size += taxp->a_size;
1013                         tap->a_unaloc+=taxp->a_size;
1014                         fprintf(stderr, ErrMsg, taxp->a_size, taxp->a_size>1?"s":"", tap->a_id);
1015                         lkerr++;
1016                     }
1017                }
1018                taxp = taxp->a_axp;
1019             }
1020             else if(fchar=='B')
1021             {
1022                 if(taxp->a_size!=0)
1023                 {
1024                     for(j=addr; j<((int)(addr+taxp->a_size)); j++)
1025                         idatamap[j]=fchar;
1026                 }
1027
1028                 taxp->a_addr = addr;
1029                 addr += taxp->a_size;
1030                 size += taxp->a_size;
1031                 taxp = taxp->a_axp;
1032             }
1033             else /*For concatenated BIT, CODE, and XRAM areax's*/
1034             {
1035                 if((fchar=='K') && (taxp->a_size == 1))
1036                 {
1037                     taxp->a_size = 256-(addr & 0xFF);
1038                 }
1039                 //find next unused address now
1040                 if ((rloc == 1) && taxp->a_size)
1041                 {
1042                     addr = find_empty_space(addr, taxp->a_size);
1043                     allocate_space(addr, taxp->a_size, tap->a_id);
1044                 }
1045                 taxp->a_addr = addr;
1046                 addr += taxp->a_size;
1047                 size += taxp->a_size;
1048                 taxp = taxp->a_axp;
1049             }
1050         }
1051     }
1052     tap->a_size = size;
1053
1054     if ((tap->a_flag&A_PAG) && (size > 256))
1055     {
1056         fprintf(stderr,
1057         "\n?ASlink-Warning-Paged Area %8s Length Error\n", tap->a_id);
1058         lkerr++;
1059     }
1060     if ((tap->a_flag&A_PAG) && (tap->a_size) &&
1061         ((tap->a_addr & 0xFFFFFF00) != ((addr-1) & 0xFFFFFF00)))
1062     {
1063         fprintf(stderr,
1064         "\n?ASlink-Warning-Paged Area %8s Boundary Error\n", tap->a_id);
1065         lkerr++;
1066     }
1067     return addr;
1068 }