Protect manual pages again after running code in them for a while, should speed up some games and probably not significantly slow down any.

Related new speed hack, fast-forward a block starting at 0x81FC0 which some games (FFX) run a lot.  This block is also excluded from the previous feature.
Rearrange configuration file and speed hack dialog.

git-svn-id: http://pcsx2.googlecode.com/svn/trunk@1040 96395faa-99c1-11dd-bbfe-3dabce05a288
This commit is contained in:
sudonim1 2009-04-21 23:30:06 +00:00
parent bfe128cd41
commit d7341d5b69
13 changed files with 135 additions and 73 deletions

View File

@ -58,12 +58,6 @@ extern SessionOverrideFlags g_Session;
#define CHECK_MULTIGS (Config.Options&PCSX2_GSMULTITHREAD)
#define CHECK_EEREC (!g_Session.ForceDisableEErec && Config.Options&PCSX2_EEREC)
//------------ SPEED/MISC HACKS!!! ---------------
#define CHECK_EE_CYCLERATE (Config.Hacks & 0x03)
#define CHECK_IOP_CYCLERATE (Config.Hacks & 0x08)
#define CHECK_WAITCYCLE_HACK (Config.Hacks & 0x10)
#define CHECK_INTC_STAT_HACK (Config.Hacks & 0x20)
#define CHECK_ESCAPE_HACK (Config.Hacks & 0x400)
//------------ SPECIAL GAME FIXES!!! ---------------
#define CHECK_VUADDSUBHACK (Config.GameFixes & 0x1) // Special Fix for Tri-ace games, they use an encryption algorithm that requires VU addi opcode to be bit-accurate.
#define CHECK_FPUCOMPAREHACK (Config.GameFixes & 0x4) // Special Fix for Digimon Rumble Arena 2, fixes spinning/hanging on intro-menu.
@ -136,8 +130,15 @@ public:
int Mdec;
int Patch;
int CustomFps;
int Hacks;
int VUCycleHack;
struct Hacks_t {
int EECycleRate;
bool IOPCycleDouble;
bool WaitCycleExt;
bool INTCSTATSlow;
int VUCycleSteal;
bool IdleLoopFF;
bool ESCExits; // this is a hack!?
} Hacks;
int GameFixes;
int CustomFrameSkip;
int CustomConsecutiveFrames;

View File

@ -100,8 +100,17 @@ int LoadConfig()
GetValuel("varLog", varLog);
#endif
GetValuel("Options", Config.Options);
GetValuel("Hacks", Config.Hacks);
GetValuel("VUCycleHack", Config.VUCycleHack);
GetValuel("EECycleRate", Config.Hacks.EECycleRate);
if (Config.Hacks.EECycleRate > 2)
Config.Hacks.EECycleRate = 2;
GetValuel("IOPCycleDouble", Config.Hacks.IOPCycleDouble);
GetValuel("WaitCycleExt", Config.Hacks.WaitCycleExt);
GetValuel("INTCSTATSlow", Config.Hacks.INTCSTATSlow);
GetValuel("VUCycleSteal", Config.Hacks.VUCycleSteal);
GetValuel("IdleLoopFF", Config.Hacks.IdleLoopFF);
GetValuel("ESCExits", Config.Hacks.ESCExits);
if (Config.VUCycleHack < 0 || Config.VUCycleHack > 4)
Config.VUCycleHack = 0;
GetValuel("Fixes", Config.GameFixes);
@ -165,8 +174,14 @@ void SaveConfig()
SetValuel("Options", Config.Options);
SetValuel("Hacks", Config.Hacks);
SetValuel("VUCycleHack", Config.VUCycleHack);
SetValuel("EECycleRate", Config.Hacks.EECycleRate);
SetValuel("IOPCycleDouble", Config.Hacks.IOPCycleDouble);
SetValuel("WaitCycleExt", Config.Hacks.WaitCycleExt);
SetValuel("INTCSTATSlow", Config.Hacks.INTCSTATSlow);
SetValuel("VUCycleSteal", Config.Hacks.VUCycleSteal);
SetValuel("IdleLoopFF", Config.Hacks.IdleLoopFF);
SetValuel("ESCExits", Config.Hacks.ESCExits);
SetValuel("Fixes", Config.GameFixes);
SetValuel("Patch", Config.Patch);

View File

@ -738,8 +738,8 @@ void memReset()
_ext_memWrite8<1>, _ext_memWrite16<1>, hwWrite32_page_0E, hwWrite64_page_0E, hwWrite128_generic
);
vtlbMemR32FP* page0F32( CHECK_INTC_STAT_HACK ? hwRead32_page_0F_INTC_HACK : hwRead32_page_0F );
vtlbMemR64FP* page0F64( CHECK_INTC_STAT_HACK ? hwRead64_generic_INTC_HACK : hwRead64_generic );
vtlbMemR32FP* page0F32( Config.Hacks.INTCSTATSlow ? hwRead32_page_0F_INTC_HACK : hwRead32_page_0F );
vtlbMemR64FP* page0F64( Config.Hacks.INTCSTATSlow ? hwRead64_generic_INTC_HACK : hwRead64_generic );
hw_by_page[0xf] = vtlb_RegisterHandler(
_ext_memRead8<1>, _ext_memRead16<1>, page0F32, page0F64, hwRead128_generic,
@ -820,6 +820,7 @@ void mmap_MarkCountedRamPage(void* ptr,u32 vaddr)
u32 offset=((u8*)ptr-psM);
offset>>=12;
psMPWC[(offset/32)] &= ~(1<<(offset&31));
for (u32 i=0;i<psMPWVA[offset].size();i++)
{

View File

@ -82,11 +82,11 @@ void cpuReset()
g_nextBranchCycle = cpuRegs.cycle + 4;
EEsCycle = 0;
EEoCycle = cpuRegs.cycle;
eeWaitCycles = CHECK_WAITCYCLE_HACK ? 3072 : 768;
eeWaitCycles = Config.Hacks.WaitCycleExt ? 3072 : 768;
// Cyclerate hacks effectively speed up the rate of event tests, so we can safely boost
// the WaitCycles value here for x2 and x3 modes:
if( CHECK_EE_CYCLERATE > 1 )
if( Config.Hacks.EECycleRate > 1 )
eeWaitCycles += 1024;
hwReset();

View File

@ -41,16 +41,17 @@ BOOL APIENTRY HacksProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
switch (message) {
case WM_INITDIALOG:
CheckRadioButton( hDlg, IDC_EESYNC_DEFAULT, IDC_EESYNC3, IDC_EESYNC_DEFAULT + CHECK_EE_CYCLERATE );
CheckRadioButton( hDlg, IDC_EESYNC_DEFAULT, IDC_EESYNC3, IDC_EESYNC_DEFAULT + Config.Hacks.EECycleRate );
if(CHECK_IOP_CYCLERATE) CheckDlgButton(hDlg, IDC_IOPSYNC, TRUE);
if(CHECK_WAITCYCLE_HACK) CheckDlgButton(hDlg, IDC_WAITCYCLES, TRUE);
if(CHECK_INTC_STAT_HACK) CheckDlgButton(hDlg, IDC_INTCSTATHACK, TRUE);
if(CHECK_ESCAPE_HACK) CheckDlgButton(hDlg, IDC_ESCHACK, TRUE);
if(Config.Hacks.IOPCycleDouble) CheckDlgButton(hDlg, IDC_IOPSYNC, TRUE);
if(Config.Hacks.WaitCycleExt) CheckDlgButton(hDlg, IDC_WAITCYCLES, TRUE);
if(Config.Hacks.INTCSTATSlow) CheckDlgButton(hDlg, IDC_INTCSTATHACK, TRUE);
if(Config.Hacks.IdleLoopFF) CheckDlgButton(hDlg, IDC_IDLELOOPFF, TRUE);
if(Config.Hacks.ESCExits) CheckDlgButton(hDlg, IDC_ESCHACK, TRUE);
SendDlgItemMessage(hDlg, IDC_VUCYCLE, TBM_SETRANGE, TRUE, MAKELONG(0, 4));
CheckVUCycleHack(hDlg, Config.VUCycleHack);
SendDlgItemMessage(hDlg, IDC_VUCYCLE, TBM_SETPOS, TRUE, Config.VUCycleHack);
CheckVUCycleHack(hDlg, Config.Hacks.VUCycleSteal);
SendDlgItemMessage(hDlg, IDC_VUCYCLE, TBM_SETPOS, TRUE, Config.Hacks.VUCycleSteal);
return TRUE;
@ -73,31 +74,32 @@ BOOL APIENTRY HacksProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
case IDOK:
{
int newhacks = 0;
for( int i=1; i<4; i++ )
PcsxConfig::Hacks_t newhacks;
newhacks.EECycleRate = 0;
for( int i=1; i<3; i++ )
{
if( IsDlgButtonChecked(hDlg, IDC_EESYNC_DEFAULT+i) )
{
newhacks = i;
newhacks.EECycleRate = i;
break;
}
}
newhacks |= IsDlgButtonChecked(hDlg, IDC_IOPSYNC) << 3;
newhacks |= IsDlgButtonChecked(hDlg, IDC_WAITCYCLES) << 4;
newhacks |= IsDlgButtonChecked(hDlg, IDC_INTCSTATHACK) << 5;
newhacks |= IsDlgButtonChecked(hDlg, IDC_ESCHACK) << 10;
int newvucyclehack = SendDlgItemMessage(hDlg, IDC_VUCYCLE, TBM_GETPOS, 0, 0);
CheckVUCycleHack(hDlg, newvucyclehack);
newhacks.IOPCycleDouble = IsDlgButtonChecked(hDlg, IDC_IOPSYNC);
newhacks.WaitCycleExt = IsDlgButtonChecked(hDlg, IDC_WAITCYCLES);
newhacks.INTCSTATSlow = IsDlgButtonChecked(hDlg, IDC_INTCSTATHACK);
newhacks.ESCExits = IsDlgButtonChecked(hDlg, IDC_ESCHACK);
newhacks.IdleLoopFF = IsDlgButtonChecked(hDlg, IDC_IDLELOOPFF);
newhacks.VUCycleSteal = SendDlgItemMessage(hDlg, IDC_VUCYCLE, TBM_GETPOS, 0, 0);
CheckVUCycleHack(hDlg, newhacks.VUCycleSteal);
EndDialog(hDlg, TRUE);
if( newhacks != Config.Hacks || newvucyclehack != Config.VUCycleHack)
if(memcmp(&newhacks, &Config.Hacks, sizeof(newhacks)))
{
SysRestorableReset();
Config.Hacks = newhacks;
Config.VUCycleHack = newvucyclehack;
SaveConfig();
}
}

View File

@ -442,7 +442,7 @@ namespace HostGui
}
#endif
if( CHECK_ESCAPE_HACK )
if( Config.Hacks.ESCExits )
{
g_EmulationInProgress = false;
DestroyWindow( gApp.hWnd );

View File

@ -21,7 +21,7 @@
#include "Common.h"
#include "Paths.h"
static const u32 IniVersion = 101;
static const u32 IniVersion = 102;
const char* g_CustomConfigFile;
char g_WorkingFolder[g_MaxPath]; // Working folder at application startup
@ -222,10 +222,19 @@ void IniFile::DoConfig( PcsxConfig& Conf )
Entry( "sseVUMXCSR", Conf.sseVUMXCSR, DEFAULT_sseVUMXCSR );
Entry( "eeOptions", Conf.eeOptions, DEFAULT_eeOptions );
Entry( "vuOptions", Conf.vuOptions, DEFAULT_vuOptions );
Entry( "SpeedHacks", Conf.Hacks );
Entry( "VUCycleHack", Conf.VUCycleHack, 0 );
if (Conf.VUCycleHack < 0 || Conf.VUCycleHack > 4)
Conf.VUCycleHack = 0;
SetCurrentSection("Hacks");
Entry("EECycleRate", Config.Hacks.EECycleRate);
if (Config.Hacks.EECycleRate > 2)
Config.Hacks.EECycleRate = 2;
Entry("IOPCycleDouble", Config.Hacks.IOPCycleDouble);
Entry("WaitCycleExt", Config.Hacks.WaitCycleExt);
Entry("INTCSTATSlow", Config.Hacks.INTCSTATSlow);
Entry("VUCycleSteal", Config.Hacks.VUCycleSteal);
Entry("IdleLoopFF", Config.Hacks.IdleLoopFF);
if (Conf.Hacks.VUCycleSteal < 0 || Conf.Hacks.VUCycleSteal > 4)
Conf.Hacks.VUCycleSteal = 0;
Entry("ESCExits", Config.Hacks.ESCExits);
}
//////////////////////////////////////////////////////////////////////////////////////////

View File

@ -352,28 +352,29 @@ BEGIN
CONTROL "Default Cycle Rate",IDC_EESYNC_DEFAULT,"Button",BS_AUTORADIOBUTTON,13,44,87,10
CONTROL "Use x1.5 Cycle Rate",IDC_EESYNC1,"Button",BS_AUTORADIOBUTTON,13,79,87,10
CONTROL "Use x2 Cycle Rate",IDC_EESYNC2,"Button",BS_AUTORADIOBUTTON,13,113,83,10
CONTROL "Use x3 Cycle Rate",IDC_EESYNC3,"Button",BS_AUTORADIOBUTTON,13,147,80,10
CONTROL "Enable IOP x2 Cycle Rate",IDC_IOPSYNC,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,174,88,98,10
CONTROL "WaitCycles Sync Hack",IDC_WAITCYCLES,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,174,127,90,10
CONTROL "Escape Hack - Use Esc key to fully exit PCSX2.",IDC_ESCHACK,
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,234,180,10
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,13,238,180,10
DEFPUSHBUTTON "OK",IDOK,217,242,50,14
PUSHBUTTON "Cancel",IDCANCEL,278,242,50,14
CTEXT "These hacks will speed up emulation but reduce emulation compatibility or cause visual errors. If you have problems, disable all these and try again!",IDC_HACKDESC,18,7,286,19
GROUPBOX "EmotionEngine (EE) Sync Hacks",IDC_STATIC,7,31,159,185
GROUPBOX "Miscellaneous",IDC_STATIC,7,220,194,33
LTEXT "Important: X2 and X3 sync hacks *will* cause choppy/skippy audio on many FMV movies.",IDC_STATIC,20,188,137,25
LTEXT "Known to work well with a couple games, namely Shadow of the Colossus (but breaks most other games).",IDC_STATIC,25,158,133,28
GROUPBOX "EmotionEngine (EE) Sync Hacks",IDC_STATIC,7,31,159,143
GROUPBOX "Miscellaneous",IDC_STATIC,7,223,194,33
LTEXT "Important: the X2 sync hack *will* cause choppy/skippy audio on many FMV movies.",IDC_STATIC,13,149,137,22
LTEXT "Big speedup! Works well with many games.",IDC_STATIC,25,124,125,19
LTEXT "Most compatible option - recommended for everyone with high-end machines.",IDC_STATIC,25,55,136,19
LTEXT "Small speedup and works well with most games.",IDC_STATIC,186,100,134,22
LTEXT "Small speedup. Works well with most games, but may cause certain games to crash or freeze up during bootup or stage changes.",IDC_STATIC,186,139,141,39
LTEXT "Moderate speedup and works well with most games.",IDC_STATIC,25,90,129,19
CONTROL "INTC Sync Hack (experimental)",IDC_INTCSTATHACK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,174,43,127,10
CONTROL "INTC Sync Hack",IDC_INTCSTATHACK,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,174,43,127,10
LTEXT "Huge speedup in many games, and a pretty high compatibility rate (some games still work better with EE sync hacks).",IDC_STATIC,186,55,140,28
CONTROL "",IDC_VUCYCLE,"msctls_trackbar32",TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,174,176,36,15
LTEXT "This space intentionally left blank",IDC_VUCYCLEDESC,186,194,142,30
LTEXT "VU Cycle Stealing (experimental)",IDC_STATIC,210,180,105,8
CONTROL "",IDC_VUCYCLE,"msctls_trackbar32",TBS_BOTH | TBS_NOTICKS | WS_TABSTOP,13,178,36,15
LTEXT "This space intentionally left blank",IDC_VUCYCLEDESC,25,196,142,24
LTEXT "VU Cycle Stealing (experimental)",IDC_STATIC,49,183,105,8
CONTROL "Idle Loop Fast-Forward (experimental)",IDC_IDLELOOPFF,
"Button",BS_AUTOCHECKBOX | WS_TABSTOP,174,179,139,10
LTEXT "Speedup for a few games, including FFX with no known side effects. More later.",IDC_STATIC,186,193,142,26
END

View File

@ -275,6 +275,7 @@
#define IDC_SLIDER1 1327
#define IDC_VUCYCLE 1327
#define IDC_VUCYCLEDESC 1328
#define IDC_IDLELOOPFF 1330
#define IDC_CPULOG 1500
#define IDC_MEMLOG 1501
#define IDC_HWLOG 1502
@ -408,7 +409,7 @@
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 141
#define _APS_NEXT_COMMAND_VALUE 40018
#define _APS_NEXT_CONTROL_VALUE 1329
#define _APS_NEXT_CONTROL_VALUE 1331
#define _APS_NEXT_SYMED_VALUE 104
#endif
#endif

View File

@ -800,7 +800,7 @@ void psxSetBranchImm( u32 imm )
static __forceinline u32 psxScaleBlockCycles()
{
return s_psxBlockCycles * (CHECK_IOP_CYCLERATE ? 2 : 1);
return s_psxBlockCycles * (Config.Hacks.IOPCycleDouble ? 2 : 1);
}
static void iPsxBranchTest(u32 newpc, u32 cpuBranch)

View File

@ -2297,8 +2297,10 @@ void SuperVUCleanupProgram(u32 startpc, int vuindex)
VU->cycle += s_TotalVUCycles;
//VU cycle stealing hack, 3000 cycle maximum so it doesn't get out of hand
if (s_TotalVUCycles < 3000) cpuRegs.cycle += s_TotalVUCycles * Config.VUCycleHack;
else cpuRegs.cycle += 3000 * Config.VUCycleHack;
if (s_TotalVUCycles < 3000)
cpuRegs.cycle += s_TotalVUCycles * Config.Hacks.VUCycleSteal;
else
cpuRegs.cycle += 3000 * Config.Hacks.VUCycleSteal;
if( (int)s_writeQ > 0 ) VU->VI[REG_Q] = VU->q;
if( (int)s_writeP > 0 ) {

View File

@ -48,6 +48,8 @@
#include "NakedAsm.h"
using namespace x86Emitter;
using namespace R5900;
// used to disable register freezing during cpuBranchTests (registers
@ -92,6 +94,7 @@ static BASEBLOCK* s_pCurBlock = NULL;
static BASEBLOCKEX* s_pCurBlockEx = NULL;
static u32 s_nEndBlock = 0; // what pc the current block ends
static u32 s_nHasDelay = 0;
static bool s_nBlockFF;
// save states for branches
GPR_reg64 s_saveConstRegs[32];
@ -1071,7 +1074,7 @@ u32 eeScaleBlockCycles()
// caused by sync hacks and such, since games seem to care a lot more about
// these small blocks having accurate cycle counts.
if( s_nBlockCycles <= (5<<3) || (CHECK_EE_CYCLERATE == 0) )
if( s_nBlockCycles <= (5<<3) || (Config.Hacks.EECycleRate == 0) )
return s_nBlockCycles >> 3;
uint scalarLow, scalarMid, scalarHigh;
@ -1079,7 +1082,7 @@ u32 eeScaleBlockCycles()
// Note: larger blocks get a smaller scalar, to help keep
// them from becoming "too fat" and delaying branch tests.
switch( CHECK_EE_CYCLERATE )
switch( Config.Hacks.EECycleRate )
{
case 0: return s_nBlockCycles >> 3;
@ -1147,19 +1150,27 @@ static void iBranchTest(u32 newpc, bool noDispatch)
// Equiv code to:
// cpuRegs.cycle += blockcycles;
// if( cpuRegs.cycle > g_nextBranchCycle ) { DoEvents(); }
MOV32MtoR(EAX, (uptr)&cpuRegs.cycle);
ADD32ItoR(EAX, eeScaleBlockCycles());
MOV32RtoM((uptr)&cpuRegs.cycle, EAX); // update cycles
SUB32MtoR(EAX, (uptr)&g_nextBranchCycle);
if (!noDispatch) {
if (newpc == 0xffffffff)
JS32((uptr)DispatcherReg - ( (uptr)x86Ptr + 6 ));
else
iBranch(newpc, 1);
if (Config.Hacks.IdleLoopFF && s_nBlockFF) {
xMOV(eax, ptr32[&g_nextBranchCycle]);
xADD(ptr32[&cpuRegs.cycle], eeScaleBlockCycles());
xCMP(eax, ptr32[&cpuRegs.cycle]);
xCMOVL(eax, ptr32[&cpuRegs.cycle]);
xMOV(ptr32[&cpuRegs.cycle], eax);
RET();
} else {
MOV32MtoR(EAX, (uptr)&cpuRegs.cycle);
ADD32ItoR(EAX, eeScaleBlockCycles());
MOV32RtoM((uptr)&cpuRegs.cycle, EAX); // update cycles
SUB32MtoR(EAX, (uptr)&g_nextBranchCycle);
if (!noDispatch) {
if (newpc == 0xffffffff)
JS32((uptr)DispatcherReg - ( (uptr)x86Ptr + 6 ));
else
iBranch(newpc, 1);
}
RET();
}
RET();
}
static void checkcodefn()
@ -1355,6 +1366,13 @@ void __fastcall dyna_block_discard(u32 start,u32 sz)
Cpu->Clear(start,sz);
}
void __fastcall dyna_block_reset(u32 start,u32 sz)
{
DevCon::WriteLn("dyna_block_reset %08X , count %d", params start,sz);
Cpu->Clear(start & ~0xfffUL, 0x400);
mmap_MarkCountedRamPage(PSM(start), start & ~0xfffUL);
}
void recRecompile( const u32 startpc )
{
u32 i = 0;
@ -1384,6 +1402,10 @@ void recRecompile( const u32 startpc )
x86Align(16);
recPtr = x86Ptr;
s_nBlockFF = false;
if (HWADDR(startpc) == 0x81fc0)
s_nBlockFF = true;
s_pCurBlock = PC_GETBLOCK(startpc);
assert(s_pCurBlock->GetFnptr() == (uptr)JITCompile
@ -1695,9 +1717,10 @@ StartRecomp:
iDumpBlock(startpc, recPtr);
#endif
static u16 manual_page[Ps2MemSize::Base >> 12];
u32 sz=(s_nEndBlock-startpc)>>2;
u32 inpage_ptr=startpc;
u32 inpage_ptr=HWADDR(startpc);
u32 inpage_sz=sz*4;
while(inpage_sz)
@ -1708,12 +1731,14 @@ StartRecomp:
if(PageType!=-1)
{
if (PageType==0)
if (PageType==0) {
mmap_MarkCountedRamPage(PSM(inpage_ptr),inpage_ptr&~0xFFF);
manual_page[inpage_ptr >> 12] = 0;
}
else
{
MOV32ItoR(ECX, startpc);
MOV32ItoR(EDX, sz);
MOV32ItoR(ECX, inpage_ptr);
MOV32ItoR(EDX, pgsz);
u32 lpc=inpage_ptr;
u32 stg=pgsz;
@ -1726,6 +1751,11 @@ StartRecomp:
stg-=4;
lpc+=4;
}
if (startpc != 0x81fc0) {
xADD(ptr16[&manual_page[inpage_ptr >> 12]], 1);
iJccKnownTarget(Jcc_Carry, dyna_block_reset);
}
DbgCon::WriteLn("Manual block @ %08X : %08X %d %d %d %d", params
startpc,inpage_ptr,pgsz,0x1000-inpage_offs,inpage_sz,sz*4);
}

View File

@ -367,7 +367,7 @@ void vtlb_DynGenRead32_Const( u32 bits, bool sign, u32 addr_const )
}
// Shortcut for the INTC_STAT register, which many games like to spin on heavily.
if( (bits == 32) && !CHECK_INTC_STAT_HACK && (paddr == INTC_STAT) )
if( (bits == 32) && !Config.Hacks.INTCSTATSlow && (paddr == INTC_STAT) )
{
MOV32MtoR( EAX, (uptr)&psHu32( INTC_STAT ) );
}