X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=3b_sim%2Fccpu.cpp;h=d314b5ef8b2c19961e2670492401f8aaf82f141f;hb=b819c6be9396aac52fc9cf787286580ef19b01e4;hp=fb480f48fec4843aa2f9121f199d9a27023c0f10;hpb=91f67630701b9c4e2d369b5ce8761c13d1a73eb8;p=calu.git diff --git a/3b_sim/ccpu.cpp b/3b_sim/ccpu.cpp index fb480f4..d314b5e 100644 --- a/3b_sim/ccpu.cpp +++ b/3b_sim/ccpu.cpp @@ -6,6 +6,50 @@ //void registerExtension() {}; +const char* expression = "(;.*)|(r0)|(rX)|(r1[0-5])|(r[1-5])|(r[6-9])|(0x[a-fA-F0-9]+)|([-]?\\d+)"; +const char* format = "(?1$&)" + //Return-Register: violett + "(?2\033[0m\033[35m$&\033[0m\\3:)" + // Callee-saved Register: rot + "(?4\033[0m\033[31m$&\033[0m\\3:)" + //Argument-Register: gruen + "(?5\033[0m\033[32m$&\033[0m\\3:)" + // Temporary Register: gelb + "(?6\033[0m\033[33m$&\033[0m\\3:)" + // Zahlenwerte: tuerkis + "(?7\033[0m\033[36m$&\033[0m\\3:)" + "(?8\033[0m\033[36m$&\033[0m\\3:)"; + + +string CCpu::colorifyInstr(string instr) +{ + boost::regex e; + e.assign(expression); + return boost::regex_replace(instr, e, format, boost::match_default | boost::format_all); +} + +void CCpu::registerExtension(Iext* ext) +{ + m_exts.push_back(ext); +} + +void CCpu::applyToExtensions(const vector& in) +{ + for(auto iter = m_exts.begin(); iter != m_exts.end(); ++iter) { + (*iter)->parseInput(in); + } +} + +void CCpu::breakNext() +{ + m_breakNext = true; +} + +bool CCpu::shouldBreak() +{ + return m_breakNext; +} + void CCpu::tick() { // signal extensions @@ -14,15 +58,23 @@ void CCpu::tick() m_pc = m_pc_next; m_pc_next += 4; Iinstr* instr = this->getProg(m_pc); + if(instr == NULL) { throw string("Out of Instructions!"); } + + for(auto iter = m_exts.begin(); iter != m_exts.end(); ++iter) { + (*iter)->applyTick(); + } + if(this->conditionMet(instr->getCondition())) { - cout << "Executing: " << instr->toString() << endl; + cout << color(green,black) << "Executing: " << color(white,black) << colorifyInstr(instr->toString()) << " (0x" << std::hex << m_pc << std::dec << ")" << endl; instr->execInstr(); + this->incPerfBy(instr->getClockCount()); } else { - cout << "Didn't Execute " << instr->toString() << "; condition wasn't met" << endl; + cout << color(red,black) << "Didn't Execute " << color(white,black) << colorifyInstr(instr->toString()) << "; condition wasn't met" << endl; + this->incPerf(); } } @@ -109,6 +161,13 @@ CDat CCpu::getFlags() const { return psw; } +void CCpu::setFlags(CDat psw) { + this->m_Z = ((psw & 0x1) != 0); + this->m_O = ((psw & 0x2) != 0); + this->m_C = ((psw & 0x4) != 0); + this->m_S = ((psw & 0x8) != 0); +} + void CCpu::updateFlags(CDat val) { this->m_Z = (val == 0); this->m_S = ((val >> (BIT_LEN-1)) & 0x1); @@ -120,8 +179,10 @@ void CCpu::updateFlags(CDatd val, CDat a, CDat b) { this->m_Z = (val == 0); this->m_S = ((val >> (BIT_LEN-1)) & 0x1); this->m_C = ((val >> (BIT_LEN)) & 0x1); - bool v = (((a ^ b) >> (BIT_LEN-1)) & 0x1) ? true : false; - this->m_O = (this->m_S != v); + bool a_31 = ((a >> (BIT_LEN-1)) & 0x1); + bool b_31 = ((b >> (BIT_LEN-1)) & 0x1); + bool val_31 = ((val >> (BIT_LEN-1)) & 0x1); + this->m_O = ((a_31 && b_31 && !val_31) || (!a_31 && !b_31 && val_31)); } void CCpu::updateCarry(bool c) @@ -154,11 +215,31 @@ void CCpu::setRegister(const int addr, CDat data) CDat CCpu::getRAM(const int addr) const { - return m_ram.get(addr); + if((addr & EXT_MODEL_OFFSET) == 0) { + return m_ram.get(addr); + } + else { + CDat result = 0; + for(auto iter = m_exts.begin(); iter != m_exts.end(); ++iter) { + result = (*iter)->readData(addr); + if(result != 0) { + break; + } + } + return result; + } } + void CCpu::setRAM(const int addr, CDat data) { - m_ram.set(addr, data); + if((addr & EXT_MODEL_OFFSET) == 0) { + m_ram.set(addr, data); + } + else { + for(auto iter = m_exts.begin(); iter != m_exts.end(); ++iter) { + (*iter)->loadData(addr, data); + } + } } void CCpu::setProg(int addr, Iinstr* instr) @@ -181,7 +262,28 @@ void CCpu::setStack(const int val) this->m_stack = val; } -CCpu::CCpu(int regs, int ram, int prog) : m_Z(false), m_S(false), m_C(false), m_O(false), m_pc(0), m_pc_next(0), m_reg(regs), m_ram(ram), m_prog(prog), m_stack(0) +CDat CCpu::getPerf() const +{ + return this->m_perf; +} + +void CCpu::setPerf(CDat val) +{ + this->m_perf = val; +} + +void CCpu::incPerf() +{ + this->m_perf++; +} + +void CCpu::incPerfBy(short inc) +{ + this->m_perf += inc; +} + + +CCpu::CCpu(int regs, int ram, int prog) : m_Z(false), m_S(false), m_C(false), m_O(false), m_breakNext(0), m_pc(0), m_pc_next(0), m_perf(0), m_reg(regs), m_ram(ram), m_prog(prog), m_exts(0), m_stack(0) { }