diff --git a/Source/Project64-core/Logging.cpp b/Source/Project64-core/Logging.cpp index 2050b2367..558ed9e79 100644 --- a/Source/Project64-core/Logging.cpp +++ b/Source/Project64-core/Logging.cpp @@ -59,29 +59,7 @@ void CLogging::Log_LW(uint32_t PC, uint32_t VAddr) } if (VAddr >= 0xA4400000 && VAddr <= 0xA4400034) { - if (!LogVideoInterface()) - { - return; - } - g_MMU->LW_VAddr(VAddr, Value); - - switch (VAddr) - { - case 0xA4400000: LogMessage("%08X: read from VI_STATUS_REG/VI_CONTROL_REG (%08X)", PC, Value); return; - case 0xA4400004: LogMessage("%08X: read from VI_ORIGIN_REG/VI_DRAM_ADDR_REG (%08X)", PC, Value); return; - case 0xA4400008: LogMessage("%08X: read from VI_WIDTH_REG/VI_H_WIDTH_REG (%08X)", PC, Value); return; - case 0xA440000C: LogMessage("%08X: read from VI_INTR_REG/VI_V_INTR_REG (%08X)", PC, Value); return; - case 0xA4400010: LogMessage("%08X: read from VI_CURRENT_REG/VI_V_CURRENT_LINE_REG (%08X)", PC, Value); return; - case 0xA4400014: LogMessage("%08X: read from VI_BURST_REG/VI_TIMING_REG (%08X)", PC, Value); return; - case 0xA4400018: LogMessage("%08X: read from VI_V_SYNC_REG (%08X)", PC, Value); return; - case 0xA440001C: LogMessage("%08X: read from VI_H_SYNC_REG (%08X)", PC, Value); return; - case 0xA4400020: LogMessage("%08X: read from VI_LEAP_REG/VI_H_SYNC_LEAP_REG (%08X)", PC, Value); return; - case 0xA4400024: LogMessage("%08X: read from VI_H_START_REG/VI_H_VIDEO_REG (%08X)", PC, Value); return; - case 0xA4400028: LogMessage("%08X: read from VI_V_START_REG/VI_V_VIDEO_REG (%08X)", PC, Value); return; - case 0xA440002C: LogMessage("%08X: read from VI_V_BURST_REG (%08X)", PC, Value); return; - case 0xA4400030: LogMessage("%08X: read from VI_X_SCALE_REG (%08X)", PC, Value); return; - case 0xA4400034: LogMessage("%08X: read from VI_Y_SCALE_REG (%08X)", PC, Value); return; - } + return; } if (VAddr >= 0xA4500000 && VAddr <= 0xA4500014) { @@ -253,27 +231,7 @@ void CLogging::Log_SW(uint32_t PC, uint32_t VAddr, uint32_t Value) } if (VAddr >= 0xA4400000 && VAddr <= 0xA4400034) { - if (!LogVideoInterface()) - { - return; - } - switch (VAddr) - { - case 0xA4400000: LogMessage("%08X: Writing 0x%08X to VI_STATUS_REG/VI_CONTROL_REG", PC, Value); return; - case 0xA4400004: LogMessage("%08X: Writing 0x%08X to VI_ORIGIN_REG/VI_DRAM_ADDR_REG", PC, Value); return; - case 0xA4400008: LogMessage("%08X: Writing 0x%08X to VI_WIDTH_REG/VI_H_WIDTH_REG", PC, Value); return; - case 0xA440000C: LogMessage("%08X: Writing 0x%08X to VI_INTR_REG/VI_V_INTR_REG", PC, Value); return; - case 0xA4400010: LogMessage("%08X: Writing 0x%08X to VI_CURRENT_REG/VI_V_CURRENT_LINE_REG", PC, Value); return; - case 0xA4400014: LogMessage("%08X: Writing 0x%08X to VI_BURST_REG/VI_TIMING_REG", PC, Value); return; - case 0xA4400018: LogMessage("%08X: Writing 0x%08X to VI_V_SYNC_REG", PC, Value); return; - case 0xA440001C: LogMessage("%08X: Writing 0x%08X to VI_H_SYNC_REG", PC, Value); return; - case 0xA4400020: LogMessage("%08X: Writing 0x%08X to VI_LEAP_REG/VI_H_SYNC_LEAP_REG", PC, Value); return; - case 0xA4400024: LogMessage("%08X: Writing 0x%08X to VI_H_START_REG/VI_H_VIDEO_REG", PC, Value); return; - case 0xA4400028: LogMessage("%08X: Writing 0x%08X to VI_V_START_REG/VI_V_VIDEO_REG", PC, Value); return; - case 0xA440002C: LogMessage("%08X: Writing 0x%08X to VI_V_BURST_REG", PC, Value); return; - case 0xA4400030: LogMessage("%08X: Writing 0x%08X to VI_X_SCALE_REG", PC, Value); return; - case 0xA4400034: LogMessage("%08X: Writing 0x%08X to VI_Y_SCALE_REG", PC, Value); return; - } + return; } if (VAddr >= 0xA4500000 && VAddr <= 0xA4500014) diff --git a/Source/Project64-core/N64System/MemoryHandler/VideoInterfaceHandler.cpp b/Source/Project64-core/N64System/MemoryHandler/VideoInterfaceHandler.cpp new file mode 100644 index 000000000..c3606081e --- /dev/null +++ b/Source/Project64-core/N64System/MemoryHandler/VideoInterfaceHandler.cpp @@ -0,0 +1,216 @@ +#include "stdafx.h" +#include "VideoInterfaceHandler.h" +#include +#include +#include +#include +#include + +VideoInterfaceReg::VideoInterfaceReg(uint32_t * VideoInterface) : + VI_STATUS_REG(VideoInterface[0]), + VI_CONTROL_REG(VideoInterface[0]), + VI_ORIGIN_REG(VideoInterface[1]), + VI_DRAM_ADDR_REG(VideoInterface[1]), + VI_WIDTH_REG(VideoInterface[2]), + VI_H_WIDTH_REG(VideoInterface[2]), + VI_INTR_REG(VideoInterface[3]), + VI_V_INTR_REG(VideoInterface[3]), + VI_CURRENT_REG(VideoInterface[4]), + VI_V_CURRENT_LINE_REG(VideoInterface[4]), + VI_BURST_REG(VideoInterface[5]), + VI_TIMING_REG(VideoInterface[5]), + VI_V_SYNC_REG(VideoInterface[6]), + VI_H_SYNC_REG(VideoInterface[7]), + VI_LEAP_REG(VideoInterface[8]), + VI_H_SYNC_LEAP_REG(VideoInterface[8]), + VI_H_START_REG(VideoInterface[9]), + VI_H_VIDEO_REG(VideoInterface[9]), + VI_V_START_REG(VideoInterface[10]), + VI_V_VIDEO_REG(VideoInterface[10]), + VI_V_BURST_REG(VideoInterface[11]), + VI_X_SCALE_REG(VideoInterface[12]), + VI_Y_SCALE_REG(VideoInterface[13]) +{ +} + +VideoInterfaceHandler::VideoInterfaceHandler(CMipsMemoryVM & MMU, CPlugins * Plugins, CRegisters & Reg, CSystemTimer & SystemTimer, int32_t & NextTimer) : + VideoInterfaceReg(Reg.m_Video_Interface), + m_MMU(MMU), + m_Plugins(Plugins), + m_Reg(Reg), + m_SystemTimer(SystemTimer), + m_NextTimer(NextTimer), + m_PC(Reg.m_PROGRAM_COUNTER), + m_FieldSerration(0), + m_HalfLine(0), + m_HalfLineCheck(false) +{ +} + +bool VideoInterfaceHandler::Read32(uint32_t Address, uint32_t & Value) +{ + switch (Address & 0x1FFFFFFF) + { + case 0x04400000: Value = VI_STATUS_REG; break; + case 0x04400004: Value = VI_ORIGIN_REG; break; + case 0x04400008: Value = VI_WIDTH_REG; break; + case 0x0440000C: Value = VI_INTR_REG; break; + case 0x04400010: + UpdateHalfLine(); + Value = m_HalfLine; + break; + case 0x04400014: Value = VI_BURST_REG; break; + case 0x04400018: Value = VI_V_SYNC_REG; break; + case 0x0440001C: Value = VI_H_SYNC_REG; break; + case 0x04400020: Value = VI_LEAP_REG; break; + case 0x04400024: Value = VI_H_START_REG; break; + case 0x04400028: Value = VI_V_START_REG; break; + case 0x0440002C: Value = VI_V_BURST_REG; break; + case 0x04400030: Value = VI_X_SCALE_REG; break; + case 0x04400034: Value = VI_Y_SCALE_REG; break; + default: + Value = 0; + if (HaveDebugger()) + { + g_Notify->BreakPoint(__FILE__, __LINE__); + } + } + + if (LogVideoInterface()) + { + switch (Address & 0x1FFFFFFF) + { + case 0x04400000: LogMessage("%08X: read from VI_STATUS_REG/VI_CONTROL_REG (%08X)", m_PC, Value); break; + case 0x04400004: LogMessage("%08X: read from VI_ORIGIN_REG/VI_DRAM_ADDR_REG (%08X)", m_PC, Value); break; + case 0x04400008: LogMessage("%08X: read from VI_WIDTH_REG/VI_H_WIDTH_REG (%08X)", m_PC, Value); break; + case 0x0440000C: LogMessage("%08X: read from VI_INTR_REG/VI_V_INTR_REG (%08X)", m_PC, Value); break; + case 0x04400010: LogMessage("%08X: read from VI_CURRENT_REG/VI_V_CURRENT_LINE_REG (%08X)", m_PC, Value); break; + case 0x04400014: LogMessage("%08X: read from VI_BURST_REG/VI_TIMING_REG (%08X)", m_PC, Value); break; + case 0x04400018: LogMessage("%08X: read from VI_V_SYNC_REG (%08X)", m_PC, Value); break; + case 0x0440001C: LogMessage("%08X: read from VI_H_SYNC_REG (%08X)", m_PC, Value); break; + case 0x04400020: LogMessage("%08X: read from VI_LEAP_REG/VI_H_SYNC_LEAP_REG (%08X)", m_PC, Value); break; + case 0x04400024: LogMessage("%08X: read from VI_H_START_REG/VI_H_VIDEO_REG (%08X)", m_PC, Value); break; + case 0x04400028: LogMessage("%08X: read from VI_V_START_REG/VI_V_VIDEO_REG (%08X)", m_PC, Value); break; + case 0x0440002C: LogMessage("%08X: read from VI_V_BURST_REG (%08X)", m_PC, Value); break; + case 0x04400030: LogMessage("%08X: read from VI_X_SCALE_REG (%08X)", m_PC, Value); break; + case 0x04400034: LogMessage("%08X: read from VI_Y_SCALE_REG (%08X)", m_PC, Value); break; + default: + if (HaveDebugger()) + { + g_Notify->BreakPoint(__FILE__, __LINE__); + } + } + } + return true; +} + +bool VideoInterfaceHandler::Write32(uint32_t Address, uint32_t Value, uint32_t Mask) +{ + if (LogVideoInterface()) + { + switch (Address & 0x1FFFFFFF) + { + case 0x04400000: LogMessage("%08X: Writing 0x%08X (Mask: 0x%08X) to VI_STATUS_REG/VI_CONTROL_REG", m_PC, Value, Mask); break; + case 0x04400004: LogMessage("%08X: Writing 0x%08X (Mask: 0x%08X) to VI_ORIGIN_REG/VI_DRAM_ADDR_REG", m_PC, Value, Mask); break; + case 0x04400008: LogMessage("%08X: Writing 0x%08X (Mask: 0x%08X) to VI_WIDTH_REG/VI_H_WIDTH_REG", m_PC, Value, Mask); break; + case 0x0440000C: LogMessage("%08X: Writing 0x%08X (Mask: 0x%08X) to VI_INTR_REG/VI_V_INTR_REG", m_PC, Value, Mask); break; + case 0x04400010: LogMessage("%08X: Writing 0x%08X (Mask: 0x%08X) to VI_CURRENT_REG/VI_V_CURRENT_LINE_REG", m_PC, Value, Mask); break; + case 0x04400014: LogMessage("%08X: Writing 0x%08X (Mask: 0x%08X) to VI_BURST_REG/VI_TIMING_REG", m_PC, Value, Mask); break; + case 0x04400018: LogMessage("%08X: Writing 0x%08X (Mask: 0x%08X) to VI_V_SYNC_REG", m_PC, Value, Mask); break; + case 0x0440001C: LogMessage("%08X: Writing 0x%08X (Mask: 0x%08X) to VI_H_SYNC_REG", m_PC, Value, Mask); break; + case 0x04400020: LogMessage("%08X: Writing 0x%08X (Mask: 0x%08X) to VI_LEAP_REG/VI_H_SYNC_LEAP_REG", m_PC, Value, Mask); break; + case 0x04400024: LogMessage("%08X: Writing 0x%08X (Mask: 0x%08X) to VI_H_START_REG/VI_H_VIDEO_REG", m_PC, Value, Mask); break; + case 0x04400028: LogMessage("%08X: Writing 0x%08X (Mask: 0x%08X) to VI_V_START_REG/VI_V_VIDEO_REG", m_PC, Value, Mask); break; + case 0x0440002C: LogMessage("%08X: Writing 0x%08X (Mask: 0x%08X) to VI_V_BURST_REG", m_PC, Value, Mask); break; + case 0x04400030: LogMessage("%08X: Writing 0x%08X (Mask: 0x%08X) to VI_X_SCALE_REG", m_PC, Value, Mask); break; + case 0x04400034: LogMessage("%08X: Writing 0x%08X (Mask: 0x%08X) to VI_Y_SCALE_REG", m_PC, Value, Mask); break; + default: + if (HaveDebugger()) + { + g_Notify->BreakPoint(__FILE__, __LINE__); + } + } + } + + uint32_t MaskedValue = Value & Mask; + switch (Address & 0xFFFFFFF) + { + case 0x04400000: + if (VI_STATUS_REG != ((VI_STATUS_REG & ~Mask) | (MaskedValue))) + { + VI_STATUS_REG = (VI_STATUS_REG & ~Mask) | (MaskedValue); + if (m_Plugins->Gfx()->ViStatusChanged != nullptr) + { + m_Plugins->Gfx()->ViStatusChanged(); + } + } + break; + case 0x04400004: + VI_ORIGIN_REG = ((VI_ORIGIN_REG & ~Mask) | (MaskedValue)) & 0xFFFFFF; + break; + case 0x04400008: + if (VI_WIDTH_REG != ((VI_WIDTH_REG & ~Mask) | (MaskedValue))) + { + VI_WIDTH_REG = (VI_WIDTH_REG & ~Mask) | (MaskedValue); + if (m_Plugins->Gfx()->ViWidthChanged != nullptr) + { + m_Plugins->Gfx()->ViWidthChanged(); + } + } + break; + case 0x0440000C: VI_INTR_REG = (VI_INTR_REG & ~Mask) | (MaskedValue); break; + case 0x04400010: + m_Reg.MI_INTR_REG &= ~MI_INTR_VI; + m_Reg.CheckInterrupts(); + break; + case 0x04400014: VI_BURST_REG = (VI_BURST_REG & ~Mask) | (MaskedValue); break; + case 0x04400018: VI_V_SYNC_REG = (VI_V_SYNC_REG & ~Mask) | (MaskedValue); break; + case 0x0440001C: VI_H_SYNC_REG = (VI_H_SYNC_REG & ~Mask) | (MaskedValue); break; + case 0x04400020: VI_LEAP_REG = (VI_LEAP_REG & ~Mask) | (MaskedValue); break; + case 0x04400024: VI_H_START_REG = (VI_H_START_REG & ~Mask) | (MaskedValue); break; + case 0x04400028: VI_V_START_REG = (VI_V_START_REG & ~Mask) | (MaskedValue); break; + case 0x0440002C: VI_V_BURST_REG = (VI_V_BURST_REG & ~Mask) | (MaskedValue); break; + case 0x04400030: VI_X_SCALE_REG = (VI_X_SCALE_REG & ~Mask) | (MaskedValue); break; + case 0x04400034: VI_Y_SCALE_REG = (VI_Y_SCALE_REG & ~Mask) | (MaskedValue); break; + default: + if (HaveDebugger()) + { + g_Notify->BreakPoint(__FILE__, __LINE__); + } + } + return true; +} + +void VideoInterfaceHandler::UpdateFieldSerration(uint32_t interlaced) +{ + m_FieldSerration ^= 1; + m_FieldSerration &= interlaced; +} + +void VideoInterfaceHandler::UpdateHalfLine() +{ + uint32_t NextViTimer = m_SystemTimer.GetTimer(CSystemTimer::ViTimer); + + if (m_NextTimer < 0) + { + m_HalfLine = 0; + return; + } + + int32_t check_value = (int32_t)(m_HalfLineCheck - NextViTimer); + if (check_value > 0 && check_value < 40) + { + m_NextTimer -= ViRefreshRate(); + if (m_NextTimer < 0) + { + m_NextTimer = 0 - CountPerOp(); + } + m_SystemTimer.UpdateTimers(); + NextViTimer = m_SystemTimer.GetTimer(CSystemTimer::ViTimer); + } + m_HalfLine = (uint32_t)(m_NextTimer / ViRefreshRate()); + m_HalfLine &= ~1; + m_HalfLine |= m_FieldSerration; + VI_V_CURRENT_LINE_REG = m_HalfLine; + m_HalfLineCheck = NextViTimer; +} \ No newline at end of file diff --git a/Source/Project64-core/N64System/MemoryHandler/VideoInterfaceHandler.h b/Source/Project64-core/N64System/MemoryHandler/VideoInterfaceHandler.h new file mode 100644 index 000000000..75609ecba --- /dev/null +++ b/Source/Project64-core/N64System/MemoryHandler/VideoInterfaceHandler.h @@ -0,0 +1,79 @@ +#pragma once +#include "MemoryHandler.h" +#include +#include +#include +#include + +class VideoInterfaceReg +{ +protected: + VideoInterfaceReg(uint32_t * VideoInterface); + +public: + uint32_t & VI_STATUS_REG; + uint32_t & VI_CONTROL_REG; + uint32_t & VI_ORIGIN_REG; + uint32_t & VI_DRAM_ADDR_REG; + uint32_t & VI_WIDTH_REG; + uint32_t & VI_H_WIDTH_REG; + uint32_t & VI_INTR_REG; + uint32_t & VI_V_INTR_REG; + uint32_t & VI_CURRENT_REG; + uint32_t & VI_V_CURRENT_LINE_REG; + uint32_t & VI_BURST_REG; + uint32_t & VI_TIMING_REG; + uint32_t & VI_V_SYNC_REG; + uint32_t & VI_H_SYNC_REG; + uint32_t & VI_LEAP_REG; + uint32_t & VI_H_SYNC_LEAP_REG; + uint32_t & VI_H_START_REG; + uint32_t & VI_H_VIDEO_REG; + uint32_t & VI_V_START_REG; + uint32_t & VI_V_VIDEO_REG; + uint32_t & VI_V_BURST_REG; + uint32_t & VI_X_SCALE_REG; + uint32_t & VI_Y_SCALE_REG; + +private: + VideoInterfaceReg(); + VideoInterfaceReg(const VideoInterfaceReg&); + VideoInterfaceReg& operator=(const VideoInterfaceReg&); +}; + +class CMipsMemoryVM; +class CPlugins; +class CRegisters; +class CSystemTimer; + +class VideoInterfaceHandler : + public MemoryHandler, + public VideoInterfaceReg, + private CGameSettings, + private CDebugSettings, + private CLogging +{ +public: + VideoInterfaceHandler(CMipsMemoryVM & MMU, CPlugins * Plugins, CRegisters & Reg, CSystemTimer & SystemTimer, int32_t & NextTimer); + + void UpdateFieldSerration(uint32_t interlaced); + bool Read32(uint32_t Address, uint32_t & Value); + bool Write32(uint32_t Address, uint32_t Value, uint32_t Mask); + +private: + VideoInterfaceHandler(); + VideoInterfaceHandler(const VideoInterfaceHandler &); + VideoInterfaceHandler & operator=(const VideoInterfaceHandler &); + + void UpdateHalfLine(); + + uint32_t m_FieldSerration; + uint32_t m_HalfLine; + uint32_t m_HalfLineCheck; + CMipsMemoryVM & m_MMU; + CPlugins * m_Plugins; + CRegisters & m_Reg; + CSystemTimer & m_SystemTimer; + int32_t & m_NextTimer; + uint32_t & m_PC; +}; \ No newline at end of file diff --git a/Source/Project64-core/N64System/Mips/MemoryVirtualMem.cpp b/Source/Project64-core/N64System/Mips/MemoryVirtualMem.cpp index b8753dc7b..9a055e25e 100755 --- a/Source/Project64-core/N64System/Mips/MemoryVirtualMem.cpp +++ b/Source/Project64-core/N64System/Mips/MemoryVirtualMem.cpp @@ -34,13 +34,11 @@ CMipsMemoryVM::CMipsMemoryVM(CN64System & System, CRegisters & Reg, bool SavesRe m_PeripheralInterfaceHandler(*this, Reg), m_RDRAMInterfaceHandler(Reg), m_SPRegistersHandler(System, *this, Reg), + m_VideoInterfaceHandler(*this, System.GetPlugins(), Reg, System.m_SystemTimer, System.m_NextTimer), m_Rom(nullptr), m_RomSize(0), m_RomWrittenTo(false), m_RomWroteValue(0), - m_HalfLine(0), - m_HalfLineCheck(false), - m_FieldSerration(0), m_TLB_ReadMap(nullptr), m_TLB_WriteMap(nullptr), m_RDRAM(nullptr), @@ -646,7 +644,7 @@ bool CMipsMemoryVM::LW_NonMemory(uint32_t PAddr, uint32_t* Value) case 0x04000000: m_SPRegistersHandler.Read32(PAddr, m_MemLookupValue.UW[0]); break; case 0x04100000: m_DPCommandRegistersHandler.Read32(PAddr, m_MemLookupValue.UW[0]); break; case 0x04300000: m_MIPSInterfaceHandler.Read32(PAddr, m_MemLookupValue.UW[0]); break; - case 0x04400000: Load32VideoInterface(); break; + case 0x04400000: m_VideoInterfaceHandler.Read32(PAddr, m_MemLookupValue.UW[0]); break; case 0x04500000: Load32AudioInterface(); break; case 0x04600000: m_PeripheralInterfaceHandler.Read32(PAddr, m_MemLookupValue.UW[0]); break; case 0x04700000: m_RDRAMInterfaceHandler.Read32(PAddr, m_MemLookupValue.UW[0]); break; @@ -766,7 +764,7 @@ bool CMipsMemoryVM::SW_NonMemory(uint32_t PAddr, uint32_t Value) break; case 0x04100000: m_DPCommandRegistersHandler.Write32(PAddr, Value, 0xFFFFFFFF); break; case 0x04300000: m_MIPSInterfaceHandler.Write32(PAddr, Value, 0xFFFFFFFF); break; - case 0x04400000: Write32VideoInterface(); break; + case 0x04400000: m_VideoInterfaceHandler.Write32(PAddr, Value, 0xFFFFFFFF); break; case 0x04500000: Write32AudioInterface(); break; case 0x04600000: m_PeripheralInterfaceHandler.Write32(PAddr, Value, 0xFFFFFFFF); break; case 0x04700000: m_RDRAMInterfaceHandler.Write32(PAddr, Value, 0xFFFFFFFF); break; @@ -782,40 +780,6 @@ bool CMipsMemoryVM::SW_NonMemory(uint32_t PAddr, uint32_t Value) 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); @@ -1121,36 +1085,6 @@ void CMipsMemoryVM::ChangeMiIntrMask() } } -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) @@ -1350,55 +1284,6 @@ void CMipsMemoryVM::Load32Rom(void) } } -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 != nullptr) - { - g_Plugins->Gfx()->ViStatusChanged(); - } - } - break; - case 0x04400004: - g_Reg->VI_ORIGIN_REG = (m_MemLookupValue.UW[0] & 0xFFFFFF); - 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 != nullptr) - { - 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) diff --git a/Source/Project64-core/N64System/Mips/MemoryVirtualMem.h b/Source/Project64-core/N64System/Mips/MemoryVirtualMem.h index 8f12de14e..cd55e87e5 100644 --- a/Source/Project64-core/N64System/Mips/MemoryVirtualMem.h +++ b/Source/Project64-core/N64System/Mips/MemoryVirtualMem.h @@ -13,6 +13,7 @@ #include #include #include +#include #include #ifdef __arm__ @@ -90,7 +91,6 @@ public: bool SD_PAddr(uint32_t PAddr, uint64_t Value); int32_t MemoryFilter(uint32_t dwExptCode, void * lpExceptionPointer); - void UpdateFieldSerration(uint32_t interlaced); #ifndef _WIN32 static bool SetupSegvHandler(void); @@ -113,6 +113,8 @@ public: // Labels const char * LabelName(uint32_t Address) const; + VideoInterfaceHandler & VideoInterface(void) { return m_VideoInterfaceHandler; } + private: CMipsMemoryVM(); CMipsMemoryVM(const CMipsMemoryVM&); @@ -137,7 +139,6 @@ private: bool SH_NonMemory(uint32_t PAddr, uint16_t Value); bool SW_NonMemory(uint32_t PAddr, uint32_t Value); - static void Load32VideoInterface(void); static void Load32AudioInterface(void); static void Load32SerialInterface(void); static void Load32CartridgeDomain1Address1(void); @@ -147,7 +148,6 @@ private: static void Load32PifRam(void); static void Load32Rom(void); - static void Write32VideoInterface(void); static void Write32AudioInterface(void); static void Write32SerialInterface(void); static void Write32CartridgeDomain2Address1(void); @@ -175,7 +175,6 @@ private: static void DumpArmExceptionInfo(uint32_t MemAddress, mcontext_t & context); static bool FilterArmException(uint32_t MemAddress, mcontext_t & context); #endif - void UpdateHalfLine(); void FreeMemory(); static uint8_t * m_Reserve1, *m_Reserve2; @@ -186,6 +185,7 @@ private: RDRAMInterfaceHandler m_RDRAMInterfaceHandler; RDRAMRegistersHandler m_RDRAMRegistersHandler; SPRegistersHandler m_SPRegistersHandler; + VideoInterfaceHandler m_VideoInterfaceHandler; uint8_t * m_RDRAM, *m_DMEM, *m_IMEM; uint32_t m_AllocatedRdramSize; bool m_RomMapped; @@ -196,9 +196,6 @@ private: bool m_DDRomMapped; uint8_t * m_DDRom; uint32_t m_DDRomSize; - uint32_t m_HalfLine; - uint32_t m_HalfLineCheck; - uint32_t m_FieldSerration; mutable char m_strLabelName[100]; size_t * m_TLB_ReadMap; diff --git a/Source/Project64-core/N64System/Mips/Register.cpp b/Source/Project64-core/N64System/Mips/Register.cpp index accc98807..eb6137531 100644 --- a/Source/Project64-core/N64System/Mips/Register.cpp +++ b/Source/Project64-core/N64System/Mips/Register.cpp @@ -75,33 +75,6 @@ CP0registers::CP0registers(uint32_t * _CP0) : { } -Video_InterfaceReg::Video_InterfaceReg(uint32_t * _VideoInterface) : - VI_STATUS_REG(_VideoInterface[0]), - VI_CONTROL_REG(_VideoInterface[0]), - VI_ORIGIN_REG(_VideoInterface[1]), - VI_DRAM_ADDR_REG(_VideoInterface[1]), - VI_WIDTH_REG(_VideoInterface[2]), - VI_H_WIDTH_REG(_VideoInterface[2]), - VI_INTR_REG(_VideoInterface[3]), - VI_V_INTR_REG(_VideoInterface[3]), - VI_CURRENT_REG(_VideoInterface[4]), - VI_V_CURRENT_LINE_REG(_VideoInterface[4]), - VI_BURST_REG(_VideoInterface[5]), - VI_TIMING_REG(_VideoInterface[5]), - VI_V_SYNC_REG(_VideoInterface[6]), - VI_H_SYNC_REG(_VideoInterface[7]), - VI_LEAP_REG(_VideoInterface[8]), - VI_H_SYNC_LEAP_REG(_VideoInterface[8]), - VI_H_START_REG(_VideoInterface[9]), - VI_H_VIDEO_REG(_VideoInterface[9]), - VI_V_START_REG(_VideoInterface[10]), - VI_V_VIDEO_REG(_VideoInterface[10]), - VI_V_BURST_REG(_VideoInterface[11]), - VI_X_SCALE_REG(_VideoInterface[12]), - VI_Y_SCALE_REG(_VideoInterface[13]) -{ -} - AudioInterfaceReg::AudioInterfaceReg(uint32_t * _AudioInterface) : AI_DRAM_ADDR_REG(_AudioInterface[0]), AI_LEN_REG(_AudioInterface[1]), @@ -162,7 +135,7 @@ CRegisters::CRegisters(CN64System * System, CSystemEvents * SystemEvents) : CP0registers(m_CP0), RDRAMRegistersReg(m_RDRAM_Registers), MIPSInterfaceReg(m_Mips_Interface), - Video_InterfaceReg(m_Video_Interface), + VideoInterfaceReg(m_Video_Interface), AudioInterfaceReg(m_Audio_Interface), PeripheralInterfaceReg(m_Peripheral_Interface), RDRAMInterfaceReg(m_RDRAM_Interface), diff --git a/Source/Project64-core/N64System/Mips/Register.h b/Source/Project64-core/N64System/Mips/Register.h index 41fd4b96f..f0b72dec1 100644 --- a/Source/Project64-core/N64System/Mips/Register.h +++ b/Source/Project64-core/N64System/Mips/Register.h @@ -8,6 +8,7 @@ #include #include #include +#include #include #include #include @@ -162,43 +163,6 @@ enum MI_INTR_DP = 0x20, // Bit 5: DP INTR }; -// MIPS interface registers -class Video_InterfaceReg -{ -protected: - Video_InterfaceReg (uint32_t * _VideoInterface); - -public: - uint32_t & VI_STATUS_REG; - uint32_t & VI_CONTROL_REG; - uint32_t & VI_ORIGIN_REG; - uint32_t & VI_DRAM_ADDR_REG; - uint32_t & VI_WIDTH_REG; - uint32_t & VI_H_WIDTH_REG; - uint32_t & VI_INTR_REG; - uint32_t & VI_V_INTR_REG; - uint32_t & VI_CURRENT_REG; - uint32_t & VI_V_CURRENT_LINE_REG; - uint32_t & VI_BURST_REG; - uint32_t & VI_TIMING_REG; - uint32_t & VI_V_SYNC_REG; - uint32_t & VI_H_SYNC_REG; - uint32_t & VI_LEAP_REG; - uint32_t & VI_H_SYNC_LEAP_REG; - uint32_t & VI_H_START_REG; - uint32_t & VI_H_VIDEO_REG; - uint32_t & VI_V_START_REG; - uint32_t & VI_V_VIDEO_REG; - uint32_t & VI_V_BURST_REG; - uint32_t & VI_X_SCALE_REG; - uint32_t & VI_Y_SCALE_REG; - -private: - Video_InterfaceReg(); - Video_InterfaceReg(const Video_InterfaceReg&); - Video_InterfaceReg& operator=(const Video_InterfaceReg&); -}; - // Audio interface registers class AudioInterfaceReg { @@ -412,7 +376,7 @@ class CRegisters : public CP0registers, public RDRAMRegistersReg, public MIPSInterfaceReg, - public Video_InterfaceReg, + public VideoInterfaceReg, public AudioInterfaceReg, public PeripheralInterfaceReg, public RDRAMInterfaceReg, diff --git a/Source/Project64-core/N64System/N64System.cpp b/Source/Project64-core/N64System/N64System.cpp index ad4b4f832..4ecaaca47 100644 --- a/Source/Project64-core/N64System/N64System.cpp +++ b/Source/Project64-core/N64System/N64System.cpp @@ -2438,7 +2438,7 @@ void CN64System::RefreshScreen() { WriteTrace(TraceGFXPlugin, TraceError, "Exception caught"); } - g_MMU->UpdateFieldSerration((m_Reg.VI_STATUS_REG & 0x40) != 0); + g_MMU->VideoInterface().UpdateFieldSerration((m_Reg.VI_STATUS_REG & 0x40) != 0); if ((bBasicMode() || bLimitFPS()) && (!bSyncToAudio() || !FullSpeed())) { diff --git a/Source/Project64-core/N64System/Recompiler/x86/x86RecompilerOps.cpp b/Source/Project64-core/N64System/Recompiler/x86/x86RecompilerOps.cpp index 59abbb814..e9a115bee 100644 --- a/Source/Project64-core/N64System/Recompiler/x86/x86RecompilerOps.cpp +++ b/Source/Project64-core/N64System/Recompiler/x86/x86RecompilerOps.cpp @@ -3224,20 +3224,26 @@ void CX86RecompilerOps::LW_KnownAddress(x86Reg Reg, uint32_t VAddr) 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()); - m_RegWorkingSet.BeforeCallDirect(); + { + m_RegWorkingSet.SetBlockCycleCount(m_RegWorkingSet.GetBlockCycleCount() - g_System->CountPerOp()); + UpdateCounters(m_RegWorkingSet, false, true); + m_RegWorkingSet.SetBlockCycleCount(m_RegWorkingSet.GetBlockCycleCount() + g_System->CountPerOp()); + + static uint32_t TempValue = 0; + m_RegWorkingSet.BeforeCallDirect(); + PushImm32("TempValue", (uint32_t)&TempValue); + PushImm32(PAddr & 0x1FFFFFFF); #ifdef _MSC_VER - MoveConstToX86reg((uint32_t)g_MMU, x86_ECX); - Call_Direct(AddressOf(&CMipsMemoryVM::UpdateHalfLine), "CMipsMemoryVM::UpdateHalfLine"); + MoveConstToX86reg((uint32_t)(MemoryHandler *)&g_MMU->m_VideoInterfaceHandler, x86_ECX); + Call_Direct((void *)((long**)(MemoryHandler *)&g_MMU->m_VideoInterfaceHandler)[0][0], "VideoInterfaceHandler::Read32"); #else - PushImm32((uint32_t)g_MMU); - Call_Direct(AddressOf(&CMipsMemoryVM::UpdateHalfLine), "CMipsMemoryVM::UpdateHalfLine"); - AddConstToX86Reg(x86_ESP, 4); + PushImm32((uint32_t)&g_MMU->m_VideoInterfaceHandler); + Call_Direct(AddressOf(&SPRegistersHandler::Read32), "SPRegistersHandler::Read32"); + AddConstToX86Reg(x86_ESP, 16); #endif - m_RegWorkingSet.AfterCallDirect(); - MoveVariableToX86reg((void *)&g_MMU->m_HalfLine, "MMU->m_HalfLine", Reg); + m_RegWorkingSet.AfterCallDirect(); + MoveVariableToX86reg(&m_TempValue, "m_TempValue", Reg); + } break; default: MoveConstToX86reg(0, Reg); diff --git a/Source/Project64-core/Project64-core.vcxproj b/Source/Project64-core/Project64-core.vcxproj index 56f745490..c653dba68 100644 --- a/Source/Project64-core/Project64-core.vcxproj +++ b/Source/Project64-core/Project64-core.vcxproj @@ -59,6 +59,7 @@ + @@ -161,6 +162,7 @@ + diff --git a/Source/Project64-core/Project64-core.vcxproj.filters b/Source/Project64-core/Project64-core.vcxproj.filters index c1398d52d..da8c4bb98 100644 --- a/Source/Project64-core/Project64-core.vcxproj.filters +++ b/Source/Project64-core/Project64-core.vcxproj.filters @@ -375,6 +375,9 @@ Source Files\N64 System\MemoryHandler + + Source Files\N64 System\MemoryHandler + @@ -716,6 +719,9 @@ Header Files\N64 System\MemoryHandler + + Header Files\N64 System\MemoryHandler +