X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=3b_sim%2Fccpu.cpp;h=873f1b7af8160baf9907fe600981e3226f24c0cd;hb=8f5ad4611ce8bdc9e3288e24252633557f4e950b;hp=3ad97fb8bf7873ed55c6c530bb57dd4a88ab5677;hpb=31d88f201bf427d70924b9737ecdb6e0611939d3;p=calu.git diff --git a/3b_sim/ccpu.cpp b/3b_sim/ccpu.cpp index 3ad97fb..873f1b7 100644 --- a/3b_sim/ccpu.cpp +++ b/3b_sim/ccpu.cpp @@ -8,8 +8,83 @@ void CCpu::tick() { + // signal extensions + // Todo + m_pc = m_pc_next; m_pc_next += 4; + Iinstr* instr = this->getProg(m_pc); + if(instr == NULL) { + throw string("Out of Instructions!"); + } + if(this->conditionMet(instr->getCondition())) { + cout << color(green,black) << "Executing: " << color(white,black) << instr->toString() << endl; + instr->execInstr(); + this->incPerfBy(instr->getClockCount()); + } + else { + cout << color(red,black) << "Didn't Execute " << color(white,black) << instr->toString() << "; condition wasn't met" << endl; + this->incPerf(); + } + +} + +bool CCpu::conditionMet(short cond) +{ + switch(cond) { + case NOT_EQUAL: + return !this->m_Z; + break; + case EQUAL: + return this->m_Z; + break; + case NOT_OVERFLOW: + return !this->m_O; + break; + case OVER_FLOW: + return this->m_O; + break; + case NOT_CARRY: + return !this->m_C; + break; + case CARRY: + return this->m_C; + break; + case NOT_SIGNED: + return !this->m_S; + break; + case SIGNED: + return this->m_S; + break; + case ABOVE: + return (!this->m_C && !this->m_Z); + break; + case BELOW_EQ: + return (this->m_C || this->m_Z); + break; + case GREATER_EQ: + return (this->m_S == this->m_O); + break; + case LESS: + return (this->m_S != this->m_O); + break; + case GREATER: + return (!this->m_Z && (this->m_S == this->m_O)); + break; + case LESS_EQ: + return (!this->m_Z || (this->m_S != this->m_O)); + break; + case ALWAYS: + return true; + break; + case NEVER: + return false; + break; + default: + cerr << "What did you do? more than 16 values in 5 bits?!" << endl; + return false; + } + } CDat CCpu::getNextPC() const @@ -17,19 +92,128 @@ CDat CCpu::getNextPC() const return m_pc_next; } +CDat CCpu::getCurPC() const +{ + return m_pc; +} + +void CCpu::setNextPC(CDat val) +{ + m_pc_next = val; +} + +CDat CCpu::getFlags() const { + CDat psw = 0; + psw += (this->m_Z ? 1 : 0); + psw += (this->m_O ? 2 : 0); + psw += (this->m_C ? 4 : 0); + psw += (this->m_S ? 8 : 0); + 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); +/* this->m_C = false; + this->m_O = false; */ +} + +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 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)); +} -// CDat getRegister(const short) const {}; -// void setRegister(const short, CDat&) {}; +void CCpu::updateCarry(bool c) +{ + this->m_C = c; +} -// CDat getRAM(const short) const {}; -// void setRAM(const short, CDat&) {}; +bool CCpu::getCarry() +{ + return this->m_C; +} + +void CCpu::updateFlags(bool z, bool o, bool c, bool s) +{ + this->m_Z = z; + this->m_O = o; + this->m_C = c; + this->m_S = s; +} + +CDat CCpu::getRegister(const int addr) const +{ + return m_reg.getDirect(addr); +} + +void CCpu::setRegister(const int addr, CDat data) +{ + m_reg.setDirect(addr, data); +} + +CDat CCpu::getRAM(const int addr) const +{ + return m_ram.get(addr); +} +void CCpu::setRAM(const int addr, CDat data) +{ + m_ram.set(addr, data); +} void CCpu::setProg(int addr, Iinstr* instr) { m_prog.set(addr, instr); } -CCpu::CCpu() : m_pc(0), m_pc_next(0), m_regfile(0), m_ram(0), m_prog(0) +Iinstr* CCpu::getProg(const int addr) const +{ + return m_prog.get(addr); +} + +int CCpu::getStack() const +{ + return this->m_stack; +} + +void CCpu::setStack(const int val) +{ + this->m_stack = val; +} + +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_pc(0), m_pc_next(0), m_perf(0), m_reg(regs), m_ram(ram), m_prog(prog), m_stack(0) { }