From fa066cbd0430e9117384ebc21e54e2e0466d52f4 Mon Sep 17 00:00:00 2001 From: Frank Date: Fri, 19 Aug 2022 00:22:39 +0200 Subject: [PATCH] Emu: Add cycle accurate timing --- src/cpu.cpp | 3 --- src/emu.cpp | 24 +++++++++++++++--------- src/emu.h | 16 +++++++++++----- src/main.cpp | 15 +++++++++------ src/ppu.cpp | 3 ++- 5 files changed, 37 insertions(+), 24 deletions(-) diff --git a/src/cpu.cpp b/src/cpu.cpp index 9277c05..ca7547e 100644 --- a/src/cpu.cpp +++ b/src/cpu.cpp @@ -8,7 +8,6 @@ #include // uint8_t, uint32_t #include "cpu.h" -#include "emu.h" #include "ruc/format/print.h" CPU::CPU(uint32_t frequency) @@ -28,8 +27,6 @@ void CPU::update() } print("This is an update from the CPU\n"); - Emu::the().writeMemory("RAM", 123, 42); - print("fff"); } void CPU::add(uint8_t opcode, uint8_t immediate) diff --git a/src/emu.cpp b/src/emu.cpp index 549a1c4..fb92574 100644 --- a/src/emu.cpp +++ b/src/emu.cpp @@ -7,32 +7,38 @@ void Emu::init(uint32_t frequency) { m_frequency = frequency; + m_timestep = 1.0 / m_frequency * 1000000; } void Emu::update() { - for (auto unit : m_processing_units) { - if (m_cycle % (m_frequency / unit->frequency()) == 0) { - unit->update(); + double time = m_timer.elapsedNanoseconds() / 1000.0; + m_cycle_time += (time - m_previous_time); + m_previous_time = time; + if (m_cycle_time > m_timestep) { + for (auto unit : m_processing_units) { + if (m_cycle % (m_frequency / unit.second->frequency()) == 0) { + unit.second->update(); + } } + m_cycle_time -= m_timestep; + m_cycle++; } - m_cycle++; } -void Emu::addProcessingUnit(ProcessingUnit* processing_unit) +void Emu::addProcessingUnit(const char* name, ProcessingUnit* processing_unit) { - m_processing_units.push_back(processing_unit); + m_processing_units.emplace(name, processing_unit); } void Emu::addMemorySpace(const char* name, uint32_t size) { - std::vector memory(size); + std::vector memory(size); m_memory_spaces.emplace(name, memory); } -void Emu::writeMemory(const char* memory_space, uint32_t location, uint8_t value) +void Emu::writeMemory(const char* memory_space, uint32_t location, uint32_t value) { - print("{} {} {}\n", memory_space, location, value); m_memory_spaces[memory_space][location] = value; } diff --git a/src/emu.h b/src/emu.h index a6d6076..52edb84 100644 --- a/src/emu.h +++ b/src/emu.h @@ -6,6 +6,7 @@ #include "processing-unit.h" #include "ruc/singleton.h" +#include "ruc/timer.h" class Emu final : public ruc::Singleton { public: @@ -15,17 +16,22 @@ public: void update(); - void addProcessingUnit(ProcessingUnit* processing_unit); + void addProcessingUnit(const char* name, ProcessingUnit* processing_unit); void addMemorySpace(const char* name, uint32_t size); - void writeMemory(const char* memory_space, uint32_t location, uint8_t value); + void writeMemory(const char* memory_space, uint32_t location, uint32_t value); uint8_t readMemory(const char* memory_space, uint32_t location); private: - uint32_t m_frequency; + uint32_t m_frequency = 0; + double m_timestep = 0; uint32_t m_cycle = 0; + double m_cycle_time = 0; + double m_previous_time = 0; - std::vector m_processing_units; - std::unordered_map> m_memory_spaces; + ruc::Timer m_timer; + + std::unordered_map m_processing_units; + std::unordered_map> m_memory_spaces; }; diff --git a/src/main.cpp b/src/main.cpp index 3f48447..c6b342e 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -11,17 +11,20 @@ int main(int argc, char* argv[]) printf("%fms\n", t.elapsedNanoseconds() / 1000000.0); - Emu::the().init(4000000); + Emu::the().init(8000000); - CPU cpu(1000000); - PPU ppu(2000000); + CPU cpu(8000000); + PPU ppu(4000000); - Emu::the().addProcessingUnit(&cpu); - Emu::the().addProcessingUnit(&ppu); + Emu::the().addProcessingUnit("cpu", &cpu); + Emu::the().addProcessingUnit("ppu", &ppu); Emu::the().addMemorySpace("RAM", 1024); + Emu::the().addMemorySpace("VRAM", 1024); + Emu::the().addMemorySpace("ROM", 1024); + Emu::the().addMemorySpace("CARDROM", 1024); - for (int i = 0; i < 1000; i++) { + while (true) { Emu::the().update(); } diff --git a/src/ppu.cpp b/src/ppu.cpp index 2fe91c8..5ffe542 100644 --- a/src/ppu.cpp +++ b/src/ppu.cpp @@ -6,6 +6,7 @@ */ #include "ppu.h" +#include "ruc/format/print.h" #include PPU ::PPU(unsigned int frequency) @@ -19,5 +20,5 @@ PPU ::~PPU() void PPU::update() { - printf("ppu update\n"); + print("ppu update\n"); }