snes-fix bugs caused by breakpoints leaving emulator state unstable (most noticeable when taking savestates)

This commit is contained in:
zeromus 2013-12-29 02:20:13 +00:00
parent e673062d0f
commit 50ef1b19f5
8 changed files with 31 additions and 25 deletions

View File

@ -220,11 +220,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.SNES
//this approach is slower than having one big case. but, its easier to manage. once the code is stable, someone could clean it up (probably creating a delegate table would be best)
if (Handle_SIG(msg)) continue;
if (Handle_BRK(msg)) continue;
switch (msg)
{
case eMessage.eMessage_Complete:
return;
}
}
}
@ -260,7 +255,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.SNES
public void SPECIAL_Resume()
{
WritePipeMessage(eMessage.eMessage_CMD_run);
WritePipeMessage(eMessage.eMessage_ResumeAfterBRK);
}
}

View File

@ -9,10 +9,11 @@ namespace BizHawk.Emulation.Cores.Nintendo.SNES
public enum eMessage : int
{
eMessage_NotSet,
eMessage_Complete,
eMessage_SetBuffer,
eMessage_BeginBufferIO,
eMessage_EndBufferIO,
eMessage_ResumeAfterBRK,
eMessage_QUERY_library_id,
eMessage_QUERY_library_revision_major,

View File

@ -77,7 +77,6 @@ namespace BizHawk.Emulation.Cores.Nintendo.SNES
{
WritePipeMessage(eMessage.eMessage_QUERY_serialize_size);
int ret = brPipe.ReadInt32();
Console.WriteLine("eMessage.eMessage_QUERY_serialize_size: " + ret);
if (ret > 100)
{
return ret;

View File

@ -77,7 +77,8 @@ namespace BizHawk.Emulation.Cores.Nintendo.SNES
scanlineStart(line);
//we have to notify the unmanaged process that we're done peeking thruogh its memory and whatnot so it can proceed with emulation
WritePipeMessage(eMessage.eMessage_Complete);
//HUM??????????? BRK_COMPLETE???? SCANLINE CB NEEDS RE-EVALUATING
WritePipeMessage(eMessage.eMessage_BRK_Complete);
break;
}
case eMessage.eMessage_SIG_path_request:

View File

@ -578,7 +578,7 @@ namespace BizHawk.Emulation.Cores.Nintendo.SNES
api.QUERY_set_layer_enable(4, 2, Settings.ShowOBJ_2);
api.QUERY_set_layer_enable(4, 3, Settings.ShowOBJ_3);
RefreshMemoryCallbacks();
RefreshMemoryCallbacks(false);
//apparently this is one frame?
timeFrameCounter++;
@ -596,12 +596,12 @@ namespace BizHawk.Emulation.Cores.Nintendo.SNES
api.EndBufferIO();
}
void RefreshMemoryCallbacks()
void RefreshMemoryCallbacks(bool suppress)
{
var mcs = CoreComm.MemoryCallbackSystem;
api.QUERY_set_state_hook_exec(mcs.HasExecutes);
api.QUERY_set_state_hook_read(mcs.HasReads);
api.QUERY_set_state_hook_write(mcs.HasWrites);
api.QUERY_set_state_hook_exec(!suppress && mcs.HasExecutes);
api.QUERY_set_state_hook_read(!suppress && mcs.HasReads);
api.QUERY_set_state_hook_write(!suppress && mcs.HasWrites);
}
public DisplayType DisplayType
@ -927,6 +927,8 @@ namespace BizHawk.Emulation.Cores.Nintendo.SNES
fixed (byte* pbuf = &data[0])
api.CMD_unserialize(new IntPtr(pbuf), size);
}
/// <summary>
/// handle the unmanaged part of savestating
/// </summary>

View File

@ -10,10 +10,10 @@
//TODO - factor out modular components (ringbuffer and the like)
//types of messages:
//cmd: frontend->core: "command to core" a command from the frontend which causes emulation to proceed. when sending a command, the frontend should wait for an eMessage_brk_complete before proceeding, although a debugger might proceed after any BRK
//query: frontend->core: "query to core" a query from the frontend which can (and should) be satisfied immediately by the core but which does not result in emulation processes
//cmd: frontend->core: "command to core" a command from the frontend which causes emulation to proceed. when sending a command, the frontend should wait for an eMessage_BRK_Complete before proceeding, although a debugger might proceed after any BRK
//query: frontend->core: "query to core" a query from the frontend which can (and should) be satisfied immediately by the core but which does not result in emulation processes (notably, nothing resembling a CMD and nothing which can trigger a BRK)
//sig: core->frontend: "core signal" a synchronous operation called from the emulation process which the frontend should handle immediately without issuing any calls into the core
//brk: core->frontend: "core break" the emulation process has suspended. the core is free to do whatever it wishes.
//brk: core->frontend: "core break" the emulation process has suspended. the frontend is free to do whatever it wishes.
//(and there are other assorted special messages...)
@ -41,11 +41,11 @@ typedef uint16 u16;
enum eMessage : int32
{
eMessage_NotSet,
eMessage_Complete,
eMessage_SetBuffer,
eMessage_BeginBufferIO,
eMessage_EndBufferIO,
eMessage_ResumeAfterBRK, //resumes execution of the core, after a BRK. no change to current CMD
eMessage_QUERY_library_id,
eMessage_QUERY_library_revision_major,
@ -111,7 +111,7 @@ enum eEmulationExitReason
eEmulationExitReason_NotSet,
eEmulationExitReason_BRK,
eEmulationExitReason_SIG,
eEmulationExitReason_Complete, //TODO rename CMD_Complete
eEmulationExitReason_CMD_Complete,
};
enum eEmulationCallback
@ -728,7 +728,7 @@ bool Handle_QUERY(eMessage msg)
char* dstbuf = ReadPipeSharedPtr();
uint8_t* srcbuf = snes_get_memory_data(id);
memcpy(dstbuf,srcbuf,snes_get_memory_size(id));
WritePipe(eMessage_Complete);
WritePipe(eMessage_BRK_Complete);
break;
}
@ -875,6 +875,14 @@ bool Handle_QUERY(eMessage msg)
bool Handle_CMD(eMessage msg)
{
if(msg == eMessage_ResumeAfterBRK)
{
//careful! dont switch back to co_emu, we were in another cothread probably when the BRK happened.
//i'm not sure its completely safe to be returning to co_emu below in the normal CMD handler, either...
co_switch(co_emu_suspended);
return true;
}
if(msg<=eMessage_CMD_FIRST || msg>=eMessage_CMD_LAST) return false;
s_EmulationControl.command = msg;
@ -911,11 +919,11 @@ TOP:
case eEmulationExitReason_NotSet:
goto HANDLEMESSAGES;
case eEmulationExitReason_Complete:
//printf("eEmulationExitReason_Complete (command:%d)\n",s_EmulationControl.command);
case eEmulationExitReason_CMD_Complete:
//printf("eEmulationExitReason_CMD_Complete (command:%d)\n",s_EmulationControl.command);
//MessageBox(0,"ZING","ZING",MB_OK);
//printf("WRITING COMPLETE\n");
WritePipe(eMessage_Complete);
WritePipe(eMessage_BRK_Complete);
//special post-completion messages (return values)
switch(s_EmulationControl.command)
@ -1025,7 +1033,7 @@ HANDLEMESSAGES:
switch(msg)
{
case eMessage_Complete:
case eMessage_BRK_Complete:
return;
case eMessage_SetBuffer:
@ -1172,7 +1180,7 @@ void emuthread()
break;
}
s_EmulationControl.exitReason = eEmulationExitReason_Complete;
s_EmulationControl.exitReason = eEmulationExitReason_CMD_Complete;
SETCONTROL;
}
}