2010-06-12 02:02:06 +00:00
|
|
|
#include "stdafx.h"
|
2016-01-13 15:21:58 +00:00
|
|
|
|
2022-01-04 05:41:52 +00:00
|
|
|
#include <Project64-core\N64System\Mips\MemoryVirtualMem.h>
|
|
|
|
#include <Project64-core\N64System\SystemGlobals.h>
|
|
|
|
#include <Project64-core\N64System\N64Rom.h>
|
|
|
|
#include <Project64-core\N64System\N64System.h>
|
|
|
|
#include <Project64-core\N64System\Recompiler\RecompilerCodeLog.h>
|
|
|
|
#include <Project64-core\N64System\Mips\OpcodeName.h>
|
|
|
|
#include <Project64-core\N64System\Mips\Disk.h>
|
|
|
|
#include <Project64-core\ExceptionHandler.h>
|
2016-01-13 15:01:40 +00:00
|
|
|
|
|
|
|
#include <stdio.h>
|
2016-01-13 11:52:21 +00:00
|
|
|
#include <Common/MemoryManagement.h>
|
2010-06-12 02:02:06 +00:00
|
|
|
|
2021-04-12 11:35:39 +00:00
|
|
|
uint8_t * CMipsMemoryVM::m_Reserve1 = nullptr;
|
|
|
|
uint8_t * CMipsMemoryVM::m_Reserve2 = nullptr;
|
2015-12-21 09:45:08 +00:00
|
|
|
uint32_t CMipsMemoryVM::m_MemLookupAddress = 0;
|
|
|
|
MIPS_DWORD CMipsMemoryVM::m_MemLookupValue;
|
|
|
|
bool CMipsMemoryVM::m_MemLookupValid = true;
|
2016-06-29 13:40:36 +00:00
|
|
|
uint32_t CMipsMemoryVM::RegModValue;
|
2015-11-08 18:04:32 +00:00
|
|
|
|
2016-01-13 11:52:21 +00:00
|
|
|
#pragma warning(disable:4355) // Disable 'this' : used in base member initializer list
|
2015-11-08 18:04:32 +00:00
|
|
|
|
2022-01-24 12:43:10 +00:00
|
|
|
CMipsMemoryVM::CMipsMemoryVM(CN64System & System, CRegisters & Reg, bool SavesReadOnly) :
|
2016-07-04 09:05:09 +00:00
|
|
|
CPifRam(SavesReadOnly),
|
|
|
|
CFlashram(SavesReadOnly),
|
|
|
|
CSram(SavesReadOnly),
|
|
|
|
CDMA(*this, *this),
|
2022-01-04 05:41:52 +00:00
|
|
|
m_Reg(Reg),
|
2022-02-21 09:17:14 +00:00
|
|
|
m_RDRAMRegistersHandler(Reg),
|
2016-07-04 09:05:09 +00:00
|
|
|
m_RomMapped(false),
|
2022-02-21 11:26:25 +00:00
|
|
|
m_DPCommandRegistersHandler(System, System.GetPlugins(), Reg),
|
2022-03-04 12:23:30 +00:00
|
|
|
m_MIPSInterfaceHandler(Reg),
|
2022-01-04 21:44:03 +00:00
|
|
|
m_PeripheralInterfaceHandler(*this, Reg),
|
2022-01-04 05:41:52 +00:00
|
|
|
m_RDRAMInterfaceHandler(Reg),
|
2022-01-24 12:43:10 +00:00
|
|
|
m_SPRegistersHandler(System, *this, Reg),
|
2021-04-12 11:35:39 +00:00
|
|
|
m_Rom(nullptr),
|
2016-07-04 09:05:09 +00:00
|
|
|
m_RomSize(0),
|
|
|
|
m_RomWrittenTo(false),
|
|
|
|
m_RomWroteValue(0),
|
|
|
|
m_HalfLine(0),
|
|
|
|
m_HalfLineCheck(false),
|
|
|
|
m_FieldSerration(0),
|
2021-04-12 11:35:39 +00:00
|
|
|
m_TLB_ReadMap(nullptr),
|
|
|
|
m_TLB_WriteMap(nullptr),
|
|
|
|
m_RDRAM(nullptr),
|
|
|
|
m_DMEM(nullptr),
|
|
|
|
m_IMEM(nullptr),
|
2017-01-03 05:38:44 +00:00
|
|
|
m_DDRomMapped(false),
|
2021-04-12 11:35:39 +00:00
|
|
|
m_DDRom(nullptr),
|
2017-01-03 05:38:44 +00:00
|
|
|
m_DDRomSize(0)
|
2015-11-08 18:04:32 +00:00
|
|
|
{
|
|
|
|
g_Settings->RegisterChangeCB(Game_RDRamSize, this, (CSettings::SettingChangedFunc)RdramChanged);
|
2010-06-12 02:02:06 +00:00
|
|
|
}
|
|
|
|
|
2015-11-08 18:04:32 +00:00
|
|
|
uint32_t swap32by8(uint32_t word)
|
2015-08-31 02:56:21 +00:00
|
|
|
{
|
2015-10-26 17:09:38 +00:00
|
|
|
const uint32_t swapped =
|
2015-08-31 02:56:21 +00:00
|
|
|
#if defined(_MSC_VER)
|
|
|
|
_byteswap_ulong(word)
|
|
|
|
#elif defined(__GNUC__)
|
|
|
|
__builtin_bswap32(word)
|
|
|
|
#else
|
|
|
|
(word & 0x000000FFul) << 24
|
2017-05-04 08:19:05 +00:00
|
|
|
| (word & 0x0000FF00ul) << 8
|
|
|
|
| (word & 0x00FF0000ul) >> 8
|
2015-11-08 18:04:32 +00:00
|
|
|
| (word & 0xFF000000ul) >> 24
|
2015-08-31 02:56:21 +00:00
|
|
|
#endif
|
2015-11-08 18:04:32 +00:00
|
|
|
;
|
2015-08-31 02:56:21 +00:00
|
|
|
return (swapped & 0xFFFFFFFFul);
|
|
|
|
}
|
|
|
|
|
2015-04-28 22:19:02 +00:00
|
|
|
CMipsMemoryVM::~CMipsMemoryVM()
|
2010-06-12 02:02:06 +00:00
|
|
|
{
|
2015-11-08 18:04:32 +00:00
|
|
|
g_Settings->UnregisterChangeCB(Game_RDRamSize, this, (CSettings::SettingChangedFunc)RdramChanged);
|
|
|
|
FreeMemory();
|
2010-06-12 02:02:06 +00:00
|
|
|
}
|
|
|
|
|
2015-11-08 18:04:32 +00:00
|
|
|
void CMipsMemoryVM::Reset(bool /*EraseMemory*/)
|
2010-06-14 21:14:58 +00:00
|
|
|
{
|
2015-11-08 18:04:32 +00:00
|
|
|
if (m_TLB_ReadMap)
|
|
|
|
{
|
|
|
|
size_t address;
|
|
|
|
|
|
|
|
memset(m_TLB_ReadMap, 0, 0xFFFFF * sizeof(size_t));
|
|
|
|
memset(m_TLB_WriteMap, 0, 0xFFFFF * sizeof(size_t));
|
|
|
|
for (address = 0x80000000; address < 0xC0000000; address += 0x1000)
|
|
|
|
{
|
|
|
|
m_TLB_ReadMap[address >> 12] = ((size_t)m_RDRAM + (address & 0x1FFFFFFF)) - address;
|
|
|
|
m_TLB_WriteMap[address >> 12] = ((size_t)m_RDRAM + (address & 0x1FFFFFFF)) - address;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (g_Settings->LoadDword(Rdb_TLB_VAddrStart) != 0)
|
|
|
|
{
|
|
|
|
size_t Start = g_Settings->LoadDword(Rdb_TLB_VAddrStart); //0x7F000000;
|
|
|
|
size_t Len = g_Settings->LoadDword(Rdb_TLB_VAddrLen); //0x01000000;
|
|
|
|
size_t PAddr = g_Settings->LoadDword(Rdb_TLB_PAddrStart); //0x10034b30;
|
|
|
|
size_t End = Start + Len;
|
|
|
|
for (address = Start; address < End; address += 0x1000)
|
|
|
|
{
|
|
|
|
m_TLB_ReadMap[address >> 12] = ((size_t)m_RDRAM + (address - Start + PAddr)) - address;
|
|
|
|
m_TLB_WriteMap[address >> 12] = ((size_t)m_RDRAM + (address - Start + PAddr)) - address;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2010-06-14 21:14:58 +00:00
|
|
|
}
|
|
|
|
|
2015-04-28 22:19:02 +00:00
|
|
|
void CMipsMemoryVM::ReserveMemory()
|
2012-12-18 10:43:29 +00:00
|
|
|
{
|
2017-08-22 08:08:54 +00:00
|
|
|
m_Reserve1 = (uint8_t *)AllocateAddressSpace(0x20000000, (void *)g_Settings->LoadDword(Setting_FixedRdramAddress));
|
2017-05-04 08:19:05 +00:00
|
|
|
m_Reserve2 = (uint8_t *)AllocateAddressSpace(0x04002000);
|
2012-12-18 10:43:29 +00:00
|
|
|
}
|
|
|
|
|
2015-04-28 22:19:02 +00:00
|
|
|
void CMipsMemoryVM::FreeReservedMemory()
|
2012-12-18 10:43:29 +00:00
|
|
|
{
|
2015-11-08 18:04:32 +00:00
|
|
|
if (m_Reserve1)
|
|
|
|
{
|
2016-01-13 11:52:21 +00:00
|
|
|
FreeAddressSpace(m_Reserve1, 0x20000000);
|
2021-04-12 11:35:39 +00:00
|
|
|
m_Reserve1 = nullptr;
|
2015-11-08 18:04:32 +00:00
|
|
|
}
|
|
|
|
if (m_Reserve2)
|
|
|
|
{
|
2016-01-13 11:52:21 +00:00
|
|
|
FreeAddressSpace(m_Reserve2, 0x20000000);
|
2021-04-12 11:35:39 +00:00
|
|
|
m_Reserve2 = nullptr;
|
2015-11-08 18:04:32 +00:00
|
|
|
}
|
2012-12-18 10:43:29 +00:00
|
|
|
}
|
|
|
|
|
2017-04-30 04:35:47 +00:00
|
|
|
bool CMipsMemoryVM::Initialize(bool SyncSystem)
|
2010-06-12 02:02:06 +00:00
|
|
|
{
|
2021-04-12 11:35:39 +00:00
|
|
|
if (m_RDRAM != nullptr)
|
2015-11-08 18:04:32 +00:00
|
|
|
{
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2021-04-12 11:35:39 +00:00
|
|
|
if (!SyncSystem && m_RDRAM == nullptr && m_Reserve1 != nullptr)
|
2015-11-08 18:04:32 +00:00
|
|
|
{
|
2016-09-23 22:40:58 +00:00
|
|
|
m_RDRAM = m_Reserve1;
|
2021-04-12 11:35:39 +00:00
|
|
|
m_Reserve1 = nullptr;
|
2015-11-08 18:04:32 +00:00
|
|
|
}
|
2021-04-12 11:35:39 +00:00
|
|
|
if (SyncSystem && m_RDRAM == nullptr && m_Reserve2 != nullptr)
|
2015-11-08 18:04:32 +00:00
|
|
|
{
|
2016-09-23 22:40:58 +00:00
|
|
|
m_RDRAM = m_Reserve2;
|
2021-04-12 11:35:39 +00:00
|
|
|
m_Reserve2 = nullptr;
|
2015-11-08 18:04:32 +00:00
|
|
|
}
|
2021-04-12 11:35:39 +00:00
|
|
|
if (m_RDRAM == nullptr)
|
2015-11-08 18:04:32 +00:00
|
|
|
{
|
2016-01-13 11:52:21 +00:00
|
|
|
m_RDRAM = (uint8_t *)AllocateAddressSpace(0x20000000);
|
2015-11-08 18:04:32 +00:00
|
|
|
}
|
2021-04-12 11:35:39 +00:00
|
|
|
if (m_RDRAM == nullptr)
|
2015-11-08 18:04:32 +00:00
|
|
|
{
|
2021-05-18 11:51:36 +00:00
|
|
|
WriteTrace(TraceN64System, TraceError, "Failed to reserve RDRAM (Size: 0x%X)", 0x20000000);
|
2015-11-08 18:04:32 +00:00
|
|
|
FreeMemory();
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
m_AllocatedRdramSize = g_Settings->LoadDword(Game_RDRamSize);
|
2021-04-12 11:35:39 +00:00
|
|
|
if (CommitMemory(m_RDRAM, m_AllocatedRdramSize, MEM_READWRITE) == nullptr)
|
2015-11-08 18:04:32 +00:00
|
|
|
{
|
2021-05-18 11:51:36 +00:00
|
|
|
WriteTrace(TraceN64System, TraceError, "Failed to allocate RDRAM (Size: 0x%X)", m_AllocatedRdramSize);
|
2015-11-08 18:04:32 +00:00
|
|
|
FreeMemory();
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2021-04-12 11:35:39 +00:00
|
|
|
if (CommitMemory(m_RDRAM + 0x04000000, 0x2000, MEM_READWRITE) == nullptr)
|
2015-11-08 18:04:32 +00:00
|
|
|
{
|
2021-05-18 11:51:36 +00:00
|
|
|
WriteTrace(TraceN64System, TraceError, "Failed to allocate DMEM/IMEM (Size: 0x%X)", 0x2000);
|
2015-11-08 18:04:32 +00:00
|
|
|
FreeMemory();
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
m_DMEM = (uint8_t *)(m_RDRAM + 0x04000000);
|
|
|
|
m_IMEM = (uint8_t *)(m_RDRAM + 0x04001000);
|
|
|
|
|
|
|
|
if (g_Settings->LoadBool(Game_LoadRomToMemory))
|
|
|
|
{
|
|
|
|
m_RomMapped = true;
|
|
|
|
m_Rom = m_RDRAM + 0x10000000;
|
|
|
|
m_RomSize = g_Rom->GetRomSize();
|
2021-04-12 11:35:39 +00:00
|
|
|
if (CommitMemory(m_Rom, g_Rom->GetRomSize(), MEM_READWRITE) == nullptr)
|
2015-11-08 18:04:32 +00:00
|
|
|
{
|
2021-05-18 11:51:36 +00:00
|
|
|
WriteTrace(TraceN64System, TraceError, "Failed to allocate ROM (Size: 0x%X)", g_Rom->GetRomSize());
|
2015-11-08 18:04:32 +00:00
|
|
|
FreeMemory();
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
memcpy(m_Rom, g_Rom->GetRomAddress(), g_Rom->GetRomSize());
|
|
|
|
|
2016-01-13 11:52:21 +00:00
|
|
|
::ProtectMemory(m_Rom, g_Rom->GetRomSize(), MEM_READONLY);
|
2015-11-08 18:04:32 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
m_RomMapped = false;
|
|
|
|
m_Rom = g_Rom->GetRomAddress();
|
|
|
|
m_RomSize = g_Rom->GetRomSize();
|
|
|
|
}
|
2016-01-18 19:15:01 +00:00
|
|
|
|
2021-05-18 11:51:36 +00:00
|
|
|
// 64DD IPL
|
2021-04-12 11:35:39 +00:00
|
|
|
if (g_DDRom != nullptr)
|
2016-01-18 19:15:01 +00:00
|
|
|
{
|
|
|
|
if (g_Settings->LoadBool(Game_LoadRomToMemory))
|
|
|
|
{
|
|
|
|
m_DDRomMapped = true;
|
|
|
|
m_DDRom = m_RDRAM + 0x06000000;
|
|
|
|
m_DDRomSize = g_DDRom->GetRomSize();
|
2021-04-12 11:35:39 +00:00
|
|
|
if (CommitMemory(m_DDRom, g_DDRom->GetRomSize(), MEM_READWRITE) == nullptr)
|
2016-01-18 19:15:01 +00:00
|
|
|
{
|
2021-05-18 11:51:36 +00:00
|
|
|
WriteTrace(TraceN64System, TraceError, "Failed to allocate ROM (Size: 0x%X)", g_DDRom->GetRomSize());
|
2016-01-18 19:15:01 +00:00
|
|
|
FreeMemory();
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
memcpy(m_DDRom, g_DDRom->GetRomAddress(), g_DDRom->GetRomSize());
|
|
|
|
|
|
|
|
::ProtectMemory(m_DDRom, g_DDRom->GetRomSize(), MEM_READONLY);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
m_DDRomMapped = false;
|
|
|
|
m_DDRom = g_DDRom->GetRomAddress();
|
|
|
|
m_DDRomSize = g_DDRom->GetRomSize();
|
|
|
|
}
|
|
|
|
}
|
2016-06-30 08:12:48 +00:00
|
|
|
|
2015-11-08 18:04:32 +00:00
|
|
|
CPifRam::Reset();
|
|
|
|
|
2016-01-13 11:52:21 +00:00
|
|
|
m_TLB_ReadMap = new size_t[0x100000];
|
2021-04-12 11:35:39 +00:00
|
|
|
if (m_TLB_ReadMap == nullptr)
|
2015-11-08 18:04:32 +00:00
|
|
|
{
|
2021-05-18 11:51:36 +00:00
|
|
|
WriteTrace(TraceN64System, TraceError, "Failed to allocate m_TLB_ReadMap (Size: 0x%X)", 0x100000 * sizeof(size_t));
|
2015-11-08 18:04:32 +00:00
|
|
|
FreeMemory();
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2016-01-13 11:52:21 +00:00
|
|
|
m_TLB_WriteMap = new size_t[0x100000];
|
2021-04-12 11:35:39 +00:00
|
|
|
if (m_TLB_WriteMap == nullptr)
|
2015-11-08 18:04:32 +00:00
|
|
|
{
|
2021-05-18 11:51:36 +00:00
|
|
|
WriteTrace(TraceN64System, TraceError, "Failed to allocate m_TLB_WriteMap (Size: 0x%X)", 0xFFFFF * sizeof(size_t));
|
2015-11-08 18:04:32 +00:00
|
|
|
FreeMemory();
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
Reset(false);
|
|
|
|
return true;
|
2010-06-12 02:02:06 +00:00
|
|
|
}
|
|
|
|
|
2015-04-28 22:19:02 +00:00
|
|
|
void CMipsMemoryVM::FreeMemory()
|
2010-06-12 02:02:06 +00:00
|
|
|
{
|
2015-11-08 18:04:32 +00:00
|
|
|
if (m_RDRAM)
|
|
|
|
{
|
2016-01-13 11:52:21 +00:00
|
|
|
if (DecommitMemory(m_RDRAM, 0x20000000))
|
2015-11-08 18:04:32 +00:00
|
|
|
{
|
2021-04-12 11:35:39 +00:00
|
|
|
if (m_Reserve1 == nullptr)
|
2015-11-08 18:04:32 +00:00
|
|
|
{
|
|
|
|
m_Reserve1 = m_RDRAM;
|
|
|
|
}
|
2021-04-12 11:35:39 +00:00
|
|
|
else if (m_Reserve2 == nullptr)
|
2015-11-08 18:04:32 +00:00
|
|
|
{
|
|
|
|
m_Reserve2 = m_RDRAM;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2016-01-13 11:52:21 +00:00
|
|
|
FreeAddressSpace(m_RDRAM, 0x20000000);
|
2015-11-08 18:04:32 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2016-01-13 11:52:21 +00:00
|
|
|
FreeAddressSpace(m_RDRAM, 0x20000000);
|
2015-11-08 18:04:32 +00:00
|
|
|
}
|
2021-04-12 11:35:39 +00:00
|
|
|
m_RDRAM = nullptr;
|
|
|
|
m_IMEM = nullptr;
|
|
|
|
m_DMEM = nullptr;
|
2015-11-08 18:04:32 +00:00
|
|
|
}
|
|
|
|
if (m_TLB_ReadMap)
|
|
|
|
{
|
2016-01-13 11:52:21 +00:00
|
|
|
delete[] m_TLB_ReadMap;
|
2021-04-12 11:35:39 +00:00
|
|
|
m_TLB_ReadMap = nullptr;
|
2015-11-08 18:04:32 +00:00
|
|
|
}
|
|
|
|
if (m_TLB_WriteMap)
|
|
|
|
{
|
2016-01-13 11:52:21 +00:00
|
|
|
delete[] m_TLB_WriteMap;
|
2021-04-12 11:35:39 +00:00
|
|
|
m_TLB_WriteMap = nullptr;
|
2015-11-08 18:04:32 +00:00
|
|
|
}
|
|
|
|
CPifRam::Reset();
|
2010-06-12 02:02:06 +00:00
|
|
|
}
|
|
|
|
|
2015-11-08 18:04:32 +00:00
|
|
|
uint8_t * CMipsMemoryVM::Rdram()
|
2010-06-12 02:02:06 +00:00
|
|
|
{
|
2015-11-08 18:04:32 +00:00
|
|
|
return m_RDRAM;
|
2010-06-12 02:02:06 +00:00
|
|
|
}
|
|
|
|
|
2015-11-08 18:04:32 +00:00
|
|
|
uint32_t CMipsMemoryVM::RdramSize()
|
2010-06-12 02:02:06 +00:00
|
|
|
{
|
2015-11-08 18:04:32 +00:00
|
|
|
return m_AllocatedRdramSize;
|
2010-06-12 02:02:06 +00:00
|
|
|
}
|
|
|
|
|
2015-11-08 18:04:32 +00:00
|
|
|
uint8_t * CMipsMemoryVM::Dmem()
|
2010-06-12 02:02:06 +00:00
|
|
|
{
|
2015-11-08 18:04:32 +00:00
|
|
|
return m_DMEM;
|
2010-06-12 02:02:06 +00:00
|
|
|
}
|
|
|
|
|
2015-11-08 18:04:32 +00:00
|
|
|
uint8_t * CMipsMemoryVM::Imem()
|
2010-06-12 02:02:06 +00:00
|
|
|
{
|
2015-11-08 18:04:32 +00:00
|
|
|
return m_IMEM;
|
2010-06-12 02:02:06 +00:00
|
|
|
}
|
|
|
|
|
2015-11-08 18:04:32 +00:00
|
|
|
uint8_t * CMipsMemoryVM::PifRam()
|
2010-06-12 02:02:06 +00:00
|
|
|
{
|
2015-11-08 18:04:32 +00:00
|
|
|
return m_PifRam;
|
2010-06-12 02:02:06 +00:00
|
|
|
}
|
|
|
|
|
2018-12-09 04:26:11 +00:00
|
|
|
CSram* CMipsMemoryVM::GetSram(void)
|
|
|
|
{
|
|
|
|
return dynamic_cast<CSram*>(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
CFlashram* CMipsMemoryVM::GetFlashram()
|
|
|
|
{
|
|
|
|
return dynamic_cast<CFlashram*>(this);
|
|
|
|
}
|
|
|
|
|
2015-11-08 18:04:32 +00:00
|
|
|
bool CMipsMemoryVM::LB_VAddr(uint32_t VAddr, uint8_t& Value)
|
2010-06-12 02:02:06 +00:00
|
|
|
{
|
2015-11-08 18:04:32 +00:00
|
|
|
if (m_TLB_ReadMap[VAddr >> 12] == 0)
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
2015-05-02 22:14:19 +00:00
|
|
|
|
2015-11-08 18:04:32 +00:00
|
|
|
Value = *(uint8_t*)(m_TLB_ReadMap[VAddr >> 12] + (VAddr ^ 3));
|
|
|
|
return true;
|
2010-06-12 02:02:06 +00:00
|
|
|
}
|
|
|
|
|
2015-11-08 18:04:32 +00:00
|
|
|
bool CMipsMemoryVM::LH_VAddr(uint32_t VAddr, uint16_t& Value)
|
2010-06-12 02:02:06 +00:00
|
|
|
{
|
2015-11-08 18:04:32 +00:00
|
|
|
if (m_TLB_ReadMap[VAddr >> 12] == 0)
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
2015-05-02 22:14:19 +00:00
|
|
|
|
2015-11-08 18:04:32 +00:00
|
|
|
Value = *(uint16_t*)(m_TLB_ReadMap[VAddr >> 12] + (VAddr ^ 2));
|
|
|
|
return true;
|
2010-06-12 02:02:06 +00:00
|
|
|
}
|
|
|
|
|
2015-11-08 18:04:32 +00:00
|
|
|
bool CMipsMemoryVM::LW_VAddr(uint32_t VAddr, uint32_t& Value)
|
2010-06-12 02:02:06 +00:00
|
|
|
{
|
2015-11-08 18:04:32 +00:00
|
|
|
if (VAddr >= 0xA3F00000 && VAddr < 0xC0000000)
|
|
|
|
{
|
2015-12-05 03:31:16 +00:00
|
|
|
if ((VAddr & 0xFFFFE000ul) != 0xA4000000ul) // !(A4000000 <= addr < A4002000)
|
2015-11-08 18:04:32 +00:00
|
|
|
{
|
|
|
|
VAddr &= 0x1FFFFFFF;
|
|
|
|
LW_NonMemory(VAddr, &Value);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
uint8_t* BaseAddress = (uint8_t*)m_TLB_ReadMap[VAddr >> 12];
|
2021-04-12 11:35:39 +00:00
|
|
|
if (BaseAddress == nullptr)
|
2015-11-08 18:04:32 +00:00
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
Value = *(uint32_t*)(BaseAddress + VAddr);
|
|
|
|
|
|
|
|
// if (LookUpMode == FuncFind_ChangeMemory)
|
|
|
|
// {
|
2015-12-09 11:37:58 +00:00
|
|
|
// g_Notify->BreakPoint(__FILE__, __LINE__);
|
2015-11-08 18:04:32 +00:00
|
|
|
// if ( (Command.Hex >> 16) == 0x7C7C)
|
|
|
|
// {
|
|
|
|
// Command.Hex = OrigMem[(Command.Hex & 0xFFFF)].OriginalValue;
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
return true;
|
2010-06-12 02:02:06 +00:00
|
|
|
}
|
|
|
|
|
2015-11-08 18:04:32 +00:00
|
|
|
bool CMipsMemoryVM::LD_VAddr(uint32_t VAddr, uint64_t& Value)
|
2010-06-12 02:02:06 +00:00
|
|
|
{
|
2015-11-08 18:04:32 +00:00
|
|
|
if (m_TLB_ReadMap[VAddr >> 12] == 0)
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
*((uint32_t*)(&Value) + 1) = *(uint32_t*)(m_TLB_ReadMap[VAddr >> 12] + VAddr);
|
|
|
|
*((uint32_t*)(&Value) + 0) = *(uint32_t*)(m_TLB_ReadMap[VAddr >> 12] + VAddr + 4);
|
|
|
|
return true;
|
2010-06-12 02:02:06 +00:00
|
|
|
}
|
|
|
|
|
2015-11-08 18:04:32 +00:00
|
|
|
bool CMipsMemoryVM::LB_PAddr(uint32_t PAddr, uint8_t& Value)
|
2015-01-22 05:50:20 +00:00
|
|
|
{
|
2015-11-08 18:04:32 +00:00
|
|
|
if (PAddr < RdramSize())
|
|
|
|
{
|
|
|
|
Value = *(uint8_t*)(m_RDRAM + (PAddr ^ 3));
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (PAddr > 0x18000000)
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2015-12-09 11:37:58 +00:00
|
|
|
g_Notify->BreakPoint(__FILE__, __LINE__);
|
2015-11-08 18:04:32 +00:00
|
|
|
return false;
|
2015-01-22 05:50:20 +00:00
|
|
|
}
|
|
|
|
|
2015-11-08 18:04:32 +00:00
|
|
|
bool CMipsMemoryVM::LH_PAddr(uint32_t PAddr, uint16_t& Value)
|
2015-01-22 05:50:20 +00:00
|
|
|
{
|
2015-11-08 18:04:32 +00:00
|
|
|
if (PAddr < RdramSize())
|
|
|
|
{
|
|
|
|
Value = *(uint16_t*)(m_RDRAM + (PAddr ^ 2));
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (PAddr > 0x18000000)
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2015-12-09 11:37:58 +00:00
|
|
|
g_Notify->BreakPoint(__FILE__, __LINE__);
|
2015-11-08 18:04:32 +00:00
|
|
|
return false;
|
2015-01-22 05:50:20 +00:00
|
|
|
}
|
|
|
|
|
2015-11-08 18:04:32 +00:00
|
|
|
bool CMipsMemoryVM::LW_PAddr(uint32_t PAddr, uint32_t& Value)
|
2015-01-22 05:50:20 +00:00
|
|
|
{
|
2015-11-08 18:04:32 +00:00
|
|
|
if (PAddr < RdramSize())
|
|
|
|
{
|
|
|
|
Value = *(uint32_t*)(m_RDRAM + PAddr);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (PAddr > 0x18000000)
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2015-12-09 11:37:58 +00:00
|
|
|
g_Notify->BreakPoint(__FILE__, __LINE__);
|
2015-11-08 18:04:32 +00:00
|
|
|
return false;
|
2015-01-22 05:50:20 +00:00
|
|
|
}
|
|
|
|
|
2015-11-08 18:04:32 +00:00
|
|
|
bool CMipsMemoryVM::LD_PAddr(uint32_t PAddr, uint64_t& Value)
|
2015-01-22 05:50:20 +00:00
|
|
|
{
|
2015-11-08 18:04:32 +00:00
|
|
|
if (PAddr < RdramSize())
|
|
|
|
{
|
|
|
|
*((uint32_t*)(&Value) + 1) = *(uint32_t*)(m_RDRAM + PAddr);
|
|
|
|
*((uint32_t*)(&Value) + 0) = *(uint32_t*)(m_RDRAM + PAddr + 4);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (PAddr > 0x18000000)
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2015-12-09 11:37:58 +00:00
|
|
|
g_Notify->BreakPoint(__FILE__, __LINE__);
|
2015-11-08 18:04:32 +00:00
|
|
|
return false;
|
2015-01-22 05:50:20 +00:00
|
|
|
}
|
|
|
|
|
2015-11-08 18:04:32 +00:00
|
|
|
bool CMipsMemoryVM::SB_VAddr(uint32_t VAddr, uint8_t Value)
|
2010-06-12 02:02:06 +00:00
|
|
|
{
|
2015-11-08 18:04:32 +00:00
|
|
|
if (m_TLB_WriteMap[VAddr >> 12] == 0)
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
2015-05-02 22:14:19 +00:00
|
|
|
|
2015-11-08 18:04:32 +00:00
|
|
|
*(uint8_t*)(m_TLB_WriteMap[VAddr >> 12] + (VAddr ^ 3)) = Value;
|
|
|
|
return true;
|
2010-06-12 02:02:06 +00:00
|
|
|
}
|
|
|
|
|
2015-11-08 18:04:32 +00:00
|
|
|
bool CMipsMemoryVM::SH_VAddr(uint32_t VAddr, uint16_t Value)
|
2010-06-12 02:02:06 +00:00
|
|
|
{
|
2015-11-08 18:04:32 +00:00
|
|
|
if (m_TLB_WriteMap[VAddr >> 12] == 0)
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
2015-05-02 22:14:19 +00:00
|
|
|
|
2015-11-08 18:04:32 +00:00
|
|
|
*(uint16_t*)(m_TLB_WriteMap[VAddr >> 12] + (VAddr ^ 2)) = Value;
|
|
|
|
return true;
|
2010-06-12 02:02:06 +00:00
|
|
|
}
|
|
|
|
|
2015-11-08 18:04:32 +00:00
|
|
|
bool CMipsMemoryVM::SW_VAddr(uint32_t VAddr, uint32_t Value)
|
2010-06-12 02:02:06 +00:00
|
|
|
{
|
2015-11-08 18:04:32 +00:00
|
|
|
if (VAddr >= 0xA3F00000 && VAddr < 0xC0000000)
|
|
|
|
{
|
2016-05-15 10:19:15 +00:00
|
|
|
if ((VAddr & 0xFFFFE000ul) != 0xA4000000ul) // !(A4000000 <= addr < A4002000)
|
2015-11-08 18:04:32 +00:00
|
|
|
{
|
|
|
|
VAddr &= 0x1FFFFFFF;
|
|
|
|
SW_NonMemory(VAddr, Value);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (m_TLB_WriteMap[VAddr >> 12] == 0)
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
*(uint32_t*)(m_TLB_WriteMap[VAddr >> 12] + VAddr) = Value;
|
|
|
|
return true;
|
2010-06-12 02:02:06 +00:00
|
|
|
}
|
|
|
|
|
2015-11-08 18:04:32 +00:00
|
|
|
bool CMipsMemoryVM::SD_VAddr(uint32_t VAddr, uint64_t Value)
|
2010-06-12 02:02:06 +00:00
|
|
|
{
|
2015-11-08 18:04:32 +00:00
|
|
|
if (m_TLB_WriteMap[VAddr >> 12] == 0)
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
*(uint32_t*)(m_TLB_WriteMap[VAddr >> 12] + VAddr + 0) = *((uint32_t*)(&Value) + 1);
|
|
|
|
*(uint32_t*)(m_TLB_WriteMap[VAddr >> 12] + VAddr + 4) = *((uint32_t*)(&Value));
|
|
|
|
return true;
|
2010-06-12 02:02:06 +00:00
|
|
|
}
|
|
|
|
|
2015-11-08 18:04:32 +00:00
|
|
|
bool CMipsMemoryVM::SB_PAddr(uint32_t PAddr, uint8_t Value)
|
2015-01-22 05:50:20 +00:00
|
|
|
{
|
2015-11-08 18:04:32 +00:00
|
|
|
if (PAddr < RdramSize())
|
|
|
|
{
|
|
|
|
*(uint8_t*)(m_RDRAM + (PAddr ^ 3)) = Value;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (PAddr > 0x18000000)
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2015-12-09 11:37:58 +00:00
|
|
|
g_Notify->BreakPoint(__FILE__, __LINE__);
|
2015-11-08 18:04:32 +00:00
|
|
|
return false;
|
2015-01-22 05:50:20 +00:00
|
|
|
}
|
|
|
|
|
2015-11-08 18:04:32 +00:00
|
|
|
bool CMipsMemoryVM::SH_PAddr(uint32_t PAddr, uint16_t Value)
|
2015-01-22 05:50:20 +00:00
|
|
|
{
|
2015-11-08 18:04:32 +00:00
|
|
|
if (PAddr < RdramSize())
|
|
|
|
{
|
|
|
|
*(uint16_t*)(m_RDRAM + (PAddr ^ 2)) = Value;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (PAddr > 0x18000000)
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2015-12-09 11:37:58 +00:00
|
|
|
g_Notify->BreakPoint(__FILE__, __LINE__);
|
2015-11-08 18:04:32 +00:00
|
|
|
return false;
|
2015-01-22 05:50:20 +00:00
|
|
|
}
|
|
|
|
|
2015-11-08 18:04:32 +00:00
|
|
|
bool CMipsMemoryVM::SW_PAddr(uint32_t PAddr, uint32_t Value)
|
2015-01-22 05:50:20 +00:00
|
|
|
{
|
2015-11-08 18:04:32 +00:00
|
|
|
if (PAddr < RdramSize())
|
|
|
|
{
|
|
|
|
*(uint32_t*)(m_RDRAM + PAddr) = Value;
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (PAddr > 0x18000000)
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2015-12-09 11:37:58 +00:00
|
|
|
g_Notify->BreakPoint(__FILE__, __LINE__);
|
2015-11-08 18:04:32 +00:00
|
|
|
return false;
|
2015-01-22 05:50:20 +00:00
|
|
|
}
|
|
|
|
|
2015-11-08 18:04:32 +00:00
|
|
|
bool CMipsMemoryVM::SD_PAddr(uint32_t PAddr, uint64_t Value)
|
2015-01-22 05:50:20 +00:00
|
|
|
{
|
2015-11-08 18:04:32 +00:00
|
|
|
if (PAddr < RdramSize())
|
|
|
|
{
|
|
|
|
*(uint32_t*)(m_RDRAM + PAddr + 0) = *((uint32_t*)(&Value) + 1);
|
|
|
|
*(uint32_t*)(m_RDRAM + PAddr + 4) = *((uint32_t*)(&Value));
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (PAddr > 0x18000000)
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2015-12-09 11:37:58 +00:00
|
|
|
g_Notify->BreakPoint(__FILE__, __LINE__);
|
2015-11-08 18:04:32 +00:00
|
|
|
return false;
|
2015-01-22 05:50:20 +00:00
|
|
|
}
|
|
|
|
|
2015-11-08 18:04:32 +00:00
|
|
|
bool CMipsMemoryVM::ValidVaddr(uint32_t VAddr) const
|
2010-06-12 02:02:06 +00:00
|
|
|
{
|
2015-11-08 18:04:32 +00:00
|
|
|
return m_TLB_ReadMap[VAddr >> 12] != 0;
|
2010-06-12 02:02:06 +00:00
|
|
|
}
|
|
|
|
|
2015-11-08 18:04:32 +00:00
|
|
|
bool CMipsMemoryVM::VAddrToRealAddr(uint32_t VAddr, void * &RealAddress) const
|
2012-09-24 22:07:51 +00:00
|
|
|
{
|
2015-11-08 18:04:32 +00:00
|
|
|
if (m_TLB_ReadMap[VAddr >> 12] == 0)
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
RealAddress = (uint8_t *)(m_TLB_ReadMap[VAddr >> 12] + VAddr);
|
|
|
|
return true;
|
2012-09-24 22:07:51 +00:00
|
|
|
}
|
|
|
|
|
2015-11-08 18:04:32 +00:00
|
|
|
bool CMipsMemoryVM::TranslateVaddr(uint32_t VAddr, uint32_t &PAddr) const
|
2010-06-12 02:02:06 +00:00
|
|
|
{
|
2021-05-18 11:51:36 +00:00
|
|
|
// Change the virtual address to a physical address
|
2015-11-08 18:04:32 +00:00
|
|
|
if (m_TLB_ReadMap[VAddr >> 12] == 0)
|
|
|
|
{
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
PAddr = (uint32_t)((uint8_t *)(m_TLB_ReadMap[VAddr >> 12] + VAddr) - m_RDRAM);
|
|
|
|
return true;
|
2010-06-12 02:02:06 +00:00
|
|
|
}
|
|
|
|
|
2016-06-29 13:40:36 +00:00
|
|
|
bool CMipsMemoryVM::LB_NonMemory(uint32_t PAddr, uint32_t* Value, bool /*SignExtend*/)
|
2015-03-29 17:19:28 +00:00
|
|
|
{
|
2016-06-29 13:40:36 +00:00
|
|
|
if (PAddr < 0x800000)
|
|
|
|
{
|
|
|
|
*Value = 0;
|
|
|
|
return true;
|
|
|
|
}
|
2015-11-08 18:04:32 +00:00
|
|
|
|
2016-06-29 13:40:36 +00:00
|
|
|
if (PAddr >= 0x10000000 && PAddr < 0x16000000)
|
2015-11-08 18:04:32 +00:00
|
|
|
{
|
2016-06-29 13:40:36 +00:00
|
|
|
g_Notify->BreakPoint(__FILE__, __LINE__);
|
2015-11-08 18:04:32 +00:00
|
|
|
}
|
2016-06-29 13:40:36 +00:00
|
|
|
*Value = 0;
|
|
|
|
return true;
|
2017-08-22 08:08:54 +00:00
|
|
|
}
|
2015-11-08 18:04:32 +00:00
|
|
|
|
2016-06-29 13:40:36 +00:00
|
|
|
bool CMipsMemoryVM::LH_NonMemory(uint32_t PAddr, uint32_t* Value, bool/* SignExtend*/)
|
|
|
|
{
|
|
|
|
if (PAddr < 0x800000)
|
2015-11-08 18:04:32 +00:00
|
|
|
{
|
2016-06-29 13:40:36 +00:00
|
|
|
*Value = 0;
|
|
|
|
return true;
|
2015-11-08 18:04:32 +00:00
|
|
|
}
|
|
|
|
|
2016-06-29 13:40:36 +00:00
|
|
|
if (PAddr >= 0x10000000 && PAddr < 0x16000000)
|
2015-11-08 18:04:32 +00:00
|
|
|
{
|
2016-06-29 13:40:36 +00:00
|
|
|
g_Notify->BreakPoint(__FILE__, __LINE__);
|
2015-11-08 18:04:32 +00:00
|
|
|
}
|
2016-06-29 13:40:36 +00:00
|
|
|
*Value = 0;
|
|
|
|
return false;
|
2010-06-12 02:02:06 +00:00
|
|
|
}
|
|
|
|
|
2016-06-29 13:40:36 +00:00
|
|
|
bool CMipsMemoryVM::LW_NonMemory(uint32_t PAddr, uint32_t* Value)
|
2015-03-29 17:19:28 +00:00
|
|
|
{
|
2016-06-29 13:40:36 +00:00
|
|
|
m_MemLookupAddress = PAddr;
|
|
|
|
if (PAddr >= 0x10000000 && PAddr < 0x16000000)
|
|
|
|
{
|
|
|
|
Load32Rom();
|
2015-11-08 18:04:32 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
switch (PAddr & 0xFFF00000)
|
|
|
|
{
|
2022-02-21 09:17:14 +00:00
|
|
|
case 0x03F00000: m_RDRAMRegistersHandler.Read32(PAddr, m_MemLookupValue.UW[0]); break;
|
|
|
|
case 0x04000000: m_SPRegistersHandler.Read32(PAddr, m_MemLookupValue.UW[0]); break;
|
2022-02-21 11:26:25 +00:00
|
|
|
case 0x04100000: m_DPCommandRegistersHandler.Read32(PAddr, m_MemLookupValue.UW[0]); break;
|
2022-03-04 12:23:30 +00:00
|
|
|
case 0x04300000: m_MIPSInterfaceHandler.Read32(PAddr, m_MemLookupValue.UW[0]); break;
|
2016-06-29 13:40:36 +00:00
|
|
|
case 0x04400000: Load32VideoInterface(); break;
|
|
|
|
case 0x04500000: Load32AudioInterface(); break;
|
2022-01-04 21:44:03 +00:00
|
|
|
case 0x04600000: m_PeripheralInterfaceHandler.Read32(PAddr, m_MemLookupValue.UW[0]); break;
|
2022-01-04 05:41:52 +00:00
|
|
|
case 0x04700000: m_RDRAMInterfaceHandler.Read32(PAddr, m_MemLookupValue.UW[0]); break;
|
2016-06-29 13:40:36 +00:00
|
|
|
case 0x04800000: Load32SerialInterface(); break;
|
|
|
|
case 0x05000000: Load32CartridgeDomain2Address1(); break;
|
|
|
|
case 0x06000000: Load32CartridgeDomain1Address1(); break;
|
|
|
|
case 0x08000000: Load32CartridgeDomain2Address2(); break;
|
|
|
|
case 0x1FC00000: Load32PifRam(); break;
|
|
|
|
case 0x1FF00000: Load32CartridgeDomain1Address3(); break;
|
2015-11-08 18:04:32 +00:00
|
|
|
default:
|
2016-06-29 13:40:36 +00:00
|
|
|
m_MemLookupValue.UW[0] = PAddr & 0xFFFF;
|
|
|
|
m_MemLookupValue.UW[0] = (m_MemLookupValue.UW[0] << 16) | m_MemLookupValue.UW[0];
|
2015-11-08 18:04:32 +00:00
|
|
|
}
|
|
|
|
}
|
2016-06-29 13:40:36 +00:00
|
|
|
*Value = m_MemLookupValue.UW[0];
|
|
|
|
return true;
|
2017-08-22 08:08:54 +00:00
|
|
|
}
|
2010-06-12 02:02:06 +00:00
|
|
|
|
2016-06-29 13:40:36 +00:00
|
|
|
bool CMipsMemoryVM::SB_NonMemory(uint32_t PAddr, uint8_t Value)
|
2015-03-29 17:19:28 +00:00
|
|
|
{
|
2015-11-08 18:04:32 +00:00
|
|
|
switch (PAddr & 0xFFF00000)
|
|
|
|
{
|
|
|
|
case 0x00000000:
|
|
|
|
case 0x00100000:
|
|
|
|
case 0x00200000:
|
|
|
|
case 0x00300000:
|
|
|
|
case 0x00400000:
|
|
|
|
case 0x00500000:
|
|
|
|
case 0x00600000:
|
|
|
|
case 0x00700000:
|
2016-06-29 13:40:36 +00:00
|
|
|
if (PAddr < RdramSize())
|
2015-11-08 18:04:32 +00:00
|
|
|
{
|
2016-06-29 13:40:36 +00:00
|
|
|
g_Recompiler->ClearRecompCode_Phys(PAddr & ~0xFFF, 0xFFC, CRecompiler::Remove_ProtectedMem);
|
|
|
|
::ProtectMemory(m_RDRAM + (PAddr & ~0xFFF), 0xFFC, MEM_READWRITE);
|
|
|
|
*(uint8_t *)(m_RDRAM + PAddr) = Value;
|
2015-11-08 18:04:32 +00:00
|
|
|
}
|
2016-06-29 13:40:36 +00:00
|
|
|
break;
|
|
|
|
default:
|
|
|
|
return false;
|
2015-11-08 18:04:32 +00:00
|
|
|
}
|
|
|
|
|
2016-06-29 13:40:36 +00:00
|
|
|
return true;
|
2010-06-12 02:02:06 +00:00
|
|
|
}
|
|
|
|
|
2016-06-29 13:40:36 +00:00
|
|
|
bool CMipsMemoryVM::SH_NonMemory(uint32_t PAddr, uint16_t Value)
|
2010-06-16 07:31:47 +00:00
|
|
|
{
|
2016-06-29 13:40:36 +00:00
|
|
|
switch (PAddr & 0xFFF00000)
|
2015-11-08 18:04:32 +00:00
|
|
|
{
|
2016-06-29 13:40:36 +00:00
|
|
|
case 0x00000000:
|
|
|
|
case 0x00100000:
|
|
|
|
case 0x00200000:
|
|
|
|
case 0x00300000:
|
|
|
|
case 0x00400000:
|
|
|
|
case 0x00500000:
|
|
|
|
case 0x00600000:
|
|
|
|
case 0x00700000:
|
|
|
|
if (PAddr < RdramSize())
|
|
|
|
{
|
|
|
|
g_Recompiler->ClearRecompCode_Phys(PAddr & ~0xFFF, 0x1000, CRecompiler::Remove_ProtectedMem);
|
|
|
|
::ProtectMemory(m_RDRAM + (PAddr & ~0xFFF), 0xFFC, MEM_READWRITE);
|
|
|
|
*(uint16_t *)(m_RDRAM + PAddr) = Value;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
return false;
|
2015-11-08 18:04:32 +00:00
|
|
|
}
|
|
|
|
|
2016-06-29 13:40:36 +00:00
|
|
|
return true;
|
2010-06-16 07:31:47 +00:00
|
|
|
}
|
|
|
|
|
2016-06-29 13:40:36 +00:00
|
|
|
bool CMipsMemoryVM::SW_NonMemory(uint32_t PAddr, uint32_t Value)
|
2010-06-12 02:02:06 +00:00
|
|
|
{
|
2016-06-29 13:40:36 +00:00
|
|
|
m_MemLookupValue.UW[0] = Value;
|
|
|
|
m_MemLookupAddress = PAddr;
|
2015-11-08 18:04:32 +00:00
|
|
|
|
2016-06-29 13:40:36 +00:00
|
|
|
if (PAddr >= 0x10000000 && PAddr < 0x16000000)
|
2015-11-08 18:04:32 +00:00
|
|
|
{
|
2016-06-29 13:40:36 +00:00
|
|
|
if ((PAddr - 0x10000000) < g_Rom->GetRomSize())
|
2015-11-08 18:04:32 +00:00
|
|
|
{
|
2016-06-29 13:40:36 +00:00
|
|
|
m_RomWrittenTo = true;
|
|
|
|
m_RomWroteValue = Value;
|
2015-11-08 18:04:32 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2016-06-29 13:40:36 +00:00
|
|
|
return false;
|
2015-11-08 18:04:32 +00:00
|
|
|
}
|
2017-08-22 08:08:54 +00:00
|
|
|
}
|
2016-06-29 13:40:36 +00:00
|
|
|
|
|
|
|
switch (PAddr & 0xFFF00000)
|
2015-11-08 18:04:32 +00:00
|
|
|
{
|
2016-06-29 13:40:36 +00:00
|
|
|
case 0x00000000:
|
|
|
|
case 0x00100000:
|
|
|
|
case 0x00200000:
|
|
|
|
case 0x00300000:
|
|
|
|
case 0x00400000:
|
|
|
|
case 0x00500000:
|
|
|
|
case 0x00600000:
|
|
|
|
case 0x00700000:
|
|
|
|
if (PAddr < RdramSize())
|
2015-11-08 18:04:32 +00:00
|
|
|
{
|
2016-06-29 13:40:36 +00:00
|
|
|
g_Recompiler->ClearRecompCode_Phys(PAddr & ~0xFFF, 0x1000, CRecompiler::Remove_ProtectedMem);
|
|
|
|
::ProtectMemory(m_RDRAM + (PAddr & ~0xFFF), 0xFFC, MEM_READWRITE);
|
|
|
|
*(uint32_t *)(m_RDRAM + PAddr) = Value;
|
2015-11-08 18:04:32 +00:00
|
|
|
}
|
2016-06-29 13:40:36 +00:00
|
|
|
break;
|
2022-02-21 09:17:14 +00:00
|
|
|
case 0x03F00000: m_RDRAMRegistersHandler.Write32(PAddr, Value, 0xFFFFFFFF); break;
|
2016-06-29 13:40:36 +00:00
|
|
|
case 0x04000000:
|
|
|
|
if (PAddr < 0x04002000)
|
2015-11-08 18:04:32 +00:00
|
|
|
{
|
2016-06-29 13:40:36 +00:00
|
|
|
g_Recompiler->ClearRecompCode_Phys(PAddr & ~0xFFF, 0xFFF, CRecompiler::Remove_ProtectedMem);
|
|
|
|
*(uint32_t *)(m_RDRAM + PAddr) = Value;
|
2015-11-08 18:04:32 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2022-01-24 12:43:10 +00:00
|
|
|
m_SPRegistersHandler.Write32(PAddr, Value, 0xFFFFFFFF);
|
2015-11-08 18:04:32 +00:00
|
|
|
}
|
2016-06-29 13:40:36 +00:00
|
|
|
break;
|
2022-02-21 11:26:25 +00:00
|
|
|
case 0x04100000: m_DPCommandRegistersHandler.Write32(PAddr, Value, 0xFFFFFFFF); break;
|
2022-03-04 12:23:30 +00:00
|
|
|
case 0x04300000: m_MIPSInterfaceHandler.Write32(PAddr, Value, 0xFFFFFFFF); break;
|
2016-06-29 13:40:36 +00:00
|
|
|
case 0x04400000: Write32VideoInterface(); break;
|
|
|
|
case 0x04500000: Write32AudioInterface(); break;
|
2022-01-04 21:44:03 +00:00
|
|
|
case 0x04600000: m_PeripheralInterfaceHandler.Write32(PAddr, Value, 0xFFFFFFFF); break;
|
2022-01-04 05:41:52 +00:00
|
|
|
case 0x04700000: m_RDRAMInterfaceHandler.Write32(PAddr, Value, 0xFFFFFFFF); break;
|
2016-06-29 13:40:36 +00:00
|
|
|
case 0x04800000: Write32SerialInterface(); break;
|
|
|
|
case 0x05000000: Write32CartridgeDomain2Address1(); break;
|
|
|
|
case 0x08000000: Write32CartridgeDomain2Address2(); break;
|
|
|
|
case 0x1FC00000: Write32PifRam(); break;
|
|
|
|
default:
|
|
|
|
return false;
|
|
|
|
break;
|
2015-11-08 18:04:32 +00:00
|
|
|
}
|
2016-06-29 13:40:36 +00:00
|
|
|
|
|
|
|
return true;
|
2017-08-22 08:08:54 +00:00
|
|
|
}
|
2010-06-12 02:02:06 +00:00
|
|
|
|
2016-06-29 13:40:36 +00:00
|
|
|
void CMipsMemoryVM::UpdateHalfLine()
|
2010-06-12 02:02:06 +00:00
|
|
|
{
|
2016-06-29 13:40:36 +00:00
|
|
|
uint32_t NextViTimer = g_SystemTimer->GetTimer(CSystemTimer::ViTimer);
|
2015-11-08 18:04:32 +00:00
|
|
|
|
2016-06-29 13:40:36 +00:00
|
|
|
if (*g_NextTimer < 0)
|
2015-11-08 18:04:32 +00:00
|
|
|
{
|
2016-06-29 13:40:36 +00:00
|
|
|
m_HalfLine = 0;
|
2015-11-08 18:04:32 +00:00
|
|
|
return;
|
|
|
|
}
|
2016-06-29 13:40:36 +00:00
|
|
|
|
|
|
|
int32_t check_value = (int32_t)(m_HalfLineCheck - NextViTimer);
|
|
|
|
if (check_value > 0 && check_value < 40)
|
2015-11-08 18:04:32 +00:00
|
|
|
{
|
2016-06-29 13:40:36 +00:00
|
|
|
*g_NextTimer -= g_System->ViRefreshRate();
|
|
|
|
if (*g_NextTimer < 0)
|
2015-11-08 18:04:32 +00:00
|
|
|
{
|
2016-06-29 13:40:36 +00:00
|
|
|
*g_NextTimer = 0 - g_System->CountPerOp();
|
2015-11-08 18:04:32 +00:00
|
|
|
}
|
2016-06-29 13:40:36 +00:00
|
|
|
g_SystemTimer->UpdateTimers();
|
|
|
|
NextViTimer = g_SystemTimer->GetTimer(CSystemTimer::ViTimer);
|
2015-11-08 18:04:32 +00:00
|
|
|
}
|
2016-06-29 13:40:36 +00:00
|
|
|
m_HalfLine = (uint32_t)(*g_NextTimer / g_System->ViRefreshRate());
|
|
|
|
m_HalfLine &= ~1;
|
|
|
|
m_HalfLine |= m_FieldSerration;
|
|
|
|
g_Reg->VI_V_CURRENT_LINE_REG = m_HalfLine;
|
|
|
|
m_HalfLineCheck = NextViTimer;
|
2010-06-12 02:02:06 +00:00
|
|
|
}
|
|
|
|
|
2016-06-29 13:40:36 +00:00
|
|
|
void CMipsMemoryVM::UpdateFieldSerration(uint32_t interlaced)
|
2015-03-29 17:19:28 +00:00
|
|
|
{
|
2016-06-29 13:40:36 +00:00
|
|
|
m_FieldSerration ^= 1;
|
|
|
|
m_FieldSerration &= interlaced;
|
|
|
|
}
|
2010-06-22 20:36:28 +00:00
|
|
|
|
2016-06-29 13:40:36 +00:00
|
|
|
void CMipsMemoryVM::ProtectMemory(uint32_t StartVaddr, uint32_t EndVaddr)
|
|
|
|
{
|
|
|
|
WriteTrace(TraceProtectedMem, TraceDebug, "StartVaddr: %08X EndVaddr: %08X", StartVaddr, EndVaddr);
|
|
|
|
if (!ValidVaddr(StartVaddr) || !ValidVaddr(EndVaddr))
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
2015-05-02 22:14:19 +00:00
|
|
|
|
2021-05-18 11:51:36 +00:00
|
|
|
// Get physical addresses passed
|
2016-06-29 13:40:36 +00:00
|
|
|
uint32_t StartPAddr, EndPAddr;
|
|
|
|
if (!TranslateVaddr(StartVaddr, StartPAddr))
|
|
|
|
{
|
|
|
|
g_Notify->BreakPoint(__FILE__, __LINE__);
|
|
|
|
}
|
|
|
|
if (!TranslateVaddr(EndVaddr, EndPAddr))
|
2015-11-08 18:04:32 +00:00
|
|
|
{
|
2016-06-29 13:40:36 +00:00
|
|
|
g_Notify->BreakPoint(__FILE__, __LINE__);
|
2015-11-08 18:04:32 +00:00
|
|
|
}
|
2015-05-02 22:14:19 +00:00
|
|
|
|
2021-05-18 11:51:36 +00:00
|
|
|
// Get length of memory being protected
|
2016-06-29 13:40:36 +00:00
|
|
|
int32_t Length = ((EndPAddr + 3) - StartPAddr) & ~3;
|
|
|
|
if (Length < 0)
|
2015-11-08 18:04:32 +00:00
|
|
|
{
|
2016-06-29 13:40:36 +00:00
|
|
|
g_Notify->BreakPoint(__FILE__, __LINE__);
|
2015-11-08 18:04:32 +00:00
|
|
|
}
|
2015-05-02 22:14:19 +00:00
|
|
|
|
2021-05-18 11:51:36 +00:00
|
|
|
// Protect that memory address space
|
2016-06-29 13:40:36 +00:00
|
|
|
uint8_t * MemLoc = Rdram() + StartPAddr;
|
|
|
|
WriteTrace(TraceProtectedMem, TraceDebug, "Paddr: %08X Length: %X", StartPAddr, Length);
|
|
|
|
|
|
|
|
::ProtectMemory(MemLoc, Length, MEM_READONLY);
|
2010-06-12 02:02:06 +00:00
|
|
|
}
|
|
|
|
|
2016-06-29 13:40:36 +00:00
|
|
|
void CMipsMemoryVM::UnProtectMemory(uint32_t StartVaddr, uint32_t EndVaddr)
|
2015-03-29 17:19:28 +00:00
|
|
|
{
|
2016-06-29 13:40:36 +00:00
|
|
|
WriteTrace(TraceProtectedMem, TraceDebug, "StartVaddr: %08X EndVaddr: %08X", StartVaddr, EndVaddr);
|
|
|
|
if (!ValidVaddr(StartVaddr) || !ValidVaddr(EndVaddr)) { return; }
|
2015-05-02 22:14:19 +00:00
|
|
|
|
2021-05-18 11:51:36 +00:00
|
|
|
// Get physical addresses passed
|
2016-06-29 13:40:36 +00:00
|
|
|
uint32_t StartPAddr, EndPAddr;
|
|
|
|
if (!TranslateVaddr(StartVaddr, StartPAddr))
|
|
|
|
{
|
|
|
|
g_Notify->BreakPoint(__FILE__, __LINE__);
|
|
|
|
}
|
|
|
|
if (!TranslateVaddr(EndVaddr, EndPAddr))
|
2015-11-08 18:04:32 +00:00
|
|
|
{
|
2016-06-29 13:40:36 +00:00
|
|
|
g_Notify->BreakPoint(__FILE__, __LINE__);
|
2015-11-08 18:04:32 +00:00
|
|
|
}
|
2015-05-02 22:14:19 +00:00
|
|
|
|
2021-05-18 11:51:36 +00:00
|
|
|
// Get length of memory being protected
|
2016-06-29 13:40:36 +00:00
|
|
|
int32_t Length = ((EndPAddr + 3) - StartPAddr) & ~3;
|
|
|
|
if (Length < 0)
|
2015-11-08 18:04:32 +00:00
|
|
|
{
|
2016-06-29 13:40:36 +00:00
|
|
|
g_Notify->BreakPoint(__FILE__, __LINE__);
|
2015-11-08 18:04:32 +00:00
|
|
|
}
|
2015-05-02 22:14:19 +00:00
|
|
|
|
2016-06-29 13:40:36 +00:00
|
|
|
//Protect that memory address space
|
|
|
|
uint8_t * MemLoc = Rdram() + StartPAddr;
|
|
|
|
::ProtectMemory(MemLoc, Length, MEM_READWRITE);
|
2010-06-12 02:02:06 +00:00
|
|
|
}
|
|
|
|
|
2016-01-13 11:52:21 +00:00
|
|
|
const char * CMipsMemoryVM::LabelName(uint32_t Address) const
|
2010-06-12 02:02:06 +00:00
|
|
|
{
|
2015-11-08 18:04:32 +00:00
|
|
|
sprintf(m_strLabelName, "0x%08X", Address);
|
|
|
|
return m_strLabelName;
|
2010-06-12 02:02:06 +00:00
|
|
|
}
|
|
|
|
|
2015-11-08 18:04:32 +00:00
|
|
|
void CMipsMemoryVM::TLB_Mapped(uint32_t VAddr, uint32_t Len, uint32_t PAddr, bool bReadOnly)
|
2010-06-12 02:02:06 +00:00
|
|
|
{
|
2015-11-08 18:04:32 +00:00
|
|
|
size_t count, VEnd;
|
|
|
|
|
|
|
|
VEnd = VAddr + Len;
|
|
|
|
for (count = VAddr; count < VEnd; count += 0x1000)
|
|
|
|
{
|
|
|
|
size_t Index = count >> 12;
|
|
|
|
m_TLB_ReadMap[Index] = ((size_t)m_RDRAM + (count - VAddr + PAddr)) - count;
|
|
|
|
if (!bReadOnly)
|
|
|
|
{
|
|
|
|
m_TLB_WriteMap[Index] = ((size_t)m_RDRAM + (count - VAddr + PAddr)) - count;
|
|
|
|
}
|
|
|
|
}
|
2010-06-12 02:02:06 +00:00
|
|
|
}
|
|
|
|
|
2015-11-08 18:04:32 +00:00
|
|
|
void CMipsMemoryVM::TLB_Unmaped(uint32_t Vaddr, uint32_t Len)
|
2010-06-12 02:02:06 +00:00
|
|
|
{
|
2015-11-08 18:04:32 +00:00
|
|
|
size_t count, End;
|
|
|
|
|
|
|
|
End = Vaddr + Len;
|
|
|
|
for (count = Vaddr; count < End; count += 0x1000)
|
|
|
|
{
|
|
|
|
size_t Index = count >> 12;
|
2016-01-18 08:52:14 +00:00
|
|
|
m_TLB_ReadMap[Index] = 0;
|
|
|
|
m_TLB_WriteMap[Index] = 0;
|
2015-11-08 18:04:32 +00:00
|
|
|
}
|
2010-06-12 02:02:06 +00:00
|
|
|
}
|
|
|
|
|
2015-11-08 18:04:32 +00:00
|
|
|
void CMipsMemoryVM::RdramChanged(CMipsMemoryVM * _this)
|
2010-06-12 02:02:06 +00:00
|
|
|
{
|
2015-11-08 18:04:32 +00:00
|
|
|
const size_t new_size = g_Settings->LoadDword(Game_RDRamSize);
|
|
|
|
const size_t old_size = _this->m_AllocatedRdramSize;
|
|
|
|
|
|
|
|
if (old_size == new_size)
|
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (old_size > new_size)
|
|
|
|
{
|
2016-01-13 11:52:21 +00:00
|
|
|
DecommitMemory(_this->m_RDRAM + new_size, old_size - new_size);
|
2015-11-08 18:04:32 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2016-01-13 11:52:21 +00:00
|
|
|
void * result = CommitMemory(_this->m_RDRAM + old_size, new_size - old_size, MEM_READWRITE);
|
2021-04-12 11:35:39 +00:00
|
|
|
if (result == nullptr)
|
2015-11-08 18:04:32 +00:00
|
|
|
{
|
2021-05-18 11:51:36 +00:00
|
|
|
WriteTrace(TraceN64System, TraceError, "Failed to allocate extended memory");
|
2015-11-08 18:04:32 +00:00
|
|
|
g_Notify->FatalError(GS(MSG_MEM_ALLOC_ERROR));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (new_size > 0xFFFFFFFFul)
|
2021-05-18 11:51:36 +00:00
|
|
|
{ // Should be unreachable because: size_t new_size = g_Settings->(uint32_t)
|
2015-12-09 11:37:58 +00:00
|
|
|
g_Notify->BreakPoint(__FILE__, __LINE__);
|
2021-05-18 11:51:36 +00:00
|
|
|
} // However, FFFFFFFF also is a limit to RCP addressing, so we care
|
2015-11-08 18:04:32 +00:00
|
|
|
_this->m_AllocatedRdramSize = (uint32_t)new_size;
|
2010-06-12 02:02:06 +00:00
|
|
|
}
|
|
|
|
|
2015-04-28 22:19:02 +00:00
|
|
|
void CMipsMemoryVM::ChangeSpStatus()
|
2010-06-12 02:02:06 +00:00
|
|
|
{
|
2015-11-08 18:04:32 +00:00
|
|
|
if ((RegModValue & SP_CLR_HALT) != 0)
|
|
|
|
{
|
|
|
|
g_Reg->SP_STATUS_REG &= ~SP_STATUS_HALT;
|
|
|
|
}
|
|
|
|
if ((RegModValue & SP_SET_HALT) != 0)
|
|
|
|
{
|
|
|
|
g_Reg->SP_STATUS_REG |= SP_STATUS_HALT;
|
|
|
|
}
|
|
|
|
if ((RegModValue & SP_CLR_BROKE) != 0)
|
|
|
|
{
|
|
|
|
g_Reg->SP_STATUS_REG &= ~SP_STATUS_BROKE;
|
|
|
|
}
|
|
|
|
if ((RegModValue & SP_CLR_INTR) != 0)
|
|
|
|
{
|
|
|
|
g_Reg->MI_INTR_REG &= ~MI_INTR_SP;
|
|
|
|
g_Reg->m_RspIntrReg &= ~MI_INTR_SP;
|
|
|
|
g_Reg->CheckInterrupts();
|
|
|
|
}
|
2018-01-15 21:23:21 +00:00
|
|
|
if ((RegModValue & SP_SET_INTR) != 0 && HaveDebugger())
|
2015-11-08 18:04:32 +00:00
|
|
|
{
|
2015-12-23 20:04:36 +00:00
|
|
|
g_Notify->DisplayError("SP_SET_INTR");
|
2015-11-08 18:04:32 +00:00
|
|
|
}
|
|
|
|
if ((RegModValue & SP_CLR_SSTEP) != 0)
|
|
|
|
{
|
|
|
|
g_Reg->SP_STATUS_REG &= ~SP_STATUS_SSTEP;
|
|
|
|
}
|
|
|
|
if ((RegModValue & SP_SET_SSTEP) != 0)
|
|
|
|
{
|
|
|
|
g_Reg->SP_STATUS_REG |= SP_STATUS_SSTEP;
|
|
|
|
}
|
|
|
|
if ((RegModValue & SP_CLR_INTR_BREAK) != 0)
|
|
|
|
{
|
|
|
|
g_Reg->SP_STATUS_REG &= ~SP_STATUS_INTR_BREAK;
|
|
|
|
}
|
|
|
|
if ((RegModValue & SP_SET_INTR_BREAK) != 0)
|
|
|
|
{
|
|
|
|
g_Reg->SP_STATUS_REG |= SP_STATUS_INTR_BREAK;
|
|
|
|
}
|
|
|
|
if ((RegModValue & SP_CLR_SIG0) != 0)
|
|
|
|
{
|
|
|
|
g_Reg->SP_STATUS_REG &= ~SP_STATUS_SIG0;
|
|
|
|
}
|
|
|
|
if ((RegModValue & SP_SET_SIG0) != 0)
|
|
|
|
{
|
|
|
|
g_Reg->SP_STATUS_REG |= SP_STATUS_SIG0;
|
|
|
|
}
|
|
|
|
if ((RegModValue & SP_CLR_SIG1) != 0)
|
|
|
|
{
|
|
|
|
g_Reg->SP_STATUS_REG &= ~SP_STATUS_SIG1;
|
|
|
|
}
|
|
|
|
if ((RegModValue & SP_SET_SIG1) != 0)
|
|
|
|
{
|
|
|
|
g_Reg->SP_STATUS_REG |= SP_STATUS_SIG1;
|
|
|
|
}
|
|
|
|
if ((RegModValue & SP_CLR_SIG2) != 0)
|
|
|
|
{
|
|
|
|
g_Reg->SP_STATUS_REG &= ~SP_STATUS_SIG2;
|
|
|
|
}
|
|
|
|
if ((RegModValue & SP_SET_SIG2) != 0)
|
|
|
|
{
|
|
|
|
g_Reg->SP_STATUS_REG |= SP_STATUS_SIG2;
|
|
|
|
}
|
|
|
|
if ((RegModValue & SP_CLR_SIG3) != 0)
|
|
|
|
{
|
|
|
|
g_Reg->SP_STATUS_REG &= ~SP_STATUS_SIG3;
|
|
|
|
}
|
|
|
|
if ((RegModValue & SP_SET_SIG3) != 0)
|
|
|
|
{
|
|
|
|
g_Reg->SP_STATUS_REG |= SP_STATUS_SIG3;
|
|
|
|
}
|
|
|
|
if ((RegModValue & SP_CLR_SIG4) != 0)
|
|
|
|
{
|
|
|
|
g_Reg->SP_STATUS_REG &= ~SP_STATUS_SIG4;
|
|
|
|
}
|
|
|
|
if ((RegModValue & SP_SET_SIG4) != 0)
|
|
|
|
{
|
|
|
|
g_Reg->SP_STATUS_REG |= SP_STATUS_SIG4;
|
|
|
|
}
|
|
|
|
if ((RegModValue & SP_CLR_SIG5) != 0)
|
|
|
|
{
|
|
|
|
g_Reg->SP_STATUS_REG &= ~SP_STATUS_SIG5;
|
|
|
|
}
|
|
|
|
if ((RegModValue & SP_SET_SIG5) != 0)
|
|
|
|
{
|
|
|
|
g_Reg->SP_STATUS_REG |= SP_STATUS_SIG5;
|
|
|
|
}
|
|
|
|
if ((RegModValue & SP_CLR_SIG6) != 0)
|
|
|
|
{
|
|
|
|
g_Reg->SP_STATUS_REG &= ~SP_STATUS_SIG6;
|
|
|
|
}
|
|
|
|
if ((RegModValue & SP_SET_SIG6) != 0)
|
|
|
|
{
|
|
|
|
g_Reg->SP_STATUS_REG |= SP_STATUS_SIG6;
|
|
|
|
}
|
|
|
|
if ((RegModValue & SP_CLR_SIG7) != 0)
|
|
|
|
{
|
|
|
|
g_Reg->SP_STATUS_REG &= ~SP_STATUS_SIG7;
|
|
|
|
}
|
|
|
|
if ((RegModValue & SP_SET_SIG7) != 0)
|
|
|
|
{
|
|
|
|
g_Reg->SP_STATUS_REG |= SP_STATUS_SIG7;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((RegModValue & SP_SET_SIG0) != 0 && g_System->RspAudioSignal())
|
|
|
|
{
|
|
|
|
g_Reg->MI_INTR_REG |= MI_INTR_SP;
|
|
|
|
g_Reg->CheckInterrupts();
|
|
|
|
}
|
|
|
|
//if (*( uint32_t *)(DMEM + 0xFC0) == 1)
|
|
|
|
//{
|
|
|
|
// ChangeTimer(RspTimer,0x40000);
|
|
|
|
//}
|
|
|
|
//else
|
|
|
|
//{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
g_System->RunRSP();
|
|
|
|
}
|
|
|
|
catch (...)
|
|
|
|
{
|
2015-12-09 11:37:58 +00:00
|
|
|
g_Notify->BreakPoint(__FILE__, __LINE__);
|
2015-11-08 18:04:32 +00:00
|
|
|
}
|
|
|
|
//}
|
2010-06-12 02:02:06 +00:00
|
|
|
}
|
|
|
|
|
2015-04-28 22:19:02 +00:00
|
|
|
void CMipsMemoryVM::ChangeMiIntrMask()
|
2015-03-29 17:19:28 +00:00
|
|
|
{
|
2015-11-08 18:04:32 +00:00
|
|
|
if ((RegModValue & MI_INTR_MASK_CLR_SP) != 0)
|
|
|
|
{
|
|
|
|
g_Reg->MI_INTR_MASK_REG &= ~MI_INTR_MASK_SP;
|
|
|
|
}
|
|
|
|
if ((RegModValue & MI_INTR_MASK_SET_SP) != 0)
|
|
|
|
{
|
|
|
|
g_Reg->MI_INTR_MASK_REG |= MI_INTR_MASK_SP;
|
|
|
|
}
|
|
|
|
if ((RegModValue & MI_INTR_MASK_CLR_SI) != 0)
|
|
|
|
{
|
|
|
|
g_Reg->MI_INTR_MASK_REG &= ~MI_INTR_MASK_SI;
|
|
|
|
}
|
|
|
|
if ((RegModValue & MI_INTR_MASK_SET_SI) != 0)
|
|
|
|
{
|
|
|
|
g_Reg->MI_INTR_MASK_REG |= MI_INTR_MASK_SI;
|
|
|
|
}
|
|
|
|
if ((RegModValue & MI_INTR_MASK_CLR_AI) != 0)
|
|
|
|
{
|
|
|
|
g_Reg->MI_INTR_MASK_REG &= ~MI_INTR_MASK_AI;
|
|
|
|
}
|
|
|
|
if ((RegModValue & MI_INTR_MASK_SET_AI) != 0)
|
|
|
|
{
|
|
|
|
g_Reg->MI_INTR_MASK_REG |= MI_INTR_MASK_AI;
|
|
|
|
}
|
|
|
|
if ((RegModValue & MI_INTR_MASK_CLR_VI) != 0)
|
|
|
|
{
|
|
|
|
g_Reg->MI_INTR_MASK_REG &= ~MI_INTR_MASK_VI;
|
|
|
|
}
|
|
|
|
if ((RegModValue & MI_INTR_MASK_SET_VI) != 0)
|
|
|
|
{
|
|
|
|
g_Reg->MI_INTR_MASK_REG |= MI_INTR_MASK_VI;
|
|
|
|
}
|
|
|
|
if ((RegModValue & MI_INTR_MASK_CLR_PI) != 0)
|
|
|
|
{
|
|
|
|
g_Reg->MI_INTR_MASK_REG &= ~MI_INTR_MASK_PI;
|
|
|
|
}
|
|
|
|
if ((RegModValue & MI_INTR_MASK_SET_PI) != 0)
|
|
|
|
{
|
|
|
|
g_Reg->MI_INTR_MASK_REG |= MI_INTR_MASK_PI;
|
|
|
|
}
|
|
|
|
if ((RegModValue & MI_INTR_MASK_CLR_DP) != 0)
|
|
|
|
{
|
|
|
|
g_Reg->MI_INTR_MASK_REG &= ~MI_INTR_MASK_DP;
|
|
|
|
}
|
|
|
|
if ((RegModValue & MI_INTR_MASK_SET_DP) != 0)
|
|
|
|
{
|
|
|
|
g_Reg->MI_INTR_MASK_REG |= MI_INTR_MASK_DP;
|
|
|
|
}
|
2015-12-21 09:45:08 +00:00
|
|
|
}
|
|
|
|
|
2015-12-21 10:01:56 +00:00
|
|
|
void CMipsMemoryVM::Load32VideoInterface(void)
|
|
|
|
{
|
|
|
|
switch (m_MemLookupAddress & 0x1FFFFFFF)
|
|
|
|
{
|
|
|
|
case 0x04400000: m_MemLookupValue.UW[0] = g_Reg->VI_STATUS_REG; break;
|
|
|
|
case 0x04400004: m_MemLookupValue.UW[0] = g_Reg->VI_ORIGIN_REG; break;
|
|
|
|
case 0x04400008: m_MemLookupValue.UW[0] = g_Reg->VI_WIDTH_REG; break;
|
|
|
|
case 0x0440000C: m_MemLookupValue.UW[0] = g_Reg->VI_INTR_REG; break;
|
|
|
|
case 0x04400010:
|
|
|
|
g_MMU->UpdateHalfLine();
|
|
|
|
m_MemLookupValue.UW[0] = g_MMU->m_HalfLine;
|
|
|
|
break;
|
|
|
|
case 0x04400014: m_MemLookupValue.UW[0] = g_Reg->VI_BURST_REG; break;
|
|
|
|
case 0x04400018: m_MemLookupValue.UW[0] = g_Reg->VI_V_SYNC_REG; break;
|
|
|
|
case 0x0440001C: m_MemLookupValue.UW[0] = g_Reg->VI_H_SYNC_REG; break;
|
|
|
|
case 0x04400020: m_MemLookupValue.UW[0] = g_Reg->VI_LEAP_REG; break;
|
|
|
|
case 0x04400024: m_MemLookupValue.UW[0] = g_Reg->VI_H_START_REG; break;
|
|
|
|
case 0x04400028: m_MemLookupValue.UW[0] = g_Reg->VI_V_START_REG; break;
|
|
|
|
case 0x0440002C: m_MemLookupValue.UW[0] = g_Reg->VI_V_BURST_REG; break;
|
|
|
|
case 0x04400030: m_MemLookupValue.UW[0] = g_Reg->VI_X_SCALE_REG; break;
|
|
|
|
case 0x04400034: m_MemLookupValue.UW[0] = g_Reg->VI_Y_SCALE_REG; break;
|
|
|
|
default:
|
|
|
|
m_MemLookupValue.UW[0] = 0;
|
2018-01-15 21:23:21 +00:00
|
|
|
if (HaveDebugger())
|
2015-12-21 10:01:56 +00:00
|
|
|
{
|
|
|
|
g_Notify->BreakPoint(__FILE__, __LINE__);
|
|
|
|
}
|
|
|
|
}
|
2015-12-21 10:06:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void CMipsMemoryVM::Load32AudioInterface(void)
|
|
|
|
{
|
|
|
|
switch (m_MemLookupAddress & 0x1FFFFFFF)
|
|
|
|
{
|
|
|
|
case 0x04500004:
|
|
|
|
if (g_System->bFixedAudio())
|
|
|
|
{
|
|
|
|
m_MemLookupValue.UW[0] = g_Audio->GetLength();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2021-04-12 11:35:39 +00:00
|
|
|
if (g_Plugins->Audio()->AiReadLength != nullptr)
|
2015-12-21 10:06:51 +00:00
|
|
|
{
|
|
|
|
m_MemLookupValue.UW[0] = g_Plugins->Audio()->AiReadLength();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
m_MemLookupValue.UW[0] = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 0x0450000C:
|
|
|
|
if (g_System->bFixedAudio())
|
|
|
|
{
|
|
|
|
m_MemLookupValue.UW[0] = g_Audio->GetStatus();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
m_MemLookupValue.UW[0] = g_Reg->AI_STATUS_REG;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
m_MemLookupValue.UW[0] = 0;
|
2018-01-15 21:23:21 +00:00
|
|
|
if (HaveDebugger())
|
2015-12-21 10:06:51 +00:00
|
|
|
{
|
|
|
|
g_Notify->BreakPoint(__FILE__, __LINE__);
|
|
|
|
}
|
|
|
|
}
|
2015-12-21 18:45:07 +00:00
|
|
|
}
|
|
|
|
|
2015-12-21 19:59:17 +00:00
|
|
|
void CMipsMemoryVM::Load32SerialInterface(void)
|
|
|
|
{
|
|
|
|
switch (m_MemLookupAddress & 0x1FFFFFFF)
|
|
|
|
{
|
|
|
|
case 0x04800018: m_MemLookupValue.UW[0] = g_Reg->SI_STATUS_REG; break;
|
|
|
|
default:
|
|
|
|
m_MemLookupValue.UW[0] = 0;
|
2018-01-15 21:23:21 +00:00
|
|
|
if (HaveDebugger())
|
2015-12-21 19:59:17 +00:00
|
|
|
{
|
|
|
|
g_Notify->BreakPoint(__FILE__, __LINE__);
|
|
|
|
}
|
|
|
|
}
|
2015-12-21 21:03:14 +00:00
|
|
|
}
|
|
|
|
|
2016-01-17 06:38:29 +00:00
|
|
|
void CMipsMemoryVM::Load32CartridgeDomain1Address1(void)
|
|
|
|
{
|
2021-05-18 11:51:36 +00:00
|
|
|
// 64DD IPL ROM
|
2021-04-12 11:35:39 +00:00
|
|
|
if (g_DDRom != nullptr && (m_MemLookupAddress & 0xFFFFFF) < g_MMU->m_DDRomSize)
|
2016-01-18 19:15:01 +00:00
|
|
|
{
|
|
|
|
m_MemLookupValue.UW[0] = *(uint32_t *)&g_MMU->m_DDRom[(m_MemLookupAddress & 0xFFFFFF)];
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
m_MemLookupValue.UW[0] = m_MemLookupAddress & 0xFFFF;
|
|
|
|
m_MemLookupValue.UW[0] = (m_MemLookupValue.UW[0] << 16) | m_MemLookupValue.UW[0];
|
|
|
|
}
|
2016-01-17 06:38:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void CMipsMemoryVM::Load32CartridgeDomain1Address3(void)
|
|
|
|
{
|
|
|
|
m_MemLookupValue.UW[0] = m_MemLookupAddress & 0xFFFF;
|
|
|
|
m_MemLookupValue.UW[0] = (m_MemLookupValue.UW[0] << 16) | m_MemLookupValue.UW[0];
|
|
|
|
}
|
|
|
|
|
2015-12-21 21:03:14 +00:00
|
|
|
void CMipsMemoryVM::Load32CartridgeDomain2Address1(void)
|
|
|
|
{
|
2021-05-18 11:51:36 +00:00
|
|
|
// 64DD registers
|
2022-01-03 23:37:52 +00:00
|
|
|
if (EnableDisk())
|
2016-01-19 18:53:18 +00:00
|
|
|
{
|
|
|
|
switch (m_MemLookupAddress & 0x1FFFFFFF)
|
|
|
|
{
|
|
|
|
case 0x05000500: m_MemLookupValue.UW[0] = g_Reg->ASIC_DATA; break;
|
|
|
|
case 0x05000504: m_MemLookupValue.UW[0] = g_Reg->ASIC_MISC_REG; break;
|
2016-01-20 13:31:29 +00:00
|
|
|
case 0x05000508:
|
|
|
|
m_MemLookupValue.UW[0] = g_Reg->ASIC_STATUS;
|
|
|
|
DiskGapSectorCheck();
|
|
|
|
break;
|
2016-01-19 18:53:18 +00:00
|
|
|
case 0x0500050C: m_MemLookupValue.UW[0] = g_Reg->ASIC_CUR_TK; break;
|
|
|
|
case 0x05000510: m_MemLookupValue.UW[0] = g_Reg->ASIC_BM_STATUS; break;
|
|
|
|
case 0x05000514: m_MemLookupValue.UW[0] = g_Reg->ASIC_ERR_SECTOR; break;
|
|
|
|
case 0x05000518: m_MemLookupValue.UW[0] = g_Reg->ASIC_SEQ_STATUS; break;
|
|
|
|
case 0x0500051C: m_MemLookupValue.UW[0] = g_Reg->ASIC_CUR_SECTOR; break;
|
|
|
|
case 0x05000520: m_MemLookupValue.UW[0] = g_Reg->ASIC_HARD_RESET; break;
|
|
|
|
case 0x05000524: m_MemLookupValue.UW[0] = g_Reg->ASIC_C1_S0; break;
|
|
|
|
case 0x05000528: m_MemLookupValue.UW[0] = g_Reg->ASIC_HOST_SECBYTE; break;
|
|
|
|
case 0x0500052C: m_MemLookupValue.UW[0] = g_Reg->ASIC_C1_S2; break;
|
|
|
|
case 0x05000530: m_MemLookupValue.UW[0] = g_Reg->ASIC_SEC_BYTE; break;
|
|
|
|
case 0x05000534: m_MemLookupValue.UW[0] = g_Reg->ASIC_C1_S4; break;
|
|
|
|
case 0x05000538: m_MemLookupValue.UW[0] = g_Reg->ASIC_C1_S6; break;
|
|
|
|
case 0x0500053C: m_MemLookupValue.UW[0] = g_Reg->ASIC_CUR_ADDR; break;
|
|
|
|
case 0x05000540: m_MemLookupValue.UW[0] = g_Reg->ASIC_ID_REG; break;
|
|
|
|
case 0x05000544: m_MemLookupValue.UW[0] = g_Reg->ASIC_TEST_REG; break;
|
|
|
|
case 0x05000548: m_MemLookupValue.UW[0] = g_Reg->ASIC_TEST_PIN_SEL; break;
|
|
|
|
default:
|
|
|
|
m_MemLookupValue.UW[0] = m_MemLookupAddress & 0xFFFF;
|
|
|
|
m_MemLookupValue.UW[0] = (m_MemLookupValue.UW[0] << 16) | m_MemLookupValue.UW[0];
|
2018-01-15 21:23:21 +00:00
|
|
|
if (HaveDebugger())
|
2016-01-19 18:53:18 +00:00
|
|
|
{
|
|
|
|
g_Notify->BreakPoint(__FILE__, __LINE__);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
2015-12-21 21:03:14 +00:00
|
|
|
{
|
2016-01-19 18:53:18 +00:00
|
|
|
m_MemLookupValue.UW[0] = m_MemLookupAddress & 0xFFFF;
|
|
|
|
m_MemLookupValue.UW[0] = (m_MemLookupValue.UW[0] << 16) | m_MemLookupValue.UW[0];
|
2015-12-21 21:03:14 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void CMipsMemoryVM::Load32CartridgeDomain2Address2(void)
|
|
|
|
{
|
2019-12-19 01:51:47 +00:00
|
|
|
uint32_t offset = (m_MemLookupAddress & 0x1FFFFFFF) - 0x08000000;
|
2022-01-11 21:03:56 +00:00
|
|
|
if (offset > 0x88000)
|
2019-12-16 21:19:01 +00:00
|
|
|
{
|
2019-12-19 01:51:47 +00:00
|
|
|
m_MemLookupValue.UW[0] = ((offset & 0xFFFF) << 16) | (offset & 0xFFFF);
|
2019-12-16 21:19:01 +00:00
|
|
|
return;
|
|
|
|
}
|
2015-12-21 21:03:14 +00:00
|
|
|
if (g_System->m_SaveUsing == SaveChip_Auto)
|
|
|
|
{
|
|
|
|
g_System->m_SaveUsing = SaveChip_FlashRam;
|
|
|
|
}
|
|
|
|
if (g_System->m_SaveUsing == SaveChip_Sram)
|
|
|
|
{
|
2021-05-18 11:51:36 +00:00
|
|
|
// Load SRAM
|
2015-12-21 21:03:14 +00:00
|
|
|
uint8_t tmp[4] = "";
|
2019-12-19 01:51:47 +00:00
|
|
|
g_MMU->DmaFromSram(tmp, offset, 4);
|
2015-12-21 21:03:14 +00:00
|
|
|
m_MemLookupValue.UW[0] = tmp[3] << 24 | tmp[2] << 16 | tmp[1] << 8 | tmp[0];
|
|
|
|
}
|
|
|
|
else if (g_System->m_SaveUsing != SaveChip_FlashRam)
|
|
|
|
{
|
2018-01-15 21:23:21 +00:00
|
|
|
if (HaveDebugger())
|
2015-12-21 21:03:14 +00:00
|
|
|
{
|
|
|
|
g_Notify->BreakPoint(__FILE__, __LINE__);
|
|
|
|
}
|
|
|
|
m_MemLookupValue.UW[0] = m_MemLookupAddress & 0xFFFF;
|
|
|
|
m_MemLookupValue.UW[0] = (m_MemLookupValue.UW[0] << 16) | m_MemLookupValue.UW[0];
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
m_MemLookupValue.UW[0] = g_MMU->ReadFromFlashStatus(m_MemLookupAddress & 0x1FFFFFFF);
|
|
|
|
}
|
2015-12-21 21:15:26 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void CMipsMemoryVM::Load32PifRam(void)
|
|
|
|
{
|
|
|
|
if ((m_MemLookupAddress & 0x1FFFFFFF) < 0x1FC007C0)
|
|
|
|
{
|
|
|
|
//m_MemLookupValue.UW[0] = swap32by8(*(uint32_t *)(&PifRom[PAddr - 0x1FC00000]));
|
|
|
|
m_MemLookupValue.UW[0] = 0;
|
2018-01-15 21:23:21 +00:00
|
|
|
if (HaveDebugger())
|
2015-12-21 21:15:26 +00:00
|
|
|
{
|
|
|
|
g_Notify->BreakPoint(__FILE__, __LINE__);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if ((m_MemLookupAddress & 0x1FFFFFFF) < 0x1FC00800)
|
|
|
|
{
|
|
|
|
uint8_t * PIF_Ram = g_MMU->PifRam();
|
|
|
|
m_MemLookupValue.UW[0] = *(uint32_t *)(&PIF_Ram[(m_MemLookupAddress & 0x1FFFFFFF) - 0x1FC007C0]);
|
|
|
|
m_MemLookupValue.UW[0] = swap32by8(m_MemLookupValue.UW[0]);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
m_MemLookupValue.UW[0] = 0;
|
2018-01-15 21:23:21 +00:00
|
|
|
if (HaveDebugger())
|
2015-12-21 21:15:26 +00:00
|
|
|
{
|
|
|
|
g_Notify->BreakPoint(__FILE__, __LINE__);
|
|
|
|
}
|
|
|
|
}
|
2015-12-21 21:24:37 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void CMipsMemoryVM::Load32Rom(void)
|
|
|
|
{
|
|
|
|
if (g_MMU->m_RomWrittenTo)
|
|
|
|
{
|
|
|
|
m_MemLookupValue.UW[0] = g_MMU->m_RomWroteValue;
|
2021-05-18 11:51:36 +00:00
|
|
|
//LogMessage("%X: Read crap from ROM %08X from %08X",PROGRAM_COUNTER,*Value,PAddr);
|
2015-12-21 21:24:37 +00:00
|
|
|
g_MMU->m_RomWrittenTo = false;
|
2015-12-22 05:31:13 +00:00
|
|
|
}
|
2015-12-21 21:24:37 +00:00
|
|
|
else if ((m_MemLookupAddress & 0xFFFFFFF) < g_MMU->m_RomSize)
|
|
|
|
{
|
|
|
|
m_MemLookupValue.UW[0] = *(uint32_t *)&g_MMU->m_Rom[(m_MemLookupAddress & 0xFFFFFFF)];
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
m_MemLookupValue.UW[0] = m_MemLookupAddress & 0xFFFF;
|
|
|
|
m_MemLookupValue.UW[0] = (m_MemLookupValue.UW[0] << 16) | m_MemLookupValue.UW[0];
|
|
|
|
}
|
2017-05-06 09:27:06 +00:00
|
|
|
}
|
2015-12-21 21:35:06 +00:00
|
|
|
|
2015-12-22 05:40:19 +00:00
|
|
|
void CMipsMemoryVM::Write32VideoInterface(void)
|
|
|
|
{
|
|
|
|
switch ((m_MemLookupAddress & 0xFFFFFFF))
|
|
|
|
{
|
|
|
|
case 0x04400000:
|
|
|
|
if (g_Reg->VI_STATUS_REG != m_MemLookupValue.UW[0])
|
|
|
|
{
|
|
|
|
g_Reg->VI_STATUS_REG = m_MemLookupValue.UW[0];
|
2021-04-12 11:35:39 +00:00
|
|
|
if (g_Plugins->Gfx()->ViStatusChanged != nullptr)
|
2015-12-22 05:40:19 +00:00
|
|
|
{
|
|
|
|
g_Plugins->Gfx()->ViStatusChanged();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 0x04400004:
|
|
|
|
g_Reg->VI_ORIGIN_REG = (m_MemLookupValue.UW[0] & 0xFFFFFF);
|
|
|
|
break;
|
|
|
|
case 0x04400008:
|
|
|
|
if (g_Reg->VI_WIDTH_REG != m_MemLookupValue.UW[0])
|
|
|
|
{
|
|
|
|
g_Reg->VI_WIDTH_REG = m_MemLookupValue.UW[0];
|
2021-04-12 11:35:39 +00:00
|
|
|
if (g_Plugins->Gfx()->ViWidthChanged != nullptr)
|
2015-12-22 05:40:19 +00:00
|
|
|
{
|
|
|
|
g_Plugins->Gfx()->ViWidthChanged();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 0x0440000C: g_Reg->VI_INTR_REG = m_MemLookupValue.UW[0]; break;
|
|
|
|
case 0x04400010:
|
|
|
|
g_Reg->MI_INTR_REG &= ~MI_INTR_VI;
|
|
|
|
g_Reg->CheckInterrupts();
|
|
|
|
break;
|
|
|
|
case 0x04400014: g_Reg->VI_BURST_REG = m_MemLookupValue.UW[0]; break;
|
|
|
|
case 0x04400018: g_Reg->VI_V_SYNC_REG = m_MemLookupValue.UW[0]; break;
|
|
|
|
case 0x0440001C: g_Reg->VI_H_SYNC_REG = m_MemLookupValue.UW[0]; break;
|
|
|
|
case 0x04400020: g_Reg->VI_LEAP_REG = m_MemLookupValue.UW[0]; break;
|
|
|
|
case 0x04400024: g_Reg->VI_H_START_REG = m_MemLookupValue.UW[0]; break;
|
|
|
|
case 0x04400028: g_Reg->VI_V_START_REG = m_MemLookupValue.UW[0]; break;
|
|
|
|
case 0x0440002C: g_Reg->VI_V_BURST_REG = m_MemLookupValue.UW[0]; break;
|
|
|
|
case 0x04400030: g_Reg->VI_X_SCALE_REG = m_MemLookupValue.UW[0]; break;
|
|
|
|
case 0x04400034: g_Reg->VI_Y_SCALE_REG = m_MemLookupValue.UW[0]; break;
|
|
|
|
default:
|
2018-01-15 21:23:21 +00:00
|
|
|
if (HaveDebugger())
|
2015-12-22 05:40:19 +00:00
|
|
|
{
|
|
|
|
g_Notify->BreakPoint(__FILE__, __LINE__);
|
|
|
|
}
|
|
|
|
}
|
2017-05-06 09:27:06 +00:00
|
|
|
}
|
2015-12-22 05:46:08 +00:00
|
|
|
|
|
|
|
void CMipsMemoryVM::Write32AudioInterface(void)
|
|
|
|
{
|
|
|
|
switch (m_MemLookupAddress & 0xFFFFFFF)
|
|
|
|
{
|
|
|
|
case 0x04500000: g_Reg->AI_DRAM_ADDR_REG = m_MemLookupValue.UW[0]; break;
|
|
|
|
case 0x04500004:
|
|
|
|
g_Reg->AI_LEN_REG = m_MemLookupValue.UW[0];
|
|
|
|
if (g_System->bFixedAudio())
|
|
|
|
{
|
|
|
|
g_Audio->LenChanged();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2021-04-12 11:35:39 +00:00
|
|
|
if (g_Plugins->Audio()->AiLenChanged != nullptr)
|
2015-12-22 05:46:08 +00:00
|
|
|
{
|
|
|
|
g_Plugins->Audio()->AiLenChanged();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 0x04500008: g_Reg->AI_CONTROL_REG = (m_MemLookupValue.UW[0] & 1); break;
|
|
|
|
case 0x0450000C:
|
2021-05-18 11:51:36 +00:00
|
|
|
// Clear interrupt
|
2015-12-22 05:46:08 +00:00
|
|
|
g_Reg->MI_INTR_REG &= ~MI_INTR_AI;
|
|
|
|
g_Reg->m_AudioIntrReg &= ~MI_INTR_AI;
|
|
|
|
g_Reg->CheckInterrupts();
|
|
|
|
break;
|
|
|
|
case 0x04500010:
|
|
|
|
g_Reg->AI_DACRATE_REG = m_MemLookupValue.UW[0];
|
|
|
|
g_Plugins->Audio()->DacrateChanged(g_System->SystemType());
|
|
|
|
if (g_System->bFixedAudio())
|
|
|
|
{
|
|
|
|
g_Audio->SetFrequency(m_MemLookupValue.UW[0], g_System->SystemType());
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case 0x04500014: g_Reg->AI_BITRATE_REG = m_MemLookupValue.UW[0]; break;
|
|
|
|
default:
|
2018-01-15 21:23:21 +00:00
|
|
|
if (HaveDebugger())
|
2015-12-22 05:46:08 +00:00
|
|
|
{
|
|
|
|
g_Notify->BreakPoint(__FILE__, __LINE__);
|
|
|
|
}
|
|
|
|
}
|
2015-12-22 05:51:50 +00:00
|
|
|
}
|
|
|
|
|
2015-12-22 06:02:08 +00:00
|
|
|
void CMipsMemoryVM::Write32SerialInterface(void)
|
|
|
|
{
|
|
|
|
switch (m_MemLookupAddress & 0xFFFFFFF)
|
|
|
|
{
|
|
|
|
case 0x04800000: g_Reg->SI_DRAM_ADDR_REG = m_MemLookupValue.UW[0]; break;
|
|
|
|
case 0x04800004:
|
|
|
|
g_Reg->SI_PIF_ADDR_RD64B_REG = m_MemLookupValue.UW[0];
|
|
|
|
g_MMU->SI_DMA_READ();
|
|
|
|
break;
|
|
|
|
case 0x04800010:
|
|
|
|
g_Reg->SI_PIF_ADDR_WR64B_REG = m_MemLookupValue.UW[0];
|
|
|
|
g_MMU->SI_DMA_WRITE();
|
|
|
|
break;
|
|
|
|
case 0x04800018:
|
|
|
|
g_Reg->MI_INTR_REG &= ~MI_INTR_SI;
|
|
|
|
g_Reg->SI_STATUS_REG &= ~SI_STATUS_INTERRUPT;
|
|
|
|
g_Reg->CheckInterrupts();
|
|
|
|
break;
|
|
|
|
default:
|
2018-01-15 21:23:21 +00:00
|
|
|
if (HaveDebugger())
|
2015-12-22 06:02:08 +00:00
|
|
|
{
|
|
|
|
g_Notify->BreakPoint(__FILE__, __LINE__);
|
|
|
|
}
|
|
|
|
}
|
2015-12-22 06:09:27 +00:00
|
|
|
}
|
|
|
|
|
2016-01-19 18:53:18 +00:00
|
|
|
void CMipsMemoryVM::Write32CartridgeDomain2Address1(void)
|
|
|
|
{
|
2021-05-18 11:51:36 +00:00
|
|
|
// 64DD registers
|
2022-01-03 23:37:52 +00:00
|
|
|
if (EnableDisk())
|
2016-01-19 18:53:18 +00:00
|
|
|
{
|
|
|
|
switch (m_MemLookupAddress & 0xFFFFFFF)
|
|
|
|
{
|
|
|
|
case 0x05000500: g_Reg->ASIC_DATA = m_MemLookupValue.UW[0]; break;
|
|
|
|
case 0x05000508:
|
|
|
|
g_Reg->ASIC_CMD = m_MemLookupValue.UW[0];
|
|
|
|
DiskCommand();
|
|
|
|
break;
|
|
|
|
case 0x05000510:
|
|
|
|
//ASIC_BM_STATUS_CTL
|
|
|
|
g_Reg->ASIC_BM_CTL = m_MemLookupValue.UW[0];
|
|
|
|
DiskBMControl();
|
|
|
|
break;
|
|
|
|
case 0x05000518:
|
|
|
|
//ASIC_SEQ_STATUS_CTL
|
|
|
|
break;
|
|
|
|
case 0x05000520: DiskReset(); break;
|
|
|
|
case 0x05000528: g_Reg->ASIC_HOST_SECBYTE = m_MemLookupValue.UW[0]; break;
|
|
|
|
case 0x05000530: g_Reg->ASIC_SEC_BYTE = m_MemLookupValue.UW[0]; break;
|
|
|
|
case 0x05000548: g_Reg->ASIC_TEST_PIN_SEL = m_MemLookupValue.UW[0]; break;
|
|
|
|
default:
|
2018-01-15 21:23:21 +00:00
|
|
|
if (HaveDebugger())
|
2016-01-19 18:53:18 +00:00
|
|
|
{
|
|
|
|
g_Notify->BreakPoint(__FILE__, __LINE__);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-12-22 06:09:27 +00:00
|
|
|
void CMipsMemoryVM::Write32CartridgeDomain2Address2(void)
|
|
|
|
{
|
2019-12-27 15:41:21 +00:00
|
|
|
uint32_t offset = (m_MemLookupAddress & 0x1FFFFFFF) - 0x08000000;
|
2022-01-11 21:03:56 +00:00
|
|
|
if (g_System->m_SaveUsing == SaveChip_Sram && offset < 0x88000)
|
2015-12-22 06:09:27 +00:00
|
|
|
{
|
2021-05-18 11:51:36 +00:00
|
|
|
// Store SRAM
|
2015-12-22 06:09:27 +00:00
|
|
|
uint8_t tmp[4] = "";
|
|
|
|
tmp[0] = 0xFF & (m_MemLookupValue.UW[0]);
|
|
|
|
tmp[1] = 0xFF & (m_MemLookupValue.UW[0] >> 8);
|
|
|
|
tmp[2] = 0xFF & (m_MemLookupValue.UW[0] >> 16);
|
|
|
|
tmp[3] = 0xFF & (m_MemLookupValue.UW[0] >> 24);
|
2016-04-30 08:33:44 +00:00
|
|
|
g_MMU->DmaToSram(tmp, (m_MemLookupAddress & 0x1FFFFFFF) - 0x08000000, 4);
|
2015-12-22 06:09:27 +00:00
|
|
|
return;
|
|
|
|
}
|
2016-03-21 14:00:21 +00:00
|
|
|
/*if ((m_MemLookupAddress & 0x1FFFFFFF) != 0x08010000)
|
2015-12-22 06:09:27 +00:00
|
|
|
{
|
2018-01-15 21:23:21 +00:00
|
|
|
if (HaveDebugger())
|
2016-07-03 10:17:45 +00:00
|
|
|
{
|
|
|
|
g_Notify->BreakPoint(__FILE__, __LINE__);
|
|
|
|
}
|
2016-03-21 14:00:21 +00:00
|
|
|
}*/
|
2019-12-27 15:41:21 +00:00
|
|
|
if (offset > 0x10000)
|
2019-12-16 21:19:01 +00:00
|
|
|
{
|
|
|
|
return;
|
|
|
|
}
|
2015-12-22 06:09:27 +00:00
|
|
|
if (g_System->m_SaveUsing == SaveChip_Auto)
|
|
|
|
{
|
|
|
|
g_System->m_SaveUsing = SaveChip_FlashRam;
|
|
|
|
}
|
|
|
|
if (g_System->m_SaveUsing == SaveChip_FlashRam)
|
|
|
|
{
|
|
|
|
g_MMU->WriteToFlashCommand(m_MemLookupValue.UW[0]);
|
|
|
|
}
|
2015-12-22 08:04:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
void CMipsMemoryVM::Write32PifRam(void)
|
|
|
|
{
|
|
|
|
if ((m_MemLookupAddress & 0x1FFFFFFF) < 0x1FC007C0)
|
|
|
|
{
|
2018-01-15 21:23:21 +00:00
|
|
|
if (HaveDebugger())
|
2015-12-22 08:04:55 +00:00
|
|
|
{
|
|
|
|
g_Notify->BreakPoint(__FILE__, __LINE__);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if ((m_MemLookupAddress & 0x1FFFFFFF) < 0x1FC00800)
|
|
|
|
{
|
|
|
|
uint32_t Value = swap32by8(m_MemLookupValue.UW[0]);
|
|
|
|
*(uint32_t *)(&g_MMU->m_PifRam[(m_MemLookupAddress & 0x1FFFFFFF) - 0x1FC007C0]) = Value;
|
|
|
|
if ((m_MemLookupAddress & 0x1FFFFFFF) == 0x1FC007FC)
|
|
|
|
{
|
|
|
|
g_MMU->PifRamWrite();
|
|
|
|
}
|
|
|
|
}
|
2017-05-04 08:19:05 +00:00
|
|
|
}
|