mirror of
https://github.com/RPCS3/rpcs3.git
synced 2025-07-08 16:01:42 +12:00
Small update
This commit is contained in:
parent
4a6779469c
commit
752449bbc0
10 changed files with 173 additions and 76 deletions
|
@ -80,7 +80,7 @@ void SPUThread::InitRegs()
|
|||
|
||||
cfg.Reset();
|
||||
|
||||
dmac.ls_offset = m_offset;
|
||||
ls_offset = m_offset;
|
||||
|
||||
SPU.Status.SetValue(SPU_STATUS_STOPPED);
|
||||
|
||||
|
@ -148,19 +148,27 @@ void SPUThread::DoClose()
|
|||
|
||||
void SPUThread::FastCall(u32 ls_addr)
|
||||
{
|
||||
// doesn't touch thread status (instead of PPUThread::FastCall2);
|
||||
// can't be called from another thread (because it doesn't make sense);
|
||||
// FastStop-like routine is not defined (TODO);
|
||||
// can't be called from another thread (because it doesn't make sense)
|
||||
WriteLS32(0x0, 2);
|
||||
|
||||
auto old_PC = PC;
|
||||
auto old_stack = GPR[1]; // only saved and restored (may be wrong)
|
||||
auto old_LR = GPR[0]._u32[3];
|
||||
auto old_stack = GPR[1]._u32[3]; // only saved and restored (may be wrong)
|
||||
|
||||
m_status = Running;
|
||||
PC = ls_addr;
|
||||
GPR[0]._u32[3] = 0x0;
|
||||
|
||||
CPUThread::Task();
|
||||
|
||||
PC = old_PC;
|
||||
GPR[1] = old_stack;
|
||||
GPR[0]._u32[3] = old_LR;
|
||||
GPR[1]._u32[3] = old_stack;
|
||||
}
|
||||
|
||||
void SPUThread::FastStop()
|
||||
{
|
||||
m_status = Stopped;
|
||||
}
|
||||
|
||||
void SPUThread::WriteSNR(bool number, u32 value)
|
||||
|
@ -206,11 +214,11 @@ void SPUThread::ProcessCmd(u32 cmd, u32 tag, u32 lsa, u64 ea, u32 size)
|
|||
if ((addr <= 0x3ffff) && (addr + size <= 0x40000))
|
||||
{
|
||||
// LS access
|
||||
ea = spu->dmac.ls_offset + addr;
|
||||
ea = spu->ls_offset + addr;
|
||||
}
|
||||
else if ((cmd & MFC_PUT_CMD) && size == 4 && (addr == SYS_SPU_THREAD_SNR1 || addr == SYS_SPU_THREAD_SNR2))
|
||||
{
|
||||
spu->WriteSNR(SYS_SPU_THREAD_SNR2 == addr, vm::read32(dmac.ls_offset + lsa));
|
||||
spu->WriteSNR(SYS_SPU_THREAD_SNR2 == addr, vm::read32(ls_offset + lsa));
|
||||
return;
|
||||
}
|
||||
else
|
||||
|
@ -256,13 +264,13 @@ void SPUThread::ProcessCmd(u32 cmd, u32 tag, u32 lsa, u64 ea, u32 size)
|
|||
{
|
||||
case MFC_PUT_CMD:
|
||||
{
|
||||
memcpy(vm::get_ptr<void>(ea), vm::get_ptr<void>(dmac.ls_offset + lsa), size);
|
||||
memcpy(vm::get_ptr<void>(ea), vm::get_ptr<void>(ls_offset + lsa), size);
|
||||
return;
|
||||
}
|
||||
|
||||
case MFC_GET_CMD:
|
||||
{
|
||||
memcpy(vm::get_ptr<void>(dmac.ls_offset + lsa), vm::get_ptr<void>(ea), size);
|
||||
memcpy(vm::get_ptr<void>(ls_offset + lsa), vm::get_ptr<void>(ea), size);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -294,7 +302,7 @@ void SPUThread::ListCmd(u32 lsa, u64 ea, u16 tag, u16 size, u32 cmd, MFCReg& MFC
|
|||
|
||||
for (u32 i = 0; i < list_size; i++)
|
||||
{
|
||||
auto rec = vm::ptr<list_element>::make(dmac.ls_offset + list_addr + i * 8);
|
||||
auto rec = vm::ptr<list_element>::make(ls_offset + list_addr + i * 8);
|
||||
|
||||
u32 size = rec->ts;
|
||||
if (!(rec->s.ToBE() & se16(0x8000)) && size < 16 && size != 1 && size != 2 && size != 4 && size != 8)
|
||||
|
@ -405,7 +413,7 @@ void SPUThread::EnqMfcCmd(MFCReg& MFCArgs)
|
|||
for (u32 i = 0; i < 16; i++)
|
||||
{
|
||||
R_DATA[i] = vm::get_ptr<u64>(R_ADDR)[i];
|
||||
vm::get_ptr<u64>(dmac.ls_offset + lsa)[i] = R_DATA[i];
|
||||
vm::get_ptr<u64>(ls_offset + lsa)[i] = R_DATA[i];
|
||||
}
|
||||
MFCArgs.AtomicStat.PushUncond(MFC_GETLLAR_SUCCESS);
|
||||
}
|
||||
|
@ -419,7 +427,7 @@ void SPUThread::EnqMfcCmd(MFCReg& MFCArgs)
|
|||
u64 buf[16];
|
||||
for (u32 i = 0; i < 16; i++)
|
||||
{
|
||||
buf[i] = vm::get_ptr<u64>(dmac.ls_offset + lsa)[i];
|
||||
buf[i] = vm::get_ptr<u64>(ls_offset + lsa)[i];
|
||||
if (buf[i] != R_DATA[i])
|
||||
{
|
||||
changed++;
|
||||
|
@ -464,8 +472,8 @@ void SPUThread::EnqMfcCmd(MFCReg& MFCArgs)
|
|||
for (s32 i = (s32)PC; i < (s32)PC + 4 * 7; i += 4)
|
||||
{
|
||||
dis_asm.dump_pc = i;
|
||||
dis_asm.offset = vm::get_ptr<u8>(dmac.ls_offset);
|
||||
const u32 opcode = vm::read32(i + dmac.ls_offset);
|
||||
dis_asm.offset = vm::get_ptr<u8>(ls_offset);
|
||||
const u32 opcode = vm::read32(i + ls_offset);
|
||||
(*SPU_instr::rrr_list)(&dis_asm, opcode);
|
||||
if (i >= 0 && i < 0x40000)
|
||||
{
|
||||
|
@ -526,18 +534,20 @@ bool SPUThread::CheckEvents()
|
|||
|
||||
u32 SPUThread::GetChannelCount(u32 ch)
|
||||
{
|
||||
u32 res = 0xdeafbeef;
|
||||
|
||||
switch (ch)
|
||||
{
|
||||
case SPU_WrOutMbox: return SPU.Out_MBox.GetFreeCount();
|
||||
case SPU_WrOutIntrMbox: return SPU.Out_IntrMBox.GetFreeCount();
|
||||
case SPU_RdInMbox: return SPU.In_MBox.GetCount();
|
||||
case MFC_RdTagStat: return MFC1.TagStatus.GetCount();
|
||||
case MFC_RdListStallStat: return StallStat.GetCount();
|
||||
case MFC_WrTagUpdate: return MFC1.TagStatus.GetCount(); // hack
|
||||
case SPU_RdSigNotify1: return SPU.SNR[0].GetCount();
|
||||
case SPU_RdSigNotify2: return SPU.SNR[1].GetCount();
|
||||
case MFC_RdAtomicStat: return MFC1.AtomicStat.GetCount();
|
||||
case SPU_RdEventStat: return CheckEvents() ? 1 : 0;
|
||||
case SPU_WrOutMbox: res = SPU.Out_MBox.GetFreeCount(); break;
|
||||
case SPU_WrOutIntrMbox: res = SPU.Out_IntrMBox.GetFreeCount(); break;
|
||||
case SPU_RdInMbox: res = SPU.In_MBox.GetCount(); break;
|
||||
case MFC_RdTagStat: res = MFC1.TagStatus.GetCount(); break;
|
||||
case MFC_RdListStallStat: res = StallStat.GetCount(); break;
|
||||
case MFC_WrTagUpdate: res = MFC1.TagStatus.GetCount(); break;// hack
|
||||
case SPU_RdSigNotify1: res = SPU.SNR[0].GetCount(); break;
|
||||
case SPU_RdSigNotify2: res = SPU.SNR[1].GetCount(); break;
|
||||
case MFC_RdAtomicStat: res = MFC1.AtomicStat.GetCount(); break;
|
||||
case SPU_RdEventStat: res = CheckEvents() ? 1 : 0; break;
|
||||
|
||||
default:
|
||||
{
|
||||
|
@ -546,12 +556,17 @@ u32 SPUThread::GetChannelCount(u32 ch)
|
|||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
//LOG_NOTICE(Log::SPU, "%s(%s) -> 0x%x", __FUNCTION__, spu_ch_name[ch], res);
|
||||
return res;
|
||||
}
|
||||
|
||||
void SPUThread::WriteChannel(u32 ch, const u128& r)
|
||||
{
|
||||
const u32 v = r._u32[3];
|
||||
|
||||
//LOG_NOTICE(Log::SPU, "%s(%s): v=0x%x", __FUNCTION__, spu_ch_name[ch], v);
|
||||
|
||||
switch (ch)
|
||||
{
|
||||
case SPU_WrOutIntrMbox:
|
||||
|
@ -908,13 +923,27 @@ void SPUThread::ReadChannel(u128& r, u32 ch)
|
|||
|
||||
case SPU_RdSigNotify1:
|
||||
{
|
||||
while (!SPU.SNR[0].Pop(v) && !Emu.IsStopped()) std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
||||
if (cfg.value & 1)
|
||||
{
|
||||
while (!SPU.SNR[0].Pop_XCHG(v) && !Emu.IsStopped()) std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
||||
}
|
||||
else
|
||||
{
|
||||
while (!SPU.SNR[0].Pop(v) && !Emu.IsStopped()) std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case SPU_RdSigNotify2:
|
||||
{
|
||||
while (!SPU.SNR[1].Pop(v) && !Emu.IsStopped()) std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
||||
if (cfg.value & 2)
|
||||
{
|
||||
while (!SPU.SNR[1].Pop_XCHG(v) && !Emu.IsStopped()) std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
||||
}
|
||||
else
|
||||
{
|
||||
while (!SPU.SNR[1].Pop(v) && !Emu.IsStopped()) std::this_thread::sleep_for(std::chrono::milliseconds(1));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -964,6 +993,8 @@ void SPUThread::ReadChannel(u128& r, u32 ch)
|
|||
}
|
||||
|
||||
if (Emu.IsStopped()) LOG_WARNING(Log::SPU, "%s(%s) aborted", __FUNCTION__, spu_ch_name[ch]);
|
||||
|
||||
//LOG_NOTICE(Log::SPU, "%s(%s) -> 0x%x", __FUNCTION__, spu_ch_name[ch], v);
|
||||
}
|
||||
|
||||
void SPUThread::StopAndSignal(u32 code)
|
||||
|
@ -973,6 +1004,18 @@ void SPUThread::StopAndSignal(u32 code)
|
|||
|
||||
switch (code)
|
||||
{
|
||||
case 0x001:
|
||||
{
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1)); // hack
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x002:
|
||||
{
|
||||
FastStop();
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x110:
|
||||
{
|
||||
/* ===== sys_spu_thread_receive_event ===== */
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue