mirror of https://github.com/PCSX2/pcsx2.git
Major Fix: Found and fixed a big vmhack / COP0 bug. This should fix several games, including those in Issue 49, Issue 58, and possibly Issue 59 as well (testing of those issues and a confirmation is needed).
Code cleanup to iHw.c : Removed some rampant abuse of macros and quite a bit of unnecessary code bloat. git-svn-id: http://pcsx2-playground.googlecode.com/svn/trunk@393 a6443dda-0b58-4228-96e9-037be469359c
This commit is contained in:
parent
e8366b171a
commit
b8e4a35de6
13
pcsx2/COP0.c
13
pcsx2/COP0.c
|
@ -134,8 +134,7 @@ void MTC0() {
|
|||
}
|
||||
|
||||
int CPCOND0() {
|
||||
if(((psHu16(DMAC_STAT) & psHu16(DMAC_PCR)) & 0x3ff) == (psHu16(DMAC_PCR) & 0x3ff)) return 1;
|
||||
else return 0;
|
||||
return (((psHu16(DMAC_STAT) & psHu16(DMAC_PCR)) & 0x3ff) == (psHu16(DMAC_PCR) & 0x3ff));
|
||||
}
|
||||
|
||||
//#define CPCOND0 1
|
||||
|
@ -147,10 +146,12 @@ int CPCOND0() {
|
|||
|
||||
void BC0F() {
|
||||
BC0(== 0);
|
||||
COP0_LOG( "COP0 > BC0F\n" );
|
||||
}
|
||||
|
||||
void BC0T() {
|
||||
BC0(== 1);
|
||||
COP0_LOG( "COP0 > BC0T\n" );
|
||||
}
|
||||
|
||||
#define BC0L(cond) \
|
||||
|
@ -160,10 +161,12 @@ void BC0T() {
|
|||
|
||||
void BC0FL() {
|
||||
BC0L(== 0);
|
||||
COP0_LOG( "COP0 > BC0FL\n" );
|
||||
}
|
||||
|
||||
void BC0TL() {
|
||||
BC0L(== 1);
|
||||
COP0_LOG( "COP0 > BCOTL\n" );
|
||||
}
|
||||
|
||||
void TLBR() {
|
||||
|
@ -176,7 +179,7 @@ void TLBR() {
|
|||
// if( !bExecBIOS )
|
||||
// __Log("TLBR %d\n", cpuRegs.CP0.n.Index&0x1f);
|
||||
|
||||
SysPrintf("COP0_TLBR\n");
|
||||
COP0_LOG("COP0 > TLBR\n");
|
||||
cpuRegs.CP0.n.PageMask = tlb[i].PageMask;
|
||||
cpuRegs.CP0.n.EntryHi = tlb[i].EntryHi&~(tlb[i].PageMask|0x1f00);
|
||||
cpuRegs.CP0.n.EntryLo0 = (tlb[i].EntryLo0&~1)|((tlb[i].EntryHi>>12)&1);
|
||||
|
@ -219,6 +222,8 @@ void WriteTLB(int i) {
|
|||
u32 mask, addr;
|
||||
u32 saddr, eaddr;
|
||||
|
||||
COP0_LOG( "COP0 > WriteTLB" );
|
||||
|
||||
tlb[i].PageMask = cpuRegs.CP0.n.PageMask;
|
||||
tlb[i].EntryHi = cpuRegs.CP0.n.EntryHi;
|
||||
tlb[i].EntryLo0 = cpuRegs.CP0.n.EntryLo0;
|
||||
|
@ -340,7 +345,7 @@ void DI() {
|
|||
if (cpuRegs.CP0.n.Status.b._EDI || cpuRegs.CP0.n.Status.b.EXL ||
|
||||
cpuRegs.CP0.n.Status.b.ERL || (cpuRegs.CP0.n.Status.b.KSU == 0)) {
|
||||
cpuRegs.CP0.n.Status.b.EIE = 0;
|
||||
UpdateCP0Status();
|
||||
//UpdateCP0Status(); // ints are disabled so checking for them is kinda silly...
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1160,7 +1160,7 @@ __forceinline void intcInterrupt() {
|
|||
}
|
||||
|
||||
// fixme: dead/unused code?
|
||||
void dmacTestInterrupt() {
|
||||
/*void dmacTestInterrupt() {
|
||||
cpuRegs.interrupt &= ~(1 << 31);
|
||||
if ((cpuRegs.CP0.n.Status.val & 0x800) != 0x800) return;
|
||||
|
||||
|
@ -1168,7 +1168,7 @@ void dmacTestInterrupt() {
|
|||
psHu16(0xe010) & 0x8000) == 0) return;
|
||||
|
||||
if((psHu32(DMAC_CTRL) & 0x1) == 0) return;
|
||||
}
|
||||
}*/
|
||||
|
||||
__forceinline void dmacInterrupt()
|
||||
{
|
||||
|
|
|
@ -414,6 +414,11 @@ static __forceinline void _cpuTestTIMR()
|
|||
cpuRegs.CP0.n.Count += cpuRegs.cycle-s_iLastCOP0Cycle;
|
||||
s_iLastCOP0Cycle = cpuRegs.cycle;
|
||||
|
||||
// fixme: this looks like a hack to make up for the fact that the TIMR
|
||||
// doesn't yet have a proper mecahnism for setting itself up on a nextBranchCycle.
|
||||
// A proper fix would schedule the TIMR to trigger at a specific cycle anytime
|
||||
// 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);
|
||||
|
@ -440,7 +445,7 @@ 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 512 // 2048 is still unstable due to COP0
|
||||
#define EE_WAIT_CYCLE 1024 // 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;
|
||||
|
@ -463,9 +468,9 @@ static __forceinline void _cpuBranchTest_Shared()
|
|||
if( cpuTestCycle( nextsCounter, nextCounter ) )
|
||||
{
|
||||
rcntUpdate();
|
||||
_cpuTestPERF();
|
||||
}
|
||||
|
||||
_cpuTestPERF();
|
||||
_cpuTestTIMR();
|
||||
|
||||
//#ifdef CPU_LOG
|
||||
|
@ -496,7 +501,7 @@ static __forceinline void _cpuBranchTest_Shared()
|
|||
if( iopBranchAction )
|
||||
{
|
||||
//if( EEsCycle < -500 )
|
||||
// SysPrintf( " IOP ahead by: %d\n", -EEsCycle );
|
||||
// SysPrintf( " IOP ahead by: %d cycles\n", -EEsCycle );
|
||||
|
||||
psxCpu->ExecuteBlock();
|
||||
}
|
||||
|
|
|
@ -516,13 +516,13 @@ __forceinline void sif1Interrupt() {
|
|||
|
||||
__forceinline void EEsif0Interrupt() {
|
||||
sif0dma->chcr &= ~0x100;
|
||||
hwDmacIrq(5);
|
||||
hwDmacIrq(DMAC_SIF0);
|
||||
cpuRegs.interrupt &= ~(1 << 5);
|
||||
|
||||
}
|
||||
|
||||
__forceinline void EEsif1Interrupt() {
|
||||
hwDmacIrq(6);
|
||||
hwDmacIrq(DMAC_SIF1);
|
||||
sif1dma->chcr &= ~0x100;
|
||||
cpuRegs.interrupt &= ~(1 << 6);
|
||||
|
||||
|
@ -578,7 +578,6 @@ _inline void dmaSIF1() {
|
|||
|
||||
}
|
||||
|
||||
// fixme: Unused code
|
||||
_inline void dmaSIF2() {
|
||||
SIF_LOG("dmaSIF2 chcr = %lx, madr = %lx, qwc = %lx\n",
|
||||
sif2dma->chcr, sif2dma->madr, sif2dma->qwc);
|
||||
|
|
|
@ -16,6 +16,12 @@
|
|||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
// Important Note to Future Developers:
|
||||
// None of the COP0 instructions are really critical performance items,
|
||||
// so don't waste time converting any more them into recompiled code
|
||||
// unless it can make them nicely compact. Calling the C versions will
|
||||
// suffice.
|
||||
|
||||
#if !(defined(_MSC_VER) && defined(PCSX2_NORECBUILD))
|
||||
|
||||
#include "Common.h"
|
||||
|
@ -47,8 +53,6 @@ REC_SYS(EI);
|
|||
|
||||
#else
|
||||
|
||||
////////////////////////////////////////////////////
|
||||
//REC_SYS(MTC0);
|
||||
////////////////////////////////////////////////////
|
||||
REC_SYS(BC0F);
|
||||
////////////////////////////////////////////////////
|
||||
|
@ -65,12 +69,6 @@ REC_SYS(TLBWI);
|
|||
REC_SYS(TLBWR);
|
||||
////////////////////////////////////////////////////
|
||||
REC_SYS(TLBP);
|
||||
////////////////////////////////////////////////////
|
||||
REC_SYS(ERET);
|
||||
////////////////////////////////////////////////////
|
||||
REC_SYS(DI);
|
||||
////////////////////////////////////////////////////
|
||||
REC_SYS(EI);
|
||||
|
||||
////////////////////////////////////////////////////
|
||||
extern u32 s_iLastCOP0Cycle;
|
||||
|
@ -329,6 +327,47 @@ void recMTC0()
|
|||
}
|
||||
}
|
||||
|
||||
void recERET()
|
||||
{
|
||||
// Must branch immediately after ERET!
|
||||
branch = 2;
|
||||
MOV32ItoM( (uptr)&cpuRegs.code, (u32)cpuRegs.code );
|
||||
MOV32MtoR( ECX, (uptr)&cpuRegs.cycle );
|
||||
MOV32ItoM( (uptr)&cpuRegs.pc, (u32)pc );
|
||||
MOV32RtoM( (uptr)&g_nextBranchCycle, ECX );
|
||||
iFlushCall(FLUSH_EVERYTHING);
|
||||
CALLFunc( (uptr)ERET );
|
||||
}
|
||||
|
||||
void recEI()
|
||||
{
|
||||
// Must branch immediately after enabling ints!
|
||||
branch = 2;
|
||||
|
||||
MOV32ItoM( (uptr)&cpuRegs.code, (u32)cpuRegs.code );
|
||||
MOV32MtoR( ECX, (uptr)&cpuRegs.cycle );
|
||||
MOV32ItoM( (uptr)&cpuRegs.pc, (u32)pc );
|
||||
MOV32RtoM( (uptr)&g_nextBranchCycle, ECX );
|
||||
|
||||
iFlushCall(FLUSH_EVERYTHING);
|
||||
CALLFunc( (uptr)EI );
|
||||
}
|
||||
|
||||
void recDI()
|
||||
{
|
||||
// No need to branch after disabling interrupts...
|
||||
|
||||
//branch = 2;
|
||||
//MOV32ItoM( (uptr)&cpuRegs.code, (u32)cpuRegs.code );
|
||||
MOV32MtoR( ECX, (uptr)&cpuRegs.cycle );
|
||||
//MOV32ItoM( (uptr)&cpuRegs.pc, (u32)pc );
|
||||
MOV32RtoM( (uptr)&g_nextBranchCycle, ECX );
|
||||
|
||||
iFlushCall(FLUSH_EVERYTHING);
|
||||
CALLFunc( (uptr)DI );
|
||||
}
|
||||
|
||||
|
||||
/*void rec(COP0) {
|
||||
}
|
||||
|
||||
|
@ -354,11 +393,7 @@ void rec(TLBWR) {
|
|||
}
|
||||
|
||||
void rec(TLBP) {
|
||||
}
|
||||
|
||||
void rec(ERET) {
|
||||
}
|
||||
*/
|
||||
}*/
|
||||
|
||||
#endif
|
||||
|
||||
|
|
308
pcsx2/x86/iHw.c
308
pcsx2/x86/iHw.c
|
@ -455,36 +455,38 @@ void hwConstRead128(u32 mem, int xmmreg) {
|
|||
}
|
||||
|
||||
// when writing imm
|
||||
#define recDmaExecI8(name, num) { \
|
||||
MOV8ItoM((uptr)&PS2MEM_HW[(mem) & 0xffff], g_cpuConstRegs[(mmreg>>16)&0x1f].UL[0]); \
|
||||
if( g_cpuConstRegs[(mmreg>>16)&0x1f].UL[0] & 1 ) { \
|
||||
TEST8ItoM((uptr)&PS2MEM_HW[DMAC_CTRL&0xffff], 1); \
|
||||
j8Ptr[6] = JZ8(0); \
|
||||
CALLFunc((uptr)dma##name); \
|
||||
x86SetJ8( j8Ptr[6] ); \
|
||||
} \
|
||||
} \
|
||||
static void recDmaExecI8(void (*name)(), u32 mem, int mmreg)
|
||||
{
|
||||
MOV8ItoM((uptr)&PS2MEM_HW[(mem) & 0xffff], g_cpuConstRegs[(mmreg>>16)&0x1f].UL[0]);
|
||||
if( g_cpuConstRegs[(mmreg>>16)&0x1f].UL[0] & 1 ) {
|
||||
TEST8ItoM((uptr)&PS2MEM_HW[DMAC_CTRL&0xffff], 1);
|
||||
j8Ptr[6] = JZ8(0);
|
||||
CALLFunc((uptr)name);
|
||||
x86SetJ8( j8Ptr[6] );
|
||||
}
|
||||
}
|
||||
|
||||
#define recDmaExec8(name, num) { \
|
||||
iFlushCall(0); \
|
||||
if( IS_EECONSTREG(mmreg) ) { \
|
||||
recDmaExecI8(name, num); \
|
||||
} \
|
||||
else { \
|
||||
_eeMoveMMREGtoR(EAX, mmreg); \
|
||||
_eeWriteConstMem8((uptr)&PS2MEM_HW[(mem) & 0xffff], mmreg); \
|
||||
\
|
||||
TEST8ItoR(EAX, 1); \
|
||||
j8Ptr[5] = JZ8(0); \
|
||||
TEST8ItoM((uptr)&PS2MEM_HW[DMAC_CTRL&0xffff], 1); \
|
||||
j8Ptr[6] = JZ8(0); \
|
||||
\
|
||||
CALLFunc((uptr)dma##name); \
|
||||
\
|
||||
x86SetJ8( j8Ptr[5] ); \
|
||||
x86SetJ8( j8Ptr[6] ); \
|
||||
} \
|
||||
} \
|
||||
static void recDmaExec8(void (*name)(), u32 mem, int mmreg)
|
||||
{
|
||||
iFlushCall(0);
|
||||
if( IS_EECONSTREG(mmreg) ) {
|
||||
recDmaExecI8(name, mem, mmreg);
|
||||
}
|
||||
else {
|
||||
_eeMoveMMREGtoR(EAX, mmreg);
|
||||
_eeWriteConstMem8((uptr)&PS2MEM_HW[(mem) & 0xffff], mmreg);
|
||||
|
||||
TEST8ItoR(EAX, 1);
|
||||
j8Ptr[5] = JZ8(0);
|
||||
TEST8ItoM((uptr)&PS2MEM_HW[DMAC_CTRL&0xffff], 1);
|
||||
j8Ptr[6] = JZ8(0);
|
||||
|
||||
CALLFunc((uptr)name);
|
||||
|
||||
x86SetJ8( j8Ptr[5] );
|
||||
x86SetJ8( j8Ptr[6] );
|
||||
}
|
||||
}
|
||||
|
||||
static void PrintDebug(u8 value)
|
||||
{
|
||||
|
@ -536,51 +538,51 @@ void hwConstWrite8(u32 mem, int mmreg)
|
|||
CONSTWRITE_TIMERS(8)
|
||||
|
||||
case 0x1000f180:
|
||||
_recPushReg(mmreg); \
|
||||
_recPushReg(mmreg);
|
||||
iFlushCall(0);
|
||||
CALLFunc((uptr)PrintDebug);
|
||||
ADD32ItoR(ESP, 4);
|
||||
break;
|
||||
|
||||
case 0x10008001: // dma0 - vif0
|
||||
recDmaExec8(VIF0, 0);
|
||||
recDmaExec8(dmaVIF0, mem, mmreg);
|
||||
break;
|
||||
|
||||
case 0x10009001: // dma1 - vif1
|
||||
recDmaExec8(VIF1, 1);
|
||||
recDmaExec8(dmaVIF1, mem, mmreg);
|
||||
break;
|
||||
|
||||
case 0x1000a001: // dma2 - gif
|
||||
recDmaExec8(GIF, 2);
|
||||
recDmaExec8(dmaGIF, mem, mmreg);
|
||||
break;
|
||||
|
||||
case 0x1000b001: // dma3 - fromIPU
|
||||
recDmaExec8(IPU0, 3);
|
||||
recDmaExec8(dmaIPU0, mem, mmreg);
|
||||
break;
|
||||
|
||||
case 0x1000b401: // dma4 - toIPU
|
||||
recDmaExec8(IPU1, 4);
|
||||
recDmaExec8(dmaIPU1, mem, mmreg);
|
||||
break;
|
||||
|
||||
case 0x1000c001: // dma5 - sif0
|
||||
//if (value == 0) psxSu32(0x30) = 0x40000;
|
||||
recDmaExec8(SIF0, 5);
|
||||
recDmaExec8(dmaSIF0, mem, mmreg);
|
||||
break;
|
||||
|
||||
case 0x1000c401: // dma6 - sif1
|
||||
recDmaExec8(SIF1, 6);
|
||||
recDmaExec8(dmaSIF1, mem, mmreg);
|
||||
break;
|
||||
|
||||
case 0x1000c801: // dma7 - sif2
|
||||
recDmaExec8(SIF2, 7);
|
||||
recDmaExec8(dmaSIF2, mem, mmreg);
|
||||
break;
|
||||
|
||||
case 0x1000d001: // dma8 - fromSPR
|
||||
recDmaExec8(SPR0, 8);
|
||||
recDmaExec8(dmaSPR0, mem, mmreg);
|
||||
break;
|
||||
|
||||
case 0x1000d401: // dma9 - toSPR
|
||||
recDmaExec8(SPR1, 9);
|
||||
recDmaExec8(dmaSPR1, mem, mmreg);
|
||||
break;
|
||||
|
||||
case 0x1000f592: // DMAC_ENABLEW
|
||||
|
@ -636,79 +638,81 @@ void hwConstWrite8(u32 mem, int mmreg)
|
|||
}
|
||||
}
|
||||
|
||||
#define recDmaExecI16(name, num) { \
|
||||
MOV16ItoM((uptr)&PS2MEM_HW[(mem) & 0xffff], g_cpuConstRegs[(mmreg>>16)&0x1f].UL[0]); \
|
||||
if( g_cpuConstRegs[(mmreg>>16)&0x1f].UL[0] & 0x100 ) { \
|
||||
TEST8ItoM((uptr)&PS2MEM_HW[DMAC_CTRL&0xffff], 1); \
|
||||
j8Ptr[6] = JZ8(0); \
|
||||
CALLFunc((uptr)dma##name); \
|
||||
x86SetJ8( j8Ptr[6] ); \
|
||||
} \
|
||||
} \
|
||||
static void recDmaExecI16( void (*name)(), u32 mem, int mmreg )
|
||||
{
|
||||
MOV16ItoM((uptr)&PS2MEM_HW[(mem) & 0xffff], g_cpuConstRegs[(mmreg>>16)&0x1f].UL[0]);
|
||||
if( g_cpuConstRegs[(mmreg>>16)&0x1f].UL[0] & 0x100 ) {
|
||||
TEST8ItoM((uptr)&PS2MEM_HW[DMAC_CTRL&0xffff], 1);
|
||||
j8Ptr[6] = JZ8(0);
|
||||
CALLFunc((uptr)name);
|
||||
x86SetJ8( j8Ptr[6] );
|
||||
}
|
||||
}
|
||||
|
||||
#define recDmaExec16(name, num) { \
|
||||
iFlushCall(0); \
|
||||
if( IS_EECONSTREG(mmreg) ) { \
|
||||
recDmaExecI16(name, num); \
|
||||
} \
|
||||
else { \
|
||||
_eeMoveMMREGtoR(EAX, mmreg); \
|
||||
_eeWriteConstMem16((uptr)&PS2MEM_HW[(mem) & 0xffff], mmreg); \
|
||||
\
|
||||
TEST16ItoR(EAX, 0x100); \
|
||||
j8Ptr[5] = JZ8(0); \
|
||||
TEST8ItoM((uptr)&PS2MEM_HW[DMAC_CTRL&0xffff], 1); \
|
||||
j8Ptr[6] = JZ8(0); \
|
||||
\
|
||||
CALLFunc((uptr)dma##name); \
|
||||
\
|
||||
x86SetJ8( j8Ptr[5] ); \
|
||||
x86SetJ8( j8Ptr[6] ); \
|
||||
} \
|
||||
} \
|
||||
static void recDmaExec16(void (*name)(), u32 mem, int mmreg)
|
||||
{
|
||||
iFlushCall(0);
|
||||
if( IS_EECONSTREG(mmreg) ) {
|
||||
recDmaExecI16(name, mem, mmreg);
|
||||
}
|
||||
else {
|
||||
_eeMoveMMREGtoR(EAX, mmreg);
|
||||
_eeWriteConstMem16((uptr)&PS2MEM_HW[(mem) & 0xffff], mmreg);
|
||||
|
||||
TEST16ItoR(EAX, 0x100);
|
||||
j8Ptr[5] = JZ8(0);
|
||||
TEST8ItoM((uptr)&PS2MEM_HW[DMAC_CTRL&0xffff], 1);
|
||||
j8Ptr[6] = JZ8(0);
|
||||
|
||||
CALLFunc((uptr)name);
|
||||
|
||||
x86SetJ8( j8Ptr[5] );
|
||||
x86SetJ8( j8Ptr[6] );
|
||||
}
|
||||
}
|
||||
|
||||
void hwConstWrite16(u32 mem, int mmreg)
|
||||
{
|
||||
switch(mem) {
|
||||
CONSTWRITE_TIMERS(16)
|
||||
case 0x10008000: // dma0 - vif0
|
||||
recDmaExec16(VIF0, 0);
|
||||
recDmaExec16(dmaVIF0, mem, mmreg);
|
||||
break;
|
||||
|
||||
case 0x10009000: // dma1 - vif1 - chcr
|
||||
recDmaExec16(VIF1, 1);
|
||||
recDmaExec16(dmaVIF1, mem, mmreg);
|
||||
break;
|
||||
|
||||
case 0x1000a000: // dma2 - gif
|
||||
recDmaExec16(GIF, 2);
|
||||
recDmaExec16(dmaGIF, mem, mmreg);
|
||||
break;
|
||||
case 0x1000b000: // dma3 - fromIPU
|
||||
recDmaExec16(IPU0, 3);
|
||||
recDmaExec16(dmaIPU0, mem, mmreg);
|
||||
break;
|
||||
case 0x1000b400: // dma4 - toIPU
|
||||
recDmaExec16(IPU1, 4);
|
||||
recDmaExec16(dmaIPU1, mem, mmreg);
|
||||
break;
|
||||
case 0x1000c000: // dma5 - sif0
|
||||
//if (value == 0) psxSu32(0x30) = 0x40000;
|
||||
recDmaExec16(SIF0, 5);
|
||||
recDmaExec16(dmaSIF0, mem, mmreg);
|
||||
break;
|
||||
case 0x1000c002:
|
||||
//?
|
||||
break;
|
||||
case 0x1000c400: // dma6 - sif1
|
||||
recDmaExec16(SIF1, 6);
|
||||
recDmaExec16(dmaSIF1, mem, mmreg);
|
||||
break;
|
||||
case 0x1000c800: // dma7 - sif2
|
||||
recDmaExec16(SIF2, 7);
|
||||
recDmaExec16(dmaSIF2, mem, mmreg);
|
||||
break;
|
||||
case 0x1000c802:
|
||||
//?
|
||||
break;
|
||||
case 0x1000d000: // dma8 - fromSPR
|
||||
recDmaExec16(SPR0, 8);
|
||||
recDmaExec16(dmaSPR0, mem, mmreg);
|
||||
break;
|
||||
case 0x1000d400: // dma9 - toSPR
|
||||
recDmaExec16(SPR1, 9);
|
||||
recDmaExec16(dmaSPR1, mem, mmreg);
|
||||
break;
|
||||
case 0x1000f592: // DMAC_ENABLEW
|
||||
_eeWriteConstMem16((uptr)&PS2MEM_HW[0xf522], mmreg);
|
||||
|
@ -781,57 +785,59 @@ void hwConstWrite16(u32 mem, int mmreg)
|
|||
}
|
||||
|
||||
// when writing an Imm
|
||||
#define recDmaExecI(name, num) { \
|
||||
u32 c = g_cpuConstRegs[(mmreg>>16)&0x1f].UL[0]; \
|
||||
/* Keep the old tag if in chain mode and hw doesnt set it*/ \
|
||||
if( (c & 0xc) == 0x4 && (c&0xffff0000) == 0 ) { \
|
||||
MOV16ItoM((uptr)&PS2MEM_HW[(mem) & 0xffff], c); \
|
||||
} \
|
||||
else MOV32ItoM((uptr)&PS2MEM_HW[(mem) & 0xffff], c); \
|
||||
if( c & 0x100 ) { \
|
||||
TEST8ItoM((uptr)&PS2MEM_HW[DMAC_CTRL&0xffff], 1); \
|
||||
j8Ptr[6] = JZ8(0); \
|
||||
CALLFunc((uptr)dma##name); \
|
||||
x86SetJ8( j8Ptr[6] ); \
|
||||
} \
|
||||
} \
|
||||
|
||||
#define recDmaExec(name, num) { \
|
||||
iFlushCall(0); \
|
||||
if( IS_EECONSTREG(mmreg) ) { \
|
||||
recDmaExecI(name, num); \
|
||||
} \
|
||||
else { \
|
||||
_eeMoveMMREGtoR(EAX, mmreg); \
|
||||
TEST32ItoR(EAX, 0xffff0000); \
|
||||
j8Ptr[6] = JNZ8(0); \
|
||||
MOV32RtoR(ECX, EAX); \
|
||||
AND32ItoR(ECX, 0xc); \
|
||||
CMP32ItoR(ECX, 4); \
|
||||
j8Ptr[7] = JNE8(0); \
|
||||
if( IS_XMMREG(mmreg) || IS_MMXREG(mmreg) ) { \
|
||||
MOV16RtoM((uptr)&PS2MEM_HW[(mem) & 0xffff], EAX); \
|
||||
} \
|
||||
else { \
|
||||
_eeWriteConstMem16((uptr)&PS2MEM_HW[(mem) & 0xffff], mmreg); \
|
||||
} \
|
||||
j8Ptr[8] = JMP8(0); \
|
||||
x86SetJ8(j8Ptr[6]); \
|
||||
x86SetJ8(j8Ptr[7]); \
|
||||
_eeWriteConstMem32((uptr)&PS2MEM_HW[(mem) & 0xffff], mmreg); \
|
||||
x86SetJ8(j8Ptr[8]); \
|
||||
\
|
||||
TEST16ItoR(EAX, 0x100); \
|
||||
j8Ptr[5] = JZ8(0); \
|
||||
TEST32ItoM((uptr)&PS2MEM_HW[DMAC_CTRL&0xffff], 1); \
|
||||
j8Ptr[6] = JZ8(0); \
|
||||
\
|
||||
CALLFunc((uptr)dma##name); \
|
||||
\
|
||||
x86SetJ8( j8Ptr[5] ); \
|
||||
x86SetJ8( j8Ptr[6] ); \
|
||||
} \
|
||||
} \
|
||||
static void recDmaExecI( void (*name)(), u32 mem, int mmreg )
|
||||
{
|
||||
u32 c = g_cpuConstRegs[(mmreg>>16)&0x1f].UL[0];
|
||||
/* Keep the old tag if in chain mode and hw doesnt set it*/
|
||||
if( (c & 0xc) == 0x4 && (c&0xffff0000) == 0 ) {
|
||||
MOV16ItoM((uptr)&PS2MEM_HW[(mem) & 0xffff], c);
|
||||
}
|
||||
else MOV32ItoM((uptr)&PS2MEM_HW[(mem) & 0xffff], c);
|
||||
if( c & 0x100 ) {
|
||||
TEST8ItoM((uptr)&PS2MEM_HW[DMAC_CTRL&0xffff], 1);
|
||||
j8Ptr[6] = JZ8(0);
|
||||
CALLFunc((uptr)name);
|
||||
x86SetJ8( j8Ptr[6] );
|
||||
}
|
||||
}
|
||||
|
||||
static void recDmaExec( void (*name)(), u32 mem, int mmreg )
|
||||
{
|
||||
iFlushCall(0);
|
||||
if( IS_EECONSTREG(mmreg) ) {
|
||||
recDmaExecI(name, mem, mmreg);
|
||||
}
|
||||
else {
|
||||
_eeMoveMMREGtoR(EAX, mmreg);
|
||||
TEST32ItoR(EAX, 0xffff0000);
|
||||
j8Ptr[6] = JNZ8(0);
|
||||
MOV32RtoR(ECX, EAX);
|
||||
AND32ItoR(ECX, 0xc);
|
||||
CMP32ItoR(ECX, 4);
|
||||
j8Ptr[7] = JNE8(0);
|
||||
if( IS_XMMREG(mmreg) || IS_MMXREG(mmreg) ) {
|
||||
MOV16RtoM((uptr)&PS2MEM_HW[(mem) & 0xffff], EAX);
|
||||
}
|
||||
else {
|
||||
_eeWriteConstMem16((uptr)&PS2MEM_HW[(mem) & 0xffff], mmreg);
|
||||
}
|
||||
j8Ptr[8] = JMP8(0);
|
||||
x86SetJ8(j8Ptr[6]);
|
||||
x86SetJ8(j8Ptr[7]);
|
||||
_eeWriteConstMem32((uptr)&PS2MEM_HW[(mem) & 0xffff], mmreg);
|
||||
x86SetJ8(j8Ptr[8]);
|
||||
|
||||
TEST16ItoR(EAX, 0x100);
|
||||
j8Ptr[5] = JZ8(0);
|
||||
TEST32ItoM((uptr)&PS2MEM_HW[DMAC_CTRL&0xffff], 1);
|
||||
j8Ptr[6] = JZ8(0);
|
||||
|
||||
CALLFunc((uptr)name);
|
||||
x86SetJ8( j8Ptr[5] );
|
||||
x86SetJ8( j8Ptr[6] );
|
||||
}
|
||||
}
|
||||
|
||||
#define CONSTWRITE_CALLTIMER32(name, index, bit) { \
|
||||
_recPushReg(mmreg); \
|
||||
|
@ -925,42 +931,42 @@ void hwConstWrite32(u32 mem, int mmreg)
|
|||
return;
|
||||
|
||||
case 0x10008000: // dma0 - vif0
|
||||
recDmaExec(VIF0, 0);
|
||||
recDmaExec(dmaVIF0, mem, mmreg);
|
||||
break;
|
||||
|
||||
case 0x10009000: // dma1 - vif1 - chcr
|
||||
recDmaExec(VIF1, 1);
|
||||
recDmaExec(dmaVIF1, mem, mmreg);
|
||||
break;
|
||||
|
||||
case 0x1000a000: // dma2 - gif
|
||||
recDmaExec(GIF, 2);
|
||||
recDmaExec(dmaGIF, mem, mmreg);
|
||||
break;
|
||||
|
||||
case 0x1000b000: // dma3 - fromIPU
|
||||
recDmaExec(IPU0, 3);
|
||||
recDmaExec(dmaIPU0, mem, mmreg);
|
||||
break;
|
||||
case 0x1000b400: // dma4 - toIPU
|
||||
recDmaExec(IPU1, 4);
|
||||
recDmaExec(dmaIPU1, mem, mmreg);
|
||||
break;
|
||||
case 0x1000c000: // dma5 - sif0
|
||||
//if (value == 0) psxSu32(0x30) = 0x40000;
|
||||
recDmaExec(SIF0, 5);
|
||||
recDmaExec(dmaSIF0, mem, mmreg);
|
||||
break;
|
||||
|
||||
case 0x1000c400: // dma6 - sif1
|
||||
recDmaExec(SIF1, 6);
|
||||
recDmaExec(dmaSIF1, mem, mmreg);
|
||||
break;
|
||||
|
||||
case 0x1000c800: // dma7 - sif2
|
||||
recDmaExec(SIF2, 7);
|
||||
recDmaExec(dmaSIF2, mem, mmreg);
|
||||
break;
|
||||
|
||||
case 0x1000d000: // dma8 - fromSPR
|
||||
recDmaExec(SPR0, 8);
|
||||
recDmaExec(dmaSPR0, mem, mmreg);
|
||||
break;
|
||||
|
||||
case 0x1000d400: // dma9 - toSPR
|
||||
recDmaExec(SPR1, 9);
|
||||
recDmaExec(dmaSPR1, mem, mmreg);
|
||||
break;
|
||||
|
||||
case 0x1000e010: // DMAC_STAT
|
||||
|
@ -972,12 +978,7 @@ void hwConstWrite32(u32 mem, int mmreg)
|
|||
|
||||
SHR32ItoR(EAX, 16);
|
||||
XOR16RtoM((uptr)&PS2MEM_HW[0xe012], EAX);
|
||||
|
||||
// cpuRegs.CP0.n.Status.val is checked by cpuTestDMACInts.
|
||||
//MOV32MtoR(EAX, (uptr)&cpuRegs.CP0.n.Status.val);
|
||||
//AND32ItoR(EAX, 0x10807);
|
||||
//CMP32ItoR(EAX, 0x10801);
|
||||
//j8Ptr[5] = JNE8(0);
|
||||
|
||||
CALLFunc((uptr)cpuTestDMACInts);
|
||||
|
||||
//x86SetJ8( j8Ptr[5] );
|
||||
|
@ -985,29 +986,14 @@ void hwConstWrite32(u32 mem, int mmreg)
|
|||
|
||||
case 0x1000f000: // INTC_STAT
|
||||
_eeWriteConstMem32OP((uptr)&PS2MEM_HW[0xf000], mmreg, 2);
|
||||
// note: cpuRegs.CP0.n.Status.val conditional is done by cpuTestINTCInts.
|
||||
//MOV32MtoR(EAX, (uptr)&cpuRegs.CP0.n.Status.val);
|
||||
//AND32ItoR(EAX, 0x10407);
|
||||
//CMP32ItoR(EAX, 0x10401);
|
||||
//j8Ptr[5] = JNE8(0);
|
||||
CALLFunc((uptr)cpuTestINTCInts);
|
||||
|
||||
//x86SetJ8( j8Ptr[5] );
|
||||
break;
|
||||
|
||||
case 0x1000f010: // INTC_MASK
|
||||
_eeMoveMMREGtoR(EAX, mmreg);
|
||||
iFlushCall(0);
|
||||
XOR16RtoM((uptr)&PS2MEM_HW[0xf010], EAX);
|
||||
|
||||
// note: cpuRegs.CP0.n.Status.val conditional is done by cpuTestINTCInts.
|
||||
//MOV32MtoR(EAX, (uptr)&cpuRegs.CP0.n.Status.val);
|
||||
//AND32ItoR(EAX, 0x10407);
|
||||
//CMP32ItoR(EAX, 0x10401);
|
||||
//j8Ptr[5] = JNE8(0);
|
||||
CALLFunc((uptr)cpuTestINTCInts);
|
||||
|
||||
//x86SetJ8( j8Ptr[5] );
|
||||
break;
|
||||
|
||||
case 0x1000f130:
|
||||
|
@ -1174,7 +1160,7 @@ void hwConstWrite64(u32 mem, int mmreg)
|
|||
return;
|
||||
|
||||
case 0x1000a000: // dma2 - gif
|
||||
recDmaExec(GIF, 2);
|
||||
recDmaExec(dmaGIF, mem, mmreg);
|
||||
break;
|
||||
|
||||
case 0x1000e010: // DMAC_STAT
|
||||
|
|
Loading…
Reference in New Issue