Download | Plain Text | No Line Numbers


  1. /**
  2.  * @module instructions
  3.  * @author Guenther Neuwirth (0626638), Manuel Mausz (0728348)
  4.  * @brief Implementations of CInstruction
  5.  * @date 10.05.2009
  6.  */
  7.  
  8. #include <map>
  9. #include <assert.h>
  10. #include "instructions.h"
  11.  
  12. using namespace std;
  13.  
  14. void CInstructionInc::compile(std::list<std::string>& params)
  15. {
  16. if (params.size() != 1)
  17. throw runtime_error("Invalid paramater count - must be 1");
  18. m_regidx1 = parseRegister(params.front());
  19. params.pop_front();
  20. }
  21.  
  22. /*----------------------------------------------------------------------------*/
  23.  
  24. void CInstructionInc::execute(CCPU *cpu)
  25. {
  26. assert(cpu != NULL);
  27. assert(cpu->getRegisters() != NULL);
  28. checkRegister(cpu, m_regidx1);
  29. cpu->getRegisters()[ m_regidx1 ]++;
  30. }
  31.  
  32. /*============================================================================*/
  33.  
  34. void CInstructionDec::compile(std::list<std::string>& params)
  35. {
  36. if (params.size() != 1)
  37. throw runtime_error("Invalid paramater count - must be 1");
  38. m_regidx1 = parseRegister(params.front());
  39. params.pop_front();
  40. }
  41.  
  42. /*----------------------------------------------------------------------------*/
  43.  
  44. void CInstructionDec::execute(CCPU *cpu)
  45. {
  46. assert(cpu != NULL);
  47. assert(cpu->getRegisters() != NULL);
  48. checkRegister(cpu, m_regidx1);
  49. cpu->getRegisters()[ m_regidx1 ]--;
  50. }
  51.  
  52. /*============================================================================*/
  53.  
  54. void CInstructionAdd::compile(std::list<std::string>& params)
  55. {
  56. if (params.size() != 3)
  57. throw runtime_error("Invalid paramater count - must be 3");
  58. m_regidx1 = parseRegister(params.front());
  59. params.pop_front();
  60. m_regidx2 = parseRegister(params.front());
  61. params.pop_front();
  62. m_regidx3 = parseRegister(params.front());
  63. params.pop_front();
  64. }
  65.  
  66. /*----------------------------------------------------------------------------*/
  67.  
  68. void CInstructionAdd::execute(CCPU *cpu)
  69. {
  70. assert(cpu != NULL);
  71. assert(cpu->getRegisters() != NULL);
  72. checkRegister(cpu, m_regidx1);
  73. checkRegister(cpu, m_regidx2);
  74. checkRegister(cpu, m_regidx3);
  75. cpu->getRegisters()[ m_regidx1 ] = cpu->getRegisters()[ m_regidx2 ]
  76. + cpu->getRegisters()[ m_regidx3 ];
  77. }
  78.  
  79. /*============================================================================*/
  80.  
  81. void CInstructionSub::compile(std::list<std::string>& params)
  82. {
  83. if (params.size() != 3)
  84. throw runtime_error("Invalid paramater count - must be 3");
  85. m_regidx1 = parseRegister(params.front());
  86. params.pop_front();
  87. m_regidx2 = parseRegister(params.front());
  88. params.pop_front();
  89. m_regidx3 = parseRegister(params.front());
  90. params.pop_front();
  91. }
  92.  
  93. /*----------------------------------------------------------------------------*/
  94.  
  95. void CInstructionSub::execute(CCPU *cpu)
  96. {
  97. assert(cpu != NULL);
  98. assert(cpu->getRegisters() != NULL);
  99. checkRegister(cpu, m_regidx1);
  100. checkRegister(cpu, m_regidx2);
  101. checkRegister(cpu, m_regidx3);
  102. cpu->getRegisters()[ m_regidx1 ] = cpu->getRegisters()[ m_regidx2 ]
  103. - cpu->getRegisters()[ m_regidx3 ];
  104. }
  105.  
  106. /*============================================================================*/
  107.  
  108. void CInstructionMul::compile(std::list<std::string>& params)
  109. {
  110. if (params.size() != 3)
  111. throw runtime_error("Invalid paramater count - must be 3");
  112. m_regidx1 = parseRegister(params.front());
  113. params.pop_front();
  114. m_regidx2 = parseRegister(params.front());
  115. params.pop_front();
  116. m_regidx3 = parseRegister(params.front());
  117. params.pop_front();
  118. }
  119.  
  120. /*----------------------------------------------------------------------------*/
  121.  
  122. void CInstructionMul::execute(CCPU *cpu)
  123. {
  124. checkRegister(cpu, m_regidx1);
  125. checkRegister(cpu, m_regidx2);
  126. checkRegister(cpu, m_regidx3);
  127. cpu->getRegisters()[ m_regidx1 ] = cpu->getRegisters()[ m_regidx2 ]
  128. * cpu->getRegisters()[ m_regidx3 ];
  129. }
  130.  
  131. /*============================================================================*/
  132.  
  133. void CInstructionDiv::compile(std::list<std::string>& params)
  134. {
  135. if (params.size() != 3)
  136. throw runtime_error("Invalid paramater count - must be 3");
  137. m_regidx1 = parseRegister(params.front());
  138. params.pop_front();
  139. m_regidx2 = parseRegister(params.front());
  140. params.pop_front();
  141. m_regidx3 = parseRegister(params.front());
  142. params.pop_front();
  143. }
  144.  
  145. /*----------------------------------------------------------------------------*/
  146.  
  147. void CInstructionDiv::execute(CCPU *cpu)
  148. {
  149. assert(cpu != NULL);
  150. assert(cpu->getRegisters() != NULL);
  151. checkRegister(cpu, m_regidx1);
  152. checkRegister(cpu, m_regidx2);
  153. checkRegister(cpu, m_regidx3);
  154. cpu->getRegisters()[ m_regidx1 ] = cpu->getRegisters()[ m_regidx2 ]
  155. / cpu->getRegisters()[ m_regidx3 ];
  156. }
  157.  
  158. /*============================================================================*/
  159.  
  160. void CInstructionLoad::compile(std::list<std::string>& params)
  161. {
  162. if (params.size() != 2)
  163. throw runtime_error("Invalid paramater count - must be 2");
  164. m_regidx1 = parseRegister(params.front());
  165. params.pop_front();
  166. m_regidx2 = parseRegister(params.front());
  167. params.pop_front();
  168. }
  169.  
  170. /*----------------------------------------------------------------------------*/
  171.  
  172. void CInstructionLoad::execute(CCPU *cpu)
  173. {
  174. assert(cpu != NULL);
  175. assert(cpu->getRegisters() != NULL);
  176. assert(cpu->getMemory() != NULL);
  177. checkRegister(cpu, m_regidx1);
  178. checkRegister(cpu, m_regidx2);
  179. CDat val(cpu->getRegisters()[ m_regidx2 ]);
  180. cpu->getRegisters()[ m_regidx1 ] = (*cpu->getMemory())[ val ];
  181. }
  182.  
  183. /*============================================================================*/
  184.  
  185. void CInstructionStore::compile(std::list<std::string>& params)
  186. {
  187. if (params.size() != 2)
  188. throw runtime_error("Invalid paramater count - must be 2");
  189. m_regidx1 = parseRegister(params.front());
  190. params.pop_front();
  191. m_regidx2 = parseRegister(params.front());
  192. params.pop_front();
  193. }
  194.  
  195. /*----------------------------------------------------------------------------*/
  196.  
  197. void CInstructionStore::execute(CCPU *cpu)
  198. {
  199. assert(cpu != NULL);
  200. assert(cpu->getRegisters() != NULL);
  201. assert(cpu->getMemory() != NULL);
  202. checkRegister(cpu, m_regidx1);
  203. checkRegister(cpu, m_regidx2);
  204. CDat val(cpu->getRegisters()[ m_regidx2 ]);
  205. (*cpu->getMemory())[ val ] = cpu->getRegisters()[ m_regidx1 ];
  206. }
  207.  
  208. /*============================================================================*/
  209.  
  210. void CInstructionTest::compile(std::list<std::string>& params)
  211. {
  212. if (params.size() != 1)
  213. throw runtime_error("Invalid paramater count - must be 1");
  214. m_regidx1 = parseRegister(params.front());
  215. params.pop_front();
  216. }
  217.  
  218. /*----------------------------------------------------------------------------*/
  219.  
  220. void CInstructionTest::execute(CCPU *cpu)
  221. {
  222. assert(cpu != NULL);
  223. assert(cpu->getRegisters() != NULL);
  224. checkRegister(cpu, m_regidx1);
  225. if (cpu->getRegisters()[ m_regidx1 ] == CDat(0))
  226. cpu->setFlagZero(true);
  227. if (cpu->getRegisters()[ m_regidx1 ] < CDat(0))
  228. cpu->setFlagSign(true);
  229. }
  230.  
  231. /*============================================================================*/
  232.  
  233. void CInstructionJumpA::compile(std::list<std::string>& params)
  234. {
  235. if (params.size() != 1)
  236. throw runtime_error("Invalid paramater count - must be 1");
  237. m_addr = params.front();
  238. params.pop_front();
  239. }
  240.  
  241. /*----------------------------------------------------------------------------*/
  242.  
  243. void CInstructionJumpA::execute(CCPU *cpu)
  244. {
  245. assert(cpu != NULL);
  246. assert(cpu->getRegisters() != NULL);
  247. assert(cpu->getProgram() != NULL);
  248. if (m_addr.empty())
  249. throw runtime_error("Empty address");
  250. cpu->getRegisters()[ 0 ] = cpu->getProgram()->findLabel(m_addr);
  251. }
  252.  
  253. /*============================================================================*/
  254.  
  255. void CInstructionJumpZ::compile(std::list<std::string>& params)
  256. {
  257. if (params.size() != 1)
  258. throw runtime_error("Invalid paramater count - must be 1");
  259. m_addr = params.front();
  260. params.pop_front();
  261. }
  262.  
  263. /*----------------------------------------------------------------------------*/
  264.  
  265. void CInstructionJumpZ::execute(CCPU *cpu)
  266. {
  267. assert(cpu != NULL);
  268. assert(cpu->getRegisters() != NULL);
  269. assert(cpu->getProgram() != NULL);
  270. if (!cpu->getFlagZero())
  271. return;
  272. if (m_addr.empty())
  273. throw runtime_error("Empty address");
  274. cpu->getRegisters()[ 0 ] = cpu->getProgram()->findLabel(m_addr);
  275. }
  276.  
  277. /*============================================================================*/
  278.  
  279. void CInstructionJumpS::compile(std::list<std::string>& params)
  280. {
  281. if (params.size() != 1)
  282. throw runtime_error("Invalid paramater count - must be 1");
  283. m_addr = params.front();
  284. params.pop_front();
  285. }
  286.  
  287. /*----------------------------------------------------------------------------*/
  288.  
  289. void CInstructionJumpS::execute(CCPU *cpu)
  290. {
  291. assert(cpu != NULL);
  292. assert(cpu->getRegisters() != NULL);
  293. assert(cpu->getProgram() != NULL);
  294. if (!cpu->getFlagSign())
  295. return;
  296. if (m_addr.empty())
  297. throw runtime_error("Empty address");
  298. cpu->getRegisters()[ 0 ] = cpu->getProgram()->findLabel(m_addr);
  299. }
  300.  
  301. /*============================================================================*/
  302.  
  303. void CInstructionWrite::compile(std::list<std::string>& params)
  304. {
  305. if (params.size() != 2)
  306. throw runtime_error("Invalid paramater count - must be 2");
  307. m_dev = params.front();
  308. params.pop_front();
  309. m_regidx1 = parseRegister(params.front());
  310. params.pop_front();
  311. }
  312.  
  313. /*----------------------------------------------------------------------------*/
  314.  
  315. void CInstructionWrite::execute(CCPU *cpu)
  316. {
  317. assert(cpu != NULL);
  318. assert(cpu->getRegisters() != NULL);
  319. checkRegister(cpu, m_regidx1);
  320. if (m_dev.empty())
  321. throw runtime_error("Empty device");
  322.  
  323. CDisplay *display = NULL;
  324. std::set<CDisplay *> displays = cpu->getDisplays();
  325. std::set<CDisplay *>::iterator it;
  326. for(it = displays.begin(); it != displays.end(); ++it)
  327. {
  328. if ((*it)->getName() == m_dev)
  329. {
  330. display = *it;
  331. break;
  332. }
  333. }
  334. if (display == NULL)
  335. throw runtime_error("Unknown display");
  336.  
  337. display->display(cpu->getRegisters()[ m_regidx1 ]);
  338. }
  339.  
  340.  
  341. /* vim: set et sw=2 ts=2: */
  342.