summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authormanuel <manuel@nc8430.lan>2009-05-28 19:22:52 +0200
committermanuel <manuel@nc8430.lan>2009-05-28 19:22:52 +0200
commitf67834dd18859ed333c88360f4141a99dc7db5dd (patch)
treef668d395e258ce9601ddde380b85e9369265dedb
parent064eaaed391835d0e0d057466f6f552e43e79bd8 (diff)
downloadooprog-f67834dd18859ed333c88360f4141a99dc7db5dd.tar.gz
ooprog-f67834dd18859ed333c88360f4141a99dc7db5dd.tar.bz2
ooprog-f67834dd18859ed333c88360f4141a99dc7db5dd.zip
push for me
-rw-r--r--.hgignore1
-rw-r--r--ue4/doxygen.conf1
-rw-r--r--ue4/mycpu/Makefile4
-rw-r--r--ue4/mycpu/ccpu.h128
-rw-r--r--ue4/mycpu/cdat.h70
-rw-r--r--ue4/mycpu/cdatn.h382
-rw-r--r--ue4/mycpu/cdatset.h56
-rw-r--r--ue4/mycpu/cdisplay.h12
-rw-r--r--ue4/mycpu/cinstruction.h91
-rw-r--r--ue4/mycpu/cmem.h65
-rw-r--r--ue4/mycpu/cprogram.h76
-rw-r--r--ue4/mycpu/displays.h10
-rw-r--r--ue4/mycpu/instructions.h157
-rw-r--r--ue4/mycpu/mycpu.cpp212
-rwxr-xr-xue4/mycpu/test/test.sh11
-rw-r--r--ue4/mycpu/test/test1_args1
-rw-r--r--ue4/mycpu/test/test2_args1
-rw-r--r--ue4/mycpu/test/test2_memory1
-rw-r--r--ue4/mycpu/test/test2_output19
-rw-r--r--ue4/mycpu/test/test2_program13
-rw-r--r--ue4/mycpu/test/test3_args1
-rw-r--r--ue4/mycpu/test/test3_memory1
-rw-r--r--ue4/mycpu/test/test3_output21
-rw-r--r--ue4/mycpu/test/test3_program13
24 files changed, 1013 insertions, 334 deletions
diff --git a/.hgignore b/.hgignore
index b96a5d0..3896220 100644
--- a/.hgignore
+++ b/.hgignore
@@ -11,3 +11,4 @@ ue2/imgsynth/test/*_out*
11ue2/imgsynth2/imgsynth2 11ue2/imgsynth2/imgsynth2
12ue2/imgsynth2/test/*_out* 12ue2/imgsynth2/test/*_out*
13ue3/mycpu/mycpu 13ue3/mycpu/mycpu
14ue4/mycpu/mycpu
diff --git a/ue4/doxygen.conf b/ue4/doxygen.conf
index d8b9773..c7dd94a 100644
--- a/ue4/doxygen.conf
+++ b/ue4/doxygen.conf
@@ -190,7 +190,6 @@ ALIASES += "func=\par Functionname:\n"
190ALIASES += "method=\par Methodname:\n" 190ALIASES += "method=\par Methodname:\n"
191ALIASES += "globalvars=\par Global variables used:\n" 191ALIASES += "globalvars=\par Global variables used:\n"
192#ALIASES += "exceptions=\par Exceptions thrown:\n" 192#ALIASES += "exceptions=\par Exceptions thrown:\n"
193ALIASES += "conditions=\par Conditions:\n"
194 193
195# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C 194# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C
196# sources only. Doxygen will then generate output that is more tailored for C. 195# sources only. Doxygen will then generate output that is more tailored for C.
diff --git a/ue4/mycpu/Makefile b/ue4/mycpu/Makefile
index 9e6db7a..bf4ebc8 100644
--- a/ue4/mycpu/Makefile
+++ b/ue4/mycpu/Makefile
@@ -7,13 +7,13 @@ LD= $(CXX)
7DEBUGFLAGS= -DNDEBUG 7DEBUGFLAGS= -DNDEBUG
8INCLUDE_PATH= -I/usr/local/include 8INCLUDE_PATH= -I/usr/local/include
9CXXFLAGS= -O -ansi -pedantic-errors -Wall -Wno-long-long $(INCLUDE_PATH) $(DEBUGFLAGS) 9CXXFLAGS= -O -ansi -pedantic-errors -Wall -Wno-long-long $(INCLUDE_PATH) $(DEBUGFLAGS)
10CXXFLAGS= -ansi -pedantic-errors -Wall -Wno-long-long $(INCLUDE_PATH) $(DEBUGFLAGS)
10LDFLAGS= 11LDFLAGS=
11LIBS= -L/usr/local/lib -lboost_program_options 12LIBS= -L/usr/local/lib -lboost_program_options
12 13
13BIN= mycpu 14BIN= mycpu
14OBJS= mycpu.o 15OBJS= mycpu.o
15HEADERS= cdat.h cdatn.h cdatset.h cmem.h cinstruction.h instructions.h \ 16HEADERS= cdat.h cdatset.h cdatn.h cmem.h cinstruction.h instructions.h cprogram.h cdisplay.h displays.h ccpu.h
16 cprogram.h cdisplay.h displays.h ccpu.h
17 17
18.SUFFIXES: .cpp .o 18.SUFFIXES: .cpp .o
19 19
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 */
25class 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 */
25template <class T=CDat<int>, int width=0> 49template <class T>
26class CProgram; 50class 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 */
34template<class T=CDat<int>, int width=0> 58template <class T>
35class CCPU 59class 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
253template<class T, int width> 293template <class T>
254CCPU<T, width>::CCPU(const unsigned cnt) 294CCPU<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
269template<class T, int width> 304template <class T>
270CCPU<T>::~CCPU() 305CCPU<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
283template<class T, int width> 314template <class T>
284void CCPU<T>::run() 315void 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
315template<class T, int width> 353template <class T>
316void CCPU<T>::dumpRegisters(std::ostream& out) 354void CCPU<T>::dumpRegisters(std::ostream& out)
317{ 355{
318 out << "[REGISTER DUMP]" << std::endl; 356 out << "[REGISTER DUMP]" << std::endl;
diff --git a/ue4/mycpu/cdat.h b/ue4/mycpu/cdat.h
index ca9d745..a5f2ce0 100644
--- a/ue4/mycpu/cdat.h
+++ b/ue4/mycpu/cdat.h
@@ -18,7 +18,7 @@
18 */ 18 */
19template <class T> 19template <class T>
20class CDat 20class CDat
21 : boost::operators<CDat<T> > 21 : public boost::operators<CDat<T> >
22{ 22{
23 public: 23 public:
24 /** 24 /**
@@ -28,7 +28,8 @@ class CDat
28 * @return - 28 * @return -
29 * @globalvars none 29 * @globalvars none
30 * @exception bad_alloc 30 * @exception bad_alloc
31 * @conditions none 31 * @pre none
32 * @post none
32 */ 33 */
33 CDat() 34 CDat()
34 {} 35 {}
@@ -40,9 +41,10 @@ class CDat
40 * @return - 41 * @return -
41 * @globalvars none 42 * @globalvars none
42 * @exception none 43 * @exception none
43 * @conditions none 44 * @pre none
45 * @post none
44 */ 46 */
45 ~CDat() 47 virtual ~CDat()
46 {} 48 {}
47 49
48 /** 50 /**
@@ -52,7 +54,8 @@ class CDat
52 * @return - 54 * @return -
53 * @globalvars none 55 * @globalvars none
54 * @exception none 56 * @exception none
55 * @conditions none 57 * @pre none
58 * @post none
56 */ 59 */
57 CDat(const CDat& other) 60 CDat(const CDat& other)
58 : m_value(other.m_value) 61 : m_value(other.m_value)
@@ -60,14 +63,15 @@ class CDat
60 63
61 /** 64 /**
62 * @method CDat 65 * @method CDat
63 * @brief Copy constructor for int 66 * @brief Copy constructor for T
64 * @param newval new value for CDat 67 * @param newval new value for CDat
65 * @return - 68 * @return -
66 * @globalvars none 69 * @globalvars none
67 * @exception none 70 * @exception none
68 * @conditions none 71 * @pre none
72 * @post none
69 */ 73 */
70 CDat(T newval) 74 CDat(const T newval)
71 : m_value(newval) 75 : m_value(newval)
72 {} 76 {}
73 77
@@ -78,7 +82,8 @@ class CDat
78 * @return value of CDat 82 * @return value of CDat
79 * @globalvars none 83 * @globalvars none
80 * @exception none 84 * @exception none
81 * @conditions none 85 * @pre none
86 * @post none
82 */ 87 */
83 T getValue() const 88 T getValue() const
84 { 89 {
@@ -92,7 +97,8 @@ class CDat
92 * @return T 97 * @return T
93 * @globalvars none 98 * @globalvars none
94 * @exception none 99 * @exception none
95 * @conditions none 100 * @pre none
101 * @post none
96 */ 102 */
97 operator T() 103 operator T()
98 { 104 {
@@ -106,7 +112,8 @@ class CDat
106 * @return true if cdat is less than object x 112 * @return true if cdat is less than object x
107 * @globalvars none 113 * @globalvars none
108 * @exception none 114 * @exception none
109 * @conditions none 115 * @pre none
116 * @post none
110 */ 117 */
111 bool operator<(const CDat& x) const 118 bool operator<(const CDat& x) const
112 { 119 {
@@ -120,7 +127,8 @@ class CDat
120 * @return true if cdat equals object x 127 * @return true if cdat equals object x
121 * @globalvars none 128 * @globalvars none
122 * @exception none 129 * @exception none
123 * @conditions none 130 * @pre none
131 * @post none
124 */ 132 */
125 bool operator==(const CDat& x) const 133 bool operator==(const CDat& x) const
126 { 134 {
@@ -134,7 +142,8 @@ class CDat
134 * @return refecence to CDat 142 * @return refecence to CDat
135 * @globalvars none 143 * @globalvars none
136 * @exception none 144 * @exception none
137 * @conditions none 145 * @pre none
146 * @post none
138 */ 147 */
139 CDat& operator+=(const CDat& x) 148 CDat& operator+=(const CDat& x)
140 { 149 {
@@ -149,7 +158,8 @@ class CDat
149 * @return refecence to CDat 158 * @return refecence to CDat
150 * @globalvars none 159 * @globalvars none
151 * @exception none 160 * @exception none
152 * @conditions none 161 * @pre none
162 * @post none
153 */ 163 */
154 CDat& operator-=(const CDat& x) 164 CDat& operator-=(const CDat& x)
155 { 165 {
@@ -164,7 +174,8 @@ class CDat
164 * @return refecence to CDat 174 * @return refecence to CDat
165 * @globalvars none 175 * @globalvars none
166 * @exception none 176 * @exception none
167 * @conditions none 177 * @pre none
178 * @post none
168 */ 179 */
169 CDat& operator*=(const CDat& x) 180 CDat& operator*=(const CDat& x)
170 { 181 {
@@ -179,7 +190,8 @@ class CDat
179 * @return refecence to CDat 190 * @return refecence to CDat
180 * @globalvars none 191 * @globalvars none
181 * @exception none 192 * @exception none
182 * @conditions none 193 * @pre none
194 * @post none
183 */ 195 */
184 CDat& operator/=(const CDat& x) 196 CDat& operator/=(const CDat& x)
185 { 197 {
@@ -194,7 +206,8 @@ class CDat
194 * @return refecence to CDat 206 * @return refecence to CDat
195 * @globalvars none 207 * @globalvars none
196 * @exception none 208 * @exception none
197 * @conditions none 209 * @pre none
210 * @post none
198 */ 211 */
199 CDat& operator%=(const CDat& x) 212 CDat& operator%=(const CDat& x)
200 { 213 {
@@ -209,7 +222,8 @@ class CDat
209 * @return refecence to CDat 222 * @return refecence to CDat
210 * @globalvars none 223 * @globalvars none
211 * @exception none 224 * @exception none
212 * @conditions none 225 * @pre none
226 * @post none
213 */ 227 */
214 CDat& operator|=(const CDat& x) 228 CDat& operator|=(const CDat& x)
215 { 229 {
@@ -224,7 +238,8 @@ class CDat
224 * @return refecence to CDat 238 * @return refecence to CDat
225 * @globalvars none 239 * @globalvars none
226 * @exception none 240 * @exception none
227 * @conditions none 241 * @pre none
242 * @post none
228 */ 243 */
229 CDat& operator&=(const CDat& x) 244 CDat& operator&=(const CDat& x)
230 { 245 {
@@ -239,7 +254,8 @@ class CDat
239 * @return refecence to CDat 254 * @return refecence to CDat
240 * @globalvars none 255 * @globalvars none
241 * @exception none 256 * @exception none
242 * @conditions none 257 * @pre none
258 * @post none
243 */ 259 */
244 CDat& operator^=(const CDat& x) 260 CDat& operator^=(const CDat& x)
245 { 261 {
@@ -254,7 +270,8 @@ class CDat
254 * @return refecence to CDat 270 * @return refecence to CDat
255 * @globalvars none 271 * @globalvars none
256 * @exception none 272 * @exception none
257 * @conditions none 273 * @pre none
274 * @post none
258 */ 275 */
259 CDat& operator++() 276 CDat& operator++()
260 { 277 {
@@ -269,7 +286,8 @@ class CDat
269 * @return refecence to CDat 286 * @return refecence to CDat
270 * @globalvars none 287 * @globalvars none
271 * @exception none 288 * @exception none
272 * @conditions none 289 * @pre none
290 * @post none
273 */ 291 */
274 CDat& operator--() 292 CDat& operator--()
275 { 293 {
@@ -285,7 +303,8 @@ class CDat
285 * @return reference to outputstream 303 * @return reference to outputstream
286 * @globalvars none 304 * @globalvars none
287 * @exception none 305 * @exception none
288 * @conditions none 306 * @pre none
307 * @post none
289 */ 308 */
290 friend std::ostream& operator<<(std::ostream& stream, CDat cdat) 309 friend std::ostream& operator<<(std::ostream& stream, CDat cdat)
291 { 310 {
@@ -301,7 +320,8 @@ class CDat
301 * @return reference to inputstream 320 * @return reference to inputstream
302 * @globalvars none 321 * @globalvars none
303 * @exception none 322 * @exception none
304 * @conditions none 323 * @pre none
324 * @post none
305 */ 325 */
306 friend std::istream& operator>>(std::istream & stream, CDat& cdat) 326 friend std::istream& operator>>(std::istream & stream, CDat& cdat)
307 { 327 {
@@ -309,7 +329,7 @@ class CDat
309 return stream; 329 return stream;
310 } 330 }
311 331
312 private: 332 protected:
313 /* members */ 333 /* members */
314 T m_value; 334 T m_value;
315}; 335};
diff --git a/ue4/mycpu/cdatn.h b/ue4/mycpu/cdatn.h
new file mode 100644
index 0000000..32d8d7b
--- /dev/null
+++ b/ue4/mycpu/cdatn.h
@@ -0,0 +1,382 @@
1/**
2 * @module cdatn
3 * @author Guenther Neuwirth (0626638), Manuel Mausz (0728348)
4 * @brief Datatype template and datatype definition for CCPU and CMem
5 * @date 26.05.2009
6 */
7
8#ifndef CDATN_H
9#define CDATN_H 1
10
11#include <boost/operators.hpp>
12#include <iostream>
13
14/**
15 * @class CDatN
16 *
17 * Datatype template for CCPU and CMem.
18 */
19class CDatN
20 : public boost::operators<CDatN>
21{
22 private:
23 /**
24 * @method CDatN
25 * @brief Default ctor
26 * @param -
27 * @return -
28 * @globalvars none
29 * @exception bad_alloc
30 * @pre none
31 * @post none
32 */
33 CDatN()
34 {}
35
36 public:
37 /**
38 * @method ~CDatN
39 * @brief Default dtor
40 * @param -
41 * @return -
42 * @globalvars none
43 * @exception none
44 * @pre none
45 * @post none
46 */
47 virtual ~CDatN()
48 {}
49
50 /**
51 * @method CDatN
52 * @brief Copy constructor for CDatN
53 * @param other reference to CDatN which will be copied
54 * @return -
55 * @globalvars none
56 * @exception none
57 * @pre none
58 * @post none
59 */
60 CDatN(const CDatN& other)
61 : m_value(other.m_value), m_width(other.m_width)
62 {}
63
64 /**
65 * @method CDatN
66 * @brief Copy constructor for int
67 * @param newval new value for CDatN
68 * @param width maximum width
69 * @return -
70 * @globalvars none
71 * @exception none
72 * @pre none
73 * @post none
74 */
75 CDatN(const int newval, unsigned width = 31)
76 : m_value(((1 << width) - 1) & newval), m_width(width)
77 {}
78
79 /**
80 * @method getValue
81 * @brief returns value of CDatN
82 * @param -
83 * @return value of CDatN
84 * @globalvars none
85 * @exception none
86 * @pre none
87 * @post none
88 */
89 int getValue() const
90 {
91 return m_value;
92 }
93
94 /**
95 * @method operator int
96 * @brief convert to int
97 * @param -
98 * @return int
99 * @globalvars none
100 * @exception none
101 * @pre none
102 * @post none
103 */
104 operator int()
105 {
106 return m_value;
107 }
108
109 /**
110 * @method operator<
111 * @brief implementation of operator <
112 * @param x reference to CDatN
113 * @return true if cdat is less than object x
114 * @globalvars none
115 * @exception none
116 * @pre none
117 * @post none
118 */
119 bool operator<(const CDatN& x) const
120 {
121 return m_value < x.m_value;
122 }
123
124 /**
125 * @method operator==
126 * @brief implementation of operator ==
127 * @param x reference to CDatN
128 * @return true if cdat equals object x
129 * @globalvars none
130 * @exception none
131 * @pre none
132 * @post none
133 */
134 bool operator==(const CDatN& x) const
135 {
136 return m_value == x.m_value;
137 }
138
139 /**
140 * @method operator=
141 * @brief implementation of operator =
142 * @param x reference to int
143 * @return refecence to int
144 * @globalvars none
145 * @exception none
146 * @pre none
147 * @post none
148 */
149 CDatN &operator=(const int& newval)
150 {
151 m_value = newval;
152 align();
153 return *this;
154 }
155
156 /**
157 * @method operator+=
158 * @brief implementation of operator +=
159 * @param x reference to CDatN
160 * @return refecence to CDatN
161 * @globalvars none
162 * @exception none
163 * @pre none
164 * @post none
165 */
166 CDatN& operator+=(const CDatN& x)
167 {
168 m_value += x.m_value;
169 align();
170 return *this;
171 }
172
173 /**
174 * @method operator-=
175 * @brief implementation of operator -=
176 * @param x reference to CDatN
177 * @return refecence to CDatN
178 * @globalvars none
179 * @exception none
180 * @pre none
181 * @post none
182 */
183 CDatN& operator-=(const CDatN& x)
184 {
185 m_value -= x.m_value;
186 align();
187 return *this;
188 }
189
190 /**
191 * @method operator*=
192 * @brief implementation of operator *=
193 * @param x reference to CDatN
194 * @return refecence to CDatN
195 * @globalvars none
196 * @exception none
197 * @pre none
198 * @post none
199 */
200 CDatN& operator*=(const CDatN& x)
201 {
202 m_value *= x.m_value;
203 align();
204 return *this;
205 }
206
207 /**
208 * @method operator/=
209 * @brief implementation of operator /=
210 * @param x reference to CDatN
211 * @return refecence to CDatN
212 * @globalvars none
213 * @exception none
214 * @pre none
215 * @post none
216 */
217 CDatN& operator/=(const CDatN& x)
218 {
219 m_value /= x.m_value;
220 align();
221 return *this;
222 }
223
224 /**
225 * @method operator%=
226 * @brief implementation of operator %=
227 * @param x reference to CDatN
228 * @return refecence to CDatN
229 * @globalvars none
230 * @exception none
231 * @pre none
232 * @post none
233 */
234 CDatN& operator%=(const CDatN& x)
235 {
236 m_value %= x.m_value;
237 align();
238 return *this;
239 }
240
241 /**
242 * @method operator|=
243 * @brief implementation of operator |=
244 * @param x reference to CDatN
245 * @return refecence to CDatN
246 * @globalvars none
247 * @exception none
248 * @pre none
249 * @post none
250 */
251 CDatN& operator|=(const CDatN& x)
252 {
253 m_value |= x.m_value;
254 align();
255 return *this;
256 }
257
258 /**
259 * @method operator&=
260 * @brief implementation of operator &=
261 * @param x reference to CDatN
262 * @return refecence to CDatN
263 * @globalvars none
264 * @exception none
265 * @pre none
266 * @post none
267 */
268 CDatN& operator&=(const CDatN& x)
269 {
270 m_value &= x.m_value;
271 align();
272 return *this;
273 }
274
275 /**
276 * @method operator^=
277 * @brief implementation of operator ^=
278 * @param x reference to CDatN
279 * @return refecence to CDatN
280 * @globalvars none
281 * @exception none
282 * @pre none
283 * @post none
284 */
285 CDatN& operator^=(const CDatN& x)
286 {
287 m_value ^= x.m_value;
288 align();
289 return *this;
290 }
291
292 /**
293 * @method operator++
294 * @brief implementation of operator ++
295 * @param -
296 * @return refecence to CDatN
297 * @globalvars none
298 * @exception none
299 * @pre none
300 * @post none
301 */
302 CDatN& operator++()
303 {
304 m_value++;
305 align();
306 return *this;
307 }
308
309 /**
310 * @method operator--
311 * @brief implementation of operator --
312 * @param -
313 * @return refecence to CDatN
314 * @globalvars none
315 * @exception none
316 * @pre none
317 * @post none
318 */
319 CDatN& operator--()
320 {
321 m_value--;
322 return *this;
323 }
324
325 /**
326 * @method operator<<
327 * @brief Shift/output operator for outputstream
328 * @param stream reference to outputstream
329 * @param cdat object which will be printed to stream
330 * @return reference to outputstream
331 * @globalvars none
332 * @exception none
333 * @pre none
334 * @post none
335 */
336 friend std::ostream& operator<<(std::ostream& stream, CDatN cdat)
337 {
338 stream << cdat.m_value;
339 return stream;
340 }
341
342 /**
343 * @method operator>>
344 * @brief Shift/read operator for inputstream
345 * @param stream reference to inputstream
346 * @param cdat reference to object which will be read from stream
347 * @return reference to inputstream
348 * @globalvars none
349 * @exception none
350 * @pre none
351 * @post none
352 */
353 friend std::istream& operator>>(std::istream & stream, CDatN& cdat)
354 {
355 stream >> cdat.m_value;
356 cdat.align();
357 return stream;
358 }
359
360 protected:
361 /**
362 * @method align
363 * @brief aligns value by width
364 * @return -
365 * @globalvars none
366 * @exception none
367 * @pre none
368 * @post none
369 */
370 inline void align()
371 {
372 m_value &= ((1 << m_width) - 1);
373 }
374
375 /* members */
376 int m_value;
377 unsigned m_width;
378};
379
380#endif
381
382/* vim: set et sw=2 ts=2: */
diff --git a/ue4/mycpu/cdatset.h b/ue4/mycpu/cdatset.h
index 03e71f4..56a0630 100644
--- a/ue4/mycpu/cdatset.h
+++ b/ue4/mycpu/cdatset.h
@@ -1,5 +1,5 @@
1/** 1/**
2 * @module cdat 2 * @module cdatset
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 26.05.2009 5 * @date 26.05.2009
@@ -8,20 +8,46 @@
8#ifndef CDATSET_H 8#ifndef CDATSET_H
9#define CDATSET_H 1 9#define CDATSET_H 1
10 10
11#include <boost/operators.hpp>
12#include <iostream> 11#include <iostream>
12#include "cdat.h"
13 13
14/** 14/**
15 * @class CDat 15 * @class CDatSet
16 * 16 *
17 * Datatype template for CCPU and CMem. 17 * Datatype template for CCPU and CMem.
18 */ 18 */
19template <class T>
20class CDatSet 19class CDatSet
21 : public CDat<T> 20 : public CDat<int>, public boost::operators<CDatSet>
22{ 21{
23 public: 22 public:
24 /** 23 /**
24 * @method CDatSet
25 * @brief Default ctor
26 * @param -
27 * @return -
28 * @globalvars none
29 * @exception bad_alloc
30 * @pre none
31 * @post none
32 */
33 CDatSet()
34 {}
35
36 /**
37 * @method CDatSet
38 * @brief Copy constructor for int
39 * @param newval new value for CDatSet
40 * @return -
41 * @globalvars none
42 * @exception none
43 * @pre none
44 * @post none
45 */
46 CDatSet(const int newval)
47 : CDat<int>(newval)
48 {}
49
50 /**
25 * @method operator>> 51 * @method operator>>
26 * @brief Shift/read operator for inputstream 52 * @brief Shift/read operator for inputstream
27 * @param stream reference to inputstream 53 * @param stream reference to inputstream
@@ -29,19 +55,23 @@ class CDatSet
29 * @return reference to inputstream 55 * @return reference to inputstream
30 * @globalvars none 56 * @globalvars none
31 * @exception none 57 * @exception none
32 * @conditions none 58 * @pre none
59 * @post none
33 */ 60 */
34 friend std::istream& operator>>(std::istream & stream, CDatSet& cdat) 61 friend std::istream& operator>>(std::istream & stream, CDatSet& cdat)
35 { 62 {
36 std::string s; 63 unsigned count = 0;
37 stream >> s; 64 while(stream.good() && !stream.eof())
38 cdat.m_value = s.size(); 65 {
66 int val = stream.get();
67 if (val != 'o')
68 break;
69 ++count;
70 }
71 stream.clear();
72 cdat.m_value = count;
39 return stream; 73 return stream;
40 } 74 }
41
42 private:
43 /* members */
44 T m_value;
45}; 75};
46 76
47#endif 77#endif
diff --git a/ue4/mycpu/cdisplay.h b/ue4/mycpu/cdisplay.h
index 8d15eb9..7108442 100644
--- a/ue4/mycpu/cdisplay.h
+++ b/ue4/mycpu/cdisplay.h
@@ -24,7 +24,8 @@ class CDisplay
24 * @return - 24 * @return -
25 * @globalvars none 25 * @globalvars none
26 * @exception none 26 * @exception none
27 * @conditions none 27 * @pre none
28 * @post none
28 */ 29 */
29 CDisplay(std::string name) 30 CDisplay(std::string name)
30 : m_name(name) 31 : m_name(name)
@@ -37,7 +38,8 @@ class CDisplay
37 * @return - 38 * @return -
38 * @globalvars none 39 * @globalvars none
39 * @exception none 40 * @exception none
40 * @conditions none 41 * @pre none
42 * @post none
41 */ 43 */
42 virtual ~CDisplay() 44 virtual ~CDisplay()
43 {} 45 {}
@@ -49,7 +51,8 @@ class CDisplay
49 * @return name of display 51 * @return name of display
50 * @globalvars none 52 * @globalvars none
51 * @exception none 53 * @exception none
52 * @conditions none 54 * @pre none
55 * @post none
53 */ 56 */
54 virtual const std::string& getName() 57 virtual const std::string& getName()
55 { 58 {
@@ -63,7 +66,8 @@ class CDisplay
63 * @return - 66 * @return -
64 * @globalvars none 67 * @globalvars none
65 * @exception none 68 * @exception none
66 * @conditions none 69 * @pre none
70 * @post none
67 */ 71 */
68 virtual void display(const T &value) = 0; 72 virtual void display(const T &value) = 0;
69 73
diff --git a/ue4/mycpu/cinstruction.h b/ue4/mycpu/cinstruction.h
index a2e3743..85122b4 100644
--- a/ue4/mycpu/cinstruction.h
+++ b/ue4/mycpu/cinstruction.h
@@ -1,7 +1,7 @@
1/** 1/**
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 instructions
5 * @date 26.05.2009 5 * @date 26.05.2009
6 */ 6 */
7 7
@@ -11,21 +11,46 @@
11#include <iostream> 11#include <iostream>
12#include <list> 12#include <list>
13#include <sstream> 13#include <sstream>
14#include <stdexcept>
15#include <boost/lexical_cast.hpp> 14#include <boost/lexical_cast.hpp>
16#include <assert.h> 15#include <assert.h>
16#include <stdexcept>
17
18/**
19 * @class CInstructionError
20 *
21 * Exception thrown by implemententations of CInstruction
22 */
23class CInstructionError
24 : public std::invalid_argument
25{
26 public:
27 /**
28 * @method CInstructionError
29 * @brief Default exception ctor
30 * @param what message to pass along
31 * @return -
32 * @globalvars none
33 * @exception none
34 * @pre none
35 * @post none
36 */
37 CInstructionError(const std::string& what)
38 : std::invalid_argument(what)
39 {}
40};
41
17#include "ccpu.h" 42#include "ccpu.h"
18 43
19/* forward declare CCPU */ 44/* forward declare CCPU */
20template<class T, int > 45template <class T>
21class CCPU; 46class CCPU;
22 47
23/** 48/**
24 * @class CInstruction 49 * @class CInstruction
25 * 50 *
26 * Abstract class for displays 51 * Abstract class for instructions
27 */ 52 */
28template<class T=CDat<int>, int width=0> 53template <class T>
29class CInstruction 54class CInstruction
30{ 55{
31 public: 56 public:
@@ -36,7 +61,8 @@ class CInstruction
36 * @return - 61 * @return -
37 * @globalvars none 62 * @globalvars none
38 * @exception none 63 * @exception none
39 * @conditions none 64 * @pre none
65 * @post none
40 */ 66 */
41 CInstruction(std::string name) 67 CInstruction(std::string name)
42 : m_name(name) 68 : m_name(name)
@@ -49,7 +75,8 @@ class CInstruction
49 * @return - 75 * @return -
50 * @globalvars none 76 * @globalvars none
51 * @exception none 77 * @exception none
52 * @conditions none 78 * @pre none
79 * @post none
53 */ 80 */
54 virtual ~CInstruction() 81 virtual ~CInstruction()
55 {} 82 {}
@@ -61,7 +88,8 @@ class CInstruction
61 * @return true if instructionname is name 88 * @return true if instructionname is name
62 * @globalvars none 89 * @globalvars none
63 * @exception none 90 * @exception none
64 * @conditions none 91 * @pre none
92 * @post none
65 */ 93 */
66 virtual bool operator==(std::string& name) 94 virtual bool operator==(std::string& name)
67 { 95 {
@@ -74,8 +102,9 @@ class CInstruction
74 * @param cpu pointer to cpu 102 * @param cpu pointer to cpu
75 * @return - 103 * @return -
76 * @globalvars none 104 * @globalvars none
77 * @exception std::runtime_error 105 * @exception CInstructionError
78 * @conditions none 106 * @pre none
107 * @post none
79 */ 108 */
80 virtual CInstruction& operator()(CCPU<T> *cpu) 109 virtual CInstruction& operator()(CCPU<T> *cpu)
81 { 110 {
@@ -90,7 +119,8 @@ class CInstruction
90 * @return name of instruction 119 * @return name of instruction
91 * @globalvars none 120 * @globalvars none
92 * @exception none 121 * @exception none
93 * @conditions none 122 * @pre none
123 * @post none
94 */ 124 */
95 virtual const std::string& getName() 125 virtual const std::string& getName()
96 { 126 {
@@ -104,7 +134,8 @@ class CInstruction
104 * @return reference to outputstream 134 * @return reference to outputstream
105 * @globalvars none 135 * @globalvars none
106 * @exception none 136 * @exception none
107 * @conditions none 137 * @pre none
138 * @post none
108 */ 139 */
109 virtual std::ostream& dump(std::ostream& stream) 140 virtual std::ostream& dump(std::ostream& stream)
110 { 141 {
@@ -120,7 +151,8 @@ class CInstruction
120 * @return reference to outputstream 151 * @return reference to outputstream
121 * @globalvars none 152 * @globalvars none
122 * @exception none 153 * @exception none
123 * @conditions none 154 * @pre none
155 * @post none
124 */ 156 */
125 friend std::ostream& operator<<(std::ostream& stream, CInstruction& instr) 157 friend std::ostream& operator<<(std::ostream& stream, CInstruction& instr)
126 { 158 {
@@ -133,8 +165,9 @@ class CInstruction
133 * @param str register in assembler syntax 165 * @param str register in assembler syntax
134 * @return registernumber 166 * @return registernumber
135 * @globalvars none 167 * @globalvars none
136 * @exception std::runtime_error 168 * @exception CInstructionError
137 * @conditions none 169 * @pre none
170 * @post none
138 */ 171 */
139 virtual const unsigned parseRegister(const std::string& str); 172 virtual const unsigned parseRegister(const std::string& str);
140 173
@@ -146,8 +179,9 @@ class CInstruction
146 * @param regidx registernumber 179 * @param regidx registernumber
147 * @return - 180 * @return -
148 * @globalvars none 181 * @globalvars none
149 * @exception std::runtime_error 182 * @exception CInstructionError
150 * @conditions none 183 * @pre none
184 * @post none
151 */ 185 */
152 virtual void checkRegister(CCPU<T> *cpu, const unsigned regidx); 186 virtual void checkRegister(CCPU<T> *cpu, const unsigned regidx);
153 187
@@ -158,7 +192,8 @@ class CInstruction
158 * @return new instruction instance 192 * @return new instruction instance
159 * @globalvars none 193 * @globalvars none
160 * @exception none 194 * @exception none
161 * @conditions none 195 * @pre none
196 * @post none
162 */ 197 */
163 virtual CInstruction *factory() = 0; 198 virtual CInstruction *factory() = 0;
164 199
@@ -169,8 +204,9 @@ class CInstruction
169 * @param params list of parameters of this instruction 204 * @param params list of parameters of this instruction
170 * @return - 205 * @return -
171 * @globalvars none 206 * @globalvars none
172 * @exception std::runtime_error 207 * @exception CInstructionError
173 * @conditions none 208 * @pre none
209 * @post none
174 */ 210 */
175 virtual void compile(std::list<std::string>& params) = 0; 211 virtual void compile(std::list<std::string>& params) = 0;
176 212
@@ -180,8 +216,9 @@ class CInstruction
180 * @param cpu pointer to cpu 216 * @param cpu pointer to cpu
181 * @return - 217 * @return -
182 * @globalvars none 218 * @globalvars none
183 * @exception std::runtime_error 219 * @exception CInstructionError
184 * @conditions none 220 * @pre none
221 * @post none
185 */ 222 */
186 virtual void execute(CCPU<T> *cpu) = 0; 223 virtual void execute(CCPU<T> *cpu) = 0;
187 224
@@ -193,12 +230,12 @@ class CInstruction
193 230
194/*----------------------------------------------------------------------------*/ 231/*----------------------------------------------------------------------------*/
195 232
196template<class T=CDat<int>, int width=0> 233template<class T>
197const unsigned CInstruction<T>::parseRegister(const std::string& str) 234const unsigned CInstruction<T>::parseRegister(const std::string& str)
198{ 235{
199 unsigned reg; 236 unsigned reg;
200 if (str.length() < 2 || str[0] != 'r') 237 if (str.length() < 2 || str[0] != 'r')
201 throw std::runtime_error("Invalid syntax of register"); 238 throw CInstructionError("Invalid syntax of register");
202 239
203 try 240 try
204 { 241 {
@@ -206,7 +243,7 @@ const unsigned CInstruction<T>::parseRegister(const std::string& str)
206 } 243 }
207 catch(boost::bad_lexical_cast& ex) 244 catch(boost::bad_lexical_cast& ex)
208 { 245 {
209 throw std::runtime_error("Invalid syntax of register"); 246 throw CInstructionError("Invalid syntax of register");
210 } 247 }
211 248
212 return reg; 249 return reg;
@@ -214,7 +251,7 @@ const unsigned CInstruction<T>::parseRegister(const std::string& str)
214 251
215/*----------------------------------------------------------------------------*/ 252/*----------------------------------------------------------------------------*/
216 253
217template<class T=CDat<int>, int width=0> 254template<class T>
218inline void CInstruction<T>::checkRegister(CCPU<T> *cpu, const unsigned regidx) 255inline void CInstruction<T>::checkRegister(CCPU<T> *cpu, const unsigned regidx)
219{ 256{
220 assert(cpu != NULL); 257 assert(cpu != NULL);
@@ -222,7 +259,7 @@ inline void CInstruction<T>::checkRegister(CCPU<T> *cpu, const unsigned regidx)
222 { 259 {
223 std::stringstream sstr; 260 std::stringstream sstr;
224 sstr << "Register R" << regidx << " doesn't exist (out of bound)"; 261 sstr << "Register R" << regidx << " doesn't exist (out of bound)";
225 throw std::runtime_error(sstr.str()); 262 throw CInstructionError(sstr.str());
226 } 263 }
227} 264}
228 265
diff --git a/ue4/mycpu/cmem.h b/ue4/mycpu/cmem.h
index c6b8735..3f35a70 100644
--- a/ue4/mycpu/cmem.h
+++ b/ue4/mycpu/cmem.h
@@ -12,21 +12,43 @@
12#include <istream> 12#include <istream>
13#include <sstream> 13#include <sstream>
14#include <stdexcept> 14#include <stdexcept>
15#include <boost/lexical_cast.hpp>
16#include <boost/algorithm/string.hpp>
17#ifdef DEBUG 15#ifdef DEBUG
18# include <iostream> 16# include <iostream>
19# include <iomanip> 17# include <iomanip>
20#endif 18#endif
21 19
22/** 20/**
21 * @class CMemError
22 *
23 * Exception thrown by implemententations of CMem
24 */
25class CMemError
26 : public std::invalid_argument
27{
28 public:
29 /**
30 * @method CMemError
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 CMemError(const std::string& what)
40 : std::invalid_argument(what)
41 {}
42};
43
44/**
23 * @class CMem 45 * @class CMem
24 * 46 *
25 * Extends std::vector template for use as memory for CCPU. 47 * Extends std::vector template for use as memory for CCPU.
26 */ 48 */
27template<class T=CDat<int>, int width=0> 49template <class T>
28class CMem 50class CMem
29 : public std::vector<T> 51 : public std::vector<T>
30{ 52{
31 typedef std::vector<T> super; 53 typedef std::vector<T> super;
32 typedef typename super::iterator iterator; 54 typedef typename super::iterator iterator;
@@ -39,13 +61,15 @@ class CMem
39 * @method initialize 61 * @method initialize
40 * @brief initialize the vector with the content of istream. istream is 62 * @brief initialize the vector with the content of istream. istream is
41 * read per line. empty lines will add unitialized elements. 63 * read per line. empty lines will add unitialized elements.
42 * @param in inputstream to read from 64 * @param in inputstream to read from
65 * @param datatype reference instance of datatype to copy from
43 * @return void 66 * @return void
44 * @globalvars none 67 * @globalvars none
45 * @exception std::runtime_error 68 * @exception CMemError
46 * @conditions none 69 * @pre none
70 * @post none
47 */ 71 */
48 void initialize(std::istream& in) 72 void initialize(std::istream& in, T& datatype)
49 { 73 {
50 if (!in.good()) 74 if (!in.good())
51 return; 75 return;
@@ -56,24 +80,22 @@ class CMem
56 { 80 {
57 ++i; 81 ++i;
58 std::getline(in, line); 82 std::getline(in, line);
59 boost::algorithm::trim(line); 83
60
61 /* skip last line if it's empty */ 84 /* skip last line if it's empty */
62 if (line.empty() && in.eof()) 85 if (line.empty() && in.eof())
63 break; 86 break;
64 87
65 T value; 88 T value(datatype);
66 try
67 {
68 if (!line.empty()) 89 if (!line.empty())
69 { 90 {
70 value = boost::lexical_cast<T>(line); 91 /* simple boost::lexical_cast replacement */
71 } 92 std::stringstream interpreter;
72 catch(boost::bad_lexical_cast& ex) 93 if(!(interpreter << line && interpreter >> value && interpreter.get() == std::char_traits<char>::eof()))
73 { 94 {
74 std::stringstream sstr; 95 std::stringstream sstr;
75 sstr << "Unable to convert input (line " << i << "): " << ex.what(); 96 sstr << "Unable to convert input (line " << i << ") to datatype";
76 throw std::runtime_error(sstr.str()); 97 throw CMemError(sstr.str());
98 }
77 } 99 }
78 100
79 push_back(value); 101 push_back(value);
@@ -88,7 +110,8 @@ class CMem
88 * @return void 110 * @return void
89 * @globalvars none 111 * @globalvars none
90 * @exception none 112 * @exception none
91 * @conditions none 113 * @pre none
114 * @post none
92 */ 115 */
93 void dump(std::ostream& out) 116 void dump(std::ostream& out)
94 { 117 {
diff --git a/ue4/mycpu/cprogram.h b/ue4/mycpu/cprogram.h
index d8f7d5e..6908db7 100644
--- a/ue4/mycpu/cprogram.h
+++ b/ue4/mycpu/cprogram.h
@@ -11,17 +11,43 @@
11#include <vector> 11#include <vector>
12#include <set> 12#include <set>
13#include <map> 13#include <map>
14#include <stdexcept>
14#include <boost/algorithm/string.hpp> 15#include <boost/algorithm/string.hpp>
15#include <boost/algorithm/string/split.hpp> 16#include <boost/algorithm/string/split.hpp>
16#ifdef DEBUG 17#ifdef DEBUG
17# include <iostream> 18# include <iostream>
18# include <iomanip> 19# include <iomanip>
19#endif 20#endif
21
22/**
23 * @class CProgramError
24 *
25 * Exception thrown by implemententations of CProgram
26 */
27class CProgramError
28 : public std::invalid_argument
29{
30 public:
31 /**
32 * @method CProgramError
33 * @brief Default exception ctor
34 * @param what message to pass along
35 * @return -
36 * @globalvars none
37 * @exception none
38 * @pre none
39 * @post none
40 */
41 CProgramError(const std::string& what)
42 : std::invalid_argument(what)
43 {}
44};
45
20#include "cinstruction.h" 46#include "cinstruction.h"
21#include "instructions.h" 47#include "instructions.h"
22 48
23/* forward declare CInstruction */ 49/* forward declare CInstruction */
24template<class T=CDat<int>, int width=0> 50template <class T>
25class CInstruction; 51class CInstruction;
26 52
27/** 53/**
@@ -30,9 +56,9 @@ class CInstruction;
30 * CProgram extends std::vector and adds a method for parsing 56 * CProgram extends std::vector and adds a method for parsing
31 * programfile. This adds instances of CInstruction to CProgram itself. 57 * programfile. This adds instances of CInstruction to CProgram itself.
32 */ 58 */
33template<class T=CDat<int>, int width=0> 59template <class T>
34class CProgram 60class CProgram
35 : public std::vector<CInstruction<T> *> 61 : public std::vector<CInstruction<T> *>
36{ 62{
37 typedef typename std::set<CInstruction<T> *>::iterator setiterator; 63 typedef typename std::set<CInstruction<T> *>::iterator setiterator;
38 typedef std::vector<CInstruction<T> *> super; 64 typedef std::vector<CInstruction<T> *> super;
@@ -49,7 +75,8 @@ class CProgram
49 * @return - 75 * @return -
50 * @globalvars none 76 * @globalvars none
51 * @exception none 77 * @exception none
52 * @conditions none 78 * @pre none
79 * @post none
53 */ 80 */
54 CProgram(); 81 CProgram();
55 82
@@ -60,7 +87,8 @@ class CProgram
60 * @return - 87 * @return -
61 * @globalvars none 88 * @globalvars none
62 * @exception none 89 * @exception none
63 * @conditions none 90 * @pre none
91 * @post none
64 */ 92 */
65 ~CProgram(); 93 ~CProgram();
66 94
@@ -71,7 +99,8 @@ class CProgram
71 * @return reference to labels map 99 * @return reference to labels map
72 * @globalvars none 100 * @globalvars none
73 * @exception none 101 * @exception none
74 * @conditions none 102 * @pre none
103 * @post none
75 */ 104 */
76 const std::map<std::string, unsigned>& getLabels() const 105 const std::map<std::string, unsigned>& getLabels() const
77 { 106 {
@@ -84,8 +113,9 @@ class CProgram
84 * @param label name of label to search for 113 * @param label name of label to search for
85 * @return index of found label in program 114 * @return index of found label in program
86 * @globalvars none 115 * @globalvars none
87 * @exception std::runtime_error 116 * @exception CProgramError
88 * @conditions none 117 * @pre none
118 * @post none
89 */ 119 */
90 unsigned findLabel(const std::string& label) const; 120 unsigned findLabel(const std::string& label) const;
91 121
@@ -95,8 +125,9 @@ class CProgram
95 * @param in inputstream to read from 125 * @param in inputstream to read from
96 * @return void 126 * @return void
97 * @globalvars none 127 * @globalvars none
98 * @exception std::runtime_error 128 * @exception CProgramError
99 * @conditions none 129 * @pre none
130 * @post none
100 */ 131 */
101 void compile(std::istream& in); 132 void compile(std::istream& in);
102 133
@@ -108,7 +139,8 @@ class CProgram
108 * @return void 139 * @return void
109 * @globalvars none 140 * @globalvars none
110 * @exception none 141 * @exception none
111 * @conditions none 142 * @pre none
143 * @post none
112 */ 144 */
113 void dump(std::ostream& out); 145 void dump(std::ostream& out);
114#endif 146#endif
@@ -122,7 +154,7 @@ class CProgram
122 154
123/*----------------------------------------------------------------------------*/ 155/*----------------------------------------------------------------------------*/
124 156
125template<class T=CDat<int>, int width=0> 157template <class T>
126CProgram<T>::CProgram() 158CProgram<T>::CProgram()
127{ 159{
128 m_instrset.insert(new CInstructionInc<T>); 160 m_instrset.insert(new CInstructionInc<T>);
@@ -143,7 +175,7 @@ CProgram<T>::CProgram()
143 175
144/*----------------------------------------------------------------------------*/ 176/*----------------------------------------------------------------------------*/
145 177
146template<class T=CDat<int>, int width=0> 178template <class T>
147CProgram<T>::~CProgram() 179CProgram<T>::~CProgram()
148{ 180{
149 /* free instruction set */ 181 /* free instruction set */
@@ -157,7 +189,7 @@ CProgram<T>::~CProgram()
157 189
158/*----------------------------------------------------------------------------*/ 190/*----------------------------------------------------------------------------*/
159 191
160template<class T=CDat<int>, int width=0> 192template <class T>
161void CProgram<T>::compile(std::istream& in) 193void CProgram<T>::compile(std::istream& in)
162{ 194{
163 if (!in.good()) 195 if (!in.good())
@@ -200,7 +232,7 @@ void CProgram<T>::compile(std::istream& in)
200 { 232 {
201 std::stringstream sstr; 233 std::stringstream sstr;
202 sstr << "Unknown instruction '" << instrname << "' on line " << i << "."; 234 sstr << "Unknown instruction '" << instrname << "' on line " << i << ".";
203 throw std::runtime_error(sstr.str()); 235 throw CProgramError(sstr.str());
204 } 236 }
205 237
206 /* create instruction */ 238 /* create instruction */
@@ -219,20 +251,20 @@ void CProgram<T>::compile(std::istream& in)
219 if (instrname == "label") 251 if (instrname == "label")
220 { 252 {
221 if (instrparams.size() != 1) 253 if (instrparams.size() != 1)
222 throw std::runtime_error("Invalid paramater count - must be 1"); 254 throw CInstructionError("Invalid paramater count - must be 1");
223 std::string label(instrparams.front()); 255 std::string label(instrparams.front());
224 if (label.length() < 2 || label[ label.length() - 1] != ':') 256 if (label.length() < 2 || label[ label.length() - 1] != ':')
225 throw std::runtime_error("Label has invalid syntax"); 257 throw CInstructionError("Label has invalid syntax");
226 m_labels[ label.substr(0, label.length() - 1) ] = size(); 258 m_labels[ label.substr(0, label.length() - 1) ] = size();
227 } 259 }
228 instr->compile(instrparams); 260 instr->compile(instrparams);
229 } 261 }
230 catch(std::runtime_error& ex) 262 catch(CInstructionError& ex)
231 { 263 {
232 std::stringstream sstr; 264 std::stringstream sstr;
233 sstr << "Unable to compile instruction '" << instrname 265 sstr << "Unable to compile instruction '" << instrname
234 << "' (line " << i << "): " << ex.what(); 266 << "' (line " << i << "): " << ex.what();
235 throw std::runtime_error(sstr.str()); 267 throw CProgramError(sstr.str());
236 } 268 }
237 269
238 push_back(instr); 270 push_back(instr);
@@ -241,20 +273,20 @@ void CProgram<T>::compile(std::istream& in)
241 273
242/*----------------------------------------------------------------------------*/ 274/*----------------------------------------------------------------------------*/
243 275
244template<class T=CDat<int>, int width=0> 276template <class T>
245unsigned CProgram<T>::findLabel(const std::string& label) const 277unsigned CProgram<T>::findLabel(const std::string& label) const
246{ 278{
247 std::map<std::string, unsigned>::const_iterator it; 279 std::map<std::string, unsigned>::const_iterator it;
248 it = m_labels.find(label); 280 it = m_labels.find(label);
249 if (it == m_labels.end()) 281 if (it == m_labels.end())
250 throw std::runtime_error("Unknown label '" + label + "'"); 282 throw CProgramError("Unknown label '" + label + "'");
251 return it->second; 283 return it->second;
252} 284}
253 285
254/*----------------------------------------------------------------------------*/ 286/*----------------------------------------------------------------------------*/
255 287
256#if DEBUG 288#if DEBUG
257template<class T=CDat<int>, int width=0> 289template <class T>
258void CProgram<T>::dump(std::ostream& out) 290void CProgram<T>::dump(std::ostream& out)
259{ 291{
260 out << "[PROGRAM DUMP]" << std::endl; 292 out << "[PROGRAM DUMP]" << std::endl;
diff --git a/ue4/mycpu/displays.h b/ue4/mycpu/displays.h
index 33d81bb..123547f 100644
--- a/ue4/mycpu/displays.h
+++ b/ue4/mycpu/displays.h
@@ -19,7 +19,7 @@
19 */ 19 */
20template <class T> 20template <class T>
21class CDisplayWDEZ 21class CDisplayWDEZ
22 : public CDisplay<T> 22 : public CDisplay<T>
23{ 23{
24 public: 24 public:
25 CDisplayWDEZ() 25 CDisplayWDEZ()
@@ -33,7 +33,8 @@ class CDisplayWDEZ
33 * @return - 33 * @return -
34 * @globalvars none 34 * @globalvars none
35 * @exception none 35 * @exception none
36 * @conditions none 36 * @pre none
37 * @post none
37 */ 38 */
38 void display(const T &value) 39 void display(const T &value)
39 { 40 {
@@ -51,7 +52,7 @@ class CDisplayWDEZ
51 */ 52 */
52template <class T> 53template <class T>
53class CDisplayWHEX 54class CDisplayWHEX
54 : public CDisplay<T> 55 : public CDisplay<T>
55{ 56{
56 public: 57 public:
57 CDisplayWHEX() 58 CDisplayWHEX()
@@ -65,7 +66,8 @@ class CDisplayWHEX
65 * @return - 66 * @return -
66 * @globalvars none 67 * @globalvars none
67 * @exception none 68 * @exception none
68 * @conditions none 69 * @pre none
70 * @post none
69 */ 71 */
70 void display(const T &value) 72 void display(const T &value)
71 { 73 {
diff --git a/ue4/mycpu/instructions.h b/ue4/mycpu/instructions.h
index 3f2fd51..fd547aa 100644
--- a/ue4/mycpu/instructions.h
+++ b/ue4/mycpu/instructions.h
@@ -19,9 +19,9 @@
19 * Syntax: inc R1 19 * Syntax: inc R1
20 * (R1++) 20 * (R1++)
21 */ 21 */
22template<class T=CDat<int>, int width=0> 22template <class T>
23class CInstructionInc 23class CInstructionInc
24 : public CInstruction<T> 24 : public CInstruction<T>
25{ 25{
26 typedef CInstruction<T> super; 26 typedef CInstruction<T> super;
27 27
@@ -45,22 +45,21 @@ class CInstructionInc
45 45
46/*----------------------------------------------------------------------------*/ 46/*----------------------------------------------------------------------------*/
47 47
48template<class T=CDat<int>, int width=0> 48template <class T>
49void CInstructionInc<T>::compile(std::list<std::string>& params) 49void CInstructionInc<T>::compile(std::list<std::string>& params)
50{ 50{
51 if (params.size() != 1) 51 if (params.size() != 1)
52 throw std::runtime_error("Invalid paramater count - must be 1"); 52 throw CInstructionError("Invalid paramater count - must be 1");
53 m_regidx1 = super::parseRegister(params.front()); 53 m_regidx1 = super::parseRegister(params.front());
54 params.pop_front(); 54 params.pop_front();
55} 55}
56 56
57/*----------------------------------------------------------------------------*/ 57/*----------------------------------------------------------------------------*/
58 58
59template<class T=CDat<int>, int width=0> 59template <class T>
60void CInstructionInc<T>::execute(CCPU<T> *cpu) 60void CInstructionInc<T>::execute(CCPU<T> *cpu)
61{ 61{
62 assert(cpu != NULL); 62 assert(cpu != NULL);
63 assert(cpu->getRegisters() != NULL);
64 super::checkRegister(cpu, m_regidx1); 63 super::checkRegister(cpu, m_regidx1);
65 cpu->getRegisters()[ m_regidx1 ]++; 64 cpu->getRegisters()[ m_regidx1 ]++;
66} 65}
@@ -74,7 +73,7 @@ void CInstructionInc<T>::execute(CCPU<T> *cpu)
74 * Syntax: dec R1 73 * Syntax: dec R1
75 * (R1--) 74 * (R1--)
76 */ 75 */
77template<class T=CDat<int>, int width=0> 76template <class T>
78class CInstructionDec 77class CInstructionDec
79 : public CInstruction<T> 78 : public CInstruction<T>
80{ 79{
@@ -100,22 +99,21 @@ class CInstructionDec
100 99
101/*----------------------------------------------------------------------------*/ 100/*----------------------------------------------------------------------------*/
102 101
103template<class T=CDat<int>, int width=0> 102template <class T>
104void CInstructionDec<T>::compile(std::list<std::string>& params) 103void CInstructionDec<T>::compile(std::list<std::string>& params)
105{ 104{
106 if (params.size() != 1) 105 if (params.size() != 1)
107 throw std::runtime_error("Invalid paramater count - must be 1"); 106 throw CInstructionError("Invalid paramater count - must be 1");
108 m_regidx1 = super::parseRegister(params.front()); 107 m_regidx1 = super::parseRegister(params.front());
109 params.pop_front(); 108 params.pop_front();
110} 109}
111 110
112/*----------------------------------------------------------------------------*/ 111/*----------------------------------------------------------------------------*/
113 112
114template<class T=CDat<int>, int width=0> 113template <class T>
115void CInstructionDec<T>::execute(CCPU<T> *cpu) 114void CInstructionDec<T>::execute(CCPU<T> *cpu)
116{ 115{
117 assert(cpu != NULL); 116 assert(cpu != NULL);
118 assert(cpu->getRegisters() != NULL);
119 super::checkRegister(cpu, m_regidx1); 117 super::checkRegister(cpu, m_regidx1);
120 cpu->getRegisters()[ m_regidx1 ]--; 118 cpu->getRegisters()[ m_regidx1 ]--;
121} 119}
@@ -129,7 +127,7 @@ void CInstructionDec<T>::execute(CCPU<T> *cpu)
129 * Syntax: add R1, R2, R3 127 * Syntax: add R1, R2, R3
130 * (R1 = R2 + R3) 128 * (R1 = R2 + R3)
131 */ 129 */
132template<class T=CDat<int>, int width=0> 130template <class T>
133class CInstructionAdd 131class CInstructionAdd
134 : public CInstruction<T> 132 : public CInstruction<T>
135{ 133{
@@ -159,11 +157,11 @@ class CInstructionAdd
159 157
160/*----------------------------------------------------------------------------*/ 158/*----------------------------------------------------------------------------*/
161 159
162template<class T=CDat<int>, int width=0> 160template <class T>
163void CInstructionAdd<T>::compile(std::list<std::string>& params) 161void CInstructionAdd<T>::compile(std::list<std::string>& params)
164{ 162{
165 if (params.size() != 3) 163 if (params.size() != 3)
166 throw std::runtime_error("Invalid paramater count - must be 3"); 164 throw CInstructionError("Invalid paramater count - must be 3");
167 m_regidx1 = super::parseRegister(params.front()); 165 m_regidx1 = super::parseRegister(params.front());
168 params.pop_front(); 166 params.pop_front();
169 m_regidx2 = super::parseRegister(params.front()); 167 m_regidx2 = super::parseRegister(params.front());
@@ -174,11 +172,10 @@ void CInstructionAdd<T>::compile(std::list<std::string>& params)
174 172
175/*----------------------------------------------------------------------------*/ 173/*----------------------------------------------------------------------------*/
176 174
177template<class T=CDat<int>, int width=0> 175template <class T>
178void CInstructionAdd<T>::execute(CCPU<T> *cpu) 176void CInstructionAdd<T>::execute(CCPU<T> *cpu)
179{ 177{
180 assert(cpu != NULL); 178 assert(cpu != NULL);
181 assert(cpu->getRegisters() != NULL);
182 super::checkRegister(cpu, m_regidx1); 179 super::checkRegister(cpu, m_regidx1);
183 super::checkRegister(cpu, m_regidx2); 180 super::checkRegister(cpu, m_regidx2);
184 super::checkRegister(cpu, m_regidx3); 181 super::checkRegister(cpu, m_regidx3);
@@ -195,7 +192,7 @@ void CInstructionAdd<T>::execute(CCPU<T> *cpu)
195 * Syntax: sub R1, R2, R3 192 * Syntax: sub R1, R2, R3
196 * (R1 = R2 - R3) 193 * (R1 = R2 - R3)
197 */ 194 */
198template<class T=CDat<int>, int width=0> 195template <class T>
199class CInstructionSub 196class CInstructionSub
200 : public CInstruction<T> 197 : public CInstruction<T>
201{ 198{
@@ -225,11 +222,11 @@ class CInstructionSub
225 222
226/*----------------------------------------------------------------------------*/ 223/*----------------------------------------------------------------------------*/
227 224
228template<class T=CDat<int>, int width=0> 225template <class T>
229void CInstructionSub<T>::compile(std::list<std::string>& params) 226void CInstructionSub<T>::compile(std::list<std::string>& params)
230{ 227{
231 if (params.size() != 3) 228 if (params.size() != 3)
232 throw std::runtime_error("Invalid paramater count - must be 3"); 229 throw CInstructionError("Invalid paramater count - must be 3");
233 m_regidx1 = super::parseRegister(params.front()); 230 m_regidx1 = super::parseRegister(params.front());
234 params.pop_front(); 231 params.pop_front();
235 m_regidx2 = super::parseRegister(params.front()); 232 m_regidx2 = super::parseRegister(params.front());
@@ -240,11 +237,10 @@ void CInstructionSub<T>::compile(std::list<std::string>& params)
240 237
241/*----------------------------------------------------------------------------*/ 238/*----------------------------------------------------------------------------*/
242 239
243template<class T=CDat<int>, int width=0> 240template <class T>
244void CInstructionSub<T>::execute(CCPU<T> *cpu) 241void CInstructionSub<T>::execute(CCPU<T> *cpu)
245{ 242{
246 assert(cpu != NULL); 243 assert(cpu != NULL);
247 assert(cpu->getRegisters() != NULL);
248 super::checkRegister(cpu, m_regidx1); 244 super::checkRegister(cpu, m_regidx1);
249 super::checkRegister(cpu, m_regidx2); 245 super::checkRegister(cpu, m_regidx2);
250 super::checkRegister(cpu, m_regidx3); 246 super::checkRegister(cpu, m_regidx3);
@@ -261,7 +257,7 @@ void CInstructionSub<T>::execute(CCPU<T> *cpu)
261 * Syntax: mul R1, R2, R3 257 * Syntax: mul R1, R2, R3
262 * (R1 = R2 * R3) 258 * (R1 = R2 * R3)
263 */ 259 */
264template<class T=CDat<int>, int width=0> 260template <class T>
265class CInstructionMul 261class CInstructionMul
266 : public CInstruction<T> 262 : public CInstruction<T>
267{ 263{
@@ -291,11 +287,11 @@ class CInstructionMul
291 287
292/*----------------------------------------------------------------------------*/ 288/*----------------------------------------------------------------------------*/
293 289
294template<class T=CDat<int>, int width=0> 290template <class T>
295void CInstructionMul<T>::compile(std::list<std::string>& params) 291void CInstructionMul<T>::compile(std::list<std::string>& params)
296{ 292{
297 if (params.size() != 3) 293 if (params.size() != 3)
298 throw std::runtime_error("Invalid paramater count - must be 3"); 294 throw CInstructionError("Invalid paramater count - must be 3");
299 m_regidx1 = super::parseRegister(params.front()); 295 m_regidx1 = super::parseRegister(params.front());
300 params.pop_front(); 296 params.pop_front();
301 m_regidx2 = super::parseRegister(params.front()); 297 m_regidx2 = super::parseRegister(params.front());
@@ -306,7 +302,7 @@ void CInstructionMul<T>::compile(std::list<std::string>& params)
306 302
307/*----------------------------------------------------------------------------*/ 303/*----------------------------------------------------------------------------*/
308 304
309template<class T=CDat<int>, int width=0> 305template <class T>
310void CInstructionMul<T>::execute(CCPU<T> *cpu) 306void CInstructionMul<T>::execute(CCPU<T> *cpu)
311{ 307{
312 super::checkRegister(cpu, m_regidx1); 308 super::checkRegister(cpu, m_regidx1);
@@ -325,7 +321,7 @@ void CInstructionMul<T>::execute(CCPU<T> *cpu)
325 * Syntax: div R1, R2, R3 321 * Syntax: div R1, R2, R3
326 * (R1 = R2 / R3) 322 * (R1 = R2 / R3)
327 */ 323 */
328template<class T=CDat<int>, int width=0> 324template <class T>
329class CInstructionDiv 325class CInstructionDiv
330 : public CInstruction<T> 326 : public CInstruction<T>
331{ 327{
@@ -355,11 +351,11 @@ class CInstructionDiv
355 351
356/*----------------------------------------------------------------------------*/ 352/*----------------------------------------------------------------------------*/
357 353
358template<class T=CDat<int>, int width=0> 354template <class T>
359void CInstructionDiv<T>::compile(std::list<std::string>& params) 355void CInstructionDiv<T>::compile(std::list<std::string>& params)
360{ 356{
361 if (params.size() != 3) 357 if (params.size() != 3)
362 throw std::runtime_error("Invalid paramater count - must be 3"); 358 throw CInstructionError("Invalid paramater count - must be 3");
363 m_regidx1 = super::parseRegister(params.front()); 359 m_regidx1 = super::parseRegister(params.front());
364 params.pop_front(); 360 params.pop_front();
365 m_regidx2 = super::parseRegister(params.front()); 361 m_regidx2 = super::parseRegister(params.front());
@@ -370,11 +366,10 @@ void CInstructionDiv<T>::compile(std::list<std::string>& params)
370 366
371/*----------------------------------------------------------------------------*/ 367/*----------------------------------------------------------------------------*/
372 368
373template<class T=CDat<int>, int width=0> 369template <class T>
374void CInstructionDiv<T>::execute(CCPU<T> *cpu) 370void CInstructionDiv<T>::execute(CCPU<T> *cpu)
375{ 371{
376 assert(cpu != NULL); 372 assert(cpu != NULL);
377 assert(cpu->getRegisters() != NULL);
378 super::checkRegister(cpu, m_regidx1); 373 super::checkRegister(cpu, m_regidx1);
379 super::checkRegister(cpu, m_regidx2); 374 super::checkRegister(cpu, m_regidx2);
380 super::checkRegister(cpu, m_regidx3); 375 super::checkRegister(cpu, m_regidx3);
@@ -391,7 +386,7 @@ void CInstructionDiv<T>::execute(CCPU<T> *cpu)
391 * Syntax: load R1, R2 386 * Syntax: load R1, R2
392 * (R1 = memory[R2]) 387 * (R1 = memory[R2])
393 */ 388 */
394template<class T=CDat<int>, int width=0> 389template <class T>
395class CInstructionLoad 390class CInstructionLoad
396 : public CInstruction<T> 391 : public CInstruction<T>
397{ 392{
@@ -419,11 +414,11 @@ class CInstructionLoad
419 414
420/*----------------------------------------------------------------------------*/ 415/*----------------------------------------------------------------------------*/
421 416
422template<class T=CDat<int>, int width=0> 417template <class T>
423void CInstructionLoad<T>::compile(std::list<std::string>& params) 418void CInstructionLoad<T>::compile(std::list<std::string>& params)
424{ 419{
425 if (params.size() != 2) 420 if (params.size() != 2)
426 throw std::runtime_error("Invalid paramater count - must be 2"); 421 throw CInstructionError("Invalid paramater count - must be 2");
427 m_regidx1 = super::parseRegister(params.front()); 422 m_regidx1 = super::parseRegister(params.front());
428 params.pop_front(); 423 params.pop_front();
429 m_regidx2 = super::parseRegister(params.front()); 424 m_regidx2 = super::parseRegister(params.front());
@@ -432,11 +427,10 @@ void CInstructionLoad<T>::compile(std::list<std::string>& params)
432 427
433/*----------------------------------------------------------------------------*/ 428/*----------------------------------------------------------------------------*/
434 429
435template<class T=CDat<int>, int width=0> 430template <class T>
436void CInstructionLoad<T>::execute(CCPU<T> *cpu) 431void CInstructionLoad<T>::execute(CCPU<T> *cpu)
437{ 432{
438 assert(cpu != NULL); 433 assert(cpu != NULL);
439 assert(cpu->getRegisters() != NULL);
440 assert(cpu->getMemory() != NULL); 434 assert(cpu->getMemory() != NULL);
441 super::checkRegister(cpu, m_regidx1); 435 super::checkRegister(cpu, m_regidx1);
442 super::checkRegister(cpu, m_regidx2); 436 super::checkRegister(cpu, m_regidx2);
@@ -453,7 +447,7 @@ void CInstructionLoad<T>::execute(CCPU<T> *cpu)
453 * Syntax: store R1, R2 447 * Syntax: store R1, R2
454 * (memory[R2] = R1) 448 * (memory[R2] = R1)
455 */ 449 */
456template<class T=CDat<int>, int width=0> 450template <class T>
457class CInstructionStore 451class CInstructionStore
458 : public CInstruction<T> 452 : public CInstruction<T>
459{ 453{
@@ -481,11 +475,11 @@ class CInstructionStore
481 475
482/*----------------------------------------------------------------------------*/ 476/*----------------------------------------------------------------------------*/
483 477
484template<class T=CDat<int>, int width=0> 478template <class T>
485void CInstructionStore<T>::compile(std::list<std::string>& params) 479void CInstructionStore<T>::compile(std::list<std::string>& params)
486{ 480{
487 if (params.size() != 2) 481 if (params.size() != 2)
488 throw std::runtime_error("Invalid paramater count - must be 2"); 482 throw CInstructionError("Invalid paramater count - must be 2");
489 m_regidx1 = super::parseRegister(params.front()); 483 m_regidx1 = super::parseRegister(params.front());
490 params.pop_front(); 484 params.pop_front();
491 m_regidx2 = super::parseRegister(params.front()); 485 m_regidx2 = super::parseRegister(params.front());
@@ -494,11 +488,10 @@ void CInstructionStore<T>::compile(std::list<std::string>& params)
494 488
495/*----------------------------------------------------------------------------*/ 489/*----------------------------------------------------------------------------*/
496 490
497template<class T=CDat<int>, int width=0> 491template <class T>
498void CInstructionStore<T>::execute(CCPU<T> *cpu) 492void CInstructionStore<T>::execute(CCPU<T> *cpu)
499{ 493{
500 assert(cpu != NULL); 494 assert(cpu != NULL);
501 assert(cpu->getRegisters() != NULL);
502 assert(cpu->getMemory() != NULL); 495 assert(cpu->getMemory() != NULL);
503 super::checkRegister(cpu, m_regidx1); 496 super::checkRegister(cpu, m_regidx1);
504 super::checkRegister(cpu, m_regidx2); 497 super::checkRegister(cpu, m_regidx2);
@@ -515,7 +508,7 @@ void CInstructionStore<T>::execute(CCPU<T> *cpu)
515 * Syntax: test R1 508 * Syntax: test R1
516 * (R1 == 0: zeroflag: true, R1 < 0: signflag: true) 509 * (R1 == 0: zeroflag: true, R1 < 0: signflag: true)
517 */ 510 */
518template<class T=CDat<int>, int width=0> 511template <class T>
519class CInstructionTest 512class CInstructionTest
520 : public CInstruction<T> 513 : public CInstruction<T>
521{ 514{
@@ -541,22 +534,21 @@ class CInstructionTest
541 534
542/*----------------------------------------------------------------------------*/ 535/*----------------------------------------------------------------------------*/
543 536
544template<class T=CDat<int>, int width=0> 537template <class T>
545void CInstructionTest<T>::compile(std::list<std::string>& params) 538void CInstructionTest<T>::compile(std::list<std::string>& params)
546{ 539{
547 if (params.size() != 1) 540 if (params.size() != 1)
548 throw std::runtime_error("Invalid paramater count - must be 1"); 541 throw CInstructionError("Invalid paramater count - must be 1");
549 m_regidx1 = super::parseRegister(params.front()); 542 m_regidx1 = super::parseRegister(params.front());
550 params.pop_front(); 543 params.pop_front();
551} 544}
552 545
553/*----------------------------------------------------------------------------*/ 546/*----------------------------------------------------------------------------*/
554 547
555template<class T=CDat<int>, int width=0> 548template <class T>
556void CInstructionTest<T>::execute(CCPU<T> *cpu) 549void CInstructionTest<T>::execute(CCPU<T> *cpu)
557{ 550{
558 assert(cpu != NULL); 551 assert(cpu != NULL);
559 assert(cpu->getRegisters() != NULL);
560 super::checkRegister(cpu, m_regidx1); 552 super::checkRegister(cpu, m_regidx1);
561 if (cpu->getRegisters()[ m_regidx1 ] == T(0)) 553 if (cpu->getRegisters()[ m_regidx1 ] == T(0))
562 cpu->setFlagZero(true); 554 cpu->setFlagZero(true);
@@ -572,7 +564,7 @@ void CInstructionTest<T>::execute(CCPU<T> *cpu)
572 * Implementation of assembler command "label" 564 * Implementation of assembler command "label"
573 * Syntax: label name: 565 * Syntax: label name:
574 */ 566 */
575template<class T=CDat<int>, int width=0> 567template <class T>
576class CInstructionLabel 568class CInstructionLabel
577 : public CInstruction<T> 569 : public CInstruction<T>
578{ 570{
@@ -604,7 +596,7 @@ class CInstructionLabel
604 * Syntax: jumpa labelname 596 * Syntax: jumpa labelname
605 * (jump to labelname) 597 * (jump to labelname)
606 */ 598 */
607template<class T=CDat<int>, int width=0> 599template <class T>
608class CInstructionJumpA 600class CInstructionJumpA
609 : public CInstruction<T> 601 : public CInstruction<T>
610{ 602{
@@ -630,26 +622,32 @@ class CInstructionJumpA
630 622
631/*----------------------------------------------------------------------------*/ 623/*----------------------------------------------------------------------------*/
632 624
633template<class T=CDat<int>, int width=0> 625template <class T>
634void CInstructionJumpA<T>::compile(std::list<std::string>& params) 626void CInstructionJumpA<T>::compile(std::list<std::string>& params)
635{ 627{
636 if (params.size() != 1) 628 if (params.size() != 1)
637 throw std::runtime_error("Invalid paramater count - must be 1"); 629 throw CInstructionError("Invalid paramater count - must be 1");
638 m_addr = params.front(); 630 m_addr = params.front();
639 params.pop_front(); 631 params.pop_front();
640} 632}
641 633
642/*----------------------------------------------------------------------------*/ 634/*----------------------------------------------------------------------------*/
643 635
644template<class T=CDat<int>, int width=0> 636template <class T>
645void CInstructionJumpA<T>::execute(CCPU<T> *cpu) 637void CInstructionJumpA<T>::execute(CCPU<T> *cpu)
646{ 638{
647 assert(cpu != NULL); 639 assert(cpu != NULL);
648 assert(cpu->getRegisters() != NULL);
649 assert(cpu->getProgram() != NULL); 640 assert(cpu->getProgram() != NULL);
650 if (m_addr.empty()) 641 if (m_addr.empty())
651 throw std::runtime_error("Empty address"); 642 throw CInstructionError("Empty address");
652 cpu->getRegisters()[ 0 ] = cpu->getProgram()->findLabel(m_addr); 643 try
644 {
645 cpu->getRegisters()[ 0 ] = cpu->getProgram()->findLabel(m_addr);
646 }
647 catch(CProgramError& ex)
648 {
649 throw CInstructionError(ex.what());
650 }
653} 651}
654 652
655/*============================================================================*/ 653/*============================================================================*/
@@ -661,7 +659,7 @@ void CInstructionJumpA<T>::execute(CCPU<T> *cpu)
661 * Syntax: jumpz labelname 659 * Syntax: jumpz labelname
662 * (jump to labelname if zeroflag) 660 * (jump to labelname if zeroflag)
663 */ 661 */
664template<class T=CDat<int>, int width=0> 662template <class T>
665class CInstructionJumpZ 663class CInstructionJumpZ
666 : public CInstruction<T> 664 : public CInstruction<T>
667{ 665{
@@ -687,28 +685,34 @@ class CInstructionJumpZ
687 685
688/*----------------------------------------------------------------------------*/ 686/*----------------------------------------------------------------------------*/
689 687
690template<class T=CDat<int>, int width=0> 688template <class T>
691void CInstructionJumpZ<T>::compile(std::list<std::string>& params) 689void CInstructionJumpZ<T>::compile(std::list<std::string>& params)
692{ 690{
693 if (params.size() != 1) 691 if (params.size() != 1)
694 throw std::runtime_error("Invalid paramater count - must be 1"); 692 throw CInstructionError("Invalid paramater count - must be 1");
695 m_addr = params.front(); 693 m_addr = params.front();
696 params.pop_front(); 694 params.pop_front();
697} 695}
698 696
699/*----------------------------------------------------------------------------*/ 697/*----------------------------------------------------------------------------*/
700 698
701template<class T=CDat<int>, int width=0> 699template <class T>
702void CInstructionJumpZ<T>::execute(CCPU<T> *cpu) 700void CInstructionJumpZ<T>::execute(CCPU<T> *cpu)
703{ 701{
704 assert(cpu != NULL); 702 assert(cpu != NULL);
705 assert(cpu->getRegisters() != NULL);
706 assert(cpu->getProgram() != NULL); 703 assert(cpu->getProgram() != NULL);
707 if (!cpu->getFlagZero()) 704 if (!cpu->getFlagZero())
708 return; 705 return;
709 if (m_addr.empty()) 706 if (m_addr.empty())
710 throw std::runtime_error("Empty address"); 707 throw CInstructionError("Empty address");
711 cpu->getRegisters()[ 0 ] = cpu->getProgram()->findLabel(m_addr); 708 try
709 {
710 cpu->getRegisters()[ 0 ] = cpu->getProgram()->findLabel(m_addr);
711 }
712 catch(CProgramError& ex)
713 {
714 throw CInstructionError(ex.what());
715 }
712} 716}
713 717
714/*============================================================================*/ 718/*============================================================================*/
@@ -720,7 +724,7 @@ void CInstructionJumpZ<T>::execute(CCPU<T> *cpu)
720 * Syntax: jumps labelname 724 * Syntax: jumps labelname
721 * (jump to labelname if signflag) 725 * (jump to labelname if signflag)
722 */ 726 */
723template<class T=CDat<int>, int width=0> 727template <class T>
724class CInstructionJumpS 728class CInstructionJumpS
725 : public CInstruction<T> 729 : public CInstruction<T>
726{ 730{
@@ -746,28 +750,34 @@ class CInstructionJumpS
746 750
747/*----------------------------------------------------------------------------*/ 751/*----------------------------------------------------------------------------*/
748 752
749template<class T=CDat<int>, int width=0> 753template <class T>
750void CInstructionJumpS<T>::compile(std::list<std::string>& params) 754void CInstructionJumpS<T>::compile(std::list<std::string>& params)
751{ 755{
752 if (params.size() != 1) 756 if (params.size() != 1)
753 throw std::runtime_error("Invalid paramater count - must be 1"); 757 throw CInstructionError("Invalid paramater count - must be 1");
754 m_addr = params.front(); 758 m_addr = params.front();
755 params.pop_front(); 759 params.pop_front();
756} 760}
757 761
758/*----------------------------------------------------------------------------*/ 762/*----------------------------------------------------------------------------*/
759 763
760template<class T=CDat<int>, int width=0> 764template <class T>
761void CInstructionJumpS<T>::execute(CCPU<T> *cpu) 765void CInstructionJumpS<T>::execute(CCPU<T> *cpu)
762{ 766{
763 assert(cpu != NULL); 767 assert(cpu != NULL);
764 assert(cpu->getRegisters() != NULL);
765 assert(cpu->getProgram() != NULL); 768 assert(cpu->getProgram() != NULL);
766 if (!cpu->getFlagSign()) 769 if (!cpu->getFlagSign())
767 return; 770 return;
768 if (m_addr.empty()) 771 if (m_addr.empty())
769 throw std::runtime_error("Empty address"); 772 throw CInstructionError("Empty address");
770 cpu->getRegisters()[ 0 ] = cpu->getProgram()->findLabel(m_addr); 773 try
774 {
775 cpu->getRegisters()[ 0 ] = cpu->getProgram()->findLabel(m_addr);
776 }
777 catch(CProgramError& ex)
778 {
779 throw CInstructionError(ex.what());
780 }
771} 781}
772 782
773/*============================================================================*/ 783/*============================================================================*/
@@ -779,7 +789,7 @@ void CInstructionJumpS<T>::execute(CCPU<T> *cpu)
779 * Syntax: write DEV, R1 789 * Syntax: write DEV, R1
780 * (write R1 to DEV, which is a name of a display) 790 * (write R1 to DEV, which is a name of a display)
781 */ 791 */
782template<class T=CDat<int>, int width=0> 792template <class T>
783class CInstructionWrite 793class CInstructionWrite
784 : public CInstruction<T> 794 : public CInstruction<T>
785{ 795{
@@ -808,11 +818,11 @@ class CInstructionWrite
808 818
809/*----------------------------------------------------------------------------*/ 819/*----------------------------------------------------------------------------*/
810 820
811template<class T=CDat<int>, int width=0> 821template <class T>
812void CInstructionWrite<T>::compile(std::list<std::string>& params) 822void CInstructionWrite<T>::compile(std::list<std::string>& params)
813{ 823{
814 if (params.size() != 2) 824 if (params.size() != 2)
815 throw std::runtime_error("Invalid paramater count - must be 2"); 825 throw CInstructionError("Invalid paramater count - must be 2");
816 m_dev = params.front(); 826 m_dev = params.front();
817 params.pop_front(); 827 params.pop_front();
818 m_regidx1 = super::parseRegister(params.front()); 828 m_regidx1 = super::parseRegister(params.front());
@@ -821,14 +831,13 @@ void CInstructionWrite<T>::compile(std::list<std::string>& params)
821 831
822/*----------------------------------------------------------------------------*/ 832/*----------------------------------------------------------------------------*/
823 833
824template<class T=CDat<int>, int width=0> 834template <class T>
825void CInstructionWrite<T>::execute(CCPU<T> *cpu) 835void CInstructionWrite<T>::execute(CCPU<T> *cpu)
826{ 836{
827 assert(cpu != NULL); 837 assert(cpu != NULL);
828 assert(cpu->getRegisters() != NULL);
829 super::checkRegister(cpu, m_regidx1); 838 super::checkRegister(cpu, m_regidx1);
830 if (m_dev.empty()) 839 if (m_dev.empty())
831 throw std::runtime_error("Empty device"); 840 throw CInstructionError("Empty device");
832 841
833 CDisplay<T> *display = NULL; 842 CDisplay<T> *display = NULL;
834 std::set<CDisplay<T> *> displays = cpu->getDisplays(); 843 std::set<CDisplay<T> *> displays = cpu->getDisplays();
@@ -841,7 +850,7 @@ void CInstructionWrite<T>::execute(CCPU<T> *cpu)
841 } 850 }
842 } 851 }
843 if (display == NULL) 852 if (display == NULL)
844 throw std::runtime_error("Unknown display"); 853 throw CInstructionError("Unknown display");
845 854
846 display->display(cpu->getRegisters()[ m_regidx1 ]); 855 display->display(cpu->getRegisters()[ m_regidx1 ]);
847} 856}
diff --git a/ue4/mycpu/mycpu.cpp b/ue4/mycpu/mycpu.cpp
index 2d73177..ac4498a 100644
--- a/ue4/mycpu/mycpu.cpp
+++ b/ue4/mycpu/mycpu.cpp
@@ -12,20 +12,100 @@
12 */ 12 */
13 13
14#include <boost/program_options.hpp> 14#include <boost/program_options.hpp>
15#include <boost/lexical_cast.hpp>
15#include <iostream> 16#include <iostream>
16#include <fstream> 17#include <fstream>
17#include <stdexcept> 18#include <stdexcept>
18#include <stdlib.h> 19#include <stdlib.h>
19#include "cdat.h" 20#include "cdat.h"
20#include "cdatn.h"
21#include "cdatset.h" 21#include "cdatset.h"
22#include "cdatn.h"
23#include "ccpu.h"
22#include "cmem.h" 24#include "cmem.h"
23#include "cprogram.h" 25#include "cprogram.h"
24#include "ccpu.h" 26
27#define REGISTERS 256
25 28
26using namespace std; 29using namespace std;
27namespace po = boost::program_options; 30namespace po = boost::program_options;
28 31
32/* TODO */
33template<class T>
34void cpu_run(string& me, po::variables_map& vm, unsigned registers, T& datatype)
35{
36 CMem<T> memory;
37 /* optionally initialize memory from file */
38 if (vm.count("memory"))
39 {
40 string memoryfile(vm["memory"].as<string>());
41 ifstream file(memoryfile.c_str(), ios::in);
42 if (!file.is_open())
43 throw runtime_error("Unable to open memoryfile '" + memoryfile + "' for reading.");
44
45 try
46 {
47 memory.initialize(file, datatype);
48 file.close();
49 }
50 catch(CMemError& ex)
51 {
52 file.close();
53 std::stringstream sstr;
54 sstr << "Error while reading from memoryfile:" << endl << " " << ex.what();
55 throw runtime_error(sstr.str());
56 }
57
58#if DEBUG
59 memory.dump(cerr);
60#endif
61 }
62
63 /* create program instance */
64 CProgram<T> program;
65 string programfile(vm["compile"].as<string>());
66 ifstream file(programfile.c_str(), ios::in);
67 if (!file.is_open())
68 throw runtime_error("Unable to open programfile '" + programfile + "' for reading.");
69
70 try
71 {
72 program.compile(file);
73 file.close();
74 }
75 catch(CProgramError& ex)
76 {
77 file.close();
78 std::stringstream sstr;
79 sstr << "Error while compiling programfile:" << endl << " " << ex.what();
80 throw runtime_error(sstr.str());
81 }
82
83#if DEBUG
84 program.dump(cerr);
85#endif
86
87 /* execute the program */
88 CCPU<T> cpu(registers, datatype);
89 try
90 {
91 cpu.setMemory(&memory);
92 cpu.setProgram(&program);
93 cpu.run();
94#if DEBUG
95 //cpu.dumpRegisters(cerr);
96#endif
97 }
98 catch(CCPUError& ex)
99 {
100 std::stringstream sstr;
101 sstr << "Error while executing program:" << endl << " " << ex.what();
102#if DEBUG
103 memory.dump(cerr);
104#endif
105 throw runtime_error(sstr.str());
106 }
107}
108
29/** 109/**
30 * @func main 110 * @func main
31 * @brief program entry point 111 * @brief program entry point
@@ -34,7 +114,8 @@ namespace po = boost::program_options;
34 * @return 0 on success, not 0 otherwise 114 * @return 0 on success, not 0 otherwise
35 * @globalvars none 115 * @globalvars none
36 * @exception none 116 * @exception none
37 * @conditions none 117 * @pre none
118 * @post none
38 * 119 *
39 * parse commandline options, create and initialize memory, 120 * parse commandline options, create and initialize memory,
40 * create cprogram instance, which parses the programfile and 121 * create cprogram instance, which parses the programfile and
@@ -50,7 +131,7 @@ int main(int argc, char* argv[])
50 po::options_description desc("Allowed options"); 131 po::options_description desc("Allowed options");
51 desc.add_options() 132 desc.add_options()
52 ("help,h", "this help message") 133 ("help,h", "this help message")
53 ("format,f", po::value<string>(), "format") 134 ("format,f", po::value<string>(), "input format")
54 ("compile,c", po::value<string>(), "input programfile") 135 ("compile,c", po::value<string>(), "input programfile")
55 ("memory,m", po::value<string>(), "input memoryfile"); 136 ("memory,m", po::value<string>(), "input memoryfile");
56 137
@@ -64,6 +145,7 @@ int main(int argc, char* argv[])
64 catch(po::error& ex) 145 catch(po::error& ex)
65 { 146 {
66 cerr << me << ": Error: " << ex.what() << endl; 147 cerr << me << ": Error: " << ex.what() << endl;
148 return 1;
67 } 149 }
68 150
69 /* print usage upon request or missing params */ 151 /* print usage upon request or missing params */
@@ -74,107 +156,49 @@ int main(int argc, char* argv[])
74 return 0; 156 return 0;
75 } 157 }
76 158
77 /* create memory and optionally initialize memory from file */ 159 /* create memory, program and cpu from templates */
78 160 try
79 CMem *memory = NULL;
80 if (vm.count("format"))
81 { 161 {
82 string format(vm["format"].as<string>()); 162 if (vm.count("format"))
83 if(format == "s")
84 memory = new CMem<CDatSet<int> >();
85 else
86 { 163 {
87 try 164 string format(vm["format"].as<string>());
165 if (format == "s")
88 { 166 {
89 int bc = boost::lexical_cast<int>(format); 167 CDatSet datatype(0);
90 if (bc > 1 && bc < 33) 168 cpu_run<CDatSet>(me, vm, REGISTERS, datatype);
91 memory = new CMem<CDatN<int> >(); 169 }
92 } 170 else
93 catch(boost::bad_lexical_cast& ex)
94 { 171 {
95 std::stringstream sstr; 172 unsigned bc;
96 sstr << "Illegal format: (" << format << "): " << ex.what(); 173 try
97 throw std::runtime_error(sstr.str()); 174 {
175 bc = boost::lexical_cast<unsigned>(format);
176 }
177 catch(boost::bad_lexical_cast& ex)
178 {
179 cerr << me << ": Paramater 'format' has invalid or unknown format." << endl;
180 return 1;
181 }
182
183 if (bc < 2 || bc > 31)
184 {
185 cerr << me << ": Paramater 'format' must be inbetween 2 and 32." << endl;
186 return 1;
187 }
188
189 CDatN datatype(0, bc);
190 cpu_run<CDatN>(me, vm, REGISTERS, datatype);
98 } 191 }
99 } 192 }
100 } 193 else
101 else
102
103
104 if (vm.count("memory"))
105 {
106 string memoryfile(vm["memory"].as<string>());
107 ifstream file(memoryfile.c_str(), ios::in);
108 if (!file.is_open())
109 {
110 cerr << me << ": Unable to open memoryfile '" << memoryfile << "' for reading." << endl;
111 return 1;
112 }
113
114 try
115 {
116 memory->initialize(file);
117 file.close();
118 }
119 catch(runtime_error& ex)
120 { 194 {
121 file.close(); 195 CDat<int> datatype(0);
122 cerr << me << ": Error while reading from memoryfile:" << endl 196 cpu_run<CDat<int> >(me, vm, REGISTERS, datatype);
123 << " " << ex.what() << endl;
124 return 1;
125 } 197 }
126
127#if DEBUG
128 memory->dump(cerr);
129#endif
130 }
131
132 /* create program instance */
133 CProgram<CDat<int> > program;
134 string programfile(vm["compile"].as<string>());
135 ifstream file(programfile.c_str(), ios::in);
136 if (!file.is_open())
137 {
138 cerr << me << ": Unable to open programfile '" << programfile << "' for reading." << endl;
139 return 1;
140 }
141
142 try
143 {
144 program.compile(file);
145 file.close();
146 }
147 catch(runtime_error& ex)
148 {
149 file.close();
150 cerr << me << ": Error while compiling programfile:" << endl
151 << " " << ex.what() << endl;
152 return 1;
153 }
154
155#if DEBUG
156 program.dump(cerr);
157#endif
158
159
160 /* create cpu and execute the program */
161 try
162 {
163 CCPU<CDat<int> > cpu(256);
164 cpu.setMemory(memory);
165 cpu.setProgram(&program);
166 cpu.run();
167#if DEBUG
168 //cpu.dumpRegisters(cerr);
169#endif
170 } 198 }
171 catch(runtime_error& ex) 199 catch(runtime_error& ex)
172 { 200 {
173 cerr << me << ": Error while executing program:" << endl 201 cerr << me << ": " << ex.what() << endl;
174 << " " << ex.what() << endl;
175#if DEBUG
176 memory->dump(cerr);
177#endif
178 return 1; 202 return 1;
179 } 203 }
180 204
diff --git a/ue4/mycpu/test/test.sh b/ue4/mycpu/test/test.sh
index ff1076c..43ddb9a 100755
--- a/ue4/mycpu/test/test.sh
+++ b/ue4/mycpu/test/test.sh
@@ -10,13 +10,20 @@ do
10 10
11 programfile="$input" 11 programfile="$input"
12 args="-c $programfile" 12 args="-c $programfile"
13 argsfile="${input/_program/_args}"
13 memoryfile="${input/_program/_memory}" 14 memoryfile="${input/_program/_memory}"
14 reffile="${input/_program/_output}" 15 reffile="${input/_program/_output}"
15 if [ -e "$memoryfile" ] 16
17 if [ ! -e "$argsfile" ]
16 then 18 then
17 args+=" -m $memoryfile" 19 echo " ERROR: argsfile $argsfile doesn't exist"
20 exit 1
18 fi 21 fi
19 22
23 args=$(cat "$argsfile")
24 args=${args/\#program\#/$input}
25 args=${args/\#memory\#/$memoryfile}
26
20 if [ ! -e "$reffile" ] 27 if [ ! -e "$reffile" ]
21 then 28 then
22 echo " ERROR: reference file $reffile doesn't exist" 29 echo " ERROR: reference file $reffile doesn't exist"
diff --git a/ue4/mycpu/test/test1_args b/ue4/mycpu/test/test1_args
new file mode 100644
index 0000000..c494f4e
--- /dev/null
+++ b/ue4/mycpu/test/test1_args
@@ -0,0 +1 @@
-c #program# -m #memory#
diff --git a/ue4/mycpu/test/test2_args b/ue4/mycpu/test/test2_args
new file mode 100644
index 0000000..1ef5766
--- /dev/null
+++ b/ue4/mycpu/test/test2_args
@@ -0,0 +1 @@
-f s -c #program# -m #memory#
diff --git a/ue4/mycpu/test/test2_memory b/ue4/mycpu/test/test2_memory
new file mode 100644
index 0000000..bd9648e
--- /dev/null
+++ b/ue4/mycpu/test/test2_memory
@@ -0,0 +1 @@
oooooooooooooooooooo
diff --git a/ue4/mycpu/test/test2_output b/ue4/mycpu/test/test2_output
new file mode 100644
index 0000000..ac30dc2
--- /dev/null
+++ b/ue4/mycpu/test/test2_output
@@ -0,0 +1,19 @@
11
22
33
44
55
66
77
88
99
1010
1111
1212
1313
1414
1515
1616
1717
1818
1919
diff --git a/ue4/mycpu/test/test2_program b/ue4/mycpu/test/test2_program
new file mode 100644
index 0000000..ae5e9d2
--- /dev/null
+++ b/ue4/mycpu/test/test2_program
@@ -0,0 +1,13 @@
1# set R2 = 10
2LOAD R2, R1
3
4# start of loop
5label Loop:
6inc R3
7sub R4, R3, R2
8test R4
9jumpz EndLoop
10write WDEZ, R3
11jumpa Loop
12
13label EndLoop:
diff --git a/ue4/mycpu/test/test3_args b/ue4/mycpu/test/test3_args
new file mode 100644
index 0000000..098d137
--- /dev/null
+++ b/ue4/mycpu/test/test3_args
@@ -0,0 +1 @@
-f 5 -c #program# -m #memory#
diff --git a/ue4/mycpu/test/test3_memory b/ue4/mycpu/test/test3_memory
new file mode 100644
index 0000000..fa8f08c
--- /dev/null
+++ b/ue4/mycpu/test/test3_memory
@@ -0,0 +1 @@
150
diff --git a/ue4/mycpu/test/test3_output b/ue4/mycpu/test/test3_output
new file mode 100644
index 0000000..d4de868
--- /dev/null
+++ b/ue4/mycpu/test/test3_output
@@ -0,0 +1,21 @@
11
22
33
44
55
66
77
88
99
1010
1111
1212
1313
1414
1515
1616
1717
1818
1919
2020
2121
diff --git a/ue4/mycpu/test/test3_program b/ue4/mycpu/test/test3_program
new file mode 100644
index 0000000..ae5e9d2
--- /dev/null
+++ b/ue4/mycpu/test/test3_program
@@ -0,0 +1,13 @@
1# set R2 = 10
2LOAD R2, R1
3
4# start of loop
5label Loop:
6inc R3
7sub R4, R3, R2
8test R4
9jumpz EndLoop
10write WDEZ, R3
11jumpa Loop
12
13label EndLoop: