psx - support memory callbacks

This commit is contained in:
zeromus 2016-01-21 21:47:16 -06:00
parent d7186c9e6f
commit c0421965f1
6 changed files with 86 additions and 8 deletions

View File

@ -324,6 +324,7 @@ namespace BizHawk.Emulation.Cores.Sony.PSX
OctoshockDll.shock_Create(out psx, SystemRegion, pFirmware);
SetMemoryDomains();
InitMemCallbacks();
//set a default framebuffer based on the first frame of emulation, to cut down on flickering or whatever
//this is probably quixotic, but we have to pick something
@ -790,6 +791,39 @@ namespace BizHawk.Emulation.Cores.Sony.PSX
#region Debugging
OctoshockDll.ShockCallback_Mem mem_cb;
void ShockMemCallback(uint address, OctoshockDll.eShockMemCb type, uint size, uint value)
{
switch (type)
{
case OctoshockDll.eShockMemCb.Read:
MemoryCallbacks.CallReads(address);
break;
case OctoshockDll.eShockMemCb.Write:
MemoryCallbacks.CallWrites(address);
break;
case OctoshockDll.eShockMemCb.Execute:
MemoryCallbacks.CallExecutes(address);
break;
}
}
void InitMemCallbacks()
{
mem_cb = new OctoshockDll.ShockCallback_Mem(ShockMemCallback);
_memoryCallbacks.ActiveChanged += RefreshMemCallbacks;
}
void RefreshMemCallbacks()
{
OctoshockDll.eShockMemCb mask = OctoshockDll.eShockMemCb.None;
if (MemoryCallbacks.HasReads) mask |= OctoshockDll.eShockMemCb.Read;
if (MemoryCallbacks.HasWrites) mask |= OctoshockDll.eShockMemCb.Write;
if (MemoryCallbacks.HasExecutes) mask |= OctoshockDll.eShockMemCb.Execute;
OctoshockDll.shock_SetMemCb(psx, mem_cb, mask);
}
unsafe void SetMemoryDomains()
{
var mmd = new List<MemoryDomain>();
@ -1284,13 +1318,13 @@ namespace BizHawk.Emulation.Cores.Sony.PSX
public ITraceable Tracer { get { return tracer; } }
public int ShockTraceCallback(IntPtr opaque, uint PC, uint inst, string dis)
public void ShockTraceCallback(IntPtr opaque, uint PC, uint inst, string dis)
{
Tracer.Put(dis);
return OctoshockDll.SHOCK_OK;
}
public IMemoryCallbackSystem MemoryCallbacks { get { throw new NotImplementedException(); } }
private readonly MemoryCallbackSystem _memoryCallbacks = new MemoryCallbackSystem();
public IMemoryCallbackSystem MemoryCallbacks { get { return _memoryCallbacks; } }
public bool CanStep(StepType type) { return false; }

View File

@ -96,6 +96,15 @@ namespace BizHawk.Emulation.Cores.Sony.PSX
BobOffset
}
[Flags]
public enum eShockMemCb : int
{
None = 0,
Read = 1,
Write = 2,
Execute = 4
}
public const int SHOCK_OK = 0;
public const int SHOCK_FALSE = 0;
public const int SHOCK_TRUE = 1;
@ -172,8 +181,9 @@ namespace BizHawk.Emulation.Cores.Sony.PSX
public TextStateFPtrs ff;
};
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate int ShockTraceCallback(IntPtr opaque, uint PC, uint inst, string dis);
public delegate void ShockCallback_Trace(IntPtr opaque, uint PC, uint inst, string dis);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate int ShockDisc_ReadTOC(IntPtr opaque, ShockTOC* read_target, ShockTOCTrack* tracks101);
@ -181,6 +191,9 @@ namespace BizHawk.Emulation.Cores.Sony.PSX
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate int ShockDisc_ReadLBA(IntPtr opaque, int lba, void* dst);
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
public delegate void ShockCallback_Mem(uint address, eShockMemCb type, uint size, uint value);
[DllImport(dd, CallingConvention = cc)]
public static extern int shock_Util_DisassembleMIPS(uint PC, uint instr, IntPtr outbuf, int buflen);
@ -193,8 +206,6 @@ namespace BizHawk.Emulation.Cores.Sony.PSX
[DllImport(dd, CallingConvention = cc)]
public static extern int shock_AnalyzeDisc(IntPtr disc, out ShockDiscInfo info);
[DllImport(dd, CallingConvention = cc)]
public static extern int shock_Create(out IntPtr psx, eRegion region, void* firmware512k);
@ -271,7 +282,10 @@ namespace BizHawk.Emulation.Cores.Sony.PSX
public static extern int shock_SetRegister_CPU(IntPtr psx, int index, uint value);
[DllImport(dd, CallingConvention = cc)]
public static extern int shock_SetTraceCallback(IntPtr psx, IntPtr opaque, ShockTraceCallback callback);
public static extern int shock_SetTraceCallback(IntPtr psx, IntPtr opaque, ShockCallback_Trace callback);
[DllImport(dd, CallingConvention = cc)]
public static extern int shock_SetMemCb(IntPtr psx, ShockCallback_Mem cb, eShockMemCb cbMask);
[DllImport(dd, CallingConvention = cc)]
public static extern int shock_SetLEC(IntPtr psx, bool enable);

Binary file not shown.

View File

@ -29,6 +29,8 @@
//not very organized, is it
void* g_ShockTraceCallbackOpaque = NULL;
ShockCallback_Trace g_ShockTraceCallback = NULL;
ShockCallback_Mem g_ShockMemCallback;
eShockMemCb g_ShockMemCbType;
/* TODO
Make sure load delays are correct.
@ -252,6 +254,9 @@ INLINE T PS_CPU::ReadMemory(pscpu_timestamp_t &timestamp, uint32 address, bool D
ReadAbsorb[ReadAbsorbWhich] = 0;
ReadAbsorbWhich = 0;
if (g_ShockMemCallback && (g_ShockMemCbType & eShockMemCb_Read))
g_ShockMemCallback(address, eShockMemCb_Read, DS24 ? 24 : 32, 0);
address &= addr_mask[address >> 29];
if(address >= 0x1F800000 && address <= 0x1F8003FF)
@ -296,6 +301,9 @@ INLINE T PS_CPU::ReadMemory(pscpu_timestamp_t &timestamp, uint32 address, bool D
template<typename T>
INLINE void PS_CPU::WriteMemory(pscpu_timestamp_t &timestamp, uint32 address, uint32 value, bool DS24)
{
if (g_ShockMemCallback && (g_ShockMemCbType & eShockMemCb_Write))
g_ShockMemCallback(address, eShockMemCb_Write, DS24 ? 24 : 32, value);
if(MDFN_LIKELY(!(CP0.SR & 0x10000)))
{
address &= addr_mask[address >> 29];

View File

@ -2700,6 +2700,8 @@ EW_EXPORT s32 shock_SetRenderOptions(void* pxs, ShockRenderOptions* opts)
extern void* g_ShockTraceCallbackOpaque;
extern ShockCallback_Trace g_ShockTraceCallback;
extern ShockCallback_Mem g_ShockMemCallback;
extern eShockMemCb g_ShockMemCbType;
//Sets the callback to be used for CPU tracing
EW_EXPORT s32 shock_SetTraceCallback(void* psx, void* opaque, ShockCallback_Trace callback)
@ -2710,6 +2712,14 @@ EW_EXPORT s32 shock_SetTraceCallback(void* psx, void* opaque, ShockCallback_Trac
return SHOCK_OK;
}
//Sets the callback to be used for memory hook events
EW_EXPORT s32 shock_SetMemCb(void* psx, ShockCallback_Mem callback, eShockMemCb cbMask)
{
g_ShockMemCallback = callback;
g_ShockMemCbType = cbMask;
return SHOCK_OK;
}
//Sets whether LEC is enabled (sector level error correction). Defaults to FALSE (disabled)
EW_EXPORT s32 shock_SetLEC(void* psx, bool enabled)
{

View File

@ -192,6 +192,13 @@ enum eShockMemcardTransaction
eShockMemcardTransaction_CheckDirty = 4, //checks whether the memcard is dirty
};
enum eShockMemCb
{
eShockMemCb_None = 0,
eShockMemCb_Read = 1,
eShockMemCb_Write = 2,
eShockMemCb_Execute = 4
};
#define MDFN_MSC_RESET 0
#define MDFN_MSC_POWER 1
@ -237,7 +244,12 @@ typedef s32 (*ShockDisc_ReadTOC)(void* opaque, ShockTOC *read_target, ShockTOCTr
typedef s32 (*ShockDisc_ReadLBA)(void* opaque, s32 lba, void* dst);
//The callback to be issued for traces
typedef s32 (*ShockCallback_Trace)(void* opaque, u32 PC, u32 inst, const char* msg);
typedef void (*ShockCallback_Trace)(void* opaque, u32 PC, u32 inst, const char* msg);
//the callback to be issued for memory hook events
//note: only one callback can be set. the type is sent to mask that one callback, not indicate which event type the callback is fore.
//there isnt one callback per type.
typedef void (*ShockCallback_Mem)(u32 address, eShockMemCb type, u32 size, u32 value);
class ShockDiscRef
{