Added basic support for transfers from GS to EE memory.

This commit is contained in:
Jean-Philip Desjardins 2015-11-17 22:09:46 -05:00
parent 4afd80949a
commit bb6840c6a8
10 changed files with 102 additions and 14 deletions

View File

@ -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:

View File

@ -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));

View File

@ -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;

View File

@ -50,6 +50,8 @@ public:
uint32 GetRegister(uint32);
void SetRegister(uint32, uint32);
CGSHandler* GetGsHandler();
void SetPath3Masked(bool);
void LoadState(Framework::CZipArchiveReader&);

View File

@ -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())
{

View File

@ -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];

View File

@ -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

View File

@ -16,6 +16,8 @@ public:
virtual uint32 GetTOP() const override;
virtual uint32 ReceiveDMA(uint32, uint32, uint32, bool) override;
private:
typedef std::vector<uint8> ByteArray;

View File

@ -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)
{

View File

@ -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();