mycpu/ccpu.h

00001 
00009 #ifndef CCPU_H
00010 #define CCPU_H 1
00011 
00012 #include <iostream>
00013 #include <set>
00014 #include <stdexcept>
00015 #ifdef DEBUG
00016 # include <iostream>
00017 # include <iomanip>
00018 #endif
00019 
00025 class CCPUError
00026  : public std::invalid_argument
00027 {
00028   public:
00039     CCPUError(const std::string& what)
00040       : std::invalid_argument(what)
00041     {}
00042 };
00043 
00044 #include "cmem.h"
00045 #include "displays.h"
00046 #include "cprogram.h"
00047 
00048 /* forward declare CProgram */
00049 template <class T>
00050 class CProgram;
00051 
00058 template <class T>
00059 class CCPU
00060 {
00061   typedef typename std::set<CDisplay<T> *>::iterator displayiterator;
00062 
00063   public:
00075     CCPU(const unsigned cnt, T& datatype);
00076 
00087     ~CCPU();
00088 
00099     const unsigned getRegisterCount() const
00100     {
00101       return m_regcnt;
00102     }
00103 
00114     std::vector<T> &getRegisters()
00115     {
00116       return m_registers;
00117     }
00118 
00129     void setMemory(CMem<T> *memory)
00130     {
00131       m_memory = memory;
00132     }
00133 
00144     CMem<T> *getMemory() const
00145     {
00146       return m_memory;
00147     }
00148 
00159     void setProgram(const CProgram<T> *program)
00160     {
00161       m_program = program;
00162     }
00163 
00174     const CProgram<T> *getProgram()
00175     {
00176       return m_program;
00177     }
00178 
00189     const std::set<CDisplay<T> *>& getDisplays()
00190     {
00191       return m_displays;
00192     }
00193 
00204     void setFlagZero(const bool value)
00205     {
00206       m_flagzero = value;
00207     }
00208 
00219     const bool getFlagZero()
00220     {
00221       return m_flagzero;
00222     }
00223 
00234     void setFlagSign(const bool value)
00235     {
00236       m_flagsign = value;
00237     }
00238 
00249     const bool getFlagSign()
00250     {
00251       return m_flagsign;
00252     }
00253 
00264     void run();
00265 
00266 #if DEBUG
00267 
00277     void dumpRegisters(std::ostream& out);
00278 #endif
00279 
00280   private:
00281     /* members */
00282     T m_datatype;
00283     std::vector<T> m_registers;
00284     unsigned m_regcnt;
00285     CMem<T> *m_memory;
00286     const CProgram<T> *m_program;
00287     std::set<CDisplay<T> *> m_displays;
00288     bool m_flagzero;
00289     bool m_flagsign;
00290 };
00291 
00292 /*----------------------------------------------------------------------------*/
00293 
00294 template <class T>
00295 CCPU<T>::CCPU(const unsigned cnt, T& datatype)
00296   : 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)
00297 {
00298   /* create displays */
00299   m_displays.insert(new CDisplayWDEZ<T>);
00300   m_displays.insert(new CDisplayWHEX<T>);
00301 }
00302 
00303 /*----------------------------------------------------------------------------*/
00304 
00305 template <class T>
00306 CCPU<T>::~CCPU()
00307 {
00308   /* delete displays */
00309   for (displayiterator it = m_displays.begin() ; it != m_displays.end(); ++it)
00310     delete *it;
00311 }
00312 
00313 /*----------------------------------------------------------------------------*/
00314 
00315 template <class T>
00316 void CCPU<T>::run()
00317 {
00318   if (m_memory == NULL)
00319     throw CCPUError("CPU has no memory");
00320   if (m_program == NULL)
00321     throw CCPUError("CPU has no program to execute");
00322   if (m_regcnt == 0)
00323     throw CCPUError("CPU has no registers");
00324 
00325   bool run = true;
00326   while(run)
00327   {
00328     unsigned pc = static_cast<unsigned>(m_registers[0]);
00329 
00330     /* end of the program reached */
00331     if (pc == m_program->size())
00332       break;
00333 
00334     /* pc is out of bound */
00335     if (pc > m_program->size())
00336       throw CCPUError("Programcounter is out of bound");
00337 
00338     /* execute instruction */
00339     try
00340     {
00341       (*m_program->at(pc))(this);
00342       ++m_registers[0];
00343     }
00344     catch(CInstructionError& ex)
00345     {
00346       throw CCPUError(ex.what());
00347     }
00348   }
00349 }
00350 
00351 /*----------------------------------------------------------------------------*/
00352 
00353 #if DEBUG
00354 template <class T>
00355 void CCPU<T>::dumpRegisters(std::ostream& out)
00356 {
00357   out << "[REGISTER DUMP]" << std::endl;
00358   for(unsigned i = 0; i < getRegisterCount(); ++i)
00359   {
00360     out << "[" << std::setw(4) << std::setfill('0') << i << "]  "
00361         << m_registers[i] << std::endl;
00362   }
00363 }
00364 #endif
00365 
00366 #endif
00367 
00368 /* vim: set et sw=2 ts=2: */

Generated on Sat May 30 16:32:35 2009 for mycpu by  doxygen 1.5.3