CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!
CoCalc provides the best real-time collaborative environment for Jupyter Notebooks, LaTeX documents, and SageMath, scalable from individual users to large groups and classes!
Path: blob/master/Core/MemMapFunctions.cpp
Views: 1401
// Copyright (C) 2003 Dolphin Project / 2012 PPSSPP Project12// This program is free software: you can redistribute it and/or modify3// it under the terms of the GNU General Public License as published by4// the Free Software Foundation, version 2.0 or later versions.56// This program is distributed in the hope that it will be useful,7// but WITHOUT ANY WARRANTY; without even the implied warranty of8// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the9// GNU General Public License 2.0 for more details.1011// A copy of the GPL 2.0 should have been included with the program.12// If not, see http://www.gnu.org/licenses/1314// Official git repository and contact information can be found at15// https://github.com/hrydgard/ppsspp and http://www.ppsspp.org/.1617#include "Common/CommonTypes.h"18#include "Common/LogReporting.h"1920#include "Core/Core.h"21#include "Core/MemMap.h"22#include "Core/Config.h"23#include "Core/ConfigValues.h"2425#include "Core/MIPS/MIPS.h"2627namespace Memory {2829u8 *GetPointerWrite(const u32 address) {30if ((address & 0x3E000000) == 0x08000000 || // RAM31(address & 0x3F800000) == 0x04000000 || // VRAM32(address & 0xBFFFC000) == 0x00010000 || // Scratchpad33((address & 0x3F000000) >= 0x08000000 && (address & 0x3F000000) < 0x08000000 + g_MemorySize)) { // More RAM (remasters, etc.)34return GetPointerWriteUnchecked(address);35} else {36static bool reported = false;37if (!reported) {38Reporting::ReportMessage("Unknown GetPointerWrite %08x PC %08x LR %08x", address, currentMIPS->pc, currentMIPS->r[MIPS_REG_RA]);39reported = true;40}4142// Size is not known, we pass 0 to signal that.43Core_MemoryException(address, 0, currentMIPS->pc, MemoryExceptionType::WRITE_BLOCK);44return nullptr;45}46}4748const u8 *GetPointer(const u32 address) {49if ((address & 0x3E000000) == 0x08000000 || // RAM50(address & 0x3F800000) == 0x04000000 || // VRAM51(address & 0xBFFFC000) == 0x00010000 || // Scratchpad52((address & 0x3F000000) >= 0x08000000 && (address & 0x3F000000) < 0x08000000 + g_MemorySize)) { // More RAM (remasters, etc.)53return GetPointerUnchecked(address);54} else {55static bool reported = false;56if (!reported) {57Reporting::ReportMessage("Unknown GetPointer %08x PC %08x LR %08x", address, currentMIPS->pc, currentMIPS->r[MIPS_REG_RA]);58reported = true;59}60// Size is not known, we pass 0 to signal that.61Core_MemoryException(address, 0, currentMIPS->pc, MemoryExceptionType::READ_BLOCK);62return nullptr;63}64}6566u8 *GetPointerWriteRange(const u32 address, const u32 size) {67u8 *ptr = GetPointerWrite(address);68if (ptr) {69if (ValidSize(address, size) != size) {70// That's a memory exception! TODO: Adjust reported address to the end of the range?71Core_MemoryException(address, size, currentMIPS->pc, MemoryExceptionType::WRITE_BLOCK);72return nullptr;73} else {74return ptr;75}76} else {77// Error was reported in GetPointerWrite already, if we're not ignoring errors.78return nullptr;79}80}8182const u8 *GetPointerRange(const u32 address, const u32 size) {83const u8 *ptr = GetPointer(address);84if (ptr) {85if (ValidSize(address, size) != size) {86// That's a memory exception! TODO: Adjust reported address to the end of the range?87Core_MemoryException(address, size, currentMIPS->pc, MemoryExceptionType::READ_BLOCK);88return nullptr;89} else {90return ptr;91}92} else {93// Error was reported in GetPointer already, if we're not ignoring errors.94return nullptr;95}96}9798template <typename T>99inline void ReadFromHardware(T &var, const u32 address) {100// TODO: Figure out the fastest order of tests for both read and write (they are probably different).101if ((address & 0x3E000000) == 0x08000000) {102// RAM103var = *((const T*)GetPointerUnchecked(address));104} else if ((address & 0x3F800000) == 0x04000000) {105// VRAM106var = *((const T*)GetPointerUnchecked(address));107} else if ((address & 0xBFFFC000) == 0x00010000) {108// Scratchpad109var = *((const T*)GetPointerUnchecked(address));110} else if ((address & 0x3F000000) >= 0x08000000 && (address & 0x3F000000) < 0x08000000 + g_MemorySize) {111// More RAM (remasters, etc.)112var = *((const T*)GetPointerUnchecked(address));113} else {114static bool reported = false;115if (!reported) {116Reporting::ReportMessage("ReadFromHardware: Invalid address %08x near PC %08x LR %08x", address, currentMIPS->pc, currentMIPS->r[MIPS_REG_RA]);117reported = true;118}119Core_MemoryException(address, sizeof(T), currentMIPS->pc, MemoryExceptionType::READ_WORD);120var = 0;121}122}123124template <typename T>125inline void WriteToHardware(u32 address, const T data) {126if ((address & 0x3E000000) == 0x08000000) {127// RAM128*(T*)GetPointerUnchecked(address) = data;129} else if ((address & 0x3F800000) == 0x04000000) {130// VRAM131*(T*)GetPointerUnchecked(address) = data;132} else if ((address & 0xBFFFC000) == 0x00010000) {133// Scratchpad134*(T*)GetPointerUnchecked(address) = data;135} else if ((address & 0x3F000000) >= 0x08000000 && (address & 0x3F000000) < 0x08000000 + g_MemorySize) {136// More RAM (remasters, etc.)137*(T*)GetPointerUnchecked(address) = data;138} else {139static bool reported = false;140if (!reported) {141Reporting::ReportMessage("WriteToHardware: Invalid address %08x near PC %08x LR %08x", address, currentMIPS->pc, currentMIPS->r[MIPS_REG_RA]);142reported = true;143}144Core_MemoryException(address, sizeof(T), currentMIPS->pc, MemoryExceptionType::WRITE_WORD);145}146}147148bool IsRAMAddress(const u32 address) {149if ((address & 0x3E000000) == 0x08000000) {150return true;151} else if ((address & 0x3F000000) >= 0x08000000 && (address & 0x3F000000) < 0x08000000 + g_MemorySize) {152return true;153} else {154return false;155}156}157158bool IsScratchpadAddress(const u32 address) {159return (address & 0xBFFFC000) == 0x00010000;160}161162u8 Read_U8(const u32 address) {163u8 value = 0;164ReadFromHardware<u8>(value, address);165return (u8)value;166}167168u16 Read_U16(const u32 address) {169u16_le value = 0;170ReadFromHardware<u16_le>(value, address);171return (u16)value;172}173174u32 Read_U32(const u32 address) {175u32_le value = 0;176ReadFromHardware<u32_le>(value, address);177return value;178}179180u64 Read_U64(const u32 address) {181u64_le value = 0;182ReadFromHardware<u64_le>(value, address);183return value;184}185186u32 Read_U8_ZX(const u32 address) {187return (u32)Read_U8(address);188}189190u32 Read_U16_ZX(const u32 address) {191return (u32)Read_U16(address);192}193194void Write_U8(const u8 _Data, const u32 address) {195WriteToHardware<u8>(address, _Data);196}197198void Write_U16(const u16 _Data, const u32 address) {199WriteToHardware<u16_le>(address, _Data);200}201202void Write_U32(const u32 _Data, const u32 address) {203WriteToHardware<u32_le>(address, _Data);204}205206void Write_U64(const u64 _Data, const u32 address) {207WriteToHardware<u64_le>(address, _Data);208}209210} // namespace Memory211212213