summaryrefslogtreecommitdiffstats
path: root/ue4/mycpu/ccpu.h
diff options
context:
space:
mode:
Diffstat (limited to 'ue4/mycpu/ccpu.h')
-rw-r--r--ue4/mycpu/ccpu.h112
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 */
25template <class T>
26class 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 */
34template <class T>
25class CCPU 35class 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
253template <class T>
254CCPU<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
269template <class T>
270CCPU<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
283template <class T>
284void 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
315template <class T>
316void 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: */