Some cleanup

This commit is contained in:
Nekotekina 2014-07-07 21:22:36 +04:00
parent faab4ed6db
commit d1fff053c2
23 changed files with 278 additions and 850 deletions

View File

@ -52,7 +52,22 @@ void ThreadBase::Start()
g_tls_this_thread = this; g_tls_this_thread = this;
g_thread_count++; g_thread_count++;
Task(); try
{
Task();
}
catch (const std::string& e)
{
LOG_ERROR(GENERAL, "Exception: %s", e.c_str());
}
catch (const char* e)
{
LOG_ERROR(GENERAL, "Exception: %s", e);
}
catch (int exitcode)
{
LOG_SUCCESS(GENERAL, "Exit Code: %d", exitcode);
}
m_alive = false; m_alive = false;
g_thread_count--; g_thread_count--;

View File

@ -280,68 +280,72 @@ void CPUThread::ExecOnce()
SendDbgCommand(DID_PAUSED_THREAD, this); SendDbgCommand(DID_PAUSED_THREAD, this);
} }
void _se_translator(unsigned int u, EXCEPTION_POINTERS* pExp)
{
const u64 addr = (u64)Memory.GetBaseAddr() - (u64)pExp->ExceptionRecord->ExceptionAddress;
if (addr < 0x100000000 && u == EXCEPTION_ACCESS_VIOLATION)
{
// TODO: allow recovering from a page fault
//GetCurrentPPUThread().Stop();
Emu.Pause();
throw fmt::Format("Access violation: addr = 0x%x", (u32)addr);
}
else
{
// some fatal error (should crash)
return;
}
}
void CPUThread::Task() void CPUThread::Task()
{ {
if (Ini.HLELogging.GetValue()) LOG_NOTICE(PPU, "%s enter", CPUThread::GetFName().c_str()); if (Ini.HLELogging.GetValue()) LOG_NOTICE(PPU, "%s enter", CPUThread::GetFName().c_str());
const std::vector<u64>& bp = Emu.GetBreakPoints(); const std::vector<u64>& bp = Emu.GetBreakPoints();
try for (uint i = 0; i<bp.size(); ++i)
{ {
for(uint i=0; i<bp.size(); ++i) if (bp[i] == m_offset + PC)
{ {
if(bp[i] == m_offset + PC) Emu.Pause();
break;
}
}
_set_se_translator(_se_translator);
while (true)
{
int status = ThreadStatus();
if (status == CPUThread_Stopped || status == CPUThread_Break)
{
break;
}
if (status == CPUThread_Sleeping)
{
Sleep(1);
continue;
}
Step();
NextPc(m_dec->DecodeMemory(PC + m_offset));
if (status == CPUThread_Step)
{
m_is_step = false;
break;
}
for (uint i = 0; i < bp.size(); ++i)
{
if (bp[i] == PC)
{ {
Emu.Pause(); Emu.Pause();
break; break;
} }
} }
while(true)
{
int status = ThreadStatus();
if(status == CPUThread_Stopped || status == CPUThread_Break)
{
break;
}
if(status == CPUThread_Sleeping)
{
Sleep(1);
continue;
}
Step();
NextPc(m_dec->DecodeMemory(PC + m_offset));
if(status == CPUThread_Step)
{
m_is_step = false;
break;
}
for(uint i=0; i<bp.size(); ++i)
{
if(bp[i] == PC)
{
Emu.Pause();
break;
}
}
}
}
catch(const std::string& e)
{
LOG_ERROR(PPU, "Exception: %s", e.c_str());
}
catch(const char* e)
{
LOG_ERROR(PPU, "Exception: %s", e);
}
catch(int exitcode)
{
LOG_SUCCESS(PPU, "Exit Code: %d", exitcode);
} }
if (Ini.HLELogging.GetValue()) LOG_NOTICE(PPU, "%s leave", CPUThread::GetFName().c_str()); if (Ini.HLELogging.GetValue()) LOG_NOTICE(PPU, "%s leave", CPUThread::GetFName().c_str());

View File

@ -5,9 +5,8 @@
u8 PPCDecoder::DecodeMemory(const u64 address) u8 PPCDecoder::DecodeMemory(const u64 address)
{ {
u32 instr; u32 instr = Memory.Read32(address);
Memory.Read32ByAddr(address, &instr);
Decode(instr); Decode(instr);
return 4; return sizeof(u32);
} }

View File

@ -12,48 +12,13 @@ RawSPUThread::RawSPUThread(u32 index, CPUThreadType type)
, MemoryBlock() , MemoryBlock()
, m_index(index) , m_index(index)
{ {
Memory.MemoryBlocks.push_back(SetRange(RAW_SPU_BASE_ADDR + RAW_SPU_OFFSET * index, RAW_SPU_OFFSET)); Memory.InitRawSPU(SetRange(RAW_SPU_BASE_ADDR + RAW_SPU_OFFSET * index, RAW_SPU_PROB_OFFSET), m_index);
Reset(); Reset();
} }
RawSPUThread::~RawSPUThread() RawSPUThread::~RawSPUThread()
{ {
for(int i=0; i<Memory.MemoryBlocks.size(); ++i) Memory.CloseRawSPU(this, m_index);
{
if(Memory.MemoryBlocks[i]->GetStartAddr() == GetStartAddr())
{
Memory.MemoryBlocks.erase(Memory.MemoryBlocks.begin() + i);
break;
}
}
//Close();
}
bool RawSPUThread::Read8(const u64 addr, u8* value)
{
if(addr < GetStartAddr() + RAW_SPU_PROB_OFFSET)
{
return MemoryBlock::Read8(addr, value);
}
u32 offset = addr - GetStartAddr() - RAW_SPU_PROB_OFFSET;
LOG_ERROR(Log::SPU, "RawSPUThread[%d]: Read8(0x%x)", m_index, offset);
Emu.Pause();
return false;
}
bool RawSPUThread::Read16(const u64 addr, u16* value)
{
if(addr < GetStartAddr() + RAW_SPU_PROB_OFFSET)
{
return MemoryBlock::Read16(addr, value);
}
u32 offset = addr - GetStartAddr() - RAW_SPU_PROB_OFFSET;
LOG_ERROR(Log::SPU, "RawSPUThread[%d]: Read16(0x%x)", m_index, offset);
Emu.Pause();
return false;
} }
bool RawSPUThread::Read32(const u64 addr, u32* value) bool RawSPUThread::Read32(const u64 addr, u32* value)
@ -88,7 +53,7 @@ bool RawSPUThread::Read32(const u64 addr, u32* value)
SPU.MBox_Status.SetValue((SPU.Out_MBox.GetCount() & 0xff) | (SPU.In_MBox.GetFreeCount() << 8)); SPU.MBox_Status.SetValue((SPU.Out_MBox.GetCount() & 0xff) | (SPU.In_MBox.GetFreeCount() << 8));
*value = SPU.MBox_Status.GetValue(); *value = SPU.MBox_Status.GetValue();
break; break;
case SPU_RunCntl_offs: LOG_WARNING(Log::SPU, "RawSPUThread[%d]: Read32(SPU_RunCntl)", m_index); *value = SPU.RunCntl.GetValue(); break; case SPU_RunCntl_offs: LOG_WARNING(Log::SPU, "RawSPUThread[%d]: Read32(SPU_RunCntl)", m_index); *value = (u32)IsRunning(); break;
case SPU_Status_offs: case SPU_Status_offs:
//LOG_WARNING(Log::SPU, "RawSPUThread[%d]: Read32(SPU_Status)", m_index); //LOG_WARNING(Log::SPU, "RawSPUThread[%d]: Read32(SPU_Status)", m_index);
*value = SPU.Status.GetValue(); *value = SPU.Status.GetValue();
@ -106,58 +71,6 @@ bool RawSPUThread::Read32(const u64 addr, u32* value)
return true; return true;
} }
bool RawSPUThread::Read64(const u64 addr, u64* value)
{
if(addr < GetStartAddr() + RAW_SPU_PROB_OFFSET)
{
return MemoryBlock::Read64(addr, value);
}
u32 offset = addr - GetStartAddr() - RAW_SPU_PROB_OFFSET;
LOG_ERROR(Log::SPU, "RawSPUThread[%d]: Read64(0x%x)", m_index, offset);
Emu.Pause();
return false;
}
bool RawSPUThread::Read128(const u64 addr, u128* value)
{
if(addr < GetStartAddr() + RAW_SPU_PROB_OFFSET)
{
return MemoryBlock::Read128(addr, value);
}
u32 offset = addr - GetStartAddr() - RAW_SPU_PROB_OFFSET;
LOG_ERROR(Log::SPU, "RawSPUThread[%d]: Read128(0x%x)", m_index, offset);
Emu.Pause();
return false;
}
bool RawSPUThread::Write8(const u64 addr, const u8 value)
{
if(addr < GetStartAddr() + RAW_SPU_PROB_OFFSET)
{
return MemoryBlock::Write8(addr, value);
}
u32 offset = addr - GetStartAddr() - RAW_SPU_PROB_OFFSET;
LOG_ERROR(Log::SPU, "RawSPUThread[%d]: Write8(0x%x, 0x%x)", m_index, offset, value);
Emu.Pause();
return false;
}
bool RawSPUThread::Write16(const u64 addr, const u16 value)
{
if(addr < GetStartAddr() + RAW_SPU_PROB_OFFSET)
{
return MemoryBlock::Write16(addr, value);
}
u32 offset = addr - GetStartAddr() - RAW_SPU_PROB_OFFSET;
LOG_ERROR(Log::SPU, "RawSPUThread[%d]: Write16(0x%x, 0x%x)", m_index, offset, value);
Emu.Pause();
return false;
}
bool RawSPUThread::Write32(const u64 addr, const u32 value) bool RawSPUThread::Write32(const u64 addr, const u32 value)
{ {
if(addr < GetStartAddr() + RAW_SPU_PROB_OFFSET) if(addr < GetStartAddr() + RAW_SPU_PROB_OFFSET)
@ -206,7 +119,25 @@ bool RawSPUThread::Write32(const u64 addr, const u32 value)
SPU.In_MBox.PushUncond(value); //if In_MBox is already full, the last message will be overwritten SPU.In_MBox.PushUncond(value); //if In_MBox is already full, the last message will be overwritten
break; break;
case SPU_MBox_Status_offs: LOG_WARNING(Log::SPU, "RawSPUThread[%d]: Write32(SPU_MBox_Status, 0x%x)", m_index, value); SPU.MBox_Status.SetValue(value); break; case SPU_MBox_Status_offs: LOG_WARNING(Log::SPU, "RawSPUThread[%d]: Write32(SPU_MBox_Status, 0x%x)", m_index, value); SPU.MBox_Status.SetValue(value); break;
case SPU_RunCntl_offs: LOG_WARNING(Log::SPU, "RawSPUThread[%d]: Write32(SPU_RunCntl, 0x%x)", m_index, value); SPU.RunCntl.SetValue(value); break; case SPU_RunCntl_offs:
{
if (value == SPU_RUNCNTL_RUNNABLE)
{
SPU.Status.SetValue(SPU_STATUS_RUNNING);
Exec();
}
else if (value == SPU_RUNCNTL_STOP)
{
SPU.Status.SetValue(SPU_STATUS_STOPPED);
Stop();
}
else
{
LOG_ERROR(Log::SPU, "RawSPUThread[%d]: Write32(SPU_RunCtrl, 0x%x): unknown value", m_index, value);
Emu.Pause();
}
break;
}
case SPU_Status_offs: LOG_WARNING(Log::SPU, "RawSPUThread[%d]: Write32(SPU_Status, 0x%x)", m_index, value); SPU.Status.SetValue(value); break; case SPU_Status_offs: LOG_WARNING(Log::SPU, "RawSPUThread[%d]: Write32(SPU_Status, 0x%x)", m_index, value); SPU.Status.SetValue(value); break;
case SPU_NPC_offs: LOG_WARNING(Log::SPU, "RawSPUThread[%d]: Write32(SPU_NPC, 0x%x)", m_index, value); SPU.NPC.SetValue(value); break; case SPU_NPC_offs: LOG_WARNING(Log::SPU, "RawSPUThread[%d]: Write32(SPU_NPC, 0x%x)", m_index, value); SPU.NPC.SetValue(value); break;
case SPU_RdSigNotify1_offs: LOG_WARNING(Log::SPU, "RawSPUThread[%d]: Write32(SPU_RdSigNotify1, 0x%x)", m_index, value); SPU.SNR[0].SetValue(value); break; case SPU_RdSigNotify1_offs: LOG_WARNING(Log::SPU, "RawSPUThread[%d]: Write32(SPU_RdSigNotify1, 0x%x)", m_index, value); SPU.SNR[0].SetValue(value); break;
@ -221,32 +152,6 @@ bool RawSPUThread::Write32(const u64 addr, const u32 value)
return true; return true;
} }
bool RawSPUThread::Write64(const u64 addr, const u64 value)
{
if(addr < GetStartAddr() + RAW_SPU_PROB_OFFSET)
{
return MemoryBlock::Write64(addr, value);
}
u32 offset = addr - GetStartAddr() - RAW_SPU_PROB_OFFSET;
LOG_ERROR(Log::SPU, "RawSPUThread[%d]: Write64(0x%x, 0x%llx)", m_index, offset, value);
Emu.Pause();
return false;
}
bool RawSPUThread::Write128(const u64 addr, const u128 value)
{
if(addr < GetStartAddr() + RAW_SPU_PROB_OFFSET)
{
return MemoryBlock::Write128(addr, value);
}
u32 offset = addr - GetStartAddr() - RAW_SPU_PROB_OFFSET;
LOG_ERROR(Log::SPU, "RawSPUThread[%d]: Write128(0x%x, 0x%llx_%llx)", m_index, offset, value._u64[1], value._u64[0]);
Emu.Pause();
return false;
}
void RawSPUThread::InitRegs() void RawSPUThread::InitRegs()
{ {
dmac.ls_offset = m_offset = GetStartAddr() + RAW_SPU_LS_OFFSET; dmac.ls_offset = m_offset = GetStartAddr() + RAW_SPU_LS_OFFSET;
@ -260,88 +165,9 @@ u32 RawSPUThread::GetIndex() const
void RawSPUThread::Task() void RawSPUThread::Task()
{ {
if (Ini.HLELogging.GetValue()) LOG_NOTICE(Log::SPU, "%s enter", PPCThread::GetFName().c_str()); PC = SPU.NPC.GetValue();
const std::vector<u64>& bp = Emu.GetBreakPoints(); CPUThread::Task();
try SPU.NPC.SetValue(PC);
{
for(uint i=0; i<bp.size(); ++i)
{
if(bp[i] == m_offset + PC)
{
Emu.Pause();
break;
}
}
bool is_last_paused = true;
while(true)
{
int status = ThreadStatus();
if(status == CPUThread_Stopped || status == CPUThread_Break)
{
break;
}
if(status == CPUThread_Sleeping)
{
Sleep(1);
continue;
}
//dmac.DoCmd();
if(SPU.RunCntl.GetValue() != SPU_RUNCNTL_RUNNABLE)
{
if(!is_last_paused)
{
is_last_paused = true;
SPU.NPC.SetValue(PC);
SPU.Status.SetValue(SPU_STATUS_WAITING_FOR_CHANNEL);
}
Sleep(1);
continue;
}
if(is_last_paused)
{
is_last_paused = false;
PC = SPU.NPC.GetValue();
SPU.Status.SetValue(SPU_STATUS_RUNNING);
LOG_WARNING(Log::SPU, "Starting RawSPU...");
}
Step();
NextPc(m_dec->DecodeMemory(PC + m_offset));
if(status == CPUThread_Step)
{
m_is_step = false;
continue;
}
for(uint i=0; i<bp.size(); ++i)
{
if(bp[i] == PC)
{
Emu.Pause();
continue;
}
}
}
}
catch(const std::string& e)
{
LOG_ERROR(Log::SPU, "Exception: %s", e.c_str());
}
catch(const char* e)
{
LOG_ERROR(Log::SPU, "Exception: %s", e);
}
if (Ini.HLELogging.GetValue()) LOG_NOTICE(Log::SPU, "%s leave", PPCThread::GetFName().c_str());
} }

View File

@ -22,17 +22,9 @@ public:
RawSPUThread(u32 index, CPUThreadType type = CPU_THREAD_RAW_SPU); RawSPUThread(u32 index, CPUThreadType type = CPU_THREAD_RAW_SPU);
virtual ~RawSPUThread(); virtual ~RawSPUThread();
virtual bool Read8(const u64 addr, u8* value) override;
virtual bool Read16(const u64 addr, u16* value) override;
virtual bool Read32(const u64 addr, u32* value) override; virtual bool Read32(const u64 addr, u32* value) override;
virtual bool Read64(const u64 addr, u64* value) override;
virtual bool Read128(const u64 addr, u128* value) override;
virtual bool Write8(const u64 addr, const u8 value) override;
virtual bool Write16(const u64 addr, const u16 value) override;
virtual bool Write32(const u64 addr, const u32 value) override; virtual bool Write32(const u64 addr, const u32 value) override;
virtual bool Write64(const u64 addr, const u64 value) override;
virtual bool Write128(const u64 addr, const u128 value) override;
public: public:
virtual void InitRegs(); virtual void InitRegs();

View File

@ -61,8 +61,7 @@ void SPUThread::InitRegs()
dmac.proxy_lock = 0; dmac.proxy_lock = 0;
dmac.queue_lock = 0;*/ dmac.queue_lock = 0;*/
SPU.RunCntl.SetValue(SPU_RUNCNTL_STOP); SPU.Status.SetValue(SPU_STATUS_STOPPED);
SPU.Status.SetValue(SPU_STATUS_RUNNING);
Prxy.QueryType.SetValue(0); Prxy.QueryType.SetValue(0);
MFC1.CMDStatus.SetValue(0); MFC1.CMDStatus.SetValue(0);
MFC2.CMDStatus.SetValue(0); MFC2.CMDStatus.SetValue(0);

View File

@ -151,14 +151,6 @@ enum
SPU_RdSigNotify2_offs = 0x1C00C, SPU_RdSigNotify2_offs = 0x1C00C,
}; };
enum : u64
{
RAW_SPU_OFFSET = 0x0000000000100000,
RAW_SPU_BASE_ADDR = 0x00000000E0000000,
RAW_SPU_LS_OFFSET = 0x0000000000000000,
RAW_SPU_PROB_OFFSET = 0x0000000000040000,
};
//Floating point status and control register. Unsure if this is one of the GPRs or SPRs //Floating point status and control register. Unsure if this is one of the GPRs or SPRs
//Is 128 bits, but bits 0-19, 24-28, 32-49, 56-60, 64-81, 88-92, 96-115, 120-124 are unused //Is 128 bits, but bits 0-19, 24-28, 32-49, 56-60, 64-81, 88-92, 96-115, 120-124 are unused
class FPSCR class FPSCR
@ -562,7 +554,6 @@ public:
Channel<1> Out_IntrMBox; Channel<1> Out_IntrMBox;
Channel<4> In_MBox; Channel<4> In_MBox;
Channel<1> MBox_Status; Channel<1> MBox_Status;
Channel<1> RunCntl;
Channel<1> Status; Channel<1> Status;
Channel<1> NPC; Channel<1> NPC;
Channel<1> SNR[2]; Channel<1> SNR[2];

View File

@ -2492,6 +2492,7 @@ void RSXThread::Task()
{ {
m_call_stack.push(get + 4); m_call_stack.push(get + 4);
u32 offs = cmd & ~CELL_GCM_METHOD_FLAG_CALL; u32 offs = cmd & ~CELL_GCM_METHOD_FLAG_CALL;
u32 addr = Memory.RSXIOMem.GetStartAddr() + offs;
//LOG_WARNING(RSX, "rsx call(0x%x) #0x%x - 0x%x - 0x%x", offs, addr, cmd, get); //LOG_WARNING(RSX, "rsx call(0x%x) #0x%x - 0x%x - 0x%x", offs, addr, cmd, get);
m_ctrl->get = offs; m_ctrl->get = offs;
continue; continue;
@ -2501,7 +2502,6 @@ void RSXThread::Task()
//LOG_WARNING(RSX, "rsx return!"); //LOG_WARNING(RSX, "rsx return!");
u32 get = m_call_stack.top(); u32 get = m_call_stack.top();
m_call_stack.pop(); m_call_stack.pop();
u32 addr = Memory.RSXIOMem.GetStartAddr() + offs;
//LOG_WARNING(RSX, "rsx return(0x%x)", get); //LOG_WARNING(RSX, "rsx return(0x%x)", get);
m_ctrl->get = get; m_ctrl->get = get;
continue; continue;

View File

@ -41,7 +41,7 @@ bool DynamicMemoryBlockBase<PT>::IsMyAddress(const u64 addr)
const u32 index = MemoryBlock::FixAddr(addr) >> 12; const u32 index = MemoryBlock::FixAddr(addr) >> 12;
return m_pages[index] && !m_locked[index]; return m_pages[index] != nullptr;
} }
template<typename PT> template<typename PT>
@ -54,9 +54,7 @@ MemoryBlock* DynamicMemoryBlockBase<PT>::SetRange(const u64 start, const u32 siz
const u32 page_count = m_max_size >> 12; const u32 page_count = m_max_size >> 12;
m_pages.resize(page_count); m_pages.resize(page_count);
m_locked.resize(page_count);
memset(m_pages.data(), 0, sizeof(u8*) * page_count); memset(m_pages.data(), 0, sizeof(u8*) * page_count);
memset(m_locked.data(), 0, sizeof(u8*) * page_count);
return this; return this;
} }
@ -70,7 +68,6 @@ void DynamicMemoryBlockBase<PT>::Delete()
m_max_size = 0; m_max_size = 0;
m_pages.clear(); m_pages.clear();
m_locked.clear();
MemoryBlock::Delete(); MemoryBlock::Delete();
} }
@ -108,8 +105,7 @@ bool DynamicMemoryBlockBase<PT>::AllocFixed(u64 addr, u32 size)
template<typename PT> template<typename PT>
void DynamicMemoryBlockBase<PT>::AppendMem(u64 addr, u32 size) /* private */ void DynamicMemoryBlockBase<PT>::AppendMem(u64 addr, u32 size) /* private */
{ {
//u8* pointer = (u8*)m_allocated[m_allocated.Move(new MemBlockInfo(addr, size))].mem; m_allocated.emplace_back(addr, size, Memory.GetBaseAddr());
m_allocated.emplace_back(addr, size);
u8* pointer = (u8*) m_allocated.back().mem; u8* pointer = (u8*) m_allocated.back().mem;
const u32 first = MemoryBlock::FixAddr(addr) >> 12; const u32 first = MemoryBlock::FixAddr(addr) >> 12;
@ -119,7 +115,6 @@ void DynamicMemoryBlockBase<PT>::AppendMem(u64 addr, u32 size) /* private */
for (u32 i = first; i <= last; i++) for (u32 i = first; i <= last; i++)
{ {
m_pages[i] = pointer; m_pages[i] = pointer;
m_locked[i] = nullptr;
pointer += 4096; pointer += 4096;
} }
} }
@ -195,16 +190,15 @@ bool DynamicMemoryBlockBase<PT>::Free(u64 addr)
const u32 last = first + ((m_allocated[num].size - 1) >> 12); const u32 last = first + ((m_allocated[num].size - 1) >> 12);
// check if locked: // check if locked:
for (u32 i = first; i <= last; i++) //for (u32 i = first; i <= last; i++)
{ //{
if (!m_pages[i] || m_locked[i]) return false; // if (!m_pages[i]) return false;
} //}
// clear pointers: // clear pointers:
for (u32 i = first; i <= last; i++) for (u32 i = first; i <= last; i++)
{ {
m_pages[i] = nullptr; m_pages[i] = nullptr;
m_locked[i] = nullptr;
} }
m_allocated.erase(m_allocated.begin() + num); m_allocated.erase(m_allocated.begin() + num);
@ -217,6 +211,7 @@ bool DynamicMemoryBlockBase<PT>::Free(u64 addr)
{ {
LOG_NOTICE(MEMORY, "*** Memory Block: addr = 0x%llx, size = 0x%x", m_allocated[i].addr, m_allocated[i].size); LOG_NOTICE(MEMORY, "*** Memory Block: addr = 0x%llx, size = 0x%x", m_allocated[i].addr, m_allocated[i].size);
} }
assert(0);
return false; return false;
} }
@ -233,97 +228,34 @@ u8* DynamicMemoryBlockBase<PT>::GetMem(u64 addr) const // lock-free, addr is fix
} }
} }
LOG_ERROR(MEMORY, "GetMem(%llx) from not allocated address.", addr); LOG_ERROR(MEMORY, "GetMem(0x%llx) from not allocated address.", addr);
assert(0); assert(0);
return nullptr; return nullptr;
} }
template<typename PT> template<typename PT>
bool DynamicMemoryBlockBase<PT>::IsLocked(u64 addr) // lock-free bool DynamicMemoryBlockBase<PT>::IsLocked(u64 addr)
{ {
if (IsInMyRange(addr)) // TODO
{ LOG_ERROR(MEMORY, "IsLocked(0x%llx) not implemented", addr);
const u32 index = MemoryBlock::FixAddr(addr) >> 12; assert(0);
if (index < m_locked.size())
{
if (m_locked[index]) return true;
}
}
return false; return false;
} }
template<typename PT> template<typename PT>
bool DynamicMemoryBlockBase<PT>::Lock(u64 addr, u32 size) bool DynamicMemoryBlockBase<PT>::Lock(u64 addr, u32 size)
{ {
size = PAGE_4K(size); // align size // TODO
LOG_ERROR(MEMORY, "Lock(0x%llx, 0x%x) not implemented", addr, size);
addr &= ~4095; // align start address assert(0);
return false;
if (!IsInMyRange(addr, size))
{
assert(0);
return false;
}
if (IsMyAddress(addr) || IsMyAddress(addr + size - 1))
{
return false;
}
const u32 first = MemoryBlock::FixAddr(addr) >> 12;
const u32 last = first + ((size - 1) >> 12);
for (u32 i = first; i <= last; i++)
{
if (u8* pointer = m_pages[i])
{
m_locked[i] = pointer;
m_pages[i] = nullptr;
}
else // already locked or empty
{
}
}
return true;
} }
template<typename PT> template<typename PT>
bool DynamicMemoryBlockBase<PT>::Unlock(u64 addr, u32 size) bool DynamicMemoryBlockBase<PT>::Unlock(u64 addr, u32 size)
{ {
size = PAGE_4K(size); // align size // TODO
LOG_ERROR(MEMORY, "Unlock(0x%llx, 0x%x) not implemented", addr, size);
addr &= ~4095; // align start address assert(0);
return false;
if (!IsInMyRange(addr, size))
{
assert(0);
return false;
}
if (IsMyAddress(addr) || IsMyAddress(addr + size - 1))
{
return false;
}
const u32 first = MemoryBlock::FixAddr(addr) >> 12;
const u32 last = first + ((size - 1) >> 12);
for (u32 i = first; i <= last; i++)
{
if (u8* pointer = m_locked[i])
{
m_pages[i] = pointer;
m_locked[i] = nullptr;
}
else // already unlocked or empty
{
}
}
return true;
} }

View File

@ -31,16 +31,13 @@ void MemoryBlock::InitMemory()
{ {
if(!range_size) return; if(!range_size) return;
//if(mem) safe_free(mem);
if (mem) VirtualFree(mem, range_size, MEM_DECOMMIT); if (mem) VirtualFree(mem, range_size, MEM_DECOMMIT);
//mem = (u8*)malloc(range_size);
mem = (u8*)VirtualAlloc((void*)((u64)Memory.GetBaseAddr() + range_start), range_size, MEM_COMMIT, PAGE_READWRITE); mem = (u8*)VirtualAlloc((void*)((u64)Memory.GetBaseAddr() + range_start), range_size, MEM_COMMIT, PAGE_READWRITE);
memset(mem, 0, range_size); memset(mem, 0, range_size);
} }
void MemoryBlock::Delete() void MemoryBlock::Delete()
{ {
//if(mem) safe_free(mem);
if (mem) VirtualFree(mem, range_size, MEM_DECOMMIT); if (mem) VirtualFree(mem, range_size, MEM_DECOMMIT);
Init(); Init();
} }
@ -54,7 +51,6 @@ bool MemoryBlock::GetMemFromAddr(void* dst, const u64 addr, const u32 size)
{ {
if(!IsMyAddress(addr) || FixAddr(addr) + size > GetSize()) return false; if(!IsMyAddress(addr) || FixAddr(addr) + size > GetSize()) return false;
// mem cpy(dst, GetMem(FixAddr(addr)), size);
return Memory.CopyToReal(dst, (u32)addr, size); return Memory.CopyToReal(dst, (u32)addr, size);
} }
@ -62,7 +58,6 @@ bool MemoryBlock::SetMemFromAddr(void* src, const u64 addr, const u32 size)
{ {
if(!IsMyAddress(addr) || FixAddr(addr) + size > GetSize()) return false; if(!IsMyAddress(addr) || FixAddr(addr) + size > GetSize()) return false;
// mem cpy(GetMem(FixAddr(addr)), src, size);
return Memory.CopyFromReal((u32)addr, src, size); return Memory.CopyFromReal((u32)addr, src, size);
} }
@ -121,7 +116,6 @@ bool MemoryBlock::Read8(const u64 addr, u8* value)
return false; return false;
} }
//*value = std::atomic_load((volatile std::atomic<u8>*)GetMem(FixAddr(addr)));
*value = FastRead<u8>(FixAddr(addr)); *value = FastRead<u8>(FixAddr(addr));
return true; return true;
} }
@ -134,7 +128,6 @@ bool MemoryBlock::Read16(const u64 addr, u16* value)
return false; return false;
} }
//se_t<u16>::func(*value, std::atomic_load((volatile std::atomic<u16>*)GetMem(FixAddr(addr))));
*value = FastRead<u16>(FixAddr(addr)); *value = FastRead<u16>(FixAddr(addr));
return true; return true;
} }
@ -147,7 +140,6 @@ bool MemoryBlock::Read32(const u64 addr, u32* value)
return false; return false;
} }
//se_t<u32>::func(*value, std::atomic_load((volatile std::atomic<u32>*)GetMem(FixAddr(addr))));
*value = FastRead<u32>(FixAddr(addr)); *value = FastRead<u32>(FixAddr(addr));
return true; return true;
} }
@ -160,7 +152,6 @@ bool MemoryBlock::Read64(const u64 addr, u64* value)
return false; return false;
} }
//se_t<u64>::func(*value, std::atomic_load((volatile std::atomic<u64>*)GetMem(FixAddr(addr))));
*value = FastRead<u64>(FixAddr(addr)); *value = FastRead<u64>(FixAddr(addr));
return true; return true;
} }
@ -173,9 +164,6 @@ bool MemoryBlock::Read128(const u64 addr, u128* value)
return false; return false;
} }
//u64 f_addr = FixAddr(addr);
//se_t<u64>::func(value->lo, std::atomic_load((volatile std::atomic<u64>*)GetMem(f_addr)));
//se_t<u64>::func(value->hi, std::atomic_load((volatile std::atomic<u64>*)GetMem(f_addr + 8)));
*value = FastRead<u128>(FixAddr(addr)); *value = FastRead<u128>(FixAddr(addr));
return true; return true;
} }
@ -199,7 +187,6 @@ bool MemoryBlock::Write8(const u64 addr, const u8 value)
{ {
if(!IsMyAddress(addr) || IsLocked(addr)) return false; if(!IsMyAddress(addr) || IsLocked(addr)) return false;
//std::atomic_store((std::atomic<u8>*)GetMem(FixAddr(addr)), value);
FastWrite<u8>(FixAddr(addr), value); FastWrite<u8>(FixAddr(addr), value);
return true; return true;
} }
@ -208,9 +195,6 @@ bool MemoryBlock::Write16(const u64 addr, const u16 value)
{ {
if(!IsMyAddress(addr) || IsLocked(addr)) return false; if(!IsMyAddress(addr) || IsLocked(addr)) return false;
//u16 re_value;
//se_t<u16>::func(re_value, value);
//std::atomic_store((std::atomic<u16>*)GetMem(FixAddr(addr)), re_value);
FastWrite<u16>(FixAddr(addr), value); FastWrite<u16>(FixAddr(addr), value);
return true; return true;
} }
@ -219,9 +203,6 @@ bool MemoryBlock::Write32(const u64 addr, const u32 value)
{ {
if(!IsMyAddress(addr) || IsLocked(addr)) return false; if(!IsMyAddress(addr) || IsLocked(addr)) return false;
//u32 re_value;
//se_t<u32>::func(re_value, value);
//std::atomic_store((std::atomic<u32>*)GetMem(FixAddr(addr)), re_value);
FastWrite<u32>(FixAddr(addr), value); FastWrite<u32>(FixAddr(addr), value);
return true; return true;
} }
@ -230,9 +211,6 @@ bool MemoryBlock::Write64(const u64 addr, const u64 value)
{ {
if(!IsMyAddress(addr) || IsLocked(addr)) return false; if(!IsMyAddress(addr) || IsLocked(addr)) return false;
//u64 re_value;
//se_t<u64>::func(re_value, value);
//std::atomic_store((std::atomic<u64>*)GetMem(FixAddr(addr)), re_value);
FastWrite<u64>(FixAddr(addr), value); FastWrite<u64>(FixAddr(addr), value);
return true; return true;
} }
@ -241,12 +219,6 @@ bool MemoryBlock::Write128(const u64 addr, const u128 value)
{ {
if(!IsMyAddress(addr) || IsLocked(addr)) return false; if(!IsMyAddress(addr) || IsLocked(addr)) return false;
//u64 f_addr = FixAddr(addr);
//u64 re_value;
//se_t<u64>::func(re_value, value.lo);
//std::atomic_store((std::atomic<u64>*)GetMem(f_addr), re_value);
//se_t<u64>::func(re_value, value.hi);
//std::atomic_store((std::atomic<u64>*)GetMem(f_addr + 8), re_value);
FastWrite<u128>(FixAddr(addr), value); FastWrite<u128>(FixAddr(addr), value);
return true; return true;
} }
@ -331,121 +303,36 @@ bool MemoryBlockLE::Write128(const u64 addr, const u128 value)
return true; return true;
} }
//NullMemoryBlock
bool NullMemoryBlock::Read8(const u64 addr, u8* )
{
LOG_ERROR(MEMORY, "Read8 from null block: [%08llx]", addr);
if (!Ini.CPUIgnoreRWErrors.GetValue())
Emu.Pause();
return false;
}
bool NullMemoryBlock::Read16(const u64 addr, u16* )
{
LOG_ERROR(MEMORY, "Read16 from null block: [%08llx]", addr);
if (!Ini.CPUIgnoreRWErrors.GetValue())
Emu.Pause();
return false;
}
bool NullMemoryBlock::Read32(const u64 addr, u32* )
{
LOG_ERROR(MEMORY, "Read32 from null block: [%08llx]", addr);
if (!Ini.CPUIgnoreRWErrors.GetValue())
Emu.Pause();
return false;
}
bool NullMemoryBlock::Read64(const u64 addr, u64* )
{
LOG_ERROR(MEMORY, "Read64 from null block: [%08llx]", addr);
if (!Ini.CPUIgnoreRWErrors.GetValue())
Emu.Pause();
return false;
}
bool NullMemoryBlock::Read128(const u64 addr, u128* )
{
LOG_ERROR(MEMORY, "Read128 from null block: [%08llx]", addr);
if (!Ini.CPUIgnoreRWErrors.GetValue())
Emu.Pause();
return false;
}
bool NullMemoryBlock::Write8(const u64 addr, const u8 value)
{
LOG_ERROR(MEMORY, "Write8 to null block: [%08llx]: %x", addr, value);
if (!Ini.CPUIgnoreRWErrors.GetValue())
Emu.Pause();
return false;
}
bool NullMemoryBlock::Write16(const u64 addr, const u16 value)
{
LOG_ERROR(MEMORY, "Write16 to null block: [%08llx]: %x", addr, value);
if (!Ini.CPUIgnoreRWErrors.GetValue())
Emu.Pause();
return false;
}
bool NullMemoryBlock::Write32(const u64 addr, const u32 value)
{
LOG_ERROR(MEMORY, "Write32 to null block: [%08llx]: %x", addr, value);
if (!Ini.CPUIgnoreRWErrors.GetValue())
Emu.Pause();
return false;
}
bool NullMemoryBlock::Write64(const u64 addr, const u64 value)
{
LOG_ERROR(MEMORY, "Write64 to null block: [%08llx]: %llx", addr, value);
if (!Ini.CPUIgnoreRWErrors.GetValue())
Emu.Pause();
return false;
}
bool NullMemoryBlock::Write128(const u64 addr, const u128 value)
{
LOG_ERROR(MEMORY, "Write128 to null block: [%08llx]: %llx_%llx", addr, value.hi, value.lo);
if (!Ini.CPUIgnoreRWErrors.GetValue())
Emu.Pause();
return false;
}
//MemoryBase //MemoryBase
void MemoryBase::Write8(u64 addr, const u8 data) void MemoryBase::Write8(u64 addr, const u8 data)
{ {
//GetMemByAddr(addr).Write8(addr, data);
*(u8*)((u64)GetBaseAddr() + addr) = data; *(u8*)((u64)GetBaseAddr() + addr) = data;
} }
void MemoryBase::Write16(u64 addr, const u16 data) void MemoryBase::Write16(u64 addr, const u16 data)
{ {
//GetMemByAddr(addr).Write16(addr, data);
*(u16*)((u64)GetBaseAddr() + addr) = re16(data); *(u16*)((u64)GetBaseAddr() + addr) = re16(data);
} }
void MemoryBase::Write32(u64 addr, const u32 data) void MemoryBase::Write32(u64 addr, const u32 data)
{ {
if (addr < 0xE0000000 || (addr % 0x100000) < 0x40000) if (addr < RAW_SPU_BASE_ADDR || (addr % RAW_SPU_OFFSET) < RAW_SPU_PROB_OFFSET || !RawSPUMem[(addr - RAW_SPU_BASE_ADDR) / RAW_SPU_OFFSET])
{ {
*(u32*)((u64)GetBaseAddr() + addr) = re32(data); *(u32*)((u64)GetBaseAddr() + addr) = re32(data);
} }
else else
{ {
GetMemByAddr(addr).Write32(addr, data); RawSPUMem[(addr - RAW_SPU_BASE_ADDR) / RAW_SPU_OFFSET]->Write32(addr, data);
} }
} }
void MemoryBase::Write64(u64 addr, const u64 data) void MemoryBase::Write64(u64 addr, const u64 data)
{ {
//GetMemByAddr(addr).Write64(addr, data);
*(u64*)((u64)GetBaseAddr() + addr) = re64(data); *(u64*)((u64)GetBaseAddr() + addr) = re64(data);
} }
void MemoryBase::Write128(u64 addr, const u128 data) void MemoryBase::Write128(u64 addr, const u128 data)
{ {
//GetMemByAddr(addr).Write128(addr, data);
*(u128*)((u64)GetBaseAddr() + addr) = re128(data); *(u128*)((u64)GetBaseAddr() + addr) = re128(data);
} }
@ -486,37 +373,36 @@ bool MemoryBase::Write128NN(u64 addr, const u128 data)
u8 MemoryBase::Read8(u64 addr) u8 MemoryBase::Read8(u64 addr)
{ {
u8 res; return *(u8*)((u64)GetBaseAddr() + addr);
Read8ByAddr(addr, &res);
return res;
} }
u16 MemoryBase::Read16(u64 addr) u16 MemoryBase::Read16(u64 addr)
{ {
u16 res; return re16(*(u16*)((u64)GetBaseAddr() + addr));
Read16ByAddr(addr, &res);
return res;
} }
u32 MemoryBase::Read32(u64 addr) u32 MemoryBase::Read32(u64 addr)
{ {
u32 res; if (addr < RAW_SPU_BASE_ADDR || (addr % RAW_SPU_OFFSET) < RAW_SPU_PROB_OFFSET || !RawSPUMem[(addr - RAW_SPU_BASE_ADDR) / RAW_SPU_OFFSET])
Read32ByAddr(addr, &res); {
return res; return re32(*(u32*)((u64)GetBaseAddr() + addr));
}
else
{
u32 res;
RawSPUMem[(addr - RAW_SPU_BASE_ADDR) / RAW_SPU_OFFSET]->Read32(addr, &res);
return res;
}
} }
u64 MemoryBase::Read64(u64 addr) u64 MemoryBase::Read64(u64 addr)
{ {
u64 res; return re64(*(u64*)((u64)GetBaseAddr() + addr));
Read64ByAddr(addr, &res);
return res;
} }
u128 MemoryBase::Read128(u64 addr) u128 MemoryBase::Read128(u64 addr)
{ {
u128 res; return re128(*(u128*)((u64)GetBaseAddr() + addr));
Read128ByAddr(addr, &res);
return res;
} }
template<> __forceinline u64 MemoryBase::ReverseData<1>(u64 val) { return val; } template<> __forceinline u64 MemoryBase::ReverseData<1>(u64 val) { return val; }

View File

@ -12,13 +12,21 @@ enum MemoryType
Memory_PSP, Memory_PSP,
}; };
enum : u64
{
RAW_SPU_OFFSET = 0x0000000000100000,
RAW_SPU_BASE_ADDR = 0x00000000E0000000,
RAW_SPU_LS_OFFSET = 0x0000000000000000,
RAW_SPU_PROB_OFFSET = 0x0000000000040000,
};
class MemoryBase class MemoryBase
{ {
NullMemoryBlock NullMem;
void* m_base_addr; void* m_base_addr;
std::vector<MemoryBlock*> MemoryBlocks;
std::mutex m_mutex;
public: public:
std::vector<MemoryBlock*> MemoryBlocks;
MemoryBlock* UserMemory; MemoryBlock* UserMemory;
DynamicMemoryBlock MainMem; DynamicMemoryBlock MainMem;
@ -27,8 +35,7 @@ public:
DynamicMemoryBlock MmaperMem; DynamicMemoryBlock MmaperMem;
DynamicMemoryBlock RSXFBMem; DynamicMemoryBlock RSXFBMem;
DynamicMemoryBlock StackMem; DynamicMemoryBlock StackMem;
MemoryBlock SpuRawMem; MemoryBlock* RawSPUMem[32];
MemoryBlock SpuThrMem;
VirtualMemoryBlock RSXIOMem; VirtualMemoryBlock RSXIOMem;
struct struct
@ -66,42 +73,23 @@ public:
static __forceinline u16 Reverse16(const u16 val) static __forceinline u16 Reverse16(const u16 val)
{ {
return _byteswap_ushort(val); return _byteswap_ushort(val);
//return ((val >> 8) & 0xff) | ((val << 8) & 0xff00);
} }
static __forceinline u32 Reverse32(const u32 val) static __forceinline u32 Reverse32(const u32 val)
{ {
return _byteswap_ulong(val); return _byteswap_ulong(val);
/*
return
((val >> 24) & 0x000000ff) |
((val >> 8) & 0x0000ff00) |
((val << 8) & 0x00ff0000) |
((val << 24) & 0xff000000);
*/
} }
static __forceinline u64 Reverse64(const u64 val) static __forceinline u64 Reverse64(const u64 val)
{ {
return _byteswap_uint64(val); return _byteswap_uint64(val);
/*
return
((val >> 56) & 0x00000000000000ff) |
((val >> 40) & 0x000000000000ff00) |
((val >> 24) & 0x0000000000ff0000) |
((val >> 8) & 0x00000000ff000000) |
((val << 8) & 0x000000ff00000000) |
((val << 24) & 0x0000ff0000000000) |
((val << 40) & 0x00ff000000000000) |
((val << 56) & 0xff00000000000000);
*/
} }
static __forceinline u128 Reverse128(const u128 val) static __forceinline u128 Reverse128(const u128 val)
{ {
u128 ret; u128 ret;
ret.lo = re64(val.hi); ret.lo = _byteswap_uint64(val.hi);
ret.hi = re64(val.lo); ret.hi = _byteswap_uint64(val.lo);
return ret; return ret;
} }
@ -112,99 +100,8 @@ public:
return (T)ReverseData<sizeof(T)>(val); return (T)ReverseData<sizeof(T)>(val);
}; };
MemoryBlock& GetMemByNum(const u8 num)
{
if(num >= MemoryBlocks.size()) return NullMem;
return *MemoryBlocks[num];
}
MemoryBlock& GetMemByAddr(const u64 addr)
{
for (auto block : MemoryBlocks)
{
if (block->IsMyAddress(addr))
return *block;
}
return NullMem;
}
bool Read8ByAddr(const u64 addr, u8 *value)
{
*value = *(u8*)((u64)GetBaseAddr() + addr);
return true;
/*for (auto block : MemoryBlocks)
{
if (block->Read8(addr, value))
return true;
}
return NullMem.Read8(addr, value);*/
}
bool Read16ByAddr(const u64 addr, u16 *value)
{
*value = re16(*(u16*)((u64)GetBaseAddr() + addr));
return true;
/*for (auto block : MemoryBlocks)
{
if (block->Read16(addr, value))
return true;
}
return NullMem.Read16(addr, value);*/
}
bool Read32ByAddr(const u64 addr, u32 *value)
{
if (addr < 0xE0000000 || (addr % 0x100000) < 0x40000)
{
*value = re32(*(u32*)((u64)GetBaseAddr() + addr));
return true;
}
for (auto block : MemoryBlocks)
{
if (block->Read32(addr, value))
return true;
}
return NullMem.Read32(addr, value);
}
bool Read64ByAddr(const u64 addr, u64 *value)
{
*value = re64(*(u64*)((u64)GetBaseAddr() + addr));
return true;
/*for (auto block : MemoryBlocks)
{
if (block->Read64(addr, value))
return true;
}
return NullMem.Read64(addr, value);*/
}
bool Read128ByAddr(const u64 addr, u128 *value)
{
*value = re128(*(u128*)((u64)GetBaseAddr() + addr));
return true;
/*for (auto block : MemoryBlocks)
{
if (block->Read128(addr, value))
return true;
}
return NullMem.Read128(addr, value);*/
}
u8* GetMemFromAddr(const u64 addr) u8* GetMemFromAddr(const u64 addr)
{ {
//return GetMemByAddr(addr).GetMemFromAddr(addr);
return (u8*)GetBaseAddr() + addr; return (u8*)GetBaseAddr() + addr;
} }
@ -215,36 +112,49 @@ public:
u64 RealToVirtualAddr(const void* addr) u64 RealToVirtualAddr(const void* addr)
{ {
const u64 raddr = (u64)addr; const u64 res = (u64)addr - (u64)GetBaseAddr();
for (auto block : MemoryBlocks)
if (res < 0x100000000)
{ {
MemoryBlock& b = *block; return res;
const u64 baddr = (u64)b.GetMem(); }
else
if(raddr >= baddr && raddr < baddr + b.GetSize()) {
{ return 0;
return b.GetStartAddr() + (raddr - baddr);
}
} }
return 0;
} }
bool InitSpuRawMem(const u32 max_spu_raw) void InitRawSPU(MemoryBlock* raw_spu, const u32 num)
{ {
//if(SpuRawMem.GetSize()) return false; std::lock_guard<std::mutex> lock(m_mutex);
MemoryBlocks.push_back(SpuRawMem.SetRange(0xe0000000, 0x100000 * max_spu_raw)); MemoryBlocks.push_back(raw_spu);
if (num < 32) RawSPUMem[num] = raw_spu;
}
return true; void CloseRawSPU(MemoryBlock* raw_spu, const u32 num)
{
std::lock_guard<std::mutex> lock(m_mutex);
for (int i = 0; i < MemoryBlocks.size(); ++i)
{
if (MemoryBlocks[i] == raw_spu)
{
MemoryBlocks.erase(MemoryBlocks.begin() + i);
break;
}
}
if (num < 32) RawSPUMem[num] = nullptr;
} }
void Init(MemoryType type) void Init(MemoryType type)
{ {
std::lock_guard<std::mutex> lock(m_mutex);
if(m_inited) return; if(m_inited) return;
m_inited = true; m_inited = true;
m_base_addr = VirtualAlloc(0, 0x100000000, MEM_RESERVE, PAGE_NOACCESS); m_base_addr = VirtualAlloc(nullptr, 0x100000000, MEM_RESERVE, PAGE_NOACCESS);
if (!m_base_addr) if (!m_base_addr)
{ {
LOG_ERROR(MEMORY, "Initing memory: VirtualAlloc() failed"); LOG_ERROR(MEMORY, "Initing memory: VirtualAlloc() failed");
@ -254,6 +164,11 @@ public:
LOG_NOTICE(MEMORY, "Initing memory: m_base_addr = 0x%llx", (u64)m_base_addr); LOG_NOTICE(MEMORY, "Initing memory: m_base_addr = 0x%llx", (u64)m_base_addr);
} }
for (u32 i = 0; i < 32; i++)
{
RawSPUMem[i] = nullptr;
}
switch(type) switch(type)
{ {
case Memory_PS3: case Memory_PS3:
@ -263,8 +178,6 @@ public:
MemoryBlocks.push_back(MmaperMem.SetRange(0xB0000000, 0x10000000)); MemoryBlocks.push_back(MmaperMem.SetRange(0xB0000000, 0x10000000));
MemoryBlocks.push_back(RSXFBMem.SetRange(0xC0000000, 0x10000000)); MemoryBlocks.push_back(RSXFBMem.SetRange(0xC0000000, 0x10000000));
MemoryBlocks.push_back(StackMem.SetRange(0xD0000000, 0x10000000)); MemoryBlocks.push_back(StackMem.SetRange(0xD0000000, 0x10000000));
//MemoryBlocks.push_back(SpuRawMem.SetRange(0xE0000000, 0x10000000));
//MemoryBlocks.push_back(SpuThrMem.SetRange(0xF0000000, 0x10000000));
break; break;
case Memory_PSV: case Memory_PSV:
@ -286,34 +199,68 @@ public:
bool IsGoodAddr(const u64 addr) bool IsGoodAddr(const u64 addr)
{ {
for (auto block : MemoryBlocks) //std::lock_guard<std::mutex> lock(m_mutex);
__try
{ {
if (block->IsMyAddress(addr)) volatile const u8 test = *GetMemFromAddr(addr);
return true; }
__except (EXCEPTION_EXECUTE_HANDLER)
{
return false;
} }
return false; return true;
//for (auto block : MemoryBlocks)
//{
// if (block->IsMyAddress(addr))
// return true;
//}
//return false;
} }
bool IsGoodAddr(const u64 addr, const u32 size) bool IsGoodAddr(const u64 addr, const u32 size)
{ {
const u64 end = addr + size - 1; //std::lock_guard<std::mutex> lock(m_mutex);
for (auto block : MemoryBlocks)
__try
{ {
if (block->IsMyAddress(addr) && block->IsMyAddress(end)) volatile const u8 test1 = *GetMemFromAddr(addr);
return true; volatile const u8 test2 = *GetMemFromAddr(addr + size - 1);
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
return false;
} }
return false; return true;
//const u64 end = addr + size - 1;
//for (auto block : MemoryBlocks)
//{
// if (block->IsMyAddress(addr) && block->IsMyAddress(end))
// return true;
//}
//return false;
} }
void Close() void Close()
{ {
std::lock_guard<std::mutex> lock(m_mutex);
if(!m_inited) return; if(!m_inited) return;
m_inited = false; m_inited = false;
LOG_NOTICE(MEMORY, "Closing memory..."); LOG_NOTICE(MEMORY, "Closing memory...");
for (u32 i = 0; i < 32; i++)
{
RawSPUMem[i] = nullptr;
}
for (auto block : MemoryBlocks) for (auto block : MemoryBlocks)
{ {
block->Delete(); block->Delete();
@ -345,78 +292,25 @@ public:
u64 Read64(const u64 addr); u64 Read64(const u64 addr);
u128 Read128(const u64 addr); u128 Read128(const u64 addr);
bool CopyToReal(void* real, u32 from, u32 count) // (4K pages) copy from virtual to real memory bool CopyToReal(void* real, u32 from, u32 count)
{ {
if (!count) return true; if (!count) return true;
u8* to = (u8*)real; memcpy(real, GetMemFromAddr(from), count);
if (u32 frag = from & 4095)
{
if (!IsGoodAddr(from)) return false;
u32 num = 4096 - frag;
if (count < num) num = count;
memcpy(to, GetMemFromAddr(from), num);
to += num;
from += num;
count -= num;
}
for (u32 page = count / 4096; page > 0; page--)
{
if (!IsGoodAddr(from)) return false;
memcpy(to, GetMemFromAddr(from), 4096);
to += 4096;
from += 4096;
count -= 4096;
}
if (count)
{
if (!IsGoodAddr(from)) return false;
memcpy(to, GetMemFromAddr(from), count);
}
return true; return true;
} }
bool CopyFromReal(u32 to, const void* real, u32 count) // (4K pages) copy from real to virtual memory bool CopyFromReal(u32 to, const void* real, u32 count)
{ {
if (!count) return true; if (!count) return true;
const u8* from = (const u8*)real; memcpy(GetMemFromAddr(to), real, count);
if (u32 frag = to & 4095)
{
if (!IsGoodAddr(to)) return false;
u32 num = 4096 - frag;
if (count < num) num = count;
memcpy(GetMemFromAddr(to), from, num);
to += num;
from += num;
count -= num;
}
for (u32 page = count / 4096; page > 0; page--)
{
if (!IsGoodAddr(to)) return false;
memcpy(GetMemFromAddr(to), from, 4096);
to += 4096;
from += 4096;
count -= 4096;
}
if (count)
{
if (!IsGoodAddr(to)) return false;
memcpy(GetMemFromAddr(to), from, count);
}
return true; return true;
} }
bool Copy(u32 to, u32 from, u32 count) // (4K pages) copy from virtual to virtual memory through real bool Copy(u32 to, u32 from, u32 count)
{ {
if (u8* buf = (u8*)malloc(count)) if (u8* buf = (u8*)malloc(count))
{ {
@ -447,54 +341,22 @@ public:
void ReadLeft(u8* dst, const u64 addr, const u32 size) void ReadLeft(u8* dst, const u64 addr, const u32 size)
{ {
MemoryBlock& mem = GetMemByAddr(addr); for (u32 i = 0; i < size; ++i) dst[size - 1 - i] = Read8(addr + i);
if(mem.IsNULL())
{
LOG_ERROR(MEMORY, "ReadLeft[%d] from null block (0x%llx)", size, addr);
return;
}
for(u32 i=0; i<size; ++i) mem.Read8(addr + i, dst + size - 1 - i);
} }
void WriteLeft(const u64 addr, const u32 size, const u8* src) void WriteLeft(const u64 addr, const u32 size, const u8* src)
{ {
MemoryBlock& mem = GetMemByAddr(addr); for (u32 i = 0; i < size; ++i) Write8(addr + i, src[size - 1 - i]);
if(mem.IsNULL())
{
LOG_ERROR(MEMORY, "WriteLeft[%d] to null block (0x%llx)", size, addr);
return;
}
for(u32 i=0; i<size; ++i) mem.Write8(addr + i, src[size - 1 - i]);
} }
void ReadRight(u8* dst, const u64 addr, const u32 size) void ReadRight(u8* dst, const u64 addr, const u32 size)
{ {
MemoryBlock& mem = GetMemByAddr(addr); for (u32 i = 0; i < size; ++i) dst[i] = Read8(addr + (size - 1 - i));
if(mem.IsNULL())
{
LOG_ERROR(MEMORY, "ReadRight[%d] from null block (0x%llx)", size, addr);
return;
}
for(u32 i=0; i<size; ++i) mem.Read8(addr + (size - 1 - i), dst + i);
} }
void WriteRight(const u64 addr, const u32 size, const u8* src) void WriteRight(const u64 addr, const u32 size, const u8* src)
{ {
MemoryBlock& mem = GetMemByAddr(addr); for (u32 i = 0; i < size; ++i) Write8(addr + (size - 1 - i), src[i]);
if(mem.IsNULL())
{
LOG_ERROR(MEMORY, "WriteRight[%d] to null block (0x%llx)", size, addr);
return;
}
for(u32 i=0; i<size; ++i) mem.Write8(addr + (size - 1 - i), src[i]);
} }
template<typename T> void WriteData(const u64 addr, const T* data) template<typename T> void WriteData(const u64 addr, const T* data)
@ -521,12 +383,6 @@ public:
void WriteString(const u64 addr, const std::string& str) void WriteString(const u64 addr, const std::string& str)
{ {
if(!IsGoodAddr(addr, str.length()))
{
LOG_ERROR(MEMORY,"Memory::WriteString error: bad address (0x%llx)", addr);
return;
}
strcpy((char*)GetMemFromAddr(addr), str.c_str()); strcpy((char*)GetMemFromAddr(addr), str.c_str());
} }
@ -567,6 +423,8 @@ public:
bool Map(const u64 dst_addr, const u64 src_addr, const u32 size) bool Map(const u64 dst_addr, const u64 src_addr, const u32 size)
{ {
std::lock_guard<std::mutex> lock(m_mutex);
if(IsGoodAddr(dst_addr) || !IsGoodAddr(src_addr)) if(IsGoodAddr(dst_addr) || !IsGoodAddr(src_addr))
{ {
return false; return false;
@ -579,6 +437,8 @@ public:
bool Unmap(const u64 addr) bool Unmap(const u64 addr)
{ {
std::lock_guard<std::mutex> lock(m_mutex);
bool result = false; bool result = false;
for(uint i=0; i<MemoryBlocks.size(); ++i) for(uint i=0; i<MemoryBlocks.size(); ++i)
{ {
@ -598,8 +458,6 @@ public:
u8* operator + (const u64 vaddr) u8* operator + (const u64 vaddr)
{ {
u8* ret = GetMemFromAddr(vaddr); u8* ret = GetMemFromAddr(vaddr);
if(ret == nullptr)
throw fmt::Format("GetMemFromAddr(0x%x)", vaddr);
return ret; return ret;
} }

View File

@ -24,7 +24,6 @@ struct MemBlockInfo : public MemInfo
MemBlockInfo(u64 _addr, u32 _size, void* base_addr) MemBlockInfo(u64 _addr, u32 _size, void* base_addr)
: MemInfo(_addr, PAGE_4K(_size)) : MemInfo(_addr, PAGE_4K(_size))
//, mem(_aligned_malloc(PAGE_4K(_size), 128))
, mem(VirtualAlloc((void*)((u64)base_addr + _addr), PAGE_4K(_size), MEM_COMMIT, PAGE_READWRITE)) , mem(VirtualAlloc((void*)((u64)base_addr + _addr), PAGE_4K(_size), MEM_COMMIT, PAGE_READWRITE))
{ {
if(!mem) if(!mem)
@ -44,7 +43,6 @@ struct MemBlockInfo : public MemInfo
MemBlockInfo& operator =(MemBlockInfo &&other){ MemBlockInfo& operator =(MemBlockInfo &&other){
this->addr = other.addr; this->addr = other.addr;
this->size = other.size; this->size = other.size;
//if (this->mem) _aligned_free(mem);
if (this->mem) VirtualFree(this->mem, this->size, MEM_DECOMMIT); if (this->mem) VirtualFree(this->mem, this->size, MEM_DECOMMIT);
this->mem = other.mem; this->mem = other.mem;
other.mem = nullptr; other.mem = nullptr;
@ -53,7 +51,6 @@ struct MemBlockInfo : public MemInfo
~MemBlockInfo() ~MemBlockInfo()
{ {
//if(mem) _aligned_free(mem);
if (mem) VirtualFree(mem, size, MEM_DECOMMIT); if (mem) VirtualFree(mem, size, MEM_DECOMMIT);
mem = nullptr; mem = nullptr;
} }
@ -207,7 +204,6 @@ class DynamicMemoryBlockBase : public PT
mutable std::mutex m_lock; mutable std::mutex m_lock;
std::vector<MemBlockInfo> m_allocated; // allocation info std::vector<MemBlockInfo> m_allocated; // allocation info
std::vector<u8*> m_pages; // real addresses of every 4096 byte pages (array size should be fixed) std::vector<u8*> m_pages; // real addresses of every 4096 byte pages (array size should be fixed)
std::vector<u8*> m_locked; // locked pages should be moved here
u32 m_max_size; u32 m_max_size;

View File

@ -315,17 +315,16 @@ int cellGcmInit(u32 context_addr, u32 cmdSize, u32 ioSize, u32 ioAddress)
if (system_mode == CELL_GCM_SYSTEM_MODE_IOMAP_512MB) if (system_mode == CELL_GCM_SYSTEM_MODE_IOMAP_512MB)
{ {
cellGcmSys->Warning("cellGcmInit(): 512MB io address space used"); cellGcmSys->Warning("cellGcmInit(): 512MB io address space used");
Memory.MemoryBlocks.push_back(Memory.RSXIOMem.SetRange(0x50000000, 0x20000000/*512MB*/));//TODO: implement allocateAdressSpace in memoryBase Memory.RSXIOMem.SetRange(0x50000000, 0x20000000 /*512MB*/);
} }
else else
{ {
cellGcmSys->Warning("cellGcmInit(): 256MB io address space used"); cellGcmSys->Warning("cellGcmInit(): 256MB io address space used");
Memory.MemoryBlocks.push_back(Memory.RSXIOMem.SetRange(0x50000000, 0x10000000/*256MB*/));//TODO: implement allocateAdressSpace in memoryBase Memory.RSXIOMem.SetRange(0x50000000, 0x10000000 /*256MB*/);
} }
if(cellGcmMapEaIoAddress(ioAddress, 0, ioSize) != CELL_OK) if(cellGcmMapEaIoAddress(ioAddress, 0, ioSize) != CELL_OK)
{ {
Memory.MemoryBlocks.pop_back();
cellGcmSys->Error("cellGcmInit : CELL_GCM_ERROR_FAILURE"); cellGcmSys->Error("cellGcmInit : CELL_GCM_ERROR_FAILURE");
return CELL_GCM_ERROR_FAILURE; return CELL_GCM_ERROR_FAILURE;
} }

View File

@ -1135,7 +1135,7 @@ int cellRescSetBufferAddress(mem32_t colorBuffers, mem32_t vertexArray, mem32_t
if(colorBuffers.GetAddr() % COLOR_BUFFER_ALIGNMENT || vertexArray.GetAddr() % VERTEX_BUFFER_ALIGNMENT || fragmentShader.GetAddr() % FRAGMENT_SHADER_ALIGNMENT) if(colorBuffers.GetAddr() % COLOR_BUFFER_ALIGNMENT || vertexArray.GetAddr() % VERTEX_BUFFER_ALIGNMENT || fragmentShader.GetAddr() % FRAGMENT_SHADER_ALIGNMENT)
{ {
cellResc->Error("cellRescSetBufferAddress : CELL_RESC_ERROR_BAD_ARGUMENT"); cellResc->Error("cellRescSetBufferAddress : CELL_RESC_ERROR_BAD_ARGUMENT (alignment)");
return CELL_RESC_ERROR_BAD_ARGUMENT; return CELL_RESC_ERROR_BAD_ARGUMENT;
} }

View File

@ -335,9 +335,6 @@ int cellVideoOutGetResolutionAvailability(u32 videoOut, u32 resolutionId, u32 as
return CELL_VIDEO_OUT_ERROR_UNSUPPORTED_VIDEO_OUT; return CELL_VIDEO_OUT_ERROR_UNSUPPORTED_VIDEO_OUT;
} }
extern std::atomic<u32> g_FsAioReadID;
extern std::atomic<u32> g_FsAioReadCur;
int cellSysutilCheckCallback() int cellSysutilCheckCallback()
{ {
cellSysutil->Log("cellSysutilCheckCallback()"); cellSysutil->Log("cellSysutilCheckCallback()");
@ -346,7 +343,7 @@ int cellSysutilCheckCallback()
CPUThread& thr = Emu.GetCallbackThread(); CPUThread& thr = Emu.GetCallbackThread();
while (thr.IsAlive() || (g_FsAioReadCur < g_FsAioReadID)) while (thr.IsAlive())
{ {
Sleep(1); Sleep(1);
if (Emu.IsStopped()) if (Emu.IsStopped())

View File

@ -361,7 +361,7 @@ int cellSurMixerCreate(const mem_ptr_t<CellSurMixerConfig> config)
break; break;
} }
if (mixcount > (port.tag + 15)) // preemptive buffer filling (probably hack) if (mixcount > (port.tag + 14)) // preemptive buffer filling (probably hack)
{ {
Sleep(1); Sleep(1);
continue; continue;

View File

@ -162,74 +162,35 @@ void fsAioRead(u32 fd, mem_ptr_t<CellFsAio> aio, int xid, mem_func_ptr_t<void (*
u64 nbytes = aio->size; u64 nbytes = aio->size;
u32 buf_addr = aio->buf_addr; u32 buf_addr = aio->buf_addr;
u32 res = 0;
u32 error = CELL_OK; u32 error = CELL_OK;
vfsStream& file = *(vfsStream*)orig_file; vfsStream& file = *(vfsStream*)orig_file;
const u64 old_pos = file.Tell(); const u64 old_pos = file.Tell();
file.Seek((u64)aio->offset); file.Seek((u64)aio->offset);
u32 count = nbytes; // TODO: use code from cellFsRead or something
if (nbytes != (u64)count)
u64 res = 0;
if (nbytes != (u32)nbytes)
{ {
error = CELL_ENOMEM; error = CELL_ENOMEM;
goto fin;
} }
else
if (!Memory.IsGoodAddr(buf_addr))
{ {
error = CELL_EFAULT; res = nbytes ? file.Read(Memory.GetMemFromAddr(buf_addr), nbytes) : 0;
goto fin;
} }
if (count) if (u32 frag = buf_addr & 4095) // memory page fragment
{
u32 req = std::min(count, 4096 - frag);
u32 read = file.Read(Memory + buf_addr, req);
buf_addr += req;
res += read;
count -= req;
if (read < req) goto fin;
}
for (u32 pages = count / 4096; pages > 0; pages--) // full pages
{
if (!Memory.IsGoodAddr(buf_addr)) goto fin; // ??? (probably EFAULT)
u32 read = file.Read(Memory + buf_addr, 4096);
buf_addr += 4096;
res += read;
count -= 4096;
if (read < 4096) goto fin;
}
if (count) // last fragment
{
if (!Memory.IsGoodAddr(buf_addr)) goto fin;
res += file.Read(Memory + buf_addr, count);
}
fin:
file.Seek(old_pos); file.Seek(old_pos);
LOG_WARNING(HLE, "*** fsAioRead(fd=%d, offset=0x%llx, buf_addr=0x%x, size=0x%x, error=0x%x, res=0x%x, xid=0x%x [%s])", if (Ini.HLELogging.GetValue())
fd, (u64)aio->offset, buf_addr, (u64)aio->size, error, res, xid, orig_file->GetPath().c_str()); LOG_NOTICE(HLE, "*** fsAioRead(fd=%d, offset=0x%llx, buf_addr=0x%x, size=0x%x, error=0x%x, res=0x%x, xid=0x%x [%s])",
fd, (u64)aio->offset, buf_addr, (u64)aio->size, error, res, xid, orig_file->GetPath().c_str());
if (func) // start callback thread if (func) // start callback thread
{ {
func.async(aio, error, xid, res); func.async(aio, error, xid, res);
} }
/*CPUThread& thr = Emu.GetCallbackThread();
while (thr.IsAlive())
{
Sleep(1);
if (Emu.IsStopped())
{
LOG_WARNING(HLE, "fsAioRead() aborted");
break;
}
}*/
g_FsAioReadCur++; g_FsAioReadCur++;
} }

View File

@ -146,39 +146,11 @@ s32 cellFsRead(u32 fd, u32 buf_addr, u64 nbytes, mem64_t nread)
if (nread.GetAddr() && !nread.IsGood()) return CELL_EFAULT; if (nread.GetAddr() && !nread.IsGood()) return CELL_EFAULT;
u32 res = 0; if (nbytes != (u32)nbytes) return CELL_ENOMEM;
u32 count = nbytes;
if (nbytes != (u64)count) return CELL_ENOMEM;
if (!Memory.IsGoodAddr(buf_addr)) return CELL_EFAULT; // TODO: checks
if (count) if (u32 frag = buf_addr & 4095) // memory page fragment const u64 res = nbytes ? file->Read(Memory.GetMemFromAddr(buf_addr), nbytes) : 0;
{
u32 req = std::min(count, 4096 - frag);
u32 read = file->Read(Memory + buf_addr, req);
buf_addr += req;
res += read;
count -= req;
if (read < req) goto fin;
}
for (u32 pages = count / 4096; pages > 0; pages--) // full pages
{
if (!Memory.IsGoodAddr(buf_addr)) goto fin; // ??? (probably EFAULT)
u32 read = file->Read(Memory + buf_addr, 4096);
buf_addr += 4096;
res += read;
count -= 4096;
if (read < 4096) goto fin;
}
if (count) // last fragment
{
if (!Memory.IsGoodAddr(buf_addr)) goto fin;
res += file->Read(Memory + buf_addr, count);
}
fin:
if (nread.GetAddr()) nread = res; // write value if not NULL if (nread.GetAddr()) nread = res; // write value if not NULL
@ -192,16 +164,15 @@ s32 cellFsWrite(u32 fd, u32 buf_addr, u64 nbytes, mem64_t nwrite)
vfsStream* file; vfsStream* file;
if(!sys_fs->CheckId(fd, file)) return CELL_ESRCH; if(!sys_fs->CheckId(fd, file)) return CELL_ESRCH;
if(Memory.IsGoodAddr(buf_addr) && !Memory.IsGoodAddr(buf_addr, nbytes)) if (nwrite.GetAddr() && !nwrite.IsGood()) return CELL_EFAULT;
{
MemoryBlock& block = Memory.GetMemByAddr(buf_addr); if (nbytes != (u32)nbytes) return CELL_ENOMEM;
nbytes = block.GetSize() - (buf_addr - block.GetStartAddr());
} // TODO: checks
const u64 res = nbytes ? file->Write(Memory.GetMemFromAddr(buf_addr), nbytes) : 0; const u64 res = nbytes ? file->Write(Memory.GetMemFromAddr(buf_addr), nbytes) : 0;
if(nwrite.IsGood()) if (nwrite.GetAddr()) nwrite = res; // write value if not NULL
nwrite = res;
return CELL_OK; return CELL_OK;
} }

View File

@ -23,14 +23,16 @@ s32 sys_process_getppid()
s32 sys_process_exit(s32 errorcode) s32 sys_process_exit(s32 errorcode)
{ {
sc_p.Warning("sys_process_exit(%d)", errorcode); sc_p.Warning("sys_process_exit(%d)", errorcode);
Emu.Pause(); // Emu.Stop() does crash Emu.Pause();
LOG_SUCCESS(HLE, "Process finished"); LOG_SUCCESS(HLE, "Process finished");
wxGetApp().CallAfter([]()
if (Ini.HLEExitOnStop.GetValue())
{ {
Ini.HLEExitOnStop.SetValue(false); Emu.Stop();
// TODO: Find a way of calling Emu.Stop() and/or exiting RPCS3 (that is, TheApp->Exit()) without crashes if (Ini.HLEExitOnStop.GetValue())
} {
wxGetApp().Exit();
}
});
return CELL_OK; return CELL_OK;
} }

View File

@ -391,14 +391,6 @@ s32 sys_spu_initialize(u32 max_usable_spu, u32 max_raw_spu)
return CELL_EINVAL; return CELL_EINVAL;
} }
//if(!Memory.InitSpuRawMem(max_raw_spu))
//{
// return CELL_ENOMEM;
//}
//Ini.HLELogging.SetValue(true);
//dump_enable = true;
return CELL_OK; return CELL_OK;
} }
@ -773,7 +765,6 @@ s32 sys_raw_spu_create(mem32_t id, u32 attr_addr)
CPUThread& new_thread = Emu.GetCPU().AddThread(CPU_THREAD_RAW_SPU); CPUThread& new_thread = Emu.GetCPU().AddThread(CPU_THREAD_RAW_SPU);
id = ((RawSPUThread&)new_thread).GetIndex(); id = ((RawSPUThread&)new_thread).GetIndex();
new_thread.Run(); new_thread.Run();
new_thread.Exec();
return CELL_OK; return CELL_OK;
} }

View File

@ -312,6 +312,7 @@
<ClInclude Include="Emu\Io\Windows\WindowsKeyboardHandler.h" /> <ClInclude Include="Emu\Io\Windows\WindowsKeyboardHandler.h" />
<ClInclude Include="Emu\Io\Windows\WindowsMouseHandler.h" /> <ClInclude Include="Emu\Io\Windows\WindowsMouseHandler.h" />
<ClInclude Include="Emu\Io\Windows\WindowsPadHandler.h" /> <ClInclude Include="Emu\Io\Windows\WindowsPadHandler.h" />
<ClInclude Include="Emu\Memory\DynamicMemoryBlockBase.h" />
<ClInclude Include="Emu\Memory\Memory.h" /> <ClInclude Include="Emu\Memory\Memory.h" />
<ClInclude Include="Emu\Memory\MemoryBlock.h" /> <ClInclude Include="Emu\Memory\MemoryBlock.h" />
<ClInclude Include="Emu\SysCalls\Callback.h" /> <ClInclude Include="Emu\SysCalls\Callback.h" />
@ -505,6 +506,7 @@
<PrecompiledHeader>Use</PrecompiledHeader> <PrecompiledHeader>Use</PrecompiledHeader>
<PreprocessorDefinitions>_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>_UNICODE;UNICODE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PrecompiledHeaderFile>stdafx.h</PrecompiledHeaderFile> <PrecompiledHeaderFile>stdafx.h</PrecompiledHeaderFile>
<ExceptionHandling>Async</ExceptionHandling>
</ClCompile> </ClCompile>
<Link> <Link>
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
@ -518,6 +520,7 @@
<PrecompiledHeader>Use</PrecompiledHeader> <PrecompiledHeader>Use</PrecompiledHeader>
<PreprocessorDefinitions>_UNICODE;UNICODE;MSVC_CRT_MEMLEAK_DETECTION;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>_UNICODE;UNICODE;MSVC_CRT_MEMLEAK_DETECTION;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<PrecompiledHeaderFile>stdafx.h</PrecompiledHeaderFile> <PrecompiledHeaderFile>stdafx.h</PrecompiledHeaderFile>
<ExceptionHandling>Async</ExceptionHandling>
</ClCompile> </ClCompile>
<Link> <Link>
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
@ -548,6 +551,7 @@
<SDLCheck>false</SDLCheck> <SDLCheck>false</SDLCheck>
<PrecompiledHeader>Use</PrecompiledHeader> <PrecompiledHeader>Use</PrecompiledHeader>
<PrecompiledHeaderFile>stdafx.h</PrecompiledHeaderFile> <PrecompiledHeaderFile>stdafx.h</PrecompiledHeaderFile>
<ExceptionHandling>Async</ExceptionHandling>
</ClCompile> </ClCompile>
<Link> <Link>
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>

View File

@ -1093,5 +1093,8 @@
<ClInclude Include="Emu\SysCalls\Modules\cellMsgDialog.h"> <ClInclude Include="Emu\SysCalls\Modules\cellMsgDialog.h">
<Filter>Emu\SysCalls\Modules</Filter> <Filter>Emu\SysCalls\Modules</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="Emu\Memory\DynamicMemoryBlockBase.h">
<Filter>Emu\Memory</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@ -81,6 +81,7 @@
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat> <DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
<PrecompiledHeader>Use</PrecompiledHeader> <PrecompiledHeader>Use</PrecompiledHeader>
<AdditionalIncludeDirectories>..\wxWidgets\include\msvc</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>..\wxWidgets\include\msvc</AdditionalIncludeDirectories>
<ExceptionHandling>Async</ExceptionHandling>
</ClCompile> </ClCompile>
<Link> <Link>
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
@ -104,6 +105,7 @@
<PrecompiledHeader>Use</PrecompiledHeader> <PrecompiledHeader>Use</PrecompiledHeader>
<AdditionalIncludeDirectories>..\wxWidgets\include\msvc</AdditionalIncludeDirectories> <AdditionalIncludeDirectories>..\wxWidgets\include\msvc</AdditionalIncludeDirectories>
<PreprocessorDefinitions>_UNICODE;UNICODE;MSVC_CRT_MEMLEAK_DETECTION;%(PreprocessorDefinitions)</PreprocessorDefinitions> <PreprocessorDefinitions>_UNICODE;UNICODE;MSVC_CRT_MEMLEAK_DETECTION;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ExceptionHandling>Async</ExceptionHandling>
</ClCompile> </ClCompile>
<Link> <Link>
<GenerateDebugInformation>true</GenerateDebugInformation> <GenerateDebugInformation>true</GenerateDebugInformation>
@ -131,7 +133,7 @@
<DisableLanguageExtensions>false</DisableLanguageExtensions> <DisableLanguageExtensions>false</DisableLanguageExtensions>
<PrecompiledHeader>Use</PrecompiledHeader> <PrecompiledHeader>Use</PrecompiledHeader>
<FavorSizeOrSpeed>Speed</FavorSizeOrSpeed> <FavorSizeOrSpeed>Speed</FavorSizeOrSpeed>
<ExceptionHandling>Sync</ExceptionHandling> <ExceptionHandling>Async</ExceptionHandling>
<EnablePREfast>false</EnablePREfast> <EnablePREfast>false</EnablePREfast>
<MultiProcessorCompilation>true</MultiProcessorCompilation> <MultiProcessorCompilation>true</MultiProcessorCompilation>
</ClCompile> </ClCompile>