diff --git a/Source/Project64-core/N64System/MemoryHandler/PeripheralInterfaceHandler.cpp b/Source/Project64-core/N64System/MemoryHandler/PeripheralInterfaceHandler.cpp index ed06f7cfe..2e80d4b7e 100644 --- a/Source/Project64-core/N64System/MemoryHandler/PeripheralInterfaceHandler.cpp +++ b/Source/Project64-core/N64System/MemoryHandler/PeripheralInterfaceHandler.cpp @@ -388,6 +388,7 @@ void PeripheralInterfaceHandler::PI_DMA_WRITE() uint8_t Block[128]; bool FirstBlock = true; uint8_t * Rdram = m_MMU.Rdram(); + uint32_t RdramSize = m_MMU.RdramSize(); uint32_t TransferLen = 0; while (Length > 0) { @@ -425,7 +426,15 @@ void PeripheralInterfaceHandler::PI_DMA_WRITE() BlockLen = ReadLen; } - for (int32_t i = 0; i < BlockLen; i++) + if ((PI_DRAM_ADDR_REG + BlockLen) >= RdramSize) + { + BlockLen = RdramSize - PI_DRAM_ADDR_REG; + if (BlockLen < 0) + { + BlockLen = 0; + } + } + for (int32_t i = 0; i < BlockLen ; i++) { Rdram[(PI_DRAM_ADDR_REG + i) ^ 3] = Block[i]; } diff --git a/Source/Project64-core/N64System/MemoryHandler/RDRAMRegistersHandler.cpp b/Source/Project64-core/N64System/MemoryHandler/RDRAMRegistersHandler.cpp index 5f960b687..52ffd4077 100644 --- a/Source/Project64-core/N64System/MemoryHandler/RDRAMRegistersHandler.cpp +++ b/Source/Project64-core/N64System/MemoryHandler/RDRAMRegistersHandler.cpp @@ -23,24 +23,28 @@ RDRAMRegistersHandler::RDRAMRegistersHandler(CRegisters & Reg) : RDRAMRegistersReg(Reg.m_RDRAM_Registers), m_PC(Reg.m_PROGRAM_COUNTER) { + memset(m_Device, 0, sizeof(m_Device)); } bool RDRAMRegistersHandler::Read32(uint32_t Address, uint32_t & Value) { - switch (Address & 0x1FFFFFFF) + uint32_t DeviceID = Address >> 13 & 3; + RDRAM_DEVICE & Device = m_Device[DeviceID]; + + switch (Address & 0x3fc) { - case 0x03F00000: Value = RDRAM_CONFIG_REG; break; - case 0x03F00004: Value = RDRAM_DEVICE_ID_REG; break; - case 0x03F00008: Value = RDRAM_DELAY_REG; break; - case 0x03F0000C: Value = RDRAM_MODE_REG; break; - case 0x03F00010: Value = RDRAM_REF_INTERVAL_REG; break; - case 0x03F00014: Value = RDRAM_REF_ROW_REG; break; - case 0x03F00018: Value = RDRAM_RAS_INTERVAL_REG; break; - case 0x03F0001C: Value = RDRAM_MIN_INTERVAL_REG; break; - case 0x03F00020: Value = RDRAM_ADDR_SELECT_REG; break; - case 0x03F00024: Value = RDRAM_DEVICE_MANUF_REG; break; + case 0x00: Value = Device.DeviceType; break; + case 0x04: Value = Device.DeviceId; break; + case 0x08: Value = Device.Delay; break; + case 0x0C: Value = Device.Mode ^ 0xc0c0c0c0; break; + case 0x10: Value = Device.RefreshInterval; break; + case 0x14: Value = Device.RefreshRow; break; + case 0x18: Value = Device.RasInterval; break; + case 0x1C: Value = Device.MinInterval; break; + case 0x20: Value = Device.AddressSelect; break; + case 0x24: Value = Device.DeviceManufacturer; break; + case 0x28: Value = Device.CurrentControl; break; default: - Value = 0; if (HaveDebugger()) { g_Notify->BreakPoint(__FILE__, __LINE__); @@ -49,18 +53,19 @@ bool RDRAMRegistersHandler::Read32(uint32_t Address, uint32_t & Value) if (LogRDRamRegisters()) { - switch (Address & 0x1FFFFFFF) + switch (Address & 0x3fc) { - case 0x03F00000: LogMessage("%016llX: read from RDRAM_CONFIG_REG/RDRAM_DEVICE_TYPE_REG (%08X)", m_PC, Value); break; - case 0x03F00004: LogMessage("%016llX: read from RDRAM_DEVICE_ID_REG (%08X)", m_PC, Value); break; - case 0x03F00008: LogMessage("%016llX: read from RDRAM_DELAY_REG (%08X)", m_PC, Value); break; - case 0x03F0000C: LogMessage("%016llX: read from RDRAM_MODE_REG (%08X)", m_PC, Value); break; - case 0x03F00010: LogMessage("%016llX: read from RDRAM_REF_INTERVAL_REG (%08X)", m_PC, Value); break; - case 0x03F00014: LogMessage("%016llX: read from RDRAM_REF_ROW_REG (%08X)", m_PC, Value); break; - case 0x03F00018: LogMessage("%016llX: read from RDRAM_RAS_INTERVAL_REG (%08X)", m_PC, Value); break; - case 0x03F0001C: LogMessage("%016llX: read from RDRAM_MIN_INTERVAL_REG (%08X)", m_PC, Value); break; - case 0x03F00020: LogMessage("%016llX: read from RDRAM_ADDR_SELECT_REG (%08X)", m_PC, Value); break; - case 0x03F00024: LogMessage("%016llX: read from RDRAM_DEVICE_MANUF_REG (%08X)", m_PC, Value); break; + case 0x00: LogMessage("%016llX: read from Device[%d].DeviceType (%08X)", m_PC, DeviceID, Value); break; + case 0x04: LogMessage("%016llX: read from Device[%d].DeviceId (%08X)", m_PC, DeviceID, Value); break; + case 0x08: LogMessage("%016llX: read from Device[%d].Delay (%08X)", m_PC, DeviceID, Value); break; + case 0x0C: LogMessage("%016llX: read from Device[%d].Mode (%08X)", m_PC, DeviceID, Value); break; + case 0x10: LogMessage("%016llX: read from Device[%d].RefreshInterval (%08X)", m_PC, DeviceID, Value); break; + case 0x14: LogMessage("%016llX: read from Device[%d].RefreshRow (%08X)", m_PC, DeviceID, Value); break; + case 0x18: LogMessage("%016llX: read from Device[%d].RasInterval (%08X)", m_PC, DeviceID, Value); break; + case 0x1C: LogMessage("%016llX: read from Device[%d].MinInterval (%08X)", m_PC, DeviceID, Value); break; + case 0x20: LogMessage("%016llX: read from Device[%d].AddressSelect (%08X)", m_PC, DeviceID, Value); break; + case 0x24: LogMessage("%016llX: read from Device[%d].DeviceManufacturer (%08X)", m_PC, DeviceID, Value); break; + case 0x28: LogMessage("%016llX: read from Device[%d].CurrentControl (%08X)", m_PC, DeviceID, Value); break; default: if (HaveDebugger()) { @@ -73,26 +78,24 @@ bool RDRAMRegistersHandler::Read32(uint32_t Address, uint32_t & Value) bool RDRAMRegistersHandler::Write32(uint32_t Address, uint32_t Value, uint32_t Mask) { + uint32_t DeviceID = Address >> 13 & 3; + RDRAM_DEVICE & Device = m_Device[DeviceID]; + if (LogRDRamRegisters()) { - switch (Address & 0x1FFFFFFF) + switch (Address & 0x3fc) { - case 0x03F00000: LogMessage("%016llX: Writing 0x%08X (Mask: 0x%08X) to RDRAM_CONFIG_REG/RDRAM_DEVICE_TYPE_REG", m_PC, Value, Mask); break; - case 0x03F00004: LogMessage("%016llX: Writing 0x%08X (Mask: 0x%08X) to RDRAM_DEVICE_ID_REG", m_PC, Value, Mask); break; - case 0x03F00008: LogMessage("%016llX: Writing 0x%08X (Mask: 0x%08X) to RDRAM_DELAY_REG", m_PC, Value, Mask); break; - case 0x03F0000C: LogMessage("%016llX: Writing 0x%08X (Mask: 0x%08X) to RDRAM_MODE_REG", m_PC, Value, Mask); break; - case 0x03F00010: LogMessage("%016llX: Writing 0x%08X (Mask: 0x%08X) to RDRAM_REF_INTERVAL_REG", m_PC, Value, Mask); break; - case 0x03F00014: LogMessage("%016llX: Writing 0x%08X (Mask: 0x%08X) to RDRAM_REF_ROW_REG", m_PC, Value, Mask); break; - case 0x03F00018: LogMessage("%016llX: Writing 0x%08X (Mask: 0x%08X) to RDRAM_RAS_INTERVAL_REG", m_PC, Value, Mask); break; - case 0x03F0001C: LogMessage("%016llX: Writing 0x%08X (Mask: 0x%08X) to RDRAM_MIN_INTERVAL_REG", m_PC, Value, Mask); break; - case 0x03F00020: LogMessage("%016llX: Writing 0x%08X (Mask: 0x%08X) to RDRAM_ADDR_SELECT_REG", m_PC, Value, Mask); break; - case 0x03F00024: LogMessage("%016llX: Writing 0x%08X (Mask: 0x%08X) to RDRAM_DEVICE_MANUF_REG", m_PC, Value, Mask); break; - case 0x03F04004: LogMessage("%016llX: Writing 0x%08X (Mask: 0x%08X) to 0x%08X - Ignored", m_PC, Value, Mask, Address); break; - case 0x03F08004: LogMessage("%016llX: Writing 0x%08X (Mask: 0x%08X) to 0x%08X - Ignored", m_PC, Value, Mask, Address); break; - case 0x03F80004: LogMessage("%016llX: Writing 0x%08X (Mask: 0x%08X) to 0x%08X - Ignored", m_PC, Value, Mask, Address); break; - case 0x03F80008: LogMessage("%016llX: Writing 0x%08X (Mask: 0x%08X) to 0x%08X - Ignored", m_PC, Value, Mask, Address); break; - case 0x03F8000C: LogMessage("%016llX: Writing 0x%08X (Mask: 0x%08X) to 0x%08X - Ignored", m_PC, Value, Mask, Address); break; - case 0x03F80014: LogMessage("%016llX: Writing 0x%08X (Mask: 0x%08X) to 0x%08X - Ignored", m_PC, Value, Mask, Address); break; + case 0x00: LogMessage("%016llX: Writing 0x%08X (Mask: 0x%08X) to Device[%d].DeviceType", m_PC, Value, Mask, DeviceID); break; + case 0x04: LogMessage("%016llX: Writing 0x%08X (Mask: 0x%08X) to Device[%d].DeviceId", m_PC, Value, Mask, DeviceID); break; + case 0x08: LogMessage("%016llX: Writing 0x%08X (Mask: 0x%08X) to Device[%d].Delay", m_PC, Value, Mask, DeviceID); break; + case 0x0C: LogMessage("%016llX: Writing 0x%08X (Mask: 0x%08X) to Device[%d].Mode", m_PC, Value, Mask, DeviceID); break; + case 0x10: LogMessage("%016llX: Writing 0x%08X (Mask: 0x%08X) to Device[%d].RefreshInterval", m_PC, Value, Mask, DeviceID); break; + case 0x14: LogMessage("%016llX: Writing 0x%08X (Mask: 0x%08X) to Device[%d].RefreshRow", m_PC, Value, Mask, DeviceID); break; + case 0x18: LogMessage("%016llX: Writing 0x%08X (Mask: 0x%08X) to Device[%d].RasInterval", m_PC, Value, Mask, DeviceID); break; + case 0x1C: LogMessage("%016llX: Writing 0x%08X (Mask: 0x%08X) to Device[%d].MinInterval", m_PC, Value, Mask, DeviceID); break; + case 0x20: LogMessage("%016llX: Writing 0x%08X (Mask: 0x%08X) to Device[%d].AddressSelect", m_PC, Value, Mask, DeviceID); break; + case 0x24: LogMessage("%016llX: Writing 0x%08X (Mask: 0x%08X) to Device[%d].DeviceManufacturer", m_PC, Value, Mask, DeviceID); break; + case 0x28: LogMessage("%016llX: Writing 0x%08X (Mask: 0x%08X) to Device[%d].CurrentControl", m_PC, Value, Mask, DeviceID); break; default: if (HaveDebugger()) { @@ -101,24 +104,19 @@ bool RDRAMRegistersHandler::Write32(uint32_t Address, uint32_t Value, uint32_t M } } - switch ((Address & 0x1FFFFFFF)) + switch (Address & 0x3fc) { - case 0x03F00000: RDRAM_CONFIG_REG = (RDRAM_CONFIG_REG & ~Mask) | (Value & Mask); break; - case 0x03F00004: RDRAM_DEVICE_ID_REG = (RDRAM_DEVICE_ID_REG & ~Mask) | (Value & Mask); break; - case 0x03F00008: RDRAM_DELAY_REG = (RDRAM_DELAY_REG & ~Mask) | (Value & Mask); break; - case 0x03F0000C: RDRAM_MODE_REG = (RDRAM_MODE_REG & ~Mask) | (Value & Mask); break; - case 0x03F00010: RDRAM_REF_INTERVAL_REG = (RDRAM_REF_INTERVAL_REG & ~Mask) | (Value & Mask); break; - case 0x03F00014: RDRAM_REF_ROW_REG = (RDRAM_REF_ROW_REG & ~Mask) | (Value & Mask); break; - case 0x03F00018: RDRAM_RAS_INTERVAL_REG = (RDRAM_RAS_INTERVAL_REG & ~Mask) | (Value & Mask); break; - case 0x03F0001C: RDRAM_MIN_INTERVAL_REG = (RDRAM_MIN_INTERVAL_REG & ~Mask) | (Value & Mask); break; - case 0x03F00020: RDRAM_ADDR_SELECT_REG = (RDRAM_ADDR_SELECT_REG & ~Mask) | (Value & Mask); break; - case 0x03F00024: RDRAM_DEVICE_MANUF_REG = (RDRAM_DEVICE_MANUF_REG & ~Mask) | (Value & Mask); break; - case 0x03F04004: break; - case 0x03F08004: break; - case 0x03F80004: break; - case 0x03F80008: break; - case 0x03F8000C: break; - case 0x03F80014: break; + case 0x00: Device.DeviceType = (Device.DeviceType & ~Mask) | (Value & Mask); break; + case 0x04: Device.DeviceId = (Device.DeviceId & ~Mask) | (Value & Mask); break; + case 0x08: Device.Delay = (Device.Delay & ~Mask) | (Value & Mask); break; + case 0x0C: Device.Mode = (Device.Mode & ~Mask) | (Value & Mask); break; + case 0x10: Device.RefreshInterval = (Device.RefreshInterval & ~Mask) | (Value & Mask); break; + case 0x14: Device.RefreshRow = (Device.RefreshRow & ~Mask) | (Value & Mask); break; + case 0x18: Device.RasInterval = (Device.RasInterval & ~Mask) | (Value & Mask); break; + case 0x1C: Device.MinInterval = (Device.MinInterval & ~Mask) | (Value & Mask); break; + case 0x20: Device.AddressSelect = (Device.AddressSelect & ~Mask) | (Value & Mask); break; + case 0x24: Device.DeviceManufacturer = (Device.DeviceManufacturer & ~Mask) | (Value & Mask); break; + case 0x28: Device.CurrentControl = (Device.CurrentControl & ~Mask) | (Value & Mask); break; default: if (HaveDebugger()) { diff --git a/Source/Project64-core/N64System/MemoryHandler/RDRAMRegistersHandler.h b/Source/Project64-core/N64System/MemoryHandler/RDRAMRegistersHandler.h index 899755451..5f07bca15 100644 --- a/Source/Project64-core/N64System/MemoryHandler/RDRAMRegistersHandler.h +++ b/Source/Project64-core/N64System/MemoryHandler/RDRAMRegistersHandler.h @@ -36,6 +36,20 @@ class RDRAMRegistersHandler : private CDebugSettings, private CLogging { + struct RDRAM_DEVICE + { + uint32_t DeviceType; + uint32_t DeviceId; + uint32_t Delay; + uint32_t Mode; + uint32_t RefreshInterval; + uint32_t RefreshRow; + uint32_t RasInterval; + uint32_t MinInterval; + uint32_t AddressSelect; + uint32_t DeviceManufacturer; + uint32_t CurrentControl; + }; public: RDRAMRegistersHandler(CRegisters & Reg); @@ -47,5 +61,6 @@ private: RDRAMRegistersHandler(const RDRAMRegistersHandler &); RDRAMRegistersHandler & operator=(const RDRAMRegistersHandler &); + RDRAM_DEVICE m_Device[4]; uint64_t & m_PC; }; \ No newline at end of file diff --git a/Source/Project64-core/N64System/Mips/Register.cpp b/Source/Project64-core/N64System/Mips/Register.cpp index 719f016b3..ea3ac8bca 100644 --- a/Source/Project64-core/N64System/Mips/Register.cpp +++ b/Source/Project64-core/N64System/Mips/Register.cpp @@ -331,6 +331,11 @@ void CRegisters::Init(void) m_GfxIntrReg = 0; m_RspIntrReg = 0; + RI_MODE_REG = 0x0e; + RI_CONFIG_REG = 0x40; + RI_SELECT_REG = 0x14; + RI_REFRESH_REG = 0x00063634; + FixFpuLocations(); }