diff options
Diffstat (limited to 'emulator.cpp')
-rw-r--r-- | emulator.cpp | 57 |
1 files changed, 44 insertions, 13 deletions
diff --git a/emulator.cpp b/emulator.cpp index 1c8c6f9..5228231 100644 --- a/emulator.cpp +++ b/emulator.cpp @@ -31,6 +31,7 @@ static constexpr struct timespec kOneMillisecond{0, 1000000}; char msg_buf[MESSAGE_BUFFER_SIZE]; +M68KDebuggingControl g_m68k_debug{}; static int set_socket_reuseaddr(int socket_fd) { @@ -116,9 +117,19 @@ static std::string CreateResponse( return "1"; } else if (packet.type == PacketType::kInterrupt) { return "OK"; + } else if (packet.type == PacketType::kSetBreakpoint) { + const auto * const bkpt_data = + static_cast<const PacketDataBreakpoint*>(packet.data.get()); + m68k_debug.SetBreakpoint(bkpt_data->type, bkpt_data->offset, bkpt_data->length); + return "OK"; + } else if (packet.type == PacketType::kDeleteBreakpoint) { + const auto * const bkpt_data = + static_cast<const PacketDataBreakpoint*>(packet.data.get()); + m68k_debug.RemoveBreakpoint(bkpt_data->type, bkpt_data->offset, bkpt_data->length); + return "OK"; } else if (packet.type == PacketType::kReadMemory) { const auto * const data = - reinterpret_cast<const PacketDataReadMemory*>(packet.data.get()); + static_cast<const PacketDataReadMemory*>(packet.data.get()); const uint32_t offset = data->offset; const uint32_t length = data->length; auto ret_data = std::string(length * 2, '\0'); @@ -129,7 +140,7 @@ static std::string CreateResponse( return ret_data; } else if (packet.type == PacketType::kWriteMemory) { const auto * const packet_data = - reinterpret_cast<const PacketDataWriteMemory*>(packet.data.get()); + static_cast<const PacketDataWriteMemory*>(packet.data.get()); const uint32_t offset = packet_data->offset; const uint32_t length = packet_data->length; const auto write_data = packet_data->data; @@ -194,17 +205,30 @@ static void make_hex(char* buff, unsigned int pc, unsigned int length) } } +// TODO m68k_set_illg_instr_callback for true software breakpoint "4e4f" + void m68k_instr_callback(int pc) { - if (!DEBUG_TRACE_INSTRUCTIONS) - return; - char buff[100]; - unsigned int instr_size = - m68k_disassemble(buff, pc, M68K_CPU_TYPE_68000); - char buff2[100]; - make_hex(buff2, pc, instr_size); - printf(" %08X: %-20s: %s\n", pc, buff2, buff); - fflush(stdout); + const auto it = std::find_if( + code_bkpts.begin(), + code_bkpts.end(), + [&](const Breakpoint& b) { return b.offset == static_cast<uint32_t>(pc); }); + if (it != code_bkpts.end()) { + g_m68k_debug.SetRunning(false); + g_m68k_debug.RaiseBreakpoint(); + m68k_end_timeslice(); + printf("Breakpoint!\n"); + // TODO notify GDB somehow that breakpoint has been hit + } + if (DEBUG_TRACE_INSTRUCTIONS) { + char buff[100]; + unsigned int instr_size = + m68k_disassemble(buff, pc, M68K_CPU_TYPE_68000); + char buff2[100]; + make_hex(buff2, pc, instr_size); + printf(" %08X: %-20s: %s\n", pc, buff2, buff); + fflush(stdout); + } } void ParseAndReact( @@ -291,6 +315,14 @@ int emulator(M68KDebuggingControl& m68k_debug) if (m68k_debug.IsRunning()) { m68k_execute(1000); } + if (m68k_debug.HasBreakpoint()) { + m68k_debug.ResetPendingBreakpoint(); + const auto response = + exchange_ctx.WrapDataToSend("S05"); + printf("-> \"%s\"\n", response.c_str()); + if (send(conn_fd, &response[0], response.length(), 0) == -1) + perror("Send failed (response)"); + } // TODO turn off O_NONBLOCK and poll instead of sleep, only use // nonlock when freerunning clock_nanosleep(CLOCK_MONOTONIC, 0, &kOneMillisecond, nullptr); @@ -323,8 +355,7 @@ int main(int argc, char* argv[]) m68k_set_cpu_type(M68K_CPU_TYPE_68000); m68k_pulse_reset(); - M68KDebuggingControl m68k_debug{}; - emulator(m68k_debug); + emulator(g_m68k_debug); while (0) { // Values to execute determine the interleave rate. |