From 89e202f49b9857dcd3627fbc4e0262125d729bbc Mon Sep 17 00:00:00 2001 From: manuel Date: Wed, 13 May 2009 04:09:39 +0200 Subject: adding all instructions and displays --- ue3/mycpu/Makefile | 2 +- ue3/mycpu/ccpu.cpp | 18 +- ue3/mycpu/ccpu.h | 84 +++++++++- ue3/mycpu/cdat.h | 4 +- ue3/mycpu/cdisplay.h | 41 ++++- ue3/mycpu/cinstruction.cpp | 4 +- ue3/mycpu/cinstruction.h | 133 +++++++++++++-- ue3/mycpu/cprogram.cpp | 14 ++ ue3/mycpu/displays.h | 56 +++++++ ue3/mycpu/instructions.cpp | 339 +++++++++++++++++++++++++++++++++++++- ue3/mycpu/instructions.h | 399 ++++++++++++++++++++++++++++++++++++++++++--- ue3/mycpu/mycpu.cpp | 16 +- ue3/mycpu/test/memory1 | 1 + ue3/mycpu/test/program1 | 13 ++ 14 files changed, 1051 insertions(+), 73 deletions(-) create mode 100644 ue3/mycpu/displays.h create mode 100644 ue3/mycpu/test/memory1 create mode 100644 ue3/mycpu/test/program1 diff --git a/ue3/mycpu/Makefile b/ue3/mycpu/Makefile index 16067d1..eec8b47 100644 --- a/ue3/mycpu/Makefile +++ b/ue3/mycpu/Makefile @@ -12,7 +12,7 @@ LIBS= -L/usr/local/lib -lboost_program_options BIN= mycpu OBJS= cinstruction.o instructions.o cprogram.o ccpu.o mycpu.o -HEADERS= cdat.h cmem.h cinstruction.h instructions.h cprogram.h cdisplay.h ccpu.h +HEADERS= cdat.h cmem.h cinstruction.h instructions.h cprogram.h cdisplay.h displays.h ccpu.h .SUFFIXES: .cpp .o diff --git a/ue3/mycpu/ccpu.cpp b/ue3/mycpu/ccpu.cpp index 6f364f8..b1539a4 100644 --- a/ue3/mycpu/ccpu.cpp +++ b/ue3/mycpu/ccpu.cpp @@ -10,23 +10,35 @@ # include #endif #include "ccpu.h" +#include "displays.h" using namespace std; CCPU::CCPU(const unsigned cnt) - : m_regcnt(cnt), m_memory(NULL), m_program(NULL), m_flagzero(0), m_flagsign(0) + : m_regcnt(cnt), m_memory(NULL), m_program(NULL), m_flagzero(false), m_flagsign(false) { + /* create registers */ m_registers = new CDat[cnt]; for(unsigned i = 0; i < cnt; ++i) m_registers[i] = 0; + + /* create displays */ + m_displays.insert(new CDisplayWDEZ); + m_displays.insert(new CDisplayWHEX); } /*----------------------------------------------------------------------------*/ CCPU::~CCPU() { + /* delete registers */ delete[] m_registers; m_registers = NULL; + + /* delete displays */ + std::set::iterator it; + for (it = m_displays.begin() ; it != m_displays.end(); ++it) + delete *it; } /*----------------------------------------------------------------------------*/ @@ -47,7 +59,7 @@ void CCPU::run() /* end of the program reached */ if (pc == m_program->size()) - return; + break; /* pc is out of bound */ if (pc > m_program->size()) @@ -57,8 +69,6 @@ void CCPU::run() m_program->at(pc)->execute(this); ++m_registers[0]; } - - cout << "LALA" << endl; } /*----------------------------------------------------------------------------*/ diff --git a/ue3/mycpu/ccpu.h b/ue3/mycpu/ccpu.h index e28a7cc..1ef1923 100644 --- a/ue3/mycpu/ccpu.h +++ b/ue3/mycpu/ccpu.h @@ -8,11 +8,12 @@ #ifndef CCPU_H #define CCPU_H 1 -#include #include +#include #include "cdat.h" #include "cmem.h" #include "cprogram.h" +#include "cdisplay.h" /** * @class CCPU @@ -53,7 +54,7 @@ class CCPU * @exception none * @conditions none */ - const unsigned getRegisterCount() + const unsigned getRegisterCount() const { return m_regcnt; } @@ -67,7 +68,7 @@ class CCPU * @exception none * @conditions none */ - CDat *getRegisters() + CDat *getRegisters() const { return m_registers; } @@ -81,7 +82,7 @@ class CCPU * @exception none * @conditions none */ - void setMemory(const CMem *memory) + void setMemory(CMem *memory) { m_memory = memory; } @@ -95,7 +96,7 @@ class CCPU * @exception none * @conditions none */ - const CMem *getMemory() + CMem *getMemory() const { return m_memory; } @@ -128,6 +129,76 @@ class CCPU return m_program; } + /** + * @method getDisplays + * @brief get set of pointers to displays + * @param - + * @return reference to set of pointers to displays + * @globalvars none + * @exception none + * @conditions none + */ + const std::set& getDisplays() + { + return m_displays; + } + + /** + * @method setFlagZero + * @brief set zero flag + * @param value new value of zero flag + * @return - + * @globalvars none + * @exception none + * @conditions none + */ + void setFlagZero(const bool value) + { + m_flagzero = value; + } + + /** + * @method getFlagZero + * @brief get value of zero flag + * @param - + * @return value of zero flag + * @globalvars none + * @exception none + * @conditions none + */ + const bool getFlagZero() + { + return m_flagzero; + } + + /** + * @method setFlagSign + * @brief set sign flag + * @param value new value of sign flag + * @return - + * @globalvars none + * @exception none + * @conditions none + */ + void setFlagSign(const bool value) + { + m_flagsign = value; + } + + /** + * @method getFlagSign + * @brief get value of sign flag + * @param - + * @return value of sign flag + * @globalvars none + * @exception none + * @conditions none + */ + const bool getFlagSign() + { + return m_flagsign; + } + /** * @method run * @brief execute current program @@ -156,8 +227,9 @@ class CCPU /* members */ CDat *m_registers; unsigned m_regcnt; - const CMem *m_memory; + CMem *m_memory; const CProgram *m_program; + std::set m_displays; bool m_flagzero; bool m_flagsign; }; diff --git a/ue3/mycpu/cdat.h b/ue3/mycpu/cdat.h index 365bd88..c656b99 100644 --- a/ue3/mycpu/cdat.h +++ b/ue3/mycpu/cdat.h @@ -72,7 +72,7 @@ class CDatT {} /** - * @method value + * @method getValue * @brief returns value of CDatT * @param - * @return value of CDatT @@ -80,7 +80,7 @@ class CDatT * @exception none * @conditions none */ - T value() const + T getValue() const { return m_value; } diff --git a/ue3/mycpu/cdisplay.h b/ue3/mycpu/cdisplay.h index 629ec88..ed9b84d 100644 --- a/ue3/mycpu/cdisplay.h +++ b/ue3/mycpu/cdisplay.h @@ -6,7 +6,7 @@ */ #ifndef CDISPLAY_H -#define CDISPLAY_H #1 +#define CDISPLAY_H 1 /** * @class CDisplay @@ -19,14 +19,16 @@ class CDisplay /** * @method CDisplay * @brief Default ctor - * @param - + * @param name name of display * @return - * @globalvars none * @exception none * @conditions none */ - CDisplay() - {}; + CDisplay(std::string name) + { + m_name = name; + } /** * @method ~CDisplay @@ -37,10 +39,37 @@ class CDisplay * @exception none * @conditions none */ - ~CDisplay(); + virtual ~CDisplay() + {} + + /** + * @method getName + * @brief returns name of display + * @param - + * @return name of display + * @globalvars none + * @exception none + * @conditions none + */ + virtual const std::string& getName() + { + return m_name; + } + + /** + * @method getName + * @brief prints value to display + * @param value value to display + * @return - + * @globalvars none + * @exception none + * @conditions none + */ + virtual void display(const CDat &value) = 0; - private: + protected: /* members */ + std::string m_name; }; #endif diff --git a/ue3/mycpu/cinstruction.cpp b/ue3/mycpu/cinstruction.cpp index 32bdd2f..57acd5f 100644 --- a/ue3/mycpu/cinstruction.cpp +++ b/ue3/mycpu/cinstruction.cpp @@ -16,7 +16,7 @@ using namespace std; const unsigned CInstruction::parseRegister(const std::string& str) { unsigned reg; - if (str.length() < 2 || str[0] != 'R') + if (str.length() < 2 || str[0] != 'r') throw runtime_error("Invalid syntax of register"); try @@ -33,7 +33,7 @@ const unsigned CInstruction::parseRegister(const std::string& str) /*----------------------------------------------------------------------------*/ -inline void CInstruction::checkRegister(CCPU *cpu, unsigned regidx) +inline void CInstruction::checkRegister(CCPU *cpu, const unsigned regidx) { if (regidx >= cpu->getRegisterCount()) { diff --git a/ue3/mycpu/cinstruction.h b/ue3/mycpu/cinstruction.h index b16c067..57fcff1 100644 --- a/ue3/mycpu/cinstruction.h +++ b/ue3/mycpu/cinstruction.h @@ -10,9 +10,8 @@ #include #include -//#include "ccpu.h" -/* declare CCPU */ +/* forward declare CCPU */ class CCPU; /** @@ -26,7 +25,7 @@ class CInstruction /** * @method CInstruction * @brief Default ctor - * @param - + * @param name name of instruction * @return - * @globalvars none * @exception none @@ -34,7 +33,7 @@ class CInstruction */ CInstruction(std::string name) : m_name(name) - {}; + {} /** * @method ~CInstruction @@ -46,46 +45,150 @@ class CInstruction * @conditions none */ virtual ~CInstruction() - {}; + {} - /* TODO */ + /** + * @method operator== + * @brief implementation of operator == + * @param reference to std::string + * @return true if instructionname is name + * @globalvars none + * @exception none + * @conditions none + */ virtual bool operator==(std::string& name) { return name == m_name; } - /* TODO */ + /** + * @method getName + * @brief returns instruction name + * @param - + * @return name of instruction + * @globalvars none + * @exception none + * @conditions none + */ virtual const std::string& getName() { return m_name; } - /* TODO */ + /** + * @method isLabel + * @brief returns true if the instruction defines a label + * @param - + * @return true if the instruction defines a label + * @globalvars none + * @exception none + * @conditions none + */ + virtual const bool isLabel() + { + return false; + } + + /** + * @method getLabelName + * @brief returns labelname if the instruction defines a label + * @param - + * @return labelname if the instruction defines a label + * @globalvars none + * @exception none + * @conditions none + */ + virtual const std::string getLabelName() + { + return ""; + } + + /** + * @method dump + * @brief dumps information about instruction to outputstream + * @param stream outputstream + * @return reference to outputstream + * @globalvars none + * @exception none + * @conditions none + */ virtual std::ostream& dump(std::ostream& stream) { stream << m_name; return stream; } - /* TODO */ + /** + * @method operator<< + * @brief Shift/output operator for outputstream + * @param stream reference to outputstream + * @param cdat object which will be printed to stream + * @return reference to outputstream + * @globalvars none + * @exception none + * @conditions none + */ friend std::ostream& operator<<(std::ostream& stream, CInstruction& instr) { return instr.dump(stream); } - /* TODO */ + /** + * @method parseRegister + * @brief parses register syntax Rx (e.g. "R1") + * @param str register in assembler syntax + * @return registernumber + * @globalvars none + * @exception runtime_error + * @conditions none + */ virtual const unsigned parseRegister(const std::string& str); - /* TODO */ - virtual void checkRegister(CCPU *cpu, unsigned regidx); + /** + * @method checkRegister + * @brief performs a register boundary check + * does the register exist in cpu? + * @param cpu pointer to cpu + * @param regidx registernumber + * @return - + * @globalvars none + * @exception runtime_error + * @conditions none + */ + virtual void checkRegister(CCPU *cpu, const unsigned regidx); - /* TODO */ + /** + * @method factory + * @brief creates a new instance of this instruction + * @param - + * @return new instruction instance + * @globalvars none + * @exception none + * @conditions none + */ virtual CInstruction *factory() = 0; - /* TODO */ + /** + * @method compile + * @brief parses instruction parameters and prepares the + * instruction for executing + * @param params list of parameters of this instruction + * @return - + * @globalvars none + * @exception runtime_error + * @conditions none + */ virtual void compile(std::list& params) = 0; - /* TODO */ + /** + * @method execute + * @brief executes the instruction + * @param cpu pointer to cpu + * @return - + * @globalvars none + * @exception runtime_error + * @conditions none + */ virtual void execute(CCPU *cpu) = 0; protected: diff --git a/ue3/mycpu/cprogram.cpp b/ue3/mycpu/cprogram.cpp index 03d4c30..f6fc3cb 100644 --- a/ue3/mycpu/cprogram.cpp +++ b/ue3/mycpu/cprogram.cpp @@ -19,6 +19,19 @@ using namespace std; CProgram::CProgram() { m_instrset.insert(new CInstructionInc); + m_instrset.insert(new CInstructionDec); + m_instrset.insert(new CInstructionAdd); + m_instrset.insert(new CInstructionSub); + m_instrset.insert(new CInstructionMul); + m_instrset.insert(new CInstructionDiv); + m_instrset.insert(new CInstructionLoad); + m_instrset.insert(new CInstructionStore); + m_instrset.insert(new CInstructionTest); + m_instrset.insert(new CInstructionLabel); + m_instrset.insert(new CInstructionJumpA); + m_instrset.insert(new CInstructionJumpZ); + m_instrset.insert(new CInstructionJumpS); + m_instrset.insert(new CInstructionWrite); } /*----------------------------------------------------------------------------*/ @@ -54,6 +67,7 @@ void CProgram::compile(std::istream& in) continue; boost::trim(line); + boost::to_lower(line); /* ignore comments */ if (line.find_first_of('#') == 0) diff --git a/ue3/mycpu/displays.h b/ue3/mycpu/displays.h new file mode 100644 index 0000000..f7adbdb --- /dev/null +++ b/ue3/mycpu/displays.h @@ -0,0 +1,56 @@ +/** + * @module displays + * @author Guenther Neuwirth (0626638), Manuel Mausz (0728348) + * @brief TODO + * @date 10.05.2009 + */ + +#ifndef DISPLAYS_H +#define DISPLAYS_H 1 + +#include +#include "cdisplay.h" + +/** + * @class CDisplayWDEZ + * + * TODO + */ +class CDisplayWDEZ + : public CDisplay +{ + public: + CDisplayWDEZ() + : CDisplay("wdez") + {} + + void display(const CDat &value) + { + std::cout << std::dec << value << std::endl; + } +}; + +/*============================================================================*/ + +/** + * @class CDisplayWHEX + * + * TODO + */ +class CDisplayWHEX + : public CDisplay +{ + public: + CDisplayWHEX() + : CDisplay("whex") + {} + + void display(const CDat &value) + { + std::cout << std::hex << value << std::endl; + } +}; + +#endif + +/* vim: set et sw=2 ts=2: */ diff --git a/ue3/mycpu/instructions.cpp b/ue3/mycpu/instructions.cpp index c283e57..609cd1c 100644 --- a/ue3/mycpu/instructions.cpp +++ b/ue3/mycpu/instructions.cpp @@ -14,6 +14,7 @@ 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(); } /*----------------------------------------------------------------------------*/ @@ -21,7 +22,343 @@ void CInstructionInc::compile(std::list& params) void CInstructionInc::execute(CCPU *cpu) { checkRegister(cpu, m_regidx1); - cpu->getRegisters()[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) +{ + 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) +{ + 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) +{ + 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) +{ + 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) +{ + 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) +{ + 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) +{ + 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 CInstructionLabel::compile(std::list& params) +{ + if (params.size() != 1) + throw runtime_error("Invalid paramater count - must be 1"); + string label = params.front(); + params.pop_front(); + if (label.length() < 2 || label[ label.length() - 1] != ':') + throw runtime_error("Label has invalid syntax"); + m_label = label.substr(0, label.length() - 1); +} + +/*----------------------------------------------------------------------------*/ + +void CInstructionLabel::execute(CCPU *cpu) +{ + if (m_label.empty()) + throw runtime_error("Empty label"); +} + +/*============================================================================*/ + +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) +{ + if (m_addr.empty()) + throw runtime_error("Empty address"); + + const CProgram *progam = cpu->getProgram(); + for(unsigned i = 0; i < progam->size(); i++) + { + if (progam->at(i)->isLabel() && progam->at(i)->getLabelName() == m_addr) + { + cpu->getRegisters()[ 0 ] = i; + return; + } + } + + throw runtime_error("Unknown label '" + 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) +{ + if (!cpu->getFlagZero()) + return; + if (m_addr.empty()) + throw runtime_error("Empty address"); + + const CProgram *progam = cpu->getProgram(); + for(unsigned i = 0; i < progam->size(); i++) + { + if (progam->at(i)->isLabel() && progam->at(i)->getLabelName() == m_addr) + { + cpu->getRegisters()[ 0 ] = i; + return; + } + } + + throw runtime_error("Unknown label '" + 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) +{ + if (!cpu->getFlagSign()) + return; + if (m_addr.empty()) + throw runtime_error("Empty address"); + + const CProgram *progam = cpu->getProgram(); + for(unsigned i = 0; i < progam->size(); i++) + { + if (progam->at(i)->isLabel() && progam->at(i)->getLabelName() == m_addr) + { + cpu->getRegisters()[ 0 ] = i; + return; + } + } + + throw runtime_error("Unknown label '" + 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) +{ + 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: */ diff --git a/ue3/mycpu/instructions.h b/ue3/mycpu/instructions.h index ebd1533..8c62e0b 100644 --- a/ue3/mycpu/instructions.h +++ b/ue3/mycpu/instructions.h @@ -20,45 +20,392 @@ class CInstructionInc : public CInstruction { public: - /** - * @method CInstruction - * @brief Default ctor - * @param - - * @return - - * @globalvars none - * @exception none - * @conditions none - */ CInstructionInc() : CInstruction("inc") - {}; - - /** - * @method ~CInstruction - * @brief Default dtor - * @param - - * @return - - * @globalvars none - * @exception none - * @conditions none - */ - ~CInstructionInc() - {}; - - /* TODO */ + {} + CInstructionInc *factory() { return new CInstructionInc; } - /* TODO */ void compile(std::list& params); + void execute(CCPU *cpu); + + protected: + unsigned m_regidx1; +}; + +/*============================================================================*/ + +/** + * @class CInstructionDec + * + * TODO + */ +class CInstructionDec + : public CInstruction +{ + public: + CInstructionDec() + : CInstruction("dec") + {} + + CInstructionDec *factory() + { + return new CInstructionDec; + } + + void compile(std::list& params); + void execute(CCPU *cpu); + + protected: + unsigned m_regidx1; +}; + +/*============================================================================*/ + +/** + * @class CInstructionAdd + * + * TODO + */ +class CInstructionAdd + : public CInstruction +{ + public: + CInstructionAdd() + : CInstruction("add") + {} + + CInstructionAdd *factory() + { + return new CInstructionAdd; + } + + void compile(std::list& params); + void execute(CCPU *cpu); + + protected: + unsigned m_regidx1; + unsigned m_regidx2; + unsigned m_regidx3; +}; + +/*============================================================================*/ + +/** + * @class CInstructionSub + * + * TODO + */ +class CInstructionSub + : public CInstruction +{ + public: + CInstructionSub() + : CInstruction("sub") + {} + + CInstructionSub *factory() + { + return new CInstructionSub; + } + + void compile(std::list& params); + void execute(CCPU *cpu); + + protected: + unsigned m_regidx1; + unsigned m_regidx2; + unsigned m_regidx3; +}; - /* TODO */ +/*============================================================================*/ + +/** + * @class CInstructionMul + * + * TODO + */ +class CInstructionMul + : public CInstruction +{ + public: + CInstructionMul() + : CInstruction("mul") + {} + + CInstructionMul *factory() + { + return new CInstructionMul; + } + + void compile(std::list& params); + void execute(CCPU *cpu); + + protected: + unsigned m_regidx1; + unsigned m_regidx2; + unsigned m_regidx3; +}; + +/*============================================================================*/ + +/** + * @class CInstructionDiv + * + * TODO + */ +class CInstructionDiv + : public CInstruction +{ + public: + CInstructionDiv() + : CInstruction("div") + {} + + CInstructionDiv *factory() + { + return new CInstructionDiv; + } + + void compile(std::list& params); + void execute(CCPU *cpu); + + protected: + unsigned m_regidx1; + unsigned m_regidx2; + unsigned m_regidx3; +}; + +/*============================================================================*/ + +/** + * @class CInstructionLoad + * + * TODO + */ +class CInstructionLoad + : public CInstruction +{ + public: + CInstructionLoad() + : CInstruction("load") + {} + + CInstructionLoad *factory() + { + return new CInstructionLoad; + } + + void compile(std::list& params); + void execute(CCPU *cpu); + + protected: + unsigned m_regidx1; + unsigned m_regidx2; +}; + +/*============================================================================*/ + +/** + * @class CInstructionStore + * + * TODO + */ +class CInstructionStore + : public CInstruction +{ + public: + CInstructionStore() + : CInstruction("store") + {} + + CInstructionStore *factory() + { + return new CInstructionStore; + } + + void compile(std::list& params); + void execute(CCPU *cpu); + + protected: + unsigned m_regidx1; + unsigned m_regidx2; +}; + +/*============================================================================*/ + +/** + * @class CInstructionTest + * + * TODO + */ +class CInstructionTest + : public CInstruction +{ + public: + CInstructionTest() + : CInstruction("test") + {} + + CInstructionTest *factory() + { + return new CInstructionTest; + } + + void compile(std::list& params); + void execute(CCPU *cpu); + + protected: + unsigned m_regidx1; +}; + +/*============================================================================*/ + +/** + * @class CInstructionLabel + * + * TODO + */ +class CInstructionLabel + : public CInstruction +{ + public: + CInstructionLabel() + : CInstruction("label"), m_label("") + {} + + const bool isLabel() + { + return true; + } + + const std::string getLabelName() + { + return m_label; + } + + CInstructionLabel *factory() + { + return new CInstructionLabel; + } + + void compile(std::list& params); + void execute(CCPU *cpu); + + protected: + std::string m_label; +}; + +/*============================================================================*/ + +/** + * @class CInstructionJumpA + * + * TODO + */ +class CInstructionJumpA + : public CInstruction +{ + public: + CInstructionJumpA() + : CInstruction("jumpa"), m_addr("") + {} + + CInstructionJumpA *factory() + { + return new CInstructionJumpA; + } + + void compile(std::list& params); + void execute(CCPU *cpu); + + protected: + std::string m_addr; +}; + +/*============================================================================*/ + +/** + * @class CInstructionJumpZ + * + * TODO + */ +class CInstructionJumpZ + : public CInstruction +{ + public: + CInstructionJumpZ() + : CInstruction("jumpz"), m_addr("") + {} + + CInstructionJumpZ *factory() + { + return new CInstructionJumpZ; + } + + void compile(std::list& params); + void execute(CCPU *cpu); + + protected: + std::string m_addr; +}; + +/*============================================================================*/ + +/** + * @class CInstructionJumpS + * + * TODO + */ +class CInstructionJumpS + : public CInstruction +{ + public: + CInstructionJumpS() + : CInstruction("jumps"), m_addr("") + {} + + CInstructionJumpS *factory() + { + return new CInstructionJumpS; + } + + void compile(std::list& params); + void execute(CCPU *cpu); + + protected: + std::string m_addr; +}; + +/*============================================================================*/ + +/** + * @class CInstructionWrite + * + * TODO + */ +class CInstructionWrite + : public CInstruction +{ + public: + CInstructionWrite() + : CInstruction("write"), m_dev("") + {} + + CInstructionWrite *factory() + { + return new CInstructionWrite; + } + + void compile(std::list& params); void execute(CCPU *cpu); protected: unsigned m_regidx1; + std::string m_dev; }; #endif diff --git a/ue3/mycpu/mycpu.cpp b/ue3/mycpu/mycpu.cpp index af91fe7..08861a4 100644 --- a/ue3/mycpu/mycpu.cpp +++ b/ue3/mycpu/mycpu.cpp @@ -19,13 +19,6 @@ using namespace std; namespace po = boost::program_options; -/** TODO */ -void myterminate() -{ - cerr << "Unexpected termination" << endl; - abort(); -} - /** * @func main * @brief program entry point @@ -40,7 +33,6 @@ void myterminate() */ int main(int argc, char* argv[]) { - //TODO set_terminate(myterminate); string me(argv[0]); /* define commandline options */ @@ -136,13 +128,17 @@ int main(int argc, char* argv[]) cpu.setProgram(&program); cpu.run(); #if DEBUG - cpu.dumpRegisters(cout); + //cpu.dumpRegisters(cout); #endif } catch(runtime_error& ex) { cerr << me << ": Error while executing program:" << endl - << " " << ex.what() << endl; + << " " << ex.what() << endl; +#if DEBUG + memory.dump(cout); + //cpu.dumpRegisters(cout); +#endif return 1; } diff --git a/ue3/mycpu/test/memory1 b/ue3/mycpu/test/memory1 new file mode 100644 index 0000000..209e3ef --- /dev/null +++ b/ue3/mycpu/test/memory1 @@ -0,0 +1 @@ +20 diff --git a/ue3/mycpu/test/program1 b/ue3/mycpu/test/program1 new file mode 100644 index 0000000..ae5e9d2 --- /dev/null +++ b/ue3/mycpu/test/program1 @@ -0,0 +1,13 @@ +# set R2 = 10 +LOAD R2, R1 + +# start of loop +label Loop: +inc R3 +sub R4, R3, R2 +test R4 +jumpz EndLoop +write WDEZ, R3 +jumpa Loop + +label EndLoop: -- cgit v1.2.3