Changed the chcr stuff over to bitfields, and got various other bitfield stuff ready for later on.

git-svn-id: http://pcsx2.googlecode.com/svn/trunk@1705 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
arcum42 2009-08-29 00:35:20 +00:00
parent 712a23b7d6
commit 2b57f23634
13 changed files with 342 additions and 296 deletions

View File

@ -131,7 +131,7 @@ void iDumpRegisters(u32 startpc, u32 temp)
for(i = 0; i < ArraySize(dmacs); ++i) {
DMACh* p = (DMACh*)(PS2MEM_HW+dmacs[i]);
__Log("dma%d c%x m%x q%x t%x s%x", i, p->chcr, p->madr, p->qwc, p->tadr, p->sadr);
__Log("dma%d c%x m%x q%x t%x s%x", i, p->chcr._u32, p->madr, p->qwc, p->tadr, p->sadr);
}
__Log("dmac %x %x %x %x", psHu32(DMAC_CTRL), psHu32(DMAC_STAT), psHu32(DMAC_RBSR), psHu32(DMAC_RBOR));
__Log("intc %x %x", psHu32(INTC_STAT), psHu32(INTC_MASK));

View File

@ -57,9 +57,9 @@ __forceinline void gsInterrupt()
{
GIF_LOG("gsInterrupt: %8.8x", cpuRegs.cycle);
if (!(CHCR::STR(gif)))
if (!(gif->chcr.STR))
{
//Console::WriteLn("Eh? why are you still interrupting! chcr %x, qwc %x, done = %x", params gif->chcr, gif->qwc, done);
//Console::WriteLn("Eh? why are you still interrupting! chcr %x, qwc %x, done = %x", params gif->chcr._u32, gif->qwc, done);
return;
}
@ -86,7 +86,7 @@ __forceinline void gsInterrupt()
gspath3done = 0;
gscycles = 0;
CHCR::clearSTR(gif);
gif->chcr.STR = 0;
vif1Regs->stat &= ~VIF1_STAT_VGW;
psHu32(GIF_STAT) &= ~(GIF_STAT_APATH3 | GIF_STAT_OPH | GIF_STAT_P3Q | GIF_STAT_FQC);
@ -160,7 +160,7 @@ static __forceinline void GIFchain()
static __forceinline bool checkTieBit(u32* &ptag)
{
if ((CHCR::TIE(gif)) && (Tag::IRQ(ptag))) //Check TIE bit of CHCR and IRQ bit of tag
if (gif->chcr.TIE && (Tag::IRQ(ptag))) //Check TIE bit of CHCR and IRQ bit of tag
{
GIF_LOG("dmaIrq Set");
gspath3done = 1;
@ -238,7 +238,7 @@ void GIFdma()
{
if (gif->qwc == 0)
{
if ((CHCR::MOD(gif) == CHAIN_MODE) && CHCR::STR(gif))
if ((gif->chcr.MOD == CHAIN_MODE) && gif->chcr.STR)
{
if (!ReadTag(ptag, id)) 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);
@ -261,10 +261,10 @@ void GIFdma()
}
// Transfer Dn_QWC from Dn_MADR to GIF
if ((CHCR::MOD(gif) == NORMAL_MODE) || (gif->qwc > 0)) // Normal Mode
if ((gif->chcr.MOD == NORMAL_MODE) || (gif->qwc > 0)) // Normal Mode
{
if (((psHu32(DMAC_CTRL) & 0xC0) == 0x80) && (CHCR::MOD(gif) == NORMAL_MODE))
if (((psHu32(DMAC_CTRL) & 0xC0) == 0x80) && (gif->chcr.MOD == NORMAL_MODE))
{
Console::WriteLn("DMA Stall Control on GIF normal");
}
@ -275,7 +275,7 @@ void GIFdma()
return;
}
if ((CHCR::MOD(gif) == CHAIN_MODE) && (gspath3done == 0)) // Chain Mode
if ((gif->chcr.MOD == CHAIN_MODE) && (gspath3done == 0)) // Chain Mode
{
if (!ReadTag(ptag, id)) return;
GIF_LOG("gifdmaChain %8.8x_%8.8x size=%d, id=%d, addr=%lx", ptag[1], ptag[0], gif->qwc, id, gif->madr);
@ -326,7 +326,7 @@ void dmaGIF()
{
//We used to add wait time for the buffer to fill here, fixing some timing problems in path 3 masking
//It takes the time of 24 QW for the BUS to become ready - The Punisher And Streetball
GIF_LOG("dmaGIFstart chcr = %lx, madr = %lx, qwc = %lx\n tadr = %lx, asr0 = %lx, asr1 = %lx", gif->chcr, gif->madr, gif->qwc, gif->tadr, gif->asr0, gif->asr1);
GIF_LOG("dmaGIFstart chcr = %lx, madr = %lx, qwc = %lx\n tadr = %lx, asr0 = %lx, asr1 = %lx", gif->chcr._u32, gif->madr, gif->qwc, gif->tadr, gif->asr0, gif->asr1);
Path3progress = STOPPED_MODE;
gspath3done = 0; // For some reason this doesn't clear? So when the system starts the thread, we will clear it :)
@ -341,7 +341,7 @@ void dmaGIF()
return;
}
if ((gif->qwc == 0) && ((CHCR::MOD(gif) != NORMAL_MODE)))
if ((gif->qwc == 0) && (gif->chcr.MOD != NORMAL_MODE))
{
u32 *ptag;
@ -447,7 +447,7 @@ void mfifoGIFtransfer(int qwc)
gifstate &= ~GIF_STATE_EMPTY;
}
GIF_LOG("mfifoGIFtransfer %x madr %x, tadr %x", gif->chcr, gif->madr, gif->tadr);
GIF_LOG("mfifoGIFtransfer %x madr %x, tadr %x", gif->chcr._u32, gif->madr, gif->tadr);
if (gif->qwc == 0)
{
@ -505,7 +505,7 @@ void mfifoGIFtransfer(int qwc)
break;
}
if ((CHCR::TIE(gif)) && (Tag::IRQ(ptag)))
if ((gif->chcr.TIE) && (Tag::IRQ(ptag)))
{
SPR_LOG("dmaIrq Set");
gifstate = GIF_STATE_DONE;
@ -525,7 +525,7 @@ void mfifoGIFtransfer(int qwc)
if ((gif->qwc == 0) && (gifstate == GIF_STATE_DONE)) gifstate = GIF_STATE_STALL;
CPU_INT(11,mfifocycles);
SPR_LOG("mfifoGIFtransfer end %x madr %x, tadr %x", gif->chcr, gif->madr, gif->tadr);
SPR_LOG("mfifoGIFtransfer end %x madr %x, tadr %x", gif->chcr._u32, gif->madr, gif->tadr);
}
void gifMFIFOInterrupt()
@ -533,13 +533,13 @@ void gifMFIFOInterrupt()
mfifocycles = 0;
if (Path3progress == STOPPED_MODE) psHu32(GIF_STAT)&= ~(GIF_STAT_APATH3 | GIF_STAT_OPH); // OPH=0 | APATH=0
if ((CHCR::STR(spr0)) && (spr0->qwc == 0))
if ((spr0->chcr.STR) && (spr0->qwc == 0))
{
CHCR::clearSTR(spr0);
spr0->chcr.STR = 0;
hwDmacIrq(DMAC_FROM_SPR);
}
if (!(CHCR::STR(gif)))
if (!(gif->chcr.STR))
{
Console::WriteLn("WTF GIFMFIFO");
cpuRegs.interrupt &= ~(1 << 11);
@ -583,7 +583,7 @@ void gifMFIFOInterrupt()
psHu32(GIF_STAT) &= ~(GIF_STAT_APATH3 | GIF_STAT_OPH | GIF_STAT_P3Q | GIF_STAT_FQC); // OPH, APATH, P3Q, FQC = 0
vif1Regs->stat &= ~VIF1_STAT_VGW;
CHCR::clearSTR(gif);
gif->chcr.STR = 0;
gifstate = GIF_STATE_READY;
hwDmacIrq(DMAC_GIF);
clearFIFOstuff(false);

View File

@ -46,9 +46,9 @@ union tGIF_CTRL
u32 PSE : 1;
u32 reserved2 : 28;
};
u32 value;
u32 _u32;
tGIF_CTRL( u32 val ) : value( val )
tGIF_CTRL( u32 val ) : _u32( val )
{
}
};
@ -62,9 +62,9 @@ union tGIF_MODE
u32 IMT : 1;
u32 reserved2 : 29;
};
u32 value;
u32 _u32;
tGIF_MODE( u32 val ) : value( val )
tGIF_MODE( u32 val ) : _u32( val )
{
}
};
@ -89,9 +89,9 @@ union tGIF_STAT
u32 FQC : 5;
u32 reserved3 : 3;
};
u32 value;
u32 _u32;
tGIF_STAT( u32 val ) : value( val )
tGIF_STAT( u32 val ) : _u32( val )
{
}
};
@ -104,9 +104,9 @@ union tGIF_TAG0
u32 EOP : 1;
u32 TAG : 16;
};
u32 value;
u32 _u32;
tGIF_TAG0( u32 val ) : value( val )
tGIF_TAG0( u32 val ) : _u32( val )
{
}
};
@ -121,9 +121,9 @@ union tGIF_TAG1
u32 FLG : 2;
u32 NREG : 4;
};
u32 value;
u32 _u32;
tGIF_TAG1( u32 val ) : value( val )
tGIF_TAG1( u32 val ) : _u32( val )
{
}
};
@ -139,9 +139,9 @@ union tGIF_CNT
u32 reserved2 : 10;
};
u32 value;
u32 _u32;
tGIF_CNT( u32 val ) : value( val )
tGIF_CNT( u32 val ) : _u32( val )
{
}
};
@ -153,9 +153,9 @@ union tGIF_P3CNT
u32 P3CNT : 15;
u32 reserved1 : 17;
};
u32 value;
u32 _u32;
tGIF_P3CNT( u32 val ) : value( val )
tGIF_P3CNT( u32 val ) : _u32( val )
{
}
};
@ -168,9 +168,9 @@ union tGIF_P3TAG
u32 EOP : 1;
u32 reserved1 : 16;
};
u32 value;
u32 _u32;
tGIF_P3TAG( u32 val ) : value( val )
tGIF_P3TAG( u32 val ) : _u32( val )
{
}
};

View File

@ -177,15 +177,15 @@ bool hwDmacSrcChainWithStack(DMACh *dma, int id) {
dma->madr = dma->tadr + 16; //Set MADR to data following the tag
switch(CHCR::ASP(dma))
switch(dma->chcr.ASP)
{
case 0: { //Check if ASR0 is empty
dma->asr0 = dma->madr + (dma->qwc << 4); //If yes store Succeeding tag
dma->chcr = (dma->chcr & 0xffffffcf) | 0x10; //1 Address in call stack
dma->chcr._u32 = (dma->chcr._u32 & 0xffffffcf) | 0x10; //1 Address in call stack
break;
}
case 1: {
dma->chcr = (dma->chcr & 0xffffffcf) | 0x20; //2 Addresses in call stack
dma->chcr._u32 = (dma->chcr._u32 & 0xffffffcf) | 0x20; //2 Addresses in call stack
dma->asr1 = dma->madr + (dma->qwc << 4); //If no store Succeeding tag in ASR1
break;
}
@ -200,17 +200,17 @@ bool hwDmacSrcChainWithStack(DMACh *dma, int id) {
}
case TAG_RET: // Ret - Transfer QWC following the tag, load next tag
dma->madr = dma->tadr + 16; //Set MADR to data following the tag
switch(CHCR::ASP(dma))
switch(dma->chcr.ASP)
{
case 2: { //If ASR1 is NOT equal to 0 (Contains address)
dma->chcr = (dma->chcr & 0xffffffcf) | 0x10; //1 Address left in call stack
dma->chcr._u32 = (dma->chcr._u32 & 0xffffffcf) | 0x10; //1 Address left in call stack
dma->tadr = dma->asr1; //Read ASR1 as next tag
dma->asr1 = 0; //Clear ASR1
break;
}
//If ASR1 is empty (No address held)
case 1:{ //Check if ASR0 is NOT equal to 0 (Contains address)
dma->chcr = (dma->chcr & 0xffffffcf); //No addresses left in call stack
dma->chcr._u32 = (dma->chcr._u32 & 0xffffffcf); //No addresses left in call stack
dma->tadr = dma->asr0; //Read ASR0 as next tag
dma->asr0 = 0; //Clear ASR0
break;

View File

@ -47,8 +47,23 @@ void __fastcall WriteFIFO_page_7(u32 mem, const mem128_t *value);
// --- DMA ---
//
union tDMA_CHCR {
struct {
u32 DIR : 1;
u32 reserved1 : 1;
u32 MOD : 2;
u32 ASP : 2;
u32 TTE : 1;
u32 TIE : 1;
u32 STR : 1;
u32 reserved2 : 7;
u32 TAG : 16;
};
u32 _u32;
};
struct DMACh {
u32 chcr;
tDMA_CHCR chcr;
u32 null0[3];
u32 madr;
u32 null1[3];
@ -418,6 +433,137 @@ enum DMAInter
MEISintr = 0x40004000
};
union tDMAC_CTRL {
struct {
u32 DMAE : 1;
u32 RELE : 1;
u32 MFD : 2;
u32 STS : 2;
u32 STD : 2;
u32 RCYC : 3;
u32 reserved1 : 21;
};
u32 _u32;
};
union tDMAC_STAT {
struct {
u32 CIS0 : 1;
u32 CIS1 : 1;
u32 CIS2 : 1;
u32 CIS3 : 1;
u32 CIS4 : 1;
u32 CIS5 : 1;
u32 CIS6 : 1;
u32 CIS7 : 1;
u32 CIS8 : 1;
u32 CIS9 : 1;
u32 reserved1 : 3;
u32 SIS : 1;
u32 MEIS : 1;
u32 BEIS : 1;
u32 CIM0 : 1;
u32 CIM1 : 1;
u32 CIM2 : 1;
u32 CIM3 : 1;
u32 CIM4 : 1;
u32 CIM5 : 1;
u32 CIM6 : 1;
u32 CIM7 : 1;
u32 CIM8 : 1;
u32 CIM9 : 1;
u32 reserved2 : 3;
u32 SIM : 1;
u32 MEIM : 1;
u32 reserved3 : 1;
};
u32 _u32;
};
union tDMAC_PCR {
struct {
u32 CPC0 : 1;
u32 CPC1 : 1;
u32 CPC2 : 1;
u32 CPC3 : 1;
u32 CPC4 : 1;
u32 CPC5 : 1;
u32 CPC6 : 1;
u32 CPC7 : 1;
u32 CPC8 : 1;
u32 CPC9 : 1;
u32 reserved1 : 6;
u32 CDE0 : 1;
u32 CDE1 : 1;
u32 CDE2 : 1;
u32 CDE3 : 1;
u32 CDE4 : 1;
u32 CDE5 : 1;
u32 CDE6 : 1;
u32 CDE7 : 1;
u32 CDE8 : 1;
u32 CDE9 : 1;
u32 reserved2 : 5;
u32 PCE : 1;
};
u32 _u32;
};
union tDMAC_SQWC {
struct {
u32 SQWC : 8;
u32 reserved1 : 8;
u32 TQWC : 8;
u32 reserved2 : 8;
};
u32 _u32;
};
union tDMAC_RBSR {
struct {
u32 RMSK : 31;
u32 reserved1 : 1;
};
u32 _u32;
};
union tDMAC_RBOR {
struct {
u32 ADDR : 31;
u32 reserved1 : 1;
};
u32 _u32;
};
union tDMAC_STADR {
struct {
u32 ADDR : 31;
u32 reserved1 : 1;
};
u32 _u32;
};
struct DMACregisters
{
// Note: not yet tested.
tDMAC_CTRL ctrl;
u32 padding[3];
tDMAC_STAT stat;
u32 padding1[3];
tDMAC_PCR pcr;
u32 padding2[3];
tDMAC_SQWC sqwc;
u32 padding3[3];
tDMAC_RBSR rbsr;
u32 padding4[3];
tDMAC_RBOR rbor;
u32 padding5[3];
tDMAC_STADR stadr;
};
#define dmacRegs ((DMACregisters*)(PS2MEM_HW+0xE000))
#ifdef PCSX2_VIRTUAL_MEM
#define dmaGetAddrBase(addr) (((addr) & 0x80000000) ? (void*)&PS2MEM_SCRATCH[(addr) & 0x3ff0] : (void*)(PS2MEM_BASE+TRANSFORM_ADDR(addr)))
@ -485,7 +631,7 @@ static __forceinline u32 *_dmaGetAddr(DMACh *dma, u32 addr, u32 num)
// DMA End
psHu32(DMAC_STAT) |= 1<<num;
dma->chcr &= ~0x100;
dma->chcr.STR = 0;
}
return ptr;

View File

@ -811,7 +811,7 @@ void IPUCMD_WRITE(u32 val)
case SCE_IPU_FDEC:
IPU_LOG("IPU FDEC command. Skip 0x%X bits, FIFO 0x%X qwords, BP 0x%X, FP %d, CHCR 0x%x, %x",
val & 0x3f, g_BP.IFC, (int)g_BP.BP, g_BP.FP, ipu1dma->chcr, cpuRegs.pc);
val & 0x3f, g_BP.IFC, (int)g_BP.BP, g_BP.FP, ipu1dma->chcr._u32, cpuRegs.pc);
g_BP.BP += val & 0x3F;
if (ipuFDEC(val)) return;
ipuRegs->cmd.BUSY = 0x80000000;
@ -840,7 +840,7 @@ void IPUCMD_WRITE(u32 val)
if (ipuCSC(ipuRegs->cmd.DATA))
{
if (ipu0dma->qwc > 0 && (CHCR::STR(ipu0dma))) IPU_INT0_FROM();
if (ipu0dma->qwc > 0 && ipu0dma->chcr.STR) IPU_INT0_FROM();
return;
}
break;
@ -855,7 +855,7 @@ void IPUCMD_WRITE(u32 val)
if (ipuIDEC(val))
{
// idec done, ipu0 done too
if (ipu0dma->qwc > 0 && (CHCR::STR(ipu0dma))) IPU_INT0_FROM();
if (ipu0dma->qwc > 0 && ipu0dma->chcr.STR) IPU_INT0_FROM();
return;
}
ipuRegs->topbusy = 0x80000000;
@ -867,7 +867,7 @@ void IPUCMD_WRITE(u32 val)
case SCE_IPU_BDEC:
if (ipuBDEC(val))
{
if (ipu0dma->qwc > 0 && (CHCR::STR(ipu0dma))) IPU_INT0_FROM();
if (ipu0dma->qwc > 0 && ipu0dma->chcr.STR) IPU_INT0_FROM();
if (ipuRegs->ctrl.SCD || ipuRegs->ctrl.ECD) hwIntcIrq(INTC_IPU);
return;
}
@ -931,7 +931,7 @@ void IPUWorker()
hwIntcIrq(INTC_IPU);
return;
}
if ((ipu0dma->qwc > 0) && (CHCR::STR(ipu0dma))) IPU_INT0_FROM();
if (ipu0dma->qwc > 0 && ipu0dma->chcr.STR) IPU_INT0_FROM();
break;
case SCE_IPU_PACK:
@ -957,7 +957,7 @@ void IPUWorker()
ipuCurCmd = 0xffffffff;
// CHECK!: IPU0dma remains when IDEC is done, so we need to clear it
if ((ipu0dma->qwc > 0) && (CHCR::STR(ipu0dma))) IPU_INT0_FROM();
if (ipu0dma->qwc > 0 && ipu0dma->chcr.STR) IPU_INT0_FROM();
s_routine = NULL;
break;
@ -974,7 +974,7 @@ void IPUWorker()
ipuRegs->cmd.BUSY = 0;
ipuCurCmd = 0xffffffff;
if ((ipu0dma->qwc > 0) && (CHCR::STR(ipu0dma))) IPU_INT0_FROM();
if (ipu0dma->qwc > 0 && ipu0dma->chcr.STR) IPU_INT0_FROM();
s_routine = NULL;
if (ipuRegs->ctrl.SCD || ipuRegs->ctrl.ECD) hwIntcIrq(INTC_IPU);
return;
@ -1450,9 +1450,9 @@ static __forceinline bool ipuDmacSrcChain(DMACh *tag, u32 *ptag)
static __forceinline void flushGIF()
{
while(CHCR::STR(gif) && (vif1Regs->mskpath3 == 0))
while(gif->chcr.STR && (vif1Regs->mskpath3 == 0))
{
GIF_LOG("Flushing gif chcr %x tadr %x madr %x qwc %x", gif->chcr, gif->tadr, gif->madr, gif->qwc);
GIF_LOG("Flushing gif chcr %x tadr %x madr %x qwc %x", gif->chcr._u32, gif->tadr, gif->madr, gif->qwc);
gsInterrupt();
}
}
@ -1463,9 +1463,9 @@ int IPU1dma()
bool done = false;
int ipu1cycles = 0, totalqwc = 0;
assert(!(CHCR::TTE(ipu1dma)));
assert(!ipu1dma->chcr.TTE);
if (!(CHCR::STR(ipu1dma)) || (cpuRegs.interrupt & (1 << DMAC_TO_IPU))) return 0;
if (!(ipu1dma->chcr.STR) || (cpuRegs.interrupt & (1 << DMAC_TO_IPU))) return 0;
assert(!(g_nDMATransfer & IPU_DMA_TIE1));
@ -1478,7 +1478,7 @@ int IPU1dma()
if (IPU1chain(totalqwc)) return totalqwc;
//Check TIE bit of CHCR and IRQ bit of tag
if (CHCR::TIE(ipu1dma) && (g_nDMATransfer & IPU_DMA_DOTIE1))
if (ipu1dma->chcr.TIE && (g_nDMATransfer & IPU_DMA_DOTIE1))
{
Console::WriteLn("IPU1 TIE");
@ -1488,7 +1488,7 @@ int IPU1dma()
return totalqwc;
}
if (CHCR::MOD(ipu1dma) == NORMAL_MODE) // If mode is normal mode.
if (ipu1dma->chcr.MOD == NORMAL_MODE) // If mode is normal mode.
{
IPU_INT_TO(totalqwc * BIAS);
return totalqwc;
@ -1496,9 +1496,9 @@ int IPU1dma()
else
{
// Chain mode.
u32 tag = ipu1dma->chcr; // upper bits describe current tag
u32 tag = ipu1dma->chcr._u32; // upper bits describe current tag
if (CHCR::TIE(ipu1dma) && Tag::IRQ(tag))
if (ipu1dma->chcr.TIE && Tag::IRQ(tag))
{
ptag = (u32*)dmaGetAddr(ipu1dma->tadr);
@ -1523,7 +1523,7 @@ int IPU1dma()
}
// Normal Mode & qwc is finished
if ((CHCR::MOD(ipu1dma) == NORMAL_MODE) && (ipu1dma->qwc == 0))
if ((ipu1dma->chcr.MOD == NORMAL_MODE) && (ipu1dma->qwc == 0))
{
//Console::WriteLn("ipu1 normal empty qwc?");
return totalqwc;
@ -1555,7 +1555,7 @@ int IPU1dma()
ptag[1], ptag[0], ipu1dma->qwc, ipu1dma->madr, 8 - g_BP.IFC);
if (CHCR::TIE(ipu1dma) && Tag::IRQ(ptag))
if (ipu1dma->chcr.TIE && Tag::IRQ(ptag))
g_nDMATransfer |= IPU_DMA_DOTIE1;
else
g_nDMATransfer &= ~IPU_DMA_DOTIE1;
@ -1672,15 +1672,15 @@ int IPU0dma()
int readsize;
void* pMem;
if ((!(CHCR::STR(ipu0dma)) || (cpuRegs.interrupt & (1 << DMAC_FROM_IPU))) || (ipu0dma->qwc == 0))
if ((!(ipu0dma->chcr.STR) || (cpuRegs.interrupt & (1 << DMAC_FROM_IPU))) || (ipu0dma->qwc == 0))
return 0;
assert(!(CHCR::TTE(ipu0dma)));
assert(!(ipu0dma->chcr.TTE));
IPU_LOG("dmaIPU0 chcr = %lx, madr = %lx, qwc = %lx",
ipu0dma->chcr, ipu0dma->madr, ipu0dma->qwc);
ipu0dma->chcr._u32, ipu0dma->madr, ipu0dma->qwc);
assert((ipu0dma->chcr & 0xC) == 0);
assert((ipu0dma->chcr._u32 & 0xC) == 0);
pMem = (u32*)dmaGetAddr(ipu0dma->madr);
readsize = min(ipu0dma->qwc, (u16)ipuRegs->ctrl.OFC);
FIFOfrom_read(pMem, readsize);
@ -1734,14 +1734,14 @@ void ipu0Interrupt()
{
// gif
g_nDMATransfer &= ~IPU_DMA_GIFSTALL;
if (CHCR::STR(gif)) GIFdma();
if (gif->chcr.STR) GIFdma();
}
if (g_nDMATransfer & IPU_DMA_VIFSTALL)
{
// vif
g_nDMATransfer &= ~IPU_DMA_VIFSTALL;
if (CHCR::STR(vif1ch)) dmaVIF1();
if (vif1ch->chcr.STR) dmaVIF1();
}
if (g_nDMATransfer & IPU_DMA_TIE0)
@ -1749,7 +1749,7 @@ void ipu0Interrupt()
g_nDMATransfer &= ~IPU_DMA_TIE0;
}
CHCR::clearSTR(ipu0dma);
ipu0dma->chcr.STR = 0;
hwDmacIrq(DMAC_FROM_IPU);
}
@ -1767,7 +1767,7 @@ IPU_FORCEINLINE void ipu1Interrupt()
if (g_nDMATransfer & IPU_DMA_TIE1)
g_nDMATransfer &= ~IPU_DMA_TIE1;
else
CHCR::clearSTR(ipu1dma);
ipu1dma->chcr.STR = 0;
hwDmacIrq(DMAC_TO_IPU);
}

View File

@ -60,40 +60,6 @@ union tIPU_CMD {
};
};
enum ipu_ctrl_m_flags
{
IPU_CTRL_IFC_M = (0x0f<< 0),
IPU_CTRL_OFC_M = (0x0f<< 4),
IPU_CTRL_CBP_M = (0x3f<< 8),
IPU_CTRL_ECD_M = (0x01<<14),
IPU_CTRL_SCD_M = (0x01<<15),
IPU_CTRL_IDP_M = (0x03<<16),
IPU_CTRL_AS_M = (0x01<<20),
IPU_CTRL_IVF_M = (0x01<<21),
IPU_CTRL_QST_M = (0x01<<22),
IPU_CTRL_MP1_M = (0x01<<23),
IPU_CTRL_PCT_M = (0x07<<24),
IPU_CTRL_RST_M = (0x01<<30),
IPU_CTRL_BUSY_M = (0x01<<31)
};
enum ipu_ctrl_o_flags
{
IPU_CTRL_IFC_O = ( 0),
IPU_CTRL_OFC_O = ( 4),
IPU_CTRL_CBP_O = ( 8),
IPU_CTRL_ECD_O = (14),
IPU_CTRL_SCD_O = (15),
IPU_CTRL_IDP_O = (16),
IPU_CTRL_AS_O = (20),
IPU_CTRL_IVF_O = (21),
IPU_CTRL_QST_O = (22),
IPU_CTRL_MP1_O = (23),
IPU_CTRL_PCT_O = (24),
IPU_CTRL_RST_O = (30),
IPU_CTRL_BUSY_O = (31)
};
//
// Bitfield Structure
//
@ -118,20 +84,6 @@ union tIPU_CTRL {
u32 _u32;
};
enum ipu_bp_m_flags
{
IPU_BP_BP_M = (0x7f<< 0),
IPU_BP_IFC_M = (0x0f<< 8),
IPU_BP_FP_M = (0x03<<16)
};
enum ipu_bp_o_flags
{
IPU_BP_BP_O = ( 0),
IPU_BP_IFC_O = ( 8),
IPU_BP_FP_O = (16)
};
//
// Bitfield Structure
//

View File

@ -140,7 +140,7 @@ static __forceinline void _dmaSPR0()
}
// Transfer Dn_QWC from SPR to Dn_MADR
switch(CHCR::MOD(spr0))
switch(spr0->chcr.MOD)
{
case NORMAL_MODE:
{
@ -192,7 +192,7 @@ static __forceinline void _dmaSPR0()
break;
}
SPR0chain();
if (CHCR::TIE(spr0) && Tag::IRQ(ptag)) //Check TIE bit of CHCR and IRQ bit of tag
if (spr0->chcr.TIE && Tag::IRQ(ptag)) //Check TIE bit of CHCR and IRQ bit of tag
{
//Console::WriteLn("SPR0 TIE");
done = TRUE;
@ -229,23 +229,23 @@ void SPRFROMinterrupt()
{
if ((spr0->madr & ~psHu32(DMAC_RBSR)) != psHu32(DMAC_RBOR)) Console::WriteLn("GIF MFIFO Write outside MFIFO area");
spr0->madr = psHu32(DMAC_RBOR) + (spr0->madr & psHu32(DMAC_RBSR));
//Console::WriteLn("mfifoGIFtransfer %x madr %x, tadr %x", params gif->chcr, gif->madr, gif->tadr);
//Console::WriteLn("mfifoGIFtransfer %x madr %x, tadr %x", params gif->chcr._u32, gif->madr, gif->tadr);
mfifoGIFtransfer(mfifotransferred);
mfifotransferred = 0;
if (CHCR::STR(gif)) return;
if (gif->chcr.STR) return;
}
else if ((psHu32(DMAC_CTRL) & 0xC) == 0x8) // VIF1 MFIFO
{
if ((spr0->madr & ~psHu32(DMAC_RBSR)) != psHu32(DMAC_RBOR)) Console::WriteLn("VIF MFIFO Write outside MFIFO area");
spr0->madr = psHu32(DMAC_RBOR) + (spr0->madr & psHu32(DMAC_RBSR));
//Console::WriteLn("mfifoVIF1transfer %x madr %x, tadr %x", params vif1ch->chcr, vif1ch->madr, vif1ch->tadr);
//Console::WriteLn("mfifoVIF1transfer %x madr %x, tadr %x", params vif1ch->chcr._u32, vif1ch->madr, vif1ch->tadr);
mfifoVIF1transfer(mfifotransferred);
mfifotransferred = 0;
if (CHCR::STR(vif1ch)) return;
if (vif1ch->chcr.STR) return;
}
}
if (spr0finished == 0) return;
CHCR::clearSTR(spr0);
spr0->chcr.STR = 0;
hwDmacIrq(DMAC_FROM_SPR);
}
@ -253,9 +253,9 @@ void SPRFROMinterrupt()
void dmaSPR0() // fromSPR
{
SPR_LOG("dmaSPR0 chcr = %lx, madr = %lx, qwc = %lx, sadr = %lx",
spr0->chcr, spr0->madr, spr0->qwc, spr0->sadr);
spr0->chcr._u32, spr0->madr, spr0->qwc, spr0->sadr);
if ((CHCR::MOD(spr0) == CHAIN_MODE) && spr0->qwc == 0)
if ((spr0->chcr.MOD == CHAIN_MODE) && spr0->qwc == 0)
{
u32 *ptag;
ptag = (u32*) & PS2MEM_SCRATCH[spr0->sadr & 0x3fff]; //Set memory pointer to SADR
@ -324,7 +324,7 @@ void _SPR1interleave()
void _dmaSPR1() // toSPR work function
{
switch(CHCR::MOD(spr1))
switch(spr1->chcr.MOD)
{
case NORMAL_MODE:
{
@ -338,7 +338,7 @@ void _dmaSPR1() // toSPR work function
{
u32 *ptag;
int id;
bool done = FALSE;
bool done = false;
if (spr1->qwc > 0)
{
@ -353,7 +353,7 @@ void _dmaSPR1() // toSPR work function
if (!(Tag::Transfer("SPR1 Tag", spr1, ptag)))
{
done = TRUE;
done = true;
spr1finished = (done) ? 1: 0;
}
@ -361,7 +361,7 @@ void _dmaSPR1() // toSPR work function
spr1->madr = ptag[1]; //MADR = ADDR field
// Transfer dma tag if tte is set
if (CHCR::TTE(spr1))
if (spr1->chcr.TTE)
{
SPR_LOG("SPR TTE: %x_%x\n", ptag[3], ptag[2]);
SPR1transfer(ptag, 4); //Transfer Tag
@ -373,12 +373,12 @@ void _dmaSPR1() // toSPR work function
done = (hwDmacSrcChain(spr1, id) == 1);
SPR1chain(); //Transfers the data set by the switch
if (CHCR::TIE(spr1) && Tag::IRQ(ptag)) //Check TIE bit of CHCR and IRQ bit of tag
if (spr1->chcr.TIE && Tag::IRQ(ptag)) //Check TIE bit of CHCR and IRQ bit of tag
{
SPR_LOG("dmaIrq Set");
//Console::WriteLn("SPR1 TIE");
done = TRUE;
done = true;
}
spr1finished = done;
@ -403,10 +403,10 @@ void dmaSPR1() // toSPR
SPR_LOG("dmaSPR1 chcr = 0x%x, madr = 0x%x, qwc = 0x%x\n"
" tadr = 0x%x, sadr = 0x%x",
spr1->chcr, spr1->madr, spr1->qwc,
spr1->chcr._u32, spr1->madr, spr1->qwc,
spr1->tadr, spr1->sadr);
if ((CHCR::MOD(spr1) == CHAIN_MODE) && (spr1->qwc == 0))
if ((spr1->chcr.MOD == CHAIN_MODE) && (spr1->qwc == 0))
{
u32 *ptag;
ptag = (u32*)dmaGetAddr(spr1->tadr); //Set memory pointer to TADR
@ -423,7 +423,7 @@ void SPRTOinterrupt()
{
_dmaSPR1();
if (spr1finished == 0) return;
CHCR::clearSTR(spr1);
spr1->chcr.STR = 0;
hwDmacIrq(DMAC_TO_SPR);
}

View File

@ -222,7 +222,7 @@ __forceinline void SIF0Dma()
if (sif0dma->qwc == 0)
{
// Stop if TIE & the IRQ are set, or at the end. (I'll try to convert this to use the tags code later.)
if (((sif0dma->chcr & 0x80000080) == 0x80000080) || (sif0.end))
if (((sif0dma->chcr._u32 & 0x80000080) == 0x80000080) || (sif0.end))
{
if (sif0.end)
SIF_LOG(" EE SIF end");
@ -241,7 +241,7 @@ __forceinline void SIF0Dma()
sif0dma->qwc = (u16)tag[0];
sif0dma->madr = tag[1];
sif0dma->chcr = (sif0dma->chcr & 0xffff) | (tag[0] & 0xffff0000);
sif0dma->chcr._u32 = (sif0dma->chcr._u32 & 0xffff) | (tag[0] & 0xffff0000);
SIF_LOG(" EE SIF dest chain tag madr:%08X qwc:%04X id:%X irq:%d(%08X_%08X)", sif0dma->madr, sif0dma->qwc, (tag[0] >> 28)&3, (tag[0] >> 31)&1, tag[1], tag[0]);
@ -274,7 +274,7 @@ __forceinline void SIF1Dma()
if (sif1dma->qwc == 0) // If there's no more to transfer
{
if ((CHCR::MOD(sif1dma) == NORMAL_MODE) || sif1.end) // If NORMAL mode or end of CHAIN then stop DMA
if ((sif1dma->chcr.MOD == NORMAL_MODE) || sif1.end) // If NORMAL mode or end of CHAIN then stop DMA
{
// Stop & signal interrupts on EE
SIF_LOG("EE SIF1 End %x", sif1.end);
@ -294,10 +294,10 @@ __forceinline void SIF1Dma()
//_dmaGetAddr(sif1dma, *ptag, sif1dma->tadr, 6);
sif1dma->chcr = (sif1dma->chcr & 0xFFFF) | ((*ptag) & 0xFFFF0000); // Copy the tag
sif1dma->chcr._u32 = (sif1dma->chcr._u32 & 0xFFFF) | ((*ptag) & 0xFFFF0000); // Copy the tag
sif1dma->qwc = (u16)ptag[0];
if (CHCR::TTE(sif1dma))
if (sif1dma->chcr.TTE)
{
Console::WriteLn("SIF1 TTE");
SIF1write(ptag + 2, 2);
@ -343,7 +343,7 @@ __forceinline void SIF1Dma()
default:
Console::WriteLn("Bad addr1 source chain");
}
if ((CHCR::TIE(sif1dma)) && (Tag::IRQ(ptag)))
if ((sif1dma->chcr.TIE) && (Tag::IRQ(ptag)))
{
Console::WriteLn("SIF1 TIE");
sif1.end = 1;
@ -435,19 +435,19 @@ __forceinline void sif1Interrupt()
__forceinline void EEsif0Interrupt()
{
hwDmacIrq(DMAC_SIF0);
CHCR::clearSTR(sif0dma);
sif0dma->chcr.STR = 0;
}
__forceinline void EEsif1Interrupt()
{
hwDmacIrq(DMAC_SIF1);
CHCR::clearSTR(sif1dma);
sif1dma->chcr.STR = 0;
}
__forceinline void dmaSIF0()
{
SIF_LOG("EE: dmaSIF0 chcr = %lx, madr = %lx, qwc = %lx, tadr = %lx",
sif0dma->chcr, sif0dma->madr, sif0dma->qwc, sif0dma->tadr);
sif0dma->chcr._u32, sif0dma->madr, sif0dma->qwc, sif0dma->tadr);
if (sif0.fifoReadPos != sif0.fifoWritePos)
{
@ -470,7 +470,7 @@ __forceinline void dmaSIF0()
__forceinline void dmaSIF1()
{
SIF_LOG("EE: dmaSIF1 chcr = %lx, madr = %lx, qwc = %lx, tadr = %lx",
sif1dma->chcr, sif1dma->madr, sif1dma->qwc, sif1dma->tadr);
sif1dma->chcr._u32, sif1dma->madr, sif1dma->qwc, sif1dma->tadr);
if (sif1.fifoReadPos != sif1.fifoWritePos)
{
@ -494,9 +494,9 @@ __forceinline void dmaSIF1()
__forceinline void dmaSIF2()
{
SIF_LOG("dmaSIF2 chcr = %lx, madr = %lx, qwc = %lx",
sif2dma->chcr, sif2dma->madr, sif2dma->qwc);
sif2dma->chcr._u32, sif2dma->madr, sif2dma->qwc);
CHCR::clearSTR(sif2dma);
sif2dma->chcr.STR = 0;
hwDmacIrq(DMAC_SIF2);
Console::WriteLn("*PCSX2*: dmaSIF2");
}

View File

@ -107,7 +107,7 @@ namespace Tag
static __forceinline void UpperTransfer(DMACh *tag, u32* ptag)
{
// Transfer upper part of tag to CHCR bits 31-15
tag->chcr = (tag->chcr & 0xFFFF) | ((*ptag) & 0xFFFF0000);
tag->chcr._u32 = (tag->chcr._u32 & 0xFFFF) | ((*ptag) & 0xFFFF0000);
}
static __forceinline void LowerTransfer(DMACh *tag, u32* ptag)
@ -193,100 +193,28 @@ namespace Tag
}
}
namespace CHCR
// Print information about a chcr tag.
static __forceinline void PrintCHCR(const char* s, DMACh *tag)
{
// Query the flags in the channel control register.
static __forceinline bool STR(DMACh *tag) { return !!(tag->chcr & CHCR_STR); }
static __forceinline bool TIE(DMACh *tag) { return !!(tag->chcr & CHCR_TIE); }
static __forceinline bool TTE(DMACh *tag) { return !!(tag->chcr & CHCR_TTE); }
static __forceinline u8 DIR(DMACh *tag) { return (tag->chcr & CHCR_DIR); }
static __forceinline TransferMode MOD(DMACh *tag)
{
return (TransferMode)((tag->chcr & CHCR_MOD) >> 2);
}
static __forceinline u8 ASP(DMACh *tag)
{
u8 num_addr = tag->chcr.ASP;
u32 mode = tag->chcr.MOD;
return (TransferMode)((tag->chcr & CHCR_ASP) >> 4);
}
// Clear the individual flags.
static __forceinline void clearSTR(DMACh *tag) { tag->chcr &= ~CHCR_STR; }
static __forceinline void clearTIE(DMACh *tag) { tag->chcr &= ~CHCR_TIE; }
static __forceinline void clearTTE(DMACh *tag) { tag->chcr &= ~CHCR_TTE; }
static __forceinline void clearDIR(DMACh *tag) { tag->chcr &= ~CHCR_DIR; }
// Set them.
static __forceinline void setSTR(DMACh *tag) { tag->chcr |= CHCR_STR; }
static __forceinline void setTIE(DMACh *tag) { tag->chcr |= CHCR_TIE; }
static __forceinline void setTTE(DMACh *tag) { tag->chcr |= CHCR_TTE; }
static __forceinline void setDIR(DMACh *tag) { tag->chcr |= CHCR_DIR; }
static __forceinline void setMOD(DMACh *tag, TransferMode mode)
{
if (mode & (1 << 0))
tag->chcr |= CHCR_MOD1;
else
tag->chcr &= CHCR_MOD1;
if (mode & (1 << 1))
tag->chcr |= CHCR_MOD2;
else
tag->chcr &= CHCR_MOD2;
}
static __forceinline void setASP(DMACh *tag, u8 num)
{
if (num & (1 << 0))
tag->chcr |= CHCR_ASP1;
else
tag->chcr &= CHCR_ASP2;
if (num & (1 << 1))
tag->chcr |= CHCR_ASP1;
else
tag->chcr &= CHCR_ASP2;
}
// Print information about a chcr tag.
static __forceinline void Print(const char* s, DMACh *tag)
{
u8 num_addr = ASP(tag);
TransferMode mode = MOD(tag);
Console::Write("%s chcr %s mem: ", params s, (tag->chcr.DIR) ? "from" : "to");
Console::Write("%s chcr %s mem: ", params s, (DIR(tag)) ? "from" : "to");
if (mode == NORMAL_MODE)
Console::Write(" normal mode; ");
else if (mode == CHAIN_MODE)
Console::Write(" chain mode; ");
else if (mode == INTERLEAVE_MODE)
Console::Write(" interleave mode; ");
else
Console::Write(" ?? mode; ");
if (mode == NORMAL_MODE)
Console::Write(" normal mode; ");
else if (mode == CHAIN_MODE)
Console::Write(" chain mode; ");
else if (mode == INTERLEAVE_MODE)
Console::Write(" interleave mode; ");
else
Console::Write(" ?? mode; ");
if (num_addr != 0) Console::Write("ASP = %d;", params num_addr);
if (TTE(tag)) Console::Write("TTE;");
if (TIE(tag)) Console::Write("TIE;");
if (STR(tag)) Console::Write(" (DMA started)."); else Console::Write(" (DMA stopped).");
Console::WriteLn("");
}
}
namespace QWC
{
static __forceinline bool Empty(DMACh *tag)
{
return (tag->qwc == 0);
}
static __forceinline void Clear(DMACh *tag)
{
tag->qwc = 0;
}
if (num_addr != 0) Console::Write("ASP = %d;", params num_addr);
if (tag->chcr.TTE) Console::Write("TTE;");
if (tag->chcr.TIE) Console::Write("TIE;");
if (tag->chcr.STR) Console::Write(" (DMA started)."); else Console::Write(" (DMA stopped).");
Console::WriteLn("");
}
namespace D_CTRL

View File

@ -434,7 +434,7 @@ void mfifoVIF1transfer(int qwc)
if (qwc > 0)
{
vifqwc += qwc;
SPR_LOG("Added %x qw to mfifo, total now %x - Vif CHCR %x Stalled %x done %x", qwc, vifqwc, vif1ch->chcr, vif1.vifstalled, vif1.done);
SPR_LOG("Added %x qw to mfifo, total now %x - Vif CHCR %x Stalled %x done %x", qwc, vifqwc, vif1ch->chcr._u32, vif1.vifstalled, vif1.done);
if (vif1.inprogress & 0x10)
{
if (vif1ch->madr >= psHu32(DMAC_RBOR) && vif1ch->madr <= (psHu32(DMAC_RBOR) + psHu32(DMAC_RBSR)))
@ -453,7 +453,7 @@ void mfifoVIF1transfer(int qwc)
{
ptag = (u32*)dmaGetAddr(vif1ch->tadr);
if (CHCR::TTE(vif1ch))
if (vif1ch->chcr.TTE)
{
if (vif1.stallontag)
ret = VIF1transfer(ptag + (2 + vif1.irqoffset), 2 - vif1.irqoffset, 1); //Transfer Tag on Stall
@ -513,7 +513,7 @@ void mfifoVIF1transfer(int qwc)
break;
}
if ((CHCR::TIE(vif1ch)) && (Tag::IRQ(ptag)))
if ((vif1ch->chcr.TIE) && (Tag::IRQ(ptag)))
{
VIF_LOG("dmaIrq Set");
vif1.done = true;
@ -522,7 +522,7 @@ void mfifoVIF1transfer(int qwc)
vif1.inprogress |= 1;
SPR_LOG("mfifoVIF1transfer end %x madr %x, tadr %x vifqwc %x", vif1ch->chcr, vif1ch->madr, vif1ch->tadr, vifqwc);
SPR_LOG("mfifoVIF1transfer end %x madr %x, tadr %x vifqwc %x", vif1ch->chcr._u32, vif1ch->madr, vif1ch->tadr, vifqwc);
}
void vifMFIFOInterrupt()
@ -533,7 +533,7 @@ void vifMFIFOInterrupt()
if ((vif1Regs->stat & VIF1_STAT_VGW))
{
if (CHCR::STR(gif))
if (gif->chcr.STR)
{
CPU_INT(10, 16);
return;
@ -545,9 +545,9 @@ void vifMFIFOInterrupt()
}
if ((CHCR::STR(spr0)) && (spr0->qwc == 0))
if ((spr0->chcr.STR) && (spr0->qwc == 0))
{
CHCR::clearSTR(spr0);
spr0->chcr.STR = 0;
hwDmacIrq(DMAC_FROM_SPR);
}
@ -559,7 +559,7 @@ void vifMFIFOInterrupt()
if (vif1Regs->stat & (VIF1_STAT_VSS | VIF1_STAT_VIS | VIF1_STAT_VFS))
{
vif1Regs->stat &= ~VIF1_STAT_FQC; // FQC=0
CHCR::clearSTR(vif1ch);
vif1ch->chcr.STR = 0;
return;
}
}
@ -606,7 +606,7 @@ void vifMFIFOInterrupt()
vif1.done = 1;
g_vifCycles = 0;
CHCR::clearSTR(vif1ch);
vif1ch->chcr.STR = 0;
hwDmacIrq(DMAC_VIF1);
VIF_LOG("vif mfifo dma end");

View File

@ -29,32 +29,52 @@ struct vifCycle {
//
union tVIF_STAT {
struct {
u32 VPS : 2;
u32 VEW : 1;
u32 VGW : 1;
u32 VPS : 2; // Vif(0/1) status.
u32 VEW : 1; // E-bit wait (1 - wait, 0 - don't wait)
u32 VGW : 1; // Status waiting for the end of gif transfer (Vif1 only)
u32 reserved : 2;
u32 MRK : 1;
u32 DBF : 1;
u32 VSS : 1;
u32 VFS : 1;
u32 VIS : 1;
u32 INT : 1;
u32 ER0 : 1;
u32 ER1 : 1;
u32 MRK : 1; // Mark Detect
u32 DBF : 1; // Double Buffer Flag
u32 VSS : 1; // Stopped by STOP
u32 VFS : 1; // Stopped by ForceBreak
u32 VIS : 1; // Vif Interrupt Stall
u32 INT : 1; // Intereupt by the i bit.
u32 ER0 : 1; // DmaTag Mismatch error.
u32 ER1 : 1; // VifCode error
u32 reserved2 : 9;
u32 FDR : 1;
u32 FQC : 5;
u32 FDR : 1; // VIF/FIFO transfer direction. (0 - memory -> Vif, 1 - Vif -> memory)
u32 FQC : 5; // Amount of data. Up to 8 qwords on Vif0, 16 on Vif1.
};
u32 _u32;
};
union tVIF_FBRST {
struct {
u32 RST : 1; // Resets Vif(0/1) when written.
u32 FBK : 1; // Causes a Forcebreak to Vif((0/1) when 1 is written. (Stall)
u32 STP : 1; // Stops after the end of the Vifcode in progress when written. (Stall)
u32 STC : 1; // Cancels the Vif(0/1) stall and clears Vif Stats VSS, VFS, VIS, INT, ER0 & ER1.
u32 reserved : 28;
};
u32 _u32;
};
union tVIF_ERR {
struct {
u32 MII : 1; // Masks Stat INT.
u32 ME0 : 1; // Masks Stat Err0.
u32 ME1 : 1; // Masks Stat Err1.
u32 reserved : 29;
};
u32 _u32;
};
// r0-r3 and c0-c3 would be more managable as arrays.
struct VIFregisters {
u32 stat;
u32 pad0[3];
u32 fbrst;
u32 pad1[3];
u32 err;
tVIF_ERR err;
u32 pad2[3];
u32 mark;
u32 pad3[3];
@ -102,7 +122,7 @@ struct VIFregisters {
u32 addr;
};
enum vif_errors
/*enum vif_errors
{
VIF_ERR_MII = 0x1,
VIF_ERR_ME0 = 0x2,
@ -120,7 +140,7 @@ namespace VIF_ERR
// If true, VifCode errors are masked.
static __forceinline bool ME1(VIFregisters *tag) { return !!(tag->err & VIF_ERR_ME1); }
}
}*/
extern "C"
{

View File

@ -1222,7 +1222,7 @@ static void Vif0CMDMPGTransfer() // MPG
static void Vif0CMDNull() // invalid opcode
{
// if ME1, then force the vif to interrupt
if (!(VIF_ERR::ME1(vif0Regs))) //Ignore vifcode and tag mismatch error
if (!(vif0Regs->err.ME1)) //Ignore vifcode and tag mismatch error
{
Console::WriteLn("UNKNOWN VifCmd: %x", params vif0.cmd);
vif0Regs->stat |= VIF0_STAT_ER1;
@ -1274,7 +1274,7 @@ int VIF0transfer(u32 *data, int size, int istag)
if ((vif0.cmd & 0x7f) > 0x4A)
{
if (!(VIF_ERR::ME1(vif0Regs))) //Ignore vifcode and tag mismatch error
if (!(vif0Regs->err.ME1)) //Ignore vifcode and tag mismatch error
{
Console::WriteLn("UNKNOWN VifCmd: %x", params vif0.cmd);
vif0Regs->stat |= VIF0_STAT_ER1;
@ -1294,7 +1294,7 @@ int VIF0transfer(u32 *data, int size, int istag)
{
vif0.cmd &= 0x7f;
if (!(VIF_ERR::MII(vif0Regs))) //i bit on vifcode and not masked by VIF0_ERR
if (!(vif0Regs->err.MII)) //i bit on vifcode and not masked by VIF0_ERR
{
VIF_LOG("Interrupt on VIFcmd: %x (INTC_MASK = %x)", vif0.cmd, psHu32(INTC_MASK));
@ -1385,7 +1385,7 @@ int _chainVIF0()
vif0ptag[1], vif0ptag[0], vif0ch->qwc, id, vif0ch->madr, vif0ch->tadr);
// Transfer dma tag if tte is set
if (CHCR::TTE(vif0ch))
if (vif0ch->chcr.TTE)
{
if (vif0.vifstalled)
ret = VIF0transfer(vif0ptag + (2 + vif0.irqoffset), 2 - vif0.irqoffset, 1); //Transfer Tag on stall
@ -1403,7 +1403,7 @@ int _chainVIF0()
ret = _VIF0chain(); //Transfers the data set by the switch
if (CHCR::TIE(vif0ch) && Tag::IRQ(vif0ptag)) //Check TIE bit of CHCR and IRQ bit of tag
if (vif0ch->chcr.TIE && Tag::IRQ(vif0ptag)) //Check TIE bit of CHCR and IRQ bit of tag
{
VIF_LOG("dmaIrq Set\n");
@ -1426,7 +1426,7 @@ void vif0Interrupt()
if (vif0Regs->stat & (VIF0_STAT_VSS | VIF0_STAT_VIS | VIF0_STAT_VFS))
{
vif0Regs->stat &= ~VIF0_STAT_FQC; // FQC=0
CHCR::clearSTR(vif0ch);
vif0ch->chcr.STR = 0;
return;
}
@ -1442,9 +1442,9 @@ void vif0Interrupt()
}
}
if (!CHCR::STR(vif0ch)) Console::WriteLn("Vif0 running when CHCR = %x", params vif0ch->chcr);
if (!vif0ch->chcr.STR) Console::WriteLn("Vif0 running when CHCR = %x", params vif0ch->chcr._u32);
if ((CHCR::MOD(vif0ch) == CHAIN_MODE) && (!vif0.done) && (!vif0.vifstalled))
if ((vif0ch->chcr.STR == CHAIN_MODE) && (!vif0.done) && (!vif0.vifstalled))
{
if (!(psHu32(DMAC_CTRL) & 0x1))
@ -1465,7 +1465,7 @@ void vif0Interrupt()
if (vif0ch->qwc > 0) Console::WriteLn("VIF0 Ending with QWC left");
if (vif0.cmd != 0) Console::WriteLn("vif0.cmd still set %x", params vif0.cmd);
CHCR::clearSTR(vif0ch);
vif0ch->chcr.STR = 0;
hwDmacIrq(DMAC_VIF0);
vif0Regs->stat &= ~VIF0_STAT_FQC; // FQC=0
}
@ -1510,14 +1510,14 @@ void dmaVIF0()
{
VIF_LOG("dmaVIF0 chcr = %lx, madr = %lx, qwc = %lx\n"
" tadr = %lx, asr0 = %lx, asr1 = %lx\n",
vif0ch->chcr, vif0ch->madr, vif0ch->qwc,
vif0ch->chcr._u32, vif0ch->madr, vif0ch->qwc,
vif0ch->tadr, vif0ch->asr0, vif0ch->asr1);
g_vifCycles = 0;
vif0Regs->stat |= 0x8000000; // FQC=8
if (!(vif0ch->chcr & 0x4) || vif0ch->qwc > 0) // Normal Mode
if (!(vif0ch->chcr.MOD & 0x1) || vif0ch->qwc > 0) // Normal Mode
{
if (_VIF0chain() == -2)
{
@ -1561,7 +1561,7 @@ void vif0Write32(u32 mem, u32 value)
psHu64(VIF0_FIFO) = 0;
psHu64(VIF0_FIFO + 8) = 0; // VIF0_FIFO + 8
vif0.done = true;
vif0Regs->err = 0;
vif0Regs->err._u32 = 0;
vif0Regs->stat &= ~(VIF0_STAT_FQC | VIF0_STAT_INT | VIF0_STAT_VSS | VIF0_STAT_VIS | VIF0_STAT_VFS | VIF0_STAT_VPS); // FQC=0
}
@ -1608,7 +1608,7 @@ void vif0Write32(u32 mem, u32 value)
else
_VIF0chain();
CHCR::setSTR(vif0ch);
vif0ch->chcr.STR = 1;
CPU_INT(0, g_vifCycles); // Gets the timing right - Flatout
}
}
@ -1620,7 +1620,7 @@ void vif0Write32(u32 mem, u32 value)
VIF_LOG("VIF0_ERR write32 0x%8.8x", value);
/* Set VIF0_ERR with 'value' */
vif0Regs->err = value;
vif0Regs->err._u32 = value;
break;
case VIF0_R0:
@ -1862,7 +1862,7 @@ static int __fastcall Vif1TransDirectHL(u32 *data)
if ((vif1.cmd & 0x7f) == 0x51)
{
if (CHCR::STR(gif) && (!vif1Regs->mskpath3 && (Path3progress == IMAGE_MODE))) //PATH3 is in image mode, so wait for end of transfer
if (gif->chcr.STR && (!vif1Regs->mskpath3 && (Path3progress == IMAGE_MODE))) //PATH3 is in image mode, so wait for end of transfer
{
vif1Regs->stat |= VIF1_STAT_VGW;
return 0;
@ -2068,7 +2068,7 @@ void Vif1MskPath3() // MSKPATH3
}
static void Vif1CMDMskPath3() // MSKPATH3
{
if (CHCR::STR(vif1ch))
if (vif1ch->chcr.STR)
{
schedulepath3msk = 0x10 | ((vif1Regs->code >> 15) & 0x1);
vif1.vifstalled = true;
@ -2096,7 +2096,7 @@ static void Vif1CMDFlush() // FLUSH/E/A
if ((vif1.cmd & 0x7f) == 0x13)
{
// Gif is already transferring so wait for it.
if (((Path3progress != STOPPED_MODE) || !vif1Regs->mskpath3) && CHCR::STR(gif))
if (((Path3progress != STOPPED_MODE) || !vif1Regs->mskpath3) && gif->chcr.STR)
{
vif1Regs->stat |= VIF1_STAT_VGW;
CPU_INT(2, 4);
@ -2157,7 +2157,7 @@ static void Vif1CMDNull() // invalid opcode
{
// if ME1, then force the vif to interrupt
if (!(VIF_ERR::ME1(vif1Regs))) //Ignore vifcode and tag mismatch error
if (!(vif1Regs->err.ME1)) //Ignore vifcode and tag mismatch error
{
Console::WriteLn("UNKNOWN VifCmd: %x\n", params vif1.cmd);
vif1Regs->stat |= VIF1_STAT_ER1;
@ -2255,7 +2255,7 @@ int VIF1transfer(u32 *data, int size, int istag)
if ((vif1.cmd & 0x7f) > 0x51)
{
if (!(VIF_ERR::ME1(vif1Regs))) //Ignore vifcode and tag mismatch error
if (!(vif0Regs->err.ME1)) //Ignore vifcode and tag mismatch error
{
Console::WriteLn("UNKNOWN VifCmd: %x", params vif1.cmd);
vif1Regs->stat |= VIF1_STAT_ER1;
@ -2273,7 +2273,7 @@ int VIF1transfer(u32 *data, int size, int istag)
{
vif1.cmd &= 0x7f;
if (!(VIF_ERR::MII(vif1Regs))) //i bit on vifcode and not masked by VIF1_ERR
if (!(vif1Regs->err.MII)) //i bit on vifcode and not masked by VIF1_ERR
{
VIF_LOG("Interrupt on VIFcmd: %x (INTC_MASK = %x)", vif1.cmd, psHu32(INTC_MASK));
@ -2474,7 +2474,7 @@ __forceinline void vif1SetupTransfer()
vif1.inprogress = 1;
if (CHCR::TTE(vif1ch))
if (vif1ch->chcr.TTE)
{
if (vif1.vifstalled)
@ -2493,7 +2493,7 @@ __forceinline void vif1SetupTransfer()
vif1.done |= hwDmacSrcChainWithStack(vif1ch, id);
//Check TIE bit of CHCR and IRQ bit of tag
if ((CHCR::TIE(vif1ch)) && (Tag::IRQ(vif1ptag)))
if (vif1ch->chcr.TIE && (Tag::IRQ(vif1ptag)))
{
VIF_LOG("dmaIrq Set");
@ -2514,7 +2514,7 @@ __forceinline void vif1Interrupt()
if((vif1Regs->stat & VIF1_STAT_VGW))
{
if (CHCR::STR(gif))
if (gif->chcr.STR)
{
CPU_INT(1, gif->qwc * BIAS);
return;
@ -2523,7 +2523,7 @@ __forceinline void vif1Interrupt()
}
if (!(CHCR::STR(vif1ch))) Console::WriteLn("Vif1 running when CHCR == %x", params vif1ch->chcr);
if (!(vif1ch->chcr.STR)) Console::WriteLn("Vif1 running when CHCR == %x", params vif1ch->chcr._u32);
if (vif1.irq && vif1.tag.size == 0)
{
@ -2535,7 +2535,7 @@ __forceinline void vif1Interrupt()
vif1Regs->stat &= ~VIF1_STAT_FQC; // FQC=0
// One game doesnt like vif stalling at end, cant remember what. Spiderman isnt keen on it tho
CHCR::clearSTR(vif1ch);
vif1ch->chcr.STR = 0;
return;
}
else if ((vif1ch->qwc > 0) || (vif1.irqoffset > 0))
@ -2580,7 +2580,7 @@ __forceinline void vif1Interrupt()
#endif
vif1Regs->stat &= ~VIF1_STAT_VPS; //Vif goes idle as the stall happened between commands;
CHCR::clearSTR(vif1ch);
vif1ch->chcr.STR = 0;
g_vifCycles = 0;
hwDmacIrq(DMAC_VIF1);
@ -2588,7 +2588,7 @@ __forceinline void vif1Interrupt()
//Games effected by setting, Fatal Frame, KH2, Shox, Crash N Burn, GT3/4 possibly
//Im guessing due to the full gs fifo before the reverse? (Refraction)
//Note also this is only the condition for reverse fifo mode, normal direction clears it as normal
if (!vif1Regs->mskpath3 || (CHCR::DIR(vif1ch))) vif1Regs->stat &= ~0x1F000000; // FQC=0
if (!vif1Regs->mskpath3 || vif1ch->chcr.DIR) vif1Regs->stat &= ~0x1F000000; // FQC=0
}
void dmaVIF1()
@ -2605,7 +2605,7 @@ void dmaVIF1()
{
//Console::WriteLn("VIFMFIFO\n");
// Test changed because the Final Fantasy 12 opening somehow has the tag in *Undefined* mode, which is not in the documentation that I saw.
if (CHCR::MOD(vif1ch) == NORMAL_MODE) Console::WriteLn("MFIFO mode is normal (which isn't normal here)! %x", params vif1ch->chcr);
if (vif1ch->chcr.MOD == NORMAL_MODE) Console::WriteLn("MFIFO mode is normal (which isn't normal here)! %x", params vif1ch->chcr);
vifMFIFOInterrupt();
return;
}
@ -2617,13 +2617,13 @@ void dmaVIF1()
}
#endif
if ((CHCR::MOD(vif1ch) == NORMAL_MODE) || vif1ch->qwc > 0) // Normal Mode
if ((vif1ch->chcr.MOD == NORMAL_MODE) || vif1ch->qwc > 0) // Normal Mode
{
if ((psHu32(DMAC_CTRL) & 0xC0) == 0x40)
Console::WriteLn("DMA Stall Control on VIF1 normal");
if ((CHCR::DIR(vif1ch))) // to Memory
if (vif1ch->chcr.DIR) // to Memory
vif1.dmamode = VIF_NORMAL_TO_MEM_MODE;
else
vif1.dmamode = VIF_NORMAL_FROM_MEM_MODE;
@ -2672,10 +2672,10 @@ void vif1Write32(u32 mem, u32 value)
{
vif1Regs->mskpath3 = 0;
psHu32(GIF_STAT) &= ~GIF_STAT_IMT;
if (CHCR::STR(gif)) CPU_INT(2, 4);
if (gif->chcr.STR) CPU_INT(2, 4);
}
vif1Regs->err = 0;
vif1Regs->err._u32 = 0;
vif1.inprogress = 0;
vif1Regs->stat &= ~(VIF1_STAT_FQC | VIF1_STAT_FDR | VIF1_STAT_INT | VIF1_STAT_VSS | VIF1_STAT_VIS | VIF1_STAT_VFS | VIF1_STAT_VPS); // FQC=0
}
@ -2731,7 +2731,7 @@ void vif1Write32(u32 mem, u32 value)
// Gets the timing right - Flatout
CPU_INT(1, vif1ch->qwc * BIAS);
}
CHCR::setSTR(vif1ch);
vif1ch->chcr.STR = 1;
}
}
}
@ -2741,7 +2741,7 @@ void vif1Write32(u32 mem, u32 value)
VIF_LOG("VIF1_ERR write32 0x%8.8x", value);
/* Set VIF1_ERR with 'value' */
vif1Regs->err = value;
vif1Regs->err._u32 = value;
break;
case VIF1_STAT: // STAT