/** * @module instructions * @author Guenther Neuwirth (0626638), Manuel Mausz (0728348) * @brief Implementations of CInstruction * @date 10.05.2009 */ #include #include #include "instructions.h" using namespace std; void CInstructionInc::compile(std::list& params) { if (params.size() != 1) throw runtime_error("Invalid paramater count - must be 1"); m_regidx1 = parseRegister(params.front()); params.pop_front(); } /*----------------------------------------------------------------------------*/ void CInstructionInc::execute(CCPU *cpu) { assert(cpu != NULL); assert(cpu->getRegisters() != NULL); checkRegister(cpu, m_regidx1); cpu->getRegisters()[ m_regidx1 ]++; } /*============================================================================*/ void CInstructionDec::compile(std::list& params) { if (params.size() != 1) throw runtime_error("Invalid paramater count - must be 1"); m_regidx1 = parseRegister(params.front()); params.pop_front(); } /*----------------------------------------------------------------------------*/ void CInstructionDec::execute(CCPU *cpu) { assert(cpu != NULL); assert(cpu->getRegisters() != NULL); checkRegister(cpu, m_regidx1); cpu->getRegisters()[ m_regidx1 ]--; } /*============================================================================*/ void CInstructionAdd::compile(std::list& params) { if (params.size() != 3) throw runtime_error("Invalid paramater count - must be 3"); m_regidx1 = parseRegister(params.front()); params.pop_front(); m_regidx2 = parseRegister(params.front()); params.pop_front(); m_regidx3 = parseRegister(params.front()); params.pop_front(); } /*----------------------------------------------------------------------------*/ void CInstructionAdd::execute(CCPU *cpu) { assert(cpu != NULL); assert(cpu->getRegisters() != NULL); checkRegister(cpu, m_regidx1); checkRegister(cpu, m_regidx2); checkRegister(cpu, m_regidx3); cpu->getRegisters()[ m_regidx1 ] = cpu->getRegisters()[ m_regidx2 ] + cpu->getRegisters()[ m_regidx3 ]; } /*============================================================================*/ void CInstructionSub::compile(std::list& params) { if (params.size() != 3) throw runtime_error("Invalid paramater count - must be 3"); m_regidx1 = parseRegister(params.front()); params.pop_front(); m_regidx2 = parseRegister(params.front()); params.pop_front(); m_regidx3 = parseRegister(params.front()); params.pop_front(); } /*----------------------------------------------------------------------------*/ void CInstructionSub::execute(CCPU *cpu) { assert(cpu != NULL); assert(cpu->getRegisters() != NULL); checkRegister(cpu, m_regidx1); checkRegister(cpu, m_regidx2); checkRegister(cpu, m_regidx3); cpu->getRegisters()[ m_regidx1 ] = cpu->getRegisters()[ m_regidx2 ] - cpu->getRegisters()[ m_regidx3 ]; } /*============================================================================*/ void CInstructionMul::compile(std::list& params) { if (params.size() != 3) throw runtime_error("Invalid paramater count - must be 3"); m_regidx1 = parseRegister(params.front()); params.pop_front(); m_regidx2 = parseRegister(params.front()); params.pop_front(); m_regidx3 = parseRegister(params.front()); params.pop_front(); } /*----------------------------------------------------------------------------*/ void CInstructionMul::execute(CCPU *cpu) { checkRegister(cpu, m_regidx1); checkRegister(cpu, m_regidx2); checkRegister(cpu, m_regidx3); cpu->getRegisters()[ m_regidx1 ] = cpu->getRegisters()[ m_regidx2 ] * cpu->getRegisters()[ m_regidx3 ]; } /*============================================================================*/ void CInstructionDiv::compile(std::list& params) { if (params.size() != 3) throw runtime_error("Invalid paramater count - must be 3"); m_regidx1 = parseRegister(params.front()); params.pop_front(); m_regidx2 = parseRegister(params.front()); params.pop_front(); m_regidx3 = parseRegister(params.front()); params.pop_front(); } /*----------------------------------------------------------------------------*/ void CInstructionDiv::execute(CCPU *cpu) { assert(cpu != NULL); assert(cpu->getRegisters() != NULL); checkRegister(cpu, m_regidx1); checkRegister(cpu, m_regidx2); checkRegister(cpu, m_regidx3); cpu->getRegisters()[ m_regidx1 ] = cpu->getRegisters()[ m_regidx2 ] / cpu->getRegisters()[ m_regidx3 ]; } /*============================================================================*/ void CInstructionLoad::compile(std::list& params) { if (params.size() != 2) throw runtime_error("Invalid paramater count - must be 2"); m_regidx1 = parseRegister(params.front()); params.pop_front(); m_regidx2 = parseRegister(params.front()); params.pop_front(); } /*----------------------------------------------------------------------------*/ void CInstructionLoad::execute(CCPU *cpu) { assert(cpu != NULL); assert(cpu->getRegisters() != NULL); assert(cpu->getMemory() != NULL); checkRegister(cpu, m_regidx1); checkRegister(cpu, m_regidx2); CDat val(cpu->getRegisters()[ m_regidx2 ]); cpu->getRegisters()[ m_regidx1 ] = (*cpu->getMemory())[ val ]; } /*============================================================================*/ void CInstructionStore::compile(std::list& params) { if (params.size() != 2) throw runtime_error("Invalid paramater count - must be 2"); m_regidx1 = parseRegister(params.front()); params.pop_front(); m_regidx2 = parseRegister(params.front()); params.pop_front(); } /*----------------------------------------------------------------------------*/ void CInstructionStore::execute(CCPU *cpu) { assert(cpu != NULL); assert(cpu->getRegisters() != NULL); assert(cpu->getMemory() != NULL); checkRegister(cpu, m_regidx1); checkRegister(cpu, m_regidx2); CDat val(cpu->getRegisters()[ m_regidx2 ]); (*cpu->getMemory())[ val ] = cpu->getRegisters()[ m_regidx1 ]; } /*============================================================================*/ void CInstructionTest::compile(std::list& params) { if (params.size() != 1) throw runtime_error("Invalid paramater count - must be 1"); m_regidx1 = parseRegister(params.front()); params.pop_front(); } /*----------------------------------------------------------------------------*/ void CInstructionTest::execute(CCPU *cpu) { assert(cpu != NULL); assert(cpu->getRegisters() != NULL); checkRegister(cpu, m_regidx1); if (cpu->getRegisters()[ m_regidx1 ] == CDat(0)) cpu->setFlagZero(true); if (cpu->getRegisters()[ m_regidx1 ] < CDat(0)) cpu->setFlagSign(true); } /*============================================================================*/ void CInstructionJumpA::compile(std::list& params) { if (params.size() != 1) throw runtime_error("Invalid paramater count - must be 1"); m_addr = params.front(); params.pop_front(); } /*----------------------------------------------------------------------------*/ void CInstructionJumpA::execute(CCPU *cpu) { assert(cpu != NULL); assert(cpu->getRegisters() != NULL); assert(cpu->getProgram() != NULL); if (m_addr.empty()) throw runtime_error("Empty address"); cpu->getRegisters()[ 0 ] = cpu->getProgram()->findLabel(m_addr); } /*============================================================================*/ void CInstructionJumpZ::compile(std::list& params) { if (params.size() != 1) throw runtime_error("Invalid paramater count - must be 1"); m_addr = params.front(); params.pop_front(); } /*----------------------------------------------------------------------------*/ void CInstructionJumpZ::execute(CCPU *cpu) { assert(cpu != NULL); assert(cpu->getRegisters() != NULL); assert(cpu->getProgram() != NULL); if (!cpu->getFlagZero()) return; if (m_addr.empty()) throw runtime_error("Empty address"); cpu->getRegisters()[ 0 ] = cpu->getProgram()->findLabel(m_addr); } /*============================================================================*/ void CInstructionJumpS::compile(std::list& params) { if (params.size() != 1) throw runtime_error("Invalid paramater count - must be 1"); m_addr = params.front(); params.pop_front(); } /*----------------------------------------------------------------------------*/ void CInstructionJumpS::execute(CCPU *cpu) { assert(cpu != NULL); assert(cpu->getRegisters() != NULL); assert(cpu->getProgram() != NULL); if (!cpu->getFlagSign()) return; if (m_addr.empty()) throw runtime_error("Empty address"); cpu->getRegisters()[ 0 ] = cpu->getProgram()->findLabel(m_addr); } /*============================================================================*/ void CInstructionWrite::compile(std::list& params) { if (params.size() != 2) throw runtime_error("Invalid paramater count - must be 2"); m_dev = params.front(); params.pop_front(); m_regidx1 = parseRegister(params.front()); params.pop_front(); } /*----------------------------------------------------------------------------*/ void CInstructionWrite::execute(CCPU *cpu) { assert(cpu != NULL); assert(cpu->getRegisters() != NULL); checkRegister(cpu, m_regidx1); if (m_dev.empty()) throw runtime_error("Empty device"); CDisplay *display = NULL; std::set displays = cpu->getDisplays(); std::set::iterator it; for(it = displays.begin(); it != displays.end(); ++it) { if ((*it)->getName() == m_dev) { display = *it; break; } } if (display == NULL) throw runtime_error("Unknown display"); display->display(cpu->getRegisters()[ m_regidx1 ]); } /* vim: set et sw=2 ts=2: */