Play-/tools/SpuTest/KeyOnOffTest.cpp

70 lines
2.5 KiB
C++
Raw Normal View History

2020-12-30 16:31:00 -05:00
#include "KeyOnOffTest.h"
void CKeyOnOffTest::Execute()
{
//Loosely based on Black
//The game will send a KON and KOFF sequence to update the voice addresses
//Since the game is enabling IRQ checks, if we don't handle the change properly
//the SPU might trigger IRQs because the voice address has not been updated
static unsigned int testCoreIndex = 0;
static unsigned int testVoiceIndex = 0;
static uint32 sampleAddress1 = 0x5000;
static uint32 sampleAddress2 = 0x6000;
//Set some samples
m_ram[sampleAddress1 + 0] = 0;
m_ram[sampleAddress1 + 1] = 0x07;
m_ram[sampleAddress2 + 0] = 0;
m_ram[sampleAddress2 + 1] = 0x07;
//Setup voices
for(unsigned int i = 0; i < VOICE_COUNT; i++)
{
SetVoiceRegister(testCoreIndex, i, Iop::Spu2::CCore::VP_PITCH, 0x1000);
SetVoiceAddress(testCoreIndex, i, Iop::Spu2::CCore::VA_SSA_HI, sampleAddress1);
}
//Send KEY-ON
SetCoreRegister(testCoreIndex, Iop::Spu2::CCore::A_KON_HI, 0xFFFF);
SetCoreRegister(testCoreIndex, Iop::Spu2::CCore::A_KON_LO, 0xFF);
RunSpu(64);
//We sent a KEY-ON, current address should be what we set as start address
{
uint32 testVoiceCurrAddr = GetVoiceAddress(testCoreIndex, testVoiceIndex, Iop::Spu2::CCore::VA_NAX_HI);
TEST_VERIFY(testVoiceCurrAddr == sampleAddress1);
}
//Change start address and then send KEY-ON and KEY-OFF right after
SetVoiceAddress(testCoreIndex, testVoiceIndex, Iop::Spu2::CCore::VA_SSA_HI, sampleAddress2);
SetCoreRegister(testCoreIndex, Iop::Spu2::CCore::A_KON_HI, (1 << testVoiceIndex));
SetCoreRegister(testCoreIndex, Iop::Spu2::CCore::A_KOFF_HI, (1 << testVoiceIndex));
RunSpu(64);
//After a quick key-on and key-off sequence, the current voice address should have been updated
//On a real console, I think this would take a few cycles, but since we don't update the SPU
//all the time, we should be able to handle this even though the update timestep is not small
{
uint32 testVoiceCurrAddr = GetVoiceAddress(testCoreIndex, testVoiceIndex, Iop::Spu2::CCore::VA_NAX_HI);
TEST_VERIFY(testVoiceCurrAddr == sampleAddress2);
}
//Enable IRQs and check that our voice's address is still good
SetCoreRegister(testCoreIndex, Iop::Spu2::CCore::CORE_ATTR, Iop::CSpuBase::CONTROL_IRQ);
SetCoreAddress(testCoreIndex, Iop::Spu2::CCore::A_IRQA_HI, 0);
RunSpu(64);
{
uint32 irqInfo = m_spu.ReadRegister(Iop::CSpu2::C_IRQINFO);
TEST_VERIFY(irqInfo == 0);
uint32 testVoiceCurrAddr = GetVoiceAddress(testCoreIndex, testVoiceIndex, Iop::Spu2::CCore::VA_NAX_HI);
TEST_VERIFY(testVoiceCurrAddr == sampleAddress2);
}
}