mirror of https://github.com/PCSX2/pcsx2.git
Tags.h meets SPR.cpp. Plus some more work on Tags.h and Misc...
git-svn-id: http://pcsx2.googlecode.com/svn/trunk@1653 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
parent
0587cdc210
commit
490d996abc
31
pcsx2/Hw.cpp
31
pcsx2/Hw.cpp
|
@ -177,35 +177,50 @@ bool hwDmacSrcChainWithStack(DMACh *dma, int id) {
|
|||
|
||||
dma->madr = dma->tadr + 16; //Set MADR to data following the tag
|
||||
|
||||
if ((dma->chcr & 0x30) == 0x0) { //Check if ASR0 is empty
|
||||
switch(CHCR::ASP(dma))
|
||||
{
|
||||
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
|
||||
break;
|
||||
}
|
||||
else if((dma->chcr & 0x30) == 0x10){
|
||||
case 1: {
|
||||
dma->chcr = (dma->chcr & 0xffffffcf) | 0x20; //2 Addresses in call stack
|
||||
dma->asr1 = dma->madr + (dma->qwc << 4); //If no store Succeeding tag in ASR1
|
||||
}else {
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
Console::Notice("Call Stack Overflow (report if it fixes/breaks anything)");
|
||||
return true; //Return done
|
||||
}
|
||||
}
|
||||
dma->tadr = temp; //Set TADR to temporarily stored ADDR
|
||||
|
||||
return false;
|
||||
}
|
||||
case TAG_RET: // Ret - Transfer QWC following the tag, load next tag
|
||||
dma->madr = dma->tadr + 16; //Set MADR to data following the tag
|
||||
|
||||
if ((dma->chcr & 0x30) == 0x20) { //If ASR1 is NOT equal to 0 (Contains address)
|
||||
switch(CHCR::ASP(dma))
|
||||
{
|
||||
case 2: { //If ASR1 is NOT equal to 0 (Contains address)
|
||||
dma->chcr = (dma->chcr & 0xffffffcf) | 0x10; //1 Address left in call stack
|
||||
dma->tadr = dma->asr1; //Read ASR1 as next tag
|
||||
dma->asr1 = 0; //Clear ASR1
|
||||
break;
|
||||
}
|
||||
else { //If ASR1 is empty (No address held)
|
||||
if((dma->chcr & 0x30) == 0x10) { //Check if ASR0 is NOT equal to 0 (Contains address)
|
||||
//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->tadr = dma->asr0; //Read ASR0 as next tag
|
||||
dma->asr0 = 0; //Clear ASR0
|
||||
} else { //Else if ASR1 and ASR0 are empty
|
||||
break;
|
||||
}
|
||||
case 0: { //Else if ASR1 and ASR0 are empty
|
||||
//dma->tadr += 16; //Clear tag address - Kills Klonoa 2
|
||||
return true; //End Transfer
|
||||
}
|
||||
default: { //Else if ASR1 and ASR0 are messed up
|
||||
//Console::Error("TAG_RET: ASR 1 & 0 == 1. This shouldn't happen!");
|
||||
//dma->tadr += 16; //Clear tag address - Kills Klonoa 2
|
||||
return true; //End Transfer
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include "SPR.h"
|
||||
#include "iR5900.h"
|
||||
#include "VUmicro.h"
|
||||
#include "Tags.h"
|
||||
|
||||
extern void mfifoGIFtransfer(int);
|
||||
|
||||
|
@ -139,13 +140,15 @@ static __forceinline void _dmaSPR0()
|
|||
}
|
||||
|
||||
// Transfer Dn_QWC from SPR to Dn_MADR
|
||||
if ((spr0->chcr & 0xc) == 0x0) // Normal Mode
|
||||
switch(CHCR::MOD(spr0))
|
||||
{
|
||||
case NORMAL_MODE:
|
||||
{
|
||||
SPR0chain();
|
||||
spr0finished = 1;
|
||||
return;
|
||||
}
|
||||
else if ((spr0->chcr & 0xc) == 0x4)
|
||||
case CHAIN_MODE:
|
||||
{
|
||||
u32 *ptag;
|
||||
int id;
|
||||
|
@ -161,11 +164,9 @@ static __forceinline void _dmaSPR0()
|
|||
ptag = (u32*) & PS2MEM_SCRATCH[spr0->sadr & 0x3fff];
|
||||
spr0->sadr += 16;
|
||||
|
||||
// Transfer dma tag if tte is set
|
||||
spr0->chcr = (spr0->chcr & 0xFFFF) | ((*ptag) & 0xFFFF0000); //Transfer upper part of tag to CHCR bits 31-15
|
||||
Tag::UnsafeTransfer(spr0, ptag);
|
||||
id = Tag::Id(ptag);
|
||||
|
||||
id = (ptag[0] >> 28) & 0x7; //ID for DmaChain copied from bit 28 of the tag
|
||||
spr0->qwc = (u16)ptag[0]; //QWC set to lower 16bits of the tag
|
||||
spr0->madr = ptag[1]; //MADR = ADDR field
|
||||
|
||||
SPR_LOG("spr0 dmaChain %8.8x_%8.8x size=%d, id=%d, addr=%lx spr=%lx",
|
||||
|
@ -178,20 +179,20 @@ static __forceinline void _dmaSPR0()
|
|||
|
||||
switch (id)
|
||||
{
|
||||
case 0: // CNTS - Transfer QWC following the tag (Stall Control)
|
||||
case TAG_CNTS: // CNTS - Transfer QWC following the tag (Stall Control)
|
||||
if ((psHu32(DMAC_CTRL) & 0x30) == 0x20) psHu32(DMAC_STADR) = spr0->madr + (spr0->qwc * 16); //Copy MADR to DMAC_STADR stall addr register
|
||||
break;
|
||||
|
||||
case 1: // CNT - Transfer QWC following the tag.
|
||||
case TAG_CNT: // CNT - Transfer QWC following the tag.
|
||||
done = FALSE;
|
||||
break;
|
||||
|
||||
case 7: // End - Transfer QWC following the tag
|
||||
case TAG_END: // End - Transfer QWC following the tag
|
||||
done = TRUE;
|
||||
break;
|
||||
}
|
||||
SPR0chain();
|
||||
if (spr0->chcr & 0x80 && ptag[0] >> 31) //Check TIE bit of CHCR and IRQ bit of tag
|
||||
if (CHCR::TIE(spr0) && Tag::IRQ(ptag)) //Check TIE bit of CHCR and IRQ bit of tag
|
||||
{
|
||||
//Console::WriteLn("SPR0 TIE");
|
||||
done = TRUE;
|
||||
|
@ -207,10 +208,14 @@ static __forceinline void _dmaSPR0()
|
|||
}
|
||||
SPR_LOG("spr0 dmaChain complete %8.8x_%8.8x size=%d, id=%d, addr=%lx spr=%lx",
|
||||
ptag[1], ptag[0], spr0->qwc, id, spr0->madr);
|
||||
break;
|
||||
}
|
||||
else // Interleave Mode
|
||||
//case INTERLEAVE_MODE:
|
||||
default:
|
||||
{
|
||||
_SPR0interleave();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -227,7 +232,7 @@ void SPRFROMinterrupt()
|
|||
//Console::WriteLn("mfifoGIFtransfer %x madr %x, tadr %x", params gif->chcr, gif->madr, gif->tadr);
|
||||
mfifoGIFtransfer(mfifotransferred);
|
||||
mfifotransferred = 0;
|
||||
if(gif->chcr & 0x100)return;
|
||||
if (CHCR::STR(gif)) return;
|
||||
}
|
||||
else if ((psHu32(DMAC_CTRL) & 0xC) == 0x8) // VIF1 MFIFO
|
||||
{
|
||||
|
@ -236,11 +241,11 @@ void SPRFROMinterrupt()
|
|||
//Console::WriteLn("mfifoVIF1transfer %x madr %x, tadr %x", params vif1ch->chcr, vif1ch->madr, vif1ch->tadr);
|
||||
mfifoVIF1transfer(mfifotransferred);
|
||||
mfifotransferred = 0;
|
||||
if(vif1ch->chcr & 0x100)return;
|
||||
if (CHCR::STR(vif1ch)) return;
|
||||
}
|
||||
}
|
||||
if (spr0finished == 0) return;
|
||||
spr0->chcr &= ~0x100;
|
||||
CHCR::clearSTR(spr0);
|
||||
hwDmacIrq(DMAC_FROM_SPR);
|
||||
}
|
||||
|
||||
|
@ -250,7 +255,7 @@ void dmaSPR0() // fromSPR
|
|||
SPR_LOG("dmaSPR0 chcr = %lx, madr = %lx, qwc = %lx, sadr = %lx",
|
||||
spr0->chcr, spr0->madr, spr0->qwc, spr0->sadr);
|
||||
|
||||
if ((spr0->chcr & 0xc) == 0x4 && spr0->qwc == 0)
|
||||
if ((CHCR::MOD(spr0) == CHAIN_MODE) && spr0->qwc == 0)
|
||||
{
|
||||
u32 *ptag;
|
||||
ptag = (u32*) & PS2MEM_SCRATCH[spr0->sadr & 0x3fff]; //Set memory pointer to SADR
|
||||
|
@ -319,7 +324,9 @@ void _SPR1interleave()
|
|||
|
||||
void _dmaSPR1() // toSPR work function
|
||||
{
|
||||
if ((spr1->chcr & 0xc) == 0) // Normal Mode
|
||||
switch(CHCR::MOD(spr1))
|
||||
{
|
||||
case NORMAL_MODE:
|
||||
{
|
||||
//int cycles = 0;
|
||||
// Transfer Dn_QWC from Dn_MADR to SPR1
|
||||
|
@ -327,7 +334,7 @@ void _dmaSPR1() // toSPR work function
|
|||
spr1finished = 1;
|
||||
return;
|
||||
}
|
||||
else if ((spr1->chcr & 0xc) == 0x4)
|
||||
case CHAIN_MODE:
|
||||
{
|
||||
u32 *ptag;
|
||||
int id;
|
||||
|
@ -343,23 +350,18 @@ void _dmaSPR1() // toSPR work function
|
|||
// Chain Mode
|
||||
|
||||
ptag = (u32*)dmaGetAddr(spr1->tadr); //Set memory pointer to TADR
|
||||
if (ptag == NULL) //Is ptag empty?
|
||||
|
||||
if (!(Tag::Transfer("SPR1 Tag", spr1, ptag)))
|
||||
{
|
||||
Console::WriteLn("SPR1 Tag BUSERR");
|
||||
spr1->chcr = (spr1->chcr & 0xFFFF) | ((*ptag) & 0xFFFF0000); //Transfer upper part of tag to CHCR bits 31-15
|
||||
psHu32(DMAC_STAT) |= DMAC_STAT_BEIS; //If yes, set BEIS (BUSERR) in DMAC_STAT register
|
||||
done = TRUE;
|
||||
spr1finished = (done) ? 1: 0;
|
||||
return;
|
||||
}
|
||||
spr1->chcr = (spr1->chcr & 0xFFFF) | ((*ptag) & 0xFFFF0000); //Transfer upper part of tag to CHCR bits 31-15
|
||||
|
||||
id = (ptag[0] >> 28) & 0x7; //ID for DmaChain copied from bit 28 of the tag
|
||||
spr1->qwc = (u16)ptag[0]; //QWC set to lower 16bits of the tag until SPR1chain is called in a few lines.
|
||||
id = Tag::Id(ptag);
|
||||
spr1->madr = ptag[1]; //MADR = ADDR field
|
||||
|
||||
// Transfer dma tag if tte is set
|
||||
if (spr1->chcr & 0x40)
|
||||
if (CHCR::TTE(spr1))
|
||||
{
|
||||
SPR_LOG("SPR TTE: %x_%x\n", ptag[3], ptag[2]);
|
||||
SPR1transfer(ptag, 4); //Transfer Tag
|
||||
|
@ -371,7 +373,7 @@ void _dmaSPR1() // toSPR work function
|
|||
done = (hwDmacSrcChain(spr1, id) == 1);
|
||||
SPR1chain(); //Transfers the data set by the switch
|
||||
|
||||
if (spr1->chcr & 0x80 && ptag[0] >> 31) //Check TIE bit of CHCR and IRQ bit of tag
|
||||
if (CHCR::TIE(spr1) && Tag::IRQ(ptag)) //Check TIE bit of CHCR and IRQ bit of tag
|
||||
{
|
||||
SPR_LOG("dmaIrq Set");
|
||||
|
||||
|
@ -385,10 +387,14 @@ void _dmaSPR1() // toSPR work function
|
|||
ptag = (u32*)dmaGetAddr(spr1->tadr); //Set memory pointer to TADR
|
||||
CPU_INT(9, (((u16)ptag[0]) / BIAS));// the lower 16 bits of the tag / BIAS);
|
||||
}
|
||||
break;
|
||||
}
|
||||
else // Interleave Mode
|
||||
//case INTERLEAVE_MODE:
|
||||
default:
|
||||
{
|
||||
_SPR1interleave();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -400,7 +406,7 @@ void dmaSPR1() // toSPR
|
|||
spr1->chcr, spr1->madr, spr1->qwc,
|
||||
spr1->tadr, spr1->sadr);
|
||||
|
||||
if (((spr1->chcr & 0xc) == 0x4) && (spr1->qwc == 0))
|
||||
if ((CHCR::MOD(spr1) == CHAIN_MODE) && (spr1->qwc == 0))
|
||||
{
|
||||
u32 *ptag;
|
||||
ptag = (u32*)dmaGetAddr(spr1->tadr); //Set memory pointer to TADR
|
||||
|
@ -417,7 +423,7 @@ void SPRTOinterrupt()
|
|||
{
|
||||
_dmaSPR1();
|
||||
if (spr1finished == 0) return;
|
||||
spr1->chcr &= ~0x100;
|
||||
CHCR::clearSTR(spr1);
|
||||
hwDmacIrq(DMAC_TO_SPR);
|
||||
}
|
||||
|
||||
|
|
62
pcsx2/Tags.h
62
pcsx2/Tags.h
|
@ -22,6 +22,42 @@
|
|||
|
||||
// Actually, looks like I didn't need templates after all... :)
|
||||
|
||||
enum mfd_type
|
||||
{
|
||||
NO_MFD,
|
||||
MFD_RESERVED,
|
||||
MFD_VIF1,
|
||||
MFD_GIF
|
||||
};
|
||||
|
||||
enum sts_type
|
||||
{
|
||||
NO_STS,
|
||||
STS_SIF0,
|
||||
STS_fromSPR,
|
||||
STS_fromIPU
|
||||
};
|
||||
|
||||
enum std_type
|
||||
{
|
||||
NO_STD,
|
||||
STD_VIF1,
|
||||
STD_GIF,
|
||||
STD_SIF1
|
||||
};
|
||||
|
||||
enum d_ctrl_flags
|
||||
{
|
||||
CTRL_DMAE = 0x1, // 0/1 - disables/enables all DMAs
|
||||
CTRL_RELE = 0x2, // 0/1 - cycle stealing off/on
|
||||
CTRL_MFD = 0xC, // Memory FIFO drain channel (mfd_type)
|
||||
CTRL_STS = 0x30, // Stall Control source channel (sts type)
|
||||
CTRL_STD = 0xC0, // Stall Controll drain channel (std_type)
|
||||
CTRL_RCYC = 0x100 // Release cycle (8/16/32/64/128/256)
|
||||
// When cycle stealing is on, the release cycle sets the period to release
|
||||
// the bus to EE.
|
||||
};
|
||||
|
||||
enum pce_values
|
||||
{
|
||||
PCE_NOTHING = 0,
|
||||
|
@ -32,6 +68,7 @@ enum pce_values
|
|||
|
||||
enum tag_id
|
||||
{
|
||||
TAG_CNTS = 0,
|
||||
TAG_REFE = 0, // Transfer Packet According to ADDR field, clear STR, and end
|
||||
TAG_CNT, // Transfer QWC following the tag.
|
||||
TAG_NEXT, // Transfer QWC following tag. TADR = ADDR
|
||||
|
@ -171,7 +208,8 @@ namespace CHCR
|
|||
|
||||
static __forceinline u8 ASP(DMACh *tag)
|
||||
{
|
||||
return (TransferMode)((tag->chcr & CHCR_ASP) >> 2);
|
||||
|
||||
return (TransferMode)((tag->chcr & CHCR_ASP) >> 4);
|
||||
}
|
||||
|
||||
// Clear the individual flags.
|
||||
|
@ -250,3 +288,25 @@ namespace QWC
|
|||
tag->qwc = 0;
|
||||
}
|
||||
}
|
||||
|
||||
namespace D_CTRL
|
||||
{
|
||||
static __forceinline bool DMAE() { return !!(psHu32(DMAC_CTRL) & CTRL_DMAE); }
|
||||
static __forceinline bool RELE() { return !!(psHu32(DMAC_CTRL) & CTRL_RELE); }
|
||||
static __forceinline bool MFD()
|
||||
{
|
||||
return (mfd_type)((psHu32(DMAC_CTRL) & CTRL_MFD) >> 2);
|
||||
}
|
||||
static __forceinline bool STS()
|
||||
{
|
||||
return (sts_type)((psHu32(DMAC_CTRL) & CTRL_STS) >> 2);
|
||||
}
|
||||
static __forceinline bool STD()
|
||||
{
|
||||
return (std_type)((psHu32(DMAC_CTRL) & CTRL_STD) >> 2);
|
||||
}
|
||||
static __forceinline bool RCLC()
|
||||
{
|
||||
return ((((psHu32(DMAC_CTRL) & CTRL_RCYC) >> 3) + 1) * 8);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1426,7 +1426,7 @@ void vif0Interrupt()
|
|||
if (vif0Regs->stat & (VIF0_STAT_VSS | VIF0_STAT_VIS | VIF0_STAT_VFS))
|
||||
{
|
||||
vif0Regs->stat &= ~0xF000000; // FQC=0
|
||||
vif0ch->chcr &= ~0x100;
|
||||
CHCR::clearSTR(vif0ch);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1608,7 +1608,7 @@ void vif0Write32(u32 mem, u32 value)
|
|||
else
|
||||
_VIF0chain();
|
||||
|
||||
vif0ch->chcr |= 0x100;
|
||||
CHCR::setSTR(vif0ch);
|
||||
CPU_INT(0, g_vifCycles); // Gets the timing right - Flatout
|
||||
}
|
||||
}
|
||||
|
@ -2535,7 +2535,7 @@ __forceinline void vif1Interrupt()
|
|||
vif1Regs->stat &= ~0x1F000000; // FQC=0
|
||||
|
||||
// One game doesnt like vif stalling at end, cant remember what. Spiderman isnt keen on it tho
|
||||
vif1ch->chcr &= ~0x100;
|
||||
CHCR::clearSTR(vif1ch);
|
||||
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;
|
||||
vif1ch->chcr &= ~0x100;
|
||||
CHCR::clearSTR(vif1ch);
|
||||
g_vifCycles = 0;
|
||||
hwDmacIrq(DMAC_VIF1);
|
||||
|
||||
|
|
Loading…
Reference in New Issue