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

This commit is contained in:
jpd002 2008-10-27 22:27:25 +00:00
parent 1d1298fef1
commit f9d4017041
12 changed files with 170 additions and 44 deletions

View File

@ -14,27 +14,73 @@ CIntc::~CIntc()
}
void CIntc::Reset()
{
m_status.f = 0;
m_mask.f = 0;
}
uint32 CIntc::ReadRegister(uint32 address)
{
switch(address)
{
case MASK0:
return m_mask.h0;
break;
case MASK1:
return m_mask.h1;
break;
case STATUS0:
return m_status.h0;
break;
case STATUS1:
return m_status.h1;
break;
}
return 0;
}
uint32 CIntc::WriteRegister(uint32 address, uint32 value)
{
switch(address)
{
case MASK0:
m_mask.h0 = value;
break;
case MASK1:
m_mask.h1 = value;
break;
case STATUS0:
m_status.h0 &= value;
break;
case STATUS1:
m_status.h1 &= value;
break;
}
return 0;
}
void CIntc::AssertLine(unsigned int line)
{
m_status |= 1 << line;
m_status.f |= 1LL << line;
}
void CIntc::ClearLine(unsigned int line)
{
m_status &= ~(1 << line);
m_status.f &= ~(1LL << line);
}
void CIntc::SetMask(uint32 mask)
void CIntc::SetMask(uint64 mask)
{
m_mask = mask;
m_mask.f = mask;
}
void CIntc::SetStatus(uint32 status)
void CIntc::SetStatus(uint64 status)
{
m_status = status;
m_status.f = status;
}
bool CIntc::HasPendingInterrupt()
{
return (m_mask & m_status) != 0;
return (m_mask.f & m_status.f) != 0;
}

View File

@ -2,6 +2,7 @@
#define _IOP_INTC_H_
#include "Types.h"
#include "BasicUnions.h"
namespace Iop
{
@ -13,6 +14,7 @@ namespace Iop
LINE_VBLANK = 0x00,
LINE_SBUS = 0x01,
LINE_CDROM = 0x02,
LINE_DMAC = 0x03,
LINE_RTC0 = 0x04,
LINE_RTC1 = 0x05,
LINE_RTC2 = 0x06,
@ -25,7 +27,7 @@ namespace Iop
LINE_SIO2 = 0x11,
LINE_USB = 0x16,
LINE_ILINK = 0x18,
LINE_DMA_BASE = 0x20,
LINE_DMA2 = 0x22,
LINE_DMA4 = 0x24, //spu2 core0
LINE_DMA8 = 0x28, //spu2 core1
@ -33,18 +35,38 @@ namespace Iop
LINE_DMA9 = 0x2A, //sif0
LINE_DMA10 = 0x2B, //sif1
};
enum
{
ADDR_BEGIN = 0x1F801070,
ADDR_END = 0x1F80107F
};
enum
{
STATUS0 = 0x1F801070,
MASK0 = 0x1F801074,
STATUS1 = 0x1F801078,
MASK1 = 0x1F80107C,
};
CIntc();
virtual ~CIntc();
void Reset();
uint32 ReadRegister(uint32);
uint32 WriteRegister(uint32, uint32);
void AssertLine(unsigned int);
void ClearLine(unsigned int);
void SetStatus(uint32);
void SetMask(uint32);
void SetStatus(uint64);
void SetMask(uint64);
bool HasPendingInterrupt();
private:
uint32 m_status;
uint32 m_mask;
UNION64_32 m_status;
UNION64_32 m_mask;
};
}

View File

@ -1,6 +1,7 @@
#include "Iop_Intrman.h"
#include "../Log.h"
#include "../COP_SCU.h"
#include "Iop_Intc.h"
#define LOGNAME "iop_intrman"
@ -42,11 +43,13 @@ void CIntrman::Invoke(CMIPS& context, unsigned int functionId)
break;
case 6:
context.m_State.nGPR[CMIPS::V0].nD0 = static_cast<int32>(EnableIntrLine(
context,
context.m_State.nGPR[CMIPS::A0].nV0
));
break;
case 7:
context.m_State.nGPR[CMIPS::V0].nD0 = static_cast<int32>(DisableIntrLine(
context,
context.m_State.nGPR[CMIPS::A0].nV0,
context.m_State.nGPR[CMIPS::A1].nV0
));
@ -97,22 +100,34 @@ uint32 CIntrman::ReleaseIntrHandler(uint32 line)
return 0;
}
uint32 CIntrman::EnableIntrLine(uint32 line)
uint32 CIntrman::EnableIntrLine(CMIPS& context, uint32 line)
{
#ifdef _DEBUG
CLog::GetInstance().Print(LOGNAME, "EnableIntrLine(line = %d);\r\n",
line);
#endif
return 0;
UNION64_32 mask(
context.m_pMemoryMap->GetWord(CIntc::MASK0),
context.m_pMemoryMap->GetWord(CIntc::MASK1));
mask.f |= 1LL << line;
context.m_pMemoryMap->SetWord(CIntc::MASK0, mask.h0);
context.m_pMemoryMap->SetWord(CIntc::MASK1, mask.h1);
return 0;
}
uint32 CIntrman::DisableIntrLine(uint32 line, uint32 res)
uint32 CIntrman::DisableIntrLine(CMIPS& context, uint32 line, uint32 res)
{
#ifdef _DEBUG
CLog::GetInstance().Print(LOGNAME, "DisableIntrLine(line = %d, res = %0.8X);\r\n",
line, res);
#endif
return 0;
UNION64_32 mask(
context.m_pMemoryMap->GetWord(CIntc::MASK0),
context.m_pMemoryMap->GetWord(CIntc::MASK1));
mask.f &= ~(1LL << line);
context.m_pMemoryMap->SetWord(CIntc::MASK0, mask.h0);
context.m_pMemoryMap->SetWord(CIntc::MASK1, mask.h1);
return 0;
}
uint32 CIntrman::EnableInterrupts(CMIPS& context)

View File

@ -17,8 +17,8 @@ namespace Iop
private:
uint32 RegisterIntrHandler(uint32, uint32, uint32, uint32);
uint32 ReleaseIntrHandler(uint32);
uint32 EnableIntrLine(uint32);
uint32 DisableIntrLine(uint32, uint32);
uint32 EnableIntrLine(CMIPS&, uint32);
uint32 DisableIntrLine(CMIPS&, uint32, uint32);
uint32 EnableInterrupts(CMIPS&);
uint32 SuspendInterrupts(CMIPS&, uint32*);
uint32 ResumeInterrupts(CMIPS&, uint32);

View File

@ -1,17 +1,30 @@
#ifndef _BASICUNIONS_H_
#define _BASICUNIONS_H_
struct UNION32_16
#include <boost/static_assert.hpp>
template <typename FullType, typename HalfType>
struct basic_union
{
BOOST_STATIC_ASSERT(sizeof(FullType) == (2 * sizeof(HalfType)));
basic_union() {}
basic_union(const FullType& f) : f(f) {}
basic_union(const HalfType& h0, const HalfType& h1) : h0(h0), h1(h1) {}
union
{
struct
{
uint16 h0;
uint16 h1;
HalfType h0;
HalfType h1;
};
uint32 w;
FullType f;
};
};
typedef basic_union<uint32, uint16> UNION32_16;
typedef basic_union<uint64, uint32> UNION64_32;
typedef basic_union<uint64, UNION32_16> UNION64_32_16;
#endif

View File

@ -130,8 +130,8 @@ void CSpu::Reset()
m_status0 = 0;
m_status1 = 0;
m_bufferAddr = 0;
m_channelOn.w = 0;
m_channelReverb.w = 0;
m_channelOn.f = 0;
m_channelReverb.f = 0;
m_reverbTicks = 0;
m_reverbCurrAddr = 0;
@ -144,12 +144,12 @@ void CSpu::Reset()
uint32 CSpu::GetChannelOn() const
{
return m_channelOn.w;
return m_channelOn.f;
}
uint32 CSpu::GetChannelReverb() const
{
return m_channelReverb.w;
return m_channelReverb.f;
}
CSpu::CHANNEL& CSpu::GetChannel(unsigned int channelNumber)
@ -208,7 +208,7 @@ void CSpu::Render(int16* samples, unsigned int sampleCount, unsigned int sampleR
SampleMixer()(inputSample, channel.volumeLeft, samples + 0);
SampleMixer()(inputSample, channel.volumeRight, samples + 1);
//Mix in reverb if enabled for this channel
if(m_channelReverb.w & (1 << i))
if(m_channelReverb.f & (1 << i))
{
SampleMixer()(inputSample, channel.volumeLeft, reverbSample + 0);
SampleMixer()(inputSample, channel.volumeRight, reverbSample + 1);

View File

@ -1,14 +1,16 @@
#include <assert.h>
#include "Iop_Dmac.h"
#include "Log.h"
#include "iop/Iop_Intc.h"
#define LOG_NAME ("iop_dmac")
using namespace Iop;
using namespace Iop::Dmac;
CDmac::CDmac(uint8* ram) :
CDmac::CDmac(uint8* ram, CIntc& intc) :
m_ram(ram),
m_intc(intc),
m_channelSpu(CH4_BASE, 4, *this)
{
memset(m_channel, 0, sizeof(m_channel));
@ -56,7 +58,8 @@ CChannel* CDmac::GetChannelFromAddress(uint32 address)
void CDmac::AssertLine(unsigned int line)
{
m_DICR |= 1 << (line + 24);
//m_intc.AssertLine(CIntc::LINE_DMAC);
// m_intc.AssertLine(CIntc::LINE_DMAC);
m_intc.AssertLine(CIntc::LINE_DMA_BASE + line);
}
uint8* CDmac::GetRam()

View File

@ -6,6 +6,8 @@
namespace Iop
{
class CIntc;
class CDmac
{
public:
@ -31,7 +33,7 @@ namespace Iop
DMAC_ZONE1_END = 0x1F8010FF,
};
CDmac(uint8*);
CDmac(uint8*, CIntc&);
virtual ~CDmac();
void Reset();
@ -59,6 +61,7 @@ namespace Iop
uint32 m_DPCR;
uint32 m_DICR;
uint8* m_ram;
CIntc& m_intc;
};
}

View File

@ -14,7 +14,7 @@ using namespace Iop;
CPsfVm::CPsfVm() :
m_ram(new uint8[IOPRAMSIZE]),
m_cpu(MEMORYMAP_ENDIAN_LSBF, 0x00000000, IOPRAMSIZE),
m_dmac(m_ram),
m_dmac(m_ram, m_intc),
m_executor(m_cpu),
m_status(PAUSED),
m_singleStep(false),
@ -25,14 +25,16 @@ m_thread(bind(&CPsfVm::ThreadProc, this))
//IOP context setup
{
//Read map
m_cpu.m_pMemoryMap->InsertReadMap(0x00000000, IOPRAMSIZE - 1, m_ram, 0x00);
m_cpu.m_pMemoryMap->InsertReadMap(CDmac::DMAC_ZONE1_START, CDmac::DMAC_ZONE1_END, bind(&CDmac::ReadRegister, &m_dmac, _1), 0x01);
m_cpu.m_pMemoryMap->InsertReadMap(CSpu2::REGS_BEGIN, CSpu2::REGS_END, bind(&CSpu2::ReadRegister, &m_spu, _1), 0x02);
m_cpu.m_pMemoryMap->InsertReadMap(0x00000000, IOPRAMSIZE - 1, m_ram, 0x00);
m_cpu.m_pMemoryMap->InsertReadMap(CIntc::ADDR_BEGIN, CIntc::ADDR_END, bind(&CIntc::ReadRegister, &m_intc, _1), 0x01);
m_cpu.m_pMemoryMap->InsertReadMap(CDmac::DMAC_ZONE1_START, CDmac::DMAC_ZONE1_END, bind(&CDmac::ReadRegister, &m_dmac, _1), 0x02);
m_cpu.m_pMemoryMap->InsertReadMap(CSpu2::REGS_BEGIN, CSpu2::REGS_END, bind(&CSpu2::ReadRegister, &m_spu, _1), 0x03);
//Write map
m_cpu.m_pMemoryMap->InsertWriteMap(0x00000000, IOPRAMSIZE - 1, m_ram, 0x00);
m_cpu.m_pMemoryMap->InsertWriteMap(CDmac::DMAC_ZONE1_START, CDmac::DMAC_ZONE1_END, bind(&CDmac::WriteRegister, &m_dmac, _1, _2), 0x01);
m_cpu.m_pMemoryMap->InsertWriteMap(CSpu2::REGS_BEGIN, CSpu2::REGS_END, bind(&CSpu2::WriteRegister, &m_spu, _1, _2), 0x02);
m_cpu.m_pMemoryMap->InsertWriteMap(CIntc::ADDR_BEGIN, CIntc::ADDR_END, bind(&CIntc::WriteRegister, &m_intc, _1, _2), 0x01);
m_cpu.m_pMemoryMap->InsertWriteMap(CDmac::DMAC_ZONE1_START, CDmac::DMAC_ZONE1_END, bind(&CDmac::WriteRegister, &m_dmac, _1, _2), 0x02);
m_cpu.m_pMemoryMap->InsertWriteMap(CSpu2::REGS_BEGIN, CSpu2::REGS_END, bind(&CSpu2::WriteRegister, &m_spu, _1, _2), 0x03);
//Instruction map
m_cpu.m_pMemoryMap->InsertInstructionMap(0x00000000, IOPRAMSIZE - 1, m_ram, 0x00);
@ -70,7 +72,8 @@ void CPsfVm::LoadPsf(const CPsfDevice::PsfFile& psfFile)
void CPsfVm::Reset()
{
memset(m_ram, 0, IOPRAMSIZE);
m_bios.Reset();
m_intc.Reset();
m_bios.Reset();
m_dmac.Reset();
}

View File

@ -41,8 +41,8 @@ namespace PS2
uint8* m_ram;
CSpu2 m_spu;
Iop::CDmac m_dmac;
Iop::CIntc m_intc;
Iop::CDmac m_dmac;
CMipsExecutor m_executor;
CMIPS m_cpu;
CIopBios m_bios;

View File

@ -34,7 +34,7 @@ CCore::~CCore()
void CCore::Reset()
{
memset(m_ram, 0, RAMSIZE);
m_transferAddress.w = 0;
m_transferAddress.f = 0;
}
uint32 CCore::ReadRegister(uint32 address, uint32 value)
@ -49,7 +49,20 @@ uint32 CCore::WriteRegister(uint32 address, uint32 value)
uint32 CCore::ReceiveDma(uint8* buffer, uint32 blockSize, uint32 blockAmount)
{
return blockAmount;
assert((blockSize & 1) == 0);
unsigned int blocksTransfered = 0;
uint32 dstAddress = m_transferAddress.f << 1;
for(unsigned int i = 0; i < blockAmount; i++)
{
uint32 copySize = min<uint32>(RAMSIZE - dstAddress, blockSize);
memcpy(m_ram + dstAddress, buffer, copySize);
dstAddress += blockSize;
dstAddress &= RAMSIZE - 1;
buffer += blockSize;
blocksTransfered++;
}
m_transferAddress.f = dstAddress >> 1;
return blocksTransfered;
}
uint32 CCore::ProcessRegisterAccess(const REGISTER_DISPATCH_INFO& dispatchInfo, uint32 address, uint32 value)
@ -96,10 +109,10 @@ uint32 CCore::WriteRegisterCore(unsigned int channelId, uint32 address, uint32 v
{
case A_STD:
{
uint32 address = m_transferAddress.w << 1;
uint32 address = m_transferAddress.f << 1;
address &= RAMSIZE - 1;
*reinterpret_cast<uint16*>(m_ram + address) = static_cast<uint16>(value);
m_transferAddress.w++;
m_transferAddress.f++;
}
break;
case A_TSA_HI:

View File

@ -40,7 +40,7 @@
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories="&quot;C:\Program Files\OpenAL 1.1 SDK\include&quot;;C:\Projects\Rawr\Source;C:\Projects\zlib;C:\Components\boost_1_35_0\boost\tr1\tr1;C:\Components\boost_1_35_0;C:\Projects\Framework\include;C:\Projects\Rawr\tools\PsfPlayer\Source"
AdditionalIncludeDirectories="&quot;C:\Program Files\OpenAL 1.1 SDK\include&quot;;C:\Projects\Rawr\Source;C:\Projects\zlib;C:\Components\boost_1_35_0\boost\tr1\tr1;C:\Components\boost_1_35_0;C:\Projects\Framework\include;C:\Projects\Rawr\tools\PsfPlayer2\Source"
PreprocessorDefinitions="WIN32;_DEBUG;_CRT_SECURE_NO_WARNINGS;_SCL_SECURE_NO_WARNINGS;_MSVC;_PSX;DEBUGGER_INCLUDED;_NULL_SIFMAN"
MinimalRebuild="true"
BasicRuntimeChecks="3"
@ -118,7 +118,7 @@
/>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories="&quot;C:\Program Files\OpenAL 1.1 SDK\include&quot;;C:\Projects\Rawr\Source;C:\Projects\zlib;C:\Components\boost_1_35_0\boost\tr1\tr1;C:\Components\boost_1_35_0;C:\Projects\Framework\include;C:\Projects\Rawr\tools\PsfPlayer\Source"
AdditionalIncludeDirectories="&quot;C:\Program Files\OpenAL 1.1 SDK\include&quot;;C:\Projects\Rawr\Source;C:\Projects\zlib;C:\Components\boost_1_35_0\boost\tr1\tr1;C:\Components\boost_1_35_0;C:\Projects\Framework\include;C:\Projects\Rawr\tools\PsfPlayer2\Source"
PreprocessorDefinitions="WIN32;NDEBUG;_CRT_SECURE_NO_WARNINGS;_MSVC;_PSX;_NULL_SIFMAN"
RuntimeLibrary="2"
UsePrecompiledHeader="0"
@ -372,6 +372,14 @@
RelativePath=".\Source\ps2\Iop_Dmac.h"
>
</File>
<File
RelativePath=".\Source\ps2\Iop_DmacChannel.cpp"
>
</File>
<File
RelativePath=".\Source\ps2\Iop_DmacChannel.h"
>
</File>
<File
RelativePath=".\Source\ps2\PsfDevice.cpp"
>