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() {
|
int CPCOND0() {
|
||||||
if(((psHu16(DMAC_STAT) & psHu16(DMAC_PCR)) & 0x3ff) == (psHu16(DMAC_PCR) & 0x3ff)) return 1;
|
return (((psHu16(DMAC_STAT) & psHu16(DMAC_PCR)) & 0x3ff) == (psHu16(DMAC_PCR) & 0x3ff));
|
||||||
else return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//#define CPCOND0 1
|
//#define CPCOND0 1
|
||||||
|
@ -147,10 +146,12 @@ int CPCOND0() {
|
||||||
|
|
||||||
void BC0F() {
|
void BC0F() {
|
||||||
BC0(== 0);
|
BC0(== 0);
|
||||||
|
COP0_LOG( "COP0 > BC0F\n" );
|
||||||
}
|
}
|
||||||
|
|
||||||
void BC0T() {
|
void BC0T() {
|
||||||
BC0(== 1);
|
BC0(== 1);
|
||||||
|
COP0_LOG( "COP0 > BC0T\n" );
|
||||||
}
|
}
|
||||||
|
|
||||||
#define BC0L(cond) \
|
#define BC0L(cond) \
|
||||||
|
@ -160,10 +161,12 @@ void BC0T() {
|
||||||
|
|
||||||
void BC0FL() {
|
void BC0FL() {
|
||||||
BC0L(== 0);
|
BC0L(== 0);
|
||||||
|
COP0_LOG( "COP0 > BC0FL\n" );
|
||||||
}
|
}
|
||||||
|
|
||||||
void BC0TL() {
|
void BC0TL() {
|
||||||
BC0L(== 1);
|
BC0L(== 1);
|
||||||
|
COP0_LOG( "COP0 > BCOTL\n" );
|
||||||
}
|
}
|
||||||
|
|
||||||
void TLBR() {
|
void TLBR() {
|
||||||
|
@ -176,7 +179,7 @@ void TLBR() {
|
||||||
// if( !bExecBIOS )
|
// if( !bExecBIOS )
|
||||||
// __Log("TLBR %d\n", cpuRegs.CP0.n.Index&0x1f);
|
// __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.PageMask = tlb[i].PageMask;
|
||||||
cpuRegs.CP0.n.EntryHi = tlb[i].EntryHi&~(tlb[i].PageMask|0x1f00);
|
cpuRegs.CP0.n.EntryHi = tlb[i].EntryHi&~(tlb[i].PageMask|0x1f00);
|
||||||
cpuRegs.CP0.n.EntryLo0 = (tlb[i].EntryLo0&~1)|((tlb[i].EntryHi>>12)&1);
|
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 mask, addr;
|
||||||
u32 saddr, eaddr;
|
u32 saddr, eaddr;
|
||||||
|
|
||||||
|
COP0_LOG( "COP0 > WriteTLB" );
|
||||||
|
|
||||||
tlb[i].PageMask = cpuRegs.CP0.n.PageMask;
|
tlb[i].PageMask = cpuRegs.CP0.n.PageMask;
|
||||||
tlb[i].EntryHi = cpuRegs.CP0.n.EntryHi;
|
tlb[i].EntryHi = cpuRegs.CP0.n.EntryHi;
|
||||||
tlb[i].EntryLo0 = cpuRegs.CP0.n.EntryLo0;
|
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 ||
|
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.ERL || (cpuRegs.CP0.n.Status.b.KSU == 0)) {
|
||||||
cpuRegs.CP0.n.Status.b.EIE = 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?
|
// fixme: dead/unused code?
|
||||||
void dmacTestInterrupt() {
|
/*void dmacTestInterrupt() {
|
||||||
cpuRegs.interrupt &= ~(1 << 31);
|
cpuRegs.interrupt &= ~(1 << 31);
|
||||||
if ((cpuRegs.CP0.n.Status.val & 0x800) != 0x800) return;
|
if ((cpuRegs.CP0.n.Status.val & 0x800) != 0x800) return;
|
||||||
|
|
||||||
|
@ -1168,7 +1168,7 @@ void dmacTestInterrupt() {
|
||||||
psHu16(0xe010) & 0x8000) == 0) return;
|
psHu16(0xe010) & 0x8000) == 0) return;
|
||||||
|
|
||||||
if((psHu32(DMAC_CTRL) & 0x1) == 0) return;
|
if((psHu32(DMAC_CTRL) & 0x1) == 0) return;
|
||||||
}
|
}*/
|
||||||
|
|
||||||
__forceinline void dmacInterrupt()
|
__forceinline void dmacInterrupt()
|
||||||
{
|
{
|
||||||
|
|
|
@ -414,6 +414,11 @@ static __forceinline void _cpuTestTIMR()
|
||||||
cpuRegs.CP0.n.Count += cpuRegs.cycle-s_iLastCOP0Cycle;
|
cpuRegs.CP0.n.Count += cpuRegs.cycle-s_iLastCOP0Cycle;
|
||||||
s_iLastCOP0Cycle = cpuRegs.cycle;
|
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) &&
|
if ( (cpuRegs.CP0.n.Status.val & 0x8000) &&
|
||||||
cpuRegs.CP0.n.Count >= cpuRegs.CP0.n.Compare && cpuRegs.CP0.n.Count < cpuRegs.CP0.n.Compare+1000 ) {
|
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);
|
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
|
// Maximum wait between branches. Lower values provide a tighter synchronization between
|
||||||
// the EE and the IOP, but incur more execution overhead.
|
// 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
|
// if cpuRegs.cycle is greater than this cycle, should check cpuBranchTest for updates
|
||||||
u32 g_nextBranchCycle = 0;
|
u32 g_nextBranchCycle = 0;
|
||||||
|
@ -463,9 +468,9 @@ static __forceinline void _cpuBranchTest_Shared()
|
||||||
if( cpuTestCycle( nextsCounter, nextCounter ) )
|
if( cpuTestCycle( nextsCounter, nextCounter ) )
|
||||||
{
|
{
|
||||||
rcntUpdate();
|
rcntUpdate();
|
||||||
|
_cpuTestPERF();
|
||||||
}
|
}
|
||||||
|
|
||||||
_cpuTestPERF();
|
|
||||||
_cpuTestTIMR();
|
_cpuTestTIMR();
|
||||||
|
|
||||||
//#ifdef CPU_LOG
|
//#ifdef CPU_LOG
|
||||||
|
@ -496,7 +501,7 @@ static __forceinline void _cpuBranchTest_Shared()
|
||||||
if( iopBranchAction )
|
if( iopBranchAction )
|
||||||
{
|
{
|
||||||
//if( EEsCycle < -500 )
|
//if( EEsCycle < -500 )
|
||||||
// SysPrintf( " IOP ahead by: %d\n", -EEsCycle );
|
// SysPrintf( " IOP ahead by: %d cycles\n", -EEsCycle );
|
||||||
|
|
||||||
psxCpu->ExecuteBlock();
|
psxCpu->ExecuteBlock();
|
||||||
}
|
}
|
||||||
|
|
|
@ -516,13 +516,13 @@ __forceinline void sif1Interrupt() {
|
||||||
|
|
||||||
__forceinline void EEsif0Interrupt() {
|
__forceinline void EEsif0Interrupt() {
|
||||||
sif0dma->chcr &= ~0x100;
|
sif0dma->chcr &= ~0x100;
|
||||||
hwDmacIrq(5);
|
hwDmacIrq(DMAC_SIF0);
|
||||||
cpuRegs.interrupt &= ~(1 << 5);
|
cpuRegs.interrupt &= ~(1 << 5);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
__forceinline void EEsif1Interrupt() {
|
__forceinline void EEsif1Interrupt() {
|
||||||
hwDmacIrq(6);
|
hwDmacIrq(DMAC_SIF1);
|
||||||
sif1dma->chcr &= ~0x100;
|
sif1dma->chcr &= ~0x100;
|
||||||
cpuRegs.interrupt &= ~(1 << 6);
|
cpuRegs.interrupt &= ~(1 << 6);
|
||||||
|
|
||||||
|
@ -578,7 +578,6 @@ _inline void dmaSIF1() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// fixme: Unused code
|
|
||||||
_inline void dmaSIF2() {
|
_inline void dmaSIF2() {
|
||||||
SIF_LOG("dmaSIF2 chcr = %lx, madr = %lx, qwc = %lx\n",
|
SIF_LOG("dmaSIF2 chcr = %lx, madr = %lx, qwc = %lx\n",
|
||||||
sif2dma->chcr, sif2dma->madr, sif2dma->qwc);
|
sif2dma->chcr, sif2dma->madr, sif2dma->qwc);
|
||||||
|
|
|
@ -16,6 +16,12 @@
|
||||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
* 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))
|
#if !(defined(_MSC_VER) && defined(PCSX2_NORECBUILD))
|
||||||
|
|
||||||
#include "Common.h"
|
#include "Common.h"
|
||||||
|
@ -47,8 +53,6 @@ REC_SYS(EI);
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
////////////////////////////////////////////////////
|
|
||||||
//REC_SYS(MTC0);
|
|
||||||
////////////////////////////////////////////////////
|
////////////////////////////////////////////////////
|
||||||
REC_SYS(BC0F);
|
REC_SYS(BC0F);
|
||||||
////////////////////////////////////////////////////
|
////////////////////////////////////////////////////
|
||||||
|
@ -65,12 +69,6 @@ REC_SYS(TLBWI);
|
||||||
REC_SYS(TLBWR);
|
REC_SYS(TLBWR);
|
||||||
////////////////////////////////////////////////////
|
////////////////////////////////////////////////////
|
||||||
REC_SYS(TLBP);
|
REC_SYS(TLBP);
|
||||||
////////////////////////////////////////////////////
|
|
||||||
REC_SYS(ERET);
|
|
||||||
////////////////////////////////////////////////////
|
|
||||||
REC_SYS(DI);
|
|
||||||
////////////////////////////////////////////////////
|
|
||||||
REC_SYS(EI);
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////
|
////////////////////////////////////////////////////
|
||||||
extern u32 s_iLastCOP0Cycle;
|
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) {
|
/*void rec(COP0) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -354,11 +393,7 @@ void rec(TLBWR) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void rec(TLBP) {
|
void rec(TLBP) {
|
||||||
}
|
}*/
|
||||||
|
|
||||||
void rec(ERET) {
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
308
pcsx2/x86/iHw.c
308
pcsx2/x86/iHw.c
|
@ -455,36 +455,38 @@ void hwConstRead128(u32 mem, int xmmreg) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// when writing imm
|
// when writing imm
|
||||||
#define recDmaExecI8(name, num) { \
|
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 ) { \
|
MOV8ItoM((uptr)&PS2MEM_HW[(mem) & 0xffff], g_cpuConstRegs[(mmreg>>16)&0x1f].UL[0]);
|
||||||
TEST8ItoM((uptr)&PS2MEM_HW[DMAC_CTRL&0xffff], 1); \
|
if( g_cpuConstRegs[(mmreg>>16)&0x1f].UL[0] & 1 ) {
|
||||||
j8Ptr[6] = JZ8(0); \
|
TEST8ItoM((uptr)&PS2MEM_HW[DMAC_CTRL&0xffff], 1);
|
||||||
CALLFunc((uptr)dma##name); \
|
j8Ptr[6] = JZ8(0);
|
||||||
x86SetJ8( j8Ptr[6] ); \
|
CALLFunc((uptr)name);
|
||||||
} \
|
x86SetJ8( j8Ptr[6] );
|
||||||
} \
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#define recDmaExec8(name, num) { \
|
static void recDmaExec8(void (*name)(), u32 mem, int mmreg)
|
||||||
iFlushCall(0); \
|
{
|
||||||
if( IS_EECONSTREG(mmreg) ) { \
|
iFlushCall(0);
|
||||||
recDmaExecI8(name, num); \
|
if( IS_EECONSTREG(mmreg) ) {
|
||||||
} \
|
recDmaExecI8(name, mem, mmreg);
|
||||||
else { \
|
}
|
||||||
_eeMoveMMREGtoR(EAX, mmreg); \
|
else {
|
||||||
_eeWriteConstMem8((uptr)&PS2MEM_HW[(mem) & 0xffff], mmreg); \
|
_eeMoveMMREGtoR(EAX, mmreg);
|
||||||
\
|
_eeWriteConstMem8((uptr)&PS2MEM_HW[(mem) & 0xffff], mmreg);
|
||||||
TEST8ItoR(EAX, 1); \
|
|
||||||
j8Ptr[5] = JZ8(0); \
|
TEST8ItoR(EAX, 1);
|
||||||
TEST8ItoM((uptr)&PS2MEM_HW[DMAC_CTRL&0xffff], 1); \
|
j8Ptr[5] = JZ8(0);
|
||||||
j8Ptr[6] = JZ8(0); \
|
TEST8ItoM((uptr)&PS2MEM_HW[DMAC_CTRL&0xffff], 1);
|
||||||
\
|
j8Ptr[6] = JZ8(0);
|
||||||
CALLFunc((uptr)dma##name); \
|
|
||||||
\
|
CALLFunc((uptr)name);
|
||||||
x86SetJ8( j8Ptr[5] ); \
|
|
||||||
x86SetJ8( j8Ptr[6] ); \
|
x86SetJ8( j8Ptr[5] );
|
||||||
} \
|
x86SetJ8( j8Ptr[6] );
|
||||||
} \
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void PrintDebug(u8 value)
|
static void PrintDebug(u8 value)
|
||||||
{
|
{
|
||||||
|
@ -536,51 +538,51 @@ void hwConstWrite8(u32 mem, int mmreg)
|
||||||
CONSTWRITE_TIMERS(8)
|
CONSTWRITE_TIMERS(8)
|
||||||
|
|
||||||
case 0x1000f180:
|
case 0x1000f180:
|
||||||
_recPushReg(mmreg); \
|
_recPushReg(mmreg);
|
||||||
iFlushCall(0);
|
iFlushCall(0);
|
||||||
CALLFunc((uptr)PrintDebug);
|
CALLFunc((uptr)PrintDebug);
|
||||||
ADD32ItoR(ESP, 4);
|
ADD32ItoR(ESP, 4);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x10008001: // dma0 - vif0
|
case 0x10008001: // dma0 - vif0
|
||||||
recDmaExec8(VIF0, 0);
|
recDmaExec8(dmaVIF0, mem, mmreg);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x10009001: // dma1 - vif1
|
case 0x10009001: // dma1 - vif1
|
||||||
recDmaExec8(VIF1, 1);
|
recDmaExec8(dmaVIF1, mem, mmreg);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x1000a001: // dma2 - gif
|
case 0x1000a001: // dma2 - gif
|
||||||
recDmaExec8(GIF, 2);
|
recDmaExec8(dmaGIF, mem, mmreg);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x1000b001: // dma3 - fromIPU
|
case 0x1000b001: // dma3 - fromIPU
|
||||||
recDmaExec8(IPU0, 3);
|
recDmaExec8(dmaIPU0, mem, mmreg);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x1000b401: // dma4 - toIPU
|
case 0x1000b401: // dma4 - toIPU
|
||||||
recDmaExec8(IPU1, 4);
|
recDmaExec8(dmaIPU1, mem, mmreg);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x1000c001: // dma5 - sif0
|
case 0x1000c001: // dma5 - sif0
|
||||||
//if (value == 0) psxSu32(0x30) = 0x40000;
|
//if (value == 0) psxSu32(0x30) = 0x40000;
|
||||||
recDmaExec8(SIF0, 5);
|
recDmaExec8(dmaSIF0, mem, mmreg);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x1000c401: // dma6 - sif1
|
case 0x1000c401: // dma6 - sif1
|
||||||
recDmaExec8(SIF1, 6);
|
recDmaExec8(dmaSIF1, mem, mmreg);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x1000c801: // dma7 - sif2
|
case 0x1000c801: // dma7 - sif2
|
||||||
recDmaExec8(SIF2, 7);
|
recDmaExec8(dmaSIF2, mem, mmreg);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x1000d001: // dma8 - fromSPR
|
case 0x1000d001: // dma8 - fromSPR
|
||||||
recDmaExec8(SPR0, 8);
|
recDmaExec8(dmaSPR0, mem, mmreg);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x1000d401: // dma9 - toSPR
|
case 0x1000d401: // dma9 - toSPR
|
||||||
recDmaExec8(SPR1, 9);
|
recDmaExec8(dmaSPR1, mem, mmreg);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x1000f592: // DMAC_ENABLEW
|
case 0x1000f592: // DMAC_ENABLEW
|
||||||
|
@ -636,79 +638,81 @@ void hwConstWrite8(u32 mem, int mmreg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#define recDmaExecI16(name, num) { \
|
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 ) { \
|
MOV16ItoM((uptr)&PS2MEM_HW[(mem) & 0xffff], g_cpuConstRegs[(mmreg>>16)&0x1f].UL[0]);
|
||||||
TEST8ItoM((uptr)&PS2MEM_HW[DMAC_CTRL&0xffff], 1); \
|
if( g_cpuConstRegs[(mmreg>>16)&0x1f].UL[0] & 0x100 ) {
|
||||||
j8Ptr[6] = JZ8(0); \
|
TEST8ItoM((uptr)&PS2MEM_HW[DMAC_CTRL&0xffff], 1);
|
||||||
CALLFunc((uptr)dma##name); \
|
j8Ptr[6] = JZ8(0);
|
||||||
x86SetJ8( j8Ptr[6] ); \
|
CALLFunc((uptr)name);
|
||||||
} \
|
x86SetJ8( j8Ptr[6] );
|
||||||
} \
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#define recDmaExec16(name, num) { \
|
static void recDmaExec16(void (*name)(), u32 mem, int mmreg)
|
||||||
iFlushCall(0); \
|
{
|
||||||
if( IS_EECONSTREG(mmreg) ) { \
|
iFlushCall(0);
|
||||||
recDmaExecI16(name, num); \
|
if( IS_EECONSTREG(mmreg) ) {
|
||||||
} \
|
recDmaExecI16(name, mem, mmreg);
|
||||||
else { \
|
}
|
||||||
_eeMoveMMREGtoR(EAX, mmreg); \
|
else {
|
||||||
_eeWriteConstMem16((uptr)&PS2MEM_HW[(mem) & 0xffff], mmreg); \
|
_eeMoveMMREGtoR(EAX, mmreg);
|
||||||
\
|
_eeWriteConstMem16((uptr)&PS2MEM_HW[(mem) & 0xffff], mmreg);
|
||||||
TEST16ItoR(EAX, 0x100); \
|
|
||||||
j8Ptr[5] = JZ8(0); \
|
TEST16ItoR(EAX, 0x100);
|
||||||
TEST8ItoM((uptr)&PS2MEM_HW[DMAC_CTRL&0xffff], 1); \
|
j8Ptr[5] = JZ8(0);
|
||||||
j8Ptr[6] = JZ8(0); \
|
TEST8ItoM((uptr)&PS2MEM_HW[DMAC_CTRL&0xffff], 1);
|
||||||
\
|
j8Ptr[6] = JZ8(0);
|
||||||
CALLFunc((uptr)dma##name); \
|
|
||||||
\
|
CALLFunc((uptr)name);
|
||||||
x86SetJ8( j8Ptr[5] ); \
|
|
||||||
x86SetJ8( j8Ptr[6] ); \
|
x86SetJ8( j8Ptr[5] );
|
||||||
} \
|
x86SetJ8( j8Ptr[6] );
|
||||||
} \
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void hwConstWrite16(u32 mem, int mmreg)
|
void hwConstWrite16(u32 mem, int mmreg)
|
||||||
{
|
{
|
||||||
switch(mem) {
|
switch(mem) {
|
||||||
CONSTWRITE_TIMERS(16)
|
CONSTWRITE_TIMERS(16)
|
||||||
case 0x10008000: // dma0 - vif0
|
case 0x10008000: // dma0 - vif0
|
||||||
recDmaExec16(VIF0, 0);
|
recDmaExec16(dmaVIF0, mem, mmreg);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x10009000: // dma1 - vif1 - chcr
|
case 0x10009000: // dma1 - vif1 - chcr
|
||||||
recDmaExec16(VIF1, 1);
|
recDmaExec16(dmaVIF1, mem, mmreg);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x1000a000: // dma2 - gif
|
case 0x1000a000: // dma2 - gif
|
||||||
recDmaExec16(GIF, 2);
|
recDmaExec16(dmaGIF, mem, mmreg);
|
||||||
break;
|
break;
|
||||||
case 0x1000b000: // dma3 - fromIPU
|
case 0x1000b000: // dma3 - fromIPU
|
||||||
recDmaExec16(IPU0, 3);
|
recDmaExec16(dmaIPU0, mem, mmreg);
|
||||||
break;
|
break;
|
||||||
case 0x1000b400: // dma4 - toIPU
|
case 0x1000b400: // dma4 - toIPU
|
||||||
recDmaExec16(IPU1, 4);
|
recDmaExec16(dmaIPU1, mem, mmreg);
|
||||||
break;
|
break;
|
||||||
case 0x1000c000: // dma5 - sif0
|
case 0x1000c000: // dma5 - sif0
|
||||||
//if (value == 0) psxSu32(0x30) = 0x40000;
|
//if (value == 0) psxSu32(0x30) = 0x40000;
|
||||||
recDmaExec16(SIF0, 5);
|
recDmaExec16(dmaSIF0, mem, mmreg);
|
||||||
break;
|
break;
|
||||||
case 0x1000c002:
|
case 0x1000c002:
|
||||||
//?
|
//?
|
||||||
break;
|
break;
|
||||||
case 0x1000c400: // dma6 - sif1
|
case 0x1000c400: // dma6 - sif1
|
||||||
recDmaExec16(SIF1, 6);
|
recDmaExec16(dmaSIF1, mem, mmreg);
|
||||||
break;
|
break;
|
||||||
case 0x1000c800: // dma7 - sif2
|
case 0x1000c800: // dma7 - sif2
|
||||||
recDmaExec16(SIF2, 7);
|
recDmaExec16(dmaSIF2, mem, mmreg);
|
||||||
break;
|
break;
|
||||||
case 0x1000c802:
|
case 0x1000c802:
|
||||||
//?
|
//?
|
||||||
break;
|
break;
|
||||||
case 0x1000d000: // dma8 - fromSPR
|
case 0x1000d000: // dma8 - fromSPR
|
||||||
recDmaExec16(SPR0, 8);
|
recDmaExec16(dmaSPR0, mem, mmreg);
|
||||||
break;
|
break;
|
||||||
case 0x1000d400: // dma9 - toSPR
|
case 0x1000d400: // dma9 - toSPR
|
||||||
recDmaExec16(SPR1, 9);
|
recDmaExec16(dmaSPR1, mem, mmreg);
|
||||||
break;
|
break;
|
||||||
case 0x1000f592: // DMAC_ENABLEW
|
case 0x1000f592: // DMAC_ENABLEW
|
||||||
_eeWriteConstMem16((uptr)&PS2MEM_HW[0xf522], mmreg);
|
_eeWriteConstMem16((uptr)&PS2MEM_HW[0xf522], mmreg);
|
||||||
|
@ -781,57 +785,59 @@ void hwConstWrite16(u32 mem, int mmreg)
|
||||||
}
|
}
|
||||||
|
|
||||||
// when writing an Imm
|
// 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) { \
|
static void recDmaExecI( void (*name)(), u32 mem, int mmreg )
|
||||||
iFlushCall(0); \
|
{
|
||||||
if( IS_EECONSTREG(mmreg) ) { \
|
u32 c = g_cpuConstRegs[(mmreg>>16)&0x1f].UL[0];
|
||||||
recDmaExecI(name, num); \
|
/* Keep the old tag if in chain mode and hw doesnt set it*/
|
||||||
} \
|
if( (c & 0xc) == 0x4 && (c&0xffff0000) == 0 ) {
|
||||||
else { \
|
MOV16ItoM((uptr)&PS2MEM_HW[(mem) & 0xffff], c);
|
||||||
_eeMoveMMREGtoR(EAX, mmreg); \
|
}
|
||||||
TEST32ItoR(EAX, 0xffff0000); \
|
else MOV32ItoM((uptr)&PS2MEM_HW[(mem) & 0xffff], c);
|
||||||
j8Ptr[6] = JNZ8(0); \
|
if( c & 0x100 ) {
|
||||||
MOV32RtoR(ECX, EAX); \
|
TEST8ItoM((uptr)&PS2MEM_HW[DMAC_CTRL&0xffff], 1);
|
||||||
AND32ItoR(ECX, 0xc); \
|
j8Ptr[6] = JZ8(0);
|
||||||
CMP32ItoR(ECX, 4); \
|
CALLFunc((uptr)name);
|
||||||
j8Ptr[7] = JNE8(0); \
|
x86SetJ8( j8Ptr[6] );
|
||||||
if( IS_XMMREG(mmreg) || IS_MMXREG(mmreg) ) { \
|
}
|
||||||
MOV16RtoM((uptr)&PS2MEM_HW[(mem) & 0xffff], EAX); \
|
}
|
||||||
} \
|
|
||||||
else { \
|
static void recDmaExec( void (*name)(), u32 mem, int mmreg )
|
||||||
_eeWriteConstMem16((uptr)&PS2MEM_HW[(mem) & 0xffff], mmreg); \
|
{
|
||||||
} \
|
iFlushCall(0);
|
||||||
j8Ptr[8] = JMP8(0); \
|
if( IS_EECONSTREG(mmreg) ) {
|
||||||
x86SetJ8(j8Ptr[6]); \
|
recDmaExecI(name, mem, mmreg);
|
||||||
x86SetJ8(j8Ptr[7]); \
|
}
|
||||||
_eeWriteConstMem32((uptr)&PS2MEM_HW[(mem) & 0xffff], mmreg); \
|
else {
|
||||||
x86SetJ8(j8Ptr[8]); \
|
_eeMoveMMREGtoR(EAX, mmreg);
|
||||||
\
|
TEST32ItoR(EAX, 0xffff0000);
|
||||||
TEST16ItoR(EAX, 0x100); \
|
j8Ptr[6] = JNZ8(0);
|
||||||
j8Ptr[5] = JZ8(0); \
|
MOV32RtoR(ECX, EAX);
|
||||||
TEST32ItoM((uptr)&PS2MEM_HW[DMAC_CTRL&0xffff], 1); \
|
AND32ItoR(ECX, 0xc);
|
||||||
j8Ptr[6] = JZ8(0); \
|
CMP32ItoR(ECX, 4);
|
||||||
\
|
j8Ptr[7] = JNE8(0);
|
||||||
CALLFunc((uptr)dma##name); \
|
if( IS_XMMREG(mmreg) || IS_MMXREG(mmreg) ) {
|
||||||
\
|
MOV16RtoM((uptr)&PS2MEM_HW[(mem) & 0xffff], EAX);
|
||||||
x86SetJ8( j8Ptr[5] ); \
|
}
|
||||||
x86SetJ8( j8Ptr[6] ); \
|
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) { \
|
#define CONSTWRITE_CALLTIMER32(name, index, bit) { \
|
||||||
_recPushReg(mmreg); \
|
_recPushReg(mmreg); \
|
||||||
|
@ -925,42 +931,42 @@ void hwConstWrite32(u32 mem, int mmreg)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case 0x10008000: // dma0 - vif0
|
case 0x10008000: // dma0 - vif0
|
||||||
recDmaExec(VIF0, 0);
|
recDmaExec(dmaVIF0, mem, mmreg);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x10009000: // dma1 - vif1 - chcr
|
case 0x10009000: // dma1 - vif1 - chcr
|
||||||
recDmaExec(VIF1, 1);
|
recDmaExec(dmaVIF1, mem, mmreg);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x1000a000: // dma2 - gif
|
case 0x1000a000: // dma2 - gif
|
||||||
recDmaExec(GIF, 2);
|
recDmaExec(dmaGIF, mem, mmreg);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x1000b000: // dma3 - fromIPU
|
case 0x1000b000: // dma3 - fromIPU
|
||||||
recDmaExec(IPU0, 3);
|
recDmaExec(dmaIPU0, mem, mmreg);
|
||||||
break;
|
break;
|
||||||
case 0x1000b400: // dma4 - toIPU
|
case 0x1000b400: // dma4 - toIPU
|
||||||
recDmaExec(IPU1, 4);
|
recDmaExec(dmaIPU1, mem, mmreg);
|
||||||
break;
|
break;
|
||||||
case 0x1000c000: // dma5 - sif0
|
case 0x1000c000: // dma5 - sif0
|
||||||
//if (value == 0) psxSu32(0x30) = 0x40000;
|
//if (value == 0) psxSu32(0x30) = 0x40000;
|
||||||
recDmaExec(SIF0, 5);
|
recDmaExec(dmaSIF0, mem, mmreg);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x1000c400: // dma6 - sif1
|
case 0x1000c400: // dma6 - sif1
|
||||||
recDmaExec(SIF1, 6);
|
recDmaExec(dmaSIF1, mem, mmreg);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x1000c800: // dma7 - sif2
|
case 0x1000c800: // dma7 - sif2
|
||||||
recDmaExec(SIF2, 7);
|
recDmaExec(dmaSIF2, mem, mmreg);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x1000d000: // dma8 - fromSPR
|
case 0x1000d000: // dma8 - fromSPR
|
||||||
recDmaExec(SPR0, 8);
|
recDmaExec(dmaSPR0, mem, mmreg);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x1000d400: // dma9 - toSPR
|
case 0x1000d400: // dma9 - toSPR
|
||||||
recDmaExec(SPR1, 9);
|
recDmaExec(dmaSPR1, mem, mmreg);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x1000e010: // DMAC_STAT
|
case 0x1000e010: // DMAC_STAT
|
||||||
|
@ -972,12 +978,7 @@ void hwConstWrite32(u32 mem, int mmreg)
|
||||||
|
|
||||||
SHR32ItoR(EAX, 16);
|
SHR32ItoR(EAX, 16);
|
||||||
XOR16RtoM((uptr)&PS2MEM_HW[0xe012], EAX);
|
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);
|
CALLFunc((uptr)cpuTestDMACInts);
|
||||||
|
|
||||||
//x86SetJ8( j8Ptr[5] );
|
//x86SetJ8( j8Ptr[5] );
|
||||||
|
@ -985,29 +986,14 @@ void hwConstWrite32(u32 mem, int mmreg)
|
||||||
|
|
||||||
case 0x1000f000: // INTC_STAT
|
case 0x1000f000: // INTC_STAT
|
||||||
_eeWriteConstMem32OP((uptr)&PS2MEM_HW[0xf000], mmreg, 2);
|
_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);
|
CALLFunc((uptr)cpuTestINTCInts);
|
||||||
|
|
||||||
//x86SetJ8( j8Ptr[5] );
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x1000f010: // INTC_MASK
|
case 0x1000f010: // INTC_MASK
|
||||||
_eeMoveMMREGtoR(EAX, mmreg);
|
_eeMoveMMREGtoR(EAX, mmreg);
|
||||||
iFlushCall(0);
|
iFlushCall(0);
|
||||||
XOR16RtoM((uptr)&PS2MEM_HW[0xf010], EAX);
|
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);
|
CALLFunc((uptr)cpuTestINTCInts);
|
||||||
|
|
||||||
//x86SetJ8( j8Ptr[5] );
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x1000f130:
|
case 0x1000f130:
|
||||||
|
@ -1174,7 +1160,7 @@ void hwConstWrite64(u32 mem, int mmreg)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
case 0x1000a000: // dma2 - gif
|
case 0x1000a000: // dma2 - gif
|
||||||
recDmaExec(GIF, 2);
|
recDmaExec(dmaGIF, mem, mmreg);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 0x1000e010: // DMAC_STAT
|
case 0x1000e010: // DMAC_STAT
|
||||||
|
|
Loading…
Reference in New Issue