From 0683b9fa0e63e32870b1511fd27868dc17d527fb Mon Sep 17 00:00:00 2001 From: Connor McLaughlin Date: Wed, 11 Jan 2023 19:01:20 +1000 Subject: [PATCH] InterruptController: Convert to namespace --- src/core/bus.cpp | 4 +- src/core/cdrom.cpp | 2 +- src/core/dma.cpp | 2 +- src/core/gpu.cpp | 2 +- src/core/gpu_commands.cpp | 2 +- src/core/interrupt_controller.cpp | 41 ++++++++++------ src/core/interrupt_controller.h | 79 +++++++++++++------------------ src/core/pad.cpp | 2 +- src/core/spu.cpp | 2 +- src/core/system.cpp | 8 ++-- src/core/timers.cpp | 2 +- 11 files changed, 71 insertions(+), 75 deletions(-) diff --git a/src/core/bus.cpp b/src/core/bus.cpp index 534b3ed30..776191e5a 100644 --- a/src/core/bus.cpp +++ b/src/core/bus.cpp @@ -1233,13 +1233,13 @@ ALWAYS_INLINE static TickCount DoAccessInterruptController(u32 offset, u32& valu { if constexpr (type == MemoryAccessType::Read) { - value = g_interrupt_controller.ReadRegister(FIXUP_WORD_OFFSET(size, offset)); + value = InterruptController::ReadRegister(FIXUP_WORD_OFFSET(size, offset)); value = FIXUP_WORD_READ_VALUE(size, offset, value); return 2; } else { - g_interrupt_controller.WriteRegister(FIXUP_WORD_OFFSET(size, offset), FIXUP_WORD_WRITE_VALUE(size, offset, value)); + InterruptController::WriteRegister(FIXUP_WORD_OFFSET(size, offset), FIXUP_WORD_WRITE_VALUE(size, offset, value)); return 0; } } diff --git a/src/core/cdrom.cpp b/src/core/cdrom.cpp index 7e3a1b5d5..04a225bd5 100644 --- a/src/core/cdrom.cpp +++ b/src/core/cdrom.cpp @@ -1180,7 +1180,7 @@ void CDROM::UpdateInterruptRequest() if ((s_interrupt_flag_register & s_interrupt_enable_register) == 0) return; - g_interrupt_controller.InterruptRequest(InterruptController::IRQ::CDROM); + InterruptController::InterruptRequest(InterruptController::IRQ::CDROM); } bool CDROM::HasPendingDiscEvent() diff --git a/src/core/dma.cpp b/src/core/dma.cpp index 05e12424c..72715d10f 100644 --- a/src/core/dma.cpp +++ b/src/core/dma.cpp @@ -430,7 +430,7 @@ void DMA::UpdateIRQ() if (s_DICR.master_flag) { Log_TracePrintf("Firing DMA master interrupt"); - g_interrupt_controller.InterruptRequest(InterruptController::IRQ::DMA); + InterruptController::InterruptRequest(InterruptController::IRQ::DMA); } } diff --git a/src/core/gpu.cpp b/src/core/gpu.cpp index 51b6e4b84..9781eb35e 100644 --- a/src/core/gpu.cpp +++ b/src/core/gpu.cpp @@ -898,7 +898,7 @@ void GPU::CRTCTickEvent(TickCount ticks) if (new_vblank) { Log_DebugPrintf("Now in v-blank"); - g_interrupt_controller.InterruptRequest(InterruptController::IRQ::VBLANK); + InterruptController::InterruptRequest(InterruptController::IRQ::VBLANK); // flush any pending draws and "scan out" the image FlushRender(); diff --git a/src/core/gpu_commands.cpp b/src/core/gpu_commands.cpp index 7b301db13..7187b3fd5 100644 --- a/src/core/gpu_commands.cpp +++ b/src/core/gpu_commands.cpp @@ -210,7 +210,7 @@ bool GPU::HandleInterruptRequestCommand() if (!m_GPUSTAT.interrupt_request) { m_GPUSTAT.interrupt_request = true; - g_interrupt_controller.InterruptRequest(InterruptController::IRQ::GPU); + InterruptController::InterruptRequest(InterruptController::IRQ::GPU); } m_fifo.RemoveOne(); diff --git a/src/core/interrupt_controller.cpp b/src/core/interrupt_controller.cpp index c9e2ebbca..517928068 100644 --- a/src/core/interrupt_controller.cpp +++ b/src/core/interrupt_controller.cpp @@ -7,11 +7,17 @@ #include "util/state_wrapper.h" Log_SetChannel(InterruptController); -InterruptController g_interrupt_controller; +namespace InterruptController { -InterruptController::InterruptController() = default; +static constexpr u32 REGISTER_WRITE_MASK = (u32(1) << NUM_IRQS) - 1; +static constexpr u32 DEFAULT_INTERRUPT_MASK = 0; //(u32(1) << NUM_IRQS) - 1; -InterruptController::~InterruptController() = default; +static void UpdateCPUInterruptRequest(); + +static u32 s_interrupt_status_register = 0; +static u32 s_interrupt_mask_register = DEFAULT_INTERRUPT_MASK; + +} // namespace InterruptController void InterruptController::Initialize() { @@ -22,22 +28,27 @@ void InterruptController::Shutdown() {} void InterruptController::Reset() { - m_interrupt_status_register = 0; - m_interrupt_mask_register = DEFAULT_INTERRUPT_MASK; + s_interrupt_status_register = 0; + s_interrupt_mask_register = DEFAULT_INTERRUPT_MASK; } bool InterruptController::DoState(StateWrapper& sw) { - sw.Do(&m_interrupt_status_register); - sw.Do(&m_interrupt_mask_register); + sw.Do(&s_interrupt_status_register); + sw.Do(&s_interrupt_mask_register); return !sw.HasError(); } +bool InterruptController::GetIRQLineState() +{ + return (s_interrupt_status_register != 0); +} + void InterruptController::InterruptRequest(IRQ irq) { const u32 bit = (u32(1) << static_cast(irq)); - m_interrupt_status_register |= bit; + s_interrupt_status_register |= bit; UpdateCPUInterruptRequest(); } @@ -46,10 +57,10 @@ u32 InterruptController::ReadRegister(u32 offset) switch (offset) { case 0x00: // I_STATUS - return m_interrupt_status_register; + return s_interrupt_status_register; case 0x04: // I_MASK - return m_interrupt_mask_register; + return s_interrupt_mask_register; default: Log_ErrorPrintf("Invalid read at offset 0x%08X", offset); @@ -63,10 +74,10 @@ void InterruptController::WriteRegister(u32 offset, u32 value) { case 0x00: // I_STATUS { - if ((m_interrupt_status_register & ~value) != 0) - Log_DebugPrintf("Clearing bits 0x%08X", (m_interrupt_status_register & ~value)); + if ((s_interrupt_status_register & ~value) != 0) + Log_DebugPrintf("Clearing bits 0x%08X", (s_interrupt_status_register & ~value)); - m_interrupt_status_register = m_interrupt_status_register & (value & REGISTER_WRITE_MASK); + s_interrupt_status_register = s_interrupt_status_register & (value & REGISTER_WRITE_MASK); UpdateCPUInterruptRequest(); } break; @@ -74,7 +85,7 @@ void InterruptController::WriteRegister(u32 offset, u32 value) case 0x04: // I_MASK { Log_DebugPrintf("Interrupt mask <- 0x%08X", value); - m_interrupt_mask_register = value & REGISTER_WRITE_MASK; + s_interrupt_mask_register = value & REGISTER_WRITE_MASK; UpdateCPUInterruptRequest(); } break; @@ -88,7 +99,7 @@ void InterruptController::WriteRegister(u32 offset, u32 value) void InterruptController::UpdateCPUInterruptRequest() { // external interrupts set bit 10 only? - if ((m_interrupt_status_register & m_interrupt_mask_register) != 0) + if ((s_interrupt_status_register & s_interrupt_mask_register) != 0) CPU::SetExternalInterrupt(2); else CPU::ClearExternalInterrupt(2); diff --git a/src/core/interrupt_controller.h b/src/core/interrupt_controller.h index 634bbd2de..91184458b 100644 --- a/src/core/interrupt_controller.h +++ b/src/core/interrupt_controller.h @@ -6,53 +6,38 @@ class StateWrapper; -class InterruptController final +namespace InterruptController { + +static constexpr u32 NUM_IRQS = 11; + +enum class IRQ : u32 { -public: - static constexpr u32 NUM_IRQS = 11; - - enum class IRQ : u32 - { - VBLANK = 0, // IRQ0 - VBLANK - GPU = 1, // IRQ1 - GPU via GP0(1Fh) - CDROM = 2, // IRQ2 - CDROM - DMA = 3, // IRQ3 - DMA - TMR0 = 4, // IRQ4 - TMR0 - Sysclk or Dotclk - TMR1 = 5, // IRQ5 - TMR1 - Sysclk Hblank - TMR2 = 6, // IRQ6 - TMR2 - Sysclk or Sysclk / 8 - IRQ7 = 7, // IRQ7 - Controller and Memory Card Byte Received - SIO = 8, // IRQ8 - SIO - SPU = 9, // IRQ9 - SPU - IRQ10 = 10 // IRQ10 - Lightpen interrupt, PIO - }; - - - InterruptController(); - ~InterruptController(); - - void Initialize(); - void Shutdown(); - void Reset(); - bool DoState(StateWrapper& sw); - - // Should mirror CPU state. - ALWAYS_INLINE bool GetIRQLineState() const { return (m_interrupt_status_register != 0); } - - // Interupts are edge-triggered, so if it is masked when TriggerInterrupt() is called, it will be lost. - void InterruptRequest(IRQ irq); - - // I/O - u32 ReadRegister(u32 offset); - void WriteRegister(u32 offset, u32 value); - -private: - static constexpr u32 REGISTER_WRITE_MASK = (u32(1) << NUM_IRQS) - 1; - static constexpr u32 DEFAULT_INTERRUPT_MASK = 0; //(u32(1) << NUM_IRQS) - 1; - - void UpdateCPUInterruptRequest(); - - u32 m_interrupt_status_register = 0; - u32 m_interrupt_mask_register = DEFAULT_INTERRUPT_MASK; + VBLANK = 0, // IRQ0 - VBLANK + GPU = 1, // IRQ1 - GPU via GP0(1Fh) + CDROM = 2, // IRQ2 - CDROM + DMA = 3, // IRQ3 - DMA + TMR0 = 4, // IRQ4 - TMR0 - Sysclk or Dotclk + TMR1 = 5, // IRQ5 - TMR1 - Sysclk Hblank + TMR2 = 6, // IRQ6 - TMR2 - Sysclk or Sysclk / 8 + IRQ7 = 7, // IRQ7 - Controller and Memory Card Byte Received + SIO = 8, // IRQ8 - SIO + SPU = 9, // IRQ9 - SPU + IRQ10 = 10 // IRQ10 - Lightpen interrupt, PIO }; -extern InterruptController g_interrupt_controller; \ No newline at end of file +void Initialize(); +void Shutdown(); +void Reset(); +bool DoState(StateWrapper& sw); + +// Should mirror CPU state. +bool GetIRQLineState(); + +// Interupts are edge-triggered, so if it is masked when TriggerInterrupt() is called, it will be lost. +void InterruptRequest(IRQ irq); + +// I/O +u32 ReadRegister(u32 offset); +void WriteRegister(u32 offset, u32 value); + +} // namespace InterruptController diff --git a/src/core/pad.cpp b/src/core/pad.cpp index cabfee365..f50e3f393 100644 --- a/src/core/pad.cpp +++ b/src/core/pad.cpp @@ -594,7 +594,7 @@ void Pad::DoACK() { Log_DebugPrintf("Triggering ACK interrupt"); m_JOY_STAT.INTR = true; - g_interrupt_controller.InterruptRequest(InterruptController::IRQ::IRQ7); + InterruptController::InterruptRequest(InterruptController::IRQ::IRQ7); } EndTransfer(); diff --git a/src/core/spu.cpp b/src/core/spu.cpp index 685e30dd8..d5d8e42c9 100644 --- a/src/core/spu.cpp +++ b/src/core/spu.cpp @@ -1146,7 +1146,7 @@ void SPU::TriggerRAMIRQ() { DebugAssert(IsRAMIRQTriggerable()); s_SPUSTAT.irq9_flag = true; - g_interrupt_controller.InterruptRequest(InterruptController::IRQ::SPU); + InterruptController::InterruptRequest(InterruptController::IRQ::SPU); } void SPU::CheckForLateRAMIRQs() diff --git a/src/core/system.cpp b/src/core/system.cpp index 3b18ac67a..69dcd0b71 100644 --- a/src/core/system.cpp +++ b/src/core/system.cpp @@ -1387,7 +1387,7 @@ bool System::Initialize(bool force_software_renderer) CPU::CodeCache::Initialize(); DMA::Initialize(); - g_interrupt_controller.Initialize(); + InterruptController::Initialize(); CDROM::Initialize(); g_pad.Initialize(); @@ -1457,7 +1457,7 @@ void System::DestroySystem() g_pad.Shutdown(); CDROM::Shutdown(); g_gpu.reset(); - g_interrupt_controller.Shutdown(); + InterruptController::Shutdown(); DMA::Shutdown(); PGXP::Shutdown(); CPU::CodeCache::Shutdown(); @@ -1643,7 +1643,7 @@ bool System::DoState(StateWrapper& sw, GPUTexture** host_texture, bool update_di if (!sw.DoMarker("DMA") || !DMA::DoState(sw)) return false; - if (!sw.DoMarker("InterruptController") || !g_interrupt_controller.DoState(sw)) + if (!sw.DoMarker("InterruptController") || !InterruptController::DoState(sw)) return false; g_gpu->RestoreGraphicsAPIState(); @@ -1740,7 +1740,7 @@ void System::InternalReset() Bus::Reset(); DMA::Reset(); - g_interrupt_controller.Reset(); + InterruptController::Reset(); g_gpu->Reset(true); CDROM::Reset(); g_pad.Reset(); diff --git a/src/core/timers.cpp b/src/core/timers.cpp index c03cd738f..67f2abaa2 100644 --- a/src/core/timers.cpp +++ b/src/core/timers.cpp @@ -417,7 +417,7 @@ void Timers::UpdateIRQ(u32 index) Log_DebugPrintf("Raising timer %u IRQ", index); cs.irq_done = true; - g_interrupt_controller.InterruptRequest( + InterruptController::InterruptRequest( static_cast(static_cast(InterruptController::IRQ::TMR0) + index)); }