summaryrefslogtreecommitdiffstats
path: root/ue4/mycpu/instructions.h
diff options
context:
space:
mode:
Diffstat (limited to 'ue4/mycpu/instructions.h')
-rw-r--r--ue4/mycpu/instructions.h483
1 files changed, 440 insertions, 43 deletions
diff --git a/ue4/mycpu/instructions.h b/ue4/mycpu/instructions.h
index 4c36562..fcff3e7 100644
--- a/ue4/mycpu/instructions.h
+++ b/ue4/mycpu/instructions.h
@@ -2,7 +2,7 @@
2 * @module instructions 2 * @module instructions
3 * @author Guenther Neuwirth (0626638), Manuel Mausz (0728348) 3 * @author Guenther Neuwirth (0626638), Manuel Mausz (0728348)
4 * @brief Implementations of CInstruction 4 * @brief Implementations of CInstruction
5 * @date 10.05.2009 5 * @date 26.05.2009
6 */ 6 */
7 7
8#ifndef INSTRUCTIONS_H 8#ifndef INSTRUCTIONS_H
@@ -10,6 +10,7 @@
10 10
11#include "cinstruction.h" 11#include "cinstruction.h"
12#include "ccpu.h" 12#include "ccpu.h"
13#include "cprogram.h"
13 14
14/** 15/**
15 * @class CInstructionInc 16 * @class CInstructionInc
@@ -18,12 +19,15 @@
18 * Syntax: inc R1 19 * Syntax: inc R1
19 * (R1++) 20 * (R1++)
20 */ 21 */
22template <class T>
21class CInstructionInc 23class CInstructionInc
22 : public CInstruction 24 : public CInstruction<T>
23{ 25{
26 typedef CInstruction<T> super;
27
24 public: 28 public:
25 CInstructionInc() 29 CInstructionInc()
26 : CInstruction("inc") 30 : CInstruction<T>("inc")
27 {} 31 {}
28 32
29 CInstructionInc *factory() 33 CInstructionInc *factory()
@@ -32,13 +36,35 @@ class CInstructionInc
32 } 36 }
33 37
34 void compile(std::list<std::string>& params); 38 void compile(std::list<std::string>& params);
35 void execute(CCPU *cpu); 39 void execute(CCPU<T> *cpu);
36 40
37 protected: 41 protected:
38 /** register number */ 42 /** register number */
39 unsigned m_regidx1; 43 unsigned m_regidx1;
40}; 44};
41 45
46/*----------------------------------------------------------------------------*/
47
48template <class T>
49void CInstructionInc<T>::compile(std::list<std::string>& params)
50{
51 if (params.size() != 1)
52 throw std::runtime_error("Invalid paramater count - must be 1");
53 m_regidx1 = super::parseRegister(params.front());
54 params.pop_front();
55}
56
57/*----------------------------------------------------------------------------*/
58
59template <class T>
60void CInstructionInc<T>::execute(CCPU<T> *cpu)
61{
62 assert(cpu != NULL);
63 assert(cpu->getRegisters() != NULL);
64 super::checkRegister(cpu, m_regidx1);
65 cpu->getRegisters()[ m_regidx1 ]++;
66}
67
42/*============================================================================*/ 68/*============================================================================*/
43 69
44/** 70/**
@@ -48,12 +74,15 @@ class CInstructionInc
48 * Syntax: dec R1 74 * Syntax: dec R1
49 * (R1--) 75 * (R1--)
50 */ 76 */
77template <class T>
51class CInstructionDec 78class CInstructionDec
52 : public CInstruction 79 : public CInstruction<T>
53{ 80{
81 typedef CInstruction<T> super;
82
54 public: 83 public:
55 CInstructionDec() 84 CInstructionDec()
56 : CInstruction("dec") 85 : CInstruction<T>("dec")
57 {} 86 {}
58 87
59 CInstructionDec *factory() 88 CInstructionDec *factory()
@@ -62,13 +91,35 @@ class CInstructionDec
62 } 91 }
63 92
64 void compile(std::list<std::string>& params); 93 void compile(std::list<std::string>& params);
65 void execute(CCPU *cpu); 94 void execute(CCPU<T> *cpu);
66 95
67 protected: 96 protected:
68 /** register number */ 97 /** register number */
69 unsigned m_regidx1; 98 unsigned m_regidx1;
70}; 99};
71 100
101/*----------------------------------------------------------------------------*/
102
103template <class T>
104void CInstructionDec<T>::compile(std::list<std::string>& params)
105{
106 if (params.size() != 1)
107 throw std::runtime_error("Invalid paramater count - must be 1");
108 m_regidx1 = super::parseRegister(params.front());
109 params.pop_front();
110}
111
112/*----------------------------------------------------------------------------*/
113
114template <class T>
115void CInstructionDec<T>::execute(CCPU<T> *cpu)
116{
117 assert(cpu != NULL);
118 assert(cpu->getRegisters() != NULL);
119 super::checkRegister(cpu, m_regidx1);
120 cpu->getRegisters()[ m_regidx1 ]--;
121}
122
72/*============================================================================*/ 123/*============================================================================*/
73 124
74/** 125/**
@@ -78,12 +129,15 @@ class CInstructionDec
78 * Syntax: add R1, R2, R3 129 * Syntax: add R1, R2, R3
79 * (R1 = R2 + R3) 130 * (R1 = R2 + R3)
80 */ 131 */
132template <class T>
81class CInstructionAdd 133class CInstructionAdd
82 : public CInstruction 134 : public CInstruction<T>
83{ 135{
136 typedef CInstruction<T> super;
137
84 public: 138 public:
85 CInstructionAdd() 139 CInstructionAdd()
86 : CInstruction("add") 140 : CInstruction<T>("add")
87 {} 141 {}
88 142
89 CInstructionAdd *factory() 143 CInstructionAdd *factory()
@@ -92,7 +146,7 @@ class CInstructionAdd
92 } 146 }
93 147
94 void compile(std::list<std::string>& params); 148 void compile(std::list<std::string>& params);
95 void execute(CCPU *cpu); 149 void execute(CCPU<T> *cpu);
96 150
97 protected: 151 protected:
98 /** register number */ 152 /** register number */
@@ -103,6 +157,35 @@ class CInstructionAdd
103 unsigned m_regidx3; 157 unsigned m_regidx3;
104}; 158};
105 159
160/*----------------------------------------------------------------------------*/
161
162template <class T>
163void CInstructionAdd<T>::compile(std::list<std::string>& params)
164{
165 if (params.size() != 3)
166 throw std::runtime_error("Invalid paramater count - must be 3");
167 m_regidx1 = super::parseRegister(params.front());
168 params.pop_front();
169 m_regidx2 = super::parseRegister(params.front());
170 params.pop_front();
171 m_regidx3 = super::parseRegister(params.front());
172 params.pop_front();
173}
174
175/*----------------------------------------------------------------------------*/
176
177template <class T>
178void CInstructionAdd<T>::execute(CCPU<T> *cpu)
179{
180 assert(cpu != NULL);
181 assert(cpu->getRegisters() != NULL);
182 super::checkRegister(cpu, m_regidx1);
183 super::checkRegister(cpu, m_regidx2);
184 super::checkRegister(cpu, m_regidx3);
185 cpu->getRegisters()[ m_regidx1 ] = cpu->getRegisters()[ m_regidx2 ]
186 + cpu->getRegisters()[ m_regidx3 ];
187}
188
106/*============================================================================*/ 189/*============================================================================*/
107 190
108/** 191/**
@@ -112,12 +195,15 @@ class CInstructionAdd
112 * Syntax: sub R1, R2, R3 195 * Syntax: sub R1, R2, R3
113 * (R1 = R2 - R3) 196 * (R1 = R2 - R3)
114 */ 197 */
198template <class T>
115class CInstructionSub 199class CInstructionSub
116 : public CInstruction 200 : public CInstruction<T>
117{ 201{
202 typedef CInstruction<T> super;
203
118 public: 204 public:
119 CInstructionSub() 205 CInstructionSub()
120 : CInstruction("sub") 206 : CInstruction<T>("sub")
121 {} 207 {}
122 208
123 CInstructionSub *factory() 209 CInstructionSub *factory()
@@ -126,7 +212,7 @@ class CInstructionSub
126 } 212 }
127 213
128 void compile(std::list<std::string>& params); 214 void compile(std::list<std::string>& params);
129 void execute(CCPU *cpu); 215 void execute(CCPU<T> *cpu);
130 216
131 protected: 217 protected:
132 /** register number */ 218 /** register number */
@@ -137,6 +223,35 @@ class CInstructionSub
137 unsigned m_regidx3; 223 unsigned m_regidx3;
138}; 224};
139 225
226/*----------------------------------------------------------------------------*/
227
228template <class T>
229void CInstructionSub<T>::compile(std::list<std::string>& params)
230{
231 if (params.size() != 3)
232 throw std::runtime_error("Invalid paramater count - must be 3");
233 m_regidx1 = super::parseRegister(params.front());
234 params.pop_front();
235 m_regidx2 = super::parseRegister(params.front());
236 params.pop_front();
237 m_regidx3 = super::parseRegister(params.front());
238 params.pop_front();
239}
240
241/*----------------------------------------------------------------------------*/
242
243template <class T>
244void CInstructionSub<T>::execute(CCPU<T> *cpu)
245{
246 assert(cpu != NULL);
247 assert(cpu->getRegisters() != NULL);
248 super::checkRegister(cpu, m_regidx1);
249 super::checkRegister(cpu, m_regidx2);
250 super::checkRegister(cpu, m_regidx3);
251 cpu->getRegisters()[ m_regidx1 ] = cpu->getRegisters()[ m_regidx2 ]
252 - cpu->getRegisters()[ m_regidx3 ];
253}
254
140/*============================================================================*/ 255/*============================================================================*/
141 256
142/** 257/**
@@ -146,12 +261,15 @@ class CInstructionSub
146 * Syntax: mul R1, R2, R3 261 * Syntax: mul R1, R2, R3
147 * (R1 = R2 * R3) 262 * (R1 = R2 * R3)
148 */ 263 */
264template <class T>
149class CInstructionMul 265class CInstructionMul
150 : public CInstruction 266 : public CInstruction<T>
151{ 267{
268 typedef CInstruction<T> super;
269
152 public: 270 public:
153 CInstructionMul() 271 CInstructionMul()
154 : CInstruction("mul") 272 : CInstruction<T>("mul")
155 {} 273 {}
156 274
157 CInstructionMul *factory() 275 CInstructionMul *factory()
@@ -160,7 +278,7 @@ class CInstructionMul
160 } 278 }
161 279
162 void compile(std::list<std::string>& params); 280 void compile(std::list<std::string>& params);
163 void execute(CCPU *cpu); 281 void execute(CCPU<T> *cpu);
164 282
165 protected: 283 protected:
166 /** register number */ 284 /** register number */
@@ -171,6 +289,33 @@ class CInstructionMul
171 unsigned m_regidx3; 289 unsigned m_regidx3;
172}; 290};
173 291
292/*----------------------------------------------------------------------------*/
293
294template <class T>
295void CInstructionMul<T>::compile(std::list<std::string>& params)
296{
297 if (params.size() != 3)
298 throw std::runtime_error("Invalid paramater count - must be 3");
299 m_regidx1 = super::parseRegister(params.front());
300 params.pop_front();
301 m_regidx2 = super::parseRegister(params.front());
302 params.pop_front();
303 m_regidx3 = super::parseRegister(params.front());
304 params.pop_front();
305}
306
307/*----------------------------------------------------------------------------*/
308
309template <class T>
310void CInstructionMul<T>::execute(CCPU<T> *cpu)
311{
312 super::checkRegister(cpu, m_regidx1);
313 super::checkRegister(cpu, m_regidx2);
314 super::checkRegister(cpu, m_regidx3);
315 cpu->getRegisters()[ m_regidx1 ] = cpu->getRegisters()[ m_regidx2 ]
316 * cpu->getRegisters()[ m_regidx3 ];
317}
318
174/*============================================================================*/ 319/*============================================================================*/
175 320
176/** 321/**
@@ -180,12 +325,15 @@ class CInstructionMul
180 * Syntax: div R1, R2, R3 325 * Syntax: div R1, R2, R3
181 * (R1 = R2 / R3) 326 * (R1 = R2 / R3)
182 */ 327 */
328template <class T>
183class CInstructionDiv 329class CInstructionDiv
184 : public CInstruction 330 : public CInstruction<T>
185{ 331{
332 typedef CInstruction<T> super;
333
186 public: 334 public:
187 CInstructionDiv() 335 CInstructionDiv()
188 : CInstruction("div") 336 : CInstruction<T>("div")
189 {} 337 {}
190 338
191 CInstructionDiv *factory() 339 CInstructionDiv *factory()
@@ -194,7 +342,7 @@ class CInstructionDiv
194 } 342 }
195 343
196 void compile(std::list<std::string>& params); 344 void compile(std::list<std::string>& params);
197 void execute(CCPU *cpu); 345 void execute(CCPU<T> *cpu);
198 346
199 protected: 347 protected:
200 /** register number */ 348 /** register number */
@@ -205,6 +353,35 @@ class CInstructionDiv
205 unsigned m_regidx3; 353 unsigned m_regidx3;
206}; 354};
207 355
356/*----------------------------------------------------------------------------*/
357
358template <class T>
359void CInstructionDiv<T>::compile(std::list<std::string>& params)
360{
361 if (params.size() != 3)
362 throw std::runtime_error("Invalid paramater count - must be 3");
363 m_regidx1 = super::parseRegister(params.front());
364 params.pop_front();
365 m_regidx2 = super::parseRegister(params.front());
366 params.pop_front();
367 m_regidx3 = super::parseRegister(params.front());
368 params.pop_front();
369}
370
371/*----------------------------------------------------------------------------*/
372
373template <class T>
374void CInstructionDiv<T>::execute(CCPU<T> *cpu)
375{
376 assert(cpu != NULL);
377 assert(cpu->getRegisters() != NULL);
378 super::checkRegister(cpu, m_regidx1);
379 super::checkRegister(cpu, m_regidx2);
380 super::checkRegister(cpu, m_regidx3);
381 cpu->getRegisters()[ m_regidx1 ] = cpu->getRegisters()[ m_regidx2 ]
382 / cpu->getRegisters()[ m_regidx3 ];
383}
384
208/*============================================================================*/ 385/*============================================================================*/
209 386
210/** 387/**
@@ -214,12 +391,15 @@ class CInstructionDiv
214 * Syntax: load R1, R2 391 * Syntax: load R1, R2
215 * (R1 = memory[R2]) 392 * (R1 = memory[R2])
216 */ 393 */
394template <class T>
217class CInstructionLoad 395class CInstructionLoad
218 : public CInstruction 396 : public CInstruction<T>
219{ 397{
398 typedef CInstruction<T> super;
399
220 public: 400 public:
221 CInstructionLoad() 401 CInstructionLoad()
222 : CInstruction("load") 402 : CInstruction<T>("load")
223 {} 403 {}
224 404
225 CInstructionLoad *factory() 405 CInstructionLoad *factory()
@@ -228,7 +408,7 @@ class CInstructionLoad
228 } 408 }
229 409
230 void compile(std::list<std::string>& params); 410 void compile(std::list<std::string>& params);
231 void execute(CCPU *cpu); 411 void execute(CCPU<T> *cpu);
232 412
233 protected: 413 protected:
234 /** register number */ 414 /** register number */
@@ -237,6 +417,33 @@ class CInstructionLoad
237 unsigned m_regidx2; 417 unsigned m_regidx2;
238}; 418};
239 419
420/*----------------------------------------------------------------------------*/
421
422template <class T>
423void CInstructionLoad<T>::compile(std::list<std::string>& params)
424{
425 if (params.size() != 2)
426 throw std::runtime_error("Invalid paramater count - must be 2");
427 m_regidx1 = super::parseRegister(params.front());
428 params.pop_front();
429 m_regidx2 = super::parseRegister(params.front());
430 params.pop_front();
431}
432
433/*----------------------------------------------------------------------------*/
434
435template <class T>
436void CInstructionLoad<T>::execute(CCPU<T> *cpu)
437{
438 assert(cpu != NULL);
439 assert(cpu->getRegisters() != NULL);
440 assert(cpu->getMemory() != NULL);
441 super::checkRegister(cpu, m_regidx1);
442 super::checkRegister(cpu, m_regidx2);
443 T val(cpu->getRegisters()[ m_regidx2 ]);
444 cpu->getRegisters()[ m_regidx1 ] = (*cpu->getMemory())[ val ];
445}
446
240/*============================================================================*/ 447/*============================================================================*/
241 448
242/** 449/**
@@ -246,12 +453,15 @@ class CInstructionLoad
246 * Syntax: store R1, R2 453 * Syntax: store R1, R2
247 * (memory[R2] = R1) 454 * (memory[R2] = R1)
248 */ 455 */
456template <class T>
249class CInstructionStore 457class CInstructionStore
250 : public CInstruction 458 : public CInstruction<T>
251{ 459{
460 typedef CInstruction<T> super;
461
252 public: 462 public:
253 CInstructionStore() 463 CInstructionStore()
254 : CInstruction("store") 464 : CInstruction<T>("store")
255 {} 465 {}
256 466
257 CInstructionStore *factory() 467 CInstructionStore *factory()
@@ -260,7 +470,7 @@ class CInstructionStore
260 } 470 }
261 471
262 void compile(std::list<std::string>& params); 472 void compile(std::list<std::string>& params);
263 void execute(CCPU *cpu); 473 void execute(CCPU<T> *cpu);
264 474
265 protected: 475 protected:
266 /** register number */ 476 /** register number */
@@ -269,6 +479,33 @@ class CInstructionStore
269 unsigned m_regidx2; 479 unsigned m_regidx2;
270}; 480};
271 481
482/*----------------------------------------------------------------------------*/
483
484template <class T>
485void CInstructionStore<T>::compile(std::list<std::string>& params)
486{
487 if (params.size() != 2)
488 throw std::runtime_error("Invalid paramater count - must be 2");
489 m_regidx1 = super::parseRegister(params.front());
490 params.pop_front();
491 m_regidx2 = super::parseRegister(params.front());
492 params.pop_front();
493}
494
495/*----------------------------------------------------------------------------*/
496
497template <class T>
498void CInstructionStore<T>::execute(CCPU<T> *cpu)
499{
500 assert(cpu != NULL);
501 assert(cpu->getRegisters() != NULL);
502 assert(cpu->getMemory() != NULL);
503 super::checkRegister(cpu, m_regidx1);
504 super::checkRegister(cpu, m_regidx2);
505 T val(cpu->getRegisters()[ m_regidx2 ]);
506 (*cpu->getMemory())[ val ] = cpu->getRegisters()[ m_regidx1 ];
507}
508
272/*============================================================================*/ 509/*============================================================================*/
273 510
274/** 511/**
@@ -278,12 +515,15 @@ class CInstructionStore
278 * Syntax: test R1 515 * Syntax: test R1
279 * (R1 == 0: zeroflag: true, R1 < 0: signflag: true) 516 * (R1 == 0: zeroflag: true, R1 < 0: signflag: true)
280 */ 517 */
518template <class T>
281class CInstructionTest 519class CInstructionTest
282 : public CInstruction 520 : public CInstruction<T>
283{ 521{
522 typedef CInstruction<T> super;
523
284 public: 524 public:
285 CInstructionTest() 525 CInstructionTest()
286 : CInstruction("test") 526 : CInstruction<T>("test")
287 {} 527 {}
288 528
289 CInstructionTest *factory() 529 CInstructionTest *factory()
@@ -292,13 +532,38 @@ class CInstructionTest
292 } 532 }
293 533
294 void compile(std::list<std::string>& params); 534 void compile(std::list<std::string>& params);
295 void execute(CCPU *cpu); 535 void execute(CCPU<T> *cpu);
296 536
297 protected: 537 protected:
298 /** register number */ 538 /** register number */
299 unsigned m_regidx1; 539 unsigned m_regidx1;
300}; 540};
301 541
542/*----------------------------------------------------------------------------*/
543
544template <class T>
545void CInstructionTest<T>::compile(std::list<std::string>& params)
546{
547 if (params.size() != 1)
548 throw std::runtime_error("Invalid paramater count - must be 1");
549 m_regidx1 = super::parseRegister(params.front());
550 params.pop_front();
551}
552
553/*----------------------------------------------------------------------------*/
554
555template <class T>
556void CInstructionTest<T>::execute(CCPU<T> *cpu)
557{
558 assert(cpu != NULL);
559 assert(cpu->getRegisters() != NULL);
560 super::checkRegister(cpu, m_regidx1);
561 if (cpu->getRegisters()[ m_regidx1 ] == T(0))
562 cpu->setFlagZero(true);
563 if (cpu->getRegisters()[ m_regidx1 ] < T(0))
564 cpu->setFlagSign(true);
565}
566
302/*============================================================================*/ 567/*============================================================================*/
303 568
304/** 569/**
@@ -307,12 +572,15 @@ class CInstructionTest
307 * Implementation of assembler command "label" 572 * Implementation of assembler command "label"
308 * Syntax: label name: 573 * Syntax: label name:
309 */ 574 */
575template <class T>
310class CInstructionLabel 576class CInstructionLabel
311 : public CInstruction 577 : public CInstruction<T>
312{ 578{
579 typedef CInstruction<T> super;
580
313 public: 581 public:
314 CInstructionLabel() 582 CInstructionLabel()
315 : CInstruction("label") 583 : CInstruction<T>("label")
316 {} 584 {}
317 585
318 CInstructionLabel *factory() 586 CInstructionLabel *factory()
@@ -323,7 +591,7 @@ class CInstructionLabel
323 void compile(std::list<std::string>& params) 591 void compile(std::list<std::string>& params)
324 {} 592 {}
325 593
326 void execute(CCPU *cpu) 594 void execute(CCPU<T> *cpu)
327 {} 595 {}
328}; 596};
329 597
@@ -336,12 +604,15 @@ class CInstructionLabel
336 * Syntax: jumpa labelname 604 * Syntax: jumpa labelname
337 * (jump to labelname) 605 * (jump to labelname)
338 */ 606 */
607template <class T>
339class CInstructionJumpA 608class CInstructionJumpA
340 : public CInstruction 609 : public CInstruction<T>
341{ 610{
611 typedef CInstruction<T> super;
612
342 public: 613 public:
343 CInstructionJumpA() 614 CInstructionJumpA()
344 : CInstruction("jumpa"), m_addr("") 615 : CInstruction<T>("jumpa"), m_addr("")
345 {} 616 {}
346 617
347 CInstructionJumpA *factory() 618 CInstructionJumpA *factory()
@@ -350,13 +621,37 @@ class CInstructionJumpA
350 } 621 }
351 622
352 void compile(std::list<std::string>& params); 623 void compile(std::list<std::string>& params);
353 void execute(CCPU *cpu); 624 void execute(CCPU<T> *cpu);
354 625
355 protected: 626 protected:
356 /** labelname */ 627 /** labelname */
357 std::string m_addr; 628 std::string m_addr;
358}; 629};
359 630
631/*----------------------------------------------------------------------------*/
632
633template <class T>
634void CInstructionJumpA<T>::compile(std::list<std::string>& params)
635{
636 if (params.size() != 1)
637 throw std::runtime_error("Invalid paramater count - must be 1");
638 m_addr = params.front();
639 params.pop_front();
640}
641
642/*----------------------------------------------------------------------------*/
643
644template <class T>
645void CInstructionJumpA<T>::execute(CCPU<T> *cpu)
646{
647 assert(cpu != NULL);
648 assert(cpu->getRegisters() != NULL);
649 assert(cpu->getProgram() != NULL);
650 if (m_addr.empty())
651 throw std::runtime_error("Empty address");
652 cpu->getRegisters()[ 0 ] = cpu->getProgram()->findLabel(m_addr);
653}
654
360/*============================================================================*/ 655/*============================================================================*/
361 656
362/** 657/**
@@ -366,12 +661,15 @@ class CInstructionJumpA
366 * Syntax: jumpz labelname 661 * Syntax: jumpz labelname
367 * (jump to labelname if zeroflag) 662 * (jump to labelname if zeroflag)
368 */ 663 */
664template <class T>
369class CInstructionJumpZ 665class CInstructionJumpZ
370 : public CInstruction 666 : public CInstruction<T>
371{ 667{
668 typedef CInstruction<T> super;
669
372 public: 670 public:
373 CInstructionJumpZ() 671 CInstructionJumpZ()
374 : CInstruction("jumpz"), m_addr("") 672 : CInstruction<T>("jumpz"), m_addr("")
375 {} 673 {}
376 674
377 CInstructionJumpZ *factory() 675 CInstructionJumpZ *factory()
@@ -380,13 +678,39 @@ class CInstructionJumpZ
380 } 678 }
381 679
382 void compile(std::list<std::string>& params); 680 void compile(std::list<std::string>& params);
383 void execute(CCPU *cpu); 681 void execute(CCPU<T> *cpu);
384 682
385 protected: 683 protected:
386 /** labelname */ 684 /** labelname */
387 std::string m_addr; 685 std::string m_addr;
388}; 686};
389 687
688/*----------------------------------------------------------------------------*/
689
690template <class T>
691void CInstructionJumpZ<T>::compile(std::list<std::string>& params)
692{
693 if (params.size() != 1)
694 throw std::runtime_error("Invalid paramater count - must be 1");
695 m_addr = params.front();
696 params.pop_front();
697}
698
699/*----------------------------------------------------------------------------*/
700
701template <class T>
702void CInstructionJumpZ<T>::execute(CCPU<T> *cpu)
703{
704 assert(cpu != NULL);
705 assert(cpu->getRegisters() != NULL);
706 assert(cpu->getProgram() != NULL);
707 if (!cpu->getFlagZero())
708 return;
709 if (m_addr.empty())
710 throw std::runtime_error("Empty address");
711 cpu->getRegisters()[ 0 ] = cpu->getProgram()->findLabel(m_addr);
712}
713
390/*============================================================================*/ 714/*============================================================================*/
391 715
392/** 716/**
@@ -396,12 +720,15 @@ class CInstructionJumpZ
396 * Syntax: jumps labelname 720 * Syntax: jumps labelname
397 * (jump to labelname if signflag) 721 * (jump to labelname if signflag)
398 */ 722 */
723template <class T>
399class CInstructionJumpS 724class CInstructionJumpS
400 : public CInstruction 725 : public CInstruction<T>
401{ 726{
727 typedef CInstruction<T> super;
728
402 public: 729 public:
403 CInstructionJumpS() 730 CInstructionJumpS()
404 : CInstruction("jumps"), m_addr("") 731 : CInstruction<T>("jumps"), m_addr("")
405 {} 732 {}
406 733
407 CInstructionJumpS *factory() 734 CInstructionJumpS *factory()
@@ -410,13 +737,39 @@ class CInstructionJumpS
410 } 737 }
411 738
412 void compile(std::list<std::string>& params); 739 void compile(std::list<std::string>& params);
413 void execute(CCPU *cpu); 740 void execute(CCPU<T> *cpu);
414 741
415 protected: 742 protected:
416 /** labelname */ 743 /** labelname */
417 std::string m_addr; 744 std::string m_addr;
418}; 745};
419 746
747/*----------------------------------------------------------------------------*/
748
749template <class T>
750void CInstructionJumpS<T>::compile(std::list<std::string>& params)
751{
752 if (params.size() != 1)
753 throw std::runtime_error("Invalid paramater count - must be 1");
754 m_addr = params.front();
755 params.pop_front();
756}
757
758/*----------------------------------------------------------------------------*/
759
760template <class T>
761void CInstructionJumpS<T>::execute(CCPU<T> *cpu)
762{
763 assert(cpu != NULL);
764 assert(cpu->getRegisters() != NULL);
765 assert(cpu->getProgram() != NULL);
766 if (!cpu->getFlagSign())
767 return;
768 if (m_addr.empty())
769 throw std::runtime_error("Empty address");
770 cpu->getRegisters()[ 0 ] = cpu->getProgram()->findLabel(m_addr);
771}
772
420/*============================================================================*/ 773/*============================================================================*/
421 774
422/** 775/**
@@ -426,12 +779,16 @@ class CInstructionJumpS
426 * Syntax: write DEV, R1 779 * Syntax: write DEV, R1
427 * (write R1 to DEV, which is a name of a display) 780 * (write R1 to DEV, which is a name of a display)
428 */ 781 */
782template <class T>
429class CInstructionWrite 783class CInstructionWrite
430 : public CInstruction 784 : public CInstruction<T>
431{ 785{
786 typedef CInstruction<T> super;
787 typedef typename std::set<CDisplay<T> *>::iterator setiterator;
788
432 public: 789 public:
433 CInstructionWrite() 790 CInstructionWrite()
434 : CInstruction("write"), m_dev("") 791 : CInstruction<T>("write"), m_dev("")
435 {} 792 {}
436 793
437 CInstructionWrite *factory() 794 CInstructionWrite *factory()
@@ -440,7 +797,7 @@ class CInstructionWrite
440 } 797 }
441 798
442 void compile(std::list<std::string>& params); 799 void compile(std::list<std::string>& params);
443 void execute(CCPU *cpu); 800 void execute(CCPU<T> *cpu);
444 801
445 protected: 802 protected:
446 /** register number */ 803 /** register number */
@@ -449,6 +806,46 @@ class CInstructionWrite
449 std::string m_dev; 806 std::string m_dev;
450}; 807};
451 808
809/*----------------------------------------------------------------------------*/
810
811template <class T>
812void CInstructionWrite<T>::compile(std::list<std::string>& params)
813{
814 if (params.size() != 2)
815 throw std::runtime_error("Invalid paramater count - must be 2");
816 m_dev = params.front();
817 params.pop_front();
818 m_regidx1 = super::parseRegister(params.front());
819 params.pop_front();
820}
821
822/*----------------------------------------------------------------------------*/
823
824template <class T>
825void CInstructionWrite<T>::execute(CCPU<T> *cpu)
826{
827 assert(cpu != NULL);
828 assert(cpu->getRegisters() != NULL);
829 super::checkRegister(cpu, m_regidx1);
830 if (m_dev.empty())
831 throw std::runtime_error("Empty device");
832
833 CDisplay<T> *display = NULL;
834 std::set<CDisplay<T> *> displays = cpu->getDisplays();
835 for(setiterator it = displays.begin(); it != displays.end(); ++it)
836 {
837 if ((*it)->getName() == m_dev)
838 {
839 display = *it;
840 break;
841 }
842 }
843 if (display == NULL)
844 throw std::runtime_error("Unknown display");
845
846 display->display(cpu->getRegisters()[ m_regidx1 ]);
847}
848
452#endif 849#endif
453 850
454/* vim: set et sw=2 ts=2: */ 851/* vim: set et sw=2 ts=2: */