mirror of
https://github.com/libretro/Play-.git
synced 2025-01-26 03:04:20 +00:00
git-svn-id: http://svn.purei.org/purei/trunk@392 b36208d7-6611-0410-8bec-b1987f11c4a2
This commit is contained in:
parent
1d1298fef1
commit
f9d4017041
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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()
|
||||
|
@ -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;
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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:
|
||||
|
@ -40,7 +40,7 @@
|
||||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories=""C:\Program Files\OpenAL 1.1 SDK\include";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=""C:\Program Files\OpenAL 1.1 SDK\include";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=""C:\Program Files\OpenAL 1.1 SDK\include";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=""C:\Program Files\OpenAL 1.1 SDK\include";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"
|
||||
>
|
||||
|
Loading…
x
Reference in New Issue
Block a user