psx - add cpu registers get/set
This commit is contained in:
parent
7b580e7dca
commit
ee1e99fc49
|
@ -23,7 +23,7 @@ namespace BizHawk.Emulation.Cores.Sony.PSX
|
|||
isPorted: true,
|
||||
isReleased: false
|
||||
)]
|
||||
public unsafe class Octoshock : IEmulator, IVideoProvider, ISyncSoundProvider, IMemoryDomains, ISaveRam, IStatable, IDriveLight, IInputPollable, ISettable<Octoshock.Settings, Octoshock.SyncSettings>
|
||||
public unsafe class Octoshock : IEmulator, IVideoProvider, ISyncSoundProvider, IMemoryDomains, ISaveRam, IStatable, IDriveLight, IInputPollable, ISettable<Octoshock.Settings, Octoshock.SyncSettings>, IDebuggable
|
||||
{
|
||||
public string SystemId { get { return "PSX"; } }
|
||||
|
||||
|
@ -429,6 +429,9 @@ namespace BizHawk.Emulation.Cores.Sony.PSX
|
|||
OctoshockDll.shock_GetMemData(psx, out ptr, out size, OctoshockDll.eMemType.PIOMem);
|
||||
mmd.Add(MemoryDomain.FromIntPtr("PIOMem", size, MemoryDomain.Endian.Little, ptr, true));
|
||||
|
||||
OctoshockDll.shock_GetMemData(psx, out ptr, out size, OctoshockDll.eMemType.DCache);
|
||||
mmd.Add(MemoryDomain.FromIntPtr("DCache", size, MemoryDomain.Endian.Little, ptr, true));
|
||||
|
||||
MemoryDomains = new MemoryDomainList(mmd, 0);
|
||||
}
|
||||
|
||||
|
@ -697,5 +700,76 @@ namespace BizHawk.Emulation.Cores.Sony.PSX
|
|||
|
||||
#endregion
|
||||
|
||||
#region IDebuggable
|
||||
|
||||
public IDictionary<string, int> GetCpuFlagsAndRegisters()
|
||||
{
|
||||
Dictionary<string, int> ret = new Dictionary<string, int>();
|
||||
var regs = new OctoshockDll.ShockRegisters_CPU();
|
||||
|
||||
OctoshockDll.shock_GetRegisters_CPU(psx, ref regs);
|
||||
|
||||
ret["r1"] = (int)regs.GPR[1]; ret["r2"] = (int)regs.GPR[2]; ret["r3"] = (int)regs.GPR[3];
|
||||
ret["r4"] = (int)regs.GPR[4]; ret["r5"] = (int)regs.GPR[5]; ret["r6"] = (int)regs.GPR[6]; ret["r7"] = (int)regs.GPR[7];
|
||||
ret["r8"] = (int)regs.GPR[8]; ret["r9"] = (int)regs.GPR[9]; ret["r10"] = (int)regs.GPR[10]; ret["r11"] = (int)regs.GPR[11];
|
||||
ret["r12"] = (int)regs.GPR[12]; ret["r13"] = (int)regs.GPR[13]; ret["r14"] = (int)regs.GPR[14]; ret["r15"] = (int)regs.GPR[15];
|
||||
ret["r16"] = (int)regs.GPR[16]; ret["r17"] = (int)regs.GPR[17]; ret["r18"] = (int)regs.GPR[18]; ret["r19"] = (int)regs.GPR[19];
|
||||
ret["r20"] = (int)regs.GPR[20]; ret["r21"] = (int)regs.GPR[21]; ret["r22"] = (int)regs.GPR[22]; ret["r23"] = (int)regs.GPR[23];
|
||||
ret["r24"] = (int)regs.GPR[24]; ret["r25"] = (int)regs.GPR[25]; ret["r26"] = (int)regs.GPR[26]; ret["r27"] = (int)regs.GPR[27];
|
||||
ret["r28"] = (int)regs.GPR[28]; ret["r29"] = (int)regs.GPR[29]; ret["r30"] = (int)regs.GPR[30]; ret["r31"] = (int)regs.GPR[31];
|
||||
|
||||
ret["at"] = (int)regs.GPR[1];
|
||||
ret["v0"] = (int)regs.GPR[2]; ret["v1"] = (int)regs.GPR[3];
|
||||
ret["a0"] = (int)regs.GPR[4]; ret["a1"] = (int)regs.GPR[5]; ret["a2"] = (int)regs.GPR[6]; ret["a3"] = (int)regs.GPR[7];
|
||||
ret["t0"] = (int)regs.GPR[8]; ret["t1"] = (int)regs.GPR[9]; ret["t2"] = (int)regs.GPR[10]; ret["t3"] = (int)regs.GPR[11];
|
||||
ret["t4"] = (int)regs.GPR[12]; ret["t5"] = (int)regs.GPR[13]; ret["t6"] = (int)regs.GPR[14]; ret["t7"] = (int)regs.GPR[15];
|
||||
ret["s0"] = (int)regs.GPR[16]; ret["s1"] = (int)regs.GPR[17]; ret["s2"] = (int)regs.GPR[18]; ret["s3"] = (int)regs.GPR[19];
|
||||
ret["s4"] = (int)regs.GPR[20]; ret["s5"] = (int)regs.GPR[21]; ret["s6"] = (int)regs.GPR[22]; ret["s7"] = (int)regs.GPR[23];
|
||||
ret["t8"] = (int)regs.GPR[24]; ret["t9"] = (int)regs.GPR[25];
|
||||
ret["k0"] = (int)regs.GPR[26]; ret["k1"] = (int)regs.GPR[27];
|
||||
ret["gp"] = (int)regs.GPR[28];
|
||||
ret["sp"] = (int)regs.GPR[29];
|
||||
ret["fp"] = (int)regs.GPR[30];
|
||||
ret["ra"] = (int)regs.GPR[31];
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static Dictionary<string, int> CpuRegisterIndices = new Dictionary<string, int>() {
|
||||
{"r1",1},{"r2",2},{"r3",3},{"r4",4},{"r5",5},{"r6",6},{"r7",7},
|
||||
{"r8",8},{"r9",9},{"r10",10},{"r11",11},{"r12",12},{"r13",13},{"r14",14},{"r15",15},
|
||||
{"r16",16},{"r17",17},{"r18",18},{"r19",19},{"r20",20},{"r21",21},{"r22",22},{"r23",23},
|
||||
{"r24",24},{"r25",25},{"r26",26},{"r27",27},{"r28",28},{"r29",29},{"r30",30},{"r31",31},
|
||||
{"at",1},{"v0",2},{"v1",3},
|
||||
{"a0",4},{"a1",5},{"a2",6},{"a3",7},
|
||||
{"t0",8},{"t1",9},{"t2",10},{"t3",11},
|
||||
{"t4",12},{"t5",13},{"t6",14},{"t7",15},
|
||||
{"s0",16},{"s1",17},{"s2",18},{"s3",19},
|
||||
{"s4",20},{"s5",21},{"s6",22},{"s7",23},
|
||||
{"t8",24},{"t9",25},
|
||||
{"k0",26},{"k1",27},
|
||||
{"gp",28},{"sp",29},{"fp",30},{"ra",31}
|
||||
};
|
||||
|
||||
public void SetCpuRegister(string register, int value)
|
||||
{
|
||||
int index = CpuRegisterIndices[register];
|
||||
OctoshockDll.shock_SetRegister_CPU(psx, index, (uint)value);
|
||||
}
|
||||
|
||||
[FeatureNotImplemented]
|
||||
public ITracer Tracer { get { throw new NotImplementedException(); } }
|
||||
|
||||
[FeatureNotImplemented]
|
||||
public IMemoryCallbackSystem MemoryCallbacks { get { throw new NotImplementedException(); } }
|
||||
|
||||
[FeatureNotImplemented]
|
||||
public void StepInto() { throw new NotImplementedException(); }
|
||||
[FeatureNotImplemented]
|
||||
public void StepOut() { throw new NotImplementedException(); }
|
||||
[FeatureNotImplemented]
|
||||
public void StepOver() { throw new NotImplementedException(); }
|
||||
|
||||
#endregion //IDebuggable
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,7 +37,8 @@ namespace BizHawk.Emulation.Cores.Sony.PSX
|
|||
BiosROM = 1, //512K
|
||||
PIOMem = 2, //64K
|
||||
GPURAM = 3, //512K
|
||||
SPURAM = 4 //512K
|
||||
SPURAM = 4, //512K
|
||||
DCache = 5 //1K
|
||||
};
|
||||
|
||||
public enum eShockStateTransaction : int
|
||||
|
@ -117,6 +118,15 @@ namespace BizHawk.Emulation.Cores.Sony.PSX
|
|||
public void* buffer128k;
|
||||
};
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct ShockRegisters_CPU
|
||||
{
|
||||
public fixed uint GPR[32];
|
||||
public uint PC, PC_NEXT;
|
||||
public uint IN_BD_SLOT;
|
||||
public uint LO, HI;
|
||||
public uint SR, CAUSE, EPC;
|
||||
};
|
||||
|
||||
[StructLayout(LayoutKind.Sequential)]
|
||||
public struct ShockStateTransaction
|
||||
|
@ -200,5 +210,10 @@ namespace BizHawk.Emulation.Cores.Sony.PSX
|
|||
[DllImport(dd, CallingConvention = cc)]
|
||||
public static extern int shock_StateTransaction(IntPtr psx, ref ShockStateTransaction transaction);
|
||||
|
||||
[DllImport(dd, CallingConvention = cc)]
|
||||
public static extern int shock_GetRegisters_CPU(IntPtr psx, ref ShockRegisters_CPU buffer);
|
||||
|
||||
[DllImport(dd, CallingConvention = cc)]
|
||||
public static extern int shock_SetRegister_CPU(IntPtr psx, int index, uint value);
|
||||
}
|
||||
}
|
Binary file not shown.
|
@ -232,6 +232,8 @@ class PS_CPU
|
|||
public:
|
||||
void SetCPUHook(void (*cpuh)(const pscpu_timestamp_t timestamp, uint32_t pc), void (*addbt)(uint32_t from, uint32_t to, bool exception));
|
||||
void CheckBreakpoints(void (*callback)(bool write, uint32_t address, unsigned int len), uint32_t instr);
|
||||
void* debug_GetScratchRAMPtr() { return ScratchRAM.data8; }
|
||||
void* debug_GetGPRPtr() { return GPR; }
|
||||
|
||||
enum
|
||||
{
|
||||
|
|
|
@ -2357,6 +2357,7 @@ EW_EXPORT s32 shock_GetMemData(void* psx, void** ptr, s32* size, s32 memType)
|
|||
case eMemType_PIOMem: *ptr = PIOMem->data8; *size = 64*1024; break;
|
||||
case eMemType_GPURAM: *ptr = GPU->GPURAM; *size = 2*512*1024; break;
|
||||
case eMemType_SPURAM: *ptr = SPU->SPURAM; *size = 512*1024; break;
|
||||
case eMemType_DCache: *ptr = CPU->debug_GetScratchRAMPtr(); *size = 1024; break;
|
||||
default:
|
||||
return SHOCK_ERROR;
|
||||
}
|
||||
|
@ -2489,4 +2490,28 @@ EW_EXPORT s32 shock_StateTransaction(void *psx, ShockStateTransaction* transacti
|
|||
default:
|
||||
return SHOCK_ERROR;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
EW_EXPORT s32 shock_GetRegisters_CPU(void* psx, ShockRegisters_CPU* buffer)
|
||||
{
|
||||
memcpy(buffer->GPR,CPU->debug_GetGPRPtr(),32*4);
|
||||
buffer->PC = CPU->GetRegister(PS_CPU::GSREG_PC_NEXT,NULL,0);
|
||||
buffer->PC_NEXT = CPU->GetRegister(PS_CPU::GSREG_PC_NEXT,NULL,0);
|
||||
buffer->IN_BD_SLOT = CPU->GetRegister(PS_CPU::GSREG_IN_BD_SLOT,NULL,0);
|
||||
buffer->LO = CPU->GetRegister(PS_CPU::GSREG_LO,NULL,0);
|
||||
buffer->HI = CPU->GetRegister(PS_CPU::GSREG_HI,NULL,0);
|
||||
buffer->SR = CPU->GetRegister(PS_CPU::GSREG_SR,NULL,0);
|
||||
buffer->CAUSE = CPU->GetRegister(PS_CPU::GSREG_CAUSE,NULL,0);
|
||||
buffer->EPC = CPU->GetRegister(PS_CPU::GSREG_EPC,NULL,0);
|
||||
|
||||
return SHOCK_OK;
|
||||
}
|
||||
|
||||
//Sets a CPU register. Rather than have an enum for the registers, lets just use the index (not offset) within the struct
|
||||
EW_EXPORT s32 shock_SetRegister_CPU(void* psx, s32 index, u32 value)
|
||||
{
|
||||
//takes advantage of layout of GSREG_ matchign our struct (not an accident!)
|
||||
CPU->SetRegister((u32)index,value);
|
||||
|
||||
return SHOCK_OK;
|
||||
}
|
||||
|
|
|
@ -138,7 +138,8 @@ enum eMemType
|
|||
eMemType_BiosROM = 1, //512K
|
||||
eMemType_PIOMem = 2, //64K
|
||||
eMemType_GPURAM = 3, //512K
|
||||
eMemType_SPURAM = 4 //512K
|
||||
eMemType_SPURAM = 4, //512K
|
||||
eMemType_DCache = 5 //1K
|
||||
};
|
||||
|
||||
enum ePeripheralType
|
||||
|
@ -198,6 +199,15 @@ struct ShockTOC
|
|||
u8 disc_type;
|
||||
};
|
||||
|
||||
struct ShockRegisters_CPU
|
||||
{
|
||||
u32 GPR[32];
|
||||
u32 PC, PC_NEXT;
|
||||
u32 IN_BD_SLOT;
|
||||
u32 LO, HI;
|
||||
u32 SR, CAUSE, EPC;
|
||||
};
|
||||
|
||||
// [0] is unused, [100] is for the leadout track.
|
||||
// Also, for convenience, tracks[last_track + 1] will always refer
|
||||
// to the leadout track(even if last_track < 99, IE the leadout track details are duplicated).
|
||||
|
@ -334,3 +344,9 @@ EW_EXPORT s32 shock_GetMemData(void* psx, void** ptr, s32* size, s32 memType);
|
|||
|
||||
//savestate work. Returns the size if that's what was requested, otherwise error codes
|
||||
EW_EXPORT s32 shock_StateTransaction(void *psx, ShockStateTransaction* transaction);
|
||||
|
||||
//Retrieves the CPU registers in a compact struct
|
||||
EW_EXPORT s32 shock_GetRegisters_CPU(void* psx, ShockRegisters_CPU* buffer);
|
||||
|
||||
//Sets a CPU register. Rather than have an enum for the registers, lets just use the index (not offset) within the struct
|
||||
EW_EXPORT s32 shock_SetRegister_CPU(void* psx, s32 index, u32 value);
|
||||
|
|
Loading…
Reference in New Issue