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) //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_SIG(msg)) continue;
if (Handle_BRK(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() 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 public enum eMessage : int
{ {
eMessage_NotSet, eMessage_NotSet,
eMessage_Complete,
eMessage_SetBuffer, eMessage_SetBuffer,
eMessage_BeginBufferIO, eMessage_BeginBufferIO,
eMessage_EndBufferIO, eMessage_EndBufferIO,
eMessage_ResumeAfterBRK,
eMessage_QUERY_library_id, eMessage_QUERY_library_id,
eMessage_QUERY_library_revision_major, eMessage_QUERY_library_revision_major,

View File

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

View File

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

View File

@ -10,10 +10,10 @@
//TODO - factor out modular components (ringbuffer and the like) //TODO - factor out modular components (ringbuffer and the like)
//types of messages: //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 //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 //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 //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...) //(and there are other assorted special messages...)
@ -41,11 +41,11 @@ typedef uint16 u16;
enum eMessage : int32 enum eMessage : int32
{ {
eMessage_NotSet, eMessage_NotSet,
eMessage_Complete,
eMessage_SetBuffer, eMessage_SetBuffer,
eMessage_BeginBufferIO, eMessage_BeginBufferIO,
eMessage_EndBufferIO, eMessage_EndBufferIO,
eMessage_ResumeAfterBRK, //resumes execution of the core, after a BRK. no change to current CMD
eMessage_QUERY_library_id, eMessage_QUERY_library_id,
eMessage_QUERY_library_revision_major, eMessage_QUERY_library_revision_major,
@ -111,7 +111,7 @@ enum eEmulationExitReason
eEmulationExitReason_NotSet, eEmulationExitReason_NotSet,
eEmulationExitReason_BRK, eEmulationExitReason_BRK,
eEmulationExitReason_SIG, eEmulationExitReason_SIG,
eEmulationExitReason_Complete, //TODO rename CMD_Complete eEmulationExitReason_CMD_Complete,
}; };
enum eEmulationCallback enum eEmulationCallback
@ -728,7 +728,7 @@ bool Handle_QUERY(eMessage msg)
char* dstbuf = ReadPipeSharedPtr(); char* dstbuf = ReadPipeSharedPtr();
uint8_t* srcbuf = snes_get_memory_data(id); uint8_t* srcbuf = snes_get_memory_data(id);
memcpy(dstbuf,srcbuf,snes_get_memory_size(id)); memcpy(dstbuf,srcbuf,snes_get_memory_size(id));
WritePipe(eMessage_Complete); WritePipe(eMessage_BRK_Complete);
break; break;
} }
@ -875,6 +875,14 @@ bool Handle_QUERY(eMessage msg)
bool Handle_CMD(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; if(msg<=eMessage_CMD_FIRST || msg>=eMessage_CMD_LAST) return false;
s_EmulationControl.command = msg; s_EmulationControl.command = msg;
@ -911,11 +919,11 @@ TOP:
case eEmulationExitReason_NotSet: case eEmulationExitReason_NotSet:
goto HANDLEMESSAGES; goto HANDLEMESSAGES;
case eEmulationExitReason_Complete: case eEmulationExitReason_CMD_Complete:
//printf("eEmulationExitReason_Complete (command:%d)\n",s_EmulationControl.command); //printf("eEmulationExitReason_CMD_Complete (command:%d)\n",s_EmulationControl.command);
//MessageBox(0,"ZING","ZING",MB_OK); //MessageBox(0,"ZING","ZING",MB_OK);
//printf("WRITING COMPLETE\n"); //printf("WRITING COMPLETE\n");
WritePipe(eMessage_Complete); WritePipe(eMessage_BRK_Complete);
//special post-completion messages (return values) //special post-completion messages (return values)
switch(s_EmulationControl.command) switch(s_EmulationControl.command)
@ -1025,7 +1033,7 @@ HANDLEMESSAGES:
switch(msg) switch(msg)
{ {
case eMessage_Complete: case eMessage_BRK_Complete:
return; return;
case eMessage_SetBuffer: case eMessage_SetBuffer:
@ -1172,7 +1180,7 @@ void emuthread()
break; break;
} }
s_EmulationControl.exitReason = eEmulationExitReason_Complete; s_EmulationControl.exitReason = eEmulationExitReason_CMD_Complete;
SETCONTROL; SETCONTROL;
} }
} }