/**************************************************************************** * * * Project64 - A Nintendo 64 emulator. * * http://www.pj64-emu.com/ * * Copyright (C) 2012 Project64. All rights reserved. * * * * License: * * GNU/GPLv2 http://www.gnu.org/licenses/gpl-2.0.html * * * ****************************************************************************/ #pragma once #include "MemoryVirtualMem.h" #include "TranslateVaddr.h" #include #include #include #include #include #include __interface CMipsMemory_CallBack { //Protected memory has been written to, returns true if that memory has been unprotected virtual bool WriteToProtectedMemory(uint32_t Address, int32_t length) = 0; }; /* * 64-bit Windows exception recovery facilities will expect to interact with * the 64-bit registers of the Intel architecture (e.g., rax instead of eax). * * Attempting to read the 32-bit subsets seems to be erroneous and forbidden. * Refer to "MemoryFilter" in `Memory Virtual Mem.cpp`. */ #ifdef _WIN64 #define Eax Rax #define Ebx Rbx #define Ecx Rcx #define Edx Rdx #define Esp Rsp #define Ebp Rbp #define Esi Rsi #define Edi Rdi #define Eip Rip #endif /* * To do: Have address translation functions here? * `return` either the translated address or the mask to XOR by? * * This will help us gradually be able to port Project64 for big-endian CPUs. * Currently it is written to assume 32-bit little-endian, like so: * * 0xAABBCCDD EEFFGGHH --> 0xDDCCBBAA HHGGFFEE * GPR bits[63..0] b1b2b3b4 b5b6b7b8 */ class CMipsMemoryVM : public CTransVaddr, private CRecompilerOps, private R4300iOp, private CPifRam, private CFlashram, private CSram, private CDMA { public: CMipsMemoryVM(CMipsMemory_CallBack * CallBack, bool SavesReadOnly); ~CMipsMemoryVM(); static void ReserveMemory(); static void FreeReservedMemory(); bool Initialize(); void Reset(bool EraseMemory); uint8_t * Rdram(); uint32_t RdramSize(); uint8_t * Dmem(); uint8_t * Imem(); uint8_t * PifRam(); bool LB_VAddr(uint32_t VAddr, uint8_t & Value); bool LH_VAddr(uint32_t VAddr, uint16_t & Value); bool LW_VAddr(uint32_t VAddr, uint32_t & Value); bool LD_VAddr(uint32_t VAddr, uint64_t & Value); bool LB_PAddr(uint32_t PAddr, uint8_t & Value); bool LH_PAddr(uint32_t PAddr, uint16_t & Value); bool LW_PAddr(uint32_t PAddr, uint32_t & Value); bool LD_PAddr(uint32_t PAddr, uint64_t & Value); bool SB_VAddr(uint32_t VAddr, uint8_t Value); bool SH_VAddr(uint32_t VAddr, uint16_t Value); bool SW_VAddr(uint32_t VAddr, uint32_t Value); bool SD_VAddr(uint32_t VAddr, uint64_t Value); bool SB_PAddr(uint32_t PAddr, uint8_t Value); bool SH_PAddr(uint32_t PAddr, uint16_t Value); bool SW_PAddr(uint32_t PAddr, uint32_t Value); bool SD_PAddr(uint32_t PAddr, uint64_t Value); int32_t MemoryFilter(uint32_t dwExptCode, void * lpExceptionPointer); void UpdateFieldSerration(uint32_t interlaced); //Protect the Memory from being written to void ProtectMemory(uint32_t StartVaddr, uint32_t EndVaddr); void UnProtectMemory(uint32_t StartVaddr, uint32_t EndVaddr); //Compilation Functions void ResetMemoryStack(); void Compile_LB(); void Compile_LBU(); void Compile_LH(); void Compile_LHU(); void Compile_LW(); void Compile_LL(); void Compile_LWC1(); void Compile_LWU(); void Compile_LWL(); void Compile_LWR(); void Compile_LD(); void Compile_LDC1(); void Compile_LDL(); void Compile_LDR(); void Compile_SB(); void Compile_SH(); void Compile_SW(); void Compile_SWL(); void Compile_SWR(); void Compile_SD(); void Compile_SDL(); void Compile_SDR(); void Compile_SC(); void Compile_SWC1(); void Compile_SDC1(); void ResetMemoryStack(CRegInfo& RegInfo); void Compile_LB(CX86Ops::x86Reg Reg, uint32_t Addr, bool SignExtend); void Compile_LH(CX86Ops::x86Reg Reg, uint32_t Addr, bool SignExtend); void Compile_LW(CX86Ops::x86Reg Reg, uint32_t Addr); void Compile_SB_Const(uint8_t Value, uint32_t Addr); void Compile_SB_Register(CX86Ops::x86Reg Reg, uint32_t Addr); void Compile_SH_Const(uint16_t Value, uint32_t Addr); void Compile_SH_Register(CX86Ops::x86Reg Reg, uint32_t Addr); void Compile_SW_Const(uint32_t Value, uint32_t Addr); void Compile_SW_Register(CX86Ops::x86Reg Reg, uint32_t Addr); //Functions for TLB notification void TLB_Mapped(uint32_t VAddr, uint32_t Len, uint32_t PAddr, bool bReadOnly); void TLB_Unmaped(uint32_t Vaddr, uint32_t Len); // CTransVaddr interface bool TranslateVaddr(uint32_t VAddr, uint32_t &PAddr) const; bool ValidVaddr(uint32_t VAddr) const; bool VAddrToRealAddr(uint32_t VAddr, void * &RealAddress) const; // Labels const char * LabelName(uint32_t Address) const; private: CMipsMemoryVM(); // Disable default constructor CMipsMemoryVM(const CMipsMemoryVM&); // Disable copy constructor CMipsMemoryVM& operator=(const CMipsMemoryVM&); // Disable assignment void Compile_LW(bool ResultSigned, bool bRecordLLbit); void Compile_SW(bool bCheckLLbit); static void RdramChanged(CMipsMemoryVM * _this); static void ChangeSpStatus(); static void ChangeMiIntrMask(); bool LB_NonMemory(uint32_t PAddr, uint32_t * Value, bool SignExtend); bool LH_NonMemory(uint32_t PAddr, uint32_t * Value, bool SignExtend); bool LW_NonMemory(uint32_t PAddr, uint32_t * Value); bool SB_NonMemory(uint32_t PAddr, uint8_t Value); bool SH_NonMemory(uint32_t PAddr, uint16_t Value); bool SW_NonMemory(uint32_t PAddr, uint32_t Value); void Compile_StoreInstructClean(x86Reg AddressReg, int32_t Length); static void Load32RDRAMRegisters(void); static void Load32SPRegisters(void); static void Load32DPCommand(void); static void Load32MIPSInterface(void); static void Load32VideoInterface(void); static void Load32AudioInterface(void); static void Load32PeripheralInterface(void); static void Load32RDRAMInterface(void); static void Load32SerialInterface(void); static void Load32CartridgeDomain2Address1(void); static void Load32CartridgeDomain2Address2(void); static void Load32PifRam(void); static void Load32Rom(void); static void Write32RDRAMRegisters(void); static void Write32SPRegisters(void); static void Write32DPCommandRegisters(void); static void Write32MIPSInterface(void); static void Write32VideoInterface(void); static void Write32AudioInterface(void); static void Write32PeripheralInterface(void); static void Write32RDRAMInterface(void); static void Write32SerialInterface(void); static void Write32CartridgeDomain2Address2(void); CMipsMemory_CallBack * const m_CBClass; //Memory Locations static uint8_t * m_Reserve1, *m_Reserve2; uint8_t * m_RDRAM, *m_DMEM, *m_IMEM; uint32_t m_AllocatedRdramSize; //Rom Information bool m_RomMapped; uint8_t * m_Rom; uint32_t m_RomSize; bool m_RomWrittenTo; uint32_t m_RomWroteValue; //Current Half line void UpdateHalfLine(); uint32_t m_HalfLine; uint32_t m_HalfLineCheck; uint32_t m_FieldSerration; uint32_t m_TempValue; //Initializing and resetting information about the memory system void FreeMemory(); mutable char m_strLabelName[100]; //BIG look up table to quickly translate the tlb to real mem address size_t * m_TLB_ReadMap; size_t * m_TLB_WriteMap; static uint32_t m_MemLookupAddress; static MIPS_DWORD m_MemLookupValue; static bool m_MemLookupValid; };