diff options
| author | manuel <manuel@nc8430.lan> | 2009-05-12 23:18:17 +0200 |
|---|---|---|
| committer | manuel <manuel@nc8430.lan> | 2009-05-12 23:18:17 +0200 |
| commit | 45581d3d376e8deed84952cb838ae330549e5241 (patch) | |
| tree | ab23bd5cc1f2e32e95faa372b3b46e69ccb6a3c3 /ue3/mycpu | |
| parent | fe1ef6b47f59899e8687bb1dcc92eba1d103a08f (diff) | |
| download | ooprog-45581d3d376e8deed84952cb838ae330549e5241.tar.gz ooprog-45581d3d376e8deed84952cb838ae330549e5241.tar.bz2 ooprog-45581d3d376e8deed84952cb838ae330549e5241.zip | |
my cpu design
Diffstat (limited to 'ue3/mycpu')
| -rw-r--r-- | ue3/mycpu/Makefile | 8 | ||||
| -rw-r--r-- | ue3/mycpu/ccpu.cpp | 78 | ||||
| -rw-r--r-- | ue3/mycpu/ccpu.h | 167 | ||||
| -rw-r--r-- | ue3/mycpu/cdat.h | 29 | ||||
| -rw-r--r-- | ue3/mycpu/cdisplay.h | 48 | ||||
| -rw-r--r-- | ue3/mycpu/cinstruction.cpp | 46 | ||||
| -rw-r--r-- | ue3/mycpu/cinstruction.h | 98 | ||||
| -rw-r--r-- | ue3/mycpu/cmem.h | 109 | ||||
| -rw-r--r-- | ue3/mycpu/cprogram.cpp | 126 | ||||
| -rw-r--r-- | ue3/mycpu/cprogram.h | 78 | ||||
| -rw-r--r-- | ue3/mycpu/instructions.cpp | 27 | ||||
| -rw-r--r-- | ue3/mycpu/instructions.h | 66 | ||||
| -rw-r--r-- | ue3/mycpu/mycpu.cpp | 152 |
13 files changed, 1022 insertions, 10 deletions
diff --git a/ue3/mycpu/Makefile b/ue3/mycpu/Makefile index 6f57741..16067d1 100644 --- a/ue3/mycpu/Makefile +++ b/ue3/mycpu/Makefile | |||
| @@ -6,13 +6,13 @@ CXX= g++ | |||
| 6 | LD= $(CXX) | 6 | LD= $(CXX) |
| 7 | DEBUGFLAGS= -DNDEBUG | 7 | DEBUGFLAGS= -DNDEBUG |
| 8 | INCLUDE_PATH= -I/usr/local/include | 8 | INCLUDE_PATH= -I/usr/local/include |
| 9 | CXXFLAGS= -O -ansi -pedantic-errors -Wall $(INCLUDE_PATH) $(DEBUGFLAGS) | 9 | CXXFLAGS= -O -ansi -pedantic-errors -Wall -Wno-long-long $(INCLUDE_PATH) $(DEBUGFLAGS) |
| 10 | LDFLAGS= | 10 | LDFLAGS= |
| 11 | LIBS= -L/usr/local/lib | 11 | LIBS= -L/usr/local/lib -lboost_program_options |
| 12 | 12 | ||
| 13 | BIN= mycpu | 13 | BIN= mycpu |
| 14 | OBJS= mycpu.o cdat.o | 14 | OBJS= cinstruction.o instructions.o cprogram.o ccpu.o mycpu.o |
| 15 | HEADERS= cdat.h | 15 | HEADERS= cdat.h cmem.h cinstruction.h instructions.h cprogram.h cdisplay.h ccpu.h |
| 16 | 16 | ||
| 17 | .SUFFIXES: .cpp .o | 17 | .SUFFIXES: .cpp .o |
| 18 | 18 | ||
diff --git a/ue3/mycpu/ccpu.cpp b/ue3/mycpu/ccpu.cpp new file mode 100644 index 0000000..6f364f8 --- /dev/null +++ b/ue3/mycpu/ccpu.cpp | |||
| @@ -0,0 +1,78 @@ | |||
| 1 | /** | ||
| 2 | * @module ccpu | ||
| 3 | * @author Guenther Neuwirth (0626638), Manuel Mausz (0728348) | ||
| 4 | * @brief TODO | ||
| 5 | * @date 10.05.2009 | ||
| 6 | */ | ||
| 7 | |||
| 8 | #ifdef DEBUG | ||
| 9 | # include <iostream> | ||
| 10 | # include <iomanip> | ||
| 11 | #endif | ||
| 12 | #include "ccpu.h" | ||
| 13 | |||
| 14 | using namespace std; | ||
| 15 | |||
| 16 | CCPU::CCPU(const unsigned cnt) | ||
| 17 | : m_regcnt(cnt), m_memory(NULL), m_program(NULL), m_flagzero(0), m_flagsign(0) | ||
| 18 | { | ||
| 19 | m_registers = new CDat[cnt]; | ||
| 20 | for(unsigned i = 0; i < cnt; ++i) | ||
| 21 | m_registers[i] = 0; | ||
| 22 | } | ||
| 23 | |||
| 24 | /*----------------------------------------------------------------------------*/ | ||
| 25 | |||
| 26 | CCPU::~CCPU() | ||
| 27 | { | ||
| 28 | delete[] m_registers; | ||
| 29 | m_registers = NULL; | ||
| 30 | } | ||
| 31 | |||
| 32 | /*----------------------------------------------------------------------------*/ | ||
| 33 | |||
| 34 | void CCPU::run() | ||
| 35 | { | ||
| 36 | if (m_memory == NULL) | ||
| 37 | throw runtime_error("CPU has no memory"); | ||
| 38 | if (m_program == NULL) | ||
| 39 | throw runtime_error("CPU has no program to execute"); | ||
| 40 | if (m_regcnt == 0) | ||
| 41 | throw runtime_error("CPU has no registers"); | ||
| 42 | |||
| 43 | bool run = true; | ||
| 44 | while(run) | ||
| 45 | { | ||
| 46 | unsigned pc = static_cast<unsigned>(m_registers[0]); | ||
| 47 | |||
| 48 | /* end of the program reached */ | ||
| 49 | if (pc == m_program->size()) | ||
| 50 | return; | ||
| 51 | |||
| 52 | /* pc is out of bound */ | ||
| 53 | if (pc > m_program->size()) | ||
| 54 | throw runtime_error("Programcounter is out of bound"); | ||
| 55 | |||
| 56 | /* execute instruction */ | ||
| 57 | m_program->at(pc)->execute(this); | ||
| 58 | ++m_registers[0]; | ||
| 59 | } | ||
| 60 | |||
| 61 | cout << "LALA" << endl; | ||
| 62 | } | ||
| 63 | |||
| 64 | /*----------------------------------------------------------------------------*/ | ||
| 65 | |||
| 66 | #if DEBUG | ||
| 67 | void CCPU::dumpRegisters(std::ostream& out) | ||
| 68 | { | ||
| 69 | out << "[REGISTER DUMP]" << endl; | ||
| 70 | for(unsigned i = 0; i < getRegisterCount(); ++i) | ||
| 71 | { | ||
| 72 | out << "[" << std::setw(4) << std::setfill('0') << i << "] " | ||
| 73 | << m_registers[i] << endl; | ||
| 74 | } | ||
| 75 | } | ||
| 76 | #endif | ||
| 77 | |||
| 78 | /* vim: set et sw=2 ts=2: */ | ||
diff --git a/ue3/mycpu/ccpu.h b/ue3/mycpu/ccpu.h new file mode 100644 index 0000000..e28a7cc --- /dev/null +++ b/ue3/mycpu/ccpu.h | |||
| @@ -0,0 +1,167 @@ | |||
| 1 | /** | ||
| 2 | * @module ccpu | ||
| 3 | * @author Guenther Neuwirth (0626638), Manuel Mausz (0728348) | ||
| 4 | * @brief TODO | ||
| 5 | * @date 10.05.2009 | ||
| 6 | */ | ||
| 7 | |||
| 8 | #ifndef CCPU_H | ||
| 9 | #define CCPU_H 1 | ||
| 10 | |||
| 11 | #include <vector> | ||
| 12 | #include <iostream> | ||
| 13 | #include "cdat.h" | ||
| 14 | #include "cmem.h" | ||
| 15 | #include "cprogram.h" | ||
| 16 | |||
| 17 | /** | ||
| 18 | * @class CCPU | ||
| 19 | * | ||
| 20 | * TODO | ||
| 21 | */ | ||
| 22 | class CCPU | ||
| 23 | { | ||
| 24 | public: | ||
| 25 | /** | ||
| 26 | * @method CCPU | ||
| 27 | * @brief Default ctor | ||
| 28 | * @param cnt number of registers to allocate for this cpu | ||
| 29 | * @return - | ||
| 30 | * @globalvars none | ||
| 31 | * @exception none | ||
| 32 | * @conditions none | ||
| 33 | */ | ||
| 34 | CCPU(const unsigned cnt); | ||
| 35 | |||
| 36 | /** | ||
| 37 | * @method ~CCPU | ||
| 38 | * @brief Default dtor | ||
| 39 | * @param - | ||
| 40 | * @return - | ||
| 41 | * @globalvars none | ||
| 42 | * @exception none | ||
| 43 | * @conditions none | ||
| 44 | */ | ||
| 45 | ~CCPU(); | ||
| 46 | |||
| 47 | /** | ||
| 48 | * @method getRegisterCount | ||
| 49 | * @brief get number of registers | ||
| 50 | * @param - | ||
| 51 | * @return number of registers | ||
| 52 | * @globalvars none | ||
| 53 | * @exception none | ||
| 54 | * @conditions none | ||
| 55 | */ | ||
| 56 | const unsigned getRegisterCount() | ||
| 57 | { | ||
| 58 | return m_regcnt; | ||
| 59 | } | ||
| 60 | |||
| 61 | /** | ||
| 62 | * @method getRegisters | ||
| 63 | * @brief get pointer to registers array | ||
| 64 | * @param - | ||
| 65 | * @return pointer to registers array | ||
| 66 | * @globalvars none | ||
| 67 | * @exception none | ||
| 68 | * @conditions none | ||
| 69 | */ | ||
| 70 | CDat *getRegisters() | ||
| 71 | { | ||
| 72 | return m_registers; | ||
| 73 | } | ||
| 74 | |||
| 75 | /** | ||
| 76 | * @method setMemory | ||
| 77 | * @brief set memory of cpu | ||
| 78 | * @param memory pointer to memory | ||
| 79 | * @return - | ||
| 80 | * @globalvars none | ||
| 81 | * @exception none | ||
| 82 | * @conditions none | ||
| 83 | */ | ||
| 84 | void setMemory(const CMem *memory) | ||
| 85 | { | ||
| 86 | m_memory = memory; | ||
| 87 | } | ||
| 88 | |||
| 89 | /** | ||
| 90 | * @method getMemory | ||
| 91 | * @brief get pointer to memory | ||
| 92 | * @param - | ||
| 93 | * @return pointer to memory | ||
| 94 | * @globalvars none | ||
| 95 | * @exception none | ||
| 96 | * @conditions none | ||
| 97 | */ | ||
| 98 | const CMem *getMemory() | ||
| 99 | { | ||
| 100 | return m_memory; | ||
| 101 | } | ||
| 102 | |||
| 103 | /** | ||
| 104 | * @method setProgram | ||
| 105 | * @brief set program to execute | ||
| 106 | * @param memory pointer to program | ||
| 107 | * @return - | ||
| 108 | * @globalvars none | ||
| 109 | * @exception none | ||
| 110 | * @conditions none | ||
| 111 | */ | ||
| 112 | void setProgram(const CProgram *program) | ||
| 113 | { | ||
| 114 | m_program = program; | ||
| 115 | } | ||
| 116 | |||
| 117 | /** | ||
| 118 | * @method getProgram | ||
| 119 | * @brief get pointer to program | ||
| 120 | * @param - | ||
| 121 | * @return pointer to program | ||
| 122 | * @globalvars none | ||
| 123 | * @exception none | ||
| 124 | * @conditions none | ||
| 125 | */ | ||
| 126 | const CProgram *getProgram() | ||
| 127 | { | ||
| 128 | return m_program; | ||
| 129 | } | ||
| 130 | |||
| 131 | /** | ||
| 132 | * @method run | ||
| 133 | * @brief execute current program | ||
| 134 | * @param - | ||
| 135 | * @return - | ||
| 136 | * @globalvars none | ||
| 137 | * @exception runtime_error | ||
| 138 | * @conditions none | ||
| 139 | */ | ||
| 140 | void run(); | ||
| 141 | |||
| 142 | #if DEBUG | ||
| 143 | /** | ||
| 144 | * @method dumpRegisters | ||
| 145 | * @brief dump content of registers to outputstream | ||
| 146 | * @param out outputstream to write to | ||
| 147 | * @return void | ||
| 148 | * @globalvars none | ||
| 149 | * @exception none | ||
| 150 | * @conditions none | ||
| 151 | */ | ||
| 152 | void dumpRegisters(std::ostream& out); | ||
| 153 | #endif | ||
| 154 | |||
| 155 | private: | ||
| 156 | /* members */ | ||
| 157 | CDat *m_registers; | ||
| 158 | unsigned m_regcnt; | ||
| 159 | const CMem *m_memory; | ||
| 160 | const CProgram *m_program; | ||
| 161 | bool m_flagzero; | ||
| 162 | bool m_flagsign; | ||
| 163 | }; | ||
| 164 | |||
| 165 | #endif | ||
| 166 | |||
| 167 | /* vim: set et sw=2 ts=2: */ | ||
diff --git a/ue3/mycpu/cdat.h b/ue3/mycpu/cdat.h index dc8a07c..365bd88 100644 --- a/ue3/mycpu/cdat.h +++ b/ue3/mycpu/cdat.h | |||
| @@ -1,12 +1,12 @@ | |||
| 1 | /** | 1 | /** |
| 2 | * @module cdat | 2 | * @module cdat |
| 3 | * @author Guenther Neuwirth (0626638), Manuel Mausz (0728348) | 3 | * @author Guenther Neuwirth (0626638), Manuel Mausz (0728348) |
| 4 | * @brief Datatype template for mycpu | 4 | * @brief Datatype template and datatype definition for CCPU and CMem |
| 5 | * @date 10.05.2009 | 5 | * @date 10.05.2009 |
| 6 | */ | 6 | */ |
| 7 | 7 | ||
| 8 | #ifndef CDATT_H | 8 | #ifndef CDAT_H |
| 9 | #define CDATT_H | 9 | #define CDAT_H 1 |
| 10 | 10 | ||
| 11 | #include <boost/operators.hpp> | 11 | #include <boost/operators.hpp> |
| 12 | #include <iostream> | 12 | #include <iostream> |
| @@ -14,7 +14,7 @@ | |||
| 14 | /** | 14 | /** |
| 15 | * @class CDatT | 15 | * @class CDatT |
| 16 | * | 16 | * |
| 17 | * Datatype template for mycpu. | 17 | * Datatype template for CCPU and CMem. |
| 18 | */ | 18 | */ |
| 19 | template <class T> | 19 | template <class T> |
| 20 | class CDatT | 20 | class CDatT |
| @@ -86,6 +86,20 @@ class CDatT | |||
| 86 | } | 86 | } |
| 87 | 87 | ||
| 88 | /** | 88 | /** |
| 89 | * @method operator T | ||
| 90 | * @brief convert to T | ||
| 91 | * @param - | ||
| 92 | * @return T | ||
| 93 | * @globalvars none | ||
| 94 | * @exception none | ||
| 95 | * @conditions none | ||
| 96 | */ | ||
| 97 | operator T() | ||
| 98 | { | ||
| 99 | return m_value; | ||
| 100 | } | ||
| 101 | |||
| 102 | /** | ||
| 89 | * @method operator< | 103 | * @method operator< |
| 90 | * @brief implementation of operator < | 104 | * @brief implementation of operator < |
| 91 | * @param reference to CDatT | 105 | * @param reference to CDatT |
| @@ -300,8 +314,11 @@ class CDatT | |||
| 300 | T m_value; | 314 | T m_value; |
| 301 | }; | 315 | }; |
| 302 | 316 | ||
| 303 | 317 | /** | |
| 304 | /** define CDat */ | 318 | * @class CDat |
| 319 | * | ||
| 320 | * Datatype for CCPU and CMem | ||
| 321 | */ | ||
| 305 | typedef CDatT<int> CDat; | 322 | typedef CDatT<int> CDat; |
| 306 | 323 | ||
| 307 | #endif | 324 | #endif |
diff --git a/ue3/mycpu/cdisplay.h b/ue3/mycpu/cdisplay.h new file mode 100644 index 0000000..629ec88 --- /dev/null +++ b/ue3/mycpu/cdisplay.h | |||
| @@ -0,0 +1,48 @@ | |||
| 1 | /** | ||
| 2 | * @module cdisplay | ||
| 3 | * @author Guenther Neuwirth (0626638), Manuel Mausz (0728348) | ||
| 4 | * @brief TODO | ||
| 5 | * @date 10.05.2009 | ||
| 6 | */ | ||
| 7 | |||
| 8 | #ifndef CDISPLAY_H | ||
| 9 | #define CDISPLAY_H #1 | ||
| 10 | |||
| 11 | /** | ||
| 12 | * @class CDisplay | ||
| 13 | * | ||
| 14 | * TODO | ||
| 15 | */ | ||
| 16 | class CDisplay | ||
| 17 | { | ||
| 18 | public: | ||
| 19 | /** | ||
| 20 | * @method CDisplay | ||
| 21 | * @brief Default ctor | ||
| 22 | * @param - | ||
| 23 | * @return - | ||
| 24 | * @globalvars none | ||
| 25 | * @exception none | ||
| 26 | * @conditions none | ||
| 27 | */ | ||
| 28 | CDisplay() | ||
| 29 | {}; | ||
| 30 | |||
| 31 | /** | ||
| 32 | * @method ~CDisplay | ||
| 33 | * @brief Default dtor | ||
| 34 | * @param - | ||
| 35 | * @return - | ||
| 36 | * @globalvars none | ||
| 37 | * @exception none | ||
| 38 | * @conditions none | ||
| 39 | */ | ||
| 40 | ~CDisplay(); | ||
| 41 | |||
| 42 | private: | ||
| 43 | /* members */ | ||
| 44 | }; | ||
| 45 | |||
| 46 | #endif | ||
| 47 | |||
| 48 | /* vim: set et sw=2 ts=2: */ | ||
diff --git a/ue3/mycpu/cinstruction.cpp b/ue3/mycpu/cinstruction.cpp new file mode 100644 index 0000000..32bdd2f --- /dev/null +++ b/ue3/mycpu/cinstruction.cpp | |||
| @@ -0,0 +1,46 @@ | |||
| 1 | /** | ||
| 2 | * @module cinstruction | ||
| 3 | * @author Guenther Neuwirth (0626638), Manuel Mausz (0728348) | ||
| 4 | * @brief TODO | ||
| 5 | * @date 10.05.2009 | ||
| 6 | */ | ||
| 7 | |||
| 8 | #include <sstream> | ||
| 9 | #include <stdexcept> | ||
| 10 | #include <boost/lexical_cast.hpp> | ||
| 11 | #include "cinstruction.h" | ||
| 12 | #include "ccpu.h" | ||
| 13 | |||
| 14 | using namespace std; | ||
| 15 | |||
| 16 | const unsigned CInstruction::parseRegister(const std::string& str) | ||
| 17 | { | ||
| 18 | unsigned reg; | ||
| 19 | if (str.length() < 2 || str[0] != 'R') | ||
| 20 | throw runtime_error("Invalid syntax of register"); | ||
| 21 | |||
| 22 | try | ||
| 23 | { | ||
| 24 | reg = boost::lexical_cast<unsigned>(str.substr(1)); | ||
| 25 | } | ||
| 26 | catch(boost::bad_lexical_cast& ex) | ||
| 27 | { | ||
| 28 | throw runtime_error("Invalid syntax of register"); | ||
| 29 | } | ||
| 30 | |||
| 31 | return reg; | ||
| 32 | } | ||
| 33 | |||
| 34 | /*----------------------------------------------------------------------------*/ | ||
| 35 | |||
| 36 | inline void CInstruction::checkRegister(CCPU *cpu, unsigned regidx) | ||
| 37 | { | ||
| 38 | if (regidx >= cpu->getRegisterCount()) | ||
| 39 | { | ||
| 40 | stringstream sstr; | ||
| 41 | sstr << "Register R" << regidx << " doesn't exist (out of bound)"; | ||
| 42 | throw runtime_error(sstr.str()); | ||
| 43 | } | ||
| 44 | } | ||
| 45 | |||
| 46 | /* vim: set et sw=2 ts=2: */ | ||
diff --git a/ue3/mycpu/cinstruction.h b/ue3/mycpu/cinstruction.h new file mode 100644 index 0000000..b16c067 --- /dev/null +++ b/ue3/mycpu/cinstruction.h | |||
| @@ -0,0 +1,98 @@ | |||
| 1 | /** | ||
| 2 | * @module cinstruction | ||
| 3 | * @author Guenther Neuwirth (0626638), Manuel Mausz (0728348) | ||
| 4 | * @brief TODO | ||
| 5 | * @date 10.05.2009 | ||
| 6 | */ | ||
| 7 | |||
| 8 | #ifndef CINSTRUCTION_H | ||
| 9 | #define CINSTRUCTION_H 1 | ||
| 10 | |||
| 11 | #include <iostream> | ||
| 12 | #include <list> | ||
| 13 | //#include "ccpu.h" | ||
| 14 | |||
| 15 | /* declare CCPU */ | ||
| 16 | class CCPU; | ||
| 17 | |||
| 18 | /** | ||
| 19 | * @class CInstruction | ||
| 20 | * | ||
| 21 | * TODO | ||
| 22 | */ | ||
| 23 | class CInstruction | ||
| 24 | { | ||
| 25 | public: | ||
| 26 | /** | ||
| 27 | * @method CInstruction | ||
| 28 | * @brief Default ctor | ||
| 29 | * @param - | ||
| 30 | * @return - | ||
| 31 | * @globalvars none | ||
| 32 | * @exception none | ||
| 33 | * @conditions none | ||
| 34 | */ | ||
| 35 | CInstruction(std::string name) | ||
| 36 | : m_name(name) | ||
| 37 | {}; | ||
| 38 | |||
| 39 | /** | ||
| 40 | * @method ~CInstruction | ||
| 41 | * @brief Default dtor | ||
| 42 | * @param - | ||
| 43 | * @return - | ||
| 44 | * @globalvars none | ||
| 45 | * @exception none | ||
| 46 | * @conditions none | ||
| 47 | */ | ||
| 48 | virtual ~CInstruction() | ||
| 49 | {}; | ||
| 50 | |||
| 51 | /* TODO */ | ||
| 52 | virtual bool operator==(std::string& name) | ||
| 53 | { | ||
| 54 | return name == m_name; | ||
| 55 | } | ||
| 56 | |||
| 57 | /* TODO */ | ||
| 58 | virtual const std::string& getName() | ||
| 59 | { | ||
| 60 | return m_name; | ||
| 61 | } | ||
| 62 | |||
| 63 | /* TODO */ | ||
| 64 | virtual std::ostream& dump(std::ostream& stream) | ||
| 65 | { | ||
| 66 | stream << m_name; | ||
| 67 | return stream; | ||
| 68 | } | ||
| 69 | |||
| 70 | /* TODO */ | ||
| 71 | friend std::ostream& operator<<(std::ostream& stream, CInstruction& instr) | ||
| 72 | { | ||
| 73 | return instr.dump(stream); | ||
| 74 | } | ||
| 75 | |||
| 76 | /* TODO */ | ||
| 77 | virtual const unsigned parseRegister(const std::string& str); | ||
| 78 | |||
| 79 | /* TODO */ | ||
| 80 | virtual void checkRegister(CCPU *cpu, unsigned regidx); | ||
| 81 | |||
| 82 | /* TODO */ | ||
| 83 | virtual CInstruction *factory() = 0; | ||
| 84 | |||
| 85 | /* TODO */ | ||
| 86 | virtual void compile(std::list<std::string>& params) = 0; | ||
| 87 | |||
| 88 | /* TODO */ | ||
| 89 | virtual void execute(CCPU *cpu) = 0; | ||
| 90 | |||
| 91 | protected: | ||
| 92 | /* members */ | ||
| 93 | std::string m_name; | ||
| 94 | }; | ||
| 95 | |||
| 96 | #endif | ||
| 97 | |||
| 98 | /* vim: set et sw=2 ts=2: */ | ||
diff --git a/ue3/mycpu/cmem.h b/ue3/mycpu/cmem.h new file mode 100644 index 0000000..5045c34 --- /dev/null +++ b/ue3/mycpu/cmem.h | |||
| @@ -0,0 +1,109 @@ | |||
| 1 | /** | ||
| 2 | * @module cmem | ||
| 3 | * @author Guenther Neuwirth (0626638), Manuel Mausz (0728348) | ||
| 4 | * @brief Memory template and memory definition for CCPU | ||
| 5 | * @date 10.05.2009 | ||
| 6 | */ | ||
| 7 | |||
| 8 | #ifndef CMEM_H | ||
| 9 | #define CMEM_H 1 | ||
| 10 | |||
| 11 | #include <vector> | ||
| 12 | #include <istream> | ||
| 13 | #include <sstream> | ||
| 14 | #include <stdexcept> | ||
| 15 | #include <boost/lexical_cast.hpp> | ||
| 16 | #ifdef DEBUG | ||
| 17 | # include <iostream> | ||
| 18 | # include <iomanip> | ||
| 19 | #endif | ||
| 20 | #include "cdat.h" | ||
| 21 | |||
| 22 | /** | ||
| 23 | * @class CVectorMem | ||
| 24 | * | ||
| 25 | * Extends std::vector template for use as memory for CCPU. | ||
| 26 | */ | ||
| 27 | template <class T, class Allocator=std::allocator<T> > | ||
| 28 | class CVectorMem | ||
| 29 | : public std::vector<T, Allocator> | ||
| 30 | { | ||
| 31 | public: | ||
| 32 | using std::vector<T, Allocator>::size; | ||
| 33 | using std::vector<T, Allocator>::at; | ||
| 34 | |||
| 35 | /** | ||
| 36 | * @method initialize | ||
| 37 | * @brief initialize the vector with the content of istream. istream is | ||
| 38 | * read per line. empty lines will add unitialized elements. | ||
| 39 | * @param in inputstream to read from | ||
| 40 | * @return void | ||
| 41 | * @globalvars none | ||
| 42 | * @exception std::runtime_error | ||
| 43 | * @conditions none | ||
| 44 | */ | ||
| 45 | void initialize(std::istream& in) | ||
| 46 | { | ||
| 47 | if (!in.good()) | ||
| 48 | return; | ||
| 49 | |||
| 50 | std::string line; | ||
| 51 | unsigned i = 0; | ||
| 52 | while (!in.eof() && in.good()) | ||
| 53 | { | ||
| 54 | ++i; | ||
| 55 | std::getline(in, line); | ||
| 56 | |||
| 57 | /* skip last line if it's empty */ | ||
| 58 | if (line.empty() && in.eof()) | ||
| 59 | break; | ||
| 60 | |||
| 61 | T value; | ||
| 62 | try | ||
| 63 | { | ||
| 64 | if (!line.empty()) | ||
| 65 | value = boost::lexical_cast<T>(line); | ||
| 66 | } | ||
| 67 | catch(boost::bad_lexical_cast& ex) | ||
| 68 | { | ||
| 69 | std::stringstream sstr; | ||
| 70 | sstr << "Unable to convert input (line " << i << "): " << ex.what(); | ||
| 71 | throw std::runtime_error(sstr.str()); | ||
| 72 | } | ||
| 73 | |||
| 74 | push_back(value); | ||
| 75 | } | ||
| 76 | } | ||
| 77 | |||
| 78 | #if DEBUG | ||
| 79 | /** | ||
| 80 | * @method dump | ||
| 81 | * @brief dumps contents of vector to outputstream | ||
| 82 | * @param out outputstream to write to | ||
| 83 | * @return void | ||
| 84 | * @globalvars none | ||
| 85 | * @exception none | ||
| 86 | * @conditions none | ||
| 87 | */ | ||
| 88 | void dump(std::ostream& out) | ||
| 89 | { | ||
| 90 | out << "[MEMORY DUMP]" << std::endl; | ||
| 91 | for(unsigned i = 0; i < size(); ++i) | ||
| 92 | { | ||
| 93 | out << "[" << std::setw(4) << std::setfill('0') << i << "] " | ||
| 94 | << at(i) << std::endl; | ||
| 95 | } | ||
| 96 | } | ||
| 97 | #endif | ||
| 98 | }; | ||
| 99 | |||
| 100 | /** | ||
| 101 | * @class CMem | ||
| 102 | * | ||
| 103 | * Memory definition for CCPU | ||
| 104 | */ | ||
| 105 | typedef CVectorMem<CDat> CMem; | ||
| 106 | |||
| 107 | #endif | ||
| 108 | |||
| 109 | /* vim: set et sw=2 ts=2: */ | ||
diff --git a/ue3/mycpu/cprogram.cpp b/ue3/mycpu/cprogram.cpp new file mode 100644 index 0000000..03d4c30 --- /dev/null +++ b/ue3/mycpu/cprogram.cpp | |||
| @@ -0,0 +1,126 @@ | |||
| 1 | /** | ||
| 2 | * @module cprogram | ||
| 3 | * @author Guenther Neuwirth (0626638), Manuel Mausz (0728348) | ||
| 4 | * @brief TODO | ||
| 5 | * @date 12.05.2009 | ||
| 6 | */ | ||
| 7 | |||
| 8 | #include <boost/algorithm/string.hpp> | ||
| 9 | #include <boost/algorithm/string/split.hpp> | ||
| 10 | #ifdef DEBUG | ||
| 11 | # include <iostream> | ||
| 12 | # include <iomanip> | ||
| 13 | #endif | ||
| 14 | #include "cprogram.h" | ||
| 15 | #include "instructions.h" | ||
| 16 | |||
| 17 | using namespace std; | ||
| 18 | |||
| 19 | CProgram::CProgram() | ||
| 20 | { | ||
| 21 | m_instrset.insert(new CInstructionInc); | ||
| 22 | } | ||
| 23 | |||
| 24 | /*----------------------------------------------------------------------------*/ | ||
| 25 | |||
| 26 | CProgram::~CProgram() | ||
| 27 | { | ||
| 28 | /* free instruction set */ | ||
| 29 | set<CInstruction *>::iterator it; | ||
| 30 | for (it = m_instrset.begin(); it != m_instrset.end(); ++it) | ||
| 31 | delete *it; | ||
| 32 | |||
| 33 | /* free instruction */ | ||
| 34 | for (iterator it = begin(); it != end(); ++it) | ||
| 35 | delete *it; | ||
| 36 | } | ||
| 37 | |||
| 38 | /*----------------------------------------------------------------------------*/ | ||
| 39 | |||
| 40 | void CProgram::compile(std::istream& in) | ||
| 41 | { | ||
| 42 | if (!in.good()) | ||
| 43 | return; | ||
| 44 | |||
| 45 | string line; | ||
| 46 | unsigned i = 0; | ||
| 47 | while (!in.eof() && in.good()) | ||
| 48 | { | ||
| 49 | ++i; | ||
| 50 | |||
| 51 | /* read stream per line */ | ||
| 52 | getline(in, line); | ||
| 53 | if (line.empty()) | ||
| 54 | continue; | ||
| 55 | |||
| 56 | boost::trim(line); | ||
| 57 | |||
| 58 | /* ignore comments */ | ||
| 59 | if (line.find_first_of('#') == 0) | ||
| 60 | continue; | ||
| 61 | |||
| 62 | /* get instruction name */ | ||
| 63 | size_t pos = line.find_first_of(' '); | ||
| 64 | string instrname = line.substr(0, pos); | ||
| 65 | |||
| 66 | /* search and create instruction */ | ||
| 67 | CInstruction *instrptr = NULL; | ||
| 68 | set<CInstruction *>::iterator it; | ||
| 69 | for (it = m_instrset.begin(); it != m_instrset.end(); ++it) | ||
| 70 | { | ||
| 71 | if (*(*it) == instrname) | ||
| 72 | { | ||
| 73 | instrptr = *it; | ||
| 74 | break; | ||
| 75 | } | ||
| 76 | } | ||
| 77 | if (instrptr == NULL) | ||
| 78 | { | ||
| 79 | stringstream sstr; | ||
| 80 | sstr << "Unknown instruction '" << instrname << "' on line " << i << "."; | ||
| 81 | throw runtime_error(sstr.str()); | ||
| 82 | } | ||
| 83 | |||
| 84 | /* create instruction */ | ||
| 85 | CInstruction *instr = instrptr->factory(); | ||
| 86 | |||
| 87 | /* parse instruction parameters */ | ||
| 88 | string params = (pos == string::npos) ? "" : line.substr(pos + 1); | ||
| 89 | boost::trim(params); | ||
| 90 | list<string> instrparams; | ||
| 91 | boost::split(instrparams, params, boost::is_any_of(", "), boost::token_compress_on); | ||
| 92 | |||
| 93 | /* let instruction parse the parameters. catch+throw exception */ | ||
| 94 | try | ||
| 95 | { | ||
| 96 | instr->compile(instrparams); | ||
| 97 | } | ||
| 98 | catch(runtime_error& ex) | ||
| 99 | { | ||
| 100 | stringstream sstr; | ||
| 101 | sstr << "Unable to compile instruction '" << instrname | ||
| 102 | << "' (line " << i << "): " << ex.what(); | ||
| 103 | throw runtime_error(sstr.str()); | ||
| 104 | } | ||
| 105 | |||
| 106 | push_back(instr); | ||
| 107 | } | ||
| 108 | } | ||
| 109 | |||
| 110 | /*----------------------------------------------------------------------------*/ | ||
| 111 | |||
| 112 | #if DEBUG | ||
| 113 | void CProgram::dump(std::ostream& out) | ||
| 114 | { | ||
| 115 | out << "[PROGRAM DUMP]" << endl; | ||
| 116 | unsigned i = 0; | ||
| 117 | for(iterator it = begin(); it < end(); ++it) | ||
| 118 | { | ||
| 119 | out << "[" << std::setw(4) << std::setfill('0') << i << "] " | ||
| 120 | << *(*it) << endl; | ||
| 121 | ++i; | ||
| 122 | } | ||
| 123 | } | ||
| 124 | #endif | ||
| 125 | |||
| 126 | /* vim: set et sw=2 ts=2: */ | ||
diff --git a/ue3/mycpu/cprogram.h b/ue3/mycpu/cprogram.h new file mode 100644 index 0000000..bf161b8 --- /dev/null +++ b/ue3/mycpu/cprogram.h | |||
| @@ -0,0 +1,78 @@ | |||
| 1 | /** | ||
| 2 | * @module cprogram | ||
| 3 | * @author Guenther Neuwirth (0626638), Manuel Mausz (0728348) | ||
| 4 | * @brief TODO | ||
| 5 | * @date 10.05.2009 | ||
| 6 | */ | ||
| 7 | |||
| 8 | #ifndef CPROGRAM_H | ||
| 9 | #define CPROGRAM_H 1 | ||
| 10 | |||
| 11 | #include <vector> | ||
| 12 | #include <set> | ||
| 13 | #include "cinstruction.h" | ||
| 14 | |||
| 15 | /** | ||
| 16 | * @class CProgram | ||
| 17 | * | ||
| 18 | * TODO | ||
| 19 | */ | ||
| 20 | class CProgram | ||
| 21 | : public std::vector<CInstruction *> | ||
| 22 | { | ||
| 23 | public: | ||
| 24 | /** | ||
| 25 | * @method CProgram | ||
| 26 | * @brief Default ctor | ||
| 27 | * @param - | ||
| 28 | * @return - | ||
| 29 | * @globalvars none | ||
| 30 | * @exception none | ||
| 31 | * @conditions none | ||
| 32 | */ | ||
| 33 | CProgram(); | ||
| 34 | |||
| 35 | /** | ||
| 36 | * @method ~CProgram | ||
| 37 | * @brief Default dtor | ||
| 38 | * @param - | ||
| 39 | * @return - | ||
| 40 | * @globalvars none | ||
| 41 | * @exception none | ||
| 42 | * @conditions none | ||
| 43 | */ | ||
| 44 | ~CProgram(); | ||
| 45 | |||
| 46 | /** | ||
| 47 | * @method compile | ||
| 48 | * @brief create instructions from parsing stream | ||
| 49 | * @param in inputstream to read from | ||
| 50 | * @return void | ||
| 51 | * @globalvars none | ||
| 52 | * @exception std::runtime_error | ||
| 53 | * @conditions none | ||
| 54 | */ | ||
| 55 | void compile(std::istream& in); | ||
| 56 | |||
| 57 | #if DEBUG | ||
| 58 | /** | ||
| 59 | * @method dump | ||
| 60 | * @brief dumps contents to outputstream | ||
| 61 | * @param out outputstream to write to | ||
| 62 | * @return void | ||
| 63 | * @globalvars none | ||
| 64 | * @exception none | ||
| 65 | * @conditions none | ||
| 66 | */ | ||
| 67 | void dump(std::ostream& out); | ||
| 68 | #endif | ||
| 69 | |||
| 70 | private: | ||
| 71 | /* members */ | ||
| 72 | /** set of known instructions */ | ||
| 73 | std::set<CInstruction *> m_instrset; | ||
| 74 | }; | ||
| 75 | |||
| 76 | #endif | ||
| 77 | |||
| 78 | /* vim: set et sw=2 ts=2: */ | ||
diff --git a/ue3/mycpu/instructions.cpp b/ue3/mycpu/instructions.cpp new file mode 100644 index 0000000..c283e57 --- /dev/null +++ b/ue3/mycpu/instructions.cpp | |||
| @@ -0,0 +1,27 @@ | |||
| 1 | /** | ||
| 2 | * @module instructions | ||
| 3 | * @author Guenther Neuwirth (0626638), Manuel Mausz (0728348) | ||
| 4 | * @brief TODO | ||
| 5 | * @date 10.05.2009 | ||
| 6 | */ | ||
| 7 | |||
| 8 | #include "instructions.h" | ||
| 9 | |||
| 10 | using namespace std; | ||
| 11 | |||
| 12 | void CInstructionInc::compile(std::list<std::string>& params) | ||
| 13 | { | ||
| 14 | if (params.size() != 1) | ||
| 15 | throw runtime_error("Invalid paramater count - must be 1"); | ||
| 16 | m_regidx1 = parseRegister(params.front()); | ||
| 17 | } | ||
| 18 | |||
| 19 | /*----------------------------------------------------------------------------*/ | ||
| 20 | |||
| 21 | void CInstructionInc::execute(CCPU *cpu) | ||
| 22 | { | ||
| 23 | checkRegister(cpu, m_regidx1); | ||
| 24 | cpu->getRegisters()[m_regidx1]++; | ||
| 25 | } | ||
| 26 | |||
| 27 | /* vim: set et sw=2 ts=2: */ | ||
diff --git a/ue3/mycpu/instructions.h b/ue3/mycpu/instructions.h new file mode 100644 index 0000000..ebd1533 --- /dev/null +++ b/ue3/mycpu/instructions.h | |||
| @@ -0,0 +1,66 @@ | |||
| 1 | /** | ||
| 2 | * @module instructions | ||
| 3 | * @author Guenther Neuwirth (0626638), Manuel Mausz (0728348) | ||
| 4 | * @brief TODO | ||
| 5 | * @date 10.05.2009 | ||
| 6 | */ | ||
| 7 | |||
| 8 | #ifndef INSTRUCTIONS_H | ||
| 9 | #define INSTRUCTIONS_H 1 | ||
| 10 | |||
| 11 | #include "cinstruction.h" | ||
| 12 | #include "ccpu.h" | ||
| 13 | |||
| 14 | /** | ||
| 15 | * @class CInstructionInc | ||
| 16 | * | ||
| 17 | * TODO | ||
| 18 | */ | ||
| 19 | class CInstructionInc | ||
| 20 | : public CInstruction | ||
| 21 | { | ||
| 22 | public: | ||
| 23 | /** | ||
| 24 | * @method CInstruction | ||
| 25 | * @brief Default ctor | ||
| 26 | * @param - | ||
| 27 | * @return - | ||
| 28 | * @globalvars none | ||
| 29 | * @exception none | ||
| 30 | * @conditions none | ||
| 31 | */ | ||
| 32 | CInstructionInc() | ||
| 33 | : CInstruction("inc") | ||
| 34 | {}; | ||
| 35 | |||
| 36 | /** | ||
| 37 | * @method ~CInstruction | ||
| 38 | * @brief Default dtor | ||
| 39 | * @param - | ||
| 40 | * @return - | ||
| 41 | * @globalvars none | ||
| 42 | * @exception none | ||
| 43 | * @conditions none | ||
| 44 | */ | ||
| 45 | ~CInstructionInc() | ||
| 46 | {}; | ||
| 47 | |||
| 48 | /* TODO */ | ||
| 49 | CInstructionInc *factory() | ||
| 50 | { | ||
| 51 | return new CInstructionInc; | ||
| 52 | } | ||
| 53 | |||
| 54 | /* TODO */ | ||
| 55 | void compile(std::list<std::string>& params); | ||
| 56 | |||
| 57 | /* TODO */ | ||
| 58 | void execute(CCPU *cpu); | ||
| 59 | |||
| 60 | protected: | ||
| 61 | unsigned m_regidx1; | ||
| 62 | }; | ||
| 63 | |||
| 64 | #endif | ||
| 65 | |||
| 66 | /* vim: set et sw=2 ts=2: */ | ||
diff --git a/ue3/mycpu/mycpu.cpp b/ue3/mycpu/mycpu.cpp new file mode 100644 index 0000000..af91fe7 --- /dev/null +++ b/ue3/mycpu/mycpu.cpp | |||
| @@ -0,0 +1,152 @@ | |||
| 1 | /** | ||
| 2 | * @module mycpu | ||
| 3 | * @author Guenther Neuwirth (0626638), Manuel Mausz (0728348) | ||
| 4 | * @brief TODO | ||
| 5 | * @date 11.05.2009 | ||
| 6 | * @par Exercise | ||
| 7 | * 3 | ||
| 8 | */ | ||
| 9 | |||
| 10 | #include <boost/program_options.hpp> | ||
| 11 | #include <iostream> | ||
| 12 | #include <fstream> | ||
| 13 | #include <stdexcept> | ||
| 14 | #include <stdlib.h> | ||
| 15 | #include "ccpu.h" | ||
| 16 | #include "cmem.h" | ||
| 17 | #include "cprogram.h" | ||
| 18 | |||
| 19 | using namespace std; | ||
| 20 | namespace po = boost::program_options; | ||
| 21 | |||
| 22 | /** TODO */ | ||
| 23 | void myterminate() | ||
| 24 | { | ||
| 25 | cerr << "Unexpected termination" << endl; | ||
| 26 | abort(); | ||
| 27 | } | ||
| 28 | |||
| 29 | /** | ||
| 30 | * @func main | ||
| 31 | * @brief program entry point | ||
| 32 | * @param argc standard parameter of main | ||
| 33 | * @param argv standard parameter of main | ||
| 34 | * @return 0 on success, not 0 otherwise | ||
| 35 | * @globalvars none | ||
| 36 | * @exception none | ||
| 37 | * @conditions none | ||
| 38 | * | ||
| 39 | * TODO | ||
| 40 | */ | ||
| 41 | int main(int argc, char* argv[]) | ||
| 42 | { | ||
| 43 | //TODO set_terminate(myterminate); | ||
| 44 | string me(argv[0]); | ||
| 45 | |||
| 46 | /* define commandline options */ | ||
| 47 | po::options_description desc("Allowed options"); | ||
| 48 | desc.add_options() | ||
| 49 | ("help,h", "this help message") | ||
| 50 | ("compile,c", po::value<string>(), "input programfile") | ||
| 51 | ("memory,m", po::value<string>(), "input memoryfile"); | ||
| 52 | |||
| 53 | /* parse commandline options */ | ||
| 54 | po::variables_map vm; | ||
| 55 | try | ||
| 56 | { | ||
| 57 | po::store(po::parse_command_line(argc, argv, desc), vm); | ||
| 58 | po::notify(vm); | ||
| 59 | } | ||
| 60 | catch(po::error& ex) | ||
| 61 | { | ||
| 62 | cerr << me << ": Error: " << ex.what() << endl; | ||
| 63 | } | ||
| 64 | |||
| 65 | /* print usage upon request or missing params */ | ||
| 66 | if (vm.count("help") || !vm.count("compile")) | ||
| 67 | { | ||
| 68 | cout << "Usage: " << me << " -c <programfile> [-m <memoryfile>]" << endl; | ||
| 69 | cout << desc << endl; | ||
| 70 | return 0; | ||
| 71 | } | ||
| 72 | |||
| 73 | /* create memory and optionally initialize memory from file */ | ||
| 74 | CMem memory; | ||
| 75 | if (vm.count("memory")) | ||
| 76 | { | ||
| 77 | string memoryfile(vm["memory"].as<string>()); | ||
| 78 | ifstream file(memoryfile.c_str(), ios::in); | ||
| 79 | if (!file.is_open()) | ||
| 80 | { | ||
| 81 | cerr << me << ": Unable to open memoryfile '" << memoryfile << "' for reading." << endl; | ||
| 82 | return 1; | ||
| 83 | } | ||
| 84 | |||
| 85 | try | ||
| 86 | { | ||
| 87 | memory.initialize(file); | ||
| 88 | file.close(); | ||
| 89 | } | ||
| 90 | catch(runtime_error& ex) | ||
| 91 | { | ||
| 92 | file.close(); | ||
| 93 | cerr << me << ": Error while reading from memoryfile:" << endl | ||
| 94 | << " " << ex.what() << endl; | ||
| 95 | return 1; | ||
| 96 | } | ||
| 97 | |||
| 98 | #if DEBUG | ||
| 99 | memory.dump(cout); | ||
| 100 | #endif | ||
| 101 | } | ||
| 102 | |||
| 103 | /* create program instance */ | ||
| 104 | CProgram program; | ||
| 105 | string programfile(vm["compile"].as<string>()); | ||
| 106 | ifstream file(programfile.c_str(), ios::in); | ||
| 107 | if (!file.is_open()) | ||
| 108 | { | ||
| 109 | cerr << me << ": Unable to open programfile '" << programfile << "' for reading." << endl; | ||
| 110 | return 1; | ||
| 111 | } | ||
| 112 | |||
| 113 | try | ||
| 114 | { | ||
| 115 | program.compile(file); | ||
| 116 | file.close(); | ||
| 117 | } | ||
| 118 | catch(runtime_error& ex) | ||
| 119 | { | ||
| 120 | file.close(); | ||
| 121 | cerr << me << ": Error while compiling programfile:" << endl | ||
| 122 | << " " << ex.what() << endl; | ||
| 123 | return 1; | ||
| 124 | } | ||
| 125 | |||
| 126 | #if DEBUG | ||
| 127 | program.dump(cout); | ||
| 128 | #endif | ||
| 129 | |||
| 130 | |||
| 131 | /* create cpu and execute the program */ | ||
| 132 | try | ||
| 133 | { | ||
| 134 | CCPU cpu(256); | ||
| 135 | cpu.setMemory(&memory); | ||
| 136 | cpu.setProgram(&program); | ||
| 137 | cpu.run(); | ||
| 138 | #if DEBUG | ||
| 139 | cpu.dumpRegisters(cout); | ||
| 140 | #endif | ||
| 141 | } | ||
| 142 | catch(runtime_error& ex) | ||
| 143 | { | ||
| 144 | cerr << me << ": Error while executing program:" << endl | ||
| 145 | << " " << ex.what() << endl; | ||
| 146 | return 1; | ||
| 147 | } | ||
| 148 | |||
| 149 | return 0; | ||
| 150 | } | ||
| 151 | |||
| 152 | /* vim: set et sw=2 ts=2: */ | ||
