summaryrefslogtreecommitdiffstats
path: root/ue3/mycpu/instructions.cpp
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/mycpu/instructions.cpp
parent45581d3d376e8deed84952cb838ae330549e5241 (diff)
downloadooprog-89e202f49b9857dcd3627fbc4e0262125d729bbc.tar.gz
ooprog-89e202f49b9857dcd3627fbc4e0262125d729bbc.tar.bz2
ooprog-89e202f49b9857dcd3627fbc4e0262125d729bbc.zip
adding all instructions and displays
Diffstat (limited to 'ue3/mycpu/instructions.cpp')
-rw-r--r--ue3/mycpu/instructions.cpp339
1 files changed, 338 insertions, 1 deletions
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: */