Compare commits

...

7 Commits

9 changed files with 169 additions and 52 deletions

View File

@ -291,6 +291,24 @@ void* HostSys::CreateSharedMemory(const char* name, size_t size)
return reinterpret_cast<void*>(static_cast<uintptr_t>(port)); return reinterpret_cast<void*>(static_cast<uintptr_t>(port));
} }
void* HostSys::CreateMappingFromFile(FILE* file)
{
return reinterpret_cast<void*>(static_cast<uintptr_t>(fileno(file)));
}
void* HostSys::MapMapping(void* handle, size_t size, const PageProtectionMode& mode)
{
const u32 mmap_prot = (mode.CanWrite() ? (PROT_READ | PROT_WRITE) : (PROT_READ)) | (mode.CanExecute() ? PROT_EXEC : 0);
return mmap(nullptr, size, mmap_prot, MAP_PRIVATE | MAP_ANON, static_cast<int>(reinterpret_cast<intptr_t>(handle)), 0);
}
void HostSys::DestroyMapping(void* handle)
{
// The handle mmap requires is the same as the file descriptor.
return;
}
void HostSys::DestroySharedMemory(void* ptr) void HostSys::DestroySharedMemory(void* ptr)
{ {
mach_port_deallocate(mach_task_self(), static_cast<mach_port_t>(reinterpret_cast<uintptr_t>(ptr))); mach_port_deallocate(mach_task_self(), static_cast<mach_port_t>(reinterpret_cast<uintptr_t>(ptr)));

View File

@ -101,6 +101,11 @@ namespace HostSys
extern std::string GetFileMappingName(const char* prefix); extern std::string GetFileMappingName(const char* prefix);
extern void* CreateSharedMemory(const char* name, size_t size); extern void* CreateSharedMemory(const char* name, size_t size);
extern void* CreateMappingFromFile(FILE* file);
extern void* MapMapping(void* handle, size_t size, const PageProtectionMode& mode);
extern void DestroyMapping(void* handle);
extern void DestroySharedMemory(void* ptr); extern void DestroySharedMemory(void* ptr);
extern void* MapSharedMemory(void* handle, size_t offset, void* baseaddr, size_t size, const PageProtectionMode& mode); extern void* MapSharedMemory(void* handle, size_t offset, void* baseaddr, size_t size, const PageProtectionMode& mode);
extern void UnmapSharedMemory(void* baseaddr, size_t size); extern void UnmapSharedMemory(void* baseaddr, size_t size);

View File

@ -115,6 +115,22 @@ void* HostSys::CreateSharedMemory(const char* name, size_t size)
return reinterpret_cast<void*>(static_cast<intptr_t>(fd)); return reinterpret_cast<void*>(static_cast<intptr_t>(fd));
} }
void* HostSys::CreateMappingFromFile(FILE* file)
{
return reinterpret_cast<void*>(static_cast<intptr_t>(fileno(file)));
}
void* HostSys::MapMapping(void* handle, size_t size, const PageProtectionMode& mode)
{
return HostSys::MapSharedMemory(handle, 0, nullptr, size, mode);
}
void HostSys::DestroyMapping(void* handle)
{
// The handle mmap requires is the same as the file descriptor.
return;
}
void HostSys::DestroySharedMemory(void* ptr) void HostSys::DestroySharedMemory(void* ptr)
{ {
close(static_cast<int>(reinterpret_cast<intptr_t>(ptr))); close(static_cast<int>(reinterpret_cast<intptr_t>(ptr)));

View File

@ -12,6 +12,7 @@
#include "fmt/format.h" #include "fmt/format.h"
#include <io.h>
#include <mutex> #include <mutex>
static DWORD ConvertToWinApi(const PageProtectionMode& mode) static DWORD ConvertToWinApi(const PageProtectionMode& mode)
@ -71,6 +72,22 @@ void* HostSys::CreateSharedMemory(const char* name, size_t size)
static_cast<DWORD>(size >> 32), static_cast<DWORD>(size), StringUtil::UTF8StringToWideString(name).c_str())); static_cast<DWORD>(size >> 32), static_cast<DWORD>(size), StringUtil::UTF8StringToWideString(name).c_str()));
} }
void* HostSys::CreateMappingFromFile(FILE* fd)
{
return static_cast<void*>(CreateFileMappingW(reinterpret_cast<HANDLE>(_get_osfhandle(_fileno(fd))), NULL, PAGE_READWRITE,
0, 0, nullptr));
}
void* HostSys::MapMapping(void* handle, size_t size, const PageProtectionMode& mode)
{
return MapViewOfFile(static_cast<HANDLE>(handle), FILE_MAP_READ | FILE_MAP_WRITE, 0, 0, 0);
}
void HostSys::DestroyMapping(void* handle)
{
CloseHandle(static_cast<HANDLE>(handle));
}
void HostSys::DestroySharedMemory(void* ptr) void HostSys::DestroySharedMemory(void* ptr)
{ {
CloseHandle(static_cast<HANDLE>(ptr)); CloseHandle(static_cast<HANDLE>(ptr));

View File

@ -10,6 +10,7 @@
#include <ctime> #include <ctime>
#include <functional> #include <functional>
#include <memory>
#include <mutex> #include <mutex>
#include <optional> #include <optional>
#include <string> #include <string>

View File

@ -10,6 +10,7 @@
#include "common/Console.h" #include "common/Console.h"
#include "common/Error.h" #include "common/Error.h"
#include "common/FileSystem.h" #include "common/FileSystem.h"
#include "common/HostSys.h"
#include "common/Path.h" #include "common/Path.h"
#include "common/StringUtil.h" #include "common/StringUtil.h"
@ -157,6 +158,9 @@ class FileMemoryCard
{ {
protected: protected:
std::FILE* m_file[8] = {}; std::FILE* m_file[8] = {};
u8* m_mappings[8] = {};
void* m_mapping_handles[8] = {};
s64 m_fileSize[8] = {}; s64 m_fileSize[8] = {};
std::string m_filenames[8] = {}; std::string m_filenames[8] = {};
std::vector<u8> m_currentdata; std::vector<u8> m_currentdata;
@ -164,6 +168,8 @@ protected:
bool m_ispsx[8] = {}; bool m_ispsx[8] = {};
u32 m_chkaddr = 0; u32 m_chkaddr = 0;
std::chrono::time_point<std::chrono::system_clock> m_lastSaveTime = std::chrono::system_clock::now();
public: public:
FileMemoryCard(); FileMemoryCard();
~FileMemoryCard(); ~FileMemoryCard();
@ -319,10 +325,22 @@ void FileMemoryCard::Open()
"Close any other instances of PCSX2, or restart your computer.\n"), "Close any other instances of PCSX2, or restart your computer.\n"),
fname)); fname));
} }
else // Load checksum else // Load memory map and checksum
{ {
m_fileSize[slot] = FileSystem::FSize64(m_file[slot]); m_fileSize[slot] = FileSystem::FSize64(m_file[slot]);
m_mapping_handles[slot] = HostSys::CreateMappingFromFile(m_file[slot]);
if (!m_mapping_handles[slot])
{
Console.Warning("CreateMappingFromFile failed!");
}
m_mappings[slot] = static_cast<u8*>(HostSys::MapMapping(m_mapping_handles[slot], m_fileSize[slot], PageAccess_ReadWrite()));
if (!m_mappings[slot])
{
Console.Warning("MapSharedMemory failed! %d. %s", errno, strerror(errno));
}
Console.WriteLnFmt(Color_Green, "McdSlot {} [File]: {} [{} MB, {}]", slot, Path::GetFileName(fname), Console.WriteLnFmt(Color_Green, "McdSlot {} [File]: {} [{} MB, {}]", slot, Path::GetFileName(fname),
(m_fileSize[slot] + (MCD_SIZE + 1)) / MC2_MBSIZE, (m_fileSize[slot] + (MCD_SIZE + 1)) / MC2_MBSIZE,
FileMcd_IsMemoryCardFormatted(m_file[slot]) ? "Formatted" : "UNFORMATTED"); FileMcd_IsMemoryCardFormatted(m_file[slot]) ? "Formatted" : "UNFORMATTED");
@ -331,11 +349,9 @@ void FileMemoryCard::Open()
m_ispsx[slot] = m_fileSize[slot] == 0x20000; m_ispsx[slot] = m_fileSize[slot] == 0x20000;
m_chkaddr = 0x210; m_chkaddr = 0x210;
if (!m_ispsx[slot] && FileSystem::FSeek64(m_file[slot], m_chkaddr, SEEK_SET) == 0) if (!m_ispsx[slot])
{ {
const size_t read_result = std::fread(&m_chksum[slot], sizeof(m_chksum[slot]), 1, m_file[slot]); std::memcpy(&m_chksum[slot], m_mappings[slot] + m_chkaddr, sizeof(m_chksum[slot]));
if (read_result == 0)
Host::ReportErrorAsync("Memory Card Read Failed", "Error reading memory card.");
} }
} }
} }
@ -349,8 +365,8 @@ void FileMemoryCard::Close()
continue; continue;
// Store checksum // Store checksum
if (!m_ispsx[slot] && FileSystem::FSeek64(m_file[slot], m_chkaddr, SEEK_SET) == 0) if (!m_ispsx[slot])
std::fwrite(&m_chksum[slot], sizeof(m_chksum[slot]), 1, m_file[slot]); std::memcpy(m_mappings[slot] + m_chkaddr, &m_chksum[slot], sizeof(m_chksum[slot]));
std::fclose(m_file[slot]); std::fclose(m_file[slot]);
m_file[slot] = nullptr; m_file[slot] = nullptr;
@ -362,6 +378,13 @@ void FileMemoryCard::Close()
FileSystem::DeleteFilePath(name_in.c_str()); FileSystem::DeleteFilePath(name_in.c_str());
} }
if (m_mappings[slot])
{
HostSys::UnmapSharedMemory(m_mappings[slot], m_fileSize[slot]);
HostSys::DestroyMapping(m_mapping_handles[slot]);
m_mappings[slot] = nullptr;
}
m_filenames[slot] = {}; m_filenames[slot] = {};
m_fileSize[slot] = -1; m_fileSize[slot] = -1;
} }
@ -430,13 +453,21 @@ s32 FileMemoryCard::Read(uint slot, u8* dest, u32 adr, int size)
memset(dest, 0, size); memset(dest, 0, size);
return 1; return 1;
} }
if (!Seek(mcfp, adr))
return 0; if (adr + size > static_cast<u32>(m_fileSize[slot]))
return std::fread(dest, size, 1, mcfp) == 1; {
Console.Warning("(FileMcd) Warning: read past end of file. (%d) [%08X]", slot, adr);
}
std::memcpy(dest, m_mappings[slot] + adr, size);
return 1;
} }
s32 FileMemoryCard::Save(uint slot, const u8* src, u32 adr, int size) s32 FileMemoryCard::Save(uint slot, const u8* src, u32 adr, int size)
{ {
if (adr + size > static_cast<u32>(m_fileSize[slot]))
return 0;
std::FILE* mcfp = m_file[slot]; std::FILE* mcfp = m_file[slot];
if (!mcfp) if (!mcfp)
@ -454,14 +485,10 @@ s32 FileMemoryCard::Save(uint slot, const u8* src, u32 adr, int size)
} }
else else
{ {
if (!Seek(mcfp, adr))
return 0;
if (static_cast<int>(m_currentdata.size()) < size) if (static_cast<int>(m_currentdata.size()) < size)
m_currentdata.resize(size); m_currentdata.resize(size);
const size_t read_result = std::fread(m_currentdata.data(), size, 1, mcfp); std::memcpy(m_currentdata.data(), m_mappings[slot] + adr, size);
if (read_result == 0)
Host::ReportErrorAsync("Memory Card Read Failed", "Error reading memory card.");
for (int i = 0; i < size; i++) for (int i = 0; i < size; i++)
{ {
@ -483,26 +510,18 @@ s32 FileMemoryCard::Save(uint slot, const u8* src, u32 adr, int size)
} }
} }
if (!Seek(mcfp, adr)) std::memcpy(m_mappings[slot] + adr, src, size);
return 0;
if (std::fwrite(m_currentdata.data(), size, 1, mcfp) == 1) std::chrono::duration<float> elapsed = std::chrono::system_clock::now() - m_lastSaveTime;
if (elapsed > std::chrono::seconds(5))
{ {
static auto last = std::chrono::time_point<std::chrono::system_clock>(); Host::AddIconOSDMessage(fmt::format("MemoryCardSave{}", slot), ICON_PF_MEMORY_CARD,
fmt::format(TRANSLATE_FS("MemoryCard", "Memory Card '{}' was saved to storage."),
std::chrono::duration<float> elapsed = std::chrono::system_clock::now() - last; Path::GetFileName(m_filenames[slot])),
if (elapsed > std::chrono::seconds(5)) Host::OSD_INFO_DURATION);
{ m_lastSaveTime = std::chrono::system_clock::now();
Host::AddIconOSDMessage(fmt::format("MemoryCardSave{}", slot), ICON_PF_MEMORY_CARD,
fmt::format(TRANSLATE_FS("MemoryCard", "Memory Card '{}' was saved to storage."),
Path::GetFileName(m_filenames[slot])),
Host::OSD_INFO_DURATION);
last = std::chrono::system_clock::now();
}
return 1;
} }
return 1;
return 0;
} }
s32 FileMemoryCard::EraseBlock(uint slot, u32 adr) s32 FileMemoryCard::EraseBlock(uint slot, u32 adr)
@ -517,9 +536,9 @@ s32 FileMemoryCard::EraseBlock(uint slot, u32 adr)
if (!Seek(mcfp, adr)) if (!Seek(mcfp, adr))
return 0; return 0;
u8 buf[MC2_ERASE_SIZE]; std::memset(m_mappings[slot] + adr, 0xff, MC2_ERASE_SIZE);
std::memset(buf, 0xff, sizeof(buf));
return std::fwrite(buf, sizeof(buf), 1, mcfp) == 1; return 1;
} }
u64 FileMemoryCard::GetCRC(uint slot) u64 FileMemoryCard::GetCRC(uint slot)
@ -532,9 +551,6 @@ u64 FileMemoryCard::GetCRC(uint slot)
if (m_ispsx[slot]) if (m_ispsx[slot])
{ {
if (!Seek(mcfp, 0))
return 0;
const s64 mcfpsize = m_fileSize[slot]; const s64 mcfpsize = m_fileSize[slot];
if (mcfpsize < 0) if (mcfpsize < 0)
return 0; return 0;
@ -546,8 +562,7 @@ u64 FileMemoryCard::GetCRC(uint slot)
const uint filesize = static_cast<uint>(mcfpsize) / sizeof(buffer); const uint filesize = static_cast<uint>(mcfpsize) / sizeof(buffer);
for (uint i = filesize; i; --i) for (uint i = filesize; i; --i)
{ {
if (std::fread(buffer, sizeof(buffer), 1, mcfp) != 1) std::memcpy(buffer, m_mappings[slot], sizeof(buffer));
return 0;
for (uint t = 0; t < std::size(buffer); ++t) for (uint t = 0; t < std::size(buffer); ++t)
retval ^= buffer[t]; retval ^= buffer[t];

View File

@ -93,19 +93,19 @@ namespace usb_pad
u8 right_turntable = 0x80; u8 right_turntable = 0x80;
if (data.left_turntable_ccw > 0) if (data.left_turntable_ccw > 0)
{ {
left_turntable -= static_cast<u8>(std::min<int>(data.left_turntable_ccw * turntable_multiplier, 0x7F)); left_turntable -= static_cast<u8>(std::min<int>(data.left_turntable_ccw, 0x7F));
} }
else else
{ {
left_turntable += static_cast<u8>(std::min<int>(data.left_turntable_cw * turntable_multiplier, 0x7F)); left_turntable += static_cast<u8>(std::min<int>(data.left_turntable_cw, 0x7F));
} }
if (data.right_turntable_ccw > 0) if (data.right_turntable_ccw > 0)
{ {
right_turntable -= static_cast<u8>(std::min<int>(data.right_turntable_ccw * turntable_multiplier, 0x7F)); right_turntable -= static_cast<u8>(std::min<int>(data.right_turntable_ccw, 0x7F));
} }
else else
{ {
right_turntable += static_cast<u8>(std::min<int>(data.right_turntable_cw * turntable_multiplier, 0x7F)); right_turntable += static_cast<u8>(std::min<int>(data.right_turntable_cw, 0x7F));
} }
buf[3] = 0x80; buf[3] = 0x80;
buf[4] = 0x80; buf[4] = 0x80;
@ -369,19 +369,19 @@ namespace usb_pad
break; break;
case CID_DJ_LEFT_TURNTABLE_CW: case CID_DJ_LEFT_TURNTABLE_CW:
s->data.left_turntable_cw = static_cast<u32>(std::clamp<long>(std::lroundf(value * 128.0f), 0, 128)); s->data.left_turntable_cw = static_cast<u32>(std::clamp<long>(std::lroundf(value * s->turntable_multiplier * 128.0f), 0, 128));
break; break;
case CID_DJ_LEFT_TURNTABLE_CCW: case CID_DJ_LEFT_TURNTABLE_CCW:
s->data.left_turntable_ccw = static_cast<u32>(std::clamp<long>(std::lroundf(value * 128.0f), 0, 128)); s->data.left_turntable_ccw = static_cast<u32>(std::clamp<long>(std::lroundf(value * s->turntable_multiplier * 128.0f), 0, 128));
break; break;
case CID_DJ_RIGHT_TURNTABLE_CW: case CID_DJ_RIGHT_TURNTABLE_CW:
s->data.right_turntable_cw = static_cast<u32>(std::clamp<long>(std::lroundf(value * 128.0f), 0, 128)); s->data.right_turntable_cw = static_cast<u32>(std::clamp<long>(std::lroundf(value * s->turntable_multiplier * 128.0f), 0, 128));
break; break;
case CID_DJ_RIGHT_TURNTABLE_CCW: case CID_DJ_RIGHT_TURNTABLE_CCW:
s->data.right_turntable_ccw = static_cast<u32>(std::clamp<long>(std::lroundf(value * 128.0f), 0, 128)); s->data.right_turntable_ccw = static_cast<u32>(std::clamp<long>(std::lroundf(value * s->turntable_multiplier * 128.0f), 0, 128));
break; break;
case CID_DJ_DPAD_UP: case CID_DJ_DPAD_UP:
@ -446,8 +446,8 @@ namespace usb_pad
{"EffectsKnobRight", TRANSLATE_NOOP("USB", "Effects Knob Right"), nullptr, InputBindingInfo::Type::HalfAxis, CID_DJ_EFFECTSKNOB_RIGHT, GenericInputBinding::RightStickRight}, {"EffectsKnobRight", TRANSLATE_NOOP("USB", "Effects Knob Right"), nullptr, InputBindingInfo::Type::HalfAxis, CID_DJ_EFFECTSKNOB_RIGHT, GenericInputBinding::RightStickRight},
{"LeftTurntableCW", TRANSLATE_NOOP("USB", "Left Turntable Clockwise"), nullptr, InputBindingInfo::Type::HalfAxis, CID_DJ_LEFT_TURNTABLE_CW, GenericInputBinding::LeftStickRight}, {"LeftTurntableCW", TRANSLATE_NOOP("USB", "Left Turntable Clockwise"), nullptr, InputBindingInfo::Type::HalfAxis, CID_DJ_LEFT_TURNTABLE_CW, GenericInputBinding::LeftStickRight},
{"LeftTurntableCCW", TRANSLATE_NOOP("USB", "Left Turntable Counterclockwise"), nullptr, InputBindingInfo::Type::HalfAxis, CID_DJ_LEFT_TURNTABLE_CCW, GenericInputBinding::LeftStickLeft}, {"LeftTurntableCCW", TRANSLATE_NOOP("USB", "Left Turntable Counterclockwise"), nullptr, InputBindingInfo::Type::HalfAxis, CID_DJ_LEFT_TURNTABLE_CCW, GenericInputBinding::LeftStickLeft},
{"RightTurntableCW", TRANSLATE_NOOP("USB", "Right Turntable Clockwise"), nullptr, InputBindingInfo::Type::HalfAxis, CID_DJ_RIGHT_TURNTABLE_CW, GenericInputBinding::LeftStickDown}, {"RightTurntableCW", TRANSLATE_NOOP("USB", "Right Turntable Clockwise"), nullptr, InputBindingInfo::Type::HalfAxis, CID_DJ_RIGHT_TURNTABLE_CW, GenericInputBinding::LeftStickUp},
{"RightTurntableCCW", TRANSLATE_NOOP("USB", "Right Turntable Counterclockwise"), nullptr, InputBindingInfo::Type::HalfAxis, CID_DJ_RIGHT_TURNTABLE_CCW, GenericInputBinding::LeftStickUp}, {"RightTurntableCCW", TRANSLATE_NOOP("USB", "Right Turntable Counterclockwise"), nullptr, InputBindingInfo::Type::HalfAxis, CID_DJ_RIGHT_TURNTABLE_CCW, GenericInputBinding::LeftStickDown},
{"LeftTurntableGreen", TRANSLATE_NOOP("USB", "Left Turntable Green"), nullptr, InputBindingInfo::Type::Button, CID_DJ_LEFT_GREEN, GenericInputBinding::Unknown}, {"LeftTurntableGreen", TRANSLATE_NOOP("USB", "Left Turntable Green"), nullptr, InputBindingInfo::Type::Button, CID_DJ_LEFT_GREEN, GenericInputBinding::Unknown},
{"LeftTurntableRed", TRANSLATE_NOOP("USB", "Left Turntable Red"), nullptr, InputBindingInfo::Type::Button, CID_DJ_LEFT_RED, GenericInputBinding::Unknown}, {"LeftTurntableRed", TRANSLATE_NOOP("USB", "Left Turntable Red"), nullptr, InputBindingInfo::Type::Button, CID_DJ_LEFT_RED, GenericInputBinding::Unknown},
{"LeftTurntableBlue", TRANSLATE_NOOP("USB", "Left Turntable Blue"), nullptr, InputBindingInfo::Type::Button, CID_DJ_LEFT_BLUE, GenericInputBinding::Unknown}, {"LeftTurntableBlue", TRANSLATE_NOOP("USB", "Left Turntable Blue"), nullptr, InputBindingInfo::Type::Button, CID_DJ_LEFT_BLUE, GenericInputBinding::Unknown},
@ -464,8 +464,8 @@ namespace usb_pad
{ {
static constexpr const SettingInfo info[] = { static constexpr const SettingInfo info[] = {
{SettingInfo::Type::Float, "TurntableMultiplier", TRANSLATE_NOOP("USB", "Turntable Multiplier"), {SettingInfo::Type::Float, "TurntableMultiplier", TRANSLATE_NOOP("USB", "Turntable Multiplier"),
TRANSLATE_NOOP("USB", "Apply a multiplier to the turntable"), TRANSLATE_NOOP("USB", "Apply a sensitivity multiplier to turntable rotation.\nXbox 360 turntables require a 256x multiplier, most other turntables can use the default 1x multiplier."),
"1.00", "0.00", "100.0", "1.0", "%.0fx", nullptr, nullptr, 1.0f}}; "1.00", "0.00", "512.0", "1.0", "%.0fx", nullptr, nullptr, 1.0f}};
return info; return info;
} }

View File

@ -1595,6 +1595,14 @@ static void iopRecRecompile(const u32 startpc)
while (1) while (1)
{ {
BASEBLOCK* pblock = PSX_GETBLOCK(i);
if (i != startpc && pblock->GetFnptr() != (uptr)iopJITCompile)
{
// branch = 3
willbranch3 = 1;
s_nEndBlock = i;
break;
}
psxRegs.code = iopMemRead32(i); psxRegs.code = iopMemRead32(i);

View File

@ -2294,6 +2294,8 @@ static void recRecompile(const u32 startpc)
while (1) while (1)
{ {
BASEBLOCK* pblock = PC_GETBLOCK(i);
// stop before breakpoints // stop before breakpoints
if (isBreakpointNeeded(i) != 0 || isMemcheckNeeded(i) != 0) if (isBreakpointNeeded(i) != 0 || isMemcheckNeeded(i) != 0)
{ {
@ -2311,6 +2313,13 @@ static void recRecompile(const u32 startpc)
eeRecPerfLog.Write("Pagesplit @ %08X : size=%d insts", startpc, (i - startpc) / 4); eeRecPerfLog.Write("Pagesplit @ %08X : size=%d insts", startpc, (i - startpc) / 4);
break; break;
} }
if (pblock->GetFnptr() != (uptr)JITCompile)
{
willbranch3 = 1;
s_nEndBlock = i;
break;
}
} }
//HUH ? PSM ? whut ? THIS IS VIRTUAL ACCESS GOD DAMMIT //HUH ? PSM ? whut ? THIS IS VIRTUAL ACCESS GOD DAMMIT
@ -2614,6 +2623,34 @@ StartRecomp:
pxAssert((pc - startpc) >> 2 <= 0xffff); pxAssert((pc - startpc) >> 2 <= 0xffff);
s_pCurBlockEx->size = (pc - startpc) >> 2; s_pCurBlockEx->size = (pc - startpc) >> 2;
if (HWADDR(pc) <= Ps2MemSize::ExposedRam)
{
BASEBLOCKEX* oldBlock;
int i;
i = recBlocks.LastIndex(HWADDR(pc) - 4);
while ((oldBlock = recBlocks[i--]))
{
if (oldBlock == s_pCurBlockEx)
continue;
if (oldBlock->startpc >= HWADDR(pc))
continue;
if ((oldBlock->startpc + oldBlock->size * 4) <= HWADDR(startpc))
break;
if (memcmp(&recRAMCopy[oldBlock->startpc / 4], PSM(oldBlock->startpc),
oldBlock->size * 4))
{
recClear(startpc, (pc - startpc) / 4);
s_pCurBlockEx = recBlocks.Get(HWADDR(startpc));
pxAssert(s_pCurBlockEx->startpc == HWADDR(startpc));
break;
}
}
memcpy(&recRAMCopy[HWADDR(startpc) / 4], PSM(startpc), pc - startpc);
}
s_pCurBlock->SetFnptr((uptr)recPtr); s_pCurBlock->SetFnptr((uptr)recPtr);
if (!(pc & 0x10000000)) if (!(pc & 0x10000000))