summaryrefslogtreecommitdiffstats
path: root/ue4/mycpu
diff options
context:
space:
mode:
authormanuel <manuel@nc8430.lan>2009-05-26 23:10:13 +0200
committermanuel <manuel@nc8430.lan>2009-05-26 23:10:13 +0200
commit26a97259f5a7b066cff2927e88c867fac2aaad87 (patch)
tree40250b999ce0ca02d0ebcde55640c56be975e555 /ue4/mycpu
parent1a60d0c2a8eeef3b39ef276f0f3552552a1519b1 (diff)
downloadooprog-26a97259f5a7b066cff2927e88c867fac2aaad87.tar.gz
ooprog-26a97259f5a7b066cff2927e88c867fac2aaad87.tar.bz2
ooprog-26a97259f5a7b066cff2927e88c867fac2aaad87.zip
template FTW!!!!!11
Diffstat (limited to 'ue4/mycpu')
-rw-r--r--ue4/mycpu/Makefile2
-rw-r--r--ue4/mycpu/ccpu.cpp89
-rw-r--r--ue4/mycpu/ccpu.h112
-rw-r--r--ue4/mycpu/cdat.h109
-rw-r--r--ue4/mycpu/cdisplay.h21
-rw-r--r--ue4/mycpu/cinstruction.cpp48
-rw-r--r--ue4/mycpu/cinstruction.h50
-rw-r--r--ue4/mycpu/cmem.h33
-rw-r--r--ue4/mycpu/cprogram.cpp161
-rw-r--r--ue4/mycpu/cprogram.h173
-rw-r--r--ue4/mycpu/displays.h20
-rw-r--r--ue4/mycpu/instructions.cpp341
-rw-r--r--ue4/mycpu/instructions.h483
-rw-r--r--ue4/mycpu/mycpu.cpp14
14 files changed, 849 insertions, 807 deletions
diff --git a/ue4/mycpu/Makefile b/ue4/mycpu/Makefile
index 0dbb51a..8022614 100644
--- a/ue4/mycpu/Makefile
+++ b/ue4/mycpu/Makefile
@@ -11,7 +11,7 @@ LDFLAGS=
11LIBS= -L/usr/local/lib -lboost_program_options 11LIBS= -L/usr/local/lib -lboost_program_options
12 12
13BIN= mycpu 13BIN= mycpu
14OBJS= cinstruction.o instructions.o cprogram.o ccpu.o mycpu.o 14OBJS= mycpu.o
15HEADERS= cdat.h cmem.h cinstruction.h instructions.h cprogram.h cdisplay.h displays.h ccpu.h 15HEADERS= cdat.h cmem.h cinstruction.h instructions.h cprogram.h cdisplay.h displays.h ccpu.h
16 16
17.SUFFIXES: .cpp .o 17.SUFFIXES: .cpp .o
diff --git a/ue4/mycpu/ccpu.cpp b/ue4/mycpu/ccpu.cpp
deleted file mode 100644
index af86200..0000000
--- a/ue4/mycpu/ccpu.cpp
+++ /dev/null
@@ -1,89 +0,0 @@
1/**
2 * @module ccpu
3 * @author Guenther Neuwirth (0626638), Manuel Mausz (0728348)
4 * @brief CPU implementation. Used as a container for memory and instructions.
5 * Implements an run method to execute the program (= the instructions).
6 * @date 10.05.2009
7 */
8
9#ifdef DEBUG
10# include <iostream>
11# include <iomanip>
12#endif
13#include "ccpu.h"
14#include "displays.h"
15
16using namespace std;
17
18CCPU::CCPU(const unsigned cnt)
19 : m_regcnt(cnt), m_memory(NULL), m_program(NULL), m_flagzero(false), m_flagsign(false)
20{
21 /* create registers */
22 m_registers = new CDat[cnt];
23 for(unsigned i = 0; i < cnt; ++i)
24 m_registers[i] = 0;
25
26 /* create displays */
27 m_displays.insert(new CDisplayWDEZ);
28 m_displays.insert(new CDisplayWHEX);
29}
30
31/*----------------------------------------------------------------------------*/
32
33CCPU::~CCPU()
34{
35 /* delete registers */
36 delete[] m_registers;
37 m_registers = NULL;
38
39 /* delete displays */
40 std::set<CDisplay *>::iterator it;
41 for (it = m_displays.begin() ; it != m_displays.end(); ++it)
42 delete *it;
43}
44
45/*----------------------------------------------------------------------------*/
46
47void CCPU::run()
48{
49 if (m_memory == NULL)
50 throw runtime_error("CPU has no memory");
51 if (m_program == NULL)
52 throw runtime_error("CPU has no program to execute");
53 if (m_regcnt == 0)
54 throw runtime_error("CPU has no registers");
55
56 bool run = true;
57 while(run)
58 {
59 unsigned pc = static_cast<unsigned>(m_registers[0]);
60
61 /* end of the program reached */
62 if (pc == m_program->size())
63 break;
64
65 /* pc is out of bound */
66 if (pc > m_program->size())
67 throw runtime_error("Programcounter is out of bound");
68
69 /* execute instruction */
70 (*m_program->at(pc))(this);
71 ++m_registers[0];
72 }
73}
74
75/*----------------------------------------------------------------------------*/
76
77#if DEBUG
78void CCPU::dumpRegisters(std::ostream& out)
79{
80 out << "[REGISTER DUMP]" << endl;
81 for(unsigned i = 0; i < getRegisterCount(); ++i)
82 {
83 out << "[" << std::setw(4) << std::setfill('0') << i << "] "
84 << m_registers[i] << endl;
85 }
86}
87#endif
88
89/* vim: set et sw=2 ts=2: */
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: */
diff --git a/ue4/mycpu/cdat.h b/ue4/mycpu/cdat.h
index a533fae..ca9d745 100644
--- a/ue4/mycpu/cdat.h
+++ b/ue4/mycpu/cdat.h
@@ -2,7 +2,7 @@
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 and datatype definition for CCPU and CMem 4 * @brief Datatype template and datatype definition for CCPU and CMem
5 * @date 10.05.2009 5 * @date 26.05.2009
6 */ 6 */
7 7
8#ifndef CDAT_H 8#ifndef CDAT_H
@@ -12,17 +12,17 @@
12#include <iostream> 12#include <iostream>
13 13
14/** 14/**
15 * @class CDatT 15 * @class CDat
16 * 16 *
17 * Datatype template for CCPU and CMem. 17 * Datatype template for CCPU and CMem.
18 */ 18 */
19template <class T> 19template <class T>
20class CDatT 20class CDat
21 : boost::operators<CDatT<T> > 21 : boost::operators<CDat<T> >
22{ 22{
23 public: 23 public:
24 /** 24 /**
25 * @method CDatT 25 * @method CDat
26 * @brief Default ctor 26 * @brief Default ctor
27 * @param - 27 * @param -
28 * @return - 28 * @return -
@@ -30,11 +30,11 @@ class CDatT
30 * @exception bad_alloc 30 * @exception bad_alloc
31 * @conditions none 31 * @conditions none
32 */ 32 */
33 CDatT() 33 CDat()
34 {} 34 {}
35 35
36 /** 36 /**
37 * @method ~CDatT 37 * @method ~CDat
38 * @brief Default dtor 38 * @brief Default dtor
39 * @param - 39 * @param -
40 * @return - 40 * @return -
@@ -42,40 +42,40 @@ class CDatT
42 * @exception none 42 * @exception none
43 * @conditions none 43 * @conditions none
44 */ 44 */
45 ~CDatT() 45 ~CDat()
46 {} 46 {}
47 47
48 /** 48 /**
49 * @method CDatT 49 * @method CDat
50 * @brief Copy constructor for CDatT 50 * @brief Copy constructor for CDat
51 * @param other reference to CDatT which will be copied 51 * @param other reference to CDat which will be copied
52 * @return - 52 * @return -
53 * @globalvars none 53 * @globalvars none
54 * @exception none 54 * @exception none
55 * @conditions none 55 * @conditions none
56 */ 56 */
57 CDatT(const CDatT& other) 57 CDat(const CDat& other)
58 : m_value(other.m_value) 58 : m_value(other.m_value)
59 {} 59 {}
60 60
61 /** 61 /**
62 * @method CDatT 62 * @method CDat
63 * @brief Copy constructor for int 63 * @brief Copy constructor for int
64 * @param newval new value for CDatT 64 * @param newval new value for CDat
65 * @return - 65 * @return -
66 * @globalvars none 66 * @globalvars none
67 * @exception none 67 * @exception none
68 * @conditions none 68 * @conditions none
69 */ 69 */
70 CDatT(T newval) 70 CDat(T newval)
71 : m_value(newval) 71 : m_value(newval)
72 {} 72 {}
73 73
74 /** 74 /**
75 * @method getValue 75 * @method getValue
76 * @brief returns value of CDatT 76 * @brief returns value of CDat
77 * @param - 77 * @param -
78 * @return value of CDatT 78 * @return value of CDat
79 * @globalvars none 79 * @globalvars none
80 * @exception none 80 * @exception none
81 * @conditions none 81 * @conditions none
@@ -102,13 +102,13 @@ class CDatT
102 /** 102 /**
103 * @method operator< 103 * @method operator<
104 * @brief implementation of operator < 104 * @brief implementation of operator <
105 * @param x reference to CDatT 105 * @param x reference to CDat
106 * @return true if cdat is less than object x 106 * @return true if cdat is less than object x
107 * @globalvars none 107 * @globalvars none
108 * @exception none 108 * @exception none
109 * @conditions none 109 * @conditions none
110 */ 110 */
111 bool operator<(const CDatT& x) const 111 bool operator<(const CDat& x) const
112 { 112 {
113 return m_value < x.m_value; 113 return m_value < x.m_value;
114 } 114 }
@@ -116,13 +116,13 @@ class CDatT
116 /** 116 /**
117 * @method operator== 117 * @method operator==
118 * @brief implementation of operator == 118 * @brief implementation of operator ==
119 * @param x reference to CDatT 119 * @param x reference to CDat
120 * @return true if cdat equals object x 120 * @return true if cdat equals object x
121 * @globalvars none 121 * @globalvars none
122 * @exception none 122 * @exception none
123 * @conditions none 123 * @conditions none
124 */ 124 */
125 bool operator==(const CDatT& x) const 125 bool operator==(const CDat& x) const
126 { 126 {
127 return m_value == x.m_value; 127 return m_value == x.m_value;
128 } 128 }
@@ -130,13 +130,13 @@ class CDatT
130 /** 130 /**
131 * @method operator+= 131 * @method operator+=
132 * @brief implementation of operator += 132 * @brief implementation of operator +=
133 * @param x reference to CDatT 133 * @param x reference to CDat
134 * @return refecence to CDatT 134 * @return refecence to CDat
135 * @globalvars none 135 * @globalvars none
136 * @exception none 136 * @exception none
137 * @conditions none 137 * @conditions none
138 */ 138 */
139 CDatT& operator+=(const CDatT& x) 139 CDat& operator+=(const CDat& x)
140 { 140 {
141 m_value += x.m_value; 141 m_value += x.m_value;
142 return *this; 142 return *this;
@@ -145,13 +145,13 @@ class CDatT
145 /** 145 /**
146 * @method operator-= 146 * @method operator-=
147 * @brief implementation of operator -= 147 * @brief implementation of operator -=
148 * @param x reference to CDatT 148 * @param x reference to CDat
149 * @return refecence to CDatT 149 * @return refecence to CDat
150 * @globalvars none 150 * @globalvars none
151 * @exception none 151 * @exception none
152 * @conditions none 152 * @conditions none
153 */ 153 */
154 CDatT& operator-=(const CDatT& x) 154 CDat& operator-=(const CDat& x)
155 { 155 {
156 m_value -= x.m_value; 156 m_value -= x.m_value;
157 return *this; 157 return *this;
@@ -160,13 +160,13 @@ class CDatT
160 /** 160 /**
161 * @method operator*= 161 * @method operator*=
162 * @brief implementation of operator *= 162 * @brief implementation of operator *=
163 * @param x reference to CDatT 163 * @param x reference to CDat
164 * @return refecence to CDatT 164 * @return refecence to CDat
165 * @globalvars none 165 * @globalvars none
166 * @exception none 166 * @exception none
167 * @conditions none 167 * @conditions none
168 */ 168 */
169 CDatT& operator*=(const CDatT& x) 169 CDat& operator*=(const CDat& x)
170 { 170 {
171 m_value *= x.m_value; 171 m_value *= x.m_value;
172 return *this; 172 return *this;
@@ -175,13 +175,13 @@ class CDatT
175 /** 175 /**
176 * @method operator/= 176 * @method operator/=
177 * @brief implementation of operator /= 177 * @brief implementation of operator /=
178 * @param x reference to CDatT 178 * @param x reference to CDat
179 * @return refecence to CDatT 179 * @return refecence to CDat
180 * @globalvars none 180 * @globalvars none
181 * @exception none 181 * @exception none
182 * @conditions none 182 * @conditions none
183 */ 183 */
184 CDatT& operator/=(const CDatT& x) 184 CDat& operator/=(const CDat& x)
185 { 185 {
186 m_value /= x.m_value; 186 m_value /= x.m_value;
187 return *this; 187 return *this;
@@ -190,13 +190,13 @@ class CDatT
190 /** 190 /**
191 * @method operator%= 191 * @method operator%=
192 * @brief implementation of operator %= 192 * @brief implementation of operator %=
193 * @param x reference to CDatT 193 * @param x reference to CDat
194 * @return refecence to CDatT 194 * @return refecence to CDat
195 * @globalvars none 195 * @globalvars none
196 * @exception none 196 * @exception none
197 * @conditions none 197 * @conditions none
198 */ 198 */
199 CDatT& operator%=(const CDatT& x) 199 CDat& operator%=(const CDat& x)
200 { 200 {
201 m_value %= x.m_value; 201 m_value %= x.m_value;
202 return *this; 202 return *this;
@@ -205,13 +205,13 @@ class CDatT
205 /** 205 /**
206 * @method operator|= 206 * @method operator|=
207 * @brief implementation of operator |= 207 * @brief implementation of operator |=
208 * @param x reference to CDatT 208 * @param x reference to CDat
209 * @return refecence to CDatT 209 * @return refecence to CDat
210 * @globalvars none 210 * @globalvars none
211 * @exception none 211 * @exception none
212 * @conditions none 212 * @conditions none
213 */ 213 */
214 CDatT& operator|=(const CDatT& x) 214 CDat& operator|=(const CDat& x)
215 { 215 {
216 m_value |= x.m_value; 216 m_value |= x.m_value;
217 return *this; 217 return *this;
@@ -220,13 +220,13 @@ class CDatT
220 /** 220 /**
221 * @method operator&= 221 * @method operator&=
222 * @brief implementation of operator &= 222 * @brief implementation of operator &=
223 * @param x reference to CDatT 223 * @param x reference to CDat
224 * @return refecence to CDatT 224 * @return refecence to CDat
225 * @globalvars none 225 * @globalvars none
226 * @exception none 226 * @exception none
227 * @conditions none 227 * @conditions none
228 */ 228 */
229 CDatT& operator&=(const CDatT& x) 229 CDat& operator&=(const CDat& x)
230 { 230 {
231 m_value &= x.m_value; 231 m_value &= x.m_value;
232 return *this; 232 return *this;
@@ -235,13 +235,13 @@ class CDatT
235 /** 235 /**
236 * @method operator^= 236 * @method operator^=
237 * @brief implementation of operator ^= 237 * @brief implementation of operator ^=
238 * @param x reference to CDatT 238 * @param x reference to CDat
239 * @return refecence to CDatT 239 * @return refecence to CDat
240 * @globalvars none 240 * @globalvars none
241 * @exception none 241 * @exception none
242 * @conditions none 242 * @conditions none
243 */ 243 */
244 CDatT& operator^=(const CDatT& x) 244 CDat& operator^=(const CDat& x)
245 { 245 {
246 m_value ^= x.m_value; 246 m_value ^= x.m_value;
247 return *this; 247 return *this;
@@ -251,12 +251,12 @@ class CDatT
251 * @method operator++ 251 * @method operator++
252 * @brief implementation of operator ++ 252 * @brief implementation of operator ++
253 * @param - 253 * @param -
254 * @return refecence to CDatT 254 * @return refecence to CDat
255 * @globalvars none 255 * @globalvars none
256 * @exception none 256 * @exception none
257 * @conditions none 257 * @conditions none
258 */ 258 */
259 CDatT& operator++() 259 CDat& operator++()
260 { 260 {
261 m_value++; 261 m_value++;
262 return *this; 262 return *this;
@@ -266,12 +266,12 @@ class CDatT
266 * @method operator-- 266 * @method operator--
267 * @brief implementation of operator -- 267 * @brief implementation of operator --
268 * @param - 268 * @param -
269 * @return refecence to CDatT 269 * @return refecence to CDat
270 * @globalvars none 270 * @globalvars none
271 * @exception none 271 * @exception none
272 * @conditions none 272 * @conditions none
273 */ 273 */
274 CDatT& operator--() 274 CDat& operator--()
275 { 275 {
276 m_value--; 276 m_value--;
277 return *this; 277 return *this;
@@ -287,7 +287,7 @@ class CDatT
287 * @exception none 287 * @exception none
288 * @conditions none 288 * @conditions none
289 */ 289 */
290 friend std::ostream& operator<<(std::ostream& stream, CDatT cdat) 290 friend std::ostream& operator<<(std::ostream& stream, CDat cdat)
291 { 291 {
292 stream << cdat.m_value; 292 stream << cdat.m_value;
293 return stream; 293 return stream;
@@ -303,7 +303,7 @@ class CDatT
303 * @exception none 303 * @exception none
304 * @conditions none 304 * @conditions none
305 */ 305 */
306 friend std::istream& operator>>(std::istream & stream, CDatT& cdat) 306 friend std::istream& operator>>(std::istream & stream, CDat& cdat)
307 { 307 {
308 stream >> cdat.m_value; 308 stream >> cdat.m_value;
309 return stream; 309 return stream;
@@ -314,13 +314,6 @@ class CDatT
314 T m_value; 314 T m_value;
315}; 315};
316 316
317/**
318 * @class CDat
319 *
320 * Datatype for CCPU and CMem
321 */
322typedef CDatT<int> CDat;
323
324#endif 317#endif
325 318
326/* vim: set et sw=2 ts=2: */ 319/* vim: set et sw=2 ts=2: */
diff --git a/ue4/mycpu/cdisplay.h b/ue4/mycpu/cdisplay.h
index 82776ee..8d15eb9 100644
--- a/ue4/mycpu/cdisplay.h
+++ b/ue4/mycpu/cdisplay.h
@@ -2,23 +2,23 @@
2 * @module cdisplay 2 * @module cdisplay
3 * @author Guenther Neuwirth (0626638), Manuel Mausz (0728348) 3 * @author Guenther Neuwirth (0626638), Manuel Mausz (0728348)
4 * @brief Abstract template class for displays 4 * @brief Abstract template class for displays
5 * @date 10.05.2009 5 * @date 26.05.2009
6 */ 6 */
7 7
8#ifndef CDISPLAY_H 8#ifndef CDISPLAY_H
9#define CDISPLAY_H 1 9#define CDISPLAY_H 1
10 10
11/** 11/**
12 * @class CDisplayT 12 * @class CDisplay
13 * 13 *
14 * Abstract template class for displays 14 * Abstract template class for displays
15 */ 15 */
16template <class T> 16template <class T>
17class CDisplayT 17class CDisplay
18{ 18{
19 public: 19 public:
20 /** 20 /**
21 * @method CDisplayT 21 * @method CDisplay
22 * @brief Default ctor 22 * @brief Default ctor
23 * @param name name of display 23 * @param name name of display
24 * @return - 24 * @return -
@@ -26,12 +26,12 @@ class CDisplayT
26 * @exception none 26 * @exception none
27 * @conditions none 27 * @conditions none
28 */ 28 */
29 CDisplayT(std::string name) 29 CDisplay(std::string name)
30 : m_name(name) 30 : m_name(name)
31 {} 31 {}
32 32
33 /** 33 /**
34 * @method ~CDisplayT 34 * @method ~CDisplay
35 * @brief Default dtor 35 * @brief Default dtor
36 * @param - 36 * @param -
37 * @return - 37 * @return -
@@ -39,7 +39,7 @@ class CDisplayT
39 * @exception none 39 * @exception none
40 * @conditions none 40 * @conditions none
41 */ 41 */
42 virtual ~CDisplayT() 42 virtual ~CDisplay()
43 {} 43 {}
44 44
45 /** 45 /**
@@ -73,13 +73,6 @@ class CDisplayT
73 std::string m_name; 73 std::string m_name;
74}; 74};
75 75
76/**
77 * @class CDisplay
78 *
79 * Memory definition for CCPU
80 */
81typedef CDisplayT<CDat> CDisplay;
82
83#endif 76#endif
84 77
85/* vim: set et sw=2 ts=2: */ 78/* vim: set et sw=2 ts=2: */
diff --git a/ue4/mycpu/cinstruction.cpp b/ue4/mycpu/cinstruction.cpp
deleted file mode 100644
index a766015..0000000
--- a/ue4/mycpu/cinstruction.cpp
+++ /dev/null
@@ -1,48 +0,0 @@
1/**
2 * @module cinstruction
3 * @author Guenther Neuwirth (0626638), Manuel Mausz (0728348)
4 * @brief Abstract class for displays
5 * @date 13.05.2009
6 */
7
8#include <sstream>
9#include <stdexcept>
10#include <boost/lexical_cast.hpp>
11#include <assert.h>
12#include "cinstruction.h"
13#include "ccpu.h"
14
15using namespace std;
16
17const unsigned CInstruction::parseRegister(const std::string& str)
18{
19 unsigned reg;
20 if (str.length() < 2 || str[0] != 'r')
21 throw runtime_error("Invalid syntax of register");
22
23 try
24 {
25 reg = boost::lexical_cast<unsigned>(str.substr(1));
26 }
27 catch(boost::bad_lexical_cast& ex)
28 {
29 throw runtime_error("Invalid syntax of register");
30 }
31
32 return reg;
33}
34
35/*----------------------------------------------------------------------------*/
36
37inline void CInstruction::checkRegister(CCPU *cpu, const unsigned regidx)
38{
39 assert(cpu != NULL);
40 if (regidx >= cpu->getRegisterCount())
41 {
42 stringstream sstr;
43 sstr << "Register R" << regidx << " doesn't exist (out of bound)";
44 throw runtime_error(sstr.str());
45 }
46}
47
48/* vim: set et sw=2 ts=2: */
diff --git a/ue4/mycpu/cinstruction.h b/ue4/mycpu/cinstruction.h
index 4cc69de..8c35d2c 100644
--- a/ue4/mycpu/cinstruction.h
+++ b/ue4/mycpu/cinstruction.h
@@ -2,7 +2,7 @@
2 * @module cinstruction 2 * @module cinstruction
3 * @author Guenther Neuwirth (0626638), Manuel Mausz (0728348) 3 * @author Guenther Neuwirth (0626638), Manuel Mausz (0728348)
4 * @brief Abstract class for displays 4 * @brief Abstract class for displays
5 * @date 13.05.2009 5 * @date 26.05.2009
6 */ 6 */
7 7
8#ifndef CINSTRUCTION_H 8#ifndef CINSTRUCTION_H
@@ -10,8 +10,14 @@
10 10
11#include <iostream> 11#include <iostream>
12#include <list> 12#include <list>
13#include <sstream>
14#include <stdexcept>
15#include <boost/lexical_cast.hpp>
16#include <assert.h>
17#include "ccpu.h"
13 18
14/* forward declare CCPU */ 19/* forward declare CCPU */
20template <class T>
15class CCPU; 21class CCPU;
16 22
17/** 23/**
@@ -19,6 +25,7 @@ class CCPU;
19 * 25 *
20 * Abstract class for displays 26 * Abstract class for displays
21 */ 27 */
28template <class T>
22class CInstruction 29class CInstruction
23{ 30{
24 public: 31 public:
@@ -70,7 +77,7 @@ class CInstruction
70 * @exception std::runtime_error 77 * @exception std::runtime_error
71 * @conditions none 78 * @conditions none
72 */ 79 */
73 virtual CInstruction& operator()(CCPU *cpu) 80 virtual CInstruction& operator()(CCPU<T> *cpu)
74 { 81 {
75 execute(cpu); 82 execute(cpu);
76 return *this; 83 return *this;
@@ -142,7 +149,7 @@ class CInstruction
142 * @exception std::runtime_error 149 * @exception std::runtime_error
143 * @conditions none 150 * @conditions none
144 */ 151 */
145 virtual void checkRegister(CCPU *cpu, const unsigned regidx); 152 virtual void checkRegister(CCPU<T> *cpu, const unsigned regidx);
146 153
147 /** 154 /**
148 * @method factory 155 * @method factory
@@ -176,7 +183,7 @@ class CInstruction
176 * @exception std::runtime_error 183 * @exception std::runtime_error
177 * @conditions none 184 * @conditions none
178 */ 185 */
179 virtual void execute(CCPU *cpu) = 0; 186 virtual void execute(CCPU<T> *cpu) = 0;
180 187
181 protected: 188 protected:
182 /* members */ 189 /* members */
@@ -184,6 +191,41 @@ class CInstruction
184 std::string m_name; 191 std::string m_name;
185}; 192};
186 193
194/*----------------------------------------------------------------------------*/
195
196template<class T>
197const unsigned CInstruction<T>::parseRegister(const std::string& str)
198{
199 unsigned reg;
200 if (str.length() < 2 || str[0] != 'r')
201 throw std::runtime_error("Invalid syntax of register");
202
203 try
204 {
205 reg = boost::lexical_cast<unsigned>(str.substr(1));
206 }
207 catch(boost::bad_lexical_cast& ex)
208 {
209 throw std::runtime_error("Invalid syntax of register");
210 }
211
212 return reg;
213}
214
215/*----------------------------------------------------------------------------*/
216
217template<class T>
218inline void CInstruction<T>::checkRegister(CCPU<T> *cpu, const unsigned regidx)
219{
220 assert(cpu != NULL);
221 if (regidx >= cpu->getRegisterCount())
222 {
223 std::stringstream sstr;
224 sstr << "Register R" << regidx << " doesn't exist (out of bound)";
225 throw std::runtime_error(sstr.str());
226 }
227}
228
187#endif 229#endif
188 230
189/* vim: set et sw=2 ts=2: */ 231/* vim: set et sw=2 ts=2: */
diff --git a/ue4/mycpu/cmem.h b/ue4/mycpu/cmem.h
index 5045c34..6b23111 100644
--- a/ue4/mycpu/cmem.h
+++ b/ue4/mycpu/cmem.h
@@ -2,7 +2,7 @@
2 * @module cmem 2 * @module cmem
3 * @author Guenther Neuwirth (0626638), Manuel Mausz (0728348) 3 * @author Guenther Neuwirth (0626638), Manuel Mausz (0728348)
4 * @brief Memory template and memory definition for CCPU 4 * @brief Memory template and memory definition for CCPU
5 * @date 10.05.2009 5 * @date 26.05.2009
6 */ 6 */
7 7
8#ifndef CMEM_H 8#ifndef CMEM_H
@@ -17,21 +17,23 @@
17# include <iostream> 17# include <iostream>
18# include <iomanip> 18# include <iomanip>
19#endif 19#endif
20#include "cdat.h"
21 20
22/** 21/**
23 * @class CVectorMem 22 * @class CMem
24 * 23 *
25 * Extends std::vector template for use as memory for CCPU. 24 * Extends std::vector template for use as memory for CCPU.
26 */ 25 */
27template <class T, class Allocator=std::allocator<T> > 26template <class T>
28class CVectorMem 27class CMem
29 : public std::vector<T, Allocator> 28 : public std::vector<T>
30{ 29{
31 public: 30 typedef std::vector<T> super;
32 using std::vector<T, Allocator>::size; 31 typedef typename super::iterator iterator;
33 using std::vector<T, Allocator>::at; 32 using super::size;
33 using super::begin;
34 using super::end;
34 35
36 public:
35 /** 37 /**
36 * @method initialize 38 * @method initialize
37 * @brief initialize the vector with the content of istream. istream is 39 * @brief initialize the vector with the content of istream. istream is
@@ -88,22 +90,17 @@ class CVectorMem
88 void dump(std::ostream& out) 90 void dump(std::ostream& out)
89 { 91 {
90 out << "[MEMORY DUMP]" << std::endl; 92 out << "[MEMORY DUMP]" << std::endl;
91 for(unsigned i = 0; i < size(); ++i) 93 unsigned i = 0;
94 for(iterator it = begin(); it != end(); ++it)
92 { 95 {
93 out << "[" << std::setw(4) << std::setfill('0') << i << "] " 96 out << "[" << std::setw(4) << std::setfill('0') << i << "] "
94 << at(i) << std::endl; 97 << *it << std::endl;
98 ++i;
95 } 99 }
96 } 100 }
97#endif 101#endif
98}; 102};
99 103
100/**
101 * @class CMem
102 *
103 * Memory definition for CCPU
104 */
105typedef CVectorMem<CDat> CMem;
106
107#endif 104#endif
108 105
109/* vim: set et sw=2 ts=2: */ 106/* vim: set et sw=2 ts=2: */
diff --git a/ue4/mycpu/cprogram.cpp b/ue4/mycpu/cprogram.cpp
deleted file mode 100644
index 3fcf734..0000000
--- a/ue4/mycpu/cprogram.cpp
+++ /dev/null
@@ -1,161 +0,0 @@
1/**
2 * @module cprogram
3 * @author Guenther Neuwirth (0626638), Manuel Mausz (0728348)
4 * @brief CProgram extends std::vector and adds a method for parsing programfile
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
17using namespace std;
18
19CProgram::CProgram()
20{
21 m_instrset.insert(new CInstructionInc);
22 m_instrset.insert(new CInstructionDec);
23 m_instrset.insert(new CInstructionAdd);
24 m_instrset.insert(new CInstructionSub);
25 m_instrset.insert(new CInstructionMul);
26 m_instrset.insert(new CInstructionDiv);
27 m_instrset.insert(new CInstructionLoad);
28 m_instrset.insert(new CInstructionStore);
29 m_instrset.insert(new CInstructionTest);
30 m_instrset.insert(new CInstructionLabel);
31 m_instrset.insert(new CInstructionJumpA);
32 m_instrset.insert(new CInstructionJumpZ);
33 m_instrset.insert(new CInstructionJumpS);
34 m_instrset.insert(new CInstructionWrite);
35}
36
37/*----------------------------------------------------------------------------*/
38
39CProgram::~CProgram()
40{
41 /* free instruction set */
42 set<CInstruction *>::iterator it;
43 for (it = m_instrset.begin(); it != m_instrset.end(); ++it)
44 delete *it;
45
46 /* free instruction */
47 for (iterator it = begin(); it != end(); ++it)
48 delete *it;
49}
50
51/*----------------------------------------------------------------------------*/
52
53void CProgram::compile(std::istream& in)
54{
55 if (!in.good())
56 return;
57
58 string line;
59 unsigned i = 0;
60 while (!in.eof() && in.good())
61 {
62 ++i;
63
64 /* read stream per line */
65 getline(in, line);
66 if (line.empty())
67 continue;
68
69 boost::trim(line);
70 boost::to_lower(line);
71
72 /* ignore comments */
73 if (line.find_first_of('#') == 0)
74 continue;
75
76 /* get instruction name */
77 size_t pos = line.find_first_of(' ');
78 string instrname(line.substr(0, pos));
79
80 /* search and create instruction */
81 CInstruction *instrptr = NULL;
82 set<CInstruction *>::iterator it;
83 for (it = m_instrset.begin(); it != m_instrset.end(); ++it)
84 {
85 if (*(*it) == instrname)
86 {
87 instrptr = *it;
88 break;
89 }
90 }
91 if (instrptr == NULL)
92 {
93 stringstream sstr;
94 sstr << "Unknown instruction '" << instrname << "' on line " << i << ".";
95 throw runtime_error(sstr.str());
96 }
97
98 /* create instruction */
99 CInstruction *instr = instrptr->factory();
100
101 /* parse instruction parameters */
102 string params = (pos == string::npos) ? "" : line.substr(pos + 1);
103 boost::trim(params);
104 list<string> instrparams;
105 boost::split(instrparams, params, boost::is_any_of(", \t"), boost::token_compress_on);
106
107 /* let instruction parse the parameters. catch+throw exception */
108 try
109 {
110 /* handle label instruction ourself, but still add a dummy instruction */
111 if (instrname == "label")
112 {
113 if (instrparams.size() != 1)
114 throw runtime_error("Invalid paramater count - must be 1");
115 string label(instrparams.front());
116 if (label.length() < 2 || label[ label.length() - 1] != ':')
117 throw runtime_error("Label has invalid syntax");
118 m_labels[ label.substr(0, label.length() - 1) ] = size();
119 }
120 instr->compile(instrparams);
121 }
122 catch(runtime_error& ex)
123 {
124 stringstream sstr;
125 sstr << "Unable to compile instruction '" << instrname
126 << "' (line " << i << "): " << ex.what();
127 throw runtime_error(sstr.str());
128 }
129
130 push_back(instr);
131 }
132}
133
134/*----------------------------------------------------------------------------*/
135
136unsigned CProgram::findLabel(const std::string& label) const
137{
138 map<string, unsigned>::const_iterator it;
139 it = m_labels.find(label);
140 if (it == m_labels.end())
141 throw runtime_error("Unknown label '" + label + "'");
142 return it->second;
143}
144
145/*----------------------------------------------------------------------------*/
146
147#if DEBUG
148void CProgram::dump(std::ostream& out)
149{
150 out << "[PROGRAM DUMP]" << endl;
151 unsigned i = 0;
152 for(iterator it = begin(); it < end(); ++it)
153 {
154 out << "[" << std::setw(4) << std::setfill('0') << i << "] "
155 << *(*it) << endl;
156 ++i;
157 }
158}
159#endif
160
161/* vim: set et sw=2 ts=2: */
diff --git a/ue4/mycpu/cprogram.h b/ue4/mycpu/cprogram.h
index 27e7647..43193ac 100644
--- a/ue4/mycpu/cprogram.h
+++ b/ue4/mycpu/cprogram.h
@@ -2,7 +2,7 @@
2 * @module cprogram 2 * @module cprogram
3 * @author Guenther Neuwirth (0626638), Manuel Mausz (0728348) 3 * @author Guenther Neuwirth (0626638), Manuel Mausz (0728348)
4 * @brief CProgram extends std::vector and adds a method for parsing programfile 4 * @brief CProgram extends std::vector and adds a method for parsing programfile
5 * @date 10.05.2009 5 * @date 26.05.2009
6 */ 6 */
7 7
8#ifndef CPROGRAM_H 8#ifndef CPROGRAM_H
@@ -11,7 +11,18 @@
11#include <vector> 11#include <vector>
12#include <set> 12#include <set>
13#include <map> 13#include <map>
14#include <boost/algorithm/string.hpp>
15#include <boost/algorithm/string/split.hpp>
16#ifdef DEBUG
17# include <iostream>
18# include <iomanip>
19#endif
14#include "cinstruction.h" 20#include "cinstruction.h"
21#include "instructions.h"
22
23/* forward declare CInstruction */
24template <class T>
25class CInstruction;
15 26
16/** 27/**
17 * @class CProgram 28 * @class CProgram
@@ -19,9 +30,17 @@
19 * CProgram extends std::vector and adds a method for parsing 30 * CProgram extends std::vector and adds a method for parsing
20 * programfile. This adds instances of CInstruction to CProgram itself. 31 * programfile. This adds instances of CInstruction to CProgram itself.
21 */ 32 */
33template <class T>
22class CProgram 34class CProgram
23 : public std::vector<CInstruction *> 35 : public std::vector<CInstruction<T> *>
24{ 36{
37 typedef typename std::set<CInstruction<T> *>::iterator setiterator;
38 typedef std::vector<CInstruction<T> *> super;
39 typedef typename super::iterator iterator;
40 using super::begin;
41 using super::end;
42 using super::size;
43
25 public: 44 public:
26 /** 45 /**
27 * @method CProgram 46 * @method CProgram
@@ -97,10 +116,158 @@ class CProgram
97 private: 116 private:
98 /* members */ 117 /* members */
99 /** set of known instructions */ 118 /** set of known instructions */
100 std::set<CInstruction *> m_instrset; 119 std::set<CInstruction<T> *> m_instrset;
101 std::map<std::string, unsigned> m_labels; 120 std::map<std::string, unsigned> m_labels;
102}; 121};
103 122
123/*----------------------------------------------------------------------------*/
124
125template <class T>
126CProgram<T>::CProgram()
127{
128 m_instrset.insert(new CInstructionInc<T>);
129 m_instrset.insert(new CInstructionDec<T>);
130 m_instrset.insert(new CInstructionAdd<T>);
131 m_instrset.insert(new CInstructionSub<T>);
132 m_instrset.insert(new CInstructionMul<T>);
133 m_instrset.insert(new CInstructionDiv<T>);
134 m_instrset.insert(new CInstructionLoad<T>);
135 m_instrset.insert(new CInstructionStore<T>);
136 m_instrset.insert(new CInstructionTest<T>);
137 m_instrset.insert(new CInstructionLabel<T>);
138 m_instrset.insert(new CInstructionJumpA<T>);
139 m_instrset.insert(new CInstructionJumpZ<T>);
140 m_instrset.insert(new CInstructionJumpS<T>);
141 m_instrset.insert(new CInstructionWrite<T>);
142}
143
144/*----------------------------------------------------------------------------*/
145
146template <class T>
147CProgram<T>::~CProgram()
148{
149 /* free instruction set */
150 for (setiterator it = m_instrset.begin(); it != m_instrset.end(); ++it)
151 delete *it;
152
153 /* free instruction */
154 for (iterator it2 = begin(); it2 != end(); ++it2)
155 delete *it2;
156}
157
158/*----------------------------------------------------------------------------*/
159
160template <class T>
161void CProgram<T>::compile(std::istream& in)
162{
163 if (!in.good())
164 return;
165
166 std::string line;
167 unsigned i = 0;
168 while (!in.eof() && in.good())
169 {
170 ++i;
171
172 /* read stream per line */
173 std::getline(in, line);
174 if (line.empty())
175 continue;
176
177 boost::trim(line);
178 boost::to_lower(line);
179
180 /* ignore comments */
181 if (line.find_first_of('#') == 0)
182 continue;
183
184 /* get instruction name */
185 size_t pos = line.find_first_of(' ');
186 std::string instrname(line.substr(0, pos));
187
188 /* search and create instruction */
189 CInstruction<T> *instrptr = NULL;
190 setiterator it;
191 for (it = m_instrset.begin(); it != m_instrset.end(); ++it)
192 {
193 if (*(*it) == instrname)
194 {
195 instrptr = *it;
196 break;
197 }
198 }
199 if (instrptr == NULL)
200 {
201 std::stringstream sstr;
202 sstr << "Unknown instruction '" << instrname << "' on line " << i << ".";
203 throw std::runtime_error(sstr.str());
204 }
205
206 /* create instruction */
207 CInstruction<T> *instr = instrptr->factory();
208
209 /* parse instruction parameters */
210 std::string params = (pos == std::string::npos) ? "" : line.substr(pos + 1);
211 boost::trim(params);
212 std::list<std::string> instrparams;
213 boost::split(instrparams, params, boost::is_any_of(", \t"), boost::token_compress_on);
214
215 /* let instruction parse the parameters. catch+throw exception */
216 try
217 {
218 /* handle label instruction ourself, but still add a dummy instruction */
219 if (instrname == "label")
220 {
221 if (instrparams.size() != 1)
222 throw std::runtime_error("Invalid paramater count - must be 1");
223 std::string label(instrparams.front());
224 if (label.length() < 2 || label[ label.length() - 1] != ':')
225 throw std::runtime_error("Label has invalid syntax");
226 m_labels[ label.substr(0, label.length() - 1) ] = size();
227 }
228 instr->compile(instrparams);
229 }
230 catch(std::runtime_error& ex)
231 {
232 std::stringstream sstr;
233 sstr << "Unable to compile instruction '" << instrname
234 << "' (line " << i << "): " << ex.what();
235 throw std::runtime_error(sstr.str());
236 }
237
238 push_back(instr);
239 }
240}
241
242/*----------------------------------------------------------------------------*/
243
244template <class T>
245unsigned CProgram<T>::findLabel(const std::string& label) const
246{
247 std::map<std::string, unsigned>::const_iterator it;
248 it = m_labels.find(label);
249 if (it == m_labels.end())
250 throw std::runtime_error("Unknown label '" + label + "'");
251 return it->second;
252}
253
254/*----------------------------------------------------------------------------*/
255
256#if DEBUG
257template <class T>
258void CProgram<T>::dump(std::ostream& out)
259{
260 out << "[PROGRAM DUMP]" << std::endl;
261 unsigned i = 0;
262 for(iterator it = begin(); it != end(); ++it)
263 {
264 out << "[" << std::setw(4) << std::setfill('0') << i << "] "
265 << *(*it) << std::endl;
266 ++i;
267 }
268}
269#endif
270
104#endif 271#endif
105 272
106/* vim: set et sw=2 ts=2: */ 273/* vim: set et sw=2 ts=2: */
diff --git a/ue4/mycpu/displays.h b/ue4/mycpu/displays.h
index d4f3f36..33d81bb 100644
--- a/ue4/mycpu/displays.h
+++ b/ue4/mycpu/displays.h
@@ -2,7 +2,7 @@
2 * @module displays 2 * @module displays
3 * @author Guenther Neuwirth (0626638), Manuel Mausz (0728348) 3 * @author Guenther Neuwirth (0626638), Manuel Mausz (0728348)
4 * @brief Implementations of CDisplay 4 * @brief Implementations of CDisplay
5 * @date 10.05.2009 5 * @date 26.05.2009
6 */ 6 */
7 7
8#ifndef DISPLAYS_H 8#ifndef DISPLAYS_H
@@ -15,14 +15,15 @@
15 * @class CDisplayWDEZ 15 * @class CDisplayWDEZ
16 * 16 *
17 * Implementation of CDisplay 17 * Implementation of CDisplay
18 * Prints CDat to stdout as decimal 18 * Prints T to stdout as decimal
19 */ 19 */
20template <class T>
20class CDisplayWDEZ 21class CDisplayWDEZ
21 : public CDisplay 22 : public CDisplay<T>
22{ 23{
23 public: 24 public:
24 CDisplayWDEZ() 25 CDisplayWDEZ()
25 : CDisplay("wdez") 26 : CDisplay<T>("wdez")
26 {} 27 {}
27 28
28 /** 29 /**
@@ -34,7 +35,7 @@ class CDisplayWDEZ
34 * @exception none 35 * @exception none
35 * @conditions none 36 * @conditions none
36 */ 37 */
37 void display(const CDat &value) 38 void display(const T &value)
38 { 39 {
39 std::cout << std::dec << value << std::endl; 40 std::cout << std::dec << value << std::endl;
40 } 41 }
@@ -46,14 +47,15 @@ class CDisplayWDEZ
46 * @class CDisplayWHEX 47 * @class CDisplayWHEX
47 * 48 *
48 * Implementation of CDisplay 49 * Implementation of CDisplay
49 * Prints CDat to stdout as decimal 50 * Prints T to stdout as decimal
50 */ 51 */
52template <class T>
51class CDisplayWHEX 53class CDisplayWHEX
52 : public CDisplay 54 : public CDisplay<T>
53{ 55{
54 public: 56 public:
55 CDisplayWHEX() 57 CDisplayWHEX()
56 : CDisplay("whex") 58 : CDisplay<T>("whex")
57 {} 59 {}
58 60
59 /** 61 /**
@@ -65,7 +67,7 @@ class CDisplayWHEX
65 * @exception none 67 * @exception none
66 * @conditions none 68 * @conditions none
67 */ 69 */
68 void display(const CDat &value) 70 void display(const T &value)
69 { 71 {
70 std::cout << std::hex << value << std::endl; 72 std::cout << std::hex << value << std::endl;
71 } 73 }
diff --git a/ue4/mycpu/instructions.cpp b/ue4/mycpu/instructions.cpp
deleted file mode 100644
index ef9e944..0000000
--- a/ue4/mycpu/instructions.cpp
+++ /dev/null
@@ -1,341 +0,0 @@
1/**
2 * @module instructions
3 * @author Guenther Neuwirth (0626638), Manuel Mausz (0728348)
4 * @brief Implementations of CInstruction
5 * @date 10.05.2009
6 */
7
8#include <map>
9#include <assert.h>
10#include "instructions.h"
11
12using namespace std;
13
14void CInstructionInc::compile(std::list<std::string>& params)
15{
16 if (params.size() != 1)
17 throw runtime_error("Invalid paramater count - must be 1");
18 m_regidx1 = parseRegister(params.front());
19 params.pop_front();
20}
21
22/*----------------------------------------------------------------------------*/
23
24void CInstructionInc::execute(CCPU *cpu)
25{
26 assert(cpu != NULL);
27 assert(cpu->getRegisters() != NULL);
28 checkRegister(cpu, m_regidx1);
29 cpu->getRegisters()[ m_regidx1 ]++;
30}
31
32/*============================================================================*/
33
34void CInstructionDec::compile(std::list<std::string>& params)
35{
36 if (params.size() != 1)
37 throw runtime_error("Invalid paramater count - must be 1");
38 m_regidx1 = parseRegister(params.front());
39 params.pop_front();
40}
41
42/*----------------------------------------------------------------------------*/
43
44void CInstructionDec::execute(CCPU *cpu)
45{
46 assert(cpu != NULL);
47 assert(cpu->getRegisters() != NULL);
48 checkRegister(cpu, m_regidx1);
49 cpu->getRegisters()[ m_regidx1 ]--;
50}
51
52/*============================================================================*/
53
54void CInstructionAdd::compile(std::list<std::string>& params)
55{
56 if (params.size() != 3)
57 throw runtime_error("Invalid paramater count - must be 3");
58 m_regidx1 = parseRegister(params.front());
59 params.pop_front();
60 m_regidx2 = parseRegister(params.front());
61 params.pop_front();
62 m_regidx3 = parseRegister(params.front());
63 params.pop_front();
64}
65
66/*----------------------------------------------------------------------------*/
67
68void CInstructionAdd::execute(CCPU *cpu)
69{
70 assert(cpu != NULL);
71 assert(cpu->getRegisters() != NULL);
72 checkRegister(cpu, m_regidx1);
73 checkRegister(cpu, m_regidx2);
74 checkRegister(cpu, m_regidx3);
75 cpu->getRegisters()[ m_regidx1 ] = cpu->getRegisters()[ m_regidx2 ]
76 + cpu->getRegisters()[ m_regidx3 ];
77}
78
79/*============================================================================*/
80
81void CInstructionSub::compile(std::list<std::string>& params)
82{
83 if (params.size() != 3)
84 throw runtime_error("Invalid paramater count - must be 3");
85 m_regidx1 = parseRegister(params.front());
86 params.pop_front();
87 m_regidx2 = parseRegister(params.front());
88 params.pop_front();
89 m_regidx3 = parseRegister(params.front());
90 params.pop_front();
91}
92
93/*----------------------------------------------------------------------------*/
94
95void CInstructionSub::execute(CCPU *cpu)
96{
97 assert(cpu != NULL);
98 assert(cpu->getRegisters() != NULL);
99 checkRegister(cpu, m_regidx1);
100 checkRegister(cpu, m_regidx2);
101 checkRegister(cpu, m_regidx3);
102 cpu->getRegisters()[ m_regidx1 ] = cpu->getRegisters()[ m_regidx2 ]
103 - cpu->getRegisters()[ m_regidx3 ];
104}
105
106/*============================================================================*/
107
108void CInstructionMul::compile(std::list<std::string>& params)
109{
110 if (params.size() != 3)
111 throw runtime_error("Invalid paramater count - must be 3");
112 m_regidx1 = parseRegister(params.front());
113 params.pop_front();
114 m_regidx2 = parseRegister(params.front());
115 params.pop_front();
116 m_regidx3 = parseRegister(params.front());
117 params.pop_front();
118}
119
120/*----------------------------------------------------------------------------*/
121
122void CInstructionMul::execute(CCPU *cpu)
123{
124 checkRegister(cpu, m_regidx1);
125 checkRegister(cpu, m_regidx2);
126 checkRegister(cpu, m_regidx3);
127 cpu->getRegisters()[ m_regidx1 ] = cpu->getRegisters()[ m_regidx2 ]
128 * cpu->getRegisters()[ m_regidx3 ];
129}
130
131/*============================================================================*/
132
133void CInstructionDiv::compile(std::list<std::string>& params)
134{
135 if (params.size() != 3)
136 throw runtime_error("Invalid paramater count - must be 3");
137 m_regidx1 = parseRegister(params.front());
138 params.pop_front();
139 m_regidx2 = parseRegister(params.front());
140 params.pop_front();
141 m_regidx3 = parseRegister(params.front());
142 params.pop_front();
143}
144
145/*----------------------------------------------------------------------------*/
146
147void CInstructionDiv::execute(CCPU *cpu)
148{
149 assert(cpu != NULL);
150 assert(cpu->getRegisters() != NULL);
151 checkRegister(cpu, m_regidx1);
152 checkRegister(cpu, m_regidx2);
153 checkRegister(cpu, m_regidx3);
154 cpu->getRegisters()[ m_regidx1 ] = cpu->getRegisters()[ m_regidx2 ]
155 / cpu->getRegisters()[ m_regidx3 ];
156}
157
158/*============================================================================*/
159
160void CInstructionLoad::compile(std::list<std::string>& params)
161{
162 if (params.size() != 2)
163 throw runtime_error("Invalid paramater count - must be 2");
164 m_regidx1 = parseRegister(params.front());
165 params.pop_front();
166 m_regidx2 = parseRegister(params.front());
167 params.pop_front();
168}
169
170/*----------------------------------------------------------------------------*/
171
172void CInstructionLoad::execute(CCPU *cpu)
173{
174 assert(cpu != NULL);
175 assert(cpu->getRegisters() != NULL);
176 assert(cpu->getMemory() != NULL);
177 checkRegister(cpu, m_regidx1);
178 checkRegister(cpu, m_regidx2);
179 CDat val(cpu->getRegisters()[ m_regidx2 ]);
180 cpu->getRegisters()[ m_regidx1 ] = (*cpu->getMemory())[ val ];
181}
182
183/*============================================================================*/
184
185void CInstructionStore::compile(std::list<std::string>& params)
186{
187 if (params.size() != 2)
188 throw runtime_error("Invalid paramater count - must be 2");
189 m_regidx1 = parseRegister(params.front());
190 params.pop_front();
191 m_regidx2 = parseRegister(params.front());
192 params.pop_front();
193}
194
195/*----------------------------------------------------------------------------*/
196
197void CInstructionStore::execute(CCPU *cpu)
198{
199 assert(cpu != NULL);
200 assert(cpu->getRegisters() != NULL);
201 assert(cpu->getMemory() != NULL);
202 checkRegister(cpu, m_regidx1);
203 checkRegister(cpu, m_regidx2);
204 CDat val(cpu->getRegisters()[ m_regidx2 ]);
205 (*cpu->getMemory())[ val ] = cpu->getRegisters()[ m_regidx1 ];
206}
207
208/*============================================================================*/
209
210void CInstructionTest::compile(std::list<std::string>& params)
211{
212 if (params.size() != 1)
213 throw runtime_error("Invalid paramater count - must be 1");
214 m_regidx1 = parseRegister(params.front());
215 params.pop_front();
216}
217
218/*----------------------------------------------------------------------------*/
219
220void CInstructionTest::execute(CCPU *cpu)
221{
222 assert(cpu != NULL);
223 assert(cpu->getRegisters() != NULL);
224 checkRegister(cpu, m_regidx1);
225 if (cpu->getRegisters()[ m_regidx1 ] == CDat(0))
226 cpu->setFlagZero(true);
227 if (cpu->getRegisters()[ m_regidx1 ] < CDat(0))
228 cpu->setFlagSign(true);
229}
230
231/*============================================================================*/
232
233void CInstructionJumpA::compile(std::list<std::string>& params)
234{
235 if (params.size() != 1)
236 throw runtime_error("Invalid paramater count - must be 1");
237 m_addr = params.front();
238 params.pop_front();
239}
240
241/*----------------------------------------------------------------------------*/
242
243void CInstructionJumpA::execute(CCPU *cpu)
244{
245 assert(cpu != NULL);
246 assert(cpu->getRegisters() != NULL);
247 assert(cpu->getProgram() != NULL);
248 if (m_addr.empty())
249 throw runtime_error("Empty address");
250 cpu->getRegisters()[ 0 ] = cpu->getProgram()->findLabel(m_addr);
251}
252
253/*============================================================================*/
254
255void CInstructionJumpZ::compile(std::list<std::string>& params)
256{
257 if (params.size() != 1)
258 throw runtime_error("Invalid paramater count - must be 1");
259 m_addr = params.front();
260 params.pop_front();
261}
262
263/*----------------------------------------------------------------------------*/
264
265void CInstructionJumpZ::execute(CCPU *cpu)
266{
267 assert(cpu != NULL);
268 assert(cpu->getRegisters() != NULL);
269 assert(cpu->getProgram() != NULL);
270 if (!cpu->getFlagZero())
271 return;
272 if (m_addr.empty())
273 throw runtime_error("Empty address");
274 cpu->getRegisters()[ 0 ] = cpu->getProgram()->findLabel(m_addr);
275}
276
277/*============================================================================*/
278
279void CInstructionJumpS::compile(std::list<std::string>& params)
280{
281 if (params.size() != 1)
282 throw runtime_error("Invalid paramater count - must be 1");
283 m_addr = params.front();
284 params.pop_front();
285}
286
287/*----------------------------------------------------------------------------*/
288
289void CInstructionJumpS::execute(CCPU *cpu)
290{
291 assert(cpu != NULL);
292 assert(cpu->getRegisters() != NULL);
293 assert(cpu->getProgram() != NULL);
294 if (!cpu->getFlagSign())
295 return;
296 if (m_addr.empty())
297 throw runtime_error("Empty address");
298 cpu->getRegisters()[ 0 ] = cpu->getProgram()->findLabel(m_addr);
299}
300
301/*============================================================================*/
302
303void CInstructionWrite::compile(std::list<std::string>& params)
304{
305 if (params.size() != 2)
306 throw runtime_error("Invalid paramater count - must be 2");
307 m_dev = params.front();
308 params.pop_front();
309 m_regidx1 = parseRegister(params.front());
310 params.pop_front();
311}
312
313/*----------------------------------------------------------------------------*/
314
315void CInstructionWrite::execute(CCPU *cpu)
316{
317 assert(cpu != NULL);
318 assert(cpu->getRegisters() != NULL);
319 checkRegister(cpu, m_regidx1);
320 if (m_dev.empty())
321 throw runtime_error("Empty device");
322
323 CDisplay *display = NULL;
324 std::set<CDisplay *> displays = cpu->getDisplays();
325 std::set<CDisplay *>::iterator it;
326 for(it = displays.begin(); it != displays.end(); ++it)
327 {
328 if ((*it)->getName() == m_dev)
329 {
330 display = *it;
331 break;
332 }
333 }
334 if (display == NULL)
335 throw runtime_error("Unknown display");
336
337 display->display(cpu->getRegisters()[ m_regidx1 ]);
338}
339
340
341/* vim: set et sw=2 ts=2: */
diff --git a/ue4/mycpu/instructions.h b/ue4/mycpu/instructions.h
index 4c36562..fcff3e7 100644
--- a/ue4/mycpu/instructions.h
+++ b/ue4/mycpu/instructions.h
@@ -2,7 +2,7 @@
2 * @module instructions 2 * @module instructions
3 * @author Guenther Neuwirth (0626638), Manuel Mausz (0728348) 3 * @author Guenther Neuwirth (0626638), Manuel Mausz (0728348)
4 * @brief Implementations of CInstruction 4 * @brief Implementations of CInstruction
5 * @date 10.05.2009 5 * @date 26.05.2009
6 */ 6 */
7 7
8#ifndef INSTRUCTIONS_H 8#ifndef INSTRUCTIONS_H
@@ -10,6 +10,7 @@
10 10
11#include "cinstruction.h" 11#include "cinstruction.h"
12#include "ccpu.h" 12#include "ccpu.h"
13#include "cprogram.h"
13 14
14/** 15/**
15 * @class CInstructionInc 16 * @class CInstructionInc
@@ -18,12 +19,15 @@
18 * Syntax: inc R1 19 * Syntax: inc R1
19 * (R1++) 20 * (R1++)
20 */ 21 */
22template <class T>
21class CInstructionInc 23class CInstructionInc
22 : public CInstruction 24 : public CInstruction<T>
23{ 25{
26 typedef CInstruction<T> super;
27
24 public: 28 public:
25 CInstructionInc() 29 CInstructionInc()
26 : CInstruction("inc") 30 : CInstruction<T>("inc")
27 {} 31 {}
28 32
29 CInstructionInc *factory() 33 CInstructionInc *factory()
@@ -32,13 +36,35 @@ class CInstructionInc
32 } 36 }
33 37
34 void compile(std::list<std::string>& params); 38 void compile(std::list<std::string>& params);
35 void execute(CCPU *cpu); 39 void execute(CCPU<T> *cpu);
36 40
37 protected: 41 protected:
38 /** register number */ 42 /** register number */
39 unsigned m_regidx1; 43 unsigned m_regidx1;
40}; 44};
41 45
46/*----------------------------------------------------------------------------*/
47
48template <class T>
49void CInstructionInc<T>::compile(std::list<std::string>& params)
50{
51 if (params.size() != 1)
52 throw std::runtime_error("Invalid paramater count - must be 1");
53 m_regidx1 = super::parseRegister(params.front());
54 params.pop_front();
55}
56
57/*----------------------------------------------------------------------------*/
58
59template <class T>
60void CInstructionInc<T>::execute(CCPU<T> *cpu)
61{
62 assert(cpu != NULL);
63 assert(cpu->getRegisters() != NULL);
64 super::checkRegister(cpu, m_regidx1);
65 cpu->getRegisters()[ m_regidx1 ]++;
66}
67
42/*============================================================================*/ 68/*============================================================================*/
43 69
44/** 70/**
@@ -48,12 +74,15 @@ class CInstructionInc
48 * Syntax: dec R1 74 * Syntax: dec R1
49 * (R1--) 75 * (R1--)
50 */ 76 */
77template <class T>
51class CInstructionDec 78class CInstructionDec
52 : public CInstruction 79 : public CInstruction<T>
53{ 80{
81 typedef CInstruction<T> super;
82
54 public: 83 public:
55 CInstructionDec() 84 CInstructionDec()
56 : CInstruction("dec") 85 : CInstruction<T>("dec")
57 {} 86 {}
58 87
59 CInstructionDec *factory() 88 CInstructionDec *factory()
@@ -62,13 +91,35 @@ class CInstructionDec
62 } 91 }
63 92
64 void compile(std::list<std::string>& params); 93 void compile(std::list<std::string>& params);
65 void execute(CCPU *cpu); 94 void execute(CCPU<T> *cpu);
66 95
67 protected: 96 protected:
68 /** register number */ 97 /** register number */
69 unsigned m_regidx1; 98 unsigned m_regidx1;
70}; 99};
71 100
101/*----------------------------------------------------------------------------*/
102
103template <class T>
104void CInstructionDec<T>::compile(std::list<std::string>& params)
105{
106 if (params.size() != 1)
107 throw std::runtime_error("Invalid paramater count - must be 1");
108 m_regidx1 = super::parseRegister(params.front());
109 params.pop_front();
110}
111
112/*----------------------------------------------------------------------------*/
113
114template <class T>
115void CInstructionDec<T>::execute(CCPU<T> *cpu)
116{
117 assert(cpu != NULL);
118 assert(cpu->getRegisters() != NULL);
119 super::checkRegister(cpu, m_regidx1);
120 cpu->getRegisters()[ m_regidx1 ]--;
121}
122
72/*============================================================================*/ 123/*============================================================================*/
73 124
74/** 125/**
@@ -78,12 +129,15 @@ class CInstructionDec
78 * Syntax: add R1, R2, R3 129 * Syntax: add R1, R2, R3
79 * (R1 = R2 + R3) 130 * (R1 = R2 + R3)
80 */ 131 */
132template <class T>
81class CInstructionAdd 133class CInstructionAdd
82 : public CInstruction 134 : public CInstruction<T>
83{ 135{
136 typedef CInstruction<T> super;
137
84 public: 138 public:
85 CInstructionAdd() 139 CInstructionAdd()
86 : CInstruction("add") 140 : CInstruction<T>("add")
87 {} 141 {}
88 142
89 CInstructionAdd *factory() 143 CInstructionAdd *factory()
@@ -92,7 +146,7 @@ class CInstructionAdd
92 } 146 }
93 147
94 void compile(std::list<std::string>& params); 148 void compile(std::list<std::string>& params);
95 void execute(CCPU *cpu); 149 void execute(CCPU<T> *cpu);
96 150
97 protected: 151 protected:
98 /** register number */ 152 /** register number */
@@ -103,6 +157,35 @@ class CInstructionAdd
103 unsigned m_regidx3; 157 unsigned m_regidx3;
104}; 158};
105 159
160/*----------------------------------------------------------------------------*/
161
162template <class T>
163void CInstructionAdd<T>::compile(std::list<std::string>& params)
164{
165 if (params.size() != 3)
166 throw std::runtime_error("Invalid paramater count - must be 3");
167 m_regidx1 = super::parseRegister(params.front());
168 params.pop_front();
169 m_regidx2 = super::parseRegister(params.front());
170 params.pop_front();
171 m_regidx3 = super::parseRegister(params.front());
172 params.pop_front();
173}
174
175/*----------------------------------------------------------------------------*/
176
177template <class T>
178void CInstructionAdd<T>::execute(CCPU<T> *cpu)
179{
180 assert(cpu != NULL);
181 assert(cpu->getRegisters() != NULL);
182 super::checkRegister(cpu, m_regidx1);
183 super::checkRegister(cpu, m_regidx2);
184 super::checkRegister(cpu, m_regidx3);
185 cpu->getRegisters()[ m_regidx1 ] = cpu->getRegisters()[ m_regidx2 ]
186 + cpu->getRegisters()[ m_regidx3 ];
187}
188
106/*============================================================================*/ 189/*============================================================================*/
107 190
108/** 191/**
@@ -112,12 +195,15 @@ class CInstructionAdd
112 * Syntax: sub R1, R2, R3 195 * Syntax: sub R1, R2, R3
113 * (R1 = R2 - R3) 196 * (R1 = R2 - R3)
114 */ 197 */
198template <class T>
115class CInstructionSub 199class CInstructionSub
116 : public CInstruction 200 : public CInstruction<T>
117{ 201{
202 typedef CInstruction<T> super;
203
118 public: 204 public:
119 CInstructionSub() 205 CInstructionSub()
120 : CInstruction("sub") 206 : CInstruction<T>("sub")
121 {} 207 {}
122 208
123 CInstructionSub *factory() 209 CInstructionSub *factory()
@@ -126,7 +212,7 @@ class CInstructionSub
126 } 212 }
127 213
128 void compile(std::list<std::string>& params); 214 void compile(std::list<std::string>& params);
129 void execute(CCPU *cpu); 215 void execute(CCPU<T> *cpu);
130 216
131 protected: 217 protected:
132 /** register number */ 218 /** register number */
@@ -137,6 +223,35 @@ class CInstructionSub
137 unsigned m_regidx3; 223 unsigned m_regidx3;
138}; 224};
139 225
226/*----------------------------------------------------------------------------*/
227
228template <class T>
229void CInstructionSub<T>::compile(std::list<std::string>& params)
230{
231 if (params.size() != 3)
232 throw std::runtime_error("Invalid paramater count - must be 3");
233 m_regidx1 = super::parseRegister(params.front());
234 params.pop_front();
235 m_regidx2 = super::parseRegister(params.front());
236 params.pop_front();
237 m_regidx3 = super::parseRegister(params.front());
238 params.pop_front();
239}
240
241/*----------------------------------------------------------------------------*/
242
243template <class T>
244void CInstructionSub<T>::execute(CCPU<T> *cpu)
245{
246 assert(cpu != NULL);
247 assert(cpu->getRegisters() != NULL);
248 super::checkRegister(cpu, m_regidx1);
249 super::checkRegister(cpu, m_regidx2);
250 super::checkRegister(cpu, m_regidx3);
251 cpu->getRegisters()[ m_regidx1 ] = cpu->getRegisters()[ m_regidx2 ]
252 - cpu->getRegisters()[ m_regidx3 ];
253}
254
140/*============================================================================*/ 255/*============================================================================*/
141 256
142/** 257/**
@@ -146,12 +261,15 @@ class CInstructionSub
146 * Syntax: mul R1, R2, R3 261 * Syntax: mul R1, R2, R3
147 * (R1 = R2 * R3) 262 * (R1 = R2 * R3)
148 */ 263 */
264template <class T>
149class CInstructionMul 265class CInstructionMul
150 : public CInstruction 266 : public CInstruction<T>
151{ 267{
268 typedef CInstruction<T> super;
269
152 public: 270 public:
153 CInstructionMul() 271 CInstructionMul()
154 : CInstruction("mul") 272 : CInstruction<T>("mul")
155 {} 273 {}
156 274
157 CInstructionMul *factory() 275 CInstructionMul *factory()
@@ -160,7 +278,7 @@ class CInstructionMul
160 } 278 }
161 279
162 void compile(std::list<std::string>& params); 280 void compile(std::list<std::string>& params);
163 void execute(CCPU *cpu); 281 void execute(CCPU<T> *cpu);
164 282
165 protected: 283 protected:
166 /** register number */ 284 /** register number */
@@ -171,6 +289,33 @@ class CInstructionMul
171 unsigned m_regidx3; 289 unsigned m_regidx3;
172}; 290};
173 291
292/*----------------------------------------------------------------------------*/
293
294template <class T>
295void CInstructionMul<T>::compile(std::list<std::string>& params)
296{
297 if (params.size() != 3)
298 throw std::runtime_error("Invalid paramater count - must be 3");
299 m_regidx1 = super::parseRegister(params.front());
300 params.pop_front();
301 m_regidx2 = super::parseRegister(params.front());
302 params.pop_front();
303 m_regidx3 = super::parseRegister(params.front());
304 params.pop_front();
305}
306
307/*----------------------------------------------------------------------------*/
308
309template <class T>
310void CInstructionMul<T>::execute(CCPU<T> *cpu)
311{
312 super::checkRegister(cpu, m_regidx1);
313 super::checkRegister(cpu, m_regidx2);
314 super::checkRegister(cpu, m_regidx3);
315 cpu->getRegisters()[ m_regidx1 ] = cpu->getRegisters()[ m_regidx2 ]
316 * cpu->getRegisters()[ m_regidx3 ];
317}
318
174/*============================================================================*/ 319/*============================================================================*/
175 320
176/** 321/**
@@ -180,12 +325,15 @@ class CInstructionMul
180 * Syntax: div R1, R2, R3 325 * Syntax: div R1, R2, R3
181 * (R1 = R2 / R3) 326 * (R1 = R2 / R3)
182 */ 327 */
328template <class T>
183class CInstructionDiv 329class CInstructionDiv
184 : public CInstruction 330 : public CInstruction<T>
185{ 331{
332 typedef CInstruction<T> super;
333
186 public: 334 public:
187 CInstructionDiv() 335 CInstructionDiv()
188 : CInstruction("div") 336 : CInstruction<T>("div")
189 {} 337 {}
190 338
191 CInstructionDiv *factory() 339 CInstructionDiv *factory()
@@ -194,7 +342,7 @@ class CInstructionDiv
194 } 342 }
195 343
196 void compile(std::list<std::string>& params); 344 void compile(std::list<std::string>& params);
197 void execute(CCPU *cpu); 345 void execute(CCPU<T> *cpu);
198 346
199 protected: 347 protected:
200 /** register number */ 348 /** register number */
@@ -205,6 +353,35 @@ class CInstructionDiv
205 unsigned m_regidx3; 353 unsigned m_regidx3;
206}; 354};
207 355
356/*----------------------------------------------------------------------------*/
357
358template <class T>
359void CInstructionDiv<T>::compile(std::list<std::string>& params)
360{
361 if (params.size() != 3)
362 throw std::runtime_error("Invalid paramater count - must be 3");
363 m_regidx1 = super::parseRegister(params.front());
364 params.pop_front();
365 m_regidx2 = super::parseRegister(params.front());
366 params.pop_front();
367 m_regidx3 = super::parseRegister(params.front());
368 params.pop_front();
369}
370
371/*----------------------------------------------------------------------------*/
372
373template <class T>
374void CInstructionDiv<T>::execute(CCPU<T> *cpu)
375{
376 assert(cpu != NULL);
377 assert(cpu->getRegisters() != NULL);
378 super::checkRegister(cpu, m_regidx1);
379 super::checkRegister(cpu, m_regidx2);
380 super::checkRegister(cpu, m_regidx3);
381 cpu->getRegisters()[ m_regidx1 ] = cpu->getRegisters()[ m_regidx2 ]
382 / cpu->getRegisters()[ m_regidx3 ];
383}
384
208/*============================================================================*/ 385/*============================================================================*/
209 386
210/** 387/**
@@ -214,12 +391,15 @@ class CInstructionDiv
214 * Syntax: load R1, R2 391 * Syntax: load R1, R2
215 * (R1 = memory[R2]) 392 * (R1 = memory[R2])
216 */ 393 */
394template <class T>
217class CInstructionLoad 395class CInstructionLoad
218 : public CInstruction 396 : public CInstruction<T>
219{ 397{
398 typedef CInstruction<T> super;
399
220 public: 400 public:
221 CInstructionLoad() 401 CInstructionLoad()
222 : CInstruction("load") 402 : CInstruction<T>("load")
223 {} 403 {}
224 404
225 CInstructionLoad *factory() 405 CInstructionLoad *factory()
@@ -228,7 +408,7 @@ class CInstructionLoad
228 } 408 }
229 409
230 void compile(std::list<std::string>& params); 410 void compile(std::list<std::string>& params);
231 void execute(CCPU *cpu); 411 void execute(CCPU<T> *cpu);
232 412
233 protected: 413 protected:
234 /** register number */ 414 /** register number */
@@ -237,6 +417,33 @@ class CInstructionLoad
237 unsigned m_regidx2; 417 unsigned m_regidx2;
238}; 418};
239 419
420/*----------------------------------------------------------------------------*/
421
422template <class T>
423void CInstructionLoad<T>::compile(std::list<std::string>& params)
424{
425 if (params.size() != 2)
426 throw std::runtime_error("Invalid paramater count - must be 2");
427 m_regidx1 = super::parseRegister(params.front());
428 params.pop_front();
429 m_regidx2 = super::parseRegister(params.front());
430 params.pop_front();
431}
432
433/*----------------------------------------------------------------------------*/
434
435template <class T>
436void CInstructionLoad<T>::execute(CCPU<T> *cpu)
437{
438 assert(cpu != NULL);
439 assert(cpu->getRegisters() != NULL);
440 assert(cpu->getMemory() != NULL);
441 super::checkRegister(cpu, m_regidx1);
442 super::checkRegister(cpu, m_regidx2);
443 T val(cpu->getRegisters()[ m_regidx2 ]);
444 cpu->getRegisters()[ m_regidx1 ] = (*cpu->getMemory())[ val ];
445}
446
240/*============================================================================*/ 447/*============================================================================*/
241 448
242/** 449/**
@@ -246,12 +453,15 @@ class CInstructionLoad
246 * Syntax: store R1, R2 453 * Syntax: store R1, R2
247 * (memory[R2] = R1) 454 * (memory[R2] = R1)
248 */ 455 */
456template <class T>
249class CInstructionStore 457class CInstructionStore
250 : public CInstruction 458 : public CInstruction<T>
251{ 459{
460 typedef CInstruction<T> super;
461
252 public: 462 public:
253 CInstructionStore() 463 CInstructionStore()
254 : CInstruction("store") 464 : CInstruction<T>("store")
255 {} 465 {}
256 466
257 CInstructionStore *factory() 467 CInstructionStore *factory()
@@ -260,7 +470,7 @@ class CInstructionStore
260 } 470 }
261 471
262 void compile(std::list<std::string>& params); 472 void compile(std::list<std::string>& params);
263 void execute(CCPU *cpu); 473 void execute(CCPU<T> *cpu);
264 474
265 protected: 475 protected:
266 /** register number */ 476 /** register number */
@@ -269,6 +479,33 @@ class CInstructionStore
269 unsigned m_regidx2; 479 unsigned m_regidx2;
270}; 480};
271 481
482/*----------------------------------------------------------------------------*/
483
484template <class T>
485void CInstructionStore<T>::compile(std::list<std::string>& params)
486{
487 if (params.size() != 2)
488 throw std::runtime_error("Invalid paramater count - must be 2");
489 m_regidx1 = super::parseRegister(params.front());
490 params.pop_front();
491 m_regidx2 = super::parseRegister(params.front());
492 params.pop_front();
493}
494
495/*----------------------------------------------------------------------------*/
496
497template <class T>
498void CInstructionStore<T>::execute(CCPU<T> *cpu)
499{
500 assert(cpu != NULL);
501 assert(cpu->getRegisters() != NULL);
502 assert(cpu->getMemory() != NULL);
503 super::checkRegister(cpu, m_regidx1);
504 super::checkRegister(cpu, m_regidx2);
505 T val(cpu->getRegisters()[ m_regidx2 ]);
506 (*cpu->getMemory())[ val ] = cpu->getRegisters()[ m_regidx1 ];
507}
508
272/*============================================================================*/ 509/*============================================================================*/
273 510
274/** 511/**
@@ -278,12 +515,15 @@ class CInstructionStore
278 * Syntax: test R1 515 * Syntax: test R1
279 * (R1 == 0: zeroflag: true, R1 < 0: signflag: true) 516 * (R1 == 0: zeroflag: true, R1 < 0: signflag: true)
280 */ 517 */
518template <class T>
281class CInstructionTest 519class CInstructionTest
282 : public CInstruction 520 : public CInstruction<T>
283{ 521{
522 typedef CInstruction<T> super;
523
284 public: 524 public:
285 CInstructionTest() 525 CInstructionTest()
286 : CInstruction("test") 526 : CInstruction<T>("test")
287 {} 527 {}
288 528
289 CInstructionTest *factory() 529 CInstructionTest *factory()
@@ -292,13 +532,38 @@ class CInstructionTest
292 } 532 }
293 533
294 void compile(std::list<std::string>& params); 534 void compile(std::list<std::string>& params);
295 void execute(CCPU *cpu); 535 void execute(CCPU<T> *cpu);
296 536
297 protected: 537 protected:
298 /** register number */ 538 /** register number */
299 unsigned m_regidx1; 539 unsigned m_regidx1;
300}; 540};
301 541
542/*----------------------------------------------------------------------------*/
543
544template <class T>
545void CInstructionTest<T>::compile(std::list<std::string>& params)
546{
547 if (params.size() != 1)
548 throw std::runtime_error("Invalid paramater count - must be 1");
549 m_regidx1 = super::parseRegister(params.front());
550 params.pop_front();
551}
552
553/*----------------------------------------------------------------------------*/
554
555template <class T>
556void CInstructionTest<T>::execute(CCPU<T> *cpu)
557{
558 assert(cpu != NULL);
559 assert(cpu->getRegisters() != NULL);
560 super::checkRegister(cpu, m_regidx1);
561 if (cpu->getRegisters()[ m_regidx1 ] == T(0))
562 cpu->setFlagZero(true);
563 if (cpu->getRegisters()[ m_regidx1 ] < T(0))
564 cpu->setFlagSign(true);
565}
566
302/*============================================================================*/ 567/*============================================================================*/
303 568
304/** 569/**
@@ -307,12 +572,15 @@ class CInstructionTest
307 * Implementation of assembler command "label" 572 * Implementation of assembler command "label"
308 * Syntax: label name: 573 * Syntax: label name:
309 */ 574 */
575template <class T>
310class CInstructionLabel 576class CInstructionLabel
311 : public CInstruction 577 : public CInstruction<T>
312{ 578{
579 typedef CInstruction<T> super;
580
313 public: 581 public:
314 CInstructionLabel() 582 CInstructionLabel()
315 : CInstruction("label") 583 : CInstruction<T>("label")
316 {} 584 {}
317 585
318 CInstructionLabel *factory() 586 CInstructionLabel *factory()
@@ -323,7 +591,7 @@ class CInstructionLabel
323 void compile(std::list<std::string>& params) 591 void compile(std::list<std::string>& params)
324 {} 592 {}
325 593
326 void execute(CCPU *cpu) 594 void execute(CCPU<T> *cpu)
327 {} 595 {}
328}; 596};
329 597
@@ -336,12 +604,15 @@ class CInstructionLabel
336 * Syntax: jumpa labelname 604 * Syntax: jumpa labelname
337 * (jump to labelname) 605 * (jump to labelname)
338 */ 606 */
607template <class T>
339class CInstructionJumpA 608class CInstructionJumpA
340 : public CInstruction 609 : public CInstruction<T>
341{ 610{
611 typedef CInstruction<T> super;
612
342 public: 613 public:
343 CInstructionJumpA() 614 CInstructionJumpA()
344 : CInstruction("jumpa"), m_addr("") 615 : CInstruction<T>("jumpa"), m_addr("")
345 {} 616 {}
346 617
347 CInstructionJumpA *factory() 618 CInstructionJumpA *factory()
@@ -350,13 +621,37 @@ class CInstructionJumpA
350 } 621 }
351 622
352 void compile(std::list<std::string>& params); 623 void compile(std::list<std::string>& params);
353 void execute(CCPU *cpu); 624 void execute(CCPU<T> *cpu);
354 625
355 protected: 626 protected:
356 /** labelname */ 627 /** labelname */
357 std::string m_addr; 628 std::string m_addr;
358}; 629};
359 630
631/*----------------------------------------------------------------------------*/
632
633template <class T>
634void CInstructionJumpA<T>::compile(std::list<std::string>& params)
635{
636 if (params.size() != 1)
637 throw std::runtime_error("Invalid paramater count - must be 1");
638 m_addr = params.front();
639 params.pop_front();
640}
641
642/*----------------------------------------------------------------------------*/
643
644template <class T>
645void CInstructionJumpA<T>::execute(CCPU<T> *cpu)
646{
647 assert(cpu != NULL);
648 assert(cpu->getRegisters() != NULL);
649 assert(cpu->getProgram() != NULL);
650 if (m_addr.empty())
651 throw std::runtime_error("Empty address");
652 cpu->getRegisters()[ 0 ] = cpu->getProgram()->findLabel(m_addr);
653}
654
360/*============================================================================*/ 655/*============================================================================*/
361 656
362/** 657/**
@@ -366,12 +661,15 @@ class CInstructionJumpA
366 * Syntax: jumpz labelname 661 * Syntax: jumpz labelname
367 * (jump to labelname if zeroflag) 662 * (jump to labelname if zeroflag)
368 */ 663 */
664template <class T>
369class CInstructionJumpZ 665class CInstructionJumpZ
370 : public CInstruction 666 : public CInstruction<T>
371{ 667{
668 typedef CInstruction<T> super;
669
372 public: 670 public:
373 CInstructionJumpZ() 671 CInstructionJumpZ()
374 : CInstruction("jumpz"), m_addr("") 672 : CInstruction<T>("jumpz"), m_addr("")
375 {} 673 {}
376 674
377 CInstructionJumpZ *factory() 675 CInstructionJumpZ *factory()
@@ -380,13 +678,39 @@ class CInstructionJumpZ
380 } 678 }
381 679
382 void compile(std::list<std::string>& params); 680 void compile(std::list<std::string>& params);
383 void execute(CCPU *cpu); 681 void execute(CCPU<T> *cpu);
384 682
385 protected: 683 protected:
386 /** labelname */ 684 /** labelname */
387 std::string m_addr; 685 std::string m_addr;
388}; 686};
389 687
688/*----------------------------------------------------------------------------*/
689
690template <class T>
691void CInstructionJumpZ<T>::compile(std::list<std::string>& params)
692{
693 if (params.size() != 1)
694 throw std::runtime_error("Invalid paramater count - must be 1");
695 m_addr = params.front();
696 params.pop_front();
697}
698
699/*----------------------------------------------------------------------------*/
700
701template <class T>
702void CInstructionJumpZ<T>::execute(CCPU<T> *cpu)
703{
704 assert(cpu != NULL);
705 assert(cpu->getRegisters() != NULL);
706 assert(cpu->getProgram() != NULL);
707 if (!cpu->getFlagZero())
708 return;
709 if (m_addr.empty())
710 throw std::runtime_error("Empty address");
711 cpu->getRegisters()[ 0 ] = cpu->getProgram()->findLabel(m_addr);
712}
713
390/*============================================================================*/ 714/*============================================================================*/
391 715
392/** 716/**
@@ -396,12 +720,15 @@ class CInstructionJumpZ
396 * Syntax: jumps labelname 720 * Syntax: jumps labelname
397 * (jump to labelname if signflag) 721 * (jump to labelname if signflag)
398 */ 722 */
723template <class T>
399class CInstructionJumpS 724class CInstructionJumpS
400 : public CInstruction 725 : public CInstruction<T>
401{ 726{
727 typedef CInstruction<T> super;
728
402 public: 729 public:
403 CInstructionJumpS() 730 CInstructionJumpS()
404 : CInstruction("jumps"), m_addr("") 731 : CInstruction<T>("jumps"), m_addr("")
405 {} 732 {}
406 733
407 CInstructionJumpS *factory() 734 CInstructionJumpS *factory()
@@ -410,13 +737,39 @@ class CInstructionJumpS
410 } 737 }
411 738
412 void compile(std::list<std::string>& params); 739 void compile(std::list<std::string>& params);
413 void execute(CCPU *cpu); 740 void execute(CCPU<T> *cpu);
414 741
415 protected: 742 protected:
416 /** labelname */ 743 /** labelname */
417 std::string m_addr; 744 std::string m_addr;
418}; 745};
419 746
747/*----------------------------------------------------------------------------*/
748
749template <class T>
750void CInstructionJumpS<T>::compile(std::list<std::string>& params)
751{
752 if (params.size() != 1)
753 throw std::runtime_error("Invalid paramater count - must be 1");
754 m_addr = params.front();
755 params.pop_front();
756}
757
758/*----------------------------------------------------------------------------*/
759
760template <class T>
761void CInstructionJumpS<T>::execute(CCPU<T> *cpu)
762{
763 assert(cpu != NULL);
764 assert(cpu->getRegisters() != NULL);
765 assert(cpu->getProgram() != NULL);
766 if (!cpu->getFlagSign())
767 return;
768 if (m_addr.empty())
769 throw std::runtime_error("Empty address");
770 cpu->getRegisters()[ 0 ] = cpu->getProgram()->findLabel(m_addr);
771}
772
420/*============================================================================*/ 773/*============================================================================*/
421 774
422/** 775/**
@@ -426,12 +779,16 @@ class CInstructionJumpS
426 * Syntax: write DEV, R1 779 * Syntax: write DEV, R1
427 * (write R1 to DEV, which is a name of a display) 780 * (write R1 to DEV, which is a name of a display)
428 */ 781 */
782template <class T>
429class CInstructionWrite 783class CInstructionWrite
430 : public CInstruction 784 : public CInstruction<T>
431{ 785{
786 typedef CInstruction<T> super;
787 typedef typename std::set<CDisplay<T> *>::iterator setiterator;
788
432 public: 789 public:
433 CInstructionWrite() 790 CInstructionWrite()
434 : CInstruction("write"), m_dev("") 791 : CInstruction<T>("write"), m_dev("")
435 {} 792 {}
436 793
437 CInstructionWrite *factory() 794 CInstructionWrite *factory()
@@ -440,7 +797,7 @@ class CInstructionWrite
440 } 797 }
441 798
442 void compile(std::list<std::string>& params); 799 void compile(std::list<std::string>& params);
443 void execute(CCPU *cpu); 800 void execute(CCPU<T> *cpu);
444 801
445 protected: 802 protected:
446 /** register number */ 803 /** register number */
@@ -449,6 +806,46 @@ class CInstructionWrite
449 std::string m_dev; 806 std::string m_dev;
450}; 807};
451 808
809/*----------------------------------------------------------------------------*/
810
811template <class T>
812void CInstructionWrite<T>::compile(std::list<std::string>& params)
813{
814 if (params.size() != 2)
815 throw std::runtime_error("Invalid paramater count - must be 2");
816 m_dev = params.front();
817 params.pop_front();
818 m_regidx1 = super::parseRegister(params.front());
819 params.pop_front();
820}
821
822/*----------------------------------------------------------------------------*/
823
824template <class T>
825void CInstructionWrite<T>::execute(CCPU<T> *cpu)
826{
827 assert(cpu != NULL);
828 assert(cpu->getRegisters() != NULL);
829 super::checkRegister(cpu, m_regidx1);
830 if (m_dev.empty())
831 throw std::runtime_error("Empty device");
832
833 CDisplay<T> *display = NULL;
834 std::set<CDisplay<T> *> displays = cpu->getDisplays();
835 for(setiterator it = displays.begin(); it != displays.end(); ++it)
836 {
837 if ((*it)->getName() == m_dev)
838 {
839 display = *it;
840 break;
841 }
842 }
843 if (display == NULL)
844 throw std::runtime_error("Unknown display");
845
846 display->display(cpu->getRegisters()[ m_regidx1 ]);
847}
848
452#endif 849#endif
453 850
454/* vim: set et sw=2 ts=2: */ 851/* vim: set et sw=2 ts=2: */
diff --git a/ue4/mycpu/mycpu.cpp b/ue4/mycpu/mycpu.cpp
index b25e721..6c9f71a 100644
--- a/ue4/mycpu/mycpu.cpp
+++ b/ue4/mycpu/mycpu.cpp
@@ -6,7 +6,7 @@
6 * be executed in linear order (except jumps) afterwards. In order to 6 * be executed in linear order (except jumps) afterwards. In order to
7 * initialize the memory of the cpu before execution an optional 7 * initialize the memory of the cpu before execution an optional
8 * memoryfile can be passed as commandline option. 8 * memoryfile can be passed as commandline option.
9 * @date 13.05.2009 9 * @date 26.05.2009
10 * @par Exercise 10 * @par Exercise
11 * 4 11 * 4
12 */ 12 */
@@ -16,9 +16,10 @@
16#include <fstream> 16#include <fstream>
17#include <stdexcept> 17#include <stdexcept>
18#include <stdlib.h> 18#include <stdlib.h>
19#include "ccpu.h" 19#include "cdat.h"
20#include "cmem.h" 20#include "cmem.h"
21#include "cprogram.h" 21#include "cprogram.h"
22#include "ccpu.h"
22 23
23using namespace std; 24using namespace std;
24namespace po = boost::program_options; 25namespace po = boost::program_options;
@@ -47,6 +48,7 @@ int main(int argc, char* argv[])
47 po::options_description desc("Allowed options"); 48 po::options_description desc("Allowed options");
48 desc.add_options() 49 desc.add_options()
49 ("help,h", "this help message") 50 ("help,h", "this help message")
51 ("format,f", po::value<string>(), "format")
50 ("compile,c", po::value<string>(), "input programfile") 52 ("compile,c", po::value<string>(), "input programfile")
51 ("memory,m", po::value<string>(), "input memoryfile"); 53 ("memory,m", po::value<string>(), "input memoryfile");
52 54
@@ -65,13 +67,13 @@ int main(int argc, char* argv[])
65 /* print usage upon request or missing params */ 67 /* print usage upon request or missing params */
66 if (vm.count("help") || !vm.count("compile")) 68 if (vm.count("help") || !vm.count("compile"))
67 { 69 {
68 cout << "Usage: " << me << " -c <programfile> [-m <memoryfile>]" << endl; 70 cout << "Usage: " << me << " [-f <format>] -c <programfile> [-m <memoryfile>]" << endl;
69 cout << desc << endl; 71 cout << desc << endl;
70 return 0; 72 return 0;
71 } 73 }
72 74
73 /* create memory and optionally initialize memory from file */ 75 /* create memory and optionally initialize memory from file */
74 CMem memory; 76 CMem<CDat<int> > memory;
75 if (vm.count("memory")) 77 if (vm.count("memory"))
76 { 78 {
77 string memoryfile(vm["memory"].as<string>()); 79 string memoryfile(vm["memory"].as<string>());
@@ -101,7 +103,7 @@ int main(int argc, char* argv[])
101 } 103 }
102 104
103 /* create program instance */ 105 /* create program instance */
104 CProgram program; 106 CProgram<CDat<int> > program;
105 string programfile(vm["compile"].as<string>()); 107 string programfile(vm["compile"].as<string>());
106 ifstream file(programfile.c_str(), ios::in); 108 ifstream file(programfile.c_str(), ios::in);
107 if (!file.is_open()) 109 if (!file.is_open())
@@ -131,7 +133,7 @@ int main(int argc, char* argv[])
131 /* create cpu and execute the program */ 133 /* create cpu and execute the program */
132 try 134 try
133 { 135 {
134 CCPU cpu(256); 136 CCPU<CDat<int> > cpu(256);
135 cpu.setMemory(&memory); 137 cpu.setMemory(&memory);
136 cpu.setProgram(&program); 138 cpu.setProgram(&program);
137 cpu.run(); 139 cpu.run();