AVR devices register with the factory and can then be instantiated by the factory. Makes adding new devices easier.
Signed-off-by: Onno Kortmann <[email protected]> --- src/Makefile.am | 2 + src/at4433.cpp | 3 ++ src/at8515.cpp | 3 ++ src/atmega128.cpp | 3 ++ src/avrfactory.cpp | 56 ++++++++++++++++++++++++++++++--------------------- src/avrfactory.h | 18 ++++++++++++++++ src/main.cpp | 4 +-- 7 files changed, 63 insertions(+), 26 deletions(-) diff --git a/src/Makefile.am b/src/Makefile.am index 63a7c27..839c73f 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -23,6 +23,7 @@ libavrsim_pp_la_SOURCES = \ atmega128.cpp \ avrdevice.cpp \ avrerror.cpp \ + avrfactory.cpp \ avrmalloc.cpp \ decoder.cpp \ decoder_trace.cpp \ @@ -72,6 +73,7 @@ pkginclude_HEADERS = \ avrdevice.h \ avrdevice_impl.h \ avrerror.h \ + avrfactory.h \ avrmalloc.h \ breakpoint.h \ config_deprecated.h \ diff --git a/src/at4433.cpp b/src/at4433.cpp index 25656d0..894608d 100644 --- a/src/at4433.cpp +++ b/src/at4433.cpp @@ -36,7 +36,9 @@ #include "ioregs.h" //mcucr #include "hwtimer01irq.h" #include "hwad.h" +#include "avrfactory.h" +AVR_REGISTER(AT4433, AvrDevice_at90s4433); @@ -168,3 +170,4 @@ unsigned char AvrDevice_at90s4433::GetRampz() { void AvrDevice_at90s4433::SetRampz(unsigned char val) { cerr << "Illegal Rampz operation in at8515 core"; } + diff --git a/src/at8515.cpp b/src/at8515.cpp index b319666..ce7842d 100644 --- a/src/at8515.cpp +++ b/src/at8515.cpp @@ -28,6 +28,9 @@ #include "hwport.h" #include "hwtimer01irq.h" #include "hwwado.h" +#include "avrfactory.h" + +AVR_REGISTER(AT8515, AvrDevice_at90s8515); diff --git a/src/atmega128.cpp b/src/atmega128.cpp index 0ece665..69df097 100644 --- a/src/atmega128.cpp +++ b/src/atmega128.cpp @@ -32,6 +32,9 @@ #include "hweeprom.h" #include "hwmegatimer0123irq.h" #include "hwwado.h" +#include "avrfactory.h" + +AVR_REGISTER(ATMEGA128, AvrDevice_atmega128); //#include "avrdevice_impl.h" diff --git a/src/avrfactory.cpp b/src/avrfactory.cpp index 4808288..e3cb945 100644 --- a/src/avrfactory.cpp +++ b/src/avrfactory.cpp @@ -21,42 +21,52 @@ * **************************************************************************** */ - -#include <ctype.h> //toupper +#include <map> +#include <iostream> #include "config.h" -#include "at4433.h" -#include "at8515.h" -#include "atmega128.h" #include "avrfactory.h" using namespace std; +typedef map<std::string, AvrFactory::AvrDeviceCreator> AVRDeviceMap; -/* FIXME: Replace this factory with an automatically and pluggable -factory pattern. (-> AVR devices register themselves.) */ +AVRDeviceMap devmap; -AvrDevice* AvrFactory::makeDevice(const std::string in) { - string c(in); //use copy to transform to lower case - transform(c.begin(), c.end(), c.begin(), ::toupper); - - if (c=="AT90S4433") - return new AvrDevice_at90s4433(); - else if (c=="AT90S8515") - return new AvrDevice_at90s8515(); - else if (c=="ATMEGA128") - return new AvrDevice_atmega128(); +void AvrFactory::reg(const std::string name, + AvrDeviceCreator create) { + AVRDeviceMap::iterator i=devmap.find(name); + if (i==devmap.end()) + devmap[name]=create; else { - cerr << "Invalid device specification:" << c << endl; - exit(1); + cerr << "Duplicate device specification " << name << endl; + exit(1); + } +} + +AvrDevice* AvrFactory::makeDevice(const std::string in) { + AVRDeviceMap::iterator i=devmap.find(in); + if (i==devmap.end()) { + cerr << "Invalid device specification: " << in << endl; + exit(1); } + + return devmap[in](); +} + +std::string AvrFactory::supportedDevices() { + std::string ret; + + for (AVRDeviceMap::iterator i=devmap.begin(); + i!=devmap.end(); i++) + ret+=i->first+"\n"; + return ret; } AvrFactory& AvrFactory::instance() { - static AvrFactory *f=0; + static AvrFactory *f; if (!f) { - f=new AvrFactory(); + f=new AvrFactory(); + return *f; } - - return *f; } AvrFactory::AvrFactory() {} diff --git a/src/avrfactory.h b/src/avrfactory.h index 17dbe9b..3a54ecd 100644 --- a/src/avrfactory.h +++ b/src/avrfactory.h @@ -30,6 +30,8 @@ class AvrDevice; class AvrFactory { public: + typedef AvrDevice*(*AvrDeviceCreator)(); + /*! Produces an AVR device according to the configuration string. Right now, the configuration string is simply the full name of the AVR device, like AT90S4433 or ATMEGA128. @@ -38,9 +40,25 @@ class AvrFactory { //! Singleton class access. static AvrFactory& instance(); + static std::string supportedDevices(); + + //! Register a creation static method with the factory + static void reg(const std::string name, + AvrDeviceCreator create); private: AvrFactory(); }; +#define AVR_REGISTER(name, class) \ + struct AVRFactoryEntryMaker_ ## name { \ + public: \ + static AvrDevice *create_one() { \ + return new class; \ + } \ + AVRFactoryEntryMaker_ ## name() { \ + AvrFactory::reg(#name, create_one); \ + } \ +}; \ +AVRFactoryEntryMaker_ ## name maker_ ##name; #endif diff --git a/src/main.cpp b/src/main.cpp index c066d95..3e4885d 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -196,9 +196,7 @@ int main(int argc, char *argv[]) { cout << "-T --terminate <label> or <address> stops simulation if PC runs on <label> or <address>" << endl; cout << endl; cout << "Supported devices:" << endl; - cout << "AT90S4433" << endl; - cout << "AT90S8515" << endl; - cout << "ATMEGA128" << endl; + cout << AvrFactory::supportedDevices(); cout << endl; exit(0); -- 1.5.6.5 _______________________________________________ Simulavr-devel mailing list [email protected] http://lists.nongnu.org/mailman/listinfo/simulavr-devel
