summaryrefslogtreecommitdiff
path: root/bus.cpp
diff options
context:
space:
mode:
authorOxore <oxore@protonmail.com>2022-09-26 01:32:22 +0300
committerOxore <oxore@protonmail.com>2022-09-26 01:35:42 +0300
commitab0fddd81a4c2cf6075f6a59014a1f12eab19c70 (patch)
tree17da7138346289a84b2821eac22b8c22104be9a0 /bus.cpp
parent3acfbd6f634a1d48045fb6b2a2c1031efebe80e4 (diff)
Fix watchpoints, add PC backtrace
Diffstat (limited to 'bus.cpp')
-rw-r--r--bus.cpp184
1 files changed, 90 insertions, 94 deletions
diff --git a/bus.cpp b/bus.cpp
index df44164..085275a 100644
--- a/bus.cpp
+++ b/bus.cpp
@@ -16,12 +16,13 @@ namespace Adr {
static constexpr uint32_t kZ80BusReq = 0x00a11100;
}
+extern void m68k_breakpoint_callback(void);
+
unsigned char g_rom[ROM_SIZE] = {};
unsigned char g_ram[RAM_SIZE] = {};
unsigned char g_sound_ram[SOUND_RAM_SIZE] = {};
unsigned char g_io1[IO1_SIZE] = {};
unsigned char g_io2[IO2_SIZE] = {};
-
std::vector<Breakpoint> code_bkpts{}, read_bkpts{}, write_bkpts{}, access_bkpts{};
static void exit_error(const char* fmt, ...)
@@ -60,6 +61,7 @@ static void report_error(const char* fmt, ...)
char buff[100]{};
m68k_disassemble(buff, pc, M68K_CPU_TYPE_68000);
fprintf(stderr, "%08x: %s\n", pc, buff);
+ in_error = false;
}
static inline bool is_in_range(uint32_t value, uint32_t begin, uint32_t length)
@@ -68,9 +70,9 @@ static inline bool is_in_range(uint32_t value, uint32_t begin, uint32_t length)
}
enum bitness {
- BITNESS_8,
- BITNESS_16,
- BITNESS_32,
+ BITNESS_8 = 1,
+ BITNESS_16 = 2,
+ BITNESS_32 = 4,
};
struct read_result {
@@ -79,9 +81,9 @@ struct read_result {
};
static inline unsigned int memory_read_concrete(
- enum bitness bitness,
+ const enum bitness bitness,
unsigned char const * base,
- unsigned int address)
+ const uint32_t address)
{
switch (bitness) {
case BITNESS_8:
@@ -97,10 +99,40 @@ static inline unsigned int memory_read_concrete(
UNREACHABLE;
}
+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);
+}
+
+static inline 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()) {
+ printf("Access watchpoint @ 0x%08x\n", address);
+ m68k_breakpoint_callback();
+ }
+ 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()) {
+ printf("Read watchpoint @ 0x%08x\n", address);
+ m68k_breakpoint_callback();
+ }
+}
+
static inline struct read_result memory_read(
- enum bitness bitness,
- unsigned int address)
+ const enum bitness bitness,
+ const uint32_t address)
{
+ m68k_read_callback(address, bitness);
if (is_in_range(address, ROM_START, ROM_SIZE)) {
return read_result{
memory_read_concrete(bitness, g_rom, address - ROM_START),
@@ -132,9 +164,9 @@ static inline struct read_result memory_read(
static inline void memory_write_concrete(
enum bitness bitness,
- unsigned char * base,
- unsigned int address,
- unsigned int value)
+ unsigned char * const base,
+ const uint32_t address,
+ const unsigned int value)
{
switch (bitness) {
case BITNESS_8:
@@ -153,11 +185,32 @@ static inline void memory_write_concrete(
}
}
+static inline 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()) {
+ printf("Access watchpoint @ 0x%08x\n", address);
+ m68k_breakpoint_callback();
+ }
+ 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()) {
+ printf("Write watchpoint @ 0x%08x\n", address);
+ m68k_breakpoint_callback();
+ }
+}
+
static inline bool memory_write(
- enum bitness bitness,
- unsigned int address,
- unsigned int value)
+ const enum bitness bitness,
+ const uint32_t address,
+ const unsigned int value)
{
+ m68k_write_callback(address, bitness);
if (is_in_range(address, ROM_START, ROM_SIZE)) {
memory_write_concrete(bitness, g_rom, address - ROM_START, value);
return true;
@@ -184,142 +237,85 @@ 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))
+#define MASK_24(X) ((X) & 0x00ffffff)
-static void m68k_read_callback(const uint32_t address, const uint32_t size)
+unsigned int m68k_read_memory_8(const unsigned int address_a)
{
- 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 uint32_t address = MASK_24(address_a);
const struct read_result ret = memory_read(BITNESS_8, address);
if (!ret.successful) {
- m68k_breakpoint_callback();
report_error("Read error u8 @%08x", address);
+ m68k_breakpoint_callback();
}
return ret.result;
}
-unsigned int m68k_read_memory_16(unsigned int address)
+unsigned int m68k_read_memory_16(const unsigned int address_a)
{
- m68k_read_callback(address, 2);
- assert(MASK_24(address) == 0); // Just curious
+ const uint32_t address = MASK_24(address_a);
const struct read_result ret = memory_read(BITNESS_16, address);
if (!ret.successful) {
- m68k_breakpoint_callback();
report_error("Read error u16 @%08x", address);
+ m68k_breakpoint_callback();
}
return ret.result;
}
-unsigned int m68k_read_memory_32(unsigned int address)
+unsigned int m68k_read_memory_32(const unsigned int address_a)
{
- m68k_read_callback(address, 1);
- assert(MASK_24(address) == 0); // Just curious
+ const uint32_t address = MASK_24(address_a);
const struct read_result ret = memory_read(BITNESS_32, address);
if (!ret.successful) {
- m68k_breakpoint_callback();
report_error("Read error u32 @%08x", address);
+ m68k_breakpoint_callback();
}
return ret.result;
}
-unsigned int m68k_read_disassembler_16(unsigned int address)
+unsigned int m68k_read_disassembler_16(const unsigned int address_a)
{
- assert(MASK_24(address) == 0); // Just curious
+ const uint32_t address = MASK_24(address_a);
const struct read_result ret = memory_read(BITNESS_16, address);
if (0 && !ret.successful)
exit_error("Disasm read error u16 @0x%08x", address);
return ret.result;
}
-unsigned int m68k_read_disassembler_32(unsigned int address)
+unsigned int m68k_read_disassembler_32(const unsigned int address_a)
{
- assert(MASK_24(address) == 0); // Just curious
+ const uint32_t address = MASK_24(address_a);
const struct read_result ret = memory_read(BITNESS_32, address);
if (0 && !ret.successful)
exit_error("Disasm read error u32 @0x%08x", address);
return ret.result;
}
-void m68k_write_memory_8(unsigned int address, unsigned int value)
+void m68k_write_memory_8(const unsigned int address_a, const unsigned int value)
{
- assert(MASK_24(address) == 0); // Just curious
- m68k_write_callback(address, 1);
+ const uint32_t address = MASK_24(address_a);
const bool successful = memory_write(BITNESS_8, address, value);
if (!successful) {
- m68k_breakpoint_callback();
report_error("Attempted to write 0x%02x (u8) to address %08x", value&0xff, address);
+ m68k_breakpoint_callback();
}
}
-void m68k_write_memory_16(unsigned int address, unsigned int value)
+void m68k_write_memory_16(const unsigned int address_a, const unsigned int value)
{
- assert(MASK_24(address) == 0); // Just curious
- m68k_write_callback(address, 2);
+ const uint32_t address = MASK_24(address_a);
const bool successful = memory_write(BITNESS_16, address, value);
if (!successful) {
- m68k_breakpoint_callback();
report_error("Attempted to write 0x%04x (u16) to address %08x", value&0xff, address);
+ m68k_breakpoint_callback();
}
}
-void m68k_write_memory_32(unsigned int address, unsigned int value)
+void m68k_write_memory_32(const unsigned int address_a, const unsigned int value)
{
- assert(MASK_24(address) == 0); // Just curious
- m68k_write_callback(address, 4);
+ const uint32_t address = MASK_24(address_a);
const bool successful = memory_write(BITNESS_16, address, value);
if (!successful) {
- m68k_breakpoint_callback();
report_error("Attempted to write 0x%08x (u32) to address %08x", value&0xff, address);
+ m68k_breakpoint_callback();
}
}