Download | Plain Text | No Line Numbers
- /**
- * @module ccpu
- * @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 26.05.2009
- */
-
- #ifndef CCPU_H
- #define CCPU_H 1
-
- #include <iostream>
- #include <set>
- #include <stdexcept>
- #ifdef DEBUG
- # include <iostream>
- # include <iomanip>
- #endif
-
- /**
- * @class CCPUError
- *
- * Exception thrown by implemententations of CCPU
- */
- class CCPUError
- : public std::invalid_argument
- {
- public:
- /**
- * @method CCPUError
- * @brief Default exception ctor
- * @param what message to pass along
- * @return -
- * @globalvars none
- * @exception none
- * @pre none
- * @post none
- */
- CCPUError(const std::string& what)
- : std::invalid_argument(what)
- {}
- };
-
- #include "cmem.h"
- #include "displays.h"
- #include "cprogram.h"
-
- /* forward declare CProgram */
- template <class T>
- class CProgram;
-
- /**
- * @class CCPU
- *
- * CPU implementation. Used as a container for memory and instructions.
- * Implements a run method to execute the program (= the instructions).
- */
- template <class T>
- class CCPU
- {
- typedef typename std::set<CDisplay<T> *>::iterator displayiterator;
-
- public:
- /**
- * @method CCPU
- * @brief Default ctor
- * @param cnt number of registers to allocate for this cpu
- * @param datatype reference instance of datatype to copy from
- * @return -
- * @globalvars none
- * @exception none
- * @pre none
- * @post none
- */
- CCPU(const unsigned cnt, T& datatype);
-
- /**
- * @method ~CCPU
- * @brief Default dtor
- * @param -
- * @return -
- * @globalvars none
- * @exception none
- * @pre none
- * @post none
- */
- ~CCPU();
-
- /**
- * @method getRegisterCount
- * @brief get number of registers
- * @param -
- * @return number of registers
- * @globalvars none
- * @exception none
- * @pre none
- * @post none
- */
- const unsigned getRegisterCount() const
- {
- return m_regcnt;
- }
-
- /**
- * @method getRegisters
- * @brief get reference to registers vector
- * @param -
- * @return reference to registers vector
- * @globalvars none
- * @exception none
- * @pre none
- * @post none
- */
- std::vector<T> &getRegisters()
- {
- return m_registers;
- }
-
- /**
- * @method setMemory
- * @brief set memory of cpu
- * @param memory pointer to memory
- * @return -
- * @globalvars none
- * @exception none
- * @pre none
- * @post none
- */
- void setMemory(CMem<T> *memory)
- {
- m_memory = memory;
- }
-
- /**
- * @method getMemory
- * @brief get pointer to memory
- * @param -
- * @return pointer to memory
- * @globalvars none
- * @exception none
- * @pre none
- * @post none
- */
- CMem<T> *getMemory() const
- {
- return m_memory;
- }
-
- /**
- * @method setProgram
- * @brief set program to execute
- * @param program pointer to program
- * @return -
- * @globalvars none
- * @exception none
- * @pre none
- * @post none
- */
- void setProgram(const CProgram<T> *program)
- {
- m_program = program;
- }
-
- /**
- * @method getProgram
- * @brief get pointer to program
- * @param -
- * @return pointer to program
- * @globalvars none
- * @exception none
- * @pre none
- * @post none
- */
- const CProgram<T> *getProgram()
- {
- 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
- * @pre none
- * @post none
- */
- const std::set<CDisplay<T> *>& getDisplays()
- {
- return m_displays;
- }
-
- /**
- * @method setFlagZero
- * @brief set zero flag
- * @param value new value of zero flag
- * @return -
- * @globalvars none
- * @exception none
- * @pre none
- * @post 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
- * @pre none
- * @post 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
- * @pre none
- * @post 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
- * @pre none
- * @post none
- */
- const bool getFlagSign()
- {
- return m_flagsign;
- }
-
- /**
- * @method run
- * @brief execute current program
- * @param -
- * @return -
- * @globalvars none
- * @exception CCPUError
- * @pre m_memory and m_program still exist
- * @post 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
- * @pre none
- * @post none
- */
- void dumpRegisters(std::ostream& out);
- #endif
-
- private:
- /* members */
- T m_datatype;
- std::vector<T> m_registers;
- unsigned m_regcnt;
- CMem<T> *m_memory;
- const CProgram<T> *m_program;
- std::set<CDisplay<T> *> m_displays;
- bool m_flagzero;
- bool m_flagsign;
- };
-
- /*----------------------------------------------------------------------------*/
-
- template <class T>
- CCPU<T>::CCPU(const unsigned cnt, T& datatype)
- : m_datatype(datatype), m_registers(cnt, T(m_datatype) = 0), m_regcnt(cnt), m_memory(NULL), m_program(NULL), m_flagzero(false), m_flagsign(false)
- {
- /* create displays */
- m_displays.insert(new CDisplayWDEZ<T>);
- m_displays.insert(new CDisplayWHEX<T>);
- }
-
- /*----------------------------------------------------------------------------*/
-
- template <class T>
- CCPU<T>::~CCPU()
- {
- /* delete displays */
- for (displayiterator it = m_displays.begin() ; it != m_displays.end(); ++it)
- delete *it;
- }
-
- /*----------------------------------------------------------------------------*/
-
- template <class T>
- void CCPU<T>::run()
- {
- if (m_memory == NULL)
- throw CCPUError("CPU has no memory");
- if (m_program == NULL)
- throw CCPUError("CPU has no program to execute");
- if (m_regcnt == 0)
- throw CCPUError("CPU has no registers");
-
- bool run = true;
- while(run)
- {
- unsigned pc = static_cast<unsigned>(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 CCPUError("Programcounter is out of bound");
-
- /* execute instruction */
- try
- {
- (*m_program->at(pc))(this);
- ++m_registers[0];
- }
- catch(CInstructionError& ex)
- {
- throw CCPUError(ex.what());
- }
- }
- }
-
- /*----------------------------------------------------------------------------*/
-
- #if DEBUG
- template <class T>
- void CCPU<T>::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: */
-