struct / union in initializer, RFE #901.
[sdcc.git] / sdcc / sdas / linksrc / lkarea.c
blob77e6f848e55ff9f98a1fdb52a7552a9af95e0f37
1 /* lkarea.c */
3 /*
4 * Copyright (C) 1989-2009 Alan R. Baldwin
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 * Alan R. Baldwin
21 * 721 Berkeley St.
22 * Kent, Ohio 44240
26 * 02-Apr-98 JLH: add code to link 8051 data spaces
29 #include "aslink.h"
31 /*)Module lkarea.c
33 * The module lkarea.c contains the functions which
34 * create and link together all area definitions read
35 * from the .rel file(s).
37 * lkarea.c contains the following functions:
38 * VOID lnkarea()
39 * VOID lnksect()
40 * VOID lkparea()
41 * VOID newarea()
42 * VOID setarea()
44 * lkarea.c contains no global variables.
47 /*)Function VOID newarea()
49 * The function newarea() creates and/or modifies area
50 * and areax structures for each A directive read from
51 * the .rel file(s). The function lkparea() is called
52 * to find the area structure associated with this name.
53 * If the area does not yet exist then a new area
54 * structure is created and linked to any existing
55 * linked area structures. The area flags are copied
56 * into the area flag variable. For each occurence of
57 * an A directive an areax structure is created and
58 * linked to the areax structures associated with this
59 * area. The size of this area section is placed into
60 * the areax structure. The flag value for all subsequent
61 * area definitions for the same area are compared and
62 * flagged as an error if they are not identical.
63 * The areax structure created for every occurence of
64 * an A directive is loaded with a pointer to the base
65 * area structure and a pointer to the associated
66 * head structure. And finally, a pointer to this
67 * areax structure is loaded into the list of areax
68 * structures in the head structure. Refer to lkdata.c
69 * for details of the structures and their linkage.
71 * local variables:
72 * areax **halp pointer to an array of pointers
73 * a_uint i value
74 * char id[] id string
75 * int k counter, loop variable
76 * int narea number of areas in this head structure
77 * areax * taxp pointer to an areax structure
78 * to areax structures
80 * global variables:
81 * area *ap Pointer to the current
82 * area structure
83 * areax *axp Pointer to the current
84 * areax structure
85 * head *hp Pointer to the current
86 * head structure
87 * int lkerr error flag
89 * functions called:
90 * a_uint eval() lkeval.c
91 * VOID exit() c_library
92 * int fprintf() c_library
93 * VOID getid() lklex.c
94 * VOID lkparea() lkarea.c
95 * VOID skip() lklex.c
97 * side effects:
98 * The area and areax structures are created and
99 * linked with the appropriate head structures.
100 * Failure to allocate area or areax structure
101 * space will terminate the linker. Other internal
102 * errors most likely caused by corrupted .rel
103 * files will also terminate the linker.
107 * Create an area entry.
109 * A xxxxxx size nnnn flags mm bank n
110 * | | | |
111 * | | | `-- ap->a_bank
112 * | | `---------- ap->a_flag
113 * | `--------------------- axp->a_size
114 * `--------------------------------- ap->a_id
117 VOID
118 newarea(void)
120 a_uint i;
121 int k, narea;
122 struct areax *taxp;
123 struct areax **halp;
124 char id[NCPS];
126 if (headp == NULL) {
127 fprintf(stderr, "No header defined\n");
128 lkexit(ER_FATAL);
131 * Create Area entry
133 getid(id, -1);
134 lkparea(id);
136 * Evaluate area size
138 skip(-1);
139 axp->a_size = eval();
141 * Evaluate flags
143 skip(-1);
144 i = 0;
145 taxp = ap->a_axp;
146 while (taxp->a_axp) {
147 ++i;
148 taxp = taxp->a_axp;
150 if (i == 0) {
151 ap->a_flag = eval();
152 } else {
153 i = eval();
154 if ((!is_sdld() || TARGET_IS_Z80 || TARGET_IS_Z180 || TARGET_IS_GB) &&
155 i && (ap->a_flag != i)) {
156 fprintf(stderr, "Conflicting flags in area %8s\n", id);
157 lkerr++;
160 if (is_sdld() && !(TARGET_IS_Z80 || TARGET_IS_Z180 || TARGET_IS_GB)) {
162 * Evaluate area address
164 skip(-1);
165 axp->a_addr = eval();
168 * Place pointer in header area list
170 narea = hp->h_narea;
171 halp = hp->a_list;
172 for (k=0; k < narea ;++k) {
173 if (halp[k] == NULL) {
174 halp[k] = taxp;
175 return;
178 fprintf(stderr, "Header area list overflow\n");
179 lkexit(ER_FATAL);
182 /*)Function VOID lkparea(id)
184 * char * id pointer to the area name string
186 * The function lkparea() searches the linked area structures
187 * for a name match. If the name is not found then an area
188 * structure is created. An areax structure is created and
189 * appended to the areax structures linked to the area structure.
190 * The associated base area and head structure pointers are
191 * loaded into the areax structure.
193 * local variables:
194 * area * tap pointer to an area structure
195 * areax * taxp pointer to an areax structure
197 * global variables:
198 * area *ap Pointer to the current
199 * area structure
200 * area *areap The pointer to the first
201 * area structure of a linked list
202 * areax *axp Pointer to the current
203 * areax structure
205 * functions called:
206 * VOID * new() lksym()
207 * char * strsto() lksym.c
208 * int symeq() lksym.c
210 * side effects:
211 * Area and/or areax structures are created.
212 * Failure to allocate space for created structures
213 * will terminate the linker.
216 VOID
217 lkparea(char *id)
219 struct area *tap;
220 struct areax *taxp;
222 ap = areap;
223 axp = (struct areax *) new (sizeof(struct areax));
224 if (is_sdld() && !(TARGET_IS_Z80 || TARGET_IS_Z180 || TARGET_IS_GB))
225 axp->a_addr = -1; /* default: no address yet */
226 while (ap) {
227 if (symeq(id, ap->a_id, 1)) {
228 taxp = ap->a_axp;
229 while (taxp->a_axp)
230 taxp = taxp->a_axp;
231 taxp->a_axp = axp;
232 axp->a_bap = ap;
233 axp->a_bhp = hp;
234 return;
236 ap = ap->a_ap;
238 ap = (struct area *) new (sizeof(struct area));
239 if (areap == NULL) {
240 areap = ap;
241 } else {
242 tap = areap;
243 while (tap->a_ap)
244 tap = tap->a_ap;
245 tap->a_ap = ap;
247 ap->a_axp = axp;
248 axp->a_bap = ap;
249 axp->a_bhp = hp;
250 ap->a_id = strsto(id);
251 if (is_sdld() && !(TARGET_IS_Z80 || TARGET_IS_Z180 || TARGET_IS_GB))
252 ap->a_addr = 0;
255 /*)Function VOID lnkarea()
257 * The function lnkarea() resolves all area addresses.
258 * The function evaluates each area structure (and all
259 * the associated areax structures) in sequence. The
260 * linking process supports four (4) possible area types:
262 * ABS/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.
269 * ABS/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.
275 * NOTE: Multiple absolute (ABS) areas are
276 * never concatenated with each other,
277 * thus absolute area A and absolute area
278 * B will overlay each other if they begin
279 * at the same location (the default is
280 * always address 0 for absolute areas).
282 * REL/OVR - All sections (each individual areax
283 * section) starts at the identical base
284 * area address overlaying all other
285 * areax sections for this area. The
286 * size of the area is largest of the area
287 * sections.
289 * REL/CON - All sections (each individual areax
290 * section) are concatenated with the
291 * first section starting at the base
292 * area address. The size of the area
293 * is the sum of the section sizes.
295 * NOTE: Relocatable (REL) areas are always concatenated
296 * with each other, thus relocatable area B
297 * (defined after area A) will follow
298 * relocatable area A independent of the
299 * starting address of area A. Within a
300 * specific area each areax section may be
301 * overlayed or concatenated with other
302 * areax sections.
305 * If a base address for an area is specified then the
306 * area will start at that address. Any relocatable
307 * areas defined subsequently will be concatenated to the
308 * previous relocatable area if it does not have a base
309 * address specified.
311 * The names s_<areaname> and l_<areaname> are created to
312 * define the starting address and length of each area.
314 * local variables:
315 * a_uint rloc ;current relocation address
316 * char temp[] ;temporary string
317 * struct symbol *sp ;symbol structure
319 * global variables:
320 * area *ap Pointer to the current
321 * area structure
322 * area *areap The pointer to the first
323 * area structure of a linked list
325 * functions called:
326 * int fprintf() c_library
327 * VOID lnksect() lkarea.c
328 * symbol *lkpsym() lksysm.c
329 * char * strncpy() c_library
330 * int symeq() lksysm.c
332 * side effects:
333 * All area and areax addresses and sizes are
334 * determined and saved in their respective
335 * structures.
338 /* sdld6808 specific */
339 unsigned long codemap6808[2048];
340 /* end sdld6808 specific */
341 /* sdld specific */
342 VOID lnksect(struct area *tap);
343 /* end sdld specific */
345 * Resolve all bank/area addresses.
347 VOID
348 lnkarea(void)
350 /* sdld specific */
351 a_uint rloc[4] = { 0, 0, 0, 0 };
352 int locIndex;
353 /* end sdld specific */
354 /* sdld8051 & sdld6808 specific */
355 /*JCF: used to save the REG_BANK_[0-3] and SBIT_BYTES area pointers*/
356 struct area *ta[5];
357 int j;
358 /* end sdld8051 & sdld6808 specific */
359 /* sdld6800 specific */
360 a_uint gs_size = 0;
361 struct area *abs_ap = NULL;
362 struct area *gs0_ap = NULL;
363 /* end sdld6800 specific */
364 char temp[NCPS+2];
365 struct sym *sp;
367 if (TARGET_IS_6808) {
368 memset(codemap6808, 0, sizeof(codemap6808));
370 /* first sort all absolute areas to the front */
371 ap = areap;
372 /* no need to check first area, it's in front anyway */
373 while (ap && ap->a_ap) {
374 if (ap->a_ap->a_flag & A3_ABS)
375 {/* next area is absolute, move it to front,
376 reversed sequence is no problem for absolutes */
377 abs_ap = ap->a_ap;
378 ap->a_ap = abs_ap->a_ap;
379 abs_ap->a_ap = areap;
380 areap = abs_ap;
382 else {
383 ap = ap->a_ap;
387 /* next accumulate all GSINITx/GSFINAL area sizes
388 into GSINIT so they stay together */
389 ap = areap;
390 while (ap) {
391 if (!strncmp(ap->a_id, "GS", 2))
392 {/* GSxxxxx area */
393 if (ap->a_size == 0)
395 axp = ap->a_axp;
396 while (axp)
398 ap->a_size += axp->a_size;
399 axp = axp->a_axp;
402 gs_size += ap->a_size;
403 if (!strcmp(ap->a_id, "GSINIT0"))
404 {/* GSINIT0 area */
405 gs0_ap = ap;
408 ap = ap->a_ap;
410 if (gs0_ap)
411 gs0_ap->a_size = gs_size;
414 ap = areap;
415 while (ap) {
416 if(TARGET_IS_GB && ap->a_addr == 0) {
417 if(!strncmp(ap->a_id, "_CODE_", 6) && atoi(ap->a_id+6)!=0) {
418 // set sane default values for rom banking
419 // 0x4000 is correct for MBC1,2,3,5,7
420 ap->a_addr = (atoi(ap->a_id+6) << 16) + 0x4000;
422 if(!strncmp(ap->a_id, "_DATA_", 6)) {
423 // set sane default values for ram banking
424 ap->a_addr = (atoi(ap->a_id+6) << 16) + 0xA000;
427 if (ap->a_flag & A3_ABS) {
429 * Absolute sections
431 lnksect(ap);
432 } else {
433 /* sdld specific */
434 /* Determine memory space */
435 locIndex = 0;
436 if ((TARGET_IS_8051)) {
437 if (ap->a_flag & A_CODE) {
438 locIndex = 1;
440 if (ap->a_flag & A_XDATA) {
441 locIndex = 2;
443 if (ap->a_flag & A_BIT) {
444 locIndex = 3;
448 * Relocatable sections
450 if (!is_sdld() || TARGET_IS_Z80 || TARGET_IS_Z180 || TARGET_IS_GB) {
451 if (ap->a_addr == 0)
452 ap->a_addr = rloc[locIndex];
454 else if (ap->a_bset == 0) {
455 if ((TARGET_IS_6808 || TARGET_IS_STM8) && ap->a_flag & A_NOLOAD) {
456 locIndex = 2;
457 ap->a_addr = 0;
459 else {
460 ap->a_addr = rloc[locIndex];
462 ap->a_bset = 1;
464 lnksect(ap);
465 rloc[ locIndex ] = ap->a_addr + ap->a_size;
466 /* end sdld specific */
470 * Create symbols called:
471 * s_<areaname> the start address of the area
472 * l_<areaname> the length of the area
475 if (! symeq(ap->a_id, _abs_, 1)) {
476 strcpy(temp+2, ap->a_id);
477 *(temp+1) = '_';
479 *temp = 's';
480 sp = lkpsym(temp, 1);
481 sp->s_addr = ap->a_addr;
482 if (!is_sdld() || TARGET_IS_Z80 || TARGET_IS_Z180 || TARGET_IS_GB)
483 sp->s_axp = NULL;
484 sp->s_type |= S_DEF;
486 *temp = 'l';
487 sp = lkpsym(temp, 1);
488 sp->s_addr = ap->a_size;
489 sp->s_axp = NULL;
490 sp->s_type |= S_DEF;
493 if (is_sdld() && !(TARGET_IS_Z80 || TARGET_IS_Z180 || TARGET_IS_GB)) {
494 /*JCF: Since area BSEG is defined just before BSEG_BYTES, use the bit size of BSEG
495 to compute the byte size of BSEG_BYTES: */
496 if (!strcmp(ap->a_id, "BSEG")) {
497 if (TARGET_IS_8051)
498 ap->a_ap->a_axp->a_size += ((ap->a_addr + ap->a_size + 7)/8); /*Bits to bytes*/
499 else
500 ap->a_ap->a_axp->a_size=(ap->a_addr/8)+((ap->a_size+7)/8); /*Bits to bytes*/
502 else if (!strcmp(ap->a_id, "REG_BANK_0")) ta[0]=ap;
503 else if (!strcmp(ap->a_id, "REG_BANK_1")) ta[1]=ap;
504 else if (!strcmp(ap->a_id, "REG_BANK_2")) ta[2]=ap;
505 else if (!strcmp(ap->a_id, "REG_BANK_3")) ta[3]=ap;
506 else if (!strcmp(ap->a_id, "BSEG_BYTES"))
508 ta[4]=ap;
509 for(j=4; j>1; j--)
511 /*If upper register banks are not used roll back the relocation counter*/
512 if ( (ta[j]->a_size==0) && (ta[j-1]->a_size==0) )
514 rloc[0]-=8;
516 else break;
520 ap = ap->a_ap;
524 /* sdld specific */
525 static
526 a_uint find_empty_space(a_uint start, a_uint size, char *id, unsigned long *map, unsigned int map_size)
528 a_uint i, j, k;
529 unsigned long mask, b;
530 map_size /= sizeof(*map); /* Convert from bytes to number of elements */
532 while (1) {
533 a_uint a = start;
534 i = start >> 5;
535 j = (start + size) >> 5;
536 mask = -(1 << (start & 0x1F));
538 if (j > map_size) {
539 fprintf(stderr, "internal memory limit is exceeded for %s; memory size = 0x%06X, address = 0x%06X\n", id, map_size << 5, start + size - 1);
540 break;
542 else {
543 while (i < j) {
544 if (map[i] & mask) {
545 k = 32;
546 for (b=0x80000000; b!=0; b>>=1, k--) {
547 if (map[i] & b)
548 break;
550 start = a + k;
551 break;
553 i++;
554 mask = 0xFFFFFFFF;
555 a += 32;
557 if (start > a)
558 continue;
560 mask &= (1 << ((start + size) & 0x1F)) - 1;
561 if (i < map_size && map[i] & mask) {
562 k = 32;
563 for (b=0x80000000; b!=0; b>>=1, k--) {
564 if (map[i] & b)
565 break;
567 start = (a & ~0x1F) + k;
569 if (start <= a)
570 break;
573 return start;
576 static
577 a_uint allocate_space(a_uint start, a_uint size, char *id, unsigned long *map, unsigned int map_size)
579 a_uint i, j;
580 unsigned long mask;
581 a_uint a = start;
582 i = start >> 5;
583 j = (start + size) >> 5;
584 mask = -(1 << (start & 0x1F));
585 map_size /= sizeof(*map); /* Convert from bytes to number of elements */
587 if (j > map_size) {
588 fprintf(stderr, "internal memory limit is exceeded for %s; memory size = 0x%06X, address = 0x%06X\n", id, map_size << 5, start + size - 1);
590 else {
591 while (i < j) {
592 if (map[i] & mask) {
593 fprintf(stderr, "memory overlap near 0x%X for %s\n", a, id);
595 map[i++] |= mask;
596 mask = 0xFFFFFFFF;
597 a += 32;
599 mask &= (1 << ((start + size) & 0x1F)) - 1;
600 if (i < map_size && map[i] & mask) {
601 fprintf(stderr, "memory overlap near 0x%X for %s\n", a, id);
603 map[i] |= mask;
605 return start;
607 /* end sdld specific */
609 /*)Function VOID lnksect(tap)
611 * area * tap pointer to an area structure
613 * The function lnksect() is the function called by
614 * lnkarea() to resolve the areax addresses. Refer
615 * to the function lnkarea() for more detail. Pageing
616 * boundary and length errors will be reported by this
617 * function.
619 * local variables:
620 * a_uint size size of area
621 * a_uint addr address of area
622 * areax * taxp pointer to an areax structure
624 * global variables:
625 * int lkerr error flag
627 * functions called:
628 * none
630 * side effects:
631 * All area and areax addresses and sizes are determined
632 * and linked into the structures.
635 VOID
636 lnksect(struct area *tap)
638 a_uint size, addr;
639 struct areax *taxp;
641 size = 0;
642 addr = tap->a_addr;
643 taxp = tap->a_axp;
644 if (tap->a_flag & A3_OVR) {
646 * Overlayed sections
648 while (taxp) {
649 taxp->a_addr = addr;
650 if (taxp->a_size > size)
651 size = taxp->a_size;
652 taxp = taxp->a_axp;
654 } else if (TARGET_IS_6808 && tap->a_flag & A3_ABS) {
656 * Absolute sections
658 while (taxp) {
659 allocate_space(taxp->a_addr, taxp->a_size, tap->a_id, codemap6808, sizeof (codemap6808));
660 taxp->a_addr = 0; /* reset to zero so relative addresses become absolute */
661 size += taxp->a_size;
662 taxp = taxp->a_axp;
664 } else {
666 * Concatenated sections
668 if (TARGET_IS_6808 && tap->a_size && !(ap->a_flag & A_NOLOAD)) {
669 addr = find_empty_space(addr, tap->a_size, tap->a_id, codemap6808, sizeof (codemap6808));
671 while (taxp) {
672 /* find next unused address now */
673 if (TARGET_IS_6808 && taxp->a_size && !(ap->a_flag & A_NOLOAD)) {
674 addr = find_empty_space(addr, taxp->a_size, tap->a_id, codemap6808, sizeof (codemap6808));
675 allocate_space(addr, taxp->a_size, tap->a_id, codemap6808, sizeof (codemap6808));
677 taxp->a_addr = addr;
678 addr += taxp->a_size;
679 size += taxp->a_size;
680 taxp = taxp->a_axp;
683 tap->a_size = size;
684 tap->a_addr = tap->a_axp->a_addr;
685 for (taxp = tap->a_axp; taxp && !taxp->a_size; taxp = taxp->a_axp)
688 if (taxp)
690 tap->a_addr = taxp->a_addr;
693 if ((tap->a_flag & A3_PAG) && (size > 256)) {
694 fprintf(stderr,
695 "\n?ASlink-Warning-Paged Area %s Length Error\n",
696 tap->a_id);
697 lkerr++;
699 if (TARGET_IS_8051 &&
700 (tap->a_flag & A3_PAG) && (tap->a_size) &&
701 ((tap->a_addr & 0xFFFFFF00) != ((addr-1) & 0xFFFFFF00)))
703 fprintf(stderr,
704 "\n?ASlink-Warning-Paged Area %s Boundary Error\n",
705 tap->a_id);
706 lkerr++;
711 /*)Function VOID setarea()
713 * The function setarea() scans the base address lines in the
714 * basep structure, evaluates the arguments, and sets the beginning
715 * address of the specified areas.
717 * local variables:
718 * a_uint v expression value
719 * char id[] base id string
721 * global variables:
722 * area *ap Pointer to the current
723 * area structure
724 * area *areap The pointer to the first
725 * area structure of a linked list
726 * base *basep The pointer to the first
727 * base structure
728 * base *bsp Pointer to the current
729 * base structure
730 * char *ip pointer into the REL file
731 * text line in ib[]
732 * int lkerr error flag
734 * functions called:
735 * a_uint expr() lkeval.c
736 * int fprintf() c_library
737 * VOID getid() lklex.c
738 * int getnb() lklex.c
739 * int symeq() lksym.c
741 * side effects:
742 * The base address of an area is set.
745 VOID
746 setarea(void)
748 a_uint v;
749 char id[NCPS];
751 bsp = basep;
752 while (bsp) {
753 ip = bsp->b_strp;
754 getid(id, -1);
755 if (getnb() == '=') {
756 v = expr(0);
757 for (ap = areap; ap != NULL; ap = ap->a_ap) {
758 if (symeq(id, ap->a_id, 1))
759 break;
761 if (ap == NULL) {
762 fprintf(stderr,
763 "ASlink-Warning-No definition of area %s\n", id);
764 lkerr++;
765 } else {
766 ap->a_addr = v;
767 ap->a_bset = 1;
769 } else {
770 fprintf(stderr, "ASlink-Warning-No '=' in base expression");
771 lkerr++;
773 bsp = bsp->b_base;
779 /* sdld specific */
780 a_uint lnksect2 (struct area *tap, int locIndex);
781 unsigned long codemap8051[524288];
782 unsigned long xdatamap[131216];
783 struct area *dseg_ap = NULL;
784 a_uint dram_start = 0;
785 a_uint iram_start = 0;
787 /*Modified version of the functions for packing variables in internal data memory*/
788 VOID lnkarea2 (void)
790 a_uint rloc[4]={0, 0, 0, 0};
791 a_uint gs_size = 0;
792 int locIndex;
793 char temp[NCPS+2];
794 struct sym *sp;
795 int j;
796 struct area *bseg_ap = NULL;
797 struct area *abs_ap = NULL;
798 struct area *gs0_ap = NULL;
799 struct sym *sp_dseg_s=NULL, *sp_dseg_l=NULL;
801 memset(idatamap, ' ', 256);
802 memset(codemap8051, 0, sizeof(codemap8051));
803 memset(xdatamap, 0, sizeof(xdatamap));
805 /* first sort all absolute areas to the front */
806 ap = areap;
807 /* no need to check first area, it's in front anyway */
808 while (ap && ap->a_ap)
810 if (ap->a_ap->a_flag & A3_ABS)
811 {/* next area is absolute, move it to front,
812 reversed sequence is no problem for absolutes */
813 abs_ap = ap->a_ap;
814 ap->a_ap = abs_ap->a_ap;
815 abs_ap->a_ap = areap;
816 areap = abs_ap;
818 else
820 ap = ap->a_ap;
824 /* next accumulate all GSINITx/GSFINAL area sizes
825 into GSINIT so they stay together */
826 ap = areap;
827 abs_ap = areap;
828 while (ap)
830 if (ap->a_flag & A3_ABS)
832 abs_ap = ap; /* Remember the last abs area */
834 if (!strncmp(ap->a_id, "GS", 2))
835 {/* GSxxxxx area */
836 if (ap->a_size == 0)
838 axp = ap->a_axp;
839 while (axp)
841 ap->a_size += axp->a_size;
842 axp = axp->a_axp;
845 gs_size += ap->a_size;
846 if (!strcmp(ap->a_id, "GSINIT0"))
847 {/* GSINIT0 area */
848 gs0_ap = ap;
851 /*Since area BSEG is defined just before BSEG_BYTES, use the bit size of BSEG
852 to compute the byte size of BSEG_BYTES: */
853 else if (!strcmp(ap->a_id, "BSEG"))
855 bseg_ap = ap->a_ap; //BSEG_BYTES
856 for (axp=ap->a_axp; axp; axp=axp->a_axp)
857 ap->a_size += axp->a_size;
858 bseg_ap->a_axp->a_size = ((ap->a_addr + ap->a_size + 7)/8); /*Bits to bytes*/
859 ap->a_ap = bseg_ap->a_ap; //removed BSEG_BYTES from list
860 bseg_ap->a_ap = abs_ap->a_ap;
861 abs_ap->a_ap = bseg_ap; //inserted BSEG_BYTES after abs
862 bseg_ap = ap; //BSEG
864 else if (!strcmp(ap->a_id, "DSEG"))
866 dseg_ap = ap; /*Need it later*/
867 dram_start = ap->a_addr;
869 else if (!strcmp(ap->a_id, "ISEG"))
871 iram_start = ap->a_addr;
873 ap = ap->a_ap;
875 if (gs0_ap)
876 gs0_ap->a_size = gs_size;
878 ap = areap;
879 while (ap)
881 /* Determine memory space */
882 if (ap->a_flag & A_CODE) locIndex = 1;
883 else if (ap->a_flag & A_XDATA) locIndex = 2;
884 else if (ap->a_flag & A_BIT) locIndex = 3;
885 else locIndex = 0;
887 if (ap->a_flag & A3_ABS) /* Absolute sections */
889 lnksect2(ap, locIndex);
891 else /* Relocatable sections */
893 if (ap->a_bset == 0)
895 ap->a_addr = rloc[locIndex];
896 ap->a_bset = 1;
899 rloc[locIndex] = lnksect2(ap, locIndex);
902 if (!strcmp(ap->a_id, "BSEG_BYTES") && (ap->a_axp->a_addr >= 0x20))
904 bseg_ap->a_addr += (ap->a_axp->a_addr - 0x20) * 8; /*Bytes to bits*/
907 * Create symbols called:
908 * s_<areaname> the start address of the area
909 * l_<areaname> the length of the area
912 if (! symeq(ap->a_id, _abs_, 1))
914 strcpy(temp+2,ap->a_id);
915 *(temp+1) = '_';
917 *temp = 's';
918 sp = lkpsym(temp, 1);
919 sp->s_addr = ap->a_addr;
920 sp->s_type |= S_DEF;
921 if (!strcmp(ap->a_id, "DSEG")) sp_dseg_s=sp;
923 *temp = 'l';
924 sp = lkpsym(temp, 1);
925 sp->s_addr = ap->a_size;
926 sp->s_axp = NULL;
927 sp->s_type |= S_DEF;
928 if (!strcmp(ap->a_id, "DSEG")) sp_dseg_l=sp;
931 ap = ap->a_ap;
934 /*Compute the size of DSEG*/
935 if(dseg_ap!=NULL)
937 dseg_ap->a_addr=0;
938 dseg_ap->a_size=0;
939 for(j=0; j<0x80; j++) if(idatamap[j]!=' ') dseg_ap->a_size++;
941 if(sp_dseg_s!=NULL) sp_dseg_s->s_addr=0;
942 if(sp_dseg_l!=NULL) sp_dseg_l->s_addr=dseg_ap->a_size;
945 a_uint lnksect2 (struct area *tap, int locIndex)
947 a_uint size, addr;
948 struct areax *taxp;
949 int j, k, ramlimit, ramstart;
950 char fchar=' ', dchar='a';
951 char ErrMsg[]="?ASlink-Error-Could not get %d consecutive byte%s"
952 " in internal RAM for area %s.\n";
954 tap->a_unaloc=0;
956 /*Notice that only ISEG and SSEG can be in the indirectly addressable internal RAM*/
957 if( (!strcmp(tap->a_id, "ISEG")) || (!strcmp(tap->a_id, "SSEG")) )
959 ramstart = iram_start;
961 if ((iram_size <= 0) || (ramstart + iram_size > 0x100))
962 ramlimit = 0x100;
963 else
964 ramlimit = ramstart + iram_size;
966 else
968 ramstart = dram_start;
970 if ((iram_size <= 0) || (ramstart + iram_size > 0x80))
971 ramlimit = 0x80;
972 else
973 ramlimit = ramstart + iram_size;
976 size = 0;
977 addr = tap->a_addr;
978 taxp = tap->a_axp;
980 /*Use a letter to identify each area in the internal RAM layout map*/
981 if (locIndex==0)
983 /**/ if(!strcmp(tap->a_id, "DSEG"))
984 fchar='D'; /*It will be converted to letters 'a' to 'z' later for each areax*/
985 else if(!strcmp(tap->a_id, "ISEG"))
986 fchar='I';
987 else if(!strcmp(tap->a_id, "SSEG"))
988 fchar='S';
989 else if(!strcmp(tap->a_id, "OSEG"))
990 fchar='Q';
991 else if(!strcmp(tap->a_id, "REG_BANK_0"))
992 fchar='0';
993 else if(!strcmp(tap->a_id, "REG_BANK_1"))
994 fchar='1';
995 else if(!strcmp(tap->a_id, "REG_BANK_2"))
996 fchar='2';
997 else if(!strcmp(tap->a_id, "REG_BANK_3"))
998 fchar='3';
999 else if(!strcmp(tap->a_id, "BSEG_BYTES"))
1000 fchar='B';
1001 else if(!strcmp(tap->a_id, "BIT_BANK"))
1002 fchar='T';
1003 else
1004 fchar=' ';/*???*/
1006 else if (locIndex == 1)
1008 /**/ if(!strcmp(tap->a_id, "GSINIT"))
1009 fchar='G';
1011 else if (locIndex == 2)
1013 /**/ if(!strcmp(tap->a_id, "XSTK"))
1014 fchar='K';
1017 if (tap->a_flag & A3_OVR) /* Overlayed sections */
1019 while (taxp)
1021 if(taxp->a_size == 0)
1023 taxp = taxp->a_axp;
1024 continue;
1027 if ( (fchar=='0')||(fchar=='1')||(fchar=='2')||(fchar=='3') ) /*Reg banks*/
1029 addr=(fchar-'0')*8;
1030 taxp->a_addr=addr;
1031 size=taxp->a_size;
1032 for(j=addr; (j<(int)(addr+size)) && (j<ramlimit); j++)
1033 idatamap[j]=fchar;
1035 else if( (fchar=='S') || (fchar=='Q') ) /*Overlay and stack in internal RAM*/
1037 /*Find the size of the space currently used for this areax overlay*/
1038 for(j=ramstart, size=0; j<ramlimit; j++)
1039 if(idatamap[j]==fchar) size++;
1041 if( (fchar=='S') && (stacksize==0) )
1043 /*Search for the largest space available and use it for stack*/
1044 for(j=ramstart, k=0, taxp->a_size=0; j<ramlimit; j++)
1046 if(idatamap[j]==' ')
1048 if((++k)>(int)taxp->a_size)
1049 taxp->a_size=k;
1051 else
1053 k=0;
1056 stacksize=taxp->a_size;
1059 /*If more space required, release the previously allocated areax in
1060 internal RAM and search for a bigger one*/
1061 if((int)taxp->a_size>size)
1063 size=(int)taxp->a_size;
1065 for(j=ramstart; j<ramlimit; j++)
1066 if(idatamap[j]==fchar) idatamap[j]=' ';
1068 /*Search for a space large enough in data memory for this overlay areax*/
1069 for(j=ramstart, k=0; j<ramlimit; j++)
1071 if(idatamap[j]==' ')
1072 k++;
1073 else
1074 k=0;
1075 if(k==(int)taxp->a_size)
1076 break;
1079 /*Mark the memory used for overlay*/
1080 if(k==(int)taxp->a_size)
1082 addr = j-k+1;
1083 for(j=addr; (j<(int)(addr+size)); j++)
1084 idatamap[j]=fchar;
1086 else /*Couldn't find a chunk big enough: report the problem.*/
1088 tap->a_unaloc=taxp->a_size;
1089 fprintf(stderr, ErrMsg, taxp->a_size, taxp->a_size>1?"s":"", tap->a_id);
1090 lkerr++;
1093 /* avoid redundant processing SSEG */
1094 if (fchar == 'S')
1095 break;
1098 else if (fchar=='T') /*Bit addressable bytes in internal RAM*/
1100 /*Find the size of the space currently used for this areax overlay*/
1101 // for(j=0x20, size=0; j<0x30; j++)
1102 // if(idatamap[j]==fchar) size++;
1104 /*If more space required, release the previously allocated areax in
1105 internal RAM and search for a bigger one*/
1106 if((int)taxp->a_size>size)
1108 size=(int)taxp->a_size;
1110 for(j=0x20; j<0x30; j++)
1111 if(idatamap[j]==fchar) idatamap[j]=' ';
1113 /*Search for a space large enough in data memory for this overlay areax*/
1114 for(j=0x20, k=0; j<0x30; j++)
1116 if(idatamap[j]==' ')
1117 k++;
1118 else
1119 k=0;
1120 if(k==(int)taxp->a_size)
1121 break;
1124 /*Mark the memory used for overlay*/
1125 if(k==(int)size)
1127 addr = j-k+1;
1128 for(j=addr; (j<(int)(addr+size)); j++)
1129 idatamap[j]=fchar;
1131 else /*Couldn't find a chunk big enough: report the problem.*/
1133 tap->a_unaloc=taxp->a_size;
1134 fprintf(stderr, ErrMsg, taxp->a_size, taxp->a_size>1?"s":"", tap->a_id);
1135 lkerr++;
1139 else /*Overlay areas not in internal ram*/
1141 taxp->a_addr = addr;
1142 if (taxp->a_size > size) size = taxp->a_size;
1144 taxp = taxp->a_axp;
1146 /*Now set all overlayed areax to the same start address*/
1147 taxp = tap->a_axp;
1148 while (taxp)
1150 taxp->a_addr = addr;
1151 taxp = taxp->a_axp;
1154 else if (tap->a_flag & A3_ABS) /* Absolute sections */
1156 while (taxp)
1158 if (locIndex == 0)
1160 for (j=taxp->a_addr; (j<(int)(taxp->a_addr+taxp->a_size)) && (j<256); j++)
1162 if (idatamap[j] == ' ')
1163 idatamap[j] = 'A';
1164 else
1165 fprintf(stderr, "memory overlap at 0x%X for %s\n", j, tap->a_id);
1168 else if (locIndex == 1)
1170 allocate_space(taxp->a_addr, taxp->a_size, tap->a_id, codemap8051, sizeof (codemap8051));
1172 else if (locIndex == 2)
1174 allocate_space(taxp->a_addr, taxp->a_size, tap->a_id, xdatamap, sizeof (xdatamap));
1176 taxp->a_addr = 0; /* reset to zero so relative addresses become absolute */
1177 size += taxp->a_size;
1178 taxp = taxp->a_axp;
1181 else /* Concatenated sections */
1183 if ((locIndex == 1) && tap->a_size)
1185 addr = find_empty_space(addr, tap->a_size, tap->a_id, codemap8051, sizeof (codemap8051));
1187 if ((locIndex == 2) && tap->a_size)
1189 addr = find_empty_space(addr, tap->a_size, tap->a_id, xdatamap, sizeof (xdatamap));
1191 while (taxp)
1193 if (taxp->a_size)
1195 if( (fchar=='D') || (fchar=='I') )
1197 /*Search for a space large enough in internal RAM for this areax*/
1198 for(j=ramstart, k=0; j<ramlimit; j++)
1200 if(idatamap[j]==' ')
1201 k++;
1202 else
1203 k=0;
1204 if(k==(int)taxp->a_size)
1205 break;
1208 if(k==(int)taxp->a_size)
1210 taxp->a_addr = j-k+1;
1212 size += taxp->a_size;
1214 for(j=taxp->a_addr; (j<(int)(taxp->a_addr+taxp->a_size)) && (j<ramlimit); j++)
1215 idatamap[j]=(fchar=='D')?dchar:fchar;
1216 if((taxp->a_size>0)&&(fchar=='D'))dchar++;
1217 if((dchar<'a')||(dchar>'z')) dchar='D'; /*Ran out of letters?*/
1219 else /*We are in trouble, there is not enough memory for an areax chunk*/
1221 taxp->a_addr = addr;
1222 addr += taxp->a_size;
1223 size += taxp->a_size;
1224 tap->a_unaloc+=taxp->a_size;
1225 fprintf(stderr, ErrMsg, taxp->a_size, taxp->a_size>1?"s":"", tap->a_id);
1226 lkerr++;
1229 else if (fchar=='B')
1231 /*Search for a space large enough in data memory for this areax*/
1232 for(j=0x20, k=0; j<0x30; j++)
1234 if(idatamap[j]==' ')
1235 k++;
1236 else
1237 k=0;
1238 if(k==(int)taxp->a_size) break;
1241 /*Mark the memory used*/
1242 if(k==(int)taxp->a_size)
1244 taxp->a_addr = j-k+1;
1245 for(j=taxp->a_addr; (j<(int)(taxp->a_addr+taxp->a_size)) && (j<0x30); j++)
1246 idatamap[j]=fchar;
1248 else /*Couldn't find a chunk big enough: report the problem.*/
1250 tap->a_unaloc=taxp->a_size;
1251 fprintf(stderr, ErrMsg, taxp->a_size, taxp->a_size>1?"s":"", tap->a_id);
1252 lkerr++;
1254 size += taxp->a_size;
1256 else /*For concatenated BIT, CODE, and XRAM areax's*/
1258 //expand external stack
1259 if((fchar=='K') && (taxp->a_size == 1))
1261 taxp->a_size = 256-(addr & 0xFF);
1263 //find next unused address now
1264 if (locIndex == 1)
1266 addr = find_empty_space(addr, taxp->a_size, tap->a_id, codemap8051, sizeof (codemap8051));
1267 allocate_space(addr, taxp->a_size, tap->a_id, codemap8051, sizeof (codemap8051));
1269 if (locIndex == 2)
1271 addr = find_empty_space(addr, taxp->a_size, tap->a_id, xdatamap, sizeof (xdatamap));
1272 allocate_space(addr, taxp->a_size, tap->a_id, xdatamap, sizeof (xdatamap));
1274 taxp->a_addr = addr;
1275 addr += taxp->a_size;
1276 size += taxp->a_size;
1279 else
1281 taxp->a_addr = addr;
1283 taxp = taxp->a_axp;
1286 tap->a_size = size;
1287 tap->a_addr = tap->a_axp->a_addr;
1288 for (taxp = tap->a_axp; taxp && !taxp->a_size; taxp = taxp->a_axp)
1291 if (taxp)
1293 tap->a_addr = taxp->a_addr;
1296 if ((tap->a_flag & A3_PAG) && (size > 256))
1298 fprintf(stderr,
1299 "\n?ASlink-Warning-Paged Area %s Length Error\n",
1300 tap->a_id);
1301 lkerr++;
1303 if ((tap->a_flag & A3_PAG) && (tap->a_size) &&
1304 ((tap->a_addr & 0xFFFFFF00) != ((addr-1) & 0xFFFFFF00)))
1306 fprintf(stderr,
1307 "\n?ASlink-Warning-Paged Area %s Boundary Error\n",
1308 tap->a_id);
1309 lkerr++;
1311 return addr;
1313 /* end sdld specific */