From 26a97259f5a7b066cff2927e88c867fac2aaad87 Mon Sep 17 00:00:00 2001 From: manuel Date: Tue, 26 May 2009 23:10:13 +0200 Subject: template FTW!!!!!11 --- ue4/mycpu/ccpu.h | 112 +++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 100 insertions(+), 12 deletions(-) (limited to 'ue4/mycpu/ccpu.h') diff --git a/ue4/mycpu/ccpu.h b/ue4/mycpu/ccpu.h index 6849623..519cee9 100644 --- a/ue4/mycpu/ccpu.h +++ b/ue4/mycpu/ccpu.h @@ -3,7 +3,7 @@ * @author Guenther Neuwirth (0626638), Manuel Mausz (0728348) * @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 + * @date 26.05.2009 */ #ifndef CCPU_H @@ -11,10 +11,19 @@ #include #include +#include +#ifdef DEBUG +# include +# include +#endif #include "cdat.h" #include "cmem.h" +#include "displays.h" #include "cprogram.h" -#include "cdisplay.h" + +/* forward declare CProgram */ +template +class CProgram; /** * @class CCPU @@ -22,8 +31,11 @@ * CPU implementation. Used as a container for memory and instructions. * Implements a run method to execute the program (= the instructions). */ +template class CCPU { + typedef typename std::set *>::iterator displayiterator; + public: /** * @method CCPU @@ -70,7 +82,7 @@ class CCPU * @exception none * @conditions none */ - CDat *getRegisters() const + T *getRegisters() const { return m_registers; } @@ -84,7 +96,7 @@ class CCPU * @exception none * @conditions none */ - void setMemory(CMem *memory) + void setMemory(CMem *memory) { m_memory = memory; } @@ -98,7 +110,7 @@ class CCPU * @exception none * @conditions none */ - CMem *getMemory() const + CMem *getMemory() const { return m_memory; } @@ -112,7 +124,7 @@ class CCPU * @exception none * @conditions none */ - void setProgram(const CProgram *program) + void setProgram(const CProgram *program) { m_program = program; } @@ -126,7 +138,7 @@ class CCPU * @exception none * @conditions none */ - const CProgram *getProgram() + const CProgram *getProgram() { return m_program; } @@ -140,7 +152,7 @@ class CCPU * @exception none * @conditions none */ - const std::set& getDisplays() + const std::set *>& getDisplays() { return m_displays; } @@ -227,15 +239,91 @@ class CCPU private: /* members */ - CDat *m_registers; + T *m_registers; unsigned m_regcnt; - CMem *m_memory; - const CProgram *m_program; - std::set m_displays; + CMem *m_memory; + const CProgram *m_program; + std::set *> m_displays; bool m_flagzero; bool m_flagsign; }; +/*----------------------------------------------------------------------------*/ + +template +CCPU::CCPU(const unsigned cnt) + : m_regcnt(cnt), m_memory(NULL), m_program(NULL), m_flagzero(false), m_flagsign(false) +{ + /* create registers */ + m_registers = new T[cnt]; + for(unsigned i = 0; i < cnt; ++i) + m_registers[i] = 0; + + /* create displays */ + m_displays.insert(new CDisplayWDEZ); + m_displays.insert(new CDisplayWHEX); +} + +/*----------------------------------------------------------------------------*/ + +template +CCPU::~CCPU() +{ + /* delete registers */ + delete[] m_registers; + m_registers = NULL; + + /* delete displays */ + for (displayiterator it = m_displays.begin() ; it != m_displays.end(); ++it) + delete *it; +} + +/*----------------------------------------------------------------------------*/ + +template +void CCPU::run() +{ + if (m_memory == NULL) + throw std::runtime_error("CPU has no memory"); + if (m_program == NULL) + throw std::runtime_error("CPU has no program to execute"); + if (m_regcnt == 0) + throw std::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()) + break; + + /* pc is out of bound */ + if (pc > m_program->size()) + throw std::runtime_error("Programcounter is out of bound"); + + /* execute instruction */ + (*m_program->at(pc))(this); + ++m_registers[0]; + } +} + +/*----------------------------------------------------------------------------*/ + +#if DEBUG +template +void CCPU::dumpRegisters(std::ostream& out) +{ + out << "[REGISTER DUMP]" << std::endl; + for(unsigned i = 0; i < getRegisterCount(); ++i) + { + out << "[" << std::setw(4) << std::setfill('0') << i << "] " + << m_registers[i] << std::endl; + } +} +#endif + #endif /* vim: set et sw=2 ts=2: */ -- cgit v1.2.3