MSXHawk: More trace logger and bug fixes

This commit is contained in:
alyosha-tas 2020-01-16 18:53:11 -05:00
parent 1c3e823ea2
commit 6637510379
6 changed files with 302 additions and 169 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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