From 66733f5a6dd795ed7a7f2a160ba34aba602aa8a3 Mon Sep 17 00:00:00 2001 From: "Jake.Stine" Date: Fri, 30 Jan 2009 14:02:39 +0000 Subject: [PATCH] Bugfix for emu crash after deleting the ini file. Added more correct support for hwWrite16 to counters registers (hwWrite16s to the counters were being completely ignored until now) Added x86AlignExecutable() to the emitter -- generates an executable instruction to pad an area to a given alignment. It's not used yet but could be useful as an optimization in some rare cases in the future. git-svn-id: http://pcsx2-playground.googlecode.com/svn/trunk@659 a6443dda-0b58-4228-96e9-037be469359c --- pcsx2/Hw.cpp | 94 ++++++++++++++++++++++++++++--------- pcsx2/Linux/memzero.h | 2 +- pcsx2/windows/ConfigDlg.cpp | 2 +- pcsx2/windows/WinMain.cpp | 4 +- pcsx2/x86/ix86/ix86.cpp | 33 +++++++++++++ pcsx2/x86/ix86/ix86.h | 2 + 6 files changed, 112 insertions(+), 25 deletions(-) diff --git a/pcsx2/Hw.cpp b/pcsx2/Hw.cpp index 96f3ac50b3..2181b5db8f 100644 --- a/pcsx2/Hw.cpp +++ b/pcsx2/Hw.cpp @@ -77,31 +77,61 @@ __forceinline u8 hwRead8(u32 mem) { u8 ret; - if( mem >= 0x10000000 && mem < 0x10008000 ) + if( mem >= 0x10002000 && mem < 0x10008000 ) DevCon::Notice("hwRead8 to %x", params mem); SPR_LOG("Hardware read 8bit at %lx, ret %lx\n", mem, psHu8(mem)); -// switch (mem) { -// default: - if ((mem & 0xffffff0f) == 0x1000f200) { - if(mem == 0x1000f260) ret = 0; - else if(mem == 0x1000F240) { - ret = psHu32(mem); - //psHu32(mem) &= ~0x4000; - } - else ret = psHu32(mem); - return (u8)ret; - } - - if (mem < 0x10010000) + switch (mem) { - ret = psHu8(mem); + case 0x10000000: ret = (u8)rcntRcount(0); break; + case 0x10000010: ret = (u8)counters[0].modeval; break; + case 0x10000020: ret = (u8)counters[0].target; break; + case 0x10000030: ret = (u8)counters[0].hold; break; + case 0x10000001: ret = (u8)(rcntRcount(0)>>8); break; + case 0x10000011: ret = (u8)(counters[0].modeval>>8); break; + case 0x10000021: ret = (u8)(counters[0].target>>8); break; + case 0x10000031: ret = (u8)(counters[0].hold>>8); break; + + case 0x10000800: ret = (u8)rcntRcount(1); break; + case 0x10000810: ret = (u8)counters[1].modeval; break; + case 0x10000820: ret = (u8)counters[1].target; break; + case 0x10000830: ret = (u8)counters[1].hold; break; + case 0x10000801: ret = (u8)(rcntRcount(1)>>8); break; + case 0x10000811: ret = (u8)(counters[1].modeval>>8); break; + case 0x10000821: ret = (u8)(counters[1].target>>8); break; + case 0x10000831: ret = (u8)(counters[1].hold>>8); break; + + case 0x10001000: ret = (u8)rcntRcount(2); break; + case 0x10001010: ret = (u8)counters[2].modeval; break; + case 0x10001020: ret = (u8)counters[2].target; break; + case 0x10001001: ret = (u8)(rcntRcount(2)>>8); break; + case 0x10001011: ret = (u8)(counters[2].modeval>>8); break; + case 0x10001021: ret = (u8)(counters[2].target>>8); break; + + case 0x10001800: ret = (u8)rcntRcount(3); break; + case 0x10001810: ret = (u8)counters[3].modeval; break; + case 0x10001820: ret = (u8)counters[3].target; break; + case 0x10001801: ret = (u8)(rcntRcount(3)>>8); break; + case 0x10001811: ret = (u8)(counters[3].modeval>>8); break; + case 0x10001821: ret = (u8)(counters[3].target>>8); break; + + default: + if ((mem & 0xffffff0f) == 0x1000f200) + { + if(mem == 0x1000f260) ret = 0; + else if(mem == 0x1000F240) { + ret = psHu32(mem); + //psHu32(mem) &= ~0x4000; + } + else ret = psHu32(mem); + return (u8)ret; + } + + ret = psHu8(mem); + HW_LOG("Unknown Hardware Read 8 at %x\n",mem); + break; } - else ret = 0; - HW_LOG("Unknown Hardware Read 8 at %x\n",mem); -// break; -// } return ret; } @@ -391,7 +421,7 @@ int sio_count; void hwWrite8(u32 mem, u8 value) { #ifdef PCSX2_DEVBUILD - if( mem >= 0x10000000 && mem < 0x10008000 ) + if( mem >= 0x10002000 && mem < 0x10008000 ) SysPrintf("hwWrite8 to %x\n", mem); #endif @@ -518,10 +548,30 @@ void hwWrite8(u32 mem, u8 value) { __forceinline void hwWrite16(u32 mem, u16 value) { #ifdef PCSX2_DEVBUILD - if( mem >= 0x10000000 && mem < 0x10008000 ) + if( mem >= 0x10002000 && mem < 0x10008000 ) SysPrintf("hwWrite16 to %x\n", mem); #endif - switch(mem) { + + switch(mem) + { + case 0x10000000: rcntWcount(0, value); break; + case 0x10000010: rcntWmode(0, value); break; + case 0x10000020: rcntWtarget(0, value); break; + case 0x10000030: rcntWhold(0, value); break; + + case 0x10000800: rcntWcount(1, value); break; + case 0x10000810: rcntWmode(1, value); break; + case 0x10000820: rcntWtarget(1, value); break; + case 0x10000830: rcntWhold(1, value); break; + + case 0x10001000: rcntWcount(2, value); break; + case 0x10001010: rcntWmode(2, value); break; + case 0x10001020: rcntWtarget(2, value); break; + + case 0x10001800: rcntWcount(3, value); break; + case 0x10001810: rcntWmode(3, value); break; + case 0x10001820: rcntWtarget(3, value); break; + case 0x10008000: // dma0 - vif0 DMA_LOG("VIF0dma %lx\n", value); DmaExec16(dmaVIF0, mem, value); diff --git a/pcsx2/Linux/memzero.h b/pcsx2/Linux/memzero.h index 8c14e5967e..f3f66557ca 100644 --- a/pcsx2/Linux/memzero.h +++ b/pcsx2/Linux/memzero.h @@ -62,7 +62,7 @@ template< u16 data, typename T > static __forceinline void memset16_obj( T& obj ) { if( (sizeof(T) & 0x3) != 0 ) - _memset_16_unaligned( &obj, data, sizeof( T ) ) + _memset_16_unaligned( &obj, data, sizeof( T ) ); else memset32_obj( obj ); } diff --git a/pcsx2/windows/ConfigDlg.cpp b/pcsx2/windows/ConfigDlg.cpp index 6468a97c11..536cb3f937 100644 --- a/pcsx2/windows/ConfigDlg.cpp +++ b/pcsx2/windows/ConfigDlg.cpp @@ -298,7 +298,7 @@ void OnOK(HWND hW) { SaveConfig(); SysRestorableReset(); - ResetPlugins(); + ReleasePlugins(); } diff --git a/pcsx2/windows/WinMain.cpp b/pcsx2/windows/WinMain.cpp index 4004a41496..84da958a0c 100644 --- a/pcsx2/windows/WinMain.cpp +++ b/pcsx2/windows/WinMain.cpp @@ -671,7 +671,9 @@ LRESULT WINAPI MainWndProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) case ID_CONFIG_CONFIGURE: Pcsx2Configure(hWnd); - ReleasePlugins(); + + // Configure may unload plugins if the user changes settings, so reload + // them here. If they weren't unloaded these functions do nothing. LoadPlugins(); return FALSE; diff --git a/pcsx2/x86/ix86/ix86.cpp b/pcsx2/x86/ix86/ix86.cpp index 7b819bfc27..c020ee837e 100644 --- a/pcsx2/x86/ix86/ix86.cpp +++ b/pcsx2/x86/ix86/ix86.cpp @@ -258,6 +258,39 @@ __forceinline void x86Align( int bytes ) x86Ptr = (u8*)( ( (uptr)x86Ptr + bytes - 1) & ~( bytes - 1 ) ); } +//////////////////////////////////////////////////// +// Generates executable code to align to the given alignment (could be useful for the second leg +// of if/else conditionals, which usually fall through a jump target label). +void x86AlignExecutable( int align ) +{ + uptr newx86 = ( (uptr)x86Ptr + align - 1) & ~( align - 1 ); + uptr bytes = ( newx86 - (uptr)x86Ptr ); + + switch( bytes ) + { + case 0: break; + + case 1: NOP(); break; + case 2: MOV32RtoR( ESI, ESI ); break; + case 3: write8(0x08D); write8(0x024); write8(0x024); break; + case 5: NOP(); // falls through to 4... + case 4: write8(0x08D); write8(0x064); write8(0x024); write8(0); break; + case 6: write8(0x08D); write8(0x0B6); write32(0); break; + case 8: NOP(); // falls through to 7... + case 7: write8(0x08D); write8(0x034); write8(0x035); write32(0); break; + + default: + { + // for larger alignments, just use a JMP... + u8* aligned_target = JMP8(0); + x86Ptr = (u8*)newx86; + x86SetJ8( aligned_target ); + } + } + + jASSUME( x86Ptr == (u8*)newx86 ); +} + /********************/ /* IX86 intructions */ /********************/ diff --git a/pcsx2/x86/ix86/ix86.h b/pcsx2/x86/ix86/ix86.h index 3df81b31b7..31934ce358 100644 --- a/pcsx2/x86/ix86/ix86.h +++ b/pcsx2/x86/ix86/ix86.h @@ -197,6 +197,8 @@ extern void x86SetJ32( u32 *j32 ); extern void x86SetJ32A( u32 *j32 ); extern void x86Align( int bytes ); +extern void x86AlignExecutable( int align ); + u64 GetCPUTick( void ); // General Helper functions