From 45581d3d376e8deed84952cb838ae330549e5241 Mon Sep 17 00:00:00 2001 From: manuel Date: Tue, 12 May 2009 23:18:17 +0200 Subject: my cpu design --- ue3/mycpu/Makefile | 8 +-- ue3/mycpu/ccpu.cpp | 78 +++++++++++++++++++++ ue3/mycpu/ccpu.h | 167 +++++++++++++++++++++++++++++++++++++++++++++ ue3/mycpu/cdat.h | 29 ++++++-- ue3/mycpu/cdisplay.h | 48 +++++++++++++ ue3/mycpu/cinstruction.cpp | 46 +++++++++++++ ue3/mycpu/cinstruction.h | 98 ++++++++++++++++++++++++++ ue3/mycpu/cmem.h | 109 +++++++++++++++++++++++++++++ ue3/mycpu/cprogram.cpp | 126 ++++++++++++++++++++++++++++++++++ ue3/mycpu/cprogram.h | 78 +++++++++++++++++++++ ue3/mycpu/instructions.cpp | 27 ++++++++ ue3/mycpu/instructions.h | 66 ++++++++++++++++++ ue3/mycpu/mycpu.cpp | 152 +++++++++++++++++++++++++++++++++++++++++ 13 files changed, 1022 insertions(+), 10 deletions(-) create mode 100644 ue3/mycpu/ccpu.cpp create mode 100644 ue3/mycpu/ccpu.h create mode 100644 ue3/mycpu/cdisplay.h create mode 100644 ue3/mycpu/cinstruction.cpp create mode 100644 ue3/mycpu/cinstruction.h create mode 100644 ue3/mycpu/cmem.h create mode 100644 ue3/mycpu/cprogram.cpp create mode 100644 ue3/mycpu/cprogram.h create mode 100644 ue3/mycpu/instructions.cpp create mode 100644 ue3/mycpu/instructions.h create mode 100644 ue3/mycpu/mycpu.cpp (limited to 'ue3/mycpu') diff --git a/ue3/mycpu/Makefile b/ue3/mycpu/Makefile index 6f57741..16067d1 100644 --- a/ue3/mycpu/Makefile +++ b/ue3/mycpu/Makefile @@ -6,13 +6,13 @@ CXX= g++ LD= $(CXX) DEBUGFLAGS= -DNDEBUG INCLUDE_PATH= -I/usr/local/include -CXXFLAGS= -O -ansi -pedantic-errors -Wall $(INCLUDE_PATH) $(DEBUGFLAGS) +CXXFLAGS= -O -ansi -pedantic-errors -Wall -Wno-long-long $(INCLUDE_PATH) $(DEBUGFLAGS) LDFLAGS= -LIBS= -L/usr/local/lib +LIBS= -L/usr/local/lib -lboost_program_options BIN= mycpu -OBJS= mycpu.o cdat.o -HEADERS= cdat.h +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 .SUFFIXES: .cpp .o diff --git a/ue3/mycpu/ccpu.cpp b/ue3/mycpu/ccpu.cpp new file mode 100644 index 0000000..6f364f8 --- /dev/null +++ b/ue3/mycpu/ccpu.cpp @@ -0,0 +1,78 @@ +/** + * @module ccpu + * @author Guenther Neuwirth (0626638), Manuel Mausz (0728348) + * @brief TODO + * @date 10.05.2009 + */ + +#ifdef DEBUG +# include +# include +#endif +#include "ccpu.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_registers = new CDat[cnt]; + for(unsigned i = 0; i < cnt; ++i) + m_registers[i] = 0; +} + +/*----------------------------------------------------------------------------*/ + +CCPU::~CCPU() +{ + delete[] m_registers; + m_registers = NULL; +} + +/*----------------------------------------------------------------------------*/ + +void CCPU::run() +{ + if (m_memory == NULL) + throw runtime_error("CPU has no memory"); + if (m_program == NULL) + throw runtime_error("CPU has no program to execute"); + if (m_regcnt == 0) + throw runtime_error("CPU has no registers"); + + bool run = true; + while(run) + { + unsigned pc = static_cast(m_registers[0]); + + /* end of the program reached */ + if (pc == m_program->size()) + return; + + /* pc is out of bound */ + if (pc > m_program->size()) + throw runtime_error("Programcounter is out of bound"); + + /* execute instruction */ + m_program->at(pc)->execute(this); + ++m_registers[0]; + } + + cout << "LALA" << endl; +} + +/*----------------------------------------------------------------------------*/ + +#if DEBUG +void CCPU::dumpRegisters(std::ostream& out) +{ + out << "[REGISTER DUMP]" << endl; + for(unsigned i = 0; i < getRegisterCount(); ++i) + { + out << "[" << std::setw(4) << std::setfill('0') << i << "] " + << m_registers[i] << endl; + } +} +#endif + +/* vim: set et sw=2 ts=2: */ diff --git a/ue3/mycpu/ccpu.h b/ue3/mycpu/ccpu.h new file mode 100644 index 0000000..e28a7cc --- /dev/null +++ b/ue3/mycpu/ccpu.h @@ -0,0 +1,167 @@ +/** + * @module ccpu + * @author Guenther Neuwirth (0626638), Manuel Mausz (0728348) + * @brief TODO + * @date 10.05.2009 + */ + +#ifndef CCPU_H +#define CCPU_H 1 + +#include +#include +#include "cdat.h" +#include "cmem.h" +#include "cprogram.h" + +/** + * @class CCPU + * + * TODO + */ +class CCPU +{ + public: + /** + * @method CCPU + * @brief Default ctor + * @param cnt number of registers to allocate for this cpu + * @return - + * @globalvars none + * @exception none + * @conditions none + */ + CCPU(const unsigned cnt); + + /** + * @method ~CCPU + * @brief Default dtor + * @param - + * @return - + * @globalvars none + * @exception none + * @conditions none + */ + ~CCPU(); + + /** + * @method getRegisterCount + * @brief get number of registers + * @param - + * @return number of registers + * @globalvars none + * @exception none + * @conditions none + */ + const unsigned getRegisterCount() + { + return m_regcnt; + } + + /** + * @method getRegisters + * @brief get pointer to registers array + * @param - + * @return pointer to registers array + * @globalvars none + * @exception none + * @conditions none + */ + CDat *getRegisters() + { + return m_registers; + } + + /** + * @method setMemory + * @brief set memory of cpu + * @param memory pointer to memory + * @return - + * @globalvars none + * @exception none + * @conditions none + */ + void setMemory(const CMem *memory) + { + m_memory = memory; + } + + /** + * @method getMemory + * @brief get pointer to memory + * @param - + * @return pointer to memory + * @globalvars none + * @exception none + * @conditions none + */ + const CMem *getMemory() + { + return m_memory; + } + + /** + * @method setProgram + * @brief set program to execute + * @param memory pointer to program + * @return - + * @globalvars none + * @exception none + * @conditions none + */ + void setProgram(const CProgram *program) + { + m_program = program; + } + + /** + * @method getProgram + * @brief get pointer to program + * @param - + * @return pointer to program + * @globalvars none + * @exception none + * @conditions none + */ + const CProgram *getProgram() + { + return m_program; + } + + /** + * @method run + * @brief execute current program + * @param - + * @return - + * @globalvars none + * @exception runtime_error + * @conditions none + */ + void run(); + +#if DEBUG + /** + * @method dumpRegisters + * @brief dump content of registers to outputstream + * @param out outputstream to write to + * @return void + * @globalvars none + * @exception none + * @conditions none + */ + void dumpRegisters(std::ostream& out); +#endif + + private: + /* members */ + CDat *m_registers; + unsigned m_regcnt; + const CMem *m_memory; + const CProgram *m_program; + bool m_flagzero; + bool m_flagsign; +}; + +#endif + +/* vim: set et sw=2 ts=2: */ diff --git a/ue3/mycpu/cdat.h b/ue3/mycpu/cdat.h index dc8a07c..365bd88 100644 --- a/ue3/mycpu/cdat.h +++ b/ue3/mycpu/cdat.h @@ -1,12 +1,12 @@ /** * @module cdat * @author Guenther Neuwirth (0626638), Manuel Mausz (0728348) - * @brief Datatype template for mycpu + * @brief Datatype template and datatype definition for CCPU and CMem * @date 10.05.2009 */ -#ifndef CDATT_H -#define CDATT_H +#ifndef CDAT_H +#define CDAT_H 1 #include #include @@ -14,7 +14,7 @@ /** * @class CDatT * - * Datatype template for mycpu. + * Datatype template for CCPU and CMem. */ template class CDatT @@ -85,6 +85,20 @@ class CDatT return m_value; } + /** + * @method operator T + * @brief convert to T + * @param - + * @return T + * @globalvars none + * @exception none + * @conditions none + */ + operator T() + { + return m_value; + } + /** * @method operator< * @brief implementation of operator < @@ -300,8 +314,11 @@ class CDatT T m_value; }; - -/** define CDat */ +/** + * @class CDat + * + * Datatype for CCPU and CMem + */ typedef CDatT CDat; #endif diff --git a/ue3/mycpu/cdisplay.h b/ue3/mycpu/cdisplay.h new file mode 100644 index 0000000..629ec88 --- /dev/null +++ b/ue3/mycpu/cdisplay.h @@ -0,0 +1,48 @@ +/** + * @module cdisplay + * @author Guenther Neuwirth (0626638), Manuel Mausz (0728348) + * @brief TODO + * @date 10.05.2009 + */ + +#ifndef CDISPLAY_H +#define CDISPLAY_H #1 + +/** + * @class CDisplay + * + * TODO + */ +class CDisplay +{ + public: + /** + * @method CDisplay + * @brief Default ctor + * @param - + * @return - + * @globalvars none + * @exception none + * @conditions none + */ + CDisplay() + {}; + + /** + * @method ~CDisplay + * @brief Default dtor + * @param - + * @return - + * @globalvars none + * @exception none + * @conditions none + */ + ~CDisplay(); + + private: + /* members */ +}; + +#endif + +/* vim: set et sw=2 ts=2: */ diff --git a/ue3/mycpu/cinstruction.cpp b/ue3/mycpu/cinstruction.cpp new file mode 100644 index 0000000..32bdd2f --- /dev/null +++ b/ue3/mycpu/cinstruction.cpp @@ -0,0 +1,46 @@ +/** + * @module cinstruction + * @author Guenther Neuwirth (0626638), Manuel Mausz (0728348) + * @brief TODO + * @date 10.05.2009 + */ + +#include +#include +#include +#include "cinstruction.h" +#include "ccpu.h" + +using namespace std; + +const unsigned CInstruction::parseRegister(const std::string& str) +{ + unsigned reg; + if (str.length() < 2 || str[0] != 'R') + throw runtime_error("Invalid syntax of register"); + + try + { + reg = boost::lexical_cast(str.substr(1)); + } + catch(boost::bad_lexical_cast& ex) + { + throw runtime_error("Invalid syntax of register"); + } + + return reg; +} + +/*----------------------------------------------------------------------------*/ + +inline void CInstruction::checkRegister(CCPU *cpu, unsigned regidx) +{ + if (regidx >= cpu->getRegisterCount()) + { + stringstream sstr; + sstr << "Register R" << regidx << " doesn't exist (out of bound)"; + throw runtime_error(sstr.str()); + } +} + +/* vim: set et sw=2 ts=2: */ diff --git a/ue3/mycpu/cinstruction.h b/ue3/mycpu/cinstruction.h new file mode 100644 index 0000000..b16c067 --- /dev/null +++ b/ue3/mycpu/cinstruction.h @@ -0,0 +1,98 @@ +/** + * @module cinstruction + * @author Guenther Neuwirth (0626638), Manuel Mausz (0728348) + * @brief TODO + * @date 10.05.2009 + */ + +#ifndef CINSTRUCTION_H +#define CINSTRUCTION_H 1 + +#include +#include +//#include "ccpu.h" + +/* declare CCPU */ +class CCPU; + +/** + * @class CInstruction + * + * TODO + */ +class CInstruction +{ + public: + /** + * @method CInstruction + * @brief Default ctor + * @param - + * @return - + * @globalvars none + * @exception none + * @conditions none + */ + CInstruction(std::string name) + : m_name(name) + {}; + + /** + * @method ~CInstruction + * @brief Default dtor + * @param - + * @return - + * @globalvars none + * @exception none + * @conditions none + */ + virtual ~CInstruction() + {}; + + /* TODO */ + virtual bool operator==(std::string& name) + { + return name == m_name; + } + + /* TODO */ + virtual const std::string& getName() + { + return m_name; + } + + /* TODO */ + virtual std::ostream& dump(std::ostream& stream) + { + stream << m_name; + return stream; + } + + /* TODO */ + friend std::ostream& operator<<(std::ostream& stream, CInstruction& instr) + { + return instr.dump(stream); + } + + /* TODO */ + virtual const unsigned parseRegister(const std::string& str); + + /* TODO */ + virtual void checkRegister(CCPU *cpu, unsigned regidx); + + /* TODO */ + virtual CInstruction *factory() = 0; + + /* TODO */ + virtual void compile(std::list& params) = 0; + + /* TODO */ + virtual void execute(CCPU *cpu) = 0; + + protected: + /* members */ + std::string m_name; +}; + +#endif + +/* vim: set et sw=2 ts=2: */ diff --git a/ue3/mycpu/cmem.h b/ue3/mycpu/cmem.h new file mode 100644 index 0000000..5045c34 --- /dev/null +++ b/ue3/mycpu/cmem.h @@ -0,0 +1,109 @@ +/** + * @module cmem + * @author Guenther Neuwirth (0626638), Manuel Mausz (0728348) + * @brief Memory template and memory definition for CCPU + * @date 10.05.2009 + */ + +#ifndef CMEM_H +#define CMEM_H 1 + +#include +#include +#include +#include +#include +#ifdef DEBUG +# include +# include +#endif +#include "cdat.h" + +/** + * @class CVectorMem + * + * Extends std::vector template for use as memory for CCPU. + */ +template > +class CVectorMem + : public std::vector +{ + public: + using std::vector::size; + using std::vector::at; + + /** + * @method initialize + * @brief initialize the vector with the content of istream. istream is + * read per line. empty lines will add unitialized elements. + * @param in inputstream to read from + * @return void + * @globalvars none + * @exception std::runtime_error + * @conditions none + */ + void initialize(std::istream& in) + { + if (!in.good()) + return; + + std::string line; + unsigned i = 0; + while (!in.eof() && in.good()) + { + ++i; + std::getline(in, line); + + /* skip last line if it's empty */ + if (line.empty() && in.eof()) + break; + + T value; + try + { + if (!line.empty()) + value = boost::lexical_cast(line); + } + catch(boost::bad_lexical_cast& ex) + { + std::stringstream sstr; + sstr << "Unable to convert input (line " << i << "): " << ex.what(); + throw std::runtime_error(sstr.str()); + } + + push_back(value); + } + } + +#if DEBUG + /** + * @method dump + * @brief dumps contents of vector to outputstream + * @param out outputstream to write to + * @return void + * @globalvars none + * @exception none + * @conditions none + */ + void dump(std::ostream& out) + { + out << "[MEMORY DUMP]" << std::endl; + for(unsigned i = 0; i < size(); ++i) + { + out << "[" << std::setw(4) << std::setfill('0') << i << "] " + << at(i) << std::endl; + } + } +#endif +}; + +/** + * @class CMem + * + * Memory definition for CCPU + */ +typedef CVectorMem CMem; + +#endif + +/* vim: set et sw=2 ts=2: */ diff --git a/ue3/mycpu/cprogram.cpp b/ue3/mycpu/cprogram.cpp new file mode 100644 index 0000000..03d4c30 --- /dev/null +++ b/ue3/mycpu/cprogram.cpp @@ -0,0 +1,126 @@ +/** + * @module cprogram + * @author Guenther Neuwirth (0626638), Manuel Mausz (0728348) + * @brief TODO + * @date 12.05.2009 + */ + +#include +#include +#ifdef DEBUG +# include +# include +#endif +#include "cprogram.h" +#include "instructions.h" + +using namespace std; + +CProgram::CProgram() +{ + m_instrset.insert(new CInstructionInc); +} + +/*----------------------------------------------------------------------------*/ + +CProgram::~CProgram() +{ + /* free instruction set */ + set::iterator it; + for (it = m_instrset.begin(); it != m_instrset.end(); ++it) + delete *it; + + /* free instruction */ + for (iterator it = begin(); it != end(); ++it) + delete *it; +} + +/*----------------------------------------------------------------------------*/ + +void CProgram::compile(std::istream& in) +{ + if (!in.good()) + return; + + string line; + unsigned i = 0; + while (!in.eof() && in.good()) + { + ++i; + + /* read stream per line */ + getline(in, line); + if (line.empty()) + continue; + + boost::trim(line); + + /* ignore comments */ + if (line.find_first_of('#') == 0) + continue; + + /* get instruction name */ + size_t pos = line.find_first_of(' '); + string instrname = line.substr(0, pos); + + /* search and create instruction */ + CInstruction *instrptr = NULL; + set::iterator it; + for (it = m_instrset.begin(); it != m_instrset.end(); ++it) + { + if (*(*it) == instrname) + { + instrptr = *it; + break; + } + } + if (instrptr == NULL) + { + stringstream sstr; + sstr << "Unknown instruction '" << instrname << "' on line " << i << "."; + throw runtime_error(sstr.str()); + } + + /* create instruction */ + CInstruction *instr = instrptr->factory(); + + /* parse instruction parameters */ + string params = (pos == string::npos) ? "" : line.substr(pos + 1); + boost::trim(params); + list instrparams; + boost::split(instrparams, params, boost::is_any_of(", "), boost::token_compress_on); + + /* let instruction parse the parameters. catch+throw exception */ + try + { + instr->compile(instrparams); + } + catch(runtime_error& ex) + { + stringstream sstr; + sstr << "Unable to compile instruction '" << instrname + << "' (line " << i << "): " << ex.what(); + throw runtime_error(sstr.str()); + } + + push_back(instr); + } +} + +/*----------------------------------------------------------------------------*/ + +#if DEBUG +void CProgram::dump(std::ostream& out) +{ + out << "[PROGRAM DUMP]" << endl; + unsigned i = 0; + for(iterator it = begin(); it < end(); ++it) + { + out << "[" << std::setw(4) << std::setfill('0') << i << "] " + << *(*it) << endl; + ++i; + } +} +#endif + +/* vim: set et sw=2 ts=2: */ diff --git a/ue3/mycpu/cprogram.h b/ue3/mycpu/cprogram.h new file mode 100644 index 0000000..bf161b8 --- /dev/null +++ b/ue3/mycpu/cprogram.h @@ -0,0 +1,78 @@ +/** + * @module cprogram + * @author Guenther Neuwirth (0626638), Manuel Mausz (0728348) + * @brief TODO + * @date 10.05.2009 + */ + +#ifndef CPROGRAM_H +#define CPROGRAM_H 1 + +#include +#include +#include "cinstruction.h" + +/** + * @class CProgram + * + * TODO + */ +class CProgram + : public std::vector +{ + public: + /** + * @method CProgram + * @brief Default ctor + * @param - + * @return - + * @globalvars none + * @exception none + * @conditions none + */ + CProgram(); + + /** + * @method ~CProgram + * @brief Default dtor + * @param - + * @return - + * @globalvars none + * @exception none + * @conditions none + */ + ~CProgram(); + + /** + * @method compile + * @brief create instructions from parsing stream + * @param in inputstream to read from + * @return void + * @globalvars none + * @exception std::runtime_error + * @conditions none + */ + void compile(std::istream& in); + +#if DEBUG + /** + * @method dump + * @brief dumps contents to outputstream + * @param out outputstream to write to + * @return void + * @globalvars none + * @exception none + * @conditions none + */ + void dump(std::ostream& out); +#endif + + private: + /* members */ + /** set of known instructions */ + std::set m_instrset; +}; + +#endif + +/* vim: set et sw=2 ts=2: */ diff --git a/ue3/mycpu/instructions.cpp b/ue3/mycpu/instructions.cpp new file mode 100644 index 0000000..c283e57 --- /dev/null +++ b/ue3/mycpu/instructions.cpp @@ -0,0 +1,27 @@ +/** + * @module instructions + * @author Guenther Neuwirth (0626638), Manuel Mausz (0728348) + * @brief TODO + * @date 10.05.2009 + */ + +#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()); +} + +/*----------------------------------------------------------------------------*/ + +void CInstructionInc::execute(CCPU *cpu) +{ + checkRegister(cpu, m_regidx1); + cpu->getRegisters()[m_regidx1]++; +} + +/* vim: set et sw=2 ts=2: */ diff --git a/ue3/mycpu/instructions.h b/ue3/mycpu/instructions.h new file mode 100644 index 0000000..ebd1533 --- /dev/null +++ b/ue3/mycpu/instructions.h @@ -0,0 +1,66 @@ +/** + * @module instructions + * @author Guenther Neuwirth (0626638), Manuel Mausz (0728348) + * @brief TODO + * @date 10.05.2009 + */ + +#ifndef INSTRUCTIONS_H +#define INSTRUCTIONS_H 1 + +#include "cinstruction.h" +#include "ccpu.h" + +/** + * @class CInstructionInc + * + * TODO + */ +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); + + /* TODO */ + void execute(CCPU *cpu); + + protected: + unsigned m_regidx1; +}; + +#endif + +/* vim: set et sw=2 ts=2: */ diff --git a/ue3/mycpu/mycpu.cpp b/ue3/mycpu/mycpu.cpp new file mode 100644 index 0000000..af91fe7 --- /dev/null +++ b/ue3/mycpu/mycpu.cpp @@ -0,0 +1,152 @@ +/** + * @module mycpu + * @author Guenther Neuwirth (0626638), Manuel Mausz (0728348) + * @brief TODO + * @date 11.05.2009 + * @par Exercise + * 3 + */ + +#include +#include +#include +#include +#include +#include "ccpu.h" +#include "cmem.h" +#include "cprogram.h" + +using namespace std; +namespace po = boost::program_options; + +/** TODO */ +void myterminate() +{ + cerr << "Unexpected termination" << endl; + abort(); +} + +/** + * @func main + * @brief program entry point + * @param argc standard parameter of main + * @param argv standard parameter of main + * @return 0 on success, not 0 otherwise + * @globalvars none + * @exception none + * @conditions none + * + * TODO + */ +int main(int argc, char* argv[]) +{ + //TODO set_terminate(myterminate); + string me(argv[0]); + + /* define commandline options */ + po::options_description desc("Allowed options"); + desc.add_options() + ("help,h", "this help message") + ("compile,c", po::value(), "input programfile") + ("memory,m", po::value(), "input memoryfile"); + + /* parse commandline options */ + po::variables_map vm; + try + { + po::store(po::parse_command_line(argc, argv, desc), vm); + po::notify(vm); + } + catch(po::error& ex) + { + cerr << me << ": Error: " << ex.what() << endl; + } + + /* print usage upon request or missing params */ + if (vm.count("help") || !vm.count("compile")) + { + cout << "Usage: " << me << " -c [-m ]" << endl; + cout << desc << endl; + return 0; + } + + /* create memory and optionally initialize memory from file */ + CMem memory; + if (vm.count("memory")) + { + string memoryfile(vm["memory"].as()); + ifstream file(memoryfile.c_str(), ios::in); + if (!file.is_open()) + { + cerr << me << ": Unable to open memoryfile '" << memoryfile << "' for reading." << endl; + return 1; + } + + try + { + memory.initialize(file); + file.close(); + } + catch(runtime_error& ex) + { + file.close(); + cerr << me << ": Error while reading from memoryfile:" << endl + << " " << ex.what() << endl; + return 1; + } + +#if DEBUG + memory.dump(cout); +#endif + } + + /* create program instance */ + CProgram program; + string programfile(vm["compile"].as()); + ifstream file(programfile.c_str(), ios::in); + if (!file.is_open()) + { + cerr << me << ": Unable to open programfile '" << programfile << "' for reading." << endl; + return 1; + } + + try + { + program.compile(file); + file.close(); + } + catch(runtime_error& ex) + { + file.close(); + cerr << me << ": Error while compiling programfile:" << endl + << " " << ex.what() << endl; + return 1; + } + +#if DEBUG + program.dump(cout); +#endif + + + /* create cpu and execute the program */ + try + { + CCPU cpu(256); + cpu.setMemory(&memory); + cpu.setProgram(&program); + cpu.run(); +#if DEBUG + cpu.dumpRegisters(cout); +#endif + } + catch(runtime_error& ex) + { + cerr << me << ": Error while executing program:" << endl + << " " << ex.what() << endl; + return 1; + } + + return 0; +} + +/* vim: set et sw=2 ts=2: */ -- cgit v1.2.3 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 (limited to 'ue3/mycpu') 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 From 431bbac5a99abbccf33500e22aa353ec792eff94 Mon Sep 17 00:00:00 2001 From: manuel Date: Wed, 13 May 2009 15:29:51 +0200 Subject: * adding -Wno-long-long to all Makefiles * adding execute operator to cinstruction * added labels map for better performance --- ue3/mycpu/ccpu.cpp | 2 +- ue3/mycpu/ccpu.h | 2 +- ue3/mycpu/cinstruction.h | 47 ++++++++++++--------------------- ue3/mycpu/cprogram.cpp | 21 +++++++++++++++ ue3/mycpu/cprogram.h | 27 +++++++++++++++++++ ue3/mycpu/instructions.cpp | 65 +++------------------------------------------- ue3/mycpu/instructions.h | 20 ++++---------- 7 files changed, 76 insertions(+), 108 deletions(-) (limited to 'ue3/mycpu') diff --git a/ue3/mycpu/ccpu.cpp b/ue3/mycpu/ccpu.cpp index b1539a4..16209e2 100644 --- a/ue3/mycpu/ccpu.cpp +++ b/ue3/mycpu/ccpu.cpp @@ -66,7 +66,7 @@ void CCPU::run() throw runtime_error("Programcounter is out of bound"); /* execute instruction */ - m_program->at(pc)->execute(this); + (*m_program->at(pc))(this); ++m_registers[0]; } } diff --git a/ue3/mycpu/ccpu.h b/ue3/mycpu/ccpu.h index 1ef1923..01c897f 100644 --- a/ue3/mycpu/ccpu.h +++ b/ue3/mycpu/ccpu.h @@ -205,7 +205,7 @@ class CCPU * @param - * @return - * @globalvars none - * @exception runtime_error + * @exception std::runtime_error * @conditions none */ void run(); diff --git a/ue3/mycpu/cinstruction.h b/ue3/mycpu/cinstruction.h index 57fcff1..40e9ddc 100644 --- a/ue3/mycpu/cinstruction.h +++ b/ue3/mycpu/cinstruction.h @@ -62,45 +62,32 @@ class CInstruction } /** - * @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; - } - - /** - * @method isLabel - * @brief returns true if the instruction defines a label - * @param - - * @return true if the instruction defines a label + * @method operator() + * @brief implementation of operator (CCPU) + * @param cpu pointer to cpu + * @return - * @globalvars none - * @exception none + * @exception std::runtime_error * @conditions none */ - virtual const bool isLabel() + virtual CInstruction& operator()(CCPU *cpu) { - return false; + execute(cpu); + return *this; } /** - * @method getLabelName - * @brief returns labelname if the instruction defines a label + * @method getName + * @brief returns instruction name * @param - - * @return labelname if the instruction defines a label + * @return name of instruction * @globalvars none * @exception none * @conditions none */ - virtual const std::string getLabelName() + virtual const std::string& getName() { - return ""; + return m_name; } /** @@ -139,7 +126,7 @@ class CInstruction * @param str register in assembler syntax * @return registernumber * @globalvars none - * @exception runtime_error + * @exception std::runtime_error * @conditions none */ virtual const unsigned parseRegister(const std::string& str); @@ -152,7 +139,7 @@ class CInstruction * @param regidx registernumber * @return - * @globalvars none - * @exception runtime_error + * @exception std::runtime_error * @conditions none */ virtual void checkRegister(CCPU *cpu, const unsigned regidx); @@ -175,7 +162,7 @@ class CInstruction * @param params list of parameters of this instruction * @return - * @globalvars none - * @exception runtime_error + * @exception std::runtime_error * @conditions none */ virtual void compile(std::list& params) = 0; @@ -186,7 +173,7 @@ class CInstruction * @param cpu pointer to cpu * @return - * @globalvars none - * @exception runtime_error + * @exception std::runtime_error * @conditions none */ virtual void execute(CCPU *cpu) = 0; diff --git a/ue3/mycpu/cprogram.cpp b/ue3/mycpu/cprogram.cpp index f6fc3cb..f904bce 100644 --- a/ue3/mycpu/cprogram.cpp +++ b/ue3/mycpu/cprogram.cpp @@ -107,6 +107,16 @@ void CProgram::compile(std::istream& in) /* let instruction parse the parameters. catch+throw exception */ try { + /* handle label instruction ourself, but still add a dummy instruction */ + if (instrname == "label") + { + if (instrparams.size() != 1) + throw runtime_error("Invalid paramater count - must be 1"); + string label = instrparams.front(); + if (label.length() < 2 || label[ label.length() - 1] != ':') + throw runtime_error("Label has invalid syntax"); + m_labels[ label.substr(0, label.length() - 1) ] = size(); + } instr->compile(instrparams); } catch(runtime_error& ex) @@ -123,6 +133,17 @@ void CProgram::compile(std::istream& in) /*----------------------------------------------------------------------------*/ +unsigned CProgram::findLabel(const std::string& label) const +{ + map::const_iterator it; + it = m_labels.find(label); + if (it == m_labels.end()) + throw runtime_error("Unknown label '" + label + "'"); + return it->second; +} + +/*----------------------------------------------------------------------------*/ + #if DEBUG void CProgram::dump(std::ostream& out) { diff --git a/ue3/mycpu/cprogram.h b/ue3/mycpu/cprogram.h index bf161b8..c145832 100644 --- a/ue3/mycpu/cprogram.h +++ b/ue3/mycpu/cprogram.h @@ -10,6 +10,7 @@ #include #include +#include #include "cinstruction.h" /** @@ -43,6 +44,31 @@ class CProgram */ ~CProgram(); + /** + * @method getLabels + * @brief get reference to labels map + * @param - + * @return reference to labels map + * @globalvars none + * @exception none + * @conditions none + */ + const std::map& getLabels() const + { + return m_labels; + } + + /** + * @method findLabel + * @brief search for label + * @param label name of label to search for + * @return index of found label in program + * @globalvars none + * @exception std::runtime_error + * @conditions none + */ + unsigned findLabel(const std::string& label) const; + /** * @method compile * @brief create instructions from parsing stream @@ -71,6 +97,7 @@ class CProgram /* members */ /** set of known instructions */ std::set m_instrset; + std::map m_labels; }; #endif diff --git a/ue3/mycpu/instructions.cpp b/ue3/mycpu/instructions.cpp index 609cd1c..a6ac611 100644 --- a/ue3/mycpu/instructions.cpp +++ b/ue3/mycpu/instructions.cpp @@ -5,6 +5,7 @@ * @date 10.05.2009 */ +#include #include "instructions.h" using namespace std; @@ -210,27 +211,6 @@ void CInstructionTest::execute(CCPU *cpu) /*============================================================================*/ -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) @@ -245,18 +225,7 @@ 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 + "'"); + cpu->getRegisters()[ 0 ] = cpu->getProgram()->findLabel(m_addr); } /*============================================================================*/ @@ -275,20 +244,7 @@ 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 + "'"); + cpu->getRegisters()[ 0 ] = cpu->getProgram()->findLabel(m_addr); } /*============================================================================*/ @@ -307,20 +263,7 @@ 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 + "'"); + cpu->getRegisters()[ 0 ] = cpu->getProgram()->findLabel(m_addr); } /*============================================================================*/ diff --git a/ue3/mycpu/instructions.h b/ue3/mycpu/instructions.h index 8c62e0b..0e4d99c 100644 --- a/ue3/mycpu/instructions.h +++ b/ue3/mycpu/instructions.h @@ -274,29 +274,19 @@ class CInstructionLabel { public: CInstructionLabel() - : CInstruction("label"), m_label("") + : CInstruction("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); + void compile(std::list& params) + {} - protected: - std::string m_label; + void execute(CCPU *cpu) + {} }; /*============================================================================*/ -- cgit v1.2.3 From 3c6f886d5a8bfd36c796b963d6e3178ad9577742 Mon Sep 17 00:00:00 2001 From: manuel Date: Wed, 13 May 2009 16:55:17 +0200 Subject: * added documentation (no more TODOs) * added testsuite + testcase * used copyctor instead of assign operator more often --- ue3/mycpu/ccpu.cpp | 3 ++- ue3/mycpu/ccpu.h | 6 +++-- ue3/mycpu/cdisplay.h | 9 ++++--- ue3/mycpu/cinstruction.cpp | 4 ++-- ue3/mycpu/cinstruction.h | 6 ++--- ue3/mycpu/cprogram.cpp | 6 ++--- ue3/mycpu/cprogram.h | 5 ++-- ue3/mycpu/displays.h | 8 ++++--- ue3/mycpu/instructions.cpp | 6 ++--- ue3/mycpu/instructions.h | 57 ++++++++++++++++++++++++++++++++------------ ue3/mycpu/mycpu.cpp | 25 ++++++++++++------- ue3/mycpu/test/test.sh | 40 +++++++++++++++++++++++++++++++ ue3/mycpu/test/test1_memory | 1 + ue3/mycpu/test/test1_output | 19 +++++++++++++++ ue3/mycpu/test/test1_program | 13 ++++++++++ 15 files changed, 160 insertions(+), 48 deletions(-) create mode 100755 ue3/mycpu/test/test.sh create mode 100644 ue3/mycpu/test/test1_memory create mode 100644 ue3/mycpu/test/test1_output create mode 100644 ue3/mycpu/test/test1_program (limited to 'ue3/mycpu') diff --git a/ue3/mycpu/ccpu.cpp b/ue3/mycpu/ccpu.cpp index 16209e2..af86200 100644 --- a/ue3/mycpu/ccpu.cpp +++ b/ue3/mycpu/ccpu.cpp @@ -1,7 +1,8 @@ /** * @module ccpu * @author Guenther Neuwirth (0626638), Manuel Mausz (0728348) - * @brief TODO + * @brief CPU implementation. Used as a container for memory and instructions. + * Implements an run method to execute the program (= the instructions). * @date 10.05.2009 */ diff --git a/ue3/mycpu/ccpu.h b/ue3/mycpu/ccpu.h index 01c897f..05b5c03 100644 --- a/ue3/mycpu/ccpu.h +++ b/ue3/mycpu/ccpu.h @@ -1,7 +1,8 @@ /** * @module ccpu * @author Guenther Neuwirth (0626638), Manuel Mausz (0728348) - * @brief TODO + * @brief CPU implementation. Used as a container for memory and instructions. + * Implements a run method to execute the program (= the instructions). * @date 10.05.2009 */ @@ -18,7 +19,8 @@ /** * @class CCPU * - * TODO + * CPU implementation. Used as a container for memory and instructions. + * Implements a run method to execute the program (= the instructions). */ class CCPU { diff --git a/ue3/mycpu/cdisplay.h b/ue3/mycpu/cdisplay.h index ed9b84d..c2a84a6 100644 --- a/ue3/mycpu/cdisplay.h +++ b/ue3/mycpu/cdisplay.h @@ -1,7 +1,7 @@ /** * @module cdisplay * @author Guenther Neuwirth (0626638), Manuel Mausz (0728348) - * @brief TODO + * @brief Abstract class for displays * @date 10.05.2009 */ @@ -11,7 +11,7 @@ /** * @class CDisplay * - * TODO + * Abstract class for displays */ class CDisplay { @@ -26,9 +26,8 @@ class CDisplay * @conditions none */ CDisplay(std::string name) - { - m_name = name; - } + : m_name(name) + {} /** * @method ~CDisplay diff --git a/ue3/mycpu/cinstruction.cpp b/ue3/mycpu/cinstruction.cpp index 57acd5f..5c1bd5c 100644 --- a/ue3/mycpu/cinstruction.cpp +++ b/ue3/mycpu/cinstruction.cpp @@ -1,8 +1,8 @@ /** * @module cinstruction * @author Guenther Neuwirth (0626638), Manuel Mausz (0728348) - * @brief TODO - * @date 10.05.2009 + * @brief Abstract class for displays + * @date 13.05.2009 */ #include diff --git a/ue3/mycpu/cinstruction.h b/ue3/mycpu/cinstruction.h index 40e9ddc..942d8cf 100644 --- a/ue3/mycpu/cinstruction.h +++ b/ue3/mycpu/cinstruction.h @@ -1,8 +1,8 @@ /** * @module cinstruction * @author Guenther Neuwirth (0626638), Manuel Mausz (0728348) - * @brief TODO - * @date 10.05.2009 + * @brief Abstract class for displays + * @date 13.05.2009 */ #ifndef CINSTRUCTION_H @@ -17,7 +17,7 @@ class CCPU; /** * @class CInstruction * - * TODO + * Abstract class for displays */ class CInstruction { diff --git a/ue3/mycpu/cprogram.cpp b/ue3/mycpu/cprogram.cpp index f904bce..1a450f5 100644 --- a/ue3/mycpu/cprogram.cpp +++ b/ue3/mycpu/cprogram.cpp @@ -1,7 +1,7 @@ /** * @module cprogram * @author Guenther Neuwirth (0626638), Manuel Mausz (0728348) - * @brief TODO + * @brief CProgram extends std::vector and adds a method for parsing programfile * @date 12.05.2009 */ @@ -75,7 +75,7 @@ void CProgram::compile(std::istream& in) /* get instruction name */ size_t pos = line.find_first_of(' '); - string instrname = line.substr(0, pos); + string instrname(line.substr(0, pos)); /* search and create instruction */ CInstruction *instrptr = NULL; @@ -112,7 +112,7 @@ void CProgram::compile(std::istream& in) { if (instrparams.size() != 1) throw runtime_error("Invalid paramater count - must be 1"); - string label = instrparams.front(); + string label(instrparams.front()); if (label.length() < 2 || label[ label.length() - 1] != ':') throw runtime_error("Label has invalid syntax"); m_labels[ label.substr(0, label.length() - 1) ] = size(); diff --git a/ue3/mycpu/cprogram.h b/ue3/mycpu/cprogram.h index c145832..27e7647 100644 --- a/ue3/mycpu/cprogram.h +++ b/ue3/mycpu/cprogram.h @@ -1,7 +1,7 @@ /** * @module cprogram * @author Guenther Neuwirth (0626638), Manuel Mausz (0728348) - * @brief TODO + * @brief CProgram extends std::vector and adds a method for parsing programfile * @date 10.05.2009 */ @@ -16,7 +16,8 @@ /** * @class CProgram * - * TODO + * CProgram extends std::vector and adds a method for parsing + * programfile. This adds instances of CInstruction to CProgram itself. */ class CProgram : public std::vector diff --git a/ue3/mycpu/displays.h b/ue3/mycpu/displays.h index f7adbdb..87b9408 100644 --- a/ue3/mycpu/displays.h +++ b/ue3/mycpu/displays.h @@ -1,7 +1,7 @@ /** * @module displays * @author Guenther Neuwirth (0626638), Manuel Mausz (0728348) - * @brief TODO + * @brief Implementations of CDisplay * @date 10.05.2009 */ @@ -14,7 +14,8 @@ /** * @class CDisplayWDEZ * - * TODO + * Implementation of CDisplay + * Prints CDat to stdout as decimal */ class CDisplayWDEZ : public CDisplay @@ -35,7 +36,8 @@ class CDisplayWDEZ /** * @class CDisplayWHEX * - * TODO + * Implementation of CDisplay + * Prints CDat to stdout as decimal */ class CDisplayWHEX : public CDisplay diff --git a/ue3/mycpu/instructions.cpp b/ue3/mycpu/instructions.cpp index a6ac611..c2ce096 100644 --- a/ue3/mycpu/instructions.cpp +++ b/ue3/mycpu/instructions.cpp @@ -1,7 +1,7 @@ /** * @module instructions * @author Guenther Neuwirth (0626638), Manuel Mausz (0728348) - * @brief TODO + * @brief Implementations of CInstruction * @date 10.05.2009 */ @@ -162,7 +162,7 @@ void CInstructionLoad::execute(CCPU *cpu) { checkRegister(cpu, m_regidx1); checkRegister(cpu, m_regidx2); - CDat val = cpu->getRegisters()[ m_regidx2 ]; + CDat val(cpu->getRegisters()[ m_regidx2 ]); cpu->getRegisters()[ m_regidx1 ] = (*cpu->getMemory())[ val ]; } @@ -184,7 +184,7 @@ void CInstructionStore::execute(CCPU *cpu) { checkRegister(cpu, m_regidx1); checkRegister(cpu, m_regidx2); - CDat val = cpu->getRegisters()[ m_regidx2 ]; + CDat val(cpu->getRegisters()[ m_regidx2 ]); (*cpu->getMemory())[ val ] = cpu->getRegisters()[ m_regidx1 ]; } diff --git a/ue3/mycpu/instructions.h b/ue3/mycpu/instructions.h index 0e4d99c..a52b991 100644 --- a/ue3/mycpu/instructions.h +++ b/ue3/mycpu/instructions.h @@ -1,7 +1,7 @@ /** * @module instructions * @author Guenther Neuwirth (0626638), Manuel Mausz (0728348) - * @brief TODO + * @brief Implementations of CInstruction * @date 10.05.2009 */ @@ -14,7 +14,9 @@ /** * @class CInstructionInc * - * TODO + * Implementation of assembler command "inc" + * Syntax: inc R1 + * (R1++) */ class CInstructionInc : public CInstruction @@ -41,7 +43,9 @@ class CInstructionInc /** * @class CInstructionDec * - * TODO + * Implementation of assembler command "dec" + * Syntax: dec R1 + * (R1--) */ class CInstructionDec : public CInstruction @@ -68,7 +72,9 @@ class CInstructionDec /** * @class CInstructionAdd * - * TODO + * Implementation of assembler command "add" + * Syntax: add R1, R2, R3 + * (R1 = R2 + R3) */ class CInstructionAdd : public CInstruction @@ -97,7 +103,9 @@ class CInstructionAdd /** * @class CInstructionSub * - * TODO + * Implementation of assembler command "sub" + * Syntax: sub R1, R2, R3 + * (R1 = R2 - R3) */ class CInstructionSub : public CInstruction @@ -126,7 +134,9 @@ class CInstructionSub /** * @class CInstructionMul * - * TODO + * Implementation of assembler command "mul" + * Syntax: mul R1, R2, R3 + * (R1 = R2 * R3) */ class CInstructionMul : public CInstruction @@ -155,7 +165,9 @@ class CInstructionMul /** * @class CInstructionDiv * - * TODO + * Implementation of assembler command "div" + * Syntax: div R1, R2, R3 + * (R1 = R2 / R3) */ class CInstructionDiv : public CInstruction @@ -184,7 +196,9 @@ class CInstructionDiv /** * @class CInstructionLoad * - * TODO + * Implementation of assembler command "load" + * Syntax: load R1, R2 + * (R1 = memory[R2]) */ class CInstructionLoad : public CInstruction @@ -212,7 +226,9 @@ class CInstructionLoad /** * @class CInstructionStore * - * TODO + * Implementation of assembler command "store" + * Syntax: store R1, R2 + * (memory[R2] = R1) */ class CInstructionStore : public CInstruction @@ -240,7 +256,9 @@ class CInstructionStore /** * @class CInstructionTest * - * TODO + * Implementation of assembler command "test" + * Syntax: test R1 + * (R1 == 0: zeroflag: true, R1 < 0: signflag: true) */ class CInstructionTest : public CInstruction @@ -267,7 +285,8 @@ class CInstructionTest /** * @class CInstructionLabel * - * TODO + * Implementation of assembler command "label" + * Syntax: label name: */ class CInstructionLabel : public CInstruction @@ -294,7 +313,9 @@ class CInstructionLabel /** * @class CInstructionJumpA * - * TODO + * Implementation of assembler command "jumpa" + * Syntax: jumpa labelname + * (jump to labelname) */ class CInstructionJumpA : public CInstruction @@ -321,7 +342,9 @@ class CInstructionJumpA /** * @class CInstructionJumpZ * - * TODO + * Implementation of assembler command "jumpz" + * Syntax: jumpz labelname + * (jump to labelname if zeroflag) */ class CInstructionJumpZ : public CInstruction @@ -348,7 +371,9 @@ class CInstructionJumpZ /** * @class CInstructionJumpS * - * TODO + * Implementation of assembler command "jumps" + * Syntax: jumps labelname + * (jump to labelname if signflag) */ class CInstructionJumpS : public CInstruction @@ -375,7 +400,9 @@ class CInstructionJumpS /** * @class CInstructionWrite * - * TODO + * Implementation of assembler command "write" + * Syntax: write DEV, R1 + * (write R1 to DEV, which is a name of a display) */ class CInstructionWrite : public CInstruction diff --git a/ue3/mycpu/mycpu.cpp b/ue3/mycpu/mycpu.cpp index 08861a4..b25e721 100644 --- a/ue3/mycpu/mycpu.cpp +++ b/ue3/mycpu/mycpu.cpp @@ -1,10 +1,14 @@ /** * @module mycpu * @author Guenther Neuwirth (0626638), Manuel Mausz (0728348) - * @brief TODO - * @date 11.05.2009 + * @brief mycpu executes a programfile (in simple assembler) by parsing the + * programfile first. This creates a vector of instructions, which will + * be executed in linear order (except jumps) afterwards. In order to + * initialize the memory of the cpu before execution an optional + * memoryfile can be passed as commandline option. + * @date 13.05.2009 * @par Exercise - * 3 + * 4 */ #include @@ -29,7 +33,11 @@ namespace po = boost::program_options; * @exception none * @conditions none * - * TODO + * parse commandline options, create and initialize memory, + * create cprogram instance, which parses the programfile and + * execute CCPU::run() + * On error print error message to stderr. + * Unknown commandline options will print a usage message. */ int main(int argc, char* argv[]) { @@ -88,7 +96,7 @@ int main(int argc, char* argv[]) } #if DEBUG - memory.dump(cout); + memory.dump(cerr); #endif } @@ -116,7 +124,7 @@ int main(int argc, char* argv[]) } #if DEBUG - program.dump(cout); + program.dump(cerr); #endif @@ -128,7 +136,7 @@ int main(int argc, char* argv[]) cpu.setProgram(&program); cpu.run(); #if DEBUG - //cpu.dumpRegisters(cout); + //cpu.dumpRegisters(cerr); #endif } catch(runtime_error& ex) @@ -136,8 +144,7 @@ int main(int argc, char* argv[]) cerr << me << ": Error while executing program:" << endl << " " << ex.what() << endl; #if DEBUG - memory.dump(cout); - //cpu.dumpRegisters(cout); + memory.dump(cerr); #endif return 1; } diff --git a/ue3/mycpu/test/test.sh b/ue3/mycpu/test/test.sh new file mode 100755 index 0000000..ad2ae4d --- /dev/null +++ b/ue3/mycpu/test/test.sh @@ -0,0 +1,40 @@ +#!/bin/bash + +binary="./mycpu" +tmpfile="test/tmpfile" +inputs=( $(ls test/* | grep _program | sort -n) ) + +for input in ${inputs[@]} +do + echo "Testing $input ..." + + programfile="$input" + args="-c $programfile" + memoryfile="${input/_program/_memory}" + reffile="${input/_program/_output}" + if [ -e "$memoryfile" ] + then + args+=" -m $memoryfile" + fi + + if [ ! -e "$reffile" ] + then + echo " ERROR: reference file $reffile doesn't exist" + exit 1 + fi + + rm -rf "$tmpfile" + echo " Executing $binary $args ..." + $binary $args > $tmpfile + + md5_1=$(md5sum < "$reffile") + md5_2=$(md5sum < "$tmpfile") + if [ "$md5_1" != "$md5_2" ] + then + echo " ERROR: output and $reffile differ" + diff -Nau $reffile $tmpfile + exit 1 + else + echo " SUCCESS" + fi +done diff --git a/ue3/mycpu/test/test1_memory b/ue3/mycpu/test/test1_memory new file mode 100644 index 0000000..209e3ef --- /dev/null +++ b/ue3/mycpu/test/test1_memory @@ -0,0 +1 @@ +20 diff --git a/ue3/mycpu/test/test1_output b/ue3/mycpu/test/test1_output new file mode 100644 index 0000000..ac30dc2 --- /dev/null +++ b/ue3/mycpu/test/test1_output @@ -0,0 +1,19 @@ +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 diff --git a/ue3/mycpu/test/test1_program b/ue3/mycpu/test/test1_program new file mode 100644 index 0000000..ae5e9d2 --- /dev/null +++ b/ue3/mycpu/test/test1_program @@ -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 From 67e99a217bd88a289d997b73f3e7cae6019bc22f Mon Sep 17 00:00:00 2001 From: manuel Date: Wed, 13 May 2009 17:01:15 +0200 Subject: fixing doxygen documentation --- ue3/mycpu/ccpu.h | 2 +- ue3/mycpu/cdat.h | 20 ++++++++++---------- ue3/mycpu/cdisplay.h | 1 + ue3/mycpu/cinstruction.h | 5 +++-- ue3/mycpu/instructions.h | 24 ++++++++++++++++++++++++ 5 files changed, 39 insertions(+), 13 deletions(-) (limited to 'ue3/mycpu') diff --git a/ue3/mycpu/ccpu.h b/ue3/mycpu/ccpu.h index 05b5c03..6849623 100644 --- a/ue3/mycpu/ccpu.h +++ b/ue3/mycpu/ccpu.h @@ -106,7 +106,7 @@ class CCPU /** * @method setProgram * @brief set program to execute - * @param memory pointer to program + * @param program pointer to program * @return - * @globalvars none * @exception none diff --git a/ue3/mycpu/cdat.h b/ue3/mycpu/cdat.h index c656b99..a533fae 100644 --- a/ue3/mycpu/cdat.h +++ b/ue3/mycpu/cdat.h @@ -102,7 +102,7 @@ class CDatT /** * @method operator< * @brief implementation of operator < - * @param reference to CDatT + * @param x reference to CDatT * @return true if cdat is less than object x * @globalvars none * @exception none @@ -116,7 +116,7 @@ class CDatT /** * @method operator== * @brief implementation of operator == - * @param reference to CDatT + * @param x reference to CDatT * @return true if cdat equals object x * @globalvars none * @exception none @@ -130,7 +130,7 @@ class CDatT /** * @method operator+= * @brief implementation of operator += - * @param reference to CDatT + * @param x reference to CDatT * @return refecence to CDatT * @globalvars none * @exception none @@ -145,7 +145,7 @@ class CDatT /** * @method operator-= * @brief implementation of operator -= - * @param reference to CDatT + * @param x reference to CDatT * @return refecence to CDatT * @globalvars none * @exception none @@ -160,7 +160,7 @@ class CDatT /** * @method operator*= * @brief implementation of operator *= - * @param reference to CDatT + * @param x reference to CDatT * @return refecence to CDatT * @globalvars none * @exception none @@ -175,7 +175,7 @@ class CDatT /** * @method operator/= * @brief implementation of operator /= - * @param reference to CDatT + * @param x reference to CDatT * @return refecence to CDatT * @globalvars none * @exception none @@ -190,7 +190,7 @@ class CDatT /** * @method operator%= * @brief implementation of operator %= - * @param reference to CDatT + * @param x reference to CDatT * @return refecence to CDatT * @globalvars none * @exception none @@ -205,7 +205,7 @@ class CDatT /** * @method operator|= * @brief implementation of operator |= - * @param reference to CDatT + * @param x reference to CDatT * @return refecence to CDatT * @globalvars none * @exception none @@ -220,7 +220,7 @@ class CDatT /** * @method operator&= * @brief implementation of operator &= - * @param reference to CDatT + * @param x reference to CDatT * @return refecence to CDatT * @globalvars none * @exception none @@ -235,7 +235,7 @@ class CDatT /** * @method operator^= * @brief implementation of operator ^= - * @param reference to CDatT + * @param x reference to CDatT * @return refecence to CDatT * @globalvars none * @exception none diff --git a/ue3/mycpu/cdisplay.h b/ue3/mycpu/cdisplay.h index c2a84a6..0a0a723 100644 --- a/ue3/mycpu/cdisplay.h +++ b/ue3/mycpu/cdisplay.h @@ -68,6 +68,7 @@ class CDisplay protected: /* members */ + /** name of display */ std::string m_name; }; diff --git a/ue3/mycpu/cinstruction.h b/ue3/mycpu/cinstruction.h index 942d8cf..4cc69de 100644 --- a/ue3/mycpu/cinstruction.h +++ b/ue3/mycpu/cinstruction.h @@ -50,7 +50,7 @@ class CInstruction /** * @method operator== * @brief implementation of operator == - * @param reference to std::string + * @param name reference to std::string * @return true if instructionname is name * @globalvars none * @exception none @@ -109,7 +109,7 @@ class CInstruction * @method operator<< * @brief Shift/output operator for outputstream * @param stream reference to outputstream - * @param cdat object which will be printed to stream + * @param instr object which will be printed to stream * @return reference to outputstream * @globalvars none * @exception none @@ -180,6 +180,7 @@ class CInstruction protected: /* members */ + /** name of instruction */ std::string m_name; }; diff --git a/ue3/mycpu/instructions.h b/ue3/mycpu/instructions.h index a52b991..4c36562 100644 --- a/ue3/mycpu/instructions.h +++ b/ue3/mycpu/instructions.h @@ -35,6 +35,7 @@ class CInstructionInc void execute(CCPU *cpu); protected: + /** register number */ unsigned m_regidx1; }; @@ -64,6 +65,7 @@ class CInstructionDec void execute(CCPU *cpu); protected: + /** register number */ unsigned m_regidx1; }; @@ -93,8 +95,11 @@ class CInstructionAdd void execute(CCPU *cpu); protected: + /** register number */ unsigned m_regidx1; + /** register number */ unsigned m_regidx2; + /** register number */ unsigned m_regidx3; }; @@ -124,8 +129,11 @@ class CInstructionSub void execute(CCPU *cpu); protected: + /** register number */ unsigned m_regidx1; + /** register number */ unsigned m_regidx2; + /** register number */ unsigned m_regidx3; }; @@ -155,8 +163,11 @@ class CInstructionMul void execute(CCPU *cpu); protected: + /** register number */ unsigned m_regidx1; + /** register number */ unsigned m_regidx2; + /** register number */ unsigned m_regidx3; }; @@ -186,8 +197,11 @@ class CInstructionDiv void execute(CCPU *cpu); protected: + /** register number */ unsigned m_regidx1; + /** register number */ unsigned m_regidx2; + /** register number */ unsigned m_regidx3; }; @@ -217,7 +231,9 @@ class CInstructionLoad void execute(CCPU *cpu); protected: + /** register number */ unsigned m_regidx1; + /** register number */ unsigned m_regidx2; }; @@ -247,7 +263,9 @@ class CInstructionStore void execute(CCPU *cpu); protected: + /** register number */ unsigned m_regidx1; + /** register number */ unsigned m_regidx2; }; @@ -277,6 +295,7 @@ class CInstructionTest void execute(CCPU *cpu); protected: + /** register number */ unsigned m_regidx1; }; @@ -334,6 +353,7 @@ class CInstructionJumpA void execute(CCPU *cpu); protected: + /** labelname */ std::string m_addr; }; @@ -363,6 +383,7 @@ class CInstructionJumpZ void execute(CCPU *cpu); protected: + /** labelname */ std::string m_addr; }; @@ -392,6 +413,7 @@ class CInstructionJumpS void execute(CCPU *cpu); protected: + /** labelname */ std::string m_addr; }; @@ -421,7 +443,9 @@ class CInstructionWrite void execute(CCPU *cpu); protected: + /** register number */ unsigned m_regidx1; + /** device name */ std::string m_dev; }; -- cgit v1.2.3 From 9e7c204525a50f36ba7aa7563f1a9702d0bb6f44 Mon Sep 17 00:00:00 2001 From: manuel Date: Wed, 13 May 2009 17:11:40 +0200 Subject: adding tab as whitespace --- ue3/mycpu/cprogram.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'ue3/mycpu') diff --git a/ue3/mycpu/cprogram.cpp b/ue3/mycpu/cprogram.cpp index 1a450f5..3fcf734 100644 --- a/ue3/mycpu/cprogram.cpp +++ b/ue3/mycpu/cprogram.cpp @@ -102,7 +102,7 @@ void CProgram::compile(std::istream& in) string params = (pos == string::npos) ? "" : line.substr(pos + 1); boost::trim(params); list instrparams; - boost::split(instrparams, params, boost::is_any_of(", "), boost::token_compress_on); + boost::split(instrparams, params, boost::is_any_of(", \t"), boost::token_compress_on); /* let instruction parse the parameters. catch+throw exception */ try -- cgit v1.2.3 From ad6ca84f6e93f983de926ae71f31f42325986f61 Mon Sep 17 00:00:00 2001 From: manuel Date: Thu, 14 May 2009 18:15:28 +0200 Subject: * making cdisplay a template * adding some asserts * adding classdiagramm and protokoll * fixing protokoll.pdf in ue1 --- ue3/mycpu/cdisplay.h | 26 +++++++++++++++++--------- ue3/mycpu/cinstruction.cpp | 2 ++ ue3/mycpu/instructions.cpp | 34 ++++++++++++++++++++++++++++++++++ ue3/mycpu/test/memory1 | 1 - ue3/mycpu/test/program1 | 13 ------------- ue3/mycpu/test/test.sh | 4 +++- 6 files changed, 56 insertions(+), 24 deletions(-) delete mode 100644 ue3/mycpu/test/memory1 delete mode 100644 ue3/mycpu/test/program1 (limited to 'ue3/mycpu') diff --git a/ue3/mycpu/cdisplay.h b/ue3/mycpu/cdisplay.h index 0a0a723..1523f68 100644 --- a/ue3/mycpu/cdisplay.h +++ b/ue3/mycpu/cdisplay.h @@ -1,7 +1,7 @@ /** * @module cdisplay * @author Guenther Neuwirth (0626638), Manuel Mausz (0728348) - * @brief Abstract class for displays + * @brief Abstract template class for displays * @date 10.05.2009 */ @@ -9,15 +9,16 @@ #define CDISPLAY_H 1 /** - * @class CDisplay + * @class CDisplayT * - * Abstract class for displays + * Abstract template class for displays */ -class CDisplay +template +class CDisplayT { public: /** - * @method CDisplay + * @method CDisplayT * @brief Default ctor * @param name name of display * @return - @@ -25,12 +26,12 @@ class CDisplay * @exception none * @conditions none */ - CDisplay(std::string name) + CDisplayT(std::string name) : m_name(name) {} /** - * @method ~CDisplay + * @method ~CDisplayT * @brief Default dtor * @param - * @return - @@ -38,7 +39,7 @@ class CDisplay * @exception none * @conditions none */ - virtual ~CDisplay() + virtual ~CDisplayT() {} /** @@ -64,7 +65,7 @@ class CDisplay * @exception none * @conditions none */ - virtual void display(const CDat &value) = 0; + virtual void display(const T &value) = 0; protected: /* members */ @@ -72,6 +73,13 @@ class CDisplay std::string m_name; }; +/** + * @class CDisplay + * + * Memory definition for CCPU + */ +typedef CDisplayT CDisplay; + #endif /* vim: set et sw=2 ts=2: */ diff --git a/ue3/mycpu/cinstruction.cpp b/ue3/mycpu/cinstruction.cpp index 5c1bd5c..a766015 100644 --- a/ue3/mycpu/cinstruction.cpp +++ b/ue3/mycpu/cinstruction.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #include "cinstruction.h" #include "ccpu.h" @@ -35,6 +36,7 @@ const unsigned CInstruction::parseRegister(const std::string& str) inline void CInstruction::checkRegister(CCPU *cpu, const unsigned regidx) { + assert(cpu != NULL); if (regidx >= cpu->getRegisterCount()) { stringstream sstr; diff --git a/ue3/mycpu/instructions.cpp b/ue3/mycpu/instructions.cpp index c2ce096..ef9e944 100644 --- a/ue3/mycpu/instructions.cpp +++ b/ue3/mycpu/instructions.cpp @@ -6,6 +6,7 @@ */ #include +#include #include "instructions.h" using namespace std; @@ -22,6 +23,8 @@ void CInstructionInc::compile(std::list& params) void CInstructionInc::execute(CCPU *cpu) { + assert(cpu != NULL); + assert(cpu->getRegisters() != NULL); checkRegister(cpu, m_regidx1); cpu->getRegisters()[ m_regidx1 ]++; } @@ -40,6 +43,8 @@ void CInstructionDec::compile(std::list& params) void CInstructionDec::execute(CCPU *cpu) { + assert(cpu != NULL); + assert(cpu->getRegisters() != NULL); checkRegister(cpu, m_regidx1); cpu->getRegisters()[ m_regidx1 ]--; } @@ -62,6 +67,8 @@ void CInstructionAdd::compile(std::list& params) void CInstructionAdd::execute(CCPU *cpu) { + assert(cpu != NULL); + assert(cpu->getRegisters() != NULL); checkRegister(cpu, m_regidx1); checkRegister(cpu, m_regidx2); checkRegister(cpu, m_regidx3); @@ -87,6 +94,8 @@ void CInstructionSub::compile(std::list& params) void CInstructionSub::execute(CCPU *cpu) { + assert(cpu != NULL); + assert(cpu->getRegisters() != NULL); checkRegister(cpu, m_regidx1); checkRegister(cpu, m_regidx2); checkRegister(cpu, m_regidx3); @@ -137,6 +146,8 @@ void CInstructionDiv::compile(std::list& params) void CInstructionDiv::execute(CCPU *cpu) { + assert(cpu != NULL); + assert(cpu->getRegisters() != NULL); checkRegister(cpu, m_regidx1); checkRegister(cpu, m_regidx2); checkRegister(cpu, m_regidx3); @@ -160,6 +171,9 @@ void CInstructionLoad::compile(std::list& params) 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 ]); @@ -182,6 +196,9 @@ void CInstructionStore::compile(std::list& params) 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 ]); @@ -202,6 +219,8 @@ void CInstructionTest::compile(std::list& params) 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); @@ -223,6 +242,9 @@ void CInstructionJumpA::compile(std::list& params) 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); @@ -242,8 +264,13 @@ void CInstructionJumpZ::compile(std::list& params) 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); } @@ -261,8 +288,13 @@ void CInstructionJumpS::compile(std::list& params) 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); } @@ -282,6 +314,8 @@ void CInstructionWrite::compile(std::list& params) 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"); diff --git a/ue3/mycpu/test/memory1 b/ue3/mycpu/test/memory1 deleted file mode 100644 index 209e3ef..0000000 --- a/ue3/mycpu/test/memory1 +++ /dev/null @@ -1 +0,0 @@ -20 diff --git a/ue3/mycpu/test/program1 b/ue3/mycpu/test/program1 deleted file mode 100644 index ae5e9d2..0000000 --- a/ue3/mycpu/test/program1 +++ /dev/null @@ -1,13 +0,0 @@ -# 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: diff --git a/ue3/mycpu/test/test.sh b/ue3/mycpu/test/test.sh index ad2ae4d..ff1076c 100755 --- a/ue3/mycpu/test/test.sh +++ b/ue3/mycpu/test/test.sh @@ -32,9 +32,11 @@ do if [ "$md5_1" != "$md5_2" ] then echo " ERROR: output and $reffile differ" - diff -Nau $reffile $tmpfile + diff -Naur "$reffile" "$tmpfile" + rm -rf "$tmpfile" exit 1 else echo " SUCCESS" fi + rm -rf "$tmpfile" done -- cgit v1.2.3 From 3563c6dfd0f5f102cb748ecc6ad318601990515e Mon Sep 17 00:00:00 2001 From: manuel Date: Thu, 14 May 2009 18:21:15 +0200 Subject: adding doxygen docs --- ue3/mycpu/cdisplay.h | 2 +- ue3/mycpu/displays.h | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) (limited to 'ue3/mycpu') diff --git a/ue3/mycpu/cdisplay.h b/ue3/mycpu/cdisplay.h index 1523f68..82776ee 100644 --- a/ue3/mycpu/cdisplay.h +++ b/ue3/mycpu/cdisplay.h @@ -57,7 +57,7 @@ class CDisplayT } /** - * @method getName + * @method display * @brief prints value to display * @param value value to display * @return - diff --git a/ue3/mycpu/displays.h b/ue3/mycpu/displays.h index 87b9408..d4f3f36 100644 --- a/ue3/mycpu/displays.h +++ b/ue3/mycpu/displays.h @@ -25,6 +25,15 @@ class CDisplayWDEZ : CDisplay("wdez") {} + /** + * @method display + * @brief prints value to display + * @param value value to display + * @return - + * @globalvars none + * @exception none + * @conditions none + */ void display(const CDat &value) { std::cout << std::dec << value << std::endl; @@ -47,6 +56,15 @@ class CDisplayWHEX : CDisplay("whex") {} + /** + * @method display + * @brief prints value to display + * @param value value to display + * @return - + * @globalvars none + * @exception none + * @conditions none + */ void display(const CDat &value) { std::cout << std::hex << value << std::endl; -- cgit v1.2.3