#pragma once #include "common/bitfield.h" #include "types.h" #include class StateWrapper; class System; class DMA; class InterruptController; class SPU { public: SPU(); ~SPU(); bool Initialize(System* system, DMA* dma, InterruptController* interrupt_controller); void Reset(); bool DoState(StateWrapper& sw); u16 ReadRegister(u32 offset); void WriteRegister(u32 offset, u16 value); u32 DMARead(); void DMAWrite(u32 value); private: static constexpr u32 RAM_SIZE = 512 * 1024; static constexpr u32 RAM_MASK = RAM_SIZE - 1; static constexpr u32 SPU_BASE = 0x1F801C00; enum class RAMTransferMode : u8 { Stopped =0, ManualWrite = 1, DMAWrite = 2, DMARead = 3 }; union SPUCNT { u16 bits; BitField enable; BitField mute; BitField noise_frequency_shift; BitField noise_frequency_step; BitField reverb_master_enable; BitField irq9_enable; BitField ram_transfer_mode; BitField external_audio_reverb; BitField cd_audio_reverb; BitField external_audio_enable; BitField cd_audio_enable; BitField mode; }; union SPUSTAT { u16 bits; BitField second_half_capture_buffer; BitField transfer_busy; BitField dma_read_request; BitField dma_write_request; BitField dma_read_write_request; BitField irq9_flag; BitField mode; }; #if 0 struct Voice { static constexpr u32 NUM_REGS = 8; static constexpr u32 NUM_FLAGS = 6; std::array regs; }; #endif void UpdateDMARequest(); u16 RAMTransferRead(); void RAMTransferWrite(u16 value); System* m_system = nullptr; DMA* m_dma = nullptr; InterruptController* m_interrupt_controller = nullptr; SPUCNT m_SPUCNT = {}; SPUSTAT m_SPUSTAT = {}; u16 m_transfer_address_reg = 0; u32 m_transfer_address = 0; std::array m_ram{}; };