Core: Have save states handle COP0/TLB being 64bit now

Core: Clean up tlb class
This commit is contained in:
zilmar 2023-10-05 13:10:45 +10:30
parent 35105e814e
commit 4b844495b7
6 changed files with 266 additions and 199 deletions

View File

@ -19,6 +19,34 @@
#pragma warning(push) #pragma warning(push)
#pragma warning(disable : 4201) // Non-standard extension used: nameless struct/union #pragma warning(disable : 4201) // Non-standard extension used: nameless struct/union
union COP0EntryLo
{
uint64_t Value;
struct
{
uint64_t GLOBAL : 1;
uint64_t V : 1;
uint64_t D : 1;
uint64_t C : 3;
uint64_t PFN : 28;
uint64_t : 28;
uint64_t UC : 2;
};
};
union COP0PageMask
{
uint64_t Value;
struct
{
uint64_t : 13;
uint64_t Mask : 12;
uint64_t : 39;
};
};
union COP0EntryHi union COP0EntryHi
{ {
uint64_t Value; uint64_t Value;

View File

@ -1,11 +1,16 @@
#include "stdafx.h" #include "stdafx.h"
#include "TLB.h" #include "TLB.h"
#include <Project64-core/Debugger.h>
#include <Project64-core/N64System/Mips/MemoryVirtualMem.h>
#include <Project64-core/N64System/Mips/Register.h> #include <Project64-core/N64System/Mips/Register.h>
#include <Project64-core/N64System/Recompiler/Recompiler.h>
#include <Project64-core/N64System/SystemGlobals.h> #include <Project64-core/N64System/SystemGlobals.h>
CTLB::CTLB(CTLB_CB * CallBack) : CTLB::CTLB(CMipsMemoryVM & MMU, CRegisters & Reg, CRecompiler *& Recomp) :
m_CB(CallBack) m_MMU(MMU),
m_Reg(Reg),
m_Recomp(Recomp)
{ {
WriteTrace(TraceTLB, TraceDebug, "Start"); WriteTrace(TraceTLB, TraceDebug, "Start");
memset(m_tlb, 0, sizeof(m_tlb)); memset(m_tlb, 0, sizeof(m_tlb));
@ -64,12 +69,17 @@ bool CTLB::AddressDefined(uint64_t VAddr)
return false; return false;
} }
TLB_ENTRY & CTLB::TlbEntry(int32_t Entry)
{
return m_tlb[Entry];
}
void CTLB::Probe() void CTLB::Probe()
{ {
int Counter; int Counter;
WriteTrace(TraceTLB, TraceDebug, "Start"); WriteTrace(TraceTLB, TraceDebug, "Start");
g_Reg->INDEX_REGISTER |= 0x80000000; m_Reg.INDEX_REGISTER |= 0x80000000;
for (Counter = 0; Counter < 32; Counter++) for (Counter = 0; Counter < 32; Counter++)
{ {
if (!m_tlb[Counter].EntryDefined) if (!m_tlb[Counter].EntryDefined)
@ -77,17 +87,17 @@ void CTLB::Probe()
continue; continue;
} }
uint32_t & TlbEntryHiValue = m_tlb[Counter].EntryHi.Value; uint64_t & TlbEntryHiValue = m_tlb[Counter].EntryHi.Value;
uint32_t Mask = ~m_tlb[Counter].PageMask.Mask << 13; uint32_t Mask = (uint32_t)(~m_tlb[Counter].PageMask.Mask << 13);
uint32_t TlbValueMasked = TlbEntryHiValue & Mask; uint32_t TlbValueMasked = TlbEntryHiValue & Mask;
uint32_t EntryHiMasked = g_Reg->ENTRYHI_REGISTER.Value & Mask; uint32_t EntryHiMasked = m_Reg.ENTRYHI_REGISTER.Value & Mask;
if (TlbValueMasked == EntryHiMasked) if (TlbValueMasked == EntryHiMasked)
{ {
if ((TlbEntryHiValue & 0x100) != 0 || // Global if ((TlbEntryHiValue & 0x100) != 0 || // Global
((TlbEntryHiValue & 0xFF) == (g_Reg->ENTRYHI_REGISTER.Value & 0xFF))) // SameAsid ((TlbEntryHiValue & 0xFF) == (m_Reg.ENTRYHI_REGISTER.Value & 0xFF))) // SameAsid
{ {
g_Reg->INDEX_REGISTER = Counter; m_Reg.INDEX_REGISTER = Counter;
int FastIndx = Counter << 1; int FastIndx = Counter << 1;
m_FastTlb[FastIndx].Probed = true; m_FastTlb[FastIndx].Probed = true;
m_FastTlb[FastIndx + 1].Probed = true; m_FastTlb[FastIndx + 1].Probed = true;
@ -100,24 +110,24 @@ void CTLB::Probe()
void CTLB::ReadEntry() void CTLB::ReadEntry()
{ {
uint32_t index = g_Reg->INDEX_REGISTER & 0x1F; uint32_t Index = m_Reg.INDEX_REGISTER & 0x1F;
g_Reg->PAGE_MASK_REGISTER = m_tlb[index].PageMask.Value; m_Reg.PAGE_MASK_REGISTER = m_tlb[Index].PageMask.Value;
g_Reg->ENTRYHI_REGISTER.Value = (m_tlb[index].EntryHi.Value & ~m_tlb[index].PageMask.Value); m_Reg.ENTRYHI_REGISTER.Value = (m_tlb[Index].EntryHi.Value & ~m_tlb[Index].PageMask.Value);
g_Reg->ENTRYLO0_REGISTER = m_tlb[index].EntryLo0.Value; m_Reg.ENTRYLO0_REGISTER = m_tlb[Index].EntryLo0.Value;
g_Reg->ENTRYLO1_REGISTER = m_tlb[index].EntryLo1.Value; m_Reg.ENTRYLO1_REGISTER = m_tlb[Index].EntryLo1.Value;
} }
void CTLB::WriteEntry(int index, bool Random) void CTLB::WriteEntry(uint32_t Index, bool Random)
{ {
int FastIndx; uint32_t FastIndx;
WriteTrace(TraceTLB, TraceDebug, "%02d %d %08X %08X %08X %08X ", index, Random, g_Reg->PAGE_MASK_REGISTER, g_Reg->ENTRYHI_REGISTER, g_Reg->ENTRYLO0_REGISTER, g_Reg->ENTRYLO1_REGISTER); WriteTrace(TraceTLB, TraceDebug, "%02d %d %08X %08X %08X %08X ", Index, Random, m_Reg.PAGE_MASK_REGISTER, m_Reg.ENTRYHI_REGISTER, m_Reg.ENTRYLO0_REGISTER, m_Reg.ENTRYLO1_REGISTER);
// Check to see if entry is unmapping itself // Check to see if entry is unmapping itself
if (m_tlb[index].EntryDefined) if (m_tlb[Index].EntryDefined)
{ {
FastIndx = index << 1; FastIndx = Index << 1;
if (*_PROGRAM_COUNTER >= m_FastTlb[FastIndx].VSTART && if (*_PROGRAM_COUNTER >= m_FastTlb[FastIndx].VSTART &&
*_PROGRAM_COUNTER < m_FastTlb[FastIndx].VEND && *_PROGRAM_COUNTER < m_FastTlb[FastIndx].VEND &&
m_FastTlb[FastIndx].ValidEntry && m_FastTlb[FastIndx].VALID) m_FastTlb[FastIndx].ValidEntry && m_FastTlb[FastIndx].VALID)
@ -135,9 +145,9 @@ void CTLB::WriteEntry(int index, bool Random)
} }
// Reset old addresses // Reset old addresses
if (m_tlb[index].EntryDefined) if (m_tlb[Index].EntryDefined)
{ {
for (FastIndx = index << 1; FastIndx <= (index << 1) + 1; FastIndx++) for (FastIndx = Index << 1; FastIndx <= (Index << 1) + 1; FastIndx++)
{ {
if (!m_FastTlb[FastIndx].ValidEntry) if (!m_FastTlb[FastIndx].ValidEntry)
{ {
@ -147,76 +157,79 @@ void CTLB::WriteEntry(int index, bool Random)
{ {
continue; continue;
} }
if (m_tlb[index].PageMask.Value == g_Reg->PAGE_MASK_REGISTER && if (m_tlb[Index].PageMask.Value == m_Reg.PAGE_MASK_REGISTER &&
m_tlb[index].EntryHi.Value == g_Reg->ENTRYHI_REGISTER.Value) m_tlb[Index].EntryHi.Value == m_Reg.ENTRYHI_REGISTER.Value)
{ {
if (FastIndx == (index << 1) && m_tlb[index].EntryLo0.Value == g_Reg->ENTRYLO0_REGISTER) if (FastIndx == (Index << 1) && m_tlb[Index].EntryLo0.Value == m_Reg.ENTRYLO0_REGISTER)
{ {
continue; continue;
} }
if (FastIndx != (index << 1) && m_tlb[index].EntryLo1.Value == g_Reg->ENTRYLO1_REGISTER) if (FastIndx != (Index << 1) && m_tlb[Index].EntryLo1.Value == m_Reg.ENTRYLO1_REGISTER)
{ {
continue; continue;
} }
} }
m_CB->TLB_Unmaped(m_FastTlb[FastIndx].VSTART, m_FastTlb[FastIndx].Length); TLB_Unmaped(m_FastTlb[FastIndx].VSTART, m_FastTlb[FastIndx].Length);
} }
} }
// Fill in m_tlb entry // Fill in m_tlb entry
m_tlb[index].PageMask.Value = (uint32_t)g_Reg->PAGE_MASK_REGISTER; m_tlb[Index].PageMask.Value = (uint32_t)m_Reg.PAGE_MASK_REGISTER;
m_tlb[index].EntryHi.Value = (uint32_t)g_Reg->ENTRYHI_REGISTER.Value; m_tlb[Index].EntryHi.Value = (uint32_t)m_Reg.ENTRYHI_REGISTER.Value;
m_tlb[index].EntryLo0.Value = (uint32_t)g_Reg->ENTRYLO0_REGISTER; m_tlb[Index].EntryLo0.Value = (uint32_t)m_Reg.ENTRYLO0_REGISTER;
m_tlb[index].EntryLo1.Value = (uint32_t)g_Reg->ENTRYLO1_REGISTER; m_tlb[Index].EntryLo1.Value = (uint32_t)m_Reg.ENTRYLO1_REGISTER;
m_tlb[index].EntryDefined = true; m_tlb[Index].EntryDefined = true;
SetupTLB_Entry(index, Random); SetupTLB_Entry(Index, Random);
m_CB->TLB_Changed(); if (g_Debugger != nullptr)
{
g_Debugger->TLBChanged();
}
} }
void CTLB::SetupTLB_Entry(int index, bool Random) void CTLB::SetupTLB_Entry(uint32_t Index, bool Random)
{ {
// Fix up fast TLB entries // Fix up fast TLB entries
if (!m_tlb[index].EntryDefined) if (!m_tlb[Index].EntryDefined)
{ {
return; return;
} }
int FastIndx = index << 1; uint32_t FastIndx = Index << 1;
if (m_FastTlb[FastIndx].VALID) if (m_FastTlb[FastIndx].VALID)
{ {
m_CB->TLB_Unmaped(m_FastTlb[FastIndx].VSTART, m_FastTlb[FastIndx].Length); TLB_Unmaped(m_FastTlb[FastIndx].VSTART, m_FastTlb[FastIndx].Length);
} }
m_FastTlb[FastIndx].Length = (m_tlb[index].PageMask.Mask << 12) + 0xFFF; m_FastTlb[FastIndx].Length = (uint32_t)((m_tlb[Index].PageMask.Mask << 12) + 0xFFF);
m_FastTlb[FastIndx].VSTART = m_tlb[index].EntryHi.VPN2 << 13; m_FastTlb[FastIndx].VSTART = (uint32_t)(m_tlb[Index].EntryHi.VPN2 << 13);
m_FastTlb[FastIndx].VEND = m_FastTlb[FastIndx].VSTART + m_FastTlb[FastIndx].Length; m_FastTlb[FastIndx].VEND = m_FastTlb[FastIndx].VSTART + m_FastTlb[FastIndx].Length;
m_FastTlb[FastIndx].PHYSSTART = m_tlb[index].EntryLo0.PFN << 12; m_FastTlb[FastIndx].PHYSSTART = (uint32_t)(m_tlb[Index].EntryLo0.PFN << 12);
m_FastTlb[FastIndx].PHYSEND = m_FastTlb[FastIndx].PHYSSTART + m_FastTlb[FastIndx].Length; m_FastTlb[FastIndx].PHYSEND = m_FastTlb[FastIndx].PHYSSTART + m_FastTlb[FastIndx].Length;
m_FastTlb[FastIndx].VALID = m_tlb[index].EntryLo0.V; m_FastTlb[FastIndx].VALID = m_tlb[Index].EntryLo0.V;
m_FastTlb[FastIndx].DIRTY = m_tlb[index].EntryLo0.D; m_FastTlb[FastIndx].DIRTY = m_tlb[Index].EntryLo0.D;
m_FastTlb[FastIndx].GLOBAL = m_tlb[index].EntryLo0.GLOBAL & m_tlb[index].EntryLo1.GLOBAL; m_FastTlb[FastIndx].GLOBAL = m_tlb[Index].EntryLo0.GLOBAL & m_tlb[Index].EntryLo1.GLOBAL;
m_FastTlb[FastIndx].ValidEntry = false; m_FastTlb[FastIndx].ValidEntry = false;
m_FastTlb[FastIndx].Random = Random; m_FastTlb[FastIndx].Random = Random;
m_FastTlb[FastIndx].Probed = false; m_FastTlb[FastIndx].Probed = false;
FastIndx = (index << 1) + 1; FastIndx = (Index << 1) + 1;
if (m_FastTlb[FastIndx].VALID) if (m_FastTlb[FastIndx].VALID)
{ {
m_CB->TLB_Unmaped(m_FastTlb[FastIndx].VSTART, m_FastTlb[FastIndx].Length); TLB_Unmaped(m_FastTlb[FastIndx].VSTART, m_FastTlb[FastIndx].Length);
} }
m_FastTlb[FastIndx].Length = (m_tlb[index].PageMask.Mask << 12) + 0xFFF; m_FastTlb[FastIndx].Length = (uint32_t)((m_tlb[Index].PageMask.Mask << 12) + 0xFFF);
m_FastTlb[FastIndx].VSTART = (m_tlb[index].EntryHi.VPN2 << 13) + (m_FastTlb[FastIndx].Length + 1); m_FastTlb[FastIndx].VSTART = (uint32_t)((m_tlb[Index].EntryHi.VPN2 << 13) + (m_FastTlb[FastIndx].Length + 1));
m_FastTlb[FastIndx].VEND = m_FastTlb[FastIndx].VSTART + m_FastTlb[FastIndx].Length; m_FastTlb[FastIndx].VEND = m_FastTlb[FastIndx].VSTART + m_FastTlb[FastIndx].Length;
m_FastTlb[FastIndx].PHYSSTART = m_tlb[index].EntryLo1.PFN << 12; m_FastTlb[FastIndx].PHYSSTART = (uint32_t)(m_tlb[Index].EntryLo1.PFN << 12);
m_FastTlb[FastIndx].PHYSEND = m_FastTlb[FastIndx].PHYSSTART + m_FastTlb[FastIndx].Length; m_FastTlb[FastIndx].PHYSEND = m_FastTlb[FastIndx].PHYSSTART + m_FastTlb[FastIndx].Length;
m_FastTlb[FastIndx].VALID = m_tlb[index].EntryLo1.V; m_FastTlb[FastIndx].VALID = m_tlb[Index].EntryLo1.V;
m_FastTlb[FastIndx].DIRTY = m_tlb[index].EntryLo1.D; m_FastTlb[FastIndx].DIRTY = m_tlb[Index].EntryLo1.D;
m_FastTlb[FastIndx].GLOBAL = m_tlb[index].EntryLo0.GLOBAL & m_tlb[index].EntryLo1.GLOBAL; m_FastTlb[FastIndx].GLOBAL = m_tlb[Index].EntryLo0.GLOBAL & m_tlb[Index].EntryLo1.GLOBAL;
m_FastTlb[FastIndx].ValidEntry = false; m_FastTlb[FastIndx].ValidEntry = false;
m_FastTlb[FastIndx].Random = Random; m_FastTlb[FastIndx].Random = Random;
m_FastTlb[FastIndx].Probed = false; m_FastTlb[FastIndx].Probed = false;
// Test both entries to see if they are valid // Test both entries to see if they are valid
for (FastIndx = index << 1; FastIndx <= (index << 1) + 1; FastIndx++) for (FastIndx = Index << 1; FastIndx <= (Index << 1) + 1; FastIndx++)
{ {
if (!m_FastTlb[FastIndx].VALID) if (!m_FastTlb[FastIndx].VALID)
{ {
@ -239,7 +252,16 @@ void CTLB::SetupTLB_Entry(int index, bool Random)
// Map the new m_tlb entry for reading and writing // Map the new m_tlb entry for reading and writing
m_FastTlb[FastIndx].ValidEntry = true; m_FastTlb[FastIndx].ValidEntry = true;
m_CB->TLB_Mapped(m_FastTlb[FastIndx].VSTART, m_FastTlb[FastIndx].Length, m_FastTlb[FastIndx].PHYSSTART, !m_FastTlb[FastIndx].DIRTY); m_MMU.TLB_Mapped(m_FastTlb[FastIndx].VSTART, m_FastTlb[FastIndx].Length, m_FastTlb[FastIndx].PHYSSTART, !m_FastTlb[FastIndx].DIRTY);
}
}
void CTLB::TLB_Unmaped(uint32_t VAddr, uint32_t Len)
{
m_MMU.TLB_Unmaped(VAddr, Len);
if (m_Recomp && bSMM_TLB())
{
m_Recomp->ClearRecompCode_Virt(VAddr, Len, CRecompiler::Remove_TLB);
} }
} }

View File

@ -4,111 +4,26 @@
#include <Project64-core/N64System/Mips/Register.h> #include <Project64-core/N64System/Mips/Register.h>
class CDebugTlb; class CDebugTlb;
class CRecompiler;
__interface CTLB_CB
{
virtual void TLB_Mapped(uint32_t VAddr, uint32_t Len, uint32_t PAddr, bool bReadOnly) = 0;
virtual void TLB_Unmaped(uint32_t VAddr, uint32_t Len) = 0;
virtual void TLB_Changed() = 0;
};
#pragma warning(push) #pragma warning(push)
#pragma warning(disable : 4201) // warning C4201: nonstandard extension used : nameless struct/union #pragma warning(disable : 4201) // warning C4201: nonstandard extension used : nameless struct/union
class CTLB : struct TLB_ENTRY
protected CSystemRegisters
{ {
public: bool EntryDefined;
struct TLB_ENTRY COP0PageMask PageMask;
{ COP0EntryHi EntryHi;
bool EntryDefined; COP0EntryLo EntryLo0;
union COP0EntryLo EntryLo1;
{ };
uint32_t Value;
uint8_t A[4];
struct class CTLB :
{ protected CSystemRegisters,
unsigned zero : 13; private CGameSettings
unsigned Mask : 12; {
unsigned zero2 : 7; friend class CDebugTlb;
};
} PageMask;
union
{
uint32_t Value;
uint8_t A[4];
struct
{
unsigned ASID : 8;
unsigned Zero : 4;
unsigned G : 1;
unsigned VPN2 : 19;
};
} EntryHi;
union
{
uint32_t Value;
uint8_t A[4];
struct
{
unsigned GLOBAL : 1;
unsigned V : 1;
unsigned D : 1;
unsigned C : 3;
unsigned PFN : 20;
unsigned ZERO : 6;
};
} EntryLo0;
union
{
uint32_t Value;
uint8_t A[4];
struct
{
unsigned GLOBAL : 1;
unsigned V : 1;
unsigned D : 1;
unsigned C : 3;
unsigned PFN : 20;
unsigned ZERO : 6;
};
} EntryLo1;
};
public:
CTLB(CTLB_CB * CallBack);
~CTLB();
void Reset(bool InvalidateTLB);
// Used by opcodes of the same name to manipulate the TLB (reads the registers)
void Probe();
void ReadEntry();
void WriteEntry(int32_t index, bool Random);
// See if a VAddr has an entry to translate to a PAddr
bool AddressDefined(uint64_t VAddr);
const TLB_ENTRY & TlbEntry(int32_t Entry) const
{
return m_tlb[Entry];
}
bool PAddrToVAddr(uint32_t PAddr, uint32_t & VAddr, uint32_t & Index);
void RecordDifference(CLog & LogFile, const CTLB & rTLB);
bool operator==(const CTLB & rTLB) const;
bool operator!=(const CTLB & rTLB) const;
private:
struct FASTTLB struct FASTTLB
{ {
uint32_t VSTART; uint32_t VSTART;
@ -124,19 +39,35 @@ private:
bool Probed; bool Probed;
}; };
friend class CDebugTlb; // Enable debug window to read class public:
CTLB(CMipsMemoryVM & MMU, CRegisters & Reg, CRecompiler *& Recomp);
~CTLB();
CTLB_CB * const m_CB; void Reset(bool InvalidateTLB);
void Probe();
void ReadEntry();
void WriteEntry(uint32_t index, bool Random);
bool AddressDefined(uint64_t VAddr);
TLB_ENTRY & TlbEntry(int32_t Entry);
bool PAddrToVAddr(uint32_t PAddr, uint32_t & VAddr, uint32_t & Index);
void RecordDifference(CLog & LogFile, const CTLB & rTLB);
TLB_ENTRY m_tlb[32]; bool operator==(const CTLB & rTLB) const;
FASTTLB m_FastTlb[64]; bool operator!=(const CTLB & rTLB) const;
void SetupTLB_Entry(int32_t index, bool Random);
private: private:
CTLB(); CTLB();
CTLB(const CTLB &); CTLB(const CTLB &);
CTLB & operator=(const CTLB &); CTLB & operator=(const CTLB &);
void SetupTLB_Entry(uint32_t index, bool Random);
void TLB_Unmaped(uint32_t VAddr, uint32_t Len);
CMipsMemoryVM & m_MMU;
CRegisters & m_Reg;
CRecompiler *& m_Recomp;
TLB_ENTRY m_tlb[32];
FASTTLB m_FastTlb[64];
}; };
#pragma warning(pop) #pragma warning(pop)

View File

@ -33,7 +33,7 @@ CN64System::CN64System(CPlugins * Plugins, uint32_t randomizer_seed, bool SavesR
m_MMU_VM(*this, SavesReadOnly), m_MMU_VM(*this, SavesReadOnly),
//m_Cheats(m_MMU_VM), //m_Cheats(m_MMU_VM),
m_Reg(*this, *this), m_Reg(*this, *this),
m_TLB(this), m_TLB(m_MMU_VM, m_Reg, m_Recomp),
m_Recomp(nullptr), m_Recomp(nullptr),
m_InReset(false), m_InReset(false),
m_NextTimer(0), m_NextTimer(0),
@ -1672,7 +1672,7 @@ bool CN64System::SaveState()
ZipFile.Delete(); ZipFile.Delete();
zipFile file = zipOpen(ZipFile, 0); zipFile file = zipOpen(ZipFile, 0);
zipOpenNewFileInZip(file, SaveFile.GetNameExtension().c_str(), nullptr, nullptr, 0, nullptr, 0, nullptr, Z_DEFLATED, Z_DEFAULT_COMPRESSION); zipOpenNewFileInZip(file, SaveFile.GetNameExtension().c_str(), nullptr, nullptr, 0, nullptr, 0, nullptr, Z_DEFLATED, Z_DEFAULT_COMPRESSION);
zipWriteInFileInZip(file, &SaveID_0, sizeof(SaveID_0)); zipWriteInFileInZip(file, &SaveID_0_1, sizeof(SaveID_0_1));
zipWriteInFileInZip(file, &RdramSize, sizeof(uint32_t)); zipWriteInFileInZip(file, &RdramSize, sizeof(uint32_t));
if (EnableDisk() && g_Disk) if (EnableDisk() && g_Disk)
{ {
@ -1685,7 +1685,8 @@ bool CN64System::SaveState()
zipWriteInFileInZip(file, g_Rom->GetRomAddress(), 0x40); zipWriteInFileInZip(file, g_Rom->GetRomAddress(), 0x40);
} }
zipWriteInFileInZip(file, &NextViTimer, sizeof(uint32_t)); zipWriteInFileInZip(file, &NextViTimer, sizeof(uint32_t));
zipWriteInFileInZip(file, &m_Reg.m_PROGRAM_COUNTER, sizeof(m_Reg.m_PROGRAM_COUNTER)); int32_t WriteProgramCounter = ((int32_t)m_Reg.m_PROGRAM_COUNTER);
zipWriteInFileInZip(file, &WriteProgramCounter, sizeof(int64_t));
zipWriteInFileInZip(file, m_Reg.m_GPR, sizeof(int64_t) * 32); zipWriteInFileInZip(file, m_Reg.m_GPR, sizeof(int64_t) * 32);
zipWriteInFileInZip(file, m_Reg.m_FPR, sizeof(int64_t) * 32); zipWriteInFileInZip(file, m_Reg.m_FPR, sizeof(int64_t) * 32);
zipWriteInFileInZip(file, m_Reg.m_CP0, sizeof(uint32_t) * 32); zipWriteInFileInZip(file, m_Reg.m_CP0, sizeof(uint32_t) * 32);
@ -1701,7 +1702,7 @@ bool CN64System::SaveState()
zipWriteInFileInZip(file, m_Reg.m_Peripheral_Interface, sizeof(uint32_t) * 13); zipWriteInFileInZip(file, m_Reg.m_Peripheral_Interface, sizeof(uint32_t) * 13);
zipWriteInFileInZip(file, m_Reg.m_RDRAM_Interface, sizeof(uint32_t) * 8); zipWriteInFileInZip(file, m_Reg.m_RDRAM_Interface, sizeof(uint32_t) * 8);
zipWriteInFileInZip(file, m_Reg.m_SerialInterface, sizeof(uint32_t) * 4); zipWriteInFileInZip(file, m_Reg.m_SerialInterface, sizeof(uint32_t) * 4);
zipWriteInFileInZip(file, (void * const)&m_TLB.TlbEntry(0), sizeof(CTLB::TLB_ENTRY) * 32); zipWriteInFileInZip(file, (void * const)&m_TLB.TlbEntry(0), sizeof(TLB_ENTRY) * 32);
zipWriteInFileInZip(file, m_MMU_VM.PifRam().PifRam(), 0x40); zipWriteInFileInZip(file, m_MMU_VM.PifRam().PifRam(), 0x40);
zipWriteInFileInZip(file, m_MMU_VM.Rdram(), RdramSize); zipWriteInFileInZip(file, m_MMU_VM.Rdram(), RdramSize);
zipWriteInFileInZip(file, m_MMU_VM.Dmem(), 0x1000); zipWriteInFileInZip(file, m_MMU_VM.Dmem(), 0x1000);
@ -1742,7 +1743,7 @@ bool CN64System::SaveState()
// Write info to file // Write info to file
hSaveFile.SeekToBegin(); hSaveFile.SeekToBegin();
hSaveFile.Write(&SaveID_0, sizeof(uint32_t)); hSaveFile.Write(&SaveID_0_1, sizeof(uint32_t));
hSaveFile.Write(&RdramSize, sizeof(uint32_t)); hSaveFile.Write(&RdramSize, sizeof(uint32_t));
if (EnableDisk() && g_Disk) if (EnableDisk() && g_Disk)
{ {
@ -1755,10 +1756,11 @@ bool CN64System::SaveState()
hSaveFile.Write(g_Rom->GetRomAddress(), 0x40); hSaveFile.Write(g_Rom->GetRomAddress(), 0x40);
} }
hSaveFile.Write(&NextViTimer, sizeof(uint32_t)); hSaveFile.Write(&NextViTimer, sizeof(uint32_t));
hSaveFile.Write(&m_Reg.m_PROGRAM_COUNTER, sizeof(m_Reg.m_PROGRAM_COUNTER)); int32_t WriteProgramCounter = ((int32_t)m_Reg.m_PROGRAM_COUNTER);
hSaveFile.Write(&WriteProgramCounter, sizeof(int64_t));
hSaveFile.Write(m_Reg.m_GPR, sizeof(int64_t) * 32); hSaveFile.Write(m_Reg.m_GPR, sizeof(int64_t) * 32);
hSaveFile.Write(m_Reg.m_FPR, sizeof(int64_t) * 32); hSaveFile.Write(m_Reg.m_FPR, sizeof(int64_t) * 32);
hSaveFile.Write(m_Reg.m_CP0, sizeof(uint32_t) * 32); hSaveFile.Write(m_Reg.m_CP0, sizeof(uint64_t) * 32);
hSaveFile.Write(m_Reg.m_FPCR, sizeof(uint32_t) * 32); hSaveFile.Write(m_Reg.m_FPCR, sizeof(uint32_t) * 32);
hSaveFile.Write(&m_Reg.m_HI, sizeof(int64_t)); hSaveFile.Write(&m_Reg.m_HI, sizeof(int64_t));
hSaveFile.Write(&m_Reg.m_LO, sizeof(int64_t)); hSaveFile.Write(&m_Reg.m_LO, sizeof(int64_t));
@ -1771,7 +1773,7 @@ bool CN64System::SaveState()
hSaveFile.Write(m_Reg.m_Peripheral_Interface, sizeof(uint32_t) * 13); hSaveFile.Write(m_Reg.m_Peripheral_Interface, sizeof(uint32_t) * 13);
hSaveFile.Write(m_Reg.m_RDRAM_Interface, sizeof(uint32_t) * 8); hSaveFile.Write(m_Reg.m_RDRAM_Interface, sizeof(uint32_t) * 8);
hSaveFile.Write(m_Reg.m_SerialInterface, sizeof(uint32_t) * 4); hSaveFile.Write(m_Reg.m_SerialInterface, sizeof(uint32_t) * 4);
hSaveFile.Write(&m_TLB.TlbEntry(0), sizeof(CTLB::TLB_ENTRY) * 32); hSaveFile.Write(&m_TLB.TlbEntry(0), sizeof(TLB_ENTRY) * 32);
hSaveFile.Write(g_MMU->PifRam().PifRam(), 0x40); hSaveFile.Write(g_MMU->PifRam().PifRam(), 0x40);
hSaveFile.Write(g_MMU->Rdram(), RdramSize); hSaveFile.Write(g_MMU->Rdram(), RdramSize);
hSaveFile.Write(g_MMU->Dmem(), 0x1000); hSaveFile.Write(g_MMU->Dmem(), 0x1000);
@ -1917,8 +1919,9 @@ bool CN64System::LoadState(const char * FileName)
port = -1; port = -1;
continue; continue;
} }
unzReadCurrentFile(file, &Value, 4); uint32_t SaveID;
if (!LoadedZipFile && Value == SaveID_0 && port == UNZ_OK) unzReadCurrentFile(file, &SaveID, 4);
if (!LoadedZipFile && (SaveID == SaveID_0 || SaveID == SaveID_0_1) && port == UNZ_OK)
{ {
unzReadCurrentFile(file, &SaveRDRAMSize, sizeof(SaveRDRAMSize)); unzReadCurrentFile(file, &SaveRDRAMSize, sizeof(SaveRDRAMSize));
// Check header // Check header
@ -1950,10 +1953,34 @@ bool CN64System::LoadState(const char * FileName)
m_MMU_VM.UnProtectMemory(0xA4001000, 0xA4001FFC); m_MMU_VM.UnProtectMemory(0xA4001000, 0xA4001FFC);
g_Settings->SaveDword(Game_RDRamSize, SaveRDRAMSize); g_Settings->SaveDword(Game_RDRamSize, SaveRDRAMSize);
unzReadCurrentFile(file, &NextVITimer, sizeof(NextVITimer)); unzReadCurrentFile(file, &NextVITimer, sizeof(NextVITimer));
unzReadCurrentFile(file, &m_Reg.m_PROGRAM_COUNTER, sizeof(m_Reg.m_PROGRAM_COUNTER)); if (SaveID == 0x23D8A6C8)
{
uint32_t ReadProgramCounter;
unzReadCurrentFile(file, &ReadProgramCounter, sizeof(ReadProgramCounter));
m_Reg.m_PROGRAM_COUNTER = ReadProgramCounter;
}
else
{
uint64_t ReadProgramCounter;
unzReadCurrentFile(file, &ReadProgramCounter, sizeof(ReadProgramCounter));
m_Reg.m_PROGRAM_COUNTER = (uint32_t)ReadProgramCounter;
}
unzReadCurrentFile(file, m_Reg.m_GPR, sizeof(int64_t) * 32); unzReadCurrentFile(file, m_Reg.m_GPR, sizeof(int64_t) * 32);
unzReadCurrentFile(file, m_Reg.m_FPR, sizeof(int64_t) * 32); unzReadCurrentFile(file, m_Reg.m_FPR, sizeof(int64_t) * 32);
unzReadCurrentFile(file, m_Reg.m_CP0, sizeof(uint32_t) * 32); if (SaveID == 0x23D8A6C8)
{
uint32_t ReadCP0[32];
unzReadCurrentFile(file, &ReadCP0, sizeof(uint32_t) * 32);
for (uint32_t i = 0; i < 32; i++)
{
m_Reg.m_CP0[i] = ReadCP0[i];
}
}
else
{
unzReadCurrentFile(file, m_Reg.m_CP0, sizeof(uint64_t) * 32);
}
unzReadCurrentFile(file, m_Reg.m_FPCR, sizeof(uint32_t) * 32); unzReadCurrentFile(file, m_Reg.m_FPCR, sizeof(uint32_t) * 32);
unzReadCurrentFile(file, &m_Reg.m_HI, sizeof(int64_t)); unzReadCurrentFile(file, &m_Reg.m_HI, sizeof(int64_t));
unzReadCurrentFile(file, &m_Reg.m_LO, sizeof(int64_t)); unzReadCurrentFile(file, &m_Reg.m_LO, sizeof(int64_t));
@ -1966,7 +1993,32 @@ bool CN64System::LoadState(const char * FileName)
unzReadCurrentFile(file, m_Reg.m_Peripheral_Interface, sizeof(uint32_t) * 13); unzReadCurrentFile(file, m_Reg.m_Peripheral_Interface, sizeof(uint32_t) * 13);
unzReadCurrentFile(file, m_Reg.m_RDRAM_Interface, sizeof(uint32_t) * 8); unzReadCurrentFile(file, m_Reg.m_RDRAM_Interface, sizeof(uint32_t) * 8);
unzReadCurrentFile(file, m_Reg.m_SerialInterface, sizeof(uint32_t) * 4); unzReadCurrentFile(file, m_Reg.m_SerialInterface, sizeof(uint32_t) * 4);
unzReadCurrentFile(file, (void * const)&m_TLB.TlbEntry(0), sizeof(CTLB::TLB_ENTRY) * 32); if (SaveID == 0x23D8A6C8)
{
struct TLB_ENTRY_OLD
{
bool EntryDefined;
uint32_t PageMask;
uint32_t EntryHi;
uint32_t EntryLo0;
uint32_t EntryLo1;
};
TLB_ENTRY_OLD Tlb[32];
unzReadCurrentFile(file, (void * const)&Tlb, sizeof(TLB_ENTRY_OLD) * 32);
for (uint32_t i = 0; i < 32; i++)
{
TLB_ENTRY & Entry = m_TLB.TlbEntry(i);
Entry.EntryDefined = Tlb[i].EntryDefined;
Entry.PageMask.Value = Tlb[i].PageMask;
Entry.EntryHi.Value = Tlb[i].EntryHi;
Entry.EntryLo0.Value = Tlb[i].EntryLo0;
Entry.EntryLo1.Value = Tlb[i].EntryLo1;
}
}
else
{
unzReadCurrentFile(file, (void * const)&m_TLB.TlbEntry(0), sizeof(TLB_ENTRY) * 32);
}
unzReadCurrentFile(file, m_MMU_VM.PifRam().PifRam(), 0x40); unzReadCurrentFile(file, m_MMU_VM.PifRam().PifRam(), 0x40);
unzReadCurrentFile(file, m_MMU_VM.Rdram(), SaveRDRAMSize); unzReadCurrentFile(file, m_MMU_VM.Rdram(), SaveRDRAMSize);
unzReadCurrentFile(file, m_MMU_VM.Dmem(), 0x1000); unzReadCurrentFile(file, m_MMU_VM.Dmem(), 0x1000);
@ -2010,8 +2062,9 @@ bool CN64System::LoadState(const char * FileName)
} }
hSaveFile.SeekToBegin(); hSaveFile.SeekToBegin();
hSaveFile.Read(&Value, sizeof(Value)); uint32_t SaveID;
if (Value != SaveID_0) hSaveFile.Read(&SaveID, sizeof(SaveID));
if (SaveID != SaveID_0 && SaveID != SaveID_0_1)
{ {
return false; return false;
} }
@ -2045,10 +2098,33 @@ bool CN64System::LoadState(const char * FileName)
g_Settings->SaveDword(Game_RDRamSize, SaveRDRAMSize); g_Settings->SaveDword(Game_RDRamSize, SaveRDRAMSize);
hSaveFile.Read(&NextVITimer, sizeof(NextVITimer)); hSaveFile.Read(&NextVITimer, sizeof(NextVITimer));
hSaveFile.Read(&m_Reg.m_PROGRAM_COUNTER, sizeof(m_Reg.m_PROGRAM_COUNTER)); if (SaveID == 0x23D8A6C8)
{
uint32_t ReadProgramCounter;
hSaveFile.Read(&ReadProgramCounter, sizeof(ReadProgramCounter));
m_Reg.m_PROGRAM_COUNTER = ReadProgramCounter;
}
else
{
uint64_t ReadProgramCounter;
hSaveFile.Read(&ReadProgramCounter, sizeof(ReadProgramCounter));
m_Reg.m_PROGRAM_COUNTER = (uint32_t)ReadProgramCounter;
}
hSaveFile.Read(m_Reg.m_GPR, sizeof(int64_t) * 32); hSaveFile.Read(m_Reg.m_GPR, sizeof(int64_t) * 32);
hSaveFile.Read(m_Reg.m_FPR, sizeof(int64_t) * 32); hSaveFile.Read(m_Reg.m_FPR, sizeof(int64_t) * 32);
hSaveFile.Read(m_Reg.m_CP0, sizeof(uint32_t) * 32); if (SaveID == 0x23D8A6C8)
{
uint32_t ReadCP0[32];
hSaveFile.Read(&ReadCP0, sizeof(uint32_t) * 32);
for (uint32_t i = 0; i < 32; i++)
{
m_Reg.m_CP0[i] = ReadCP0[i];
}
}
else
{
hSaveFile.Read(m_Reg.m_CP0, sizeof(uint64_t) * 32);
}
hSaveFile.Read(m_Reg.m_FPCR, sizeof(uint32_t) * 32); hSaveFile.Read(m_Reg.m_FPCR, sizeof(uint32_t) * 32);
hSaveFile.Read(&m_Reg.m_HI, sizeof(int64_t)); hSaveFile.Read(&m_Reg.m_HI, sizeof(int64_t));
hSaveFile.Read(&m_Reg.m_LO, sizeof(int64_t)); hSaveFile.Read(&m_Reg.m_LO, sizeof(int64_t));
@ -2061,7 +2137,32 @@ bool CN64System::LoadState(const char * FileName)
hSaveFile.Read(m_Reg.m_Peripheral_Interface, sizeof(uint32_t) * 13); hSaveFile.Read(m_Reg.m_Peripheral_Interface, sizeof(uint32_t) * 13);
hSaveFile.Read(m_Reg.m_RDRAM_Interface, sizeof(uint32_t) * 8); hSaveFile.Read(m_Reg.m_RDRAM_Interface, sizeof(uint32_t) * 8);
hSaveFile.Read(m_Reg.m_SerialInterface, sizeof(uint32_t) * 4); hSaveFile.Read(m_Reg.m_SerialInterface, sizeof(uint32_t) * 4);
hSaveFile.Read((void * const)&m_TLB.TlbEntry(0), sizeof(CTLB::TLB_ENTRY) * 32); if (SaveID == 0x23D8A6C8)
{
struct TLB_ENTRY_OLD
{
bool EntryDefined;
uint32_t PageMask;
uint32_t EntryHi;
uint32_t EntryLo0;
uint32_t EntryLo1;
};
TLB_ENTRY_OLD Tlb[32];
hSaveFile.Read((void * const)&Tlb, sizeof(TLB_ENTRY_OLD) * 32);
for (uint32_t i = 0; i < 32; i++)
{
TLB_ENTRY & Entry = m_TLB.TlbEntry(i);
Entry.EntryDefined = Tlb[i].EntryDefined;
Entry.PageMask.Value = Tlb[i].PageMask;
Entry.EntryHi.Value = Tlb[i].EntryHi;
Entry.EntryLo0.Value = Tlb[i].EntryLo0;
Entry.EntryLo1.Value = Tlb[i].EntryLo1;
}
}
else
{
hSaveFile.Read((void *)&m_TLB.TlbEntry(0), sizeof(TLB_ENTRY) * 32);
}
hSaveFile.Read(m_MMU_VM.PifRam().PifRam(), 0x40); hSaveFile.Read(m_MMU_VM.PifRam().PifRam(), 0x40);
hSaveFile.Read(m_MMU_VM.Rdram(), SaveRDRAMSize); hSaveFile.Read(m_MMU_VM.Rdram(), SaveRDRAMSize);
hSaveFile.Read(m_MMU_VM.Dmem(), 0x1000); hSaveFile.Read(m_MMU_VM.Dmem(), 0x1000);
@ -2337,11 +2438,6 @@ void CN64System::RefreshScreen()
// if (bProfiling) { m_Profile.StartTimer(ProfilingAddr != Timer_None ? ProfilingAddr : Timer_R4300); } // if (bProfiling) { m_Profile.StartTimer(ProfilingAddr != Timer_None ? ProfilingAddr : Timer_R4300); }
} }
void CN64System::TLB_Mapped(uint32_t VAddr, uint32_t Len, uint32_t PAddr, bool bReadOnly)
{
m_MMU_VM.TLB_Mapped(VAddr, Len, PAddr, bReadOnly);
}
void CN64System::TLB_Unmaped(uint32_t VAddr, uint32_t Len) void CN64System::TLB_Unmaped(uint32_t VAddr, uint32_t Len)
{ {
m_MMU_VM.TLB_Unmaped(VAddr, Len); m_MMU_VM.TLB_Unmaped(VAddr, Len);
@ -2349,12 +2445,4 @@ void CN64System::TLB_Unmaped(uint32_t VAddr, uint32_t Len)
{ {
m_Recomp->ClearRecompCode_Virt(VAddr, Len, CRecompiler::Remove_TLB); m_Recomp->ClearRecompCode_Virt(VAddr, Len, CRecompiler::Remove_TLB);
} }
}
void CN64System::TLB_Changed()
{
if (g_Debugger)
{
g_Debugger->TLBChanged();
}
} }

View File

@ -37,7 +37,6 @@ enum CN64SystemCB
class CN64System : class CN64System :
public CLogging, public CLogging,
public CTLB_CB,
private CSystemEvents, private CSystemEvents,
protected CN64SystemSettings, protected CN64SystemSettings,
public CGameSettings, public CGameSettings,
@ -174,9 +173,7 @@ private:
void CpuStopped(); void CpuStopped();
// Functions in CTLB_CB // Functions in CTLB_CB
void TLB_Mapped(uint32_t VAddr, uint32_t Len, uint32_t PAddr, bool bReadOnly);
void TLB_Unmaped(uint32_t VAddr, uint32_t Len); void TLB_Unmaped(uint32_t VAddr, uint32_t Len);
void TLB_Changed();
SETTING_CALLBACK m_Callback; SETTING_CALLBACK m_Callback;
CPlugins * const m_Plugins; // The plugin container CPlugins * const m_Plugins; // The plugin container
@ -219,7 +216,8 @@ private:
FUNC_CALLS m_FunctionCalls; FUNC_CALLS m_FunctionCalls;
// List of save state file IDs // List of save state file IDs
const uint32_t SaveID_0 = 0x23D8A6C8; // Main save state info (*.pj) const uint32_t SaveID_0 = 0x23D8A6C8; // Main save state info (*.pj)
const uint32_t SaveID_1 = 0x56D2CD23; // Extra data v1 (system timing) info (*.dat) const uint32_t SaveID_0_1 = 0x25EF3FAC; // Main save state info (*.pj)
const uint32_t SaveID_2 = 0x750A6BEB; // Extra data v2 (timing + disk registers) (*.dat) const uint32_t SaveID_1 = 0x56D2CD23; // Extra data v1 (system timing) info (*.dat)
const uint32_t SaveID_2 = 0x750A6BEB; // Extra data v2 (timing + disk registers) (*.dat)
}; };

View File

@ -110,7 +110,7 @@ void CDebugTlb::RefreshTLBWindow(void)
LV_ITEM item, OldItem; LV_ITEM item, OldItem;
int count; int count;
CTLB::TLB_ENTRY * tlb = g_TLB->m_tlb; TLB_ENTRY * tlb = g_TLB->m_tlb;
for (count = 0; count < 32; count++) for (count = 0; count < 32; count++)
{ {
swprintf(Output, sizeof(Output), L"0x%02X", count); swprintf(Output, sizeof(Output), L"0x%02X", count);
@ -139,7 +139,7 @@ void CDebugTlb::RefreshTLBWindow(void)
} }
if (tlb[count].EntryDefined) if (tlb[count].EntryDefined)
{ {
swprintf(Output, sizeof(Output), L"0x%08X", tlb[count].PageMask.Value); swprintf(Output, sizeof(Output), L"0x%I64X", tlb[count].PageMask.Value);
} }
else else
{ {
@ -155,7 +155,7 @@ void CDebugTlb::RefreshTLBWindow(void)
if (tlb[count].EntryDefined) if (tlb[count].EntryDefined)
{ {
swprintf(Output, sizeof(Output), L"0x%08X", tlb[count].EntryHi.Value); swprintf(Output, sizeof(Output), L"0x%I64X", tlb[count].EntryHi.Value);
} }
else else
{ {
@ -171,7 +171,7 @@ void CDebugTlb::RefreshTLBWindow(void)
if (tlb[count].EntryDefined) if (tlb[count].EntryDefined)
{ {
swprintf(Output, sizeof(Output), L"0x%08X", tlb[count].EntryLo0.Value); swprintf(Output, sizeof(Output), L"0x%I64X", tlb[count].EntryLo0.Value);
} }
else else
{ {
@ -187,7 +187,7 @@ void CDebugTlb::RefreshTLBWindow(void)
if (tlb[count].EntryDefined) if (tlb[count].EntryDefined)
{ {
swprintf(Output, sizeof(Output), L"0x%08X", tlb[count].EntryLo1.Value); swprintf(Output, sizeof(Output), L"0x%I64X", tlb[count].EntryLo1.Value);
} }
else else
{ {