#include "ccpu.hpp" /* CDat m_pc, m_pc_next; CMem m_regfile, m_ram; */ //void registerExtension() {}; 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 << "Executing: " << instr->toString() << endl; instr->execInstr(); this->incPerfBy(instr->getClockCount()); } else { cout << "Didn't Execute " << 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 { 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)); } void CCpu::updateCarry(bool c) { this->m_C = c; } 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); } 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) { }