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 set_flags(u32 flags) { _u32 |= flags; }
void clear_flags(u32 flags) { _u32 &= ~flags; } void clear_flags(u32 flags) { _u32 &= ~flags; }
void reset() { _u32 = 0; } void reset() { _u32 = 0; }
u16 upper() { return (_u32 >> 16); }
u16 lower() { return (u16)_u32; }
wxString desc() { return wxsFormat(L"Chcr: 0x%x", _u32); } wxString desc() { return wxsFormat(L"Chcr: 0x%x", _u32); }
}; };
#define CHCR(value) ((tDMA_CHCR)(value))
union tDMA_SADR { union tDMA_SADR {
struct { struct {
u32 ADDR : 14; u32 ADDR : 14;
@ -303,6 +307,31 @@ enum DMAInter
MEISintr = 0x40004000 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 { union tDMAC_CTRL {
struct { struct {
u32 DMAE : 1; // 0/1 - disables/enables all DMAs u32 DMAE : 1; // 0/1 - disables/enables all DMAs

View File

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

View File

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

View File

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