project64/Source/Project64-rsp-core/cpu/RspMemory.cpp

125 lines
3.1 KiB
C++
Raw Normal View History

2023-08-16 23:29:22 +00:00
#include <Common/MemoryManagement.h>
#include <Project64-rsp-core/RSPInfo.h>
2023-09-28 02:22:06 +00:00
#include <Project64-rsp-core/cpu/RSPCpu.h>
2023-08-16 23:29:22 +00:00
#include <Project64-rsp-core/cpu/RSPRegisters.h>
#include <Settings/Settings.h>
#include <stdio.h>
#include <string.h>
2024-06-27 06:55:13 +00:00
#include <zlib/zlib.h>
2023-08-16 23:29:22 +00:00
enum
{
MaxMaps = 32
};
2016-01-27 09:11:59 +00:00
uint32_t NoOfMaps, MapsCRC[MaxMaps];
uint32_t Table;
2023-08-16 23:29:22 +00:00
uint8_t *RecompCode, *RecompCodeSecondary, *RecompPos, *JumpTables;
2016-01-27 09:11:59 +00:00
void ** JumpTable;
2024-07-20 09:40:36 +00:00
extern uint8_t *pLastSecondary, *pLastPrimary;
int AllocateMemory(void)
{
2023-08-16 23:29:22 +00:00
if (RecompCode == nullptr)
{
RecompCode = (uint8_t *)AllocateAddressSpace(0x00800004);
RecompCode = (uint8_t *)CommitMemory(RecompCode, 0x00800000, MEM_EXECUTE_READWRITE);
2023-08-16 23:29:22 +00:00
if (RecompCode == nullptr)
{
2023-08-16 23:29:22 +00:00
g_Notify->DisplayError("Not enough memory for RSP RecompCode!");
2023-06-29 02:59:07 +00:00
return false;
}
}
2023-08-16 23:29:22 +00:00
if (RecompCodeSecondary == nullptr)
{
2023-08-16 23:29:22 +00:00
RecompCodeSecondary = (uint8_t *)AllocateAddressSpace(0x00200004);
RecompCodeSecondary = (uint8_t *)CommitMemory(RecompCodeSecondary, 0x00200000, MEM_EXECUTE_READWRITE);
2023-08-16 23:29:22 +00:00
if (RecompCodeSecondary == nullptr)
{
2023-08-16 23:29:22 +00:00
g_Notify->DisplayError("Not enough memory for RSP RecompCode Secondary!");
2023-06-29 02:59:07 +00:00
return false;
}
}
2023-08-16 23:29:22 +00:00
if (JumpTables == nullptr)
{
2023-08-16 23:29:22 +00:00
JumpTables = (uint8_t *)AllocateAddressSpace(0x1000 * MaxMaps);
JumpTables = (uint8_t *)CommitMemory(JumpTables, 0x1000 * MaxMaps, MEM_READWRITE);
2023-08-16 23:29:22 +00:00
if (JumpTables == nullptr)
{
2023-08-16 23:29:22 +00:00
g_Notify->DisplayError("Not enough memory for jump table!");
2023-06-29 02:59:07 +00:00
return false;
}
}
JumpTable = (void **)JumpTables;
RecompPos = RecompCode;
NoOfMaps = 0;
2023-06-29 02:59:07 +00:00
return true;
}
void FreeMemory(void)
{
FreeAddressSpace(RecompCode, 0x00800004);
2023-08-16 23:29:22 +00:00
FreeAddressSpace(JumpTable, 0x1000 * MaxMaps);
FreeAddressSpace(RecompCodeSecondary, 0x00200004);
2023-08-16 23:29:22 +00:00
RecompCode = nullptr;
JumpTables = nullptr;
RecompCodeSecondary = nullptr;
}
void ResetJumpTables(void)
{
memset(JumpTables, 0, 0x1000 * MaxMaps);
RecompPos = RecompCode;
pLastPrimary = nullptr;
pLastSecondary = nullptr;
NoOfMaps = 0;
}
void SetJumpTable(uint32_t End)
{
2024-06-27 06:55:13 +00:00
uint32_t CRC = crc32(0L, Z_NULL, 0);
if (End < 0x800)
{
End = 0x800;
}
2023-09-28 02:22:06 +00:00
if (End == 0x1000 && ((g_RSPRegisterHandler->PendingSPMemAddr() & 0x0FFF) & ~7) == 0x80)
{
End = 0x800;
}
2024-06-27 06:55:13 +00:00
CRC = crc32(CRC, RSPInfo.IMEM, End);
for (uint32_t i = 0; i < NoOfMaps; i++)
{
2024-06-27 06:55:13 +00:00
if (CRC == MapsCRC[i])
{
2024-06-27 06:55:13 +00:00
JumpTable = (void **)(JumpTables + i * 0x1000);
Table = i;
return;
}
}
//DisplayError("%X %X",NoOfMaps,CRC);
if (NoOfMaps == MaxMaps)
{
ResetJumpTables();
}
MapsCRC[NoOfMaps] = CRC;
JumpTable = (void **)(JumpTables + NoOfMaps * 0x1000);
Table = NoOfMaps;
NoOfMaps += 1;
}
void RSP_LW_IMEM(uint32_t Addr, uint32_t * Value)
{
if ((Addr & 0x3) != 0)
{
2023-08-16 23:29:22 +00:00
g_Notify->DisplayError("Unaligned RSP_LW_IMEM");
}
*Value = *(uint32_t *)(RSPInfo.IMEM + (Addr & 0xFFF));
}