mirror of
https://github.com/holub/mame
synced 2025-06-06 04:43:45 +03:00
netlist: untangle sound and cpu devices.
* member variables are now where they belong. * Avoid over/underclocking of netlist sound devices.
This commit is contained in:
parent
51503ac1c9
commit
c721e728f4
@ -35,12 +35,15 @@
|
||||
#define LOG_GENERAL (1U << 0)
|
||||
#define LOG_DEV_CALLS (1U << 1)
|
||||
#define LOG_DEBUG (1U << 2)
|
||||
#define LOG_TIMING (1U << 3)
|
||||
|
||||
//#define LOG_MASK (LOG_GENERAL | LOG_DEV_CALLS | LOG_DEBUG)
|
||||
//#define LOG_MASK (LOG_TIMING)
|
||||
#define LOG_MASK (0)
|
||||
|
||||
#define LOGDEVCALLS(...) LOGMASKED(LOG_DEV_CALLS, __VA_ARGS__)
|
||||
#define LOGDEBUG(...) LOGMASKED(LOG_DEBUG, __VA_ARGS__)
|
||||
#define LOGTIMING(...) LOGMASKED(LOG_TIMING, __VA_ARGS__)
|
||||
|
||||
#define LOG_OUTPUT_FUNC printf
|
||||
|
||||
@ -904,10 +907,6 @@ netlist_mame_device::netlist_mame_device(const machine_config &mconfig, const ch
|
||||
|
||||
netlist_mame_device::netlist_mame_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock)
|
||||
: device_t(mconfig, type, tag, owner, clock)
|
||||
, m_icount(0)
|
||||
, m_cur_time(attotime::zero)
|
||||
, m_attotime_per_clock(attotime::zero)
|
||||
, m_old(netlist::netlist_time_ext::zero())
|
||||
, m_setup_func(nullptr)
|
||||
, m_device_reset_called(false)
|
||||
{
|
||||
@ -1025,15 +1024,8 @@ void netlist_mame_device::device_validity_check(validity_checker &valid) const
|
||||
}
|
||||
|
||||
|
||||
void netlist_mame_device::device_start()
|
||||
void netlist_mame_device::device_start_common()
|
||||
{
|
||||
LOGDEVCALLS("device_start entry\n");
|
||||
m_attotime_per_clock = attotime(0, m_attoseconds_per_clock);
|
||||
|
||||
//netlist().save(*this, m_cur_time, pstring(this->name()), "m_cur_time");
|
||||
save_item(NAME(m_cur_time));
|
||||
save_item(NAME(m_attotime_per_clock));
|
||||
|
||||
m_netlist = std::make_unique<netlist_mame_t>(*this, "netlist");
|
||||
if (!machine().options().verbose())
|
||||
{
|
||||
@ -1044,29 +1036,19 @@ void netlist_mame_device::device_start()
|
||||
common_dev_start(m_netlist.get());
|
||||
m_netlist->setup().prepare_to_run();
|
||||
|
||||
// FIXME: use save_helper
|
||||
m_netlist->save(*this, m_rem, pstring(this->name()), "m_rem");
|
||||
m_netlist->save(*this, m_div, pstring(this->name()), "m_div");
|
||||
m_netlist->save(*this, m_old, pstring(this->name()), "m_old");
|
||||
|
||||
save_state();
|
||||
|
||||
m_old = netlist::netlist_time_ext::zero();
|
||||
m_rem = netlist::netlist_time_ext::zero();
|
||||
m_cur_time = attotime::zero;
|
||||
|
||||
m_device_reset_called = false;
|
||||
|
||||
LOGDEVCALLS("device_start exit\n");
|
||||
}
|
||||
|
||||
void netlist_mame_device::device_clock_changed()
|
||||
|
||||
void netlist_mame_device::device_start()
|
||||
{
|
||||
m_div = static_cast<netlist::netlist_time_ext>(
|
||||
(netlist::netlist_time_ext::resolution() << MDIV_SHIFT) / clock());
|
||||
//printf("m_div %d\n", (int) m_div.as_raw());
|
||||
netlist().log().debug("Setting clock {1} and divisor {2}\n", clock(), m_div.as_double());
|
||||
m_attotime_per_clock = attotime(0, m_attoseconds_per_clock);
|
||||
LOGDEVCALLS("device_start entry\n");
|
||||
|
||||
device_start_common();
|
||||
save_state();
|
||||
|
||||
LOGDEVCALLS("device_start exit\n");
|
||||
}
|
||||
|
||||
|
||||
@ -1108,7 +1090,7 @@ void netlist_mame_device::device_pre_save()
|
||||
netlist().run_state_manager().pre_save();
|
||||
}
|
||||
|
||||
void netlist_mame_device::update_icount(netlist::netlist_time_ext time) noexcept
|
||||
void netlist_mame_cpu_device::update_icount(netlist::netlist_time_ext time) noexcept
|
||||
{
|
||||
const netlist::netlist_time_ext delta = (time - m_old).shl(MDIV_SHIFT) + m_rem;
|
||||
const uint64_t d = delta / m_div;
|
||||
@ -1118,7 +1100,7 @@ void netlist_mame_device::update_icount(netlist::netlist_time_ext time) noexcept
|
||||
m_icount -= d;
|
||||
}
|
||||
|
||||
void netlist_mame_device::check_mame_abort_slice() noexcept
|
||||
void netlist_mame_cpu_device::check_mame_abort_slice() noexcept
|
||||
{
|
||||
if (m_icount <= 0)
|
||||
netlist().exec().abort_current_queue_slice();
|
||||
@ -1173,6 +1155,8 @@ netlist_mame_cpu_device::netlist_mame_cpu_device(const machine_config &mconfig,
|
||||
, device_disasm_interface(mconfig, *this)
|
||||
, device_memory_interface(mconfig, *this)
|
||||
, m_program_config("program", ENDIANNESS_LITTLE, 8, 12) // Interface is needed to keep debugger happy
|
||||
, m_icount(0)
|
||||
, m_old(netlist::netlist_time_ext::zero())
|
||||
, m_genPC(0)
|
||||
{
|
||||
}
|
||||
@ -1209,9 +1193,18 @@ private:
|
||||
|
||||
void netlist_mame_cpu_device::device_start()
|
||||
{
|
||||
netlist_mame_device::device_start();
|
||||
LOGDEVCALLS("device_start entry\n");
|
||||
|
||||
// State support
|
||||
device_start_common();
|
||||
// FIXME: use save_helper
|
||||
netlist().save(*this, m_rem, pstring(this->name()), "m_rem");
|
||||
netlist().save(*this, m_div, pstring(this->name()), "m_div");
|
||||
netlist().save(*this, m_old, pstring(this->name()), "m_old");
|
||||
|
||||
m_old = netlist::netlist_time_ext::zero();
|
||||
m_rem = netlist::netlist_time_ext::zero();
|
||||
|
||||
save_state();
|
||||
|
||||
state_add(STATE_GENPC, "GENPC", m_genPC).noshow();
|
||||
state_add(STATE_GENPCBASE, "CURPC", m_genPC).noshow();
|
||||
@ -1241,8 +1234,17 @@ void netlist_mame_cpu_device::device_start()
|
||||
|
||||
// set our instruction counter
|
||||
set_icountptr(m_icount);
|
||||
|
||||
LOGDEVCALLS("device_start exit\n");
|
||||
}
|
||||
|
||||
void netlist_mame_cpu_device::device_clock_changed()
|
||||
{
|
||||
m_div = static_cast<netlist::netlist_time_ext>(
|
||||
(netlist::netlist_time_ext::resolution() << MDIV_SHIFT) / clock());
|
||||
//printf("m_div %d\n", (int) m_div.as_raw());
|
||||
netlist().log().debug("Setting clock {1} and divisor {2}\n", clock(), m_div.as_double());
|
||||
}
|
||||
|
||||
void netlist_mame_cpu_device::nl_register_devices(netlist::nlparse_t &parser) const
|
||||
{
|
||||
@ -1313,11 +1315,15 @@ offs_t netlist_disassembler::disassemble(std::ostream &stream, offs_t pc, const
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
||||
netlist_mame_sound_device::netlist_mame_sound_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock)
|
||||
: netlist_mame_device(mconfig, NETLIST_SOUND, tag, owner, clock)
|
||||
: netlist_mame_device(mconfig, NETLIST_SOUND, tag, owner, 0)
|
||||
, device_sound_interface(mconfig, *this)
|
||||
, m_in(nullptr)
|
||||
, m_stream(nullptr)
|
||||
, m_cur_time(attotime::zero)
|
||||
, m_sound_clock(clock)
|
||||
, m_attotime_per_clock(attotime::zero)
|
||||
, m_is_device_call(false)
|
||||
, m_last_update_to_current_time(attotime::zero)
|
||||
{
|
||||
}
|
||||
|
||||
@ -1353,23 +1359,29 @@ void netlist_mame_sound_device::device_reset()
|
||||
|
||||
void netlist_mame_sound_device::device_start()
|
||||
{
|
||||
netlist_mame_device::device_start();
|
||||
|
||||
LOGDEVCALLS("sound device_start\n");
|
||||
|
||||
m_attotime_per_clock = attotime::from_hz(m_sound_clock);
|
||||
|
||||
save_item(NAME(m_cur_time));
|
||||
save_item(NAME(m_attotime_per_clock));
|
||||
|
||||
device_start_common();
|
||||
save_state();
|
||||
|
||||
m_cur_time = attotime::zero;
|
||||
|
||||
// Configure outputs
|
||||
|
||||
if (m_out.size() == 0)
|
||||
fatalerror("No output devices");
|
||||
|
||||
//m_num_outputs = outdevs.size();
|
||||
|
||||
/* resort channels */
|
||||
for (auto &outdev : m_out)
|
||||
{
|
||||
if (outdev.first < 0 || outdev.first >= m_out.size())
|
||||
fatalerror("illegal channel number %d", outdev.first);
|
||||
outdev.second->set_sample_time(netlist::netlist_time::from_hz(clock()));
|
||||
outdev.second->set_sample_time(netlist::netlist_time::from_hz(m_sound_clock));
|
||||
outdev.second->buffer_reset(netlist::netlist_time_ext::zero());
|
||||
}
|
||||
|
||||
@ -1385,13 +1397,15 @@ void netlist_mame_sound_device::device_start()
|
||||
if (indevs.size() == 1)
|
||||
{
|
||||
m_in = indevs[0];
|
||||
const auto sample_time = netlist::netlist_time::from_raw(static_cast<netlist::netlist_time::internal_type>(nltime_from_attotime(clocks_to_attotime(1)).as_raw()));
|
||||
const auto sample_time = netlist::netlist_time::from_raw(static_cast<netlist::netlist_time::internal_type>(nltime_from_attotime(m_attotime_per_clock).as_raw()));
|
||||
m_in->resolve_params(sample_time);
|
||||
}
|
||||
|
||||
/* initialize the stream(s) */
|
||||
m_is_device_call = false;
|
||||
m_stream = machine().sound().stream_alloc(*this, m_in ? m_in->num_channels() : 0, m_out.size(), clock());
|
||||
m_stream = machine().sound().stream_alloc(*this, m_in ? m_in->num_channels() : 0, m_out.size(), m_sound_clock);
|
||||
|
||||
LOGDEVCALLS("sound device_start exit\n");
|
||||
}
|
||||
|
||||
|
||||
@ -1408,18 +1422,6 @@ void netlist_mame_sound_device::register_stream_output(int channel, netlist_mame
|
||||
m_out[channel] = so;
|
||||
}
|
||||
|
||||
void netlist_mame_sound_device::device_clock_changed()
|
||||
{
|
||||
netlist_mame_device::device_clock_changed();
|
||||
|
||||
for (auto &e : m_out)
|
||||
{
|
||||
e.second->set_sample_time(nltime_from_clocks(1));
|
||||
}
|
||||
}
|
||||
|
||||
static attotime last;
|
||||
|
||||
void netlist_mame_sound_device::update_to_current_time()
|
||||
{
|
||||
LOGDEBUG("before update\n");
|
||||
@ -1427,29 +1429,28 @@ void netlist_mame_sound_device::update_to_current_time()
|
||||
get_stream()->update();
|
||||
m_is_device_call = false;
|
||||
|
||||
if (machine().time() < last)
|
||||
LOGDEBUG("machine.time() decreased 2\n");
|
||||
if (machine().time() < m_last_update_to_current_time)
|
||||
LOGTIMING("machine.time() decreased 2\n");
|
||||
|
||||
last = machine().time();
|
||||
m_last_update_to_current_time = machine().time();
|
||||
|
||||
const auto mtime = nltime_from_attotime(machine().time());
|
||||
const auto cur(netlist().exec().time());
|
||||
|
||||
if (mtime > cur)
|
||||
{
|
||||
if ((mtime - cur) >= nltime_from_clocks(1))
|
||||
LOGDEBUG("%f us\n", (mtime - cur).as_double() * 1000000.0);
|
||||
LOGTIMING("%f us\n", (mtime - cur).as_double() * 1000000.0);
|
||||
netlist().exec().process_queue(mtime - cur);
|
||||
}
|
||||
else if (mtime < cur)
|
||||
LOGDEBUG("%s : %f ns before machine time\n", this->name(), (cur - mtime).as_double() * 1000000000.0);
|
||||
LOGTIMING("%s : %f us before machine time\n", this->name(), (cur - mtime).as_double() * 1000000.0);
|
||||
}
|
||||
|
||||
void netlist_mame_sound_device::sound_stream_update(sound_stream &stream, stream_sample_t **inputs, stream_sample_t **outputs, int samples)
|
||||
{
|
||||
if (machine().time() < last)
|
||||
LOGDEBUG("machine.time() decreased 1\n");
|
||||
last = machine().time();
|
||||
if (machine().time() < m_last_update_to_current_time)
|
||||
LOGTIMING("machine.time() decreased 1\n");
|
||||
m_last_update_to_current_time = machine().time();
|
||||
LOGDEBUG("samples %d %d\n", (int) m_is_device_call, samples);
|
||||
|
||||
if (m_in)
|
||||
|
@ -75,25 +75,8 @@ public:
|
||||
netlist::setup_t &setup();
|
||||
netlist_mame_t &netlist() noexcept { return *m_netlist; }
|
||||
|
||||
void update_icount(netlist::netlist_time_ext time) noexcept;
|
||||
void check_mame_abort_slice() noexcept;
|
||||
|
||||
static void register_memregion_source(netlist::nlparse_t &parser, device_t &dev, const char *name);
|
||||
|
||||
int m_icount;
|
||||
|
||||
static constexpr const unsigned MDIV_SHIFT = 16;
|
||||
|
||||
netlist::netlist_time_ext nltime_ext_from_clocks(unsigned c) const noexcept
|
||||
{
|
||||
return (m_div * c).shr(MDIV_SHIFT);
|
||||
}
|
||||
|
||||
netlist::netlist_time nltime_from_clocks(unsigned c) const noexcept
|
||||
{
|
||||
return static_cast<netlist::netlist_time>((m_div * c).shr(MDIV_SHIFT));
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
netlist_mame_device(const machine_config &mconfig, device_type type, const char *tag, device_t *owner, uint32_t clock);
|
||||
@ -109,21 +92,16 @@ protected:
|
||||
virtual void device_reset() override;
|
||||
virtual void device_post_load() override;
|
||||
virtual void device_pre_save() override;
|
||||
virtual void device_clock_changed() override;
|
||||
//virtual void device_clock_changed() override;
|
||||
|
||||
void device_start_common();
|
||||
void save_state();
|
||||
|
||||
std::unique_ptr<netlist::netlist_state_t> base_validity_check(validity_checker &valid) const;
|
||||
|
||||
attotime m_cur_time;
|
||||
attotime m_attotime_per_clock;
|
||||
private:
|
||||
void save_state();
|
||||
|
||||
void common_dev_start(netlist::netlist_state_t *lnetlist) const;
|
||||
|
||||
netlist::netlist_time_ext m_div;
|
||||
netlist::netlist_time_ext m_rem;
|
||||
netlist::netlist_time_ext m_old;
|
||||
|
||||
std::unique_ptr<netlist_mame_t> m_netlist;
|
||||
|
||||
func_type m_setup_func;
|
||||
@ -156,6 +134,8 @@ class netlist_mame_cpu_device : public netlist_mame_device,
|
||||
public device_memory_interface
|
||||
{
|
||||
public:
|
||||
static constexpr const unsigned MDIV_SHIFT = 16;
|
||||
|
||||
// construction/destruction
|
||||
netlist_mame_cpu_device(const machine_config &mconfig, const char *tag, device_t *owner, uint32_t clock);
|
||||
|
||||
@ -179,12 +159,26 @@ public:
|
||||
return *this;
|
||||
}
|
||||
|
||||
void update_icount(netlist::netlist_time_ext time) noexcept;
|
||||
void check_mame_abort_slice() noexcept;
|
||||
|
||||
netlist::netlist_time_ext nltime_ext_from_clocks(unsigned c) const noexcept
|
||||
{
|
||||
return (m_div * c).shr(MDIV_SHIFT);
|
||||
}
|
||||
|
||||
netlist::netlist_time nltime_from_clocks(unsigned c) const noexcept
|
||||
{
|
||||
return static_cast<netlist::netlist_time>((m_div * c).shr(MDIV_SHIFT));
|
||||
}
|
||||
|
||||
protected:
|
||||
// netlist_mame_device
|
||||
virtual void nl_register_devices(netlist::nlparse_t &parser) const override;
|
||||
|
||||
// device_t overrides
|
||||
virtual void device_start() override;
|
||||
virtual void device_clock_changed() override;
|
||||
|
||||
// device_execute_interface overrides
|
||||
virtual uint64_t execute_clocks_to_cycles(uint64_t clocks) const noexcept override;
|
||||
@ -204,6 +198,10 @@ protected:
|
||||
address_space_config m_program_config;
|
||||
|
||||
private:
|
||||
int m_icount;
|
||||
netlist::netlist_time_ext m_div;
|
||||
netlist::netlist_time_ext m_rem;
|
||||
netlist::netlist_time_ext m_old;
|
||||
offs_t m_genPC;
|
||||
};
|
||||
|
||||
@ -249,13 +247,16 @@ protected:
|
||||
// device_t overrides
|
||||
virtual void device_start() override;
|
||||
virtual void device_reset() override;
|
||||
virtual void device_clock_changed() override;
|
||||
|
||||
private:
|
||||
std::map<int, netlist_mame_stream_output_device *> m_out;
|
||||
nld_sound_in *m_in;
|
||||
sound_stream *m_stream;
|
||||
attotime m_cur_time;
|
||||
uint32_t m_sound_clock;
|
||||
attotime m_attotime_per_clock;
|
||||
bool m_is_device_call;
|
||||
attotime m_last_update_to_current_time;
|
||||
};
|
||||
|
||||
// ----------------------------------------------------------------------------------------
|
||||
|
Loading…
Reference in New Issue
Block a user