ultimecia

A ps1 emulator in c
Log | Files | Refs

cpu.c (19069B)


      1 #include <stdio.h>
      2 #include <stdlib.h>
      3 #include <string.h>
      4 #include "interconnect.h"
      5 #include "cpu.h"
      6 #include "types.h"
      7 #include "util.h"
      8 #include "log.h"
      9 
     10 CPU*
     11 new_cpu(Interconnect* inter) {
     12 	CPU* cpu = (CPU*)malloc(sizeof(CPU));
     13 
     14 	cpu->pc = 0xBFC00000;
     15 	cpu->next_pc = cpu->pc + 4;
     16 	cpu->current_pc = 0;
     17 	cpu->cause = 0x0; cpu->epc = 0x0; cpu->sr = 0x0;
     18 	cpu->hi = 0xdeaddead;
     19 	cpu->lo = 0xdeaddead;
     20 	cpu->branch = 0;
     21 	cpu->delay_slot = 0;
     22 	cpu->inter = inter;
     23 	cpu->load._0 = 0; cpu->load._1 = 0;
     24 	cpu->next_instruction = new_instr(0); /* NOP */
     25 	memset(cpu->regs, 0, sizeof(cpu->regs));
     26 	memset(cpu->out_regs, 0, sizeof(cpu->out_regs));
     27 	return cpu;
     28 }
     29 
     30 u32 CPU_load32(CPU* cpu, u32 addr) { return INTER_load32(cpu->inter, addr); }
     31 u16 CPU_load16(CPU* cpu, u32 addr) { return INTER_load16(cpu->inter, addr); }
     32 u8 CPU_load8(CPU* cpu, u32 addr) { return INTER_load8(cpu->inter, addr); }
     33 
     34 void CPU_store32(CPU* cpu, u32 addr, u32 val) { INTER_store32(cpu->inter, addr, val); }
     35 void CPU_store16(CPU* cpu, u32 addr, u16 val) { INTER_store16(cpu->inter, addr, val); }
     36 void CPU_store8(CPU*  cpu, u32 addr, u8  val) { INTER_store8(cpu->inter, addr, val); }
     37 void set_reg(CPU* cpu, u32 reg, u32 val) { cpu->out_regs[reg] = val; cpu->out_regs[0] = 0; }
     38 u32 reg(CPU* cpu, u32 reg) { return cpu->out_regs[reg]; }
     39 
     40 void
     41 exception(CPU* cpu, EXCEPTION cause)
     42 {
     43 	u32 handler, mode;
     44 
     45 	handler = ((cpu->sr & (1 << 22)) != 0) ? 0xBFC00180 : 0x80000080;
     46 	mode = cpu->sr & 0x3f;
     47 	cpu->sr &= ~0x3f;
     48 	cpu->sr |= (mode << 2) & 0x3f;
     49 	cpu->cause = (u32)cause << 2;
     50 	cpu->epc = cpu->current_pc;
     51 
     52 	if (cpu->delay_slot)
     53 	{
     54 		cpu->epc -= 4;
     55 		cpu->cause |= 1 << 31;
     56 	}
     57 
     58 	cpu->pc = handler;
     59 	cpu->next_pc = cpu->pc + 4;
     60 
     61 	return;
     62 }
     63 
     64 
     65 void
     66 op_lui(CPU* cpu, instruction* i)
     67 {
     68   u32 v = i->imm << 16;
     69   set_reg(cpu, i->t, v);
     70 }
     71 
     72 void
     73 op_or(CPU* cpu, instruction* i)
     74 {
     75   u32 v;
     76   v = reg(cpu, i->s) | reg(cpu, i->t);
     77   set_reg(cpu, i->d, v);
     78 }
     79 
     80 void
     81 op_xor(CPU* cpu, instruction* i)
     82 {
     83   u32 v;
     84   v = reg(cpu, i->s) ^ reg(cpu, i->t);
     85   set_reg(cpu, i->d, v);
     86 }
     87 
     88 void
     89 op_nor(CPU* cpu, instruction* i)
     90 {
     91   u32 v;
     92   v = !(reg(cpu, i->s) | reg(cpu, i->t));
     93   set_reg(cpu, i->d, v);
     94 }
     95 
     96 void
     97 op_and(CPU* cpu, instruction* i)
     98 {
     99   u32 v;
    100   v = reg(cpu, i->s) & reg(cpu, i->t);
    101   set_reg(cpu, i->d, v);
    102 }
    103 
    104 void
    105 op_ori(CPU* cpu, instruction* i)
    106 {
    107   u32 v;
    108   v = reg(cpu, i->s) | i->imm;
    109   set_reg(cpu, i->t, v);
    110 }
    111 
    112 void
    113 op_xori(CPU* cpu, instruction* i)
    114 {
    115   u32 v;
    116   v = reg(cpu, i->s) ^ i->imm;
    117   set_reg(cpu, i->t, v);
    118 }
    119 
    120 void
    121 op_sw(CPU* cpu, instruction* i)
    122 {
    123   u32 imm_se, t, s, addr, v;
    124 
    125   if ((cpu->sr & 0x10000) != 0)
    126   {
    127     log_debug("ignoring store while cache is isolated!");
    128     return;
    129   }
    130 
    131   imm_se = i->imm_se; 
    132   t = i->t; 
    133   s = i->s;
    134   
    135   addr = reg(cpu, s) + imm_se;
    136   v = reg(cpu, t);
    137 	if ((addr % 4) == 0)
    138 	{
    139 		CPU_store32(cpu, addr, v);
    140 	}
    141 	else
    142 	{
    143 		exception(cpu, E_STORE_ADRESS_ERROR);
    144 	}
    145 }
    146 
    147 void
    148 op_swl(CPU* cpu, instruction* i)
    149 {
    150   u32 addr, v, aligned_addr, cur_mem, mem;
    151 
    152   addr = reg(cpu, i->s) + i->imm_se;
    153   v = reg(cpu, i->t);
    154 	aligned_addr = addr & ~3;
    155 	cur_mem = CPU_load32(cpu, aligned_addr);
    156 
    157 	switch(addr & 3)
    158 	{
    159 		case 0: mem = (cur_mem & 0xffffff00) | (v >> 24); break; 
    160 		case 1: mem = (cur_mem & 0xffff0000) | (v >> 16); break;
    161 		case 2: mem = (cur_mem & 0xff000000) | (v >> 8); break;
    162 		case 3: mem = (cur_mem & 0x00000000) | (v >> 0); break;
    163 		default: log_fatal("* STORE WORD LEFT.. WHAT ARE YOU DOING *"); exit(EXIT_FAILURE);
    164 	}
    165 
    166 	CPU_store32(cpu, addr, mem);
    167 }
    168 
    169 void
    170 op_swr(CPU* cpu, instruction* i)
    171 {
    172   u32 addr, v, aligned_addr, cur_mem, mem;
    173 
    174   addr = reg(cpu, i->s) + i->imm_se;
    175   v = reg(cpu, i->t);
    176 	aligned_addr = addr & ~3;
    177 	cur_mem = CPU_load32(cpu, aligned_addr);
    178 
    179 	switch(addr & 3)
    180 	{
    181 		case 0: mem = (cur_mem & 0x00000000) | (v << 0); break; 
    182 		case 1: mem = (cur_mem & 0x000000ff) | (v << 8); break;
    183 		case 2: mem = (cur_mem & 0x0000ffff) | (v << 16); break;
    184 		case 3: mem = (cur_mem & 0x00ffffff) | (v << 24); break;
    185 		default: log_fatal("* STORE WORD RIGHT.. WHAT ARE YOU DOING *"); exit(EXIT_FAILURE);
    186 	}
    187 
    188 	CPU_store32(cpu, addr, mem);
    189 }
    190 
    191 void
    192 op_sh(CPU* cpu, instruction* i)
    193 {
    194   u32 imm_se, t, s, addr, v;
    195 
    196   if ((cpu->sr & 0x10000) != 0)
    197   {
    198     log_info("ignoring store while cache is isolated!");
    199     return;
    200   }
    201 
    202   imm_se = i->imm_se; 
    203   t = i->t; 
    204   s = i->s;
    205   
    206   addr = reg(cpu, s) + imm_se;
    207   v = reg(cpu, t);
    208 
    209 	if ((addr % 2) == 0)
    210 	{
    211 		CPU_store16(cpu, addr, (u16)v);
    212 	}
    213 	else
    214 	{
    215 		exception(cpu, E_STORE_ADRESS_ERROR);
    216 	}
    217 }
    218 
    219 void
    220 op_sb(CPU* cpu, instruction* i)
    221 {
    222   u32 imm_se, t, s, addr, v;
    223 
    224   if ((cpu->sr & 0x10000) != 0)
    225   {
    226     log_info("ignoring store while cache is isolated!");
    227     return;
    228   }
    229 
    230   imm_se = i->imm_se; 
    231   t = i->t; 
    232   s = i->s;
    233   
    234   addr = reg(cpu, s) + imm_se;
    235   v = reg(cpu, t);
    236   CPU_store8(cpu, addr, (u8)v);
    237 }
    238 
    239 void
    240 op_sll(CPU* cpu, instruction* i)
    241 {
    242   u32 shift, t, d, v;
    243 
    244   shift = i->shift;
    245   t = i->t;
    246   d = i->d;
    247 
    248   v = reg(cpu, t) << shift;
    249   set_reg(cpu, d, v);
    250 
    251 }
    252 
    253 void
    254 op_srlv(CPU* cpu, instruction* i)
    255 {
    256   u32 v;
    257 
    258   v = reg(cpu, i->t) >> (reg(cpu, i->s) & 0x1f);
    259   set_reg(cpu, i->d, v);
    260 }
    261 
    262 void
    263 op_sllv(CPU* cpu, instruction* i)
    264 {
    265   u32 v;
    266 
    267   v = reg(cpu, i->t) << (reg(cpu, i->s) & 0x1f);
    268   set_reg(cpu, i->d, v);
    269 }
    270 
    271 void
    272 op_addiu(CPU* cpu, instruction* i)
    273 {
    274   u32 v;
    275   v = reg(cpu, i->s) + i->imm_se;
    276   set_reg(cpu, i->t, v);
    277 }
    278 
    279 void
    280 op_addi(CPU* cpu, instruction* i)
    281 {
    282   i32 v;
    283   i32 imm_se;
    284   i32 res;
    285 
    286   imm_se = (i32)i->imm_se;
    287   v = (i32)reg(cpu, i->s);
    288 
    289   if(checked_addi32(v, imm_se, &res))
    290     set_reg(cpu, i->t, res);
    291   else
    292 		exception(cpu, E_OVERFLOW);
    293 }
    294 
    295 void
    296 op_j(CPU* cpu, instruction* i)
    297 {
    298   cpu->next_pc = (cpu->next_pc & 0xf0000000) | (i->imm_jump << 2);
    299 	cpu->branch = 1;
    300 }
    301 
    302 void 
    303 op_jal(CPU* cpu, instruction* i) 
    304 { 
    305 	set_reg(cpu, 31, cpu->next_pc); 
    306 	op_j(cpu, i); 
    307 }
    308 
    309 void 
    310 op_jr(CPU* cpu, instruction* i) 
    311 { 
    312 	cpu->next_pc = reg(cpu, i->s); 
    313 	cpu->branch = 1;
    314 }
    315 
    316 void op_jalr(CPU* cpu, instruction* i) 
    317 { 
    318   set_reg(cpu, i->d, cpu->next_pc);
    319   cpu->next_pc = reg(cpu, i->s);
    320 	cpu->branch = 1;
    321 }
    322 
    323 void
    324 op_mtc0(CPU* cpu, instruction* i)
    325 {
    326   u32 cop_r, v;
    327 
    328   cop_r = i->d; 
    329   v = reg(cpu, i->t);
    330 
    331   switch(cop_r) {
    332   case 3: case 5: case 6: case 7: case 9: case 11:
    333     if (v != 0)
    334     {
    335       log_fatal("Unhandled cop0r%d", cop_r);
    336       exit(EXIT_FAILURE);
    337     }
    338     break;
    339   case 12: 
    340     cpu->sr = v;
    341     break;
    342   case 13: 
    343     if (v != 0)
    344     {
    345       log_fatal("Unhandled write to CAUSE register");
    346       exit(EXIT_FAILURE);
    347     }
    348     break;
    349   default: 
    350     log_fatal("Unhandled cop0 register %d", cop_r); 
    351     exit(EXIT_FAILURE);
    352   }
    353 }
    354 
    355 void
    356 op_mfc0(CPU* cpu, instruction* i)
    357 {
    358   u32 cop_r;
    359 
    360   cop_r = i->d; 
    361 
    362   switch(cop_r) {
    363   case 12: 
    364     cpu->load._0 = i->t;
    365     cpu->load._1 = cpu->sr;
    366     break;
    367   case 13: 
    368     cpu->load._0 = i->t;
    369     cpu->load._1 = cpu->cause;
    370     break;
    371   case 14: 
    372     cpu->load._0 = i->t;
    373     cpu->load._1 = cpu->epc;
    374     break;
    375   default: 
    376     log_fatal("Unhandled read from cop0r%d", cop_r); 
    377     exit(EXIT_FAILURE);
    378   }
    379 }
    380 
    381 void
    382 op_rfe(CPU* cpu, instruction* i)
    383 {
    384 	u32 mode;
    385 
    386 	if ((i->_0 & 0x3f) != 0x10)
    387 	{
    388 		log_fatal("Invalid cop0 instruction %08X", i->_0);
    389 		exit(EXIT_FAILURE);
    390 	}
    391 
    392 	mode = cpu->sr & 0x3f;
    393 	cpu->sr &= ~0x3f;
    394 	cpu->sr |= mode >> 2;
    395 }
    396 
    397 void
    398 op_cop0(CPU* cpu, instruction* i)
    399 {
    400   switch (i->cop_opcode) {
    401   case 0x00: op_mfc0(cpu, i); break;
    402   case 0x04: op_mtc0(cpu, i); break;
    403 	case 0x10: op_rfe(cpu, i); break;
    404   default: log_fatal("Unhandled cop0 instruction %08X", i->_0); exit(EXIT_FAILURE);
    405   }
    406 }
    407 
    408 void
    409 op_cop1(CPU* cpu, instruction* i)
    410 {
    411 	(void)i;
    412 	exception(cpu, E_COPROCESSOR_ERROR);
    413 }
    414 
    415 /* GTE */
    416 void
    417 op_cop2(CPU* cpu, instruction* i)
    418 {
    419 	(void)i;(void)cpu;
    420 	log_fatal("Unhandle GTE Instruction: %08X", i->_0);
    421 	exit(EXIT_FAILURE);
    422 	/* exception(cpu, E_COPROCESSOR_ERROR); */
    423 }
    424 
    425 void
    426 op_cop3(CPU* cpu, instruction* i)
    427 {
    428 	(void)i;
    429 	exception(cpu, E_COPROCESSOR_ERROR);
    430 }
    431 
    432 void
    433 branch(CPU* cpu, u32 offset)
    434 {
    435   cpu->next_pc += (offset << 2) - 4;
    436 	cpu->branch = 1;
    437 }
    438 
    439 void
    440 op_bne(CPU* cpu, instruction* i)
    441 {
    442   if (reg(cpu, i->s) != reg(cpu, i->t)) branch(cpu, i->imm_se);
    443 }
    444 
    445 void
    446 op_beq(CPU* cpu, instruction* i)
    447 {
    448   if (reg(cpu, i->s) == reg(cpu, i->t)) branch(cpu, i->imm_se);
    449 }
    450 
    451 void
    452 op_bgtz(CPU* cpu, instruction* i)
    453 {
    454   i32 v;
    455 
    456   v = (i32)reg(cpu, i->s);
    457 
    458   if (v > 0)
    459     branch(cpu, i->imm_se);
    460 }
    461 
    462 void
    463 op_blez(CPU* cpu, instruction* i)
    464 {
    465   i32 v;
    466 
    467   v = (i32)reg(cpu, i->s);
    468 
    469   if (v <= 0)
    470     branch(cpu, i->imm_se);
    471 }
    472 
    473 void
    474 op_bxx(CPU* cpu, instruction* i)
    475 {
    476   u8 is_bgez, is_link;
    477   u32 test;
    478   i32 v;
    479 
    480   is_bgez = (i->_0 >> 16) & 1;
    481   is_link = ((i->_0 >> 20) & 1) != 0;
    482 
    483   v = (i32)reg(cpu, i->s);
    484 
    485   test = v < 0;
    486 
    487   test = test ^ is_bgez;
    488 
    489   if (test != 0)
    490   {
    491     if (is_link)
    492       set_reg(cpu, 31, cpu->pc);
    493 
    494     branch(cpu, i->imm_se);
    495   }
    496 }
    497 
    498 void
    499 op_lw(CPU* cpu, instruction* i)
    500 {
    501   u32 v, addr;
    502 
    503   addr = reg(cpu, i->s) + i->imm_se;
    504 
    505 	if ((addr % 4) == 0)
    506 	{
    507 		v = CPU_load32(cpu, addr);
    508 
    509 		cpu->load._0 = i->t;
    510 		cpu->load._1 = v;
    511 	}
    512 	else
    513 	{
    514 		exception(cpu, E_STORE_ADRESS_ERROR);
    515 	}
    516 }
    517 
    518 void
    519 op_lwl(CPU* cpu, instruction* i)
    520 {
    521   u32 v, addr, cur_v, aligned_addr, aligned_word;
    522 
    523   addr = reg(cpu, i->s) + i->imm_se;
    524 
    525 	cur_v = cpu->out_regs[i->t];
    526 
    527 	aligned_addr = addr & ~3;
    528 	aligned_word = CPU_load32(cpu, aligned_addr);
    529 
    530 	switch(addr & 3)
    531 	{
    532 		case 0: v = (cur_v & 0x00ffffff) | (aligned_word << 24); break;
    533 		case 1: v = (cur_v & 0x0000ffff) | (aligned_word << 16); break;
    534 		case 2: v = (cur_v & 0x000000ff) | (aligned_word << 8); break;
    535 		case 3: v = (cur_v & 0x00000000) | (aligned_word << 0); break;
    536 		default: log_fatal("* LOAD WORD LEFT.. WHAT ARE YOU DOING *"); exit(EXIT_FAILURE);
    537 	}
    538 
    539 	cpu->load._0 = i->t;
    540 	cpu->load._1 = v;
    541 }
    542 
    543 void
    544 op_lwr(CPU* cpu, instruction* i)
    545 {
    546   u32 v, addr, cur_v, aligned_addr, aligned_word;
    547 
    548   addr = reg(cpu, i->s) + i->imm_se;
    549 
    550 	cur_v = cpu->out_regs[i->t];
    551 
    552 	aligned_addr = addr & ~3;
    553 	aligned_word = CPU_load32(cpu, aligned_addr);
    554 
    555 	switch(addr & 3)
    556 	{
    557 		case 0: v = (cur_v & 0x00000000) | (aligned_word >> 0); break;
    558 		case 1: v = (cur_v & 0xff000000) | (aligned_word >> 8); break;
    559 		case 2: v = (cur_v & 0xffff0000) | (aligned_word >> 16); break;
    560 		case 3: v = (cur_v & 0xffffff00) | (aligned_word >> 24); break;
    561 		default: log_fatal("* LOAD WORD RIGHT.. WHAT ARE YOU DOING *"); exit(EXIT_FAILURE);
    562 	}
    563 
    564 	cpu->load._0 = i->t;
    565 	cpu->load._1 = v;
    566 }
    567 
    568 void
    569 op_lb(CPU* cpu, instruction* i)
    570 {
    571   i8 v;
    572   u32 addr;
    573 
    574   addr = reg(cpu, i->s) + i->imm_se;
    575   v = (i8)CPU_load8(cpu, addr);
    576 
    577   cpu->load._0 = i->t;
    578   cpu->load._1 = (u32)v;
    579 }
    580 
    581 void
    582 op_lbu(CPU* cpu, instruction* i)
    583 {
    584   u32 v, addr;
    585 
    586   addr = reg(cpu, i->s) + i->imm_se;
    587   v = CPU_load8(cpu, addr);
    588 
    589   cpu->load._0 = i->t;
    590   cpu->load._1 = (u32)v;
    591 }
    592 
    593 void
    594 op_lh(CPU* cpu, instruction* i)
    595 {
    596   u32 addr;
    597 	i16 v;
    598 
    599   addr = reg(cpu, i->s) + i->imm_se;
    600 
    601 	if (addr % 2 == 0)
    602 	{
    603 		v = (i16)CPU_load16(cpu, addr);
    604 
    605 		cpu->load._0 = i->t;
    606 		cpu->load._1 = (u32)v;
    607 	}
    608 	else
    609 	{
    610 		exception(cpu, E_LOAD_ADRESS_ERROR);
    611 	}
    612 }
    613 
    614 void
    615 op_lhu(CPU* cpu, instruction* i)
    616 {
    617 	u32 v, addr;
    618 
    619 	addr = reg(cpu, i->s) + i->imm_se;
    620 
    621 	if (addr % 2 == 0)
    622 	{
    623 		v = CPU_load16(cpu, addr);
    624 
    625 		cpu->load._0 = i->t;
    626 		cpu->load._1 = (u32)v;
    627 	}
    628 	else
    629 	{
    630 		exception(cpu, E_LOAD_ADRESS_ERROR);
    631 	}
    632 }
    633 
    634 void
    635 op_slt(CPU* cpu, instruction* i)
    636 {
    637   u32 v;
    638 
    639   v = (i32)reg(cpu, i->s) < (i32)reg(cpu, i->t);
    640   set_reg(cpu, i->d, (u32)v);
    641 }
    642 
    643 void
    644 op_sltu(CPU* cpu, instruction* i)
    645 {
    646   u32 v;
    647 
    648   v = reg(cpu, i->s) < reg(cpu, i->t);
    649   set_reg(cpu, i->d, v);
    650 }
    651 
    652 void
    653 op_slti(CPU* cpu, instruction* i)
    654 {
    655   u32 v;
    656   v = (i32)reg(cpu, i->s) < (i32)i->imm_se;
    657   set_reg(cpu, i->t, v);
    658 }
    659 
    660 void
    661 op_sltiu(CPU* cpu, instruction* i)
    662 {
    663   u32 v;
    664   v = reg(cpu, i->s) < i->imm_se;
    665   set_reg(cpu, i->t, v);
    666 }
    667 
    668 void
    669 op_add(CPU* cpu, instruction* i)
    670 {
    671   i32 s, t;
    672   i32 res;
    673 
    674   s = (i32)reg(cpu, i->s);
    675   t = (i32)reg(cpu, i->t);
    676 
    677   if(checked_addi32(s, t, &res))
    678     set_reg(cpu, i->d, (u32)res);
    679   else
    680 		exception(cpu, E_OVERFLOW);
    681 }
    682 
    683 void
    684 op_addu(CPU* cpu, instruction* i)
    685 {
    686   u32 v;
    687 
    688   v = reg(cpu, i->t) + reg(cpu, i->s);
    689   set_reg(cpu, i->d, v);
    690 
    691 }
    692 
    693 void
    694 op_sub(CPU* cpu, instruction* i)
    695 {
    696   i32 s, t;
    697   i32 res;
    698 
    699   s = (i32)reg(cpu, i->s);
    700   t = (i32)reg(cpu, i->t);
    701 
    702   if(checked_subi32(s, t, &res))
    703     set_reg(cpu, i->d, (u32)res);
    704   else
    705 		exception(cpu, E_OVERFLOW);
    706 
    707 }
    708 
    709 void
    710 op_subu(CPU* cpu, instruction* i)
    711 {
    712   u32 v;
    713 
    714   v = reg(cpu, i->s) - reg(cpu, i->t);
    715   set_reg(cpu, i->d, v);
    716 
    717 }
    718 
    719 void
    720 op_andi(CPU* cpu, instruction *i)
    721 {
    722   u32 v;
    723   v = reg(cpu, i->s) & i->imm;
    724   set_reg(cpu, i->t, v);
    725 }
    726 
    727 void
    728 op_sra(CPU* cpu, instruction* i)
    729 {
    730   i32 v;
    731   v = (i32)reg(cpu, i->t) >> i->shift;
    732   set_reg(cpu, i->d, (u32)v);
    733 }
    734 
    735 void
    736 op_srav(CPU* cpu, instruction* i)
    737 {
    738   i32 v;
    739 
    740   v = (i32)reg(cpu, i->t) >> (reg(cpu, i->s) & 0x1f);
    741   set_reg(cpu, i->d, (u32)v);
    742 }
    743 
    744 void
    745 op_srl(CPU* cpu, instruction* i)
    746 {
    747   u32 v;
    748   v = reg(cpu, i->t) >> i->shift;
    749   set_reg(cpu, i->d, v);
    750 }
    751 
    752 void
    753 op_div(CPU* cpu, instruction* i)
    754 {
    755   i32 n, d;
    756 
    757   n = (i32)reg(cpu, i->s);
    758   d = (i32)reg(cpu, i->t);
    759   
    760   if (d == 0)
    761   {
    762     cpu->hi = (u32)n;
    763     if (n >= 0)
    764       cpu->lo = 0xffffffff;
    765     else
    766       cpu->lo = 1;
    767   }
    768   else if ((u32)n == 0x80000000 && d == -1)
    769   {
    770     cpu->hi = 0;
    771     cpu->lo = 0x80000000;
    772   }
    773   else
    774   {
    775     cpu->hi = (u32)(n % d);
    776     cpu->lo = (u32)(n / d);
    777   }
    778 }
    779 
    780 void
    781 op_divu(CPU* cpu, instruction* i)
    782 {
    783   u32 n, d;
    784 
    785   n = reg(cpu, i->s);
    786   d = reg(cpu, i->t);
    787   
    788   if (d == 0)
    789   {
    790     cpu->hi = (u32)n;
    791     cpu->lo = 0xffffffff;
    792   }
    793   else
    794   {
    795     cpu->hi = (n % d);
    796     cpu->lo = (n / d);
    797   }
    798 }
    799 
    800 void
    801 op_mult(CPU* cpu, instruction* i)
    802 {
    803   i64 a, b;
    804 	u64 v;
    805 
    806   a = (i64)((i32)reg(cpu, i->s));
    807   b = (i64)((i32)reg(cpu, i->t));
    808 
    809 	v = (u64)(a * b);
    810 
    811 	cpu->hi = (u32)(v >> 32); 
    812 	cpu->lo = (u32)v;
    813 }
    814 
    815 void
    816 op_multu(CPU* cpu, instruction* i)
    817 {
    818   u64 a, b, v;
    819 
    820   a = (u64)reg(cpu, i->s);
    821   b = (u64)reg(cpu, i->t);
    822 
    823 	v = a * b;
    824 
    825 	cpu->hi = (u32)(v >> 32); 
    826 	cpu->lo = (u32)v;
    827 }
    828 
    829 
    830 void
    831 op_mflo(CPU* cpu, instruction* i)
    832 {
    833   set_reg(cpu, i->d, cpu->lo);
    834 }
    835 
    836 void
    837 op_mtlo(CPU* cpu, instruction* i)
    838 {
    839 	cpu->lo = reg(cpu, i->s);
    840 }
    841 
    842 void
    843 op_mfhi(CPU* cpu, instruction* i)
    844 {
    845   set_reg(cpu, i->d, cpu->hi);
    846 }
    847 
    848 void
    849 op_mthi(CPU* cpu, instruction* i)
    850 {
    851 	cpu->hi = reg(cpu, i->s);
    852 }
    853 
    854 void op_syscall(CPU* cpu, instruction* i)
    855 {
    856 	(void)i;
    857 	exception(cpu, E_SYSCALL);
    858 }
    859 
    860 void
    861 op_break(CPU* cpu, instruction* i)
    862 {
    863 	(void)i;
    864 	exception(cpu, E_BREAK);
    865 }
    866 
    867 void op_lwc0(CPU* cpu, instruction* i) { (void)i; exception(cpu, E_COPROCESSOR_ERROR); }
    868 void op_lwc1(CPU* cpu, instruction* i) { (void)i; exception(cpu, E_COPROCESSOR_ERROR); }
    869 void op_lwc2(CPU* cpu, instruction* i) { (void)i; (void)cpu; log_fatal("Unhandled GTE LWC: %08X", i->_0); exit(EXIT_FAILURE); }
    870 void op_lwc3(CPU* cpu, instruction* i) { (void)i; exception(cpu, E_COPROCESSOR_ERROR); }
    871 
    872 void op_swc0(CPU* cpu, instruction* i) { (void)i; exception(cpu, E_COPROCESSOR_ERROR); }
    873 void op_swc1(CPU* cpu, instruction* i) { (void)i; exception(cpu, E_COPROCESSOR_ERROR); }
    874 void op_swc2(CPU* cpu, instruction* i) { (void)i; (void)cpu; log_fatal("Unhandled GTE SWC: %08X", i->_0); exit(EXIT_FAILURE); }
    875 void op_swc3(CPU* cpu, instruction* i) { (void)i; exception(cpu, E_COPROCESSOR_ERROR); }
    876 
    877 void
    878 op_illegal(CPU* cpu, instruction* i)
    879 {
    880 	(void)i;
    881 	log_warn("Illegal instruction %08X", i->_0);
    882 	exception(cpu, E_ILLEGAL_INSTRUCTION);
    883 }
    884 
    885 
    886 void
    887 CPU_decode_and_execute(CPU* cpu, instruction* i)
    888 {
    889 
    890   switch(i->fn) {
    891   case 0x0: 
    892       switch(i->sub) {
    893       case 0x0: op_sll(cpu, i); break; 
    894       case 0x02: op_srl(cpu, i); break;
    895       case 0x03: op_sra(cpu, i); break;
    896       case 0x0d: op_break(cpu, i); break;
    897       case 0x07: op_srav(cpu, i); break;
    898       case 0x04: op_sllv(cpu, i); break;
    899       case 0x06: op_srlv(cpu, i); break;
    900       case 0x08: op_jr(cpu, i); break;
    901       case 0x09: op_jalr(cpu, i); break;
    902       case 0x24: op_and(cpu, i); break;
    903       case 0x25: op_or(cpu, i); break;
    904       case 0x26: op_xor(cpu, i); break;
    905       case 0x27: op_nor(cpu, i); break;
    906       case 0x2a: op_slt(cpu, i); break;
    907       case 0x2B: op_sltu(cpu, i); break;
    908       case 0x20: op_add(cpu, i); break;
    909       case 0x21: op_addu(cpu, i); break;
    910       case 0x22: op_sub(cpu, i); break;
    911       case 0x23: op_subu(cpu, i); break;
    912       case 0x1a: op_div(cpu, i); break;
    913       case 0x1b: op_divu(cpu, i); break;
    914       case 0x10: op_mfhi(cpu, i); break;
    915       case 0x11: op_mthi(cpu, i); break;
    916       case 0x12: op_mflo(cpu, i); break;
    917       case 0x13: op_mtlo(cpu, i); break;
    918       case 0x18: op_mult(cpu, i); break;
    919       case 0x19: op_multu(cpu, i); break;
    920       case 0x0C: op_syscall(cpu, i); break;
    921       default: op_illegal(cpu, i); break;
    922       }
    923       break;
    924   case 0x01: op_bxx(cpu, i); break;
    925   case 0x02: op_j(cpu, i); break;
    926   case 0x03: op_jal(cpu, i); break;
    927   case 0x04: op_beq(cpu, i); break;
    928   case 0x05: op_bne(cpu, i); break;
    929   case 0x06: op_blez(cpu, i); break;
    930   case 0x07: op_bgtz(cpu, i); break;
    931   case 0x08: op_addi(cpu, i); break;
    932   case 0x09: op_addiu(cpu, i); break;
    933   case 0x0a: op_slti(cpu, i); break;
    934   case 0x0b: op_sltiu(cpu, i); break;
    935   case 0x0c: op_andi(cpu, i); break;
    936   case 0x0d: op_ori(cpu, i); break;
    937   case 0x0e: op_xori(cpu, i); break;
    938   case 0x0f: op_lui(cpu, i); break;
    939   case 0x10: op_cop0(cpu, i); break;
    940 	case 0x11: op_cop1(cpu, i); break;
    941 	case 0x12: op_cop2(cpu, i); break;
    942 	case 0x13: op_cop3(cpu, i); break;
    943   case 0x20: op_lb(cpu, i); break;
    944   case 0x21: op_lh(cpu, i); break;
    945 	case 0x22: op_lwl(cpu, i); break;
    946   case 0x23: op_lw(cpu, i); break;
    947   case 0x24: op_lbu(cpu, i); break;
    948 	case 0x25: op_lhu(cpu, i); break;
    949 	case 0x26: op_lwr(cpu, i); break;
    950 	case 0x2a: op_swl(cpu, i); break;
    951 	case 0x2e: op_swr(cpu, i); break;
    952   case 0x2b: op_sw(cpu, i); break;
    953   case 0x28: op_sb(cpu, i); break;
    954   case 0x29: op_sh(cpu, i); break;
    955   case 0x30: op_lwc0(cpu, i); break;
    956   case 0x31: op_lwc1(cpu, i); break;
    957   case 0x32: op_lwc2(cpu, i); break;
    958   case 0x33: op_lwc3(cpu, i); break;
    959   case 0x38: op_swc0(cpu, i); break;
    960   case 0x39: op_swc1(cpu, i); break;
    961   case 0x3a: op_swc2(cpu, i); break;
    962   case 0x3b: op_swc3(cpu, i); break;
    963   default: op_illegal(cpu, i); break;
    964   }
    965 
    966 }
    967 
    968 void
    969 CPU_run_next_instruction(CPU* cpu)
    970 {
    971 	instruction i = new_instr(CPU_load32(cpu, cpu->pc));
    972 
    973 	cpu->delay_slot = cpu->branch;
    974 	cpu->branch = 0;
    975 
    976 	cpu->current_pc = cpu->pc;
    977 
    978 	if ((cpu->current_pc % 4) != 0)
    979 	{
    980 		exception(cpu, E_LOAD_ADRESS_ERROR);
    981 		return;
    982 	}
    983     if (cpu->pc == 0x80058498) {
    984         //puts("Hey");
    985         //printf("cpu->pc: %08x\n", cpu->pc);
    986         //printf("Target: %08x\n", i.t);
    987         //printf("IMM: %08x\n", i.imm);
    988         //printf("FN: %08x\n", i.fn);
    989         //exit(1);
    990     }
    991 
    992 	cpu->pc = cpu->next_pc;
    993 	cpu->next_pc = cpu->next_pc + 4;
    994 
    995 	set_reg(cpu, cpu->load._0, cpu->load._1);
    996 
    997 	cpu->load._0 = 0; 
    998 	cpu->load._1 = 0;
    999 
   1000 	CPU_decode_and_execute(cpu, &i);
   1001 
   1002 	memcpy(cpu->regs, cpu->out_regs, sizeof(u32) * 32);
   1003 }
   1004 
   1005 instruction
   1006 new_instr(u32 i)
   1007 {
   1008 	instruction ins;
   1009 	ins._0 = i;
   1010 	ins.fn = i >> 26;
   1011 	ins.sub = i & 0x3f;
   1012 	ins.s = (i >> 21) & 0x1f;
   1013 	ins.t = (i >> 16) & 0x1f;
   1014 	ins.d = (i >> 11) & 0x1f;
   1015 	ins.shift = (i >> 6) & 0x1f;
   1016 	ins.imm = i & 0xffff;
   1017 	ins.imm_se = (u32)((i16)(i & 0xffff));
   1018 	ins.imm_jump = i & 0x3ffffff;
   1019 	ins.cop_opcode = (i >> 21) & 0x1f;
   1020 	return ins;
   1021 }