diff --git a/BizHawk.Client.EmuHawk/BizHawk.Client.EmuHawk.csproj b/BizHawk.Client.EmuHawk/BizHawk.Client.EmuHawk.csproj index 51aa3b37f6..a1edbcb140 100644 --- a/BizHawk.Client.EmuHawk/BizHawk.Client.EmuHawk.csproj +++ b/BizHawk.Client.EmuHawk/BizHawk.Client.EmuHawk.csproj @@ -46,7 +46,7 @@ prompt 4 x86 - true + false true AllRules.ruleset diff --git a/BizHawk.Emulation/Consoles/Nintendo/SNES/LibsnesApi.cs b/BizHawk.Emulation/Consoles/Nintendo/SNES/LibsnesApi.cs index 4b4b704cd6..449cdf472a 100644 --- a/BizHawk.Emulation/Consoles/Nintendo/SNES/LibsnesApi.cs +++ b/BizHawk.Emulation/Consoles/Nintendo/SNES/LibsnesApi.cs @@ -389,7 +389,18 @@ namespace BizHawk.Emulation.Consoles.Nintendo.SNES eMessage_SetBuffer, eMessage_BeginBufferIO, - eMessage_EndBufferIO + eMessage_EndBufferIO, + + eMessage_set_state_hook_exec, + eMessage_set_state_hook_read, + eMessage_set_state_hook_write, + eMessage_set_state_hook_nmi, + eMessage_set_state_hook_irq, + eMessage_snes_cb_hook_exec, + eMessage_snes_cb_hook_read, + eMessage_snes_cb_hook_write, + eMessage_snes_cb_hook_nmi, + eMessage_snes_cb_hook_irq, }; static bool DryRun(string exePath) @@ -635,6 +646,12 @@ namespace BizHawk.Emulation.Consoles.Nintendo.SNES public void snes_term() { WritePipeMessage(eMessage.eMessage_snes_term); } public void snes_unload_cartridge() { WritePipeMessage(eMessage.eMessage_snes_unload_cartridge); } + public void snes_set_state_hook_exec(bool state) + { + WritePipeMessage(eMessage.eMessage_set_state_hook_exec); + bwPipe.Write(state); + } + public bool snes_load_cartridge_super_game_boy(string rom_xml, byte[] rom_data, uint rom_size, string dmg_xml, byte[] dmg_data, uint dmg_size) { WritePipeMessage(eMessage.eMessage_snes_load_cartridge_super_game_boy); @@ -932,6 +949,29 @@ namespace BizHawk.Emulation.Consoles.Nintendo.SNES SharedMemoryBlocks.Remove(name); break; } + + case eMessage.eMessage_snes_cb_hook_exec: + { + var addr = brPipe.ReadInt32(); + //Console.WriteLine("received hook messages from libsnes\n"); + //not sure how to shuttle these out of an emu core yet. do we have mechanisms for that? + break; + } + case eMessage.eMessage_snes_cb_hook_read: + { + var addr = brPipe.ReadInt32(); + break; + } + case eMessage.eMessage_snes_cb_hook_write: + { + var addr = brPipe.ReadInt32(); + var value = brPipe.ReadByte(); + break; + } + case eMessage.eMessage_snes_cb_hook_nmi: + break; + case eMessage.eMessage_snes_cb_hook_irq: + break; } } } //WaitForCompletion() diff --git a/BizHawk.Emulation/Consoles/Nintendo/SNES/LibsnesCore.cs b/BizHawk.Emulation/Consoles/Nintendo/SNES/LibsnesCore.cs index aa6aa8a50c..a3ab0f1322 100644 --- a/BizHawk.Emulation/Consoles/Nintendo/SNES/LibsnesCore.cs +++ b/BizHawk.Emulation/Consoles/Nintendo/SNES/LibsnesCore.cs @@ -259,6 +259,7 @@ namespace BizHawk.Emulation.Consoles.Nintendo.SNES CoreComm.CpuTraceAvailable = true; api.snes_power(); + api.snes_set_state_hook_exec(true); SetupMemoryDomains(romData,sgbRomData); diff --git a/libsnes/bizwinmakeone.sh b/libsnes/bizwinmakeone.sh index ee3a20830e..f1199f6170 100644 --- a/libsnes/bizwinmakeone.sh +++ b/libsnes/bizwinmakeone.sh @@ -15,10 +15,10 @@ if [ "$1" == "32" ]; then fi #debug: -#export BIZWINCFLAGS="-I. -O0 -g -masm=intel -DLIBCO_IMPORT -DLIBCO_MSVC -static-libgcc -static-libstdc++" +#export BIZWINCFLAGS="-I. -O0 -g -masm=intel -DHOOKS -DLIBCO_IMPORT -DLIBCO_MSVC -static-libgcc -static-libstdc++" #not debug -export BIZWINCFLAGS="-I. -O3 -masm=intel -static-libgcc -static-libstdc++ ${cflags64}" +export BIZWINCFLAGS="-I. -O3 -masm=intel -DHOOKS -static-libgcc -static-libstdc++ ${cflags64}" export TARGET_LIBSNES_LIBDEPS="-L ../libco_msvc_win32/release/ -static -static-libgcc -static-libstdc++ ${cflags64} ${cflags32} -mwindows" export profile=$2 @@ -28,7 +28,7 @@ platform=win target=libsnes make -e -j 4 cd .. filename=libsneshawk-${bits}-${profile}.exe -targetdir=../BizHawk.MultiClient/output/dll +targetdir=../output/dll targetpath=${targetdir}/${filename} cp bsnes/out/${filename} ${targetdir} if [ "$3" == "compress" ]; then diff --git a/libsnes/bsnes/base/base.hpp b/libsnes/bsnes/base/base.hpp index 940eba20e1..7d8c181a8d 100644 --- a/libsnes/bsnes/base/base.hpp +++ b/libsnes/bsnes/base/base.hpp @@ -32,7 +32,7 @@ template struct hook { function callback; R operator()(P... p) const { - #if defined(DEBUGGER) + #if defined(DEBUGGER) || defined(HOOKS) if(callback) return callback(std::forward

(p)...); #endif return R(); diff --git a/libsnes/bsnes/snes/cpu/cpu.hpp b/libsnes/bsnes/snes/cpu/cpu.hpp index ec5a6df79b..11c3620438 100644 --- a/libsnes/bsnes/snes/cpu/cpu.hpp +++ b/libsnes/bsnes/snes/cpu/cpu.hpp @@ -135,6 +135,7 @@ privileged: static void Enter(); void op_step(); +public: struct Debugger { hook op_exec; hook op_read; diff --git a/libsnes/bsnes/target-libsnes/libsnes_pwrap.cpp b/libsnes/bsnes/target-libsnes/libsnes_pwrap.cpp index 00282c6103..321511c966 100644 --- a/libsnes/bsnes/target-libsnes/libsnes_pwrap.cpp +++ b/libsnes/bsnes/target-libsnes/libsnes_pwrap.cpp @@ -169,7 +169,7 @@ HANDLE hPipe, hMapFile; void* hMapFilePtr; static bool running = false; -enum eMessage : int +enum eMessage : int32 { eMessage_Complete, @@ -228,7 +228,18 @@ enum eMessage : int eMessage_SetBuffer, eMessage_BeginBufferIO, - eMessage_EndBufferIO + eMessage_EndBufferIO, + + eMessage_set_state_hook_exec, + eMessage_set_state_hook_read, + eMessage_set_state_hook_write, + eMessage_set_state_hook_nmi, + eMessage_set_state_hook_irq, + eMessage_snes_cb_hook_exec, + eMessage_snes_cb_hook_read, + eMessage_snes_cb_hook_write, + eMessage_snes_cb_hook_nmi, + eMessage_snes_cb_hook_irq, }; void ReadPipeBuffer(void* buf, int len) @@ -474,6 +485,36 @@ void InitBsnes() snes_set_freeSharedMemory(snes_freeSharedMemory); } + +static void debug_op_exec(uint24 addr) +{ + WritePipe(eMessage_snes_cb_hook_exec); + WritePipe((uint32)addr); +} + +static void debug_op_read(uint24 addr) +{ + WritePipe(eMessage_snes_cb_hook_read); + WritePipe((uint32)addr); +} + +static void debug_op_write(uint24 addr, uint8 value) +{ + WritePipe(eMessage_snes_cb_hook_write); + WritePipe((uint32)addr); + WritePipe(value); +} + +static void debug_op_nmi() +{ + WritePipe(eMessage_snes_cb_hook_nmi); +} + +static void debug_op_irq() +{ + WritePipe(eMessage_snes_cb_hook_irq); +} + void RunMessageLoop() { for(;;) @@ -689,6 +730,26 @@ void RunMessageLoop() bufio = false; break; + case eMessage_set_state_hook_exec: + SNES::cpu.debugger.op_exec = ReadPipe() ? debug_op_exec : hook(); + break; + + case eMessage_set_state_hook_read: + SNES::cpu.debugger.op_read = ReadPipe() ? debug_op_read : hook(); + break; + + case eMessage_set_state_hook_write: + SNES::cpu.debugger.op_write = ReadPipe() ? debug_op_write : hook(); + break; + + case eMessage_set_state_hook_nmi: + SNES::cpu.debugger.op_nmi = ReadPipe() ? debug_op_nmi : hook(); + break; + + case eMessage_set_state_hook_irq: + SNES::cpu.debugger.op_irq = ReadPipe() ? debug_op_irq : hook(); + break; + } //switch(msg) } } @@ -764,5 +825,6 @@ int CALLBACK WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine void pwrap_init() { + //bsnes's interface initialization calls into this after initializing itself, so we can get a chance to mod it for pwrap functionalities InitBsnes(); } \ No newline at end of file diff --git a/output/dll/libsneshawk-32-compatibility.exe b/output/dll/libsneshawk-32-compatibility.exe index ad37f7b1a5..a1502704aa 100644 Binary files a/output/dll/libsneshawk-32-compatibility.exe and b/output/dll/libsneshawk-32-compatibility.exe differ