mirror of
https://github.com/PCSX2/pcsx2.git
synced 2025-04-02 10:52:54 -04:00
git-svn-id: http://pcsx2.googlecode.com/svn/branches/pcsx2_0.9.4@186 96395faa-99c1-11dd-bbfe-3dabce05a288
1297 lines
31 KiB
C
1297 lines
31 KiB
C
/* Pcsx2 - Pc Ps2 Emulator
|
|
* Copyright (C) 2002-2007 Pcsx2 Team
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
*/
|
|
|
|
// stop compiling if NORECBUILD build (only for Visual Studio)
|
|
#if !(defined(_MSC_VER) && defined(PCSX2_NORECBUILD))
|
|
|
|
#include <string.h>
|
|
#include <malloc.h>
|
|
#include <assert.h>
|
|
|
|
#include "Common.h"
|
|
#include "iR5900.h"
|
|
#include "VUmicro.h"
|
|
#include "PsxMem.h"
|
|
#include "IPU/IPU.h"
|
|
#include "GS.h"
|
|
|
|
#ifndef PCSX2_VIRTUAL_MEM
|
|
extern u8 *psH; // hw mem
|
|
extern u16 *psHW;
|
|
extern u32 *psHL;
|
|
extern u64 *psHD;
|
|
#endif
|
|
|
|
extern int rdram_devices; // put 8 for TOOL and 2 for PS2 and PSX
|
|
extern int rdram_sdevid;
|
|
extern char sio_buffer[1024];
|
|
extern int sio_count;
|
|
|
|
int hwConstRead8(u32 x86reg, u32 mem, u32 sign)
|
|
{
|
|
#ifdef PCSX2_DEVBUILD
|
|
if( mem >= 0x10000000 && mem < 0x10008000 )
|
|
SysPrintf("hwRead8 to %x\n", mem);
|
|
#endif
|
|
|
|
if ((mem & 0xffffff0f) == 0x1000f200) {
|
|
if(mem == 0x1000f260) {
|
|
MMXONLY(if( IS_MMXREG(x86reg) ) PXORRtoR(x86reg&0xf, x86reg&0xf);
|
|
else)
|
|
XOR32RtoR(x86reg, x86reg);
|
|
return 0;
|
|
}
|
|
else if(mem == 0x1000F240) {
|
|
|
|
_eeReadConstMem8(x86reg, (uptr)&PS2MEM_HW[(mem) & 0xffff], sign);
|
|
//psHu32(mem) &= ~0x4000;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
if (mem < 0x10010000)
|
|
{
|
|
_eeReadConstMem8(x86reg, (uptr)&PS2MEM_HW[(mem) & 0xffff], sign);
|
|
}
|
|
else {
|
|
MMXONLY(if( IS_MMXREG(x86reg) ) PXORRtoR(x86reg&0xf, x86reg&0xf);
|
|
else )
|
|
XOR32RtoR(x86reg, x86reg);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
#define CONSTREAD16_CALL(name) { \
|
|
iFlushCall(0); \
|
|
CALLFunc((uptr)name); \
|
|
if( sign ) MOVSX32R16toR(EAX, EAX); \
|
|
else MOVZX32R16toR(EAX, EAX); \
|
|
} \
|
|
|
|
static u32 s_regreads[3] = {0x010200000, 0xbfff0000, 0xF0000102};
|
|
int hwConstRead16(u32 x86reg, u32 mem, u32 sign)
|
|
{
|
|
#ifdef PCSX2_DEVBUILD
|
|
if( mem >= 0x10002000 && mem < 0x10008000 )
|
|
SysPrintf("hwRead16 to %x\n", mem);
|
|
#endif
|
|
#ifdef PCSX2_DEVBUILD
|
|
if( mem >= 0x10000000 && mem < 0x10002000 ){
|
|
#ifdef EECNT_LOG
|
|
EECNT_LOG("cnt read to %x\n", mem);
|
|
#endif
|
|
}
|
|
#endif
|
|
|
|
switch (mem) {
|
|
case 0x10000000:
|
|
PUSH32I(0);
|
|
CONSTREAD16_CALL(rcntRcount);
|
|
ADD32ItoR(ESP, 4);
|
|
return 1;
|
|
case 0x10000010:
|
|
_eeReadConstMem16(x86reg, (uptr)&counters[0].mode, sign);
|
|
return 0;
|
|
case 0x10000020:
|
|
_eeReadConstMem16(x86reg, (uptr)&counters[0].mode, sign);
|
|
return 0;
|
|
case 0x10000030:
|
|
_eeReadConstMem16(x86reg, (uptr)&counters[0].hold, sign);
|
|
return 0;
|
|
|
|
case 0x10000800:
|
|
PUSH32I(1);
|
|
CONSTREAD16_CALL(rcntRcount);
|
|
ADD32ItoR(ESP, 4);
|
|
return 1;
|
|
|
|
case 0x10000810:
|
|
_eeReadConstMem16(x86reg, (uptr)&counters[1].mode, sign);
|
|
return 0;
|
|
|
|
case 0x10000820:
|
|
_eeReadConstMem16(x86reg, (uptr)&counters[1].target, sign);
|
|
return 0;
|
|
|
|
case 0x10000830:
|
|
_eeReadConstMem16(x86reg, (uptr)&counters[1].hold, sign);
|
|
return 0;
|
|
|
|
case 0x10001000:
|
|
PUSH32I(2);
|
|
CONSTREAD16_CALL(rcntRcount);
|
|
ADD32ItoR(ESP, 4);
|
|
return 1;
|
|
|
|
case 0x10001010:
|
|
_eeReadConstMem16(x86reg, (uptr)&counters[2].mode, sign);
|
|
return 0;
|
|
|
|
case 0x10001020:
|
|
_eeReadConstMem16(x86reg, (uptr)&counters[2].target, sign);
|
|
return 0;
|
|
|
|
case 0x10001800:
|
|
PUSH32I(3);
|
|
CONSTREAD16_CALL(rcntRcount);
|
|
ADD32ItoR(ESP, 4);
|
|
return 1;
|
|
|
|
case 0x10001810:
|
|
_eeReadConstMem16(x86reg, (uptr)&counters[3].mode, sign);
|
|
return 0;
|
|
|
|
case 0x10001820:
|
|
_eeReadConstMem16(x86reg, (uptr)&counters[3].target, sign);
|
|
return 0;
|
|
|
|
default:
|
|
if ((mem & 0xffffff0f) == 0x1000f200) {
|
|
if(mem == 0x1000f260) {
|
|
MMXONLY(if( IS_MMXREG(x86reg) ) PXORRtoR(x86reg&0xf, x86reg&0xf);
|
|
else )
|
|
XOR32RtoR(x86reg, x86reg);
|
|
return 0;
|
|
}
|
|
else if(mem == 0x1000F240) {
|
|
|
|
MMXONLY(if( IS_MMXREG(x86reg) ) {
|
|
MOVDMtoMMX(x86reg&0xf, (uptr)&PS2MEM_HW[(mem) & 0xffff] - 2);
|
|
PORMtoR(x86reg&0xf, (uptr)&s_regreads[0]);
|
|
PANDMtoR(x86reg&0xf, (uptr)&s_regreads[1]);
|
|
}
|
|
else )
|
|
{
|
|
if( sign ) MOVSX32M16toR(x86reg, (uptr)&PS2MEM_HW[(mem) & 0xffff]);
|
|
else MOVZX32M16toR(x86reg, (uptr)&PS2MEM_HW[(mem) & 0xffff]);
|
|
|
|
OR32ItoR(x86reg, 0x0102);
|
|
AND32ItoR(x86reg, ~0x4000);
|
|
}
|
|
return 0;
|
|
}
|
|
}
|
|
if (mem < 0x10010000) {
|
|
_eeReadConstMem16(x86reg, (uptr)&PS2MEM_HW[(mem) & 0xffff], sign);
|
|
}
|
|
else {
|
|
MMXONLY(if( IS_MMXREG(x86reg) ) PXORRtoR(x86reg&0xf, x86reg&0xf);
|
|
else )
|
|
XOR32RtoR(x86reg, x86reg);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
#ifdef PCSX2_VIRTUAL_MEM
|
|
//
|
|
//#if defined(_MSC_VER) && !defined(__x86_64__)
|
|
//__declspec(naked) void recCheckF440()
|
|
//{
|
|
// __asm {
|
|
// add b440, 1
|
|
// mov eax, b440
|
|
// sub eax, 3
|
|
// mov edx, 31
|
|
//
|
|
// cmp eax, 27
|
|
// ja WriteVal
|
|
// shl eax, 2
|
|
// mov edx, dword ptr [eax+b440table]
|
|
//
|
|
//WriteVal:
|
|
// mov eax, PS2MEM_BASE_+0x1000f440
|
|
// mov dword ptr [eax], edx
|
|
// ret
|
|
// }
|
|
//}
|
|
//#else
|
|
//void recCheckF440();
|
|
//#endif
|
|
|
|
void iMemRead32Check()
|
|
{
|
|
// test if 0xf440
|
|
// if( bExecBIOS ) {
|
|
// u8* ptempptr[2];
|
|
// CMP32ItoR(ECX, 0x1000f440);
|
|
// ptempptr[0] = JNE8(0);
|
|
//
|
|
//// // increment and test
|
|
//// INC32M((uptr)&b440);
|
|
//// MOV32MtoR(EAX, (uptr)&b440);
|
|
//// SUB32ItoR(EAX, 3);
|
|
//// MOV32ItoR(EDX, 31);
|
|
////
|
|
//// CMP32ItoR(EAX, 27);
|
|
////
|
|
//// // look up table
|
|
//// ptempptr[1] = JA8(0);
|
|
//// SHL32ItoR(EAX, 2);
|
|
//// ADD32ItoR(EAX, (int)b440table);
|
|
//// MOV32RmtoR(EDX, EAX);
|
|
////
|
|
//// x86SetJ8( ptempptr[1] );
|
|
////
|
|
//// MOV32RtoM( (int)PS2MEM_HW+0xf440, EDX);
|
|
// CALLFunc((uptr)recCheckF440);
|
|
//
|
|
// x86SetJ8( ptempptr[0] );
|
|
// }
|
|
}
|
|
|
|
#endif
|
|
|
|
int hwContRead32_f440()
|
|
{
|
|
if ((psHu32(0xf430) >> 6) & 0xF)
|
|
return 0;
|
|
else
|
|
switch ((psHu32(0xf430)>>16) & 0xFFF){//MCH_RICM: x:4|SA:12|x:5|SDEV:1|SOP:4|SBC:1|SDEV:5
|
|
case 0x21://INIT
|
|
{
|
|
int ret = 0x1F * (rdram_sdevid < rdram_devices);
|
|
rdram_sdevid += (rdram_sdevid < rdram_devices);
|
|
return ret;
|
|
}
|
|
case 0x23://CNFGA
|
|
return 0x0D0D; //PVER=3 | MVER=16 | DBL=1 | REFBIT=5
|
|
case 0x24://CNFGB
|
|
//0x0110 for PSX SVER=0 | CORG=8(5x9x7) | SPT=1 | DEVTYP=0 | BYTE=0
|
|
return 0x0090; //SVER=0 | CORG=4(5x9x6) | SPT=1 | DEVTYP=0 | BYTE=0
|
|
case 0x40://DEVID
|
|
return psHu32(0xf430) & 0x1F; // =SDEV
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int hwConstRead32(u32 x86reg, u32 mem)
|
|
{
|
|
//IPU regs
|
|
if ((mem>=0x10002000) && (mem<0x10003000)) {
|
|
return ipuConstRead32(x86reg, mem);
|
|
}
|
|
|
|
switch (mem) {
|
|
case 0x10000000:
|
|
iFlushCall(0);
|
|
PUSH32I(0);
|
|
CALLFunc((uptr)rcntRcount);
|
|
#ifdef EECNT_LOG
|
|
EECNT_LOG("Counter 0 count read = %x\n", rcntRcount(0));
|
|
#endif
|
|
ADD32ItoR(ESP, 4);
|
|
return 1;
|
|
case 0x10000010:
|
|
_eeReadConstMem32(x86reg, (uptr)&counters[0].mode);
|
|
#ifdef EECNT_LOG
|
|
EECNT_LOG("Counter 0 mode read = %x\n", counters[0].mode);
|
|
#endif
|
|
return 0;
|
|
case 0x10000020:
|
|
_eeReadConstMem32(x86reg, (uptr)&counters[0].target);
|
|
#ifdef EECNT_LOG
|
|
EECNT_LOG("Counter 0 target read = %x\n", counters[0].target);
|
|
#endif
|
|
return 0;
|
|
case 0x10000030:
|
|
_eeReadConstMem32(x86reg, (uptr)&counters[0].hold);
|
|
return 0;
|
|
|
|
case 0x10000800:
|
|
iFlushCall(0);
|
|
PUSH32I(1);
|
|
CALLFunc((uptr)rcntRcount);
|
|
#ifdef EECNT_LOG
|
|
EECNT_LOG("Counter 1 count read = %x\n", rcntRcount(1));
|
|
#endif
|
|
ADD32ItoR(ESP, 4);
|
|
return 1;
|
|
case 0x10000810:
|
|
_eeReadConstMem32(x86reg, (uptr)&counters[1].mode);
|
|
#ifdef EECNT_LOG
|
|
EECNT_LOG("Counter 1 mode read = %x\n", counters[1].mode);
|
|
#endif
|
|
return 0;
|
|
case 0x10000820:
|
|
_eeReadConstMem32(x86reg, (uptr)&counters[1].target);
|
|
#ifdef EECNT_LOG
|
|
EECNT_LOG("Counter 1 target read = %x\n", counters[1].target);
|
|
#endif
|
|
return 0;
|
|
case 0x10000830:
|
|
_eeReadConstMem32(x86reg, (uptr)&counters[1].hold);
|
|
return 0;
|
|
|
|
case 0x10001000:
|
|
iFlushCall(0);
|
|
PUSH32I(2);
|
|
CALLFunc((uptr)rcntRcount);
|
|
#ifdef EECNT_LOG
|
|
EECNT_LOG("Counter 2 count read = %x\n", rcntRcount(2));
|
|
#endif
|
|
ADD32ItoR(ESP, 4);
|
|
return 1;
|
|
case 0x10001010:
|
|
_eeReadConstMem32(x86reg, (uptr)&counters[2].mode);
|
|
#ifdef EECNT_LOG
|
|
EECNT_LOG("Counter 2 mode read = %x\n", counters[2].mode);
|
|
#endif
|
|
return 0;
|
|
case 0x10001020:
|
|
_eeReadConstMem32(x86reg, (uptr)&counters[2].target);
|
|
#ifdef EECNT_LOG
|
|
EECNT_LOG("Counter 2 target read = %x\n", counters[2].target);
|
|
#endif
|
|
return 0;
|
|
case 0x10001030:
|
|
_eeReadConstMem32(x86reg, (uptr)&counters[2].hold);
|
|
return 0;
|
|
|
|
case 0x10001800:
|
|
iFlushCall(0);
|
|
PUSH32I(3);
|
|
CALLFunc((uptr)rcntRcount);
|
|
#ifdef EECNT_LOG
|
|
EECNT_LOG("Counter 3 count read = %x\n", rcntRcount(3));
|
|
#endif
|
|
ADD32ItoR(ESP, 4);
|
|
return 1;
|
|
case 0x10001810:
|
|
_eeReadConstMem32(x86reg, (uptr)&counters[3].mode);
|
|
#ifdef EECNT_LOG
|
|
EECNT_LOG("Counter 3 mode read = %x\n", counters[3].mode);
|
|
#endif
|
|
return 0;
|
|
case 0x10001820:
|
|
_eeReadConstMem32(x86reg, (uptr)&counters[3].target);
|
|
#ifdef EECNT_LOG
|
|
EECNT_LOG("Counter 3 target read = %x\n", counters[3].target);
|
|
#endif
|
|
return 0;
|
|
case 0x10001830:
|
|
_eeReadConstMem32(x86reg, (uptr)&counters[3].hold);
|
|
return 0;
|
|
|
|
case 0x1000f130:
|
|
case 0x1000f410:
|
|
case 0x1000f430:
|
|
if( IS_XMMREG(x86reg) ) SSEX_PXOR_XMM_to_XMM(x86reg&0xf, x86reg&0xf);
|
|
MMXONLY(else if( IS_MMXREG(x86reg) ) PXORRtoR(x86reg&0xf, x86reg&0xf);)
|
|
else XOR32RtoR(x86reg, x86reg);
|
|
return 0;
|
|
|
|
case 0x1000f440:
|
|
iFlushCall(0);
|
|
CALLFunc((uptr)hwContRead32_f440);
|
|
return 1;
|
|
|
|
case 0x1000f520: // DMAC_ENABLER
|
|
_eeReadConstMem32(x86reg, (uptr)&PS2MEM_HW[0xf590]);
|
|
return 0;
|
|
|
|
default:
|
|
if ((mem & 0xffffff0f) == 0x1000f200) {
|
|
if(mem == 0x1000f260) {
|
|
if( IS_XMMREG(x86reg) ) SSEX_PXOR_XMM_to_XMM(x86reg&0xf, x86reg&0xf);
|
|
MMXONLY(else if( IS_MMXREG(x86reg) ) PXORRtoR(x86reg&0xf, x86reg&0xf);)
|
|
else XOR32RtoR(x86reg, x86reg);
|
|
return 0;
|
|
}
|
|
else if(mem == 0x1000F240) {
|
|
|
|
if( IS_XMMREG(x86reg) ) {
|
|
SSEX_MOVD_M32_to_XMM(x86reg&0xf, (uptr)&PS2MEM_HW[(mem) & 0xffff]);
|
|
SSEX_POR_M128_to_XMM(x86reg&0xf, (uptr)&s_regreads[2]);
|
|
}
|
|
MMXONLY(else if( IS_MMXREG(x86reg) ) {
|
|
MOVDMtoMMX(x86reg&0xf, (uptr)&PS2MEM_HW[(mem) & 0xffff]);
|
|
PORMtoR(x86reg&0xf, (uptr)&s_regreads[2]);
|
|
})
|
|
else {
|
|
MOV32MtoR(x86reg, (uptr)&PS2MEM_HW[(mem) & 0xffff]);
|
|
OR32ItoR(x86reg, 0xF0000102);
|
|
}
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
if (mem < 0x10010000) {
|
|
_eeReadConstMem32(x86reg, (uptr)&PS2MEM_HW[(mem) & 0xffff]);
|
|
}
|
|
else {
|
|
if( IS_XMMREG(x86reg) ) SSEX_PXOR_XMM_to_XMM(x86reg&0xf, x86reg&0xf);
|
|
MMXONLY(else if( IS_MMXREG(x86reg) ) PXORRtoR(x86reg&0xf, x86reg&0xf);)
|
|
else XOR32RtoR(x86reg, x86reg);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
void hwConstRead64(u32 mem, int mmreg) {
|
|
if ((mem>=0x10002000) && (mem<0x10003000)) {
|
|
ipuConstRead64(mem, mmreg);
|
|
return;
|
|
}
|
|
|
|
if( IS_XMMREG(mmreg) ) SSE_MOVLPS_M64_to_XMM(mmreg&0xff, (uptr)PSM(mem));
|
|
else {
|
|
X86_64ASSERT();
|
|
MMXONLY(MOVQMtoR(mmreg, (uptr)PSM(mem));
|
|
SetMMXstate();)
|
|
}
|
|
}
|
|
|
|
PCSX2_ALIGNED16(u32 s_TempFIFO[4]);
|
|
void hwConstRead128(u32 mem, int xmmreg) {
|
|
if (mem >= 0x10004000 && mem < 0x10008000) {
|
|
iFlushCall(0);
|
|
PUSH32I((uptr)&s_TempFIFO[0]);
|
|
PUSH32I(mem);
|
|
CALLFunc((uptr)ReadFIFO);
|
|
ADD32ItoR(ESP, 8);
|
|
_eeReadConstMem128( xmmreg, (uptr)&s_TempFIFO[0]);
|
|
return;
|
|
}
|
|
|
|
_eeReadConstMem128( xmmreg, (uptr)PSM(mem));
|
|
}
|
|
|
|
// 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] ); \
|
|
} \
|
|
} \
|
|
|
|
#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 PrintDebug(u8 value)
|
|
{
|
|
if (value == '\n') {
|
|
sio_buffer[sio_count] = 0;
|
|
SysPrintf(COLOR_GREEN "%s\n" COLOR_RESET, sio_buffer);
|
|
sio_count = 0;
|
|
} else {
|
|
if (sio_count < 1023) {
|
|
sio_buffer[sio_count++] = value;
|
|
}
|
|
}
|
|
}
|
|
|
|
#define CONSTWRITE_CALLTIMER(name, index, bit) { \
|
|
if( !IS_EECONSTREG(mmreg) ) { \
|
|
if( bit == 8 ) MOVZX32R8toR(mmreg&0xf, mmreg&0xf); \
|
|
else if( bit == 16 ) MOVZX32R16toR(mmreg&0xf, mmreg&0xf); \
|
|
} \
|
|
_recPushReg(mmreg); \
|
|
iFlushCall(0); \
|
|
PUSH32I(index); \
|
|
CALLFunc((uptr)name); \
|
|
ADD32ItoR(ESP, 8); \
|
|
} \
|
|
|
|
#define CONSTWRITE_TIMERS(bit) \
|
|
case 0x10000000: CONSTWRITE_CALLTIMER(rcntWcount, 0, bit); break; \
|
|
case 0x10000010: CONSTWRITE_CALLTIMER(rcntWmode, 0, bit); break; \
|
|
case 0x10000020: CONSTWRITE_CALLTIMER(rcntWtarget, 0, bit); break; \
|
|
case 0x10000030: CONSTWRITE_CALLTIMER(rcntWhold, 0, bit); break; \
|
|
\
|
|
case 0x10000800: CONSTWRITE_CALLTIMER(rcntWcount, 1, bit); break; \
|
|
case 0x10000810: CONSTWRITE_CALLTIMER(rcntWmode, 1, bit); break; \
|
|
case 0x10000820: CONSTWRITE_CALLTIMER(rcntWtarget, 1, bit); break; \
|
|
case 0x10000830: CONSTWRITE_CALLTIMER(rcntWhold, 1, bit); break; \
|
|
\
|
|
case 0x10001000: CONSTWRITE_CALLTIMER(rcntWcount, 2, bit); break; \
|
|
case 0x10001010: CONSTWRITE_CALLTIMER(rcntWmode, 2, bit); break; \
|
|
case 0x10001020: CONSTWRITE_CALLTIMER(rcntWtarget, 2, bit); break; \
|
|
\
|
|
case 0x10001800: CONSTWRITE_CALLTIMER(rcntWcount, 3, bit); break; \
|
|
case 0x10001810: CONSTWRITE_CALLTIMER(rcntWmode, 3, bit); break; \
|
|
case 0x10001820: CONSTWRITE_CALLTIMER(rcntWtarget, 3, bit); break; \
|
|
|
|
void hwConstWrite8(u32 mem, int mmreg)
|
|
{
|
|
switch (mem) {
|
|
CONSTWRITE_TIMERS(8)
|
|
|
|
case 0x1000f180:
|
|
_recPushReg(mmreg); \
|
|
iFlushCall(0);
|
|
CALLFunc((uptr)PrintDebug);
|
|
ADD32ItoR(ESP, 4);
|
|
break;
|
|
|
|
case 0x10008001: // dma0 - vif0
|
|
recDmaExec8(VIF0, 0);
|
|
break;
|
|
|
|
case 0x10009001: // dma1 - vif1
|
|
recDmaExec8(VIF1, 1);
|
|
break;
|
|
|
|
case 0x1000a001: // dma2 - gif
|
|
recDmaExec8(GIF, 2);
|
|
break;
|
|
|
|
case 0x1000b001: // dma3 - fromIPU
|
|
recDmaExec8(IPU0, 3);
|
|
break;
|
|
|
|
case 0x1000b401: // dma4 - toIPU
|
|
recDmaExec8(IPU1, 4);
|
|
break;
|
|
|
|
case 0x1000c001: // dma5 - sif0
|
|
//if (value == 0) psxSu32(0x30) = 0x40000;
|
|
recDmaExec8(SIF0, 5);
|
|
break;
|
|
|
|
case 0x1000c401: // dma6 - sif1
|
|
recDmaExec8(SIF1, 6);
|
|
break;
|
|
|
|
case 0x1000c801: // dma7 - sif2
|
|
recDmaExec8(SIF2, 7);
|
|
break;
|
|
|
|
case 0x1000d001: // dma8 - fromSPR
|
|
recDmaExec8(SPR0, 8);
|
|
break;
|
|
|
|
case 0x1000d401: // dma9 - toSPR
|
|
recDmaExec8(SPR1, 9);
|
|
break;
|
|
|
|
case 0x1000f592: // DMAC_ENABLEW
|
|
_eeWriteConstMem8( (uptr)&PS2MEM_HW[0xf522], mmreg );
|
|
_eeWriteConstMem8( (uptr)&PS2MEM_HW[0xf592], mmreg );
|
|
break;
|
|
|
|
default:
|
|
if ((mem & 0xffffff0f) == 0x1000f200) {
|
|
u32 at = mem & 0xf0;
|
|
switch(at)
|
|
{
|
|
case 0x00:
|
|
_eeWriteConstMem8( (uptr)&PS2MEM_HW[mem&0xffff], mmreg);
|
|
break;
|
|
case 0x40:
|
|
if( IS_EECONSTREG(mmreg) ) {
|
|
if( !(g_cpuConstRegs[(mmreg>>16)&0x1f].UL[0] & 0x100) ) {
|
|
AND32ItoM( (uptr)&PS2MEM_HW[mem&0xfffc], ~0x100);
|
|
}
|
|
}
|
|
else {
|
|
_eeMoveMMREGtoR(EAX, mmreg);
|
|
TEST16ItoR(EAX, 0x100);
|
|
j8Ptr[5] = JNZ8(0);
|
|
AND32ItoM( (uptr)&PS2MEM_HW[mem&0xfffc], ~0x100);
|
|
x86SetJ8(j8Ptr[5]);
|
|
}
|
|
break;
|
|
}
|
|
return;
|
|
}
|
|
assert( (mem&0xff0f) != 0xf200 );
|
|
|
|
switch(mem&~3) {
|
|
case 0x1000f130:
|
|
case 0x1000f410:
|
|
case 0x1000f430:
|
|
break;
|
|
default:
|
|
#ifdef PCSX2_VIRTUAL_MEM
|
|
//NOTE: this might cause crashes, but is more correct
|
|
_eeWriteConstMem8((u32)PS2MEM_BASE + mem, mmreg);
|
|
#else
|
|
if (mem < 0x10010000)
|
|
{
|
|
_eeWriteConstMem8((uptr)&PS2MEM_HW[mem&0xffff], mmreg);
|
|
}
|
|
#endif
|
|
}
|
|
|
|
break;
|
|
}
|
|
}
|
|
|
|
#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] ); \
|
|
} \
|
|
} \
|
|
|
|
#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] ); \
|
|
} \
|
|
} \
|
|
|
|
void hwConstWrite16(u32 mem, int mmreg)
|
|
{
|
|
switch(mem&~3) {
|
|
CONSTWRITE_TIMERS(16)
|
|
case 0x10008000: // dma0 - vif0
|
|
recDmaExec16(VIF0, 0);
|
|
break;
|
|
|
|
case 0x10009000: // dma1 - vif1 - chcr
|
|
recDmaExec16(VIF1, 1);
|
|
break;
|
|
|
|
case 0x1000a000: // dma2 - gif
|
|
recDmaExec16(GIF, 2);
|
|
break;
|
|
case 0x1000b000: // dma3 - fromIPU
|
|
recDmaExec16(IPU0, 3);
|
|
break;
|
|
case 0x1000b400: // dma4 - toIPU
|
|
recDmaExec16(IPU1, 4);
|
|
break;
|
|
case 0x1000c000: // dma5 - sif0
|
|
//if (value == 0) psxSu32(0x30) = 0x40000;
|
|
recDmaExec16(SIF0, 5);
|
|
break;
|
|
case 0x1000c002:
|
|
//?
|
|
break;
|
|
case 0x1000c400: // dma6 - sif1
|
|
recDmaExec16(SIF1, 6);
|
|
break;
|
|
case 0x1000c800: // dma7 - sif2
|
|
recDmaExec16(SIF2, 7);
|
|
break;
|
|
case 0x1000c802:
|
|
//?
|
|
break;
|
|
case 0x1000d000: // dma8 - fromSPR
|
|
recDmaExec16(SPR0, 8);
|
|
break;
|
|
case 0x1000d400: // dma9 - toSPR
|
|
recDmaExec16(SPR1, 9);
|
|
break;
|
|
case 0x1000f592: // DMAC_ENABLEW
|
|
_eeWriteConstMem16((uptr)&PS2MEM_HW[0xf522], mmreg);
|
|
_eeWriteConstMem16((uptr)&PS2MEM_HW[0xf592], mmreg);
|
|
break;
|
|
case 0x1000f130:
|
|
case 0x1000f410:
|
|
case 0x1000f430:
|
|
break;
|
|
default:
|
|
if ((mem & 0xffffff0f) == 0x1000f200) {
|
|
u32 at = mem & 0xf0;
|
|
switch(at)
|
|
{
|
|
case 0x00:
|
|
_eeWriteConstMem16((uptr)&PS2MEM_HW[mem&0xffff], mmreg);
|
|
break;
|
|
case 0x20:
|
|
_eeWriteConstMem16OP((uptr)&PS2MEM_HW[mem&0xffff], mmreg, 1);
|
|
break;
|
|
case 0x30:
|
|
if( IS_EECONSTREG(mmreg) ) {
|
|
AND16ItoM((uptr)&PS2MEM_HW[mem&0xffff], ~g_cpuConstRegs[(mmreg>>16)&0x1f].UL[0]);
|
|
}
|
|
else {
|
|
NOT32R(mmreg&0xf);
|
|
AND16RtoM((uptr)&PS2MEM_HW[mem&0xffff], mmreg&0xf);
|
|
}
|
|
break;
|
|
case 0x40:
|
|
if( IS_EECONSTREG(mmreg) ) {
|
|
if( !(g_cpuConstRegs[(mmreg>>16)&0x1f].UL[0] & 0x100) ) {
|
|
AND16ItoM((uptr)&PS2MEM_HW[mem&0xffff], ~0x100);
|
|
}
|
|
else {
|
|
OR16ItoM((uptr)&PS2MEM_HW[mem&0xffff], 0x100);
|
|
}
|
|
}
|
|
else {
|
|
_eeMoveMMREGtoR(EAX, mmreg);
|
|
TEST16ItoR(EAX, 0x100);
|
|
j8Ptr[5] = JZ8(0);
|
|
OR16ItoM((uptr)&PS2MEM_HW[mem&0xffff], 0x100);
|
|
j8Ptr[6] = JMP8(0);
|
|
|
|
x86SetJ8( j8Ptr[5] );
|
|
AND16ItoM((uptr)&PS2MEM_HW[mem&0xffff], ~0x100);
|
|
|
|
x86SetJ8( j8Ptr[6] );
|
|
}
|
|
|
|
break;
|
|
case 0x60:
|
|
_eeWriteConstMem16((uptr)&PS2MEM_HW[mem&0xffff], 0);
|
|
break;
|
|
}
|
|
return;
|
|
}
|
|
|
|
#ifdef PCSX2_VIRTUAL_MEM
|
|
//NOTE: this might cause crashes, but is more correct
|
|
_eeWriteConstMem16((u32)PS2MEM_BASE + mem, mmreg);
|
|
#else
|
|
if (mem < 0x10010000)
|
|
{
|
|
_eeWriteConstMem16((uptr)&PS2MEM_HW[mem&0xffff], mmreg);
|
|
}
|
|
#endif
|
|
}
|
|
}
|
|
|
|
// 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] ); \
|
|
} \
|
|
} \
|
|
|
|
#define CONSTWRITE_CALLTIMER32(name, index, bit) { \
|
|
_recPushReg(mmreg); \
|
|
iFlushCall(0); \
|
|
PUSH32I(index); \
|
|
CALLFunc((uptr)name); \
|
|
ADD32ItoR(ESP, 8); \
|
|
} \
|
|
|
|
void hwConstWrite32(u32 mem, int mmreg)
|
|
{
|
|
//IPU regs
|
|
if ((mem>=0x10002000) && (mem<0x10003000)) {
|
|
//psHu32(mem) = value;
|
|
ipuConstWrite32(mem, mmreg);
|
|
return;
|
|
}
|
|
|
|
if ((mem>=0x10003800) && (mem<0x10003c00)) {
|
|
_recPushReg(mmreg);
|
|
iFlushCall(0);
|
|
PUSH32I(mem);
|
|
CALLFunc((uptr)vif0Write32);
|
|
ADD32ItoR(ESP, 8);
|
|
return;
|
|
}
|
|
if ((mem>=0x10003c00) && (mem<0x10004000)) {
|
|
_recPushReg(mmreg);
|
|
iFlushCall(0);
|
|
PUSH32I(mem);
|
|
CALLFunc((uptr)vif1Write32);
|
|
ADD32ItoR(ESP, 8);
|
|
return;
|
|
}
|
|
|
|
switch (mem) {
|
|
case 0x10000000: CONSTWRITE_CALLTIMER32(rcntWcount, 0, bit); break;
|
|
case 0x10000010: CONSTWRITE_CALLTIMER32(rcntWmode, 0, bit); break;
|
|
case 0x10000020: CONSTWRITE_CALLTIMER32(rcntWtarget, 0, bit); break;
|
|
case 0x10000030: CONSTWRITE_CALLTIMER32(rcntWhold, 0, bit); break;
|
|
|
|
case 0x10000800: CONSTWRITE_CALLTIMER32(rcntWcount, 1, bit); break;
|
|
case 0x10000810: CONSTWRITE_CALLTIMER32(rcntWmode, 1, bit); break;
|
|
case 0x10000820: CONSTWRITE_CALLTIMER32(rcntWtarget, 1, bit); break;
|
|
case 0x10000830: CONSTWRITE_CALLTIMER32(rcntWhold, 1, bit); break;
|
|
|
|
case 0x10001000: CONSTWRITE_CALLTIMER32(rcntWcount, 2, bit); break;
|
|
case 0x10001010: CONSTWRITE_CALLTIMER32(rcntWmode, 2, bit); break;
|
|
case 0x10001020: CONSTWRITE_CALLTIMER32(rcntWtarget, 2, bit); break;
|
|
|
|
case 0x10001800: CONSTWRITE_CALLTIMER32(rcntWcount, 3, bit); break;
|
|
case 0x10001810: CONSTWRITE_CALLTIMER32(rcntWmode, 3, bit); break;
|
|
case 0x10001820: CONSTWRITE_CALLTIMER32(rcntWtarget, 3, bit); break;
|
|
|
|
case GIF_CTRL:
|
|
|
|
_eeMoveMMREGtoR(EAX, mmreg);
|
|
|
|
iFlushCall(0);
|
|
TEST8ItoR(EAX, 1);
|
|
j8Ptr[5] = JZ8(0);
|
|
|
|
// reset GS
|
|
CALLFunc((uptr)gsGIFReset);
|
|
j8Ptr[6] = JMP8(0);
|
|
|
|
x86SetJ8( j8Ptr[5] );
|
|
AND32I8toR(EAX, 8);
|
|
MOV32RtoM((uptr)&PS2MEM_HW[mem&0xffff], EAX);
|
|
|
|
TEST16ItoR(EAX, 8);
|
|
j8Ptr[5] = JZ8(0);
|
|
OR8ItoM((uptr)&PS2MEM_HW[GIF_STAT&0xffff], 8);
|
|
j8Ptr[7] = JMP8(0);
|
|
|
|
x86SetJ8( j8Ptr[5] );
|
|
AND8ItoM((uptr)&PS2MEM_HW[GIF_STAT&0xffff], ~8);
|
|
x86SetJ8( j8Ptr[6] );
|
|
x86SetJ8( j8Ptr[7] );
|
|
return;
|
|
|
|
case GIF_MODE:
|
|
_eeMoveMMREGtoR(EAX, mmreg);
|
|
_eeWriteConstMem32((uptr)&PS2MEM_HW[mem&0xffff], mmreg);
|
|
AND8ItoM((uptr)&PS2MEM_HW[GIF_STAT&0xffff], ~5);
|
|
AND8ItoR(EAX, 5);
|
|
OR8RtoM((uptr)&PS2MEM_HW[GIF_STAT&0xffff], EAX);
|
|
return;
|
|
|
|
case GIF_STAT: // stat is readonly
|
|
return;
|
|
|
|
case 0x10008000: // dma0 - vif0
|
|
recDmaExec(VIF0, 0);
|
|
break;
|
|
|
|
case 0x10009000: // dma1 - vif1 - chcr
|
|
recDmaExec(VIF1, 1);
|
|
break;
|
|
|
|
case 0x1000a000: // dma2 - gif
|
|
recDmaExec(GIF, 2);
|
|
break;
|
|
|
|
case 0x1000b000: // dma3 - fromIPU
|
|
recDmaExec(IPU0, 3);
|
|
break;
|
|
case 0x1000b400: // dma4 - toIPU
|
|
recDmaExec(IPU1, 4);
|
|
break;
|
|
case 0x1000c000: // dma5 - sif0
|
|
//if (value == 0) psxSu32(0x30) = 0x40000;
|
|
recDmaExec(SIF0, 5);
|
|
break;
|
|
|
|
case 0x1000c400: // dma6 - sif1
|
|
recDmaExec(SIF1, 6);
|
|
break;
|
|
|
|
case 0x1000c800: // dma7 - sif2
|
|
recDmaExec(SIF2, 7);
|
|
break;
|
|
|
|
case 0x1000d000: // dma8 - fromSPR
|
|
recDmaExec(SPR0, 8);
|
|
break;
|
|
|
|
case 0x1000d400: // dma9 - toSPR
|
|
recDmaExec(SPR1, 9);
|
|
break;
|
|
|
|
case 0x1000e010: // DMAC_STAT
|
|
_eeMoveMMREGtoR(EAX, mmreg);
|
|
iFlushCall(0);
|
|
MOV32RtoR(ECX, EAX);
|
|
NOT32R(ECX);
|
|
AND16RtoM((uptr)&PS2MEM_HW[0xe010], ECX);
|
|
|
|
SHR32ItoR(EAX, 16);
|
|
XOR16RtoM((uptr)&PS2MEM_HW[0xe012], EAX);
|
|
|
|
MOV32MtoR(EAX, (uptr)&cpuRegs.CP0.n.Status.val);
|
|
AND32ItoR(EAX, 0x10807);
|
|
CMP32ItoR(EAX, 0x10801);
|
|
j8Ptr[5] = JNE8(0);
|
|
CALLFunc((uptr)cpuTestDMACInts);
|
|
|
|
x86SetJ8( j8Ptr[5] );
|
|
break;
|
|
|
|
case 0x1000f000: // INTC_STAT
|
|
_eeWriteConstMem32OP((uptr)&PS2MEM_HW[0xf000], mmreg, 2);
|
|
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);
|
|
|
|
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:
|
|
case 0x1000f410:
|
|
break;
|
|
|
|
case 0x1000f430://MCH_RICM: x:4|SA:12|x:5|SDEV:1|SOP:4|SBC:1|SDEV:5
|
|
|
|
//if ((((value >> 16) & 0xFFF) == 0x21) && (((value >> 6) & 0xF) == 1) && (((psHu32(0xf440) >> 7) & 1) == 0))//INIT & SRP=0
|
|
// rdram_sdevid = 0
|
|
_eeMoveMMREGtoR(EAX, mmreg);
|
|
MOV32RtoR(EDX, EAX);
|
|
MOV32RtoR(ECX, EAX);
|
|
SHR32ItoR(EAX, 6);
|
|
SHR32ItoR(EDX, 16);
|
|
AND32ItoR(EAX, 0xf);
|
|
AND32ItoR(EDX, 0xfff);
|
|
CMP32ItoR(EAX, 1);
|
|
j8Ptr[5] = JNE8(0);
|
|
CMP32ItoR(EDX, 0x21);
|
|
j8Ptr[6] = JNE8(0);
|
|
|
|
TEST32ItoM((uptr)&psHu32(0xf440), 0x80);
|
|
j8Ptr[7] = JNZ8(0);
|
|
|
|
// if SIO repeater is cleared, reset sdevid
|
|
MOV32ItoM((uptr)&rdram_sdevid, 0);
|
|
|
|
//kill the busy bit
|
|
x86SetJ8(j8Ptr[5]);
|
|
x86SetJ8(j8Ptr[6]);
|
|
x86SetJ8(j8Ptr[7]);
|
|
AND32ItoR(ECX, ~0x80000000);
|
|
MOV32RtoM((uptr)&psHu32(0xf430), ECX);
|
|
break;
|
|
|
|
case 0x1000f440://MCH_DRD:
|
|
_eeWriteConstMem32((uptr)&PS2MEM_HW[0xf440], mmreg);
|
|
break;
|
|
|
|
case 0x1000f590: // DMAC_ENABLEW
|
|
_eeWriteConstMem32((uptr)&PS2MEM_HW[0xf520], mmreg);
|
|
_eeWriteConstMem32((uptr)&PS2MEM_HW[0xf590], mmreg);
|
|
return;
|
|
|
|
default:
|
|
if ((mem & 0xffffff0f) == 0x1000f200) {
|
|
u32 at = mem & 0xf0;
|
|
switch(at)
|
|
{
|
|
case 0x00:
|
|
_eeWriteConstMem32((uptr)&PS2MEM_HW[mem&0xffff], mmreg);
|
|
break;
|
|
case 0x20:
|
|
_eeWriteConstMem32OP((uptr)&PS2MEM_HW[mem&0xffff], mmreg, 1);
|
|
break;
|
|
case 0x30:
|
|
_eeWriteConstMem32OP((uptr)&PS2MEM_HW[mem&0xffff], mmreg, 2);
|
|
break;
|
|
case 0x40:
|
|
if( IS_EECONSTREG(mmreg) ) {
|
|
if( !(g_cpuConstRegs[(mmreg>>16)&0x1f].UL[0] & 0x100) ) {
|
|
AND32ItoM( (uptr)&PS2MEM_HW[mem&0xfffc], ~0x100);
|
|
}
|
|
else {
|
|
OR32ItoM((uptr)&PS2MEM_HW[mem&0xffff], 0x100);
|
|
}
|
|
}
|
|
else {
|
|
_eeMoveMMREGtoR(EAX, mmreg);
|
|
TEST32ItoR(EAX, 0x100);
|
|
j8Ptr[5] = JZ8(0);
|
|
OR32ItoM((uptr)&PS2MEM_HW[mem&0xffff], 0x100);
|
|
j8Ptr[6] = JMP8(0);
|
|
|
|
x86SetJ8( j8Ptr[5] );
|
|
AND32ItoM((uptr)&PS2MEM_HW[mem&0xffff], ~0x100);
|
|
|
|
x86SetJ8( j8Ptr[6] );
|
|
}
|
|
|
|
break;
|
|
case 0x60:
|
|
MOV32ItoM((uptr)&PS2MEM_HW[mem&0xffff], 0);
|
|
break;
|
|
}
|
|
return;
|
|
}
|
|
|
|
#ifdef PCSX2_VIRTUAL_MEM
|
|
//NOTE: this might cause crashes, but is more correct
|
|
_eeWriteConstMem32((u32)PS2MEM_BASE + mem, mmreg);
|
|
#else
|
|
if (mem < 0x10010000)
|
|
{
|
|
_eeWriteConstMem32((uptr)&PS2MEM_HW[mem&0xffff], mmreg);
|
|
}
|
|
#endif
|
|
break;
|
|
}
|
|
}
|
|
|
|
void hwConstWrite64(u32 mem, int mmreg)
|
|
{
|
|
if ((mem>=0x10002000) && (mem<=0x10002030)) {
|
|
ipuConstWrite64(mem, mmreg);
|
|
return;
|
|
}
|
|
|
|
if ((mem>=0x10003800) && (mem<0x10003c00)) {
|
|
_recPushReg(mmreg);
|
|
iFlushCall(0);
|
|
PUSH32I(mem);
|
|
CALLFunc((uptr)vif0Write32);
|
|
ADD32ItoR(ESP, 8);
|
|
return;
|
|
}
|
|
if ((mem>=0x10003c00) && (mem<0x10004000)) {
|
|
_recPushReg(mmreg);
|
|
iFlushCall(0);
|
|
PUSH32I(mem);
|
|
CALLFunc((uptr)vif1Write32);
|
|
ADD32ItoR(ESP, 8);
|
|
return;
|
|
}
|
|
|
|
switch (mem) {
|
|
case GIF_CTRL:
|
|
_eeMoveMMREGtoR(EAX, mmreg);
|
|
|
|
iFlushCall(0);
|
|
TEST8ItoR(EAX, 1);
|
|
j8Ptr[5] = JZ8(0);
|
|
|
|
// reset GS
|
|
CALLFunc((uptr)gsGIFReset);
|
|
j8Ptr[6] = JMP8(0);
|
|
|
|
x86SetJ8( j8Ptr[5] );
|
|
AND32I8toR(EAX, 8);
|
|
MOV32RtoM((uptr)&PS2MEM_HW[mem&0xffff], EAX);
|
|
|
|
TEST16ItoR(EAX, 8);
|
|
j8Ptr[5] = JZ8(0);
|
|
OR8ItoM((uptr)&PS2MEM_HW[GIF_STAT&0xffff], 8);
|
|
j8Ptr[7] = JMP8(0);
|
|
|
|
x86SetJ8( j8Ptr[5] );
|
|
AND8ItoM((uptr)&PS2MEM_HW[GIF_STAT&0xffff], ~8);
|
|
x86SetJ8( j8Ptr[6] );
|
|
x86SetJ8( j8Ptr[7] );
|
|
return;
|
|
|
|
case GIF_MODE:
|
|
_eeMoveMMREGtoR(EAX, mmreg);
|
|
_eeWriteConstMem32((uptr)&PS2MEM_HW[mem&0xffff], mmreg);
|
|
|
|
AND8ItoM((uptr)&PS2MEM_HW[GIF_STAT&0xffff], ~5);
|
|
AND8ItoR(EAX, 5);
|
|
OR8RtoM((uptr)&PS2MEM_HW[GIF_STAT&0xffff], EAX);
|
|
break;
|
|
|
|
case GIF_STAT: // stat is readonly
|
|
return;
|
|
|
|
case 0x1000a000: // dma2 - gif
|
|
recDmaExec(GIF, 2);
|
|
break;
|
|
|
|
case 0x1000e010: // DMAC_STAT
|
|
_eeMoveMMREGtoR(EAX, mmreg);
|
|
|
|
iFlushCall(0);
|
|
MOV32RtoR(ECX, EAX);
|
|
NOT32R(ECX);
|
|
AND16RtoM((uptr)&PS2MEM_HW[0xe010], ECX);
|
|
|
|
SHR32ItoR(EAX, 16);
|
|
XOR16RtoM((uptr)&PS2MEM_HW[0xe012], EAX);
|
|
|
|
MOV32MtoR(EAX, (uptr)&cpuRegs.CP0.n.Status.val);
|
|
AND32ItoR(EAX, 0x10807);
|
|
CMP32ItoR(EAX, 0x10801);
|
|
j8Ptr[5] = JNE8(0);
|
|
CALLFunc((uptr)cpuTestDMACInts);
|
|
|
|
x86SetJ8( j8Ptr[5] );
|
|
break;
|
|
|
|
case 0x1000f590: // DMAC_ENABLEW
|
|
_eeWriteConstMem32((uptr)&PS2MEM_HW[0xf520], mmreg);
|
|
_eeWriteConstMem32((uptr)&PS2MEM_HW[0xf590], mmreg);
|
|
break;
|
|
|
|
case 0x1000f000: // INTC_STAT
|
|
_eeWriteConstMem32OP((uptr)&PS2MEM_HW[mem&0xffff], mmreg, 2);
|
|
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);
|
|
|
|
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:
|
|
case 0x1000f410:
|
|
case 0x1000f430:
|
|
break;
|
|
default:
|
|
|
|
_eeWriteConstMem64((uptr)PSM(mem), mmreg);
|
|
break;
|
|
}
|
|
}
|
|
|
|
void hwConstWrite128(u32 mem, int mmreg)
|
|
{
|
|
if (mem >= 0x10004000 && mem < 0x10008000) {
|
|
_eeWriteConstMem128((uptr)&s_TempFIFO[0], mmreg);
|
|
iFlushCall(0);
|
|
PUSH32I((uptr)&s_TempFIFO[0]);
|
|
PUSH32I(mem);
|
|
CALLFunc((uptr)WriteFIFO);
|
|
ADD32ItoR(ESP, 8);
|
|
return;
|
|
}
|
|
|
|
switch (mem) {
|
|
case 0x1000f590: // DMAC_ENABLEW
|
|
_eeWriteConstMem32((uptr)&PS2MEM_HW[0xf520], mmreg);
|
|
_eeWriteConstMem32((uptr)&PS2MEM_HW[0xf590], mmreg);
|
|
break;
|
|
case 0x1000f130:
|
|
case 0x1000f410:
|
|
case 0x1000f430:
|
|
break;
|
|
|
|
default:
|
|
|
|
#ifdef PCSX2_VIRTUAL_MEM
|
|
_eeWriteConstMem128( PS2MEM_BASE_+mem, mmreg);
|
|
#else
|
|
if (mem < 0x10010000)
|
|
_eeWriteConstMem128((uptr)&PS2MEM_HW[mem&0xffff], mmreg);
|
|
#endif
|
|
break;
|
|
}
|
|
}
|
|
|
|
#endif // PCSX2_NORECBUILD
|