-
Notifications
You must be signed in to change notification settings - Fork 478
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Core: Move Audio Interface code in to handler
- Loading branch information
Showing
17 changed files
with
366 additions
and
361 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
196 changes: 196 additions & 0 deletions
196
Source/Project64-core/N64System/MemoryHandler/AudioInterfaceHandler.cpp
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,196 @@ | ||
#include "stdafx.h" | ||
#include "AudioInterfaceHandler.h" | ||
#include <Project64-core\N64System\N64System.h> | ||
#include <Project64-core\N64System\Mips\Register.h> | ||
#include <Project64-core\N64System\SystemGlobals.h> | ||
|
||
AudioInterfaceReg::AudioInterfaceReg(uint32_t * _AudioInterface) : | ||
AI_DRAM_ADDR_REG(_AudioInterface[0]), | ||
AI_LEN_REG(_AudioInterface[1]), | ||
AI_CONTROL_REG(_AudioInterface[2]), | ||
AI_STATUS_REG(_AudioInterface[3]), | ||
AI_DACRATE_REG(_AudioInterface[4]), | ||
AI_BITRATE_REG(_AudioInterface[5]) | ||
{ | ||
} | ||
|
||
AudioInterfaceHandler::AudioInterfaceHandler(CN64System & System, CRegisters & Reg) : | ||
AudioInterfaceReg(Reg.m_Audio_Interface), | ||
m_System(System), | ||
m_Reg(Reg), | ||
m_Plugins(System.GetPlugins()), | ||
m_PC(Reg.m_PROGRAM_COUNTER) | ||
{ | ||
System.RegisterCallBack(CN64SystemCB_Reset, this, (CN64System::CallBackFunction)stSystemReset); | ||
System.RegisterCallBack(CN64SystemCB_LoadedGameState, this, (CN64System::CallBackFunction)stLoadedGameState); | ||
} | ||
|
||
AudioInterfaceHandler::~AudioInterfaceHandler() | ||
{ | ||
m_System.UnregisterCallBack(CN64SystemCB_Reset, this, (CN64System::CallBackFunction)stSystemReset); | ||
m_System.UnregisterCallBack(CN64SystemCB_LoadedGameState, this, (CN64System::CallBackFunction)stLoadedGameState); | ||
} | ||
|
||
bool AudioInterfaceHandler::Read32(uint32_t Address, uint32_t & Value) | ||
{ | ||
switch (Address & 0x1FFFFFFF) | ||
{ | ||
case 0x04500004: | ||
if (bFixedAudio()) | ||
{ | ||
Value = m_Audio.GetLength(); | ||
} | ||
else | ||
{ | ||
if (m_Plugins->Audio()->AiReadLength != nullptr) | ||
{ | ||
Value = m_Plugins->Audio()->AiReadLength(); | ||
} | ||
else | ||
{ | ||
Value = 0; | ||
} | ||
} | ||
break; | ||
case 0x0450000C: | ||
if (bFixedAudio()) | ||
{ | ||
Value = m_Audio.GetStatus(); | ||
} | ||
else | ||
{ | ||
Value = AI_STATUS_REG; | ||
} | ||
break; | ||
default: | ||
Value = 0; | ||
if (HaveDebugger()) | ||
{ | ||
g_Notify->BreakPoint(__FILE__, __LINE__); | ||
} | ||
} | ||
|
||
if (GenerateLog() && LogAudioInterface()) | ||
{ | ||
switch (Address & 0x1FFFFFFF) | ||
{ | ||
case 0x04500000: LogMessage("%08X: read from AI_DRAM_ADDR_REG (%08X)", m_PC, Value); break; | ||
case 0x04500004: LogMessage("%08X: read from AI_LEN_REG (%08X)", m_PC, Value); break; | ||
case 0x04500008: LogMessage("%08X: read from AI_CONTROL_REG (%08X)", m_PC, Value); break; | ||
case 0x0450000C: LogMessage("%08X: read from AI_STATUS_REG (%08X)", m_PC, Value); break; | ||
case 0x04500010: LogMessage("%08X: read from AI_DACRATE_REG (%08X)", m_PC, Value); break; | ||
case 0x04500014: LogMessage("%08X: read from AI_BITRATE_REG (%08X)", m_PC, Value); break; | ||
default: | ||
if (HaveDebugger()) | ||
{ | ||
g_Notify->BreakPoint(__FILE__, __LINE__); | ||
} | ||
} | ||
} | ||
return true; | ||
} | ||
|
||
bool AudioInterfaceHandler::Write32(uint32_t Address, uint32_t Value, uint32_t Mask) | ||
{ | ||
if (GenerateLog() && LogAudioInterface()) | ||
{ | ||
switch (Address & 0x1FFFFFFF) | ||
{ | ||
case 0x04500000: LogMessage("%08X: Writing 0x%08X (Mask: 0x%08X) to AI_DRAM_ADDR_REG", m_PC, Value, Mask); break; | ||
case 0x04500004: LogMessage("%08X: Writing 0x%08X (Mask: 0x%08X) to AI_LEN_REG", m_PC, Value, Mask); break; | ||
case 0x04500008: LogMessage("%08X: Writing 0x%08X (Mask: 0x%08X) to AI_CONTROL_REG", m_PC, Value, Mask); break; | ||
case 0x0450000C: LogMessage("%08X: Writing 0x%08X (Mask: 0x%08X) to AI_STATUS_REG", m_PC, Value, Mask); break; | ||
case 0x04500010: LogMessage("%08X: Writing 0x%08X (Mask: 0x%08X) to AI_DACRATE_REG", m_PC, Value, Mask); break; | ||
case 0x04500014: LogMessage("%08X: Writing 0x%08X (Mask: 0x%08X) to AI_BITRATE_REG", m_PC, Value, Mask); break; | ||
default: | ||
if (HaveDebugger()) | ||
{ | ||
g_Notify->BreakPoint(__FILE__, __LINE__); | ||
} | ||
} | ||
} | ||
|
||
uint32_t MaskedValue = Value & Mask; | ||
switch (Address & 0x1FFFFFFF) | ||
{ | ||
case 0x04500000: AI_DRAM_ADDR_REG = (AI_DRAM_ADDR_REG & ~Mask) | (MaskedValue); break; | ||
case 0x04500004: | ||
AI_LEN_REG = (AI_LEN_REG & ~Mask) | (MaskedValue); | ||
if (bFixedAudio()) | ||
{ | ||
m_Audio.LenChanged(); | ||
} | ||
else | ||
{ | ||
if (m_Plugins->Audio()->AiLenChanged != nullptr) | ||
{ | ||
m_Plugins->Audio()->AiLenChanged(); | ||
} | ||
} | ||
break; | ||
case 0x04500008: AI_CONTROL_REG = (MaskedValue & 1); break; | ||
case 0x0450000C: | ||
m_Reg.MI_INTR_REG &= ~MI_INTR_AI; | ||
m_Reg.m_AudioIntrReg &= ~MI_INTR_AI; | ||
m_Reg.CheckInterrupts(); | ||
break; | ||
case 0x04500010: | ||
AI_DACRATE_REG = (AI_DACRATE_REG & ~Mask) | (MaskedValue); | ||
m_Plugins->Audio()->DacrateChanged(m_System.SystemType()); | ||
if (bFixedAudio()) | ||
{ | ||
m_Audio.SetFrequency(AI_DACRATE_REG, m_System.SystemType()); | ||
} | ||
break; | ||
case 0x04500014: AI_DACRATE_REG = (AI_BITRATE_REG & ~Mask) | (MaskedValue); break; | ||
default: | ||
if (HaveDebugger()) | ||
{ | ||
g_Notify->BreakPoint(__FILE__, __LINE__); | ||
} | ||
} | ||
return true; | ||
} | ||
|
||
void AudioInterfaceHandler::TimerInterrupt(void) | ||
{ | ||
m_Audio.InterruptTimerDone(); | ||
} | ||
|
||
void AudioInterfaceHandler::TimerBusy(void) | ||
{ | ||
m_Audio.BusyTimerDone(); | ||
} | ||
|
||
void AudioInterfaceHandler::SetViIntr(uint32_t VI_INTR_TIME) | ||
{ | ||
m_Audio.SetViIntr(VI_INTR_TIME); | ||
} | ||
|
||
void AudioInterfaceHandler::SetFrequency(uint32_t Dacrate, uint32_t System) | ||
{ | ||
m_Audio.SetFrequency(Dacrate, System); | ||
} | ||
|
||
void AudioInterfaceHandler::LoadedGameState(void) | ||
{ | ||
if (bFixedAudio()) | ||
{ | ||
m_Audio.SetFrequency(m_Reg.AI_DACRATE_REG, SystemType()); | ||
} | ||
} | ||
|
||
void AudioInterfaceHandler::SystemReset(void) | ||
{ | ||
m_Audio.Reset(); | ||
} | ||
|
||
uint32_t AudioInterfaceHandler::GetLength(void) | ||
{ | ||
return m_Audio.GetLength(); | ||
} | ||
|
||
uint32_t AudioInterfaceHandler::GetStatus(void) | ||
{ | ||
return m_Audio.GetStatus(); | ||
} |
76 changes: 76 additions & 0 deletions
76
Source/Project64-core/N64System/MemoryHandler/AudioInterfaceHandler.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,76 @@ | ||
#pragma once | ||
#include "MemoryHandler.h" | ||
#include <Project64-core/N64System/Mips/Audio.h> | ||
#include <Project64-core\Settings\DebugSettings.h> | ||
#include <Project64-core\Settings\GameSettings.h> | ||
#include <Project64-core\Logging.h> | ||
#include <stdint.h> | ||
|
||
enum | ||
{ | ||
AI_STATUS_FIFO_FULL = 0x80000000, // Bit 31: Full | ||
AI_STATUS_DMA_BUSY = 0x40000000, // Bit 30: Busy | ||
}; | ||
|
||
class AudioInterfaceReg | ||
{ | ||
protected: | ||
AudioInterfaceReg(uint32_t * _AudioInterface); | ||
|
||
public: | ||
uint32_t & AI_DRAM_ADDR_REG; | ||
uint32_t & AI_LEN_REG; | ||
uint32_t & AI_CONTROL_REG; | ||
uint32_t & AI_STATUS_REG; | ||
uint32_t & AI_DACRATE_REG; | ||
uint32_t & AI_BITRATE_REG; | ||
|
||
private: | ||
AudioInterfaceReg(); | ||
AudioInterfaceReg(const AudioInterfaceReg&); | ||
AudioInterfaceReg& operator=(const AudioInterfaceReg&); | ||
}; | ||
|
||
class CRegisters; | ||
class CN64System; | ||
class CPlugins; | ||
class CAudio; | ||
|
||
class AudioInterfaceHandler : | ||
public MemoryHandler, | ||
public AudioInterfaceReg, | ||
private CGameSettings, | ||
private CDebugSettings, | ||
private CLogging | ||
{ | ||
public: | ||
AudioInterfaceHandler(CN64System & System, CRegisters & Reg); | ||
~AudioInterfaceHandler(); | ||
|
||
bool Read32(uint32_t Address, uint32_t & Value); | ||
bool Write32(uint32_t Address, uint32_t Value, uint32_t Mask); | ||
|
||
void TimerInterrupt(void); | ||
void TimerBusy(void); | ||
void SetViIntr(uint32_t VI_INTR_TIME); | ||
void SetFrequency(uint32_t Dacrate, uint32_t System); | ||
uint32_t GetLength(); | ||
uint32_t GetStatus(); | ||
|
||
private: | ||
AudioInterfaceHandler(); | ||
AudioInterfaceHandler(const AudioInterfaceHandler &); | ||
AudioInterfaceHandler & operator=(const AudioInterfaceHandler &); | ||
|
||
static void stSystemReset(AudioInterfaceHandler * _this) { _this->SystemReset(); } | ||
static void stLoadedGameState(AudioInterfaceHandler * _this) { _this->LoadedGameState(); } | ||
|
||
void LoadedGameState(void); | ||
void SystemReset(void); | ||
|
||
CN64System & m_System; | ||
CRegisters & m_Reg; | ||
CPlugins * m_Plugins; | ||
CAudio m_Audio; | ||
uint32_t & m_PC; | ||
}; |
Oops, something went wrong.