/**************************************************************************** * * * 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 * * * ****************************************************************************/ #include "stdafx.h" uint32_t RegModValue; uint8_t * CMipsMemoryVM::m_Reserve1 = NULL; uint8_t * CMipsMemoryVM::m_Reserve2 = NULL; CMipsMemoryVM::CMipsMemoryVM(CMipsMemory_CallBack * CallBack, bool SavesReadOnly) : CPifRam(SavesReadOnly), CFlashram(SavesReadOnly), CSram(SavesReadOnly), CDMA(*this, *this), m_CBClass(CallBack), m_RomMapped(false), m_Rom(NULL), m_RomSize(0), m_RomWrittenTo(false), m_RomWroteValue(0), m_HalfLine(0), m_HalfLineCheck(false), m_FieldSerration(0), m_TempValue(0), m_TLB_ReadMap(NULL), m_TLB_WriteMap(NULL) { g_Settings->RegisterChangeCB(Game_RDRamSize, this, (CSettings::SettingChangedFunc)RdramChanged); m_RDRAM = NULL; m_DMEM = NULL; m_IMEM = NULL; } uint32_t swap32by8(uint32_t word) { const uint32_t swapped = #if defined(_MSC_VER) _byteswap_ulong(word) #elif defined(__GNUC__) __builtin_bswap32(word) #else (word & 0x000000FFul) << 24 | (word & 0x0000FF00ul) << 8 | (word & 0x00FF0000ul) >> 8 | (word & 0xFF000000ul) >> 24 #endif ; return (swapped & 0xFFFFFFFFul); } CMipsMemoryVM::~CMipsMemoryVM() { g_Settings->UnregisterChangeCB(Game_RDRamSize, this, (CSettings::SettingChangedFunc)RdramChanged); FreeMemory(); } void CMipsMemoryVM::Reset(bool /*EraseMemory*/) { if (m_TLB_ReadMap) { size_t address; memset(m_TLB_ReadMap, 0, 0xFFFFF * sizeof(size_t)); memset(m_TLB_WriteMap, 0, 0xFFFFF * sizeof(size_t)); for (address = 0x80000000; address < 0xC0000000; address += 0x1000) { m_TLB_ReadMap[address >> 12] = ((size_t)m_RDRAM + (address & 0x1FFFFFFF)) - address; m_TLB_WriteMap[address >> 12] = ((size_t)m_RDRAM + (address & 0x1FFFFFFF)) - address; } if (g_Settings->LoadDword(Rdb_TLB_VAddrStart) != 0) { size_t Start = g_Settings->LoadDword(Rdb_TLB_VAddrStart); //0x7F000000; size_t Len = g_Settings->LoadDword(Rdb_TLB_VAddrLen); //0x01000000; size_t PAddr = g_Settings->LoadDword(Rdb_TLB_PAddrStart); //0x10034b30; size_t End = Start + Len; for (address = Start; address < End; address += 0x1000) { m_TLB_ReadMap[address >> 12] = ((size_t)m_RDRAM + (address - Start + PAddr)) - address; m_TLB_WriteMap[address >> 12] = ((size_t)m_RDRAM + (address - Start + PAddr)) - address; } } } } void CMipsMemoryVM::ReserveMemory() { m_Reserve1 = (uint8_t *)VirtualAlloc(NULL, 0x20000000, MEM_RESERVE | MEM_TOP_DOWN, PAGE_READWRITE); if (g_Settings->LoadBool(Debugger_Enabled)) { m_Reserve2 = (uint8_t *)VirtualAlloc(NULL, 0x20000000, MEM_RESERVE | MEM_TOP_DOWN, PAGE_READWRITE); } } void CMipsMemoryVM::FreeReservedMemory() { if (m_Reserve1) { VirtualFree(m_Reserve1, 0, MEM_RELEASE); m_Reserve1 = NULL; } if (m_Reserve2) { VirtualFree(m_Reserve2, 0, MEM_RELEASE); m_Reserve2 = NULL; } } bool CMipsMemoryVM::Initialize() { if (m_RDRAM != NULL) { return true; } if (m_Reserve1) { m_RDRAM = m_Reserve1; m_Reserve1 = NULL; } if (m_RDRAM == NULL && m_Reserve2) { m_RDRAM = m_Reserve2; m_Reserve2 = NULL; } if (m_RDRAM == NULL) { m_RDRAM = (uint8_t *)VirtualAlloc(NULL, 0x20000000, MEM_RESERVE | MEM_TOP_DOWN, PAGE_READWRITE); } if (m_RDRAM == NULL) { WriteTraceF(TraceError, __FUNCTION__ ": Failed to Reserve RDRAM (Size: 0x%X)", 0x20000000); FreeMemory(); return false; } m_AllocatedRdramSize = g_Settings->LoadDword(Game_RDRamSize); if (VirtualAlloc(m_RDRAM, m_AllocatedRdramSize, MEM_COMMIT, PAGE_READWRITE) == NULL) { WriteTraceF(TraceError, __FUNCTION__ ": Failed to Allocate RDRAM (Size: 0x%X)", m_AllocatedRdramSize); FreeMemory(); return false; } if (VirtualAlloc(m_RDRAM + 0x04000000, 0x2000, MEM_COMMIT, PAGE_READWRITE) == NULL) { WriteTraceF(TraceError, __FUNCTION__ ": Failed to Allocate DMEM/IMEM (Size: 0x%X)", 0x2000); FreeMemory(); return false; } m_DMEM = (uint8_t *)(m_RDRAM + 0x04000000); m_IMEM = (uint8_t *)(m_RDRAM + 0x04001000); if (g_Settings->LoadBool(Game_LoadRomToMemory)) { m_RomMapped = true; m_Rom = m_RDRAM + 0x10000000; m_RomSize = g_Rom->GetRomSize(); if (VirtualAlloc(m_Rom, g_Rom->GetRomSize(), MEM_COMMIT, PAGE_READWRITE) == NULL) { WriteTraceF(TraceError, __FUNCTION__ ": Failed to Allocate Rom (Size: 0x%X)", g_Rom->GetRomSize()); FreeMemory(); return false; } memcpy(m_Rom, g_Rom->GetRomAddress(), g_Rom->GetRomSize()); DWORD OldProtect; VirtualProtect(m_Rom, g_Rom->GetRomSize(), PAGE_READONLY, &OldProtect); } else { m_RomMapped = false; m_Rom = g_Rom->GetRomAddress(); m_RomSize = g_Rom->GetRomSize(); } CPifRam::Reset(); m_TLB_ReadMap = (size_t *)VirtualAlloc( NULL, 0xFFFFF * sizeof(size_t), MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE ); if (m_TLB_ReadMap == NULL) { WriteTraceF(TraceError, __FUNCTION__": Failed to Allocate m_TLB_ReadMap (Size: 0x%X)", 0xFFFFF * sizeof(size_t)); FreeMemory(); return false; } m_TLB_WriteMap = (size_t *)VirtualAlloc( NULL, 0xFFFFF * sizeof(size_t), MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE ); if (m_TLB_WriteMap == NULL) { WriteTraceF(TraceError, __FUNCTION__": Failed to Allocate m_TLB_WriteMap (Size: 0x%X)", 0xFFFFF * sizeof(size_t)); FreeMemory(); return false; } Reset(false); return true; } void CMipsMemoryVM::FreeMemory() { if (m_RDRAM) { if (VirtualFree(m_RDRAM, 0x20000000, MEM_DECOMMIT) != 0) { if (m_Reserve1 == NULL) { m_Reserve1 = m_RDRAM; } else if (m_Reserve2 == NULL) { m_Reserve2 = m_RDRAM; } else { VirtualFree(m_RDRAM, 0, MEM_RELEASE); } } else { VirtualFree(m_RDRAM, 0, MEM_RELEASE); } m_RDRAM = NULL; m_IMEM = NULL; m_DMEM = NULL; } if (m_TLB_ReadMap) { VirtualFree(m_TLB_ReadMap, 0, MEM_RELEASE); m_TLB_ReadMap = NULL; } if (m_TLB_WriteMap) { VirtualFree(m_TLB_WriteMap, 0, MEM_RELEASE); m_TLB_WriteMap = NULL; } CPifRam::Reset(); } uint8_t * CMipsMemoryVM::Rdram() { return m_RDRAM; } uint32_t CMipsMemoryVM::RdramSize() { return m_AllocatedRdramSize; } uint8_t * CMipsMemoryVM::Dmem() { return m_DMEM; } uint8_t * CMipsMemoryVM::Imem() { return m_IMEM; } uint8_t * CMipsMemoryVM::PifRam() { return m_PifRam; } bool CMipsMemoryVM::LB_VAddr(uint32_t VAddr, uint8_t& Value) { if (m_TLB_ReadMap[VAddr >> 12] == 0) { return false; } Value = *(uint8_t*)(m_TLB_ReadMap[VAddr >> 12] + (VAddr ^ 3)); return true; } bool CMipsMemoryVM::LH_VAddr(uint32_t VAddr, uint16_t& Value) { if (m_TLB_ReadMap[VAddr >> 12] == 0) { return false; } Value = *(uint16_t*)(m_TLB_ReadMap[VAddr >> 12] + (VAddr ^ 2)); return true; } bool CMipsMemoryVM::LW_VAddr(uint32_t VAddr, uint32_t& Value) { if (VAddr >= 0xA3F00000 && VAddr < 0xC0000000) { if (VAddr < 0xA4000000 || VAddr >= 0xA4002000) { VAddr &= 0x1FFFFFFF; LW_NonMemory(VAddr, &Value); return true; } } uint8_t* BaseAddress = (uint8_t*)m_TLB_ReadMap[VAddr >> 12]; if (BaseAddress == NULL) { return false; } Value = *(uint32_t*)(BaseAddress + VAddr); // if (LookUpMode == FuncFind_ChangeMemory) // { // g_Notify->BreakPoint(__FILEW__,__LINE__); // if ( (Command.Hex >> 16) == 0x7C7C) // { // Command.Hex = OrigMem[(Command.Hex & 0xFFFF)].OriginalValue; // } // } return true; } bool CMipsMemoryVM::LD_VAddr(uint32_t VAddr, uint64_t& Value) { if (m_TLB_ReadMap[VAddr >> 12] == 0) { return false; } *((uint32_t*)(&Value) + 1) = *(uint32_t*)(m_TLB_ReadMap[VAddr >> 12] + VAddr); *((uint32_t*)(&Value) + 0) = *(uint32_t*)(m_TLB_ReadMap[VAddr >> 12] + VAddr + 4); return true; } bool CMipsMemoryVM::LB_PAddr(uint32_t PAddr, uint8_t& Value) { if (PAddr < RdramSize()) { Value = *(uint8_t*)(m_RDRAM + (PAddr ^ 3)); return true; } if (PAddr > 0x18000000) { return false; } g_Notify->BreakPoint(__FILEW__, __LINE__); return false; } bool CMipsMemoryVM::LH_PAddr(uint32_t PAddr, uint16_t& Value) { if (PAddr < RdramSize()) { Value = *(uint16_t*)(m_RDRAM + (PAddr ^ 2)); return true; } if (PAddr > 0x18000000) { return false; } g_Notify->BreakPoint(__FILEW__, __LINE__); return false; } bool CMipsMemoryVM::LW_PAddr(uint32_t PAddr, uint32_t& Value) { if (PAddr < RdramSize()) { Value = *(uint32_t*)(m_RDRAM + PAddr); return true; } if (PAddr > 0x18000000) { return false; } g_Notify->BreakPoint(__FILEW__, __LINE__); return false; } bool CMipsMemoryVM::LD_PAddr(uint32_t PAddr, uint64_t& Value) { if (PAddr < RdramSize()) { *((uint32_t*)(&Value) + 1) = *(uint32_t*)(m_RDRAM + PAddr); *((uint32_t*)(&Value) + 0) = *(uint32_t*)(m_RDRAM + PAddr + 4); return true; } if (PAddr > 0x18000000) { return false; } g_Notify->BreakPoint(__FILEW__, __LINE__); return false; } bool CMipsMemoryVM::SB_VAddr(uint32_t VAddr, uint8_t Value) { if (m_TLB_WriteMap[VAddr >> 12] == 0) { return false; } *(uint8_t*)(m_TLB_WriteMap[VAddr >> 12] + (VAddr ^ 3)) = Value; return true; } bool CMipsMemoryVM::SH_VAddr(uint32_t VAddr, uint16_t Value) { if (m_TLB_WriteMap[VAddr >> 12] == 0) { return false; } *(uint16_t*)(m_TLB_WriteMap[VAddr >> 12] + (VAddr ^ 2)) = Value; return true; } bool CMipsMemoryVM::SW_VAddr(uint32_t VAddr, uint32_t Value) { if (VAddr >= 0xA3F00000 && VAddr < 0xC0000000) { if (VAddr < 0xA4000000 || VAddr >= 0xA4002000) { VAddr &= 0x1FFFFFFF; SW_NonMemory(VAddr, Value); return true; } } if (m_TLB_WriteMap[VAddr >> 12] == 0) { return false; } *(uint32_t*)(m_TLB_WriteMap[VAddr >> 12] + VAddr) = Value; return true; } bool CMipsMemoryVM::SD_VAddr(uint32_t VAddr, uint64_t Value) { if (m_TLB_WriteMap[VAddr >> 12] == 0) { return false; } *(uint32_t*)(m_TLB_WriteMap[VAddr >> 12] + VAddr + 0) = *((uint32_t*)(&Value) + 1); *(uint32_t*)(m_TLB_WriteMap[VAddr >> 12] + VAddr + 4) = *((uint32_t*)(&Value)); return true; } bool CMipsMemoryVM::SB_PAddr(uint32_t PAddr, uint8_t Value) { if (PAddr < RdramSize()) { *(uint8_t*)(m_RDRAM + (PAddr ^ 3)) = Value; return true; } if (PAddr > 0x18000000) { return false; } g_Notify->BreakPoint(__FILEW__, __LINE__); return false; } bool CMipsMemoryVM::SH_PAddr(uint32_t PAddr, uint16_t Value) { if (PAddr < RdramSize()) { *(uint16_t*)(m_RDRAM + (PAddr ^ 2)) = Value; return true; } if (PAddr > 0x18000000) { return false; } g_Notify->BreakPoint(__FILEW__, __LINE__); return false; } bool CMipsMemoryVM::SW_PAddr(uint32_t PAddr, uint32_t Value) { if (PAddr < RdramSize()) { *(uint32_t*)(m_RDRAM + PAddr) = Value; return true; } if (PAddr > 0x18000000) { return false; } g_Notify->BreakPoint(__FILEW__, __LINE__); return false; } bool CMipsMemoryVM::SD_PAddr(uint32_t PAddr, uint64_t Value) { if (PAddr < RdramSize()) { *(uint32_t*)(m_RDRAM + PAddr + 0) = *((uint32_t*)(&Value) + 1); *(uint32_t*)(m_RDRAM + PAddr + 4) = *((uint32_t*)(&Value)); return true; } if (PAddr > 0x18000000) { return false; } g_Notify->BreakPoint(__FILEW__, __LINE__); return false; } bool CMipsMemoryVM::ValidVaddr(uint32_t VAddr) const { return m_TLB_ReadMap[VAddr >> 12] != 0; } bool CMipsMemoryVM::VAddrToRealAddr(uint32_t VAddr, void * &RealAddress) const { if (m_TLB_ReadMap[VAddr >> 12] == 0) { return false; } RealAddress = (uint8_t *)(m_TLB_ReadMap[VAddr >> 12] + VAddr); return true; } bool CMipsMemoryVM::TranslateVaddr(uint32_t VAddr, uint32_t &PAddr) const { //Change the Virtual address to a Physical Address if (m_TLB_ReadMap[VAddr >> 12] == 0) { return false; } PAddr = (uint32_t)((uint8_t *)(m_TLB_ReadMap[VAddr >> 12] + VAddr) - m_RDRAM); return true; } void CMipsMemoryVM::Compile_LB(x86Reg Reg, uint32_t VAddr, bool SignExtend) { uint32_t PAddr; char VarName[100]; if (VAddr < 0x80000000 || VAddr >= 0xC0000000) { if (!g_System->bUseTlb()) { g_Notify->BreakPoint(__FILEW__, __LINE__); return; } x86Reg TlbMappReg = Map_TempReg(x86_Any, -1, false); MoveConstToX86reg(VAddr >> 12, TlbMappReg); x86Reg AddrReg = Map_TempReg(x86_Any, -1, false); MoveConstToX86reg(VAddr, AddrReg); MoveVariableDispToX86Reg(m_TLB_ReadMap, "m_TLB_ReadMap", TlbMappReg, TlbMappReg, 4); CompileReadTLBMiss(AddrReg, TlbMappReg); if (SignExtend) { MoveSxByteX86regPointerToX86reg(AddrReg, TlbMappReg, Reg); } else { MoveZxByteX86regPointerToX86reg(AddrReg, TlbMappReg, Reg); } return; } if (!TranslateVaddr(VAddr, PAddr)) { MoveConstToX86reg(0, Reg); CPU_Message("Compile_LB\nFailed to translate address %08X", VAddr); if (g_Settings->LoadBool(Debugger_ShowUnhandledMemory)) { g_Notify->DisplayError(stdstr_f(__FUNCTION__ "\nFailed to translate address %08X", VAddr).ToUTF16().c_str()); } return; } switch (PAddr & 0xFFF00000) { case 0x00000000: case 0x00100000: case 0x00200000: case 0x00300000: case 0x00400000: case 0x00500000: case 0x00600000: case 0x00700000: case 0x10000000: sprintf(VarName, "m_RDRAM + %X", PAddr); if (SignExtend) { MoveSxVariableToX86regByte(PAddr + m_RDRAM, VarName, Reg); } else { MoveZxVariableToX86regByte(PAddr + m_RDRAM, VarName, Reg); } break; default: MoveConstToX86reg(0, Reg); if (g_Settings->LoadBool(Debugger_ShowUnhandledMemory)) { g_Notify->DisplayError(stdstr_f(__FUNCTION__ "\nFailed to compile address: %08X", VAddr).ToUTF16().c_str()); } } } void CMipsMemoryVM::Compile_LH(x86Reg Reg, uint32_t VAddr, bool SignExtend) { char VarName[100]; uint32_t PAddr; if (VAddr < 0x80000000 || VAddr >= 0xC0000000) { if (!g_System->bUseTlb()) { g_Notify->BreakPoint(__FILEW__, __LINE__); return; } x86Reg TlbMappReg = Map_TempReg(x86_Any, -1, false); MoveConstToX86reg(VAddr >> 12, TlbMappReg); x86Reg AddrReg = Map_TempReg(x86_Any, -1, false); MoveConstToX86reg(VAddr, AddrReg); MoveVariableDispToX86Reg(m_TLB_ReadMap, "m_TLB_ReadMap", TlbMappReg, TlbMappReg, 4); CompileReadTLBMiss(AddrReg, TlbMappReg); if (SignExtend) { MoveSxHalfX86regPointerToX86reg(AddrReg, TlbMappReg, Reg); } else { MoveZxHalfX86regPointerToX86reg(AddrReg, TlbMappReg, Reg); } return; } if (!TranslateVaddr(VAddr, PAddr)) { MoveConstToX86reg(0, Reg); CPU_Message("Compile_LH\nFailed to translate address %08X", VAddr); if (g_Settings->LoadBool(Debugger_ShowUnhandledMemory)) { g_Notify->DisplayError(stdstr_f(__FUNCTION__ "\nFailed to translate address %08X", VAddr).ToUTF16().c_str()); } return; } switch (PAddr & 0xFFF00000) { case 0x00000000: case 0x00100000: case 0x00200000: case 0x00300000: case 0x00400000: case 0x00500000: case 0x00600000: case 0x00700000: case 0x10000000: sprintf(VarName, "m_RDRAM + %X", PAddr); if (SignExtend) { MoveSxVariableToX86regHalf(PAddr + m_RDRAM, VarName, Reg); } else { MoveZxVariableToX86regHalf(PAddr + m_RDRAM, VarName, Reg); } break; default: MoveConstToX86reg(0, Reg); if (g_Settings->LoadBool(Debugger_ShowUnhandledMemory)) { g_Notify->DisplayError(stdstr_f(__FUNCTION__ "\nFailed to compile address: %08X", VAddr).ToUTF16().c_str()); } } } void CMipsMemoryVM::Compile_LW(x86Reg Reg, uint32_t VAddr) { char VarName[100]; uint32_t PAddr; m_RegWorkingSet.SetX86Protected(Reg, true); if (VAddr < 0x80000000 || VAddr >= 0xC0000000) { if (!g_System->bUseTlb()) { g_Notify->BreakPoint(__FILEW__, __LINE__); return; } x86Reg TlbMappReg = Map_TempReg(x86_Any, -1, false); MoveConstToX86reg(VAddr >> 12, TlbMappReg); MoveVariableDispToX86Reg(m_TLB_ReadMap, "m_TLB_ReadMap", TlbMappReg, TlbMappReg, 4); CompileReadTLBMiss(VAddr, TlbMappReg); AddConstToX86Reg(TlbMappReg, VAddr); MoveX86PointerToX86reg(Reg, TlbMappReg); } else { if (!TranslateVaddr(VAddr, PAddr)) { g_Notify->BreakPoint(__FILEW__, __LINE__); } switch (PAddr & 0xFFF00000) { case 0x00000000: case 0x00100000: case 0x00200000: case 0x00300000: case 0x00400000: case 0x00500000: case 0x00600000: case 0x00700000: sprintf(VarName, "m_RDRAM + %X", PAddr); MoveVariableToX86reg(PAddr + m_RDRAM, VarName, Reg); break; case 0x04000000: if (PAddr < 0x04002000) { sprintf(VarName, "m_RDRAM + %X", PAddr); MoveVariableToX86reg(PAddr + m_RDRAM, VarName, Reg); break; } switch (PAddr) { case 0x04040010: MoveVariableToX86reg(&g_Reg->SP_STATUS_REG, "SP_STATUS_REG", Reg); break; case 0x04040014: MoveVariableToX86reg(&g_Reg->SP_DMA_FULL_REG, "SP_DMA_FULL_REG", Reg); break; case 0x04040018: MoveVariableToX86reg(&g_Reg->SP_DMA_BUSY_REG, "SP_DMA_BUSY_REG", Reg); break; case 0x0404001C: MoveVariableToX86reg(&g_Reg->SP_SEMAPHORE_REG, "SP_SEMAPHORE_REG", Reg); MoveConstToVariable(1, &g_Reg->SP_SEMAPHORE_REG, "SP_SEMAPHORE_REG"); break; case 0x04080000: MoveVariableToX86reg(&g_Reg->SP_PC_REG, "SP_PC_REG", Reg); break; default: MoveConstToX86reg(0, Reg); if (g_Settings->LoadBool(Debugger_ShowUnhandledMemory)) { g_Notify->DisplayError(stdstr_f(__FUNCTION__ "\nFailed to translate address: %08X", VAddr).ToUTF16().c_str()); } } break; case 0x04100000: { static uint32_t TempValue = 0; BeforeCallDirect(m_RegWorkingSet); PushImm32("TempValue", (uint32_t)&TempValue); PushImm32(PAddr); MoveConstToX86reg((ULONG)((CMipsMemoryVM *)this), x86_ECX); Call_Direct(AddressOf(&CMipsMemoryVM::LW_NonMemory), "CMipsMemoryVM::LW_NonMemory"); AfterCallDirect(m_RegWorkingSet); MoveVariableToX86reg(&TempValue, "TempValue", Reg); } break; case 0x04300000: switch (PAddr) { case 0x04300000: MoveVariableToX86reg(&g_Reg->MI_MODE_REG, "MI_MODE_REG", Reg); break; case 0x04300004: MoveVariableToX86reg(&g_Reg->MI_VERSION_REG, "MI_VERSION_REG", Reg); break; case 0x04300008: MoveVariableToX86reg(&g_Reg->MI_INTR_REG, "MI_INTR_REG", Reg); break; case 0x0430000C: MoveVariableToX86reg(&g_Reg->MI_INTR_MASK_REG, "MI_INTR_MASK_REG", Reg); break; default: MoveConstToX86reg(0, Reg); if (g_Settings->LoadBool(Debugger_ShowUnhandledMemory)) { g_Notify->DisplayError(stdstr_f(__FUNCTION__ "\nFailed to translate address: %08X", VAddr).ToUTF16().c_str()); } } break; case 0x04400000: switch (PAddr) { case 0x04400010: m_RegWorkingSet.SetBlockCycleCount(m_RegWorkingSet.GetBlockCycleCount() - g_System->CountPerOp()); UpdateCounters(m_RegWorkingSet, false, true); m_RegWorkingSet.SetBlockCycleCount(m_RegWorkingSet.GetBlockCycleCount() + g_System->CountPerOp()); BeforeCallDirect(m_RegWorkingSet); MoveConstToX86reg((uint32_t)this, x86_ECX); Call_Direct(AddressOf(&CMipsMemoryVM::UpdateHalfLine), "CMipsMemoryVM::UpdateHalfLine"); AfterCallDirect(m_RegWorkingSet); MoveVariableToX86reg(&m_HalfLine, "m_HalfLine", Reg); break; default: MoveConstToX86reg(0, Reg); if (g_Settings->LoadBool(Debugger_ShowUnhandledMemory)) { g_Notify->DisplayError(stdstr_f(__FUNCTION__ "\nFailed to translate address: %08X", VAddr).ToUTF16().c_str()); } } break; case 0x04500000: /* AI registers */ switch (PAddr) { case 0x04500004: if (g_System->bFixedAudio()) { m_RegWorkingSet.SetBlockCycleCount(m_RegWorkingSet.GetBlockCycleCount() - g_System->CountPerOp()); UpdateCounters(m_RegWorkingSet, false, true); m_RegWorkingSet.SetBlockCycleCount(m_RegWorkingSet.GetBlockCycleCount() + g_System->CountPerOp()); BeforeCallDirect(m_RegWorkingSet); MoveConstToX86reg((uint32_t)g_Audio, x86_ECX); Call_Direct(AddressOf(&CAudio::GetLength), "CAudio::GetLength"); MoveX86regToVariable(x86_EAX, &m_TempValue, "m_TempValue"); AfterCallDirect(m_RegWorkingSet); MoveVariableToX86reg(&m_TempValue, "m_TempValue", Reg); } else { if (g_Plugins->Audio()->AiReadLength != NULL) { BeforeCallDirect(m_RegWorkingSet); Call_Direct(g_Plugins->Audio()->AiReadLength, "AiReadLength"); MoveX86regToVariable(x86_EAX, &m_TempValue, "m_TempValue"); AfterCallDirect(m_RegWorkingSet); MoveVariableToX86reg(&m_TempValue, "m_TempValue", Reg); } else { MoveConstToX86reg(0, Reg); } } break; case 0x0450000C: if (g_System->bFixedAudio()) { BeforeCallDirect(m_RegWorkingSet); MoveConstToX86reg((uint32_t)g_Audio, x86_ECX); Call_Direct(AddressOf(&CAudio::GetStatus), "GetStatus"); MoveX86regToVariable(x86_EAX, &m_TempValue, "m_TempValue"); AfterCallDirect(m_RegWorkingSet); MoveVariableToX86reg(&m_TempValue, "m_TempValue", Reg); } else { MoveVariableToX86reg(&g_Reg->AI_STATUS_REG, "AI_STATUS_REG", Reg); } break; default: MoveConstToX86reg(0, Reg); if (g_Settings->LoadBool(Debugger_ShowUnhandledMemory)) { g_Notify->DisplayError(stdstr_f(__FUNCTION__ "\nFailed to translate address: %08X", VAddr).ToUTF16().c_str()); } } break; case 0x04600000: switch (PAddr) { case 0x04600010: MoveVariableToX86reg(&g_Reg->PI_STATUS_REG, "PI_STATUS_REG", Reg); break; case 0x04600014: MoveVariableToX86reg(&g_Reg->PI_DOMAIN1_REG, "PI_DOMAIN1_REG", Reg); break; case 0x04600018: MoveVariableToX86reg(&g_Reg->PI_BSD_DOM1_PWD_REG, "PI_BSD_DOM1_PWD_REG", Reg); break; case 0x0460001C: MoveVariableToX86reg(&g_Reg->PI_BSD_DOM1_PGS_REG, "PI_BSD_DOM1_PGS_REG", Reg); break; case 0x04600020: MoveVariableToX86reg(&g_Reg->PI_BSD_DOM1_RLS_REG, "PI_BSD_DOM1_RLS_REG", Reg); break; case 0x04600024: MoveVariableToX86reg(&g_Reg->PI_DOMAIN2_REG, "PI_DOMAIN2_REG", Reg); break; case 0x04600028: MoveVariableToX86reg(&g_Reg->PI_BSD_DOM2_PWD_REG, "PI_BSD_DOM2_PWD_REG", Reg); break; case 0x0460002C: MoveVariableToX86reg(&g_Reg->PI_BSD_DOM2_PGS_REG, "PI_BSD_DOM2_PGS_REG", Reg); break; case 0x04600030: MoveVariableToX86reg(&g_Reg->PI_BSD_DOM2_RLS_REG, "PI_BSD_DOM2_RLS_REG", Reg); break; default: MoveConstToX86reg(0, Reg); if (g_Settings->LoadBool(Debugger_ShowUnhandledMemory)) { g_Notify->DisplayError(stdstr_f(__FUNCTION__ "\nFailed to translate address: %08X", VAddr).ToUTF16().c_str()); } } break; case 0x04700000: switch (PAddr) { case 0x0470000C: MoveVariableToX86reg(&g_Reg->RI_SELECT_REG, "RI_SELECT_REG", Reg); break; case 0x04700010: MoveVariableToX86reg(&g_Reg->RI_REFRESH_REG, "RI_REFRESH_REG", Reg); break; default: MoveConstToX86reg(0, Reg); if (g_Settings->LoadBool(Debugger_ShowUnhandledMemory)) { g_Notify->DisplayError(stdstr_f(__FUNCTION__ "\nFailed to translate address: %08X", VAddr).ToUTF16().c_str()); } } break; case 0x04800000: switch (PAddr) { case 0x04800018: MoveVariableToX86reg(&g_Reg->SI_STATUS_REG, "SI_STATUS_REG", Reg); break; default: MoveConstToX86reg(0, Reg); if (g_Settings->LoadBool(Debugger_ShowUnhandledMemory)) { g_Notify->DisplayError(stdstr_f(__FUNCTION__ "\nFailed to translate address: %08X", VAddr).ToUTF16().c_str()); } } break; case 0x1FC00000: sprintf(VarName, "m_RDRAM + %X", PAddr); MoveVariableToX86reg(PAddr + m_RDRAM, VarName, Reg); break; default: if ((PAddr & 0xF0000000) == 0x10000000 && (PAddr - 0x10000000) < m_RomSize) { // read from rom sprintf(VarName, "m_RDRAM + %X", PAddr); MoveVariableToX86reg(PAddr + m_RDRAM, VarName, Reg); } else { MoveConstToX86reg(((PAddr & 0xFFFF) << 16) | (PAddr & 0xFFFF), Reg); if (g_Settings->LoadBool(Debugger_ShowUnhandledMemory)) { CPU_Message(__FUNCTION__ "\nFailed to translate address: %08X", VAddr); g_Notify->DisplayError(stdstr_f(__FUNCTION__ "\nFailed to translate address: %08X", VAddr).ToUTF16().c_str()); } } } } } void CMipsMemoryVM::Compile_SB_Const(uint8_t Value, uint32_t VAddr) { char VarName[100]; uint32_t PAddr; if (VAddr < 0x80000000 || VAddr >= 0xC0000000) { x86Reg TempReg1 = Map_TempReg(x86_Any, -1, false); x86Reg TempReg2 = Map_TempReg(x86_Any, -1, false); MoveConstToX86reg(VAddr, TempReg1); MoveX86RegToX86Reg(TempReg1, TempReg2); ShiftRightUnsignImmed(TempReg2, 12); MoveVariableDispToX86Reg(m_TLB_WriteMap, "m_TLB_WriteMap", TempReg2, TempReg2, 4); CompileWriteTLBMiss(TempReg1, TempReg2); MoveConstByteToX86regPointer(Value, TempReg1, TempReg2); return; } if (!TranslateVaddr(VAddr, PAddr)) { CPU_Message("Compile_SB\nFailed to translate address: %08X", VAddr); if (g_Settings->LoadBool(Debugger_ShowUnhandledMemory)) { g_Notify->DisplayError(stdstr_f(__FUNCTION__ "\nFailed to translate address: %08X", VAddr).ToUTF16().c_str()); } return; } switch (PAddr & 0xFFF00000) { case 0x00000000: case 0x00100000: case 0x00200000: case 0x00300000: case 0x00400000: case 0x00500000: case 0x00600000: case 0x00700000: sprintf(VarName, "m_RDRAM + %X", PAddr); MoveConstByteToVariable(Value, PAddr + m_RDRAM, VarName); break; default: if (g_Settings->LoadBool(Debugger_ShowUnhandledMemory)) { g_Notify->DisplayError(stdstr_f(__FUNCTION__ "\ntrying to store %02X in %08X?", Value, VAddr).ToUTF16().c_str()); } } } void CMipsMemoryVM::Compile_SB_Register(x86Reg Reg, uint32_t VAddr) { char VarName[100]; uint32_t PAddr; if (VAddr < 0x80000000 || VAddr >= 0xC0000000) { m_RegWorkingSet.SetX86Protected(Reg, true); x86Reg TempReg1 = Map_TempReg(x86_Any, -1, false); x86Reg TempReg2 = Map_TempReg(x86_Any, -1, false); MoveConstToX86reg(VAddr, TempReg1); MoveX86RegToX86Reg(TempReg1, TempReg2); ShiftRightUnsignImmed(TempReg2, 12); MoveVariableDispToX86Reg(m_TLB_WriteMap, "m_TLB_WriteMap", TempReg2, TempReg2, 4); CompileWriteTLBMiss(TempReg1, TempReg2); MoveX86regByteToX86regPointer(Reg, TempReg1, TempReg2); return; } if (!TranslateVaddr(VAddr, PAddr)) { CPU_Message("Compile_SB\nFailed to translate address: %08X", VAddr); if (g_Settings->LoadBool(Debugger_ShowUnhandledMemory)) { g_Notify->DisplayError(stdstr_f(__FUNCTION__ "\nFailed to translate address: %08X", VAddr).ToUTF16().c_str()); } return; } switch (PAddr & 0xFFF00000) { case 0x00000000: case 0x00100000: case 0x00200000: case 0x00300000: case 0x00400000: case 0x00500000: case 0x00600000: case 0x00700000: sprintf(VarName, "m_RDRAM + %X", PAddr); MoveX86regByteToVariable(Reg, PAddr + m_RDRAM, VarName); break; default: if (g_Settings->LoadBool(Debugger_ShowUnhandledMemory)) { g_Notify->DisplayError(stdstr_f(__FUNCTION__ "\ntrying to store in %08X?", VAddr).ToUTF16().c_str()); } } } void CMipsMemoryVM::Compile_SH_Const(uint16_t Value, uint32_t VAddr) { char VarName[100]; uint32_t PAddr; if (VAddr < 0x80000000 || VAddr >= 0xC0000000) { x86Reg TempReg1 = Map_TempReg(x86_Any, -1, false); x86Reg TempReg2 = Map_TempReg(x86_Any, -1, false); MoveConstToX86reg(VAddr, TempReg1); MoveX86RegToX86Reg(TempReg1, TempReg2); ShiftRightUnsignImmed(TempReg2, 12); MoveVariableDispToX86Reg(m_TLB_WriteMap, "m_TLB_WriteMap", TempReg2, TempReg2, 4); CompileWriteTLBMiss(TempReg1, TempReg2); MoveConstHalfToX86regPointer(Value, TempReg1, TempReg2); return; } if (!TranslateVaddr(VAddr, PAddr)) { CPU_Message("Compile_SH\nFailed to translate address: %08X", VAddr); if (g_Settings->LoadBool(Debugger_ShowUnhandledMemory)) { g_Notify->DisplayError(stdstr_f(__FUNCTION__ "\nFailed to translate address: %08X", VAddr).ToUTF16().c_str()); } return; } switch (PAddr & 0xFFF00000) { case 0x00000000: case 0x00100000: case 0x00200000: case 0x00300000: case 0x00400000: case 0x00500000: case 0x00600000: case 0x00700000: sprintf(VarName, "m_RDRAM + %X", PAddr); MoveConstHalfToVariable(Value, PAddr + m_RDRAM, VarName); break; default: if (g_Settings->LoadBool(Debugger_ShowUnhandledMemory)) { g_Notify->DisplayError(stdstr_f(__FUNCTION__ "\ntrying to store %04X in %08X?", Value, VAddr).ToUTF16().c_str()); } } } void CMipsMemoryVM::Compile_SH_Register(x86Reg Reg, uint32_t VAddr) { char VarName[100]; uint32_t PAddr; if (VAddr < 0x80000000 || VAddr >= 0xC0000000) { m_RegWorkingSet.SetX86Protected(Reg, true); x86Reg TempReg1 = Map_TempReg(x86_Any, -1, false); x86Reg TempReg2 = Map_TempReg(x86_Any, -1, false); MoveConstToX86reg(VAddr, TempReg1); MoveX86RegToX86Reg(TempReg1, TempReg2); ShiftRightUnsignImmed(TempReg2, 12); MoveVariableDispToX86Reg(m_TLB_WriteMap, "m_TLB_WriteMap", TempReg2, TempReg2, 4); CompileWriteTLBMiss(TempReg1, TempReg2); MoveX86regHalfToX86regPointer(Reg, TempReg1, TempReg2); return; } if (!TranslateVaddr(VAddr, PAddr)) { CPU_Message("Compile_SH\nFailed to translate address: %08X", VAddr); if (g_Settings->LoadBool(Debugger_ShowUnhandledMemory)) { g_Notify->DisplayError(stdstr_f(__FUNCTION__ "\nFailed to translate address: %08X", VAddr).ToUTF16().c_str()); } return; } switch (PAddr & 0xFFF00000) { case 0x00000000: case 0x00100000: case 0x00200000: case 0x00300000: case 0x00400000: case 0x00500000: case 0x00600000: case 0x00700000: sprintf(VarName, "m_RDRAM + %X", PAddr); MoveX86regHalfToVariable(Reg, PAddr + m_RDRAM, VarName); break; default: if (g_Settings->LoadBool(Debugger_ShowUnhandledMemory)) { g_Notify->DisplayError(stdstr_f(__FUNCTION__ "\ntrying to store in %08X?", PAddr).ToUTF16().c_str()); } } } void CMipsMemoryVM::Compile_SW_Const(uint32_t Value, uint32_t VAddr) { char VarName[100]; uint8_t * Jump; uint32_t PAddr; if (VAddr < 0x80000000 || VAddr >= 0xC0000000) { x86Reg TempReg1 = Map_TempReg(x86_Any, -1, false); x86Reg TempReg2 = Map_TempReg(x86_Any, -1, false); MoveConstToX86reg(VAddr, TempReg1); MoveX86RegToX86Reg(TempReg1, TempReg2); ShiftRightUnsignImmed(TempReg2, 12); MoveVariableDispToX86Reg(m_TLB_WriteMap, "m_TLB_WriteMap", TempReg2, TempReg2, 4); CompileWriteTLBMiss(TempReg1, TempReg2); MoveConstToX86regPointer(Value, TempReg1, TempReg2); return; } if (!TranslateVaddr(VAddr, PAddr)) { CPU_Message("Compile_SW\nFailed to translate address: %08X", VAddr); if (g_Settings->LoadBool(Debugger_ShowUnhandledMemory)) { g_Notify->DisplayError(stdstr_f(__FUNCTION__ "\nFailed to translate address: %08X", VAddr).ToUTF16().c_str()); } return; } switch (PAddr & 0xFFF00000) { case 0x00000000: case 0x00100000: case 0x00200000: case 0x00300000: case 0x00400000: case 0x00500000: case 0x00600000: case 0x00700000: sprintf(VarName, "m_RDRAM + %X", PAddr); MoveConstToVariable(Value, PAddr + m_RDRAM, VarName); break; case 0x03F00000: switch (PAddr) { case 0x03F00000: MoveConstToVariable(Value, &g_Reg->RDRAM_CONFIG_REG, "RDRAM_CONFIG_REG"); break; case 0x03F00004: MoveConstToVariable(Value, &g_Reg->RDRAM_DEVICE_ID_REG, "RDRAM_DEVICE_ID_REG"); break; case 0x03F00008: MoveConstToVariable(Value, &g_Reg->RDRAM_DELAY_REG, "RDRAM_DELAY_REG"); break; case 0x03F0000C: MoveConstToVariable(Value, &g_Reg->RDRAM_MODE_REG, "RDRAM_MODE_REG"); break; case 0x03F00010: MoveConstToVariable(Value, &g_Reg->RDRAM_REF_INTERVAL_REG, "RDRAM_REF_INTERVAL_REG"); break; case 0x03F00014: MoveConstToVariable(Value, &g_Reg->RDRAM_REF_ROW_REG, "RDRAM_REF_ROW_REG"); break; case 0x03F00018: MoveConstToVariable(Value, &g_Reg->RDRAM_RAS_INTERVAL_REG, "RDRAM_RAS_INTERVAL_REG"); break; case 0x03F0001C: MoveConstToVariable(Value, &g_Reg->RDRAM_MIN_INTERVAL_REG, "RDRAM_MIN_INTERVAL_REG"); break; case 0x03F00020: MoveConstToVariable(Value, &g_Reg->RDRAM_ADDR_SELECT_REG, "RDRAM_ADDR_SELECT_REG"); break; case 0x03F00024: MoveConstToVariable(Value, &g_Reg->RDRAM_DEVICE_MANUF_REG, "RDRAM_DEVICE_MANUF_REG"); break; case 0x03F04004: break; case 0x03F08004: break; case 0x03F80004: break; case 0x03F80008: break; case 0x03F8000C: break; case 0x03F80014: break; default: if (g_Settings->LoadBool(Debugger_ShowUnhandledMemory)) { g_Notify->DisplayError(stdstr_f(__FUNCTION__ "\ntrying to store %08X in %08X?", Value, VAddr).ToUTF16().c_str()); } } break; case 0x04000000: if (PAddr < 0x04002000) { sprintf(VarName, "m_RDRAM + %X", PAddr); MoveConstToVariable(Value, PAddr + m_RDRAM, VarName); break; } switch (PAddr) { case 0x04040000: MoveConstToVariable(Value, &g_Reg->SP_MEM_ADDR_REG, "SP_MEM_ADDR_REG"); break; case 0x04040004: MoveConstToVariable(Value, &g_Reg->SP_DRAM_ADDR_REG, "SP_DRAM_ADDR_REG"); break; case 0x04040008: MoveConstToVariable(Value, &g_Reg->SP_RD_LEN_REG, "SP_RD_LEN_REG"); BeforeCallDirect(m_RegWorkingSet); MoveConstToX86reg((ULONG)((CDMA *)this), x86_ECX); Call_Direct(AddressOf(&CDMA::SP_DMA_READ), "CDMA::SP_DMA_READ"); AfterCallDirect(m_RegWorkingSet); break; case 0x04040010: { m_RegWorkingSet.SetBlockCycleCount(m_RegWorkingSet.GetBlockCycleCount() - g_System->CountPerOp()); UpdateCounters(m_RegWorkingSet, false, true); m_RegWorkingSet.SetBlockCycleCount(m_RegWorkingSet.GetBlockCycleCount() + g_System->CountPerOp()); BeforeCallDirect(m_RegWorkingSet); PushImm32(Value); PushImm32(PAddr); MoveConstToX86reg((ULONG)((CMipsMemoryVM *)this), x86_ECX); Call_Direct(AddressOf(&CMipsMemoryVM::SW_NonMemory), "CMipsMemoryVM::SW_NonMemory"); AfterCallDirect(m_RegWorkingSet); } break; case 0x0404001C: MoveConstToVariable(0, &g_Reg->SP_SEMAPHORE_REG, "SP_SEMAPHORE_REG"); break; case 0x04080000: MoveConstToVariable(Value & 0xFFC, &g_Reg->SP_PC_REG, "SP_PC_REG"); break; default: if (g_Settings->LoadBool(Debugger_ShowUnhandledMemory)) { g_Notify->DisplayError(stdstr_f(__FUNCTION__ "\ntrying to store %08X in %08X?", Value, VAddr).ToUTF16().c_str()); } } break; case 0x04100000: switch (PAddr) { case 0x0410000C: BeforeCallDirect(m_RegWorkingSet); PushImm32(Value); PushImm32(PAddr); MoveConstToX86reg((ULONG)((CMipsMemoryVM *)this), x86_ECX); Call_Direct(AddressOf(&CMipsMemoryVM::SW_NonMemory), "CMipsMemoryVM::SW_NonMemory"); AfterCallDirect(m_RegWorkingSet); break; default: if (g_Settings->LoadBool(Debugger_ShowUnhandledMemory)) { g_Notify->DisplayError(stdstr_f(__FUNCTION__ "\ntrying to store %08X in %08X?", Value, VAddr).ToUTF16().c_str()); } } break; case 0x04300000: switch (PAddr) { case 0x04300000: { uint32_t ModValue; ModValue = 0x7F; if ((Value & MI_CLR_INIT) != 0) { ModValue |= MI_MODE_INIT; } if ((Value & MI_CLR_EBUS) != 0) { ModValue |= MI_MODE_EBUS; } if ((Value & MI_CLR_RDRAM) != 0) { ModValue |= MI_MODE_RDRAM; } if (ModValue != 0) { AndConstToVariable(~ModValue, &g_Reg->MI_MODE_REG, "MI_MODE_REG"); } ModValue = (Value & 0x7F); if ((Value & MI_SET_INIT) != 0) { ModValue |= MI_MODE_INIT; } if ((Value & MI_SET_EBUS) != 0) { ModValue |= MI_MODE_EBUS; } if ((Value & MI_SET_RDRAM) != 0) { ModValue |= MI_MODE_RDRAM; } if (ModValue != 0) { OrConstToVariable(ModValue, &g_Reg->MI_MODE_REG, "MI_MODE_REG"); } if ((Value & MI_CLR_DP_INTR) != 0) { AndConstToVariable((uint32_t)~MI_INTR_DP, &g_Reg->MI_INTR_REG, "MI_INTR_REG"); AndConstToVariable((uint32_t)~MI_INTR_DP, &g_Reg->m_GfxIntrReg, "m_GfxIntrReg"); } } break; case 0x0430000C: { uint32_t ModValue; ModValue = 0; if ((Value & MI_INTR_MASK_CLR_SP) != 0) { ModValue |= MI_INTR_MASK_SP; } if ((Value & MI_INTR_MASK_CLR_SI) != 0) { ModValue |= MI_INTR_MASK_SI; } if ((Value & MI_INTR_MASK_CLR_AI) != 0) { ModValue |= MI_INTR_MASK_AI; } if ((Value & MI_INTR_MASK_CLR_VI) != 0) { ModValue |= MI_INTR_MASK_VI; } if ((Value & MI_INTR_MASK_CLR_PI) != 0) { ModValue |= MI_INTR_MASK_PI; } if ((Value & MI_INTR_MASK_CLR_DP) != 0) { ModValue |= MI_INTR_MASK_DP; } if (ModValue != 0) { AndConstToVariable(~ModValue, &g_Reg->MI_INTR_MASK_REG, "MI_INTR_MASK_REG"); } ModValue = 0; if ((Value & MI_INTR_MASK_SET_SP) != 0) { ModValue |= MI_INTR_MASK_SP; } if ((Value & MI_INTR_MASK_SET_SI) != 0) { ModValue |= MI_INTR_MASK_SI; } if ((Value & MI_INTR_MASK_SET_AI) != 0) { ModValue |= MI_INTR_MASK_AI; } if ((Value & MI_INTR_MASK_SET_VI) != 0) { ModValue |= MI_INTR_MASK_VI; } if ((Value & MI_INTR_MASK_SET_PI) != 0) { ModValue |= MI_INTR_MASK_PI; } if ((Value & MI_INTR_MASK_SET_DP) != 0) { ModValue |= MI_INTR_MASK_DP; } if (ModValue != 0) { OrConstToVariable(ModValue, &g_Reg->MI_INTR_MASK_REG, "MI_INTR_MASK_REG"); } } break; default: if (g_Settings->LoadBool(Debugger_ShowUnhandledMemory)) { g_Notify->DisplayError(stdstr_f(__FUNCTION__ "\ntrying to store %08X in %08X?", Value, VAddr).ToUTF16().c_str()); } } break; case 0x04400000: switch (PAddr) { case 0x04400000: if (g_Plugins->Gfx()->ViStatusChanged != NULL) { CompConstToVariable(Value, &g_Reg->VI_STATUS_REG, "VI_STATUS_REG"); JeLabel8("Continue", 0); Jump = m_RecompPos - 1; MoveConstToVariable(Value, &g_Reg->VI_STATUS_REG, "VI_STATUS_REG"); BeforeCallDirect(m_RegWorkingSet); Call_Direct(g_Plugins->Gfx()->ViStatusChanged, "ViStatusChanged"); AfterCallDirect(m_RegWorkingSet); CPU_Message(""); CPU_Message(" Continue:"); SetJump8(Jump, m_RecompPos); } break; case 0x04400004: MoveConstToVariable((Value & 0xFFFFFF), &g_Reg->VI_ORIGIN_REG, "VI_ORIGIN_REG"); break; case 0x04400008: if (g_Plugins->Gfx()->ViWidthChanged != NULL) { CompConstToVariable(Value, &g_Reg->VI_WIDTH_REG, "VI_WIDTH_REG"); JeLabel8("Continue", 0); Jump = m_RecompPos - 1; MoveConstToVariable(Value, &g_Reg->VI_WIDTH_REG, "VI_WIDTH_REG"); BeforeCallDirect(m_RegWorkingSet); Call_Direct(g_Plugins->Gfx()->ViWidthChanged, "ViWidthChanged"); AfterCallDirect(m_RegWorkingSet); CPU_Message(""); CPU_Message(" Continue:"); SetJump8(Jump, m_RecompPos); } break; case 0x0440000C: MoveConstToVariable(Value, &g_Reg->VI_INTR_REG, "VI_INTR_REG"); break; case 0x04400010: AndConstToVariable((uint32_t)~MI_INTR_VI, &g_Reg->MI_INTR_REG, "MI_INTR_REG"); BeforeCallDirect(m_RegWorkingSet); MoveConstToX86reg((uint32_t)g_Reg, x86_ECX); Call_Direct(AddressOf(&CRegisters::CheckInterrupts), "CRegisters::CheckInterrupts"); AfterCallDirect(m_RegWorkingSet); break; case 0x04400014: MoveConstToVariable(Value, &g_Reg->VI_BURST_REG, "VI_BURST_REG"); break; case 0x04400018: MoveConstToVariable(Value, &g_Reg->VI_V_SYNC_REG, "VI_V_SYNC_REG"); break; case 0x0440001C: MoveConstToVariable(Value, &g_Reg->VI_H_SYNC_REG, "VI_H_SYNC_REG"); break; case 0x04400020: MoveConstToVariable(Value, &g_Reg->VI_LEAP_REG, "VI_LEAP_REG"); break; case 0x04400024: MoveConstToVariable(Value, &g_Reg->VI_H_START_REG, "VI_H_START_REG"); break; case 0x04400028: MoveConstToVariable(Value, &g_Reg->VI_V_START_REG, "VI_V_START_REG"); break; case 0x0440002C: MoveConstToVariable(Value, &g_Reg->VI_V_BURST_REG, "VI_V_BURST_REG"); break; case 0x04400030: MoveConstToVariable(Value, &g_Reg->VI_X_SCALE_REG, "VI_X_SCALE_REG"); break; case 0x04400034: MoveConstToVariable(Value, &g_Reg->VI_Y_SCALE_REG, "VI_Y_SCALE_REG"); break; default: if (g_Settings->LoadBool(Debugger_ShowUnhandledMemory)) { g_Notify->DisplayError(stdstr_f(__FUNCTION__ "\ntrying to store %08X in %08X?", Value, VAddr).ToUTF16().c_str()); } } break; case 0x04500000: /* AI registers */ switch (PAddr) { case 0x04500000: MoveConstToVariable(Value, &g_Reg->AI_DRAM_ADDR_REG, "AI_DRAM_ADDR_REG"); break; case 0x04500004: MoveConstToVariable(Value, &g_Reg->AI_LEN_REG, "AI_LEN_REG"); BeforeCallDirect(m_RegWorkingSet); if (g_System->bFixedAudio()) { X86BreakPoint(__FILEW__, __LINE__); MoveConstToX86reg((uint32_t)g_Audio, x86_ECX); Call_Direct(AddressOf(&CAudio::LenChanged), "LenChanged"); } else { Call_Direct(g_Plugins->Audio()->AiLenChanged, "AiLenChanged"); } AfterCallDirect(m_RegWorkingSet); break; case 0x04500008: MoveConstToVariable((Value & 1), &g_Reg->AI_CONTROL_REG, "AI_CONTROL_REG"); break; case 0x0450000C: /* Clear Interrupt */; AndConstToVariable((uint32_t)~MI_INTR_AI, &g_Reg->MI_INTR_REG, "MI_INTR_REG"); AndConstToVariable((uint32_t)~MI_INTR_AI, &g_Reg->m_AudioIntrReg, "m_AudioIntrReg"); BeforeCallDirect(m_RegWorkingSet); MoveConstToX86reg((uint32_t)g_Reg, x86_ECX); Call_Direct(AddressOf(&CRegisters::CheckInterrupts), "CRegisters::CheckInterrupts"); AfterCallDirect(m_RegWorkingSet); break; case 0x04500010: sprintf(VarName, "m_RDRAM + %X", PAddr); MoveConstToVariable(Value, PAddr + m_RDRAM, VarName); break; case 0x04500014: MoveConstToVariable(Value, &g_Reg->AI_BITRATE_REG, "AI_BITRATE_REG"); break; default: sprintf(VarName, "m_RDRAM + %X", PAddr); MoveConstToVariable(Value, PAddr + m_RDRAM, VarName); if (g_Settings->LoadBool(Debugger_ShowUnhandledMemory)) { g_Notify->DisplayError(stdstr_f(__FUNCTION__ "\ntrying to store %08X in %08X?", Value, VAddr).ToUTF16().c_str()); } } break; case 0x04600000: switch (PAddr) { case 0x04600000: MoveConstToVariable(Value, &g_Reg->PI_DRAM_ADDR_REG, "PI_DRAM_ADDR_REG"); break; case 0x04600004: MoveConstToVariable(Value, &g_Reg->PI_CART_ADDR_REG, "PI_CART_ADDR_REG"); break; case 0x04600008: MoveConstToVariable(Value, &g_Reg->PI_RD_LEN_REG, "PI_RD_LEN_REG"); BeforeCallDirect(m_RegWorkingSet); MoveConstToX86reg((ULONG)((CDMA *)this), x86_ECX); Call_Direct(AddressOf(&CDMA::PI_DMA_READ), "CDMA::PI_DMA_READ"); AfterCallDirect(m_RegWorkingSet); break; case 0x0460000C: MoveConstToVariable(Value, &g_Reg->PI_WR_LEN_REG, "PI_WR_LEN_REG"); BeforeCallDirect(m_RegWorkingSet); MoveConstToX86reg((ULONG)((CDMA *)this), x86_ECX); Call_Direct(AddressOf(&CDMA::PI_DMA_WRITE), "CDMA::PI_DMA_WRITE"); AfterCallDirect(m_RegWorkingSet); break; case 0x04600010: if ((Value & PI_CLR_INTR) != 0) { AndConstToVariable((uint32_t)~MI_INTR_PI, &g_Reg->MI_INTR_REG, "MI_INTR_REG"); BeforeCallDirect(m_RegWorkingSet); MoveConstToX86reg((uint32_t)g_Reg, x86_ECX); Call_Direct(AddressOf(&CRegisters::CheckInterrupts), "CRegisters::CheckInterrupts"); AfterCallDirect(m_RegWorkingSet); } break; case 0x04600014: MoveConstToVariable((Value & 0xFF), &g_Reg->PI_DOMAIN1_REG, "PI_DOMAIN1_REG"); break; case 0x04600018: MoveConstToVariable((Value & 0xFF), &g_Reg->PI_BSD_DOM1_PWD_REG, "PI_BSD_DOM1_PWD_REG"); break; case 0x0460001C: MoveConstToVariable((Value & 0xFF), &g_Reg->PI_BSD_DOM1_PGS_REG, "PI_BSD_DOM1_PGS_REG"); break; case 0x04600020: MoveConstToVariable((Value & 0xFF), &g_Reg->PI_BSD_DOM1_RLS_REG, "PI_BSD_DOM1_RLS_REG"); break; default: if (g_Settings->LoadBool(Debugger_ShowUnhandledMemory)) { g_Notify->DisplayError(stdstr_f(__FUNCTION__ "\ntrying to store %08X in %08X?", Value, VAddr).ToUTF16().c_str()); } } break; case 0x04700000: switch (PAddr) { case 0x04700000: MoveConstToVariable(Value, &g_Reg->RI_MODE_REG, "RI_MODE_REG"); break; case 0x04700004: MoveConstToVariable(Value, &g_Reg->RI_CONFIG_REG, "RI_CONFIG_REG"); break; case 0x04700008: MoveConstToVariable(Value, &g_Reg->RI_CURRENT_LOAD_REG, "RI_CURRENT_LOAD_REG"); break; case 0x0470000C: MoveConstToVariable(Value, &g_Reg->RI_SELECT_REG, "RI_SELECT_REG"); break; default: if (g_Settings->LoadBool(Debugger_ShowUnhandledMemory)) { g_Notify->DisplayError(stdstr_f(__FUNCTION__ "\ntrying to store %08X in %08X?", Value, VAddr).ToUTF16().c_str()); } } break; case 0x04800000: switch (PAddr) { case 0x04800000: MoveConstToVariable(Value, &g_Reg->SI_DRAM_ADDR_REG, "SI_DRAM_ADDR_REG"); break; case 0x04800004: m_RegWorkingSet.SetBlockCycleCount(m_RegWorkingSet.GetBlockCycleCount() - g_System->CountPerOp()); UpdateCounters(m_RegWorkingSet, false, true); m_RegWorkingSet.SetBlockCycleCount(m_RegWorkingSet.GetBlockCycleCount() + g_System->CountPerOp()); MoveConstToVariable(Value, &g_Reg->SI_PIF_ADDR_RD64B_REG, "SI_PIF_ADDR_RD64B_REG"); BeforeCallDirect(m_RegWorkingSet); MoveConstToX86reg((uint32_t)((CPifRam *)this), x86_ECX); Call_Direct(AddressOf(&CPifRam::SI_DMA_READ), "CPifRam::SI_DMA_READ"); AfterCallDirect(m_RegWorkingSet); break; case 0x04800010: m_RegWorkingSet.SetBlockCycleCount(m_RegWorkingSet.GetBlockCycleCount() - g_System->CountPerOp()); UpdateCounters(m_RegWorkingSet, false, true); m_RegWorkingSet.SetBlockCycleCount(m_RegWorkingSet.GetBlockCycleCount() + g_System->CountPerOp()); MoveConstToVariable(Value, &g_Reg->SI_PIF_ADDR_WR64B_REG, "SI_PIF_ADDR_WR64B_REG"); BeforeCallDirect(m_RegWorkingSet); MoveConstToX86reg((uint32_t)((CPifRam *)this), x86_ECX); Call_Direct(AddressOf(&CPifRam::SI_DMA_WRITE), "CPifRam::SI_DMA_WRITE"); AfterCallDirect(m_RegWorkingSet); break; case 0x04800018: AndConstToVariable((uint32_t)~MI_INTR_SI, &g_Reg->MI_INTR_REG, "MI_INTR_REG"); AndConstToVariable((uint32_t)~SI_STATUS_INTERRUPT, &g_Reg->SI_STATUS_REG, "SI_STATUS_REG"); BeforeCallDirect(m_RegWorkingSet); MoveConstToX86reg((uint32_t)g_Reg, x86_ECX); Call_Direct(AddressOf(&CRegisters::CheckInterrupts), "CRegisters::CheckInterrupts"); AfterCallDirect(m_RegWorkingSet); break; default: if (g_Settings->LoadBool(Debugger_ShowUnhandledMemory)) { g_Notify->DisplayError(stdstr_f(__FUNCTION__ "\ntrying to store %08X in %08X?", Value, VAddr).ToUTF16().c_str()); } } break; case 0x1fc00000: { m_RegWorkingSet.SetBlockCycleCount(m_RegWorkingSet.GetBlockCycleCount() - g_System->CountPerOp()); UpdateCounters(m_RegWorkingSet, false, true); m_RegWorkingSet.SetBlockCycleCount(m_RegWorkingSet.GetBlockCycleCount() + g_System->CountPerOp()); BeforeCallDirect(m_RegWorkingSet); PushImm32(Value); PushImm32(PAddr); MoveConstToX86reg((ULONG)((CMipsMemoryVM *)this), x86_ECX); Call_Direct(AddressOf(&CMipsMemoryVM::SW_NonMemory), "CMipsMemoryVM::SW_NonMemory"); AfterCallDirect(m_RegWorkingSet); } break; default: if (g_Settings->LoadBool(Debugger_ShowUnhandledMemory)) { g_Notify->DisplayError(stdstr_f(__FUNCTION__ "\ntrying to store %08X in %08X?", Value, VAddr).ToUTF16().c_str()); } m_RegWorkingSet.SetBlockCycleCount(m_RegWorkingSet.GetBlockCycleCount() - g_System->CountPerOp()); UpdateCounters(m_RegWorkingSet, false, true); m_RegWorkingSet.SetBlockCycleCount(m_RegWorkingSet.GetBlockCycleCount() + g_System->CountPerOp()); BeforeCallDirect(m_RegWorkingSet); PushImm32(Value); PushImm32(PAddr); MoveConstToX86reg((ULONG)((CMipsMemoryVM *)this), x86_ECX); Call_Direct(AddressOf(&CMipsMemoryVM::SW_NonMemory), "CMipsMemoryVM::SW_NonMemory"); AfterCallDirect(m_RegWorkingSet); } } void CMipsMemoryVM::Compile_SW_Register(x86Reg Reg, uint32_t VAddr) { if (VAddr < 0x80000000 || VAddr >= 0xC0000000) { m_RegWorkingSet.SetX86Protected(Reg, true); x86Reg TempReg1 = Map_TempReg(x86_Any, -1, false); x86Reg TempReg2 = Map_TempReg(x86_Any, -1, false); MoveConstToX86reg(VAddr, TempReg1); MoveX86RegToX86Reg(TempReg1, TempReg2); ShiftRightUnsignImmed(TempReg2, 12); MoveVariableDispToX86Reg(m_TLB_WriteMap, "m_TLB_WriteMap", TempReg2, TempReg2, 4); CompileWriteTLBMiss(TempReg1, TempReg2); MoveX86regToX86regPointer(Reg, TempReg1, TempReg2); return; } char VarName[100]; uint8_t * Jump; uint32_t PAddr; if (!TranslateVaddr(VAddr, PAddr)) { CPU_Message("Compile_SW_Register\nFailed to translate address: %08X", VAddr); if (g_Settings->LoadBool(Debugger_ShowUnhandledMemory)) { g_Notify->DisplayError(stdstr_f(__FUNCTION__ "\nFailed to translate address: %08X", VAddr).ToUTF16().c_str()); } return; } switch (PAddr & 0xFFF00000) { case 0x00000000: case 0x00100000: case 0x00200000: case 0x00300000: case 0x00400000: case 0x00500000: case 0x00600000: case 0x00700000: sprintf(VarName, "m_RDRAM + %X", PAddr); MoveX86regToVariable(Reg, PAddr + m_RDRAM, VarName); break; case 0x04000000: switch (PAddr) { case 0x04040000: MoveX86regToVariable(Reg, &g_Reg->SP_MEM_ADDR_REG, "SP_MEM_ADDR_REG"); break; case 0x04040004: MoveX86regToVariable(Reg, &g_Reg->SP_DRAM_ADDR_REG, "SP_DRAM_ADDR_REG"); break; case 0x04040008: MoveX86regToVariable(Reg, &g_Reg->SP_RD_LEN_REG, "SP_RD_LEN_REG"); BeforeCallDirect(m_RegWorkingSet); MoveConstToX86reg((ULONG)((CDMA *)this), x86_ECX); Call_Direct(AddressOf(&CDMA::SP_DMA_READ), "CDMA::SP_DMA_READ"); AfterCallDirect(m_RegWorkingSet); break; case 0x0404000C: MoveX86regToVariable(Reg, &g_Reg->SP_WR_LEN_REG, "SP_WR_LEN_REG"); BeforeCallDirect(m_RegWorkingSet); MoveConstToX86reg((ULONG)((CDMA *)this), x86_ECX); Call_Direct(AddressOf(&CDMA::SP_DMA_WRITE), "CDMA::SP_DMA_WRITE"); AfterCallDirect(m_RegWorkingSet); break; case 0x04040010: m_RegWorkingSet.SetBlockCycleCount(m_RegWorkingSet.GetBlockCycleCount() - g_System->CountPerOp()); UpdateCounters(m_RegWorkingSet, false, true); m_RegWorkingSet.SetBlockCycleCount(m_RegWorkingSet.GetBlockCycleCount() + g_System->CountPerOp()); MoveX86regToVariable(Reg, &RegModValue, "RegModValue"); BeforeCallDirect(m_RegWorkingSet); Call_Direct(ChangeSpStatus, "ChangeSpStatus"); AfterCallDirect(m_RegWorkingSet); break; case 0x0404001C: MoveConstToVariable(0, &g_Reg->SP_SEMAPHORE_REG, "SP_SEMAPHORE_REG"); break; case 0x04080000: MoveX86regToVariable(Reg, &g_Reg->SP_PC_REG, "SP_PC_REG"); AndConstToVariable(0xFFC, &g_Reg->SP_PC_REG, "SP_PC_REG"); break; default: if (PAddr < 0x04002000) { sprintf(VarName, "m_RDRAM + %X", PAddr); MoveX86regToVariable(Reg, PAddr + m_RDRAM, VarName); } else { CPU_Message(" Should be moving %s in to %08X ?!?", x86_Name(Reg), VAddr); if (g_Settings->LoadBool(Debugger_ShowUnhandledMemory)) { g_Notify->DisplayError(stdstr_f(__FUNCTION__ "\ntrying to store in %08X?", VAddr).ToUTF16().c_str()); } } } break; case 0x04100000: if (PAddr == 0x0410000C) { m_RegWorkingSet.SetBlockCycleCount(m_RegWorkingSet.GetBlockCycleCount() - g_System->CountPerOp()); UpdateCounters(m_RegWorkingSet, false, true); m_RegWorkingSet.SetBlockCycleCount(m_RegWorkingSet.GetBlockCycleCount() + g_System->CountPerOp()); } BeforeCallDirect(m_RegWorkingSet); Push(Reg); PushImm32(PAddr); MoveConstToX86reg((ULONG)((CMipsMemoryVM *)this), x86_ECX); Call_Direct(AddressOf(&CMipsMemoryVM::SW_NonMemory), "CMipsMemoryVM::SW_NonMemory"); AfterCallDirect(m_RegWorkingSet); break; case 0x04300000: switch (PAddr) { case 0x04300000: MoveX86regToVariable(Reg, &RegModValue, "RegModValue"); BeforeCallDirect(m_RegWorkingSet); Call_Direct(ChangeMiIntrMask, "ChangeMiModeReg"); AfterCallDirect(m_RegWorkingSet); break; case 0x0430000C: MoveX86regToVariable(Reg, &RegModValue, "RegModValue"); BeforeCallDirect(m_RegWorkingSet); Call_Direct(ChangeMiIntrMask, "ChangeMiIntrMask"); AfterCallDirect(m_RegWorkingSet); break; default: CPU_Message(" Should be moving %s in to %08X ?!?", x86_Name(Reg), VAddr); if (g_Settings->LoadBool(Debugger_ShowUnhandledMemory)) { g_Notify->DisplayError(stdstr_f(__FUNCTION__ "\ntrying to store in %08X?", VAddr).ToUTF16().c_str()); } } break; case 0x04400000: switch (PAddr) { case 0x04400000: if (g_Plugins->Gfx()->ViStatusChanged != NULL) { CompX86regToVariable(Reg, &g_Reg->VI_STATUS_REG, "VI_STATUS_REG"); JeLabel8("Continue", 0); Jump = m_RecompPos - 1; MoveX86regToVariable(Reg, &g_Reg->VI_STATUS_REG, "VI_STATUS_REG"); BeforeCallDirect(m_RegWorkingSet); Call_Direct(g_Plugins->Gfx()->ViStatusChanged, "ViStatusChanged"); AfterCallDirect(m_RegWorkingSet); CPU_Message(""); CPU_Message(" Continue:"); SetJump8(Jump, m_RecompPos); } break; case 0x04400004: MoveX86regToVariable(Reg, &g_Reg->VI_ORIGIN_REG, "VI_ORIGIN_REG"); AndConstToVariable(0xFFFFFF, &g_Reg->VI_ORIGIN_REG, "VI_ORIGIN_REG"); break; case 0x04400008: if (g_Plugins->Gfx()->ViWidthChanged != NULL) { CompX86regToVariable(Reg, &g_Reg->VI_WIDTH_REG, "VI_WIDTH_REG"); JeLabel8("Continue", 0); Jump = m_RecompPos - 1; MoveX86regToVariable(Reg, &g_Reg->VI_WIDTH_REG, "VI_WIDTH_REG"); BeforeCallDirect(m_RegWorkingSet); Call_Direct(g_Plugins->Gfx()->ViWidthChanged, "ViWidthChanged"); AfterCallDirect(m_RegWorkingSet); CPU_Message(""); CPU_Message(" Continue:"); SetJump8(Jump, m_RecompPos); } break; case 0x0440000C: MoveX86regToVariable(Reg, &g_Reg->VI_INTR_REG, "VI_INTR_REG"); break; case 0x04400010: AndConstToVariable((uint32_t)~MI_INTR_VI, &g_Reg->MI_INTR_REG, "MI_INTR_REG"); BeforeCallDirect(m_RegWorkingSet); MoveConstToX86reg((uint32_t)g_Reg, x86_ECX); Call_Direct(AddressOf(&CRegisters::CheckInterrupts), "CRegisters::CheckInterrupts"); AfterCallDirect(m_RegWorkingSet); break; case 0x04400014: MoveX86regToVariable(Reg, &g_Reg->VI_BURST_REG, "VI_BURST_REG"); break; case 0x04400018: MoveX86regToVariable(Reg, &g_Reg->VI_V_SYNC_REG, "VI_V_SYNC_REG"); break; case 0x0440001C: MoveX86regToVariable(Reg, &g_Reg->VI_H_SYNC_REG, "VI_H_SYNC_REG"); break; case 0x04400020: MoveX86regToVariable(Reg, &g_Reg->VI_LEAP_REG, "VI_LEAP_REG"); break; case 0x04400024: MoveX86regToVariable(Reg, &g_Reg->VI_H_START_REG, "VI_H_START_REG"); break; case 0x04400028: MoveX86regToVariable(Reg, &g_Reg->VI_V_START_REG, "VI_V_START_REG"); break; case 0x0440002C: MoveX86regToVariable(Reg, &g_Reg->VI_V_BURST_REG, "VI_V_BURST_REG"); break; case 0x04400030: MoveX86regToVariable(Reg, &g_Reg->VI_X_SCALE_REG, "VI_X_SCALE_REG"); break; case 0x04400034: MoveX86regToVariable(Reg, &g_Reg->VI_Y_SCALE_REG, "VI_Y_SCALE_REG"); break; default: CPU_Message(" Should be moving %s in to %08X ?!?", x86_Name(Reg), VAddr); if (g_Settings->LoadBool(Debugger_ShowUnhandledMemory)) { g_Notify->DisplayError(stdstr_f(__FUNCTION__ "\ntrying to store in %08X?", VAddr).ToUTF16().c_str()); } } break; case 0x04500000: /* AI registers */ switch (PAddr) { case 0x04500000: MoveX86regToVariable(Reg, &g_Reg->AI_DRAM_ADDR_REG, "AI_DRAM_ADDR_REG"); break; case 0x04500004: m_RegWorkingSet.SetBlockCycleCount(m_RegWorkingSet.GetBlockCycleCount() - g_System->CountPerOp()); UpdateCounters(m_RegWorkingSet, false, true); m_RegWorkingSet.SetBlockCycleCount(m_RegWorkingSet.GetBlockCycleCount() + g_System->CountPerOp()); MoveX86regToVariable(Reg, &g_Reg->AI_LEN_REG, "AI_LEN_REG"); BeforeCallDirect(m_RegWorkingSet); if (g_System->bFixedAudio()) { MoveConstToX86reg((uint32_t)g_Audio, x86_ECX); Call_Direct(AddressOf(&CAudio::LenChanged), "LenChanged"); } else { Call_Direct(g_Plugins->Audio()->AiLenChanged, "g_Plugins->Audio()->LenChanged"); } AfterCallDirect(m_RegWorkingSet); break; case 0x04500008: MoveX86regToVariable(Reg, &g_Reg->AI_CONTROL_REG, "AI_CONTROL_REG"); AndConstToVariable(1, &g_Reg->AI_CONTROL_REG, "AI_CONTROL_REG"); case 0x0450000C: /* Clear Interrupt */; AndConstToVariable((uint32_t)~MI_INTR_AI, &g_Reg->MI_INTR_REG, "MI_INTR_REG"); AndConstToVariable((uint32_t)~MI_INTR_AI, &g_Reg->m_AudioIntrReg, "m_AudioIntrReg"); BeforeCallDirect(m_RegWorkingSet); MoveConstToX86reg((uint32_t)g_Reg, x86_ECX); Call_Direct(AddressOf(&CRegisters::CheckInterrupts), "CRegisters::CheckInterrupts"); AfterCallDirect(m_RegWorkingSet); break; case 0x04500010: sprintf(VarName, "m_RDRAM + %X", PAddr); MoveX86regToVariable(Reg, PAddr + m_RDRAM, VarName); break; case 0x04500014: MoveX86regToVariable(Reg, &g_Reg->AI_BITRATE_REG, "AI_BITRATE_REG"); break; default: sprintf(VarName, "m_RDRAM + %X", PAddr); MoveX86regToVariable(Reg, PAddr + m_RDRAM, VarName); if (g_Settings->LoadBool(Debugger_ShowUnhandledMemory)) { g_Notify->DisplayError(stdstr_f(__FUNCTION__ "\ntrying to store in %08X?", VAddr).ToUTF16().c_str()); } } break; case 0x04600000: switch (PAddr) { case 0x04600000: MoveX86regToVariable(Reg, &g_Reg->PI_DRAM_ADDR_REG, "PI_DRAM_ADDR_REG"); break; case 0x04600004: MoveX86regToVariable(Reg, &g_Reg->PI_CART_ADDR_REG, "PI_CART_ADDR_REG"); break; case 0x04600008: MoveX86regToVariable(Reg, &g_Reg->PI_RD_LEN_REG, "PI_RD_LEN_REG"); BeforeCallDirect(m_RegWorkingSet); MoveConstToX86reg((ULONG)((CDMA *)this), x86_ECX); Call_Direct(AddressOf(&CDMA::PI_DMA_READ), "CDMA::PI_DMA_READ"); AfterCallDirect(m_RegWorkingSet); break; case 0x0460000C: MoveX86regToVariable(Reg, &g_Reg->PI_WR_LEN_REG, "PI_WR_LEN_REG"); BeforeCallDirect(m_RegWorkingSet); MoveConstToX86reg((ULONG)((CDMA *)this), x86_ECX); Call_Direct(AddressOf(&CDMA::PI_DMA_WRITE), "CDMA::PI_DMA_WRITE"); AfterCallDirect(m_RegWorkingSet); break; case 0x04600010: if (g_Settings->LoadBool(Debugger_ShowUnhandledMemory)) { g_Notify->DisplayError(stdstr_f(__FUNCTION__ "\ntrying to store in %08X?", VAddr).ToUTF16().c_str()); } AndConstToVariable((uint32_t)~MI_INTR_PI, &g_Reg->MI_INTR_REG, "MI_INTR_REG"); BeforeCallDirect(m_RegWorkingSet); MoveConstToX86reg((uint32_t)g_Reg, x86_ECX); Call_Direct(AddressOf(&CRegisters::CheckInterrupts), "CRegisters::CheckInterrupts"); AfterCallDirect(m_RegWorkingSet); break; case 0x04600014: MoveX86regToVariable(Reg, &g_Reg->PI_DOMAIN1_REG, "PI_DOMAIN1_REG"); AndConstToVariable(0xFF, &g_Reg->PI_DOMAIN1_REG, "PI_DOMAIN1_REG"); break; case 0x04600018: MoveX86regToVariable(Reg, &g_Reg->PI_BSD_DOM1_PWD_REG, "PI_BSD_DOM1_PWD_REG"); AndConstToVariable(0xFF, &g_Reg->PI_BSD_DOM1_PWD_REG, "PI_BSD_DOM1_PWD_REG"); break; case 0x0460001C: MoveX86regToVariable(Reg, &g_Reg->PI_BSD_DOM1_PGS_REG, "PI_BSD_DOM1_PGS_REG"); AndConstToVariable(0xFF, &g_Reg->PI_BSD_DOM1_PGS_REG, "PI_BSD_DOM1_PGS_REG"); break; case 0x04600020: MoveX86regToVariable(Reg, &g_Reg->PI_BSD_DOM1_RLS_REG, "PI_BSD_DOM1_RLS_REG"); AndConstToVariable(0xFF, &g_Reg->PI_BSD_DOM1_RLS_REG, "PI_BSD_DOM1_RLS_REG"); break; default: CPU_Message(" Should be moving %s in to %08X ?!?", x86_Name(Reg), VAddr); if (g_Settings->LoadBool(Debugger_ShowUnhandledMemory)) { g_Notify->DisplayError(stdstr_f(__FUNCTION__ "\ntrying to store in %08X?", VAddr).ToUTF16().c_str()); } } break; case 0x04700000: switch (PAddr) { case 0x04700010: MoveX86regToVariable(Reg, &g_Reg->RI_REFRESH_REG, "RI_REFRESH_REG"); break; default: if (g_Settings->LoadBool(Debugger_ShowUnhandledMemory)) { g_Notify->DisplayError(stdstr_f(__FUNCTION__ "\ntrying to store in %08X?", VAddr).ToUTF16().c_str()); } } break; case 0x04800000: switch (PAddr) { case 0x04800000: MoveX86regToVariable(Reg, &g_Reg->SI_DRAM_ADDR_REG, "SI_DRAM_ADDR_REG"); break; case 0x04800004: MoveX86regToVariable(Reg, &g_Reg->SI_PIF_ADDR_RD64B_REG, "SI_PIF_ADDR_RD64B_REG"); BeforeCallDirect(m_RegWorkingSet); MoveConstToX86reg((uint32_t)((CPifRam *)this), x86_ECX); Call_Direct(AddressOf(&CPifRam::SI_DMA_READ), "CPifRam::SI_DMA_READ"); AfterCallDirect(m_RegWorkingSet); break; case 0x04800010: MoveX86regToVariable(Reg, &g_Reg->SI_PIF_ADDR_WR64B_REG, "SI_PIF_ADDR_WR64B_REG"); BeforeCallDirect(m_RegWorkingSet); MoveConstToX86reg((uint32_t)((CPifRam *)this), x86_ECX); Call_Direct(AddressOf(&CPifRam::SI_DMA_WRITE), "CPifRam::SI_DMA_WRITE"); AfterCallDirect(m_RegWorkingSet); break; case 0x04800018: AndConstToVariable((uint32_t)~MI_INTR_SI, &g_Reg->MI_INTR_REG, "MI_INTR_REG"); AndConstToVariable((uint32_t)~SI_STATUS_INTERRUPT, &g_Reg->SI_STATUS_REG, "SI_STATUS_REG"); BeforeCallDirect(m_RegWorkingSet); MoveConstToX86reg((uint32_t)g_Reg, x86_ECX); Call_Direct(AddressOf(&CRegisters::CheckInterrupts), "CRegisters::CheckInterrupts"); AfterCallDirect(m_RegWorkingSet); break; default: if (g_Settings->LoadBool(Debugger_ShowUnhandledMemory)) { g_Notify->DisplayError(stdstr_f(__FUNCTION__ "\ntrying to store in %08X?", VAddr).ToUTF16().c_str()); } } break; case 0x1FC00000: sprintf(VarName, "m_RDRAM + %X", PAddr); MoveX86regToVariable(Reg, PAddr + m_RDRAM, VarName); break; default: CPU_Message(" Should be moving %s in to %08X ?!?", x86_Name(Reg), VAddr); if (g_Settings->LoadBool(Debugger_ShowUnhandledMemory)) { g_Notify->DisplayError(stdstr_f(__FUNCTION__ "\ntrying to store in %08X?", VAddr).ToUTF16().c_str()); } } } void CMipsMemoryVM::ResetMemoryStack() { x86Reg Reg, TempReg; int32_t MipsReg = 29; CPU_Message(" ResetMemoryStack"); Reg = Get_MemoryStack(); if (Reg == x86_Unknown) { Reg = Map_TempReg(x86_Any, MipsReg, false); } else { if (IsUnknown(MipsReg)) { MoveVariableToX86reg(&_GPR[MipsReg].UW[0], CRegName::GPR_Lo[MipsReg], Reg); } else if (IsMapped(MipsReg)) { MoveX86RegToX86Reg(GetMipsRegMapLo(MipsReg), Reg); } else { MoveConstToX86reg(GetMipsRegLo(MipsReg), Reg); } } if (g_System->bUseTlb()) { TempReg = Map_TempReg(x86_Any, -1, false); MoveX86RegToX86Reg(Reg, TempReg); ShiftRightUnsignImmed(TempReg, 12); MoveVariableDispToX86Reg(m_TLB_ReadMap, "m_TLB_ReadMap", TempReg, TempReg, 4); AddX86RegToX86Reg(Reg, TempReg); } else { AndConstToX86Reg(Reg, 0x1FFFFFFF); AddConstToX86Reg(Reg, (uint32_t)m_RDRAM); } MoveX86regToVariable(Reg, &(g_Recompiler->MemoryStackPos()), "MemoryStack"); } int32_t CMipsMemoryVM::MemoryFilter(uint32_t dwExptCode, void * lpExceptionPointer) { #if defined(_M_IX86) && defined(_WIN32) // to do: Remove the _M_IX86 criteria. This can compile on 64-bit Windows. #ifndef _WIN64 DWORD * Reg; // We need this to fix 32-bit Windows builds, // because Project64 currently uses uint32_t all the time instead of int32_t. #else size_t * Reg; #endif if (dwExptCode != EXCEPTION_ACCESS_VIOLATION) { if (bHaveDebugger()) { g_Notify->BreakPoint(__FILEW__, __LINE__); } return EXCEPTION_EXECUTE_HANDLER; } //convert the pointer since we are not having win32 structures in headers LPEXCEPTION_POINTERS lpEP = (LPEXCEPTION_POINTERS)lpExceptionPointer; uint32_t MemAddress = (char *)lpEP->ExceptionRecord->ExceptionInformation[1] - (char *)g_MMU->Rdram(); if ((int32_t)(MemAddress) < 0 || MemAddress > 0x1FFFFFFF) { // if (bHaveDebugger()) // { // g_Notify->BreakPoint(__FILEW__,__LINE__); // } return EXCEPTION_EXECUTE_HANDLER; } uint8_t * TypePos = (uint8_t *)lpEP->ContextRecord->Eip; EXCEPTION_RECORD exRec = *lpEP->ExceptionRecord; Reg = NULL; if (*TypePos == 0xF3 && (*(TypePos + 1) == 0xA4 || *(TypePos + 1) == 0xA5)) { uint32_t Start = (lpEP->ContextRecord->Edi - (uint32_t)m_RDRAM); uint32_t End = Start + lpEP->ContextRecord->Ecx; if ((int32_t)Start < 0) { if (bHaveDebugger()) { g_Notify->BreakPoint(__FILEW__, __LINE__); } return EXCEPTION_EXECUTE_HANDLER; } #ifdef CFB_READ uint32_t count, OldProtect; if (Start >= CFBStart && End < CFBEnd) { for ( count = Start; count < End; count += 0x1000 ) { VirtualProtect(m_RDRAM+count,4,PAGE_READONLY, &OldProtect); if (FrameBufferRead) { FrameBufferRead(count & ~0xFFF); } } return EXCEPTION_CONTINUE_EXECUTION; } #endif if (End < RdramSize()) { for (uint32_t count = (Start & ~0xFFF); count < End; count += 0x1000) { g_Recompiler->ClearRecompCode_Phys(count, 0x1000, CRecompiler::Remove_ProtectedMem); } return EXCEPTION_CONTINUE_EXECUTION; } if (Start >= 0x04000000 && End < 0x04002000) { g_Recompiler->ClearRecompCode_Phys(Start & ~0xFFF, 0x1000, CRecompiler::Remove_ProtectedMem); return EXCEPTION_CONTINUE_EXECUTION; } if (bHaveDebugger()) { g_Notify->BreakPoint(__FILEW__, __LINE__); } return EXCEPTION_EXECUTE_HANDLER; } uint8_t * ReadPos; if (*TypePos == 0x0F && *(TypePos + 1) == 0xB6) { ReadPos = TypePos + 2; } else if (*TypePos == 0x0F && *(TypePos + 1) == 0xB7) { ReadPos = TypePos + 2; } else if (*TypePos == 0x0F && *(TypePos + 1) == 0xBE) { ReadPos = TypePos + 2; } else if (*TypePos == 0x0F && *(TypePos + 1) == 0xBF) { ReadPos = TypePos + 2; } else if (*TypePos == 0x66) { ReadPos = TypePos + 2; } else { ReadPos = TypePos + 1; } switch (*ReadPos & 0x38) { case 0x00: Reg = &(lpEP->ContextRecord->Eax); break; case 0x08: Reg = &(lpEP->ContextRecord->Ecx); break; case 0x10: Reg = &(lpEP->ContextRecord->Edx); break; case 0x18: Reg = &(lpEP->ContextRecord->Ebx); break; case 0x20: Reg = &(lpEP->ContextRecord->Esp); break; case 0x28: Reg = &(lpEP->ContextRecord->Ebp); break; case 0x30: Reg = &(lpEP->ContextRecord->Esi); break; case 0x38: Reg = &(lpEP->ContextRecord->Edi); break; } switch ((*ReadPos & 0xC7)) { case 0: ReadPos += 1; break; case 1: ReadPos += 1; break; case 2: ReadPos += 1; break; case 3: ReadPos += 1; break; case 4: ReadPos += 1; switch ((*ReadPos & 0xC7)) { case 0: ReadPos += 1; break; case 1: ReadPos += 1; break; case 2: ReadPos += 1; break; case 3: ReadPos += 1; break; case 6: ReadPos += 1; break; case 7: ReadPos += 1; break; case 0x80: ReadPos += 1; break; default: g_Notify->BreakPoint(__FILEW__, __LINE__); } break; case 5: ReadPos += 5; break; case 6: ReadPos += 1; break; case 7: ReadPos += 1; break; case 0x40: ReadPos += 2; break; case 0x41: ReadPos += 2; break; case 0x42: ReadPos += 2; break; case 0x43: ReadPos += 2; break; case 0x44: ReadPos += 3; break; case 0x46: ReadPos += 2; break; case 0x47: ReadPos += 2; break; case 0x80: ReadPos += 5; break; case 0x81: ReadPos += 5; break; case 0x82: ReadPos += 5; break; case 0x83: ReadPos += 5; break; case 0x86: ReadPos += 5; break; case 0x87: ReadPos += 5; break; default: if (bHaveDebugger()) { g_Notify->BreakPoint(__FILEW__, __LINE__); } return EXCEPTION_EXECUTE_HANDLER; } if (Reg == NULL) { if (bHaveDebugger()) { g_Notify->BreakPoint(__FILEW__, __LINE__); } return EXCEPTION_EXECUTE_HANDLER; } switch (*TypePos) { case 0x0F: switch (*(TypePos + 1)) { case 0xB6: if (!LB_NonMemory(MemAddress, (uint32_t *)Reg, false)) { if (g_Settings->LoadDword(Debugger_ShowUnhandledMemory)) { g_Notify->DisplayError(stdstr_f("Failed to load byte\n\nMIPS Address: %08X\nX86 Address: %08X", (char *)exRec.ExceptionInformation[1] - (char *)m_RDRAM, (uint8_t *)lpEP->ContextRecord->Eip).ToUTF16().c_str()); } } lpEP->ContextRecord->Eip = (uint32_t)ReadPos; return EXCEPTION_CONTINUE_EXECUTION; case 0xB7: if (!LH_NonMemory(MemAddress, (uint32_t *)Reg, false)) { if (g_Settings->LoadDword(Debugger_ShowUnhandledMemory)) { g_Notify->DisplayError(stdstr_f("Failed to load half word\n\nMIPS Address: %08X\nX86 Address: %08X", (char *)exRec.ExceptionInformation[1] - (char *)m_RDRAM, (uint8_t *)lpEP->ContextRecord->Eip).ToUTF16().c_str()); } } lpEP->ContextRecord->Eip = (uint32_t)ReadPos; return EXCEPTION_CONTINUE_EXECUTION; case 0xBE: if (!LB_NonMemory(MemAddress, (uint32_t *)Reg, true)) { if (g_Settings->LoadDword(Debugger_ShowUnhandledMemory)) { g_Notify->DisplayError(stdstr_f("Failed to load byte\n\nMIPS Address: %08X\nX86 Address: %08X", (char *)exRec.ExceptionInformation[1] - (char *)m_RDRAM, (uint8_t *)lpEP->ContextRecord->Eip).ToUTF16().c_str()); } } lpEP->ContextRecord->Eip = (uint32_t)ReadPos; return EXCEPTION_CONTINUE_EXECUTION; case 0xBF: if (!LH_NonMemory(MemAddress, (uint32_t *)Reg, true)) { if (g_Settings->LoadDword(Debugger_ShowUnhandledMemory)) { g_Notify->DisplayError(stdstr_f("Failed to load half word\n\nMIPS Address: %08X\nX86 Address: %08X", (char *)exRec.ExceptionInformation[1] - (char *)m_RDRAM, (uint8_t *)lpEP->ContextRecord->Eip).ToUTF16().c_str()); } } lpEP->ContextRecord->Eip = (uint32_t)ReadPos; return EXCEPTION_CONTINUE_EXECUTION; default: if (bHaveDebugger()) { g_Notify->BreakPoint(__FILEW__, __LINE__); } return EXCEPTION_EXECUTE_HANDLER; } break; case 0x66: switch (*(TypePos + 1)) { case 0x8B: if (!LH_NonMemory(MemAddress, (uint32_t *)Reg, false)) { if (g_Settings->LoadDword(Debugger_ShowUnhandledMemory)) { g_Notify->DisplayError(stdstr_f("Failed to half word\n\nMIPS Address: %08X\nX86 Address: %08X", (char *)exRec.ExceptionInformation[1] - (char *)m_RDRAM, (uint8_t *)lpEP->ContextRecord->Eip).ToUTF16().c_str()); } } lpEP->ContextRecord->Eip = (uint32_t)ReadPos; return EXCEPTION_CONTINUE_EXECUTION; case 0x89: if (!SH_NonMemory(MemAddress, *(uint16_t *)Reg)) { if (g_Settings->LoadDword(Debugger_ShowUnhandledMemory)) { g_Notify->DisplayError(stdstr_f("Failed to store half word\n\nMIPS Address: %08X\nX86 Address: %08X", MemAddress, (uint8_t *)lpEP->ContextRecord->Eip).ToUTF16().c_str()); } } lpEP->ContextRecord->Eip = (uint32_t)ReadPos; return EXCEPTION_CONTINUE_EXECUTION; case 0xC7: if (Reg != &lpEP->ContextRecord->Eax) { if (bHaveDebugger()) { g_Notify->BreakPoint(__FILEW__, __LINE__); } return EXCEPTION_EXECUTE_HANDLER; } if (!SH_NonMemory(MemAddress, *(uint16_t *)ReadPos)) { if (g_Settings->LoadDword(Debugger_ShowUnhandledMemory)) { g_Notify->DisplayError(stdstr_f("Failed to store half word\n\nMIPS Address: %08X\nX86 Address: %08X", MemAddress, (uint8_t *)lpEP->ContextRecord->Eip).ToUTF16().c_str()); } } lpEP->ContextRecord->Eip = (uint32_t)(ReadPos + 2); return EXCEPTION_CONTINUE_EXECUTION; default: if (bHaveDebugger()) { g_Notify->BreakPoint(__FILEW__, __LINE__); } return EXCEPTION_EXECUTE_HANDLER; } break; case 0x88: if (!SB_NonMemory(MemAddress, *(uint8_t *)Reg)) { if (g_Settings->LoadDword(Debugger_ShowUnhandledMemory)) { g_Notify->DisplayError(stdstr_f("Failed to store byte\n\nMIPS Address: %08X\nX86 Address: %08X", (char *)exRec.ExceptionInformation[1] - (char *)m_RDRAM, (uint8_t *)lpEP->ContextRecord->Eip).ToUTF16().c_str()); } } lpEP->ContextRecord->Eip = (uint32_t)ReadPos; return EXCEPTION_CONTINUE_EXECUTION; case 0x8A: if (!LB_NonMemory(MemAddress, (uint32_t *)Reg, false)) { if (g_Settings->LoadDword(Debugger_ShowUnhandledMemory)) { g_Notify->DisplayError(stdstr_f("Failed to load byte\n\nMIPS Address: %08X\nX86 Address: %08X", (char *)exRec.ExceptionInformation[1] - (char *)m_RDRAM, (uint8_t *)lpEP->ContextRecord->Eip).ToUTF16().c_str()); } } lpEP->ContextRecord->Eip = (uint32_t)ReadPos; return EXCEPTION_CONTINUE_EXECUTION; case 0x8B: if (!LW_NonMemory(MemAddress, (uint32_t *)Reg)) { if (g_Settings->LoadDword(Debugger_ShowUnhandledMemory)) { g_Notify->DisplayError(stdstr_f("Failed to load word\n\nMIPS Address: %08X\nX86 Address: %08X", (char *)exRec.ExceptionInformation[1] - (char *)m_RDRAM, (uint8_t *)lpEP->ContextRecord->Eip).ToUTF16().c_str()); } } lpEP->ContextRecord->Eip = (uint32_t)ReadPos; return EXCEPTION_CONTINUE_EXECUTION; case 0x89: if (!SW_NonMemory(MemAddress, *(uint32_t *)Reg)) { if (g_Settings->LoadDword(Debugger_ShowUnhandledMemory)) { g_Notify->DisplayError(stdstr_f("Failed to store word\n\nMIPS Address: %08X\nX86 Address: %08X", MemAddress, (uint8_t *)lpEP->ContextRecord->Eip).ToUTF16().c_str()); } } lpEP->ContextRecord->Eip = (uint32_t)ReadPos; return EXCEPTION_CONTINUE_EXECUTION; case 0xC6: if (Reg != &lpEP->ContextRecord->Eax) { if (bHaveDebugger()) { g_Notify->BreakPoint(__FILEW__, __LINE__); } return EXCEPTION_EXECUTE_HANDLER; } if (!SB_NonMemory(MemAddress, *(uint8_t *)ReadPos)) { if (g_Settings->LoadDword(Debugger_ShowUnhandledMemory)) { g_Notify->DisplayError(stdstr_f("Failed to store byte\n\nMIPS Address: %08X\nX86 Address: %08X", MemAddress, (uint8_t *)lpEP->ContextRecord->Eip).ToUTF16().c_str()); } } lpEP->ContextRecord->Eip = (uint32_t)(ReadPos + 1); return EXCEPTION_CONTINUE_EXECUTION; case 0xC7: if (Reg != &lpEP->ContextRecord->Eax) { if (bHaveDebugger()) { g_Notify->BreakPoint(__FILEW__, __LINE__); } return EXCEPTION_EXECUTE_HANDLER; } if (!SW_NonMemory(MemAddress, *(uint32_t *)ReadPos)) { if (g_Settings->LoadDword(Debugger_ShowUnhandledMemory)) { g_Notify->DisplayError(stdstr_f("Failed to store word\n\nMIPS Address: %08X\nX86 Address: %08X", MemAddress, (uint8_t *)lpEP->ContextRecord->Eip).ToUTF16().c_str()); } } lpEP->ContextRecord->Eip = (uint32_t)(ReadPos + 4); return EXCEPTION_CONTINUE_EXECUTION; } if (bHaveDebugger()) { g_Notify->BreakPoint(__FILEW__, __LINE__); } #else g_Notify->BreakPoint(__FILEW__,__LINE__); #endif return EXCEPTION_EXECUTE_HANDLER; } bool CMipsMemoryVM::LB_NonMemory(uint32_t PAddr, uint32_t* Value, bool /*SignExtend*/) { if (PAddr < 0x800000) { *Value = 0; return true; } if (PAddr >= 0x10000000 && PAddr < 0x16000000) { g_Notify->BreakPoint(__FILEW__, __LINE__); #ifdef tofix if (WrittenToRom) { return false; } if ((PAddr & 2) == 0) { PAddr = (PAddr + 4) ^ 2; } if ((PAddr - 0x10000000) < RomFileSize) { if (SignExtend) { *Value = (int32_t)((char)ROM[PAddr - 0x10000000]); } else { *Value = ROM[PAddr - 0x10000000]; } return true; } else { *Value = 0; return false; } #endif } // switch (PAddr & 0xFFF00000) //{ // default: *Value = 0; // return false; // break; // } return true; } bool CMipsMemoryVM::LH_NonMemory(uint32_t PAddr, uint32_t* Value, bool/* SignExtend*/) { if (PAddr < 0x800000) { *Value = 0; return true; } if (PAddr >= 0x10000000 && PAddr < 0x16000000) { g_Notify->BreakPoint(__FILEW__, __LINE__); } // switch (PAddr & 0xFFF00000) // { // default: *Value = 0; return false; // } // return true; } bool CMipsMemoryVM::LW_NonMemory(uint32_t PAddr, uint32_t* Value) { #ifdef CFB_READ if (PAddr >= CFBStart && PAddr < CFBEnd) { uint32_t OldProtect; VirtualProtect(m_RDRAM+(PAddr & ~0xFFF),0xFFC,PAGE_READONLY, &OldProtect); if (FrameBufferRead) { FrameBufferRead(PAddr & ~0xFFF); } *Value = *(uint32_t *)(m_RDRAM+PAddr); return true; } #endif if (PAddr >= 0x10000000 && PAddr < 0x16000000) { if (m_RomWrittenTo) { *Value = m_RomWroteValue; //LogMessage("%X: Read crap from Rom %08X from %08X",PROGRAM_COUNTER,*Value,PAddr); m_RomWrittenTo = false; #ifdef ROM_IN_MAPSPACE { uint32_t OldProtect; VirtualProtect(ROM,RomFileSize,PAGE_READONLY, &OldProtect); } #endif return true; } if ((PAddr - 0x10000000) < m_RomSize) { *Value = *(uint32_t *)&m_Rom[PAddr - 0x10000000]; return true; } else { *Value = PAddr & 0xFFFF; *Value = (*Value << 16) | *Value; return false; } } switch (PAddr & 0xFFF00000) { case 0x03F00000: switch (PAddr) { case 0x03F00000: *Value = g_Reg->RDRAM_CONFIG_REG; break; case 0x03F00004: *Value = g_Reg->RDRAM_DEVICE_ID_REG; break; case 0x03F00008: *Value = g_Reg->RDRAM_DELAY_REG; break; case 0x03F0000C: *Value = g_Reg->RDRAM_MODE_REG; break; case 0x03F00010: *Value = g_Reg->RDRAM_REF_INTERVAL_REG; break; case 0x03F00014: *Value = g_Reg->RDRAM_REF_ROW_REG; break; case 0x03F00018: *Value = g_Reg->RDRAM_RAS_INTERVAL_REG; break; case 0x03F0001C: *Value = g_Reg->RDRAM_MIN_INTERVAL_REG; break; case 0x03F00020: *Value = g_Reg->RDRAM_ADDR_SELECT_REG; break; case 0x03F00024: *Value = g_Reg->RDRAM_DEVICE_MANUF_REG; break; default: *Value = 0; return false; } break; case 0x04000000: switch (PAddr) { case 0x04040010: *Value = g_Reg->SP_STATUS_REG; break; case 0x04040014: *Value = g_Reg->SP_DMA_FULL_REG; break; case 0x04040018: *Value = g_Reg->SP_DMA_BUSY_REG; break; case 0x0404001C: *Value = g_Reg->SP_SEMAPHORE_REG; g_Reg->SP_SEMAPHORE_REG = 1; break; case 0x04080000: *Value = g_Reg->SP_PC_REG; break; default: *Value = 0; return false; } break; case 0x04100000: switch (PAddr) { case 0x0410000C: *Value = g_Reg->DPC_STATUS_REG; break; case 0x04100010: *Value = g_Reg->DPC_CLOCK_REG; break; case 0x04100014: *Value = g_Reg->DPC_BUFBUSY_REG; break; case 0x04100018: *Value = g_Reg->DPC_PIPEBUSY_REG; break; case 0x0410001C: *Value = g_Reg->DPC_TMEM_REG; break; default: *Value = 0; return false; } break; case 0x04300000: switch (PAddr) { case 0x04300000: *Value = g_Reg->MI_MODE_REG; break; case 0x04300004: *Value = g_Reg->MI_VERSION_REG; break; case 0x04300008: *Value = g_Reg->MI_INTR_REG; break; case 0x0430000C: *Value = g_Reg->MI_INTR_MASK_REG; break; default: *Value = 0; return false; } break; case 0x04400000: switch (PAddr) { case 0x04400000: *Value = g_Reg->VI_STATUS_REG; break; case 0x04400004: *Value = g_Reg->VI_ORIGIN_REG; break; case 0x04400008: *Value = g_Reg->VI_WIDTH_REG; break; case 0x0440000C: *Value = g_Reg->VI_INTR_REG; break; case 0x04400010: UpdateHalfLine(); *Value = m_HalfLine; break; case 0x04400014: *Value = g_Reg->VI_BURST_REG; break; case 0x04400018: *Value = g_Reg->VI_V_SYNC_REG; break; case 0x0440001C: *Value = g_Reg->VI_H_SYNC_REG; break; case 0x04400020: *Value = g_Reg->VI_LEAP_REG; break; case 0x04400024: *Value = g_Reg->VI_H_START_REG; break; case 0x04400028: *Value = g_Reg->VI_V_START_REG; break; case 0x0440002C: *Value = g_Reg->VI_V_BURST_REG; break; case 0x04400030: *Value = g_Reg->VI_X_SCALE_REG; break; case 0x04400034: *Value = g_Reg->VI_Y_SCALE_REG; break; default: *Value = 0; return false; } break; case 0x04500000: switch (PAddr) { case 0x04500004: if (g_System->bFixedAudio()) { *Value = g_Audio->GetLength(); } else { if (g_Plugins->Audio()->AiReadLength != NULL) { *Value = g_Plugins->Audio()->AiReadLength(); } else { *Value = 0; } } break; case 0x0450000C: if (g_System->bFixedAudio()) { *Value = g_Audio->GetStatus(); } else { *Value = g_Reg->AI_STATUS_REG; } break; default: *Value = 0; return false; } break; case 0x04600000: switch (PAddr) { case 0x04600010: *Value = g_Reg->PI_STATUS_REG; break; case 0x04600014: *Value = g_Reg->PI_DOMAIN1_REG; break; case 0x04600018: *Value = g_Reg->PI_BSD_DOM1_PWD_REG; break; case 0x0460001C: *Value = g_Reg->PI_BSD_DOM1_PGS_REG; break; case 0x04600020: *Value = g_Reg->PI_BSD_DOM1_RLS_REG; break; case 0x04600024: *Value = g_Reg->PI_DOMAIN2_REG; break; case 0x04600028: *Value = g_Reg->PI_BSD_DOM2_PWD_REG; break; case 0x0460002C: *Value = g_Reg->PI_BSD_DOM2_PGS_REG; break; case 0x04600030: *Value = g_Reg->PI_BSD_DOM2_RLS_REG; break; default: *Value = 0; return false; } break; case 0x04700000: switch (PAddr) { case 0x04700000: *Value = g_Reg->RI_MODE_REG; break; case 0x04700004: *Value = g_Reg->RI_CONFIG_REG; break; case 0x04700008: *Value = g_Reg->RI_CURRENT_LOAD_REG; break; case 0x0470000C: *Value = g_Reg->RI_SELECT_REG; break; case 0x04700010: *Value = g_Reg->RI_REFRESH_REG; break; case 0x04700014: *Value = g_Reg->RI_LATENCY_REG; break; case 0x04700018: *Value = g_Reg->RI_RERROR_REG; break; case 0x0470001C: *Value = g_Reg->RI_WERROR_REG; break; default: *Value = 0; return false; } break; case 0x04800000: switch (PAddr) { case 0x04800018: *Value = g_Reg->SI_STATUS_REG; break; default: *Value = 0; return false; } break; case 0x05000000: *Value = PAddr & 0xFFFF; *Value = (*Value << 16) | *Value; return false; case 0x08000000: if (g_System->m_SaveUsing == SaveChip_Auto) { g_System->m_SaveUsing = SaveChip_FlashRam; } if (g_System->m_SaveUsing == SaveChip_Sram) { //Load Sram uint8_t tmp[4] = ""; DmaFromSram(tmp, PAddr - 0x08000000, 4); *Value = tmp[3] << 24 | tmp[2] << 16 | tmp[1] << 8 | tmp[0]; return true; } else if (g_System->m_SaveUsing != SaveChip_FlashRam) { *Value = PAddr & 0xFFFF; *Value = (*Value << 16) | *Value; return false; } *Value = ReadFromFlashStatus(PAddr); break; case 0x1FC00000: if (PAddr < 0x1FC007C0) { /* *Value = *(uint32_t *)(&PifRom[PAddr - 0x1FC00000]); *Value = swap32by8(*Value); */ g_Notify->BreakPoint(__FILEW__, __LINE__); return true; } else if (PAddr < 0x1FC00800) { uint8_t * PIF_Ram = g_MMU->PifRam(); *Value = *(uint32_t *)(&PIF_Ram[PAddr - 0x1FC007C0]); *Value = swap32by8(*Value); return true; } else { *Value = 0; return false; } break; default: *Value = PAddr & 0xFFFF; *Value = (*Value << 16) | *Value; return false; break; } return true; } bool CMipsMemoryVM::SB_NonMemory(uint32_t PAddr, uint8_t Value) { switch (PAddr & 0xFFF00000) { case 0x00000000: case 0x00100000: case 0x00200000: case 0x00300000: case 0x00400000: case 0x00500000: case 0x00600000: case 0x00700000: #ifdef CFB_READ if (PAddr >= CFBStart && PAddr < CFBEnd) { uint32_t OldProtect; VirtualProtect(m_RDRAM+(PAddr & ~0xFFF),0xFFC,PAGE_READWRITE, &OldProtect); *(uint8_t *)(m_RDRAM+PAddr) = Value; VirtualProtect(m_RDRAM+(PAddr & ~0xFFF),0xFFC,OldProtect, &OldProtect); g_Notify->DisplayError(L"FrameBufferWrite"); if (FrameBufferWrite) { FrameBufferWrite(PAddr,1); } break; } #endif if (PAddr < RdramSize()) { DWORD OldProtect; g_Recompiler->ClearRecompCode_Phys(PAddr & ~0xFFF, 0xFFC, CRecompiler::Remove_ProtectedMem); VirtualProtect(m_RDRAM + (PAddr & ~0xFFF), 0xFFC, PAGE_READWRITE, &OldProtect); *(uint8_t *)(m_RDRAM + PAddr) = Value; } break; default: return false; } return true; } bool CMipsMemoryVM::SH_NonMemory(uint32_t PAddr, uint16_t Value) { switch (PAddr & 0xFFF00000) { case 0x00000000: case 0x00100000: case 0x00200000: case 0x00300000: case 0x00400000: case 0x00500000: case 0x00600000: case 0x00700000: #ifdef CFB_READ if (PAddr >= CFBStart && PAddr < CFBEnd) { uint32_t OldProtect; VirtualProtect(m_RDRAM+(PAddr & ~0xFFF),0xFFC,PAGE_READWRITE, &OldProtect); *(uint16_t *)(m_RDRAM+PAddr) = Value; if (FrameBufferWrite) { FrameBufferWrite(PAddr & ~0xFFF,2); } //*(uint16_t *)(m_RDRAM+PAddr) = 0xFFFF; //VirtualProtect(m_RDRAM+(PAddr & ~0xFFF),0xFFC,PAGE_NOACCESS, &OldProtect); g_Notify->DisplayError(L"PAddr = %x",PAddr); break; } #endif if (PAddr < RdramSize()) { DWORD OldProtect; g_Recompiler->ClearRecompCode_Phys(PAddr & ~0xFFF, 0x1000, CRecompiler::Remove_ProtectedMem); VirtualProtect(m_RDRAM + (PAddr & ~0xFFF), 0xFFC, PAGE_READWRITE, &OldProtect); *(uint16_t *)(m_RDRAM + PAddr) = Value; } break; default: return false; } return true; } bool CMipsMemoryVM::SW_NonMemory(uint32_t PAddr, uint32_t Value) { if (PAddr >= 0x10000000 && PAddr < 0x16000000) { if ((PAddr - 0x10000000) < g_Rom->GetRomSize()) { m_RomWrittenTo = true; m_RomWroteValue = Value; #ifdef ROM_IN_MAPSPACE { uint32_t OldProtect; VirtualProtect(ROM,RomFileSize,PAGE_NOACCESS, &OldProtect); } #endif //LogMessage("%X: Wrote To Rom %08X from %08X",PROGRAM_COUNTER,Value,PAddr); } else { return false; } } switch (PAddr & 0xFFF00000) { case 0x00000000: case 0x00100000: case 0x00200000: case 0x00300000: case 0x00400000: case 0x00500000: case 0x00600000: case 0x00700000: #ifdef CFB_READ if (PAddr >= CFBStart && PAddr < CFBEnd) { uint32_t OldProtect; VirtualProtect(m_RDRAM+(PAddr & ~0xFFF),0xFFC,PAGE_READWRITE, &OldProtect); *(uint32_t *)(m_RDRAM+PAddr) = Value; VirtualProtect(m_RDRAM+(PAddr & ~0xFFF),0xFFC,OldProtect, &OldProtect); g_Notify->DisplayError(L"FrameBufferWrite %X",PAddr); if (FrameBufferWrite) { FrameBufferWrite(PAddr,4); } break; } #endif if (PAddr < RdramSize()) { DWORD OldProtect; g_Recompiler->ClearRecompCode_Phys(PAddr & ~0xFFF, 0x1000, CRecompiler::Remove_ProtectedMem); VirtualProtect(m_RDRAM + (PAddr & ~0xFFF), 0xFFC, PAGE_READWRITE, &OldProtect); *(uint32_t *)(m_RDRAM + PAddr) = Value; } break; case 0x03F00000: switch (PAddr) { case 0x03F00000: g_Reg->RDRAM_CONFIG_REG = Value; break; case 0x03F00004: g_Reg->RDRAM_DEVICE_ID_REG = Value; break; case 0x03F00008: g_Reg->RDRAM_DELAY_REG = Value; break; case 0x03F0000C: g_Reg->RDRAM_MODE_REG = Value; break; case 0x03F00010: g_Reg->RDRAM_REF_INTERVAL_REG = Value; break; case 0x03F00014: g_Reg->RDRAM_REF_ROW_REG = Value; break; case 0x03F00018: g_Reg->RDRAM_RAS_INTERVAL_REG = Value; break; case 0x03F0001C: g_Reg->RDRAM_MIN_INTERVAL_REG = Value; break; case 0x03F00020: g_Reg->RDRAM_ADDR_SELECT_REG = Value; break; case 0x03F00024: g_Reg->RDRAM_DEVICE_MANUF_REG = Value; break; case 0x03F04004: break; case 0x03F08004: break; case 0x03F80004: break; case 0x03F80008: break; case 0x03F8000C: break; case 0x03F80014: break; default: return false; } break; case 0x04000000: if (PAddr < 0x04002000) { g_Recompiler->ClearRecompCode_Phys(PAddr & ~0xFFF, 0xFFF, CRecompiler::Remove_ProtectedMem); *(uint32_t *)(m_RDRAM + PAddr) = Value; } else { switch (PAddr) { case 0x04040000: g_Reg->SP_MEM_ADDR_REG = Value; break; case 0x04040004: g_Reg->SP_DRAM_ADDR_REG = Value; break; case 0x04040008: g_Reg->SP_RD_LEN_REG = Value; SP_DMA_READ(); break; case 0x0404000C: g_Reg->SP_WR_LEN_REG = Value; SP_DMA_WRITE(); break; case 0x04040010: if ((Value & SP_CLR_HALT) != 0) { g_Reg->SP_STATUS_REG &= ~SP_STATUS_HALT; } if ((Value & SP_SET_HALT) != 0) { g_Reg->SP_STATUS_REG |= SP_STATUS_HALT; } if ((Value & SP_CLR_BROKE) != 0) { g_Reg->SP_STATUS_REG &= ~SP_STATUS_BROKE; } if ((Value & SP_CLR_INTR) != 0) { g_Reg->MI_INTR_REG &= ~MI_INTR_SP; g_Reg->m_RspIntrReg &= ~MI_INTR_SP; g_Reg->CheckInterrupts(); } if ((Value & SP_SET_INTR) != 0) { g_Notify->DisplayError(L"SP_SET_INTR"); } if ((Value & SP_CLR_SSTEP) != 0) { g_Reg->SP_STATUS_REG &= ~SP_STATUS_SSTEP; } if ((Value & SP_SET_SSTEP) != 0) { g_Reg->SP_STATUS_REG |= SP_STATUS_SSTEP; } if ((Value & SP_CLR_INTR_BREAK) != 0) { g_Reg->SP_STATUS_REG &= ~SP_STATUS_INTR_BREAK; } if ((Value & SP_SET_INTR_BREAK) != 0) { g_Reg->SP_STATUS_REG |= SP_STATUS_INTR_BREAK; } if ((Value & SP_CLR_SIG0) != 0) { g_Reg->SP_STATUS_REG &= ~SP_STATUS_SIG0; } if ((Value & SP_SET_SIG0) != 0) { g_Reg->SP_STATUS_REG |= SP_STATUS_SIG0; } if ((Value & SP_CLR_SIG1) != 0) { g_Reg->SP_STATUS_REG &= ~SP_STATUS_SIG1; } if ((Value & SP_SET_SIG1) != 0) { g_Reg->SP_STATUS_REG |= SP_STATUS_SIG1; } if ((Value & SP_CLR_SIG2) != 0) { g_Reg->SP_STATUS_REG &= ~SP_STATUS_SIG2; } if ((Value & SP_SET_SIG2) != 0) { g_Reg->SP_STATUS_REG |= SP_STATUS_SIG2; } if ((Value & SP_CLR_SIG3) != 0) { g_Reg->SP_STATUS_REG &= ~SP_STATUS_SIG3; } if ((Value & SP_SET_SIG3) != 0) { g_Reg->SP_STATUS_REG |= SP_STATUS_SIG3; } if ((Value & SP_CLR_SIG4) != 0) { g_Reg->SP_STATUS_REG &= ~SP_STATUS_SIG4; } if ((Value & SP_SET_SIG4) != 0) { g_Reg->SP_STATUS_REG |= SP_STATUS_SIG4; } if ((Value & SP_CLR_SIG5) != 0) { g_Reg->SP_STATUS_REG &= ~SP_STATUS_SIG5; } if ((Value & SP_SET_SIG5) != 0) { g_Reg->SP_STATUS_REG |= SP_STATUS_SIG5; } if ((Value & SP_CLR_SIG6) != 0) { g_Reg->SP_STATUS_REG &= ~SP_STATUS_SIG6; } if ((Value & SP_SET_SIG6) != 0) { g_Reg->SP_STATUS_REG |= SP_STATUS_SIG6; } if ((Value & SP_CLR_SIG7) != 0) { g_Reg->SP_STATUS_REG &= ~SP_STATUS_SIG7; } if ((Value & SP_SET_SIG7) != 0) { g_Reg->SP_STATUS_REG |= SP_STATUS_SIG7; } if ((Value & SP_SET_SIG0) != 0 && g_System->RspAudioSignal()) { g_Reg->MI_INTR_REG |= MI_INTR_SP; g_Reg->CheckInterrupts(); } //if (*( uint32_t *)(DMEM + 0xFC0) == 1) //{ // ChangeTimer(RspTimer,0x30000); //} //else //{ try { g_System->RunRSP(); } catch (...) { g_Notify->BreakPoint(__FILEW__, __LINE__); } //} break; case 0x0404001C: g_Reg->SP_SEMAPHORE_REG = 0; break; case 0x04080000: g_Reg->SP_PC_REG = Value & 0xFFC; break; default: return false; } } break; case 0x04100000: switch (PAddr) { case 0x04100000: g_Reg->DPC_START_REG = Value; g_Reg->DPC_CURRENT_REG = Value; break; case 0x04100004: g_Reg->DPC_END_REG = Value; if (g_Plugins->Gfx()->ProcessRDPList) { g_Plugins->Gfx()->ProcessRDPList(); } break; //case 0x04100008: g_Reg->DPC_CURRENT_REG = Value; break; case 0x0410000C: if ((Value & DPC_CLR_XBUS_DMEM_DMA) != 0) { g_Reg->DPC_STATUS_REG &= ~DPC_STATUS_XBUS_DMEM_DMA; } if ((Value & DPC_SET_XBUS_DMEM_DMA) != 0) { g_Reg->DPC_STATUS_REG |= DPC_STATUS_XBUS_DMEM_DMA; } if ((Value & DPC_CLR_FREEZE) != 0) { g_Reg->DPC_STATUS_REG &= ~DPC_STATUS_FREEZE; } if ((Value & DPC_SET_FREEZE) != 0) { g_Reg->DPC_STATUS_REG |= DPC_STATUS_FREEZE; } if ((Value & DPC_CLR_FLUSH) != 0) { g_Reg->DPC_STATUS_REG &= ~DPC_STATUS_FLUSH; } if ((Value & DPC_SET_FLUSH) != 0) { g_Reg->DPC_STATUS_REG |= DPC_STATUS_FLUSH; } if ((Value & DPC_CLR_FREEZE) != 0) { if ((g_Reg->SP_STATUS_REG & SP_STATUS_HALT) == 0) { if ((g_Reg->SP_STATUS_REG & SP_STATUS_BROKE) == 0) { try { g_System->RunRSP(); } catch (...) { g_Notify->BreakPoint(__FILEW__, __LINE__); } } } } #ifdef tofix if (ShowUnhandledMemory) { //if ( ( Value & DPC_CLR_TMEM_CTR ) != 0) //{ // g_Notify->DisplayError(L"RSP: DPC_STATUS_REG: DPC_CLR_TMEM_CTR"); //} //if ( ( Value & DPC_CLR_PIPE_CTR ) != 0) //{ // g_Notify->DisplayError(L"RSP: DPC_STATUS_REG: DPC_CLR_PIPE_CTR"); //} //if ( ( Value & DPC_CLR_CMD_CTR ) != 0) //{ // g_Notify->DisplayError(L"RSP: DPC_STATUS_REG: DPC_CLR_CMD_CTR"); //} //if ( ( Value & DPC_CLR_CLOCK_CTR ) != 0) //{ // g_Notify->DisplayError(L"RSP: DPC_STATUS_REG: DPC_CLR_CLOCK_CTR"); //} } #endif break; default: return false; } break; case 0x04300000: switch (PAddr) { case 0x04300000: g_Reg->MI_MODE_REG &= ~0x7F; g_Reg->MI_MODE_REG |= (Value & 0x7F); if ((Value & MI_CLR_INIT) != 0) { g_Reg->MI_MODE_REG &= ~MI_MODE_INIT; } if ((Value & MI_SET_INIT) != 0) { g_Reg->MI_MODE_REG |= MI_MODE_INIT; } if ((Value & MI_CLR_EBUS) != 0) { g_Reg->MI_MODE_REG &= ~MI_MODE_EBUS; } if ((Value & MI_SET_EBUS) != 0) { g_Reg->MI_MODE_REG |= MI_MODE_EBUS; } if ((Value & MI_CLR_DP_INTR) != 0) { g_Reg->MI_INTR_REG &= ~MI_INTR_DP; g_Reg->m_GfxIntrReg &= ~MI_INTR_DP; g_Reg->CheckInterrupts(); } if ((Value & MI_CLR_RDRAM) != 0) { g_Reg->MI_MODE_REG &= ~MI_MODE_RDRAM; } if ((Value & MI_SET_RDRAM) != 0) { g_Reg->MI_MODE_REG |= MI_MODE_RDRAM; } break; case 0x0430000C: if ((Value & MI_INTR_MASK_CLR_SP) != 0) { g_Reg->MI_INTR_MASK_REG &= ~MI_INTR_MASK_SP; } if ((Value & MI_INTR_MASK_SET_SP) != 0) { g_Reg->MI_INTR_MASK_REG |= MI_INTR_MASK_SP; } if ((Value & MI_INTR_MASK_CLR_SI) != 0) { g_Reg->MI_INTR_MASK_REG &= ~MI_INTR_MASK_SI; } if ((Value & MI_INTR_MASK_SET_SI) != 0) { g_Reg->MI_INTR_MASK_REG |= MI_INTR_MASK_SI; } if ((Value & MI_INTR_MASK_CLR_AI) != 0) { g_Reg->MI_INTR_MASK_REG &= ~MI_INTR_MASK_AI; } if ((Value & MI_INTR_MASK_SET_AI) != 0) { g_Reg->MI_INTR_MASK_REG |= MI_INTR_MASK_AI; } if ((Value & MI_INTR_MASK_CLR_VI) != 0) { g_Reg->MI_INTR_MASK_REG &= ~MI_INTR_MASK_VI; } if ((Value & MI_INTR_MASK_SET_VI) != 0) { g_Reg->MI_INTR_MASK_REG |= MI_INTR_MASK_VI; } if ((Value & MI_INTR_MASK_CLR_PI) != 0) { g_Reg->MI_INTR_MASK_REG &= ~MI_INTR_MASK_PI; } if ((Value & MI_INTR_MASK_SET_PI) != 0) { g_Reg->MI_INTR_MASK_REG |= MI_INTR_MASK_PI; } if ((Value & MI_INTR_MASK_CLR_DP) != 0) { g_Reg->MI_INTR_MASK_REG &= ~MI_INTR_MASK_DP; } if ((Value & MI_INTR_MASK_SET_DP) != 0) { g_Reg->MI_INTR_MASK_REG |= MI_INTR_MASK_DP; } break; default: return false; } break; case 0x04400000: switch (PAddr) { case 0x04400000: if (g_Reg->VI_STATUS_REG != Value) { g_Reg->VI_STATUS_REG = Value; if (g_Plugins->Gfx()->ViStatusChanged != NULL) { g_Plugins->Gfx()->ViStatusChanged(); } } break; case 0x04400004: #ifdef CFB_READ if (g_Reg->VI_ORIGIN_REG > 0x280) { SetFrameBuffer(g_Reg->VI_ORIGIN_REG, (uint32_t)(VI_WIDTH_REG * (VI_WIDTH_REG *.75))); } #endif g_Reg->VI_ORIGIN_REG = (Value & 0xFFFFFF); //if (UpdateScreen != NULL ) //{ // UpdateScreen(); //} break; case 0x04400008: if (g_Reg->VI_WIDTH_REG != Value) { g_Reg->VI_WIDTH_REG = Value; if (g_Plugins->Gfx()->ViWidthChanged != NULL) { g_Plugins->Gfx()->ViWidthChanged(); } } break; case 0x0440000C: g_Reg->VI_INTR_REG = Value; break; case 0x04400010: g_Reg->MI_INTR_REG &= ~MI_INTR_VI; g_Reg->CheckInterrupts(); break; case 0x04400014: g_Reg->VI_BURST_REG = Value; break; case 0x04400018: g_Reg->VI_V_SYNC_REG = Value; break; case 0x0440001C: g_Reg->VI_H_SYNC_REG = Value; break; case 0x04400020: g_Reg->VI_LEAP_REG = Value; break; case 0x04400024: g_Reg->VI_H_START_REG = Value; break; case 0x04400028: g_Reg->VI_V_START_REG = Value; break; case 0x0440002C: g_Reg->VI_V_BURST_REG = Value; break; case 0x04400030: g_Reg->VI_X_SCALE_REG = Value; break; case 0x04400034: g_Reg->VI_Y_SCALE_REG = Value; break; default: return false; } break; case 0x04500000: switch (PAddr) { case 0x04500000: g_Reg->AI_DRAM_ADDR_REG = Value; break; case 0x04500004: g_Reg->AI_LEN_REG = Value; if (g_System->bFixedAudio()) { g_Audio->LenChanged(); } else { if (g_Plugins->Audio()->AiLenChanged != NULL) { g_Plugins->Audio()->AiLenChanged(); } } break; case 0x04500008: g_Reg->AI_CONTROL_REG = (Value & 1); break; case 0x0450000C: /* Clear Interrupt */; g_Reg->MI_INTR_REG &= ~MI_INTR_AI; g_Reg->m_AudioIntrReg &= ~MI_INTR_AI; g_Reg->CheckInterrupts(); break; case 0x04500010: g_Reg->AI_DACRATE_REG = Value; g_Plugins->Audio()->DacrateChanged(g_System->SystemType()); if (g_System->bFixedAudio()) { g_Audio->SetFrequency(Value, g_System->SystemType()); } break; case 0x04500014: g_Reg->AI_BITRATE_REG = Value; break; default: return false; } break; case 0x04600000: switch (PAddr) { case 0x04600000: g_Reg->PI_DRAM_ADDR_REG = Value; break; case 0x04600004: g_Reg->PI_CART_ADDR_REG = Value; break; case 0x04600008: g_Reg->PI_RD_LEN_REG = Value; PI_DMA_READ(); break; case 0x0460000C: g_Reg->PI_WR_LEN_REG = Value; PI_DMA_WRITE(); break; case 0x04600010: //if ((Value & PI_SET_RESET) != 0 ) //{ // g_Notify->DisplayError(L"reset Controller"); //} if ((Value & PI_CLR_INTR) != 0) { g_Reg->MI_INTR_REG &= ~MI_INTR_PI; g_Reg->CheckInterrupts(); } break; case 0x04600014: g_Reg->PI_DOMAIN1_REG = (Value & 0xFF); break; case 0x04600018: g_Reg->PI_BSD_DOM1_PWD_REG = (Value & 0xFF); break; case 0x0460001C: g_Reg->PI_BSD_DOM1_PGS_REG = (Value & 0xFF); break; case 0x04600020: g_Reg->PI_BSD_DOM1_RLS_REG = (Value & 0xFF); break; case 0x04600024: g_Reg->PI_DOMAIN2_REG = (Value & 0xFF); break; case 0x04600028: g_Reg->PI_BSD_DOM2_PWD_REG = (Value & 0xFF); break; case 0x0460002C: g_Reg->PI_BSD_DOM2_PGS_REG = (Value & 0xFF); break; case 0x04600030: g_Reg->PI_BSD_DOM2_RLS_REG = (Value & 0xFF); break; default: return false; } break; case 0x04700000: switch (PAddr) { case 0x04700000: g_Reg->RI_MODE_REG = Value; break; case 0x04700004: g_Reg->RI_CONFIG_REG = Value; break; case 0x04700008: g_Reg->RI_CURRENT_LOAD_REG = Value; break; case 0x0470000C: g_Reg->RI_SELECT_REG = Value; break; case 0x04700010: g_Reg->RI_REFRESH_REG = Value; break; case 0x04700014: g_Reg->RI_LATENCY_REG = Value; break; case 0x04700018: g_Reg->RI_RERROR_REG = Value; break; case 0x0470001C: g_Reg->RI_WERROR_REG = Value; break; default: return false; } break; case 0x04800000: switch (PAddr) { case 0x04800000: g_Reg->SI_DRAM_ADDR_REG = Value; break; case 0x04800004: g_Reg->SI_PIF_ADDR_RD64B_REG = Value; SI_DMA_READ(); break; case 0x04800010: g_Reg->SI_PIF_ADDR_WR64B_REG = Value; SI_DMA_WRITE(); break; case 0x04800018: g_Reg->MI_INTR_REG &= ~MI_INTR_SI; g_Reg->SI_STATUS_REG &= ~SI_STATUS_INTERRUPT; g_Reg->CheckInterrupts(); break; default: return false; } break; case 0x08000000: if (g_System->m_SaveUsing == SaveChip_Sram) { //Store Sram uint8_t tmp[4] = ""; tmp[0] = 0xFF & (Value); tmp[1] = 0xFF & (Value >> 8); tmp[2] = 0xFF & (Value >> 16); tmp[3] = 0xFF & (Value >> 24); DmaFromSram(tmp, PAddr - 0x08000000, 4); return true; } if (PAddr != 0x08010000) { return false; } if (g_System->m_SaveUsing == SaveChip_Auto) { g_System->m_SaveUsing = SaveChip_FlashRam; } if (g_System->m_SaveUsing != SaveChip_FlashRam) { return true; } WriteToFlashCommand(Value); return true; break; case 0x1FC00000: if (PAddr < 0x1FC007C0) { return false; } else if (PAddr < 0x1FC00800) { Value = swap32by8(Value); *(uint32_t *)(&m_PifRam[PAddr - 0x1FC007C0]) = Value; if (PAddr == 0x1FC007FC) { PifRamWrite(); } return true; } return false; break; default: return false; break; } return true; } void CMipsMemoryVM::UpdateHalfLine() { uint32_t NextViTimer = g_SystemTimer->GetTimer(CSystemTimer::ViTimer); if (*g_NextTimer < 0) { m_HalfLine = 0; return; } int32_t check_value = (int32_t)(m_HalfLineCheck - NextViTimer); if (check_value > 0 && check_value < 40) { *g_NextTimer -= g_System->ViRefreshRate(); if (*g_NextTimer < 0) { *g_NextTimer = 0 - g_System->CountPerOp(); } g_SystemTimer->UpdateTimers(); NextViTimer = g_SystemTimer->GetTimer(CSystemTimer::ViTimer); } m_HalfLine = (uint32_t)(*g_NextTimer / g_System->ViRefreshRate()); m_HalfLine &= ~1; m_HalfLine |= m_FieldSerration; g_Reg->VI_V_CURRENT_LINE_REG = m_HalfLine; m_HalfLineCheck = NextViTimer; } void CMipsMemoryVM::UpdateFieldSerration(uint32_t interlaced) { m_FieldSerration ^= 1; m_FieldSerration &= interlaced; } void CMipsMemoryVM::ProtectMemory(uint32_t StartVaddr, uint32_t EndVaddr) { WriteTraceF(TraceProtectedMem, __FUNCTION__ ": StartVaddr: %08X EndVaddr: %08X", StartVaddr, EndVaddr); if (!ValidVaddr(StartVaddr) || !ValidVaddr(EndVaddr)) { return; } //Get Physical Addresses passed uint32_t StartPAddr, EndPAddr; if (!TranslateVaddr(StartVaddr, StartPAddr)) { g_Notify->BreakPoint(__FILEW__, __LINE__); } if (!TranslateVaddr(EndVaddr, EndPAddr)) { g_Notify->BreakPoint(__FILEW__, __LINE__); } //Get Length of memory being protected int32_t Length = ((EndPAddr + 3) - StartPAddr) & ~3; if (Length < 0) { g_Notify->BreakPoint(__FILEW__, __LINE__); } //Protect that memory address space DWORD OldProtect; uint8_t * MemLoc = Rdram() + StartPAddr; WriteTraceF(TraceProtectedMem, __FUNCTION__ ": Paddr: %08X Length: %X", StartPAddr, Length); VirtualProtect(MemLoc, Length, PAGE_READONLY, &OldProtect); } void CMipsMemoryVM::UnProtectMemory(uint32_t StartVaddr, uint32_t EndVaddr) { WriteTraceF(TraceProtectedMem, __FUNCTION__ ": StartVaddr: %08X EndVaddr: %08X", StartVaddr, EndVaddr); if (!ValidVaddr(StartVaddr) || !ValidVaddr(EndVaddr)) { return; } //Get Physical Addresses passed uint32_t StartPAddr, EndPAddr; if (!TranslateVaddr(StartVaddr, StartPAddr)) { g_Notify->BreakPoint(__FILEW__, __LINE__); } if (!TranslateVaddr(EndVaddr, EndPAddr)) { g_Notify->BreakPoint(__FILEW__, __LINE__); } //Get Length of memory being protected int32_t Length = ((EndPAddr + 3) - StartPAddr) & ~3; if (Length < 0) { g_Notify->BreakPoint(__FILEW__, __LINE__); } //Protect that memory address space DWORD OldProtect; uint8_t * MemLoc = Rdram() + StartPAddr; VirtualProtect(MemLoc, Length, PAGE_READWRITE, &OldProtect); } void CMipsMemoryVM::Compile_LB() { OPCODE & Opcode = CRecompilerOps::m_Opcode; x86Reg TempReg1, TempReg2; CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(Opcode.Hex, m_CompilePC)); if (Opcode.rt == 0) { return; } if (IsConst(Opcode.base)) { uint32_t Address = (GetMipsRegLo(Opcode.base) + (int16_t)Opcode.offset) ^ 3; Map_GPR_32bit(Opcode.rt, true, -1); Compile_LB(GetMipsRegMapLo(Opcode.rt), Address, true); return; } if (IsMapped(Opcode.rt)) { ProtectGPR(Opcode.rt); } if (IsMapped(Opcode.base)) { ProtectGPR(Opcode.base); if (Opcode.offset != 0) { TempReg1 = Map_TempReg(x86_Any, -1, false); LeaSourceAndOffset(TempReg1, GetMipsRegMapLo(Opcode.base), (int16_t)Opcode.offset); } else { TempReg1 = Map_TempReg(x86_Any, Opcode.base, false); } } else { TempReg1 = Map_TempReg(x86_Any, Opcode.base, false); AddConstToX86Reg(TempReg1, (int16_t)Opcode.immediate); } if (g_System->bUseTlb()) { TempReg2 = Map_TempReg(x86_Any, -1, false); MoveX86RegToX86Reg(TempReg1, TempReg2); ShiftRightUnsignImmed(TempReg2, 12); MoveVariableDispToX86Reg(m_TLB_ReadMap, "m_TLB_ReadMap", TempReg2, TempReg2, 4); CompileReadTLBMiss(TempReg1, TempReg2); XorConstToX86Reg(TempReg1, 3); Map_GPR_32bit(Opcode.rt, true, -1); MoveSxByteX86regPointerToX86reg(TempReg1, TempReg2, GetMipsRegMapLo(Opcode.rt)); } else { AndConstToX86Reg(TempReg1, 0x1FFFFFFF); XorConstToX86Reg(TempReg1, 3); Map_GPR_32bit(Opcode.rt, true, -1); MoveSxN64MemToX86regByte(GetMipsRegMapLo(Opcode.rt), TempReg1); } } void CMipsMemoryVM::Compile_LBU() { OPCODE & Opcode = CRecompilerOps::m_Opcode; x86Reg TempReg1, TempReg2; CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(Opcode.Hex, m_CompilePC)); if (Opcode.rt == 0) { return; } if (IsConst(Opcode.base)) { uint32_t Address = (GetMipsRegLo(Opcode.base) + (int16_t)Opcode.offset) ^ 3; Map_GPR_32bit(Opcode.rt, false, -1); Compile_LB(GetMipsRegMapLo(Opcode.rt), Address, false); return; } if (IsMapped(Opcode.rt)) { ProtectGPR(Opcode.rt); } if (IsMapped(Opcode.base)) { ProtectGPR(Opcode.base); if (Opcode.offset != 0) { TempReg1 = Map_TempReg(x86_Any, -1, false); LeaSourceAndOffset(TempReg1, GetMipsRegMapLo(Opcode.base), (int16_t)Opcode.offset); } else { TempReg1 = Map_TempReg(x86_Any, Opcode.base, false); } } else { TempReg1 = Map_TempReg(x86_Any, Opcode.base, false); AddConstToX86Reg(TempReg1, (int16_t)Opcode.immediate); } if (g_System->bUseTlb()) { TempReg2 = Map_TempReg(x86_Any, -1, false); MoveX86RegToX86Reg(TempReg1, TempReg2); ShiftRightUnsignImmed(TempReg2, 12); MoveVariableDispToX86Reg(m_TLB_ReadMap, "m_TLB_ReadMap", TempReg2, TempReg2, 4); CompileReadTLBMiss(TempReg1, TempReg2); XorConstToX86Reg(TempReg1, 3); Map_GPR_32bit(Opcode.rt, false, -1); MoveZxByteX86regPointerToX86reg(TempReg1, TempReg2, GetMipsRegMapLo(Opcode.rt)); } else { AndConstToX86Reg(TempReg1, 0x1FFFFFFF); XorConstToX86Reg(TempReg1, 3); Map_GPR_32bit(Opcode.rt, false, -1); MoveZxN64MemToX86regByte(GetMipsRegMapLo(Opcode.rt), TempReg1); } } void CMipsMemoryVM::Compile_LH() { OPCODE & Opcode = CRecompilerOps::m_Opcode; x86Reg TempReg1, TempReg2; CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(Opcode.Hex, m_CompilePC)); if (Opcode.rt == 0) return; if (IsConst(Opcode.base)) { uint32_t Address = (GetMipsRegLo(Opcode.base) + (int16_t)Opcode.offset) ^ 2; Map_GPR_32bit(Opcode.rt, true, -1); Compile_LH(GetMipsRegMapLo(Opcode.rt), Address, true); return; } if (IsMapped(Opcode.rt)) { ProtectGPR(Opcode.rt); } if (IsMapped(Opcode.base)) { ProtectGPR(Opcode.base); if (Opcode.offset != 0) { TempReg1 = Map_TempReg(x86_Any, -1, false); LeaSourceAndOffset(TempReg1, GetMipsRegMapLo(Opcode.base), (int16_t)Opcode.offset); } else { TempReg1 = Map_TempReg(x86_Any, Opcode.base, false); } } else { TempReg1 = Map_TempReg(x86_Any, Opcode.base, false); AddConstToX86Reg(TempReg1, (int16_t)Opcode.immediate); } if (g_System->bUseTlb()) { TempReg2 = Map_TempReg(x86_Any, -1, false); MoveX86RegToX86Reg(TempReg1, TempReg2); ShiftRightUnsignImmed(TempReg2, 12); MoveVariableDispToX86Reg(m_TLB_ReadMap, "m_TLB_ReadMap", TempReg2, TempReg2, 4); CompileReadTLBMiss(TempReg1, TempReg2); XorConstToX86Reg(TempReg1, 2); Map_GPR_32bit(Opcode.rt, true, -1); MoveSxHalfX86regPointerToX86reg(TempReg1, TempReg2, GetMipsRegMapLo(Opcode.rt)); } else { AndConstToX86Reg(TempReg1, 0x1FFFFFFF); XorConstToX86Reg(TempReg1, 2); Map_GPR_32bit(Opcode.rt, true, -1); MoveSxN64MemToX86regHalf(GetMipsRegMapLo(Opcode.rt), TempReg1); } } void CMipsMemoryVM::Compile_LHU() { OPCODE & Opcode = CRecompilerOps::m_Opcode; x86Reg TempReg1, TempReg2; CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(Opcode.Hex, m_CompilePC)); if (Opcode.rt == 0) { return; } if (IsConst(Opcode.base)) { uint32_t Address = (GetMipsRegLo(Opcode.base) + (int16_t)Opcode.offset) ^ 2; Map_GPR_32bit(Opcode.rt, false, -1); Compile_LH(GetMipsRegMapLo(Opcode.rt), Address, false); return; } if (IsMapped(Opcode.rt)) { ProtectGPR(Opcode.rt); } if (IsMapped(Opcode.base)) { ProtectGPR(Opcode.base); if (Opcode.offset != 0) { TempReg1 = Map_TempReg(x86_Any, -1, false); LeaSourceAndOffset(TempReg1, GetMipsRegMapLo(Opcode.base), (int16_t)Opcode.offset); } else { TempReg1 = Map_TempReg(x86_Any, Opcode.base, false); } } else { TempReg1 = Map_TempReg(x86_Any, Opcode.base, false); AddConstToX86Reg(TempReg1, (int16_t)Opcode.immediate); } if (g_System->bUseTlb()) { TempReg2 = Map_TempReg(x86_Any, -1, false); MoveX86RegToX86Reg(TempReg1, TempReg2); ShiftRightUnsignImmed(TempReg2, 12); MoveVariableDispToX86Reg(m_TLB_ReadMap, "m_TLB_ReadMap", TempReg2, TempReg2, 4); CompileReadTLBMiss(TempReg1, TempReg2); XorConstToX86Reg(TempReg1, 2); Map_GPR_32bit(Opcode.rt, false, -1); MoveZxHalfX86regPointerToX86reg(TempReg1, TempReg2, GetMipsRegMapLo(Opcode.rt)); } else { AndConstToX86Reg(TempReg1, 0x1FFFFFFF); XorConstToX86Reg(TempReg1, 2); Map_GPR_32bit(Opcode.rt, true, -1); MoveZxN64MemToX86regHalf(GetMipsRegMapLo(Opcode.rt), TempReg1); } } void CMipsMemoryVM::Compile_LW() { Compile_LW(true, false); } void CMipsMemoryVM::Compile_LL() { Compile_LW(true, true); } void CMipsMemoryVM::Compile_LW(bool ResultSigned, bool bRecordLLBit) { OPCODE & Opcode = CRecompilerOps::m_Opcode; CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(Opcode.Hex, m_CompilePC)); if (Opcode.rt == 0) return; x86Reg TempReg1, TempReg2; if (Opcode.base == 29 && g_System->bFastSP()) { char String[100]; Map_GPR_32bit(Opcode.rt, ResultSigned, -1); TempReg1 = Map_MemoryStack(x86_Any, true); sprintf(String, "%Xh", (int16_t)Opcode.offset); MoveVariableDispToX86Reg((void *)((uint32_t)(int16_t)Opcode.offset), String, GetMipsRegMapLo(Opcode.rt), TempReg1, 1); if (bRecordLLBit) { g_Notify->BreakPoint(__FILEW__, __LINE__); } } else { if (IsConst(Opcode.base)) { uint32_t Address = GetMipsRegLo(Opcode.base) + (int16_t)Opcode.offset; Map_GPR_32bit(Opcode.rt, ResultSigned, -1); Compile_LW(GetMipsRegMapLo(Opcode.rt), Address); if (bRecordLLBit) { g_Notify->BreakPoint(__FILEW__, __LINE__); } } else { if (g_System->bUseTlb()) { if (IsMapped(Opcode.rt)) { ProtectGPR(Opcode.rt); } if (IsMapped(Opcode.base) && Opcode.offset == 0) { ProtectGPR(Opcode.base); TempReg1 = GetMipsRegMapLo(Opcode.base); } else { if (IsMapped(Opcode.base)) { ProtectGPR(Opcode.base); if (Opcode.offset != 0) { TempReg1 = Map_TempReg(x86_Any, -1, false); LeaSourceAndOffset(TempReg1, GetMipsRegMapLo(Opcode.base), (int16_t)Opcode.offset); } else { TempReg1 = Map_TempReg(x86_Any, Opcode.base, false); } } else { TempReg1 = Map_TempReg(x86_Any, Opcode.base, false); AddConstToX86Reg(TempReg1, (int16_t)Opcode.immediate); } } TempReg2 = Map_TempReg(x86_Any, -1, false); MoveX86RegToX86Reg(TempReg1, TempReg2); ShiftRightUnsignImmed(TempReg2, 12); MoveVariableDispToX86Reg(m_TLB_ReadMap, "m_TLB_ReadMap", TempReg2, TempReg2, 4); CompileReadTLBMiss(TempReg1, TempReg2); Map_GPR_32bit(Opcode.rt, ResultSigned, -1); MoveX86regPointerToX86reg(TempReg1, TempReg2, GetMipsRegMapLo(Opcode.rt)); if (bRecordLLBit) { MoveConstToVariable(1, _LLBit, "LLBit"); } } else { if (IsMapped(Opcode.base)) { ProtectGPR(Opcode.base); if (Opcode.offset != 0) { Map_GPR_32bit(Opcode.rt, ResultSigned, -1); LeaSourceAndOffset(GetMipsRegMapLo(Opcode.rt), GetMipsRegMapLo(Opcode.base), (int16_t)Opcode.offset); } else { Map_GPR_32bit(Opcode.rt, ResultSigned, Opcode.base); } } else { Map_GPR_32bit(Opcode.rt, ResultSigned, Opcode.base); AddConstToX86Reg(GetMipsRegMapLo(Opcode.rt), (int16_t)Opcode.immediate); } AndConstToX86Reg(GetMipsRegMapLo(Opcode.rt), 0x1FFFFFFF); MoveN64MemToX86reg(GetMipsRegMapLo(Opcode.rt), GetMipsRegMapLo(Opcode.rt)); if (bRecordLLBit) { MoveConstToVariable(1, _LLBit, "LLBit"); } } } } if (g_System->bFastSP() && Opcode.rt == 29) { ResetX86Protection(); ResetMemoryStack(); } } void CMipsMemoryVM::Compile_LWC1() { OPCODE & Opcode = CRecompilerOps::m_Opcode; x86Reg TempReg1, TempReg2, TempReg3; char Name[50]; CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(Opcode.Hex, m_CompilePC)); m_Section->CompileCop1Test(); if ((Opcode.ft & 1) != 0) { if (RegInStack(Opcode.ft - 1, CRegInfo::FPU_Double) || RegInStack(Opcode.ft - 1, CRegInfo::FPU_Qword)) { UnMap_FPR(Opcode.ft - 1, true); } } if (RegInStack(Opcode.ft, CRegInfo::FPU_Double) || RegInStack(Opcode.ft, CRegInfo::FPU_Qword)) { UnMap_FPR(Opcode.ft, true); } else { UnMap_FPR(Opcode.ft, false); } if (IsConst(Opcode.base)) { uint32_t Address = GetMipsRegLo(Opcode.base) + (int16_t)Opcode.offset; TempReg1 = Map_TempReg(x86_Any, -1, false); Compile_LW(TempReg1, Address); TempReg2 = Map_TempReg(x86_Any, -1, false); sprintf(Name, "_FPR_S[%d]", Opcode.ft); MoveVariableToX86reg(&_FPR_S[Opcode.ft], Name, TempReg2); MoveX86regToX86Pointer(TempReg1, TempReg2); return; } if (IsMapped(Opcode.base) && Opcode.offset == 0) { if (g_System->bUseTlb()) { ProtectGPR(Opcode.base); TempReg1 = GetMipsRegMapLo(Opcode.base); } else { TempReg1 = Map_TempReg(x86_Any, Opcode.base, false); } } else { if (IsMapped(Opcode.base)) { ProtectGPR(Opcode.base); if (Opcode.offset != 0) { TempReg1 = Map_TempReg(x86_Any, -1, false); LeaSourceAndOffset(TempReg1, GetMipsRegMapLo(Opcode.base), (int16_t)Opcode.offset); } else { TempReg1 = Map_TempReg(x86_Any, Opcode.base, false); } UnProtectGPR(Opcode.base); } else { TempReg1 = Map_TempReg(x86_Any, Opcode.base, false); if (Opcode.immediate == 0) { } else if (Opcode.immediate == 1) { IncX86reg(TempReg1); } else if (Opcode.immediate == 0xFFFF) { DecX86reg(TempReg1); } else { AddConstToX86Reg(TempReg1, (int16_t)Opcode.immediate); } } } TempReg2 = Map_TempReg(x86_Any, -1, false); if (g_System->bUseTlb()) { MoveX86RegToX86Reg(TempReg1, TempReg2); ShiftRightUnsignImmed(TempReg2, 12); MoveVariableDispToX86Reg(m_TLB_ReadMap, "m_TLB_ReadMap", TempReg2, TempReg2, 4); CompileReadTLBMiss(TempReg1, TempReg2); TempReg3 = Map_TempReg(x86_Any, -1, false); MoveX86regPointerToX86reg(TempReg1, TempReg2, TempReg3); } else { AndConstToX86Reg(TempReg1, 0x1FFFFFFF); TempReg3 = Map_TempReg(x86_Any, -1, false); MoveN64MemToX86reg(TempReg3, TempReg1); } sprintf(Name, "_FPR_S[%d]", Opcode.ft); MoveVariableToX86reg(&_FPR_S[Opcode.ft], Name, TempReg2); MoveX86regToX86Pointer(TempReg3, TempReg2); } void CMipsMemoryVM::Compile_LWL() { OPCODE & Opcode = CRecompilerOps::m_Opcode; x86Reg TempReg1 = x86_Unknown, TempReg2 = x86_Unknown, OffsetReg = x86_Unknown, shift = x86_Unknown; CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(Opcode.Hex, m_CompilePC)); if (Opcode.rt == 0) { return; } if (IsConst(Opcode.base)) { uint32_t Address = GetMipsRegLo(Opcode.base) + (int16_t)Opcode.offset; uint32_t Offset = Address & 3; Map_GPR_32bit(Opcode.rt, true, Opcode.rt); x86Reg Value = Map_TempReg(x86_Any, -1, false); Compile_LW(Value, (Address & ~3)); AndConstToX86Reg(GetMipsRegMapLo(Opcode.rt), LWL_MASK[Offset]); ShiftLeftSignImmed(Value, (uint8_t)LWL_SHIFT[Offset]); AddX86RegToX86Reg(GetMipsRegMapLo(Opcode.rt), Value); return; } shift = Map_TempReg(x86_ECX, -1, false); if (IsMapped(Opcode.rt)) { ProtectGPR(Opcode.rt); } if (IsMapped(Opcode.base)) { ProtectGPR(Opcode.base); if (Opcode.offset != 0) { TempReg1 = Map_TempReg(x86_Any, -1, false); LeaSourceAndOffset(TempReg1, GetMipsRegMapLo(Opcode.base), (int16_t)Opcode.offset); } else { TempReg1 = Map_TempReg(x86_Any, Opcode.base, false); } UnProtectGPR(Opcode.base); } else { TempReg1 = Map_TempReg(x86_Any, Opcode.base, false); AddConstToX86Reg(TempReg1, (int16_t)Opcode.immediate); } if (g_System->bUseTlb()) { TempReg2 = Map_TempReg(x86_Any, -1, false); MoveX86RegToX86Reg(TempReg1, TempReg2); ShiftRightUnsignImmed(TempReg2, 12); MoveVariableDispToX86Reg(m_TLB_ReadMap, "m_TLB_ReadMap", TempReg2, TempReg2, 4); CompileReadTLBMiss(TempReg1, TempReg2); } OffsetReg = Map_TempReg(x86_Any, -1, false); MoveX86RegToX86Reg(TempReg1, OffsetReg); AndConstToX86Reg(OffsetReg, 3); AndConstToX86Reg(TempReg1, (uint32_t)~3); Map_GPR_32bit(Opcode.rt, true, Opcode.rt); AndVariableDispToX86Reg((void *)LWL_MASK, "LWL_MASK", GetMipsRegMapLo(Opcode.rt), OffsetReg, Multip_x4); MoveVariableDispToX86Reg((void *)LWL_SHIFT, "LWL_SHIFT", shift, OffsetReg, 4); if (g_System->bUseTlb()) { MoveX86regPointerToX86reg(TempReg1, TempReg2, TempReg1); } else { AndConstToX86Reg(TempReg1, 0x1FFFFFFF); MoveN64MemToX86reg(TempReg1, TempReg1); } ShiftLeftSign(TempReg1); AddX86RegToX86Reg(GetMipsRegMapLo(Opcode.rt), TempReg1); } void CMipsMemoryVM::Compile_LWR() { OPCODE & Opcode = CRecompilerOps::m_Opcode; x86Reg TempReg1 = x86_Unknown, TempReg2 = x86_Unknown, OffsetReg = x86_Unknown, shift = x86_Unknown; CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(Opcode.Hex, m_CompilePC)); if (Opcode.rt == 0) { return; } if (IsConst(Opcode.base)) { uint32_t Address = GetMipsRegLo(Opcode.base) + (int16_t)Opcode.offset; uint32_t Offset = Address & 3; Map_GPR_32bit(Opcode.rt, true, Opcode.rt); x86Reg Value = Map_TempReg(x86_Any, -1, false); Compile_LW(Value, (Address & ~3)); AndConstToX86Reg(GetMipsRegMapLo(Opcode.rt), LWR_MASK[Offset]); ShiftRightUnsignImmed(Value, (uint8_t)LWR_SHIFT[Offset]); AddX86RegToX86Reg(GetMipsRegMapLo(Opcode.rt), Value); return; } shift = Map_TempReg(x86_ECX, -1, false); if (IsMapped(Opcode.rt)) { ProtectGPR(Opcode.rt); } if (IsMapped(Opcode.base)) { ProtectGPR(Opcode.base); if (Opcode.offset != 0) { TempReg1 = Map_TempReg(x86_Any, -1, false); LeaSourceAndOffset(TempReg1, GetMipsRegMapLo(Opcode.base), (int16_t)Opcode.offset); } else { TempReg1 = Map_TempReg(x86_Any, Opcode.base, false); } UnProtectGPR(Opcode.base); } else { TempReg1 = Map_TempReg(x86_Any, Opcode.base, false); AddConstToX86Reg(TempReg1, (int16_t)Opcode.immediate); } if (g_System->bUseTlb()) { TempReg2 = Map_TempReg(x86_Any, -1, false); MoveX86RegToX86Reg(TempReg1, TempReg2); ShiftRightUnsignImmed(TempReg2, 12); MoveVariableDispToX86Reg(m_TLB_ReadMap, "m_TLB_ReadMap", TempReg2, TempReg2, 4); CompileReadTLBMiss(TempReg1, TempReg2); } OffsetReg = Map_TempReg(x86_Any, -1, false); MoveX86RegToX86Reg(TempReg1, OffsetReg); AndConstToX86Reg(OffsetReg, 3); AndConstToX86Reg(TempReg1, (uint32_t)~3); Map_GPR_32bit(Opcode.rt, true, Opcode.rt); AndVariableDispToX86Reg((void *)LWR_MASK, "LWR_MASK", GetMipsRegMapLo(Opcode.rt), OffsetReg, Multip_x4); MoveVariableDispToX86Reg((void *)LWR_SHIFT, "LWR_SHIFT", shift, OffsetReg, 4); if (g_System->bUseTlb()) { MoveX86regPointerToX86reg(TempReg1, TempReg2, TempReg1); } else { AndConstToX86Reg(TempReg1, 0x1FFFFFFF); MoveN64MemToX86reg(TempReg1, TempReg1); } ShiftRightUnsign(TempReg1); AddX86RegToX86Reg(GetMipsRegMapLo(Opcode.rt), TempReg1); } void CMipsMemoryVM::Compile_LWU() { Compile_LW(false, false); } void CMipsMemoryVM::Compile_LD() { OPCODE & Opcode = CRecompilerOps::m_Opcode; CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(Opcode.Hex, m_CompilePC)); if (Opcode.rt == 0) { return; } x86Reg TempReg1, TempReg2; if (IsConst(Opcode.base)) { uint32_t Address = GetMipsRegLo(Opcode.base) + (int16_t)Opcode.offset; Map_GPR_64bit(Opcode.rt, -1); Compile_LW(GetMipsRegMapHi(Opcode.rt), Address); Compile_LW(GetMipsRegMapLo(Opcode.rt), Address + 4); if (g_System->bFastSP() && Opcode.rt == 29) { ResetMemoryStack(); } return; } if (IsMapped(Opcode.rt)) { ProtectGPR(Opcode.rt); } if (IsMapped(Opcode.base) && Opcode.offset == 0) { if (g_System->bUseTlb()) { ProtectGPR(Opcode.base); TempReg1 = GetMipsRegMapLo(Opcode.base); } else { TempReg1 = Map_TempReg(x86_Any, Opcode.base, false); } } else { if (IsMapped(Opcode.base)) { ProtectGPR(Opcode.base); if (Opcode.offset != 0) { TempReg1 = Map_TempReg(x86_Any, -1, false); LeaSourceAndOffset(TempReg1, GetMipsRegMapLo(Opcode.base), (int16_t)Opcode.offset); } else { TempReg1 = Map_TempReg(x86_Any, Opcode.base, false); } } else { TempReg1 = Map_TempReg(x86_Any, Opcode.base, false); AddConstToX86Reg(TempReg1, (int16_t)Opcode.immediate); } } if (g_System->bUseTlb()) { TempReg2 = Map_TempReg(x86_Any, -1, false); MoveX86RegToX86Reg(TempReg1, TempReg2); ShiftRightUnsignImmed(TempReg2, 12); MoveVariableDispToX86Reg(m_TLB_ReadMap, "m_TLB_ReadMap", TempReg2, TempReg2, 4); CompileReadTLBMiss(TempReg1, TempReg2); Map_GPR_64bit(Opcode.rt, -1); MoveX86regPointerToX86reg(TempReg1, TempReg2, GetMipsRegMapHi(Opcode.rt)); MoveX86regPointerToX86regDisp8(TempReg1, TempReg2, GetMipsRegMapLo(Opcode.rt), 4); } else { AndConstToX86Reg(TempReg1, 0x1FFFFFFF); Map_GPR_64bit(Opcode.rt, -1); MoveN64MemToX86reg(GetMipsRegMapHi(Opcode.rt), TempReg1); MoveN64MemDispToX86reg(GetMipsRegMapLo(Opcode.rt), TempReg1, 4); } if (g_System->bFastSP() && Opcode.rt == 29) { ResetX86Protection(); g_MMU->ResetMemoryStack(); } } void CMipsMemoryVM::Compile_LDC1() { OPCODE & Opcode = CRecompilerOps::m_Opcode; x86Reg TempReg1, TempReg2, TempReg3; char Name[50]; CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(Opcode.Hex, m_CompilePC)); m_Section->CompileCop1Test(); UnMap_FPR(Opcode.ft, false); if (IsConst(Opcode.base)) { uint32_t Address = GetMipsRegLo(Opcode.base) + (int16_t)Opcode.offset; TempReg1 = Map_TempReg(x86_Any, -1, false); Compile_LW(TempReg1, Address); TempReg2 = Map_TempReg(x86_Any, -1, false); sprintf(Name, "_FPR_D[%d]", Opcode.ft); MoveVariableToX86reg(&_FPR_D[Opcode.ft], Name, TempReg2); AddConstToX86Reg(TempReg2, 4); MoveX86regToX86Pointer(TempReg1, TempReg2); Compile_LW(TempReg1, Address + 4); sprintf(Name, "_FPR_S[%d]", Opcode.ft); MoveVariableToX86reg(&_FPR_D[Opcode.ft], Name, TempReg2); MoveX86regToX86Pointer(TempReg1, TempReg2); return; } if (IsMapped(Opcode.base) && Opcode.offset == 0) { if (g_System->bUseTlb()) { ProtectGPR(Opcode.base); TempReg1 = GetMipsRegMapLo(Opcode.base); } else { TempReg1 = Map_TempReg(x86_Any, Opcode.base, false); } } else { if (IsMapped(Opcode.base)) { ProtectGPR(Opcode.base); if (Opcode.offset != 0) { TempReg1 = Map_TempReg(x86_Any, -1, false); LeaSourceAndOffset(TempReg1, GetMipsRegMapLo(Opcode.base), (int16_t)Opcode.offset); } else { TempReg1 = Map_TempReg(x86_Any, Opcode.base, false); } } else { TempReg1 = Map_TempReg(x86_Any, Opcode.base, false); if (Opcode.immediate == 0) { } else if (Opcode.immediate == 1) { IncX86reg(TempReg1); } else if (Opcode.immediate == 0xFFFF) { DecX86reg(TempReg1); } else { AddConstToX86Reg(TempReg1, (int16_t)Opcode.immediate); } } } TempReg2 = Map_TempReg(x86_Any, -1, false); if (g_System->bUseTlb()) { MoveX86RegToX86Reg(TempReg1, TempReg2); ShiftRightUnsignImmed(TempReg2, 12); MoveVariableDispToX86Reg(m_TLB_ReadMap, "m_TLB_ReadMap", TempReg2, TempReg2, 4); CompileReadTLBMiss(TempReg1, TempReg2); TempReg3 = Map_TempReg(x86_Any, -1, false); MoveX86regPointerToX86reg(TempReg1, TempReg2, TempReg3); Push(TempReg2); sprintf(Name, "_FPR_S[%d]", Opcode.ft); MoveVariableToX86reg(&_FPR_D[Opcode.ft], Name, TempReg2); AddConstToX86Reg(TempReg2, 4); MoveX86regToX86Pointer(TempReg3, TempReg2); Pop(TempReg2); MoveX86regPointerToX86regDisp8(TempReg1, TempReg2, TempReg3, 4); sprintf(Name, "_FPR_S[%d]", Opcode.ft); MoveVariableToX86reg(&_FPR_D[Opcode.ft], Name, TempReg2); MoveX86regToX86Pointer(TempReg3, TempReg2); } else { AndConstToX86Reg(TempReg1, 0x1FFFFFFF); TempReg3 = Map_TempReg(x86_Any, -1, false); MoveN64MemToX86reg(TempReg3, TempReg1); sprintf(Name, "_FPR_S[%d]", Opcode.ft); MoveVariableToX86reg(&_FPR_D[Opcode.ft], Name, TempReg2); AddConstToX86Reg(TempReg2, 4); MoveX86regToX86Pointer(TempReg3, TempReg2); MoveN64MemDispToX86reg(TempReg3, TempReg1, 4); sprintf(Name, "_FPR_S[%d]", Opcode.ft); MoveVariableToX86reg(&_FPR_D[Opcode.ft], Name, TempReg2); MoveX86regToX86Pointer(TempReg3, TempReg2); } } void CMipsMemoryVM::Compile_LDL() { OPCODE & Opcode = CRecompilerOps::m_Opcode; CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(Opcode.Hex, m_CompilePC)); if (Opcode.base != 0) { UnMap_GPR(Opcode.base, true); } if (Opcode.rt != 0) { UnMap_GPR(Opcode.rt, true); } BeforeCallDirect(m_RegWorkingSet); MoveConstToVariable(Opcode.Hex, &R4300iOp::m_Opcode.Hex, "R4300iOp::m_Opcode.Hex"); Call_Direct(R4300iOp::LDL, "R4300iOp::LDL"); AfterCallDirect(m_RegWorkingSet); } void CMipsMemoryVM::Compile_LDR() { OPCODE & Opcode = CRecompilerOps::m_Opcode; CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(Opcode.Hex, m_CompilePC)); if (Opcode.base != 0) { UnMap_GPR(Opcode.base, true); } if (Opcode.rt != 0) { UnMap_GPR(Opcode.rt, true); } BeforeCallDirect(m_RegWorkingSet); MoveConstToVariable(Opcode.Hex, &R4300iOp::m_Opcode.Hex, "R4300iOp::m_Opcode.Hex"); Call_Direct(R4300iOp::LDR, "R4300iOp::LDR"); AfterCallDirect(m_RegWorkingSet); } void CMipsMemoryVM::Compile_SB() { OPCODE & Opcode = CRecompilerOps::m_Opcode; x86Reg TempReg1, TempReg2; CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(Opcode.Hex, m_CompilePC)); if (IsConst(Opcode.base)) { uint32_t Address = (GetMipsRegLo(Opcode.base) + (int16_t)Opcode.offset) ^ 3; if (IsConst(Opcode.rt)) { Compile_SB_Const((uint8_t)(GetMipsRegLo(Opcode.rt) & 0xFF), Address); } else if (IsMapped(Opcode.rt) && Is8BitReg(GetMipsRegMapLo(Opcode.rt))) { Compile_SB_Register(GetMipsRegMapLo(Opcode.rt), Address); } else { Compile_SB_Register(Map_TempReg(x86_Any8Bit, Opcode.rt, false), Address); } return; } if (IsMapped(Opcode.rt)) { ProtectGPR(Opcode.rt); } if (IsMapped(Opcode.base)) { ProtectGPR(Opcode.base); if (Opcode.offset != 0) { TempReg1 = Map_TempReg(x86_Any, -1, false); LeaSourceAndOffset(TempReg1, GetMipsRegMapLo(Opcode.base), (int16_t)Opcode.offset); } else { TempReg1 = Map_TempReg(x86_Any, Opcode.base, false); } UnProtectGPR(Opcode.base); } else { TempReg1 = Map_TempReg(x86_Any, Opcode.base, false); AddConstToX86Reg(TempReg1, (int16_t)Opcode.immediate); } Compile_StoreInstructClean(TempReg1, 4); if (g_System->bUseTlb()) { TempReg2 = Map_TempReg(x86_Any, -1, false); MoveX86RegToX86Reg(TempReg1, TempReg2); ShiftRightUnsignImmed(TempReg2, 12); MoveVariableDispToX86Reg(m_TLB_WriteMap, "m_TLB_WriteMap", TempReg2, TempReg2, 4); CompileWriteTLBMiss(TempReg1, TempReg2); XorConstToX86Reg(TempReg1, 3); if (IsConst(Opcode.rt)) { MoveConstByteToX86regPointer((uint8_t)(GetMipsRegLo(Opcode.rt) & 0xFF), TempReg1, TempReg2); } else if (IsMapped(Opcode.rt) && Is8BitReg(GetMipsRegMapLo(Opcode.rt))) { MoveX86regByteToX86regPointer(GetMipsRegMapLo(Opcode.rt), TempReg1, TempReg2); } else { UnProtectGPR(Opcode.rt); MoveX86regByteToX86regPointer(Map_TempReg(x86_Any8Bit, Opcode.rt, false), TempReg1, TempReg2); } } else { AndConstToX86Reg(TempReg1, 0x1FFFFFFF); XorConstToX86Reg(TempReg1, 3); if (IsConst(Opcode.rt)) { MoveConstByteToN64Mem((uint8_t)(GetMipsRegLo(Opcode.rt) & 0xFF), TempReg1); } else if (IsMapped(Opcode.rt) && Is8BitReg(GetMipsRegMapLo(Opcode.rt))) { MoveX86regByteToN64Mem(GetMipsRegMapLo(Opcode.rt), TempReg1); } else { UnProtectGPR(Opcode.rt); MoveX86regByteToN64Mem(Map_TempReg(x86_Any8Bit, Opcode.rt, false), TempReg1); } } } void CMipsMemoryVM::Compile_SH() { OPCODE & Opcode = CRecompilerOps::m_Opcode; x86Reg TempReg1, TempReg2; CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(Opcode.Hex, m_CompilePC)); if (IsConst(Opcode.base)) { uint32_t Address = (GetMipsRegLo(Opcode.base) + (int16_t)Opcode.offset) ^ 2; if (IsConst(Opcode.rt)) { Compile_SH_Const((uint16_t)(GetMipsRegLo(Opcode.rt) & 0xFFFF), Address); } else if (IsMapped(Opcode.rt)) { Compile_SH_Register(GetMipsRegMapLo(Opcode.rt), Address); } else { Compile_SH_Register(Map_TempReg(x86_Any, Opcode.rt, false), Address); } return; } if (IsMapped(Opcode.rt)) { ProtectGPR(Opcode.rt); } if (IsMapped(Opcode.base)) { ProtectGPR(Opcode.base); if (Opcode.offset != 0) { TempReg1 = Map_TempReg(x86_Any, -1, false); LeaSourceAndOffset(TempReg1, GetMipsRegMapLo(Opcode.base), (int16_t)Opcode.offset); } else { TempReg1 = Map_TempReg(x86_Any, Opcode.base, false); } UnProtectGPR(Opcode.base); } else { TempReg1 = Map_TempReg(x86_Any, Opcode.base, false); AddConstToX86Reg(TempReg1, (int16_t)Opcode.immediate); } if (g_System->bUseTlb()) { TempReg2 = Map_TempReg(x86_Any, -1, false); MoveX86RegToX86Reg(TempReg1, TempReg2); ShiftRightUnsignImmed(TempReg2, 12); MoveVariableDispToX86Reg(m_TLB_WriteMap, "m_TLB_WriteMap", TempReg2, TempReg2, 4); CompileWriteTLBMiss(TempReg1, TempReg2); XorConstToX86Reg(TempReg1, 2); if (IsConst(Opcode.rt)) { MoveConstHalfToX86regPointer((uint16_t)(GetMipsRegLo(Opcode.rt) & 0xFFFF), TempReg1, TempReg2); } else if (IsMapped(Opcode.rt)) { MoveX86regHalfToX86regPointer(GetMipsRegMapLo(Opcode.rt), TempReg1, TempReg2); } else { MoveX86regHalfToX86regPointer(Map_TempReg(x86_Any, Opcode.rt, false), TempReg1, TempReg2); } } else { AndConstToX86Reg(TempReg1, 0x1FFFFFFF); XorConstToX86Reg(TempReg1, 2); if (IsConst(Opcode.rt)) { MoveConstHalfToN64Mem((uint16_t)(GetMipsRegLo(Opcode.rt) & 0xFFFF), TempReg1); } else if (IsMapped(Opcode.rt)) { MoveX86regHalfToN64Mem(GetMipsRegMapLo(Opcode.rt), TempReg1); } else { MoveX86regHalfToN64Mem(Map_TempReg(x86_Any, Opcode.rt, false), TempReg1); } } } void CMipsMemoryVM::Compile_SW() { Compile_SW(false); } void CMipsMemoryVM::Compile_SC() { Compile_SW(true); } void CMipsMemoryVM::Compile_SW(bool bCheckLLbit) { OPCODE & Opcode = CRecompilerOps::m_Opcode; CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(Opcode.Hex, m_CompilePC)); x86Reg TempReg1, TempReg2; if (Opcode.base == 29 && g_System->bFastSP()) { if (bCheckLLbit) { g_Notify->BreakPoint(__FILEW__, __LINE__); } if (IsMapped(Opcode.rt)) { ProtectGPR(Opcode.rt); } TempReg1 = Map_MemoryStack(x86_Any, true); if (IsConst(Opcode.rt)) { MoveConstToMemoryDisp(GetMipsRegLo(Opcode.rt), TempReg1, (uint32_t)((int16_t)Opcode.offset)); } else if (IsMapped(Opcode.rt)) { MoveX86regToMemory(GetMipsRegMapLo(Opcode.rt), TempReg1, (uint32_t)((int16_t)Opcode.offset)); } else { TempReg2 = Map_TempReg(x86_Any, Opcode.rt, false); MoveX86regToMemory(TempReg2, TempReg1, (uint32_t)((int16_t)Opcode.offset)); } } else { if (IsConst(Opcode.base)) { uint32_t Address = GetMipsRegLo(Opcode.base) + (int16_t)Opcode.offset; if (bCheckLLbit) { g_Notify->BreakPoint(__FILEW__, __LINE__); } if (IsConst(Opcode.rt)) { Compile_SW_Const(GetMipsRegLo(Opcode.rt), Address); } else if (IsMapped(Opcode.rt)) { Compile_SW_Register(GetMipsRegMapLo(Opcode.rt), Address); } else { Compile_SW_Register(Map_TempReg(x86_Any, Opcode.rt, false), Address); } return; } if (IsMapped(Opcode.rt)) ProtectGPR(Opcode.rt); if (IsMapped(Opcode.base)) { ProtectGPR(Opcode.base); if (g_System->bDelaySI() || g_System->bDelayDP()) { m_RegWorkingSet.SetBlockCycleCount(m_RegWorkingSet.GetBlockCycleCount() - g_System->CountPerOp()); UpdateCounters(m_RegWorkingSet, false, true); m_RegWorkingSet.SetBlockCycleCount(m_RegWorkingSet.GetBlockCycleCount() + g_System->CountPerOp()); } if (Opcode.offset != 0) { TempReg1 = Map_TempReg(x86_Any, -1, false); LeaSourceAndOffset(TempReg1, GetMipsRegMapLo(Opcode.base), (int16_t)Opcode.offset); } else { TempReg1 = Map_TempReg(x86_Any, Opcode.base, false); } UnProtectGPR(Opcode.base); } else { TempReg1 = Map_TempReg(x86_Any, Opcode.base, false); AddConstToX86Reg(TempReg1, (int16_t)Opcode.immediate); } Compile_StoreInstructClean(TempReg1, 4); if (g_System->bUseTlb()) { TempReg2 = Map_TempReg(x86_Any, -1, false); MoveX86RegToX86Reg(TempReg1, TempReg2); ShiftRightUnsignImmed(TempReg2, 12); MoveVariableDispToX86Reg(m_TLB_WriteMap, "m_TLB_WriteMap", TempReg2, TempReg2, 4); CompileWriteTLBMiss(TempReg1, TempReg2); uint8_t * Jump = NULL; if (bCheckLLbit) { CompConstToVariable(1, _LLBit, "_LLBit"); JneLabel8("LLBit_Continue", 0); Jump = m_RecompPos - 1; } if (IsConst(Opcode.rt)) { MoveConstToX86regPointer(GetMipsRegLo(Opcode.rt), TempReg1, TempReg2); } else if (IsMapped(Opcode.rt)) { MoveX86regToX86regPointer(GetMipsRegMapLo(Opcode.rt), TempReg1, TempReg2); } else { MoveX86regToX86regPointer(Map_TempReg(x86_Any, Opcode.rt, false), TempReg1, TempReg2); } if (bCheckLLbit) { CPU_Message(" "); CPU_Message(" LLBit_Continue:"); SetJump8(Jump, m_RecompPos); Map_GPR_32bit(Opcode.rt, false, -1); MoveVariableToX86reg(_LLBit, "_LLBit", GetMipsRegMapLo(Opcode.rt)); } } else { if (bCheckLLbit) { g_Notify->BreakPoint(__FILEW__, __LINE__); } AndConstToX86Reg(TempReg1, 0x1FFFFFFF); if (IsConst(Opcode.rt)) { MoveConstToN64Mem(GetMipsRegLo(Opcode.rt), TempReg1); } else if (IsMapped(Opcode.rt)) { MoveX86regToN64Mem(GetMipsRegMapLo(Opcode.rt), TempReg1); } else { MoveX86regToN64Mem(Map_TempReg(x86_Any, Opcode.rt, false), TempReg1); } } } } void CMipsMemoryVM::Compile_SWC1() { OPCODE & Opcode = CRecompilerOps::m_Opcode; x86Reg TempReg1, TempReg2, TempReg3; char Name[50]; CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(Opcode.Hex, m_CompilePC)); m_Section->CompileCop1Test(); if (IsConst(Opcode.base)) { uint32_t Address = GetMipsRegLo(Opcode.base) + (int16_t)Opcode.offset; UnMap_FPR(Opcode.ft, true); TempReg1 = Map_TempReg(x86_Any, -1, false); sprintf(Name, "_FPR_S[%d]", Opcode.ft); MoveVariableToX86reg(&_FPR_S[Opcode.ft], Name, TempReg1); MoveX86PointerToX86reg(TempReg1, TempReg1); Compile_SW_Register(TempReg1, Address); return; } if (IsMapped(Opcode.base)) { ProtectGPR(Opcode.base); if (Opcode.offset != 0) { TempReg1 = Map_TempReg(x86_Any, -1, false); LeaSourceAndOffset(TempReg1, GetMipsRegMapLo(Opcode.base), (int16_t)Opcode.offset); } else { TempReg1 = Map_TempReg(x86_Any, Opcode.base, false); } } else { TempReg1 = Map_TempReg(x86_Any, Opcode.base, false); if (Opcode.immediate == 0) { } else if (Opcode.immediate == 1) { IncX86reg(TempReg1); } else if (Opcode.immediate == 0xFFFF) { DecX86reg(TempReg1); } else { AddConstToX86Reg(TempReg1, (int16_t)Opcode.immediate); } } if (g_System->bUseTlb()) { TempReg2 = Map_TempReg(x86_Any, -1, false); MoveX86RegToX86Reg(TempReg1, TempReg2); ShiftRightUnsignImmed(TempReg2, 12); MoveVariableDispToX86Reg(m_TLB_WriteMap, "m_TLB_WriteMap", TempReg2, TempReg2, 4); CompileWriteTLBMiss(TempReg1, TempReg2); UnMap_FPR(Opcode.ft, true); TempReg3 = Map_TempReg(x86_Any, -1, false); sprintf(Name, "_FPR_S[%d]", Opcode.ft); MoveVariableToX86reg(&_FPR_S[Opcode.ft], Name, TempReg3); MoveX86PointerToX86reg(TempReg3, TempReg3); MoveX86regToX86regPointer(TempReg3, TempReg1, TempReg2); } else { TempReg2 = Map_TempReg(x86_Any, -1, false); UnMap_FPR(Opcode.ft, true); sprintf(Name, "_FPR_S[%d]", Opcode.ft); MoveVariableToX86reg(&_FPR_S[Opcode.ft], Name, TempReg2); MoveX86PointerToX86reg(TempReg2, TempReg2); AndConstToX86Reg(TempReg1, 0x1FFFFFFF); MoveX86regToN64Mem(TempReg2, TempReg1); } } void CMipsMemoryVM::Compile_SWL() { OPCODE & Opcode = CRecompilerOps::m_Opcode; x86Reg TempReg1 = x86_Unknown, TempReg2 = x86_Unknown, Value = x86_Unknown, shift = x86_Unknown, OffsetReg = x86_Unknown; CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(Opcode.Hex, m_CompilePC)); if (IsConst(Opcode.base)) { uint32_t Address; Address = GetMipsRegLo(Opcode.base) + (int16_t)Opcode.offset; uint32_t Offset = Address & 3; Value = Map_TempReg(x86_Any, -1, false); Compile_LW(Value, (Address & ~3)); AndConstToX86Reg(Value, R4300iOp::SWL_MASK[Offset]); TempReg1 = Map_TempReg(x86_Any, Opcode.rt, false); ShiftRightUnsignImmed(TempReg1, (uint8_t)SWL_SHIFT[Offset]); AddX86RegToX86Reg(Value, TempReg1); Compile_SW_Register(Value, (Address & ~3)); return; } shift = Map_TempReg(x86_ECX, -1, false); if (IsMapped(Opcode.base)) { ProtectGPR(Opcode.base); if (Opcode.offset != 0) { TempReg1 = Map_TempReg(x86_Any, -1, false); LeaSourceAndOffset(TempReg1, GetMipsRegMapLo(Opcode.base), (int16_t)Opcode.offset); } else { TempReg1 = Map_TempReg(x86_Any, Opcode.base, false); } UnProtectGPR(Opcode.base); } else { TempReg1 = Map_TempReg(x86_Any, Opcode.base, false); AddConstToX86Reg(TempReg1, (int16_t)Opcode.immediate); } if (g_System->bUseTlb()) { TempReg2 = Map_TempReg(x86_Any, -1, false); MoveX86RegToX86Reg(TempReg1, TempReg2); ShiftRightUnsignImmed(TempReg2, 12); MoveVariableDispToX86Reg(m_TLB_ReadMap, "m_TLB_ReadMap", TempReg2, TempReg2, 4); CompileReadTLBMiss(TempReg1, TempReg2); } OffsetReg = Map_TempReg(x86_Any, -1, false); MoveX86RegToX86Reg(TempReg1, OffsetReg); AndConstToX86Reg(OffsetReg, 3); AndConstToX86Reg(TempReg1, (uint32_t)~3); Value = Map_TempReg(x86_Any, -1, false); if (g_System->bUseTlb()) { MoveX86regPointerToX86reg(TempReg1, TempReg2, Value); } else { AndConstToX86Reg(TempReg1, 0x1FFFFFFF); MoveN64MemToX86reg(Value, TempReg1); } AndVariableDispToX86Reg((void *)SWL_MASK, "SWL_MASK", Value, OffsetReg, Multip_x4); if (!IsConst(Opcode.rt) || GetMipsRegLo(Opcode.rt) != 0) { MoveVariableDispToX86Reg((void *)SWL_SHIFT, "SWL_SHIFT", shift, OffsetReg, 4); if (IsConst(Opcode.rt)) { MoveConstToX86reg(GetMipsRegLo(Opcode.rt), OffsetReg); } else if (IsMapped(Opcode.rt)) { MoveX86RegToX86Reg(GetMipsRegMapLo(Opcode.rt), OffsetReg); } else { MoveVariableToX86reg(&_GPR[Opcode.rt].UW[0], CRegName::GPR_Lo[Opcode.rt], OffsetReg); } ShiftRightUnsign(OffsetReg); AddX86RegToX86Reg(Value, OffsetReg); } if (g_System->bUseTlb()) { MoveX86RegToX86Reg(TempReg1, TempReg2); ShiftRightUnsignImmed(TempReg2, 12); MoveVariableDispToX86Reg(m_TLB_WriteMap, "m_TLB_WriteMap", TempReg2, TempReg2, 4); MoveX86regToX86regPointer(Value, TempReg1, TempReg2); } else { MoveX86regToN64Mem(Value, TempReg1); } } void CMipsMemoryVM::Compile_SWR() { OPCODE & Opcode = CRecompilerOps::m_Opcode; x86Reg TempReg1 = x86_Unknown, TempReg2 = x86_Unknown, Value = x86_Unknown, OffsetReg = x86_Unknown, shift = x86_Unknown; CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(Opcode.Hex, m_CompilePC)); if (IsConst(Opcode.base)) { uint32_t Address = GetMipsRegLo(Opcode.base) + (int16_t)Opcode.offset; uint32_t Offset = Address & 3; Value = Map_TempReg(x86_Any, -1, false); Compile_LW(Value, (Address & ~3)); AndConstToX86Reg(Value, SWR_MASK[Offset]); TempReg1 = Map_TempReg(x86_Any, Opcode.rt, false); ShiftLeftSignImmed(TempReg1, (uint8_t)SWR_SHIFT[Offset]); AddX86RegToX86Reg(Value, TempReg1); Compile_SW_Register(Value, (Address & ~3)); return; } shift = Map_TempReg(x86_ECX, -1, false); if (IsMapped(Opcode.base)) { ProtectGPR(Opcode.base); if (Opcode.offset != 0) { TempReg1 = Map_TempReg(x86_Any, -1, false); LeaSourceAndOffset(TempReg1, GetMipsRegMapLo(Opcode.base), (int16_t)Opcode.offset); } else { TempReg1 = Map_TempReg(x86_Any, Opcode.base, false); } UnProtectGPR(Opcode.base); } else { TempReg1 = Map_TempReg(x86_Any, Opcode.base, false); AddConstToX86Reg(TempReg1, (int16_t)Opcode.immediate); } if (g_System->bUseTlb()) { TempReg2 = Map_TempReg(x86_Any, -1, false); MoveX86RegToX86Reg(TempReg1, TempReg2); ShiftRightUnsignImmed(TempReg2, 12); MoveVariableDispToX86Reg(m_TLB_ReadMap, "m_TLB_ReadMap", TempReg2, TempReg2, 4); CompileReadTLBMiss(TempReg1, TempReg2); } OffsetReg = Map_TempReg(x86_Any, -1, false); MoveX86RegToX86Reg(TempReg1, OffsetReg); AndConstToX86Reg(OffsetReg, 3); AndConstToX86Reg(TempReg1, (uint32_t)~3); Value = Map_TempReg(x86_Any, -1, false); if (g_System->bUseTlb()) { MoveX86regPointerToX86reg(TempReg1, TempReg2, Value); } else { AndConstToX86Reg(TempReg1, 0x1FFFFFFF); MoveN64MemToX86reg(Value, TempReg1); } AndVariableDispToX86Reg((void *)SWR_MASK, "SWR_MASK", Value, OffsetReg, Multip_x4); if (!IsConst(Opcode.rt) || GetMipsRegLo(Opcode.rt) != 0) { MoveVariableDispToX86Reg((void *)SWR_SHIFT, "SWR_SHIFT", shift, OffsetReg, 4); if (IsConst(Opcode.rt)) { MoveConstToX86reg(GetMipsRegLo(Opcode.rt), OffsetReg); } else if (IsMapped(Opcode.rt)) { MoveX86RegToX86Reg(GetMipsRegMapLo(Opcode.rt), OffsetReg); } else { MoveVariableToX86reg(&_GPR[Opcode.rt].UW[0], CRegName::GPR_Lo[Opcode.rt], OffsetReg); } ShiftLeftSign(OffsetReg); AddX86RegToX86Reg(Value, OffsetReg); } if (g_System->bUseTlb()) { MoveX86RegToX86Reg(TempReg1, TempReg2); ShiftRightUnsignImmed(TempReg2, 12); MoveVariableDispToX86Reg(m_TLB_WriteMap, "m_TLB_WriteMap", TempReg2, TempReg2, 4); MoveX86regToX86regPointer(Value, TempReg1, TempReg2); } else { MoveX86regToN64Mem(Value, TempReg1); } } void CMipsMemoryVM::Compile_StoreInstructClean(x86Reg AddressReg, int32_t Length) { if (!g_System->bSMM_StoreInstruc()) { return; } g_Notify->BreakPoint(__FILEW__, __LINE__); /* stdstr_f strLen("%d",Length); UnMap_AllFPRs(); /*x86Reg StoreTemp1 = Map_TempReg(x86_Any,-1,false); MoveX86RegToX86Reg(AddressReg, StoreTemp1); AndConstToX86Reg(StoreTemp1,0xFFC);*/ BeforeCallDirect(m_RegWorkingSet); PushImm32("CRecompiler::Remove_StoreInstruc", CRecompiler::Remove_StoreInstruc); PushImm32(Length); Push(AddressReg); MoveConstToX86reg((uint32_t)g_Recompiler, x86_ECX); Call_Direct(AddressOf(&CRecompiler::ClearRecompCode_Virt), "CRecompiler::ClearRecompCode_Virt"); AfterCallDirect(m_RegWorkingSet); /*JmpLabel8("MemCheckDone",0); uint8_t * MemCheckDone = m_RecompPos - 1; CPU_Message(" "); CPU_Message(" NotDelaySlot:"); SetJump8(NotDelaySlotJump,m_RecompPos); MoveX86RegToX86Reg(AddressReg, StoreTemp1); ShiftRightUnsignImmed(StoreTemp1,12); LeaRegReg(StoreTemp1,StoreTemp1,(ULONG)&(g_Recompiler->FunctionTable()[0]),Multip_x4); CompConstToX86regPointer(StoreTemp1,0); JeLabel8("MemCheckDone",0); uint8_t * MemCheckDone2 = m_RecompPos - 1; BeforeCallDirect(m_RegWorkingSet); PushImm32("CRecompiler::Remove_StoreInstruc",CRecompiler::Remove_StoreInstruc); PushImm32(strLen.c_str(),Length); Push(AddressReg); MoveConstToX86reg((uint32_t)g_Recompiler,x86_ECX); Call_Direct(AddressOf(&CRecompiler::ClearRecompCode_Virt), "CRecompiler::ClearRecompCode_Virt"); AfterCallDirect(m_RegWorkingSet); CPU_Message(" "); CPU_Message(" MemCheckDone:"); SetJump8(MemCheckDone,m_RecompPos); SetJump8(MemCheckDone2,m_RecompPos); X86Protected(StoreTemp1) = false;*/ } void CMipsMemoryVM::Compile_SD() { OPCODE & Opcode = CRecompilerOps::m_Opcode; x86Reg TempReg1, TempReg2; CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(Opcode.Hex, m_CompilePC)); if (IsConst(Opcode.base)) { uint32_t Address = GetMipsRegLo(Opcode.base) + (int16_t)Opcode.offset; if (IsConst(Opcode.rt)) { Compile_SW_Const(Is64Bit(Opcode.rt) ? GetMipsRegHi(Opcode.rt) : (GetMipsRegLo_S(Opcode.rt) >> 31), Address); Compile_SW_Const(GetMipsRegLo(Opcode.rt), Address + 4); } else if (IsMapped(Opcode.rt)) { Compile_SW_Register(Is64Bit(Opcode.rt) ? GetMipsRegMapHi(Opcode.rt) : Map_TempReg(x86_Any, Opcode.rt, true), Address); Compile_SW_Register(GetMipsRegMapLo(Opcode.rt), Address + 4); } else { TempReg1 = Map_TempReg(x86_Any, Opcode.rt, true); Compile_SW_Register(TempReg1, Address); Compile_SW_Register(Map_TempReg(TempReg1, Opcode.rt, false), Address + 4); } } else { if (IsMapped(Opcode.rt)) { ProtectGPR(Opcode.rt); } if (IsMapped(Opcode.base)) { ProtectGPR(Opcode.base); if (Opcode.offset != 0) { TempReg1 = Map_TempReg(x86_Any, -1, false); LeaSourceAndOffset(TempReg1, GetMipsRegMapLo(Opcode.base), (int16_t)Opcode.offset); } else { TempReg1 = Map_TempReg(x86_Any, Opcode.base, false); } UnProtectGPR(Opcode.base); } else { TempReg1 = Map_TempReg(x86_Any, Opcode.base, false); AddConstToX86Reg(TempReg1, (int16_t)Opcode.immediate); } Compile_StoreInstructClean(TempReg1, 8); if (g_System->bUseTlb()) { TempReg2 = Map_TempReg(x86_Any, -1, false); MoveX86RegToX86Reg(TempReg1, TempReg2); ShiftRightUnsignImmed(TempReg2, 12); MoveVariableDispToX86Reg(m_TLB_WriteMap, "m_TLB_WriteMap", TempReg2, TempReg2, 4); CompileWriteTLBMiss(TempReg1, TempReg2); if (IsConst(Opcode.rt)) { if (Is64Bit(Opcode.rt)) { MoveConstToX86regPointer(GetMipsRegHi(Opcode.rt), TempReg1, TempReg2); } else { MoveConstToX86regPointer((GetMipsRegLo_S(Opcode.rt) >> 31), TempReg1, TempReg2); } AddConstToX86Reg(TempReg1, 4); MoveConstToX86regPointer(GetMipsRegLo(Opcode.rt), TempReg1, TempReg2); } else if (IsMapped(Opcode.rt)) { if (Is64Bit(Opcode.rt)) { MoveX86regToX86regPointer(GetMipsRegMapHi(Opcode.rt), TempReg1, TempReg2); } else { MoveX86regToX86regPointer(Map_TempReg(x86_Any, Opcode.rt, true), TempReg1, TempReg2); } AddConstToX86Reg(TempReg1, 4); MoveX86regToX86regPointer(GetMipsRegMapLo(Opcode.rt), TempReg1, TempReg2); } else { x86Reg Reg = Map_TempReg(x86_Any, Opcode.rt, true); MoveX86regToX86regPointer(Reg, TempReg1, TempReg2); AddConstToX86Reg(TempReg1, 4); MoveX86regToX86regPointer(Map_TempReg(Reg, Opcode.rt, false), TempReg1, TempReg2); } } else { AndConstToX86Reg(TempReg1, 0x1FFFFFFF); if (IsConst(Opcode.rt)) { if (Is64Bit(Opcode.rt)) { MoveConstToN64Mem(GetMipsRegHi(Opcode.rt), TempReg1); } else if (IsSigned(Opcode.rt)) { MoveConstToN64Mem((GetMipsRegLo_S(Opcode.rt) >> 31), TempReg1); } else { MoveConstToN64Mem(0, TempReg1); } MoveConstToN64MemDisp(GetMipsRegLo(Opcode.rt), TempReg1, 4); } else if (IsKnown(Opcode.rt) && IsMapped(Opcode.rt)) { if (Is64Bit(Opcode.rt)) { MoveX86regToN64Mem(GetMipsRegMapHi(Opcode.rt), TempReg1); } else if (IsSigned(Opcode.rt)) { MoveX86regToN64Mem(Map_TempReg(x86_Any, Opcode.rt, true), TempReg1); } else { MoveConstToN64Mem(0, TempReg1); } MoveX86regToN64MemDisp(GetMipsRegMapLo(Opcode.rt), TempReg1, 4); } else { x86Reg Reg; MoveX86regToN64Mem(Reg = Map_TempReg(x86_Any, Opcode.rt, true), TempReg1); MoveX86regToN64MemDisp(Map_TempReg(Reg, Opcode.rt, false), TempReg1, 4); } } } } void CMipsMemoryVM::Compile_SDC1() { OPCODE & Opcode = CRecompilerOps::m_Opcode; x86Reg TempReg1, TempReg2, TempReg3; char Name[50]; CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(Opcode.Hex, m_CompilePC)); m_Section->CompileCop1Test(); if (IsConst(Opcode.base)) { uint32_t Address = GetMipsRegLo(Opcode.base) + (int16_t)Opcode.offset; TempReg1 = Map_TempReg(x86_Any, -1, false); sprintf(Name, "_FPR_D[%d]", Opcode.ft); MoveVariableToX86reg((uint8_t *)&_FPR_D[Opcode.ft], Name, TempReg1); AddConstToX86Reg(TempReg1, 4); MoveX86PointerToX86reg(TempReg1, TempReg1); Compile_SW_Register(TempReg1, Address); sprintf(Name, "_FPR_D[%d]", Opcode.ft); MoveVariableToX86reg(&_FPR_D[Opcode.ft], Name, TempReg1); MoveX86PointerToX86reg(TempReg1, TempReg1); Compile_SW_Register(TempReg1, Address + 4); return; } if (IsMapped(Opcode.base)) { ProtectGPR(Opcode.base); if (Opcode.offset != 0) { TempReg1 = Map_TempReg(x86_Any, -1, false); LeaSourceAndOffset(TempReg1, GetMipsRegMapLo(Opcode.base), (int16_t)Opcode.offset); } else { TempReg1 = Map_TempReg(x86_Any, Opcode.base, false); } } else { TempReg1 = Map_TempReg(x86_Any, Opcode.base, false); if (Opcode.immediate == 0) { } else if (Opcode.immediate == 1) { IncX86reg(TempReg1); } else if (Opcode.immediate == 0xFFFF) { DecX86reg(TempReg1); } else { AddConstToX86Reg(TempReg1, (int16_t)Opcode.immediate); } } if (g_System->bUseTlb()) { TempReg2 = Map_TempReg(x86_Any, -1, false); MoveX86RegToX86Reg(TempReg1, TempReg2); ShiftRightUnsignImmed(TempReg2, 12); MoveVariableDispToX86Reg(m_TLB_WriteMap, "m_TLB_WriteMap", TempReg2, TempReg2, 4); CompileWriteTLBMiss(TempReg1, TempReg2); TempReg3 = Map_TempReg(x86_Any, -1, false); sprintf(Name, "_FPR_D[%d]", Opcode.ft); MoveVariableToX86reg((uint8_t *)&_FPR_D[Opcode.ft], Name, TempReg3); AddConstToX86Reg(TempReg3, 4); MoveX86PointerToX86reg(TempReg3, TempReg3); MoveX86regToX86regPointer(TempReg3, TempReg1, TempReg2); AddConstToX86Reg(TempReg1, 4); sprintf(Name, "_FPR_D[%d]", Opcode.ft); MoveVariableToX86reg((uint8_t *)&_FPR_D[Opcode.ft], Name, TempReg3); MoveX86PointerToX86reg(TempReg3, TempReg3); MoveX86regToX86regPointer(TempReg3, TempReg1, TempReg2); } else { AndConstToX86Reg(TempReg1, 0x1FFFFFFF); TempReg3 = Map_TempReg(x86_Any, -1, false); sprintf(Name, "_FPR_D[%d]", Opcode.ft); MoveVariableToX86reg((uint8_t *)&_FPR_D[Opcode.ft], Name, TempReg3); AddConstToX86Reg(TempReg3, 4); MoveX86PointerToX86reg(TempReg3, TempReg3); MoveX86regToN64Mem(TempReg3, TempReg1); sprintf(Name, "_FPR_D[%d]", Opcode.ft); MoveVariableToX86reg((uint8_t *)&_FPR_D[Opcode.ft], Name, TempReg3); MoveX86PointerToX86reg(TempReg3, TempReg3); MoveX86regToN64MemDisp(TempReg3, TempReg1, 4); } } void CMipsMemoryVM::Compile_SDL() { OPCODE & Opcode = CRecompilerOps::m_Opcode; CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(Opcode.Hex, m_CompilePC)); if (Opcode.base != 0) { UnMap_GPR(Opcode.base, true); } if (Opcode.rt != 0) { UnMap_GPR(Opcode.rt, true); } BeforeCallDirect(m_RegWorkingSet); MoveConstToVariable(Opcode.Hex, &R4300iOp::m_Opcode.Hex, "R4300iOp::m_Opcode.Hex"); Call_Direct(R4300iOp::SDL, "R4300iOp::SDL"); AfterCallDirect(m_RegWorkingSet); } void CMipsMemoryVM::Compile_SDR() { OPCODE & Opcode = CRecompilerOps::m_Opcode; CPU_Message(" %X %s", m_CompilePC, R4300iOpcodeName(Opcode.Hex, m_CompilePC)); if (Opcode.base != 0) { UnMap_GPR(Opcode.base, true); } if (Opcode.rt != 0) { UnMap_GPR(Opcode.rt, true); } BeforeCallDirect(m_RegWorkingSet); MoveConstToVariable(Opcode.Hex, &R4300iOp::m_Opcode.Hex, "R4300iOp::m_Opcode.Hex"); Call_Direct(R4300iOp::SDR, "R4300iOp::SDR"); AfterCallDirect(m_RegWorkingSet); } LPCTSTR CMipsMemoryVM::LabelName(uint32_t Address) const { //StringMap::iterator theIterator = m_LabelList.find(Address); //if (theIterator != m_LabelList.end()) //{ // return (*theIterator).second; //} sprintf(m_strLabelName, "0x%08X", Address); return m_strLabelName; } void CMipsMemoryVM::TLB_Mapped(uint32_t VAddr, uint32_t Len, uint32_t PAddr, bool bReadOnly) { size_t count, VEnd; VEnd = VAddr + Len; for (count = VAddr; count < VEnd; count += 0x1000) { size_t Index = count >> 12; m_TLB_ReadMap[Index] = ((size_t)m_RDRAM + (count - VAddr + PAddr)) - count; if (!bReadOnly) { m_TLB_WriteMap[Index] = ((size_t)m_RDRAM + (count - VAddr + PAddr)) - count; } } } void CMipsMemoryVM::TLB_Unmaped(uint32_t Vaddr, uint32_t Len) { size_t count, End; End = Vaddr + Len; for (count = Vaddr; count < End; count += 0x1000) { size_t Index = count >> 12; m_TLB_ReadMap[Index] = NULL; m_TLB_WriteMap[Index] = NULL; } } void CMipsMemoryVM::RdramChanged(CMipsMemoryVM * _this) { const size_t new_size = g_Settings->LoadDword(Game_RDRamSize); const size_t old_size = _this->m_AllocatedRdramSize; if (old_size == new_size) { return; } if (old_size > new_size) { VirtualFree( _this->m_RDRAM + new_size, old_size - new_size, MEM_DECOMMIT ); } else { void * result; result = VirtualAlloc( _this->m_RDRAM + old_size, new_size - old_size, MEM_COMMIT, PAGE_READWRITE ); if (result == NULL) { WriteTrace(TraceError, __FUNCTION__": failed to allocate extended memory"); g_Notify->FatalError(GS(MSG_MEM_ALLOC_ERROR)); } } if (new_size > 0xFFFFFFFFul) { // should be unreachable because: size_t new_size = g_Settings->(uint32_t) g_Notify->BreakPoint(__FILEW__, __LINE__); } // ...However, FFFFFFFF also is a limit to RCP addressing, so we care. _this->m_AllocatedRdramSize = (uint32_t)new_size; } void CMipsMemoryVM::ChangeSpStatus() { if ((RegModValue & SP_CLR_HALT) != 0) { g_Reg->SP_STATUS_REG &= ~SP_STATUS_HALT; } if ((RegModValue & SP_SET_HALT) != 0) { g_Reg->SP_STATUS_REG |= SP_STATUS_HALT; } if ((RegModValue & SP_CLR_BROKE) != 0) { g_Reg->SP_STATUS_REG &= ~SP_STATUS_BROKE; } if ((RegModValue & SP_CLR_INTR) != 0) { g_Reg->MI_INTR_REG &= ~MI_INTR_SP; g_Reg->m_RspIntrReg &= ~MI_INTR_SP; g_Reg->CheckInterrupts(); } if ((RegModValue & SP_SET_INTR) != 0 && bHaveDebugger()) { g_Notify->DisplayError(L"SP_SET_INTR"); } if ((RegModValue & SP_CLR_SSTEP) != 0) { g_Reg->SP_STATUS_REG &= ~SP_STATUS_SSTEP; } if ((RegModValue & SP_SET_SSTEP) != 0) { g_Reg->SP_STATUS_REG |= SP_STATUS_SSTEP; } if ((RegModValue & SP_CLR_INTR_BREAK) != 0) { g_Reg->SP_STATUS_REG &= ~SP_STATUS_INTR_BREAK; } if ((RegModValue & SP_SET_INTR_BREAK) != 0) { g_Reg->SP_STATUS_REG |= SP_STATUS_INTR_BREAK; } if ((RegModValue & SP_CLR_SIG0) != 0) { g_Reg->SP_STATUS_REG &= ~SP_STATUS_SIG0; } if ((RegModValue & SP_SET_SIG0) != 0) { g_Reg->SP_STATUS_REG |= SP_STATUS_SIG0; } if ((RegModValue & SP_CLR_SIG1) != 0) { g_Reg->SP_STATUS_REG &= ~SP_STATUS_SIG1; } if ((RegModValue & SP_SET_SIG1) != 0) { g_Reg->SP_STATUS_REG |= SP_STATUS_SIG1; } if ((RegModValue & SP_CLR_SIG2) != 0) { g_Reg->SP_STATUS_REG &= ~SP_STATUS_SIG2; } if ((RegModValue & SP_SET_SIG2) != 0) { g_Reg->SP_STATUS_REG |= SP_STATUS_SIG2; } if ((RegModValue & SP_CLR_SIG3) != 0) { g_Reg->SP_STATUS_REG &= ~SP_STATUS_SIG3; } if ((RegModValue & SP_SET_SIG3) != 0) { g_Reg->SP_STATUS_REG |= SP_STATUS_SIG3; } if ((RegModValue & SP_CLR_SIG4) != 0) { g_Reg->SP_STATUS_REG &= ~SP_STATUS_SIG4; } if ((RegModValue & SP_SET_SIG4) != 0) { g_Reg->SP_STATUS_REG |= SP_STATUS_SIG4; } if ((RegModValue & SP_CLR_SIG5) != 0) { g_Reg->SP_STATUS_REG &= ~SP_STATUS_SIG5; } if ((RegModValue & SP_SET_SIG5) != 0) { g_Reg->SP_STATUS_REG |= SP_STATUS_SIG5; } if ((RegModValue & SP_CLR_SIG6) != 0) { g_Reg->SP_STATUS_REG &= ~SP_STATUS_SIG6; } if ((RegModValue & SP_SET_SIG6) != 0) { g_Reg->SP_STATUS_REG |= SP_STATUS_SIG6; } if ((RegModValue & SP_CLR_SIG7) != 0) { g_Reg->SP_STATUS_REG &= ~SP_STATUS_SIG7; } if ((RegModValue & SP_SET_SIG7) != 0) { g_Reg->SP_STATUS_REG |= SP_STATUS_SIG7; } if ((RegModValue & SP_SET_SIG0) != 0 && g_System->RspAudioSignal()) { g_Reg->MI_INTR_REG |= MI_INTR_SP; g_Reg->CheckInterrupts(); } //if (*( uint32_t *)(DMEM + 0xFC0) == 1) //{ // ChangeTimer(RspTimer,0x40000); //} //else //{ try { g_System->RunRSP(); } catch (...) { g_Notify->BreakPoint(__FILEW__, __LINE__); } //} } void CMipsMemoryVM::ChangeMiIntrMask() { if ((RegModValue & MI_INTR_MASK_CLR_SP) != 0) { g_Reg->MI_INTR_MASK_REG &= ~MI_INTR_MASK_SP; } if ((RegModValue & MI_INTR_MASK_SET_SP) != 0) { g_Reg->MI_INTR_MASK_REG |= MI_INTR_MASK_SP; } if ((RegModValue & MI_INTR_MASK_CLR_SI) != 0) { g_Reg->MI_INTR_MASK_REG &= ~MI_INTR_MASK_SI; } if ((RegModValue & MI_INTR_MASK_SET_SI) != 0) { g_Reg->MI_INTR_MASK_REG |= MI_INTR_MASK_SI; } if ((RegModValue & MI_INTR_MASK_CLR_AI) != 0) { g_Reg->MI_INTR_MASK_REG &= ~MI_INTR_MASK_AI; } if ((RegModValue & MI_INTR_MASK_SET_AI) != 0) { g_Reg->MI_INTR_MASK_REG |= MI_INTR_MASK_AI; } if ((RegModValue & MI_INTR_MASK_CLR_VI) != 0) { g_Reg->MI_INTR_MASK_REG &= ~MI_INTR_MASK_VI; } if ((RegModValue & MI_INTR_MASK_SET_VI) != 0) { g_Reg->MI_INTR_MASK_REG |= MI_INTR_MASK_VI; } if ((RegModValue & MI_INTR_MASK_CLR_PI) != 0) { g_Reg->MI_INTR_MASK_REG &= ~MI_INTR_MASK_PI; } if ((RegModValue & MI_INTR_MASK_SET_PI) != 0) { g_Reg->MI_INTR_MASK_REG |= MI_INTR_MASK_PI; } if ((RegModValue & MI_INTR_MASK_CLR_DP) != 0) { g_Reg->MI_INTR_MASK_REG &= ~MI_INTR_MASK_DP; } if ((RegModValue & MI_INTR_MASK_SET_DP) != 0) { g_Reg->MI_INTR_MASK_REG |= MI_INTR_MASK_DP; } }