/**************************************************************************** * * * 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" #include #include #include #include #include #include #include #include #include #include uint8_t * CMipsMemoryVM::m_Reserve1 = NULL; uint8_t * CMipsMemoryVM::m_Reserve2 = NULL; uint32_t CMipsMemoryVM::m_MemLookupAddress = 0; MIPS_DWORD CMipsMemoryVM::m_MemLookupValue; bool CMipsMemoryVM::m_MemLookupValid = true; uint32_t CMipsMemoryVM::RegModValue; #pragma warning(disable:4355) // Disable 'this' : used in base member initializer list CMipsMemoryVM::CMipsMemoryVM(bool SavesReadOnly) : CPifRam(SavesReadOnly), CFlashram(SavesReadOnly), CSram(SavesReadOnly), CDMA(*this, *this), 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_TLB_ReadMap(NULL), m_TLB_WriteMap(NULL), m_RDRAM(NULL), m_DMEM(NULL), m_IMEM(NULL), m_DDRomMapped(false), m_DDRom(NULL), m_DDRomSize(0) { g_Settings->RegisterChangeCB(Game_RDRamSize, this, (CSettings::SettingChangedFunc)RdramChanged); } 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 *)AllocateAddressSpace(0x20000000, (void *)g_Settings->LoadDword(Setting_FixedRdramAddress)); m_Reserve2 = (uint8_t *)AllocateAddressSpace(0x04002000); } void CMipsMemoryVM::FreeReservedMemory() { if (m_Reserve1) { FreeAddressSpace(m_Reserve1, 0x20000000); m_Reserve1 = NULL; } if (m_Reserve2) { FreeAddressSpace(m_Reserve2, 0x20000000); m_Reserve2 = NULL; } } bool CMipsMemoryVM::Initialize(bool SyncSystem) { if (m_RDRAM != NULL) { return true; } if (!SyncSystem && m_RDRAM == NULL && m_Reserve1 != NULL) { m_RDRAM = m_Reserve1; m_Reserve1 = NULL; } if (SyncSystem && m_RDRAM == NULL && m_Reserve2 != NULL) { m_RDRAM = m_Reserve2; m_Reserve2 = NULL; } if (m_RDRAM == NULL) { m_RDRAM = (uint8_t *)AllocateAddressSpace(0x20000000); } if (m_RDRAM == NULL) { WriteTrace(TraceN64System, TraceError, "Failed to Reserve RDRAM (Size: 0x%X)", 0x20000000); FreeMemory(); return false; } m_AllocatedRdramSize = g_Settings->LoadDword(Game_RDRamSize); if (CommitMemory(m_RDRAM, m_AllocatedRdramSize, MEM_READWRITE) == NULL) { WriteTrace(TraceN64System, TraceError, "Failed to Allocate RDRAM (Size: 0x%X)", m_AllocatedRdramSize); FreeMemory(); return false; } if (CommitMemory(m_RDRAM + 0x04000000, 0x2000, MEM_READWRITE) == NULL) { WriteTrace(TraceN64System, TraceError, "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 (CommitMemory(m_Rom, g_Rom->GetRomSize(), MEM_READWRITE) == NULL) { WriteTrace(TraceN64System, TraceError, "Failed to Allocate Rom (Size: 0x%X)", g_Rom->GetRomSize()); FreeMemory(); return false; } memcpy(m_Rom, g_Rom->GetRomAddress(), g_Rom->GetRomSize()); ::ProtectMemory(m_Rom, g_Rom->GetRomSize(), MEM_READONLY); } else { m_RomMapped = false; m_Rom = g_Rom->GetRomAddress(); m_RomSize = g_Rom->GetRomSize(); } //64DD IPL if (g_DDRom != NULL) { if (g_Settings->LoadBool(Game_LoadRomToMemory)) { m_DDRomMapped = true; m_DDRom = m_RDRAM + 0x06000000; m_DDRomSize = g_DDRom->GetRomSize(); if (CommitMemory(m_DDRom, g_DDRom->GetRomSize(), MEM_READWRITE) == NULL) { WriteTrace(TraceN64System, TraceError, "Failed to Allocate Rom (Size: 0x%X)", g_DDRom->GetRomSize()); FreeMemory(); return false; } memcpy(m_DDRom, g_DDRom->GetRomAddress(), g_DDRom->GetRomSize()); ::ProtectMemory(m_DDRom, g_DDRom->GetRomSize(), MEM_READONLY); } else { m_DDRomMapped = false; m_DDRom = g_DDRom->GetRomAddress(); m_DDRomSize = g_DDRom->GetRomSize(); } } CPifRam::Reset(); m_TLB_ReadMap = new size_t[0x100000]; if (m_TLB_ReadMap == NULL) { WriteTrace(TraceN64System, TraceError, "Failed to Allocate m_TLB_ReadMap (Size: 0x%X)", 0x100000 * sizeof(size_t)); FreeMemory(); return false; } m_TLB_WriteMap = new size_t[0x100000]; if (m_TLB_WriteMap == NULL) { WriteTrace(TraceN64System, TraceError, "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 (DecommitMemory(m_RDRAM, 0x20000000)) { if (m_Reserve1 == NULL) { m_Reserve1 = m_RDRAM; } else if (m_Reserve2 == NULL) { m_Reserve2 = m_RDRAM; } else { FreeAddressSpace(m_RDRAM, 0x20000000); } } else { FreeAddressSpace(m_RDRAM, 0x20000000); } m_RDRAM = NULL; m_IMEM = NULL; m_DMEM = NULL; } if (m_TLB_ReadMap) { delete[] m_TLB_ReadMap; m_TLB_ReadMap = NULL; } if (m_TLB_WriteMap) { delete[] m_TLB_WriteMap; 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; } CSram* CMipsMemoryVM::GetSram(void) { return dynamic_cast(this); } CFlashram* CMipsMemoryVM::GetFlashram() { return dynamic_cast(this); } 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 & 0xFFFFE000ul) != 0xA4000000ul) // !(A4000000 <= addr < A4002000) { 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(__FILE__, __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(__FILE__, __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(__FILE__, __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(__FILE__, __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(__FILE__, __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 & 0xFFFFE000ul) != 0xA4000000ul) // !(A4000000 <= addr < A4002000) { 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(__FILE__, __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(__FILE__, __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(__FILE__, __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(__FILE__, __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; } 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(__FILE__, __LINE__); #ifdef legacycode 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(__FILE__, __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 m_MemLookupAddress = PAddr; if (PAddr >= 0x10000000 && PAddr < 0x16000000) { Load32Rom(); } else { switch (PAddr & 0xFFF00000) { case 0x03F00000: Load32RDRAMRegisters(); break; case 0x04000000: Load32SPRegisters(); break; case 0x04100000: Load32DPCommand(); break; case 0x04300000: Load32MIPSInterface(); break; case 0x04400000: Load32VideoInterface(); break; case 0x04500000: Load32AudioInterface(); break; case 0x04600000: Load32PeripheralInterface(); break; case 0x04700000: Load32RDRAMInterface(); break; case 0x04800000: Load32SerialInterface(); break; case 0x05000000: Load32CartridgeDomain2Address1(); break; case 0x06000000: Load32CartridgeDomain1Address1(); break; case 0x08000000: Load32CartridgeDomain2Address2(); break; case 0x1FC00000: Load32PifRam(); break; case 0x1FF00000: Load32CartridgeDomain1Address3(); break; default: m_MemLookupValue.UW[0] = PAddr & 0xFFFF; m_MemLookupValue.UW[0] = (m_MemLookupValue.UW[0] << 16) | m_MemLookupValue.UW[0]; } } *Value = m_MemLookupValue.UW[0]; 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("FrameBufferWrite"); if (FrameBufferWrite) { FrameBufferWrite(PAddr, 1); } break; } #endif if (PAddr < RdramSize()) { g_Recompiler->ClearRecompCode_Phys(PAddr & ~0xFFF, 0xFFC, CRecompiler::Remove_ProtectedMem); ::ProtectMemory(m_RDRAM + (PAddr & ~0xFFF), 0xFFC, MEM_READWRITE); *(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("PAddr = %x", PAddr); break; } #endif if (PAddr < RdramSize()) { g_Recompiler->ClearRecompCode_Phys(PAddr & ~0xFFF, 0x1000, CRecompiler::Remove_ProtectedMem); ::ProtectMemory(m_RDRAM + (PAddr & ~0xFFF), 0xFFC, MEM_READWRITE); *(uint16_t *)(m_RDRAM + PAddr) = Value; } break; default: return false; } return true; } bool CMipsMemoryVM::SW_NonMemory(uint32_t PAddr, uint32_t Value) { m_MemLookupValue.UW[0] = Value; m_MemLookupAddress = PAddr; 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("FrameBufferWrite %X", PAddr); if (FrameBufferWrite) { FrameBufferWrite(PAddr, 4); } break; } #endif if (PAddr < RdramSize()) { g_Recompiler->ClearRecompCode_Phys(PAddr & ~0xFFF, 0x1000, CRecompiler::Remove_ProtectedMem); ::ProtectMemory(m_RDRAM + (PAddr & ~0xFFF), 0xFFC, MEM_READWRITE); *(uint32_t *)(m_RDRAM + PAddr) = Value; } break; case 0x03F00000: Write32RDRAMRegisters(); break; case 0x04000000: if (PAddr < 0x04002000) { g_Recompiler->ClearRecompCode_Phys(PAddr & ~0xFFF, 0xFFF, CRecompiler::Remove_ProtectedMem); *(uint32_t *)(m_RDRAM + PAddr) = Value; } else { Write32SPRegisters(); } break; case 0x04100000: Write32DPCommandRegisters(); break; case 0x04300000: Write32MIPSInterface(); break; case 0x04400000: Write32VideoInterface(); break; case 0x04500000: Write32AudioInterface(); break; case 0x04600000: Write32PeripheralInterface(); break; case 0x04700000: Write32RDRAMInterface(); break; case 0x04800000: Write32SerialInterface(); break; case 0x05000000: Write32CartridgeDomain2Address1(); break; case 0x08000000: Write32CartridgeDomain2Address2(); break; case 0x1FC00000: Write32PifRam(); 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) { WriteTrace(TraceProtectedMem, TraceDebug, "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(__FILE__, __LINE__); } if (!TranslateVaddr(EndVaddr, EndPAddr)) { g_Notify->BreakPoint(__FILE__, __LINE__); } //Get Length of memory being protected int32_t Length = ((EndPAddr + 3) - StartPAddr) & ~3; if (Length < 0) { g_Notify->BreakPoint(__FILE__, __LINE__); } //Protect that memory address space uint8_t * MemLoc = Rdram() + StartPAddr; WriteTrace(TraceProtectedMem, TraceDebug, "Paddr: %08X Length: %X", StartPAddr, Length); ::ProtectMemory(MemLoc, Length, MEM_READONLY); } void CMipsMemoryVM::UnProtectMemory(uint32_t StartVaddr, uint32_t EndVaddr) { WriteTrace(TraceProtectedMem, TraceDebug, "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(__FILE__, __LINE__); } if (!TranslateVaddr(EndVaddr, EndPAddr)) { g_Notify->BreakPoint(__FILE__, __LINE__); } //Get Length of memory being protected int32_t Length = ((EndPAddr + 3) - StartPAddr) & ~3; if (Length < 0) { g_Notify->BreakPoint(__FILE__, __LINE__); } //Protect that memory address space uint8_t * MemLoc = Rdram() + StartPAddr; ::ProtectMemory(MemLoc, Length, MEM_READWRITE); } const char * 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] = 0; m_TLB_WriteMap[Index] = 0; } } 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) { DecommitMemory(_this->m_RDRAM + new_size, old_size - new_size); } else { void * result = CommitMemory(_this->m_RDRAM + old_size, new_size - old_size, MEM_READWRITE); if (result == NULL) { WriteTrace(TraceN64System, TraceError, "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(__FILE__, __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 && HaveDebugger()) { g_Notify->DisplayError("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(__FILE__, __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; } } void CMipsMemoryVM::Load32RDRAMRegisters(void) { switch (m_MemLookupAddress & 0x1FFFFFFF) { case 0x03F00000: m_MemLookupValue.UW[0] = g_Reg->RDRAM_CONFIG_REG; break; case 0x03F00004: m_MemLookupValue.UW[0] = g_Reg->RDRAM_DEVICE_ID_REG; break; case 0x03F00008: m_MemLookupValue.UW[0] = g_Reg->RDRAM_DELAY_REG; break; case 0x03F0000C: m_MemLookupValue.UW[0] = g_Reg->RDRAM_MODE_REG; break; case 0x03F00010: m_MemLookupValue.UW[0] = g_Reg->RDRAM_REF_INTERVAL_REG; break; case 0x03F00014: m_MemLookupValue.UW[0] = g_Reg->RDRAM_REF_ROW_REG; break; case 0x03F00018: m_MemLookupValue.UW[0] = g_Reg->RDRAM_RAS_INTERVAL_REG; break; case 0x03F0001C: m_MemLookupValue.UW[0] = g_Reg->RDRAM_MIN_INTERVAL_REG; break; case 0x03F00020: m_MemLookupValue.UW[0] = g_Reg->RDRAM_ADDR_SELECT_REG; break; case 0x03F00024: m_MemLookupValue.UW[0] = g_Reg->RDRAM_DEVICE_MANUF_REG; break; default: m_MemLookupValue.UW[0] = 0; if (HaveDebugger()) { g_Notify->BreakPoint(__FILE__, __LINE__); } } m_MemLookupValid = true; } void CMipsMemoryVM::Load32SPRegisters(void) { switch (m_MemLookupAddress & 0x1FFFFFFF) { case 0x04040010: m_MemLookupValue.UW[0] = g_Reg->SP_STATUS_REG; break; case 0x04040014: m_MemLookupValue.UW[0] = g_Reg->SP_DMA_FULL_REG; break; case 0x04040018: m_MemLookupValue.UW[0] = g_Reg->SP_DMA_BUSY_REG; break; case 0x0404001C: m_MemLookupValue.UW[0] = g_Reg->SP_SEMAPHORE_REG; g_Reg->SP_SEMAPHORE_REG = 1; break; case 0x04080000: m_MemLookupValue.UW[0] = g_Reg->SP_PC_REG; break; default: m_MemLookupValue.UW[0] = 0; if (HaveDebugger()) { g_Notify->BreakPoint(__FILE__, __LINE__); } } } void CMipsMemoryVM::Load32DPCommand(void) { switch (m_MemLookupAddress & 0x1FFFFFFF) { case 0x0410000C: m_MemLookupValue.UW[0] = g_Reg->DPC_STATUS_REG; break; case 0x04100010: m_MemLookupValue.UW[0] = g_Reg->DPC_CLOCK_REG; break; case 0x04100014: m_MemLookupValue.UW[0] = g_Reg->DPC_BUFBUSY_REG; break; case 0x04100018: m_MemLookupValue.UW[0] = g_Reg->DPC_PIPEBUSY_REG; break; case 0x0410001C: m_MemLookupValue.UW[0] = g_Reg->DPC_TMEM_REG; break; default: m_MemLookupValue.UW[0] = 0; if (HaveDebugger()) { g_Notify->BreakPoint(__FILE__, __LINE__); } } } void CMipsMemoryVM::Load32MIPSInterface(void) { switch (m_MemLookupAddress & 0x1FFFFFFF) { case 0x04300000: m_MemLookupValue.UW[0] = g_Reg->MI_MODE_REG; break; case 0x04300004: m_MemLookupValue.UW[0] = g_Reg->MI_VERSION_REG; break; case 0x04300008: m_MemLookupValue.UW[0] = g_Reg->MI_INTR_REG; break; case 0x0430000C: m_MemLookupValue.UW[0] = g_Reg->MI_INTR_MASK_REG; break; default: m_MemLookupValue.UW[0] = 0; if (HaveDebugger()) { g_Notify->BreakPoint(__FILE__, __LINE__); } } } void CMipsMemoryVM::Load32VideoInterface(void) { switch (m_MemLookupAddress & 0x1FFFFFFF) { case 0x04400000: m_MemLookupValue.UW[0] = g_Reg->VI_STATUS_REG; break; case 0x04400004: m_MemLookupValue.UW[0] = g_Reg->VI_ORIGIN_REG; break; case 0x04400008: m_MemLookupValue.UW[0] = g_Reg->VI_WIDTH_REG; break; case 0x0440000C: m_MemLookupValue.UW[0] = g_Reg->VI_INTR_REG; break; case 0x04400010: g_MMU->UpdateHalfLine(); m_MemLookupValue.UW[0] = g_MMU->m_HalfLine; break; case 0x04400014: m_MemLookupValue.UW[0] = g_Reg->VI_BURST_REG; break; case 0x04400018: m_MemLookupValue.UW[0] = g_Reg->VI_V_SYNC_REG; break; case 0x0440001C: m_MemLookupValue.UW[0] = g_Reg->VI_H_SYNC_REG; break; case 0x04400020: m_MemLookupValue.UW[0] = g_Reg->VI_LEAP_REG; break; case 0x04400024: m_MemLookupValue.UW[0] = g_Reg->VI_H_START_REG; break; case 0x04400028: m_MemLookupValue.UW[0] = g_Reg->VI_V_START_REG; break; case 0x0440002C: m_MemLookupValue.UW[0] = g_Reg->VI_V_BURST_REG; break; case 0x04400030: m_MemLookupValue.UW[0] = g_Reg->VI_X_SCALE_REG; break; case 0x04400034: m_MemLookupValue.UW[0] = g_Reg->VI_Y_SCALE_REG; break; default: m_MemLookupValue.UW[0] = 0; if (HaveDebugger()) { g_Notify->BreakPoint(__FILE__, __LINE__); } } } void CMipsMemoryVM::Load32AudioInterface(void) { switch (m_MemLookupAddress & 0x1FFFFFFF) { case 0x04500004: if (g_System->bFixedAudio()) { m_MemLookupValue.UW[0] = g_Audio->GetLength(); } else { if (g_Plugins->Audio()->AiReadLength != NULL) { m_MemLookupValue.UW[0] = g_Plugins->Audio()->AiReadLength(); } else { m_MemLookupValue.UW[0] = 0; } } break; case 0x0450000C: if (g_System->bFixedAudio()) { m_MemLookupValue.UW[0] = g_Audio->GetStatus(); } else { m_MemLookupValue.UW[0] = g_Reg->AI_STATUS_REG; } break; default: m_MemLookupValue.UW[0] = 0; if (HaveDebugger()) { g_Notify->BreakPoint(__FILE__, __LINE__); } } } void CMipsMemoryVM::Load32PeripheralInterface(void) { switch (m_MemLookupAddress & 0x1FFFFFFF) { case 0x04600000: m_MemLookupValue.UW[0] = g_Reg->PI_DRAM_ADDR_REG; break; case 0x04600004: m_MemLookupValue.UW[0] = g_Reg->PI_CART_ADDR_REG; break; case 0x04600008: m_MemLookupValue.UW[0] = g_Reg->PI_RD_LEN_REG; break; case 0x0460000C: m_MemLookupValue.UW[0] = g_Reg->PI_WR_LEN_REG; break; case 0x04600010: m_MemLookupValue.UW[0] = g_Reg->PI_STATUS_REG; break; case 0x04600014: m_MemLookupValue.UW[0] = g_Reg->PI_DOMAIN1_REG; break; case 0x04600018: m_MemLookupValue.UW[0] = g_Reg->PI_BSD_DOM1_PWD_REG; break; case 0x0460001C: m_MemLookupValue.UW[0] = g_Reg->PI_BSD_DOM1_PGS_REG; break; case 0x04600020: m_MemLookupValue.UW[0] = g_Reg->PI_BSD_DOM1_RLS_REG; break; case 0x04600024: m_MemLookupValue.UW[0] = g_Reg->PI_DOMAIN2_REG; break; case 0x04600028: m_MemLookupValue.UW[0] = g_Reg->PI_BSD_DOM2_PWD_REG; break; case 0x0460002C: m_MemLookupValue.UW[0] = g_Reg->PI_BSD_DOM2_PGS_REG; break; case 0x04600030: m_MemLookupValue.UW[0] = g_Reg->PI_BSD_DOM2_RLS_REG; break; default: m_MemLookupValue.UW[0] = 0; if (HaveDebugger()) { g_Notify->BreakPoint(__FILE__, __LINE__); } } } void CMipsMemoryVM::Load32RDRAMInterface(void) { switch (m_MemLookupAddress & 0x1FFFFFFF) { case 0x04700000: m_MemLookupValue.UW[0] = g_Reg->RI_MODE_REG; break; case 0x04700004: m_MemLookupValue.UW[0] = g_Reg->RI_CONFIG_REG; break; case 0x04700008: m_MemLookupValue.UW[0] = g_Reg->RI_CURRENT_LOAD_REG; break; case 0x0470000C: m_MemLookupValue.UW[0] = g_Reg->RI_SELECT_REG; break; case 0x04700010: m_MemLookupValue.UW[0] = g_Reg->RI_REFRESH_REG; break; case 0x04700014: m_MemLookupValue.UW[0] = g_Reg->RI_LATENCY_REG; break; case 0x04700018: m_MemLookupValue.UW[0] = g_Reg->RI_RERROR_REG; break; case 0x0470001C: m_MemLookupValue.UW[0] = g_Reg->RI_WERROR_REG; break; default: m_MemLookupValue.UW[0] = 0; if (HaveDebugger()) { g_Notify->BreakPoint(__FILE__, __LINE__); } } } void CMipsMemoryVM::Load32SerialInterface(void) { switch (m_MemLookupAddress & 0x1FFFFFFF) { case 0x04800018: m_MemLookupValue.UW[0] = g_Reg->SI_STATUS_REG; break; default: m_MemLookupValue.UW[0] = 0; if (HaveDebugger()) { g_Notify->BreakPoint(__FILE__, __LINE__); } } } void CMipsMemoryVM::Load32CartridgeDomain1Address1(void) { //64DD IPL ROM if (g_DDRom != NULL && (m_MemLookupAddress & 0xFFFFFF) < g_MMU->m_DDRomSize) { m_MemLookupValue.UW[0] = *(uint32_t *)&g_MMU->m_DDRom[(m_MemLookupAddress & 0xFFFFFF)]; } else { m_MemLookupValue.UW[0] = m_MemLookupAddress & 0xFFFF; m_MemLookupValue.UW[0] = (m_MemLookupValue.UW[0] << 16) | m_MemLookupValue.UW[0]; } } void CMipsMemoryVM::Load32CartridgeDomain1Address3(void) { m_MemLookupValue.UW[0] = m_MemLookupAddress & 0xFFFF; m_MemLookupValue.UW[0] = (m_MemLookupValue.UW[0] << 16) | m_MemLookupValue.UW[0]; } void CMipsMemoryVM::Load32CartridgeDomain2Address1(void) { //64DD REGISTERS if (g_Settings->LoadBool(Setting_EnableDisk)) { switch (m_MemLookupAddress & 0x1FFFFFFF) { case 0x05000500: m_MemLookupValue.UW[0] = g_Reg->ASIC_DATA; break; case 0x05000504: m_MemLookupValue.UW[0] = g_Reg->ASIC_MISC_REG; break; case 0x05000508: m_MemLookupValue.UW[0] = g_Reg->ASIC_STATUS; DiskGapSectorCheck(); break; case 0x0500050C: m_MemLookupValue.UW[0] = g_Reg->ASIC_CUR_TK; break; case 0x05000510: m_MemLookupValue.UW[0] = g_Reg->ASIC_BM_STATUS; break; case 0x05000514: m_MemLookupValue.UW[0] = g_Reg->ASIC_ERR_SECTOR; break; case 0x05000518: m_MemLookupValue.UW[0] = g_Reg->ASIC_SEQ_STATUS; break; case 0x0500051C: m_MemLookupValue.UW[0] = g_Reg->ASIC_CUR_SECTOR; break; case 0x05000520: m_MemLookupValue.UW[0] = g_Reg->ASIC_HARD_RESET; break; case 0x05000524: m_MemLookupValue.UW[0] = g_Reg->ASIC_C1_S0; break; case 0x05000528: m_MemLookupValue.UW[0] = g_Reg->ASIC_HOST_SECBYTE; break; case 0x0500052C: m_MemLookupValue.UW[0] = g_Reg->ASIC_C1_S2; break; case 0x05000530: m_MemLookupValue.UW[0] = g_Reg->ASIC_SEC_BYTE; break; case 0x05000534: m_MemLookupValue.UW[0] = g_Reg->ASIC_C1_S4; break; case 0x05000538: m_MemLookupValue.UW[0] = g_Reg->ASIC_C1_S6; break; case 0x0500053C: m_MemLookupValue.UW[0] = g_Reg->ASIC_CUR_ADDR; break; case 0x05000540: m_MemLookupValue.UW[0] = g_Reg->ASIC_ID_REG; break; case 0x05000544: m_MemLookupValue.UW[0] = g_Reg->ASIC_TEST_REG; break; case 0x05000548: m_MemLookupValue.UW[0] = g_Reg->ASIC_TEST_PIN_SEL; break; default: m_MemLookupValue.UW[0] = m_MemLookupAddress & 0xFFFF; m_MemLookupValue.UW[0] = (m_MemLookupValue.UW[0] << 16) | m_MemLookupValue.UW[0]; if (HaveDebugger()) { g_Notify->BreakPoint(__FILE__, __LINE__); } } } else { m_MemLookupValue.UW[0] = m_MemLookupAddress & 0xFFFF; m_MemLookupValue.UW[0] = (m_MemLookupValue.UW[0] << 16) | m_MemLookupValue.UW[0]; } } void CMipsMemoryVM::Load32CartridgeDomain2Address2(void) { uint32_t offset = (m_MemLookupAddress & 0x1FFFFFFF) - 0x08000000; if (offset > 0x10000) { m_MemLookupValue.UW[0] = ((offset & 0xFFFF) << 16) | (offset & 0xFFFF); return; } 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] = ""; g_MMU->DmaFromSram(tmp, offset, 4); m_MemLookupValue.UW[0] = tmp[3] << 24 | tmp[2] << 16 | tmp[1] << 8 | tmp[0]; } else if (g_System->m_SaveUsing != SaveChip_FlashRam) { if (HaveDebugger()) { g_Notify->BreakPoint(__FILE__, __LINE__); } m_MemLookupValue.UW[0] = m_MemLookupAddress & 0xFFFF; m_MemLookupValue.UW[0] = (m_MemLookupValue.UW[0] << 16) | m_MemLookupValue.UW[0]; } else { m_MemLookupValue.UW[0] = g_MMU->ReadFromFlashStatus(m_MemLookupAddress & 0x1FFFFFFF); } } void CMipsMemoryVM::Load32PifRam(void) { if ((m_MemLookupAddress & 0x1FFFFFFF) < 0x1FC007C0) { //m_MemLookupValue.UW[0] = swap32by8(*(uint32_t *)(&PifRom[PAddr - 0x1FC00000])); m_MemLookupValue.UW[0] = 0; if (HaveDebugger()) { g_Notify->BreakPoint(__FILE__, __LINE__); } } else if ((m_MemLookupAddress & 0x1FFFFFFF) < 0x1FC00800) { uint8_t * PIF_Ram = g_MMU->PifRam(); m_MemLookupValue.UW[0] = *(uint32_t *)(&PIF_Ram[(m_MemLookupAddress & 0x1FFFFFFF) - 0x1FC007C0]); m_MemLookupValue.UW[0] = swap32by8(m_MemLookupValue.UW[0]); } else { m_MemLookupValue.UW[0] = 0; if (HaveDebugger()) { g_Notify->BreakPoint(__FILE__, __LINE__); } } } void CMipsMemoryVM::Load32Rom(void) { if (g_MMU->m_RomWrittenTo) { m_MemLookupValue.UW[0] = g_MMU->m_RomWroteValue; //LogMessage("%X: Read crap from Rom %08X from %08X",PROGRAM_COUNTER,*Value,PAddr); g_MMU->m_RomWrittenTo = false; #ifdef ROM_IN_MAPSPACE { uint32_t OldProtect; VirtualProtect(ROM, RomFileSize, PAGE_READONLY, &OldProtect); } #endif } else if ((m_MemLookupAddress & 0xFFFFFFF) < g_MMU->m_RomSize) { m_MemLookupValue.UW[0] = *(uint32_t *)&g_MMU->m_Rom[(m_MemLookupAddress & 0xFFFFFFF)]; } else { m_MemLookupValue.UW[0] = m_MemLookupAddress & 0xFFFF; m_MemLookupValue.UW[0] = (m_MemLookupValue.UW[0] << 16) | m_MemLookupValue.UW[0]; } } void CMipsMemoryVM::Write32RDRAMRegisters(void) { switch ((m_MemLookupAddress & 0xFFFFFFF)) { case 0x03F00000: g_Reg->RDRAM_CONFIG_REG = m_MemLookupValue.UW[0]; break; case 0x03F00004: g_Reg->RDRAM_DEVICE_ID_REG = m_MemLookupValue.UW[0]; break; case 0x03F00008: g_Reg->RDRAM_DELAY_REG = m_MemLookupValue.UW[0]; break; case 0x03F0000C: g_Reg->RDRAM_MODE_REG = m_MemLookupValue.UW[0]; break; case 0x03F00010: g_Reg->RDRAM_REF_INTERVAL_REG = m_MemLookupValue.UW[0]; break; case 0x03F00014: g_Reg->RDRAM_REF_ROW_REG = m_MemLookupValue.UW[0]; break; case 0x03F00018: g_Reg->RDRAM_RAS_INTERVAL_REG = m_MemLookupValue.UW[0]; break; case 0x03F0001C: g_Reg->RDRAM_MIN_INTERVAL_REG = m_MemLookupValue.UW[0]; break; case 0x03F00020: g_Reg->RDRAM_ADDR_SELECT_REG = m_MemLookupValue.UW[0]; break; case 0x03F00024: g_Reg->RDRAM_DEVICE_MANUF_REG = m_MemLookupValue.UW[0]; break; case 0x03F04004: break; case 0x03F08004: break; case 0x03F80004: break; case 0x03F80008: break; case 0x03F8000C: break; case 0x03F80014: break; default: if (HaveDebugger()) { g_Notify->BreakPoint(__FILE__, __LINE__); } } } void CMipsMemoryVM::Write32SPRegisters(void) { switch ((m_MemLookupAddress & 0xFFFFFFF)) { case 0x04040000: g_Reg->SP_MEM_ADDR_REG = m_MemLookupValue.UW[0]; break; case 0x04040004: g_Reg->SP_DRAM_ADDR_REG = m_MemLookupValue.UW[0]; break; case 0x04040008: g_Reg->SP_RD_LEN_REG = m_MemLookupValue.UW[0]; g_MMU->SP_DMA_READ(); break; case 0x0404000C: g_Reg->SP_WR_LEN_REG = m_MemLookupValue.UW[0]; g_MMU->SP_DMA_WRITE(); break; case 0x04040010: if ((m_MemLookupValue.UW[0] & SP_CLR_HALT) != 0) { g_Reg->SP_STATUS_REG &= ~SP_STATUS_HALT; } if ((m_MemLookupValue.UW[0] & SP_SET_HALT) != 0) { g_Reg->SP_STATUS_REG |= SP_STATUS_HALT; } if ((m_MemLookupValue.UW[0] & SP_CLR_BROKE) != 0) { g_Reg->SP_STATUS_REG &= ~SP_STATUS_BROKE; } if ((m_MemLookupValue.UW[0] & SP_CLR_INTR) != 0) { g_Reg->MI_INTR_REG &= ~MI_INTR_SP; g_Reg->m_RspIntrReg &= ~MI_INTR_SP; g_Reg->CheckInterrupts(); } if ((m_MemLookupValue.UW[0] & SP_SET_INTR) != 0) { g_Notify->DisplayError("SP_SET_INTR"); } if ((m_MemLookupValue.UW[0] & SP_CLR_SSTEP) != 0) { g_Reg->SP_STATUS_REG &= ~SP_STATUS_SSTEP; } if ((m_MemLookupValue.UW[0] & SP_SET_SSTEP) != 0) { g_Reg->SP_STATUS_REG |= SP_STATUS_SSTEP; } if ((m_MemLookupValue.UW[0] & SP_CLR_INTR_BREAK) != 0) { g_Reg->SP_STATUS_REG &= ~SP_STATUS_INTR_BREAK; } if ((m_MemLookupValue.UW[0] & SP_SET_INTR_BREAK) != 0) { g_Reg->SP_STATUS_REG |= SP_STATUS_INTR_BREAK; } if ((m_MemLookupValue.UW[0] & SP_CLR_SIG0) != 0) { g_Reg->SP_STATUS_REG &= ~SP_STATUS_SIG0; } if ((m_MemLookupValue.UW[0] & SP_SET_SIG0) != 0) { g_Reg->SP_STATUS_REG |= SP_STATUS_SIG0; } if ((m_MemLookupValue.UW[0] & SP_CLR_SIG1) != 0) { g_Reg->SP_STATUS_REG &= ~SP_STATUS_SIG1; } if ((m_MemLookupValue.UW[0] & SP_SET_SIG1) != 0) { g_Reg->SP_STATUS_REG |= SP_STATUS_SIG1; } if ((m_MemLookupValue.UW[0] & SP_CLR_SIG2) != 0) { g_Reg->SP_STATUS_REG &= ~SP_STATUS_SIG2; } if ((m_MemLookupValue.UW[0] & SP_SET_SIG2) != 0) { g_Reg->SP_STATUS_REG |= SP_STATUS_SIG2; } if ((m_MemLookupValue.UW[0] & SP_CLR_SIG3) != 0) { g_Reg->SP_STATUS_REG &= ~SP_STATUS_SIG3; } if ((m_MemLookupValue.UW[0] & SP_SET_SIG3) != 0) { g_Reg->SP_STATUS_REG |= SP_STATUS_SIG3; } if ((m_MemLookupValue.UW[0] & SP_CLR_SIG4) != 0) { g_Reg->SP_STATUS_REG &= ~SP_STATUS_SIG4; } if ((m_MemLookupValue.UW[0] & SP_SET_SIG4) != 0) { g_Reg->SP_STATUS_REG |= SP_STATUS_SIG4; } if ((m_MemLookupValue.UW[0] & SP_CLR_SIG5) != 0) { g_Reg->SP_STATUS_REG &= ~SP_STATUS_SIG5; } if ((m_MemLookupValue.UW[0] & SP_SET_SIG5) != 0) { g_Reg->SP_STATUS_REG |= SP_STATUS_SIG5; } if ((m_MemLookupValue.UW[0] & SP_CLR_SIG6) != 0) { g_Reg->SP_STATUS_REG &= ~SP_STATUS_SIG6; } if ((m_MemLookupValue.UW[0] & SP_SET_SIG6) != 0) { g_Reg->SP_STATUS_REG |= SP_STATUS_SIG6; } if ((m_MemLookupValue.UW[0] & SP_CLR_SIG7) != 0) { g_Reg->SP_STATUS_REG &= ~SP_STATUS_SIG7; } if ((m_MemLookupValue.UW[0] & SP_SET_SIG7) != 0) { g_Reg->SP_STATUS_REG |= SP_STATUS_SIG7; } if ((m_MemLookupValue.UW[0] & 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(__FILE__, __LINE__); } //} break; case 0x0404001C: g_Reg->SP_SEMAPHORE_REG = 0; break; case 0x04080000: g_Reg->SP_PC_REG = m_MemLookupValue.UW[0] & 0xFFC; break; default: if (HaveDebugger()) { g_Notify->BreakPoint(__FILE__, __LINE__); } } } void CMipsMemoryVM::Write32DPCommandRegisters(void) { switch ((m_MemLookupAddress & 0xFFFFFFF)) { case 0x04100000: g_Reg->DPC_START_REG = m_MemLookupValue.UW[0]; g_Reg->DPC_CURRENT_REG = m_MemLookupValue.UW[0]; break; case 0x04100004: g_Reg->DPC_END_REG = m_MemLookupValue.UW[0]; if (g_Plugins->Gfx()->ProcessRDPList) { g_Plugins->Gfx()->ProcessRDPList(); } break; //case 0x04100008: g_Reg->DPC_CURRENT_REG = Value; break; case 0x0410000C: if ((m_MemLookupValue.UW[0] & DPC_CLR_XBUS_DMEM_DMA) != 0) { g_Reg->DPC_STATUS_REG &= ~DPC_STATUS_XBUS_DMEM_DMA; } if ((m_MemLookupValue.UW[0] & DPC_SET_XBUS_DMEM_DMA) != 0) { g_Reg->DPC_STATUS_REG |= DPC_STATUS_XBUS_DMEM_DMA; } if ((m_MemLookupValue.UW[0] & DPC_CLR_FREEZE) != 0) { g_Reg->DPC_STATUS_REG &= ~DPC_STATUS_FREEZE; } if ((m_MemLookupValue.UW[0] & DPC_SET_FREEZE) != 0) { g_Reg->DPC_STATUS_REG |= DPC_STATUS_FREEZE; } if ((m_MemLookupValue.UW[0] & DPC_CLR_FLUSH) != 0) { g_Reg->DPC_STATUS_REG &= ~DPC_STATUS_FLUSH; } if ((m_MemLookupValue.UW[0] & DPC_SET_FLUSH) != 0) { g_Reg->DPC_STATUS_REG |= DPC_STATUS_FLUSH; } if ((m_MemLookupValue.UW[0] & DPC_CLR_FREEZE) != 0) { if ((g_Reg->SP_STATUS_REG & SP_STATUS_HALT) == 0) { if ((g_Reg->SP_STATUS_REG & SP_STATUS_BROKE) == 0) { __except_try() { g_System->RunRSP(); } __except_catch() { g_Notify->BreakPoint(__FILE__, __LINE__); } } } } #ifdef legacycode if (ShowUnhandledMemory) { //if ( ( m_MemLookupValue.UW[0] & DPC_CLR_TMEM_CTR ) != 0) //{ // g_Notify->DisplayError("RSP: DPC_STATUS_REG: DPC_CLR_TMEM_CTR"); //} //if ( ( m_MemLookupValue.UW[0] & DPC_CLR_PIPE_CTR ) != 0) //{ // g_Notify->DisplayError("RSP: DPC_STATUS_REG: DPC_CLR_PIPE_CTR"); //} //if ( ( m_MemLookupValue.UW[0] & DPC_CLR_CMD_CTR ) != 0) //{ // g_Notify->DisplayError("RSP: DPC_STATUS_REG: DPC_CLR_CMD_CTR"); //} //if ( ( m_MemLookupValue.UW[0] & DPC_CLR_CLOCK_CTR ) != 0) //{ // g_Notify->DisplayError("RSP: DPC_STATUS_REG: DPC_CLR_CLOCK_CTR"); //} } #endif break; default: if (HaveDebugger()) { g_Notify->BreakPoint(__FILE__, __LINE__); } } } void CMipsMemoryVM::Write32MIPSInterface(void) { switch ((m_MemLookupAddress & 0xFFFFFFF)) { case 0x04300000: g_Reg->MI_MODE_REG &= ~0x7F; g_Reg->MI_MODE_REG |= (m_MemLookupValue.UW[0] & 0x7F); if ((m_MemLookupValue.UW[0] & MI_CLR_INIT) != 0) { g_Reg->MI_MODE_REG &= ~MI_MODE_INIT; } if ((m_MemLookupValue.UW[0] & MI_SET_INIT) != 0) { g_Reg->MI_MODE_REG |= MI_MODE_INIT; } if ((m_MemLookupValue.UW[0] & MI_CLR_EBUS) != 0) { g_Reg->MI_MODE_REG &= ~MI_MODE_EBUS; } if ((m_MemLookupValue.UW[0] & MI_SET_EBUS) != 0) { g_Reg->MI_MODE_REG |= MI_MODE_EBUS; } if ((m_MemLookupValue.UW[0] & MI_CLR_DP_INTR) != 0) { g_Reg->MI_INTR_REG &= ~MI_INTR_DP; g_Reg->m_GfxIntrReg &= ~MI_INTR_DP; g_Reg->CheckInterrupts(); } if ((m_MemLookupValue.UW[0] & MI_CLR_RDRAM) != 0) { g_Reg->MI_MODE_REG &= ~MI_MODE_RDRAM; } if ((m_MemLookupValue.UW[0] & MI_SET_RDRAM) != 0) { g_Reg->MI_MODE_REG |= MI_MODE_RDRAM; } break; case 0x0430000C: if ((m_MemLookupValue.UW[0] & MI_INTR_MASK_CLR_SP) != 0) { g_Reg->MI_INTR_MASK_REG &= ~MI_INTR_MASK_SP; } if ((m_MemLookupValue.UW[0] & MI_INTR_MASK_SET_SP) != 0) { g_Reg->MI_INTR_MASK_REG |= MI_INTR_MASK_SP; } if ((m_MemLookupValue.UW[0] & MI_INTR_MASK_CLR_SI) != 0) { g_Reg->MI_INTR_MASK_REG &= ~MI_INTR_MASK_SI; } if ((m_MemLookupValue.UW[0] & MI_INTR_MASK_SET_SI) != 0) { g_Reg->MI_INTR_MASK_REG |= MI_INTR_MASK_SI; } if ((m_MemLookupValue.UW[0] & MI_INTR_MASK_CLR_AI) != 0) { g_Reg->MI_INTR_MASK_REG &= ~MI_INTR_MASK_AI; } if ((m_MemLookupValue.UW[0] & MI_INTR_MASK_SET_AI) != 0) { g_Reg->MI_INTR_MASK_REG |= MI_INTR_MASK_AI; } if ((m_MemLookupValue.UW[0] & MI_INTR_MASK_CLR_VI) != 0) { g_Reg->MI_INTR_MASK_REG &= ~MI_INTR_MASK_VI; } if ((m_MemLookupValue.UW[0] & MI_INTR_MASK_SET_VI) != 0) { g_Reg->MI_INTR_MASK_REG |= MI_INTR_MASK_VI; } if ((m_MemLookupValue.UW[0] & MI_INTR_MASK_CLR_PI) != 0) { g_Reg->MI_INTR_MASK_REG &= ~MI_INTR_MASK_PI; } if ((m_MemLookupValue.UW[0] & MI_INTR_MASK_SET_PI) != 0) { g_Reg->MI_INTR_MASK_REG |= MI_INTR_MASK_PI; } if ((m_MemLookupValue.UW[0] & MI_INTR_MASK_CLR_DP) != 0) { g_Reg->MI_INTR_MASK_REG &= ~MI_INTR_MASK_DP; } if ((m_MemLookupValue.UW[0] & MI_INTR_MASK_SET_DP) != 0) { g_Reg->MI_INTR_MASK_REG |= MI_INTR_MASK_DP; } break; default: if (HaveDebugger()) { g_Notify->BreakPoint(__FILE__, __LINE__); } } } void CMipsMemoryVM::Write32VideoInterface(void) { switch ((m_MemLookupAddress & 0xFFFFFFF)) { case 0x04400000: if (g_Reg->VI_STATUS_REG != m_MemLookupValue.UW[0]) { g_Reg->VI_STATUS_REG = m_MemLookupValue.UW[0]; 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 = (m_MemLookupValue.UW[0] & 0xFFFFFF); //if (UpdateScreen != NULL ) //{ // UpdateScreen(); //} break; case 0x04400008: if (g_Reg->VI_WIDTH_REG != m_MemLookupValue.UW[0]) { g_Reg->VI_WIDTH_REG = m_MemLookupValue.UW[0]; if (g_Plugins->Gfx()->ViWidthChanged != NULL) { g_Plugins->Gfx()->ViWidthChanged(); } } break; case 0x0440000C: g_Reg->VI_INTR_REG = m_MemLookupValue.UW[0]; break; case 0x04400010: g_Reg->MI_INTR_REG &= ~MI_INTR_VI; g_Reg->CheckInterrupts(); break; case 0x04400014: g_Reg->VI_BURST_REG = m_MemLookupValue.UW[0]; break; case 0x04400018: g_Reg->VI_V_SYNC_REG = m_MemLookupValue.UW[0]; break; case 0x0440001C: g_Reg->VI_H_SYNC_REG = m_MemLookupValue.UW[0]; break; case 0x04400020: g_Reg->VI_LEAP_REG = m_MemLookupValue.UW[0]; break; case 0x04400024: g_Reg->VI_H_START_REG = m_MemLookupValue.UW[0]; break; case 0x04400028: g_Reg->VI_V_START_REG = m_MemLookupValue.UW[0]; break; case 0x0440002C: g_Reg->VI_V_BURST_REG = m_MemLookupValue.UW[0]; break; case 0x04400030: g_Reg->VI_X_SCALE_REG = m_MemLookupValue.UW[0]; break; case 0x04400034: g_Reg->VI_Y_SCALE_REG = m_MemLookupValue.UW[0]; break; default: if (HaveDebugger()) { g_Notify->BreakPoint(__FILE__, __LINE__); } } } void CMipsMemoryVM::Write32AudioInterface(void) { switch (m_MemLookupAddress & 0xFFFFFFF) { case 0x04500000: g_Reg->AI_DRAM_ADDR_REG = m_MemLookupValue.UW[0]; break; case 0x04500004: g_Reg->AI_LEN_REG = m_MemLookupValue.UW[0]; 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 = (m_MemLookupValue.UW[0] & 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 = m_MemLookupValue.UW[0]; g_Plugins->Audio()->DacrateChanged(g_System->SystemType()); if (g_System->bFixedAudio()) { g_Audio->SetFrequency(m_MemLookupValue.UW[0], g_System->SystemType()); } break; case 0x04500014: g_Reg->AI_BITRATE_REG = m_MemLookupValue.UW[0]; break; default: if (HaveDebugger()) { g_Notify->BreakPoint(__FILE__, __LINE__); } } } void CMipsMemoryVM::Write32PeripheralInterface(void) { switch (m_MemLookupAddress & 0xFFFFFFF) { case 0x04600000: g_Reg->PI_DRAM_ADDR_REG = m_MemLookupValue.UW[0]; break; case 0x04600004: g_Reg->PI_CART_ADDR_REG = m_MemLookupValue.UW[0]; if (g_Settings->LoadBool(Setting_EnableDisk)) { DiskDMACheck(); } break; case 0x04600008: g_Reg->PI_RD_LEN_REG = m_MemLookupValue.UW[0]; g_MMU->PI_DMA_READ(); break; case 0x0460000C: g_Reg->PI_WR_LEN_REG = m_MemLookupValue.UW[0]; g_MMU->PI_DMA_WRITE(); break; case 0x04600010: //if ((Value & PI_SET_RESET) != 0 ) //{ // g_Notify->DisplayError("reset Controller"); //} if ((m_MemLookupValue.UW[0] & PI_CLR_INTR) != 0) { g_Reg->MI_INTR_REG &= ~MI_INTR_PI; g_Reg->CheckInterrupts(); } break; case 0x04600014: g_Reg->PI_DOMAIN1_REG = (m_MemLookupValue.UW[0] & 0xFF); break; case 0x04600018: g_Reg->PI_BSD_DOM1_PWD_REG = (m_MemLookupValue.UW[0] & 0xFF); break; case 0x0460001C: g_Reg->PI_BSD_DOM1_PGS_REG = (m_MemLookupValue.UW[0] & 0xFF); break; case 0x04600020: g_Reg->PI_BSD_DOM1_RLS_REG = (m_MemLookupValue.UW[0] & 0xFF); break; case 0x04600024: g_Reg->PI_DOMAIN2_REG = (m_MemLookupValue.UW[0] & 0xFF); break; case 0x04600028: g_Reg->PI_BSD_DOM2_PWD_REG = (m_MemLookupValue.UW[0] & 0xFF); break; case 0x0460002C: g_Reg->PI_BSD_DOM2_PGS_REG = (m_MemLookupValue.UW[0] & 0xFF); break; case 0x04600030: g_Reg->PI_BSD_DOM2_RLS_REG = (m_MemLookupValue.UW[0] & 0xFF); break; default: if (HaveDebugger()) { g_Notify->BreakPoint(__FILE__, __LINE__); } } } void CMipsMemoryVM::Write32RDRAMInterface(void) { switch (m_MemLookupAddress & 0xFFFFFFF) { case 0x04700000: g_Reg->RI_MODE_REG = m_MemLookupValue.UW[0]; break; case 0x04700004: g_Reg->RI_CONFIG_REG = m_MemLookupValue.UW[0]; break; case 0x04700008: g_Reg->RI_CURRENT_LOAD_REG = m_MemLookupValue.UW[0]; break; case 0x0470000C: g_Reg->RI_SELECT_REG = m_MemLookupValue.UW[0]; break; case 0x04700010: g_Reg->RI_REFRESH_REG = m_MemLookupValue.UW[0]; break; case 0x04700014: g_Reg->RI_LATENCY_REG = m_MemLookupValue.UW[0]; break; case 0x04700018: g_Reg->RI_RERROR_REG = m_MemLookupValue.UW[0]; break; case 0x0470001C: g_Reg->RI_WERROR_REG = m_MemLookupValue.UW[0]; break; default: if (HaveDebugger()) { g_Notify->BreakPoint(__FILE__, __LINE__); } } } void CMipsMemoryVM::Write32SerialInterface(void) { switch (m_MemLookupAddress & 0xFFFFFFF) { case 0x04800000: g_Reg->SI_DRAM_ADDR_REG = m_MemLookupValue.UW[0]; break; case 0x04800004: g_Reg->SI_PIF_ADDR_RD64B_REG = m_MemLookupValue.UW[0]; g_MMU->SI_DMA_READ(); break; case 0x04800010: g_Reg->SI_PIF_ADDR_WR64B_REG = m_MemLookupValue.UW[0]; g_MMU->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: if (HaveDebugger()) { g_Notify->BreakPoint(__FILE__, __LINE__); } } } void CMipsMemoryVM::Write32CartridgeDomain2Address1(void) { //64DD Registers if (g_Settings->LoadBool(Setting_EnableDisk)) { switch (m_MemLookupAddress & 0xFFFFFFF) { case 0x05000500: g_Reg->ASIC_DATA = m_MemLookupValue.UW[0]; break; case 0x05000508: g_Reg->ASIC_CMD = m_MemLookupValue.UW[0]; DiskCommand(); break; case 0x05000510: //ASIC_BM_STATUS_CTL g_Reg->ASIC_BM_CTL = m_MemLookupValue.UW[0]; DiskBMControl(); break; case 0x05000518: //ASIC_SEQ_STATUS_CTL break; case 0x05000520: DiskReset(); break; case 0x05000528: g_Reg->ASIC_HOST_SECBYTE = m_MemLookupValue.UW[0]; break; case 0x05000530: g_Reg->ASIC_SEC_BYTE = m_MemLookupValue.UW[0]; break; case 0x05000548: g_Reg->ASIC_TEST_PIN_SEL = m_MemLookupValue.UW[0]; break; default: if (HaveDebugger()) { g_Notify->BreakPoint(__FILE__, __LINE__); } } } } void CMipsMemoryVM::Write32CartridgeDomain2Address2(void) { uint32_t offset = (m_MemLookupAddress & 0x1FFFFFFF) - 0x08000000; if (g_System->m_SaveUsing == SaveChip_Sram && offset < 0x8000) { //Store Sram uint8_t tmp[4] = ""; tmp[0] = 0xFF & (m_MemLookupValue.UW[0]); tmp[1] = 0xFF & (m_MemLookupValue.UW[0] >> 8); tmp[2] = 0xFF & (m_MemLookupValue.UW[0] >> 16); tmp[3] = 0xFF & (m_MemLookupValue.UW[0] >> 24); g_MMU->DmaToSram(tmp, (m_MemLookupAddress & 0x1FFFFFFF) - 0x08000000, 4); return; } /*if ((m_MemLookupAddress & 0x1FFFFFFF) != 0x08010000) { if (HaveDebugger()) { g_Notify->BreakPoint(__FILE__, __LINE__); } }*/ if (offset > 0x10000) { return; } if (g_System->m_SaveUsing == SaveChip_Auto) { g_System->m_SaveUsing = SaveChip_FlashRam; } if (g_System->m_SaveUsing == SaveChip_FlashRam) { g_MMU->WriteToFlashCommand(m_MemLookupValue.UW[0]); } } void CMipsMemoryVM::Write32PifRam(void) { if ((m_MemLookupAddress & 0x1FFFFFFF) < 0x1FC007C0) { if (HaveDebugger()) { g_Notify->BreakPoint(__FILE__, __LINE__); } } else if ((m_MemLookupAddress & 0x1FFFFFFF) < 0x1FC00800) { uint32_t Value = swap32by8(m_MemLookupValue.UW[0]); *(uint32_t *)(&g_MMU->m_PifRam[(m_MemLookupAddress & 0x1FFFFFFF) - 0x1FC007C0]) = Value; if ((m_MemLookupAddress & 0x1FFFFFFF) == 0x1FC007FC) { g_MMU->PifRamWrite(); } } }