Core: Have save states handle COP0/TLB being 64bit now
Core: Clean up tlb class
This commit is contained in:
parent
35105e814e
commit
4b844495b7
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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();
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -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)
|
||||||
};
|
};
|
||||||
|
|
|
@ -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
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue