MSXHawk: More trace logger and bug fixes
This commit is contained in:
parent
1c3e823ea2
commit
6637510379
|
@ -53,6 +53,7 @@ namespace BizHawk.Emulation.Cores.Computers.MSX
|
|||
[DllImport("MSXHAWK.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern void MSX_get_video(IntPtr core, int[] videobuf);
|
||||
|
||||
#region Tracer
|
||||
/// <summary>
|
||||
/// type of the cpu trace callback
|
||||
/// </summary>
|
||||
|
@ -68,6 +69,27 @@ namespace BizHawk.Emulation.Cores.Computers.MSX
|
|||
[DllImport("MSXHAWK.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern void MSX_settracecallback(IntPtr core, TraceCallback callback);
|
||||
|
||||
/// <summary>
|
||||
/// get the trace logger header length
|
||||
/// </summary>
|
||||
/// <param name="core">opaque state pointer</param>
|
||||
[DllImport("MSXHAWK.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern int MSX_getheaderlength(IntPtr core);
|
||||
|
||||
/// <summary>
|
||||
/// get the trace logger disassembly length, a constant
|
||||
/// </summary>
|
||||
/// <param name="core">opaque state pointer</param>
|
||||
[DllImport("MSXHAWK.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern int MSX_getdisasmlength(IntPtr core);
|
||||
|
||||
/// <summary>
|
||||
/// get the trace logger register string length, a constant
|
||||
/// </summary>
|
||||
/// <param name="core">opaque state pointer</param>
|
||||
[DllImport("MSXHAWK.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern int MSX_getregstringlength(IntPtr core);
|
||||
|
||||
/// <summary>
|
||||
/// get the trace logger header
|
||||
/// </summary>
|
||||
|
@ -75,16 +97,7 @@ namespace BizHawk.Emulation.Cores.Computers.MSX
|
|||
/// <param name="h">pointer to const char *</param>
|
||||
/// <param name="callback">null to clear</param>
|
||||
[DllImport("MSXHAWK.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern void MSX_getheader(IntPtr core, StringBuilder h);
|
||||
|
||||
/// <summary>
|
||||
/// get the trace logger header length
|
||||
/// </summary>
|
||||
/// <param name="core">opaque state pointer</param>
|
||||
/// <param name="h">pointer to const char *</param>
|
||||
/// <param name="callback">null to clear</param>
|
||||
[DllImport("MSXHAWK.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern int MSX_getheaderlength(IntPtr core);
|
||||
public static extern void MSX_getheader(IntPtr core, StringBuilder h, int l);
|
||||
|
||||
/// <summary>
|
||||
/// get the register state from the cpu
|
||||
|
@ -92,8 +105,9 @@ namespace BizHawk.Emulation.Cores.Computers.MSX
|
|||
/// <param name="core">opaque state pointer</param>
|
||||
/// <param name="r">pointer to const char *</param>
|
||||
/// <param name="t">call type</param>
|
||||
/// <param name="l">copy length, must be obtained from appropriate get legnth function</param>
|
||||
[DllImport("MSXHAWK.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern void MSX_getregisterstate(IntPtr core, StringBuilder h, int t);
|
||||
public static extern void MSX_getregisterstate(IntPtr core, StringBuilder h, int t, int l);
|
||||
|
||||
/// <summary>
|
||||
/// get the register state from the cpu
|
||||
|
@ -101,7 +115,9 @@ namespace BizHawk.Emulation.Cores.Computers.MSX
|
|||
/// <param name="core">opaque state pointer</param>
|
||||
/// <param name="d">pointer to const char *</param>
|
||||
/// <param name="t">call type</param>
|
||||
/// <param name="l">copy length, must be obtained from appropriate get legnth function</param>
|
||||
[DllImport("MSXHAWK.dll", CallingConvention = CallingConvention.Cdecl)]
|
||||
public static extern void MSX_getdisassembly(IntPtr core, StringBuilder h, int t);
|
||||
public static extern void MSX_getdisassembly(IntPtr core, StringBuilder h, int t, int l);
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,9 +39,16 @@ namespace BizHawk.Emulation.Cores.Computers.MSX
|
|||
|
||||
InputCallbacks = new InputCallbackSystem();
|
||||
|
||||
int new_header_size = LibMSX.MSX_getheaderlength(MSX_Pntr);
|
||||
StringBuilder new_header = new StringBuilder(new_header_size);
|
||||
LibMSX.MSX_getheader(MSX_Pntr, new_header);
|
||||
Header_Length = LibMSX.MSX_getheaderlength(MSX_Pntr);
|
||||
Disasm_Length = LibMSX.MSX_getdisasmlength(MSX_Pntr);
|
||||
Reg_String_Length = LibMSX.MSX_getregstringlength(MSX_Pntr);
|
||||
|
||||
StringBuilder new_header = new StringBuilder(Header_Length);
|
||||
LibMSX.MSX_getheader(MSX_Pntr, new_header, Header_Length);
|
||||
|
||||
|
||||
|
||||
Console.WriteLine(Header_Length + " " + Disasm_Length + " " + Reg_String_Length);
|
||||
|
||||
Tracer = new TraceBuffer { Header = new_header.ToString() };
|
||||
|
||||
|
@ -74,15 +81,18 @@ namespace BizHawk.Emulation.Cores.Computers.MSX
|
|||
|
||||
private LibMSX.TraceCallback tracecb;
|
||||
|
||||
// these will be constant values assigned during core construction
|
||||
private int Header_Length;
|
||||
private int Disasm_Length;
|
||||
private int Reg_String_Length;
|
||||
|
||||
private void MakeTrace(int t)
|
||||
{
|
||||
StringBuilder new_d = new StringBuilder(Disasm_Length);
|
||||
StringBuilder new_r = new StringBuilder(Reg_String_Length);
|
||||
|
||||
|
||||
StringBuilder new_d = new StringBuilder(500);
|
||||
StringBuilder new_r = new StringBuilder(500);
|
||||
|
||||
LibMSX.MSX_getdisassembly(MSX_Pntr, new_d, t);
|
||||
LibMSX.MSX_getregisterstate(MSX_Pntr, new_r, t);
|
||||
LibMSX.MSX_getdisassembly(MSX_Pntr, new_d, t, Disasm_Length);
|
||||
LibMSX.MSX_getregisterstate(MSX_Pntr, new_r, t, Reg_String_Length);
|
||||
|
||||
Tracer.Put(new TraceInfo
|
||||
{
|
||||
|
|
|
@ -19,6 +19,7 @@ namespace MSXHawk
|
|||
MemMap.vdp_pntr = &vdp;
|
||||
MemMap.psg_pntr = &psg;
|
||||
cpu.mem_ctrl = &MemMap;
|
||||
vdp.INT_FLAG = &cpu.FlagI;
|
||||
};
|
||||
|
||||
VDP vdp;
|
||||
|
@ -79,7 +80,11 @@ namespace MSXHawk
|
|||
//vdp.ProcessOverscan();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
while (cpu.TotalExecutedCycles < 211936) {
|
||||
cpu.ExecuteOne();
|
||||
}
|
||||
*/
|
||||
return MemMap.lagged;
|
||||
}
|
||||
|
||||
|
@ -95,48 +100,64 @@ namespace MSXHawk
|
|||
}
|
||||
}
|
||||
|
||||
void SetTraceCallback(void (*callback)(int))
|
||||
#pragma region Tracer
|
||||
|
||||
void SetTraceCallback(void (*callback)(int))
|
||||
{
|
||||
cpu.TraceCallback = callback;
|
||||
}
|
||||
|
||||
void GetHeader(char* h)
|
||||
{
|
||||
memcpy(h, cpu.TraceHeader, *(&cpu.TraceHeader + 1) - cpu.TraceHeader);
|
||||
}
|
||||
|
||||
int GetHeaderLength()
|
||||
{
|
||||
return *(&cpu.TraceHeader + 1) - cpu.TraceHeader;
|
||||
return 105 + 1;
|
||||
}
|
||||
|
||||
void GetRegisterState(char* r, int t)
|
||||
int GetDisasmLength()
|
||||
{
|
||||
if (t == 0)
|
||||
{
|
||||
memcpy(r, cpu.CPURegisterState().c_str(), cpu.CPURegisterState().length() + 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(r, cpu.No_Reg, *(&cpu.No_Reg + 1) - cpu.No_Reg);
|
||||
}
|
||||
return 48 + 1;
|
||||
}
|
||||
|
||||
void GetDisassembly(char* d, int t)
|
||||
int GetRegStringLength()
|
||||
{
|
||||
return 86 + 1;
|
||||
}
|
||||
|
||||
void GetHeader(char* h, int l)
|
||||
{
|
||||
memcpy(h, cpu.TraceHeader, l);
|
||||
}
|
||||
|
||||
// the copy length l must be supplied ahead of time from GetRegStrngLength
|
||||
void GetRegisterState(char* r, int t, int l)
|
||||
{
|
||||
if (t == 0)
|
||||
{
|
||||
memcpy(d, cpu.CPUDisassembly().c_str(), cpu.CPUDisassembly().length() + 1);
|
||||
}
|
||||
else if (t == 1)
|
||||
{
|
||||
memcpy(d, cpu.NMI_event, *(&cpu.NMI_event + 1) - cpu.NMI_event);
|
||||
memcpy(r, cpu.CPURegisterState().c_str(), l);
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(d, cpu.IRQ_event, *(&cpu.IRQ_event + 1) - cpu.IRQ_event);
|
||||
memcpy(r, cpu.No_Reg, l);
|
||||
}
|
||||
}
|
||||
|
||||
// the copy length l must be supplied ahead of time from GetDisasmLength
|
||||
void GetDisassembly(char* d, int t, int l)
|
||||
{
|
||||
if (t == 0)
|
||||
{
|
||||
memcpy(d, cpu.CPUDisassembly().c_str(), l);
|
||||
}
|
||||
else if (t == 1)
|
||||
{
|
||||
memcpy(d, cpu.NMI_event, l);
|
||||
}
|
||||
else
|
||||
{
|
||||
memcpy(d, cpu.IRQ_event, l);
|
||||
}
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -46,23 +46,36 @@ MSXHAWK_EXPORT void MSX_settracecallback(MSXCore* p, void (*callback)(int)) {
|
|||
p->SetTraceCallback(callback);
|
||||
}
|
||||
|
||||
// return the cpu trace header
|
||||
MSXHAWK_EXPORT void MSX_getheader(MSXCore* p, char* h) {
|
||||
p->GetHeader(h);
|
||||
}
|
||||
#pragma region Tracer
|
||||
|
||||
// return the cpu trace header length
|
||||
MSXHAWK_EXPORT int MSX_getheaderlength(MSXCore* p) {
|
||||
return p->GetHeaderLength();
|
||||
}
|
||||
|
||||
// return the cpu disassembly length
|
||||
MSXHAWK_EXPORT int MSX_getdisasmlength(MSXCore* p) {
|
||||
return p->GetDisasmLength();
|
||||
}
|
||||
|
||||
// return the cpu register string length
|
||||
MSXHAWK_EXPORT int MSX_getregstringlength(MSXCore* p) {
|
||||
return p->GetRegStringLength();
|
||||
}
|
||||
|
||||
// return the cpu trace header
|
||||
MSXHAWK_EXPORT void MSX_getheader(MSXCore* p, char* h, int l) {
|
||||
p->GetHeader(h, l);
|
||||
}
|
||||
|
||||
// return the cpu register state
|
||||
MSXHAWK_EXPORT void MSX_getregisterstate(MSXCore* p, char* r, int t) {
|
||||
p->GetRegisterState(r, t);
|
||||
MSXHAWK_EXPORT void MSX_getregisterstate(MSXCore* p, char* r, int t, int l) {
|
||||
p->GetRegisterState(r, t, l);
|
||||
}
|
||||
|
||||
// return the cpu disassembly
|
||||
MSXHAWK_EXPORT void MSX_getdisassembly(MSXCore* p, char* d, int t) {
|
||||
p->GetDisassembly(d, t);
|
||||
MSXHAWK_EXPORT void MSX_getdisassembly(MSXCore* p, char* d, int t, int l) {
|
||||
p->GetDisassembly(d, t, l);
|
||||
}
|
||||
|
||||
#pragma endregion
|
|
@ -13,7 +13,7 @@ namespace MSXHawk
|
|||
#pragma region VDP
|
||||
|
||||
// external pointers to CPU
|
||||
bool* INT_FLAG;
|
||||
bool* INT_FLAG = nullptr;
|
||||
// external flags to display background or sprites
|
||||
bool SHOW_BG, SHOW_SPRITES;
|
||||
|
||||
|
|
|
@ -118,8 +118,6 @@ namespace MSXHawk
|
|||
interruptMode = value;
|
||||
}
|
||||
|
||||
char replacer[32] = {};
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#pragma region Constant Declarations
|
||||
|
@ -339,163 +337,205 @@ namespace MSXHawk
|
|||
Regs[R] = ((Regs[R] & 0x80) | temp_R);
|
||||
break;
|
||||
case RD:
|
||||
Read_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
|
||||
Read_Func(cur_instr[instr_pntr], cur_instr[instr_pntr + 1], cur_instr[instr_pntr + 2]);
|
||||
instr_pntr += 3;
|
||||
break;
|
||||
case WR:
|
||||
Write_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
|
||||
Write_Func(cur_instr[instr_pntr], cur_instr[instr_pntr + 1], cur_instr[instr_pntr + 2]);
|
||||
instr_pntr += 3;
|
||||
break;
|
||||
case RD_INC:
|
||||
Read_INC_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
|
||||
Read_INC_Func(cur_instr[instr_pntr], cur_instr[instr_pntr + 1], cur_instr[instr_pntr + 2]);
|
||||
instr_pntr += 3;
|
||||
break;
|
||||
case RD_INC_TR_PC:
|
||||
Read_INC_TR_PC_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++], cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
|
||||
Read_INC_TR_PC_Func(cur_instr[instr_pntr], cur_instr[instr_pntr + 1], cur_instr[instr_pntr + 2], cur_instr[instr_pntr + 3]);
|
||||
instr_pntr += 4;
|
||||
break;
|
||||
case RD_OP:
|
||||
if (cur_instr[instr_pntr++] == 1) { Read_INC_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++], cur_instr[instr_pntr++]); }
|
||||
else { Read_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++], cur_instr[instr_pntr++]); }
|
||||
|
||||
switch (cur_instr[instr_pntr++])
|
||||
if (cur_instr[instr_pntr++] == 1) { Read_INC_Func(cur_instr[instr_pntr], cur_instr[instr_pntr + 1], cur_instr[instr_pntr + 2]); }
|
||||
else { Read_Func(cur_instr[instr_pntr], cur_instr[instr_pntr + 1], cur_instr[instr_pntr + 2]); }
|
||||
instr_pntr += 3;
|
||||
switch (cur_instr[instr_pntr])
|
||||
{
|
||||
case ADD8:
|
||||
ADD8_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
|
||||
ADD8_Func(cur_instr[instr_pntr + 1], cur_instr[instr_pntr + 2]);
|
||||
break;
|
||||
case ADC8:
|
||||
ADC8_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
|
||||
ADC8_Func(cur_instr[instr_pntr + 1], cur_instr[instr_pntr + 2]);
|
||||
break;
|
||||
case SUB8:
|
||||
SUB8_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
|
||||
SUB8_Func(cur_instr[instr_pntr + 1], cur_instr[instr_pntr + 2]);
|
||||
break;
|
||||
case SBC8:
|
||||
SBC8_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
|
||||
SBC8_Func(cur_instr[instr_pntr + 1], cur_instr[instr_pntr + 2]);
|
||||
break;
|
||||
case AND8:
|
||||
AND8_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
|
||||
AND8_Func(cur_instr[instr_pntr + 1], cur_instr[instr_pntr + 2]);
|
||||
break;
|
||||
case XOR8:
|
||||
XOR8_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
|
||||
XOR8_Func(cur_instr[instr_pntr + 1], cur_instr[instr_pntr + 2]);
|
||||
break;
|
||||
case OR8:
|
||||
OR8_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
|
||||
OR8_Func(cur_instr[instr_pntr + 1], cur_instr[instr_pntr + 2]);
|
||||
break;
|
||||
case CP8:
|
||||
CP8_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
|
||||
CP8_Func(cur_instr[instr_pntr + 1], cur_instr[instr_pntr + 2]);
|
||||
break;
|
||||
case TR:
|
||||
TR_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
|
||||
TR_Func(cur_instr[instr_pntr + 1], cur_instr[instr_pntr + 2]);
|
||||
break;
|
||||
}
|
||||
instr_pntr += 3;
|
||||
break;
|
||||
case WR_INC:
|
||||
Write_INC_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
|
||||
Write_INC_Func(cur_instr[instr_pntr], cur_instr[instr_pntr + 1], cur_instr[instr_pntr + 2]);
|
||||
instr_pntr += 3;
|
||||
break;
|
||||
case WR_DEC:
|
||||
Write_DEC_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
|
||||
Write_DEC_Func(cur_instr[instr_pntr], cur_instr[instr_pntr + 1], cur_instr[instr_pntr + 2]);
|
||||
instr_pntr += 3;
|
||||
break;
|
||||
case WR_TR_PC:
|
||||
Write_TR_PC_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
|
||||
Write_TR_PC_Func(cur_instr[instr_pntr], cur_instr[instr_pntr + 1], cur_instr[instr_pntr + 2]);
|
||||
instr_pntr += 3;
|
||||
break;
|
||||
case WR_INC_WA:
|
||||
Write_INC_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
|
||||
Write_INC_Func(cur_instr[instr_pntr], cur_instr[instr_pntr + 1], cur_instr[instr_pntr + 2]);
|
||||
instr_pntr += 3;
|
||||
Regs[W] = Regs[A];
|
||||
break;
|
||||
case TR:
|
||||
TR_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
|
||||
TR_Func(cur_instr[instr_pntr], cur_instr[instr_pntr + 1]);
|
||||
instr_pntr += 2;
|
||||
break;
|
||||
case TR16:
|
||||
TR16_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++], cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
|
||||
TR16_Func(cur_instr[instr_pntr], cur_instr[instr_pntr + 1], cur_instr[instr_pntr + 2], cur_instr[instr_pntr + 3]);
|
||||
instr_pntr += 4;
|
||||
break;
|
||||
case ADD16:
|
||||
ADD16_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++], cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
|
||||
ADD16_Func(cur_instr[instr_pntr], cur_instr[instr_pntr + 1], cur_instr[instr_pntr + 2], cur_instr[instr_pntr + 3]);
|
||||
instr_pntr += 4;
|
||||
break;
|
||||
case ADD8:
|
||||
ADD8_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
|
||||
ADD8_Func(cur_instr[instr_pntr], cur_instr[instr_pntr + 1]);
|
||||
instr_pntr += 2;
|
||||
break;
|
||||
case SUB8:
|
||||
SUB8_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
|
||||
SUB8_Func(cur_instr[instr_pntr], cur_instr[instr_pntr + 1]);
|
||||
instr_pntr += 2;
|
||||
break;
|
||||
case ADC8:
|
||||
ADC8_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
|
||||
ADC8_Func(cur_instr[instr_pntr], cur_instr[instr_pntr + 1]);
|
||||
instr_pntr += 2;
|
||||
break;
|
||||
case ADC16:
|
||||
ADC_16_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++], cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
|
||||
ADC_16_Func(cur_instr[instr_pntr], cur_instr[instr_pntr + 1], cur_instr[instr_pntr + 2], cur_instr[instr_pntr + 3]);
|
||||
instr_pntr += 4;
|
||||
break;
|
||||
case SBC8:
|
||||
SBC8_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
|
||||
SBC8_Func(cur_instr[instr_pntr], cur_instr[instr_pntr + 1]);
|
||||
instr_pntr += 2;
|
||||
break;
|
||||
case SBC16:
|
||||
SBC_16_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++], cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
|
||||
SBC_16_Func(cur_instr[instr_pntr], cur_instr[instr_pntr + 1], cur_instr[instr_pntr + 2], cur_instr[instr_pntr + 3]);
|
||||
instr_pntr += 4;
|
||||
break;
|
||||
case INC16:
|
||||
INC16_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
|
||||
INC16_Func(cur_instr[instr_pntr], cur_instr[instr_pntr + 1]);
|
||||
instr_pntr += 2;
|
||||
break;
|
||||
case INC8:
|
||||
INC8_Func(cur_instr[instr_pntr++]);
|
||||
INC8_Func(cur_instr[instr_pntr]);
|
||||
instr_pntr += 1;
|
||||
break;
|
||||
case DEC16:
|
||||
DEC16_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
|
||||
DEC16_Func(cur_instr[instr_pntr], cur_instr[instr_pntr + 1]);
|
||||
instr_pntr += 2;
|
||||
break;
|
||||
case DEC8:
|
||||
DEC8_Func(cur_instr[instr_pntr++]);
|
||||
DEC8_Func(cur_instr[instr_pntr]);
|
||||
instr_pntr += 1;
|
||||
break;
|
||||
case RLC:
|
||||
RLC_Func(cur_instr[instr_pntr++]);
|
||||
RLC_Func(cur_instr[instr_pntr]);
|
||||
instr_pntr += 1;
|
||||
break;
|
||||
case RL:
|
||||
RL_Func(cur_instr[instr_pntr++]);
|
||||
RL_Func(cur_instr[instr_pntr]);
|
||||
instr_pntr += 1;
|
||||
break;
|
||||
case RRC:
|
||||
RRC_Func(cur_instr[instr_pntr++]);
|
||||
RRC_Func(cur_instr[instr_pntr]);
|
||||
instr_pntr += 1;
|
||||
break;
|
||||
case RR:
|
||||
RR_Func(cur_instr[instr_pntr++]);
|
||||
RR_Func(cur_instr[instr_pntr]);
|
||||
instr_pntr += 1;
|
||||
break;
|
||||
case CPL:
|
||||
CPL_Func(cur_instr[instr_pntr++]);
|
||||
CPL_Func(cur_instr[instr_pntr]);
|
||||
instr_pntr += 1;
|
||||
break;
|
||||
case DA:
|
||||
DA_Func(cur_instr[instr_pntr++]);
|
||||
DA_Func(cur_instr[instr_pntr]);
|
||||
instr_pntr += 1;
|
||||
break;
|
||||
case SCF:
|
||||
SCF_Func(cur_instr[instr_pntr++]);
|
||||
SCF_Func(cur_instr[instr_pntr]);
|
||||
instr_pntr += 1;
|
||||
break;
|
||||
case CCF:
|
||||
CCF_Func(cur_instr[instr_pntr++]);
|
||||
CCF_Func(cur_instr[instr_pntr]);
|
||||
instr_pntr += 1;
|
||||
break;
|
||||
case AND8:
|
||||
AND8_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
|
||||
AND8_Func(cur_instr[instr_pntr], cur_instr[instr_pntr + 1]);
|
||||
instr_pntr += 2;
|
||||
break;
|
||||
case XOR8:
|
||||
XOR8_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
|
||||
XOR8_Func(cur_instr[instr_pntr], cur_instr[instr_pntr + 1]);
|
||||
instr_pntr += 2;
|
||||
break;
|
||||
case OR8:
|
||||
OR8_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
|
||||
OR8_Func(cur_instr[instr_pntr], cur_instr[instr_pntr + 1]);
|
||||
instr_pntr += 2;
|
||||
break;
|
||||
case CP8:
|
||||
CP8_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
|
||||
CP8_Func(cur_instr[instr_pntr], cur_instr[instr_pntr + 1]);
|
||||
instr_pntr += 2;
|
||||
break;
|
||||
case SLA:
|
||||
SLA_Func(cur_instr[instr_pntr++]);
|
||||
SLA_Func(cur_instr[instr_pntr]);
|
||||
instr_pntr += 1;
|
||||
break;
|
||||
case SRA:
|
||||
SRA_Func(cur_instr[instr_pntr++]);
|
||||
SRA_Func(cur_instr[instr_pntr]);
|
||||
instr_pntr += 1;
|
||||
break;
|
||||
case SRL:
|
||||
SRL_Func(cur_instr[instr_pntr++]);
|
||||
SRL_Func(cur_instr[instr_pntr]);
|
||||
instr_pntr += 1;
|
||||
break;
|
||||
case SLL:
|
||||
SLL_Func(cur_instr[instr_pntr++]);
|
||||
SLL_Func(cur_instr[instr_pntr]);
|
||||
instr_pntr += 1;
|
||||
break;
|
||||
case BIT:
|
||||
BIT_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
|
||||
BIT_Func(cur_instr[instr_pntr], cur_instr[instr_pntr + 1]);
|
||||
instr_pntr += 2;
|
||||
break;
|
||||
case I_BIT:
|
||||
I_BIT_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
|
||||
I_BIT_Func(cur_instr[instr_pntr], cur_instr[instr_pntr + 1]);
|
||||
instr_pntr += 2;
|
||||
break;
|
||||
case RES:
|
||||
RES_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
|
||||
RES_Func(cur_instr[instr_pntr], cur_instr[instr_pntr + 1]);
|
||||
instr_pntr += 2;
|
||||
break;
|
||||
case SET:
|
||||
SET_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
|
||||
SET_Func(cur_instr[instr_pntr], cur_instr[instr_pntr + 1]);
|
||||
instr_pntr += 2;
|
||||
break;
|
||||
case EI:
|
||||
EI_pending = 2;
|
||||
|
@ -512,7 +552,8 @@ namespace MSXHawk
|
|||
EXCH_16_Func(L_s, H_s, L, H);
|
||||
break;
|
||||
case EXCH_16:
|
||||
EXCH_16_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++], cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
|
||||
EXCH_16_Func(cur_instr[instr_pntr], cur_instr[instr_pntr + 1], cur_instr[instr_pntr + 2], cur_instr[instr_pntr + 3]);
|
||||
instr_pntr += 4;
|
||||
break;
|
||||
case PREFIX:
|
||||
src_t = PRE_SRC;
|
||||
|
@ -548,10 +589,12 @@ namespace MSXHawk
|
|||
|
||||
break;
|
||||
case ASGN:
|
||||
ASGN_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
|
||||
ASGN_Func(cur_instr[instr_pntr], cur_instr[instr_pntr + 1]);
|
||||
instr_pntr += 2;
|
||||
break;
|
||||
case ADDS:
|
||||
ADDS_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++], cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
|
||||
ADDS_Func(cur_instr[instr_pntr], cur_instr[instr_pntr + 1], cur_instr[instr_pntr + 2], cur_instr[instr_pntr + 3]);
|
||||
instr_pntr += 4;
|
||||
break;
|
||||
case EI_RETI:
|
||||
// NOTE: This is needed for systems using multiple interrupt sources, it triggers the next interrupt
|
||||
|
@ -562,31 +605,40 @@ namespace MSXHawk
|
|||
IFF1 = IFF2;
|
||||
break;
|
||||
case OUT:
|
||||
OUT_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
|
||||
OUT_Func(cur_instr[instr_pntr], cur_instr[instr_pntr + 1], cur_instr[instr_pntr + 2]);
|
||||
instr_pntr += 3;
|
||||
break;
|
||||
case OUT_INC:
|
||||
OUT_INC_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
|
||||
OUT_INC_Func(cur_instr[instr_pntr], cur_instr[instr_pntr + 1], cur_instr[instr_pntr + 2]);
|
||||
instr_pntr += 3;
|
||||
break;
|
||||
case IN:
|
||||
IN_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
|
||||
IN_Func(cur_instr[instr_pntr], cur_instr[instr_pntr + 1], cur_instr[instr_pntr + 2]);
|
||||
instr_pntr += 3;
|
||||
break;
|
||||
case IN_INC:
|
||||
IN_INC_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
|
||||
IN_INC_Func(cur_instr[instr_pntr], cur_instr[instr_pntr + 1], cur_instr[instr_pntr + 2]);
|
||||
instr_pntr += 3;
|
||||
break;
|
||||
case IN_A_N_INC:
|
||||
IN_A_N_INC_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
|
||||
IN_A_N_INC_Func(cur_instr[instr_pntr], cur_instr[instr_pntr + 1], cur_instr[instr_pntr + 2]);
|
||||
instr_pntr += 3;
|
||||
break;
|
||||
case NEG:
|
||||
NEG_8_Func(cur_instr[instr_pntr++]);
|
||||
NEG_8_Func(cur_instr[instr_pntr]);
|
||||
instr_pntr += 1;
|
||||
break;
|
||||
case INT_MODE:
|
||||
interruptMode = cur_instr[instr_pntr++];
|
||||
interruptMode = cur_instr[instr_pntr];
|
||||
instr_pntr += 1;
|
||||
break;
|
||||
case RRD:
|
||||
RRD_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
|
||||
RRD_Func(cur_instr[instr_pntr], cur_instr[instr_pntr + 1]);
|
||||
instr_pntr += 2;
|
||||
break;
|
||||
case RLD:
|
||||
RLD_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
|
||||
RLD_Func(cur_instr[instr_pntr], cur_instr[instr_pntr + 1]);
|
||||
instr_pntr += 2;
|
||||
break;
|
||||
case SET_FL_LD_R:
|
||||
DEC16_Func(C, B);
|
||||
|
@ -666,7 +718,8 @@ namespace MSXHawk
|
|||
Regs[W] = 0;
|
||||
break;
|
||||
case REP_OP_I:
|
||||
Write_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
|
||||
Write_Func(cur_instr[instr_pntr], cur_instr[instr_pntr + 1], cur_instr[instr_pntr + 2]);
|
||||
instr_pntr += 3;
|
||||
|
||||
Ztemp4 = cur_instr[instr_pntr++];
|
||||
if (Ztemp4 == DEC16)
|
||||
|
@ -722,7 +775,8 @@ namespace MSXHawk
|
|||
}
|
||||
break;
|
||||
case REP_OP_O:
|
||||
OUT_Func(cur_instr[instr_pntr++], cur_instr[instr_pntr++], cur_instr[instr_pntr++]);
|
||||
OUT_Func(cur_instr[instr_pntr], cur_instr[instr_pntr + 1], cur_instr[instr_pntr + 2]);
|
||||
instr_pntr += 3;
|
||||
|
||||
Ztemp4 = cur_instr[instr_pntr++];
|
||||
if (Ztemp4 == DEC16)
|
||||
|
@ -4449,56 +4503,63 @@ namespace MSXHawk
|
|||
|
||||
#pragma region Disassemble
|
||||
|
||||
// disassemblies will also return strings of the same length
|
||||
const char* TraceHeader = "Z80A: PC, machine code, mnemonic, operands, registers (AF, BC, DE, HL, IX, IY, SP, Cy), flags (CNP3H5ZS)";
|
||||
const char* NMI_event = "====NMI====";
|
||||
const char* IRQ_event = "====IRQ====";
|
||||
const char* No_Reg = "Q";
|
||||
const char* NMI_event = " ====NMI==== ";
|
||||
const char* IRQ_event = " ====IRQ==== ";
|
||||
const char* No_Reg = " ";
|
||||
const char* Reg_template = "AF:AAFF BC:BBCC DE:DDEE HL:HHLL Ix:IxIx Iy:IyIy SP:SPSP Cy:FEDCBA9876543210 CNP3H5ZSE";
|
||||
const char* Disasm_template = "PCPC: AA BB CC DD Di Di, XXXXX ";
|
||||
|
||||
char replacer[32] = {};
|
||||
char* val_char_1 = nullptr;
|
||||
char* val_char_2 = nullptr;
|
||||
int temp_reg;
|
||||
|
||||
|
||||
void (*TraceCallback)(int);
|
||||
|
||||
string CPURegisterState()
|
||||
{
|
||||
string reg_state = " ";
|
||||
|
||||
char* val_char = replacer;
|
||||
{
|
||||
val_char_1 = replacer;
|
||||
|
||||
int temp_reg = (Regs[A] << 8) + Regs[F];
|
||||
sprintf_s(val_char, 5, "%04X", temp_reg);
|
||||
reg_state.append(val_char, 4);
|
||||
reg_state.append(" ");
|
||||
|
||||
string reg_state = "AF:";
|
||||
temp_reg = (Regs[A] << 8) + Regs[F];
|
||||
sprintf_s(val_char_1, 5, "%04X", temp_reg);
|
||||
reg_state.append(val_char_1, 4);
|
||||
|
||||
reg_state.append(" BC:");
|
||||
temp_reg = (Regs[B] << 8) + Regs[C];
|
||||
sprintf_s(val_char, 5, "%04X", temp_reg);
|
||||
reg_state.append(val_char, 4);
|
||||
reg_state.append(" ");
|
||||
|
||||
sprintf_s(val_char_1, 5, "%04X", temp_reg);
|
||||
reg_state.append(val_char_1, 4);
|
||||
|
||||
reg_state.append(" DE:");
|
||||
temp_reg = (Regs[D] << 8) + Regs[E];
|
||||
sprintf_s(val_char, 5, "%04X", temp_reg);
|
||||
reg_state.append(val_char, 4);
|
||||
reg_state.append(" ");
|
||||
sprintf_s(val_char_1, 5, "%04X", temp_reg);
|
||||
reg_state.append(val_char_1, 4);
|
||||
|
||||
reg_state.append(" HL:");
|
||||
temp_reg = (Regs[H] << 8) + Regs[L];
|
||||
sprintf_s(val_char, 5, "%04X", temp_reg);
|
||||
reg_state.append(val_char, 4);
|
||||
reg_state.append(" ");
|
||||
sprintf_s(val_char_1, 5, "%04X", temp_reg);
|
||||
reg_state.append(val_char_1, 4);
|
||||
|
||||
reg_state.append(" Ix:");
|
||||
temp_reg = (Regs[Ixh] << 8) + Regs[Ixl];
|
||||
sprintf_s(val_char, 5, "%04X", temp_reg);
|
||||
reg_state.append(val_char, 4);
|
||||
reg_state.append(" ");
|
||||
sprintf_s(val_char_1, 5, "%04X", temp_reg);
|
||||
reg_state.append(val_char_1, 4);
|
||||
|
||||
reg_state.append(" Iy:");
|
||||
temp_reg = (Regs[Iyh] << 8) + Regs[Iyl];
|
||||
sprintf_s(val_char, 5, "%04X", temp_reg);
|
||||
reg_state.append(val_char, 4);
|
||||
reg_state.append(" ");
|
||||
sprintf_s(val_char_1, 5, "%04X", temp_reg);
|
||||
reg_state.append(val_char_1, 4);
|
||||
|
||||
reg_state.append(" SP:");
|
||||
temp_reg = (Regs[SPh] << 8) + Regs[SPl];
|
||||
sprintf_s(val_char, 5, "%04X", temp_reg);
|
||||
reg_state.append(val_char, 4);
|
||||
reg_state.append(" ");
|
||||
|
||||
int tot_long = sprintf_s(val_char, 32, "%16u", TotalExecutedCycles);
|
||||
reg_state.append(val_char, tot_long);
|
||||
sprintf_s(val_char_1, 5, "%04X", temp_reg);
|
||||
reg_state.append(val_char_1, 4);
|
||||
|
||||
reg_state.append(" Cy:");
|
||||
reg_state.append(val_char_1, sprintf_s(val_char_1, 32, "%16u", TotalExecutedCycles));
|
||||
reg_state.append(" ");
|
||||
|
||||
reg_state.append(FlagCget() ? "C" : "c");
|
||||
|
@ -4523,7 +4584,14 @@ namespace MSXHawk
|
|||
string disasm = Disassemble(RegPCget(), bytes_read_ptr);
|
||||
string byte_code = "";
|
||||
|
||||
for (uint32_t i = 0; i < bytes_read; i++)
|
||||
val_char_1 = replacer;
|
||||
sprintf_s(val_char_1, 5, "%04X", RegPCget() & 0xFFFF);
|
||||
byte_code.append(val_char_1, 4);
|
||||
byte_code.append(": ");
|
||||
|
||||
uint32_t i = 0;
|
||||
|
||||
for (i = 0; i < bytes_read; i++)
|
||||
{
|
||||
bank_num = bank_offset = (RegPCget() + i) & 0xFFFF;
|
||||
bank_offset &= low_mask;
|
||||
|
@ -4534,15 +4602,20 @@ namespace MSXHawk
|
|||
string val1(val_char_1, 2);
|
||||
|
||||
byte_code.append(val1);
|
||||
if (i < (bytes_read - 1))
|
||||
{
|
||||
byte_code.append(" ");
|
||||
}
|
||||
byte_code.append(" ");
|
||||
}
|
||||
|
||||
while (i < 4)
|
||||
{
|
||||
byte_code.append(" ");
|
||||
i++;
|
||||
}
|
||||
|
||||
byte_code.append(" ");
|
||||
|
||||
byte_code.append(disasm);
|
||||
|
||||
while (byte_code.length() < 32)
|
||||
while (byte_code.length() < 48)
|
||||
{
|
||||
byte_code.append(" ");
|
||||
}
|
||||
|
@ -4565,7 +4638,7 @@ namespace MSXHawk
|
|||
bank_num = (bank_num >> bank_shift) & high_mask;
|
||||
addr++;
|
||||
|
||||
char* val_char_1 = replacer;
|
||||
val_char_1 = replacer;
|
||||
sprintf_s(val_char_1, 5, "%02X", MemoryMap[bank_num][bank_offset]);
|
||||
string val1(val_char_1, 2);
|
||||
|
||||
|
@ -4574,7 +4647,7 @@ namespace MSXHawk
|
|||
bank_num = (bank_num >> bank_shift)& high_mask;
|
||||
addr++;
|
||||
|
||||
char* val_char_2 = replacer;
|
||||
val_char_2 = replacer;
|
||||
sprintf_s(val_char_2, 5, "%02X", MemoryMap[bank_num][bank_offset]);
|
||||
string val2(val_char_2, 2);
|
||||
|
||||
|
@ -4592,7 +4665,7 @@ namespace MSXHawk
|
|||
bank_num = (bank_num >> bank_shift)& high_mask;
|
||||
addr++;
|
||||
|
||||
char* val_char_1 = replacer;
|
||||
val_char_1 = replacer;
|
||||
sprintf_s(val_char_1, 5, "%02X", MemoryMap[bank_num][bank_offset]);
|
||||
string val1(val_char_1, 2);
|
||||
|
||||
|
@ -4609,7 +4682,7 @@ namespace MSXHawk
|
|||
bank_num = (bank_num >> bank_shift)& high_mask;
|
||||
addr++;
|
||||
|
||||
char* val_char_1 = replacer;
|
||||
val_char_1 = replacer;
|
||||
sprintf_s(val_char_1, 5, "%u", MemoryMap[bank_num][bank_offset]);
|
||||
string val1(val_char_1, 2);
|
||||
|
||||
|
@ -4627,7 +4700,7 @@ namespace MSXHawk
|
|||
|
||||
int8_t temp = (int8_t)MemoryMap[bank_num][bank_offset];
|
||||
|
||||
char* val_char_1 = replacer;
|
||||
val_char_1 = replacer;
|
||||
sprintf_s(val_char_1, 5, "%d", temp);
|
||||
string val1(val_char_1, 3);
|
||||
|
||||
|
|
Loading…
Reference in New Issue