summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt2
-rw-r--r--bus.cpp46
-rw-r--r--bus.hpp6
-rw-r--r--vdp.cpp64
-rw-r--r--vdp.hpp23
5 files changed, 117 insertions, 24 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 0b2323c..5edf23b 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -20,6 +20,7 @@ set(emulator_sources
emulator.cpp
gdbremote_parser.cpp
m68k_debugging.cpp
+ vdp.cpp
)
set(musashi_m68k_sources
musashi-m68k/m68kcpu.c
@@ -49,6 +50,7 @@ target_link_libraries(emulator musashi_m68k)
target_compile_definitions(emulator PRIVATE
DEBUG_TRACE_INSTRUCTIONS=0
DEBUG_TRACE_GDB_REMOTE=0
+ DEBUG_TRACE_VDP_ACCESS=1
)
## Target for GDB Remote Debugging protocol implementation testing
diff --git a/bus.cpp b/bus.cpp
index 835bb56..eb2c83b 100644
--- a/bus.cpp
+++ b/bus.cpp
@@ -4,6 +4,7 @@
#include "bus.hpp"
#include "musashi-m68k/m68k.h"
#include "utils.hpp"
+#include "vdp.hpp"
#include <cassert>
#include <cstdarg>
@@ -12,6 +13,10 @@
#include <cstdint>
#include <cstdlib>
+#if !defined(DEBUG_TRACE_VDP_ACCESS)
+# define DEBUG_TRACE_VDP_ACCESS 0
+#endif
+
namespace Adr {
static constexpr uint32_t kZ80BusReq = 0x00a11100;
}
@@ -22,9 +27,10 @@ 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[VDP_SIZE] = {};
std::vector<Breakpoint> code_bkpts{}, read_bkpts{}, write_bkpts{}, access_bkpts{};
+static VDP g_vdp(VDP_START);
+
static void exit_error(const char* fmt, ...)
{
static bool in_error = false;
@@ -69,13 +75,7 @@ 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 = 1,
- BITNESS_16 = 2,
- BITNESS_32 = 4,
-};
-
-struct read_result {
+struct ReadResult {
unsigned int result;
bool successful;
};
@@ -128,39 +128,38 @@ static inline void m68k_read_callback(const uint32_t address, const uint32_t siz
}
}
-static inline struct read_result memory_read(
+static inline ReadResult memory_read(
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{
+ return ReadResult{
memory_read_concrete(bitness, g_rom, address - ROM_START),
true,
};
} else if (is_in_range(address, RAM_START, RAM_SIZE)) {
- return read_result{
+ return ReadResult{
memory_read_concrete(bitness, g_ram, address - RAM_START),
true,
};
} else if (is_in_range(address, SOUND_RAM_START, SOUND_RAM_SIZE)) {
- return read_result{
+ return ReadResult{
memory_read_concrete(bitness, g_sound_ram, address - SOUND_RAM_START),
true,
};
} else if (is_in_range(address, IO1_START, IO1_SIZE)) {
- return read_result{
+ return ReadResult{
memory_read_concrete(bitness, g_io1, address - IO1_START),
true,
};
} else if (is_in_range(address, VDP_START, VDP_SIZE)) {
- printf("VDP read u%d 0x%0x\n", bitness * 8, address);
- return read_result{
- memory_read_concrete(bitness, g_io2, address - VDP_START),
+ return ReadResult{
+ g_vdp.Read(address - g_vdp.base_address, bitness),
true,
};
}
- return read_result{0, false};
+ return ReadResult{0, false};
}
static inline void memory_write_concrete(
@@ -232,8 +231,7 @@ static inline bool memory_write(
}
return true;
} else if (is_in_range(address, VDP_START, VDP_SIZE)) {
- printf("VDP write u%d 0x%0x\n", bitness * 8, address);
- memory_write_concrete(bitness, g_io2, address - VDP_START, value);
+ g_vdp.Write(address - g_vdp.base_address, bitness, value);
return true;
}
return false;
@@ -244,7 +242,7 @@ static inline bool memory_write(
unsigned int m68k_read_memory_8(const unsigned int address_a)
{
const uint32_t address = MASK_24(address_a);
- const struct read_result ret = memory_read(BITNESS_8, address);
+ const ReadResult ret = memory_read(BITNESS_8, address);
if (!ret.successful) {
report_error("Read error u8 @%08x", address);
m68k_breakpoint_callback();
@@ -255,7 +253,7 @@ unsigned int m68k_read_memory_8(const unsigned int address_a)
unsigned int m68k_read_memory_16(const unsigned int address_a)
{
const uint32_t address = MASK_24(address_a);
- const struct read_result ret = memory_read(BITNESS_16, address);
+ const ReadResult ret = memory_read(BITNESS_16, address);
if (!ret.successful) {
report_error("Read error u16 @%08x", address);
m68k_breakpoint_callback();
@@ -266,7 +264,7 @@ unsigned int m68k_read_memory_16(const unsigned int address_a)
unsigned int m68k_read_memory_32(const unsigned int address_a)
{
const uint32_t address = MASK_24(address_a);
- const struct read_result ret = memory_read(BITNESS_32, address);
+ const ReadResult ret = memory_read(BITNESS_32, address);
if (!ret.successful) {
report_error("Read error u32 @%08x", address);
m68k_breakpoint_callback();
@@ -277,7 +275,7 @@ unsigned int m68k_read_memory_32(const unsigned int address_a)
unsigned int m68k_read_disassembler_16(const unsigned int address_a)
{
const uint32_t address = MASK_24(address_a);
- const struct read_result ret = memory_read(BITNESS_16, address);
+ const ReadResult ret = memory_read(BITNESS_16, address);
if (0 && !ret.successful)
exit_error("Disasm read error u16 @0x%08x", address);
return ret.result;
@@ -286,7 +284,7 @@ unsigned int m68k_read_disassembler_16(const unsigned int address_a)
unsigned int m68k_read_disassembler_32(const unsigned int address_a)
{
const uint32_t address = MASK_24(address_a);
- const struct read_result ret = memory_read(BITNESS_32, address);
+ const ReadResult ret = memory_read(BITNESS_32, address);
if (0 && !ret.successful)
exit_error("Disasm read error u32 @0x%08x", address);
return ret.result;
diff --git a/bus.hpp b/bus.hpp
index 9745073..0492abd 100644
--- a/bus.hpp
+++ b/bus.hpp
@@ -18,6 +18,12 @@
#define VDP_START (0xC00000)
#define VDP_SIZE (0x20)
+enum bitness {
+ BITNESS_8 = 1,
+ BITNESS_16 = 2,
+ BITNESS_32 = 4,
+};
+
struct Breakpoint {
uint32_t offset, length;
};
diff --git a/vdp.cpp b/vdp.cpp
new file mode 100644
index 0000000..632429d
--- /dev/null
+++ b/vdp.cpp
@@ -0,0 +1,64 @@
+/* SPDX-License-Identifier: Unlicense
+ */
+
+#include "vdp.hpp"
+
+uint32_t VDP::Read(const uint32_t offset, const enum bitness bitness)
+{
+ const uint32_t res{};
+ if (DEBUG_TRACE_VDP_ACCESS) {
+ printf(
+ "VDP r%d%s @0x%08x 0x%0*x\n",
+ bitness * 8,
+ (bitness <= 1 ? " " : ""),
+ base_address + offset,
+ bitness * 2,
+ res);
+ }
+ if (bitness == BITNESS_32) {
+ // TODO
+ } else if (bitness == BITNESS_16) {
+ // TODO
+ }
+ // Ignore 8-bit reads for now
+ return 0;
+}
+
+void VDP::Write(const uint32_t offset, const enum bitness bitness, const uint32_t value)
+{
+ if (DEBUG_TRACE_VDP_ACCESS) {
+ printf(
+ "VDP w%d%s @0x%08x 0x%0*x",
+ bitness * 8,
+ (bitness <= 1 ? " " : ""),
+ base_address + offset,
+ bitness * 2,
+ value);
+ }
+ if (bitness == BITNESS_32) {
+ if (offset == 4 || offset == 6) {
+ writeControl((value >> 16) & 0xffff);
+ writeControl(value & 0xffff);
+ }
+ } else if (bitness == BITNESS_16) {
+ if (offset == 4 || offset == 6) {
+ writeControl(value & 0xffff);
+ }
+ }
+ if (DEBUG_TRACE_VDP_ACCESS) {
+ printf("\n");
+ }
+ // Ignore 8-bit writes for now
+}
+
+void VDP::writeControl(const uint16_t value)
+{
+ if (((value >> 13) & 0x7) == 4) {
+ const uint8_t reg_num = (value >> 8) & 0x1f;
+ const uint8_t reg_val = value & 0xff;
+ if (DEBUG_TRACE_VDP_ACCESS) {
+ printf(": reg 0x%02x w 0x%02x", reg_num, reg_val);
+ }
+ _reg[reg_num] = reg_val;
+ }
+}
diff --git a/vdp.hpp b/vdp.hpp
new file mode 100644
index 0000000..0e911c9
--- /dev/null
+++ b/vdp.hpp
@@ -0,0 +1,23 @@
+/* SPDX-License-Identifier: Unlicense
+ */
+
+#pragma once
+
+#include "bus.hpp"
+
+#include <cstdio>
+
+class VDP {
+ public:
+ VDP(const uint32_t base_address_a = VDP_START): base_address(base_address_a) {}
+ uint32_t Read(uint32_t offset, enum bitness);
+ void Write(uint32_t offset, enum bitness, uint32_t value);
+
+ const uint32_t base_address;
+
+ private:
+ void writeControl(uint16_t value);
+
+ static constexpr size_t kRegistersCount = 0x18;
+ uint8_t _reg[kRegistersCount]{};
+};