mirror of
https://github.com/hrydgard/ppsspp.git
synced 2026-10-01 14:58:14 +00:00
More memory access cleanup
This commit is contained in:
1 parent
4cd10efe07
commit
0596ee97f6
37 files changed
+288
-294
No files matched your search
+20
-15
@@ -429,36 +429,41 @@ u32 GetSyscallOp(std::string_view moduleName, u32 nib) {
|
||||
}
|
||||
}
|
||||
|
||||
void WriteFuncStub(u32 stubAddr, u32 symAddr)
|
||||
{
|
||||
// It's assumed that stubAddr and symAddr are valid.
|
||||
void WriteFuncStub(u32 stubAddr, u32 symAddr) {
|
||||
_dbg_assert_(Memory::IsValid4AlignedAddress(stubAddr));
|
||||
_dbg_assert_(Memory::IsValid4AlignedAddress(symAddr));
|
||||
|
||||
// Note that this should be J not JAL, as otherwise control will return to the stub..
|
||||
Memory::Write_U32(MIPS_MAKE_J(symAddr), stubAddr);
|
||||
Memory::WriteUnchecked_U32(MIPS_MAKE_J(symAddr), stubAddr);
|
||||
// Note: doing that, we can't trace external module calls, so maybe something else should be done to debug more efficiently
|
||||
// Perhaps a syscall here (and verify support in jit), marking the module by uid (debugIdentifier)?
|
||||
Memory::Write_U32(MIPS_MAKE_NOP(), stubAddr + 4);
|
||||
Memory::WriteUnchecked_U32(MIPS_MAKE_NOP(), stubAddr + 4);
|
||||
}
|
||||
|
||||
void WriteFuncMissingStub(u32 stubAddr, u32 nid)
|
||||
{
|
||||
// It's assumed that stubAddr is valid.
|
||||
void WriteFuncMissingStub(u32 stubAddr, u32 nid) {
|
||||
_dbg_assert_(Memory::IsValid4AlignedAddress(stubAddr));
|
||||
// Write a trap so we notice this func if it's called before resolving.
|
||||
Memory::Write_U32(MIPS_MAKE_JR_RA(), stubAddr); // jr ra
|
||||
Memory::Write_U32(GetSyscallOp("", nid), stubAddr + 4);
|
||||
Memory::WriteUnchecked_U32(MIPS_MAKE_JR_RA(), stubAddr); // jr ra
|
||||
Memory::WriteUnchecked_U32(GetSyscallOp("", nid), stubAddr + 4);
|
||||
}
|
||||
|
||||
bool WriteHLESyscall(std::string_view moduleName, u32 nib, u32 address)
|
||||
{
|
||||
// It's assumed that address is valid.
|
||||
bool WriteHLESyscall(std::string_view moduleName, u32 nib, u32 address) {
|
||||
_dbg_assert_(Memory::IsValid4AlignedAddress(address));
|
||||
if (nib == 0)
|
||||
{
|
||||
WARN_LOG_REPORT(Log::HLE, "Wrote patched out nid=0 syscall (%.*s)", (int)moduleName.size(), moduleName.data());
|
||||
Memory::Write_U32(MIPS_MAKE_JR_RA(), address); //patched out?
|
||||
Memory::Write_U32(MIPS_MAKE_NOP(), address+4); //patched out?
|
||||
Memory::WriteUnchecked_U32(MIPS_MAKE_JR_RA(), address); //patched out?
|
||||
Memory::WriteUnchecked_U32(MIPS_MAKE_NOP(), address+4); //patched out?
|
||||
return true;
|
||||
}
|
||||
int modindex = GetHLEModuleIndex(moduleName);
|
||||
if (modindex != -1)
|
||||
{
|
||||
Memory::Write_U32(MIPS_MAKE_JR_RA(), address); // jr ra
|
||||
Memory::Write_U32(GetSyscallOp(moduleName, nib), address + 4);
|
||||
Memory::WriteUnchecked_U32(MIPS_MAKE_JR_RA(), address); // jr ra
|
||||
Memory::WriteUnchecked_U32(GetSyscallOp(moduleName, nib), address + 4);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
@@ -640,7 +645,7 @@ void hleFlushCalls() {
|
||||
}
|
||||
stackData->argc = (int)info.args.size();
|
||||
for (int j = 0; j < (int)info.args.size(); ++j) {
|
||||
Memory::Write_U32(info.args[j], sp + sizeof(HLEMipsCallStack) + j * sizeof(u32));
|
||||
Memory::WriteUnchecked_U32(info.args[j], sp + sizeof(HLEMipsCallStack) + j * sizeof(u32));
|
||||
}
|
||||
}
|
||||
enqueuedMipsCalls.clear();
|
||||
|
||||
@@ -26,18 +26,18 @@
|
||||
#include "Core/HLE/sceKernelMemory.h"
|
||||
#include "Core/MIPS/MIPSCodeUtils.h"
|
||||
|
||||
HLEHelperThread::HLEHelperThread() : id_(0), entry_(0) {
|
||||
}
|
||||
HLEHelperThread::HLEHelperThread() : id_(0), entry_(0) {}
|
||||
|
||||
HLEHelperThread::HLEHelperThread(const char *threadName, const u32 instructions[], u32 instrCount, u32 prio, int stacksize) {
|
||||
u32 instrBytes = instrCount * sizeof(u32);
|
||||
u32 totalBytes = instrBytes + sizeof(u32) * 2;
|
||||
AllocEntry(totalBytes);
|
||||
_dbg_assert_(Memory::IsValid4AlignedAddress(entry_)); // after AllocEntry.
|
||||
Memory::Memcpy(entry_, instructions, instrBytes, "HelperMIPS");
|
||||
|
||||
// Just to simplify things, we add the return here.
|
||||
Memory::Write_U32(MIPS_MAKE_JR_RA(), entry_ + instrBytes + 0);
|
||||
Memory::Write_U32(MIPS_MAKE_NOP(), entry_ + instrBytes + 4);
|
||||
Memory::WriteUnchecked_U32(MIPS_MAKE_JR_RA(), entry_ + instrBytes + 0);
|
||||
Memory::WriteUnchecked_U32(MIPS_MAKE_NOP(), entry_ + instrBytes + 4);
|
||||
|
||||
Create(threadName, prio, stacksize);
|
||||
}
|
||||
@@ -45,8 +45,9 @@ HLEHelperThread::HLEHelperThread(const char *threadName, const u32 instructions[
|
||||
HLEHelperThread::HLEHelperThread(const char *threadName, const char *module, const char *func, u32 prio, int stacksize) {
|
||||
const u32 bytes = sizeof(u32) * 2;
|
||||
AllocEntry(bytes);
|
||||
Memory::Write_U32(MIPS_MAKE_JR_RA(), entry_ + 0);
|
||||
Memory::Write_U32(MIPS_MAKE_SYSCALL(module, func), entry_ + 4);
|
||||
_dbg_assert_(Memory::IsValid4AlignedAddress(entry_)); // after AllocEntry.
|
||||
Memory::WriteUnchecked_U32(MIPS_MAKE_JR_RA(), entry_ + 0);
|
||||
Memory::WriteUnchecked_U32(MIPS_MAKE_SYSCALL(module, func), entry_ + 4);
|
||||
|
||||
Create(threadName, prio, stacksize);
|
||||
}
|
||||
@@ -60,6 +61,7 @@ HLEHelperThread::~HLEHelperThread() {
|
||||
|
||||
void HLEHelperThread::AllocEntry(u32 size) {
|
||||
entry_ = kernelMemory.Alloc(size, false, "HLEHelper");
|
||||
_dbg_assert_(Memory::IsValid4AlignedAddress(entry_)); // after AllocEntry.
|
||||
Memory::Memset(entry_, 0, size, "HLEHelperClear");
|
||||
currentMIPS->InvalidateICache(entry_, size);
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ inline void WaitExecTimeout(SceUID threadID) {
|
||||
if (ko)
|
||||
{
|
||||
if (timeoutPtr != 0)
|
||||
Memory::Write_U32(0, timeoutPtr);
|
||||
Memory::WriteOrException_U32(0, timeoutPtr);
|
||||
|
||||
// This thread isn't waiting anymore, but we'll remove it from waitingThreads later.
|
||||
// The reason is, if it times out, but what it was waiting on is DELETED prior to it
|
||||
@@ -196,7 +196,7 @@ WaitBeginEndCallbackResult WaitEndCallback(SceUID threadID, SceUID prevCallbackI
|
||||
// TODO: Since it was deleted, we don't know how long was actually left.
|
||||
// For now, we just say the full time was taken.
|
||||
if (timeoutPtr != 0 && waitTimer != -1) {
|
||||
Memory::Write_U32(0, timeoutPtr);
|
||||
Memory::WriteOrException_U32(0, timeoutPtr);
|
||||
}
|
||||
|
||||
__KernelResumeThreadFromWait(threadID, SCE_KERNEL_ERROR_WAIT_DELETE);
|
||||
@@ -217,7 +217,7 @@ WaitBeginEndCallbackResult WaitEndCallback(SceUID threadID, SceUID prevCallbackI
|
||||
s64 cyclesLeft = waitDeadline - CoreTiming::GetTicks();
|
||||
if (cyclesLeft < 0 && waitDeadline != 0) {
|
||||
if (timeoutPtr != 0 && waitTimer != -1) {
|
||||
Memory::Write_U32(0, timeoutPtr);
|
||||
Memory::WriteOrException_U32(0, timeoutPtr);
|
||||
}
|
||||
|
||||
__KernelResumeThreadFromWait(threadID, SCE_KERNEL_ERROR_WAIT_TIMEOUT);
|
||||
@@ -247,7 +247,7 @@ WaitBeginEndCallbackResult WaitEndCallback(SceUID threadID, SceUID prevCallbackI
|
||||
// TODO: Since it was deleted, we don't know how long was actually left.
|
||||
// For now, we just say the full time was taken.
|
||||
if (timeoutPtr != 0 && waitTimer != -1) {
|
||||
Memory::Write_U32(0, timeoutPtr);
|
||||
Memory::WriteOrException_U32(0, timeoutPtr);
|
||||
}
|
||||
|
||||
__KernelResumeThreadFromWait(threadID, SCE_KERNEL_ERROR_WAIT_DELETE);
|
||||
|
||||
+18
-13
@@ -1501,12 +1501,13 @@ static int Hook_starocean_clear_framebuf_after() {
|
||||
u32 y_address, h_address;
|
||||
|
||||
if (GetMIPSGPAddress(y_address, -204) && GetMIPSGPAddress(h_address, -200)) {
|
||||
int y = (s16)Memory::Read_U16(y_address);
|
||||
int h = (s16)Memory::Read_U16(h_address);
|
||||
|
||||
DEBUG_LOG(Log::HLE, "starocean_clear_framebuf() - %08x y=%d-%d", framebuf, y, h);
|
||||
// TODO: This is always clearing to 0, actually, which could be faster than an upload.
|
||||
gpu->PerformWriteColorFromMemory(framebuf + 512 * y * 4, 512 * h * 4);
|
||||
if (Memory::IsValid2AlignedAddress(y_address) && Memory::IsValid2AlignedAddress(h_address)) {
|
||||
int y = (s16)Memory::ReadUnchecked_U16(y_address);
|
||||
int h = (s16)Memory::ReadUnchecked_U16(h_address);
|
||||
DEBUG_LOG(Log::HLE, "starocean_clear_framebuf() - %08x y=%d-%d", framebuf, y, h);
|
||||
// TODO: This is always clearing to 0, actually, which could be faster than an upload.
|
||||
gpu->PerformWriteColorFromMemory(framebuf + 512 * y * 4, 512 * h * 4);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -1515,9 +1516,9 @@ static int Hook_motorstorm_pixel_read() {
|
||||
if (!Memory::IsValidRange(currentMIPS->r[MIPS_REG_A0] + 0x18, 0x20)) {
|
||||
return 0;
|
||||
}
|
||||
u32 fb_address = Memory::ReadUnchecked_U32(currentMIPS->r[MIPS_REG_A0] + 0x18);
|
||||
u32 fb_height = Memory::ReadUnchecked_U16(currentMIPS->r[MIPS_REG_A0] + 0x26);
|
||||
u32 fb_stride = Memory::ReadUnchecked_U16(currentMIPS->r[MIPS_REG_A0] + 0x28);
|
||||
const u32 fb_address = Memory::ReadUnchecked_U32(currentMIPS->r[MIPS_REG_A0] + 0x18);
|
||||
const u32 fb_height = Memory::ReadUnchecked_U16(currentMIPS->r[MIPS_REG_A0] + 0x26);
|
||||
const u32 fb_stride = Memory::ReadUnchecked_U16(currentMIPS->r[MIPS_REG_A0] + 0x28);
|
||||
gpu->PerformReadbackToMemory(fb_address, fb_height * fb_stride);
|
||||
NotifyMemInfo(MemBlockFlags::WRITE, fb_address, fb_height * fb_stride, "motorstorm_pixel_read");
|
||||
return 0;
|
||||
@@ -1525,8 +1526,8 @@ static int Hook_motorstorm_pixel_read() {
|
||||
|
||||
static int Hook_worms_copy_normalize_alpha() {
|
||||
// At this point in the function (0x0CC), s1 is the framebuf and a2 is the size.
|
||||
u32 fb_address = currentMIPS->r[MIPS_REG_S1];
|
||||
u32 fb_size = currentMIPS->r[MIPS_REG_A2];
|
||||
const u32 fb_address = currentMIPS->r[MIPS_REG_S1];
|
||||
const u32 fb_size = currentMIPS->r[MIPS_REG_A2];
|
||||
if (Memory::IsVRAMAddress(fb_address) && Memory::IsValidRange(fb_address, fb_size)) {
|
||||
gpu->PerformReadbackToMemory(fb_address, fb_size);
|
||||
NotifyMemInfo(MemBlockFlags::WRITE, fb_address, fb_size, "worms_copy_normalize_alpha");
|
||||
@@ -1881,7 +1882,7 @@ std::map<u32, u32> SaveAndClearReplacements() {
|
||||
const u32 curInstr = Memory::Read_Opcode_JIT(addr).encoding;
|
||||
if (MIPS_IS_REPLACEMENT(curInstr)) {
|
||||
saved[addr] = curInstr;
|
||||
Memory::Write_U32(instr, addr);
|
||||
Memory::WriteUnchecked_U32(instr, addr);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1892,7 +1893,11 @@ std::map<u32, u32> SaveAndClearReplacements() {
|
||||
void RestoreSavedReplacements(const std::map<u32, u32> &saved) {
|
||||
for (const auto &[addr, instr] : saved) {
|
||||
// Just put the replacements back.
|
||||
Memory::Write_U32(instr, addr);
|
||||
if (Memory::IsValid4AlignedAddress(addr)) {
|
||||
Memory::WriteUnchecked_U32(instr, addr);
|
||||
} else {
|
||||
ERROR_LOG(Log::HLE, "RestoreSavedReplacements: Invalid address %08x", addr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -482,15 +482,15 @@ static int sceCtrlSetIdleCancelThreshold(int idleReset, int idleBack)
|
||||
|
||||
static int sceCtrlGetIdleCancelThreshold(u32 idleResetPtr, u32 idleBackPtr)
|
||||
{
|
||||
if (idleResetPtr && !Memory::IsValidAddress(idleResetPtr))
|
||||
if (idleResetPtr && !Memory::IsValid4AlignedAddress(idleResetPtr))
|
||||
return hleLogError(Log::sceCtrl, SCE_KERNEL_ERROR_PRIV_REQUIRED);
|
||||
if (idleBackPtr && !Memory::IsValidAddress(idleBackPtr))
|
||||
if (idleBackPtr && !Memory::IsValid4AlignedAddress(idleBackPtr))
|
||||
return hleLogError(Log::sceCtrl, SCE_KERNEL_ERROR_PRIV_REQUIRED);
|
||||
|
||||
if (idleResetPtr)
|
||||
Memory::Write_U32(ctrlIdleReset, idleResetPtr);
|
||||
Memory::WriteUnchecked_U32(ctrlIdleReset, idleResetPtr);
|
||||
if (idleBackPtr)
|
||||
Memory::Write_U32(ctrlIdleBack, idleBackPtr);
|
||||
Memory::WriteUnchecked_U32(ctrlIdleBack, idleBackPtr);
|
||||
|
||||
return hleLogDebug(Log::sceCtrl, 0);
|
||||
}
|
||||
|
||||
+18
-18
@@ -955,12 +955,12 @@ bool __DisplayGetFramebuf(PSPPointer<u8> *topaddr, u32 *linesize, u32 *pixelForm
|
||||
static u32 sceDisplayGetFramebuf(u32 topaddrPtr, u32 linesizePtr, u32 pixelFormatPtr, int latchedMode) {
|
||||
const FrameBufferState &fbState = latchedMode == PSP_DISPLAY_SETBUF_NEXTFRAME ? latchedFramebuf : framebuf;
|
||||
|
||||
if (Memory::IsValidAddress(topaddrPtr))
|
||||
Memory::Write_U32(fbState.topaddr, topaddrPtr);
|
||||
if (Memory::IsValidAddress(linesizePtr))
|
||||
Memory::Write_U32(fbState.stride, linesizePtr);
|
||||
if (Memory::IsValidAddress(pixelFormatPtr))
|
||||
Memory::Write_U32(fbState.fmt, pixelFormatPtr);
|
||||
if (Memory::IsValid4AlignedAddress(topaddrPtr))
|
||||
Memory::WriteUnchecked_U32(fbState.topaddr, topaddrPtr);
|
||||
if (Memory::IsValid4AlignedAddress(linesizePtr))
|
||||
Memory::WriteUnchecked_U32(fbState.stride, linesizePtr);
|
||||
if (Memory::IsValid4AlignedAddress(pixelFormatPtr))
|
||||
Memory::WriteUnchecked_U32(fbState.fmt, pixelFormatPtr);
|
||||
|
||||
return hleLogDebug(Log::sceDisplay, 0);
|
||||
}
|
||||
@@ -1068,12 +1068,12 @@ static u32 sceDisplayIsForeground() {
|
||||
}
|
||||
|
||||
static u32 sceDisplayGetMode(u32 modeAddr, u32 widthAddr, u32 heightAddr) {
|
||||
if (Memory::IsValidAddress(modeAddr))
|
||||
Memory::Write_U32(mode, modeAddr);
|
||||
if (Memory::IsValidAddress(widthAddr))
|
||||
Memory::Write_U32(width, widthAddr);
|
||||
if (Memory::IsValidAddress(heightAddr))
|
||||
Memory::Write_U32(height, heightAddr);
|
||||
if (Memory::IsValid4AlignedAddress(modeAddr))
|
||||
Memory::WriteUnchecked_U32(mode, modeAddr);
|
||||
if (Memory::IsValid4AlignedAddress(widthAddr))
|
||||
Memory::WriteUnchecked_U32(width, widthAddr);
|
||||
if (Memory::IsValid4AlignedAddress(heightAddr))
|
||||
Memory::WriteUnchecked_U32(height, heightAddr);
|
||||
return hleLogDebug(Log::sceDisplay, 0);
|
||||
}
|
||||
|
||||
@@ -1086,8 +1086,8 @@ static u32 sceDisplayIsVsync() {
|
||||
}
|
||||
|
||||
static u32 sceDisplayGetResumeMode(u32 resumeModeAddr) {
|
||||
if (Memory::IsValidAddress(resumeModeAddr))
|
||||
Memory::Write_U32(resumeMode, resumeModeAddr);
|
||||
if (Memory::IsValid4AlignedAddress(resumeModeAddr))
|
||||
Memory::WriteUnchecked_U32(resumeMode, resumeModeAddr);
|
||||
return hleLogDebug(Log::sceDisplay, 0);
|
||||
}
|
||||
|
||||
@@ -1100,12 +1100,12 @@ static u32 sceDisplaySetResumeMode(u32 rMode) {
|
||||
static u32 sceDisplayGetBrightness(u32 levelAddr, u32 otherAddr) {
|
||||
// Standard levels on a PSP: 44, 60, 72, 84 (AC only)
|
||||
|
||||
if (Memory::IsValidAddress(levelAddr)) {
|
||||
Memory::Write_U32(brightnessLevel, levelAddr);
|
||||
if (Memory::IsValid4AlignedAddress(levelAddr)) {
|
||||
Memory::WriteUnchecked_U32(brightnessLevel, levelAddr);
|
||||
}
|
||||
// Always seems to write zero?
|
||||
if (Memory::IsValidAddress(otherAddr)) {
|
||||
Memory::Write_U32(0, otherAddr);
|
||||
if (Memory::IsValid4AlignedAddress(otherAddr)) {
|
||||
Memory::WriteUnchecked_U32(0, otherAddr);
|
||||
}
|
||||
return hleLogWarning(Log::sceDisplay, 0);
|
||||
}
|
||||
|
||||
@@ -785,7 +785,7 @@ void PostAllocCallback::run(MipsCall &call) {
|
||||
if (v0 == 0) {
|
||||
// TODO: Who deletes fontLib?
|
||||
if (errorCodePtr_)
|
||||
Memory::Write_U32(SCE_FONT_ERROR_OUT_OF_MEMORY, errorCodePtr_);
|
||||
Memory::WriteOrException_U32(SCE_FONT_ERROR_OUT_OF_MEMORY, errorCodePtr_);
|
||||
call.setReturnValue(0);
|
||||
} else {
|
||||
_dbg_assert_(fontLibID_ >= 0);
|
||||
|
||||
@@ -22,7 +22,7 @@
|
||||
#include "Core/MIPS/MIPS.h"
|
||||
|
||||
static u32 sceHprmPeekCurrentKey(u32 keyAddress) {
|
||||
Memory::Write_U32(0, keyAddress);
|
||||
Memory::WriteOrException_U32(0, keyAddress);
|
||||
return hleLogDebug(Log::HLE, 0);
|
||||
}
|
||||
|
||||
|
||||
@@ -389,9 +389,9 @@ static int JpegGetOutputInfo(u32 jpegAddr, int jpegSize, u32 colourInfoAddr) {
|
||||
// - Bits 16 to 24 (Color mode): 0x00 (Unknown), 0x01 (Greyscale) or 0x02 (YCbCr)
|
||||
// - Bits 8 to 16 (Vertical chroma subsampling value): 0x00, 0x01 or 0x02
|
||||
// - Bits 0 to 8 (Horizontal chroma subsampling value): 0x00, 0x01 or 0x02
|
||||
if (Memory::IsValidAddress(colourInfoAddr)) {
|
||||
if (Memory::IsValid4AlignedAddress(colourInfoAddr)) {
|
||||
// Note: can't actually seem to get any other subsampling values or color modes to work on a PSP.
|
||||
Memory::Write_U32(0x00020202, colourInfoAddr);
|
||||
Memory::WriteUnchecked_U32(0x00020202, colourInfoAddr);
|
||||
NotifyMemInfo(MemBlockFlags::WRITE, colourInfoAddr, 4, "JpegGetOutputInfo");
|
||||
}
|
||||
|
||||
|
||||
@@ -144,8 +144,8 @@ static bool __KernelCheckEventFlagMatches(u32 pattern, u32 bits, u8 wait) {
|
||||
|
||||
static bool __KernelApplyEventFlagMatch(u32_le *pattern, u32 bits, u8 wait, u32 outAddr) {
|
||||
if (__KernelCheckEventFlagMatches(*pattern, bits, wait)) {
|
||||
if (Memory::IsValidAddress(outAddr))
|
||||
Memory::Write_U32(*pattern, outAddr);
|
||||
if (Memory::IsValid4AlignedAddress(outAddr))
|
||||
Memory::WriteUnchecked_U32(*pattern, outAddr);
|
||||
|
||||
if (wait & PSP_EVENT_WAITCLEAR)
|
||||
*pattern &= ~bits;
|
||||
@@ -167,14 +167,14 @@ static bool __KernelUnlockEventFlagForThread(EventFlag *e, EventFlagTh &th, u32
|
||||
} else {
|
||||
// Otherwise, we set the current result since we're bailing.
|
||||
if (Memory::IsValidAddress(th.outAddr))
|
||||
Memory::Write_U32(e->nef.currentPattern, th.outAddr);
|
||||
Memory::WriteOrException_U32(e->nef.currentPattern, th.outAddr);
|
||||
}
|
||||
|
||||
u32 timeoutPtr = __KernelGetWaitTimeoutPtr(th.threadID, error);
|
||||
if (timeoutPtr != 0 && eventFlagWaitTimer != -1) {
|
||||
// Remove any event for this thread.
|
||||
s64 cyclesLeft = CoreTiming::UnscheduleEvent(eventFlagWaitTimer, th.threadID);
|
||||
Memory::Write_U32((u32) cyclesToUs(cyclesLeft), timeoutPtr);
|
||||
Memory::WriteOrException_U32((u32) cyclesToUs(cyclesLeft), timeoutPtr);
|
||||
}
|
||||
|
||||
__KernelResumeThreadFromWait(th.threadID, result);
|
||||
@@ -327,7 +327,7 @@ void __KernelEventFlagTimeout(u64 userdata, int cycleslate) {
|
||||
EventFlag *e = kernelObjects.Get<EventFlag>(flagID, error);
|
||||
if (e) {
|
||||
if (timeoutPtr != 0)
|
||||
Memory::Write_U32(0, timeoutPtr);
|
||||
Memory::WriteOrException_U32(0, timeoutPtr);
|
||||
|
||||
for (size_t i = 0; i < e->waitingThreads.size(); i++) {
|
||||
EventFlagTh *t = &e->waitingThreads[i];
|
||||
@@ -349,7 +349,7 @@ static void __KernelSetEventFlagTimeout(EventFlag *e, u32 timeoutPtr) {
|
||||
if (timeoutPtr == 0 || eventFlagWaitTimer == -1)
|
||||
return;
|
||||
|
||||
int micro = (int) Memory::Read_U32(timeoutPtr);
|
||||
int micro = (int) Memory::ReadOrException_U32(timeoutPtr);
|
||||
|
||||
// This seems like the actual timing of timeouts on hardware.
|
||||
if (micro <= 1)
|
||||
@@ -385,7 +385,7 @@ int sceKernelWaitEventFlag(SceUID id, u32 bits, u32 wait, u32 outBitsPtr, u32 ti
|
||||
|
||||
u32 timeout = 0xFFFFFFFF;
|
||||
if (Memory::IsValidAddress(timeoutPtr))
|
||||
timeout = Memory::Read_U32(timeoutPtr);
|
||||
timeout = Memory::ReadOrException_U32(timeoutPtr);
|
||||
|
||||
// Do we allow more than one thread to wait?
|
||||
if (e->waitingThreads.size() > 0 && (e->nef.attr & PSP_EVENT_WAITMULTIPLE) == 0) {
|
||||
@@ -448,7 +448,7 @@ int sceKernelWaitEventFlagCB(SceUID id, u32 bits, u32 wait, u32 outBitsPtr, u32
|
||||
|
||||
u32 timeout = 0xFFFFFFFF;
|
||||
if (Memory::IsValidAddress(timeoutPtr))
|
||||
timeout = Memory::Read_U32(timeoutPtr);
|
||||
timeout = Memory::ReadOrException_U32(timeoutPtr);
|
||||
|
||||
// Do we allow more than one thread to wait?
|
||||
if (e->waitingThreads.size() > 0 && (e->nef.attr & PSP_EVENT_WAITMULTIPLE) == 0) {
|
||||
@@ -502,8 +502,9 @@ int sceKernelPollEventFlag(SceUID id, u32 bits, u32 wait, u32 outBitsPtr) {
|
||||
EventFlag *e = kernelObjects.Get<EventFlag>(id, error);
|
||||
if (e) {
|
||||
if (!__KernelApplyEventFlagMatch(&e->nef.currentPattern, bits, wait, outBitsPtr)) {
|
||||
if (Memory::IsValidAddress(outBitsPtr))
|
||||
Memory::Write_U32(e->nef.currentPattern, outBitsPtr);
|
||||
if (Memory::IsValid4AlignedAddress(outBitsPtr)) {
|
||||
Memory::WriteUnchecked_U32(e->nef.currentPattern, outBitsPtr);
|
||||
}
|
||||
|
||||
if (e->waitingThreads.size() > 0 && (e->nef.attr & PSP_EVENT_WAITMULTIPLE) == 0) {
|
||||
return hleLogDebug(Log::sceKernel, SCE_KERNEL_ERROR_EVF_MULTI);
|
||||
|
||||
@@ -207,7 +207,7 @@ static bool __KernelUnlockMbxForThread(Mbx *m, MbxWaitingThread &th, u32 &error,
|
||||
{
|
||||
// Remove any event for this thread.
|
||||
s64 cyclesLeft = CoreTiming::UnscheduleEvent(mbxWaitTimer, th.threadID);
|
||||
Memory::Write_U32((u32) cyclesToUs(cyclesLeft), timeoutPtr);
|
||||
Memory::WriteOrException_U32((u32) cyclesToUs(cyclesLeft), timeoutPtr);
|
||||
}
|
||||
|
||||
__KernelResumeThreadFromWait(th.threadID, result);
|
||||
@@ -254,7 +254,7 @@ static void __KernelWaitMbx(Mbx *m, u32 timeoutPtr)
|
||||
if (timeoutPtr == 0 || mbxWaitTimer == -1)
|
||||
return;
|
||||
|
||||
int micro = (int) Memory::Read_U32(timeoutPtr);
|
||||
int micro = (int) Memory::ReadOrException_U32(timeoutPtr);
|
||||
|
||||
// This seems to match the actual timing.
|
||||
if (micro <= 2)
|
||||
@@ -379,7 +379,7 @@ int sceKernelSendMbx(SceUID id, u32 packetAddr)
|
||||
m->waitingThreads.erase(iter);
|
||||
|
||||
if (wokeThreads) {
|
||||
Memory::Write_U32(packetAddr, t.packetAddr);
|
||||
Memory::WriteOrException_U32(packetAddr, t.packetAddr);
|
||||
hleReSchedule("mbx sent");
|
||||
|
||||
// We don't need to do anything else, finish here.
|
||||
@@ -521,7 +521,7 @@ int sceKernelCancelReceiveMbx(SceUID id, u32 numWaitingThreadsAddr) {
|
||||
hleReSchedule("mbx canceled");
|
||||
|
||||
if (numWaitingThreadsAddr)
|
||||
Memory::Write_U32(count, numWaitingThreadsAddr);
|
||||
Memory::WriteOrException_U32(count, numWaitingThreadsAddr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -457,7 +457,7 @@ static bool __KernelUnlockFplForThread(FPL *fpl, FplWaitingThread &threadInfo, u
|
||||
int blockNum = fpl->AllocateBlock();
|
||||
if (blockNum >= 0) {
|
||||
u32 blockPtr = fpl->address + fpl->alignedSize * blockNum;
|
||||
Memory::Write_U32(blockPtr, threadInfo.addrPtr);
|
||||
Memory::WriteOrException_U32(blockPtr, threadInfo.addrPtr);
|
||||
NotifyMemInfo(MemBlockFlags::SUB_ALLOC, blockPtr, fpl->alignedSize, "FplAllocate");
|
||||
} else {
|
||||
return false;
|
||||
@@ -468,7 +468,7 @@ static bool __KernelUnlockFplForThread(FPL *fpl, FplWaitingThread &threadInfo, u
|
||||
if (timeoutPtr != 0 && fplWaitTimer != -1) {
|
||||
// Remove any event for this thread.
|
||||
s64 cyclesLeft = CoreTiming::UnscheduleEvent(fplWaitTimer, threadID);
|
||||
Memory::Write_U32((u32) cyclesToUs(cyclesLeft), timeoutPtr);
|
||||
Memory::WriteOrException_U32((u32) cyclesToUs(cyclesLeft), timeoutPtr);
|
||||
}
|
||||
|
||||
__KernelResumeThreadFromWait(threadID, result);
|
||||
@@ -543,10 +543,10 @@ int sceKernelCreateFpl(const char *name, u32 mpid, u32 attr, u32 blockSize, u32
|
||||
return hleReportWarning(Log::sceKernel, SCE_KERNEL_ERROR_ILLEGAL_MEMSIZE, "invalid blockSize/count");
|
||||
|
||||
int alignment = 4;
|
||||
if (Memory::IsValidRange(optPtr, 4)) {
|
||||
if (Memory::IsValidRange(optPtr, 8)) {
|
||||
u32 size = Memory::ReadUnchecked_U32(optPtr);
|
||||
if (size >= 4)
|
||||
alignment = Memory::Read_U32(optPtr + 4);
|
||||
alignment = Memory::ReadUnchecked_U32(optPtr + 4);
|
||||
// Must be a power of 2 to be valid.
|
||||
if ((alignment & (alignment - 1)) != 0)
|
||||
return hleLogWarning(Log::sceKernel, SCE_KERNEL_ERROR_ILLEGAL_ARGUMENT, "invalid alignment %d", alignment);
|
||||
@@ -614,7 +614,7 @@ static void __KernelSetFplTimeout(u32 timeoutPtr)
|
||||
if (timeoutPtr == 0 || fplWaitTimer == -1)
|
||||
return;
|
||||
|
||||
int micro = (int) Memory::Read_U32(timeoutPtr);
|
||||
int micro = (int) Memory::ReadOrException_U32(timeoutPtr);
|
||||
|
||||
// TODO: test for fpls.
|
||||
// This happens to be how the hardware seems to time things.
|
||||
@@ -697,7 +697,7 @@ int sceKernelTryAllocateFpl(SceUID uid, u32 blockPtrAddr) {
|
||||
int blockNum = fpl->AllocateBlock();
|
||||
if (blockNum >= 0) {
|
||||
u32 blockPtr = fpl->address + fpl->alignedSize * blockNum;
|
||||
Memory::Write_U32(blockPtr, blockPtrAddr);
|
||||
Memory::WriteOrException_U32(blockPtr, blockPtrAddr);
|
||||
NotifyMemInfo(MemBlockFlags::SUB_ALLOC, blockPtr, fpl->alignedSize, "FplAllocate");
|
||||
return hleLogDebug(Log::sceKernel, 0);
|
||||
} else {
|
||||
@@ -757,8 +757,9 @@ int sceKernelCancelFpl(SceUID uid, u32 numWaitThreadsPtr) {
|
||||
}
|
||||
|
||||
fpl->nf.numWaitThreads = (int) fpl->waitingThreads.size();
|
||||
if (Memory::IsValidAddress(numWaitThreadsPtr))
|
||||
Memory::Write_U32(fpl->nf.numWaitThreads, numWaitThreadsPtr);
|
||||
if (Memory::IsValid4AlignedAddress(numWaitThreadsPtr)) {
|
||||
Memory::WriteUnchecked_U32(fpl->nf.numWaitThreads, numWaitThreadsPtr);
|
||||
}
|
||||
bool wokeThreads = __KernelClearFplThreads(fpl, SCE_KERNEL_ERROR_WAIT_CANCEL);
|
||||
if (wokeThreads)
|
||||
hleReSchedule("fpl canceled");
|
||||
@@ -1247,7 +1248,7 @@ static bool __KernelUnlockVplForThread(VPL *vpl, VplWaitingThread &threadInfo, u
|
||||
addr = vpl->alloc.Alloc(allocSize, true);
|
||||
}
|
||||
if (addr != (u32) -1) {
|
||||
Memory::Write_U32(addr, threadInfo.addrPtr);
|
||||
Memory::WriteOrException_U32(addr, threadInfo.addrPtr);
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
@@ -1257,7 +1258,7 @@ static bool __KernelUnlockVplForThread(VPL *vpl, VplWaitingThread &threadInfo, u
|
||||
if (timeoutPtr != 0 && vplWaitTimer != -1) {
|
||||
// Remove any event for this thread.
|
||||
s64 cyclesLeft = CoreTiming::UnscheduleEvent(vplWaitTimer, threadID);
|
||||
Memory::Write_U32((u32) cyclesToUs(cyclesLeft), timeoutPtr);
|
||||
Memory::WriteOrException_U32((u32) cyclesToUs(cyclesLeft), timeoutPtr);
|
||||
}
|
||||
|
||||
__KernelResumeThreadFromWait(threadID, result);
|
||||
@@ -1428,7 +1429,7 @@ static bool __KernelAllocateVpl(SceUID uid, u32 size, u32 addrPtr, u32 &error, b
|
||||
addr = vpl->alloc.Alloc(allocSize, true, "VplAllocate");
|
||||
}
|
||||
if (addr != (u32) -1) {
|
||||
Memory::Write_U32(addr, addrPtr);
|
||||
Memory::WriteOrException_U32(addr, addrPtr);
|
||||
error = 0;
|
||||
} else {
|
||||
error = SCE_KERNEL_ERROR_NO_MEMORY;
|
||||
@@ -1465,7 +1466,7 @@ static void __KernelSetVplTimeout(u32 timeoutPtr)
|
||||
if (timeoutPtr == 0 || vplWaitTimer == -1)
|
||||
return;
|
||||
|
||||
int micro = (int) Memory::Read_U32(timeoutPtr);
|
||||
int micro = (int) Memory::ReadOrException_U32(timeoutPtr);
|
||||
|
||||
// This happens to be how the hardware seems to time things.
|
||||
if (micro <= 5)
|
||||
@@ -1487,7 +1488,7 @@ int sceKernelAllocateVpl(SceUID uid, u32 size, u32 addrPtr, u32 timeoutPtr)
|
||||
VPL *vpl = kernelObjects.Get<VPL>(uid, ignore);
|
||||
if (error == SCE_KERNEL_ERROR_NO_MEMORY)
|
||||
{
|
||||
if (timeoutPtr != 0 && Memory::Read_U32(timeoutPtr) == 0)
|
||||
if (timeoutPtr != 0 && Memory::ReadOrException_U32(timeoutPtr) == 0)
|
||||
return hleLogError(Log::sceKernel, SCE_KERNEL_ERROR_WAIT_TIMEOUT);
|
||||
|
||||
if (vpl) {
|
||||
@@ -1517,7 +1518,7 @@ int sceKernelAllocateVplCB(SceUID uid, u32 size, u32 addrPtr, u32 timeoutPtr)
|
||||
VPL *vpl = kernelObjects.Get<VPL>(uid, ignore);
|
||||
if (error == SCE_KERNEL_ERROR_NO_MEMORY)
|
||||
{
|
||||
if (timeoutPtr != 0 && Memory::Read_U32(timeoutPtr) == 0)
|
||||
if (timeoutPtr != 0 && Memory::ReadOrException_U32(timeoutPtr) == 0)
|
||||
return hleLogError(Log::sceKernel, SCE_KERNEL_ERROR_WAIT_TIMEOUT);
|
||||
|
||||
if (vpl)
|
||||
@@ -1669,7 +1670,7 @@ static u32 sceKernelGetMemoryBlockAddr(u32 uid, u32 addr) {
|
||||
u32 error;
|
||||
PartitionMemoryBlock *block = kernelObjects.Get<PartitionMemoryBlock>(uid, error);
|
||||
if (block) {
|
||||
Memory::Write_U32(block->address, addr);
|
||||
Memory::WriteOrException_U32(block->address, addr);
|
||||
return hleLogInfo(Log::sceKernel, 0, "block address: %08x", block->address);
|
||||
} else {
|
||||
return hleLogError(Log::sceKernel, 0, "failed");
|
||||
|
||||
@@ -395,7 +395,7 @@ public:
|
||||
};
|
||||
|
||||
void AfterModuleEntryCall::run(MipsCall &call) {
|
||||
Memory::Write_U32(retValAddr, currentMIPS->r[MIPS_REG_V0]);
|
||||
Memory::WriteOrException_U32(retValAddr, currentMIPS->r[MIPS_REG_V0]);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////
|
||||
@@ -571,7 +571,7 @@ static void WriteVarSymbol(WriteVarSymbolState &state, u32 exportAddress, u32 re
|
||||
// The low instruction will be a signed add, which means (full & 0x8000) will subtract.
|
||||
// We add 1 in that case so that it ends up the right value.
|
||||
u16 high = (full >> 16) + ((full & 0x8000) ? 1 : 0);
|
||||
Memory::Write_U32((reloc.data & ~0xFFFF) | high, reloc.addr);
|
||||
Memory::WriteUnchecked_U32((reloc.data & ~0xFFFF) | high, reloc.addr);
|
||||
currentMIPS->InvalidateICache(reloc.addr, 4);
|
||||
}
|
||||
state.lastHI16Processed = true;
|
||||
@@ -586,7 +586,7 @@ static void WriteVarSymbol(WriteVarSymbolState &state, u32 exportAddress, u32 re
|
||||
WARN_LOG_REPORT(Log::Loader, "Unsupported var relocation type %d - %08x => %08x", type, exportAddress, relocAddress);
|
||||
}
|
||||
|
||||
Memory::Write_U32(relocData, relocAddress);
|
||||
Memory::WriteUnchecked_U32(relocData, relocAddress);
|
||||
currentMIPS->InvalidateICache(relocAddress, 4);
|
||||
}
|
||||
|
||||
@@ -2138,7 +2138,7 @@ u32 sceKernelStartModule(u32 moduleId, u32 argsize, u32 argAddr, u32 returnValue
|
||||
return hleLogWarning(Log::sceModule, error, "error %08x", error);
|
||||
} else if (module->isFake) {
|
||||
if (returnValueAddr)
|
||||
Memory::Write_U32(0, returnValueAddr);
|
||||
Memory::WriteOrException_U32(0, returnValueAddr);
|
||||
return hleLogInfo(Log::sceModule, moduleId, "Faked module");
|
||||
} else if (module->nm.status == MODULE_STATUS_STARTED) {
|
||||
// TODO: Maybe should be SCE_KERNEL_ERROR_ALREADY_STARTED, but I get SCE_KERNEL_ERROR_ERROR.
|
||||
@@ -2176,7 +2176,7 @@ static u32 sceKernelStopModule(u32 moduleId, u32 argSize, u32 argAddr, u32 retur
|
||||
|
||||
if (module->isFake) {
|
||||
if (returnValueAddr)
|
||||
Memory::Write_U32(0, returnValueAddr);
|
||||
Memory::WriteOrException_U32(0, returnValueAddr);
|
||||
return hleLogInfo(Log::sceModule, 0, "faking");
|
||||
}
|
||||
if (module->nm.status != MODULE_STATUS_STARTED) {
|
||||
@@ -2192,8 +2192,7 @@ static u32 sceKernelStopModule(u32 moduleId, u32 argSize, u32 argAddr, u32 retur
|
||||
attr = module->nm.module_stop_thread_attr;
|
||||
|
||||
// TODO: Need to test how this really works. Let's assume it's an override.
|
||||
if (Memory::IsValidAddress(optionAddr))
|
||||
{
|
||||
if (Memory::IsValidRange(optionAddr, sizeof(SceKernelSMOption))) {
|
||||
auto options = PSPPointer<SceKernelSMOption>::Create(optionAddr);
|
||||
// TODO: Check how size handling actually works.
|
||||
if (options->size != 0 && options->priority != 0)
|
||||
@@ -2207,8 +2206,7 @@ static u32 sceKernelStopModule(u32 moduleId, u32 argSize, u32 argAddr, u32 retur
|
||||
WARN_LOG_REPORT(Log::sceModule, "Stopping module with attr=%x, but options specify 0", attr);
|
||||
}
|
||||
|
||||
if (Memory::IsValidAddress(stopFunc))
|
||||
{
|
||||
if (Memory::IsValid4AlignedAddress(stopFunc)) {
|
||||
SceUID threadID = __KernelCreateThread(module->nm.name, moduleId, stopFunc, priority, stacksize, attr, 0, (module->nm.attribute & 0x1000) != 0);
|
||||
_dbg_assert_(threadID > 0);
|
||||
// TOOD: Check the return value and bail?
|
||||
@@ -2219,14 +2217,10 @@ static u32 sceKernelStopModule(u32 moduleId, u32 argSize, u32 argAddr, u32 retur
|
||||
const ModuleWaitingThread mwt = {__KernelGetCurThread(), returnValueAddr};
|
||||
module->nm.status = MODULE_STATUS_STOPPING;
|
||||
module->waitingThreads.push_back(mwt);
|
||||
}
|
||||
else if (stopFunc == 0)
|
||||
{
|
||||
} else if (stopFunc == 0) {
|
||||
module->nm.status = MODULE_STATUS_STOPPED;
|
||||
return hleLogInfo(Log::sceModule, 0, "no stop func, skipping");
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
module->nm.status = MODULE_STATUS_STOPPED;
|
||||
return hleLogError(Log::sceModule, 0, "sceKernelStopModule(%08x, %08x, %08x, %08x, %08x): bad stop func address", moduleId, argSize, argAddr, returnValueAddr, optionAddr);
|
||||
}
|
||||
@@ -2378,7 +2372,7 @@ void __KernelReturnFromModuleFunc() {
|
||||
hleCall(ThreadManForKernel, int, sceKernelTerminateDeleteThread, it->threadID);
|
||||
} else {
|
||||
if (it->statusPtr != 0)
|
||||
Memory::Write_U32(exitStatus, it->statusPtr);
|
||||
Memory::WriteOrException_U32(exitStatus, it->statusPtr);
|
||||
__KernelResumeThreadFromWait(it->threadID, module->nm.status == MODULE_STATUS_STARTED ? leftModuleID : 0);
|
||||
}
|
||||
}
|
||||
@@ -2644,14 +2638,14 @@ static u32 sceKernelGetModuleIdList(u32 resultBuffer, u32 resultBufferSize, u32
|
||||
PSPModule *module = kernelObjects.Get<PSPModule>(moduleId, error);
|
||||
if (!module->isFake || liedAboutThisModule(module)) {
|
||||
if (resultBufferOffset < resultBufferSize) {
|
||||
Memory::Write_U32(module->GetUID(), resultBuffer + resultBufferOffset);
|
||||
Memory::WriteOrException_U32(module->GetUID(), resultBuffer + resultBufferOffset);
|
||||
resultBufferOffset += 4;
|
||||
}
|
||||
idCount++;
|
||||
} // Actually, should we return fake modules too? They wouldn't be fake on the real hardware. Not like any games use this function though.
|
||||
}
|
||||
|
||||
Memory::Write_U32(idCount, idCountAddr);
|
||||
Memory::WriteOrException_U32(idCount, idCountAddr);
|
||||
|
||||
return hleNoLog(0);
|
||||
}
|
||||
|
||||
@@ -85,7 +85,7 @@ struct MsgPipeWaitingThread
|
||||
{
|
||||
// Remove any event for this thread.
|
||||
s64 cyclesLeft = CoreTiming::UnscheduleEvent(waitTimer, threadID);
|
||||
Memory::Write_U32((u32) cyclesToUs(cyclesLeft), timeoutPtr);
|
||||
Memory::WriteOrException_U32((u32) cyclesToUs(cyclesLeft), timeoutPtr);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -369,8 +369,8 @@ static int __KernelSendMsgPipe(MsgPipe *m, u32 sendBufAddr, u32 sendSize, int wa
|
||||
if (poll)
|
||||
{
|
||||
// Generally, result is not updated in this case. But for a 0 size buffer in ASAP mode, it is.
|
||||
if (Memory::IsValidAddress(resultAddr) && waitMode == SCE_KERNEL_MPW_ASAP)
|
||||
Memory::Write_U32(curSendAddr - sendBufAddr, resultAddr);
|
||||
if (Memory::IsValid4AlignedAddress(resultAddr) && waitMode == SCE_KERNEL_MPW_ASAP)
|
||||
Memory::WriteUnchecked_U32(curSendAddr - sendBufAddr, resultAddr);
|
||||
return SCE_KERNEL_ERROR_MPP_FULL;
|
||||
}
|
||||
else
|
||||
@@ -424,8 +424,8 @@ static int __KernelSendMsgPipe(MsgPipe *m, u32 sendBufAddr, u32 sendSize, int wa
|
||||
}
|
||||
|
||||
// We didn't wait, so update the number of bytes transferred now.
|
||||
if (Memory::IsValidAddress(resultAddr))
|
||||
Memory::Write_U32(curSendAddr - sendBufAddr, resultAddr);
|
||||
if (Memory::IsValid4AlignedAddress(resultAddr))
|
||||
Memory::WriteUnchecked_U32(curSendAddr - sendBufAddr, resultAddr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -469,8 +469,8 @@ static int __KernelReceiveMsgPipe(MsgPipe *m, u32 receiveBufAddr, u32 receiveSiz
|
||||
if (poll)
|
||||
{
|
||||
// Generally, result is not updated in this case. But for a 0 size buffer in ASAP mode, it is.
|
||||
if (Memory::IsValidAddress(resultAddr) && waitMode == SCE_KERNEL_MPW_ASAP)
|
||||
Memory::Write_U32(curReceiveAddr - receiveBufAddr, resultAddr);
|
||||
if (Memory::IsValid4AlignedAddress(resultAddr) && waitMode == SCE_KERNEL_MPW_ASAP)
|
||||
Memory::WriteUnchecked_U32(curReceiveAddr - receiveBufAddr, resultAddr);
|
||||
return SCE_KERNEL_ERROR_MPP_EMPTY;
|
||||
}
|
||||
else
|
||||
@@ -520,8 +520,8 @@ static int __KernelReceiveMsgPipe(MsgPipe *m, u32 receiveBufAddr, u32 receiveSiz
|
||||
}
|
||||
}
|
||||
|
||||
if (Memory::IsValidAddress(resultAddr))
|
||||
Memory::Write_U32(curReceiveAddr - receiveBufAddr, resultAddr);
|
||||
if (Memory::IsValid4AlignedAddress(resultAddr))
|
||||
Memory::WriteUnchecked_U32(curReceiveAddr - receiveBufAddr, resultAddr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -263,7 +263,7 @@ static bool __KernelUnlockMutexForThread(PSPMutex *mutex, SceUID threadID, u32 &
|
||||
{
|
||||
// Remove any event for this thread.
|
||||
s64 cyclesLeft = CoreTiming::UnscheduleEvent(mutexWaitTimer, threadID);
|
||||
Memory::Write_U32((u32) cyclesToUs(cyclesLeft), timeoutPtr);
|
||||
Memory::WriteOrException_U32((u32) cyclesToUs(cyclesLeft), timeoutPtr);
|
||||
}
|
||||
|
||||
__KernelResumeThreadFromWait(threadID, result);
|
||||
@@ -498,8 +498,8 @@ int sceKernelCancelMutex(SceUID uid, int count, u32 numWaitThreadsPtr) {
|
||||
// Remove threads no longer waiting on this first (so the numWaitThreads value is correct.)
|
||||
HLEKernel::CleanupWaitingThreads(WAITTYPE_MUTEX, uid, mutex->waitingThreads);
|
||||
|
||||
if (Memory::IsValidAddress(numWaitThreadsPtr))
|
||||
Memory::Write_U32((u32)mutex->waitingThreads.size(), numWaitThreadsPtr);
|
||||
if (Memory::IsValid4AlignedAddress(numWaitThreadsPtr))
|
||||
Memory::WriteUnchecked_U32((u32)mutex->waitingThreads.size(), numWaitThreadsPtr);
|
||||
|
||||
bool wokeThreads = false;
|
||||
for (auto iter = mutex->waitingThreads.begin(), end = mutex->waitingThreads.end(); iter != end; ++iter)
|
||||
@@ -730,8 +730,7 @@ bool __KernelUnlockLwMutexForThread(LwMutex *mutex, T workarea, SceUID threadID,
|
||||
return false;
|
||||
|
||||
// If result is an error code, we're just letting it go.
|
||||
if (result == 0)
|
||||
{
|
||||
if (result == 0) {
|
||||
workarea->lockLevel = (int) __KernelGetWaitValue(threadID, error);
|
||||
workarea->lockThread = threadID;
|
||||
}
|
||||
@@ -740,7 +739,7 @@ bool __KernelUnlockLwMutexForThread(LwMutex *mutex, T workarea, SceUID threadID,
|
||||
if (timeoutPtr != 0 && lwMutexWaitTimer != -1) {
|
||||
// Remove any event for this thread.
|
||||
s64 cyclesLeft = CoreTiming::UnscheduleEvent(lwMutexWaitTimer, threadID);
|
||||
Memory::Write_U32((u32) cyclesToUs(cyclesLeft), timeoutPtr);
|
||||
Memory::WriteOrException_U32((u32) cyclesToUs(cyclesLeft), timeoutPtr);
|
||||
}
|
||||
|
||||
__KernelResumeThreadFromWait(threadID, result);
|
||||
|
||||
@@ -132,7 +132,7 @@ static bool __KernelUnlockSemaForThread(PSPSemaphore *s, SceUID threadID, u32 &e
|
||||
s64 cyclesLeft = CoreTiming::UnscheduleEvent(semaWaitTimer, threadID);
|
||||
if (cyclesLeft < 0)
|
||||
cyclesLeft = 0;
|
||||
Memory::Write_U32((u32) cyclesToUs(cyclesLeft), timeoutPtr);
|
||||
Memory::WriteOrException_U32((u32) cyclesToUs(cyclesLeft), timeoutPtr);
|
||||
}
|
||||
|
||||
__KernelResumeThreadFromWait(threadID, result);
|
||||
@@ -184,7 +184,7 @@ int sceKernelCancelSema(SceUID id, int newCount, u32 numWaitThreadsPtr)
|
||||
|
||||
s->ns.numWaitThreads = (int) s->waitingThreads.size();
|
||||
if (Memory::IsValidAddress(numWaitThreadsPtr))
|
||||
Memory::Write_U32(s->ns.numWaitThreads, numWaitThreadsPtr);
|
||||
Memory::WriteOrException_U32(s->ns.numWaitThreads, numWaitThreadsPtr);
|
||||
|
||||
if (newCount < 0)
|
||||
s->ns.currentCount = s->ns.initCount;
|
||||
|
||||
@@ -382,13 +382,13 @@ bool PSPThread::FillStack() {
|
||||
context.r[MIPS_REG_K0] = context.r[MIPS_REG_SP];
|
||||
u32 k0 = context.r[MIPS_REG_K0];
|
||||
Memory::Memset(k0, 0, 0x100, "ThreadK0");
|
||||
Memory::Write_U32(GetUID(), k0 + 0xc0);
|
||||
Memory::Write_U32(nt.initialStack, k0 + 0xc8);
|
||||
Memory::Write_U32(0xffffffff, k0 + 0xf8);
|
||||
Memory::Write_U32(0xffffffff, k0 + 0xfc);
|
||||
Memory::WriteOrException_U32(GetUID(), k0 + 0xc0);
|
||||
Memory::WriteOrException_U32(nt.initialStack, k0 + 0xc8);
|
||||
Memory::WriteOrException_U32(0xffffffff, k0 + 0xf8);
|
||||
Memory::WriteOrException_U32(0xffffffff, k0 + 0xfc);
|
||||
// After k0 comes the arguments, which is done by sceKernelStartThread().
|
||||
|
||||
Memory::Write_U32(GetUID(), nt.initialStack);
|
||||
Memory::WriteOrException_U32(GetUID(), nt.initialStack);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -418,7 +418,7 @@ bool PSPThread::PushExtendedStack(u32 size) {
|
||||
|
||||
// We still drop the threadID at the bottom and fill it, but there's no k0.
|
||||
Memory::Memset(currentStack.start, 0xFF, nt.stackSize, "ThreadExtendStack");
|
||||
Memory::Write_U32(GetUID(), nt.initialStack);
|
||||
Memory::WriteOrException_U32(GetUID(), nt.initialStack);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -715,7 +715,7 @@ static bool __KernelCheckResumeThreadEnd(PSPThread *t, SceUID waitingThreadID, u
|
||||
u32 timeoutPtr = __KernelGetWaitTimeoutPtr(waitingThreadID, error);
|
||||
s64 cyclesLeft = CoreTiming::UnscheduleEvent(eventThreadEndTimeout, waitingThreadID);
|
||||
if (timeoutPtr != 0)
|
||||
Memory::Write_U32((u32) cyclesToUs(cyclesLeft), timeoutPtr);
|
||||
Memory::WriteOrException_U32((u32) cyclesToUs(cyclesLeft), timeoutPtr);
|
||||
s32 exitStatus = t->nt.exitStatus;
|
||||
__KernelResumeThreadFromWait(waitingThreadID, exitStatus);
|
||||
return true;
|
||||
@@ -1327,7 +1327,7 @@ u32 sceKernelGetThreadmanIdList(u32 type, u32 readBufPtr, u32 readBufSize, u32 i
|
||||
}
|
||||
|
||||
if (Memory::IsValidAddress(idCountPtr)) {
|
||||
Memory::Write_U32(total, idCountPtr);
|
||||
Memory::WriteOrException_U32(total, idCountPtr);
|
||||
}
|
||||
return total > readBufSize ? readBufSize : total;
|
||||
}
|
||||
@@ -1420,8 +1420,9 @@ void __KernelWaitCurThread(WaitType type, SceUID waitID, u32 waitValue, u32 time
|
||||
thread->waitInfo.waitValue = waitValue;
|
||||
thread->waitInfo.timeoutPtr = timeoutPtr;
|
||||
|
||||
if (!reason)
|
||||
if (!reason) {
|
||||
reason = "started wait";
|
||||
}
|
||||
|
||||
hleReSchedule(processCallbacks, reason);
|
||||
}
|
||||
@@ -1513,7 +1514,7 @@ void __KernelStopThread(SceUID threadID, int exitStatus, const char *reason)
|
||||
{
|
||||
s64 cyclesLeft = CoreTiming::UnscheduleEvent(eventThreadEndTimeout, waitingThread);
|
||||
if (timeoutPtr != 0)
|
||||
Memory::Write_U32((u32) cyclesToUs(cyclesLeft), timeoutPtr);
|
||||
Memory::WriteOrException_U32((u32) cyclesToUs(cyclesLeft), timeoutPtr);
|
||||
|
||||
HLEKernel::ResumeFromWait(waitingThread, WAITTYPE_THREADEND, threadID, exitStatus);
|
||||
}
|
||||
@@ -1956,8 +1957,8 @@ int __KernelStartThread(SceUID threadToStartID, int argSize, u32 argBlockPtr, bo
|
||||
// At the bottom of those 64 bytes, the return syscall and ra is written.
|
||||
// Test Drive Unlimited actually depends on it being in the correct place.
|
||||
WriteHLESyscall("FakeSysCalls", NID_THREADRETURN, sp);
|
||||
Memory::Write_U32(MIPS_MAKE_B(-1), sp + 8);
|
||||
Memory::Write_U32(MIPS_MAKE_NOP(), sp + 12);
|
||||
Memory::WriteOrException_U32(MIPS_MAKE_B(-1), sp + 8);
|
||||
Memory::WriteOrException_U32(MIPS_MAKE_NOP(), sp + 12);
|
||||
|
||||
// Point ra at our return stub, and start fp off matching sp.
|
||||
startThread->context.r[MIPS_REG_RA] = sp;
|
||||
@@ -2792,9 +2793,9 @@ u32 sceKernelExtendThreadStack(u32 size, u32 entryAddr, u32 entryParameter) {
|
||||
// The stack has been changed now, so it's do or die time.
|
||||
|
||||
// Push the old SP, RA, and PC onto the stack (so we can restore them later.)
|
||||
Memory::Write_U32(currentMIPS->r[MIPS_REG_RA], thread->currentStack.end - 4);
|
||||
Memory::Write_U32(currentMIPS->r[MIPS_REG_SP], thread->currentStack.end - 8);
|
||||
Memory::Write_U32(currentMIPS->pc, thread->currentStack.end - 12);
|
||||
Memory::WriteOrException_U32(currentMIPS->r[MIPS_REG_RA], thread->currentStack.end - 4);
|
||||
Memory::WriteOrException_U32(currentMIPS->r[MIPS_REG_SP], thread->currentStack.end - 8);
|
||||
Memory::WriteOrException_U32(currentMIPS->pc, thread->currentStack.end - 12);
|
||||
|
||||
KernelValidateThreadTarget(entryAddr);
|
||||
|
||||
@@ -3116,11 +3117,11 @@ bool __KernelExecuteMipsCallOnCurrentThread(u32 callId, bool reschedAfter)
|
||||
// Let's just save regs generously. Better to be safe.
|
||||
sp -= 32 * 4;
|
||||
for (int i = MIPS_REG_A0; i <= MIPS_REG_T7; ++i) {
|
||||
Memory::Write_U32(currentMIPS->r[i], sp + i * 4);
|
||||
Memory::WriteOrException_U32(currentMIPS->r[i], sp + i * 4);
|
||||
}
|
||||
Memory::Write_U32(currentMIPS->r[MIPS_REG_T8], sp + MIPS_REG_T8 * 4);
|
||||
Memory::Write_U32(currentMIPS->r[MIPS_REG_T9], sp + MIPS_REG_T9 * 4);
|
||||
Memory::Write_U32(currentMIPS->r[MIPS_REG_RA], sp + MIPS_REG_RA * 4);
|
||||
Memory::WriteOrException_U32(currentMIPS->r[MIPS_REG_T8], sp + MIPS_REG_T8 * 4);
|
||||
Memory::WriteOrException_U32(currentMIPS->r[MIPS_REG_T9], sp + MIPS_REG_T9 * 4);
|
||||
Memory::WriteOrException_U32(currentMIPS->r[MIPS_REG_RA], sp + MIPS_REG_RA * 4);
|
||||
|
||||
// Save the few regs that need saving
|
||||
call->savedPc = currentMIPS->pc;
|
||||
|
||||
+2
-2
@@ -739,8 +739,8 @@ static u32 sceMp3LowLevelDecode(u32 mp3, u32 sourceAddr, u32 sourceBytesConsumed
|
||||
int outBytes = outSamples * sizeof(int16_t) * 2;
|
||||
NotifyMemInfo(MemBlockFlags::WRITE, samplesAddr, outBytes, "Mp3LowLevelDecode");
|
||||
|
||||
Memory::Write_U32(inbytesConsumed, sourceBytesConsumedAddr);
|
||||
Memory::Write_U32(outBytes, sampleBytesAddr);
|
||||
Memory::WriteOrException_U32(inbytesConsumed, sourceBytesConsumedAddr);
|
||||
Memory::WriteOrException_U32(outBytes, sampleBytesAddr);
|
||||
return hleLogDebug(Log::ME, 0);
|
||||
}
|
||||
|
||||
|
||||
+30
-30
@@ -509,15 +509,15 @@ static u32 sceMpegCreate(u32 mpegAddr, u32 dataPtr, u32 size, u32 ringbufferAddr
|
||||
|
||||
// Generate, and write mpeg handle into mpeg data, for some reason
|
||||
int mpegHandle = dataPtr + 0x30;
|
||||
Memory::Write_U32(mpegHandle, mpegAddr);
|
||||
Memory::WriteUnchecked_U32(mpegHandle, mpegAddr);
|
||||
|
||||
// Initialize fake mpeg struct.
|
||||
Memory::Memcpy(mpegHandle, "LIBMPEG\0", 8, "Mpeg");
|
||||
Memory::Memcpy(mpegHandle + 8, "001\0", 4, "Mpeg");
|
||||
Memory::Write_U32(-1, mpegHandle + 12);
|
||||
Memory::WriteUnchecked_U32(-1, mpegHandle + 12);
|
||||
if (ringbuffer.IsValid()) {
|
||||
Memory::Write_U32(ringbufferAddr, mpegHandle + 16);
|
||||
Memory::Write_U32(ringbuffer->dataUpperBound, mpegHandle + 20);
|
||||
Memory::WriteUnchecked_U32(ringbufferAddr, mpegHandle + 16);
|
||||
Memory::WriteUnchecked_U32(ringbuffer->dataUpperBound, mpegHandle + 20);
|
||||
}
|
||||
MpegContext *ctx = new MpegContext();
|
||||
if (g_mpegCtxs.find(mpegHandle) != g_mpegCtxs.end()) {
|
||||
@@ -1158,11 +1158,11 @@ static u32 sceMpegAvcDecode(u32 mpeg, u32 auAddr, u32 frameWidth, u32 bufferAddr
|
||||
|
||||
if (mpegLibVersion >= 0x0105 && mpegLibVersion < 0x010a) {
|
||||
//Killzone - Liberation expect , issue #16727
|
||||
Memory::Write_U32(1, initAddr);
|
||||
Memory::WriteOrException_U32(1, initAddr);
|
||||
}
|
||||
else {
|
||||
// Save the current frame's status to initAddr
|
||||
Memory::Write_U32(ctx->avc.avcFrameStatus, initAddr);
|
||||
Memory::WriteOrException_U32(ctx->avc.avcFrameStatus, initAddr);
|
||||
}
|
||||
ctx->avc.avcDecodeResult = MPEG_AVC_DECODE_SUCCESS;
|
||||
|
||||
@@ -1186,7 +1186,7 @@ static u32 sceMpegAvcDecodeStop(u32 mpeg, u32 frameWidth, u32 bufferAddr, u32 st
|
||||
}
|
||||
|
||||
// No last frame generated
|
||||
Memory::Write_U32(0, statusAddr);
|
||||
Memory::WriteOrException_U32(0, statusAddr);
|
||||
return hleLogDebug(Log::Mpeg, 0);
|
||||
}
|
||||
|
||||
@@ -1225,7 +1225,7 @@ static u32 sceMpegUnRegistStream(u32 mpeg, int streamUid) {
|
||||
}
|
||||
|
||||
static int sceMpegAvcDecodeDetail(u32 mpeg, u32 detailAddr) {
|
||||
if (!Memory::IsValidAddress(detailAddr)) {
|
||||
if (!Memory::IsValidRange(detailAddr, 36)) {
|
||||
return hleLogError(Log::Mpeg, -1, "invalid addresses");
|
||||
}
|
||||
|
||||
@@ -1234,15 +1234,15 @@ static int sceMpegAvcDecodeDetail(u32 mpeg, u32 detailAddr) {
|
||||
return hleLogWarning(Log::Mpeg, -1, "bad mpeg handle");
|
||||
}
|
||||
|
||||
Memory::Write_U32(ctx->avc.avcDecodeResult, detailAddr + 0);
|
||||
Memory::Write_U32(ctx->videoFrameCount, detailAddr + 4);
|
||||
Memory::Write_U32(ctx->avc.avcDetailFrameWidth, detailAddr + 8);
|
||||
Memory::Write_U32(ctx->avc.avcDetailFrameHeight, detailAddr + 12);
|
||||
Memory::Write_U32(0, detailAddr + 16);
|
||||
Memory::Write_U32(0, detailAddr + 20);
|
||||
Memory::Write_U32(0, detailAddr + 24);
|
||||
Memory::Write_U32(0, detailAddr + 28);
|
||||
Memory::Write_U32(ctx->avc.avcFrameStatus, detailAddr + 32);
|
||||
Memory::WriteUnchecked_U32(ctx->avc.avcDecodeResult, detailAddr + 0);
|
||||
Memory::WriteUnchecked_U32(ctx->videoFrameCount, detailAddr + 4);
|
||||
Memory::WriteUnchecked_U32(ctx->avc.avcDetailFrameWidth, detailAddr + 8);
|
||||
Memory::WriteUnchecked_U32(ctx->avc.avcDetailFrameHeight, detailAddr + 12);
|
||||
Memory::WriteUnchecked_U32(0, detailAddr + 16);
|
||||
Memory::WriteUnchecked_U32(0, detailAddr + 20);
|
||||
Memory::WriteUnchecked_U32(0, detailAddr + 24);
|
||||
Memory::WriteUnchecked_U32(0, detailAddr + 28);
|
||||
Memory::WriteUnchecked_U32(ctx->avc.avcFrameStatus, detailAddr + 32);
|
||||
return hleLogDebug(Log::Mpeg, 0);
|
||||
}
|
||||
|
||||
@@ -1378,7 +1378,7 @@ static int sceMpegInitAu(u32 mpeg, u32 bufferAddr, u32 auPointer) {
|
||||
}
|
||||
|
||||
static int sceMpegQueryAtracEsSize(u32 mpeg, u32 esSizeAddr, u32 outSizeAddr) {
|
||||
if (!Memory::IsValidAddress(esSizeAddr) || !Memory::IsValidAddress(outSizeAddr)) {
|
||||
if (!Memory::IsValid4AlignedAddress(esSizeAddr) || !Memory::IsValid4AlignedAddress(outSizeAddr)) {
|
||||
return hleLogError(Log::Mpeg, -1, "invalid addresses");
|
||||
}
|
||||
|
||||
@@ -1387,8 +1387,8 @@ static int sceMpegQueryAtracEsSize(u32 mpeg, u32 esSizeAddr, u32 outSizeAddr) {
|
||||
return hleLogWarning(Log::Mpeg, -1, "bad mpeg handle");
|
||||
}
|
||||
|
||||
Memory::Write_U32(MPEG_ATRAC_ES_SIZE, esSizeAddr);
|
||||
Memory::Write_U32(MPEG_ATRAC_ES_OUTPUT_SIZE, outSizeAddr);
|
||||
Memory::WriteUnchecked_U32(MPEG_ATRAC_ES_SIZE, esSizeAddr);
|
||||
Memory::WriteUnchecked_U32(MPEG_ATRAC_ES_OUTPUT_SIZE, outSizeAddr);
|
||||
return hleLogDebug(Log::Mpeg, 0);
|
||||
}
|
||||
|
||||
@@ -1611,8 +1611,8 @@ static int sceMpegGetAvcAu(u32 mpeg, u32 streamId, u32 auAddr, u32 attrAddr)
|
||||
avcAu.dts = avcAu.pts - videoTimestampStep;
|
||||
avcAu.esBuffer = streamInfo->second.num;
|
||||
avcAu.write(auAddr);
|
||||
if (Memory::IsValidAddress(attrAddr)) {
|
||||
Memory::Write_U32(1, attrAddr);
|
||||
if (Memory::IsValid4AlignedAddress(attrAddr)) {
|
||||
Memory::WriteUnchecked_U32(1, attrAddr);
|
||||
}
|
||||
return hleDelayResult(hleLogDebug(Log::Mpeg, 0), "mpeg get avc ignore", 100);
|
||||
}
|
||||
@@ -1651,7 +1651,7 @@ static int sceMpegGetAvcAu(u32 mpeg, u32 streamId, u32 auAddr, u32 attrAddr)
|
||||
if (result == 0) {
|
||||
// Jeanne d'Arc return 00000000 as attrAddr here and cause WriteMemoryOrRaiseException error
|
||||
if (Memory::IsValidAddress(attrAddr)) {
|
||||
Memory::Write_U32(1, attrAddr);
|
||||
Memory::WriteOrException_U32(1, attrAddr);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1710,8 +1710,8 @@ static int sceMpegGetAtracAu(u32 mpeg, u32 streamId, u32 auAddr, u32 attrAddr)
|
||||
atracAu.dts = atracAu.pts;
|
||||
atracAu.esBuffer = streamInfo->second.num;
|
||||
atracAu.write(auAddr);
|
||||
if (Memory::IsValidAddress(attrAddr)) {
|
||||
Memory::Write_U32(0, attrAddr);
|
||||
if (Memory::IsValid4AlignedAddress(attrAddr)) {
|
||||
Memory::WriteUnchecked_U32(0, attrAddr);
|
||||
}
|
||||
return hleDelayResult(hleLogDebug(Log::Mpeg, 0), "mpeg get atrac ignore", 100);
|
||||
}
|
||||
@@ -1750,8 +1750,8 @@ static int sceMpegGetAtracAu(u32 mpeg, u32 streamId, u32 auAddr, u32 attrAddr)
|
||||
|
||||
if (result == 0) {
|
||||
// 3rd birthday return 00000000 as attrAddr here and cause WriteMemoryOrRaiseException error
|
||||
if (Memory::IsValidAddress(attrAddr)) {
|
||||
Memory::Write_U32(0, attrAddr);
|
||||
if (Memory::IsValid4AlignedAddress(attrAddr)) {
|
||||
Memory::WriteUnchecked_U32(0, attrAddr);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1761,7 +1761,7 @@ static int sceMpegGetAtracAu(u32 mpeg, u32 streamId, u32 auAddr, u32 attrAddr)
|
||||
|
||||
static int sceMpegQueryPcmEsSize(u32 mpeg, u32 esSizeAddr, u32 outSizeAddr)
|
||||
{
|
||||
if (!Memory::IsValidAddress(esSizeAddr) || !Memory::IsValidAddress(outSizeAddr)) {
|
||||
if (!Memory::IsValid4AlignedAddress(esSizeAddr) || !Memory::IsValid4AlignedAddress(outSizeAddr)) {
|
||||
return hleLogError(Log::Mpeg, -1, "invalid addresses");
|
||||
}
|
||||
|
||||
@@ -1770,8 +1770,8 @@ static int sceMpegQueryPcmEsSize(u32 mpeg, u32 esSizeAddr, u32 outSizeAddr)
|
||||
return hleLogWarning(Log::Mpeg, -1, "bad mpeg handle");
|
||||
}
|
||||
|
||||
Memory::Write_U32(MPEG_PCM_ES_SIZE, esSizeAddr);
|
||||
Memory::Write_U32(MPEG_PCM_ES_OUTPUT_SIZE, outSizeAddr);
|
||||
Memory::WriteUnchecked_U32(MPEG_PCM_ES_SIZE, esSizeAddr);
|
||||
Memory::WriteUnchecked_U32(MPEG_PCM_ES_OUTPUT_SIZE, outSizeAddr);
|
||||
return hleLogError(Log::Mpeg, 0, "UNIMPL");
|
||||
}
|
||||
|
||||
|
||||
+7
-7
@@ -1521,7 +1521,7 @@ static int sceNetApctlGetState(u32 pStateAddr) {
|
||||
// Valid Arguments
|
||||
if (Memory::IsValidAddress(pStateAddr)) {
|
||||
// Return Thread Status
|
||||
Memory::Write_U32(NetApctl_GetState(), pStateAddr);
|
||||
Memory::WriteOrException_U32(NetApctl_GetState(), pStateAddr);
|
||||
// Return Success
|
||||
return hleLogDebug(Log::sceNet, 0);
|
||||
}
|
||||
@@ -1557,7 +1557,7 @@ int NetApctl_GetBSSDescIDListUser(u32 sizeAddr, u32 bufAddr) {
|
||||
|
||||
int size = Memory::ReadUnchecked_U32(sizeAddr);
|
||||
// Return size required
|
||||
Memory::Write_U32(entries * userInfoSize, sizeAddr);
|
||||
Memory::WriteUnchecked_U32(entries * userInfoSize, sizeAddr);
|
||||
|
||||
if (bufAddr != 0 && Memory::IsValidAddress(sizeAddr)) {
|
||||
int offset = 0;
|
||||
@@ -1570,16 +1570,16 @@ int NetApctl_GetBSSDescIDListUser(u32 sizeAddr, u32 bufAddr) {
|
||||
DEBUG_LOG(Log::sceNet, "%s writing ID#%d to %08x", __FUNCTION__, i, bufAddr + offset);
|
||||
|
||||
// Pointer to next Network structure in list
|
||||
Memory::Write_U32((i + 1) * userInfoSize + bufAddr, bufAddr + offset);
|
||||
Memory::WriteUnchecked_U32((i + 1) * userInfoSize + bufAddr, bufAddr + offset);
|
||||
offset += 4;
|
||||
|
||||
// Entry ID
|
||||
Memory::Write_U32(i, bufAddr + offset);
|
||||
Memory::WriteUnchecked_U32(i, bufAddr + offset);
|
||||
offset += 4;
|
||||
}
|
||||
// Fix the last Pointer
|
||||
if (offset > 0)
|
||||
Memory::Write_U32(0, bufAddr + offset - userInfoSize);
|
||||
Memory::WriteUnchecked_U32(0, bufAddr + offset - userInfoSize);
|
||||
}
|
||||
|
||||
return hleLogInfo(Log::sceNet, 0);
|
||||
@@ -1762,8 +1762,8 @@ static int sceNetUpnpGetNatInfo() {
|
||||
}
|
||||
|
||||
static int sceNetGetDropRate(u32 dropRateAddr, u32 dropDurationAddr) {
|
||||
Memory::Write_U32(netDropRate, dropRateAddr);
|
||||
Memory::Write_U32(netDropDuration, dropDurationAddr);
|
||||
Memory::WriteOrException_U32(netDropRate, dropRateAddr);
|
||||
Memory::WriteOrException_U32(netDropDuration, dropDurationAddr);
|
||||
return hleLogInfo(Log::sceNet, 0);
|
||||
}
|
||||
|
||||
|
||||
+15
-15
@@ -2023,7 +2023,7 @@ int sceNetAdhocctlGetState(u32 ptrToStatus) {
|
||||
|
||||
int state = NetAdhocctl_GetState();
|
||||
// Output Adhocctl State
|
||||
Memory::Write_U32(state, ptrToStatus);
|
||||
Memory::WriteOrException_U32(state, ptrToStatus);
|
||||
|
||||
// Return Success
|
||||
return hleLogVerbose(Log::sceNet, 0, "state = %d", state);
|
||||
@@ -5788,7 +5788,7 @@ int sceNetAdhocGetSocketAlert(int id, u32 flagPtr) {
|
||||
return hleLogDebug(Log::sceNet, SCE_NET_ADHOC_ERROR_INVALID_SOCKET_ID, "invalid socket id");
|
||||
|
||||
s32_le flg = adhocSockets[id - 1]->flags;
|
||||
Memory::Write_U32(flg, flagPtr);
|
||||
Memory::WriteOrException_U32(flg, flagPtr);
|
||||
|
||||
return hleLogDebug(Log::sceNet, 0, "flags = %08x", flg);
|
||||
}
|
||||
@@ -6216,7 +6216,7 @@ int sceNetAdhocDiscoverInitStart(u32 paramAddr) {
|
||||
Memory::Memset(netAdhocDiscoverBufAddr, 0, bufSize);
|
||||
}
|
||||
// FIME: Not sure what is this address 0x000010B0 used for (current Step may be?), but return 0x80411301 if (*((int *) 0x000010B0) != 0)
|
||||
//if (Memory::Read_U32(netAdhocDiscoverBufAddr + 0x80) != 0) //if (*((int*)Memory::GetPointer(0x000010B0)) != 0)
|
||||
//if (Memory::ReadOrException_U32(netAdhocDiscoverBufAddr + 0x80) != 0) //if (*((int*)Memory::GetPointer(0x000010B0)) != 0)
|
||||
// return 0x80411301; // Already Initialized/Started?
|
||||
// TODO: Need to findout whether using invalid params or param address will return an error code or not
|
||||
netAdhocDiscoverParam = (SceNetAdhocDiscoverParam*)Memory::GetPointer(paramAddr);
|
||||
@@ -6292,16 +6292,16 @@ int sceNetAdhocDiscoverTerm() {
|
||||
// if (sceKernelCheckThreadStack() < 0x00000FF0)
|
||||
// return 0x80410005;
|
||||
//
|
||||
// if (!(Memory::Read_U32(netAdhocDiscoverBufAddr + 0x80) > 0 && (Memory::Read_U32(netAdhocDiscoverBufAddr + 0x80) ^ 0x13) > 0))
|
||||
// if (!(Memory::ReadOrException_U32(netAdhocDiscoverBufAddr + 0x80) > 0 && (Memory::ReadOrException_U32(netAdhocDiscoverBufAddr + 0x80) ^ 0x13) > 0))
|
||||
// return 0x80411301; // Not Initialized/Started yet?
|
||||
|
||||
// TODO: Use sceNetAdhocctl_lib_1C679240 to remove adhocctl state callback handler setup in sceNetAdhocDiscoverInitStart
|
||||
// if (Memory::Read_U32(netAdhocDiscoverBufAddr + 0x70) >= 0) {
|
||||
// LinkDiscoverSkip(Memory::Read_U32(netAdhocDiscoverBufAddr + 0x70)); //sceNetAdhocctl_lib_1C679240
|
||||
// Memory::Write_U32(0xffffffff, netAdhocDiscoverBufAddr + 0x70);
|
||||
// if (Memory::ReadOrException_U32(netAdhocDiscoverBufAddr + 0x70) >= 0) {
|
||||
// LinkDiscoverSkip(Memory::ReadOrException_U32(netAdhocDiscoverBufAddr + 0x70)); //sceNetAdhocctl_lib_1C679240
|
||||
// Memory::WriteOrException_U32(0xffffffff, netAdhocDiscoverBufAddr + 0x70);
|
||||
// }
|
||||
// Memory::Write_U32(0, netAdhocDiscoverBufAddr + 0x80);
|
||||
// Memory::Write_U32(0, netAdhocDiscoverBufAddr + 0xA8);
|
||||
// Memory::WriteOrException_U32(0, netAdhocDiscoverBufAddr + 0x80);
|
||||
// Memory::WriteOrException_U32(0, netAdhocDiscoverBufAddr + 0xA8);
|
||||
|
||||
netAdhocDiscoverStatus = NET_ADHOC_DISCOVER_STATUS_NONE;
|
||||
//if (netAdhocDiscoverParam) netAdhocDiscoverParam->result = NET_ADHOC_DISCOVER_RESULT_NO_PEER_FOUND; // Test: Using result = NET_ADHOC_DISCOVER_RESULT_NO_PEER_FOUND will trigger Legend Of The Dragon to call sceNetAdhocctlGetPeerList after DiscoverTerm
|
||||
@@ -6317,11 +6317,11 @@ int sceNetAdhocDiscoverGetStatus() {
|
||||
DEBUG_LOG(Log::sceNet, "UNIMPL sceNetAdhocDiscoverGetStatus() at %08x", currentMIPS->pc);
|
||||
if (sceKernelCheckThreadStack() < 0x00000FF0)
|
||||
return 0x80410005;
|
||||
// if (Memory::Read_U32(netAdhocDiscoverBufAddr + 0x80) <= 0)
|
||||
// if (Memory::ReadOrException_U32(netAdhocDiscoverBufAddr + 0x80) <= 0)
|
||||
// return 0;
|
||||
// if (Memory::Read_U32(netAdhocDiscoverBufAddr + 0x80) <= 0x13)
|
||||
// if (Memory::ReadOrException_U32(netAdhocDiscoverBufAddr + 0x80) <= 0x13)
|
||||
// return 1;
|
||||
// if (Memory::Read_U32(netAdhocDiscoverBufAddr + 0x80) == 0x13)
|
||||
// if (Memory::ReadOrException_U32(netAdhocDiscoverBufAddr + 0x80) == 0x13)
|
||||
// return 2;
|
||||
return hleLogDebug(Log::sceNet, netAdhocDiscoverStatus); // Returning 2 will trigger Legend Of The Dragon to call sceNetAdhocctlGetPeerList (only happened if it was the first sceNetAdhocDiscoverGetStatus after sceNetAdhocDiscoverInitStart)
|
||||
}
|
||||
@@ -6332,13 +6332,13 @@ int sceNetAdhocDiscoverRequestSuspend()
|
||||
// FIXME: Not sure what is this syscall used for, may be related to Sleep Mode and can be triggered by using Power/Hold Switch? (based on what's written on Dissidia 012)
|
||||
if (sceKernelCheckThreadStack() < 0x00000FF0)
|
||||
return 0x80410005;
|
||||
// if (Memory::Read_U32(netAdhocDiscoverBufAddr + 0xA4) == 0)
|
||||
// if (Memory::ReadOrException_U32(netAdhocDiscoverBufAddr + 0xA4) == 0)
|
||||
// return 0x80411303; // Already Suspended?
|
||||
// if (Memory::Read_U32(netAdhocDiscoverBufAddr + 0x80) != 0)
|
||||
// if (Memory::ReadOrException_U32(netAdhocDiscoverBufAddr + 0x80) != 0)
|
||||
// return 0x80411303; // Already Suspended?
|
||||
// int ret = sceNetAdhocctl_lib_1572422C();
|
||||
// if (ret >= 0)
|
||||
// Memory::Write_U32(0, netAdhocDiscoverBufAddr + 0xA4);
|
||||
// Memory::WriteOrException_U32(0, netAdhocDiscoverBufAddr + 0xA4);
|
||||
// return ret;
|
||||
// Since we don't know what this supposed to do, and we currently don't have a working AdhocDiscover yet, may be we should cancel the progress for now?
|
||||
netAdhocDiscoverIsStopping = true;
|
||||
|
||||
@@ -112,7 +112,7 @@ static int NetResolver_StartNtoA(NetResolver *resolver, u32 hostnamePtr, u32 inA
|
||||
}
|
||||
}
|
||||
net::DNSResolveFree(resolved);
|
||||
Memory::Write_U32(addr.in.sin_addr.s_addr, inAddrPtr);
|
||||
Memory::WriteOrException_U32(addr.in.sin_addr.s_addr, inAddrPtr);
|
||||
INFO_LOG(Log::sceNet, "%s - Hostname: %s => IPv4: %s", __FUNCTION__, hostname.c_str(),
|
||||
ip2str(addr.in.sin_addr, false).c_str());
|
||||
}
|
||||
|
||||
+3
-3
@@ -173,8 +173,8 @@ static int sceNpGetContentRatingFlag(u32 parentalControlAddr, u32 userAgeAddr)
|
||||
INFO_LOG(Log::sceNet, "%s - Parental Control: %d", __FUNCTION__, npParentalControl);
|
||||
INFO_LOG(Log::sceNet, "%s - User Age: %d", __FUNCTION__, npUserAge);
|
||||
|
||||
Memory::Write_U32(npParentalControl, parentalControlAddr);
|
||||
Memory::Write_U32(npUserAge, userAgeAddr);
|
||||
Memory::WriteOrException_U32(npParentalControl, parentalControlAddr);
|
||||
Memory::WriteOrException_U32(npUserAge, userAgeAddr);
|
||||
|
||||
return hleLogWarning(Log::sceNet, 0, "UNTESTED");
|
||||
}
|
||||
@@ -184,7 +184,7 @@ static int sceNpGetChatRestrictionFlag(u32 flagAddr)
|
||||
if (!Memory::IsValidAddress(flagAddr))
|
||||
return hleLogError(Log::sceNet, SCE_NP_ERROR_INVALID_ARGUMENT, "invalid arg");
|
||||
|
||||
Memory::Write_U32(npChatRestriction, flagAddr);
|
||||
Memory::WriteOrException_U32(npChatRestriction, flagAddr);
|
||||
|
||||
return hleLogWarning(Log::sceNet, 0, "Chat restriction: %d", npChatRestriction);
|
||||
}
|
||||
|
||||
+8
-8
@@ -449,7 +449,7 @@ static int sceRtcConvertLocalTimeToUTC(u32 tickLocalPtr,u32 tickUTCPtr)
|
||||
tm *time = localtime(&timezone);
|
||||
srcTick -= time->tm_gmtoff*1000000ULL;
|
||||
#endif
|
||||
Memory::Write_U64(srcTick, tickUTCPtr);
|
||||
Memory::WriteUnchecked_U64(srcTick, tickUTCPtr);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -902,10 +902,10 @@ static bool rtcParseRFC2822(const char *s, RtcParseResult &r) {
|
||||
|
||||
static int sceRtcParseDateTime(u32 destTickPtr, u32 dateStringPtr)
|
||||
{
|
||||
if (!Memory::IsValidAddress(destTickPtr) || !Memory::IsValidAddress(dateStringPtr))
|
||||
if (!Memory::IsValid4AlignedRange(destTickPtr, 8) || !Memory::IsValidAddress(dateStringPtr))
|
||||
return hleLogError(Log::sceRtc, -1, "bad address");
|
||||
|
||||
const char *s = (const char *)Memory::GetPointer(dateStringPtr);
|
||||
const char *s = Memory::GetCharPointer(dateStringPtr);
|
||||
if (!s) {
|
||||
return hleLogError(Log::sceRtc, -1, "null string");
|
||||
}
|
||||
@@ -917,7 +917,7 @@ static int sceRtcParseDateTime(u32 destTickPtr, u32 dateStringPtr)
|
||||
u64 ticks = __RtcPspTimeToTicks(r.date);
|
||||
s64 offsetUs = (s64)r.tzOffsetMinutes * 60 * 1000000;
|
||||
ticks -= offsetUs;
|
||||
Memory::Write_U64(ticks, destTickPtr);
|
||||
Memory::WriteUnchecked_U64(ticks, destTickPtr);
|
||||
return hleLogDebug(Log::sceRtc, 0);
|
||||
}
|
||||
|
||||
@@ -927,16 +927,16 @@ static int sceRtcParseDateTime(u32 destTickPtr, u32 dateStringPtr)
|
||||
|
||||
static int sceRtcGetLastAdjustedTime(u32 tickPtr)
|
||||
{
|
||||
if (Memory::IsValidAddress(tickPtr))
|
||||
Memory::Write_U64(rtcLastAdjustedTicks, tickPtr);
|
||||
if (Memory::IsValid4AlignedRange(tickPtr, 8))
|
||||
Memory::WriteUnchecked_U64(rtcLastAdjustedTicks, tickPtr);
|
||||
DEBUG_LOG(Log::sceRtc, "sceRtcGetLastAdjustedTime(%d)", tickPtr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sceRtcGetLastReincarnatedTime(u32 tickPtr)
|
||||
{
|
||||
if (Memory::IsValidAddress(tickPtr))
|
||||
Memory::Write_U64(rtcLastReincarnatedTicks, tickPtr);
|
||||
if (Memory::IsValid4AlignedRange(tickPtr, 8))
|
||||
Memory::WriteUnchecked_U64(rtcLastReincarnatedTicks, tickPtr);
|
||||
DEBUG_LOG(Log::sceRtc, "sceRtcGetLastReincarnatedTime(%d)", tickPtr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
+2
-2
@@ -665,7 +665,7 @@ static u32 sceSasGetAllEnvelopeHeights(u32 core, u32 heightsAddr) {
|
||||
__SasDrain();
|
||||
for (int i = 0; i < PSP_SAS_VOICES_MAX; i++) {
|
||||
int voiceHeight = sas->voices[i].envelope.GetHeight();
|
||||
Memory::Write_U32(voiceHeight, heightsAddr + i * 4);
|
||||
Memory::WriteOrException_U32(voiceHeight, heightsAddr + i * 4);
|
||||
}
|
||||
|
||||
return hleLogDebug(Log::sceSas, 0);
|
||||
@@ -735,7 +735,7 @@ static u32 __sceSasUnsetATRAC3(u32 core, int voiceNum) {
|
||||
v.on = false;
|
||||
// This unpauses. Some games, like Sol Trigger, depend on this.
|
||||
v.paused = false;
|
||||
Memory::Write_U32(0, core + 56 * voiceNum + 20);
|
||||
Memory::WriteOrException_U32(0, core + 56 * voiceNum + 20);
|
||||
|
||||
return hleLogDebug(Log::sceSas, 0);
|
||||
}
|
||||
|
||||
+24
-42
@@ -23,19 +23,17 @@
|
||||
#include "Core/MemMap.h"
|
||||
#include "Core/HLE/sceSsl.h"
|
||||
|
||||
bool isSslInit;
|
||||
u32 maxMemSize;
|
||||
u32 currentMemSize;
|
||||
static bool isSslInit;
|
||||
static u32 maxMemSize;
|
||||
static u32 currentMemSize;
|
||||
|
||||
void __SslInit()
|
||||
{
|
||||
void __SslInit() {
|
||||
isSslInit = 0;
|
||||
maxMemSize = 0;
|
||||
currentMemSize = 0;
|
||||
}
|
||||
|
||||
void __SslDoState(PointerWrap &p)
|
||||
{
|
||||
void __SslDoState(PointerWrap &p) {
|
||||
auto s = p.Section("sceSsl", 1);
|
||||
if (!s)
|
||||
return;
|
||||
@@ -45,67 +43,52 @@ void __SslDoState(PointerWrap &p)
|
||||
Do(p, currentMemSize);
|
||||
}
|
||||
|
||||
static int sceSslInit(int heapSize)
|
||||
{
|
||||
DEBUG_LOG(Log::HLE, "sceSslInit %d", heapSize);
|
||||
if (isSslInit)
|
||||
{
|
||||
static int sceSslInit(int heapSize) {
|
||||
if (isSslInit) {
|
||||
return SCE_SSL_ERROR_ALREADY_INIT;
|
||||
}
|
||||
if (heapSize <= 0)
|
||||
{
|
||||
if (heapSize <= 0) {
|
||||
return SCE_SSL_ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
maxMemSize = heapSize;
|
||||
currentMemSize = heapSize / 2; // As per jpcsp
|
||||
isSslInit = true;
|
||||
return 0;
|
||||
return hleLogDebug(Log::HLE, 0);
|
||||
}
|
||||
|
||||
static int sceSslEnd()
|
||||
{
|
||||
static int sceSslEnd() {
|
||||
DEBUG_LOG(Log::HLE, "sceSslEnd");
|
||||
if (!isSslInit)
|
||||
{
|
||||
if (!isSslInit) {
|
||||
return SCE_SSL_ERROR_NOT_INIT;
|
||||
}
|
||||
isSslInit = false;
|
||||
return 0;
|
||||
return hleLogDebug(Log::HLE, 0);
|
||||
}
|
||||
|
||||
static int sceSslGetUsedMemoryMax(u32 maxMemPtr)
|
||||
{
|
||||
DEBUG_LOG(Log::HLE, "sceSslGetUsedMemoryMax %d", maxMemPtr);
|
||||
if (!isSslInit)
|
||||
{
|
||||
static int sceSslGetUsedMemoryMax(u32 maxMemPtr) {
|
||||
if (!isSslInit) {
|
||||
return SCE_SSL_ERROR_NOT_INIT;
|
||||
}
|
||||
|
||||
if (Memory::IsValidAddress(maxMemPtr))
|
||||
{
|
||||
Memory::Write_U32(maxMemSize, maxMemPtr);
|
||||
if (Memory::IsValid4AlignedAddress(maxMemPtr)) {
|
||||
Memory::WriteUnchecked_U32(maxMemSize, maxMemPtr);
|
||||
}
|
||||
return 0;
|
||||
return hleLogDebug(Log::HLE, 0);
|
||||
}
|
||||
|
||||
static int sceSslGetUsedMemoryCurrent(u32 currentMemPtr)
|
||||
{
|
||||
DEBUG_LOG(Log::HLE, "sceSslGetUsedMemoryCurrent %d", currentMemPtr);
|
||||
if (!isSslInit)
|
||||
{
|
||||
static int sceSslGetUsedMemoryCurrent(u32 currentMemPtr) {
|
||||
if (!isSslInit) {
|
||||
return SCE_SSL_ERROR_NOT_INIT;
|
||||
}
|
||||
|
||||
if (Memory::IsValidAddress(currentMemPtr))
|
||||
{
|
||||
Memory::Write_U32(currentMemSize, currentMemPtr);
|
||||
if (Memory::IsValid4AlignedAddress(currentMemPtr)) {
|
||||
Memory::WriteUnchecked_U32(currentMemSize, currentMemPtr);
|
||||
}
|
||||
return 0;
|
||||
return hleLogDebug(Log::HLE, 0);
|
||||
}
|
||||
|
||||
const HLEFunction sceSsl[] =
|
||||
{
|
||||
const HLEFunction sceSsl[] = {
|
||||
{0X957ECBE2, &WrapI_I<sceSslInit>, "sceSslInit", 'i', "i"},
|
||||
{0X191CDEFF, &WrapI_V<sceSslEnd>, "sceSslEnd", 'i', "" },
|
||||
{0X5BFB6B61, nullptr, "sceSslGetNotAfter", '?', "" },
|
||||
@@ -120,7 +103,6 @@ const HLEFunction sceSsl[] =
|
||||
{0XF57765D3, nullptr, "sceSslGetKeyUsage", '?', "" },
|
||||
};
|
||||
|
||||
void Register_sceSsl()
|
||||
{
|
||||
void Register_sceSsl() {
|
||||
RegisterHLEModule("sceSsl", ARRAY_SIZE(sceSsl), sceSsl);
|
||||
}
|
||||
@@ -1090,7 +1090,7 @@ static int sceUtilityGetNetParam(int id, int param, u32 dataAddr) {
|
||||
static int sceUtilityGetNetParamLatestID(u32 idAddr) {
|
||||
DEBUG_LOG(Log::sceUtility, "sceUtilityGetNetParamLatestID(%08x)", idAddr);
|
||||
// This function is saving the last net param ID (non-zero ID?) and not the number of net configurations.
|
||||
Memory::Write_U32(netParamLatestId, idAddr);
|
||||
Memory::WriteOrException_U32(netParamLatestId, idAddr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1269,7 +1269,7 @@ static u32 sceUtilityGetSystemParamInt(u32 id, u32 destaddr) {
|
||||
// FIXME: Outputted channel (might be unchanged?) either 0 when not connected to a group yet (ie. adhocctlState == ADHOCCTL_STATE_DISCONNECTED),
|
||||
// or -1 (0xFFFFFFFF) when a scan is in progress (ie. adhocctlState == ADHOCCTL_STATE_SCANNING),
|
||||
// or 0x60 early when in connected state (ie. adhocctlState == ADHOCCTL_STATE_CONNECTED) right after Creating a group, regardless the channel settings.
|
||||
Memory::Write_U32(param, destaddr);
|
||||
Memory::WriteOrException_U32(param, destaddr);
|
||||
return 0x800ADF4;
|
||||
}
|
||||
break;
|
||||
@@ -1309,7 +1309,7 @@ static u32 sceUtilityGetSystemParamInt(u32 id, u32 destaddr) {
|
||||
return hleLogError(Log::sceUtility, SCE_ERROR_UTILITY_INVALID_SYSTEM_PARAM_ID);
|
||||
}
|
||||
|
||||
Memory::Write_U32(param, destaddr);
|
||||
Memory::WriteOrException_U32(param, destaddr);
|
||||
return hleLogInfo(Log::sceUtility, 0, "(%s): %08x", SystemParamToString(id), param);
|
||||
}
|
||||
|
||||
|
||||
@@ -496,7 +496,7 @@ u32 AuCtx::AuDecode(u32 pcmAddr) {
|
||||
int outpcmbufsize = 0;
|
||||
|
||||
if (pcmAddr)
|
||||
Memory::Write_U32(outptr, pcmAddr);
|
||||
Memory::WriteOrException_U32(outptr, pcmAddr);
|
||||
|
||||
// Decode a single frame in sourcebuff and output into PCMBuf.
|
||||
if (!sourcebuff.empty()) {
|
||||
|
||||
+1
-1
@@ -55,7 +55,7 @@ static int r32(int address) {
|
||||
|
||||
static void w32(int address, int value) {
|
||||
if (Memory::IsValid4AlignedAddress(address)) {
|
||||
Memory::Write_U32(value, address); // NOTE: These are backwards for historical reasons.
|
||||
Memory::WriteUnchecked_U32(value, address); // NOTE: These are backwards for historical reasons.
|
||||
} else {
|
||||
g_lua.Print(LogLineType::Error, StringFromFormat("w32: bad address %08x trying to write %08x", address, value));
|
||||
}
|
||||
|
||||
@@ -281,7 +281,7 @@ namespace MIPSComp
|
||||
}
|
||||
break;
|
||||
|
||||
case 58: //sv.s // Memory::Write_U32(VI(vt), addr);
|
||||
case 58: //sv.s
|
||||
{
|
||||
if (!gpr.IsImm(rs) && jo.cachePointers && g_Config.bFastMemory && (offset & 3) == 0 && offset < 0x400 && offset > -0x400) {
|
||||
gpr.MapRegAsPointer(rs);
|
||||
|
||||
@@ -346,7 +346,7 @@ void JitSafeMem::IndirectCALL(const void *safeFunc) {
|
||||
|
||||
void JitSafeMem::Finish()
|
||||
{
|
||||
// Memory::Read_U32/etc. may have tripped coreState.
|
||||
// Memory::ReadOrException_U32/etc. may have tripped coreState.
|
||||
if (needsCheck_ && !g_Config.bIgnoreBadMemAccess)
|
||||
jit_->js.afterOp |= JitState::AFTER_CORE_STATE;
|
||||
if (needsSkip_)
|
||||
@@ -365,18 +365,18 @@ void JitSafeMemFuncs::Init(ThunkManager *thunks) {
|
||||
|
||||
BeginWrite(1024);
|
||||
readU32 = GetCodePtr();
|
||||
CreateReadFunc(32, (const void *)&Memory::Read_U32);
|
||||
CreateReadFunc(32, (const void *)&Memory::ReadOrException_U32);
|
||||
readU16 = GetCodePtr();
|
||||
CreateReadFunc(16, (const void *)&Memory::Read_U16);
|
||||
CreateReadFunc(16, (const void *)&Memory::ReadOrException_U16);
|
||||
readU8 = GetCodePtr();
|
||||
CreateReadFunc(8, (const void *)&Memory::Read_U8);
|
||||
CreateReadFunc(8, (const void *)&Memory::ReadOrException_U8);
|
||||
|
||||
writeU32 = GetCodePtr();
|
||||
CreateWriteFunc(32, (const void *)&Memory::Write_U32);
|
||||
CreateWriteFunc(32, (const void *)&Memory::WriteOrException_U32);
|
||||
writeU16 = GetCodePtr();
|
||||
CreateWriteFunc(16, (const void *)&Memory::Write_U16);
|
||||
CreateWriteFunc(16, (const void *)&Memory::WriteOrException_U16);
|
||||
writeU8 = GetCodePtr();
|
||||
CreateWriteFunc(8, (const void *)&Memory::Write_U8);
|
||||
CreateWriteFunc(8, (const void *)&Memory::WriteOrException_U8);
|
||||
EndWrite();
|
||||
}
|
||||
|
||||
|
||||
+7
-7
@@ -137,9 +137,9 @@ void Write_Opcode_JIT(const u32 _Address, const Opcode& _Value);
|
||||
Opcode Read_Instruction(const u32 _Address, bool resolveReplacements = false);
|
||||
Opcode ReadUnchecked_Instruction(const u32 _Address, bool resolveReplacements = false);
|
||||
|
||||
u8 Read_U8(const u32 _Address);
|
||||
u16 Read_U16(const u32 _Address);
|
||||
u32 Read_U32(const u32 _Address);
|
||||
u8 ReadOrException_U8(const u32 _Address);
|
||||
u16 ReadOrException_U16(const u32 _Address);
|
||||
u32 ReadOrException_U32(const u32 _Address);
|
||||
|
||||
inline u8* GetPointerWriteUnchecked(const u32 address) {
|
||||
#ifdef MASKED_PSP_MEMORY
|
||||
@@ -237,10 +237,10 @@ inline void WriteUnchecked_U8(u8 data, u32 address) {
|
||||
#endif
|
||||
}
|
||||
|
||||
void Write_U8(const u8 data, const u32 address);
|
||||
void Write_U16(const u16 data, const u32 address);
|
||||
void Write_U32(const u32 data, const u32 address);
|
||||
void Write_U64(const u64 data, const u32 address);
|
||||
void WriteOrException_U8(const u8 data, const u32 address);
|
||||
void WriteOrException_U16(const u16 data, const u32 address);
|
||||
void WriteOrException_U32(const u32 data, const u32 address);
|
||||
void WriteOrException_U64(const u64 data, const u32 address);
|
||||
|
||||
u8* GetPointerWrite(const u32 address);
|
||||
const u8* GetPointer(const u32 address);
|
||||
|
||||
@@ -124,19 +124,19 @@ bool IsScratchpadAddress(const u32 address) {
|
||||
return (address & 0xBFFFC000) == 0x00010000;
|
||||
}
|
||||
|
||||
u8 Read_U8(const u32 address) {
|
||||
u8 ReadOrException_U8(const u32 address) {
|
||||
u8 value = 0;
|
||||
ReadMemoryOrRaiseException<u8>(value, address);
|
||||
return (u8)value;
|
||||
}
|
||||
|
||||
u16 Read_U16(const u32 address) {
|
||||
u16 ReadOrException_U16(const u32 address) {
|
||||
u16_le value = 0;
|
||||
ReadMemoryOrRaiseException<u16_le>(value, address);
|
||||
return (u16)value;
|
||||
}
|
||||
|
||||
u32 Read_U32(const u32 address) {
|
||||
u32 ReadOrException_U32(const u32 address) {
|
||||
u32_le value = 0;
|
||||
ReadMemoryOrRaiseException<u32_le>(value, address);
|
||||
return value;
|
||||
@@ -148,19 +148,19 @@ u64 Read_U64(const u32 address) {
|
||||
return value;
|
||||
}
|
||||
|
||||
void Write_U8(const u8 _Data, const u32 address) {
|
||||
void WriteOrException_U8(const u8 _Data, const u32 address) {
|
||||
WriteMemoryOrRaiseException<u8>(address, _Data);
|
||||
}
|
||||
|
||||
void Write_U16(const u16 _Data, const u32 address) {
|
||||
void WriteOrException_U16(const u16 _Data, const u32 address) {
|
||||
WriteMemoryOrRaiseException<u16_le>(address, _Data);
|
||||
}
|
||||
|
||||
void Write_U32(const u32 _Data, const u32 address) {
|
||||
void WriteOrException_U32(const u32 _Data, const u32 address) {
|
||||
WriteMemoryOrRaiseException<u32_le>(address, _Data);
|
||||
}
|
||||
|
||||
void Write_U64(const u64 _Data, const u32 address) {
|
||||
void WriteOrException_U64(const u64 _Data, const u32 address) {
|
||||
WriteMemoryOrRaiseException<u64_le>(address, _Data);
|
||||
}
|
||||
|
||||
|
||||
@@ -156,7 +156,7 @@ void PPGeSetTexture(u32 dataAddr, int width, int height);
|
||||
|
||||
//only 0xFFFFFF of data is used
|
||||
static void WriteCmd(u8 cmd, u32 data) {
|
||||
Memory::Write_U32((cmd << 24) | (data & 0xFFFFFF), dlWritePtr);
|
||||
Memory::WriteUnchecked_U32((cmd << 24) | (data & 0xFFFFFF), dlWritePtr);
|
||||
dlWritePtr += 4;
|
||||
_dbg_assert_(dlWritePtr <= dlPtr + dlSize);
|
||||
}
|
||||
|
||||
@@ -434,7 +434,7 @@ void DumpExecute::Registers(u32 ptr, u32 sz) {
|
||||
}
|
||||
|
||||
execListPos = execListBuf;
|
||||
Memory::Write_U32(GE_CMD_NOP << 24, execListPos);
|
||||
Memory::WriteUnchecked_U32(GE_CMD_NOP << 24, execListPos);
|
||||
execListPos += 4;
|
||||
|
||||
// TODO: Why do we disable interrupts here?
|
||||
@@ -447,8 +447,8 @@ void DumpExecute::Registers(u32 ptr, u32 sz) {
|
||||
// Validate space for jump.
|
||||
u32 allocSize = pendingSize + sz + 8;
|
||||
if (execListPos + allocSize >= execListBuf + LIST_BUF_SIZE) {
|
||||
Memory::Write_U32((GE_CMD_BASE << 24) | ((execListBuf >> 8) & 0x00FF0000), execListPos);
|
||||
Memory::Write_U32((GE_CMD_JUMP << 24) | (execListBuf & 0x00FFFFFF), execListPos + 4);
|
||||
Memory::WriteUnchecked_U32((GE_CMD_BASE << 24) | ((execListBuf >> 8) & 0x00FF0000), execListPos);
|
||||
Memory::WriteUnchecked_U32((GE_CMD_JUMP << 24) | (execListBuf & 0x00FFFFFF), execListPos + 4);
|
||||
|
||||
execListPos = execListBuf;
|
||||
lastBase_ = execListBuf & 0xFF000000;
|
||||
@@ -506,8 +506,8 @@ void DumpExecute::SubmitListEnd() {
|
||||
}
|
||||
|
||||
// There's always space for the end, same size as a jump.
|
||||
Memory::Write_U32(GE_CMD_FINISH << 24, execListPos);
|
||||
Memory::Write_U32(GE_CMD_END << 24, execListPos + 4);
|
||||
Memory::WriteUnchecked_U32(GE_CMD_FINISH << 24, execListPos);
|
||||
Memory::WriteUnchecked_U32(GE_CMD_END << 24, execListPos + 4);
|
||||
execListPos += 8;
|
||||
|
||||
for (int i = 0; i < 8; ++i)
|
||||
|
||||
@@ -782,8 +782,10 @@ void ImDisasmView::PopupMenu(ImControl &control) {
|
||||
assembleOpcode(curAddress_, "");
|
||||
}
|
||||
if (ImGui::MenuItem("NOP instructions (destructive)")) {
|
||||
for (u32 addr = selectRangeStart_; addr < selectRangeEnd_; addr += 4) {
|
||||
Memory::Write_U32(0, addr);
|
||||
if (Memory::IsValid4AlignedRange(selectRangeStart_, selectRangeEnd_ - selectRangeStart_)) {
|
||||
for (u32 addr = selectRangeStart_; addr < selectRangeEnd_; addr += 4) {
|
||||
Memory::WriteUnchecked_U32(0, addr);
|
||||
}
|
||||
}
|
||||
if (currentMIPS) {
|
||||
currentMIPS->InvalidateICache(selectRangeStart_, selectRangeEnd_ - selectRangeStart_);
|
||||
|
||||
@@ -954,8 +954,10 @@ void CtrlDisAsmView::NopInstructions(u32 selectRangeStart, u32 selectRangeEnd) {
|
||||
// Route the memory writes to the CPU thread instead of poking at it directly from this GUI
|
||||
// thread - see Core_RunOnCPUThread() in Core.h.
|
||||
Core_RunOnCPUThread([&] {
|
||||
for (u32 addr = selectRangeStart; addr < selectRangeEnd; addr += 4) {
|
||||
Memory::Write_U32(0, addr);
|
||||
if (Memory::IsValidRange(selectRangeStart, selectRangeEnd - selectRangeStart)) {
|
||||
for (u32 addr = selectRangeStart; addr < selectRangeEnd; addr += 4) {
|
||||
Memory::WriteUnchecked_U32(0, addr);
|
||||
}
|
||||
}
|
||||
|
||||
if (currentMIPS) {
|
||||
|
||||
Reference in new issue
Block a user