Small update

This commit is contained in:
Nekotekina 2015-03-17 03:44:35 +03:00
parent 0ca4c189a5
commit 573f112b37
2 changed files with 166 additions and 18 deletions

View File

@ -13,7 +13,7 @@
void ppu_interpreter::NULL_OP(PPUThread& CPU, ppu_opcode_t op)
{
throw __FUNCTION__;
PPUInterpreter inter(CPU); (*PPU_instr::main_list)(&inter, op.opcode);
}
void ppu_interpreter::NOP(PPUThread& CPU, ppu_opcode_t op)
@ -23,12 +23,30 @@ void ppu_interpreter::NOP(PPUThread& CPU, ppu_opcode_t op)
void ppu_interpreter::TDI(PPUThread& CPU, ppu_opcode_t op)
{
throw __FUNCTION__;
s64 a = CPU.GPR[op.ra];
if ((a < (s64)op.simm16 && (op.bo & 0x10)) ||
(a >(s64)op.simm16 && (op.bo & 0x8)) ||
(a == (s64)op.simm16 && (op.bo & 0x4)) ||
((u64)a < (u64)op.simm16 && (op.bo & 0x2)) ||
((u64)a >(u64)op.simm16 && (op.bo & 0x1)))
{
throw fmt::format("Trap! (tdi 0x%x, r%d, 0x%x)", op.bo, op.ra, op.simm16);
}
}
void ppu_interpreter::TWI(PPUThread& CPU, ppu_opcode_t op)
{
throw __FUNCTION__;
s32 a = (s32)CPU.GPR[op.ra];
if ((a < op.simm16 && (op.bo & 0x10)) ||
(a > op.simm16 && (op.bo & 0x8)) ||
(a == op.simm16 && (op.bo & 0x4)) ||
((u32)a < (u32)op.simm16 && (op.bo & 0x2)) ||
((u32)a >(u32)op.simm16 && (op.bo & 0x1)))
{
throw fmt::Format("Trap! (twi 0x%x, r%d, 0x%x)", op.bo, op.ra, op.simm16);
}
}
@ -39,6 +57,7 @@ void ppu_interpreter::MFVSCR(PPUThread& CPU, ppu_opcode_t op)
void ppu_interpreter::MTVSCR(PPUThread& CPU, ppu_opcode_t op)
{
// ignored (MFVSCR disabled)
}
void ppu_interpreter::VADDCUW(PPUThread& CPU, ppu_opcode_t op)
@ -59,57 +78,144 @@ void ppu_interpreter::VADDFP(PPUThread& CPU, ppu_opcode_t op)
void ppu_interpreter::VADDSBS(PPUThread& CPU, ppu_opcode_t op)
{
PPUInterpreter inter(CPU); (*PPU_instr::main_list)(&inter, op.opcode);
for (u32 b = 0; b < 16; ++b)
{
s16 result = (s16)CPU.VPR[op.va]._s8[b] + (s16)CPU.VPR[op.vb]._s8[b];
if (result > 0x7f)
{
CPU.VPR[op.vd]._s8[b] = 0x7f;
}
else if (result < -0x80)
{
CPU.VPR[op.vd]._s8[b] = -0x80;
}
else
CPU.VPR[op.vd]._s8[b] = (s8)result;
}
}
void ppu_interpreter::VADDSHS(PPUThread& CPU, ppu_opcode_t op)
{
PPUInterpreter inter(CPU); (*PPU_instr::main_list)(&inter, op.opcode);
for (uint h = 0; h < 8; h++)
{
s32 result = (s32)CPU.VPR[op.va]._s16[h] + (s32)CPU.VPR[op.vb]._s16[h];
if (result > 0x7fff)
{
CPU.VPR[op.vd]._s16[h] = 0x7fff;
}
else if (result < -0x8000)
{
CPU.VPR[op.vd]._s16[h] = -0x8000;
}
else
CPU.VPR[op.vd]._s16[h] = result;
}
}
void ppu_interpreter::VADDSWS(PPUThread& CPU, ppu_opcode_t op)
{
PPUInterpreter inter(CPU); (*PPU_instr::main_list)(&inter, op.opcode);
for (uint w = 0; w < 4; w++)
{
s64 result = (s64)CPU.VPR[op.va]._s32[w] + (s64)CPU.VPR[op.vb]._s32[w];
if (result > 0x7fffffff)
{
CPU.VPR[op.vd]._s32[w] = 0x7fffffff;
}
else if (result < (s32)0x80000000)
{
CPU.VPR[op.vd]._s32[w] = 0x80000000;
}
else
CPU.VPR[op.vd]._s32[w] = (s32)result;
}
}
void ppu_interpreter::VADDUBM(PPUThread& CPU, ppu_opcode_t op)
{
PPUInterpreter inter(CPU); (*PPU_instr::main_list)(&inter, op.opcode);
for (uint b = 0; b < 16; b++)
{
CPU.VPR[op.vd]._u8[b] = CPU.VPR[op.va]._u8[b] + CPU.VPR[op.vb]._u8[b];
}
}
void ppu_interpreter::VADDUBS(PPUThread& CPU, ppu_opcode_t op)
{
PPUInterpreter inter(CPU); (*PPU_instr::main_list)(&inter, op.opcode);
for (uint b = 0; b < 16; b++)
{
u16 result = (u16)CPU.VPR[op.va]._u8[b] + (u16)CPU.VPR[op.vb]._u8[b];
if (result > 0xff)
{
CPU.VPR[op.vd]._u8[b] = 0xff;
}
else
CPU.VPR[op.vd]._u8[b] = (u8)result;
}
}
void ppu_interpreter::VADDUHM(PPUThread& CPU, ppu_opcode_t op)
{
PPUInterpreter inter(CPU); (*PPU_instr::main_list)(&inter, op.opcode);
for (uint h = 0; h < 8; h++)
{
CPU.VPR[op.vd]._u16[h] = CPU.VPR[op.va]._u16[h] + CPU.VPR[op.vb]._u16[h];
}
}
void ppu_interpreter::VADDUHS(PPUThread& CPU, ppu_opcode_t op)
{
PPUInterpreter inter(CPU); (*PPU_instr::main_list)(&inter, op.opcode);
for (uint h = 0; h < 8; h++)
{
u32 result = (u32)CPU.VPR[op.va]._u16[h] + (u32)CPU.VPR[op.vb]._u16[h];
if (result > 0xffff)
{
CPU.VPR[op.vd]._u16[h] = 0xffff;
}
else
CPU.VPR[op.vd]._u16[h] = result;
}
}
void ppu_interpreter::VADDUWM(PPUThread& CPU, ppu_opcode_t op)
{
PPUInterpreter inter(CPU); (*PPU_instr::main_list)(&inter, op.opcode);
for (uint w = 0; w < 4; w++)
{
CPU.VPR[op.vd]._u32[w] = CPU.VPR[op.va]._u32[w] + CPU.VPR[op.vb]._u32[w];
}
}
void ppu_interpreter::VADDUWS(PPUThread& CPU, ppu_opcode_t op)
{
PPUInterpreter inter(CPU); (*PPU_instr::main_list)(&inter, op.opcode);
for (uint w = 0; w < 4; w++)
{
u64 result = (u64)CPU.VPR[op.va]._u32[w] + (u64)CPU.VPR[op.vb]._u32[w];
if (result > 0xffffffff)
{
CPU.VPR[op.vd]._u32[w] = 0xffffffff;
}
else
CPU.VPR[op.vd]._u32[w] = (u32)result;
}
}
void ppu_interpreter::VAND(PPUThread& CPU, ppu_opcode_t op)
{
PPUInterpreter inter(CPU); (*PPU_instr::main_list)(&inter, op.opcode);
for (uint w = 0; w < 4; w++)
{
CPU.VPR[op.vd]._u32[w] = CPU.VPR[op.va]._u32[w] & CPU.VPR[op.vb]._u32[w];
}
}
void ppu_interpreter::VANDC(PPUThread& CPU, ppu_opcode_t op)
{
PPUInterpreter inter(CPU); (*PPU_instr::main_list)(&inter, op.opcode);
for (uint w = 0; w < 4; w++)
{
CPU.VPR[op.vd]._u32[w] = CPU.VPR[op.va]._u32[w] & (~CPU.VPR[op.vb]._u32[w]);
}
}
void ppu_interpreter::VAVGSB(PPUThread& CPU, ppu_opcode_t op)

View File

@ -7,6 +7,27 @@ union ppu_opcode_t
{
u32 opcode;
struct
{
u32 rc : 1; // 31
u32 shh : 1; // 30
u32 : 3; // 27..29
u32 mbmeh : 1; // 26
u32 mbmel : 5; // 21..25
u32 shl : 5; // 16..20
u32 vuimm : 5; // 11..15
u32 vs : 5; // 6..10
u32 : 6;
};
struct
{
u32 : 6; // 26..31
u32 vsh : 4; // 22..25
u32 : 1; // 21
u32 spr : 10; // 11..20
};
struct
{
u32 : 6; // 26..31
@ -14,7 +35,7 @@ union ppu_opcode_t
u32 vb : 5; // 16..20
u32 va : 5; // 11..15
u32 vd : 5; // 6..10
u32 : 6; // 0..5
u32 : 6;
};
struct
@ -24,7 +45,7 @@ union ppu_opcode_t
u32 rb : 5; // 16..20
u32 ra : 5; // 11..15
u32 rd : 5; // 6..10
u32 : 6; // 0..5
u32 : 6;
};
struct
@ -32,13 +53,34 @@ union ppu_opcode_t
u32 uimm16 : 16; // 16..31
u32 : 5; // 11..15
u32 rs : 5; // 6..10
u32 : 6; // 0..5
u32 : 6;
};
struct
{
s32 simm16 : 16; // 16..31
s32 : 16;
s32 vsimm : 5; // 11..15
s32 : 11;
};
struct
{
u32 : 18; // 14..31
u32 crfs : 3; // 11..13
u32 : 2; // 9..10
u32 crfd : 3; // 6..8
u32 : 6;
};
struct
{
u32 rc : 1; // 31
u32 me : 5; // 26..30
u32 mb : 5; // 21..25
u32 sh : 5; // 16..20
u32 bi : 5; // 11..15
u32 bo : 5; // 6..10
u32 : 6;
};
};