/* */
/* */
/* */
-/* (C) 2002 Ullrich von Bassewitz */
-/* Wacholderweg 14 */
-/* D-70597 Stuttgart */
-/* EMail: uz@musoftware.de */
+/* (C) 2002-2003 Ullrich von Bassewitz */
+/* Römerstrasse 52 */
+/* D-70794 Filderstadt */
+/* EMail: uz@cc65.org */
/* */
/* */
/* This software is provided 'as-is', without any expressed or implied */
typedef struct CfgData CfgData;
struct CfgData {
- char* Attr; /* The attribute name */
enum {
- Invalid,
- Id,
- Number,
- String
+ CfgDataInvalid,
+ CfgDataId,
+ CfgDataNumber,
+ CfgDataString
} Type; /* Type of the value */
union {
char* SVal; /* String or id value */
long IVal; /* Integer value */
} V;
+ unsigned Line; /* Line where the attribute was defined */
+ unsigned Col; /* Column of attribute definition */
+ char Attr[1]; /* The attribute name */
};
/* */
/* */
/* */
-/* (C) 2002 Ullrich von Bassewitz */
-/* Wacholderweg 14 */
-/* D-70597 Stuttgart */
-/* EMail: uz@musoftware.de */
+/* (C) 2002-2003 Ullrich von Bassewitz */
+/* Römerstrasse 52 */
+/* D-70794 Filderstadt */
+/* EMail: uz@cc65.org */
/* */
/* */
/* This software is provided 'as-is', without any expressed or implied */
-static Chip* NewChip (ChipLibrary* Library, const ChipData* Data)
+Chip* NewChip (ChipLibrary* Library, const ChipData* Data)
/* Allocate a new chip structure, initialize and return it */
{
/* Allocate memory */
C->Data = Data;
C->Instances = EmptyCollection;
+ /* Insert the new chip into the collection of all chips */
+ CollAppend (&Chips, C);
+
/* Return the structure */
return C;
}
-#if 0
-static void FreeChip (Chip* C)
-/* ## Free the given chip structure */
+ChipInstance* NewChipInstance (unsigned long Addr, unsigned Size)
+/* Allocate a new chip instance for the chip. */
{
- /* Free the structure itself */
- xfree (C);
-}
-#endif
-
-
+ /* Allocate a new ChipInstance structure */
+ ChipInstance* Instance = xmalloc (sizeof (*Instance));
-void LoadChips (void)
-/* Load all chips from all libraries */
-{
- unsigned I, J;
-
- /* Walk through all libraries */
- for (I = 0; I < CollCount (&ChipLibraries); ++I) {
-
- /* Get the library entry */
- ChipLibrary* L = CollAt (&ChipLibraries, I);
-
- /* Create the chips */
- for (J = 0; J < L->ChipCount; ++J) {
-
- /* Get a pointer to the chip data */
- const ChipData* Data = L->Data + J;
-
- /* Check if the chip data has the correct version */
- if (Data->MajorVersion != CHIPDATA_VER_MAJOR) {
- Warning ("Version mismatch for `%s' (%s), expected %u, got %u",
- Data->ChipName, L->LibName,
- CHIPDATA_VER_MAJOR, Data->MajorVersion);
- /* Ignore this chip */
- continue;
- }
-
- /* Generate a new chip and insert it into the collection */
- CollAppend (&Chips, NewChip (L, Data));
-
- /* Output chip name and version to keep the user happy */
- Print (stdout, 1,
- "Found chip `%s' version %u.%u\n",
- Data->ChipName,
- Data->MajorVersion,
- Data->MinorVersion);
- }
- }
+ /* Initialize the fields */
+ Instance->C = 0;
+ Instance->Addr = Addr;
+ Instance->Size = Size;
+ Instance->InstanceData = 0;
- /* Last act: Sort the chips by name */
- CollSort (&Chips, CmpChips, 0);
+ /* Return the new struct */
+ return Instance;
}
-const Chip* FindChip (const char* Name)
+static Chip* FindChip (const char* Name)
/* Find a chip by name. Returns the Chip data structure or NULL if the chip
* could not be found.
*/
/* ## We do a linear search for now */
for (I = 0; I < CollCount (&Chips); ++I) {
- /* Get the chip at this position */
- const Chip* C = CollConstAt (&Chips, I);
+ /* Get the chip at this position */
+ Chip* C = CollAt (&Chips, I);
- /* Compare the name */
- if (strcmp (Name, C->Data->ChipName) == 0) {
- /* Found */
- return C;
- }
+ /* Compare the name */
+ if (strcmp (Name, C->Data->ChipName) == 0) {
+ /* Found */
+ return C;
+ }
}
/* Not found */
+void InitChipInstance (ChipInstance* CI, const char* ChipName,
+ const struct CfgData** Data, unsigned Count)
+/* Initialize the given chip instance. Assign it to the chip named ChipName,
+ * and call the init function of the chip passing the given config data.
+ */
+{
+ /* Find the chip with the given name */
+ Chip* C = FindChip (ChipName);
+ if (C == 0) {
+ Error ("No chip `%s' found for address $%6lX", ChipName, CI->Addr);
+ }
+
+ /* Call the initialization function */
+ CI->InstanceData = C->Data->InitInstance (CI->Addr, CI->Size, Data, Count);
+
+ /* Assign the chip instance to the chip */
+ CI->C = C;
+ CollAppend (&C->Instances, CI);
+}
+
+
+
+void SortChips (void)
+/* Sort all chips by name. Called after loading */
+{
+ /* Last act: Sort the chips by name */
+ CollSort (&Chips, CmpChips, 0);
+}
+
+
+
-#if 0
+/* Forwards */
+struct CfgData;
+struct ChipLibrary;
+typedef struct Chip Chip;
typedef struct ChipInstance ChipInstance;
+
+/* One instance of a chip */
struct ChipInstance {
- Chip* C; /* Pointer to corresponding chip */
- unsigned Addr; /* Start address of range */
- unsigned Size; /* Size of range */
+ Chip* C; /* Pointer to corresponding chip */
+ unsigned long Addr; /* Start address of range */
+ unsigned Size; /* Size of range */
+ void* InstanceData; /* Chip instance data */
};
-#endif
-
-
/* Chip structure */
-typedef struct Chip Chip;
struct Chip {
struct ChipLibrary* Library; /* Pointer to library data structure */
const ChipData* Data; /* Chip data as given by the library */
/*****************************************************************************/
-/* Code */
+/* Code */
/*****************************************************************************/
-void LoadChips (void);
-/* Load all chips from all libraries */
+Chip* NewChip (struct ChipLibrary* Library, const ChipData* Data);
+/* Allocate a new chip structure, initialize and return it */
+
+ChipInstance* NewChipInstance (unsigned long Addr, unsigned Size);
+/* Allocate a new chip instance for the chip. */
-const Chip* FindChip (const char* Name);
-/* Find a chip by name. Returns the Chip data structure or NULL if the chip
- * could not be found.
+void InitChipInstance (ChipInstance* CI, const char* ChipName,
+ const struct CfgData** Data, unsigned Count);
+/* Initialize the given chip instance. Assign it to the chip named ChipName,
+ * and call the init function of the chip passing the given config data.
*/
+void SortChips (void);
+/* Sort all chips by name. Called after loading */
+
/* End of chip.h */
+
/* */
/* */
/* */
-/* (C) 2002 Ullrich von Bassewitz */
-/* Wacholderweg 14 */
-/* D-70597 Stuttgart */
-/* EMail: uz@musoftware.de */
+/* (C) 2002-2003 Ullrich von Bassewitz */
+/* Römerstrasse 52 */
+/* D-70794 Filderstadt */
+/* EMail: uz@cc65.org */
/* */
/* */
/* This software is provided 'as-is', without any expressed or implied */
#define CHIPDATA_VER_MINOR 0U
/* Forwards */
+struct CfgData;
struct SimData;
/* ChipDesc structure */
/* -- Exported functions -- */
int (*InitChip) (const struct SimData* Data);
- void* (*InitInstance) (unsigned Addr, unsigned Range);
+ void* (*InitInstance) (unsigned Addr, unsigned Range,
+ const struct CfgData** Data, unsigned CfgDataCount);
void (*WriteCtrl) (void* Data, unsigned Offs, unsigned char Val);
void (*Write) (void* Data, unsigned Offs, unsigned char Val);
unsigned char (*ReadCtrl) (void* Data, unsigned Offs);
/* */
/* */
/* */
-/* (C) 2002 Ullrich von Bassewitz */
-/* Wacholderweg 14 */
-/* D-70597 Stuttgart */
-/* EMail: uz@musoftware.de */
+/* (C) 2002-2003 Ullrich von Bassewitz */
+/* Römerstrasse 52 */
+/* D-70794 Filderstadt */
+/* EMail: uz@cc65.org */
/* */
/* */
/* This software is provided 'as-is', without any expressed or implied */
#include <dlfcn.h>
/* common */
+#include "fname.h"
#include "print.h"
#include "xmalloc.h"
/* sim65 */
+#include "chip.h"
#include "chippath.h"
#include "error.h"
#include "chiplib.h"
-/* Forwards */
-struct ChipData;
-
/* A collection containing all libraries */
Collection ChipLibraries = STATIC_COLLECTION_INITIALIZER;
-static ChipLibrary* NewChipLibrary (const char* LibName)
+static ChipLibrary* NewChipLibrary (const char* PathName)
/* Create, initialize and return a new ChipLibrary structure */
{
/* Allocate memory */
ChipLibrary* L = xmalloc (sizeof (ChipLibrary));
/* Initialize the fields */
- L->LibName = xstrdup (LibName);
- L->PathName = 0;
+ L->LibName = xstrdup (FindName (PathName));
+ L->PathName = xstrdup (PathName);
L->Handle = 0;
- L->Data = 0;
- L->ChipCount = 0;
L->Chips = EmptyCollection;
/* Return the allocated structure */
void LoadChipLibrary (const char* LibName)
-/* Load a chip library . This includes loading the shared libary, allocating
- * and initializing the data structure.
+/* Load a chip library. This includes loading the shared libary, allocating
+ * and initializing the data structure, and loading all chip data from the
+ * library.
*/
{
const char* Msg;
int (*GetChipData) (const struct ChipData**, unsigned*);
int ErrorCode;
+ const ChipData* Data; /* Pointer to chip data */
+ unsigned ChipCount; /* Number of chips in this library */
+ unsigned I;
+
/* Allocate a new ChipLibrary structure */
ChipLibrary* L = NewChipLibrary (LibName);
- /* Locate the library */
- L->PathName = FindChipLib (LibName);
- if (L->PathName == 0) {
- /* Library not found */
- Error ("Cannot find chip plugin library `%s'", LibName);
- FreeChipLibrary (L);
- return;
- }
-
/* Open the library */
L->Handle = dlopen (L->PathName, RTLD_GLOBAL | RTLD_LAZY);
}
/* Call the function to read the chip data */
- ErrorCode = GetChipData (&L->Data, &L->ChipCount);
+ ErrorCode = GetChipData (&Data, &ChipCount);
if (ErrorCode != 0) {
Error ("Function `GetChipData' in `%s' returned error %d", L->LibName, ErrorCode);
FreeChipLibrary (L);
/* Print some information */
Print (stderr, 1, "Opened chip library `%s'\n", L->PathName);
+
+ /* Create the chips */
+ for (I = 0; I < ChipCount; ++I) {
+
+ Chip* C;
+
+ /* Get a pointer to the chip data */
+ const ChipData* D = Data + I;
+
+ /* Check if the chip data has the correct version */
+ if (Data->MajorVersion != CHIPDATA_VER_MAJOR) {
+ Warning ("Version mismatch for `%s' (%s), expected %u, got %u",
+ D->ChipName, L->LibName,
+ CHIPDATA_VER_MAJOR, D->MajorVersion);
+ /* Ignore this chip */
+ continue;
+ }
+
+ /* Generate a new chip */
+ C = NewChip (L, D);
+
+ /* Insert a reference to the chip into the library exporting it */
+ CollAppend (&L->Chips, C);
+
+ /* Output chip name and version to keep the user happy */
+ Print (stdout, 1,
+ " Found `%s', version %u.%u in library `%s'\n",
+ Data->ChipName,
+ Data->MajorVersion,
+ Data->MinorVersion,
+ L->LibName);
+ }
}
/* common */
#include "coll.h"
+/* sim65 */
+#include "chipdata.h"
+
/*****************************************************************************/
char* LibName; /* Name of the library as given */
char* PathName; /* Name of library including path */
void* Handle; /* Pointer to libary handle */
- const struct ChipData* Data; /* Pointer to chip data */
- unsigned ChipCount; /* Number of chips in this library */
Collection Chips; /* Chips in this library */
};
void LoadChipLibrary (const char* LibName);
-/* Load a chip library . This includes loading the shared libary, allocating
- * and initializing the data structure.
- */
-
-void* GetChipLibSym (const ChipLibrary* L, const char* SymName);
-/* Locate a symbol in a module and return it. Abort on errors (may be modified
- * later to return NULL).
+/* Load a chip library. This includes loading the shared libary, allocating
+ * and initializing the data structure, and loading all chip data from the
+ * library.
*/
int InitChip (const struct SimData* Data);
/* Initialize the chip, return an error code */
-static void* InitInstance (unsigned Addr, unsigned Range);
+static void* InitInstance (unsigned Addr, unsigned Range,
+ const CfgData** Data, unsigned CfgDataCount);
/* Initialize a new chip instance */
static void WriteCtrl (void* Data, unsigned Offs, unsigned char Val);
-static void* InitInstance (unsigned Addr, unsigned Range)
+static void* InitInstance (unsigned Addr, unsigned Range,
+ const CfgData** Data, unsigned CfgDataCount)
/* Initialize a new chip instance */
{
/* Allocate a new instance structure */
int InitChip (const struct SimData* Data);
/* Initialize the chip, return an error code */
-static void* InitInstance (unsigned Addr, unsigned Range);
+static void* InitInstance (unsigned Addr, unsigned Range,
+ const CfgData** Data, unsigned CfgDataCount);
/* Initialize a new chip instance */
+
static void Write (void* Data, unsigned Offs, unsigned char Val);
/* Write user data */
-static void* InitInstance (unsigned Addr attribute ((unused)),
- unsigned Range attribute ((unused)))
+static void* InitInstance (unsigned Addr, unsigned Range,
+ const CfgData** Data, unsigned CfgDataCount)
/* Initialize a new chip instance */
+
{
/* We don't need any instance data */
return 0;
-
+
/* */
/* */
/* */
-/* (C) 1998-2002 Ullrich von Bassewitz */
-/* Wacholderweg 14 */
-/* D-70597 Stuttgart */
-/* EMail: uz@musoftware.de */
+/* (C) 1998-2003 Ullrich von Bassewitz */
+/* Römerstrasse 52 */
+/* D-70794 Filderstadt */
+/* EMail: uz@cc65.org */
/* */
/* */
/* This software is provided 'as-is', without any expressed or implied */
#include "check.h"
#include "bitops.h"
#include "print.h"
+#include "strutil.h"
#include "xmalloc.h"
/* sim65 */
/*****************************************************************************/
-/* struct CfgData */
+/* Data */
/*****************************************************************************/
-static CfgData* NewCfgData (const char* Tok)
-/* Create and intialize a new CfgData struct, then return it */
+/* List of all memory locations */
+static Collection Locations;
+
+/* One memory location */
+typedef struct Location Location;
+struct Location {
+ unsigned long Start; /* Start of memory location */
+ unsigned long End; /* End memory location */
+ Collection Attributes; /* Attributes given */
+ unsigned Line; /* Line in config file */
+ unsigned Col; /* Column in config file */
+};
+
+
+
+/*****************************************************************************/
+/* struct CfgData */
+/*****************************************************************************/
+
+
+
+static CfgData* NewCfgData (void)
+/* Create and intialize a new CfgData struct, then return it. The function
+ * uses the current output of the config scanner.
+ */
{
+ /* Get the length of the identifier */
+ unsigned AttrLen = strlen (CfgSVal);
+
/* Allocate memory */
- CfgData* D = xmalloc (sizeof (CfgData));
+ CfgData* D = xmalloc (sizeof (CfgData) + AttrLen);
/* Initialize the fields */
- D->Attr = xstrdup (Tok);
- D->Type = Invalid;
+ D->Type = CfgDataInvalid;
+ D->Line = CfgErrorLine;
+ D->Col = CfgErrorCol;
+ memcpy (D->Attr, CfgSVal, AttrLen+1);
/* Return the new struct */
return D;
/*****************************************************************************/
-/* Data */
+/* struct Location */
+/*****************************************************************************/
+
+
+
+static Location* NewLocation (unsigned long Start, unsigned long End)
+/* Create a new location, initialize and return it */
+{
+ /* Allocate memory */
+ Location* L = xmalloc (sizeof (Location));
+
+ /* Initialize the fields */
+ L->Start = Start;
+ L->End = End;
+ L->Attributes = EmptyCollection;
+ L->Line = CfgErrorLine;
+ L->Col = CfgErrorCol;
+
+ /* Return the new struct */
+ return L;
+}
+
+
+
+static int CmpLocations (void* Data attribute ((unused)),
+ const void* lhs, const void* rhs)
+/* Compare function for CollSort */
+{
+ /* Cast the object pointers */
+ const Location* Left = (const Location*) rhs;
+ const Location* Right = (const Location*) lhs;
+
+ /* Do the compare */
+ if (Left->Start < Right->Start) {
+ return 1;
+ } else if (Left->Start > Right->Start) {
+ return -1;
+ } else {
+ return 0;
+ }
+}
+
+
+
+static const CfgData* LocationFindAttr (const Location* L, const char* AttrName)
+/* Find the attribute with the given name and return it. Return NULL if the
+ * attribute was not found.
+ */
+{
+ unsigned I;
+
+ /* Walk through the attributes checking for a "mirror" attribute */
+ for (I = 0; I < CollCount (&L->Attributes); ++I) {
+
+ /* Get the next attribute */
+ const CfgData* D = CollConstAt (&L->Attributes, I);
+
+ /* Compare the name */
+ if (StrCaseCmp (D->Attr, AttrName) == 0) {
+ /* Found */
+ return D;
+ }
+ }
+
+ /* Not found */
+ return 0;
+}
+
+
+
+static int LocationIsMirror (const Location* L)
+/* Return true if the given location is a mirror of another one. */
+{
+ /* Find the "mirror" attribute */
+ return (LocationFindAttr (L, "mirror") != 0);
+}
+
+
+
+/*****************************************************************************/
+/* Code */
/*****************************************************************************/
-static void ParseChips (void)
-/* Parse a CHIPS section */
+static void ParseMemory (void)
+/* Parse a MEMORY section */
{
- static const IdentTok Attributes [] = {
- { "ADDR", CFGTOK_ADDR },
- { "RANGE", CFGTOK_RANGE },
- };
+ unsigned I;
+ const Location* Last;
- /* Bits and stuff to remember which attributes we have read */
- enum {
- CA_ADDR = 0x01,
- CA_RANGE = 0x02
- };
- unsigned Attr;
- /* Attribute values. Initialize to make gcc happy. */
- const Chip* C;
- unsigned Addr = 0;
- unsigned Range = 0;
+ while (CfgTok == CFGTOK_INTCON) {
- while (CfgTok == CFGTOK_IDENT) {
+ Location* L;
- /* Search the chip with the given name */
- C = FindChip (CfgSVal);
- if (C == 0) {
- CfgError ("No such chip: `%s'", CfgSVal);
- }
+ /* Remember the start address and skip it */
+ unsigned long Start = CfgIVal;
+ CfgNextTok ();
- /* Skip the name plus the following colon */
- CfgNextTok ();
- CfgConsumeColon ();
+ /* .. must follow */
+ CfgConsume (CFGTOK_DOTDOT, "`..' expected");
+
+ /* End address must follow and must be greater than start */
+ CfgAssureInt ();
+ if (CfgIVal < Start) {
+ CfgError ("Start address must be greater than end address");
+ }
+
+ /* Create a new location and add it to the list */
+ L = NewLocation (Start, CfgIVal);
+ CollAppend (&Locations, L);
+
+ /* Skip the end address and the following colon */
+ CfgNextTok ();
+ CfgConsumeColon ();
- /* Read the attributes */
- Attr = 0;
- while (CfgTok == CFGTOK_IDENT) {
+ /* Parse attributes terminated by a semicolon */
+ while (CfgTok == CFGTOK_IDENT) {
- /* Map the identifier to a token */
- cfgtok_t AttrTok;
- CfgSpecialToken (Attributes, ENTRY_COUNT (Attributes), "Attribute");
- AttrTok = CfgTok;
+ /* Generate a new attribute with the given name, then skip it */
+ CfgData* D = NewCfgData ();
+ CfgNextTok ();
/* An optional assignment follows */
- CfgNextTok ();
CfgOptionalAssign ();
- /* Check which attribute was given */
- switch (AttrTok) {
+ /* Check and assign the attribute value */
+ switch (CfgTok) {
+
+ case CFGTOK_INTCON:
+ D->Type = CfgDataNumber;
+ D->V.IVal = CfgIVal;
+ break;
- case CFGTOK_ADDR:
- CfgAssureInt ();
- CfgRangeCheck (0, 0xFFFF);
- FlagAttr (&Attr, CA_ADDR, "ADDR");
- Addr = (unsigned) CfgIVal;
- break;
+ case CFGTOK_STRCON:
+ D->Type = CfgDataString;
+ D->V.SVal = xstrdup (CfgSVal);
+ break;
- case CFGTOK_RANGE:
- CfgAssureInt ();
- CfgRangeCheck (0, 0xFFFF);
- FlagAttr (&Attr, CA_RANGE, "RANGE");
- Range = (unsigned) CfgIVal;
- break;
+ case CFGTOK_IDENT:
+ D->Type = CfgDataId;
+ D->V.SVal = xstrdup (CfgSVal);
+ break;
- default:
- FAIL ("Unexpected attribute token");
+ default:
+ CfgError ("Invalid attribute type");
+ }
- }
+ /* Add the attribute to the location */
+ CollAppend (&L->Attributes, D);
/* Skip the attribute value and an optional comma */
CfgNextTok ();
/* Skip the semicolon */
CfgConsumeSemi ();
+ }
- /* Check for mandatory parameters */
- AttrCheck (Attr, CA_ADDR, "ADDR");
- AttrCheck (Attr, CA_RANGE, "RANGE");
-
- /* Address + Range may not exceed 16 bits */
- if (((unsigned long) Range) > 0x10000UL - Addr) {
- CfgError ("Range error");
- }
-
- /* Create the chip ## */
-
+ /* Sort all memory locations */
+ CollSort (&Locations, CmpLocations, 0);
+
+ /* Check for overlaps and other problems */
+ Last = 0;
+ for (I = 0; I < CollCount (&Locations); ++I) {
+
+ /* Get this location */
+ const Location* L = CollAtUnchecked (&Locations, I);
+
+ /* Check for an overlap with the following location */
+ if (Last && Last->End >= L->Start) {
+ Error ("%s(%u): Address range overlap (overlapping entry is in line %u)",
+ CfgGetName(), L->Line, Last->Line);
+ }
+
+ /* If the location is a mirror, it must not have other attributes,
+ * and the mirror attribute must be an integer.
+ */
+ if (LocationIsMirror (L)) {
+ const CfgData* D;
+ if (CollCount (&L->Attributes) > 1) {
+ Error ("%s(%u): Location at address $%06lX is a mirror "
+ "but has attributes", CfgGetName(), L->Line, L->Start);
+ }
+ D = CollConstAt (&L->Attributes, 0);
+ if (D->Type != CfgDataNumber) {
+ Error ("%s(%u): Mirror attribute is not an integer",
+ CfgGetName (), L->Line);
+ }
+ }
+
+ /* Remember this entry */
+ Last = L;
}
}
/* Parse the config file */
{
static const IdentTok BlockNames [] = {
- { "CHIPS", CFGTOK_CHIPS },
+ { "MEMORY", CFGTOK_MEMORY },
};
cfgtok_t BlockTok;
/* Read the block */
switch (BlockTok) {
- case CFGTOK_CHIPS:
- ParseChips ();
- break;
+ case CFGTOK_MEMORY:
+ ParseMemory ();
+ break;
default:
FAIL ("Unexpected block token");
/* */
/* */
/* */
-/* (C) 1998-2002 Ullrich von Bassewitz */
-/* Wacholderweg 14 */
-/* D-70597 Stuttgart */
-/* EMail: uz@musoftware.de */
+/* (C) 1998-2003 Ullrich von Bassewitz */
+/* Römerstrasse 52 */
+/* D-70794 Filderstadt */
+/* EMail: uz@cc65.org */
/* */
/* */
/* This software is provided 'as-is', without any expressed or implied */
-
+
/* Special test and set macros. The meaning of the parameter depends on the
* actual flag that should be set or reset.
*/
-#define TEST_ZF(v) SET_ZF (((v) & 0xFF) == 0)
-#define TEST_SF(v) SET_SF (((v) & 0x80) != 0)
-#define TEST_CF(v) SET_CF (((v) & 0xFF00) != 0)
+#define TEST_ZF(v) SET_ZF (((v) & 0xFF) == 0)
+#define TEST_SF(v) SET_SF (((v) & 0x80) != 0)
+#define TEST_CF(v) SET_CF (((v) & 0xFF00) != 0)
/* Program counter halves */
#define PCL (PC & 0xFF)
#include <string.h>
#include <stdlib.h>
#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <dirent.h>
+#include <unistd.h>
/* common */
#include "abend.h"
#include "cmdline.h"
#include "print.h"
#include "version.h"
+#include "xmalloc.h"
/* sim65 */
#include "chip.h"
static void OptChipDir (const char* Opt attribute ((unused)), const char* Arg)
/* Handle the --chipdir option */
{
- AddChipPath (Arg);
+ struct dirent* E;
+
+ /* Get the length of the directory name */
+ unsigned DirLen = strlen (Arg);
+
+ /* Open the directory */
+ DIR* D = opendir (Arg);
+ if (D == 0) {
+ AbEnd ("Cannot read directory `%s': %s", Arg, strerror (errno));
+ }
+
+ /* Read in all files and treat them as libraries */
+ while ((E = readdir (D)) != 0) {
+
+ struct stat S;
+
+ /* Create the full file name */
+ char* Name = xmalloc (DirLen + 1 + strlen (E->d_name) + 1);
+ strcpy (Name, Arg);
+ strcpy (Name + DirLen, "/");
+ strcpy (Name + DirLen + 1, E->d_name);
+
+ /* Stat the file */
+ if (stat (Name, &S) != 0) {
+ Warning ("Cannot stat `%s': %s", Name, strerror (errno));
+ xfree (Name);
+ continue;
+ }
+
+ /* Check if this is a regular file */
+ if (S_ISREG (S.st_mode)) {
+ /* Treat it as a library */
+ LoadChipLibrary (Name);
+ }
+
+ /* Free the name */
+ xfree (Name);
+ }
+
+ /* Close the directory */
+ closedir (D);
}
++I;
}
+ /* Sort the already loaded chips */
+ SortChips ();
+
/* Check if we have a valid configuration */
if (!CfgAvail ()) {
Error ("Simulator configuration missing");
}
- /* Load the chips */
- AddChipPath ("chips");
- LoadChipLibrary ("ram.so");
- LoadChips ();
-
/* Read the config file */
CfgRead ();
/* */
/* */
/* */
-/* (C) 1998-2002 Ullrich von Bassewitz */
-/* Wacholderweg 14 */
-/* D-70597 Stuttgart */
-/* EMail: uz@musoftware.de */
+/* (C) 1998-2003 Ullrich von Bassewitz */
+/* Römerstrasse 52 */
+/* D-70794 Filderstadt */
+/* EMail: uz@cc65.org */
/* */
/* */
/* This software is provided 'as-is', without any expressed or implied */
break;
case '.':
- NextChar ();
- CfgTok = CFGTOK_DOT;
+ NextChar ();
+ if (C == '.') {
+ NextChar ();
+ CfgTok = CFGTOK_DOTDOT;
+ } else {
+ CfgTok = CFGTOK_DOT;
+ }
break;
case ',':
/* */
/* */
/* */
-/* (C) 1998-2002 Ullrich von Bassewitz */
-/* Wacholderweg 14 */
-/* D-70597 Stuttgart */
-/* EMail: uz@musoftware.de */
+/* (C) 1998-2003 Ullrich von Bassewitz */
+/* Römerstrasse 52 */
+/* D-70794 Filderstadt */
+/* EMail: uz@cc65.org */
/* */
/* */
/* This software is provided 'as-is', without any expressed or implied */
CFGTOK_EQ,
CFGTOK_COLON,
CFGTOK_DOT,
+ CFGTOK_DOTDOT,
CFGTOK_EOF,
/* Primary blocks */
- CFGTOK_CHIPS,
-
- /* Chips section */
- CFGTOK_NAME,
- CFGTOK_ADDR,
- CFGTOK_RANGE,
+ CFGTOK_MEMORY,
/* Special identifiers */
CFGTOK_TRUE,