mirror of
https://github.com/libretro/Play-.git
synced 2024-12-04 15:26:23 +00:00
Added basic support for transfers from GS to EE memory.
This commit is contained in:
parent
4afd80949a
commit
bb6840c6a8
@ -115,13 +115,6 @@ void CChannel::Execute()
|
||||
assert(m_number == CDMAC::CHANNEL_ID_TO_IPU);
|
||||
return;
|
||||
}
|
||||
if((m_number == CDMAC::CHANNEL_ID_VIF1) && (m_CHCR.nDIR == 0))
|
||||
{
|
||||
//Humm, destination mode, not supported for now.
|
||||
CLog::GetInstance().Print(LOG_NAME, "Warning: Using destination mode for channel %d. Cancelling transfer.\r\n", m_number);
|
||||
ClearSTR();
|
||||
return;
|
||||
}
|
||||
switch(m_CHCR.nMOD)
|
||||
{
|
||||
case 0x00:
|
||||
|
@ -129,8 +129,8 @@ CSubSystem::CSubSystem(uint8* iopRam, CIopBios& iopBios)
|
||||
m_VU0.m_vuMem = m_vuMem0;
|
||||
m_VU1.m_vuMem = m_vuMem1;
|
||||
|
||||
m_dmac.SetChannelTransferFunction(CDMAC::CHANNEL_ID_VIF0, bind(&CVif::ReceiveDMA, &m_vpu0->GetVif(), PLACEHOLDER_1, PLACEHOLDER_2, PLACEHOLDER_4));
|
||||
m_dmac.SetChannelTransferFunction(CDMAC::CHANNEL_ID_VIF1, bind(&CVif::ReceiveDMA, &m_vpu1->GetVif(), PLACEHOLDER_1, PLACEHOLDER_2, PLACEHOLDER_4));
|
||||
m_dmac.SetChannelTransferFunction(CDMAC::CHANNEL_ID_VIF0, bind(&CVif::ReceiveDMA, &m_vpu0->GetVif(), PLACEHOLDER_1, PLACEHOLDER_2, PLACEHOLDER_3, PLACEHOLDER_4));
|
||||
m_dmac.SetChannelTransferFunction(CDMAC::CHANNEL_ID_VIF1, bind(&CVif::ReceiveDMA, &m_vpu1->GetVif(), PLACEHOLDER_1, PLACEHOLDER_2, PLACEHOLDER_3, PLACEHOLDER_4));
|
||||
m_dmac.SetChannelTransferFunction(CDMAC::CHANNEL_ID_GIF, bind(&CGIF::ReceiveDMA, &m_gif, PLACEHOLDER_1, PLACEHOLDER_2, PLACEHOLDER_3, PLACEHOLDER_4));
|
||||
m_dmac.SetChannelTransferFunction(CDMAC::CHANNEL_ID_TO_IPU, bind(&CIPU::ReceiveDMA4, &m_ipu, PLACEHOLDER_1, PLACEHOLDER_2, PLACEHOLDER_4, m_ram));
|
||||
m_dmac.SetChannelTransferFunction(CDMAC::CHANNEL_ID_SIF0, bind(&CSIF::ReceiveDMA5, &m_sif, PLACEHOLDER_1, PLACEHOLDER_2, PLACEHOLDER_3, PLACEHOLDER_4));
|
||||
|
@ -375,6 +375,11 @@ void CGIF::SetRegister(uint32 address, uint32 value)
|
||||
#endif
|
||||
}
|
||||
|
||||
CGSHandler* CGIF::GetGsHandler()
|
||||
{
|
||||
return m_gs;
|
||||
}
|
||||
|
||||
void CGIF::SetPath3Masked(bool masked)
|
||||
{
|
||||
m_path3Masked = masked;
|
||||
|
@ -50,6 +50,8 @@ public:
|
||||
uint32 GetRegister(uint32);
|
||||
void SetRegister(uint32, uint32);
|
||||
|
||||
CGSHandler* GetGsHandler();
|
||||
|
||||
void SetPath3Masked(bool);
|
||||
|
||||
void LoadState(Framework::CZipArchiveReader&);
|
||||
|
@ -36,6 +36,8 @@
|
||||
|
||||
CVif::CVif(unsigned int number, CVpu& vpu, uint8* ram, uint8* spr)
|
||||
: m_number(number)
|
||||
, m_ram(ram)
|
||||
, m_spr(spr)
|
||||
, m_stream(ram, spr)
|
||||
, m_vpu(vpu)
|
||||
, m_vifProfilerZone(CProfiler::GetInstance().RegisterZone(string_format("VIF%d", number).c_str()))
|
||||
@ -194,7 +196,7 @@ uint32 CVif::GetITOP() const
|
||||
return m_ITOP;
|
||||
}
|
||||
|
||||
uint32 CVif::ReceiveDMA(uint32 address, uint32 qwc, bool tagIncluded)
|
||||
uint32 CVif::ReceiveDMA(uint32 address, uint32 qwc, uint32 unused, bool tagIncluded)
|
||||
{
|
||||
if(m_STAT.nVEW && m_vpu.IsVuRunning())
|
||||
{
|
||||
|
@ -43,7 +43,7 @@ public:
|
||||
virtual uint32 GetTOP() const;
|
||||
virtual uint32 GetITOP() const;
|
||||
|
||||
uint32 ReceiveDMA(uint32, uint32, bool);
|
||||
virtual uint32 ReceiveDMA(uint32, uint32, uint32, bool);
|
||||
|
||||
bool IsWaitingForProgramEnd() const;
|
||||
bool IsStalledByInterrupt() const;
|
||||
@ -182,6 +182,8 @@ protected:
|
||||
|
||||
unsigned int m_number = 0;
|
||||
CVpu& m_vpu;
|
||||
uint8* m_ram = nullptr;
|
||||
uint8* m_spr = nullptr;
|
||||
CFifoStream m_stream;
|
||||
|
||||
uint8 m_fifoBuffer[FIFO_SIZE];
|
||||
|
@ -4,6 +4,7 @@
|
||||
#include "../RegisterStateFile.h"
|
||||
#include "../FrameDump.h"
|
||||
#include "GIF.h"
|
||||
#include "Dmac_Channel.h"
|
||||
#include "Vpu.h"
|
||||
#include "Vif1.h"
|
||||
|
||||
@ -64,6 +65,34 @@ uint32 CVif1::GetTOP() const
|
||||
return m_TOP;
|
||||
}
|
||||
|
||||
uint32 CVif1::ReceiveDMA(uint32 address, uint32 qwc, uint32 direction, bool tagIncluded)
|
||||
{
|
||||
if(direction == Dmac::CChannel::CHCR_DIR_TO)
|
||||
{
|
||||
uint8* source = nullptr;
|
||||
uint32 size = qwc * 0x10;
|
||||
if(address & 0x80000000)
|
||||
{
|
||||
source = m_spr;
|
||||
address &= (PS2::EE_SPR_SIZE - 1);
|
||||
assert((address + size) <= PS2::EE_SPR_SIZE);
|
||||
}
|
||||
else
|
||||
{
|
||||
source = m_ram;
|
||||
address &= (PS2::EE_RAM_SIZE - 1);
|
||||
assert((address + size) <= PS2::EE_RAM_SIZE);
|
||||
}
|
||||
auto gs = m_gif.GetGsHandler();
|
||||
gs->ReadImageData(source + address, size);
|
||||
return qwc;
|
||||
}
|
||||
else
|
||||
{
|
||||
return CVif::ReceiveDMA(address, qwc, direction, tagIncluded);
|
||||
}
|
||||
}
|
||||
|
||||
void CVif1::ExecuteCommand(StreamType& stream, CODE nCommand)
|
||||
{
|
||||
#ifdef _DEBUG
|
||||
|
@ -16,6 +16,8 @@ public:
|
||||
|
||||
virtual uint32 GetTOP() const override;
|
||||
|
||||
virtual uint32 ReceiveDMA(uint32, uint32, uint32, bool) override;
|
||||
|
||||
private:
|
||||
typedef std::vector<uint8> ByteArray;
|
||||
|
||||
|
@ -392,6 +392,11 @@ void CGSHandler::FeedImageData(const void* data, uint32 length)
|
||||
m_mailBox.SendCall(std::bind(&CGSHandler::FeedImageDataImpl, this, buffer, length));
|
||||
}
|
||||
|
||||
void CGSHandler::ReadImageData(void* data, uint32 length)
|
||||
{
|
||||
m_mailBox.SendCall([this, data, length] () { ReadImageDataImpl(data, length); }, true);
|
||||
}
|
||||
|
||||
void CGSHandler::WriteRegisterMassively(const RegisterWrite* writeList, unsigned int count, const CGsPacketMetadata* metadata)
|
||||
{
|
||||
for(unsigned int i = 0; i < count; i++)
|
||||
@ -504,7 +509,7 @@ void CGSHandler::FeedImageDataImpl(void* pData, uint32 nLength)
|
||||
if(m_trxCtx.nSize == 0)
|
||||
{
|
||||
auto trxReg = make_convertible<TRXREG>(m_nReg[GS_REG_TRXREG]);
|
||||
assert(m_trxCtx.nRRY == trxReg.nRRH);
|
||||
//assert(m_trxCtx.nRRY == trxReg.nRRH);
|
||||
ProcessImageTransfer();
|
||||
|
||||
#ifdef _DEBUG
|
||||
@ -517,6 +522,41 @@ void CGSHandler::FeedImageDataImpl(void* pData, uint32 nLength)
|
||||
m_transferCount--;
|
||||
}
|
||||
|
||||
void CGSHandler::ReadImageDataImpl(void* ptr, uint32 size)
|
||||
{
|
||||
assert(m_trxCtx.nSize != 0);
|
||||
assert(m_trxCtx.nSize == size);
|
||||
auto bltBuf = make_convertible<BITBLTBUF>(m_nReg[GS_REG_BITBLTBUF]);
|
||||
auto trxReg = make_convertible<TRXREG>(m_nReg[GS_REG_TRXREG]);
|
||||
auto trxPos = make_convertible<TRXPOS>(m_nReg[GS_REG_TRXPOS]);
|
||||
|
||||
assert(trxPos.nDIR == 0);
|
||||
switch(bltBuf.nSrcPsm)
|
||||
{
|
||||
case PSMCT32:
|
||||
{
|
||||
CGsPixelFormats::CPixelIndexorPSMCT32 indexor(m_pRAM, bltBuf.GetSrcPtr(), bltBuf.nSrcWidth);
|
||||
for(uint32 i = 0; i < size / sizeof(uint32); i++)
|
||||
{
|
||||
uint32 x = (m_trxCtx.nRRX + trxPos.nSSAX) % 2048;
|
||||
uint32 y = (m_trxCtx.nRRY + trxPos.nSSAY) % 2048;
|
||||
auto pixel = indexor.GetPixel(x, y);
|
||||
reinterpret_cast<uint32*>(ptr)[i] = pixel;
|
||||
m_trxCtx.nRRX++;
|
||||
if(m_trxCtx.nRRX == trxReg.nRRW)
|
||||
{
|
||||
m_trxCtx.nRRX = 0;
|
||||
m_trxCtx.nRRY++;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
default:
|
||||
assert(false);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void CGSHandler::WriteRegisterMassivelyImpl(MASSIVEWRITE_INFO* massiveWrite)
|
||||
{
|
||||
#ifdef DEBUGGER_INCLUDED
|
||||
@ -541,9 +581,9 @@ void CGSHandler::WriteRegisterMassivelyImpl(MASSIVEWRITE_INFO* massiveWrite)
|
||||
void CGSHandler::BeginTransfer()
|
||||
{
|
||||
uint32 trxDir = m_nReg[GS_REG_TRXDIR] & 0x03;
|
||||
if(trxDir == 0)
|
||||
if(trxDir == 0 || trxDir == 1)
|
||||
{
|
||||
//From Host to Local
|
||||
//"Host to Local" or "Local to Host"
|
||||
auto bltBuf = make_convertible<BITBLTBUF>(m_nReg[GS_REG_BITBLTBUF]);
|
||||
auto trxReg = make_convertible<TRXREG>(m_nReg[GS_REG_TRXREG]);
|
||||
unsigned int nPixelSize = 0;
|
||||
@ -582,6 +622,17 @@ void CGSHandler::BeginTransfer()
|
||||
m_trxCtx.nRRX = 0;
|
||||
m_trxCtx.nRRY = 0;
|
||||
m_trxCtx.nDirty = false;
|
||||
|
||||
if(trxDir == 0)
|
||||
{
|
||||
CLog::GetInstance().Print(LOG_NAME, "Starting transfer to 0x%0.8X, buffer size %d, psm: %d, size (%dx%d)\r\n",
|
||||
bltBuf.GetDstPtr(), bltBuf.GetDstWidth(), bltBuf.nDstPsm, trxReg.nRRW, trxReg.nRRH);
|
||||
}
|
||||
else if(trxDir == 1)
|
||||
{
|
||||
CLog::GetInstance().Print(LOG_NAME, "Starting transfer from 0x%0.8X, buffer size %d, psm: %d, size (%dx%d)\r\n",
|
||||
bltBuf.GetSrcPtr(), bltBuf.GetSrcWidth(), bltBuf.nSrcPsm, trxReg.nRRW, trxReg.nRRH);
|
||||
}
|
||||
}
|
||||
else if(trxDir == 2)
|
||||
{
|
||||
|
@ -521,6 +521,7 @@ public:
|
||||
|
||||
void WriteRegister(uint8, uint64);
|
||||
void FeedImageData(const void*, uint32);
|
||||
void ReadImageData(void*, uint32);
|
||||
void WriteRegisterMassively(const RegisterWrite*, unsigned int, const CGsPacketMetadata*);
|
||||
|
||||
virtual void SetCrt(bool, unsigned int, bool);
|
||||
@ -680,6 +681,7 @@ protected:
|
||||
void MarkNewFrame();
|
||||
virtual void WriteRegisterImpl(uint8, uint64);
|
||||
virtual void FeedImageDataImpl(void*, uint32);
|
||||
void ReadImageDataImpl(void*, uint32);
|
||||
virtual void WriteRegisterMassivelyImpl(MASSIVEWRITE_INFO*);
|
||||
|
||||
void BeginTransfer();
|
||||
|
Loading…
Reference in New Issue
Block a user