mirror of https://github.com/PCSX2/pcsx2.git
Some minor IPU changes.
git-svn-id: http://pcsx2.googlecode.com/svn/trunk@1892 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
parent
705ca3d92a
commit
48cdfb263b
|
@ -433,7 +433,7 @@ void MTC0()
|
|||
}
|
||||
|
||||
int CPCOND0() {
|
||||
return (((psHu16(DMAC_STAT) | ~psHu16(DMAC_PCR)) & 0x3ff) == 0x3ff);
|
||||
return ((dmacRegs->stat.CIS | ~dmacRegs->pcr.CPC) == 0x3ff);
|
||||
}
|
||||
|
||||
//#define CPCOND0 1
|
||||
|
|
|
@ -84,7 +84,7 @@ static __forceinline void DmaExec16( void (*func)(), u32 mem, u16 value )
|
|||
}
|
||||
|
||||
psHu16(mem) = (u16)value;
|
||||
if ((psHu16(mem) & 0x100) && (psHu32(DMAC_CTRL) & 0x1))
|
||||
if ((psHu16(mem) & 0x100) && dmacRegs->ctrl.DMAE)
|
||||
{
|
||||
//Console::WriteLn("16bit DMA Start");
|
||||
func();
|
||||
|
|
|
@ -46,26 +46,15 @@ using namespace std; // for min / max
|
|||
# define IPU_FORCEINLINE __forceinline
|
||||
#endif
|
||||
|
||||
#define IPU_DMA_GIFSTALL 1
|
||||
#define IPU_DMA_TIE0 2
|
||||
#define IPU_DMA_TIE1 4
|
||||
#define IPU_DMA_ACTV1 8
|
||||
#define IPU_DMA_DOTIE1 16
|
||||
#define IPU_DMA_FIREINT0 32
|
||||
#define IPU_DMA_FIREINT1 64
|
||||
#define IPU_DMA_VIFSTALL 128
|
||||
|
||||
// FIXME - g_nIPU0Data and Pointer are not saved in the savestate, which breaks savestates for some
|
||||
// FMVs at random (if they get saved during the half frame of a 30fps rate). The fix is complicated
|
||||
// since coroutine is such a pita. (air)
|
||||
|
||||
static int g_nDMATransfer = 0;
|
||||
int g_nIPU0Data = 0; // data left to transfer
|
||||
u8* g_pIPU0Pointer = NULL;
|
||||
int g_nCmdPos[2] = {0}, g_nCmdIndex = 0;
|
||||
int ipuCurCmd = 0xffffffff;
|
||||
|
||||
|
||||
int FOreadpos = 0, FOwritepos = 0;
|
||||
static int FIreadpos = 0, FIwritepos = 0;
|
||||
PCSX2_ALIGNED16(u32 fifo_input[32]);
|
||||
|
@ -158,6 +147,7 @@ int ipuInit()
|
|||
memzero_obj(*ipuRegs);
|
||||
memzero_obj(g_BP);
|
||||
init_g_decoder();
|
||||
g_nDMATransfer._u32 = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -165,7 +155,7 @@ int ipuInit()
|
|||
void ipuReset()
|
||||
{
|
||||
memzero_obj(*ipuRegs);
|
||||
g_nDMATransfer = 0;
|
||||
g_nDMATransfer._u32 = 0;
|
||||
}
|
||||
|
||||
void ipuShutdown()
|
||||
|
@ -174,7 +164,7 @@ void ipuShutdown()
|
|||
|
||||
void ReportIPU()
|
||||
{
|
||||
Console::WriteLn("g_nDMATransfer = 0x%x.", g_nDMATransfer);
|
||||
Console::WriteLn("g_nDMATransfer = 0x%x.", g_nDMATransfer._u32);
|
||||
Console::WriteLn("FIreadpos = 0x%x, FIwritepos = 0x%x.", FIreadpos, FIwritepos);
|
||||
Console::WriteLn("fifo_input = 0x%x.", fifo_input);
|
||||
Console::WriteLn("FOreadpos = 0x%x, FOwritepos = 0x%x.", FOreadpos, FOwritepos);
|
||||
|
@ -204,7 +194,7 @@ void SaveStateBase::ipuFreeze()
|
|||
// old versions saved the IPU regs, but they're already saved as part of HW!
|
||||
//FreezeMem(ipuRegs, sizeof(IPUregisters));
|
||||
|
||||
Freeze(g_nDMATransfer);
|
||||
Freeze(g_nDMATransfer._u32);
|
||||
Freeze(FIreadpos);
|
||||
Freeze(FIwritepos);
|
||||
Freeze(fifo_input);
|
||||
|
@ -1380,7 +1370,7 @@ static __forceinline bool IPU1chain(int &totalqwc)
|
|||
|
||||
if (ipu1dma->qwc > 0)
|
||||
{
|
||||
g_nDMATransfer |= IPU_DMA_ACTV1;
|
||||
g_nDMATransfer.ACTV1 = 1;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -1464,24 +1454,26 @@ int IPU1dma()
|
|||
|
||||
if (!(ipu1dma->chcr.STR) || (cpuRegs.interrupt & (1 << DMAC_TO_IPU))) return 0;
|
||||
|
||||
assert(!(g_nDMATransfer & IPU_DMA_TIE1));
|
||||
assert(g_nDMATransfer.TIE1 == 0);
|
||||
|
||||
//We need to make sure GIF has flushed before sending IPU data, it seems to REALLY screw FFX videos
|
||||
flushGIF();
|
||||
|
||||
// in kh, qwc == 0 when dma_actv1 is set
|
||||
if ((g_nDMATransfer & IPU_DMA_ACTV1) && ipu1dma->qwc > 0)
|
||||
if ((g_nDMATransfer.ACTV1) && ipu1dma->qwc > 0)
|
||||
{
|
||||
if (IPU1chain(totalqwc)) return totalqwc;
|
||||
|
||||
//Check TIE bit of CHCR and IRQ bit of tag
|
||||
if (ipu1dma->chcr.TIE && (g_nDMATransfer & IPU_DMA_DOTIE1))
|
||||
if (ipu1dma->chcr.TIE && (g_nDMATransfer.DOTIE1))
|
||||
{
|
||||
Console::WriteLn("IPU1 TIE");
|
||||
|
||||
IPU_INT_TO(totalqwc * BIAS);
|
||||
g_nDMATransfer &= ~(IPU_DMA_ACTV1 | IPU_DMA_DOTIE1);
|
||||
g_nDMATransfer |= IPU_DMA_TIE1;
|
||||
g_nDMATransfer.TIE1 = 1;
|
||||
g_nDMATransfer.DOTIE1 = 0;
|
||||
g_nDMATransfer.ACTV1 = 0;
|
||||
|
||||
return totalqwc;
|
||||
}
|
||||
|
||||
|
@ -1505,7 +1497,7 @@ int IPU1dma()
|
|||
|
||||
IPU_LOG("IPU dmaIrq Set");
|
||||
IPU_INT_TO(totalqwc * BIAS);
|
||||
g_nDMATransfer |= IPU_DMA_TIE1;
|
||||
g_nDMATransfer.TIE1 = 1;
|
||||
return totalqwc;
|
||||
}
|
||||
|
||||
|
@ -1516,7 +1508,8 @@ int IPU1dma()
|
|||
}
|
||||
}
|
||||
|
||||
g_nDMATransfer &= ~(IPU_DMA_ACTV1 | IPU_DMA_DOTIE1);
|
||||
g_nDMATransfer.DOTIE1 = 0;
|
||||
g_nDMATransfer.ACTV1 = 0;
|
||||
}
|
||||
|
||||
// Normal Mode & qwc is finished
|
||||
|
@ -1551,16 +1544,12 @@ int IPU1dma()
|
|||
IPU_LOG("dmaIPU1 dmaChain %8.8x_%8.8x size=%d, addr=%lx, fifosize=%x",
|
||||
ptag[1], ptag[0], ipu1dma->qwc, ipu1dma->madr, 8 - g_BP.IFC);
|
||||
|
||||
|
||||
if (ipu1dma->chcr.TIE && Tag::IRQ(ptag))
|
||||
g_nDMATransfer |= IPU_DMA_DOTIE1;
|
||||
else
|
||||
g_nDMATransfer &= ~IPU_DMA_DOTIE1;
|
||||
g_nDMATransfer.DOTIE1 = (ipu1dma->chcr.TIE && Tag::IRQ(ptag));
|
||||
|
||||
if (ipu1dma->qwc == 0)
|
||||
{
|
||||
//Check TIE bit of CHCR and IRQ bit of tag
|
||||
if (g_nDMATransfer & IPU_DMA_DOTIE1)
|
||||
if (g_nDMATransfer.DOTIE1)
|
||||
{
|
||||
Console::WriteLn("IPU1 TIE");
|
||||
|
||||
|
@ -1577,7 +1566,7 @@ int IPU1dma()
|
|||
}
|
||||
|
||||
IPU_INT_TO(ipu1cycles + totalqwc * BIAS); // Should it be (ipu1cycles + totalqwc) * BIAS?
|
||||
g_nDMATransfer |= IPU_DMA_TIE1;
|
||||
g_nDMATransfer.TIE1 = 1;
|
||||
return totalqwc;
|
||||
}
|
||||
else
|
||||
|
@ -1679,22 +1668,30 @@ int IPU0dma()
|
|||
|
||||
assert((ipu0dma->chcr._u32 & 0xC) == 0);
|
||||
pMem = (u32*)dmaGetAddr(ipu0dma->madr);
|
||||
|
||||
readsize = min(ipu0dma->qwc, (u16)ipuRegs->ctrl.OFC);
|
||||
FIFOfrom_read(pMem, readsize);
|
||||
|
||||
ipu0dma->madr += readsize << 4;
|
||||
ipu0dma->qwc -= readsize; // note: qwc is u16
|
||||
|
||||
if (ipu0dma->qwc == 0)
|
||||
{
|
||||
if ((psHu32(DMAC_CTRL) & 0x30) == 0x30) // STS == fromIPU
|
||||
if (dmacRegs->ctrl.STS == STS_fromIPU) // STS == fromIPU
|
||||
{
|
||||
psHu32(DMAC_STADR) = ipu0dma->madr;
|
||||
switch (psHu32(DMAC_CTRL) & 0xC0)
|
||||
dmacRegs->stadr.ADDR = ipu0dma->madr;
|
||||
switch (dmacRegs->ctrl.STD)
|
||||
{
|
||||
case 0x80: // GIF
|
||||
g_nDMATransfer |= IPU_DMA_GIFSTALL;
|
||||
case NO_STD:
|
||||
break;
|
||||
case 0x40: // VIF
|
||||
g_nDMATransfer |= IPU_DMA_VIFSTALL;
|
||||
case STD_GIF: // GIF
|
||||
g_nDMATransfer.GIFSTALL = 1;
|
||||
break;
|
||||
case STD_VIF1: // VIF
|
||||
g_nDMATransfer.VIFSTALL = 1;
|
||||
break;
|
||||
case STD_SIF1:
|
||||
g_nDMATransfer.SIFSTALL = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1721,33 +1718,42 @@ void ipu0Interrupt()
|
|||
{
|
||||
IPU_LOG("ipu0Interrupt: %x", cpuRegs.cycle);
|
||||
|
||||
if (g_nDMATransfer & IPU_DMA_FIREINT0)
|
||||
if (g_nDMATransfer.FIREINT0)
|
||||
{
|
||||
g_nDMATransfer.FIREINT0 = 0;
|
||||
hwIntcIrq(INTC_IPU);
|
||||
g_nDMATransfer &= ~IPU_DMA_FIREINT0;
|
||||
}
|
||||
|
||||
if (g_nDMATransfer & IPU_DMA_GIFSTALL)
|
||||
if (g_nDMATransfer.GIFSTALL)
|
||||
{
|
||||
// gif
|
||||
g_nDMATransfer &= ~IPU_DMA_GIFSTALL;
|
||||
g_nDMATransfer.GIFSTALL = 0;
|
||||
if (gif->chcr.STR) GIFdma();
|
||||
}
|
||||
|
||||
if (g_nDMATransfer & IPU_DMA_VIFSTALL)
|
||||
if (g_nDMATransfer.VIFSTALL)
|
||||
{
|
||||
// vif
|
||||
g_nDMATransfer &= ~IPU_DMA_VIFSTALL;
|
||||
g_nDMATransfer.VIFSTALL = 0;
|
||||
if (vif1ch->chcr.STR) dmaVIF1();
|
||||
}
|
||||
|
||||
if (g_nDMATransfer & IPU_DMA_TIE0)
|
||||
if (g_nDMATransfer.SIFSTALL)
|
||||
{
|
||||
g_nDMATransfer &= ~IPU_DMA_TIE0;
|
||||
// sif
|
||||
g_nDMATransfer.SIFSTALL = 0;
|
||||
|
||||
// Not totally sure whether this needs to be done or not, so I'm
|
||||
// leaving it commented out for the moment.
|
||||
//if (sif1dma->chcr.STR) SIF1Dma();
|
||||
}
|
||||
|
||||
if (g_nDMATransfer.TIE0)
|
||||
{
|
||||
g_nDMATransfer.TIE0 = 0;
|
||||
}
|
||||
|
||||
ipu0dma->chcr.STR = 0;
|
||||
|
||||
hwDmacIrq(DMAC_FROM_IPU);
|
||||
}
|
||||
|
||||
|
@ -1755,14 +1761,14 @@ IPU_FORCEINLINE void ipu1Interrupt()
|
|||
{
|
||||
IPU_LOG("ipu1Interrupt %x:", cpuRegs.cycle);
|
||||
|
||||
if (g_nDMATransfer & IPU_DMA_FIREINT1)
|
||||
if (g_nDMATransfer.FIREINT1)
|
||||
{
|
||||
hwIntcIrq(INTC_IPU);
|
||||
g_nDMATransfer &= ~IPU_DMA_FIREINT1;
|
||||
g_nDMATransfer.FIREINT1 = 0;
|
||||
}
|
||||
|
||||
if (g_nDMATransfer & IPU_DMA_TIE1)
|
||||
g_nDMATransfer &= ~IPU_DMA_TIE1;
|
||||
if (g_nDMATransfer.TIE1)
|
||||
g_nDMATransfer.TIE1 = 0;
|
||||
else
|
||||
ipu1dma->chcr.STR = 0;
|
||||
|
||||
|
|
|
@ -154,6 +154,25 @@ union tIPU_CMD_CSC
|
|||
}
|
||||
};
|
||||
|
||||
union tIPU_DMA
|
||||
{
|
||||
struct
|
||||
{
|
||||
u32 GIFSTALL : 1;
|
||||
u32 TIE0 :1;
|
||||
u32 TIE1 : 1;
|
||||
u32 ACTV1 : 1;
|
||||
u32 DOTIE1 : 1;
|
||||
u32 FIREINT0 : 1;
|
||||
u32 FIREINT1 : 1;
|
||||
u32 VIFSTALL : 1;
|
||||
u32 SIFSTALL : 1;
|
||||
};
|
||||
u32 _u32;
|
||||
};
|
||||
|
||||
static tIPU_DMA g_nDMATransfer;
|
||||
|
||||
enum SCE_IPU
|
||||
{
|
||||
SCE_IPU_BCLR = 0x0
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
// the lower 16 bit value. IF the change is breaking of all compatibility with old
|
||||
// states, increment the upper 16 bit value, and clear the lower 16 bits to 0.
|
||||
|
||||
static const u32 g_SaveVersion = 0x8b410002;
|
||||
static const u32 g_SaveVersion = 0x8b410003;
|
||||
|
||||
// this function is meant to be used in the place of GSfreeze, and provides a safe layer
|
||||
// between the GS saving function and the MTGS's needs. :)
|
||||
|
|
42
pcsx2/Tags.h
42
pcsx2/Tags.h
|
@ -121,7 +121,7 @@ namespace Tag
|
|||
UpperTransfer(tag, ptag);
|
||||
|
||||
// Set BEIS (BUSERR) in DMAC_STAT register
|
||||
psHu32(DMAC_STAT) |= DMAC_STAT_BEIS;
|
||||
dmacRegs->stat.BEIS = 1;
|
||||
return false;
|
||||
}
|
||||
else
|
||||
|
@ -132,25 +132,6 @@ namespace Tag
|
|||
}
|
||||
}
|
||||
|
||||
/*// Not sure if I'll need this one.
|
||||
static __forceinline bool SafeTransfer(const char *s, DMACh *tag, u32* ptag)
|
||||
{
|
||||
if (ptag == NULL) // Is ptag empty?
|
||||
{
|
||||
Console::Error("%s BUSERR", s);
|
||||
|
||||
// Set BEIS (BUSERR) in DMAC_STAT register
|
||||
psHu32(DMAC_STAT) |= DMAC_STAT_BEIS;
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
UpperTransfer(tag, ptag);
|
||||
LowerTransfer(tag, ptag);
|
||||
return true;
|
||||
}
|
||||
}*/
|
||||
|
||||
static __forceinline void UnsafeTransfer(DMACh *tag, u32* ptag)
|
||||
{
|
||||
UpperTransfer(tag, ptag);
|
||||
|
@ -214,24 +195,3 @@ static __forceinline void PrintCHCR(const char* s, DMACh *tag)
|
|||
Console::WriteLn("");
|
||||
}
|
||||
|
||||
namespace D_CTRL
|
||||
{
|
||||
static __forceinline bool DMAE() { return !!(psHu32(DMAC_CTRL) & CTRL_DMAE); }
|
||||
static __forceinline bool RELE() { return !!(psHu32(DMAC_CTRL) & CTRL_RELE); }
|
||||
static __forceinline mfd_type MFD()
|
||||
{
|
||||
return (mfd_type)((psHu32(DMAC_CTRL) & CTRL_MFD) >> 2);
|
||||
}
|
||||
static __forceinline sts_type STS()
|
||||
{
|
||||
return (sts_type)((psHu32(DMAC_CTRL) & CTRL_STS) >> 4);
|
||||
}
|
||||
static __forceinline std_type STD()
|
||||
{
|
||||
return (std_type)((psHu32(DMAC_CTRL) & CTRL_STD) >> 6);
|
||||
}
|
||||
static __forceinline int RCYC()
|
||||
{
|
||||
return ((((psHu32(DMAC_CTRL) & CTRL_RCYC) >> 3) + 1) * 8);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue