From 251547f028e2064e2427ef89137d442145c606e8 Mon Sep 17 00:00:00 2001 From: cuz Date: Sun, 27 Apr 2003 11:49:53 +0000 Subject: [PATCH] Working git-svn-id: svn://svn.cc65.org/cc65/trunk@2091 b7a2c559-68d2-44c3-8de9-860c34a00d81 --- src/sim65/cfgdata.h | 20 +-- src/sim65/chip.c | 119 ++++++++--------- src/sim65/chip.h | 38 ++++-- src/sim65/chipdata.h | 12 +- src/sim65/chiplib.c | 73 ++++++---- src/sim65/chiplib.h | 15 +-- src/sim65/chips/ram.c | 6 +- src/sim65/chips/stdio.c | 11 +- src/sim65/config.c | 285 +++++++++++++++++++++++++++++----------- src/sim65/config.h | 10 +- src/sim65/cpucore.c | 6 +- src/sim65/main.c | 55 +++++++- src/sim65/scanner.c | 17 ++- src/sim65/scanner.h | 16 +-- 14 files changed, 449 insertions(+), 234 deletions(-) diff --git a/src/sim65/cfgdata.h b/src/sim65/cfgdata.h index 2841333df..c0ea32b83 100644 --- a/src/sim65/cfgdata.h +++ b/src/sim65/cfgdata.h @@ -6,10 +6,10 @@ /* */ /* */ /* */ -/* (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 */ @@ -46,17 +46,19 @@ 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 */ }; diff --git a/src/sim65/chip.c b/src/sim65/chip.c index 3035e7683..6bae69444 100644 --- a/src/sim65/chip.c +++ b/src/sim65/chip.c @@ -6,10 +6,10 @@ /* */ /* */ /* */ -/* (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 */ @@ -94,7 +94,7 @@ static int CmpChips (void* Data attribute ((unused)), -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 */ @@ -105,68 +105,34 @@ static Chip* NewChip (ChipLibrary* Library, const ChipData* Data) 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. */ @@ -176,14 +142,14 @@ const Chip* FindChip (const char* Name) /* ## 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 */ @@ -192,3 +158,34 @@ const Chip* FindChip (const char* Name) +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); +} + + + diff --git a/src/sim65/chip.h b/src/sim65/chip.h index 9959ac31b..dbdbcaf3b 100644 --- a/src/sim65/chip.h +++ b/src/sim65/chip.h @@ -53,19 +53,21 @@ -#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 */ @@ -75,19 +77,26 @@ struct Chip { /*****************************************************************************/ -/* 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 */ @@ -96,3 +105,4 @@ const Chip* FindChip (const char* Name); + diff --git a/src/sim65/chipdata.h b/src/sim65/chipdata.h index 5224b5b07..8eb978ae8 100644 --- a/src/sim65/chipdata.h +++ b/src/sim65/chipdata.h @@ -6,10 +6,10 @@ /* */ /* */ /* */ -/* (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 */ @@ -49,6 +49,7 @@ #define CHIPDATA_VER_MINOR 0U /* Forwards */ +struct CfgData; struct SimData; /* ChipDesc structure */ @@ -60,7 +61,8 @@ struct ChipData { /* -- 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); diff --git a/src/sim65/chiplib.c b/src/sim65/chiplib.c index d35cd67db..d17c077c3 100644 --- a/src/sim65/chiplib.c +++ b/src/sim65/chiplib.c @@ -6,10 +6,10 @@ /* */ /* */ /* */ -/* (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 */ @@ -36,10 +36,12 @@ #include /* common */ +#include "fname.h" #include "print.h" #include "xmalloc.h" /* sim65 */ +#include "chip.h" #include "chippath.h" #include "error.h" #include "chiplib.h" @@ -52,9 +54,6 @@ -/* Forwards */ -struct ChipData; - /* A collection containing all libraries */ Collection ChipLibraries = STATIC_COLLECTION_INITIALIZER; @@ -66,18 +65,16 @@ 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 */ @@ -109,26 +106,22 @@ static void FreeChipLibrary (ChipLibrary* L) 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); @@ -153,7 +146,7 @@ void LoadChipLibrary (const char* LibName) } /* 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); @@ -165,6 +158,38 @@ void LoadChipLibrary (const char* LibName) /* 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); + } } diff --git a/src/sim65/chiplib.h b/src/sim65/chiplib.h index f4a019fc3..bc0132d28 100644 --- a/src/sim65/chiplib.h +++ b/src/sim65/chiplib.h @@ -41,6 +41,9 @@ /* common */ #include "coll.h" +/* sim65 */ +#include "chipdata.h" + /*****************************************************************************/ @@ -58,8 +61,6 @@ struct ChipLibrary { 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 */ }; @@ -75,13 +76,9 @@ extern Collection ChipLibraries; 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. */ diff --git a/src/sim65/chips/ram.c b/src/sim65/chips/ram.c index 210404def..544364cb8 100644 --- a/src/sim65/chips/ram.c +++ b/src/sim65/chips/ram.c @@ -50,7 +50,8 @@ 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); @@ -144,7 +145,8 @@ int InitChip (const struct SimData* Data) -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 */ diff --git a/src/sim65/chips/stdio.c b/src/sim65/chips/stdio.c index e75a05e8a..55a2cf233 100644 --- a/src/sim65/chips/stdio.c +++ b/src/sim65/chips/stdio.c @@ -54,9 +54,11 @@ 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 */ @@ -129,9 +131,10 @@ int InitChip (const struct SimData* 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; @@ -159,4 +162,4 @@ static unsigned char Read (void* Data attribute ((unused)), - + diff --git a/src/sim65/config.c b/src/sim65/config.c index b620a765f..e29366c9e 100644 --- a/src/sim65/config.c +++ b/src/sim65/config.c @@ -6,10 +6,10 @@ /* */ /* */ /* */ -/* (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 */ @@ -42,6 +42,7 @@ #include "check.h" #include "bitops.h" #include "print.h" +#include "strutil.h" #include "xmalloc.h" /* sim65 */ @@ -55,20 +56,48 @@ /*****************************************************************************/ -/* 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; @@ -77,7 +106,87 @@ static CfgData* NewCfgData (const char* Tok) /*****************************************************************************/ -/* 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 */ /*****************************************************************************/ @@ -105,72 +214,72 @@ static void AttrCheck (unsigned Attr, unsigned Mask, const char* Name) -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 (); @@ -179,18 +288,42 @@ static void ParseChips (void) /* 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; } } @@ -200,7 +333,7 @@ static void ParseConfig (void) /* Parse the config file */ { static const IdentTok BlockNames [] = { - { "CHIPS", CFGTOK_CHIPS }, + { "MEMORY", CFGTOK_MEMORY }, }; cfgtok_t BlockTok; @@ -217,9 +350,9 @@ static void ParseConfig (void) /* Read the block */ switch (BlockTok) { - case CFGTOK_CHIPS: - ParseChips (); - break; + case CFGTOK_MEMORY: + ParseMemory (); + break; default: FAIL ("Unexpected block token"); diff --git a/src/sim65/config.h b/src/sim65/config.h index bf34deba8..020903e11 100644 --- a/src/sim65/config.h +++ b/src/sim65/config.h @@ -6,10 +6,10 @@ /* */ /* */ /* */ -/* (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 */ @@ -56,4 +56,4 @@ void CfgRead (void); - + diff --git a/src/sim65/cpucore.c b/src/sim65/cpucore.c index 934b76670..8f7e35f80 100644 --- a/src/sim65/cpucore.c +++ b/src/sim65/cpucore.c @@ -113,9 +113,9 @@ int CPUHalted; /* 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) diff --git a/src/sim65/main.c b/src/sim65/main.c index 38f68bba7..7cfd0ed5c 100644 --- a/src/sim65/main.c +++ b/src/sim65/main.c @@ -37,12 +37,17 @@ #include #include #include +#include +#include +#include +#include /* common */ #include "abend.h" #include "cmdline.h" #include "print.h" #include "version.h" +#include "xmalloc.h" /* sim65 */ #include "chip.h" @@ -92,7 +97,47 @@ static void Usage (void) 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); } @@ -239,16 +284,14 @@ int main (int argc, char* argv[]) ++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 (); diff --git a/src/sim65/scanner.c b/src/sim65/scanner.c index ae1d08927..805dac488 100644 --- a/src/sim65/scanner.c +++ b/src/sim65/scanner.c @@ -6,10 +6,10 @@ /* */ /* */ /* */ -/* (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 */ @@ -237,8 +237,13 @@ Again: break; case '.': - NextChar (); - CfgTok = CFGTOK_DOT; + NextChar (); + if (C == '.') { + NextChar (); + CfgTok = CFGTOK_DOTDOT; + } else { + CfgTok = CFGTOK_DOT; + } break; case ',': diff --git a/src/sim65/scanner.h b/src/sim65/scanner.h index 25427e889..ce0652050 100644 --- a/src/sim65/scanner.h +++ b/src/sim65/scanner.h @@ -6,10 +6,10 @@ /* */ /* */ /* */ -/* (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 */ @@ -57,15 +57,11 @@ typedef enum { 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, -- 2.39.5