diff --git a/BizHawk.Emulation.Cores/Computers/MSX/LibMSX.cs b/BizHawk.Emulation.Cores/Computers/MSX/LibMSX.cs
index c0a683a06c..8daa0225e2 100644
--- a/BizHawk.Emulation.Cores/Computers/MSX/LibMSX.cs
+++ b/BizHawk.Emulation.Cores/Computers/MSX/LibMSX.cs
@@ -1,6 +1,7 @@
using System;
using System.Runtime.InteropServices;
using BizHawk.Emulation.Common;
+using System.Text;
namespace BizHawk.Emulation.Cores.Computers.MSX
{
@@ -39,5 +40,68 @@ namespace BizHawk.Emulation.Cores.Computers.MSX
/// 0 on success, negative value on failure.
[DllImport("MSXHAWK.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern bool MSX_frame_advance(IntPtr core, byte ctrl1, byte ctrl2, bool render, bool sound);
+
+ ///
+ /// Get Video data
+ ///
+ /// opaque state pointer
+ /// controller data for player 1
+ /// controller data for player 2
+ /// length of romdata in bytes
+ /// Mapper number to load core with
+ /// 0 on success, negative value on failure.
+ [DllImport("MSXHAWK.dll", CallingConvention = CallingConvention.Cdecl)]
+ public static extern void MSX_get_video(IntPtr core, int[] videobuf);
+
+ ///
+ /// type of the cpu trace callback
+ ///
+ /// type of event
+ [UnmanagedFunctionPointer(CallingConvention.Cdecl)]
+ public delegate void TraceCallback(int t);
+
+ ///
+ /// set a callback for trace logging
+ ///
+ /// opaque state pointer
+ /// null to clear
+ [DllImport("MSXHAWK.dll", CallingConvention = CallingConvention.Cdecl)]
+ public static extern void MSX_settracecallback(IntPtr core, TraceCallback callback);
+
+ ///
+ /// get the trace logger header
+ ///
+ /// opaque state pointer
+ /// pointer to const char *
+ /// null to clear
+ [DllImport("MSXHAWK.dll", CallingConvention = CallingConvention.Cdecl)]
+ public static extern void MSX_getheader(IntPtr core, StringBuilder h);
+
+ ///
+ /// get the trace logger header length
+ ///
+ /// opaque state pointer
+ /// pointer to const char *
+ /// null to clear
+ [DllImport("MSXHAWK.dll", CallingConvention = CallingConvention.Cdecl)]
+ public static extern int MSX_getheaderlength(IntPtr core);
+
+ ///
+ /// get the register state from the cpu
+ ///
+ /// opaque state pointer
+ /// pointer to const char *
+ /// call type
+ [DllImport("MSXHAWK.dll", CallingConvention = CallingConvention.Cdecl)]
+ public static extern void MSX_getregisterstate(IntPtr core, StringBuilder h, int t);
+
+ ///
+ /// get the register state from the cpu
+ ///
+ /// opaque state pointer
+ /// pointer to const char *
+ /// call type
+ [DllImport("MSXHAWK.dll", CallingConvention = CallingConvention.Cdecl)]
+ public static extern void MSX_getdisassembly(IntPtr core, StringBuilder h, int t);
}
}
diff --git a/BizHawk.Emulation.Cores/Computers/MSX/MSX.IEmulator.cs b/BizHawk.Emulation.Cores/Computers/MSX/MSX.IEmulator.cs
index a20cc9c4bb..dcf2e50b35 100644
--- a/BizHawk.Emulation.Cores/Computers/MSX/MSX.IEmulator.cs
+++ b/BizHawk.Emulation.Cores/Computers/MSX/MSX.IEmulator.cs
@@ -23,8 +23,21 @@ namespace BizHawk.Emulation.Cores.Computers.MSX
_controller = controller;
_frame++;
+
+ if (Tracer.Enabled)
+ {
+ tracecb = MakeTrace;
+ }
+ else
+ {
+ tracecb = null;
+ }
- return LibMSX.MSX_frame_advance(MSX_Pntr, 0, 0, true, true);
+ LibMSX.MSX_settracecallback(MSX_Pntr, tracecb);
+
+ LibMSX.MSX_frame_advance(MSX_Pntr, 0, 0, true, true);
+
+ return true;
}
public int Frame => _frame;
@@ -119,13 +132,12 @@ namespace BizHawk.Emulation.Cores.Computers.MSX
#region Video
public int _frameHz = 60;
- public int[] _vidbuffer;
-
- public int[] frame_buffer = new int[160 * 144];
+ public int[] _vidbuffer = new int[160 * 144];
public int[] GetVideoBuffer()
{
- return frame_buffer;
+ LibMSX.MSX_get_video(MSX_Pntr, _vidbuffer);
+ return _vidbuffer;
}
public int VirtualWidth => 160;
diff --git a/BizHawk.Emulation.Cores/Computers/MSX/MSX.cs b/BizHawk.Emulation.Cores/Computers/MSX/MSX.cs
index b534ad87f1..8b5f6ab858 100644
--- a/BizHawk.Emulation.Cores/Computers/MSX/MSX.cs
+++ b/BizHawk.Emulation.Cores/Computers/MSX/MSX.cs
@@ -1,5 +1,5 @@
using System;
-
+using System.Text;
using BizHawk.Emulation.Common;
namespace BizHawk.Emulation.Cores.Computers.MSX
@@ -39,8 +39,14 @@ namespace BizHawk.Emulation.Cores.Computers.MSX
InputCallbacks = new InputCallbackSystem();
- //var serviceProvider = ServiceProvider as BasicServiceProvider;
- //serviceProvider.Register(Tracer);
+ int new_header_size = LibMSX.MSX_getheaderlength(MSX_Pntr);
+ StringBuilder new_header = new StringBuilder(new_header_size);
+ LibMSX.MSX_getheader(MSX_Pntr, new_header);
+
+ Tracer = new TraceBuffer { Header = new_header.ToString() };
+
+ var serviceProvider = ServiceProvider as BasicServiceProvider;
+ serviceProvider.Register(Tracer);
}
public void HardReset()
@@ -63,7 +69,29 @@ namespace BizHawk.Emulation.Cores.Computers.MSX
public DisplayType Region => DisplayType.NTSC;
- private readonly ITraceable Tracer;
+ #region Trace Logger
+ private ITraceable Tracer;
+
+ private LibMSX.TraceCallback tracecb;
+
+ private void MakeTrace(int t)
+ {
+
+
+ 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);
+
+ Tracer.Put(new TraceInfo
+ {
+ Disassembly = new_d.ToString().PadRight(36),
+ RegisterInfo = new_r.ToString()
+ });
+ }
+
+ #endregion
private MemoryCallbackSystem _memorycallbacks = new MemoryCallbackSystem(new[] { "System Bus" });
public IMemoryCallbackSystem MemoryCallbacks => _memorycallbacks;
diff --git a/libHawk/MSXHawk/MSXHawk/Core.h b/libHawk/MSXHawk/MSXHawk/Core.h
index 3e8c433c90..640268d9da 100644
--- a/libHawk/MSXHawk/MSXHawk/Core.h
+++ b/libHawk/MSXHawk/MSXHawk/Core.h
@@ -21,6 +21,11 @@ namespace MSXHawk
cpu.mem_ctrl = &MemMap;
};
+ VDP vdp;
+ Z80A cpu;
+ SN76489sms psg;
+ MemoryManager MemMap;
+
void Load_ROM(uint8_t* ext_rom, uint32_t ext_rom_size, uint32_t ext_rom_mapper)
{
MemMap.Load_ROM(ext_rom, ext_rom_size, ext_rom_mapper);
@@ -78,10 +83,60 @@ namespace MSXHawk
return MemMap.lagged;
}
- VDP vdp;
- Z80A cpu;
- SN76489sms psg;
- MemoryManager MemMap;
+ void GetVideo(uint32_t* dest) {
+ uint32_t* src = vdp.GameGearFrameBuffer;
+ uint32_t* dst = dest;
+
+ for (int i = 0; i < 144; i++)
+ {
+ std::memcpy(dst, src, sizeof uint32_t * 160);
+ src += 160;
+ dst += 160;
+ }
+ }
+
+ 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;
+ }
+
+ void GetRegisterState(char* r, int t)
+ {
+ 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);
+ }
+ }
+
+ void GetDisassembly(char* d, int t)
+ {
+ 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);
+ }
+ else
+ {
+ memcpy(d, cpu.IRQ_event, *(&cpu.IRQ_event + 1) - cpu.IRQ_event);
+ }
+ }
};
}
diff --git a/libHawk/MSXHawk/MSXHawk/MSXHawk.cpp b/libHawk/MSXHawk/MSXHawk/MSXHawk.cpp
index 2e30e62d82..314cb10db8 100644
--- a/libHawk/MSXHawk/MSXHawk/MSXHawk.cpp
+++ b/libHawk/MSXHawk/MSXHawk/MSXHawk.cpp
@@ -35,3 +35,34 @@ MSXHAWK_EXPORT void MSX_frame_advance(MSXCore* p, uint8_t ctrl1, uint8_t ctrl2,
p->FrameAdvance(ctrl1, ctrl2, render, sound);
}
+// send video data to external video provider
+MSXHAWK_EXPORT void MSX_get_video(MSXCore* p, uint32_t* dest)
+{
+ p->GetVideo(dest);
+}
+
+// set tracer callback
+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);
+}
+
+// return the cpu trace header length
+MSXHAWK_EXPORT int MSX_getheaderlength(MSXCore* p) {
+ return p->GetHeaderLength();
+}
+
+// return the cpu register state
+MSXHAWK_EXPORT void MSX_getregisterstate(MSXCore* p, char* r, int t) {
+ p->GetRegisterState(r, t);
+}
+
+// return the cpu disassembly
+MSXHAWK_EXPORT void MSX_getdisassembly(MSXCore* p, char* d, int t) {
+ p->GetDisassembly(d, t);
+}
+
diff --git a/libHawk/MSXHawk/MSXHawk/VDP.h b/libHawk/MSXHawk/MSXHawk/VDP.h
index 902373b4fd..66ba7fb2d4 100644
--- a/libHawk/MSXHawk/MSXHawk/VDP.h
+++ b/libHawk/MSXHawk/MSXHawk/VDP.h
@@ -59,8 +59,8 @@ namespace MSXHawk
int32_t IPeriod = 228;
int32_t FrameHeight = 192;
- int32_t FrameBuffer[256 * 244];
- int32_t GameGearFrameBuffer[160 * 144];
+ uint32_t FrameBuffer[256 * 244];
+ uint32_t GameGearFrameBuffer[160 * 144];
int32_t OverscanFrameBuffer[1];
int32_t ScanLine;
diff --git a/libHawk/MSXHawk/MSXHawk/Z80A.h b/libHawk/MSXHawk/MSXHawk/Z80A.h
index 4bf6ac0267..84ea44bca6 100644
--- a/libHawk/MSXHawk/MSXHawk/Z80A.h
+++ b/libHawk/MSXHawk/MSXHawk/Z80A.h
@@ -118,6 +118,8 @@ namespace MSXHawk
interruptMode = value;
}
+ char replacer[32] = {};
+
#pragma endregion
#pragma region Constant Declarations
@@ -263,8 +265,8 @@ namespace MSXHawk
Z80A()
{
- //Reset();
- //InitTableParity();
+ Reset();
+ InitTableParity();
}
void Reset()
@@ -308,7 +310,9 @@ namespace MSXHawk
case OP_F:
// Read the opcode of the next instruction
//if (OnExecFetch != null) OnExecFetch(RegPC);
- //if (TraceCallback != null) TraceCallback(State());
+
+ if (TraceCallback) { TraceCallback(0); }
+
bank_num = bank_offset = RegPCget();
bank_offset &= low_mask;
bank_num = (bank_num >> bank_shift)& high_mask;
@@ -786,12 +790,9 @@ namespace MSXHawk
if (nonMaskableInterruptPending)
{
nonMaskableInterruptPending = false;
- /*
- if (TraceCallback != null)
- {
- TraceCallback(new TraceInfo{ Disassembly = "====NMI====", RegisterInfo = "" });
- }
- */
+
+ if (TraceCallback) { TraceCallback(1); }
+
IFF2 = IFF1;
IFF1 = false;
NMI_();
@@ -810,12 +811,9 @@ namespace MSXHawk
{
IFF1 = IFF2 = false;
EI_pending = 0;
- /*
- if (TraceCallback != null)
- {
- TraceCallback(new TraceInfo{ Disassembly = "====IRQ====", RegisterInfo = "" });
- }
- */
+
+ if (TraceCallback) { TraceCallback(2); }
+
switch (interruptMode)
{
case 0:
@@ -864,64 +862,6 @@ namespace MSXHawk
TotalExecutedCycles++;
}
- const string TraceHeader = "Z80A: PC, machine code, mnemonic, operands, registers (AF, BC, DE, HL, IX, IY, SP, Cy), flags (CNP3H5ZS)";
-
- string CPUDisassembly()
- {
- return "";
-
- /*
- uint32_t bytes_read = 0;
-
- int* bytes_read_ptr = &bytes_read;
-
- string disasm = disassemble ? Disassemble(RegPCget(), bytes_read_ptr) : "---";
- string byte_code = "";
-
- for (uint32_t i = 0; i < bytes_read; i++)
- {
- byte_code += $"{ReadMemory((uint32_t)(RegPC + i)):X2}";
- if (i < (bytes_read - 1))
- {
- byte_code += " ";
- }
- }
-
- return new TraceInfo
- {
- Disassembly = $"{RegPC:X4}: {byte_code.PadRight(12)} {disasm.PadRight(26)}",
-
- };
- */
- }
-
- string CPURegisterState()
- {
- return "";
-
- /*
- RegisterInfo = string.Join(" ",
- $"AF:{(Regs[A] << 8) + Regs[F]:X4}",
- $"BC:{(Regs[B] << 8) + Regs[C]:X4}",
- $"DE:{(Regs[D] << 8) + Regs[E]:X4}",
- $"HL:{(Regs[H] << 8) + Regs[L]:X4}",
- $"IX:{(Regs[Ixh] << 8) + Regs[Ixl]:X4}",
- $"IY:{(Regs[Iyh] << 8) + Regs[Iyl]:X4}",
- $"SP:{Regs[SPl] | (Regs[SPh] << 8):X4}",
- $"Cy:{TotalExecutedCycles}",
- string.Concat(
- FlagC ? "C" : "c",
- FlagN ? "N" : "n",
- FlagP ? "P" : "p",
- Flag3 ? "3" : "-",
- FlagH ? "H" : "h",
- Flag5 ? "5" : "-",
- FlagZ ? "Z" : "z",
- FlagS ? "S" : "s",
- FlagI ? "E" : "e"))
- */
- }
-
///
/// Optimization method to set BUSRQ
///
@@ -4509,25 +4449,302 @@ namespace MSXHawk
#pragma region Disassemble
- static string Result(string format, uint32_t addr)
+ 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";
+
+ void (*TraceCallback)(int);
+
+ string CPURegisterState()
+ {
+ string reg_state = " ";
+
+ char* val_char = 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(" ");
+
+ temp_reg = (Regs[B] << 8) + Regs[C];
+ sprintf_s(val_char, 5, "%04X", temp_reg);
+ reg_state.append(val_char, 4);
+ reg_state.append(" ");
+
+ temp_reg = (Regs[D] << 8) + Regs[E];
+ sprintf_s(val_char, 5, "%04X", temp_reg);
+ reg_state.append(val_char, 4);
+ reg_state.append(" ");
+
+ temp_reg = (Regs[H] << 8) + Regs[L];
+ sprintf_s(val_char, 5, "%04X", temp_reg);
+ reg_state.append(val_char, 4);
+ reg_state.append(" ");
+
+ temp_reg = (Regs[Ixh] << 8) + Regs[Ixl];
+ sprintf_s(val_char, 5, "%04X", temp_reg);
+ reg_state.append(val_char, 4);
+ reg_state.append(" ");
+
+ temp_reg = (Regs[Iyh] << 8) + Regs[Iyl];
+ sprintf_s(val_char, 5, "%04X", temp_reg);
+ reg_state.append(val_char, 4);
+ reg_state.append(" ");
+
+ 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);
+ reg_state.append(" ");
+
+ reg_state.append(FlagCget() ? "C" : "c");
+ reg_state.append(FlagNget() ? "N" : "n");
+ reg_state.append(FlagPget() ? "P" : "p");
+ reg_state.append(Flag3get() ? "3" : "-");
+ reg_state.append(FlagHget() ? "H" : "h");
+ reg_state.append(Flag5get() ? "5" : "-");
+ reg_state.append(FlagZget() ? "Z" : "z");
+ reg_state.append(FlagSget() ? "S" : "s");
+ reg_state.append(FlagI ? "E" : "e");
+
+ return reg_state;
+ }
+
+ string CPUDisassembly()
+ {
+ uint32_t bytes_read = 0;
+
+ uint32_t* bytes_read_ptr = &bytes_read;
+
+ string disasm = Disassemble(RegPCget(), bytes_read_ptr);
+ string byte_code = "";
+
+ for (uint32_t i = 0; i < bytes_read; i++)
+ {
+ bank_num = bank_offset = (RegPCget() + i) & 0xFFFF;
+ bank_offset &= low_mask;
+ bank_num = (bank_num >> bank_shift)& high_mask;
+
+ char* val_char_1 = replacer;
+ sprintf_s(val_char_1, 5, "%02X", MemoryMap[bank_num][bank_offset]);
+ string val1(val_char_1, 2);
+
+ byte_code.append(val1);
+ if (i < (bytes_read - 1))
+ {
+ byte_code.append(" ");
+ }
+ }
+
+ byte_code.append(disasm);
+
+ while (byte_code.length() < 32)
+ {
+ byte_code.append(" ");
+ }
+
+ return byte_code;
+ }
+
+ string Result(string format, uint32_t addr)
{
//d immediately succeeds the opcode
//n immediate succeeds the opcode and the displacement (if present)
//nn immediately succeeds the opcode and the displacement (if present)
- /*
- if (format.IndexOf("nn") != -1) format = format.Replace("nn", $"{read(addr++) + (read(addr++) << 8):X4}h"); // LSB is read first
- if (format.IndexOf("n") != -1) format = format.Replace("n", $"{read(addr++):X2}h");
- if (format.IndexOf("+d") != -1) format = format.Replace("+d", "d");
- if (format.IndexOf("d") != -1)
+ if (format.find("nn") != string::npos)
{
- var b = unchecked((sbyte)read(addr++));
- format = format.Replace("d", $"{(b < 0 ? '-' : '+')}{(b < 0 ? -b : b):X2}h");
+ size_t str_loc = format.find("nn");
+
+ bank_num = bank_offset = addr & 0xFFFF;
+ bank_offset &= low_mask;
+ bank_num = (bank_num >> bank_shift) & high_mask;
+ addr++;
+
+ char* val_char_1 = replacer;
+ sprintf_s(val_char_1, 5, "%02X", MemoryMap[bank_num][bank_offset]);
+ string val1(val_char_1, 2);
+
+ bank_num = bank_offset = addr & 0xFFFF;
+ bank_offset &= low_mask;
+ bank_num = (bank_num >> bank_shift)& high_mask;
+ addr++;
+
+ char* val_char_2 = replacer;
+ sprintf_s(val_char_2, 5, "%02X", MemoryMap[bank_num][bank_offset]);
+ string val2(val_char_2, 2);
+
+ format.erase(str_loc, 2);
+ format.insert(str_loc, val1);
+ format.insert(str_loc, val2);
}
- */
+
+ if (format.find("n") != string::npos)
+ {
+ size_t str_loc = format.find("n");
+
+ bank_num = bank_offset = addr & 0xFFFF;
+ bank_offset &= low_mask;
+ bank_num = (bank_num >> bank_shift)& high_mask;
+ addr++;
+
+ char* val_char_1 = replacer;
+ sprintf_s(val_char_1, 5, "%02X", MemoryMap[bank_num][bank_offset]);
+ string val1(val_char_1, 2);
+
+ format.erase(str_loc, 1);
+ format.insert(str_loc, val1);
+ }
+
+ if (format.find("+d") != string::npos)
+ {
+ size_t str_loc = format.find("+d");
+
+ bank_num = bank_offset = addr & 0xFFFF;
+ bank_offset &= low_mask;
+ bank_num = (bank_num >> bank_shift)& high_mask;
+ addr++;
+
+ char* val_char_1 = replacer;
+ sprintf_s(val_char_1, 5, "%u", MemoryMap[bank_num][bank_offset]);
+ string val1(val_char_1, 2);
+
+ format.erase(str_loc + 1, 1);
+ format.insert(str_loc + 1, val1);
+ }
+ if (format.find("d") != string::npos)
+ {
+ size_t str_loc = format.find("d");
+
+ bank_num = bank_offset = addr & 0xFFFF;
+ bank_offset &= low_mask;
+ bank_num = (bank_num >> bank_shift)& high_mask;
+ addr++;
+
+ int8_t temp = (int8_t)MemoryMap[bank_num][bank_offset];
+
+ char* val_char_1 = replacer;
+ sprintf_s(val_char_1, 5, "%d", temp);
+ string val1(val_char_1, 3);
+
+ format.erase(str_loc, 1);
+ format.insert(str_loc, val1);
+ }
+
return format;
}
+ string Disassemble(uint32_t addr, uint32_t* size)
+ {
+ uint32_t start_addr = addr;
+ uint32_t extra_inc = 0;
+
+ bank_num = bank_offset = addr & 0xFFFF;
+ bank_offset &= low_mask;
+ bank_num = (bank_num >> bank_shift) & high_mask;
+ addr++;
+
+ uint32_t A = MemoryMap[bank_num][bank_offset];
+ string format;
+ switch (A)
+ {
+ case 0xCB:
+ bank_num = bank_offset = addr & 0xFFFF;
+ bank_offset &= low_mask;
+ bank_num = (bank_num >> bank_shift) & high_mask;
+ addr++;
+
+ A = MemoryMap[bank_num][bank_offset];
+ format = mnemonicsCB[A];
+ break;
+ case 0xDD:
+ bank_num = bank_offset = addr & 0xFFFF;
+ bank_offset &= low_mask;
+ bank_num = (bank_num >> bank_shift) & high_mask;
+ addr++;
+
+ A = MemoryMap[bank_num][bank_offset];
+ switch (A)
+ {
+ case 0xCB:
+ bank_num = bank_offset = (addr + 1) & 0xFFFF;
+ bank_offset &= low_mask;
+ bank_num = (bank_num >> bank_shift) & high_mask;
+
+ format = mnemonicsDDCB[MemoryMap[bank_num][bank_offset]];
+ extra_inc = 1;
+ break;
+ case 0xED:
+ format = mnemonicsED[A];
+ break;
+ default:
+ format = mnemonicsDD[A];
+ break;
+ }
+ break;
+ case 0xED:
+ bank_num = bank_offset = addr & 0xFFFF;
+ bank_offset &= low_mask;
+ bank_num = (bank_num >> bank_shift) & high_mask;
+ addr++;
+
+ A = MemoryMap[bank_num][bank_offset];
+ format = mnemonicsED[A];
+ break;
+ case 0xFD:
+ bank_num = bank_offset = addr & 0xFFFF;
+ bank_offset &= low_mask;
+ bank_num = (bank_num >> bank_shift) & high_mask;
+ addr++;
+
+ A = MemoryMap[bank_num][bank_offset];
+ switch (A)
+ {
+ case 0xCB:
+ bank_num = bank_offset = (addr + 1) & 0xFFFF;
+ bank_offset &= low_mask;
+ bank_num = (bank_num >> bank_shift)& high_mask;
+
+ format = mnemonicsFDCB[MemoryMap[bank_num][bank_offset]];
+ extra_inc = 1;
+ break;
+ case 0xED:
+ format = mnemonicsED[A];
+ break;
+ default:
+ format = mnemonicsFD[A];
+ break;
+ }
+ break;
+ default: format = mnemonics[A]; break;
+ }
+
+ string temp = Result(format, addr);
+
+ addr += extra_inc;
+
+ size[0] = addr - start_addr;
+ // handle case of addr wrapping around at 16 bit boundary
+ if (addr < start_addr)
+ {
+ size[0] = (0x10000 + addr) - start_addr;
+ }
+
+ return temp;
+ }
+
+ /*
+ string Disassemble(MemoryDomain m, uuint32_t addr, out uint32_t length)
+ {
+ string ret = Disassemble((uint32_t)addr, a = > m.PeekByte(a), out length);
+ return ret;
+ }
+ */
+
const string mnemonics[256] =
{
"NOP", "LD BC, nn", "LD (BC), A", "INC BC", //0x04
@@ -4881,112 +5098,6 @@ namespace MSXHawk
"NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", //0xF0
"NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", "NOP", //0x100
};
-
- string Disassemble(uint32_t addr, int* size)
- {
- uint32_t start_addr = addr;
- uint32_t extra_inc = 0;
-
- bank_num = bank_offset = addr & 0xFFFF;
- bank_offset &= low_mask;
- bank_num = (bank_num >> bank_shift)& high_mask;
- addr++;
-
- uint32_t A = MemoryMap[bank_num][bank_offset];
- string format;
- switch (A)
- {
- case 0xCB:
- bank_num = bank_offset = addr & 0xFFFF;
- bank_offset &= low_mask;
- bank_num = (bank_num >> bank_shift)& high_mask;
- addr++;
-
- A = MemoryMap[bank_num][bank_offset];
- format = mnemonicsCB[A];
- break;
- case 0xDD:
- bank_num = bank_offset = addr & 0xFFFF;
- bank_offset &= low_mask;
- bank_num = (bank_num >> bank_shift)& high_mask;
- addr++;
-
- A = MemoryMap[bank_num][bank_offset];
- switch (A)
- {
- case 0xCB:
- bank_num = bank_offset = (addr + 1) & 0xFFFF;
- bank_offset &= low_mask;
- bank_num = (bank_num >> bank_shift)& high_mask;
-
- format = mnemonicsDDCB[MemoryMap[bank_num][bank_offset]];
- extra_inc = 1;
- break;
- case 0xED:
- format = mnemonicsED[A];
- break;
- default:
- format = mnemonicsDD[A];
- break;
- }
- break;
- case 0xED:
- bank_num = bank_offset = addr & 0xFFFF;
- bank_offset &= low_mask;
- bank_num = (bank_num >> bank_shift)& high_mask;
- addr++;
-
- A = MemoryMap[bank_num][bank_offset];
- format = mnemonicsED[A];
- break;
- case 0xFD:
- bank_num = bank_offset = addr & 0xFFFF;
- bank_offset &= low_mask;
- bank_num = (bank_num >> bank_shift)& high_mask;
- addr++;
-
- A = MemoryMap[bank_num][bank_offset];
- switch (A)
- {
- case 0xCB:
- bank_num = bank_offset = (addr + 1) & 0xFFFF;
- bank_offset &= low_mask;
- bank_num = (bank_num >> bank_shift)& high_mask;
-
- format = mnemonicsFDCB[MemoryMap[bank_num][bank_offset]];
- extra_inc = 1;
- break;
- case 0xED:
- format = mnemonicsED[A];
- break;
- default:
- format = mnemonicsFD[A];
- break;
- }
- break;
- default: format = mnemonics[A]; break;
- }
-
- string temp = Result(format, addr);
-
- addr += extra_inc;
-
- size[0] = addr - start_addr;
- // handle case of addr wrapping around at 16 bit boundary
- if (addr < start_addr)
- {
- size[0] = (0x10000 + addr) - start_addr;
- }
-
- return temp;
- }
- /*
- string Disassemble(MemoryDomain m, uuint32_t addr, out uint32_t length)
- {
- string ret = Disassemble((uint32_t)addr, a = > m.PeekByte(a), out length);
- return ret;
- }
- */
#pragma endregion
};
}