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