1 #include "cpu_definitions.h"
4 uint64_t N
= 0x00000000; //Negative
5 uint64_t Z
= 0x00000000; //Zero
6 uint64_t C
= 0x00000000; //Carry (or Unsigned Overflow)
7 uint64_t V
= 0x00000000; //Overflow (Signed)
9 uint64_t PC
= 0x00000000; //Program Counter
13 void mem_writeData(uint64_t *data
) {
14 uint64_t despacito
= 0x00000000;
15 uint64_t dametucosita
= 0x00000000;
16 while(sizeof(despacito
) < sizeof(data
)) {
17 mem
[despacito
] = data
[dametucosita
];
18 despacito
= despacito
+ 0x01;
19 dametucosita
= dametucosita
+ 0x01;
23 void mem_write(uint64_t addr
, uint64_t value
) {
27 uint64_t mem_read(uint64_t addr
) {
31 void start_cpu() { //Start emulating the CPU
33 while(isRunning
== 1) {
34 opcode
= mem
[PC
]; //fetch opcode
35 interpret(opcode
); //interpret opcode
39 void stop_cpu() { //Stop emulating the CPU
43 void interpret(uint64_t opcode
) { /* emulate opcode */
44 switch(opcode
) { //ADC (Add with Carry)
45 /* Add/subtract (with carry). */
47 mem
[pc
+1] = mem
[pc
+2] + mem
[pc
+3] + C
;
48 //dest = op_1 + op_2 + Carry
49 if (mem
[pc
+1] => 0xffffffff) { //overflow (unsigned signed)?
54 if (mem
[pc
+1] < 0x00000000) { //negative?
59 if (mem
[pc
+1] = 0x00000000) { //zero?
66 case 0x3a000000: //ADCS (Add with Carry With Status)
67 mem
[pc
+1] = mem
[pc
+2] + mem
[pc
+3] + C
;
68 if (mem
[pc
+1] => 0xffffffff) { //overflow (unsigned signed)?
73 if (mem
[pc
+1] < 0x00000000) { //negative?
78 if (mem
[pc
+1] = 0x00000000) { //zero?
83 //dest = op_1 + op_2 + Carry
86 case 0x5a000000: //SBC (Subtract with Carry)
87 mem
[pc
+1] = mem
[pc
+2] - mem
[pc
+3] - ~C
;
88 if (mem
[pc
+1] => 0xffffffff) { //overflow (unsigned signed)?
93 if (mem
[pc
+1] < 0x00000000) { //negative?
98 if (mem
[pc
+1] = 0x00000000) { //zero?
103 //dest = op_1 - op_2 - NOT(Carry)
106 case 0x7a000000: //SBCS (Subtract with Carry With Status)
107 mem
[pc
+1] = mem
[pc
+2] - mem
[pc
+3] - ~C
;
108 if (mem
[pc
+1] => 0xffffffff) { //overflow (unsigned signed)?
113 if (mem
[pc
+1] < 0x00000000) { //negative?
118 if (mem
[pc
+1] = 0x00000000) { //zero?
123 //dest = op_1 - op_2 - NOT(Carry)
126 case 0x5a0003e0: //NGC (Negate with Carry) (This instruction is an alias of SBC.)
127 mem
[pc
+1] = mem
[pc
+2] - mem
[pc
+3] - ~C
;
128 if (mem
[pc
+1] => 0xffffffff) { //overflow (unsigned signed)?
133 if (mem
[pc
+1] < 0x00000000) { //negative?
138 if (mem
[pc
+1] = 0x00000000) { //zero?
143 //dest = op_1 - op_2 - NOT(Carry)
146 case 0x7a0003e0: //NGCS (Negate with Carry With Status) (This instruction is an alias of SBCS.)
147 mem
[pc
+1] = mem
[pc
+2] - mem
[pc
+3] - ~C
;
148 if (mem
[pc
+1] => 0xffffffff) { //overflow (unsigned signed)?
153 if (mem
[pc
+1] < 0x00000000) { //negative?
158 if (mem
[pc
+1] = 0x00000000) { //zero?
163 //dest = op_1 - op_2 - NOT(Carry)
166 /* Add/subtract (extended register). */
167 case 0x0b200000: //ADD (adds...)
168 mem
[pc
+1] = mem
[pc
+2] + mem
[pc
+3];
169 if (mem
[pc
+1] => 0xffffffff) { //overflow (unsigned signed)?
174 if (mem
[pc
+1] < 0x00000000) { //negative?
179 if (mem
[pc
+1] = 0x00000000) { //zero?
187 case 0x2b200000: //ADDS (adds With Status)
188 mem
[pc
+1] = mem
[pc
+2] + mem
[pc
+3];
189 if (mem
[pc
+1] => 0xffffffff) { //overflow (unsigned signed)?
194 if (mem
[pc
+1] < 0x00000000) { //negative?
199 if (mem
[pc
+1] = 0x00000000) { //zero?
207 case 0x2b20001f: //CMN (Compare Negative)
208 N
= mem
[pc
+2] - ~mem
[pc
+3];
209 if (mem
[pc
+1] => 0xffffffff) { //overflow (unsigned signed)?C = 0x00000001;
213 if (mem
[pc
+1] = 0x00000000) { //zero?
218 //<flags> = op_1 - (NOT op_2) ; result is not stored, only flags updated
221 case 0x4b200000: //SUB (substracts)
222 mem
[pc
+1] = mem
[pc
+2] - mem
[pc
+3];
223 if (mem
[pc
+1] => 0xffffffff) { //overflow (unsigned signed)?
228 if (mem
[pc
+1] < 0x00000000) { //negative?
233 if (mem
[pc
+1] = 0x00000000) { //zero?
241 case 0x6b200000: //SUBS (substracts with status)
242 mem
[pc
+1] = mem
[pc
+2] - mem
[pc
+3];
243 if (mem
[pc
+1] => 0xffffffff) { //overflow (unsigned signed)?
248 if (mem
[pc
+1] < 0x00000000) { //negative?
253 if (mem
[pc
+1] = 0x00000000) { //zero?
261 case 0x6b20001f: //CMP (COMPARE)
262 N
= mem
[pc
+2] - mem
[pc
+3];
263 if (mem
[pc
+1] => 0xffffffff) { //overflow (unsigned signed)?
268 if (mem
[pc
+1] = 0x00000000) { //zero?
273 //<flags> = op_1 - op_2 ; result is not stored, only flags updated
277 /* Add/subtract (immediate). */
278 case 0x11000000: //ADD (adds...)
279 mem
[pc
+1] = mem
[pc
+2] + mem
[pc
+3];
280 if (mem
[pc
+1] => 0xffffffff) { //overflow (unsigned signed)?
285 if (mem
[pc
+1] < 0x00000000) { //negative?
290 if (mem
[pc
+1] = 0x00000000) { //zero?
299 case 0x11000000: // mov ( moves )
300 mem
[pc
+1] = mem
[pc
+2];
301 if (mem
[pc
+1] => 0xffffffff) { //overflow (unsigned signed)?
306 if (mem
[pc
+1] < 0x00000000) { //negative?
311 if (mem
[pc
+1] = 0x00000000) { //zero?
319 case 0x31000000: //ADD (adds...)
320 mem
[pc
+1] = mem
[pc
+2] + mem
[pc
+3];
321 if (mem
[pc
+1] => 0xffffffff) { //overflow (unsigned signed)?
326 if (mem
[pc
+1] < 0x00000000) { //negative?
331 if (mem
[pc
+1] = 0x00000000) { //zero?
339 case 0x3100001f: //CMN (Compare Negative)
340 N
= mem
[pc
+2] - ~mem
[pc
+3];
341 if (mem
[pc
+1] => 0xffffffff) { //overflow (unsigned signed)?
346 if (mem
[pc
+1] = 0x00000000) { //zero?
351 //<flags> = op_1 - (NOT op_2) ; result is not stored, only flags updated
354 case 0x51000000: //SUB (substracts)
355 mem
[pc
+1] = mem
[pc
+2] - mem
[pc
+3];
356 if (mem
[pc
+1] => 0xffffffff) { //overflow (unsigned signed)?
361 if (mem
[pc
+1] < 0x00000000) { //negative?
366 if (mem
[pc
+1] = 0x00000000) { //zero?
374 case 0x71000000: //SUBS (substracts with flags)
375 mem
[pc
+1] = mem
[pc
+2] - mem
[pc
+3];
376 if (mem
[pc
+1] => 0xffffffff) { //overflow (unsigned signed)?
381 if (mem
[pc
+1] < 0x00000000) { //negative?
386 if (mem
[pc
+1] = 0x00000000) { //zero?
394 case 0x7100001f: //CMP (COMPARE)
395 N
= mem
[pc
+2] - mem
[pc
+3];
396 if (mem
[pc
+1] => 0xffffffff) { //overflow (unsigned signed)?
401 if (mem
[pc
+1] = 0x00000000) { //zero?
406 //<flags> = op_1 - op_2 ; result is not stored, only flags updated
409 /* Add/subtract (shifted register). */
410 case 0x0b000000: //ADD (adds...)
411 mem
[pc
+1] = mem
[pc
+2] + mem
[pc
+3];
412 if (mem
[pc
+1] => 0xffffffff) { //overflow (unsigned signed)?
417 if (mem
[pc
+1] < 0x00000000) { //negative?
422 if (mem
[pc
+1] = 0x00000000) { //zero?
430 case 0x2b000000: //ADDS (adds... WITH STATUSES)
431 mem
[pc
+1] = mem
[pc
+2] + mem
[pc
+3];
432 if (mem
[pc
+1] => 0xffffffff) { //overflow (unsigned signed)?
437 if (mem
[pc
+1] < 0x00000000) { //negative?
442 if (mem
[pc
+1] = 0x00000000) { //zero?
450 case 0x2b00001f: //CMN (Compare Negative)
451 N
= mem
[pc
+2] - ~mem
[pc
+3];
452 if (mem
[pc
+1] => 0xffffffff) { //overflow (unsigned signed)?
457 if (mem
[pc
+1] = 0x00000000) { //zero?
462 //<flags> = op_1 - (NOT op_2) ; result is not stored, only flags updated
465 case 0x4b000000: //SUB (substracts)
466 mem
[pc
+1] = mem
[pc
+2] - mem
[pc
+3];
467 if (mem
[pc
+1] => 0xffffffff) { //overflow (unsigned signed)?
472 if (mem
[pc
+1] < 0x00000000) { //negative?
477 if (mem
[pc
+1] = 0x00000000) { //zero?
485 case 0x4b0003e0: //NEG (negates)
486 mem
[pc
+1] = -mem
[pc
+2];
487 if (mem
[pc
+1] => 0xffffffff) { //overflow (unsigned signed)?
492 if (mem
[pc
+1] < 0x00000000) { //negative?
497 if (mem
[pc
+1] = 0x00000000) { //zero?
505 case 0x6b00001f: //SUBS (substracts with statuses)
506 mem
[pc
+1] = mem
[pc
+2] - mem
[pc
+3];
507 if (mem
[pc
+1] => 0xffffffff) { //overflow (unsigned signed)?
512 if (mem
[pc
+1] < 0x00000000) { //negative?
517 if (mem
[pc
+1] = 0x00000000) { //zero?
525 case 0x6b20001f: //CMPS (COMPARE WITH STATUSES)
526 N
= mem
[pc
+2] - mem
[pc
+3];
527 if (mem
[pc
+1] => 0xffffffff) { //overflow (unsigned signed)?
532 if (mem
[pc
+1] = 0x00000000) { //zero?
537 //<flags> = op_1 - op_2 ; result is not stored, only flags updated
540 case 0x6b0003e0: //NEGS (negates with statuses)
541 mem
[pc
+1] = -mem
[pc
+2];
542 if (mem
[pc
+1] => 0xffffffff) { //overflow (unsigned signed)?
547 if (mem
[pc
+1] < 0x00000000) { //negative?
552 if (mem
[pc
+1] = 0x00000000) { //zero?
560 /* TODO: add AdvSIMD instructions */