diff options
Diffstat (limited to 'ue3/mycpu/ccpu.cpp')
| -rw-r--r-- | ue3/mycpu/ccpu.cpp | 125 |
1 files changed, 69 insertions, 56 deletions
diff --git a/ue3/mycpu/ccpu.cpp b/ue3/mycpu/ccpu.cpp index 978f1f7..af86200 100644 --- a/ue3/mycpu/ccpu.cpp +++ b/ue3/mycpu/ccpu.cpp | |||
| @@ -1,76 +1,89 @@ | |||
| 1 | /** | 1 | /** |
| 2 | * @module ccpu | 2 | * @module ccpu |
| 3 | * @author Guenther Neuwirth (0626638), Manuel Mausz (0728348) | 3 | * @author Guenther Neuwirth (0626638), Manuel Mausz (0728348) |
| 4 | * @brief class for processing a program | 4 | * @brief CPU implementation. Used as a container for memory and instructions. |
| 5 | * @date 11.05.2009 | 5 | * Implements an run method to execute the program (= the instructions). |
| 6 | * @date 10.05.2009 | ||
| 6 | */ | 7 | */ |
| 7 | 8 | ||
| 8 | #include <fstream> | 9 | #ifdef DEBUG |
| 9 | #include <boost/tokenizer.hpp> | 10 | # include <iostream> |
| 10 | #include <boost/algorithm/string.hpp> | 11 | # include <iomanip> |
| 11 | 12 | #endif | |
| 12 | #include "ccpu.h" | 13 | #include "ccpu.h" |
| 13 | #include "cinstruction.h" | 14 | #include "displays.h" |
| 14 | #include "cprogram.h" | ||
| 15 | #include "cmem.h" | ||
| 16 | |||
| 17 | 15 | ||
| 18 | using namespace std; | 16 | using namespace std; |
| 19 | using namespace boost; | ||
| 20 | 17 | ||
| 21 | CCPU::CCPU(const std::string& progfile, const std::string& memfile) | 18 | CCPU::CCPU(const unsigned cnt) |
| 22 | : m_program(progfile), m_memory(memfile) | 19 | : m_regcnt(cnt), m_memory(NULL), m_program(NULL), m_flagzero(false), m_flagsign(false) |
| 23 | { | 20 | { |
| 24 | f_zero = false; | 21 | /* create registers */ |
| 25 | f_sign = false; | 22 | m_registers = new CDat[cnt]; |
| 26 | m_instrHandler["inc"] = new CInc(); | 23 | for(unsigned i = 0; i < cnt; ++i) |
| 27 | m_instrHandler["dec"] = new CDec(); | 24 | m_registers[i] = 0; |
| 28 | m_instrHandler["add"] = new CAdd(); | 25 | |
| 29 | m_instrHandler["sub"] = new CSub(); | 26 | /* create displays */ |
| 30 | m_instrHandler["mul"] = new CMul(); | 27 | m_displays.insert(new CDisplayWDEZ); |
| 31 | m_instrHandler["div"] = new CDiv(); | 28 | m_displays.insert(new CDisplayWHEX); |
| 32 | m_instrHandler["load"] = new CLoad(); | ||
| 33 | m_instrHandler["store"] = new CStore(); | ||
| 34 | m_instrHandler["test"] = new CTest(f_zero, f_sign); | ||
| 35 | m_instrHandler["label"] = new CLabel(); | ||
| 36 | m_instrHandler["jumpa"] = new CJumpa(m_program.getJumpAddrs()); | ||
| 37 | m_instrHandler["jumpz"] = new CJumpz(f_zero, f_sign, m_program.getJumpAddrs()); | ||
| 38 | m_instrHandler["jumps"] = new CJumps(f_zero, f_sign, m_program.getJumpAddrs()); | ||
| 39 | m_instrHandler["write"] = new CWrite(); | ||
| 40 | } | 29 | } |
| 41 | 30 | ||
| 31 | /*----------------------------------------------------------------------------*/ | ||
| 32 | |||
| 42 | CCPU::~CCPU() | 33 | CCPU::~CCPU() |
| 43 | { | 34 | { |
| 44 | std::map<std::string, CInstruction *>::iterator it; | 35 | /* delete registers */ |
| 45 | for (it = m_instrHandler.begin(); it != m_instrHandler.end(); it++) | 36 | delete[] m_registers; |
| 46 | delete (*it).second ; | 37 | m_registers = NULL; |
| 38 | |||
| 39 | /* delete displays */ | ||
| 40 | std::set<CDisplay *>::iterator it; | ||
| 41 | for (it = m_displays.begin() ; it != m_displays.end(); ++it) | ||
| 42 | delete *it; | ||
| 47 | } | 43 | } |
| 48 | void CCPU::proceed() | 44 | |
| 45 | /*----------------------------------------------------------------------------*/ | ||
| 46 | |||
| 47 | void CCPU::run() | ||
| 49 | { | 48 | { |
| 50 | 49 | if (m_memory == NULL) | |
| 51 | while (m_memory.getRegister("R0") < m_program.getMaxProgramCount()) | 50 | throw runtime_error("CPU has no memory"); |
| 52 | { | 51 | if (m_program == NULL) |
| 53 | std::vector<std::string>& i_list = m_program.getInstruction( | 52 | throw runtime_error("CPU has no program to execute"); |
| 54 | m_memory.getRegister("R0") | 53 | if (m_regcnt == 0) |
| 55 | ); | 54 | throw runtime_error("CPU has no registers"); |
| 56 | 55 | ||
| 57 | 56 | bool run = true; | |
| 58 | 57 | while(run) | |
| 59 | m_instrHandler[i_list[0]]->exec(m_memory, i_list); | 58 | { |
| 60 | /* for(int i = 0; i < (int)i_list.size(); i++) | 59 | unsigned pc = static_cast<unsigned>(m_registers[0]); |
| 61 | cout << i_list[i] << " "; | 60 | |
| 62 | if (i_list[0] == "load") | 61 | /* end of the program reached */ |
| 63 | { | 62 | if (pc == m_program->size()) |
| 64 | 63 | break; | |
| 65 | cout << m_memory.getRegister(i_list[1])<<" "<<m_memory.getRegister("R255")<<endl; | 64 | |
| 66 | break; | 65 | /* pc is out of bound */ |
| 67 | }*/ | 66 | if (pc > m_program->size()) |
| 68 | m_memory.getRegister("R0")++; | 67 | throw runtime_error("Programcounter is out of bound"); |
| 69 | // cout << m_memory.getRegister("R0")<<endl; | 68 | |
| 70 | // cout<<endl; | 69 | /* execute instruction */ |
| 71 | } | 70 | (*m_program->at(pc))(this); |
| 72 | 71 | ++m_registers[0]; | |
| 72 | } | ||
| 73 | } | 73 | } |
| 74 | 74 | ||
| 75 | /*----------------------------------------------------------------------------*/ | ||
| 75 | 76 | ||
| 77 | #if DEBUG | ||
| 78 | void CCPU::dumpRegisters(std::ostream& out) | ||
| 79 | { | ||
| 80 | out << "[REGISTER DUMP]" << endl; | ||
| 81 | for(unsigned i = 0; i < getRegisterCount(); ++i) | ||
| 82 | { | ||
| 83 | out << "[" << std::setw(4) << std::setfill('0') << i << "] " | ||
| 84 | << m_registers[i] << endl; | ||
| 85 | } | ||
| 86 | } | ||
| 87 | #endif | ||
| 76 | 88 | ||
| 89 | /* vim: set et sw=2 ts=2: */ | ||
