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/>.
26 * 02-Apr-98 JLH: add code to link 8051 data spaces
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:
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.
72 * areax **halp pointer to an array of pointers
75 * int k counter, loop variable
76 * int narea number of areas in this head structure
77 * areax * taxp pointer to an areax structure
81 * area *ap Pointer to the current
83 * areax *axp Pointer to the current
85 * head *hp Pointer to the current
87 * int lkerr error flag
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
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
111 * | | | `-- ap->a_bank
112 * | | `---------- ap->a_flag
113 * | `--------------------- axp->a_size
114 * `--------------------------------- ap->a_id
127 fprintf(stderr
, "No header defined\n");
139 axp
->a_size
= eval();
146 while (taxp
->a_axp
) {
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
);
160 if (is_sdld() && !(TARGET_IS_Z80
|| TARGET_IS_Z180
|| TARGET_IS_GB
)) {
162 * Evaluate area address
165 axp
->a_addr
= eval();
168 * Place pointer in header area list
172 for (k
=0; k
< narea
;++k
) {
173 if (halp
[k
] == NULL
) {
178 fprintf(stderr
, "Header area list overflow\n");
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.
194 * area * tap pointer to an area structure
195 * areax * taxp pointer to an areax structure
198 * area *ap Pointer to the current
200 * area *areap The pointer to the first
201 * area structure of a linked list
202 * areax *axp Pointer to the current
206 * VOID * new() lksym()
207 * char * strsto() lksym.c
208 * int symeq() lksym.c
211 * Area and/or areax structures are created.
212 * Failure to allocate space for created structures
213 * will terminate the linker.
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 */
227 if (symeq(id
, ap
->a_id
, 1)) {
238 ap
= (struct area
*) new (sizeof(struct area
));
250 ap
->a_id
= strsto(id
);
251 if (is_sdld() && !(TARGET_IS_Z80
|| TARGET_IS_Z180
|| TARGET_IS_GB
))
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
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
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
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
311 * The names s_<areaname> and l_<areaname> are created to
312 * define the starting address and length of each area.
315 * a_uint rloc ;current relocation address
316 * char temp[] ;temporary string
317 * struct symbol *sp ;symbol structure
320 * area *ap Pointer to the current
322 * area *areap The pointer to the first
323 * area structure of a linked list
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
333 * All area and areax addresses and sizes are
334 * determined and saved in their respective
338 /* sdld6808 specific */
339 unsigned long codemap6808
[2048];
340 /* end sdld6808 specific */
342 VOID
lnksect(struct area
*tap
);
343 /* end sdld specific */
345 * Resolve all bank/area addresses.
351 a_uint rloc
[4] = { 0, 0, 0, 0 };
353 /* end sdld specific */
354 /* sdld8051 & sdld6808 specific */
355 /*JCF: used to save the REG_BANK_[0-3] and SBIT_BYTES area pointers*/
358 /* end sdld8051 & sdld6808 specific */
359 /* sdld6800 specific */
361 struct area
*abs_ap
= NULL
;
362 struct area
*gs0_ap
= NULL
;
363 /* end sdld6800 specific */
367 if (TARGET_IS_6808
) {
368 memset(codemap6808
, 0, sizeof(codemap6808
));
370 /* first sort all absolute areas to the front */
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 */
378 ap
->a_ap
= abs_ap
->a_ap
;
379 abs_ap
->a_ap
= areap
;
387 /* next accumulate all GSINITx/GSFINAL area sizes
388 into GSINIT so they stay together */
391 if (!strncmp(ap
->a_id
, "GS", 2))
398 ap
->a_size
+= axp
->a_size
;
402 gs_size
+= ap
->a_size
;
403 if (!strcmp(ap
->a_id
, "GSINIT0"))
411 gs0_ap
->a_size
= gs_size
;
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
) {
434 /* Determine memory space */
436 if ((TARGET_IS_8051
)) {
437 if (ap
->a_flag
& A_CODE
) {
440 if (ap
->a_flag
& A_XDATA
) {
443 if (ap
->a_flag
& A_BIT
) {
448 * Relocatable sections
450 if (!is_sdld() || TARGET_IS_Z80
|| TARGET_IS_Z180
|| TARGET_IS_GB
) {
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
) {
460 ap
->a_addr
= rloc
[locIndex
];
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
);
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
)
487 sp
= lkpsym(temp
, 1);
488 sp
->s_addr
= ap
->a_size
;
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")) {
498 ap
->a_ap
->a_axp
->a_size
+= ((ap
->a_addr
+ ap
->a_size
+ 7)/8); /*Bits to bytes*/
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"))
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) )
526 a_uint
find_empty_space(a_uint start
, a_uint size
, char *id
, unsigned long *map
, unsigned int map_size
)
529 unsigned long mask
, b
;
530 map_size
/= sizeof(*map
); /* Convert from bytes to number of elements */
535 j
= (start
+ size
) >> 5;
536 mask
= -(1 << (start
& 0x1F));
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);
546 for (b
=0x80000000; b
!=0; b
>>=1, k
--) {
560 mask
&= (1 << ((start
+ size
) & 0x1F)) - 1;
561 if (i
< map_size
&& map
[i
] & mask
) {
563 for (b
=0x80000000; b
!=0; b
>>=1, k
--) {
567 start
= (a
& ~0x1F) + k
;
577 a_uint
allocate_space(a_uint start
, a_uint size
, char *id
, unsigned long *map
, unsigned int map_size
)
583 j
= (start
+ size
) >> 5;
584 mask
= -(1 << (start
& 0x1F));
585 map_size
/= sizeof(*map
); /* Convert from bytes to number of elements */
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);
593 fprintf(stderr
, "memory overlap near 0x%X for %s\n", a
, id
);
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
);
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
620 * a_uint size size of area
621 * a_uint addr address of area
622 * areax * taxp pointer to an areax structure
625 * int lkerr error flag
631 * All area and areax addresses and sizes are determined
632 * and linked into the structures.
636 lnksect(struct area
*tap
)
644 if (tap
->a_flag
& A3_OVR
) {
650 if (taxp
->a_size
> size
)
654 } else if (TARGET_IS_6808
&& tap
->a_flag
& A3_ABS
) {
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
;
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
));
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
));
678 addr
+= taxp
->a_size
;
679 size
+= taxp
->a_size
;
684 tap
->a_addr
= tap
->a_axp
->a_addr
;
685 for (taxp
= tap
->a_axp
; taxp
&& !taxp
->a_size
; taxp
= taxp
->a_axp
)
690 tap
->a_addr
= taxp
->a_addr
;
693 if ((tap
->a_flag
& A3_PAG
) && (size
> 256)) {
695 "\n?ASlink-Warning-Paged Area %s Length Error\n",
699 if (TARGET_IS_8051
&&
700 (tap
->a_flag
& A3_PAG
) && (tap
->a_size
) &&
701 ((tap
->a_addr
& 0xFFFFFF00) != ((addr
-1) & 0xFFFFFF00)))
704 "\n?ASlink-Warning-Paged Area %s Boundary Error\n",
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.
718 * a_uint v expression value
719 * char id[] base id string
722 * area *ap Pointer to the current
724 * area *areap The pointer to the first
725 * area structure of a linked list
726 * base *basep The pointer to the first
728 * base *bsp Pointer to the current
730 * char *ip pointer into the REL file
732 * int lkerr error flag
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
742 * The base address of an area is set.
755 if (getnb() == '=') {
757 for (ap
= areap
; ap
!= NULL
; ap
= ap
->a_ap
) {
758 if (symeq(id
, ap
->a_id
, 1))
763 "ASlink-Warning-No definition of area %s\n", id
);
770 fprintf(stderr
, "ASlink-Warning-No '=' in base expression");
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*/
790 a_uint rloc
[4]={0, 0, 0, 0};
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 */
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 */
814 ap
->a_ap
= abs_ap
->a_ap
;
815 abs_ap
->a_ap
= areap
;
824 /* next accumulate all GSINITx/GSFINAL area sizes
825 into GSINIT so they stay together */
830 if (ap
->a_flag
& A3_ABS
)
832 abs_ap
= ap
; /* Remember the last abs area */
834 if (!strncmp(ap
->a_id
, "GS", 2))
841 ap
->a_size
+= axp
->a_size
;
845 gs_size
+= ap
->a_size
;
846 if (!strcmp(ap
->a_id
, "GSINIT0"))
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
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
;
876 gs0_ap
->a_size
= gs_size
;
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;
887 if (ap
->a_flag
& A3_ABS
) /* Absolute sections */
889 lnksect2(ap
, locIndex
);
891 else /* Relocatable sections */
895 ap
->a_addr
= rloc
[locIndex
];
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
);
918 sp
= lkpsym(temp
, 1);
919 sp
->s_addr
= ap
->a_addr
;
921 if (!strcmp(ap
->a_id
, "DSEG")) sp_dseg_s
=sp
;
924 sp
= lkpsym(temp
, 1);
925 sp
->s_addr
= ap
->a_size
;
928 if (!strcmp(ap
->a_id
, "DSEG")) sp_dseg_l
=sp
;
934 /*Compute the size of DSEG*/
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
)
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";
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))
964 ramlimit
= ramstart
+ iram_size
;
968 ramstart
= dram_start
;
970 if ((iram_size
<= 0) || (ramstart
+ iram_size
> 0x80))
973 ramlimit
= ramstart
+ iram_size
;
980 /*Use a letter to identify each area in the internal RAM layout map*/
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"))
987 else if(!strcmp(tap
->a_id
, "SSEG"))
989 else if(!strcmp(tap
->a_id
, "OSEG"))
991 else if(!strcmp(tap
->a_id
, "REG_BANK_0"))
993 else if(!strcmp(tap
->a_id
, "REG_BANK_1"))
995 else if(!strcmp(tap
->a_id
, "REG_BANK_2"))
997 else if(!strcmp(tap
->a_id
, "REG_BANK_3"))
999 else if(!strcmp(tap
->a_id
, "BSEG_BYTES"))
1001 else if(!strcmp(tap
->a_id
, "BIT_BANK"))
1006 else if (locIndex
== 1)
1008 /**/ if(!strcmp(tap
->a_id
, "GSINIT"))
1011 else if (locIndex
== 2)
1013 /**/ if(!strcmp(tap
->a_id
, "XSTK"))
1017 if (tap
->a_flag
& A3_OVR
) /* Overlayed sections */
1021 if(taxp
->a_size
== 0)
1027 if ( (fchar
=='0')||(fchar
=='1')||(fchar
=='2')||(fchar
=='3') ) /*Reg banks*/
1032 for(j
=addr
; (j
<(int)(addr
+size
)) && (j
<ramlimit
); j
++)
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
)
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
]==' ')
1075 if(k
==(int)taxp
->a_size
)
1079 /*Mark the memory used for overlay*/
1080 if(k
==(int)taxp
->a_size
)
1083 for(j
=addr
; (j
<(int)(addr
+size
)); j
++)
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
);
1093 /* avoid redundant processing SSEG */
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
]==' ')
1120 if(k
==(int)taxp
->a_size
)
1124 /*Mark the memory used for overlay*/
1128 for(j
=addr
; (j
<(int)(addr
+size
)); j
++)
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
);
1139 else /*Overlay areas not in internal ram*/
1141 taxp
->a_addr
= addr
;
1142 if (taxp
->a_size
> size
) size
= taxp
->a_size
;
1146 /*Now set all overlayed areax to the same start address*/
1150 taxp
->a_addr
= addr
;
1154 else if (tap
->a_flag
& A3_ABS
) /* Absolute sections */
1160 for (j
=taxp
->a_addr
; (j
<(int)(taxp
->a_addr
+taxp
->a_size
)) && (j
<256); j
++)
1162 if (idatamap
[j
] == ' ')
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
;
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
));
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
]==' ')
1204 if(k
==(int)taxp
->a_size
)
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
);
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
]==' ')
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
++)
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
);
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
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
));
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
;
1281 taxp
->a_addr
= addr
;
1287 tap
->a_addr
= tap
->a_axp
->a_addr
;
1288 for (taxp
= tap
->a_axp
; taxp
&& !taxp
->a_size
; taxp
= taxp
->a_axp
)
1293 tap
->a_addr
= taxp
->a_addr
;
1296 if ((tap
->a_flag
& A3_PAG
) && (size
> 256))
1299 "\n?ASlink-Warning-Paged Area %s Length Error\n",
1303 if ((tap
->a_flag
& A3_PAG
) && (tap
->a_size
) &&
1304 ((tap
->a_addr
& 0xFFFFFF00) != ((addr
-1) & 0xFFFFFF00)))
1307 "\n?ASlink-Warning-Paged Area %s Boundary Error\n",
1313 /* end sdld specific */