/* * Copyright (C) 2022 Riyyi * Copyright (C) 2022 Th3FrankXD * * SPDX-License-Identifier: MIT */ #pragma once #include // uint32_t #include #include #include #include #include "processing-unit.h" #include "ruc/singleton.h" #include "ruc/timer.h" using BankedMemory = std::vector>; struct MemorySpace { BankedMemory memory; uint32_t active_bank { 0 }; uint32_t start_address { 0 }; uint32_t end_address { 0 }; }; class Emu final : public ruc::Singleton { public: Emu(s) {} void init(uint32_t frequency); void update(); void addProcessingUnit(std::string_view name, ProcessingUnit* processing_unit); void addMemorySpace(std::string_view name, uint32_t start_address, uint32_t end_address, uint32_t amount_of_banks = 1); void writeMemory(uint32_t address, uint32_t value); uint32_t readMemory(uint32_t address) const; // ------------------------------------- ProcessingUnit* processingUnit(std::string_view name) const { return m_processing_units.at(name); } private: uint32_t m_frequency { 0 }; double m_timestep { 0 }; uint32_t m_cycle { 0 }; double m_cycle_time { 0 }; double m_previous_time { 0 }; ruc::Timer m_timer; std::unordered_map m_processing_units; std::unordered_map m_memory_spaces; };