diff options
Diffstat (limited to 'ue4/mycpu/ccpu.h')
| -rw-r--r-- | ue4/mycpu/ccpu.h | 128 |
1 files changed, 83 insertions, 45 deletions
diff --git a/ue4/mycpu/ccpu.h b/ue4/mycpu/ccpu.h index 545b870..7257a87 100644 --- a/ue4/mycpu/ccpu.h +++ b/ue4/mycpu/ccpu.h | |||
| @@ -16,13 +16,37 @@ | |||
| 16 | # include <iostream> | 16 | # include <iostream> |
| 17 | # include <iomanip> | 17 | # include <iomanip> |
| 18 | #endif | 18 | #endif |
| 19 | #include "cdat.h" | 19 | |
| 20 | /** | ||
| 21 | * @class CCPUError | ||
| 22 | * | ||
| 23 | * Exception thrown by implemententations of CCPU | ||
| 24 | */ | ||
| 25 | class CCPUError | ||
| 26 | : public std::invalid_argument | ||
| 27 | { | ||
| 28 | public: | ||
| 29 | /** | ||
| 30 | * @method CCPUError | ||
| 31 | * @brief Default exception ctor | ||
| 32 | * @param what message to pass along | ||
| 33 | * @return - | ||
| 34 | * @globalvars none | ||
| 35 | * @exception none | ||
| 36 | * @pre none | ||
| 37 | * @post none | ||
| 38 | */ | ||
| 39 | CCPUError(const std::string& what) | ||
| 40 | : std::invalid_argument(what) | ||
| 41 | {} | ||
| 42 | }; | ||
| 43 | |||
| 20 | #include "cmem.h" | 44 | #include "cmem.h" |
| 21 | #include "displays.h" | 45 | #include "displays.h" |
| 22 | #include "cprogram.h" | 46 | #include "cprogram.h" |
| 23 | 47 | ||
| 24 | /* forward declare CProgram */ | 48 | /* forward declare CProgram */ |
| 25 | template <class T=CDat<int>, int width=0> | 49 | template <class T> |
| 26 | class CProgram; | 50 | class CProgram; |
| 27 | 51 | ||
| 28 | /** | 52 | /** |
| @@ -31,7 +55,7 @@ class CProgram; | |||
| 31 | * CPU implementation. Used as a container for memory and instructions. | 55 | * CPU implementation. Used as a container for memory and instructions. |
| 32 | * Implements a run method to execute the program (= the instructions). | 56 | * Implements a run method to execute the program (= the instructions). |
| 33 | */ | 57 | */ |
| 34 | template<class T=CDat<int>, int width=0> | 58 | template <class T> |
| 35 | class CCPU | 59 | class CCPU |
| 36 | { | 60 | { |
| 37 | typedef typename std::set<CDisplay<T> *>::iterator displayiterator; | 61 | typedef typename std::set<CDisplay<T> *>::iterator displayiterator; |
| @@ -44,9 +68,10 @@ class CCPU | |||
| 44 | * @return - | 68 | * @return - |
| 45 | * @globalvars none | 69 | * @globalvars none |
| 46 | * @exception none | 70 | * @exception none |
| 47 | * @conditions none | 71 | * @pre none |
| 72 | * @post none | ||
| 48 | */ | 73 | */ |
| 49 | CCPU(const unsigned cnt); | 74 | CCPU(const unsigned cnt, T& datatype); |
| 50 | 75 | ||
| 51 | /** | 76 | /** |
| 52 | * @method ~CCPU | 77 | * @method ~CCPU |
| @@ -55,7 +80,8 @@ class CCPU | |||
| 55 | * @return - | 80 | * @return - |
| 56 | * @globalvars none | 81 | * @globalvars none |
| 57 | * @exception none | 82 | * @exception none |
| 58 | * @conditions none | 83 | * @pre none |
| 84 | * @post none | ||
| 59 | */ | 85 | */ |
| 60 | ~CCPU(); | 86 | ~CCPU(); |
| 61 | 87 | ||
| @@ -66,7 +92,8 @@ class CCPU | |||
| 66 | * @return number of registers | 92 | * @return number of registers |
| 67 | * @globalvars none | 93 | * @globalvars none |
| 68 | * @exception none | 94 | * @exception none |
| 69 | * @conditions none | 95 | * @pre none |
| 96 | * @post none | ||
| 70 | */ | 97 | */ |
| 71 | const unsigned getRegisterCount() const | 98 | const unsigned getRegisterCount() const |
| 72 | { | 99 | { |
| @@ -75,14 +102,15 @@ class CCPU | |||
| 75 | 102 | ||
| 76 | /** | 103 | /** |
| 77 | * @method getRegisters | 104 | * @method getRegisters |
| 78 | * @brief get pointer to registers array | 105 | * @brief get reference to registers vector |
| 79 | * @param - | 106 | * @param - |
| 80 | * @return pointer to registers array | 107 | * @return reference to registers vector |
| 81 | * @globalvars none | 108 | * @globalvars none |
| 82 | * @exception none | 109 | * @exception none |
| 83 | * @conditions none | 110 | * @pre none |
| 111 | * @post none | ||
| 84 | */ | 112 | */ |
| 85 | T *getRegisters() const | 113 | std::vector<T> &getRegisters() |
| 86 | { | 114 | { |
| 87 | return m_registers; | 115 | return m_registers; |
| 88 | } | 116 | } |
| @@ -94,7 +122,8 @@ class CCPU | |||
| 94 | * @return - | 122 | * @return - |
| 95 | * @globalvars none | 123 | * @globalvars none |
| 96 | * @exception none | 124 | * @exception none |
| 97 | * @conditions none | 125 | * @pre none |
| 126 | * @post none | ||
| 98 | */ | 127 | */ |
| 99 | void setMemory(CMem<T> *memory) | 128 | void setMemory(CMem<T> *memory) |
| 100 | { | 129 | { |
| @@ -108,7 +137,8 @@ class CCPU | |||
| 108 | * @return pointer to memory | 137 | * @return pointer to memory |
| 109 | * @globalvars none | 138 | * @globalvars none |
| 110 | * @exception none | 139 | * @exception none |
| 111 | * @conditions none | 140 | * @pre none |
| 141 | * @post none | ||
| 112 | */ | 142 | */ |
| 113 | CMem<T> *getMemory() const | 143 | CMem<T> *getMemory() const |
| 114 | { | 144 | { |
| @@ -122,7 +152,8 @@ class CCPU | |||
| 122 | * @return - | 152 | * @return - |
| 123 | * @globalvars none | 153 | * @globalvars none |
| 124 | * @exception none | 154 | * @exception none |
| 125 | * @conditions none | 155 | * @pre none |
| 156 | * @post none | ||
| 126 | */ | 157 | */ |
| 127 | void setProgram(const CProgram<T> *program) | 158 | void setProgram(const CProgram<T> *program) |
| 128 | { | 159 | { |
| @@ -136,7 +167,8 @@ class CCPU | |||
| 136 | * @return pointer to program | 167 | * @return pointer to program |
| 137 | * @globalvars none | 168 | * @globalvars none |
| 138 | * @exception none | 169 | * @exception none |
| 139 | * @conditions none | 170 | * @pre none |
| 171 | * @post none | ||
| 140 | */ | 172 | */ |
| 141 | const CProgram<T> *getProgram() | 173 | const CProgram<T> *getProgram() |
| 142 | { | 174 | { |
| @@ -150,7 +182,8 @@ class CCPU | |||
| 150 | * @return reference to set of pointers to displays | 182 | * @return reference to set of pointers to displays |
| 151 | * @globalvars none | 183 | * @globalvars none |
| 152 | * @exception none | 184 | * @exception none |
| 153 | * @conditions none | 185 | * @pre none |
| 186 | * @post none | ||
| 154 | */ | 187 | */ |
| 155 | const std::set<CDisplay<T> *>& getDisplays() | 188 | const std::set<CDisplay<T> *>& getDisplays() |
| 156 | { | 189 | { |
| @@ -164,7 +197,8 @@ class CCPU | |||
| 164 | * @return - | 197 | * @return - |
| 165 | * @globalvars none | 198 | * @globalvars none |
| 166 | * @exception none | 199 | * @exception none |
| 167 | * @conditions none | 200 | * @pre none |
| 201 | * @post none | ||
| 168 | */ | 202 | */ |
| 169 | void setFlagZero(const bool value) | 203 | void setFlagZero(const bool value) |
| 170 | { | 204 | { |
| @@ -178,7 +212,8 @@ class CCPU | |||
| 178 | * @return value of zero flag | 212 | * @return value of zero flag |
| 179 | * @globalvars none | 213 | * @globalvars none |
| 180 | * @exception none | 214 | * @exception none |
| 181 | * @conditions none | 215 | * @pre none |
| 216 | * @post none | ||
| 182 | */ | 217 | */ |
| 183 | const bool getFlagZero() | 218 | const bool getFlagZero() |
| 184 | { | 219 | { |
| @@ -192,7 +227,8 @@ class CCPU | |||
| 192 | * @return - | 227 | * @return - |
| 193 | * @globalvars none | 228 | * @globalvars none |
| 194 | * @exception none | 229 | * @exception none |
| 195 | * @conditions none | 230 | * @pre none |
| 231 | * @post none | ||
| 196 | */ | 232 | */ |
| 197 | void setFlagSign(const bool value) | 233 | void setFlagSign(const bool value) |
| 198 | { | 234 | { |
| @@ -206,7 +242,8 @@ class CCPU | |||
| 206 | * @return value of sign flag | 242 | * @return value of sign flag |
| 207 | * @globalvars none | 243 | * @globalvars none |
| 208 | * @exception none | 244 | * @exception none |
| 209 | * @conditions none | 245 | * @pre none |
| 246 | * @post none | ||
| 210 | */ | 247 | */ |
| 211 | const bool getFlagSign() | 248 | const bool getFlagSign() |
| 212 | { | 249 | { |
| @@ -219,8 +256,9 @@ class CCPU | |||
| 219 | * @param - | 256 | * @param - |
| 220 | * @return - | 257 | * @return - |
| 221 | * @globalvars none | 258 | * @globalvars none |
| 222 | * @exception std::runtime_error | 259 | * @exception CCPUError |
| 223 | * @conditions none | 260 | * @pre none |
| 261 | * @post none | ||
| 224 | */ | 262 | */ |
| 225 | void run(); | 263 | void run(); |
| 226 | 264 | ||
| @@ -232,14 +270,16 @@ class CCPU | |||
| 232 | * @return void | 270 | * @return void |
| 233 | * @globalvars none | 271 | * @globalvars none |
| 234 | * @exception none | 272 | * @exception none |
| 235 | * @conditions none | 273 | * @pre none |
| 274 | * @post none | ||
| 236 | */ | 275 | */ |
| 237 | void dumpRegisters(std::ostream& out); | 276 | void dumpRegisters(std::ostream& out); |
| 238 | #endif | 277 | #endif |
| 239 | 278 | ||
| 240 | private: | 279 | private: |
| 241 | /* members */ | 280 | /* members */ |
| 242 | T *m_registers; | 281 | T m_datatype; |
| 282 | std::vector<T> m_registers; | ||
| 243 | unsigned m_regcnt; | 283 | unsigned m_regcnt; |
| 244 | CMem<T> *m_memory; | 284 | CMem<T> *m_memory; |
| 245 | const CProgram<T> *m_program; | 285 | const CProgram<T> *m_program; |
| @@ -250,15 +290,10 @@ class CCPU | |||
| 250 | 290 | ||
| 251 | /*----------------------------------------------------------------------------*/ | 291 | /*----------------------------------------------------------------------------*/ |
| 252 | 292 | ||
| 253 | template<class T, int width> | 293 | template <class T> |
| 254 | CCPU<T, width>::CCPU(const unsigned cnt) | 294 | CCPU<T>::CCPU(const unsigned cnt, T& datatype) |
| 255 | : m_regcnt(cnt), m_memory(NULL), m_program(NULL), m_flagzero(false), m_flagsign(false) | 295 | : m_datatype(datatype), m_registers(cnt, T(m_datatype) = 0), m_regcnt(cnt), m_memory(NULL), m_program(NULL), m_flagzero(false), m_flagsign(false) |
| 256 | { | 296 | { |
| 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 */ | 297 | /* create displays */ |
| 263 | m_displays.insert(new CDisplayWDEZ<T>); | 298 | m_displays.insert(new CDisplayWDEZ<T>); |
| 264 | m_displays.insert(new CDisplayWHEX<T>); | 299 | m_displays.insert(new CDisplayWHEX<T>); |
| @@ -266,13 +301,9 @@ CCPU<T, width>::CCPU(const unsigned cnt) | |||
| 266 | 301 | ||
| 267 | /*----------------------------------------------------------------------------*/ | 302 | /*----------------------------------------------------------------------------*/ |
| 268 | 303 | ||
| 269 | template<class T, int width> | 304 | template <class T> |
| 270 | CCPU<T>::~CCPU() | 305 | CCPU<T>::~CCPU() |
| 271 | { | 306 | { |
| 272 | /* delete registers */ | ||
| 273 | delete[] m_registers; | ||
| 274 | m_registers = NULL; | ||
| 275 | |||
| 276 | /* delete displays */ | 307 | /* delete displays */ |
| 277 | for (displayiterator it = m_displays.begin() ; it != m_displays.end(); ++it) | 308 | for (displayiterator it = m_displays.begin() ; it != m_displays.end(); ++it) |
| 278 | delete *it; | 309 | delete *it; |
| @@ -280,15 +311,15 @@ CCPU<T>::~CCPU() | |||
| 280 | 311 | ||
| 281 | /*----------------------------------------------------------------------------*/ | 312 | /*----------------------------------------------------------------------------*/ |
| 282 | 313 | ||
| 283 | template<class T, int width> | 314 | template <class T> |
| 284 | void CCPU<T>::run() | 315 | void CCPU<T>::run() |
| 285 | { | 316 | { |
| 286 | if (m_memory == NULL) | 317 | if (m_memory == NULL) |
| 287 | throw std::runtime_error("CPU has no memory"); | 318 | throw CCPUError("CPU has no memory"); |
| 288 | if (m_program == NULL) | 319 | if (m_program == NULL) |
| 289 | throw std::runtime_error("CPU has no program to execute"); | 320 | throw CCPUError("CPU has no program to execute"); |
| 290 | if (m_regcnt == 0) | 321 | if (m_regcnt == 0) |
| 291 | throw std::runtime_error("CPU has no registers"); | 322 | throw CCPUError("CPU has no registers"); |
| 292 | 323 | ||
| 293 | bool run = true; | 324 | bool run = true; |
| 294 | while(run) | 325 | while(run) |
| @@ -301,18 +332,25 @@ void CCPU<T>::run() | |||
| 301 | 332 | ||
| 302 | /* pc is out of bound */ | 333 | /* pc is out of bound */ |
| 303 | if (pc > m_program->size()) | 334 | if (pc > m_program->size()) |
| 304 | throw std::runtime_error("Programcounter is out of bound"); | 335 | throw CCPUError("Programcounter is out of bound"); |
| 305 | 336 | ||
| 306 | /* execute instruction */ | 337 | /* execute instruction */ |
| 307 | (*m_program->at(pc))(this); | 338 | try |
| 308 | ++m_registers[0]; | 339 | { |
| 340 | (*m_program->at(pc))(this); | ||
| 341 | ++m_registers[0]; | ||
| 342 | } | ||
| 343 | catch(CInstructionError& ex) | ||
| 344 | { | ||
| 345 | throw CCPUError(ex.what()); | ||
| 346 | } | ||
| 309 | } | 347 | } |
| 310 | } | 348 | } |
| 311 | 349 | ||
| 312 | /*----------------------------------------------------------------------------*/ | 350 | /*----------------------------------------------------------------------------*/ |
| 313 | 351 | ||
| 314 | #if DEBUG | 352 | #if DEBUG |
| 315 | template<class T, int width> | 353 | template <class T> |
| 316 | void CCPU<T>::dumpRegisters(std::ostream& out) | 354 | void CCPU<T>::dumpRegisters(std::ostream& out) |
| 317 | { | 355 | { |
| 318 | out << "[REGISTER DUMP]" << std::endl; | 356 | out << "[REGISTER DUMP]" << std::endl; |
