diff --git a/Source/Project64-core/N64System/Mips/Register.h b/Source/Project64-core/N64System/Mips/Register.h index b2031a467b..9be9ec1249 100644 --- a/Source/Project64-core/N64System/Mips/Register.h +++ b/Source/Project64-core/N64System/Mips/Register.h @@ -19,6 +19,34 @@ #pragma warning(push) #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 { uint64_t Value; diff --git a/Source/Project64-core/N64System/Mips/TLB.cpp b/Source/Project64-core/N64System/Mips/TLB.cpp index d81e5eba3d..1f69b81acc 100644 --- a/Source/Project64-core/N64System/Mips/TLB.cpp +++ b/Source/Project64-core/N64System/Mips/TLB.cpp @@ -1,11 +1,16 @@ #include "stdafx.h" #include "TLB.h" +#include +#include #include +#include #include -CTLB::CTLB(CTLB_CB * CallBack) : - m_CB(CallBack) +CTLB::CTLB(CMipsMemoryVM & MMU, CRegisters & Reg, CRecompiler *& Recomp) : + m_MMU(MMU), + m_Reg(Reg), + m_Recomp(Recomp) { WriteTrace(TraceTLB, TraceDebug, "Start"); memset(m_tlb, 0, sizeof(m_tlb)); @@ -64,12 +69,17 @@ bool CTLB::AddressDefined(uint64_t VAddr) return false; } +TLB_ENTRY & CTLB::TlbEntry(int32_t Entry) +{ + return m_tlb[Entry]; +} + void CTLB::Probe() { int Counter; WriteTrace(TraceTLB, TraceDebug, "Start"); - g_Reg->INDEX_REGISTER |= 0x80000000; + m_Reg.INDEX_REGISTER |= 0x80000000; for (Counter = 0; Counter < 32; Counter++) { if (!m_tlb[Counter].EntryDefined) @@ -77,17 +87,17 @@ void CTLB::Probe() continue; } - uint32_t & TlbEntryHiValue = m_tlb[Counter].EntryHi.Value; - uint32_t Mask = ~m_tlb[Counter].PageMask.Mask << 13; + uint64_t & TlbEntryHiValue = m_tlb[Counter].EntryHi.Value; + uint32_t Mask = (uint32_t)(~m_tlb[Counter].PageMask.Mask << 13); 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 ((TlbEntryHiValue & 0x100) != 0 || // Global - ((TlbEntryHiValue & 0xFF) == (g_Reg->ENTRYHI_REGISTER.Value & 0xFF))) // SameAsid + if ((TlbEntryHiValue & 0x100) != 0 || // Global + ((TlbEntryHiValue & 0xFF) == (m_Reg.ENTRYHI_REGISTER.Value & 0xFF))) // SameAsid { - g_Reg->INDEX_REGISTER = Counter; + m_Reg.INDEX_REGISTER = Counter; int FastIndx = Counter << 1; m_FastTlb[FastIndx].Probed = true; m_FastTlb[FastIndx + 1].Probed = true; @@ -100,24 +110,24 @@ void CTLB::Probe() 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; - g_Reg->ENTRYHI_REGISTER.Value = (m_tlb[index].EntryHi.Value & ~m_tlb[index].PageMask.Value); - g_Reg->ENTRYLO0_REGISTER = m_tlb[index].EntryLo0.Value; - g_Reg->ENTRYLO1_REGISTER = m_tlb[index].EntryLo1.Value; + m_Reg.PAGE_MASK_REGISTER = m_tlb[Index].PageMask.Value; + m_Reg.ENTRYHI_REGISTER.Value = (m_tlb[Index].EntryHi.Value & ~m_tlb[Index].PageMask.Value); + m_Reg.ENTRYLO0_REGISTER = m_tlb[Index].EntryLo0.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 - if (m_tlb[index].EntryDefined) + if (m_tlb[Index].EntryDefined) { - FastIndx = index << 1; + FastIndx = Index << 1; if (*_PROGRAM_COUNTER >= m_FastTlb[FastIndx].VSTART && *_PROGRAM_COUNTER < m_FastTlb[FastIndx].VEND && m_FastTlb[FastIndx].ValidEntry && m_FastTlb[FastIndx].VALID) @@ -135,9 +145,9 @@ void CTLB::WriteEntry(int index, bool Random) } // 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) { @@ -147,76 +157,79 @@ void CTLB::WriteEntry(int index, bool Random) { continue; } - if (m_tlb[index].PageMask.Value == g_Reg->PAGE_MASK_REGISTER && - m_tlb[index].EntryHi.Value == g_Reg->ENTRYHI_REGISTER.Value) + if (m_tlb[Index].PageMask.Value == m_Reg.PAGE_MASK_REGISTER && + 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; } - 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; } } - 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 - m_tlb[index].PageMask.Value = (uint32_t)g_Reg->PAGE_MASK_REGISTER; - m_tlb[index].EntryHi.Value = (uint32_t)g_Reg->ENTRYHI_REGISTER.Value; - m_tlb[index].EntryLo0.Value = (uint32_t)g_Reg->ENTRYLO0_REGISTER; - m_tlb[index].EntryLo1.Value = (uint32_t)g_Reg->ENTRYLO1_REGISTER; - m_tlb[index].EntryDefined = true; - SetupTLB_Entry(index, Random); - m_CB->TLB_Changed(); + m_tlb[Index].PageMask.Value = (uint32_t)m_Reg.PAGE_MASK_REGISTER; + m_tlb[Index].EntryHi.Value = (uint32_t)m_Reg.ENTRYHI_REGISTER.Value; + m_tlb[Index].EntryLo0.Value = (uint32_t)m_Reg.ENTRYLO0_REGISTER; + m_tlb[Index].EntryLo1.Value = (uint32_t)m_Reg.ENTRYLO1_REGISTER; + m_tlb[Index].EntryDefined = true; + SetupTLB_Entry(Index, Random); + 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 - if (!m_tlb[index].EntryDefined) + if (!m_tlb[Index].EntryDefined) { return; } - int FastIndx = index << 1; + uint32_t FastIndx = Index << 1; 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].VSTART = m_tlb[index].EntryHi.VPN2 << 13; + m_FastTlb[FastIndx].Length = (uint32_t)((m_tlb[Index].PageMask.Mask << 12) + 0xFFF); + 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].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].VALID = m_tlb[index].EntryLo0.V; - 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].VALID = m_tlb[Index].EntryLo0.V; + 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].ValidEntry = false; m_FastTlb[FastIndx].Random = Random; m_FastTlb[FastIndx].Probed = false; - FastIndx = (index << 1) + 1; + FastIndx = (Index << 1) + 1; 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].VSTART = (m_tlb[index].EntryHi.VPN2 << 13) + (m_FastTlb[FastIndx].Length + 1); + m_FastTlb[FastIndx].Length = (uint32_t)((m_tlb[Index].PageMask.Mask << 12) + 0xFFF); + 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].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].VALID = m_tlb[index].EntryLo1.V; - 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].VALID = m_tlb[Index].EntryLo1.V; + 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].ValidEntry = false; m_FastTlb[FastIndx].Random = Random; m_FastTlb[FastIndx].Probed = false; // 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) { @@ -239,7 +252,16 @@ void CTLB::SetupTLB_Entry(int index, bool Random) // Map the new m_tlb entry for reading and writing 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); } } diff --git a/Source/Project64-core/N64System/Mips/TLB.h b/Source/Project64-core/N64System/Mips/TLB.h index 9a471ea80b..7f64e80fec 100644 --- a/Source/Project64-core/N64System/Mips/TLB.h +++ b/Source/Project64-core/N64System/Mips/TLB.h @@ -4,111 +4,26 @@ #include class CDebugTlb; - -__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; -}; +class CRecompiler; #pragma warning(push) #pragma warning(disable : 4201) // warning C4201: nonstandard extension used : nameless struct/union -class CTLB : - protected CSystemRegisters +struct TLB_ENTRY { -public: - struct TLB_ENTRY - { - bool EntryDefined; - union - { - uint32_t Value; - uint8_t A[4]; - - struct - { - unsigned zero : 13; - unsigned Mask : 12; - unsigned zero2 : 7; - }; - } 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 EntryDefined; + COP0PageMask PageMask; + COP0EntryHi EntryHi; + COP0EntryLo EntryLo0; + COP0EntryLo EntryLo1; +}; - bool operator==(const CTLB & rTLB) const; - bool operator!=(const CTLB & rTLB) const; +class CTLB : + protected CSystemRegisters, + private CGameSettings +{ + friend class CDebugTlb; -private: struct FASTTLB { uint32_t VSTART; @@ -124,19 +39,35 @@ class CTLB : bool Probed; }; - friend class CDebugTlb; // Enable debug window to read class - - CTLB_CB * const m_CB; +public: + CTLB(CMipsMemoryVM & MMU, CRegisters & Reg, CRecompiler *& Recomp); + ~CTLB(); - TLB_ENTRY m_tlb[32]; - FASTTLB m_FastTlb[64]; + 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); - void SetupTLB_Entry(int32_t index, bool Random); + bool operator==(const CTLB & rTLB) const; + bool operator!=(const CTLB & rTLB) const; private: CTLB(); CTLB(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) diff --git a/Source/Project64-core/N64System/N64System.cpp b/Source/Project64-core/N64System/N64System.cpp index d0893e3a91..85c927d9d6 100644 --- a/Source/Project64-core/N64System/N64System.cpp +++ b/Source/Project64-core/N64System/N64System.cpp @@ -33,7 +33,7 @@ CN64System::CN64System(CPlugins * Plugins, uint32_t randomizer_seed, bool SavesR m_MMU_VM(*this, SavesReadOnly), //m_Cheats(m_MMU_VM), m_Reg(*this, *this), - m_TLB(this), + m_TLB(m_MMU_VM, m_Reg, m_Recomp), m_Recomp(nullptr), m_InReset(false), m_NextTimer(0), @@ -1672,7 +1672,7 @@ bool CN64System::SaveState() ZipFile.Delete(); zipFile file = zipOpen(ZipFile, 0); 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)); if (EnableDisk() && g_Disk) { @@ -1685,7 +1685,8 @@ bool CN64System::SaveState() zipWriteInFileInZip(file, g_Rom->GetRomAddress(), 0x40); } 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_FPR, sizeof(int64_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_RDRAM_Interface, sizeof(uint32_t) * 8); 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.Rdram(), RdramSize); zipWriteInFileInZip(file, m_MMU_VM.Dmem(), 0x1000); @@ -1742,7 +1743,7 @@ bool CN64System::SaveState() // Write info to file hSaveFile.SeekToBegin(); - hSaveFile.Write(&SaveID_0, sizeof(uint32_t)); + hSaveFile.Write(&SaveID_0_1, sizeof(uint32_t)); hSaveFile.Write(&RdramSize, sizeof(uint32_t)); if (EnableDisk() && g_Disk) { @@ -1755,10 +1756,11 @@ bool CN64System::SaveState() hSaveFile.Write(g_Rom->GetRomAddress(), 0x40); } 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_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_HI, 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_RDRAM_Interface, sizeof(uint32_t) * 8); 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->Rdram(), RdramSize); hSaveFile.Write(g_MMU->Dmem(), 0x1000); @@ -1917,8 +1919,9 @@ bool CN64System::LoadState(const char * FileName) port = -1; continue; } - unzReadCurrentFile(file, &Value, 4); - if (!LoadedZipFile && Value == SaveID_0 && port == UNZ_OK) + uint32_t SaveID; + unzReadCurrentFile(file, &SaveID, 4); + if (!LoadedZipFile && (SaveID == SaveID_0 || SaveID == SaveID_0_1) && port == UNZ_OK) { unzReadCurrentFile(file, &SaveRDRAMSize, sizeof(SaveRDRAMSize)); // Check header @@ -1950,10 +1953,34 @@ bool CN64System::LoadState(const char * FileName) m_MMU_VM.UnProtectMemory(0xA4001000, 0xA4001FFC); g_Settings->SaveDword(Game_RDRamSize, SaveRDRAMSize); 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_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_HI, 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_RDRAM_Interface, sizeof(uint32_t) * 8); 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.Rdram(), SaveRDRAMSize); unzReadCurrentFile(file, m_MMU_VM.Dmem(), 0x1000); @@ -2010,8 +2062,9 @@ bool CN64System::LoadState(const char * FileName) } hSaveFile.SeekToBegin(); - hSaveFile.Read(&Value, sizeof(Value)); - if (Value != SaveID_0) + uint32_t SaveID; + hSaveFile.Read(&SaveID, sizeof(SaveID)); + if (SaveID != SaveID_0 && SaveID != SaveID_0_1) { return false; } @@ -2045,10 +2098,33 @@ bool CN64System::LoadState(const char * FileName) g_Settings->SaveDword(Game_RDRamSize, SaveRDRAMSize); 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_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_HI, 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_RDRAM_Interface, sizeof(uint32_t) * 8); 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.Rdram(), SaveRDRAMSize); 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); } } -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) { 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); } -} - -void CN64System::TLB_Changed() -{ - if (g_Debugger) - { - g_Debugger->TLBChanged(); - } } \ No newline at end of file diff --git a/Source/Project64-core/N64System/N64System.h b/Source/Project64-core/N64System/N64System.h index ccdc0b6ff7..0aea37206b 100644 --- a/Source/Project64-core/N64System/N64System.h +++ b/Source/Project64-core/N64System/N64System.h @@ -37,7 +37,6 @@ enum CN64SystemCB class CN64System : public CLogging, - public CTLB_CB, private CSystemEvents, protected CN64SystemSettings, public CGameSettings, @@ -174,9 +173,7 @@ class CN64System : void CpuStopped(); // 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_Changed(); SETTING_CALLBACK m_Callback; CPlugins * const m_Plugins; // The plugin container @@ -219,7 +216,8 @@ class CN64System : FUNC_CALLS m_FunctionCalls; // List of save state file IDs - 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_2 = 0x750A6BEB; // Extra data v2 (timing + disk registers) (*.dat) + const uint32_t SaveID_0 = 0x23D8A6C8; // Main save state info (*.pj) + const uint32_t SaveID_0_1 = 0x25EF3FAC; // Main save state info (*.pj) + 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) }; diff --git a/Source/Project64/UserInterface/Debugger/Debugger-TLB.cpp b/Source/Project64/UserInterface/Debugger/Debugger-TLB.cpp index eccfccf866..b8a5e26d4b 100644 --- a/Source/Project64/UserInterface/Debugger/Debugger-TLB.cpp +++ b/Source/Project64/UserInterface/Debugger/Debugger-TLB.cpp @@ -110,7 +110,7 @@ void CDebugTlb::RefreshTLBWindow(void) LV_ITEM item, OldItem; int count; - CTLB::TLB_ENTRY * tlb = g_TLB->m_tlb; + TLB_ENTRY * tlb = g_TLB->m_tlb; for (count = 0; count < 32; count++) { swprintf(Output, sizeof(Output), L"0x%02X", count); @@ -139,7 +139,7 @@ void CDebugTlb::RefreshTLBWindow(void) } 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 { @@ -155,7 +155,7 @@ void CDebugTlb::RefreshTLBWindow(void) 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 { @@ -171,7 +171,7 @@ void CDebugTlb::RefreshTLBWindow(void) 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 { @@ -187,7 +187,7 @@ void CDebugTlb::RefreshTLBWindow(void) 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 {