summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOxore <oxore@protonmail.com>2023-06-09 00:41:05 +0300
committerOxore <oxore@protonmail.com>2023-06-09 00:41:05 +0300
commita8beae02428f4c7762c3621b4a6d23a498b7d394 (patch)
treee8f0bcc67aa62aeb1d74a462119923e615ea3031
parent0c6c5803588a06160fbb55dd4228e94453df89ff (diff)
Impl VDP register bits tracing
-rw-r--r--vdp.cpp119
-rw-r--r--vdp.hpp216
2 files changed, 221 insertions, 114 deletions
diff --git a/vdp.cpp b/vdp.cpp
index 02cc21c..df3a7cc 100644
--- a/vdp.cpp
+++ b/vdp.cpp
@@ -131,6 +131,117 @@ static constexpr uint16_t kScrollSpeedMask = BitsCountToMask(10);
// Each pixel has 4 bit depth color
static constexpr uint16_t kPixelColorMask = BitsCountToMask(kBitsPerPixel);
+static const char* reg_mode_set_1_bits[8] = {
+ "Unused(7)",
+ "Unused(6)",
+ "Unused(5)",
+ "HInt(4)",
+ "Unused(3)",
+ "AllBitsFromColor(2)",
+ "HVCounter(1)",
+ "Unused(0)",
+};
+
+static const char* reg_mode_set_2_bits[8] = {
+ "Unused(7)",
+ "Display(6)",
+ "VInt(5)",
+ "DMA(4)",
+ "V30Cell(3)",
+ "Unused(2)",
+ "Unused(1)",
+ "Unused(0)",
+};
+
+static const char* reg_mode_set_3_bits[8] = {
+ "Unused(7)",
+ "Unused(6)",
+ "Unused(5)",
+ "Unused(4)",
+ "ExtInt(3)",
+ "2CellVScroll(2)",
+ "HScrollHi(1)",
+ "HScrollLo(0)",
+};
+
+static const char* reg_mode_set_4_bits[8] = {
+ "H40CellHi(7)",
+ "Unused(6)",
+ "Unused(5)",
+ "Unused(4)",
+ "Shadow(3)",
+ "InterlaceHi(2)",
+ "InterlaceLo(1)",
+ "H40CellLo(0)",
+};
+
+static void TraceRegBits(FILE* s, const char* bits_desc[8], const uint8_t val)
+{
+ fprintf(s, "(");
+ bool separator{};
+ for (size_t i = 0; i < 8; i++) {
+ if (val & (1 << (7 - i))) {
+ if (separator) {
+ fprintf(s, " | ");
+ separator = false;
+ }
+ fprintf(s, bits_desc[i]);
+ separator = true;
+ }
+ }
+ fprintf(s, ")");
+}
+
+static void TraceRegWrite(FILE* const s, const uint8_t reg, const uint8_t val)
+{
+ const auto reg_id = static_cast<VDP::RegID>(reg);
+ fprintf(s, ": reg 0x%02x(%s) = 0x%02x", reg, VDP::RegIDToString(reg_id), val);
+ switch (reg_id) {
+ case VDP::RegID::kModeSet1:
+ return TraceRegBits(s, reg_mode_set_1_bits, val);
+ case VDP::RegID::kModeSet2:
+ return TraceRegBits(s, reg_mode_set_2_bits, val);
+ case VDP::RegID::kScrollAAddress:
+ break;
+ case VDP::RegID::kWindowAddress:
+ break;
+ case VDP::RegID::kScrollBAddress:
+ break;
+ case VDP::RegID::kSpritesTableAddress:
+ break;
+ case VDP::RegID::kBackgroundColor:
+ break;
+ case VDP::RegID::kHint:
+ break;
+ case VDP::RegID::kModeSet3:
+ return TraceRegBits(s, reg_mode_set_3_bits, val);
+ case VDP::RegID::kModeSet4:
+ return TraceRegBits(s, reg_mode_set_4_bits, val);
+ case VDP::RegID::kHScrollTableAddress:
+ break;
+ case VDP::RegID::kAutoIncrement:
+ break;
+ case VDP::RegID::kScrollSize:
+ break;
+ case VDP::RegID::kWindowHorizontalPosition:
+ break;
+ case VDP::RegID::kWindowVertialPosition:
+ break;
+ case VDP::RegID::kDMALengthCounterLow:
+ break;
+ case VDP::RegID::kDMALengthCounterHigh:
+ break;
+ case VDP::RegID::kDMASourceAddressLow:
+ break;
+ case VDP::RegID::kDMASourceAddressMid:
+ break;
+ case VDP::RegID::kDMASourceAddressHigh:
+ break;
+ case VDP::RegID::kRegistersCount:
+ break;
+ }
+}
+
uint32_t VDP::Read(const uint32_t offset, const enum bitness bitness)
{
uint32_t ret{};
@@ -634,11 +745,7 @@ void VDP::writeControl(const uint16_t value)
const uint8_t reg_num = (value >> 8) & 0x1f;
const uint8_t reg_val = value & 0xff;
if (DEBUG_TRACE_VDP_ACCESS) {
- printf(
- ": reg 0x%02x(%s) = 0x%02x",
- reg_num,
- regIDToString(static_cast<RegID>(reg_num)),
- reg_val);
+ TraceRegWrite(stdout, reg_num, reg_val);
}
_reg[reg_num] = reg_val;
// TODO print warnings of all invalid values or writes that ignore a mask
@@ -838,7 +945,7 @@ const char* VDP::addressModeToString(const uint8_t address_mode)
return "Unknown";
}
-const char* VDP::regIDToString(const RegID reg_id)
+const char* VDP::RegIDToString(const RegID reg_id)
{
switch (reg_id) {
case RegID::kModeSet1:
diff --git a/vdp.hpp b/vdp.hpp
index f506ca4..ab8c337 100644
--- a/vdp.hpp
+++ b/vdp.hpp
@@ -22,121 +22,121 @@ struct SpriteAttributeEntry {
};
class VDP {
- public:
- constexpr 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);
- bool Scanline(); // Returns true if display disabled or vblank happened
- void Reset();
- constexpr const uint32_t* GetRenderedBuffer() const { return _rendered_buffer; }
+public:
+ enum class RegID: size_t {
+ kModeSet1 = 0,
+ kModeSet2 = 1,
+ kScrollAAddress = 2,
+ kWindowAddress = 3,
+ kScrollBAddress = 4,
+ kSpritesTableAddress = 5,
+ kBackgroundColor = 7,
+ kHint = 10,
+ kModeSet3 = 11,
+ kModeSet4 = 12,
+ kHScrollTableAddress = 13,
+ kAutoIncrement = 15,
+ kScrollSize = 16,
+ kWindowHorizontalPosition = 17,
+ kWindowVertialPosition = 18,
+ kDMALengthCounterLow = 19,
+ kDMALengthCounterHigh = 20,
+ kDMASourceAddressLow = 21,
+ kDMASourceAddressMid = 22,
+ kDMASourceAddressHigh = 23,
+ kRegistersCount, ///< Keep it last
+ };
- const uint32_t base_address;
+ constexpr 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);
+ bool Scanline(); // Returns true if display disabled or vblank happened
+ void Reset();
+ constexpr const uint32_t* GetRenderedBuffer() const { return _rendered_buffer; }
+ static const char* RegIDToString(RegID);
- static constexpr size_t kRenderHeight = 224;
- static constexpr size_t kRenderWidth = 320;
- static constexpr size_t render_buffer_size = kRenderWidth * kRenderHeight *
- sizeof(*reinterpret_cast<VDP*>(4)->GetRenderedBuffer());
+ static constexpr size_t kRenderHeight = 224;
+ static constexpr size_t kRenderWidth = 320;
+ static constexpr size_t render_buffer_size = kRenderWidth * kRenderHeight *
+ sizeof(*reinterpret_cast<VDP*>(4)->GetRenderedBuffer());
- private:
- struct StatusRegister {
- bool fifo_not_empty{};
- bool fifo_full{};
- bool v_irq{};
- bool sprites_overflow{};
- bool sprites_collision{};
- bool odd_frame{};
- bool vblank{};
- bool hblank{};
- bool dma_busy{};
- bool pal_mode{};
- };
+ const uint32_t base_address;
- enum class AddressMode: uint8_t {
- kVRAMWrite = 1,
- kCRAMWrite = 3,
- kVSRAMWrite = 5,
- kVRAMRead = 0,
- kCRAMRead = 8,
- kVSRAMRead = 4,
- };
+private:
+ struct StatusRegister {
+ bool fifo_not_empty{};
+ bool fifo_full{};
+ bool v_irq{};
+ bool sprites_overflow{};
+ bool sprites_collision{};
+ bool odd_frame{};
+ bool vblank{};
+ bool hblank{};
+ bool dma_busy{};
+ bool pal_mode{};
+ };
- enum class RegID: size_t {
- kModeSet1 = 0,
- kModeSet2 = 1,
- kScrollAAddress = 2,
- kWindowAddress = 3,
- kScrollBAddress = 4,
- kSpritesTableAddress = 5,
- kBackgroundColor = 7,
- kHint = 10,
- kModeSet3 = 11,
- kModeSet4 = 12,
- kHScrollTableAddress = 13,
- kAutoIncrement = 15,
- kScrollSize = 16,
- kWindowHorizontalPosition = 17,
- kWindowVertialPosition = 18,
- kDMALengthCounterLow = 19,
- kDMALengthCounterHigh = 20,
- kDMASourceAddressLow = 21,
- kDMASourceAddressMid = 22,
- kDMASourceAddressHigh = 23,
- kRegistersCount, ///< Keep it last
- };
+ enum class AddressMode: uint8_t {
+ kVRAMWrite = 1,
+ kCRAMWrite = 3,
+ kVSRAMWrite = 5,
+ kVRAMRead = 0,
+ kCRAMRead = 8,
+ kVSRAMRead = 4,
+ };
- void renderScrollLine(
- size_t line_index,
- uint16_t plane_addr,
- uint16_t hscroll_table_addr,
- size_t plane_index,
- size_t hcell_count,
- size_t vcell_count);
- void renderScrollALine(size_t line_index, size_t hcell_count, size_t vcell_count);
- void renderScrollBLine(size_t line_index, size_t hcell_count, size_t vcell_count);
- void renderSpritesLine(size_t line_index);
- void renderSpriteOnTheLine(SpriteAttributeEntry, size_t line_index);
- void writeData(uint8_t address_mode, uint16_t address, uint16_t value);
- void writeControl(uint16_t value);
- uint16_t readData(uint8_t address_mode, uint16_t address);
- uint16_t readStatusRegister() const;
- uint8_t* baseFromAddressMode(uint8_t address_mode);
- const char* addressModeToString(uint8_t address_mode);
- const char* regIDToString(RegID);
+ void renderScrollLine(
+ size_t line_index,
+ uint16_t plane_addr,
+ uint16_t hscroll_table_addr,
+ size_t plane_index,
+ size_t hcell_count,
+ size_t vcell_count);
+ void renderScrollALine(size_t line_index, size_t hcell_count, size_t vcell_count);
+ void renderScrollBLine(size_t line_index, size_t hcell_count, size_t vcell_count);
+ void renderSpritesLine(size_t line_index);
+ void renderSpriteOnTheLine(SpriteAttributeEntry, size_t line_index);
+ void writeData(uint8_t address_mode, uint16_t address, uint16_t value);
+ void writeControl(uint16_t value);
+ uint16_t readData(uint8_t address_mode, uint16_t address);
+ uint16_t readStatusRegister() const;
+ uint8_t* baseFromAddressMode(uint8_t address_mode);
+ const char* addressModeToString(uint8_t address_mode);
- static void runDMAMemoryToVRAM(
- uint8_t* base,
- uint32_t source_address,
- uint16_t destination_address,
- uint16_t transfer_size,
- uint8_t increment);
- static void runDMAVRAMFill(
- uint8_t* base,
- uint16_t destination_address,
- uint16_t transfer_size,
- uint8_t increment,
- uint16_t filler);
- static void runDMAVRAMCopy(uint8_t* base);
+ static void runDMAMemoryToVRAM(
+ uint8_t* base,
+ uint32_t source_address,
+ uint16_t destination_address,
+ uint16_t transfer_size,
+ uint8_t increment);
+ static void runDMAVRAMFill(
+ uint8_t* base,
+ uint16_t destination_address,
+ uint16_t transfer_size,
+ uint8_t increment,
+ uint16_t filler);
+ static void runDMAVRAMCopy(uint8_t* base);
- static constexpr size_t kRegistersCount = static_cast<size_t>(RegID::kRegistersCount);
- static constexpr size_t kVRAMSize = 64*1024;
- static constexpr size_t kCRAMSize = 64*2;
- static constexpr size_t kVSRAMSize = 40*2;
- static constexpr uint16_t kLinesPerScreenNTSC = 262;
- static constexpr uint16_t kLinesPerScreenPAL = 312;
+ static constexpr size_t kRegistersCount = static_cast<size_t>(RegID::kRegistersCount);
+ static constexpr size_t kVRAMSize = 64*1024;
+ static constexpr size_t kCRAMSize = 64*2;
+ static constexpr size_t kVSRAMSize = 40*2;
+ static constexpr uint16_t kLinesPerScreenNTSC = 262;
+ static constexpr uint16_t kLinesPerScreenPAL = 312;
- StatusRegister _status{};
- bool _control_write_second_word{};
- // DMA Fill is ready to kick in, waiting for filler set to data port
- bool _dma_ready{};
- uint16_t _lines_counter{};
- // TODO: Make _address_mode of type AddressMode somehow and all private
- // methods using it should be accepting AddressMode instead of uint8_t.
- uint8_t _address_mode{};
- uint16_t _address{};
- uint8_t _reg[kRegistersCount]{};
- uint8_t _vram[kVRAMSize]{};
- uint8_t _cram[kCRAMSize]{};
- uint8_t _vsram[kVSRAMSize]{};
- uint32_t _rendered_buffer[kLinesPerScreenNTSC * kRenderWidth]{};
- bool _unclosed_sprites_list{};
+ StatusRegister _status{};
+ bool _control_write_second_word{};
+ // DMA Fill is ready to kick in, waiting for filler set to data port
+ bool _dma_ready{};
+ uint16_t _lines_counter{};
+ // TODO: Make _address_mode of type AddressMode somehow and all private
+ // methods using it should be accepting AddressMode instead of uint8_t.
+ uint8_t _address_mode{};
+ uint16_t _address{};
+ uint8_t _reg[kRegistersCount]{};
+ uint8_t _vram[kVRAMSize]{};
+ uint8_t _cram[kCRAMSize]{};
+ uint8_t _vsram[kVSRAMSize]{};
+ uint32_t _rendered_buffer[kLinesPerScreenNTSC * kRenderWidth]{};
+ bool _unclosed_sprites_list{};
};