#pragma once #include #include "Memory.h" #include "Ram.h" namespace EightBit { class InputOutput final : public Memory { public: enum class AccessType { Unknown, Reading, Writing }; [[nodiscard]] size_t size() const noexcept override; [[nodiscard]] uint8_t peek(uint16_t address) const noexcept override; [[nodiscard]] uint8_t& reference(uint16_t address) noexcept override; int load(std::ifstream& file, int writeOffset = 0, int readOffset = 0, int limit = -1) override; int load(std::string path, int writeOffset = 0, int readOffset = 0, int limit = -1) override; int load(const std::vector& bytes, int writeOffset = 0, int readOffset = 0, int limit = -1) override; [[nodiscard]] constexpr const auto& accessType() const noexcept { return m_access; } [[nodiscard]] constexpr auto& accessType() noexcept { return m_access; } [[nodiscard]] auto readPort(uint8_t port, AccessType access) noexcept { accessType() = access; return reference(port); } [[nodiscard]] auto readInputPort(uint8_t port) noexcept { return readPort(port, AccessType::Reading); } [[nodiscard]] auto readOutputPort(uint8_t port) noexcept { return readPort(port, AccessType::Writing); } void writePort(uint8_t port, uint8_t value, AccessType access) noexcept { accessType() = access; reference(port) = value; } void writeInputPort(uint8_t port, uint8_t value) noexcept { writePort(port, value, AccessType::Reading); } void writeOutputPort(uint8_t port, uint8_t value) noexcept { writePort(port, value, AccessType::Writing); } protected: void poke(uint16_t address, uint8_t value) noexcept override; private: Ram m_input = 0x100; Ram m_output = 0x100; uint8_t m_delivered = 0xff; AccessType m_access = AccessType::Unknown; }; }