6bfb65481fd61162ddcb9afd2ec3a9f14f102de1
[calu.git] / 3b_sim / ccpu.cpp
1 #include "ccpu.hpp"
2
3 /*              CDat m_pc, m_pc_next;
4                 CMem m_regfile, m_ram;
5 */
6
7 //void registerExtension() {};
8
9 void CCpu::tick()
10 {
11         // signal extensions
12         // Todo
13
14         m_pc = m_pc_next;
15         m_pc_next += 4;
16         Iinstr* instr = this->getProg(m_pc);
17         if(instr == NULL) {
18                 throw string("Out of Instructions!");
19         }
20         if(this->conditionMet(instr->getCondition())) {
21                 cout << "Executing: " << instr->toString() << endl;
22                 instr->execInstr();
23                 this->incPerfBy(instr->getClockCount());
24         }
25         else {
26                 cout << "Didn't Execute " << instr->toString() << "; condition wasn't met" << endl;
27                 this->incPerf();
28         }
29
30 }
31
32 bool CCpu::conditionMet(short cond)
33 {
34         switch(cond) {
35                 case NOT_EQUAL:
36                         return !this->m_Z;
37                         break;
38                 case EQUAL:
39                         return this->m_Z;
40                         break;
41                 case NOT_OVERFLOW:
42                         return !this->m_O;
43                         break;
44                 case OVER_FLOW:
45                         return this->m_O;
46                         break;
47                 case NOT_CARRY:
48                         return !this->m_C;
49                         break;
50                 case CARRY:
51                         return this->m_C;
52                         break;
53                 case NOT_SIGNED:
54                         return !this->m_S;
55                         break;
56                 case SIGNED:
57                         return this->m_S;
58                         break;
59                 case ABOVE:
60                         return (!this->m_C && !this->m_Z);
61                         break;
62                 case BELOW_EQ:
63                         return (this->m_C || this->m_Z);
64                         break;
65                 case GREATER_EQ:
66                         return (this->m_S == this->m_O);
67                         break;
68                 case LESS:
69                         return (this->m_S != this->m_O);
70                         break;
71                 case GREATER:
72                         return (!this->m_Z && (this->m_S == this->m_O));
73                         break;
74                 case LESS_EQ:
75                         return (!this->m_Z || (this->m_S != this->m_O));
76                         break;
77                 case ALWAYS:
78                         return true;
79                         break;
80                 case NEVER:
81                         return false;
82                         break;
83                 default:
84                         cerr << "What did you do? more than 16 values in 5 bits?!" << endl;
85                         return false;
86         }
87
88 }
89
90 CDat CCpu::getNextPC() const
91 {
92         return m_pc_next;
93 }
94
95 CDat CCpu::getCurPC() const
96 {
97         return m_pc;
98 }
99
100 void CCpu::setNextPC(CDat val)
101 {
102         m_pc_next = val;
103 }
104
105 CDat CCpu::getFlags() const {
106         CDat psw = 0;
107         psw += (this->m_Z ? 1 : 0);
108         psw += (this->m_O ? 2 : 0);
109         psw += (this->m_C ? 4 : 0);
110         psw += (this->m_S ? 8 : 0);
111         return psw;
112 }
113
114 void CCpu::setFlags(CDat psw) {
115         this->m_Z = ((psw & 0x1) != 0);
116         this->m_O = ((psw & 0x2) != 0);
117         this->m_C = ((psw & 0x4) != 0);
118         this->m_S = ((psw & 0x8) != 0);
119 }
120
121 void CCpu::updateFlags(CDat val) {
122         this->m_Z = (val == 0);
123         this->m_S = ((val >> (BIT_LEN-1)) & 0x1);
124 /*      this->m_C = false;
125         this->m_O = false; */
126 }
127
128 void CCpu::updateFlags(CDatd val, CDat a, CDat b) {
129         this->m_Z = (val == 0);
130         this->m_S = ((val >> (BIT_LEN-1)) & 0x1);
131         this->m_C = ((val >> (BIT_LEN)) & 0x1);
132         bool a_31 = ((a >> (BIT_LEN-1)) & 0x1);
133         bool b_31 = ((b >> (BIT_LEN-1)) & 0x1);
134         bool val_31 = ((val >> (BIT_LEN-1)) & 0x1);
135         this->m_O = ((a_31 && b_31 && !val_31) || (!a_31 && !b_31 && val_31));
136 }
137
138 void CCpu::updateCarry(bool c)
139 {
140         this->m_C = c;
141 }
142
143 bool CCpu::getCarry()
144 {
145         return this->m_C;
146 }
147
148 void CCpu::updateFlags(bool z, bool o, bool c, bool s)
149 {
150         this->m_Z = z;
151         this->m_O = o;
152         this->m_C = c;
153         this->m_S = s;
154 }
155
156 CDat CCpu::getRegister(const int addr) const
157 {
158         return m_reg.getDirect(addr);
159 }
160
161 void CCpu::setRegister(const int addr, CDat data)
162 {
163         m_reg.setDirect(addr, data);
164 }
165
166 CDat CCpu::getRAM(const int addr) const
167 {
168         return m_ram.get(addr);
169 }
170 void CCpu::setRAM(const int addr, CDat data)
171 {
172         m_ram.set(addr, data);
173 }
174
175 void CCpu::setProg(int addr, Iinstr* instr)
176 {
177         m_prog.set(addr, instr);
178 }
179
180 Iinstr* CCpu::getProg(const int addr) const
181 {
182         return m_prog.get(addr);
183 }
184
185 int CCpu::getStack() const
186 {
187         return this->m_stack;
188 }
189
190 void CCpu::setStack(const int val)
191 {
192         this->m_stack = val;
193 }
194
195 CDat CCpu::getPerf() const
196 {
197         return this->m_perf;
198 }
199
200 void CCpu::setPerf(CDat val)
201 {
202         this->m_perf = val;
203 }
204
205 void CCpu::incPerf()
206 {
207         this->m_perf++;
208 }
209
210 void CCpu::incPerfBy(short inc)
211 {
212         this->m_perf += inc;
213 }
214
215
216 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)
217 {
218 }
219
220