git-svn-id: http://svn.purei.org/purei/trunk@334 b36208d7-6611-0410-8bec-b1987f11c4a2

This commit is contained in:
jpd002 2008-05-30 22:01:00 +00:00
parent 6d6b93bb5d
commit e12a8893a0
5 changed files with 226 additions and 178 deletions

View File

@ -182,172 +182,172 @@ void CPsxBios::HandleInterrupt()
void CPsxBios::HandleException()
{
assert(m_cpu.m_State.nHasException);
// uint32 searchAddress = m_cpu.m_State.nCOP0[CCOP_SCU::EPC];
uint32 searchAddress = m_cpu.m_State.nGPR[CMIPS::K1].nV0;
uint32 callInstruction = m_cpu.m_pMemoryMap->GetWord(searchAddress);
if(callInstruction != 0x0000000C)
{
throw runtime_error("Not a SYSCALL.");
}
#ifdef _DEBUG
DisassembleSyscall(searchAddress);
#endif
if(searchAddress == 0xA0)
{
ProcessSubFunction(m_handlerA0, MAX_HANDLER_A0);
}
else if(searchAddress == 0xB0)
{
ProcessSubFunction(m_handlerB0, MAX_HANDLER_B0);
}
else if(searchAddress == 0xC0)
{
ProcessSubFunction(m_handlerC0, MAX_HANDLER_C0);
}
else
{
uint32 functionId = m_cpu.m_State.nGPR[CMIPS::A0].nV0;
switch(functionId)
{
case 0x01:
sc_EnterCriticalSection();
break;
case 0x02:
sc_ExitCriticalSection();
break;
default:
sc_Illegal();
break;
}
}
// uint32 searchAddress = m_cpu.m_State.nCOP0[CCOP_SCU::EPC];
uint32 searchAddress = m_cpu.m_State.nGPR[CMIPS::K1].nV0;
uint32 callInstruction = m_cpu.m_pMemoryMap->GetWord(searchAddress);
if(callInstruction != 0x0000000C)
{
throw runtime_error("Not a SYSCALL.");
}
#ifdef _DEBUG
DisassembleSyscall(searchAddress);
#endif
if(searchAddress == 0xA0)
{
ProcessSubFunction(m_handlerA0, MAX_HANDLER_A0);
}
else if(searchAddress == 0xB0)
{
ProcessSubFunction(m_handlerB0, MAX_HANDLER_B0);
}
else if(searchAddress == 0xC0)
{
ProcessSubFunction(m_handlerC0, MAX_HANDLER_C0);
}
else
{
uint32 functionId = m_cpu.m_State.nGPR[CMIPS::A0].nV0;
switch(functionId)
{
case 0x01:
sc_EnterCriticalSection();
break;
case 0x02:
sc_ExitCriticalSection();
break;
default:
sc_Illegal();
break;
}
}
m_cpu.m_State.nHasException = 0;
}
void CPsxBios::ProcessSubFunction(SyscallHandler* handlerTable, unsigned int handlerTableLength)
{
uint32 functionId = m_cpu.m_State.nGPR[CMIPS::T1].nV0;
if(functionId >= handlerTableLength)
{
sc_Illegal();
}
functionId %= handlerTableLength;
((this)->*(handlerTable[functionId]))();
uint32 functionId = m_cpu.m_State.nGPR[CMIPS::T1].nV0;
if(functionId >= handlerTableLength)
{
sc_Illegal();
}
functionId %= handlerTableLength;
((this)->*(handlerTable[functionId]))();
}
void CPsxBios::DisassembleSyscall(uint32 searchAddress)
{
if(searchAddress == 0x00A0)
{
uint32 functionId = m_cpu.m_State.nGPR[CMIPS::T1].nV0;
switch(functionId)
{
case 0x39:
CLog::GetInstance().Print(LOG_NAME, "InitHeap(block = 0x%0.8X, n = 0x%0.8X);\r\n",
m_cpu.m_State.nGPR[SC_PARAM0].nV0,
m_cpu.m_State.nGPR[SC_PARAM1].nV0);
break;
case 0x70:
CLog::GetInstance().Print(LOG_NAME, "_bu_init();\r\n");
break;
case 0x72:
CLog::GetInstance().Print(LOG_NAME, "_96_remove();\r\n");
break;
case 0x9F:
CLog::GetInstance().Print(LOG_NAME, "SetMem(size = %i);\r\n",
m_cpu.m_State.nGPR[SC_PARAM0].nV0);
break;
default:
CLog::GetInstance().Print(LOG_NAME, "Unknown system call encountered (0xA0, 0x%X).\r\n", functionId);
break;
}
}
else if(searchAddress == 0x00B0)
{
uint32 functionId = m_cpu.m_State.nGPR[CMIPS::T1].nV0;
switch(functionId)
{
case 0x00:
CLog::GetInstance().Print(LOG_NAME, "SysMalloc(size = 0x%X);\r\n",
m_cpu.m_State.nGPR[SC_PARAM0].nV0);
break;
case 0x07:
CLog::GetInstance().Print(LOG_NAME, "DeliverEvent(class = 0x%X, event = 0x%X);\r\n",
m_cpu.m_State.nGPR[SC_PARAM0].nV0,
m_cpu.m_State.nGPR[SC_PARAM1].nV0);
break;
case 0x08:
CLog::GetInstance().Print(LOG_NAME, "OpenEvent(class = 0x%X, spec = 0x%X, mode = 0x%X, func = 0x%X);\r\n",
m_cpu.m_State.nGPR[SC_PARAM0].nV0,
m_cpu.m_State.nGPR[SC_PARAM1].nV0,
m_cpu.m_State.nGPR[SC_PARAM2].nV0,
m_cpu.m_State.nGPR[SC_PARAM3].nV0);
break;
case 0x0A:
CLog::GetInstance().Print(LOG_NAME, "WaitEvent(event = 0x%X);\r\n",
m_cpu.m_State.nGPR[SC_PARAM0].nV0);
break;
case 0x0C:
CLog::GetInstance().Print(LOG_NAME, "EnableEvent(event = 0x%X);\r\n",
m_cpu.m_State.nGPR[SC_PARAM0].nV0);
break;
case 0x0D:
CLog::GetInstance().Print(LOG_NAME, "DisableEvent(event = 0x%X);\r\n",
m_cpu.m_State.nGPR[SC_PARAM0].nV0);
break;
case 0x17:
CLog::GetInstance().Print(LOG_NAME, "ReturnFromException();\r\n");
break;
case 0x19:
CLog::GetInstance().Print(LOG_NAME, "HookEntryInt(address = 0x%0.8X);\r\n",
m_cpu.m_State.nGPR[SC_PARAM0].nV0);
break;
case 0x5B:
CLog::GetInstance().Print(LOG_NAME, "ChangeClearPad(param = %i);\r\n",
m_cpu.m_State.nGPR[SC_PARAM0].nV0);
break;
default:
CLog::GetInstance().Print(LOG_NAME, "Unknown system call encountered (0xB0, 0x%X).\r\n", functionId);
break;
}
}
else if(searchAddress == 0x00C0)
{
uint32 functionId = m_cpu.m_State.nGPR[CMIPS::T1].nV0;
switch(functionId)
{
case 0x03:
CLog::GetInstance().Print(LOG_NAME, "SysDeqIntRP(index = %i, queue = 0x%X);\r\n",
m_cpu.m_State.nGPR[SC_PARAM0].nV0,
m_cpu.m_State.nGPR[SC_PARAM1].nV0);
break;
case 0x08:
CLog::GetInstance().Print(LOG_NAME, "SysInitMemory();\r\n");
break;
case 0x0A:
CLog::GetInstance().Print(LOG_NAME, "ChangeClearRCnt(param0 = %i, param1 = %i);\r\n",
m_cpu.m_State.nGPR[SC_PARAM0].nV0,
m_cpu.m_State.nGPR[SC_PARAM1].nV0);
break;
default:
CLog::GetInstance().Print(LOG_NAME, "Unknown system call encountered (0xC0, 0x%X).\r\n", functionId);
break;
}
}
else
{
uint32 functionId = m_cpu.m_State.nGPR[CMIPS::A0].nV0;
switch(functionId)
{
case 0x01:
CLog::GetInstance().Print(LOG_NAME, "EnterCriticalSection();\r\n");
break;
case 0x02:
CLog::GetInstance().Print(LOG_NAME, "ExitCriticalSection();\r\n");
break;
default:
CLog::GetInstance().Print(LOG_NAME, "Unknown system call encountered.\r\n");
break;
}
if(searchAddress == 0x00A0)
{
uint32 functionId = m_cpu.m_State.nGPR[CMIPS::T1].nV0;
switch(functionId)
{
case 0x39:
CLog::GetInstance().Print(LOG_NAME, "InitHeap(block = 0x%0.8X, n = 0x%0.8X);\r\n",
m_cpu.m_State.nGPR[SC_PARAM0].nV0,
m_cpu.m_State.nGPR[SC_PARAM1].nV0);
break;
case 0x70:
CLog::GetInstance().Print(LOG_NAME, "_bu_init();\r\n");
break;
case 0x72:
CLog::GetInstance().Print(LOG_NAME, "_96_remove();\r\n");
break;
case 0x9F:
CLog::GetInstance().Print(LOG_NAME, "SetMem(size = %i);\r\n",
m_cpu.m_State.nGPR[SC_PARAM0].nV0);
break;
default:
CLog::GetInstance().Print(LOG_NAME, "Unknown system call encountered (0xA0, 0x%X).\r\n", functionId);
break;
}
}
else if(searchAddress == 0x00B0)
{
uint32 functionId = m_cpu.m_State.nGPR[CMIPS::T1].nV0;
switch(functionId)
{
case 0x00:
CLog::GetInstance().Print(LOG_NAME, "SysMalloc(size = 0x%X);\r\n",
m_cpu.m_State.nGPR[SC_PARAM0].nV0);
break;
case 0x07:
CLog::GetInstance().Print(LOG_NAME, "DeliverEvent(class = 0x%X, event = 0x%X);\r\n",
m_cpu.m_State.nGPR[SC_PARAM0].nV0,
m_cpu.m_State.nGPR[SC_PARAM1].nV0);
break;
case 0x08:
CLog::GetInstance().Print(LOG_NAME, "OpenEvent(class = 0x%X, spec = 0x%X, mode = 0x%X, func = 0x%X);\r\n",
m_cpu.m_State.nGPR[SC_PARAM0].nV0,
m_cpu.m_State.nGPR[SC_PARAM1].nV0,
m_cpu.m_State.nGPR[SC_PARAM2].nV0,
m_cpu.m_State.nGPR[SC_PARAM3].nV0);
break;
case 0x0A:
CLog::GetInstance().Print(LOG_NAME, "WaitEvent(event = 0x%X);\r\n",
m_cpu.m_State.nGPR[SC_PARAM0].nV0);
break;
case 0x0C:
CLog::GetInstance().Print(LOG_NAME, "EnableEvent(event = 0x%X);\r\n",
m_cpu.m_State.nGPR[SC_PARAM0].nV0);
break;
case 0x0D:
CLog::GetInstance().Print(LOG_NAME, "DisableEvent(event = 0x%X);\r\n",
m_cpu.m_State.nGPR[SC_PARAM0].nV0);
break;
case 0x17:
CLog::GetInstance().Print(LOG_NAME, "ReturnFromException();\r\n");
break;
case 0x19:
CLog::GetInstance().Print(LOG_NAME, "HookEntryInt(address = 0x%0.8X);\r\n",
m_cpu.m_State.nGPR[SC_PARAM0].nV0);
break;
case 0x5B:
CLog::GetInstance().Print(LOG_NAME, "ChangeClearPad(param = %i);\r\n",
m_cpu.m_State.nGPR[SC_PARAM0].nV0);
break;
default:
CLog::GetInstance().Print(LOG_NAME, "Unknown system call encountered (0xB0, 0x%X).\r\n", functionId);
break;
}
}
else if(searchAddress == 0x00C0)
{
uint32 functionId = m_cpu.m_State.nGPR[CMIPS::T1].nV0;
switch(functionId)
{
case 0x03:
CLog::GetInstance().Print(LOG_NAME, "SysDeqIntRP(index = %i, queue = 0x%X);\r\n",
m_cpu.m_State.nGPR[SC_PARAM0].nV0,
m_cpu.m_State.nGPR[SC_PARAM1].nV0);
break;
case 0x08:
CLog::GetInstance().Print(LOG_NAME, "SysInitMemory();\r\n");
break;
case 0x0A:
CLog::GetInstance().Print(LOG_NAME, "ChangeClearRCnt(param0 = %i, param1 = %i);\r\n",
m_cpu.m_State.nGPR[SC_PARAM0].nV0,
m_cpu.m_State.nGPR[SC_PARAM1].nV0);
break;
default:
CLog::GetInstance().Print(LOG_NAME, "Unknown system call encountered (0xC0, 0x%X).\r\n", functionId);
break;
}
}
else
{
uint32 functionId = m_cpu.m_State.nGPR[CMIPS::A0].nV0;
switch(functionId)
{
case 0x01:
CLog::GetInstance().Print(LOG_NAME, "EnterCriticalSection();\r\n");
break;
case 0x02:
CLog::GetInstance().Print(LOG_NAME, "ExitCriticalSection();\r\n");
break;
default:
CLog::GetInstance().Print(LOG_NAME, "Unknown system call encountered.\r\n");
break;
}
}
}

View File

@ -52,9 +52,13 @@ CPsxVm::~CPsxVm()
void CPsxVm::Reset()
{
memset(m_ram, 0, RAMSIZE);
m_executor.Clear();
m_cpu.Reset();
m_bios.Reset();
m_spu.Reset();
m_counters.Reset();
m_dmac.Reset();
m_intc.Reset();
}
uint32 CPsxVm::ReadIoRegister(uint32 address)

View File

@ -1,7 +1,7 @@
#include "SH_OpenAL.h"
#include "alloca_def.h"
#define LOGGING
//#define LOGGING
ALCint g_attrList[] =
{
@ -45,7 +45,7 @@ void CSH_OpenAL::Update(CSpu& spu)
//Update bufferLength worth of samples
const unsigned int sampleCount = (44100 * bufferLength) / 1000;
const unsigned int sampleCount = (44100 * bufferLength * 2) / 1000;
const unsigned int sampleRate = 44100;
int16 samples[sampleCount];
spu.Render(samples, sampleCount, sampleRate);
@ -55,7 +55,7 @@ void CSH_OpenAL::Update(CSpu& spu)
ALuint buffer = *m_availableBuffers.begin();
m_availableBuffers.pop_front();
alBufferData(buffer, AL_FORMAT_MONO16, samples, sampleCount * sizeof(int16), sampleRate);
alBufferData(buffer, AL_FORMAT_STEREO16, samples, sampleCount * sizeof(int16), sampleRate);
#ifdef LOGGING
FILE* log = fopen("log.raw", "ab");
fwrite(samples, sampleCount * sizeof(int16), 1, log);

View File

@ -120,8 +120,10 @@ CSpu::CHANNEL& CSpu::GetChannel(unsigned int channelNumber)
void CSpu::Render(int16* samples, unsigned int sampleCount, unsigned int sampleRate)
{
assert((sampleCount & 0x01) == 0);
unsigned int ticks = sampleCount / 2;
memset(samples, 0, sizeof(int16) * sampleCount);
int16* bufferTemp = reinterpret_cast<int16*>(_alloca(sizeof(int16) * sampleCount));
int16* bufferTemp = reinterpret_cast<int16*>(_alloca(sizeof(int16) * ticks));
for(unsigned int i = 0; i < 24; i++)
// for(unsigned int i = 1; i < 2; i++)
{
@ -135,19 +137,33 @@ void CSpu::Render(int16* samples, unsigned int sampleCount, unsigned int sampleR
channel.status = ATTACK;
}
reader.SetPitch(channel.pitch);
reader.GetSamples(bufferTemp, sampleCount, sampleRate);
reader.GetSamples(bufferTemp, ticks, sampleRate);
//Mix samples
for(unsigned int j = 0; j < sampleCount; j++)
int16* samplePtr = samples;
for(unsigned int j = 0; j < ticks; j++)
{
if(channel.status == STOPPED) break;
if(channel.status == RELEASE)
{
channel.status = STOPPED;
}
int32 resultSample = static_cast<int32>(bufferTemp[j]) + static_cast<int32>(samples[j]);
resultSample = max<int32>(resultSample, SHRT_MIN);
resultSample = min<int32>(resultSample, SHRT_MAX);
samples[j] = static_cast<int16>(resultSample);
int32 inputSample = static_cast<int32>(bufferTemp[j]);
struct SampleMixer
{
void operator() (int32 inputSample, const CHANNEL_VOLUME& volume, int16*& output) const
{
if(!volume.mode.mode)
{
inputSample = (inputSample * static_cast<int32>(volume.volume.volume)) / 0x3FFF;
}
int32 resultSample = inputSample + static_cast<int32>(*output);
resultSample = max<int32>(resultSample, SHRT_MIN);
resultSample = min<int32>(resultSample, SHRT_MAX);
(*output++) = static_cast<int16>(resultSample);
}
};
SampleMixer()(inputSample, channel.volumeLeft, samplePtr);
SampleMixer()(inputSample, channel.volumeRight, samplePtr);
}
}
}
@ -234,10 +250,10 @@ void CSpu::WriteRegister(uint32 address, uint16 value)
switch(registerId)
{
case CH_VOL_LEFT:
m_channel[channel].volumeLeft = value;
m_channel[channel].volumeLeft <<= value;
break;
case CH_VOL_RIGHT:
m_channel[channel].volumeRight = value;
m_channel[channel].volumeRight <<= value;
break;
case CH_PITCH:
m_channel[channel].pitch = value;

View File

@ -28,17 +28,45 @@ public:
};
BOOST_STATIC_ASSERT(sizeof(ADSR_RATE) >= sizeof(uint16));
struct CHANNEL_VOLUME : public convertible<uint16>
{
union
{
struct
{
unsigned int unused0 : 15;
unsigned int mode : 1;
} mode;
struct
{
unsigned int volume : 14;
unsigned int phase : 1;
unsigned int mode : 1;
} volume;
struct
{
unsigned int volume : 7;
unsigned int unused0 : 5;
unsigned int phase : 1;
unsigned int decrease : 1;
unsigned int slope : 1;
unsigned int mode : 1;
} sweep;
};
};
BOOST_STATIC_ASSERT(sizeof(CHANNEL_VOLUME) >= sizeof(uint16));
struct CHANNEL
{
uint16 volumeLeft;
uint16 volumeRight;
uint16 pitch;
uint16 address;
ADSR_LEVEL adsrLevel;
ADSR_RATE adsrRate;
int32 adsrVolume;
uint16 repeat;
uint16 status;
CHANNEL_VOLUME volumeLeft;
CHANNEL_VOLUME volumeRight;
uint16 pitch;
uint16 address;
ADSR_LEVEL adsrLevel;
ADSR_RATE adsrRate;
int32 adsrVolume;
uint16 repeat;
uint16 status;
};
CSpu();