From 573f112b37f9e9623b47ae4654be5eeae78c0e4d Mon Sep 17 00:00:00 2001 From: Nekotekina Date: Tue, 17 Mar 2015 03:44:35 +0300 Subject: [PATCH] Small update --- rpcs3/Emu/Cell/PPUInterpreter.cpp | 134 ++++++++++++++++++++++++++---- rpcs3/Emu/Cell/PPUInterpreter2.h | 50 ++++++++++- 2 files changed, 166 insertions(+), 18 deletions(-) diff --git a/rpcs3/Emu/Cell/PPUInterpreter.cpp b/rpcs3/Emu/Cell/PPUInterpreter.cpp index d38adcf020..2188f160a1 100644 --- a/rpcs3/Emu/Cell/PPUInterpreter.cpp +++ b/rpcs3/Emu/Cell/PPUInterpreter.cpp @@ -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) diff --git a/rpcs3/Emu/Cell/PPUInterpreter2.h b/rpcs3/Emu/Cell/PPUInterpreter2.h index d99396d756..f6399b394b 100644 --- a/rpcs3/Emu/Cell/PPUInterpreter2.h +++ b/rpcs3/Emu/Cell/PPUInterpreter2.h @@ -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; }; };