From 1a60d0c2a8eeef3b39ef276f0f3552552a1519b1 Mon Sep 17 00:00:00 2001 From: manuel Date: Tue, 26 May 2009 14:49:37 +0200 Subject: adding ue4 (copy from ue3) --- ue4/mycpu/instructions.cpp | 341 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 341 insertions(+) create mode 100644 ue4/mycpu/instructions.cpp (limited to 'ue4/mycpu/instructions.cpp') diff --git a/ue4/mycpu/instructions.cpp b/ue4/mycpu/instructions.cpp new file mode 100644 index 0000000..ef9e944 --- /dev/null +++ b/ue4/mycpu/instructions.cpp @@ -0,0 +1,341 @@ +/** + * @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: */ -- cgit v1.2.3