More Tag stuff, mainly in Gif and HwWrite.

git-svn-id: http://pcsx2.googlecode.com/svn/trunk@2305 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
arcum42 2009-12-04 07:01:27 +00:00
parent 9736b4b854
commit 8a4d58ff76
4 changed files with 156 additions and 126 deletions

View File

@ -121,9 +121,13 @@ union tDMA_CHCR {
void set_flags(u32 flags) { _u32 |= flags; }
void clear_flags(u32 flags) { _u32 &= ~flags; }
void reset() { _u32 = 0; }
u16 upper() { return (_u32 >> 16); }
u16 lower() { return (u16)_u32; }
wxString desc() { return wxsFormat(L"Chcr: 0x%x", _u32); }
};
#define CHCR(value) ((tDMA_CHCR)(value))
union tDMA_SADR {
struct {
u32 ADDR : 14;
@ -303,6 +307,31 @@ enum DMAInter
MEISintr = 0x40004000
};
union tDMAC_QUEUE
{
struct
{
u16 VIF0 : 1;
u16 VIF1 : 1;
u16 GIF : 1;
u16 IPU0 : 1;
u16 IPU1 : 1;
u16 SIF0 : 1;
u16 SIF1 : 1;
u16 SIF2 : 1;
u16 SPR0 : 1;
u16 SPR1 : 1;
u16 SIS : 1;
u16 MEIS : 1;
u16 BEIS : 1;
};
u16 _u16;
tDMAC_QUEUE(u16 val) { _u16 = val; }
void reset() { _u16 = 0; }
bool empty() { return (_u16 == 0); }
};
union tDMAC_CTRL {
struct {
u32 DMAE : 1; // 0/1 - disables/enables all DMAs

View File

@ -91,7 +91,6 @@ __forceinline void gsInterrupt()
clearFIFOstuff(false);
hwDmacIrq(DMAC_GIF);
GIF_LOG("GIF DMA end");
}
static u32 WRITERING_DMA(u32 *pMem, u32 qwc)
@ -108,12 +107,17 @@ static u32 WRITERING_DMA(u32 *pMem, u32 qwc)
return size;
}
static u32 WRITERING_DMA(tDMA_TAG *pMem, u32 qwc)
{
return WRITERING_DMA((u32*)pMem, qwc);
}
int _GIFchain()
{
u32 qwc = min( gifsplit, (int)gif->qwc );
u32 *pMem;
tDMA_TAG *pMem;
pMem = (u32*)dmaGetAddr(gif->madr);
pMem = (tDMA_TAG*)dmaGetAddr(gif->madr);
if (pMem == NULL)
{
// reset path3, fixes dark cloud 2
@ -136,9 +140,9 @@ static __forceinline void GIFchain()
Registers::Thaw();
}
static __forceinline bool checkTieBit(u32* &ptag)
static __forceinline bool checkTieBit(tDMA_TAG* &ptag)
{
if (gif->chcr.TIE && (Tag::IRQ(ptag)))
if (gif->chcr.TIE && ptag->IRQ)
{
GIF_LOG("dmaIrq Set");
gspath3done = true;
@ -148,36 +152,33 @@ static __forceinline bool checkTieBit(u32* &ptag)
return false;
}
static __forceinline u32* ReadTag(u32 &id)
static __forceinline tDMA_TAG* ReadTag()
{
u32* ptag = (u32*)dmaGetAddr(gif->tadr); //Set memory pointer to TADR
tDMA_TAG* ptag = (tDMA_TAG*)dmaGetAddr(gif->tadr); //Set memory pointer to TADR
if (!(Tag::Transfer("Gif", gif, ptag))) return NULL;
if (!(gif->transfer("Gif", ptag))) return NULL;
gif->madr = ptag[1]; //MADR = ADDR field
id = Tag::Id(ptag);
gif->madr = ptag[1].ADDR; //MADR = ADDR field
gscycles += 2; // Add 1 cycles from the QW read for the tag
gspath3done = hwDmacSrcChainWithStack(gif, id);
gspath3done = hwDmacSrcChainWithStack(gif, ptag->ID);
return ptag;
}
static __forceinline u32* ReadTag2()
static __forceinline tDMA_TAG* ReadTag2()
{
u32* ptag = (u32*)dmaGetAddr(gif->tadr); //Set memory pointer to TADR
tDMA_TAG* ptag = (tDMA_TAG*)dmaGetAddr(gif->tadr); //Set memory pointer to TADR
Tag::UnsafeTransfer(gif, ptag);
gif->madr = ptag[1];
gif->unsafeTransfer(ptag);
gif->madr = ptag[1].ADDR;
gspath3done = hwDmacSrcChainWithStack(gif, Tag::Id(ptag));
gspath3done = hwDmacSrcChainWithStack(gif, ptag->ID);
return ptag;
}
void GIFdma()
{
u32 *ptag;
u32 id;
tDMA_TAG *ptag;
gscycles = prevcycles;
@ -220,9 +221,9 @@ void GIFdma()
{
if ((gif->chcr.MOD == CHAIN_MODE) && gif->chcr.STR)
{
ptag = ReadTag(id);
ptag = ReadTag();
if (ptag == NULL) return;
GIF_LOG("PTH3 MASK gifdmaChain %8.8x_%8.8x size=%d, id=%d, addr=%lx", ptag[1], ptag[0], gif->qwc, id, gif->madr);
GIF_LOG("PTH3 MASK gifdmaChain %8.8x_%8.8x size=%d, id=%d, addr=%lx", ptag[1]._u32, ptag[0]._u32, gif->qwc, ptag->ID, gif->madr);
//Check TIE bit of CHCR and IRQ bit of tag
if (checkTieBit(ptag)) GIF_LOG("PATH3 MSK dmaIrq Set");
@ -258,14 +259,14 @@ void GIFdma()
if ((gif->chcr.MOD == CHAIN_MODE) && (!gspath3done)) // Chain Mode
{
ptag = ReadTag(id);
ptag = ReadTag();
if (ptag == NULL) return;
GIF_LOG("gifdmaChain %8.8x_%8.8x size=%d, id=%d, addr=%lx", ptag[1], ptag[0], gif->qwc, id, gif->madr);
GIF_LOG("gifdmaChain %8.8x_%8.8x size=%d, id=%d, addr=%lx", ptag[1]._u32, ptag[0]._u32, gif->qwc, ptag->ID, gif->madr);
if (dmacRegs->ctrl.STD == STD_GIF)
{
// there are still bugs, need to also check if gif->madr +16*qwc >= stadr, if not, stall
if (!gspath3done && ((gif->madr + (gif->qwc * 16)) > dmacRegs->stadr.ADDR) && (id == 4))
if (!gspath3done && ((gif->madr + (gif->qwc * 16)) > dmacRegs->stadr.ADDR) && (ptag->ID == TAG_REFS))
{
// stalled
Console.WriteLn("GS Stall Control Source = %x, Drain = %x\n MADR = %x, STADR = %x", (psHu32(0xe000) >> 4) & 0x3, (psHu32(0xe000) >> 6) & 0x3,gif->madr, psHu32(DMAC_STADR));
@ -285,16 +286,15 @@ void GIFdma()
if ((!gspath3done) && (gif->qwc == 0))
{
ptag = (u32*)dmaGetAddr(gif->tadr); //Set memory pointer to TADR
ptag = (tDMA_TAG*)dmaGetAddr(gif->tadr); //Set memory pointer to TADR
gif->unsafeTransfer(ptag);
gif->madr = ptag[1].ADDR;
Tag::UnsafeTransfer(gif, ptag);
gif->madr = ptag[1];
gspath3done = hwDmacSrcChainWithStack(gif, Tag::Id(ptag));
gspath3done = hwDmacSrcChainWithStack(gif, ptag->ID);
checkTieBit(ptag);
GIF_LOG("gifdmaChain %8.8x_%8.8x size=%d, id=%d, addr=%lx", ptag[1], ptag[0], gif->qwc, (ptag[0] >> 28) & 0x7, gif->madr);
GIF_LOG("gifdmaChain %8.8x_%8.8x size=%d, id=%d, addr=%lx", ptag[1]._u32, ptag[0]._u32, gif->qwc, ptag->ID, gif->madr);
CPU_INT(2, gscycles * BIAS);
}
else
@ -327,8 +327,8 @@ void dmaGIF()
if ((gif->qwc == 0) && (gif->chcr.MOD != NORMAL_MODE))
{
u32* ptag = ReadTag2();
GIF_LOG("gifdmaChain %8.8x_%8.8x size=%d, id=%d, addr=%lx", ptag[1], ptag[0], gif->qwc, (ptag[0] >> 28), gif->madr);
tDMA_TAG* ptag = ReadTag2();
GIF_LOG("gifdmaChain %8.8x_%8.8x size=%d, id=%d, addr=%lx", ptag[1]._u32, ptag[0]._u32, gif->qwc, ptag->ID, gif->madr);
checkTieBit(ptag);
GIFdma();
@ -342,7 +342,7 @@ void dmaGIF()
}
// called from only one location, so forceinline it:
static __forceinline int mfifoGIFrbTransfer()
static __forceinline bool mfifoGIFrbTransfer()
{
u32 mfifoqwc = min(gifqwc, (u32)gif->qwc);
u32 *src;
@ -357,14 +357,14 @@ static __forceinline int mfifoGIFrbTransfer()
/* it does (wrap around), so first copy 's1' bytes from 'addr' to 'data' */
src = (u32*)PSM(gif->madr);
if (src == NULL) return -1;
if (src == NULL) return false;
s1 = WRITERING_DMA(src, s1);
if (s1 == (mfifoqwc - s2))
{
/* and second copy 's2' bytes from 'maddr' to '&data[s1]' */
src = (u32*)PSM(dmacRegs->rbor.ADDR);
if (src == NULL) return -1;
if (src == NULL) return false;
s2 = WRITERING_DMA(src, s2);
}
else
@ -378,39 +378,39 @@ static __forceinline int mfifoGIFrbTransfer()
{
/* it doesn't, so just transfer 'qwc*16' words from 'gif->madr' to GS */
src = (u32*)PSM(gif->madr);
if (src == NULL) return -1;
if (src == NULL) return false;
mfifoqwc = WRITERING_DMA(src, mfifoqwc);
gif->madr = dmacRegs->rbor.ADDR + (gif->madr & dmacRegs->rbsr.RMSK);
}
gifqwc -= mfifoqwc;
return 0;
return true;
}
// called from only one location, so forceinline it:
static __forceinline int mfifoGIFchain()
static __forceinline bool mfifoGIFchain()
{
/* Is QWC = 0? if so there is nothing to transfer */
if (gif->qwc == 0) return 0;
if (gif->qwc == 0) return true;
if (gif->madr >= dmacRegs->rbor.ADDR &&
gif->madr <= (dmacRegs->rbor.ADDR + dmacRegs->rbsr.RMSK))
{
if (mfifoGIFrbTransfer() == -1) return -1;
if (!mfifoGIFrbTransfer()) return false;
}
else
{
int mfifoqwc;
u32 *pMem = (u32*)dmaGetAddr(gif->madr);
if (pMem == NULL) return -1;
tDMA_TAG *pMem = (tDMA_TAG*)dmaGetAddr(gif->madr);
if (pMem == NULL) return false;
mfifoqwc = WRITERING_DMA(pMem, gif->qwc);
mfifocycles += (mfifoqwc) * 2; /* guessing */
}
return 0;
return true;
}
static u32 qwctag(u32 mask)
@ -420,8 +420,7 @@ static u32 qwctag(u32 mask)
void mfifoGIFtransfer(int qwc)
{
u32 *ptag;
int id;
tDMA_TAG *ptag;
mfifocycles = 0;
gifmfifoirq = false;
@ -451,19 +450,18 @@ void mfifoGIFtransfer(int qwc)
gif->tadr = qwctag(gif->tadr);
ptag = (u32*)dmaGetAddr(gif->tadr);
Tag::UnsafeTransfer(gif, ptag);
ptag = (tDMA_TAG*)dmaGetAddr(gif->tadr);
gif->unsafeTransfer(ptag);
gif->madr = ptag[1].ADDR;
gif->madr = ptag[1];
id =Tag::Id(ptag);
mfifocycles += 2;
GIF_LOG("dmaChain %8.8x_%8.8x size=%d, id=%d, madr=%lx, tadr=%lx mfifo qwc = %x spr0 madr = %x",
ptag[1], ptag[0], gif->qwc, id, gif->madr, gif->tadr, gifqwc, spr0->madr);
ptag[1]._u32, ptag[0]._u32, gif->qwc, ptag->ID, gif->madr, gif->tadr, gifqwc, spr0->madr);
gifqwc--;
switch (id)
switch (ptag->ID)
{
case TAG_REFE: // Refe - Transfer Packet According to ADDR field
gif->tadr = qwctag(gif->tadr + 16);
@ -498,7 +496,7 @@ void mfifoGIFtransfer(int qwc)
break;
}
if ((gif->chcr.TIE) && (Tag::IRQ(ptag)))
if ((gif->chcr.TIE) && (ptag->IRQ))
{
SPR_LOG("dmaIrq Set");
gifstate = GIF_STATE_DONE;
@ -507,7 +505,7 @@ void mfifoGIFtransfer(int qwc)
}
Registers::Freeze();
if (mfifoGIFchain() == -1)
if (!mfifoGIFchain())
{
Console.WriteLn("GIF dmaChain error size=%d, madr=%lx, tadr=%lx", gif->qwc, gif->madr, gif->tadr);
gifstate = GIF_STATE_STALL;

View File

@ -55,7 +55,7 @@ static __forceinline void DmaExec16( void (*func)(), u32 mem, u16 value )
u32 qwcRegister = mem | 0x20;
//It's invalid for the hardware to write a DMA while it is active, not without Suspending the DMAC
if ((value & 0x100) && ((psHu32(mem) & 0x100) == 0x100) && dmacRegs->ctrl.DMAE)
if ((CHCR(value).STR) && (psH_Chcr(mem).STR) && dmacRegs->ctrl.DMAE)
{
DevCon.Warning( "DMAExec16 Attempt to run DMA while one is already active mem = %x", mem);
}
@ -64,12 +64,11 @@ static __forceinline void DmaExec16( void (*func)(), u32 mem, u16 value )
if ((psHu32(qwcRegister) >> 16) != 0)
{
DMA_LOG("DMA QWC (%x) upper 16bits set to %x\n",
qwcRegister,
psHu32(qwcRegister) >> 16);
qwcRegister, psHu32(qwcRegister) >> 16);
psHu32(qwcRegister) = 0;
}
psHu16(mem) = (u16)value;
psHu16(mem) = CHCR(value).lower();
if ((psHu16(mem) & 0x100) && dmacRegs->ctrl.DMAE)
{
//Console.WriteLn("16bit DMA Start");
@ -82,7 +81,7 @@ static void DmaExec( void (*func)(), u32 mem, u32 value )
u32 qwcRegister = mem | 0x20;
//It's invalid for the hardware to write a DMA while it is active, not without Suspending the DMAC
if ((value & 0x100) && ((psHu32(mem) & 0x100) == 0x100) && dmacRegs->ctrl.DMAE)
if ((CHCR(value).STR) && (psH_Chcr(mem).STR) && dmacRegs->ctrl.DMAE)
{
DevCon.Warning( "DMAExec32 Attempt to run DMA while one is already active mem = %x", mem );
@ -95,28 +94,26 @@ static void DmaExec( void (*func)(), u32 mem, u32 value )
if ((psHu32(qwcRegister) >> 16) != 0)
{
DevCon.Warning("DMA QWC (%x) upper 16bits set to %x\n",
qwcRegister,
psHu32(qwcRegister) >> 16);
qwcRegister, psHu32(qwcRegister) >> 16);
psHu32(qwcRegister) = 0;
}
/* Keep the old tag if in chain mode and hw doesn't set it*/
if (((value & 0xc) == 0x4) && ((value & 0xffff0000) == 0))
psHu32(mem) = (psHu32(mem) & 0xffff0000) | (u16)value;
if ((CHCR(value).MOD == CHAIN_MODE) && (CHCR(value).TAG == 0))
psHu32(mem) = (psH_Chcr(mem).TAG << 16) | CHCR(value).lower();
else /* Else (including Normal mode etc) write whatever the hardware sends*/
psHu32(mem) = (u32)value;
psHu32(mem) = value;
if ((psHu32(mem) & 0x100) && dmacRegs->ctrl.DMAE)
if (psH_Chcr(mem).STR && dmacRegs->ctrl.DMAE)
func();
}
/////////////////////////////////////////////////////////////////////////
// Hardware WRITE 8 bit
char sio_buffer[1024];
int sio_count;
u16 QueuedDMA = 0;
tDMAC_QUEUE QueuedDMA(0);
void hwWrite8(u32 mem, u8 value)
{
@ -189,7 +186,7 @@ void hwWrite8(u32 mem, u8 value)
if ((value & 0x1) && !dmacRegs->ctrl.DMAE)
{
DevCon.Warning("8 bit VIF0 DMA Start while DMAC Disabled\n");
QueuedDMA |= 0x1;
QueuedDMA.VIF0 = true;
}
DmaExec8(dmaVIF0, mem, value);
break;
@ -199,7 +196,7 @@ void hwWrite8(u32 mem, u8 value)
if ((value & 0x1) && !dmacRegs->ctrl.DMAE)
{
DevCon.Warning("8 bit VIF1 DMA Start while DMAC Disabled\n");
QueuedDMA |= 0x2;
QueuedDMA.VIF1 = true;
}
if(value & 0x1) vif1.done = false; //This must be done here! some games (ala Crash of the Titans) pause the dma to start MFIFO
DmaExec8(dmaVIF1, mem, value);
@ -210,7 +207,7 @@ void hwWrite8(u32 mem, u8 value)
if ((value & 0x1) && !dmacRegs->ctrl.DMAE)
{
DevCon.Warning("8 bit GIF DMA Start while DMAC Disabled\n");
QueuedDMA |= 0x4;
QueuedDMA.GIF = true;
}
DmaExec8(dmaGIF, mem, value);
break;
@ -220,7 +217,7 @@ void hwWrite8(u32 mem, u8 value)
if ((value & 0x1) && !dmacRegs->ctrl.DMAE)
{
DevCon.Warning("8 bit IPU0 DMA Start while DMAC Disabled\n");
QueuedDMA |= 0x8;
QueuedDMA.IPU0 = true;
}
DmaExec8(dmaIPU0, mem, value);
break;
@ -230,7 +227,7 @@ void hwWrite8(u32 mem, u8 value)
if ((value & 0x1) && !dmacRegs->ctrl.DMAE)
{
DevCon.Warning("8 bit IPU1 DMA Start while DMAC Disabled\n");
QueuedDMA |= 0x10;
QueuedDMA.IPU1 = true;
}
DmaExec8(dmaIPU1, mem, value);
break;
@ -241,7 +238,7 @@ void hwWrite8(u32 mem, u8 value)
if ((value & 0x1) && !dmacRegs->ctrl.DMAE)
{
DevCon.Warning("8 bit SIF0 DMA Start while DMAC Disabled\n");
QueuedDMA |= 0x20;
QueuedDMA.SIF0 = true;
}
DmaExec8(dmaSIF0, mem, value);
break;
@ -251,7 +248,7 @@ void hwWrite8(u32 mem, u8 value)
if ((value & 0x1) && !dmacRegs->ctrl.DMAE)
{
DevCon.Warning("8 bit SIF1 DMA Start while DMAC Disabled\n");
QueuedDMA |= 0x40;
QueuedDMA.SIF1 = true;
}
DmaExec8(dmaSIF1, mem, value);
break;
@ -261,7 +258,7 @@ void hwWrite8(u32 mem, u8 value)
if ((value & 0x1) && !dmacRegs->ctrl.DMAE)
{
DevCon.Warning("8 bit SIF2 DMA Start while DMAC Disabled\n");
QueuedDMA |= 0x80;
QueuedDMA.SIF2 |= true;
}
DmaExec8(dmaSIF2, mem, value);
break;
@ -271,7 +268,7 @@ void hwWrite8(u32 mem, u8 value)
if ((value & 0x1) && !dmacRegs->ctrl.DMAE)
{
DevCon.Warning("8 bit SPR0 DMA Start while DMAC Disabled\n");
QueuedDMA |= 0x100;
QueuedDMA.SPR0 = true;
}
DmaExec8(dmaSPR0, mem, value);
break;
@ -281,7 +278,7 @@ void hwWrite8(u32 mem, u8 value)
if ((value & 0x1) && !dmacRegs->ctrl.DMAE)
{
DevCon.Warning("8 bit SPR1 DMA Start while DMAC Disabled\n");
QueuedDMA |= 0x200;
QueuedDMA .SPR1 = true;
}
DmaExec8(dmaSPR1, mem, value);
break;
@ -366,7 +363,7 @@ __forceinline void hwWrite16(u32 mem, u16 value)
if ((value & 0x100) && !dmacRegs->ctrl.DMAE)
{
DevCon.Warning("16 bit VIF0 DMA Start while DMAC Disabled\n");
QueuedDMA |= 0x1;
QueuedDMA.VIF0 = true;
}
DmaExec16(dmaVIF0, mem, value);
break;
@ -376,9 +373,10 @@ __forceinline void hwWrite16(u32 mem, u16 value)
if ((value & 0x100) && !dmacRegs->ctrl.DMAE)
{
DevCon.Warning("16 bit VIF1 DMA Start while DMAC Disabled\n");
QueuedDMA |= 0x2;
QueuedDMA.VIF1 = true;
}
if(value & 0x100) vif1.done = false; //This must be done here! some games (ala Crash of the Titans) pause the dma to start MFIFO
if (value & 0x100) vif1.done = false; //This must be done here! some games (ala Crash of the Titans) pause the dma to start MFIFO
DmaExec16(dmaVIF1, mem, value);
break;
@ -420,7 +418,7 @@ __forceinline void hwWrite16(u32 mem, u16 value)
if ((value & 0x100) && !dmacRegs->ctrl.DMAE)
{
DevCon.Warning("16 bit GIF DMA Start while DMAC Disabled\n");
QueuedDMA |= 0x4;
QueuedDMA.GIF = true;
}
DmaExec16(dmaGIF, mem, value);
break;
@ -462,7 +460,7 @@ __forceinline void hwWrite16(u32 mem, u16 value)
if ((value & 0x100) && !dmacRegs->ctrl.DMAE)
{
DevCon.Warning("16 bit IPU0 DMA Start while DMAC Disabled\n");
QueuedDMA |= 0x8;
QueuedDMA.IPU0 = true;
}
DmaExec16(dmaIPU0, mem, value);
break;
@ -494,7 +492,7 @@ __forceinline void hwWrite16(u32 mem, u16 value)
if ((value & 0x100) && !dmacRegs->ctrl.DMAE)
{
DevCon.Warning("16 bit IPU1 DMA Start while DMAC Disabled\n");
QueuedDMA |= 0x10;
QueuedDMA.IPU1 = true;
}
DmaExec16(dmaIPU1, mem, value);
break;
@ -526,7 +524,7 @@ __forceinline void hwWrite16(u32 mem, u16 value)
if ((value & 0x100) && !dmacRegs->ctrl.DMAE)
{
DevCon.Warning("16 bit SIF0 DMA Start while DMAC Disabled\n");
QueuedDMA |= 0x20;
QueuedDMA.SIF0 = true;
}
DmaExec16(dmaSIF0, mem, value);
break;
@ -540,7 +538,7 @@ __forceinline void hwWrite16(u32 mem, u16 value)
if ((value & 0x100) && !dmacRegs->ctrl.DMAE)
{
DevCon.Warning("16 bit SIF1 DMA Start while DMAC Disabled\n");
QueuedDMA |= 0x40;
QueuedDMA.SIF1 = true;
}
DmaExec16(dmaSIF1, mem, value);
break;
@ -572,7 +570,7 @@ __forceinline void hwWrite16(u32 mem, u16 value)
if ((value & 0x100) && !dmacRegs->ctrl.DMAE)
{
DevCon.Warning("16 bit SIF2 DMA Start while DMAC Disabled\n");
QueuedDMA |= 0x80;
QueuedDMA.SIF2 = true;
}
DmaExec16(dmaSIF2, mem, value);
break;
@ -586,7 +584,7 @@ __forceinline void hwWrite16(u32 mem, u16 value)
if ((value & 0x100) && !dmacRegs->ctrl.DMAE)
{
DevCon.Warning("16 bit SPR0 DMA Start while DMAC Disabled\n");
QueuedDMA |= 0x100;
QueuedDMA.SPR0 = true;
}
DmaExec16(dmaSPR0, mem, value);
break;
@ -596,7 +594,7 @@ __forceinline void hwWrite16(u32 mem, u16 value)
if ((value & 0x100) && !dmacRegs->ctrl.DMAE)
{
DevCon.Warning("16 bit SPR1 DMA Start while DMAC Disabled\n");
QueuedDMA |= 0x200;
QueuedDMA.SPR1 = true;
}
DmaExec16(dmaSPR1, mem, value);
break;
@ -751,10 +749,10 @@ void __fastcall hwWrite32_page_0B( u32 mem, u32 value )
{
case D3_CHCR: // dma3 - fromIPU
DMA_LOG("IPU0dma EXECUTE, value=0x%x\n", value);
if ((value & 0x100) && !dmacRegs->ctrl.DMAE)
if (CHCR(value).STR && !dmacRegs->ctrl.DMAE)
{
DevCon.Warning("32 bit IPU0 DMA Start while DMAC Disabled\n");
QueuedDMA |= 0x8;
QueuedDMA.IPU0 = true;
}
DmaExec(dmaIPU0, mem, value);
return;
@ -768,10 +766,10 @@ void __fastcall hwWrite32_page_0B( u32 mem, u32 value )
case D4_CHCR: // dma4 - toIPU
DMA_LOG("IPU1dma EXECUTE, value=0x%x\n", value);
if ((value & 0x100) && !dmacRegs->ctrl.DMAE)
if (CHCR(value).STR && !dmacRegs->ctrl.DMAE)
{
DevCon.Warning("32 bit IPU1 DMA Start while DMAC Disabled\n");
QueuedDMA |= 0x10;
QueuedDMA.IPU1 = true;
}
DmaExec(dmaIPU1, mem, value);
return;
@ -788,16 +786,16 @@ void __fastcall hwWrite32_page_0B( u32 mem, u32 value )
void __fastcall StartQueuedDMA()
{
if(QueuedDMA & 0x001) { QueuedDMA &= ~0x001; dmaVIF0(); }
if(QueuedDMA & 0x002) { QueuedDMA &= ~0x002; dmaVIF1(); }
if(QueuedDMA & 0x004) { QueuedDMA &= ~0x004; dmaGIF(); }
if(QueuedDMA & 0x008) { QueuedDMA &= ~0x008; dmaIPU0(); }
if(QueuedDMA & 0x010) { QueuedDMA &= ~0x010; dmaIPU1(); }
if(QueuedDMA & 0x020) { QueuedDMA &= ~0x020; dmaSIF0(); }
if(QueuedDMA & 0x040) { QueuedDMA &= ~0x040; dmaSIF1(); }
if(QueuedDMA & 0x080) { QueuedDMA &= ~0x080; dmaSIF2(); }
if(QueuedDMA & 0x100) { QueuedDMA &= ~0x100; dmaSPR0(); }
if(QueuedDMA & 0x200) { QueuedDMA &= ~0x200; dmaSPR1(); }
if (QueuedDMA.VIF0) { QueuedDMA.VIF0 = false; dmaVIF0(); }
if (QueuedDMA.VIF1) { QueuedDMA.VIF1 = false; dmaVIF1(); }
if (QueuedDMA.GIF ) { QueuedDMA.GIF = false; dmaGIF(); }
if (QueuedDMA.IPU0) { QueuedDMA.IPU0 = false; dmaIPU0(); }
if (QueuedDMA.IPU1) { QueuedDMA.IPU1 = false; dmaIPU1(); }
if (QueuedDMA.SIF0) { QueuedDMA.SIF0 = false; dmaSIF0(); }
if (QueuedDMA.SIF1) { QueuedDMA.SIF1 = false; dmaSIF1(); }
if (QueuedDMA.SIF2) { QueuedDMA.SIF2 = false; dmaSIF2(); }
if (QueuedDMA.SPR0) { QueuedDMA.SPR0 = false; dmaSPR0(); }
if (QueuedDMA.SPR1) { QueuedDMA.SPR1 = false; dmaSPR1(); }
}
void __fastcall hwWrite32_page_0E( u32 mem, u32 value )
@ -814,7 +812,7 @@ void __fastcall hwWrite32_page_0E( u32 mem, u32 value )
//Check for DMAS that were started while the DMAC was disabled
if (((oldvalue & 0x1) == 0) && ((value & 0x1) == 1))
{
if (QueuedDMA != 0) StartQueuedDMA();
if (!QueuedDMA.empty()) StartQueuedDMA();
}
break;
}
@ -919,10 +917,10 @@ void __fastcall hwWrite32_generic( u32 mem, u32 value )
case D0_CHCR: // dma0 - vif0
DMA_LOG("VIF0dma EXECUTE, value=0x%x", value);
if ((value & 0x100) && !dmacRegs->ctrl.DMAE)
if (CHCR(value).STR && !dmacRegs->ctrl.DMAE)
{
DevCon.Warning("32 bit VIF0 DMA Start while DMAC Disabled\n");
QueuedDMA |= 0x1;
QueuedDMA.VIF0 = true;
}
DmaExec(dmaVIF0, mem, value);
@ -932,16 +930,20 @@ void __fastcall hwWrite32_generic( u32 mem, u32 value )
case D1_CHCR: // dma1 - vif1 - chcr
DMA_LOG("VIF1dma EXECUTE, value=0x%x", value);
if ((value & 0x100) && !dmacRegs->ctrl.DMAE)
if (CHCR(value).STR && !dmacRegs->ctrl.DMAE)
{
DevCon.Warning("32 bit VIF1 DMA Start while DMAC Disabled\n");
QueuedDMA |= 0x2;
QueuedDMA.VIF1 = true;
}
if (value & 0x100)
if (CHCR(value).STR)
{
vif1.done = false; //This must be done here! some games (ala Crash of the Titans) pause the dma to start MFIFO
} else cpuRegs.interrupt &= ~(1<<10) | ~(1<<1); //Tekken tag seems to stop vif and start it again in normal, so we will cancel the mfifo loop
}
else
{
cpuRegs.interrupt &= ~(1<<10) | ~(1<<1); //Tekken tag seems to stop vif and start it again in normal, so we will cancel the mfifo loop
}
DmaExec(dmaVIF1, mem, value);
return;
@ -956,10 +958,10 @@ void __fastcall hwWrite32_generic( u32 mem, u32 value )
//------------------------------------------------------------------
case D2_CHCR: // dma2 - gif
DMA_LOG("GIFdma EXECUTE, value=0x%x", value);
if ((value & 0x100) && !dmacRegs->ctrl.DMAE)
if (CHCR(value).STR && !dmacRegs->ctrl.DMAE)
{
DevCon.Warning("32 bit GIF DMA Start while DMAC Disabled\n");
QueuedDMA |= 0x4;
QueuedDMA.GIF = true;
}
DmaExec(dmaGIF, mem, value);
return;
@ -975,20 +977,20 @@ void __fastcall hwWrite32_generic( u32 mem, u32 value )
case D5_CHCR: // dma5 - sif0
DMA_LOG("SIF0dma EXECUTE, value=0x%x", value);
//if (value == 0) psxSu32(0x30) = 0x40000;
if ((value & 0x100) && !dmacRegs->ctrl.DMAE)
if (CHCR(value).STR && !dmacRegs->ctrl.DMAE)
{
DevCon.Warning("32 bit SIF0 DMA Start while DMAC Disabled\n");
QueuedDMA |= 0x20;
QueuedDMA.SIF0 = true;
}
DmaExec(dmaSIF0, mem, value);
return;
//------------------------------------------------------------------
case D6_CHCR: // dma6 - sif1
DMA_LOG("SIF1dma EXECUTE, value=0x%x", value);
if ((value & 0x100) && !dmacRegs->ctrl.DMAE)
if (CHCR(value).STR && !dmacRegs->ctrl.DMAE)
{
DevCon.Warning("32 bit SIF1 DMA Start while DMAC Disabled\n");
QueuedDMA |= 0x40;
QueuedDMA.SIF1 = true;
}
DmaExec(dmaSIF1, mem, value);
return;
@ -1000,30 +1002,30 @@ void __fastcall hwWrite32_generic( u32 mem, u32 value )
//------------------------------------------------------------------
case D7_CHCR: // dma7 - sif2
DMA_LOG("SIF2dma EXECUTE, value=0x%x", value);
if ((value & 0x100) && !dmacRegs->ctrl.DMAE)
if (CHCR(value).STR && !dmacRegs->ctrl.DMAE)
{
DevCon.Warning("32 bit SIF2 DMA Start while DMAC Disabled\n");
QueuedDMA |= 0x80;
QueuedDMA.SIF2 = true;
}
DmaExec(dmaSIF2, mem, value);
return;
//------------------------------------------------------------------
case D8_CHCR: // dma8 - fromSPR
DMA_LOG("SPR0dma EXECUTE (fromSPR), value=0x%x", value);
if ((value & 0x100) && !dmacRegs->ctrl.DMAE)
if (CHCR(value).STR && !dmacRegs->ctrl.DMAE)
{
DevCon.Warning("32 bit SPR0 DMA Start while DMAC Disabled\n");
QueuedDMA |= 0x100;
QueuedDMA.SPR0 = true;
}
DmaExec(dmaSPR0, mem, value);
return;
//------------------------------------------------------------------
case SPR1_CHCR: // dma9 - toSPR
DMA_LOG("SPR1dma EXECUTE (toSPR), value=0x%x", value);
if ((value & 0x100) && !dmacRegs->ctrl.DMAE)
if (CHCR(value).STR && !dmacRegs->ctrl.DMAE)
{
DevCon.Warning("32 bit SPR1 DMA Start while DMAC Disabled\n");
QueuedDMA |= 0x200;
QueuedDMA.SPR1 = true;
}
DmaExec(dmaSPR1, mem, value);
return;
@ -1120,7 +1122,7 @@ void __fastcall hwWrite64_page_0E( u32 mem, const mem64_t* srcval )
if (((oldvalue & 0x1) == 0) && ((value & 0x1) == 1))
{
if (QueuedDMA != 0) StartQueuedDMA();
if (!QueuedDMA.empty()) StartQueuedDMA();
}
break;
}

View File

@ -119,6 +119,7 @@ extern u8 *psS; //0.015 mb, scratch pad
#define psSu32(mem) (*(u32*)&PS2MEM_SCRATCH[(mem) & 0x3fff])
#define psSu64(mem) (*(u64*)&PS2MEM_SCRATCH[(mem) & 0x3fff])
#define psH_Chcr(mem) (*(tDMA_CHCR*)&PS2MEM_HW[(mem) & 0xffff])
extern void memAlloc();
extern void memReset(); // clears PS2 ram and loads the bios. Throws Exception::FileNotFound on error.
extern void memShutdown();