Download | Plain Text | Line Numbers
/**
* @module instructions
* @author Guenther Neuwirth (0626638), Manuel Mausz (0728348)
* @brief Implementations of CInstruction
* @date 10.05.2009
*/
#include <map>
#include <assert.h>
#include "instructions.h"
using namespace std;
void CInstructionInc::compile(std::list<std::string>& 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<std::string>& 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<std::string>& 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<std::string>& 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<std::string>& 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<std::string>& 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<std::string>& 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<std::string>& 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<std::string>& 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<std::string>& 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<std::string>& 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<std::string>& 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<std::string>& 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<CDisplay *> displays = cpu->getDisplays();
std::set<CDisplay *>::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: */