Sif: Refinements on my last commit.

git-svn-id: http://pcsx2.googlecode.com/svn/trunk@2537 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
arcum42 2010-01-29 04:06:22 +00:00
parent be9faf9002
commit 6db393faec
4 changed files with 104 additions and 44 deletions

View File

@ -20,8 +20,7 @@
#include "IopCommon.h"
#include "Sif.h"
_sif sif0, sif1;
extern _sif sif0, sif1;
bool eesifbusy[2] = { false, false };
extern bool iopsifbusy[2];

View File

@ -69,6 +69,13 @@ struct sifFifo
}
SIF_LOG(" SIF - %d = %d (pos=%d)", words, size, readPos);
}
void clear()
{
memzero(data);
readPos = 0;
writePos = 0;
size = 0;
}
};
struct _sif
@ -80,10 +87,8 @@ struct _sif
s32 counter;
struct sifData data;
};
extern _sif sif0, sif1;
extern bool eesifbusy[2];
extern bool iopsifbusy[2];
extern bool eesifbusy[2], iopsifbusy[2];
extern void sifInit();

View File

@ -20,7 +20,23 @@
#include "IopCommon.h"
#include "Sif.h"
static __forceinline bool SifEERead(int &cycles)
_sif sif0;
static bool done = false;
static int cycles = 0, psxCycles = 0;
static __forceinline void Sif0Init()
{
done = false;
cycles = 0;
psxCycles = 0;
memzero(sif0);
//sif0.end = 0;
//sif0.data.data = 0;
}
// Write from Fifo to EE.
static __forceinline bool SifEERead()
{
const int readSize = min((s32)sif0dma->qwc, sif0.fifo.size >> 2);
//if (readSize <= 0)
@ -54,7 +70,8 @@ static __forceinline bool SifEERead(int &cycles)
return true;
}
static __forceinline bool SifIOPWrite(int &psxCycles)
// Write IOP to Fifo.
static __forceinline bool SifIOPWrite()
{
// There's some data ready to transfer into the fifo..
const int writeSize = min(sif0.counter, sif0.fifo.free());
@ -76,6 +93,7 @@ static __forceinline bool SifIOPWrite(int &psxCycles)
return true;
}
// Read Fifo into an ee tag, transfer it to sif0dma, and process it.
static __forceinline bool SIFEEReadTag()
{
static __aligned16 u32 tag[4];
@ -116,14 +134,17 @@ static __forceinline bool SIFEEReadTag()
return true;
}
// Read Fifo into an ee tag, and transfer it to hw_dma(9). And presumably process it.
static __forceinline bool SIFIOPWriteTag()
{
// Process DMA tag at HW_DMA9_TADR
// Process DMA tag at hw_dma(9).tadr
sif0.data = *(sifData *)iopPhysMem(hw_dma(9).tadr);
sif0.data.words = (sif0.data.words + 3) & 0xfffffffc; // Round up to nearest 4.
sif0.fifo.write((u32*)iopPhysMem(hw_dma(9).tadr + 8), 4);
hw_dma(9).tadr += 16; ///hw_dma(9).madr + 16 + sif0.sifData.words << 2;
// Looks like we are only copying the first 24 bits.
hw_dma(9).madr = sif0.data.data & 0xFFFFFF;
sif0.counter = sif0.data.words & 0xFFFFFF;
@ -132,19 +153,17 @@ static __forceinline bool SIFIOPWriteTag()
return true;
}
static __forceinline void SIF0EEend(int &cycles)
// Stop transferring ee, and signal an interrupt.
static __forceinline void SIF0EEend()
{
// Stop & signal interrupts on EE
sif0.end = 0;
eesifbusy[0] = false;
if (cycles == 0) DevCon.Warning("EESIF0cycles = 0"); // No transfer happened
else CPU_INT(DMAC_SIF0, cycles*BIAS); // Hence no Interrupt
}
static __forceinline void SIF0IOPend(int &psxCycles)
// Stop transferring iop, and signal an interrupt.
static __forceinline void SIF0IOPend()
{
// Stop & signal interrupts on IOP
sif0.data.data = 0;
iopsifbusy[0] = false;
// iop is 1/8th the clock rate of the EE and psxcycles is in words (not quadwords)
@ -154,7 +173,8 @@ static __forceinline void SIF0IOPend(int &psxCycles)
else PSX_INT(IopEvt_SIF0, psxCycles); // Hence no Interrupt
}
static __forceinline void SIF0EEDma(int &cycles, bool &done)
// Handle the EE transfer.
static __forceinline void SIF0EEDma()
{
#ifdef PCSX2_DEVBUILD
if (dmacRegs->ctrl.STS == STS_SIF0)
@ -168,7 +188,7 @@ static __forceinline void SIF0EEDma(int &cycles, bool &done)
if ((sif0dma->chcr.MOD == NORMAL_MODE) || sif0.end)
{
done = true;
SIF0EEend(cycles);
SIF0EEend();
}
else if (sif0.fifo.size >= 4) // Read a tag
{
@ -179,19 +199,20 @@ static __forceinline void SIF0EEDma(int &cycles, bool &done)
if (sif0dma->qwc > 0) // If we're reading something continue to do so
{
SifEERead(cycles);
SifEERead();
}
}
// Handle the IOP transfer.
// Note: Test any changes in this function against Grandia III.
static __forceinline void SIF0IOPDma(int &psxCycles, bool &done)
static __forceinline void SIF0IOPDma()
{
if (sif0.counter <= 0) // If there's no more to transfer
{
if (sif0_tag.IRQ || (sif0_tag.ID & 4))
{
done = true;
SIF0IOPend(psxCycles);
SIF0IOPend();
}
else // Chain mode
{
@ -201,22 +222,28 @@ static __forceinline void SIF0IOPDma(int &psxCycles, bool &done)
}
else
{
SifIOPWrite(psxCycles);
SifIOPWrite();
}
}
static __forceinline void Sif0End()
{
}
// Transfer IOP to EE, putting data in the fifo as an intermediate step.
__forceinline void SIF0Dma()
{
bool done = false;
int cycles = 0, psxCycles = 0;
SIF_LOG("SIF0 DMA start...");
Sif0Init();
do
{
if (iopsifbusy[0]) SIF0IOPDma(psxCycles, done);
if (eesifbusy[0]) SIF0EEDma(cycles, done);
if (iopsifbusy[0]) SIF0IOPDma();
if (eesifbusy[0]) SIF0EEDma();
} while (!done);
SIF_LOG("SIF0 DMA end...");
Sif0End();
}
__forceinline void sif0Interrupt()

View File

@ -20,7 +20,23 @@
#include "IopCommon.h"
#include "Sif.h"
static __forceinline bool SifEEWrite(int &cycles)
_sif sif1;
static bool done = false;
static int cycles = 0, psxCycles = 0;
static __forceinline void Sif1Init()
{
done = false;
cycles = 0;
psxCycles = 0;
memzero(sif1);
//sif1.end = 0;
//sif1.data.data = 0;
}
// Write from the EE to Fifo.
static __forceinline bool SifEEWrite()
{
// There's some data ready to transfer into the fifo..
@ -50,7 +66,8 @@ static __forceinline bool SifEEWrite(int &cycles)
return true;
}
static __forceinline bool SifIOPRead(int &psxCycles)
// Read from the fifo and write to IOP
static __forceinline bool SifIOPRead()
{
// If we're reading something, continue to do so.
const int readSize = min (sif1.counter, sif1.fifo.size);
@ -72,6 +89,7 @@ static __forceinline bool SifIOPRead(int &psxCycles)
return true;
}
// Get a tag and process it.
static __forceinline bool SIFEEWriteTag()
{
// Chain mode
@ -138,6 +156,7 @@ static __forceinline bool SIFEEWriteTag()
return true;
}
// Write fifo to data, and put it in IOP.
static __forceinline bool SIFIOPReadTag()
{
// Read a tag.
@ -151,10 +170,9 @@ static __forceinline bool SIFIOPReadTag()
return true;
}
static __forceinline void SIF1EEend(int &cycles)
// Stop processing EE, and signal an interrupt.
static __forceinline void SIF1EEend()
{
// Stop & signal interrupts on EE
sif1.end = 0;
eesifbusy[1] = false;
// Voodoocycles : Okami wants around 100 cycles when booting up
@ -164,10 +182,9 @@ static __forceinline void SIF1EEend(int &cycles)
else CPU_INT(DMAC_SIF1, min((int)(cycles*BIAS), 384)); // Hence no Interrupt (fixes Eternal Poison reboot when selecting new game)
}
static __forceinline void SIF1IOPend(int &psxCycles)
// Stop processing IOP, and signal an interrupt.
static __forceinline void SIF1IOPend()
{
// Stop & signal interrupts on IOP
sif1.data.data = 0;
iopsifbusy[1] = false;
//Fixme ( voodoocycles ):
@ -178,7 +195,8 @@ static __forceinline void SIF1IOPend(int &psxCycles)
else PSX_INT(IopEvt_SIF1, min((psxCycles * 26), 1024)); // Hence no Interrupt
}
static __forceinline void SIF1EEDma(int &cycles, bool &done)
// Handle the EE transfer.
static __forceinline void SIF1EEDma()
{
#ifdef PCSX2_DEVBUILD
if (dmacRegs->ctrl.STD == STD_SIF1)
@ -194,7 +212,7 @@ static __forceinline void SIF1EEDma(int &cycles, bool &done)
if ((sif1dma->chcr.MOD == NORMAL_MODE) || sif1.end)
{
done = true;
SIF1EEend(cycles);
SIF1EEend();
}
else
{
@ -204,15 +222,16 @@ static __forceinline void SIF1EEDma(int &cycles, bool &done)
}
else
{
SifEEWrite(cycles);
SifEEWrite();
}
}
static __forceinline void SIF1IOPDma(int &psxCycles, bool &done)
// Handle the IOP transfer.
static __forceinline void SIF1IOPDma()
{
if (sif1.counter > 0)
{
SifIOPRead(psxCycles);
SifIOPRead();
}
if (sif1.counter <= 0)
@ -220,7 +239,7 @@ static __forceinline void SIF1IOPDma(int &psxCycles, bool &done)
if (sif1_tag.IRQ || (sif1_tag.ID & 4))
{
done = true;
SIF1IOPend(psxCycles);
SIF1IOPend();
}
else if (sif1.fifo.size >= 4)
{
@ -231,17 +250,25 @@ static __forceinline void SIF1IOPDma(int &psxCycles, bool &done)
}
}
static __forceinline void Sif1End()
{
}
// Transfer EE to IOP, putting data in the fifo as an intermediate step.
__forceinline void SIF1Dma()
{
bool done = false;
int cycles = 0, psxCycles = 0;
SIF_LOG("SIF1 DMA start...");
Sif1Init();
do
{
if (eesifbusy[1]) SIF1EEDma(cycles, done);
if (iopsifbusy[1]) SIF1IOPDma(psxCycles, done);
if (eesifbusy[1]) SIF1EEDma();
if (iopsifbusy[1]) SIF1IOPDma();
} while (!done);
SIF_LOG("SIF0 DMA end...");
Sif1End();
}
__forceinline void sif1Interrupt()
@ -256,6 +283,8 @@ __forceinline void EEsif1Interrupt()
sif1dma->chcr.STR = false;
}
// Do almost exactly the same thing as psxDma10 in IopDma.cpp.
// Main difference is this checks for iop, where psxDma10 checks for ee.
__forceinline void dmaSIF1()
{
SIF_LOG(wxString(L"dmaSIF1" + sif1dma->cmqt_to_str()).To8BitData());