/* SPDX-License-Identifier: Unlicense */ #pragma once #include "bus.hpp" #include #include 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); bool Scanline(); // Returns true if display disabled or vblank happened void Reset(); const uint32_t base_address; 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 AddressMode: uint8_t { kVRAMWrite = 1, kCRAMWrite = 3, kVSRAMWrite = 5, kVRAMRead = 0, kCRAMRead = 8, kVSRAMRead = 4, }; 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, kDMACounterLow = 19, kDMACounterHigh = 20, kDMASourceAddressLow = 21, kDMASourceAddressMid = 22, kDMASourceAddressHigh = 23, kRegistersCount, ///< Keep it last }; 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; const char* addressModeToString(uint8_t address_mode); const char* regIDToString(RegID); static constexpr size_t kRegistersCount = static_cast(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{}; uint16_t _lines_counter{}; uint8_t _address_mode{}; uint16_t _address{}; uint8_t _reg[kRegistersCount]{}; uint8_t _vram[kVRAMSize]{}; uint8_t _cram[kCRAMSize]{}; uint8_t _vsram[kVSRAMSize]{}; };