1 /*****************************************************************************/
5 /* Memory location description */
9 /* (C) 2003 Ullrich von Bassewitz */
10 /* Römerstrasse 52 */
11 /* D-70794 Filderstadt */
12 /* EMail: uz@cc65.org */
15 /* This software is provided 'as-is', without any expressed or implied */
16 /* warranty. In no event will the authors be held liable for any damages */
17 /* arising from the use of this software. */
19 /* Permission is granted to anyone to use this software for any purpose, */
20 /* including commercial applications, and to alter it and redistribute it */
21 /* freely, subject to the following restrictions: */
23 /* 1. The origin of this software must not be misrepresented; you must not */
24 /* claim that you wrote the original software. If you use this software */
25 /* in a product, an acknowledgment in the product documentation would be */
26 /* appreciated but is not required. */
27 /* 2. Altered source versions must be plainly marked as such, and must not */
28 /* be misrepresented as being the original software. */
29 /* 3. This notice may not be removed or altered from any source */
32 /*****************************************************************************/
48 /*****************************************************************************/
50 /*****************************************************************************/
54 /* List of all memory locations */
55 Collection Locations = STATIC_COLLECTION_INITIALIZER;
59 /*****************************************************************************/
61 /*****************************************************************************/
65 Location* NewLocation (unsigned long Start, unsigned long End)
66 /* Create a new location, initialize and return it */
69 Location* L = xmalloc (sizeof (Location));
71 /* Initialize the fields */
74 L->Attributes = EmptyCollection;
75 L->Line = CfgErrorLine;
78 /* Return the new struct */
84 static int CmpLocations (void* Data attribute ((unused)),
85 const void* lhs, const void* rhs)
86 /* Compare function for CollSort */
88 /* Cast the object pointers */
89 const Location* Left = (const Location*) rhs;
90 const Location* Right = (const Location*) lhs;
93 if (Left->Start < Right->Start) {
95 } else if (Left->Start > Right->Start) {
104 int LocationGetAttr (const Location* L, const char* AttrName)
105 /* Find the attribute with the given name and return it. Call Error() if the
106 * attribute was not found.
109 int I = CfgDataFind (&L->Attributes, AttrName);
111 Error ("%s(%u): Attribute `%s' missing", CfgGetName(), L->Line, AttrName);
118 int LocationIsMirror (const Location* L)
119 /* Return true if the given location is a mirror of another one. */
121 /* Find the "mirror" attribute */
122 return (CfgDataFind (&L->Attributes, "mirror") >= 0);
127 void LocationSort (Collection* Locations)
128 /* Sort all locations by address */
130 /* Sort all memory locations */
131 CollSort (Locations, CmpLocations, 0);
136 void LocationCheck (const Collection* Locations)
137 /* Check all locations for problems */
141 /* Check for overlaps and other problems */
142 const Location* Last = 0;
143 for (I = 0; I < CollCount (Locations); ++I) {
145 /* Get this location */
146 const Location* L = CollConstAt (Locations, I);
148 /* Check for an overlap with the following location */
149 if (Last && Last->End >= L->Start) {
150 Error ("%s(%u): Address range overlap (overlapping entry is in line %u)",
151 CfgGetName(), L->Line, Last->Line);
154 /* If the location is a mirror, it must not have other attributes,
155 * and the mirror attribute must be an integer.
157 if (LocationIsMirror (L)) {
159 if (CollCount (&L->Attributes) > 1) {
160 Error ("%s(%u): Location at address $%06X is a mirror "
161 "but has attributes", CfgGetName(), L->Line, L->Start);
163 D = CollConstAt (&L->Attributes, 0);
164 CfgDataCheckType (D, CfgDataNumber);
167 /* Remember this entry */