2012-12-19 09:30:18 +00:00
|
|
|
/****************************************************************************
|
|
|
|
* *
|
2015-11-10 05:21:49 +00:00
|
|
|
* Project64 - A Nintendo 64 emulator. *
|
2012-12-19 09:30:18 +00:00
|
|
|
* 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
|
2016-01-13 11:15:30 +00:00
|
|
|
#include <Project64-core/N64System/Mips/MemoryVirtualMem.h>
|
2015-12-06 09:59:58 +00:00
|
|
|
#include "TranslateVaddr.h"
|
2016-07-04 07:51:11 +00:00
|
|
|
#include <Project64-core/N64System/Recompiler/RecompilerOps.h>
|
2015-12-06 09:59:58 +00:00
|
|
|
#include <Project64-core/N64System/Interpreter/InterpreterOps.h>
|
|
|
|
#include <Project64-core/N64System/Mips/PifRam.h>
|
|
|
|
#include <Project64-core/N64System/Mips/FlashRam.h>
|
|
|
|
#include <Project64-core/N64System/Mips/Sram.h>
|
|
|
|
#include <Project64-core/N64System/Mips/Dma.h>
|
2012-12-19 09:30:18 +00:00
|
|
|
|
2016-06-04 23:42:49 +00:00
|
|
|
#ifdef __arm__
|
|
|
|
#include <sys/ucontext.h>
|
|
|
|
#endif
|
|
|
|
|
2016-06-05 17:06:27 +00:00
|
|
|
#ifndef _WIN32
|
|
|
|
#include <signal.h>
|
|
|
|
/* siginfo_t */
|
|
|
|
#endif
|
|
|
|
|
2015-09-30 17:45:30 +00:00
|
|
|
/*
|
2016-07-04 09:25:39 +00:00
|
|
|
* To do: Have address translation functions here?
|
|
|
|
* `return` either the translated address or the mask to XOR by?
|
2015-11-08 18:04:32 +00:00
|
|
|
*
|
2016-07-04 09:25:39 +00:00
|
|
|
* 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
|
2015-11-08 18:04:32 +00:00
|
|
|
*/
|
2015-09-30 17:45:30 +00:00
|
|
|
|
2016-07-06 20:14:12 +00:00
|
|
|
#if defined(__i386__) || defined(_M_IX86)
|
2016-07-04 07:51:11 +00:00
|
|
|
class CX86RecompilerOps;
|
2016-11-21 07:06:14 +00:00
|
|
|
#elif defined(__arm__) || defined(_M_ARM)
|
|
|
|
class CArmRecompilerOps;
|
2016-07-06 20:14:12 +00:00
|
|
|
#endif
|
2015-09-07 16:16:36 +00:00
|
|
|
|
2010-05-31 00:21:08 +00:00
|
|
|
class CMipsMemoryVM :
|
2015-11-08 18:04:32 +00:00
|
|
|
public CTransVaddr,
|
|
|
|
private R4300iOp,
|
|
|
|
private CPifRam,
|
|
|
|
private CFlashram,
|
|
|
|
private CSram,
|
|
|
|
private CDMA
|
2010-05-31 00:21:08 +00:00
|
|
|
{
|
|
|
|
public:
|
2016-01-04 20:46:56 +00:00
|
|
|
CMipsMemoryVM(bool SavesReadOnly);
|
2015-11-08 18:04:32 +00:00
|
|
|
~CMipsMemoryVM();
|
|
|
|
|
|
|
|
static void ReserveMemory();
|
|
|
|
static void FreeReservedMemory();
|
|
|
|
|
2015-12-13 07:26:31 +00:00
|
|
|
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);
|
2015-11-08 18:04:32 +00:00
|
|
|
|
|
|
|
int32_t MemoryFilter(uint32_t dwExptCode, void * lpExceptionPointer);
|
|
|
|
void UpdateFieldSerration(uint32_t interlaced);
|
2016-06-04 23:42:49 +00:00
|
|
|
#ifndef _WIN32
|
2016-06-05 17:06:27 +00:00
|
|
|
static bool SetupSegvHandler(void);
|
2016-06-04 23:42:49 +00:00
|
|
|
static void segv_handler(int signal, siginfo_t *siginfo, void *sigcontext);
|
|
|
|
#endif
|
2015-11-08 18:04:32 +00:00
|
|
|
|
|
|
|
//Protect the Memory from being written to
|
|
|
|
void ProtectMemory(uint32_t StartVaddr, uint32_t EndVaddr);
|
|
|
|
void UnProtectMemory(uint32_t StartVaddr, uint32_t EndVaddr);
|
|
|
|
|
|
|
|
//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;
|
2010-05-31 00:21:08 +00:00
|
|
|
|
|
|
|
private:
|
2015-11-08 18:04:32 +00:00
|
|
|
CMipsMemoryVM(); // Disable default constructor
|
|
|
|
CMipsMemoryVM(const CMipsMemoryVM&); // Disable copy constructor
|
|
|
|
CMipsMemoryVM& operator=(const CMipsMemoryVM&); // Disable assignment
|
2012-12-18 10:43:29 +00:00
|
|
|
|
2016-07-06 20:14:12 +00:00
|
|
|
#if defined(__i386__) || defined(_M_IX86)
|
2016-11-27 20:28:13 +00:00
|
|
|
friend class CX86RecompilerOps;
|
2016-09-23 22:40:58 +00:00
|
|
|
#elif defined(__arm__) || defined(_M_ARM)
|
2016-11-27 20:28:13 +00:00
|
|
|
friend class CArmRegInfo;
|
|
|
|
friend class CArmRecompilerOps;
|
2016-07-06 20:14:12 +00:00
|
|
|
#endif
|
2013-01-11 21:57:51 +00:00
|
|
|
|
2015-12-13 07:26:31 +00:00
|
|
|
static void RdramChanged(CMipsMemoryVM * _this);
|
|
|
|
static void ChangeSpStatus();
|
2015-11-08 18:04:32 +00:00
|
|
|
static void ChangeMiIntrMask();
|
2010-06-12 02:02:06 +00:00
|
|
|
|
2015-12-13 07:26:31 +00:00
|
|
|
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);
|
2010-05-31 00:21:08 +00:00
|
|
|
|
2015-12-13 07:26:31 +00:00
|
|
|
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);
|
2010-05-31 00:21:08 +00:00
|
|
|
|
2015-12-21 09:45:08 +00:00
|
|
|
static void Load32RDRAMRegisters(void);
|
2015-12-21 09:49:13 +00:00
|
|
|
static void Load32SPRegisters(void);
|
2015-12-21 09:52:59 +00:00
|
|
|
static void Load32DPCommand(void);
|
2015-12-21 09:56:24 +00:00
|
|
|
static void Load32MIPSInterface(void);
|
2015-12-21 10:01:56 +00:00
|
|
|
static void Load32VideoInterface(void);
|
2015-12-21 10:06:51 +00:00
|
|
|
static void Load32AudioInterface(void);
|
2015-12-21 18:45:07 +00:00
|
|
|
static void Load32PeripheralInterface(void);
|
|
|
|
static void Load32RDRAMInterface(void);
|
2015-12-21 19:59:17 +00:00
|
|
|
static void Load32SerialInterface(void);
|
2016-01-17 06:38:29 +00:00
|
|
|
static void Load32CartridgeDomain1Address1(void);
|
|
|
|
static void Load32CartridgeDomain1Address3(void);
|
2015-12-21 21:03:14 +00:00
|
|
|
static void Load32CartridgeDomain2Address1(void);
|
|
|
|
static void Load32CartridgeDomain2Address2(void);
|
2015-12-21 21:15:26 +00:00
|
|
|
static void Load32PifRam(void);
|
2015-12-21 21:24:37 +00:00
|
|
|
static void Load32Rom(void);
|
2015-12-21 09:45:08 +00:00
|
|
|
|
2015-12-21 21:35:06 +00:00
|
|
|
static void Write32RDRAMRegisters(void);
|
2015-12-21 21:41:49 +00:00
|
|
|
static void Write32SPRegisters(void);
|
2015-12-21 21:49:58 +00:00
|
|
|
static void Write32DPCommandRegisters(void);
|
2015-12-22 05:31:13 +00:00
|
|
|
static void Write32MIPSInterface(void);
|
2015-12-22 05:40:19 +00:00
|
|
|
static void Write32VideoInterface(void);
|
2015-12-22 05:46:08 +00:00
|
|
|
static void Write32AudioInterface(void);
|
2015-12-22 05:51:50 +00:00
|
|
|
static void Write32PeripheralInterface(void);
|
2015-12-22 05:57:18 +00:00
|
|
|
static void Write32RDRAMInterface(void);
|
2015-12-22 06:02:08 +00:00
|
|
|
static void Write32SerialInterface(void);
|
2016-01-19 18:53:18 +00:00
|
|
|
static void Write32CartridgeDomain2Address1(void);
|
2015-12-22 06:09:27 +00:00
|
|
|
static void Write32CartridgeDomain2Address2(void);
|
2015-12-22 08:04:55 +00:00
|
|
|
static void Write32PifRam(void);
|
2015-12-21 21:35:06 +00:00
|
|
|
|
2016-06-04 23:42:49 +00:00
|
|
|
#if defined(__i386__) || defined(_M_IX86)
|
|
|
|
|
2016-07-03 10:17:45 +00:00
|
|
|
typedef struct _X86_CONTEXT
|
2016-06-04 23:42:49 +00:00
|
|
|
{
|
|
|
|
uint32_t * Edi;
|
|
|
|
uint32_t * Esi;
|
|
|
|
uint32_t * Ebx;
|
|
|
|
uint32_t * Edx;
|
|
|
|
uint32_t * Ecx;
|
|
|
|
uint32_t * Eax;
|
|
|
|
uint32_t * Eip;
|
|
|
|
uint32_t * Esp;
|
|
|
|
uint32_t * Ebp;
|
|
|
|
} X86_CONTEXT;
|
|
|
|
|
|
|
|
static bool FilterX86Exception(uint32_t MemAddress, X86_CONTEXT & context);
|
|
|
|
#endif
|
|
|
|
#ifdef __arm__
|
|
|
|
static bool FilterArmException(uint32_t MemAddress, mcontext_t & context);
|
|
|
|
#endif
|
|
|
|
|
2015-11-08 18:04:32 +00:00
|
|
|
//Memory Locations
|
2015-12-13 07:26:31 +00:00
|
|
|
static uint8_t * m_Reserve1, *m_Reserve2;
|
|
|
|
uint8_t * m_RDRAM, *m_DMEM, *m_IMEM;
|
2015-11-08 18:04:32 +00:00
|
|
|
uint32_t m_AllocatedRdramSize;
|
2012-12-18 10:43:29 +00:00
|
|
|
|
2015-11-08 18:04:32 +00:00
|
|
|
//Rom Information
|
|
|
|
bool m_RomMapped;
|
|
|
|
uint8_t * m_Rom;
|
|
|
|
uint32_t m_RomSize;
|
|
|
|
bool m_RomWrittenTo;
|
|
|
|
uint32_t m_RomWroteValue;
|
2012-12-18 10:43:29 +00:00
|
|
|
|
2016-01-18 19:15:01 +00:00
|
|
|
//DDRom Information
|
|
|
|
bool m_DDRomMapped;
|
|
|
|
uint8_t * m_DDRom;
|
|
|
|
uint32_t m_DDRomSize;
|
|
|
|
|
2015-11-08 18:04:32 +00:00
|
|
|
//Current Half line
|
|
|
|
void UpdateHalfLine();
|
|
|
|
uint32_t m_HalfLine;
|
|
|
|
uint32_t m_HalfLineCheck;
|
|
|
|
uint32_t m_FieldSerration;
|
2012-12-18 10:43:29 +00:00
|
|
|
|
2015-11-08 18:04:32 +00:00
|
|
|
//Initializing and resetting information about the memory system
|
|
|
|
void FreeMemory();
|
2012-12-18 10:43:29 +00:00
|
|
|
|
2015-11-08 18:04:32 +00:00
|
|
|
mutable char m_strLabelName[100];
|
2010-05-31 00:21:08 +00:00
|
|
|
|
2015-11-08 18:04:32 +00:00
|
|
|
//BIG look up table to quickly translate the tlb to real mem address
|
|
|
|
size_t * m_TLB_ReadMap;
|
|
|
|
size_t * m_TLB_WriteMap;
|
2015-12-21 09:45:08 +00:00
|
|
|
|
|
|
|
static uint32_t m_MemLookupAddress;
|
|
|
|
static MIPS_DWORD m_MemLookupValue;
|
|
|
|
static bool m_MemLookupValid;
|
2016-06-29 13:40:36 +00:00
|
|
|
static uint32_t RegModValue;
|
2010-05-31 00:21:08 +00:00
|
|
|
};
|