summaryrefslogtreecommitdiffstatshomepage
path: root/src/devices/sound/sn76496.cpp (follow)
Commit message (Expand)AuthorAgeFilesLines
* added device_clock_changed (nw) smf-2018-07-281-0/+5
* as if millions of this pointers suddenly cried out in terror, and were sudden... Vas Crabb2018-06-081-5/+0
* Move static data out of devices into the device types. This is a significant... Vas Crabb2017-05-141-44/+72
* Self-registering devices prep: Vas Crabb2017-02-271-10/+10
* NOTICE (TYPE NAME CONSOLIDATION) Miodrag Milanovic2016-10-221-14/+14
* reverting: Miodrag Milanovic2016-01-201-11/+11
* Revert "rest of device parameters to std::string (nw)" Miodrag Milanovic2016-01-201-1/+1
* Revert "some additional (nw)" Miodrag Milanovic2016-01-201-1/+1
* some additional (nw) Miodrag Milanovic2016-01-161-1/+1
* rest of device parameters to std::string (nw) Miodrag Milanovic2016-01-161-1/+1
* tags are now strings (nw) Miodrag Milanovic2016-01-161-11/+11
* cleanup (nw) Miodrag Milanovic2015-12-261-1/+1
* clang-modernize part 3 Miodrag Milanovic2015-12-041-1/+1
* Rename *.c -> *.cpp in our source (nw) Miodrag Milanovic2015-11-081-0/+446
to compute the final one. If you recieve a XTAL object and want to turn it to a final frequency, use value() to get an integer or dvalue() to get a double. If you recieve a XTAL object and want to check if the initial crystal value is sane, use check(context message). It will fatalerror if the value is not in the authorized value list. It has a (small) cost, so don't do it in a hot path. Remember that with PLLs it is perfectly normal to multiply frequencies by a rational. For instance the 315-5746 in the Sega Saturn generates two dotclocks at 57.27MHz and 53.69MHz as needed from a single 13.32MHz crystal. Banks of oscillators connected to a chip usually don't exist. So if you're doing a switch to select a frequency between multiple XTAL() ones, you're probably doing it wrong. If you're selecting multipliers on a single crystal otoh, that's perfectly normal. I'm looking at you, VGA pixel clock generators. ***************************************************************************/ #ifndef MAME_EMU_XTAL_H #define MAME_EMU_XTAL_H #include "emucore.h" #pragma once class XTAL { public: constexpr explicit XTAL(double base_clock) : m_base_clock(base_clock), m_current_clock(base_clock) {} constexpr double dvalue() const noexcept { return m_current_clock; } constexpr u32 value() const noexcept { return u32(m_current_clock + 1e-3); } constexpr double base() const noexcept { return m_base_clock; } template <typename T> constexpr XTAL operator *(T &&mult) const noexcept { return XTAL(m_base_clock, m_current_clock * mult); } template <typename T> constexpr XTAL operator /(T &&div) const noexcept { return XTAL(m_base_clock, m_current_clock / div); } friend constexpr XTAL operator *(int mult, const XTAL &xtal); friend constexpr XTAL operator *(unsigned int mult, const XTAL &xtal); friend constexpr XTAL operator *(double mult, const XTAL &xtal); void validate(const char *message) const; void validate(const std::string &message) const; private: double m_base_clock, m_current_clock; constexpr XTAL(double base_clock, double current_clock) noexcept : m_base_clock(base_clock), m_current_clock(current_clock) {} static const double known_xtals[]; static double last_correct_value, xtal_error_low, xtal_error_high; static void fail(double base_clock, const std::string &message); static bool validate(double base_clock); static void check_ordering(); }; template <typename T> constexpr auto operator /(T &&div, const XTAL &xtal) { return div / xtal.dvalue(); } constexpr XTAL operator *(int mult, const XTAL &xtal) { return XTAL(xtal.base(), mult * xtal.dvalue()); } constexpr XTAL operator *(unsigned int mult, const XTAL &xtal) { return XTAL(xtal.base(), mult * xtal.dvalue()); } constexpr XTAL operator *(double mult, const XTAL &xtal) { return XTAL(xtal.base(), mult * xtal.dvalue()); } constexpr XTAL operator ""_Hz_XTAL(long double clock) { return XTAL(double(clock)); } constexpr XTAL operator ""_kHz_XTAL(long double clock) { return XTAL(double(clock * 1e3)); } constexpr XTAL operator ""_MHz_XTAL(long double clock) { return XTAL(double(clock * 1e6)); } constexpr XTAL operator ""_Hz_XTAL(unsigned long long clock) { return XTAL(double(clock)); } constexpr XTAL operator ""_kHz_XTAL(unsigned long long clock) { return XTAL(double(clock) * 1e3); } constexpr XTAL operator ""_MHz_XTAL(unsigned long long clock) { return XTAL(double(clock) * 1e6); } #endif // MAME_EMU_XTAL_H