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
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
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
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
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
00331 if (pc == m_program->size())
00332 break;
00333
00334
00335 if (pc > m_program->size())
00336 throw CCPUError("Programcounter is out of bound");
00337
00338
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