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:
couriersud 2020-08-14 22:05:30 +02:00
parent 51503ac1c9
commit c721e728f4
2 changed files with 92 additions and 90 deletions

View File

@ -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)

View File

@ -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;
};
// ----------------------------------------------------------------------------------------