diff --git a/src/sim65/cfgdata.c b/src/sim65/cfgdata.c new file mode 100644 index 000000000..cd824292f --- /dev/null +++ b/src/sim65/cfgdata.c @@ -0,0 +1,223 @@ +/*****************************************************************************/ +/* */ +/* cfgdata.c */ +/* */ +/* Config data structure */ +/* */ +/* */ +/* */ +/* (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 */ +/* warranty. In no event will the authors be held liable for any damages */ +/* arising from the use of this software. */ +/* */ +/* Permission is granted to anyone to use this software for any purpose, */ +/* including commercial applications, and to alter it and redistribute it */ +/* freely, subject to the following restrictions: */ +/* */ +/* 1. The origin of this software must not be misrepresented; you must not */ +/* claim that you wrote the original software. If you use this software */ +/* in a product, an acknowledgment in the product documentation would be */ +/* appreciated but is not required. */ +/* 2. Altered source versions must be plainly marked as such, and must not */ +/* be misrepresented as being the original software. */ +/* 3. This notice may not be removed or altered from any source */ +/* distribution. */ +/* */ +/*****************************************************************************/ + + + +#include + +/* common */ +#include "strutil.h" +#include "xmalloc.h" + +/* sim65 */ +#include "scanner.h" +#include "cfgdata.h" + + + +/*****************************************************************************/ +/* Code */ +/*****************************************************************************/ + + + +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) + AttrLen); + + /* Initialize the fields */ + D->Type = CfgDataInvalid; + D->Line = CfgErrorLine; + D->Col = CfgErrorCol; + memcpy (D->Attr, CfgSVal, AttrLen+1); + + /* Return the new struct */ + return D; +} + + + +void FreeCfgData (CfgData* D) +/* Free a config data structure */ +{ + if (D->Type == CfgDataString) { + /* Free the string value */ + xfree (D->V.SVal); + } + /* Free the structure */ + xfree (D); +} + + + +int CfgDataFind (Collection* Attributes, const char* AttrName) +/* Find the attribute with the given name and return its index. Return -1 if + * the attribute was not found. + */ +{ + unsigned I; + + /* Walk through the attributes checking for a "mirror" attribute */ + for (I = 0; I < CollCount (Attributes); ++I) { + + /* Get the next attribute */ + const CfgData* D = CollConstAt (Attributes, I); + + /* Compare the name */ + if (StrCaseCmp (D->Attr, AttrName) == 0) { + /* Found */ + return I; + } + } + + /* Not found */ + return -1; +} + + + +CfgData* CfgDataGetTyped (Collection* Attributes, const char* Name, unsigned Type) +/* Find the attribute with the given name and type. If found, remove it from + * Attributes and return it. If not found or wrong type, return NULL. + */ +{ + CfgData* D; + + /* Search for the attribute */ + int I = CfgDataFind (Attributes, Name); + if (I < 0) { + /* Not found */ + return 0; + } + + /* Get the attribute */ + D = CollAtUnchecked (Attributes, I); + + /* Check the type */ + if (D->Type != Type) { + /* Wrong type. ### Warn here? */ + return 0; + } + + /* Remove the attribute and return it */ + CollDelete (Attributes, I); + return D; +} + + + +int CfgDataGetId (Collection* Attributes, const char* Name, char** Id) +/* Search CfgInfo for an attribute with the given name and type "id". If + * found, remove it from the configuration, copy it into Buf and return + * true. If not found, return false. + */ +{ + CfgData* D = CfgDataGetTyped (Attributes, Name, CfgDataId); + if (D == 0) { + /* Not found or wrong type */ + return 0; + } + + /* Use the string value and invalidate the type, so FreeCfgData won't + * delete the string. + */ + *Id = D->V.SVal; + D->Type = CfgDataInvalid; + + /* Delete the config data struct */ + FreeCfgData (D); + + /* Success */ + return 1; +} + + + +int CfgDataGetStr (Collection* Attributes, const char* Name, char** S) +/* Search CfgInfo for an attribute with the given name and type "string". + * If found, remove it from the configuration, copy it into Buf and return + * true. If not found, return false. + */ +{ + CfgData* D = CfgDataGetTyped (Attributes, Name, CfgDataString); + if (D == 0) { + /* Not found or wrong type */ + return 0; + } + + /* Use the string value and invalidate the type, so FreeCfgData won't + * delete the string. + */ + *S = D->V.SVal; + D->Type = CfgDataInvalid; + + /* Delete the config data struct */ + FreeCfgData (D); + + /* Success */ + return 1; +} + + + +int CfgDataGetNum (Collection* Attributes, const char* Name, long* Val) +/* Search CfgInfo for an attribute with the given name and type "number". + * If found, remove it from the configuration, copy it into Val and return + * true. If not found, return false. + */ +{ + CfgData* D = CfgDataGetTyped (Attributes, Name, CfgDataString); + if (D == 0) { + /* Not found or wrong type */ + return 0; + } + + /* Return the value to the caller */ + *Val = D->V.IVal; + + /* Delete the config data struct */ + FreeCfgData (D); + + /* Success */ + return 1; +} + + + diff --git a/src/sim65/cfgdata.h b/src/sim65/cfgdata.h index c0ea32b83..655145585 100644 --- a/src/sim65/cfgdata.h +++ b/src/sim65/cfgdata.h @@ -38,6 +38,11 @@ +/* common */ +#include "coll.h" + + + /*****************************************************************************/ /* Data */ /*****************************************************************************/ @@ -50,7 +55,7 @@ struct CfgData { CfgDataInvalid, CfgDataId, CfgDataNumber, - CfgDataString + CfgDataString } Type; /* Type of the value */ union { char* SVal; /* String or id value */ @@ -63,6 +68,45 @@ struct CfgData { +/*****************************************************************************/ +/* Code */ +/*****************************************************************************/ + + + +CfgData* NewCfgData (void); +/* Create and intialize a new CfgData struct, then return it. The function + * uses the current output of the config scanner. + */ + +void FreeCfgData (CfgData* D); +/* Free a config data structure */ + +int CfgDataFind (Collection* Attributes, const char* AttrName); +/* Find the attribute with the given name and return its index. Return -1 if + * the attribute was not found. + */ + +int CfgDataGetId (Collection* Attributes, const char* Name, char** Id); +/* Search CfgInfo for an attribute with the given name and type "id". If + * found, remove it from the configuration, copy it into Buf and return + * true. If not found, return false. + */ + +int CfgDataGetStr (Collection* Attributes, const char* Name, char** S); +/* Search CfgInfo for an attribute with the given name and type "string". + * If found, remove it from the configuration, copy it into Buf and return + * true. If not found, return false. + */ + +int CfgDataGetNum (Collection* Attributes, const char* Name, long* Val); +/* Search CfgInfo for an attribute with the given name and type "number". + * If found, remove it from the configuration, copy it into Val and return + * true. If not found, return false. + */ + + + /* End of cfgdata.h */ #endif diff --git a/src/sim65/chip.c b/src/sim65/chip.c index ddea1fa0d..57e920616 100644 --- a/src/sim65/chip.c +++ b/src/sim65/chip.c @@ -66,9 +66,14 @@ static Collection ChipLibraries = STATIC_COLLECTION_INITIALIZER; static const SimData Sim65Data = { 1, /* MajorVersion */ 1, /* MinorVersion */ - xmalloc, /* void* (*Malloc) (size_t Size); */ - Warning, /* void (*Warning) (const char* Format, ...); */ - Error /* void (*Error) (const char* Format, ...); */ + xmalloc, + xfree, + Warning, + Error, + Internal, + CfgDataGetId, + CfgDataGetStr, + CfgDataGetNum }; diff --git a/src/sim65/chipif.h b/src/sim65/chipif.h index c58136fb4..1badc3696 100644 --- a/src/sim65/chipif.h +++ b/src/sim65/chipif.h @@ -39,7 +39,6 @@ /* sim65 */ -#include "cfgdata.h" #include "chipdata.h" #include "simdata.h" diff --git a/src/sim65/chips/ram.c b/src/sim65/chips/ram.c index 544364cb8..639b05bfa 100644 --- a/src/sim65/chips/ram.c +++ b/src/sim65/chips/ram.c @@ -50,8 +50,7 @@ int InitChip (const struct SimData* Data); /* Initialize the chip, return an error code */ -static void* InitInstance (unsigned Addr, unsigned Range, - const CfgData** Data, unsigned CfgDataCount); +static void* InitInstance (unsigned Addr, unsigned Range, void* CfgInfo); /* Initialize a new chip instance */ static void WriteCtrl (void* Data, unsigned Offs, unsigned char Val); @@ -145,8 +144,7 @@ int InitChip (const struct SimData* Data) -static void* InitInstance (unsigned Addr, unsigned Range, - const CfgData** Data, unsigned CfgDataCount) +static void* InitInstance (unsigned Addr, unsigned Range, void* CfgInfo) /* 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 55a2cf233..5eddd3ca2 100644 --- a/src/sim65/chips/stdio.c +++ b/src/sim65/chips/stdio.c @@ -54,11 +54,9 @@ int InitChip (const struct SimData* Data); /* Initialize the chip, return an error code */ -static void* InitInstance (unsigned Addr, unsigned Range, - const CfgData** Data, unsigned CfgDataCount); +static void* InitInstance (unsigned Addr, unsigned Range, void* CfgInfo); /* Initialize a new chip instance */ - static void Write (void* Data, unsigned Offs, unsigned char Val); /* Write user data */ @@ -131,10 +129,8 @@ int InitChip (const struct SimData* Data) -static void* InitInstance (unsigned Addr, unsigned Range, - const CfgData** Data, unsigned CfgDataCount) +static void* InitInstance (unsigned Addr, unsigned Range, void* CfgInfo) /* Initialize a new chip instance */ - { /* We don't need any instance data */ return 0; diff --git a/src/sim65/config.c b/src/sim65/config.c index c95380dee..b65c9a63a 100644 --- a/src/sim65/config.c +++ b/src/sim65/config.c @@ -83,42 +83,6 @@ struct Location { -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) + AttrLen); - - /* Initialize the fields */ - D->Type = CfgDataInvalid; - D->Line = CfgErrorLine; - D->Col = CfgErrorCol; - memcpy (D->Attr, CfgSVal, AttrLen+1); - - /* Return the new struct */ - return D; -} - - - -static void FreeCfgData (CfgData* D) -/* Free a config data structure */ -{ - if (D->Type == CfgDataString) { - /* Free the string value */ - xfree (D->V.SVal); - } - /* Free the structure */ - xfree (D); -} - - - static void CfgDataCheckType (const CfgData* D, unsigned Type) /* Check the config data type */ { diff --git a/src/sim65/make/gcc.mak b/src/sim65/make/gcc.mak index da7685e1d..b51eecf3c 100644 --- a/src/sim65/make/gcc.mak +++ b/src/sim65/make/gcc.mak @@ -10,7 +10,8 @@ CC = gcc EBIND = emxbind LDFLAGS = -OBJS = chip.o \ +OBJS = cfgdata.o \ + chip.o \ chippath.o \ config.o \ cpucore.o \ diff --git a/src/sim65/scanner.h b/src/sim65/scanner.h index ce0652050..7607310d8 100644 --- a/src/sim65/scanner.h +++ b/src/sim65/scanner.h @@ -37,6 +37,11 @@ #define SCANNER_H + +/* common */ +#include "attrib.h" + + /*****************************************************************************/ /* Data */ diff --git a/src/sim65/simdata.h b/src/sim65/simdata.h index 72424ebf2..915c31c7c 100644 --- a/src/sim65/simdata.h +++ b/src/sim65/simdata.h @@ -51,9 +51,43 @@ struct SimData { unsigned MinorVersion; /* -- Callback functions -- */ + void* (*Malloc) (size_t Size); + /* Allocate a memory block of the given size */ + + void (*Free) (void* Block); + /* Free an allocated memory block */ + void (*Warning) (const char* Format, ...); + /* Print a warning */ + void (*Error) (const char* Format, ...); + /* Print an error and terminate the program */ + + void (*Internal) (const char* Format, ...); + /* Print an internal program error and terminate */ + + int (*GetCfgId) (void* CfgInfo, const char* Name, char** Id); + /* Search CfgInfo for an attribute with the given name and type "id". If + * found, remove it from the configuration, pass a pointer to a dynamically + * allocated string containing the value to Id, and return true. If not + * found, return false. The memory passed in Id must be free by a call to + * Free(); + */ + + int (*GetCfgStr) (void* CfgInfo, const char* Name, char** S); + /* Search CfgInfo for an attribute with the given name and type "id". If + * found, remove it from the configuration, pass a pointer to a dynamically + * allocated string containing the value to Id, and return true. If not + * found, return false. The memory passed in S must be free by a call to + * Free(); + */ + + int (*GetCfgNum) (void* CfgInfo, const char* Name, long* Val); + /* Search CfgInfo for an attribute with the given name and type "number". + * If found, remove it from the configuration, copy it into Val and return + * true. If not found, return false. + */ };