summaryrefslogtreecommitdiff
path: root/bus.cpp
diff options
context:
space:
mode:
authorOxore <oxore@protonmail.com>2022-09-25 21:13:36 +0300
committerOxore <oxore@protonmail.com>2022-09-25 21:13:36 +0300
commit0b0ae3586c50c110dad12cc04c029106e5f2eeb5 (patch)
treed02ee03752e608f4beeb178de5b8849af622068d /bus.cpp
parent0dc9d15cdcc9cadffaeec9dfbc2b047fe064fee4 (diff)
Break execution on bus fault, support GDB NoAck mode
Diffstat (limited to 'bus.cpp')
-rw-r--r--bus.cpp119
1 files changed, 98 insertions, 21 deletions
diff --git a/bus.cpp b/bus.cpp
index f611eba..df44164 100644
--- a/bus.cpp
+++ b/bus.cpp
@@ -26,10 +26,6 @@ std::vector<Breakpoint> code_bkpts{}, read_bkpts{}, write_bkpts{}, access_bkpts{
static void exit_error(const char* fmt, ...)
{
- va_list args;
- va_start(args, fmt);
- vfprintf(stderr, fmt, args);
- va_end(args);
static bool in_error = false;
if (in_error)
{
@@ -37,14 +33,35 @@ static void exit_error(const char* fmt, ...)
return;
}
in_error = true;
+ va_list args;
+ va_start(args, fmt);
+ vfprintf(stderr, fmt, args);
+ va_end(args);
fprintf(stderr, "\n");
unsigned int pc = m68k_get_reg(NULL, M68K_REG_PPC);
- char buff[100];
+ char buff[100]{};
m68k_disassemble(buff, pc, M68K_CPU_TYPE_68000);
fprintf(stderr, "%08x: %s\n", pc, buff);
exit(EXIT_FAILURE);
}
+static void report_error(const char* fmt, ...)
+{
+ static bool in_error = false;
+ if (in_error)
+ return;
+ in_error = true;
+ va_list args;
+ va_start(args, fmt);
+ vfprintf(stderr, fmt, args);
+ va_end(args);
+ fprintf(stderr, "\n");
+ unsigned int pc = m68k_get_reg(NULL, M68K_REG_PPC);
+ char buff[100]{};
+ m68k_disassemble(buff, pc, M68K_CPU_TYPE_68000);
+ fprintf(stderr, "%08x: %s\n", pc, buff);
+}
+
static inline bool is_in_range(uint32_t value, uint32_t begin, uint32_t length)
{
return value >= begin && value <= begin + length;
@@ -167,18 +184,68 @@ static inline bool memory_write(
return false;
}
+static inline bool ranges_overlap(
+ const uint32_t a_start,
+ const uint32_t a_len,
+ const uint32_t b_start,
+ const uint32_t b_len)
+{
+ return (a_start < b_start + b_len && b_start < a_start + a_len);
+}
+
+extern void m68k_breakpoint_callback(void);
+
#define MASK_24(X) ((X) & (0xFF << 24))
-extern void m68k_read_callback(const uint32_t address, const uint32_t size);
-extern void m68k_write_callback(const uint32_t address, const uint32_t size);
+static void m68k_read_callback(const uint32_t address, const uint32_t size)
+{
+ const auto access_it = std::find_if(
+ access_bkpts.begin(),
+ access_bkpts.end(),
+ [&](const Breakpoint& b) { return ranges_overlap(address, size, b.offset, b.length); });
+ if (access_it != access_bkpts.end()) {
+ m68k_breakpoint_callback();
+ printf("Access watchpoint @ 0x%08x\n", address);
+ }
+ const auto it = std::find_if(
+ read_bkpts.begin(),
+ read_bkpts.end(),
+ [&](const Breakpoint& b) { return ranges_overlap(address, size, b.offset, b.length); });
+ if (it != read_bkpts.end()) {
+ m68k_breakpoint_callback();
+ printf("Read watchpoint @ 0x%08x\n", address);
+ }
+}
+
+static void m68k_write_callback(const uint32_t address, const uint32_t size)
+{
+ const auto access_it = std::find_if(
+ access_bkpts.begin(),
+ access_bkpts.end(),
+ [&](const Breakpoint& b) { return ranges_overlap(address, size, b.offset, b.length); });
+ if (access_it != access_bkpts.end()) {
+ m68k_breakpoint_callback();
+ printf("Access watchpoint @ 0x%08x\n", address);
+ }
+ const auto it = std::find_if(
+ write_bkpts.begin(),
+ write_bkpts.end(),
+ [&](const Breakpoint& b) { return ranges_overlap(address, size, b.offset, b.length); });
+ if (it != write_bkpts.end()) {
+ m68k_breakpoint_callback();
+ printf("Write watchpoint @ 0x%08x\n", address);
+ }
+}
unsigned int m68k_read_memory_8(unsigned int address)
{
assert(MASK_24(address) == 0); // Just curious
m68k_read_callback(address, 4);
const struct read_result ret = memory_read(BITNESS_8, address);
- if (!ret.successful)
- exit_error("Read error u8 @%08x", address);
+ if (!ret.successful) {
+ m68k_breakpoint_callback();
+ report_error("Read error u8 @%08x", address);
+ }
return ret.result;
}
@@ -187,8 +254,10 @@ unsigned int m68k_read_memory_16(unsigned int address)
m68k_read_callback(address, 2);
assert(MASK_24(address) == 0); // Just curious
const struct read_result ret = memory_read(BITNESS_16, address);
- if (!ret.successful)
- exit_error("Read error u16 @%08x", address);
+ if (!ret.successful) {
+ m68k_breakpoint_callback();
+ report_error("Read error u16 @%08x", address);
+ }
return ret.result;
}
@@ -197,8 +266,10 @@ unsigned int m68k_read_memory_32(unsigned int address)
m68k_read_callback(address, 1);
assert(MASK_24(address) == 0); // Just curious
const struct read_result ret = memory_read(BITNESS_32, address);
- if (!ret.successful)
- exit_error("Read error u32 @%08x", address);
+ if (!ret.successful) {
+ m68k_breakpoint_callback();
+ report_error("Read error u32 @%08x", address);
+ }
return ret.result;
}
@@ -206,7 +277,7 @@ unsigned int m68k_read_disassembler_16(unsigned int address)
{
assert(MASK_24(address) == 0); // Just curious
const struct read_result ret = memory_read(BITNESS_16, address);
- if (!ret.successful)
+ if (0 && !ret.successful)
exit_error("Disasm read error u16 @0x%08x", address);
return ret.result;
}
@@ -215,7 +286,7 @@ unsigned int m68k_read_disassembler_32(unsigned int address)
{
assert(MASK_24(address) == 0); // Just curious
const struct read_result ret = memory_read(BITNESS_32, address);
- if (!ret.successful)
+ if (0 && !ret.successful)
exit_error("Disasm read error u32 @0x%08x", address);
return ret.result;
}
@@ -225,8 +296,10 @@ void m68k_write_memory_8(unsigned int address, unsigned int value)
assert(MASK_24(address) == 0); // Just curious
m68k_write_callback(address, 1);
const bool successful = memory_write(BITNESS_8, address, value);
- if (!successful)
- exit_error("Attempted to write 0x%02x (u8) to address %08x", value&0xff, address);
+ if (!successful) {
+ m68k_breakpoint_callback();
+ report_error("Attempted to write 0x%02x (u8) to address %08x", value&0xff, address);
+ }
}
void m68k_write_memory_16(unsigned int address, unsigned int value)
@@ -234,8 +307,10 @@ void m68k_write_memory_16(unsigned int address, unsigned int value)
assert(MASK_24(address) == 0); // Just curious
m68k_write_callback(address, 2);
const bool successful = memory_write(BITNESS_16, address, value);
- if (!successful)
- exit_error("Attempted to write 0x%04x (u16) to address %08x", value&0xffff, address);
+ if (!successful) {
+ m68k_breakpoint_callback();
+ report_error("Attempted to write 0x%04x (u16) to address %08x", value&0xff, address);
+ }
}
void m68k_write_memory_32(unsigned int address, unsigned int value)
@@ -243,6 +318,8 @@ void m68k_write_memory_32(unsigned int address, unsigned int value)
assert(MASK_24(address) == 0); // Just curious
m68k_write_callback(address, 4);
const bool successful = memory_write(BITNESS_16, address, value);
- if (!successful)
- exit_error("Attempted to write 0x%08x (u32) to address %08x", value, address);
+ if (!successful) {
+ m68k_breakpoint_callback();
+ report_error("Attempted to write 0x%08x (u32) to address %08x", value&0xff, address);
+ }
}