summaryrefslogtreecommitdiff
path: root/emulator.cpp
diff options
context:
space:
mode:
authorOxore <oxore@protonmail.com>2022-09-03 17:33:07 +0300
committerOxore <oxore@protonmail.com>2022-09-03 17:33:07 +0300
commitd2b615061e008c4d13a6ce0f11efd8ec337f41c6 (patch)
tree0aab1cc72db576761524267ea3594a21db14b829 /emulator.cpp
parent9037b017d6519fed435eea20c3553d40d871d379 (diff)
Impl breakpoints (pretty much draft)
Breakpoints work somehow, but overstep 1 instruction. Needs to be fixed.
Diffstat (limited to 'emulator.cpp')
-rw-r--r--emulator.cpp57
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.