diff options
Diffstat (limited to 'ue4/mycpu/ccpu.h')
| -rw-r--r-- | ue4/mycpu/ccpu.h | 112 |
1 files changed, 100 insertions, 12 deletions
diff --git a/ue4/mycpu/ccpu.h b/ue4/mycpu/ccpu.h index 6849623..519cee9 100644 --- a/ue4/mycpu/ccpu.h +++ b/ue4/mycpu/ccpu.h | |||
| @@ -3,7 +3,7 @@ | |||
| 3 | * @author Guenther Neuwirth (0626638), Manuel Mausz (0728348) | 3 | * @author Guenther Neuwirth (0626638), Manuel Mausz (0728348) |
| 4 | * @brief CPU implementation. Used as a container for memory and instructions. | 4 | * @brief CPU implementation. Used as a container for memory and instructions. |
| 5 | * Implements a run method to execute the program (= the instructions). | 5 | * Implements a run method to execute the program (= the instructions). |
| 6 | * @date 10.05.2009 | 6 | * @date 26.05.2009 |
| 7 | */ | 7 | */ |
| 8 | 8 | ||
| 9 | #ifndef CCPU_H | 9 | #ifndef CCPU_H |
| @@ -11,10 +11,19 @@ | |||
| 11 | 11 | ||
| 12 | #include <iostream> | 12 | #include <iostream> |
| 13 | #include <set> | 13 | #include <set> |
| 14 | #include <stdexcept> | ||
| 15 | #ifdef DEBUG | ||
| 16 | # include <iostream> | ||
| 17 | # include <iomanip> | ||
| 18 | #endif | ||
| 14 | #include "cdat.h" | 19 | #include "cdat.h" |
| 15 | #include "cmem.h" | 20 | #include "cmem.h" |
| 21 | #include "displays.h" | ||
| 16 | #include "cprogram.h" | 22 | #include "cprogram.h" |
| 17 | #include "cdisplay.h" | 23 | |
| 24 | /* forward declare CProgram */ | ||
| 25 | template <class T> | ||
| 26 | class CProgram; | ||
| 18 | 27 | ||
| 19 | /** | 28 | /** |
| 20 | * @class CCPU | 29 | * @class CCPU |
| @@ -22,8 +31,11 @@ | |||
| 22 | * CPU implementation. Used as a container for memory and instructions. | 31 | * CPU implementation. Used as a container for memory and instructions. |
| 23 | * Implements a run method to execute the program (= the instructions). | 32 | * Implements a run method to execute the program (= the instructions). |
| 24 | */ | 33 | */ |
| 34 | template <class T> | ||
| 25 | class CCPU | 35 | class CCPU |
| 26 | { | 36 | { |
| 37 | typedef typename std::set<CDisplay<T> *>::iterator displayiterator; | ||
| 38 | |||
| 27 | public: | 39 | public: |
| 28 | /** | 40 | /** |
| 29 | * @method CCPU | 41 | * @method CCPU |
| @@ -70,7 +82,7 @@ class CCPU | |||
| 70 | * @exception none | 82 | * @exception none |
| 71 | * @conditions none | 83 | * @conditions none |
| 72 | */ | 84 | */ |
| 73 | CDat *getRegisters() const | 85 | T *getRegisters() const |
| 74 | { | 86 | { |
| 75 | return m_registers; | 87 | return m_registers; |
| 76 | } | 88 | } |
| @@ -84,7 +96,7 @@ class CCPU | |||
| 84 | * @exception none | 96 | * @exception none |
| 85 | * @conditions none | 97 | * @conditions none |
| 86 | */ | 98 | */ |
| 87 | void setMemory(CMem *memory) | 99 | void setMemory(CMem<T> *memory) |
| 88 | { | 100 | { |
| 89 | m_memory = memory; | 101 | m_memory = memory; |
| 90 | } | 102 | } |
| @@ -98,7 +110,7 @@ class CCPU | |||
| 98 | * @exception none | 110 | * @exception none |
| 99 | * @conditions none | 111 | * @conditions none |
| 100 | */ | 112 | */ |
| 101 | CMem *getMemory() const | 113 | CMem<T> *getMemory() const |
| 102 | { | 114 | { |
| 103 | return m_memory; | 115 | return m_memory; |
| 104 | } | 116 | } |
| @@ -112,7 +124,7 @@ class CCPU | |||
| 112 | * @exception none | 124 | * @exception none |
| 113 | * @conditions none | 125 | * @conditions none |
| 114 | */ | 126 | */ |
| 115 | void setProgram(const CProgram *program) | 127 | void setProgram(const CProgram<T> *program) |
| 116 | { | 128 | { |
| 117 | m_program = program; | 129 | m_program = program; |
| 118 | } | 130 | } |
| @@ -126,7 +138,7 @@ class CCPU | |||
| 126 | * @exception none | 138 | * @exception none |
| 127 | * @conditions none | 139 | * @conditions none |
| 128 | */ | 140 | */ |
| 129 | const CProgram *getProgram() | 141 | const CProgram<T> *getProgram() |
| 130 | { | 142 | { |
| 131 | return m_program; | 143 | return m_program; |
| 132 | } | 144 | } |
| @@ -140,7 +152,7 @@ class CCPU | |||
| 140 | * @exception none | 152 | * @exception none |
| 141 | * @conditions none | 153 | * @conditions none |
| 142 | */ | 154 | */ |
| 143 | const std::set<CDisplay *>& getDisplays() | 155 | const std::set<CDisplay<T> *>& getDisplays() |
| 144 | { | 156 | { |
| 145 | return m_displays; | 157 | return m_displays; |
| 146 | } | 158 | } |
| @@ -227,15 +239,91 @@ class CCPU | |||
| 227 | 239 | ||
| 228 | private: | 240 | private: |
| 229 | /* members */ | 241 | /* members */ |
| 230 | CDat *m_registers; | 242 | T *m_registers; |
| 231 | unsigned m_regcnt; | 243 | unsigned m_regcnt; |
| 232 | CMem *m_memory; | 244 | CMem<T> *m_memory; |
| 233 | const CProgram *m_program; | 245 | const CProgram<T> *m_program; |
| 234 | std::set<CDisplay *> m_displays; | 246 | std::set<CDisplay<T> *> m_displays; |
| 235 | bool m_flagzero; | 247 | bool m_flagzero; |
| 236 | bool m_flagsign; | 248 | bool m_flagsign; |
| 237 | }; | 249 | }; |
| 238 | 250 | ||
| 251 | /*----------------------------------------------------------------------------*/ | ||
| 252 | |||
| 253 | template <class T> | ||
| 254 | CCPU<T>::CCPU(const unsigned cnt) | ||
| 255 | : m_regcnt(cnt), m_memory(NULL), m_program(NULL), m_flagzero(false), m_flagsign(false) | ||
| 256 | { | ||
| 257 | /* create registers */ | ||
| 258 | m_registers = new T[cnt]; | ||
| 259 | for(unsigned i = 0; i < cnt; ++i) | ||
| 260 | m_registers[i] = 0; | ||
| 261 | |||
| 262 | /* create displays */ | ||
| 263 | m_displays.insert(new CDisplayWDEZ<T>); | ||
| 264 | m_displays.insert(new CDisplayWHEX<T>); | ||
| 265 | } | ||
| 266 | |||
| 267 | /*----------------------------------------------------------------------------*/ | ||
| 268 | |||
| 269 | template <class T> | ||
| 270 | CCPU<T>::~CCPU() | ||
| 271 | { | ||
| 272 | /* delete registers */ | ||
| 273 | delete[] m_registers; | ||
| 274 | m_registers = NULL; | ||
| 275 | |||
| 276 | /* delete displays */ | ||
| 277 | for (displayiterator it = m_displays.begin() ; it != m_displays.end(); ++it) | ||
| 278 | delete *it; | ||
| 279 | } | ||
| 280 | |||
| 281 | /*----------------------------------------------------------------------------*/ | ||
| 282 | |||
| 283 | template <class T> | ||
| 284 | void CCPU<T>::run() | ||
| 285 | { | ||
| 286 | if (m_memory == NULL) | ||
| 287 | throw std::runtime_error("CPU has no memory"); | ||
| 288 | if (m_program == NULL) | ||
| 289 | throw std::runtime_error("CPU has no program to execute"); | ||
| 290 | if (m_regcnt == 0) | ||
| 291 | throw std::runtime_error("CPU has no registers"); | ||
| 292 | |||
| 293 | bool run = true; | ||
| 294 | while(run) | ||
| 295 | { | ||
| 296 | unsigned pc = static_cast<unsigned>(m_registers[0]); | ||
| 297 | |||
| 298 | /* end of the program reached */ | ||
| 299 | if (pc == m_program->size()) | ||
| 300 | break; | ||
| 301 | |||
| 302 | /* pc is out of bound */ | ||
| 303 | if (pc > m_program->size()) | ||
| 304 | throw std::runtime_error("Programcounter is out of bound"); | ||
| 305 | |||
| 306 | /* execute instruction */ | ||
| 307 | (*m_program->at(pc))(this); | ||
| 308 | ++m_registers[0]; | ||
| 309 | } | ||
| 310 | } | ||
| 311 | |||
| 312 | /*----------------------------------------------------------------------------*/ | ||
| 313 | |||
| 314 | #if DEBUG | ||
| 315 | template <class T> | ||
| 316 | void CCPU<T>::dumpRegisters(std::ostream& out) | ||
| 317 | { | ||
| 318 | out << "[REGISTER DUMP]" << std::endl; | ||
| 319 | for(unsigned i = 0; i < getRegisterCount(); ++i) | ||
| 320 | { | ||
| 321 | out << "[" << std::setw(4) << std::setfill('0') << i << "] " | ||
| 322 | << m_registers[i] << std::endl; | ||
| 323 | } | ||
| 324 | } | ||
| 325 | #endif | ||
| 326 | |||
| 239 | #endif | 327 | #endif |
| 240 | 328 | ||
| 241 | /* vim: set et sw=2 ts=2: */ | 329 | /* vim: set et sw=2 ts=2: */ |
