1 /*****************************************************************************/
5 /* Interface for the chip plugins */
9 /* (C) 2002-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 /*****************************************************************************/
53 /*****************************************************************************/
55 /*****************************************************************************/
59 /* Sorted list of all chip data structures */
60 static Collection Chips = STATIC_COLLECTION_INITIALIZER;
62 /* A collection containing all libraries */
63 static Collection ChipLibraries = STATIC_COLLECTION_INITIALIZER;
65 /* SimData instance */
66 static const SimData Sim65Data = {
81 /*****************************************************************************/
82 /* Helper functions */
83 /*****************************************************************************/
87 static int CmpChips (void* Data attribute ((unused)),
88 const void* lhs, const void* rhs)
89 /* Compare function for CollSort */
91 /* Cast the object pointers */
92 const Chip* Left = (const Chip*) rhs;
93 const Chip* Right = (const Chip*) lhs;
96 return strcmp (Left->Data->ChipName, Right->Data->ChipName);
101 static Chip* FindChip (const char* Name)
102 /* Find a chip by name. Returns the Chip data structure or NULL if the chip
103 * could not be found.
108 /* ## We do a linear search for now */
109 for (I = 0; I < CollCount (&Chips); ++I) {
111 /* Get the chip at this position */
112 Chip* C = CollAt (&Chips, I);
114 /* Compare the name */
115 if (strcmp (Name, C->Data->ChipName) == 0) {
127 /*****************************************************************************/
129 /*****************************************************************************/
133 static ChipLibrary* NewChipLibrary (const char* PathName)
134 /* Create, initialize and return a new ChipLibrary structure */
136 /* Allocate memory */
137 ChipLibrary* L = xmalloc (sizeof (ChipLibrary));
139 /* Initialize the fields */
140 L->LibName = xstrdup (FindName (PathName));
141 L->PathName = xstrdup (PathName);
143 L->Chips = EmptyCollection;
145 /* Return the allocated structure */
151 static void FreeChipLibrary (ChipLibrary* L)
152 /* Free a ChipLibrary structure */
158 /* If the library is open, close it. Discard any errors. */
164 /* We may have to handle the Chip pointers, but currently the function
165 * is never called with a non empty Chips collection, so we don't care
173 static Chip* NewChip (ChipLibrary* Library, const ChipData* Data)
174 /* Allocate a new chip structure, initialize and return it */
176 /* Allocate memory */
177 Chip* C = xmalloc (sizeof (Chip));
179 /* Initialize the fields */
180 C->Library = Library;
182 C->Instances = EmptyCollection;
184 /* Insert the new chip into the collection of all chips */
185 CollAppend (&Chips, C);
187 /* Return the structure */
193 ChipInstance* NewChipInstance (const char* ChipName, unsigned Addr,
194 unsigned Size, Collection* Attributes)
198 /* Find the chip with the given name */
199 Chip* C = FindChip (ChipName);
201 Error ("No chip `%s' found for address $%06X", ChipName, Addr);
204 /* Allocate a new ChipInstance structure */
205 CI = xmalloc (sizeof (*CI));
207 /* Initialize the fields */
211 CI->Data = C->Data->InitInstance (Addr, Size, Attributes);
213 /* Assign the chip instance to the chip */
214 CollAppend (&C->Instances, CI);
216 /* Return the new instance struct */
222 ChipInstance* MirrorChipInstance (const ChipInstance* Orig, unsigned Addr)
223 /* Generate a chip instance mirror and return it. */
225 /* Allocate a new ChipInstance structure */
226 ChipInstance* CI = xmalloc (sizeof (*CI));
228 /* Initialize the fields */
231 CI->Size = Orig->Size;
232 CI->Data = Orig->Data;
234 /* Assign the chip instance to the chip */
235 CollAppend (&CI->C->Instances, CI);
237 /* Return the new instance struct */
243 void SortChips (void)
244 /* Sort all chips by name. Called after loading */
246 /* Last act: Sort the chips by name */
247 CollSort (&Chips, CmpChips, 0);
252 void LoadChipLibrary (const char* LibName)
253 /* Load a chip library. This includes loading the shared libary, allocating
254 * and initializing the data structure, and loading all chip data from the
259 int (*GetChipData) (const struct ChipData**, unsigned*);
261 const ChipData* Data; /* Pointer to chip data */
262 unsigned ChipCount; /* Number of chips in this library */
266 /* Allocate a new ChipLibrary structure */
267 ChipLibrary* L = NewChipLibrary (LibName);
269 /* Open the library */
270 L->Handle = dlopen (L->PathName, RTLD_GLOBAL | RTLD_LAZY);
272 /* Check for errors */
275 Error ("Cannot open `%s': %s", L->PathName, Msg);
280 /* Locate the GetChipData function */
281 GetChipData = dlsym (L->Handle, "GetChipData");
283 /* Check the error message */
286 /* We had an error */
287 Error ("Cannot find export `GetChipData' in `%s': %s", L->LibName, Msg);
292 /* Call the function to read the chip data */
293 ErrorCode = GetChipData (&Data, &ChipCount);
294 if (ErrorCode != 0) {
295 Error ("Function `GetChipData' in `%s' returned error %d", L->LibName, ErrorCode);
300 /* Remember the library */
301 CollAppend (&ChipLibraries, L);
303 /* Print some information */
304 Print (stderr, 1, "Opened chip library `%s'\n", L->PathName);
306 /* Create the chips */
307 for (I = 0; I < ChipCount; ++I) {
311 /* Get a pointer to the chip data */
312 const ChipData* D = Data + I;
314 /* Check if the chip data has the correct version */
315 if (Data->MajorVersion != CHIPDATA_VER_MAJOR) {
316 Warning ("Version mismatch for `%s' (%s), expected %u, got %u",
317 D->ChipName, L->LibName,
318 CHIPDATA_VER_MAJOR, D->MajorVersion);
319 /* Ignore this chip */
323 /* Generate a new chip */
326 /* Insert a reference to the chip into the library exporting it */
327 CollAppend (&L->Chips, C);
329 /* Output chip name and version to keep the user happy */
331 " Found `%s', version %u.%u in library `%s'\n",