From b58b29d977a2273bb21f4aa219d02e408d57056b Mon Sep 17 00:00:00 2001 From: ergo720 <45463469+ergo720@users.noreply.github.com> Date: Thu, 21 Mar 2024 21:26:25 +0100 Subject: [PATCH] nv2a: implemented more bits of NV_PMC_ENABLE --- src/hw/video/gpu/nv2a.cpp | 20 +++++++-------- src/hw/video/gpu/pbus.hpp | 2 +- src/hw/video/gpu/pcrtc.cpp | 47 ++++++++++++++++++++++++++++++--- src/hw/video/gpu/pcrtc.hpp | 8 +++--- src/hw/video/gpu/pfb.cpp | 47 ++++++++++++++++++++++++++++++--- src/hw/video/gpu/pfb.hpp | 8 +++--- src/hw/video/gpu/pfifo.cpp | 47 ++++++++++++++++++++++++++++++--- src/hw/video/gpu/pfifo.hpp | 8 +++--- src/hw/video/gpu/pmc.cpp | 22 ++++++++++++---- src/hw/video/gpu/pmc.hpp | 20 ++++++++++++++- src/hw/video/gpu/pramdac.hpp | 2 +- src/hw/video/gpu/pramin.hpp | 2 +- src/hw/video/gpu/ptimer.cpp | 50 ++++++++++++++++++++++++++++++++---- src/hw/video/gpu/ptimer.hpp | 11 ++++---- src/hw/video/gpu/pvga.hpp | 2 +- src/hw/video/gpu/pvideo.cpp | 47 ++++++++++++++++++++++++++++++--- src/hw/video/gpu/pvideo.hpp | 8 +++--- 17 files changed, 293 insertions(+), 58 deletions(-) diff --git a/src/hw/video/gpu/nv2a.cpp b/src/hw/video/gpu/nv2a.cpp index c8fc367..31eaf22 100644 --- a/src/hw/video/gpu/nv2a.cpp +++ b/src/hw/video/gpu/nv2a.cpp @@ -50,14 +50,14 @@ nv2a::get_next_update_time(uint64_t now) void nv2a::apply_log_settings() { - m_pmc.update_io_logging(); - m_pcrtc.update_io_logging(); - m_pramdac.update_io_logging(); - m_ptimer.update_io_logging(); - m_pfb.update_io_logging(); - m_pbus.update_io_logging(); - m_pramin.update_io_logging(); - m_pfifo.update_io_logging(); - m_pvga.update_io_logging(); - m_pvideo.update_io_logging(); + m_pmc.update_io(); + m_pcrtc.update_io(); + m_pramdac.update_io(); + m_ptimer.update_io(); + m_pfb.update_io(); + m_pbus.update_io(); + m_pramin.update_io(); + m_pfifo.update_io(); + m_pvga.update_io(); + m_pvideo.update_io(); } diff --git a/src/hw/video/gpu/pbus.hpp b/src/hw/video/gpu/pbus.hpp index 8d837fd..32364d5 100644 --- a/src/hw/video/gpu/pbus.hpp +++ b/src/hw/video/gpu/pbus.hpp @@ -14,7 +14,7 @@ class pbus { pbus(machine *machine) : m_machine(machine), m_pci_conf(nullptr) {} bool init(); void reset(); - void update_io_logging() { update_io(true); } + void update_io() { update_io(true); } template<bool log = false> uint32_t read(uint32_t addr); template<bool log = false> diff --git a/src/hw/video/gpu/pcrtc.cpp b/src/hw/video/gpu/pcrtc.cpp index 6b9a058..312da88 100644 --- a/src/hw/video/gpu/pcrtc.cpp +++ b/src/hw/video/gpu/pcrtc.cpp @@ -17,9 +17,12 @@ #define NV_PCRTC_UNKNOWN0 (NV2A_REGISTER_BASE + 0x00600804) -template<bool log> +template<bool log, bool enabled> void pcrtc::write(uint32_t addr, const uint32_t data) { + if constexpr (!enabled) { + return; + } if constexpr (log) { log_io_write(); } @@ -49,9 +52,13 @@ void pcrtc::write(uint32_t addr, const uint32_t data) } } -template<bool log> +template<bool log, bool enabled> uint32_t pcrtc::read(uint32_t addr) { + if constexpr (!enabled) { + return 0; + } + uint32_t value = 0; switch (addr) @@ -83,14 +90,46 @@ uint32_t pcrtc::read(uint32_t addr) return value; } +template<bool is_write> +auto pcrtc::get_io_func(bool log, bool enabled) +{ + if constexpr (is_write) { + if (enabled) { + if (log) { + return cpu_write<pcrtc, uint32_t, &pcrtc::write<true>>; + } + else { + return cpu_write<pcrtc, uint32_t, &pcrtc::write<false>>; + } + } + else { + return cpu_write<pcrtc, uint32_t, &pcrtc::write<false, false>>; + } + } + else { + if (enabled) { + if (log) { + return cpu_read<pcrtc, uint32_t, &pcrtc::read<true>>; + } + else { + return cpu_read<pcrtc, uint32_t, &pcrtc::read<false>>; + } + } + else { + return cpu_read<pcrtc, uint32_t, &pcrtc::read<false, false>>; + } + } +} + bool pcrtc::update_io(bool is_update) { bool log = module_enabled(); + bool enabled = m_machine->get<pmc>().engine_enabled & NV_PMC_ENABLE_PCRTC; if (!LC86_SUCCESS(mem_init_region_io(m_machine->get<cpu_t *>(), NV_PCRTC_BASE, NV_PCRTC_SIZE, false, { - .fnr32 = log ? cpu_read<pcrtc, uint32_t, &pcrtc::read<true>> : cpu_read<pcrtc, uint32_t, &pcrtc::read<false>>, - .fnw32 = log ? cpu_write<pcrtc, uint32_t, &pcrtc::write<true>> : cpu_write<pcrtc, uint32_t, &pcrtc::write<false>> + .fnr32 = get_io_func<false>(log, enabled), + .fnw32 = get_io_func<true>(log, enabled) }, this, is_update, is_update))) { logger_en(error, "Failed to update mmio region"); diff --git a/src/hw/video/gpu/pcrtc.hpp b/src/hw/video/gpu/pcrtc.hpp index 4e611e9..f3dc5e6 100644 --- a/src/hw/video/gpu/pcrtc.hpp +++ b/src/hw/video/gpu/pcrtc.hpp @@ -17,14 +17,16 @@ class pcrtc { pcrtc(machine *machine) : m_machine(machine) {} bool init(); void reset(); - void update_io_logging() { update_io(true); } - template<bool log = false> + void update_io() { update_io(true); } + template<bool log = false, bool enabled = true> uint32_t read(uint32_t addr); - template<bool log = false> + template<bool log = false, bool enabled = true> void write(uint32_t addr, const uint32_t data); private: bool update_io(bool is_update); + template<bool is_write> + auto get_io_func(bool log, bool enabled); friend class pmc; machine *const m_machine; diff --git a/src/hw/video/gpu/pfb.cpp b/src/hw/video/gpu/pfb.cpp index fc8c50e..edcca47 100644 --- a/src/hw/video/gpu/pfb.cpp +++ b/src/hw/video/gpu/pfb.cpp @@ -16,9 +16,12 @@ #define NV_PFB_NVM (NV2A_REGISTER_BASE + 0x00100214) -template<bool log> +template<bool log, bool enabled> void pfb::write(uint32_t addr, const uint32_t data) { + if constexpr (!enabled) { + return; + } if constexpr (log) { log_io_write(); } @@ -46,9 +49,13 @@ void pfb::write(uint32_t addr, const uint32_t data) } } -template<bool log> +template<bool log, bool enabled> uint32_t pfb::read(uint32_t addr) { + if constexpr (!enabled) { + return 0; + } + uint32_t value = 0; switch (addr) @@ -80,14 +87,46 @@ uint32_t pfb::read(uint32_t addr) return value; } +template<bool is_write> +auto pfb::get_io_func(bool log, bool enabled) +{ + if constexpr (is_write) { + if (enabled) { + if (log) { + return cpu_write<pfb, uint32_t, &pfb::write<true>>; + } + else { + return cpu_write<pfb, uint32_t, &pfb::write<false>>; + } + } + else { + return cpu_write<pfb, uint32_t, &pfb::write<false, false>>; + } + } + else { + if (enabled) { + if (log) { + return cpu_read<pfb, uint32_t, &pfb::read<true>>; + } + else { + return cpu_read<pfb, uint32_t, &pfb::read<false>>; + } + } + else { + return cpu_read<pfb, uint32_t, &pfb::read<false, false>>; + } + } +} + bool pfb::update_io(bool is_update) { bool log = module_enabled(); + bool enabled = m_machine->get<pmc>().engine_enabled & NV_PMC_ENABLE_PFB; if (!LC86_SUCCESS(mem_init_region_io(m_machine->get<cpu_t *>(), NV_PFB_BASE, NV_PFB_SIZE, false, { - .fnr32 = log ? cpu_read<pfb, uint32_t, &pfb::read<true>> : cpu_read<pfb, uint32_t, &pfb::read<false>>, - .fnw32 = log ? cpu_write<pfb, uint32_t, &pfb::write<true>> : cpu_write<pfb, uint32_t, &pfb::write<false>> + .fnr32 = get_io_func<false>(log, enabled), + .fnw32 = get_io_func<true>(log, enabled) }, this, is_update, is_update))) { logger_en(error, "Failed to update mmio region"); diff --git a/src/hw/video/gpu/pfb.hpp b/src/hw/video/gpu/pfb.hpp index 49c7bde..34c41df 100644 --- a/src/hw/video/gpu/pfb.hpp +++ b/src/hw/video/gpu/pfb.hpp @@ -15,14 +15,16 @@ class pfb { pfb(machine *machine) : m_machine(machine) {} bool init(); void reset(); - void update_io_logging() { update_io(true); } - template<bool log = false> + void update_io() { update_io(true); } + template<bool log = false, bool enabled = true> uint32_t read(uint32_t addr); - template<bool log = false> + template<bool log = false, bool enabled = true> void write(uint32_t addr, const uint32_t data); private: bool update_io(bool is_update); + template<bool is_write> + auto get_io_func(bool log, bool enabled); friend class pramin; machine *const m_machine; diff --git a/src/hw/video/gpu/pfifo.cpp b/src/hw/video/gpu/pfifo.cpp index ca4d67c..71e2d2b 100644 --- a/src/hw/video/gpu/pfifo.cpp +++ b/src/hw/video/gpu/pfifo.cpp @@ -15,9 +15,12 @@ #define NV_PFIFO_RAMRO (NV2A_REGISTER_BASE + 0x00002218) -template<bool log> +template<bool log, bool enabled> void pfifo::write(uint32_t addr, const uint32_t data) { + if constexpr (!enabled) { + return; + } if constexpr (log) { log_io_write(); } @@ -41,9 +44,13 @@ void pfifo::write(uint32_t addr, const uint32_t data) } } -template<bool log> +template<bool log, bool enabled> uint32_t pfifo::read(uint32_t addr) { + if constexpr (!enabled) { + return 0; + } + uint32_t value = 0; switch (addr) @@ -71,14 +78,46 @@ uint32_t pfifo::read(uint32_t addr) return value; } +template<bool is_write> +auto pfifo::get_io_func(bool log, bool enabled) +{ + if constexpr (is_write) { + if (enabled) { + if (log) { + return cpu_write<pfifo, uint32_t, &pfifo::write<true>>; + } + else { + return cpu_write<pfifo, uint32_t, &pfifo::write<false>>; + } + } + else { + return cpu_write<pfifo, uint32_t, &pfifo::write<false, false>>; + } + } + else { + if (enabled) { + if (log) { + return cpu_read<pfifo, uint32_t, &pfifo::read<true>>; + } + else { + return cpu_read<pfifo, uint32_t, &pfifo::read<false>>; + } + } + else { + return cpu_read<pfifo, uint32_t, &pfifo::read<false, false>>; + } + } +} + bool pfifo::update_io(bool is_update) { bool log = module_enabled(); + bool enabled = m_machine->get<pmc>().engine_enabled & NV_PMC_ENABLE_PFIFO; if (!LC86_SUCCESS(mem_init_region_io(m_machine->get<cpu_t *>(), NV_PFIFO_BASE, NV_PFIFO_SIZE, false, { - .fnr32 = log ? cpu_read<pfifo, uint32_t, &pfifo::read<true>> : cpu_read<pfifo, uint32_t, &pfifo::read<false>>, - .fnw32 = log ? cpu_write<pfifo, uint32_t, &pfifo::write<true>> : cpu_write<pfifo, uint32_t, &pfifo::write<false>> + .fnr32 = get_io_func<false>(log, enabled), + .fnw32 = get_io_func<true>(log, enabled) }, this, is_update, is_update))) { logger_en(error, "Failed to update mmio region"); diff --git a/src/hw/video/gpu/pfifo.hpp b/src/hw/video/gpu/pfifo.hpp index d493142..c749d75 100644 --- a/src/hw/video/gpu/pfifo.hpp +++ b/src/hw/video/gpu/pfifo.hpp @@ -14,14 +14,16 @@ class pfifo { pfifo(machine *machine) : m_machine(machine) {} bool init(); void reset(); - void update_io_logging() { update_io(true); } - template<bool log = false> + void update_io() { update_io(true); } + template<bool log = false, bool enabled = true> uint32_t read(uint32_t addr); - template<bool log = false> + template<bool log = false, bool enabled = true> void write(uint32_t addr, const uint32_t data); private: bool update_io(bool is_update); + template<bool is_write> + auto get_io_func(bool log, bool enabled); machine *const m_machine; struct { diff --git a/src/hw/video/gpu/pmc.cpp b/src/hw/video/gpu/pmc.cpp index 6475166..8cd467b 100644 --- a/src/hw/video/gpu/pmc.cpp +++ b/src/hw/video/gpu/pmc.cpp @@ -32,10 +32,6 @@ #define NV_PMC_INTR_EN_0_INTA_DISABLED 0x00000000 #define NV_PMC_INTR_EN_0_INTA_HARDWARE 0x00000001 #define NV_PMC_INTR_EN_0_INTA_SOFTWARE 0x00000002 -#define NV_PMC_ENABLE (NV2A_REGISTER_BASE + 0x00000200) -#define NV_PMC_ENABLE_PTIMER (1 << 16) -#define NV_PMC_ENABLE_PFB (1 << 20) -#define NV_PMC_ENABLE_PCRTC (1 << 24) template<bool log> @@ -76,7 +72,11 @@ void pmc::write(uint32_t addr, const uint32_t data) case NV_PMC_ENABLE: { bool has_int_state_changed = false; + uint32_t old_state = engine_enabled; engine_enabled = data; + if ((data & NV_PMC_ENABLE_PFIFO) == 0) { + m_machine->get<pfifo>().reset(); + } if ((data & NV_PMC_ENABLE_PTIMER) == 0) { m_machine->get<ptimer>().reset(); has_int_state_changed = true; @@ -88,6 +88,17 @@ void pmc::write(uint32_t addr, const uint32_t data) m_machine->get<pcrtc>().reset(); has_int_state_changed = true; } + if ((data & NV_PMC_ENABLE_PVIDEO) == 0) { + m_machine->get<pvideo>().reset(); + } + if ((old_state ^ engine_enabled) & NV_PMC_ENABLE_MASK) { + m_machine->get<pfifo>().update_io(); + m_machine->get<ptimer>().update_io(); + m_machine->get<pfb>().update_io(); + m_machine->get<pcrtc>().update_io(); + m_machine->get<pvideo>().update_io(); + mem_init_region_io(m_machine->get<cpu_t *>(), 0, 0, true, {}, m_machine->get<cpu_t *>(), true, 3); // trigger the update in lib86cpu too + } if (has_int_state_changed) { update_irq(); } @@ -205,10 +216,11 @@ pmc::update_io(bool is_update) void pmc::reset() { + // Values dumped from a Retail 1.0 xbox endianness = NV_PMC_BOOT_1_ENDIAN0_LITTLE_MASK | NV_PMC_BOOT_1_ENDIAN24_LITTLE_MASK; int_status = NV_PMC_INTR_0_NOT_PENDING; int_enabled = NV_PMC_INTR_EN_0_INTA_DISABLED; - engine_enabled = 0; + engine_enabled = NV_PMC_ENABLE_PTIMER | NV_PMC_ENABLE_PFB | NV_PMC_ENABLE_PCRTC; } bool diff --git a/src/hw/video/gpu/pmc.hpp b/src/hw/video/gpu/pmc.hpp index 85efb73..44c648f 100644 --- a/src/hw/video/gpu/pmc.hpp +++ b/src/hw/video/gpu/pmc.hpp @@ -6,15 +6,28 @@ #include <cstdint> +#define NV_PMC_ENABLE (NV2A_REGISTER_BASE + 0x00000200) +#define NV_PMC_ENABLE_PFIFO (1 << 8) +#define NV_PMC_ENABLE_PTIMER (1 << 16) +#define NV_PMC_ENABLE_PFB (1 << 20) +#define NV_PMC_ENABLE_PCRTC (1 << 24) +#define NV_PMC_ENABLE_PVIDEO (1 << 28) +#define NV_PMC_ENABLE_MASK (NV_PMC_ENABLE_PFIFO | NV_PMC_ENABLE_PTIMER | NV_PMC_ENABLE_PFB | NV_PMC_ENABLE_PCRTC | NV_PMC_ENABLE_PVIDEO) + class machine; +class pfifo; +class ptimer; +class pfb; +class pcrtc; +class pvideo; class pmc { public: pmc(machine *machine) : m_machine(machine) {} bool init(); void reset(); - void update_io_logging() { update_io(true); } + void update_io() { update_io(true); } void update_irq(); template<bool log = false> uint32_t read(uint32_t addr); @@ -24,6 +37,11 @@ class pmc { private: bool update_io(bool is_update); + friend class pfifo; + friend class ptimer; + friend class pfb; + friend class pcrtc; + friend class pvideo; machine *const m_machine; struct { uint32_t endianness; diff --git a/src/hw/video/gpu/pramdac.hpp b/src/hw/video/gpu/pramdac.hpp index abe2dd9..86f3c67 100644 --- a/src/hw/video/gpu/pramdac.hpp +++ b/src/hw/video/gpu/pramdac.hpp @@ -15,7 +15,7 @@ class pramdac { pramdac(machine *machine) : m_machine(machine) {} bool init(); void reset(); - void update_io_logging() { update_io(true); } + void update_io() { update_io(true); } template<bool log = false> uint8_t read8(uint32_t addr); template<bool log = false> diff --git a/src/hw/video/gpu/pramin.hpp b/src/hw/video/gpu/pramin.hpp index 524254b..da5da16 100644 --- a/src/hw/video/gpu/pramin.hpp +++ b/src/hw/video/gpu/pramin.hpp @@ -13,7 +13,7 @@ class pramin { public: pramin(machine *machine) : m_machine(machine) {} bool init(); - void update_io_logging() { update_io(true); } + void update_io() { update_io(true); } template<bool log = false> uint8_t read8(uint32_t addr); template<bool log = false> diff --git a/src/hw/video/gpu/ptimer.cpp b/src/hw/video/gpu/ptimer.cpp index 68c4e16..3019c23 100644 --- a/src/hw/video/gpu/ptimer.cpp +++ b/src/hw/video/gpu/ptimer.cpp @@ -62,9 +62,12 @@ ptimer::get_next_alarm_time(uint64_t now) return std::numeric_limits<uint64_t>::max(); } -template<bool log> +template<bool log, bool enabled> void ptimer::write(uint32_t addr, const uint32_t data) { + if constexpr (!enabled) { + return; + } if constexpr (log) { log_io_write(); } @@ -145,9 +148,13 @@ void ptimer::write(uint32_t addr, const uint32_t data) } } -template<bool log> +template<bool log, bool enabled> uint32_t ptimer::read(uint32_t addr) { + if constexpr (!enabled) { + return 0; + } + uint32_t value = 0; switch (addr) @@ -197,14 +204,46 @@ uint32_t ptimer::read(uint32_t addr) return value; } +template<bool is_write> +auto ptimer::get_io_func(bool log, bool enabled) +{ + if constexpr (is_write) { + if (enabled) { + if (log) { + return cpu_write<ptimer, uint32_t, &ptimer::write<true>>; + } + else { + return cpu_write<ptimer, uint32_t, &ptimer::write<false>>; + } + } + else { + return cpu_write<ptimer, uint32_t, &ptimer::write<false, false>>; + } + } + else { + if (enabled) { + if (log) { + return cpu_read<ptimer, uint32_t, &ptimer::read<true>>; + } + else { + return cpu_read<ptimer, uint32_t, &ptimer::read<false>>; + } + } + else { + return cpu_read<ptimer, uint32_t, &ptimer::read<false, false>>; + } + } +} + bool ptimer::update_io(bool is_update) { bool log = module_enabled(); + bool enabled = m_machine->get<pmc>().engine_enabled & NV_PMC_ENABLE_PTIMER; if (!LC86_SUCCESS(mem_init_region_io(m_machine->get<cpu_t *>(), NV_PTIMER_BASE, NV_PTIMER_SIZE, false, { - .fnr32 = log ? cpu_read<ptimer, uint32_t, &ptimer::read<true>> : cpu_read<ptimer, uint32_t, &ptimer::read<false>>, - .fnw32 = log ? cpu_write<ptimer, uint32_t, &ptimer::write<true>> : cpu_write<ptimer, uint32_t, &ptimer::write<false>> + .fnr32 = get_io_func<false>(log, enabled), + .fnw32 = get_io_func<true>(log, enabled) }, this, is_update, is_update))) { logger_en(error, "Failed to update mmio region"); @@ -223,10 +262,11 @@ ptimer::reset() multiplier = 0x00001DCD; divider = 0x0000DE86; alarm = 0xFFFFFFE0; - counter_period = 0; + counter_period = counter_to_us(); counter_active = COUNTER_ON; counter_offset = 0; counter_bias = 0; + cpu_set_timeout(m_machine->get<cpu_t *>(), m_machine->get<cpu>().check_periodic_events(timer::get_now())); } bool diff --git a/src/hw/video/gpu/ptimer.hpp b/src/hw/video/gpu/ptimer.hpp index ab3c36e..de4719b 100644 --- a/src/hw/video/gpu/ptimer.hpp +++ b/src/hw/video/gpu/ptimer.hpp @@ -16,20 +16,21 @@ class ptimer { ptimer(machine *machine) : m_machine(machine) {} bool init(); void reset(); - void update_io_logging() { update_io(true); } + void update_io() { update_io(true); } uint64_t get_next_alarm_time(uint64_t now); - template<bool log = false> + template<bool log = false, bool enabled = true> uint32_t read(uint32_t addr); - template<bool log = false> + template<bool log = false, bool enabled = true> void write(uint32_t addr, const uint32_t data); private: bool update_io(bool is_update); + template<bool is_write> + auto get_io_func(bool log, bool enabled); + uint64_t counter_to_us(); friend class pmc; friend class pramdac; - uint64_t counter_to_us(); - machine *const m_machine; // Host time when the last alarm interrupt was triggered uint64_t last_alarm_time; diff --git a/src/hw/video/gpu/pvga.hpp b/src/hw/video/gpu/pvga.hpp index 2041acc..ccd4462 100644 --- a/src/hw/video/gpu/pvga.hpp +++ b/src/hw/video/gpu/pvga.hpp @@ -14,7 +14,7 @@ class pvga { pvga(machine *machine) : m_machine(machine) {} bool init(); void reset(); - void update_io_logging() { update_io(true); } + void update_io() { update_io(true); } template<bool log = false> uint8_t io_read8(uint32_t addr); template<bool log = false> diff --git a/src/hw/video/gpu/pvideo.cpp b/src/hw/video/gpu/pvideo.cpp index da10bd5..6bfd674 100644 --- a/src/hw/video/gpu/pvideo.cpp +++ b/src/hw/video/gpu/pvideo.cpp @@ -23,9 +23,12 @@ #define NV_PVIDEO_DEBUG_10 (NV2A_REGISTER_BASE + 0x000080A8) -template<bool log> +template<bool log, bool enabled> void pvideo::write(uint32_t addr, const uint32_t data) { + if constexpr (!enabled) { + return; + } if constexpr (log) { log_io_write(); } @@ -51,9 +54,13 @@ void pvideo::write(uint32_t addr, const uint32_t data) } } -template<bool log> +template<bool log, bool enabled> uint32_t pvideo::read(uint32_t addr) { + if constexpr (!enabled) { + return 0; + } + uint32_t value = 0; switch (addr) @@ -83,14 +90,46 @@ uint32_t pvideo::read(uint32_t addr) return value; } +template<bool is_write> +auto pvideo::get_io_func(bool log, bool enabled) +{ + if constexpr (is_write) { + if (enabled) { + if (log) { + return cpu_write<pvideo, uint32_t, &pvideo::write<true>>; + } + else { + return cpu_write<pvideo, uint32_t, &pvideo::write<false>>; + } + } + else { + return cpu_write<pvideo, uint32_t, &pvideo::write<false, false>>; + } + } + else { + if (enabled) { + if (log) { + return cpu_read<pvideo, uint32_t, &pvideo::read<true>>; + } + else { + return cpu_read<pvideo, uint32_t, &pvideo::read<false>>; + } + } + else { + return cpu_read<pvideo, uint32_t, &pvideo::read<false, false>>; + } + } +} + bool pvideo::update_io(bool is_update) { bool log = module_enabled(); + bool enabled = m_machine->get<pmc>().engine_enabled & NV_PMC_ENABLE_PVIDEO; if (!LC86_SUCCESS(mem_init_region_io(m_machine->get<cpu_t *>(), NV_PVIDEO_BASE, NV_PVIDEO_SIZE, false, { - .fnr32 = log ? cpu_read<pvideo, uint32_t, &pvideo::read<true>> : cpu_read<pvideo, uint32_t, &pvideo::read<false>>, - .fnw32 = log ? cpu_write<pvideo, uint32_t, &pvideo::write<true>> : cpu_write<pvideo, uint32_t, &pvideo::write<false>> + .fnr32 = get_io_func<false>(log, enabled), + .fnw32 = get_io_func<true>(log, enabled) }, this, is_update, is_update))) { logger_en(error, "Failed to update mmio region"); diff --git a/src/hw/video/gpu/pvideo.hpp b/src/hw/video/gpu/pvideo.hpp index d544695..226b2f2 100644 --- a/src/hw/video/gpu/pvideo.hpp +++ b/src/hw/video/gpu/pvideo.hpp @@ -14,14 +14,16 @@ class pvideo { pvideo(machine *machine) : m_machine(machine) {} bool init(); void reset(); - void update_io_logging() { update_io(true); } - template<bool log = false> + void update_io() { update_io(true); } + template<bool log = false, bool enabled = true> uint32_t read(uint32_t addr); - template<bool log = false> + template<bool log = false, bool enabled = true> void write(uint32_t addr, const uint32_t data); private: bool update_io(bool is_update); + template<bool is_write> + auto get_io_func(bool log, bool enabled); machine *const m_machine; struct {