diff --git a/rpcs3/Emu/Cell/SPUDisAsm.h b/rpcs3/Emu/Cell/SPUDisAsm.h index 69d10c4c8a..4a417dbbd7 100644 --- a/rpcs3/Emu/Cell/SPUDisAsm.h +++ b/rpcs3/Emu/Cell/SPUDisAsm.h @@ -140,7 +140,7 @@ public: //0 - 10 void STOP(spu_opcode_t op) { - DisAsm("stop", op.opcode & 0x1fffff); + op.rb ? UNK(op) : DisAsm("stop", op.opcode & 0x3fff); } void LNOP(spu_opcode_t op) { diff --git a/rpcs3/Emu/Cell/SPUThread.cpp b/rpcs3/Emu/Cell/SPUThread.cpp index 02943234b6..2df51a765f 100644 --- a/rpcs3/Emu/Cell/SPUThread.cpp +++ b/rpcs3/Emu/Cell/SPUThread.cpp @@ -1061,8 +1061,37 @@ bool SPUThread::stop_and_signal(u32 code) { case 0x000: { - // Hack: execute as NOP - return true; + LOG_WARNING(SPU, "STOP 0x0"); + + // HACK: find an ILA instruction + for (u32 addr = pc; addr < 0x40000; addr += 4) + { + const u32 instr = _ref(addr); + + if (instr >> 25 == 0x21) + { + pc = addr; + return false; + } + + if (instr > 0x1fffff) + { + break; + } + } + + // HACK: wait for executable code + while (!_ref(pc)) + { + if (test(state & cpu_flag::stop)) + { + return false; + } + + thread_ctrl::wait_for(1000); + } + + return false; } case 0x001: