summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOxore <oxore@protonmail.com>2022-09-25 15:22:07 +0300
committerOxore <oxore@protonmail.com>2022-09-25 15:22:07 +0300
commitbf5c361ed5ff57c077bb3b45d794325e8bdadc9a (patch)
tree21379b36857d19763eae02aaf31a6fc4b1681462
parent2e363155df0380bed5210e41d395015320a9bb74 (diff)
Use switch-case for handling GDB commands
-rw-r--r--emulator.cpp165
1 files changed, 98 insertions, 67 deletions
diff --git a/emulator.cpp b/emulator.cpp
index 5dd266a..7a1dffa 100644
--- a/emulator.cpp
+++ b/emulator.cpp
@@ -109,83 +109,114 @@ static std::string CreateResponse(
{
using namespace GDBRemote;
// TODO use switch-case
- if (0) {
- } else if (packet.type == PacketType::kQueryHaltReason) {
+ switch (packet.type) {
+ case PacketType::kNone:
+ break;
+ case PacketType::kQuerySupported:
+ break;
+ case PacketType::kQueryHaltReason:
return "S05"; // TODO real reason
- } else if (packet.type == PacketType::kStep) {
- m68k_execute(1);
- return "S05"; // TODO real reason
- } else if (packet.type == PacketType::kContinue) {
- m68k_debug.SetRunning(true);
+ case PacketType::kQueryC:
+ break;
+ case PacketType::kQueryFThreadInfo:
+ break;
+ case PacketType::kQuerySThreadInfo:
+ break;
+ case PacketType::kQueryRTOSThreadInfo:
+ break;
+ case PacketType::kQueryAttached:
+ return "1";
+ case PacketType::kQueryTraceStatus:
+ break;
+ case PacketType::kQueryRcmd:
+ {
+ const auto * const packet_data =
+ static_cast<const PacketDataRcmd*>(packet.data.get());
+ if (IsReset(packet_data->data)) {
+ m68k_pulse_reset();
+ // I don't want to skip reset cycles here, because GDB does not
+ // re-read registers every time, and if we skip reset cycles
+ // here, the consequent "stepi" in gdb will end up on second
+ // instruction of reset handler. If we don't skip reset cycles,
+ // the first "stepi" after "monitor reset" will land us on the
+ // first instruction in reset handler - I'd prefer this exact
+ // behavior for now.
+ return "OK";
+ }
+ }
+ break;
+ case PacketType::kSetThreadForCont:
return "OK";
- } else if (packet.type == PacketType::kInterrupt) {
+ case PacketType::kSetThreadForOps:
+ break;
+ case PacketType::kVMustReplyEmpty:
+ break;
+ case PacketType::kEnableExtendedMode:
+ break;
+ case PacketType::kInterrupt:
m68k_debug.SetRunning(false);
return "S05"; // TODO real reason
- } else if (packet.type == PacketType::kSetThreadForCont) {
+ case PacketType::kContinue:
+ m68k_debug.SetRunning(true);
return "OK";
- } else if (packet.type == PacketType::kQueryAttached) {
- return "1";
- } else if (packet.type == PacketType::kQueryRcmd) {
- const auto * const packet_data =
- static_cast<const PacketDataRcmd*>(packet.data.get());
- if (IsReset(packet_data->data)) {
- m68k_pulse_reset();
- // I don't want to skip reset cycles here, because GDB does not
- // re-read registers every time, and if we skip reset cycles here,
- // the consequent "stepi" in gdb will end up on second instruction
- // of reset handler. If we don't skip reset cycles, the first
- // "stepi" after "monitor reset" will land us on the first
- // instruction in reset handler - I'd prefer this exact behavior for
- // now.
- return "OK";
+ case PacketType::kContinueAskSupported:
+ return "vCont:c:s";
+ case PacketType::kReadGeneralRegisters:
+ {
+ const M68KCPUState state = m68k_debug.GetCPUState();
+ std::string result{};
+ for (size_t i = 0; i < state.registers_count ;i++)
+ {
+ constexpr size_t value_size = std::string_view("12345678").length();
+ char value[value_size + 1]{};
+ const int ret = snprintf(value, value_size + 1, "%08x", state.registers[i]);
+ assert(ret == value_size);
+ result += std::string(value, value_size);
+ }
+ return result;
}
- } 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 =
- 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');
- for (uint32_t i = 0; i < length; i++) {
- const uint8_t byte = m68k_debug.Read8(i + offset);
- Utils::ConvertByteToHex(byte, &ret_data[i*2]);
+ case PacketType::kReadMemory:
+ {
+ const auto * const data =
+ 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');
+ for (uint32_t i = 0; i < length; i++) {
+ const uint8_t byte = m68k_debug.Read8(i + offset);
+ Utils::ConvertByteToHex(byte, &ret_data[i*2]);
+ }
+ return ret_data;
}
- return ret_data;
- } else if (packet.type == PacketType::kWriteMemory) {
- const auto * const packet_data =
- 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;
- for (uint32_t i = 0; i < length; i++) {
- m68k_debug.Write8(i + offset, write_data[i]);
+ case PacketType::kWriteMemory:
+ {
+ const auto * const packet_data =
+ 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;
+ for (uint32_t i = 0; i < length; i++) {
+ m68k_debug.Write8(i + offset, write_data[i]);
+ }
+ return "OK";
}
- return "OK";
- } else if (packet.type == PacketType::kReadGeneralRegisters) {
- const M68KCPUState state = m68k_debug.GetCPUState();
- std::string result{};
- for (size_t i = 0; i < state.registers_count ;i++)
+ case PacketType::kStep:
+ m68k_execute(1);
+ return "S05"; // TODO real reason
+ case PacketType::kSetBreakpoint:
{
- constexpr size_t value_size = 8;
- char value[value_size + 1]{};
- const int ret = snprintf(value, value_size + 1, "%08x", state.registers[i]);
- assert(ret == value_size);
- result += std::string(value, value_size);
+ 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";
+ }
+ case 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";
}
- return result;
- } else if (packet.type == PacketType::kContinueAskSupported) {
- return "vCont:c:s";
}
return "";
}