diff --git a/pcsx2/CDVD.cpp b/pcsx2/CDVD.cpp index 1034734b61..6cf94718a2 100644 --- a/pcsx2/CDVD.cpp +++ b/pcsx2/CDVD.cpp @@ -206,7 +206,7 @@ static void CDVD_INT(int eCycle) static void cdvdSetIrq( uint id = (1< 0 ) { gsPostVsyncEnd( false ); diff --git a/pcsx2/Hw.cpp b/pcsx2/Hw.cpp index 90d513cbcc..7b424a3031 100644 --- a/pcsx2/Hw.cpp +++ b/pcsx2/Hw.cpp @@ -932,8 +932,7 @@ void hwWrite32(u32 mem, u32 value) { psHu16(0xe010)&= ~(value & 0xffff); // clear on 1 psHu16(0xe012) ^= (u16)(value >> 16); - if ((cpuRegs.CP0.n.Status.val & 0x10807) == 0x10801) - cpuTestDMACInts(); + cpuTestDMACInts(); break; //------------------------------------------------------------------ case 0x1000f000: // INTC_STAT @@ -945,7 +944,6 @@ void hwWrite32(u32 mem, u32 value) { case 0x1000f010: // INTC_MASK HW_LOG("INTC_MASK Write 32bit %x\n", value); psHu32(0xf010) ^= (u16)value; - cpuTestINTCInts(); break; //------------------------------------------------------------------ @@ -984,22 +982,18 @@ void hwWrite32(u32 mem, u32 value) { //------------------------------------------------------------------ case 0x1000f130: case 0x1000f410: -#ifdef PCSX2_DEVBUILD - HW_LOG("Unknown Hardware write 32 at %x with value %x (%x)\n", mem, value, cpuRegs.CP0.n.Status); -#endif + HW_LOG("Unknown Hardware write 32 at %x with value %x (%x)\n", mem, value, cpuRegs.CP0.n.Status.val); break; //------------------------------------------------------------------ default: #ifndef PCSX2_VIRTUAL_MEM - if (mem < 0x10010000) + if (mem < 0x10010000) #endif - { - psHu32(mem) = value; - } -#ifdef PCSX2_DEVBUILD - HW_LOG("Unknown Hardware write 32 at %x with value %x (%x)\n", mem, value, cpuRegs.CP0.n.Status); -#endif - break; + { + psHu32(mem) = value; + } + HW_LOG("Unknown Hardware write 32 at %x with value %x (%x)\n", mem, value, cpuRegs.CP0.n.Status.val); + break; } } @@ -1021,9 +1015,7 @@ void hwWrite64(u32 mem, u64 value) { switch (mem) { case GIF_CTRL: -#ifdef PCSX2_DEVBUILD - SysPrintf("GIF_CTRL write 64\n", value); -#endif + DevCon::Status("GIF_CTRL write 64", value); psHu32(mem) = value & 0x8; if(value & 0x1) { gsGIFReset(); @@ -1038,7 +1030,7 @@ void hwWrite64(u32 mem, u64 value) { case GIF_MODE: #ifdef GSPATH3FIX - SysPrintf("GIFMODE64 %x\n", value); + Console::Status("GIFMODE64 %x\n", value); #endif psHu64(GIF_MODE) = value; if (value & 0x1) psHu32(GIF_STAT)|= 0x1; @@ -1055,12 +1047,10 @@ void hwWrite64(u32 mem, u64 value) { DmaExec(dmaGIF, mem, value); break; -#ifdef HW_LOG case 0x1000e000: // DMAC_CTRL HW_LOG("DMAC_CTRL Write 64bit %x\n", value); psHu64(mem) = value; break; -#endif case 0x1000e010: // DMAC_STAT HW_LOG("DMAC_STAT Write 64bit %x\n", value); @@ -1073,8 +1063,7 @@ void hwWrite64(u32 mem, u64 value) { else psHu16(0xe012)|= 1<>16)&0x1f)].UL[0]); else if( IS_PSXCONSTREG(mmreg) ) AND16ItoM(mem, g_psxConstRegs[((mmreg>>16)&0x1f)]); else AND16RtoM(mem, mmreg); break; - case 1: // and + case 1: // OR operation if( IS_EECONSTREG(mmreg) ) OR16ItoM(mem, g_cpuConstRegs[((mmreg>>16)&0x1f)].UL[0]); else if( IS_PSXCONSTREG(mmreg) ) OR16ItoM(mem, g_psxConstRegs[((mmreg>>16)&0x1f)]); else OR16RtoM(mem, mmreg); break; - default: assert(0); + + jNO_DEFAULT } } @@ -2595,7 +2597,12 @@ static u8* m_psAllMem = NULL; int memInit() { #ifdef __LINUX__ - InstallLinuxExceptionHandler(); + struct sigaction sa; + + sigemptyset(&sa.sa_mask); + sa.sa_flags = SA_SIGINFO; + sa.sa_sigaction = &SysPageFaultExceptionFilter; + sigaction(SIGSEGV, &sa, NULL); #endif if (!vtlb_Init()) return -1; @@ -2923,29 +2930,14 @@ int SysPageFaultExceptionFilter(EXCEPTION_POINTERS* eps) } #else -#include "errno.h" - -__forceinline void __fastcall InstallLinuxExceptionHandler() -{ - struct sigaction sa; - - sigemptyset(&sa.sa_mask); - sa.sa_flags = SA_SIGINFO; - sa.sa_sigaction = &SysPageFaultExceptionFilter; - sigaction(SIGSEGV, &sa, NULL); -} // Linux implementation of SIGSEGV handler. Bind it using sigaction(). // This is my shot in the dark. Probably needs some work. Good luck! (air) __forceinline void __fastcall SysPageFaultExceptionFilter( int signal, siginfo_t *info, void * ) { - int err; - u32 pagesize = getpagesize(); - - //DevCon::Error("SysPageFaultExceptionFilter!"); + //Console::Error("SysPageFaultExceptionFilter!"); // get bad virtual address u32 offset = (u8*)info->si_addr - psM; - uptr pageoffset = ( offset / pagesize ) * pagesize; if (offset>=Ps2MemSize::Base) { @@ -2954,9 +2946,8 @@ __forceinline void __fastcall SysPageFaultExceptionFilter( int signal, siginfo_t assert( false ); } - err = mprotect( &psM[pageoffset], pagesize, PROT_READ | PROT_WRITE ); - if (err) DevCon::Error("SysPageFaultExceptionFilter: %s", strerror(errno)); - + mprotect(&psM[offset], 1, PROT_READ|PROT_WRITE); + offset>>=12; psMPWC[(offset/32)]|=(1<<(offset&31)); diff --git a/pcsx2/PsxCounters.cpp b/pcsx2/PsxCounters.cpp index fe734830a8..469b7a67cf 100644 --- a/pcsx2/PsxCounters.cpp +++ b/pcsx2/PsxCounters.cpp @@ -16,6 +16,10 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ +// Note on INTC usage: All counters code is always called from inside the context of an +// event test, so instead of using the iopTestIntc we just set the 0x1070 flags directly. +// The EventText function will pick it up. + #include "PrecompiledHeader.h" #include diff --git a/pcsx2/PsxDma.cpp b/pcsx2/PsxDma.cpp index 51d544dda0..49606afb8e 100644 --- a/pcsx2/PsxDma.cpp +++ b/pcsx2/PsxDma.cpp @@ -26,60 +26,72 @@ // Dma11/12 in PsxSio2.c int iopsifbusy[2] = { 0, 0 }; -void psxDma4(u32 madr, u32 bcr, u32 chcr) { // SPU - const int size = (bcr >> 16) * (bcr & 0xFFFF); // Number of blocks to transfer - /*if (chcr & 0x400) SysPrintf("SPU 2 DMA 4 linked list chain mode! chcr = %x madr = %x bcr = %x\n", chcr, madr, bcr); - if (chcr & 0x40000000) SysPrintf("SPU 2 DMA 4 Unusual bit set on 'to' direction chcr = %x madr = %x bcr = %x\n", chcr, madr, bcr); - if ((chcr & 0x1) == 0) SysPrintf("SPU 2 DMA 4 loading from spu2 memory chcr = %x madr = %x bcr = %x\n", chcr, madr, bcr);*/ +static void __fastcall psxDmaGeneric(u32 madr, u32 bcr, u32 chcr, u32 spuCore, _SPU2writeDMA4Mem spu2WriteFunc ) +{ + const char dmaNum = spuCore ? '7' : '4'; + /*if (chcr & 0x400) DevCon::Status("SPU 2 DMA %c linked list chain mode! chcr = %x madr = %x bcr = %x\n", dmaNum, chcr, madr, bcr); + if (chcr & 0x40000000) DevCon::Notice("SPU 2 DMA %c Unusual bit set on 'to' direction chcr = %x madr = %x bcr = %x\n", dmaNum, chcr, madr, bcr); + if ((chcr & 0x1) == 0) DevCon::Status("SPU 2 DMA %c loading from spu2 memory chcr = %x madr = %x bcr = %x\n", dmaNum, chcr, madr, bcr);*/ + + const int size = (bcr >> 16) * (bcr & 0xFFFF); + + // Update the spu2 to the current cycle before initiating the DMA if(SPU2async) - { - SPU2async(psxRegs.cycle - psxCounters[6].sCycleT); + { + SPU2async(psxRegs.cycle - psxCounters[6].sCycleT); + //Console::Status("cycles sent to SPU2 %x\n", psxRegs.cycle - psxCounters[6].sCycleT); - //SysPrintf("cycles sent to SPU2 %x\n", psxRegs.cycle - psxCounters[6].sCycleT); psxCounters[6].sCycleT = psxRegs.cycle; psxCounters[6].CycleT = size * 3; - + psxNextCounter -= (psxRegs.cycle-psxNextsCounter); psxNextsCounter = psxRegs.cycle; - if(psxCounters[6].CycleT < psxNextCounter) psxNextCounter = psxCounters[6].CycleT; + if(psxCounters[6].CycleT < psxNextCounter) + psxNextCounter = psxCounters[6].CycleT; } - switch (chcr) { - case 0x01000201: //cpu to spu transfer - PSXDMA_LOG("*** DMA 4 - SPU mem2spu *** %lx addr = %lx size = %lx\n", chcr, madr, bcr); - //SysPrintf("DMA4 write blocks %x, size per block %x\n", (bcr >> 16), (bcr & 0xFFFF)); - - SPU2writeDMA4Mem((u16 *)PSXM(madr), size*2); - break; - case 0x01000200: //spu to cpu transfer - PSXDMA_LOG("*** DMA 4 - SPU spu2mem *** %lx addr = %lx size = %lx\n", chcr, madr, bcr); - //SysPrintf("DMA4 read blocks %x, size per block %x\n", (bcr >> 16), (bcr & 0xFFFF)); - - SPU2readDMA4Mem((u16 *)PSXM(madr), size*2); - psxCpu->Clear(HW_DMA4_MADR, size); - break; + switch (chcr) + { + case 0x01000201: //cpu to spu2 transfer + PSXDMA_LOG("*** DMA %c - mem2spu *** %lx addr = %lx size = %lx\n", dmaNum, chcr, madr, bcr); + spu2WriteFunc((u16 *)PSXM(madr), size*2); + break; + + case 0x01000200: //spu2 to cpu transfer + PSXDMA_LOG("*** DMA %c - spu2mem *** %lx addr = %lx size = %lx\n", dmaNum, chcr, madr, bcr); + spu2WriteFunc((u16 *)PSXM(madr), size*2); + psxCpu->Clear(spuCore ? HW_DMA7_MADR : HW_DMA4_MADR, size); + break; default: - SysPrintf("*** DMA 4 - SPU unknown *** %lx addr = %lx size = %lx\n", chcr, madr, bcr); - break; + Console::Error("*** DMA %c - SPU unknown *** %lx addr = %lx size = %lx\n", dmaNum, chcr, madr, bcr); + break; } } -int psxDma4Interrupt() { - HW_DMA4_CHCR &= ~0x01000000; - psxDmaInterrupt(4); - psxHu32(0x1070)|= 1<<9; - return 1; +void psxDma4(u32 madr, u32 bcr, u32 chcr) // SPU2's Core 0 +{ + psxDmaGeneric( madr, bcr, chcr, 0, SPU2writeDMA4Mem ); } -void psxDma2(u32 madr, u32 bcr, u32 chcr) { // GPU +int psxDma4Interrupt() +{ + HW_DMA4_CHCR &= ~0x01000000; + psxDmaInterrupt(4); + iopIntcIrq( 9 ); + return 1; +} + +void psxDma2(u32 madr, u32 bcr, u32 chcr) // GPU +{ HW_DMA2_CHCR &= ~0x01000000; psxDmaInterrupt(2); } -void psxDma6(u32 madr, u32 bcr, u32 chcr) { +void psxDma6(u32 madr, u32 bcr, u32 chcr) +{ u32 *mem = (u32 *)PSXM(madr); PSXDMA_LOG("*** DMA 6 - OT *** %lx addr = %lx size = %lx\n", chcr, madr, bcr); @@ -98,50 +110,22 @@ void psxDma6(u32 madr, u32 bcr, u32 chcr) { psxDmaInterrupt(6); } -void psxDma7(u32 madr, u32 bcr, u32 chcr) { - int size = (bcr >> 16) * (bcr & 0xFFFF); - - if(SPU2async) - { - SPU2async(psxRegs.cycle - psxCounters[6].sCycleT); - - psxCounters[6].sCycleT = psxRegs.cycle; - psxCounters[6].CycleT = size * 3; - - psxNextCounter -= (psxRegs.cycle-psxNextsCounter); - psxNextsCounter = psxRegs.cycle; - if(psxCounters[6].CycleT < psxNextCounter) psxNextCounter = psxCounters[6].CycleT; - - } - - switch (chcr) { - case 0x01000201: //cpu to spu2 transfer - PSXDMA_LOG("*** DMA 7 - SPU2 mem2spu *** %lx addr = %lx size = %lx\n", chcr, madr, bcr); - //SysPrintf("DMA7 write blocks %x, size per block %x\n", (bcr >> 16), (bcr & 0xFFFF)); - - SPU2writeDMA7Mem((u16 *)PSXM(madr), size*2); - break; - case 0x01000200: //spu2 to cpu transfer - PSXDMA_LOG("*** DMA 7 - SPU2 spu2mem *** %lx addr = %lx size = %lx\n", chcr, madr, bcr); - //SysPrintf("DMA7 read blocks %x, size per block %x\n", (bcr >> 16), (bcr & 0xFFFF)); - - SPU2readDMA7Mem((u16 *)PSXM(madr), size*2); - psxCpu->Clear(HW_DMA7_MADR, size); - break; - default: - SysPrintf("*** DMA 7 - SPU unknown *** %lx addr = %lx size = %lx\n", chcr, madr, bcr); - break; - } +void psxDma7(u32 madr, u32 bcr, u32 chcr) // SPU2's Core 1 +{ + psxDmaGeneric( madr, bcr, chcr, 1, SPU2writeDMA7Mem ); } -int psxDma7Interrupt() { - HW_DMA7_CHCR &= ~0x01000000; - psxDmaInterrupt2(0); - return 1; +int psxDma7Interrupt() +{ + HW_DMA7_CHCR &= ~0x01000000; + psxDmaInterrupt2(0); + //iopIntcIrq( 9 ); + return 1; } extern int eesifbusy[2]; -void psxDma9(u32 madr, u32 bcr, u32 chcr) { +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); iopsifbusy[0] = 1; @@ -171,25 +155,23 @@ void psxDma10(u32 madr, u32 bcr, u32 chcr) { } void psxDma8(u32 madr, u32 bcr, u32 chcr) { - int size; + + const int size = (bcr >> 16) * (bcr & 0xFFFF) * 8; switch (chcr & 0x01000201) { case 0x01000201: //cpu to dev9 transfer PSXDMA_LOG("*** DMA 8 - DEV9 mem2dev9 *** %lx addr = %lx size = %lx\n", chcr, madr, bcr); + DEV9writeDMA8Mem((u32*)PSXM(madr), size); + break; - size = (bcr >> 16) * (bcr & 0xFFFF); // Number of blocks to transfer - DEV9writeDMA8Mem((u32*)PSXM(madr), size*8); - break; case 0x01000200: //dev9 to cpu transfer PSXDMA_LOG("*** DMA 8 - DEV9 dev9mem *** %lx addr = %lx size = %lx\n", chcr, madr, bcr); + DEV9readDMA8Mem((u32*)PSXM(madr), size); + break; - size = (bcr >> 16) * (bcr & 0xFFFF); // Number of blocks to transfer - - DEV9readDMA8Mem((u32*)PSXM(madr), size*8); - break; default: PSXDMA_LOG("*** DMA 8 - DEV9 unknown *** %lx addr = %lx size = %lx\n", chcr, madr, bcr); - break; + break; } HW_DMA8_CHCR &= ~0x01000000; psxDmaInterrupt2(1); @@ -198,8 +180,8 @@ void psxDma8(u32 madr, u32 bcr, u32 chcr) { void dev9Interrupt() { if( (dev9Handler != NULL) && (dev9Handler() != 1) ) return; - - psxHu32(0x1070)|= 1<<13; + + iopIntcIrq( 13 ); hwIntcIrq(INTC_SBUS); } @@ -211,7 +193,7 @@ void usbInterrupt() { if( usbHandler != NULL && (usbHandler() != 1) ) return; - psxHu32(0x1070)|= 1<<22; + iopIntcIrq( 22 ); hwIntcIrq(INTC_SBUS); } @@ -220,7 +202,7 @@ void usbIrq(int cycles) { } void fwIrq() { - psxHu32(0x1070)|= 1<<24; + iopIntcIrq( 24 ); hwIntcIrq(INTC_SBUS); } @@ -239,6 +221,12 @@ void spu2DMA7Irq() { } void spu2Irq() { - psxHu32(0x1070)|= 1<<9; + iopIntcIrq( 9 ); hwIntcIrq(INTC_SBUS); } + +void iopIntcIrq( uint irqType ) +{ + psxHu32(0x1070)|= 1<= 0x1f801600 && add < 0x1f801700) { USBwrite16(add, value); return; } -#ifdef PCSX2_DEVBUILD - if((add & 0xf) == 0x9) SysPrintf("16bit write (possible chcr set) %x value %x\n", add, value); -#endif + + if((add & 0xf) == 0x9) DevCon::WriteLn("16bit write (possible chcr set) %x value %x", add, value); + switch (add) { case 0x1f801040: sioWrite8((u8)value); @@ -741,13 +741,23 @@ void psxHwWrite16(u32 add, u16 value) { // if (Config.SpuIrq) psxHu16(0x1070) |= 0x200; psxHu16(0x1070) &= value; return; - case 0x1f801074: PSXHW_LOG("IMASK 16bit write %x\n", value); + + case 0x1f801074: + PSXHW_LOG("IMASK 16bit write %x\n", value); psxHu16(0x1074) = value; + iopTestIntc(); + return; + + case 0x1f801078: // see the 32-bit version for notes! + PSXHW_LOG("ICTRL 16bit write %x\n", value); + psxHu16(0x1078) = value; + iopTestIntc(); return; case 0x1f8010c4: PSXHW_LOG("DMA4 BCR_size 16bit write %lx\n", value); - psxHu16(0x10c4) = value; return; // DMA4 bcr_size + psxHu16(0x10c4) = value; + return; // DMA4 bcr_size case 0x1f8010c6: PSXHW_LOG("DMA4 BCR_count 16bit write %lx\n", value); @@ -868,6 +878,7 @@ void psxHwWrite32(u32 add, u32 value) { psxHu32(add) = value; return; // Ram size +//------------------------------------------------------------------ case 0x1f801070: PSXHW_LOG("IREG 32bit write %lx\n", value); // if (Config.Sio) psxHu32(0x1070) |= 0x80; @@ -878,13 +889,16 @@ void psxHwWrite32(u32 add, u32 value) { case 0x1f801074: PSXHW_LOG("IMASK 32bit write %lx\n", value); psxHu32(0x1074) = value; + iopTestIntc(); return; case 0x1f801078: PSXHW_LOG("ICTRL 32bit write %lx\n", value); - psxHu32(0x1078) = value;//1; //According to pSXAuthor this allways becomes 1 on write, but MHPB won't boot if value is not writen ;p + psxHu32(0x1078) = value; //1; //According to pSXAuthor this allways becomes 1 on write, but MHPB won't boot if value is not writen ;p + iopTestIntc(); return; +//------------------------------------------------------------------ //SSBus registers case 0x1f801000: psxHu32(0x1000) = value; @@ -958,6 +972,8 @@ void psxHwWrite32(u32 add, u32 value) { psxHu32(0x1420) = value; PSXHW_LOG("SSBUS 32bit write %lx\n", value); return; + +//------------------------------------------------------------------ case 0x1f801080: PSXHW_LOG("DMA0 MADR 32bit write %lx\n", value); HW_DMA0_MADR = value; return; // DMA0 madr @@ -970,6 +986,7 @@ void psxHwWrite32(u32 add, u32 value) { // DmaExec(0); return; +//------------------------------------------------------------------ case 0x1f801090: PSXHW_LOG("DMA1 MADR 32bit write %lx\n", value); HW_DMA1_MADR = value; return; // DMA1 madr @@ -982,6 +999,7 @@ void psxHwWrite32(u32 add, u32 value) { // DmaExec(1); return; +//------------------------------------------------------------------ case 0x1f8010a0: PSXHW_LOG("DMA2 MADR 32bit write %lx\n", value); HW_DMA2_MADR = value; return; // DMA2 madr @@ -994,6 +1012,7 @@ void psxHwWrite32(u32 add, u32 value) { DmaExec(2); return; +//------------------------------------------------------------------ case 0x1f8010b0: PSXHW_LOG("DMA3 MADR 32bit write %lx\n", value); HW_DMA3_MADR = value; return; // DMA3 madr @@ -1007,6 +1026,7 @@ void psxHwWrite32(u32 add, u32 value) { return; +//------------------------------------------------------------------ case 0x1f8010c0: PSXHW_LOG("DMA4 MADR 32bit write %lx\n", value); SPU2WriteMemAddr(0,value); @@ -1020,6 +1040,7 @@ void psxHwWrite32(u32 add, u32 value) { DmaExec(4); return; +//------------------------------------------------------------------ #if 0 case 0x1f8010d0: break; //DMA5write_madr(); case 0x1f8010d4: break; //DMA5write_bcr(); @@ -1038,6 +1059,7 @@ void psxHwWrite32(u32 add, u32 value) { DmaExec(6); return; +//------------------------------------------------------------------ case 0x1f801500: PSXHW_LOG("DMA7 MADR 32bit write %lx\n", value); SPU2WriteMemAddr(1,value); @@ -1051,6 +1073,7 @@ void psxHwWrite32(u32 add, u32 value) { DmaExec2(7); return; +//------------------------------------------------------------------ case 0x1f801510: PSXHW_LOG("DMA8 MADR 32bit write %lx\n", value); HW_DMA8_MADR = value; return; // DMA8 madr @@ -1063,6 +1086,7 @@ void psxHwWrite32(u32 add, u32 value) { DmaExec2(8); return; +//------------------------------------------------------------------ case 0x1f801520: PSXHW_LOG("DMA9 MADR 32bit write %lx\n", value); HW_DMA9_MADR = value; return; // DMA9 madr @@ -1078,6 +1102,7 @@ void psxHwWrite32(u32 add, u32 value) { PSXHW_LOG("DMA9 TADR 32bit write %lx\n", value); HW_DMA9_TADR = value; return; // DMA9 tadr +//------------------------------------------------------------------ case 0x1f801530: PSXHW_LOG("DMA10 MADR 32bit write %lx\n", value); HW_DMA10_MADR = value; return; // DMA10 madr @@ -1090,6 +1115,7 @@ void psxHwWrite32(u32 add, u32 value) { DmaExec2(10); return; +//------------------------------------------------------------------ case 0x1f801540: PSXHW_LOG("DMA11 SIO2in MADR 32bit write %lx\n", value); HW_DMA11_MADR = value; return; @@ -1103,6 +1129,7 @@ void psxHwWrite32(u32 add, u32 value) { DmaExec2(11); return; +//------------------------------------------------------------------ case 0x1f801550: PSXHW_LOG("DMA12 SIO2out MADR 32bit write %lx\n", value); HW_DMA12_MADR = value; return; @@ -1116,6 +1143,7 @@ void psxHwWrite32(u32 add, u32 value) { DmaExec2(12); return; +//------------------------------------------------------------------ case 0x1f801570: psxHu32(0x1570) = value; PSXHW_LOG("DMA PCR2 32bit write %lx\n", value); @@ -1130,17 +1158,18 @@ void psxHwWrite32(u32 add, u32 value) { { u32 tmp = (~value) & HW_DMA_ICR; HW_DMA_ICR = ((tmp ^ value) & 0xffffff) ^ tmp; - return; } + return; case 0x1f801574: PSXHW_LOG("DMA ICR2 32bit write %lx\n", value); { u32 tmp = (~value) & HW_DMA_ICR2; HW_DMA_ICR2 = ((tmp ^ value) & 0xffffff) ^ tmp; - return; } + return; +//------------------------------------------------------------------ /* case 0x1f801810: PSXHW_LOG("GPU DATA 32bit write %lx\n", value); GPU_writeData(value); return; @@ -1213,9 +1242,10 @@ void psxHwWrite32(u32 add, u32 value) { PSXCNT_LOG("COUNTER 5 TARGET 32bit write %lx\n", value); psxRcntWtarget32(5, value); return; +//------------------------------------------------------------------ case 0x1f8014c0: PSXHW_LOG("RTC_HOLDMODE 32bit write %lx\n", value); - SysPrintf("RTC_HOLDMODE 32bit write %lx\n", value); + Console::Notice("** RTC_HOLDMODE 32bit write %lx", value); break; case 0x1f801450: @@ -1230,6 +1260,7 @@ void psxHwWrite32(u32 add, u32 value) { psxHu32(0x1450) = /*(*/value/* & (~0x8)) | (psxHu32(0x1450) & 0x8)*/; return; +//------------------------------------------------------------------ case 0x1F808200: case 0x1F808204: case 0x1F808208: @@ -1279,6 +1310,7 @@ void psxHwWrite32(u32 add, u32 value) { PSXHW_LOG("SIO2 write INTR <- %lx\n", value); sio2_setIntr(value); return; +//------------------------------------------------------------------ default: psxHu32(add) = value; PSXHW_LOG("*Unknown 32bit write at address %lx value %lx\n", add, value); @@ -1350,20 +1382,13 @@ void psxHw4Write8(u32 add, u8 value) { case 0x1f40200A: cdvdWrite0A(value); return; case 0x1f40200F: cdvdWrite0F(value); return; case 0x1f402014: cdvdWrite14(value); return; - case 0x1f402016: - cdvdWrite16(value); - //fixme - are these supposed to be here? - FreezeMMXRegs(0); - FreezeXMMRegs(0); - return; + case 0x1f402016: cdvdWrite16(value); return; case 0x1f402017: cdvdWrite17(value); return; case 0x1f402018: cdvdWrite18(value); return; case 0x1f40203A: cdvdWrite3A(value); return; default: - // note: use SysPrintF to notify console since this is a potentially serious - // emulation problem: //PSXHW_LOG("*Unknown 8bit write at address %lx value %x\n", add, value); - SysPrintf("*Unknown 8bit write at address %lx value %x\n", add, value); + Console::Notice("*Unknown 8bit write at address %lx value %x", add, value); return; } PSXHW_LOG("*Known 8bit write at address %lx value %x\n", add, value); @@ -1373,7 +1398,7 @@ void psxDmaInterrupt(int n) { if (HW_DMA_ICR & (1 << (16 + n))) { HW_DMA_ICR|= (1 << (24 + n)); psxRegs.CP0.n.Cause |= 1 << (9 + n); - psxHu32(0x1070) |= 8; + iopIntcIrq( 3 ); } } @@ -1387,6 +1412,6 @@ void psxDmaInterrupt2(int n) { }*/ HW_DMA_ICR2|= (1 << (24 + n)); psxRegs.CP0.n.Cause |= 1 << (16 + n); - psxHu32(0x1070) |= 8; + iopIntcIrq( 3 ); } } diff --git a/pcsx2/PsxSio2.cpp b/pcsx2/PsxSio2.cpp index bf899b5d46..29f84f8fe1 100644 --- a/pcsx2/PsxSio2.cpp +++ b/pcsx2/PsxSio2.cpp @@ -117,8 +117,7 @@ void sio2_setCtrl(u32 value){ if (sio2.ctrl & 1){ //recv packet //handle data that had been sent - //trigger interupt for SIO2 - psxHu32(0x1070)|=0x20000; + iopIntcIrq( 17 ); //SBUS sio2.recvIndex=0; sio2.ctrl &= ~1; diff --git a/pcsx2/R3000A.cpp b/pcsx2/R3000A.cpp index 7c118a4a02..b91f4fbf5b 100644 --- a/pcsx2/R3000A.cpp +++ b/pcsx2/R3000A.cpp @@ -43,8 +43,9 @@ s32 psxCycleEE = -1; // Used to signal to the EE when important actions that need IOP-attention have // happened (hsyncs, vsyncs, IOP exceptions, etc). IOP runs code whenever this // is true, even if it's already running ahead a bit. -int iopBranchAction = 0; +bool iopBranchAction = false; +bool iopEventTestIsActive = false; PCSX2_ALIGNED16(psxRegisters psxRegs); @@ -245,25 +246,38 @@ void psxBranchTest() if( psxTestCycle( psxNextsCounter, psxNextCounter ) ) { psxRcntUpdate(); - iopBranchAction = 1; + iopBranchAction = true; } // start the next branch at the next counter event by default // the interrupt code below will assign nearer branches if needed. g_psxNextBranchCycle = psxNextsCounter+psxNextCounter; - if (psxRegs.interrupt) _psxTestInterrupts(); - - if (psxHu32(0x1078)) { - if(psxHu32(0x1070) & psxHu32(0x1074)){ - if ((psxRegs.CP0.n.Status & 0xFE01) >= 0x401) - { -// PSXCPU_LOG("Interrupt: %x %x\n", HWMu32(0x1070), HWMu32(0x1074)); - psxException(0, 0); - iopBranchAction = 1; - } - } + if (psxRegs.interrupt) + { + iopEventTestIsActive = true; + _psxTestInterrupts(); + iopEventTestIsActive = false; } + + if( psxHu32(0x1078) == 0 ) return; + if( (psxHu32(0x1070) & psxHu32(0x1074)) == 0 ) return; + + if ((psxRegs.CP0.n.Status & 0xFE01) >= 0x401) + { +// PSXCPU_LOG("Interrupt: %x %x\n", HWMu32(0x1070), HWMu32(0x1074)); + psxException(0, 0); + iopBranchAction = true; + } +} + +void iopTestIntc() +{ + if( iopEventTestIsActive ) return; + if( psxHu32(0x1078) == 0 ) return; + if( (psxHu32(0x1070) & psxHu32(0x1074)) == 0 ) return; + + psxSetNextBranchDelta( 4 ); } void psxExecuteBios() { diff --git a/pcsx2/R3000A.h b/pcsx2/R3000A.h index eb397c0f0a..edce3e05c3 100644 --- a/pcsx2/R3000A.h +++ b/pcsx2/R3000A.h @@ -214,6 +214,7 @@ void psxExecuteBios(); extern s32 psxNextCounter; extern u32 psxNextsCounter; -extern int iopBranchAction; +extern bool iopBranchAction; +extern bool iopEventTestIsActive; #endif /* __R3000A_H__ */ diff --git a/pcsx2/R5900.cpp b/pcsx2/R5900.cpp index f8700bc6e3..fdffee82d9 100644 --- a/pcsx2/R5900.cpp +++ b/pcsx2/R5900.cpp @@ -45,6 +45,8 @@ u32 bExecBIOS = 0; // set if the BIOS has already been executed static bool cpuIsInitialized = false; static uint eeWaitCycles = 1024; +bool eeEventTestIsActive = false; + #ifdef _DEBUG extern u32 s_vucount; #endif @@ -208,7 +210,7 @@ void cpuException(u32 code, u32 bd) { } } else { offset = 0x180; //Overrride the cause - SysPrintf("cpuException: Status.EXL = 1 cause %x\n", code); + Console::Notice("cpuException: Status.EXL = 1 cause %x", code); } if (cpuRegs.CP0.n.Status.b.BEV == 0) { cpuRegs.pc = 0x80000000 + offset; @@ -216,7 +218,7 @@ void cpuException(u32 code, u32 bd) { cpuRegs.pc = 0xBFC00200 + offset; } } else { //Error Level 2 - Console::Error("FIX ME: Level 2 cpuException"); + Console::Error("*PCSX2* FIX ME: Level 2 cpuException"); if((code & 0x38000) <= 0x8000 ) { //Reset / NMI cpuRegs.pc = 0xBFC00000; Console::Notice("Reset request"); @@ -430,10 +432,6 @@ static __forceinline void _cpuTestInterrupts() TESTINT(10, vifMFIFOInterrupt); TESTINT(11, gifMFIFOInterrupt); } - - if ((cpuRegs.CP0.n.Status.val & 0x10007) != 0x10001) return; - TESTINT(30, intcInterrupt); - TESTINT(31, dmacInterrupt); } u32 s_iLastCOP0Cycle = 0; @@ -450,8 +448,9 @@ static __forceinline void _cpuTestTIMR() // the Count or Compare registers are modified. if ( (cpuRegs.CP0.n.Status.val & 0x8000) && - cpuRegs.CP0.n.Count >= cpuRegs.CP0.n.Compare && cpuRegs.CP0.n.Count < cpuRegs.CP0.n.Compare+1000 ) { - SysPrintf("timr intr: %x, %x\n", cpuRegs.CP0.n.Count, cpuRegs.CP0.n.Compare); + cpuRegs.CP0.n.Count >= cpuRegs.CP0.n.Compare && cpuRegs.CP0.n.Count < cpuRegs.CP0.n.Compare+1000 ) + { + Console::Status("timr intr: %x, %x", cpuRegs.CP0.n.Count, cpuRegs.CP0.n.Compare); cpuException(0x808000, cpuRegs.branch); } } @@ -473,11 +472,6 @@ static __forceinline void _cpuTestPERF() } } -// Maximum wait between branches. Lower values provide a tighter synchronization between -// the EE and the IOP, but incur more execution overhead. -//#define EE_WAIT_CYCLE 3072 // 2048 is probably stable now, but starting low first - - // if cpuRegs.cycle is greater than this cycle, should check cpuBranchTest for updates u32 g_nextBranchCycle = 0; @@ -485,6 +479,7 @@ u32 g_nextBranchCycle = 0; // and the recompiler. (moved here to help alleviate redundant code) static __forceinline void _cpuBranchTest_Shared() { + eeEventTestIsActive = true; g_nextBranchCycle = cpuRegs.cycle + eeWaitCycles; EEsCycle += cpuRegs.cycle - EEoCycle; @@ -504,10 +499,6 @@ static __forceinline void _cpuBranchTest_Shared() _cpuTestTIMR(); - //#ifdef CPU_LOG - // cpuTestMissingHwInts(); - //#endif - // ---- Interrupts ------------- if( cpuRegs.interrupt ) @@ -537,41 +528,6 @@ static __forceinline void _cpuBranchTest_Shared() psxCpu->ExecuteBlock(); } - // The IOP cound be running ahead/behind of us, so adjust the iop's next branch by its - // relative position to the EE (via EEsCycle) - cpuSetNextBranchDelta( ((g_psxNextBranchCycle-psxRegs.cycle)*8) - EEsCycle ); - - // Apply the hsync counter's nextCycle - cpuSetNextBranch( counters[4].sCycle, counters[4].CycleT ); - - // Apply vsync and other counter nextCycles - cpuSetNextBranch( nextsCounter, nextCounter ); -} - -#ifdef PCSX2_DEVBUILD -extern u8 g_globalXMMSaved; -extern u8 g_globalMMXSaved; -#endif - -void cpuBranchTest() -{ - // cpuBranchTest should be called from the recompiler only. - assert( Cpu == &recCpu ); - -#ifdef PCSX2_DEVBUILD - // dont' remove this check unless doing an official release - if( g_globalXMMSaved || g_globalMMXSaved) - SysPrintf("frozen regs have not been restored!!!\n"); - assert( !g_globalXMMSaved && !g_globalMMXSaved); -#endif - - // Don't need to freeze any regs during a BranchTest. - // Everything has been flushed already. - g_EEFreezeRegs = false; - - // Perform counters, ints, and IOP updates: - _cpuBranchTest_Shared(); - // ---- VU0 ------------- if (VU0.VI[REG_VPU_STAT].UL & 0x1) @@ -590,6 +546,56 @@ void cpuBranchTest() // one shot always. That is, when a program is executed the VU1 doesn't even // bother to return until the program is completely finished. + // ---- Schedule Next Event Test -------------- + + // The IOP cound be running ahead/behind of us, so adjust the iop's next branch by its + // relative position to the EE (via EEsCycle) + cpuSetNextBranchDelta( ((g_psxNextBranchCycle-psxRegs.cycle)*8) - EEsCycle ); + + // Apply the hsync counter's nextCycle + cpuSetNextBranch( counters[4].sCycle, counters[4].CycleT ); + + // Apply vsync and other counter nextCycles + cpuSetNextBranch( nextsCounter, nextCounter ); + + eeEventTestIsActive = false; + + // ---- INTC / DMAC Exceptions ----------------- + // Raise the INTC and DMAC interrupts here, which usually throw exceptions. + // This should be done last since the IOP and the VU0 can raise several EE + // exceptions. + + if ((cpuRegs.CP0.n.Status.val & 0x10007) == 0x10001) + { + TESTINT(30, intcInterrupt); + TESTINT(31, dmacInterrupt); + } +} + +#ifdef PCSX2_DEVBUILD +extern u8 g_globalXMMSaved; +extern u8 g_globalMMXSaved; +#endif + +void cpuBranchTest() +{ + // cpuBranchTest should be called from the recompiler only. + assert( Cpu == &recCpu ); + +#ifdef PCSX2_DEVBUILD + // dont' remove this check unless doing an official release + if( g_globalXMMSaved || g_globalMMXSaved) + DevCon::Error("Pcsx2 Foopah! Frozen regs have not been restored!!!"); + assert( !g_globalXMMSaved && !g_globalMMXSaved); +#endif + + // Don't need to freeze any regs during a BranchTest. + // Everything has been flushed already. + g_EEFreezeRegs = false; + + // Perform counters, ints, and IOP updates: + _cpuBranchTest_Shared(); + #ifdef PCSX2_DEVBUILD assert( !g_globalXMMSaved && !g_globalMMXSaved); #endif @@ -616,28 +622,37 @@ __forceinline void CPU_INT( u32 n, s32 ecycle) cpuSetNextBranchDelta( cpuRegs.eCycle[n] ); } -__forceinline void cpuTestINTCInts() { +void cpuTestINTCInts() +{ + if( cpuRegs.interrupt & (1 << 30) ) return; if( (cpuRegs.CP0.n.Status.val & 0x10407) != 0x10401 ) return; if( (psHu32(INTC_STAT) & psHu32(INTC_MASK)) == 0 ) return; - if( cpuRegs.interrupt & (1 << 30) ) return; - // fixme: The counters code throws INT30's alot, and most of the time they're - // "late" already, so firing them immediately instead of after the next branch - // (in which case they'll be really late) would be a lot better in theory. - // However, setting this to zero for everything breaks games, so if it's done - // it needs to be done for counters only. + cpuRegs.interrupt|= 1 << 30; + cpuRegs.sCycle[30] = cpuRegs.cycle; + cpuRegs.eCycle[30] = 0; - CPU_INT(30,4); + // only set the next branch delta if the exception won't be handled for + // the current branch... + if( !eeEventTestIsActive ) + cpuSetNextBranchDelta( 4 ); } __forceinline void cpuTestDMACInts() { - if ((cpuRegs.CP0.n.Status.val & 0x10807) != 0x10801) return; if ( cpuRegs.interrupt & (1 << 31) ) return; + if ((cpuRegs.CP0.n.Status.val & 0x10807) != 0x10801) return; if ( ( (psHu16(0xe012) & psHu16(0xe010)) == 0) && ( (psHu16(0xe010) & 0x8000) == 0) ) return; - CPU_INT(31, 4); + cpuRegs.interrupt|= 1 << 31; + cpuRegs.sCycle[31] = cpuRegs.cycle; + cpuRegs.eCycle[31] = 0; + + // only set the next branch delta if the exception won't be handled for + // the current branch... + if( !eeEventTestIsActive ) + cpuSetNextBranchDelta( 4 ); } __forceinline void cpuTestTIMRInts() { @@ -711,11 +726,5 @@ void IntcpuBranchTest() } - // fixme: why is this in the interpreter but not in the recompiler? (Air) - - if (VU0.VI[REG_VPU_STAT].UL & 0x100) { - Cpu->ExecuteVU1Block(); - } - g_EEFreezeRegs = true; } diff --git a/pcsx2/R5900.h b/pcsx2/R5900.h index bf9ffa0870..2b1961e03a 100644 --- a/pcsx2/R5900.h +++ b/pcsx2/R5900.h @@ -127,6 +127,7 @@ struct cpuRegisters { extern s32 EEsCycle; extern u32 EEoCycle; +extern bool eeEventTestIsActive; extern PCSX2_ALIGNED16_DECL(cpuRegisters cpuRegs); // used for optimization diff --git a/pcsx2/SPR.cpp b/pcsx2/SPR.cpp index 3dd1c8b973..8e63fd26b2 100644 --- a/pcsx2/SPR.cpp +++ b/pcsx2/SPR.cpp @@ -128,7 +128,7 @@ void _SPR0interleave() { CPU_INT(8, cycles); } -void _dmaSPR0() { +static __forceinline void _dmaSPR0() { if ((psHu32(DMAC_CTRL) & 0x30) == 0x20) { // STS == fromSPR diff --git a/pcsx2/Sio.cpp b/pcsx2/Sio.cpp index 9fa3a7eaed..c2ca550f68 100644 --- a/pcsx2/Sio.cpp +++ b/pcsx2/Sio.cpp @@ -517,10 +517,6 @@ void SIO_FORCEINLINE sioInterrupt() { void SaveState::sioFreeze() { - // eh, not supported anymore.. :) - //if( Mode == 0 && dwCurSaveStateVer == 0x7a30000e ) - // savesize -= 4; - if( IsLoading() ) sio.count = 0; Freeze( sio ); diff --git a/pcsx2/x86/iHw.cpp b/pcsx2/x86/iHw.cpp index 435d538c4b..fc9216d40b 100644 --- a/pcsx2/x86/iHw.cpp +++ b/pcsx2/x86/iHw.cpp @@ -497,7 +497,8 @@ static void __fastcall PrintDebug(u8 value) } // fixme: this would be more optimal as a C++ template (with bit as the template parameter) -static __forceinline void ConstWrite_ExecTimer( uptr func, u8 index, u8 bit, int mmreg) +template< uint bit > +static void ConstWrite_ExecTimer( uptr func, u8 index, int mmreg) { if( bit != 32 ) { @@ -518,23 +519,23 @@ static __forceinline void ConstWrite_ExecTimer( uptr func, u8 index, u8 bit, int } #define CONSTWRITE_TIMERS(bit) \ - case 0x10000000: ConstWrite_ExecTimer((uptr)&rcntWcount, 0, bit, mmreg); break; \ - case 0x10000010: ConstWrite_ExecTimer((uptr)&rcntWmode, 0, bit, mmreg); break; \ - case 0x10000020: ConstWrite_ExecTimer((uptr)&rcntWtarget, 0, bit, mmreg); break; \ - case 0x10000030: ConstWrite_ExecTimer((uptr)&rcntWhold, 0, bit, mmreg); break; \ + case 0x10000000: ConstWrite_ExecTimer((uptr)&rcntWcount, 0, mmreg); break; \ + case 0x10000010: ConstWrite_ExecTimer((uptr)&rcntWmode, 0, mmreg); break; \ + case 0x10000020: ConstWrite_ExecTimer((uptr)&rcntWtarget, 0, mmreg); break; \ + case 0x10000030: ConstWrite_ExecTimer((uptr)&rcntWhold, 0, mmreg); break; \ \ - case 0x10000800: ConstWrite_ExecTimer((uptr)&rcntWcount, 1, bit, mmreg); break; \ - case 0x10000810: ConstWrite_ExecTimer((uptr)&rcntWmode, 1, bit, mmreg); break; \ - case 0x10000820: ConstWrite_ExecTimer((uptr)&rcntWtarget, 1, bit, mmreg); break; \ - case 0x10000830: ConstWrite_ExecTimer((uptr)&rcntWhold, 1, bit, mmreg); break; \ + case 0x10000800: ConstWrite_ExecTimer((uptr)&rcntWcount, 1, mmreg); break; \ + case 0x10000810: ConstWrite_ExecTimer((uptr)&rcntWmode, 1, mmreg); break; \ + case 0x10000820: ConstWrite_ExecTimer((uptr)&rcntWtarget, 1, mmreg); break; \ + case 0x10000830: ConstWrite_ExecTimer((uptr)&rcntWhold, 1, mmreg); break; \ \ - case 0x10001000: ConstWrite_ExecTimer((uptr)&rcntWcount, 2, bit, mmreg); break; \ - case 0x10001010: ConstWrite_ExecTimer((uptr)&rcntWmode, 2, bit, mmreg); break; \ - case 0x10001020: ConstWrite_ExecTimer((uptr)&rcntWtarget, 2, bit, mmreg); break; \ + case 0x10001000: ConstWrite_ExecTimer((uptr)&rcntWcount, 2, mmreg); break; \ + case 0x10001010: ConstWrite_ExecTimer((uptr)&rcntWmode, 2, mmreg); break; \ + case 0x10001020: ConstWrite_ExecTimer((uptr)&rcntWtarget, 2, mmreg); break; \ \ - case 0x10001800: ConstWrite_ExecTimer((uptr)&rcntWcount, 3, bit, mmreg); break; \ - case 0x10001810: ConstWrite_ExecTimer((uptr)&rcntWmode, 3, bit, mmreg); break; \ - case 0x10001820: ConstWrite_ExecTimer((uptr)&rcntWtarget, 3, bit, mmreg); break; \ + case 0x10001800: ConstWrite_ExecTimer((uptr)&rcntWcount, 3, mmreg); break; \ + case 0x10001810: ConstWrite_ExecTimer((uptr)&rcntWmode, 3, mmreg); break; \ + case 0x10001820: ConstWrite_ExecTimer((uptr)&rcntWtarget, 3, mmreg); break; \ void hwConstWrite8(u32 mem, int mmreg) { @@ -971,11 +972,10 @@ void hwConstWrite32(u32 mem, int mmreg) _eeMoveMMREGtoR(EAX, mmreg); iFlushCall(0); MOV32RtoR(ECX, EAX); - NOT32R(ECX); - AND16RtoM((uptr)&PS2MEM_HW[0xe010], ECX); - SHR32ItoR(EAX, 16); + NOT32R(ECX); XOR16RtoM((uptr)&PS2MEM_HW[0xe012], EAX); + AND16RtoM((uptr)&PS2MEM_HW[0xe010], ECX); CALLFunc((uptr)cpuTestDMACInts); break; @@ -1164,11 +1164,11 @@ void hwConstWrite64(u32 mem, int mmreg) iFlushCall(0); MOV32RtoR(ECX, EAX); + SHR32ItoR(EAX, 16); NOT32R(ECX); + XOR16RtoM((uptr)&PS2MEM_HW[0xe012], EAX); AND16RtoM((uptr)&PS2MEM_HW[0xe010], ECX); - SHR32ItoR(EAX, 16); - XOR16RtoM((uptr)&PS2MEM_HW[0xe012], EAX); CALLFunc((uptr)cpuTestDMACInts); break; diff --git a/pcsx2/x86/iPsxHw.cpp b/pcsx2/x86/iPsxHw.cpp index 68d1c7f0dd..550e7602eb 100644 --- a/pcsx2/x86/iPsxHw.cpp +++ b/pcsx2/x86/iPsxHw.cpp @@ -610,8 +610,21 @@ void psxHwConstWrite16(u32 add, int mmreg) { _eeWriteConstMem16((uptr)&sio.BaudReg, mmreg); return; - case 0x1f801070: - _eeWriteConstMem16OP((uptr)&psxH[(add) & 0xffff], mmreg, 0); + case 0x1f801070: + _eeWriteConstMem16OP((uptr)&psxHu32(0x1070), mmreg, 0); // AND operation + return; + + case 0x1f801074: + _eeWriteConstMem16((uptr)&psxHu32(0x1074), mmreg); + iFlushCall(0); + CALLFunc( (uptr)&iopTestIntc ); + return; + + case 0x1f801078: + //According to pSXAuthor this allways becomes 1 on write, but MHPB won't boot if value is not writen ;p + _eeWriteConstMem16((uptr)&psxHu32(0x1078), mmreg); + iFlushCall(0); + CALLFunc( (uptr)&iopTestIntc ); return; // counters[0] @@ -807,7 +820,20 @@ void psxHwConstWrite32(u32 add, int mmreg) return; case 0x1f801070: - _eeWriteConstMem32OP((uptr)&psxH[(add) & 0xffff], mmreg, 0); // and + _eeWriteConstMem32OP((uptr)&psxHu32(0x1070), mmreg, 0); // and + return; + + case 0x1f801074: + _eeWriteConstMem32((uptr)&psxHu32(0x1074), mmreg); + iFlushCall(0); + CALLFunc( (uptr)&iopTestIntc ); + return; + + case 0x1f801078: + //According to pSXAuthor this allways becomes 1 on write, but MHPB won't boot if value is not writen ;p + _eeWriteConstMem32((uptr)&psxHu32(0x1078), mmreg); + iFlushCall(0); + CALLFunc( (uptr)&iopTestIntc ); return; // case 0x1f801088: @@ -1123,7 +1149,7 @@ int psxHw4ConstRead8(u32 x86reg, u32 add, u32 sign) { case 0x1f402039: CONSTREAD8_CALL((uptr)cdvdRead39); return 1; case 0x1f40203A: CONSTREAD8_CALL((uptr)cdvdRead3A); return 1; default: - SysPrintf("*Unknown 8bit read at address %lx\n", add); + Console::Notice("*Unknown 8bit read at address %lx\n", add); XOR32RtoR(x86reg, x86reg); return 0; } @@ -1147,7 +1173,7 @@ void psxHw4ConstWrite8(u32 add, int mmreg) { case 0x1f402018: CONSTWRITE_CALL(cdvdWrite18); return; case 0x1f40203A: CONSTWRITE_CALL(cdvdWrite3A); return; default: - SysPrintf("*Unknown 8bit write at address %lx\n", add); + Console::Notice("*Unknown 8bit write at address %lx\n", add); return; } } diff --git a/pcsx2/x86/iR3000Atables.cpp b/pcsx2/x86/iR3000Atables.cpp index 8be0d93056..d733662aa5 100644 --- a/pcsx2/x86/iR3000Atables.cpp +++ b/pcsx2/x86/iR3000Atables.cpp @@ -1761,6 +1761,11 @@ void rpsxRFE() SHR32ItoR(ECX, 2); OR32RtoR (EAX, ECX); MOV32RtoM((uptr)&psxRegs.CP0.n.Status, EAX); + + // Test the IOP's INTC status, so that any pending ints get raised. + + _psxFlushCall(0); + CALLFunc( (uptr)&iopTestIntc ); } // R3000A tables