mirror of
https://github.com/libretro/Play-.git
synced 2024-11-30 20:21:25 +00:00
Add basic destination chain transfer mode support for DMAch8.
This commit is contained in:
parent
900893d4a6
commit
7c3460ace5
@ -130,7 +130,14 @@ void CChannel::Execute()
|
||||
break;
|
||||
case 0x01:
|
||||
case 0x03: //FFXII uses 3 here, assuming source chain mode
|
||||
ExecuteSourceChain();
|
||||
if(m_number == CDMAC::CHANNEL_ID_FROM_SPR)
|
||||
{
|
||||
ExecuteDestinationChain();
|
||||
}
|
||||
else
|
||||
{
|
||||
ExecuteSourceChain();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
assert(0);
|
||||
@ -469,6 +476,43 @@ void CChannel::ExecuteSourceChain()
|
||||
}
|
||||
}
|
||||
|
||||
void CChannel::ExecuteDestinationChain()
|
||||
{
|
||||
assert(m_number == CDMAC::CHANNEL_ID_FROM_SPR);
|
||||
|
||||
while(m_CHCR.nSTR == 1)
|
||||
{
|
||||
assert(m_nQWC == 0);
|
||||
|
||||
auto tag = make_convertible<DMAtag>(m_dmac.FetchDMATag(m_dmac.m_D8_SADR | 0x80000000));
|
||||
m_dmac.m_D8_SADR += 0x10;
|
||||
|
||||
assert(tag.irq == 0);
|
||||
switch(tag.id)
|
||||
{
|
||||
case DMATAG_DST_CNT:
|
||||
case DMATAG_DST_END:
|
||||
m_nMADR = tag.addr;
|
||||
m_nQWC = tag.qwc;
|
||||
break;
|
||||
default:
|
||||
assert(false);
|
||||
break;
|
||||
}
|
||||
|
||||
uint32 recv = m_receive(m_nMADR, m_nQWC, m_CHCR.nDIR, false);
|
||||
assert(recv == m_nQWC);
|
||||
|
||||
m_nMADR += recv * 0x10;
|
||||
m_nQWC -= recv;
|
||||
|
||||
if(tag.id == DMATAG_DST_END)
|
||||
{
|
||||
ClearSTR();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void CChannel::SetReceiveHandler(const DmaReceiveHandler& handler)
|
||||
{
|
||||
m_receive = handler;
|
||||
|
@ -34,6 +34,17 @@ namespace Dmac
|
||||
DMATAG_DST_END = 7,
|
||||
};
|
||||
|
||||
struct DMAtag : public convertible<uint64>
|
||||
{
|
||||
unsigned int qwc : 16;
|
||||
unsigned int reserved : 10;
|
||||
unsigned int pce : 2;
|
||||
unsigned int id : 3;
|
||||
unsigned int irq : 1;
|
||||
unsigned int addr : 32;
|
||||
};
|
||||
static_assert(sizeof(DMAtag) == sizeof(uint64), "Size of DMAtag struct must be 8 bytes.");
|
||||
|
||||
enum CHCR_DIR
|
||||
{
|
||||
CHCR_DIR_TO = 0,
|
||||
@ -66,6 +77,7 @@ namespace Dmac
|
||||
void ExecuteNormal();
|
||||
void ExecuteInterleave();
|
||||
void ExecuteSourceChain();
|
||||
void ExecuteDestinationChain();
|
||||
void SetReceiveHandler(const DmaReceiveHandler&);
|
||||
|
||||
CHCR m_CHCR;
|
||||
|
Loading…
Reference in New Issue
Block a user