Some hack

This commit is contained in:
Nekotekina 2014-08-15 16:50:59 +04:00
parent 9f0c5899d6
commit cb58a773c9
7 changed files with 57 additions and 34 deletions

View file

@ -2104,6 +2104,7 @@ private:
Emu.GetSFuncManager()[CPU.GPR[11]]->name, CPU.GPR[3], CPU.PC);
}
break;
case 0x4: CPU.FastStop(); break;
case 0x22: UNK("HyperCall LV1"); break;
default: UNK(fmt::Format("Unknown sc: %x", sc_code));
}
@ -2368,13 +2369,9 @@ private:
}
void LWARX(u32 rd, u32 ra, u32 rb)
{
const u64 addr = ra ? CPU.GPR[ra] + CPU.GPR[rb] : CPU.GPR[rb];
SMutexLockerR lock(reservation.mutex);
reservation.owner = lock.tid;
reservation.addr = addr;
reservation.size = 4;
reservation.data32 = CPU.GPR[rd] = Memory.Read32(addr);
CPU.R_ADDR = ra ? CPU.GPR[ra] + CPU.GPR[rb] : CPU.GPR[rb];
CPU.R_VALUE = (u32&)Memory[CPU.R_ADDR];
CPU.GPR[rd] = re32((u32)CPU.R_VALUE);
}
void LDX(u32 rd, u32 ra, u32 rb)
{
@ -2523,13 +2520,9 @@ private:
}
void LDARX(u32 rd, u32 ra, u32 rb)
{
const u64 addr = ra ? CPU.GPR[ra] + CPU.GPR[rb] : CPU.GPR[rb];
SMutexLockerR lock(reservation.mutex);
reservation.owner = lock.tid;
reservation.addr = addr;
reservation.size = 8;
reservation.data64 = CPU.GPR[rd] = Memory.Read64(addr);
CPU.R_ADDR = ra ? CPU.GPR[ra] + CPU.GPR[rb] : CPU.GPR[rb];
CPU.R_VALUE = (u64&)Memory[CPU.R_ADDR];
CPU.GPR[rd] = re64(CPU.R_VALUE);
}
void DCBF(u32 ra, u32 rb)
{
@ -2644,17 +2637,13 @@ private:
{
const u64 addr = ra ? CPU.GPR[ra] + CPU.GPR[rb] : CPU.GPR[rb];
SMutexLockerR lock(reservation.mutex);
if (lock.tid == reservation.owner && reservation.addr == addr && reservation.size == 4)
if (CPU.R_ADDR == addr)
{
// Memory.Write32(addr, CPU.GPR[rs]);
CPU.SetCR_EQ(0, InterlockedCompareExchange((volatile long*) (Memory + addr), re((u32) CPU.GPR[rs]), re(reservation.data32)) == re(reservation.data32));
reservation.clear();
CPU.SetCR_EQ(0, InterlockedCompareExchange((volatile u32*)(Memory + addr), re32((u32)CPU.GPR[rs]), (u32)CPU.R_VALUE) == (u32)CPU.R_VALUE);
}
else
{
CPU.SetCR_EQ(0, false);
if (lock.tid == reservation.owner) reservation.clear();
}
}
void STWX(u32 rs, u32 ra, u32 rb)
@ -2705,17 +2694,13 @@ private:
{
const u64 addr = ra ? CPU.GPR[ra] + CPU.GPR[rb] : CPU.GPR[rb];
SMutexLockerR lock(reservation.mutex);
if (lock.tid == reservation.owner && reservation.addr == addr && reservation.size == 8)
if (CPU.R_ADDR == addr)
{
// Memory.Write64(addr, CPU.GPR[rs]);
CPU.SetCR_EQ(0, InterlockedCompareExchange64((volatile long long*)(Memory + addr), re(CPU.GPR[rs]), re(reservation.data64)) == re(reservation.data64));
reservation.clear();
CPU.SetCR_EQ(0, InterlockedCompareExchange((volatile u64*)(Memory + addr), re64(CPU.GPR[rs]), CPU.R_VALUE) == CPU.R_VALUE);
}
else
{
CPU.SetCR_EQ(0, false);
if (lock.tid == reservation.owner) reservation.clear();
}
}
void STBX(u32 rs, u32 ra, u32 rb)

View file

@ -219,3 +219,34 @@ int FPRdouble::Cmp(PPCdouble a, PPCdouble b)
return CR_SO;
}
u64 PPUThread::FastCall(u64 addr, u64 arg1, u64 arg2, u64 arg3, u64 arg4, u64 arg5, u64 arg6, u64 arg7, u64 arg8)
{
auto old_status = m_status;
auto old_PC = PC;
auto old_LR = LR;
PC = addr;
GPR[3] = arg1;
GPR[4] = arg2;
GPR[5] = arg3;
GPR[6] = arg4;
GPR[7] = arg5;
GPR[8] = arg6;
GPR[9] = arg7;
GPR[10] = arg8;
LR = Emu.m_ppu_thr_stop;
Task();
LR = old_LR;
PC = old_PC;
m_status = old_status;
return GPR[3];
}
void PPUThread::FastStop()
{
m_status = Stopped;
}

View file

@ -607,6 +607,9 @@ public:
u64 cycle;
u64 R_ADDR; // reservation address
u64 R_VALUE; // reservation value (BE)
public:
PPUThread();
virtual ~PPUThread();
@ -839,6 +842,8 @@ public:
public:
virtual void InitRegs();
virtual u64 GetFreeStackSize() const;
u64 FastCall(u64 addr, u64 arg1 = 0, u64 arg2 = 0, u64 arg3 = 0, u64 arg4 = 0, u64 arg5 = 0, u64 arg6 = 0, u64 arg7 = 0, u64 arg8 = 0);
void FastStop();
protected:
virtual void DoReset() override;

View file

@ -550,7 +550,7 @@ int cellAudioOutGetNumberOfDevice(u32 audioOut)
int cellAudioOutGetDeviceInfo(u32 audioOut, u32 deviceIndex, mem_ptr_t<CellAudioOutDeviceInfo> info)
{
cellSysutil->Todo("Unimplemented function: cellAudioOutGetDeviceInfo(audioOut=%u, deviceIndex=%u, info_addr=0x%x)",
cellSysutil->Todo("cellAudioOutGetDeviceInfo(audioOut=%u, deviceIndex=%u, info_addr=0x%x)",
audioOut, deviceIndex, info.GetAddr());
if(deviceIndex) return CELL_AUDIO_OUT_ERROR_DEVICE_NOT_FOUND;

View file

@ -45,7 +45,7 @@ static func_caller* sc_table[kSyscallTableLength] =
bind_func(sys_process_kill), //19 (0x013)
null_func, //20 (0x014) UNS
null_func,//bind_func(_sys_process_spawn), //21 (0x015) DBG
bind_func(sys_process_exit), //22 (0x016)
null_func,//bind_func(sys_process_exit), //22 (0x016)
bind_func(sys_process_wait_for_child2), //23 (0x017) DBG
null_func,//bind_func(), //24 (0x018) DBG
bind_func(sys_process_get_sdk_version), //25 (0x019)

View file

@ -324,11 +324,17 @@ void Emulator::Load()
m_ppu_thr_exit = Memory.MainMem.AllocAlign(4 * 4);
mem32_ptr_t ppu_thr_exit_data(m_ppu_thr_exit);
ppu_thr_exit_data += ADDI(3, 0, 0);
//ppu_thr_exit_data += ADDI(3, 0, 0); // why it kills return value (GPR[3]) ?
ppu_thr_exit_data += ADDI(11, 0, 41);
ppu_thr_exit_data += SC(2);
ppu_thr_exit_data += BCLR(0x10 | 0x04, 0, 0, 0);
m_ppu_thr_stop = Memory.MainMem.AllocAlign(2 * 4);
mem32_ptr_t ppu_thr_stop_data(m_ppu_thr_stop);
ppu_thr_stop_data += SC(4);
ppu_thr_exit_data += BCLR(0x10 | 0x04, 0, 0, 0);
Memory.Write64(Memory.PRXMem.AllocAlign(0x10000), 0xDEADBEEFABADCAFE);
}
break;
@ -422,11 +428,6 @@ void Emulator::Stop()
break;
}
std::this_thread::sleep_for(std::chrono::milliseconds(1));
if (counter++ > 3000)
{
LOG_ERROR(HLE, "%d threads not stopped (timeout)", (u32)(g_thread_count - uncounted));
break;
}
}
m_rsx_callback = 0;

View file

@ -106,6 +106,7 @@ public:
std::string m_path;
std::string m_elf_path;
std::string m_title_id;
u32 m_ppu_thr_stop;
s32 m_sdk_version;
Emulator();