summaryrefslogtreecommitdiffstats
path: root/ue3
diff options
context:
space:
mode:
authormanuel <manuel@nc8430.lan>2009-05-13 04:09:39 +0200
committermanuel <manuel@nc8430.lan>2009-05-13 04:09:39 +0200
commit89e202f49b9857dcd3627fbc4e0262125d729bbc (patch)
treedbe69dd8498eb0a489bc7b7e24f2b73580c598d2 /ue3
parent45581d3d376e8deed84952cb838ae330549e5241 (diff)
downloadooprog-89e202f49b9857dcd3627fbc4e0262125d729bbc.tar.gz
ooprog-89e202f49b9857dcd3627fbc4e0262125d729bbc.tar.bz2
ooprog-89e202f49b9857dcd3627fbc4e0262125d729bbc.zip
adding all instructions and displays
Diffstat (limited to 'ue3')
-rw-r--r--ue3/mycpu/Makefile2
-rw-r--r--ue3/mycpu/ccpu.cpp18
-rw-r--r--ue3/mycpu/ccpu.h84
-rw-r--r--ue3/mycpu/cdat.h4
-rw-r--r--ue3/mycpu/cdisplay.h41
-rw-r--r--ue3/mycpu/cinstruction.cpp4
-rw-r--r--ue3/mycpu/cinstruction.h133
-rw-r--r--ue3/mycpu/cprogram.cpp14
-rw-r--r--ue3/mycpu/displays.h56
-rw-r--r--ue3/mycpu/instructions.cpp339
-rw-r--r--ue3/mycpu/instructions.h399
-rw-r--r--ue3/mycpu/mycpu.cpp16
-rw-r--r--ue3/mycpu/test/memory11
-rw-r--r--ue3/mycpu/test/program113
14 files changed, 1051 insertions, 73 deletions
diff --git a/ue3/mycpu/Makefile b/ue3/mycpu/Makefile
index 16067d1..eec8b47 100644
--- a/ue3/mycpu/Makefile
+++ b/ue3/mycpu/Makefile
@@ -12,7 +12,7 @@ LIBS= -L/usr/local/lib -lboost_program_options
12 12
13BIN= mycpu 13BIN= mycpu
14OBJS= cinstruction.o instructions.o cprogram.o ccpu.o mycpu.o 14OBJS= cinstruction.o instructions.o cprogram.o ccpu.o mycpu.o
15HEADERS= cdat.h cmem.h cinstruction.h instructions.h cprogram.h cdisplay.h ccpu.h 15HEADERS= cdat.h cmem.h cinstruction.h instructions.h cprogram.h cdisplay.h displays.h ccpu.h
16 16
17.SUFFIXES: .cpp .o 17.SUFFIXES: .cpp .o
18 18
diff --git a/ue3/mycpu/ccpu.cpp b/ue3/mycpu/ccpu.cpp
index 6f364f8..b1539a4 100644
--- a/ue3/mycpu/ccpu.cpp
+++ b/ue3/mycpu/ccpu.cpp
@@ -10,23 +10,35 @@
10# include <iomanip> 10# include <iomanip>
11#endif 11#endif
12#include "ccpu.h" 12#include "ccpu.h"
13#include "displays.h"
13 14
14using namespace std; 15using namespace std;
15 16
16CCPU::CCPU(const unsigned cnt) 17CCPU::CCPU(const unsigned cnt)
17 : m_regcnt(cnt), m_memory(NULL), m_program(NULL), m_flagzero(0), m_flagsign(0) 18 : m_regcnt(cnt), m_memory(NULL), m_program(NULL), m_flagzero(false), m_flagsign(false)
18{ 19{
20 /* create registers */
19 m_registers = new CDat[cnt]; 21 m_registers = new CDat[cnt];
20 for(unsigned i = 0; i < cnt; ++i) 22 for(unsigned i = 0; i < cnt; ++i)
21 m_registers[i] = 0; 23 m_registers[i] = 0;
24
25 /* create displays */
26 m_displays.insert(new CDisplayWDEZ);
27 m_displays.insert(new CDisplayWHEX);
22} 28}
23 29
24/*----------------------------------------------------------------------------*/ 30/*----------------------------------------------------------------------------*/
25 31
26CCPU::~CCPU() 32CCPU::~CCPU()
27{ 33{
34 /* delete registers */
28 delete[] m_registers; 35 delete[] m_registers;
29 m_registers = NULL; 36 m_registers = NULL;
37
38 /* delete displays */
39 std::set<CDisplay *>::iterator it;
40 for (it = m_displays.begin() ; it != m_displays.end(); ++it)
41 delete *it;
30} 42}
31 43
32/*----------------------------------------------------------------------------*/ 44/*----------------------------------------------------------------------------*/
@@ -47,7 +59,7 @@ void CCPU::run()
47 59
48 /* end of the program reached */ 60 /* end of the program reached */
49 if (pc == m_program->size()) 61 if (pc == m_program->size())
50 return; 62 break;
51 63
52 /* pc is out of bound */ 64 /* pc is out of bound */
53 if (pc > m_program->size()) 65 if (pc > m_program->size())
@@ -57,8 +69,6 @@ void CCPU::run()
57 m_program->at(pc)->execute(this); 69 m_program->at(pc)->execute(this);
58 ++m_registers[0]; 70 ++m_registers[0];
59 } 71 }
60
61 cout << "LALA" << endl;
62} 72}
63 73
64/*----------------------------------------------------------------------------*/ 74/*----------------------------------------------------------------------------*/
diff --git a/ue3/mycpu/ccpu.h b/ue3/mycpu/ccpu.h
index e28a7cc..1ef1923 100644
--- a/ue3/mycpu/ccpu.h
+++ b/ue3/mycpu/ccpu.h
@@ -8,11 +8,12 @@
8#ifndef CCPU_H 8#ifndef CCPU_H
9#define CCPU_H 1 9#define CCPU_H 1
10 10
11#include <vector>
12#include <iostream> 11#include <iostream>
12#include <set>
13#include "cdat.h" 13#include "cdat.h"
14#include "cmem.h" 14#include "cmem.h"
15#include "cprogram.h" 15#include "cprogram.h"
16#include "cdisplay.h"
16 17
17/** 18/**
18 * @class CCPU 19 * @class CCPU
@@ -53,7 +54,7 @@ class CCPU
53 * @exception none 54 * @exception none
54 * @conditions none 55 * @conditions none
55 */ 56 */
56 const unsigned getRegisterCount() 57 const unsigned getRegisterCount() const
57 { 58 {
58 return m_regcnt; 59 return m_regcnt;
59 } 60 }
@@ -67,7 +68,7 @@ class CCPU
67 * @exception none 68 * @exception none
68 * @conditions none 69 * @conditions none
69 */ 70 */
70 CDat *getRegisters() 71 CDat *getRegisters() const
71 { 72 {
72 return m_registers; 73 return m_registers;
73 } 74 }
@@ -81,7 +82,7 @@ class CCPU
81 * @exception none 82 * @exception none
82 * @conditions none 83 * @conditions none
83 */ 84 */
84 void setMemory(const CMem *memory) 85 void setMemory(CMem *memory)
85 { 86 {
86 m_memory = memory; 87 m_memory = memory;
87 } 88 }
@@ -95,7 +96,7 @@ class CCPU
95 * @exception none 96 * @exception none
96 * @conditions none 97 * @conditions none
97 */ 98 */
98 const CMem *getMemory() 99 CMem *getMemory() const
99 { 100 {
100 return m_memory; 101 return m_memory;
101 } 102 }
@@ -129,6 +130,76 @@ class CCPU
129 } 130 }
130 131
131 /** 132 /**
133 * @method getDisplays
134 * @brief get set of pointers to displays
135 * @param -
136 * @return reference to set of pointers to displays
137 * @globalvars none
138 * @exception none
139 * @conditions none
140 */
141 const std::set<CDisplay *>& getDisplays()
142 {
143 return m_displays;
144 }
145
146 /**
147 * @method setFlagZero
148 * @brief set zero flag
149 * @param value new value of zero flag
150 * @return -
151 * @globalvars none
152 * @exception none
153 * @conditions none
154 */
155 void setFlagZero(const bool value)
156 {
157 m_flagzero = value;
158 }
159
160 /**
161 * @method getFlagZero
162 * @brief get value of zero flag
163 * @param -
164 * @return value of zero flag
165 * @globalvars none
166 * @exception none
167 * @conditions none
168 */
169 const bool getFlagZero()
170 {
171 return m_flagzero;
172 }
173
174 /**
175 * @method setFlagSign
176 * @brief set sign flag
177 * @param value new value of sign flag
178 * @return -
179 * @globalvars none
180 * @exception none
181 * @conditions none
182 */
183 void setFlagSign(const bool value)
184 {
185 m_flagsign = value;
186 }
187
188 /**
189 * @method getFlagSign
190 * @brief get value of sign flag
191 * @param -
192 * @return value of sign flag
193 * @globalvars none
194 * @exception none
195 * @conditions none
196 */
197 const bool getFlagSign()
198 {
199 return m_flagsign;
200 }
201
202 /**
132 * @method run 203 * @method run
133 * @brief execute current program 204 * @brief execute current program
134 * @param - 205 * @param -
@@ -156,8 +227,9 @@ class CCPU
156 /* members */ 227 /* members */
157 CDat *m_registers; 228 CDat *m_registers;
158 unsigned m_regcnt; 229 unsigned m_regcnt;
159 const CMem *m_memory; 230 CMem *m_memory;
160 const CProgram *m_program; 231 const CProgram *m_program;
232 std::set<CDisplay *> m_displays;
161 bool m_flagzero; 233 bool m_flagzero;
162 bool m_flagsign; 234 bool m_flagsign;
163}; 235};
diff --git a/ue3/mycpu/cdat.h b/ue3/mycpu/cdat.h
index 365bd88..c656b99 100644
--- a/ue3/mycpu/cdat.h
+++ b/ue3/mycpu/cdat.h
@@ -72,7 +72,7 @@ class CDatT
72 {} 72 {}
73 73
74 /** 74 /**
75 * @method value 75 * @method getValue
76 * @brief returns value of CDatT 76 * @brief returns value of CDatT
77 * @param - 77 * @param -
78 * @return value of CDatT 78 * @return value of CDatT
@@ -80,7 +80,7 @@ class CDatT
80 * @exception none 80 * @exception none
81 * @conditions none 81 * @conditions none
82 */ 82 */
83 T value() const 83 T getValue() const
84 { 84 {
85 return m_value; 85 return m_value;
86 } 86 }
diff --git a/ue3/mycpu/cdisplay.h b/ue3/mycpu/cdisplay.h
index 629ec88..ed9b84d 100644
--- a/ue3/mycpu/cdisplay.h
+++ b/ue3/mycpu/cdisplay.h
@@ -6,7 +6,7 @@
6 */ 6 */
7 7
8#ifndef CDISPLAY_H 8#ifndef CDISPLAY_H
9#define CDISPLAY_H #1 9#define CDISPLAY_H 1
10 10
11/** 11/**
12 * @class CDisplay 12 * @class CDisplay
@@ -19,14 +19,16 @@ class CDisplay
19 /** 19 /**
20 * @method CDisplay 20 * @method CDisplay
21 * @brief Default ctor 21 * @brief Default ctor
22 * @param - 22 * @param name name of display
23 * @return - 23 * @return -
24 * @globalvars none 24 * @globalvars none
25 * @exception none 25 * @exception none
26 * @conditions none 26 * @conditions none
27 */ 27 */
28 CDisplay() 28 CDisplay(std::string name)
29 {}; 29 {
30 m_name = name;
31 }
30 32
31 /** 33 /**
32 * @method ~CDisplay 34 * @method ~CDisplay
@@ -37,10 +39,37 @@ class CDisplay
37 * @exception none 39 * @exception none
38 * @conditions none 40 * @conditions none
39 */ 41 */
40 ~CDisplay(); 42 virtual ~CDisplay()
43 {}
44
45 /**
46 * @method getName
47 * @brief returns name of display
48 * @param -
49 * @return name of display
50 * @globalvars none
51 * @exception none
52 * @conditions none
53 */
54 virtual const std::string& getName()
55 {
56 return m_name;
57 }
58
59 /**
60 * @method getName
61 * @brief prints value to display
62 * @param value value to display
63 * @return -
64 * @globalvars none
65 * @exception none
66 * @conditions none
67 */
68 virtual void display(const CDat &value) = 0;
41 69
42 private: 70 protected:
43 /* members */ 71 /* members */
72 std::string m_name;
44}; 73};
45 74
46#endif 75#endif
diff --git a/ue3/mycpu/cinstruction.cpp b/ue3/mycpu/cinstruction.cpp
index 32bdd2f..57acd5f 100644
--- a/ue3/mycpu/cinstruction.cpp
+++ b/ue3/mycpu/cinstruction.cpp
@@ -16,7 +16,7 @@ using namespace std;
16const unsigned CInstruction::parseRegister(const std::string& str) 16const unsigned CInstruction::parseRegister(const std::string& str)
17{ 17{
18 unsigned reg; 18 unsigned reg;
19 if (str.length() < 2 || str[0] != 'R') 19 if (str.length() < 2 || str[0] != 'r')
20 throw runtime_error("Invalid syntax of register"); 20 throw runtime_error("Invalid syntax of register");
21 21
22 try 22 try
@@ -33,7 +33,7 @@ const unsigned CInstruction::parseRegister(const std::string& str)
33 33
34/*----------------------------------------------------------------------------*/ 34/*----------------------------------------------------------------------------*/
35 35
36inline void CInstruction::checkRegister(CCPU *cpu, unsigned regidx) 36inline void CInstruction::checkRegister(CCPU *cpu, const unsigned regidx)
37{ 37{
38 if (regidx >= cpu->getRegisterCount()) 38 if (regidx >= cpu->getRegisterCount())
39 { 39 {
diff --git a/ue3/mycpu/cinstruction.h b/ue3/mycpu/cinstruction.h
index b16c067..57fcff1 100644
--- a/ue3/mycpu/cinstruction.h
+++ b/ue3/mycpu/cinstruction.h
@@ -10,9 +10,8 @@
10 10
11#include <iostream> 11#include <iostream>
12#include <list> 12#include <list>
13//#include "ccpu.h"
14 13
15/* declare CCPU */ 14/* forward declare CCPU */
16class CCPU; 15class CCPU;
17 16
18/** 17/**
@@ -26,7 +25,7 @@ class CInstruction
26 /** 25 /**
27 * @method CInstruction 26 * @method CInstruction
28 * @brief Default ctor 27 * @brief Default ctor
29 * @param - 28 * @param name name of instruction
30 * @return - 29 * @return -
31 * @globalvars none 30 * @globalvars none
32 * @exception none 31 * @exception none
@@ -34,7 +33,7 @@ class CInstruction
34 */ 33 */
35 CInstruction(std::string name) 34 CInstruction(std::string name)
36 : m_name(name) 35 : m_name(name)
37 {}; 36 {}
38 37
39 /** 38 /**
40 * @method ~CInstruction 39 * @method ~CInstruction
@@ -46,46 +45,150 @@ class CInstruction
46 * @conditions none 45 * @conditions none
47 */ 46 */
48 virtual ~CInstruction() 47 virtual ~CInstruction()
49 {}; 48 {}
50 49
51 /* TODO */ 50 /**
51 * @method operator==
52 * @brief implementation of operator ==
53 * @param reference to std::string
54 * @return true if instructionname is name
55 * @globalvars none
56 * @exception none
57 * @conditions none
58 */
52 virtual bool operator==(std::string& name) 59 virtual bool operator==(std::string& name)
53 { 60 {
54 return name == m_name; 61 return name == m_name;
55 } 62 }
56 63
57 /* TODO */ 64 /**
65 * @method getName
66 * @brief returns instruction name
67 * @param -
68 * @return name of instruction
69 * @globalvars none
70 * @exception none
71 * @conditions none
72 */
58 virtual const std::string& getName() 73 virtual const std::string& getName()
59 { 74 {
60 return m_name; 75 return m_name;
61 } 76 }
62 77
63 /* TODO */ 78 /**
79 * @method isLabel
80 * @brief returns true if the instruction defines a label
81 * @param -
82 * @return true if the instruction defines a label
83 * @globalvars none
84 * @exception none
85 * @conditions none
86 */
87 virtual const bool isLabel()
88 {
89 return false;
90 }
91
92 /**
93 * @method getLabelName
94 * @brief returns labelname if the instruction defines a label
95 * @param -
96 * @return labelname if the instruction defines a label
97 * @globalvars none
98 * @exception none
99 * @conditions none
100 */
101 virtual const std::string getLabelName()
102 {
103 return "";
104 }
105
106 /**
107 * @method dump
108 * @brief dumps information about instruction to outputstream
109 * @param stream outputstream
110 * @return reference to outputstream
111 * @globalvars none
112 * @exception none
113 * @conditions none
114 */
64 virtual std::ostream& dump(std::ostream& stream) 115 virtual std::ostream& dump(std::ostream& stream)
65 { 116 {
66 stream << m_name; 117 stream << m_name;
67 return stream; 118 return stream;
68 } 119 }
69 120
70 /* TODO */ 121 /**
122 * @method operator<<
123 * @brief Shift/output operator for outputstream
124 * @param stream reference to outputstream
125 * @param cdat object which will be printed to stream
126 * @return reference to outputstream
127 * @globalvars none
128 * @exception none
129 * @conditions none
130 */
71 friend std::ostream& operator<<(std::ostream& stream, CInstruction& instr) 131 friend std::ostream& operator<<(std::ostream& stream, CInstruction& instr)
72 { 132 {
73 return instr.dump(stream); 133 return instr.dump(stream);
74 } 134 }
75 135
76 /* TODO */ 136 /**
137 * @method parseRegister
138 * @brief parses register syntax Rx (e.g. "R1")
139 * @param str register in assembler syntax
140 * @return registernumber
141 * @globalvars none
142 * @exception runtime_error
143 * @conditions none
144 */
77 virtual const unsigned parseRegister(const std::string& str); 145 virtual const unsigned parseRegister(const std::string& str);
78 146
79 /* TODO */ 147 /**
80 virtual void checkRegister(CCPU *cpu, unsigned regidx); 148 * @method checkRegister
149 * @brief performs a register boundary check
150 * does the register exist in cpu?
151 * @param cpu pointer to cpu
152 * @param regidx registernumber
153 * @return -
154 * @globalvars none
155 * @exception runtime_error
156 * @conditions none
157 */
158 virtual void checkRegister(CCPU *cpu, const unsigned regidx);
81 159
82 /* TODO */ 160 /**
161 * @method factory
162 * @brief creates a new instance of this instruction
163 * @param -
164 * @return new instruction instance
165 * @globalvars none
166 * @exception none
167 * @conditions none
168 */
83 virtual CInstruction *factory() = 0; 169 virtual CInstruction *factory() = 0;
84 170
85 /* TODO */ 171 /**
172 * @method compile
173 * @brief parses instruction parameters and prepares the
174 * instruction for executing
175 * @param params list of parameters of this instruction
176 * @return -
177 * @globalvars none
178 * @exception runtime_error
179 * @conditions none
180 */
86 virtual void compile(std::list<std::string>& params) = 0; 181 virtual void compile(std::list<std::string>& params) = 0;
87 182
88 /* TODO */ 183 /**
184 * @method execute
185 * @brief executes the instruction
186 * @param cpu pointer to cpu
187 * @return -
188 * @globalvars none
189 * @exception runtime_error
190 * @conditions none
191 */
89 virtual void execute(CCPU *cpu) = 0; 192 virtual void execute(CCPU *cpu) = 0;
90 193
91 protected: 194 protected:
diff --git a/ue3/mycpu/cprogram.cpp b/ue3/mycpu/cprogram.cpp
index 03d4c30..f6fc3cb 100644
--- a/ue3/mycpu/cprogram.cpp
+++ b/ue3/mycpu/cprogram.cpp
@@ -19,6 +19,19 @@ using namespace std;
19CProgram::CProgram() 19CProgram::CProgram()
20{ 20{
21 m_instrset.insert(new CInstructionInc); 21 m_instrset.insert(new CInstructionInc);
22 m_instrset.insert(new CInstructionDec);
23 m_instrset.insert(new CInstructionAdd);
24 m_instrset.insert(new CInstructionSub);
25 m_instrset.insert(new CInstructionMul);
26 m_instrset.insert(new CInstructionDiv);
27 m_instrset.insert(new CInstructionLoad);
28 m_instrset.insert(new CInstructionStore);
29 m_instrset.insert(new CInstructionTest);
30 m_instrset.insert(new CInstructionLabel);
31 m_instrset.insert(new CInstructionJumpA);
32 m_instrset.insert(new CInstructionJumpZ);
33 m_instrset.insert(new CInstructionJumpS);
34 m_instrset.insert(new CInstructionWrite);
22} 35}
23 36
24/*----------------------------------------------------------------------------*/ 37/*----------------------------------------------------------------------------*/
@@ -54,6 +67,7 @@ void CProgram::compile(std::istream& in)
54 continue; 67 continue;
55 68
56 boost::trim(line); 69 boost::trim(line);
70 boost::to_lower(line);
57 71
58 /* ignore comments */ 72 /* ignore comments */
59 if (line.find_first_of('#') == 0) 73 if (line.find_first_of('#') == 0)
diff --git a/ue3/mycpu/displays.h b/ue3/mycpu/displays.h
new file mode 100644
index 0000000..f7adbdb
--- /dev/null
+++ b/ue3/mycpu/displays.h
@@ -0,0 +1,56 @@
1/**
2 * @module displays
3 * @author Guenther Neuwirth (0626638), Manuel Mausz (0728348)
4 * @brief TODO
5 * @date 10.05.2009
6 */
7
8#ifndef DISPLAYS_H
9#define DISPLAYS_H 1
10
11#include <iomanip>
12#include "cdisplay.h"
13
14/**
15 * @class CDisplayWDEZ
16 *
17 * TODO
18 */
19class CDisplayWDEZ
20 : public CDisplay
21{
22 public:
23 CDisplayWDEZ()
24 : CDisplay("wdez")
25 {}
26
27 void display(const CDat &value)
28 {
29 std::cout << std::dec << value << std::endl;
30 }
31};
32
33/*============================================================================*/
34
35/**
36 * @class CDisplayWHEX
37 *
38 * TODO
39 */
40class CDisplayWHEX
41 : public CDisplay
42{
43 public:
44 CDisplayWHEX()
45 : CDisplay("whex")
46 {}
47
48 void display(const CDat &value)
49 {
50 std::cout << std::hex << value << std::endl;
51 }
52};
53
54#endif
55
56/* vim: set et sw=2 ts=2: */
diff --git a/ue3/mycpu/instructions.cpp b/ue3/mycpu/instructions.cpp
index c283e57..609cd1c 100644
--- a/ue3/mycpu/instructions.cpp
+++ b/ue3/mycpu/instructions.cpp
@@ -14,6 +14,7 @@ void CInstructionInc::compile(std::list<std::string>& params)
14 if (params.size() != 1) 14 if (params.size() != 1)
15 throw runtime_error("Invalid paramater count - must be 1"); 15 throw runtime_error("Invalid paramater count - must be 1");
16 m_regidx1 = parseRegister(params.front()); 16 m_regidx1 = parseRegister(params.front());
17 params.pop_front();
17} 18}
18 19
19/*----------------------------------------------------------------------------*/ 20/*----------------------------------------------------------------------------*/
@@ -21,7 +22,343 @@ void CInstructionInc::compile(std::list<std::string>& params)
21void CInstructionInc::execute(CCPU *cpu) 22void CInstructionInc::execute(CCPU *cpu)
22{ 23{
23 checkRegister(cpu, m_regidx1); 24 checkRegister(cpu, m_regidx1);
24 cpu->getRegisters()[m_regidx1]++; 25 cpu->getRegisters()[ m_regidx1 ]++;
25} 26}
26 27
28/*============================================================================*/
29
30void CInstructionDec::compile(std::list<std::string>& params)
31{
32 if (params.size() != 1)
33 throw runtime_error("Invalid paramater count - must be 1");
34 m_regidx1 = parseRegister(params.front());
35 params.pop_front();
36}
37
38/*----------------------------------------------------------------------------*/
39
40void CInstructionDec::execute(CCPU *cpu)
41{
42 checkRegister(cpu, m_regidx1);
43 cpu->getRegisters()[ m_regidx1 ]--;
44}
45
46/*============================================================================*/
47
48void CInstructionAdd::compile(std::list<std::string>& params)
49{
50 if (params.size() != 3)
51 throw runtime_error("Invalid paramater count - must be 3");
52 m_regidx1 = parseRegister(params.front());
53 params.pop_front();
54 m_regidx2 = parseRegister(params.front());
55 params.pop_front();
56 m_regidx3 = parseRegister(params.front());
57 params.pop_front();
58}
59
60/*----------------------------------------------------------------------------*/
61
62void CInstructionAdd::execute(CCPU *cpu)
63{
64 checkRegister(cpu, m_regidx1);
65 checkRegister(cpu, m_regidx2);
66 checkRegister(cpu, m_regidx3);
67 cpu->getRegisters()[ m_regidx1 ] = cpu->getRegisters()[ m_regidx2 ]
68 + cpu->getRegisters()[ m_regidx3 ];
69}
70
71/*============================================================================*/
72
73void CInstructionSub::compile(std::list<std::string>& params)
74{
75 if (params.size() != 3)
76 throw runtime_error("Invalid paramater count - must be 3");
77 m_regidx1 = parseRegister(params.front());
78 params.pop_front();
79 m_regidx2 = parseRegister(params.front());
80 params.pop_front();
81 m_regidx3 = parseRegister(params.front());
82 params.pop_front();
83}
84
85/*----------------------------------------------------------------------------*/
86
87void CInstructionSub::execute(CCPU *cpu)
88{
89 checkRegister(cpu, m_regidx1);
90 checkRegister(cpu, m_regidx2);
91 checkRegister(cpu, m_regidx3);
92 cpu->getRegisters()[ m_regidx1 ] = cpu->getRegisters()[ m_regidx2 ]
93 - cpu->getRegisters()[ m_regidx3 ];
94}
95
96/*============================================================================*/
97
98void CInstructionMul::compile(std::list<std::string>& params)
99{
100 if (params.size() != 3)
101 throw runtime_error("Invalid paramater count - must be 3");
102 m_regidx1 = parseRegister(params.front());
103 params.pop_front();
104 m_regidx2 = parseRegister(params.front());
105 params.pop_front();
106 m_regidx3 = parseRegister(params.front());
107 params.pop_front();
108}
109
110/*----------------------------------------------------------------------------*/
111
112void CInstructionMul::execute(CCPU *cpu)
113{
114 checkRegister(cpu, m_regidx1);
115 checkRegister(cpu, m_regidx2);
116 checkRegister(cpu, m_regidx3);
117 cpu->getRegisters()[ m_regidx1 ] = cpu->getRegisters()[ m_regidx2 ]
118 * cpu->getRegisters()[ m_regidx3 ];
119}
120
121/*============================================================================*/
122
123void CInstructionDiv::compile(std::list<std::string>& params)
124{
125 if (params.size() != 3)
126 throw runtime_error("Invalid paramater count - must be 3");
127 m_regidx1 = parseRegister(params.front());
128 params.pop_front();
129 m_regidx2 = parseRegister(params.front());
130 params.pop_front();
131 m_regidx3 = parseRegister(params.front());
132 params.pop_front();
133}
134
135/*----------------------------------------------------------------------------*/
136
137void CInstructionDiv::execute(CCPU *cpu)
138{
139 checkRegister(cpu, m_regidx1);
140 checkRegister(cpu, m_regidx2);
141 checkRegister(cpu, m_regidx3);
142 cpu->getRegisters()[ m_regidx1 ] = cpu->getRegisters()[ m_regidx2 ]
143 / cpu->getRegisters()[ m_regidx3 ];
144}
145
146/*============================================================================*/
147
148void CInstructionLoad::compile(std::list<std::string>& params)
149{
150 if (params.size() != 2)
151 throw runtime_error("Invalid paramater count - must be 2");
152 m_regidx1 = parseRegister(params.front());
153 params.pop_front();
154 m_regidx2 = parseRegister(params.front());
155 params.pop_front();
156}
157
158/*----------------------------------------------------------------------------*/
159
160void CInstructionLoad::execute(CCPU *cpu)
161{
162 checkRegister(cpu, m_regidx1);
163 checkRegister(cpu, m_regidx2);
164 CDat val = cpu->getRegisters()[ m_regidx2 ];
165 cpu->getRegisters()[ m_regidx1 ] = (*cpu->getMemory())[ val ];
166}
167
168/*============================================================================*/
169
170void CInstructionStore::compile(std::list<std::string>& params)
171{
172 if (params.size() != 2)
173 throw runtime_error("Invalid paramater count - must be 2");
174 m_regidx1 = parseRegister(params.front());
175 params.pop_front();
176 m_regidx2 = parseRegister(params.front());
177 params.pop_front();
178}
179
180/*----------------------------------------------------------------------------*/
181
182void CInstructionStore::execute(CCPU *cpu)
183{
184 checkRegister(cpu, m_regidx1);
185 checkRegister(cpu, m_regidx2);
186 CDat val = cpu->getRegisters()[ m_regidx2 ];
187 (*cpu->getMemory())[ val ] = cpu->getRegisters()[ m_regidx1 ];
188}
189
190/*============================================================================*/
191
192void CInstructionTest::compile(std::list<std::string>& params)
193{
194 if (params.size() != 1)
195 throw runtime_error("Invalid paramater count - must be 1");
196 m_regidx1 = parseRegister(params.front());
197 params.pop_front();
198}
199
200/*----------------------------------------------------------------------------*/
201
202void CInstructionTest::execute(CCPU *cpu)
203{
204 checkRegister(cpu, m_regidx1);
205 if (cpu->getRegisters()[ m_regidx1 ] == CDat(0))
206 cpu->setFlagZero(true);
207 if (cpu->getRegisters()[ m_regidx1 ] < CDat(0))
208 cpu->setFlagSign(true);
209}
210
211/*============================================================================*/
212
213void CInstructionLabel::compile(std::list<std::string>& params)
214{
215 if (params.size() != 1)
216 throw runtime_error("Invalid paramater count - must be 1");
217 string label = params.front();
218 params.pop_front();
219 if (label.length() < 2 || label[ label.length() - 1] != ':')
220 throw runtime_error("Label has invalid syntax");
221 m_label = label.substr(0, label.length() - 1);
222}
223
224/*----------------------------------------------------------------------------*/
225
226void CInstructionLabel::execute(CCPU *cpu)
227{
228 if (m_label.empty())
229 throw runtime_error("Empty label");
230}
231
232/*============================================================================*/
233
234void CInstructionJumpA::compile(std::list<std::string>& params)
235{
236 if (params.size() != 1)
237 throw runtime_error("Invalid paramater count - must be 1");
238 m_addr = params.front();
239 params.pop_front();
240}
241
242/*----------------------------------------------------------------------------*/
243
244void CInstructionJumpA::execute(CCPU *cpu)
245{
246 if (m_addr.empty())
247 throw runtime_error("Empty address");
248
249 const CProgram *progam = cpu->getProgram();
250 for(unsigned i = 0; i < progam->size(); i++)
251 {
252 if (progam->at(i)->isLabel() && progam->at(i)->getLabelName() == m_addr)
253 {
254 cpu->getRegisters()[ 0 ] = i;
255 return;
256 }
257 }
258
259 throw runtime_error("Unknown label '" + m_addr + "'");
260}
261
262/*============================================================================*/
263
264void CInstructionJumpZ::compile(std::list<std::string>& params)
265{
266 if (params.size() != 1)
267 throw runtime_error("Invalid paramater count - must be 1");
268 m_addr = params.front();
269 params.pop_front();
270}
271
272/*----------------------------------------------------------------------------*/
273
274void CInstructionJumpZ::execute(CCPU *cpu)
275{
276 if (!cpu->getFlagZero())
277 return;
278 if (m_addr.empty())
279 throw runtime_error("Empty address");
280
281 const CProgram *progam = cpu->getProgram();
282 for(unsigned i = 0; i < progam->size(); i++)
283 {
284 if (progam->at(i)->isLabel() && progam->at(i)->getLabelName() == m_addr)
285 {
286 cpu->getRegisters()[ 0 ] = i;
287 return;
288 }
289 }
290
291 throw runtime_error("Unknown label '" + m_addr + "'");
292}
293
294/*============================================================================*/
295
296void CInstructionJumpS::compile(std::list<std::string>& params)
297{
298 if (params.size() != 1)
299 throw runtime_error("Invalid paramater count - must be 1");
300 m_addr = params.front();
301 params.pop_front();
302}
303
304/*----------------------------------------------------------------------------*/
305
306void CInstructionJumpS::execute(CCPU *cpu)
307{
308 if (!cpu->getFlagSign())
309 return;
310 if (m_addr.empty())
311 throw runtime_error("Empty address");
312
313 const CProgram *progam = cpu->getProgram();
314 for(unsigned i = 0; i < progam->size(); i++)
315 {
316 if (progam->at(i)->isLabel() && progam->at(i)->getLabelName() == m_addr)
317 {
318 cpu->getRegisters()[ 0 ] = i;
319 return;
320 }
321 }
322
323 throw runtime_error("Unknown label '" + m_addr + "'");
324}
325
326/*============================================================================*/
327
328void CInstructionWrite::compile(std::list<std::string>& params)
329{
330 if (params.size() != 2)
331 throw runtime_error("Invalid paramater count - must be 2");
332 m_dev = params.front();
333 params.pop_front();
334 m_regidx1 = parseRegister(params.front());
335 params.pop_front();
336}
337
338/*----------------------------------------------------------------------------*/
339
340void CInstructionWrite::execute(CCPU *cpu)
341{
342 checkRegister(cpu, m_regidx1);
343 if (m_dev.empty())
344 throw runtime_error("Empty device");
345
346 CDisplay *display = NULL;
347 std::set<CDisplay *> displays = cpu->getDisplays();
348 std::set<CDisplay *>::iterator it;
349 for(it = displays.begin(); it != displays.end(); ++it)
350 {
351 if ((*it)->getName() == m_dev)
352 {
353 display = *it;
354 break;
355 }
356 }
357 if (display == NULL)
358 throw runtime_error("Unknown display");
359
360 display->display(cpu->getRegisters()[ m_regidx1 ]);
361}
362
363
27/* vim: set et sw=2 ts=2: */ 364/* vim: set et sw=2 ts=2: */
diff --git a/ue3/mycpu/instructions.h b/ue3/mycpu/instructions.h
index ebd1533..8c62e0b 100644
--- a/ue3/mycpu/instructions.h
+++ b/ue3/mycpu/instructions.h
@@ -20,45 +20,392 @@ class CInstructionInc
20 : public CInstruction 20 : public CInstruction
21{ 21{
22 public: 22 public:
23 /**
24 * @method CInstruction
25 * @brief Default ctor
26 * @param -
27 * @return -
28 * @globalvars none
29 * @exception none
30 * @conditions none
31 */
32 CInstructionInc() 23 CInstructionInc()
33 : CInstruction("inc") 24 : CInstruction("inc")
34 {}; 25 {}
35 26
36 /**
37 * @method ~CInstruction
38 * @brief Default dtor
39 * @param -
40 * @return -
41 * @globalvars none
42 * @exception none
43 * @conditions none
44 */
45 ~CInstructionInc()
46 {};
47
48 /* TODO */
49 CInstructionInc *factory() 27 CInstructionInc *factory()
50 { 28 {
51 return new CInstructionInc; 29 return new CInstructionInc;
52 } 30 }
53 31
54 /* TODO */
55 void compile(std::list<std::string>& params); 32 void compile(std::list<std::string>& params);
33 void execute(CCPU *cpu);
34
35 protected:
36 unsigned m_regidx1;
37};
38
39/*============================================================================*/
40
41/**
42 * @class CInstructionDec
43 *
44 * TODO
45 */
46class CInstructionDec
47 : public CInstruction
48{
49 public:
50 CInstructionDec()
51 : CInstruction("dec")
52 {}
53
54 CInstructionDec *factory()
55 {
56 return new CInstructionDec;
57 }
58
59 void compile(std::list<std::string>& params);
60 void execute(CCPU *cpu);
61
62 protected:
63 unsigned m_regidx1;
64};
65
66/*============================================================================*/
67
68/**
69 * @class CInstructionAdd
70 *
71 * TODO
72 */
73class CInstructionAdd
74 : public CInstruction
75{
76 public:
77 CInstructionAdd()
78 : CInstruction("add")
79 {}
80
81 CInstructionAdd *factory()
82 {
83 return new CInstructionAdd;
84 }
85
86 void compile(std::list<std::string>& params);
87 void execute(CCPU *cpu);
88
89 protected:
90 unsigned m_regidx1;
91 unsigned m_regidx2;
92 unsigned m_regidx3;
93};
94
95/*============================================================================*/
96
97/**
98 * @class CInstructionSub
99 *
100 * TODO
101 */
102class CInstructionSub
103 : public CInstruction
104{
105 public:
106 CInstructionSub()
107 : CInstruction("sub")
108 {}
109
110 CInstructionSub *factory()
111 {
112 return new CInstructionSub;
113 }
114
115 void compile(std::list<std::string>& params);
116 void execute(CCPU *cpu);
117
118 protected:
119 unsigned m_regidx1;
120 unsigned m_regidx2;
121 unsigned m_regidx3;
122};
56 123
57 /* TODO */ 124/*============================================================================*/
125
126/**
127 * @class CInstructionMul
128 *
129 * TODO
130 */
131class CInstructionMul
132 : public CInstruction
133{
134 public:
135 CInstructionMul()
136 : CInstruction("mul")
137 {}
138
139 CInstructionMul *factory()
140 {
141 return new CInstructionMul;
142 }
143
144 void compile(std::list<std::string>& params);
145 void execute(CCPU *cpu);
146
147 protected:
148 unsigned m_regidx1;
149 unsigned m_regidx2;
150 unsigned m_regidx3;
151};
152
153/*============================================================================*/
154
155/**
156 * @class CInstructionDiv
157 *
158 * TODO
159 */
160class CInstructionDiv
161 : public CInstruction
162{
163 public:
164 CInstructionDiv()
165 : CInstruction("div")
166 {}
167
168 CInstructionDiv *factory()
169 {
170 return new CInstructionDiv;
171 }
172
173 void compile(std::list<std::string>& params);
174 void execute(CCPU *cpu);
175
176 protected:
177 unsigned m_regidx1;
178 unsigned m_regidx2;
179 unsigned m_regidx3;
180};
181
182/*============================================================================*/
183
184/**
185 * @class CInstructionLoad
186 *
187 * TODO
188 */
189class CInstructionLoad
190 : public CInstruction
191{
192 public:
193 CInstructionLoad()
194 : CInstruction("load")
195 {}
196
197 CInstructionLoad *factory()
198 {
199 return new CInstructionLoad;
200 }
201
202 void compile(std::list<std::string>& params);
203 void execute(CCPU *cpu);
204
205 protected:
206 unsigned m_regidx1;
207 unsigned m_regidx2;
208};
209
210/*============================================================================*/
211
212/**
213 * @class CInstructionStore
214 *
215 * TODO
216 */
217class CInstructionStore
218 : public CInstruction
219{
220 public:
221 CInstructionStore()
222 : CInstruction("store")
223 {}
224
225 CInstructionStore *factory()
226 {
227 return new CInstructionStore;
228 }
229
230 void compile(std::list<std::string>& params);
231 void execute(CCPU *cpu);
232
233 protected:
234 unsigned m_regidx1;
235 unsigned m_regidx2;
236};
237
238/*============================================================================*/
239
240/**
241 * @class CInstructionTest
242 *
243 * TODO
244 */
245class CInstructionTest
246 : public CInstruction
247{
248 public:
249 CInstructionTest()
250 : CInstruction("test")
251 {}
252
253 CInstructionTest *factory()
254 {
255 return new CInstructionTest;
256 }
257
258 void compile(std::list<std::string>& params);
259 void execute(CCPU *cpu);
260
261 protected:
262 unsigned m_regidx1;
263};
264
265/*============================================================================*/
266
267/**
268 * @class CInstructionLabel
269 *
270 * TODO
271 */
272class CInstructionLabel
273 : public CInstruction
274{
275 public:
276 CInstructionLabel()
277 : CInstruction("label"), m_label("")
278 {}
279
280 const bool isLabel()
281 {
282 return true;
283 }
284
285 const std::string getLabelName()
286 {
287 return m_label;
288 }
289
290 CInstructionLabel *factory()
291 {
292 return new CInstructionLabel;
293 }
294
295 void compile(std::list<std::string>& params);
296 void execute(CCPU *cpu);
297
298 protected:
299 std::string m_label;
300};
301
302/*============================================================================*/
303
304/**
305 * @class CInstructionJumpA
306 *
307 * TODO
308 */
309class CInstructionJumpA
310 : public CInstruction
311{
312 public:
313 CInstructionJumpA()
314 : CInstruction("jumpa"), m_addr("")
315 {}
316
317 CInstructionJumpA *factory()
318 {
319 return new CInstructionJumpA;
320 }
321
322 void compile(std::list<std::string>& params);
323 void execute(CCPU *cpu);
324
325 protected:
326 std::string m_addr;
327};
328
329/*============================================================================*/
330
331/**
332 * @class CInstructionJumpZ
333 *
334 * TODO
335 */
336class CInstructionJumpZ
337 : public CInstruction
338{
339 public:
340 CInstructionJumpZ()
341 : CInstruction("jumpz"), m_addr("")
342 {}
343
344 CInstructionJumpZ *factory()
345 {
346 return new CInstructionJumpZ;
347 }
348
349 void compile(std::list<std::string>& params);
350 void execute(CCPU *cpu);
351
352 protected:
353 std::string m_addr;
354};
355
356/*============================================================================*/
357
358/**
359 * @class CInstructionJumpS
360 *
361 * TODO
362 */
363class CInstructionJumpS
364 : public CInstruction
365{
366 public:
367 CInstructionJumpS()
368 : CInstruction("jumps"), m_addr("")
369 {}
370
371 CInstructionJumpS *factory()
372 {
373 return new CInstructionJumpS;
374 }
375
376 void compile(std::list<std::string>& params);
377 void execute(CCPU *cpu);
378
379 protected:
380 std::string m_addr;
381};
382
383/*============================================================================*/
384
385/**
386 * @class CInstructionWrite
387 *
388 * TODO
389 */
390class CInstructionWrite
391 : public CInstruction
392{
393 public:
394 CInstructionWrite()
395 : CInstruction("write"), m_dev("")
396 {}
397
398 CInstructionWrite *factory()
399 {
400 return new CInstructionWrite;
401 }
402
403 void compile(std::list<std::string>& params);
58 void execute(CCPU *cpu); 404 void execute(CCPU *cpu);
59 405
60 protected: 406 protected:
61 unsigned m_regidx1; 407 unsigned m_regidx1;
408 std::string m_dev;
62}; 409};
63 410
64#endif 411#endif
diff --git a/ue3/mycpu/mycpu.cpp b/ue3/mycpu/mycpu.cpp
index af91fe7..08861a4 100644
--- a/ue3/mycpu/mycpu.cpp
+++ b/ue3/mycpu/mycpu.cpp
@@ -19,13 +19,6 @@
19using namespace std; 19using namespace std;
20namespace po = boost::program_options; 20namespace po = boost::program_options;
21 21
22/** TODO */
23void myterminate()
24{
25 cerr << "Unexpected termination" << endl;
26 abort();
27}
28
29/** 22/**
30 * @func main 23 * @func main
31 * @brief program entry point 24 * @brief program entry point
@@ -40,7 +33,6 @@ void myterminate()
40 */ 33 */
41int main(int argc, char* argv[]) 34int main(int argc, char* argv[])
42{ 35{
43 //TODO set_terminate(myterminate);
44 string me(argv[0]); 36 string me(argv[0]);
45 37
46 /* define commandline options */ 38 /* define commandline options */
@@ -136,13 +128,17 @@ int main(int argc, char* argv[])
136 cpu.setProgram(&program); 128 cpu.setProgram(&program);
137 cpu.run(); 129 cpu.run();
138#if DEBUG 130#if DEBUG
139 cpu.dumpRegisters(cout); 131 //cpu.dumpRegisters(cout);
140#endif 132#endif
141 } 133 }
142 catch(runtime_error& ex) 134 catch(runtime_error& ex)
143 { 135 {
144 cerr << me << ": Error while executing program:" << endl 136 cerr << me << ": Error while executing program:" << endl
145 << " " << ex.what() << endl; 137 << " " << ex.what() << endl;
138#if DEBUG
139 memory.dump(cout);
140 //cpu.dumpRegisters(cout);
141#endif
146 return 1; 142 return 1;
147 } 143 }
148 144
diff --git a/ue3/mycpu/test/memory1 b/ue3/mycpu/test/memory1
new file mode 100644
index 0000000..209e3ef
--- /dev/null
+++ b/ue3/mycpu/test/memory1
@@ -0,0 +1 @@
20
diff --git a/ue3/mycpu/test/program1 b/ue3/mycpu/test/program1
new file mode 100644
index 0000000..ae5e9d2
--- /dev/null
+++ b/ue3/mycpu/test/program1
@@ -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: