summaryrefslogtreecommitdiff
path: root/bus.cpp
diff options
context:
space:
mode:
authorOxore <oxore@protonmail.com>2022-08-27 11:53:25 +0300
committerOxore <oxore@protonmail.com>2022-08-27 11:53:25 +0300
commit903b8dbcaad887f6e14cc8cffc22ddda08dc9f85 (patch)
tree01254a3d08791a71dea3e7f987b859ae58921d35 /bus.cpp
parentc1b9fead37e32be1b2f97d5be2d8254fdc16d307 (diff)
Move to C++ completely
Diffstat (limited to 'bus.cpp')
-rw-r--r--bus.cpp208
1 files changed, 208 insertions, 0 deletions
diff --git a/bus.cpp b/bus.cpp
new file mode 100644
index 0000000..caff07c
--- /dev/null
+++ b/bus.cpp
@@ -0,0 +1,208 @@
+/* SPDX-License-Identifier: Unlicense
+ */
+
+#include "bus.hpp"
+#include "musashi-m68k/m68k.h"
+
+#include <cassert>
+#include <cstdarg>
+#include <cstdbool>
+#include <cstdio>
+#include <cstdint>
+#include <cstdlib>
+
+unsigned char g_rom[ROM_SIZE] = {};
+unsigned char g_ram[RAM_SIZE] = {};
+unsigned char g_io1[IO1_SIZE] = {};
+unsigned char g_io2[IO2_SIZE] = {};
+
+static void exit_error(const char* fmt, ...)
+{
+ 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);
+ exit(EXIT_FAILURE);
+}
+
+static inline bool is_in_range(uint32_t value, uint32_t begin, uint32_t length)
+{
+ return value >= begin && value <= begin + length;
+}
+
+enum bitness {
+ BITNESS_8,
+ BITNESS_16,
+ BITNESS_32,
+};
+
+struct read_result {
+ unsigned int result;
+ bool successful;
+};
+
+static inline unsigned int memory_read_concrete(
+ enum bitness bitness,
+ unsigned char const * base,
+ unsigned int address)
+{
+ switch (bitness) {
+ case BITNESS_8:
+ return base[address];
+ case BITNESS_16:
+ return (base[address] << 8) | base[address + 1];
+ case BITNESS_32:
+ return (base[address] << 24) |
+ (base[address + 1] << 16) |
+ (base[address + 2] << 8) |
+ base[address + 3];
+ }
+ __builtin_unreachable();
+}
+
+static inline struct read_result memory_read(
+ enum bitness bitness,
+ unsigned int address)
+{
+ if (is_in_range(address, ROM_START, ROM_SIZE))
+ return (struct read_result){
+ memory_read_concrete(bitness, g_rom, address - ROM_START),
+ true,
+ };
+ else if (is_in_range(address, RAM_START, RAM_SIZE))
+ return (struct read_result){
+ memory_read_concrete(bitness, g_ram, address - RAM_START),
+ true,
+ };
+ else if (is_in_range(address, IO1_START, IO1_SIZE))
+ return (struct read_result){
+ memory_read_concrete(bitness, g_io1, address - IO1_START),
+ true,
+ };
+ else if (is_in_range(address, IO2_START, IO2_SIZE))
+ return (struct read_result){
+ memory_read_concrete(bitness, g_io2, address - IO2_START),
+ true,
+ };
+ return (struct read_result){0, false};
+}
+
+static inline void memory_write_concrete(
+ enum bitness bitness,
+ unsigned char * base,
+ unsigned int address,
+ unsigned int value)
+{
+ switch (bitness) {
+ case BITNESS_8:
+ base[address] = value & 0xff;
+ break;
+ case BITNESS_16:
+ base[address + 0] = (value >> 8) & 0xff;
+ base[address + 1] = value & 0xff;
+ break;
+ case BITNESS_32:
+ base[address + 0] = (value >> 24) & 0xff;
+ base[address + 1] = (value >> 16) & 0xff;
+ base[address + 2] = (value >> 8) & 0xff;
+ base[address + 3] = value & 0xff;
+ break;
+ }
+}
+
+static inline bool memory_write(
+ enum bitness bitness,
+ unsigned int address,
+ unsigned int value)
+{
+ if (is_in_range(address, ROM_START, ROM_SIZE)) {
+ memory_write_concrete(bitness, g_rom, address - ROM_START, value);
+ return true;
+ } else if (is_in_range(address, RAM_START, RAM_SIZE)) {
+ memory_write_concrete(bitness, g_ram, address - RAM_START, value);
+ return true;
+ } else if (is_in_range(address, IO1_START, IO1_SIZE)) {
+ memory_write_concrete(bitness, g_io1, address - IO1_START, value);
+ return true;
+ } else if (is_in_range(address, IO2_START, IO2_SIZE)) {
+ memory_write_concrete(bitness, g_io2, address - IO2_START, value);
+ return true;
+ }
+ return false;
+}
+
+#define MASK_24(X) ((X) & (0xFF << 24))
+
+unsigned int m68k_read_memory_8(unsigned int address)
+{
+ assert(MASK_24(address) == 0); // Just curious
+ const struct read_result ret = memory_read(BITNESS_8, address);
+ if (!ret.successful)
+ exit_error("Read error u8 @%08x", address);
+ return ret.result;
+}
+
+unsigned int m68k_read_memory_16(unsigned int address)
+{
+ 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);
+ return ret.result;
+}
+
+unsigned int m68k_read_memory_32(unsigned int address)
+{
+ 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);
+ return ret.result;
+}
+
+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)
+ exit_error("Disasm read error u16 @0x%08x", address);
+ return ret.result;
+}
+
+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)
+ exit_error("Disasm read error u32 @0x%08x", address);
+ return ret.result;
+}
+
+void m68k_write_memory_8(unsigned int address, unsigned int value)
+{
+ assert(MASK_24(address) == 0); // Just curious
+ const bool successful = memory_write(BITNESS_8, address, value);
+ if (!successful)
+ exit_error("Attempted to write %02x (u8) to address %08x", value&0xff, address);
+}
+
+void m68k_write_memory_16(unsigned int address, unsigned int value)
+{
+ assert(MASK_24(address) == 0); // Just curious
+ const bool successful = memory_write(BITNESS_16, address, value);
+ if (!successful)
+ exit_error("Attempted to write %04x (u16) to address %08x", value&0xffff, address);
+}
+
+void m68k_write_memory_32(unsigned int address, unsigned int value)
+{
+ assert(MASK_24(address) == 0); // Just curious
+ const bool successful = memory_write(BITNESS_16, address, value);
+ if (!successful)
+ exit_error("Attempted to write %08x (u32) to address %08x", value, address);
+}