[PSX] Make Octoshock more debuggable (#2508)

* [PSX] Bodge in a system bus memory domain

Fixes: debugger window crashes when adding a breakpoint

* [PSX] Use Octoshock's built-in disassembler

* [PSX] Add support for execute memcbs to the core

* [PSX] Have memcbs include actual values

* [PSX] Use SafeHandles instead of raw pointers

* [PSX] Use core's internal peek and poke functions for System Bus

* [PSX] Move memory maps into IDebuggable impl to be next to memory map hooks

* [PSX] Revert using SafeHandles

* [PSX] Fire execution callback after trace callback instead of at end of fetch
This commit is contained in:
Andrew Cook 2020-12-08 12:34:24 -05:00 committed by GitHub
parent e81fa92f80
commit 58cbec6dd6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 119 additions and 72 deletions

Binary file not shown.

View File

@ -253,8 +253,6 @@ 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);
#if 0
if(MDFN_UNLIKELY(CP0.SR & 0x10000))
{
@ -302,9 +300,13 @@ INLINE T PS_CPU::ReadMemory(pscpu_timestamp_t &timestamp, uint32 address, bool D
LDAbsorb = 0;
if(DS24)
return ScratchRAM.ReadU24(address & 0x3FF);
ret = ScratchRAM.ReadU24(address & 0x3FF);
else
return ScratchRAM.Read<T>(address & 0x3FF);
ret = ScratchRAM.Read<T>(address & 0x3FF);
if (g_ShockMemCallback && (g_ShockMemCbType & eShockMemCb_Read))
g_ShockMemCallback(address, eShockMemCb_Read, DS24 ? 24 : sizeof(T) * 8, ret);
return(ret);
}
timestamp += (ReadFudge >> 4) & 2;
@ -333,6 +335,8 @@ INLINE T PS_CPU::ReadMemory(pscpu_timestamp_t &timestamp, uint32 address, bool D
LDAbsorb = (lts - timestamp);
timestamp = lts;
if (g_ShockMemCallback && (g_ShockMemCbType & eShockMemCb_Read))
g_ShockMemCallback(address, eShockMemCb_Read, DS24 ? 24 : sizeof(T) * 8, ret);
return(ret);
}
@ -340,7 +344,7 @@ 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);
g_ShockMemCallback(address, eShockMemCb_Write, DS24 ? 24 : sizeof(T) * 8, value);
if(MDFN_LIKELY(!(CP0.SR & 0x10000)))
{
@ -631,6 +635,10 @@ pscpu_timestamp_t PS_CPU::RunReal(pscpu_timestamp_t timestamp_in)
g_ShockTraceCallback(NULL, PC, instr, disasm_buf);
}
if (g_ShockMemCallback && (g_ShockMemCbType & eShockMemCb_Execute))
g_ShockMemCallback(PC, eShockMemCb_Execute, 32, instr);
opf = instr & 0x3F;
if(instr & (0x3F << 26))

View File

@ -2841,4 +2841,25 @@ EW_EXPORT s32 shock_SetLEC(void* psx, bool enabled)
EW_EXPORT s32 shock_GetGPUUnlagged(void* psx)
{
return GpuFrameForLag ? SHOCK_TRUE : SHOCK_FALSE;
}
EW_EXPORT s32 shock_PeekMemory(void* psx, u32 address, u8* value)
{
if (!s_Created) {
return SHOCK_NOCANDO;
}
*value = CPU->PeekMem8(address);
return SHOCK_OK;
}
EW_EXPORT s32 shock_PokeMemory(void* psx, u32 address, u8 value)
{
if (!s_Created) {
return SHOCK_NOCANDO;
}
CPU->PokeMem8(address, value);
return SHOCK_OK;
}

View File

@ -454,3 +454,7 @@ EW_EXPORT s32 shock_SetLEC(void* psx, bool enabled);
//whether "determine lag from GPU frames" signal is set (GPU did something considered non-lag)
//returns SHOCK_TRUE or SHOCK_FALSE
EW_EXPORT s32 shock_GetGPUUnlagged(void* psx);
EW_EXPORT s32 shock_PeekMemory(void* psx, u32 address, u8* value);
EW_EXPORT s32 shock_PokeMemory(void* psx, u32 address, u8 value);

View File

@ -87,5 +87,74 @@ namespace BizHawk.Emulation.Cores.Sony.PSX
[FeatureNotImplemented]
public long TotalExecutedCycles => throw new NotImplementedException();
OctoshockDll.ShockCallback_Mem mem_cb;
void ShockMemCallback(uint address, OctoshockDll.eShockMemCb type, uint size, uint value)
{
MemoryCallbackFlags flags = 0;
switch (type)
{
case OctoshockDll.eShockMemCb.Read:
flags |= MemoryCallbackFlags.AccessRead;
break;
case OctoshockDll.eShockMemCb.Write:
flags |= MemoryCallbackFlags.AccessWrite;
break;
case OctoshockDll.eShockMemCb.Execute:
flags |= MemoryCallbackFlags.AccessExecute;
break;
}
MemoryCallbacks.CallMemoryCallbacks(address, value, (uint)flags, "System Bus");
}
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>();
OctoshockDll.shock_GetMemData(psx, out var ptr, out var size, OctoshockDll.eMemType.MainRAM);
mmd.Add(new MemoryDomainIntPtr("MainRAM", MemoryDomain.Endian.Little, ptr, size, true, 4));
OctoshockDll.shock_GetMemData(psx, out ptr, out size, OctoshockDll.eMemType.GPURAM);
mmd.Add(new MemoryDomainIntPtr("GPURAM", MemoryDomain.Endian.Little, ptr, size, true, 4));
OctoshockDll.shock_GetMemData(psx, out ptr, out size, OctoshockDll.eMemType.SPURAM);
mmd.Add(new MemoryDomainIntPtr("SPURAM", MemoryDomain.Endian.Little, ptr, size, true, 4));
OctoshockDll.shock_GetMemData(psx, out ptr, out size, OctoshockDll.eMemType.BiosROM);
mmd.Add(new MemoryDomainIntPtr("BiosROM", MemoryDomain.Endian.Little, ptr, size, true, 4));
OctoshockDll.shock_GetMemData(psx, out ptr, out size, OctoshockDll.eMemType.PIOMem);
mmd.Add(new MemoryDomainIntPtr("PIOMem", MemoryDomain.Endian.Little, ptr, size, true, 4));
OctoshockDll.shock_GetMemData(psx, out ptr, out size, OctoshockDll.eMemType.DCache);
mmd.Add(new MemoryDomainIntPtr("DCache", MemoryDomain.Endian.Little, ptr, size, true, 4));
mmd.Add(new MemoryDomainDelegate("System Bus", 0x1_0000_0000, MemoryDomain.Endian.Little,
(a) => { byte v; OctoshockDll.shock_PeekMemory(psx, (uint)a, out v); return v; },
(a, v) => { OctoshockDll.shock_PokeMemory(psx, (uint)a, v); },
4));
MemoryDomains = new MemoryDomainList(mmd);
(ServiceProvider as BasicServiceProvider).Register<IMemoryDomains>(MemoryDomains);
}
private IMemoryDomains MemoryDomains;
}
}

View File

@ -1,4 +1,5 @@
using System.Collections.Generic;
using System.Text;
using BizHawk.Emulation.Common;
namespace BizHawk.Emulation.Cores.Sony.PSX
@ -24,8 +25,9 @@ namespace BizHawk.Emulation.Cores.Sony.PSX
public string Disassemble(MemoryDomain m, uint addr, out int length)
{
length = 4;
//var result = OctoshockDll.shock_Util_DisassembleMIPS();
return "";
var buf = new StringBuilder(32);
var result = OctoshockDll.shock_Util_DisassembleMIPS(addr, m.PeekUint(addr, false), buf, buf.Capacity);
return result==0?buf.ToString():"";
}
}
}

View File

@ -931,70 +931,6 @@ namespace BizHawk.Emulation.Cores.Sony.PSX
public System.Drawing.Size VideoProvider_Padding { get; private set; }
OctoshockDll.ShockCallback_Mem mem_cb;
void ShockMemCallback(uint address, OctoshockDll.eShockMemCb type, uint size, uint value)
{
MemoryCallbackFlags flags = 0;
switch (type)
{
case OctoshockDll.eShockMemCb.Read:
flags |= MemoryCallbackFlags.AccessRead;
break;
case OctoshockDll.eShockMemCb.Write:
flags |= MemoryCallbackFlags.AccessWrite;
break;
case OctoshockDll.eShockMemCb.Execute:
flags |= MemoryCallbackFlags.AccessExecute;
break;
}
MemoryCallbacks.CallMemoryCallbacks(address, value, (uint)flags, "System Bus");
}
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>();
OctoshockDll.shock_GetMemData(psx, out var ptr, out var size, OctoshockDll.eMemType.MainRAM);
mmd.Add(new MemoryDomainIntPtr("MainRAM", MemoryDomain.Endian.Little, ptr, size, true, 4));
OctoshockDll.shock_GetMemData(psx, out ptr, out size, OctoshockDll.eMemType.GPURAM);
mmd.Add(new MemoryDomainIntPtr("GPURAM", MemoryDomain.Endian.Little, ptr, size, true, 4));
OctoshockDll.shock_GetMemData(psx, out ptr, out size, OctoshockDll.eMemType.SPURAM);
mmd.Add(new MemoryDomainIntPtr("SPURAM", MemoryDomain.Endian.Little, ptr, size, true, 4));
OctoshockDll.shock_GetMemData(psx, out ptr, out size, OctoshockDll.eMemType.BiosROM);
mmd.Add(new MemoryDomainIntPtr("BiosROM", MemoryDomain.Endian.Little, ptr, size, true, 4));
OctoshockDll.shock_GetMemData(psx, out ptr, out size, OctoshockDll.eMemType.PIOMem);
mmd.Add(new MemoryDomainIntPtr("PIOMem", MemoryDomain.Endian.Little, ptr, size, true, 4));
OctoshockDll.shock_GetMemData(psx, out ptr, out size, OctoshockDll.eMemType.DCache);
mmd.Add(new MemoryDomainIntPtr("DCache", MemoryDomain.Endian.Little, ptr, size, true, 4));
MemoryDomains = new MemoryDomainList(mmd);
(ServiceProvider as BasicServiceProvider).Register<IMemoryDomains>(MemoryDomains);
}
private IMemoryDomains MemoryDomains;
//private short[] sbuff = new short[1454 * 2]; //this is the most ive ever seen.. don't know why. two frames worth i guess
private short[] sbuff = new short[1611 * 2]; //need this for pal
private int sbuffcontains = 0;

View File

@ -2,6 +2,7 @@
using System;
using System.Runtime.InteropServices;
using System.Text;
using BizHawk.Emulation.Common;
@ -197,7 +198,7 @@ namespace BizHawk.Emulation.Cores.Sony.PSX
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);
public static extern int shock_Util_DisassembleMIPS(uint PC, uint instr, StringBuilder outbuf, int buflen);
[DllImport(dd, CallingConvention = cc)]
public static extern int shock_CreateDisc(out IntPtr outDisc, IntPtr Opaque, int lbaCount, ShockDisc_ReadTOC ReadTOC, ShockDisc_ReadLBA ReadLBA2448, bool suppliesDeinterleavedSubcode);
@ -297,5 +298,11 @@ namespace BizHawk.Emulation.Cores.Sony.PSX
[DllImport(dd, CallingConvention = cc)]
public static extern int shock_GetGPUUnlagged(IntPtr psx);
[DllImport(dd, CallingConvention = cc)]
public static extern int shock_PeekMemory(IntPtr psx, uint address, out byte value);
[DllImport(dd, CallingConvention = cc)]
public static extern int shock_PokeMemory(IntPtr psx, uint address, byte value);
}
}