693b5d493bdb9a14178ed30a6567cde6faf1ba56
[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(id)
195 char *id;
196 {
197         register struct area *tap;
198         register struct areax *taxp;
199
200         ap = areap;
201         axp = (struct areax *) new (sizeof(struct areax));
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 ae 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()        lksysm.c
304  *              char *  strncpy()       c_library
305  *              int             symeq()         lksysm.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/8)+((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 rellocation 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(tap)
436 register struct area *tap;
437 {
438         register Addr_T size, addr;
439         register struct areax *taxp;
440
441         size = 0;
442         addr = tap->a_addr;
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         taxp = tap->a_axp;
449         if (tap->a_flag&A_OVR) {
450                 /*
451                  * Overlayed sections
452                  */
453                 while (taxp) {
454                         taxp->a_addr = addr;
455                         if (taxp->a_size > size)
456                                 size = taxp->a_size;
457                         taxp = taxp->a_axp;
458                 }
459         } else {
460                 /*
461                  * Concatenated sections
462                  */
463                 while (taxp) {
464                         taxp->a_addr = addr;
465                         addr += taxp->a_size;
466                         size += taxp->a_size;
467                         taxp = taxp->a_axp;
468                 }
469         }
470         tap->a_size = size;
471         if ((tap->a_flag&A_PAG) && (size > 256)) {
472             fprintf(stderr,
473             "\n?ASlink-Warning-Paged Area %8s Length Error\n", tap->a_id);
474             lkerr++;
475         }
476 }
477
478 void lnksect2 (struct area *tap, int rloc);
479 char idatamap[256];
480
481 /*Modified version of the functions for packing variables in internal data memory*/
482 VOID lnkarea2 (void)
483 {
484     Addr_T rloc[4]={0, 0, 0, 0};
485         int  locIndex;
486         char temp[NCPS];
487         struct sym *sp;
488         int j;
489     struct area *dseg_ap=NULL;
490         struct sym *sp_dseg_s=NULL, *sp_dseg_l=NULL;
491
492         for(j=0; j<256; j++) idatamap[j]=' ';
493
494         ap = areap;
495         while (ap)
496         {
497                 /* Determine memory space */
498              if (ap->a_flag & A_CODE)  locIndex = 1;
499         else if (ap->a_flag & A_XDATA) locIndex = 2;
500         else if (ap->a_flag & A_BIT)   locIndex = 3;
501         else locIndex = 0;
502
503         if (ap->a_flag&A_ABS) /* Absolute sections */
504                 {
505                         lnksect2(ap, locIndex);
506                 }
507                 else /* Relocatable sections */
508                 {
509                         if (ap->a_type == 0)
510             {
511                                 ap->a_addr=rloc[locIndex];
512                                 ap->a_type=1;
513                         }
514                         
515                         lnksect2(ap, locIndex);
516                         rloc[locIndex] = ap->a_addr + ap->a_size;
517                 }
518
519                 /*
520                  * Create symbols called:
521                  *      s_<areaname>    the start address of the area
522                  *      l_<areaname>    the length of the area
523                  */
524
525                 if (! symeq(ap->a_id, _abs_))
526                 {
527                         strncpy(temp+2,ap->a_id,NCPS-2);
528                         *(temp+1) = '_';
529
530                         *temp = 's';
531                         sp = lkpsym(temp, 1);
532                         sp->s_addr = ap->a_addr ;
533                         sp->s_type |= S_DEF;
534             if (!strcmp(ap->a_id, "DSEG")) sp_dseg_s=sp;
535
536                         *temp = 'l';
537                         sp = lkpsym(temp, 1);
538                         sp->s_addr = ap->a_size;
539                         sp->s_axp = NULL;
540                         sp->s_type |= S_DEF;
541             if (!strcmp(ap->a_id, "DSEG")) sp_dseg_l=sp;
542                 }
543                 
544                 /*Since area BSEG is defined just before BSEG_BYTES, use the bit size of BSEG
545                 to compute the byte size of BSEG_BYTES: */
546                 if (!strcmp(ap->a_id, "BSEG"))
547         {
548                         ap->a_ap->a_axp->a_size=(ap->a_addr/8)+((ap->a_size+7)/8); /*Bits to bytes*/
549                 }
550         else if (!strcmp(ap->a_id, "DSEG"))
551         {
552             dseg_ap=ap; /*Need it later to set its correct size*/
553         }
554                 ap = ap->a_ap;
555         }
556
557     /*Compute the size of DSEG*/
558         if(dseg_ap!=NULL)
559         {
560                 dseg_ap->a_addr=0;
561                 dseg_ap->a_size=0;
562                 for(j=0; j<0x80; j++) if(idatamap[j]!=' ') dseg_ap->a_size++;
563         }
564     if(sp_dseg_s!=NULL) sp_dseg_s->s_addr=0;
565     if(sp_dseg_l!=NULL) sp_dseg_l->s_addr=dseg_ap->a_size;
566
567 #if 0
568     /*Print the memory map*/
569         fprintf(stderr, "Internal RAM layout:\n"
570            "      0 1 2 3 4 5 6 7 8 9 A B C D E F");
571     for(j=0; j<256; j++)
572         {
573                 if(j%16==0) fprintf(stderr, "\n0x%02x:|", j);
574                 fprintf(stderr, "%c|", idatamap[j]);
575         }
576         fprintf(stderr, "\n0-3:Reg Banks, a-z:Data, B:Bits, Q:Overlay, I:iData, S:Stack\n");
577 #endif
578 }
579
580 void lnksect2 (struct area *tap, int rloc)
581 {
582         register Addr_T size, addr;
583         register struct areax *taxp;
584         int j, k, ramlimit;
585     char fchar, dchar='a';
586     char ErrMsg[]="?ASlink-Error-Could not get %d consecutive byte%s" 
587                   " in internal RAM for area %s.\n";
588
589     tap->a_unaloc=0;
590     
591     /*Notice that only ISEG and SSEG can be in the indirectly addressable internal RAM*/
592     if( (!strcmp(tap->a_id, "ISEG")) || (!strcmp(tap->a_id, "SSEG")) )
593     {
594         if((iram_size<=0)||(iram_size>0x100))
595             ramlimit=0x100;
596         else
597             ramlimit=iram_size;
598     }
599     else
600     {
601         ramlimit=0x80;
602     }
603
604         size = 0;
605         addr = tap->a_addr;
606         if ((tap->a_flag&A_PAG) && (addr & 0xFF))
607     {
608             fprintf(stderr,
609             "\n?ASlink-Warning-Paged Area %8s Boundary Error\n", tap->a_id);
610             lkerr++;
611         }
612         taxp = tap->a_axp;
613
614     /*Use a letter to identify each area in the internal RAM layout map*/
615     if(rloc==0)
616     {
617         /**/ if(!strcmp(tap->a_id, "DSEG"))
618             fchar='D'; /*It will be converted to letters 'a' to 'z' latter for each areax*/
619         else if(!strcmp(tap->a_id, "ISEG"))
620             fchar='I';
621         else if(!strcmp(tap->a_id, "SSEG"))
622             fchar='S';
623         else if(!strcmp(tap->a_id, "OSEG"))
624             fchar='Q';
625         else if(!strcmp(tap->a_id, "REG_BANK_0"))
626             fchar='0';
627         else if(!strcmp(tap->a_id, "REG_BANK_1"))
628             fchar='1';
629         else if(!strcmp(tap->a_id, "REG_BANK_2"))
630             fchar='2';
631         else if(!strcmp(tap->a_id, "REG_BANK_3"))
632             fchar='3';
633         else if(!strcmp(tap->a_id, "BSEG_BYTES"))
634             fchar='B';
635         else
636             fchar=' ';/*???*/
637     }
638     else
639     {
640         fchar=' ';
641     }
642
643         if (tap->a_flag&A_OVR) /* Overlayed sections */
644     {
645         while (taxp)
646         {
647             if ( (fchar=='0')||(fchar=='1')||(fchar=='2')||(fchar=='3') ) /*Reg banks*/
648             {
649                 addr=(fchar-'0')*8;
650                 taxp->a_addr=addr;
651                 size=taxp->a_size;
652                 for(j=addr; (j<(int)(addr+taxp->a_size)) && (j<ramlimit); j++)
653                     idatamap[j]=fchar;
654             }
655             else if( (fchar=='S') || (fchar=='Q') ) /*Overlay and stack in internal RAM*/
656             {
657                 /*Find the size of the space currently used for this areax overlay*/
658                 for(j=0, size=0; j<ramlimit; j++)
659                     if(idatamap[j]==fchar) size++;
660
661                 if( (fchar=='S') && (stacksize==0) )
662                 {
663                    /*Search for the largest space available and use it for stack*/
664                     for(j=0, k=0, taxp->a_size=0; j<ramlimit; j++)
665                     {
666                         if(idatamap[j]==' ')
667                         {
668                             if((++k)>(int)taxp->a_size) taxp->a_size=k;
669                         }
670                         else
671                         {
672                             k=0;
673                         }
674                     }
675                     stacksize=taxp->a_size;
676                 }
677
678                 /*If more space required, release the previously allocated areax in 
679                 internal RAM and search for a bigger one*/
680                 if((int)taxp->a_size>size)
681                 {
682                     size=(int)taxp->a_size;
683
684                     for(j=0; j<ramlimit; j++)
685                         if(idatamap[j]==fchar) idatamap[j]=' ';
686                
687                     /*Search for a space large enough in data memory for this overlay areax*/
688                     for(j=0, k=0; j<ramlimit; j++)
689                     {
690                         if(idatamap[j]==' ')
691                             k++;
692                         else
693                             k=0;
694                         if(k==(int)taxp->a_size) break;
695                     }
696
697                     if(k==(int)taxp->a_size)
698                     {
699                         taxp->a_addr = j-k+1;
700                         if(addr<(unsigned int)ramlimit)
701                         {
702                             for(j=ramlimit-1; (j>=0)&&(idatamap[j]==' '); j--);
703                             if(j>=0) addr=j+1;
704                         }
705                     }
706                 
707                     /*Mark the memory used for overlay*/
708                     if(k==(int)taxp->a_size)
709                     {
710                         for(j=taxp->a_addr; (j<(int)(taxp->a_addr+taxp->a_size)) && (j<ramlimit); j++)
711                             idatamap[j]=fchar;
712
713                         /*Set the new size of the data memory area*/
714                         size=ramlimit-addr;
715                     }
716                     else /*Couldn't find a chunk big enough: report the problem.*/
717                     {
718                         tap->a_unaloc=taxp->a_size;
719                         fprintf(stderr, ErrMsg, taxp->a_size, taxp->a_size>1?"s":"", tap->a_id);
720                         lkerr++;
721                     }
722                }
723                 
724                 for(j=0; j<ramlimit; j++)
725                 {
726                     if (idatamap[j]==fchar)
727                     {
728                         addr=j;
729                         tap->a_addr=addr;
730                                 taxp->a_addr=addr;
731                         break;
732                     }
733                 }
734             }
735             else /*Overlay areas not in internal ram*/
736             {
737                             taxp->a_addr = addr;
738                             if (taxp->a_size > size) size = taxp->a_size;
739             }
740             taxp = taxp->a_axp;
741                 }
742         }
743     else /* Concatenated sections */
744     {
745                 while (taxp)
746         {
747                         if( (fchar=='D') || (fchar=='I') )
748                         {
749                 if(taxp->a_size)
750                 {
751                     /*Search for a space large enough in internal RAM for this areax*/
752                     for(j=0, k=0; j<ramlimit; j++)
753                     {
754                         if(idatamap[j]==' ')
755                             k++;
756                         else
757                             k=0;
758                         if(k==(int)taxp->a_size) break;
759                     }
760
761                     if(k==(int)taxp->a_size)
762                     {
763                         taxp->a_addr = j-k+1;
764                         if(addr<(unsigned int)ramlimit)
765                         {
766                             for(j=ramlimit-1; (j>=0)&&(idatamap[j]==' '); j--);
767                             if(j>=0) addr=j+1;
768                             size=ramlimit-addr;
769                         }
770                         
771                         for(j=taxp->a_addr; (j<(int)(taxp->a_addr+taxp->a_size)) && (j<ramlimit); j++)
772                             idatamap[j]=(fchar=='D')?dchar:fchar;
773                         if((taxp->a_size>0)&&(fchar=='D'))dchar++;
774                         if((dchar<'a')||(dchar>'z')) dchar='D'; /*Ran out of letters?*/
775                     }
776                     else /*We are in trouble, there is not enough memory for an areax chunk*/
777                     {
778                         taxp->a_addr = addr;
779                         addr += taxp->a_size;
780                                     size += taxp->a_size;
781                         tap->a_unaloc+=taxp->a_size;
782                         fprintf(stderr, ErrMsg, taxp->a_size, taxp->a_size>1?"s":"", tap->a_id);
783                         lkerr++;
784                     }
785                }
786                            taxp = taxp->a_axp;
787                         }
788             else if(fchar=='B')
789             {
790                 if(taxp->a_size!=0)
791                 {
792                     for(j=0x20+taxp->a_addr; j<((int)(0x20+taxp->a_addr+taxp->a_size)); j++)
793                         idatamap[j]=fchar;
794                 }
795
796                         taxp->a_addr = addr;
797                             addr += taxp->a_size;
798                             size += taxp->a_size;
799                             taxp = taxp->a_axp;
800             }
801             else /*For concatenated BIT, CODE, and XRAM areax's*/
802             {
803                         taxp->a_addr = addr;
804                             addr += taxp->a_size;
805                             size += taxp->a_size;
806                             taxp = taxp->a_axp;
807             }
808                 }
809         }
810         tap->a_size = size;
811
812         if ((tap->a_flag&A_PAG) && (size > 256))
813         {
814             fprintf(stderr,
815             "\n?ASlink-Warning-Paged Area %8s Length Error\n", tap->a_id);
816             lkerr++;
817         }
818 }