summaryrefslogtreecommitdiffstatshomepage
path: root/src/emu
diff options
context:
space:
mode:
Diffstat (limited to 'src/emu')
-rw-r--r--src/emu/devcpu.cpp2
-rw-r--r--src/emu/devcpu.h2
-rw-r--r--src/emu/device.cpp18
-rw-r--r--src/emu/device.h36
-rw-r--r--src/emu/device.ipp2
-rw-r--r--src/emu/diexec.cpp10
-rw-r--r--src/emu/diserial.h9
-rw-r--r--src/emu/dislot.h11
-rw-r--r--src/emu/disound.cpp4
-rw-r--r--src/emu/disound.h4
-rw-r--r--src/emu/drawgfx.cpp2
-rw-r--r--src/emu/drawgfx.h4
-rw-r--r--src/emu/driver.cpp2
-rw-r--r--src/emu/drivers/testcpu.cpp2
-rw-r--r--src/emu/emupal.cpp4
-rw-r--r--src/emu/emupal.h6
-rw-r--r--src/emu/machine.h2
-rw-r--r--src/emu/mconfig.cpp8
-rw-r--r--src/emu/mconfig.h20
-rw-r--r--src/emu/recording.cpp4
-rw-r--r--src/emu/save.h37
-rw-r--r--src/emu/screen.cpp2
-rw-r--r--src/emu/screen.h14
-rw-r--r--src/emu/softlist_dev.cpp2
-rw-r--r--src/emu/softlist_dev.h2
-rw-r--r--src/emu/sound.cpp76
-rw-r--r--src/emu/sound.h62
-rw-r--r--src/emu/speaker.cpp4
-rw-r--r--src/emu/speaker.h4
-rw-r--r--src/emu/tilemap.cpp2
-rw-r--r--src/emu/tilemap.h8
-rw-r--r--src/emu/validity.cpp6
-rw-r--r--src/emu/xtal.cpp6
-rw-r--r--src/emu/xtal.h41
34 files changed, 234 insertions, 184 deletions
diff --git a/src/emu/devcpu.cpp b/src/emu/devcpu.cpp
index 03df7990a3d..67968a69efa 100644
--- a/src/emu/devcpu.cpp
+++ b/src/emu/devcpu.cpp
@@ -21,7 +21,7 @@
// cpu_device - constructor
//-------------------------------------------------
-cpu_device::cpu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock)
+cpu_device::cpu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, const XTAL &clock)
: device_t(mconfig, type, tag, owner, clock),
device_execute_interface(mconfig, *this),
device_memory_interface(mconfig, *this),
diff --git a/src/emu/devcpu.h b/src/emu/devcpu.h
index 6e9251ab3a9..222a941a325 100644
--- a/src/emu/devcpu.h
+++ b/src/emu/devcpu.h
@@ -38,7 +38,7 @@ public:
protected:
// construction/destruction
- cpu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock);
+ cpu_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, const XTAL &clock);
private:
// configured state
diff --git a/src/emu/device.cpp b/src/emu/device.cpp
index 425ce52d461..f0ecdc1053d 100644
--- a/src/emu/device.cpp
+++ b/src/emu/device.cpp
@@ -82,16 +82,16 @@ emu::detail::device_registrar const registered_device_types;
// from the provided config
//-------------------------------------------------
-device_t::device_t(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, u32 clock)
+device_t::device_t(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, const XTAL &clock)
: m_type(type)
, m_owner(owner)
, m_next(nullptr)
- , m_configured_clock(clock)
- , m_unscaled_clock(clock)
- , m_clock(clock)
+ , m_configured_clock(clock.dvalue())
+ , m_unscaled_clock(clock.dvalue())
+ , m_clock(clock.dvalue())
, m_clock_scale(1.0)
- , m_attoseconds_per_clock((clock == 0) ? 0 : HZ_TO_ATTOSECONDS(clock))
+ , m_attoseconds_per_clock(clock.disabled() ? 0 : HZ_TO_ATTOSECONDS(clock))
, m_machine_config(mconfig)
, m_input_defaults(nullptr)
@@ -234,7 +234,7 @@ void device_t::add_machine_configuration(machine_config &config)
// a device
//-------------------------------------------------
-void device_t::set_clock(u32 clock)
+void device_t::internal_set_clock(u32 clock)
{
m_configured_clock = clock;
@@ -242,7 +242,7 @@ void device_t::set_clock(u32 clock)
if ((clock & 0xff000000) == 0xff000000)
calculate_derived_clock();
else
- set_unscaled_clock(clock);
+ internal_set_unscaled_clock(clock);
}
@@ -365,7 +365,7 @@ void device_t::reset()
// unscaled clock
//-------------------------------------------------
-void device_t::set_unscaled_clock(u32 clock, bool sync_on_new_clock_domain)
+void device_t::internal_set_unscaled_clock(u32 clock, bool sync_on_new_clock_domain)
{
// do nothing if no actual change
if (clock == m_unscaled_clock)
@@ -420,7 +420,7 @@ void device_t::calculate_derived_clock()
if ((m_configured_clock & 0xff000000) == 0xff000000)
{
assert(m_owner != nullptr);
- set_unscaled_clock(m_owner->m_clock * ((m_configured_clock >> 12) & 0xfff) / ((m_configured_clock >> 0) & 0xfff));
+ internal_set_unscaled_clock(m_owner->m_clock * ((m_configured_clock >> 12) & 0xfff) / ((m_configured_clock >> 0) & 0xfff));
}
}
diff --git a/src/emu/device.h b/src/emu/device.h
index 402bbb1ccff..4392ede1a7c 100644
--- a/src/emu/device.h
+++ b/src/emu/device.h
@@ -32,7 +32,7 @@
//**************************************************************************
// macro for specifying a clock derived from an owning device
-#define DERIVED_CLOCK(num, den) (0xff000000 | ((num) << 12) | ((den) << 0))
+#define DERIVED_CLOCK(num, den) XTAL::u((0xff000000 | ((num) << 12) | ((den) << 0)))
@@ -191,7 +191,7 @@ class device_type_impl_base
private:
friend class device_registrar;
- typedef std::unique_ptr<device_t> (*create_func)(device_type_impl_base const &type, machine_config const &mconfig, char const *tag, device_t *owner, u32 clock);
+ typedef std::unique_ptr<device_t> (*create_func)(device_type_impl_base const &type, machine_config const &mconfig, char const *tag, device_t *owner, const XTAL &clock);
device_type_impl_base(device_type_impl_base const &) = delete;
device_type_impl_base(device_type_impl_base &&) = delete;
@@ -199,16 +199,15 @@ private:
device_type_impl_base &operator=(device_type_impl_base &&) = delete;
template <typename DeviceClass>
- static std::unique_ptr<device_t> create_device(device_type_impl_base const &type, machine_config const &mconfig, char const *tag, device_t *owner, u32 clock)
+ static std::unique_ptr<device_t> create_device(device_type_impl_base const &type, machine_config const &mconfig, char const *tag, device_t *owner, const XTAL &clock)
{
return std::make_unique<DeviceClass>(mconfig, tag, owner, clock);
}
template <typename DriverClass>
- static std::unique_ptr<device_t> create_driver(device_type_impl_base const &type, machine_config const &mconfig, char const *tag, device_t *owner, u32 clock)
+ static std::unique_ptr<device_t> create_driver(device_type_impl_base const &type, machine_config const &mconfig, char const *tag, device_t *owner, const XTAL &clock)
{
assert(!owner);
- assert(!clock);
return std::make_unique<DriverClass>(mconfig, type, tag);
}
@@ -276,7 +275,7 @@ public:
device_feature::type imperfect_features() const { return m_imperfect_features; }
device_type_impl_base const *parent_rom_device_type() const { return m_parent_rom; }
- std::unique_ptr<device_t> create(machine_config const &mconfig, char const *tag, device_t *owner, u32 clock) const
+ std::unique_ptr<device_t> create(machine_config const &mconfig, char const *tag, device_t *owner, const XTAL &clock) const
{
return m_creator(*this, mconfig, tag, owner, clock);
}
@@ -575,7 +574,7 @@ protected:
device_type type,
const char *tag,
device_t *owner,
- u32 clock);
+ const XTAL &clock = XTAL());
public:
// device flags
@@ -634,7 +633,7 @@ public:
const char *source() const { return m_type.source(); }
device_t *owner() const { return m_owner; }
device_t *next() const { return m_next; }
- u32 configured_clock() const { return m_configured_clock; }
+ XTAL configured_clock() const { return XTAL::u(m_configured_clock); }
const machine_config &mconfig() const { return m_machine_config; }
const input_device_default *input_ports_defaults() const { return m_input_defaults; }
const std::vector<rom_entry> &rom_region_vector() const;
@@ -677,8 +676,11 @@ public:
// configuration helpers
void add_machine_configuration(machine_config &config);
- void set_clock(u32 clock);
- void set_clock(const XTAL &xtal) { set_clock(xtal.value()); }
+
+private:
+ void internal_set_clock(u32 clock);
+public:
+ void set_clock(const XTAL &xtal) { internal_set_clock(xtal.value()); }
void set_input_default(const input_device_default *config) { m_input_defaults = config; }
template <typename... Params> void set_default_bios_tag(Params &&... args) { assert(!configured()); m_default_bios_tag.assign(std::forward<Params>(args)...); }
@@ -690,12 +692,14 @@ public:
void reset();
// clock/timing accessors
- u32 clock() const { return m_clock; }
- u32 unscaled_clock() const { return m_unscaled_clock; }
- void set_unscaled_clock(u32 clock, bool sync_on_new_clock_domain = false);
- void set_unscaled_clock(const XTAL &xtal, bool sync_on_new_clock_domain = false) { set_unscaled_clock(xtal.value(), sync_on_new_clock_domain); }
- void set_unscaled_clock_int(u32 clock) { set_unscaled_clock(clock, false); } // non-overloaded name because binding to overloads is ugly
- void set_unscaled_clock_int_sync(u32 clock) { set_unscaled_clock(clock, true); } // non-overloaded name because binding to overloads is ugly
+ XTAL clock() const { return XTAL::u(m_clock); }
+ XTAL unscaled_clock() const { return XTAL::u(m_unscaled_clock); }
+private:
+ void internal_set_unscaled_clock(u32 clock, bool sync_on_new_clock_domain = false);
+public:
+ void set_unscaled_clock(const XTAL &xtal, bool sync_on_new_clock_domain = false) { internal_set_unscaled_clock(xtal.value(), sync_on_new_clock_domain); }
+ void set_unscaled_clock_ns(const XTAL &clock) { set_unscaled_clock(clock, false); } // non-overloaded name because binding to overloads is ugly
+ void set_unscaled_clock_s(const XTAL &clock) { set_unscaled_clock(clock, true); } // non-overloaded name because binding to overloads is ugly
double clock_scale() const { return m_clock_scale; }
void set_clock_scale(double clockscale);
attotime clocks_to_attotime(u64 clocks) const noexcept;
diff --git a/src/emu/device.ipp b/src/emu/device.ipp
index c7b2d43346b..b886bb47205 100644
--- a/src/emu/device.ipp
+++ b/src/emu/device.ipp
@@ -21,7 +21,7 @@
// TYPE DEFINITIONS
//**************************************************************************
-typedef device_delegate<void (u32)> clock_update_delegate;
+typedef device_delegate<void (const XTAL &)> clock_update_delegate;
//**************************************************************************
diff --git a/src/emu/diexec.cpp b/src/emu/diexec.cpp
index b1f885e2b9d..eab91b55f89 100644
--- a/src/emu/diexec.cpp
+++ b/src/emu/diexec.cpp
@@ -442,7 +442,7 @@ void device_execute_interface::interface_pre_reset()
// enable all devices (except for disabled and unclocked devices)
if (disabled())
suspend(SUSPEND_REASON_DISABLE, true);
- else if (device().clock() != 0)
+ else if (!device().clock().disabled())
resume(SUSPEND_ANY_REASON);
}
@@ -486,7 +486,7 @@ void device_execute_interface::interface_post_reset()
void device_execute_interface::interface_clock_changed(bool sync_on_new_clock_domain)
{
// a clock of zero disables the device
- if (device().clock() == 0)
+ if (device().clock().disabled())
{
suspend(SUSPEND_REASON_CLOCK, true);
return;
@@ -497,7 +497,7 @@ void device_execute_interface::interface_clock_changed(bool sync_on_new_clock_do
resume(SUSPEND_REASON_CLOCK);
// recompute cps and spc
- m_cycles_per_second = clocks_to_cycles(device().clock());
+ m_cycles_per_second = clocks_to_cycles(device().clock().value());
m_attoseconds_per_cycle = HZ_TO_ATTOSECONDS(m_cycles_per_second);
// resynchronize the localtime to the clock domain when asked to
@@ -557,13 +557,13 @@ int device_execute_interface::standard_irq_callback(int irqline)
attoseconds_t device_execute_interface::minimum_quantum() const
{
// if we don't have a clock, return a huge factor
- if (device().clock() == 0)
+ if (device().clock().disabled())
return ATTOSECONDS_PER_SECOND - 1;
// if we don't have the quantum time, compute it
attoseconds_t basetick = m_attoseconds_per_cycle;
if (basetick == 0)
- basetick = HZ_TO_ATTOSECONDS(clocks_to_cycles(device().clock()));
+ basetick = HZ_TO_ATTOSECONDS(clocks_to_cycles(device().clock().value()));
// apply the minimum cycle count
return basetick * min_cycles();
diff --git a/src/emu/diserial.h b/src/emu/diserial.h
index 62b13c028a1..3c6e42456c6 100644
--- a/src/emu/diserial.h
+++ b/src/emu/diserial.h
@@ -90,13 +90,10 @@ protected:
void set_rcv_rate(const attotime &rate);
void set_tra_rate(const attotime &rate);
- void set_rcv_rate(u32 clock, int div) { set_rcv_rate((clock && div) ? (attotime::from_hz(clock) * div) : attotime::never); }
- void set_tra_rate(u32 clock, int div) { set_tra_rate((clock && div) ? (attotime::from_hz(clock) * div) : attotime::never); }
- void set_rcv_rate(int baud) { set_rcv_rate(baud ? attotime::from_hz(baud) : attotime::never); }
- void set_tra_rate(int baud) { set_tra_rate(baud ? attotime::from_hz(baud) : attotime::never); }
+ void set_rcv_rate(const XTAL &clock) { set_rcv_rate(clock.disabled() ? attotime::never : attotime::from_seconds(1/clock.dvalue())); }
+ void set_tra_rate(const XTAL &clock) { set_tra_rate(clock.disabled() ? attotime::never : attotime::from_seconds(1/clock.dvalue())); }
void set_rate(const attotime &rate) { set_rcv_rate(rate); set_tra_rate(rate); }
- void set_rate(u32 clock, int div) { set_rcv_rate(clock, div); set_tra_rate(clock, div); }
- void set_rate(int baud) { set_rcv_rate(baud); set_tra_rate(baud); }
+ void set_rate(const XTAL &clock) { set_rcv_rate(clock); set_tra_rate(clock); }
void transmit_register_reset();
void transmit_register_add_bit(int bit);
diff --git a/src/emu/dislot.h b/src/emu/dislot.h
index dd2fde5fac1..b337e5b4e3a 100644
--- a/src/emu/dislot.h
+++ b/src/emu/dislot.h
@@ -54,13 +54,12 @@ public:
char const *default_bios() const { return m_default_bios; }
std::function<void (device_t *)> const &machine_config() const { return m_machine_config; }
input_device_default const *input_device_defaults() const { return m_input_device_defaults; }
- u32 clock() const { return m_clock; }
+ XTAL clock() const { return m_clock; }
slot_option &default_bios(char const *default_bios) { m_default_bios = default_bios; return *this; }
template <typename Object> slot_option &machine_config(Object &&cb) { m_machine_config = std::forward<Object>(cb); return *this; }
slot_option &input_device_defaults(input_device_default const *dev_inp_def) { m_input_device_defaults = dev_inp_def; return *this; }
- slot_option &clock(u32 clock) { m_clock = clock; return *this; }
- slot_option &clock(XTAL clock) { clock.validate(std::string("Configuring slot option ") + m_name); m_clock = clock.value(); return *this; }
+ slot_option &clock(const XTAL &clock) { clock.validate(std::string("Configuring slot option ") + m_name); m_clock = clock; return *this; }
private:
// internal state
@@ -70,7 +69,7 @@ public:
char const *m_default_bios;
std::function<void (device_t *)> m_machine_config;
input_device_default const *m_input_device_defaults;
- u32 m_clock;
+ XTAL m_clock;
};
virtual ~device_slot_interface();
@@ -171,12 +170,12 @@ public:
protected:
device_slot_interface(machine_config const &mconfig, device_t &device);
virtual void interface_validity_check(validity_checker &valid) const override ATTR_COLD;
- void set_default_clock(u32 clock) { m_default_clock = clock; }
+ void set_default_clock(const XTAL &clock) { m_default_clock = clock; }
private:
// internal state
std::unordered_map<std::string, std::unique_ptr<slot_option>> m_options;
- u32 m_default_clock;
+ XTAL m_default_clock;
char const *m_default_option;
bool m_fixed;
device_t *m_card_device;
diff --git a/src/emu/disound.cpp b/src/emu/disound.cpp
index 83d2c2bf084..0a57a9d4bd7 100644
--- a/src/emu/disound.cpp
+++ b/src/emu/disound.cpp
@@ -71,12 +71,12 @@ device_sound_interface &device_sound_interface::add_route(u32 output, device_t &
// associated with this device
//-------------------------------------------------
-sound_stream *device_sound_interface::stream_alloc(int inputs, int outputs, int sample_rate)
+sound_stream *device_sound_interface::stream_alloc(int inputs, int outputs, const XTAL &sample_rate)
{
return device().machine().sound().stream_alloc(*this, inputs, outputs, sample_rate, stream_update_delegate(&device_sound_interface::sound_stream_update, this), STREAM_DEFAULT_FLAGS);
}
-sound_stream *device_sound_interface::stream_alloc(int inputs, int outputs, int sample_rate, sound_stream_flags flags)
+sound_stream *device_sound_interface::stream_alloc(int inputs, int outputs, const XTAL &sample_rate, sound_stream_flags flags)
{
return device().machine().sound().stream_alloc(*this, inputs, outputs, sample_rate, stream_update_delegate(&device_sound_interface::sound_stream_update, this), flags);
}
diff --git a/src/emu/disound.h b/src/emu/disound.h
index e48ba290bc6..8ad9dbd8494 100644
--- a/src/emu/disound.h
+++ b/src/emu/disound.h
@@ -80,8 +80,8 @@ public:
virtual void sound_stream_update(sound_stream &stream, std::vector<read_stream_view> const &inputs, std::vector<write_stream_view> &outputs);
// stream creation
- sound_stream *stream_alloc(int inputs, int outputs, int sample_rate);
- sound_stream *stream_alloc(int inputs, int outputs, int sample_rate, sound_stream_flags flags);
+ sound_stream *stream_alloc(int inputs, int outputs, const XTAL &sample_rate);
+ sound_stream *stream_alloc(int inputs, int outputs, const XTAL &sample_rate, sound_stream_flags flags);
// helpers
int inputs() const;
diff --git a/src/emu/drawgfx.cpp b/src/emu/drawgfx.cpp
index 8a63d71467c..42b2b5db79e 100644
--- a/src/emu/drawgfx.cpp
+++ b/src/emu/drawgfx.cpp
@@ -58,7 +58,7 @@ static inline s32 normalize_yscroll(const bitmap_t &bitmap, s32 yscroll)
DEFINE_DEVICE_TYPE(GFXDECODE, gfxdecode_device, "gfxdecode", "gfxdecode")
-gfxdecode_device::gfxdecode_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) :
+gfxdecode_device::gfxdecode_device(const machine_config &mconfig, const char *tag, device_t *owner, const XTAL &clock) :
device_t(mconfig, GFXDECODE, tag, owner, clock),
device_gfx_interface(mconfig, *this)
{
diff --git a/src/emu/drawgfx.h b/src/emu/drawgfx.h
index 4b5be8a4fa3..f88d3f98c9b 100644
--- a/src/emu/drawgfx.h
+++ b/src/emu/drawgfx.h
@@ -539,12 +539,12 @@ public:
// construction/destruction
template <typename T>
gfxdecode_device(const machine_config &mconfig, const char *tag, device_t *owner, T &&palette_tag, const gfx_decode_entry *gfxinfo)
- : gfxdecode_device(mconfig, tag, owner, 0)
+ : gfxdecode_device(mconfig, tag, owner)
{
set_palette(std::forward<T>(palette_tag));
set_info(gfxinfo);
}
- gfxdecode_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 0);
+ gfxdecode_device(const machine_config &mconfig, const char *tag, device_t *owner, const XTAL &clock = XTAL());
protected:
virtual void device_start() override {}
diff --git a/src/emu/driver.cpp b/src/emu/driver.cpp
index 9b0dd9c5e59..09690110829 100644
--- a/src/emu/driver.cpp
+++ b/src/emu/driver.cpp
@@ -23,7 +23,7 @@
//-------------------------------------------------
driver_device::driver_device(const machine_config &mconfig, device_type type, const char *tag)
- : device_t(mconfig, type, tag, nullptr, 0)
+ : device_t(mconfig, type, tag, nullptr, XTAL())
, m_system(mconfig.gamedrv())
, m_flip_screen_x(0)
, m_flip_screen_y(0)
diff --git a/src/emu/drivers/testcpu.cpp b/src/emu/drivers/testcpu.cpp
index 95e3d5a1ec2..e7fa0cbbb13 100644
--- a/src/emu/drivers/testcpu.cpp
+++ b/src/emu/drivers/testcpu.cpp
@@ -193,7 +193,7 @@ void testcpu_state::ppc_mem(address_map &map)
void testcpu_state::testcpu(machine_config &config)
{
// CPUs
- PPC603E(config, m_cpu, 66000000);
+ PPC603E(config, m_cpu, XTAL::u(66000000));
m_cpu->set_bus_frequency(66000000); // Multiplier 1, Bus = 66MHz, Core = 66MHz
m_cpu->set_addrmap(AS_PROGRAM, &testcpu_state::ppc_mem);
}
diff --git a/src/emu/emupal.cpp b/src/emu/emupal.cpp
index 9e1370a24ed..f83d2150b61 100644
--- a/src/emu/emupal.cpp
+++ b/src/emu/emupal.cpp
@@ -19,7 +19,7 @@
DEFINE_DEVICE_TYPE(PALETTE, palette_device, "palette", "palette")
palette_device::palette_device(const machine_config &mconfig, const char *tag, device_t *owner, init_delegate &&init, u32 entries, u32 indirect)
- : palette_device(mconfig, tag, owner, 0U)
+ : palette_device(mconfig, tag, owner)
{
set_entries(entries, indirect);
m_init = std::move(init);
@@ -101,7 +101,7 @@ palette_device::palette_device(const machine_config &mconfig, const char *tag, d
}
-palette_device::palette_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
+palette_device::palette_device(const machine_config &mconfig, const char *tag, device_t *owner, const XTAL &clock)
: device_t(mconfig, PALETTE, tag, owner, clock)
, device_palette_interface(mconfig, *this)
, m_entries(0)
diff --git a/src/emu/emupal.h b/src/emu/emupal.h
index cb4884a72fb..60bab6efc6c 100644
--- a/src/emu/emupal.h
+++ b/src/emu/emupal.h
@@ -267,7 +267,7 @@ public:
palette_device(const machine_config &mconfig, const char *tag, device_t *owner, bgr_555_t);
palette_device(const machine_config &mconfig, const char *tag, device_t *owner, rgb_565_t);
palette_device(const machine_config &mconfig, const char *tag, device_t *owner, bgr_565_t);
- palette_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 0);
+ palette_device(const machine_config &mconfig, const char *tag, device_t *owner, const XTAL &clock = XTAL());
template <typename T>
palette_device(const machine_config &mconfig, const char *tag, device_t *owner, rgb_444_prom_t, T &&region, u32 entries)
@@ -278,11 +278,11 @@ public:
template <typename F>
palette_device(const machine_config &mconfig, const char *tag, device_t *owner, F &&init, std::enable_if_t<init_delegate::supports_callback<F>::value, const char *> name, u32 entries = 0U, u32 indirect = 0U)
- : palette_device(mconfig, tag, owner, 0U)
+ : palette_device(mconfig, tag, owner)
{ set_init(std::forward<F>(init), name).set_entries(entries, indirect); }
template <typename T, typename F>
palette_device(const machine_config &mconfig, const char *tag, device_t *owner, T &&devname, F &&init, std::enable_if_t<init_delegate::supports_callback<F>::value, const char *> name, u32 entries = 0U, u32 indirect = 0U)
- : palette_device(mconfig, tag, owner, 0U)
+ : palette_device(mconfig, tag, owner)
{ set_init(std::forward<T>(devname), std::forward<F>(init), name).set_entries(entries, indirect); }
// configuration
diff --git a/src/emu/machine.h b/src/emu/machine.h
index a49c5f1dbf9..cd99867ac95 100644
--- a/src/emu/machine.h
+++ b/src/emu/machine.h
@@ -147,7 +147,7 @@ public:
bool hard_reset_pending() const { return m_hard_reset_pending; }
bool ui_active() const { return m_ui_active; }
const std::string &basename() const { return m_basename; }
- int sample_rate() const { return m_sample_rate; }
+ XTAL sample_rate() const { return XTAL::u(m_sample_rate); }
bool save_or_load_pending() const { return !m_saveload_pending_file.empty(); }
// RAII-based side effect disable
diff --git a/src/emu/mconfig.cpp b/src/emu/mconfig.cpp
index 2c8c1aa011b..26debad4119 100644
--- a/src/emu/mconfig.cpp
+++ b/src/emu/mconfig.cpp
@@ -48,7 +48,7 @@ machine_config::machine_config(const game_driver &gamedrv, emu_options &options)
, m_perfect_quantum_device(nullptr, "")
{
// add the root device
- device_add("root", gamedrv.type, 0);
+ device_add("root", gamedrv.type, XTAL());
// intialize slot devices - make sure that any required devices have been allocated
for (device_slot_interface &slot : slot_interface_enumerator(root_device()))
@@ -195,8 +195,9 @@ void machine_config::set_maximum_quantum(attotime const &quantum)
// new device
//-------------------------------------------------
-device_t *machine_config::device_add(const char *tag, device_type type, u32 clock)
+device_t *machine_config::device_add(const char *tag, device_type type, const XTAL &clock)
{
+ clock.validate(std::string("Instanciating device ") + tag);
std::pair<const char *, device_t *> const owner(resolve_owner(tag));
return &add_device(type.create(*this, owner.first, owner.second, clock), owner.second);
}
@@ -207,8 +208,9 @@ device_t *machine_config::device_add(const char *tag, device_type type, u32 cloc
// replace one device with a new device
//-------------------------------------------------
-device_t *machine_config::device_replace(const char *tag, device_type type, u32 clock)
+device_t *machine_config::device_replace(const char *tag, device_type type, const XTAL &clock)
{
+ clock.validate(std::string("Replacing device ") + tag);
std::tuple<const char *, device_t *, device_t *> const existing(prepare_replace(tag));
std::unique_ptr<device_t> device(type.create(*this, std::get<0>(existing), std::get<1>(existing), clock));
return &replace_device(std::move(device), *std::get<1>(existing), std::get<2>(existing));
diff --git a/src/emu/mconfig.h b/src/emu/mconfig.h
index c6cacde581f..203c213f649 100644
--- a/src/emu/mconfig.h
+++ b/src/emu/mconfig.h
@@ -180,9 +180,9 @@ public:
m_current_device = &device;
return token(*this, device);
}
- device_t *device_add(const char *tag, device_type type, u32 clock);
+ device_t *device_add(const char *tag, device_type type, const XTAL &clock = XTAL());
template <typename Creator>
- device_t *device_add(const char *tag, Creator &&type, u32 clock)
+ device_t *device_add(const char *tag, Creator &&type, const XTAL &clock = XTAL())
{
return device_add(tag, device_type(type), clock);
}
@@ -196,15 +196,9 @@ public:
add_device(std::move(device), owner.second);
return &result;
}
- template <typename Creator, typename... Params>
- auto device_add(const char *tag, Creator &&type, XTAL clock, Params &&... args)
- {
- clock.validate(std::string("Instantiating device ") + tag);
- return device_add(tag, std::forward<Creator>(type), clock.value(), std::forward<Params>(args)...);
- }
- device_t *device_replace(const char *tag, device_type type, u32 clock);
+ device_t *device_replace(const char *tag, device_type type, const XTAL &clock = XTAL());
template <typename Creator>
- device_t *device_replace(const char *tag, Creator &&type, u32 clock)
+ device_t *device_replace(const char *tag, Creator &&type, const XTAL &clock = XTAL())
{
return device_replace(tag, device_type(type), clock);
}
@@ -218,12 +212,6 @@ public:
replace_device(std::move(device), *std::get<1>(existing), std::get<2>(existing));
return &result;
}
- template <typename Creator, typename... Params>
- auto device_replace(const char *tag, Creator &&type, XTAL clock, Params &&... args)
- {
- clock.validate(std::string("Replacing device ") + tag);
- return device_replace(tag, std::forward<Creator>(type), clock.value(), std::forward<Params>(args)...);
- }
device_t *device_remove(const char *tag);
private:
diff --git a/src/emu/recording.cpp b/src/emu/recording.cpp
index 611e5ae327b..2208d2fe7b2 100644
--- a/src/emu/recording.cpp
+++ b/src/emu/recording.cpp
@@ -186,12 +186,12 @@ bool avi_movie_recording::initialize(running_machine &machine, std::unique_ptr<e
info.video_depth = 24;
info.audio_format = 0;
- info.audio_timescale = machine.sample_rate();
+ info.audio_timescale = machine.sample_rate().value();
info.audio_sampletime = 1;
info.audio_numsamples = 0;
info.audio_channels = 2;
info.audio_samplebits = 16;
- info.audio_samplerate = machine.sample_rate();
+ info.audio_samplerate = machine.sample_rate().value();
// compute the frame time
set_frame_period(attotime::from_seconds(1000) / info.video_timescale);
diff --git a/src/emu/save.h b/src/emu/save.h
index 677f127853a..330533d07cd 100644
--- a/src/emu/save.h
+++ b/src/emu/save.h
@@ -285,6 +285,43 @@ public:
save_item(device, module, tag, index, value, &attotime::m_seconds, tempstr.c_str(), count);
}
+ // specializations for XTAL
+ template <typename ItemType>
+ std::enable_if_t<std::is_same<typename save_manager::array_unwrap<ItemType>::underlying_type, XTAL>::value> save_item(device_t *device, const char *module, const char *tag, int index, ItemType &value, const char *valname)
+ {
+ std::string tempstr;
+ tempstr.assign(valname).append(".base_clock");
+ save_item(device, module, tag, index, value, &XTAL::m_base_clock, tempstr.c_str());
+ tempstr.assign(valname).append(".current_clock");
+ save_item(device, module, tag, index, value, &XTAL::m_current_clock, tempstr.c_str());
+ tempstr.assign(valname).append(".disable_validation");
+ save_item(device, module, tag, index, value, &XTAL::m_disable_validation, tempstr.c_str());
+ }
+
+ template <typename ItemType>
+ std::enable_if_t<std::is_same<typename save_manager::array_unwrap<ItemType>::underlying_type, XTAL>::value> save_pointer(device_t *device, const char *module, const char *tag, int index, ItemType *value, const char *valname, u32 count)
+ {
+ std::string tempstr;
+ tempstr.assign(valname).append(".base_clock");
+ save_item(device, module, tag, index, value, &XTAL::m_base_clock, tempstr.c_str());
+ tempstr.assign(valname).append(".current_clock");
+ save_item(device, module, tag, index, value, &XTAL::m_current_clock, tempstr.c_str());
+ tempstr.assign(valname).append(".disable_validation");
+ save_item(device, module, tag, index, value, &XTAL::m_disable_validation, tempstr.c_str());
+ }
+
+ template <typename ItemType>
+ std::enable_if_t<std::is_same<typename save_manager::array_unwrap<ItemType>::underlying_type, XTAL>::value> save_pointer(device_t *device, const char *module, const char *tag, int index, const std::unique_ptr<ItemType []> &value, const char *valname, u32 count)
+ {
+ std::string tempstr;
+ tempstr.assign(valname).append(".base_clock");
+ save_item(device, module, tag, index, value, &XTAL::m_base_clock, tempstr.c_str());
+ tempstr.assign(valname).append(".current_clock");
+ save_item(device, module, tag, index, value, &XTAL::m_current_clock, tempstr.c_str());
+ tempstr.assign(valname).append(".disable_validation");
+ save_item(device, module, tag, index, value, &XTAL::m_disable_validation, tempstr.c_str());
+ }
+
// global memory registration
template <typename ItemType>
void save_item(ItemType &value, const char *valname, int index = 0)
diff --git a/src/emu/screen.cpp b/src/emu/screen.cpp
index f69a03ac13e..3932ffa7b94 100644
--- a/src/emu/screen.cpp
+++ b/src/emu/screen.cpp
@@ -526,7 +526,7 @@ void screen_device::svg_renderer::rebuild_cache()
// screen_device - constructor
//-------------------------------------------------
-screen_device::screen_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
+screen_device::screen_device(const machine_config &mconfig, const char *tag, device_t *owner, const XTAL &clock)
: device_t(mconfig, SCREEN, tag, owner, clock)
, m_type(SCREEN_TYPE_RASTER)
, m_orientation(ROT0)
diff --git a/src/emu/screen.h b/src/emu/screen.h
index 685d4c913a9..daafa2c822a 100644
--- a/src/emu/screen.h
+++ b/src/emu/screen.h
@@ -167,15 +167,15 @@ class screen_device : public device_t
public:
// construction/destruction
- screen_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock);
+ screen_device(const machine_config &mconfig, const char *tag, device_t *owner, const XTAL &clock);
screen_device(const machine_config &mconfig, const char *tag, device_t *owner, screen_type_enum type)
- : screen_device(mconfig, tag, owner, u32(0))
+ : screen_device(mconfig, tag, owner, XTAL())
{
set_type(type);
}
screen_device(const machine_config &mconfig, const char *tag, device_t *owner, screen_type_enum type, rgb_t color)
- : screen_device(mconfig, tag, owner, u32(0))
+ : screen_device(mconfig, tag, owner, XTAL())
{
set_type(type);
set_color(color);
@@ -222,10 +222,10 @@ public:
/// \param [in] vbstart Index of first line in vertical blanking
/// period after visible lines.
/// \return Reference to device for method chaining.
- screen_device &set_raw(u32 pixclock, u16 htotal, u16 hbend, u16 hbstart, u16 vtotal, u16 vbend, u16 vbstart)
+private:
+ screen_device &internal_set_raw(u32 pixclock, u16 htotal, u16 hbend, u16 hbstart, u16 vtotal, u16 vbend, u16 vbstart)
{
assert(pixclock != 0);
- set_clock(pixclock);
m_refresh = HZ_TO_ATTOSECONDS(pixclock) * htotal * vtotal;
m_vblank = m_refresh / vtotal * (vtotal - (vbstart - vbend));
m_width = htotal;
@@ -233,10 +233,12 @@ public:
m_visarea.set(hbend, hbstart ? hbstart - 1 : htotal - 1, vbend, vbstart - 1);
return *this;
}
+public:
screen_device &set_raw(const XTAL &xtal, u16 htotal, u16 hbend, u16 hbstart, u16 vtotal, u16 vbend, u16 vbstart)
{
xtal.validate(std::string("Configuring screen ") + tag());
- return set_raw(xtal.value(), htotal, hbend, hbstart, vtotal, vbend, vbstart);
+ set_clock(xtal);
+ return internal_set_raw(xtal.value(), htotal, hbend, hbstart, vtotal, vbend, vbstart);
}
screen_device &set_raw(const XTAL &xtal, u16 htotal, u16 vtotal, rectangle visarea)
{
diff --git a/src/emu/softlist_dev.cpp b/src/emu/softlist_dev.cpp
index 6db85f917cf..0098dd7d02d 100644
--- a/src/emu/softlist_dev.cpp
+++ b/src/emu/softlist_dev.cpp
@@ -85,7 +85,7 @@ bool image_software_list_loader::load_software(device_image_interface &image, so
// software_list_device - constructor
//-------------------------------------------------
-software_list_device::software_list_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock) :
+software_list_device::software_list_device(const machine_config &mconfig, const char *tag, device_t *owner, const XTAL &clock) :
device_t(mconfig, SOFTWARE_LIST, tag, owner, clock),
m_list_type(softlist_type::ORIGINAL_SYSTEM),
m_filter(nullptr),
diff --git a/src/emu/softlist_dev.h b/src/emu/softlist_dev.h
index 9e919dabe78..19275e379bc 100644
--- a/src/emu/softlist_dev.h
+++ b/src/emu/softlist_dev.h
@@ -99,7 +99,7 @@ public:
};
// construction/destruction
- software_list_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 0);
+ software_list_device(const machine_config &mconfig, const char *tag, device_t *owner, const XTAL &clock = XTAL());
// inline configuration helpers
software_list_device &set_type(const char *list, softlist_type list_type) { m_list_name.assign(list); m_list_type = list_type; return *this; }
diff --git a/src/emu/sound.cpp b/src/emu/sound.cpp
index 6862845e8da..b52111dc612 100644
--- a/src/emu/sound.cpp
+++ b/src/emu/sound.cpp
@@ -55,12 +55,12 @@ const attotime sound_manager::STREAMS_UPDATE_ATTOTIME = attotime::from_hz(STREAM
// stream_buffer - constructor
//-------------------------------------------------
-stream_buffer::stream_buffer(u32 sample_rate) :
+stream_buffer::stream_buffer(const XTAL &sample_rate) :
m_end_second(0),
m_end_sample(0),
m_sample_rate(sample_rate),
- m_sample_attos((sample_rate == 0) ? ATTOSECONDS_PER_SECOND : ((ATTOSECONDS_PER_SECOND + sample_rate - 1) / sample_rate)),
- m_buffer(sample_rate)
+ m_sample_attos(sample_rate.disabled() ? ATTOSECONDS_PER_SECOND : ((ATTOSECONDS_PER_SECOND + sample_rate.value() - 1) / sample_rate.value())),
+ m_buffer(sample_rate.disabled() ? 1 : sample_rate.value())
{
}
@@ -83,15 +83,16 @@ stream_buffer::~stream_buffer()
// this buffer
//-------------------------------------------------
-void stream_buffer::set_sample_rate(u32 rate, bool resample)
+void stream_buffer::set_sample_rate(const XTAL &rate, bool resample)
{
// skip if nothing is actually changing
if (rate == m_sample_rate)
return;
+ u32 irate = rate.value();
+
// force resampling off if coming to or from an invalid rate, or if we're at time 0 (startup)
- sound_assert(rate >= SAMPLE_RATE_MINIMUM - 1);
- if (rate < SAMPLE_RATE_MINIMUM || m_sample_rate < SAMPLE_RATE_MINIMUM || (m_end_second == 0 && m_end_sample == 0))
+ if (rate.disabled() || !m_sample_rate.disabled() || (m_end_second == 0 && m_end_sample == 0))
resample = false;
// note the time and period of the current buffer (end_time is AFTER the final sample)
@@ -99,7 +100,7 @@ void stream_buffer::set_sample_rate(u32 rate, bool resample)
attotime prevend = end_time();
// compute the time and period of the new buffer
- attotime newperiod = attotime(0, (ATTOSECONDS_PER_SECOND + rate - 1) / rate);
+ attotime newperiod = attotime(0, (ATTOSECONDS_PER_SECOND + irate - 1) / irate);
attotime newend = attotime(prevend.seconds(), (prevend.attoseconds() / newperiod.attoseconds()) * newperiod.attoseconds());
// buffer a short runway of previous samples; in order to support smooth
@@ -109,11 +110,11 @@ void stream_buffer::set_sample_rate(u32 rate, bool resample)
// voice when jumping off the edge in Q*Bert; without this extra effort
// it is crackly and/or glitchy at times
sample_t buffer[64];
- int buffered_samples = std::min(m_sample_rate, std::min(rate, u32(std::size(buffer))));
+ int buffered_samples = std::min(m_sample_rate.value(), std::min(irate, u32(std::size(buffer))));
// if the new rate is lower, downsample into our holding buffer;
// otherwise just copy into our holding buffer for later upsampling
- bool new_rate_higher = (rate > m_sample_rate);
+ bool new_rate_higher = (irate > m_sample_rate.value());
if (resample)
{
if (!new_rate_higher)
@@ -137,8 +138,8 @@ void stream_buffer::set_sample_rate(u32 rate, bool resample)
}
// ensure our buffer is large enough to hold a full second at the new rate
- if (m_buffer.size() < rate)
- m_buffer.resize(rate);
+ if (m_buffer.size() < irate)
+ m_buffer.resize(irate);
// set the new rate
m_sample_rate = rate;
@@ -529,7 +530,7 @@ read_stream_view sound_stream_input::update(attotime start, attotime end)
// them of our current rate
//-------------------------------------------------
-void sound_stream_input::apply_sample_rate_changes(u32 updatenum, u32 downstream_rate)
+void sound_stream_input::apply_sample_rate_changes(u32 updatenum, const XTAL &downstream_rate)
{
// shouldn't get here unless valid
sound_assert(valid());
@@ -553,21 +554,21 @@ void sound_stream_input::apply_sample_rate_changes(u32 updatenum, u32 downstream
// sound_stream - private common constructor
//-------------------------------------------------
-sound_stream::sound_stream(device_t &device, u32 inputs, u32 outputs, u32 output_base, u32 sample_rate, sound_stream_flags flags) :
+sound_stream::sound_stream(device_t &device, u32 inputs, u32 outputs, u32 output_base, const XTAL &sample_rate, u32 flags) :
m_device(device),
m_next(nullptr),
- m_sample_rate((sample_rate < SAMPLE_RATE_MINIMUM) ? (SAMPLE_RATE_MINIMUM - 1) : (sample_rate < SAMPLE_RATE_OUTPUT_ADAPTIVE) ? sample_rate : 48000),
- m_pending_sample_rate(SAMPLE_RATE_INVALID),
+ m_sample_rate(sample_rate),
+ m_pending_sample_rate(),
m_last_sample_rate_update(0),
- m_input_adaptive(sample_rate == SAMPLE_RATE_INPUT_ADAPTIVE),
- m_output_adaptive(sample_rate == SAMPLE_RATE_OUTPUT_ADAPTIVE),
+ m_input_adaptive(flags & SAMPLE_RATE_INPUT_ADAPTIVE),
+ m_output_adaptive(flags & SAMPLE_RATE_OUTPUT_ADAPTIVE),
m_synchronous((flags & STREAM_SYNCHRONOUS) != 0),
m_resampling_disabled((flags & STREAM_DISABLE_INPUT_RESAMPLING) != 0),
m_sync_timer(nullptr),
m_last_update_end_time(attotime::zero),
m_input(inputs),
m_input_view(inputs),
- m_empty_buffer(100),
+ m_empty_buffer(),
m_output_base(output_base),
m_output(outputs),
m_output_view(outputs)
@@ -620,7 +621,7 @@ sound_stream::sound_stream(device_t &device, u32 inputs, u32 outputs, u32 output
// sound_stream - constructor
//-------------------------------------------------
-sound_stream::sound_stream(device_t &device, u32 inputs, u32 outputs, u32 output_base, u32 sample_rate, stream_update_delegate callback, sound_stream_flags flags) :
+sound_stream::sound_stream(device_t &device, u32 inputs, u32 outputs, u32 output_base, const XTAL &sample_rate, stream_update_delegate callback, u32 flags) :
sound_stream(device, inputs, outputs, output_base, sample_rate, flags)
{
m_callback_ex = std::move(callback);
@@ -641,7 +642,7 @@ sound_stream::~sound_stream()
// given stream
//-------------------------------------------------
-void sound_stream::set_sample_rate(u32 new_rate)
+void sound_stream::set_sample_rate(const XTAL &new_rate)
{
// we will update this on the next global update
if (new_rate != sample_rate())
@@ -724,7 +725,7 @@ read_stream_view sound_stream::update_view(attotime start, attotime end, u32 out
// skip if nothing to do
u32 samples = m_output_view[0].samples();
sound_assert(samples >= 0);
- if (samples != 0 && m_sample_rate >= SAMPLE_RATE_MINIMUM)
+ if (samples != 0 && m_sample_rate.enabled())
{
sound_assert(!synchronous() || samples == 1);
@@ -771,16 +772,11 @@ read_stream_view sound_stream::update_view(attotime start, attotime end, u32 out
// pending sample rate change, apply it now
//-------------------------------------------------
-void sound_stream::apply_sample_rate_changes(u32 updatenum, u32 downstream_rate)
+void sound_stream::apply_sample_rate_changes(u32 updatenum, const XTAL &downstream_rate)
{
// grab the new rate and invalidate
- u32 new_rate = (m_pending_sample_rate != SAMPLE_RATE_INVALID) ? m_pending_sample_rate : m_sample_rate;
- m_pending_sample_rate = SAMPLE_RATE_INVALID;
-
- // clamp to the minimum - 1 (anything below minimum means "off" and
- // will not call the sound callback at all)
- if (new_rate < SAMPLE_RATE_MINIMUM)
- new_rate = SAMPLE_RATE_MINIMUM - 1;
+ XTAL new_rate = m_pending_sample_rate.enabled() ? m_pending_sample_rate : m_sample_rate;
+ m_pending_sample_rate = XTAL();
// if we're input adaptive, override with the rate of our input
if (input_adaptive() && m_input.size() > 0 && m_input[0].valid())
@@ -797,11 +793,11 @@ void sound_stream::apply_sample_rate_changes(u32 updatenum, u32 downstream_rate)
}
// if something is different, process the change
- if (new_rate != SAMPLE_RATE_INVALID && new_rate != m_sample_rate)
+ if (new_rate.enabled() && new_rate != m_sample_rate)
{
// update to the new rate and notify everyone
#if (SOUND_DEBUG)
- printf("stream %s changing rates %d -> %d\n", name().c_str(), m_sample_rate, new_rate);
+ printf("stream %s changing rates %d -> %d\n", name().c_str(), m_sample_rate.value(), new_rate.value());
#endif
m_sample_rate = new_rate;
sample_rate_changed();
@@ -845,7 +841,7 @@ void sound_stream::print_graph_recursive(int indent, int index)
void sound_stream::sample_rate_changed()
{
// if invalid, just punt
- if (m_sample_rate == SAMPLE_RATE_INVALID)
+ if (m_sample_rate.disabled())
return;
// update all output buffers
@@ -938,7 +934,7 @@ read_stream_view sound_stream::empty_view(attotime start, attotime end)
//-------------------------------------------------
default_resampler_stream::default_resampler_stream(device_t &device) :
- sound_stream(device, 1, 1, 0, SAMPLE_RATE_OUTPUT_ADAPTIVE, stream_update_delegate(&default_resampler_stream::resampler_sound_update, this), STREAM_DISABLE_INPUT_RESAMPLING),
+ sound_stream(device, 1, 1, 0, XTAL(), stream_update_delegate(&default_resampler_stream::resampler_sound_update, this), STREAM_DISABLE_INPUT_RESAMPLING|SAMPLE_RATE_OUTPUT_ADAPTIVE),
m_max_latency(0)
{
// create a name
@@ -963,7 +959,7 @@ void default_resampler_stream::resampler_sound_update(sound_stream &stream, std:
auto &output = outputs[0];
// if the input has an invalid rate, just fill with zeros
- if (input.sample_rate() <= 1)
+ if (input.sample_rate().disabled())
{
output.fill(0);
return;
@@ -973,7 +969,7 @@ void default_resampler_stream::resampler_sound_update(sound_stream &stream, std:
sound_assert(input.sample_rate() != output.sample_rate());
// compute the stepping value and the inverse
- stream_buffer::sample_t step = stream_buffer::sample_t(input.sample_rate()) / stream_buffer::sample_t(output.sample_rate());
+ stream_buffer::sample_t step = stream_buffer::sample_t(input.sample_rate().value()) / stream_buffer::sample_t(output.sample_rate().value());
stream_buffer::sample_t stepinv = 1.0 / step;
// determine the latency we need to introduce, in input samples:
@@ -1080,9 +1076,9 @@ sound_manager::sound_manager(running_machine &machine) :
m_last_update(attotime::zero),
m_finalmix_leftover(0),
m_samples_this_update(0),
- m_finalmix(machine.sample_rate()),
- m_leftmix(machine.sample_rate()),
- m_rightmix(machine.sample_rate()),
+ m_finalmix(machine.sample_rate().value()),
+ m_leftmix(machine.sample_rate().value()),
+ m_rightmix(machine.sample_rate().value()),
m_compressor_scale(1.0),
m_compressor_counter(0),
m_compressor_enabled(machine.options().compressor()),
@@ -1135,7 +1131,7 @@ sound_manager::~sound_manager()
// new-style callback and flags
//-------------------------------------------------
-sound_stream *sound_manager::stream_alloc(device_t &device, u32 inputs, u32 outputs, u32 sample_rate, stream_update_delegate callback, sound_stream_flags flags)
+sound_stream *sound_manager::stream_alloc(device_t &device, u32 inputs, u32 outputs, const XTAL &sample_rate, stream_update_delegate callback, u32 flags)
{
// determine output base
u32 output_base = 0;
@@ -1156,7 +1152,7 @@ bool sound_manager::start_recording(std::string_view filename)
{
if (m_wavfile)
return false;
- m_wavfile = util::wav_open(filename, machine().sample_rate(), 2);
+ m_wavfile = util::wav_open(filename, machine().sample_rate().value(), 2);
return bool(m_wavfile);
}
diff --git a/src/emu/sound.h b/src/emu/sound.h
index 15f6a5743a2..9387a6bc30c 100644
--- a/src/emu/sound.h
+++ b/src/emu/sound.h
@@ -65,20 +65,6 @@
//**************************************************************************
-// CONSTANTS
-//**************************************************************************
-
-// special sample-rate values
-constexpr u32 SAMPLE_RATE_INVALID = 0xffffffff;
-constexpr u32 SAMPLE_RATE_INPUT_ADAPTIVE = 0xfffffffe;
-constexpr u32 SAMPLE_RATE_OUTPUT_ADAPTIVE = 0xfffffffd;
-
-// anything below this sample rate is effectively treated as "off"
-constexpr u32 SAMPLE_RATE_MINIMUM = 50;
-
-
-
-//**************************************************************************
// DEBUGGING
//**************************************************************************
@@ -119,7 +105,7 @@ public:
private:
// constructor/destructor
- stream_buffer(u32 sample_rate = 48000);
+ stream_buffer(const XTAL &sample_rate = XTAL());
~stream_buffer();
// disable copying of stream_buffers directly
@@ -127,10 +113,10 @@ private:
stream_buffer &operator=(stream_buffer const &rhs) = delete;
// return the current sample rate
- u32 sample_rate() const { return m_sample_rate; }
+ XTAL sample_rate() const { return m_sample_rate; }
// set a new sample rate
- void set_sample_rate(u32 rate, bool resample);
+ void set_sample_rate(const XTAL &rate, bool resample);
// return the current sample period in attoseconds
attoseconds_t sample_period_attoseconds() const { return m_sample_attos; }
@@ -148,7 +134,7 @@ private:
// return the effective buffer size; currently it is a full second of audio
// at the current sample rate, but this maybe change in the future
- u32 size() const { return m_sample_rate; }
+ u32 size() const { return m_sample_rate.value(); }
// read the sample at the given index (clamped); should be valid in all cases
sample_t get(s32 index) const
@@ -202,7 +188,7 @@ private:
// internal state
u32 m_end_second; // current full second of the buffer end
u32 m_end_sample; // current sample number within the final second
- u32 m_sample_rate; // sample rate of the data in the buffer
+ XTAL m_sample_rate; // sample rate of the data in the buffer
attoseconds_t m_sample_attos; // pre-computed attoseconds per sample
std::vector<sample_t> m_buffer; // vector of actual buffer data
@@ -288,7 +274,7 @@ public:
sample_t gain() const { return m_gain; }
// return the sample rate of the data
- u32 sample_rate() const { return m_buffer->sample_rate(); }
+ XTAL sample_rate() const { return m_buffer->sample_rate(); }
// return the sample period (in attoseconds) of the data
attoseconds_t sample_period_attoseconds() const { return m_buffer->sample_period_attoseconds(); }
@@ -492,7 +478,7 @@ public:
attotime end_time() const { return m_buffer.end_time(); }
u32 index() const { return m_index; }
stream_buffer::sample_t gain() const { return m_gain; }
- u32 buffer_sample_rate() const { return m_buffer.sample_rate(); }
+ XTAL buffer_sample_rate() const { return m_buffer.sample_rate(); }
// simple setters
void set_gain(float gain) { m_gain = gain; }
@@ -501,7 +487,7 @@ public:
std::string name() const;
// handle a changing sample rate
- void sample_rate_changed(u32 rate) { m_buffer.set_sample_rate(rate, true); }
+ void sample_rate_changed(const XTAL &rate) { m_buffer.set_sample_rate(rate, true); }
// return an output view covering a time period
write_stream_view view(attotime start, attotime end) { return write_stream_view(m_buffer, start, end); }
@@ -563,7 +549,7 @@ public:
read_stream_view update(attotime start, attotime end);
// tell inputs to apply sample rate changes
- void apply_sample_rate_changes(u32 updatenum, u32 downstream_rate);
+ void apply_sample_rate_changes(u32 updatenum, const XTAL &downstream_rate);
private:
// internal state
@@ -596,7 +582,15 @@ enum sound_stream_flags : u32
// specify that input streams should not be resampled; stream update handler
// must be able to accommodate multiple strams of differing input rates
- STREAM_DISABLE_INPUT_RESAMPLING = 0x02
+ STREAM_DISABLE_INPUT_RESAMPLING = 0x02,
+
+ // specify that the input frequency should be set to the connected
+ // source frequency
+ SAMPLE_RATE_INPUT_ADAPTIVE = 0x04,
+
+ // specify that the output frequency should be set to the connected
+ // sink frequency
+ SAMPLE_RATE_OUTPUT_ADAPTIVE = 0x08,
};
@@ -607,11 +601,11 @@ class sound_stream
friend class sound_manager;
// private common constructopr
- sound_stream(device_t &device, u32 inputs, u32 outputs, u32 output_base, u32 sample_rate, sound_stream_flags flags);
+ sound_stream(device_t &device, u32 inputs, u32 outputs, u32 output_base, const XTAL &sample_rate, u32 flags);
public:
// construction/destruction
- sound_stream(device_t &device, u32 inputs, u32 outputs, u32 output_base, u32 sample_rate, stream_update_delegate callback, sound_stream_flags flags = STREAM_DEFAULT_FLAGS);
+ sound_stream(device_t &device, u32 inputs, u32 outputs, u32 output_base, const XTAL &sample_rate, stream_update_delegate callback, u32 flags = STREAM_DEFAULT_FLAGS);
virtual ~sound_stream();
// simple getters
@@ -631,13 +625,13 @@ public:
sound_stream_output &output(int index) { sound_assert(index >= 0 && index < m_output.size()); return m_output[index]; }
// sample rate and timing getters
- u32 sample_rate() const { return (m_pending_sample_rate != SAMPLE_RATE_INVALID) ? m_pending_sample_rate : m_sample_rate; }
+ XTAL sample_rate() const { return m_pending_sample_rate.enabled() ? m_pending_sample_rate : m_sample_rate; }
attotime sample_time() const { return m_output[0].end_time(); }
attotime sample_period() const { return attotime(0, sample_period_attoseconds()); }
- attoseconds_t sample_period_attoseconds() const { return (m_sample_rate != SAMPLE_RATE_INVALID) ? HZ_TO_ATTOSECONDS(m_sample_rate) : ATTOSECONDS_PER_SECOND; }
+ attoseconds_t sample_period_attoseconds() const { return m_sample_rate.enabled() ? HZ_TO_ATTOSECONDS(m_sample_rate.dvalue()) : ATTOSECONDS_PER_SECOND; }
// set the sample rate of the stream; will kick in at the next global update
- void set_sample_rate(u32 sample_rate);
+ void set_sample_rate(const XTAL &sample_rate);
// connect the output 'outputnum' of given input_stream to this stream's input 'inputnum'
void set_input(int inputnum, sound_stream *input_stream, int outputnum = 0, float gain = 1.0f);
@@ -649,7 +643,7 @@ public:
read_stream_view update_view(attotime start, attotime end, u32 outputnum = 0);
// apply any pending sample rate changes; should only be called by the sound manager
- void apply_sample_rate_changes(u32 updatenum, u32 downstream_rate);
+ void apply_sample_rate_changes(u32 updatenum, const XTAL &downstream_rate);
#if (SOUND_DEBUG)
// print one level of the sound graph and recursively tell our inputs to do the same
@@ -662,7 +656,7 @@ protected:
private:
// perform most of the initialization here
- void init_common(u32 inputs, u32 outputs, u32 sample_rate, sound_stream_flags flags);
+ void init_common(u32 inputs, u32 outputs, const XTAL &sample_rate, u32 flags);
// if the sample rate has changed, this gets called to update internals
void sample_rate_changed();
@@ -687,8 +681,8 @@ private:
sound_stream *m_next; // next stream in the chain
// general information
- u32 m_sample_rate; // current live sample rate
- u32 m_pending_sample_rate; // pending sample rate for dynamic changes
+ XTAL m_sample_rate; // current live sample rate
+ XTAL m_pending_sample_rate; // pending sample rate for dynamic changes
u32 m_last_sample_rate_update; // update number of last sample rate change
bool m_input_adaptive; // adaptive stream that runs at the sample rate of its input
bool m_output_adaptive; // adaptive stream that runs at the sample rate of its output
@@ -771,7 +765,7 @@ public:
stream_buffer::sample_t compressor_scale() const { return m_compressor_scale; }
// allocate a new stream with a new-style callback
- sound_stream *stream_alloc(device_t &device, u32 inputs, u32 outputs, u32 sample_rate, stream_update_delegate callback, sound_stream_flags flags);
+ sound_stream *stream_alloc(device_t &device, u32 inputs, u32 outputs, const XTAL &sample_rate, stream_update_delegate callback, u32 flags);
// WAV recording
bool is_recording() const { return bool(m_wavfile); }
diff --git a/src/emu/speaker.cpp b/src/emu/speaker.cpp
index 3cbb14355a4..58792327ad1 100644
--- a/src/emu/speaker.cpp
+++ b/src/emu/speaker.cpp
@@ -31,7 +31,7 @@ DEFINE_DEVICE_TYPE(SPEAKER, speaker_device, "speaker", "Speaker")
// speaker_device - constructor
//-------------------------------------------------
-speaker_device::speaker_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
+speaker_device::speaker_device(const machine_config &mconfig, const char *tag, device_t *owner, const XTAL &clock)
: device_t(mconfig, SPEAKER, tag, owner, clock)
, device_mixer_interface(mconfig, *this)
, m_x(0.0)
@@ -73,7 +73,7 @@ void speaker_device::mix(stream_buffer::sample_t *leftmix, stream_buffer::sample
// track maximum sample value for each 0.1s bucket
if (machine().options().speaker_report() != 0)
{
- u32 samples_per_bucket = m_mixer_stream->sample_rate() / BUCKETS_PER_SECOND;
+ u32 samples_per_bucket = m_mixer_stream->sample_rate().value() / BUCKETS_PER_SECOND;
for (int sample = 0; sample < expected_samples; sample++)
{
m_current_max = std::max(m_current_max, fabsf(view.get(sample)));
diff --git a/src/emu/speaker.h b/src/emu/speaker.h
index 54aa00603c9..751ba29e566 100644
--- a/src/emu/speaker.h
+++ b/src/emu/speaker.h
@@ -46,11 +46,11 @@ class speaker_device : public device_t, public device_mixer_interface
public:
// construction/destruction
speaker_device(const machine_config &mconfig, const char *tag, device_t *owner, double x, double y, double z)
- : speaker_device(mconfig, tag, owner, 0)
+ : speaker_device(mconfig, tag, owner)
{
set_position(x, y, z);
}
- speaker_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 0);
+ speaker_device(const machine_config &mconfig, const char *tag, device_t *owner, const XTAL &clock = XTAL());
virtual ~speaker_device();
// inline configuration helpers
diff --git a/src/emu/tilemap.cpp b/src/emu/tilemap.cpp
index 5757f35341f..422aca9bbd6 100644
--- a/src/emu/tilemap.cpp
+++ b/src/emu/tilemap.cpp
@@ -1659,7 +1659,7 @@ DEFINE_DEVICE_TYPE(TILEMAP, tilemap_device, "tilemap", "Tilemap")
// tilemap_device - constructor
//-------------------------------------------------
-tilemap_device::tilemap_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock)
+tilemap_device::tilemap_device(const machine_config &mconfig, const char *tag, device_t *owner, const XTAL &clock)
: device_t(mconfig, TILEMAP, tag, owner, clock)
, tilemap_t(static_cast<device_t &>(*this))
, m_gfxdecode(*this, finder_base::DUMMY_TAG)
diff --git a/src/emu/tilemap.h b/src/emu/tilemap.h
index b6b2c566bfa..46ffe2a836b 100644
--- a/src/emu/tilemap.h
+++ b/src/emu/tilemap.h
@@ -669,7 +669,7 @@ public:
template <typename T>
tilemap_device(const machine_config &mconfig, const char *tag, device_t *owner, T &&gfxtag, int entrybytes
, u16 tilewidth, u16 tileheight, tilemap_standard_mapper mapper, u32 columns, u32 rows, pen_t transpen)
- : tilemap_device(mconfig, tag, owner, (u32)0)
+ : tilemap_device(mconfig, tag, owner)
{
set_gfxdecode(std::forward<T>(gfxtag));
set_bytes_per_entry(entrybytes);
@@ -681,7 +681,7 @@ public:
template <typename T>
tilemap_device(const machine_config &mconfig, const char *tag, device_t *owner, T &&gfxtag, int entrybytes
, u16 tilewidth, u16 tileheight, tilemap_standard_mapper mapper, u32 columns, u32 rows)
- : tilemap_device(mconfig, tag, owner, (u32)0)
+ : tilemap_device(mconfig, tag, owner)
{
set_gfxdecode(std::forward<T>(gfxtag));
set_bytes_per_entry(entrybytes);
@@ -691,14 +691,14 @@ public:
template <typename T>
tilemap_device(const machine_config &mconfig, const char *tag, device_t *owner, T &&gfxtag, int entrybytes, u16 tilewidth, u16 tileheight)
- : tilemap_device(mconfig, tag, owner, (u32)0)
+ : tilemap_device(mconfig, tag, owner)
{
set_gfxdecode(std::forward<T>(gfxtag));
set_bytes_per_entry(entrybytes);
set_tile_size(tilewidth, tileheight);
}
- tilemap_device(const machine_config &mconfig, const char *tag, device_t *owner, u32 clock = 0);
+ tilemap_device(const machine_config &mconfig, const char *tag, device_t *owner, const XTAL &clock = XTAL());
template <typename T> void set_gfxdecode(T &&tag) { m_gfxdecode.set_tag(std::forward<T>(tag)); }
void set_bytes_per_entry(int bpe) { m_bytes_per_entry = bpe; }
diff --git a/src/emu/validity.cpp b/src/emu/validity.cpp
index 8fed2d6def0..6b23a8831d8 100644
--- a/src/emu/validity.cpp
+++ b/src/emu/validity.cpp
@@ -2656,7 +2656,7 @@ void validity_checker::validate_device_types()
machine_config::token const tok(config.begin_configuration(config.root_device()));
for (device_type type : registered_device_types)
{
- device_t *const dev = config.device_add(type.shortname(), type, 0);
+ device_t *const dev = config.device_add(type.shortname(), type);
char const *name((dev->shortname() && *dev->shortname()) ? dev->shortname() : type.type().name());
std::string const description((dev->source() && *dev->source()) ? util::string_format("%s(%s)", core_filename_extract_base(dev->source()), name) : name);
@@ -2696,7 +2696,7 @@ void validity_checker::validate_device_types()
}
else if (!devname.second)
{
- device_t *const dup = config.device_add("_dup", *devname.first->second, 0);
+ device_t *const dup = config.device_add("_dup", *devname.first->second);
osd_printf_error("Device %s short name is a duplicate of %s(%s)\n", description, core_filename_extract_base(dup->source()), dup->shortname());
config.device_remove("_dup");
}
@@ -2720,7 +2720,7 @@ void validity_checker::validate_device_types()
}
else if (!devdesc.second)
{
- device_t *const dup = config.device_add("_dup", *devdesc.first->second, 0);
+ device_t *const dup = config.device_add("_dup", *devdesc.first->second);
osd_printf_error("Device %s name '%s' is a duplicate of %s(%s)\n", description, dev->name(), core_filename_extract_base(dup->source()), dup->shortname());
config.device_remove("_dup");
}
diff --git a/src/emu/xtal.cpp b/src/emu/xtal.cpp
index fc606c4f7db..5f9d661acf6 100644
--- a/src/emu/xtal.cpp
+++ b/src/emu/xtal.cpp
@@ -550,12 +550,18 @@ bool XTAL::validate(double base_clock)
void XTAL::validate(const char *message) const
{
+ if(!m_base_clock || m_disable_validation)
+ return;
+
if(!validate(m_base_clock))
fail(m_base_clock, message);
}
void XTAL::validate(const std::string &message) const
{
+ if(!m_base_clock || m_disable_validation)
+ return;
+
if(!validate(m_base_clock))
fail(m_base_clock, message);
}
diff --git a/src/emu/xtal.h b/src/emu/xtal.h
index b58f00943b2..700e75e730f 100644
--- a/src/emu/xtal.h
+++ b/src/emu/xtal.h
@@ -45,27 +45,47 @@ Usage:
class XTAL {
public:
+ constexpr explicit XTAL() : m_base_clock(0), m_current_clock(0), m_disable_validation(true) {}
- constexpr explicit XTAL(double base_clock) : m_base_clock(base_clock), m_current_clock(base_clock) {}
+ constexpr explicit XTAL(double base_clock) : m_base_clock(base_clock), m_current_clock(base_clock), m_disable_validation(true) {}
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); }
+ template <typename T> constexpr XTAL operator *(T &&mult) const noexcept { return XTAL(m_base_clock, m_current_clock * mult, m_disable_validation); }
+ template <typename T> constexpr XTAL operator /(T &&div) const noexcept { return XTAL(m_base_clock, m_current_clock / div, m_disable_validation); }
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);
+ friend constexpr XTAL operator *(const XTAL &xtal, int mult);
+ friend constexpr XTAL operator *(const XTAL &xtal, unsigned int mult);
+ friend constexpr XTAL operator /(const XTAL &xtal, int div);
+ friend constexpr XTAL operator /(const XTAL &xtal, unsigned int div);
+
+ static constexpr XTAL u(unsigned int clock);
void validate(const char *message) const;
void validate(const std::string &message) const;
+ bool disabled() const noexcept { return m_base_clock == 0; }
+ bool enabled() const noexcept { return m_base_clock != 0; }
+
+ bool operator == (const XTAL &clock) const {
+ return clock.m_base_clock == m_base_clock && clock.m_current_clock == m_current_clock;
+ }
+
+ bool operator != (const XTAL &clock) const {
+ return !(*this == clock);
+ }
+
+
private:
+ friend class save_manager;
double m_base_clock, m_current_clock;
+ bool m_disable_validation;
- constexpr XTAL(double base_clock, double current_clock) noexcept : m_base_clock(base_clock), m_current_clock(current_clock) {}
+ constexpr XTAL(double base_clock, double current_clock, bool disable_validation) noexcept : m_base_clock(base_clock), m_current_clock(current_clock), m_disable_validation(disable_validation) {}
static const double known_xtals[];
static double last_correct_value, xtal_error_low, xtal_error_high;
@@ -76,9 +96,14 @@ private:
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 *(int mult, const XTAL &xtal) { return XTAL(xtal.base(), xtal.dvalue() * mult, xtal.m_disable_validation); }
+constexpr XTAL operator *(unsigned int mult, const XTAL &xtal) { return XTAL(xtal.base(), xtal.dvalue() * mult, xtal.m_disable_validation); }
+constexpr XTAL operator *(const XTAL &xtal, int mult) { return XTAL(xtal.base(), xtal.dvalue() * mult, xtal.m_disable_validation); }
+constexpr XTAL operator *(const XTAL &xtal, unsigned int mult) { return XTAL(xtal.base(), xtal.dvalue() * mult, xtal.m_disable_validation); }
+constexpr XTAL operator /(const XTAL &xtal, int div) { return XTAL(xtal.base(), xtal.dvalue() / div, xtal.m_disable_validation); }
+constexpr XTAL operator /(const XTAL &xtal, unsigned int div) { return XTAL(xtal.base(), xtal.dvalue() / div, xtal.m_disable_validation); }
+
+constexpr XTAL XTAL::u(unsigned int clock) { return XTAL(clock, clock, true); }
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)); }