changed how a few IOP counter things work, reverted one of my VIF changes and fixed another possible Unpack situation i hadnt accounted for.

Oh and the best news, SIF timing now exists, you know what that means? yes, Okami no longer needs a patch
This commit is contained in:
refractionpcsx2
2008-03-28 00:57:30 +00:00
parent 46d4e2be2c
commit aa5b2607b4
7 changed files with 116 additions and 68 deletions

View File

@@ -285,10 +285,13 @@ void _testRcnt16target(int i) {
psxCounters[i].target &= 0xffff;
//SysPrintf("IOP 16 Correcting target target %x\n", psxCounters[i].target);
}
psxCounters[i].mode|= 0x0800; // Target flag
if(psxCounters[i].mode & 0x80)
if (psxCounters[i].mode & 0x10)psxCounters[i].mode&= ~0x0400; // Interrupt flag
if (psxCounters[i].mode & 0x10){
if(psxCounters[i].mode & 0x80)psxCounters[i].mode&= ~0x0400; // Interrupt flag
psxCounters[i].mode|= 0x0800; // Target flag
}
if (psxCounters[i].mode & 0x10) { // Target interrupt
psxHu32(0x1070)|= psxCounters[i].interrupt;
@@ -311,11 +314,14 @@ void _testRcnt16overflow(int i) {
PSXCNT_LOG("[%d] overflow 0x%x >= 0x%x (Cycle); Rcount=0x%x, count=0x%x\n", i, (psxRegs.cycle - psxCounters[i].sCycle) / psxCounters[i].rate, psxCounters[i].Cycle, psxRcntRcount16(i), psxCounters[i].count);
#endif
psxCounters[i].mode|= 0x1000; // Overflow flag
if (psxCounters[i].mode & 0x0020) { // Overflow interrupt
psxHu32(0x1070)|= psxCounters[i].interrupt;
if(psxCounters[i].mode & 0x80)
psxCounters[i].mode|= 0x1000; // Overflow flag
if(psxCounters[i].mode & 0x80){
psxCounters[i].mode&= ~0x0400; // Interrupt flag
}
//SysPrintf("Overflow 16\n");
}
psxCounters[i].count -= 0x10000;
@@ -337,11 +343,14 @@ void _testRcnt32target(int i) {
psxCounters[i].target &= 0xffffffff;
}
psxCounters[i].mode|= 0x0800; // Target flag
// newtarget[i] = 0;
if(psxCounters[i].mode & 0x80)
if (psxCounters[i].mode & 0x10)psxCounters[i].mode&= ~0x0400; // Interrupt flag
if (psxCounters[i].mode & 0x10){
if(psxCounters[i].mode & 0x80)psxCounters[i].mode&= ~0x0400; // Interrupt flag
psxCounters[i].mode|= 0x0800; // Target flag
}
if (psxCounters[i].mode & 0x10) { // Target interrupt
@@ -366,11 +375,13 @@ void _testRcnt32overflow(int i) {
PSXCNT_LOG("[%d] overflow 0x%x >= 0x%x (Cycle); Rcount=0x%x, count=0x%x\n", i, (psxRegs.cycle - psxCounters[i].sCycle), psxCounters[i].Cycle, psxRcntRcount32(i), psxCounters[i].count);
#endif
//SysPrintf("Overflow 32\n");
psxCounters[i].mode|= 0x1000; // Overflow flag
if (psxCounters[i].mode & 0x0020) { // Overflow interrupt
psxHu32(0x1070)|= psxCounters[i].interrupt;
if(psxCounters[i].mode & 0x80)
psxCounters[i].mode|= 0x1000; // Overflow flag
if(psxCounters[i].mode & 0x80){
psxCounters[i].mode&= ~0x0400; // Interrupt flag
}
}
psxCounters[i].count -= 0x100000000;
if(psxCounters[i].target > 0xffffffff) {

View File

@@ -26,7 +26,7 @@
// Dma11/12 in PsxSio2.c
//static int spudmaenable[2];
int spu2interrupts[2];
int iopsifbusy[2] = { 0, 0 };
void psxDma4(u32 madr, u32 bcr, u32 chcr) { // SPU
int size;
@@ -163,7 +163,7 @@ int psxDma7Interrupt() {
return 1;
}
extern int eesifbusy[2];
void psxDma9(u32 madr, u32 bcr, u32 chcr) {
DMACh *dma = (DMACh*)&PS2MEM_HW[0xc000];
@@ -172,8 +172,9 @@ void psxDma9(u32 madr, u32 bcr, u32 chcr) {
SIF_LOG("IOP: dmaSIF0 chcr = %lx, madr = %lx, bcr = %lx, tadr = %lx\n", chcr, madr, bcr, HW_DMA9_TADR);
#endif
iopsifbusy[0] = 1;
psHu32(0x1000F240) |= 0x2000;
if (dma->chcr & 0x100 && HW_DMA9_CHCR & 0x01000000) {
if (eesifbusy[0] == 1 && iopsifbusy[0] == 1) {
SIF0Dma();
psHu32(0x1000F240) &= ~0x20;
psHu32(0x1000F240) &= ~0x2000;
@@ -187,8 +188,9 @@ void psxDma10(u32 madr, u32 bcr, u32 chcr) {
SIF_LOG("IOP: dmaSIF1 chcr = %lx, madr = %lx, bcr = %lx\n", chcr, madr, bcr);
#endif
iopsifbusy[1] = 1;
psHu32(0x1000F240) |= 0x4000;
if (dma->chcr & 0x100 && HW_DMA10_CHCR & 0x01000000) {
if (eesifbusy[1] == 1 && iopsifbusy[1] == 1) {
SIF1Dma();
psHu32(0x1000F240) &= ~0x40;
psHu32(0x1000F240) &= ~0x100;

View File

@@ -149,6 +149,8 @@ static void _psxTestInterrupts() {
/*PSX_TESTINT(4, psxDma4Interrupt);
PSX_TESTINT(7, psxDma7Interrupt);*/
PSX_TESTINT(9, sif0Interrupt); // SIF0
PSX_TESTINT(10, sif1Interrupt); // SIF1
PSX_TESTINT(11, psxDMA11Interrupt); // SIO2
PSX_TESTINT(12, psxDMA12Interrupt); // SIO2
PSX_TESTINT(16, sioInterrupt);

View File

@@ -347,8 +347,8 @@ void _cpuTestInterrupts() {
TESTINT(2, gsInterrupt);
TESTINT(3, ipu0Interrupt);
TESTINT(4, ipu1Interrupt);
/*TESTINT(5, EEsif0Interrupt);
TESTINT(6, EEsif1Interrupt);*/
TESTINT(5, EEsif0Interrupt);
TESTINT(6, EEsif1Interrupt);
TESTINT(8, SPRFROMinterrupt);
TESTINT(9, SPRTOinterrupt);

View File

@@ -30,6 +30,8 @@
#define FIFO_SIF0_W 128
#define FIFO_SIF1_W 128
int eesifbusy[2] = { 0, 0 };
extern int iopsifbusy[2];
typedef struct {
u32 fifoData[FIFO_SIF0_W];
int fifoReadPos;
@@ -169,7 +171,7 @@ void SIF0Dma()
{
u32 *ptag;
int notDone;
//int cycles = 0, psxCycles = 0;
int cycles = 0, psxCycles = 0;
FreezeMMXRegs(1);
#ifdef SIF_LOG
SIF_LOG("SIF0 DMA start...\n");
@@ -181,7 +183,7 @@ void SIF0Dma()
/*if ((psHu32(DMAC_CTRL) & 0xC0)) {
SysPrintf("DMA Stall Control %x\n",(psHu32(DMAC_CTRL) & 0xC0));
}*/
if(HW_DMA9_CHCR & 0x01000000) // If EE SIF0 is enabled
if(iopsifbusy[0] == 1) // If EE SIF0 is enabled
{
//int size = sif0.counter; //HW_DMA9_BCR >> 16;
@@ -195,8 +197,10 @@ void SIF0Dma()
#endif
// Stop & signal interrupts on IOP
HW_DMA9_CHCR &= ~0x01000000; //reset TR flag
psxDmaInterrupt2(2);
//HW_DMA9_CHCR &= ~0x01000000; //reset TR flag
//psxDmaInterrupt2(2);
iopsifbusy[0] = 0;
PSX_INT(9, psxCycles);
//hwIntcIrq(INTC_SBUS);
sif0.sifData.data = 0;
}
@@ -246,14 +250,14 @@ void SIF0Dma()
SIF0write((u32*)PSXM(HW_DMA9_MADR), wTransfer);
HW_DMA9_MADR += wTransfer << 2;
//HW_DMA9_BCR = (HW_DMA9_BCR & 0xFFFF) | (((HW_DMA9_BCR >> 16) - wTransfer)<<16);
//psxCycles += (wTransfer / 4) * BIAS;
psxCycles += (wTransfer / 4) * BIAS;
sif0.counter -= wTransfer;
notDone = 1;
}
}
if(sif0dma->chcr & 0x100) // If EE SIF enabled and there's something to transfer
if(eesifbusy[0] == 1) // If EE SIF enabled and there's something to transfer
{
int size = sif0dma->qwc;
if ((psHu32(DMAC_CTRL) & 0x30) == 0x10) { // STS == fromSIF0
@@ -282,7 +286,7 @@ void SIF0Dma()
Cpu->Clear(sif0dma->madr, readSize*4);
//cycles += readSize * BIAS;
cycles += readSize * BIAS;
sif0dma->qwc -= readSize;
sif0dma->madr += readSize << 4;
@@ -291,14 +295,16 @@ void SIF0Dma()
}
else
{
if(sif0.chain && sif0dma->chcr & 0x80000000) // Stop on tag IRQ
if((sif0dma->chcr & 0x80000080) == 0x80000080) // Stop on tag IRQ
{
// Tag interrupt
#ifdef SIF_LOG
SIF_LOG(" EE SIF interrupt\n");
#endif
sif0dma->chcr &= ~0x100;
hwDmacIrq(5);
//sif0dma->chcr &= ~0x100;
eesifbusy[0] = 0;
INT(5, cycles*BIAS);
//hwDmacIrq(5);
notDone = 0;
}
else if(sif0.end) // Stop on tag END
@@ -307,8 +313,10 @@ void SIF0Dma()
#ifdef SIF_LOG
SIF_LOG(" EE SIF end\n");
#endif
sif0dma->chcr &= ~0x100;
hwDmacIrq(5);
//sif0dma->chcr &= ~0x100;
//hwDmacIrq(5);
eesifbusy[0] = 0;
INT(5, cycles*BIAS);
notDone = 0;
}
else if(sif0.fifoSize >= 4) // Read a tag
@@ -321,6 +329,9 @@ void SIF0Dma()
sif0dma->madr = tag[1];
sif0dma->chcr = (sif0dma->chcr & 0xffff) | (tag[0] & 0xffff0000);
/*if ((sif0dma->chcr & 0x80) && (tag[0] >> 31)) {
SysPrintf("SIF0 TIE\n");
}*/
#ifdef SIF_LOG
SIF_LOG(" EE SIF dest chain tag madr:%08X qwc:%04X id:%X irq:%d(%08X_%08X)\n", sif0dma->madr, sif0dma->qwc, (tag[0]>>28)&3, (tag[0]>>31)&1, tag[1], tag[0]);
#endif
@@ -343,13 +354,13 @@ void SIF1Dma()
int id;
u32 *ptag;
int notDone;
//int cycles = 0, psxCycles = 0;
int cycles = 0, psxCycles = 0;
do
{
notDone = 0;
if(sif1dma->chcr & 0x100) // If EE SIF1 is enabled
if(eesifbusy[1] == 1) // If EE SIF1 is enabled
{
if ((psHu32(DMAC_CTRL) & 0xC0) == 0xC0) { // STS == fromSIF1
SysPrintf("SIF1 stall control\n");
@@ -360,8 +371,10 @@ void SIF1Dma()
if ((sif1dma->chcr & 0xc) == 0 || sif1.end) // If NORMAL mode or end of CHAIN then stop DMA
{
// Stop & signal interrupts on EE
sif1dma->chcr &= ~0x100;
hwDmacIrq(6);
//sif1dma->chcr &= ~0x100;
//hwDmacIrq(6);
eesifbusy[1] = 0;
INT(6, cycles*BIAS);
sif1.chain = 0;
sif1.end = 0;
}
@@ -377,7 +390,7 @@ void SIF1Dma()
SysPrintf("SIF1 TTE\n");
SIF1write(ptag+2, 2);
}
sif1.chain = 1;
id = (ptag[0] >> 28) & 0x7;
@@ -429,6 +442,10 @@ void SIF1Dma()
default:
SysPrintf("Bad addr1 source chain\n");
}
if ((sif1dma->chcr & 0x80) && (ptag[0] >> 31)) {
SysPrintf("SIF1 TIE\n");
sif1.end = 1;
}
}
}
else // There's some data ready to transfer into the fifo..
@@ -446,12 +463,12 @@ void SIF1Dma()
SIF1write(data, qwTransfer << 2);
sif1dma->madr += qwTransfer << 4;
//cycles += qwTransfer * BIAS;
cycles += qwTransfer * BIAS;
sif1dma->qwc -= qwTransfer;
}
}
if(HW_DMA10_CHCR & 0x01000000 ) // If IOP SIF enabled and there's something to transfer
if(iopsifbusy[1] == 1) // If IOP SIF enabled and there's something to transfer
{
int size = sif1.counter;
@@ -470,7 +487,7 @@ void SIF1Dma()
SIF1read((u32*)PSXM(HW_DMA10_MADR), readSize);
psxCpu->Clear(HW_DMA10_MADR, readSize);
//psxCycles += readSize / 4;
psxCycles += readSize / 4;
sif1.counter = size-readSize;
HW_DMA10_MADR += readSize << 2;
notDone = 1;
@@ -485,8 +502,10 @@ void SIF1Dma()
#ifdef SIF_LOG
SIF_LOG(" IOP SIF interrupt\n");
#endif
HW_DMA10_CHCR &= ~0x01000000; //reset TR flag
psxDmaInterrupt2(3);
//HW_DMA10_CHCR &= ~0x01000000; //reset TR flag
//psxDmaInterrupt2(3);
iopsifbusy[1] = 0;
PSX_INT(10, psxCycles);
//hwIntcIrq(INTC_SBUS);
sif1.tagMode = 0;
notDone = 0;
@@ -497,8 +516,10 @@ void SIF1Dma()
#ifdef SIF_LOG
SIF_LOG(" IOP SIF end\n");
#endif
HW_DMA10_CHCR &= ~0x01000000; //reset TR flag
psxDmaInterrupt2(3);
//HW_DMA10_CHCR &= ~0x01000000; //reset TR flag
//psxDmaInterrupt2(3);
iopsifbusy[1] = 0;
PSX_INT(10, psxCycles);
//hwIntcIrq(INTC_SBUS);
sif1.tagMode = 0;
notDone = 0;
@@ -523,18 +544,20 @@ void SIF1Dma()
}
int sif0Interrupt() {
void sif0Interrupt() {
/*if (psxHu32(0x1070) & 8) {
PSX_INT(9, 0x800);
return 0;
}*/
HW_DMA9_CHCR &= ~0x01000000;
psxDmaInterrupt2(2);
//hwIntcIrq(INTC_SBUS);
return 1;
psxRegs.interrupt&= ~(1 << 9);
//return 1;
}
int sif1Interrupt() {
void sif1Interrupt() {
/*if (psxHu32(0x1070) & 8) {
PSX_INT(10, 0x800);
return 0;
@@ -543,28 +566,32 @@ int sif1Interrupt() {
HW_DMA10_CHCR &= ~0x01000000; //reset TR flag
psxDmaInterrupt2(3);
//hwIntcIrq(INTC_SBUS);
return 1;
psxRegs.interrupt&= ~(1 << 10);
//return 1;
}
int EEsif0Interrupt() {
void EEsif0Interrupt() {
/*if (psHu32(DMAC_STAT) & (1<<5)) {
INT(5, 0x800);
return 0;
}*/
sif0dma->chcr &= ~0x100;
hwDmacIrq(5);
cpuRegs.interrupt &= ~(1 << 5);
return 1;
//return 1;
}
int EEsif1Interrupt() {
void EEsif1Interrupt() {
/*if (psHu32(DMAC_STAT) & (1<<6)) {
INT(6, 0x800);
return 0;
}*/
hwDmacIrq(6);
sif1dma->chcr &= ~0x100;
cpuRegs.interrupt &= ~(1 << 6);
return 1;
// return 1;
}
void dmaSIF0() {
@@ -583,7 +610,8 @@ void dmaSIF0() {
// }
psHu32(0x1000F240) |= 0x2000;
if(sif0dma->chcr & 0x100 && HW_DMA9_CHCR & 0x01000000) {
eesifbusy[0] = 1;
if(eesifbusy[0] == 1 && iopsifbusy[0] == 1) {
hwIntcIrq(INTC_SBUS);
SIF0Dma();
psHu32(0x1000F240) &= ~0x20;
@@ -608,7 +636,8 @@ void dmaSIF1() {
// }
FreezeMMXRegs(1);
psHu32(0x1000F240) |= 0x4000;
if(sif1dma->chcr & 0x100 && HW_DMA10_CHCR & 0x01000000) {
eesifbusy[1] = 1;
if(eesifbusy[1] == 1 && iopsifbusy[1] == 1) {
SIF1Dma();
psHu32(0x1000F240) &= ~0x40;
psHu32(0x1000F240) &= ~0x100;

View File

@@ -40,8 +40,10 @@ void SIF1Dma();
void dmaSIF0();
void dmaSIF1();
void dmaSIF2();
int EEsif1Interrupt();
int EEsif0Interrupt();
void sif1Interrupt();
void sif0Interrupt();
void EEsif1Interrupt();
void EEsif0Interrupt();
int EEsif2Interrupt();
int sifFreeze(gzFile f, int Mode);

View File

@@ -469,7 +469,10 @@ static void VIFunpack(u32 *data, vifCode *v, int size, const unsigned int VIFdma
if (v->size != (size>>2))ProcessMemSkip(size, unpackType, VIFdmanum);
if(vifRegs->offset < (u32)ft->qsize){
unpacksize = (ft->qsize - vifRegs->offset);
if((size/ft->dsize) < (ft->qsize - vifRegs->offset)){
SysPrintf("wasnt enough left size/dsize = %x left to write %x\n", (size/ft->dsize), (ft->qsize - vifRegs->offset));
}
unpacksize = min((size/ft->dsize), (ft->qsize - vifRegs->offset));
} else {
unpacksize = 0;
SysPrintf("Unpack align offset = 0\n");
@@ -500,7 +503,6 @@ static void VIFunpack(u32 *data, vifCode *v, int size, const unsigned int VIFdma
SysPrintf("aligning packet done size = %d offset %d addr %x\n", size, vifRegs->offset, vif->tag.addr);
#endif
//}
//skipmeminc += (((vifRegs->cycle.cl - vifRegs->cycle.wl)<<2)*4) * skipped;
} else if (v->size != (size>>2))ProcessMemSkip(size, unpackType, VIFdmanum);
@@ -1082,9 +1084,6 @@ int VIF0transfer(u32 *data, int size, int istag) {
vif0.vifstalled = 0;
vif0.vifpacketsize = size;
if ((vif0ch->chcr & 0x40) == 0 && istag == 1 && vif0.tag.size > 0) {
return 0;
}
while (vif0.vifpacketsize > 0) {
@@ -1226,7 +1225,7 @@ int _chainVIF0() {
vif0ch->chcr = ( vif0ch->chcr & 0xFFFF ) | ( (*ptag) & 0xFFFF0000 ); //Transfer upper part of tag to CHCR bits 31-15
// Transfer dma tag if tte is set
//if (vif0ch->chcr & 0x40) {
if (vif0ch->chcr & 0x40) {
if(vif0.vifstalled == 1) ret = VIF0transfer(ptag+(2+vif0.irqoffset), 2-vif0.irqoffset, 1); //Transfer Tag on stall
else ret = VIF0transfer(ptag+2, 2, 1); //Transfer Tag
if (ret == -1) return -1; //There has been an error
@@ -1235,7 +1234,7 @@ int _chainVIF0() {
//vif0.vifstalled = 1;
return vif0.done; //IRQ set by VIFTransfer
}
//}
}
vif0.done |= hwDmacSrcChainWithStack(vif0ch, id);
@@ -1823,6 +1822,7 @@ static void Vif1CMDSTMod(){ // STMOD
}
static void Vif1CMDMskPath3(){ // MSKPATH3
int qwc;
vif1Regs->mskpath3 = (vif1Regs->code >> 15) & 0x1;
//SysPrintf("VIF MSKPATH3 %x\n", vif1Regs->mskpath3);
#ifdef GSPATH3FIX
@@ -1830,13 +1830,15 @@ static void Vif1CMDMskPath3(){ // MSKPATH3
if ( (vif1Regs->code >> 15) & 0x1 ) {
while((gif->chcr & 0x100)){ //Can be done 2 different ways, depends on the game/company
if(path3hack == 0)if(Path3transfer == 0 && gif->qwc == 0) break;
qwc = gif->qwc;
gsInterrupt();
g_vifCycles += qwc - gif->qwc;
if(path3hack == 1)if(gif->qwc == 0) break; //add games not working with it to elfheader.c to enable this instead
}
//while(gif->chcr & 0x100) gsInterrupt(); // Finish the transfer first
psHu32(GIF_STAT) |= 0x2;
} else {
if(gif->chcr & 0x100) INT(2, ((transferred>>2)*BIAS)); // Restart Path3 on its own, time it right!
if(gif->chcr & 0x100) INT(2, g_vifCycles * BIAS); // Restart Path3 on its own, time it right!
psHu32(GIF_STAT) &= ~0x2;
}
#else
@@ -1857,15 +1859,18 @@ static void Vif1CMDMark(){ // MARK
vif1.cmd &= ~0x7f;
}
static void Vif1CMDFlush(){ // FLUSH/E/A
int qwc;
vif1FLUSH();
if((vif1.cmd & 0x7f) == 0x13) {
//SysPrintf("FlushA\n");
while((gif->chcr & 0x100)){
if(Path3transfer == 0 && gif->qwc == 0) break;
gsInterrupt();
qwc = gif->qwc;
gsInterrupt();
g_vifCycles += qwc - gif->qwc;
}
}
vif1FLUSH();
vif1.cmd &= ~0x7f;
}
static void Vif1CMDMSCALF(){ //MSCAL/F
@@ -1968,9 +1973,6 @@ int VIF1transfer(u32 *data, int size, int istag) {
#endif
if ((vif1ch->chcr & 0x40) == 0 && istag == 1 && vif1.cmd) {
return 0;
}
vif1.irqoffset = 0;
vif1.vifstalled = 0;
vif1.stallontag = 0;
@@ -2162,7 +2164,7 @@ int _chainVIF1() {
}
//prevvifcycles = 0;
//if (vif1ch->chcr & 0x40) {
if (vif1ch->chcr & 0x40) {
if(vif1.vifstalled == 1) ret = VIF1transfer(vifptag+(2+vif1.irqoffset), 2-vif1.irqoffset, 1); //Transfer Tag on stall
else ret = VIF1transfer(vifptag+2, 2, 1); //Transfer Tag
if (ret == -1) return -1; //There has been an error
@@ -2170,7 +2172,7 @@ int _chainVIF1() {
//if(vif1.tag.size > 0)SysPrintf("VIF1 Stall on tag %x code %x\n", vif1.irqoffset, vif1Regs->code);
return 0; //IRQ set by VIFTransfer
}
//}
}
//if((psHu32(DMAC_CTRL) & 0xC0) != 0x40 || id != 4)
vif1.done |= hwDmacSrcChainWithStack(vif1ch, id);