psx - add cpu registers get/set

This commit is contained in:
zeromus 2014-12-15 05:28:06 +00:00
parent 7b580e7dca
commit ee1e99fc49
6 changed files with 136 additions and 4 deletions

View File

@ -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
}
}

View File

@ -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.

View File

@ -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
{

View File

@ -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;
}

View File

@ -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);